Audit chgrp(1)

1) Refactor manpage so it's actually fun to read.
2) BUGFIX: Call (l)chown properly when the H-flag is specified
   (only when depth > 0).
3) BUGFIX: Call (l)chown properly when the h-flag is specified
   (only when depth = 0).
4) BUGFIX: Only recurse() in chgrp() when the initial chownf()
   succeeds.
5) Style fixes, argv-basing.
6) Rename status to ret for consistency.
7) Add blank line before return.
This commit is contained in:
FRIGN 2015-03-08 23:31:59 +01:00
parent 8ffa06b3dc
commit fba669da88
3 changed files with 38 additions and 33 deletions

2
README
View File

@ -12,7 +12,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support,
=*| basename yes none =*| basename yes none
=*| cal yes none =*| cal yes none
=*| cat yes none =*| cat yes none
=* chgrp yes none =*| chgrp yes none
=*| chmod yes none =*| chmod yes none
=* chown yes none =* chown yes none
=*| chroot non-posix none =*| chroot non-posix none

26
chgrp.1
View File

@ -1,9 +1,9 @@
.Dd February 9, 2015 .Dd March 8, 2015
.Dt CHGRP 1 .Dt CHGRP 1
.Os sbase .Os sbase
.Sh NAME .Sh NAME
.Nm chgrp .Nm chgrp
.Nd change the file group ownership .Nd change file group ownership
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl h .Op Fl h
@ -15,26 +15,26 @@
.Ar file ... .Ar file ...
.Sh DESCRIPTION .Sh DESCRIPTION
.Nm .Nm
sets the group id of the files specified by sets the group id of each
.Ar file .Ar file
to the gid of the group named to the gid of
.Ar group . .Ar group .
.Sh OPTIONS .Sh OPTIONS
.Bl -tag -width Ds .Bl -tag -width Ds
.It Fl h .It Fl h
Change the group ID of the symlink itself. This flag cannot be used Preserve
with .Ar file
.Op Fl R . if it is a symbolic link.
.It Fl R .It Fl R
Change file group ownership recursively. Change file group ownerships recursively.
.It Fl H .It Fl H
Only dereference symbolic links that are passed as command line arguments when Dereference
recursively traversing directories. .Ar file
if it is a symbolic link.
.It Fl L .It Fl L
Always dereference symbolic links while recursively traversing directories. Dereference all symbolic links.
.It Fl P .It Fl P
Don't dereference symbolic links (default). Preserve symbolic links. This is the default.
.Ar file .
.El .El
.Sh SEE ALSO .Sh SEE ALSO
.Xr chmod 1 , .Xr chmod 1 ,

41
chgrp.c
View File

@ -8,22 +8,32 @@
#include "util.h" #include "util.h"
static int gid; static int gid;
static int status; static int ret = 0;
static int Rflag; static int hflag = 0;
static int Rflag = 0;
static struct stat st; static struct stat st;
static char *chownf_name = "chown";
static int (*chownf)(const char *, uid_t, gid_t) = chown;
static void static void
chgrp(const char *path, int depth) chgrp(const char *path, int depth)
{ {
char *chownf_name;
int (*chownf)(const char *, uid_t, gid_t);
if (recurse_follow == 'P' || (recurse_follow == 'H' && depth) || (hflag && !depth)) {
chownf_name = "lchown";
chownf = lchown;
} else {
chownf_name = "chown";
chownf = chown;
}
if (chownf(path, st.st_uid, gid) < 0) { if (chownf(path, st.st_uid, gid) < 0) {
weprintf("%s %s:", chownf_name, path); weprintf("%s %s:", chownf_name, path);
status = 1; ret = 1;
} } else if (Rflag) {
if (Rflag)
recurse(path, chgrp, depth); recurse(path, chgrp, depth);
} }
}
static void static void
usage(void) usage(void)
@ -38,8 +48,7 @@ main(int argc, char *argv[])
ARGBEGIN { ARGBEGIN {
case 'h': case 'h':
chownf_name = "lchown"; hflag = 1;
chownf = lchown;
break; break;
case 'R': case 'R':
Rflag = 1; Rflag = 1;
@ -55,14 +64,9 @@ main(int argc, char *argv[])
if (argc < 2) if (argc < 2)
usage(); usage();
if (recurse_follow == 'P') {
chownf_name = "lchown";
chownf = lchown;
}
errno = 0; errno = 0;
gr = getgrnam(argv[0]); if (!(gr = getgrnam(argv[0]))) {
if (!gr) {
if (errno) if (errno)
eprintf("getgrnam %s:", argv[0]); eprintf("getgrnam %s:", argv[0]);
else else
@ -70,13 +74,14 @@ main(int argc, char *argv[])
} }
gid = gr->gr_gid; gid = gr->gr_gid;
while (*++argv) { for (; *argv; argc--, argv++) {
if (stat(*argv, &st) < 0) { if (stat(*argv, &st) < 0) {
weprintf("stat %s:", *argv); weprintf("stat %s:", *argv);
status = 1; ret = 1;
continue; continue;
} }
chgrp(*argv, 0); chgrp(*argv, 0);
} }
return status;
return ret;
} }