]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Merge r195389 from FreeBSD-CURRENT: Rework the
authorTim Kientzle <kientzle@gmail.com>
Sun, 19 Jul 2009 08:35:58 +0000 (04:35 -0400)
committerTim Kientzle <kientzle@gmail.com>
Sun, 19 Jul 2009 08:35:58 +0000 (04:35 -0400)
numeric uid/gid support for the -R option.

SVN-Revision: 1242

cpio/cmdline.c
cpio/test/test_owner_parse.c

index 6dd6082b757d9737447d7a4492abace0c958fe35..d16386ca0e65094d28a3fe39d50f10666bf57557 100644 (file)
@@ -279,29 +279,14 @@ cpio_getopt(struct cpio *cpio)
  *   :<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.
+ * are names to be looked up in system database.  Note that we try
+ * to look up an argument as a name first, then try numeric parsing.
  *
  * A period can be used instead of the colon.
  *
  * 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)
 {
@@ -310,6 +295,9 @@ owner_parse(const char *spec, int *uid, int *gid)
        *uid = -1;
        *gid = -1;
 
+       if (spec[0] == '\0')
+               return (1);
+
        /*
         * Split spec into [user][:.][group]
         *  u -> first char of username, NULL if no username
@@ -342,32 +330,34 @@ owner_parse(const char *spec, int *uid, int *gid)
                }
                memcpy(user, u, ue - u);
                user[ue - u] = '\0';
-               *uid = decimal_parse(user);
-               if (*uid < 0) {
-                       /* Couldn't parse as integer, try username lookup. */
-                       pwent = getpwnam(user);
-                       if (pwent == NULL) {
+               if ((pwent = getpwnam(user)) != NULL) {
+                       *uid = pwent->pw_uid;
+                       if (*ue != '\0')
+                               *gid = pwent->pw_gid;
+               } else {
+                       char *end;
+                       errno = 0;
+                       *uid = strtoul(user, &end, 10);
+                       if (errno || *end != '\0') {
                                lafe_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);
        }
+
        if (*g != '\0') {
-               *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 {
+               struct group *grp;
+               if ((grp = getgrnam(g)) != NULL) {
+                       *gid = grp->gr_gid;
+               } else {
+                       char *end;
+                       errno = 0;
+                       *gid = strtoul(g, &end, 10);
+                       if (errno || *end != '\0') {
                                lafe_warnc(errno,
-                                   "Couldn't look up group ``%s''", g);
+                                   "Couldn't lookup group ``%s''", g);
                                return (1);
                        }
                }
index 050d5a088d28d3e4563503b5e89db12dc58392bf..7288bb496d5ac3dbc985eeb95e01c1277a40ecba 100644 (file)
@@ -52,6 +52,7 @@ int_in_list(int i, int *l, size_t n)
        while (n-- > 0)
                if (*l++ == i)
                        return (1);
+       failure("%d", i);
        return (0);
 }
 
@@ -63,8 +64,6 @@ DEFINE_TEST(test_owner_parse)
 #else
        int uid, gid;
 
-       lafe_progname = "cpio";
-
        assertEqualInt(0, owner_parse(ROOT, &uid, &gid));
        assert(int_in_list(uid, root_uids,
                sizeof(root_uids)/sizeof(root_uids[0])));