diff options
author | Tim Kientzle <kientzle@gmail.com> | 2009-07-19 04:35:58 -0400 |
---|---|---|
committer | Tim Kientzle <kientzle@gmail.com> | 2009-07-19 04:35:58 -0400 |
commit | 85c48957c151e86b9e20c4b3fcaa95f815d7a44c (patch) | |
tree | 7ef47b5bbb6091de9feec4539497336d540eed01 /cpio/cmdline.c | |
parent | 6f0409633d03a5eb1a72b262a156ebeae5d82f20 (diff) | |
download | libarchive-85c48957c151e86b9e20c4b3fcaa95f815d7a44c.tar.gz |
Merge r195389 from FreeBSD-CURRENT: Rework the
numeric uid/gid support for the -R option.
SVN-Revision: 1242
Diffstat (limited to 'cpio/cmdline.c')
-rw-r--r-- | cpio/cmdline.c | 58 |
1 files changed, 24 insertions, 34 deletions
diff --git a/cpio/cmdline.c b/cpio/cmdline.c index 6dd6082b..d16386ca 100644 --- a/cpio/cmdline.c +++ b/cpio/cmdline.c @@ -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); } } |