summaryrefslogtreecommitdiff
path: root/libarchive/archive_write_disk_set_standard_lookup.c
diff options
context:
space:
mode:
authorTim Kientzle <kientzle@gmail.com>2009-04-01 20:30:54 -0400
committerTim Kientzle <kientzle@gmail.com>2009-04-01 20:30:54 -0400
commit4a55d43d91f7ce0617658afa1d764965abf743fc (patch)
tree2102ca1c40f3d83db127f5e8fe32273c8d79afef /libarchive/archive_write_disk_set_standard_lookup.c
parent88b368fb0c3bcbf770cd77b7811b2f5a849c51bb (diff)
downloadlibarchive-4a55d43d91f7ce0617658afa1d764965abf743fc.tar.gz
Issue 19: Use getpwnam_r/getgrnam_r to look up uids and gids,
since they're thread-safe. SVN-Revision: 905
Diffstat (limited to 'libarchive/archive_write_disk_set_standard_lookup.c')
-rw-r--r--libarchive/archive_write_disk_set_standard_lookup.c56
1 files changed, 50 insertions, 6 deletions
diff --git a/libarchive/archive_write_disk_set_standard_lookup.c b/libarchive/archive_write_disk_set_standard_lookup.c
index 805c8c68..55373b8c 100644
--- a/libarchive/archive_write_disk_set_standard_lookup.c
+++ b/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;