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 */
 

Reply via email to