merge OpenBSD changes:
- correct -C processing - add ability to read filenames and flags from a file - don't print dangerous escape sequences to the terminal - use strlcpy/strncpy properly. - handle tmpfile creation better. - improve documentation of options. - handle stdout/stderr list selection correctly. - kill gzip when we get interrupted. - simplify gzip setup. - add more flags to programs. additional changes: - librmt processing. - set POSIXLY_CORRECT in options parsing. - prevent more string overruns. - support -T we don't turn the switch on to replace tar and cpio yet.
This commit is contained in:
parent
b73dcc21ce
commit
0c61202168
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.19 2002/08/19 09:56:01 lukem Exp $
|
||||
# $NetBSD: Makefile,v 1.20 2002/10/12 15:39:29 christos Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
|
||||
# To install on versions prior to BSD 4.4 the following may have to be
|
||||
|
@ -52,8 +52,8 @@ CPPFLAGS+= -I${NETBSDSRCDIR}/usr.sbin/mtree \
|
|||
NOHTML=doc2html-error
|
||||
|
||||
.ifndef HOSTPROG
|
||||
LDADD+= -lutil
|
||||
DPADD+= ${LIBUTIL}
|
||||
LDADD+= -lutil -lrmt
|
||||
DPADD+= ${LIBUTIL} ${LIBRMT}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
.endif
|
||||
|
|
268
bin/pax/ar_io.c
268
bin/pax/ar_io.c
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ar_io.c,v 1.22 2002/01/31 19:27:53 tv Exp $ */
|
||||
/* $NetBSD: ar_io.c,v 1.23 2002/10/12 15:39:29 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)ar_io.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: ar_io.c,v 1.22 2002/01/31 19:27:53 tv Exp $");
|
||||
__RCSID("$NetBSD: ar_io.c,v 1.23 2002/10/12 15:39:29 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -52,6 +52,7 @@ __RCSID("$NetBSD: ar_io.c,v 1.22 2002/01/31 19:27:53 tv Exp $");
|
|||
#include <sys/ioctl.h>
|
||||
#include <sys/mtio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -60,7 +61,10 @@ __RCSID("$NetBSD: ar_io.c,v 1.22 2002/01/31 19:27:53 tv Exp $");
|
|||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#define __RMTLIB_PRIVATE
|
||||
#include <rmt.h>
|
||||
#include "pax.h"
|
||||
#include "options.h"
|
||||
#include "extern.h"
|
||||
|
||||
/*
|
||||
|
@ -86,16 +90,22 @@ static int wr_trail = 1; /* trailer was rewritten in append */
|
|||
static int can_unlnk = 0; /* do we unlink null archives? */
|
||||
const char *arcname; /* printable name of archive */
|
||||
const char *gzip_program; /* name of gzip program */
|
||||
static pid_t zpid = -1; /* pid of child process */
|
||||
time_t starttime; /* time the run started */
|
||||
int minusCfd = -1; /* active -C directory */
|
||||
int curdirfd = -1; /* original current directory */
|
||||
int force_one_volume; /* 1 if we ignore volume changes */
|
||||
|
||||
static int get_phys(void);
|
||||
extern sigset_t s_mask;
|
||||
static void ar_start_gzip(int);
|
||||
static void ar_start_gzip(int, const char *, int);
|
||||
static const char *timefmt(char *, size_t, off_t, time_t);
|
||||
static const char *sizefmt(char *, size_t, off_t);
|
||||
#ifdef SYS_NO_RESTART
|
||||
static int rmtread_with_restart(int, void *, int);
|
||||
static int rmtwrite_with_restart(int, void *, int);
|
||||
#else
|
||||
#define rmtread_with_restart(a, b, c) rmtread((a), (b), (c))
|
||||
#define rmtwrite_with_restart(a, b, c) rmtwrite((a), (b), (c))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ar_open()
|
||||
|
@ -111,12 +121,6 @@ ar_open(const char *name)
|
|||
{
|
||||
struct mtget mb;
|
||||
|
||||
/*
|
||||
* change back to the current directory (for now).
|
||||
*/
|
||||
if (curdirfd != -1)
|
||||
fchdir(curdirfd);
|
||||
|
||||
if (arfd != -1)
|
||||
(void)close(arfd);
|
||||
arfd = -1;
|
||||
|
@ -124,6 +128,17 @@ ar_open(const char *name)
|
|||
artyp = ISREG;
|
||||
flcnt = 0;
|
||||
|
||||
if (strchr(name, ':') != NULL && !forcelocal) {
|
||||
artyp = ISRMT;
|
||||
if ((arfd = rmtopen(name, O_RDWR, DMOD)) == -1) {
|
||||
syswarn(0, errno, "Failed open on %s", name);
|
||||
return -1;
|
||||
}
|
||||
blksz = rdblksz = 8192;
|
||||
lstrval = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* open based on overall operation mode
|
||||
*/
|
||||
|
@ -135,8 +150,8 @@ ar_open(const char *name)
|
|||
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);
|
||||
if (arfd != -1 && gzip_program != NULL)
|
||||
ar_start_gzip(arfd, gzip_program, 0);
|
||||
break;
|
||||
case ARCHIVE:
|
||||
if (name == NULL) {
|
||||
|
@ -146,12 +161,10 @@ ar_open(const char *name)
|
|||
syswarn(0, 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 gzip while appending");
|
||||
if (name == NULL) {
|
||||
arfd = STDOUT_FILENO;
|
||||
arcname = STDO;
|
||||
|
@ -170,6 +183,9 @@ ar_open(const char *name)
|
|||
if (arfd < 0)
|
||||
return(-1);
|
||||
|
||||
if (chdname != NULL)
|
||||
if (chdir(chdname) != 0)
|
||||
syswarn(1, errno, "Failed chdir to %s", chdname);
|
||||
/*
|
||||
* set up is based on device type
|
||||
*/
|
||||
|
@ -205,12 +221,6 @@ ar_open(const char *name)
|
|||
if (artyp != ISREG)
|
||||
can_unlnk = 0;
|
||||
|
||||
/*
|
||||
* change directory if necessary
|
||||
*/
|
||||
if (minusCfd != -1)
|
||||
fchdir(minusCfd);
|
||||
|
||||
/*
|
||||
* if we are writing, we are done
|
||||
*/
|
||||
|
@ -320,17 +330,11 @@ ar_open(const char *name)
|
|||
void
|
||||
ar_close(void)
|
||||
{
|
||||
FILE *outf;
|
||||
|
||||
if (arfd < 0) {
|
||||
did_io = io_ok = flcnt = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (act == LIST)
|
||||
outf = stdout;
|
||||
else
|
||||
outf = stderr;
|
||||
|
||||
/*
|
||||
* Close archive file. This may take a LONG while on tapes (we may be
|
||||
|
@ -340,11 +344,11 @@ ar_close(void)
|
|||
*/
|
||||
if (vflag && (artyp == ISTAPE)) {
|
||||
if (vfpart)
|
||||
(void)putc('\n', outf);
|
||||
(void)fprintf(outf,
|
||||
(void)putc('\n', listf);
|
||||
(void)fprintf(listf,
|
||||
"%s: Waiting for tape drive close to complete...",
|
||||
argv0);
|
||||
(void)fflush(outf);
|
||||
(void)fflush(listf);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -357,12 +361,25 @@ ar_close(void)
|
|||
can_unlnk = 0;
|
||||
}
|
||||
|
||||
(void)close(arfd);
|
||||
/*
|
||||
* for a quick extract/list, pax frequently exits before the child
|
||||
* process is done
|
||||
*/
|
||||
if ((act == LIST || act == EXTRACT) && nflag && zpid > 0) {
|
||||
int status;
|
||||
kill(zpid, SIGINT);
|
||||
waitpid(zpid, &status, 0);
|
||||
}
|
||||
|
||||
if (artyp == ISRMT)
|
||||
(void)rmtclose(arfd);
|
||||
else
|
||||
(void)close(arfd);
|
||||
|
||||
if (vflag && (artyp == ISTAPE)) {
|
||||
(void)fputs("done.\n", outf);
|
||||
(void)fputs("done.\n", listf);
|
||||
vfpart = 0;
|
||||
(void)fflush(outf);
|
||||
(void)fflush(listf);
|
||||
}
|
||||
arfd = -1;
|
||||
|
||||
|
@ -388,13 +405,35 @@ ar_close(void)
|
|||
* Print out a summary of I/O for this archive volume.
|
||||
*/
|
||||
if (vfpart) {
|
||||
(void)putc('\n', outf);
|
||||
(void)putc('\n', listf);
|
||||
vfpart = 0;
|
||||
}
|
||||
/*
|
||||
* If we have not determined the format yet, we just say how many bytes
|
||||
* we have skipped over looking for a header to id. there is no way we
|
||||
* could have written anything yet.
|
||||
*/
|
||||
if (frmt == NULL) {
|
||||
(void)fprintf(listf, "%s: unknown format, " OFFT_F
|
||||
" bytes skipped.\n", argv0, rdcnt);
|
||||
(void)fflush(listf);
|
||||
flcnt = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(NM_CPIO, argv0) == 0) {
|
||||
(void)fprintf(listf, OFFT_F " blocks\n",
|
||||
(rdcnt ? rdcnt : wrcnt) / 5120);
|
||||
} else if (strcmp(NM_TAR, argv0) != 0) {
|
||||
(void)fprintf(listf,
|
||||
"%s: %s vol %d, %lu files, " OFFT_F " bytes read, "
|
||||
OFFT_F " bytes written.\n",
|
||||
argv0, frmt->name, arvol-1, flcnt, rdcnt, wrcnt);
|
||||
}
|
||||
|
||||
ar_summary(0);
|
||||
|
||||
(void)fflush(outf);
|
||||
(void)fflush(listf);
|
||||
flcnt = 0;
|
||||
}
|
||||
|
||||
|
@ -422,8 +461,13 @@ ar_drain(void)
|
|||
/*
|
||||
* keep reading until pipe is drained
|
||||
*/
|
||||
while ((res = read_with_restart(arfd, drbuf, sizeof(drbuf))) > 0)
|
||||
;
|
||||
if (artyp == ISRMT) {
|
||||
while ((res = rmtread_with_restart(arfd, drbuf, sizeof(drbuf))) > 0)
|
||||
continue;
|
||||
} else {
|
||||
while ((res = read_with_restart(arfd, drbuf, sizeof(drbuf))) > 0)
|
||||
continue;
|
||||
}
|
||||
lstrval = res;
|
||||
}
|
||||
|
||||
|
@ -507,7 +551,25 @@ read_with_restart(int fd, void *buf, int bsz)
|
|||
int r;
|
||||
|
||||
while (((r = read(fd, buf, bsz)) < 0) && errno == EINTR)
|
||||
;
|
||||
continue;
|
||||
|
||||
return(r);
|
||||
}
|
||||
|
||||
/*
|
||||
* rmtread_with_restart()
|
||||
* Equivalent to rmtread() but does retry on signals.
|
||||
* This function is not needed on 4.2BSD and later.
|
||||
* Return:
|
||||
* Number of bytes written. -1 indicates an error.
|
||||
*/
|
||||
static int
|
||||
rmtread_with_restart(int fd, void *buf, int bsz)
|
||||
{
|
||||
int r;
|
||||
|
||||
while (((r = rmtread(fd, buf, bsz)) < 0) && errno == EINTR)
|
||||
continue;
|
||||
|
||||
return(r);
|
||||
}
|
||||
|
@ -529,7 +591,7 @@ xread(int fd, void *buf, int bsz)
|
|||
int r;
|
||||
|
||||
do {
|
||||
if ((r = read_with_restart(fd, b, bsz)) <= 0)
|
||||
if ((r = rmtread_with_restart(fd, b, bsz)) <= 0)
|
||||
break;
|
||||
b += r;
|
||||
bsz -= r;
|
||||
|
@ -558,6 +620,25 @@ write_with_restart(int fd, void *buf, int bsz)
|
|||
|
||||
return(r);
|
||||
}
|
||||
|
||||
/*
|
||||
* rmtwrite_with_restart()
|
||||
* Equivalent to write() but does retry on signals.
|
||||
* This function is not needed on 4.2BSD and later.
|
||||
* Return:
|
||||
* Number of bytes written. -1 indicates an error.
|
||||
*/
|
||||
|
||||
static int
|
||||
rmtwrite_with_restart(int fd, void *buf, int bsz)
|
||||
{
|
||||
int r;
|
||||
|
||||
while (((r = rmtwrite(fd, buf, bsz)) < 0) && errno == EINTR)
|
||||
;
|
||||
|
||||
return(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -576,7 +657,7 @@ xwrite(int fd, void *buf, int bsz)
|
|||
int r;
|
||||
|
||||
do {
|
||||
if ((r = write_with_restart(fd, b, bsz)) <= 0)
|
||||
if ((r = rmtwrite_with_restart(fd, b, bsz)) <= 0)
|
||||
break;
|
||||
b += r;
|
||||
bsz -= r;
|
||||
|
@ -610,6 +691,12 @@ ar_read(char *buf, int cnt)
|
|||
* how we read must be based on device type
|
||||
*/
|
||||
switch (artyp) {
|
||||
case ISRMT:
|
||||
if ((res = rmtread_with_restart(arfd, buf, cnt)) > 0) {
|
||||
io_ok = 1;
|
||||
return res;
|
||||
}
|
||||
break;
|
||||
case ISTAPE:
|
||||
if ((res = read_with_restart(arfd, buf, cnt)) > 0) {
|
||||
/*
|
||||
|
@ -732,6 +819,7 @@ ar_write(char *buf, int bsz)
|
|||
case ISTAPE:
|
||||
case ISCHR:
|
||||
case ISBLK:
|
||||
case ISRMT:
|
||||
if (res >= 0)
|
||||
break;
|
||||
if (errno == EACCES) {
|
||||
|
@ -823,6 +911,7 @@ ar_rdsync(void)
|
|||
did_io = 1;
|
||||
|
||||
switch(artyp) {
|
||||
case ISRMT:
|
||||
case ISTAPE:
|
||||
/*
|
||||
* if the last i/o was a successful data transfer, we assume
|
||||
|
@ -839,8 +928,13 @@ ar_rdsync(void)
|
|||
}
|
||||
mb.mt_op = MTFSR;
|
||||
mb.mt_count = 1;
|
||||
if (ioctl(arfd, MTIOCTOP, &mb) < 0)
|
||||
break;
|
||||
if (artyp == ISRMT) {
|
||||
if (rmtioctl(arfd, MTIOCTOP, &mb) < 0)
|
||||
break;
|
||||
} else {
|
||||
if (ioctl(arfd, MTIOCTOP, &mb) < 0)
|
||||
break;
|
||||
}
|
||||
lstrval = 1;
|
||||
break;
|
||||
case ISREG:
|
||||
|
@ -907,7 +1001,7 @@ ar_fow(off_t sksz, off_t *skipped)
|
|||
* number of physical blocks to skip (we do not know physical block
|
||||
* size at this point), so we must only read forward on tapes!
|
||||
*/
|
||||
if (artyp == ISTAPE || artyp == ISPIPE)
|
||||
if (artyp == ISTAPE || artyp == ISPIPE || artyp == ISRMT)
|
||||
return(0);
|
||||
|
||||
/*
|
||||
|
@ -1017,6 +1111,7 @@ ar_rev(off_t sksz)
|
|||
}
|
||||
break;
|
||||
case ISTAPE:
|
||||
case ISRMT:
|
||||
/*
|
||||
* Calculate and move the proper number of PHYSICAL tape
|
||||
* blocks. If the sksz is not an even multiple of the physical
|
||||
|
@ -1057,7 +1152,7 @@ ar_rev(off_t sksz)
|
|||
*/
|
||||
mb.mt_op = MTBSR;
|
||||
mb.mt_count = sksz/phyblk;
|
||||
if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
|
||||
if (rmtioctl(arfd, MTIOCTOP, &mb) < 0) {
|
||||
syswarn(1,errno, "Unable to backspace tape %ld blocks.",
|
||||
(long) mb.mt_count);
|
||||
lstrval = -1;
|
||||
|
@ -1098,7 +1193,7 @@ get_phys(void)
|
|||
* we know we are at file mark when we get back a 0 from
|
||||
* read()
|
||||
*/
|
||||
while ((res = read_with_restart(arfd, scbuf, sizeof(scbuf))) > 0)
|
||||
while ((res = rmtread_with_restart(arfd, scbuf, sizeof(scbuf))) > 0)
|
||||
padsz += res;
|
||||
if (res < 0) {
|
||||
syswarn(1, errno, "Unable to locate tape filemark.");
|
||||
|
@ -1112,7 +1207,7 @@ get_phys(void)
|
|||
*/
|
||||
mb.mt_op = MTBSF;
|
||||
mb.mt_count = 1;
|
||||
if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
|
||||
if (rmtioctl(arfd, MTIOCTOP, &mb) < 0) {
|
||||
syswarn(1, errno, "Unable to backspace over tape filemark.");
|
||||
return(-1);
|
||||
}
|
||||
|
@ -1123,11 +1218,11 @@ get_phys(void)
|
|||
*/
|
||||
mb.mt_op = MTBSR;
|
||||
mb.mt_count = 1;
|
||||
if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
|
||||
if (rmtioctl(arfd, MTIOCTOP, &mb) < 0) {
|
||||
syswarn(1, errno, "Unable to backspace over last tape block.");
|
||||
return(-1);
|
||||
}
|
||||
if ((phyblk = read_with_restart(arfd, scbuf, sizeof(scbuf))) <= 0) {
|
||||
if ((phyblk = rmtread_with_restart(arfd, scbuf, sizeof(scbuf))) <= 0) {
|
||||
syswarn(1, errno, "Cannot determine archive tape blocksize.");
|
||||
return(-1);
|
||||
}
|
||||
|
@ -1136,7 +1231,7 @@ get_phys(void)
|
|||
* 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_with_restart(arfd, scbuf, sizeof(scbuf))) > 0)
|
||||
while ((res = rmtread_with_restart(arfd, scbuf, sizeof(scbuf))) > 0)
|
||||
;
|
||||
if (res < 0) {
|
||||
syswarn(1, errno, "Unable to locate tape filemark.");
|
||||
|
@ -1144,7 +1239,7 @@ get_phys(void)
|
|||
}
|
||||
mb.mt_op = MTBSF;
|
||||
mb.mt_count = 1;
|
||||
if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
|
||||
if (rmtioctl(arfd, MTIOCTOP, &mb) < 0) {
|
||||
syswarn(1, errno, "Unable to backspace over tape filemark.");
|
||||
return(-1);
|
||||
}
|
||||
|
@ -1175,7 +1270,7 @@ get_phys(void)
|
|||
*/
|
||||
mb.mt_op = MTBSR;
|
||||
mb.mt_count = padsz/phyblk;
|
||||
if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
|
||||
if (rmtioctl(arfd, MTIOCTOP, &mb) < 0) {
|
||||
syswarn(1,errno,"Unable to backspace tape over %ld pad blocks",
|
||||
(long)mb.mt_count);
|
||||
return(-1);
|
||||
|
@ -1222,7 +1317,7 @@ ar_next(void)
|
|||
*/
|
||||
if (strcmp(arcname, STDO) && strcmp(arcname, STDN) && (artyp != ISREG)
|
||||
&& (artyp != ISPIPE)) {
|
||||
if (artyp == ISTAPE) {
|
||||
if (artyp == ISTAPE || artyp == ISRMT) {
|
||||
tty_prnt("%s ready for archive tape volume: %d\n",
|
||||
arcname, arvol);
|
||||
tty_prnt("Load the NEXT TAPE on the tape drive");
|
||||
|
@ -1340,52 +1435,38 @@ ar_next(void)
|
|||
* to keep the fd the same in the calling function (parent).
|
||||
*/
|
||||
void
|
||||
ar_start_gzip(int fd)
|
||||
ar_start_gzip(int fd, const char *gzp, int wr)
|
||||
{
|
||||
pid_t pid;
|
||||
int fds[2];
|
||||
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)
|
||||
if (execlp(gzp, gzp, gzip_flags, NULL) < 0)
|
||||
err(1, "could not exec");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
@ -1496,33 +1577,14 @@ ar_summary(int n)
|
|||
int
|
||||
ar_dochdir(char *name)
|
||||
{
|
||||
if (curdirfd == -1) {
|
||||
/* first time. remember where we came from */
|
||||
curdirfd = open(".", O_RDONLY);
|
||||
if (curdirfd < 0) {
|
||||
syswarn(0, errno, "failed to open directory .");
|
||||
return (-1);
|
||||
}
|
||||
} else /* XXX if (*name != '/') XXX */ {
|
||||
/*
|
||||
* relative chdir. Make sure to get the same directory
|
||||
* each time by fchdir-ing back first.
|
||||
*/
|
||||
fchdir(curdirfd);
|
||||
/* First fchdir() back... */
|
||||
if (fchdir(cwdfd) < 0) {
|
||||
syswarn(1, errno, "Can't fchdir to starting directory");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (minusCfd != -1) {
|
||||
/* don't leak descriptors */
|
||||
close(minusCfd);
|
||||
minusCfd = -1;
|
||||
if (chdir(name) < 0) {
|
||||
syswarn(1, errno, "Can't chdir to %s", name);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
minusCfd = open(name, O_RDONLY);
|
||||
if (minusCfd < 0) {
|
||||
syswarn(0, errno, "failed to open directory %s", name);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
fchdir(minusCfd);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ar_subs.c,v 1.16 2002/01/31 19:27:53 tv Exp $ */
|
||||
/* $NetBSD: ar_subs.c,v 1.17 2002/10/12 15:39:29 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)ar_subs.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: ar_subs.c,v 1.16 2002/01/31 19:27:53 tv Exp $");
|
||||
__RCSID("$NetBSD: ar_subs.c,v 1.17 2002/10/12 15:39:29 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -131,7 +131,7 @@ list(void)
|
|||
if ((res = mod_name(arcn)) < 0)
|
||||
break;
|
||||
if (res == 0)
|
||||
ls_list(arcn, now);
|
||||
ls_list(arcn, now, stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -166,6 +166,7 @@ extract(void)
|
|||
off_t cnt;
|
||||
struct stat sb;
|
||||
int fd;
|
||||
time_t now;
|
||||
|
||||
arcn = &archd;
|
||||
/*
|
||||
|
@ -177,6 +178,8 @@ extract(void)
|
|||
((*frmt->st_rd)() < 0) || (dir_start() < 0))
|
||||
return;
|
||||
|
||||
now = time((time_t *)NULL);
|
||||
|
||||
/*
|
||||
* When we are doing interactive rename, we store the mapping of names
|
||||
* so we can fix up hard links files later in the archive.
|
||||
|
@ -281,10 +284,21 @@ extract(void)
|
|||
}
|
||||
|
||||
if (vflag) {
|
||||
(void)fputs(arcn->name, stderr);
|
||||
vfpart = 1;
|
||||
if (vflag > 1)
|
||||
ls_list(arcn, now, listf);
|
||||
else {
|
||||
(void)safe_print(arcn->name, listf);
|
||||
vfpart = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* if required, chdir around.
|
||||
*/
|
||||
if ((arcn->pat != NULL) && (arcn->pat->chdname != NULL))
|
||||
if (chdir(arcn->pat->chdname) != 0)
|
||||
syswarn(1, errno, "Cannot chdir to %s",
|
||||
arcn->pat->chdname);
|
||||
/*
|
||||
* all ok, extract this member based on type
|
||||
*/
|
||||
|
@ -305,7 +319,7 @@ extract(void)
|
|||
purg_lnk(arcn);
|
||||
|
||||
if (vflag && vfpart) {
|
||||
(void)putc('\n', stderr);
|
||||
(void)putc('\n', listf);
|
||||
vfpart = 0;
|
||||
}
|
||||
continue;
|
||||
|
@ -329,11 +343,19 @@ extract(void)
|
|||
if (!gnu_longlink_hack)
|
||||
file_close(arcn, fd);
|
||||
if (vflag && vfpart) {
|
||||
(void)putc('\n', stderr);
|
||||
(void)putc('\n', listf);
|
||||
vfpart = 0;
|
||||
}
|
||||
if (!res)
|
||||
(void)rd_skip(cnt + arcn->pad);
|
||||
|
||||
/*
|
||||
* if required, chdir around.
|
||||
*/
|
||||
if ((arcn->pat != NULL) && (arcn->pat->chdname != NULL))
|
||||
if (fchdir(cwdfd) != 0)
|
||||
syswarn(1, errno,
|
||||
"Can't fchdir to starting directory");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -363,6 +385,7 @@ wr_archive(ARCHD *arcn, int is_app)
|
|||
off_t cnt;
|
||||
int (*wrf)(ARCHD *);
|
||||
int fd = -1;
|
||||
time_t now;
|
||||
|
||||
/*
|
||||
* if this format supports hard link storage, start up the database
|
||||
|
@ -378,6 +401,8 @@ wr_archive(ARCHD *arcn, int is_app)
|
|||
return;
|
||||
wrf = frmt->wr;
|
||||
|
||||
now = time((time_t *)NULL);
|
||||
|
||||
/*
|
||||
* When we are doing interactive rename, we store the mapping of names
|
||||
* so we can fix up hard links files later in the archive.
|
||||
|
@ -462,8 +487,12 @@ wr_archive(ARCHD *arcn, int is_app)
|
|||
}
|
||||
|
||||
if (vflag) {
|
||||
(void)fputs(arcn->name, stderr);
|
||||
vfpart = 1;
|
||||
if (vflag > 1)
|
||||
ls_list(arcn, now, listf);
|
||||
else {
|
||||
(void)safe_print(arcn->name, listf);
|
||||
vfpart = 1;
|
||||
}
|
||||
}
|
||||
++flcnt;
|
||||
|
||||
|
@ -482,7 +511,7 @@ wr_archive(ARCHD *arcn, int is_app)
|
|||
* so we are done messing with this file
|
||||
*/
|
||||
if (vflag && vfpart) {
|
||||
(void)putc('\n', stderr);
|
||||
(void)putc('\n', listf);
|
||||
vfpart = 0;
|
||||
}
|
||||
rdfile_close(arcn, &fd);
|
||||
|
@ -500,7 +529,7 @@ wr_archive(ARCHD *arcn, int is_app)
|
|||
res = (*frmt->wr_data)(arcn, fd, &cnt);
|
||||
rdfile_close(arcn, &fd);
|
||||
if (vflag && vfpart) {
|
||||
(void)putc('\n', stderr);
|
||||
(void)putc('\n', listf);
|
||||
vfpart = 0;
|
||||
}
|
||||
if (res < 0)
|
||||
|
@ -611,7 +640,7 @@ append(void)
|
|||
* reading the archive may take a long time. If verbose tell the user
|
||||
*/
|
||||
if (vflag) {
|
||||
(void)fprintf(stderr,
|
||||
(void)fprintf(listf,
|
||||
"%s: Reading archive to position at the end...", argv0);
|
||||
vfpart = 1;
|
||||
}
|
||||
|
@ -673,7 +702,7 @@ append(void)
|
|||
* tell the user we are done reading.
|
||||
*/
|
||||
if (vflag && vfpart) {
|
||||
(void)fputs("done.\n", stderr);
|
||||
(void)safe_print("done.\n", listf);
|
||||
vfpart = 0;
|
||||
}
|
||||
|
||||
|
@ -731,7 +760,12 @@ copy(void)
|
|||
* 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, PAXPATHLEN);
|
||||
dlen = strlcpy(dirbuf, dirptr, sizeof(dirbuf));
|
||||
if (dlen >= sizeof(dirbuf) ||
|
||||
(dlen == sizeof(dirbuf) - 1 && dirbuf[dlen - 1] != '/')) {
|
||||
tty_warn(1, "directory name is too long %s", dirptr);
|
||||
return;
|
||||
}
|
||||
dest_pt = dirbuf + dlen;
|
||||
if (*(dest_pt-1) != '/') {
|
||||
*dest_pt++ = '/';
|
||||
|
@ -795,17 +829,12 @@ copy(void)
|
|||
/*
|
||||
* 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) {
|
||||
tty_warn(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
|
||||
|
@ -859,7 +888,7 @@ copy(void)
|
|||
}
|
||||
|
||||
if (vflag) {
|
||||
(void)fputs(arcn->name, stderr);
|
||||
(void)safe_print(arcn->name, listf);
|
||||
vfpart = 1;
|
||||
}
|
||||
++flcnt;
|
||||
|
@ -874,7 +903,7 @@ copy(void)
|
|||
res = chk_same(arcn);
|
||||
if (res <= 0) {
|
||||
if (vflag && vfpart) {
|
||||
(void)putc('\n', stderr);
|
||||
(void)putc('\n', listf);
|
||||
vfpart = 0;
|
||||
}
|
||||
continue;
|
||||
|
@ -894,7 +923,7 @@ copy(void)
|
|||
if (res < 0)
|
||||
purg_lnk(arcn);
|
||||
if (vflag && vfpart) {
|
||||
(void)putc('\n', stderr);
|
||||
(void)putc('\n', listf);
|
||||
vfpart = 0;
|
||||
}
|
||||
continue;
|
||||
|
@ -924,7 +953,7 @@ copy(void)
|
|||
rdfile_close(arcn, &fdsrc);
|
||||
|
||||
if (vflag && vfpart) {
|
||||
(void)putc('\n', stderr);
|
||||
(void)putc('\n', listf);
|
||||
vfpart = 0;
|
||||
}
|
||||
}
|
||||
|
@ -969,6 +998,7 @@ next_head(ARCHD *arcn)
|
|||
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. */
|
||||
|
||||
/*
|
||||
* set up initial conditions, we want a whole frmt->hsz block as we
|
||||
|
@ -986,6 +1016,17 @@ next_head(ARCHD *arcn)
|
|||
if ((ret = rd_wrbuf(hdend, res)) == res)
|
||||
break;
|
||||
|
||||
/*
|
||||
* If we read 0 bytes (EOF) from an archive when we
|
||||
* expect to find a header, we have stepped upon
|
||||
* an archive without the customary block of zeroes
|
||||
* end marker. It's just stupid to error out on
|
||||
* them, so exit gracefully.
|
||||
*/
|
||||
if (first && ret == 0)
|
||||
return(-1);
|
||||
first = 0;
|
||||
|
||||
/*
|
||||
* some kind of archive read problem, try to resync the
|
||||
* storage device, better give the user the bad news.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: extern.h,v 1.30 2002/01/31 22:43:35 tv Exp $ */
|
||||
/* $NetBSD: extern.h,v 1.31 2002/10/12 15:39:29 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -54,6 +54,9 @@ extern int curdirfd;
|
|||
extern const char *gzip_program;
|
||||
extern time_t starttime;
|
||||
extern int force_one_volume;
|
||||
extern char *chdname;
|
||||
extern int forcelocal;
|
||||
|
||||
int ar_open(const char *);
|
||||
void ar_close(void);
|
||||
void ar_drain(void);
|
||||
|
@ -172,10 +175,9 @@ int next_file(ARCHD *);
|
|||
/*
|
||||
* gen_subs.c
|
||||
*/
|
||||
void ls_list(ARCHD *, time_t);
|
||||
void ls_list(ARCHD *, time_t, FILE *);
|
||||
void ls_tty(ARCHD *);
|
||||
void zf_strncpy(char *, const char *, int);
|
||||
int l_strncpy(char *, const char *, int);
|
||||
void safe_print(const char *, FILE *);
|
||||
u_long asc_ul(char *, int, int);
|
||||
int ul_asc(u_long, char *, int, int);
|
||||
#ifndef NET2_STAT
|
||||
|
@ -195,18 +197,18 @@ int getoldopt(int, char **, const char *, struct option *, int *);
|
|||
*/
|
||||
extern FSUB fsub[];
|
||||
extern int ford[];
|
||||
extern int cpio_mode;
|
||||
void options(int, char **);
|
||||
OPLIST * opt_next(void);
|
||||
int opt_add(const char *);
|
||||
int opt_chdir(char *);
|
||||
int bad_opt(void);
|
||||
int mkpath(char *);
|
||||
char *chdname;
|
||||
|
||||
/*
|
||||
* pat_rep.c
|
||||
*/
|
||||
int rep_add(char *);
|
||||
int pat_add(char *, int);
|
||||
int pat_add(char *, char *);
|
||||
void pat_chk(void);
|
||||
int pat_sel(ARCHD *);
|
||||
int pat_match(ARCHD *);
|
||||
|
@ -220,6 +222,7 @@ extern int act;
|
|||
extern FSUB *frmt;
|
||||
extern int Aflag;
|
||||
extern int cflag;
|
||||
extern int cwdfd;
|
||||
extern int dflag;
|
||||
extern int iflag;
|
||||
extern int kflag;
|
||||
|
@ -239,13 +242,20 @@ extern int Zflag;
|
|||
extern int vfpart;
|
||||
extern int patime;
|
||||
extern int pmtime;
|
||||
extern int nodirs;
|
||||
extern int pfflags;
|
||||
extern int pmode;
|
||||
extern int pids;
|
||||
extern int rmleadslash;
|
||||
extern int exit_val;
|
||||
extern int docrc;
|
||||
extern char *dirptr;
|
||||
extern char *ltmfrmt;
|
||||
extern char *argv0;
|
||||
extern FILE *listf;
|
||||
extern char *tempfile;
|
||||
extern char *tempbase;
|
||||
|
||||
int main(int, char **);
|
||||
void sig_cleanup(int);
|
||||
|
||||
|
@ -268,7 +278,7 @@ int ftime_start(void);
|
|||
int chk_ftime(ARCHD *);
|
||||
int name_start(void);
|
||||
int add_name(char *, int, char *);
|
||||
void sub_name(char *, int *);
|
||||
void sub_name(char *, int *, size_t);
|
||||
int dev_start(void);
|
||||
int add_dev(ARCHD *);
|
||||
int map_dev(ARCHD *, u_long, u_long);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: file_subs.c,v 1.23 2002/02/11 11:19:26 wiz Exp $ */
|
||||
/* $NetBSD: file_subs.c,v 1.24 2002/10/12 15:39:29 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)file_subs.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: file_subs.c,v 1.23 2002/02/11 11:19:26 wiz Exp $");
|
||||
__RCSID("$NetBSD: file_subs.c,v 1.24 2002/10/12 15:39:29 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -60,6 +60,7 @@ __RCSID("$NetBSD: file_subs.c,v 1.23 2002/02/11 11:19:26 wiz Exp $");
|
|||
#include <stdlib.h>
|
||||
#include "pax.h"
|
||||
#include "extern.h"
|
||||
#include "options.h"
|
||||
|
||||
static int
|
||||
mk_link(char *,struct stat *,char *, int);
|
||||
|
@ -121,7 +122,7 @@ file_creat(ARCHD *arcn)
|
|||
file_mode)) >= 0)
|
||||
break;
|
||||
oerrno = errno;
|
||||
if (chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) {
|
||||
if (nodirs || chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) {
|
||||
syswarn(1, oerrno, "Unable to create %s", arcn->name);
|
||||
return(-1);
|
||||
}
|
||||
|
@ -357,6 +358,9 @@ node_creat(ARCHD *arcn)
|
|||
int pass = 0;
|
||||
mode_t file_mode;
|
||||
struct stat sb;
|
||||
char target[MAXPATHLEN];
|
||||
char *nm = arcn->name;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* create node based on type, if that fails try to unlink the node and
|
||||
|
@ -369,20 +373,43 @@ node_creat(ARCHD *arcn)
|
|||
for (;;) {
|
||||
switch(arcn->type) {
|
||||
case PAX_DIR:
|
||||
res = mkdir(arcn->name, file_mode);
|
||||
/*
|
||||
* If -h (or -L) was given in tar-mode, follow the
|
||||
* potential symlink chain before trying to create the
|
||||
* directory.
|
||||
*/
|
||||
if (strcmp(NM_TAR, argv0) == 0 && Lflag) {
|
||||
while (lstat(nm, &sb) == 0 &&
|
||||
S_ISLNK(sb.st_mode)) {
|
||||
len = readlink(nm, target,
|
||||
sizeof target - 1);
|
||||
if (len == -1) {
|
||||
syswarn(0, errno,
|
||||
"cannot follow symlink %s in chain for %s",
|
||||
nm, arcn->name);
|
||||
res = -1;
|
||||
goto badlink;
|
||||
}
|
||||
target[len] = '\0';
|
||||
nm = target;
|
||||
}
|
||||
}
|
||||
res = mkdir(nm, file_mode);
|
||||
|
||||
badlink:
|
||||
if (ign)
|
||||
res = 0;
|
||||
break;
|
||||
case PAX_CHR:
|
||||
file_mode |= S_IFCHR;
|
||||
res = mknod(arcn->name, file_mode, arcn->sb.st_rdev);
|
||||
res = mknod(nm, file_mode, arcn->sb.st_rdev);
|
||||
break;
|
||||
case PAX_BLK:
|
||||
file_mode |= S_IFBLK;
|
||||
res = mknod(arcn->name, file_mode, arcn->sb.st_rdev);
|
||||
res = mknod(nm, file_mode, arcn->sb.st_rdev);
|
||||
break;
|
||||
case PAX_FIF:
|
||||
res = mkfifo(arcn->name, file_mode);
|
||||
res = mkfifo(nm, file_mode);
|
||||
break;
|
||||
case PAX_SCK:
|
||||
/*
|
||||
|
@ -390,10 +417,10 @@ node_creat(ARCHD *arcn)
|
|||
*/
|
||||
tty_warn(0,
|
||||
"%s skipped. Sockets cannot be copied or extracted",
|
||||
arcn->name);
|
||||
nm);
|
||||
return(-1);
|
||||
case PAX_SLK:
|
||||
res = symlink(arcn->ln_name, arcn->name);
|
||||
res = symlink(arcn->ln_name, nm);
|
||||
break;
|
||||
case PAX_CTG:
|
||||
case PAX_HLK:
|
||||
|
@ -404,7 +431,7 @@ node_creat(ARCHD *arcn)
|
|||
* we should never get here
|
||||
*/
|
||||
tty_warn(0, "%s has an unknown file type, skipping",
|
||||
arcn->name);
|
||||
nm);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
@ -420,14 +447,14 @@ node_creat(ARCHD *arcn)
|
|||
* we failed to make the node
|
||||
*/
|
||||
oerrno = errno;
|
||||
if ((ign = unlnk_exist(arcn->name, arcn->type)) < 0)
|
||||
if ((ign = unlnk_exist(nm, arcn->type)) < 0)
|
||||
return(-1);
|
||||
|
||||
if (++pass <= 1)
|
||||
continue;
|
||||
|
||||
if (chk_path(arcn->name,arcn->sb.st_uid,arcn->sb.st_gid) < 0) {
|
||||
syswarn(1, oerrno, "Could not create: %s", arcn->name);
|
||||
if (nodirs || chk_path(nm,arcn->sb.st_uid,arcn->sb.st_gid) < 0) {
|
||||
syswarn(1, oerrno, "Could not create: %s", nm);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
@ -440,7 +467,7 @@ node_creat(ARCHD *arcn)
|
|||
#else
|
||||
if (pids && arcn->type != PAX_SLK)
|
||||
#endif
|
||||
res = set_ids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid);
|
||||
res = set_ids(nm, arcn->sb.st_uid, arcn->sb.st_gid);
|
||||
else
|
||||
res = 0;
|
||||
|
||||
|
@ -458,7 +485,7 @@ node_creat(ARCHD *arcn)
|
|||
#endif
|
||||
set_pmode(arcn->name, arcn->sb.st_mode);
|
||||
|
||||
if (arcn->type == PAX_DIR) {
|
||||
if (arcn->type == PAX_DIR && strcmp(NM_CPIO, argv0) != 0) {
|
||||
/*
|
||||
* Dirs must be processed again at end of extract to set times
|
||||
* and modes to agree with those stored in the archive. However
|
||||
|
@ -468,11 +495,11 @@ node_creat(ARCHD *arcn)
|
|||
* and modes will be fixed after the entire archive is read and
|
||||
* before pax exits.
|
||||
*/
|
||||
if (access(arcn->name, R_OK | W_OK | X_OK) < 0) {
|
||||
if (lstat(arcn->name, &sb) < 0) {
|
||||
if (access(nm, R_OK | W_OK | X_OK) < 0) {
|
||||
if (lstat(nm, &sb) < 0) {
|
||||
syswarn(0, errno,"Could not access %s (stat)",
|
||||
arcn->name);
|
||||
set_pmode(arcn->name,file_mode | S_IRWXU);
|
||||
set_pmode(nm,file_mode | S_IRWXU);
|
||||
} else {
|
||||
/*
|
||||
* We have to add rights to the dir, so we make
|
||||
|
@ -480,7 +507,7 @@ node_creat(ARCHD *arcn)
|
|||
* restored AS CREATED and not as stored if
|
||||
* pmode is not set.
|
||||
*/
|
||||
set_pmode(arcn->name,
|
||||
set_pmode(nm,
|
||||
((sb.st_mode & FILEBITS) | S_IRWXU));
|
||||
if (!pmode)
|
||||
arcn->sb.st_mode = sb.st_mode;
|
||||
|
@ -490,9 +517,9 @@ node_creat(ARCHD *arcn)
|
|||
* we have to force the mode to what was set here,
|
||||
* since we changed it from the default as created.
|
||||
*/
|
||||
add_dir(arcn->name, arcn->nlen, &(arcn->sb), 1);
|
||||
add_dir(nm, arcn->nlen, &(arcn->sb), 1);
|
||||
} else if (pmode || patime || pmtime)
|
||||
add_dir(arcn->name, arcn->nlen, &(arcn->sb), 0);
|
||||
add_dir(nm, arcn->nlen, &(arcn->sb), 0);
|
||||
}
|
||||
|
||||
#if HAVE_LUTIMES
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ftree.c,v 1.21 2002/06/28 11:29:45 lukem Exp $ */
|
||||
/* $NetBSD: ftree.c,v 1.22 2002/10/12 15:39:29 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -78,7 +78,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)ftree.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: ftree.c,v 1.21 2002/06/28 11:29:45 lukem Exp $");
|
||||
__RCSID("$NetBSD: ftree.c,v 1.22 2002/10/12 15:39:29 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -96,6 +96,7 @@ __RCSID("$NetBSD: ftree.c,v 1.21 2002/06/28 11:29:45 lukem Exp $");
|
|||
#include "pax.h"
|
||||
#include "ftree.h"
|
||||
#include "extern.h"
|
||||
#include "options.h"
|
||||
#ifndef SMALL
|
||||
#include "mtree.h"
|
||||
#endif /* SMALL */
|
||||
|
@ -529,7 +530,7 @@ next_file(ARCHD *arcn)
|
|||
if (ftnode->type == F_DIR && ftnode->child != NULL) {
|
||||
/* directory with unseen child */
|
||||
ftnode = ftnode->child;
|
||||
curdirlen = l_strncpy(curdir, curpath, sizeof(curdir));
|
||||
curdirlen = strlcpy(curdir, curpath, sizeof(curdir));
|
||||
} else do {
|
||||
if (ftnode->next != NULL) {
|
||||
/* next node at current level */
|
||||
|
@ -597,7 +598,7 @@ next_file(ARCHD *arcn)
|
|||
* here. failure to do so results in massive amounts
|
||||
* of duplicated files in the output.
|
||||
*/
|
||||
if (cpio_mode)
|
||||
if (strcmp(NM_CPIO, argv0) == 0)
|
||||
continue;
|
||||
/* FALLTHROUGH */
|
||||
case FTS_DEFAULT:
|
||||
|
@ -704,7 +705,7 @@ next_file(ARCHD *arcn)
|
|||
case S_IFLNK:
|
||||
arcn->type = PAX_SLK;
|
||||
if (curlink != NULL) {
|
||||
cnt = l_strncpy(arcn->ln_name, curlink,
|
||||
cnt = strlcpy(arcn->ln_name, curlink,
|
||||
sizeof(arcn->ln_name));
|
||||
/*
|
||||
* have to read the symlink path from the file
|
||||
|
@ -741,8 +742,7 @@ next_file(ARCHD *arcn)
|
|||
/*
|
||||
* copy file name, set file name length
|
||||
*/
|
||||
arcn->nlen = l_strncpy(arcn->name, ftent->fts_path, PAXPATHLEN+1);
|
||||
arcn->name[arcn->nlen] = '\0';
|
||||
arcn->nlen = strlcpy(arcn->name, ftent->fts_path, sizeof(arcn->name));
|
||||
arcn->org_name = ftent->fts_path;
|
||||
return(0);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: gen_subs.c,v 1.24 2002/08/01 18:41:34 wiz Exp $ */
|
||||
/* $NetBSD: gen_subs.c,v 1.25 2002/10/12 15:39:29 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)gen_subs.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: gen_subs.c,v 1.24 2002/08/01 18:41:34 wiz Exp $");
|
||||
__RCSID("$NetBSD: gen_subs.c,v 1.25 2002/10/12 15:39:29 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -54,6 +54,7 @@ __RCSID("$NetBSD: gen_subs.c,v 1.24 2002/08/01 18:41:34 wiz Exp $");
|
|||
#include <ctype.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <vis.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -87,7 +88,7 @@ __RCSID("$NetBSD: gen_subs.c,v 1.24 2002/08/01 18:41:34 wiz Exp $");
|
|||
*/
|
||||
|
||||
void
|
||||
ls_list(ARCHD *arcn, time_t now)
|
||||
ls_list(ARCHD *arcn, time_t now, FILE *fp)
|
||||
{
|
||||
struct stat *sbp;
|
||||
char f_mode[MODELEN];
|
||||
|
@ -98,8 +99,8 @@ ls_list(ARCHD *arcn, time_t now)
|
|||
* if not verbose, just print the file name
|
||||
*/
|
||||
if (!vflag) {
|
||||
(void)printf("%s\n", arcn->name);
|
||||
(void)fflush(stdout);
|
||||
(void)fprintf(fp, "%s\n", arcn->name);
|
||||
(void)fflush(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -124,31 +125,31 @@ ls_list(ARCHD *arcn, time_t now)
|
|||
f_date[0] = '\0';
|
||||
user = user_from_uid(sbp->st_uid, 0);
|
||||
group = group_from_gid(sbp->st_gid, 0);
|
||||
(void)printf("%s%2lu %-*s %-*s ", f_mode, (unsigned long)sbp->st_nlink,
|
||||
(void)fprintf(fp, "%s%2lu %-*s %-*s ", f_mode,
|
||||
(unsigned long)sbp->st_nlink,
|
||||
UT_NAMESIZE, user ? user : "", UT_GRPSIZE, group ? group : "");
|
||||
|
||||
/*
|
||||
* print device id's for devices, or sizes for other nodes
|
||||
*/
|
||||
if ((arcn->type == PAX_CHR) || (arcn->type == PAX_BLK))
|
||||
(void)printf("%4lu,%4lu ", (long) MAJOR(sbp->st_rdev),
|
||||
(void)fprintf(fp, "%4lu,%4lu ", (long) MAJOR(sbp->st_rdev),
|
||||
(long) MINOR(sbp->st_rdev));
|
||||
else {
|
||||
(void)printf(OFFT_FP("9") " ", (OFFT_T)sbp->st_size);
|
||||
(void)fprintf(fp, OFFT_FP("9") " ", (OFFT_T)sbp->st_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* print name and link info for hard and soft links
|
||||
*/
|
||||
(void)printf("%s %s", f_date, arcn->name);
|
||||
(void)fprintf(fp, "%s %s", f_date, arcn->name);
|
||||
if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG))
|
||||
(void)printf(" == %s\n", arcn->ln_name);
|
||||
(void)fprintf(fp, " == %s\n", arcn->ln_name);
|
||||
else if (arcn->type == PAX_SLK)
|
||||
(void)printf(" => %s\n", arcn->ln_name);
|
||||
(void)fprintf(fp, " => %s\n", arcn->ln_name);
|
||||
else
|
||||
(void)putchar('\n');
|
||||
(void)fflush(stdout);
|
||||
return;
|
||||
(void)fputc('\n', fp);
|
||||
(void)fflush(fp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -179,48 +180,23 @@ ls_tty(ARCHD *arcn)
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* zf_strncpy()
|
||||
* copy src to dest up to len chars (stopping at first '\0'), when src is
|
||||
* shorter than len, pads to len with '\0'. big performance win (and
|
||||
* a lot easier to code) over strncpy(), then a strlen() then a
|
||||
* memset(). (or doing the memset() first).
|
||||
*/
|
||||
|
||||
void
|
||||
zf_strncpy(char *dest, const char *src, int len)
|
||||
safe_print(const char *str, FILE *fp)
|
||||
{
|
||||
char *stop;
|
||||
char visbuf[5];
|
||||
const char *cp;
|
||||
|
||||
stop = dest + len;
|
||||
while ((dest < stop) && (*src != '\0'))
|
||||
*dest++ = *src++;
|
||||
while (dest < stop)
|
||||
*dest++ = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* l_strncpy()
|
||||
* copy src to dest up to len chars (stopping at first '\0')
|
||||
* Return:
|
||||
* number of chars copied. (Note this is a real performance win over
|
||||
* doing a strncpy() then a strlen()
|
||||
*/
|
||||
|
||||
int
|
||||
l_strncpy(char *dest, const char *src, int len)
|
||||
{
|
||||
char *stop;
|
||||
char *start;
|
||||
|
||||
stop = dest + len;
|
||||
start = dest;
|
||||
while ((dest < stop) && (*src != '\0'))
|
||||
*dest++ = *src++;
|
||||
if (dest < stop)
|
||||
*dest = '\0';
|
||||
return(dest - start);
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: getoldopt.c,v 1.14 2002/01/31 22:43:35 tv Exp $ */
|
||||
/* $NetBSD: getoldopt.c,v 1.15 2002/10/12 15:39:29 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Plug-compatible replacement for getopt() for parsing tar-like
|
||||
|
@ -11,12 +11,13 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(__RCSID) && !defined(lint)
|
||||
__RCSID("$NetBSD: getoldopt.c,v 1.14 2002/01/31 22:43:35 tv Exp $");
|
||||
__RCSID("$NetBSD: getoldopt.c,v 1.15 2002/10/12 15:39:29 christos Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "pax.h"
|
||||
|
@ -42,10 +43,19 @@ getoldopt(int argc, char **argv, const char *optstring,
|
|||
optind = 2;
|
||||
}
|
||||
|
||||
if (use_getopt)
|
||||
return ((longopts != NULL) ?
|
||||
getopt_long(argc, argv, optstring, longopts, idx) :
|
||||
getopt(argc, argv, optstring));
|
||||
if (use_getopt) {
|
||||
if (longopts != NULL) {
|
||||
/*
|
||||
* Setting POSIXLY_CORRECT here, makes getopt_long
|
||||
* stop argument processing at the first non-option.
|
||||
*/
|
||||
setenv("POSIXLY_CORRECT", "", 0);
|
||||
return getopt_long(argc, argv, optstring,
|
||||
longopts, idx);
|
||||
} else {
|
||||
return getopt(argc, argv, optstring);
|
||||
}
|
||||
}
|
||||
|
||||
c = *key++;
|
||||
if (c == '\0') {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: options.c,v 1.39 2002/02/02 12:34:39 lukem Exp $ */
|
||||
/* $NetBSD: options.c,v 1.40 2002/10/12 15:39:29 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: options.c,v 1.39 2002/02/02 12:34:39 lukem Exp $");
|
||||
__RCSID("$NetBSD: options.c,v 1.40 2002/10/12 15:39:29 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -52,12 +52,14 @@ __RCSID("$NetBSD: options.c,v 1.39 2002/02/02 12:34:39 lukem Exp $");
|
|||
#include <sys/mtio.h>
|
||||
#include <sys/param.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <paths.h>
|
||||
#include "pax.h"
|
||||
#include "options.h"
|
||||
#include "cpio.h"
|
||||
|
@ -71,18 +73,16 @@ __RCSID("$NetBSD: options.c,v 1.39 2002/02/02 12:34:39 lukem Exp $");
|
|||
* Routines which handle command line options
|
||||
*/
|
||||
|
||||
int cpio_mode; /* set if we are in cpio mode */
|
||||
|
||||
static int nopids; /* tar mode: suppress "pids" for -p option */
|
||||
static char *flgch = FLGCH; /* list of all possible flags (pax) */
|
||||
static OPLIST *ophead = NULL; /* head for format specific options -x */
|
||||
static OPLIST *optail = NULL; /* option tail */
|
||||
static char *firstminusC; /* first -C argument encountered. */
|
||||
|
||||
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 **);
|
||||
|
@ -90,7 +90,10 @@ static void tar_usage(void);
|
|||
static void cpio_options(int, char **);
|
||||
static void cpio_usage(void);
|
||||
|
||||
static void checkpositionalminusC(char ***, int (*)(char *, int));
|
||||
/* 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 */
|
||||
|
@ -169,12 +172,12 @@ options(int argc, char **argv)
|
|||
argv0 = argv[0];
|
||||
|
||||
if (strcmp(NM_TAR, argv0) == 0)
|
||||
tar_options(argc, argv);
|
||||
return(tar_options(argc, argv));
|
||||
else if (strcmp(NM_CPIO, argv0) == 0)
|
||||
cpio_options(argc, argv);
|
||||
return(cpio_options(argc, argv));
|
||||
else {
|
||||
argv0 = NM_PAX;
|
||||
pax_options(argc, argv);
|
||||
return(pax_options(argc, argv));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,8 +327,8 @@ pax_options(int argc, char **argv)
|
|||
pmode = 1;
|
||||
break;
|
||||
default:
|
||||
tty_warn(1,
|
||||
"Invalid -p string: %c", *pt);
|
||||
tty_warn(1, "Invalid -p string: %c",
|
||||
*pt);
|
||||
pax_usage();
|
||||
break;
|
||||
}
|
||||
|
@ -397,7 +400,6 @@ pax_options(int argc, char **argv)
|
|||
/*
|
||||
* use gzip. Non standard option.
|
||||
*/
|
||||
zflag = 1;
|
||||
gzip_program = GZIP_CMD;
|
||||
break;
|
||||
case 'A':
|
||||
|
@ -567,6 +569,7 @@ pax_options(int argc, char **argv)
|
|||
*/
|
||||
if (ISLIST(flg)) {
|
||||
act = LIST;
|
||||
listf = stdout;
|
||||
bflg = flg & BDLIST;
|
||||
} else if (ISEXTRACT(flg)) {
|
||||
act = EXTRACT;
|
||||
|
@ -602,7 +605,7 @@ pax_options(int argc, char **argv)
|
|||
case LIST:
|
||||
case EXTRACT:
|
||||
for (; optind < argc; optind++)
|
||||
if (pat_add(argv[optind], 0) < 0)
|
||||
if (pat_add(argv[optind], NULL) < 0)
|
||||
pax_usage();
|
||||
break;
|
||||
case COPY:
|
||||
|
@ -610,8 +613,9 @@ pax_options(int argc, char **argv)
|
|||
tty_warn(0, "Destination directory was not supplied");
|
||||
pax_usage();
|
||||
}
|
||||
--argc;
|
||||
dirptr = argv[argc];
|
||||
dirptr = argv[optind++];
|
||||
if (mkpath(dirptr) < 0)
|
||||
cpio_usage();
|
||||
/* FALLTHROUGH */
|
||||
case ARCHIVE:
|
||||
case APPND:
|
||||
|
@ -647,6 +651,7 @@ pax_options(int argc, char **argv)
|
|||
#define OPT_EXCLUDE 11
|
||||
#define OPT_BLOCK_COMPRESS 12
|
||||
#define OPT_NORECURSE 13
|
||||
#define OPT_FORCE_LOCAL 14
|
||||
|
||||
struct option tar_longopts[] = {
|
||||
{ "block-size", required_argument, 0, 'b' },
|
||||
|
@ -675,6 +680,7 @@ struct option tar_longopts[] = {
|
|||
{ "directory", required_argument, 0, 'C' },
|
||||
{ "tape-length", required_argument, 0, 'L' },
|
||||
{ "absolute-paths", no_argument, 0, 'P' },
|
||||
{ "files-from", required_argument, 0, 'T' },
|
||||
{ "exclude-from", required_argument, 0, 'X' },
|
||||
{ "compress", no_argument, 0, 'Z' },
|
||||
{ "uncompress", no_argument, 0, 'Z' },
|
||||
|
@ -684,6 +690,8 @@ struct option tar_longopts[] = {
|
|||
OPT_UNLINK },
|
||||
{ "use-compress-program", required_argument, 0,
|
||||
OPT_USE_COMPRESS_PROGRAM },
|
||||
{ "force-local", no_argument, 0,
|
||||
OPT_FORCE_LOCAL },
|
||||
#if 0 /* Not implemented */
|
||||
{ "catenate", no_argument, 0, 'A' }, /* F */
|
||||
{ "concatenate", no_argument, 0, 'A' }, /* F */
|
||||
|
@ -714,7 +722,6 @@ struct option tar_longopts[] = {
|
|||
{ "same-order", no_argument, 0, 's' },
|
||||
{ "preserve-order", no_argument, 0, 's' },
|
||||
{ "sparse", no_argument, 0, 'S' },
|
||||
{ "files-from", no_argument, 0, 'T' },
|
||||
{ "null", no_argument, 0,
|
||||
OPT_NULL },
|
||||
{ "totals", no_argument, 0,
|
||||
|
@ -739,22 +746,37 @@ tar_options(int argc, char **argv)
|
|||
{
|
||||
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.
|
||||
*/
|
||||
rmleadslash = 1;
|
||||
|
||||
/*
|
||||
* process option flags
|
||||
*/
|
||||
while ((c = getoldopt(argc, argv, "b:cef:hlmoprutvwxzBC:LPX:Z014578",
|
||||
while ((c = getoldopt(argc, argv,
|
||||
"b:cef:hlmopqrstuvwxzBC:HI:LOPTX:Z014578",
|
||||
tar_longopts, NULL))
|
||||
!= -1) {
|
||||
switch(c) {
|
||||
case 'b':
|
||||
/*
|
||||
* specify blocksize
|
||||
* specify blocksize in 512-byte blocks
|
||||
*/
|
||||
if ((wrblksz = (int)str_offt(optarg)) <= 0) {
|
||||
tty_warn(1, "Invalid block size %s", optarg);
|
||||
tar_usage();
|
||||
}
|
||||
wrblksz *= 512; /* XXX - check for int oflow */
|
||||
break;
|
||||
case 'c':
|
||||
/*
|
||||
|
@ -762,13 +784,6 @@ tar_options(int argc, char **argv)
|
|||
*/
|
||||
act = ARCHIVE;
|
||||
break;
|
||||
case 'C':
|
||||
/*
|
||||
* chdir here before extracting.
|
||||
* do so lazily, in case it's a list
|
||||
*/
|
||||
firstminusC = optarg;
|
||||
break;
|
||||
case 'e':
|
||||
/*
|
||||
* stop after first error
|
||||
|
@ -784,7 +799,7 @@ tar_options(int argc, char **argv)
|
|||
* treat a - as stdin
|
||||
*/
|
||||
fstdin = 1;
|
||||
arcname = (char *)0;
|
||||
arcname = NULL;
|
||||
break;
|
||||
}
|
||||
fstdin = 0;
|
||||
|
@ -826,6 +841,9 @@ tar_options(int argc, char **argv)
|
|||
nopids = 1;
|
||||
}
|
||||
break;
|
||||
case 'O':
|
||||
Oflag = 1;
|
||||
break;
|
||||
case 'p':
|
||||
/*
|
||||
* preserve user id, group id, file
|
||||
|
@ -837,6 +855,12 @@ tar_options(int argc, char **argv)
|
|||
patime = 1;
|
||||
pmtime = 1;
|
||||
break;
|
||||
case 'q':
|
||||
/*
|
||||
* select first match for a pattern only
|
||||
*/
|
||||
nflag = 1;
|
||||
break;
|
||||
case 'r':
|
||||
case 'u':
|
||||
/*
|
||||
|
@ -844,6 +868,15 @@ tar_options(int argc, char **argv)
|
|||
*/
|
||||
act = APPND;
|
||||
break;
|
||||
case 's':
|
||||
/*
|
||||
* file name substitution name pattern
|
||||
*/
|
||||
if (rep_add(optarg) < 0) {
|
||||
tar_usage();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
/*
|
||||
* list contents of the tape
|
||||
|
@ -864,9 +897,11 @@ tar_options(int argc, char **argv)
|
|||
break;
|
||||
case 'x':
|
||||
/*
|
||||
* write an archive
|
||||
* extract an archive, preserving mode,
|
||||
* and mtime if possible.
|
||||
*/
|
||||
act = EXTRACT;
|
||||
pmtime = 1;
|
||||
break;
|
||||
case 'z':
|
||||
/*
|
||||
|
@ -880,6 +915,30 @@ tar_options(int argc, char **argv)
|
|||
* Nothing to do here, this is pax default
|
||||
*/
|
||||
break;
|
||||
case 'C':
|
||||
chdname = optarg;
|
||||
break;
|
||||
case 'H':
|
||||
/*
|
||||
* follow command line symlinks only
|
||||
*/
|
||||
Hflag = 1;
|
||||
break;
|
||||
case 'I':
|
||||
case 'T':
|
||||
if (++nincfiles > incfiles_max) {
|
||||
incfiles_max = nincfiles + 3;
|
||||
incfiles = realloc(incfiles,
|
||||
sizeof(*incfiles) * incfiles_max);
|
||||
if (incfiles == NULL) {
|
||||
tty_warn(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
|
||||
|
@ -887,6 +946,10 @@ tar_options(int argc, char **argv)
|
|||
Lflag = 1;
|
||||
break;
|
||||
case 'P':
|
||||
/*
|
||||
* do not remove leading '/' from pathnames
|
||||
*/
|
||||
rmleadslash = 0;
|
||||
Aflag = 1;
|
||||
break;
|
||||
case 'X':
|
||||
|
@ -931,6 +994,9 @@ tar_options(int argc, char **argv)
|
|||
zflag = 1;
|
||||
gzip_program = optarg;
|
||||
break;
|
||||
case OPT_FORCE_LOCAL:
|
||||
forcelocal = 1;
|
||||
break;
|
||||
default:
|
||||
tar_usage();
|
||||
break;
|
||||
|
@ -939,31 +1005,159 @@ tar_options(int argc, char **argv)
|
|||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (firstminusC && (opt_chdir(firstminusC) < 0))
|
||||
tty_warn(1, "can't remember -C directory");
|
||||
/* Traditional tar behaviour (pax uses stderr unless in list mode) */
|
||||
if (fstdin == 1 && act == ARCHIVE)
|
||||
listf = stderr;
|
||||
else
|
||||
listf = stdout;
|
||||
|
||||
/* 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 && frmt == NULL)
|
||||
frmt = &(fsub[F_USTAR]);
|
||||
if (act == ARCHIVE || act == APPND)
|
||||
frmt = &(fsub[Oflag ? F_TAR : F_USTAR]);
|
||||
else if (Oflag) {
|
||||
tty_warn(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
|
||||
*/
|
||||
switch (act) {
|
||||
case LIST:
|
||||
default:
|
||||
while (*argv != (char *)NULL)
|
||||
if (pat_add(*argv++, 0) < 0)
|
||||
tar_usage();
|
||||
break;
|
||||
case EXTRACT:
|
||||
checkpositionalminusC(&argv, pat_add);
|
||||
default:
|
||||
{
|
||||
int sawpat = 0;
|
||||
char *file, *dir;
|
||||
|
||||
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) {
|
||||
tty_warn(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) {
|
||||
tty_warn(1, "Problem with file '%s'", file);
|
||||
tar_usage();
|
||||
}
|
||||
} else if (strcmp(*argv, "-C") == 0) {
|
||||
if (*++argv == NULL)
|
||||
break;
|
||||
chdname = *argv++;
|
||||
} else if (pat_add(*argv++, chdname) < 0)
|
||||
tar_usage();
|
||||
else
|
||||
sawpat = 1;
|
||||
}
|
||||
/*
|
||||
* if patterns were added, we are doing chdir()
|
||||
* on a file-by-file basis, else, just one
|
||||
* global chdir (if any) after opening input.
|
||||
*/
|
||||
if (sawpat > 0)
|
||||
chdname = NULL;
|
||||
}
|
||||
break;
|
||||
case ARCHIVE:
|
||||
case APPND:
|
||||
checkpositionalminusC(&argv, ftree_add);
|
||||
if (chdname != NULL) { /* initial chdir() */
|
||||
if (ftree_add(chdname, 1) < 0)
|
||||
tar_usage();
|
||||
}
|
||||
|
||||
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;
|
||||
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) {
|
||||
tty_warn(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) {
|
||||
tty_warn(1, "Problem with file '%s'",
|
||||
file);
|
||||
tar_usage();
|
||||
}
|
||||
} else if (strcmp(*argv, "-C") == 0) {
|
||||
if (*++argv == NULL)
|
||||
break;
|
||||
if (ftree_add(*argv++, 1) < 0)
|
||||
tar_usage();
|
||||
} else if (ftree_add(*argv++, 0) < 0)
|
||||
tar_usage();
|
||||
}
|
||||
/*
|
||||
* no read errors allowed on updates/append operation!
|
||||
*/
|
||||
|
@ -972,11 +1166,45 @@ tar_options(int argc, char **argv)
|
|||
}
|
||||
if (!fstdin && ((arcname == (char *)NULL) || (*arcname == '\0'))) {
|
||||
arcname = getenv("TAPE");
|
||||
if ((arcname == (char *)NULL) || (*arcname == '\0'))
|
||||
arcname = DEV_8;
|
||||
if ((arcname == NULL) || (*arcname == '\0'))
|
||||
arcname = _PATH_DEFTAPE;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
mkpath(path)
|
||||
char *path;
|
||||
{
|
||||
struct stat sb;
|
||||
char *slash;
|
||||
int done = 0;
|
||||
|
||||
slash = path;
|
||||
|
||||
while (!done) {
|
||||
slash += strspn(slash, "/");
|
||||
slash += strcspn(slash, "/");
|
||||
|
||||
done = (*slash == '\0');
|
||||
*slash = '\0';
|
||||
|
||||
if (stat(path, &sb)) {
|
||||
if (errno != ENOENT || mkdir(path, 0777)) {
|
||||
tty_warn(1, "%s", path);
|
||||
return (-1);
|
||||
}
|
||||
} else if (!S_ISDIR(sb.st_mode)) {
|
||||
syswarn(1, ENOTDIR, "%s", path);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (!done)
|
||||
*slash = '/';
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* cpio_options()
|
||||
* look at the user specified flags. set globals as required and check if
|
||||
|
@ -990,14 +1218,141 @@ cpio_options(int argc, char **argv)
|
|||
unsigned int flg = 0;
|
||||
unsigned int bflg = 0;
|
||||
int c, i;
|
||||
FILE *fp;
|
||||
char *str;
|
||||
|
||||
cpio_mode = uflag = 1;
|
||||
uflag = 1;
|
||||
kflag = 1;
|
||||
pids = 1;
|
||||
pmode = 1;
|
||||
pmtime = 0;
|
||||
arcname = NULL;
|
||||
dflag = 1;
|
||||
act = -1;
|
||||
nodirs = 1;
|
||||
/*
|
||||
* process option flags
|
||||
*/
|
||||
while ((c = getoldopt(argc, argv,
|
||||
"ABC:E:H:I:LM:O:R:SVabcdfiklmoprstuv", NULL, NULL)) != -1) {
|
||||
"abcdfiklmoprstuvzABC:E:F:H:I:LM:O:R:SVZ6", NULL, NULL)) != -1) {
|
||||
switch(c) {
|
||||
case 'a':
|
||||
/*
|
||||
* preserve access time on filesystem nodes we read
|
||||
*/
|
||||
tflag = 1;
|
||||
flg |= TF;
|
||||
break;
|
||||
#ifdef notyet
|
||||
case 'b':
|
||||
/*
|
||||
* swap bytes and half-words when reading data
|
||||
*/
|
||||
break;
|
||||
#endif
|
||||
case 'c':
|
||||
/*
|
||||
* ASCII cpio header
|
||||
*/
|
||||
frmt = &fsub[F_SV4CPIO];
|
||||
break;
|
||||
case 'd':
|
||||
/*
|
||||
* create directories as needed
|
||||
* pax does this by default ..
|
||||
*/
|
||||
nodirs = 0;
|
||||
flg |= RF;
|
||||
break;
|
||||
case 'f':
|
||||
/*
|
||||
* inverse match on patterns
|
||||
*/
|
||||
cflag = 1;
|
||||
flg |= CF;
|
||||
break;
|
||||
case 'i':
|
||||
/*
|
||||
* read the archive
|
||||
*/
|
||||
act = EXTRACT;
|
||||
flg |= RF;
|
||||
break;
|
||||
#ifdef notyet
|
||||
case 'k':
|
||||
break;
|
||||
#endif
|
||||
case 'l':
|
||||
/*
|
||||
* try to link src to dest with copy (-rw)
|
||||
*/
|
||||
lflag = 1;
|
||||
flg |= LF;
|
||||
break;
|
||||
case 'm':
|
||||
/*
|
||||
* preserve mtime
|
||||
*/
|
||||
flg |= PF;
|
||||
pmtime = 1;
|
||||
break;
|
||||
case 'o':
|
||||
/*
|
||||
* write an archive
|
||||
*/
|
||||
act = ARCHIVE;
|
||||
frmt = &(fsub[F_SV4CRC]);
|
||||
flg |= WF;
|
||||
break;
|
||||
case 'p':
|
||||
/*
|
||||
* cpio -p is like pax -rw
|
||||
*/
|
||||
act = COPY;
|
||||
flg |= RF | WF;
|
||||
break;
|
||||
case 'r':
|
||||
/*
|
||||
* interactive file rename
|
||||
*/
|
||||
iflag = 1;
|
||||
flg |= IF;
|
||||
break;
|
||||
#ifdef notyet
|
||||
case 's':
|
||||
/*
|
||||
* swap bytes after reading data
|
||||
*/
|
||||
break;
|
||||
#endif
|
||||
case 't':
|
||||
/*
|
||||
* list contents of archive
|
||||
*/
|
||||
act = LIST;
|
||||
listf = stdout;
|
||||
break;
|
||||
case 'u':
|
||||
/*
|
||||
* don't ignore those older files
|
||||
*/
|
||||
uflag = 0;
|
||||
kflag = 0;
|
||||
flg |= UF;
|
||||
break;
|
||||
case 'v':
|
||||
/*
|
||||
* verbose operation mode
|
||||
*/
|
||||
vflag = 1;
|
||||
flg |= VF;
|
||||
break;
|
||||
case 'z':
|
||||
/*
|
||||
* use gzip. Non standard option.
|
||||
*/
|
||||
gzip_program = GZIP_CMD;
|
||||
break;
|
||||
case 'A':
|
||||
/*
|
||||
* append to an archive
|
||||
|
@ -1020,11 +1375,24 @@ cpio_options(int argc, char **argv)
|
|||
tar_usage();
|
||||
}
|
||||
break;
|
||||
#ifdef notyet
|
||||
case 'E':
|
||||
arg = optarg;
|
||||
/*
|
||||
* file with patterns to extract or list
|
||||
*/
|
||||
if ((fp = fopen(optarg, "r")) == NULL) {
|
||||
tty_warn(1, "Unable to open file '%s' for read",
|
||||
optarg);
|
||||
cpio_usage();
|
||||
}
|
||||
while ((str = getline(fp)) != NULL) {
|
||||
pat_add(str, NULL);
|
||||
}
|
||||
fclose(fp);
|
||||
if (getline_error) {
|
||||
tty_warn(1, "Problem with file '%s'", optarg);
|
||||
cpio_usage();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 'H':
|
||||
/*
|
||||
* specify an archive format on write
|
||||
|
@ -1052,7 +1420,7 @@ cpio_options(int argc, char **argv)
|
|||
/*
|
||||
* treat a - as stdin
|
||||
*/
|
||||
arcname = (char *)0;
|
||||
arcname = NULL;
|
||||
break;
|
||||
}
|
||||
arcname = optarg;
|
||||
|
@ -1073,103 +1441,26 @@ cpio_options(int argc, char **argv)
|
|||
break;
|
||||
#endif
|
||||
case 'S':
|
||||
/*
|
||||
* swap halfwords after reading data
|
||||
*/
|
||||
cpio_swp_head = 1;
|
||||
break;
|
||||
#ifdef notyet
|
||||
case 'V':
|
||||
break;
|
||||
#endif
|
||||
case 'a':
|
||||
case 'Z':
|
||||
/*
|
||||
* preserve access time on filesystem nodes we read
|
||||
* use compress. Non standard option.
|
||||
*/
|
||||
tflag = 1;
|
||||
flg |= TF;
|
||||
gzip_program = COMPRESS_CMD;
|
||||
break;
|
||||
#ifdef notyet
|
||||
case 'b':
|
||||
break;
|
||||
#endif
|
||||
case 'c':
|
||||
frmt = &fsub[F_SV4CPIO];
|
||||
break;
|
||||
case 'd':
|
||||
case '6':
|
||||
/*
|
||||
* pax does this by default ..
|
||||
* process Version 6 cpio format
|
||||
*/
|
||||
flg |= RF;
|
||||
break;
|
||||
case 'f':
|
||||
/*
|
||||
* inverse match on patterns
|
||||
*/
|
||||
cflag = 1;
|
||||
flg |= CF;
|
||||
break;
|
||||
case 'i':
|
||||
/*
|
||||
* read the archive
|
||||
*/
|
||||
flg |= RF;
|
||||
break;
|
||||
#ifdef notyet
|
||||
case 'k':
|
||||
break;
|
||||
#endif
|
||||
case 'l':
|
||||
/*
|
||||
* try to link src to dest with copy (-rw)
|
||||
*/
|
||||
lflag = 1;
|
||||
flg |= LF;
|
||||
break;
|
||||
case 'm':
|
||||
/*
|
||||
* preserve mtime
|
||||
*/
|
||||
flg |= PF;
|
||||
pmtime = 1;
|
||||
break;
|
||||
case 'o':
|
||||
/*
|
||||
* write an archive
|
||||
*/
|
||||
flg |= WF;
|
||||
break;
|
||||
case 'p':
|
||||
/*
|
||||
* cpio -p is like pax -rw
|
||||
*/
|
||||
flg |= RF | WF;
|
||||
break;
|
||||
case 'r':
|
||||
/*
|
||||
* interactive file rename
|
||||
*/
|
||||
iflag = 1;
|
||||
flg |= IF;
|
||||
break;
|
||||
#ifdef notyet
|
||||
case 's':
|
||||
break;
|
||||
#endif
|
||||
case 't':
|
||||
act = LIST;
|
||||
break;
|
||||
case 'u':
|
||||
/*
|
||||
* don't ignore those older files
|
||||
*/
|
||||
uflag = 0;
|
||||
flg |= UF;
|
||||
break;
|
||||
case 'v':
|
||||
/*
|
||||
* verbose operation mode
|
||||
*/
|
||||
vflag = 1;
|
||||
flg |= VF;
|
||||
break;
|
||||
frmt = &(fsub[F_BCPIO]);
|
||||
default:
|
||||
cpio_usage();
|
||||
break;
|
||||
|
@ -1229,13 +1520,26 @@ cpio_options(int argc, char **argv)
|
|||
/* FALLTHROUGH */
|
||||
case ARCHIVE:
|
||||
case APPND:
|
||||
for (; optind < argc; optind++)
|
||||
if (ftree_add(argv[optind], 0) < 0)
|
||||
cpio_usage();
|
||||
if (argc != optind) {
|
||||
for (; optind < argc; optind++)
|
||||
if (ftree_add(argv[optind], 0) < 0)
|
||||
cpio_usage();
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* no read errors allowed on updates/append operation!
|
||||
*/
|
||||
maxflt = 0;
|
||||
while ((str = getline(stdin)) != NULL) {
|
||||
ftree_add(str, NULL);
|
||||
}
|
||||
if (getline_error) {
|
||||
tty_warn(1, "Problem while reading stdin");
|
||||
cpio_usage();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cpio_usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1329,12 +1633,17 @@ opt_add(const char *str)
|
|||
char *frpt;
|
||||
char *pt;
|
||||
char *endpt;
|
||||
char *dstr;
|
||||
|
||||
if ((str == NULL) || (*str == '\0')) {
|
||||
tty_warn(0, "Invalid option name");
|
||||
return(-1);
|
||||
}
|
||||
frpt = endpt = strdup(str);
|
||||
if ((dstr = strdup(str)) == NULL) {
|
||||
tty_warn(0, "Unable to allocate space for option list");
|
||||
return(-1);
|
||||
}
|
||||
frpt = endpt = dstr;
|
||||
|
||||
/*
|
||||
* break into name and values pieces and stuff each one into a
|
||||
|
@ -1346,10 +1655,12 @@ opt_add(const char *str)
|
|||
*endpt = '\0';
|
||||
if ((pt = strchr(frpt, '=')) == NULL) {
|
||||
tty_warn(0, "Invalid options format");
|
||||
free(dstr);
|
||||
return(-1);
|
||||
}
|
||||
if ((opt = (OPLIST *)malloc(sizeof(OPLIST))) == NULL) {
|
||||
tty_warn(0, "Unable to allocate space for option list");
|
||||
free(dstr);
|
||||
return(-1);
|
||||
}
|
||||
*pt++ = '\0';
|
||||
|
@ -1442,6 +1753,29 @@ str_offt(char *val)
|
|||
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.
|
||||
|
@ -1531,48 +1865,3 @@ cpio_usage(void)
|
|||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* opt_chdir
|
||||
* call ftree_add or pat_add, depending on archive type.
|
||||
*
|
||||
* Returns: -1 for listing, else what ftree_add or pat_add returned.
|
||||
*/
|
||||
|
||||
int
|
||||
opt_chdir(char *name)
|
||||
{
|
||||
switch (act) {
|
||||
default:
|
||||
return (-1);
|
||||
break;
|
||||
case ARCHIVE:
|
||||
case APPND:
|
||||
return (ftree_add(name, 1));
|
||||
break;
|
||||
case EXTRACT:
|
||||
return (pat_add(name, 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* checkpositionalminusC(argvp, addfunc)
|
||||
*/
|
||||
|
||||
void
|
||||
checkpositionalminusC(char ***argvp, int (*addfunc)(char *, int))
|
||||
{
|
||||
while (**argvp != (char *)NULL) {
|
||||
if (!strcmp(**argvp, "-C")) {
|
||||
/* XXX should be allow for positional -C/dir, too? */
|
||||
if ((*addfunc)(*++*argvp, 1) < 0) {
|
||||
tar_usage();
|
||||
}
|
||||
++*argvp;
|
||||
continue;
|
||||
}
|
||||
if ((*addfunc)(*(*argvp)++, 0) < 0)
|
||||
tar_usage();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pat_rep.c,v 1.13 2002/01/31 19:27:54 tv Exp $ */
|
||||
/* $NetBSD: pat_rep.c,v 1.14 2002/10/12 15:39:30 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)pat_rep.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: pat_rep.c,v 1.13 2002/01/31 19:27:54 tv Exp $");
|
||||
__RCSID("$NetBSD: pat_rep.c,v 1.14 2002/10/12 15:39:30 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -77,7 +77,7 @@ static PATTERN *pattail = NULL; /* file pattern match list tail */
|
|||
static REPLACE *rephead = NULL; /* replacement string list head */
|
||||
static REPLACE *reptail = NULL; /* replacement string list tail */
|
||||
|
||||
static int rep_name(char *, int *, int);
|
||||
static int rep_name(char *, size_t, int *, int);
|
||||
static int tty_rename(ARCHD *);
|
||||
static int fix_path(char *, int *, char *, int);
|
||||
static int fn_match(char *, char *, char **);
|
||||
|
@ -125,13 +125,17 @@ rep_add(char *str)
|
|||
|
||||
/*
|
||||
* first character in the string specifies what the delimiter is for
|
||||
* this expression. find the end and middle, from the end. this
|
||||
* allows the string to be something like /foo\/bar//, but will still
|
||||
* fail on /foo\/bar/foo\/baz/. XXX need to parse the RE to properly
|
||||
* do this!
|
||||
* this expression.
|
||||
*/
|
||||
if ((pt2 = strrchr(str+1, *str)) == NULL || pt2 == str+1 ||
|
||||
(*pt2 = '\0') || (pt1 = strrchr(str+1, *str)) == NULL) {
|
||||
for (pt1 = str+1; *pt1; pt1++) {
|
||||
if (*pt1 == '\\') {
|
||||
pt1++;
|
||||
continue;
|
||||
}
|
||||
if (*pt1 == *str)
|
||||
break;
|
||||
}
|
||||
if (pt1 == NULL) {
|
||||
tty_warn(1, "Invalid replacement string %s", str);
|
||||
return(-1);
|
||||
}
|
||||
|
@ -164,6 +168,26 @@ rep_add(char *str)
|
|||
* we then point the node at the new substitution string
|
||||
*/
|
||||
*pt1++ = *str;
|
||||
for (pt2 = pt1; *pt2; pt2++) {
|
||||
if (*pt2 == '\\') {
|
||||
pt2++;
|
||||
continue;
|
||||
}
|
||||
if (*pt2 == *str)
|
||||
break;
|
||||
}
|
||||
if (pt2 == NULL) {
|
||||
#ifdef NET2_REGEX
|
||||
(void)free((char *)rep->rcmp);
|
||||
#else
|
||||
regfree(&(rep->rcmp));
|
||||
#endif
|
||||
(void)free((char *)rep);
|
||||
tty_warn(1, "Invalid replacement string %s", str);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
*pt2 = '\0';
|
||||
rep->nstr = pt1;
|
||||
pt1 = pt2++;
|
||||
rep->flgs = 0;
|
||||
|
@ -217,13 +241,12 @@ rep_add(char *str)
|
|||
* supplied to pax, all members in the archive will be selected (and the
|
||||
* pattern match list is empty).
|
||||
*
|
||||
* if ischdir is !0, a special entry used for chdiring is created.
|
||||
* Return:
|
||||
* 0 if the pattern was added to the list, -1 otherwise
|
||||
*/
|
||||
|
||||
int
|
||||
pat_add(char *str, int ischdir)
|
||||
pat_add(char *str, char *chdn)
|
||||
{
|
||||
PATTERN *pt;
|
||||
|
||||
|
@ -249,7 +272,8 @@ pat_add(char *str, int ischdir)
|
|||
pt->pend = NULL;
|
||||
pt->plen = strlen(str);
|
||||
pt->fow = NULL;
|
||||
pt->flgs = ischdir ? PTCHDIR : 0;
|
||||
pt->flgs = 0;
|
||||
pt->chdname = chdn;
|
||||
if (pathead == NULL) {
|
||||
pattail = pathead = pt;
|
||||
return(0);
|
||||
|
@ -276,7 +300,7 @@ pat_chk(void)
|
|||
* if not complain
|
||||
*/
|
||||
for (pt = pathead; pt != NULL; pt = pt->fow) {
|
||||
if (pt->flgs & (MTCH|PTCHDIR))
|
||||
if (pt->flgs & MTCH)
|
||||
continue;
|
||||
if (!wban) {
|
||||
tty_warn(1, "WARNING! These patterns were not matched:");
|
||||
|
@ -442,13 +466,7 @@ pat_match(ARCHD *arcn)
|
|||
* have to search down the list one at a time looking for a match.
|
||||
*/
|
||||
pt = pathead;
|
||||
fchdir(curdirfd);
|
||||
while (pt != NULL) {
|
||||
if (pt->flgs & PTCHDIR) {
|
||||
ar_dochdir(pt->pstr);
|
||||
pt = pt->fow;
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* check for a file name match unless we have DIR_MTCH set in
|
||||
* this pattern then we want a prefix match
|
||||
|
@ -620,6 +638,38 @@ mod_name(ARCHD *arcn)
|
|||
{
|
||||
int res = 0;
|
||||
|
||||
/*
|
||||
* Strip off leading '/' if appropriate.
|
||||
* Currently, this option is only set for the tar format.
|
||||
*/
|
||||
if (rmleadslash && arcn->name[0] == '/') {
|
||||
if (arcn->name[1] == '\0') {
|
||||
arcn->name[0] = '.';
|
||||
} else {
|
||||
(void)memmove(arcn->name, &arcn->name[1],
|
||||
strlen(arcn->name));
|
||||
arcn->nlen--;
|
||||
}
|
||||
if (rmleadslash < 2) {
|
||||
rmleadslash = 2;
|
||||
tty_warn(0, "Removing leading / from absolute path names in the archive");
|
||||
}
|
||||
}
|
||||
if (rmleadslash && arcn->ln_name[0] == '/' &&
|
||||
(arcn->type == PAX_HLK || arcn->type == PAX_HRG)) {
|
||||
if (arcn->ln_name[1] == '\0') {
|
||||
arcn->ln_name[0] = '.';
|
||||
} else {
|
||||
(void)memmove(arcn->ln_name, &arcn->ln_name[1],
|
||||
strlen(arcn->ln_name));
|
||||
arcn->ln_nlen--;
|
||||
}
|
||||
if (rmleadslash < 2) {
|
||||
rmleadslash = 2;
|
||||
tty_warn(0, "Removing leading / from absolute path names in the archive");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* IMPORTANT: We have a problem. what do we do with symlinks?
|
||||
* Modifying a hard link name makes sense, as we know the file it
|
||||
|
@ -644,12 +694,14 @@ mod_name(ARCHD *arcn)
|
|||
* we have replacement strings, modify the name and the link
|
||||
* name if any.
|
||||
*/
|
||||
if ((res = rep_name(arcn->name, &(arcn->nlen), 1)) != 0)
|
||||
if ((res = rep_name(arcn->name, sizeof(arcn->name),
|
||||
&(arcn->nlen), 1)) != 0)
|
||||
return(res);
|
||||
|
||||
if (((arcn->type == PAX_SLK) || (arcn->type == PAX_HLK) ||
|
||||
(arcn->type == PAX_HRG)) &&
|
||||
((res = rep_name(arcn->ln_name, &(arcn->ln_nlen), 0)) != 0))
|
||||
((res = rep_name(arcn->ln_name, sizeof(arcn->ln_name),
|
||||
&(arcn->ln_nlen), 0)) != 0))
|
||||
return(res);
|
||||
}
|
||||
|
||||
|
@ -661,7 +713,7 @@ mod_name(ARCHD *arcn)
|
|||
return(res);
|
||||
if ((arcn->type == PAX_SLK) || (arcn->type == PAX_HLK) ||
|
||||
(arcn->type == PAX_HRG))
|
||||
sub_name(arcn->ln_name, &(arcn->ln_nlen));
|
||||
sub_name(arcn->ln_name, &(arcn->ln_nlen), sizeof(arcn->ln_name));
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
@ -727,7 +779,7 @@ tty_rename(ARCHD *arcn)
|
|||
*/
|
||||
tty_prnt("Processing continues, name changed to: %s\n", tmpname);
|
||||
res = add_name(arcn->name, arcn->nlen, tmpname);
|
||||
arcn->nlen = l_strncpy(arcn->name, tmpname, PAXPATHLEN+1);
|
||||
arcn->nlen = strlcpy(arcn->name, tmpname, sizeof(arcn->name));
|
||||
if (res < 0)
|
||||
return(-1);
|
||||
return(0);
|
||||
|
@ -823,6 +875,7 @@ fix_path( char *or_name, int *or_len, char *dir_name, int dir_len)
|
|||
* --Parameters--
|
||||
* name is the file name we are going to apply the regular expressions to
|
||||
* (and may be modified)
|
||||
* namelen the size of the name buffer.
|
||||
* nlen is the length of this name (and is modified to hold the length of
|
||||
* the final string).
|
||||
* prnt is a flag that says whether to print the final result.
|
||||
|
@ -832,7 +885,7 @@ fix_path( char *or_name, int *or_len, char *dir_name, int dir_len)
|
|||
*/
|
||||
|
||||
static int
|
||||
rep_name(char *name, int *nlen, int prnt)
|
||||
rep_name(char *name, size_t namelen, int *nlen, int prnt)
|
||||
{
|
||||
REPLACE *pt;
|
||||
char *inpt;
|
||||
|
@ -983,7 +1036,7 @@ rep_name(char *name, int *nlen, int prnt)
|
|||
*/
|
||||
if (*nname == '\0')
|
||||
return(1);
|
||||
*nlen = l_strncpy(name, nname, PAXPATHLEN + 1);
|
||||
*nlen = strlcpy(name, nname, namelen);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
@ -1028,9 +1081,8 @@ resub(regexp *prog, char *src, char *dest, char *destend)
|
|||
* fail if we run out of space or the match string is damaged
|
||||
*/
|
||||
if (len > (destend - dpt))
|
||||
len = destend - dpt;
|
||||
if (l_strncpy(dpt, prog->startp[no], len) != len)
|
||||
return(-1);
|
||||
return (-1);
|
||||
strncpy(dpt, prog->startp[no], len);
|
||||
dpt += len;
|
||||
}
|
||||
return(dpt - dest);
|
||||
|
@ -1096,9 +1148,8 @@ resub(regex_t *rp, regmatch_t *pm, char *src, char *txt, char *dest,
|
|||
* fail if we run out of space or the match string is damaged
|
||||
*/
|
||||
if (len > (destend - dpt))
|
||||
len = destend - dpt;
|
||||
if (l_strncpy(dpt, txt + pmpt->rm_so, len) != len)
|
||||
return(-1);
|
||||
return -1;
|
||||
strncpy(dpt, txt + pmpt->rm_so, len);
|
||||
dpt += len;
|
||||
}
|
||||
return(dpt - dest);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pax.c,v 1.17 2002/01/31 19:27:54 tv Exp $ */
|
||||
/* $NetBSD: pax.c,v 1.18 2002/10/12 15:39:30 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -47,20 +47,22 @@ __COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)pax.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: pax.c,v 1.17 2002/01/31 19:27:54 tv Exp $");
|
||||
__RCSID("$NetBSD: pax.c,v 1.18 2002/10/12 15:39:30 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <paths.h>
|
||||
#include "pax.h"
|
||||
#include "extern.h"
|
||||
static int gen_init(void);
|
||||
|
@ -75,6 +77,7 @@ static int gen_init(void);
|
|||
int act = DEFOP; /* read/write/append/copy */
|
||||
FSUB *frmt = NULL; /* archive format type */
|
||||
int cflag; /* match all EXCEPT pattern/file */
|
||||
int cwdfd; /* starting cwd */
|
||||
int dflag; /* directory member match only */
|
||||
int iflag; /* interactive file/archive rename */
|
||||
int kflag; /* do not overwrite existing files */
|
||||
|
@ -95,14 +98,23 @@ int Zflag; /* same as uflg except after name mode */
|
|||
int vfpart; /* is partial verbose output in progress */
|
||||
int patime = 1; /* preserve file access time */
|
||||
int pmtime = 1; /* preserve file modification times */
|
||||
int nodirs; /* do not create directories as needed */
|
||||
int pfflags = 1; /* preserve file flags */
|
||||
int pmode; /* preserve file mode bits */
|
||||
int pids; /* preserve file uid/gid */
|
||||
int rmleadslash = 0; /* remove leading '/' from pathnames */
|
||||
int exit_val; /* exit value */
|
||||
int docrc; /* check/create file crc */
|
||||
char *dirptr; /* destination dir in a copy */
|
||||
char *ltmfrmt; /* -v locale time format (if any) */
|
||||
char *argv0; /* root of argv[0] */
|
||||
sigset_t s_mask; /* signal mask for cleanup critical sect */
|
||||
FILE *listf = stderr; /* file pointer to print file list to */
|
||||
char *tempfile; /* tempfile to use for mkstemp(3) */
|
||||
char *tempbase; /* basename of tempfile to use for mkstemp(3) */
|
||||
int forcelocal; /* force local operation even if the name
|
||||
* contains a :
|
||||
*/
|
||||
|
||||
/*
|
||||
* PAX - Portable Archive Interchange
|
||||
|
@ -227,6 +239,36 @@ sigset_t s_mask; /* signal mask for cleanup critical sect */
|
|||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *tmpdir;
|
||||
size_t tdlen;
|
||||
|
||||
/*
|
||||
* Keep a reference to cwd, so we can always come back home.
|
||||
*/
|
||||
cwdfd = open(".", O_RDONLY);
|
||||
if (cwdfd < 0) {
|
||||
syswarn(0, errno, "Can't open current working directory.");
|
||||
return(exit_val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Where should we put temporary files?
|
||||
*/
|
||||
if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0')
|
||||
tmpdir = _PATH_TMP;
|
||||
tdlen = strlen(tmpdir);
|
||||
while(tdlen > 0 && tmpdir[tdlen - 1] == '/')
|
||||
tdlen--;
|
||||
tempfile = malloc(tdlen + 1 + sizeof(_TFILE_BASE));
|
||||
if (tempfile == NULL) {
|
||||
tty_warn(1, "Cannot allocate memory for temp file name.");
|
||||
return(exit_val);
|
||||
}
|
||||
if (tdlen)
|
||||
memcpy(tempfile, tmpdir, tdlen);
|
||||
tempbase = tempfile + tdlen;
|
||||
*tempbase++ = '/';
|
||||
|
||||
/*
|
||||
* parse options, determine operational mode, general init
|
||||
*/
|
||||
|
@ -249,6 +291,8 @@ main(int argc, char **argv)
|
|||
archive();
|
||||
break;
|
||||
case APPND:
|
||||
if (gzip_program != NULL)
|
||||
err(1, "can not gzip while appending");
|
||||
append();
|
||||
break;
|
||||
case COPY:
|
||||
|
@ -290,7 +334,6 @@ sig_cleanup(int which_sig)
|
|||
if (tflag)
|
||||
atdir_end();
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -342,6 +385,13 @@ gen_init(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Handle posix locale
|
||||
*
|
||||
* set user defines time printing format for -v option
|
||||
*/
|
||||
ltmfrmt = getenv("LC_TIME");
|
||||
|
||||
/*
|
||||
* signal handling to reset stored directory times and modes. Since
|
||||
* we deal with broken pipes via failed writes we ignore it. We also
|
||||
|
@ -355,6 +405,7 @@ gen_init(void)
|
|||
tty_warn(1, "Unable to set up signal mask");
|
||||
return(-1);
|
||||
}
|
||||
memset(&n_hand, 0, sizeof n_hand);
|
||||
n_hand.sa_mask = s_mask;
|
||||
n_hand.sa_flags = 0;
|
||||
n_hand.sa_handler = sig_cleanup;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pax.h,v 1.13 2002/01/31 22:43:36 tv Exp $ */
|
||||
/* $NetBSD: pax.h,v 1.14 2002/10/12 15:39:30 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -80,6 +80,7 @@
|
|||
#define ISBLK 2 /* block device */
|
||||
#define ISTAPE 3 /* tape drive */
|
||||
#define ISPIPE 4 /* pipe/socket */
|
||||
#define ISRMT 5 /* rmt */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -90,11 +91,11 @@
|
|||
typedef struct pattern {
|
||||
char *pstr; /* pattern to match, user supplied */
|
||||
char *pend; /* end of a prefix match */
|
||||
char *chdname; /* the dir to change to if not NULL. */
|
||||
int plen; /* length of pstr */
|
||||
int flgs; /* processing/state flags */
|
||||
#define MTCH 0x1 /* pattern has been matched */
|
||||
#define DIR_MTCH 0x2 /* pattern matched a directory */
|
||||
#define PTCHDIR 0x4 /* not pattern but chdir */
|
||||
struct pattern *fow; /* next pattern */
|
||||
} PATTERN;
|
||||
|
||||
|
@ -259,7 +260,7 @@ typedef struct oplist {
|
|||
* Pathname base component of the temporary file template, to be created in
|
||||
* ${TMPDIR} or, as a fall-back, _PATH_TMP.
|
||||
*/
|
||||
#define TMPFILE "paxXXXXXX"
|
||||
#define _TFILE_BASE "paxXXXXXXXXXX"
|
||||
|
||||
/*
|
||||
* Macros to manipulate off_t as a unsigned long or unsigned long long
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tables.c,v 1.17 2002/01/31 19:27:54 tv Exp $ */
|
||||
/* $NetBSD: tables.c,v 1.18 2002/10/12 15:39:30 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)tables.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: tables.c,v 1.17 2002/01/31 19:27:54 tv Exp $");
|
||||
__RCSID("$NetBSD: tables.c,v 1.18 2002/10/12 15:39:30 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -176,8 +176,8 @@ chk_lnk(ARCHD *arcn)
|
|||
* handle hardlinks to regular files differently than
|
||||
* other links.
|
||||
*/
|
||||
arcn->ln_nlen = l_strncpy(arcn->ln_name, pt->name,
|
||||
PAXPATHLEN+1);
|
||||
arcn->ln_nlen = strlcpy(arcn->ln_name, pt->name,
|
||||
sizeof(arcn->ln_name));
|
||||
if (arcn->type == PAX_REG)
|
||||
arcn->type = PAX_HRG;
|
||||
else
|
||||
|
@ -340,9 +340,6 @@ lnk_end(void)
|
|||
int
|
||||
ftime_start(void)
|
||||
{
|
||||
const char *tmpdir;
|
||||
char template[MAXPATHLEN];
|
||||
|
||||
if (ftab != NULL)
|
||||
return(0);
|
||||
if ((ftab = (FTM **)calloc(F_TAB_SZ, sizeof(FTM *))) == NULL) {
|
||||
|
@ -354,16 +351,14 @@ ftime_start(void)
|
|||
* get random name and create temporary scratch file, unlink name
|
||||
* so it will get removed on exit
|
||||
*/
|
||||
if ((tmpdir = getenv("TMPDIR")) == NULL)
|
||||
tmpdir = _PATH_TMP;
|
||||
(void)snprintf(template, sizeof(template), "%s/%s", tmpdir, TMPFILE);
|
||||
if ((ffd = mkstemp(template)) == -1) {
|
||||
memcpy(tempbase, _TFILE_BASE, sizeof(_TFILE_BASE));
|
||||
if ((ffd = mkstemp(tempfile)) == -1) {
|
||||
syswarn(1, errno, "Unable to create temporary file: %s",
|
||||
template);
|
||||
tempfile);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
(void)unlink(template);
|
||||
(void)unlink(tempfile);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -589,7 +584,7 @@ add_name(char *oname, int onamelen, char *nname)
|
|||
*/
|
||||
|
||||
void
|
||||
sub_name(char *oname, int *onamelen)
|
||||
sub_name(char *oname, int *onamelen, size_t onamesize)
|
||||
{
|
||||
NAMT *pt;
|
||||
u_int indx;
|
||||
|
@ -612,7 +607,7 @@ sub_name(char *oname, int *onamelen)
|
|||
* found it, replace it with the new name
|
||||
* and return (we know that oname has enough space)
|
||||
*/
|
||||
*onamelen = l_strncpy(oname, pt->nname, PAXPATHLEN+1);
|
||||
*onamelen = strlcpy(oname, pt->nname, onamesize);
|
||||
return;
|
||||
}
|
||||
pt = pt->fow;
|
||||
|
@ -1112,24 +1107,19 @@ int
|
|||
dir_start(void)
|
||||
{
|
||||
#ifdef DIRS_USE_FILE
|
||||
const char *tmpdir;
|
||||
char template[MAXPATHLEN];
|
||||
|
||||
if (dirfd != -1)
|
||||
return(0);
|
||||
|
||||
/*
|
||||
* unlink the file so it goes away at termination by itself
|
||||
*/
|
||||
if ((tmpdir = getenv("TMPDIR")) == NULL)
|
||||
tmpdir = _PATH_TMP;
|
||||
(void)snprintf(template, sizeof(template), "%s/%s", tmpdir, TMPFILE);
|
||||
if ((dirfd = mkstemp(template)) >= 0) {
|
||||
(void)unlink(template);
|
||||
memcpy(tempbase, _TFILE_BASE, sizeof(_TFILE_BASE));
|
||||
if ((dirfd = mkstemp(tempfile)) >= 0) {
|
||||
(void)unlink(tempfile);
|
||||
return(0);
|
||||
}
|
||||
tty_warn(1, "Unable to create temporary file for directory times: %s",
|
||||
template);
|
||||
tempfile);
|
||||
return(-1);
|
||||
#else
|
||||
return (0);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tar.c,v 1.22 2002/10/11 13:07:36 christos Exp $ */
|
||||
/* $NetBSD: tar.c,v 1.23 2002/10/12 15:39:30 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)tar.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: tar.c,v 1.22 2002/10/11 13:07:36 christos Exp $");
|
||||
__RCSID("$NetBSD: tar.c,v 1.23 2002/10/12 15:39:30 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -650,7 +650,12 @@ tar_wr(ARCHD *arcn)
|
|||
*/
|
||||
if (ul_oct(tar_chksm(hdblk, sizeof(HD_TAR)), hd->chksum,
|
||||
sizeof(hd->chksum), 3))
|
||||
goto out;
|
||||
goto out; /* XXX Something's wrong here
|
||||
* because a zero-byte file can
|
||||
* cause this to be done and
|
||||
* yet the resulting warning
|
||||
* seems incorrect */
|
||||
|
||||
if (wr_rdbuf(hdblk, sizeof(HD_TAR)) < 0)
|
||||
return(-1);
|
||||
if (wr_skip((off_t)(BLKMULT - sizeof(HD_TAR))) < 0)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tar.h,v 1.5 2000/02/17 03:12:27 itohy Exp $ */
|
||||
/* $NetBSD: tar.h,v 1.6 2002/10/12 15:39:30 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -119,12 +119,12 @@ typedef struct {
|
|||
/*
|
||||
* default device names
|
||||
*/
|
||||
#define DEV_0 "/dev/rmt0"
|
||||
#define DEV_1 "/dev/rmt1"
|
||||
#define DEV_4 "/dev/rmt4"
|
||||
#define DEV_5 "/dev/rmt5"
|
||||
#define DEV_7 "/dev/rmt7"
|
||||
#define DEV_8 "/dev/rmt8"
|
||||
#define DEV_0 "/dev/rst0"
|
||||
#define DEV_1 "/dev/rst1"
|
||||
#define DEV_4 "/dev/rst4"
|
||||
#define DEV_5 "/dev/rst5"
|
||||
#define DEV_7 "/dev/rst7"
|
||||
#define DEV_8 "/dev/rst8"
|
||||
#endif /* _PAX_ */
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue