diff options
Diffstat (limited to 'bin/chflags/chflags.c')
-rw-r--r-- | bin/chflags/chflags.c | 51 |
1 files changed, 27 insertions, 24 deletions
diff --git a/bin/chflags/chflags.c b/bin/chflags/chflags.c index e94c34d..2029ac5 100644 --- a/bin/chflags/chflags.c +++ b/bin/chflags/chflags.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include <err.h> #include <errno.h> +#include <fcntl.h> #include <fts.h> #include <stdio.h> #include <stdlib.h> @@ -65,7 +66,6 @@ main(int argc, char *argv[]) int Hflag, Lflag, Rflag, fflag, hflag, vflag; int ch, fts_options, oct, rval; char *flags, *ep; - int (*change_flags)(const char *, unsigned long); Hflag = Lflag = Rflag = fflag = hflag = vflag = 0; while ((ch = getopt(argc, argv, "HLPRfhv")) != -1) @@ -104,20 +104,23 @@ main(int argc, char *argv[]) usage(); if (Rflag) { - fts_options = FTS_PHYSICAL; if (hflag) - errx(1, "the -R and -h options " - "may not be specified together"); - if (Hflag) - fts_options |= FTS_COMFOLLOW; + errx(1, "the -R and -h options may not be " + "specified together."); if (Lflag) { - fts_options &= ~FTS_PHYSICAL; - fts_options |= FTS_LOGICAL; - } - } else - fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL; + fts_options = FTS_LOGICAL; + } else { + fts_options = FTS_PHYSICAL; - change_flags = hflag ? lchflags : chflags; + if (Hflag) { + fts_options |= FTS_COMFOLLOW; + } + } + } else if (hflag) { + fts_options = FTS_PHYSICAL; + } else { + fts_options = FTS_LOGICAL; + } flags = *argv; if (*flags >= '0' && *flags <= '7') { @@ -142,12 +145,21 @@ main(int argc, char *argv[]) err(1, NULL); for (rval = 0; (p = fts_read(ftsp)) != NULL;) { + int atflag; + + if ((fts_options & FTS_LOGICAL) || + ((fts_options & FTS_COMFOLLOW) && + p->fts_level == FTS_ROOTLEVEL)) + atflag = 0; + else + atflag = AT_SYMLINK_NOFOLLOW; + switch (p->fts_info) { case FTS_D: /* Change it at FTS_DP if we're recursive. */ if (!Rflag) fts_set(ftsp, p, FTS_SKIP); continue; - case FTS_DNR: /* Warn, chflag, continue. */ + case FTS_DNR: /* Warn, chflags. */ warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); rval = 1; break; @@ -156,16 +168,6 @@ main(int argc, char *argv[]) warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); rval = 1; continue; - case FTS_SL: /* Ignore. */ - case FTS_SLNONE: - /* - * The only symlinks that end up here are ones that - * don't point to anything and ones that we found - * doing a physical walk. - */ - if (!hflag) - continue; - /* FALLTHROUGH */ default: break; } @@ -175,7 +177,8 @@ main(int argc, char *argv[]) newflags = (p->fts_statp->st_flags | set) & clear; if (newflags == p->fts_statp->st_flags) continue; - if ((*change_flags)(p->fts_accpath, newflags) && !fflag) { + if (chflagsat(AT_FDCWD, p->fts_accpath, newflags, + atflag) == -1 && !fflag) { warn("%s", p->fts_path); rval = 1; } else if (vflag) { |