configure.ac | 3 +-
doc/cpio.1 | 669 +++++++++++++++++++++++++++++++-------------------------
doc/cpio.texi | 12 +-
src/Makefile.am | 5 +-
src/copyin.c | 45 ++--
src/copyout.c | 8 +-
src/copypass.c | 18 +-
src/extern.h | 2 +-
src/global.c | 3 -
src/main.c | 17 +-
src/tar.c | 8 +-
src/util.c | 44 ++--
tests/genfile.c | 1 -
13 files changed, 474 insertions(+), 361 deletions(-)
diff --git a/configure.ac b/configure.ac
index c68bd44..9bb8956 100644
--- a/configure.ac
+++ b/configure.ac
@@ -88,10 +88,11 @@ LIBS="$LIBS $LIB_CLOCK_GETTIME"
# Initialize the test suite.
AC_CONFIG_TESTDIR(tests)
-AC_CONFIG_FILES([tests/Makefile tests/atlocal]) # FIXME: tests/preset?
AM_MISSING_PROG([AUTOM4TE], [autom4te])
AC_CONFIG_FILES([Makefile
+ tests/Makefile
+ tests/atlocal
doc/Makefile
gnu/Makefile
lib/Makefile
diff --git a/doc/cpio.1 b/doc/cpio.1
index 2a68241..670277c 100644
--- a/doc/cpio.1
+++ b/doc/cpio.1
@@ -1,355 +1,438 @@
-.\" This file is part of GNU cpio. -*- nroff -*-
-.\" Copyright 2014-2015 Free Software Foundation, Inc.
-.\"
-.\" GNU cpio is free software; you can redistribute it and/or modify
-.\" it under the terms of the GNU General Public License as published by
-.\" the Free Software Foundation; either version 3 of the License, or
-.\" (at your option) any later version.
-.\"
-.\" GNU cpio is distributed in the hope that it will be useful,
-.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
-.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-.\" GNU General Public License for more details.
-.\"
-.\" You should have received a copy of the GNU General Public License
-.\" along with GNU cpio. If not, see .
-.TH CPIO 1 "December 1, 2014" "CPIO" "GNU CPIO"
+.\" DO NOT MODIFY THIS FILE! It was (partly) generated by help2man from
+.\" cpio --help/cpio --version output and partly patched by downstream
+.\" package maintainers.
+.TH CPIO 1L \" -*- nroff -*-
.SH NAME
cpio \- copy files to and from archives
-.SH SYNOPSIS
-.B cpio
-{\fB\-o\fR|\fB\-\-create\fR} [\fB\-0acvABLV\fR] [\fB\-C\fR \fIBYTES\fR]
-[\fB\-H\fR \fIFORMAT\fR] [\fB\-M\fR \fIMESSAGE\fR]
-[\fB\-O\fR [[\fIUSER\fB@\fR]\fIHOST\fB:\fR]\fIARCHIVE\fR]
-[\fB\-F\fR [[\fIUSER\fB@\fR]\fIHOST\fB:\fR]\fIARCHIVE\fR]
-[\fB\-\-file=\fR[[\fIUSER\fB@\fR]\fIHOST\fB:\fR]\fIARCHIVE\fR]
-[\fB\-\-format=\fIFORMAT\fR] [\fB\-\-message=\fIMESSAGE\fR]
-[\fB\-\-null\fR] [\fB\-\-reset\-access\-time\fR] [\fB\-\-verbose\fR]
-[\fB\-\-dot\fR] [\fB\-\-append\fR]
-[\fB\-\-block\-size=\fIblocks\fR] [\fB\-\-dereference\fR]
-[\fB\-\-io\-size=\fIBYTES\fR] [\fB\-\-quiet\fR]
-[\fB\-\-force\-local\fR] [\fB\-\-rsh\-command=\fICOMMAND\fR]
-\fB<\fR \fIname-list\fR [\fB>\fR \fIarchive\fR]
+.SH __WARNING__
+.PP
+The cpio utility is considered LEGACY based on POSIX specification. Users are
+encouraged to use other archiving tools for archive creation.
-.B cpio
-{\fB\-i\fR|\fB\-\-extract\fR} [\fB\-bcdfmnrtsuvBSV\fR] [\fB\-C\fR \fIBYTES\fR]
-[\fB\-E\fR \fIFILE\fR] [\fB\-H\fR \fIFORMAT\fR]
-[\fB\-M\fR \fIMESSAGE\fR] [\fB\-R\fR [\fIUSER\fR][\fB:.\fR][\fIGROUP\fR]]
-[\fB\-I\fR [[\fIUSER\fB@\fR]\fIHOST\fB:\fR]\fIARCHIVE\fR]
-[\fB\-F\fR [[\fIUSER\fB@\fR]\fIHOST\fB:\fR]\fIARCHIVE\fR]
-[\fB\-\-file=\fR[[\fIUSER\fB@\fR]\fIHOST\fB:\fR]\fIARCHIVE\fR]
-[\fB\-\-make\-directories\fR] [\fB\-\-nonmatching\fR]
-[\fB\-\-preserve\-modification\-time\fR] [\fB\-\-numeric\-uid\-gid\fR]
-[\fB\-\-rename\fR] [\fB\-\-list\fR] [\fB\-\-swap\-bytes\fR]
-[\fB\-\-swap\fR] [\fB\-\-dot\fR] [\fB\-\-unconditional\fR]
-[\fB\-\-verbose\fR] [\fB\-\-block\-size=\fIBLOCKS\fR]
-[\fB\-\-swap\-halfwords\fR] [\fB\-\-io\-size=\fIBYTES\fR]
-[\fB\-\-pattern\-file=\fIFILE\fR] [\fB\-\-format=\fIFORMAT\fR]
-[\fB\-\-owner=\fR[\fIUSER][\fB:.\fR][\fIGROUP\fR]]
-[\fB\-\-no\-preserve\-owner\fR] [\fB\-\-message=\fIMESSAGE\fR]
-[\fB\-\-force\-local\fR] [\fB\-\-no\-absolute\-filenames\fR] [\fB\-\-sparse\fR]
-[\fB\-\-only\-verify\-crc\fR] [\fB\-\-to\-stdout\fR] [\fB\-\-quiet\fR]
-[\fB\-\-rsh\-command=\fICOMMAND\fR]
-[\fIpattern\fR...] [\fB<\fR \fIarchive\fR]
+If you decided to use cpio, you should almost always force cpio to use the
+ustar format in copy-out mode by the -H option (cpio -o -H ustar). This is
+because the ustar format is well defined in POSIX specification and thus
+readable by wide range of other archiving tools (including tar e.g.).
-.B cpio
-{\fB\-p\fR|\fB\-\-pass\-through\fR} [\fB\-0adlmuvLV\fR]
-[\fB\-R\fR [\fIUSER\fR][\fB:.\fR][\fIGROUP\fR]]
-[\fB\-\-null\fR] [\fB\-\-reset\-access\-time\fR]
-[\fB\-\-make\-directories\fR] [\fB\-\-link\fR] [\fB\-\-quiet\fR]
-[\fB\-\-preserve\-modification\-time] [\fB\-\-unconditional\fR]
-[\fB\-\-verbose\fR] [\fB\-\-dot\fR] [\fB\-\-dereference\fR]
-[\fB\-\-owner=\fR[\fIUSER\fR][\fB:.\fR][\fIGROUP\fR]]
-[\fB\-\-no\-preserve\-owner\fR] [\fB\-\-sparse\fR]
-\fIdestination-directory\fR \fB<\fR \fIname-list\fR
+By default, GNU cpio uses (for historical reasons) the very old binary format
+('bin') which has significant problems nowadays, e.g. with storing big inode
+numbers (see the Red Hat bug #952313).
+
+Note also that these days the modern 'pax' archive format should be considered
+as the default -- but this format is not implemented in GNU cpio. You should,
+again, consider using other archivers (e.g. 'tar --format=pax').
+.SH SYNOPSIS
+\&\fBCopy-out mode\fR
+.PP
+In copy-out mode, cpio copies files into an archive. It reads a list
+of filenames, one per line, on the standard input, and writes the
+archive onto the standard output. A typical way to generate the list
+of filenames is with the find command; you should give find the \-depth
+option to minimize problems with permissions on directories that are
+unreadable. see \*(lqOptions\*(rq.
+.PP
.B cpio
-{\fB\-?\fR|\fB\-\-help\fR|\fB\-\-usage\fR|\fB\-\-version\fR}
-.SH NOTE
-This manpage is a short description of GNU \fBcpio\fR. For a detailed
-discussion, including examples and usage recommendations, refer to the
-\fBGNU Cpio Manual\fR available in texinfo format. If the \fBinfo\fR
-reader and the cpio documentation are properly installed on your
-system, the command
+{\-o|\-\-create} [\-0acvABLV] [\-C bytes] [\-H format] [\-D DIR]
+[\-M message] [\-O [[user@]host:]archive] [\-F [[user@]host:]archive]
+[\-\-file=[[user@]host:]archive] [\-\-format=format] [\-\-warning=FLAG]
+[\-\-message=message][\-\-null] [\-\-reset\-access\-time] [\-\-verbose]
+[\-\-dot] [\-\-append] [\-\-block\-size=blocks] [\-\-dereference]
+[\-\-io\-size=bytes] [\-\-rsh\-command=command] [\-\-license] [\-\-usage]
+[\-\-help] [\-\-version]
+< name-list [> archive]
.PP
-.RS +4
-.B info cpio
-.RE
+\&\fBCopy-in mode\fR
.PP
-should give you access to the complete manual.
+In copy-in mode, cpio copies files out of an archive or lists the
+archive contents. It reads the archive from the standard input. Any
+non-option command line arguments are shell globbing patterns; only
+files in the archive whose names match one or more of those patterns are
+copied from the archive. Unlike in the shell, an initial `\fB.\fR' in a
+filename does match a wildcard at the start of a pattern, and a `\fB/\fR' in a
+filename can match wildcards. If no patterns are given, all files are
+extracted. see \*(lqOptions\*(rq.
+.PP
+.B cpio
+{\-i|\-\-extract} [\-bcdfmnrtsuvBSV] [\-C bytes] [\-E file] [\-H format]
+[\-D DIR]
+[\-M message] [\-R [user][:.][group]] [\-I [[user@]host:]archive]
+[\-F [[user@]host:]archive] [\-\-file=[[user@]host:]archive]
+[\-\-make-directories] [\-\-nonmatching] [\-\-preserve-modification-time]
+[\-\-numeric-uid-gid] [\-\-rename] [\-t|\-\-list] [\-\-swap-bytes] [\-\-swap]
+[\-\-dot] [\-\-warning=FLAG] [\-\-unconditional] [\-\-verbose]
+[\-\-block-size=blocks] [\-\-swap-halfwords] [\-\-io-size=bytes]
+[\-\-pattern-file=file] [\-\-format=format] [\-\-owner=[user][:.][group]]
+[\-\-no-preserve-owner] [\-\-message=message]
+[\-\-force\-local] [\-\-no\-absolute\-filenames] [\-\-absolute\-filenames]
+[\-\-sparse] [\-\-only\-verify\-crc] [\-\-to\-stdout] [\-\-quiet]
+[\-\-ignore\-devno] [\-\-renumber\-inodes] [\-\-device\-independent]
+[\-\-reproducible]
+[\-\-rsh-command=command] [\-\-license] [\-\-usage] [\-\-help]
+[\-\-version] [pattern...] [< archive]
+.PP
+\&\fBCopy-pass mode\fR
.PP
-You can also view the manual using the info mode in
-.BR emacs (1),
-or find it in various formats online at
+In copy-pass mode, cpio copies files from one directory tree to
+another, combining the copy-out and copy-in steps without actually
+using an archive. It reads the list of files to copy from the standard
+input; the directory into which it will copy them is given as a
+non-option argument. see \*(lqOptions\*(rq.
.PP
-.RS +4
-.B http://www.gnu.org/software/cpio/manual
-.RE
+.B cpio
+{\-p|\-\-pass-through} [\-0adlmuvLV] [\-R [user][:.][group]] [\-D DIR]
+[\-\-null] [\-\-reset-access-time] [\-\-make-directories] [\-\-link] [\-\-quiet]
+[\-\-preserve-modification-time] [\-\-unconditional] [\-\-verbose] [\-\-dot]
+[\-\-warning=FLAG] [\-\-dereference] [\-\-owner=[user][:.][group]]
+[\-\-no-preserve-owner] [\-\-sparse] [\-\-license] [\-\-usage] [\-\-help]
+[\-\-version] destination-directory < name-list
.PP
-If any discrepancies occur between this manpage and the
-\fBGNU Cpio Manual\fR, the later shall be considered the authoritative
-source.
.SH DESCRIPTION
-GNU \fBcpio\fR copies files between archives and directories. It
-supports the following archive formats: old binary cpio, old portable
-cpio, SVR4 cpio with and without checksum, HP cpio, and various tar
-formats.
+GNU cpio is a tool for creating and extracting archives, or copying
+files from one place to another. It handles a number of cpio formats as
+well as reading and writing tar files.
.PP
-The operation mode is requested by one of the following options:
-.TP
-.BR \-o ", " \-\-create
-Copy-out. Read a list of file names from the standard input and
-create on the standard output (unless overridden by the \fB\-\-file\fR
-option) an archive containing these files.
-.TP
-.BR \-i ", " \-\-extract
-Copy-in. Read the archive from standard input (or from the file
-supplied with the \fB\-\-file\fR option) and extract files from it, or
-(if the \fB\-t\fR option is given) list its contents to the standard
-output. If one or more \fIpattern\fRs are supplied, read or list only
-files matching these patterns. The \fB\-t\fR option alone implies
-\fB\-i\fR.
+Following archive formats are supported: binary, old ASCII, new ASCII, crc, HPUX binary, HPUX old
+ASCII, old tar, and POSIX.1 tar. The tar format is provided for compatibility with the tar program. By
+default, cpio creates binary format archives, for compatibility with older cpio programs. When extracting
+from archives, cpio automatically recognizes which kind of archive it is reading and can read archives created
+on machines with a different byte-order.
+.PP
+.SS "Main operation mode:"
.TP
-.BR \-p ", " \-\-pass\-through
-Pass-through. Read a list of file names from the standard input and
-copy them to the specified directory.
+\fB\-i\fR, \fB\-\-extract\fR
+Extract files from an archive (run in copy\-in
+mode)
.TP
-.BR \-? ", " \-\-help
-Give a short help summary and exit.
+\fB\-o\fR, \fB\-\-create\fR
+Create the archive (run in copy\-out mode)
.TP
-.B \-\-usage
-Print a short usage message and exit.
+\fB\-p\fR, \fB\-\-pass\-through\fR
+Run in copy\-pass mode
.TP
-.B \-\-version
-Print program version and exit.
-.SH OPTIONS
-.SS Operation modifiers valid in any mode
+\fB\-t\fR, \fB\-\-list\fR
+Print a table of contents of the input
+.SS "Operation modifiers valid in any mode:"
.TP
-\fB\-\-block\-size=\FIBLOCK-SIZE\fR
-Set the I/O block size to \fIBLOCK-SIZE\fR * 512 bytes.
+\fB\-\-block\-size\fR=\fI\,BLOCK\-SIZE\/\fR
+Set the I/O block size to BLOCK\-SIZE * 512
+bytes
.TP
-.B \-B
+\fB\-B\fR
Set the I/O block size to 5120 bytes.
+Initially the block size is 512 bytes.
.TP
-.B \-c
-Use the old portable (ASCII) archive format. This is the same as
-\fB\-H odc\fR.
+\fB\-c\fR
+Identical to "\-H newc", use the new (SVR4)
+portable format. If you wish the old portable
+(ASCII) archive format, use "\-H odc" instead.
.TP
-\fB\-C\fR, \fB\-\-io\-size=\fINUMBER\fR
-Set the I/O block size to the given \fINUMBER\fR of bytes.
+\fB\-C\fR, \fB\-\-io\-size\fR=\fI\,NUMBER\/\fR
+Set the I/O block size to the given NUMBER of
+bytes
.TP
-\fB\-D\fR, \fB\-\-directory=\fIDIR\fR
-Change to directory \fIDIR\fR.
+\fB\-D\fR, \fB\-\-directory\fR=\fI\,DIR\/\fR
+Change to directory DIR
.TP
-.B \-\-force\-local
-Archive file is local, even if its name contains colons.
+\fB\-\-force\-local\fR
+With \-F, \-I, or \-O, take the archive file name to be a local file
+even if it contains a colon, which would ordinarily indicate a
+remote host name.
.TP
-\fB\-H\fR, \fB\-\-format=\fIFORMAT\fR
-Use given archive \fBFORMAT\fR. Valid formats are (the number in
-parentheses gives maximum size for individual archive member):
-.RS
+\fB\-H\fR, \fB\-\-format\fR=\fI\,FORMAT\/\fR
+Use given archive FORMAT.
+The valid formats are listed below; the same names are also recognized in
+all\-caps. The default in copy-in mode is to automatically detect the archive
+format, and in copy-out mode is `\fBbin\fR'.
.TP
-.B bin
-The obsolete binary format. (2147483647 bytes)
+`bin'
+The obsolete binary format.
.TP
-.B odc
-The old (POSIX.1) portable format. (8589934591 bytes)
+`odc'
+The old (\s-1POSIX\s0.1) portable format.
.TP
-.B newc
-The new (SVR4) portable format, which supports file systems
-having more than 65536 i-nodes. (4294967295 bytes)
+`newc'
+The new (\s-1SVR4\s0) portable format, which supports file systems
+having more than 65536 i\-nodes.
.TP
-.B crc
-The new (SVR4) portable format with a checksum added.
+`crc'
+The new (\s-1SVR4\s0) portable format with a checksum (Sum32) added.
.TP
-.B tar
-The old tar format. (8589934591 bytes)
+`tar'
+The old tar format.
.TP
-.B ustar
-The POSIX.1 tar format. Also recognizes GNU tar archives,
-which are similar but not identical. (8589934591 bytes)
+`ustar'
+The \s-1POSIX\s0.1 tar format. Also recognizes \s-1GNU\s0 tar archives,
+which are similar but not identical.
.TP
-.B hpbin
-The obsolete binary format used by HPUX's cpio (which stores
+`hpbin'
+The obsolete binary format used by \s-1HPUX\s0's cpio (which stores
device files differently).
.TP
-.B hpodc
-The portable format used by HPUX's cpio (which stores device
+`hpodc'
+The portable format used by \s-1HPUX\s0's cpio (which stores device
files differently).
-.RE
-.TP
-\fB\-R\fR, \fB\-\-owner=\fR[\fIUSER\fR][\fB:.\fR][\fIGROUP\fR]
-In copy-in and copy-pass mode, set the ownership of all files created
-to the specified \fIUSER\fR and/or \fIGROUP\fR. In copy-out mode,
-store the supplied owner information in the archive.
-
-\fIUSER\fR and \fIGROUP\fR are first looked up in the system user and
-group databases. If not found, \fBcpio\fR checks if they consist of
-decimal digits only and, if so, treats them as numeric UID and GID,
-correspondingly.
-
-To avoid the lookup and ensure that arguments are treated as numeric
-values, prefix them with a plus sign, e.g.: \fB-R +0:+0\fR.
-.TP
-.B \-\-quiet
-Do not print the number of blocks copied at the end of the run.
-.TP
-.BI \-\-rsh\-command= COMMAND
-Use remote \fICOMMAND\fR instead of \fBrsh\fR.
-.TP
-.BR \-v ", " \-\-verbose
-Verbosely list the files processed.
-.TP
-.BR \-V ", " \-\-dot
-Print a "\fB.\fR" for each file processed.
-.TP
-\fB\-W\fR, \fB\-\-warning=\fIFLAG\fR
-Controlsи warning display. The \fIFLAG\fR is one of
-.BR none ,
-to disable all warnings,
-.BR all
-to enable them,
-.BR truncate ,
-to enable warnings about field truncation, and
-.BR no\-truncate ,
-to disable them.
-
-Multiple \fB\-W\fR options accumulate.
-.SS Operation modifiers valid in copy-in and copy-out modes
.TP
-\fB\-F\fR, \fB\-\-file=\fR[[\fIUSER\fB@\fR]\fIHOST\fB:\fR]\fIARCHIVE-FILE\fR
-Use this \fIARCHIVE-FILE\fR instead of standard input (in copy-in
-mode) or standard output (in copy-out mode). Optional \fIUSER\fR and
-\fIHOST\fR specify the user and host names in case of a remote
+\fB\-\-quiet\fR
+Do not print the number of blocks copied
+.TP
+\fB\-R\fR, \fB\-\-owner\fR=\fI\,[USER][\/\fR:.][GROUP]
+Set the ownership of all files created to the
+specified USER and/or GROUP.
+Either the user, the group, or both, must be present. If the group is omitted
+but the \&\*(lq:\*(rq or \*(lq.\*(rq separator is given, use the given user's
+login group. Only the super-user can change files' ownership in copy\-in mode.
+.TP
+\fB\-v\fR, \fB\-\-verbose\fR
+List the files processed, or with `\fB\-t\fR', give an `\fBls \-l\fR' style
+table of contents listing. In a verbose table of contents of a
+ustar archive, user and group names in the archive that do not
+exist on the local system are replaced by the names that
+correspond locally to the numeric \s-1UID\s0 and \s-1GID\s0 stored in the
archive.
.TP
-\fB\-M\fR, \fB\-\-message=\fISTRING\fR
-Print \fISTRING\fR when the end of a volume of the backup media is reached.
-.SS Operation modifiers valid only in copy-in mode
-.TP
-.BR \-b ", " \-\-swap
-Swap both halfwords of words and bytes of halfwords in the data.
-Equivalent to \fB\-sS\fR.
+\fB\-V\fR, \fB\-\-dot\fR
+Print a "." for each file processed
+.TP
+\fB\-W\fR, \fB\-\-warning\fR=\fI\,FLAG\/\fR
+Control warning display. Currently FLAG is one of
+\&'none', 'truncate', 'all'. Multiple options
+accumulate.
+.SS "Operation modifiers valid in copy-in and copy-out modes:"
+.TP
+\fB\-F\fR, \fB\-\-file\fR=\fI\,[[USER\/\fR@]HOST:]FILE\-NAME
+Use this FILE\-NAME instead of standard input or
+output. Optional USER and HOST specify the user
+and host names in case of a remote archive
+.TP
+\fB\-M\fR, \fB\-\-message\fR=\fI\,STRING\/\fR
+Print \s-1STRING\s0 when the end of a volume of the backup media (such
+as a tape or a floppy disk) is reached, to prompt the user to
+insert a new volume. If \s-1STRING\s0 contains the string \*(lq%d\*(rq, it is
+replaced by the current volume number (starting at 1).
+.TP
+\fB\-\-rsh\-command\fR=\fI\,COMMAND\/\fR
+Use COMMAND instead of rsh
+(typically /usr/bin/ssh)
+.SS "Operation modifiers valid only in copy-in mode:"
+.TP
+\fB\-b\fR, \fB\-\-swap\fR
+Swap both halfwords of words and bytes of
+halfwords in the data. Equivalent to \fB\-sS\fR
+Use this option to convert 32\-bit integers between big-endian and little-endian
+machines.
+.TP
+\fB\-f\fR, \fB\-\-nonmatching\fR
+Only copy files that do not match any of the given
+patterns
+.TP
+\fB\-I\fR [[USER@]HOST:]FILE\-NAME
+Archive filename to use instead of standard input.
+Optional USER and HOST specify the user and host
+names in case of a remote archive
+.TP
+\fB\-n\fR, \fB\-\-numeric\-uid\-gid\fR
+In the verbose table of contents listing, show
+numeric UID and GID
+.TP
+\fB\-r\fR, \fB\-\-rename\fR
+Interactively rename files
+.TP
+\fB\-s\fR, \fB\-\-swap\-bytes\fR
+Swap the bytes of each halfword in the files
+.TP
+\fB\-S\fR, \fB\-\-swap\-halfwords\fR
+Swap the halfwords of each word (4 bytes) in the
+files
+.TP
+\fB\-\-to\-stdout\fR
+Extract files to standard output
+.TP
+\fB\-E\fR, \fB\-\-pattern\-file\fR=\fI\,FILE\/\fR
+Read additional patterns specifying filenames to
+extract or list from FILE
+.TP
+\fB\-\-only\-verify\-crc\fR
+When reading a CRC format archive, only verify the
+checksum of each file in the archive, don't
+actually extract the files
+.SS "Operation modifiers valid only in copy-out mode:"
+.TP
+\fB\-A\fR, \fB\-\-append\fR
+Append to an existing archive.
+The archive must be a disk file specified with the \-O or \-F (\-file) option.
.TP
-.BR \-f ", " \-\-nonmatching
-Only copy files that do not match any of the given patterns.
+\fB\-\-device\-independent\fR, \fB\-\-reproducible\fR
+Create device\-independent (reproducible) archives
.TP
-.BR \-n ", " \-\-numeric\-uid\-gid
-In the verbose table of contents listing, show numeric UID and GID.
-.\" FIXME: special meaning when storing tar files.
+\fB\-\-ignore\-devno\fR
+Don't store device numbers
.TP
-.BR \-r ", " \-\-rename
-Interactively rename files.
+\fB\-O\fR [[USER@]HOST:]FILE\-NAME
+Archive filename to use instead of standard
+output. Optional USER and HOST specify the user
+and host names in case of a remote archive
.TP
-.BR \-s ", " \-\-swap\-bytes
-Swap the bytes of each halfword in the files.
+\fB\-\-renumber\-inodes\fR
+Renumber inodes
+.SS "Operation modifiers valid only in copy-pass mode:"
.TP
-.BR \-S ", " \-\-swap\-halfwords
-Swap the halfwords of each word (4 bytes) in the files.
+\fB\-l\fR, \fB\-\-link\fR
+Link files instead of copying them, when
+possible
+.SS "Operation modifiers valid in copy-in and copy-out modes:"
.TP
-.B \-\-to\-stdout
-Extract files to standard output.
+\fB\-\-absolute\-filenames\fR
+Do not strip file system prefix components from
+the file names
.TP
-\fB\-E\fR, \fB\-\-pattern\-file=\fIFILE\fR
-Read additional patterns specifying filenames to extract or list from
-\fIFILE\fR.
+\fB\-\-no\-absolute\-filenames\fR
+Create all files relative to the current
+directory
+.SS "Operation modifiers valid in copy-out and copy-pass modes:"
.TP
-.B \-\-only\-verify\-crc
-When reading a CRC format archive, only verify the CRC's of each file
-in the archive, without actually extracting the files.
-.SS Operation modifiers valid only in copy-out mode
+\fB\-0\fR, \fB\-\-null\fR
+Filenames in the list are delimited by null
+characters instead of newlines, so that files whose names contain newlines can
+be archived. \s-1GNU\s0 find is one way to produce a list of null-terminated
+filenames.
.TP
-.BR \-A ", " \-\-append
-Append to an existing archive.
+\fB\-a\fR, \fB\-\-reset\-access\-time\fR
+Reset the access times of files after reading them, so that it
+does not look like they have just been read.
.TP
-.BR \-\-device\-independent ", " \-\-reproducible
-Create reproducible archives. This is equivalent to
-.BR "\-\-ignore\-devno \-\-renumber\-inodes" .
+\fB\-L\fR, \fB\-\-dereference\fR
+Dereference symbolic links (copy the files
+that they point to instead of copying the links).
+.SS "Operation modifiers valid in copy-in and copy-pass modes:"
.TP
-.B \-\-ignore\-devno
-Store 0 in the device number field of each archive member, instead of
-the actual device number.
+\fB\-d\fR, \fB\-\-make\-directories\fR
+Create leading directories where needed
.TP
-\fB\-O\fR [[\fIUSER\fB@\fR]\fIHOST\fB:\fR]\fIARCHIVE-NAME\fR
-Use \fIARCHIVE-NAME\fR instead of standard output. Optional \fIUSER\fR and
-\fIHOST\fR specify the user and host names in case of a remote
-archive.
-
-The output archive name can be specified wither using this option, or
-using \fB\-F\fR (\fB\-\-file\fR), but not both.
-.TP
-.B \-\-renumber\-inodes
-Renumber inodes when storing them in the archive.
-.SS Operation modifiers valid only in copy-pass mode
-.TP
-.BR \-l ", " \-\-link
-Link files instead of copying them, when possible.
-.SS Operation modifiers valid in copy-in and copy-out modes
-.TP
-.B \-\-absolute\-filenames
-Do not strip file system prefix components from the file names.
-.TP
-.B \-\-no\-absolute\-filenames
-Create all files relative to the current directory.
-.SS Operation modifiers valid in copy-out and copy-pass modes
-.TP
-.BR \-0 ", " \-\-null
-Filenames in the list are delimited by null characters instead of
-newlines.
-.TP
-.BR \-a ", " \-\-reset\-access\-time
-Reset the access times of files after reading them.
-.TP
-\fB\-I\fR [[\fIUSER\fB@\fR]\fIHOST\fB:\fR]\fIARCHIVE-NAME\fR
-Use \fIARCHIVE-NAME\fR instead of standard input. Optional \fIUSER\fR and
-\fIHOST\fR specify the user and host names in case of a remote
-archive.
-
-The input archive name can be specified wither using this option, or
-using \fB\-F\fR (\fB\-\-file\fR), but not both.
+\fB\-m\fR, \fB\-\-preserve\-modification\-time\fR
+Retain previous file modification times when
+creating files
.TP
-.BR \-L ", " \-\-dereference
-Dereference symbolic links (copy the files that they point to instead
-of copying the links).
-.SS Operation modifiers valid in copy-in and copy-pass modes
+\fB\-\-no\-preserve\-owner\fR
+Do not change the ownership of the files; leave them owned by the
+user extracting them. This is the default for non-root users, so
+that users on System V don't inadvertently give away files. This
+option can be used in copy-in mode and copy-pass mode
.TP
-.BR \-d ", " \-\-make\-directories
-Create leading directories where needed.
+\fB\-\-sparse\fR
+Write files with large blocks of zeros as sparse
+files
.TP
-.BR \-m ", " \-\-preserve\-modification\-time
-Retain previous file modification times when creating files.
+\fB\-u\fR, \fB\-\-unconditional\fR
+Replace all files unconditionally
.TP
-.B \-\-no\-preserve\-owner
-Do not change the ownership of the files.
+\-?, \fB\-\-help\fR
+give this help list
.TP
-.B \-\-sparse
-Write files with large blocks of zeros as sparse files.
+\fB\-\-usage\fR
+give a short usage message
.TP
-.BR \-u ", " \-\-unconditional
-Replace all files unconditionally.
-.SH "RETURN VALUE"
-GNU \fBcpio\fR exits with code \fB0\fR if it was able to successfully
-complete the requested operation. On errors, it exits with code \fB2\fR.
-.SH "SEE ALSO"
-.BR tar (1),
-.BR rmt (8),
-.BR mt (1).
-.SH "BUG REPORTS"
+\fB\-\-version\fR
+print program version
+.PP
+Mandatory or optional arguments to long options are also mandatory or optional
+for any corresponding short options.
+
+.PP
+.SH EXAMPLES
+When creating an archive, cpio takes the list of files to be
+processed from the standard input, and then sends the archive to the
+standard output, or to the device defined by the `\fB\-F\fR' option.
+Usually find or ls is used to provide this list to
+the standard input. In the following example you can see the
+possibilities for archiving the contents of a single directory.
+.PP
+.B % ls | cpio \-ov > directory.cpio
+.PP
+The `\fB\-o\fR' option creates the archive, and the `\fB\-v\fR' option prints the
+names of the files archived as they are added. Notice that the options
+can be put together after a single `\fB\-\fR' or can be placed separately on
+the command line. The `\fB>\fR' redirects the cpio output to the file
+`\fBdirectory.cpio\fR'.
+.PP
+If you wanted to archive an entire directory tree, the find command
+can provide the file list to cpio:
+.PP
+.B % find . \-print \-depth | cpio \-ov > tree.cpio
+.PP
+This will take all the files in the current directory, the
+directories below and place them in the archive tree.cpio. Again the
+`\fB\-o\fR' creates an archive, and the `\fB\-v\fR' option shows you the name of the
+files as they are archived. see \*(lqCopy\-out mode\*(rq. Using the `\fB.\fR' in
+the find statement will give you more flexibility when doing restores,
+as it will save file names with a relative path vice a hard wired,
+absolute path. The `\fB\-depth\fR' option forces `\fBfind\fR' to print of the
+entries in a directory before printing the directory itself. This
+limits the effects of restrictive directory permissions by printing the
+directory entries in a directory before the directory name itself.
+.PP
+Extracting an archive requires a bit more thought because cpio will
+not create directories by default. Another characteristic, is it will
+not overwrite existing files unless you tell it to.
+.PP
+.B % cpio \-iv < directory.cpio
+.PP
+This will retrieve the files archived in the file directory.cpio and
+place them in the present directory. The `\fB\-i\fR' option extracts the
+archive and the `\fB\-v\fR' shows the file names as they are extracted. If
+you are dealing with an archived directory tree, you need to use the
+`\fB\-d\fR' option to create directories as necessary, something like:
+.PP
+.B % cpio \-idv < tree.cpio
+.PP
+This will take the contents of the archive tree.cpio and extract it
+to the current directory. If you try to extract the files on top of
+files of the same name that already exist (and have the same or later
+modification time) cpio will not extract the file unless told to do so
+by the \-u option. see \*(lqCopy\-in mode\*(rq.
+.PP
+In copy-pass mode, cpio copies files from one directory tree to
+another, combining the copy-out and copy-in steps without actually
+using an archive. It reads the list of files to copy from the standard
+input; the directory into which it will copy them is given as a
+non-option argument. see \*(lqCopy\-pass mode\*(rq.
+.PP
+.B % find . \-depth \-print0 | cpio \-\-null \-pvd new-dir
+.PP
+The example shows copying the files of the present directory, and
+sub-directories to a new directory called new\-dir. Some new options are
+the `\fB\-print0\fR' available with \s-1GNU\s0 find, combined with the `\fB\-\-null\fR'
+option of cpio. These two options act together to send file names
+between find and cpio, even if special characters are embedded in the
+file names. Another is `\fB\-p\fR', which tells cpio to pass the files it
+finds to the directory `\fBnew-dir\fR'.
+
+
+.SH AUTHOR
+Written by Phil Nelson, David MacKenzie, John Oleynick,
+and Sergey Poznyakoff.
+.SH "REPORTING BUGS"
Report bugs to .
+Report bugs in this manual page via https://bugzilla.redhat.com.
.SH COPYRIGHT
-Copyright \(co 2014 Free Software Foundation, Inc.
-.br
-.na
-License GPLv3+: GNU GPL version 3 or later
+Copyright \(co 2015 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later .
.br
-.ad
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
-.\" Local variables:
-.\" eval: (add-hook 'write-file-hooks 'time-stamp)
-.\" time-stamp-start: ".TH [A-Z_][A-Z0-9_.\\-]* [0-9] \""
-.\" time-stamp-format: "%:B %:d, %:y"
-.\" time-stamp-end: "\""
-.\" time-stamp-line-limit: 20
-.\" end:
+.SH "SEE ALSO"
+The full documentation for
+.B cpio
+is maintained as a Texinfo manual. If the
+.B info
+and
+.B cpio
+programs are properly installed at your site, the command
+.IP
+.B info cpio
+.PP
+should give you access to the complete manual.
+The online copy of the documentation is available at the following address:
+.PP
+http://www.gnu.org/software/cpio/manual
diff --git a/doc/cpio.texi b/doc/cpio.texi
index e631934..a788b5d 100644
--- a/doc/cpio.texi
+++ b/doc/cpio.texi
@@ -261,7 +261,8 @@ Sets the I/O block size to @var{block-size} * 512 bytes.
@item -B
Set the I/O block size to 5120 bytes.
@item -c
-Use the old portable (ASCII) archive format.
+Identical to "-H newc", use the new (SVR4) portable format. If you wish the old
+portable (ASCII) archive format, use "-H odc" instead.
@item -C @var{number}
@itemx --io-size=@var{number}
Set the I/O block size to the given @var{number} of bytes.
@@ -343,7 +344,8 @@ Equivalent to @option{-sS}.
@item -B
Set the I/O block size to 5120 bytes.
@item -c
-Use the old portable (ASCII) archive format.
+Identical to "-H newc", use the new (SVR4) portable format. If you wish the old
+portable (ASCII) archive format, use "-H odc" instead.
@item -C @var{number}
@itemx --io-size=@var{number}
Set the I/O block size to the given @var{number} of bytes.
@@ -454,7 +456,8 @@ Sets the I/O block size to @var{block-size} * 512 bytes.
@item -B
Set the I/O block size to 5120 bytes.
@item -c
-Use the old portable (ASCII) archive format.
+Identical to "-H newc", use the new (SVR4) portable format. If you wish the old
+portable (ASCII) archive format, use "-H odc" instead.
@item -C @var{number}
@itemx --io-size=@var{number}
Set the I/O block size to the given @var{number} of bytes.
@@ -600,7 +603,8 @@ block size is 512 bytes.
@item -c
[@ref{copy-in},@ref{copy-out},@ref{copy-pass}]
-@*Use the old portable (ASCII) archive format.
+@*Identical to "-H newc", use the new (SVR4) portable format. If you wish the
+old portable (ASCII) archive format, use "-H odc" instead.
@item -C @var{io-size}
@itemx --io-size=@var{io-size}
diff --git a/src/Makefile.am b/src/Makefile.am
index 9d1f322..75698dc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,7 +19,7 @@
AM_CPPFLAGS=-I. -I.. -I$(top_srcdir)/gnu -I$(top_builddir)/gnu -I$(top_srcdir)/lib -I$(top_builddir)/lib
-bin_PROGRAMS=cpio $(CPIO_MT)
+bin_PROGRAMS=cpio cpiostatic $(CPIO_MT)
if CPIO_MT_COND
CPIO_MT=mt
endif
@@ -53,5 +53,8 @@ noinst_HEADERS =\
filetypes.h\
safe-stat.h
+cpiostatic_SOURCES = $(cpio_SOURCES)
+cpiostatic_LDFLAGS = -static
+
LDADD=../lib/libpax.a ../gnu/libgnu.a @INTLLIBS@
diff --git a/src/copyin.c b/src/copyin.c
index cde911e..23343bf 100644
--- a/src/copyin.c
+++ b/src/copyin.c
@@ -201,11 +201,11 @@ list_file (struct cpio_file_stat* file_hdr, int in_file_des)
static int
try_existing_file (struct cpio_file_stat* file_hdr, int in_file_des,
- int *existing_dir)
+ mode_t *existing_mode)
{
struct stat file_stat;
- *existing_dir = false;
+ *existing_mode = 0;
if (lstat (file_hdr->c_name, &file_stat) == 0)
{
if (S_ISDIR (file_stat.st_mode)
@@ -214,10 +214,11 @@ try_existing_file (struct cpio_file_stat* file_hdr, int in_file_des,
/* If there is already a directory there that
we are trying to create, don't complain about
it. */
- *existing_dir = true;
+ *existing_mode = S_IFMT | file_stat.st_mode;
return 0;
}
else if (!unconditional_flag
+ && (file_hdr->c_mode & CP_IFMT) != CP_IFDIR
&& file_hdr->c_mtime <= file_stat.st_mtime)
{
error (0, 0, _("%s not created: newer or same age version exists"),
@@ -388,12 +389,12 @@ create_final_defers ()
continue;
}
out_file_des = open (d->header.c_name,
- O_CREAT | O_WRONLY | O_BINARY, 0600);
+ O_CREAT | O_EXCL | O_WRONLY | O_BINARY, 0600);
if (out_file_des < 0 && create_dir_flag)
{
create_all_directories (d->header.c_name);
out_file_des = open (d->header.c_name,
- O_CREAT | O_WRONLY | O_BINARY,
+ O_CREAT | O_EXCL | O_WRONLY | O_BINARY,
0600);
}
if (out_file_des < 0)
@@ -496,13 +497,13 @@ copyin_regular_file (struct cpio_file_stat* file_hdr, int in_file_des)
/* If not linked, copy the contents of the file. */
out_file_des = open (file_hdr->c_name,
- O_CREAT | O_WRONLY | O_BINARY, 0600);
+ O_CREAT | O_EXCL | O_WRONLY | O_BINARY, 0600);
if (out_file_des < 0 && create_dir_flag)
{
create_all_directories (file_hdr->c_name);
out_file_des = open (file_hdr->c_name,
- O_CREAT | O_WRONLY | O_BINARY,
+ O_CREAT | O_EXCL | O_WRONLY | O_BINARY,
0600);
}
@@ -615,12 +616,12 @@ copyin_device (struct cpio_file_stat* file_hdr)
return;
}
- res = mknod (file_hdr->c_name, file_hdr->c_mode,
+ res = mknod (file_hdr->c_name, file_hdr->c_mode & ~077,
makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min));
if (res < 0 && create_dir_flag)
{
create_all_directories (file_hdr->c_name);
- res = mknod (file_hdr->c_name, file_hdr->c_mode,
+ res = mknod (file_hdr->c_name, file_hdr->c_mode & ~077,
makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min));
}
if (res < 0)
@@ -698,10 +699,10 @@ copyin_link (struct cpio_file_stat *file_hdr, int in_file_des)
static void
copyin_file (struct cpio_file_stat *file_hdr, int in_file_des)
{
- int existing_dir;
+ mode_t existing_mode = 0;
if (!to_stdout_option
- && try_existing_file (file_hdr, in_file_des, &existing_dir) < 0)
+ && try_existing_file (file_hdr, in_file_des, &existing_mode) < 0)
return;
/* Do the real copy or link. */
@@ -712,7 +713,7 @@ copyin_file (struct cpio_file_stat *file_hdr, int in_file_des)
break;
case CP_IFDIR:
- cpio_create_dir (file_hdr, existing_dir);
+ cpio_create_dir (file_hdr, existing_mode);
break;
case CP_IFCHR:
@@ -918,14 +919,14 @@ from_ascii (char const *where, size_t digs, unsigned logbase)
char *p = strchr (codetab, toupper (*buf));
if (!p)
{
- error (0, 0, _("Malformed number %.*s"), digs, where);
+ error (0, 0, _("Malformed number %.*s"), (unsigned) digs, where);
break;
}
d = p - codetab;
if ((d >> logbase) > 1)
{
- error (0, 0, _("Malformed number %.*s"), digs, where);
+ error (0, 0, _("Malformed number %.*s"), (unsigned) digs, where);
break;
}
value += d;
@@ -936,7 +937,7 @@ from_ascii (char const *where, size_t digs, unsigned logbase)
}
if (overflow)
error (0, 0, _("Archive value %.*s is out of range"),
- digs, where);
+ (unsigned) digs, where);
return value;
}
@@ -965,7 +966,9 @@ read_in_header (struct cpio_file_stat *file_hdr, int in_des)
char tmpbuf[512];
int check_tar;
int peeked_bytes;
+ union { char *buf; unsigned short *num; } bufnum;
+ bufnum.buf = tmpbuf;
while (archive_format == arf_unknown)
{
peeked_bytes = tape_buffered_peek (tmpbuf, in_des, 512);
@@ -981,8 +984,8 @@ read_in_header (struct cpio_file_stat *file_hdr, int in_des)
archive_format = arf_crcascii;
crc_i_flag = true;
}
- else if ((*((unsigned short *) tmpbuf) == 070707) ||
- (*((unsigned short *) tmpbuf) == swab_short ((unsigned short) 070707)))
+ else if ((*bufnum.num == 070707) ||
+ (*bufnum.num == swab_short ((unsigned short) 070707)))
archive_format = arf_binary;
else if (peeked_bytes >= 512
&& (check_tar = is_tar_header (tmpbuf)))
@@ -1196,15 +1199,15 @@ read_in_binary (struct cpio_file_stat *file_hdr,
swab_array ((char *) short_hdr, 13);
}
- file_hdr->c_dev_maj = major (short_hdr->c_dev);
- file_hdr->c_dev_min = minor (short_hdr->c_dev);
+ file_hdr->c_dev_maj = major ((unsigned short)short_hdr->c_dev);
+ file_hdr->c_dev_min = minor ((unsigned short)short_hdr->c_dev);
file_hdr->c_ino = short_hdr->c_ino;
file_hdr->c_mode = short_hdr->c_mode;
file_hdr->c_uid = short_hdr->c_uid;
file_hdr->c_gid = short_hdr->c_gid;
file_hdr->c_nlink = short_hdr->c_nlink;
- file_hdr->c_rdev_maj = major (short_hdr->c_rdev);
- file_hdr->c_rdev_min = minor (short_hdr->c_rdev);
+ file_hdr->c_rdev_maj = major ((unsigned short)short_hdr->c_rdev);
+ file_hdr->c_rdev_min = minor ((unsigned short)short_hdr->c_rdev);
file_hdr->c_mtime = (unsigned long) short_hdr->c_mtimes[0] << 16
| short_hdr->c_mtimes[1];
diff --git a/src/copyout.c b/src/copyout.c
index 1f0987a..19378e0 100644
--- a/src/copyout.c
+++ b/src/copyout.c
@@ -158,8 +158,8 @@ writeout_other_defers (struct cpio_file_stat *file_hdr, int out_des)
struct deferment *d;
struct deferment *d_prev;
ino_t ino;
- int maj;
- int min;
+ long maj;
+ long min;
ino = file_hdr->c_ino;
maj = file_hdr->c_dev_maj;
min = file_hdr->c_dev_min;
@@ -245,7 +245,7 @@ static void
writeout_final_defers (int out_des)
{
struct deferment *d;
- int other_count;
+ size_t other_count;
while (deferouts != NULL)
{
d = deferouts;
@@ -287,7 +287,7 @@ to_ascii (char *where, uintmax_t v, size_t digits, unsigned logbase)
static void
field_width_error (const char *filename, const char *fieldname)
{
- error (0, 0, _("%s: field width not sufficient for storing %s"),
+ error (1, 0, _("%s: field width not sufficient for storing %s"),
filename, fieldname);
}
diff --git a/src/copypass.c b/src/copypass.c
index c5a9899..8d2ec67 100644
--- a/src/copypass.c
+++ b/src/copypass.c
@@ -59,7 +59,7 @@ process_copy_pass ()
struct stat out_file_stat; /* Stat record for output file. */
int in_file_des; /* Input file descriptor. */
int out_file_des; /* Output file descriptor. */
- int existing_dir; /* True if file is a dir & already exists. */
+ mode_t existing_mode; /* Mode if file is a dir & already exists. */
#ifdef HPUX_CDF
int cdf_flag;
int cdf_char;
@@ -130,7 +130,7 @@ process_copy_pass ()
ds_resize (&output_name, dirname_len + strlen (slash) + 2);
strcpy (output_name.ds_string + dirname_len + 1, slash);
- existing_dir = false;
+ existing_mode = 0;
if (lstat (output_name.ds_string, &out_file_stat) == 0)
{
if (S_ISDIR (out_file_stat.st_mode)
@@ -138,7 +138,7 @@ process_copy_pass ()
{
/* If there is already a directory there that
we are trying to create, don't complain about it. */
- existing_dir = true;
+ existing_mode = S_IFMT | out_file_stat.st_mode;
}
else if (!unconditional_flag
&& in_file_stat.st_mtime <= out_file_stat.st_mtime)
@@ -185,12 +185,12 @@ process_copy_pass ()
continue;
}
out_file_des = open (output_name.ds_string,
- O_CREAT | O_WRONLY | O_BINARY, 0600);
+ O_CREAT | O_EXCL | O_WRONLY | O_BINARY, 0600);
if (out_file_des < 0 && create_dir_flag)
{
create_all_directories (output_name.ds_string);
out_file_des = open (output_name.ds_string,
- O_CREAT | O_WRONLY | O_BINARY, 0600);
+ O_CREAT | O_EXCL | O_WRONLY | O_BINARY, 0600);
}
if (out_file_des < 0)
{
@@ -233,7 +233,7 @@ process_copy_pass ()
stat_to_cpio (&file_stat, &in_file_stat);
file_stat.c_name = output_name.ds_string;
- cpio_create_dir (&file_stat, existing_dir);
+ cpio_create_dir (&file_stat, existing_mode);
}
else if (S_ISCHR (in_file_stat.st_mode) ||
S_ISBLK (in_file_stat.st_mode) ||
@@ -259,12 +259,14 @@ process_copy_pass ()
if (link_res < 0)
{
- res = mknod (output_name.ds_string, in_file_stat.st_mode,
+ res = mknod (output_name.ds_string,
+ in_file_stat.st_mode & ~077,
in_file_stat.st_rdev);
if (res < 0 && create_dir_flag)
{
create_all_directories (output_name.ds_string);
- res = mknod (output_name.ds_string, in_file_stat.st_mode,
+ res = mknod (output_name.ds_string,
+ in_file_stat.st_mode & ~077,
in_file_stat.st_rdev);
}
if (res < 0)
diff --git a/src/extern.h b/src/extern.h
index e27d662..282d31b 100644
--- a/src/extern.h
+++ b/src/extern.h
@@ -201,7 +201,7 @@ void stat_to_cpio (struct cpio_file_stat *hdr, struct stat *st);
void cpio_to_stat (struct stat *st, struct cpio_file_stat *hdr);
void cpio_safer_name_suffix (char *name, bool link_target,
bool absolute_names, bool strip_leading_dots);
-int cpio_create_dir (struct cpio_file_stat *file_hdr, int existing_dir);
+int cpio_create_dir (struct cpio_file_stat *file_hdr, mode_t existing_mode);
void change_dir (void);
/* FIXME: These two defines should be defined in paxutils */
diff --git a/src/global.c b/src/global.c
index 57e505a..5106271 100644
--- a/src/global.c
+++ b/src/global.c
@@ -184,9 +184,6 @@ unsigned int warn_option = 0;
/* Extract to standard output? */
bool to_stdout_option = false;
-/* The name this program was run with. */
-char *program_name;
-
/* A pointer to either lstat or stat, depending on whether
dereferencing of symlinks is done for input files. */
int (*xstat) ();
diff --git a/src/main.c b/src/main.c
index a13861f..c4e0218 100644
--- a/src/main.c
+++ b/src/main.c
@@ -254,6 +254,7 @@ static struct argp_option options[] = {
static char *input_archive_name = 0;
static char *output_archive_name = 0;
+static int abs_paths_flag_changed = false;
static int
warn_control (char *arg)
@@ -329,7 +330,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
case 'c': /* Use the old portable ASCII format. */
if (archive_format != arf_unknown)
USAGE_ERROR ((0, 0, _("Archive format multiply defined")));
-#ifdef SVR4_COMPAT
+#if 1 /* used to be SVR4_COMPAT */
archive_format = arf_newascii; /* -H newc. */
#else
archive_format = arf_oldascii; /* -H odc. */
@@ -419,10 +420,12 @@ crc newc odc bin ustar tar (all-caps also recognized)"), arg));
case NO_ABSOLUTE_FILENAMES_OPTION: /* --no-absolute-filenames */
no_abs_paths_flag = true;
+ abs_paths_flag_changed = true;
break;
case ABSOLUTE_FILENAMES_OPTION: /* --absolute-filenames */
no_abs_paths_flag = false;
+ abs_paths_flag_changed = true;
break;
case NO_PRESERVE_OWNER_OPTION: /* --no-preserve-owner */
@@ -637,6 +640,8 @@ process_args (int argc, char *argv[])
save_patterns = &argv[index];
if (input_archive_name)
archive_name = input_archive_name;
+ if (!abs_paths_flag_changed)
+ no_abs_paths_flag = true;
}
else if (copy_function == copy_out)
{
@@ -673,6 +678,8 @@ process_args (int argc, char *argv[])
archive_format = arf_binary;
if (output_archive_name)
archive_name = output_archive_name;
+ if (!abs_paths_flag_changed)
+ no_abs_paths_flag = false;
if (!arf_stores_inode_p (archive_format))
renumber_inodes_option = ignore_devno_option = 0;
@@ -697,10 +704,10 @@ process_args (int argc, char *argv[])
CHECK_USAGE (rename_flag, "--rename", "--pass-through");
CHECK_USAGE (append_flag, "--append", "--pass-through");
CHECK_USAGE (rename_batch_file, "--rename-batch-file", "--pass-through");
- CHECK_USAGE (no_abs_paths_flag, "--no-absolute-pathnames",
- "--pass-through");
- CHECK_USAGE (no_abs_paths_flag, "--absolute-pathnames",
- "--pass-through");
+ CHECK_USAGE((abs_paths_flag_changed && no_abs_paths_flag),
+ "--no-absolute-pathnames", "--pass-through");
+ CHECK_USAGE((abs_paths_flag_changed && !no_abs_paths_flag),
+ "--absolute-pathnames", "--pass-through");
CHECK_USAGE (to_stdout_option, "--to-stdout", "--pass-through");
CHECK_USAGE (renumber_inodes_option, "--renumber-inodes",
"--pass-through");
diff --git a/src/tar.c b/src/tar.c
index a2ce171..e2b5f45 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -49,10 +49,12 @@ split_long_name (const char *name, size_t length)
{
size_t i;
- if (length > TARPREFIXSIZE)
- length = TARPREFIXSIZE+2;
+ if (length > TARPREFIXSIZE + 1)
+ length = TARPREFIXSIZE + 1;
+ else if (ISSLASH (name[length - 1]))
+ length--;
for (i = length - 1; i > 0; i--)
- if (name[i] == '/')
+ if (ISSLASH (name[i]))
break;
return i;
}
diff --git a/src/util.c b/src/util.c
index 6ff6032..bdbfb9b 100644
--- a/src/util.c
+++ b/src/util.c
@@ -499,7 +499,7 @@ copy_files_disk_to_tape (int in_des, int out_des, off_t num_bytes,
}
else
error (0, 0, _("Read error at byte %lld in file %s, padding with zeros"),
- original_num_bytes - num_bytes, filename);
+ (long long)(original_num_bytes - num_bytes), filename);
write_nuls_to_file (num_bytes, out_des, tape_buffered_write);
break;
}
@@ -549,7 +549,7 @@ copy_files_disk_to_disk (int in_des, int out_des, off_t num_bytes,
}
else
error (0, 0, _("Read error at byte %lld in file %s, padding with zeros"),
- original_num_bytes - num_bytes, filename);
+ (long long)(original_num_bytes - num_bytes), filename);
write_nuls_to_file (num_bytes, out_des, disk_buffered_write);
break;
}
@@ -599,19 +599,16 @@ void
create_all_directories (char *name)
{
char *dir;
- int mode;
#ifdef HPUX_CDF
int cdf;
#endif
dir = dir_name (name);
- mode = 0700;
#ifdef HPUX_CDF
cdf = islastparentcdf (name);
if (cdf)
{
dir [strlen (dir) - 1] = '\0'; /* remove final + */
- mode = 04700;
}
#endif
@@ -664,7 +661,8 @@ prepare_append (int out_file_des)
if (useful_bytes_in_block > 0)
{
tmp_buf = (char *) xmalloc (useful_bytes_in_block);
- read (out_file_des, tmp_buf, useful_bytes_in_block);
+ if (read (out_file_des, tmp_buf, useful_bytes_in_block) < 0)
+ error (1, errno, _("cannot read output"));
if (lseek (out_file_des, start_of_block, SEEK_SET) < 0)
error (PAXEXIT_FAILURE, errno, _("cannot seek on output"));
/* fix juo -- is this copy_tape_buf_out? or copy_disk? */
@@ -718,7 +716,6 @@ find_inode_val (ino_t node_num, unsigned long major_num,
unsigned long minor_num)
{
struct inode_val sample;
- struct inode_val *ival;
if (!hash_table)
return NULL;
@@ -768,7 +765,7 @@ add_inode (ino_t node_num, char *file_name, unsigned long major_num,
return e;
}
-static ino_t
+static void
get_inode_and_dev (struct cpio_file_stat *hdr, struct stat *st)
{
if (renumber_inodes_option)
@@ -1549,11 +1546,11 @@ static int
cpio_mkdir (struct cpio_file_stat *file_hdr, int *setstat_delayed)
{
int rc;
- mode_t mode = file_hdr->c_mode;
+ mode_t mode = (file_hdr->c_mode | MODE_WXUSR) & ~(S_IRWXG | S_IRWXO);
- if (!(file_hdr->c_mode & S_IWUSR))
+ rc = mkdir (file_hdr->c_name, mode);
+ if (mode != file_hdr->c_mode)
{
- rc = mkdir (file_hdr->c_name, mode | S_IWUSR);
if (rc == 0)
{
delay_cpio_set_stat (file_hdr, 0);
@@ -1562,14 +1559,13 @@ cpio_mkdir (struct cpio_file_stat *file_hdr, int *setstat_delayed)
}
else
{
- rc = mkdir (file_hdr->c_name, mode);
*setstat_delayed = 0;
}
return rc;
}
int
-cpio_create_dir (struct cpio_file_stat *file_hdr, int existing_dir)
+cpio_create_dir (struct cpio_file_stat *file_hdr, mode_t existing_mode)
{
int res; /* Result of various function calls. */
#ifdef HPUX_CDF
@@ -1597,7 +1593,25 @@ cpio_create_dir (struct cpio_file_stat *file_hdr, int existing_dir)
#ifdef HPUX_CDF
cdf_flag = 0;
#endif
- if (!existing_dir)
+ if (existing_mode)
+ {
+ existing_mode &= 07777;
+ mode_t mode = existing_mode & ~(newdir_umask & 077);
+ if (!no_chown_flag && mode != existing_mode)
+ {
+ if (chmod (file_hdr->c_name, mode) < 0)
+ {
+ chmod_error_details (file_hdr->c_name, mode);
+ }
+ else
+ {
+ delay_cpio_set_stat (file_hdr, 0);
+ setstat_delayed = 1;
+ }
+ }
+ res = 0;
+ }
+ else
{
#ifdef HPUX_CDF
/* If the directory name ends in a + and is SUID,
@@ -1614,8 +1628,6 @@ cpio_create_dir (struct cpio_file_stat *file_hdr, int existing_dir)
#endif
res = cpio_mkdir (file_hdr, &setstat_delayed);
}
- else
- res = 0;
if (res < 0 && create_dir_flag)
{
create_all_directories (file_hdr->c_name);
diff --git a/tests/genfile.c b/tests/genfile.c
index d41336b..4699d21 100644
--- a/tests/genfile.c
+++ b/tests/genfile.c
@@ -557,7 +557,6 @@ make_fragment (int fd, char *offstr, char *mapstr)
static void
generate_sparse_file (int argc, char **argv)
{
- int i;
int fd;
int flags = O_CREAT | O_RDWR | O_BINARY;