summaryrefslogtreecommitdiffstats
path: root/contrib/csup/fattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/csup/fattr.c')
-rw-r--r--contrib/csup/fattr.c106
1 files changed, 49 insertions, 57 deletions
diff --git a/contrib/csup/fattr.c b/contrib/csup/fattr.c
index 59b6607..b29d73d 100644
--- a/contrib/csup/fattr.c
+++ b/contrib/csup/fattr.c
@@ -32,14 +32,13 @@
#include <assert.h>
#include <errno.h>
-#include <grp.h>
-#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "fattr.h"
+#include "idcache.h"
#include "misc.h"
/*
@@ -126,6 +125,8 @@ fattr_init(void)
fa->mask |= FA_MODE;
defaults[i] = fa;
}
+ /* Initialize the uid/gid lookup cache. */
+ idcache_init();
}
void
@@ -133,6 +134,7 @@ fattr_fini(void)
{
int i;
+ idcache_fini();
for (i = 0; i < FT_NUMBER; i++)
fattr_free(defaults[i]);
}
@@ -336,29 +338,26 @@ fattr_encode(const struct fattr *fa, fattr_support_t support, int ignore)
int extval;
char *ext;
} pieces[FA_NUMBER], *piece;
- struct passwd *pw;
- struct group *gr;
- char *cp, *s;
+ char *cp, *s, *username, *groupname;
size_t len, vallen;
mode_t mode, modemask;
int mask, n, i;
- pw = NULL;
- gr = NULL;
+ username = NULL;
+ groupname = NULL;
if (support == NULL)
mask = fa->mask;
else
mask = fa->mask & support[fa->type];
mask &= ~ignore;
- /* XXX - Use getpwuid_r() and getgrgid_r(). */
if (fa->mask & FA_OWNER) {
- pw = getpwuid(fa->uid);
- if (pw == NULL)
+ username = getuserbyid(fa->uid);
+ if (username == NULL)
mask &= ~FA_OWNER;
}
if (fa->mask & FA_GROUP) {
- gr = getgrgid(fa->gid);
- if (gr == NULL)
+ groupname = getgroupbyid(fa->gid);
+ if (groupname == NULL)
mask &= ~FA_GROUP;
}
if (fa->mask & FA_LINKCOUNT && fa->linkcount == 1)
@@ -408,17 +407,17 @@ fattr_encode(const struct fattr *fa, fattr_support_t support, int ignore)
piece++;
}
if (mask & FA_OWNER) {
- vallen = strlen(pw->pw_name);
+ vallen = strlen(username);
piece->extval = 1;
- piece->ext = pw->pw_name;
+ piece->ext = username;
len += snprintf(piece->len, sizeof(piece->len), "%lld",
(long long)vallen) + vallen + 1;
piece++;
}
if (mask & FA_GROUP) {
- vallen = strlen(gr->gr_name);
+ vallen = strlen(groupname);
piece->extval = 1;
- piece->ext = gr->gr_name;
+ piece->ext = groupname;
len += snprintf(piece->len, sizeof(piece->len), "%lld",
(long long)vallen) + vallen + 1;
piece++;
@@ -551,11 +550,10 @@ fattr_getlinkcount(const struct fattr *fa)
static char *
fattr_scanattr(struct fattr *fa, int type, const char *attr)
{
- struct passwd *pw;
- struct group *gr;
char *attrend, *attrstart, *end;
size_t len;
unsigned long attrlen;
+ int error;
mode_t modemask;
char tmp;
@@ -606,21 +604,13 @@ fattr_scanattr(struct fattr *fa, int type, const char *attr)
goto bad;
break;
case FA_OWNER:
- /*
- * XXX - We need to use getpwnam_r() since getpwnam()
- * is not thread-safe, and we also need to use a cache.
- */
- pw = getpwnam(attrstart);
- if (pw != NULL)
- fa->uid = pw->pw_uid;
- else
+ error = getuidbyname(attrstart, &fa->uid);
+ if (error)
fa->mask &= ~FA_OWNER;
break;
case FA_GROUP:
- gr = getgrnam(attrstart);
- if (gr != NULL)
- fa->gid = gr->gr_gid;
- else
+ error = getgidbyname(attrstart, &fa->gid);
+ if (error)
fa->mask &= ~FA_GROUP;
break;
case FA_MODE:
@@ -770,11 +760,13 @@ fattr_delete(const char *path)
return (-1);
}
+#ifdef HAVE_FFLAGS
/* Clear flags. */
if (fa->mask & FA_FLAGS && fa->flags != 0) {
fa->flags = 0;
(void)chflags(path, fa->flags);
}
+#endif
if (fa->type == FT_DIRECTORY)
error = rmdir(path);
@@ -812,35 +804,35 @@ fattr_install(struct fattr *fa, const char *topath, const char *frompath)
inplace = 1;
}
old = fattr_frompath(topath, FATTR_NOFOLLOW);
- if (old == NULL)
- return (-1);
- if (inplace && fattr_equal(fa, old)) {
- fattr_free(old);
- return (0);
- }
+ if (old != NULL) {
+ if (inplace && fattr_equal(fa, old)) {
+ fattr_free(old);
+ return (0);
+ }
#ifdef HAVE_FFLAGS
- /*
- * Determine whether we need to clear the flags of the target.
- * This is bogus in that it assumes a value of 0 is safe and
- * that non-zero is unsafe. I'm not really worried by that
- * since as far as I know that's the way things are.
- */
- if ((old->mask & FA_FLAGS) && old->flags > 0) {
- (void)chflags(topath, 0);
- old->flags = 0;
- }
+ /*
+ * Determine whether we need to clear the flags of the target.
+ * This is bogus in that it assumes a value of 0 is safe and
+ * that non-zero is unsafe. I'm not really worried by that
+ * since as far as I know that's the way things are.
+ */
+ if ((old->mask & FA_FLAGS) && old->flags > 0) {
+ (void)chflags(topath, 0);
+ old->flags = 0;
+ }
#endif
- /* Determine whether we need to remove the target first. */
- if (!inplace && (fa->type == FT_DIRECTORY) !=
- (old->type == FT_DIRECTORY)) {
- if (old->type == FT_DIRECTORY)
- error = rmdir(topath);
- else
- error = unlink(topath);
- if (error)
- goto bad;
+ /* Determine whether we need to remove the target first. */
+ if (!inplace && (fa->type == FT_DIRECTORY) !=
+ (old->type == FT_DIRECTORY)) {
+ if (old->type == FT_DIRECTORY)
+ error = rmdir(topath);
+ else
+ error = unlink(topath);
+ if (error)
+ goto bad;
+ }
}
/* Change those attributes that we can before moving the file
@@ -866,8 +858,8 @@ fattr_install(struct fattr *fa, const char *topath, const char *frompath)
}
if (mask & FA_MODE) {
newmode = fa->mode & modemask;
- /* Merge in set*id bits from the old attribute. XXX - Why? */
- if (old->mask & FA_MODE) {
+ /* Merge in set*id bits from the old attribute. */
+ if (old != NULL && old->mask & FA_MODE) {
newmode |= (old->mode & ~modemask);
newmode &= (FA_SETIDMASK | FA_PERMMASK);
}
OpenPOWER on IntegriCloud