Changeset 3192 for trunk/src/kmk/kmkbuiltin/rm.c
- Timestamp:
- Mar 26, 2018, 10:25:56 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kmkbuiltin/rm.c
r3148 r3192 42 42 #endif 43 43 44 45 /********************************************************************************************************************************* 46 * Header Files * 47 *********************************************************************************************************************************/ 44 48 #include "config.h" 45 49 #include <sys/stat.h> … … 90 94 #include "k/kDefs.h" /* for K_OS */ 91 95 96 97 /********************************************************************************************************************************* 98 * Defined Constants And Macros * 99 *********************************************************************************************************************************/ 92 100 #if defined(__EMX__) || defined(KBUILD_OS_WINDOWS) 93 101 # define IS_SLASH(ch) ( (ch) == '/' || (ch) == '\\' ) … … 110 118 #endif 111 119 112 extern void bsd_strmode(mode_t mode, char *p); 113 114 static int dflag, eval, fflag, iflag, Pflag, vflag, Wflag, stdin_ok; 120 #if 1 121 #define CUR_LINE_H2(x) "[line " #x "]" 122 #define CUR_LINE_H1(x) CUR_LINE_H2(x) 123 #define CUR_LINE() CUR_LINE_H1(__LINE__) 124 #else 125 # define CUR_LINE() 126 #endif 127 128 129 /********************************************************************************************************************************* 130 * Structures and Typedefs * 131 *********************************************************************************************************************************/ 132 typedef struct RMINSTANCE 133 { 134 PKMKBUILTINCTX pCtx; 135 int dflag, eval, fflag, iflag, Pflag, vflag, Wflag, stdin_ok; 115 136 #ifdef KBUILD_OS_WINDOWS 116 static int fUseNtDeleteFile; 117 #endif 118 static uid_t uid; 119 120 static char *argv0; 121 static KBUILDPROTECTION g_ProtData; 122 137 int fUseNtDeleteFile; 138 #endif 139 uid_t uid; 140 KBUILDPROTECTION g_ProtData; 141 } RMINSTANCE; 142 typedef RMINSTANCE *PRMINSTANCE; 143 144 145 /********************************************************************************************************************************* 146 * Global Variables * 147 *********************************************************************************************************************************/ 123 148 static struct option long_options[] = 124 149 { … … 137 162 138 163 139 static int check(char *, char *, struct stat *); 140 static void checkdot(char **); 141 static int rm_file(char **); 142 static int rm_overwrite(char *, struct stat *); 143 static int rm_tree(char **); 144 static int usage(FILE *); 145 146 #if 1 147 #define CUR_LINE_H2(x) "[line " #x "]" 148 #define CUR_LINE_H1(x) CUR_LINE_H2(x) 149 #define CUR_LINE() CUR_LINE_H1(__LINE__) 150 #else 151 # define CUR_LINE() 152 #endif 164 /********************************************************************************************************************************* 165 * Internal Functions * 166 *********************************************************************************************************************************/ 167 extern void bsd_strmode(mode_t mode, char *p); /* strmode.c */ 168 169 static int check(PRMINSTANCE, char *, char *, struct stat *); 170 static void checkdot(PRMINSTANCE, char **); 171 static int rm_file(PRMINSTANCE, char **); 172 static int rm_overwrite(PRMINSTANCE, char *, struct stat *); 173 static int rm_tree(PRMINSTANCE, char **); 174 static int usage(PKMKBUILTINCTX, int); 175 153 176 154 177 … … 161 184 */ 162 185 int 163 kmk_builtin_rm(int argc, char *argv[], char **envp) 164 { 186 kmk_builtin_rm(int argc, char *argv[], char **envp, PKMKBUILTINCTX pCtx) 187 { 188 RMINSTANCE This; 165 189 int ch, rflag; 166 190 167 /* reinitialize globals */ 168 argv0 = argv[0]; 169 dflag = eval = fflag = iflag = Pflag = vflag = Wflag = stdin_ok = 0; 191 /* Init global instance data */ 192 This.pCtx = pCtx; 193 This.dflag = 0; 194 This.eval = 0; 195 This.fflag = 0; 196 This.iflag = 0; 197 This.Pflag = 0; 198 This.vflag = 0; 199 This.Wflag = 0; 200 This.stdin_ok = 0; 170 201 #ifdef KBUILD_OS_WINDOWS 171 fUseNtDeleteFile = 0;172 #endif 173 uid = 0;174 kBuildProtectionInit(& g_ProtData);202 This.fUseNtDeleteFile = 0; 203 #endif 204 This.uid = 0; 205 kBuildProtectionInit(&This.g_ProtData, pCtx); 175 206 176 207 /* kmk: reset getopt and set program name. */ 177 g_progname = argv[0];178 208 opterr = 1; 179 209 optarg = NULL; … … 181 211 optind = 0; /* init */ 182 212 183 Pflag =rflag = 0;213 rflag = 0; 184 214 while ((ch = getopt_long(argc, argv, "dfiPRvW", long_options, NULL)) != -1) 185 switch (ch) {215 switch (ch) { 186 216 case 'd': 187 dflag = 1;217 This.dflag = 1; 188 218 break; 189 219 case 'f': 190 fflag = 1;191 iflag = 0;220 This.fflag = 1; 221 This.iflag = 0; 192 222 break; 193 223 case 'i': 194 fflag = 0;195 iflag = 1;224 This.fflag = 0; 225 This.iflag = 1; 196 226 break; 197 227 case 'P': 198 Pflag = 1;228 This.Pflag = 1; 199 229 break; 200 230 case 'R': … … 205 235 break; 206 236 case 'v': 207 vflag = 1;237 This.vflag = 1; 208 238 break; 209 239 #ifdef FTS_WHITEOUT 210 240 case 'W': 211 Wflag = 1;241 This.Wflag = 1; 212 242 break; 213 243 #endif 214 244 case 261: 215 kBuildProtectionTerm(& g_ProtData);216 usage( stdout);245 kBuildProtectionTerm(&This.g_ProtData); 246 usage(pCtx, 0); 217 247 return 0; 218 248 case 262: 219 kBuildProtectionTerm(& g_ProtData);249 kBuildProtectionTerm(&This.g_ProtData); 220 250 return kbuild_version(argv[0]); 221 251 case 263: 222 kBuildProtectionDisable(& g_ProtData, KBUILDPROTECTIONTYPE_RECURSIVE);252 kBuildProtectionDisable(&This.g_ProtData, KBUILDPROTECTIONTYPE_RECURSIVE); 223 253 break; 224 254 case 264: 225 kBuildProtectionEnable(& g_ProtData, KBUILDPROTECTIONTYPE_RECURSIVE);255 kBuildProtectionEnable(&This.g_ProtData, KBUILDPROTECTIONTYPE_RECURSIVE); 226 256 break; 227 257 case 265: 228 kBuildProtectionEnable(& g_ProtData, KBUILDPROTECTIONTYPE_FULL);258 kBuildProtectionEnable(&This.g_ProtData, KBUILDPROTECTIONTYPE_FULL); 229 259 break; 230 260 case 266: 231 kBuildProtectionDisable(& g_ProtData, KBUILDPROTECTIONTYPE_FULL);261 kBuildProtectionDisable(&This.g_ProtData, KBUILDPROTECTIONTYPE_FULL); 232 262 break; 233 263 case 267: 234 if (kBuildProtectionSetDepth(& g_ProtData, optarg)) {235 kBuildProtectionTerm(& g_ProtData);264 if (kBuildProtectionSetDepth(&This.g_ProtData, optarg)) { 265 kBuildProtectionTerm(&This.g_ProtData); 236 266 return 1; 237 267 } … … 239 269 #ifdef KBUILD_OS_WINDOWS 240 270 case 268: 241 fUseNtDeleteFile = 1;271 This.fUseNtDeleteFile = 1; 242 272 break; 243 273 #endif 244 274 case '?': 245 275 default: 246 kBuildProtectionTerm(& g_ProtData);247 return usage( stderr);276 kBuildProtectionTerm(&This.g_ProtData); 277 return usage(pCtx, 1); 248 278 } 249 279 argc -= optind; … … 251 281 252 282 if (argc < 1) { 253 kBuildProtectionTerm(& g_ProtData);254 if ( fflag)283 kBuildProtectionTerm(&This.g_ProtData); 284 if (This.fflag) 255 285 return (0); 256 return usage( stderr);257 } 258 259 if (!kBuildProtectionScanEnv(& g_ProtData, envp, "KMK_RM_")) {260 checkdot( argv);261 uid = geteuid();286 return usage(pCtx, 1); 287 } 288 289 if (!kBuildProtectionScanEnv(&This.g_ProtData, envp, "KMK_RM_")) { 290 checkdot(&This, argv); 291 This.uid = geteuid(); 262 292 263 293 if (*argv) { 264 stdin_ok = isatty(STDIN_FILENO);294 This.stdin_ok = isatty(STDIN_FILENO); 265 295 if (rflag) 266 eval |= rm_tree(argv);296 This.eval |= rm_tree(&This, argv); 267 297 else 268 eval |= rm_file(argv);298 This.eval |= rm_file(&This, argv); 269 299 } 270 300 } else { 271 eval = 1;272 } 273 274 kBuildProtectionTerm(& g_ProtData);275 return eval;301 This.eval = 1; 302 } 303 304 kBuildProtectionTerm(&This.g_ProtData); 305 return This.eval; 276 306 } 277 307 308 #ifdef KMK_BUILTIN_STANDALONE 309 int main(int argc, char **argv, char **envp) 310 { 311 KMKBUILTINCTX Ctx = { "kmk_rm", NULL }; 312 return kmk_builtin_rm(argc, argv, envp, &Ctx); 313 } 314 #endif 315 278 316 static int 279 rm_tree( char **argv)317 rm_tree(PRMINSTANCE pThis, char **argv) 280 318 { 281 319 FTS *fts; … … 291 329 int i; 292 330 for (i = 0; argv[i]; i++) { 293 if (kBuildProtectionEnforce(& g_ProtData, KBUILDPROTECTIONTYPE_RECURSIVE, argv[i])) {331 if (kBuildProtectionEnforce(&pThis->g_ProtData, KBUILDPROTECTIONTYPE_RECURSIVE, argv[i])) { 294 332 return 1; 295 333 } … … 300 338 * (-i) or can't ask anyway (stdin_ok), don't stat the file. 301 339 */ 302 needstat = ! uid || (!fflag && !iflag &&stdin_ok);340 needstat = !pThis->uid || (!pThis->fflag && !pThis->iflag && pThis->stdin_ok); 303 341 304 342 /* … … 312 350 flags |= FTS_NOSTAT; 313 351 #ifdef FTS_WHITEOUT 314 if ( Wflag)352 if (pThis->Wflag) 315 353 flags |= FTS_WHITEOUT; 316 354 #endif 317 355 if (!(fts = fts_open(argv, flags, NULL))) { 318 return err( 1, "fts_open");356 return err(pThis->pCtx, 1, "fts_open"); 319 357 } 320 358 while ((p = fts_read(fts)) != NULL) { … … 322 360 switch (p->fts_info) { 323 361 case FTS_DNR: 324 if (!fflag || p->fts_errno != ENOENT) { 325 fprintf(stderr, "fts: %s: %s: %s" CUR_LINE() "\n", 326 argv0, p->fts_path, strerror(p->fts_errno)); 327 eval = 1; 328 } 362 if (!pThis->fflag || p->fts_errno != ENOENT) 363 pThis->eval = errx(pThis->pCtx, 1, "fts: %s: %s" CUR_LINE() "\n", 364 p->fts_path, strerror(p->fts_errno)); 329 365 continue; 330 366 case FTS_ERR: 331 367 fts_close(fts); 332 return errx( 1, "fts: %s: %s " CUR_LINE(), p->fts_path, strerror(p->fts_errno));368 return errx(pThis->pCtx, 1, "fts: %s: %s " CUR_LINE(), p->fts_path, strerror(p->fts_errno)); 333 369 case FTS_NS: 334 370 /* … … 338 374 if (!needstat) 339 375 break; 340 if (!fflag || p->fts_errno != ENOENT) { 341 fprintf(stderr, "fts: %s: %s: %s " CUR_LINE() "\n", 342 argv0, p->fts_path, strerror(p->fts_errno)); 343 eval = 1; 344 } 376 if (!pThis->fflag || p->fts_errno != ENOENT) 377 pThis->eval = errx(pThis->pCtx, 1, "fts: %s: %s " CUR_LINE() "\n", 378 p->fts_path, strerror(p->fts_errno)); 345 379 continue; 346 380 case FTS_D: 347 381 /* Pre-order: give user chance to skip. */ 348 if (!fflag && !check(p->fts_path, p->fts_accpath, 349 p->fts_statp)) { 382 if (!pThis->fflag && !check(pThis, p->fts_path, p->fts_accpath, p->fts_statp)) { 350 383 (void)fts_set(fts, p, FTS_SKIP); 351 384 p->fts_number = SKIPPED; 352 385 } 353 386 #ifdef UF_APPEND 354 else if (! uid &&387 else if (!pThis->uid && 355 388 (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) && 356 389 !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) && … … 366 399 break; 367 400 default: 368 if (!fflag && 369 !check(p->fts_path, p->fts_accpath, p->fts_statp)) 401 if (!pThis->fflag && !check(pThis, p->fts_path, p->fts_accpath, p->fts_statp)) 370 402 continue; 371 403 } … … 374 406 * Protect against deleting root files and directories. 375 407 */ 376 if (kBuildProtectionEnforce(& g_ProtData, KBUILDPROTECTIONTYPE_RECURSIVE, p->fts_accpath)) {408 if (kBuildProtectionEnforce(&pThis->g_ProtData, KBUILDPROTECTIONTYPE_RECURSIVE, p->fts_accpath)) { 377 409 fts_close(fts); 378 410 return 1; … … 381 413 rval = 0; 382 414 #ifdef UF_APPEND 383 if (! uid &&415 if (!pThis->uid && 384 416 (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) && 385 417 !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE))) … … 405 437 rval = rmdir(p->fts_accpath); 406 438 #endif 407 if (rval == 0 || (fflag && errno == ENOENT)) { 408 if (rval == 0 && vflag) 409 (void)printf("%s\n", 410 p->fts_path); 439 if (rval == 0 || (pThis->fflag && errno == ENOENT)) { 440 if (rval == 0 && pThis->vflag) 441 kmk_builtin_ctx_printf(pThis->pCtx, 0, "%s\n", p->fts_path); 411 442 #if defined(KMK) && defined(KBUILD_OS_WINDOWS) 412 443 if (rval == 0) { … … 423 454 case FTS_W: 424 455 rval = undelete(p->fts_accpath); 425 if (rval == 0 && ( fflag && errno == ENOENT)) {456 if (rval == 0 && (pThis->fflag && errno == ENOENT)) { 426 457 if (vflag) 427 (void)printf("%s\n", 428 p->fts_path); 458 kmk_builtin_ctx_printf(pThis->pCtx, 0, "%s\n", p->fts_path); 429 459 continue; 430 460 } … … 438 468 * the file, it can't be unlinked. 439 469 */ 440 if ( fflag)470 if (pThis->fflag) 441 471 continue; 442 472 /* FALLTHROUGH */ 443 473 default: 444 if ( Pflag)445 if (!rm_overwrite(p ->fts_accpath, NULL))474 if (pThis->Pflag) 475 if (!rm_overwrite(pThis, p->fts_accpath, NULL)) 446 476 continue; 447 477 #ifdef KBUILD_OS_WINDOWS … … 455 485 #endif 456 486 457 if (rval == 0 || (fflag && errno == ENOENT)) { 458 if (rval == 0 && vflag) 459 (void)printf("%s\n", 460 p->fts_path); 487 if (rval == 0 || (pThis->fflag && errno == ENOENT)) { 488 if (rval == 0 && pThis->vflag) 489 kmk_builtin_ctx_printf(pThis->pCtx, 0, "%s\n", p->fts_path); 461 490 continue; 462 491 } … … 468 497 err: 469 498 #endif 470 fprintf(stderr, "%s: %s: %s: %s " CUR_LINE() "\n", operation, argv0, p->fts_path, strerror(errno)); 471 eval = 1; 499 pThis->eval = errx(pThis->pCtx, 1, "%s: %s failed: %s " CUR_LINE() "\n", p->fts_path, operation, strerror(errno)); 472 500 } 473 501 if (errno) { 474 fprintf(stderr, "%s: fts_read: %s " CUR_LINE() "\n", argv0, strerror(errno)); 475 eval = 1; 502 pThis->eval = errx(pThis->pCtx, 1, "fts_read: %s " CUR_LINE() "\n", strerror(errno)); 476 503 } 477 504 fts_close(fts); 478 return eval;505 return pThis->eval; 479 506 } 480 507 481 508 static int 482 rm_file( char **argv)509 rm_file(PRMINSTANCE pThis, char **argv) 483 510 { 484 511 struct stat sb; … … 491 518 int i; 492 519 for (i = 0; argv[i]; i++) { 493 if (kBuildProtectionEnforce(& g_ProtData, KBUILDPROTECTIONTYPE_FULL, argv[i]))520 if (kBuildProtectionEnforce(&pThis->g_ProtData, KBUILDPROTECTIONTYPE_FULL, argv[i])) 494 521 return 1; 495 522 } … … 504 531 if (lstat(f, &sb)) { 505 532 #ifdef FTS_WHITEOUT 506 if ( Wflag) {533 if (pThis->Wflag) { 507 534 sb.st_mode = S_IFWHT|S_IWUSR|S_IRUSR; 508 535 } else { … … 510 537 { 511 538 #endif 512 if (!fflag || errno != ENOENT) { 513 fprintf(stderr, "lstat: %s: %s: %s " CUR_LINE() "\n", argv0, f, strerror(errno)); 514 eval = 1; 515 } 539 if (!pThis->fflag || errno != ENOENT) 540 pThis->eval = errx(pThis->pCtx, 1, "%s: lstat failed: %s " CUR_LINE() "\n", 541 f, strerror(errno)); 516 542 continue; 517 543 } 518 544 #ifdef FTS_WHITEOUT 519 } else if ( Wflag) {520 fprintf(stderr, "%s: %s: %s\n", argv0, f, strerror(EEXIST));521 eval = 1;545 } else if (pThis->Wflag) { 546 errx(pThis->pCtx, "%s: %s\n", f, strerror(EEXIST)); 547 pThis->eval = 1; 522 548 continue; 523 549 #endif 524 550 } 525 551 526 if (S_ISDIR(sb.st_mode) && !dflag) { 527 fprintf(stderr, "%s: %s: is a directory\n", argv0, f); 528 eval = 1; 552 if (S_ISDIR(sb.st_mode) && !pThis->dflag) { 553 pThis->eval = errx(pThis->pCtx, 1, "%s: is a directory\n", f); 529 554 continue; 530 555 } 531 if (! fflag && !S_ISWHT(sb.st_mode) && !check(f, f, &sb))556 if (!pThis->fflag && !S_ISWHT(sb.st_mode) && !check(pThis, f, f, &sb)) 532 557 continue; 533 558 rval = 0; … … 546 571 operation = "rmdir"; 547 572 } else { 548 if ( Pflag)549 if (!rm_overwrite( f, &sb))573 if (pThis->Pflag) 574 if (!rm_overwrite(pThis, f, &sb)) 550 575 continue; 551 576 #ifndef KBUILD_OS_WINDOWS … … 553 578 operation = "unlink"; 554 579 #else 555 if ( fUseNtDeleteFile) {580 if (pThis->fUseNtDeleteFile) { 556 581 rval = birdUnlinkForcedFast(f); 557 582 operation = "NtDeleteFile"; … … 563 588 } 564 589 } 565 if (rval && (!fflag || errno != ENOENT)) { 566 fprintf(stderr, "%s: %s: %s: %s" CUR_LINE() "\n", operation, argv0, f, strerror(errno)); 567 eval = 1; 568 } 569 if (vflag && rval == 0) 570 (void)printf("%s\n", f); 571 } 572 return eval; 590 if (rval && (!pThis->fflag || errno != ENOENT)) 591 pThis->eval = errx(pThis->pCtx, 1, "%s: %s failed: %s" CUR_LINE() "\n", f, operation, strerror(errno)); 592 if (pThis->vflag && rval == 0) 593 kmk_builtin_ctx_printf(pThis->pCtx, 0, "%s\n", f); 594 } 595 return pThis->eval; 573 596 } 574 597 … … 585 608 */ 586 609 static int 587 rm_overwrite( char *file, struct stat *sbp)610 rm_overwrite(PRMINSTANCE pThis, char *file, struct stat *sbp) 588 611 { 589 612 struct stat sb; … … 595 618 char *buf = NULL; 596 619 const char *operation = "lstat"; 620 int error; 597 621 598 622 fd = -1; … … 605 629 return (1); 606 630 operation = "open"; 607 if ((fd = open(file, O_WRONLY , 0)) == -1)631 if ((fd = open(file, O_WRONLY | KMK_OPEN_NO_INHERIT, 0)) == -1) 608 632 goto err; 609 633 #ifdef HAVE_FSTATFS … … 616 640 bsize = 1024; 617 641 #endif 618 if ((buf = malloc(bsize)) == NULL) 619 exit(err(1, "%s: malloc", file)); 642 if ((buf = malloc(bsize)) == NULL) { 643 err(pThis->pCtx, 1, "%s: malloc", file); 644 close(fd); 645 return 1; 646 } 620 647 621 648 #define PASS(byte) { \ … … 643 670 operation = "fsync/close"; 644 671 645 err: eval = 1; 672 err: pThis->eval = 1; 673 error = errno; 646 674 if (buf) 647 675 free(buf); 648 676 if (fd != -1) 649 677 close(fd); 650 fprintf(stderr, "%s: %s: %s: %s" CUR_LINE() "\n", operation, argv0, file, strerror(errno));678 errx(pThis->pCtx, 1, "%s: %s: %s: %s" CUR_LINE() "\n", operation, pThis->pCtx->pszProgName, file, strerror(error)); 651 679 return (0); 652 680 } … … 654 682 655 683 static int 656 check( char *path, char *name, struct stat *sp)684 check(PRMINSTANCE pThis, char *path, char *name, struct stat *sp) 657 685 { 658 686 int ch, first; … … 660 688 661 689 /* Check -i first. */ 662 if ( iflag)663 (void)fprintf(stderr, " remove %s? ", path);690 if (pThis->iflag) 691 (void)fprintf(stderr, "%s: remove %s? ", pThis->pCtx->pszProgName, path); 664 692 else { 665 693 /* … … 672 700 * barf later. 673 701 */ 674 if (! stdin_ok || S_ISLNK(sp->st_mode) ||Pflag ||702 if (!pThis->stdin_ok || S_ISLNK(sp->st_mode) || pThis->Pflag || 675 703 (!access(name, W_OK) && 676 704 #ifdef SF_APPEND 677 705 !(sp->st_flags & (SF_APPEND|SF_IMMUTABLE)) && 678 (!(sp->st_flags & (UF_APPEND|UF_IMMUTABLE)) || ! uid))706 (!(sp->st_flags & (UF_APPEND|UF_IMMUTABLE)) || !pThis->uid)) 679 707 #else 680 708 1) … … 684 712 bsd_strmode(sp->st_mode, modep); 685 713 #if defined(SF_APPEND) && K_OS != K_OS_GNU_KFBSD && K_OS != K_OS_GNU_HURD 686 if ((flagsp = fflagstostr(sp->st_flags)) == NULL) 687 exit(err(1, "fflagstostr")); 714 if ((flagsp = fflagstostr(sp->st_flags)) == NULL) { 715 err(pThis->pCtx, 1, "fflagstostr"); 716 flagsp = "<bad-fflagstostr>"; 717 } 688 718 (void)fprintf(stderr, "override %s%s%s/%s %s%sfor %s? ", 689 719 modep + 1, modep[9] == ' ' ? "" : " ", … … 710 740 #define ISDOT(a) ((a)[0] == '.' && (!(a)[1] || ((a)[1] == '.' && !(a)[2]))) 711 741 static void 712 checkdot( char **argv)742 checkdot(PRMINSTANCE pThis, char **argv) 713 743 { 714 744 char *p, **save, **t; … … 737 767 if (ISDOT(p)) { 738 768 if (!complained++) 739 fprintf(stderr, "%s: \".\" and \"..\" may not be removed\n", argv0);740 eval = 1;769 warnx(pThis->pCtx, "\".\" and \"..\" may not be removed\n"); 770 pThis->eval = 1; 741 771 for (save = t; (t[0] = t[1]) != NULL; ++t) 742 772 continue; … … 748 778 749 779 static int 750 usage( FILE *pf)751 { 752 fprintf(pf,753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 g_progname, g_progname, g_progname,803 780 usage(PKMKBUILTINCTX pCtx, int fIsErr) 781 { 782 kmk_builtin_ctx_printf(pCtx, fIsErr, 783 "usage: %s [options] file ...\n" 784 " or: %s --help\n" 785 " or: %s --version\n" 786 "\n" 787 "Options:\n" 788 " -f\n" 789 " Attempt to remove files without prompting, regardless of the file\n" 790 " permission. Ignore non-existing files. Overrides previous -i's.\n" 791 " -i\n" 792 " Prompt for each file. Always.\n" 793 " -d\n" 794 " Attempt to remove directories as well as other kinds of files.\n" 795 " -P\n" 796 " Overwrite regular files before deleting; three passes: ff,0,ff\n" 797 " -R\n" 798 " Attempt to remove the file hierachy rooted in each file argument.\n" 799 " This option implies -d and file protection.\n" 800 " -v\n" 801 " Be verbose, show files as they are removed.\n" 802 " -W\n" 803 " Undelete without files.\n" 804 " --disable-protection\n" 805 " Will disable the protection file protection applied with -R.\n" 806 " --enable-protection\n" 807 " Will enable the protection file protection applied with -R.\n" 808 " --enable-full-protection\n" 809 " Will enable the protection file protection for all operations.\n" 810 " --disable-full-protection\n" 811 " Will disable the protection file protection for all operations.\n" 812 " --protection-depth\n" 813 " Number or path indicating the file protection depth. Default: %d\n" 814 "\n" 815 "Environment:\n" 816 " KMK_RM_DISABLE_PROTECTION\n" 817 " Same as --disable-protection. Overrides command line.\n" 818 " KMK_RM_ENABLE_PROTECTION\n" 819 " Same as --enable-protection. Overrides everyone else.\n" 820 " KMK_RM_ENABLE_FULL_PROTECTION\n" 821 " Same as --enable-full-protection. Overrides everyone else.\n" 822 " KMK_RM_DISABLE_FULL_PROTECTION\n" 823 " Same as --disable-full-protection. Overrides command line.\n" 824 " KMK_RM_PROTECTION_DEPTH\n" 825 " Same as --protection-depth. Overrides command line.\n" 826 "\n" 827 "The file protection of the top %d layers of the file hierarchy is there\n" 828 "to try prevent makefiles from doing bad things to your system. This\n" 829 "protection is not bulletproof, but should help prevent you from shooting\n" 830 "yourself in the foot.\n" 831 , 832 pCtx->pszProgName, pCtx->pszProgName, pCtx->pszProgName, 833 kBuildProtectionDefaultDepth(), kBuildProtectionDefaultDepth()); 804 834 return EX_USAGE; 805 835 } 836
Note:
See TracChangeset
for help on using the changeset viewer.