summaryrefslogtreecommitdiffstats
path: root/bin/chflags
diff options
context:
space:
mode:
authordd <dd@FreeBSD.org>2005-05-14 23:23:10 +0000
committerdd <dd@FreeBSD.org>2005-05-14 23:23:10 +0000
commita15208c6fbb88b817909d4ed60bc476644076486 (patch)
treefb692eca432b08ed003fc04bef1bb4e8b0f9d483 /bin/chflags
parentc138dacf0cfab71856dbdc3a17fafb8d56f55dca (diff)
downloadFreeBSD-src-a15208c6fbb88b817909d4ed60bc476644076486.zip
FreeBSD-src-a15208c6fbb88b817909d4ed60bc476644076486.tar.gz
Add an interface to the lchflags(2) syscall. The new -h option is
analogous to chmod(1)'s -h. It allows setting flags on symbolic links, which *do* exist in 5.x+ despite a claim to the contrary in the chflags(1) man page. Suggested by: Chris Dillon
Diffstat (limited to 'bin/chflags')
-rw-r--r--bin/chflags/chflags.117
-rw-r--r--bin/chflags/chflags.c30
2 files changed, 35 insertions, 12 deletions
diff --git a/bin/chflags/chflags.1 b/bin/chflags/chflags.1
index 426c98e..e1200db 100644
--- a/bin/chflags/chflags.1
+++ b/bin/chflags/chflags.1
@@ -32,7 +32,7 @@
.\" @(#)chflags.1 8.4 (Berkeley) 5/2/95
.\" $FreeBSD$
.\"
-.Dd February 24, 2005
+.Dd May 14, 2005
.Dt CHFLAGS 1
.Os
.Sh NAME
@@ -40,6 +40,7 @@
.Nd change file flags
.Sh SYNOPSIS
.Nm
+.Op Fl h
.Oo
.Fl R
.Op Fl H | Fl L | Fl P
@@ -61,6 +62,11 @@ 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.)
+.It Fl h
+If the
+.Ar file
+is a symbolic link,
+change the mode of the link itself rather than the file to which it points.
.It Fl L
If the
.Fl R
@@ -114,11 +120,12 @@ clear the user immutable flag (owner or super-user only)
clear the nodump flag (owner or super-user only)
.El
.Pp
-Symbolic links do not have flags, so unless the
-.Fl H
+Unless the
+.Fl H ,
+.Fl L ,
or
-.Fl L
-option is set,
+.Fl h
+options are given,
.Nm
on a symbolic link always succeeds and has no effect.
The
diff --git a/bin/chflags/chflags.c b/bin/chflags/chflags.c
index 18c3cf6..273ba4c 100644
--- a/bin/chflags/chflags.c
+++ b/bin/chflags/chflags.c
@@ -62,11 +62,12 @@ main(int argc, char *argv[])
FTSENT *p;
u_long clear, set;
long val;
- int Hflag, Lflag, Rflag, ch, fts_options, oct, rval;
+ int Hflag, Lflag, Rflag, hflag, ch, fts_options, oct, rval;
char *flags, *ep;
+ int (*change_flags)(const char *, unsigned long);
- Hflag = Lflag = Rflag = 0;
- while ((ch = getopt(argc, argv, "HLPR")) != -1)
+ Hflag = Lflag = Rflag = hflag = 0;
+ while ((ch = getopt(argc, argv, "HLPRh")) != -1)
switch (ch) {
case 'H':
Hflag = 1;
@@ -82,6 +83,9 @@ main(int argc, char *argv[])
case 'R':
Rflag = 1;
break;
+ case 'h':
+ hflag = 1;
+ break;
case '?':
default:
usage();
@@ -94,6 +98,9 @@ main(int argc, char *argv[])
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;
if (Lflag) {
@@ -103,6 +110,12 @@ main(int argc, char *argv[])
} else
fts_options = FTS_LOGICAL;
+ /* XXX: Why don't chflags and lchflags have compatible prototypes? */
+ if (hflag)
+ change_flags = (int (*)(const char *, unsigned long))lchflags;
+ else
+ change_flags = chflags;
+
flags = *argv;
if (*flags >= '0' && *flags <= '7') {
errno = 0;
@@ -147,17 +160,20 @@ main(int argc, char *argv[])
* don't point to anything and ones that we found
* doing a physical walk.
*/
- continue;
+ if (!hflag)
+ continue;
+ /* FALLTHROUGH */
default:
break;
}
if (oct) {
- if (!chflags(p->fts_accpath, set))
+ if (!(*change_flags)(p->fts_accpath, set))
continue;
} else {
p->fts_statp->st_flags |= set;
p->fts_statp->st_flags &= clear;
- if (!chflags(p->fts_accpath, (u_long)p->fts_statp->st_flags))
+ if (!(*change_flags)(p->fts_accpath,
+ (u_long)p->fts_statp->st_flags))
continue;
}
warn("%s", p->fts_path);
@@ -172,6 +188,6 @@ void
usage(void)
{
(void)fprintf(stderr,
- "usage: chflags [-R [-H | -L | -P]] flags file ...\n");
+ "usage: chflags [-h] [-R [-H | -L | -P]] flags file ...\n");
exit(1);
}
OpenPOWER on IntegriCloud