pax(8): Switch to using libc's pwcache instead of a local implementation.
authorSascha Wildner <saw@online.de>
Thu, 5 Apr 2018 07:36:00 +0000 (09:36 +0200)
committerSascha Wildner <saw@online.de>
Thu, 5 Apr 2018 07:36:00 +0000 (09:36 +0200)
Based-on: NetBSD

bin/pax/Makefile
bin/pax/ar_subs.c
bin/pax/cache.c [deleted file]
bin/pax/cache.h [deleted file]
bin/pax/extern.h
bin/pax/gen_subs.c
bin/pax/tar.c

index ea4ce16..77cf2c0 100644 (file)
@@ -1,9 +1,8 @@
 #       @(#)Makefile   8.1 (Berkeley) 5/31/93
 # $FreeBSD: src/bin/pax/Makefile,v 1.5.2.1 2001/08/01 05:03:11 obrien Exp $
-# $DragonFly: src/bin/pax/Makefile,v 1.5 2006/09/27 19:18:00 pavalos Exp $
 
 PROG=   pax
-SRCS=  ar_io.c ar_subs.c buf_subs.c cache.c cpio.c file_subs.c ftree.c \
+SRCS=  ar_io.c ar_subs.c buf_subs.c cpio.c file_subs.c ftree.c \
        gen_subs.c getoldopt.c options.c pat_rep.c pax.c sel_subs.c \
        tables.c tar.c tty_subs.c
 
index 0a8f046..8b9cc48 100644 (file)
@@ -32,7 +32,6 @@
  *
  * @(#)ar_subs.c       8.2 (Berkeley) 4/18/94
  * $FreeBSD: src/bin/pax/ar_subs.c,v 1.13.2.1 2001/08/01 05:03:11 obrien Exp $
- * $DragonFly: src/bin/pax/ar_subs.c,v 1.7 2006/09/27 21:58:08 pavalos Exp $
  */
 
 #include <sys/types.h>
@@ -87,9 +86,6 @@ list(void)
            ((*frmt->st_rd)() < 0))
                return;
 
