Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 16 Nov 2002 11:56:37 +0100 (CET)
From:      Oliver Fromme <olli@secnetix.de>
To:        FreeBSD-gnats-submit@FreeBSD.org
Cc:        Oliver Fromme <olli@fromme.com>
Subject:   bin/45333: [PATCH] New option -r for chown and chgrp
Message-ID:  <200211161056.gAGAub7X032294@lurza.secnetix.de>

next in thread | raw e-mail | index | archive | help

>Number:         45333
>Category:       bin
>Synopsis:       [PATCH] New option -r for chown and chgrp
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sat Nov 16 03:00:04 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Oliver Fromme
>Release:        FreeBSD -stable and -current
>Organization:
secnetix GmbH & Co KG, Munich, http://www.secnetix.de/
>Environment:

        The patch presented applies both to -stable and -current
        as of the date of submission (2002-11-16).

>Description:

        The existing utilities touch(1) and truncate(1) support
        an -r option to specify a reference file from which
        information is to be taken (the time stamp in the case
        of touch(1) and the file size in the case of truncate(1)).

        However, the utilities chown and chgrp (actually hardlinks
        to the same binary) do not support such an option yet.
        In shell scripts it is sometimes useful to copy ownership
        and/or group membership from another file.  Ordinarily,
        you would have to use ls -l and parse the owner/group
        columns, which is awkward, error-prone and inefficient.

        The patch presented below adds an -r option to these
        utilities, which makes copying ownership and/or group
        membership easy.  It also improves consistency with the
        existing utilities touch(1) and truncate(1).

>How-To-Repeat:

        N/A

>Fix:

        IMPORTANT:  I have attached TWO patch sets, one for
                    -stable and one for -current.  PLEASE
                    do not confuse them!  Each of the patch
                    sets contains patches for three files:

                    chgrp.1   -   chgrp(1) manpage
                    chown.8   -   chown(8) manpage
                    chown.c   -   chgrp(1) and chown(8) source

                    Note:  Because of lack of a -current box,
                    I have not been able to actually test the
                    -current patch set, but I'm confident that
                    it works fine, since the differences are
                    pretty trivial.  I have tested the -stable
                    patch set extensively.

--- chown.stable.diff begins here ---
--- src/usr.sbin/chown/chgrp.1.orig	Thu Aug 16 17:55:44 2001
+++ src/usr.sbin/chown/chgrp.1	Sat Nov 16 10:07:35 2002
@@ -50,6 +50,14 @@
 .Oc
 .Ar group
 .Ar
+.Nm
+.Op Fl fhv
+.Oo
+.Fl R
+.Op Fl H | Fl L | Fl P
+.Oc
+.Fl r Ar rfile
+.Ar
 .Sh DESCRIPTION
 The
 .Nm
@@ -84,6 +92,9 @@
 .It Fl h
 If the file is a symbolic link, the group ID of the link itself is changed
 rather than the file that is pointed to.
+.It Fl r Ar rfile
+Sets the group ID to the group of the file
+.Ar rfile .
 .It Fl v
 Cause
 .Nm
--- src/usr.sbin/chown/chown.8.orig	Fri Apr 12 17:14:54 2002
+++ src/usr.sbin/chown/chown.8	Sat Nov 16 10:28:22 2002
@@ -55,6 +55,15 @@
 .Oc
 .No : Ns Ar group
 .Ar
+.Nm
+.Op Fl fhv
+.Oo
+.Fl R
+.Op Fl H | Fl L | Fl P
+.Oc
+.Fl r Ar rfile
+.Op Fl g
+.Ar
 .Sh DESCRIPTION
 .Nm Chown
 changes the user ID and/or the group ID of the specified files.
@@ -84,9 +93,24 @@
 .It Fl f
 Don't report any failure to change file owner or group, nor modify
 the exit status to reflect such failures.
+.It Fl g
+See the
+.Fl r
+option.
 .It Fl h
 If the file is a symbolic link, change the user ID and/or the
 group ID of the link itself.
+.It Fl r Ar rfile
+Changes the user ID to the owner of the file
+.Ar rfile .
+If the 
+.Fl g
+option is also specified, change both user ID and group ID
+to the owner and group of the file
+.Ar rfile .
+Use the
+.Xr chgrp 1
+utility to change the group ID only.
 .It Fl v
 Cause
 .Nm
--- src/usr.sbin/chown/chown.c.orig	Wed Aug  7 23:24:33 2002
+++ src/usr.sbin/chown/chown.c	Sat Nov 16 10:04:28 2002
@@ -69,7 +69,7 @@
 
 uid_t uid;
 gid_t gid;
