void rm_file(char **argv) { struct stat sb; int rval; char *f; /* * Remove a file. POSIX 1003.2 states that, by default, attempting * to remove a directory is an error, so must always stat the file. */ while ((f = *argv++) != NULL) { /* Assume if can't stat the file, can't unlink it. */ if (lstat(f, &sb)) { if (!fflag || errno != ENOENT) { warn("%s", f); eval = 1; } continue; } if (S_ISDIR(sb.st_mode) && !dflag) { warnx("%s: is a directory", f); eval = 1; continue; } if (!fflag && !check(f, f, &sb)) continue; else if (S_ISDIR(sb.st_mode)) rval = rmdir(f); else { if (Pflag) rm_overwrite(f, &sb); rval = unlink(f); } if (rval && (!fflag || errno != ENOENT)) { warn("%s", f); eval = 1; } } }
static void rm_file(char **argv) { struct stat sb; int rval; char *f; /* * Remove a file. POSIX 1003.2 states that, by default, attempting * to remove a directory is an error, so must always stat the file. */ while ((f = *argv++) != NULL) { /* Assume if can't stat the file, can't unlink it. */ if (lstat(f, &sb)) { #ifndef __ANDROID__ if (Wflag) { sb.st_mode = S_IFWHT|S_IWUSR|S_IRUSR; } else { #endif if (!fflag || !NONEXISTENT(errno)) { warn("%s", f); eval = 1; } continue; #ifndef __ANDROID__ } } else if (Wflag) { warnx("%s: %s", f, strerror(EEXIST)); eval = 1; continue; #endif } if (S_ISDIR(sb.st_mode) && !dflag) { warnx("%s: is a directory", f); eval = 1; continue; } if (!fflag && !S_ISWHT(sb.st_mode) && !check(f, f, &sb)) continue; #ifndef __ANDROID__ if (S_ISWHT(sb.st_mode)) rval = undelete(f); else if (S_ISDIR(sb.st_mode)) #else if (S_ISDIR(sb.st_mode)) #endif rval = rmdir(f); else { if (Pflag) { if (rm_overwrite(f, &sb)) continue; } rval = unlink(f); } if (rval && (!fflag || !NONEXISTENT(errno))) { warn("%s", f); eval = 1; } if (vflag && rval == 0) (void)printf("%s\n", f); } }
static void rm_tree(char **argv) { FTS *fts; FTSENT *p; int flags, needstat, rval; /* * Remove a file hierarchy. If forcing removal (-f), or interactive * (-i) or can't ask anyway (stdin_ok), don't stat the file. */ needstat = !fflag && !iflag && stdin_ok; /* * If the -i option is specified, the user can skip on the pre-order * visit. The fts_number field flags skipped directories. */ #define SKIPPED 1 flags = FTS_PHYSICAL; if (!needstat) flags |= FTS_NOSTAT; #ifndef __ANDROID__ if (Wflag) flags |= FTS_WHITEOUT; #endif if (xflag) flags |= FTS_XDEV; if ((fts = fts_open(argv, flags, NULL)) == NULL) err(1, "fts_open failed"); while ((p = fts_read(fts)) != NULL) { switch (p->fts_info) { case FTS_DNR: if (!fflag || p->fts_errno != ENOENT) { warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); eval = 1; } continue; case FTS_ERR: errx(EXIT_FAILURE, "%s: %s", p->fts_path, strerror(p->fts_errno)); /* NOTREACHED */ case FTS_NS: /* * FTS_NS: assume that if can't stat the file, it * can't be unlinked. */ if (fflag && NONEXISTENT(p->fts_errno)) continue; if (needstat) { warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); eval = 1; continue; } break; case FTS_D: /* Pre-order: give user chance to skip. */ if (!fflag && !check(p->fts_path, p->fts_accpath, p->fts_statp)) { (void)fts_set(fts, p, FTS_SKIP); p->fts_number = SKIPPED; } continue; case FTS_DP: /* Post-order: see if user skipped. */ if (p->fts_number == SKIPPED) continue; break; default: if (!fflag && !check(p->fts_path, p->fts_accpath, p->fts_statp)) continue; } rval = 0; /* * If we can't read or search the directory, may still be * able to remove it. Don't print out the un{read,search}able * message unless the remove fails. */ switch (p->fts_info) { case FTS_DP: case FTS_DNR: rval = rmdir(p->fts_accpath); if (rval != 0 && fflag && errno == ENOENT) continue; break; #ifndef __ANDROID__ case FTS_W: rval = undelete(p->fts_accpath); if (rval != 0 && fflag && errno == ENOENT) continue; break; #endif default: if (Pflag) { if (rm_overwrite(p->fts_accpath, NULL)) continue; } rval = unlink(p->fts_accpath); if (rval != 0 && fflag && NONEXISTENT(errno)) continue; break; } if (rval != 0) { warn("%s", p->fts_path); eval = 1; } else if (vflag || pinfo) { pinfo = 0; (void)printf("%s\n", p->fts_path); } } if (errno) err(1, "fts_read"); fts_close(fts); }
static void rm_file(char **argv) { struct stat sb; int rval; char *f; /* * Remove a file. POSIX 1003.2 states that, by default, attempting * to remove a directory is an error, so must always stat the file. */ while ((f = *argv++) != NULL) { /* Assume if can't stat the file, can't unlink it. */ if (lstat(f, &sb)) { if (Wflag) { sb.st_mode = S_IFWHT|S_IWUSR|S_IRUSR; } else { if (!fflag || errno != ENOENT) { warn("%s", f); eval = 1; } continue; } } else if (Wflag) { warnx("%s: %s", f, strerror(EEXIST)); eval = 1; continue; } if (S_ISDIR(sb.st_mode) && !dflag) { warnx("%s: is a directory", f); eval = 1; continue; } if (!fflag && !S_ISWHT(sb.st_mode) && !check(f, f, &sb)) continue; rval = 0; if (!uid && !S_ISWHT(sb.st_mode) && (sb.st_flags & (UF_APPEND|UF_IMMUTABLE)) && !(sb.st_flags & (SF_APPEND|SF_IMMUTABLE))) rval = lchflags(f, sb.st_flags & ~(UF_APPEND|UF_IMMUTABLE)); if (rval == 0) { if (S_ISWHT(sb.st_mode)) rval = undelete(f); else if (S_ISDIR(sb.st_mode)) rval = rmdir(f); else { if (Pflag) if (!rm_overwrite(f, &sb)) continue; rval = unlink(f); } } if (rval && (!fflag || errno != ENOENT)) { warn("%s", f); eval = 1; } if (vflag && rval == 0) (void)printf("%s\n", f); if (info && rval == 0) { info = 0; (void)printf("%s\n", f); } } }
static void rm_tree(char **argv) { FTS *fts; FTSENT *p; int needstat; int flags; int rval; /* * Remove a file hierarchy. If forcing removal (-f), or interactive * (-i) or can't ask anyway (stdin_ok), don't stat the file. */ needstat = !uid || (!fflag && !iflag && stdin_ok); /* * If the -i option is specified, the user can skip on the pre-order * visit. The fts_number field flags skipped directories. */ #define SKIPPED 1 flags = FTS_PHYSICAL; if (!needstat) flags |= FTS_NOSTAT; if (Wflag) flags |= FTS_WHITEOUT; if (xflag) flags |= FTS_XDEV; if (!(fts = fts_open(argv, flags, NULL))) { if (fflag && errno == ENOENT) return; err(1, "fts_open"); } while ((p = fts_read(fts)) != NULL) { switch (p->fts_info) { case FTS_DNR: if (!fflag || p->fts_errno != ENOENT) { warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); eval = 1; } continue; case FTS_ERR: errx(1, "%s: %s", p->fts_path, strerror(p->fts_errno)); case FTS_NS: /* * Assume that since fts_read() couldn't stat the * file, it can't be unlinked. */ if (!needstat) break; if (!fflag || p->fts_errno != ENOENT) { warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); eval = 1; } continue; case FTS_D: /* Pre-order: give user chance to skip. */ if (!fflag && !check(p->fts_path, p->fts_accpath, p->fts_statp)) { (void)fts_set(fts, p, FTS_SKIP); p->fts_number = SKIPPED; } else if (!uid && (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) && !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) && lchflags(p->fts_accpath, p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)) < 0) goto err; continue; case FTS_DP: /* Post-order: see if user skipped. */ if (p->fts_number == SKIPPED) continue; break; default: if (!fflag && !check(p->fts_path, p->fts_accpath, p->fts_statp)) continue; } rval = 0; if (!uid && (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) && !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE))) rval = lchflags(p->fts_accpath, p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)); if (rval == 0) { /* * If we can't read or search the directory, may still be * able to remove it. Don't print out the un{read,search}able * message unless the remove fails. */ switch (p->fts_info) { case FTS_DP: case FTS_DNR: rval = rmdir(p->fts_accpath); if (rval == 0 || (fflag && errno == ENOENT)) { if (rval == 0 && vflag) (void)printf("%s\n", p->fts_path); if (rval == 0 && info) { info = 0; (void)printf("%s\n", p->fts_path); } continue; } break; case FTS_W: rval = undelete(p->fts_accpath); if (rval == 0 && (fflag && errno == ENOENT)) { if (vflag) (void)printf("%s\n", p->fts_path); if (info) { info = 0; (void)printf("%s\n", p->fts_path); } continue; } break; case FTS_NS: /* * Assume that since fts_read() couldn't stat * the file, it can't be unlinked. */ if (fflag) continue; /* FALLTHROUGH */ case FTS_F: case FTS_NSOK: if (Pflag) if (!rm_overwrite(p->fts_accpath, p->fts_info == FTS_NSOK ? NULL : p->fts_statp)) continue; /* FALLTHROUGH */ default: rval = unlink(p->fts_accpath); if (rval == 0 || (fflag && errno == ENOENT)) { if (rval == 0 && vflag) (void)printf("%s\n", p->fts_path); if (rval == 0 && info) { info = 0; (void)printf("%s\n", p->fts_path); } continue; } } } err: warn("%s", p->fts_path); eval = 1; } if (!fflag && errno) err(1, "fts_read"); fts_close(fts); }
void rm_tree(char **argv) { FTS *fts; FTSENT *p; int needstat; int flags; /* * Remove a file hierarchy. If forcing removal (-f), or interactive * (-i) or can't ask anyway (stdin_ok), don't stat the file. */ needstat = !fflag && !iflag && stdin_ok; /* * If the -i option is specified, the user can skip on the pre-order * visit. The fts_number field flags skipped directories. */ #define SKIPPED 1 flags = FTS_PHYSICAL; if (!needstat) flags |= FTS_NOSTAT; if (xflag) flags |= FTS_XDEV; if (!(fts = fts_open(argv, flags, NULL))) err(1, NULL); while ((p = fts_read(fts)) != NULL) { switch (p->fts_info) { case FTS_DNR: if (!fflag || p->fts_errno != ENOENT) { warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); eval = 1; } continue; case FTS_ERR: errc(1, p->fts_errno, "%s", p->fts_path); case FTS_NS: /* * FTS_NS: assume that if can't stat the file, it * can't be unlinked. */ if (!needstat) break; if (!fflag || p->fts_errno != ENOENT) { warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); eval = 1; } continue; case FTS_D: /* Pre-order: give user chance to skip. */ if (!fflag && !check(p->fts_path, p->fts_accpath, p->fts_statp)) { (void)fts_set(fts, p, FTS_SKIP); p->fts_number = SKIPPED; } continue; case FTS_DP: /* Post-order: see if user skipped. */ if (p->fts_number == SKIPPED) continue; break; default: if (!fflag && !check(p->fts_path, p->fts_accpath, p->fts_statp)) continue; } /* * If we can't read or search the directory, may still be * able to remove it. Don't print out the un{read,search}able * message unless the remove fails. */ switch (p->fts_info) { case FTS_DP: case FTS_DNR: if (!rmdir(p->fts_accpath) || (fflag && errno == ENOENT)) continue; break; case FTS_F: case FTS_NSOK: if (Pflag) rm_overwrite(p->fts_accpath, p->fts_info == FTS_NSOK ? NULL : p->fts_statp); /* FALLTHROUGH */ default: if (!unlink(p->fts_accpath) || (fflag && errno == ENOENT)) continue; } warn("%s", p->fts_path); eval = 1; } if (errno) err(1, "fts_read"); fts_close(fts); }
rm_tree(char **argv) #endif { FTS *fts; FTSENT *p; int needstat; int rval; /* * Remove a file hierarchy. If forcing removal (-f), or interactive * (-i) or can't ask anyway (stdin_ok), don't stat the file. */ needstat = !uid || !fflag && !iflag && stdin_ok; /* * If the -i option is specified, the user can skip on the pre-order * visit. The fts_number field flags skipped directories. */ #define SKIPPED 1 if (!(fts = fts_open(argv, needstat ? FTS_PHYSICAL|FTS_NOCHDIR : FTS_PHYSICAL|FTS_NOSTAT|FTS_NOCHDIR, (int (*)())NULL))) err(1, NULL); while ((p = fts_read(fts)) != NULL) { switch (p->fts_info) { case FTS_DNR: if (!fflag || p->fts_errno != ENOENT) { warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); eval = 1; } continue; case FTS_ERR: errx(1, "%s: %s", p->fts_path, strerror(p->fts_errno)); case FTS_NS: /* * FTS_NS: assume that if can't stat the file, it * can't be unlinked. */ if (!needstat) break; if (!fflag || p->fts_errno != ENOENT) { warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); eval = 1; } continue; case FTS_D: /* Pre-order: give user chance to skip. */ if (iflag && !check(p->fts_path, p->fts_accpath, p->fts_statp)) { (void)fts_set(fts, p, FTS_SKIP); p->fts_number = SKIPPED; } #ifndef __GNO__ else if (!uid && (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) && !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) && chflags(p->fts_accpath, p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)) < 0) goto err; #endif continue; case FTS_DP: /* Post-order: see if user skipped. */ if (p->fts_number == SKIPPED) continue; break; } if (!fflag && !check(p->fts_path, p->fts_accpath, p->fts_statp)) continue; rval = 0; #ifndef __GNO__ if (!uid && (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) && !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE))) rval = chflags(p->fts_accpath, p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)); #endif if (!rval) { /* * If we can't read or search the directory, may still be * able to remove it. Don't print out the un{read,search}able * message unless the remove fails. */ if (p->fts_info == FTS_DP || p->fts_info == FTS_DNR) { if (!rmdir(p->fts_accpath)) continue; if (errno == ENOENT) { if (fflag) continue; } else if (p->fts_info != FTS_DP) warnx("%s: unable to read", p->fts_path); } else { if (Pflag) rm_overwrite(p->fts_accpath, NULL); if (!unlink(p->fts_accpath) || (fflag && errno == ENOENT)) continue; } } err: warn("%s", p->fts_path); eval = 1; } if (errno) err(1, "fts_read"); }
static int rm_file(char **argv) { struct stat sb; int rval; char *f; /* * Check up front before anything is deleted. */ int i; for (i = 0; argv[i]; i++) { if (kBuildProtectionEnforce(&g_ProtData, KBUILDPROTECTIONTYPE_FULL, argv[i])) return 1; } /* * Remove a file. POSIX 1003.2 states that, by default, attempting * to remove a directory is an error, so must always stat the file. */ while ((f = *argv++) != NULL) { const char *operation = "?"; /* Assume if can't stat the file, can't unlink it. */ if (lstat(f, &sb)) { #ifdef FTS_WHITEOUT if (Wflag) { sb.st_mode = S_IFWHT|S_IWUSR|S_IRUSR; } else { #else { #endif if (!fflag || errno != ENOENT) { fprintf(stderr, "lstat: %s: %s: %s " CUR_LINE() "\n", argv0, f, strerror(errno)); eval = 1; } continue; } #ifdef FTS_WHITEOUT } else if (Wflag) { fprintf(stderr, "%s: %s: %s\n", argv0, f, strerror(EEXIST)); eval = 1; continue; #endif } if (S_ISDIR(sb.st_mode) && !dflag) { fprintf(stderr, "%s: %s: is a directory\n", argv0, f); eval = 1; continue; } if (!fflag && !S_ISWHT(sb.st_mode) && !check(f, f, &sb)) continue; rval = 0; #ifdef UF_APPEND if (!uid && (sb.st_flags & (UF_APPEND|UF_IMMUTABLE)) && !(sb.st_flags & (SF_APPEND|SF_IMMUTABLE))) rval = chflags(f, sb.st_flags & ~(UF_APPEND|UF_IMMUTABLE)); #endif if (rval == 0) { if (S_ISWHT(sb.st_mode)) { rval = undelete(f); operation = "undelete"; } else if (S_ISDIR(sb.st_mode)) { rval = rmdir(f); operation = "rmdir"; } else { if (Pflag) if (!rm_overwrite(f, &sb)) continue; rval = unlink(f); #ifdef _MSC_VER if (rval != 0) { chmod(f, 0777); rval = unlink(f); } #endif operation = "unlink"; } } if (rval && (!fflag || errno != ENOENT)) { fprintf(stderr, "%s: %s: %s: %s" CUR_LINE() "\n", operation, argv0, f, strerror(errno)); eval = 1; } if (vflag && rval == 0) (void)printf("%s\n", f); } return eval; }
static int rm_tree(char **argv) { FTS *fts; FTSENT *p; int needstat; int flags; int rval; /* * Check up front before anything is deleted. This will not catch * everything, but we'll check the individual items later. */ int i; for (i = 0; argv[i]; i++) { if (kBuildProtectionEnforce(&g_ProtData, KBUILDPROTECTIONTYPE_RECURSIVE, argv[i])) { return 1; } } /* * Remove a file hierarchy. If forcing removal (-f), or interactive * (-i) or can't ask anyway (stdin_ok), don't stat the file. */ needstat = !uid || (!fflag && !iflag && stdin_ok); /* * If the -i option is specified, the user can skip on the pre-order * visit. The fts_number field flags skipped directories. */ #define SKIPPED 1 flags = FTS_PHYSICAL; if (!needstat) flags |= FTS_NOSTAT; #ifdef FTS_WHITEOUT if (Wflag) flags |= FTS_WHITEOUT; #endif if (!(fts = fts_open(argv, flags, NULL))) { return err(1, "fts_open"); } while ((p = fts_read(fts)) != NULL) { const char *operation = "chflags"; switch (p->fts_info) { case FTS_DNR: if (!fflag || p->fts_errno != ENOENT) { fprintf(stderr, "fts: %s: %s: %s" CUR_LINE() "\n", argv0, p->fts_path, strerror(p->fts_errno)); eval = 1; } continue; case FTS_ERR: fts_close(fts); return errx(1, "fts: %s: %s " CUR_LINE(), p->fts_path, strerror(p->fts_errno)); case FTS_NS: /* * Assume that since fts_read() couldn't stat the * file, it can't be unlinked. */ if (!needstat) break; if (!fflag || p->fts_errno != ENOENT) { fprintf(stderr, "fts: %s: %s: %s " CUR_LINE() "\n", argv0, p->fts_path, strerror(p->fts_errno)); eval = 1; } continue; case FTS_D: /* Pre-order: give user chance to skip. */ if (!fflag && !check(p->fts_path, p->fts_accpath, p->fts_statp)) { (void)fts_set(fts, p, FTS_SKIP); p->fts_number = SKIPPED; } #ifdef UF_APPEND else if (!uid && (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) && !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) && chflags(p->fts_accpath, p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)) < 0) goto err; #endif continue; case FTS_DP: /* Post-order: see if user skipped. */ if (p->fts_number == SKIPPED) continue; break; default: if (!fflag && !check(p->fts_path, p->fts_accpath, p->fts_statp)) continue; } /* * Protect against deleting root files and directories. */ if (kBuildProtectionEnforce(&g_ProtData, KBUILDPROTECTIONTYPE_RECURSIVE, p->fts_accpath)) { fts_close(fts); return 1; } rval = 0; #ifdef UF_APPEND if (!uid && (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) && !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE))) rval = chflags(p->fts_accpath, p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)); #endif if (rval == 0) { /* * If we can't read or search the directory, may still be * able to remove it. Don't print out the un{read,search}able * message unless the remove fails. */ switch (p->fts_info) { case FTS_DP: case FTS_DNR: rval = rmdir(p->fts_accpath); if (rval == 0 || (fflag && errno == ENOENT)) { if (rval == 0 && vflag) (void)printf("%s\n", p->fts_path); continue; } operation = "mkdir"; break; #ifdef FTS_W case FTS_W: rval = undelete(p->fts_accpath); if (rval == 0 && (fflag && errno == ENOENT)) { if (vflag) (void)printf("%s\n", p->fts_path); continue; } operation = "undelete"; break; #endif case FTS_NS: /* * Assume that since fts_read() couldn't stat * the file, it can't be unlinked. */ if (fflag) continue; /* FALLTHROUGH */ default: if (Pflag) if (!rm_overwrite(p->fts_accpath, NULL)) continue; rval = unlink(p->fts_accpath); #ifdef _MSC_VER if (rval != 0) { chmod(p->fts_accpath, 0777); rval = unlink(p->fts_accpath); } #endif if (rval == 0 || (fflag && errno == ENOENT)) { if (rval == 0 && vflag) (void)printf("%s\n", p->fts_path); continue; } operation = "unlink"; break; } } #ifdef UF_APPEND err: #endif fprintf(stderr, "%s: %s: %s: %s " CUR_LINE() "\n", operation, argv0, p->fts_path, strerror(errno)); eval = 1; } if (errno) { fprintf(stderr, "%s: fts_read: %s " CUR_LINE() "\n", argv0, strerror(errno)); eval = 1; } fts_close(fts); return eval; }