-       if (vflag && ((uidtb_start() < 0) || (gidtb_start() < 0)))
-               return;
-
        now = time(NULL);
 
        /*
diff --git a/bin/pax/cache.c b/bin/pax/cache.c
deleted file mode 100644 (file)
index ed9d92e..0000000
+++ /dev/null
@@ -1,420 +0,0 @@
-/*-
- * Copyright (c) 1992 Keith Muller.
- * Copyright (c) 1992, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Keith Muller of the University of California, San Diego.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)cache.c 8.1 (Berkeley) 5/31/93
- * $FreeBSD: src/bin/pax/cache.c,v 1.12.2.1 2001/08/01 05:03:11 obrien Exp $
- * $DragonFly: src/bin/pax/cache.c,v 1.7 2006/09/27 21:58:08 pavalos Exp $
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <stdio.h>
-#include <pwd.h>
-#include <grp.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include "pax.h"
-#include "cache.h"
-#include "extern.h"
-
-/*
- * routines that control user, group, uid and gid caches (for the archive
- * member print routine).
- * IMPORTANT:
- * these routines cache BOTH hits and misses, a major performance improvement
- */
-
-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 = (UIDC **)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 = (GIDC **)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:
- *     0 if ok, -1 otherwise
- */
-
-int
-usrtb_start(void)
-{
-       static int fail = 0;
-
-       if (usrtb != NULL)
-               return(0);
-       if (fail)
-               return(-1);
-       if ((usrtb = (UIDC **)calloc(UNM_SZ, sizeof(UIDC *))) == NULL) {
-               ++fail;
-               paxwarn(1, "Unable to allocate memory for user name cache table");
-               return(-1);
-       }
-       return(0);
-}
-
-/*
- * grptb_start
- *     creates an empty grptb
- * Return:
- *     0 if ok, -1 otherwise
- */
-
-int
-grptb_start(void)
-{
-       static int fail = 0;
-
-       if (grptb != NULL)
-               return(0);
-       if (fail)
-               return(-1);
-       if ((grptb = (GIDC **)calloc(GNM_SZ, sizeof(GIDC *))) == NULL) {
-               ++fail;
-               paxwarn(1,"Unable to allocate memory for group name cache table");
-               return(-1);
-       }
-       return(0);
-}
-
-/*
- * 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 = (UIDC *)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;
-               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;
-               strncpy(ptr->name, pw->pw_name, UNMLEN - 1);
-               ptr->name[UNMLEN-1] = '\0';
-               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 = (GIDC *)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;
-               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;
-               strncpy(ptr->name, gr->gr_name, GNMLEN - 1);
-               ptr->name[GNMLEN-1] = '\0';
-               ptr->valid = VALID;
-       }
-       return(ptr->name);
-}
-
-/*
- * uid_name()
- *     caches the uid for a given user name. We use a simple hash table.
- * Return
- *     the uid (if any) for a user name, or a -1 if no match can be found
- */
-
-int
-uid_name(char *name, uid_t *uid)
-{
-       struct passwd *pw;
-       UIDC *ptr;
-       int namelen;
-
-       /*
-        * return -1 for mangled names
-        */
-       if (((namelen = strlen(name)) == 0) || (name[0] == '\0'))
-               return(-1);
-       if ((usrtb == NULL) && (usrtb_start() < 0))
-               return(-1);
-
-       /*
-        * look up in hash table, if found and valid return the uid,
-        * if found and invalid, return a -1
-        */
-       ptr = usrtb[st_hash(name, namelen, UNM_SZ)];
-       if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
-               if (ptr->valid == INVALID)
-                       return(-1);
-               *uid = ptr->uid;
-               return(0);
-       }
-
-       if (!pwopn) {
-               setpassent(1);
-               ++pwopn;
-       }
-
-       if (ptr == NULL)
-               ptr = usrtb[st_hash(name, namelen, UNM_SZ)] =
-                 (UIDC *)malloc(sizeof(UIDC));
-
-       /*
-        * no match, look it up, if no match store it as an invalid entry,
-        * or store the matching uid
-        */
-       if (ptr == NULL) {
-               if ((pw = getpwnam(name)) == NULL)
-                       return(-1);
-               *uid = pw->pw_uid;
-               return(0);
-       }
-       strncpy(ptr->name, name, UNMLEN - 1);
-       ptr->name[UNMLEN-1] = '\0';
-       if ((pw = getpwnam(name)) == NULL) {
-               ptr->valid = INVALID;
-               return(-1);
-       }
-       ptr->valid = VALID;
-       *uid = ptr->uid = pw->pw_uid;
-       return(0);
-}
-
-/*
- * gid_name()
- *     caches the gid for a given group name. We use a simple hash table.
- * Return
- *     the gid (if any) for a group name, or a -1 if no match can be found
- */
-
-int
-gid_name(char *name, gid_t *gid)
-{
-       struct group *gr;
-       GIDC *ptr;
-       int namelen;
-
-       /*
-        * return -1 for mangled names
-        */
-       if (((namelen = strlen(name)) == 0) || (name[0] == '\0'))
-               return(-1);
-       if ((grptb == NULL) && (grptb_start() < 0))
-               return(-1);
-
-       /*
-        * 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)];
-       if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
-               if (ptr->valid == INVALID)
-                       return(-1);
-               *gid = ptr->gid;
-               return(0);
-       }
-
-       if (!gropn) {
-               setgroupent(1);
-               ++gropn;
-       }
-       if (ptr == NULL)
-               ptr = grptb[st_hash(name, namelen, GID_SZ)] =
-                 (GIDC *)malloc(sizeof(GIDC));
-
-       /*
-        * no match, look it up, if no match store it as an invalid entry,
-        * or store the matching gid
-        */
-       if (ptr == NULL) {
-               if ((gr = getgrnam(name)) == NULL)
-                       return(-1);
-               *gid = gr->gr_gid;
-               return(0);
-       }
-
-       strncpy(ptr->name, name, GNMLEN - 1);
-       ptr->name[GNMLEN-1] = '\0';
-       if ((gr = getgrnam(name)) == NULL) {
-               ptr->valid = INVALID;
-               return(-1);
-       }
-       ptr->valid = VALID;
-       *gid = ptr->gid = gr->gr_gid;
-       return(0);
-}
diff --git a/bin/pax/cache.h b/bin/pax/cache.h
deleted file mode 100644 (file)
index f8e813e..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*-
- * Copyright (c) 1992 Keith Muller.
- * Copyright (c) 1992, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Keith Muller of the University of California, San Diego.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *      @(#)cache.h    8.1 (Berkeley) 5/31/93
- * $FreeBSD: src/bin/pax/cache.h,v 1.6 1999/08/27 23:14:40 peter Exp $
- * $DragonFly: src/bin/pax/cache.h,v 1.2 2003/06/17 04:22:50 dillon Exp $
- */
-
-/*
- * Constants and data structures used to implement group and password file
- * caches. Traditional passwd/group cache routines perform quite poorly with
- * archives. The chances of hitting a valid lookup with an archive is quite a
- * bit worse than with files already resident on the file system. These misses
- * create a MAJOR performance cost. To address this problem, these routines
- * cache both hits and misses.
- *
- * NOTE:  name lengths must be as large as those stored in ANY PROTOCOL and
- * as stored in the passwd and group files. CACHE SIZES MUST BE PRIME
- */
-#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 VALID          1       /* entry and name are valid */
-#define INVALID                2       /* entry valid, name NOT valid */
-
-/*
- * Node structures used in the user, group, uid, and gid caches.
- */
-
-typedef struct uidc {
-       int valid;              /* is this a valid or a miss entry */
-       char name[UNMLEN];      /* uid name */
-       uid_t uid;              /* cached uid */
-} UIDC;
-
-typedef struct gidc {
-       int valid;              /* is this a valid or a miss entry */
-       char name[GNMLEN];      /* gid name */
-       gid_t gid;              /* cached gid */
-} GIDC;
index f748033..552ea0f 100644 (file)
@@ -164,7 +164,7 @@ int next_file (ARCHD *);
  */
 void ls_list (ARCHD *, time_t, FILE *);
 void ls_tty (ARCHD *);
-int l_strncpy (char *, char *, int);
+int l_strncpy (char *, const char *, int);
 u_long asc_ul (char *, int, int);
 int ul_asc (u_long, char *, int, int);
 u_quad_t asc_uqd (char *, int, int);
index e9b50f3..fcfb362 100644 (file)
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/stat.h>
+#include <grp.h>
 #include <langinfo.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"
 
@@ -74,6 +76,7 @@ ls_list(ARCHD *arcn, time_t now, FILE *fp)
        char f_mode[MODELEN];
        char f_date[DATELEN];
        char *timefrmt;
+       const char *user, *group;
 
        /*
         * if not verbose, just print the file name
@@ -105,9 +108,10 @@ ls_list(ARCHD *arcn, time_t now, FILE *fp)
         */
        if (strftime(f_date,DATELEN,timefrmt,localtime(&(sbp->st_mtime))) == 0)
                f_date[0] = '\0';
+       user = user_from_uid(sbp->st_uid, 0);
+       group = group_from_gid(sbp->st_gid, 0);
        fprintf(fp, "%s%2u %-16s %-6s ", f_mode, sbp->st_nlink,
-               name_uid(sbp->st_uid, 1),
-               name_gid(sbp->st_gid, 1));
+               user ? user : "", group ? group : "");
 
        /*
         * print device id's for devices, or sizes for other nodes
@@ -174,7 +178,7 @@ ls_tty(ARCHD *arcn)
  */
 
 int
