Subject: bin/2689: [dM] chmod(1)/setmode(3) symbolic mode improvement
To: None <gnats-bugs@NetBSD.ORG>
From: der Mouse <mouse@Holo.Rodents.Montreal.QC.CA>
List: netbsd-bugs
Date: 08/12/1996 13:14:14
>Number: 2689
>Category: bin
>Synopsis: [dM] chmod(1)/setmode(3) symbolic mode improvement
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Mon Aug 12 13:35:02 1996
>Last-Modified:
>Originator: der Mouse
>Organization:
Dis-
>Release: -current sup (1.2 release branch), today, 12 Aug 1996:
>Environment:
Any
>Description:
These patches make setmode(3), and therefore chmod(1), accept
symbolic modes such as are printed by ls(1), with the ability
to "don't-care" out bits by replacing characters with dots.
chmod.c needed touching because with these changes, a mode
argument can begin with --, which confuses getopt(3).
>How-To-Repeat:
Wish you could take a mode from ls and hand it to chmod.
Notice you can't.
Sigh.
>Fix:
Here's what I've done. I also did some fiddle edits in
chmod.1, mostly replacing "``foo''" with ".Dq foo" for various
values of foo.
--- OLD/bin/chmod/chmod.1 Thu Jan 1 00:00:00 1970
+++ NEW/bin/chmod/chmod.1 Thu Jan 1 00:00:00 1970
@@ -132,7 +132,13 @@
.Pp
The symbolic mode is described by the following grammar:
.Bd -literal -offset indent
-mode ::= clause [, clause ...]
+mode ::= ls_mode | op_mode
+ls_mode ::= ls_r ls_w ls_xs ls_r ls_w ls_xs ls_r ls_w ls_xt
+ls_r ::= r | \- | .
+ls_w ::= w | \- | .
+ls_xs ::= x | s | S | \- | .
+ls_xt ::= x | t | T | \- | .
+op_mode ::= clause [, clause ...]
clause ::= [who ...] [action ...] last_action
action ::= op [perm ...]
last_action ::= op [perm ...]
@@ -141,13 +147,35 @@
perm ::= r | s | t | w | x | X | u | g | o
.Ed
.Pp
+If an
+.Ar ls_mode
+is used, it is simply a symbolic mode such as that printed by
+.Xr ls 1
+with the first character (which indicates the file type) stripped,
+and possibly with some characters replaced by dots, indicating that
+.Nm chmod
+should not change the bit(s) corresponding to that character. (When using
+this style of symbolic mode, there is no way to, for example, specify the
+group-execute bit's state without specifying the setgid bit's state as well.
+Affecting one of a pair of bits that use the same character without
+affecting the other is simply not possible with an
+.Ar ls_mode . )
+.Pp
The
.Ar who
-symbols ``u'', ``g'', and ``o'' specify the user, group, and other parts
+symbols
+.Dq u ,
+.Dq g ,
+and
+.Dq o
+specify the user, group, and other parts
of the mode bits, respectively.
The
.Ar who
-symbol ``a'' is equivalent to ``ugo''.
+symbol
+.Dq a
+is equivalent to
+.Dq ugo .
.Pp
.ne 1i
The
@@ -170,9 +198,13 @@
execute/search bits are set in the original (unmodified) mode.
Operations with the
.Ar perm
-symbol ``X'' are only meaningful in conjunction with the
+symbol
+.Dq X
+are only meaningful in conjunction with the
.Ar op
-symbol ``+'', and are ignored in all other cases.
+symbol
+.Dq + ,
+and are ignored in all other cases.
.It u
The user permission bits in the mode of the original file.
.It g
@@ -188,7 +220,9 @@
.It +
If no value is supplied for
.Ar perm ,
-the ``+'' operation has no effect.
+the
+.Dq +
+operation has no effect.
If no value is supplied for
.Ar who ,
each permission bit specified in
@@ -203,7 +237,9 @@
.It \&\-
If no value is supplied for
.Ar perm ,
-the ``\-'' operation has no effect.
+the
+.Dq \-
+operation has no effect.
If no value is supplied for
.Ar who ,
each permission bit specified in
@@ -240,15 +276,20 @@
order specified.
.Pp
Operations upon the other permissions only (specified by the symbol
-``o'' by itself), in combination with the
+.Dq o
+by itself), in combination with the
.Ar perm
-symbols ``s'' or ``t'', are ignored.
+symbols
+.Dq s
+or
+.Dq t ,
+are ignored.
.Sh EXAMPLES
.Bl -tag -width "u=rwx,go=u-w" -compact
.It Li 644
make a file readable by anyone and writable by the owner only.
.Pp
-.It Li go-w
+.It Li go\-w
deny write permission to group and others.
.Pp
.It Li =rw,+X
@@ -261,13 +302,18 @@
.Pp
.It Li 755
.It Li u=rwx,go=rx
-.It Li u=rwx,go=u-w
+.It Li u=rwx,go=u\-w
make a file readable/executable by everyone and writable by the owner only.
.Pp
+.It Li rw.r\-.\-\-.
+make a file readable by owner and group, writeable by owner only, and do
+not touch the execute, set-ID, or sticky bits.
+.Pp
.It Li go=
+.It Li ...\-\-\-\-\-\-
clear all mode bits for group and others.
.Pp
-.It Li g=u-w
+.It Li g=u\-w
set the group bits equal to the user bits, but clear the group write bit.
.El
.Sh BUGS
@@ -293,5 +339,7 @@
symbols
.Dq t
and
-.Dq X
-which are not included in that standard.
+.Dq X ,
+and the
+.Ar ls_mode
+specifications, which are not included in that standard.
--- OLD/bin/chmod/chmod.c Thu Jan 1 00:00:00 1970
+++ NEW/bin/chmod/chmod.c Thu Jan 1 00:00:00 1970
@@ -125,6 +125,14 @@
done: argv += optind;
argc -= optind;
+ /* If we have a mode beginning with --, like --x--x--x,
+ getopt will mistake it for a -- end-of-flags indicator. */
+ if ( (argv[-1][0] == '-') &&
+ (argv[-1][1] == '-') &&
+ (strlen(argv[-1]) == 9) ) {
+ argc ++;
+ argv --;
+ }
if (argc < 2)
usage();
--- OLD/lib/libc/gen/setmode.c Thu Jan 1 00:00:00 1970
+++ NEW/lib/libc/gen/setmode.c Thu Jan 1 00:00:00 1970
@@ -168,6 +168,74 @@
#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
+static int ls_mode_p(const char *s, int *setp, int *clrp)
+{
+ /* N, ch1, set1, clr1, ch2, set2, clr2, ... chN, setN, clrN,
+ repeated once per character in the mode. N==0 signals end. */
+ static int prog[] = { 3, 'r', S_IRUSR, 0,
+ '-', 0, S_IRUSR,
+ '.', 0, 0,
+ 3, 'w', S_IWUSR, 0,
+ '-', 0, S_IWUSR,
+ '.', 0, 0,
+ 5, 'x', S_IXUSR, S_ISUID,
+ 's', S_IXUSR|S_ISUID, 0,
+ 'S', S_ISUID, S_IXUSR,
+ '-', 0, S_IXUSR|S_ISUID,
+ '.', 0, 0,
+ 3, 'r', S_IRGRP, 0,
+ '-', 0, S_IRGRP,
+ '.', 0, 0,
+ 3, 'w', S_IWGRP, 0,
+ '-', 0, S_IWGRP,
+ '.', 0, 0,
+ 5, 'x', S_IXGRP, S_ISGID,
+ 's', S_IXGRP|S_ISGID, 0,
+ 'S', S_ISGID, S_IXGRP,
+ '-', 0, S_IXGRP|S_ISGID,
+ '.', 0, 0,
+ 3, 'r', S_IROTH, 0,
+ '-', 0, S_IROTH,
+ '.', 0, 0,
+ 3, 'w', S_IWOTH, 0,
+ '-', 0, S_IWOTH,
+ '.', 0, 0,
+ 5, 'x', S_IXOTH, S_ISTXT,
+ 't', S_IXOTH|S_ISTXT, 0,
+ 'T', S_ISTXT, S_IXOTH,
+ '-', 0, S_IXOTH|S_ISTXT,
+ '.', 0, 0,
+ 0 };
+ int *pp;
+ int n;
+ int mset;
+ int mclr;
+ int bad;
+
+ pp = &prog[0];
+ mset = 0;
+ mclr = 0;
+ while (1)
+ { n = *pp++;
+ if (n == 0)
+ { if (*s) return(0);
+ *setp = mset;
+ *clrp = mclr;
+ return(1);
+ }
+ bad = 1;
+ for (;n>0;n--,pp+=3)
+ { if (*s == pp[0])
+ { mset |= pp[1];
+ mclr |= pp[2];
+ bad = 0;
+ }
+ }
+ if (bad) return(0);
+ s ++;
+ }
+}
+
void *
setmode(p)
register char *p;
@@ -178,6 +246,7 @@
sigset_t sigset, sigoset;
mode_t mask;
int equalopdone, permXbits, setlen;
+ int permset, permclr;
if (!*p)
return (NULL);
@@ -217,6 +286,15 @@
return (NULL);
}
ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
+ return (saveset);
+ }
+
+ /*
+ * Check for ls-style symbolic modes.
+ */
+ if (ls_mode_p(p,&permset,&permclr)) {
+ ADDCMD('+', STANDARD_BITS|S_ISTXT, permset, 0);
+ ADDCMD('-', STANDARD_BITS|S_ISTXT, permclr, 0);
return (saveset);
}
der Mouse
mouse@collatz.mcrcim.mcgill.edu
01 EE 31 F6 BB 0C 34 36 00 F3 7C 5A C1 A0 67 1D
>Audit-Trail:
>Unformatted:
$NetBSD: chmod.c,v 1.12 1995/03/21 09:02:09 cgd Exp $
$NetBSD: chmod.1,v 1.8 1995/03/21 09:02:07 cgd Exp $
$NetBSD: setmode.c,v 1.13 1996/04/03 19:49:01 jtc Exp $