From: Bdale Garbee Date: Mon, 11 Aug 2008 20:51:53 +0000 (-0300) Subject: Merge branch 'upstream' X-Git-Tag: debian/20090728-1~21 X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=a547751988577b94d9cefd260173ec7e69b8669c;hp=-c;p=debian%2Fpax Merge branch 'upstream' Conflicts: Makefile ar_io.c cpio.1 options.c pat_rep.c pax.1 pax.c tar.1 tar.c --- a547751988577b94d9cefd260173ec7e69b8669c diff --combined Makefile index 8a94849,9ea2e86..72f59b1 --- a/Makefile +++ b/Makefile @@@ -1,25 -1,21 +1,38 @@@ + # $OpenBSD: Makefile,v 1.10 2001/05/26 00:32:20 millert Exp $ + + # To install on versions prior to BSD 4.4 the following may have to be + # defined with CFLAGS += + # + # -DLONG_OFF_T Define this if the base type of an off_t is a long (and is + # NOT a quad). (This is often defined in the file + # /usr/include/sys/types.h). + # This define is important, as if you do have a quad_t + # off_t and define LONG_OFF_T, pax will compile but will + # NOT RUN PROPERLY. + # + PROG= pax SRCS= ar_io.c ar_subs.c buf_subs.c cache.c cpio.c file_subs.c ftree.c\ gen_subs.c getoldopt.c options.c pat_rep.c pax.c sel_subs.c tables.c\ - tar.c tty_subs.c -MAN= pax.1 tar.1 cpio.1 -LINKS= ${BINDIR}/pax ${BINDIR}/tar ${BINDIR}/pax ${BINDIR}/cpio + tar.c tty_subs.c fgetln.c strmode.c +OBJS= $(SRCS:.c=.o) +MAN= pax.1 -.include +CFLAGS= -Wall -O2 -g\ + -DNET2_STAT -D_PATH_DEFTAPE=\"/dev/rmt0\" -DDEBIAN -D_GNU_SOURCE + +prefix=/usr/local + +pax: $(OBJS) + $(CC) $(CFLAGS) $(OBJS) -o $@ $(LIBS) + +clean: + $(RM) *.o + +realclean: clean + $(RM) $(PROG) + +install: + install -d -m 755 $(prefix)/bin $(prefix)/share/man/man1 + install -s -m 755 $(PROG) $(prefix)/bin + install -m 644 $(MAN) $(prefix)/share/man/man1 diff --combined ar_io.c index 4cc4a97,2a833bb..6679547 --- a/ar_io.c +++ b/ar_io.c @@@ -1,4 -1,4 +1,4 @@@ - /* $OpenBSD: ar_io.c,v 1.18 1998/09/20 02:22:21 millert Exp $ */ + /* $OpenBSD: ar_io.c,v 1.38 2008/06/11 00:49:08 pvalchev Exp $ */ /* $NetBSD: ar_io.c,v 1.5 1996/03/26 23:54:13 mrg Exp $ */ /*- @@@ -17,11 -17,7 +17,7 @@@ * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 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. * @@@ -40,9 -36,9 +36,9 @@@ #ifndef lint #if 0 - static char sccsid[] = "@(#)ar_io.c 8.2 (Berkeley) 4/18/94"; + static const char sccsid[] = "@(#)ar_io.c 8.2 (Berkeley) 4/18/94"; #else - static char rcsid[] = "$OpenBSD: ar_io.c,v 1.18 1998/09/20 02:22:21 millert Exp $"; + static const char rcsid[] = "$OpenBSD: ar_io.c,v 1.38 2008/06/11 00:49:08 pvalchev Exp $"; #endif #endif /* not lint */ @@@ -52,6 -48,7 +48,7 @@@ #include #include #include + #include #include #include #include @@@ -72,8 -69,8 +69,8 @@@ #define EXT_MODE O_RDONLY /* open mode for list/extract */ #define AR_MODE (O_WRONLY | O_CREAT | O_TRUNC) /* mode for archive */ #define APP_MODE O_RDWR /* mode for append */ - #define STDO "" /* psuedo name for stdout */ - #define STDN "" /* psuedo name for stdin */ + #define STDO "" /* pseudo name for stdout */ + #define STDN "" /* pseudo name for stdin */ static int arfd = -1; /* archive file descriptor */ static int artyp = ISREG; /* archive type: file/FIFO/tape */ static int arvol = 1; /* archive volume number */ @@@ -85,12 -82,14 +82,14 @@@ static struct stat arsb; /* stat of ar static int invld_rec; /* tape has out of spec record size */ static int wr_trail = 1; /* trailer was rewritten in append */ static int can_unlnk = 0; /* do we unlink null archives? */ - char *arcname; /* printable name of archive */ - char *gzip_program; /* name of gzip program */ + const char *arcname; /* printable name of archive */ + const char *gzip_program; /* name of gzip program */ + static pid_t zpid = -1; /* pid of child process */ + int force_one_volume; /* 1 if we ignore volume changes */ - static int get_phys __P((void)); + static int get_phys(void); extern sigset_t s_mask; - static void ar_start_gzip __P((int)); + static void ar_start_gzip(int, const char *, int); /* * ar_open() @@@ -101,14 -100,8 +100,8 @@@ * -1 on failure, 0 otherwise */ - #ifdef __STDC__ int - ar_open(char *name) - #else - int - ar_open(name) - char *name; - #endif + ar_open(const char *name) { struct mtget mb; @@@ -129,29 -122,27 +122,27 @@@ arfd = STDIN_FILENO; arcname = STDN; } else if ((arfd = open(name, EXT_MODE, DMOD)) < 0) - syswarn(0, errno, "Failed open to read on %s", name); - if (zflag) - ar_start_gzip(arfd); + syswarn(1, errno, "Failed open to read on %s", name); + if (arfd != -1 && gzip_program != NULL) + ar_start_gzip(arfd, gzip_program, 0); break; case ARCHIVE: if (name == NULL) { arfd = STDOUT_FILENO; arcname = STDO; } else if ((arfd = open(name, AR_MODE, DMOD)) < 0) - syswarn(0, errno, "Failed open to write on %s", name); + syswarn(1, errno, "Failed open to write on %s", name); else can_unlnk = 1; - if (zflag) - ar_start_gzip(arfd); + if (arfd != -1 && gzip_program != NULL) + ar_start_gzip(arfd, gzip_program, 1); break; case APPND: - if (zflag) - err(1, "can not filter through compressor while appending"); if (name == NULL) { arfd = STDOUT_FILENO; arcname = STDO; } else if ((arfd = open(name, APP_MODE, DMOD)) < 0) - syswarn(0, errno, "Failed open to read/write on %s", + syswarn(1, errno, "Failed open to read/write on %s", name); break; case COPY: @@@ -166,13 -157,15 +157,15 @@@ return(-1); if (chdname != NULL) - if (chdir(chdname) != 0) + if (chdir(chdname) != 0) { syswarn(1, errno, "Failed chdir to %s", chdname); + return(-1); + } /* * set up is based on device type */ if (fstat(arfd, &arsb) < 0) { - syswarn(0, errno, "Failed stat on %s", arcname); + syswarn(1, errno, "Failed stat on %s", arcname); (void)close(arfd); arfd = -1; can_unlnk = 0; @@@ -214,11 -207,11 +207,11 @@@ /* * set default blksz on read. APPNDs writes rdblksz on the last volume * On all new archive volumes, we shift to wrblksz (if the user - * specified one, otherwize we will continue to use rdblksz). We - * must to set blocksize based on what kind of device the archive is + * specified one, otherwise we will continue to use rdblksz). We + * must set blocksize based on what kind of device the archive is * stored. */ - switch(artyp) { + switch (artyp) { case ISTAPE: /* * Tape drives come in at least two flavors. Those that support @@@ -281,7 -274,7 +274,7 @@@ if ((arsb.st_size % rdblksz) == 0) break; /* - * When we cannont find a match, we may have a flawed archive. + * When we cannot find a match, we may have a flawed archive. */ if (rdblksz <= 0) rdblksz = FILEBLK; @@@ -295,7 -288,7 +288,7 @@@ break; default: /* - * should never happen, worse case, slow... + * should never happen, worst case, slow... */ blksz = rdblksz = BLKMULT; break; @@@ -308,14 -301,10 +301,10 @@@ * ar_close() * closes archive device, increments volume number, and prints i/o summary */ - #ifdef __STDC__ void ar_close(void) - #else - void - ar_close() - #endif { + int status; if (arfd < 0) { did_io = io_ok = flcnt = 0; @@@ -347,8 -336,19 +336,19 @@@ can_unlnk = 0; } + /* + * for a quick extract/list, pax frequently exits before the child + * process is done + */ + if ((act == LIST || act == EXTRACT) && nflag && zpid > 0) + kill(zpid, SIGINT); + (void)close(arfd); + /* Do not exit before child to ensure data integrity */ + if (zpid > 0) + waitpid(zpid, &status, 0); + if (vflag && (artyp == ISTAPE)) { (void)fputs("done.\n", listf); vfpart = 0; @@@ -388,7 -388,7 +388,7 @@@ * could have written anything yet. */ if (frmt == NULL) { - # ifdef NET2_STAT + # ifdef LONG_OFF_T (void)fprintf(listf, "%s: unknown format, %lu bytes skipped.\n", # else (void)fprintf(listf, "%s: unknown format, %qu bytes skipped.\n", @@@ -403,7 -403,7 +403,7 @@@ (void)fprintf(listf, "%qu blocks\n", (rdcnt ? rdcnt : wrcnt) / 5120); else if (strcmp(NM_TAR, argv0) != 0) (void)fprintf(listf, - # ifdef NET2_STAT + # ifdef LONG_OFF_T "%s: %s vol %d, %lu files, %lu bytes read, %lu bytes written.\n", # else "%s: %s vol %d, %lu files, %qu bytes read, %qu bytes written.\n", @@@ -420,15 -420,10 +420,10 @@@ * other side of the pipe from getting a SIGPIPE (pax will stop * reading an archive once a format dependent trailer is detected). */ - #ifdef __STDC__ void ar_drain(void) - #else - void - ar_drain() - #endif { - register int res; + int res; char drbuf[MAXBLK]; /* @@@ -457,13 -452,8 +452,8 @@@ * 0 if all ready to write, -1 otherwise */ - #ifdef __STDC__ int ar_set_wr(void) - #else - int - ar_set_wr() - #endif { off_t cpos; @@@ -473,7 -463,7 +463,7 @@@ */ wr_trail = 0; - /* + /* * Add any device dependent code as required here */ if (artyp != ISREG) @@@ -494,19 -484,14 +484,14 @@@ /* * ar_app_ok() * check if the last volume in the archive allows appends. We cannot check - * this until we are ready to write since there is no spec that says all + * this until we are ready to write since there is no spec that says all * volumes in a single archive have to be of the same type... * Return: * 0 if we can append, -1 otherwise. */ - #ifdef __STDC__ int ar_app_ok(void) - #else - int - ar_app_ok() - #endif { if (artyp == ISPIPE) { paxwarn(1, "Cannot append to an archive obtained from a pipe."); @@@ -529,17 -514,10 +514,10 @@@ * Number of bytes in buffer. 0 for end of file, -1 for a read error. */ - #ifdef __STDC__ int - ar_read(register char *buf, register int cnt) - #else - int - ar_read(buf, cnt) - register char *buf; - register int cnt; - #endif + ar_read(char *buf, int cnt) { - register int res = 0; + int res = 0; /* * if last i/o was in error, no more reads until reset or new volume @@@ -563,10 -541,10 +541,10 @@@ io_ok = 1; if (res != rdblksz) { /* - * Record size changed. If this is happens on + * Record size changed. If this happens on * any record after the first, we probably have * a tape drive which has a fixed record size - * we are getting multiple records in a single + * (we are getting multiple records in a single * read). Watch out for record blocking that * violates pax spec (must be a multiple of * BLKMULT). @@@ -616,20 -594,13 +594,13 @@@ * Return: * Number of bytes written. 0 indicates end of volume reached and with no * flaws (as best that can be detected). A -1 indicates an unrecoverable - * error in the archive occured. + * error in the archive occurred. */ - #ifdef __STDC__ int - ar_write(register char *buf, register int bsz) - #else - int - ar_write(buf, bsz) - register char *buf; - register int bsz; - #endif + ar_write(char *buf, int bsz) { - register int res; + int res; off_t cpos; /* @@@ -657,10 -628,10 +628,10 @@@ case ISREG: if ((res > 0) && (res % BLKMULT)) { /* - * try to fix up partial writes which are not BLKMULT + * try to fix up partial writes which are not BLKMULT * in size by forcing the runt record to next archive * volume - */ + */ if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) break; cpos -= (off_t)res; @@@ -705,7 -676,7 +676,7 @@@ /* * Better tell the user the bad news... * if this is a block aligned archive format, we may have a bad archive - * if the format wants the header to start at a BLKMULT boundry. While + * if the format wants the header to start at a BLKMULT boundary.. While * we can deal with the mis-aligned data, it violates spec and other * archive readers will likely fail. if the format is not block * aligned, the user may be lucky (and the archive is ok). @@@ -744,13 -715,8 +715,8 @@@ * 0 when ok to try i/o again, -1 otherwise. */ - #ifdef __STDC__ int ar_rdsync(void) - #else - int - ar_rdsync() - #endif { long fsbz; off_t cpos; @@@ -758,7 -724,7 +724,7 @@@ struct mtop mb; /* - * Fail resync attempts at user request (done) or this is going to be + * Fail resync attempts at user request (done) or if this is going to be * an update/append to a existing archive. if last i/o hit media end, * we need to go to the next volume not try a resync */ @@@ -772,13 -738,13 +738,13 @@@ if (io_ok) did_io = 1; - switch(artyp) { + switch (artyp) { case ISTAPE: /* * if the last i/o was a successful data transfer, we assume * the fault is just a bad record on the tape that we are now * past. If we did not get any data since the last resync try - * to move the tape foward one PHYSICAL record past any + * to move the tape forward one PHYSICAL record past any * damaged tape section. Some tape drives are stubborn and need * to be pushed. */ @@@ -827,7 -793,7 +793,7 @@@ /* * ar_fow() - * Move the I/O position within the archive foward the specified number of + * Move the I/O position within the archive forward the specified number of * bytes as supported by the device. If we cannot move the requested * number of bytes, return the actual number of bytes moved in skipped. * Return: @@@ -835,15 -801,8 +801,8 @@@ * partial move (the amount moved is in skipped) */ - #ifdef __STDC__ int ar_fow(off_t sksz, off_t *skipped) - #else - int - ar_fow(sksz, skipped) - off_t sksz; - off_t *skipped; - #endif { off_t cpos; off_t mpos; @@@ -853,7 -812,7 +812,7 @@@ return(0); /* - * we cannot move foward at EOF or error + * we cannot move forward at EOF or error */ if (lstrval <= 0) return(lstrval); @@@ -862,7 -821,7 +821,7 @@@ * Safer to read forward on devices where it is hard to find the end of * the media without reading to it. With tapes we cannot be sure of the * number of physical blocks to skip (we do not know physical block - * size at this point), so we must only read foward on tapes! + * size at this point), so we must only read forward on tapes! */ if (artyp != ISREG) return(0); @@@ -871,12 -830,12 +830,12 @@@ * figure out where we are in the archive */ if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) >= 0) { - /* - * we can be asked to move farther than there are bytes in this + /* + * 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() * deal with the end of file (it will go to next volume by * itself) - */ + */ if ((mpos = cpos + sksz) > arsb.st_size) { *skipped = arsb.st_size - cpos; mpos = arsb.st_size; @@@ -885,7 -844,7 +844,7 @@@ if (lseek(arfd, mpos, SEEK_SET) >= 0) return(0); } - syswarn(1, errno, "Foward positioning operation on archive failed"); + syswarn(1, errno, "Forward positioning operation on archive failed"); lstrval = -1; return(-1); } @@@ -901,18 -860,12 +860,12 @@@ * 0 if moved the requested distance, -1 on complete failure */ - #ifdef __STDC__ int ar_rev(off_t sksz) - #else - int - ar_rev(sksz) - off_t sksz; - #endif { off_t cpos; struct mtop mb; - register int phyblk; + int phyblk; /* * make sure we do not have try to reverse on a flawed archive @@@ -920,7 -873,7 +873,7 @@@ if (lstrval < 0) return(lstrval); - switch(artyp) { + switch (artyp) { case ISPIPE: if (sksz <= 0) break; @@@ -953,8 -906,8 +906,8 @@@ /* * we may try to go backwards past the start when the archive - * is only a single record. If this hapens and we are on a - * multi volume archive, we need to go to the end of the + * is only a single record. If this happens and we are on a + * multi-volume archive, we need to go to the end of the * previous volume and continue our movement backwards from * there. */ @@@ -977,12 -930,12 +930,12 @@@ break; case ISTAPE: /* - * Calculate and move the proper number of PHYSICAL tape + * Calculate and move the proper number of PHYSICAL tape * blocks. If the sksz is not an even multiple of the physical * tape size, we cannot do the move (this should never happen). - * (We also cannot handler trailers spread over two vols). + * (We also cannot handle trailers spread over two vols.) * get_phys() also makes sure we are in front of the filemark. - */ + */ if ((phyblk = get_phys()) <= 0) { lstrval = -1; return(-1); @@@ -1031,7 -984,7 +984,7 @@@ /* * get_phys() * Determine the physical block size on a tape drive. We need the physical - * block size so we know how many bytes we skip over when we move with + * block size so we know how many bytes we skip over when we move with * mtio commands. We also make sure we are BEFORE THE TAPE FILEMARK when * return. * This is one really SLOW routine... @@@ -1039,17 -992,12 +992,12 @@@ * physical block size if ok (ok > 0), -1 otherwise */ - #ifdef __STDC__ static int get_phys(void) - #else - static int - get_phys() - #endif { - register int padsz = 0; - register int res; - register int phyblk; + int padsz = 0; + int res; + int phyblk; struct mtop mb; char scbuf[MAXBLK]; @@@ -1097,7 -1045,7 +1045,7 @@@ } /* - * read foward to the file mark, then back up in front of the filemark + * read forward to the file mark, then back up in front of the filemark * (this is a bit paranoid, but should be safe to do). */ while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0) @@@ -1157,13 -1105,8 +1105,8 @@@ * 0 when ready to continue, -1 when all done */ - #ifdef __STDC__ int ar_next(void) - #else - int - ar_next() - #endif { char buf[PAXPATHLEN+2]; static int freeit = 0; @@@ -1180,7 -1123,7 +1123,7 @@@ if (sigprocmask(SIG_SETMASK, &o_mask, NULL) < 0) syswarn(0, errno, "Unable to restore signal mask"); - if (done || !wr_trail || strcmp(NM_TAR, argv0) == 0) + if (done || !wr_trail || force_one_volume || strcmp(NM_TAR, argv0) == 0) return(-1); tty_prnt("\nATTENTION! %s archive volume change required.\n", argv0); @@@ -1206,7 -1149,7 +1149,7 @@@ else tty_prnt("\n"); - for(;;) { + for (;;) { tty_prnt("Type \"y\" to continue, \".\" to quit %s,", argv0); tty_prnt(" or \"s\" to switch to new device.\nIf you"); @@@ -1285,7 -1228,7 +1228,7 @@@ */ if (ar_open(buf) >= 0) { if (freeit) { - (void)free(arcname); + (void)free((char *)arcname); freeit = 0; } if ((arcname = strdup(buf)) == NULL) { @@@ -1305,63 -1248,43 +1248,44 @@@ /* * ar_start_gzip() - * starts the gzip compression/decompression process as a child, using magic - * to keep the fd the same in the calling function (parent). + * starts the compress, gzip or bzip2 compression/decompression process + * as a child, using magic to keep the fd the same in the calling function + * (parent). */ void - #ifdef __STDC__ - ar_start_gzip(int fd) - #else - ar_start_gzip(fd) - int fd; - #endif + ar_start_gzip(int fd, const char *gzip_program, int wr) { - pid_t pid; int fds[2]; - char *gzip_flags; + const char *gzip_flags; if (pipe(fds) < 0) err(1, "could not pipe"); - pid = fork(); - if (pid < 0) + zpid = fork(); + if (zpid < 0) err(1, "could not fork"); /* parent */ - if (pid) { - switch (act) { - case ARCHIVE: + if (zpid) { + if (wr) dup2(fds[1], fd); - break; - case LIST: - case EXTRACT: + else dup2(fds[0], fd); - break; - default: - errx(1, "ar_start_gzip: impossible"); - } close(fds[0]); close(fds[1]); } else { - switch (act) { - case ARCHIVE: + if (wr) { dup2(fds[0], STDIN_FILENO); dup2(fd, STDOUT_FILENO); gzip_flags = "-c"; - break; - case LIST: - case EXTRACT: + } else { dup2(fds[1], STDOUT_FILENO); dup2(fd, STDIN_FILENO); gzip_flags = "-dc"; - break; - default: - errx(1, "ar_start_gzip: impossible"); } close(fds[0]); close(fds[1]); - if (execlp(gzip_program, gzip_program, gzip_flags, NULL) < 0) - err(1, "could not exec"); + if (execlp(gzip_program, gzip_program, gzip_flags, (char *)NULL) < 0) + err(1, "could not exec %s", gzip_program); /* NOTREACHED */ } } diff --combined ar_subs.c index eaf3362,73aefda..382462c --- a/ar_subs.c +++ b/ar_subs.c @@@ -1,4 -1,4 +1,4 @@@ - /* $OpenBSD: ar_subs.c,v 1.14 1998/09/20 02:22:21 millert Exp $ */ + /* $OpenBSD: ar_subs.c,v 1.32 2008/05/06 06:54:28 henning Exp $ */ /* $NetBSD: ar_subs.c,v 1.5 1995/03/21 09:07:06 cgd Exp $ */ /*- @@@ -17,11 -17,7 +17,7 @@@ * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 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. * @@@ -40,15 -36,14 +36,15 @@@ #ifndef lint #if 0 - static char sccsid[] = "@(#)ar_subs.c 8.2 (Berkeley) 4/18/94"; + static const char sccsid[] = "@(#)ar_subs.c 8.2 (Berkeley) 4/18/94"; #else - static char rcsid[] = "$OpenBSD: ar_subs.c,v 1.14 1998/09/20 02:22:21 millert Exp $"; + static const char rcsid[] = "$OpenBSD: ar_subs.c,v 1.32 2008/05/06 06:54:28 henning Exp $"; #endif #endif /* not lint */ #include #include +#include #include #include #include @@@ -61,9 -56,9 +57,9 @@@ #include "pax.h" #include "extern.h" - static void wr_archive __P((register ARCHD *, int is_app)); - static int get_arc __P((void)); - static int next_head __P((register ARCHD *)); + static void wr_archive(ARCHD *, int is_app); + static int get_arc(void); + static int next_head(ARCHD *); extern sigset_t s_mask; /* @@@ -80,16 -75,11 +76,11 @@@ u_long flcnt; /* number of files pro * (no pattern matches all). */ - #ifdef __STDC__ void list(void) - #else - void - list() - #endif { - register ARCHD *arcn; - register int res; + ARCHD *arcn; + int res; ARCHD archd; time_t now; @@@ -114,6 -104,17 +105,17 @@@ * step through the archive until the format says it is done */ while (next_head(arcn) == 0) { + if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) { + /* + * we need to read, to get the real filename + */ + off_t cnt; + if (!(*frmt->rd_data)(arcn, arcn->type == PAX_GLF + ? -1 : -2, &cnt)) + (void)rd_skip(cnt + arcn->pad); + continue; + } + /* * check for pattern, and user specified options match. * When all patterns are matched we are done. @@@ -162,16 -163,11 +164,11 @@@ * pattern(s) (no patterns extracts all members) */ - #ifdef __STDC__ void extract(void) - #else - void - extract() - #endif { - register ARCHD *arcn; - register int res; + ARCHD *arcn; + int res; off_t cnt; ARCHD archd; struct stat sb; @@@ -202,6 -198,15 +199,15 @@@ * says it is done */ while (next_head(arcn) == 0) { + if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) { + /* + * we need to read, to get the real filename + */ + if (!(*frmt->rd_data)(arcn, arcn->type == PAX_GLF + ? -1 : -2, &cnt)) + (void)rd_skip(cnt + arcn->pad); + continue; + } /* * check for pattern, and user specified options match. When @@@ -221,7 -226,7 +227,7 @@@ /* * with -u or -D only extract when the archive member is newer - * than the file with the same name in the file system (nos + * than the file with the same name in the file system (no * test of being the same type is required). * NOTE: this test is done BEFORE name modifications as * specified by pax. this operation can be confusing to the @@@ -262,7 -267,7 +268,7 @@@ } /* - * Non standard -Y and -Z flag. When the exisiting file is + * Non standard -Y and -Z flag. When the existing file is * same age or newer skip */ if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) { @@@ -287,7 -292,7 +293,7 @@@ if (vflag > 1) ls_list(arcn, now, listf); else { - (void)fputs(arcn->name, listf); + (void)safe_print(arcn->name, listf); vfpart = 1; } } @@@ -322,7 -327,7 +328,7 @@@ (void)putc('\n', listf); vfpart = 0; } - continue; + goto popd; } /* * we have a file with data here. If we can not create it, skip @@@ -331,7 -336,7 +337,7 @@@ if ((fd = file_creat(arcn)) < 0) { (void)rd_skip(arcn->skip + arcn->pad); purg_lnk(arcn); - continue; + goto popd; } /* * extract the file from the archive and skip over padding and @@@ -346,6 -351,7 +352,7 @@@ if (!res) (void)rd_skip(cnt + arcn->pad); + popd: /* * if required, chdir around. */ @@@ -373,21 -379,14 +380,14 @@@ * previously written archive. */ - #ifdef __STDC__ static void - wr_archive(register ARCHD *arcn, int is_app) - #else - static void - wr_archive(arcn, is_app) - register ARCHD *arcn; - int is_app; - #endif + wr_archive(ARCHD *arcn, int is_app) { - register int res; - register int hlk; - register int wr_one; + int res; + int hlk; + int wr_one; off_t cnt; - int (*wrf)(); + int (*wrf)(ARCHD *); int fd = -1; time_t now; @@@ -398,11 -397,22 +398,22 @@@ if (((hlk = frmt->hlk) == 1) && (lnk_start() < 0)) return; + /* + * if this is not append, and there are no files, we do not write a + * trailer + */ + wr_one = is_app; + /* * start up the file traversal code and format specific write */ - if ((ftree_start() < 0) || ((*frmt->st_wr)() < 0)) + if (ftree_start() < 0) { + if (is_app) + goto trailer; return; + } else if (((*frmt->st_wr)() < 0)) + return; + wrf = frmt->wr; /* @@@ -412,11 -422,6 +423,6 @@@ if (iflag && (name_start() < 0)) return; - /* - * if this not append, and there are no files, we do no write a trailer - */ - wr_one = is_app; - now = time(NULL); /* @@@ -436,8 -441,10 +442,10 @@@ */ if ((res = chk_ftime(arcn)) < 0) break; - if (res > 0) + if (res > 0) { + ftree_skipped_newer(arcn); continue; + } } /* @@@ -480,7 -487,7 +488,7 @@@ if ((res > 0) || (docrc && (set_crc(arcn, fd) < 0))) { /* * unable to obtain the crc we need, close the file, - * purge link table entry + * purge link table entry */ rdfile_close(arcn, &fd); purg_lnk(arcn); @@@ -491,7 -498,7 +499,7 @@@ if (vflag > 1) ls_list(arcn, now, listf); else { - (void)fputs(arcn->name, listf); + (void)safe_print(arcn->name, listf); vfpart = 1; } } @@@ -507,7 -514,7 +515,7 @@@ } wr_one = 1; if (res > 0) { - /* + /* * format write says no file data needs to be stored * so we are done messing with this file */ @@@ -544,8 -551,9 +552,9 @@@ break; } + trailer: /* - * tell format to write trailer; pad to block boundry; reset directory + * tell format to write trailer; pad to block boundary; reset directory * mode/access times, and check if all patterns supplied by the user * were matched. block off signals to avoid chance for multiple entry * into the cleanup code @@@ -570,7 -578,7 +579,7 @@@ * is called to add the new members. * PAX IMPLEMENTATION DETAIL NOTE: * -u is implemented by adding the new members to the end of the archive. - * Care is taken so that these do not end up as links to the older + * Care is taken so that these do not end up as links to the older * version of the same file already stored in the archive. It is expected * when extraction occurs these newer versions will over-write the older * ones stored "earlier" in the archive (this may be a bad assumption as @@@ -583,16 -591,11 +592,11 @@@ * over write existing files that it creates. */ - #ifdef __STDC__ void append(void) - #else - void - append() - #endif { - register ARCHD *arcn; - register int res; + ARCHD *arcn; + int res; ARCHD archd; FSUB *orgfrmt; int udev; @@@ -603,7 -606,7 +607,7 @@@ /* * Do not allow an append operation if the actual archive is of a - * different format than the user specified foramt. + * different format than the user specified format. */ if (get_arc() < 0) return; @@@ -699,7 -702,7 +703,7 @@@ lnk_end(); /* - * try to postion for write, if this fails quit. if any error occurs, + * try to position for write, if this fails quit. if any error occurs, * we will refuse to write */ if (appnd_start(tlen) < 0) @@@ -712,7 -715,7 +716,7 @@@ (void)fputs("done.\n", listf); vfpart = 0; } - + /* * go to the writing phase to add the new members */ @@@ -724,13 -727,8 +728,8 @@@ * write a new archive */ - #ifdef __STDC__ void archive(void) - #else - void - archive() - #endif { ARCHD archd; @@@ -755,20 -753,15 +754,15 @@@ * (except the files are forced to be under the destination directory). */ - #ifdef __STDC__ void copy(void) - #else - void - copy() - #endif { - register ARCHD *arcn; - register int res; - register int fddest; - register char *dest_pt; - register int dlen; - register int drem; + ARCHD *arcn; + int res; + int fddest; + char *dest_pt; + int dlen; + int drem; int fdsrc = -1; struct stat sb; ARCHD archd; @@@ -779,13 -772,18 +773,18 @@@ * set up the destination dir path and make sure it is a directory. We * make sure we have a trailing / on the destination */ - dlen = l_strncpy(dirbuf, dirptr, sizeof(dirbuf) - 1); + dlen = strlcpy(dirbuf, dirptr, sizeof(dirbuf)); + if (dlen >= sizeof(dirbuf) || + (dlen == sizeof(dirbuf) - 1 && dirbuf[dlen - 1] != '/')) { + paxwarn(1, "directory name is too long %s", dirptr); + return; + } dest_pt = dirbuf + dlen; if (*(dest_pt-1) != '/') { *dest_pt++ = '/'; + *dest_pt = '\0'; ++dlen; } - *dest_pt = '\0'; drem = PAXPATHLEN - dlen; if (stat(dirptr, &sb) < 0) { @@@ -800,7 -798,7 +799,7 @@@ /* * start up the hard link table; file traversal routines and the - * modification time and access mode database + * modification time and access mode database */ if ((lnk_start() < 0) || (ftree_start() < 0) || (dir_start() < 0)) return; @@@ -843,17 -841,12 +842,12 @@@ /* * create the destination name */ - if (*(arcn->name) == '/') - res = 1; - else - res = 0; - if ((arcn->nlen - res) > drem) { + if (strlcpy(dest_pt, arcn->name + (*arcn->name == '/'), + drem + 1) > drem) { paxwarn(1, "Destination pathname too long %s", arcn->name); continue; } - (void)strncpy(dest_pt, arcn->name + res, drem); - dirbuf[PAXPATHLEN] = '\0'; /* * if existing file is same age or newer skip @@@ -861,10 -854,11 +855,11 @@@ res = lstat(dirbuf, &sb); *dest_pt = '\0'; - if (res == 0) { + if (res == 0) { + ftree_skipped_newer(arcn); if (uflag && Dflag) { if ((arcn->sb.st_mtime<=sb.st_mtime) && - (arcn->sb.st_ctime<=sb.st_ctime)) + (arcn->sb.st_ctime<=sb.st_ctime)) continue; } else if (Dflag) { if (arcn->sb.st_ctime <= sb.st_ctime) @@@ -891,7 -885,7 +886,7 @@@ } /* - * Non standard -Y and -Z flag. When the exisiting file is + * Non standard -Y and -Z flag. When the existing file is * same age or newer skip */ if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) { @@@ -907,7 -901,7 +902,7 @@@ } if (vflag) { - (void)fputs(arcn->name, listf); + (void)safe_print(arcn->name, listf); vfpart = 1; } ++flcnt; @@@ -1007,21 -1001,15 +1002,15 @@@ * the specs for rd_wrbuf() for more details) */ - #ifdef __STDC__ - static int - next_head(register ARCHD *arcn) - #else static int - next_head(arcn) - register ARCHD *arcn; - #endif + next_head(ARCHD *arcn) { - register int ret; - register char *hdend; - register int res; - register int shftsz; - register int hsz; - register int in_resync = 0; /* set when we are in resync mode */ + int ret; + char *hdend; + int res; + int shftsz; + int hsz; + int in_resync = 0; /* set when we are in resync mode */ int cnt = 0; /* counter for trailer function */ int first = 1; /* on 1st read, EOF isn't premature. */ @@@ -1032,7 -1020,7 +1021,7 @@@ res = hsz = frmt->hsz; hdend = hdbuf; shftsz = hsz - 1; - for(;;) { + for (;;) { /* * keep looping until we get a contiguous FULL buffer * (frmt->hsz is the proper size) @@@ -1096,7 -1084,7 +1085,7 @@@ /* * this format has trailers outside of valid headers */ - if ((ret = (*frmt->trail)(hdbuf,in_resync,&cnt)) == 0){ + if ((ret = (*frmt->trail)(arcn,hdbuf,in_resync,&cnt)) == 0){ /* * valid trailer found, drain input as required */ @@@ -1143,7 -1131,7 +1132,7 @@@ * the header. NOTE: the parameters are different than trailer routines * which encode trailers outside of the header! */ - if (frmt->inhead && ((*frmt->trail)(arcn) == 0)) { + if (frmt->inhead && ((*frmt->trail)(arcn,NULL,0,NULL) == 0)) { /* * valid trailer found, drain input as required */ @@@ -1165,18 -1153,13 +1154,13 @@@ * 0 if archive found -1 otherwise */ - #ifdef __STDC__ static int get_arc(void) - #else - static int - get_arc() - #endif { - register int i; - register int hdsz = 0; - register int res; - register int minhd = BLKMULT; + int i; + int hdsz = 0; + int res; + int minhd = BLKMULT; char *hdend; int notice = 0; @@@ -1193,7 -1176,7 +1177,7 @@@ res = BLKMULT; hdsz = 0; hdend = hdbuf; - for(;;) { + for (;;) { for (;;) { /* * fill the buffer with at least the smallest header @@@ -1239,7 -1222,7 +1223,7 @@@ if ((*fsub[ford[i]].id)(hdbuf, hdsz) < 0) continue; frmt = &(fsub[ford[i]]); - /* + /* * yuck, to avoid slow special case code in the extract * routines, just push this header back as if it was * not seen. We have left extra space at start of the diff --combined cache.c index 0e4730a,44eda1f..4f80b7c --- a/cache.c +++ b/cache.c @@@ -1,4 -1,4 +1,4 @@@ - /* $OpenBSD: cache.c,v 1.6 1997/07/25 18:58:27 mickey Exp $ */ + /* $OpenBSD: cache.c,v 1.17 2004/03/16 03:28:34 tedu Exp $ */ /* $NetBSD: cache.c,v 1.4 1995/03/21 09:07:10 cgd Exp $ */ /*- @@@ -17,11 -17,7 +17,7 @@@ * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 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. * @@@ -40,9 -36,9 +36,9 @@@ #ifndef lint #if 0 - static char sccsid[] = "@(#)cache.c 8.1 (Berkeley) 5/31/93"; + static const char sccsid[] = "@(#)cache.c 8.1 (Berkeley) 5/31/93"; #else - static char rcsid[] = "$OpenBSD: cache.c,v 1.6 1997/07/25 18:58:27 mickey Exp $"; + static const char rcsid[] = "$OpenBSD: cache.c,v 1.17 2004/03/16 03:28:34 tedu Exp $"; #endif #endif /* not lint */ @@@ -76,18 -72,13 +72,13 @@@ static GIDC **grptb = NULL; /* group na /* * uidtb_start - * creates an an empty uidtb + * creates an empty uidtb * Return: * 0 if ok, -1 otherwise */ - #ifdef __STDC__ int uidtb_start(void) - #else - int - uidtb_start() - #endif { static int fail = 0; @@@ -105,18 -96,13 +96,13 @@@ /* * gidtb_start - * creates an an empty gidtb + * creates an empty gidtb * Return: * 0 if ok, -1 otherwise */ - #ifdef __STDC__ int gidtb_start(void) - #else - int - gidtb_start() - #endif { static int fail = 0; @@@ -134,18 -120,13 +120,13 @@@ /* * usrtb_start - * creates an an empty usrtb + * creates an empty usrtb * Return: * 0 if ok, -1 otherwise */ - #ifdef __STDC__ int usrtb_start(void) - #else - int - usrtb_start() - #endif { static int fail = 0; @@@ -163,18 -144,13 +144,13 @@@ /* * grptb_start - * creates an an empty grptb + * creates an empty grptb * Return: * 0 if ok, -1 otherwise */ - #ifdef __STDC__ int grptb_start(void) - #else - int - grptb_start() - #endif { static int fail = 0; @@@ -198,18 -174,11 +174,11 @@@ * Pointer to stored name (or a empty string) */ - #ifdef __STDC__ char * name_uid(uid_t uid, int frc) - #else - char * - name_uid(uid, frc) - uid_t uid; - int frc; - #endif { - register struct passwd *pw; - register UIDC *ptr; + struct passwd *pw; + UIDC *ptr; if ((uidtb == NULL) && (uidtb_start() < 0)) return(""); @@@ -231,31 -200,23 +200,27 @@@ * No entry for this uid, we will add it */ if (!pwopn) { +#ifdef DEBIAN + setpwent(); +#else setpassent(1); +#endif ++pwopn; } if (ptr == NULL) - ptr = (UIDC *)malloc(sizeof(UIDC)); + 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 numberic format + * a string that is the uid in numeric format */ if (ptr == NULL) return(""); ptr->uid = uid; ptr->valid = INVALID; - # ifdef NET2_STAT - (void)snprintf(ptr->name, sizeof(ptr->name), "%u", uid); - # else (void)snprintf(ptr->name, sizeof(ptr->name), "%lu", (unsigned long)uid); - # endif if (frc == 0) return(""); } else { @@@ -265,8 -226,7 +230,7 @@@ if (ptr == NULL) return(pw->pw_name); ptr->uid = uid; - (void)strncpy(ptr->name, pw->pw_name, UNMLEN-1); - ptr->name[UNMLEN-1] = '\0'; + (void)strlcpy(ptr->name, pw->pw_name, sizeof(ptr->name)); ptr->valid = VALID; } return(ptr->name); @@@ -280,18 -240,11 +244,11 @@@ * Pointer to stored name (or a empty string) */ - #ifdef __STDC__ char * name_gid(gid_t gid, int frc) - #else - char * - name_gid(gid, frc) - gid_t gid; - int frc; - #endif { - register struct group *gr; - register GIDC *ptr; + struct group *gr; + GIDC *ptr; if ((gidtb == NULL) && (gidtb_start() < 0)) return(""); @@@ -313,15 -266,11 +270,15 @@@ * No entry for this gid, we will add it */ if (!gropn) { +#ifdef DEBIAN + setgrent(); +#else setgroupent(1); +#endif ++gropn; } if (ptr == NULL) - ptr = (GIDC *)malloc(sizeof(GIDC)); + ptr = gidtb[gid % GID_SZ] = malloc(sizeof(GIDC)); if ((gr = getgrgid(gid)) == NULL) { /* @@@ -332,12 -281,8 +289,8 @@@ return(""); ptr->gid = gid; ptr->valid = INVALID; - # ifdef NET2_STAT - (void)snprintf(ptr->name, sizeof(ptr->name), "%u", gid); - # else (void)snprintf(ptr->name, sizeof(ptr->name), "%lu", (unsigned long)gid); - # endif if (frc == 0) return(""); } else { @@@ -347,8 -292,7 +300,7 @@@ if (ptr == NULL) return(gr->gr_name); ptr->gid = gid; - (void)strncpy(ptr->name, gr->gr_name, GNMLEN-1); - ptr->name[GNMLEN-1] = '\0'; + (void)strlcpy(ptr->name, gr->gr_name, sizeof(ptr->name)); ptr->valid = VALID; } return(ptr->name); @@@ -361,19 -305,12 +313,12 @@@ * the uid (if any) for a user name, or a -1 if no match can be found */ - #ifdef __STDC__ int uid_name(char *name, uid_t *uid) - #else - int - uid_name(name, uid) - char *name; - uid_t *uid; - #endif { - register struct passwd *pw; - register UIDC *ptr; - register int namelen; + struct passwd *pw; + UIDC *ptr; + int namelen; /* * return -1 for mangled names @@@ -396,16 -333,13 +341,17 @@@ } if (!pwopn) { +#ifdef DEBIAN + setpwent(); +#else setpassent(1); +#endif ++pwopn; } if (ptr == NULL) - ptr = (UIDC *)malloc(sizeof(UIDC)); + ptr = usrtb[st_hash(name, namelen, UNM_SZ)] = + (UIDC *)malloc(sizeof(UIDC)); /* * no match, look it up, if no match store it as an invalid entry, @@@ -417,8 -351,7 +363,7 @@@ *uid = pw->pw_uid; return(0); } - (void)strncpy(ptr->name, name, UNMLEN-1); - ptr->name[UNMLEN-1] = '\0'; + (void)strlcpy(ptr->name, name, sizeof(ptr->name)); if ((pw = getpwnam(name)) == NULL) { ptr->valid = INVALID; return(-1); @@@ -435,19 -368,12 +380,12 @@@ * the gid (if any) for a group name, or a -1 if no match can be found */ - #ifdef __STDC__ int gid_name(char *name, gid_t *gid) - #else - int - gid_name(name, gid) - char *name; - gid_t *gid; - #endif { - register struct group *gr; - register GIDC *ptr; - register int namelen; + struct group *gr; + GIDC *ptr; + int namelen; /* * return -1 for mangled names @@@ -470,15 -396,12 +408,16 @@@ } if (!gropn) { +#ifdef DEBIAN + setgrent(); +#else setgroupent(1); +#endif ++gropn; } if (ptr == NULL) - ptr = (GIDC *)malloc(sizeof(GIDC)); + ptr = grptb[st_hash(name, namelen, GID_SZ)] = + (GIDC *)malloc(sizeof(GIDC)); /* * no match, look it up, if no match store it as an invalid entry, @@@ -491,8 -414,7 +430,7 @@@ return(0); } - (void)strncpy(ptr->name, name, GNMLEN-1); - ptr->name[GNMLEN-1] = '\0'; + (void)strlcpy(ptr->name, name, sizeof(ptr->name)); if ((gr = getgrnam(name)) == NULL) { ptr->valid = INVALID; return(-1); diff --combined cpio.c index eb486fe,4a97960..2019e6d --- a/cpio.c +++ b/cpio.c @@@ -1,4 -1,4 +1,4 @@@ - /* $OpenBSD: cpio.c,v 1.5 1997/07/25 18:58:28 mickey Exp $ */ + /* $OpenBSD: cpio.c,v 1.18 2008/01/01 16:22:44 tobias Exp $ */ /* $NetBSD: cpio.c,v 1.5 1995/03/21 09:07:13 cgd Exp $ */ /*- @@@ -17,11 -17,7 +17,7 @@@ * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 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. * @@@ -40,14 -36,13 +36,14 @@@ #ifndef lint #if 0 - static char sccsid[] = "@(#)cpio.c 8.1 (Berkeley) 5/31/93"; + static const char sccsid[] = "@(#)cpio.c 8.1 (Berkeley) 5/31/93"; #else - static char rcsid[] = "$OpenBSD: cpio.c,v 1.5 1997/07/25 18:58:28 mickey Exp $"; + static const char rcsid[] = "$OpenBSD: cpio.c,v 1.18 2008/01/01 16:22:44 tobias Exp $"; #endif #endif /* not lint */ #include +#include #include #include #include @@@ -59,9 -54,9 +55,9 @@@ #include "cpio.h" #include "extern.h" - static int rd_nm __P((register ARCHD *, int)); - static int rd_ln_nm __P((register ARCHD *)); - static int com_rd __P((register ARCHD *)); + static int rd_nm(ARCHD *, int); + static int rd_ln_nm(ARCHD *); + static int com_rd(ARCHD *); /* * Routines which support the different cpio versions @@@ -80,13 -75,8 +76,8 @@@ static int swp_head; /* binary cpio he * 0 if ok -1 otherwise (the return values of lnk_start()) */ - #ifdef __STDC__ int cpio_strd(void) - #else - int - cpio_strd() - #endif { return(lnk_start()); } @@@ -98,17 -88,11 +89,11 @@@ * mode; looking for a valid header), and cnt (which starts at zero) * which is used to count the number of empty blocks we have seen so far. * Return: - * 0 if a valid trailer, -1 if not a valid trailer, + * 0 if a valid trailer, -1 if not a valid trailer, */ - #ifdef __STDC__ - int - cpio_trail(register ARCHD *arcn) - #else int - cpio_trail(arcn) - register ARCHD *arcn; - #endif + cpio_trail(ARCHD *arcn, char *notused, int notused2, int *notused3) { /* * look for trailer id in file we are about to process @@@ -125,19 -109,13 +110,13 @@@ * 0 */ - #ifdef __STDC__ - static int - com_rd(register ARCHD *arcn) - #else static int - com_rd(arcn) - register ARCHD *arcn; - #endif + com_rd(ARCHD *arcn) { arcn->skip = 0; arcn->pat = NULL; arcn->org_name = arcn->name; - switch(arcn->sb.st_mode & C_IFMT) { + switch (arcn->sb.st_mode & C_IFMT) { case C_ISFIFO: arcn->type = PAX_FIF; break; @@@ -174,19 -152,14 +153,14 @@@ } /* - * cpio_end_wr() + * cpio_endwr() * write the special file with the name trailer in the proper format * Return: * result of the write of the trailer from the cpio specific write func */ - #ifdef __STDC__ int cpio_endwr(void) - #else - int - cpio_endwr() - #endif { ARCHD last; @@@ -197,7 -170,7 +171,7 @@@ last.nlen = sizeof(TRAILER) - 1; last.type = PAX_REG; last.sb.st_nlink = 1; - (void)strcpy(last.name, TRAILER); + (void)strlcpy(last.name, TRAILER, sizeof(last.name)); return((*frmt->wr)(&last)); } @@@ -208,15 -181,8 +182,8 @@@ * 0 if ok, -1 otherwise */ - #ifdef __STDC__ static int - rd_nm(register ARCHD *arcn, int nsz) - #else - static int - rd_nm(arcn, nsz) - register ARCHD *arcn; - int nsz; - #endif + rd_nm(ARCHD *arcn, int nsz) { /* * do not even try bogus values @@@ -245,21 -211,15 +212,15 @@@ * 0 if ok, -1 otherwise */ - #ifdef __STDC__ - static int - rd_ln_nm(register ARCHD *arcn) - #else static int - rd_ln_nm(arcn) - register ARCHD *arcn; - #endif + rd_ln_nm(ARCHD *arcn) { /* * check the length specified for bogus values */ if ((arcn->sb.st_size == 0) || (arcn->sb.st_size >= sizeof(arcn->ln_name))) { - # ifdef NET2_STAT + # ifdef LONG_OFF_T paxwarn(1, "Cpio link name length is invalid: %lu", arcn->sb.st_size); # else @@@ -302,15 -262,8 +263,8 @@@ * 0 if a valid header, -1 otherwise */ - #ifdef __STDC__ int cpio_id(char *blk, int size) - #else - int - cpio_id(blk, size) - char *blk; - int size; - #endif { if ((size < sizeof(HD_CPIO)) || (strncmp(blk, AMAGIC, sizeof(AMAGIC) - 1) != 0)) @@@ -326,18 -279,11 +280,11 @@@ * 0 if a valid header, -1 otherwise. */ - #ifdef __STDC__ - int - cpio_rd(register ARCHD *arcn, register char *buf) - #else int - cpio_rd(arcn, buf) - register ARCHD *arcn; - register char *buf; - #endif + cpio_rd(ARCHD *arcn, char *buf) { - register int nsz; - register HD_CPIO *hd; + int nsz; + HD_CPIO *hd; /* * check that this is a valid header, if not return -1 @@@ -362,7 -308,7 +309,7 @@@ arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime, sizeof(hd->c_mtime), OCT); arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; - # ifdef NET2_STAT + # ifdef LONG_OFF_T arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,sizeof(hd->c_filesize), OCT); # else @@@ -382,8 -328,8 +329,8 @@@ if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) { /* - * no link name to read for this file - */ + * no link name to read for this file + */ arcn->ln_nlen = 0; arcn->ln_name[0] = '\0'; return(com_rd(arcn)); @@@ -409,13 -355,8 +356,8 @@@ * size of trailer header in this format */ - #ifdef __STDC__ off_t cpio_endrd(void) - #else - off_t - cpio_endrd() - #endif { return((off_t)(sizeof(HD_CPIO) + sizeof(TRAILER))); } @@@ -427,13 -368,8 +369,8 @@@ * 0 if ok, -1 otherwise (what dev_start() returns) */ - #ifdef __STDC__ int cpio_stwr(void) - #else - int - cpio_stwr() - #endif { return(dev_start()); } @@@ -447,17 -383,11 +384,11 @@@ * data to write after the header, -1 if archive write failed */ - #ifdef __STDC__ int - cpio_wr(register ARCHD *arcn) - #else - int - cpio_wr(arcn) - register ARCHD *arcn; - #endif + cpio_wr(ARCHD *arcn) { - register HD_CPIO *hd; - register int nsz; + HD_CPIO *hd; + int nsz; char hdblk[sizeof(HD_CPIO)]; /* @@@ -472,14 -402,14 +403,14 @@@ if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) arcn->sb.st_rdev = 0; - switch(arcn->type) { + switch (arcn->type) { case PAX_CTG: case PAX_REG: case PAX_HRG: /* * set data size for file data */ - # ifdef NET2_STAT + # ifdef LONG_OFF_T if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize, sizeof(hd->c_filesize), OCT)) { # else @@@ -577,21 -507,14 +508,14 @@@ /* * vcpio_id() * determine if a block given to us is a valid system VR4 cpio header - * WITHOUT crc. WATCH it the magic cookies are in OCTAL, the header + * WITHOUT crc. WATCH it the magic cookies are in OCTAL, the header * uses HEX * Return: * 0 if a valid header, -1 otherwise */ - #ifdef __STDC__ int vcpio_id(char *blk, int size) - #else - int - vcpio_id(blk, size) - char *blk; - int size; - #endif { if ((size < sizeof(HD_VCPIO)) || (strncmp(blk, AVMAGIC, sizeof(AVMAGIC) - 1) != 0)) @@@ -607,15 -530,8 +531,8 @@@ * 0 if a valid header, -1 otherwise */ - #ifdef __STDC__ int crc_id(char *blk, int size) - #else - int - crc_id(blk, size) - char *blk; - int size; - #endif { if ((size < sizeof(HD_VCPIO)) || (strncmp(blk, AVCMAGIC, sizeof(AVCMAGIC) - 1) != 0)) @@@ -630,13 -546,8 +547,8 @@@ * 0 if ok -1 otherwise (the return values of lnk_start()) */ - #ifdef __STDC__ int crc_strd(void) - #else - int - crc_strd() - #endif { docrc = 1; return(lnk_start()); @@@ -650,20 -561,13 +562,13 @@@ * 0 if a valid header, -1 otherwise. */ - #ifdef __STDC__ - int - vcpio_rd(register ARCHD *arcn, register char *buf) - #else int - vcpio_rd(arcn, buf) - register ARCHD *arcn; - register char *buf; - #endif + vcpio_rd(ARCHD *arcn, char *buf) { - register HD_VCPIO *hd; + HD_VCPIO *hd; dev_t devminor; dev_t devmajor; - register int nsz; + int nsz; /* * during the id phase it was determined if we were using CRC, use the @@@ -689,7 -593,7 +594,7 @@@ arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), HEX); arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX); arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; - # ifdef NET2_STAT + # ifdef LONG_OFF_T arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize, sizeof(hd->c_filesize), HEX); # else @@@ -717,7 -621,7 +622,7 @@@ return(-1); /* - * skip padding. header + filename is aligned to 4 byte boundries + * skip padding. header + filename is aligned to 4 byte boundaries */ if (rd_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0) return(-1); @@@ -756,13 -660,8 +661,8 @@@ * size of trailer header in this format */ - #ifdef __STDC__ off_t vcpio_endrd(void) - #else - off_t - vcpio_endrd() - #endif { return((off_t)(sizeof(HD_VCPIO) + sizeof(TRAILER) + (VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER))))); @@@ -775,13 -674,8 +675,8 @@@ * 0 if ok, -1 otherwise (what dev_start() returns) */ - #ifdef __STDC__ int crc_stwr(void) - #else - int - crc_stwr() - #endif { docrc = 1; return(dev_start()); @@@ -796,16 -690,10 +691,10 @@@ * NO data to write after the header, -1 if archive write failed */ - #ifdef __STDC__ - int - vcpio_wr(register ARCHD *arcn) - #else int - vcpio_wr(arcn) - register ARCHD *arcn; - #endif + vcpio_wr(ARCHD *arcn) { - register HD_VCPIO *hd; + HD_VCPIO *hd; unsigned int nsz; char hdblk[sizeof(HD_VCPIO)]; @@@ -826,18 -714,18 +715,18 @@@ */ if (docrc) { if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic), - OCT) || + OCT) || ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum), - HEX)) + HEX)) goto out; } else { if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic), - OCT) || + OCT) || ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX)) goto out; } - switch(arcn->type) { + switch (arcn->type) { case PAX_CTG: case PAX_REG: case PAX_HRG: @@@ -846,7 -734,7 +735,7 @@@ * much to pad. */ arcn->pad = VCPIO_PAD(arcn->sb.st_size); - # ifdef NET2_STAT + # ifdef LONG_OFF_T if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize, sizeof(hd->c_filesize), HEX)) { # else @@@ -889,11 -777,11 +778,11 @@@ 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) || + HEX) || ul_asc((u_long)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime), - HEX) || + HEX) || ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), - HEX) || + 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), @@@ -959,15 -847,8 +848,8 @@@ * 0 if a valid header, -1 otherwise */ - #ifdef __STDC__ int bcpio_id(char *blk, int size) - #else - int - bcpio_id(blk, size) - char *blk; - int size; - #endif { if (size < sizeof(HD_BCPIO)) return(-1); @@@ -994,18 -875,11 +876,11 @@@ * 0 if a valid header, -1 otherwise. */ - #ifdef __STDC__ - int - bcpio_rd(register ARCHD *arcn, register char *buf) - #else int - bcpio_rd(arcn, buf) - register ARCHD *arcn; - register char *buf; - #endif + bcpio_rd(ARCHD *arcn, char *buf) { - register HD_BCPIO *hd; - register int nsz; + HD_BCPIO *hd; + int nsz; /* * check the header @@@ -1017,7 -891,7 +892,7 @@@ hd = (HD_BCPIO *)buf; if (swp_head) { /* - * header has swapped bytes on 16 bit boundries + * header has swapped bytes on 16 bit boundaries */ arcn->sb.st_dev = (dev_t)(RSHRT_EXT(hd->h_dev)); arcn->sb.st_ino = (ino_t)(RSHRT_EXT(hd->h_ino)); @@@ -1062,7 -936,7 +937,7 @@@ return(-1); /* - * header + file name are aligned to 2 byte boundries, skip if needed + * header + file name are aligned to 2 byte boundaries, skip if needed */ if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0) return(-1); @@@ -1098,13 -972,8 +973,8 @@@ * size of trailer header in this format */ - #ifdef __STDC__ off_t bcpio_endrd(void) - #else - off_t - bcpio_endrd() - #endif { return((off_t)(sizeof(HD_BCPIO) + sizeof(TRAILER) + (BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER))))); @@@ -1114,24 -983,18 +984,18 @@@ * bcpio_wr() * copy the data in the ARCHD to buffer in old binary cpio format * There is a real chance of field overflow with this critter. So we - * always check the conversion is ok. nobody in his their right mind - * should write an achive in this format... + * always check the conversion is ok. nobody in their right mind + * should write an archive in this format... * Return * 0 if file has data to be written after the header, 1 if file has NO * data to write after the header, -1 if archive write failed */ - #ifdef __STDC__ int - bcpio_wr(register ARCHD *arcn) - #else - int - bcpio_wr(arcn) - register ARCHD *arcn; - #endif + bcpio_wr(ARCHD *arcn) { - register HD_BCPIO *hd; - register int nsz; + HD_BCPIO *hd; + int nsz; char hdblk[sizeof(HD_BCPIO)]; off_t t_offt; int t_int; @@@ -1148,7 -1011,7 +1012,7 @@@ arcn->sb.st_rdev = 0; hd = (HD_BCPIO *)hdblk; - switch(arcn->type) { + switch (arcn->type) { case PAX_CTG: case PAX_REG: case PAX_HRG: diff --combined gen_subs.c index 69fe373,7e66f62..07c9e96 --- a/gen_subs.c +++ b/gen_subs.c @@@ -1,4 -1,4 +1,4 @@@ - /* $OpenBSD: gen_subs.c,v 1.8 1997/09/01 18:29:51 deraadt Exp $ */ + /* $OpenBSD: gen_subs.c,v 1.19 2007/04/04 21:55:10 millert Exp $ */ /* $NetBSD: gen_subs.c,v 1.5 1995/03/21 09:07:26 cgd Exp $ */ /*- @@@ -17,11 -17,7 +17,7 @@@ * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 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. * @@@ -40,29 -36,26 +36,30 @@@ #ifndef lint #if 0 - static char sccsid[] = "@(#)gen_subs.c 8.1 (Berkeley) 5/31/93"; + static const char sccsid[] = "@(#)gen_subs.c 8.1 (Berkeley) 5/31/93"; #else - static char rcsid[] = "$OpenBSD: gen_subs.c,v 1.8 1997/09/01 18:29:51 deraadt Exp $"; + static const char rcsid[] = "$OpenBSD: gen_subs.c,v 1.19 2007/04/04 21:55:10 millert Exp $"; #endif #endif /* not lint */ #include +#include #include +#include #include #include #include -#include +#include "tzfile.h" #include #include #include #include + #include #include "pax.h" #include "extern.h" +#include "strmode.h" + /* * a collection of general purpose subroutines used by pax */ @@@ -75,37 -68,33 +72,33 @@@ #define SIXMONTHS ((DAYSPERNYEAR / 2) * SECSPERDAY) #define CURFRMT "%b %e %H:%M" #define OLDFRMT "%b %e %Y" - #ifndef UT_NAMESIZE - #define UT_NAMESIZE 8 - #endif - #define UT_GRPSIZE 6 + #define NAME_WIDTH 8 /* * ls_list() * list the members of an archive in ls format */ - #ifdef __STDC__ - void - ls_list(register ARCHD *arcn, time_t now, FILE *fp) - #else void - ls_list(arcn, now, fp) - register ARCHD *arcn; - time_t now; - FILE *fp; - #endif + ls_list(ARCHD *arcn, time_t now, FILE *fp) { - register struct stat *sbp; + struct stat *sbp; char f_mode[MODELEN]; char f_date[DATELEN]; - char *timefrmt; + const char *timefrmt; + int term; + + term = zeroflag ? '\0' : '\n'; /* path termination character */ /* * if not verbose, just print the file name */ if (!vflag) { - (void)fprintf(fp, "%s\n", arcn->name); + if (zeroflag) + (void)fputs(arcn->name, fp); + else + safe_print(arcn->name, fp); + (void)putc(term, fp); (void)fflush(fp); return; } @@@ -133,22 -122,22 +126,22 @@@ */ if (strftime(f_date,DATELEN,timefrmt,localtime(&(sbp->st_mtime))) == 0) f_date[0] = '\0'; - (void)fprintf(fp, "%s%2u %-*s %-*s ", f_mode, sbp->st_nlink, - UT_NAMESIZE, name_uid(sbp->st_uid, 1), UT_GRPSIZE, - name_gid(sbp->st_gid, 1)); + (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)); /* * print device id's for devices, or sizes for other nodes */ if ((arcn->type == PAX_CHR) || (arcn->type == PAX_BLK)) - # ifdef NET2_STAT + # ifdef LONG_OFF_T (void)fprintf(fp, "%4u,%4u ", MAJOR(sbp->st_rdev), # else (void)fprintf(fp, "%4lu,%4lu ", (unsigned long)MAJOR(sbp->st_rdev), # endif (unsigned long)MINOR(sbp->st_rdev)); else { - # ifdef NET2_STAT + # ifdef LONG_OFF_T (void)fprintf(fp, "%9lu ", sbp->st_size); # else (void)fprintf(fp, "%9qu ", sbp->st_size); @@@ -158,34 -147,32 +151,32 @@@ /* * print name and link info for hard and soft links */ - (void)fprintf(fp, "%s %s", f_date, arcn->name); - if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) - (void)fprintf(fp, " == %s\n", arcn->ln_name); - else if (arcn->type == PAX_SLK) - (void)fprintf(fp, " => %s\n", arcn->ln_name); - else - (void)putc('\n', fp); + (void)fputs(f_date, fp); + (void)putc(' ', fp); + safe_print(arcn->name, fp); + if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) { + fputs(" == ", fp); + safe_print(arcn->ln_name, fp); + } else if (arcn->type == PAX_SLK) { + fputs(" -> ", fp); + safe_print(arcn->ln_name, fp); + } + (void)putc(term, fp); (void)fflush(fp); return; } /* * tty_ls() - * print a short summary of file to tty. + * print a short summary of file to tty. */ - #ifdef __STDC__ - void - ls_tty(register ARCHD *arcn) - #else void - ls_tty(arcn) - register ARCHD *arcn; - #endif + ls_tty(ARCHD *arcn) { char f_date[DATELEN]; char f_mode[MODELEN]; - char *timefrmt; + const char *timefrmt; if (ltmfrmt == NULL) { /* @@@ -209,37 -196,23 +200,23 @@@ return; } - /* - * l_strncpy() - * copy src to dest up to len chars (stopping at first '\0'). - * when src is shorter than len, pads to len with '\0'. - * Return: - * number of chars copied. (Note this is a real performance win over - * doing a strncpy(), a strlen(), and then a possible memset()) - */ - - #ifdef __STDC__ - int - l_strncpy(register char *dest, register char *src, int len) - #else - int - l_strncpy(dest, src, len) - register char *dest; - register char *src; - int len; - #endif + void + safe_print(const char *str, FILE *fp) { - register char *stop; - register char *start; - - stop = dest + len; - start = dest; - while ((dest < stop) && (*src != '\0')) - *dest++ = *src++; - len = dest - start; - while (dest < stop) - *dest++ = '\0'; - return(len); + char visbuf[5]; + const char *cp; + + /* + * if printing to a tty, use vis(3) to print special characters. + */ + if (isatty(fileno(fp))) { + for (cp = str; *cp; cp++) { + (void)vis(visbuf, cp[0], VIS_CSTYLE, cp[1]); + (void)fputs(visbuf, fp); + } + } else { + (void)fputs(str, fp); + } } /* @@@ -252,18 -225,10 +229,10 @@@ * unsigned long value */ - #ifdef __STDC__ u_long - asc_ul(register char *str, int len, register int base) - #else - u_long - asc_ul(str, len, base) - register char *str; - int len; - register int base; - #endif + asc_ul(char *str, int len, int base) { - register char *stop; + char *stop; u_long tval = 0; stop = str + len; @@@ -290,7 -255,7 +259,7 @@@ break; } } else { - while ((str < stop) && (*str >= '0') && (*str <= '7')) + while ((str < stop) && (*str >= '0') && (*str <= '7')) tval = (tval << 3) + (*str++ - '0'); } return(tval); @@@ -303,19 -268,10 +272,10 @@@ * NOTE: the string created is NOT TERMINATED. */ - #ifdef __STDC__ int - ul_asc(u_long val, register char *str, register int len, register int base) - #else - int - ul_asc(val, str, len, base) - u_long val; - register char *str; - register int len; - register int base; - #endif + ul_asc(u_long val, char *str, int len, int base) { - register char *pt; + char *pt; u_long digit; /* @@@ -355,7 -311,7 +315,7 @@@ return(0); } - #ifndef NET2_STAT + #ifndef LONG_OFF_T /* * asc_uqd() * convert hex/octal character string into a u_quad_t. We do not have to @@@ -366,18 -322,10 +326,10 @@@ * u_quad_t value */ - #ifdef __STDC__ - u_quad_t - asc_uqd(register char *str, int len, register int base) - #else u_quad_t - asc_uqd(str, len, base) - register char *str; - int len; - register int base; - #endif + asc_uqd(char *str, int len, int base) { - register char *stop; + char *stop; u_quad_t tval = 0; stop = str + len; @@@ -404,7 -352,7 +356,7 @@@ break; } } else { - while ((str < stop) && (*str >= '0') && (*str <= '7')) + while ((str < stop) && (*str >= '0') && (*str <= '7')) tval = (tval << 3) + (*str++ - '0'); } return(tval); @@@ -417,19 -365,10 +369,10 @@@ * NOTE: the string created is NOT TERMINATED. */ - #ifdef __STDC__ - int - uqd_asc(u_quad_t val, register char *str, register int len, register int base) - #else int - uqd_asc(val, str, len, base) - u_quad_t val; - register char *str; - register int len; - register int base; - #endif + uqd_asc(u_quad_t val, char *str, int len, int base) { - register char *pt; + char *pt; u_quad_t digit; /* @@@ -469,3 -408,25 +412,25 @@@ return(0); } #endif + + /* + * Copy at max min(bufz, fieldsz) chars from field to buf, stopping + * at the first NUL char. NUL terminate buf if there is room left. + */ + size_t + fieldcpy(char *buf, size_t bufsz, const char *field, size_t fieldsz) + { + char *p = buf; + const char *q = field; + size_t i = 0; + + if (fieldsz > bufsz) + fieldsz = bufsz; + while (i < fieldsz && *q != '\0') { + *p++ = *q++; + i++; + } + if (i < bufsz) + *p = '\0'; + return(i); + } diff --combined options.c index 49592e6,fa19889..4cc16d7 --- a/options.c +++ b/options.c @@@ -1,4 -1,4 +1,4 @@@ - /* $OpenBSD: options.c,v 1.34 1998/09/20 02:22:22 millert Exp $ */ + /* $OpenBSD: options.c,v 1.70 2008/06/11 00:49:08 pvalchev Exp $ */ /* $NetBSD: options.c,v 1.6 1996/03/26 23:54:18 mrg Exp $ */ /*- @@@ -17,11 -17,7 +17,7 @@@ * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 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. * @@@ -40,9 -36,9 +36,9 @@@ #ifndef lint #if 0 - static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94"; + static const char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94"; #else - static char rcsid[] = "$OpenBSD: options.c,v 1.34 1998/09/20 02:22:22 millert Exp $"; + static const char rcsid[] = "$OpenBSD: options.c,v 1.70 2008/06/11 00:49:08 pvalchev Exp $"; #endif #endif /* not lint */ @@@ -64,8 -60,6 +60,8 @@@ #include "tar.h" #include "extern.h" +#include "fgetln.h" /* added, David */ + /* * Routines which handle command line options */ @@@ -74,16 -68,23 +70,23 @@@ static char flgch[] = FLGCH; /* list o static OPLIST *ophead = NULL; /* head for format specific options -x */ static OPLIST *optail = NULL; /* option tail */ - static int no_op __P((void)); - static void printflg __P((unsigned int)); - static int c_frmt __P((const void *, const void *)); - static off_t str_offt __P((char *)); - static void pax_options __P((register int, register char **)); - static void pax_usage __P((void)); - static void tar_options __P((register int, register char **)); - static void tar_usage __P((void)); - static void cpio_options __P((register int, register char **)); - static void cpio_usage __P((void)); + static int no_op(void); + static void printflg(unsigned int); + static int c_frmt(const void *, const void *); + static off_t str_offt(char *); + static char *getline(FILE *fp); + static void pax_options(int, char **); + static void pax_usage(void); + static void tar_options(int, char **); + static void tar_usage(void); + static void cpio_options(int, char **); + static void cpio_usage(void); + + /* errors from getline */ + #define GETLINE_FILE_CORRUPT 1 + #define GETLINE_OUT_OF_MEM 2 + static int getline_error; + #define GZIP_CMD "gzip" /* command to run as gzip */ #define COMPRESS_CMD "compress" /* command to run as compress */ @@@ -138,26 -139,24 +141,24 @@@ FSUB fsub[] = /* * ford is the archive search order used by get_arc() to determine what kind - * of archive we are dealing with. This helps to properly id archive formats + * of archive we are dealing with. This helps to properly id archive formats * some formats may be subsets of others.... */ int ford[] = {5, 4, 3, 2, 1, 0, -1 }; + /* + * Do we have -C anywhere? + */ + int havechd = 0; + /* * options() * figure out if we are pax, tar or cpio. Call the appropriate options * parser */ - #ifdef __STDC__ - void - options(register int argc, register char **argv) - #else void - options(argc, argv) - register int argc; - register char **argv; - #endif + options(int argc, char **argv) { /* @@@ -168,15 -167,18 +169,18 @@@ else argv0 = argv[0]; - if (strcmp(NM_TAR, argv0) == 0) - return(tar_options(argc, argv)); - else if (strcmp(NM_CPIO, argv0) == 0) - return(cpio_options(argc, argv)); + if (strcmp(NM_TAR, argv0) == 0) { + tar_options(argc, argv); + return; + } else if (strcmp(NM_CPIO, argv0) == 0) { + cpio_options(argc, argv); + return; + } /* * assume pax as the default */ argv0 = NM_PAX; - return(pax_options(argc, argv)); + pax_options(argc, argv); } /* @@@ -185,30 -187,21 +189,21 @@@ * the user specified a legal set of flags. If not, complain and exit */ - #ifdef __STDC__ - static void - pax_options(register int argc, register char **argv) - #else static void - pax_options(argc, argv) - register int argc; - register char **argv; - #endif + pax_options(int argc, char **argv) { - register int c; - register int i; + int c; + int i; unsigned int flg = 0; unsigned int bflg = 0; - register char *pt; + char *pt; FSUB tmp; - extern char *optarg; - extern int optind; /* * process option flags */ - while ((c=getopt(argc,argv,"ab:cdf:ijklno:p:rs:tuvwx:zB:DE:G:HLPT:U:XYZ")) - != EOF) { + while ((c=getopt(argc,argv,"ab:cdf:ijklno:p:rs:tuvwx:zB:DE:G:HLOPT:U:XYZ0")) + != -1) { switch (c) { case 'a': /* @@@ -258,7 -251,6 +253,6 @@@ /* * use bzip2. Non standard option. */ - zflag = 1; gzip_program = BZIP2_CMD; break; case 'k': @@@ -295,7 -287,7 +289,7 @@@ * specify file characteristic options */ for (pt = optarg; *pt != '\0'; ++pt) { - switch(*pt) { + switch (*pt) { case 'a': /* * do not preserve access time @@@ -326,7 -318,7 +320,7 @@@ break; case 'p': /* - * preserver file mode bits + * preserve file mode bits */ pmode = 1; break; @@@ -402,7 -394,6 +396,6 @@@ /* * use gzip. Non standard option. */ - zflag = 1; gzip_program = GZIP_CMD; break; case 'B': @@@ -468,6 -459,12 +461,12 @@@ Lflag = 1; flg |= CLF; break; + case 'O': + /* + * Force one volume. Non standard option. + */ + force_one_volume = 1; + break; case 'P': /* * do NOT follow symlinks (default) @@@ -520,6 -517,14 +519,14 @@@ Zflag = 1; flg |= CZF; break; + case '0': + /* + * Use \0 as pathname terminator. + * (For use with the -print0 option of find(1).) + */ + zeroflag = 1; + flg |= C0F; + break; default: pax_usage(); break; @@@ -600,19 -605,19 +607,19 @@@ * the user specified a legal set of flags. If not, complain and exit */ - #ifdef __STDC__ - static void - tar_options(register int argc, register char **argv) - #else static void - tar_options(argc, argv) - register int argc; - register char **argv; - #endif + tar_options(int argc, char **argv) { - register int c; + int c; int fstdin = 0; int Oflag = 0; + int nincfiles = 0; + int incfiles_max = 0; + struct incfile { + char *file; + char *dir; + }; + struct incfile *incfiles = NULL; /* * Set default values. @@@ -623,9 -628,8 +630,8 @@@ * process option flags */ while ((c = getoldopt(argc, argv, - "b:cef:hjmopruts:vwxzBC:HLOPXZ014578")) - != EOF) { - switch(c) { + "b:cef:hjmopqruts:vwxzBC:HI:LOPXZ014578")) != -1) { + switch (c) { case 'b': /* * specify blocksize in 512-byte blocks @@@ -673,7 -677,6 +679,6 @@@ /* * use bzip2. Non standard option. */ - zflag = 1; gzip_program = BZIP2_CMD; break; case 'm': @@@ -682,12 -685,12 +687,12 @@@ */ pmtime = 0; break; - case 'o': - if (opt_add("write_opt=nodir") < 0) - tar_usage(); case 'O': Oflag = 1; break; + case 'o': + Oflag = 2; + break; case 'p': /* * preserve uid/gid and file mode, regardless of umask @@@ -695,6 -698,12 +700,12 @@@ pmode = 1; pids = 1; break; + case 'q': + /* + * select first match for a pattern only + */ + nflag = 1; + break; case 'r': case 'u': /* @@@ -741,7 -750,6 +752,6 @@@ /* * use gzip. Non standard option. */ - zflag = 1; gzip_program = GZIP_CMD; break; case 'B': @@@ -750,6 -758,7 +760,7 @@@ */ break; case 'C': + havechd++; chdname = optarg; break; case 'H': @@@ -758,6 -767,20 +769,20 @@@ */ Hflag = 1; break; + case 'I': + if (++nincfiles > incfiles_max) { + incfiles_max = nincfiles + 3; + incfiles = realloc(incfiles, + sizeof(*incfiles) * incfiles_max); + if (incfiles == NULL) { + paxwarn(0, "Unable to allocate space " + "for option list"); + exit(1); + } + } + incfiles[nincfiles - 1].file = optarg; + incfiles[nincfiles - 1].dir = chdname; + break; case 'L': /* * follow symlinks @@@ -780,7 -803,6 +805,6 @@@ /* * use compress. */ - zflag = 1; gzip_program = COMPRESS_CMD; break; case '0': @@@ -815,21 -837,10 +839,10 @@@ else listf = stdout; - /* Traditional tar behaviour (pax wants to read filelist from stdin) */ - if ((act == ARCHIVE || act == APPND) && argc == 0) + /* Traditional tar behaviour (pax wants to read file list from stdin) */ + if ((act == ARCHIVE || act == APPND) && argc == 0 && nincfiles == 0) exit(0); - /* - * if we are writing (ARCHIVE) specify tar, otherwise run like pax - * (unless -o specified) - */ - if (act == ARCHIVE || act == APPND) - frmt = &(fsub[Oflag ? F_OTAR : F_TAR]); - else if (Oflag) { - paxwarn(1, "The -O/-o options are only valid when writing an archive"); - tar_usage(); /* only valid when writing */ - } - /* * process the args as they are interpreted by the operation mode */ @@@ -839,22 -850,62 +852,62 @@@ default: { int sawpat = 0; + char *file, *dir; - while (*argv != NULL) { - if (strcmp(*argv, "-C") == 0) { - if(*++argv == NULL) + while (nincfiles || *argv != NULL) { + /* + * If we queued up any include files, + * pull them in now. Otherwise, check + * for -I and -C positional flags. + * Anything else must be a file to + * extract. + */ + if (nincfiles) { + file = incfiles->file; + dir = incfiles->dir; + incfiles++; + nincfiles--; + } else if (strcmp(*argv, "-I") == 0) { + if (*++argv == NULL) + break; + file = *argv++; + dir = chdname; + } else + file = NULL; + if (file != NULL) { + FILE *fp; + char *str; + + if (strcmp(file, "-") == 0) + fp = stdin; + else if ((fp = fopen(file, "r")) == NULL) { + paxwarn(1, "Unable to open file '%s' for read", file); + tar_usage(); + } + while ((str = getline(fp)) != NULL) { + if (pat_add(str, dir) < 0) + tar_usage(); + sawpat = 1; + } + if (strcmp(file, "-") != 0) + fclose(fp); + if (getline_error) { + paxwarn(1, "Problem with file '%s'", file); + tar_usage(); + } + } else if (strcmp(*argv, "-C") == 0) { + if (*++argv == NULL) break; chdname = *argv++; - - continue; - } - if (pat_add(*argv++, chdname) < 0) + havechd++; + } else if (pat_add(*argv++, chdname) < 0) tar_usage(); - sawpat++; + else + sawpat = 1; } /* * if patterns were added, we are doing chdir() - * on a file-by-file basis, else, just one + * on a file-by-file basis, else, just one * global chdir (if any) after opening input. */ if (sawpat > 0) @@@ -863,21 -914,72 +916,72 @@@ break; case ARCHIVE: case APPND: + frmt = &(fsub[Oflag ? F_OTAR : F_TAR]); + + if (Oflag == 2 && opt_add("write_opt=nodir") < 0) + tar_usage(); + if (chdname != NULL) { /* initial chdir() */ if (ftree_add(chdname, 1) < 0) tar_usage(); } - while (*argv != NULL) { - if (!strcmp(*argv, "-C")) { + while (nincfiles || *argv != NULL) { + char *file, *dir; + + /* + * If we queued up any include files, pull them in + * now. Otherwise, check for -I and -C positional + * flags. Anything else must be a file to include + * in the archive. + */ + if (nincfiles) { + file = incfiles->file; + dir = incfiles->dir; + incfiles++; + nincfiles--; + } else if (strcmp(*argv, "-I") == 0) { if (*++argv == NULL) break; - if (ftree_add(*argv++, 1) < 0) + file = *argv++; + dir = NULL; + } else + file = NULL; + if (file != NULL) { + FILE *fp; + char *str; + + /* Set directory if needed */ + if (dir) { + if (ftree_add(dir, 1) < 0) + tar_usage(); + } + + if (strcmp(file, "-") == 0) + fp = stdin; + else if ((fp = fopen(file, "r")) == NULL) { + paxwarn(1, "Unable to open file '%s' for read", file); + tar_usage(); + } + while ((str = getline(fp)) != NULL) { + if (ftree_add(str, 0) < 0) + tar_usage(); + } + if (strcmp(file, "-") != 0) + fclose(fp); + if (getline_error) { + paxwarn(1, "Problem with file '%s'", + file); tar_usage(); - } else { - if (ftree_add(*argv++, 0) < 0) + } + } else if (strcmp(*argv, "-C") == 0) { + if (*++argv == NULL) + break; + if (ftree_add(*argv++, 1) < 0) tar_usage(); - } + havechd++; + } else if (ftree_add(*argv++, 0) < 0) + tar_usage(); } /* * no read errors allowed on updates/append operation! @@@ -892,12 -994,14 +996,14 @@@ } } + int mkpath(char *); + int mkpath(path) char *path; { struct stat sb; - register char *slash; + char *slash; int done = 0; slash = path; @@@ -931,18 -1035,10 +1037,10 @@@ * the user specified a legal set of flags. If not, complain and exit */ - #ifdef __STDC__ static void - cpio_options(register int argc, register char **argv) - #else - static void - cpio_options(argc, argv) - register int argc; - register char **argv; - #endif + cpio_options(int argc, char **argv) { - register int c, i; - size_t len; + int c, i; char *str; FSUB tmp; FILE *fp; @@@ -955,7 -1051,7 +1053,7 @@@ dflag = 1; act = -1; nodirs = 1; - while ((c=getopt(argc,argv,"abcdfijklmoprstuvzABC:E:F:H:I:LO:SZ6")) != EOF) + while ((c=getopt(argc,argv,"abcdfijklmoprstuvzABC:E:F:H:I:LO:SZ6")) != -1) switch (c) { case 'a': /* @@@ -996,7 -1092,6 +1094,6 @@@ /* * use bzip2. Non standard option. */ - zflag = 1; gzip_program = BZIP2_CMD; break; case 'k': @@@ -1060,7 -1155,6 +1157,6 @@@ /* * use gzip. Non standard option. */ - zflag = 1; gzip_program = GZIP_CMD; break; case 'A': @@@ -1089,11 -1183,14 +1185,14 @@@ paxwarn(1, "Unable to open file '%s' for read", optarg); cpio_usage(); } - while ((str = fgetln(fp, &len)) != NULL) { - str[len - 1] = '\0'; + while ((str = getline(fp)) != NULL) { pat_add(str, NULL); } fclose(fp); + if (getline_error) { + paxwarn(1, "Problem with file '%s'", optarg); + cpio_usage(); + } break; case 'F': case 'I': @@@ -1140,7 -1237,6 +1239,6 @@@ /* * use compress. Non standard option. */ - zflag = 1; gzip_program = COMPRESS_CMD; break; case '6': @@@ -1186,9 -1282,12 +1284,12 @@@ * no read errors allowed on updates/append operation! */ maxflt = 0; - while ((str = fgetln(stdin, &len)) != NULL) { - str[len - 1] = '\0'; - ftree_add(strdup(str), NULL); + while ((str = getline(stdin)) != NULL) { + ftree_add(str, 0); + } + if (getline_error) { + paxwarn(1, "Problem while reading stdin"); + cpio_usage(); } break; default: @@@ -1202,14 -1301,8 +1303,8 @@@ * print out those invalid flag sets found to the user */ - #ifdef __STDC__ static void printflg(unsigned int flg) - #else - static void - printflg(flg) - unsigned int flg; - #endif { int nxt; int pos = 0; @@@ -1229,15 -1322,8 +1324,8 @@@ * by the user */ - #ifdef __STDC__ static int c_frmt(const void *a, const void *b) - #else - static int - c_frmt(a, b) - void *a; - void *b; - #endif { return(strcmp(((FSUB *)a)->name, ((FSUB *)b)->name)); } @@@ -1250,13 -1336,8 +1338,8 @@@ * pointer to next OPLIST entry or NULL (end of list). */ - #ifdef __STDC__ OPLIST * opt_next(void) - #else - OPLIST * - opt_next() - #endif { OPLIST *opt; @@@ -1271,15 -1352,10 +1354,10 @@@ * when the format does not support options. */ - #ifdef __STDC__ int bad_opt(void) - #else - int - bad_opt() - #endif { - register OPLIST *opt; + OPLIST *opt; if (ophead == NULL) return(0); @@@ -1297,34 -1373,29 +1375,29 @@@ * opt_add() * breaks the value supplied to -o into a option name and value. options * are given to -o in the form -o name-value,name=value - * mulltiple -o may be specified. + * multiple -o may be specified. * Return: * 0 if format in name=value format, -1 if -o is passed junk */ - #ifdef __STDC__ int - opt_add(register char *str) - #else - int - opt_add(str) - register char *str; - #endif + opt_add(const char *str) { - register OPLIST *opt; - register char *frpt; - register char *pt; - register char *endpt; + OPLIST *opt; + char *frpt; + char *pt; + char *endpt; + char *dstr; if ((str == NULL) || (*str == '\0')) { paxwarn(0, "Invalid option name"); return(-1); } - if ((str = strdup(str)) == NULL) { + if ((dstr = strdup(str)) == NULL) { paxwarn(0, "Unable to allocate space for option list"); return(-1); } - frpt = endpt = str; + frpt = endpt = dstr; /* * break into name and values pieces and stuff each one into a @@@ -1336,12 -1407,12 +1409,12 @@@ *endpt = '\0'; if ((pt = strchr(frpt, '=')) == NULL) { paxwarn(0, "Invalid options format"); - free(str); + free(dstr); return(-1); } if ((opt = (OPLIST *)malloc(sizeof(OPLIST))) == NULL) { paxwarn(0, "Unable to allocate space for option list"); - free(str); + free(dstr); return(-1); } *pt++ = '\0'; @@@ -1371,25 -1442,19 +1444,19 @@@ * 4) A positive decimal number followed by a m (mult by 512). * 5) A positive decimal number followed by a w (mult by sizeof int) * 6) Two or more positive decimal numbers (with/without k,b or w). - * seperated by x (also * for backwards compatibility), specifying + * separated by x (also * for backwards compatibility), specifying * the product of the indicated values. * Return: * 0 for an error, a positive value o.w. */ - #ifdef __STDC__ static off_t str_offt(char *val) - #else - static off_t - str_offt(val) - char *val; - #endif { char *expr; off_t num, t; - # ifdef NET2_STAT + # ifdef LONG_OFF_T num = strtol(val, &expr, 0); if ((num == LONG_MAX) || (num <= 0) || (expr == val)) # else @@@ -1398,7 -1463,7 +1465,7 @@@ # endif return(0); - switch(*expr) { + switch (*expr) { case 'b': t = num; num *= 512; @@@ -1429,7 -1494,7 +1496,7 @@@ break; } - switch(*expr) { + switch (*expr) { case '\0': break; case '*': @@@ -1445,6 -1510,29 +1512,29 @@@ return(num); } + char * + getline(FILE *f) + { + char *name, *temp; + size_t len; + + name = fgetln(f, &len); + if (!name) { + getline_error = ferror(f) ? GETLINE_FILE_CORRUPT : 0; + return(0); + } + if (name[len-1] != '\n') + len++; + temp = malloc(len); + if (!temp) { + getline_error = GETLINE_OUT_OF_MEM; + return(0); + } + memcpy(temp, name, len-1); + temp[len-1] = 0; + return(temp); + } + /* * no_op() * for those option functions where the archive format has nothing to do. @@@ -1452,13 -1540,8 +1542,8 @@@ * 0 */ - #ifdef __STDC__ static int no_op(void) - #else - static int - no_op() - #endif { return(0); } @@@ -1468,37 -1551,20 +1553,20 @@@ * print the usage summary to the user */ - #ifdef __STDC__ void pax_usage(void) - #else - void - pax_usage() - #endif { - (void)fputs("usage: pax [-cdjnvz] [-E limit] [-f archive] ", stderr); - (void)fputs("[-s replstr] ... [-U user] ...", stderr); - (void)fputs("\n [-G group] ... ", stderr); - (void)fputs("[-T [from_date][,to_date]] ... ", stderr); - (void)fputs("[pattern ...]\n", stderr); - (void)fputs(" pax -r [-cdijknuvzDYZ] [-E limit] ", stderr); - (void)fputs("[-f archive] [-o options] ... \n", stderr); - (void)fputs(" [-p string] ... [-s replstr] ... ", stderr); - (void)fputs("[-U user] ... [-G group] ...\n ", stderr); - (void)fputs("[-T [from_date][,to_date]] ... ", stderr); - (void)fputs(" [pattern ...]\n", stderr); - (void)fputs(" pax -w [-dijtuvzHLPX] [-b blocksize] ", stderr); - (void)fputs("[ [-a] [-f archive] ] [-x format] \n", stderr); - (void)fputs(" [-B bytes] [-s replstr] ... ", stderr); - (void)fputs("[-o options] ... [-U user] ...", stderr); - (void)fputs("\n [-G group] ... ", stderr); - (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr); - (void)fputs("[file ...]\n", stderr); - (void)fputs(" pax -r -w [-diklntuvDHLPXYZ] ", stderr); - (void)fputs("[-p string] ... [-s replstr] ...", stderr); - (void)fputs("\n [-U user] ... [-G group] ... ", stderr); - (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr); - (void)fputs("\n [file ...] directory\n", stderr); + (void)fputs( + "usage: pax [-0cdjnOvz] [-E limit] [-f archive] [-G group] [-s replstr]\n" + " [-T range] [-U user] [pattern ...]\n" + " pax -r [-0cDdijknOuvYZz] [-E limit] [-f archive] [-G group] [-o options]\n" + " [-p string] [-s replstr] [-T range] [-U user] [pattern ...]\n" + " pax -w [-0adHijLOPtuvXz] [-B bytes] [-b blocksize] [-f archive]\n" + " [-G group] [-o options] [-s replstr] [-T range] [-U user]\n" + " [-x format] [file ...]\n" + " pax -rw [-0DdHikLlnOPtuvXYZ] [-G group] [-p string] [-s replstr]\n" + " [-T range] [-U user] [file ...] directory\n", + stderr); exit(1); } @@@ -1507,17 -1573,15 +1575,15 @@@ * print the usage summary to the user */ - #ifdef __STDC__ void tar_usage(void) - #else - void - tar_usage() - #endif { - (void)fputs("usage: tar -{txru}[cevfbjmopswzBHLPXZ014578] [tapefile] ", - stderr); - (void)fputs("[blocksize] [replstr] [-C directory] file1 file2...\n", + (void)fputs( + "usage: tar {crtux}[014578befHhjLmOoPpqsvwXZz]\n" + " [blocking-factor | archive | replstr] [-C directory] [-I file]\n" + " [file ...]\n" + " tar {-crtux} [-014578eHhjLmOoPpqvwXZz] [-b blocking-factor]\n" + " [-C directory] [-f archive] [-I file] [-s replstr] [file ...]\n", stderr); exit(1); } @@@ -1527,18 -1591,15 +1593,15 @@@ * print the usage summary to the user */ - #ifdef __STDC__ void cpio_usage(void) - #else - void - cpio_usage() - #endif { - (void)fputs("usage: cpio -o [-aABcjLvVzZ] [-C bytes] [-H format] [-O archive]\n", stderr); - (void)fputs(" [-F archive] < name-list [> archive]\n", stderr); - (void)fputs(" cpio -i [-bBcdfjmnrsStuvVzZ6] [-C bytes] [-E file] [-H format]\n", stderr); - (void)fputs(" [-I archive] [-F archive] [pattern...] [< archive]\n", stderr); - (void)fputs(" cpio -p [-adlLmuvV] destination-directory < name-list\n", stderr); + (void)fputs( + "usage: cpio -o [-AaBcjLvZz] [-C bytes] [-F archive] [-H format]\n" + " [-O archive] < name-list [> archive]\n" + " cpio -i [-6BbcdfjmrSstuvZz] [-C bytes] [-E file] [-F archive] [-H format]\n" + " [-I archive] [pattern ...] [< archive]\n" + " cpio -p [-adLlmuv] destination-directory < name-list\n", + stderr); exit(1); } diff --combined sel_subs.c index d11b50c,55d3a00..b12c3ed --- a/sel_subs.c +++ b/sel_subs.c @@@ -1,4 -1,4 +1,4 @@@ - /* $OpenBSD: sel_subs.c,v 1.7 1997/08/17 23:05:09 millert Exp $ */ + /* $OpenBSD: sel_subs.c,v 1.18 2004/04/16 22:50:23 deraadt Exp $ */ /* $NetBSD: sel_subs.c,v 1.5 1995/03/21 09:07:42 cgd Exp $ */ /*- @@@ -17,11 -17,7 +17,7 @@@ * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 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. * @@@ -40,31 -36,32 +36,33 @@@ #ifndef lint #if 0 - static char sccsid[] = "@(#)sel_subs.c 8.1 (Berkeley) 5/31/93"; + static const char sccsid[] = "@(#)sel_subs.c 8.1 (Berkeley) 5/31/93"; #else - static char rcsid[] = "$OpenBSD: sel_subs.c,v 1.7 1997/08/17 23:05:09 millert Exp $"; + static const char rcsid[] = "$OpenBSD: sel_subs.c,v 1.18 2004/04/16 22:50:23 deraadt Exp $"; #endif #endif /* not lint */ #include #include +#include #include #include - #include + #include #include + #include #include + #include #include + #include #include - #include #include "pax.h" #include "sel_subs.h" #include "extern.h" - static int str_sec __P((register char *, time_t *)); - static int usr_match __P((register ARCHD *)); - static int grp_match __P((register ARCHD *)); - static int trng_match __P((register ARCHD *)); + static int str_sec(const char *, time_t *); + static int usr_match(ARCHD *); + static int grp_match(ARCHD *); + static int trng_match(ARCHD *); static TIME_RNG *trhead = NULL; /* time range list head */ static TIME_RNG *trtail = NULL; /* time range list tail */ @@@ -77,19 -74,13 +75,13 @@@ static GRPT **grptb = NULL; /* group s /* * sel_chk() - * check if this file matches a specfied uid, gid or time range + * check if this file matches a specified uid, gid or time range * Return: * 0 if this archive member should be processed, 1 if it should be skipped */ - #ifdef __STDC__ int - sel_chk(register ARCHD *arcn) - #else - int - sel_chk(arcn) - register ARCHD *arcn; - #endif + sel_chk(ARCHD *arcn) { if (((usrtb != NULL) && usr_match(arcn)) || ((grptb != NULL) && grp_match(arcn)) || @@@ -102,8 -93,8 +94,8 @@@ * User/group selection routines * * Routines to handle user selection of files based on the file uid/gid. To - * add an entry, the user supplies either then name or the uid/gid starting with - * a # on the command line. A \# will eascape the #. + * add an entry, the user supplies either the name or the uid/gid starting with + * a # on the command line. A \# will escape the #. */ /* @@@ -113,19 -104,13 +105,13 @@@ * 0 if added ok, -1 otherwise; */ - #ifdef __STDC__ int - usr_add(register char *str) - #else - int - usr_add(str) - register char *str; - #endif + usr_add(char *str) { - register u_int indx; - register USRT *pt; - register struct passwd *pw; - register uid_t uid; + u_int indx; + USRT *pt; + struct passwd *pw; + uid_t uid; /* * create the table if it doesn't exist @@@ -153,11 -138,7 +139,7 @@@ } uid = (uid_t)pw->pw_uid; } else - # ifdef NET2_STAT - uid = (uid_t)atoi(str+1); - # else uid = (uid_t)strtoul(str+1, NULL, 10); - # endif endpwent(); /* @@@ -192,16 -173,10 +174,10 @@@ * 0 if this archive member should be processed, 1 if it should be skipped */ - #ifdef __STDC__ static int - usr_match(register ARCHD *arcn) - #else - static int - usr_match(arcn) - register ARCHD *arcn; - #endif + usr_match(ARCHD *arcn) { - register USRT *pt; + USRT *pt; /* * hash and look for it in the table @@@ -226,19 -201,13 +202,13 @@@ * 0 if added ok, -1 otherwise; */ - #ifdef __STDC__ int - grp_add(register char *str) - #else - int - grp_add(str) - register char *str; - #endif + grp_add(char *str) { - register u_int indx; - register GRPT *pt; - register struct group *gr; - register gid_t gid; + u_int indx; + GRPT *pt; + struct group *gr; + gid_t gid; /* * create the table if it doesn't exist @@@ -266,11 -235,7 +236,7 @@@ } gid = (gid_t)gr->gr_gid; } else - # ifdef NET2_STAT - gid = (gid_t)atoi(str+1); - # else gid = (gid_t)strtoul(str+1, NULL, 10); - # endif endgrent(); /* @@@ -305,16 -270,10 +271,10 @@@ * 0 if this archive member should be processed, 1 if it should be skipped */ - #ifdef __STDC__ - static int - grp_match(register ARCHD *arcn) - #else static int - grp_match(arcn) - register ARCHD *arcn; - #endif + grp_match(ARCHD *arcn) { - register GRPT *pt; + GRPT *pt; /* * hash and look for it in the table @@@ -354,27 -313,21 +314,21 @@@ * trng_add() * add a time range match to the time range list. * This is a non-standard pax option. Lower and upper ranges are in the - * format: [yy[mm[dd[hh]]]]mm[.ss] and are comma separated. + * format: [[[[[cc]yy]mm]dd]HH]MM[.SS] and are comma separated. * Time ranges are based on current time, so 1234 would specify a time of * 12:34 today. * Return: * 0 if the time range was added to the list, -1 otherwise */ - #ifdef __STDC__ - int - trng_add(register char *str) - #else int - trng_add(str) - register char *str; - #endif + trng_add(char *str) { - register TIME_RNG *pt; - register char *up_pt = NULL; - register char *stpt; - register char *flgpt; - register int dot = 0; + TIME_RNG *pt; + char *up_pt = NULL; + char *stpt; + char *flgpt; + int dot = 0; /* * throw out the badly formed time ranges @@@ -420,7 -373,7 +374,7 @@@ } /* - * by default we only will check file mtime, but usee can specify + * by default we only will check file mtime, but user can specify * mtime, ctime (inode change time) or both. */ if ((flgpt == NULL) || (*flgpt == '\0')) @@@ -428,7 -381,7 +382,7 @@@ else { pt->flgs = 0; while (*flgpt != '\0') { - switch(*flgpt) { + switch (*flgpt) { case 'M': case 'm': pt->flgs |= CMPMTME; @@@ -496,7 -449,7 +450,7 @@@ return(0); out: - paxwarn(1, "Time range format is: [yy[mm[dd[hh]]]]mm[.ss][/[c][m]]"); + paxwarn(1, "Time range format is: [[[[[cc]yy]mm]dd]HH]MM[.SS][/[c][m]]"); return(-1); } @@@ -507,16 -460,10 +461,10 @@@ * 0 if this archive member should be processed, 1 if it should be skipped */ - #ifdef __STDC__ - static int - trng_match(register ARCHD *arcn) - #else static int - trng_match(arcn) - register ARCHD *arcn; - #endif + trng_match(ARCHD *arcn) { - register TIME_RNG *pt; + TIME_RNG *pt; /* * have to search down the list one at a time looking for a match. @@@ -524,7 -471,7 +472,7 @@@ */ pt = trhead; while (pt != NULL) { - switch(pt->flgs & CMPBOTH) { + switch (pt->flgs & CMPBOTH) { case CMPBOTH: /* * user wants both mtime and ctime checked for this @@@ -576,87 -523,89 +524,89 @@@ /* * str_sec() - * Convert a time string in the format of [yy[mm[dd[hh]]]]mm[.ss] to gmt - * seconds. Tval already has current time loaded into it at entry. + * Convert a time string in the format of [[[[[cc]yy]mm]dd]HH]MM[.SS] to + * seconds UTC. Tval already has current time loaded into it at entry. * Return: * 0 if converted ok, -1 otherwise */ - #ifdef __STDC__ - static int - str_sec(register char *str, time_t *tval) - #else static int - str_sec(str, tval) - register char *str; - time_t *tval; - #endif + str_sec(const char *p, time_t *tval) { - register struct tm *lt; - register char *dot = NULL; + struct tm *lt; + const char *dot, *t; + size_t len; + int bigyear; + int yearset; + + yearset = 0; + len = strlen(p); + + for (t = p, dot = NULL; *t; ++t) { + if (isdigit(*t)) + continue; + if (*t == '.' && dot == NULL) { + dot = t; + continue; + } + return(-1); + } lt = localtime(tval); - if ((dot = strchr(str, '.')) != NULL) { - /* - * seconds (.ss) - */ - *dot++ = '\0'; - if (strlen(dot) != 2) + + if (dot != NULL) { /* .SS */ + if (strlen(++dot) != 2) return(-1); - if ((lt->tm_sec = ATOI2(dot)) > 61) + lt->tm_sec = ATOI2(dot); + if (lt->tm_sec > 61) return(-1); + len -= 3; } else lt->tm_sec = 0; - switch (strlen(str)) { - case 10: - /* - * year (yy) - * watch out for year 2000 - */ - if ((lt->tm_year = ATOI2(str)) < 69) - lt->tm_year += 100; - str += 2; + switch (len) { + case 12: /* cc */ + bigyear = ATOI2(p); + lt->tm_year = (bigyear * 100) - TM_YEAR_BASE; + yearset = 1; /* FALLTHROUGH */ - case 8: - /* - * month (mm) - * watch out months are from 0 - 11 internally - */ - if ((lt->tm_mon = ATOI2(str)) > 12) + case 10: /* yy */ + if (yearset) { + lt->tm_year += ATOI2(p); + } else { + lt->tm_year = ATOI2(p); + if (lt->tm_year < 69) /* hack for 2000 ;-} */ + lt->tm_year += (2000 - TM_YEAR_BASE); + else + lt->tm_year += (1900 - TM_YEAR_BASE); + } + /* FALLTHROUGH */ + case 8: /* mm */ + lt->tm_mon = ATOI2(p); + if ((lt->tm_mon > 12) || !lt->tm_mon) return(-1); - --lt->tm_mon; - str += 2; + --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ - case 6: - /* - * day (dd) - */ - if ((lt->tm_mday = ATOI2(str)) > 31) + case 6: /* dd */ + lt->tm_mday = ATOI2(p); + if ((lt->tm_mday > 31) || !lt->tm_mday) return(-1); - str += 2; /* FALLTHROUGH */ - case 4: - /* - * hour (hh) - */ - if ((lt->tm_hour = ATOI2(str)) > 23) + case 4: /* HH */ + lt->tm_hour = ATOI2(p); + if (lt->tm_hour > 23) return(-1); - str += 2; /* FALLTHROUGH */ - case 2: - /* - * minute (mm) - */ - if ((lt->tm_min = ATOI2(str)) > 59) + case 2: /* MM */ + lt->tm_min = ATOI2(p); + if (lt->tm_min > 59) return(-1); break; default: return(-1); } - /* - * convert broken-down time to GMT clock time seconds - */ + + /* convert broken-down time to UTC clock time seconds */ if ((*tval = mktime(lt)) == -1) return(-1); return(0); diff --combined tar.c index af7f214,6a0b3b3..9763934 --- a/tar.c +++ b/tar.c @@@ -1,4 -1,4 +1,4 @@@ - /* $OpenBSD: tar.c,v 1.13 1998/09/26 21:29:41 millert Exp $ */ + /* $OpenBSD: tar.c,v 1.41 2006/03/04 20:24:55 otto Exp $ */ /* $NetBSD: tar.c,v 1.5 1995/03/21 09:07:49 cgd Exp $ */ /*- @@@ -17,11 -17,7 +17,7 @@@ * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 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. * @@@ -40,14 -36,13 +36,14 @@@ #ifndef lint #if 0 - static char sccsid[] = "@(#)tar.c 8.2 (Berkeley) 4/18/94"; + static const char sccsid[] = "@(#)tar.c 8.2 (Berkeley) 4/18/94"; #else - static char rcsid[] = "$OpenBSD: tar.c,v 1.13 1998/09/26 21:29:41 millert Exp $"; + static const char rcsid[] = "$OpenBSD: tar.c,v 1.41 2006/03/04 20:24:55 otto Exp $"; #endif #endif /* not lint */ #include +#include #include #include #include @@@ -63,18 -58,26 +59,26 @@@ * Routines for reading, writing and header identify of various versions of tar */ - static u_long tar_chksm __P((register char *, register int)); - static char *name_split __P((register char *, register int)); - static int ul_oct __P((u_long, register char *, register int, int)); - #ifndef NET2_STAT - static int uqd_oct __P((u_quad_t, register char *, register int, int)); + 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); + #ifndef LONG_OFF_T + static int uqd_oct(u_quad_t, char *, int, int); #endif + static uid_t uid_nobody; + static uid_t uid_warn; + static gid_t gid_nobody; + static gid_t gid_warn; + /* * Routines common to all versions of tar */ static int tar_nodir; /* do not write dirs under old tar */ + char *gnu_name_string; /* GNU ././@LongLink hackery name */ + char *gnu_link_string; /* GNU ././@LongLink hackery link */ /* * tar_endwr() @@@ -83,13 -86,8 +87,8 @@@ * 0 if ok, -1 otherwise (what wr_skip returns) */ - #ifdef __STDC__ int tar_endwr(void) - #else - int - tar_endwr() - #endif { return(wr_skip((off_t)(NULLCNT*BLKMULT))); } @@@ -101,13 -99,8 +100,8 @@@ * size of trailer (2 * BLKMULT) */ - #ifdef __STDC__ off_t tar_endrd(void) - #else - off_t - tar_endrd() - #endif { return((off_t)(NULLCNT*BLKMULT)); } @@@ -123,18 -116,10 +117,10 @@@ * could never contain a header. */ - #ifdef __STDC__ - int - tar_trail(register char *buf, register int in_resync, register int *cnt) - #else int - tar_trail(buf, in_resync, cnt) - register char *buf; - register int in_resync; - register int *cnt; - #endif + tar_trail(ARCHD *ignore, char *buf, int in_resync, int *cnt) { - register int i; + int i; /* * look for all zero, trailer is two consecutive blocks of zero @@@ -174,25 -159,16 +160,16 @@@ * 0 if the number fit into the string, -1 otherwise */ - #ifdef __STDC__ - static int - ul_oct(u_long val, register char *str, register int len, int term) - #else static int - ul_oct(val, str, len, term) - u_long val; - register char *str; - register int len; - int term; - #endif + ul_oct(u_long val, char *str, int len, int term) { - register char *pt; + char *pt; /* * term selects the appropriate character(s) for the end of the string */ pt = str + len - 1; - switch(term) { + switch (term) { case 3: *pt-- = '\0'; break; @@@ -226,7 -202,7 +203,7 @@@ return(0); } - #ifndef NET2_STAT + #ifndef LONG_OFF_T /* * uqd_oct() * convert an u_quad_t to an octal string. one of many oddball field @@@ -238,25 -214,16 +215,16 @@@ * 0 if the number fit into the string, -1 otherwise */ - #ifdef __STDC__ - static int - uqd_oct(u_quad_t val, register char *str, register int len, int term) - #else static int - uqd_oct(val, str, len, term) - u_quad_t val; - register char *str; - register int len; - int term; - #endif + uqd_oct(u_quad_t val, char *str, int len, int term) { - register char *pt; + char *pt; /* * term selects the appropriate character(s) for the end of the string */ pt = str + len - 1; - switch(term) { + switch (term) { case 3: *pt-- = '\0'; break; @@@ -294,26 -261,19 +262,19 @@@ /* * tar_chksm() * calculate the checksum for a tar block counting the checksum field as - * all blanks (BLNKSUM is that value pre-calculated, the sume of 8 blanks). + * all blanks (BLNKSUM is that value pre-calculated, the sum of 8 blanks). * NOTE: we use len to short circuit summing 0's on write since we ALWAYS * pad headers with 0. * Return: * unsigned long checksum */ - #ifdef __STDC__ static u_long - tar_chksm(register char *blk, register int len) - #else - static u_long - tar_chksm(blk, len) - register char *blk; - register int len; - #endif + tar_chksm(char *blk, int len) { - register char *stop; - register char *pt; - u_long chksm = BLNKSUM; /* inital value is checksum field sum */ + char *stop; + char *pt; + u_long chksm = BLNKSUM; /* initial value is checksum field sum */ /* * add the part of the block before the checksum field @@@ -349,18 -309,11 +310,11 @@@ * 0 if a tar header, -1 otherwise */ - #ifdef __STDC__ int - tar_id(register char *blk, int size) - #else - int - tar_id(blk, size) - register char *blk; - int size; - #endif + tar_id(char *blk, int size) { - register HD_TAR *hd; - register HD_USTAR *uhd; + HD_TAR *hd; + HD_USTAR *uhd; if (size < BLKMULT) return(-1); @@@ -380,6 -333,7 +334,7 @@@ return(-1); if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT)) return(-1); + force_one_volume = 1; return(0); } @@@ -390,13 -344,8 +345,8 @@@ * 0 if ok -1 otherwise */ - #ifdef __STDC__ int tar_opt(void) - #else - int - tar_opt() - #endif { OPLIST *opt; @@@ -432,39 -381,40 +382,40 @@@ * 0 */ - #ifdef __STDC__ int - tar_rd(register ARCHD *arcn, register char *buf) - #else - int - tar_rd(arcn, buf) - register ARCHD *arcn; - register char *buf; - #endif + tar_rd(ARCHD *arcn, char *buf) { - register HD_TAR *hd; - register char *pt; + HD_TAR *hd; + char *pt; /* * we only get proper sized buffers passed to us */ if (tar_id(buf, BLKMULT) < 0) return(-1); + memset(arcn, 0, sizeof(*arcn)); arcn->org_name = arcn->name; arcn->sb.st_nlink = 1; - arcn->pat = NULL; /* * copy out the name and values in the stat buffer */ hd = (HD_TAR *)buf; - arcn->nlen = l_strncpy(arcn->name, hd->name, sizeof(arcn->name) - 1); - arcn->name[arcn->nlen] = '\0'; + if (hd->linkflag != LONGLINKTYPE && hd->linkflag != LONGNAMETYPE) { + arcn->nlen = expandname(arcn->name, sizeof(arcn->name), + &gnu_name_string, hd->name, sizeof(hd->name)); + arcn->ln_nlen = expandname(arcn->ln_name, sizeof(arcn->ln_name), + &gnu_link_string, hd->linkname, sizeof(hd->linkname)); + } arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode,sizeof(hd->mode),OCT) & 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 = (size_t)asc_ul(hd->size, sizeof(hd->size), OCT); + #ifdef LONG_OFF_T + arcn->sb.st_size = (off_t)asc_ul(hd->size, sizeof(hd->size), OCT); + #else + arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT); + #endif arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT); arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; @@@ -475,16 -425,13 +426,13 @@@ pt = &(arcn->name[arcn->nlen - 1]); arcn->pad = 0; arcn->skip = 0; - switch(hd->linkflag) { + switch (hd->linkflag) { case SYMTYPE: /* * symbolic link, need to get the link name and set the type in * the st_mode so -v printing will look correct. */ arcn->type = PAX_SLK; - arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname, - sizeof(arcn->ln_name) - 1); - arcn->ln_name[arcn->ln_nlen] = '\0'; arcn->sb.st_mode |= S_IFLNK; break; case LNKTYPE: @@@ -494,9 -441,6 +442,6 @@@ */ arcn->type = PAX_HLK; arcn->sb.st_nlink = 2; - arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname, - sizeof(arcn->ln_name) - 1); - arcn->ln_name[arcn->ln_nlen] = '\0'; /* * no idea of what type this thing really points at, but @@@ -504,6 -448,17 +449,17 @@@ */ arcn->sb.st_mode |= S_IFREG; break; + case LONGLINKTYPE: + case LONGNAMETYPE: + /* + * GNU long link/file; we tag these here and let the + * pax internals deal with it -- too ugly otherwise. + */ + arcn->type = + hd->linkflag == LONGLINKTYPE ? PAX_GLL : PAX_GLF; + arcn->pad = TAR_PAD(arcn->sb.st_size); + arcn->skip = arcn->sb.st_size; + break; case DIRTYPE: /* * It is a directory, set the mode for -v printing @@@ -511,8 -466,6 +467,6 @@@ arcn->type = PAX_DIR; arcn->sb.st_mode |= S_IFDIR; arcn->sb.st_nlink = 2; - arcn->ln_name[0] = '\0'; - arcn->ln_nlen = 0; break; case AREGTYPE: case REGTYPE: @@@ -532,7 -485,7 +486,7 @@@ } else { /* * have a file that will be followed by data. Set the - * skip value to the size field and caluculate the size + * skip value to the size field and calculate the size * of the padding. */ arcn->type = PAX_REG; @@@ -547,7 -500,7 +501,7 @@@ * strip off any trailing slash. */ if (*pt == '/') { - *pt = '\0'; + *pt = '\0'; --arcn->nlen; } return(0); @@@ -565,23 -518,17 +519,17 @@@ * data to write after the header, -1 if archive write failed */ - #ifdef __STDC__ int - tar_wr(register ARCHD *arcn) - #else - int - tar_wr(arcn) - register ARCHD *arcn; - #endif + tar_wr(ARCHD *arcn) { - register HD_TAR *hd; + HD_TAR *hd; int len; char hdblk[sizeof(HD_TAR)]; /* * check for those file system types which tar cannot store */ - switch(arcn->type) { + switch (arcn->type) { case PAX_DIR: /* * user asked that dirs not be written to the archive @@@ -606,7 -553,8 +554,8 @@@ case PAX_HLK: case PAX_HRG: if (arcn->ln_nlen > sizeof(hd->linkname)) { - paxwarn(1,"Link name too long for tar %s", arcn->ln_name); + paxwarn(1, "Link name too long for tar %s", + arcn->ln_name); return(1); } break; @@@ -622,32 -570,31 +571,31 @@@ len = arcn->nlen; if (arcn->type == PAX_DIR) ++len; - if (len >= sizeof(hd->name)) { + if (len > sizeof(hd->name)) { paxwarn(1, "File name too long for tar %s", arcn->name); return(1); } /* - * copy the data out of the ARCHD into the tar header based on the type - * of the file. Remember many tar readers want the unused fields to be - * padded with zero. We set the linkflag field (type), the linkname - * (or zero if not used),the size, and set the padding (if any) to be - * added after the file data (0 for all other types, as they only have - * a header) + * Copy the data out of the ARCHD into the tar header based on the type + * of the file. Remember, many tar readers want all fields to be + * padded with zero so we zero the header first. We then set the + * linkflag field (type), the linkname, the size, and set the padding + * (if any) to be added after the file data (0 for all other types, + * as they only have a header). */ + memset(hdblk, 0, sizeof(hdblk)); hd = (HD_TAR *)hdblk; - l_strncpy(hd->name, arcn->name, sizeof(hd->name) - 1); - hd->name[sizeof(hd->name) - 1] = '\0'; + fieldcpy(hd->name, sizeof(hd->name), arcn->name, sizeof(arcn->name)); arcn->pad = 0; if (arcn->type == PAX_DIR) { /* * directories are the same as files, except have a filename - * that ends with a /, we add the slash here. No data follows, + * that ends with a /, we add the slash here. No data follows * dirs, so no pad. */ hd->linkflag = AREGTYPE; - memset(hd->linkname, 0, sizeof(hd->linkname)); hd->name[len-1] = '/'; if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1)) goto out; @@@ -656,8 -603,8 +604,8 @@@ * no data follows this file, so no pad */ hd->linkflag = SYMTYPE; - l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1); - hd->linkname[sizeof(hd->linkname) - 1] = '\0'; + 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)) goto out; } else if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) { @@@ -665,8 -612,8 +613,8 @@@ * no data follows this file, so no pad */ hd->linkflag = LNKTYPE; - l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1); - hd->linkname[sizeof(hd->linkname) - 1] = '\0'; + 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)) goto out; } else { @@@ -674,8 -621,7 +622,7 @@@ * data follows this file, so set the pad */ hd->linkflag = AREGTYPE; - memset(hd->linkname, 0, sizeof(hd->linkname)); - # ifdef NET2_STAT + # ifdef LONG_OFF_T if (ul_oct((u_long)arcn->sb.st_size, hd->size, sizeof(hd->size), 1)) { # else @@@ -694,7 -640,7 +641,7 @@@ if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 0) || 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((u_long)arcn->sb.st_mtime, hd->mtime, sizeof(hd->mtime), 1)) + ul_oct((u_long)(u_int)arcn->sb.st_mtime, hd->mtime, sizeof(hd->mtime), 1)) goto out; /* @@@ -732,13 -678,8 +679,8 @@@ * 0 if ok, -1 otherwise */ - #ifdef __STDC__ int ustar_strd(void) - #else - int - ustar_strd() - #endif { if ((usrtb_start() < 0) || (grptb_start() < 0)) return(-1); @@@ -752,13 -693,8 +694,8 @@@ * 0 if ok, -1 otherwise */ - #ifdef __STDC__ int ustar_stwr(void) - #else - int - ustar_stwr() - #endif { if ((uidtb_start() < 0) || (gidtb_start() < 0)) return(-1); @@@ -773,17 -709,10 +710,10 @@@ * 0 if a ustar header, -1 otherwise */ - #ifdef __STDC__ int ustar_id(char *blk, int size) - #else - int - ustar_id(blk, size) - char *blk; - int size; - #endif { - register HD_USTAR *hd; + HD_USTAR *hd; if (size < BLKMULT) return(-1); @@@ -795,7 -724,7 +725,7 @@@ * programs are fouled up and create archives missing the \0. Last we * check the checksum. If ok we have to assume it is a valid header. */ - if (hd->name[0] == '\0') + if (hd->prefix[0] == '\0' && hd->name[0] == '\0') return(-1); if (strncmp(hd->magic, TMAGIC, TMAGLEN - 1) != 0) return(-1); @@@ -812,19 -741,12 +742,12 @@@ * 0 */ - #ifdef __STDC__ int - ustar_rd(register ARCHD *arcn, register char *buf) - #else - int - ustar_rd(arcn, buf) - register ARCHD *arcn; - register char *buf; - #endif + ustar_rd(ARCHD *arcn, char *buf) { - register HD_USTAR *hd; - register char *dest; - register int cnt = 0; + HD_USTAR *hd; + char *dest; + int cnt = 0; dev_t devmajor; dev_t devminor; @@@ -833,31 -755,32 +756,38 @@@ */ if (ustar_id(buf, BLKMULT) < 0) return(-1); + memset(arcn, 0, sizeof(*arcn)); arcn->org_name = arcn->name; arcn->sb.st_nlink = 1; - arcn->pat = NULL; - arcn->nlen = 0; hd = (HD_USTAR *)buf; /* * see if the filename is split into two parts. if, so joint the parts. * we copy the prefix first and add a / between the prefix and name. + * + * the length passed to l_strncpy must be the length of the field + * being copied *from*, since these fields are NOT null terminated + * when full. the destination buffer is plenty big enough to hold + * the longest supported ustar path length, so there's no need + * to check against that. */ dest = arcn->name; if (*(hd->prefix) != '\0') { - cnt = l_strncpy(dest, hd->prefix, sizeof(hd->prefix)); + cnt = fieldcpy(dest, sizeof(arcn->name) - 1, hd->prefix, + sizeof(hd->prefix)); dest += cnt; *dest++ = '/'; cnt++; + } else { + cnt = 0; + } + + if (hd->typeflag != LONGLINKTYPE && hd->typeflag != LONGNAMETYPE) { + arcn->nlen = cnt + expandname(dest, sizeof(arcn->name) - cnt, + &gnu_name_string, hd->name, sizeof(hd->name)); + arcn->ln_nlen = expandname(arcn->ln_name, sizeof(arcn->ln_name), + &gnu_link_string, hd->linkname, sizeof(hd->linkname)); } - arcn->nlen = cnt + l_strncpy(dest, hd->name, sizeof(hd->name)); - arcn->name[arcn->nlen] = '\0'; /* * follow the spec to the letter. we should only have mode bits, strip @@@ -865,7 -788,11 +795,11 @@@ */ arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode, sizeof(hd->mode), OCT) & 0xfff); - arcn->sb.st_size = (size_t)asc_ul(hd->size, sizeof(hd->size), OCT); + #ifdef LONG_OFF_T + arcn->sb.st_size = (off_t)asc_ul(hd->size, sizeof(hd->size), OCT); + #else + arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT); + #endif arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT); arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; @@@ -885,8 -812,6 +819,6 @@@ /* * set the defaults, these may be changed depending on the file type */ - arcn->ln_name[0] = '\0'; - arcn->ln_nlen = 0; arcn->pad = 0; arcn->skip = 0; arcn->sb.st_rdev = (dev_t)0; @@@ -894,7 -819,7 +826,7 @@@ /* * set the mode and PAX type according to the typeflag in the header */ - switch(hd->typeflag) { + switch (hd->typeflag) { case FIFOTYPE: arcn->type = PAX_FIF; arcn->sb.st_mode |= S_IFIFO; @@@ -941,15 -866,17 +873,17 @@@ arcn->sb.st_mode |= S_IFREG; arcn->sb.st_nlink = 2; } + break; + case LONGLINKTYPE: + case LONGNAMETYPE: /* - * copy the link name - * - * see comment above (for hd->name) regarding the length - * passed to l_strncpy + * GNU long link/file; we tag these here and let the + * pax internals deal with it -- too ugly otherwise. */ - arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname, - sizeof(hd->linkname)); - arcn->ln_name[arcn->ln_nlen] = '\0'; + arcn->type = + hd->typeflag == LONGLINKTYPE ? PAX_GLL : PAX_GLF; + arcn->pad = TAR_PAD(arcn->sb.st_size); + arcn->skip = arcn->sb.st_size; break; case CONTTYPE: case AREGTYPE: @@@ -980,17 -907,11 +914,11 @@@ * data to write after the header, -1 if archive write failed */ - #ifdef __STDC__ int - ustar_wr(register ARCHD *arcn) - #else - int - ustar_wr(arcn) - register ARCHD *arcn; - #endif + ustar_wr(ARCHD *arcn) { - register HD_USTAR *hd; - register char *pt; + HD_USTAR *hd; + char *pt; char hdblk[sizeof(HD_USTAR)]; /* @@@ -1018,6 -939,11 +946,11 @@@ paxwarn(1, "File name too long for ustar %s", arcn->name); return(1); } + + /* + * zero out the header so we don't have to worry about zero fill below + */ + memset(hdblk, 0, sizeof(hdblk)); hd = (HD_USTAR *)hdblk; arcn->pad = 0L; @@@ -1030,28 -956,24 +963,24 @@@ * occur, we remove the / and copy the first part to the prefix */ *pt = '\0'; - l_strncpy(hd->prefix, arcn->name, sizeof(hd->prefix)); + fieldcpy(hd->prefix, sizeof(hd->prefix), arcn->name, + sizeof(arcn->name)); *pt++ = '/'; - } else - memset(hd->prefix, 0, sizeof(hd->prefix)); + } /* * copy the name part. this may be the whole path or the part after * the prefix */ - l_strncpy(hd->name, pt, sizeof(hd->name)); + fieldcpy(hd->name, sizeof(hd->name), pt, + sizeof(arcn->name) - (pt - arcn->name)); /* * set the fields in the header that are type dependent */ - switch(arcn->type) { + switch (arcn->type) { case PAX_DIR: hd->typeflag = DIRTYPE; - memset(hd->linkname, 0, sizeof(hd->linkname)); - memset(hd->devmajor, 0, sizeof(hd->devmajor)); - hd->devmajor[0] = '0'; - memset(hd->devminor, 0, sizeof(hd->devminor)); - hd->devminor[0] = '0'; if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) goto out; break; @@@ -1061,7 -983,6 +990,6 @@@ hd->typeflag = CHRTYPE; else hd->typeflag = BLKTYPE; - memset(hd->linkname, 0, sizeof(hd->linkname)); if (ul_oct((u_long)MAJOR(arcn->sb.st_rdev), hd->devmajor, sizeof(hd->devmajor), 3) || ul_oct((u_long)MINOR(arcn->sb.st_rdev), hd->devminor, @@@ -1071,11 -992,6 +999,6 @@@ break; case PAX_FIF: hd->typeflag = FIFOTYPE; - memset(hd->linkname, 0, sizeof(hd->linkname)); - memset(hd->devmajor, 0, sizeof(hd->devmajor)); - hd->devmajor[0] = '0'; - memset(hd->devminor, 0, sizeof(hd->devminor)); - hd->devminor[0] = '0'; if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) goto out; break; @@@ -1086,11 -1002,8 +1009,8 @@@ hd->typeflag = SYMTYPE; else hd->typeflag = LNKTYPE; - l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname)); - memset(hd->devmajor, 0, sizeof(hd->devmajor)); - hd->devmajor[0] = '0'; - memset(hd->devminor, 0, sizeof(hd->devminor)); - hd->devminor[0] = '0'; + 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)) goto out; break; @@@ -1104,13 -1017,8 +1024,8 @@@ hd->typeflag = CONTTYPE; else hd->typeflag = REGTYPE; - memset(hd->linkname, 0, sizeof(hd->linkname)); - memset(hd->devmajor, 0, sizeof(hd->devmajor)); - hd->devmajor[0] = '0'; - memset(hd->devminor, 0, sizeof(hd->devminor)); - hd->devminor[0] = '0'; arcn->pad = TAR_PAD(arcn->sb.st_size); - # ifdef NET2_STAT + # ifdef LONG_OFF_T if (ul_oct((u_long)arcn->sb.st_size, hd->size, sizeof(hd->size), 3)) { # else @@@ -1123,20 -1031,46 +1038,46 @@@ break; } - l_strncpy(hd->magic, TMAGIC, TMAGLEN); - l_strncpy(hd->version, TVERSION, TVERSLEN); + strncpy(hd->magic, TMAGIC, TMAGLEN); + strncpy(hd->version, TVERSION, TVERSLEN); /* * 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 (uid_nobody == 0) { + if (uid_name("nobody", &uid_nobody) == -1) + goto out; + } + if (uid_warn != arcn->sb.st_uid) { + uid_warn = arcn->sb.st_uid; + paxwarn(1, + "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)) + goto out; + } + if (ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3)) { + if (gid_nobody == 0) { + if (gid_name("nobody", &gid_nobody) == -1) + goto out; + } + if (gid_warn != arcn->sb.st_gid) { + gid_warn = arcn->sb.st_gid; + paxwarn(1, + "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)) + goto out; + } if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 3) || - ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 3) || - ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3) || - ul_oct((u_long)arcn->sb.st_mtime,hd->mtime,sizeof(hd->mtime),3)) + ul_oct((u_long)(u_int)arcn->sb.st_mtime,hd->mtime,sizeof(hd->mtime),3)) goto out; - l_strncpy(hd->uname,name_uid(arcn->sb.st_uid, 0),sizeof(hd->uname)); - l_strncpy(hd->gname,name_gid(arcn->sb.st_gid, 0),sizeof(hd->gname)); + 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)); /* * calculate and store the checksum write the header to the archive @@@ -1155,7 -1089,7 +1096,7 @@@ return(1); out: - /* + /* * header field is out of range */ paxwarn(1, "Ustar header field is too small for %s", arcn->org_name); @@@ -1174,21 -1108,16 +1115,16 @@@ * the file name is too long */ - #ifdef __STDC__ - static char * - name_split(register char *name, register int len) - #else static char * - name_split(name, len) - register char *name; - register int len; - #endif + name_split(char *name, int len) { - register char *start; + char *start; /* * check to see if the file name is small enough to fit in the name * field. if so just return a pointer to the name. + * The strings can fill the complete name and prefix fields + * without a NUL terminator. */ if (len <= TNMSZ) return(name); @@@ -1197,7 -1126,7 +1133,7 @@@ /* * we start looking at the biggest sized piece that fits in the name - * field. We walk foward looking for a slash to split at. The idea is + * field. We walk forward looking for a slash to split at. The idea is * to find the biggest piece to fit in the name field (or the smallest * prefix we can find) (the -1 is correct the biggest piece would * include the slash between the two parts that gets thrown away) @@@ -1228,3 -1157,20 +1164,20 @@@ */ return(start); } + + static size_t + expandname(char *buf, size_t len, char **gnu_name, const char *name, + size_t limit) + { + size_t nlen; + + if (*gnu_name) { + /* *gnu_name is NUL terminated */ + if ((nlen = strlcpy(buf, *gnu_name, len)) >= len) + nlen = len - 1; + free(*gnu_name); + *gnu_name = NULL; + } else + nlen = fieldcpy(buf, len, name, limit); + return(nlen); + }