Changeset 1551 in kBuild for trunk/src/kmk/kmkbuiltin/rm.c
- Timestamp:
- Apr 23, 2008 12:40:15 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kmkbuiltin/rm.c
r1550 r1551 71 71 # define IS_SLASH(ch) ( (ch) == '/' || (ch) == '\\' ) 72 72 # define HAVE_DOS_PATHS 1 73 # define DEFAULT_ REQUIRED_R_DEPTH 273 # define DEFAULT_PROTECTION_DEPTH 1 74 74 #else 75 75 # define IS_SLASH(ch) ( (ch) == '/' ) 76 76 # undef HAVE_DOS_PATHS 77 # define DEFAULT_ REQUIRED_R_DEPTH 377 # define DEFAULT_PROTECTION_DEPTH 2 78 78 #endif 79 79 … … 92 92 #endif 93 93 94 static int protectionflag ;94 static int protectionflag, fullprotectionflag, protectiondepth; 95 95 static int dflag, eval, fflag, iflag, Pflag, vflag, Wflag, stdin_ok; 96 96 static uid_t uid; … … 103 103 { "version", no_argument, 0, 262 }, 104 104 { "disable-protection", no_argument, 0, 263 }, 105 { "enable-protection", no_argument, 0, 264 }, 106 { "enable-full-protection", no_argument, 0, 265 }, 107 { "disable-full-protection", no_argument, 0, 266 }, 108 { "protection-depth", required_argument, 0, 267 }, 105 109 { 0, 0, 0, 0 }, 106 110 }; … … 111 115 static void rm_file(char **); 112 116 static int rm_overwrite(char *, struct stat *); 113 static void rm_tree(char ** , int);117 static void rm_tree(char **); 114 118 static int count_path_components(const char *); 119 static int set_protection_depth(const char *); 115 120 static int usage(FILE *); 116 121 … … 128 133 { 129 134 int ch, rflag; 135 int i; 130 136 131 137 /* reinitialize globals */ 132 138 argv0 = argv[0]; 133 139 dflag = eval = fflag = iflag = Pflag = vflag = Wflag = stdin_ok = 0; 140 fullprotectionflag = 0; 134 141 protectionflag = 1; 142 protectiondepth = DEFAULT_PROTECTION_DEPTH; 135 143 uid = 0; 136 144 … … 143 151 144 152 Pflag = rflag = 0; 145 while ((ch = getopt_long(argc, argv, "dfiPR rvW", long_options, NULL)) != -1)153 while ((ch = getopt_long(argc, argv, "dfiPRvW", long_options, NULL)) != -1) 146 154 switch(ch) { 147 155 case 'd': … … 162 170 #if 0 163 171 case 'r': /* Compatibility. */ 164 #endif 172 #endif 165 173 rflag = 1; 166 174 break; … … 181 189 protectionflag = 0; 182 190 break; 191 case 264: 192 protectionflag = 1; 193 break; 194 case 265: 195 fullprotectionflag = 1; 196 break; 197 case 266: 198 fullprotectionflag = 0; 199 break; 200 case 267: 201 set_protection_depth(optarg); 202 break; 183 203 case '?': 184 204 default: … … 194 214 } 195 215 216 /* Search the environment for option overrides (protection). */ 217 #define STR_SIZE_PAIR(str) str, sizeof(str) - 1 218 for (i = 0; envp[i]; i++) { 219 if (!strncmp(envp[i], "KMK_RM_", sizeof("KMK_RM_") - 1)) { 220 if (!strncmp(envp[i], STR_SIZE_PAIR("KMK_RM_PROTECTION_DEPTH="))) { 221 const char *val = envp[i] + sizeof("KMK_RM_PROTECTION_DEPTH=") - 1; 222 if (set_protection_depth(val)) 223 return eval; 224 } else if (!strncmp(envp[i], STR_SIZE_PAIR("KMK_RM_DISABLE_PROTECTION="))) { 225 if (protectionflag >= 0) 226 protectionflag = 0; 227 } else if (!strncmp(envp[i], STR_SIZE_PAIR("KMK_RM_ENABLE_PROTECTION="))) { 228 protectionflag = -1; 229 } else if (!strncmp(envp[i], STR_SIZE_PAIR("KMK_RM_DISABLE_FULL_PROTECTION="))) { 230 if (fullprotectionflag >= 0) 231 fullprotectionflag = 0; 232 } else if (!strncmp(envp[i], STR_SIZE_PAIR("KMK_RM_ENABLE_FULL_PROTECTION="))) { 233 fullprotectionflag = protectionflag = -1; 234 } 235 } 236 } 237 if (fullprotectionflag) 238 protectionflag = 1; 239 #undef STR_SIZE_PAIR 240 196 241 checkdot(argv); 197 242 uid = geteuid(); … … 199 244 if (*argv) { 200 245 stdin_ok = isatty(STDIN_FILENO); 201 if (rflag) { 202 /* 203 * Get options from the environment before doing rm_tree(). 204 */ 205 int required_r_depth = DEFAULT_REQUIRED_R_DEPTH; 206 int i; 207 for (i = 0; envp[i]; i++) { 208 if (!strncmp(envp[i], "KMK_RM_=", sizeof("KMK_RM_=") - 1)) { 209 if (!strncmp(envp[i], "KMK_RM_PROTECTION_DEPTH=", sizeof("KMK_RM_PROTECTION_DEPTH=") - 1)) { 210 char *ignore; 211 const char *val = envp[i] + sizeof("KMK_RM_PROTECTION_DEPTH=") - 1; 212 required_r_depth = isdigit(*val) ? strtol(val, &ignore, 0) : count_path_components(val); 213 if (required_r_depth < 1) 214 required_r_depth = DEFAULT_REQUIRED_R_DEPTH; 215 } else if (!strcmp(envp[i], "KMK_RM_DISABLE_PROTECTION=1")) { 216 protectionflag = 0; 217 } 218 } 219 } 220 221 if (!eval) 222 rm_tree(argv, required_r_depth); 223 } else { 246 if (rflag) 247 rm_tree(argv); 248 else 224 249 rm_file(argv); 225 } 226 } 227 250 } 251 252 return eval; 253 } 254 255 /** 256 * Sets protectiondepth according to the option argument. 257 * 258 * @returns eval, that is 0 on success and non-zero on failure 259 * 260 * @param val The value. 261 */ 262 static int 263 set_protection_depth(const char *val) 264 { 265 /* skip leading blanks, they don't count either way. */ 266 while (isspace(*val)) 267 val++; 268 269 /* number or path? */ 270 if (!isdigit(*val) || strpbrk(val, ":/\\")) { 271 protectiondepth = count_path_components(val); 272 } else { 273 char *more = 0; 274 protectiondepth = strtol(val, &more, 0); 275 if (protectiondepth != 0 && more) { 276 /* trailing space is harmless. */ 277 while (isspace(*more)) 278 more++; 279 } 280 if (!protectiondepth || val == more || *more) 281 return eval = errx(1, "bogus protection depth: %s", val); 282 } 283 284 if (protectiondepth < 1) 285 return eval = errx(1, "bogus protection depth: %s", val); 228 286 return eval; 229 287 } … … 235 293 * etc = 1 236 294 * etc/ = 1 237 * etc/x11 = 2 295 * etc/x11 = 2 238 296 * and so and and so forth. 239 297 */ … … 274 332 275 333 /** 276 * Parses the specified path counting the number of components 334 * Parses the specified path counting the number of components 277 335 * relative to root. 278 336 * 279 * We don't check symbolic links and such, just some simple and cheap 337 * We don't check symbolic links and such, just some simple and cheap 280 338 * path parsing. 281 339 * … … 296 354 if (IS_SLASH(path[0]) && IS_SLASH(path[1]) && !IS_SLASH(path[2])) { 297 355 /* skip the root - UNC */ 298 path += 3; 356 path += 3; 299 357 while (!IS_SLASH(*path) && *path) /* server name */ 300 358 path++; … … 314 372 315 373 if (IS_SLASH(path[drive_letter ? 2 : 0])) { 316 /* 374 /* 317 375 * Relative path, must count cwd depth first. 318 376 */ … … 357 415 #endif 358 416 359 /* 417 /* 360 418 * We're now past any UNC or drive letter crap, possibly positioned 361 419 * at the root slash or at the start of a path component at the … … 367 425 368 426 /** 369 * Protect the upper layers of the file system against accidental 427 * Protect the upper layers of the file system against accidental 370 428 * or malicious deletetion attempt from within a makefile. 371 429 * 372 430 * @param path The path to check. 373 * @param required_depth The minimum number of components in the 431 * @param required_depth The minimum number of components in the 374 432 * path counting from the root. 375 433 * 376 * @returns 0 on success. 434 * @returns 0 on success. 377 435 * On failure an error is printed, eval is set and -1 is returned. 378 436 */ … … 396 454 397 455 static void 398 rm_tree(char **argv , int required_r_depth)456 rm_tree(char **argv) 399 457 { 400 458 FTS *fts; … … 405 463 406 464 /* 407 * Check up front before anything is deleted. This will not catch 465 * Check up front before anything is deleted. This will not catch 408 466 * everything, but we'll check the individual items later. 409 467 */ … … 411 469 int i; 412 470 for (i = 0; argv[i]; i++) { 413 if (enforce_protection(argv[i], required_r_depth))471 if (enforce_protection(argv[i], protectiondepth + 1)) 414 472 return; 415 473 } … … 492 550 } 493 551 494 /* 552 /* 495 553 * Protect against deleting root files and directories. 496 554 */ 497 if (protectionflag && enforce_protection(p->fts_accpath, required_r_depth)) {555 if (protectionflag && enforce_protection(p->fts_accpath, protectiondepth + 1)) { 498 556 fts_close(fts); 499 557 return; … … 583 641 int rval; 584 642 char *f; 643 644 /* 645 * Check up front before anything is deleted. 646 */ 647 if (fullprotectionflag) { 648 int i; 649 for (i = 0; argv[i]; i++) { 650 if (enforce_protection(argv[i], protectiondepth + 1)) 651 return; 652 } 653 } 585 654 586 655 /* … … 824 893 usage(FILE *pf) 825 894 { 826 fprintf(pf, 827 "usage: %s [ -f | -i] [-dPRvW] [--disable-protection] file ...\n"895 fprintf(pf, 896 "usage: %s [options] file ...\n" 828 897 " or: %s --help\n" 829 898 " or: %s --version\n" … … 847 916 " Undelete without files.\n" 848 917 " --disable-protection\n" 849 " Will disable the protection file protection applied by -R.\n" 918 " Will disable the protection file protection applied with -R.\n" 919 " --enable-protection\n" 920 " Will enable the protection file protection applied with -R.\n" 921 " --enable-full-protection\n" 922 " Will enable the protection file protection for all operations.\n" 923 " --disable-full-protection\n" 924 " Will disable the protection file protection for all operations.\n" 925 " --protection-depth\n" 926 " Number or path indicating the file protection depth. Default: %d\n" 850 927 "\n" 851 928 "Environment:\n" 852 929 " KMK_RM_DISABLE_PROTECTION\n" 853 " Same as --disable-protection.\n" 930 " Same as --disable-protection. Overrides command line.\n" 931 " KMK_RM_ENABLE_PROTECTION\n" 932 " Same as --enable-protection. Overrides everyone else.\n" 933 " KMK_RM_ENABLE_FULL_PROTECTION\n" 934 " Same as --enable-full-protection. Overrides everyone else.\n" 935 " KMK_RM_DISABLE_FULL_PROTECTION\n" 936 " Same as --disable-full-protection. Overrides command line.\n" 854 937 " KMK_RM_PROTECTION_DEPTH\n" 855 " Changes the protection depth, path or number. Default: %d\n"938 " Same as --protection-depth. Overrides command line.\n" 856 939 "\n" 857 940 "The file protection of the top %d layers of the file hierarchy is there\n" 858 941 "to try prevent makefiles from doing bad things to your system. This\n" 859 942 "protection is not bulletproof, but should help prevent you from shooting\n" 860 "yourself in the foot. Not that it does NOT apply to normal file removal.\n"943 "yourself in the foot.\n" 861 944 , 862 g_progname, g_progname, g_progname, 863 DEFAULT_ REQUIRED_R_DEPTH, DEFAULT_REQUIRED_R_DEPTH);945 g_progname, g_progname, g_progname, 946 DEFAULT_PROTECTION_DEPTH, DEFAULT_PROTECTION_DEPTH); 864 947 return EX_USAGE; 865 948 }
Note:
See TracChangeset
for help on using the changeset viewer.