Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/coreutils/cp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 20  Line 20 
20    
21  /* This is a NOEXEC applet. Be very careful! */  /* This is a NOEXEC applet. Be very careful! */
22    
   
23  int cp_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;  int cp_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
24  int cp_main(int argc, char **argv)  int cp_main(int argc, char **argv)
25  {  {
# Line 31  int cp_main(int argc, char **argv) Line 30  int cp_main(int argc, char **argv)
30   int s_flags;   int s_flags;
31   int d_flags;   int d_flags;
32   int flags;   int flags;
33   int status = 0;   int status;
34   enum {   enum {
35   OPT_a = 1 << (sizeof(FILEUTILS_CP_OPTSTR)-1),   OPT_a = 1 << (sizeof(FILEUTILS_CP_OPTSTR)-1),
36   OPT_r = 1 << (sizeof(FILEUTILS_CP_OPTSTR)),   OPT_r = 1 << (sizeof(FILEUTILS_CP_OPTSTR)),
37   OPT_P = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+1),   OPT_P = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+1),
38   OPT_H = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+2),   OPT_v = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+2),
39    #if ENABLE_FEATURE_CP_LONG_OPTIONS
40     OPT_parents = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3),
41    #endif
42   };   };
43    
44   // Need at least two arguments   // Need at least two arguments
# Line 45  int cp_main(int argc, char **argv) Line 47  int cp_main(int argc, char **argv)
47   // -r and -R are the same   // -r and -R are the same
48   // -R (and therefore -r) turns on -d (coreutils does this)   // -R (and therefore -r) turns on -d (coreutils does this)
49   // -a = -pdR   // -a = -pdR
50   opt_complementary = "-2:l--s:s--l:Pd:rRd:Rd:apdR:HL";   opt_complementary = "-2:l--s:s--l:Pd:rRd:Rd:apdR";
51   flags = getopt32(argv, FILEUTILS_CP_OPTSTR "arPH");  #if ENABLE_FEATURE_CP_LONG_OPTIONS
52     applet_long_options =
53     "archive\0"        No_argument "a"
54     "force\0"          No_argument "f"
55     "interactive\0"    No_argument "i"
56     "link\0"           No_argument "l"
57     "dereference\0"    No_argument "L"
58     "no-dereference\0" No_argument "P"
59     "recursive\0"      No_argument "R"
60     "symbolic-link\0"  No_argument "s"
61     "verbose\0"        No_argument "v"
62     "parents\0"        No_argument "\xff"
63     ;
64    #endif
65     // -v (--verbose) is ignored
66     flags = getopt32(argv, FILEUTILS_CP_OPTSTR "arPv");
67     /* Options of cp from GNU coreutils 6.10:
68     * -a, --archive
69     * -f, --force
70     * -i, --interactive
71     * -l, --link
72     * -L, --dereference
73     * -P, --no-dereference
74     * -R, -r, --recursive
75     * -s, --symbolic-link
76     * -v, --verbose
77     * -H follow command-line symbolic links in SOURCE
78     * -d same as --no-dereference --preserve=links
79     * -p same as --preserve=mode,ownership,timestamps
80     * -c same as --preserve=context
81     * --parents
82     * use full source file name under DIRECTORY
83     * NOT SUPPORTED IN BBOX:
84     * --backup[=CONTROL]
85     * make a backup of each existing destination file
86     * -b like --backup but does not accept an argument
87     * --copy-contents
88     * copy contents of special files when recursive
89     * --preserve[=ATTR_LIST]
90     * preserve attributes (default: mode,ownership,timestamps),
91     * if possible additional attributes: security context,links,all
92     * --no-preserve=ATTR_LIST
93     * --remove-destination
94     * remove  each existing destination file before attempting to open
95     * --sparse=WHEN
96     * control creation of sparse files
97     * --strip-trailing-slashes
98     * remove any trailing slashes from each SOURCE argument
99     * -S, --suffix=SUFFIX
100     * override the usual backup suffix
101     * -t, --target-directory=DIRECTORY
102     * copy all SOURCE arguments into DIRECTORY
103     * -T, --no-target-directory
104     * treat DEST as a normal file
105     * -u, --update
106     * copy only when the SOURCE file is newer than the destination
107     * file or when the destination file is missing
108     * -x, --one-file-system
109     * stay on this file system
110     * -Z, --context=CONTEXT
111     * (SELinux) set SELinux security context of copy to CONTEXT
112     */
113   argc -= optind;   argc -= optind;
114   argv += optind;   argv += optind;
115   flags ^= FILEUTILS_DEREFERENCE; /* the sense of this flag was reversed */   /* Reverse this bit. If there is -d, bit is not set: */
116     flags ^= FILEUTILS_DEREFERENCE;
117   /* coreutils 6.9 compat:   /* coreutils 6.9 compat:
118   * by default, "cp" derefs symlinks (creates regular dest files),   * by default, "cp" derefs symlinks (creates regular dest files),
119   * but "cp -R" does not. We switch off deref if -r or -R (see above).   * but "cp -R" does not. We switch off deref if -r or -R (see above).
120   * However, "cp -RL" must still deref symlinks: */   * However, "cp -RL" must still deref symlinks: */
121   if (flags & FILEUTILS_DEREF_SOFTLINK) /* -L */   if (flags & FILEUTILS_DEREF_SOFTLINK) /* -L */
122   flags |= FILEUTILS_DEREFERENCE;   flags |= FILEUTILS_DEREFERENCE;
  /* The behavior of -H is *almost* like -L, but not quite, so let's  
  * just ignore it too for fun. TODO.  
  if (flags & OPT_H) ... // deref command-line params only  
  */  
