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;