lobase

Linux port of OpenBSDs userland.
Log | Files | Refs | README

commit 886b29e646941617cc11e35e285b2528135fd534
parent 575e5008b898c51ae7f786e0a4a9a99b4ea4b542
Author: Duncaen <mail@duncano.de>
Date:   Wed, 24 May 2017 03:12:22 +0200

bin/pax: update to OPENBSD_6_1

Diffstat:
bin/pax/ar_io.c | 43+++++++++++++++++++++----------------------
bin/pax/ar_subs.c | 19+++++++------------
bin/pax/buf_subs.c | 35+++++++++++++++++++----------------
bin/pax/cache.c | 237++++++++++++++-----------------------------------------------------------------
bin/pax/cache.h | 73-------------------------------------------------------------------------
bin/pax/cpio.c | 140+++++++++++++++++++++++++++++++++----------------------------------------------
bin/pax/extern.h | 12++++--------
bin/pax/file_subs.c | 33+++++++++++++++------------------
bin/pax/ftree.c | 26+++++++++++++++++++-------
bin/pax/ftree.h | 51---------------------------------------------------
bin/pax/gen_subs.c | 60++++++++++++++++++++++++++++++++----------------------------
bin/pax/options.c | 163++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
bin/pax/options.h | 113-------------------------------------------------------------------------------
bin/pax/pat_rep.c | 23++++++++++++++++-------
bin/pax/pat_rep.h | 49-------------------------------------------------
bin/pax/pax.1 | 23+++++++----------------
bin/pax/pax.c | 11++++++-----
bin/pax/sel_subs.c | 41+++++++++++++++++++++++++++++++++++++----
bin/pax/sel_subs.h | 72------------------------------------------------------------------------
bin/pax/tables.c | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
bin/pax/tables.h | 165-------------------------------------------------------------------------------
bin/pax/tar.c | 134++++++++++++++++++++++++++++++++++++-------------------------------------------
bin/pax/tty_subs.c | 10++++------
23 files changed, 603 insertions(+), 1074 deletions(-)

