svn commit: r195318 - head/usr.bin/cpio

Tim Kientzle kientzle at FreeBSD.org
Fri Jul 3 17:54:34 UTC 2009


Author: kientzle
Date: Fri Jul  3 17:54:33 2009
New Revision: 195318
URL: http://svn.freebsd.org/changeset/base/195318

Log:
  This fixes bsdcpio's -R option to accept numeric
  user or group Ids as well as user or group names.
  In particular, this fixes freesbie2, which uses
  -R 0:0 to copy a bunch of files so that the result
  will be owned by root.
  
  Also fixes a related bug that mixed-up the uid
  and gid specified by -R when in passthrough mode.
  
  Thanks to Dominique Goncalves for reporting this
  regression.
  
  Approved by:	re (kib)

Modified:
  head/usr.bin/cpio/cmdline.c
  head/usr.bin/cpio/cpio.c

Modified: head/usr.bin/cpio/cmdline.c
==============================================================================
--- head/usr.bin/cpio/cmdline.c	Fri Jul  3 16:33:42 2009	(r195317)
+++ head/usr.bin/cpio/cmdline.c	Fri Jul  3 17:54:33 2009	(r195318)
@@ -268,16 +268,36 @@ cpio_getopt(struct cpio *cpio)
  * Parse the argument to the -R or --owner flag.
  *
  * The format is one of the following:
- *   <user>    - Override user but not group
- *   <user>:   - Override both, group is user's default group
- *   <user>:<group> - Override both
- *   :<group>  - Override group but not user
+ *   <username|uid>    - Override user but not group
+ *   <username>:   - Override both, group is user's default group
+ *   <uid>:    - Override user but not group
+ *   <username|uid>:<groupname|gid> - Override both
+ *   :<groupname|gid>  - Override group but not user
+ *
+ * Where uid/gid are decimal representations and groupname/username
+ * are names to be looked up in system database.  Note that
+ * uid/gid parsing takes priority over username/groupname lookup,
+ * so this won't do a lookup for usernames or group names that
+ * consist entirely of digits.
  *
  * A period can be used instead of the colon.
  *
- * Sets uid/gid as appropriate, -1 indicates uid/gid not specified.
+ * Sets uid/gid return as appropriate, -1 indicates uid/gid not specified.
  *
  */
+static int
+decimal_parse(const char *p)
+{
+	/* TODO: guard against overflow. */
+	int n = 0;
+	for (; *p != '\0'; ++p) {
+		if (*p < '0' || *p > '9')
+			return (-1);
+		n = n * 10 + *p - '0';
+	}
+	return (n);
+}
+
 int
 owner_parse(const char *spec, int *uid, int *gid)
 {
@@ -318,24 +338,34 @@ owner_parse(const char *spec, int *uid, 
 		}
 		memcpy(user, u, ue - u);
 		user[ue - u] = '\0';
-		pwent = getpwnam(user);
-		if (pwent == NULL) {
-			cpio_warnc(errno, "Couldn't lookup user ``%s''", user);
-			return (1);
+		*uid = decimal_parse(user);
+		if (*uid < 0) {
+			/* Couldn't parse as integer, try username lookup. */
+			pwent = getpwnam(user);
+			if (pwent == NULL) {
+				cpio_warnc(errno,
+				    "Couldn't lookup user ``%s''", user);
+				return (1);
+			}
+			*uid = pwent->pw_uid;
+			if (*ue != '\0' && *g == '\0')
+				*gid = pwent->pw_gid;
 		}
 		free(user);
-		*uid = pwent->pw_uid;
-		if (*ue != '\0' && *g == '\0')
-			*gid = pwent->pw_gid;
 	}
 	if (*g != '\0') {
-		struct group *grp;
-		grp = getgrnam(g);
-		if (grp != NULL)
-			*gid = grp->gr_gid;
-		else {
-			cpio_warnc(errno, "Couldn't look up group ``%s''", g);
-			return (1);
+		*gid = decimal_parse(g);
+		if (*gid < 0) {
+			/* Couldn't parse int, try group name lookup. */
+			struct group *grp;
+			grp = getgrnam(g);
+			if (grp != NULL)
+				*gid = grp->gr_gid;
+			else {
+				cpio_warnc(errno,
+				    "Couldn't look up group ``%s''", g);
+				return (1);
+			}
 		}
 	}
 	return (0);

Modified: head/usr.bin/cpio/cpio.c
==============================================================================
--- head/usr.bin/cpio/cpio.c	Fri Jul  3 16:33:42 2009	(r195317)
+++ head/usr.bin/cpio/cpio.c	Fri Jul  3 17:54:33 2009	(r195318)
@@ -575,7 +575,7 @@ file_to_archive(struct cpio *cpio, const
 	if (cpio->uid_override >= 0)
 		st.st_uid = cpio->uid_override;
 	if (cpio->gid_override >= 0)
-		st.st_gid = cpio->uid_override;
+		st.st_gid = cpio->gid_override;
 	archive_entry_copy_stat(entry, &st);
 
 #if !defined(_WIN32) || defined(__CYGWIN__)


More information about the svn-src-head mailing list