pax includes routines for caching getpw{nam,uid} and getgr{nam,gid}
results. Okay, but libc already has caching uid->name and gid->name
routines: user_from_uid() and group_from_gid(). Let's switch pax over to
the libc routines. That'll free up a little space on the ramdisks.
Notes:
1) the pax routines and the libc routines have opposite senses on the
second argument which controls what to do when the uid/gid has no
matching user/group.
2) need to #include <pwd.h> and <grp.h> for these; I sort the <*.h>
#includes in the affected files.
3) in ustar_wr(), the header block is memset(0) so we can completely skip
the strncpy() operations when there's no matching name or when the -N
flag is used, so we can delete more strncpy()s
4) there was some confusion between GID_SZ and GNM_SZ, where the
gid_name() cache was allocated with GNM_SZ and then lookups use GID_SZ.
Good thing they were the same size, but let's make them consistent...
Verbose listing output looks the same (that's the gen_subs.c path) and the
header of a ustar archive looks like the same (that's the tar.c path).
ok?
Philip Guenther
Index: gen_subs.c
===================================================================
RCS file: /data/src/openbsd/src/bin/pax/gen_subs.c,v
retrieving revision 1.29
diff -u -p -r1.29 gen_subs.c
--- gen_subs.c 14 Aug 2016 04:47:52 -0000 1.29
+++ gen_subs.c 24 Aug 2016 22:08:28 -0000
@@ -37,12 +37,15 @@
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
+#include <grp.h>
+#include <pwd.h>
#include <stdio.h>
-#include <utmp.h>
-#include <unistd.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+#include <utmp.h>
#include <vis.h>
+
#include "pax.h"
#include "extern.h"
@@ -104,8 +107,8 @@ ls_list(ARCHD *arcn, time_t now, FILE *f
localtime(&(sbp->st_mtime))) == 0)
f_date[0] = '\0';
(void)fprintf(fp, "%s%2u %-*.*s %-*.*s ", f_mode, sbp->st_nlink,
- NAME_WIDTH, UT_NAMESIZE, name_uid(sbp->st_uid, 1),
- NAME_WIDTH, UT_NAMESIZE, name_gid(sbp->st_gid, 1));
+ NAME_WIDTH, UT_NAMESIZE, user_from_uid(sbp->st_uid, 0),
+ NAME_WIDTH, UT_NAMESIZE, group_from_gid(sbp->st_gid, 0));
/*
* print device id's for devices, or sizes for other nodes
Index: tar.c
===================================================================
RCS file: /data/src/openbsd/src/bin/pax/tar.c,v
retrieving revision 1.61
diff -u -p -r1.61 tar.c
--- tar.c 14 Aug 2016 18:30:33 -0000 1.61
+++ tar.c 24 Aug 2016 22:13:09 -0000
@@ -39,11 +39,14 @@
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>
+#include <grp.h>
#include <limits.h>
-#include <string.h>
+#include <pwd.h>
#include <stdio.h>
-#include <unistd.h>
#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
#include "pax.h"
#include "extern.h"
#include "tar.h"
@@ -679,21 +682,6 @@ ustar_strd(void)
}
/*
- * ustar_stwr()
- * initialization for ustar write
- * Return:
- * 0 if ok, -1 otherwise
- */
-
-int
-ustar_stwr(void)
-{
- if ((uidtb_start() < 0) || (gidtb_start() < 0))
- return(-1);
- return(0);
-}
-
-/*
* ustar_id()
* determine if a block given to us is a valid ustar header. We have to
* be on the lookout for those pesky blocks of all zero's
@@ -934,7 +922,7 @@ int
ustar_wr(ARCHD *arcn)
{
HD_USTAR *hd;
- char *pt;
+ char *pt, *name;
char hdblk[sizeof(HD_USTAR)];
/*
@@ -1094,11 +1082,10 @@ ustar_wr(ARCHD *arcn)
ul_oct(arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 3))
goto out;
if (!Nflag) {
- strncpy(hd->uname, name_uid(arcn->sb.st_uid, 0),
sizeof(hd->uname));
- strncpy(hd->gname, name_gid(arcn->sb.st_gid, 0),
sizeof(hd->gname));
- } else {
- strncpy(hd->uname, "", sizeof(hd->uname));
- strncpy(hd->gname, "", sizeof(hd->gname));
+ if ((name = user_from_uid(arcn->sb.st_uid, 1)) != NULL)
+ strncpy(hd->uname, name, sizeof(hd->uname));
+ if ((name = group_from_gid(arcn->sb.st_gid, 1)) != NULL)
+ strncpy(hd->gname, name, sizeof(hd->gname));
}
/*
Index: ar_subs.c
===================================================================
RCS file: /data/src/openbsd/src/bin/pax/ar_subs.c,v
retrieving revision 1.45
diff -u -p -r1.45 ar_subs.c
--- ar_subs.c 19 Mar 2015 05:14:24 -0000 1.45
+++ ar_subs.c 24 Aug 2016 22:13:55 -0000
@@ -86,9 +86,6 @@ list(void)
((*frmt->st_rd)() < 0))
return;
- if (vflag && ((uidtb_start() < 0) || (gidtb_start() < 0)))
- return;
-
now = time(NULL);
/*
Index: options.c
===================================================================
RCS file: /data/src/openbsd/src/bin/pax/options.c,v
retrieving revision 1.97
diff -u -p -r1.97 options.c
--- options.c 24 Aug 2016 19:15:42 -0000 1.97
+++ options.c 24 Aug 2016 22:07:14 -0000
@@ -126,7 +126,7 @@ FSUB fsub[] = {
/* 5: POSIX USTAR */
{"ustar", 10240, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, ustar_strd,
- ustar_rd, tar_endrd, ustar_stwr, ustar_wr, tar_endwr, tar_trail,
+ ustar_rd, tar_endrd, no_op, ustar_wr, tar_endwr, tar_trail,
tar_opt},
#ifdef SMALL
Index: extern.h
===================================================================
RCS file: /data/src/openbsd/src/bin/pax/extern.h,v
retrieving revision 1.56
diff -u -p -r1.56 extern.h
--- extern.h 23 Aug 2016 06:00:28 -0000 1.56
+++ extern.h 24 Aug 2016 22:07:30 -0000
@@ -98,12 +98,8 @@ int buf_flush(int);
/*
* cache.c
*/
-int uidtb_start(void);
-int gidtb_start(void);
int usrtb_start(void);
int grptb_start(void);
-char * name_uid(uid_t, int);
-char * name_gid(gid_t, int);
int uid_name(char *, uid_t *);
int gid_name(char *, gid_t *);
@@ -306,7 +302,6 @@ int tar_opt(void);
int tar_rd(ARCHD *, char *);
int tar_wr(ARCHD *);
int ustar_strd(void);
-int ustar_stwr(void);
int ustar_id(char *, int);
int ustar_rd(ARCHD *, char *);
int ustar_wr(ARCHD *);
Index: cache.c
===================================================================
RCS file: /data/src/openbsd/src/bin/pax/cache.c,v
retrieving revision 1.21
diff -u -p -r1.21 cache.c
--- cache.c 24 May 2014 18:51:00 -0000 1.21
+++ cache.c 24 Aug 2016 23:36:36 -0000
@@ -56,60 +56,10 @@
static int pwopn = 0; /* is password file open */
static int gropn = 0; /* is group file open */
-static UIDC **uidtb = NULL; /* uid to name cache */
-static GIDC **gidtb = NULL; /* gid to name cache */
static UIDC **usrtb = NULL; /* user name to uid cache */
static GIDC **grptb = NULL; /* group name to gid cache */
/*
- * uidtb_start
- * creates an empty uidtb
- * Return:
- * 0 if ok, -1 otherwise
- */
-
-int
-uidtb_start(void)
-{
- static int fail = 0;
-
- if (uidtb != NULL)
- return(0);
- if (fail)
- return(-1);
- if ((uidtb = calloc(UID_SZ, sizeof(UIDC *))) == NULL) {
- ++fail;
- paxwarn(1, "Unable to allocate memory for user id cache table");
- return(-1);
- }
- return(0);
-}
-
-/*
- * gidtb_start
- * creates an empty gidtb
- * Return:
- * 0 if ok, -1 otherwise
- */
-
-int
-gidtb_start(void)
-{
- static int fail = 0;
-
- if (gidtb != NULL)
- return(0);
- if (fail)
- return(-1);
- if ((gidtb = calloc(GID_SZ, sizeof(GIDC *))) == NULL) {
- ++fail;
- paxwarn(1, "Unable to allocate memory for group id cache
table");
- return(-1);
- }
- return(0);
-}
-
-/*
* usrtb_start
* creates an empty usrtb
* Return:
@@ -158,138 +108,6 @@ grptb_start(void)
}
/*
- * name_uid()
- * caches the name (if any) for the uid. If frc set, we always return the
- * the stored name (if valid or invalid match). We use a simple hash table.
- * Return
- * Pointer to stored name (or a empty string)
- */
-
-char *
-name_uid(uid_t uid, int frc)
-{
- struct passwd *pw;
- UIDC *ptr;
-
- if ((uidtb == NULL) && (uidtb_start() < 0))
- return("");
-
- /*
- * see if we have this uid cached
- */
- ptr = uidtb[uid % UID_SZ];
- if ((ptr != NULL) && (ptr->valid > 0) && (ptr->uid == uid)) {
- /*
- * have an entry for this uid
- */
- if (frc || (ptr->valid == VALID))
- return(ptr->name);
- return("");
- }
-
- /*
- * No entry for this uid, we will add it
- */
- if (!pwopn) {
- setpassent(1);
- ++pwopn;
- }
- if (ptr == NULL)
- ptr = uidtb[uid % UID_SZ] = malloc(sizeof(UIDC));
-
- if ((pw = getpwuid(uid)) == NULL) {
- /*
- * no match for this uid in the local password file
- * a string that is the uid in numeric format
- */
- if (ptr == NULL)
- return("");
- ptr->uid = uid;
- ptr->valid = INVALID;
- (void)snprintf(ptr->name, sizeof(ptr->name), "%lu",
- (unsigned long)uid);
- if (frc == 0)
- return("");
- } else {
- /*
- * there is an entry for this uid in the password file
- */
- if (ptr == NULL)
- return(pw->pw_name);
- ptr->uid = uid;
- (void)strlcpy(ptr->name, pw->pw_name, sizeof(ptr->name));
- ptr->valid = VALID;
- }
- return(ptr->name);
-}
-
-/*
- * name_gid()
- * caches the name (if any) for the gid. If frc set, we always return the
- * the stored name (if valid or invalid match). We use a simple hash table.
- * Return
- * Pointer to stored name (or a empty string)
- */
-
-char *
-name_gid(gid_t gid, int frc)
-{
- struct group *gr;
- GIDC *ptr;
-
- if ((gidtb == NULL) && (gidtb_start() < 0))
- return("");
-
- /*
- * see if we have this gid cached
- */
- ptr = gidtb[gid % GID_SZ];
- if ((ptr != NULL) && (ptr->valid > 0) && (ptr->gid == gid)) {
- /*
- * have an entry for this gid
- */
- if (frc || (ptr->valid == VALID))
- return(ptr->name);
- return("");
- }
-
- /*
- * No entry for this gid, we will add it
- */
- if (!gropn) {
- setgroupent(1);
- ++gropn;
- }
- if (ptr == NULL)
- ptr = gidtb[gid % GID_SZ] = malloc(sizeof(GIDC));
-
- if ((gr = getgrgid(gid)) == NULL) {
- /*
- * no match for this gid in the local group file, put in
- * a string that is the gid in numeric format
- */
- if (ptr == NULL)
- return("");
- ptr->gid = gid;
- ptr->valid = INVALID;
- (void)snprintf(ptr->name, sizeof(ptr->name), "%lu",
- (unsigned long)gid);
- if (frc == 0)
- return("");
- } else {
- /*
- * there is an entry for this group in the group file
- */
- if (ptr == NULL)
- return(gr->gr_name);
- ptr->gid = gid;
- (void)strlcpy(ptr->name, gr->gr_name, sizeof(ptr->name));
- ptr->valid = VALID;
- }
- return(ptr->name);
-}
-
-/*
* uid_name()
* caches the uid for a given user name. We use a simple hash table.
* Return
@@ -378,7 +196,7 @@ gid_name(char *name, gid_t *gid)
* look up in hash table, if found and valid return the uid,
* if found and invalid, return a -1
*/
- ptr = grptb[st_hash(name, namelen, GID_SZ)];
+ ptr = grptb[st_hash(name, namelen, GNM_SZ)];
if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
if (ptr->valid == INVALID)
return(-1);
@@ -391,7 +209,7 @@ gid_name(char *name, gid_t *gid)
++gropn;
}
if (ptr == NULL)
- ptr = grptb[st_hash(name, namelen, GID_SZ)] =
+ ptr = grptb[st_hash(name, namelen, GNM_SZ)] =
malloc(sizeof(GIDC));
/*
Index: cache.h
===================================================================
RCS file: /data/src/openbsd/src/bin/pax/cache.h,v
retrieving revision 1.7
diff -u -p -r1.7 cache.h
--- cache.h 24 Dec 2015 05:50:15 -0000 1.7
+++ cache.h 24 Aug 2016 23:37:47 -0000
@@ -49,10 +49,8 @@
*/
#define UNMLEN 32 /* >= user name found in any protocol */
#define GNMLEN 32 /* >= group name found in any protocol */
-#define UID_SZ 317 /* size of user_name/uid cache */
-#define UNM_SZ 317 /* size of user_name/uid cache */
-#define GID_SZ 251 /* size of gid cache */
-#define GNM_SZ 317 /* size of group name cache */
+#define UNM_SZ 317 /* size of uid_name() cache */
+#define GNM_SZ 317 /* size of gid_name() cache */
#define VALID 1 /* entry and name are valid */
#define INVALID 2 /* entry valid, name NOT valid */