Make chflags(1) more chmod(1)-like (and more feature complete):

- Add -v to print file names as they are processed; -vv prints the flags
  change as well.
- Add -f to ignore failures with the same semantics as chflags(1), neither
  printing an error nor affecting the return code.
- Don't try to set the flags if they won't change.

I made minor cosmetic tweaks to the code in the patch.

MFC after:	1 week
PR:		112827
Submitted by:	Ighighi <ighighi at gmail.com>
This commit is contained in:
rwatson 2008-03-09 12:10:24 +00:00
parent b588c3dd60
commit f0bfd374ce
2 changed files with 43 additions and 17 deletions

View File

@ -40,7 +40,7 @@
.Nd change file flags
.Sh SYNOPSIS
.Nm
.Op Fl h
.Op Fl fhv
.Oo
.Fl R
.Op Fl H | Fl L | Fl P
@ -57,6 +57,12 @@ operand.
.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl f
Do not display a diagnostic message if
.Nm
could not modify the flags for
.Va file ,
nor modify the exit status to reflect such failures.
.It Fl H
If the
.Fl R
@ -79,6 +85,14 @@ This is the default.
.It Fl R
Change the file flags for the file hierarchies rooted
in the files instead of just the files themselves.
.It Fl v
Cause
.Nm
to be verbose, showing filenames as the flags are modified.
If the
.Fl v
option is specified more than once, the old and new flags of the file
will also be printed, in octal notation.
.El
.Pp
The flags are specified as an octal number or a comma separated list

View File

@ -60,14 +60,15 @@ main(int argc, char *argv[])
{
FTS *ftsp;
FTSENT *p;
u_long clear, set;
u_long clear, newflags, set;
long val;
int Hflag, Lflag, Rflag, hflag, ch, fts_options, oct, rval;
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 = hflag = 0;
while ((ch = getopt(argc, argv, "HLPRh")) != -1)
Hflag = Lflag = Rflag = fflag = hflag = vflag = 0;
while ((ch = getopt(argc, argv, "HLPRfhv")) != -1)
switch (ch) {
case 'H':
Hflag = 1;
@ -83,9 +84,15 @@ main(int argc, char *argv[])
case 'R':
Rflag = 1;
break;
case 'f':
fflag = 1;
break;
case 'h':
hflag = 1;
break;
case 'v':
vflag++;
break;
case '?':
default:
usage();
@ -166,18 +173,23 @@ main(int argc, char *argv[])
default:
break;
}
if (oct) {
if (!(*change_flags)(p->fts_accpath, set))
continue;
} else {
p->fts_statp->st_flags |= set;
p->fts_statp->st_flags &= clear;
if (!(*change_flags)(p->fts_accpath,
(u_long)p->fts_statp->st_flags))
continue;
if (oct)
newflags = set;
else
newflags = (p->fts_statp->st_flags | set) & clear;
if (newflags == p->fts_statp->st_flags)
continue;
if ((*change_flags)(p->fts_accpath, newflags) && !fflag) {
warn("%s", p->fts_path);
rval = 1;
} else if (vflag) {
(void)printf("%s", p->fts_path);
if (vflag > 1)
(void)printf(": 0%lo -> 0%lo",
(u_long)p->fts_statp->st_flags,
newflags);
(void)printf("\n");
}
warn("%s", p->fts_path);
rval = 1;
}
if (errno)
err(1, "fts_read");
@ -188,6 +200,6 @@ void
usage(void)
{
(void)fprintf(stderr,
"usage: chflags [-h] [-R [-H | -L | -P]] flags file ...\n");
"usage: chflags [-fhv] [-R [-H | -L | -P]] flags file ...\n");
exit(1);
}