aboutsummaryrefslogtreecommitdiff
path: root/coreutils/cp.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-08-24 21:46:24 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-08-24 21:46:24 +0000
commit6666ac42a5cd63a8b18ec72f6c1364f31ef53921 (patch)
tree64110c3cfad98cada86b87d1e6059173ca33dbd7 /coreutils/cp.c
parent2062fc415524e966862c60a6e35d03285f366cbb (diff)
downloadbusybox-w32-6666ac42a5cd63a8b18ec72f6c1364f31ef53921.tar.gz
busybox-w32-6666ac42a5cd63a8b18ec72f6c1364f31ef53921.tar.bz2
busybox-w32-6666ac42a5cd63a8b18ec72f6c1364f31ef53921.zip
cp,mv: simpler arg[cv] handling -> smallish code savings
Diffstat (limited to 'coreutils/cp.c')
-rw-r--r--coreutils/cp.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/coreutils/cp.c b/coreutils/cp.c
index 884fbf70f..5b575819c 100644
--- a/coreutils/cp.c
+++ b/coreutils/cp.c
@@ -40,12 +40,16 @@ int cp_main(int argc, char **argv)
40 OPT_L = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3), 40 OPT_L = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3),
41 }; 41 };
42 42
43 // Need at least two arguments
43 // Soft- and hardlinking don't mix 44 // Soft- and hardlinking don't mix
44 // -P and -d are the same (-P is POSIX, -d is GNU) 45 // -P and -d are the same (-P is POSIX, -d is GNU)
45 // -r and -R are the same 46 // -r and -R are the same
46 // -a = -pdR 47 // -a = -pdR
47 opt_complementary = "l--s:s--l:Pd:rR:apdR"; 48 opt_complementary = "-2:l--s:s--l:Pd:rR:apdR";
48 flags = getopt32(argv, FILEUTILS_CP_OPTSTR "arPHL"); 49 flags = getopt32(argv, FILEUTILS_CP_OPTSTR "arPHL");
50 argc -= optind;
51 argv += optind;
52 flags ^= FILEUTILS_DEREFERENCE; /* The sense of this flag was reversed. */
49 /* Default behavior of cp is to dereference, so we don't have to do 53 /* Default behavior of cp is to dereference, so we don't have to do
50 * anything special when we are given -L. 54 * anything special when we are given -L.
51 * The behavior of -H is *almost* like -L, but not quite, so let's 55 * The behavior of -H is *almost* like -L, but not quite, so let's
@@ -60,19 +64,12 @@ int cp_main(int argc, char **argv)
60 } 64 }
61#endif 65#endif
62 66
63 flags ^= FILEUTILS_DEREFERENCE; /* The sense of this flag was reversed. */
64
65 if (optind + 2 > argc) {
66 bb_show_usage();
67 }
68
69 last = argv[argc - 1]; 67 last = argv[argc - 1];
70 argv += optind;
71
72 /* If there are only two arguments and... */ 68 /* If there are only two arguments and... */
73 if (optind + 2 == argc) { 69 if (argc == 2) {
74 s_flags = cp_mv_stat2(*argv, &source_stat, 70 s_flags = cp_mv_stat2(*argv, &source_stat,
75 (flags & FILEUTILS_DEREFERENCE) ? stat : lstat); 71 (flags & FILEUTILS_DEREFERENCE) ? stat : lstat);
72 /* TODO: does coreutils cp exit? "cp BAD GOOD dir"... */
76 if (s_flags < 0) 73 if (s_flags < 0)
77 return EXIT_FAILURE; 74 return EXIT_FAILURE;
78 d_flags = cp_mv_stat(last, &dest_stat); 75 d_flags = cp_mv_stat(last, &dest_stat);
@@ -85,19 +82,24 @@ int cp_main(int argc, char **argv)
85 ((flags & FILEUTILS_RECUR) && (s_flags & 2) && !d_flags) 82 ((flags & FILEUTILS_RECUR) && (s_flags & 2) && !d_flags)
86 ) { 83 ) {
87 /* ...do a simple copy. */ 84 /* ...do a simple copy. */
88 dest = xstrdup(last); 85 dest = last;
89 goto DO_COPY; /* Note: optind+2==argc implies argv[1]==last below. */ 86 goto DO_COPY; /* NB: argc==2 -> *++argv==last */
90 } 87 }
91 } 88 }
92 89
93 do { 90 while (1) {
94 dest = concat_path_file(last, bb_get_last_path_component(*argv)); 91 dest = concat_path_file(last, bb_get_last_path_component(*argv));
95 DO_COPY: 92 DO_COPY:
96 if (copy_file(*argv, dest, flags) < 0) { 93 if (copy_file(*argv, dest, flags) < 0) {
97 status = 1; 94 status = 1;
98 } 95 }
96 if (*++argv == last) {
97 /* possibly leaking dest... */
98 break;
99 }
99 free((void*)dest); 100 free((void*)dest);
100 } while (*++argv != last); 101 }
101 102
103 /* Exit. We are NOEXEC, not NOFORK. We do exit at the end of main() */
102 return status; 104 return status;
103} 105}