summaryrefslogtreecommitdiffstats
path: root/lib/libarchive
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2009-04-17 00:44:47 +0000
committerkientzle <kientzle@FreeBSD.org>2009-04-17 00:44:47 +0000
commitfecbf2a6965a8f465b8ec2172f67b38354c7191e (patch)
tree36451dfd13f16ecb0f9ba7b68031a405aa3ad4c7 /lib/libarchive
parent1b0a8e451a6fc27ef612215c82d205ee6202ddb4 (diff)
downloadFreeBSD-src-fecbf2a6965a8f465b8ec2172f67b38354c7191e.zip
FreeBSD-src-fecbf2a6965a8f465b8ec2172f67b38354c7191e.tar.gz
Use thread-safe getgrnam_r() and getpwnam_r(); dynamically size
the buffer used by this.
Diffstat (limited to 'lib/libarchive')
-rw-r--r--lib/libarchive/archive_write_disk_set_standard_lookup.c56
1 files changed, 50 insertions, 6 deletions
diff --git a/lib/libarchive/archive_write_disk_set_standard_lookup.c b/lib/libarchive/archive_write_disk_set_standard_lookup.c
index 5329425..59f6e17 100644
--- a/lib/libarchive/archive_write_disk_set_standard_lookup.c
+++ b/lib/libarchive/archive_write_disk_set_standard_lookup.c
@@ -118,12 +118,34 @@ lookup_gid(void *private_data, const char *gname, gid_t gid)
b->hash = h;
#if HAVE_GRP_H
{
- struct group *grent = getgrnam(gname);
- if (grent != NULL)
- gid = grent->gr_gid;
+ char _buffer[128];
+ size_t bufsize = 128;
+ char *buffer = _buffer;
+ struct group grent, *result;
+ int r;
+
+ for (;;) {
+ r = getgrnam_r(gname, &grent, buffer, bufsize, &result);
+ if (r == 0)
+ break;
+ if (r != ERANGE)
+ break;
+ bufsize *= 2;
+ if (buffer != _buffer)
+ free(buffer);
+ buffer = malloc(bufsize);
+ if (buffer == NULL)
+ break;
+ }
+ if (result != NULL)
+ gid = result->gr_gid;
+ if (buffer != _buffer)
+ free(buffer);
}
#elif defined(_WIN32) && !defined(__CYGWIN__)
/* TODO: do a gname->gid lookup for Windows. */
+#else
+ #error No way to perform gid lookups on this platform
#endif
b->id = gid;
@@ -155,12 +177,34 @@ lookup_uid(void *private_data, const char *uname, uid_t uid)
b->hash = h;
#if HAVE_PWD_H
{
- struct passwd *pwent = getpwnam(uname);
- if (pwent != NULL)
- uid = pwent->pw_uid;
+ char _buffer[128];
+ size_t bufsize = 128;
+ char *buffer = _buffer;
+ struct passwd pwent, *result;
+ int r;
+
+ for (;;) {
+ r = getpwnam_r(uname, &pwent, buffer, bufsize, &result);
+ if (r == 0)
+ break;
+ if (r != ERANGE)
+ break;
+ bufsize *= 2;
+ if (buffer != _buffer)
+ free(buffer);
+ buffer = malloc(bufsize);
+ if (buffer == NULL)
+ break;
+ }
+ if (result != NULL)
+ uid = result->pw_uid;
+ if (buffer != _buffer)
+ free(buffer);
}
#elif defined(_WIN32) && !defined(__CYGWIN__)
/* TODO: do a uname->uid lookup for Windows. */
+#else
+ #error No way to look up uids on this platform
#endif
b->id = uid;
OpenPOWER on IntegriCloud