mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-29 02:22:43 +00:00
Clean up, WARNSify, unbreak -v option handling.
This commit is contained in:
parent
7b24b50458
commit
8f9dacc2e6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=83410
@ -3,6 +3,7 @@
|
||||
|
||||
PROG= chown
|
||||
LINKS= ${BINDIR}/chown /usr/bin/chgrp
|
||||
WARNS?= 2
|
||||
MAN= chgrp.1 chown.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -49,8 +49,6 @@ static const char rcsid[] =
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fts.h>
|
||||
@ -61,16 +59,16 @@ static const char rcsid[] =
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void a_gid __P((char *));
|
||||
void a_uid __P((char *));
|
||||
void chownerr __P((char *));
|
||||
u_long id __P((char *, char *));
|
||||
void a_gid __P((const char *));
|
||||
void a_uid __P((const char *));
|
||||
void chownerr __P((const char *));
|
||||
u_long id __P((const char *, const char *));
|
||||
void usage __P((void));
|
||||
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int Rflag, ischown, fflag, hflag, vflag;
|
||||
char *gname, *myname;
|
||||
int ischown;
|
||||
const char *gname;
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
@ -79,25 +77,26 @@ main(argc, argv)
|
||||
{
|
||||
FTS *ftsp;
|
||||
FTSENT *p;
|
||||
int Hflag, Lflag, Pflag, ch, fts_options, hflag, rval;
|
||||
int Hflag, Lflag, Rflag, fflag, hflag, vflag;
|
||||
int ch, fts_options, rval;
|
||||
char *cp;
|
||||
|
||||
myname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
|
||||
ischown = myname[2] == 'o';
|
||||
cp = strrchr(argv[0], '/');
|
||||
cp = (cp != NULL) ? cp + 1 : argv[0];
|
||||
ischown = (strcmp(cp, "chown") == 0);
|
||||
|
||||
Hflag = Lflag = Pflag = hflag = vflag = 0;
|
||||
Hflag = Lflag = Rflag = fflag = hflag = vflag = 0;
|
||||
while ((ch = getopt(argc, argv, "HLPRfhv")) != -1)
|
||||
switch (ch) {
|
||||
case 'H':
|
||||
Hflag = 1;
|
||||
Lflag = Pflag = 0;
|
||||
Lflag = 0;
|
||||
break;
|
||||
case 'L':
|
||||
Lflag = 1;
|
||||
Hflag = Pflag = 0;
|
||||
Hflag = 0;
|
||||
break;
|
||||
case 'P':
|
||||
Pflag = 1;
|
||||
Hflag = Lflag = 0;
|
||||
break;
|
||||
case 'R':
|
||||
@ -124,18 +123,20 @@ main(argc, argv)
|
||||
|
||||
if (Rflag) {
|
||||
fts_options = FTS_PHYSICAL;
|
||||
if (hflag && (Lflag || Hflag))
|
||||
errx(1, "the -R and -h options may not be specified together");
|
||||
if (hflag && (Hflag || Lflag))
|
||||
errx(1, "the -R%c and -h options may not be "
|
||||
"specified together", Hflag ? 'H' : 'L');
|
||||
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;
|
||||
|
||||
uid = gid = -1;
|
||||
uid = (uid_t)-1;
|
||||
gid = (gid_t)-1;
|
||||
if (ischown) {
|
||||
if ((cp = strchr(*argv, ':')) != NULL) {
|
||||
*cp++ = '\0';
|
||||
@ -156,11 +157,11 @@ main(argc, argv)
|
||||
|
||||
for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
|
||||
switch (p->fts_info) {
|
||||
case FTS_D: /* Change it at FTS_DP. */
|
||||
case FTS_D: /* Change it at FTS_DP. */
|
||||
if (!Rflag)
|
||||
fts_set(ftsp, p, FTS_SKIP);
|
||||
continue;
|
||||
case FTS_DNR: /* Warn, chown, continue. */
|
||||
case FTS_DNR: /* Warn, chown. */
|
||||
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
|
||||
rval = 1;
|
||||
break;
|
||||
@ -169,7 +170,7 @@ main(argc, argv)
|
||||
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
|
||||
rval = 1;
|
||||
continue;
|
||||
case FTS_SL: /* Ignore. */
|
||||
case FTS_SL:
|
||||
case FTS_SLNONE:
|
||||
/*
|
||||
* The only symlinks that end up here are ones that
|
||||
@ -183,25 +184,17 @@ main(argc, argv)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((uid == -1 || uid == p->fts_statp->st_uid) &&
|
||||
(gid == -1 || gid == p->fts_statp->st_gid))
|
||||
if ((uid == (uid_t)-1 || uid == p->fts_statp->st_uid) &&
|
||||
(gid == (gid_t)-1 || gid == p->fts_statp->st_gid))
|
||||
continue;
|
||||
if (hflag) {
|
||||
if (lchown(p->fts_accpath, uid, gid) && !fflag) {
|
||||
if ((hflag ? lchown : chown)(p->fts_accpath, uid, gid) == -1) {
|
||||
if (!fflag) {
|
||||
chownerr(p->fts_path);
|
||||
rval = 1;
|
||||
} else {
|
||||
if (vflag)
|
||||
(void)printf("%s\n", p->fts_accpath);
|
||||
}
|
||||
} else {
|
||||
if (chown(p->fts_accpath, uid, gid) && !fflag) {
|
||||
chownerr(p->fts_path);
|
||||
rval = 1;
|
||||
} else {
|
||||
if (vflag)
|
||||
(void)printf("%s\n", p->fts_accpath);
|
||||
}
|
||||
if (vflag)
|
||||
printf("%s\n", p->fts_path);
|
||||
}
|
||||
}
|
||||
if (errno)
|
||||
@ -211,30 +204,30 @@ main(argc, argv)
|
||||
|
||||
void
|
||||
a_gid(s)
|
||||
char *s;
|
||||
const char *s;
|
||||
{
|
||||
struct group *gr;
|
||||
|
||||
if (*s == '\0') /* Argument was "uid[:.]". */
|
||||
return;
|
||||
gname = s;
|
||||
gid = ((gr = getgrnam(s)) == NULL) ? id(s, "group") : gr->gr_gid;
|
||||
gid = ((gr = getgrnam(s)) != NULL) ? gr->gr_gid : id(s, "group");
|
||||
}
|
||||
|
||||
void
|
||||
a_uid(s)
|
||||
char *s;
|
||||
const char *s;
|
||||
{
|
||||
struct passwd *pw;
|
||||
|
||||
if (*s == '\0') /* Argument was "[:.]gid". */
|
||||
return;
|
||||
uid = ((pw = getpwnam(s)) == NULL) ? id(s, "user") : pw->pw_uid;
|
||||
uid = ((pw = getpwnam(s)) != NULL) ? pw->pw_uid : id(s, "user");
|
||||
}
|
||||
|
||||
u_long
|
||||
id(name, type)
|
||||
char *name, *type;
|
||||
const char *name, *type;
|
||||
{
|
||||
u_long val;
|
||||
char *ep;
|
||||
@ -254,20 +247,21 @@ id(name, type)
|
||||
|
||||
void
|
||||
chownerr(file)
|
||||
char *file;
|
||||
const char *file;
|
||||
{
|
||||
static int euid = -1, ngroups = -1;
|
||||
gid_t groups[NGROUPS];
|
||||
static uid_t euid = -1;
|
||||
static int ngroups = -1;
|
||||
gid_t groups[NGROUPS_MAX];
|
||||
|
||||
/* Check for chown without being root. */
|
||||
if (errno != EPERM ||
|
||||
(uid != -1 && euid == -1 && (euid = geteuid()) != 0))
|
||||
(uid != (uid_t)-1 && euid == (uid_t)-1 && (euid = geteuid()) != 0))
|
||||
err(1, "%s", file);
|
||||
|
||||
/* Check group membership; kernel just returns EPERM. */
|
||||
if (gid != -1 && ngroups == -1 &&
|
||||
euid == -1 && (euid = geteuid()) != 0) {
|
||||
ngroups = getgroups(NGROUPS, groups);
|
||||
if (gid != (gid_t)-1 && ngroups == -1 &&
|
||||
euid == (uid_t)-1 && (euid = geteuid()) != 0) {
|
||||
ngroups = getgroups(NGROUPS_MAX, groups);
|
||||
while (--ngroups >= 0 && gid != groups[ngroups]);
|
||||
if (ngroups < 0)
|
||||
errx(1, "you are not a member of group %s", gname);
|
||||
@ -278,9 +272,14 @@ chownerr(file)
|
||||
void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr, "%s\n%s\n%s\n",
|
||||
"usage: chown [-R [-H | -L | -P]] [-f] [-h] [-v] owner[:group] file ...",
|
||||
" chown [-R [-H | -L | -P]] [-f] [-h] [-v] :group file ...",
|
||||
" chgrp [-R [-H | -L | -P]] [-f] [-h] [-v] group file ...");
|
||||
|
||||
if (ischown)
|
||||
(void)fprintf(stderr, "%s\n%s\n",
|
||||
"usage: chown [-fhv] [-R [-H | -L | -P]] owner[:group]"
|
||||
" file ...",
|
||||
" chown [-fhv] [-R [-H | -L | -P]] :group file ...");
|
||||
else
|
||||
(void)fprintf(stderr, "%s\n",
|
||||
"usage: chgrp [-fhv] [-R [-H | -L | -P]] group file ...");
|
||||
exit(1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user