-int Rflag, ischown, fflag, hflag, vflag;
+int Rflag, ischown, fflag, gflag, hflag, rflag, vflag;
 char *gname, *myname;
 
 int
@@ -81,12 +81,13 @@
 	FTSENT *p;
 	int Hflag, Lflag, Pflag, ch, fts_options, hflag, rval;
 	char *cp;
+	char *rname;
 
 	myname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
 	ischown = myname[2] == 'o';
 
-	Hflag = Lflag = Pflag = hflag = vflag = 0;
-	while ((ch = getopt(argc, argv, "HLPRfhv")) != -1)
+	Hflag = Lflag = Pflag = gflag = hflag = rflag = vflag = 0;
+	while ((ch = getopt(argc, argv, "HLPRfghr:v")) != -1)
 		switch (ch) {
 		case 'H':
 			Hflag = 1;
@@ -106,9 +107,16 @@
 		case 'f':
 			fflag = 1;
 			break;
+		case 'g':
+			gflag = 1;
+			break;
 		case 'h':
 			hflag = 1;
 			break;
+		case 'r':
+			rflag = 1;
+			rname = optarg;
+			break;
 		case 'v':
 			vflag = 1;
 			break;
@@ -119,7 +127,9 @@
 	argv += optind;
 	argc -= optind;
 
-	if (argc < 2)
+	if (argc < (rflag ? 1 : 2))
+		usage();
+	if (gflag && !ischown)
 		usage();
 
 	fts_options = FTS_PHYSICAL;
@@ -135,7 +145,17 @@
 	}
 
 	uid = gid = -1;
-	if (ischown) {
+	if (rflag) {
+		struct stat sb;
+
+		if (stat(rname, &sb) == -1)
+			err(EXIT_FAILURE, "%s", rname);
+		if (ischown)
+			uid = sb.st_uid;
+		if (gflag || !ischown)
+			gid = sb.st_gid;
+	}
+	else if (ischown) {
 		if ((cp = strchr(*argv, ':')) != NULL) {
 			*cp++ = '\0';
 			a_gid(cp);
@@ -147,11 +167,11 @@
 			a_gid(cp);
 		}
 #endif
-		a_uid(*argv);
+		a_uid(*argv++);
 	} else
-		a_gid(*argv);
+		a_gid(*argv++);
 
-	if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL)
+	if ((ftsp = fts_open(argv, fts_options, 0)) == NULL)
 		err(1, NULL);
 
 	for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
@@ -278,9 +298,11 @@
 void
 usage()
 {
-	(void)fprintf(stderr, "%s\n%s\n%s\n",
+	(void)fprintf(stderr, "%s\n%s\n%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 ...");
+	    "       chown [-R [-H | -L | -P]] [-f] [-h] [-v] -r rfile [-g] file ...",
+	    "       chgrp [-R [-H | -L | -P]] [-f] [-h] [-v] group file ...",
+	    "       chgrp [-R [-H | -L | -P]] [-f] [-h] [-v] -r rfile file ...");
 	exit(1);
 }
--- chown.stable.diff ends here ---

--- chown.current.diff begins here ---
--- src/usr.sbin/chown/chgrp.1.orig	Wed Aug 15 11:09:46 2001
+++ src/usr.sbin/chown/chgrp.1	Sat Nov 16 10:23:46 2002
@@ -50,6 +50,14 @@
 .Oc
 .Ar group
 .Ar
+.Nm
+.Op Fl fhv
+.Oo
+.Fl R
+.Op Fl H | Fl L | Fl P
+.Oc
+.Fl r Ar rfile
+.Ar
 .Sh DESCRIPTION
 The
 .Nm
@@ -84,6 +92,9 @@
 .It Fl h
 If the file is a symbolic link, the group ID of the link itself is changed
 rather than the file that is pointed to.
+.It Fl r Ar rfile
+Sets the group ID to the group of the file
+.Ar rfile .
 .It Fl v
 Cause
 .Nm
--- src/usr.sbin/chown/chown.8.orig	Sun Jul 14 16:42:43 2002
+++ src/usr.sbin/chown/chown.8	Sat Nov 16 10:27:45 2002
@@ -55,6 +55,15 @@
 .Oc
 .No : Ns Ar group
 .Ar
+.Nm
+.Op Fl fhv
+.Oo
+.Fl R
+.Op Fl H | Fl L | Fl P
+.Oc
+.Fl r Ar rfile
+.Op Fl g
+.Ar
 .Sh DESCRIPTION
 The
 .Nm
