Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/coreutils/mv.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/coreutils/mv.c
r1765 r2725 6 6 * SELinux support by Yuichi Nakamura <ynakam@hitachisoft.jp> 7 7 * 8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.8 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 9 9 */ 10 10 … … 14 14 */ 15 15 16 #include <sys/types.h>17 #include <sys/stat.h>18 #include <dirent.h>19 #include <getopt.h> /* struct option */20 16 #include "libbb.h" 21 17 #include "libcoreutils/coreutils.h" 18 19 //usage:#define mv_trivial_usage 20 //usage: "[-fin] SOURCE DEST\n" 21 //usage: "or: mv [-fin] SOURCE... DIRECTORY" 22 //usage:#define mv_full_usage "\n\n" 23 //usage: "Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY\n" 24 //usage: "\nOptions:" 25 //usage: "\n -f Don't prompt before overwriting" 26 //usage: "\n -i Interactive, prompt before overwrite" 27 //usage: "\n -n Don't overwrite an existing file" 28 //usage: 29 //usage:#define mv_example_usage 30 //usage: "$ mv /tmp/foo /bin/bar\n" 22 31 23 32 #if ENABLE_FEATURE_MV_LONG_OPTIONS … … 25 34 "interactive\0" No_argument "i" 26 35 "force\0" No_argument "f" 36 "no-clobber\0" No_argument "n" 27 37 ; 28 38 #endif … … 30 40 #define OPT_FILEUTILS_FORCE 1 31 41 #define OPT_FILEUTILS_INTERACTIVE 2 42 #define OPT_FILEUTILS_NOCLOBBER 4 32 43 33 static const char fmt[] ALIGN1 = 34 "cannot overwrite %sdirectory with %sdirectory"; 35 36 int mv_main(int argc, char **argv); 44 int mv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 37 45 int mv_main(int argc, char **argv) 38 46 { … … 40 48 const char *last; 41 49 const char *dest; 42 unsigned longflags;50 unsigned flags; 43 51 int dest_exists; 44 52 int status = 0; … … 48 56 applet_long_options = mv_longopts; 49 57 #endif 50 opt_complementary = "f-i:i-f"; 51 flags = getopt32(argv, "fi"); 52 if (optind + 2 > argc) { 53 bb_show_usage(); 54 } 58 /* Need at least two arguments. 59 * If more than one of -f, -i, -n is specified , only the final one 60 * takes effect (it unsets previous options). */ 61 opt_complementary = "-2:f-in:i-fn:n-fi"; 62 flags = getopt32(argv, "fin"); 63 argc -= optind; 64 argv += optind; 65 last = argv[argc - 1]; 55 66 56 last = argv[argc - 1]; 57 argv += optind; 58 59 if (optind + 2 == argc) { 67 if (argc == 2) { 60 68 dest_exists = cp_mv_stat(last, &dest_stat); 61 69 if (dest_exists < 0) { 62 return 1;70 return EXIT_FAILURE; 63 71 } 64 72 65 if (!(dest_exists & 2)) { 73 if (!(dest_exists & 2)) { /* last is not a directory */ 66 74 dest = last; 67 75 goto DO_MOVE; … … 70 78 71 79 do { 72 dest = concat_path_file(last, bb_get_last_path_component (*argv));80 dest = concat_path_file(last, bb_get_last_path_component_strip(*argv)); 73 81 dest_exists = cp_mv_stat(dest, &dest_stat); 74 82 if (dest_exists < 0) { … … 76 84 } 77 85 78 DO_MOVE: 79 80 if (dest_exists && !(flags & OPT_FILEUTILS_FORCE) && 81 ((access(dest, W_OK) < 0 && isatty(0)) || 82 (flags & OPT_FILEUTILS_INTERACTIVE))) { 83 if (fprintf(stderr, "mv: overwrite '%s'? ", dest) < 0) { 84 goto RET_1; /* Ouch! fprintf failed! */ 85 } 86 if (!bb_ask_confirmation()) { 86 DO_MOVE: 87 if (dest_exists) { 88 if (flags & OPT_FILEUTILS_NOCLOBBER) 87 89 goto RET_0; 90 if (!(flags & OPT_FILEUTILS_FORCE) 91 && ((access(dest, W_OK) < 0 && isatty(0)) 92 || (flags & OPT_FILEUTILS_INTERACTIVE)) 93 ) { 94 if (fprintf(stderr, "mv: overwrite '%s'? ", dest) < 0) { 95 goto RET_1; /* Ouch! fprintf failed! */ 96 } 97 if (!bb_ask_confirmation()) { 98 goto RET_0; 99 } 88 100 } 89 101 } 102 90 103 if (rename(*argv, dest) < 0) { 91 104 struct stat source_stat; 92 105 int source_exists; 93 106 94 if (errno != EXDEV || 95 (source_exists = cp_mv_stat(*argv, &source_stat)) < 1) { 96 bb_perror_msg("cannot rename '%s'", *argv); 107 if (errno != EXDEV 108 || (source_exists = cp_mv_stat2(*argv, &source_stat, lstat)) < 1 109 ) { 110 bb_perror_msg("can't rename '%s'", *argv); 97 111 } else { 112 static const char fmt[] ALIGN1 = 113 "can't overwrite %sdirectory with %sdirectory"; 114 98 115 if (dest_exists) { 99 116 if (dest_exists == 3) { … … 109 126 } 110 127 if (unlink(dest) < 0) { 111 bb_perror_msg("can not remove '%s'", dest);128 bb_perror_msg("can't remove '%s'", dest); 112 129 goto RET_1; 113 130 } 114 131 } 132 /* FILEUTILS_RECUR also prevents nasties like 133 * "read from device and write contents to dst" 134 * instead of "create same device node" */ 115 135 copy_flag = FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS; 116 136 #if ENABLE_SELINUX 117 137 copy_flag |= FILEUTILS_PRESERVE_SECURITY_CONTEXT; 118 138 #endif 119 if ((copy_file(*argv, dest, copy_flag) >= 0) && 120 (remove_file(*argv, FILEUTILS_RECUR | FILEUTILS_FORCE) >= 0)) { 139 if ((copy_file(*argv, dest, copy_flag) >= 0) 140 && (remove_file(*argv, FILEUTILS_RECUR | FILEUTILS_FORCE) >= 0) 141 ) { 121 142 goto RET_0; 122 143 } 123 144 } 124 RET_1:145 RET_1: 125 146 status = 1; 126 147 } 127 RET_0:148 RET_0: 128 149 if (dest != last) { 129 150 free((void *) dest);
Note:
See TracChangeset
for help on using the changeset viewer.