| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: cp.c,v 1.51 2008/07/20 00:52:39 lukem Exp $ */ | | 1 | /* $NetBSD: cp.c,v 1.52 2009/09/29 13:30:17 pooka Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1988, 1993, 1994 | | 4 | * Copyright (c) 1988, 1993, 1994 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * David Hitz of Auspex Systems Inc. | | 8 | * David Hitz of Auspex Systems Inc. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -33,27 +33,27 @@ | | | @@ -33,27 +33,27 @@ |
33 | */ | | 33 | */ |
34 | | | 34 | |
35 | #include <sys/cdefs.h> | | 35 | #include <sys/cdefs.h> |
36 | #ifndef lint | | 36 | #ifndef lint |
37 | __COPYRIGHT( | | 37 | __COPYRIGHT( |
38 | "@(#) Copyright (c) 1988, 1993, 1994\ | | 38 | "@(#) Copyright (c) 1988, 1993, 1994\ |
39 | The Regents of the University of California. All rights reserved."); | | 39 | The Regents of the University of California. All rights reserved."); |
40 | #endif /* not lint */ | | 40 | #endif /* not lint */ |
41 | | | 41 | |
42 | #ifndef lint | | 42 | #ifndef lint |
43 | #if 0 | | 43 | #if 0 |
44 | static char sccsid[] = "@(#)cp.c 8.5 (Berkeley) 4/29/95"; | | 44 | static char sccsid[] = "@(#)cp.c 8.5 (Berkeley) 4/29/95"; |
45 | #else | | 45 | #else |
46 | __RCSID("$NetBSD: cp.c,v 1.51 2008/07/20 00:52:39 lukem Exp $"); | | 46 | __RCSID("$NetBSD: cp.c,v 1.52 2009/09/29 13:30:17 pooka Exp $"); |
47 | #endif | | 47 | #endif |
48 | #endif /* not lint */ | | 48 | #endif /* not lint */ |
49 | | | 49 | |
50 | /* | | 50 | /* |
51 | * Cp copies source files to target files. | | 51 | * Cp copies source files to target files. |
52 | * | | 52 | * |
53 | * The global PATH_T structure "to" always contains the path to the | | 53 | * The global PATH_T structure "to" always contains the path to the |
54 | * current target file. Since fts(3) does not change directories, | | 54 | * current target file. Since fts(3) does not change directories, |
55 | * this path can be either absolute or dot-relative. | | 55 | * this path can be either absolute or dot-relative. |
56 | * | | 56 | * |
57 | * The basic algorithm is to initialize "to" and use fts(3) to traverse | | 57 | * The basic algorithm is to initialize "to" and use fts(3) to traverse |
58 | * the file hierarchy rooted in the argument list. A trivial case is the | | 58 | * the file hierarchy rooted in the argument list. A trivial case is the |
59 | * case of 'cp file1 file2'. The more interesting case is the case of | | 59 | * case of 'cp file1 file2'. The more interesting case is the case of |
| @@ -82,27 +82,26 @@ __RCSID("$NetBSD: cp.c,v 1.51 2008/07/20 | | | @@ -82,27 +82,26 @@ __RCSID("$NetBSD: cp.c,v 1.51 2008/07/20 |
82 | } | | 82 | } |
83 | | | 83 | |
84 | static char empty[] = ""; | | 84 | static char empty[] = ""; |
85 | PATH_T to = { .p_end = to.p_path, .target_end = empty }; | | 85 | PATH_T to = { .p_end = to.p_path, .target_end = empty }; |
86 | | | 86 | |
87 | uid_t myuid; | | 87 | uid_t myuid; |
88 | int Hflag, Lflag, Rflag, Pflag, fflag, iflag, pflag, rflag, vflag, Nflag; | | 88 | int Hflag, Lflag, Rflag, Pflag, fflag, iflag, pflag, rflag, vflag, Nflag; |
89 | mode_t myumask; | | 89 | mode_t myumask; |
90 | | | 90 | |
91 | enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE }; | | 91 | enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE }; |
92 | | | 92 | |
93 | int main(int, char *[]); | | 93 | int main(int, char *[]); |
94 | int copy(char *[], enum op, int); | | 94 | int copy(char *[], enum op, int); |
95 | int mastercmp(const FTSENT **, const FTSENT **); | | | |
96 | | | 95 | |
97 | int | | 96 | int |
98 | main(int argc, char *argv[]) | | 97 | main(int argc, char *argv[]) |
99 | { | | 98 | { |
100 | struct stat to_stat, tmp_stat; | | 99 | struct stat to_stat, tmp_stat; |
101 | enum op type; | | 100 | enum op type; |
102 | int ch, fts_options, r, have_trailing_slash; | | 101 | int ch, fts_options, r, have_trailing_slash; |
103 | char *target, **src; | | 102 | char *target, **src; |
104 | | | 103 | |
105 | setprogname(argv[0]); | | 104 | setprogname(argv[0]); |
106 | (void)setlocale(LC_ALL, ""); | | 105 | (void)setlocale(LC_ALL, ""); |
107 | | | 106 | |
108 | Hflag = Lflag = Pflag = Rflag = 0; | | 107 | Hflag = Lflag = Pflag = Rflag = 0; |
| @@ -285,27 +284,27 @@ int | | | @@ -285,27 +284,27 @@ int |
285 | copy(char *argv[], enum op type, int fts_options) | | 284 | copy(char *argv[], enum op type, int fts_options) |
286 | { | | 285 | { |
287 | struct stat to_stat; | | 286 | struct stat to_stat; |
288 | FTS *ftsp; | | 287 | FTS *ftsp; |
289 | FTSENT *curr; | | 288 | FTSENT *curr; |
290 | int base, dne, sval; | | 289 | int base, dne, sval; |
291 | int this_failed, any_failed; | | 290 | int this_failed, any_failed; |
292 | size_t nlen; | | 291 | size_t nlen; |
293 | char *p, *target_mid; | | 292 | char *p, *target_mid; |
294 | | | 293 | |
295 | dne = 0; | | 294 | dne = 0; |
296 | base = 0; /* XXX gcc -Wuninitialized (see comment below) */ | | 295 | base = 0; /* XXX gcc -Wuninitialized (see comment below) */ |
297 | | | 296 | |
298 | if ((ftsp = fts_open(argv, fts_options, mastercmp)) == NULL) | | 297 | if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL) |
299 | err(EXIT_FAILURE, "%s", argv[0]); | | 298 | err(EXIT_FAILURE, "%s", argv[0]); |
300 | /* NOTREACHED */ | | 299 | /* NOTREACHED */ |
301 | for (any_failed = 0; (curr = fts_read(ftsp)) != NULL;) { | | 300 | for (any_failed = 0; (curr = fts_read(ftsp)) != NULL;) { |
302 | this_failed = 0; | | 301 | this_failed = 0; |
303 | switch (curr->fts_info) { | | 302 | switch (curr->fts_info) { |
304 | case FTS_NS: | | 303 | case FTS_NS: |
305 | case FTS_DNR: | | 304 | case FTS_DNR: |
306 | case FTS_ERR: | | 305 | case FTS_ERR: |
307 | warnx("%s: %s", curr->fts_path, | | 306 | warnx("%s: %s", curr->fts_path, |
308 | strerror(curr->fts_errno)); | | 307 | strerror(curr->fts_errno)); |
309 | this_failed = any_failed = 1; | | 308 | this_failed = any_failed = 1; |
310 | continue; | | 309 | continue; |
311 | case FTS_DC: /* Warn, continue. */ | | 310 | case FTS_DC: /* Warn, continue. */ |
| @@ -505,39 +504,13 @@ copy(char *argv[], enum op type, int fts | | | @@ -505,39 +504,13 @@ copy(char *argv[], enum op type, int fts |
505 | this_failed = any_failed = 1; | | 504 | this_failed = any_failed = 1; |
506 | break; | | 505 | break; |
507 | } | | 506 | } |
508 | if (vflag && !this_failed) | | 507 | if (vflag && !this_failed) |
509 | (void)printf("%s -> %s\n", curr->fts_path, to.p_path); | | 508 | (void)printf("%s -> %s\n", curr->fts_path, to.p_path); |
510 | } | | 509 | } |
511 | if (errno) { | | 510 | if (errno) { |
512 | err(EXIT_FAILURE, "fts_read"); | | 511 | err(EXIT_FAILURE, "fts_read"); |
513 | /* NOTREACHED */ | | 512 | /* NOTREACHED */ |
514 | } | | 513 | } |
515 | (void)fts_close(ftsp); | | 514 | (void)fts_close(ftsp); |
516 | return (any_failed); | | 515 | return (any_failed); |
517 | } | | 516 | } |
518 | | | | |
519 | /* | | | |
520 | * mastercmp -- | | | |
521 | * The comparison function for the copy order. The order is to copy | | | |
522 | * non-directory files before directory files. The reason for this | | | |
523 | * is because files tend to be in the same cylinder group as their | | | |
524 | * parent directory, whereas directories tend not to be. Copying the | | | |
525 | * files first reduces seeking. | | | |
526 | */ | | | |
527 | int | | | |
528 | mastercmp(const FTSENT **a, const FTSENT **b) | | | |
529 | { | | | |
530 | int a_info, b_info; | | | |
531 | | | | |
532 | a_info = (*a)->fts_info; | | | |
533 | if (a_info == FTS_ERR || a_info == FTS_NS || a_info == FTS_DNR) | | | |
534 | return (0); | | | |
535 | b_info = (*b)->fts_info; | | | |
536 | if (b_info == FTS_ERR || b_info == FTS_NS || b_info == FTS_DNR) | | | |
537 | return (0); | | | |
538 | if (a_info == FTS_D) | | | |
539 | return (-1); | | | |
540 | if (b_info == FTS_D) | | | |
541 | return (1); | | | |
542 | return (0); | | | |
543 | } | | | |