diff options
author | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-10-21 23:40:20 +0000 |
---|---|---|
committer | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-10-21 23:40:20 +0000 |
commit | 05e73015aac1bc64cd889062328598c224f190de (patch) | |
tree | a6d0fa74d59e67d1570c54157f5ebcc47b4522d0 /coreutils/cp.c | |
parent | 2f36b989836df0f58dada461a7d7da608182cc02 (diff) | |
download | busybox-w32-05e73015aac1bc64cd889062328598c224f190de.tar.gz busybox-w32-05e73015aac1bc64cd889062328598c224f190de.tar.bz2 busybox-w32-05e73015aac1bc64cd889062328598c224f190de.zip |
cp: add support for -s, -l. Fix free(nonmalloc) bug.
Add doc on POSIX's rules on -i and -f (insane!).
ln: make "ln dangling_symlink new_link" work.
git-svn-id: svn://busybox.net/trunk/busybox@16419 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'coreutils/cp.c')
-rw-r--r-- | coreutils/cp.c | 72 |
1 files changed, 27 insertions, 45 deletions
diff --git a/coreutils/cp.c b/coreutils/cp.c index fabfe58e0..47ad85ecf 100644 --- a/coreutils/cp.c +++ b/coreutils/cp.c | |||
@@ -7,8 +7,6 @@ | |||
7 | * Licensed under GPL v2 or later, see file LICENSE in this tarball for details. | 7 | * Licensed under GPL v2 or later, see file LICENSE in this tarball for details. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | /* BB_AUDIT SUSv3 defects - unsupported options -H, -L, and -P. */ | ||
11 | /* BB_AUDIT GNU defects - only extension options supported are -a and -d. */ | ||
12 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/cp.html */ | 10 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/cp.html */ |
13 | 11 | ||
14 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | 12 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) |
@@ -16,15 +14,6 @@ | |||
16 | * Size reduction. | 14 | * Size reduction. |
17 | */ | 15 | */ |
18 | 16 | ||
19 | #include <sys/types.h> | ||
20 | #include <sys/stat.h> | ||
21 | #include <unistd.h> | ||
22 | #include <fcntl.h> | ||
23 | #include <utime.h> | ||
24 | #include <errno.h> | ||
25 | #include <dirent.h> | ||
26 | #include <stdlib.h> | ||
27 | #include <assert.h> | ||
28 | #include "busybox.h" | 17 | #include "busybox.h" |
29 | #include "libcoreutils/coreutils.h" | 18 | #include "libcoreutils/coreutils.h" |
30 | 19 | ||
@@ -38,31 +27,26 @@ int cp_main(int argc, char **argv) | |||
38 | int d_flags; | 27 | int d_flags; |
39 | int flags; | 28 | int flags; |
40 | int status = 0; | 29 | int status = 0; |
30 | enum { | ||
31 | OPT_a = 1 << (sizeof(FILEUTILS_CP_OPTSTR)-1), | ||
32 | OPT_r = 1 << (sizeof(FILEUTILS_CP_OPTSTR)), | ||
33 | OPT_P = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+1), | ||
34 | OPT_H = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+2), | ||
35 | OPT_L = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3), | ||
36 | }; | ||
41 | 37 | ||
42 | flags = getopt32(argc, argv, "pdRfiarPHL"); | 38 | // Soft- and hardlinking don't mix |
43 | 39 | // -P and -d are the same (-P is POSIX, -d is GNU) | |
44 | if (flags & 32) { | 40 | // -r and -R are the same |
45 | flags |= (FILEUTILS_PRESERVE_STATUS | FILEUTILS_RECUR | FILEUTILS_DEREFERENCE); | 41 | // -a = -pdR |
46 | } | 42 | opt_complementary = "?:l--s:s--l:Pd:rR:apdR"; |
47 | if (flags & 64) { | 43 | flags = getopt32(argc, argv, FILEUTILS_CP_OPTSTR "arPHL"); |
48 | /* Make -r a synonym for -R, | ||
49 | * -r was marked as obsolete in SUSv3, but is included for compatibility | ||
50 | */ | ||
51 | flags |= FILEUTILS_RECUR; | ||
52 | } | ||
53 | if (flags & 128) { | ||
54 | /* Make -P a synonym for -d, | ||
55 | * -d is the GNU option while -P is the POSIX 2003 option | ||
56 | */ | ||
57 | flags |= FILEUTILS_DEREFERENCE; | ||
58 | } | ||
59 | /* Default behavior of cp is to dereference, so we don't have to do | 44 | /* Default behavior of cp is to dereference, so we don't have to do |
60 | * anything special when we are given -L. | 45 | * anything special when we are given -L. |
61 | * The behavior of -H is *almost* like -L, but not quite, so let's | 46 | * The behavior of -H is *almost* like -L, but not quite, so let's |
62 | * just ignore it too for fun. | 47 | * just ignore it too for fun. |
63 | if (flags & 256 || flags & 512) { | 48 | if (flags & OPT_L) ... |
64 | ; | 49 | if (flags & OPT_H) ... // deref command-line params only |
65 | } | ||
66 | */ | 50 | */ |
67 | 51 | ||
68 | flags ^= FILEUTILS_DEREFERENCE; /* The sense of this flag was reversed. */ | 52 | flags ^= FILEUTILS_DEREFERENCE; /* The sense of this flag was reversed. */ |
@@ -78,33 +62,31 @@ int cp_main(int argc, char **argv) | |||
78 | if (optind + 2 == argc) { | 62 | if (optind + 2 == argc) { |
79 | s_flags = cp_mv_stat2(*argv, &source_stat, | 63 | s_flags = cp_mv_stat2(*argv, &source_stat, |
80 | (flags & FILEUTILS_DEREFERENCE) ? stat : lstat); | 64 | (flags & FILEUTILS_DEREFERENCE) ? stat : lstat); |
81 | if ((s_flags < 0) || ((d_flags = cp_mv_stat(last, &dest_stat)) < 0)) { | 65 | if (s_flags < 0) |
82 | exit(EXIT_FAILURE); | 66 | return EXIT_FAILURE; |
83 | } | 67 | d_flags = cp_mv_stat(last, &dest_stat); |
68 | if (d_flags < 0) | ||
69 | return EXIT_FAILURE; | ||
70 | |||
84 | /* ...if neither is a directory or... */ | 71 | /* ...if neither is a directory or... */ |
85 | if ( !((s_flags | d_flags) & 2) || | 72 | if ( !((s_flags | d_flags) & 2) || |
86 | /* ...recursing, the 1st is a directory, and the 2nd doesn't exist... */ | 73 | /* ...recursing, the 1st is a directory, and the 2nd doesn't exist... */ |
87 | /* ((flags & FILEUTILS_RECUR) && (s_flags & 2) && !d_flags) */ | 74 | ((flags & FILEUTILS_RECUR) && (s_flags & 2) && !d_flags) |
88 | /* Simplify the above since FILEUTILS_RECUR >> 1 == 2. */ | ||
89 | ((((flags & FILEUTILS_RECUR) >> 1) & s_flags) && !d_flags) | ||
90 | ) { | 75 | ) { |
91 | /* ...do a simple copy. */ | 76 | /* ...do a simple copy. */ |
92 | dest = last; | 77 | dest = xstrdup(last); |
93 | goto DO_COPY; /* Note: optind+2==argc implies argv[1]==last below. */ | 78 | goto DO_COPY; /* Note: optind+2==argc implies argv[1]==last below. */ |
94 | } | 79 | } |
95 | } | 80 | } |
96 | 81 | ||
97 | do { | 82 | do { |
98 | dest = concat_path_file(last, bb_get_last_path_component(*argv)); | 83 | dest = concat_path_file(last, bb_get_last_path_component(*argv)); |
99 | DO_COPY: | 84 | DO_COPY: |
100 | if (copy_file(*argv, dest, flags) < 0) { | 85 | if (copy_file(*argv, dest, flags) < 0) { |
101 | status = 1; | 86 | status = 1; |
102 | } | 87 | } |
103 | if (*++argv == last) { | 88 | free((void*)dest); |
104 | break; | 89 | } while (*++argv != last); |
105 | } | ||
106 | free((void *) dest); | ||
107 | } while (1); | ||
108 | 90 | ||
109 | exit(status); | 91 | return status; |
110 | } | 92 | } |