Index: bin/chflags/chflags.1 =================================================================== --- bin/chflags/chflags.1 +++ bin/chflags/chflags.1 @@ -32,7 +32,7 @@ .\" @(#)chflags.1 8.4 (Berkeley) 5/2/95 .\" $FreeBSD$ .\" -.Dd April 8, 2013 +.Dd April 17, 2015 .Dt CHFLAGS 1 .Os .Sh NAME @@ -69,10 +69,15 @@ option is specified, symbolic links on the command line are followed. (Symbolic links encountered in the tree traversal are not followed.) .It Fl h -If the -.Ar file -is a symbolic link, -change the file flags of the link itself rather than the file to which it points. +If the file is a symbolic link, change the flags of the link itself +rather than the file that the link points to. If used in combination +with +.Fl R +and +.Fl H +then any symbolic links on the command line will be processed as though +.Fl h +had not been specified. .It Fl L If the .Fl R Index: bin/chflags/chflags.c =================================================================== --- bin/chflags/chflags.c +++ bin/chflags/chflags.c @@ -105,12 +105,12 @@ if (Rflag) { fts_options = FTS_PHYSICAL; - if (hflag) - errx(1, "the -R and -h options " - "may not be specified together"); + if (hflag && Lflag) + errx(1, "the -R -L and -h options may not be " + "specified together"); if (Hflag) fts_options |= FTS_COMFOLLOW; - if (Lflag) { + else if (Lflag) { fts_options &= ~FTS_PHYSICAL; fts_options |= FTS_LOGICAL; } Index: bin/chmod/chmod.1 =================================================================== --- bin/chmod/chmod.1 +++ bin/chmod/chmod.1 @@ -32,7 +32,7 @@ .\" @(#)chmod.1 8.4 (Berkeley) 3/31/94 .\" $FreeBSD$ .\" -.Dd January 26, 2009 +.Dd April 17, 2015 .Dt CHMOD 1 .Os .Sh NAME @@ -64,11 +64,17 @@ If the .Fl R option is specified, symbolic links on the command line are followed. -(Symbolic links encountered in the tree traversal are not followed by -default.) +(Symbolic links encountered in the tree traversal are not followed.) .It Fl h If the file is a symbolic link, change the mode of the link itself -rather than the file that the link points to. +rather than the file that the link points to. If used in combination +with +.Fl R +and +.Fl H +then any symbolic links on the command line will be processed as though +.Fl h +had not been specified. .It Fl L If the .Fl R Index: bin/chmod/chmod.c =================================================================== --- bin/chmod/chmod.c +++ bin/chmod/chmod.c @@ -62,10 +62,11 @@ FTS *ftsp; FTSENT *p; mode_t *set; - int Hflag, Lflag, Rflag, ch, error, fflag, fts_options, hflag, rval; + int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval; int vflag; char *mode; mode_t newmode; + int (*change_mode)(const char *, unsigned long); set = NULL; Hflag = Lflag = Rflag = fflag = hflag = vflag = 0; @@ -127,18 +128,20 @@ if (Rflag) { fts_options = FTS_PHYSICAL; - if (hflag) - errx(1, - "the -R and -h options may not be specified together."); + if (hflag && Lflag) + errx(1, "the -R -L and -h options may not be " + "specified together"); if (Hflag) fts_options |= FTS_COMFOLLOW; - if (Lflag) { + else if (Lflag) { fts_options &= ~FTS_PHYSICAL; fts_options |= FTS_LOGICAL; } } else fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL; + change_mode = hflag ? lchmod : chmod; + mode = *argv; if ((set = setmode(mode)) == NULL) errx(1, "invalid file mode: %s", mode); @@ -182,32 +185,24 @@ if (may_have_nfs4acl(p, hflag) == 0 && (newmode & ALLPERMS) == (p->fts_statp->st_mode & ALLPERMS)) continue; - if (hflag) - error = lchmod(p->fts_accpath, newmode); - else - error = chmod(p->fts_accpath, newmode); - if (error) { - if (!fflag) { - warn("%s", p->fts_path); - rval = 1; - } - } else { - if (vflag) { - (void)printf("%s", p->fts_path); - - if (vflag > 1) { - char m1[12], m2[12]; - - strmode(p->fts_statp->st_mode, m1); - strmode((p->fts_statp->st_mode & - S_IFMT) | newmode, m2); - (void)printf(": 0%o [%s] -> 0%o [%s]", - p->fts_statp->st_mode, m1, - (p->fts_statp->st_mode & S_IFMT) | - newmode, m2); - } - (void)printf("\n"); + if (change_mode(p->fts_accpath, newmode) && !fflag) { + warn("%s", p->fts_path); + rval = 1; + } else if (vflag) { + (void)printf("%s", p->fts_path); + + if (vflag > 1) { + char m1[12], m2[12]; + + strmode(p->fts_statp->st_mode, m1); + strmode((p->fts_statp->st_mode & + S_IFMT) | newmode, m2); + (void)printf(": 0%o [%s] -> 0%o [%s]", + p->fts_statp->st_mode, m1, + (p->fts_statp->st_mode & S_IFMT) | + newmode, m2); } + (void)printf("\n"); } } if (errno) Index: usr.sbin/chown/chown.8 =================================================================== --- usr.sbin/chown/chown.8 +++ usr.sbin/chown/chown.8 @@ -28,7 +28,7 @@ .\" @(#)chown.8 8.3 (Berkeley) 3/31/94 .\" $FreeBSD$ .\" -.Dd February 21, 2010 +.Dd April 17, 2015 .Dt CHOWN 8 .Os .Sh NAME @@ -87,7 +87,14 @@ the exit status to reflect such failures. .It Fl h If the file is a symbolic link, change the user ID and/or the -group ID of the link itself. +group ID of the link itself rather than the file that the link points +to. If used in combination with +.Fl R +and +.Fl H +then any symbolic links on the command line will be processed as though +.Fl h +had not been specified. .It Fl v Cause .Nm Index: usr.sbin/chown/chown.c =================================================================== --- usr.sbin/chown/chown.c +++ usr.sbin/chown/chown.c @@ -76,6 +76,7 @@ int Hflag, Lflag, Rflag, fflag, hflag, vflag, xflag; int ch, fts_options, rval; char *cp; + int (*change_owner)(const char *, uid_t, gid_t); ischown = (strcmp(basename(argv[0]), "chown") == 0); @@ -120,9 +121,9 @@ if (Rflag) { fts_options = FTS_PHYSICAL; - if (hflag && (Hflag || Lflag)) - errx(1, "the -R%c and -h options may not be " - "specified together", Hflag ? 'H' : 'L'); + if (hflag && Lflag) + errx(1, "the -R -L and -h options may not be " + "specified together"); if (Hflag) fts_options |= FTS_COMFOLLOW; else if (Lflag) { @@ -131,6 +132,9 @@ } } else fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL; + + change_owner = hflag ? lchown : chown; + if (xflag) fts_options |= FTS_XDEV; @@ -187,41 +191,37 @@ if ((uid == (uid_t)-1 || uid == p->fts_statp->st_uid) && (gid == (gid_t)-1 || gid == p->fts_statp->st_gid)) continue; - if ((hflag ? lchown : chown)(p->fts_accpath, uid, gid) == -1) { - if (!fflag) { - chownerr(p->fts_path); - rval = 1; - } - } else { - if (vflag) { - printf("%s", p->fts_path); - if (vflag > 1) { - if (ischown) { - printf(": %ju:%ju -> %ju:%ju", - (uintmax_t) - p->fts_statp->st_uid, - (uintmax_t) - p->fts_statp->st_gid, - (uid == (uid_t)-1) ? - (uintmax_t) - p->fts_statp->st_uid : - (uintmax_t)uid, - (gid == (gid_t)-1) ? - (uintmax_t) - p->fts_statp->st_gid : - (uintmax_t)gid); - } else { - printf(": %ju -> %ju", - (uintmax_t) - p->fts_statp->st_gid, - (gid == (gid_t)-1) ? - (uintmax_t) - p->fts_statp->st_gid : - (uintmax_t)gid); - } + if (change_owner(p->fts_accpath, uid, gid) == -1 && !fflag) { + chownerr(p->fts_path); + rval = 1; + } else if (vflag) { + printf("%s", p->fts_path); + if (vflag > 1) { + if (ischown) { + printf(": %ju:%ju -> %ju:%ju", + (uintmax_t) + p->fts_statp->st_uid, + (uintmax_t) + p->fts_statp->st_gid, + (uid == (uid_t)-1) ? + (uintmax_t) + p->fts_statp->st_uid : + (uintmax_t)uid, + (gid == (gid_t)-1) ? + (uintmax_t) + p->fts_statp->st_gid : + (uintmax_t)gid); + } else { + printf(": %ju -> %ju", + (uintmax_t) + p->fts_statp->st_gid, + (gid == (gid_t)-1) ? + (uintmax_t) + p->fts_statp->st_gid : + (uintmax_t)gid); } - printf("\n"); } + printf("\n"); } } if (errno)