@@ -85,9 +94,24 @@
 .It Fl f
 Don't report any failure to change file owner or group, nor modify
 the exit status to reflect such failures.
+.It Fl g
+See the
+.Fl r
+option.
 .It Fl h
 If the file is a symbolic link, change the user ID and/or the
 group ID of the link itself.
+.It Fl r Ar rfile
+Changes the user ID to the owner of the file
+.Ar rfile .
+If the 
+.Fl g
+option is also specified, change both user ID and group ID
+to the owner and group of the file
+.Ar rfile .
+Use the
+.Xr chgrp 1
+utility to change the group ID only.
 .It Fl v
 Cause
 .Nm
--- src/usr.sbin/chown/chown.c.orig	Wed Jul 17 18:22:24 2002
+++ src/usr.sbin/chown/chown.c	Sat Nov 16 11:13:45 2002
@@ -75,16 +75,17 @@
 {
 	FTS *ftsp;
 	FTSENT *p;
-	int Hflag, Lflag, Rflag, fflag, hflag, vflag;
+	int Hflag, Lflag, Rflag, fflag, gflag, hflag, rflag, vflag;
 	int ch, fts_options, rval;
 	char *cp;
+	char *rname;
 
 	cp = strrchr(argv[0], '/');
 	cp = (cp != NULL) ? cp + 1 : argv[0];
 	ischown = (strcmp(cp, "chown") == 0);
 
-	Hflag = Lflag = Rflag = fflag = hflag = vflag = 0;
-	while ((ch = getopt(argc, argv, "HLPRfhv")) != -1)
+	Hflag = Lflag = Rflag = fflag = gflag = hflag = rflag = vflag = 0;
+	while ((ch = getopt(argc, argv, "HLPRfghr:v")) != -1)
 		switch (ch) {
 		case 'H':
 			Hflag = 1;
@@ -103,9 +104,16 @@
 		case 'f':
 			fflag = 1;
 			break;
+		case 'g':
+			gflag = 1;
+			break;
 		case 'h':
 			hflag = 1;
 			break;
+		case 'r':
+			rflag = 1;
+			rname = optarg;
+			break;
 		case 'v':
 			vflag = 1;
 			break;
@@ -116,7 +124,9 @@
 	argv += optind;
 	argc -= optind;
 
-	if (argc < 2)
+	if (argc < (rflag ? 1 : 2))
+		usage();
+	if (gflag && !ischown)
 		usage();
 
 	if (Rflag) {
@@ -135,7 +145,17 @@
 
 	uid = (uid_t)-1;
 	gid = (gid_t)-1;
-	if (ischown) {
+	if (rflag) {
+		struct stat sb;
+
+                if (stat(rname, &sb) == -1)
+			err(EXIT_FAILURE, "%s", rname);
+		if (ischown)
+			uid = sb.st_uid;
+		if (gflag || !ischown)
+			gid = sb.st_gid;
+	}
+	else if (ischown) {
 		if ((cp = strchr(*argv, ':')) != NULL) {
 			*cp++ = '\0';
 			a_gid(cp);
@@ -147,11 +167,11 @@
 			a_gid(cp);
 		}
 #endif
-		a_uid(*argv);
+		a_uid(*argv++);
 	} else
-		a_gid(*argv);
+		a_gid(*argv++);
 
-	if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL)
+	if ((ftsp = fts_open(argv, fts_options, 0)) == NULL)
 		err(1, NULL);
 
 	for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
@@ -273,12 +293,16 @@
 {
 
 	if (ischown)
-		(void)fprintf(stderr, "%s\n%s\n",
+		(void)fprintf(stderr, "%s\n%s\n%s\n",
 		    "usage: chown [-fhv] [-R [-H | -L | -P]] owner[:group]"
 		    " file ...",
-		    "       chown [-fhv] [-R [-H | -L | -P]] :group file ...");
+		    "       chown [-fhv] [-R [-H | -L | -P]] :group file ...",
+		    "       chown [-fhv] [-R [-H | -L | -P]] -r rfile [-g]"
+		    " file ...");
 	else
-		(void)fprintf(stderr, "%s\n",
-		    "usage: chgrp [-fhv] [-R [-H | -L | -P]] group file ...");
+		(void)fprintf(stderr, "%s\n%s\n",
+		    "usage: chgrp [-fhv] [-R [-H | -L | -P]] group file ...",
+		    "usage: chgrp [-fhv] [-R [-H | -L | -P]] -r rfile"
+		    " file ...");
 	exit(1);
 }
--- chown.current.diff ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200211161056.gAGAub7X032294>