NetBSD Problem Report #2689

From gnats  Mon Aug 12 13:22:48 1996
Received: from Collatz.McRCIM.McGill.EDU by pain.lcs.mit.edu (8.7.5/8.7.3) with SMTP id NAA24332 for <gnats-bugs@gnats.netbsd.org>; Mon, 12 Aug 1996 13:14:22 -0400 (EDT)
Message-Id: <199608121714.NAA25304@Collatz.McRCIM.McGill.EDU>
Date: Mon, 12 Aug 1996 13:14:14 -0400
From: der Mouse <mouse@Collatz.McRCIM.McGill.EDU>
Reply-To: mouse@netbsd.org
To: gnats-bugs@NetBSD.ORG
Subject: [dM] chmod(1)/setmode(3) symbolic mode improvement
X-Send-Pr-Version: 3.2

>Number:         2689
>Category:       bin
>Synopsis:       [dM] chmod(1)/setmode(3) symbolic mode improvement
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Mon Aug 12 13:35:02 +0000 1996
>Closed-Date:    
>Last-Modified:  Mon Oct 13 23:36:10 +0000 2014
>Originator:     der Mouse
>Release:        1.2
>Organization:
	Dis-
>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
>Release-Note:
>Audit-Trail:

From: Michael Graff <explorer@flame.org>
To: mouse@Holo.Rodents.Montreal.QC.CA
Cc: gnats-bugs@NetBSD.ORG
Subject: Re: bin/2689: [dM] chmod(1)/setmode(3) symbolic mode improvement
Date: 13 Aug 1996 00:38:29 -0400

 der Mouse <mouse@Holo.Rodents.Montreal.QC.CA> writes:

 > 	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.

 What is the difference between doing this with, say, symbolic changes
 like chmod u+rwX,g+rwX?

 These do the same thing, and are standard sort of critters.  I'd hate to
 break posix unless there is a good reason to do so.

 STANDARDS
      The chmod utility is expected to be IEEE Std1003.2 (``POSIX.2'') compati-
      ble with the exception of the perm symbols ``t'' and ``X'' which are not
      included in that standard.

 --Michael
From: David Holland <dholland-bugs@netbsd.org>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: bin/2689 ([dM] chmod(1)/setmode(3) symbolic mode improvement)
Date: Wed, 27 Aug 2014 19:35:02 +0000

 Because of the interaction with getopt I don't think this is a good
 idea even as an extension.

 There's also a standards-compliant way to get the same effect now:

    chmod `stat -f '%Lp' file` other-file

 Granted it's a bit ugly, and stat(1) shouldn't need to exist, but
 given that ls output is allowed to (and does) vary arbitrarily with
 locale it's more or less necessary. It might have been better if this
 had been handled differently by POSIX but at this point the ship's
 sailed.

 -- 
 David A. Holland
 dholland@netbsd.org

From: Alan Barrett <apb@cequrux.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: bin/2689 ([dM] chmod(1)/setmode(3) symbolic mode improvement)
Date: Thu, 28 Aug 2014 13:14:10 +0200

 On Wed, 27 Aug 2014, David Holland wrote:
 > Because of the interaction with getopt I don't think this is a 
 > good idea even as an extension.

 Instead of trying to make "chmod --xr.x--x file" work, and 
 recognising it based on the string length and characters included, 
 perhaps we could find a way of recognising it based on a prefix. 
 Perhaps something like "chmod m=--xr.x--x file", where the new 
 "m=" marks the new syntax.

 --apb (Alan Barrett)

>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 $

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.