From: Tim Kientzle Date: Sun, 19 Jul 2009 08:35:58 +0000 (-0400) Subject: Merge r195389 from FreeBSD-CURRENT: Rework the X-Git-Tag: v2.8.0~519 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=85c48957c151e86b9e20c4b3fcaa95f815d7a44c;p=thirdparty%2Flibarchive.git Merge r195389 from FreeBSD-CURRENT: Rework the numeric uid/gid support for the -R option. SVN-Revision: 1242 --- diff --git a/cpio/cmdline.c b/cpio/cmdline.c index 6dd6082b7..d16386ca0 100644 --- a/cpio/cmdline.c +++ b/cpio/cmdline.c @@ -279,29 +279,14 @@ cpio_getopt(struct cpio *cpio) * : - 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); } } diff --git a/cpio/test/test_owner_parse.c b/cpio/test/test_owner_parse.c index 050d5a088..7288bb496 100644 --- a/cpio/test/test_owner_parse.c +++ b/cpio/test/test_owner_parse.c @@ -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])));