Upgrading pax.
This also means importing librmt. Change-Id: Ie5b314aeaad28dca46acb64f20f2d70746ea52d0
This commit is contained in:
@@ -2,6 +2,6 @@
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
SUBDIR= cat date ed mkdir rm rmdir
|
||||
SUBDIR= cat date ed mkdir pax rm rmdir
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
||||
61
bin/pax/Makefile
Normal file
61
bin/pax/Makefile
Normal file
@@ -0,0 +1,61 @@
|
||||
# $NetBSD: Makefile,v 1.39 2010/04/23 19:41:02 joerg Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
PROG= pax
|
||||
SRCS= ar_io.c ar_subs.c buf_subs.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
|
||||
|
||||
.if defined(SMALLPROG)
|
||||
CPPFLAGS+= -DSMALL -DNO_CPIO
|
||||
.else
|
||||
SRCS+= getid.c spec.c misc.c pack_dev.c cpio.c
|
||||
CPPFLAGS+= -I${NETBSDSRCDIR}/usr.sbin/mtree \
|
||||
-I${NETBSDSRCDIR}/sbin/mknod
|
||||
.PATH: ${NETBSDSRCDIR}/usr.sbin/mtree \
|
||||
${NETBSDSRCDIR}/sbin/mknod
|
||||
|
||||
.if (${HOSTPROG:U} == "")
|
||||
DPADD+= ${LIBUTIL}
|
||||
LDADD+= -lutil
|
||||
.endif
|
||||
.endif
|
||||
|
||||
MAN= pax.1 tar.1 cpio.1
|
||||
|
||||
.if defined(HOSTPROG)
|
||||
CPPFLAGS+= -DHOSTPROG
|
||||
.else # { ! HOSTPROG
|
||||
|
||||
# XXX: Interix does not have it; we need a conditional for it.
|
||||
CPPFLAGS+= -DHAVE_SYS_MTIO_H
|
||||
|
||||
.if ${MKBSDTAR} == "no"
|
||||
LINKS+= ${BINDIR}/pax ${BINDIR}/tar
|
||||
SYMLINKS+=${BINDIR}/tar /usr/bin/tar
|
||||
.if defined(__MINIX)
|
||||
SYMLINKS+=${BINDIR}/tar /usr/bin/bsdtar
|
||||
.endif
|
||||
|
||||
LINKS+= ${BINDIR}/pax ${BINDIR}/cpio
|
||||
SYMLINKS+=${BINDIR}/cpio /usr/bin/cpio
|
||||
.endif
|
||||
.endif # } ! HOSTPROG
|
||||
|
||||
.if !defined(HOSTPROG) && !defined(SMALLPROG)
|
||||
CPPFLAGS+= -DSUPPORT_RMT
|
||||
|
||||
LDADD+= -lrmt
|
||||
DPADD+= ${LIBRMT}
|
||||
.endif
|
||||
|
||||
.if defined(__MINIX)
|
||||
CPPFLAGS+= -DHOSTPROG
|
||||
CPPFLAGS+= -Dlchown=chown -Dlchmod=chmod
|
||||
DPADD+= ${LIBUTIL}
|
||||
LDADD+= -lutil
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
1727
bin/pax/ar_io.c
Normal file
1727
bin/pax/ar_io.c
Normal file
File diff suppressed because it is too large
Load Diff
1449
bin/pax/ar_subs.c
Normal file
1449
bin/pax/ar_subs.c
Normal file
File diff suppressed because it is too large
Load Diff
1022
bin/pax/buf_subs.c
Normal file
1022
bin/pax/buf_subs.c
Normal file
File diff suppressed because it is too large
Load Diff
306
bin/pax/cpio.1
Normal file
306
bin/pax/cpio.1
Normal file
@@ -0,0 +1,306 @@
|
||||
.\" $NetBSD: cpio.1,v 1.13 2011/06/19 07:34:24 wiz Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1997 SigmaSoft, Th. Lockert
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" OpenBSD: cpio.1,v 1.14 2000/11/10 17:52:02 aaron Exp
|
||||
.\"
|
||||
.Dd June 18, 2011
|
||||
.Dt CPIO 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm cpio
|
||||
.Nd copy file archives in and out
|
||||
.Sh SYNOPSIS
|
||||
.Nm cpio
|
||||
.Fl o
|
||||
.Op Fl AaBcLvZz
|
||||
.Op Fl C Ar bytes
|
||||
.Op Fl F Ar archive
|
||||
.Op Fl H Ar format
|
||||
.Op Fl O Ar archive
|
||||
.Ar "\*[Lt] name-list"
|
||||
.Op Ar "\*[Gt] archive"
|
||||
.Nm cpio
|
||||
.Fl i
|
||||
.Op Fl 6BbcdfmrSstuvZz
|
||||
.Op Fl C Ar bytes
|
||||
.Op Fl E Ar file
|
||||
.Op Fl F Ar archive
|
||||
.Op Fl H Ar format
|
||||
.Op Fl I Ar archive
|
||||
.Op Ar "pattern ..."
|
||||
.Op Ar "\*[Lt] archive"
|
||||
.Nm cpio
|
||||
.Fl p
|
||||
.Op Fl adLlmuv
|
||||
.Ar destination-directory
|
||||
.Ar "\*[Lt] name-list"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
command copies files to and from a
|
||||
.Nm
|
||||
archive.
|
||||
If the archive is of the form:
|
||||
.Ar [[user@]host:]file
|
||||
then the archive will be processed using
|
||||
.Xr rmt 8 .
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl o , Fl Fl create
|
||||
Create an archive.
|
||||
Reads the list of files to store in the
|
||||
archive from standard input, and writes the archive on standard
|
||||
output.
|
||||
.Bl -tag -width Ds
|
||||
.It Fl a , Fl Fl reset-access-time
|
||||
Reset the access times on files that have been copied to the
|
||||
archive.
|
||||
.It Fl A , Fl Fl append
|
||||
Append to the specified archive.
|
||||
.It Fl B
|
||||
Set block size of output to 5120 bytes.
|
||||
.It Fl c
|
||||
Use ASCII format for
|
||||
.Nm
|
||||
header for portability.
|
||||
.It Fl C Ar bytes
|
||||
Set the block size of output to
|
||||
.Ar bytes .
|
||||
.It Fl F Ar archive
|
||||
.It Fl O Ar archive
|
||||
Use the specified file name as the archive to write to.
|
||||
.It Fl H Ar format
|
||||
Write the archive in the specified format.
|
||||
Recognized formats are:
|
||||
.Pp
|
||||
.Bl -tag -width sv4cpio -compact
|
||||
.It Ar bcpio
|
||||
Old binary
|
||||
.Nm
|
||||
format.
|
||||
.It Ar cpio
|
||||
Old octal character
|
||||
.Nm
|
||||
format.
|
||||
.It Ar sv4cpio
|
||||
SVR4 hex
|
||||
.Nm
|
||||
format.
|
||||
.It Ar tar
|
||||
Old tar format.
|
||||
.It Ar ustar
|
||||
POSIX ustar format.
|
||||
.El
|
||||
.It Fl L
|
||||
Follow symbolic links.
|
||||
.It Fl v
|
||||
Be verbose about operations.
|
||||
List filenames as they are written to the archive.
|
||||
.It Fl Fl xz
|
||||
Compress/decompress archive using
|
||||
.Xr xz 1
|
||||
format.
|
||||
.It Fl Z
|
||||
Compress archive using
|
||||
.Xr compress 1
|
||||
format.
|
||||
.It Fl z
|
||||
Compress/decompress archive using
|
||||
.Xr gzip 1
|
||||
format.
|
||||
.El
|
||||
.It Fl i , Fl Fl extract
|
||||
Restore files from an archive.
|
||||
Reads the archive file from
|
||||
standard input and extracts files matching the
|
||||
.Ar patterns
|
||||
that were specified on the command line.
|
||||
.Bl -tag -width Ds
|
||||
.It Fl b
|
||||
Do byte and word swapping after reading in data from the
|
||||
archive, for restoring archives created on systems with
|
||||
a different byte order.
|
||||
.It Fl B
|
||||
Set the block size of the archive being read to 5120 bytes.
|
||||
.It Fl c
|
||||
Expect the archive headers to be in ASCII format.
|
||||
.It Fl C Ar bytes
|
||||
Read archive written with a block size of
|
||||
.Ar bytes .
|
||||
.It Fl d , Fl Fl make-directories
|
||||
Create any intermediate directories as needed during
|
||||
restore.
|
||||
.It Fl E Ar file , Fl Fl pattern-file Ar file
|
||||
Read list of file name patterns to extract or list from
|
||||
.Ar file .
|
||||
.It Fl f , Fl Fl nonmatching
|
||||
Restore all files except those matching the
|
||||
.Ar patterns
|
||||
given on the command line.
|
||||
.It Fl F Ar archive , Fl Fl file Ar archive
|
||||
.It Fl I Ar archive
|
||||
Use the specified file as the input for the archive.
|
||||
.It Fl H Ar format , Fl Fl format Ar format
|
||||
Read an archive of the specified format.
|
||||
Recognized formats are:
|
||||
.Pp
|
||||
.Bl -tag -width sv4cpio -compact
|
||||
.It Ar bcpio
|
||||
Old binary
|
||||
.Nm
|
||||
format.
|
||||
.It Ar cpio
|
||||
Old octal character
|
||||
.Nm
|
||||
format.
|
||||
.It Ar sv4cpio
|
||||
SVR4 hex
|
||||
.Nm
|
||||
format.
|
||||
.It Ar tar
|
||||
Old tar format.
|
||||
.It Ar ustar
|
||||
POSIX ustar format.
|
||||
.El
|
||||
.It Fl m
|
||||
Restore modification times on files.
|
||||
.It Fl r , Fl Fl rename
|
||||
Rename restored files interactively.
|
||||
.It Fl s
|
||||
Swap bytes after reading data from the archive.
|
||||
.It Fl S , Fl Fl swap-halfwords
|
||||
Swap words after reading data from the archive.
|
||||
.It Fl t , Fl Fl list
|
||||
Only list the contents of the archive, no files or
|
||||
directories will be created.
|
||||
.It Fl u , Fl Fl unconditional
|
||||
Overwrite files even when the file in the archive is
|
||||
older than the one that will be overwritten.
|
||||
.It Fl v , Fl Fl verbose
|
||||
Be verbose about operations.
|
||||
List filenames as they are copied in from the archive.
|
||||
.It Fl z
|
||||
Uncompress archive using
|
||||
.Xr gzip 1
|
||||
format.
|
||||
.It Fl Z
|
||||
Uncompress archive using
|
||||
.Xr compress 1
|
||||
format.
|
||||
.It Fl 6
|
||||
Process old-style
|
||||
.Nm
|
||||
format archives.
|
||||
.El
|
||||
.It Fl p , Fl Fl pass-through
|
||||
Copy files from one location to another in a single pass.
|
||||
The list of files to copy are read from standard input and
|
||||
written out to a directory relative to the specified
|
||||
.Ar directory
|
||||
argument.
|
||||
.Bl -tag -width Ds
|
||||
.It Fl a
|
||||
Reset the access times on files that have been copied.
|
||||
.It Fl d
|
||||
Create any intermediate directories as needed to write
|
||||
the files at the new location.
|
||||
.It Fl l , Fl Fl link
|
||||
When possible, link files rather than creating an
|
||||
extra copy.
|
||||
.It Fl L , Fl Fl dereference
|
||||
Follow symbolic links.
|
||||
.It Fl m , Fl Fl preserve-modification-time
|
||||
Restore modification times on files.
|
||||
.It Fl u , Fl Fl unconditional
|
||||
Overwrite files even when the original file being copied is
|
||||
older than the one that will be overwritten.
|
||||
.It Fl v , Fl Fl verbose
|
||||
Be verbose about operations.
|
||||
List filenames as they are copied.
|
||||
.It Fl Fl force-local
|
||||
Do not interpret filenames that contain a
|
||||
.Sq \&:
|
||||
as remote files.
|
||||
.It Fl Fl insecure
|
||||
Normally
|
||||
.Nm
|
||||
ignores filenames that contain
|
||||
.Dq ..
|
||||
as a path component.
|
||||
With this option, files that contain
|
||||
.Dq ..
|
||||
can be processed.
|
||||
.El
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Nm
|
||||
will exit with one of the following values:
|
||||
.Bl -tag -width 2n
|
||||
.It 0
|
||||
All files were processed successfully.
|
||||
.It 1
|
||||
An error occurred.
|
||||
.El
|
||||
.Pp
|
||||
Whenever
|
||||
.Nm
|
||||
cannot create a file or a link when extracting an archive or cannot
|
||||
find a file while writing an archive, or cannot preserve the user
|
||||
ID, group ID, file mode, or access and modification times when the
|
||||
.Fl p
|
||||
option is specified, a diagnostic message is written to standard
|
||||
error and a non-zero exit value will be returned, but processing
|
||||
will continue.
|
||||
In the case where
|
||||
.Nm
|
||||
cannot create a link to a file,
|
||||
.Nm
|
||||
will not create a second copy of the file.
|
||||
.Pp
|
||||
If the extraction of a file from an archive is prematurely terminated
|
||||
by a signal or error,
|
||||
.Nm
|
||||
may have only partially extracted the file the user wanted.
|
||||
Additionally, the file modes of extracted files and directories may
|
||||
have incorrect file bits, and the modification and access times may
|
||||
be wrong.
|
||||
.Pp
|
||||
If the creation of an archive is prematurely terminated by a signal
|
||||
or error,
|
||||
.Nm
|
||||
may have only partially created the archive which may violate the
|
||||
specific archive format specification.
|
||||
.Sh SEE ALSO
|
||||
.Xr pax 1 ,
|
||||
.Xr tar 1
|
||||
.Sh AUTHORS
|
||||
Keith Muller at the University of California, San Diego.
|
||||
.Sh BUGS
|
||||
The
|
||||
.Fl s
|
||||
and
|
||||
.Fl S
|
||||
options are currently not implemented.
|
||||
1134
bin/pax/cpio.c
Normal file
1134
bin/pax/cpio.c
Normal file
File diff suppressed because it is too large
Load Diff
149
bin/pax/cpio.h
Normal file
149
bin/pax/cpio.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/* $NetBSD: cpio.h,v 1.6 2003/10/13 07:41:22 agc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cpio.h 8.1 (Berkeley) 5/31/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Defines common to all versions of cpio
|
||||
*/
|
||||
#define TRAILER "TRAILER!!!" /* name in last archive record */
|
||||
|
||||
/*
|
||||
* Header encoding of the different file types
|
||||
*/
|
||||
#define C_ISDIR 040000 /* Directory */
|
||||
#define C_ISFIFO 010000 /* FIFO */
|
||||
#define C_ISREG 0100000 /* Regular file */
|
||||
#define C_ISBLK 060000 /* Block special file */
|
||||
#define C_ISCHR 020000 /* Character special file */
|
||||
#define C_ISCTG 0110000 /* Reserved for contiguous files */
|
||||
#define C_ISLNK 0120000 /* Reserved for symbolic links */
|
||||
#define C_ISOCK 0140000 /* Reserved for sockets */
|
||||
#define C_IFMT 0170000 /* type of file */
|
||||
|
||||
/*
|
||||
* Data Interchange Format - Extended cpio header format - POSIX 1003.1-1990
|
||||
*/
|
||||
typedef struct {
|
||||
char c_magic[6]; /* magic cookie */
|
||||
char c_dev[6]; /* device number */
|
||||
char c_ino[6]; /* inode number */
|
||||
char c_mode[6]; /* file type/access */
|
||||
char c_uid[6]; /* owners uid */
|
||||
char c_gid[6]; /* owners gid */
|
||||
char c_nlink[6]; /* # of links at archive creation */
|
||||
char c_rdev[6]; /* block/char major/minor # */
|
||||
char c_mtime[11]; /* modification time */
|
||||
char c_namesize[6]; /* length of pathname */
|
||||
char c_filesize[11]; /* length of file in bytes */
|
||||
} HD_CPIO;
|
||||
|
||||
#define MAGIC 070707 /* transportable archive id */
|
||||
|
||||
#ifdef _PAX_
|
||||
#define AMAGIC "070707" /* ascii equivalent string of MAGIC */
|
||||
#define CPIO_MASK 0x3ffff /* bits valid in the dev/ino fields */
|
||||
/* used for dev/inode remaps */
|
||||
#endif /* _PAX_ */
|
||||
|
||||
/*
|
||||
* Binary cpio header structure
|
||||
*
|
||||
* CAUTION! CAUTION! CAUTION!
|
||||
* Each field really represents a 16 bit short (NOT ASCII). Described as
|
||||
* an array of chars in an attempt to improve portability!!
|
||||
*/
|
||||
typedef struct {
|
||||
u_char h_magic[2];
|
||||
u_char h_dev[2];
|
||||
u_char h_ino[2];
|
||||
u_char h_mode[2];
|
||||
u_char h_uid[2];
|
||||
u_char h_gid[2];
|
||||
u_char h_nlink[2];
|
||||
u_char h_rdev[2];
|
||||
u_char h_mtime_1[2];
|
||||
u_char h_mtime_2[2];
|
||||
u_char h_namesize[2];
|
||||
u_char h_filesize_1[2];
|
||||
u_char h_filesize_2[2];
|
||||
} HD_BCPIO;
|
||||
|
||||
#ifdef _PAX_
|
||||
/*
|
||||
* extraction and creation macros for binary cpio
|
||||
*/
|
||||
#define SHRT_EXT(ch) ((((unsigned)(ch)[0])<<8) | (((unsigned)(ch)[1])&0xff))
|
||||
#define RSHRT_EXT(ch) ((((unsigned)(ch)[1])<<8) | (((unsigned)(ch)[0])&0xff))
|
||||
#define CHR_WR_0(val) ((char)(((val) >> 24) & 0xff))
|
||||
#define CHR_WR_1(val) ((char)(((val) >> 16) & 0xff))
|
||||
#define CHR_WR_2(val) ((char)(((val) >> 8) & 0xff))
|
||||
#define CHR_WR_3(val) ((char)((val) & 0xff))
|
||||
|
||||
/*
|
||||
* binary cpio masks and pads
|
||||
*/
|
||||
#define BCPIO_PAD(x) ((2 - ((x) & 1)) & 1) /* pad to next 2 byte word */
|
||||
#define BCPIO_MASK 0xffff /* mask for dev/ino fields */
|
||||
#endif /* _PAX_ */
|
||||
|
||||
/*
|
||||
* System VR4 cpio header structure (with/without file data crc)
|
||||
*/
|
||||
typedef struct {
|
||||
char c_magic[6]; /* magic cookie */
|
||||
char c_ino[8]; /* inode number */
|
||||
char c_mode[8]; /* file type/access */
|
||||
char c_uid[8]; /* owners uid */
|
||||
char c_gid[8]; /* owners gid */
|
||||
char c_nlink[8]; /* # of links at archive creation */
|
||||
char c_mtime[8]; /* modification time */
|
||||
char c_filesize[8]; /* length of file in bytes */
|
||||
char c_maj[8]; /* block/char major # */
|
||||
char c_min[8]; /* block/char minor # */
|
||||
char c_rmaj[8]; /* special file major # */
|
||||
char c_rmin[8]; /* special file minor # */
|
||||
char c_namesize[8]; /* length of pathname */
|
||||
char c_chksum[8]; /* 0 OR CRC of bytes of FILE data */
|
||||
} HD_VCPIO;
|
||||
|
||||
#define VMAGIC 070701 /* sVr4 new portable archive id */
|
||||
#define VCMAGIC 070702 /* sVr4 new portable archive id CRC */
|
||||
#ifdef _PAX_
|
||||
#define AVMAGIC "070701" /* ascii string of above */
|
||||
#define AVCMAGIC "070702" /* ascii string of above */
|
||||
#define VCPIO_PAD(x) ((4 - ((x) & 3)) & 3) /* pad to next 4 byte word */
|
||||
#define VCPIO_MASK 0xffffffff /* mask for dev/ino fields */
|
||||
#endif /* _PAX_ */
|
||||
122
bin/pax/dumptar.c
Normal file
122
bin/pax/dumptar.c
Normal file
@@ -0,0 +1,122 @@
|
||||
/* $NetBSD: dumptar.c,v 1.2 2008/04/28 20:22:51 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "tar.h"
|
||||
|
||||
#define ussum(a) 1
|
||||
|
||||
static char *
|
||||
buf(const char *p, size_t s)
|
||||
{
|
||||
static char buf[1024];
|
||||
(void)snprintf(buf, sizeof(buf), "%s", p);
|
||||
buf[s] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
int
|
||||
intarg(const char *p, size_t s)
|
||||
{
|
||||
char *ep, *b = buf(p, s);
|
||||
int r = (int)strtol(p, &ep, 8);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
usdump(void *p)
|
||||
{
|
||||
HD_USTAR *t = p;
|
||||
int size = intarg(t->size, sizeof(t->size));
|
||||
size = ((size + 511) / 512) * 512 + 512;
|
||||
|
||||
(void)fprintf(stdout, "*****\n");
|
||||
#define PR(a) \
|
||||
(void)fprintf(stdout, #a "=%s\n", buf(t->a, sizeof(t->a)));
|
||||
#define IPR(a) \
|
||||
(void)fprintf(stdout, #a "=%d\n", intarg(t->a, sizeof(t->a)));
|
||||
#define OPR(a) \
|
||||
(void)fprintf(stdout, #a "=%o\n", intarg(t->a, sizeof(t->a)));
|
||||
PR(name);
|
||||
OPR(mode);
|
||||
IPR(uid);
|
||||
IPR(gid);
|
||||
IPR(size);
|
||||
OPR(mtime);
|
||||
OPR(chksum);
|
||||
(void)fprintf(stdout, "typeflag=%c\n", t->typeflag);
|
||||
PR(linkname);
|
||||
PR(magic);
|
||||
PR(version);
|
||||
PR(uname);
|
||||
PR(gname);
|
||||
OPR(devmajor);
|
||||
OPR(devminor);
|
||||
PR(prefix);
|
||||
return size;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int fd;
|
||||
struct stat st;
|
||||
char *p, *ep;
|
||||
|
||||
if (argc != 2) {
|
||||
(void)fprintf(stderr, "Usage: %s <filename>\n", getprogname());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((fd = open(argv[1], O_RDONLY)) == -1)
|
||||
err(1, "Cannot open `%s'", argv[1]);
|
||||
|
||||
if (fstat(fd, &st) == -1)
|
||||
err(1, "Cannot fstat `%s'", argv[1]);
|
||||
|
||||
if ((p = mmap(NULL, (size_t)st.st_size, PROT_READ,
|
||||
MAP_FILE|MAP_PRIVATE, fd, (off_t)0)) == MAP_FAILED)
|
||||
err(1, "Cannot mmap `%s'", argv[1]);
|
||||
(void)close(fd);
|
||||
|
||||
ep = (char *)p + (size_t)st.st_size;
|
||||
|
||||
for (; p < ep + sizeof(HD_USTAR);) {
|
||||
if (ussum(p))
|
||||
p += usdump(p);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
326
bin/pax/extern.h
Normal file
326
bin/pax/extern.h
Normal file
@@ -0,0 +1,326 @@
|
||||
/* $NetBSD: extern.h,v 1.59 2012/08/09 08:09:21 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)extern.h 8.2 (Berkeley) 4/18/94
|
||||
*/
|
||||
|
||||
/*
|
||||
* External references from each source file
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <err.h>
|
||||
|
||||
/*
|
||||
* ar_io.c
|
||||
*/
|
||||
extern const char *arcname;
|
||||
extern int curdirfd;
|
||||
extern const char *gzip_program;
|
||||
extern time_t starttime;
|
||||
extern int force_one_volume;
|
||||
extern char *chdname;
|
||||
extern int forcelocal;
|
||||
extern int secure;
|
||||
|
||||
int ar_open(const char *);
|
||||
void ar_close(void);
|
||||
void ar_drain(void);
|
||||
int ar_set_wr(void);
|
||||
int ar_app_ok(void);
|
||||
#ifdef SYS_NO_RESTART
|
||||
int read_with_restart(int, void *, int);
|
||||
int write_with_restart(int, void *, int);
|
||||
#else
|
||||
#define read_with_restart read
|
||||
#define write_with_restart write
|
||||
#endif
|
||||
int xread(int, void *, int);
|
||||
int xwrite(int, void *, int);
|
||||
int ar_read(char *, int);
|
||||
int ar_write(char *, int);
|
||||
int ar_rdsync(void);
|
||||
int ar_fow(off_t, off_t *);
|
||||
int ar_rev(off_t );
|
||||
int ar_next(void);
|
||||
void ar_summary(int);
|
||||
int ar_dochdir(const char *);
|
||||
|
||||
/*
|
||||
* ar_subs.c
|
||||
*/
|
||||
extern u_long flcnt;
|
||||
extern ARCHD archd;
|
||||
int updatepath(void);
|
||||
int dochdir(const char *);
|
||||
int fdochdir(int);
|
||||
int domkdir(const char *, mode_t);
|
||||
int list(void);
|
||||
int extract(void);
|
||||
int append(void);
|
||||
int archive(void);
|
||||
int copy(void);
|
||||
|
||||
/*
|
||||
* buf_subs.c
|
||||
*/
|
||||
extern int blksz;
|
||||
extern int wrblksz;
|
||||
extern int maxflt;
|
||||
extern int rdblksz;
|
||||
extern off_t wrlimit;
|
||||
extern off_t rdcnt;
|
||||
extern off_t wrcnt;
|
||||
int wr_start(void);
|
||||
int rd_start(void);
|
||||
void cp_start(void);
|
||||
int appnd_start(off_t);
|
||||
int rd_sync(void);
|
||||
void pback(char *, int);
|
||||
int rd_skip(off_t);
|
||||
void wr_fin(void);
|
||||
int wr_rdbuf(char *, int);
|
||||
int rd_wrbuf(char *, int);
|
||||
int wr_skip(off_t);
|
||||
int wr_rdfile(ARCHD *, int, off_t *);
|
||||
int rd_wrfile(ARCHD *, int, off_t *);
|
||||
void cp_file(ARCHD *, int, int);
|
||||
int buf_fill(void);
|
||||
int buf_flush(int);
|
||||
|
||||
/*
|
||||
* cpio.c
|
||||
*/
|
||||
extern int cpio_swp_head;
|
||||
int cpio_strd(void);
|
||||
int cpio_subtrail(ARCHD *);
|
||||
int cpio_endwr(void);
|
||||
int cpio_id(char *, int);
|
||||
int cpio_rd(ARCHD *, char *);
|
||||
off_t cpio_endrd(void);
|
||||
int cpio_stwr(void);
|
||||
int cpio_wr(ARCHD *);
|
||||
int vcpio_id(char *, int);
|
||||
int crc_id(char *, int);
|
||||
int crc_strd(void);
|
||||
int vcpio_rd(ARCHD *, char *);
|
||||
off_t vcpio_endrd(void);
|
||||
int crc_stwr(void);
|
||||
int vcpio_wr(ARCHD *);
|
||||
int bcpio_id(char *, int);
|
||||
int bcpio_rd(ARCHD *, char *);
|
||||
off_t bcpio_endrd(void);
|
||||
int bcpio_wr(ARCHD *);
|
||||
|
||||
/*
|
||||
* file_subs.c
|
||||
*/
|
||||
extern char *gnu_name_string, *gnu_link_string;
|
||||
extern size_t gnu_name_length, gnu_link_length;
|
||||
extern char *xtmp_name;
|
||||
int file_creat(ARCHD *, int);
|
||||
void file_close(ARCHD *, int);
|
||||
int lnk_creat(ARCHD *, int *);
|
||||
int cross_lnk(ARCHD *);
|
||||
int chk_same(ARCHD *);
|
||||
int node_creat(ARCHD *);
|
||||
int unlnk_exist(char *, int);
|
||||
int chk_path(char *, uid_t, gid_t);
|
||||
void set_ftime(char *fnm, time_t mtime, time_t atime, int frc, int slk);
|
||||
int set_ids(char *, uid_t, gid_t);
|
||||
void set_pmode(char *, mode_t);
|
||||
void set_chflags(char *fnm, u_int32_t flags);
|
||||
int file_write(int, char *, int, int *, int *, int, char *);
|
||||
void file_flush(int, char *, int);
|
||||
void rdfile_close(ARCHD *, int *);
|
||||
int set_crc(ARCHD *, int);
|
||||
|
||||
/*
|
||||
* ftree.c
|
||||
*/
|
||||
int ftree_start(void);
|
||||
int ftree_add(char *, int);
|
||||
void ftree_sel(ARCHD *);
|
||||
void ftree_chk(void);
|
||||
int next_file(ARCHD *);
|
||||
|
||||
/*
|
||||
* gen_subs.c
|
||||
*/
|
||||
void ls_list(ARCHD *, time_t, FILE *);
|
||||
void ls_tty(ARCHD *);
|
||||
void safe_print(const char *, FILE *);
|
||||
uint32_t asc_u32(char *, int, int);
|
||||
int u32_asc(uintmax_t, char *, int, int);
|
||||
uintmax_t asc_umax(char *, int, int);
|
||||
int umax_asc(uintmax_t, char *, int, int);
|
||||
int check_Aflag(void);
|
||||
|
||||
/*
|
||||
* getoldopt.c
|
||||
*/
|
||||
struct option;
|
||||
int getoldopt(int, char **, const char *, struct option *, int *);
|
||||
|
||||
/*
|
||||
* options.c
|
||||
*/
|
||||
extern FSUB fsub[];
|
||||
extern int ford[];
|
||||
extern int sep;
|
||||
extern int havechd;
|
||||
void options(int, char **);
|
||||
OPLIST * opt_next(void);
|
||||
int bad_opt(void);
|
||||
int mkpath(char *);
|
||||
char *chdname;
|
||||
#if !HAVE_NBTOOL_CONFIG_H
|
||||
int do_chroot;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* pat_rep.c
|
||||
*/
|
||||
int rep_add(char *);
|
||||
int pat_add(char *, char *, int);
|
||||
void pat_chk(void);
|
||||
int pat_sel(ARCHD *);
|
||||
int pat_match(ARCHD *);
|
||||
int mod_name(ARCHD *, int);
|
||||
int set_dest(ARCHD *, char *, int);
|
||||
|
||||
/*
|
||||
* pax.c
|
||||
*/
|
||||
extern int act;
|
||||
extern FSUB *frmt;
|
||||
extern int Aflag;
|
||||
extern int cflag;
|
||||
extern int cwdfd;
|
||||
extern int dflag;
|
||||
extern int iflag;
|
||||
extern int kflag;
|
||||
extern int lflag;
|
||||
extern int nflag;
|
||||
extern int tflag;
|
||||
extern int uflag;
|
||||
extern int vflag;
|
||||
extern int Dflag;
|
||||
extern int Hflag;
|
||||
extern int Lflag;
|
||||
extern int Mflag;
|
||||
extern int Vflag;
|
||||
extern int Xflag;
|
||||
extern int Yflag;
|
||||
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 int to_stdout;
|
||||
extern char *dirptr;
|
||||
extern char *ltmfrmt;
|
||||
extern const char *argv0;
|
||||
extern FILE *listf;
|
||||
extern char *tempfile;
|
||||
extern char *tempbase;
|
||||
|
||||
/*
|
||||
* sel_subs.c
|
||||
*/
|
||||
int sel_chk(ARCHD *);
|
||||
int grp_add(char *);
|
||||
int usr_add(char *);
|
||||
int trng_add(char *);
|
||||
|
||||
/*
|
||||
* tables.c
|
||||
*/
|
||||
int lnk_start(void);
|
||||
int chk_lnk(ARCHD *);
|
||||
void purg_lnk(ARCHD *);
|
||||
void lnk_end(void);
|
||||
int ftime_start(void);
|
||||
int chk_ftime(ARCHD *);
|
||||
int name_start(void);
|
||||
int add_name(char *, int, char *);
|
||||
void sub_name(char *, int *, size_t);
|
||||
int dev_start(void);
|
||||
int add_dev(ARCHD *);
|
||||
int map_dev(ARCHD *, u_long, u_long);
|
||||
int atdir_start(void);
|
||||
void atdir_end(void);
|
||||
void add_atdir(char *, dev_t, ino_t, time_t, time_t);
|
||||
int get_atdir(dev_t, ino_t, time_t *, time_t *);
|
||||
int dir_start(void);
|
||||
void add_dir(char *, int, struct stat *, int);
|
||||
void proc_dir(void);
|
||||
u_int st_hash(char *, int, int);
|
||||
|
||||
/*
|
||||
* tar.c
|
||||
*/
|
||||
extern int is_gnutar;
|
||||
int tar_endwr(void);
|
||||
off_t tar_endrd(void);
|
||||
int tar_trail(char *, int, int *);
|
||||
int tar_id(char *, int);
|
||||
int tar_opt(void);
|
||||
int tar_rd(ARCHD *, char *);
|
||||
int tar_wr(ARCHD *);
|
||||
int ustar_strd(void);
|
||||
int ustar_stwr(void);
|
||||
int ustar_id(char *, int);
|
||||
int ustar_rd(ARCHD *, char *);
|
||||
int ustar_wr(ARCHD *);
|
||||
int tar_gnutar_X_compat(const char *);
|
||||
int tar_gnutar_minus_minus_exclude(const char *);
|
||||
|
||||
/*
|
||||
* tty_subs.c
|
||||
*/
|
||||
int tty_init(void);
|
||||
void tty_prnt(const char *, ...)
|
||||
__attribute__((format (printf, 1, 2)));
|
||||
int tty_read(char *, int);
|
||||
void tty_warn(int, const char *, ...)
|
||||
__attribute__((format (printf, 2, 3)));
|
||||
void syswarn(int, int, const char *, ...)
|
||||
__attribute__((format (printf, 3, 4)));
|
||||
1159
bin/pax/file_subs.c
Normal file
1159
bin/pax/file_subs.c
Normal file
File diff suppressed because it is too large
Load Diff
741
bin/pax/ftree.c
Normal file
741
bin/pax/ftree.c
Normal file
@@ -0,0 +1,741 @@
|
||||
/* $NetBSD: ftree.c,v 1.42 2012/09/27 00:44:59 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Luke Mewburn of Wasabi Systems.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)ftree.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: ftree.c,v 1.42 2012/09/27 00:44:59 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fts.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "pax.h"
|
||||
#include "ftree.h"
|
||||
#include "extern.h"
|
||||
#include "options.h"
|
||||
#ifndef SMALL
|
||||
#include "mtree.h"
|
||||
#endif /* SMALL */
|
||||
|
||||
/*
|
||||
* routines to interface with the fts library function.
|
||||
*
|
||||
* file args supplied to pax are stored on a single linked list (of type FTREE)
|
||||
* and given to fts to be processed one at a time. pax "selects" files from
|
||||
* the expansion of each arg into the corresponding file tree (if the arg is a
|
||||
* directory, otherwise the node itself is just passed to pax). The selection
|
||||
* is modified by the -n and -u flags. The user is informed when a specific
|
||||
* file arg does not generate any selected files. -n keeps expanding the file
|
||||
* tree arg until one of its files is selected, then skips to the next file
|
||||
* arg. when the user does not supply the file trees as command line args to
|
||||
* pax, they are read from stdin
|
||||
*/
|
||||
|
||||
static FTS *ftsp = NULL; /* current FTS handle */
|
||||
static int ftsopts; /* options to be used on fts_open */
|
||||
static char *farray[2]; /* array for passing each arg to fts */
|
||||
static FTREE *fthead = NULL; /* head of linked list of file args */
|
||||
static FTREE *fttail = NULL; /* tail of linked list of file args */
|
||||
static FTREE *ftcur = NULL; /* current file arg being processed */
|
||||
static FTSENT *ftent = NULL; /* current file tree entry */
|
||||
static int ftree_skip; /* when set skip to next file arg */
|
||||
#ifndef SMALL
|
||||
static NODE *ftnode = NULL; /* mtree(8) specfile; used by -M */
|
||||
#endif /* SMALL */
|
||||
|
||||
static int ftree_arg(void);
|
||||
|
||||
#define FTS_ERRNO(x) (x)->fts_errno
|
||||
|
||||
/*
|
||||
* ftree_start()
|
||||
* initialize the options passed to fts_open() during this run of pax
|
||||
* options are based on the selection of pax options by the user
|
||||
* fts_start() also calls fts_arg() to open the first valid file arg. We
|
||||
* also attempt to reset directory access times when -t (tflag) is set.
|
||||
* Return:
|
||||
* 0 if there is at least one valid file arg to process, -1 otherwise
|
||||
*/
|
||||
|
||||
int
|
||||
ftree_start(void)
|
||||
{
|
||||
|
||||
#ifndef SMALL
|
||||
/*
|
||||
* if -M is given, the list of filenames on stdin is actually
|
||||
* an mtree(8) specfile, so parse the specfile into a NODE *
|
||||
* tree at ftnode, for use by next_file()
|
||||
*/
|
||||
if (Mflag) {
|
||||
if (fthead != NULL) {
|
||||
tty_warn(1,
|
||||
"The -M flag is only supported when reading file list from stdin");
|
||||
return -1;
|
||||
}
|
||||
ftnode = spec(stdin);
|
||||
if (ftnode != NULL &&
|
||||
(ftnode->type != F_DIR || strcmp(ftnode->name, ".") != 0)) {
|
||||
tty_warn(1,
|
||||
"First node of specfile is not `.' directory");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* SMALL */
|
||||
|
||||
/*
|
||||
* set up the operation mode of fts, open the first file arg. We must
|
||||
* use FTS_NOCHDIR, as the user may have to open multiple archives and
|
||||
* if fts did a chdir off into the boondocks, we may create an archive
|
||||
* volume in an place where the user did not expect to.
|
||||
*/
|
||||
ftsopts = FTS_NOCHDIR;
|
||||
|
||||
/*
|
||||
* optional user flags that effect file traversal
|
||||
* -H command line symlink follow only (half follow)
|
||||
* -L follow sylinks (logical)
|
||||
* -P do not follow sylinks (physical). This is the default.
|
||||
* -X do not cross over mount points
|
||||
* -t preserve access times on files read.
|
||||
* -n select only the first member of a file tree when a match is found
|
||||
* -d do not extract subtrees rooted at a directory arg.
|
||||
*/
|
||||
if (Lflag)
|
||||
ftsopts |= FTS_LOGICAL;
|
||||
else
|
||||
ftsopts |= FTS_PHYSICAL;
|
||||
if (Hflag)
|
||||
ftsopts |= FTS_COMFOLLOW;
|
||||
if (Xflag)
|
||||
ftsopts |= FTS_XDEV;
|
||||
|
||||
if ((fthead == NULL) && ((farray[0] = malloc(PAXPATHLEN+2)) == NULL)) {
|
||||
tty_warn(1, "Unable to allocate memory for file name buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ftree_arg() < 0)
|
||||
return -1;
|
||||
if (tflag && (atdir_start() < 0))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ftree_add()
|
||||
* add the arg to the linked list of files to process. Each will be
|
||||
* processed by fts one at a time
|
||||
* Return:
|
||||
* 0 if added to the linked list, -1 if failed
|
||||
*/
|
||||
|
||||
int
|
||||
ftree_add(char *str, int isdir)
|
||||
{
|
||||
FTREE *ft;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* simple check for bad args
|
||||
*/
|
||||
if ((str == NULL) || (*str == '\0')) {
|
||||
tty_warn(0, "Invalid file name argument");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate FTREE node and add to the end of the linked list (args are
|
||||
* processed in the same order they were passed to pax). Get rid of any
|
||||
* trailing / the user may pass us. (watch out for / by itself).
|
||||
*/
|
||||
if ((ft = (FTREE *)malloc(sizeof(FTREE))) == NULL) {
|
||||
tty_warn(0, "Unable to allocate memory for filename");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (((len = strlen(str) - 1) > 0) && (str[len] == '/'))
|
||||
str[len] = '\0';
|
||||
ft->fname = str;
|
||||
ft->refcnt = -isdir;
|
||||
ft->fow = NULL;
|
||||
if (fthead == NULL) {
|
||||
fttail = fthead = ft;
|
||||
return 0;
|
||||
}
|
||||
fttail->fow = ft;
|
||||
fttail = ft;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ftree_sel()
|
||||
* this entry has been selected by pax. bump up reference count and handle
|
||||
* -n and -d processing.
|
||||
*/
|
||||
|
||||
void
|
||||
ftree_sel(ARCHD *arcn)
|
||||
{
|
||||
/*
|
||||
* set reference bit for this pattern. This linked list is only used
|
||||
* when file trees are supplied pax as args. The list is not used when
|
||||
* the trees are read from stdin.
|
||||
*/
|
||||
if (ftcur != NULL)
|
||||
ftcur->refcnt = 1;
|
||||
|
||||
/*
|
||||
* if -n we are done with this arg, force a skip to the next arg when
|
||||
* pax asks for the next file in next_file().
|
||||
* if -M we don't use fts(3), so the rest of this function is moot.
|
||||
* if -d we tell fts only to match the directory (if the arg is a dir)
|
||||
* and not the entire file tree rooted at that point.
|
||||
*/
|
||||
if (nflag)
|
||||
ftree_skip = 1;
|
||||
|
||||
if (Mflag || !dflag || (arcn->type != PAX_DIR))
|
||||
return;
|
||||
|
||||
if (ftent != NULL)
|
||||
(void)fts_set(ftsp, ftent, FTS_SKIP);
|
||||
}
|
||||
|
||||
/*
|
||||
* ftree_chk()
|
||||
* called at end on pax execution. Prints all those file args that did not
|
||||
* have a selected member (reference count still 0)
|
||||
*/
|
||||
|
||||
void
|
||||
ftree_chk(void)
|
||||
{
|
||||
FTREE *ft;
|
||||
int wban = 0;
|
||||
|
||||
/*
|
||||
* make sure all dir access times were reset.
|
||||
*/
|
||||
if (tflag)
|
||||
atdir_end();
|
||||
|
||||
/*
|
||||
* walk down list and check reference count. Print out those members
|
||||
* that never had a match
|
||||
*/
|
||||
for (ft = fthead; ft != NULL; ft = ft->fow) {
|
||||
if (ft->refcnt != 0)
|
||||
continue;
|
||||
if (wban == 0) {
|
||||
tty_warn(1,
|
||||
"WARNING! These file names were not selected:");
|
||||
++wban;
|
||||
}
|
||||
(void)fprintf(stderr, "%s\n", ft->fname);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ftree_arg()
|
||||
* Get the next file arg for fts to process. Can be from either the linked
|
||||
* list or read from stdin when the user did not them as args to pax. Each
|
||||
* arg is processed until the first successful fts_open().
|
||||
* Return:
|
||||
* 0 when the next arg is ready to go, -1 if out of file args (or EOF on
|
||||
* stdin).
|
||||
*/
|
||||
|
||||
static int
|
||||
ftree_arg(void)
|
||||
{
|
||||
/*
|
||||
* close off the current file tree
|
||||
*/
|
||||
if (ftsp != NULL) {
|
||||
(void)fts_close(ftsp);
|
||||
ftsp = NULL;
|
||||
ftent = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* keep looping until we get a valid file tree to process. Stop when we
|
||||
* reach the end of the list (or get an eof on stdin)
|
||||
*/
|
||||
for(;;) {
|
||||
if (fthead == NULL) {
|
||||
int i, c = EOF;
|
||||
/*
|
||||
* the user didn't supply any args, get the file trees
|
||||
* to process from stdin;
|
||||
*/
|
||||
for (i = 0; i < PAXPATHLEN + 2;) {
|
||||
c = getchar();
|
||||
if (c == EOF)
|
||||
break;
|
||||
else if (c == sep) {
|
||||
if (i != 0)
|
||||
break;
|
||||
} else
|
||||
farray[0][i++] = c;
|
||||
}
|
||||
if (i == 0)
|
||||
return -1;
|
||||
farray[0][i] = '\0';
|
||||
} else {
|
||||
/*
|
||||
* the user supplied the file args as arguments to pax
|
||||
*/
|
||||
if (ftcur == NULL)
|
||||
ftcur = fthead;
|
||||
else if ((ftcur = ftcur->fow) == NULL)
|
||||
return -1;
|
||||
|
||||
if (ftcur->refcnt < 0) {
|
||||
/*
|
||||
* chdir entry.
|
||||
* Change directory and retry loop.
|
||||
*/
|
||||
if (ar_dochdir(ftcur->fname))
|
||||
return (-1);
|
||||
continue;
|
||||
}
|
||||
farray[0] = ftcur->fname;
|
||||
}
|
||||
|
||||
/*
|
||||
* watch it, fts wants the file arg stored in a array of char
|
||||
* ptrs, with the last one a null. we use a two element array
|
||||
* and set farray[0] to point at the buffer with the file name
|
||||
* in it. We cannot pass all the file args to fts at one shot
|
||||
* as we need to keep a handle on which file arg generates what
|
||||
* files (the -n and -d flags need this). If the open is
|
||||
* successful, return a 0.
|
||||
*/
|
||||
if ((ftsp = fts_open(farray, ftsopts, NULL)) != NULL)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* next_file()
|
||||
* supplies the next file to process in the supplied archd structure.
|
||||
* Return:
|
||||
* 0 when contents of arcn have been set with the next file, -1 when done.
|
||||
*/
|
||||
|
||||
int
|
||||
next_file(ARCHD *arcn)
|
||||
{
|
||||
#ifndef SMALL
|
||||
static char curdir[PAXPATHLEN+2], curpath[PAXPATHLEN+2];
|
||||
static int curdirlen;
|
||||
|
||||
struct stat statbuf;
|
||||
FTSENT Mftent;
|
||||
#endif /* SMALL */
|
||||
int cnt;
|
||||
time_t atime, mtime;
|
||||
char *curlink;
|
||||
#define MFTENT_DUMMY_DEV UINT_MAX
|
||||
|
||||
curlink = NULL;
|
||||
#ifndef SMALL
|
||||
/*
|
||||
* if parsing an mtree(8) specfile, build up `dummy' ftsent
|
||||
* from specfile info, and jump below to complete setup of arcn.
|
||||
*/
|
||||
if (Mflag) {
|
||||
int skipoptional;
|
||||
|
||||
next_ftnode:
|
||||
skipoptional = 0;
|
||||
if (ftnode == NULL) /* tree is empty */
|
||||
return (-1);
|
||||
|
||||
/* get current name */
|
||||
if (snprintf(curpath, sizeof(curpath), "%s%s%s",
|
||||
curdir, curdirlen ? "/" : "", ftnode->name)
|
||||
>= (int)sizeof(curpath)) {
|
||||
tty_warn(1, "line %lu: %s: %s", (u_long)ftnode->lineno,
|
||||
curdir, strerror(ENAMETOOLONG));
|
||||
return (-1);
|
||||
}
|
||||
ftnode->flags |= F_VISIT; /* mark node visited */
|
||||
|
||||
/* construct dummy FTSENT */
|
||||
Mftent.fts_path = curpath;
|
||||
Mftent.fts_statp = &statbuf;
|
||||
Mftent.fts_pointer = ftnode;
|
||||
ftent = &Mftent;
|
||||
/* look for existing file */
|
||||
if (lstat(Mftent.fts_path, &statbuf) == -1) {
|
||||
if (ftnode->flags & F_OPT)
|
||||
skipoptional = 1;
|
||||
|
||||
/* missing: fake up stat info */
|
||||
memset(&statbuf, 0, sizeof(statbuf));
|
||||
statbuf.st_dev = MFTENT_DUMMY_DEV;
|
||||
statbuf.st_ino = ftnode->lineno;
|
||||
statbuf.st_size = 0;
|
||||
#define NODETEST(t, m) \
|
||||
if (!(t)) { \
|
||||
tty_warn(1, "line %lu: %s: %s not specified", \
|
||||
(u_long)ftnode->lineno, \
|
||||
ftent->fts_path, m); \
|
||||
return -1; \
|
||||
}
|
||||
statbuf.st_mode = nodetoino(ftnode->type);
|
||||
NODETEST(ftnode->flags & F_TYPE, "type");
|
||||
NODETEST(ftnode->flags & F_MODE, "mode");
|
||||
if (!(ftnode->flags & F_TIME))
|
||||
statbuf.st_mtime = starttime;
|
||||
NODETEST(ftnode->flags & (F_GID | F_GNAME), "group");
|
||||
NODETEST(ftnode->flags & (F_UID | F_UNAME), "user");
|
||||
if (ftnode->type == F_BLOCK || ftnode->type == F_CHAR)
|
||||
NODETEST(ftnode->flags & F_DEV,
|
||||
"device number");
|
||||
if (ftnode->type == F_LINK)
|
||||
NODETEST(ftnode->flags & F_SLINK, "symlink");
|
||||
/* don't require F_FLAGS or F_SIZE */
|
||||
#undef NODETEST
|
||||
} else {
|
||||
if (ftnode->flags & F_TYPE && nodetoino(ftnode->type)
|
||||
!= (statbuf.st_mode & S_IFMT)) {
|
||||
tty_warn(1,
|
||||
"line %lu: %s: type mismatch: specfile %s, tree %s",
|
||||
(u_long)ftnode->lineno, ftent->fts_path,
|
||||
inotype(nodetoino(ftnode->type)),
|
||||
inotype(statbuf.st_mode));
|
||||
return -1;
|
||||
}
|
||||
if (ftnode->type == F_DIR && (ftnode->flags & F_OPT))
|
||||
skipoptional = 1;
|
||||
}
|
||||
/*
|
||||
* override settings with those from specfile
|
||||
*/
|
||||
if (ftnode->flags & F_MODE) {
|
||||
statbuf.st_mode &= ~ALLPERMS;
|
||||
statbuf.st_mode |= (ftnode->st_mode & ALLPERMS);
|
||||
}
|
||||
if (ftnode->flags & (F_GID | F_GNAME))
|
||||
statbuf.st_gid = ftnode->st_gid;
|
||||
if (ftnode->flags & (F_UID | F_UNAME))
|
||||
statbuf.st_uid = ftnode->st_uid;
|
||||
#if HAVE_STRUCT_STAT_ST_FLAGS
|
||||
if (ftnode->flags & F_FLAGS)
|
||||
statbuf.st_flags = ftnode->st_flags;
|
||||
#endif
|
||||
if (ftnode->flags & F_TIME)
|
||||
#if BSD4_4 && !HAVE_NBTOOL_CONFIG_H
|
||||
statbuf.st_mtimespec = ftnode->st_mtimespec;
|
||||
#else
|
||||
statbuf.st_mtime = ftnode->st_mtimespec.tv_sec;
|
||||
#endif
|
||||
if (ftnode->flags & F_DEV)
|
||||
statbuf.st_rdev = ftnode->st_rdev;
|
||||
if (ftnode->flags & F_SLINK)
|
||||
curlink = ftnode->slink;
|
||||
/* ignore F_SIZE */
|
||||
|
||||
/*
|
||||
* find next node
|
||||
*/
|
||||
if (ftnode->type == F_DIR && ftnode->child != NULL) {
|
||||
/* directory with unseen child */
|
||||
ftnode = ftnode->child;
|
||||
curdirlen = strlcpy(curdir, curpath, sizeof(curdir));
|
||||
} else do {
|
||||
if (ftnode->next != NULL) {
|
||||
/* next node at current level */
|
||||
ftnode = ftnode->next;
|
||||
} else { /* move back to parent */
|
||||
/* reset time only on first cd.. */
|
||||
if (Mftent.fts_pointer == ftnode && tflag &&
|
||||
(get_atdir(MFTENT_DUMMY_DEV, ftnode->lineno,
|
||||
&mtime, &atime) == 0)) {
|
||||
set_ftime(ftent->fts_path,
|
||||
mtime, atime, 1, 0);
|
||||
}
|
||||
ftnode = ftnode->parent;
|
||||
if (ftnode->parent == ftnode)
|
||||
ftnode = NULL;
|
||||
else {
|
||||
curdirlen -= strlen(ftnode->name) + 1;
|
||||
curdir[curdirlen] = '\0';
|
||||
}
|
||||
}
|
||||
} while (ftnode != NULL && ftnode->flags & F_VISIT);
|
||||
if (skipoptional) /* skip optional entries */
|
||||
goto next_ftnode;
|
||||
goto got_ftent;
|
||||
}
|
||||
#endif /* SMALL */
|
||||
|
||||
/*
|
||||
* ftree_sel() might have set the ftree_skip flag if the user has the
|
||||
* -n option and a file was selected from this file arg tree. (-n says
|
||||
* only one member is matched for each pattern) ftree_skip being 1
|
||||
* forces us to go to the next arg now.
|
||||
*/
|
||||
if (ftree_skip) {
|
||||
/*
|
||||
* clear and go to next arg
|
||||
*/
|
||||
ftree_skip = 0;
|
||||
if (ftree_arg() < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ftsp == NULL)
|
||||
return -1;
|
||||
/*
|
||||
* loop until we get a valid file to process
|
||||
*/
|
||||
for(;;) {
|
||||
if ((ftent = fts_read(ftsp)) == NULL) {
|
||||
/*
|
||||
* out of files in this tree, go to next arg, if none
|
||||
* we are done
|
||||
*/
|
||||
if (ftree_arg() < 0)
|
||||
return -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle each type of fts_read() flag
|
||||
*/
|
||||
switch(ftent->fts_info) {
|
||||
case FTS_D:
|
||||
case FTS_DEFAULT:
|
||||
case FTS_F:
|
||||
case FTS_SL:
|
||||
case FTS_SLNONE:
|
||||
/*
|
||||
* these are all ok
|
||||
*/
|
||||
break;
|
||||
case FTS_DP:
|
||||
/*
|
||||
* already saw this directory. If the user wants file
|
||||
* access times reset, we use this to restore the
|
||||
* access time for this directory since this is the
|
||||
* last time we will see it in this file subtree
|
||||
* remember to force the time (this is -t on a read
|
||||
* directory, not a created directory).
|
||||
*/
|
||||
if (!tflag || (get_atdir(
|
||||
ftent->fts_statp->st_dev, ftent->fts_statp->st_ino,
|
||||
&mtime, &atime) < 0))
|
||||
continue;
|
||||
set_ftime(ftent->fts_path, mtime, atime, 1, 0);
|
||||
continue;
|
||||
case FTS_DC:
|
||||
/*
|
||||
* fts claims a file system cycle
|
||||
*/
|
||||
tty_warn(1,"File system cycle found at %s",
|
||||
ftent->fts_path);
|
||||
continue;
|
||||
case FTS_DNR:
|
||||
syswarn(1, FTS_ERRNO(ftent),
|
||||
"Unable to read directory %s", ftent->fts_path);
|
||||
continue;
|
||||
case FTS_ERR:
|
||||
syswarn(1, FTS_ERRNO(ftent),
|
||||
"File system traversal error");
|
||||
continue;
|
||||
case FTS_NS:
|
||||
case FTS_NSOK:
|
||||
syswarn(1, FTS_ERRNO(ftent),
|
||||
"Unable to access %s", ftent->fts_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifndef SMALL
|
||||
got_ftent:
|
||||
#endif /* SMALL */
|
||||
/*
|
||||
* ok got a file tree node to process. copy info into arcn
|
||||
* structure (initialize as required)
|
||||
*/
|
||||
arcn->skip = 0;
|
||||
arcn->pad = 0;
|
||||
arcn->ln_nlen = 0;
|
||||
arcn->ln_name[0] = '\0';
|
||||
arcn->sb = *(ftent->fts_statp);
|
||||
|
||||
/*
|
||||
* file type based set up and copy into the arcn struct
|
||||
* SIDE NOTE:
|
||||
* we try to reset the access time on all files and directories
|
||||
* we may read when the -t flag is specified. files are reset
|
||||
* when we close them after copying. we reset the directories
|
||||
* when we are done with their file tree (we also clean up at
|
||||
* end in case we cut short a file tree traversal). However
|
||||
* there is no way to reset access times on symlinks.
|
||||
*/
|
||||
switch(S_IFMT & arcn->sb.st_mode) {
|
||||
case S_IFDIR:
|
||||
arcn->type = PAX_DIR;
|
||||
if (!tflag)
|
||||
break;
|
||||
add_atdir(ftent->fts_path, arcn->sb.st_dev,
|
||||
arcn->sb.st_ino, arcn->sb.st_mtime,
|
||||
arcn->sb.st_atime);
|
||||
break;
|
||||
case S_IFCHR:
|
||||
arcn->type = PAX_CHR;
|
||||
break;
|
||||
case S_IFBLK:
|
||||
arcn->type = PAX_BLK;
|
||||
break;
|
||||
case S_IFREG:
|
||||
/*
|
||||
* only regular files with have data to store on the
|
||||
* archive. all others will store a zero length skip.
|
||||
* the skip field is used by pax for actual data it has
|
||||
* to read (or skip over).
|
||||
*/
|
||||
arcn->type = PAX_REG;
|
||||
arcn->skip = arcn->sb.st_size;
|
||||
break;
|
||||
case S_IFLNK:
|
||||
arcn->type = PAX_SLK;
|
||||
if (curlink != NULL) {
|
||||
cnt = strlcpy(arcn->ln_name, curlink,
|
||||
sizeof(arcn->ln_name));
|
||||
/*
|
||||
* have to read the symlink path from the file
|
||||
*/
|
||||
} else if ((cnt =
|
||||
readlink(ftent->fts_path, arcn->ln_name,
|
||||
sizeof(arcn->ln_name) - 1)) < 0) {
|
||||
syswarn(1, errno, "Unable to read symlink %s",
|
||||
ftent->fts_path);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* set link name length, watch out readlink does not
|
||||
* always null terminate the link path
|
||||
*/
|
||||
arcn->ln_name[cnt] = '\0';
|
||||
arcn->ln_nlen = cnt;
|
||||
break;
|
||||
#ifdef S_IFSOCK
|
||||
case S_IFSOCK:
|
||||
/*
|
||||
* under BSD storing a socket is senseless but we will
|
||||
* let the format specific write function make the
|
||||
* decision of what to do with it.
|
||||
*/
|
||||
arcn->type = PAX_SCK;
|
||||
break;
|
||||
#endif
|
||||
case S_IFIFO:
|
||||
arcn->type = PAX_FIF;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy file name, set file name length
|
||||
*/
|
||||
arcn->nlen = strlcpy(arcn->name, ftent->fts_path, sizeof(arcn->name));
|
||||
arcn->org_name = arcn->fts_name;
|
||||
strlcpy(arcn->fts_name, ftent->fts_path, sizeof arcn->fts_name);
|
||||
if (strcmp(NM_CPIO, argv0) == 0) {
|
||||
/*
|
||||
* cpio does *not* descend directories listed in the
|
||||
* arguments, unlike pax/tar, so needs special handling
|
||||
* here. failure to do so results in massive amounts
|
||||
* of duplicated files in the output. We kill fts after
|
||||
* the first name is extracted, what a waste.
|
||||
*/
|
||||
ftcur->refcnt = 1;
|
||||
(void)ftree_arg();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
48
bin/pax/ftree.h
Normal file
48
bin/pax/ftree.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* $NetBSD: ftree.h,v 1.5 2003/10/13 07:41:22 agc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ftree.h 8.1 (Berkeley) 5/31/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* Data structure used by the ftree.c routines to store the file args to be
|
||||
* handed to fts(). It keeps a reference count of which args generated a
|
||||
* "selected" member
|
||||
*/
|
||||
|
||||
typedef struct ftree {
|
||||
char *fname; /* file tree name */
|
||||
int refcnt; /* has tree had a selected file? */
|
||||
struct ftree *fow; /* pointer to next entry on list */
|
||||
} FTREE;
|
||||
415
bin/pax/gen_subs.c
Normal file
415
bin/pax/gen_subs.c
Normal file
@@ -0,0 +1,415 @@
|
||||
/* $NetBSD: gen_subs.c,v 1.36 2012/08/09 08:09:21 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)gen_subs.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: gen_subs.c,v 1.36 2012/08/09 08:09:21 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <vis.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <tzfile.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "pax.h"
|
||||
#include "extern.h"
|
||||
|
||||
/*
|
||||
* a collection of general purpose subroutines used by pax
|
||||
*/
|
||||
|
||||
/*
|
||||
* constants used by ls_list() when printing out archive members
|
||||
*/
|
||||
#define MODELEN 20
|
||||
#define DATELEN 64
|
||||
#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
|
||||
|
||||
/*
|
||||
* convert time to string
|
||||
*/
|
||||
static void
|
||||
formattime(char *buf, size_t buflen, time_t when)
|
||||
{
|
||||
int error;
|
||||
struct tm tm;
|
||||
(void)localtime_r(&when, &tm);
|
||||
|
||||
if (when + SIXMONTHS <= time(NULL))
|
||||
error = strftime(buf, buflen, OLDFRMT, &tm);
|
||||
else
|
||||
error = strftime(buf, buflen, CURFRMT, &tm);
|
||||
|
||||
if (error == 0)
|
||||
buf[0] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* ls_list()
|
||||
* list the members of an archive in ls format
|
||||
*/
|
||||
|
||||
void
|
||||
ls_list(ARCHD *arcn, time_t now, FILE *fp)
|
||||
{
|
||||
struct stat *sbp;
|
||||
char f_mode[MODELEN];
|
||||
char f_date[DATELEN];
|
||||
const char *user, *group;
|
||||
|
||||
/*
|
||||
* if not verbose, just print the file name
|
||||
*/
|
||||
if (!vflag) {
|
||||
(void)fprintf(fp, "%s\n", arcn->name);
|
||||
(void)fflush(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* user wants long mode
|
||||
*/
|
||||
sbp = &(arcn->sb);
|
||||
strmode(sbp->st_mode, f_mode);
|
||||
|
||||
/*
|
||||
* time format based on age compared to the time pax was started.
|
||||
*/
|
||||
formattime(f_date, sizeof(f_date), arcn->sb.st_mtime);
|
||||
/*
|
||||
* print file mode, link count, uid, gid and time
|
||||
*/
|
||||
user = user_from_uid(sbp->st_uid, 0);
|
||||
group = group_from_gid(sbp->st_gid, 0);
|
||||
(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)fprintf(fp, "%4lu,%4lu ", (long) MAJOR(sbp->st_rdev),
|
||||
(long) MINOR(sbp->st_rdev));
|
||||
else {
|
||||
(void)fprintf(fp, OFFT_FP("9") " ", (OFFT_T)sbp->st_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)fputc('\n', fp);
|
||||
(void)fflush(fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* tty_ls()
|
||||
* print a short summary of file to tty.
|
||||
*/
|
||||
|
||||
void
|
||||
ls_tty(ARCHD *arcn)
|
||||
{
|
||||
char f_date[DATELEN];
|
||||
char f_mode[MODELEN];
|
||||
|
||||
formattime(f_date, sizeof(f_date), arcn->sb.st_mtime);
|
||||
strmode(arcn->sb.st_mode, f_mode);
|
||||
tty_prnt("%s%s %s\n", f_mode, f_date, arcn->name);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
safe_print(const char *str, FILE *fp)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* asc_u32()
|
||||
* convert hex/octal character string into a uint32_t. We do not have to
|
||||
* check for overflow! (the headers in all supported formats are not large
|
||||
* enough to create an overflow).
|
||||
* NOTE: strings passed to us are NOT TERMINATED.
|
||||
* Return:
|
||||
* uint32_t value
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
asc_u32(char *str, int len, int base)
|
||||
{
|
||||
char *stop;
|
||||
uint32_t tval = 0;
|
||||
|
||||
stop = str + len;
|
||||
|
||||
/*
|
||||
* skip over leading blanks and zeros
|
||||
*/
|
||||
while ((str < stop) && ((*str == ' ') || (*str == '0')))
|
||||
++str;
|
||||
|
||||
/*
|
||||
* for each valid digit, shift running value (tval) over to next digit
|
||||
* and add next digit
|
||||
*/
|
||||
if (base == HEX) {
|
||||
while (str < stop) {
|
||||
if ((*str >= '0') && (*str <= '9'))
|
||||
tval = (tval << 4) + (*str++ - '0');
|
||||
else if ((*str >= 'A') && (*str <= 'F'))
|
||||
tval = (tval << 4) + 10 + (*str++ - 'A');
|
||||
else if ((*str >= 'a') && (*str <= 'f'))
|
||||
tval = (tval << 4) + 10 + (*str++ - 'a');
|
||||
else
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
while ((str < stop) && (*str >= '0') && (*str <= '7'))
|
||||
tval = (tval << 3) + (*str++ - '0');
|
||||
}
|
||||
return tval;
|
||||
}
|
||||
|
||||
/*
|
||||
* u32_asc()
|
||||
* convert an uintmax_t into an hex/oct ascii string. pads with LEADING
|
||||
* ascii 0's to fill string completely
|
||||
* NOTE: the string created is NOT TERMINATED.
|
||||
*/
|
||||
|
||||
int
|
||||
u32_asc(uintmax_t val, char *str, int len, int base)
|
||||
{
|
||||
char *pt;
|
||||
uint32_t digit;
|
||||
uintmax_t p;
|
||||
|
||||
p = val & TOP_HALF;
|
||||
if (p && p != TOP_HALF)
|
||||
return -1;
|
||||
|
||||
val &= BOTTOM_HALF;
|
||||
|
||||
/*
|
||||
* WARNING str is not '\0' terminated by this routine
|
||||
*/
|
||||
pt = str + len - 1;
|
||||
|
||||
/*
|
||||
* do a tailwise conversion (start at right most end of string to place
|
||||
* least significant digit). Keep shifting until conversion value goes
|
||||
* to zero (all digits were converted)
|
||||
*/
|
||||
if (base == HEX) {
|
||||
while (pt >= str) {
|
||||
if ((digit = (val & 0xf)) < 10)
|
||||
*pt-- = '0' + (char)digit;
|
||||
else
|
||||
*pt-- = 'a' + (char)(digit - 10);
|
||||
if ((val = (val >> 4)) == (u_long)0)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
while (pt >= str) {
|
||||
*pt-- = '0' + (char)(val & 0x7);
|
||||
if ((val = (val >> 3)) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* pad with leading ascii ZEROS. We return -1 if we ran out of space.
|
||||
*/
|
||||
while (pt >= str)
|
||||
*pt-- = '0';
|
||||
if (val != 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* asc_umax()
|
||||
* convert hex/octal character string into a uintmax. We do
|
||||
* not have to to check for overflow! (the headers in all supported
|
||||
* formats are not large enough to create an overflow).
|
||||
* NOTE: strings passed to us are NOT TERMINATED.
|
||||
* Return:
|
||||
* uintmax_t value
|
||||
*/
|
||||
|
||||
uintmax_t
|
||||
asc_umax(char *str, int len, int base)
|
||||
{
|
||||
char *stop;
|
||||
uintmax_t tval = 0;
|
||||
|
||||
stop = str + len;
|
||||
|
||||
/*
|
||||
* skip over leading blanks and zeros
|
||||
*/
|
||||
while ((str < stop) && ((*str == ' ') || (*str == '0')))
|
||||
++str;
|
||||
|
||||
/*
|
||||
* for each valid digit, shift running value (tval) over to next digit
|
||||
* and add next digit
|
||||
*/
|
||||
if (base == HEX) {
|
||||
while (str < stop) {
|
||||
if ((*str >= '0') && (*str <= '9'))
|
||||
tval = (tval << 4) + (*str++ - '0');
|
||||
else if ((*str >= 'A') && (*str <= 'F'))
|
||||
tval = (tval << 4) + 10 + (*str++ - 'A');
|
||||
else if ((*str >= 'a') && (*str <= 'f'))
|
||||
tval = (tval << 4) + 10 + (*str++ - 'a');
|
||||
else
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
while ((str < stop) && (*str >= '0') && (*str <= '7'))
|
||||
tval = (tval << 3) + (*str++ - '0');
|
||||
}
|
||||
return tval;
|
||||
}
|
||||
|
||||
/*
|
||||
* umax_asc()
|
||||
* convert an uintmax_t into a hex/oct ascii string. pads with
|
||||
* LEADING ascii 0's to fill string completely
|
||||
* NOTE: the string created is NOT TERMINATED.
|
||||
*/
|
||||
|
||||
int
|
||||
umax_asc(uintmax_t val, char *str, int len, int base)
|
||||
{
|
||||
char *pt;
|
||||
uintmax_t digit;
|
||||
|
||||
/*
|
||||
* WARNING str is not '\0' terminated by this routine
|
||||
*/
|
||||
pt = str + len - 1;
|
||||
|
||||
/*
|
||||
* do a tailwise conversion (start at right most end of string to place
|
||||
* least significant digit). Keep shifting until conversion value goes
|
||||
* to zero (all digits were converted)
|
||||
*/
|
||||
if (base == HEX) {
|
||||
while (pt >= str) {
|
||||
if ((digit = (val & 0xf)) < 10)
|
||||
*pt-- = '0' + (char)digit;
|
||||
else
|
||||
*pt-- = 'a' + (char)(digit - 10);
|
||||
if ((val = (val >> 4)) == 0)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
while (pt >= str) {
|
||||
*pt-- = '0' + (char)(val & 0x7);
|
||||
if ((val = (val >> 3)) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* pad with leading ascii ZEROS. We return -1 if we ran out of space.
|
||||
*/
|
||||
while (pt >= str)
|
||||
*pt-- = '0';
|
||||
if (val != 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
check_Aflag(void)
|
||||
{
|
||||
|
||||
if (Aflag > 0)
|
||||
return 1;
|
||||
if (Aflag == 0) {
|
||||
Aflag = -1;
|
||||
tty_warn(0,
|
||||
"Removing leading / from absolute path names in the archive");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
92
bin/pax/getoldopt.c
Normal file
92
bin/pax/getoldopt.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/* $NetBSD: getoldopt.c,v 1.23 2012/08/09 11:05:59 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Plug-compatible replacement for getopt() for parsing tar-like
|
||||
* arguments. If the first argument begins with "-", it uses getopt;
|
||||
* otherwise, it uses the old rules used by tar, dump, and ps.
|
||||
*
|
||||
* Written 25 August 1985 by John Gilmore (ihnp4!hoptoad!gnu) and placed
|
||||
* in the Public Domain for your edification and enjoyment.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if !defined(lint)
|
||||
__RCSID("$NetBSD: getoldopt.c,v 1.23 2012/08/09 11:05:59 christos Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "compat_getopt.h"
|
||||
#else
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/stat.h>
|
||||
#include "pax.h"
|
||||
#include "extern.h"
|
||||
|
||||
int
|
||||
getoldopt(int argc, char **argv, const char *optstring,
|
||||
struct option *longopts, int *idx)
|
||||
{
|
||||
static char *key; /* Points to next keyletter */
|
||||
static char use_getopt; /* !=0 if argv[1][0] was '-' */
|
||||
char c;
|
||||
char *place;
|
||||
|
||||
optarg = NULL;
|
||||
|
||||
if (key == NULL) { /* First time */
|
||||
if (argc < 2) return -1;
|
||||
key = argv[1];
|
||||
if (*key == '-')
|
||||
use_getopt++;
|
||||
else
|
||||
optind = 2;
|
||||
}
|
||||
|
||||
c = '\0';
|
||||
if (!use_getopt) {
|
||||
c = *key++;
|
||||
if (c == '\0') {
|
||||
key--;
|
||||
use_getopt = 1;
|
||||
}
|
||||
}
|
||||
if (use_getopt) {
|
||||
if (longopts != NULL) {
|
||||
return getopt_long(argc, argv, optstring,
|
||||
longopts, idx);
|
||||
} else {
|
||||
return getopt(argc, argv, optstring);
|
||||
}
|
||||
}
|
||||
|
||||
place = strchr(optstring, c);
|
||||
|
||||
if (place == NULL || c == ':') {
|
||||
fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
|
||||
return '?';
|
||||
}
|
||||
|
||||
place++;
|
||||
if (*place == ':') {
|
||||
if (optind < argc) {
|
||||
optarg = argv[optind];
|
||||
optind++;
|
||||
} else {
|
||||
fprintf(stderr, "%s: %c argument missing\n",
|
||||
argv[0], c);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
2161
bin/pax/options.c
Normal file
2161
bin/pax/options.c
Normal file
File diff suppressed because it is too large
Load Diff
116
bin/pax/options.h
Normal file
116
bin/pax/options.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/* $NetBSD: options.h,v 1.11 2007/04/23 18:40:22 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)options.h 8.2 (Berkeley) 4/18/94
|
||||
*/
|
||||
|
||||
/*
|
||||
* argv[0] names. Used for tar and cpio emulation
|
||||
*/
|
||||
|
||||
#define NM_TAR "tar"
|
||||
#define NM_CPIO "cpio"
|
||||
#define NM_PAX "pax"
|
||||
|
||||
/* special value for -E */
|
||||
#define none "none"
|
||||
|
||||
/*
|
||||
* Constants used to specify the legal sets of flags in pax. For each major
|
||||
* operation mode of pax, a set of illegal flags is defined. If any one of
|
||||
* those illegal flags are found set, we scream and exit
|
||||
*/
|
||||
|
||||
/*
|
||||
* flags (one for each option).
|
||||
*/
|
||||
#define AF 0x000000001ULL
|
||||
#define BF 0x000000002ULL
|
||||
#define CF 0x000000004ULL
|
||||
#define DF 0x000000008ULL
|
||||
#define FF 0x000000010ULL
|
||||
#define IF 0x000000020ULL
|
||||
#define KF 0x000000040ULL
|
||||
#define LF 0x000000080ULL
|
||||
#define NF 0x000000100ULL
|
||||
#define OF 0x000000200ULL
|
||||
#define PF 0x000000400ULL
|
||||
#define RF 0x000000800ULL
|
||||
#define SF 0x000001000ULL
|
||||
#define TF 0x000002000ULL
|
||||
#define UF 0x000004000ULL
|
||||
#define VF 0x000008000ULL
|
||||
#define WF 0x000010000ULL
|
||||
#define XF 0x000020000ULL
|
||||
#define CAF 0x000040000ULL /* nonstandard extension */
|
||||
#define CBF 0x000080000ULL /* nonstandard extension */
|
||||
#define CDF 0x000100000ULL /* nonstandard extension */
|
||||
#define CEF 0x000200000ULL /* nonstandard extension */
|
||||
#define CGF 0x000400000ULL /* nonstandard extension */
|
||||
#define CHF 0x000800000ULL /* nonstandard extension */
|
||||
#define CLF 0x001000000ULL /* nonstandard extension */
|
||||
#define CMF 0x002000000ULL /* nonstandard extension */
|
||||
#define CPF 0x004000000ULL /* nonstandard extension */
|
||||
#define CTF 0x008000000ULL /* nonstandard extension */
|
||||
#define CUF 0x010000000ULL /* nonstandard extension */
|
||||
#define VSF 0x020000000ULL /* non-standard */
|
||||
#define CXF 0x040000000ULL
|
||||
#define CYF 0x080000000ULL /* nonstandard extension */
|
||||
#define CZF 0x100000000ULL /* nonstandard extension */
|
||||
|
||||
/*
|
||||
* ascii string indexed by bit position above (alter the above and you must
|
||||
* alter this string) used to tell the user what flags caused us to complain
|
||||
*/
|
||||
#define FLGCH "abcdfiklnoprstuvwxABDEGHLMPTUVXYZ"
|
||||
|
||||
/*
|
||||
* legal pax operation bit patterns
|
||||
*/
|
||||
|
||||
#define ISLIST(x) (((x) & (RF|WF)) == 0)
|
||||
#define ISEXTRACT(x) (((x) & (RF|WF)) == RF)
|
||||
#define ISARCHIVE(x) (((x) & (AF|RF|WF)) == WF)
|
||||
#define ISAPPND(x) (((x) & (AF|RF|WF)) == (AF|WF))
|
||||
#define ISCOPY(x) (((x) & (RF|WF)) == (RF|WF))
|
||||
#define ISWRITE(x) (((x) & (RF|WF)) == WF)
|
||||
|
||||
/*
|
||||
* Illegal option flag subsets based on pax operation
|
||||
*/
|
||||
|
||||
#define BDEXTR (AF|BF|LF|TF|WF|XF|CBF|CHF|CLF|CMF|CPF|CXF)
|
||||
#define BDARCH (CF|KF|LF|NF|PF|RF|CDF|CEF|CYF|CZF)
|
||||
#define BDCOPY (AF|BF|FF|OF|XF|CAF|CBF|CEF)
|
||||
#define BDLIST (AF|BF|IF|KF|LF|OF|PF|RF|TF|UF|WF|XF|CBF|CDF|CHF|CLF|CMF|CPF|CXF|CYF|CZF)
|
||||
1139
bin/pax/pat_rep.c
Normal file
1139
bin/pax/pat_rep.c
Normal file
File diff suppressed because it is too large
Load Diff
51
bin/pax/pat_rep.h
Normal file
51
bin/pax/pat_rep.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* $NetBSD: pat_rep.h,v 1.7 2008/02/24 20:42:46 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)pat_rep.h 8.1 (Berkeley) 5/31/93
|
||||
*/
|
||||
|
||||
#include <regex.h>
|
||||
/*
|
||||
* data structure for storing user supplied replacement strings (-s)
|
||||
*/
|
||||
typedef struct replace {
|
||||
char *nstr; /* the new string we will substitute with */
|
||||
regex_t rcmp; /* compiled regular expression used to match */
|
||||
int flgs; /* print conversions? global in operation? */
|
||||
#define PRNT 0x1
|
||||
#define GLOB 0x2
|
||||
#define RENM 0x4
|
||||
#define SYML 0x8
|
||||
struct replace *fow; /* pointer to next pattern */
|
||||
} REPLACE;
|
||||
1281
bin/pax/pax.1
Normal file
1281
bin/pax/pax.1
Normal file
File diff suppressed because it is too large
Load Diff
496
bin/pax/pax.c
Normal file
496
bin/pax/pax.c
Normal file
@@ -0,0 +1,496 @@
|
||||
/* $NetBSD: pax.c,v 1.47 2011/08/29 14:47:48 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if !defined(lint)
|
||||
__COPYRIGHT("@(#) Copyright (c) 1992, 1993\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)pax.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: pax.c,v 1.47 2011/08/29 14:47:48 joerg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#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 <string.h>
|
||||
#include <errno.h>
|
||||
#include <paths.h>
|
||||
#include <util.h>
|
||||
#include "pax.h"
|
||||
#include "extern.h"
|
||||
static int gen_init(void);
|
||||
|
||||
/*
|
||||
* PAX main routines, general globals and some simple start up routines
|
||||
*/
|
||||
|
||||
/*
|
||||
* Variables that can be accessed by any routine within pax
|
||||
*/
|
||||
int act = ERROR; /* read/write/append/copy */
|
||||
FSUB *frmt = NULL; /* archive format type */
|
||||
int cflag; /* match all EXCEPT pattern/file */
|
||||
int cwdfd = -1; /* starting cwd */
|
||||
int dflag; /* directory member match only */
|
||||
int iflag; /* interactive file/archive rename */
|
||||
int kflag; /* do not overwrite existing files */
|
||||
int lflag; /* use hard links when possible */
|
||||
int nflag; /* select first archive member match */
|
||||
int tflag; /* restore access time after read */
|
||||
int uflag; /* ignore older modification time files */
|
||||
int vflag; /* produce verbose output */
|
||||
int Aflag; /* honor absolute path */
|
||||
int Dflag; /* same as uflag except inode change time */
|
||||
int Hflag; /* follow command line symlinks (write only) */
|
||||
int Lflag; /* follow symlinks when writing */
|
||||
int Mflag; /* treat stdin as an mtree(8) specfile */
|
||||
int Vflag; /* produce somewhat verbose output (no listing) */
|
||||
int Xflag; /* archive files with same device id only */
|
||||
int Yflag; /* same as Dflg except after name mode */
|
||||
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 */
|
||||
int to_stdout; /* extract to stdout */
|
||||
char *dirptr; /* destination dir in a copy */
|
||||
char *ltmfrmt; /* -v locale time format (if any) */
|
||||
const char *argv0; /* root of argv[0] */
|
||||
sigset_t s_mask; /* signal mask for cleanup critical sect */
|
||||
FILE *listf; /* 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 :
|
||||
*/
|
||||
int secure = 1; /* don't extract names that contain .. */
|
||||
|
||||
/*
|
||||
* PAX - Portable Archive Interchange
|
||||
*
|
||||
* A utility to read, write, and write lists of the members of archive
|
||||
* files and copy directory hierarchies. A variety of archive formats
|
||||
* are supported (some are described in POSIX 1003.1 10.1):
|
||||
*
|
||||
* ustar - 10.1.1 extended tar interchange format
|
||||
* cpio - 10.1.2 extended cpio interchange format
|
||||
* tar - old BSD 4.3 tar format
|
||||
* binary cpio - old cpio with binary header format
|
||||
* sysVR4 cpio - with and without CRC
|
||||
*
|
||||
* This version is a superset of IEEE Std 1003.2b-d3
|
||||
*
|
||||
* Summary of Extensions to the IEEE Standard:
|
||||
*
|
||||
* 1 READ ENHANCEMENTS
|
||||
* 1.1 Operations which read archives will continue to operate even when
|
||||
* processing archives which may be damaged, truncated, or fail to meet
|
||||
* format specs in several different ways. Damaged sections of archives
|
||||
* are detected and avoided if possible. Attempts will be made to resync
|
||||
* archive read operations even with badly damaged media.
|
||||
* 1.2 Blocksize requirements are not strictly enforced on archive read.
|
||||
* Tapes which have variable sized records can be read without errors.
|
||||
* 1.3 The user can specify via the non-standard option flag -E if error
|
||||
* resync operation should stop on a media error, try a specified number
|
||||
* of times to correct, or try to correct forever.
|
||||
* 1.4 Sparse files (lseek holes) stored on the archive (but stored with blocks
|
||||
* of all zeros will be restored with holes appropriate for the target
|
||||
* filesystem
|
||||
* 1.5 The user is notified whenever something is found during archive
|
||||
* read operations which violates spec (but the read will continue).
|
||||
* 1.6 Multiple archive volumes can be read and may span over different
|
||||
* archive devices
|
||||
* 1.7 Rigidly restores all file attributes exactly as they are stored on the
|
||||
* archive.
|
||||
* 1.8 Modification change time ranges can be specified via multiple -T
|
||||
* options. These allow a user to select files whose modification time
|
||||
* lies within a specific time range.
|
||||
* 1.9 Files can be selected based on owner (user name or uid) via one or more
|
||||
* -U options.
|
||||
* 1.10 Files can be selected based on group (group name or gid) via one o
|
||||
* more -G options.
|
||||
* 1.11 File modification time can be checked against existing file after
|
||||
* name modification (-Z)
|
||||
*
|
||||
* 2 WRITE ENHANCEMENTS
|
||||
* 2.1 Write operation will stop instead of allowing a user to create a flawed
|
||||
* flawed archive (due to any problem).
|
||||
* 2.2 Archives written by pax are forced to strictly conform to both the
|
||||
* archive and pax the specific format specifications.
|
||||
* 2.3 Blocking size and format is rigidly enforced on writes.
|
||||
* 2.4 Formats which may exhibit header overflow problems (they have fields
|
||||
* too small for large file systems, such as inode number storage), use
|
||||
* routines designed to repair this problem. These techniques still
|
||||
* conform to both pax and format specifications, but no longer truncate
|
||||
* these fields. This removes any restrictions on using these archive
|
||||
* formats on large file systems.
|
||||
* 2.5 Multiple archive volumes can be written and may span over different
|
||||
* archive devices
|
||||
* 2.6 A archive volume record limit allows the user to specify the number
|
||||
* of bytes stored on an archive volume. When reached the user is
|
||||
* prompted for the next archive volume. This is specified with the
|
||||
* non-standard -B flag. The limit is rounded up to the next blocksize.
|
||||
* 2.7 All archive padding during write use zero filled sections. This makes
|
||||
* it much easier to pull data out of flawed archive during read
|
||||
* operations.
|
||||
* 2.8 Access time reset with the -t applies to all file nodes (including
|
||||
* directories).
|
||||
* 2.9 Symbolic links can be followed with -L (optional in the spec).
|
||||
* 2.10 Modification or inode change time ranges can be specified via
|
||||
* multiple -T options. These allow a user to select files whose
|
||||
* modification or inode change time lies within a specific time range.
|
||||
* 2.11 Files can be selected based on owner (user name or uid) via one or more
|
||||
* -U options.
|
||||
* 2.12 Files can be selected based on group (group name or gid) via one o
|
||||
* more -G options.
|
||||
* 2.13 Symlinks which appear on the command line can be followed (without
|
||||
* following other symlinks; -H flag)
|
||||
*
|
||||
* 3 COPY ENHANCEMENTS
|
||||
* 3.1 Sparse files (lseek holes) can be copied without expanding the holes
|
||||
* into zero filled blocks. The file copy is created with holes which are
|
||||
* appropriate for the target filesystem
|
||||
* 3.2 Access time as well as modification time on copied file trees can be
|
||||
* preserved with the appropriate -p options.
|
||||
* 3.3 Access time reset with the -t applies to all file nodes (including
|
||||
* directories).
|
||||
* 3.4 Symbolic links can be followed with -L (optional in the spec).
|
||||
* 3.5 Modification or inode change time ranges can be specified via
|
||||
* multiple -T options. These allow a user to select files whose
|
||||
* modification or inode change time lies within a specific time range.
|
||||
* 3.6 Files can be selected based on owner (user name or uid) via one or more
|
||||
* -U options.
|
||||
* 3.7 Files can be selected based on group (group name or gid) via one o
|
||||
* more -G options.
|
||||
* 3.8 Symlinks which appear on the command line can be followed (without
|
||||
* following other symlinks; -H flag)
|
||||
* 3.9 File inode change time can be checked against existing file before
|
||||
* name modification (-D)
|
||||
* 3.10 File inode change time can be checked against existing file after
|
||||
* name modification (-Y)
|
||||
* 3.11 File modification time can be checked against existing file after
|
||||
* name modification (-Z)
|
||||
*
|
||||
* 4 GENERAL ENHANCEMENTS
|
||||
* 4.1 Internal structure is designed to isolate format dependent and
|
||||
* independent functions. Formats are selected via a format driver table.
|
||||
* This encourages the addition of new archive formats by only having to
|
||||
* write those routines which id, read and write the archive header.
|
||||
*/
|
||||
|
||||
/*
|
||||
* main()
|
||||
* parse options, set up and operate as specified by the user.
|
||||
* any operational flaw will set exit_val to non-zero
|
||||
* Return: 0 if ok, 1 otherwise
|
||||
*/
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
const char *tmpdir;
|
||||
size_t tdlen;
|
||||
int rval;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
listf = stderr;
|
||||
|
||||
/*
|
||||
* parse options, determine operational mode
|
||||
*/
|
||||
options(argc, argv);
|
||||
|
||||
/*
|
||||
* general init
|
||||
*/
|
||||
if ((gen_init() < 0) || (tty_init() < 0))
|
||||
return exit_val;
|
||||
|
||||
/*
|
||||
* Keep a reference to cwd, so we can always come back home.
|
||||
*/
|
||||
cwdfd = open(".", O_RDONLY);
|
||||
if (cwdfd < 0) {
|
||||
syswarn(1, errno, "Can't open current working directory.");
|
||||
return exit_val;
|
||||
}
|
||||
if (updatepath() == -1)
|
||||
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++ = '/';
|
||||
|
||||
(void)time(&starttime);
|
||||
#ifdef SIGINFO
|
||||
(void)signal(SIGINFO, ar_summary);
|
||||
#endif
|
||||
/*
|
||||
* select a primary operation mode
|
||||
*/
|
||||
switch (act) {
|
||||
case EXTRACT:
|
||||
rval = extract();
|
||||
break;
|
||||
case ARCHIVE:
|
||||
rval = archive();
|
||||
break;
|
||||
case APPND:
|
||||
if (gzip_program != NULL)
|
||||
err(1, "cannot gzip while appending");
|
||||
rval = append();
|
||||
/*
|
||||
* Check if we tried to append on an empty file and
|
||||
* turned into ARCHIVE mode.
|
||||
*/
|
||||
if (act == -ARCHIVE) {
|
||||
act = ARCHIVE;
|
||||
rval = archive();
|
||||
}
|
||||
break;
|
||||
case COPY:
|
||||
rval = copy();
|
||||
break;
|
||||
default:
|
||||
case LIST:
|
||||
rval = list();
|
||||
break;
|
||||
}
|
||||
if (rval != 0)
|
||||
exit_val = 1;
|
||||
return exit_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* sig_cleanup()
|
||||
* when interrupted we try to do whatever delayed processing we can.
|
||||
* This is not critical, but we really ought to limit our damage when we
|
||||
* are aborted by the user.
|
||||
* Return:
|
||||
* never....
|
||||
*/
|
||||
|
||||
__dead static void
|
||||
sig_cleanup(int which_sig)
|
||||
{
|
||||
/*
|
||||
* restore modes and times for any dirs we may have created
|
||||
* or any dirs we may have read. Set vflag and vfpart so the user
|
||||
* will clearly see the message on a line by itself.
|
||||
*/
|
||||
vflag = vfpart = 1;
|
||||
#ifdef SIGXCPU
|
||||
if (which_sig == SIGXCPU)
|
||||
tty_warn(1, "CPU time limit reached, cleaning up.");
|
||||
else
|
||||
#endif
|
||||
tty_warn(1, "Signal caught, cleaning up.");
|
||||
|
||||
/* delete any open temporary file */
|
||||
if (xtmp_name)
|
||||
(void)unlink(xtmp_name);
|
||||
ar_close();
|
||||
proc_dir();
|
||||
if (tflag)
|
||||
atdir_end();
|
||||
|
||||
(void)raise_default_signal(which_sig);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* gen_init()
|
||||
* general setup routines. Not all are required, but they really help
|
||||
* when dealing with a medium to large sized archives.
|
||||
*/
|
||||
|
||||
static int
|
||||
gen_init(void)
|
||||
{
|
||||
#ifndef __minix
|
||||
struct rlimit reslimit;
|
||||
#endif
|
||||
struct sigaction n_hand;
|
||||
struct sigaction o_hand;
|
||||
|
||||
#ifndef __minix
|
||||
/*
|
||||
* Really needed to handle large archives. We can run out of memory for
|
||||
* internal tables really fast when we have a whole lot of files...
|
||||
*/
|
||||
if (getrlimit(RLIMIT_DATA , &reslimit) == 0){
|
||||
reslimit.rlim_cur = reslimit.rlim_max;
|
||||
(void)setrlimit(RLIMIT_DATA , &reslimit);
|
||||
}
|
||||
|
||||
/*
|
||||
* should file size limits be waived? if the os limits us, this is
|
||||
* needed if we want to write a large archive
|
||||
*/
|
||||
if (getrlimit(RLIMIT_FSIZE , &reslimit) == 0){
|
||||
reslimit.rlim_cur = reslimit.rlim_max;
|
||||
(void)setrlimit(RLIMIT_FSIZE , &reslimit);
|
||||
}
|
||||
|
||||
/*
|
||||
* increase the size the stack can grow to
|
||||
*/
|
||||
if (getrlimit(RLIMIT_STACK , &reslimit) == 0){
|
||||
reslimit.rlim_cur = reslimit.rlim_max;
|
||||
(void)setrlimit(RLIMIT_STACK , &reslimit);
|
||||
}
|
||||
|
||||
#ifdef RLIMIT_RSS
|
||||
/*
|
||||
* not really needed, but doesn't hurt
|
||||
*/
|
||||
if (getrlimit(RLIMIT_RSS , &reslimit) == 0){
|
||||
reslimit.rlim_cur = reslimit.rlim_max;
|
||||
(void)setrlimit(RLIMIT_RSS , &reslimit);
|
||||
}
|
||||
#endif
|
||||
#endif /* __minix */
|
||||
|
||||
/*
|
||||
* 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
|
||||
* deal with any file size limit through failed writes. CPU time
|
||||
* limits are caught and a cleanup is forced.
|
||||
*/
|
||||
if ((sigemptyset(&s_mask) < 0) || (sigaddset(&s_mask, SIGTERM) < 0) ||
|
||||
(sigaddset(&s_mask,SIGINT) < 0)||(sigaddset(&s_mask,SIGHUP) < 0) ||
|
||||
(sigaddset(&s_mask,SIGPIPE) < 0)||(sigaddset(&s_mask,SIGQUIT)<0)){
|
||||
tty_warn(1, "Unable to set up signal mask");
|
||||
return -1;
|
||||
}
|
||||
#ifdef SIGXCPU
|
||||
if (sigaddset(&s_mask,SIGXCPU) < 0) {
|
||||
tty_warn(1, "Unable to set up signal mask");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#ifdef SIGXFSZ
|
||||
if (sigaddset(&s_mask,SIGXFSZ) < 0) {
|
||||
tty_warn(1, "Unable to set up signal mask");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(&n_hand, 0, sizeof n_hand);
|
||||
n_hand.sa_mask = s_mask;
|
||||
n_hand.sa_flags = 0;
|
||||
n_hand.sa_handler = sig_cleanup;
|
||||
|
||||
if ((sigaction(SIGHUP, &n_hand, &o_hand) < 0) &&
|
||||
(o_hand.sa_handler == SIG_IGN) &&
|
||||
(sigaction(SIGHUP, &o_hand, &o_hand) < 0))
|
||||
goto out;
|
||||
|
||||
if ((sigaction(SIGTERM, &n_hand, &o_hand) < 0) &&
|
||||
(o_hand.sa_handler == SIG_IGN) &&
|
||||
(sigaction(SIGTERM, &o_hand, &o_hand) < 0))
|
||||
goto out;
|
||||
|
||||
if ((sigaction(SIGINT, &n_hand, &o_hand) < 0) &&
|
||||
(o_hand.sa_handler == SIG_IGN) &&
|
||||
(sigaction(SIGINT, &o_hand, &o_hand) < 0))
|
||||
goto out;
|
||||
|
||||
if ((sigaction(SIGQUIT, &n_hand, &o_hand) < 0) &&
|
||||
(o_hand.sa_handler == SIG_IGN) &&
|
||||
(sigaction(SIGQUIT, &o_hand, &o_hand) < 0))
|
||||
goto out;
|
||||
|
||||
#ifdef SIGXCPU
|
||||
if ((sigaction(SIGXCPU, &n_hand, &o_hand) < 0) &&
|
||||
(o_hand.sa_handler == SIG_IGN) &&
|
||||
(sigaction(SIGXCPU, &o_hand, &o_hand) < 0))
|
||||
goto out;
|
||||
#endif
|
||||
n_hand.sa_handler = SIG_IGN;
|
||||
if (sigaction(SIGPIPE, &n_hand, &o_hand) < 0)
|
||||
goto out;
|
||||
#ifdef SIGXFSZ
|
||||
if (sigaction(SIGXFSZ, &n_hand, &o_hand) < 0)
|
||||
goto out;
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
out:
|
||||
syswarn(1, errno, "Unable to set up signal handler");
|
||||
return -1;
|
||||
}
|
||||
283
bin/pax/pax.h
Normal file
283
bin/pax/pax.h
Normal file
@@ -0,0 +1,283 @@
|
||||
/* $NetBSD: pax.h,v 1.31 2012/08/09 08:09:21 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)pax.h 8.2 (Berkeley) 4/18/94
|
||||
*/
|
||||
|
||||
#if ! HAVE_NBTOOL_CONFIG_H && !defined(__minix)
|
||||
#define HAVE_LUTIMES 1
|
||||
#define HAVE_STRUCT_STAT_ST_FLAGS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* BSD PAX global data structures and constants.
|
||||
*/
|
||||
|
||||
#define MAXBLK 32256 /* MAX blocksize supported (posix SPEC) */
|
||||
/* WARNING: increasing MAXBLK past 32256 */
|
||||
/* will violate posix spec. */
|
||||
#define BLKMULT 512 /* blocksize must be even mult of 512 bytes */
|
||||
/* Don't even think of changing this */
|
||||
#define DEVBLK 8192 /* default read blksize for devices */
|
||||
#define FILEBLK 10240 /* default read blksize for files */
|
||||
#define PAXPATHLEN 3072 /* maximum path length for pax. MUST be */
|
||||
/* longer than the system MAXPATHLEN */
|
||||
|
||||
/*
|
||||
* Pax modes of operation
|
||||
*/
|
||||
#define ERROR -1 /* nothing selected */
|
||||
#define LIST 0 /* List the file in an archive */
|
||||
#define EXTRACT 1 /* extract the files in an archive */
|
||||
#define ARCHIVE 2 /* write a new archive */
|
||||
#define APPND 3 /* append to the end of an archive */
|
||||
#define COPY 4 /* copy files to destination dir */
|
||||
|
||||
/*
|
||||
* Device type of the current archive volume
|
||||
*/
|
||||
#define ISREG 0 /* regular file */
|
||||
#define ISCHR 1 /* character device */
|
||||
#define ISBLK 2 /* block device */
|
||||
#define ISTAPE 3 /* tape drive */
|
||||
#define ISPIPE 4 /* pipe/socket */
|
||||
#ifdef SUPPORT_RMT
|
||||
#define ISRMT 5 /* rmt */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Pattern matching structure
|
||||
*
|
||||
* Used to store command line patterns
|
||||
*/
|
||||
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 NOGLOB_MTCH 0x4 /* non-globbing match */
|
||||
struct pattern *fow; /* next pattern */
|
||||
} PATTERN;
|
||||
|
||||
/*
|
||||
* General Archive Structure (used internal to pax)
|
||||
*
|
||||
* This structure is used to pass information about archive members between
|
||||
* the format independent routines and the format specific routines. When
|
||||
* new archive formats are added, they must accept requests and supply info
|
||||
* encoded in a structure of this type. The name fields are declared statically
|
||||
* here, as there is only ONE of these floating around, size is not a major
|
||||
* consideration. Eventually converting the name fields to a dynamic length
|
||||
* may be required if and when the supporting operating system removes all
|
||||
* restrictions on the length of pathnames it will resolve.
|
||||
*/
|
||||
typedef struct {
|
||||
int nlen; /* file name length */
|
||||
char name[PAXPATHLEN+1]; /* file name */
|
||||
int ln_nlen; /* link name length */
|
||||
char ln_name[PAXPATHLEN+1]; /* name to link to (if any) */
|
||||
char *org_name; /* orig name in file system */
|
||||
char fts_name[PAXPATHLEN+1]; /* name from fts (for *org_name) */
|
||||
char *tmp_name; /* tmp name used to restore */
|
||||
PATTERN *pat; /* ptr to pattern match (if any) */
|
||||
struct stat sb; /* stat buffer see stat(2) */
|
||||
off_t pad; /* bytes of padding after file xfer */
|
||||
off_t skip; /* bytes of real data after header */
|
||||
/* IMPORTANT. The st_size field does */
|
||||
/* not always indicate the amount of */
|
||||
/* data following the header. */
|
||||
u_long crc; /* file crc */
|
||||
int type; /* type of file node */
|
||||
#define PAX_DIR 1 /* directory */
|
||||
#define PAX_CHR 2 /* character device */
|
||||
#define PAX_BLK 3 /* block device */
|
||||
#define PAX_REG 4 /* regular file */
|
||||
#define PAX_SLK 5 /* symbolic link */
|
||||
#define PAX_SCK 6 /* socket */
|
||||
#define PAX_FIF 7 /* fifo */
|
||||
#define PAX_HLK 8 /* hard link */
|
||||
#define PAX_HRG 9 /* hard link to a regular file */
|
||||
#define PAX_CTG 10 /* high performance file */
|
||||
#define PAX_GLL 11 /* GNU long symlink */
|
||||
#define PAX_GLF 12 /* GNU long file */
|
||||
} ARCHD;
|
||||
|
||||
/*
|
||||
* Format Specific Routine Table
|
||||
*
|
||||
* The format specific routine table allows new archive formats to be quickly
|
||||
* added. Overall pax operation is independent of the actual format used to
|
||||
* form the archive. Only those routines which deal directly with the archive
|
||||
* are tailored to the oddities of the specific format. All other routines are
|
||||
* independent of the archive format. Data flow in and out of the format
|
||||
* dependent routines pass pointers to ARCHD structure (described below).
|
||||
*/
|
||||
typedef struct {
|
||||
const char *name; /* name of format, this is the name the user */
|
||||
/* gives to -x option to select it. */
|
||||
int bsz; /* default block size. used when the user */
|
||||
/* does not specify a blocksize for writing */
|
||||
/* Appends continue to with the blocksize */
|
||||
/* the archive is currently using.*/
|
||||
int hsz; /* Header size in bytes. this is the size of */
|
||||
/* the smallest header this format supports. */
|
||||
/* Headers are assumed to fit in a BLKMULT. */
|
||||
/* If they are bigger, get_head() and */
|
||||
/* get_arc() must be adjusted */
|
||||
int udev; /* does append require unique dev/ino? some */
|
||||
/* formats use the device and inode fields */
|
||||
/* to specify hard links. when members in */
|
||||
/* the archive have the same inode/dev they */
|
||||
/* are assumed to be hard links. During */
|
||||
/* append we may have to generate unique ids */
|
||||
/* to avoid creating incorrect hard links */
|
||||
int hlk; /* does archive store hard links info? if */
|
||||
/* not, we do not bother to look for them */
|
||||
/* during archive write operations */
|
||||
int blkalgn; /* writes must be aligned to blkalgn boundary */
|
||||
int inhead; /* is the trailer encoded in a valid header? */
|
||||
/* if not, trailers are assumed to be found */
|
||||
/* in invalid headers (i.e like tar) */
|
||||
int (*id)(char *, int); /* checks if a buffer is a valid header */
|
||||
/* returns 1 if it is, o.w. returns a 0 */
|
||||
int (*st_rd)(void); /* initialize routine for read. so format */
|
||||
/* can set up tables etc before it starts */
|
||||
/* reading an archive */
|
||||
int (*rd) /* read header routine. passed a pointer to */
|
||||
(ARCHD *, char *); /* ARCHD. It must extract the info */
|
||||
/* from the format and store it in the ARCHD */
|
||||
/* struct. This routine is expected to fill */
|
||||
/* all the fields in the ARCHD (including */
|
||||
/* stat buf). 0 is returned when a valid */
|
||||
/* header is found. -1 when not valid. This */
|
||||
/* routine set the skip and pad fields so the */
|
||||
/* format independent routines know the */
|
||||
/* amount of padding and the number of bytes */
|
||||
/* of data which follow the header. This info */
|
||||
/* is used to skip to the next file header */
|
||||
off_t (*end_rd)(void); /* read cleanup. Allows format to clean up */
|
||||
/* and MUST RETURN THE LENGTH OF THE TRAILER */
|
||||
/* RECORD (so append knows how many bytes */
|
||||
/* to move back to rewrite the trailer) */
|
||||
int (*st_wr)(void); /* initialize routine for write operations */
|
||||
int (*wr)(ARCHD *); /* write archive header. Passed an ARCHD */
|
||||
/* filled with the specs on the next file to */
|
||||
/* archived. Returns a 1 if no file data is */
|
||||
/* is to be stored; 0 if file data is to be */
|
||||
/* added. A -1 is returned if a write */
|
||||
/* operation to the archive failed. this */
|
||||
/* function sets the skip and pad fields so */
|
||||
/* the proper padding can be added after */
|
||||
/* file data. This routine must NEVER write */
|
||||
/* a flawed archive header. */
|
||||
int (*end_wr)(void); /* end write. write the trailer and do any */
|
||||
/* other format specific functions needed */
|
||||
/* at the end of an archive write */
|
||||
int (*trail) /* returns 0 if a valid trailer, -1 if not */
|
||||
(char *, int, int *); /* For formats which encode the */
|
||||
/* trailer outside of a valid header, a */
|
||||
/* return value of 1 indicates that the block */
|
||||
/* passed to it can never contain a valid */
|
||||
/* header (skip this block, no point in */
|
||||
/* looking at it) */
|
||||
int (*subtrail) /* read/process file data from the archive */
|
||||
(ARCHD *); /* this function is called for trailers */
|
||||
/* inside headers. */
|
||||
int (*rd_data) /* read/process file data from the archive */
|
||||
(ARCHD *, int, off_t *);
|
||||
int (*wr_data) /* write/process file data to the archive */
|
||||
(ARCHD *, int, off_t *);
|
||||
int (*options)(void); /* process format specific options (-o) */
|
||||
} FSUB;
|
||||
|
||||
/*
|
||||
* Format Specific Options List
|
||||
*
|
||||
* Used to pass format options to the format options handler
|
||||
*/
|
||||
typedef struct oplist {
|
||||
char *name; /* option variable name e.g. name= */
|
||||
char *value; /* value for option variable */
|
||||
struct oplist *fow; /* next option */
|
||||
} OPLIST;
|
||||
|
||||
/*
|
||||
* General Macros
|
||||
*/
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#endif
|
||||
|
||||
#ifdef HOSTPROG
|
||||
# include "pack_dev.h" /* explicitly use NetBSD's macros */
|
||||
# define MAJOR(x) major_netbsd(x)
|
||||
# define MINOR(x) minor_netbsd(x)
|
||||
# define TODEV(x, y) makedev_netbsd((x), (y))
|
||||
#else
|
||||
# define MAJOR(x) major(x)
|
||||
# define MINOR(x) minor(x)
|
||||
# define TODEV(x, y) makedev((x), (y))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* General Defines
|
||||
*/
|
||||
#define HEX 16
|
||||
#define OCT 8
|
||||
#define _PAX_ 1
|
||||
|
||||
/*
|
||||
* Pathname base component of the temporary file template, to be created in
|
||||
* ${TMPDIR} or, as a fall-back, _PATH_TMP.
|
||||
*/
|
||||
#define _TFILE_BASE "paxXXXXXXXXXX"
|
||||
|
||||
/*
|
||||
* Macros to manipulate off_t as uintmax_t
|
||||
*/
|
||||
#define OFFT_F "%" PRIuMAX
|
||||
#define OFFT_FP(x) "%" x PRIuMAX
|
||||
#define OFFT_T uintmax_t
|
||||
#define ASC_OFFT(x,y,z) asc_umax(x,y,z)
|
||||
#define OFFT_ASC(w,x,y,z) umax_asc((uintmax_t)w,x,y,z)
|
||||
#define OFFT_OCT(w,x,y,z) umax_oct((uintmax_t)w,x,y,z)
|
||||
#define STRTOOFFT(x,y,z) strtoimax(x,y,z)
|
||||
#define OFFT_MAX INTMAX_MAX
|
||||
|
||||
#define TOP_HALF 0xffffffff00000000ULL
|
||||
#define BOTTOM_HALF 0x00000000ffffffffULL
|
||||
|
||||
617
bin/pax/sel_subs.c
Normal file
617
bin/pax/sel_subs.c
Normal file
@@ -0,0 +1,617 @@
|
||||
/* $NetBSD: sel_subs.c,v 1.24 2011/08/31 16:24:54 plunky Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)sel_subs.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: sel_subs.c,v 1.24 2011/08/31 16:24:54 plunky Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <tzfile.h>
|
||||
|
||||
#include "pax.h"
|
||||
#include "sel_subs.h"
|
||||
#include "extern.h"
|
||||
|
||||
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 */
|
||||
static USRT **usrtb = NULL; /* user selection table */
|
||||
static GRPT **grptb = NULL; /* group selection table */
|
||||
|
||||
/*
|
||||
* Routines for selection of archive members
|
||||
*/
|
||||
|
||||
/*
|
||||
* sel_chk()
|
||||
* 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
|
||||
*/
|
||||
|
||||
int
|
||||
sel_chk(ARCHD *arcn)
|
||||
{
|
||||
if (((usrtb != NULL) && usr_match(arcn)) ||
|
||||
((grptb != NULL) && grp_match(arcn)) ||
|
||||
((trhead != NULL) && trng_match(arcn)))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 the name or the uid/gid starting with
|
||||
* a # on the command line. A \# will escape the #.
|
||||
*/
|
||||
|
||||
/*
|
||||
* usr_add()
|
||||
* add a user match to the user match hash table
|
||||
* Return:
|
||||
* 0 if added ok, -1 otherwise;
|
||||
*/
|
||||
|
||||
int
|
||||
usr_add(char *str)
|
||||
{
|
||||
u_int indx;
|
||||
USRT *pt;
|
||||
struct passwd *pw;
|
||||
uid_t uid;
|
||||
|
||||
/*
|
||||
* create the table if it doesn't exist
|
||||
*/
|
||||
if ((str == NULL) || (*str == '\0'))
|
||||
return -1;
|
||||
if ((usrtb == NULL) &&
|
||||
((usrtb = (USRT **)calloc(USR_TB_SZ, sizeof(USRT *))) == NULL)) {
|
||||
tty_warn(1,
|
||||
"Unable to allocate memory for user selection table");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* figure out user spec
|
||||
*/
|
||||
if (str[0] != '#') {
|
||||
/*
|
||||
* it is a user name, \# escapes # as first char in user name
|
||||
*/
|
||||
if ((str[0] == '\\') && (str[1] == '#'))
|
||||
++str;
|
||||
if ((pw = getpwnam(str)) == NULL) {
|
||||
tty_warn(1, "Unable to find uid for user: %s", str);
|
||||
return -1;
|
||||
}
|
||||
uid = (uid_t)pw->pw_uid;
|
||||
} else
|
||||
uid = (uid_t)strtoul(str+1, NULL, 10);
|
||||
endpwent();
|
||||
|
||||
/*
|
||||
* hash it and go down the hash chain (if any) looking for it
|
||||
*/
|
||||
indx = ((unsigned)uid) % USR_TB_SZ;
|
||||
if ((pt = usrtb[indx]) != NULL) {
|
||||
while (pt != NULL) {
|
||||
if (pt->uid == uid)
|
||||
return 0;
|
||||
pt = pt->fow;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* uid is not yet in the table, add it to the front of the chain
|
||||
*/
|
||||
if ((pt = (USRT *)malloc(sizeof(USRT))) != NULL) {
|
||||
pt->uid = uid;
|
||||
pt->fow = usrtb[indx];
|
||||
usrtb[indx] = pt;
|
||||
return 0;
|
||||
}
|
||||
tty_warn(1, "User selection table out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* usr_match()
|
||||
* check if this files uid matches a selected uid.
|
||||
* Return:
|
||||
* 0 if this archive member should be processed, 1 if it should be skipped
|
||||
*/
|
||||
|
||||
static int
|
||||
usr_match(ARCHD *arcn)
|
||||
{
|
||||
USRT *pt;
|
||||
|
||||
/*
|
||||
* hash and look for it in the table
|
||||
*/
|
||||
pt = usrtb[((unsigned)arcn->sb.st_uid) % USR_TB_SZ];
|
||||
while (pt != NULL) {
|
||||
if (pt->uid == arcn->sb.st_uid)
|
||||
return 0;
|
||||
pt = pt->fow;
|
||||
}
|
||||
|
||||
/*
|
||||
* not found
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* grp_add()
|
||||
* add a group match to the group match hash table
|
||||
* Return:
|
||||
* 0 if added ok, -1 otherwise;
|
||||
*/
|
||||
|
||||
int
|
||||
grp_add(char *str)
|
||||
{
|
||||
u_int indx;
|
||||
GRPT *pt;
|
||||
struct group *gr;
|
||||
gid_t gid;
|
||||
|
||||
/*
|
||||
* create the table if it doesn't exist
|
||||
*/
|
||||
if ((str == NULL) || (*str == '\0'))
|
||||
return -1;
|
||||
if ((grptb == NULL) &&
|
||||
((grptb = (GRPT **)calloc(GRP_TB_SZ, sizeof(GRPT *))) == NULL)) {
|
||||
tty_warn(1,
|
||||
"Unable to allocate memory fo group selection table");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* figure out user spec
|
||||
*/
|
||||
if (str[0] != '#') {
|
||||
/*
|
||||
* it is a group name, \# escapes # as first char in group name
|
||||
*/
|
||||
if ((str[0] == '\\') && (str[1] == '#'))
|
||||
++str;
|
||||
if ((gr = getgrnam(str)) == NULL) {
|
||||
tty_warn(1,
|
||||
"Cannot determine gid for group name: %s", str);
|
||||
return -1;
|
||||
}
|
||||
gid = (gid_t)gr->gr_gid;
|
||||
} else
|
||||
gid = (gid_t)strtoul(str+1, NULL, 10);
|
||||
endgrent();
|
||||
|
||||
/*
|
||||
* hash it and go down the hash chain (if any) looking for it
|
||||
*/
|
||||
indx = ((unsigned)gid) % GRP_TB_SZ;
|
||||
if ((pt = grptb[indx]) != NULL) {
|
||||
while (pt != NULL) {
|
||||
if (pt->gid == gid)
|
||||
return 0;
|
||||
pt = pt->fow;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gid not in the table, add it to the front of the chain
|
||||
*/
|
||||
if ((pt = (GRPT *)malloc(sizeof(GRPT))) != NULL) {
|
||||
pt->gid = gid;
|
||||
pt->fow = grptb[indx];
|
||||
grptb[indx] = pt;
|
||||
return 0;
|
||||
}
|
||||
tty_warn(1, "Group selection table out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* grp_match()
|
||||
* check if this files gid matches a selected gid.
|
||||
* Return:
|
||||
* 0 if this archive member should be processed, 1 if it should be skipped
|
||||
*/
|
||||
|
||||
static int
|
||||
grp_match(ARCHD *arcn)
|
||||
{
|
||||
GRPT *pt;
|
||||
|
||||
/*
|
||||
* hash and look for it in the table
|
||||
*/
|
||||
pt = grptb[((unsigned)arcn->sb.st_gid) % GRP_TB_SZ];
|
||||
while (pt != NULL) {
|
||||
if (pt->gid == arcn->sb.st_gid)
|
||||
return 0;
|
||||
pt = pt->fow;
|
||||
}
|
||||
|
||||
/*
|
||||
* not found
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Time range selection routines
|
||||
*
|
||||
* Routines to handle user selection of files based on the modification and/or
|
||||
* inode change time falling within a specified time range (the non-standard
|
||||
* -T flag). The user may specify any number of different file time ranges.
|
||||
* Time ranges are checked one at a time until a match is found (if at all).
|
||||
* If the file has a mtime (and/or ctime) which lies within one of the time
|
||||
* ranges, the file is selected. Time ranges may have a lower and/or a upper
|
||||
* value. These ranges are inclusive. When no time ranges are supplied to pax
|
||||
* with the -T option, all members in the archive will be selected by the time
|
||||
* range routines. When only a lower range is supplied, only files with a
|
||||
* mtime (and/or ctime) equal to or younger are selected. When only a upper
|
||||
* range is supplied, only files with a mtime (and/or ctime) equal to or older
|
||||
* are selected. When the lower time range is equal to the upper time range,
|
||||
* only files with a mtime (or ctime) of exactly that time are selected.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* 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
|
||||
*/
|
||||
|
||||
int
|
||||
trng_add(char *str)
|
||||
{
|
||||
TIME_RNG *pt;
|
||||
char *up_pt = NULL;
|
||||
char *stpt;
|
||||
char *flgpt;
|
||||
int dot = 0;
|
||||
|
||||
/*
|
||||
* throw out the badly formed time ranges
|
||||
*/
|
||||
if ((str == NULL) || (*str == '\0')) {
|
||||
tty_warn(1, "Empty time range string");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* locate optional flags suffix /{cm}.
|
||||
*/
|
||||
if ((flgpt = strrchr(str, '/')) != NULL)
|
||||
*flgpt++ = '\0';
|
||||
|
||||
for (stpt = str; *stpt != '\0'; ++stpt) {
|
||||
if ((*stpt >= '0') && (*stpt <= '9'))
|
||||
continue;
|
||||
if ((*stpt == ',') && (up_pt == NULL)) {
|
||||
*stpt = '\0';
|
||||
up_pt = stpt + 1;
|
||||
dot = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* allow only one dot per range (secs)
|
||||
*/
|
||||
if ((*stpt == '.') && (!dot)) {
|
||||
++dot;
|
||||
continue;
|
||||
}
|
||||
tty_warn(1, "Improperly specified time range: %s", str);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate space for the time range and store the limits
|
||||
*/
|
||||
if ((pt = malloc(sizeof(TIME_RNG))) == NULL) {
|
||||
tty_warn(1, "Unable to allocate memory for time range");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* by default we only will check file mtime, but user can specify
|
||||
* mtime, ctime (inode change time) or both.
|
||||
*/
|
||||
if ((flgpt == NULL) || (*flgpt == '\0'))
|
||||
pt->flgs = CMPMTME;
|
||||
else {
|
||||
pt->flgs = 0;
|
||||
while (*flgpt != '\0') {
|
||||
switch(*flgpt) {
|
||||
case 'M':
|
||||
case 'm':
|
||||
pt->flgs |= CMPMTME;
|
||||
break;
|
||||
case 'C':
|
||||
case 'c':
|
||||
pt->flgs |= CMPCTME;
|
||||
break;
|
||||
default:
|
||||
tty_warn(1, "Bad option %c with time range %s",
|
||||
*flgpt, str);
|
||||
free(pt);
|
||||
goto out;
|
||||
}
|
||||
++flgpt;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* start off with the current time
|
||||
*/
|
||||
pt->low_time = pt->high_time = time(NULL);
|
||||
if (*str != '\0') {
|
||||
/*
|
||||
* add lower limit
|
||||
*/
|
||||
if (str_sec(str, &(pt->low_time)) < 0) {
|
||||
tty_warn(1, "Illegal lower time range %s", str);
|
||||
free(pt);
|
||||
goto out;
|
||||
}
|
||||
pt->flgs |= HASLOW;
|
||||
}
|
||||
|
||||
if ((up_pt != NULL) && (*up_pt != '\0')) {
|
||||
/*
|
||||
* add upper limit
|
||||
*/
|
||||
if (str_sec(up_pt, &(pt->high_time)) < 0) {
|
||||
tty_warn(1, "Illegal upper time range %s", up_pt);
|
||||
free(pt);
|
||||
goto out;
|
||||
}
|
||||
pt->flgs |= HASHIGH;
|
||||
|
||||
/*
|
||||
* check that the upper and lower do not overlap
|
||||
*/
|
||||
if (pt->flgs & HASLOW) {
|
||||
if (pt->low_time > pt->high_time) {
|
||||
tty_warn(1,
|
||||
"Upper %s and lower %s time overlap",
|
||||
up_pt, str);
|
||||
free(pt);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pt->fow = NULL;
|
||||
if (trhead == NULL) {
|
||||
trtail = trhead = pt;
|
||||
return 0;
|
||||
}
|
||||
trtail->fow = pt;
|
||||
trtail = pt;
|
||||
return 0;
|
||||
|
||||
out:
|
||||
tty_warn(1, "Time range format is: [yy[mm[dd[hh]]]]mm[.ss][/[c][m]]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* trng_match()
|
||||
* check if this files mtime/ctime falls within any supplied time range.
|
||||
* Return:
|
||||
* 0 if this archive member should be processed, 1 if it should be skipped
|
||||
*/
|
||||
|
||||
static int
|
||||
trng_match(ARCHD *arcn)
|
||||
{
|
||||
TIME_RNG *pt;
|
||||
|
||||
/*
|
||||
* have to search down the list one at a time looking for a match.
|
||||
* remember time range limits are inclusive.
|
||||
*/
|
||||
pt = trhead;
|
||||
while (pt != NULL) {
|
||||
switch(pt->flgs & CMPBOTH) {
|
||||
case CMPBOTH:
|
||||
/*
|
||||
* user wants both mtime and ctime checked for this
|
||||
* time range
|
||||
*/
|
||||
if (((pt->flgs & HASLOW) &&
|
||||
(arcn->sb.st_mtime < pt->low_time) &&
|
||||
(arcn->sb.st_ctime < pt->low_time)) ||
|
||||
((pt->flgs & HASHIGH) &&
|
||||
(arcn->sb.st_mtime > pt->high_time) &&
|
||||
(arcn->sb.st_ctime > pt->high_time))) {
|
||||
pt = pt->fow;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case CMPCTME:
|
||||
/*
|
||||
* user wants only ctime checked for this time range
|
||||
*/
|
||||
if (((pt->flgs & HASLOW) &&
|
||||
(arcn->sb.st_ctime < pt->low_time)) ||
|
||||
((pt->flgs & HASHIGH) &&
|
||||
(arcn->sb.st_ctime > pt->high_time))) {
|
||||
pt = pt->fow;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case CMPMTME:
|
||||
default:
|
||||
/*
|
||||
* user wants only mtime checked for this time range
|
||||
*/
|
||||
if (((pt->flgs & HASLOW) &&
|
||||
(arcn->sb.st_mtime < pt->low_time)) ||
|
||||
((pt->flgs & HASHIGH) &&
|
||||
(arcn->sb.st_mtime > pt->high_time))) {
|
||||
pt = pt->fow;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (pt == NULL)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* Return:
|
||||
* 0 if converted ok, -1 otherwise
|
||||
*/
|
||||
|
||||
#define ATOI2(s) ((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0'))
|
||||
|
||||
static int
|
||||
str_sec(const char *p, time_t *tval)
|
||||
{
|
||||
struct tm *lt;
|
||||
const char *dot, *t;
|
||||
int yearset, len;
|
||||
|
||||
for (t = p, dot = NULL; *t; ++t) {
|
||||
if (isdigit((unsigned char)*t))
|
||||
continue;
|
||||
if (*t == '.' && dot == NULL) {
|
||||
dot = t;
|
||||
continue;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
lt = localtime(tval);
|
||||
|
||||
if (dot != NULL) {
|
||||
len = strlen(dot);
|
||||
if (len != 3)
|
||||
return -1;
|
||||
++dot;
|
||||
lt->tm_sec = ATOI2(dot);
|
||||
} else {
|
||||
len = 0;
|
||||
lt->tm_sec = 0;
|
||||
}
|
||||
|
||||
yearset = 0;
|
||||
switch (strlen(p) - len) {
|
||||
case 12:
|
||||
lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE;
|
||||
yearset = 1;
|
||||
/* FALLTHROUGH */
|
||||
case 10:
|
||||
if (yearset) {
|
||||
lt->tm_year += ATOI2(p);
|
||||
} else {
|
||||
yearset = ATOI2(p);
|
||||
if (yearset < 69)
|
||||
lt->tm_year = yearset + 2000 - TM_YEAR_BASE;
|
||||
else
|
||||
lt->tm_year = yearset + 1900 - TM_YEAR_BASE;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case 8:
|
||||
lt->tm_mon = ATOI2(p);
|
||||
--lt->tm_mon;
|
||||
/* FALLTHROUGH */
|
||||
case 6:
|
||||
lt->tm_mday = ATOI2(p);
|
||||
/* FALLTHROUGH */
|
||||
case 4:
|
||||
lt->tm_hour = ATOI2(p);
|
||||
/* FALLTHROUGH */
|
||||
case 2:
|
||||
lt->tm_min = ATOI2(p);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert broken-down time to GMT clock time seconds
|
||||
*/
|
||||
if ((*tval = mktime(lt)) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
69
bin/pax/sel_subs.h
Normal file
69
bin/pax/sel_subs.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* $NetBSD: sel_subs.h,v 1.6 2003/10/13 07:41:22 agc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)sel_subs.h 8.1 (Berkeley) 5/31/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* data structure for storing uid/grp selects (-U, -G non standard options)
|
||||
*/
|
||||
|
||||
#define USR_TB_SZ 317 /* user selection table size */
|
||||
#define GRP_TB_SZ 317 /* user selection table size */
|
||||
|
||||
typedef struct usrt {
|
||||
uid_t uid;
|
||||
struct usrt *fow; /* next uid */
|
||||
} USRT;
|
||||
|
||||
typedef struct grpt {
|
||||
gid_t gid;
|
||||
struct grpt *fow; /* next gid */
|
||||
} GRPT;
|
||||
|
||||
/*
|
||||
* data structure for storing user supplied time ranges (-T option)
|
||||
*/
|
||||
|
||||
typedef struct time_rng {
|
||||
time_t low_time; /* lower inclusive time limit */
|
||||
time_t high_time; /* higher inclusive time limit */
|
||||
int flgs; /* option flags */
|
||||
#define HASLOW 0x01 /* has lower time limit */
|
||||
#define HASHIGH 0x02 /* has higher time limit */
|
||||
#define CMPMTME 0x04 /* compare file modification time */
|
||||
#define CMPCTME 0x08 /* compare inode change time */
|
||||
#define CMPBOTH (CMPMTME|CMPCTME) /* compare inode and mod time */
|
||||
struct time_rng *fow; /* next pattern */
|
||||
} TIME_RNG;
|
||||
1377
bin/pax/tables.c
Normal file
1377
bin/pax/tables.c
Normal file
File diff suppressed because it is too large
Load Diff
176
bin/pax/tables.h
Normal file
176
bin/pax/tables.h
Normal file
@@ -0,0 +1,176 @@
|
||||
/* $NetBSD: tables.h,v 1.10 2007/04/29 20:23:34 msaitoh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)tables.h 8.1 (Berkeley) 5/31/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* data structures and constants used by the different databases kept by pax
|
||||
*/
|
||||
|
||||
/*
|
||||
* Hash Table Sizes MUST BE PRIME, if set too small performance suffers.
|
||||
* Probably safe to expect 500000 inodes per tape. Assuming good key
|
||||
* distribution (inodes) chains of under 50 long (worse case) is ok.
|
||||
*/
|
||||
#define L_TAB_SZ 2503 /* hard link hash table size */
|
||||
#define F_TAB_SZ 50503 /* file time hash table size */
|
||||
#define N_TAB_SZ 541 /* interactive rename hash table */
|
||||
#define D_TAB_SZ 317 /* unique device mapping table */
|
||||
#define A_TAB_SZ 317 /* ftree dir access time reset table */
|
||||
#define MAXKEYLEN 64 /* max number of chars for hash */
|
||||
|
||||
/*
|
||||
* file hard link structure (hashed by dev/ino and chained) used to find the
|
||||
* hard links in a file system or with some archive formats (cpio)
|
||||
*/
|
||||
typedef struct hrdlnk {
|
||||
char *name; /* name of first file seen with this ino/dev */
|
||||
dev_t dev; /* files device number */
|
||||
ino_t ino; /* files inode number */
|
||||
u_long nlink; /* expected link count */
|
||||
struct hrdlnk *fow;
|
||||
} HRDLNK;
|
||||
|
||||
/*
|
||||
* Archive write update file time table (the -u, -C flag), hashed by filename.
|
||||
* Filenames are stored in a scratch file at seek offset into the file. The
|
||||
* file time (mod time) and the file name length (for a quick check) are
|
||||
* stored in a hash table node. We were forced to use a scratch file because
|
||||
* with -u, the mtime for every node in the archive must always be available
|
||||
* to compare against (and this data can get REALLY large with big archives).
|
||||
* By being careful to read only when we have a good chance of a match, the
|
||||
* performance loss is not measurable (and the size of the archive we can
|
||||
* handle is greatly increased).
|
||||
*/
|
||||
typedef struct ftm {
|
||||
int namelen; /* file name length */
|
||||
time_t mtime; /* files last modification time */
|
||||
off_t seek; /* location in scratch file */
|
||||
struct ftm *fow;
|
||||
} FTM;
|
||||
|
||||
/*
|
||||
* Interactive rename table (-i flag), hashed by orig filename.
|
||||
* We assume this will not be a large table as this mapping data can only be
|
||||
* obtained through interactive input by the user. Nobody is going to type in
|
||||
* changes for 500000 files? We use chaining to resolve collisions.
|
||||
*/
|
||||
|
||||
typedef struct namt {
|
||||
char *oname; /* old name */
|
||||
char *nname; /* new name typed in by the user */
|
||||
struct namt *fow;
|
||||
} NAMT;
|
||||
|
||||
/*
|
||||
* Unique device mapping tables. Some protocols (e.g. cpio) require that the
|
||||
* <c_dev,c_ino> pair will uniquely identify a file in an archive unless they
|
||||
* are links to the same file. Appending to archives can break this. For those
|
||||
* protocols that have this requirement we map c_dev to a unique value not seen
|
||||
* in the archive when we append. We also try to handle inode truncation with
|
||||
* this table. (When the inode field in the archive header are too small, we
|
||||
* remap the dev on writes to remove accidental collisions).
|
||||
*
|
||||
* The list is hashed by device number using chain collision resolution. Off of
|
||||
* each DEVT are linked the various remaps for this device based on those bits
|
||||
* in the inode which were truncated. For example if we are just remapping to
|
||||
* avoid a device number during an update append, off the DEVT we would have
|
||||
* only a single DLIST that has a truncation id of 0 (no inode bits were
|
||||
* stripped for this device so far). When we spot inode truncation we create
|
||||
* a new mapping based on the set of bits in the inode which were stripped off.
|
||||
* so if the top four bits of the inode are stripped and they have a pattern of
|
||||
* 0110...... (where . are those bits not truncated) we would have a mapping
|
||||
* assigned for all inodes that has the same 0110.... pattern (with this dev
|
||||
* number of course). This keeps the mapping sparse and should be able to store
|
||||
* close to the limit of files which can be represented by the optimal
|
||||
* combination of dev and inode bits, and without creating a fouled up archive.
|
||||
* Note we also remap truncated devs in the same way (an exercise for the
|
||||
* dedicated reader; always wanted to say that...:)
|
||||
*/
|
||||
|
||||
typedef struct devt {
|
||||
dev_t dev; /* the orig device number we now have to map */
|
||||
struct devt *fow; /* new device map list */
|
||||
struct dlist *list; /* map list based on inode truncation bits */
|
||||
} DEVT;
|
||||
|
||||
typedef struct dlist {
|
||||
ino_t trunc_bits; /* truncation pattern for a specific map */
|
||||
dev_t dev; /* the new device id we use */
|
||||
struct dlist *fow;
|
||||
} DLIST;
|
||||
|
||||
/*
|
||||
* ftree directory access time reset table. When we are done with a
|
||||
* subtree we reset the access and mod time of the directory when the tflag is
|
||||
* set. Not really explicitly specified in the pax spec, but easy and fast to
|
||||
* do (and this may have even been intended in the spec, it is not clear).
|
||||
* table is hashed by inode with chaining.
|
||||
*/
|
||||
|
||||
typedef struct atdir {
|
||||
char *name; /* name of directory to reset */
|
||||
dev_t dev; /* dev and inode for fast lookup */
|
||||
ino_t ino;
|
||||
time_t mtime; /* access and mod time to reset to */
|
||||
time_t atime;
|
||||
struct atdir *fow;
|
||||
} ATDIR;
|
||||
|
||||
/*
|
||||
* created directory time and mode storage entry. After pax is finished during
|
||||
* extraction or copy, we must reset directory access modes and times that
|
||||
* may have been modified after creation (they no longer have the specified
|
||||
* times and/or modes). We must reset time in the reverse order of creation,
|
||||
* because entries are added from the top of the file tree to the bottom.
|
||||
* We MUST reset times from leaf to root (it will not work the other
|
||||
* direction). Entries are recorded into a spool file to make reverse
|
||||
* reading faster.
|
||||
*/
|
||||
|
||||
typedef struct dirdata {
|
||||
#ifdef DIRS_USE_FILE
|
||||
int nlen; /* length of the directory name (includes \0) */
|
||||
off_t npos; /* position in file where this dir name starts */
|
||||
#else
|
||||
char *name; /* file name */
|
||||
struct dirdata *next;
|
||||
#endif
|
||||
mode_t mode; /* file mode to restore */
|
||||
time_t mtime; /* mtime to set */
|
||||
time_t atime; /* atime to set */
|
||||
long fflags; /* file flags to set */
|
||||
int frc_mode; /* do we force mode settings? */
|
||||
} DIRDATA;
|
||||
358
bin/pax/tar.1
Normal file
358
bin/pax/tar.1
Normal file
@@ -0,0 +1,358 @@
|
||||
.\" $NetBSD: tar.1,v 1.33 2012/03/22 07:58:17 wiz Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1996 SigmaSoft, Th. Lockert
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" OpenBSD: tar.1,v 1.28 2000/11/09 23:58:56 aaron Exp
|
||||
.\"
|
||||
.Dd June 18, 2011
|
||||
.Dt TAR 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm tar
|
||||
.Nd tape archiver
|
||||
.Sh SYNOPSIS
|
||||
.Nm tar
|
||||
.Sm off
|
||||
.Oo \&- Oc {crtux} Op Fl 014578befHhjklmOoPpqSvwXZz
|
||||
.Sm on
|
||||
.Op Ar archive
|
||||
.Op Ar blocksize
|
||||
.\" XXX how to do this right?
|
||||
.Op Fl C Ar directory
|
||||
.Op Fl s Ar replstr
|
||||
.Op Fl T Ar file
|
||||
.Op Ar file ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
command creates, adds files to, or extracts files from an
|
||||
archive file in
|
||||
.Dq tar
|
||||
format.
|
||||
A tar archive is often stored on a magnetic tape, but can be
|
||||
stored equally well on a floppy, CD-ROM, or in a regular disk file.
|
||||
.Pp
|
||||
One of the following flags must be present:
|
||||
.Bl -tag -width Ar
|
||||
.It Fl c , Fl Fl create
|
||||
Create new archive, or overwrite an existing archive,
|
||||
adding the specified files to it.
|
||||
.It Fl r , Fl Fl append
|
||||
Append the named new files to existing archive.
|
||||
Note that this will only work on media on which an end-of-file mark
|
||||
can be overwritten.
|
||||
.It Fl t , Fl Fl list
|
||||
List contents of archive.
|
||||
If any files are named on the
|
||||
command line, only those files will be listed.
|
||||
.It Fl u , Fl Fl update
|
||||
Alias for
|
||||
.Fl r .
|
||||
.It Fl x , Fl Fl extract , Fl Fl get
|
||||
Extract files from archive.
|
||||
If any files are named on the
|
||||
command line, only those files will be extracted from the
|
||||
archive.
|
||||
If more than one copy of a file exists in the
|
||||
archive, later copies will overwrite earlier copies during
|
||||
extraction.
|
||||
The file mode and modification time are preserved
|
||||
if possible.
|
||||
The file mode is subject to modification by the
|
||||
.Xr umask 2 .
|
||||
.El
|
||||
.Pp
|
||||
In addition to the flags mentioned above, any of the following
|
||||
flags may be used:
|
||||
.Bl -tag -width Ar
|
||||
.It Fl b Ar "blocking factor" , Fl Fl block-size Ar "blocking factor"
|
||||
Set blocking factor to use for the archive.
|
||||
.Nm
|
||||
uses 512 byte blocks.
|
||||
The default is 20, the maximum is 126.
|
||||
Archives with a blocking factor larger 63 violate the
|
||||
.Tn POSIX
|
||||
standard and will not be portable to all systems.
|
||||
.It Fl e
|
||||
Stop after first error.
|
||||
.It Fl f Ar archive , Fl Fl file Ar archive
|
||||
Filename where the archive is stored.
|
||||
Defaults to
|
||||
.Pa /dev/rst0 .
|
||||
If the archive is of the form:
|
||||
.Ar [[user@]host:]file
|
||||
then the archive will be processed using
|
||||
.Xr rmt 8 .
|
||||
.It Fl h , Fl Fl dereference
|
||||
Follow symbolic links as if they were normal files
|
||||
or directories.
|
||||
.It Fl j, Fl Fl bzip2, Fl Fl bunzip2
|
||||
Use
|
||||
.Xr bzip2 1
|
||||
for compression of the archive.
|
||||
This option is a GNU extension.
|
||||
.It Fl k , Fl Fl keep-old-files
|
||||
Keep existing files; don't overwrite them from archive.
|
||||
.It Fl l , Fl Fl one-file-system
|
||||
Do not descend across mount points.
|
||||
.\" should be '-X'
|
||||
.It Fl m , Fl Fl modification-time
|
||||
Do not preserve modification time.
|
||||
.It Fl O
|
||||
When creating and appending to an archive, write old-style (non-POSIX) archives.
|
||||
When extracting from an archive, extract to standard output.
|
||||
.It Fl o , Fl Fl portability , Fl Fl old-archive
|
||||
Don't write directory information that the older (V7) style
|
||||
.Nm
|
||||
is unable to decode.
|
||||
This implies the
|
||||
.Fl O
|
||||
flag.
|
||||
.It Fl p , Fl Fl preserve-permissions , Fl Fl preserve
|
||||
Preserve user and group ID as well as file mode regardless of
|
||||
the current
|
||||
.Xr umask 2 .
|
||||
The setuid and setgid bits are only preserved if the user is
|
||||
the superuser.
|
||||
Only meaningful in conjunction with the
|
||||
.Fl x
|
||||
flag.
|
||||
.It Fl q , Fl Fl fast-read
|
||||
Select the first archive member that matches each
|
||||
.Ar pattern
|
||||
operand.
|
||||
No more than one archive member is matched for each
|
||||
.Ar pattern .
|
||||
When members of type directory are matched, the file hierarchy rooted at that
|
||||
directory is also matched.
|
||||
.It Fl S , Fl Fl sparse
|
||||
This flag has no effect as
|
||||
.Nm
|
||||
always generates sparse files.
|
||||
.It Fl s Ar replstr
|
||||
Modify the file or archive member names specified by the
|
||||
.Ar pattern
|
||||
or
|
||||
.Ar file
|
||||
operands according to the substitution expression
|
||||
.Ar replstr ,
|
||||
using the syntax of the
|
||||
.Xr ed 1
|
||||
utility regular expressions.
|
||||
The format of these regular expressions are:
|
||||
.Dl /old/new/[gps]
|
||||
As in
|
||||
.Xr ed 1 ,
|
||||
.Cm old
|
||||
is a basic regular expression and
|
||||
.Cm new
|
||||
can contain an ampersand (\*[Am]), \en (where n is a digit) back-references,
|
||||
or subexpression matching.
|
||||
The
|
||||
.Cm old
|
||||
string may also contain
|
||||
.Aq Dv newline
|
||||
characters.
|
||||
Any non-null character can be used as a delimiter (/ is shown here).
|
||||
Multiple
|
||||
.Fl s
|
||||
expressions can be specified.
|
||||
The expressions are applied in the order they are specified on the
|
||||
command line, terminating with the first successful substitution.
|
||||
The optional trailing
|
||||
.Cm g
|
||||
continues to apply the substitution expression to the pathname substring
|
||||
which starts with the first character following the end of the last successful
|
||||
substitution.
|
||||
The first unsuccessful substitution stops the operation of the
|
||||
.Cm g
|
||||
option.
|
||||
The optional trailing
|
||||
.Cm p
|
||||
will cause the final result of a successful substitution to be written to
|
||||
.Dv standard error
|
||||
in the following format:
|
||||
.Dl \*[Lt]original pathname\*[Gt] \*[Gt]\*[Gt] \*[Lt]new pathname\*[Gt]
|
||||
File or archive member names that substitute to the empty string
|
||||
are not selected and will be skipped.
|
||||
The substitutions are applied by default to the destination hard and symbolic
|
||||
links.
|
||||
The optional trailing
|
||||
.Cm s
|
||||
prevents the substitutions from being performed on symbolic link destinations.
|
||||
.It Fl v
|
||||
Verbose operation mode.
|
||||
.It Fl w , Fl Fl interactive , Fl Fl confirmation
|
||||
Interactively rename files.
|
||||
This option causes
|
||||
.Nm
|
||||
to prompt the user for the filename to use when storing or
|
||||
extracting files in an archive.
|
||||
.It Fl Fl xz
|
||||
Compress/decompress archive using
|
||||
.Xr xz 1 .
|
||||
.It Fl z , Fl Fl gzip , Fl Fl gunzip
|
||||
Compress/decompress archive using
|
||||
.Xr gzip 1 .
|
||||
.It Fl B , Fl Fl read-full-blocks
|
||||
Reassemble small reads into full blocks (For reading from 4.2BSD pipes).
|
||||
.It Fl C Ar directory , Fl Fl directory Ar directory
|
||||
This is a positional argument which sets the working directory for the
|
||||
following files.
|
||||
When extracting, files will be extracted into
|
||||
the specified directory; when creating, the specified files will be matched
|
||||
from the directory.
|
||||
This argument and its parameter may also appear in a file list specified by
|
||||
.Fl T .
|
||||
.It Fl H
|
||||
Only follow symlinks given on command line.
|
||||
.Pp
|
||||
Note SysVr3/i386 picked up ISC/SCO UNIX compatibility which implemented
|
||||
.Dq Fl F Ar file
|
||||
which was defined as obtaining a list of command line switches and files
|
||||
on which to operate from the specified file,
|
||||
but SunOS-5 uses
|
||||
.Dq Fl I Ar file
|
||||
because they use
|
||||
.Sq Fl F
|
||||
to mean something else.
|
||||
We might someday provide SunOS-5 compatibility
|
||||
but it makes little sense to confuse things with ISC/SCO compatibility.
|
||||
.\".It Fl L
|
||||
.\"Do not follow any symlinks (do the opposite of
|
||||
.\".Fl h ).
|
||||
.It Fl P , Fl Fl absolute-paths
|
||||
Do not strip leading slashes
|
||||
.Pq Sq /
|
||||
from pathnames.
|
||||
The default is to strip leading slashes.
|
||||
.It Fl T Ar file , Fl Fl files-from Ar file
|
||||
Read the names of files to archive or extract from the given file, one
|
||||
per line.
|
||||
A line may also specify the positional argument
|
||||
.Dq Fl C Ar directory .
|
||||
.It Fl X Ar file , Fl Fl exclude-from Ar file
|
||||
Exclude files matching the shell glob patterns listed in the given file.
|
||||
.\" exclude should be '-E' and '-X' should be one-file-system
|
||||
.Pp
|
||||
Note that it would be more standard to use this option to mean ``do not
|
||||
cross filesystem mount points.''
|
||||
.It Fl Z , Fl Fl compress , Fl Fl uncompress
|
||||
Compress archive using compress.
|
||||
.It Fl Fl strict
|
||||
Do not enable GNU tar extensions such as long filenames and long link names.
|
||||
.It Fl Fl atime-preserve
|
||||
Preserve file access times.
|
||||
.It Fl Fl chroot
|
||||
.Fn chroot
|
||||
to the current directory before extracting files.
|
||||
Use with
|
||||
.Fl x
|
||||
and
|
||||
.Fl h
|
||||
to make absolute symlinks relative to the current directory.
|
||||
.It Fl Fl unlink
|
||||
Ignored, only accepted for compatibility with other
|
||||
.Nm
|
||||
implementations.
|
||||
.Nm
|
||||
always unlinks files before creating them.
|
||||
.It Fl Fl use-compress-program Ar program
|
||||
Use the named program as the program to decompress the input.
|
||||
.It Fl Fl force-local
|
||||
Do not interpret filenames that contain a
|
||||
.Sq \&:
|
||||
as remote files.
|
||||
.It Fl Fl insecure
|
||||
Normally
|
||||
.Nm
|
||||
ignores filenames that contain
|
||||
.Dq ..
|
||||
as a path component.
|
||||
With this option, files that contain
|
||||
.Dq ..
|
||||
can be processed.
|
||||
.It Fl Fl no-recursion
|
||||
Cause files of type directory being copied or archived, or archive members of
|
||||
type directory being extracted, to match only the directory file or archive
|
||||
member and not the file hierarchy rooted at the directory.
|
||||
.El
|
||||
.Pp
|
||||
The options
|
||||
.Op Fl 014578
|
||||
can be used to select one of the compiled-in backup devices,
|
||||
.Pa /dev/rstN .
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/dev/rst0"
|
||||
.It Pa /dev/rst0
|
||||
default archive name
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
.Nm
|
||||
will exit with one of the following values:
|
||||
.Bl -tag -width 2n
|
||||
.It 0
|
||||
All files were processed successfully.
|
||||
.It 1
|
||||
An error occurred.
|
||||
.El
|
||||
.Pp
|
||||
Whenever
|
||||
.Nm
|
||||
cannot create a file or a link when extracting an archive or cannot
|
||||
find a file while writing an archive, or cannot preserve the user
|
||||
ID, group ID, file mode, or access and modification times when the
|
||||
.Fl p
|
||||
option is specified, a diagnostic message is written to standard
|
||||
error and a non-zero exit value will be returned, but processing
|
||||
will continue.
|
||||
In the case where
|
||||
.Nm
|
||||
cannot create a link to a file,
|
||||
.Nm
|
||||
will not create a second copy of the file.
|
||||
.Pp
|
||||
If the extraction of a file from an archive is prematurely terminated
|
||||
by a signal or error,
|
||||
.Nm
|
||||
may have only partially extracted the file the user wanted.
|
||||
Additionally, the file modes of extracted files and directories may
|
||||
have incorrect file bits, and the modification and access times may
|
||||
be wrong.
|
||||
.Pp
|
||||
If the creation of an archive is prematurely terminated by a signal
|
||||
or error,
|
||||
.Nm
|
||||
may have only partially created the archive which may violate the
|
||||
specific archive format specification.
|
||||
.Sh SEE ALSO
|
||||
.Xr cpio 1 ,
|
||||
.Xr pax 1
|
||||
.Sh HISTORY
|
||||
A
|
||||
.Nm
|
||||
command first appeared in
|
||||
.At v7 .
|
||||
.Sh AUTHORS
|
||||
Keith Muller at the University of California, San Diego.
|
||||
1413
bin/pax/tar.c
Normal file
1413
bin/pax/tar.c
Normal file
File diff suppressed because it is too large
Load Diff
152
bin/pax/tar.h
Normal file
152
bin/pax/tar.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/* $NetBSD: tar.h,v 1.9 2004/05/11 17:12:26 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)tar.h 8.2 (Berkeley) 4/18/94
|
||||
*/
|
||||
|
||||
/*
|
||||
* defines and data structures common to all tar formats
|
||||
*/
|
||||
#define CHK_LEN 8 /* length of checksum field */
|
||||
#define TNMSZ 100 /* size of name field */
|
||||
#ifdef _PAX_
|
||||
#define NULLCNT 2 /* number of null blocks in trailer */
|
||||
#define CHK_OFFSET 148 /* start of chksum field */
|
||||
#define BLNKSUM 256L /* sum of checksum field using ' ' */
|
||||
#endif /* _PAX_ */
|
||||
|
||||
/*
|
||||
* Values used in typeflag field in all tar formats
|
||||
* (only REGTYPE, LNKTYPE and SYMTYPE are used in old bsd tar headers)
|
||||
*/
|
||||
#define REGTYPE '0' /* Regular File */
|
||||
#define AREGTYPE '\0' /* Regular File */
|
||||
#define LNKTYPE '1' /* Link */
|
||||
#define SYMTYPE '2' /* Symlink */
|
||||
#define CHRTYPE '3' /* Character Special File */
|
||||
#define BLKTYPE '4' /* Block Special File */
|
||||
#define DIRTYPE '5' /* Directory */
|
||||
#define FIFOTYPE '6' /* FIFO */
|
||||
#define CONTTYPE '7' /* high perf file */
|
||||
|
||||
/*
|
||||
* GNU tar compatibility;
|
||||
*/
|
||||
#define LONGLINKTYPE 'K' /* Long Symlink */
|
||||
#define LONGNAMETYPE 'L' /* Long File */
|
||||
|
||||
/*
|
||||
* Mode field encoding of the different file types - values in octal
|
||||
*/
|
||||
#define TSUID 04000 /* Set UID on execution */
|
||||
#define TSGID 02000 /* Set GID on execution */
|
||||
#define TSVTX 01000 /* Reserved */
|
||||
#define TUREAD 00400 /* Read by owner */
|
||||
#define TUWRITE 00200 /* Write by owner */
|
||||
#define TUEXEC 00100 /* Execute/Search by owner */
|
||||
#define TGREAD 00040 /* Read by group */
|
||||
#define TGWRITE 00020 /* Write by group */
|
||||
#define TGEXEC 00010 /* Execute/Search by group */
|
||||
#define TOREAD 00004 /* Read by other */
|
||||
#define TOWRITE 00002 /* Write by other */
|
||||
#define TOEXEC 00001 /* Execute/Search by other */
|
||||
|
||||
#ifdef _PAX_
|
||||
/*
|
||||
* Pad with a bit mask, much faster than doing a mod but only works on powers
|
||||
* of 2. Macro below is for block of 512 bytes.
|
||||
*/
|
||||
#define TAR_PAD(x) ((512 - ((x) & 511)) & 511)
|
||||
#endif /* _PAX_ */
|
||||
|
||||
/*
|
||||
* structure of an old tar header as it appeared in BSD releases
|
||||
*/
|
||||
typedef struct {
|
||||
char name[TNMSZ]; /* name of entry */
|
||||
char mode[8]; /* mode */
|
||||
char uid[8]; /* uid */
|
||||
char gid[8]; /* gid */
|
||||
char size[12]; /* size */
|
||||
char mtime[12]; /* modification time */
|
||||
char chksum[CHK_LEN]; /* checksum */
|
||||
char linkflag; /* norm, hard, or sym. */
|
||||
char linkname[TNMSZ]; /* linked to name */
|
||||
} HD_TAR;
|
||||
|
||||
#ifdef _PAX_
|
||||
/*
|
||||
* -o options for BSD tar to not write directories to the archive
|
||||
*/
|
||||
#define TAR_NODIR "nodir"
|
||||
#define TAR_OPTION "write_opt"
|
||||
|
||||
/*
|
||||
* default device names
|
||||
*/
|
||||
extern char DEV_0[];
|
||||
extern char DEV_1[];
|
||||
extern char DEV_4[];
|
||||
extern char DEV_5[];
|
||||
extern char DEV_7[];
|
||||
extern char DEV_8[];
|
||||
#endif /* _PAX_ */
|
||||
|
||||
/*
|
||||
* Data Interchange Format - Extended tar header format - POSIX 1003.1-1990
|
||||
*/
|
||||
#define TPFSZ 155
|
||||
#define TMAGIC "ustar" /* ustar and a null */
|
||||
#define TMAGLEN 6
|
||||
#define TVERSION "00" /* 00 and no null */
|
||||
#define TVERSLEN 2
|
||||
|
||||
typedef struct {
|
||||
char name[TNMSZ]; /* name of entry */
|
||||
char mode[8]; /* mode */
|
||||
char uid[8]; /* uid */
|
||||
char gid[8]; /* gid */
|
||||
char size[12]; /* size */
|
||||
char mtime[12]; /* modification time */
|
||||
char chksum[CHK_LEN]; /* checksum */
|
||||
char typeflag; /* type of file. */
|
||||
char linkname[TNMSZ]; /* linked to name */
|
||||
char magic[TMAGLEN]; /* magic cookie */
|
||||
char version[TVERSLEN]; /* version */
|
||||
char uname[32]; /* ascii owner name */
|
||||
char gname[32]; /* ascii group name */
|
||||
char devmajor[8]; /* major device number */
|
||||
char devminor[8]; /* minor device number */
|
||||
char prefix[TPFSZ]; /* linked to name */
|
||||
} HD_USTAR;
|
||||
200
bin/pax/tty_subs.c
Normal file
200
bin/pax/tty_subs.c
Normal file
@@ -0,0 +1,200 @@
|
||||
/* $NetBSD: tty_subs.c,v 1.19 2007/04/23 18:40:22 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Keith Muller of the University of California, San Diego.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)tty_subs.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: tty_subs.c,v 1.19 2007/04/23 18:40:22 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "pax.h"
|
||||
#include "extern.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
/*
|
||||
* routines that deal with I/O to and from the user
|
||||
*/
|
||||
|
||||
#define DEVTTY "/dev/tty" /* device for interactive i/o */
|
||||
static FILE *ttyoutf = NULL; /* output pointing at control tty */
|
||||
static FILE *ttyinf = NULL; /* input pointing at control tty */
|
||||
|
||||
/*
|
||||
* tty_init()
|
||||
* Try to open the controlling terminal (if any) for this process. If the
|
||||
* open fails, future ops that require user input will get an EOF.
|
||||
*/
|
||||
|
||||
int
|
||||
tty_init(void)
|
||||
{
|
||||
int ttyfd;
|
||||
|
||||
if ((ttyfd = open(DEVTTY, O_RDWR)) >= 0) {
|
||||
if ((ttyoutf = fdopen(ttyfd, "w")) != NULL) {
|
||||
if ((ttyinf = fdopen(ttyfd, "r")) != NULL)
|
||||
return 0;
|
||||
(void)fclose(ttyoutf);
|
||||
}
|
||||
(void)close(ttyfd);
|
||||
}
|
||||
|
||||
if (iflag) {
|
||||
tty_warn(1, "Fatal error, cannot open %s", DEVTTY);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* tty_prnt()
|
||||
* print a message using the specified format to the controlling tty
|
||||
* if there is no controlling terminal, just return.
|
||||
*/
|
||||
|
||||
void
|
||||
tty_prnt(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
if (ttyoutf == NULL)
|
||||
return;
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(ttyoutf, fmt, ap);
|
||||
va_end(ap);
|
||||
(void)fflush(ttyoutf);
|
||||
}
|
||||
|
||||
/*
|
||||
* tty_read()
|
||||
* read a string from the controlling terminal if it is open into the
|
||||
* supplied buffer
|
||||
* Return:
|
||||
* 0 if data was read, -1 otherwise.
|
||||
*/
|
||||
|
||||
int
|
||||
tty_read(char *str, int len)
|
||||
{
|
||||
char *pt;
|
||||
|
||||
if ((--len <= 0) || (ttyinf == NULL) || (fgets(str,len,ttyinf) == NULL))
|
||||
return -1;
|
||||
*(str + len) = '\0';
|
||||
|
||||
/*
|
||||
* strip off that trailing newline
|
||||
*/
|
||||
if ((pt = strchr(str, '\n')) != NULL)
|
||||
*pt = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* tty_warn()
|
||||
* write a warning message to stderr. if "set" the exit value of pax
|
||||
* will be non-zero.
|
||||
*/
|
||||
|
||||
void
|
||||
tty_warn(int set, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
if (set)
|
||||
exit_val = 1;
|
||||
/*
|
||||
* when vflag we better ship out an extra \n to get this message on a
|
||||
* line by itself
|
||||
*/
|
||||
if ((Vflag || vflag) && vfpart) {
|
||||
(void)fputc('\n', stderr);
|
||||
vfpart = 0;
|
||||
}
|
||||
(void)fprintf(stderr, "%s: ", argv0);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
|
||||
/*
|
||||
* syswarn()
|
||||
* write a warning message to stderr. if "set" the exit value of pax
|
||||
* will be non-zero.
|
||||
*/
|
||||
|
||||
void
|
||||
syswarn(int set, int errnum, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
if (set)
|
||||
exit_val = 1;
|
||||
/*
|
||||
* when vflag we better ship out an extra \n to get this message on a
|
||||
* line by itself
|
||||
*/
|
||||
if ((Vflag || vflag) && vfpart) {
|
||||
(void)fputc('\n', stdout);
|
||||
vfpart = 0;
|
||||
}
|
||||
(void)fprintf(stderr, "%s: ", argv0);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
/*
|
||||
* format and print the errno
|
||||
*/
|
||||
if (errnum > 0)
|
||||
(void)fprintf(stderr, " (%s)", strerror(errnum));
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
Reference in New Issue
Block a user