123    
124  #if ENABLE_SELINUX  #if ENABLE_SELINUX
125   if (flags & FILEUTILS_PRESERVE_SECURITY_CONTEXT) {   if (flags & FILEUTILS_PRESERVE_SECURITY_CONTEXT) {
# Line 67  int cp_main(int argc, char **argv) Line 127  int cp_main(int argc, char **argv)
127   }   }
128  #endif  #endif
129    
130     status = EXIT_SUCCESS;
131   last = argv[argc - 1];   last = argv[argc - 1];
132   /* If there are only two arguments and...  */   /* If there are only two arguments and...  */
133   if (argc == 2) {   if (argc == 2) {
134   s_flags = cp_mv_stat2(*argv, &source_stat,   s_flags = cp_mv_stat2(*argv, &source_stat,
135        (flags & FILEUTILS_DEREFERENCE) ? stat : lstat);   (flags & FILEUTILS_DEREFERENCE) ? stat : lstat);
136   if (s_flags < 0)   if (s_flags < 0)
137   return EXIT_FAILURE;   return EXIT_FAILURE;
138   d_flags = cp_mv_stat(last, &dest_stat);   d_flags = cp_mv_stat(last, &dest_stat);
139   if (d_flags < 0)   if (d_flags < 0)
140   return EXIT_FAILURE;   return EXIT_FAILURE;
141    
142   /* ...if neither is a directory or...  */  #if ENABLE_FEATURE_CP_LONG_OPTIONS
143   if ( !((s_flags | d_flags) & 2) ||   if (flags & OPT_parents) {
144   /* ...recursing, the 1st is a directory, and the 2nd doesn't exist... */   if (!(d_flags & 2)) {
145   ((flags & FILEUTILS_RECUR) && (s_flags & 2) && !d_flags)   bb_error_msg_and_die("with --parents, the destination must be a directory");
146     }
147     }
148    #endif
149    
150     /* ...if neither is a directory...  */
151     if (!((s_flags | d_flags) & 2)
152        /* ...or: recursing, the 1st is a directory, and the 2nd doesn't exist... */
153     || ((flags & FILEUTILS_RECUR) && (s_flags & 2) && !d_flags)
154   ) {   ) {
155   /* ...do a simple copy.  */   /* Do a simple copy */
156   dest = last;   dest = last;
157   goto DO_COPY; /* NB: argc==2 -> *++argv==last */   goto DO_COPY; /* NB: argc==2 -> *++argv==last */
158   }   }
159   }   }
160    
161   while (1) {   while (1) {
162    #if ENABLE_FEATURE_CP_LONG_OPTIONS
163     if (flags & OPT_parents) {
164     char *dest_dup;
165     char *dest_dir;
166     dest = concat_path_file(last, *argv);
167     dest_dup = xstrdup(dest);
168     dest_dir = dirname(dest_dup);
169     if (bb_make_directory(dest_dir, -1, FILEUTILS_RECUR)) {
170     return EXIT_FAILURE;
171     }
172     free(dest_dup);
173     goto DO_COPY;
174     }
175    #endif
176   dest = concat_path_file(last, bb_get_last_path_component_strip(*argv));   dest = concat_path_file(last, bb_get_last_path_component_strip(*argv));
177   DO_COPY:   DO_COPY:
178   if (copy_file(*argv, dest, flags) < 0) {   if (copy_file(*argv, dest, flags) < 0) {
179   status = 1;   status = EXIT_FAILURE;
180   }   }
181   if (*++argv == last) {   if (*++argv == last) {
182   /* possibly leaking dest... */   /* possibly leaking dest... */
183   break;   break;
184   }   }
185     /* don't move up: dest may be == last and not malloced! */
186   free((void*)dest);   free((void*)dest);
187   }   }
188    

Legend:
Removed from v.983  
changed lines
  Added in v.984