diff --git a/bin/pax/ar_io.c b/bin/pax/ar_io.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar_io.c,v 1.56 2016/06/03 23:22:20 tedu Exp $ */ +/* $OpenBSD: ar_io.c,v 1.62 2017/03/11 12:55:47 tb Exp $ */ /* $NetBSD: ar_io.c,v 1.5 1996/03/26 23:54:13 mrg Exp $ */ /*- @@ -35,21 +35,20 @@ */ #include <sys/types.h> -#include <sys/time.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/mtio.h> #include <sys/wait.h> -#include <signal.h> -#include <string.h> +#include <err.h> +#include <errno.h> #include <fcntl.h> -#include <unistd.h> +#include <signal.h> #include <stdio.h> -#include <errno.h> #include <stdlib.h> -#include <err.h> +#include <string.h> +#include <unistd.h> + #include "pax.h" -#include "options.h" #include "extern.h" /* @@ -175,7 +174,7 @@ ar_open(const char *name) artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE; else if (S_ISBLK(arsb.st_mode)) artyp = ISBLK; - else if ((lseek(arfd, (off_t)0L, SEEK_CUR) == -1) && (errno == ESPIPE)) + else if ((lseek(arfd, 0, SEEK_CUR) == -1) && (errno == ESPIPE)) artyp = ISPIPE; else artyp = ISREG; @@ -390,12 +389,12 @@ ar_close(int in_sig) return; } - if (strcmp(NM_PAX, argv0) == 0) + if (op_mode == OP_PAX) (void)dprintf(listfd, "%s: %s vol %d, %lu files," " %llu bytes read, %llu bytes written.\n", argv0, frmt->name, arvol-1, flcnt, rdcnt, wrcnt); #ifndef NOCPIO - else if (strcmp(NM_CPIO, argv0) == 0) + else if (op_mode == OP_CPIO) (void)dprintf(listfd, "%llu blocks\n", (rdcnt ? rdcnt : wrcnt) / 5120); #endif /* !NOCPIO */ @@ -462,7 +461,7 @@ ar_set_wr(void) * file, we must get rid of all the stuff after the current offset * (it was not written by pax). */ - if (((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) || + if (((cpos = lseek(arfd, 0, SEEK_CUR)) < 0) || (ftruncate(arfd, cpos) < 0)) { syswarn(1, errno, "Unable to truncate archive file"); return(-1); @@ -621,9 +620,9 @@ ar_write(char *buf, int bsz) * in size by forcing the runt record to next archive * volume */ - if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) + if ((cpos = lseek(arfd, 0, SEEK_CUR)) < 0) break; - cpos -= (off_t)res; + cpos -= res; if (ftruncate(arfd, cpos) < 0) break; res = lstrval = 0; @@ -757,9 +756,9 @@ ar_rdsync(void) io_ok = 0; if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG)) fsbz = BLKMULT; - if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) + if ((cpos = lseek(arfd, 0, SEEK_CUR)) < 0) break; - mpos = fsbz - (cpos % (off_t)fsbz); + mpos = fsbz - (cpos % fsbz); if (lseek(arfd, mpos, SEEK_CUR) < 0) break; lstrval = 1; @@ -818,7 +817,7 @@ ar_fow(off_t sksz, off_t *skipped) /* * figure out where we are in the archive */ - if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) >= 0) { + if ((cpos = lseek(arfd, 0, SEEK_CUR)) >= 0) { /* * we can be asked to move farther than there are bytes in this * volume, if so, just go to file end and let normal buf_fill() @@ -886,7 +885,7 @@ ar_rev(off_t sksz) * may not even have the ability to lseek() in any direction). * First we figure out where we are in the archive. */ - if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) { + if ((cpos = lseek(arfd, 0, SEEK_CUR)) < 0) { syswarn(1, errno, "Unable to obtain current archive byte offset"); lstrval = -1; @@ -900,7 +899,7 @@ ar_rev(off_t sksz) * previous volume and continue our movement backwards from * there. */ - if ((cpos -= sksz) < (off_t)0L) { + if ((cpos -= sksz) < 0) { if (arvol > 1) { /* * this should never happen @@ -909,7 +908,7 @@ ar_rev(off_t sksz) lstrval = -1; return(-1); } - cpos = (off_t)0L; + cpos = 0; } if (lseek(arfd, cpos, SEEK_SET) < 0) { syswarn(1, errno, "Unable to seek archive backwards"); @@ -1112,7 +1111,7 @@ ar_next(void) if (sigprocmask(SIG_SETMASK, &o_mask, NULL) < 0) syswarn(0, errno, "Unable to restore signal mask"); - if (done || !wr_trail || force_one_volume || strcmp(NM_TAR, argv0) == 0) + if (done || !wr_trail || force_one_volume || op_mode == OP_TAR) return(-1); tty_prnt("\nATTENTION! %s archive volume change required.\n", argv0); @@ -1262,7 +1261,7 @@ ar_start_gzip(int fd, const char *path, int wr) close(fds[1]); if (pmode == 0 || (act != EXTRACT && act != COPY)) { - if (pledge("stdio rpath wpath cpath fattr dpath getpw ioctl proc", + if (pledge("stdio rpath wpath cpath fattr dpath getpw proc tape", NULL) == -1) err(1, "pledge"); } diff --git a/bin/pax/ar_subs.c b/bin/pax/ar_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar_subs.c,v 1.45 2015/03/19 05:14:24 guenther Exp $ */ +/* $OpenBSD: ar_subs.c,v 1.48 2016/08/26 05:06:14 guenther Exp $ */ /* $NetBSD: ar_subs.c,v 1.5 1995/03/21 09:07:06 cgd Exp $ */ /*- @@ -34,19 +34,17 @@ * SUCH DAMAGE. */ -#include <sys/types.h> #include <sys/time.h> +#include <sys/types.h> #include <sys/stat.h> +#include <errno.h> +#include <fcntl.h> #include <signal.h> -#include <string.h> #include <stdio.h> -#include <fcntl.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#if !defined(__OpenBSD__) +#include <string.h> #include <time.h> -#endif +#include <unistd.h> + #include "pax.h" #include "extern.h" @@ -89,9 +87,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/buf_subs.c b/bin/pax/buf_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: buf_subs.c,v 1.27 2015/03/19 05:14:24 guenther Exp $ */ +/* $OpenBSD: buf_subs.c,v 1.30 2016/12/20 21:29:08 kettenis Exp $ */ /* $NetBSD: buf_subs.c,v 1.5 1995/03/21 09:07:08 cgd Exp $ */ /*- @@ -34,8 +34,8 @@ * SUCH DAMAGE. */ -#include <sys/types.h> #include <sys/time.h> +#include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <errno.h> @@ -236,7 +236,7 @@ appnd_start(off_t skcnt) skcnt += bufend - bufpt; if ((cnt = (skcnt/blksz) * blksz) < skcnt) cnt += blksz; - if (ar_rev((off_t)cnt) < 0) + if (ar_rev(cnt) < 0) goto out; /* @@ -258,7 +258,7 @@ appnd_start(off_t skcnt) goto out; bufpt += res; } - if (ar_rev((off_t)(bufpt - buf)) < 0) + if (ar_rev(bufpt - buf) < 0) goto out; bufpt = buf + cnt; bufend = buf + blksz; @@ -428,7 +428,7 @@ rd_skip(off_t skcnt) * what is left we have to read (which may be the whole thing if * ar_fow() told us the device can only read to skip records); */ - while (res > 0L) { + while (res > 0) { cnt = bufend - bufpt; /* * if the read fails, we will have to resync @@ -565,7 +565,7 @@ wr_skip(off_t skcnt) /* * loop while there is more padding to add */ - while (skcnt > 0L) { + while (skcnt > 0) { cnt = bufend - bufpt; if ((cnt <= 0) && ((cnt = buf_flush(blksz)) < 0)) return(-1); @@ -606,7 +606,7 @@ wr_rdfile(ARCHD *arcn, int ifd, off_t *left) /* * while there are more bytes to write */ - while (size > 0L) { + while (size > 0) { cnt = bufend - bufpt; if ((cnt <= 0) && ((cnt = buf_flush(blksz)) < 0)) { *left = size; @@ -625,7 +625,7 @@ wr_rdfile(ARCHD *arcn, int ifd, off_t *left) */ if (res < 0) syswarn(1, errno, "Read fault on %s", arcn->org_name); - else if (size != 0L) + else if (size != 0) paxwarn(1, "File changed size during read %s", arcn->org_name); else if (fstat(ifd, &sb) < 0) syswarn(1, errno, "Failed stat on %s", arcn->org_name); @@ -681,14 +681,14 @@ rd_wrfile(ARCHD *arcn, int ofd, off_t *left) } else syswarn(0,errno,"Unable to obtain block size for file %s",fnm); rem = sz; - *left = 0L; + *left = 0; /* * Copy the archive to the file the number of bytes specified. We have * to assume that we want to recover file holes as none of the archive * formats can record the location of file holes. */ - while (size > 0L) { + while (size > 0) { cnt = bufend - bufpt; /* * if we get a read error, we do not want to skip, as we may @@ -721,20 +721,20 @@ rd_wrfile(ARCHD *arcn, int ofd, off_t *left) * written. just closing with the file offset moved forward may not put * a hole at the end of the file. */ - if (isem && (arcn->sb.st_size > 0L)) + if (isem && (arcn->sb.st_size > 0)) file_flush(ofd, fnm, isem); /* * if we failed from archive read, we do not want to skip */ - if ((size > 0L) && (*left == 0L)) + if ((size > 0) && (*left == 0)) return(-1); /* * some formats record a crc on file data. If so, then we compare the * calculated crc to the crc stored in the archive */ - if (docrc && (size == 0L) && (arcn->crc != crc)) + if (docrc && (size == 0) && (arcn->crc != crc)) paxwarn(1,"Actual crc does not match expected crc %s",arcn->name); return(0); } @@ -750,7 +750,7 @@ void cp_file(ARCHD *arcn, int fd1, int fd2) { int cnt; - off_t cpcnt = 0L; + off_t cpcnt = 0; int res = 0; char *fnm = arcn->name; int no_hole = 0; @@ -813,7 +813,7 @@ cp_file(ARCHD *arcn, int fd1, int fd2) * written. just closing with the file offset moved forward may not put * a hole at the end of the file. */ - if (!no_hole && isem && (arcn->sb.st_size > 0L)) + if (!no_hole && isem && (arcn->sb.st_size > 0)) file_flush(fd2, fnm, isem); } @@ -849,10 +849,13 @@ buf_fill(void) /* * errors require resync, EOF goes to next archive + * but in case we have not determined yet the format, + * this means that we have a very short file, so we + * are done again. */ if (cnt < 0) break; - if (ar_next() < 0) { + if (frmt == NULL || ar_next() < 0) { fini = 1; return(0); } diff --git a/bin/pax/cache.c b/bin/pax/cache.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cache.c,v 1.21 2014/05/24 18:51:00 guenther Exp $ */ +/* $OpenBSD: cache.c,v 1.23 2016/08/26 04:08:18 guenther Exp $ */ /* $NetBSD: cache.c,v 1.4 1995/03/21 09:07:10 cgd Exp $ */ /*- @@ -35,79 +35,62 @@ */ #include <sys/types.h> -#include <sys/time.h> #include <sys/stat.h> -#include <string.h> -#include <stdio.h> -#include <pwd.h> #include <grp.h> -#include <unistd.h> +#include <pwd.h> +#include <stdio.h> #include <stdlib.h> +#include <string.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 + * 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 */ - -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 */ +#define UNMLEN 32 /* >= user name found in any protocol */ +#define GNMLEN 32 /* >= group name found in any protocol */ +#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 */ /* - * uidtb_start - * creates an empty uidtb - * Return: - * 0 if ok, -1 otherwise + * Node structures used in the user, group, uid, and gid caches. */ -int -uidtb_start(void) -{ - static int fail = 0; +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; - 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 + * 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 */ -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); -} +static int pwopn = 0; /* is password file open */ +static int gropn = 0; /* is group file open */ +static UIDC **usrtb = NULL; /* user name to uid cache */ +static GIDC **grptb = NULL; /* group name to gid cache */ /* * usrtb_start @@ -158,142 +141,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) { -#if 0 - setpassent(1); -#endif - ++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) { -#if 0 - setgroupent(1); -#endif - ++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 @@ -384,7 +231,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); @@ -399,7 +246,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)); /* diff --git a/bin/pax/cache.h b/bin/pax/cache.h @@ -1,73 +0,0 @@ -/* $OpenBSD: cache.h,v 1.7 2015/12/24 05:50:15 mmcc Exp $ */ -/* $NetBSD: cache.h,v 1.3 1995/03/21 09:07:12 cgd Exp $ */ - -/*- - * 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 - */ - -/* - * 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; diff --git a/bin/pax/cpio.c b/bin/pax/cpio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpio.c,v 1.27 2015/03/19 05:14:24 guenther Exp $ */ +/* $OpenBSD: cpio.c,v 1.30 2016/08/26 04:11:16 guenther Exp $ */ /* $NetBSD: cpio.c,v 1.5 1995/03/21 09:07:13 cgd Exp $ */ /*- @@ -35,7 +35,6 @@ */ #include <sys/types.h> -#include <sys/time.h> #include <sys/stat.h> #include <limits.h> #include <string.h> @@ -270,7 +269,7 @@ int cpio_rd(ARCHD *arcn, char *buf) { int nsz; - u_quad_t val; + unsigned long long val; HD_CPIO *hd; /* @@ -284,7 +283,7 @@ cpio_rd(ARCHD *arcn, char *buf) * byte oriented cpio (posix) does not have padding! extract the octal * ascii fields from the header */ - arcn->pad = 0L; + arcn->pad = 0; arcn->sb.st_dev = (dev_t)asc_ul(hd->c_dev, sizeof(hd->c_dev), OCT); arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), OCT); arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), OCT); @@ -293,14 +292,14 @@ cpio_rd(ARCHD *arcn, char *buf) arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink), OCT); arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT); - val = asc_uqd(hd->c_mtime, sizeof(hd->c_mtime), OCT); + val = asc_ull(hd->c_mtime, sizeof(hd->c_mtime), OCT); if ((time_t)val < 0 || (time_t)val != val) arcn->sb.st_mtime = INT_MAX; /* XXX 2038 */ else arcn->sb.st_mtime = val; arcn->sb.st_mtim.tv_nsec = 0; arcn->sb.st_ctim = arcn->sb.st_atim = arcn->sb.st_mtim; - arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,sizeof(hd->c_filesize), + arcn->sb.st_size = (off_t)asc_ull(hd->c_filesize,sizeof(hd->c_filesize), OCT); /* @@ -345,7 +344,7 @@ cpio_rd(ARCHD *arcn, char *buf) off_t cpio_endrd(void) { - return((off_t)(sizeof(HD_CPIO) + sizeof(TRAILER))); + return sizeof(HD_CPIO) + sizeof(TRAILER); } /* @@ -380,10 +379,10 @@ cpio_wr(ARCHD *arcn) /* * check and repair truncated device and inode fields in the header */ - if (map_dev(arcn, (u_long)CPIO_MASK, (u_long)CPIO_MASK) < 0) + if (map_dev(arcn, CPIO_MASK, CPIO_MASK) < 0) return(-1); - arcn->pad = 0L; + arcn->pad = 0; nsz = arcn->nlen + 1; hd = (HD_CPIO *)hdblk; if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) @@ -396,7 +395,7 @@ cpio_wr(ARCHD *arcn) /* * set data size for file data */ - if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize, + if (ull_asc(arcn->sb.st_size, hd->c_filesize, sizeof(hd->c_filesize), OCT)) { paxwarn(1,"File is too large for cpio format %s", arcn->org_name); @@ -407,7 +406,7 @@ cpio_wr(ARCHD *arcn) /* * set data size to hold link name */ - if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize, + if (ul_asc(arcn->ln_nlen, hd->c_filesize, sizeof(hd->c_filesize), OCT)) goto out; break; @@ -415,8 +414,7 @@ cpio_wr(ARCHD *arcn) /* * all other file types have no file data */ - if (ul_asc((u_long)0, hd->c_filesize, sizeof(hd->c_filesize), - OCT)) + if (ul_asc(0, hd->c_filesize, sizeof(hd->c_filesize), OCT)) goto out; break; } @@ -424,24 +422,17 @@ cpio_wr(ARCHD *arcn) /* * copy the values to the header using octal ascii */ - if (ul_asc((u_long)MAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) || - ul_asc((u_long)arcn->sb.st_dev, hd->c_dev, sizeof(hd->c_dev), - OCT) || - ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), - OCT) || - ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), - OCT) || - ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), - OCT) || - ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), - OCT) || - ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), - OCT) || - ul_asc((u_long)arcn->sb.st_rdev, hd->c_rdev, sizeof(hd->c_rdev), - OCT) || - uqd_asc(arcn->sb.st_mtime < 0 ? 0 : arcn->sb.st_mtime, hd->c_mtime, + if (ul_asc(MAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) || + ul_asc(arcn->sb.st_dev, hd->c_dev, sizeof(hd->c_dev), OCT) || + ul_asc(arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), OCT) || + ul_asc(arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), OCT) || + ul_asc(arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), OCT) || + ul_asc(arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), OCT) || + ul_asc(arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), OCT) || + ul_asc(arcn->sb.st_rdev, hd->c_rdev, sizeof(hd->c_rdev), OCT) || + ull_asc(arcn->sb.st_mtime < 0 ? 0 : arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime), OCT) || - ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), OCT)) + ul_asc(nsz, hd->c_namesize, sizeof(hd->c_namesize), OCT)) goto out; /* @@ -563,7 +554,7 @@ vcpio_rd(ARCHD *arcn, char *buf) } hd = (HD_VCPIO *)buf; - arcn->pad = 0L; + arcn->pad = 0; /* * extract the hex ascii fields from the header @@ -575,7 +566,7 @@ vcpio_rd(ARCHD *arcn, char *buf) arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX); arcn->sb.st_mtim.tv_nsec = 0; arcn->sb.st_ctim = arcn->sb.st_atim = arcn->sb.st_mtim; - arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize, + arcn->sb.st_size = (off_t)asc_ull(hd->c_filesize, sizeof(hd->c_filesize), HEX); arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink), HEX); @@ -600,7 +591,7 @@ vcpio_rd(ARCHD *arcn, char *buf) /* * skip padding. header + filename is aligned to 4 byte boundaries */ - if (rd_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0) + if (rd_skip(VCPIO_PAD(sizeof(HD_VCPIO) + nsz)) < 0) return(-1); /* @@ -621,7 +612,7 @@ vcpio_rd(ARCHD *arcn, char *buf) * read in the link name and skip over the padding */ if ((rd_ln_nm(arcn) < 0) || - (rd_skip((off_t)(VCPIO_PAD(arcn->sb.st_size))) < 0)) + (rd_skip(VCPIO_PAD(arcn->sb.st_size)) < 0)) return(-1); /* @@ -640,8 +631,8 @@ vcpio_rd(ARCHD *arcn, char *buf) off_t vcpio_endrd(void) { - return((off_t)(sizeof(HD_VCPIO) + sizeof(TRAILER) + - (VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER))))); + return sizeof(HD_VCPIO) + sizeof(TRAILER) + + (VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER))); } /* @@ -678,7 +669,7 @@ vcpio_wr(ARCHD *arcn) * check and repair truncated device and inode fields in the cpio * header */ - if (map_dev(arcn, (u_long)VCPIO_MASK, (u_long)VCPIO_MASK) < 0) + if (map_dev(arcn, VCPIO_MASK, VCPIO_MASK) < 0) return(-1); nsz = arcn->nlen + 1; hd = (HD_VCPIO *)hdblk; @@ -690,15 +681,12 @@ vcpio_wr(ARCHD *arcn) * file data crc's, and the crc if needed. */ if (docrc) { - if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic), - OCT) || - ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum), - HEX)) + if (ul_asc(VCMAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) || + ul_asc(arcn->crc,hd->c_chksum,sizeof(hd->c_chksum), HEX)) goto out; } else { - if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic), - OCT) || - ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX)) + if (ul_asc(VMAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) || + ul_asc(0, hd->c_chksum, sizeof(hd->c_chksum),HEX)) goto out; } @@ -711,7 +699,7 @@ vcpio_wr(ARCHD *arcn) * much to pad. */ arcn->pad = VCPIO_PAD(arcn->sb.st_size); - if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize, + if (ull_asc(arcn->sb.st_size, hd->c_filesize, sizeof(hd->c_filesize), HEX)) { paxwarn(1,"File is too large for sv4cpio format %s", arcn->org_name); @@ -723,8 +711,8 @@ vcpio_wr(ARCHD *arcn) * no file data for the caller to process, the file data has * the size of the link */ - arcn->pad = 0L; - if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize, + arcn->pad = 0; + if (ul_asc(arcn->ln_nlen, hd->c_filesize, sizeof(hd->c_filesize), HEX)) goto out; break; @@ -732,9 +720,8 @@ vcpio_wr(ARCHD *arcn) /* * no file data for the caller to process */ - arcn->pad = 0L; - if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize), - HEX)) + arcn->pad = 0; + if (ul_asc(0, hd->c_filesize, sizeof(hd->c_filesize), HEX)) goto out; break; } @@ -742,27 +729,18 @@ vcpio_wr(ARCHD *arcn) /* * set the other fields in the header */ - if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), - HEX) || - ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), - HEX) || - ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), - HEX) || - ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), - HEX) || + if (ul_asc(arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), HEX) || + ul_asc(arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), HEX) || + ul_asc(arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), HEX) || + ul_asc(arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), HEX) || ul_asc(arcn->sb.st_mtime < 0 ? 0 : arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime), HEX) || - ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), - HEX) || - ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj), - HEX) || - ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min), - HEX) || - ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj), - HEX) || - ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min), - HEX) || - ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX)) + ul_asc(arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), HEX) || + ul_asc(MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj), HEX) || + ul_asc(MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min), HEX) || + ul_asc(MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj), HEX) || + ul_asc(MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min), HEX) || + ul_asc(nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX)) goto out; /* @@ -770,7 +748,7 @@ vcpio_wr(ARCHD *arcn) */ if ((wr_rdbuf(hdblk, (int)sizeof(HD_VCPIO)) < 0) || (wr_rdbuf(arcn->name, (int)nsz) < 0) || - (wr_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)) { + (wr_skip(VCPIO_PAD(sizeof(HD_VCPIO) + nsz)) < 0)) { paxwarn(1,"Could not write sv4cpio header for %s",arcn->org_name); return(-1); } @@ -791,7 +769,7 @@ vcpio_wr(ARCHD *arcn) * write the link name, tell the caller we are done. */ if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) || - (wr_skip((off_t)(VCPIO_PAD(arcn->ln_nlen))) < 0)) { + (wr_skip(VCPIO_PAD(arcn->ln_nlen)) < 0)) { paxwarn(1,"Could not write sv4cpio link name for %s", arcn->org_name); return(-1); @@ -858,7 +836,7 @@ bcpio_rd(ARCHD *arcn, char *buf) if (bcpio_id(buf, sizeof(HD_BCPIO)) < 0) return(-1); - arcn->pad = 0L; + arcn->pad = 0; hd = (HD_BCPIO *)buf; if (swp_head) { /* @@ -910,7 +888,7 @@ bcpio_rd(ARCHD *arcn, char *buf) /* * header + file name are aligned to 2 byte boundaries, skip if needed */ - if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0) + if (rd_skip(BCPIO_PAD(sizeof(HD_BCPIO) + nsz)) < 0) return(-1); /* @@ -928,7 +906,7 @@ bcpio_rd(ARCHD *arcn, char *buf) } if ((rd_ln_nm(arcn) < 0) || - (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0)) + (rd_skip(BCPIO_PAD(arcn->sb.st_size)) < 0)) return(-1); /* @@ -947,8 +925,8 @@ bcpio_rd(ARCHD *arcn, char *buf) off_t bcpio_endrd(void) { - return((off_t)(sizeof(HD_BCPIO) + sizeof(TRAILER) + - (BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER))))); + return sizeof(HD_BCPIO) + sizeof(TRAILER) + + (BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER))); } /* @@ -976,7 +954,7 @@ bcpio_wr(ARCHD *arcn) * check and repair truncated device and inode fields in the cpio * header */ - if (map_dev(arcn, (u_long)BCPIO_MASK, (u_long)BCPIO_MASK) < 0) + if (map_dev(arcn, BCPIO_MASK, BCPIO_MASK) < 0) return(-1); if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) @@ -1009,7 +987,7 @@ bcpio_wr(ARCHD *arcn) * no file data for the caller to process, the file data has * the size of the link */ - arcn->pad = 0L; + arcn->pad = 0; hd->h_filesize_1[0] = CHR_WR_0(arcn->ln_nlen); hd->h_filesize_1[1] = CHR_WR_1(arcn->ln_nlen); hd->h_filesize_2[0] = CHR_WR_2(arcn->ln_nlen); @@ -1023,7 +1001,7 @@ bcpio_wr(ARCHD *arcn) /* * no file data for the caller to process */ - arcn->pad = 0L; + arcn->pad = 0; hd->h_filesize_1[0] = (char)0; hd->h_filesize_1[1] = (char)0; hd->h_filesize_2[0] = (char)0; @@ -1088,7 +1066,7 @@ bcpio_wr(ARCHD *arcn) */ if ((wr_rdbuf(hdblk, (int)sizeof(HD_BCPIO)) < 0) || (wr_rdbuf(arcn->name, nsz) < 0) || - (wr_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)) { + (wr_skip(BCPIO_PAD(sizeof(HD_BCPIO) + nsz)) < 0)) { paxwarn(1, "Could not write bcpio header for %s", arcn->org_name); return(-1); } @@ -1109,7 +1087,7 @@ bcpio_wr(ARCHD *arcn) * write the link name, tell the caller we are done. */ if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) || - (wr_skip((off_t)(BCPIO_PAD(arcn->ln_nlen))) < 0)) { + (wr_skip(BCPIO_PAD(arcn->ln_nlen)) < 0)) { paxwarn(1,"Could not write bcpio link name for %s",arcn->org_name); return(-1); } diff --git a/bin/pax/extern.h b/bin/pax/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.54 2016/01/01 15:56:03 tedu Exp $ */ +/* $OpenBSD: extern.h,v 1.57 2016/08/25 01:44:55 guenther Exp $ */ /* $NetBSD: extern.h,v 1.5 1996/03/26 23:54:16 mrg Exp $ */ /*- @@ -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 *); @@ -174,8 +170,8 @@ void ls_tty(ARCHD *); void safe_print(const char *, FILE *); u_long asc_ul(char *, int, int); int ul_asc(u_long, char *, int, int); -u_quad_t asc_uqd(char *, int, int); -int uqd_asc(u_quad_t, char *, int, int); +unsigned long long asc_ull(char *, int, int); +int ull_asc(unsigned long long, char *, int, int); size_t fieldcpy(char *, size_t, const char *, size_t); /* @@ -240,6 +236,7 @@ extern int exit_val; extern int docrc; extern char *dirptr; extern char *argv0; +extern enum op_mode { OP_PAX, OP_TAR, OP_CPIO } op_mode; extern FILE *listf; extern int listfd; extern char *tempfile; @@ -305,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 *); diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: file_subs.c,v 1.48 2016/02/16 04:30:07 guenther Exp $ */ +/* $OpenBSD: file_subs.c,v 1.53 2017/01/21 08:17:06 krw Exp $ */ /* $NetBSD: file_subs.c,v 1.4 1995/03/21 09:07:18 cgd Exp $ */ /*- @@ -45,7 +45,6 @@ #include <string.h> #include <unistd.h> #include "pax.h" -#include "options.h" #include "extern.h" static int @@ -371,7 +370,7 @@ node_creat(ARCHD *arcn) * potential symlink chain before trying to create the * directory. */ - if (strcmp(NM_TAR, argv0) == 0 && Lflag) { + if (op_mode == OP_TAR && Lflag) { while (lstat(nm, &sb) == 0 && S_ISLNK(sb.st_mode)) { len = readlink(nm, target, @@ -484,7 +483,7 @@ badlink: if (pmode && !defer_pmode) set_pmode(nm, arcn->sb.st_mode); - if (arcn->type == PAX_DIR && strcmp(NM_CPIO, argv0) != 0) { + if (arcn->type == PAX_DIR && op_mode != OP_CPIO) { /* * Dirs must be processed again at end of extract to set times * and modes to agree with those stored in the archive. However @@ -522,9 +521,7 @@ badlink: arcn->sb.st_ino = sb.st_ino; add_dir(nm, &(arcn->sb), 0); } - } - - if (patime || pmtime) + } else if (patime || pmtime) set_ftime(nm, &arcn->sb.st_mtim, &arcn->sb.st_atim, 0); return(0); } @@ -723,7 +720,7 @@ fset_ftime(const char *fnm, int fd, const struct timespec *mtimp, { struct timespec tv[2]; - + tv[0] = *atimp; tv[1] = *mtimp; @@ -760,7 +757,7 @@ set_ids(char *fnm, uid_t uid, gid_t gid) * ignore EPERM unless in verbose mode or being run by root. * if running as pax, POSIX requires a warning. */ - if (strcmp(NM_PAX, argv0) == 0 || errno != EPERM || vflag || + if (op_mode == OP_PAX || errno != EPERM || vflag || geteuid() == 0) syswarn(1, errno, "Unable to set file uid/gid of %s", fnm); @@ -777,7 +774,7 @@ fset_ids(char *fnm, int fd, uid_t uid, gid_t gid) * ignore EPERM unless in verbose mode or being run by root. * if running as pax, POSIX requires a warning. */ - if (strcmp(NM_PAX, argv0) == 0 || errno != EPERM || vflag || + if (op_mode == OP_PAX || errno != EPERM || vflag || geteuid() == 0) syswarn(1, errno, "Unable to set file uid/gid of %s", fnm); @@ -961,7 +958,7 @@ file_write(int fd, char *str, int cnt, int *rem, int *isempt, int sz, * skip, buf is empty so far */ if (fd > -1 && - lseek(fd, (off_t)wcnt, SEEK_CUR) < 0) { + lseek(fd, wcnt, SEEK_CUR) < 0) { syswarn(1,errno,"File seek on %s", name); return(-1); @@ -1031,7 +1028,7 @@ file_flush(int fd, char *fname, int isempt) /* * move back one byte and write a zero */ - if (lseek(fd, (off_t)-1, SEEK_CUR) < 0) { + if (lseek(fd, -1, SEEK_CUR) < 0) { syswarn(1, errno, "Failed seek on file %s", fname); return; } @@ -1080,8 +1077,8 @@ set_crc(ARCHD *arcn, int fd) { int i; int res; - off_t cpcnt = 0L; - u_long size; + off_t cpcnt = 0; + size_t size; u_int32_t crc = 0; char tbuf[FILEBLK]; struct stat sb; @@ -1090,12 +1087,12 @@ set_crc(ARCHD *arcn, int fd) /* * hmm, no fd, should never happen. well no crc then. */ - arcn->crc = 0L; + arcn->crc = 0; return(0); } - if ((size = (u_long)arcn->sb.st_blksize) > (u_long)sizeof(tbuf)) - size = (u_long)sizeof(tbuf); + if ((size = arcn->sb.st_blksize) > sizeof(tbuf)) + size = sizeof(tbuf); /* * read all the bytes we think that there are in the file. If the user @@ -1119,7 +1116,7 @@ set_crc(ARCHD *arcn, int fd) syswarn(1, errno, "Failed stat on %s", arcn->org_name); else if (timespeccmp(&arcn->sb.st_mtim, &sb.st_mtim, !=)) paxwarn(1, "File %s was modified during read", arcn->org_name); - else if (lseek(fd, (off_t)0L, SEEK_SET) < 0) + else if (lseek(fd, 0, SEEK_SET) < 0) syswarn(1, errno, "File rewind failed on: %s", arcn->org_name); else { arcn->crc = crc; diff --git a/bin/pax/ftree.c b/bin/pax/ftree.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ftree.c,v 1.39 2016/06/03 23:22:20 tedu Exp $ */ +/* $OpenBSD: ftree.c,v 1.40 2016/08/26 04:17:48 guenther Exp $ */ /* $NetBSD: ftree.c,v 1.4 1995/03/21 09:07:21 cgd Exp $ */ /*- @@ -35,19 +35,31 @@ */ #include <sys/types.h> -#include <sys/time.h> #include <sys/stat.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> #include <errno.h> -#include <stdlib.h> #include <fts.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + #include "pax.h" -#include "ftree.h" #include "extern.h" /* + * Data structure used to store the file args to be handed to fts(). + * It keeps track of which args generated a "selected" member. + */ +typedef struct ftree { + char *fname; /* file tree name */ + int refcnt; /* has tree had a selected file? */ + int newercnt; /* skipped due to -u/-D */ + int chflg; /* change directory flag */ + struct ftree *fow; /* pointer to next entry on list */ +} FTREE; + + +/* * routines to interface with the fts library function. * * file args supplied to pax are stored on a single linked list (of type FTREE) diff --git a/bin/pax/ftree.h b/bin/pax/ftree.h @@ -1,51 +0,0 @@ -/* $OpenBSD: ftree.h,v 1.5 2008/05/06 06:54:28 henning Exp $ */ -/* $NetBSD: ftree.h,v 1.3 1995/03/21 09:07:23 cgd Exp $ */ - -/*- - * 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. - * - * @(#)ftree.h 8.1 (Berkeley) 5/31/93 - */ - -/* - * Data structure used by the ftree.c routines to store the file args to be - * handed to fts(). It keeps a reference count of which args generated a - * "selected" member - */ - -typedef struct ftree { - char *fname; /* file tree name */ - int refcnt; /* has tree had a selected file? */ - int newercnt; /* skipped due to -u/-D */ - int chflg; /* change directory flag */ - struct ftree *fow; /* pointer to next entry on list */ -} FTREE; diff --git a/bin/pax/gen_subs.c b/bin/pax/gen_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gen_subs.c,v 1.28 2015/03/17 03:23:17 guenther Exp $ */ +/* $OpenBSD: gen_subs.c,v 1.32 2016/08/26 05:06:14 guenther Exp $ */ /* $NetBSD: gen_subs.c,v 1.5 1995/03/21 09:07:26 cgd Exp $ */ /*- @@ -35,17 +35,17 @@ */ #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 <vis.h> -#if !defined(__OpenBSD__) #include <time.h> -#endif +#include <unistd.h> +#include <utmp.h> +#include <vis.h> + #include "pax.h" #include "extern.h" @@ -107,8 +107,8 @@ ls_list(ARCHD *arcn, time_t now, FILE *fp) 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 @@ -254,13 +254,15 @@ ul_asc(u_long val, char *str, int len, int base) *pt-- = '0' + (char)digit; else *pt-- = 'a' + (char)(digit - 10); - if ((val = (val >> 4)) == (u_long)0) + val >>= 4; + if (val == 0) break; } } else { while (pt >= str) { *pt-- = '0' + (char)(val & 0x7); - if ((val = (val >> 3)) == (u_long)0) + val >>= 3; + if (val == 0) break; } } @@ -270,26 +272,26 @@ ul_asc(u_long val, char *str, int len, int base) */ while (pt >= str) *pt-- = '0'; - if (val != (u_long)0) + if (val != 0) return(-1); return(0); } /* - * asc_uqd() - * convert hex/octal character string into a u_quad_t. We do not have to - * check for overflow! (the headers in all supported formats are not large - * enough to create an overflow). + * asc_ull() + * Convert hex/octal character string into a unsigned long long. + * We do not have to check for overflow! (The headers in all + * supported formats are not large enough to create an overflow). * NOTE: strings passed to us are NOT TERMINATED. * Return: - * u_quad_t value + * unsigned long long value */ -u_quad_t -asc_uqd(char *str, int len, int base) +unsigned long long +asc_ull(char *str, int len, int base) { char *stop; - u_quad_t tval = 0; + unsigned long long tval = 0; stop = str + len; @@ -322,17 +324,17 @@ asc_uqd(char *str, int len, int base) } /* - * uqd_asc() - * convert an u_quad_t into a hex/oct ascii string. pads with LEADING - * ascii 0's to fill string completely + * ull_asc() + * Convert an unsigned long long into a hex/oct ascii string. + * Pads with LEADING ascii 0's to fill string completely * NOTE: the string created is NOT TERMINATED. */ int -uqd_asc(u_quad_t val, char *str, int len, int base) +ull_asc(unsigned long long val, char *str, int len, int base) { char *pt; - u_quad_t digit; + unsigned long long digit; /* * WARNING str is not '\0' terminated by this routine @@ -350,13 +352,15 @@ uqd_asc(u_quad_t val, char *str, int len, int base) *pt-- = '0' + (char)digit; else *pt-- = 'a' + (char)(digit - 10); - if ((val = (val >> 4)) == (u_quad_t)0) + val >>= 4; + if (val == 0) break; } } else { while (pt >= str) { *pt-- = '0' + (char)(val & 0x7); - if ((val = (val >> 3)) == (u_quad_t)0) + val >>= 3; + if (val == 0) break; } } @@ -366,7 +370,7 @@ uqd_asc(u_quad_t val, char *str, int len, int base) */ while (pt >= str) *pt-- = '0'; - if (val != (u_quad_t)0) + if (val != 0) return(-1); return(0); } diff --git a/bin/pax/options.c b/bin/pax/options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options.c,v 1.93 2016/04/19 03:26:11 guenther Exp $ */ +/* $OpenBSD: options.c,v 1.101 2016/12/26 23:43:52 krw Exp $ */ /* $NetBSD: options.c,v 1.6 1996/03/26 23:54:18 mrg Exp $ */ /*- @@ -35,22 +35,100 @@ */ #include <sys/types.h> -#include <sys/time.h> #include <sys/stat.h> -#include <sys/mtio.h> -#include <stdio.h> -#include <string.h> #include <errno.h> -#include <unistd.h> -#include <stdlib.h> #include <limits.h> #include <paths.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + #include "pax.h" -#include "options.h" #include "cpio.h" #include "tar.h" #include "extern.h" +#ifndef _PATH_DEFTAPE +#define _PATH_DEFTAPE "/dev/st0" +#endif + +/* + * argv[0] names. Used for tar and cpio emulation + */ + +#define NM_TAR "tar" +#define NM_CPIO "cpio" +#define NM_PAX "pax" + +/* + * Constants used to specify the legal sets of flags in pax. For each major + * operation mode of pax, a set of illegal flags is defined. If any one of + * those illegal flags are found set, we scream and exit + */ + +/* + * flags (one for each option). + */ +#define AF 0x00000001 +#define BF 0x00000002 +#define CF 0x00000004 +#define DF 0x00000008 +#define FF 0x00000010 +#define IF 0x00000020 +#define KF 0x00000040 +#define LF 0x00000080 +#define NF 0x00000100 +#define OF 0x00000200 +#define PF 0x00000400 +#define RF 0x00000800 +#define SF 0x00001000 +#define TF 0x00002000 +#define UF 0x00004000 +#define VF 0x00008000 +#define WF 0x00010000 +#define XF 0x00020000 +#define CBF 0x00040000 /* nonstandard extension */ +#define CDF 0x00080000 /* nonstandard extension */ +#define CEF 0x00100000 /* nonstandard extension */ +#define CGF 0x00200000 /* nonstandard extension */ +#define CHF 0x00400000 /* nonstandard extension */ +#define CLF 0x00800000 /* nonstandard extension */ +#define CPF 0x01000000 /* nonstandard extension */ +#define CTF 0x02000000 /* nonstandard extension */ +#define CUF 0x04000000 /* nonstandard extension */ +#define CXF 0x08000000 +#define CYF 0x10000000 /* nonstandard extension */ +#define CZF 0x20000000 /* nonstandard extension */ +#define C0F 0x40000000 /* nonstandard extension */ + +/* + * ascii string indexed by bit position above (alter the above and you must + * alter this string) used to tell the user what flags caused us to complain + */ +#define FLGCH "abcdfiklnoprstuvwxBDEGHLPTUXYZ0" + +/* + * legal pax operation bit patterns + */ + +#define ISLIST(x) (((x) & (RF|WF)) == 0) +#define ISEXTRACT(x) (((x) & (RF|WF)) == RF) +#define ISARCHIVE(x) (((x) & (AF|RF|WF)) == WF) +#define ISAPPND(x) (((x) & (AF|RF|WF)) == (AF|WF)) +#define ISCOPY(x) (((x) & (RF|WF)) == (RF|WF)) +#define ISWRITE(x) (((x) & (RF|WF)) == WF) + +/* + * Illegal option flag subsets based on pax operation + */ + +#define BDEXTR (AF|BF|LF|TF|WF|XF|CBF|CHF|CLF|CPF|CXF) +#define BDARCH (CF|KF|LF|NF|PF|RF|CDF|CEF|CYF|CZF) +#define BDCOPY (AF|BF|FF|OF|XF|CBF|CEF) +#define BDLIST (AF|BF|IF|KF|LF|OF|PF|RF|TF|UF|WF|XF|CBF|CDF|CHF|CLF|CPF|CXF|CYF|CZF) + + /* * Routines which handle command line options */ @@ -67,18 +145,16 @@ static void pax_options(int, char **); static void pax_usage(void); static void tar_options(int, char **); static void tar_usage(void); +#ifndef NOCPIO static void cpio_options(int, char **); static void cpio_usage(void); +#endif static int compress_id(char *_blk, int _size); static int gzip_id(char *_blk, int _size); static int bzip2_id(char *_blk, int _size); static int xz_id(char *_blk, int _size); -#ifndef _PATH_DEFTAPE -#define _PATH_DEFTAPE "/dev/st0" -#endif - #define GZIP_CMD "gzip" /* command to run as gzip */ #define COMPRESS_CMD "compress" /* command to run as compress */ #define BZIP2_CMD "bzip2" /* command to run as bzip2 */ @@ -130,7 +206,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 @@ -190,11 +266,13 @@ options(int argc, char **argv) argv0 = __progname; if (strcmp(NM_TAR, argv0) == 0) { + op_mode = OP_TAR; tar_options(argc, argv); return; } #ifndef NOCPIO else if (strcmp(NM_CPIO, argv0) == 0) { + op_mode = OP_CPIO; cpio_options(argc, argv); return; } @@ -203,6 +281,7 @@ options(int argc, char **argv) * assume pax as the default */ argv0 = NM_PAX; + op_mode = OP_PAX; pax_options(argc, argv); } @@ -454,17 +533,13 @@ pax_options(int argc, char **argv) /* * non-standard limit on read faults * 0 indicates stop after first error, values - * indicate a limit, "NONE" try forever + * indicate a limit */ flg |= CEF; - if (strcmp(NONE, optarg) == 0) - maxflt = -1; - else { - maxflt = strtonum(optarg, 0, INT_MAX, &errstr); - if (errstr) { - paxwarn(1, "Error count value: %s", errstr); - pax_usage(); - } + maxflt = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr) { + paxwarn(1, "Error count value: %s", errstr); + pax_usage(); } break; case 'G': @@ -642,7 +717,6 @@ static void tar_options(int argc, char **argv) { int c; - int fstdin = 0; int Oflag = 0; int nincfiles = 0; int incfiles_max = 0; @@ -689,15 +763,6 @@ tar_options(int argc, char **argv) /* * filename where the archive is stored */ - if ((optarg[0] == '-') && (optarg[1]== '\0')) { - /* - * treat a - as stdin - */ - fstdin = 1; - arcname = NULL; - break; - } - fstdin = 0; arcname = optarg; break; case 'h': @@ -873,20 +938,19 @@ tar_options(int argc, char **argv) argc -= optind; argv += optind; - if (!fstdin && ((arcname == NULL) || (*arcname == '\0'))) { + if ((arcname == NULL) || (*arcname == '\0')) { arcname = getenv("TAPE"); if ((arcname == NULL) || (*arcname == '\0')) arcname = _PATH_DEFTAPE; - else if ((arcname[0] == '-') && (arcname[1]== '\0')) { - arcname = NULL; - fstdin = 1; - } } + if ((arcname[0] == '-') && (arcname[1]== '\0')) + arcname = NULL; - /* Traditional tar behaviour (pax uses stderr unless in list mode) */ - if (fstdin == 1 && act == ARCHIVE) - listf = stderr; - else + /* + * Traditional tar behaviour: list-like output goes to stdout unless + * writing the archive there. (pax uses stderr unless in list mode) + */ + if (act == LIST || act == EXTRACT || arcname != NULL) listf = stdout; /* Traditional tar behaviour (pax wants to read file list from stdin) */ @@ -1091,7 +1155,7 @@ static void cpio_options(int argc, char **argv) { const char *errstr; - int c; + int c, list_only = 0; unsigned i; char *str; FILE *fp; @@ -1189,8 +1253,7 @@ cpio_options(int argc, char **argv) /* * list contents of archive */ - act = LIST; - listf = stdout; + list_only = 1; break; case 'u': /* @@ -1323,8 +1386,16 @@ cpio_options(int argc, char **argv) * process the args as they are interpreted by the operation mode */ switch (act) { - case LIST: case EXTRACT: + if (list_only) { + act = LIST; + + /* + * cpio is like pax: list to stderr + * unless in list mode + */ + listf = stdout; + } while (*argv != NULL) if (pat_add(*argv++, NULL) < 0) cpio_usage(); @@ -1377,7 +1448,7 @@ printflg(unsigned int flg) (void)fprintf(stderr,"%s: Invalid combination of options:", argv0); while ((nxt = ffs(flg)) != 0) { - flg = flg >> nxt; + flg >>= nxt; pos += nxt; (void)fprintf(stderr, " -%c", flgch[pos-1]); } diff --git a/bin/pax/options.h b/bin/pax/options.h @@ -1,113 +0,0 @@ -/* $OpenBSD: options.h,v 1.4 2003/06/13 17:51:14 millert Exp $ */ -/* $NetBSD: options.h,v 1.3 1995/03/21 09:07:32 cgd Exp $ */ - -/*- - * 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. - * - * @(#)options.h 8.2 (Berkeley) 4/18/94 - */ - -/* - * argv[0] names. Used for tar and cpio emulation - */ - -#define NM_TAR "tar" -#define NM_CPIO "cpio" -#define NM_PAX "pax" - -/* - * Constants used to specify the legal sets of flags in pax. For each major - * operation mode of pax, a set of illegal flags is defined. If any one of - * those illegal flags are found set, we scream and exit - */ -#define NONE "none" - -/* - * flags (one for each option). - */ -#define AF 0x00000001 -#define BF 0x00000002 -#define CF 0x00000004 -#define DF 0x00000008 -#define FF 0x00000010 -#define IF 0x00000020 -#define KF 0x00000040 -#define LF 0x00000080 -#define NF 0x00000100 -#define OF 0x00000200 -#define PF 0x00000400 -#define RF 0x00000800 -#define SF 0x00001000 -#define TF 0x00002000 -#define UF 0x00004000 -#define VF 0x00008000 -#define WF 0x00010000 -#define XF 0x00020000 -#define CBF 0x00040000 /* nonstandard extension */ -#define CDF 0x00080000 /* nonstandard extension */ -#define CEF 0x00100000 /* nonstandard extension */ -#define CGF 0x00200000 /* nonstandard extension */ -#define CHF 0x00400000 /* nonstandard extension */ -#define CLF 0x00800000 /* nonstandard extension */ -#define CPF 0x01000000 /* nonstandard extension */ -#define CTF 0x02000000 /* nonstandard extension */ -#define CUF 0x04000000 /* nonstandard extension */ -#define CXF 0x08000000 -#define CYF 0x10000000 /* nonstandard extension */ -#define CZF 0x20000000 /* nonstandard extension */ -#define C0F 0x40000000 /* nonstandard extension */ - -/* - * ascii string indexed by bit position above (alter the above and you must - * alter this string) used to tell the user what flags caused us to complain - */ -#define FLGCH "abcdfiklnoprstuvwxBDEGHLPTUXYZ0" - -/* - * legal pax operation bit patterns - */ - -#define ISLIST(x) (((x) & (RF|WF)) == 0) -#define ISEXTRACT(x) (((x) & (RF|WF)) == RF) -#define ISARCHIVE(x) (((x) & (AF|RF|WF)) == WF) -#define ISAPPND(x) (((x) & (AF|RF|WF)) == (AF|WF)) -#define ISCOPY(x) (((x) & (RF|WF)) == (RF|WF)) -#define ISWRITE(x) (((x) & (RF|WF)) == WF) - -/* - * Illegal option flag subsets based on pax operation - */ - -#define BDEXTR (AF|BF|LF|TF|WF|XF|CBF|CHF|CLF|CPF|CXF) -#define BDARCH (CF|KF|LF|NF|PF|RF|CDF|CEF|CYF|CZF) -#define BDCOPY (AF|BF|FF|OF|XF|CBF|CEF) -#define BDLIST (AF|BF|IF|KF|LF|OF|PF|RF|TF|UF|WF|XF|CBF|CDF|CHF|CLF|CPF|CXF|CYF|CZF) diff --git a/bin/pax/pat_rep.c b/bin/pax/pat_rep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pat_rep.c,v 1.40 2015/11/17 19:01:34 mmcc Exp $ */ +/* $OpenBSD: pat_rep.c,v 1.41 2016/08/26 04:19:28 guenther Exp $ */ /* $NetBSD: pat_rep.c,v 1.4 1995/03/21 09:07:33 cgd Exp $ */ /*- @@ -35,19 +35,28 @@ */ #include <sys/types.h> -#include <sys/time.h> #include <sys/stat.h> +#include <regex.h> #include <stdio.h> -#include <string.h> -#include <unistd.h> #include <stdlib.h> -#include <errno.h> -#include <regex.h> +#include <string.h> + #include "pax.h" -#include "pat_rep.h" #include "extern.h" /* + * data structure for storing user supplied replacement strings (-s) + */ +typedef struct replace { + char *nstr; /* the new string we will substitute with */ + regex_t rcmp; /* compiled regular expression used to match */ + int flgs; /* print conversions? global in operation? */ +#define PRNT 0x1 +#define GLOB 0x2 + struct replace *fow; /* pointer to next pattern */ +} REPLACE; + +/* * routines to handle pattern matching, name modification (regular expression * substitution and interactive renames), and destination name modification for * copy (-rw). Both file name and link names are adjusted as required in these diff --git a/bin/pax/pat_rep.h b/bin/pax/pat_rep.h @@ -1,49 +0,0 @@ -/* $OpenBSD: pat_rep.h,v 1.4 2003/06/02 23:32:08 millert Exp $ */ -/* $NetBSD: pat_rep.h,v 1.3 1995/03/21 09:07:35 cgd Exp $ */ - -/*- - * 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. - * - * @(#)pat_rep.h 8.1 (Berkeley) 5/31/93 - */ - -/* - * data structure for storing user supplied replacement strings (-s) - */ -typedef struct replace { - char *nstr; /* the new string we will substitute with */ - regex_t rcmp; /* compiled regular expression used to match */ - int flgs; /* print conversions? global in operation? */ -#define PRNT 0x1 -#define GLOB 0x2 - struct replace *fow; /* pointer to next pattern */ -} REPLACE; diff --git a/bin/pax/pax.1 b/bin/pax/pax.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pax.1,v 1.71 2015/03/15 05:16:56 guenther Exp $ +.\" $OpenBSD: pax.1,v 1.73 2016/08/26 04:40:27 guenther Exp $ .\" $NetBSD: pax.1,v 1.3 1995/03/21 09:07:37 cgd Exp $ .\" .\" Copyright (c) 1992 Keith Muller. @@ -34,7 +34,7 @@ .\" .\" @(#)pax.1 8.4 (Berkeley) 4/18/94 .\" -.Dd $Mdocdate: March 15 2015 $ +.Dd $Mdocdate: August 26 2016 $ .Dt PAX 1 .Os .Sh NAME @@ -358,23 +358,9 @@ A of 0 will cause .Nm to stop operation after the first read error is detected on an archive volume. -A -.Ar limit -of -.Li NONE -will cause -.Nm -to attempt to recover from read errors forever. The default .Ar limit is a small positive number of retries. -.Pp -.Sy Warning : -Using this option with -.Li NONE -should be used with extreme caution as -.Nm -may get stuck in an infinite loop on a very badly flawed archive. .It Fl f Ar archive Specify .Ar archive @@ -1116,6 +1102,11 @@ additions to the flag, and the flawed archive handling during list and read operations are extensions to that specification. +.Sh HISTORY +A +.Nm +utility appeared in +.Bx 4.4 . .Sh AUTHORS .An Keith Muller at the University of California, San Diego. diff --git a/bin/pax/pax.c b/bin/pax/pax.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pax.c,v 1.45 2016/06/23 06:37:36 semarie Exp $ */ +/* $OpenBSD: pax.c,v 1.50 2017/03/11 12:55:47 tb Exp $ */ /* $NetBSD: pax.c,v 1.5 1996/03/26 23:54:20 mrg Exp $ */ /*- @@ -36,10 +36,10 @@ #include <sys/types.h> #include <sys/stat.h> -#include <sys/time.h> #include <sys/resource.h> #include <signal.h> #include <unistd.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> @@ -90,8 +90,9 @@ int exit_val; /* exit value */ int docrc; /* check/create file crc */ char *dirptr; /* destination dir in a copy */ char *argv0; /* root of argv[0] */ +enum op_mode op_mode; /* what program are we acting as? */ sigset_t s_mask; /* signal mask for cleanup critical sect */ -FILE *listf; /* file pointer to print file list to */ +FILE *listf; /* file pointer to print file list to */ int listfd = STDERR_FILENO; /* fd matching listf, for sighandler output */ char *tempfile; /* tempfile to use for mkstemp(3) */ char *tempbase; /* basename of tempfile to use for mkstemp(3) */ @@ -263,13 +264,13 @@ main(int argc, char **argv) * so can't pledge at all then. */ if (pmode == 0 || (act != EXTRACT && act != COPY)) { - if (pledge("stdio rpath wpath cpath fattr dpath getpw ioctl proc exec", + if (pledge("stdio rpath wpath cpath fattr dpath getpw proc exec tape", NULL) == -1) err(1, "pledge"); /* Copy mode, or no gzip -- don't need to fork/exec. */ if (gzip_program == NULL || act == COPY) { - if (pledge("stdio rpath wpath cpath fattr dpath getpw ioctl", + if (pledge("stdio rpath wpath cpath fattr dpath getpw tape", NULL) == -1) err(1, "pledge"); } diff --git a/bin/pax/sel_subs.c b/bin/pax/sel_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sel_subs.c,v 1.25 2014/11/23 05:47:49 guenther Exp $ */ +/* $OpenBSD: sel_subs.c,v 1.26 2016/08/26 04:20:38 guenther Exp $ */ /* $NetBSD: sel_subs.c,v 1.5 1995/03/21 09:07:42 cgd Exp $ */ /*- @@ -35,7 +35,6 @@ */ #include <sys/types.h> -#include <sys/time.h> #include <sys/stat.h> #include <ctype.h> #include <grp.h> @@ -44,11 +43,45 @@ #include <stdlib.h> #include <string.h> #include <time.h> -#include <unistd.h> + #include "pax.h" -#include "sel_subs.h" #include "extern.h" +/* + * data structure for storing uid/grp selects (-U, -G non standard options) + */ + +#define USR_TB_SZ 317 /* user selection table size */ +#define GRP_TB_SZ 317 /* user selection table size */ + +typedef struct usrt { + uid_t uid; + struct usrt *fow; /* next uid */ +} USRT; + +typedef struct grpt { + gid_t gid; + struct grpt *fow; /* next gid */ +} GRPT; + +/* + * data structure for storing user supplied time ranges (-T option) + */ + +#define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2; + +typedef struct time_rng { + time_t low_time; /* lower inclusive time limit */ + time_t high_time; /* higher inclusive time limit */ + int flgs; /* option flags */ +#define HASLOW 0x01 /* has lower time limit */ +#define HASHIGH 0x02 /* has higher time limit */ +#define CMPMTME 0x04 /* compare file modification time */ +#define CMPCTME 0x08 /* compare inode change time */ +#define CMPBOTH (CMPMTME|CMPCTME) /* compare inode and mod time */ + struct time_rng *fow; /* next pattern */ +} TIME_RNG; + static int str_sec(const char *, time_t *); static int usr_match(ARCHD *); static int grp_match(ARCHD *); diff --git a/bin/pax/sel_subs.h b/bin/pax/sel_subs.h @@ -1,72 +0,0 @@ -/* $OpenBSD: sel_subs.h,v 1.4 2003/06/02 23:32:09 millert Exp $ */ -/* $NetBSD: sel_subs.h,v 1.3 1995/03/21 09:07:44 cgd Exp $ */ - -/*- - * 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. - * - * @(#)sel_subs.h 8.1 (Berkeley) 5/31/93 - */ - -/* - * data structure for storing uid/grp selects (-U, -G non standard options) - */ - -#define USR_TB_SZ 317 /* user selection table size */ -#define GRP_TB_SZ 317 /* user selection table size */ - -typedef struct usrt { - uid_t uid; - struct usrt *fow; /* next uid */ -} USRT; - -typedef struct grpt { - gid_t gid; - struct grpt *fow; /* next gid */ -} GRPT; - -/* - * data structure for storing user supplied time ranges (-T option) - */ - -#define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2; - -typedef struct time_rng { - time_t low_time; /* lower inclusive time limit */ - time_t high_time; /* higher inclusive time limit */ - int flgs; /* option flags */ -#define HASLOW 0x01 /* has lower time limit */ -#define HASHIGH 0x02 /* has higher time limit */ -#define CMPMTME 0x04 /* compare file modification time */ -#define CMPCTME 0x08 /* compare inode change time */ -#define CMPBOTH (CMPMTME|CMPCTME) /* compare inode and mod time */ - struct time_rng *fow; /* next pattern */ -} TIME_RNG; diff --git a/bin/pax/tables.c b/bin/pax/tables.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tables.c,v 1.47 2015/03/19 05:14:24 guenther Exp $ */ +/* $OpenBSD: tables.c,v 1.51 2017/03/16 03:53:37 deraadt Exp $ */ /* $NetBSD: tables.c,v 1.4 1995/03/21 09:07:45 cgd Exp $ */ /*- @@ -34,19 +34,19 @@ * SUCH DAMAGE. */ -#include <sys/types.h> #include <sys/time.h> +#include <sys/types.h> #include <sys/stat.h> +#include <errno.h> #include <fcntl.h> #include <limits.h> #include <signal.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> -#include <errno.h> -#include <stdlib.h> + #include "pax.h" -#include "tables.h" #include "extern.h" /* @@ -64,10 +64,140 @@ * time well spent. */ +/* + * data structures and constants used by the different databases kept by pax + */ + +/* + * Hash Table Sizes MUST BE PRIME, if set too small performance suffers. + * Probably safe to expect 500000 inodes per tape. Assuming good key + * distribution (inodes) chains of under 50 long (worst case) is ok. + */ +#define L_TAB_SZ 2503 /* hard link hash table size */ +#define F_TAB_SZ 50503 /* file time hash table size */ +#define N_TAB_SZ 541 /* interactive rename hash table */ +#define D_TAB_SZ 317 /* unique device mapping table */ +#define A_TAB_SZ 317 /* ftree dir access time reset table */ +#define SL_TAB_SZ 317 /* escape symlink tables */ +#define MAXKEYLEN 64 /* max number of chars for hash */ +#define DIRP_SIZE 64 /* initial size of created dir table */ + +/* + * file hard link structure (hashed by dev/ino and chained) used to find the + * hard links in a file system or with some archive formats (cpio) + */ +typedef struct hrdlnk { + ino_t ino; /* files inode number */ + char *name; /* name of first file seen with this ino/dev */ + dev_t dev; /* files device number */ + u_long nlink; /* expected link count */ + struct hrdlnk *fow; +} HRDLNK; + +/* + * Archive write update file time table (the -u, -C flag), hashed by filename. + * Filenames are stored in a scratch file at seek offset into the file. The + * file time (mod time) and the file name length (for a quick check) are + * stored in a hash table node. We were forced to use a scratch file because + * with -u, the mtime for every node in the archive must always be available + * to compare against (and this data can get REALLY large with big archives). + * By being careful to read only when we have a good chance of a match, the + * performance loss is not measurable (and the size of the archive we can + * handle is greatly increased). + */ +typedef struct ftm { + off_t seek; /* location in scratch file */ + struct timespec mtim; /* files last modification time */ + struct ftm *fow; + int namelen; /* file name length */ +} FTM; + +/* + * Interactive rename table (-i flag), hashed by orig filename. + * We assume this will not be a large table as this mapping data can only be + * obtained through interactive input by the user. Nobody is going to type in + * changes for 500000 files? We use chaining to resolve collisions. + */ + +typedef struct namt { + char *oname; /* old name */ + char *nname; /* new name typed in by the user */ + struct namt *fow; +} NAMT; + +/* + * Unique device mapping tables. Some protocols (e.g. cpio) require that the + * <c_dev,c_ino> pair will uniquely identify a file in an archive unless they + * are links to the same file. Appending to archives can break this. For those + * protocols that have this requirement we map c_dev to a unique value not seen + * in the archive when we append. We also try to handle inode truncation with + * this table. (When the inode field in the archive header are too small, we + * remap the dev on writes to remove accidental collisions). + * + * The list is hashed by device number using chain collision resolution. Off of + * each DEVT are linked the various remaps for this device based on those bits + * in the inode which were truncated. For example if we are just remapping to + * avoid a device number during an update append, off the DEVT we would have + * only a single DLIST that has a truncation id of 0 (no inode bits were + * stripped for this device so far). When we spot inode truncation we create + * a new mapping based on the set of bits in the inode which were stripped off. + * so if the top four bits of the inode are stripped and they have a pattern of + * 0110...... (where . are those bits not truncated) we would have a mapping + * assigned for all inodes that has the same 0110.... pattern (with this dev + * number of course). This keeps the mapping sparse and should be able to store + * close to the limit of files which can be represented by the optimal + * combination of dev and inode bits, and without creating a fouled up archive. + * Note we also remap truncated devs in the same way (an exercise for the + * dedicated reader; always wanted to say that...:) + */ + +typedef struct devt { + dev_t dev; /* the orig device number we now have to map */ + struct devt *fow; /* new device map list */ + struct dlist *list; /* map list based on inode truncation bits */ +} DEVT; + +typedef struct dlist { + ino_t trunc_bits; /* truncation pattern for a specific map */ + dev_t dev; /* the new device id we use */ + struct dlist *fow; +} DLIST; + +/* + * ftree directory access time reset table. When we are done with a + * subtree we reset the access and mod time of the directory when the tflag is + * set. Not really explicitly specified in the pax spec, but easy and fast to + * do (and this may have even been intended in the spec, it is not clear). + * table is hashed by inode with chaining. + */ + +typedef struct atdir { + struct file_times ft; + struct atdir *fow; +} ATDIR; + +/* + * created directory time and mode storage entry. After pax is finished during + * extraction or copy, we must reset directory access modes and times that + * may have been modified after creation (they no longer have the specified + * times and/or modes). We must reset time in the reverse order of creation, + * because entries are added from the top of the file tree to the bottom. + * We MUST reset times from leaf to root (it will not work the other + * direction). + */ + +typedef struct dirdata { + struct file_times ft; + u_int16_t mode; /* file mode to restore */ + u_int16_t frc_mode; /* do we force mode settings? */ +} DIRDATA; + static HRDLNK **ltab = NULL; /* hard link table for detecting hard links */ static FTM **ftab = NULL; /* file time table for updating arch */ static NAMT **ntab = NULL; /* interactive rename storage table */ +#ifndef NOCPIO static DEVT **dtab = NULL; /* device/inode mapping tables */ +#endif static ATDIR **atab = NULL; /* file tree directory time reset table */ static DIRDATA *dirp = NULL; /* storage for setting created dir time/mode */ static size_t dirsize; /* size of dirp table */ @@ -442,7 +572,7 @@ chk_ftime(ARCHD *arcn) * add the name at the end of the scratch file, saving the * offset. add the file to the head of the hash chain */ - if ((pt->seek = lseek(ffd, (off_t)0, SEEK_END)) >= 0) { + if ((pt->seek = lseek(ffd, 0, SEEK_END)) >= 0) { if (write(ffd, arcn->name, namelen) == namelen) { pt->mtim = arcn->sb.st_mtim; pt->namelen = namelen; @@ -1475,7 +1605,7 @@ add_dir(char *name, struct stat *psb, int frc_mode) name = rp; } if (dircnt == dirsize) { - dblk = reallocarray(dirp, dirsize, 2 * sizeof(DIRDATA)); + dblk = reallocarray(dirp, dirsize * 2, sizeof(DIRDATA)); if (dblk == NULL) { paxwarn(1, "Unable to store mode and times for created" " directory: %s", name); diff --git a/bin/pax/tables.h b/bin/pax/tables.h @@ -1,165 +0,0 @@ -/* $OpenBSD: tables.h,v 1.16 2015/03/19 05:14:24 guenther Exp $ */ -/* $NetBSD: tables.h,v 1.3 1995/03/21 09:07:47 cgd Exp $ */ - -/*- - * 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. - * - * @(#)tables.h 8.1 (Berkeley) 5/31/93 - */ - -/* - * data structures and constants used by the different databases kept by pax - */ - -/* - * Hash Table Sizes MUST BE PRIME, if set too small performance suffers. - * Probably safe to expect 500000 inodes per tape. Assuming good key - * distribution (inodes) chains of under 50 long (worst case) is ok. - */ -#define L_TAB_SZ 2503 /* hard link hash table size */ -#define F_TAB_SZ 50503 /* file time hash table size */ -#define N_TAB_SZ 541 /* interactive rename hash table */ -#define D_TAB_SZ 317 /* unique device mapping table */ -#define A_TAB_SZ 317 /* ftree dir access time reset table */ -#define SL_TAB_SZ 317 /* escape symlink tables */ -#define MAXKEYLEN 64 /* max number of chars for hash */ -#define DIRP_SIZE 64 /* initial size of created dir table */ - -/* - * file hard link structure (hashed by dev/ino and chained) used to find the - * hard links in a file system or with some archive formats (cpio) - */ -typedef struct hrdlnk { - ino_t ino; /* files inode number */ - char *name; /* name of first file seen with this ino/dev */ - dev_t dev; /* files device number */ - u_long nlink; /* expected link count */ - struct hrdlnk *fow; -} HRDLNK; - -/* - * Archive write update file time table (the -u, -C flag), hashed by filename. - * Filenames are stored in a scratch file at seek offset into the file. The - * file time (mod time) and the file name length (for a quick check) are - * stored in a hash table node. We were forced to use a scratch file because - * with -u, the mtime for every node in the archive must always be available - * to compare against (and this data can get REALLY large with big archives). - * By being careful to read only when we have a good chance of a match, the - * performance loss is not measurable (and the size of the archive we can - * handle is greatly increased). - */ -typedef struct ftm { - off_t seek; /* location in scratch file */ - struct timespec mtim; /* files last modification time */ - struct ftm *fow; - int namelen; /* file name length */ -} FTM; - -/* - * Interactive rename table (-i flag), hashed by orig filename. - * We assume this will not be a large table as this mapping data can only be - * obtained through interactive input by the user. Nobody is going to type in - * changes for 500000 files? We use chaining to resolve collisions. - */ - -typedef struct namt { - char *oname; /* old name */ - char *nname; /* new name typed in by the user */ - struct namt *fow; -} NAMT; - -/* - * Unique device mapping tables. Some protocols (e.g. cpio) require that the - * <c_dev,c_ino> pair will uniquely identify a file in an archive unless they - * are links to the same file. Appending to archives can break this. For those - * protocols that have this requirement we map c_dev to a unique value not seen - * in the archive when we append. We also try to handle inode truncation with - * this table. (When the inode field in the archive header are too small, we - * remap the dev on writes to remove accidental collisions). - * - * The list is hashed by device number using chain collision resolution. Off of - * each DEVT are linked the various remaps for this device based on those bits - * in the inode which were truncated. For example if we are just remapping to - * avoid a device number during an update append, off the DEVT we would have - * only a single DLIST that has a truncation id of 0 (no inode bits were - * stripped for this device so far). When we spot inode truncation we create - * a new mapping based on the set of bits in the inode which were stripped off. - * so if the top four bits of the inode are stripped and they have a pattern of - * 0110...... (where . are those bits not truncated) we would have a mapping - * assigned for all inodes that has the same 0110.... pattern (with this dev - * number of course). This keeps the mapping sparse and should be able to store - * close to the limit of files which can be represented by the optimal - * combination of dev and inode bits, and without creating a fouled up archive. - * Note we also remap truncated devs in the same way (an exercise for the - * dedicated reader; always wanted to say that...:) - */ - -typedef struct devt { - dev_t dev; /* the orig device number we now have to map */ - struct devt *fow; /* new device map list */ - struct dlist *list; /* map list based on inode truncation bits */ -} DEVT; - -typedef struct dlist { - ino_t trunc_bits; /* truncation pattern for a specific map */ - dev_t dev; /* the new device id we use */ - struct dlist *fow; -} DLIST; - -/* - * ftree directory access time reset table. When we are done with a - * subtree we reset the access and mod time of the directory when the tflag is - * set. Not really explicitly specified in the pax spec, but easy and fast to - * do (and this may have even been intended in the spec, it is not clear). - * table is hashed by inode with chaining. - */ - -typedef struct atdir { - struct file_times ft; - struct atdir *fow; -} ATDIR; - -/* - * created directory time and mode storage entry. After pax is finished during - * extraction or copy, we must reset directory access modes and times that - * may have been modified after creation (they no longer have the specified - * times and/or modes). We must reset time in the reverse order of creation, - * because entries are added from the top of the file tree to the bottom. - * We MUST reset times from leaf to root (it will not work the other - * direction). - */ - -typedef struct dirdata { - struct file_times ft; - u_int16_t mode; /* file mode to restore */ - u_int16_t frc_mode; /* do we force mode settings? */ -} DIRDATA; diff --git a/bin/pax/tar.c b/bin/pax/tar.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tar.c,v 1.59 2016/02/15 02:38:53 guenther Exp $ */ +/* $OpenBSD: tar.c,v 1.63 2016/08/26 04:11:16 guenther Exp $ */ /* $NetBSD: tar.c,v 1.5 1995/03/21 09:07:49 cgd Exp $ */ /*- @@ -35,15 +35,17 @@ */ #include <sys/types.h> -#include <sys/time.h> #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" @@ -56,7 +58,7 @@ static size_t expandname(char *, size_t, char **, const char *, size_t); static u_long tar_chksm(char *, int); static char *name_split(char *, int); static int ul_oct(u_long, char *, int, int); -static int uqd_oct(u_quad_t, char *, int, int); +static int ull_oct(unsigned long long, char *, int, int); #ifndef SMALL static int rd_xheader(ARCHD *arcn, int, off_t); #endif @@ -84,7 +86,7 @@ char *gnu_link_string; /* GNU ././@LongLink hackery link */ int tar_endwr(void) { - return(wr_skip((off_t)(NULLCNT*BLKMULT))); + return wr_skip(NULLCNT * BLKMULT); } /* @@ -97,7 +99,7 @@ tar_endwr(void) off_t tar_endrd(void) { - return((off_t)(NULLCNT*BLKMULT)); + return NULLCNT * BLKMULT; } /* @@ -186,30 +188,31 @@ ul_oct(u_long val, char *str, int len, int term) */ while (pt >= str) { *pt-- = '0' + (char)(val & 0x7); - if ((val = val >> 3) == (u_long)0) + val >>= 3; + if (val == 0) break; } while (pt >= str) *pt-- = '0'; - if (val != (u_long)0) + if (val != 0) return(-1); return(0); } /* - * uqd_oct() - * convert an u_quad_t to an octal string. one of many oddball field - * termination characters are used by the various versions of tar in the - * different fields. term selects which kind to use. str is '0' padded - * at the front to len. we are unable to use only one format as many old - * tar readers are very cranky about this. + * ull_oct() + * Convert an unsigned long long to an octal string. One of many oddball + * field termination characters are used by the various versions of tar + * in the different fields. term selects which kind to use. str is + * '0' padded at the front to len. We are unable to use only one format + * as many old tar readers are very cranky about this. * Return: * 0 if the number fit into the string, -1 otherwise */ static int -uqd_oct(u_quad_t val, char *str, int len, int term) +ull_oct(unsigned long long val, char *str, int len, int term) { char *pt; @@ -240,13 +243,14 @@ uqd_oct(u_quad_t val, char *str, int len, int term) */ while (pt >= str) { *pt-- = '0' + (char)(val & 0x7); - if ((val = val >> 3) == 0) + val >>= 3; + if (val == 0) break; } while (pt >= str) *pt-- = '0'; - if (val != (u_quad_t)0) + if (val != 0) return(-1); return(0); } @@ -378,7 +382,7 @@ int tar_rd(ARCHD *arcn, char *buf) { HD_TAR *hd; - u_quad_t val; + unsigned long long val; char *pt; /* @@ -404,8 +408,8 @@ tar_rd(ARCHD *arcn, char *buf) 0xfff); arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT); arcn->sb.st_gid = (gid_t)asc_ul(hd->gid, sizeof(hd->gid), OCT); - arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT); - val = asc_uqd(hd->mtime, sizeof(hd->mtime), OCT); + arcn->sb.st_size = (off_t)asc_ull(hd->size, sizeof(hd->size), OCT); + val = asc_ull(hd->mtime, sizeof(hd->mtime), OCT); if ((time_t)val < 0 || (time_t)val != val) arcn->sb.st_mtime = INT_MAX; /* XXX 2038 */ else @@ -590,7 +594,7 @@ tar_wr(ARCHD *arcn) */ hd->linkflag = AREGTYPE; hd->name[len-1] = '/'; - if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1)) + if (ul_oct(0, hd->size, sizeof(hd->size), 1)) goto out; } else if (arcn->type == PAX_SLK) { /* @@ -599,7 +603,7 @@ tar_wr(ARCHD *arcn) hd->linkflag = SYMTYPE; fieldcpy(hd->linkname, sizeof(hd->linkname), arcn->ln_name, sizeof(arcn->ln_name)); - if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1)) + if (ul_oct(0, hd->size, sizeof(hd->size), 1)) goto out; } else if (PAX_IS_HARDLINK(arcn->type)) { /* @@ -608,16 +612,16 @@ tar_wr(ARCHD *arcn) hd->linkflag = LNKTYPE; fieldcpy(hd->linkname, sizeof(hd->linkname), arcn->ln_name, sizeof(arcn->ln_name)); - if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1)) + if (ul_oct(0, hd->size, sizeof(hd->size), 1)) goto out; } else { /* * data follows this file, so set the pad */ hd->linkflag = AREGTYPE; - if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size, - sizeof(hd->size), 1)) { - paxwarn(1,"File is too large for tar %s", arcn->org_name); + if (ull_oct(arcn->sb.st_size, hd->size, sizeof(hd->size), 1)) { + paxwarn(1, "File is too large for tar %s", + arcn->org_name); return(1); } arcn->pad = TAR_PAD(arcn->sb.st_size); @@ -626,11 +630,11 @@ tar_wr(ARCHD *arcn) /* * copy those fields that are independent of the type */ - if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 0) || - uqd_oct(arcn->sb.st_mtime < 0 ? 0 : arcn->sb.st_mtime, hd->mtime, + if (ul_oct(arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 0) || + ull_oct(arcn->sb.st_mtime < 0 ? 0 : arcn->sb.st_mtime, hd->mtime, sizeof(hd->mtime), 1) || - ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 0) || - ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 0)) + ul_oct(arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 0) || + ul_oct(arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 0)) goto out; /* @@ -643,7 +647,7 @@ tar_wr(ARCHD *arcn) goto out; if (wr_rdbuf(hdblk, sizeof(HD_TAR)) < 0) return(-1); - if (wr_skip((off_t)(BLKMULT - sizeof(HD_TAR))) < 0) + if (wr_skip(BLKMULT - sizeof(HD_TAR)) < 0) return(-1); if (PAX_IS_REG(arcn->type)) return(0); @@ -677,21 +681,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 @@ -739,7 +728,7 @@ ustar_rd(ARCHD *arcn, char *buf) int cnt = 0; dev_t devmajor; dev_t devminor; - u_quad_t val; + unsigned long long val; /* * we only get proper sized buffers @@ -809,8 +798,8 @@ reset: */ arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode, sizeof(hd->mode), OCT) & 0xfff); - arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT); - val = asc_uqd(hd->mtime, sizeof(hd->mtime), OCT); + arcn->sb.st_size = (off_t)asc_ull(hd->size, sizeof(hd->size), OCT); + val = asc_ull(hd->mtime, sizeof(hd->mtime), OCT); if ((time_t)val < 0 || (time_t)val != val) arcn->sb.st_mtime = INT_MAX; /* XXX 2038 */ else @@ -932,7 +921,7 @@ int ustar_wr(ARCHD *arcn) { HD_USTAR *hd; - char *pt; + char *pt, *name; char hdblk[sizeof(HD_USTAR)]; /* @@ -971,7 +960,7 @@ ustar_wr(ARCHD *arcn) */ memset(hdblk, 0, sizeof(hdblk)); hd = (HD_USTAR *)hdblk; - arcn->pad = 0L; + arcn->pad = 0; /* * split the name, or zero out the prefix @@ -1000,7 +989,7 @@ ustar_wr(ARCHD *arcn) switch (arcn->type) { case PAX_DIR: hd->typeflag = DIRTYPE; - if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) + if (ul_oct(0, hd->size, sizeof(hd->size), 3)) goto out; break; case PAX_CHR: @@ -1009,16 +998,16 @@ ustar_wr(ARCHD *arcn) hd->typeflag = CHRTYPE; else hd->typeflag = BLKTYPE; - if (ul_oct((u_long)MAJOR(arcn->sb.st_rdev), hd->devmajor, + if (ul_oct(MAJOR(arcn->sb.st_rdev), hd->devmajor, sizeof(hd->devmajor), 3) || - ul_oct((u_long)MINOR(arcn->sb.st_rdev), hd->devminor, + ul_oct(MINOR(arcn->sb.st_rdev), hd->devminor, sizeof(hd->devminor), 3) || - ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) + ul_oct(0, hd->size, sizeof(hd->size), 3)) goto out; break; case PAX_FIF: hd->typeflag = FIFOTYPE; - if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) + if (ul_oct(0, hd->size, sizeof(hd->size), 3)) goto out; break; case PAX_SLK: @@ -1030,7 +1019,7 @@ ustar_wr(ARCHD *arcn) hd->typeflag = LNKTYPE; fieldcpy(hd->linkname, sizeof(hd->linkname), arcn->ln_name, sizeof(arcn->ln_name)); - if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) + if (ul_oct(0, hd->size, sizeof(hd->size), 3)) goto out; break; case PAX_REG: @@ -1044,9 +1033,9 @@ ustar_wr(ARCHD *arcn) else hd->typeflag = REGTYPE; arcn->pad = TAR_PAD(arcn->sb.st_size); - if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size, - sizeof(hd->size), 3)) { - paxwarn(1,"File is too long for ustar %s",arcn->org_name); + if (ull_oct(arcn->sb.st_size, hd->size, sizeof(hd->size), 3)) { + paxwarn(1, "File is too long for ustar %s", + arcn->org_name); return(1); } break; @@ -1059,7 +1048,7 @@ ustar_wr(ARCHD *arcn) * set the remaining fields. Some versions want all 16 bits of mode * we better humor them (they really do not meet spec though).... */ - if (ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 3)) { + if (ul_oct(arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 3)) { if (uid_nobody == 0) { if (uid_name("nobody", &uid_nobody) == -1) goto out; @@ -1070,10 +1059,10 @@ ustar_wr(ARCHD *arcn) "Ustar header field is too small for uid %lu, " "using nobody", (u_long)arcn->sb.st_uid); } - if (ul_oct((u_long)uid_nobody, hd->uid, sizeof(hd->uid), 3)) + if (ul_oct(uid_nobody, hd->uid, sizeof(hd->uid), 3)) goto out; } - if (ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3)) { + if (ul_oct(arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3)) { if (gid_nobody == 0) { if (gid_name("nobody", &gid_nobody) == -1) goto out; @@ -1084,19 +1073,18 @@ ustar_wr(ARCHD *arcn) "Ustar header field is too small for gid %lu, " "using nobody", (u_long)arcn->sb.st_gid); } - if (ul_oct((u_long)gid_nobody, hd->gid, sizeof(hd->gid), 3)) + if (ul_oct(gid_nobody, hd->gid, sizeof(hd->gid), 3)) goto out; } - if (uqd_oct(arcn->sb.st_mtime < 0 ? 0 : arcn->sb.st_mtime, hd->mtime, + if (ull_oct(arcn->sb.st_mtime < 0 ? 0 : arcn->sb.st_mtime, hd->mtime, sizeof(hd->mtime), 3) || - ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 3)) + 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)); } /* @@ -1109,7 +1097,7 @@ ustar_wr(ARCHD *arcn) goto out; if (wr_rdbuf(hdblk, sizeof(HD_USTAR)) < 0) return(-1); - if (wr_skip((off_t)(BLKMULT - sizeof(HD_USTAR))) < 0) + if (wr_skip(BLKMULT - sizeof(HD_USTAR)) < 0) return(-1); if (PAX_IS_REG(arcn->type)) return(0); diff --git a/bin/pax/tty_subs.c b/bin/pax/tty_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty_subs.c,v 1.16 2014/11/23 05:28:12 guenther Exp $ */ +/* $OpenBSD: tty_subs.c,v 1.17 2016/08/26 04:22:13 guenther Exp $ */ /* $NetBSD: tty_subs.c,v 1.5 1995/03/21 09:07:52 cgd Exp $ */ /*- @@ -35,17 +35,15 @@ */ #include <sys/types.h> -#include <sys/time.h> #include <sys/stat.h> #include <fcntl.h> +#include <stdarg.h> #include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> #include <string.h> +#include <unistd.h> + #include "pax.h" #include "extern.h" -#include <stdarg.h> /* * routines that deal with I/O to and from the user