-l_strncpy(char *dest, char *src, int len)
+l_strncpy(char *dest, const char *src, int len)
 {
        char *stop;
        char *start;
index 053c084..cad50cd 100644 (file)
  *
  * @(#)tar.c   8.2 (Berkeley) 4/18/94
  * $FreeBSD: src/bin/pax/tar.c,v 1.13.2.1 2001/08/01 05:03:12 obrien Exp $
- * $DragonFly: src/bin/pax/tar.c,v 1.7 2006/09/27 21:58:08 pavalos Exp $
  */
 
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/stat.h>
+#include <grp.h>
+#include <pwd.h>
 #include <string.h>
 #include <stdio.h>
-#include <unistd.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include "pax.h"
 #include "extern.h"
 #include "tar.h"
@@ -645,8 +646,6 @@ tar_wr(ARCHD *arcn)
 int
 ustar_strd(void)
 {
-       if ((usrtb_start() < 0) || (grptb_start() < 0))
-               return(-1);
        return(0);
 }
 
@@ -660,8 +659,6 @@ ustar_strd(void)
 int
 ustar_stwr(void)
 {
-       if ((uidtb_start() < 0) || (gidtb_start() < 0))
-               return(-1);
        return(0);
 }
 
@@ -756,10 +753,10 @@ ustar_rd(ARCHD *arcn, char *buf)
         * the POSIX spec wants).
         */
        hd->gname[sizeof(hd->gname) - 1] = '\0';
-       if (gid_name(hd->gname, &(arcn->sb.st_gid)) < 0)
+       if (gid_from_group(hd->gname, &(arcn->sb.st_gid)) < 0)
                arcn->sb.st_gid = (gid_t)asc_ul(hd->gid, sizeof(hd->gid), OCT);
        hd->uname[sizeof(hd->uname) - 1] = '\0';
-       if (uid_name(hd->uname, &(arcn->sb.st_uid)) < 0)
+       if (uid_from_user(hd->uname, &(arcn->sb.st_uid)) < 0)
                arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT);
 
        /*
@@ -863,6 +860,7 @@ ustar_wr(ARCHD *arcn)
        HD_USTAR *hd;
        char *pt;
        char hdblk[sizeof(HD_USTAR)];
+       const char *user, *group;
 
        /*
         * check for those file system types ustar cannot store
@@ -995,8 +993,10 @@ ustar_wr(ARCHD *arcn)
            ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3) ||
            ul_oct((u_long)arcn->sb.st_mtime,hd->mtime,sizeof(hd->mtime),3))
                goto out;
-       l_strncpy(hd->uname,name_uid(arcn->sb.st_uid, 0),sizeof(hd->uname));
-       l_strncpy(hd->gname,name_gid(arcn->sb.st_gid, 0),sizeof(hd->gname));
+       user = user_from_uid(arcn->sb.st_uid, 1);
+       group = group_from_gid(arcn->sb.st_gid, 1);
+       l_strncpy(hd->uname, user ? user : "", sizeof(hd->uname));
+       l_strncpy(hd->gname, group ? group : "", sizeof(hd->gname));
 
        /*
         * calculate and store the checksum write the header to the archive