Import heavily trimmed gnu cpio-2.8.
(2.9 switched to gpl3 a few weeks later)
This commit is contained in:
parent
43c61ec889
commit
6ae22f7302
4
COPYING
4
COPYING
@ -2,7 +2,7 @@
|
|||||||
Version 2, June 1991
|
Version 2, June 1991
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
@ -305,7 +305,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
384
ChangeLog
384
ChangeLog
@ -1,3 +1,387 @@
|
|||||||
|
2007-06-08 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* configure.ac, NEWS: Version number 2.8
|
||||||
|
* bootstrap.conf: Update
|
||||||
|
|
||||||
|
2007-06-07 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* NEWS: Update
|
||||||
|
* configure.ac: Raise version to 2.7.90
|
||||||
|
* doc/cpio.texi: Update
|
||||||
|
* src/extern.h (set_perms, set_file_times): Take file descriptor
|
||||||
|
as the first argument.
|
||||||
|
* src/util.c (set_perms): Take file descriptor
|
||||||
|
as the first argument and use fchmod/fchown if available. Fixes
|
||||||
|
CAN-2005-1111.
|
||||||
|
* src/copyin.c, src/copyout.c, src/copypass.c: Update calls to
|
||||||
|
set_perms.
|
||||||
|
* src/makepath.c: Remove useless includes.
|
||||||
|
|
||||||
|
* src/util.c (set_perms, stat_to_cpio): Use CPIO_UID and CPIO_GID
|
||||||
|
macros to set uid and gid
|
||||||
|
* src/main.c (process_args): Allow to use --owner in copy-out mode.
|
||||||
|
* THANKS: Add Mike Frysinger
|
||||||
|
|
||||||
|
2007-05-18 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* bootstrap: Update from tar repository
|
||||||
|
* doc/cpio.texi: Fix typo
|
||||||
|
* src/copyin.c (from_ascii): Bugfix: allow for empty fields
|
||||||
|
* src/copyout.c (process_copy_out): Fix memory leaks on
|
||||||
|
orig_file_name.
|
||||||
|
* src/copypass.c (process_copy_pass): symlink_error takes two
|
||||||
|
arguments.
|
||||||
|
* src/extern.h: Add missing includes.
|
||||||
|
|
||||||
|
2006-12-18 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* README-cvs: New file
|
||||||
|
* lib/Makefile.tmpl, lib/bcopy.c, lib/mkdir.c, lib/strdup.c,
|
||||||
|
lib/strerror.c, lib/.cvsignore, po/.cvsignore,
|
||||||
|
po/Makevars: Removed
|
||||||
|
* lib/Makefile.am: New file
|
||||||
|
* po/POTFILES.in: Update
|
||||||
|
* bootstrap: Synch with tar.
|
||||||
|
* configure.ac: Update
|
||||||
|
* gnulib.modules: Add lchown, strerror
|
||||||
|
* src/Makefile.am: Update
|
||||||
|
* src/main.c, src/mt.c: Include rmt-command.h instead of localedir.h
|
||||||
|
* .cvsignore, doc/.cvsignore: Sort
|
||||||
|
|
||||||
|
* src/util.c (sparse_write): Static. Provide a forward
|
||||||
|
declaration. Define enum sparse_write_states inside the function.
|
||||||
|
|
||||||
|
* src/copyin.c (long_format): Use PRIuMAX for printing file size
|
||||||
|
* src/copyout.c (write_out_binary_header): Fix size conversion
|
||||||
|
* src/extern.h (tape_toss_input, warn_if_file_changed): Last
|
||||||
|
argument is off_t
|
||||||
|
* src/util.c (tape_toss_input, warn_if_file_changed): Last
|
||||||
|
argument is off_t
|
||||||
|
(warn_if_file_changed): Use ngettext
|
||||||
|
|
||||||
|
2006-11-15 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* src/copypass.c: Fix setting output file permissions
|
||||||
|
|
||||||
|
2006-11-13 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* doc/cpio.texi: Consistently use @option{} for displaying command
|
||||||
|
line options.
|
||||||
|
Fix formatting in "Invoking `cpio'" section
|
||||||
|
* src/main.c (process_args): Fix usage error diagnostics in
|
||||||
|
copy-pass mode.
|
||||||
|
|
||||||
|
2006-10-24 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* src/copyout.c (process_copy_out): Add terminating zero to the
|
||||||
|
link_name.
|
||||||
|
|
||||||
|
* tests/symlink.at: New testcase
|
||||||
|
* tests/Makefile.am: New test symlink.at
|
||||||
|
* tests/inout.at: Add keywords
|
||||||
|
* tests/testsuite.at (AT_SKIP_TEST): New macro
|
||||||
|
New test symlink.at
|
||||||
|
|
||||||
|
2006-10-21 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* configure.ac, NEWS: Version 2.7
|
||||||
|
* gnulib.modules: Add stdint
|
||||||
|
* src/util.c: Use STRINGIFY_BIGINT to display num_bytes
|
||||||
|
|
||||||
|
2006-09-27 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* TODO: Update
|
||||||
|
* README-alpha: Update
|
||||||
|
* bootstrap: Imported from tar
|
||||||
|
* configure.ac: Require autoconf 2.59 and gettext 1.15
|
||||||
|
* gnulib.modules: add inttypes
|
||||||
|
* doc/cpio.texi: Minor fixes
|
||||||
|
* po/Makevars: Remove automatically generated file
|
||||||
|
* po/.cvsignore: Add Makevars
|
||||||
|
* lib/.cvsignore: Update
|
||||||
|
* src/copyin.c, src/copyout.c, src/copypass.c, src/cpio.h,
|
||||||
|
src/cpiohdr.h, src/defer.c, src/defer.h, src/extern.h,
|
||||||
|
src/global.c, src/main.c, src/makepath.c, src/tar.c,
|
||||||
|
src/util.c: Update copyright year.
|
||||||
|
|
||||||
|
2006-07-04 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* bootstrap (update_po): Fix single translation update
|
||||||
|
* lib/Makefile.tmpl: Initialize AM_CPPFLAGS
|
||||||
|
(noinst_HEADERS): Add system-ioctl.h
|
||||||
|
|
||||||
|
Start rewriting using a better suited internal representation for
|
||||||
|
the file meta-data.
|
||||||
|
|
||||||
|
* src/cpiohdr.h (struct old_cpio_header): Remove unused fields
|
||||||
|
c_mtime, c_filesize and c_name.
|
||||||
|
(struct old_ascii_header): New data type
|
||||||
|
(struct new_ascii_header): New data type. Describes the header
|
||||||
|
structure, not its internal representation.
|
||||||
|
(struct cpio_file_stat): New data type. Describes internal
|
||||||
|
representation of a file metadata
|
||||||
|
|
||||||
|
* src/copyin.c (from_ascii): New function
|
||||||
|
Use cpio_file_stat for internal header representation.
|
||||||
|
* src/copyout.c: Use cpio_file_stat for internal header
|
||||||
|
representation. Among other things this fixes bug reported by
|
||||||
|
Peter Vrabec on Mar 2, 2006
|
||||||
|
(http://lists.gnu.org/archive/html/bug-cpio/2006-03/msg00000.html)
|
||||||
|
* src/copypass.c: Use cpio_file_stat for internal header
|
||||||
|
representation.
|
||||||
|
* src/tar.c: Likewise
|
||||||
|
* src/util.c: Likewise
|
||||||
|
* src/defer.c: Likewise
|
||||||
|
* src/defer.h: Likewise
|
||||||
|
* src/extern.h: Likewise
|
||||||
|
(from_ascii): New prototype
|
||||||
|
(LG_8,LG_16,FROM_OCTAL,FROM_HEX): New defines
|
||||||
|
* src/main.c: New command line option --HANG (hidden)
|
||||||
|
|
||||||
|
2006-03-12 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* tests/Makefile.am (AM_CPPFLAGS): Define LOCALEDIR
|
||||||
|
|
||||||
|
2006-02-18 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* gnulib.modules: Add stpcpy. Thanks Benigno B. Junior for
|
||||||
|
reporting.
|
||||||
|
* THANKS: Add Benigno B. Junior
|
||||||
|
* src/makepath.c: Fix indentation.
|
||||||
|
|
||||||
|
2005-11-16 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* src/copyout.c (process_copy_out): Fix typo.
|
||||||
|
|
||||||
|
2005-11-12 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* bootstrap: Minor fix
|
||||||
|
* src/copyout.c (write_out_header): Rewritten using separate
|
||||||
|
functions for each file format. Use to_ascii to convert numbers to
|
||||||
|
ascii representation. Check for overflows and report them if
|
||||||
|
appropriate. Return 0 if it is OK to proceed with archiving this
|
||||||
|
file, 1 otherwise. All callers updated.
|
||||||
|
* src/extern.h (write_out_header): Return int.
|
||||||
|
|
||||||
|
2005-10-28 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* src/util.c: Include paxlib.
|
||||||
|
* bootstrap: If file `.bootstrap' exists in the cwd and is
|
||||||
|
readable, prepend its contents to the command line.
|
||||||
|
|
||||||
|
Fix Debian bug 335580:
|
||||||
|
|
||||||
|
* src/copyout.c (read_for_checksum,write_out_header): CRC is a
|
||||||
|
32-bit unsigned value. Patch proposed by Jim Castleberry and
|
||||||
|
Peter Vrabec.
|
||||||
|
* src/extern.h (crc): Change declaration
|
||||||
|
* src/global.c: Likewise
|
||||||
|
* src/tar.c (tar_checksum): Return unsigned int
|
||||||
|
|
||||||
|
* THANKS: Add Jim Castleberry
|
||||||
|
* NEWS: Updated
|
||||||
|
|
||||||
|
2005-09-30 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* src/copyout.c (process_copy_out): Discern between original and
|
||||||
|
(eventually fixed) file name (in tar terminology, `file name'
|
||||||
|
vs. `member name'.
|
||||||
|
|
||||||
|
2005-09-08 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||||
|
|
||||||
|
* gnulib.modules: Add utimens
|
||||||
|
* src/util.c (cpio_safer_name_suffix): Preserve ./ no matter what
|
||||||
|
the value of strip_leading_dots is.
|
||||||
|
(set_file_times): New function
|
||||||
|
* src/extern.h (set_file_times): New function
|
||||||
|
* src/copyin.c: Use set_file_times() to update file atime/mtime
|
||||||
|
* src/copyout.c: Likewise.
|
||||||
|
* src/copypass.c: Likewise.
|
||||||
|
|
||||||
|
2005-05-25 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||||
|
|
||||||
|
* src/copyin.c: Use cpio_safer_name_suffix() and CPIO_TRAILER_NAME
|
||||||
|
define instead of hardcoding the trailer file name.
|
||||||
|
* src/copyout.c: Likewise.
|
||||||
|
* src/cpio.h (CPIO_TRAILER_NAME): New define
|
||||||
|
* src/extern.h (cpio_safer_name_suffix): New proto
|
||||||
|
* src/tar.c: Use CPIO_TRAILER_NAME define instead of hardcoding
|
||||||
|
the trailer file name.
|
||||||
|
* src/util.c (cpio_safer_name_suffix): New function
|
||||||
|
(add_cdf_double_slashes): Add FIXME warning.
|
||||||
|
|
||||||
|
* lib/fatal.c: New file
|
||||||
|
* lib/Makefile.tmpl (libcpio_a_SOURCES): Add fatal.c
|
||||||
|
* src/copyout.c: Use error reporting functions from paxlib
|
||||||
|
* src/makepath.c: Likewise
|
||||||
|
* src/mt.c: Likewise
|
||||||
|
* src/main.c (fatal_exit): Moved to lib/fatal.c
|
||||||
|
|
||||||
|
2005-05-24 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||||
|
|
||||||
|
* src/copyin.c (process_copy_in): Use safer_name_suffix no matter
|
||||||
|
what the value of no_abs_paths_flag. The function knows better
|
||||||
|
what to do in any case.
|
||||||
|
* src/copyout.c (process_copy_out): Honor no_abs_paths_flag.
|
||||||
|
* src/main.c (options): Minor fixes.
|
||||||
|
|
||||||
|
2005-05-23 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||||
|
|
||||||
|
* bootstrap (copy_files): Create destination directory if it does
|
||||||
|
not exist.
|
||||||
|
Preserve longlong.m4 as longlong_gl.m4
|
||||||
|
* src/main.c: Include paxlib.h
|
||||||
|
|
||||||
|
2005-05-22 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||||
|
|
||||||
|
* lib/.cvsignore: Updated
|
||||||
|
* gnulib.modules: Add hash
|
||||||
|
* doc/cpio.texi (Reports): New chapter
|
||||||
|
* lib/Makefile.tmpl: Add new paxutils files.
|
||||||
|
* po/POTFILES.in: Likewise
|
||||||
|
* src/copyin.c [!HAVE_LCHOWN] (lchown): Define to 0 to avoid
|
||||||
|
changing ownership of the target file.
|
||||||
|
(process_copy_in): Use safer_name_suffix()
|
||||||
|
* src/main.c (parse_opt): Handle new --absolute-filenames option.
|
||||||
|
(process_args): Updated
|
||||||
|
* src/util.c: Rewrite inode lookup/insertion functions using hash
|
||||||
|
module.
|
||||||
|
|
||||||
|
u2005-05-20 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||||
|
|
||||||
|
* configure.ac: Raised version number to 2.6.90
|
||||||
|
* NEWS: Updated
|
||||||
|
* src/copyin.c: Use set_perms.
|
||||||
|
* src/copypass.c: Likewise.
|
||||||
|
* src/copyout.c (process_copy_out): Use stat_to_cpio() to convert
|
||||||
|
struct stat to struct new_cpio_header.
|
||||||
|
* src/defer.h: Remove legacy P_() stuff.
|
||||||
|
* src/dstring.c: Likewise
|
||||||
|
* src/extern.h: Likewise
|
||||||
|
* src/util.c (stat_to_cpio,set_perms): New functions
|
||||||
|
* doc/.cvsignore: Updated
|
||||||
|
* lib/.cvsignore: Updated
|
||||||
|
* tests/.cvsignore: Updated
|
||||||
|
* .cvsignore: Updated
|
||||||
|
* COPYING: Added to the repository
|
||||||
|
|
||||||
|
2005-05-19 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||||
|
|
||||||
|
* po/POTFILES.in: Add paxerror.c paxexit.c paxconvert.c
|
||||||
|
|
||||||
|
* bootstrap (copy_files): Accept optional third argument: a prefix
|
||||||
|
to be appended to destination file names.
|
||||||
|
Import paxutils/paxlib files.
|
||||||
|
* lib/Makefile.tmpl (libcpio_a_SOURCES): Add paxerror.c paxexit.c
|
||||||
|
paxconvert.c
|
||||||
|
* src/copyin.c: Use paxutils error reporting functions
|
||||||
|
* src/copyout.c: Likewise
|
||||||
|
* src/copypass.c: Likewise
|
||||||
|
* src/util.c: Likewise. Add missing includes
|
||||||
|
* src/main.c (USAGE_ERROR): Removed
|
||||||
|
(CHECK_USAGE,parse_opt,process_args): Use error() instead of USAGE_ERROR
|
||||||
|
(fatal_exit): New function
|
||||||
|
* src/tar.c (is_tar_filename_too_long): Removed unused variable
|
||||||
|
|
||||||
|
* Makefile.am, configure.ac, doc/Makefile.am,
|
||||||
|
doc/cpio.texi, doc/gendocs_template, headers/Makefile.am,
|
||||||
|
headers/fnmatch.h, lib/Makefile.tmpl, lib/mkdir.c,
|
||||||
|
lib/strdup.c, lib/strerror.c, src/Makefile.am,
|
||||||
|
src/copyin.c, src/copyout.c, src/copypass.c, src/cpio.h,
|
||||||
|
src/cpiohdr.h, src/defer.c, src/defer.h, src/dstring.c,
|
||||||
|
src/dstring.h, src/extern.h, src/filemode.c,
|
||||||
|
src/filetypes.h, src/global.c, src/idcache.c,
|
||||||
|
src/main.c, src/makepath.c, src/mt.c, src/tar.c,
|
||||||
|
src/tar.h, src/tarhdr.h, src/userspec.c, src/util.c,
|
||||||
|
tests/Makefile.am, tests/inout.at, tests/testsuite.at,
|
||||||
|
tests/version.at: Updated FSF postal mail address.
|
||||||
|
|
||||||
|
* bootstrap: Port recent changes from tar bootstrap.
|
||||||
|
* gnulib.modules: New file
|
||||||
|
* tests/Makefile.am (genfile_SOURCES,LDADD): Updated
|
||||||
|
|
||||||
|
* THANKS: Updated
|
||||||
|
* configure.ac: Remove check for gethostname, it is never used.
|
||||||
|
Remove check for setsockopt, it is provided by paxutils.
|
||||||
|
|
||||||
|
Fix LFS support issues. Proposed by Peter Vrabec and Dmitry V. Levin
|
||||||
|
|
||||||
|
* src/extern.h (copy_files_tape_to_disk, copy_files_disk_to_tape,
|
||||||
|
copy_files_disk_to_disk): Change num_bytes argument type from
|
||||||
|
long to off_t.
|
||||||
|
* src/util.c (copy_files_tape_to_disk, copy_files_disk_to_tape,
|
||||||
|
copy_files_disk_to_disk, disk_fill_input_buffer,
|
||||||
|
write_nuls_to_file): Likewise.
|
||||||
|
(write_nuls_to_file, copy_files_disk_to_tape,
|
||||||
|
copy_files_disk_to_disk): Handle `off_t num_bytes' properly.
|
||||||
|
|
||||||
|
* src/util.c (find_inode_file): Fix typos causing function to
|
||||||
|
occasionally miss inodes and, therefore, to copy out the same
|
||||||
|
(hard-linked) file several times to archive. Proposed by Brian
|
||||||
|
Mays.
|
||||||
|
|
||||||
|
2005-03-24 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||||
|
|
||||||
|
* src/main.c (process_args): Fixed discrepancy I have been
|
||||||
|
overlooking so far: cpio still does not handle --sparse option
|
||||||
|
the same way tar is handling it. --sparse is allowed in copy-in
|
||||||
|
and copy-pass modes, just as docs say it. Thanks Dmitry Levin.
|
||||||
|
* THANKS: Updated
|
||||||
|
|
||||||
|
2005-03-21 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||||
|
|
||||||
|
* src/util.c (disk_buffered_write): Fix typo introduced
|
||||||
|
2005-01-11.
|
||||||
|
* src/main.c (process_args): Fixed error message
|
||||||
|
|
||||||
|
2005-01-31 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||||
|
|
||||||
|
* src/main.c (main): Remove umask(0). Fixes CAN-1999-1572.
|
||||||
|
[__TURBOC__,__EMX__]: Removed
|
||||||
|
* src/copypass.c (process_copy_pass): Set umask 0
|
||||||
|
* src/copyin.c (process_copy_in): Likewise
|
||||||
|
* src/util.c (open_archive): Use MODE_RW.
|
||||||
|
|
||||||
|
2005-01-11 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||||
|
|
||||||
|
* doc/gendocs_template: Template file for gendocs.sh.
|
||||||
|
* doc/Makefile.am: Use gendocs.sh to generate webdocs.
|
||||||
|
* doc/cpio.texi: Updated.
|
||||||
|
|
||||||
|
* src/copyin.c: Use memset instead of bzero, memmove
|
||||||
|
(or memcpy, if appropriate), instead of bcopy, and
|
||||||
|
strchr/strrchr instead of index/rindex.
|
||||||
|
* src/copypass.c: Likewise.
|
||||||
|
* src/main.c: Likewise.
|
||||||
|
* src/makepath.c: Likewise.
|
||||||
|
* src/tar.c: Likewise.
|
||||||
|
* src/util.c: Likewise.
|
||||||
|
(write_nuls_to_file): Made extern. All callers updated
|
||||||
|
|
||||||
|
* src/copyout.c: Likewise. Use write_nuls_to_file instead
|
||||||
|
of explicitely accessing zeros_512
|
||||||
|
* src/userspec.c: Likewise.
|
||||||
|
Rename isnumber to isnumber_p. Proposed by
|
||||||
|
Albert Chin
|
||||||
|
* src/extern.h (zeros_512): Removed
|
||||||
|
(write_nuls_to_file): New function
|
||||||
|
* src/global.c (zeros_512): Removed
|
||||||
|
|
||||||
|
2005-01-06 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||||
|
|
||||||
|
* bootstrap: Add 'fileblocks' gnulib module
|
||||||
|
Create paxutils.m4
|
||||||
|
* configure.ac: Call cpio_PAXUTILS
|
||||||
|
* src/main.c: Remove ifdef around setlocale
|
||||||
|
* src/mt.c: Likewise
|
||||||
|
|
||||||
|
2004-12-21 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||||
|
|
||||||
|
* configure.ac: New option --enable-mt
|
||||||
|
Check for locale.h
|
||||||
|
* doc/cpio.info: Removed
|
||||||
|
* src/mt.c (main): Use argmatch_invalid()
|
||||||
|
|
||||||
2004-12-20 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
2004-12-20 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||||
|
|
||||||
Released version 2.6. Sources up to this point are tagged
|
Released version 2.6. Sources up to this point are tagged
|
||||||
|
65
INSTALL
65
INSTALL
@ -1,8 +1,8 @@
|
|||||||
Installation Instructions
|
Installation Instructions
|
||||||
*************************
|
*************************
|
||||||
|
|
||||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free
|
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
|
||||||
Software Foundation, Inc.
|
2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is free documentation; the Free Software Foundation gives
|
This file is free documentation; the Free Software Foundation gives
|
||||||
unlimited permission to copy, distribute and modify it.
|
unlimited permission to copy, distribute and modify it.
|
||||||
@ -10,7 +10,10 @@ unlimited permission to copy, distribute and modify it.
|
|||||||
Basic Installation
|
Basic Installation
|
||||||
==================
|
==================
|
||||||
|
|
||||||
These are generic installation instructions.
|
Briefly, the shell commands `./configure; make; make install' should
|
||||||
|
configure, build, and install this package. The following
|
||||||
|
more-detailed instructions are generic; see the `README' file for
|
||||||
|
instructions specific to this package.
|
||||||
|
|
||||||
The `configure' shell script attempts to guess correct values for
|
The `configure' shell script attempts to guess correct values for
|
||||||
various system-dependent variables used during compilation. It uses
|
various system-dependent variables used during compilation. It uses
|
||||||
@ -23,9 +26,9 @@ debugging `configure').
|
|||||||
|
|
||||||
It can also use an optional file (typically called `config.cache'
|
It can also use an optional file (typically called `config.cache'
|
||||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||||
the results of its tests to speed up reconfiguring. (Caching is
|
the results of its tests to speed up reconfiguring. Caching is
|
||||||
disabled by default to prevent problems with accidental use of stale
|
disabled by default to prevent problems with accidental use of stale
|
||||||
cache files.)
|
cache files.
|
||||||
|
|
||||||
If you need to do unusual things to compile the package, please try
|
If you need to do unusual things to compile the package, please try
|
||||||
to figure out how `configure' could check whether to do them, and mail
|
to figure out how `configure' could check whether to do them, and mail
|
||||||
@ -35,20 +38,17 @@ some point `config.cache' contains results you don't want to keep, you
|
|||||||
may remove or edit it.
|
may remove or edit it.
|
||||||
|
|
||||||
The file `configure.ac' (or `configure.in') is used to create
|
The file `configure.ac' (or `configure.in') is used to create
|
||||||
`configure' by a program called `autoconf'. You only need
|
`configure' by a program called `autoconf'. You need `configure.ac' if
|
||||||
`configure.ac' if you want to change it or regenerate `configure' using
|
you want to change it or regenerate `configure' using a newer version
|
||||||
a newer version of `autoconf'.
|
of `autoconf'.
|
||||||
|
|
||||||
The simplest way to compile this package is:
|
The simplest way to compile this package is:
|
||||||
|
|
||||||
1. `cd' to the directory containing the package's source code and type
|
1. `cd' to the directory containing the package's source code and type
|
||||||
`./configure' to configure the package for your system. If you're
|
`./configure' to configure the package for your system.
|
||||||
using `csh' on an old version of System V, you might need to type
|
|
||||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
|
||||||
`configure' itself.
|
|
||||||
|
|
||||||
Running `configure' takes awhile. While running, it prints some
|
Running `configure' might take a while. While running, it prints
|
||||||
messages telling which features it is checking for.
|
some messages telling which features it is checking for.
|
||||||
|
|
||||||
2. Type `make' to compile the package.
|
2. Type `make' to compile the package.
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ details on some of the pertinent environment variables.
|
|||||||
by setting variables in the command line or in the environment. Here
|
by setting variables in the command line or in the environment. Here
|
||||||
is an example:
|
is an example:
|
||||||
|
|
||||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||||
|
|
||||||
*Note Defining Variables::, for more details.
|
*Note Defining Variables::, for more details.
|
||||||
|
|
||||||
@ -87,31 +87,29 @@ Compiling For Multiple Architectures
|
|||||||
|
|
||||||
You can compile the package for more than one kind of computer at the
|
You can compile the package for more than one kind of computer at the
|
||||||
same time, by placing the object files for each architecture in their
|
same time, by placing the object files for each architecture in their
|
||||||
own directory. To do this, you must use a version of `make' that
|
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
|
||||||
directory where you want the object files and executables to go and run
|
directory where you want the object files and executables to go and run
|
||||||
the `configure' script. `configure' automatically checks for the
|
the `configure' script. `configure' automatically checks for the
|
||||||
source code in the directory that `configure' is in and in `..'.
|
source code in the directory that `configure' is in and in `..'.
|
||||||
|
|
||||||
If you have to use a `make' that does not support the `VPATH'
|
With a non-GNU `make', it is safer to compile the package for one
|
||||||
variable, you have to compile the package for one architecture at a
|
architecture at a time in the source code directory. After you have
|
||||||
time in the source code directory. After you have installed the
|
installed the package for one architecture, use `make distclean' before
|
||||||
package for one architecture, use `make distclean' before reconfiguring
|
reconfiguring for another architecture.
|
||||||
for another architecture.
|
|
||||||
|
|
||||||
Installation Names
|
Installation Names
|
||||||
==================
|
==================
|
||||||
|
|
||||||
By default, `make install' will install the package's files in
|
By default, `make install' installs the package's commands under
|
||||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||||
installation prefix other than `/usr/local' by giving `configure' the
|
can specify an installation prefix other than `/usr/local' by giving
|
||||||
option `--prefix=PREFIX'.
|
`configure' the option `--prefix=PREFIX'.
|
||||||
|
|
||||||
You can specify separate installation prefixes for
|
You can specify separate installation prefixes for
|
||||||
architecture-specific files and architecture-independent files. If you
|
architecture-specific files and architecture-independent files. If you
|
||||||
give `configure' the option `--exec-prefix=PREFIX', the package will
|
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||||
use PREFIX as the prefix for installing programs and libraries.
|
PREFIX as the prefix for installing programs and libraries.
|
||||||
Documentation and other data files will still use the regular prefix.
|
Documentation and other data files still use the regular prefix.
|
||||||
|
|
||||||
In addition, if you use an unusual directory layout you can give
|
In addition, if you use an unusual directory layout you can give
|
||||||
options like `--bindir=DIR' to specify different values for particular
|
options like `--bindir=DIR' to specify different values for particular
|
||||||
@ -159,7 +157,7 @@ where SYSTEM can have one of these forms:
|
|||||||
need to know the machine type.
|
need to know the machine type.
|
||||||
|
|
||||||
If you are _building_ compiler tools for cross-compiling, you should
|
If you are _building_ compiler tools for cross-compiling, you should
|
||||||
use the `--target=TYPE' option to select the type of system they will
|
use the option `--target=TYPE' to select the type of system they will
|
||||||
produce code for.
|
produce code for.
|
||||||
|
|
||||||
If you want to _use_ a cross compiler, that generates code for a
|
If you want to _use_ a cross compiler, that generates code for a
|
||||||
@ -189,9 +187,14 @@ them in the `configure' command line, using `VAR=value'. For example:
|
|||||||
|
|
||||||
./configure CC=/usr/local2/bin/gcc
|
./configure CC=/usr/local2/bin/gcc
|
||||||
|
|
||||||
will cause the specified gcc to be used as the C compiler (unless it is
|
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||||
overridden in the site shell script).
|
overridden in the site shell script).
|
||||||
|
|
||||||
|
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||||
|
an Autoconf bug. Until the bug is fixed you can use this workaround:
|
||||||
|
|
||||||
|
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||||
|
|
||||||
`configure' Invocation
|
`configure' Invocation
|
||||||
======================
|
======================
|
||||||
|
|
||||||
|
38
NEWS
38
NEWS
@ -1,10 +1,36 @@
|
|||||||
GNU cpio NEWS -- history of user-visible changes. 2004-12-20
|
GNU cpio NEWS -- history of user-visible changes. 2007-06-08
|
||||||
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||||
See the end of file for copying conditions.
|
See the end of file for copying conditions.
|
||||||
|
|
||||||
Please send cpio bug reports to <bug-cpio@gnu.org>.
|
Please send cpio bug reports to <bug-cpio@gnu.org>.
|
||||||
|
|
||||||
Version 2.6
|
Version 2.8 - Sergey Poznyakoff, 2007-06-08
|
||||||
|
|
||||||
|
* Option --owner can be used in copy-out mode, allowing to uniformly override
|
||||||
|
ownership of the files being added to the archive.
|
||||||
|
|
||||||
|
* Bugfixes:
|
||||||
|
|
||||||
|
** Symlinks were handled incorrectly in copy-out mode.
|
||||||
|
** Fix handling of large files.
|
||||||
|
** Fix setting the file permissions in copy-out mode.
|
||||||
|
** Fix CAN-2005-1111
|
||||||
|
|
||||||
|
|
||||||
|
Version 2.7 - Sergey Poznyakoff, 2006-10-21
|
||||||
|
|
||||||
|
* Improved error checking and diagnostics
|
||||||
|
|
||||||
|
* Bugfixes
|
||||||
|
** Fixed CAN-1999-1572
|
||||||
|
** Allow to use --sparse in both copy-in and copy-pass.
|
||||||
|
** Fix bug that eventually caused copying out the same hard-linked
|
||||||
|
file several times to archive.
|
||||||
|
** Fix several LFS-related issues.
|
||||||
|
** Fix Debian bug 335580.
|
||||||
|
|
||||||
|
|
||||||
|
Version 2.6 - Sergey Poznyakoff, 2004-12-20
|
||||||
|
|
||||||
* Added NLS support
|
* Added NLS support
|
||||||
|
|
||||||
@ -107,7 +133,7 @@ multiple links and of multi-volume archives on floppy disks.
|
|||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
Copyright information:
|
Copyright information:
|
||||||
|
|
||||||
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||||
|
|
||||||
Permission is granted to anyone to make or distribute verbatim copies
|
Permission is granted to anyone to make or distribute verbatim copies
|
||||||
of this document as received, in any medium, provided that the
|
of this document as received, in any medium, provided that the
|
||||||
@ -122,4 +148,8 @@ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
|||||||
Local variables:
|
Local variables:
|
||||||
mode: outline
|
mode: outline
|
||||||
paragraph-separate: "[ ]*$"
|
paragraph-separate: "[ ]*$"
|
||||||
|
eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
time-stamp-start: "changes. "
|
||||||
|
time-stamp-format: "%:y-%02m-%02d"
|
||||||
|
time-stamp-end: "\n"
|
||||||
end:
|
end:
|
||||||
|
8
THANKS
8
THANKS
@ -9,6 +9,12 @@ The following is a list of people who contributed to GNU cpio by
|
|||||||
reporting problems, suggesting various improvements or submitting actual
|
reporting problems, suggesting various improvements or submitting actual
|
||||||
code. Help us keep it complete and exempt of errors.
|
code. Help us keep it complete and exempt of errors.
|
||||||
|
|
||||||
|
Benigno B. Junior <bbj@gentux.com.br>
|
||||||
|
Brian Mays <brian@debian.org>
|
||||||
|
Dmitry V. Levin <ldv@altlinux.org>
|
||||||
|
Jim Castleberry <bhg9aha02@sneakemail.com>
|
||||||
|
Holger Fleischmann <holger_fleischmann@mra.man.de>
|
||||||
Matthew Braithwaite <mab@cnet.com>
|
Matthew Braithwaite <mab@cnet.com>
|
||||||
|
Mike Frysinger <vapier@gentoo.org>
|
||||||
Mitsuru Chinen <mchinen@yamato.ibm.com>
|
Mitsuru Chinen <mchinen@yamato.ibm.com>
|
||||||
Holger Fleischmann <holger_fleischmann@mra.man.de>
|
Peter Vrabec <pvrabec@redhat.com>
|
||||||
|
357
TODO
357
TODO
@ -1,54 +1,21 @@
|
|||||||
Following is the list of cpio-related reports to bug-gnu-utils.
|
Following is the list of cpio-related reports to bug-gnu-utils.
|
||||||
Many of them appear to be fixed, but quite a number of them is
|
Many of them appear to be fixed, but quite a number of them is
|
||||||
probably still waiting for being handled. The list is sorted
|
probably still waiting for being handled. The list is divided
|
||||||
in reverse chronological order.
|
into two parts, the messages are in somehow arbitrary order.
|
||||||
|
|
||||||
4. copyin.c cpio probably questions/rfc (score: 35)
|
* Bug reports
|
||||||
Author: Grzegorz Jaskiewicz <gj@pointblue.com.pl>
|
--------------
|
||||||
Date: Tue, 24 Jun 2003 17:12:45 +0100
|
|
||||||
Hi! I am currently working on module that (in GNU software)
|
** cpio -d bug (fwd) (score: 47)
|
||||||
will be able to read/write cpio format (only ascii). Thus i am
|
Author: Christian Smith <csmith@micromuse.com>
|
||||||
separating some of cpio structures into libcpio. I've been
|
Date: Wed, 14 Nov 2001 02:06:46 +0000 (GMT)
|
||||||
going through cop
|
This was bounced from bug-cpio@bogus.example.com I guess that
|
||||||
/archive/html/bug-gnu-utils/2003-06/msg00422.html (5,430 bytes)
|
isn't set up yet. -- /"\ \ / ASCII RIBBON CAMPAIGN - AGAINST
|
||||||
|
HTML MAIL X - AGAINST MS ATTACHMENTS / \ $ cpio --version GNU
|
||||||
|
cpio version 2
|
||||||
|
/archive/html/bug-gnu-utils/2001-11/msg00170.html (4,548 bytes)
|
||||||
|
|
||||||
5. RE: Problem when building on HP-UX 11i(11.11) (score: 4)
|
** bug in cpio with tapechange in copy-in-mode (score: 34)
|
||||||
Author: "Leon Strydom" <leon.strydom@tasima.co.za>
|
|
||||||
Date: Thu, 13 Mar 2003 09:10:02 +0200
|
|
||||||
Hi Bob, I got it to compile, thanks. The reason why I had to
|
|
||||||
try GNU-Tar is because of the 2GB file size limit problems:
|
|
||||||
Here are the errors I got: With TAR(hp-ux 11i tar): CMD: tar
|
|
||||||
cvf backup.tar /a
|
|
||||||
/archive/html/bug-gnu-utils/2003-03/msg00106.html (5,191 bytes)
|
|
||||||
|
|
||||||
6. cpio - large file support (score: 35)
|
|
||||||
Author: "Keith Ansell" <keitha@edp.fastfreenet.com>
|
|
||||||
Date: Tue, 4 Mar 2003 16:24:37 -0000
|
|
||||||
Can you help. I need to archive a large database, this will
|
|
||||||
create a cpio file greater than 2 Gigabytes. Have you added
|
|
||||||
large file support to the build of cpio. Regards Keith
|
|
||||||
Ansell.....
|
|
||||||
/archive/html/bug-gnu-utils/2003-03/msg00024.html (4,329 bytes)
|
|
||||||
|
|
||||||
7. cpio-2.5 typos (score: 36)
|
|
||||||
Author: Thomas Klausner <wiz@danbala.ifoer.tuwien.ac.at>
|
|
||||||
Date: Sat, 21 Dec 2002 23:53:38 +0100
|
|
||||||
In cpio-2.5, in cpio.texi (and thus cpio.1) and main.c the word
|
|
||||||
'compatibility' is misspelled as 'compatability'. Please fix,
|
|
||||||
thanks. Thomas -- Thomas Klausner - wiz@bogus.example.com What
|
|
||||||
is wanted
|
|
||||||
/archive/html/bug-gnu-utils/2002-12/msg00200.html (3,783 bytes)
|
|
||||||
|
|
||||||
9. Re: bug in cpio with tapechange in copy-in-mode (score: 46)
|
|
||||||
Author: Paul Eggert <eggert@twinsun.com>
|
|
||||||
Date: Mon, 5 Aug 2002 12:28:33 -0700 (PDT)
|
|
||||||
Thanks for your bug report. Can you please verify that the bug
|
|
||||||
still exists in the latest CPIO version
|
|
||||||
<ftp://ftp.gnu.org/gnu/cpio/cpio-2.5.tar.gz>, and if so, please
|
|
||||||
send a patch to <bug-cpio@bogus.
|
|
||||||
/archive/html/bug-gnu-utils/2002-08/msg00127.html (4,275 bytes)
|
|
||||||
|
|
||||||
10. bug in cpio with tapechange in copy-in-mode (score: 34)
|
|
||||||
Author: Bernd =?ISO-8859-1?Q?Sch=FCler?=
|
Author: Bernd =?ISO-8859-1?Q?Sch=FCler?=
|
||||||
<b.schueler@eckert-buerotechnik.de>
|
<b.schueler@eckert-buerotechnik.de>
|
||||||
Date: 05 Aug 2002 18:37:56 +0200
|
Date: 05 Aug 2002 18:37:56 +0200
|
||||||
@ -58,15 +25,7 @@ in reverse chronological order.
|
|||||||
sure, if the pr
|
sure, if the pr
|
||||||
/archive/html/bug-gnu-utils/2002-08/msg00122.html (4,518 bytes)
|
/archive/html/bug-gnu-utils/2002-08/msg00122.html (4,518 bytes)
|
||||||
|
|
||||||
11. Re: CPIO Bug ? (score: 36)
|
** Re: bug in cpio? (score: 40)
|
||||||
Author: Albert Chin <bug-gnu-utils@lists.thewrittenword.com>
|
|
||||||
Date: Thu, 4 Jul 2002 19:31:04 -0500
|
|
||||||
I think the default CPIO format understands only 16-bit inodes.
|
|
||||||
Look at the -H option. '-H newc' should work better for you. --
|
|
||||||
albert chin (china@bogus.example.com)
|
|
||||||
/archive/html/bug-gnu-utils/2002-07/msg00091.html (4,286 bytes)
|
|
||||||
|
|
||||||
14. Re: bug in cpio? (score: 40)
|
|
||||||
Author: kasal@matsrv.math.cas.cz (Stepan Kasal)
|
Author: kasal@matsrv.math.cas.cz (Stepan Kasal)
|
||||||
Date: Thu, 13 Jun 2002 07:44:14 +0000 (UTC)
|
Date: Thu, 13 Jun 2002 07:44:14 +0000 (UTC)
|
||||||
Hallo, the following option should help: -d, --make-directories
|
Hallo, the following option should help: -d, --make-directories
|
||||||
@ -75,44 +34,7 @@ in reverse chronological order.
|
|||||||
/home/kasal/tmp/db
|
/home/kasal/tmp/db
|
||||||
/archive/html/bug-gnu-utils/2002-06/msg00306.html (4,862 bytes)
|
/archive/html/bug-gnu-utils/2002-06/msg00306.html (4,862 bytes)
|
||||||
|
|
||||||
15. bug in cpio? (score: 34)
|
** cpio 2.4.2 bug? (score: 40)
|
||||||
Author: "Jeff Holt" <jeff.holt@hotsos.com>
|
|
||||||
Date: Wed, 12 Jun 2002 14:07:59 -0500
|
|
||||||
According to the man page, I should be able to extract an
|
|
||||||
absolute pathname from an archive and have the file created
|
|
||||||
relative to the current directory (by removing the leading
|
|
||||||
‘/’).<o:p>
|
|
||||||
/archive/html/bug-gnu-utils/2002-06/msg00296.html (5,331 bytes)
|
|
||||||
|
|
||||||
16. CPIO Bug ? (score: 35)
|
|
||||||
Author: =?iso-8859-1?Q?Gr=E9goire_Fiot?=
|
|
||||||
<gfiot@eiffageconstruction.fr>
|
|
||||||
Date: Tue, 14 May 2002 17:01:18 +0200
|
|
||||||
Hello, We ve got a problem here using cpio: many "troncating
|
|
||||||
inode number" appear during the process: cpio -ocv Is that a
|
|
||||||
real problem? Does it corrupt files? Well.. what does that
|
|
||||||
mean? We have look
|
|
||||||
/archive/html/bug-gnu-utils/2002-05/msg00333.html (3,855 bytes)
|
|
||||||
|
|
||||||
23. [cpio texinfo] typo (score: 2)
|
|
||||||
Author: fabrice bauzac <fabrice.bauzac@wanadoo.fr>
|
|
||||||
Date: Tue, 7 May 2002 16:37:28 +0200
|
|
||||||
Good afternoon, There is a typo in the Texinfo documentation of
|
|
||||||
GNU cpio, node "Copy-in mode": [--format=format]
|
|
||||||
[--owner=[user][:.][group]] [--no- preserve-owner]
|
|
||||||
[--message=message] [--help] [--ver
|
|
||||||
/archive/html/bug-gnu-utils/2002-05/msg00153.html (4,040 bytes)
|
|
||||||
|
|
||||||
26. cpio: memory exhausted (score: 43)
|
|
||||||
Author: Thomas McLaughlin <tamm@scotlegal.com>
|
|
||||||
Date: Thu, 18 Apr 2002 09:51:18 +0100
|
|
||||||
This is probably not the place for my query, but I have
|
|
||||||
exhausted other avenues and would be glad of some help. I can't
|
|
||||||
work out what's going on with my nightly cpio backup. If I do:
|
|
||||||
cd / find . -pri
|
|
||||||
/archive/html/bug-gnu-utils/2002-04/msg00406.html (4,988 bytes)
|
|
||||||
|
|
||||||
30. cpio 2.4.2 bug? (score: 40)
|
|
||||||
Author: "H.J. Thomassen" <H.J.Thomassen@ATComputing.nl>
|
Author: "H.J. Thomassen" <H.J.Thomassen@ATComputing.nl>
|
||||||
Date: Thu, 10 Jan 2002 18:09:10 +0100 (CET)
|
Date: Thu, 10 Jan 2002 18:09:10 +0100 (CET)
|
||||||
Hello, We use GNU-cpio 2.4.2 and have the following problem:
|
Hello, We use GNU-cpio 2.4.2 and have the following problem:
|
||||||
@ -120,62 +42,9 @@ in reverse chronological order.
|
|||||||
hardlinks to the same i-node. I make a crc-cpio archive with
|
hardlinks to the same i-node. I make a crc-cpio archive with
|
||||||
both files; th
|
both files; th
|
||||||
/archive/html/bug-gnu-utils/2002-01/msg00161.html (5,624 bytes)
|
/archive/html/bug-gnu-utils/2002-01/msg00161.html (5,624 bytes)
|
||||||
|
|
||||||
32. GNU cpio suggestion (score: 42)
|
** These two seem to be related:
|
||||||
Author: "H.J.Thomassen" <hjt@ATComputing.nl>
|
*** cpio copy-in and multiply-linked files (score: 35)
|
||||||
Date: Mon, 17 Dec 2001 11:27:11 +0100
|
|
||||||
Re: suggestion for GNU-cpio extension (plus reference
|
|
||||||
implementation) We use cpio for our backup purposes. The backup
|
|
||||||
is started automatically in the middle of the night. To chase
|
|
||||||
away all users we d
|
|
||||||
/archive/html/bug-gnu-utils/2001-12/msg00244.html (7,474 bytes)
|
|
||||||
|
|
||||||
35. GNU cpio compile problem (score: 34)
|
|
||||||
Author: Daniel Savard <dsavard@videotron.ca>
|
|
||||||
Date: Wed, 14 Nov 2001 12:43:11 -0500
|
|
||||||
Hi, I am trying to make the GNU cpio utility (version 2.4.2)
|
|
||||||
using the gcc 3.0.2 compiler. The make failed on the userspec.c
|
|
||||||
file compilation. I then tried to compile with gcc 2.95.3 with
|
|
||||||
the followi
|
|
||||||
/archive/html/bug-gnu-utils/2001-11/msg00180.html (5,518 bytes)
|
|
||||||
|
|
||||||
36. cpio -d bug (fwd) (score: 47)
|
|
||||||
Author: Christian Smith <csmith@micromuse.com>
|
|
||||||
Date: Wed, 14 Nov 2001 02:06:46 +0000 (GMT)
|
|
||||||
This was bounced from bug-cpio@bogus.example.com I guess that
|
|
||||||
isn't set up yet. -- /"\ \ / ASCII RIBBON CAMPAIGN - AGAINST
|
|
||||||
HTML MAIL X - AGAINST MS ATTACHMENTS / \ $ cpio --version GNU
|
|
||||||
cpio version 2
|
|
||||||
/archive/html/bug-gnu-utils/2001-11/msg00170.html (4,548 bytes)
|
|
||||||
|
|
||||||
38. [cpio] man page enhancement: a Example section ? (score: 5)
|
|
||||||
Author: Yannick Patois <patois@calvix.org>
|
|
||||||
Date: Wed, 24 Oct 2001 12:48:33 +0200 (CEST)
|
|
||||||
Hello, I seldom use cpio (as I think many people) and only had
|
|
||||||
to use it once or twice. IMHA, would be good to have a small
|
|
||||||
section with an example of most often performed actions
|
|
||||||
(creating an archiv
|
|
||||||
/archive/html/bug-gnu-utils/2001-10/msg00270.html (4,336 bytes)
|
|
||||||
|
|
||||||
39. Patch to cpio to enable verbose *skipping* of files (score: 40)
|
|
||||||
Author: Tomas Pospisek <tpo@sourcepole.ch>
|
|
||||||
Date: Mon, 8 Oct 2001 13:54:14 +0200 (CEST)
|
|
||||||
This patch enables cpio to be verbose about the files that it
|
|
||||||
does not copy, which is very handy for seeing cpio's progress
|
|
||||||
through a tape or simply for debuging. The patch along with a
|
|
||||||
Debian packag
|
|
||||||
/archive/html/bug-gnu-utils/2001-10/msg00083.html (4,548 bytes)
|
|
||||||
|
|
||||||
40. cpio-2.4.2 patch (score: 39)
|
|
||||||
Author: Alex Efros <powerman@sky.net.ua>
|
|
||||||
Date: Wed, 29 Aug 2001 07:36:31 +0300 (EEST)
|
|
||||||
Hi. Linux-2.4.9, GCC-3.0, GLIBC-2.2.4, cpio-2.4.2. Compile-time
|
|
||||||
errors: --cut-- gcc -c -DRETSIGTYPE=void -DHAVE_SYS_MTIO_H=1
|
|
||||||
-DHAVE_NETDB_H=1 -DSTDC_HEADERS=1 -DHAVE_UNISTD_H=1
|
|
||||||
-DHAVE_STRING_H=1 -DHA
|
|
||||||
/archive/html/bug-gnu-utils/2001-08/msg00264.html (5,259 bytes)
|
|
||||||
|
|
||||||
41. cpio copy-in and multiply-linked files (score: 35)
|
|
||||||
Author: Chris Jaeger <cjaeger@ensim.com>
|
Author: Chris Jaeger <cjaeger@ensim.com>
|
||||||
Date: Tue, 07 Aug 2001 23:46:04 -0700
|
Date: Tue, 07 Aug 2001 23:46:04 -0700
|
||||||
Hi, I was wondering whether it was a bug or a feature that GNU
|
Hi, I was wondering whether it was a bug or a feature that GNU
|
||||||
@ -184,14 +53,7 @@ in reverse chronological order.
|
|||||||
due to th
|
due to th
|
||||||
/archive/html/bug-gnu-utils/2001-08/msg00074.html (4,142 bytes)
|
/archive/html/bug-gnu-utils/2001-08/msg00074.html (4,142 bytes)
|
||||||
|
|
||||||
42. Re: minor problems with slackware-current (score: 7)
|
*** (no subject) (score: 2)
|
||||||
Author: Cezary Sliwa <sliwa@cft.edu.pl>
|
|
||||||
Date: Wed, 1 Aug 2001 10:43:37 +0200
|
|
||||||
"cpio --sparse" corrupts data. A fix attached. C.S. Attachment:
|
|
||||||
cpio-2.4.2-sparse.diff Description: Text document
|
|
||||||
/archive/html/bug-gnu-utils/2001-08/msg00000.html (3,989 bytes)
|
|
||||||
|
|
||||||
43. (no subject) (score: 2)
|
|
||||||
Author: brian@debian.org (Brian Mays)
|
Author: brian@debian.org (Brian Mays)
|
||||||
Date: Sat, 07 Jul 2001 16:35:13 -0400
|
Date: Sat, 07 Jul 2001 16:35:13 -0400
|
||||||
When hard-linked files (along with many other files) are
|
When hard-linked files (along with many other files) are
|
||||||
@ -200,69 +62,24 @@ in reverse chronological order.
|
|||||||
the same set of fil
|
the same set of fil
|
||||||
/archive/html/bug-gnu-utils/2001-07/msg00080.html (5,666 bytes)
|
/archive/html/bug-gnu-utils/2001-07/msg00080.html (5,666 bytes)
|
||||||
|
|
||||||
44. gnu cpio and files over 2G (score: 37)
|
** These too:
|
||||||
Author: J.S.Peatfield@damtp.cam.ac.uk
|
|
||||||
Date: Wed, 2 May 2001 06:28:18 +0100
|
*** Re: minor problems with slackware-current (score: 7)
|
||||||
As an increasing number of opertaing systems now support files
|
Author: Cezary Sliwa <sliwa@cft.edu.pl>
|
||||||
over 2G I took a look at the cpio (2.4.2) source to see how
|
Date: Wed, 1 Aug 2001 10:43:37 +0200
|
||||||
hard it would be to make it cope, and was slightly shocked at
|
"cpio --sparse" corrupts data. A fix attached. C.S. Attachment:
|
||||||
the number of
|
cpio-2.4.2-sparse.diff Description: Text document
|
||||||
/archive/html/bug-gnu-utils/2001-05/msg00010.html (4,802 bytes)
|
/archive/html/bug-gnu-utils/2001-08/msg00000.html (3,989 bytes)
|
||||||
|
|
||||||
45. cpio suggestion + patch (score: 38)
|
*** cpio --sparse (score: 34)
|
||||||
Author: Taylor Gautier <tgautier@s8.com>
|
|
||||||
Date: Fri, 20 Apr 2001 09:40:05 -0700
|
|
||||||
I have a suggestion for cpio. The suggestion is to make it copy
|
|
||||||
files into a temporary name and then rename the file as the
|
|
||||||
last operation. Since UNIX filesystems are supposed to
|
|
||||||
gaurantee atomicity
|
|
||||||
/archive/html/bug-gnu-utils/2001-04/msg00169.html (10,674
|
|
||||||
bytes)
|
|
||||||
|
|
||||||
46. [cpio 2.4.2] rmt build fails (score: 8)
|
|
||||||
Author: Gert <n8w8@n8w8.wox.org>
|
|
||||||
Date: Thu, 29 Mar 2001 21:28:52 +0200 (CEST)
|
|
||||||
Hi, The cpio 2.4.2 rmt tool fails to build on my system. I run
|
|
||||||
the following software: - Linux 2.4.2 - GCC 2.95.2 - GNU Make
|
|
||||||
3.79.1 - GNU ld 2.10 (with BFD 2.10) - glibc 2.1.3 The build
|
|
||||||
fails like th
|
|
||||||
/archive/html/bug-gnu-utils/2001-03/msg00262.html (5,498 bytes)
|
|
||||||
|
|
||||||
47. cpio --sparse (score: 34)
|
|
||||||
Author: Cezary Sliwa <sliwa@cft.edu.pl>
|
Author: Cezary Sliwa <sliwa@cft.edu.pl>
|
||||||
Date: Mon, 26 Mar 2001 10:43:34 +0200 (CEST)
|
Date: Mon, 26 Mar 2001 10:43:34 +0200 (CEST)
|
||||||
the '--sparse' option of gnu cpio causes data corruption
|
the '--sparse' option of gnu cpio causes data corruption
|
||||||
(blocks of zeros are lost or appended to other files). C.S.
|
(blocks of zeros are lost or appended to other files). C.S.
|
||||||
/archive/html/bug-gnu-utils/2001-03/msg00235.html (3,671 bytes)
|
/archive/html/bug-gnu-utils/2001-03/msg00235.html (3,671 bytes)
|
||||||
|
|
||||||
49. Re: bug with gnu cpio 2.4.2 (score: 38)
|
** And these too
|
||||||
Author: Hans-Bernhard Broeker <broeker@physik.rwth-aachen.de>
|
*** cpio-2.4.2: data corruption bug (score: 35)
|
||||||
Date: 6 Mar 2001 15:19:34 GMT
|
|
||||||
This would happen if cpio want to do any user interaction (ask
|
|
||||||
for the next tape cartridge, because the current one is full,
|
|
||||||
e.g.). Cron jobs don't have access to a terminal (/dev/tty), so
|
|
||||||
this will
|
|
||||||
/archive/html/bug-gnu-utils/2001-03/msg00029.html (5,062 bytes)
|
|
||||||
|
|
||||||
50. bug with gnu cpio 2.4.2 (score: 37)
|
|
||||||
Author: dominique.bieber@sagem.com
|
|
||||||
Date: Tue, 6 Mar 2001 12:27:14 +0100
|
|
||||||
Hi, I have a problem using cpio with a Red Hat 6.2 whith a
|
|
||||||
2.2.14-5.0smp kernel. The backup device is a HP DAT DDS4 20/40
|
|
||||||
with the right cartridge. The cpio is launched by the cron.
|
|
||||||
During the backup
|
|
||||||
/archive/html/bug-gnu-utils/2001-03/msg00024.html (4,315 bytes)
|
|
||||||
|
|
||||||
52. [PATCH] cpio 2.4.2 does not compile with libc 2.2, gcc 2.95
|
|
||||||
(score: 38)
|
|
||||||
Author: "John Fremlin" <chief@bandits.org>
|
|
||||||
Date: 11 Feb 2001 22:19:09 +0000
|
|
||||||
In fact it violates the GNU coding standards by declaring stuff
|
|
||||||
when it shouldn't. Tsk, tsk. Attachment: cpio-2.4.2-build.patch
|
|
||||||
Description: Text Data -- http://www.penguinpowered.com/~vii
|
|
||||||
/archive/html/bug-gnu-utils/2001-02/msg00065.html (4,169 bytes)
|
|
||||||
|
|
||||||
53. cpio-2.4.2: data corruption bug (score: 35)
|
|
||||||
Author: Todd Kelley <toddk@oeone.com>
|
Author: Todd Kelley <toddk@oeone.com>
|
||||||
Date: Fri, 09 Feb 2001 17:00:06 -0500
|
Date: Fri, 09 Feb 2001 17:00:06 -0500
|
||||||
Hello, Recently at OEone we fixed a bug in GNU cpio-2.4.2: When
|
Hello, Recently at OEone we fixed a bug in GNU cpio-2.4.2: When
|
||||||
@ -271,7 +88,16 @@ in reverse chronological order.
|
|||||||
corrupted. The crc do
|
corrupted. The crc do
|
||||||
/archive/html/bug-gnu-utils/2001-02/msg00062.html (4,297 bytes)
|
/archive/html/bug-gnu-utils/2001-02/msg00062.html (4,297 bytes)
|
||||||
|
|
||||||
54. cpio 2.4.2 unconditionally takes the tape drive offline (score:
|
*** cpio pass-through can corrupt files (score: 36)
|
||||||
|
Author: "Parrott, Jeff" <Jeff.Parrott@sea.siemens.com>
|
||||||
|
Date: Mon, 16 Oct 2000 13:32:57 -0400
|
||||||
|
I have seen corrupted files as a result of using the
|
||||||
|
pass-through option in cpio. The corruption occurs when
|
||||||
|
active/in-use (and growing) files are being copied. The problem
|
||||||
|
is that the file size has
|
||||||
|
/archive/html/bug-gnu-utils/2000-10/msg00087.html (4,974 bytes)
|
||||||
|
|
||||||
|
** cpio 2.4.2 unconditionally takes the tape drive offline (score:
|
||||||
39)
|
39)
|
||||||
Author: Scott Larson <scowl@plaza.ds.adp.com>
|
Author: Scott Larson <scowl@plaza.ds.adp.com>
|
||||||
Date: Thu, 11 Jan 2001 13:15:52 -0800
|
Date: Thu, 11 Jan 2001 13:15:52 -0800
|
||||||
@ -281,7 +107,7 @@ in reverse chronological order.
|
|||||||
tape) after rea
|
tape) after rea
|
||||||
/archive/html/bug-gnu-utils/2001-01/msg00087.html (4,264 bytes)
|
/archive/html/bug-gnu-utils/2001-01/msg00087.html (4,264 bytes)
|
||||||
|
|
||||||
55. cpio -t can see international filenames, find -ls also suffers
|
** cpio -t can see international filenames, find -ls also suffers
|
||||||
(score: 35)
|
(score: 35)
|
||||||
Author: "Dan Jacobson" <jidanni@kimo.FiXcomTHiS.tw>
|
Author: "Dan Jacobson" <jidanni@kimo.FiXcomTHiS.tw>
|
||||||
Date: Tue, 26 Dec 2000 07:38:53 +0800
|
Date: Tue, 26 Dec 2000 07:38:53 +0800
|
||||||
@ -291,66 +117,43 @@ in reverse chronological order.
|
|||||||
http://www.geocities.com/jidanni
|
http://www.geocities.com/jidanni
|
||||||
/archive/html/bug-gnu-utils/2000-12/msg00143.html (4,084 bytes)
|
/archive/html/bug-gnu-utils/2000-12/msg00143.html (4,084 bytes)
|
||||||
|
|
||||||
56. cpio-2.4.2 compilation problems (score: 34)
|
* Suggestions
|
||||||
Author: Thomas =?iso-8859-1?q?K=F6ller?= <tkoeller@gmx.net>
|
-------------
|
||||||
Date: Wed, 20 Dec 2000 02:50:24 +0100
|
|
||||||
I encountered several problems building cpio-2.4.2. I am
|
** GNU cpio suggestion (score: 42)
|
||||||
running linux-2.2.17, glibc-2.1.3 and gcc 2.95.2. The errors I
|
Author: "H.J.Thomassen" <hjt@ATComputing.nl>
|
||||||
received were mostly due to the source files re-declaring
|
Date: Mon, 17 Dec 2001 11:27:11 +0100
|
||||||
things unconditionall
|
Re: suggestion for GNU-cpio extension (plus reference
|
||||||
/archive/html/bug-gnu-utils/2000-12/msg00109.html (5,782 bytes)
|
implementation) We use cpio for our backup purposes. The backup
|
||||||
|
is started automatically in the middle of the night. To chase
|
||||||
|
away all users we d
|
||||||
|
/archive/html/bug-gnu-utils/2001-12/msg00244.html (7,474 bytes)
|
||||||
|
|
||||||
58. cpio-2.4.2 & glibc-2.* (score: 46)
|
** cpio suggestion + patch (score: 38)
|
||||||
Author: Florian Wunderlich <fwunderlich@devbrain.de>
|
Author: Taylor Gautier <tgautier@s8.com>
|
||||||
Date: Mon, 18 Dec 2000 16:25:00 +0100
|
Date: Fri, 20 Apr 2001 09:40:05 -0700
|
||||||
I still do not see a new version of cpio or at least extra
|
I have a suggestion for cpio. The suggestion is to make it copy
|
||||||
patches that fix it so it works with the glibc. Thus, here is a
|
files into a temporary name and then rename the file as the
|
||||||
simple patch to make it compile with glibc: diff -u
|
last operation. Since UNIX filesystems are supposed to
|
||||||
cpio-2.4.2-old/rmt.c cpi
|
gaurantee atomicity
|
||||||
/archive/html/bug-gnu-utils/2000-12/msg00098.html (4,846 bytes)
|
/archive/html/bug-gnu-utils/2001-04/msg00169.html (10,674
|
||||||
|
bytes)
|
||||||
|
|
||||||
60. cpio-2.4.2 signed-unsigned int disagreement with malloc (score:
|
** [cpio] man page enhancement: a Example section ? (score: 5)
|
||||||
39)
|
Author: Yannick Patois <patois@calvix.org>
|
||||||
Author: Antonomasia <ant@notatla.demon.co.uk>
|
Date: Wed, 24 Oct 2001 12:48:33 +0200 (CEST)
|
||||||
Date: Mon, 27 Nov 2000 07:05:01 GMT
|
Hello, I seldom use cpio (as I think many people) and only had
|
||||||
copyin.c: 534 link_name = (char *) xmalloc ((unsigned int)
|
to use it once or twice. IMHA, would be good to have a small
|
||||||
file_hdr.c_filesize + 1); 535 link_name[file_hdr.c_filesize] =
|
section with an example of most often performed actions
|
||||||
'\0'; file_hdr.c_filesize can be a large negative number as
|
(creating an archiv
|
||||||
seen here then th
|
/archive/html/bug-gnu-utils/2001-10/msg00270.html (4,336 bytes)
|
||||||
/archive/html/bug-gnu-utils/2000-11/msg00171.html (4,718 bytes)
|
|
||||||
|
** Patch to cpio to enable verbose *skipping* of files (score: 40)
|
||||||
|
Author: Tomas Pospisek <tpo@sourcepole.ch>
|
||||||
|
Date: Mon, 8 Oct 2001 13:54:14 +0200 (CEST)
|
||||||
|
This patch enables cpio to be verbose about the files that it
|
||||||
|
does not copy, which is very handy for seeing cpio's progress
|
||||||
|
through a tape or simply for debuging. The patch along with a
|
||||||
|
Debian packag
|
||||||
|
/archive/html/bug-gnu-utils/2001-10/msg00083.html (4,548 bytes)
|
||||||
|
|
||||||
61. gnu CPIO (score: 38)
|
|
||||||
Author: Clark Cooper <Clark.Cooper@vc3.com>
|
|
||||||
Date: Mon, 13 Nov 2000 13:21:07 -0500 (EST)
|
|
||||||
The gnu version of CPIO appears to send all output to stderr.
|
|
||||||
Take for instance a need to have the list of files copied and
|
|
||||||
any errors separated as should be produced by the following:
|
|
||||||
find . -print
|
|
||||||
/archive/html/bug-gnu-utils/2000-11/msg00089.html (3,903 bytes)
|
|
||||||
|
|
||||||
62. Desire enhancement to GNU cpio 2.4.2 (score: 35)
|
|
||||||
Author: Dave Dykstra <dwd@bell-labs.com>
|
|
||||||
Date: Mon, 13 Nov 2000 10:24:56 -0600
|
|
||||||
I have a new GNU/Linux system with large disks on which I need
|
|
||||||
to generate cpio files for many different systems including
|
|
||||||
older ones that don't support the "newc" format, only the "odc"
|
|
||||||
format. The
|
|
||||||
/archive/html/bug-gnu-utils/2000-11/msg00087.html (5,115 bytes)
|
|
||||||
|
|
||||||
65. cpio pass-through can corrupt files (score: 36)
|
|
||||||
Author: "Parrott, Jeff" <Jeff.Parrott@sea.siemens.com>
|
|
||||||
Date: Mon, 16 Oct 2000 13:32:57 -0400
|
|
||||||
I have seen corrupted files as a result of using the
|
|
||||||
pass-through option in cpio. The corruption occurs when
|
|
||||||
active/in-use (and growing) files are being copied. The problem
|
|
||||||
is that the file size has
|
|
||||||
/archive/html/bug-gnu-utils/2000-10/msg00087.html (4,974 bytes)
|
|
||||||
|
|
||||||
66. [Bug-gnu-utils] A small problem with cpio (score: 36)
|
|
||||||
Author: Chris Hall <Chris@clapham.org>
|
|
||||||
Date: Fri, 15 Sep 2000 11:05:56 +0100
|
|
||||||
Hi, I'm running cpio 2.4.2 on AIX 4.3.3 and have a problem with
|
|
||||||
very large files, I get this output when running the command: $
|
|
||||||
ls -l total 2867988 drwxrwxrwx 2 root sys 512 Sep 14 17:05
|
|
||||||
chris/ -rw-r
|
|
||||||
/archive/html/bug-gnu-utils/2000-09/msg00004.html (4,481 bytes)
|
|
||||||
|
317
doc/cpio.texi
317
doc/cpio.texi
@ -3,94 +3,70 @@
|
|||||||
@setfilename cpio.info
|
@setfilename cpio.info
|
||||||
@settitle cpio
|
@settitle cpio
|
||||||
@setchapternewpage off
|
@setchapternewpage off
|
||||||
@set VERSION GNU cpio 2.5
|
|
||||||
@set RELEASEDATE June 2002
|
|
||||||
@c %**end of header
|
@c %**end of header
|
||||||
|
|
||||||
@ifinfo
|
@dircategory Archiving
|
||||||
@format
|
@direntry
|
||||||
START-INFO-DIR-ENTRY
|
* Cpio: (cpio). Copy-in-copy-out archiver to tape or disk.
|
||||||
* cpio: (cpio). Making tape (or disk) archives.
|
@end direntry
|
||||||
END-INFO-DIR-ENTRY
|
|
||||||
@end format
|
|
||||||
@end ifinfo
|
|
||||||
|
|
||||||
@ifinfo
|
@include version.texi
|
||||||
This file documents @value{VERSION}.
|
|
||||||
|
|
||||||
Copyright (C) 1995, 2001, 2002 Free Software Foundation, Inc.
|
@copying
|
||||||
|
This manual documents GNU cpio (version @value{VERSION}, @value{UPDATED}).
|
||||||
|
|
||||||
Permission is granted to make and distribute verbatim copies of
|
Copyright @copyright{} 1995, 2001, 2002, 2004 Free Software Foundation, Inc.
|
||||||
this manual provided the copyright notice and this permission notice
|
@sp 1
|
||||||
are preserved on all copies.
|
@quotation
|
||||||
|
Permission is granted to copy, distribute and/or modify this document
|
||||||
@ignore
|
under the terms of the GNU Free Documentation License, Version 1.2 or
|
||||||
Permission is granted to process this file through TeX and print the
|
any later version published by the Free Software Foundation; with no
|
||||||
results, provided the printed document carries copying permission
|
Invariant Sections, with the Front-Cover texts being ``A GNU Manual'',
|
||||||
notice identical to this one except for the removal of this paragraph
|
and with the Back-Cover Texts as in (a) below. A copy of the license
|
||||||
|
is included in the section entitled ``GNU Free Documentation License''.
|
||||||
|
|
||||||
@end ignore
|
|
||||||
Permission is granted to copy and distribute modified versions of this
|
|
||||||
manual under the conditions for verbatim copying, provided that the entire
|
|
||||||
resulting derived work is distributed under the terms of a permission
|
|
||||||
notice identical to this one.
|
|
||||||
|
|
||||||
Permission is granted to copy and distribute translations of this manual
|
|
||||||
into another language, under the above conditions for modified versions,
|
|
||||||
except that this permission notice may be stated in a translation approved
|
|
||||||
by the Foundation.
|
|
||||||
@end ifinfo
|
|
||||||
|
|
||||||
|
(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
|
||||||
|
this GNU Manual, like GNU software. Copies published by the Free
|
||||||
|
Software Foundation raise funds for GNU development.''
|
||||||
|
@end quotation
|
||||||
|
@end copying
|
||||||
|
|
||||||
@titlepage
|
@titlepage
|
||||||
@title GNU CPIO
|
@title GNU CPIO
|
||||||
@subtitle @value{VERSION} @value{RELEASEDATE}
|
@subtitle @value{VERSION} @value{UPDATED}
|
||||||
@author by Robert Carleton
|
@author by Robert Carleton
|
||||||
@c copyright page
|
@c copyright page
|
||||||
@page
|
@page
|
||||||
@vskip 0pt plus 1filll
|
@vskip 0pt plus 1filll
|
||||||
Copyright @copyright{} 1995, 2001, 2002 Free Software Foundation, Inc.
|
@insertcopying
|
||||||
@sp 2
|
|
||||||
This is the first edition of the GNU cpio documentation,@*
|
|
||||||
and is consistent with @value{VERSION}.@*
|
|
||||||
@sp 2
|
@sp 2
|
||||||
Published by the Free Software Foundation @*
|
Published by the Free Software Foundation @*
|
||||||
59 Temple Place - Suite 330, @*
|
51 Franklin Street, Fifth Floor, @*
|
||||||
Boston, MA 02111-1307, USA @*
|
Boston, MA 02110-1301, USA @*
|
||||||
|
|
||||||
Permission is granted to make and distribute verbatim copies of
|
|
||||||
this manual provided the copyright notice and this permission notice
|
|
||||||
are preserved on all copies.
|
|
||||||
|
|
||||||
Permission is granted to copy and distribute modified versions of this
|
|
||||||
manual under the conditions for verbatim copying, provided that the entire
|
|
||||||
resulting derived work is distributed under the terms of a permission
|
|
||||||
notice identical to this one.
|
|
||||||
|
|
||||||
Permission is granted to copy and distribute translations of this manual
|
|
||||||
into another language, under the above conditions for modified versions,
|
|
||||||
except that this permission notice may be stated in a translation
|
|
||||||
approved by the Free Software Foundation.
|
|
||||||
@end titlepage
|
@end titlepage
|
||||||
|
|
||||||
@ifinfo
|
|
||||||
@node Top, Introduction, (dir), (dir)
|
@node Top, Introduction, (dir), (dir)
|
||||||
@comment node-name, next, previous, up
|
@comment node-name, next, previous, up
|
||||||
|
|
||||||
|
@ifinfo
|
||||||
@top
|
@top
|
||||||
|
|
||||||
GNU cpio is a tool for creating and extracting archives, or copying
|
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
|
files from one place to another. It handles a number of cpio formats as
|
||||||
well as reading and writing tar files. This is the first edition of the
|
well as reading and writing tar files. This is the first edition of the
|
||||||
GNU cpio documentation and is consistant with @value{VERSION}.
|
GNU cpio documentation and is consistent with @value{VERSION}.
|
||||||
|
|
||||||
|
@end ifinfo
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Introduction::
|
* Introduction::
|
||||||
* Tutorial:: Getting started.
|
* Tutorial:: Getting started.
|
||||||
* Invoking `cpio':: How to invoke `cpio'.
|
* Invoking cpio:: How to invoke @command{cpio}.
|
||||||
* Media:: Using tapes and other archive media.
|
* Media:: Using tapes and other archive media.
|
||||||
|
* Reports:: Reporting bugs or suggestions
|
||||||
* Concept Index:: Concept index.
|
* Concept Index:: Concept index.
|
||||||
|
|
||||||
|
@detailmenu
|
||||||
--- The Detailed Node Listing ---
|
--- The Detailed Node Listing ---
|
||||||
|
|
||||||
Invoking cpio
|
Invoking cpio
|
||||||
@ -99,9 +75,9 @@ Invoking cpio
|
|||||||
* Copy-in mode::
|
* Copy-in mode::
|
||||||
* Copy-pass mode::
|
* Copy-pass mode::
|
||||||
* Options::
|
* Options::
|
||||||
@end menu
|
|
||||||
|
|
||||||
@end ifinfo
|
@end detailmenu
|
||||||
|
@end menu
|
||||||
|
|
||||||
@node Introduction, Tutorial, Top, Top
|
@node Introduction, Tutorial, Top, Top
|
||||||
@comment node-name, next, previous, up
|
@comment node-name, next, previous, up
|
||||||
@ -112,13 +88,13 @@ can be another file on the disk, a magnetic tape, or a pipe.
|
|||||||
|
|
||||||
GNU cpio supports the following archive formats: binary, old ASCII, new
|
GNU cpio supports the following archive formats: binary, old ASCII, new
|
||||||
ASCII, crc, HPUX binary, HPUX old ASCII, old tar, and POSIX.1 tar. The
|
ASCII, crc, HPUX binary, HPUX old ASCII, old tar, and POSIX.1 tar. The
|
||||||
tar format is provided for compatability with the tar program. By
|
tar format is provided for compatibility with the tar program. By
|
||||||
default, cpio creates binary format archives, for compatibility with
|
default, cpio creates binary format archives, for compatibility with
|
||||||
older cpio programs. When extracting from archives, cpio automatically
|
older cpio programs. When extracting from archives, cpio automatically
|
||||||
recognizes which kind of archive it is reading and can read archives
|
recognizes which kind of archive it is reading and can read archives
|
||||||
created on machines with a different byte-order.
|
created on machines with a different byte-order.
|
||||||
|
|
||||||
@node Tutorial, Invoking `cpio', Introduction, Top
|
@node Tutorial, Invoking cpio, Introduction, Top
|
||||||
@comment node-name, next, previous, up
|
@comment node-name, next, previous, up
|
||||||
@chapter Tutorial
|
@chapter Tutorial
|
||||||
@cindex creating a cpio archive
|
@cindex creating a cpio archive
|
||||||
@ -134,7 +110,7 @@ disks, or one or more tapes.
|
|||||||
|
|
||||||
When creating an archive, cpio takes the list of files to be processed
|
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
|
from the standard input, and then sends the archive to the standard
|
||||||
output, or to the device defined by the @samp{-F} option.
|
output, or to the device defined by the @option{-F} option.
|
||||||
@xref{Copy-out mode}. Usually find or ls is used to provide this list
|
@xref{Copy-out mode}. Usually find or ls is used to provide this list
|
||||||
to the standard input. In the following example you can see the
|
to the standard input. In the following example you can see the
|
||||||
possibilities for archiving the contents of a single directory.
|
possibilities for archiving the contents of a single directory.
|
||||||
@ -146,9 +122,9 @@ possibilities for archiving the contents of a single directory.
|
|||||||
@end cartouche
|
@end cartouche
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
The @samp{-o} option creates the archive, and the @samp{-v} option
|
The @option{-o} option creates the archive, and the @option{-v} option
|
||||||
prints the names of the files archived as they are added. Notice that
|
prints the names of the files archived as they are added. Notice that
|
||||||
the options can be put together after a single @samp{-} or can be placed
|
the options can be put together after a single @option{-} or can be placed
|
||||||
separately on the command line. The @samp{>} redirects the cpio output
|
separately on the command line. The @samp{>} redirects the cpio output
|
||||||
to the file @samp{directory.cpio}.
|
to the file @samp{directory.cpio}.
|
||||||
|
|
||||||
@ -165,12 +141,12 @@ provide the file list to cpio:
|
|||||||
|
|
||||||
|
|
||||||
This will take all the files in the current directory, the directories
|
This will take all the files in the current directory, the directories
|
||||||
below and place them in the archive tree.cpio. Again the @samp{-o}
|
below and place them in the archive tree.cpio. Again the @option{-o}
|
||||||
creates an archive, and the @samp{-v} option shows you the name of the
|
creates an archive, and the @option{-v} option shows you the name of the
|
||||||
files as they are archived. @xref{Copy-out mode}. Using the `.' in the
|
files as they are archived. @xref{Copy-out mode}. Using the @samp{.} in the
|
||||||
find statement will give you more flexibility when doing restores, as it
|
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
|
will save file names with a relative path vice a hard wired, absolute
|
||||||
path. The @samp{-depth} option forces @samp{find} to print of the
|
path. The @option{-depth} option forces @samp{find} to print of the
|
||||||
entries in a directory before printing the directory itself. This
|
entries in a directory before printing the directory itself. This
|
||||||
limits the effects of restrictive directory permissions by printing the
|
limits the effects of restrictive directory permissions by printing the
|
||||||
directory entries in a directory before the directory name itself.
|
directory entries in a directory before the directory name itself.
|
||||||
@ -190,10 +166,10 @@ overwrite existing files unless you tell it to.
|
|||||||
@end example
|
@end example
|
||||||
|
|
||||||
This will retrieve the files archived in the file directory.cpio and
|
This will retrieve the files archived in the file directory.cpio and
|
||||||
place them in the present directory. The @samp{-i} option extracts the
|
place them in the present directory. The @option{-i} option extracts the
|
||||||
archive and the @samp{-v} shows the file names as they are extracted.
|
archive and the @option{-v} shows the file names as they are extracted.
|
||||||
If you are dealing with an archived directory tree, you need to use the
|
If you are dealing with an archived directory tree, you need to use the
|
||||||
@samp{-d} option to create directories as necessary, something like:
|
@option{-d} option to create directories as necessary, something like:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
@cartouche
|
@cartouche
|
||||||
@ -223,13 +199,13 @@ argument. @xref{Copy-pass mode}.
|
|||||||
|
|
||||||
The example shows copying the files of the present directory, and
|
The example shows copying the files of the present directory, and
|
||||||
sub-directories to a new directory called new-dir. Some new options are
|
sub-directories to a new directory called new-dir. Some new options are
|
||||||
the @samp{-print0} available with GNU find, combined with the
|
the @option{-print0} available with GNU find, combined with the
|
||||||
@samp{--null} option of cpio. These two options act together to send
|
@option{--null} option of cpio. These two options act together to send
|
||||||
file names between find and cpio, even if special characters are
|
file names between find and cpio, even if special characters are
|
||||||
embedded in the file names. Another is @samp{-p}, which tells cpio to
|
embedded in the file names. Another is @option{-p}, which tells cpio to
|
||||||
pass the files it finds to the directory @samp{new-dir}.
|
pass the files it finds to the directory @samp{new-dir}.
|
||||||
|
|
||||||
@node Invoking `cpio', Media, Tutorial, Top
|
@node Invoking cpio, Media, Tutorial, Top
|
||||||
@comment node-name, next, previous, up
|
@comment node-name, next, previous, up
|
||||||
@chapter Invoking cpio
|
@chapter Invoking cpio
|
||||||
@cindex invoking cpio
|
@cindex invoking cpio
|
||||||
@ -242,7 +218,7 @@ pass the files it finds to the directory @samp{new-dir}.
|
|||||||
* Options::
|
* Options::
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node Copy-out mode, Copy-in mode, Invoking `cpio', Invoking `cpio'
|
@node Copy-out mode, Copy-in mode, Invoking cpio, Invoking cpio
|
||||||
@comment node-name, next, previous, up
|
@comment node-name, next, previous, up
|
||||||
@section Copy-out mode
|
@section Copy-out mode
|
||||||
|
|
||||||
@ -264,7 +240,7 @@ cpio @{-o|--create@} [-0acvABLV] [-C bytes] [-H format]
|
|||||||
< name-list [> archive]
|
< name-list [> archive]
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@node Copy-in mode, Copy-pass mode, Copy-out mode, Invoking `cpio'
|
@node Copy-in mode, Copy-pass mode, Copy-out mode, Invoking cpio
|
||||||
@comment node-name, next, previous, up
|
@comment node-name, next, previous, up
|
||||||
@section Copy-in mode
|
@section Copy-in mode
|
||||||
|
|
||||||
@ -272,8 +248,8 @@ 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
|
archive contents. It reads the archive from the standard input. Any
|
||||||
non-option command line arguments are shell globbing patterns; only
|
non-option command line arguments are shell globbing patterns; only
|
||||||
files in the archive whose names match one or more of those patterns are
|
files in the archive whose names match one or more of those patterns are
|
||||||
copied from the archive. Unlike in the shell, an initial `.' in a
|
copied from the archive. Unlike in the shell, an initial @samp{.} in a
|
||||||
filename does match a wildcard at the start of a pattern, and a `/' in a
|
filename does match a wildcard at the start of a pattern, and a @samp{/} in a
|
||||||
filename can match wildcards. If no patterns are given, all files are
|
filename can match wildcards. If no patterns are given, all files are
|
||||||
extracted. @xref{Options}.
|
extracted. @xref{Options}.
|
||||||
|
|
||||||
@ -288,11 +264,11 @@ cpio @{-i|--extract@} [-bcdfmnrtsuvBSV] [-C bytes] [-E file]
|
|||||||
[--swap-halfwords] [--io-size=bytes] [--pattern-file=file]
|
[--swap-halfwords] [--io-size=bytes] [--pattern-file=file]
|
||||||
[--format=format] [--owner=[user][:.][group]]
|
[--format=format] [--owner=[user][:.][group]]
|
||||||
[--no-preserve-owner] [--message=message] [--help] [--version]
|
[--no-preserve-owner] [--message=message] [--help] [--version]
|
||||||
[-no-absolute-filenames] [--sparse] [-only-verify-crc] [-quiet]
|
[--no-absolute-filenames] [--sparse] [-only-verify-crc] [-quiet]
|
||||||
[--rsh-command=command] [pattern...] [< archive]
|
[--rsh-command=command] [pattern...] [< archive]
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@node Copy-pass mode, Options, Copy-in mode, Invoking `cpio'
|
@node Copy-pass mode, Options, Copy-in mode, Invoking cpio
|
||||||
@comment node-name, next, previous, up
|
@comment node-name, next, previous, up
|
||||||
@section Copy-pass mode
|
@section Copy-pass mode
|
||||||
|
|
||||||
@ -314,7 +290,7 @@ cpio @{-p|--pass-through@} [-0adlmuvLV] [-R [user][:.][group]]
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
@node Options, , Copy-pass mode, Invoking `cpio'
|
@node Options, , Copy-pass mode, Invoking cpio
|
||||||
@comment node-name, next, previous, up
|
@comment node-name, next, previous, up
|
||||||
@section Options
|
@section Options
|
||||||
|
|
||||||
@ -322,22 +298,26 @@ cpio @{-p|--pass-through@} [-0adlmuvLV] [-R [user][:.][group]]
|
|||||||
@table @code
|
@table @code
|
||||||
|
|
||||||
|
|
||||||
@item -0, --null
|
@item -0
|
||||||
|
@itemx --null
|
||||||
Read a list of filenames terminated by a null character, instead of a
|
Read a list of filenames terminated by a null character, instead of a
|
||||||
newline, so that files whose names contain newlines can be archived.
|
newline, so that files whose names contain newlines can be archived.
|
||||||
GNU find is one way to produce a list of null-terminated filenames.
|
GNU find is one way to produce a list of null-terminated filenames.
|
||||||
This option may be used in copy-out and copy-pass modes.
|
This option may be used in copy-out and copy-pass modes.
|
||||||
|
|
||||||
@item -a, --reset-access-time
|
@item -a
|
||||||
|
@itemx --reset-access-time
|
||||||
Reset the access times of files after reading them, so
|
Reset the access times of files after reading them, so
|
||||||
that it does not look like they have just been read.
|
that it does not look like they have just been read.
|
||||||
|
|
||||||
@item -A, --append
|
@item -A
|
||||||
|
@itemx --append
|
||||||
Append to an existing archive. Only works in copy-out
|
Append to an existing archive. Only works in copy-out
|
||||||
mode. The archive must be a disk file specified with
|
mode. The archive must be a disk file specified with
|
||||||
the -O or -F (--file) option.
|
the @option{-O} or @option{-F} (@option{--file}) option.
|
||||||
|
|
||||||
@item -b, --swap
|
@item -b
|
||||||
|
@itemx --swap
|
||||||
Swap both halfwords of words and bytes of halfwords in the data.
|
Swap both halfwords of words and bytes of halfwords in the data.
|
||||||
Equivalent to -sS. This option may be used in copy-in mode. Use this
|
Equivalent to -sS. This option may be used in copy-in mode. Use this
|
||||||
option to convert 32-bit integers between big-endian and little-endian
|
option to convert 32-bit integers between big-endian and little-endian
|
||||||
@ -347,42 +327,49 @@ machines.
|
|||||||
Set the I/O block size to 5120 bytes. Initially the
|
Set the I/O block size to 5120 bytes. Initially the
|
||||||
block size is 512 bytes.
|
block size is 512 bytes.
|
||||||
|
|
||||||
@item --block-size=BLOCK-SIZE
|
@item --block-size=@var{block-size}
|
||||||
Set the I/O block size to BLOCK-SIZE * 512 bytes.
|
Set the I/O block size to @var{block-size} * 512 bytes.
|
||||||
|
|
||||||
@item -c
|
@item -c
|
||||||
Use the old portable (ASCII) archive format.
|
Use the old portable (ASCII) archive format.
|
||||||
|
|
||||||
@item -C IO-SIZE, --io-size=IO-SIZE
|
@item -C @var{io-size}
|
||||||
Set the I/O block size to IO-SIZE bytes.
|
@itemx --io-size=@var{io-size}
|
||||||
|
Set the I/O block size to @var{io-size} bytes.
|
||||||
|
|
||||||
@item -d, --make-directories
|
@item -d
|
||||||
|
@itemx --make-directories
|
||||||
Create leading directories where needed.
|
Create leading directories where needed.
|
||||||
|
|
||||||
@item -E FILE, --pattern-file=FILE
|
@item -E @var{file}
|
||||||
|
@itemx --pattern-file=@var{file}
|
||||||
Read additional patterns specifying filenames to extract or list from
|
Read additional patterns specifying filenames to extract or list from
|
||||||
FILE. The lines of FILE are treated as if they had been non-option
|
@var{file}. The lines of @var{file} are treated as if they had been non-option
|
||||||
arguments to cpio. This option is used in copy-in mode,
|
arguments to cpio. This option is used in copy-in mode,
|
||||||
|
|
||||||
@item -f, --nonmatching
|
@item -f
|
||||||
|
@itemx --nonmatching
|
||||||
Only copy files that do not match any of the given
|
Only copy files that do not match any of the given
|
||||||
patterns.
|
patterns.
|
||||||
|
|
||||||
@item -F, --file=archive
|
@item -F @var{archive}
|
||||||
|
@itemx --file=@var{archive}
|
||||||
Archive filename to use instead of standard input or output. To use a
|
Archive filename to use instead of standard input or output. To use a
|
||||||
tape drive on another machine as the archive, use a filename that starts
|
tape drive on another machine as the archive, use a filename that starts
|
||||||
with `HOSTNAME:'. The hostname can be preceded by a username and an
|
with @samp{@var{hostname}:}, where @var{hostname} is the name or IP
|
||||||
`@@' to access the remote tape drive as that user, if you have
|
address of the machine. The hostname can be preceded by a username and an
|
||||||
permission to do so (typically an entry in that user's `~/.rhosts'
|
@samp{@@} to access the remote tape drive as that user, if you have
|
||||||
|
permission to do so (typically an entry in that user's @file{~/.rhosts}
|
||||||
file).
|
file).
|
||||||
|
|
||||||
@item --force-local
|
@item --force-local
|
||||||
With -F, -I, or -O, take the archive file name to be a
|
With @option{-F}, @option{-I}, or @option{-O}, take the archive file name to be a
|
||||||
local file even if it contains a colon, which would
|
local file even if it contains a colon, which would
|
||||||
ordinarily indicate a remote host name.
|
ordinarily indicate a remote host name.
|
||||||
|
|
||||||
@item -H FORMAT, --format=FORMAT
|
@item -H @var{format}
|
||||||
Use archive format FORMAT. The valid formats are listed below; the same
|
@itemx --format=@var{format}
|
||||||
|
Use archive format @var{format}. The valid formats are listed below; the same
|
||||||
names are also recognized in all-caps. The default in copy-in mode is
|
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
|
to automatically detect the archive format, and in copy-out mode is
|
||||||
@samp{bin}.
|
@samp{bin}.
|
||||||
@ -417,39 +404,46 @@ The portable format used by HPUX's cpio (which stores device files
|
|||||||
differently).
|
differently).
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@item -i, --extract
|
@item -i
|
||||||
|
@itemx --extract
|
||||||
Run in copy-in mode.
|
Run in copy-in mode.
|
||||||
@xref{Copy-in mode}.
|
@xref{Copy-in mode}.
|
||||||
|
|
||||||
@item -I archive
|
@item -I @var{archive}
|
||||||
Archive filename to use instead of standard input. To use a tape drive
|
Archive filename to use instead of standard input. To use a tape drive
|
||||||
on another machine as the archive, use a filename that starts with
|
on another machine as the archive, use a filename that starts with
|
||||||
`HOSTNAME:'. The hostname can be preceded by a username and an `@@' to
|
@samp{@var{hostname}:}, where @var{hostname} is the name or IP address
|
||||||
|
of the remote host. The hostname can be preceded by a username and an @samp{@@} to
|
||||||
access the remote tape drive as that user, if you have permission to do
|
access the remote tape drive as that user, if you have permission to do
|
||||||
so (typically an entry in that user's `~/.rhosts' file).
|
so (typically an entry in that user's @file{~/.rhosts} file).
|
||||||
|
|
||||||
@item -k
|
@item -k
|
||||||
Ignored; for compatibility with other versions of cpio.
|
Ignored; for compatibility with other versions of cpio.
|
||||||
|
|
||||||
@item -l, --link
|
@item -l
|
||||||
|
@itemx --link
|
||||||
Link files instead of copying them, when possible.
|
Link files instead of copying them, when possible.
|
||||||
|
|
||||||
@item -L, --dereference
|
@item -L
|
||||||
|
@itemx --dereference
|
||||||
Copy the file that a symbolic link points to, rather than the symbolic
|
Copy the file that a symbolic link points to, rather than the symbolic
|
||||||
link itself.
|
link itself.
|
||||||
|
|
||||||
@item -m, --preserve-modification-time
|
@item -m
|
||||||
|
@itemx --preserve-modification-time
|
||||||
Retain previous file modification times when creating files.
|
Retain previous file modification times when creating files.
|
||||||
|
|
||||||
@item -M MESSAGE, --message=MESSAGE
|
@item -M @var{message}
|
||||||
Print MESSAGE when the end of a volume of the backup media (such as a
|
@itemx --message=@var{message}
|
||||||
|
Print @var{message} 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
|
tape or a floppy disk) is reached, to prompt the user to insert a new
|
||||||
volume. If MESSAGE contains the string "%d", it is replaced by the
|
volume. If @var{message} contains the string @samp{%d}, it is replaced by the
|
||||||
current volume number (starting at 1).
|
current volume number (starting at 1).
|
||||||
|
|
||||||
@item -n, --numeric-uid-gid
|
@item -n
|
||||||
|
@itemx --numeric-uid-gid
|
||||||
Show numeric UID and GID instead of translating them into names when using the
|
Show numeric UID and GID instead of translating them into names when using the
|
||||||
@samp{--verbose option}.
|
@option{--verbose} option.
|
||||||
|
|
||||||
@item --no-absolute-filenames
|
@item --no-absolute-filenames
|
||||||
Create all files relative to the current directory in copy-in mode, even
|
Create all files relative to the current directory in copy-in mode, even
|
||||||
@ -461,47 +455,72 @@ extracting them. This is the default for non-root users, so that users
|
|||||||
on System V don't inadvertantly give away files. This option can be
|
on System V don't inadvertantly give away files. This option can be
|
||||||
used in copy-in mode and copy-pass mode
|
used in copy-in mode and copy-pass mode
|
||||||
|
|
||||||
@item -o, --create
|
@item -o
|
||||||
|
@itemx --create
|
||||||
Run in copy-out mode.
|
Run in copy-out mode.
|
||||||
@xref{Copy-out mode}.
|
@xref{Copy-out mode}.
|
||||||
|
|
||||||
@item -O archive
|
@item -O @var{archive}
|
||||||
Archive filename to use instead of standard output. To use a tape drive
|
Archive filename to use instead of standard output. To use a tape drive
|
||||||
on another machine as the archive, use a filename that starts with
|
on another machine as the archive, use a filename that starts with
|
||||||
`HOSTNAME:'. The hostname can be preceded by a username and an `@@' to
|
@samp{@var{hostname}:}, where @var{hostname} is the name or IP address
|
||||||
|
of the machine. The hostname can be preceded by a username and an @samp{@@} to
|
||||||
access the remote tape drive as that user, if you have permission to do
|
access the remote tape drive as that user, if you have permission to do
|
||||||
so (typically an entry in that user's `~/.rhosts' file).
|
so (typically an entry in that user's @file{~/.rhosts} file).
|
||||||
|
|
||||||
@item --only-verify-crc
|
@item --only-verify-crc
|
||||||
Verify the CRC's of each file in the archive, when reading a CRC format
|
Verify the CRC's of each file in the archive, when reading a CRC format
|
||||||
archive. Don't actually extract the files.
|
archive. Don't actually extract the files.
|
||||||
|
|
||||||
@item -p, --pass-through
|
@item -p
|
||||||
|
@itemx --pass-through
|
||||||
Run in copy-pass mode.
|
Run in copy-pass mode.
|
||||||
@xref{Copy-pass mode}.
|
@xref{Copy-pass mode}.
|
||||||
|
|
||||||
@item --quiet
|
@item --quiet
|
||||||
Do not print the number of blocks copied.
|
Do not print the number of blocks copied.
|
||||||
|
|
||||||
@item -r, --rename
|
@item -r
|
||||||
|
@itemx --rename
|
||||||
Interactively rename files.
|
Interactively rename files.
|
||||||
|
|
||||||
@item -R [user][:.][group], --owner [user][:.][group]
|
@item -R @var{owner}
|
||||||
Set the ownership of all files created to the specified user and/or
|
@itemx --owner @var{owner}
|
||||||
group in copy-out and copy-pass modes. Either the user, the group, or
|
|
||||||
both, must be present. If the group is omitted but the ":" or "."
|
|
||||||
separator is given, use the given user's login group. Only the
|
|
||||||
super-user can change files' ownership.
|
|
||||||
|
|
||||||
@item --rsh-command=COMMAND
|
In copy-in and copy-pass mode, set the ownership of all files created
|
||||||
Notifies cpio that is should use COMMAND to communicate with remote
|
to the specified @var{owner} (this operation is allowed only for the
|
||||||
|
super-user). In copy-out mode, store the supplied owner information in
|
||||||
|
the archive.
|
||||||
|
|
||||||
|
The argument can be either the user name or the user name
|
||||||
|
and group name, separated by a dot or a colon, or the group name,
|
||||||
|
preceeded by a dot or a colon, as shown in the examples below:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
@group
|
||||||
|
cpio --owner smith
|
||||||
|
cpio --owner smith:
|
||||||
|
cpio --owner smith:users
|
||||||
|
cpio --owner :users
|
||||||
|
@end group
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
If the group is omitted but the @samp{:} or @samp{.} separator is
|
||||||
|
given, as in the second example. the given user's login group will be
|
||||||
|
used.
|
||||||
|
|
||||||
|
@item --rsh-command=@var{command}
|
||||||
|
Notifies cpio that is should use @var{command} to communicate with remote
|
||||||
devices.
|
devices.
|
||||||
|
|
||||||
@item -s, --swap-bytes
|
@item -s
|
||||||
Swap the bytes of each halfword (pair of bytes) in the files.This option
|
@itemx --swap-bytes
|
||||||
|
Swap the bytes of each halfword (pair of bytes) in the files. This option
|
||||||
can be used in copy-in mode.
|
can be used in copy-in mode.
|
||||||
|
|
||||||
@item -S, --swap-halfwords
|
@item -S
|
||||||
|
@itemx --swap-halfwords
|
||||||
Swap the halfwords of each word (4 bytes) in the files. This option may
|
Swap the halfwords of each word (4 bytes) in the files. This option may
|
||||||
be used in copy-in mode.
|
be used in copy-in mode.
|
||||||
|
|
||||||
@ -509,29 +528,33 @@ be used in copy-in mode.
|
|||||||
Write files with large blocks of zeros as sparse files. This option is
|
Write files with large blocks of zeros as sparse files. This option is
|
||||||
used in copy-in and copy-pass modes.
|
used in copy-in and copy-pass modes.
|
||||||
|
|
||||||
@item -t, --list
|
@item -t
|
||||||
|
@itemx --list
|
||||||
Print a table of contents of the input.
|
Print a table of contents of the input.
|
||||||
|
|
||||||
@item -u, --unconditional
|
@item -u
|
||||||
|
@itemx --unconditional
|
||||||
Replace all files, without asking whether to replace
|
Replace all files, without asking whether to replace
|
||||||
existing newer files with older files.
|
existing newer files with older files.
|
||||||
|
|
||||||
@item -v, --verbose
|
@item -v
|
||||||
List the files processed, or with @samp{-t}, give an @samp{ls -l} style
|
@itemx --verbose
|
||||||
|
List the files processed, or with @option{-t}, give an @samp{ls -l} style
|
||||||
table of contents listing. In a verbose table of contents of a ustar
|
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
|
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
|
local system are replaced by the names that correspond locally to the
|
||||||
numeric UID and GID stored in the archive.
|
numeric UID and GID stored in the archive.
|
||||||
|
|
||||||
@item -V --dot
|
@item -V
|
||||||
Print a @kbd{.} for each file processed.
|
@itemx --dot
|
||||||
|
Print a @samp{.} for each file processed.
|
||||||
|
|
||||||
@item --version
|
@item --version
|
||||||
Print the cpio program version number and exit.
|
Print the cpio program version number and exit.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
||||||
@node Media, Concept Index, Invoking `cpio', Top
|
@node Media, Reports, Invoking cpio, Top
|
||||||
@comment node-name, next, previous, up
|
@comment node-name, next, previous, up
|
||||||
@chapter Magnetic Media
|
@chapter Magnetic Media
|
||||||
@cindex magnetic media
|
@cindex magnetic media
|
||||||
@ -554,8 +577,24 @@ be protected from such fields to avoid damage to stored data. Sticking
|
|||||||
a floppy disk to a filing cabinet using a magnet is probably not a good
|
a floppy disk to a filing cabinet using a magnet is probably not a good
|
||||||
idea.
|
idea.
|
||||||
|
|
||||||
|
@node Reports, Concept Index, Media, Top
|
||||||
|
@chapter Reporting bugs or suggestions
|
||||||
|
|
||||||
@node Concept Index, , Media, Top
|
It is possible you will encounter a bug in @command{cpio}.
|
||||||
|
If this happens, we would like to hear about it. As the purpose of bug
|
||||||
|
reporting is to improve software, please be sure to include maximum
|
||||||
|
information when reporting a bug. The information needed is:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item Version of the package you are using.
|
||||||
|
@item Compilation options used when configuring the package.
|
||||||
|
@item Conditions under which the bug appears.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
Send your report to <bug-cpio@@gnu.org>. Allow us a couple of
|
||||||
|
days to answer.
|
||||||
|
|
||||||
|
@node Concept Index, , Reports, Top
|
||||||
@comment node-name, next, previous, up
|
@comment node-name, next, previous, up
|
||||||
@unnumbered Concept Index
|
@unnumbered Concept Index
|
||||||
@printindex cp
|
@printindex cp
|
||||||
|
4
doc/version.texi
Normal file
4
doc/version.texi
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
@set UPDATED 7 June 2007
|
||||||
|
@set UPDATED-MONTH June 2007
|
||||||
|
@set EDITION 2.8
|
||||||
|
@set VERSION 2.8
|
@ -1,6 +1,6 @@
|
|||||||
/* Memory allocation on the stack.
|
/* Memory allocation on the stack.
|
||||||
|
|
||||||
Copyright (C) 1995, 1999, 2001, 2002, 2003, 2004 Free Software
|
Copyright (C) 1995, 1999, 2001-2004, 2006-2007 Free Software
|
||||||
Foundation, Inc.
|
Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it
|
This program is free software; you can redistribute it and/or modify it
|
||||||
@ -15,15 +15,13 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public
|
You should have received a copy of the GNU General Public
|
||||||
License along with this program; if not, write to the Free Software
|
License along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
USA. */
|
USA. */
|
||||||
|
|
||||||
/* When this file is included, it may be preceded only by preprocessor
|
/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H
|
||||||
declarations. Thanks to AIX. Therefore we include it right after
|
means there is a real alloca function. */
|
||||||
"config.h", not later. */
|
#ifndef _GL_ALLOCA_H
|
||||||
|
#define _GL_ALLOCA_H
|
||||||
#ifndef _ALLOCA_H
|
|
||||||
# define _ALLOCA_H
|
|
||||||
|
|
||||||
/* alloca (N) returns a pointer to N bytes of memory
|
/* alloca (N) returns a pointer to N bytes of memory
|
||||||
allocated on the stack, which will last until the function returns.
|
allocated on the stack, which will last until the function returns.
|
||||||
@ -36,19 +34,21 @@
|
|||||||
request, the program just crashes.
|
request, the program just crashes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifndef alloca
|
||||||
# define alloca __builtin_alloca
|
# ifdef __GNUC__
|
||||||
#elif defined _AIX
|
# define alloca __builtin_alloca
|
||||||
# define alloca __alloca
|
# elif defined _AIX
|
||||||
#elif defined _MSC_VER
|
# define alloca __alloca
|
||||||
# include <malloc.h>
|
# elif defined _MSC_VER
|
||||||
# define alloca _alloca
|
# include <malloc.h>
|
||||||
#else
|
# define alloca _alloca
|
||||||
# include <stddef.h>
|
# else
|
||||||
# ifdef __cplusplus
|
# include <stddef.h>
|
||||||
|
# ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
# endif
|
# endif
|
||||||
void *alloca (size_t);
|
void *alloca (size_t);
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _ALLOCA_H */
|
#endif /* _GL_ALLOCA_H */
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
/* If set by the user program, it should point to string that is the
|
/* If set by the user program, it should point to string that is the
|
||||||
bug-reporting address for the program. It will be printed by argp_help if
|
bug-reporting address for the program. It will be printed by argp_help if
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sysexits.h>
|
#include <sysexits.h>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Word-wrapping and line-truncating streams
|
/* Word-wrapping and line-truncating streams
|
||||||
Copyright (C) 1997,1998,1999,2001,2002,2003 Free Software Foundation, Inc.
|
Copyright (C) 1997-1999,2001,2002,2003,2005 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||||
|
|
||||||
@ -15,13 +15,13 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
/* This package emulates glibc `line_wrap_stream' semantics for systems that
|
/* This package emulates glibc `line_wrap_stream' semantics for systems that
|
||||||
don't have that. */
|
don't have that. */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -101,11 +101,10 @@ __argp_fmtstream_free (argp_fmtstream_t fs)
|
|||||||
if (fs->p > fs->buf)
|
if (fs->p > fs->buf)
|
||||||
{
|
{
|
||||||
#ifdef USE_IN_LIBIO
|
#ifdef USE_IN_LIBIO
|
||||||
if (_IO_fwide (fs->stream, 0) > 0)
|
__fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
|
||||||
__fwprintf (fs->stream, L"%.*s", (int) (fs->p - fs->buf), fs->buf);
|
#else
|
||||||
else
|
fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
|
||||||
#endif
|
#endif
|
||||||
fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
|
|
||||||
}
|
}
|
||||||
free (fs->buf);
|
free (fs->buf);
|
||||||
free (fs);
|
free (fs);
|
||||||
@ -247,9 +246,10 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
|
|||||||
Oh well. Put it on an overlong line by itself. */
|
Oh well. Put it on an overlong line by itself. */
|
||||||
p = buf + (r + 1 - fs->point_col);
|
p = buf + (r + 1 - fs->point_col);
|
||||||
/* Find the end of the long word. */
|
/* Find the end of the long word. */
|
||||||
do
|
if (p < nl)
|
||||||
++p;
|
do
|
||||||
while (p < nl && !isblank (*p));
|
++p;
|
||||||
|
while (p < nl && !isblank (*p));
|
||||||
if (p == nl)
|
if (p == nl)
|
||||||
{
|
{
|
||||||
/* It already ends a line. No fussing required. */
|
/* It already ends a line. No fussing required. */
|
||||||
@ -290,17 +290,15 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
|
|||||||
else
|
else
|
||||||
/* Output the first line so we can use the space. */
|
/* Output the first line so we can use the space. */
|
||||||
{
|
{
|
||||||
#ifdef USE_IN_LIBIO
|
#ifdef _LIBC
|
||||||
if (_IO_fwide (fs->stream, 0) > 0)
|
__fxprintf (fs->stream, "%.*s\n",
|
||||||
__fwprintf (fs->stream, L"%.*s\n",
|
(int) (nl - fs->buf), fs->buf);
|
||||||
(int) (nl - fs->buf), fs->buf);
|
#else
|
||||||
else
|
if (nl > fs->buf)
|
||||||
|
fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream);
|
||||||
|
putc_unlocked ('\n', fs->stream);
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
if (nl > fs->buf)
|
|
||||||
fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream);
|
|
||||||
putc_unlocked ('\n', fs->stream);
|
|
||||||
}
|
|
||||||
len += buf - fs->buf;
|
len += buf - fs->buf;
|
||||||
nl = buf = fs->buf;
|
nl = buf = fs->buf;
|
||||||
}
|
}
|
||||||
@ -359,15 +357,12 @@ __argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
|
|||||||
/* Flush FS's buffer. */
|
/* Flush FS's buffer. */
|
||||||
__argp_fmtstream_update (fs);
|
__argp_fmtstream_update (fs);
|
||||||
|
|
||||||
#ifdef USE_IN_LIBIO
|
#ifdef _LIBC
|
||||||
if (_IO_fwide (fs->stream, 0) > 0)
|
__fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
|
||||||
{
|
wrote = fs->p - fs->buf;
|
||||||
__fwprintf (fs->stream, L"%.*s", (int) (fs->p - fs->buf), fs->buf);
|
#else
|
||||||
wrote = fs->p - fs->buf;
|
wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
|
|
||||||
if (wrote == fs->p - fs->buf)
|
if (wrote == fs->p - fs->buf)
|
||||||
{
|
{
|
||||||
fs->p = fs->buf;
|
fs->p = fs->buf;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Word-wrapping and line-truncating streams.
|
/* Word-wrapping and line-truncating streams.
|
||||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
Copyright (C) 1997, 2006 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||||
|
|
||||||
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
/* This package emulates glibc `line_wrap_stream' semantics for systems that
|
/* This package emulates glibc `line_wrap_stream' semantics for systems that
|
||||||
don't have that. If the system does have it, it is just a wrapper for
|
don't have that. If the system does have it, it is just a wrapper for
|
||||||
@ -25,10 +25,6 @@
|
|||||||
#ifndef _ARGP_FMTSTREAM_H
|
#ifndef _ARGP_FMTSTREAM_H
|
||||||
#define _ARGP_FMTSTREAM_H
|
#define _ARGP_FMTSTREAM_H
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -93,10 +89,6 @@ typedef FILE *argp_fmtstream_t;
|
|||||||
|
|
||||||
#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */
|
#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */
|
||||||
/* Guess we have to define our own version. */
|
/* Guess we have to define our own version. */
|
||||||
|
|
||||||
#ifndef __const
|
|
||||||
#define __const const
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct argp_fmtstream
|
struct argp_fmtstream
|
||||||
{
|
{
|
||||||
@ -137,22 +129,22 @@ extern void __argp_fmtstream_free (argp_fmtstream_t __fs);
|
|||||||
extern void argp_fmtstream_free (argp_fmtstream_t __fs);
|
extern void argp_fmtstream_free (argp_fmtstream_t __fs);
|
||||||
|
|
||||||
extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs,
|
extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs,
|
||||||
__const char *__fmt, ...)
|
const char *__fmt, ...)
|
||||||
__attribute__ ((__format__ (printf, 2, 3)));
|
__attribute__ ((__format__ (printf, 2, 3)));
|
||||||
extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs,
|
extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs,
|
||||||
__const char *__fmt, ...)
|
const char *__fmt, ...)
|
||||||
__attribute__ ((__format__ (printf, 2, 3)));
|
__attribute__ ((__format__ (printf, 2, 3)));
|
||||||
|
|
||||||
extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
|
extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
|
||||||
extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
|
extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
|
||||||
|
|
||||||
extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str);
|
extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str);
|
||||||
extern int argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str);
|
extern int argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str);
|
||||||
|
|
||||||
extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs,
|
extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs,
|
||||||
__const char *__str, size_t __len);
|
const char *__str, size_t __len);
|
||||||
extern size_t argp_fmtstream_write (argp_fmtstream_t __fs,
|
extern size_t argp_fmtstream_write (argp_fmtstream_t __fs,
|
||||||
__const char *__str, size_t __len);
|
const char *__str, size_t __len);
|
||||||
|
|
||||||
/* Access macros for various bits of state. */
|
/* Access macros for various bits of state. */
|
||||||
#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin)
|
#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin)
|
||||||
@ -211,7 +203,7 @@ extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
|
|||||||
|
|
||||||
ARGP_FS_EI size_t
|
ARGP_FS_EI size_t
|
||||||
__argp_fmtstream_write (argp_fmtstream_t __fs,
|
__argp_fmtstream_write (argp_fmtstream_t __fs,
|
||||||
__const char *__str, size_t __len)
|
const char *__str, size_t __len)
|
||||||
{
|
{
|
||||||
if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
|
if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
|
||||||
{
|
{
|
||||||
@ -224,7 +216,7 @@ __argp_fmtstream_write (argp_fmtstream_t __fs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ARGP_FS_EI int
|
ARGP_FS_EI int
|
||||||
__argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str)
|
__argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str)
|
||||||
{
|
{
|
||||||
size_t __len = strlen (__str);
|
size_t __len = strlen (__str);
|
||||||
if (__len)
|
if (__len)
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ARGP_FS_EI
|
#define ARGP_FS_EI
|
||||||
|
312
lib/argp-help.c
312
lib/argp-help.c
@ -1,5 +1,5 @@
|
|||||||
/* Hierarchial argument parsing help output
|
/* Hierarchial argument parsing help output
|
||||||
Copyright (C) 1995-2003, 2004 Free Software Foundation, Inc.
|
Copyright (C) 1995-2005, 2007 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||||
|
|
||||||
@ -15,14 +15,14 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
#ifndef _GNU_SOURCE
|
||||||
# define _GNU_SOURCE 1
|
# define _GNU_SOURCE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
@ -89,15 +89,15 @@ struct uparams
|
|||||||
int dup_args_note;
|
int dup_args_note;
|
||||||
|
|
||||||
/* Various output columns. */
|
/* Various output columns. */
|
||||||
int short_opt_col;
|
int short_opt_col; /* column in which short options start */
|
||||||
int long_opt_col;
|
int long_opt_col; /* column in which long options start */
|
||||||
int doc_opt_col;
|
int doc_opt_col; /* column in which doc options start */
|
||||||
int opt_doc_col;
|
int opt_doc_col; /* column in which option text starts */
|
||||||
int header_col;
|
int header_col; /* column in which group headers are printed */
|
||||||
int usage_indent;
|
int usage_indent; /* indentation of wrapped usage lines */
|
||||||
int rmargin;
|
int rmargin; /* right margin used for wrapping */
|
||||||
|
|
||||||
int valid; /* True when the values in here are valid. */
|
int valid; /* True when the values in here are valid. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This is a global variable, as user options are only ever read once. */
|
/* This is a global variable, as user options are only ever read once. */
|
||||||
@ -131,91 +131,126 @@ static const struct uparam_name uparam_names[] =
|
|||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Read user options from the environment, and fill in UPARAMS appropiately. */
|
static void
|
||||||
|
validate_uparams (const struct argp_state *state, struct uparams *upptr)
|
||||||
|
{
|
||||||
|
const struct uparam_name *up;
|
||||||
|
|
||||||
|
for (up = uparam_names; up->name; up++)
|
||||||
|
{
|
||||||
|
if (up->is_bool
|
||||||
|
|| up->uparams_offs == offsetof (struct uparams, rmargin))
|
||||||
|
continue;
|
||||||
|
if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin)
|
||||||
|
{
|
||||||
|
__argp_failure (state, 0, 0,
|
||||||
|
dgettext (state->root_argp->argp_domain,
|
||||||
|
"\
|
||||||
|
ARGP_HELP_FMT: %s value is less than or equal to %s"),
|
||||||
|
"rmargin", up->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uparams = *upptr;
|
||||||
|
uparams.valid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read user options from the environment, and fill in UPARAMS appropiately. */
|
||||||
static void
|
static void
|
||||||
fill_in_uparams (const struct argp_state *state)
|
fill_in_uparams (const struct argp_state *state)
|
||||||
{
|
{
|
||||||
const char *var = getenv ("ARGP_HELP_FMT");
|
const char *var = getenv ("ARGP_HELP_FMT");
|
||||||
|
struct uparams new_params = uparams;
|
||||||
#define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
|
|
||||||
|
#define SKIPWS(p) do { while (isspace ((unsigned char) *p)) p++; } while (0);
|
||||||
|
|
||||||
if (var)
|
if (var)
|
||||||
/* Parse var. */
|
{
|
||||||
while (*var)
|
/* Parse var. */
|
||||||
{
|
while (*var)
|
||||||
SKIPWS (var);
|
{
|
||||||
|
SKIPWS (var);
|
||||||
|
|
||||||
|
if (isalpha ((unsigned char) *var))
|
||||||
|
{
|
||||||
|
size_t var_len;
|
||||||
|
const struct uparam_name *un;
|
||||||
|
int unspec = 0, val = 0;
|
||||||
|
const char *arg = var;
|
||||||
|
|
||||||
if (isalpha (*var))
|
while (isalnum ((unsigned char) *arg) || *arg == '-' || *arg == '_')
|
||||||
{
|
|
||||||
size_t var_len;
|
|
||||||
const struct uparam_name *un;
|
|
||||||
int unspec = 0, val = 0;
|
|
||||||
const char *arg = var;
|
|
||||||
|
|
||||||
while (isalnum (*arg) || *arg == '-' || *arg == '_')
|
|
||||||
arg++;
|
|
||||||
var_len = arg - var;
|
|
||||||
|
|
||||||
SKIPWS (arg);
|
|
||||||
|
|
||||||
if (*arg == '\0' || *arg == ',')
|
|
||||||
unspec = 1;
|
|
||||||
else if (*arg == '=')
|
|
||||||
{
|
|
||||||
arg++;
|
arg++;
|
||||||
SKIPWS (arg);
|
var_len = arg - var;
|
||||||
}
|
|
||||||
|
SKIPWS (arg);
|
||||||
if (unspec)
|
|
||||||
{
|
if (*arg == '\0' || *arg == ',')
|
||||||
if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
|
unspec = 1;
|
||||||
{
|
else if (*arg == '=')
|
||||||
val = 0;
|
|
||||||
var += 3;
|
|
||||||
var_len -= 3;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
val = 1;
|
|
||||||
}
|
|
||||||
else if (isdigit (*arg))
|
|
||||||
{
|
|
||||||
val = atoi (arg);
|
|
||||||
while (isdigit (*arg))
|
|
||||||
arg++;
|
|
||||||
SKIPWS (arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (un = uparam_names; un->name; un++)
|
|
||||||
if (strlen (un->name) == var_len
|
|
||||||
&& strncmp (var, un->name, var_len) == 0)
|
|
||||||
{
|
{
|
||||||
if (unspec && !un->is_bool)
|
arg++;
|
||||||
__argp_failure (state, 0, 0,
|
SKIPWS (arg);
|
||||||
dgettext (state->root_argp->argp_domain, "\
|
|
||||||
%.*s: ARGP_HELP_FMT parameter requires a value"),
|
|
||||||
(int) var_len, var);
|
|
||||||
else
|
|
||||||
*(int *)((char *)&uparams + un->uparams_offs) = val;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (! un->name)
|
|
||||||
__argp_failure (state, 0, 0,
|
if (unspec)
|
||||||
dgettext (state->root_argp->argp_domain, "\
|
{
|
||||||
|
if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
|
||||||
|
{
|
||||||
|
val = 0;
|
||||||
|
var += 3;
|
||||||
|
var_len -= 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
val = 1;
|
||||||
|
}
|
||||||
|
else if (isdigit ((unsigned char) *arg))
|
||||||
|
{
|
||||||
|
val = atoi (arg);
|
||||||
|
while (isdigit ((unsigned char) *arg))
|
||||||
|
arg++;
|
||||||
|
SKIPWS (arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (un = uparam_names; un->name; un++)
|
||||||
|
if (strlen (un->name) == var_len
|
||||||
|
&& strncmp (var, un->name, var_len) == 0)
|
||||||
|
{
|
||||||
|
if (unspec && !un->is_bool)
|
||||||
|
__argp_failure (state, 0, 0,
|
||||||
|
dgettext (state->root_argp->argp_domain,
|
||||||
|
"\
|
||||||
|
%.*s: ARGP_HELP_FMT parameter requires a value"),
|
||||||
|
(int) var_len, var);
|
||||||
|
else if (val < 0)
|
||||||
|
__argp_failure (state, 0, 0,
|
||||||
|
dgettext (state->root_argp->argp_domain,
|
||||||
|
"\
|
||||||
|
%.*s: ARGP_HELP_FMT parameter must be positive"),
|
||||||
|
(int) var_len, var);
|
||||||
|
else
|
||||||
|
*(int *)((char *)&new_params + un->uparams_offs) = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (! un->name)
|
||||||
|
__argp_failure (state, 0, 0,
|
||||||
|
dgettext (state->root_argp->argp_domain, "\
|
||||||
%.*s: Unknown ARGP_HELP_FMT parameter"),
|
%.*s: Unknown ARGP_HELP_FMT parameter"),
|
||||||
(int) var_len, var);
|
(int) var_len, var);
|
||||||
|
|
||||||
var = arg;
|
var = arg;
|
||||||
if (*var == ',')
|
if (*var == ',')
|
||||||
var++;
|
var++;
|
||||||
}
|
}
|
||||||
else if (*var)
|
else if (*var)
|
||||||
{
|
{
|
||||||
__argp_failure (state, 0, 0,
|
__argp_failure (state, 0, 0,
|
||||||
dgettext (state->root_argp->argp_domain,
|
dgettext (state->root_argp->argp_domain,
|
||||||
"Garbage in ARGP_HELP_FMT: %s"), var);
|
"Garbage in ARGP_HELP_FMT: %s"), var);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
validate_uparams (state, &new_params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns true if OPT hasn't been marked invisible. Visibility only affects
|
/* Returns true if OPT hasn't been marked invisible. Visibility only affects
|
||||||
@ -340,6 +375,9 @@ struct hol_entry
|
|||||||
|
|
||||||
/* The argp from which this option came. */
|
/* The argp from which this option came. */
|
||||||
const struct argp *argp;
|
const struct argp *argp;
|
||||||
|
|
||||||
|
/* Position in the array */
|
||||||
|
unsigned ord;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A cluster of entries to reflect the argp tree structure. */
|
/* A cluster of entries to reflect the argp tree structure. */
|
||||||
@ -638,10 +676,12 @@ static int
|
|||||||
hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
|
hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
|
||||||
{
|
{
|
||||||
/* If one cluster is deeper than the other, use its ancestor at the same
|
/* If one cluster is deeper than the other, use its ancestor at the same
|
||||||
level, so that finding the common ancestor is straightforward. */
|
level, so that finding the common ancestor is straightforward.
|
||||||
while (cl1->depth < cl2->depth)
|
|
||||||
|
clN->depth > 0 means that clN->parent != NULL (see hol_add_cluster) */
|
||||||
|
while (cl1->depth > cl2->depth)
|
||||||
cl1 = cl1->parent;
|
cl1 = cl1->parent;
|
||||||
while (cl2->depth < cl1->depth)
|
while (cl2->depth > cl1->depth)
|
||||||
cl2 = cl2->parent;
|
cl2 = cl2->parent;
|
||||||
|
|
||||||
/* Now reduce both clusters to their ancestors at the point where both have
|
/* Now reduce both clusters to their ancestors at the point where both have
|
||||||
@ -685,17 +725,19 @@ canon_doc_option (const char **name)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Skip initial whitespace. */
|
/* Skip initial whitespace. */
|
||||||
while (isspace (**name))
|
while (isspace ((unsigned char) **name))
|
||||||
(*name)++;
|
(*name)++;
|
||||||
/* Decide whether this looks like an option (leading `-') or not. */
|
/* Decide whether this looks like an option (leading `-') or not. */
|
||||||
non_opt = (**name != '-');
|
non_opt = (**name != '-');
|
||||||
/* Skip until part of name used for sorting. */
|
/* Skip until part of name used for sorting. */
|
||||||
while (**name && !isalnum (**name))
|
while (**name && !isalnum ((unsigned char) **name))
|
||||||
(*name)++;
|
(*name)++;
|
||||||
}
|
}
|
||||||
return non_opt;
|
return non_opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define HOL_ENTRY_PTRCMP(a,b) ((a)->ord < (b)->ord ? -1 : 1)
|
||||||
|
|
||||||
/* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
|
/* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
|
||||||
listing. */
|
listing. */
|
||||||
static int
|
static int
|
||||||
@ -705,6 +747,7 @@ hol_entry_cmp (const struct hol_entry *entry1,
|
|||||||
/* The group numbers by which the entries should be ordered; if either is
|
/* The group numbers by which the entries should be ordered; if either is
|
||||||
in a cluster, then this is just the group within the cluster. */
|
in a cluster, then this is just the group within the cluster. */
|
||||||
int group1 = entry1->group, group2 = entry2->group;
|
int group1 = entry1->group, group2 = entry2->group;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (entry1->cluster != entry2->cluster)
|
if (entry1->cluster != entry2->cluster)
|
||||||
{
|
{
|
||||||
@ -721,7 +764,8 @@ hol_entry_cmp (const struct hol_entry *entry1,
|
|||||||
return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
|
return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
|
||||||
else
|
else
|
||||||
/* Both entries are in clusters, we can just compare the clusters. */
|
/* Both entries are in clusters, we can just compare the clusters. */
|
||||||
return hol_cluster_cmp (entry1->cluster, entry2->cluster);
|
return (rc = hol_cluster_cmp (entry1->cluster, entry2->cluster)) ?
|
||||||
|
rc : HOL_ENTRY_PTRCMP(entry1, entry2);
|
||||||
}
|
}
|
||||||
else if (group1 == group2)
|
else if (group1 == group2)
|
||||||
/* The entries are both in the same cluster and group, so compare them
|
/* The entries are both in the same cluster and group, so compare them
|
||||||
@ -745,7 +789,8 @@ hol_entry_cmp (const struct hol_entry *entry1,
|
|||||||
return doc1 - doc2;
|
return doc1 - doc2;
|
||||||
else if (!short1 && !short2 && long1 && long2)
|
else if (!short1 && !short2 && long1 && long2)
|
||||||
/* Only long options. */
|
/* Only long options. */
|
||||||
return __strcasecmp (long1, long2);
|
return (rc = __strcasecmp (long1, long2)) ?
|
||||||
|
rc : HOL_ENTRY_PTRCMP(entry1, entry2);
|
||||||
else
|
else
|
||||||
/* Compare short/short, long/short, short/long, using the first
|
/* Compare short/short, long/short, short/long, using the first
|
||||||
character of long options. Entries without *any* valid
|
character of long options. Entries without *any* valid
|
||||||
@ -762,13 +807,15 @@ hol_entry_cmp (const struct hol_entry *entry1,
|
|||||||
#endif
|
#endif
|
||||||
/* Compare ignoring case, except when the options are both the
|
/* Compare ignoring case, except when the options are both the
|
||||||
same letter, in which case lower-case always comes first. */
|
same letter, in which case lower-case always comes first. */
|
||||||
return lower_cmp ? lower_cmp : first2 - first1;
|
return lower_cmp ? lower_cmp :
|
||||||
|
(rc = first2 - first1) ?
|
||||||
|
rc : HOL_ENTRY_PTRCMP(entry1, entry2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Within the same cluster, but not the same group, so just compare
|
/* Within the same cluster, but not the same group, so just compare
|
||||||
groups. */
|
groups. */
|
||||||
return group_cmp (group1, group2, 0);
|
return group_cmp (group1, group2, HOL_ENTRY_PTRCMP(entry1, entry2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Version of hol_entry_cmp with correct signature for qsort. */
|
/* Version of hol_entry_cmp with correct signature for qsort. */
|
||||||
@ -785,8 +832,14 @@ static void
|
|||||||
hol_sort (struct hol *hol)
|
hol_sort (struct hol *hol)
|
||||||
{
|
{
|
||||||
if (hol->num_entries > 0)
|
if (hol->num_entries > 0)
|
||||||
qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
|
{
|
||||||
hol_entry_qcmp);
|
unsigned i;
|
||||||
|
struct hol_entry *e;
|
||||||
|
for (i = 0, e = hol->entries; i < hol->num_entries; i++, e++)
|
||||||
|
e->ord = i;
|
||||||
|
qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
|
||||||
|
hol_entry_qcmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow
|
/* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow
|
||||||
@ -1055,7 +1108,13 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
|
|||||||
int old_wm = __argp_fmtstream_wmargin (stream);
|
int old_wm = __argp_fmtstream_wmargin (stream);
|
||||||
/* PEST is a state block holding some of our variables that we'd like to
|
/* PEST is a state block holding some of our variables that we'd like to
|
||||||
share with helper functions. */
|
share with helper functions. */
|
||||||
struct pentry_state pest = { entry, stream, hhstate, 1, state };
|
struct pentry_state pest;
|
||||||
|
|
||||||
|
pest.entry = entry;
|
||||||
|
pest.stream = stream;
|
||||||
|
pest.hhstate = hhstate;
|
||||||
|
pest.first = 1;
|
||||||
|
pest.state = state;
|
||||||
|
|
||||||
if (! odoc (real))
|
if (! odoc (real))
|
||||||
for (opt = real, num = entry->num; num > 0; opt++, num--)
|
for (opt = real, num = entry->num; num > 0; opt++, num--)
|
||||||
@ -1263,7 +1322,7 @@ usage_long_opt (const struct argp_option *opt,
|
|||||||
if (! arg)
|
if (! arg)
|
||||||
arg = real->arg;
|
arg = real->arg;
|
||||||
|
|
||||||
if (! (flags & OPTION_NO_USAGE))
|
if (! (flags & OPTION_NO_USAGE) && !odoc (opt))
|
||||||
{
|
{
|
||||||
if (arg)
|
if (arg)
|
||||||
{
|
{
|
||||||
@ -1434,46 +1493,51 @@ argp_doc (const struct argp *argp, const struct argp_state *state,
|
|||||||
{
|
{
|
||||||
const char *text;
|
const char *text;
|
||||||
const char *inp_text;
|
const char *inp_text;
|
||||||
|
size_t inp_text_len = 0;
|
||||||
|
const char *trans_text;
|
||||||
void *input = 0;
|
void *input = 0;
|
||||||
int anything = 0;
|
int anything = 0;
|
||||||
size_t inp_text_limit = 0;
|
|
||||||
const char *doc = dgettext (argp->argp_domain, argp->doc);
|
|
||||||
const struct argp_child *child = argp->children;
|
const struct argp_child *child = argp->children;
|
||||||
|
|
||||||
if (doc)
|
if (argp->doc)
|
||||||
{
|
{
|
||||||
char *vt = strchr (doc, '\v');
|
char *vt = strchr (argp->doc, '\v');
|
||||||
inp_text = post ? (vt ? vt + 1 : 0) : doc;
|
if (vt)
|
||||||
inp_text_limit = (!post && vt) ? (vt - doc) : 0;
|
{
|
||||||
|
if (post)
|
||||||
|
inp_text = vt + 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inp_text_len = vt - argp->doc;
|
||||||
|
inp_text = __strndup (argp->doc, inp_text_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
inp_text = post ? 0 : argp->doc;
|
||||||
|
trans_text = inp_text ? dgettext (argp->argp_domain, inp_text) : NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
inp_text = 0;
|
trans_text = inp_text = 0;
|
||||||
|
|
||||||
if (argp->help_filter)
|
if (argp->help_filter)
|
||||||
/* We have to filter the doc strings. */
|
/* We have to filter the doc strings. */
|
||||||
{
|
{
|
||||||
if (inp_text_limit)
|
|
||||||
/* Copy INP_TEXT so that it's nul-terminated. */
|
|
||||||
inp_text = __strndup (inp_text, inp_text_limit);
|
|
||||||
input = __argp_input (argp, state);
|
input = __argp_input (argp, state);
|
||||||
text =
|
text =
|
||||||
(*argp->help_filter) (post
|
(*argp->help_filter) (post
|
||||||
? ARGP_KEY_HELP_POST_DOC
|
? ARGP_KEY_HELP_POST_DOC
|
||||||
: ARGP_KEY_HELP_PRE_DOC,
|
: ARGP_KEY_HELP_PRE_DOC,
|
||||||
inp_text, input);
|
trans_text, input);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
text = (const char *) inp_text;
|
text = (const char *) trans_text;
|
||||||
|
|
||||||
if (text)
|
if (text)
|
||||||
{
|
{
|
||||||
if (pre_blank)
|
if (pre_blank)
|
||||||
__argp_fmtstream_putc (stream, '\n');
|
__argp_fmtstream_putc (stream, '\n');
|
||||||
|
|
||||||
if (text == inp_text && inp_text_limit)
|
__argp_fmtstream_puts (stream, text);
|
||||||
__argp_fmtstream_write (stream, inp_text, inp_text_limit);
|
|
||||||
else
|
|
||||||
__argp_fmtstream_puts (stream, text);
|
|
||||||
|
|
||||||
if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
|
if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
|
||||||
__argp_fmtstream_putc (stream, '\n');
|
__argp_fmtstream_putc (stream, '\n');
|
||||||
@ -1481,9 +1545,10 @@ argp_doc (const struct argp *argp, const struct argp_state *state,
|
|||||||
anything = 1;
|
anything = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text && text != inp_text)
|
if (text && text != trans_text)
|
||||||
free ((char *) text); /* Free TEXT returned from the help filter. */
|
free ((char *) text); /* Free TEXT returned from the help filter. */
|
||||||
if (inp_text && inp_text_limit && argp->help_filter)
|
|
||||||
|
if (inp_text && inp_text_len)
|
||||||
free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */
|
free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */
|
||||||
|
|
||||||
if (post && argp->help_filter)
|
if (post && argp->help_filter)
|
||||||
@ -1663,7 +1728,10 @@ Try `%s --help' or `%s --usage' for more information.\n"),
|
|||||||
void __argp_help (const struct argp *argp, FILE *stream,
|
void __argp_help (const struct argp *argp, FILE *stream,
|
||||||
unsigned flags, char *name)
|
unsigned flags, char *name)
|
||||||
{
|
{
|
||||||
_help (argp, 0, stream, flags, name);
|
struct argp_state state;
|
||||||
|
memset (&state, 0, sizeof state);
|
||||||
|
state.root_argp = argp;
|
||||||
|
_help (argp, &state, stream, flags, name);
|
||||||
}
|
}
|
||||||
#ifdef weak_alias
|
#ifdef weak_alias
|
||||||
weak_alias (__argp_help, argp_help)
|
weak_alias (__argp_help, argp_help)
|
||||||
@ -1674,8 +1742,7 @@ char *
|
|||||||
__argp_short_program_name (void)
|
__argp_short_program_name (void)
|
||||||
{
|
{
|
||||||
# if HAVE_DECL_PROGRAM_INVOCATION_NAME
|
# if HAVE_DECL_PROGRAM_INVOCATION_NAME
|
||||||
char *name = strrchr (program_invocation_name, '/');
|
return __argp_base_name (program_invocation_name);
|
||||||
return name ? name + 1 : program_invocation_name;
|
|
||||||
# else
|
# else
|
||||||
/* FIXME: What now? Miles suggests that it is better to use NULL,
|
/* FIXME: What now? Miles suggests that it is better to use NULL,
|
||||||
but currently the value is passed on directly to fputs_unlocked,
|
but currently the value is passed on directly to fputs_unlocked,
|
||||||
@ -1739,7 +1806,8 @@ __argp_error (const struct argp_state *state, const char *fmt, ...)
|
|||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
__asprintf (&buf, fmt, ap);
|
if (__asprintf (&buf, fmt, ap) < 0)
|
||||||
|
buf = NULL;
|
||||||
|
|
||||||
__fwprintf (stream, L"%s: %s\n",
|
__fwprintf (stream, L"%s: %s\n",
|
||||||
state ? state->name : __argp_short_program_name (),
|
state ? state->name : __argp_short_program_name (),
|
||||||
@ -1817,7 +1885,8 @@ __argp_failure (const struct argp_state *state, int status, int errnum,
|
|||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
__asprintf (&buf, fmt, ap);
|
if (__asprintf (&buf, fmt, ap) < 0)
|
||||||
|
buf = NULL;
|
||||||
|
|
||||||
__fwprintf (stream, L": %s", buf);
|
__fwprintf (stream, L": %s", buf);
|
||||||
|
|
||||||
@ -1857,7 +1926,8 @@ __argp_failure (const struct argp_state *state, int status, int errnum,
|
|||||||
#endif
|
#endif
|
||||||
#if !_LIBC
|
#if !_LIBC
|
||||||
if (! s && ! (s = strerror (errnum)))
|
if (! s && ! (s = strerror (errnum)))
|
||||||
s = "Unknown system error"; /* FIXME: translate this */
|
s = dgettext (state->root_argp->argp_domain,
|
||||||
|
"Unknown system error");
|
||||||
#endif
|
#endif
|
||||||
fputs (s, stream);
|
fputs (s, stream);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Name frobnication for compiling argp outside of glibc
|
/* Name frobnication for compiling argp outside of glibc
|
||||||
Copyright (C) 1997, 2003 Free Software Foundation, Inc.
|
Copyright (C) 1997, 2003, 2007 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||||
|
|
||||||
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#if !_LIBC
|
#if !_LIBC
|
||||||
/* This code is written for inclusion in gnu-libc, and uses names in the
|
/* This code is written for inclusion in gnu-libc, and uses names in the
|
||||||
@ -76,11 +76,6 @@
|
|||||||
#undef __argp_fmtstream_wmargin
|
#undef __argp_fmtstream_wmargin
|
||||||
#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
|
#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
|
||||||
|
|
||||||
#include "mempcpy.h"
|
|
||||||
#include "strcase.h"
|
|
||||||
#include "strchrnul.h"
|
|
||||||
#include "strndup.h"
|
|
||||||
|
|
||||||
/* normal libc functions we call */
|
/* normal libc functions we call */
|
||||||
#undef __flockfile
|
#undef __flockfile
|
||||||
#define __flockfile flockfile
|
#define __flockfile flockfile
|
||||||
@ -141,14 +136,21 @@
|
|||||||
# define putchar_unlocked(x) putchar (x)
|
# define putchar_unlocked(x) putchar (x)
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
extern char *__argp_basename (char *name);
|
|
||||||
|
|
||||||
#endif /* !_LIBC */
|
#endif /* !_LIBC */
|
||||||
|
|
||||||
#ifndef __set_errno
|
#ifndef __set_errno
|
||||||
#define __set_errno(e) (errno = (e))
|
#define __set_errno(e) (errno = (e))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined GNULIB_ARGP_DISABLE_DIRNAME
|
||||||
|
# define __argp_base_name(arg) arg
|
||||||
|
#elif defined GNULIB_ARGP_EXTERN_BASENAME
|
||||||
|
extern char *__argp_base_name(const char *arg);
|
||||||
|
#else
|
||||||
|
# include "dirname.h"
|
||||||
|
# define __argp_base_name base_name
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
|
#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
|
||||||
# define __argp_short_program_name() (program_invocation_short_name)
|
# define __argp_short_program_name() (program_invocation_short_name)
|
||||||
#else
|
#else
|
||||||
|
@ -15,13 +15,14 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -37,11 +38,14 @@
|
|||||||
#else
|
#else
|
||||||
# include "gettext.h"
|
# include "gettext.h"
|
||||||
#endif
|
#endif
|
||||||
#define N_(msgid) (msgid)
|
#define N_(msgid) msgid
|
||||||
|
|
||||||
#include "argp.h"
|
#include "argp.h"
|
||||||
#include "argp-namefrob.h"
|
#include "argp-namefrob.h"
|
||||||
|
|
||||||
|
#define alignof(type) offsetof (struct { char c; type x; }, x)
|
||||||
|
#define alignto(n, d) ((((n) + (d) - 1) / (d)) * (d))
|
||||||
|
|
||||||
/* Getopt return values. */
|
/* Getopt return values. */
|
||||||
#define KEY_END (-1) /* The end of the options. */
|
#define KEY_END (-1) /* The end of the options. */
|
||||||
#define KEY_ARG 1 /* A non-option argument. */
|
#define KEY_ARG 1 /* A non-option argument. */
|
||||||
@ -75,11 +79,11 @@ static volatile int _argp_hang;
|
|||||||
|
|
||||||
static const struct argp_option argp_default_options[] =
|
static const struct argp_option argp_default_options[] =
|
||||||
{
|
{
|
||||||
{"help", '?', 0, 0, N_("Give this help list"), -1},
|
{"help", '?', 0, 0, N_("give this help list"), -1},
|
||||||
{"usage", OPT_USAGE, 0, 0, N_("Give a short usage message"), 0},
|
{"usage", OPT_USAGE, 0, 0, N_("give a short usage message"), 0},
|
||||||
{"program-name",OPT_PROGNAME,"NAME", OPTION_HIDDEN, N_("Set the program name"), 0},
|
{"program-name",OPT_PROGNAME,N_("NAME"), OPTION_HIDDEN, N_("set the program name"), 0},
|
||||||
{"HANG", OPT_HANG, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
|
{"HANG", OPT_HANG, N_("SECS"), OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
|
||||||
N_("Hang for SECS seconds (default 3600)"), 0},
|
N_("hang for SECS seconds (default 3600)"), 0},
|
||||||
{NULL, 0, 0, 0, NULL, 0}
|
{NULL, 0, 0, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,7 +97,7 @@ argp_default_parser (int key, char *arg, struct argp_state *state)
|
|||||||
break;
|
break;
|
||||||
case OPT_USAGE:
|
case OPT_USAGE:
|
||||||
__argp_state_help (state, state->out_stream,
|
__argp_state_help (state, state->out_stream,
|
||||||
ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
|
ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPT_PROGNAME: /* Set the program name. */
|
case OPT_PROGNAME: /* Set the program name. */
|
||||||
@ -105,11 +109,7 @@ argp_default_parser (int key, char *arg, struct argp_state *state)
|
|||||||
to be that, so we have to be a bit careful here.] */
|
to be that, so we have to be a bit careful here.] */
|
||||||
|
|
||||||
/* Update what we use for messages. */
|
/* Update what we use for messages. */
|
||||||
state->name = strrchr (arg, '/');
|
state->name = __argp_base_name (arg);
|
||||||
if (state->name)
|
|
||||||
state->name++;
|
|
||||||
else
|
|
||||||
state->name = arg;
|
|
||||||
|
|
||||||
#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
|
#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
|
||||||
program_invocation_short_name = state->name;
|
program_invocation_short_name = state->name;
|
||||||
@ -140,7 +140,7 @@ static const struct argp argp_default_argp =
|
|||||||
|
|
||||||
static const struct argp_option argp_version_options[] =
|
static const struct argp_option argp_version_options[] =
|
||||||
{
|
{
|
||||||
{"version", 'V', 0, 0, N_("Print program version"), -1},
|
{"version", 'V', 0, 0, N_("print program version"), -1},
|
||||||
{NULL, 0, 0, 0, NULL, 0}
|
{NULL, 0, 0, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -462,6 +462,11 @@ parser_init (struct parser *parser, const struct argp *argp,
|
|||||||
struct group *group;
|
struct group *group;
|
||||||
struct parser_sizes szs;
|
struct parser_sizes szs;
|
||||||
struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER;
|
struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER;
|
||||||
|
char *storage;
|
||||||
|
size_t glen, gsum;
|
||||||
|
size_t clen, csum;
|
||||||
|
size_t llen, lsum;
|
||||||
|
size_t slen, ssum;
|
||||||
|
|
||||||
szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1;
|
szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1;
|
||||||
szs.long_len = 0;
|
szs.long_len = 0;
|
||||||
@ -472,22 +477,33 @@ parser_init (struct parser *parser, const struct argp *argp,
|
|||||||
calc_sizes (argp, &szs);
|
calc_sizes (argp, &szs);
|
||||||
|
|
||||||
/* Lengths of the various bits of storage used by PARSER. */
|
/* Lengths of the various bits of storage used by PARSER. */
|
||||||
#define GLEN (szs.num_groups + 1) * sizeof (struct group)
|
glen = (szs.num_groups + 1) * sizeof (struct group);
|
||||||
#define CLEN (szs.num_child_inputs * sizeof (void *))
|
clen = szs.num_child_inputs * sizeof (void *);
|
||||||
#define LLEN ((szs.long_len + 1) * sizeof (struct option))
|
llen = (szs.long_len + 1) * sizeof (struct option);
|
||||||
#define SLEN (szs.short_len + 1)
|
slen = szs.short_len + 1;
|
||||||
|
|
||||||
parser->storage = malloc (GLEN + CLEN + LLEN + SLEN);
|
/* Sums of previous lengths, properly aligned. There's no need to
|
||||||
|
align gsum, since struct group is aligned at least as strictly as
|
||||||
|
void * (since it contains a void * member). And there's no need
|
||||||
|
to align lsum, since struct option is aligned at least as
|
||||||
|
strictly as char. */
|
||||||
|
gsum = glen;
|
||||||
|
csum = alignto (gsum + clen, alignof (struct option));
|
||||||
|
lsum = csum + llen;
|
||||||
|
ssum = lsum + slen;
|
||||||
|
|
||||||
|
parser->storage = malloc (ssum);
|
||||||
if (! parser->storage)
|
if (! parser->storage)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
|
storage = parser->storage;
|
||||||
parser->groups = parser->storage;
|
parser->groups = parser->storage;
|
||||||
parser->child_inputs = parser->storage + GLEN;
|
parser->child_inputs = (void **) (storage + gsum);
|
||||||
parser->long_opts = parser->storage + GLEN + CLEN;
|
parser->long_opts = (struct option *) (storage + csum);
|
||||||
parser->short_opts = parser->storage + GLEN + CLEN + LLEN;
|
parser->short_opts = storage + lsum;
|
||||||
parser->opt_data = opt_data;
|
parser->opt_data = opt_data;
|
||||||
|
|
||||||
memset (parser->child_inputs, 0, szs.num_child_inputs * sizeof (void *));
|
memset (parser->child_inputs, 0, clen);
|
||||||
parser_convert (parser, argp, flags);
|
parser_convert (parser, argp, flags);
|
||||||
|
|
||||||
memset (&parser->state, 0, sizeof (struct argp_state));
|
memset (&parser->state, 0, sizeof (struct argp_state));
|
||||||
@ -542,10 +558,7 @@ parser_init (struct parser *parser, const struct argp *argp,
|
|||||||
|
|
||||||
if (parser->state.argv == argv && argv[0])
|
if (parser->state.argv == argv && argv[0])
|
||||||
/* There's an argv[0]; use it for messages. */
|
/* There's an argv[0]; use it for messages. */
|
||||||
{
|
parser->state.name = __argp_base_name (argv[0]);
|
||||||
char *short_name = strrchr (argv[0], '/');
|
|
||||||
parser->state.name = short_name ? short_name + 1 : argv[0];
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
parser->state.name = __argp_short_program_name ();
|
parser->state.name = __argp_short_program_name ();
|
||||||
|
|
||||||
@ -864,6 +877,20 @@ __argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags,
|
|||||||
to be parsed (which in some cases isn't actually an error). */
|
to be parsed (which in some cases isn't actually an error). */
|
||||||
int arg_ebadkey = 0;
|
int arg_ebadkey = 0;
|
||||||
|
|
||||||
|
#ifndef _LIBC
|
||||||
|
if (!(flags & ARGP_PARSE_ARGV0))
|
||||||
|
{
|
||||||
|
#ifdef HAVE_DECL_PROGRAM_INVOCATION_NAME
|
||||||
|
if (!program_invocation_name)
|
||||||
|
program_invocation_name = argv[0];
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
|
||||||
|
if (!program_invocation_short_name)
|
||||||
|
program_invocation_short_name = __argp_base_name (argv[0]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (! (flags & ARGP_NO_HELP))
|
if (! (flags & ARGP_NO_HELP))
|
||||||
/* Add our own options. */
|
/* Add our own options. */
|
||||||
{
|
{
|
||||||
|
28
lib/argp-pin.c
Normal file
28
lib/argp-pin.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/* Full and short program names for argp module
|
||||||
|
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program 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 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME
|
||||||
|
char *program_invocation_short_name = 0;
|
||||||
|
#endif
|
||||||
|
#ifndef HAVE_PROGRAM_INVOCATION_NAME
|
||||||
|
char *program_invocation_name = 0;
|
||||||
|
#endif
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/* Default definition for ARGP_PROGRAM_VERSION.
|
/* Default definition for ARGP_PROGRAM_VERSION.
|
||||||
Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
|
Copyright (C) 1996, 1997, 1999, 2006 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||||
|
|
||||||
@ -15,10 +15,10 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
/* If set by the user program to a non-zero value, then a default option
|
/* If set by the user program to a non-zero value, then a default option
|
||||||
--version is added (unless the ARGP_NO_HELP flag is used), which will
|
--version is added (unless the ARGP_NO_HELP flag is used), which will
|
||||||
print this this string followed by a newline and exit (unless the
|
print this string followed by a newline and exit (unless the
|
||||||
ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
|
ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
|
||||||
const char *argp_program_version;
|
const char *argp_program_version;
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "argp.h"
|
#include "argp.h"
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined _LIBC || defined HAVE_FEATURES_H
|
#if defined _LIBC || defined HAVE_FEATURES_H
|
||||||
|
124
lib/argp.h
124
lib/argp.h
@ -1,5 +1,5 @@
|
|||||||
/* Hierarchial argument parsing, layered over getopt.
|
/* Hierarchial argument parsing, layered over getopt.
|
||||||
Copyright (C) 1995-1999,2003,2004 Free Software Foundation, Inc.
|
Copyright (C) 1995-1999,2003-2007 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
Written by Miles Bader <miles@gnu.ai.mit.edu>.
|
||||||
|
|
||||||
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifndef _ARGP_H
|
#ifndef _ARGP_H
|
||||||
#define _ARGP_H
|
#define _ARGP_H
|
||||||
@ -23,14 +23,11 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#define __need_error_t
|
#define __need_error_t
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#ifndef __const
|
|
||||||
# define __const const
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __THROW
|
#ifndef __THROW
|
||||||
# define __THROW
|
# define __THROW
|
||||||
#endif
|
#endif
|
||||||
@ -52,10 +49,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* GCC 2.95 and later have "__restrict"; C99 compilers have
|
/* GCC 2.95 and later have "__restrict"; C99 compilers have
|
||||||
"restrict", and "configure" may have defined "restrict". */
|
"restrict", and "configure" may have defined "restrict".
|
||||||
|
Other compilers use __restrict, __restrict__, and _Restrict, and
|
||||||
|
'configure' might #define 'restrict' to those words. */
|
||||||
#ifndef __restrict
|
#ifndef __restrict
|
||||||
# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
|
# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
|
||||||
# if defined restrict || 199901L <= __STDC_VERSION__
|
# if 199901L <= __STDC_VERSION__
|
||||||
# define __restrict restrict
|
# define __restrict restrict
|
||||||
# else
|
# else
|
||||||
# define __restrict
|
# define __restrict
|
||||||
@ -81,7 +80,7 @@ struct argp_option
|
|||||||
{
|
{
|
||||||
/* The long option name. For more than one name for the same option, you
|
/* The long option name. For more than one name for the same option, you
|
||||||
can use following options with the OPTION_ALIAS flag set. */
|
can use following options with the OPTION_ALIAS flag set. */
|
||||||
__const char *name;
|
const char *name;
|
||||||
|
|
||||||
/* What key is returned for this option. If > 0 and printable, then it's
|
/* What key is returned for this option. If > 0 and printable, then it's
|
||||||
also accepted as a short option. */
|
also accepted as a short option. */
|
||||||
@ -89,7 +88,7 @@ struct argp_option
|
|||||||
|
|
||||||
/* If non-NULL, this is the name of the argument associated with this
|
/* If non-NULL, this is the name of the argument associated with this
|
||||||
option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */
|
option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */
|
||||||
__const char *arg;
|
const char *arg;
|
||||||
|
|
||||||
/* OPTION_ flags. */
|
/* OPTION_ flags. */
|
||||||
int flags;
|
int flags;
|
||||||
@ -97,8 +96,11 @@ struct argp_option
|
|||||||
/* The doc string for this option. If both NAME and KEY are 0, This string
|
/* The doc string for this option. If both NAME and KEY are 0, This string
|
||||||
will be printed outdented from the normal option column, making it
|
will be printed outdented from the normal option column, making it
|
||||||
useful as a group header (it will be the first thing printed in its
|
useful as a group header (it will be the first thing printed in its
|
||||||
group); in this usage, it's conventional to end the string with a `:'. */
|
group); in this usage, it's conventional to end the string with a `:'.
|
||||||
__const char *doc;
|
|
||||||
|
Write the initial value as N_("TEXT") if you want xgettext to collect
|
||||||
|
it into a POT file. */
|
||||||
|
const char *doc;
|
||||||
|
|
||||||
/* The group this option is in. In a long help message, options are sorted
|
/* The group this option is in. In a long help message, options are sorted
|
||||||
alphabetically within each group, and the groups presented in the order
|
alphabetically within each group, and the groups presented in the order
|
||||||
@ -226,7 +228,7 @@ struct argp
|
|||||||
{
|
{
|
||||||
/* An array of argp_option structures, terminated by an entry with both
|
/* An array of argp_option structures, terminated by an entry with both
|
||||||
NAME and KEY having a value of 0. */
|
NAME and KEY having a value of 0. */
|
||||||
__const struct argp_option *options;
|
const struct argp_option *options;
|
||||||
|
|
||||||
/* What to do with an option from this structure. KEY is the key
|
/* What to do with an option from this structure. KEY is the key
|
||||||
associated with the option, and ARG is any associated argument (NULL if
|
associated with the option, and ARG is any associated argument (NULL if
|
||||||
@ -242,12 +244,14 @@ struct argp
|
|||||||
contains newlines, the strings separated by them are considered
|
contains newlines, the strings separated by them are considered
|
||||||
alternative usage patterns, and printed on separate lines (lines after
|
alternative usage patterns, and printed on separate lines (lines after
|
||||||
the first are prefix by ` or: ' instead of `Usage:'). */
|
the first are prefix by ` or: ' instead of `Usage:'). */
|
||||||
__const char *args_doc;
|
const char *args_doc;
|
||||||
|
|
||||||
/* If non-NULL, a string containing extra text to be printed before and
|
/* If non-NULL, a string containing extra text to be printed before and
|
||||||
after the options in a long help message (separated by a vertical tab
|
after the options in a long help message (separated by a vertical tab
|
||||||
`\v' character). */
|
`\v' character).
|
||||||
__const char *doc;
|
Write the initial value as N_("BEFORE-TEXT") "\v" N_("AFTER-TEXT") if
|
||||||
|
you want xgettext to collect the two pieces of text into a POT file. */
|
||||||
|
const char *doc;
|
||||||
|
|
||||||
/* A vector of argp_children structures, terminated by a member with a 0
|
/* A vector of argp_children structures, terminated by a member with a 0
|
||||||
argp field, pointing to child argps should be parsed with this one. Any
|
argp field, pointing to child argps should be parsed with this one. Any
|
||||||
@ -255,7 +259,7 @@ struct argp
|
|||||||
CHILDREN list. This field is useful if you use libraries that supply
|
CHILDREN list. This field is useful if you use libraries that supply
|
||||||
their own argp structure, which you want to use in conjunction with your
|
their own argp structure, which you want to use in conjunction with your
|
||||||
own. */
|
own. */
|
||||||
__const struct argp_child *children;
|
const struct argp_child *children;
|
||||||
|
|
||||||
/* If non-zero, this should be a function to filter the output of help
|
/* If non-zero, this should be a function to filter the output of help
|
||||||
messages. KEY is either a key from an option, in which case TEXT is
|
messages. KEY is either a key from an option, in which case TEXT is
|
||||||
@ -267,7 +271,7 @@ struct argp
|
|||||||
has been done, so if any of the replacement text also needs translation,
|
has been done, so if any of the replacement text also needs translation,
|
||||||
that should be done by the filter function. INPUT is either the input
|
that should be done by the filter function. INPUT is either the input
|
||||||
supplied to argp_parse, or NULL, if argp_help was called directly. */
|
supplied to argp_parse, or NULL, if argp_help was called directly. */
|
||||||
char *(*help_filter) (int __key, __const char *__text, void *__input);
|
char *(*help_filter) (int __key, const char *__text, void *__input);
|
||||||
|
|
||||||
/* If non-zero the strings used in the argp library are translated using
|
/* If non-zero the strings used in the argp library are translated using
|
||||||
the domain described by this string. Otherwise the currently installed
|
the domain described by this string. Otherwise the currently installed
|
||||||
@ -291,7 +295,7 @@ struct argp
|
|||||||
struct argp_child
|
struct argp_child
|
||||||
{
|
{
|
||||||
/* The child parser. */
|
/* The child parser. */
|
||||||
__const struct argp *argp;
|
const struct argp *argp;
|
||||||
|
|
||||||
/* Flags for this child. */
|
/* Flags for this child. */
|
||||||
int flags;
|
int flags;
|
||||||
@ -300,7 +304,7 @@ struct argp_child
|
|||||||
child options. As a side-effect, a non-zero value forces the child
|
child options. As a side-effect, a non-zero value forces the child
|
||||||
options to be grouped together; to achieve this effect without actually
|
options to be grouped together; to achieve this effect without actually
|
||||||
printing a header string, use a value of "". */
|
printing a header string, use a value of "". */
|
||||||
__const char *header;
|
const char *header;
|
||||||
|
|
||||||
/* Where to group the child options relative to the other (`consolidated')
|
/* Where to group the child options relative to the other (`consolidated')
|
||||||
options in the parent argp; the values are the same as the GROUP field
|
options in the parent argp; the values are the same as the GROUP field
|
||||||
@ -316,7 +320,7 @@ struct argp_child
|
|||||||
struct argp_state
|
struct argp_state
|
||||||
{
|
{
|
||||||
/* The top level ARGP being parsed. */
|
/* The top level ARGP being parsed. */
|
||||||
__const struct argp *root_argp;
|
const struct argp *root_argp;
|
||||||
|
|
||||||
/* The argument vector being parsed. May be modified. */
|
/* The argument vector being parsed. May be modified. */
|
||||||
int argc;
|
int argc;
|
||||||
@ -410,22 +414,36 @@ struct argp_state
|
|||||||
routine returned a non-zero value, it is returned; otherwise 0 is
|
routine returned a non-zero value, it is returned; otherwise 0 is
|
||||||
returned. This function may also call exit unless the ARGP_NO_HELP flag
|
returned. This function may also call exit unless the ARGP_NO_HELP flag
|
||||||
is set. INPUT is a pointer to a value to be passed in to the parser. */
|
is set. INPUT is a pointer to a value to be passed in to the parser. */
|
||||||
extern error_t argp_parse (__const struct argp *__restrict __argp,
|
extern error_t argp_parse (const struct argp *__restrict __argp,
|
||||||
int __argc, char **__restrict __argv,
|
int /*argc*/, char **__restrict /*argv*/,
|
||||||
unsigned __flags, int *__restrict __arg_index,
|
unsigned __flags, int *__restrict __arg_index,
|
||||||
void *__restrict __input);
|
void *__restrict __input);
|
||||||
extern error_t __argp_parse (__const struct argp *__restrict __argp,
|
extern error_t __argp_parse (const struct argp *__restrict __argp,
|
||||||
int __argc, char **__restrict __argv,
|
int /*argc*/, char **__restrict /*argv*/,
|
||||||
unsigned __flags, int *__restrict __arg_index,
|
unsigned __flags, int *__restrict __arg_index,
|
||||||
void *__restrict __input);
|
void *__restrict __input);
|
||||||
|
|
||||||
/* Global variables. */
|
/* Global variables. */
|
||||||
|
|
||||||
|
/* GNULIB makes sure both program_invocation_name and
|
||||||
|
program_invocation_short_name are available */
|
||||||
|
#ifdef GNULIB_PROGRAM_INVOCATION_NAME
|
||||||
|
extern char *program_invocation_name;
|
||||||
|
# undef HAVE_DECL_PROGRAM_INVOCATION_NAME
|
||||||
|
# define HAVE_DECL_PROGRAM_INVOCATION_NAME 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GNULIB_PROGRAM_INVOCATION_SHORT_NAME
|
||||||
|
extern char *program_invocation_short_name;
|
||||||
|
# undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
|
||||||
|
# define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If defined or set by the user program to a non-zero value, then a default
|
/* If defined or set by the user program to a non-zero value, then a default
|
||||||
option --version is added (unless the ARGP_NO_HELP flag is used), which
|
option --version is added (unless the ARGP_NO_HELP flag is used), which
|
||||||
will print this string followed by a newline and exit (unless the
|
will print this string followed by a newline and exit (unless the
|
||||||
ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
|
ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
|
||||||
extern __const char *argp_program_version;
|
extern const char *argp_program_version;
|
||||||
|
|
||||||
/* If defined or set by the user program to a non-zero value, then a default
|
/* If defined or set by the user program to a non-zero value, then a default
|
||||||
option --version is added (unless the ARGP_NO_HELP flag is used), which
|
option --version is added (unless the ARGP_NO_HELP flag is used), which
|
||||||
@ -441,7 +459,7 @@ extern void (*argp_program_version_hook) (FILE *__restrict __stream,
|
|||||||
argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various
|
argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various
|
||||||
standard help messages), embedded in a sentence that says something like
|
standard help messages), embedded in a sentence that says something like
|
||||||
`Report bugs to ADDR.'. */
|
`Report bugs to ADDR.'. */
|
||||||
extern __const char *argp_program_bug_address;
|
extern const char *argp_program_bug_address;
|
||||||
|
|
||||||
/* The exit status that argp will use when exiting due to a parsing error.
|
/* The exit status that argp will use when exiting due to a parsing error.
|
||||||
If not defined or set by the user program, this defaults to EX_USAGE from
|
If not defined or set by the user program, this defaults to EX_USAGE from
|
||||||
@ -479,10 +497,10 @@ extern error_t argp_err_exit_status;
|
|||||||
|
|
||||||
/* Output a usage message for ARGP to STREAM. FLAGS are from the set
|
/* Output a usage message for ARGP to STREAM. FLAGS are from the set
|
||||||
ARGP_HELP_*. */
|
ARGP_HELP_*. */
|
||||||
extern void argp_help (__const struct argp *__restrict __argp,
|
extern void argp_help (const struct argp *__restrict __argp,
|
||||||
FILE *__restrict __stream,
|
FILE *__restrict __stream,
|
||||||
unsigned __flags, char *__restrict __name);
|
unsigned __flags, char *__restrict __name);
|
||||||
extern void __argp_help (__const struct argp *__restrict __argp,
|
extern void __argp_help (const struct argp *__restrict __argp,
|
||||||
FILE *__restrict __stream, unsigned __flags,
|
FILE *__restrict __stream, unsigned __flags,
|
||||||
char *__name);
|
char *__name);
|
||||||
|
|
||||||
@ -496,25 +514,25 @@ extern void __argp_help (__const struct argp *__restrict __argp,
|
|||||||
|
|
||||||
/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
|
/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
|
||||||
from the set ARGP_HELP_*. */
|
from the set ARGP_HELP_*. */
|
||||||
extern void argp_state_help (__const struct argp_state *__restrict __state,
|
extern void argp_state_help (const struct argp_state *__restrict __state,
|
||||||
FILE *__restrict __stream,
|
FILE *__restrict __stream,
|
||||||
unsigned int __flags);
|
unsigned int __flags);
|
||||||
extern void __argp_state_help (__const struct argp_state *__restrict __state,
|
extern void __argp_state_help (const struct argp_state *__restrict __state,
|
||||||
FILE *__restrict __stream,
|
FILE *__restrict __stream,
|
||||||
unsigned int __flags);
|
unsigned int __flags);
|
||||||
|
|
||||||
/* Possibly output the standard usage message for ARGP to stderr and exit. */
|
/* Possibly output the standard usage message for ARGP to stderr and exit. */
|
||||||
extern void argp_usage (__const struct argp_state *__state);
|
extern void argp_usage (const struct argp_state *__state);
|
||||||
extern void __argp_usage (__const struct argp_state *__state);
|
extern void __argp_usage (const struct argp_state *__state);
|
||||||
|
|
||||||
/* If appropriate, print the printf string FMT and following args, preceded
|
/* If appropriate, print the printf string FMT and following args, preceded
|
||||||
by the program name and `:', to stderr, and followed by a `Try ... --help'
|
by the program name and `:', to stderr, and followed by a `Try ... --help'
|
||||||
message, then exit (1). */
|
message, then exit (1). */
|
||||||
extern void argp_error (__const struct argp_state *__restrict __state,
|
extern void argp_error (const struct argp_state *__restrict __state,
|
||||||
__const char *__restrict __fmt, ...)
|
const char *__restrict __fmt, ...)
|
||||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||||
extern void __argp_error (__const struct argp_state *__restrict __state,
|
extern void __argp_error (const struct argp_state *__restrict __state,
|
||||||
__const char *__restrict __fmt, ...)
|
const char *__restrict __fmt, ...)
|
||||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||||
|
|
||||||
/* Similar to the standard gnu error-reporting function error(), but will
|
/* Similar to the standard gnu error-reporting function error(), but will
|
||||||
@ -525,31 +543,31 @@ extern void __argp_error (__const struct argp_state *__restrict __state,
|
|||||||
difference between this function and argp_error is that the latter is for
|
difference between this function and argp_error is that the latter is for
|
||||||
*parsing errors*, and the former is for other problems that occur during
|
*parsing errors*, and the former is for other problems that occur during
|
||||||
parsing but don't reflect a (syntactic) problem with the input. */
|
parsing but don't reflect a (syntactic) problem with the input. */
|
||||||
extern void argp_failure (__const struct argp_state *__restrict __state,
|
extern void argp_failure (const struct argp_state *__restrict __state,
|
||||||
int __status, int __errnum,
|
int __status, int __errnum,
|
||||||
__const char *__restrict __fmt, ...)
|
const char *__restrict __fmt, ...)
|
||||||
__attribute__ ((__format__ (__printf__, 4, 5)));
|
__attribute__ ((__format__ (__printf__, 4, 5)));
|
||||||
extern void __argp_failure (__const struct argp_state *__restrict __state,
|
extern void __argp_failure (const struct argp_state *__restrict __state,
|
||||||
int __status, int __errnum,
|
int __status, int __errnum,
|
||||||
__const char *__restrict __fmt, ...)
|
const char *__restrict __fmt, ...)
|
||||||
__attribute__ ((__format__ (__printf__, 4, 5)));
|
__attribute__ ((__format__ (__printf__, 4, 5)));
|
||||||
|
|
||||||
/* Returns true if the option OPT is a valid short option. */
|
/* Returns true if the option OPT is a valid short option. */
|
||||||
extern int _option_is_short (__const struct argp_option *__opt) __THROW;
|
extern int _option_is_short (const struct argp_option *__opt) __THROW;
|
||||||
extern int __option_is_short (__const struct argp_option *__opt) __THROW;
|
extern int __option_is_short (const struct argp_option *__opt) __THROW;
|
||||||
|
|
||||||
/* Returns true if the option OPT is in fact the last (unused) entry in an
|
/* Returns true if the option OPT is in fact the last (unused) entry in an
|
||||||
options array. */
|
options array. */
|
||||||
extern int _option_is_end (__const struct argp_option *__opt) __THROW;
|
extern int _option_is_end (const struct argp_option *__opt) __THROW;
|
||||||
extern int __option_is_end (__const struct argp_option *__opt) __THROW;
|
extern int __option_is_end (const struct argp_option *__opt) __THROW;
|
||||||
|
|
||||||
/* Return the input field for ARGP in the parser corresponding to STATE; used
|
/* Return the input field for ARGP in the parser corresponding to STATE; used
|
||||||
by the help routines. */
|
by the help routines. */
|
||||||
extern void *_argp_input (__const struct argp *__restrict __argp,
|
extern void *_argp_input (const struct argp *__restrict __argp,
|
||||||
__const struct argp_state *__restrict __state)
|
const struct argp_state *__restrict __state)
|
||||||
__THROW;
|
__THROW;
|
||||||
extern void *__argp_input (__const struct argp *__restrict __argp,
|
extern void *__argp_input (const struct argp *__restrict __argp,
|
||||||
__const struct argp_state *__restrict __state)
|
const struct argp_state *__restrict __state)
|
||||||
__THROW;
|
__THROW;
|
||||||
|
|
||||||
#ifdef __USE_EXTERN_INLINES
|
#ifdef __USE_EXTERN_INLINES
|
||||||
@ -566,25 +584,25 @@ extern void *__argp_input (__const struct argp *__restrict __argp,
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
ARGP_EI void
|
ARGP_EI void
|
||||||
__NTH (__argp_usage (__const struct argp_state *__state))
|
__argp_usage (const struct argp_state *__state)
|
||||||
{
|
{
|
||||||
__argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE);
|
__argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ARGP_EI int
|
ARGP_EI int
|
||||||
__NTH (__option_is_short (__const struct argp_option *__opt))
|
__NTH (__option_is_short (const struct argp_option *__opt))
|
||||||
{
|
{
|
||||||
if (__opt->flags & OPTION_DOC)
|
if (__opt->flags & OPTION_DOC)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int __key = __opt->key;
|
int __key = __opt->key;
|
||||||
return __key > 0 && isprint (__key);
|
return __key > 0 && __key <= UCHAR_MAX && isprint (__key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ARGP_EI int
|
ARGP_EI int
|
||||||
__NTH (__option_is_end (__const struct argp_option *__opt))
|
__NTH (__option_is_end (const struct argp_option *__opt))
|
||||||
{
|
{
|
||||||
return !__opt->key && !__opt->name && !__opt->doc && !__opt->group;
|
return !__opt->key && !__opt->name && !__opt->doc && !__opt->group;
|
||||||
}
|
}
|
||||||
|
112
lib/basename.c
112
lib/basename.c
@ -1,6 +1,6 @@
|
|||||||
/* basename.c -- return the last element in a path
|
/* basename.c -- return the last element in a file name
|
||||||
|
|
||||||
Copyright (C) 1990, 1998, 1999, 2000, 2001, 2003, 2004 Free
|
Copyright (C) 1990, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006 Free
|
||||||
Software Foundation, Inc.
|
Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
@ -15,65 +15,115 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
#include <config.h>
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "dirname.h"
|
#include "dirname.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "xalloc.h"
|
||||||
|
#include "xstrndup.h"
|
||||||
|
|
||||||
/* In general, we can't use the builtin `basename' function if available,
|
/* Return the address of the last file name component of NAME. If
|
||||||
since it has different meanings in different environments.
|
NAME has no relative file name components because it is a file
|
||||||
In some environments the builtin `basename' modifies its argument.
|
system root, return the empty string. */
|
||||||
|
|
||||||
Return the address of the last file name component of NAME. If
|
|
||||||
NAME has no file name components because it is all slashes, return
|
|
||||||
NAME if it is empty, the address of its last slash otherwise. */
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
base_name (char const *name)
|
last_component (char const *name)
|
||||||
{
|
{
|
||||||
char const *base = name + FILE_SYSTEM_PREFIX_LEN (name);
|
char const *base = name + FILE_SYSTEM_PREFIX_LEN (name);
|
||||||
char const *p;
|
char const *p;
|
||||||
|
bool saw_slash = false;
|
||||||
|
|
||||||
|
while (ISSLASH (*base))
|
||||||
|
base++;
|
||||||
|
|
||||||
for (p = base; *p; p++)
|
for (p = base; *p; p++)
|
||||||
{
|
{
|
||||||
if (ISSLASH (*p))
|
if (ISSLASH (*p))
|
||||||
|
saw_slash = true;
|
||||||
|
else if (saw_slash)
|
||||||
{
|
{
|
||||||
/* Treat multiple adjacent slashes like a single slash. */
|
|
||||||
do p++;
|
|
||||||
while (ISSLASH (*p));
|
|
||||||
|
|
||||||
/* If the file name ends in slash, use the trailing slash as
|
|
||||||
the basename if no non-slashes have been found. */
|
|
||||||
if (! *p)
|
|
||||||
{
|
|
||||||
if (ISSLASH (*base))
|
|
||||||
base = p - 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* *P is a non-slash preceded by a slash. */
|
|
||||||
base = p;
|
base = p;
|
||||||
|
saw_slash = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (char *) base;
|
return (char *) base;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the length of of the basename NAME. Typically NAME is the
|
|
||||||
value returned by base_name. Act like strlen (NAME), except omit
|
/* In general, we can't use the builtin `basename' function if available,
|
||||||
redundant trailing slashes. */
|
since it has different meanings in different environments.
|
||||||
|
In some environments the builtin `basename' modifies its argument.
|
||||||
|
|
||||||
|
Return the last file name component of NAME, allocated with
|
||||||
|
xmalloc. On systems with drive letters, a leading "./"
|
||||||
|
distinguishes relative names that would otherwise look like a drive
|
||||||
|
letter. Unlike POSIX basename(), NAME cannot be NULL,
|
||||||
|
base_name("") returns "", and the first trailing slash is not
|
||||||
|
stripped.
|
||||||
|
|
||||||
|
If lstat (NAME) would succeed, then { chdir (dir_name (NAME));
|
||||||
|
lstat (base_name (NAME)); } will access the same file. Likewise,
|
||||||
|
if the sequence { chdir (dir_name (NAME));
|
||||||
|
rename (base_name (NAME), "foo"); } succeeds, you have renamed NAME
|
||||||
|
to "foo" in the same directory NAME was in. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
base_name (char const *name)
|
||||||
|
{
|
||||||
|
char const *base = last_component (name);
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
/* If there is no last component, then name is a file system root or the
|
||||||
|
empty string. */
|
||||||
|
if (! *base)
|
||||||
|
return xstrndup (name, base_len (name));
|
||||||
|
|
||||||
|
/* Collapse a sequence of trailing slashes into one. */
|
||||||
|
length = base_len (base);
|
||||||
|
if (ISSLASH (base[length]))
|
||||||
|
length++;
|
||||||
|
|
||||||
|
/* On systems with drive letters, `a/b:c' must return `./b:c' rather
|
||||||
|
than `b:c' to avoid confusion with a drive letter. On systems
|
||||||
|
with pure POSIX semantics, this is not an issue. */
|
||||||
|
if (FILE_SYSTEM_PREFIX_LEN (base))
|
||||||
|
{
|
||||||
|
char *p = xmalloc (length + 3);
|
||||||
|
p[0] = '.';
|
||||||
|
p[1] = '/';
|
||||||
|
memcpy (p + 2, base, length);
|
||||||
|
p[length + 2] = '\0';
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally, copy the basename. */
|
||||||
|
return xstrndup (base, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the length of the basename NAME. Typically NAME is the
|
||||||
|
value returned by base_name or last_component. Act like strlen
|
||||||
|
(NAME), except omit all trailing slashes. */
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
base_len (char const *name)
|
base_len (char const *name)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
|
||||||
|
|
||||||
for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--)
|
for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (DOUBLE_SLASH_IS_DISTINCT_ROOT && len == 1
|
||||||
|
&& ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2])
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
if (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE && prefix_len
|
||||||
|
&& len == prefix_len && ISSLASH (name[prefix_len]))
|
||||||
|
return prefix_len + 1;
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
138
lib/dirname.c
138
lib/dirname.c
@ -1,6 +1,6 @@
|
|||||||
/* dirname.c -- return all but the last element in a path
|
/* dirname.c -- return all but the last element in a file name
|
||||||
|
|
||||||
Copyright (C) 1990, 1998, 2000, 2001, 2003, 2004 Free Software
|
Copyright (C) 1990, 1998, 2000, 2001, 2003, 2004, 2005, 2006 Free Software
|
||||||
Foundation, Inc.
|
Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
@ -15,107 +15,71 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
#include <config.h>
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "dirname.h"
|
#include "dirname.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "xalloc.h"
|
#include "xalloc.h"
|
||||||
|
|
||||||
/* Return the length of `dirname (PATH)', or zero if PATH is
|
/* Return the length of the prefix of FILE that will be used by
|
||||||
in the working directory. Works properly even if
|
dir_name. If FILE is in the working directory, this returns zero
|
||||||
there are trailing slashes (by effectively ignoring them). */
|
even though `dir_name (FILE)' will return ".". Works properly even
|
||||||
|
if there are trailing slashes (by effectively ignoring them). */
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
dir_len (char const *path)
|
dir_len (char const *file)
|
||||||
{
|
{
|
||||||
size_t prefix_length = FILE_SYSTEM_PREFIX_LEN (path);
|
size_t prefix_length = FILE_SYSTEM_PREFIX_LEN (file);
|
||||||
size_t length;
|
size_t length;
|
||||||
|
|
||||||
/* Strip the basename and any redundant slashes before it. */
|
/* Advance prefix_length beyond important leading slashes. */
|
||||||
for (length = base_name (path) - path; prefix_length < length; length--)
|
prefix_length += (prefix_length != 0
|
||||||
if (! ISSLASH (path[length - 1]))
|
? (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
|
||||||
return length;
|
&& ISSLASH (file[prefix_length]))
|
||||||
|
: (ISSLASH (file[0])
|
||||||
|
? ((DOUBLE_SLASH_IS_DISTINCT_ROOT
|
||||||
|
&& ISSLASH (file[1]) && ! ISSLASH (file[2])
|
||||||
|
? 2 : 1))
|
||||||
|
: 0));
|
||||||
|
|
||||||
/* But don't strip the only slash from "/". */
|
/* Strip the basename and any redundant slashes before it. */
|
||||||
return prefix_length + ISSLASH (path[prefix_length]);
|
for (length = last_component (file) - file;
|
||||||
|
prefix_length < length; length--)
|
||||||
|
if (! ISSLASH (file[length - 1]))
|
||||||
|
break;
|
||||||
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the leading directories part of PATH,
|
|
||||||
allocated with xmalloc.
|
/* In general, we can't use the builtin `dirname' function if available,
|
||||||
Works properly even if there are trailing slashes
|
since it has different meanings in different environments.
|
||||||
(by effectively ignoring them). */
|
In some environments the builtin `dirname' modifies its argument.
|
||||||
|
|
||||||
|
Return the leading directories part of FILE, allocated with xmalloc.
|
||||||
|
Works properly even if there are trailing slashes (by effectively
|
||||||
|
ignoring them). Unlike POSIX dirname(), FILE cannot be NULL.
|
||||||
|
|
||||||
|
If lstat (FILE) would succeed, then { chdir (dir_name (FILE));
|
||||||
|
lstat (base_name (FILE)); } will access the same file. Likewise,
|
||||||
|
if the sequence { chdir (dir_name (FILE));
|
||||||
|
rename (base_name (FILE), "foo"); } succeeds, you have renamed FILE
|
||||||
|
to "foo" in the same directory FILE was in. */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
dir_name (char const *path)
|
dir_name (char const *file)
|
||||||
{
|
{
|
||||||
size_t length = dir_len (path);
|
size_t length = dir_len (file);
|
||||||
bool append_dot = (length == FILE_SYSTEM_PREFIX_LEN (path));
|
bool append_dot = (length == 0
|
||||||
char *newpath = xmalloc (length + append_dot + 1);
|
|| (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
|
||||||
memcpy (newpath, path, length);
|
&& length == FILE_SYSTEM_PREFIX_LEN (file)
|
||||||
|
&& file[2] != '\0' && ! ISSLASH (file[2])));
|
||||||
|
char *dir = xmalloc (length + append_dot + 1);
|
||||||
|
memcpy (dir, file, length);
|
||||||
if (append_dot)
|
if (append_dot)
|
||||||
newpath[length++] = '.';
|
dir[length++] = '.';
|
||||||
newpath[length] = 0;
|
dir[length] = '\0';
|
||||||
return newpath;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TEST_DIRNAME
|
|
||||||
/*
|
|
||||||
|
|
||||||
Run the test like this (expect no output):
|
|
||||||
gcc -DHAVE_CONFIG_H -DTEST_DIRNAME -I.. -O -Wall \
|
|
||||||
basename.c dirname.c xmalloc.c error.c
|
|
||||||
sed -n '/^BEGIN-DATA$/,/^END-DATA$/p' dirname.c|grep -v DATA|./a.out
|
|
||||||
|
|
||||||
If it's been built on a DOS or Windows platforms, run another test like
|
|
||||||
this (again, expect no output):
|
|
||||||
sed -n '/^BEGIN-DOS-DATA$/,/^END-DOS-DATA$/p' dirname.c|grep -v DATA|./a.out
|
|
||||||
|
|
||||||
BEGIN-DATA
|
|
||||||
foo//// .
|
|
||||||
bar/foo//// bar
|
|
||||||
foo/ .
|
|
||||||
/ /
|
|
||||||
. .
|
|
||||||
a .
|
|
||||||
END-DATA
|
|
||||||
|
|
||||||
BEGIN-DOS-DATA
|
|
||||||
c:///// c:/
|
|
||||||
c:/ c:/
|
|
||||||
c:/. c:/
|
|
||||||
c:foo c:.
|
|
||||||
c:foo/bar c:foo
|
|
||||||
END-DOS-DATA
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
# define MAX_BUFF_LEN 1024
|
|
||||||
# include <stdio.h>
|
|
||||||
|
|
||||||
char *program_name;
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char buff[MAX_BUFF_LEN + 1];
|
|
||||||
|
|
||||||
program_name = argv[0];
|
|
||||||
|
|
||||||
buff[MAX_BUFF_LEN] = 0;
|
|
||||||
while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
|
|
||||||
{
|
|
||||||
char path[MAX_BUFF_LEN];
|
|
||||||
char expected_result[MAX_BUFF_LEN];
|
|
||||||
char const *result;
|
|
||||||
sscanf (buff, "%s %s", path, expected_result);
|
|
||||||
result = dir_name (path);
|
|
||||||
if (strcmp (result, expected_result))
|
|
||||||
printf ("%s: got %s, expected %s\n", path, result, expected_result);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* Take file names apart into directory and base names.
|
/* Take file names apart into directory and base names.
|
||||||
|
|
||||||
Copyright (C) 1998, 2001, 2003, 2004 Free Software Foundation, Inc.
|
Copyright (C) 1998, 2001, 2003-2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifndef DIRNAME_H_
|
#ifndef DIRNAME_H_
|
||||||
# define DIRNAME_H_ 1
|
# define DIRNAME_H_ 1
|
||||||
@ -31,17 +31,40 @@
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifndef FILE_SYSTEM_PREFIX_LEN
|
# ifndef FILE_SYSTEM_PREFIX_LEN
|
||||||
# define FILE_SYSTEM_PREFIX_LEN(Filename) 0
|
# if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
|
||||||
|
/* This internal macro assumes ASCII, but all hosts that support drive
|
||||||
|
letters use ASCII. */
|
||||||
|
# define _IS_DRIVE_LETTER(c) (((unsigned int) (c) | ('a' - 'A')) - 'a' \
|
||||||
|
<= 'z' - 'a')
|
||||||
|
# define FILE_SYSTEM_PREFIX_LEN(Filename) \
|
||||||
|
(_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0)
|
||||||
|
# else
|
||||||
|
# define FILE_SYSTEM_PREFIX_LEN(Filename) 0
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)])
|
# ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
|
||||||
|
# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
|
||||||
|
# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
|
||||||
|
# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)])
|
||||||
|
# else
|
||||||
|
# define IS_ABSOLUTE_FILE_NAME(F) \
|
||||||
|
(ISSLASH ((F)[0]) || 0 < FILE_SYSTEM_PREFIX_LEN (F))
|
||||||
|
# endif
|
||||||
# define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F))
|
# define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F))
|
||||||
|
|
||||||
char *base_name (char const *path);
|
char *base_name (char const *file);
|
||||||
char *dir_name (char const *path);
|
char *dir_name (char const *file);
|
||||||
size_t base_len (char const *path);
|
size_t base_len (char const *file);
|
||||||
size_t dir_len (char const *path);
|
size_t dir_len (char const *file);
|
||||||
|
char *last_component (char const *file);
|
||||||
|
|
||||||
bool strip_trailing_slashes (char *path);
|
bool strip_trailing_slashes (char *file);
|
||||||
|
|
||||||
#endif /* not DIRNAME_H_ */
|
#endif /* not DIRNAME_H_ */
|
||||||
|
138
lib/error.c
138
lib/error.c
@ -1,5 +1,5 @@
|
|||||||
/* Error handler for noninteractive utilities
|
/* Error handler for noninteractive utilities
|
||||||
Copyright (C) 1990-1998, 2000-2002, 2003, 2004 Free Software Foundation, Inc.
|
Copyright (C) 1990-1998, 2000-2005, 2006 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
@ -14,11 +14,11 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#if !_LIBC
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -29,13 +29,14 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef _LIBC
|
#if !_LIBC && ENABLE_NLS
|
||||||
# include <libintl.h>
|
|
||||||
#else
|
|
||||||
# include "gettext.h"
|
# include "gettext.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _LIBC
|
#ifdef _LIBC
|
||||||
|
# include <libintl.h>
|
||||||
|
# include <stdbool.h>
|
||||||
|
# include <stdint.h>
|
||||||
# include <wchar.h>
|
# include <wchar.h>
|
||||||
# define mbsrtowcs __mbsrtowcs
|
# define mbsrtowcs __mbsrtowcs
|
||||||
#endif
|
#endif
|
||||||
@ -61,6 +62,7 @@ unsigned int error_message_count;
|
|||||||
|
|
||||||
# define program_name program_invocation_name
|
# define program_name program_invocation_name
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
|
# include <limits.h>
|
||||||
# include <libio/libioP.h>
|
# include <libio/libioP.h>
|
||||||
|
|
||||||
/* In GNU libc we want do not want to use the common name `error' directly.
|
/* In GNU libc we want do not want to use the common name `error' directly.
|
||||||
@ -90,23 +92,19 @@ extern void __error_at_line (int status, int errnum, const char *file_name,
|
|||||||
char *strerror_r ();
|
char *strerror_r ();
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifndef SIZE_MAX
|
|
||||||
# define SIZE_MAX ((size_t) -1)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* The calling program should define program_name and set it to the
|
/* The calling program should define program_name and set it to the
|
||||||
name of the executing program. */
|
name of the executing program. */
|
||||||
extern char *program_name;
|
extern char *program_name;
|
||||||
|
|
||||||
# if HAVE_STRERROR_R || defined strerror_r
|
# if HAVE_STRERROR_R || defined strerror_r
|
||||||
# define __strerror_r strerror_r
|
# define __strerror_r strerror_r
|
||||||
# endif
|
# endif /* HAVE_STRERROR_R || defined strerror_r */
|
||||||
#endif /* not _LIBC */
|
#endif /* not _LIBC */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_errno_message (int errnum)
|
print_errno_message (int errnum)
|
||||||
{
|
{
|
||||||
char const *s = NULL;
|
char const *s;
|
||||||
|
|
||||||
#if defined HAVE_STRERROR_R || _LIBC
|
#if defined HAVE_STRERROR_R || _LIBC
|
||||||
char errbuf[1024];
|
char errbuf[1024];
|
||||||
@ -115,23 +113,23 @@ print_errno_message (int errnum)
|
|||||||
# else
|
# else
|
||||||
if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
|
if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
|
||||||
s = errbuf;
|
s = errbuf;
|
||||||
|
else
|
||||||
|
s = 0;
|
||||||
# endif
|
# endif
|
||||||
|
#else
|
||||||
|
s = strerror (errnum);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !_LIBC
|
#if !_LIBC
|
||||||
if (! s && ! (s = strerror (errnum)))
|
if (! s)
|
||||||
s = _("Unknown system error");
|
s = _("Unknown system error");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _LIBC
|
#if _LIBC
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
__fxprintf (NULL, ": %s", s);
|
||||||
{
|
#else
|
||||||
__fwprintf (stderr, L": %s", s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fprintf (stderr, ": %s", s);
|
fprintf (stderr, ": %s", s);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -142,26 +140,65 @@ error_tail (int status, int errnum, const char *message, va_list args)
|
|||||||
{
|
{
|
||||||
# define ALLOCA_LIMIT 2000
|
# define ALLOCA_LIMIT 2000
|
||||||
size_t len = strlen (message) + 1;
|
size_t len = strlen (message) + 1;
|
||||||
const wchar_t *wmessage = L"out of memory";
|
wchar_t *wmessage = NULL;
|
||||||
wchar_t *wbuf = (len < ALLOCA_LIMIT
|
mbstate_t st;
|
||||||
? alloca (len * sizeof *wbuf)
|
size_t res;
|
||||||
: len <= SIZE_MAX / sizeof *wbuf
|
const char *tmp;
|
||||||
? malloc (len * sizeof *wbuf)
|
bool use_malloc = false;
|
||||||
: NULL);
|
|
||||||
|
|
||||||
if (wbuf)
|
while (1)
|
||||||
{
|
{
|
||||||
size_t res;
|
if (__libc_use_alloca (len * sizeof (wchar_t)))
|
||||||
mbstate_t st;
|
wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
|
||||||
const char *tmp = message;
|
else
|
||||||
|
{
|
||||||
|
if (!use_malloc)
|
||||||
|
wmessage = NULL;
|
||||||
|
|
||||||
|
wchar_t *p = (wchar_t *) realloc (wmessage,
|
||||||
|
len * sizeof (wchar_t));
|
||||||
|
if (p == NULL)
|
||||||
|
{
|
||||||
|
free (wmessage);
|
||||||
|
fputws_unlocked (L"out of memory\n", stderr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wmessage = p;
|
||||||
|
use_malloc = true;
|
||||||
|
}
|
||||||
|
|
||||||
memset (&st, '\0', sizeof (st));
|
memset (&st, '\0', sizeof (st));
|
||||||
res = mbsrtowcs (wbuf, &tmp, len, &st);
|
tmp = message;
|
||||||
wmessage = res == (size_t) -1 ? L"???" : wbuf;
|
|
||||||
|
res = mbsrtowcs (wmessage, &tmp, len, &st);
|
||||||
|
if (res != len)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (__builtin_expect (len >= SIZE_MAX / 2, 0))
|
||||||
|
{
|
||||||
|
/* This really should not happen if everything is fine. */
|
||||||
|
res = (size_t) -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
len *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == (size_t) -1)
|
||||||
|
{
|
||||||
|
/* The string cannot be converted. */
|
||||||
|
if (use_malloc)
|
||||||
|
{
|
||||||
|
free (wmessage);
|
||||||
|
use_malloc = false;
|
||||||
|
}
|
||||||
|
wmessage = (wchar_t *) L"???";
|
||||||
}
|
}
|
||||||
|
|
||||||
__vfwprintf (stderr, wmessage, args);
|
__vfwprintf (stderr, wmessage, args);
|
||||||
if (! (len < ALLOCA_LIMIT))
|
|
||||||
free (wbuf);
|
if (use_malloc)
|
||||||
|
free (wmessage);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -172,11 +209,10 @@ error_tail (int status, int errnum, const char *message, va_list args)
|
|||||||
if (errnum)
|
if (errnum)
|
||||||
print_errno_message (errnum);
|
print_errno_message (errnum);
|
||||||
#if _LIBC
|
#if _LIBC
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
__fxprintf (NULL, "\n");
|
||||||
putwc (L'\n', stderr);
|
#else
|
||||||
else
|
putc ('\n', stderr);
|
||||||
#endif
|
#endif
|
||||||
putc ('\n', stderr);
|
|
||||||
fflush (stderr);
|
fflush (stderr);
|
||||||
if (status)
|
if (status)
|
||||||
exit (status);
|
exit (status);
|
||||||
@ -209,11 +245,10 @@ error (int status, int errnum, const char *message, ...)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if _LIBC
|
#if _LIBC
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
__fxprintf (NULL, "%s: ", program_name);
|
||||||
__fwprintf (stderr, L"%s: ", program_name);
|
#else
|
||||||
else
|
fprintf (stderr, "%s: ", program_name);
|
||||||
#endif
|
#endif
|
||||||
fprintf (stderr, "%s: ", program_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
va_start (args, message);
|
va_start (args, message);
|
||||||
@ -269,22 +304,19 @@ error_at_line (int status, int errnum, const char *file_name,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if _LIBC
|
#if _LIBC
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
__fxprintf (NULL, "%s:", program_name);
|
||||||
__fwprintf (stderr, L"%s: ", program_name);
|
#else
|
||||||
else
|
fprintf (stderr, "%s:", program_name);
|
||||||
#endif
|
#endif
|
||||||
fprintf (stderr, "%s:", program_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_name != NULL)
|
|
||||||
{
|
|
||||||
#if _LIBC
|
#if _LIBC
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
__fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
|
||||||
__fwprintf (stderr, L"%s:%d: ", file_name, line_number);
|
file_name, line_number);
|
||||||
else
|
#else
|
||||||
|
fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
|
||||||
|
file_name, line_number);
|
||||||
#endif
|
#endif
|
||||||
fprintf (stderr, "%s:%d: ", file_name, line_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
va_start (args, message);
|
va_start (args, message);
|
||||||
error_tail (status, errnum, message, args);
|
error_tail (status, errnum, message, args);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Declaration for error-reporting function
|
/* Declaration for error-reporting function
|
||||||
Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc.
|
Copyright (C) 1995, 1996, 1997, 2003, 2006 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
@ -14,14 +14,14 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifndef _ERROR_H
|
#ifndef _ERROR_H
|
||||||
#define _ERROR_H 1
|
#define _ERROR_H 1
|
||||||
|
|
||||||
#ifndef __attribute__
|
#ifndef __attribute__
|
||||||
/* This feature is available in gcc versions 2.5 and later. */
|
/* This feature is available in gcc versions 2.5 and later. */
|
||||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
|
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
|
||||||
# define __attribute__(Spec) /* empty */
|
# define __attribute__(Spec) /* empty */
|
||||||
# endif
|
# endif
|
||||||
/* The __-protected variants of `format' and `printf' attributes
|
/* The __-protected variants of `format' and `printf' attributes
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* Failure exit status
|
/* Failure exit status
|
||||||
|
|
||||||
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
|
Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -15,13 +15,12 @@
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; see the file COPYING.
|
along with this program; see the file COPYING.
|
||||||
If not, write to the Free Software Foundation,
|
If not, write to the Free Software Foundation,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
#include <config.h>
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "exitfail.h"
|
#include "exitfail.h"
|
||||||
#include "exit.h"
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
int volatile exit_failure = EXIT_FAILURE;
|
int volatile exit_failure = EXIT_FAILURE;
|
||||||
|
@ -15,6 +15,6 @@
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; see the file COPYING.
|
along with this program; see the file COPYING.
|
||||||
If not, write to the Free Software Foundation,
|
If not, write to the Free Software Foundation,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
extern int volatile exit_failure;
|
extern int volatile exit_failure;
|
||||||
|
27
lib/fatal.c
Normal file
27
lib/fatal.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* This file is part of GNU cpio.
|
||||||
|
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program 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 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
|
#include <system.h>
|
||||||
|
#include <paxlib.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
fatal_exit ()
|
||||||
|
{
|
||||||
|
exit (PAXEXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
/* An interface to read and write that retries (if necessary) until complete.
|
/* An interface to read and write that retries (if necessary) until complete.
|
||||||
|
|
||||||
Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
|
Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
|
||||||
2004 Free Software Foundation, Inc.
|
2004, 2005, 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -15,11 +15,9 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
#include <config.h>
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Specification. */
|
/* Specification. */
|
||||||
#ifdef FULL_READ
|
#ifdef FULL_READ
|
||||||
@ -62,7 +60,7 @@ size_t
|
|||||||
full_rw (int fd, const void *buf, size_t count)
|
full_rw (int fd, const void *buf, size_t count)
|
||||||
{
|
{
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
const char *ptr = buf;
|
const char *ptr = (const char *) buf;
|
||||||
|
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
{
|
{
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
88
lib/getopt.c
88
lib/getopt.c
@ -2,7 +2,7 @@
|
|||||||
NOTE: getopt is now part of the C library, so if you don't know what
|
NOTE: getopt is now part of the C library, so if you don't know what
|
||||||
"Keep this file name-space clean" means, talk to drepper@gnu.org
|
"Keep this file name-space clean" means, talk to drepper@gnu.org
|
||||||
before changing it!
|
before changing it!
|
||||||
Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004
|
Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004,2006
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
@ -18,32 +18,20 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
|
#ifndef _LIBC
|
||||||
Ditto for AIX 3.2 and <stdlib.h>. */
|
|
||||||
#ifndef _NO_PROTO
|
|
||||||
# define _NO_PROTO
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "getopt.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
/* This needs to come after some library #include
|
|
||||||
to get __GNU_LIBRARY__ defined. */
|
|
||||||
#ifdef __GNU_LIBRARY__
|
|
||||||
/* Don't include stdlib.h for non-GNU C libraries because some of them
|
|
||||||
contain conflicting prototypes for getopt. */
|
|
||||||
# include <stdlib.h>
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif /* GNU C library. */
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef VMS
|
#ifdef __VMS
|
||||||
# include <unixlib.h>
|
# include <unixlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -76,7 +64,6 @@
|
|||||||
GNU application programs can use a third alternative mode in which
|
GNU application programs can use a third alternative mode in which
|
||||||
they can distinguish the relative order of options and other arguments. */
|
they can distinguish the relative order of options and other arguments. */
|
||||||
|
|
||||||
#include "getopt.h"
|
|
||||||
#include "getopt_int.h"
|
#include "getopt_int.h"
|
||||||
|
|
||||||
/* For communication from `getopt' to the caller.
|
/* For communication from `getopt' to the caller.
|
||||||
@ -118,16 +105,9 @@ int optopt = '?';
|
|||||||
static struct _getopt_data getopt_data;
|
static struct _getopt_data getopt_data;
|
||||||
|
|
||||||
|
|
||||||
#ifndef __GNU_LIBRARY__
|
#if defined HAVE_DECL_GETENV && !HAVE_DECL_GETENV
|
||||||
|
|
||||||
/* Avoid depending on library functions or files
|
|
||||||
whose names are inconsistent. */
|
|
||||||
|
|
||||||
#ifndef getenv
|
|
||||||
extern char *getenv ();
|
extern char *getenv ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* not __GNU_LIBRARY__ */
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
#ifdef _LIBC
|
||||||
/* Stored original parameters.
|
/* Stored original parameters.
|
||||||
@ -556,10 +536,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||||||
int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
|
int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
|
||||||
((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
|
((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
|
||||||
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
__fxprintf (NULL, "%s", buf);
|
||||||
__fwprintf (stderr, L"%s", buf);
|
|
||||||
else
|
|
||||||
fputs (buf, stderr);
|
|
||||||
|
|
||||||
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
||||||
_IO_funlockfile (stderr);
|
_IO_funlockfile (stderr);
|
||||||
@ -634,10 +611,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||||||
((_IO_FILE *) stderr)->_flags2
|
((_IO_FILE *) stderr)->_flags2
|
||||||
|= _IO_FLAGS2_NOTCANCEL;
|
|= _IO_FLAGS2_NOTCANCEL;
|
||||||
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
__fxprintf (NULL, "%s", buf);
|
||||||
__fwprintf (stderr, L"%s", buf);
|
|
||||||
else
|
|
||||||
fputs (buf, stderr);
|
|
||||||
|
|
||||||
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
||||||
_IO_funlockfile (stderr);
|
_IO_funlockfile (stderr);
|
||||||
@ -674,10 +648,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||||||
((_IO_FILE *) stderr)->_flags2
|
((_IO_FILE *) stderr)->_flags2
|
||||||
|= _IO_FLAGS2_NOTCANCEL;
|
|= _IO_FLAGS2_NOTCANCEL;
|
||||||
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
__fxprintf (NULL, "%s", buf);
|
||||||
__fwprintf (stderr, L"%s", buf);
|
|
||||||
else
|
|
||||||
fputs (buf, stderr);
|
|
||||||
|
|
||||||
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
||||||
_IO_funlockfile (stderr);
|
_IO_funlockfile (stderr);
|
||||||
@ -751,10 +722,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||||||
int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
|
int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
|
||||||
((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
|
((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
|
||||||
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
__fxprintf (NULL, "%s", buf);
|
||||||
__fwprintf (stderr, L"%s", buf);
|
|
||||||
else
|
|
||||||
fputs (buf, stderr);
|
|
||||||
|
|
||||||
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
||||||
_IO_funlockfile (stderr);
|
_IO_funlockfile (stderr);
|
||||||
@ -817,10 +785,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||||||
int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
|
int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
|
||||||
((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
|
((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
|
||||||
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
__fxprintf (NULL, "%s", buf);
|
||||||
__fwprintf (stderr, L"%s", buf);
|
|
||||||
else
|
|
||||||
fputs (buf, stderr);
|
|
||||||
|
|
||||||
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
||||||
_IO_funlockfile (stderr);
|
_IO_funlockfile (stderr);
|
||||||
@ -868,10 +833,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||||||
int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
|
int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
|
||||||
((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
|
((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
|
||||||
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
__fxprintf (NULL, "%s", buf);
|
||||||
__fwprintf (stderr, L"%s", buf);
|
|
||||||
else
|
|
||||||
fputs (buf, stderr);
|
|
||||||
|
|
||||||
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
||||||
_IO_funlockfile (stderr);
|
_IO_funlockfile (stderr);
|
||||||
@ -940,10 +902,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||||||
int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
|
int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
|
||||||
((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
|
((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
|
||||||
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
__fxprintf (NULL, "%s", buf);
|
||||||
__fwprintf (stderr, L"%s", buf);
|
|
||||||
else
|
|
||||||
fputs (buf, stderr);
|
|
||||||
|
|
||||||
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
||||||
_IO_funlockfile (stderr);
|
_IO_funlockfile (stderr);
|
||||||
@ -985,10 +944,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||||||
((_IO_FILE *) stderr)->_flags2
|
((_IO_FILE *) stderr)->_flags2
|
||||||
|= _IO_FLAGS2_NOTCANCEL;
|
|= _IO_FLAGS2_NOTCANCEL;
|
||||||
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
__fxprintf (NULL, "%s", buf);
|
||||||
__fwprintf (stderr, L"%s", buf);
|
|
||||||
else
|
|
||||||
fputs (buf, stderr);
|
|
||||||
|
|
||||||
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
||||||
_IO_funlockfile (stderr);
|
_IO_funlockfile (stderr);
|
||||||
@ -1027,10 +983,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||||||
((_IO_FILE *) stderr)->_flags2
|
((_IO_FILE *) stderr)->_flags2
|
||||||
|= _IO_FLAGS2_NOTCANCEL;
|
|= _IO_FLAGS2_NOTCANCEL;
|
||||||
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
__fxprintf (NULL, "%s", buf);
|
||||||
__fwprintf (stderr, L"%s", buf);
|
|
||||||
else
|
|
||||||
fputs (buf, stderr);
|
|
||||||
|
|
||||||
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
||||||
_IO_funlockfile (stderr);
|
_IO_funlockfile (stderr);
|
||||||
@ -1101,10 +1054,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||||||
int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
|
int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
|
||||||
((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
|
((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
|
||||||
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
__fxprintf (NULL, "%s", buf);
|
||||||
__fwprintf (stderr, L"%s", buf);
|
|
||||||
else
|
|
||||||
fputs (buf, stderr);
|
|
||||||
|
|
||||||
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
((_IO_FILE *) stderr)->_flags2 = old_flags2;
|
||||||
_IO_funlockfile (stderr);
|
_IO_funlockfile (stderr);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||||
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004
|
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004,2006
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
@ -15,15 +15,12 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
#ifdef _LIBC
|
||||||
# include <getopt.h>
|
# include <getopt.h>
|
||||||
#else
|
#else
|
||||||
|
# include <config.h>
|
||||||
# include "getopt.h"
|
# include "getopt.h"
|
||||||
#endif
|
#endif
|
||||||
#include "getopt_int.h"
|
#include "getopt_int.h"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Declarations for getopt.
|
/* Declarations for getopt.
|
||||||
Copyright (C) 1989-1994,1996-1999,2001,2003,2004
|
Copyright (C) 1989-1994,1996-1999,2001,2003,2004,2005,2006,2007
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifndef _GETOPT_H
|
#ifndef _GETOPT_H
|
||||||
|
|
||||||
@ -34,9 +34,7 @@
|
|||||||
#if defined __GETOPT_PREFIX && !defined __need_getopt
|
#if defined __GETOPT_PREFIX && !defined __need_getopt
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# if HAVE_UNISTD_H
|
# include <unistd.h>
|
||||||
# include <unistd.h>
|
|
||||||
# endif
|
|
||||||
# undef __need_getopt
|
# undef __need_getopt
|
||||||
# undef getopt
|
# undef getopt
|
||||||
# undef getopt_long
|
# undef getopt_long
|
||||||
@ -67,14 +65,14 @@
|
|||||||
but it caused redefinition warnings if both unistd.h and getopt.h were
|
but it caused redefinition warnings if both unistd.h and getopt.h were
|
||||||
included, since unistd.h includes getopt.h having previously defined
|
included, since unistd.h includes getopt.h having previously defined
|
||||||
__need_getopt.
|
__need_getopt.
|
||||||
|
|
||||||
The only place where __getopt_argv_const is used is in definitions
|
The only place where __getopt_argv_const is used is in definitions
|
||||||
of getopt_long and getopt_long_only below, but these are visible
|
of getopt_long and getopt_long_only below, but these are visible
|
||||||
only if __need_getopt is not defined, so it is quite safe to rewrite
|
only if __need_getopt is not defined, so it is quite safe to rewrite
|
||||||
the conditional as follows:
|
the conditional as follows:
|
||||||
*/
|
*/
|
||||||
#if !defined __need_getopt
|
#if !defined __need_getopt
|
||||||
# if defined __GETOPT_PREFIX
|
# if defined __GETOPT_PREFIX
|
||||||
# define __getopt_argv_const /* empty */
|
# define __getopt_argv_const /* empty */
|
||||||
# else
|
# else
|
||||||
# define __getopt_argv_const const
|
# define __getopt_argv_const const
|
||||||
@ -103,7 +101,7 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -198,9 +196,10 @@ struct option
|
|||||||
scanning, explicitly telling `getopt' that there are no more
|
scanning, explicitly telling `getopt' that there are no more
|
||||||
options.
|
options.
|
||||||
|
|
||||||
If OPTS begins with `--', then non-option arguments are treated as
|
If OPTS begins with `-', then non-option arguments are treated as
|
||||||
arguments to the option '\0'. This behavior is specific to the GNU
|
arguments to the option '\1'. This behavior is specific to the GNU
|
||||||
`getopt'. */
|
`getopt'. If OPTS begins with `+', or POSIXLY_CORRECT is set in
|
||||||
|
the environment, then do not permute arguments. */
|
||||||
|
|
||||||
extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
|
extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
|
||||||
__THROW;
|
__THROW;
|
||||||
@ -217,7 +216,7 @@ extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv,
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifndef _GETOPT_INT_H
|
#ifndef _GETOPT_INT_H
|
||||||
#define _GETOPT_INT_H 1
|
#define _GETOPT_INT_H 1
|
||||||
|
220
lib/gettext.h
220
lib/gettext.h
@ -1,5 +1,5 @@
|
|||||||
/* Convenience header for conditional use of GNU <libintl.h>.
|
/* Convenience header for conditional use of GNU <libintl.h>.
|
||||||
Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc.
|
Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifndef _LIBGETTEXT_H
|
#ifndef _LIBGETTEXT_H
|
||||||
#define _LIBGETTEXT_H 1
|
#define _LIBGETTEXT_H 1
|
||||||
@ -24,6 +24,18 @@
|
|||||||
/* Get declarations of GNU message catalog functions. */
|
/* Get declarations of GNU message catalog functions. */
|
||||||
# include <libintl.h>
|
# include <libintl.h>
|
||||||
|
|
||||||
|
/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
|
||||||
|
the gettext() and ngettext() macros. This is an alternative to calling
|
||||||
|
textdomain(), and is useful for libraries. */
|
||||||
|
# ifdef DEFAULT_TEXT_DOMAIN
|
||||||
|
# undef gettext
|
||||||
|
# define gettext(Msgid) \
|
||||||
|
dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
|
||||||
|
# undef ngettext
|
||||||
|
# define ngettext(Msgid1, Msgid2, N) \
|
||||||
|
dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
|
||||||
|
# endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
|
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
|
||||||
@ -36,23 +48,38 @@
|
|||||||
# include <locale.h>
|
# include <locale.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
|
||||||
|
<libintl.h>, which chokes if dcgettext is defined as a macro. So include
|
||||||
|
it now, to make later inclusions of <libintl.h> a NOP. */
|
||||||
|
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
|
||||||
|
# include <cstdlib>
|
||||||
|
# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
|
||||||
|
# include <libintl.h>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Disabled NLS.
|
/* Disabled NLS.
|
||||||
The casts to 'const char *' serve the purpose of producing warnings
|
The casts to 'const char *' serve the purpose of producing warnings
|
||||||
for invalid uses of the value returned from these functions.
|
for invalid uses of the value returned from these functions.
|
||||||
On pre-ANSI systems without 'const', the config.h file is supposed to
|
On pre-ANSI systems without 'const', the config.h file is supposed to
|
||||||
contain "#define const". */
|
contain "#define const". */
|
||||||
# define gettext(Msgid) ((const char *) (Msgid))
|
# define gettext(Msgid) ((const char *) (Msgid))
|
||||||
# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
|
# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
|
||||||
# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
|
# define dcgettext(Domainname, Msgid, Category) \
|
||||||
|
((void) (Category), dgettext (Domainname, Msgid))
|
||||||
# define ngettext(Msgid1, Msgid2, N) \
|
# define ngettext(Msgid1, Msgid2, N) \
|
||||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
((N) == 1 \
|
||||||
|
? ((void) (Msgid2), (const char *) (Msgid1)) \
|
||||||
|
: ((void) (Msgid1), (const char *) (Msgid2)))
|
||||||
# define dngettext(Domainname, Msgid1, Msgid2, N) \
|
# define dngettext(Domainname, Msgid1, Msgid2, N) \
|
||||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
((void) (Domainname), ngettext (Msgid1, Msgid2, N))
|
||||||
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
|
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
|
||||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
|
||||||
# define textdomain(Domainname) ((const char *) (Domainname))
|
# define textdomain(Domainname) ((const char *) (Domainname))
|
||||||
# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
|
# define bindtextdomain(Domainname, Dirname) \
|
||||||
# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
|
((void) (Domainname), (const char *) (Dirname))
|
||||||
|
# define bind_textdomain_codeset(Domainname, Codeset) \
|
||||||
|
((void) (Domainname), (const char *) (Codeset))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -65,4 +92,179 @@
|
|||||||
initializer for static 'char[]' or 'const char[]' variables. */
|
initializer for static 'char[]' or 'const char[]' variables. */
|
||||||
#define gettext_noop(String) String
|
#define gettext_noop(String) String
|
||||||
|
|
||||||
|
/* The separator between msgctxt and msgid in a .mo file. */
|
||||||
|
#define GETTEXT_CONTEXT_GLUE "\004"
|
||||||
|
|
||||||
|
/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
|
||||||
|
MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
|
||||||
|
short and rarely need to change.
|
||||||
|
The letter 'p' stands for 'particular' or 'special'. */
|
||||||
|
#ifdef DEFAULT_TEXT_DOMAIN
|
||||||
|
# define pgettext(Msgctxt, Msgid) \
|
||||||
|
pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
|
||||||
|
#else
|
||||||
|
# define pgettext(Msgctxt, Msgid) \
|
||||||
|
pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
|
||||||
|
#endif
|
||||||
|
#define dpgettext(Domainname, Msgctxt, Msgid) \
|
||||||
|
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
|
||||||
|
#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
|
||||||
|
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
|
||||||
|
#ifdef DEFAULT_TEXT_DOMAIN
|
||||||
|
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
|
||||||
|
npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
|
||||||
|
#else
|
||||||
|
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
|
||||||
|
npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
|
||||||
|
#endif
|
||||||
|
#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
|
||||||
|
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
|
||||||
|
#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
|
||||||
|
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__inline
|
||||||
|
#else
|
||||||
|
#ifdef __cplusplus
|
||||||
|
inline
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
static const char *
|
||||||
|
pgettext_aux (const char *domain,
|
||||||
|
const char *msg_ctxt_id, const char *msgid,
|
||||||
|
int category)
|
||||||
|
{
|
||||||
|
const char *translation = dcgettext (domain, msg_ctxt_id, category);
|
||||||
|
if (translation == msg_ctxt_id)
|
||||||
|
return msgid;
|
||||||
|
else
|
||||||
|
return translation;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__inline
|
||||||
|
#else
|
||||||
|
#ifdef __cplusplus
|
||||||
|
inline
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
static const char *
|
||||||
|
npgettext_aux (const char *domain,
|
||||||
|
const char *msg_ctxt_id, const char *msgid,
|
||||||
|
const char *msgid_plural, unsigned long int n,
|
||||||
|
int category)
|
||||||
|
{
|
||||||
|
const char *translation =
|
||||||
|
dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
|
||||||
|
if (translation == msg_ctxt_id || translation == msgid_plural)
|
||||||
|
return (n == 1 ? msgid : msgid_plural);
|
||||||
|
else
|
||||||
|
return translation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
|
||||||
|
can be arbitrary expressions. But for string literals these macros are
|
||||||
|
less efficient than those above. */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
|
||||||
|
(((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
|
||||||
|
/* || __STDC_VERSION__ >= 199901L */ )
|
||||||
|
|
||||||
|
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define pgettext_expr(Msgctxt, Msgid) \
|
||||||
|
dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
|
||||||
|
#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
|
||||||
|
dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__inline
|
||||||
|
#else
|
||||||
|
#ifdef __cplusplus
|
||||||
|
inline
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
static const char *
|
||||||
|
dcpgettext_expr (const char *domain,
|
||||||
|
const char *msgctxt, const char *msgid,
|
||||||
|
int category)
|
||||||
|
{
|
||||||
|
size_t msgctxt_len = strlen (msgctxt) + 1;
|
||||||
|
size_t msgid_len = strlen (msgid) + 1;
|
||||||
|
const char *translation;
|
||||||
|
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
|
||||||
|
char msg_ctxt_id[msgctxt_len + msgid_len];
|
||||||
|
#else
|
||||||
|
char buf[1024];
|
||||||
|
char *msg_ctxt_id =
|
||||||
|
(msgctxt_len + msgid_len <= sizeof (buf)
|
||||||
|
? buf
|
||||||
|
: (char *) malloc (msgctxt_len + msgid_len));
|
||||||
|
if (msg_ctxt_id != NULL)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
|
||||||
|
msg_ctxt_id[msgctxt_len - 1] = '\004';
|
||||||
|
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
|
||||||
|
translation = dcgettext (domain, msg_ctxt_id, category);
|
||||||
|
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
|
||||||
|
if (msg_ctxt_id != buf)
|
||||||
|
free (msg_ctxt_id);
|
||||||
|
#endif
|
||||||
|
if (translation != msg_ctxt_id)
|
||||||
|
return translation;
|
||||||
|
}
|
||||||
|
return msgid;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
|
||||||
|
dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
|
||||||
|
#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
|
||||||
|
dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__inline
|
||||||
|
#else
|
||||||
|
#ifdef __cplusplus
|
||||||
|
inline
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
static const char *
|
||||||
|
dcnpgettext_expr (const char *domain,
|
||||||
|
const char *msgctxt, const char *msgid,
|
||||||
|
const char *msgid_plural, unsigned long int n,
|
||||||
|
int category)
|
||||||
|
{
|
||||||
|
size_t msgctxt_len = strlen (msgctxt) + 1;
|
||||||
|
size_t msgid_len = strlen (msgid) + 1;
|
||||||
|
const char *translation;
|
||||||
|
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
|
||||||
|
char msg_ctxt_id[msgctxt_len + msgid_len];
|
||||||
|
#else
|
||||||
|
char buf[1024];
|
||||||
|
char *msg_ctxt_id =
|
||||||
|
(msgctxt_len + msgid_len <= sizeof (buf)
|
||||||
|
? buf
|
||||||
|
: (char *) malloc (msgctxt_len + msgid_len));
|
||||||
|
if (msg_ctxt_id != NULL)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
|
||||||
|
msg_ctxt_id[msgctxt_len - 1] = '\004';
|
||||||
|
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
|
||||||
|
translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
|
||||||
|
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
|
||||||
|
if (msg_ctxt_id != buf)
|
||||||
|
free (msg_ctxt_id);
|
||||||
|
#endif
|
||||||
|
if (!(translation == msg_ctxt_id || translation == msgid_plural))
|
||||||
|
return translation;
|
||||||
|
}
|
||||||
|
return (n == 1 ? msgid : msgid_plural);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _LIBGETTEXT_H */
|
#endif /* _LIBGETTEXT_H */
|
||||||
|
1048
lib/hash.c
Normal file
1048
lib/hash.c
Normal file
File diff suppressed because it is too large
Load Diff
88
lib/hash.h
Normal file
88
lib/hash.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/* hash - hashing table processing.
|
||||||
|
Copyright (C) 1998, 1999, 2001, 2003 Free Software Foundation, Inc.
|
||||||
|
Written by Jim Meyering <meyering@ascend.com>, 1998.
|
||||||
|
|
||||||
|
This program 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 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* A generic hash table package. */
|
||||||
|
|
||||||
|
/* Make sure USE_OBSTACK is defined to 1 if you want the allocator to use
|
||||||
|
obstacks instead of malloc, and recompile `hash.c' with same setting. */
|
||||||
|
|
||||||
|
#ifndef HASH_H_
|
||||||
|
# define HASH_H_
|
||||||
|
|
||||||
|
# include <stdio.h>
|
||||||
|
# include <stdbool.h>
|
||||||
|
|
||||||
|
typedef size_t (*Hash_hasher) (const void *, size_t);
|
||||||
|
typedef bool (*Hash_comparator) (const void *, const void *);
|
||||||
|
typedef void (*Hash_data_freer) (void *);
|
||||||
|
typedef bool (*Hash_processor) (void *, void *);
|
||||||
|
|
||||||
|
struct hash_entry
|
||||||
|
{
|
||||||
|
void *data;
|
||||||
|
struct hash_entry *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hash_tuning
|
||||||
|
{
|
||||||
|
/* This structure is mainly used for `hash_initialize', see the block
|
||||||
|
documentation of `hash_reset_tuning' for more complete comments. */
|
||||||
|
|
||||||
|
float shrink_threshold; /* ratio of used buckets to trigger a shrink */
|
||||||
|
float shrink_factor; /* ratio of new smaller size to original size */
|
||||||
|
float growth_threshold; /* ratio of used buckets to trigger a growth */
|
||||||
|
float growth_factor; /* ratio of new bigger size to original size */
|
||||||
|
bool is_n_buckets; /* if CANDIDATE really means table size */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct hash_tuning Hash_tuning;
|
||||||
|
|
||||||
|
struct hash_table;
|
||||||
|
|
||||||
|
typedef struct hash_table Hash_table;
|
||||||
|
|
||||||
|
/* Information and lookup. */
|
||||||
|
size_t hash_get_n_buckets (const Hash_table *);
|
||||||
|
size_t hash_get_n_buckets_used (const Hash_table *);
|
||||||
|
size_t hash_get_n_entries (const Hash_table *);
|
||||||
|
size_t hash_get_max_bucket_length (const Hash_table *);
|
||||||
|
bool hash_table_ok (const Hash_table *);
|
||||||
|
void hash_print_statistics (const Hash_table *, FILE *);
|
||||||
|
void *hash_lookup (const Hash_table *, const void *);
|
||||||
|
|
||||||
|
/* Walking. */
|
||||||
|
void *hash_get_first (const Hash_table *);
|
||||||
|
void *hash_get_next (const Hash_table *, const void *);
|
||||||
|
size_t hash_get_entries (const Hash_table *, void **, size_t);
|
||||||
|
size_t hash_do_for_each (const Hash_table *, Hash_processor, void *);
|
||||||
|
|
||||||
|
/* Allocation and clean-up. */
|
||||||
|
size_t hash_string (const char *, size_t);
|
||||||
|
void hash_reset_tuning (Hash_tuning *);
|
||||||
|
Hash_table *hash_initialize (size_t, const Hash_tuning *,
|
||||||
|
Hash_hasher, Hash_comparator,
|
||||||
|
Hash_data_freer);
|
||||||
|
void hash_clear (Hash_table *);
|
||||||
|
void hash_free (Hash_table *);
|
||||||
|
|
||||||
|
/* Insertion and deletion. */
|
||||||
|
bool hash_rehash (Hash_table *, size_t);
|
||||||
|
void *hash_insert (Hash_table *, const void *);
|
||||||
|
void *hash_delete (Hash_table *, const void *);
|
||||||
|
|
||||||
|
#endif
|
78
lib/intprops.h
Normal file
78
lib/intprops.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/* intprops.h -- properties of integer types
|
||||||
|
|
||||||
|
Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program 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 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* Written by Paul Eggert. */
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
/* The extra casts in the following macros work around compiler bugs,
|
||||||
|
e.g., in Cray C 5.0.3.0. */
|
||||||
|
|
||||||
|
/* True if the arithmetic type T is an integer type. bool counts as
|
||||||
|
an integer. */
|
||||||
|
#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
|
||||||
|
|
||||||
|
/* True if negative values of the signed integer type T use two's
|
||||||
|
complement, ones' complement, or signed magnitude representation,
|
||||||
|
respectively. Much GNU code assumes two's complement, but some
|
||||||
|
people like to be portable to all possible C hosts. */
|
||||||
|
#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
|
||||||
|
#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0)
|
||||||
|
#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1)
|
||||||
|
|
||||||
|
/* True if the arithmetic type T is signed. */
|
||||||
|
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
|
||||||
|
|
||||||
|
/* The maximum and minimum values for the integer type T. These
|
||||||
|
macros have undefined behavior if T is signed and has padding bits.
|
||||||
|
If this is a problem for you, please let us know how to fix it for
|
||||||
|
your host. */
|
||||||
|
#define TYPE_MINIMUM(t) \
|
||||||
|
((t) (! TYPE_SIGNED (t) \
|
||||||
|
? (t) 0 \
|
||||||
|
: TYPE_SIGNED_MAGNITUDE (t) \
|
||||||
|
? ~ (t) 0 \
|
||||||
|
: ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))
|
||||||
|
#define TYPE_MAXIMUM(t) \
|
||||||
|
((t) (! TYPE_SIGNED (t) \
|
||||||
|
? (t) -1 \
|
||||||
|
: ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))
|
||||||
|
|
||||||
|
/* Return zero if T can be determined to be an unsigned type.
|
||||||
|
Otherwise, return 1.
|
||||||
|
When compiling with GCC, INT_STRLEN_BOUND uses this macro to obtain a
|
||||||
|
tighter bound. Otherwise, it overestimates the true bound by one byte
|
||||||
|
when applied to unsigned types of size 2, 4, 16, ... bytes.
|
||||||
|
The symbol signed_type_or_expr__ is private to this header file. */
|
||||||
|
#if __GNUC__ >= 2
|
||||||
|
# define signed_type_or_expr__(t) TYPE_SIGNED (__typeof__ (t))
|
||||||
|
#else
|
||||||
|
# define signed_type_or_expr__(t) 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Bound on length of the string representing an integer type or expression T.
|
||||||
|
Subtract 1 for the sign bit if T is signed; log10 (2.0) < 146/485;
|
||||||
|
add 1 for integer division truncation; add 1 more for a minus sign
|
||||||
|
if needed. */
|
||||||
|
#define INT_STRLEN_BOUND(t) \
|
||||||
|
((sizeof (t) * CHAR_BIT - signed_type_or_expr__ (t)) * 146 / 485 \
|
||||||
|
+ signed_type_or_expr__ (t) + 1)
|
||||||
|
|
||||||
|
/* Bound on buffer size needed to represent an integer type or expression T,
|
||||||
|
including the terminating null. */
|
||||||
|
#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
|
51
lib/inttostr.c
Normal file
51
lib/inttostr.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* inttostr.c -- convert integers to printable strings
|
||||||
|
|
||||||
|
Copyright (C) 2001, 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program 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 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* Written by Paul Eggert */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "inttostr.h"
|
||||||
|
|
||||||
|
/* Convert I to a printable string in BUF, which must be at least
|
||||||
|
INT_BUFSIZE_BOUND (INTTYPE) bytes long. Return the address of the
|
||||||
|
printable string, which need not start at BUF. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
inttostr (inttype i, char *buf)
|
||||||
|
{
|
||||||
|
char *p = buf + INT_STRLEN_BOUND (inttype);
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
if (i < 0)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
*--p = '0' - i % 10;
|
||||||
|
while ((i /= 10) != 0);
|
||||||
|
|
||||||
|
*--p = '-';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do
|
||||||
|
*--p = '0' + i % 10;
|
||||||
|
while ((i /= 10) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
/* exit() function.
|
/* inttostr.h -- convert integers to printable strings
|
||||||
Copyright (C) 1995, 2001 Free Software Foundation, Inc.
|
|
||||||
|
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software
|
||||||
|
Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -13,20 +15,16 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifndef _EXIT_H
|
/* Written by Paul Eggert */
|
||||||
#define _EXIT_H
|
|
||||||
|
|
||||||
/* Get exit() declaration. */
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
/* Some systems do not define EXIT_*, even with STDC_HEADERS. */
|
#include "intprops.h"
|
||||||
#ifndef EXIT_SUCCESS
|
|
||||||
# define EXIT_SUCCESS 0
|
|
||||||
#endif
|
|
||||||
#ifndef EXIT_FAILURE
|
|
||||||
# define EXIT_FAILURE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _EXIT_H */
|
char *offtostr (off_t, char *);
|
||||||
|
char *imaxtostr (intmax_t, char *);
|
||||||
|
char *umaxtostr (uintmax_t, char *);
|
||||||
|
char *uinttostr (unsigned int, char *);
|
@ -1,5 +1,5 @@
|
|||||||
/* Copy memory area and return pointer after last written byte.
|
/* Copy memory area and return pointer after last written byte.
|
||||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
Copyright (C) 2003, 2007 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -13,11 +13,11 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
/* Specification. */
|
/* Specification. */
|
||||||
#include "mempcpy.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* Copy N bytes of SRC to DEST, return pointer to bytes after the
|
/* Copy N bytes of SRC to DEST, return pointer to bytes after the
|
||||||
|
365
lib/paxerror.c
Normal file
365
lib/paxerror.c
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
/* Miscellaneous error functions
|
||||||
|
|
||||||
|
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program 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 2, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
#include <system.h>
|
||||||
|
#include <paxlib.h>
|
||||||
|
#include <quote.h>
|
||||||
|
#include <quotearg.h>
|
||||||
|
|
||||||
|
/* Decode MODE from its binary form in a stat structure, and encode it
|
||||||
|
into a 9-byte string STRING, terminated with a NUL. */
|
||||||
|
|
||||||
|
void
|
||||||
|
pax_decode_mode (mode_t mode, char *string)
|
||||||
|
{
|
||||||
|
*string++ = mode & S_IRUSR ? 'r' : '-';
|
||||||
|
*string++ = mode & S_IWUSR ? 'w' : '-';
|
||||||
|
*string++ = (mode & S_ISUID
|
||||||
|
? (mode & S_IXUSR ? 's' : 'S')
|
||||||
|
: (mode & S_IXUSR ? 'x' : '-'));
|
||||||
|
*string++ = mode & S_IRGRP ? 'r' : '-';
|
||||||
|
*string++ = mode & S_IWGRP ? 'w' : '-';
|
||||||
|
*string++ = (mode & S_ISGID
|
||||||
|
? (mode & S_IXGRP ? 's' : 'S')
|
||||||
|
: (mode & S_IXGRP ? 'x' : '-'));
|
||||||
|
*string++ = mode & S_IROTH ? 'r' : '-';
|
||||||
|
*string++ = mode & S_IWOTH ? 'w' : '-';
|
||||||
|
*string++ = (mode & S_ISVTX
|
||||||
|
? (mode & S_IXOTH ? 't' : 'T')
|
||||||
|
: (mode & S_IXOTH ? 'x' : '-'));
|
||||||
|
*string = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Report an error associated with the system call CALL and the
|
||||||
|
optional name NAME. */
|
||||||
|
void
|
||||||
|
call_arg_error (char const *call, char const *name)
|
||||||
|
{
|
||||||
|
int e = errno;
|
||||||
|
/* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'.
|
||||||
|
Directly translating this to another language will not work, first because
|
||||||
|
%s itself is not translated.
|
||||||
|
Translate it as `%s: Function %s failed'. */
|
||||||
|
ERROR ((0, e, _("%s: Cannot %s"), quotearg_colon (name), call));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Report a fatal error associated with the system call CALL and
|
||||||
|
the optional file name NAME. */
|
||||||
|
void
|
||||||
|
call_arg_fatal (char const *call, char const *name)
|
||||||
|
{
|
||||||
|
int e = errno;
|
||||||
|
/* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'.
|
||||||
|
Directly translating this to another language will not work, first because
|
||||||
|
%s itself is not translated.
|
||||||
|
Translate it as `%s: Function %s failed'. */
|
||||||
|
FATAL_ERROR ((0, e, _("%s: Cannot %s"), quotearg_colon (name), call));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Report a warning associated with the system call CALL and
|
||||||
|
the optional file name NAME. */
|
||||||
|
void
|
||||||
|
call_arg_warn (char const *call, char const *name)
|
||||||
|
{
|
||||||
|
int e = errno;
|
||||||
|
/* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'.
|
||||||
|
Directly translating this to another language will not work, first because
|
||||||
|
%s itself is not translated.
|
||||||
|
Translate it as `%s: Function %s failed'. */
|
||||||
|
WARN ((0, e, _("%s: Warning: Cannot %s"), quotearg_colon (name), call));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
chmod_error_details (char const *name, mode_t mode)
|
||||||
|
{
|
||||||
|
int e = errno;
|
||||||
|
char buf[10];
|
||||||
|
pax_decode_mode (mode, buf);
|
||||||
|
ERROR ((0, e, _("%s: Cannot change mode to %s"),
|
||||||
|
quotearg_colon (name), buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
chown_error_details (char const *name, uid_t uid, gid_t gid)
|
||||||
|
{
|
||||||
|
int e = errno;
|
||||||
|
ERROR ((0, e, _("%s: Cannot change ownership to uid %lu, gid %lu"),
|
||||||
|
quotearg_colon (name), (unsigned long) uid, (unsigned long) gid));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
close_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("close", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
close_warn (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_warn ("close", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
exec_fatal (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_fatal ("exec", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
link_error (char const *target, char const *source)
|
||||||
|
{
|
||||||
|
int e = errno;
|
||||||
|
ERROR ((0, e, _("%s: Cannot hard link to %s"),
|
||||||
|
quotearg_colon (source), quote_n (1, target)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mkdir_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("mkdir", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mkfifo_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("mkfifo", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mknod_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("mknod", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
open_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("open", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
open_fatal (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_fatal ("open", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
open_warn (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_warn ("open", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
read_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("read", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
read_error_details (char const *name, off_t offset, size_t size)
|
||||||
|
{
|
||||||
|
char buf[UINTMAX_STRSIZE_BOUND];
|
||||||
|
int e = errno;
|
||||||
|
ERROR ((0, e,
|
||||||
|
ngettext ("%s: Read error at byte %s, while reading %lu byte",
|
||||||
|
"%s: Read error at byte %s, while reading %lu bytes",
|
||||||
|
size),
|
||||||
|
quotearg_colon (name), STRINGIFY_BIGINT (offset, buf),
|
||||||
|
(unsigned long) size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
read_warn_details (char const *name, off_t offset, size_t size)
|
||||||
|
{
|
||||||
|
char buf[UINTMAX_STRSIZE_BOUND];
|
||||||
|
int e = errno;
|
||||||
|
WARN ((0, e,
|
||||||
|
ngettext ("%s: Warning: Read error at byte %s, while reading %lu byte",
|
||||||
|
"%s: Warning: Read error at byte %s, while reading %lu bytes",
|
||||||
|
size),
|
||||||
|
quotearg_colon (name), STRINGIFY_BIGINT (offset, buf),
|
||||||
|
(unsigned long) size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
read_fatal (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_fatal ("read", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
read_fatal_details (char const *name, off_t offset, size_t size)
|
||||||
|
{
|
||||||
|
char buf[UINTMAX_STRSIZE_BOUND];
|
||||||
|
int e = errno;
|
||||||
|
FATAL_ERROR ((0, e,
|
||||||
|
ngettext ("%s: Read error at byte %s, while reading %lu byte",
|
||||||
|
"%s: Read error at byte %s, while reading %lu bytes",
|
||||||
|
size),
|
||||||
|
quotearg_colon (name), STRINGIFY_BIGINT (offset, buf),
|
||||||
|
(unsigned long) size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
readlink_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("readlink", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
readlink_warn (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_warn ("readlink", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rmdir_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("rmdir", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
savedir_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("savedir", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
savedir_warn (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_warn ("savedir", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
seek_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("seek", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
seek_error_details (char const *name, off_t offset)
|
||||||
|
{
|
||||||
|
char buf[UINTMAX_STRSIZE_BOUND];
|
||||||
|
int e = errno;
|
||||||
|
ERROR ((0, e, _("%s: Cannot seek to %s"),
|
||||||
|
quotearg_colon (name),
|
||||||
|
STRINGIFY_BIGINT (offset, buf)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
seek_warn (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_warn ("seek", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
seek_warn_details (char const *name, off_t offset)
|
||||||
|
{
|
||||||
|
char buf[UINTMAX_STRSIZE_BOUND];
|
||||||
|
int e = errno;
|
||||||
|
WARN ((0, e, _("%s: Warning: Cannot seek to %s"),
|
||||||
|
quotearg_colon (name),
|
||||||
|
STRINGIFY_BIGINT (offset, buf)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
symlink_error (char const *contents, char const *name)
|
||||||
|
{
|
||||||
|
int e = errno;
|
||||||
|
ERROR ((0, e, _("%s: Cannot create symlink to %s"),
|
||||||
|
quotearg_colon (name), quote_n (1, contents)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
stat_fatal (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_fatal ("stat", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
stat_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("stat", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
stat_warn (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_warn ("stat", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
truncate_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("truncate", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
truncate_warn (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_warn ("truncate", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
unlink_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("unlink", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
utime_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("utime", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
waitpid_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("waitpid", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
write_error (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_error ("write", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
write_error_details (char const *name, size_t status, size_t size)
|
||||||
|
{
|
||||||
|
if (status == 0)
|
||||||
|
write_error (name);
|
||||||
|
else
|
||||||
|
ERROR ((0, 0,
|
||||||
|
ngettext ("%s: Wrote only %lu of %lu byte",
|
||||||
|
"%s: Wrote only %lu of %lu bytes",
|
||||||
|
size),
|
||||||
|
name, (unsigned long int) status, (unsigned long int) size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
write_fatal (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_fatal ("write", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
chdir_fatal (char const *name)
|
||||||
|
{
|
||||||
|
call_arg_fatal ("chdir", name);
|
||||||
|
}
|
28
lib/paxexit.c
Normal file
28
lib/paxexit.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/* Miscellaneous error functions
|
||||||
|
|
||||||
|
Copyright (C) 2005, 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program 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 2, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
#include <system.h>
|
||||||
|
#include <paxlib.h>
|
||||||
|
|
||||||
|
int exit_status = PAXEXIT_SUCCESS;
|
||||||
|
|
||||||
|
void
|
||||||
|
pax_exit ()
|
||||||
|
{
|
||||||
|
exit (exit_status);
|
||||||
|
}
|
115
lib/paxlib.h
Normal file
115
lib/paxlib.h
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/* This file is part of GNU paxutils
|
||||||
|
|
||||||
|
Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003,
|
||||||
|
2005 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program 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 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _paxlib_h_
|
||||||
|
#define _paxlib_h_
|
||||||
|
|
||||||
|
#include <hash.h>
|
||||||
|
#include <inttostr.h>
|
||||||
|
|
||||||
|
/* Error reporting functions and definitions */
|
||||||
|
|
||||||
|
/* Exit status for paxutils app. Let's try to keep this list as simple as
|
||||||
|
possible. tar -d option strongly invites a status different for unequal
|
||||||
|
comparison and other errors. */
|
||||||
|
#define PAXEXIT_SUCCESS 0
|
||||||
|
#define PAXEXIT_DIFFERS 1
|
||||||
|
#define PAXEXIT_FAILURE 2
|
||||||
|
|
||||||
|
/* Both WARN and ERROR write a message on stderr and continue processing,
|
||||||
|
however ERROR manages so tar will exit unsuccessfully. FATAL_ERROR
|
||||||
|
writes a message on stderr and aborts immediately, with another message
|
||||||
|
line telling so. USAGE_ERROR works like FATAL_ERROR except that the
|
||||||
|
other message line suggests trying --help. All four macros accept a
|
||||||
|
single argument of the form ((0, errno, _("FORMAT"), Args...)). errno
|
||||||
|
is zero when the error is not being detected by the system. */
|
||||||
|
|
||||||
|
#define WARN(Args) \
|
||||||
|
error Args
|
||||||
|
#define ERROR(Args) \
|
||||||
|
(error Args, exit_status = PAXEXIT_FAILURE)
|
||||||
|
#define FATAL_ERROR(Args) \
|
||||||
|
(error Args, fatal_exit ())
|
||||||
|
#define USAGE_ERROR(Args) \
|
||||||
|
(error Args, usage (PAXEXIT_FAILURE))
|
||||||
|
|
||||||
|
extern int exit_status;
|
||||||
|
|
||||||
|
void pax_decode_mode (mode_t mode, char *string);
|
||||||
|
void call_arg_error (char const *call, char const *name);
|
||||||
|
void call_arg_fatal (char const *call, char const *name) __attribute__ ((noreturn));
|
||||||
|
void call_arg_warn (char const *call, char const *name);
|
||||||
|
void chmod_error_details (char const *name, mode_t mode);
|
||||||
|
void chown_error_details (char const *name, uid_t uid, gid_t gid);
|
||||||
|
|
||||||
|
void decode_mode (mode_t, char *);
|
||||||
|
|
||||||
|
void chdir_fatal (char const *) __attribute__ ((noreturn));
|
||||||
|
void chmod_error_details (char const *, mode_t);
|
||||||
|
void chown_error_details (char const *, uid_t, gid_t);
|
||||||
|
void close_error (char const *);
|
||||||
|
void close_warn (char const *);
|
||||||
|
void exec_fatal (char const *) __attribute__ ((noreturn));
|
||||||
|
void link_error (char const *, char const *);
|
||||||
|
void mkdir_error (char const *);
|
||||||
|
void mkfifo_error (char const *);
|
||||||
|
void mknod_error (char const *);
|
||||||
|
void open_error (char const *);
|
||||||
|
void open_fatal (char const *) __attribute__ ((noreturn));
|
||||||
|
void open_warn (char const *);
|
||||||
|
void read_error (char const *);
|
||||||
|
void read_error_details (char const *, off_t, size_t);
|
||||||
|
void read_fatal (char const *) __attribute__ ((noreturn));
|
||||||
|
void read_fatal_details (char const *, off_t, size_t) __attribute__ ((noreturn));
|
||||||
|
void read_warn_details (char const *, off_t, size_t);
|
||||||
|
void readlink_error (char const *);
|
||||||
|
void readlink_warn (char const *);
|
||||||
|
void rmdir_error (char const *);
|
||||||
|
void savedir_error (char const *);
|
||||||
|
void savedir_warn (char const *);
|
||||||
|
void seek_error (char const *);
|
||||||
|
void seek_error_details (char const *, off_t);
|
||||||
|
void seek_warn (char const *);
|
||||||
|
void seek_warn_details (char const *, off_t);
|
||||||
|
void stat_fatal (char const *);
|
||||||
|
void stat_error (char const *);
|
||||||
|
void stat_warn (char const *);
|
||||||
|
void symlink_error (char const *, char const *);
|
||||||
|
void truncate_error (char const *);
|
||||||
|
void truncate_warn (char const *);
|
||||||
|
void unlink_error (char const *);
|
||||||
|
void utime_error (char const *);
|
||||||
|
void waitpid_error (char const *);
|
||||||
|
void write_error (char const *);
|
||||||
|
|
||||||
|
void pax_exit (void);
|
||||||
|
void fatal_exit (void) __attribute__ ((noreturn));
|
||||||
|
|
||||||
|
#define STRINGIFY_BIGINT(i, b) umaxtostr (i, b)
|
||||||
|
|
||||||
|
|
||||||
|
/* Name-related functions */
|
||||||
|
bool hash_string_insert (Hash_table **table, char const *string);
|
||||||
|
bool hash_string_lookup (Hash_table const *table, char const *string);
|
||||||
|
|
||||||
|
bool removed_prefixes_p (void);
|
||||||
|
char *safer_name_suffix (char const *file_name, bool link_target, bool absolute_names);
|
||||||
|
|
||||||
|
#endif
|
156
lib/paxnames.c
Normal file
156
lib/paxnames.c
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/* This file is part of GNU paxutils
|
||||||
|
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program 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 2, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
#include <system.h>
|
||||||
|
#include <hash.h>
|
||||||
|
#include <paxlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Hash tables of strings. */
|
||||||
|
|
||||||
|
/* Calculate the hash of a string. */
|
||||||
|
static size_t
|
||||||
|
hash_string_hasher (void const *name, size_t n_buckets)
|
||||||
|
{
|
||||||
|
return hash_string (name, n_buckets);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compare two strings for equality. */
|
||||||
|
static bool
|
||||||
|
hash_string_compare (void const *name1, void const *name2)
|
||||||
|
{
|
||||||
|
return strcmp (name1, name2) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return zero if TABLE contains a copy of STRING; otherwise, insert a
|
||||||
|
copy of STRING to TABLE and return 1. */
|
||||||
|
bool
|
||||||
|
hash_string_insert (Hash_table **table, char const *string)
|
||||||
|
{
|
||||||
|
Hash_table *t = *table;
|
||||||
|
char *s = xstrdup (string);
|
||||||
|
char *e;
|
||||||
|
|
||||||
|
if (! ((t
|
||||||
|
|| (*table = t = hash_initialize (0, 0, hash_string_hasher,
|
||||||
|
hash_string_compare, 0)))
|
||||||
|
&& (e = hash_insert (t, s))))
|
||||||
|
xalloc_die ();
|
||||||
|
|
||||||
|
if (e == s)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free (s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return 1 if TABLE contains STRING. */
|
||||||
|
bool
|
||||||
|
hash_string_lookup (Hash_table const *table, char const *string)
|
||||||
|
{
|
||||||
|
return table && hash_lookup (table, string);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Hash_table *prefix_table[2];
|
||||||
|
|
||||||
|
/* Return true if file names of some members in the archive were stripped off
|
||||||
|
their leading components. We could have used
|
||||||
|
return prefix_table[0] || prefix_table[1]
|
||||||
|
but the following seems to be safer: */
|
||||||
|
bool
|
||||||
|
removed_prefixes_p (void)
|
||||||
|
{
|
||||||
|
return (prefix_table[0] && hash_get_n_entries (prefix_table[0]) != 0)
|
||||||
|
|| (prefix_table[1] && hash_get_n_entries (prefix_table[1]) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a safer suffix of FILE_NAME, or "." if it has no safer
|
||||||
|
suffix. Check for fully specified file names and other atrocities.
|
||||||
|
Warn the user if we do not return NAME. If LINK_TARGET is 1,
|
||||||
|
FILE_NAME is the target of a hard link, not a member name.
|
||||||
|
If ABSOLUTE_NAMES is 0, strip filesystem prefix from the file name. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
safer_name_suffix (char const *file_name, bool link_target, bool absolute_names)
|
||||||
|
{
|
||||||
|
char const *p;
|
||||||
|
|
||||||
|
if (absolute_names)
|
||||||
|
p = file_name;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Skip file system prefixes, leading file name components that contain
|
||||||
|
"..", and leading slashes. */
|
||||||
|
|
||||||
|
size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (file_name);
|
||||||
|
|
||||||
|
for (p = file_name + prefix_len; *p; )
|
||||||
|
{
|
||||||
|
if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2]))
|
||||||
|
prefix_len = p + 2 - file_name;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
char c = *p++;
|
||||||
|
if (ISSLASH (c))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (p = file_name + prefix_len; ISSLASH (*p); p++)
|
||||||
|
continue;
|
||||||
|
prefix_len = p - file_name;
|
||||||
|
|
||||||
|
if (prefix_len)
|
||||||
|
{
|
||||||
|
char *prefix = alloca (prefix_len + 1);
|
||||||
|
memcpy (prefix, file_name, prefix_len);
|
||||||
|
prefix[prefix_len] = '\0';
|
||||||
|
|
||||||
|
if (hash_string_insert (&prefix_table[link_target], prefix))
|
||||||
|
{
|
||||||
|
static char const *const diagnostic[] =
|
||||||
|
{
|
||||||
|
N_("Removing leading `%s' from member names"),
|
||||||
|
N_("Removing leading `%s' from hard link targets")
|
||||||
|
};
|
||||||
|
WARN ((0, 0, _(diagnostic[link_target]), prefix));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! *p)
|
||||||
|
{
|
||||||
|
if (p == file_name)
|
||||||
|
{
|
||||||
|
static char const *const diagnostic[] =
|
||||||
|
{
|
||||||
|
N_("Substituting `.' for empty member name"),
|
||||||
|
N_("Substituting `.' for empty hard link target")
|
||||||
|
};
|
||||||
|
WARN ((0, 0, "%s", _(diagnostic[link_target])));
|
||||||
|
}
|
||||||
|
|
||||||
|
p = ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
return (char *) p;
|
||||||
|
}
|
41
lib/quote.c
Normal file
41
lib/quote.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/* quote.c - quote arguments for output
|
||||||
|
|
||||||
|
Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005, 2006 Free
|
||||||
|
Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program 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 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* Written by Paul Eggert <eggert@twinsun.com> */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "quotearg.h"
|
||||||
|
#include "quote.h"
|
||||||
|
|
||||||
|
/* Return an unambiguous printable representation of NAME,
|
||||||
|
allocated in slot N, suitable for diagnostics. */
|
||||||
|
char const *
|
||||||
|
quote_n (int n, char const *name)
|
||||||
|
{
|
||||||
|
return quotearg_n_style (n, locale_quoting_style, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return an unambiguous printable representation of NAME,
|
||||||
|
suitable for diagnostics. */
|
||||||
|
char const *
|
||||||
|
quote (char const *name)
|
||||||
|
{
|
||||||
|
return quote_n (0, name);
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
/* Searching in a string.
|
/* quote.h - prototypes for quote.c
|
||||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
|
||||||
|
Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software
|
||||||
|
Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -13,16 +15,8 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#if HAVE_STRCHRNUL
|
|
||||||
|
|
||||||
/* Get strchrnul() declaration. */
|
char const *quote_n (int n, char const *name);
|
||||||
#include <string.h>
|
char const *quote (char const *name);
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* Find the first occurrence of C in S or the final NUL byte. */
|
|
||||||
extern char *strchrnul (const char *s, int c_in);
|
|
||||||
|
|
||||||
#endif
|
|
697
lib/quotearg.c
Normal file
697
lib/quotearg.c
Normal file
@ -0,0 +1,697 @@
|
|||||||
|
/* quotearg.c - quote arguments for output
|
||||||
|
|
||||||
|
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007 Free
|
||||||
|
Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program 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 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* Written by Paul Eggert <eggert@twinsun.com> */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "quotearg.h"
|
||||||
|
|
||||||
|
#include "xalloc.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <wctype.h>
|
||||||
|
|
||||||
|
#include "gettext.h"
|
||||||
|
#define _(msgid) gettext (msgid)
|
||||||
|
#define N_(msgid) msgid
|
||||||
|
|
||||||
|
#if !HAVE_MBRTOWC
|
||||||
|
/* Disable multibyte processing entirely. Since MB_CUR_MAX is 1, the
|
||||||
|
other macros are defined only for documentation and to satisfy C
|
||||||
|
syntax. */
|
||||||
|
# undef MB_CUR_MAX
|
||||||
|
# define MB_CUR_MAX 1
|
||||||
|
# undef mbstate_t
|
||||||
|
# define mbstate_t int
|
||||||
|
# define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0)
|
||||||
|
# define iswprint(wc) isprint ((unsigned char) (wc))
|
||||||
|
# undef HAVE_MBSINIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined mbsinit && !HAVE_MBSINIT
|
||||||
|
# define mbsinit(ps) 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIZE_MAX
|
||||||
|
# define SIZE_MAX ((size_t) -1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define INT_BITS (sizeof (int) * CHAR_BIT)
|
||||||
|
|
||||||
|
struct quoting_options
|
||||||
|
{
|
||||||
|
/* Basic quoting style. */
|
||||||
|
enum quoting_style style;
|
||||||
|
|
||||||
|
/* Quote the characters indicated by this bit vector even if the
|
||||||
|
quoting style would not normally require them to be quoted. */
|
||||||
|
unsigned int quote_these_too[(UCHAR_MAX / INT_BITS) + 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Names of quoting styles. */
|
||||||
|
char const *const quoting_style_args[] =
|
||||||
|
{
|
||||||
|
"literal",
|
||||||
|
"shell",
|
||||||
|
"shell-always",
|
||||||
|
"c",
|
||||||
|
"escape",
|
||||||
|
"locale",
|
||||||
|
"clocale",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Correspondences to quoting style names. */
|
||||||
|
enum quoting_style const quoting_style_vals[] =
|
||||||
|
{
|
||||||
|
literal_quoting_style,
|
||||||
|
shell_quoting_style,
|
||||||
|
shell_always_quoting_style,
|
||||||
|
c_quoting_style,
|
||||||
|
escape_quoting_style,
|
||||||
|
locale_quoting_style,
|
||||||
|
clocale_quoting_style
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The default quoting options. */
|
||||||
|
static struct quoting_options default_quoting_options;
|
||||||
|
|
||||||
|
/* Allocate a new set of quoting options, with contents initially identical
|
||||||
|
to O if O is not null, or to the default if O is null.
|
||||||
|
It is the caller's responsibility to free the result. */
|
||||||
|
struct quoting_options *
|
||||||
|
clone_quoting_options (struct quoting_options *o)
|
||||||
|
{
|
||||||
|
int e = errno;
|
||||||
|
struct quoting_options *p = xmemdup (o ? o : &default_quoting_options,
|
||||||
|
sizeof *o);
|
||||||
|
errno = e;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the value of O's quoting style. If O is null, use the default. */
|
||||||
|
enum quoting_style
|
||||||
|
get_quoting_style (struct quoting_options *o)
|
||||||
|
{
|
||||||
|
return (o ? o : &default_quoting_options)->style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In O (or in the default if O is null),
|
||||||
|
set the value of the quoting style to S. */
|
||||||
|
void
|
||||||
|
set_quoting_style (struct quoting_options *o, enum quoting_style s)
|
||||||
|
{
|
||||||
|
(o ? o : &default_quoting_options)->style = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In O (or in the default if O is null),
|
||||||
|
set the value of the quoting options for character C to I.
|
||||||
|
Return the old value. Currently, the only values defined for I are
|
||||||
|
0 (the default) and 1 (which means to quote the character even if
|
||||||
|
it would not otherwise be quoted). */
|
||||||
|
int
|
||||||
|
set_char_quoting (struct quoting_options *o, char c, int i)
|
||||||
|
{
|
||||||
|
unsigned char uc = c;
|
||||||
|
unsigned int *p =
|
||||||
|
(o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
|
||||||
|
int shift = uc % INT_BITS;
|
||||||
|
int r = (*p >> shift) & 1;
|
||||||
|
*p ^= ((i & 1) ^ r) << shift;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MSGID approximates a quotation mark. Return its translation if it
|
||||||
|
has one; otherwise, return either it or "\"", depending on S. */
|
||||||
|
static char const *
|
||||||
|
gettext_quote (char const *msgid, enum quoting_style s)
|
||||||
|
{
|
||||||
|
char const *translation = _(msgid);
|
||||||
|
if (translation == msgid && s == clocale_quoting_style)
|
||||||
|
translation = "\"";
|
||||||
|
return translation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
|
||||||
|
argument ARG (of size ARGSIZE), using QUOTING_STYLE and the
|
||||||
|
non-quoting-style part of O to control quoting.
|
||||||
|
Terminate the output with a null character, and return the written
|
||||||
|
size of the output, not counting the terminating null.
|
||||||
|
If BUFFERSIZE is too small to store the output string, return the
|
||||||
|
value that would have been returned had BUFFERSIZE been large enough.
|
||||||
|
If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE.
|
||||||
|
|
||||||
|
This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
|
||||||
|
ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting
|
||||||
|
style specified by O, and O may not be null. */
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
quotearg_buffer_restyled (char *buffer, size_t buffersize,
|
||||||
|
char const *arg, size_t argsize,
|
||||||
|
enum quoting_style quoting_style,
|
||||||
|
struct quoting_options const *o)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
size_t len = 0;
|
||||||
|
char const *quote_string = 0;
|
||||||
|
size_t quote_string_len = 0;
|
||||||
|
bool backslash_escapes = false;
|
||||||
|
bool unibyte_locale = MB_CUR_MAX == 1;
|
||||||
|
|
||||||
|
#define STORE(c) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (len < buffersize) \
|
||||||
|
buffer[len] = (c); \
|
||||||
|
len++; \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
switch (quoting_style)
|
||||||
|
{
|
||||||
|
case c_quoting_style:
|
||||||
|
STORE ('"');
|
||||||
|
backslash_escapes = true;
|
||||||
|
quote_string = "\"";
|
||||||
|
quote_string_len = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case escape_quoting_style:
|
||||||
|
backslash_escapes = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case locale_quoting_style:
|
||||||
|
case clocale_quoting_style:
|
||||||
|
{
|
||||||
|
/* TRANSLATORS:
|
||||||
|
Get translations for open and closing quotation marks.
|
||||||
|
|
||||||
|
The message catalog should translate "`" to a left
|
||||||
|
quotation mark suitable for the locale, and similarly for
|
||||||
|
"'". If the catalog has no translation,
|
||||||
|
locale_quoting_style quotes `like this', and
|
||||||
|
clocale_quoting_style quotes "like this".
|
||||||
|
|
||||||
|
For example, an American English Unicode locale should
|
||||||
|
translate "`" to U+201C (LEFT DOUBLE QUOTATION MARK), and
|
||||||
|
should translate "'" to U+201D (RIGHT DOUBLE QUOTATION
|
||||||
|
MARK). A British English Unicode locale should instead
|
||||||
|
translate these to U+2018 (LEFT SINGLE QUOTATION MARK) and
|
||||||
|
U+2019 (RIGHT SINGLE QUOTATION MARK), respectively.
|
||||||
|
|
||||||
|
If you don't know what to put here, please see
|
||||||
|
<http://en.wikipedia.org/wiki/Quotation_mark#Glyphs>
|
||||||
|
and use glyphs suitable for your language. */
|
||||||
|
|
||||||
|
char const *left = gettext_quote (N_("`"), quoting_style);
|
||||||
|
char const *right = gettext_quote (N_("'"), quoting_style);
|
||||||
|
for (quote_string = left; *quote_string; quote_string++)
|
||||||
|
STORE (*quote_string);
|
||||||
|
backslash_escapes = true;
|
||||||
|
quote_string = right;
|
||||||
|
quote_string_len = strlen (quote_string);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case shell_always_quoting_style:
|
||||||
|
STORE ('\'');
|
||||||
|
quote_string = "'";
|
||||||
|
quote_string_len = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize); i++)
|
||||||
|
{
|
||||||
|
unsigned char c;
|
||||||
|
unsigned char esc;
|
||||||
|
|
||||||
|
if (backslash_escapes
|
||||||
|
&& quote_string_len
|
||||||
|
&& i + quote_string_len <= argsize
|
||||||
|
&& memcmp (arg + i, quote_string, quote_string_len) == 0)
|
||||||
|
STORE ('\\');
|
||||||
|
|
||||||
|
c = arg[i];
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '\0':
|
||||||
|
if (backslash_escapes)
|
||||||
|
{
|
||||||
|
STORE ('\\');
|
||||||
|
STORE ('0');
|
||||||
|
STORE ('0');
|
||||||
|
c = '0';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '?':
|
||||||
|
switch (quoting_style)
|
||||||
|
{
|
||||||
|
case shell_quoting_style:
|
||||||
|
goto use_shell_always_quoting_style;
|
||||||
|
|
||||||
|
case c_quoting_style:
|
||||||
|
if (i + 2 < argsize && arg[i + 1] == '?')
|
||||||
|
switch (arg[i + 2])
|
||||||
|
{
|
||||||
|
case '!': case '\'':
|
||||||
|
case '(': case ')': case '-': case '/':
|
||||||
|
case '<': case '=': case '>':
|
||||||
|
/* Escape the second '?' in what would otherwise be
|
||||||
|
a trigraph. */
|
||||||
|
c = arg[i + 2];
|
||||||
|
i += 2;
|
||||||
|
STORE ('?');
|
||||||
|
STORE ('\\');
|
||||||
|
STORE ('?');
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\a': esc = 'a'; goto c_escape;
|
||||||
|
case '\b': esc = 'b'; goto c_escape;
|
||||||
|
case '\f': esc = 'f'; goto c_escape;
|
||||||
|
case '\n': esc = 'n'; goto c_and_shell_escape;
|
||||||
|
case '\r': esc = 'r'; goto c_and_shell_escape;
|
||||||
|
case '\t': esc = 't'; goto c_and_shell_escape;
|
||||||
|
case '\v': esc = 'v'; goto c_escape;
|
||||||
|
case '\\': esc = c; goto c_and_shell_escape;
|
||||||
|
|
||||||
|
c_and_shell_escape:
|
||||||
|
if (quoting_style == shell_quoting_style)
|
||||||
|
goto use_shell_always_quoting_style;
|
||||||
|
c_escape:
|
||||||
|
if (backslash_escapes)
|
||||||
|
{
|
||||||
|
c = esc;
|
||||||
|
goto store_escape;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '{': case '}': /* sometimes special if isolated */
|
||||||
|
if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1))
|
||||||
|
break;
|
||||||
|
/* Fall through. */
|
||||||
|
case '#': case '~':
|
||||||
|
if (i != 0)
|
||||||
|
break;
|
||||||
|
/* Fall through. */
|
||||||
|
case ' ':
|
||||||
|
case '!': /* special in bash */
|
||||||
|
case '"': case '$': case '&':
|
||||||
|
case '(': case ')': case '*': case ';':
|
||||||
|
case '<':
|
||||||
|
case '=': /* sometimes special in 0th or (with "set -k") later args */
|
||||||
|
case '>': case '[':
|
||||||
|
case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
|
||||||
|
case '`': case '|':
|
||||||
|
/* A shell special character. In theory, '$' and '`' could
|
||||||
|
be the first bytes of multibyte characters, which means
|
||||||
|
we should check them with mbrtowc, but in practice this
|
||||||
|
doesn't happen so it's not worth worrying about. */
|
||||||
|
if (quoting_style == shell_quoting_style)
|
||||||
|
goto use_shell_always_quoting_style;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\'':
|
||||||
|
switch (quoting_style)
|
||||||
|
{
|
||||||
|
case shell_quoting_style:
|
||||||
|
goto use_shell_always_quoting_style;
|
||||||
|
|
||||||
|
case shell_always_quoting_style:
|
||||||
|
STORE ('\'');
|
||||||
|
STORE ('\\');
|
||||||
|
STORE ('\'');
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '%': case '+': case ',': case '-': case '.': case '/':
|
||||||
|
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||||
|
case '6': case '7': case '8': case '9': case ':':
|
||||||
|
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||||
|
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
|
||||||
|
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||||
|
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||||
|
case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
|
||||||
|
case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
|
||||||
|
case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
|
||||||
|
case 'o': case 'p': case 'q': case 'r': case 's': case 't':
|
||||||
|
case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
|
||||||
|
/* These characters don't cause problems, no matter what the
|
||||||
|
quoting style is. They cannot start multibyte sequences. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* If we have a multibyte sequence, copy it until we reach
|
||||||
|
its end, find an error, or come back to the initial shift
|
||||||
|
state. For C-like styles, if the sequence has
|
||||||
|
unprintable characters, escape the whole sequence, since
|
||||||
|
we can't easily escape single characters within it. */
|
||||||
|
{
|
||||||
|
/* Length of multibyte sequence found so far. */
|
||||||
|
size_t m;
|
||||||
|
|
||||||
|
bool printable;
|
||||||
|
|
||||||
|
if (unibyte_locale)
|
||||||
|
{
|
||||||
|
m = 1;
|
||||||
|
printable = isprint (c) != 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mbstate_t mbstate;
|
||||||
|
memset (&mbstate, 0, sizeof mbstate);
|
||||||
|
|
||||||
|
m = 0;
|
||||||
|
printable = true;
|
||||||
|
if (argsize == SIZE_MAX)
|
||||||
|
argsize = strlen (arg);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
wchar_t w;
|
||||||
|
size_t bytes = mbrtowc (&w, &arg[i + m],
|
||||||
|
argsize - (i + m), &mbstate);
|
||||||
|
if (bytes == 0)
|
||||||
|
break;
|
||||||
|
else if (bytes == (size_t) -1)
|
||||||
|
{
|
||||||
|
printable = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (bytes == (size_t) -2)
|
||||||
|
{
|
||||||
|
printable = false;
|
||||||
|
while (i + m < argsize && arg[i + m])
|
||||||
|
m++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Work around a bug with older shells that "see" a '\'
|
||||||
|
that is really the 2nd byte of a multibyte character.
|
||||||
|
In practice the problem is limited to ASCII
|
||||||
|
chars >= '@' that are shell special chars. */
|
||||||
|
if ('[' == 0x5b && quoting_style == shell_quoting_style)
|
||||||
|
{
|
||||||
|
size_t j;
|
||||||
|
for (j = 1; j < bytes; j++)
|
||||||
|
switch (arg[i + m + j])
|
||||||
|
{
|
||||||
|
case '[': case '\\': case '^':
|
||||||
|
case '`': case '|':
|
||||||
|
goto use_shell_always_quoting_style;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! iswprint (w))
|
||||||
|
printable = false;
|
||||||
|
m += bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (! mbsinit (&mbstate));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (1 < m || (backslash_escapes && ! printable))
|
||||||
|
{
|
||||||
|
/* Output a multibyte sequence, or an escaped
|
||||||
|
unprintable unibyte character. */
|
||||||
|
size_t ilim = i + m;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (backslash_escapes && ! printable)
|
||||||
|
{
|
||||||
|
STORE ('\\');
|
||||||
|
STORE ('0' + (c >> 6));
|
||||||
|
STORE ('0' + ((c >> 3) & 7));
|
||||||
|
c = '0' + (c & 7);
|
||||||
|
}
|
||||||
|
if (ilim <= i + 1)
|
||||||
|
break;
|
||||||
|
STORE (c);
|
||||||
|
c = arg[++i];
|
||||||
|
}
|
||||||
|
|
||||||
|
goto store_c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! (backslash_escapes
|
||||||
|
&& o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
|
||||||
|
goto store_c;
|
||||||
|
|
||||||
|
store_escape:
|
||||||
|
STORE ('\\');
|
||||||
|
|
||||||
|
store_c:
|
||||||
|
STORE (c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0 && quoting_style == shell_quoting_style)
|
||||||
|
goto use_shell_always_quoting_style;
|
||||||
|
|
||||||
|
if (quote_string)
|
||||||
|
for (; *quote_string; quote_string++)
|
||||||
|
STORE (*quote_string);
|
||||||
|
|
||||||
|
if (len < buffersize)
|
||||||
|
buffer[len] = '\0';
|
||||||
|
return len;
|
||||||
|
|
||||||
|
use_shell_always_quoting_style:
|
||||||
|
return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
|
||||||
|
shell_always_quoting_style, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
|
||||||
|
argument ARG (of size ARGSIZE), using O to control quoting.
|
||||||
|
If O is null, use the default.
|
||||||
|
Terminate the output with a null character, and return the written
|
||||||
|
size of the output, not counting the terminating null.
|
||||||
|
If BUFFERSIZE is too small to store the output string, return the
|
||||||
|
value that would have been returned had BUFFERSIZE been large enough.
|
||||||
|
If ARGSIZE is SIZE_MAX, use the string length of the argument for
|
||||||
|
ARGSIZE. */
|
||||||
|
size_t
|
||||||
|
quotearg_buffer (char *buffer, size_t buffersize,
|
||||||
|
char const *arg, size_t argsize,
|
||||||
|
struct quoting_options const *o)
|
||||||
|
{
|
||||||
|
struct quoting_options const *p = o ? o : &default_quoting_options;
|
||||||
|
int e = errno;
|
||||||
|
size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
|
||||||
|
p->style, p);
|
||||||
|
errno = e;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly
|
||||||
|
allocated storage containing the quoted string. */
|
||||||
|
char *
|
||||||
|
quotearg_alloc (char const *arg, size_t argsize,
|
||||||
|
struct quoting_options const *o)
|
||||||
|
{
|
||||||
|
int e = errno;
|
||||||
|
size_t bufsize = quotearg_buffer (0, 0, arg, argsize, o) + 1;
|
||||||
|
char *buf = xcharalloc (bufsize);
|
||||||
|
quotearg_buffer (buf, bufsize, arg, argsize, o);
|
||||||
|
errno = e;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A storage slot with size and pointer to a value. */
|
||||||
|
struct slotvec
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
char *val;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Preallocate a slot 0 buffer, so that the caller can always quote
|
||||||
|
one small component of a "memory exhausted" message in slot 0. */
|
||||||
|
static char slot0[256];
|
||||||
|
static unsigned int nslots = 1;
|
||||||
|
static struct slotvec slotvec0 = {sizeof slot0, slot0};
|
||||||
|
static struct slotvec *slotvec = &slotvec0;
|
||||||
|
|
||||||
|
void
|
||||||
|
quotearg_free (void)
|
||||||
|
{
|
||||||
|
struct slotvec *sv = slotvec;
|
||||||
|
unsigned int i;
|
||||||
|
for (i = 1; i < nslots; i++)
|
||||||
|
free (sv[i].val);
|
||||||
|
if (sv[0].val != slot0)
|
||||||
|
{
|
||||||
|
free (sv[0].val);
|
||||||
|
slotvec0.size = sizeof slot0;
|
||||||
|
slotvec0.val = slot0;
|
||||||
|
}
|
||||||
|
if (sv != &slotvec0)
|
||||||
|
{
|
||||||
|
free (sv);
|
||||||
|
slotvec = &slotvec0;
|
||||||
|
}
|
||||||
|
nslots = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use storage slot N to return a quoted version of argument ARG.
|
||||||
|
ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a
|
||||||
|
null-terminated string.
|
||||||
|
OPTIONS specifies the quoting options.
|
||||||
|
The returned value points to static storage that can be
|
||||||
|
reused by the next call to this function with the same value of N.
|
||||||
|
N must be nonnegative. N is deliberately declared with type "int"
|
||||||
|
to allow for future extensions (using negative values). */
|
||||||
|
static char *
|
||||||
|
quotearg_n_options (int n, char const *arg, size_t argsize,
|
||||||
|
struct quoting_options const *options)
|
||||||
|
{
|
||||||
|
int e = errno;
|
||||||
|
|
||||||
|
unsigned int n0 = n;
|
||||||
|
struct slotvec *sv = slotvec;
|
||||||
|
|
||||||
|
if (n < 0)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
if (nslots <= n0)
|
||||||
|
{
|
||||||
|
/* FIXME: technically, the type of n1 should be `unsigned int',
|
||||||
|
but that evokes an unsuppressible warning from gcc-4.0.1 and
|
||||||
|
older. If gcc ever provides an option to suppress that warning,
|
||||||
|
revert to the original type, so that the test in xalloc_oversized
|
||||||
|
is once again performed only at compile time. */
|
||||||
|
size_t n1 = n0 + 1;
|
||||||
|
bool preallocated = (sv == &slotvec0);
|
||||||
|
|
||||||
|
if (xalloc_oversized (n1, sizeof *sv))
|
||||||
|
xalloc_die ();
|
||||||
|
|
||||||
|
slotvec = sv = xrealloc (preallocated ? NULL : sv, n1 * sizeof *sv);
|
||||||
|
if (preallocated)
|
||||||
|
*sv = slotvec0;
|
||||||
|
memset (sv + nslots, 0, (n1 - nslots) * sizeof *sv);
|
||||||
|
nslots = n1;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
size_t size = sv[n].size;
|
||||||
|
char *val = sv[n].val;
|
||||||
|
size_t qsize = quotearg_buffer (val, size, arg, argsize, options);
|
||||||
|
|
||||||
|
if (size <= qsize)
|
||||||
|
{
|
||||||
|
sv[n].size = size = qsize + 1;
|
||||||
|
if (val != slot0)
|
||||||
|
free (val);
|
||||||
|
sv[n].val = val = xcharalloc (size);
|
||||||
|
quotearg_buffer (val, size, arg, argsize, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = e;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
quotearg_n (int n, char const *arg)
|
||||||
|
{
|
||||||
|
return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
quotearg (char const *arg)
|
||||||
|
{
|
||||||
|
return quotearg_n (0, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return quoting options for STYLE, with no extra quoting. */
|
||||||
|
static struct quoting_options
|
||||||
|
quoting_options_from_style (enum quoting_style style)
|
||||||
|
{
|
||||||
|
struct quoting_options o;
|
||||||
|
o.style = style;
|
||||||
|
memset (o.quote_these_too, 0, sizeof o.quote_these_too);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
quotearg_n_style (int n, enum quoting_style s, char const *arg)
|
||||||
|
{
|
||||||
|
struct quoting_options const o = quoting_options_from_style (s);
|
||||||
|
return quotearg_n_options (n, arg, SIZE_MAX, &o);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
quotearg_n_style_mem (int n, enum quoting_style s,
|
||||||
|
char const *arg, size_t argsize)
|
||||||
|
{
|
||||||
|
struct quoting_options const o = quoting_options_from_style (s);
|
||||||
|
return quotearg_n_options (n, arg, argsize, &o);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
quotearg_style (enum quoting_style s, char const *arg)
|
||||||
|
{
|
||||||
|
return quotearg_n_style (0, s, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
quotearg_char (char const *arg, char ch)
|
||||||
|
{
|
||||||
|
struct quoting_options options;
|
||||||
|
options = default_quoting_options;
|
||||||
|
set_char_quoting (&options, ch, 1);
|
||||||
|
return quotearg_n_options (0, arg, SIZE_MAX, &options);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
quotearg_colon (char const *arg)
|
||||||
|
{
|
||||||
|
return quotearg_char (arg, ':');
|
||||||
|
}
|
140
lib/quotearg.h
Normal file
140
lib/quotearg.h
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/* quotearg.h - quote arguments for output
|
||||||
|
|
||||||
|
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2006 Free
|
||||||
|
Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program 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 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* Written by Paul Eggert <eggert@twinsun.com> */
|
||||||
|
|
||||||
|
#ifndef QUOTEARG_H_
|
||||||
|
# define QUOTEARG_H_ 1
|
||||||
|
|
||||||
|
# include <stddef.h>
|
||||||
|
|
||||||
|
/* Basic quoting styles. */
|
||||||
|
enum quoting_style
|
||||||
|
{
|
||||||
|
/* Output names as-is (ls --quoting-style=literal). */
|
||||||
|
literal_quoting_style,
|
||||||
|
|
||||||
|
/* Quote names for the shell if they contain shell metacharacters
|
||||||
|
or would cause ambiguous output (ls --quoting-style=shell). */
|
||||||
|
shell_quoting_style,
|
||||||
|
|
||||||
|
/* Quote names for the shell, even if they would normally not
|
||||||
|
require quoting (ls --quoting-style=shell-always). */
|
||||||
|
shell_always_quoting_style,
|
||||||
|
|
||||||
|
/* Quote names as for a C language string (ls --quoting-style=c). */
|
||||||
|
c_quoting_style,
|
||||||
|
|
||||||
|
/* Like c_quoting_style except omit the surrounding double-quote
|
||||||
|
characters (ls --quoting-style=escape). */
|
||||||
|
escape_quoting_style,
|
||||||
|
|
||||||
|
/* Like clocale_quoting_style, but quote `like this' instead of
|
||||||
|
"like this" in the default C locale (ls --quoting-style=locale). */
|
||||||
|
locale_quoting_style,
|
||||||
|
|
||||||
|
/* Like c_quoting_style except use quotation marks appropriate for
|
||||||
|
the locale (ls --quoting-style=clocale). */
|
||||||
|
clocale_quoting_style
|
||||||
|
};
|
||||||
|
|
||||||
|
/* For now, --quoting-style=literal is the default, but this may change. */
|
||||||
|
# ifndef DEFAULT_QUOTING_STYLE
|
||||||
|
# define DEFAULT_QUOTING_STYLE literal_quoting_style
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* Names of quoting styles and their corresponding values. */
|
||||||
|
extern char const *const quoting_style_args[];
|
||||||
|
extern enum quoting_style const quoting_style_vals[];
|
||||||
|
|
||||||
|
struct quoting_options;
|
||||||
|
|
||||||
|
/* The functions listed below set and use a hidden variable
|
||||||
|
that contains the default quoting style options. */
|
||||||
|
|
||||||
|
/* Allocate a new set of quoting options, with contents initially identical
|
||||||
|
to O if O is not null, or to the default if O is null.
|
||||||
|
It is the caller's responsibility to free the result. */
|
||||||
|
struct quoting_options *clone_quoting_options (struct quoting_options *o);
|
||||||
|
|
||||||
|
/* Get the value of O's quoting style. If O is null, use the default. */
|
||||||
|
enum quoting_style get_quoting_style (struct quoting_options *o);
|
||||||
|
|
||||||
|
/* In O (or in the default if O is null),
|
||||||
|
set the value of the quoting style to S. */
|
||||||
|
void set_quoting_style (struct quoting_options *o, enum quoting_style s);
|
||||||
|
|
||||||
|
/* In O (or in the default if O is null),
|
||||||
|
set the value of the quoting options for character C to I.
|
||||||
|
Return the old value. Currently, the only values defined for I are
|
||||||
|
0 (the default) and 1 (which means to quote the character even if
|
||||||
|
it would not otherwise be quoted). */
|
||||||
|
int set_char_quoting (struct quoting_options *o, char c, int i);
|
||||||
|
|
||||||
|
/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
|
||||||
|
argument ARG (of size ARGSIZE), using O to control quoting.
|
||||||
|
If O is null, use the default.
|
||||||
|
Terminate the output with a null character, and return the written
|
||||||
|
size of the output, not counting the terminating null.
|
||||||
|
If BUFFERSIZE is too small to store the output string, return the
|
||||||
|
value that would have been returned had BUFFERSIZE been large enough.
|
||||||
|
If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */
|
||||||
|
size_t quotearg_buffer (char *buffer, size_t buffersize,
|
||||||
|
char const *arg, size_t argsize,
|
||||||
|
struct quoting_options const *o);
|
||||||
|
|
||||||
|
/* Like quotearg_buffer, except return the result in a newly allocated
|
||||||
|
buffer. It is the caller's responsibility to free the result. */
|
||||||
|
char *quotearg_alloc (char const *arg, size_t argsize,
|
||||||
|
struct quoting_options const *o);
|
||||||
|
|
||||||
|
/* Use storage slot N to return a quoted version of the string ARG.
|
||||||
|
Use the default quoting options.
|
||||||
|
The returned value points to static storage that can be
|
||||||
|
reused by the next call to this function with the same value of N.
|
||||||
|
N must be nonnegative. */
|
||||||
|
char *quotearg_n (int n, char const *arg);
|
||||||
|
|
||||||
|
/* Equivalent to quotearg_n (0, ARG). */
|
||||||
|
char *quotearg (char const *arg);
|
||||||
|
|
||||||
|
/* Use style S and storage slot N to return a quoted version of the string ARG.
|
||||||
|
This is like quotearg_n (N, ARG), except that it uses S with no other
|
||||||
|
options to specify the quoting method. */
|
||||||
|
char *quotearg_n_style (int n, enum quoting_style s, char const *arg);
|
||||||
|
|
||||||
|
/* Use style S and storage slot N to return a quoted version of the
|
||||||
|
argument ARG of size ARGSIZE. This is like quotearg_n_style
|
||||||
|
(N, S, ARG), except it can quote null bytes. */
|
||||||
|
char *quotearg_n_style_mem (int n, enum quoting_style s,
|
||||||
|
char const *arg, size_t argsize);
|
||||||
|
|
||||||
|
/* Equivalent to quotearg_n_style (0, S, ARG). */
|
||||||
|
char *quotearg_style (enum quoting_style s, char const *arg);
|
||||||
|
|
||||||
|
/* Like quotearg (ARG), except also quote any instances of CH. */
|
||||||
|
char *quotearg_char (char const *arg, char ch);
|
||||||
|
|
||||||
|
/* Equivalent to quotearg_char (ARG, ':'). */
|
||||||
|
char *quotearg_colon (char const *arg);
|
||||||
|
|
||||||
|
/* Free any dynamically allocated memory. */
|
||||||
|
void quotearg_free (void);
|
||||||
|
|
||||||
|
#endif /* !QUOTEARG_H_ */
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
extern char *rmt_command;
|
extern char *rmt_command;
|
||||||
extern char *rmt_dev_name__;
|
extern char *rmt_dev_name__;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* Functions for communicating with a remote tape drive.
|
/* Functions for communicating with a remote tape drive.
|
||||||
|
|
||||||
Copyright 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2004 Free
|
Copyright (C) 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2004,
|
||||||
Software Foundation, Inc.
|
2005, 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
/* The man page rmt(8) for /etc/rmt documents the remote mag tape protocol
|
/* The man page rmt(8) for /etc/rmt documents the remote mag tape protocol
|
||||||
which rdump and rrestore use. Unfortunately, the man page is *WRONG*.
|
which rdump and rrestore use. Unfortunately, the man page is *WRONG*.
|
||||||
@ -33,6 +33,8 @@
|
|||||||
code, courtesy of Dan Kegel. */
|
code, courtesy of Dan Kegel. */
|
||||||
|
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
#include "system-ioctl.h"
|
||||||
|
|
||||||
#include <safe-read.h>
|
#include <safe-read.h>
|
||||||
#include <full-write.h>
|
#include <full-write.h>
|
||||||
|
|
||||||
@ -58,7 +60,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <rmt.h>
|
#include <rmt.h>
|
||||||
#include <localedir.h>
|
#include <rmt-command.h>
|
||||||
|
|
||||||
/* Exit status if exec errors. */
|
/* Exit status if exec errors. */
|
||||||
#define EXIT_ON_EXEC_ERROR 128
|
#define EXIT_ON_EXEC_ERROR 128
|
||||||
@ -340,9 +342,7 @@ encode_oflag (char *buf, int oflag)
|
|||||||
#ifdef O_NOCTTY
|
#ifdef O_NOCTTY
|
||||||
if (oflag & O_NOCTTY) strcat (buf, "|O_NOCTTY");
|
if (oflag & O_NOCTTY) strcat (buf, "|O_NOCTTY");
|
||||||
#endif
|
#endif
|
||||||
#ifdef O_NONBLOCK
|
|
||||||
if (oflag & O_NONBLOCK) strcat (buf, "|O_NONBLOCK");
|
if (oflag & O_NONBLOCK) strcat (buf, "|O_NONBLOCK");
|
||||||
#endif
|
|
||||||
#ifdef O_RSYNC
|
#ifdef O_RSYNC
|
||||||
if (oflag & O_RSYNC) strcat (buf, "|O_RSYNC");
|
if (oflag & O_RSYNC) strcat (buf, "|O_RSYNC");
|
||||||
#endif
|
#endif
|
||||||
@ -358,7 +358,7 @@ encode_oflag (char *buf, int oflag)
|
|||||||
remote pipe number plus BIAS. REMOTE_SHELL may be overridden. On
|
remote pipe number plus BIAS. REMOTE_SHELL may be overridden. On
|
||||||
error, return -1. */
|
error, return -1. */
|
||||||
int
|
int
|
||||||
rmt_open__ (const char *file_name, int open_mode, int bias,
|
rmt_open__ (const char *file_name, int open_mode, int bias,
|
||||||
const char *remote_shell)
|
const char *remote_shell)
|
||||||
{
|
{
|
||||||
int remote_pipe_number; /* pseudo, biased file descriptor */
|
int remote_pipe_number; /* pseudo, biased file descriptor */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* An interface to read and write that retries after interrupts.
|
/* An interface to read and write that retries after interrupts.
|
||||||
|
|
||||||
Copyright (C) 1993, 1994, 1998, 2002, 2003, 2004 Free Software
|
Copyright (C) 1993, 1994, 1998, 2002, 2003, 2004, 2005, 2006 Free
|
||||||
Foundation, Inc.
|
Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -15,11 +15,9 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
#include <config.h>
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Specification. */
|
/* Specification. */
|
||||||
#ifdef SAFE_WRITE
|
#ifdef SAFE_WRITE
|
||||||
@ -30,9 +28,7 @@
|
|||||||
|
|
||||||
/* Get ssize_t. */
|
/* Get ssize_t. */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#if HAVE_UNISTD_H
|
#include <unistd.h>
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* An interface to read() that retries after interrupts.
|
/* An interface to read() that retries after interrupts.
|
||||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
Copyright (C) 2002, 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -13,13 +13,23 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define SAFE_READ_ERROR ((size_t) -1)
|
#define SAFE_READ_ERROR ((size_t) -1)
|
||||||
|
|
||||||
/* Read up to COUNT bytes at BUF from descriptor FD, retrying if interrupted.
|
/* Read up to COUNT bytes at BUF from descriptor FD, retrying if interrupted.
|
||||||
Return the actual number of bytes read, zero for EOF, or SAFE_READ_ERROR
|
Return the actual number of bytes read, zero for EOF, or SAFE_READ_ERROR
|
||||||
upon error. */
|
upon error. */
|
||||||
extern size_t safe_read (int fd, void *buf, size_t count);
|
extern size_t safe_read (int fd, void *buf, size_t count);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#define SAFE_WRITE
|
#define SAFE_WRITE
|
||||||
#include "safe-read.c"
|
#include "safe-read.c"
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* savedir.c -- save the list of files in a directory in a string
|
/* savedir.c -- save the list of files in a directory in a string
|
||||||
|
|
||||||
Copyright 1990, 1997, 1998, 1999, 2000, 2001, 2003, 2004 Free
|
Copyright (C) 1990, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
|
||||||
Software Foundation, Inc.
|
2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -15,13 +15,11 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
#include <config.h>
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "savedir.h"
|
#include "savedir.h"
|
||||||
|
|
||||||
@ -29,68 +27,62 @@
|
|||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#if HAVE_DIRENT_H
|
#include <dirent.h>
|
||||||
# include <dirent.h>
|
#ifndef _D_EXACT_NAMLEN
|
||||||
#else
|
# define _D_EXACT_NAMLEN(dp) strlen ((dp)->d_name)
|
||||||
# define dirent direct
|
|
||||||
# if HAVE_SYS_NDIR_H
|
|
||||||
# include <sys/ndir.h>
|
|
||||||
# endif
|
|
||||||
# if HAVE_SYS_DIR_H
|
|
||||||
# include <sys/dir.h>
|
|
||||||
# endif
|
|
||||||
# if HAVE_NDIR_H
|
|
||||||
# include <ndir.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CLOSEDIR_VOID
|
|
||||||
/* Fake a return value. */
|
|
||||||
# define CLOSEDIR(d) (closedir (d), 0)
|
|
||||||
#else
|
|
||||||
# define CLOSEDIR(d) closedir (d)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "openat.h"
|
||||||
#include "xalloc.h"
|
#include "xalloc.h"
|
||||||
|
|
||||||
/* Return a freshly allocated string containing the filenames
|
|
||||||
in directory DIR, separated by '\0' characters;
|
|
||||||
the end is marked by two '\0' characters in a row.
|
|
||||||
Return NULL (setting errno) if DIR cannot be opened, read, or closed. */
|
|
||||||
|
|
||||||
#ifndef NAME_SIZE_DEFAULT
|
#ifndef NAME_SIZE_DEFAULT
|
||||||
# define NAME_SIZE_DEFAULT 512
|
# define NAME_SIZE_DEFAULT 512
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *
|
/* The results of opendir() in this file are not used with dirfd and fchdir,
|
||||||
savedir (const char *dir)
|
therefore save some unnecessary work in fchdir.c. */
|
||||||
|
#undef opendir
|
||||||
|
#undef closedir
|
||||||
|
|
||||||
|
/* Return a freshly allocated string containing the file names
|
||||||
|
in directory DIRP, separated by '\0' characters;
|
||||||
|
the end is marked by two '\0' characters in a row.
|
||||||
|
Return NULL (setting errno) if DIRP cannot be read or closed.
|
||||||
|
If DIRP is NULL, return NULL without affecting errno. */
|
||||||
|
|
||||||
|
static char *
|
||||||
|
savedirstream (DIR *dirp)
|
||||||
{
|
{
|
||||||
DIR *dirp;
|
|
||||||
struct dirent *dp;
|
|
||||||
char *name_space;
|
char *name_space;
|
||||||
size_t allocated = NAME_SIZE_DEFAULT;
|
size_t allocated = NAME_SIZE_DEFAULT;
|
||||||
size_t used = 0;
|
size_t used = 0;
|
||||||
int save_errno;
|
int save_errno;
|
||||||
|
|
||||||
dirp = opendir (dir);
|
|
||||||
if (dirp == NULL)
|
if (dirp == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
name_space = xmalloc (allocated);
|
name_space = xmalloc (allocated);
|
||||||
|
|
||||||
errno = 0;
|
for (;;)
|
||||||
while ((dp = readdir (dirp)) != NULL)
|
|
||||||
{
|
{
|
||||||
|
struct dirent const *dp;
|
||||||
|
char const *entry;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
dp = readdir (dirp);
|
||||||
|
if (! dp)
|
||||||
|
break;
|
||||||
|
|
||||||
/* Skip "", ".", and "..". "" is returned by at least one buggy
|
/* Skip "", ".", and "..". "" is returned by at least one buggy
|
||||||
implementation: Solaris 2.4 readdir on NFS file systems. */
|
implementation: Solaris 2.4 readdir on NFS file systems. */
|
||||||
char const *entry = dp->d_name;
|
entry = dp->d_name;
|
||||||
if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] != '\0')
|
if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] != '\0')
|
||||||
{
|
{
|
||||||
size_t entry_size = strlen (entry) + 1;
|
size_t entry_size = _D_EXACT_NAMLEN (dp) + 1;
|
||||||
if (used + entry_size < used)
|
if (used + entry_size < used)
|
||||||
xalloc_die ();
|
xalloc_die ();
|
||||||
if (allocated <= used + entry_size)
|
if (allocated <= used + entry_size)
|
||||||
@ -111,7 +103,7 @@ savedir (const char *dir)
|
|||||||
}
|
}
|
||||||
name_space[used] = '\0';
|
name_space[used] = '\0';
|
||||||
save_errno = errno;
|
save_errno = errno;
|
||||||
if (CLOSEDIR (dirp) != 0)
|
if (closedir (dirp) != 0)
|
||||||
save_errno = errno;
|
save_errno = errno;
|
||||||
if (save_errno != 0)
|
if (save_errno != 0)
|
||||||
{
|
{
|
||||||
@ -121,3 +113,25 @@ savedir (const char *dir)
|
|||||||
}
|
}
|
||||||
return name_space;
|
return name_space;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return a freshly allocated string containing the file names
|
||||||
|
in directory DIR, separated by '\0' characters;
|
||||||
|
the end is marked by two '\0' characters in a row.
|
||||||
|
Return NULL (setting errno) if DIR cannot be opened, read, or closed. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
savedir (char const *dir)
|
||||||
|
{
|
||||||
|
return savedirstream (opendir (dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a freshly allocated string containing the file names
|
||||||
|
in directory FD, separated by '\0' characters;
|
||||||
|
the end is marked by two '\0' characters in a row.
|
||||||
|
Return NULL (setting errno) if FD cannot be read or closed. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
fdsavedir (int fd)
|
||||||
|
{
|
||||||
|
return savedirstream (fdopendir (fd));
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* Save the list of files in a directory in a string.
|
/* Save the list of files in a directory in a string.
|
||||||
|
|
||||||
Copyright 1997, 1999, 2001, 2003 Free Software Foundation, Inc.
|
Copyright (C) 1997, 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -14,13 +14,14 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||||
|
|
||||||
#if !defined SAVEDIR_H_
|
#if !defined SAVEDIR_H_
|
||||||
# define SAVEDIR_H_
|
# define SAVEDIR_H_
|
||||||
|
|
||||||
char *savedir (const char *dir);
|
char *savedir (char const *dir);
|
||||||
|
char *fdsavedir (int fd);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
/* Case-insensitive string comparison functions.
|
|
||||||
Copyright (C) 1995-1996, 2001, 2003 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program 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 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program 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 this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#ifndef _STRCASE_H
|
|
||||||
#define _STRCASE_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
|
|
||||||
greater than zero if S1 is lexicographically less than, equal to or greater
|
|
||||||
than S2.
|
|
||||||
Note: This function does not work correctly in multibyte locales. */
|
|
||||||
extern int strcasecmp (const char *s1, const char *s2);
|
|
||||||
|
|
||||||
/* Compare no more than N characters of strings S1 and S2, ignoring case,
|
|
||||||
returning less than, equal to or greater than zero if S1 is
|
|
||||||
lexicographically less than, equal to or greater than S2.
|
|
||||||
Note: This function can not work correctly in multibyte locales. */
|
|
||||||
extern int strncasecmp (const char *s1, const char *s2, size_t n);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _STRCASE_H */
|
|
@ -1,5 +1,5 @@
|
|||||||
/* Searching in a string.
|
/* Searching in a string.
|
||||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
Copyright (C) 2003, 2007 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -13,10 +13,12 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
/* Specification. */
|
/* Specification. */
|
||||||
#include "strchrnul.h"
|
#include <string.h>
|
||||||
|
|
||||||
/* Find the first occurrence of C in S or the final NUL byte. */
|
/* Find the first occurrence of C in S or the final NUL byte. */
|
||||||
char *
|
char *
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* stripslash.c -- remove redundant trailing slashes from a file name
|
/* stripslash.c -- remove redundant trailing slashes from a file name
|
||||||
Copyright (C) 1990, 2001, 2003, 2004 Free Software Foundation, Inc.
|
|
||||||
|
Copyright (C) 1990, 2001, 2003-2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -13,27 +14,32 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
#include <config.h>
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "dirname.h"
|
#include "dirname.h"
|
||||||
|
|
||||||
/* Remove trailing slashes from PATH.
|
/* Remove trailing slashes from FILE. Return true if a trailing slash
|
||||||
Return true if a trailing slash was removed.
|
was removed. This is useful when using file name completion from a
|
||||||
This is useful when using filename completion from a shell that
|
shell that adds a "/" after directory names (such as tcsh and
|
||||||
adds a "/" after directory names (such as tcsh and bash), because
|
bash), because on symlinks to directories, several system calls
|
||||||
the Unix rename and rmdir system calls return an "Invalid argument" error
|
have different semantics according to whether a trailing slash is
|
||||||
when given a path that ends in "/" (except for the root directory). */
|
present. */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
strip_trailing_slashes (char *path)
|
strip_trailing_slashes (char *file)
|
||||||
{
|
{
|
||||||
char *base = base_name (path);
|
char *base = last_component (file);
|
||||||
char *base_lim = base + base_len (base);
|
char *base_lim;
|
||||||
bool had_slash = (*base_lim != '\0');
|
bool had_slash;
|
||||||
|
|
||||||
|
/* last_component returns "" for file system roots, but we need to turn
|
||||||
|
`///' into `/'. */
|
||||||
|
if (! *base)
|
||||||
|
base = file;
|
||||||
|
base_lim = base + base_len (base);
|
||||||
|
had_slash = (*base_lim != '\0');
|
||||||
*base_lim = '\0';
|
*base_lim = '\0';
|
||||||
return had_slash;
|
return had_slash;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* Copyright (C) 1996, 1997, 1998, 2000, 2003 Free Software Foundation, Inc.
|
/* A replacement function, for systems that lack strndup.
|
||||||
|
|
||||||
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2005, 2006, 2007
|
||||||
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it
|
This program is free software; you can redistribute it and/or modify it
|
||||||
under the terms of the GNU General Public License as published by the
|
under the terms of the GNU General Public License as published by the
|
||||||
@ -15,31 +15,16 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#include <config.h>
|
||||||
# include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifndef HAVE_DECL_STRNLEN
|
#include <stdlib.h>
|
||||||
"this configure-time declaration test was not run"
|
|
||||||
#endif
|
|
||||||
#if !HAVE_DECL_STRNLEN
|
|
||||||
size_t strnlen ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef __strndup
|
|
||||||
#undef strndup
|
|
||||||
|
|
||||||
#ifndef weak_alias
|
|
||||||
# define __strndup strndup
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
__strndup (const char *s, size_t n)
|
strndup (char const *s, size_t n)
|
||||||
{
|
{
|
||||||
size_t len = strnlen (s, n);
|
size_t len = strnlen (s, n);
|
||||||
char *new = malloc (len + 1);
|
char *new = malloc (len + 1);
|
||||||
@ -50,6 +35,3 @@ __strndup (const char *s, size_t n)
|
|||||||
new[len] = '\0';
|
new[len] = '\0';
|
||||||
return memcpy (new, s, len);
|
return memcpy (new, s, len);
|
||||||
}
|
}
|
||||||
#ifdef weak_alias
|
|
||||||
weak_alias (__strndup, strndup)
|
|
||||||
#endif
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* Find the length of STRING, but scan at most MAXLEN characters.
|
/* Find the length of STRING, but scan at most MAXLEN characters.
|
||||||
Copyright (C) 1996, 1997, 1998, 2000-2003 Free Software Foundation, Inc.
|
Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
Written by Simon Josefsson.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -12,37 +12,20 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License
|
||||||
with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
#include <config.h>
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
#undef strnlen
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#undef __strnlen
|
|
||||||
#undef strnlen
|
|
||||||
|
|
||||||
#ifndef _LIBC
|
|
||||||
# define strnlen rpl_strnlen
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef weak_alias
|
|
||||||
# define __strnlen strnlen
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Find the length of STRING, but scan at most MAXLEN characters.
|
/* Find the length of STRING, but scan at most MAXLEN characters.
|
||||||
If no '\0' terminator is found in that many characters, return MAXLEN. */
|
If no '\0' terminator is found in that many characters, return MAXLEN. */
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
__strnlen (const char *string, size_t maxlen)
|
strnlen (const char *string, size_t maxlen)
|
||||||
{
|
{
|
||||||
const char *end = memchr (string, '\0', maxlen);
|
const char *end = memchr (string, '\0', maxlen);
|
||||||
return end ? (size_t) (end - string) : maxlen;
|
return end ? (size_t) (end - string) : maxlen;
|
||||||
}
|
}
|
||||||
#ifdef weak_alias
|
|
||||||
weak_alias (__strnlen, strnlen)
|
|
||||||
#endif
|
|
||||||
|
55
lib/system-ioctl.h
Normal file
55
lib/system-ioctl.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/* System dependent definitions for GNU tar's use of ioctl macros.
|
||||||
|
|
||||||
|
Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003,
|
||||||
|
2004, 2005, 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program 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 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* This is a real challenge to properly get MTIO* symbols :-(. ISC uses
|
||||||
|
<sys/gentape.h>. SCO and BSDi uses <sys/tape.h>; BSDi also requires
|
||||||
|
<sys/tprintf.h> and <sys/device.h> for defining tp_dev and tpr_t. It
|
||||||
|
seems that the rest use <sys/mtio.h>, which itself requires other files,
|
||||||
|
depending on systems. Pyramid defines _IOW in <sgtty.h>, for example. */
|
||||||
|
|
||||||
|
#if HAVE_SYS_GENTAPE_H
|
||||||
|
# include <sys/gentape.h>
|
||||||
|
#else
|
||||||
|
# if HAVE_SYS_TAPE_H
|
||||||
|
# if HAVE_SYS_DEVICE_H
|
||||||
|
# include <sys/device.h>
|
||||||
|
# endif
|
||||||
|
# if HAVE_SYS_PARAM_H
|
||||||
|
# include <sys/param.h>
|
||||||
|
# endif
|
||||||
|
# if HAVE_SYS_BUF_H
|
||||||
|
# include <sys/buf.h>
|
||||||
|
# endif
|
||||||
|
# if HAVE_SYS_TPRINTF_H
|
||||||
|
# include <sys/tprintf.h>
|
||||||
|
# endif
|
||||||
|
# include <sys/tape.h>
|
||||||
|
# else
|
||||||
|
# if HAVE_SYS_MTIO_H
|
||||||
|
# include <sys/ioctl.h>
|
||||||
|
# if HAVE_SGTTY_H
|
||||||
|
# include <sgtty.h>
|
||||||
|
# endif
|
||||||
|
# if HAVE_SYS_IO_TRIOCTL_H
|
||||||
|
# include <sys/io/trioctl.h>
|
||||||
|
# endif
|
||||||
|
# include <sys/mtio.h>
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
99
lib/system.h
99
lib/system.h
@ -1,7 +1,7 @@
|
|||||||
/* System dependent definitions for GNU tar.
|
/* System dependent definitions for GNU tar.
|
||||||
|
|
||||||
Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003,
|
Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003,
|
||||||
2004 Free Software Foundation, Inc.
|
2004, 2005, 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -15,8 +15,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
*/
|
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
#if HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
@ -109,10 +108,19 @@ extern int errno;
|
|||||||
#ifndef O_TRUNC
|
#ifndef O_TRUNC
|
||||||
# define O_TRUNC 32 /* truncate file on open */
|
# define O_TRUNC 32 /* truncate file on open */
|
||||||
#endif
|
#endif
|
||||||
/* MS-DOG forever, with my love! */
|
|
||||||
#ifndef O_BINARY
|
#ifndef O_BINARY
|
||||||
# define O_BINARY 0
|
# define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef O_DIRECTORY
|
||||||
|
# define O_DIRECTORY 0
|
||||||
|
#endif
|
||||||
|
#ifndef O_NOATIME
|
||||||
|
# define O_NOATIME 0
|
||||||
|
#endif
|
||||||
|
#ifndef O_NONBLOCK
|
||||||
|
# define O_NONBLOCK 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Declare file status routines and bits. */
|
/* Declare file status routines and bits. */
|
||||||
|
|
||||||
@ -252,9 +260,7 @@ extern int errno;
|
|||||||
#define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX)
|
#define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX)
|
||||||
|
|
||||||
/* Include <unistd.h> before any preprocessor test of _POSIX_VERSION. */
|
/* Include <unistd.h> before any preprocessor test of _POSIX_VERSION. */
|
||||||
#if HAVE_UNISTD_H
|
#include <unistd.h>
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SEEK_SET
|
#ifndef SEEK_SET
|
||||||
# define SEEK_SET 0
|
# define SEEK_SET 0
|
||||||
@ -282,6 +288,9 @@ extern int errno;
|
|||||||
|
|
||||||
#if MAJOR_IN_MKDEV
|
#if MAJOR_IN_MKDEV
|
||||||
# include <sys/mkdev.h>
|
# include <sys/mkdev.h>
|
||||||
|
# if !defined(makedev) && defined(mkdev)
|
||||||
|
# define makedev(a,b) mkdev((a),(b))
|
||||||
|
# endif
|
||||||
# define GOT_MAJOR
|
# define GOT_MAJOR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -377,45 +386,12 @@ extern int errno;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ST_NBLOCKSIZE
|
#ifndef ST_NBLOCKSIZE
|
||||||
#define ST_NBLOCKSIZE 512
|
# define ST_NBLOCKSIZE 512
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This is a real challenge to properly get MTIO* symbols :-(. ISC uses
|
#define ST_IS_SPARSE(st) \
|
||||||
<sys/gentape.h>. SCO and BSDi uses <sys/tape.h>; BSDi also requires
|
(ST_NBLOCKS (st) \
|
||||||
<sys/tprintf.h> and <sys/device.h> for defining tp_dev and tpr_t. It
|
< ((st).st_size / ST_NBLOCKSIZE + ((st).st_size % ST_NBLOCKSIZE != 0)))
|
||||||
seems that the rest use <sys/mtio.h>, which itself requires other files,
|
|
||||||
depending on systems. Pyramid defines _IOW in <sgtty.h>, for example. */
|
|
||||||
|
|
||||||
#if HAVE_SYS_GENTAPE_H
|
|
||||||
# include <sys/gentape.h>
|
|
||||||
#else
|
|
||||||
# if HAVE_SYS_TAPE_H
|
|
||||||
# if HAVE_SYS_DEVICE_H
|
|
||||||
# include <sys/device.h>
|
|
||||||
# endif
|
|
||||||
# if HAVE_SYS_PARAM_H
|
|
||||||
# include <sys/param.h>
|
|
||||||
# endif
|
|
||||||
# if HAVE_SYS_BUF_H
|
|
||||||
# include <sys/buf.h>
|
|
||||||
# endif
|
|
||||||
# if HAVE_SYS_TPRINTF_H
|
|
||||||
# include <sys/tprintf.h>
|
|
||||||
# endif
|
|
||||||
# include <sys/tape.h>
|
|
||||||
# else
|
|
||||||
# if HAVE_SYS_MTIO_H
|
|
||||||
# include <sys/ioctl.h>
|
|
||||||
# if HAVE_SGTTY_H
|
|
||||||
# include <sgtty.h>
|
|
||||||
# endif
|
|
||||||
# if HAVE_SYS_IO_TRIOCTL_H
|
|
||||||
# include <sys/io/trioctl.h>
|
|
||||||
# endif
|
|
||||||
# include <sys/mtio.h>
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Declare standard functions. */
|
/* Declare standard functions. */
|
||||||
|
|
||||||
@ -435,7 +411,6 @@ char *getenv ();
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WITH_DMALLOC
|
#if WITH_DMALLOC
|
||||||
# undef HAVE_DECL_VALLOC
|
|
||||||
# define DMALLOC_FUNC_CHECK
|
# define DMALLOC_FUNC_CHECK
|
||||||
# include <dmalloc.h>
|
# include <dmalloc.h>
|
||||||
#endif
|
#endif
|
||||||
@ -446,28 +421,11 @@ char *getenv ();
|
|||||||
# define MB_LEN_MAX 1
|
# define MB_LEN_MAX 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_INTTYPES_H
|
#include <inttypes.h>
|
||||||
# include <inttypes.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* These macros work even on ones'-complement hosts (!).
|
#include <intprops.h>
|
||||||
The extra casts work around common compiler bugs. */
|
|
||||||
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
|
|
||||||
#define TYPE_MINIMUM(t) (TYPE_SIGNED (t) \
|
|
||||||
? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) \
|
|
||||||
: (t) 0)
|
|
||||||
#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
|
|
||||||
|
|
||||||
/* Bound on length of the string representing an integer value of type t.
|
#define UINTMAX_STRSIZE_BOUND INT_BUFSIZE_BOUND (uintmax_t)
|
||||||
Subtract one for the sign bit if t is signed;
|
|
||||||
302 / 1000 is log10 (2) rounded up;
|
|
||||||
add one for integer division truncation;
|
|
||||||
add one more for a minus sign if t is signed. */
|
|
||||||
#define INT_STRLEN_BOUND(t) \
|
|
||||||
((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
|
|
||||||
+ 1 + TYPE_SIGNED (t))
|
|
||||||
|
|
||||||
#define UINTMAX_STRSIZE_BOUND (INT_STRLEN_BOUND (uintmax_t) + 1)
|
|
||||||
|
|
||||||
/* Prototypes for external functions. */
|
/* Prototypes for external functions. */
|
||||||
|
|
||||||
@ -479,16 +437,9 @@ char *getenv ();
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#if defined(HAVE_SYS_TIME_H) && defined(TIME_WITH_SYS_TIME)
|
#ifdef TIME_WITH_SYS_TIME
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
#if ! HAVE_DECL_TIME
|
|
||||||
time_t time ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_UTIME_H
|
|
||||||
# include <utime.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Library modules. */
|
/* Library modules. */
|
||||||
|
|
||||||
|
3
lib/umaxtostr.c
Normal file
3
lib/umaxtostr.c
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#define inttostr umaxtostr
|
||||||
|
#define inttype uintmax_t
|
||||||
|
#include "inttostr.c"
|
@ -14,12 +14,12 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with this program; if not, write to the Free Software Foundation,
|
with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
/* Written by Jim Meyering. */
|
/* Written by Jim Meyering. */
|
||||||
|
|
||||||
#ifndef UNLOCKED_IO_H
|
#ifndef UNLOCKED_IO_H
|
||||||
#define UNLOCKED_IO_H 1
|
# define UNLOCKED_IO_H 1
|
||||||
|
|
||||||
/* These are wrappers for functions/macros from the GNU C library, and
|
/* These are wrappers for functions/macros from the GNU C library, and
|
||||||
from other C libraries supporting POSIX's optional thread-safe functions.
|
from other C libraries supporting POSIX's optional thread-safe functions.
|
||||||
@ -32,106 +32,106 @@
|
|||||||
the *_unlocked functions directly. On hosts that lack those
|
the *_unlocked functions directly. On hosts that lack those
|
||||||
functions, invoke the non-thread-safe versions instead. */
|
functions, invoke the non-thread-safe versions instead. */
|
||||||
|
|
||||||
#include <stdio.h>
|
# include <stdio.h>
|
||||||
|
|
||||||
#if HAVE_DECL_CLEARERR_UNLOCKED
|
# if HAVE_DECL_CLEARERR_UNLOCKED
|
||||||
# undef clearerr
|
# undef clearerr
|
||||||
# define clearerr(x) clearerr_unlocked (x)
|
# define clearerr(x) clearerr_unlocked (x)
|
||||||
#else
|
# else
|
||||||
# define clearerr_unlocked(x) clearerr (x)
|
# define clearerr_unlocked(x) clearerr (x)
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#if HAVE_DECL_FEOF_UNLOCKED
|
# if HAVE_DECL_FEOF_UNLOCKED
|
||||||
# undef feof
|
# undef feof
|
||||||
# define feof(x) feof_unlocked (x)
|
# define feof(x) feof_unlocked (x)
|
||||||
#else
|
# else
|
||||||
# define feof_unlocked(x) feof (x)
|
# define feof_unlocked(x) feof (x)
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#if HAVE_DECL_FERROR_UNLOCKED
|
# if HAVE_DECL_FERROR_UNLOCKED
|
||||||
# undef ferror
|
# undef ferror
|
||||||
# define ferror(x) ferror_unlocked (x)
|
# define ferror(x) ferror_unlocked (x)
|
||||||
#else
|
# else
|
||||||
# define ferror_unlocked(x) ferror (x)
|
# define ferror_unlocked(x) ferror (x)
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#if HAVE_DECL_FFLUSH_UNLOCKED
|
# if HAVE_DECL_FFLUSH_UNLOCKED
|
||||||
# undef fflush
|
# undef fflush
|
||||||
# define fflush(x) fflush_unlocked (x)
|
# define fflush(x) fflush_unlocked (x)
|
||||||
#else
|
# else
|
||||||
# define fflush_unlocked(x) fflush (x)
|
# define fflush_unlocked(x) fflush (x)
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#if HAVE_DECL_FGETS_UNLOCKED
|
# if HAVE_DECL_FGETS_UNLOCKED
|
||||||
# undef fgets
|
# undef fgets
|
||||||
# define fgets(x,y,z) fgets_unlocked (x,y,z)
|
# define fgets(x,y,z) fgets_unlocked (x,y,z)
|
||||||
#else
|
# else
|
||||||
# define fgets_unlocked(x,y,z) fgets (x,y,z)
|
# define fgets_unlocked(x,y,z) fgets (x,y,z)
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#if HAVE_DECL_FPUTC_UNLOCKED
|
# if HAVE_DECL_FPUTC_UNLOCKED
|
||||||
# undef fputc
|
# undef fputc
|
||||||
# define fputc(x,y) fputc_unlocked (x,y)
|
# define fputc(x,y) fputc_unlocked (x,y)
|
||||||
#else
|
# else
|
||||||
# define fputc_unlocked(x,y) fputc (x,y)
|
# define fputc_unlocked(x,y) fputc (x,y)
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#if HAVE_DECL_FPUTS_UNLOCKED
|
# if HAVE_DECL_FPUTS_UNLOCKED
|
||||||
# undef fputs
|
# undef fputs
|
||||||
# define fputs(x,y) fputs_unlocked (x,y)
|
# define fputs(x,y) fputs_unlocked (x,y)
|
||||||
#else
|
# else
|
||||||
# define fputs_unlocked(x,y) fputs (x,y)
|
# define fputs_unlocked(x,y) fputs (x,y)
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#if HAVE_DECL_FREAD_UNLOCKED
|
# if HAVE_DECL_FREAD_UNLOCKED
|
||||||
# undef fread
|
# undef fread
|
||||||
# define fread(w,x,y,z) fread_unlocked (w,x,y,z)
|
# define fread(w,x,y,z) fread_unlocked (w,x,y,z)
|
||||||
#else
|
# else
|
||||||
# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
|
# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#if HAVE_DECL_FWRITE_UNLOCKED
|
# if HAVE_DECL_FWRITE_UNLOCKED
|
||||||
# undef fwrite
|
# undef fwrite
|
||||||
# define fwrite(w,x,y,z) fwrite_unlocked (w,x,y,z)
|
# define fwrite(w,x,y,z) fwrite_unlocked (w,x,y,z)
|
||||||
#else
|
# else
|
||||||
# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
|
# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#if HAVE_DECL_GETC_UNLOCKED
|
# if HAVE_DECL_GETC_UNLOCKED
|
||||||
# undef getc
|
# undef getc
|
||||||
# define getc(x) getc_unlocked (x)
|
# define getc(x) getc_unlocked (x)
|
||||||
#else
|
# else
|
||||||
# define getc_unlocked(x) getc (x)
|
# define getc_unlocked(x) getc (x)
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#if HAVE_DECL_GETCHAR_UNLOCKED
|
# if HAVE_DECL_GETCHAR_UNLOCKED
|
||||||
# undef getchar
|
# undef getchar
|
||||||
# define getchar() getchar_unlocked ()
|
# define getchar() getchar_unlocked ()
|
||||||
#else
|
# else
|
||||||
# define getchar_unlocked() getchar ()
|
# define getchar_unlocked() getchar ()
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#if HAVE_DECL_PUTC_UNLOCKED
|
# if HAVE_DECL_PUTC_UNLOCKED
|
||||||
# undef putc
|
# undef putc
|
||||||
# define putc(x,y) putc_unlocked (x,y)
|
# define putc(x,y) putc_unlocked (x,y)
|
||||||
#else
|
# else
|
||||||
# define putc_unlocked(x,y) putc (x,y)
|
# define putc_unlocked(x,y) putc (x,y)
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#if HAVE_DECL_PUTCHAR_UNLOCKED
|
# if HAVE_DECL_PUTCHAR_UNLOCKED
|
||||||
# undef putchar
|
# undef putchar
|
||||||
# define putchar(x) putchar_unlocked (x)
|
# define putchar(x) putchar_unlocked (x)
|
||||||
#else
|
# else
|
||||||
# define putchar_unlocked(x) putchar (x)
|
# define putchar_unlocked(x) putchar (x)
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#undef flockfile
|
# undef flockfile
|
||||||
#define flockfile(x) ((void) 0)
|
# define flockfile(x) ((void) 0)
|
||||||
|
|
||||||
#undef ftrylockfile
|
# undef ftrylockfile
|
||||||
#define ftrylockfile(x) 0
|
# define ftrylockfile(x) 0
|
||||||
|
|
||||||
#undef funlockfile
|
# undef funlockfile
|
||||||
#define funlockfile(x) ((void) 0)
|
# define funlockfile(x) ((void) 0)
|
||||||
|
|
||||||
#endif /* UNLOCKED_IO_H */
|
#endif /* UNLOCKED_IO_H */
|
||||||
|
189
lib/utimens.c
Normal file
189
lib/utimens.c
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
/* Set file access and modification times.
|
||||||
|
|
||||||
|
Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software
|
||||||
|
Foundation, Inc.
|
||||||
|
|
||||||
|
This program 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 2, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* Written by Paul Eggert. */
|
||||||
|
|
||||||
|
/* derived from a function in touch.c */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "utimens.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#if HAVE_UTIME_H
|
||||||
|
# include <utime.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Some systems (even some that do have <utime.h>) don't declare this
|
||||||
|
structure anywhere. */
|
||||||
|
#ifndef HAVE_STRUCT_UTIMBUF
|
||||||
|
struct utimbuf
|
||||||
|
{
|
||||||
|
long actime;
|
||||||
|
long modtime;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Some systems don't have ENOSYS. */
|
||||||
|
#ifndef ENOSYS
|
||||||
|
# ifdef ENOTSUP
|
||||||
|
# define ENOSYS ENOTSUP
|
||||||
|
# else
|
||||||
|
/* Some systems don't have ENOTSUP either. */
|
||||||
|
# define ENOSYS EINVAL
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __attribute__
|
||||||
|
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
|
||||||
|
# define __attribute__(x)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ATTRIBUTE_UNUSED
|
||||||
|
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Set the access and modification time stamps of FD (a.k.a. FILE) to be
|
||||||
|
TIMESPEC[0] and TIMESPEC[1], respectively.
|
||||||
|
FD must be either negative -- in which case it is ignored --
|
||||||
|
or a file descriptor that is open on FILE.
|
||||||
|
If FD is nonnegative, then FILE can be NULL, which means
|
||||||
|
use just futimes (or equivalent) instead of utimes (or equivalent),
|
||||||
|
and fail if on an old system without futimes (or equivalent).
|
||||||
|
If TIMESPEC is null, set the time stamps to the current time.
|
||||||
|
Return 0 on success, -1 (setting errno) on failure. */
|
||||||
|
|
||||||
|
int
|
||||||
|
gl_futimens (int fd ATTRIBUTE_UNUSED,
|
||||||
|
char const *file, struct timespec const timespec[2])
|
||||||
|
{
|
||||||
|
/* Some Linux-based NFS clients are buggy, and mishandle time stamps
|
||||||
|
of files in NFS file systems in some cases. We have no
|
||||||
|
configure-time test for this, but please see
|
||||||
|
<http://bugs.gentoo.org/show_bug.cgi?id=132673> for references to
|
||||||
|
some of the problems with Linux 2.6.16. If this affects you,
|
||||||
|
compile with -DHAVE_BUGGY_NFS_TIME_STAMPS; this is reported to
|
||||||
|
help in some cases, albeit at a cost in performance. But you
|
||||||
|
really should upgrade your kernel to a fixed version, since the
|
||||||
|
problem affects many applications. */
|
||||||
|
|
||||||
|
#if HAVE_BUGGY_NFS_TIME_STAMPS
|
||||||
|
if (fd < 0)
|
||||||
|
sync ();
|
||||||
|
else
|
||||||
|
fsync (fd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* There's currently no interface to set file timestamps with
|
||||||
|
nanosecond resolution, so do the best we can, discarding any
|
||||||
|
fractional part of the timestamp. */
|
||||||
|
#if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES
|
||||||
|
struct timeval timeval[2];
|
||||||
|
struct timeval const *t;
|
||||||
|
if (timespec)
|
||||||
|
{
|
||||||
|
timeval[0].tv_sec = timespec[0].tv_sec;
|
||||||
|
timeval[0].tv_usec = timespec[0].tv_nsec / 1000;
|
||||||
|
timeval[1].tv_sec = timespec[1].tv_sec;
|
||||||
|
timeval[1].tv_usec = timespec[1].tv_nsec / 1000;
|
||||||
|
t = timeval;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
t = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
# if HAVE_FUTIMESAT
|
||||||
|
return futimesat (AT_FDCWD, file, t);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* If futimesat or futimes fails here, don't try to speed things
|
||||||
|
up by returning right away. glibc can incorrectly fail with
|
||||||
|
errno == ENOENT if /proc isn't mounted. Also, Mandrake 10.0
|
||||||
|
in high security mode doesn't allow ordinary users to read
|
||||||
|
/proc/self, so glibc incorrectly fails with errno == EACCES.
|
||||||
|
If errno == EIO, EPERM, or EROFS, it's probably safe to fail
|
||||||
|
right away, but these cases are rare enough that they're not
|
||||||
|
worth optimizing, and who knows what other messed-up systems
|
||||||
|
are out there? So play it safe and fall back on the code
|
||||||
|
below. */
|
||||||
|
# if HAVE_FUTIMESAT
|
||||||
|
if (futimesat (fd, NULL, t) == 0)
|
||||||
|
return 0;
|
||||||
|
# elif HAVE_FUTIMES
|
||||||
|
if (futimes (fd, t) == 0)
|
||||||
|
return 0;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
#if ! (HAVE_FUTIMESAT || (HAVE_WORKING_UTIMES && HAVE_FUTIMES))
|
||||||
|
errno = ENOSYS;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Prefer EBADF to ENOSYS if both error numbers apply. */
|
||||||
|
if (errno == ENOSYS)
|
||||||
|
{
|
||||||
|
int fd2 = dup (fd);
|
||||||
|
int dup_errno = errno;
|
||||||
|
if (0 <= fd2)
|
||||||
|
close (fd2);
|
||||||
|
errno = (fd2 < 0 && dup_errno == EBADF ? EBADF : ENOSYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_WORKING_UTIMES
|
||||||
|
return utimes (file, t);
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
struct utimbuf utimbuf;
|
||||||
|
struct utimbuf const *ut;
|
||||||
|
if (timespec)
|
||||||
|
{
|
||||||
|
utimbuf.actime = timespec[0].tv_sec;
|
||||||
|
utimbuf.modtime = timespec[1].tv_sec;
|
||||||
|
ut = &utimbuf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ut = NULL;
|
||||||
|
|
||||||
|
return utime (file, ut);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the access and modification time stamps of FILE to be
|
||||||
|
TIMESPEC[0] and TIMESPEC[1], respectively. */
|
||||||
|
int
|
||||||
|
utimens (char const *file, struct timespec const timespec[2])
|
||||||
|
{
|
||||||
|
return gl_futimens (-1, file, timespec);
|
||||||
|
}
|
3
lib/utimens.h
Normal file
3
lib/utimens.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#include <time.h>
|
||||||
|
int gl_futimens (int, char const *, struct timespec const [2]);
|
||||||
|
int utimens (char const *, struct timespec const [2]);
|
@ -1,6 +1,6 @@
|
|||||||
/* Report a memory allocation failure and exit.
|
/* Report a memory allocation failure and exit.
|
||||||
|
|
||||||
Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004 Free
|
Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2006 Free
|
||||||
Software Foundation, Inc.
|
Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
@ -15,11 +15,9 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
#include <config.h>
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "xalloc.h"
|
#include "xalloc.h"
|
||||||
|
|
||||||
@ -30,7 +28,6 @@
|
|||||||
|
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
#define _(msgid) gettext (msgid)
|
#define _(msgid) gettext (msgid)
|
||||||
#define N_(msgid) msgid
|
|
||||||
|
|
||||||
void
|
void
|
||||||
xalloc_die (void)
|
xalloc_die (void)
|
||||||
|
202
lib/xalloc.h
202
lib/xalloc.h
@ -1,7 +1,7 @@
|
|||||||
/* xalloc.h -- malloc with out-of-memory checking
|
/* xalloc.h -- malloc with out-of-memory checking
|
||||||
|
|
||||||
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||||
1999, 2000, 2003, 2004 Free Software Foundation, Inc.
|
1999, 2000, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifndef XALLOC_H_
|
#ifndef XALLOC_H_
|
||||||
# define XALLOC_H_
|
# define XALLOC_H_
|
||||||
@ -46,13 +46,10 @@ extern "C" {
|
|||||||
extern void xalloc_die (void) ATTRIBUTE_NORETURN;
|
extern void xalloc_die (void) ATTRIBUTE_NORETURN;
|
||||||
|
|
||||||
void *xmalloc (size_t s);
|
void *xmalloc (size_t s);
|
||||||
void *xnmalloc (size_t n, size_t s);
|
|
||||||
void *xzalloc (size_t s);
|
void *xzalloc (size_t s);
|
||||||
void *xcalloc (size_t n, size_t s);
|
void *xcalloc (size_t n, size_t s);
|
||||||
void *xrealloc (void *p, size_t s);
|
void *xrealloc (void *p, size_t s);
|
||||||
void *xnrealloc (void *p, size_t n, size_t s);
|
|
||||||
void *x2realloc (void *p, size_t *pn);
|
void *x2realloc (void *p, size_t *pn);
|
||||||
void *x2nrealloc (void *p, size_t *pn, size_t s);
|
|
||||||
void *xmemdup (void const *p, size_t s);
|
void *xmemdup (void const *p, size_t s);
|
||||||
char *xstrdup (char const *str);
|
char *xstrdup (char const *str);
|
||||||
|
|
||||||
@ -71,8 +68,203 @@ char *xstrdup (char const *str);
|
|||||||
# define xalloc_oversized(n, s) \
|
# define xalloc_oversized(n, s) \
|
||||||
((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
|
((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
|
||||||
|
|
||||||
|
|
||||||
|
/* In the following macros, T must be an elementary or structure/union or
|
||||||
|
typedef'ed type, or a pointer to such a type. To apply one of the
|
||||||
|
following macros to a function pointer or array type, you need to typedef
|
||||||
|
it first and use the typedef name. */
|
||||||
|
|
||||||
|
/* Allocate an object of type T dynamically, with error checking. */
|
||||||
|
/* extern t *XMALLOC (typename t); */
|
||||||
|
# define XMALLOC(t) ((t *) xmalloc (sizeof (t)))
|
||||||
|
|
||||||
|
/* Allocate memory for N elements of type T, with error checking. */
|
||||||
|
/* extern t *XNMALLOC (size_t n, typename t); */
|
||||||
|
# define XNMALLOC(n, t) \
|
||||||
|
((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t))))
|
||||||
|
|
||||||
|
/* Allocate an object of type T dynamically, with error checking,
|
||||||
|
and zero it. */
|
||||||
|
/* extern t *XZALLOC (typename t); */
|
||||||
|
# define XZALLOC(t) ((t *) xzalloc (sizeof (t)))
|
||||||
|
|
||||||
|
/* Allocate memory for N elements of type T, with error checking,
|
||||||
|
and zero it. */
|
||||||
|
/* extern t *XCALLOC (size_t n, typename t); */
|
||||||
|
# define XCALLOC(n, t) \
|
||||||
|
((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
|
||||||
|
|
||||||
|
|
||||||
|
# if HAVE_INLINE
|
||||||
|
# define static_inline static inline
|
||||||
|
# else
|
||||||
|
void *xnmalloc (size_t n, size_t s);
|
||||||
|
void *xnrealloc (void *p, size_t n, size_t s);
|
||||||
|
void *x2nrealloc (void *p, size_t *pn, size_t s);
|
||||||
|
char *xcharalloc (size_t n);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef static_inline
|
||||||
|
|
||||||
|
/* Allocate an array of N objects, each with S bytes of memory,
|
||||||
|
dynamically, with error checking. S must be nonzero. */
|
||||||
|
|
||||||
|
static_inline void *
|
||||||
|
xnmalloc (size_t n, size_t s)
|
||||||
|
{
|
||||||
|
if (xalloc_oversized (n, s))
|
||||||
|
xalloc_die ();
|
||||||
|
return xmalloc (n * s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change the size of an allocated block of memory P to an array of N
|
||||||
|
objects each of S bytes, with error checking. S must be nonzero. */
|
||||||
|
|
||||||
|
static_inline void *
|
||||||
|
xnrealloc (void *p, size_t n, size_t s)
|
||||||
|
{
|
||||||
|
if (xalloc_oversized (n, s))
|
||||||
|
xalloc_die ();
|
||||||
|
return xrealloc (p, n * s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If P is null, allocate a block of at least *PN such objects;
|
||||||
|
otherwise, reallocate P so that it contains more than *PN objects
|
||||||
|
each of S bytes. *PN must be nonzero unless P is null, and S must
|
||||||
|
be nonzero. Set *PN to the new number of objects, and return the
|
||||||
|
pointer to the new block. *PN is never set to zero, and the
|
||||||
|
returned pointer is never null.
|
||||||
|
|
||||||
|
Repeated reallocations are guaranteed to make progress, either by
|
||||||
|
allocating an initial block with a nonzero size, or by allocating a
|
||||||
|
larger block.
|
||||||
|
|
||||||
|
In the following implementation, nonzero sizes are increased by a
|
||||||
|
factor of approximately 1.5 so that repeated reallocations have
|
||||||
|
O(N) overall cost rather than O(N**2) cost, but the
|
||||||
|
specification for this function does not guarantee that rate.
|
||||||
|
|
||||||
|
Here is an example of use:
|
||||||
|
|
||||||
|
int *p = NULL;
|
||||||
|
size_t used = 0;
|
||||||
|
size_t allocated = 0;
|
||||||
|
|
||||||
|
void
|
||||||
|
append_int (int value)
|
||||||
|
{
|
||||||
|
if (used == allocated)
|
||||||
|
p = x2nrealloc (p, &allocated, sizeof *p);
|
||||||
|
p[used++] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
This causes x2nrealloc to allocate a block of some nonzero size the
|
||||||
|
first time it is called.
|
||||||
|
|
||||||
|
To have finer-grained control over the initial size, set *PN to a
|
||||||
|
nonzero value before calling this function with P == NULL. For
|
||||||
|
example:
|
||||||
|
|
||||||
|
int *p = NULL;
|
||||||
|
size_t used = 0;
|
||||||
|
size_t allocated = 0;
|
||||||
|
size_t allocated1 = 1000;
|
||||||
|
|
||||||
|
void
|
||||||
|
append_int (int value)
|
||||||
|
{
|
||||||
|
if (used == allocated)
|
||||||
|
{
|
||||||
|
p = x2nrealloc (p, &allocated1, sizeof *p);
|
||||||
|
allocated = allocated1;
|
||||||
|
}
|
||||||
|
p[used++] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
static_inline void *
|
||||||
|
x2nrealloc (void *p, size_t *pn, size_t s)
|
||||||
|
{
|
||||||
|
size_t n = *pn;
|
||||||
|
|
||||||
|
if (! p)
|
||||||
|
{
|
||||||
|
if (! n)
|
||||||
|
{
|
||||||
|
/* The approximate size to use for initial small allocation
|
||||||
|
requests, when the invoking code specifies an old size of
|
||||||
|
zero. 64 bytes is the largest "small" request for the
|
||||||
|
GNU C library malloc. */
|
||||||
|
enum { DEFAULT_MXFAST = 64 };
|
||||||
|
|
||||||
|
n = DEFAULT_MXFAST / s;
|
||||||
|
n += !n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Set N = ceil (1.5 * N) so that progress is made if N == 1.
|
||||||
|
Check for overflow, so that N * S stays in size_t range.
|
||||||
|
The check is slightly conservative, but an exact check isn't
|
||||||
|
worth the trouble. */
|
||||||
|
if ((size_t) -1 / 3 * 2 / s <= n)
|
||||||
|
xalloc_die ();
|
||||||
|
n += (n + 1) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pn = n;
|
||||||
|
return xrealloc (p, n * s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a pointer to a new buffer of N bytes. This is like xmalloc,
|
||||||
|
except it returns char *. */
|
||||||
|
|
||||||
|
static_inline char *
|
||||||
|
xcharalloc (size_t n)
|
||||||
|
{
|
||||||
|
return XNMALLOC (n, char);
|
||||||
|
}
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
# ifdef __cplusplus
|
# ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* C++ does not allow conversions from void * to other pointer types
|
||||||
|
without a cast. Use templates to work around the problem when
|
||||||
|
possible. */
|
||||||
|
|
||||||
|
template <typename T> inline T *
|
||||||
|
xrealloc (T *p, size_t s)
|
||||||
|
{
|
||||||
|
return (T *) xrealloc ((void *) p, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> inline T *
|
||||||
|
xnrealloc (T *p, size_t n, size_t s)
|
||||||
|
{
|
||||||
|
return (T *) xnrealloc ((void *) p, n, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> inline T *
|
||||||
|
x2realloc (T *p, size_t *pn)
|
||||||
|
{
|
||||||
|
return (T *) x2realloc ((void *) p, pn);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> inline T *
|
||||||
|
x2nrealloc (T *p, size_t *pn, size_t s)
|
||||||
|
{
|
||||||
|
return (T *) x2nrealloc ((void *) p, pn, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> inline T *
|
||||||
|
xmemdup (T const *p, size_t s)
|
||||||
|
{
|
||||||
|
return (T *) xmemdup ((void const *) p, s);
|
||||||
|
}
|
||||||
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
|
||||||
|
162
lib/xmalloc.c
162
lib/xmalloc.c
@ -1,7 +1,8 @@
|
|||||||
/* xmalloc.c -- malloc with out of memory checking
|
/* xmalloc.c -- malloc with out of memory checking
|
||||||
|
|
||||||
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||||
1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
|
1999, 2000, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||||
|
Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -15,13 +16,15 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
#include <config.h>
|
||||||
# include <config.h>
|
|
||||||
|
#if ! HAVE_INLINE
|
||||||
|
# define static_inline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "xalloc.h"
|
#include "xalloc.h"
|
||||||
|
#undef static_inline
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -30,148 +33,36 @@
|
|||||||
# define SIZE_MAX ((size_t) -1)
|
# define SIZE_MAX ((size_t) -1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Allocate an array of N objects, each with S bytes of memory,
|
/* 1 if calloc is known to be compatible with GNU calloc. This
|
||||||
dynamically, with error checking. S must be nonzero. */
|
matters if we are not also using the calloc module, which defines
|
||||||
|
HAVE_CALLOC and supports the GNU API even on non-GNU platforms. */
|
||||||
static inline void *
|
#if defined HAVE_CALLOC || defined __GLIBC__
|
||||||
xnmalloc_inline (size_t n, size_t s)
|
enum { HAVE_GNU_CALLOC = 1 };
|
||||||
{
|
#else
|
||||||
void *p;
|
enum { HAVE_GNU_CALLOC = 0 };
|
||||||
if (xalloc_oversized (n, s) || (! (p = malloc (n * s)) && n != 0))
|
#endif
|
||||||
xalloc_die ();
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
xnmalloc (size_t n, size_t s)
|
|
||||||
{
|
|
||||||
return xnmalloc_inline (n, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate N bytes of memory dynamically, with error checking. */
|
/* Allocate N bytes of memory dynamically, with error checking. */
|
||||||
|
|
||||||
void *
|
void *
|
||||||
xmalloc (size_t n)
|
xmalloc (size_t n)
|
||||||
{
|
{
|
||||||
return xnmalloc_inline (n, 1);
|
void *p = malloc (n);
|
||||||
}
|
if (!p && n != 0)
|
||||||
|
|
||||||
/* Change the size of an allocated block of memory P to an array of N
|
|
||||||
objects each of S bytes, with error checking. S must be nonzero. */
|
|
||||||
|
|
||||||
static inline void *
|
|
||||||
xnrealloc_inline (void *p, size_t n, size_t s)
|
|
||||||
{
|
|
||||||
if (xalloc_oversized (n, s) || (! (p = realloc (p, n * s)) && n != 0))
|
|
||||||
xalloc_die ();
|
xalloc_die ();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
|
||||||
xnrealloc (void *p, size_t n, size_t s)
|
|
||||||
{
|
|
||||||
return xnrealloc_inline (p, n, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Change the size of an allocated block of memory P to N bytes,
|
/* Change the size of an allocated block of memory P to N bytes,
|
||||||
with error checking. */
|
with error checking. */
|
||||||
|
|
||||||
void *
|
void *
|
||||||
xrealloc (void *p, size_t n)
|
xrealloc (void *p, size_t n)
|
||||||
{
|
{
|
||||||
return xnrealloc_inline (p, n, 1);
|
p = realloc (p, n);
|
||||||
}
|
if (!p && n != 0)
|
||||||
|
xalloc_die ();
|
||||||
|
return p;
|
||||||
/* If P is null, allocate a block of at least *PN such objects;
|
|
||||||
otherwise, reallocate P so that it contains more than *PN objects
|
|
||||||
each of S bytes. *PN must be nonzero unless P is null, and S must
|
|
||||||
be nonzero. Set *PN to the new number of objects, and return the
|
|
||||||
pointer to the new block. *PN is never set to zero, and the
|
|
||||||
returned pointer is never null.
|
|
||||||
|
|
||||||
Repeated reallocations are guaranteed to make progress, either by
|
|
||||||
allocating an initial block with a nonzero size, or by allocating a
|
|
||||||
larger block.
|
|
||||||
|
|
||||||
In the following implementation, nonzero sizes are doubled so that
|
|
||||||
repeated reallocations have O(N log N) overall cost rather than
|
|
||||||
O(N**2) cost, but the specification for this function does not
|
|
||||||
guarantee that sizes are doubled.
|
|
||||||
|
|
||||||
Here is an example of use:
|
|
||||||
|
|
||||||
int *p = NULL;
|
|
||||||
size_t used = 0;
|
|
||||||
size_t allocated = 0;
|
|
||||||
|
|
||||||
void
|
|
||||||
append_int (int value)
|
|
||||||
{
|
|
||||||
if (used == allocated)
|
|
||||||
p = x2nrealloc (p, &allocated, sizeof *p);
|
|
||||||
p[used++] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
This causes x2nrealloc to allocate a block of some nonzero size the
|
|
||||||
first time it is called.
|
|
||||||
|
|
||||||
To have finer-grained control over the initial size, set *PN to a
|
|
||||||
nonzero value before calling this function with P == NULL. For
|
|
||||||
example:
|
|
||||||
|
|
||||||
int *p = NULL;
|
|
||||||
size_t used = 0;
|
|
||||||
size_t allocated = 0;
|
|
||||||
size_t allocated1 = 1000;
|
|
||||||
|
|
||||||
void
|
|
||||||
append_int (int value)
|
|
||||||
{
|
|
||||||
if (used == allocated)
|
|
||||||
{
|
|
||||||
p = x2nrealloc (p, &allocated1, sizeof *p);
|
|
||||||
allocated = allocated1;
|
|
||||||
}
|
|
||||||
p[used++] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline void *
|
|
||||||
x2nrealloc_inline (void *p, size_t *pn, size_t s)
|
|
||||||
{
|
|
||||||
size_t n = *pn;
|
|
||||||
|
|
||||||
if (! p)
|
|
||||||
{
|
|
||||||
if (! n)
|
|
||||||
{
|
|
||||||
/* The approximate size to use for initial small allocation
|
|
||||||
requests, when the invoking code specifies an old size of
|
|
||||||
zero. 64 bytes is the largest "small" request for the
|
|
||||||
GNU C library malloc. */
|
|
||||||
enum { DEFAULT_MXFAST = 64 };
|
|
||||||
|
|
||||||
n = DEFAULT_MXFAST / s;
|
|
||||||
n += !n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (SIZE_MAX / 2 / s < n)
|
|
||||||
xalloc_die ();
|
|
||||||
n *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pn = n;
|
|
||||||
return xrealloc (p, n * s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
x2nrealloc (void *p, size_t *pn, size_t s)
|
|
||||||
{
|
|
||||||
return x2nrealloc_inline (p, pn, s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If P is null, allocate a block of at least *PN bytes; otherwise,
|
/* If P is null, allocate a block of at least *PN bytes; otherwise,
|
||||||
@ -183,7 +74,7 @@ x2nrealloc (void *p, size_t *pn, size_t s)
|
|||||||
void *
|
void *
|
||||||
x2realloc (void *p, size_t *pn)
|
x2realloc (void *p, size_t *pn)
|
||||||
{
|
{
|
||||||
return x2nrealloc_inline (p, pn, 1);
|
return x2nrealloc (p, pn, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate S bytes of zeroed memory dynamically, with error checking.
|
/* Allocate S bytes of zeroed memory dynamically, with error checking.
|
||||||
@ -204,8 +95,11 @@ xcalloc (size_t n, size_t s)
|
|||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
/* Test for overflow, since some calloc implementations don't have
|
/* Test for overflow, since some calloc implementations don't have
|
||||||
proper overflow checks. */
|
proper overflow checks. But omit overflow and size-zero tests if
|
||||||
if (xalloc_oversized (n, s) || (! (p = calloc (n, s)) && n != 0))
|
HAVE_GNU_CALLOC, since GNU calloc catches overflow and never
|
||||||
|
returns NULL if successful. */
|
||||||
|
if ((! HAVE_GNU_CALLOC && xalloc_oversized (n, s))
|
||||||
|
|| (! (p = calloc (n, s)) && (HAVE_GNU_CALLOC || n != 0)))
|
||||||
xalloc_die ();
|
xalloc_die ();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* Copy memory area and return pointer after last written byte.
|
/* Duplicate a bounded initial segment of a string, with out-of-memory
|
||||||
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
checking.
|
||||||
|
Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -13,24 +14,24 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#ifndef mempcpy
|
#include <config.h>
|
||||||
|
|
||||||
# if HAVE_MEMPCPY
|
/* Specification. */
|
||||||
|
#include "xstrndup.h"
|
||||||
|
|
||||||
/* Get mempcpy() declaration. */
|
#include <string.h>
|
||||||
# include <string.h>
|
#include "xalloc.h"
|
||||||
|
|
||||||
# else
|
/* Return a newly allocated copy of at most N bytes of STRING.
|
||||||
|
In other words, return a copy of the initial segment of length N of
|
||||||
/* Get size_t */
|
STRING. */
|
||||||
# include <stddef.h>
|
char *
|
||||||
|
xstrndup (const char *string, size_t n)
|
||||||
/* Copy N bytes of SRC to DEST, return pointer to bytes after the
|
{
|
||||||
last written byte. */
|
char *s = strndup (string, n);
|
||||||
extern void *mempcpy (void *dest, const void *src, size_t n);
|
if (! s)
|
||||||
|
xalloc_die ();
|
||||||
# endif
|
return s;
|
||||||
|
}
|
||||||
#endif
|
|
@ -1,4 +1,5 @@
|
|||||||
/* Duplicate a size-bounded string.
|
/* Duplicate a bounded initial segment of a string, with out-of-memory
|
||||||
|
checking.
|
||||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
@ -13,18 +14,11 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
#if HAVE_STRNDUP
|
|
||||||
|
|
||||||
/* Get strndup() declaration. */
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
/* Return a newly allocated copy of at most N bytes of STRING. */
|
/* Return a newly allocated copy of at most N bytes of STRING.
|
||||||
extern char *strndup (const char *string, size_t n);
|
In other words, return a copy of the initial segment of length N of
|
||||||
|
STRING. */
|
||||||
#endif
|
extern char *xstrndup (const char *string, size_t n);
|
439
src/copyin.c
439
src/copyin.c
@ -1,5 +1,6 @@
|
|||||||
/* copyin.c - extract or list a cpio archive
|
/* copyin.c - extract or list a cpio archive
|
||||||
Copyright (C) 1990,1991,1992,2001,2002,2003,2004 Free Software Foundation, Inc.
|
Copyright (C) 1990,1991,1992,2001,2002,2003,2004,
|
||||||
|
2005, 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -11,9 +12,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
#include <system.h>
|
#include <system.h>
|
||||||
|
|
||||||
@ -27,14 +29,14 @@
|
|||||||
#include "defer.h"
|
#include "defer.h"
|
||||||
#include <rmt.h>
|
#include <rmt.h>
|
||||||
#ifndef FNM_PATHNAME
|
#ifndef FNM_PATHNAME
|
||||||
#include <fnmatch.h>
|
# include <fnmatch.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_LCHOWN
|
#ifndef HAVE_LCHOWN
|
||||||
#define lchown chown
|
# define lchown(f,u,g) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void copyin_regular_file(struct new_cpio_header* file_hdr,
|
static void copyin_regular_file(struct cpio_file_stat* file_hdr,
|
||||||
int in_file_des);
|
int in_file_des);
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -47,7 +49,7 @@ warn_junk_bytes (long bytes_skipped)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
query_rename(struct new_cpio_header* file_hdr, FILE *tty_in, FILE *tty_out,
|
query_rename(struct cpio_file_stat* file_hdr, FILE *tty_in, FILE *tty_out,
|
||||||
FILE *rename_in)
|
FILE *rename_in)
|
||||||
{
|
{
|
||||||
char *str_res; /* Result for string function. */
|
char *str_res; /* Result for string function. */
|
||||||
@ -125,7 +127,7 @@ tape_skip_padding (int in_file_des, int offset)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
list_file(struct new_cpio_header* file_hdr, int in_file_des)
|
list_file(struct cpio_file_stat* file_hdr, int in_file_des)
|
||||||
{
|
{
|
||||||
if (verbose_flag)
|
if (verbose_flag)
|
||||||
{
|
{
|
||||||
@ -176,15 +178,15 @@ list_file(struct new_cpio_header* file_hdr, int in_file_des)
|
|||||||
#endif
|
#endif
|
||||||
if (crc != file_hdr->c_chksum)
|
if (crc != file_hdr->c_chksum)
|
||||||
{
|
{
|
||||||
error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"),
|
error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"),
|
||||||
file_hdr->c_name, crc, file_hdr->c_chksum);
|
file_hdr->c_name, crc, file_hdr->c_chksum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
try_existing_file(struct new_cpio_header* file_hdr, int in_file_des,
|
try_existing_file (struct cpio_file_stat* file_hdr, int in_file_des,
|
||||||
int *existing_dir)
|
int *existing_dir)
|
||||||
{
|
{
|
||||||
struct stat file_stat;
|
struct stat file_stat;
|
||||||
|
|
||||||
@ -238,7 +240,7 @@ struct deferment *deferments = NULL;
|
|||||||
go on one list, although we could optimize this if necessary. */
|
go on one list, although we could optimize this if necessary. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
defer_copyin (struct new_cpio_header *file_hdr)
|
defer_copyin (struct cpio_file_stat *file_hdr)
|
||||||
{
|
{
|
||||||
struct deferment *d;
|
struct deferment *d;
|
||||||
d = create_deferment (file_hdr);
|
d = create_deferment (file_hdr);
|
||||||
@ -252,7 +254,7 @@ defer_copyin (struct new_cpio_header *file_hdr)
|
|||||||
list and create any which are links to this file. */
|
list and create any which are links to this file. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
create_defered_links (struct new_cpio_header *file_hdr)
|
create_defered_links (struct cpio_file_stat *file_hdr)
|
||||||
{
|
{
|
||||||
struct deferment *d;
|
struct deferment *d;
|
||||||
struct deferment *d_prev;
|
struct deferment *d_prev;
|
||||||
@ -299,7 +301,7 @@ create_defered_links (struct new_cpio_header *file_hdr)
|
|||||||
then create the other deferred links. */
|
then create the other deferred links. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
create_defered_links_to_skipped (struct new_cpio_header *file_hdr,
|
create_defered_links_to_skipped (struct cpio_file_stat *file_hdr,
|
||||||
int in_file_des)
|
int in_file_des)
|
||||||
{
|
{
|
||||||
struct deferment *d;
|
struct deferment *d;
|
||||||
@ -307,7 +309,6 @@ create_defered_links_to_skipped (struct new_cpio_header *file_hdr,
|
|||||||
int ino;
|
int ino;
|
||||||
int maj;
|
int maj;
|
||||||
int min;
|
int min;
|
||||||
int link_res;
|
|
||||||
if (file_hdr->c_filesize == 0)
|
if (file_hdr->c_filesize == 0)
|
||||||
{
|
{
|
||||||
/* The file doesn't have any data attached to it so we don't have
|
/* The file doesn't have any data attached to it so we don't have
|
||||||
@ -355,10 +356,7 @@ create_final_defers ()
|
|||||||
struct deferment *d;
|
struct deferment *d;
|
||||||
int link_res;
|
int link_res;
|
||||||
int out_file_des;
|
int out_file_des;
|
||||||
struct utimbuf times; /* For setting file times. */
|
|
||||||
/* Initialize this in case it has members we don't know to set. */
|
|
||||||
bzero (×, sizeof (struct utimbuf));
|
|
||||||
|
|
||||||
for (d = deferments; d != NULL; d = d->next)
|
for (d = deferments; d != NULL; d = d->next)
|
||||||
{
|
{
|
||||||
/* Debian hack: A line, which could cause an endless loop, was
|
/* Debian hack: A line, which could cause an endless loop, was
|
||||||
@ -385,34 +383,20 @@ create_final_defers ()
|
|||||||
}
|
}
|
||||||
if (out_file_des < 0)
|
if (out_file_des < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", d->header.c_name);
|
open_error (d->header.c_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (close (out_file_des) < 0)
|
set_perms (out_file_des, &d->header);
|
||||||
error (0, errno, "%s", d->header.c_name);
|
|
||||||
|
if (close (out_file_des) < 0)
|
||||||
|
close_error (d->header.c_name);
|
||||||
|
|
||||||
/* File is now copied; set attributes. */
|
|
||||||
if (!no_chown_flag)
|
|
||||||
if ((chown (d->header.c_name,
|
|
||||||
set_owner_flag ? set_owner : d->header.c_uid,
|
|
||||||
set_group_flag ? set_group : d->header.c_gid) < 0)
|
|
||||||
&& errno != EPERM)
|
|
||||||
error (0, errno, "%s", d->header.c_name);
|
|
||||||
/* chown may have turned off some permissions we wanted. */
|
|
||||||
if (chmod (d->header.c_name, (int) d->header.c_mode) < 0)
|
|
||||||
error (0, errno, "%s", d->header.c_name);
|
|
||||||
if (retain_time_flag)
|
|
||||||
{
|
|
||||||
times.actime = times.modtime = d->header.c_mtime;
|
|
||||||
if (utime (d->header.c_name, ×) < 0)
|
|
||||||
error (0, errno, "%s", d->header.c_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
copyin_regular_file (struct new_cpio_header* file_hdr, int in_file_des)
|
copyin_regular_file (struct cpio_file_stat* file_hdr, int in_file_des)
|
||||||
{
|
{
|
||||||
int out_file_des; /* Output file descriptor. */
|
int out_file_des; /* Output file descriptor. */
|
||||||
|
|
||||||
@ -460,7 +444,7 @@ copyin_regular_file (struct new_cpio_header* file_hdr, int in_file_des)
|
|||||||
{
|
{
|
||||||
tape_toss_input (in_file_des, file_hdr->c_filesize);
|
tape_toss_input (in_file_des, file_hdr->c_filesize);
|
||||||
tape_skip_padding (in_file_des, file_hdr->c_filesize);
|
tape_skip_padding (in_file_des, file_hdr->c_filesize);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (file_hdr->c_nlink > 1
|
else if (file_hdr->c_nlink > 1
|
||||||
@ -509,7 +493,7 @@ copyin_regular_file (struct new_cpio_header* file_hdr, int in_file_des)
|
|||||||
|
|
||||||
if (out_file_des < 0)
|
if (out_file_des < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", file_hdr->c_name);
|
open_error (file_hdr->c_name);
|
||||||
tape_toss_input (in_file_des, file_hdr->c_filesize);
|
tape_toss_input (in_file_des, file_hdr->c_filesize);
|
||||||
tape_skip_padding (in_file_des, file_hdr->c_filesize);
|
tape_skip_padding (in_file_des, file_hdr->c_filesize);
|
||||||
return;
|
return;
|
||||||
@ -541,7 +525,7 @@ copyin_regular_file (struct new_cpio_header* file_hdr, int in_file_des)
|
|||||||
if (archive_format == arf_crcascii)
|
if (archive_format == arf_crcascii)
|
||||||
{
|
{
|
||||||
if (crc != file_hdr->c_chksum)
|
if (crc != file_hdr->c_chksum)
|
||||||
error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"),
|
error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"),
|
||||||
file_hdr->c_name, crc, file_hdr->c_chksum);
|
file_hdr->c_name, crc, file_hdr->c_chksum);
|
||||||
}
|
}
|
||||||
tape_skip_padding (in_file_des, file_hdr->c_filesize);
|
tape_skip_padding (in_file_des, file_hdr->c_filesize);
|
||||||
@ -557,39 +541,19 @@ copyin_regular_file (struct new_cpio_header* file_hdr, int in_file_des)
|
|||||||
write (out_file_des, "", 1);
|
write (out_file_des, "", 1);
|
||||||
delayed_seek_count = 0;
|
delayed_seek_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_perms (out_file_des, file_hdr);
|
||||||
|
|
||||||
if (close (out_file_des) < 0)
|
if (close (out_file_des) < 0)
|
||||||
error (0, errno, "%s", file_hdr->c_name);
|
close_error (file_hdr->c_name);
|
||||||
|
|
||||||
if (archive_format == arf_crcascii)
|
if (archive_format == arf_crcascii)
|
||||||
{
|
{
|
||||||
if (crc != file_hdr->c_chksum)
|
if (crc != file_hdr->c_chksum)
|
||||||
error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"),
|
error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"),
|
||||||
file_hdr->c_name, crc, file_hdr->c_chksum);
|
file_hdr->c_name, crc, file_hdr->c_chksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* File is now copied; set attributes. */
|
|
||||||
if (!no_chown_flag)
|
|
||||||
if ((chown (file_hdr->c_name,
|
|
||||||
set_owner_flag ? set_owner : file_hdr->c_uid,
|
|
||||||
set_group_flag ? set_group : file_hdr->c_gid) < 0)
|
|
||||||
&& errno != EPERM)
|
|
||||||
error (0, errno, "%s", file_hdr->c_name);
|
|
||||||
|
|
||||||
/* chown may have turned off some permissions we wanted. */
|
|
||||||
if (chmod (file_hdr->c_name, (int) file_hdr->c_mode) < 0)
|
|
||||||
error (0, errno, "%s", file_hdr->c_name);
|
|
||||||
|
|
||||||
if (retain_time_flag)
|
|
||||||
{
|
|
||||||
struct utimbuf times; /* For setting file times. */
|
|
||||||
/* Initialize this in case it has members we don't know to set. */
|
|
||||||
bzero (×, sizeof (struct utimbuf));
|
|
||||||
|
|
||||||
times.actime = times.modtime = file_hdr->c_mtime;
|
|
||||||
if (utime (file_hdr->c_name, ×) < 0)
|
|
||||||
error (0, errno, "%s", file_hdr->c_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
tape_skip_padding (in_file_des, file_hdr->c_filesize);
|
tape_skip_padding (in_file_des, file_hdr->c_filesize);
|
||||||
if (file_hdr->c_nlink > 1
|
if (file_hdr->c_nlink > 1
|
||||||
&& (archive_format == arf_newascii || archive_format == arf_crcascii) )
|
&& (archive_format == arf_newascii || archive_format == arf_crcascii) )
|
||||||
@ -603,7 +567,7 @@ copyin_regular_file (struct new_cpio_header* file_hdr, int in_file_des)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
copyin_directory(struct new_cpio_header* file_hdr, int existing_dir)
|
copyin_directory (struct cpio_file_stat *file_hdr, int existing_dir)
|
||||||
{
|
{
|
||||||
int res; /* Result of various function calls. */
|
int res; /* Result of various function calls. */
|
||||||
#ifdef HPUX_CDF
|
#ifdef HPUX_CDF
|
||||||
@ -663,43 +627,29 @@ copyin_directory(struct new_cpio_header* file_hdr, int existing_dir)
|
|||||||
because the directory exists. If that's the case,
|
because the directory exists. If that's the case,
|
||||||
don't complain about it. */
|
don't complain about it. */
|
||||||
struct stat file_stat;
|
struct stat file_stat;
|
||||||
if ( (errno != EEXIST) ||
|
if (errno != EEXIST)
|
||||||
(lstat (file_hdr->c_name, &file_stat) != 0) ||
|
|
||||||
!(S_ISDIR (file_stat.st_mode) ) )
|
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", file_hdr->c_name);
|
mkdir_error (file_hdr->c_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (lstat (file_hdr->c_name, &file_stat))
|
||||||
|
{
|
||||||
|
stat_error (file_hdr->c_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!(S_ISDIR (file_stat.st_mode)))
|
||||||
|
{
|
||||||
|
error (0, 0, _("%s is not a directory"),
|
||||||
|
quotearg_colon (file_hdr->c_name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!no_chown_flag)
|
|
||||||
if ((chown (file_hdr->c_name,
|
|
||||||
set_owner_flag ? set_owner : file_hdr->c_uid,
|
|
||||||
set_group_flag ? set_group : file_hdr->c_gid) < 0)
|
|
||||||
&& errno != EPERM)
|
|
||||||
error (0, errno, "%s", file_hdr->c_name);
|
|
||||||
/* chown may have turned off some permissions we wanted. */
|
|
||||||
if (chmod (file_hdr->c_name, (int) file_hdr->c_mode) < 0)
|
|
||||||
error (0, errno, "%s", file_hdr->c_name);
|
|
||||||
#ifdef HPUX_CDF
|
|
||||||
if (cdf_flag)
|
|
||||||
/* Once we "hide" the directory with the chmod(),
|
|
||||||
we have to refer to it using name+ instead of name. */
|
|
||||||
file_hdr->c_name [cdf_char] = '+';
|
|
||||||
#endif
|
|
||||||
if (retain_time_flag)
|
|
||||||
{
|
|
||||||
struct utimbuf times; /* For setting file times. */
|
|
||||||
/* Initialize this in case it has members we don't know to set. */
|
|
||||||
bzero (×, sizeof (struct utimbuf));
|
|
||||||
|
|
||||||
times.actime = times.modtime = file_hdr->c_mtime;
|
set_perms (-1, file_hdr);
|
||||||
if (utime (file_hdr->c_name, ×) < 0)
|
|
||||||
error (0, errno, "%s", file_hdr->c_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
copyin_device(struct new_cpio_header* file_hdr)
|
copyin_device (struct cpio_file_stat* file_hdr)
|
||||||
{
|
{
|
||||||
int res; /* Result of various function calls. */
|
int res; /* Result of various function calls. */
|
||||||
|
|
||||||
@ -752,32 +702,27 @@ copyin_device(struct new_cpio_header* file_hdr)
|
|||||||
}
|
}
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", file_hdr->c_name);
|
mknod_error (file_hdr->c_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!no_chown_flag)
|
if (!no_chown_flag)
|
||||||
if ((chown (file_hdr->c_name,
|
{
|
||||||
set_owner_flag ? set_owner : file_hdr->c_uid,
|
uid_t uid = set_owner_flag ? set_owner : file_hdr->c_uid;
|
||||||
set_group_flag ? set_group : file_hdr->c_gid) < 0)
|
gid_t gid = set_group_flag ? set_group : file_hdr->c_gid;
|
||||||
&& errno != EPERM)
|
if ((chown (file_hdr->c_name, uid, gid) < 0)
|
||||||
error (0, errno, "%s", file_hdr->c_name);
|
&& errno != EPERM)
|
||||||
|
chown_error_details (file_hdr->c_name, uid, gid);
|
||||||
|
}
|
||||||
/* chown may have turned off some permissions we wanted. */
|
/* chown may have turned off some permissions we wanted. */
|
||||||
if (chmod (file_hdr->c_name, file_hdr->c_mode) < 0)
|
if (chmod (file_hdr->c_name, file_hdr->c_mode) < 0)
|
||||||
error (0, errno, "%s", file_hdr->c_name);
|
chmod_error_details (file_hdr->c_name, file_hdr->c_mode);
|
||||||
if (retain_time_flag)
|
if (retain_time_flag)
|
||||||
{
|
set_file_times (-1, file_hdr->c_name, file_hdr->c_mtime,
|
||||||
struct utimbuf times; /* For setting file times. */
|
file_hdr->c_mtime);
|
||||||
/* Initialize this in case it has members we don't know to set. */
|
|
||||||
bzero (×, sizeof (struct utimbuf));
|
|
||||||
|
|
||||||
times.actime = times.modtime = file_hdr->c_mtime;
|
|
||||||
if (utime (file_hdr->c_name, ×) < 0)
|
|
||||||
error (0, errno, "%s", file_hdr->c_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
copyin_link(struct new_cpio_header *file_hdr, int in_file_des)
|
copyin_link(struct cpio_file_stat *file_hdr, int in_file_des)
|
||||||
{
|
{
|
||||||
char *link_name = NULL; /* Name of hard and symbolic links. */
|
char *link_name = NULL; /* Name of hard and symbolic links. */
|
||||||
int res; /* Result of various function calls. */
|
int res; /* Result of various function calls. */
|
||||||
@ -807,23 +752,24 @@ copyin_link(struct new_cpio_header *file_hdr, int in_file_des)
|
|||||||
}
|
}
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", file_hdr->c_name);
|
error (0, errno, _("%s: Cannot symlink to %s"),
|
||||||
|
quotearg_colon (link_name), quote_n (1, file_hdr->c_name));
|
||||||
free (link_name);
|
free (link_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!no_chown_flag)
|
if (!no_chown_flag)
|
||||||
if ((lchown (file_hdr->c_name,
|
{
|
||||||
set_owner_flag ? set_owner : file_hdr->c_uid,
|
uid_t uid = set_owner_flag ? set_owner : file_hdr->c_uid;
|
||||||
set_group_flag ? set_group : file_hdr->c_gid) < 0)
|
gid_t gid = set_group_flag ? set_group : file_hdr->c_gid;
|
||||||
&& errno != EPERM)
|
if ((lchown (file_hdr->c_name, uid, gid) < 0)
|
||||||
{
|
&& errno != EPERM)
|
||||||
error (0, errno, "%s", file_hdr->c_name);
|
chown_error_details (file_hdr->c_name, uid, gid);
|
||||||
}
|
}
|
||||||
free (link_name);
|
free (link_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
copyin_file (struct new_cpio_header* file_hdr, int in_file_des)
|
copyin_file (struct cpio_file_stat* file_hdr, int in_file_des)
|
||||||
{
|
{
|
||||||
int existing_dir;
|
int existing_dir;
|
||||||
|
|
||||||
@ -835,11 +781,11 @@ copyin_file (struct new_cpio_header* file_hdr, int in_file_des)
|
|||||||
switch (file_hdr->c_mode & CP_IFMT)
|
switch (file_hdr->c_mode & CP_IFMT)
|
||||||
{
|
{
|
||||||
case CP_IFREG:
|
case CP_IFREG:
|
||||||
copyin_regular_file(file_hdr, in_file_des);
|
copyin_regular_file (file_hdr, in_file_des);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_IFDIR:
|
case CP_IFDIR:
|
||||||
copyin_directory(file_hdr, existing_dir);
|
copyin_directory (file_hdr, existing_dir);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_IFCHR:
|
case CP_IFCHR:
|
||||||
@ -850,12 +796,12 @@ copyin_file (struct new_cpio_header* file_hdr, int in_file_des)
|
|||||||
#ifdef CP_IFIFO
|
#ifdef CP_IFIFO
|
||||||
case CP_IFIFO:
|
case CP_IFIFO:
|
||||||
#endif
|
#endif
|
||||||
copyin_device(file_hdr);
|
copyin_device (file_hdr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef CP_IFLNK
|
#ifdef CP_IFLNK
|
||||||
case CP_IFLNK:
|
case CP_IFLNK:
|
||||||
copyin_link(file_hdr, in_file_des);
|
copyin_link (file_hdr, in_file_des);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -876,7 +822,7 @@ static time_t current_time;
|
|||||||
this file is a symbolic link to. */
|
this file is a symbolic link to. */
|
||||||
|
|
||||||
void
|
void
|
||||||
long_format (struct new_cpio_header *file_hdr, char *link_name)
|
long_format (struct cpio_file_stat *file_hdr, char *link_name)
|
||||||
{
|
{
|
||||||
char mbuf[11];
|
char mbuf[11];
|
||||||
char tbuf[40];
|
char tbuf[40];
|
||||||
@ -897,7 +843,7 @@ long_format (struct new_cpio_header *file_hdr, char *link_name)
|
|||||||
}
|
}
|
||||||
tbuf[16] = '\0';
|
tbuf[16] = '\0';
|
||||||
|
|
||||||
printf ("%s %3u ", mbuf, file_hdr->c_nlink);
|
printf ("%s %3lu ", mbuf, file_hdr->c_nlink);
|
||||||
|
|
||||||
if (numeric_uid)
|
if (numeric_uid)
|
||||||
printf ("%-8u %-8u ", (unsigned int) file_hdr->c_uid,
|
printf ("%-8u %-8u ", (unsigned int) file_hdr->c_uid,
|
||||||
@ -908,10 +854,10 @@ long_format (struct new_cpio_header *file_hdr, char *link_name)
|
|||||||
|
|
||||||
if ((file_hdr->c_mode & CP_IFMT) == CP_IFCHR
|
if ((file_hdr->c_mode & CP_IFMT) == CP_IFCHR
|
||||||
|| (file_hdr->c_mode & CP_IFMT) == CP_IFBLK)
|
|| (file_hdr->c_mode & CP_IFMT) == CP_IFBLK)
|
||||||
printf ("%3u, %3u ", file_hdr->c_rdev_maj,
|
printf ("%3lu, %3lu ", file_hdr->c_rdev_maj,
|
||||||
file_hdr->c_rdev_min);
|
file_hdr->c_rdev_min);
|
||||||
else
|
else
|
||||||
printf ("%8lu ", file_hdr->c_filesize);
|
printf ("%8"PRIuMAX" ", (uintmax_t) file_hdr->c_filesize);
|
||||||
|
|
||||||
printf ("%s ", tbuf + 4);
|
printf ("%s ", tbuf + 4);
|
||||||
|
|
||||||
@ -997,7 +943,7 @@ read_pattern_file ()
|
|||||||
|
|
||||||
pattern_fp = fopen (pattern_file_name, "r");
|
pattern_fp = fopen (pattern_file_name, "r");
|
||||||
if (pattern_fp == NULL)
|
if (pattern_fp == NULL)
|
||||||
error (1, errno, "%s", pattern_file_name);
|
open_error (pattern_file_name);
|
||||||
while (ds_fgetstr (pattern_fp, &pattern_name, '\n') != NULL)
|
while (ds_fgetstr (pattern_fp, &pattern_name, '\n') != NULL)
|
||||||
{
|
{
|
||||||
if (new_num_patterns >= max_new_patterns)
|
if (new_num_patterns >= max_new_patterns)
|
||||||
@ -1011,7 +957,7 @@ read_pattern_file ()
|
|||||||
++new_num_patterns;
|
++new_num_patterns;
|
||||||
}
|
}
|
||||||
if (ferror (pattern_fp) || fclose (pattern_fp) == EOF)
|
if (ferror (pattern_fp) || fclose (pattern_fp) == EOF)
|
||||||
error (1, errno, "%s", pattern_file_name);
|
close_error (pattern_file_name);
|
||||||
|
|
||||||
for (i = 0; i < num_patterns; ++i)
|
for (i = 0; i < num_patterns; ++i)
|
||||||
new_save_patterns[i] = save_patterns[i];
|
new_save_patterns[i] = save_patterns[i];
|
||||||
@ -1020,6 +966,52 @@ read_pattern_file ()
|
|||||||
num_patterns = new_num_patterns;
|
num_patterns = new_num_patterns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uintmax_t
|
||||||
|
from_ascii (char const *where, size_t digs, unsigned logbase)
|
||||||
|
{
|
||||||
|
uintmax_t value = 0;
|
||||||
|
char const *buf = where;
|
||||||
|
char const *end = buf + digs;
|
||||||
|
int overflow = 0;
|
||||||
|
static char codetab[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
for (; *buf == ' '; buf++)
|
||||||
|
{
|
||||||
|
if (buf == end)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf == end || *buf == 0)
|
||||||
|
return 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
unsigned d;
|
||||||
|
|
||||||
|
char *p = strchr (codetab, toupper (*buf));
|
||||||
|
if (!p)
|
||||||
|
{
|
||||||
|
error (0, 0, _("Malformed number %.*s"), digs, where);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
d = p - codetab;
|
||||||
|
if ((d >> logbase) > 1)
|
||||||
|
{
|
||||||
|
error (0, 0, _("Malformed number %.*s"), digs, where);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
value += d;
|
||||||
|
if (++buf == end || *buf == 0)
|
||||||
|
break;
|
||||||
|
overflow |= value ^ (value << logbase >> logbase);
|
||||||
|
value <<= logbase;
|
||||||
|
}
|
||||||
|
if (overflow)
|
||||||
|
error (0, 0, _("Archive value %.*s is out of range"),
|
||||||
|
digs, where);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1030,8 +1022,13 @@ read_pattern_file ()
|
|||||||
descriptor IN_DES into FILE_HDR. */
|
descriptor IN_DES into FILE_HDR. */
|
||||||
|
|
||||||
void
|
void
|
||||||
read_in_header (struct new_cpio_header *file_hdr, int in_des)
|
read_in_header (struct cpio_file_stat *file_hdr, int in_des)
|
||||||
{
|
{
|
||||||
|
union {
|
||||||
|
char str[6];
|
||||||
|
unsigned short num;
|
||||||
|
struct old_cpio_header old_header;
|
||||||
|
} magic;
|
||||||
long bytes_skipped = 0; /* Bytes of junk found before magic number. */
|
long bytes_skipped = 0; /* Bytes of junk found before magic number. */
|
||||||
|
|
||||||
/* Search for a valid magic number. */
|
/* Search for a valid magic number. */
|
||||||
@ -1090,52 +1087,53 @@ read_in_header (struct new_cpio_header *file_hdr, int in_des)
|
|||||||
|
|
||||||
file_hdr->c_tar_linkname = NULL;
|
file_hdr->c_tar_linkname = NULL;
|
||||||
|
|
||||||
tape_buffered_read ((char *) file_hdr, in_des, 6L);
|
tape_buffered_read (magic.str, in_des, 6L);
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (append_flag)
|
if (append_flag)
|
||||||
last_header_start = input_bytes - io_block_size
|
last_header_start = input_bytes - io_block_size
|
||||||
+ (in_buff - input_buffer) - 6;
|
+ (in_buff - input_buffer) - 6;
|
||||||
if (archive_format == arf_newascii
|
if (archive_format == arf_newascii
|
||||||
&& !strncmp ((char *) file_hdr, "070701", 6))
|
&& !strncmp (magic.str, "070701", 6))
|
||||||
{
|
{
|
||||||
if (bytes_skipped > 0)
|
if (bytes_skipped > 0)
|
||||||
warn_junk_bytes (bytes_skipped);
|
warn_junk_bytes (bytes_skipped);
|
||||||
|
file_hdr->c_magic = 070701;
|
||||||
read_in_new_ascii (file_hdr, in_des);
|
read_in_new_ascii (file_hdr, in_des);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (archive_format == arf_crcascii
|
if (archive_format == arf_crcascii
|
||||||
&& !strncmp ((char *) file_hdr, "070702", 6))
|
&& !strncmp (magic.str, "070702", 6))
|
||||||
{
|
{
|
||||||
if (bytes_skipped > 0)
|
if (bytes_skipped > 0)
|
||||||
warn_junk_bytes (bytes_skipped);
|
warn_junk_bytes (bytes_skipped);
|
||||||
|
file_hdr->c_magic = 070702;
|
||||||
read_in_new_ascii (file_hdr, in_des);
|
read_in_new_ascii (file_hdr, in_des);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
|
if ( (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
|
||||||
&& !strncmp ((char *) file_hdr, "070707", 6))
|
&& !strncmp (magic.str, "070707", 6))
|
||||||
{
|
{
|
||||||
if (bytes_skipped > 0)
|
if (bytes_skipped > 0)
|
||||||
warn_junk_bytes (bytes_skipped);
|
warn_junk_bytes (bytes_skipped);
|
||||||
|
file_hdr->c_magic = 070707;
|
||||||
read_in_old_ascii (file_hdr, in_des);
|
read_in_old_ascii (file_hdr, in_des);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( (archive_format == arf_binary || archive_format == arf_hpbinary)
|
if ( (archive_format == arf_binary || archive_format == arf_hpbinary)
|
||||||
&& (file_hdr->c_magic == 070707
|
&& (magic.num == 070707
|
||||||
|| file_hdr->c_magic == swab_short ((unsigned short) 070707)))
|
|| magic.num == swab_short ((unsigned short) 070707)))
|
||||||
{
|
{
|
||||||
/* Having to skip 1 byte because of word alignment is normal. */
|
/* Having to skip 1 byte because of word alignment is normal. */
|
||||||
if (bytes_skipped > 0)
|
if (bytes_skipped > 0)
|
||||||
warn_junk_bytes (bytes_skipped);
|
warn_junk_bytes (bytes_skipped);
|
||||||
|
file_hdr->c_magic = 070707;
|
||||||
read_in_binary (file_hdr, in_des);
|
read_in_binary (file_hdr, &magic.old_header, in_des);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bytes_skipped++;
|
bytes_skipped++;
|
||||||
bcopy ((char *) file_hdr + 1, (char *) file_hdr, 5);
|
memmove (magic.str, magic.str + 1, 5);
|
||||||
tape_buffered_read ((char *) file_hdr + 5, in_des, 1L);
|
tape_buffered_read (magic.str, in_des, 1L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1144,25 +1142,30 @@ read_in_header (struct new_cpio_header *file_hdr, int in_des)
|
|||||||
already filled in. */
|
already filled in. */
|
||||||
|
|
||||||
void
|
void
|
||||||
read_in_old_ascii (struct new_cpio_header *file_hdr, int in_des)
|
read_in_old_ascii (struct cpio_file_stat *file_hdr, int in_des)
|
||||||
{
|
{
|
||||||
char ascii_header[78];
|
struct old_ascii_header ascii_header;
|
||||||
unsigned long dev;
|
unsigned long dev;
|
||||||
unsigned long rdev;
|
|
||||||
|
|
||||||
tape_buffered_read (ascii_header, in_des, 70L);
|
tape_buffered_read (ascii_header.c_dev, in_des,
|
||||||
ascii_header[70] = '\0';
|
sizeof ascii_header - sizeof ascii_header.c_magic);
|
||||||
sscanf (ascii_header,
|
dev = FROM_OCTAL (ascii_header.c_dev);
|
||||||
"%6lo%6lo%6lo%6lo%6lo%6lo%6lo%11lo%6lo%11lo",
|
|
||||||
&dev, &file_hdr->c_ino,
|
|
||||||
&file_hdr->c_mode, &file_hdr->c_uid, &file_hdr->c_gid,
|
|
||||||
&file_hdr->c_nlink, &rdev, &file_hdr->c_mtime,
|
|
||||||
&file_hdr->c_namesize, &file_hdr->c_filesize);
|
|
||||||
file_hdr->c_dev_maj = major (dev);
|
file_hdr->c_dev_maj = major (dev);
|
||||||
file_hdr->c_dev_min = minor (dev);
|
file_hdr->c_dev_min = minor (dev);
|
||||||
file_hdr->c_rdev_maj = major (rdev);
|
|
||||||
file_hdr->c_rdev_min = minor (rdev);
|
|
||||||
|
|
||||||
|
file_hdr->c_ino = FROM_OCTAL (ascii_header.c_ino);
|
||||||
|
file_hdr->c_mode = FROM_OCTAL (ascii_header.c_mode);
|
||||||
|
file_hdr->c_uid = FROM_OCTAL (ascii_header.c_uid);
|
||||||
|
file_hdr->c_gid = FROM_OCTAL (ascii_header.c_gid);
|
||||||
|
file_hdr->c_nlink = FROM_OCTAL (ascii_header.c_nlink);
|
||||||
|
dev = FROM_OCTAL (ascii_header.c_rdev);
|
||||||
|
file_hdr->c_rdev_maj = major (dev);
|
||||||
|
file_hdr->c_rdev_min = minor (dev);
|
||||||
|
|
||||||
|
file_hdr->c_mtime = FROM_OCTAL (ascii_header.c_mtime);
|
||||||
|
file_hdr->c_namesize = FROM_OCTAL (ascii_header.c_namesize);
|
||||||
|
file_hdr->c_filesize = FROM_OCTAL (ascii_header.c_filesize);
|
||||||
|
|
||||||
/* Read file name from input. */
|
/* Read file name from input. */
|
||||||
if (file_hdr->c_name != NULL)
|
if (file_hdr->c_name != NULL)
|
||||||
free (file_hdr->c_name);
|
free (file_hdr->c_name);
|
||||||
@ -1204,19 +1207,27 @@ read_in_old_ascii (struct new_cpio_header *file_hdr, int in_des)
|
|||||||
already filled in. */
|
already filled in. */
|
||||||
|
|
||||||
void
|
void
|
||||||
read_in_new_ascii (struct new_cpio_header *file_hdr, int in_des)
|
read_in_new_ascii (struct cpio_file_stat *file_hdr, int in_des)
|
||||||
{
|
{
|
||||||
char ascii_header[112];
|
struct new_ascii_header ascii_header;
|
||||||
|
|
||||||
tape_buffered_read (ascii_header, in_des, 104L);
|
tape_buffered_read (ascii_header.c_ino, in_des,
|
||||||
ascii_header[104] = '\0';
|
sizeof ascii_header - sizeof ascii_header.c_magic);
|
||||||
sscanf (ascii_header,
|
|
||||||
"%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx",
|
file_hdr->c_ino = FROM_HEX (ascii_header.c_ino);
|
||||||
&file_hdr->c_ino, &file_hdr->c_mode, &file_hdr->c_uid,
|
file_hdr->c_mode = FROM_HEX (ascii_header.c_mode);
|
||||||
&file_hdr->c_gid, &file_hdr->c_nlink, &file_hdr->c_mtime,
|
file_hdr->c_uid = FROM_HEX (ascii_header.c_uid);
|
||||||
&file_hdr->c_filesize, &file_hdr->c_dev_maj, &file_hdr->c_dev_min,
|
file_hdr->c_gid = FROM_HEX (ascii_header.c_gid);
|
||||||
&file_hdr->c_rdev_maj, &file_hdr->c_rdev_min, &file_hdr->c_namesize,
|
file_hdr->c_nlink = FROM_HEX (ascii_header.c_nlink);
|
||||||
&file_hdr->c_chksum);
|
file_hdr->c_mtime = FROM_HEX (ascii_header.c_mtime);
|
||||||
|
file_hdr->c_filesize = FROM_HEX (ascii_header.c_filesize);
|
||||||
|
file_hdr->c_dev_maj = FROM_HEX (ascii_header.c_dev_maj);
|
||||||
|
file_hdr->c_dev_min = FROM_HEX (ascii_header.c_dev_min);
|
||||||
|
file_hdr->c_rdev_maj = FROM_HEX (ascii_header.c_rdev_maj);
|
||||||
|
file_hdr->c_rdev_min = FROM_HEX (ascii_header.c_rdev_min);
|
||||||
|
file_hdr->c_namesize = FROM_HEX (ascii_header.c_namesize);
|
||||||
|
file_hdr->c_chksum = FROM_HEX (ascii_header.c_chksum);
|
||||||
|
|
||||||
/* Read file name from input. */
|
/* Read file name from input. */
|
||||||
if (file_hdr->c_name != NULL)
|
if (file_hdr->c_name != NULL)
|
||||||
free (file_hdr->c_name);
|
free (file_hdr->c_name);
|
||||||
@ -1234,15 +1245,14 @@ read_in_new_ascii (struct new_cpio_header *file_hdr, int in_des)
|
|||||||
number, device, and inode number), which are already filled in. */
|
number, device, and inode number), which are already filled in. */
|
||||||
|
|
||||||
void
|
void
|
||||||
read_in_binary (struct new_cpio_header *file_hdr, int in_des)
|
read_in_binary (struct cpio_file_stat *file_hdr,
|
||||||
|
struct old_cpio_header *short_hdr,
|
||||||
|
int in_des)
|
||||||
{
|
{
|
||||||
struct old_cpio_header short_hdr;
|
file_hdr->c_magic = short_hdr->c_magic;
|
||||||
|
|
||||||
/* Copy the data into the short header, then later transfer
|
tape_buffered_read (((char *) short_hdr) + 6, in_des,
|
||||||
it into the argument long header. */
|
sizeof *short_hdr - 6 /* = 20 */);
|
||||||
short_hdr.c_dev = ((struct old_cpio_header *) file_hdr)->c_dev;
|
|
||||||
short_hdr.c_ino = ((struct old_cpio_header *) file_hdr)->c_ino;
|
|
||||||
tape_buffered_read (((char *) &short_hdr) + 6, in_des, 20L);
|
|
||||||
|
|
||||||
/* If the magic number is byte swapped, fix the header. */
|
/* If the magic number is byte swapped, fix the header. */
|
||||||
if (file_hdr->c_magic == swab_short ((unsigned short) 070707))
|
if (file_hdr->c_magic == swab_short ((unsigned short) 070707))
|
||||||
@ -1259,21 +1269,21 @@ read_in_binary (struct new_cpio_header *file_hdr, int in_des)
|
|||||||
swab_array ((char *) &short_hdr, 13);
|
swab_array ((char *) &short_hdr, 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
file_hdr->c_dev_maj = major (short_hdr.c_dev);
|
file_hdr->c_dev_maj = major (short_hdr->c_dev);
|
||||||
file_hdr->c_dev_min = minor (short_hdr.c_dev);
|
file_hdr->c_dev_min = minor (short_hdr->c_dev);
|
||||||
file_hdr->c_ino = short_hdr.c_ino;
|
file_hdr->c_ino = short_hdr->c_ino;
|
||||||
file_hdr->c_mode = short_hdr.c_mode;
|
file_hdr->c_mode = short_hdr->c_mode;
|
||||||
file_hdr->c_uid = short_hdr.c_uid;
|
file_hdr->c_uid = short_hdr->c_uid;
|
||||||
file_hdr->c_gid = short_hdr.c_gid;
|
file_hdr->c_gid = short_hdr->c_gid;
|
||||||
file_hdr->c_nlink = short_hdr.c_nlink;
|
file_hdr->c_nlink = short_hdr->c_nlink;
|
||||||
file_hdr->c_rdev_maj = major (short_hdr.c_rdev);
|
file_hdr->c_rdev_maj = major (short_hdr->c_rdev);
|
||||||
file_hdr->c_rdev_min = minor (short_hdr.c_rdev);
|
file_hdr->c_rdev_min = minor (short_hdr->c_rdev);
|
||||||
file_hdr->c_mtime = (unsigned long) short_hdr.c_mtimes[0] << 16
|
file_hdr->c_mtime = (unsigned long) short_hdr->c_mtimes[0] << 16
|
||||||
| short_hdr.c_mtimes[1];
|
| short_hdr->c_mtimes[1];
|
||||||
|
|
||||||
file_hdr->c_namesize = short_hdr.c_namesize;
|
file_hdr->c_namesize = short_hdr->c_namesize;
|
||||||
file_hdr->c_filesize = (unsigned long) short_hdr.c_filesizes[0] << 16
|
file_hdr->c_filesize = (unsigned long) short_hdr->c_filesizes[0] << 16
|
||||||
| short_hdr.c_filesizes[1];
|
| short_hdr->c_filesizes[1];
|
||||||
|
|
||||||
/* Read file name from input. */
|
/* Read file name from input. */
|
||||||
if (file_hdr->c_name != NULL)
|
if (file_hdr->c_name != NULL)
|
||||||
@ -1342,15 +1352,18 @@ void
|
|||||||
process_copy_in ()
|
process_copy_in ()
|
||||||
{
|
{
|
||||||
char done = false; /* True if trailer reached. */
|
char done = false; /* True if trailer reached. */
|
||||||
FILE *tty_in; /* Interactive file for rename option. */
|
FILE *tty_in = NULL; /* Interactive file for rename option. */
|
||||||
FILE *tty_out; /* Interactive file for rename option. */
|
FILE *tty_out = NULL; /* Interactive file for rename option. */
|
||||||
FILE *rename_in; /* Batch file for rename option. */
|
FILE *rename_in = NULL; /* Batch file for rename option. */
|
||||||
struct stat file_stat; /* Output file stat record. */
|
struct stat file_stat; /* Output file stat record. */
|
||||||
struct new_cpio_header file_hdr; /* Output header information. */
|
struct cpio_file_stat file_hdr; /* Output header information. */
|
||||||
int in_file_des; /* Input file descriptor. */
|
int in_file_des; /* Input file descriptor. */
|
||||||
char skip_file; /* Flag for use with patterns. */
|
char skip_file; /* Flag for use with patterns. */
|
||||||
int i; /* Loop index variable. */
|
int i; /* Loop index variable. */
|
||||||
|
|
||||||
|
umask (0); /* Reset umask to preserve modes of
|
||||||
|
created files */
|
||||||
|
|
||||||
/* Initialize the copy in. */
|
/* Initialize the copy in. */
|
||||||
if (pattern_file_name)
|
if (pattern_file_name)
|
||||||
{
|
{
|
||||||
@ -1418,7 +1431,7 @@ process_copy_in ()
|
|||||||
#ifdef DEBUG_CPIO
|
#ifdef DEBUG_CPIO
|
||||||
if (debug_flag)
|
if (debug_flag)
|
||||||
{
|
{
|
||||||
struct new_cpio_header *h;
|
struct cpio_file_stat *h;
|
||||||
h = &file_hdr;
|
h = &file_hdr;
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"magic = 0%o, ino = %d, mode = 0%o, uid = %d, gid = %d\n",
|
"magic = 0%o, ino = %d, mode = 0%o, uid = %d, gid = %d\n",
|
||||||
@ -1437,37 +1450,15 @@ process_copy_in ()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Is this the header for the TRAILER file? */
|
/* Is this the header for the TRAILER file? */
|
||||||
if (strcmp ("TRAILER!!!", file_hdr.c_name) == 0)
|
if (strcmp (CPIO_TRAILER_NAME, file_hdr.c_name) == 0)
|
||||||
{
|
{
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do we have to ignore absolute paths, and if so, does the filename
|
cpio_safer_name_suffix (file_hdr.c_name, false, !no_abs_paths_flag,
|
||||||
have an absolute path? */
|
false);
|
||||||
if (no_abs_paths_flag && file_hdr.c_name && file_hdr.c_name [0] == '/')
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
p = file_hdr.c_name;
|
|
||||||
while (*p == '/')
|
|
||||||
++p;
|
|
||||||
if (*p == '\0')
|
|
||||||
{
|
|
||||||
strcpy (file_hdr.c_name, ".");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Debian hack: file_hrd.c_name is sometimes set to
|
|
||||||
point to static memory by code in tar.c. This
|
|
||||||
causes a segfault. Therefore, memmove is used
|
|
||||||
instead of freeing and reallocating. (Reported by
|
|
||||||
Horst Knobloch.) This bug has been reported to
|
|
||||||
"bug-gnu-utils@prep.ai.mit.edu". (99/1/6) -BEM */
|
|
||||||
(void)memmove (file_hdr.c_name, p, (size_t)(strlen (p) + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Does the file name match one of the given patterns? */
|
/* Does the file name match one of the given patterns? */
|
||||||
if (num_patterns <= 0)
|
if (num_patterns <= 0)
|
||||||
skip_file = false;
|
skip_file = false;
|
||||||
@ -1530,7 +1521,7 @@ process_copy_in ()
|
|||||||
tape_skip_padding (in_file_des, file_hdr.c_filesize);
|
tape_skip_padding (in_file_des, file_hdr.c_filesize);
|
||||||
if (crc != file_hdr.c_chksum)
|
if (crc != file_hdr.c_chksum)
|
||||||
{
|
{
|
||||||
error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"),
|
error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"),
|
||||||
file_hdr.c_name, crc, file_hdr.c_chksum);
|
file_hdr.c_name, crc, file_hdr.c_chksum);
|
||||||
}
|
}
|
||||||
/* Debian hack: -v and -V now work with --only-verify-crc.
|
/* Debian hack: -v and -V now work with --only-verify-crc.
|
||||||
|
672
src/copyout.c
672
src/copyout.c
@ -1,5 +1,6 @@
|
|||||||
/* copyout.c - create a cpio archive
|
/* copyout.c - create a cpio archive
|
||||||
Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004 Free Software Foundation, Inc.
|
Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004,
|
||||||
|
2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -11,9 +12,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
#include <system.h>
|
#include <system.h>
|
||||||
|
|
||||||
@ -26,14 +28,15 @@
|
|||||||
#include "extern.h"
|
#include "extern.h"
|
||||||
#include "defer.h"
|
#include "defer.h"
|
||||||
#include <rmt.h>
|
#include <rmt.h>
|
||||||
|
#include <paxlib.h>
|
||||||
|
|
||||||
/* Read FILE_SIZE bytes of FILE_NAME from IN_FILE_DES and
|
/* Read FILE_SIZE bytes of FILE_NAME from IN_FILE_DES and
|
||||||
compute and return a checksum for them. */
|
compute and return a checksum for them. */
|
||||||
|
|
||||||
static unsigned long
|
static unsigned int
|
||||||
read_for_checksum (int in_file_des, int file_size, char *file_name)
|
read_for_checksum (int in_file_des, int file_size, char *file_name)
|
||||||
{
|
{
|
||||||
unsigned long crc;
|
unsigned int crc;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
int bytes_left;
|
int bytes_left;
|
||||||
int bytes_read;
|
int bytes_read;
|
||||||
@ -65,13 +68,8 @@ read_for_checksum (int in_file_des, int file_size, char *file_name)
|
|||||||
static void
|
static void
|
||||||
tape_clear_rest_of_block (int out_file_des)
|
tape_clear_rest_of_block (int out_file_des)
|
||||||
{
|
{
|
||||||
while (output_size < io_block_size)
|
write_nuls_to_file (io_block_size - output_size, out_file_des,
|
||||||
{
|
tape_buffered_write);
|
||||||
if ((io_block_size - output_size) > 512)
|
|
||||||
tape_buffered_write (zeros_512, out_file_des, 512);
|
|
||||||
else
|
|
||||||
tape_buffered_write (zeros_512, out_file_des, io_block_size - output_size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write NULs on OUT_FILE_DES to move from OFFSET (the current location)
|
/* Write NULs on OUT_FILE_DES to move from OFFSET (the current location)
|
||||||
@ -80,7 +78,7 @@ tape_clear_rest_of_block (int out_file_des)
|
|||||||
static void
|
static void
|
||||||
tape_pad_output (int out_file_des, int offset)
|
tape_pad_output (int out_file_des, int offset)
|
||||||
{
|
{
|
||||||
int pad;
|
size_t pad;
|
||||||
|
|
||||||
if (archive_format == arf_newascii || archive_format == arf_crcascii)
|
if (archive_format == arf_newascii || archive_format == arf_crcascii)
|
||||||
pad = (4 - (offset % 4)) % 4;
|
pad = (4 - (offset % 4)) % 4;
|
||||||
@ -92,7 +90,7 @@ tape_pad_output (int out_file_des, int offset)
|
|||||||
pad = 0;
|
pad = 0;
|
||||||
|
|
||||||
if (pad != 0)
|
if (pad != 0)
|
||||||
tape_buffered_write (zeros_512, out_file_des, pad);
|
write_nuls_to_file (pad, out_file_des, tape_buffered_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -109,7 +107,7 @@ struct deferment *deferouts = NULL;
|
|||||||
already been defered. */
|
already been defered. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
count_defered_links_to_dev_ino (struct new_cpio_header *file_hdr)
|
count_defered_links_to_dev_ino (struct cpio_file_stat *file_hdr)
|
||||||
{
|
{
|
||||||
struct deferment *d;
|
struct deferment *d;
|
||||||
int ino;
|
int ino;
|
||||||
@ -133,7 +131,7 @@ count_defered_links_to_dev_ino (struct new_cpio_header *file_hdr)
|
|||||||
we already seen and defered all of the other links? */
|
we already seen and defered all of the other links? */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
last_link (struct new_cpio_header *file_hdr)
|
last_link (struct cpio_file_stat *file_hdr)
|
||||||
{
|
{
|
||||||
int other_files_sofar;
|
int other_files_sofar;
|
||||||
|
|
||||||
@ -150,7 +148,7 @@ last_link (struct new_cpio_header *file_hdr)
|
|||||||
list. */
|
list. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_link_defer (struct new_cpio_header *file_hdr)
|
add_link_defer (struct cpio_file_stat *file_hdr)
|
||||||
{
|
{
|
||||||
struct deferment *d;
|
struct deferment *d;
|
||||||
d = create_deferment (file_hdr);
|
d = create_deferment (file_hdr);
|
||||||
@ -159,13 +157,13 @@ add_link_defer (struct new_cpio_header *file_hdr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We are about to put a file into a newc or crc archive that is
|
/* We are about to put a file into a newc or crc archive that is
|
||||||
multiply linked. We have already seen and defered all of the
|
multiply linked. We have already seen and deferred all of the
|
||||||
other links to the file but haven't written them into the archive.
|
other links to the file but haven't written them into the archive.
|
||||||
Write the other links into the archive, and remove them from the
|
Write the other links into the archive, and remove them from the
|
||||||
deferouts list. */
|
deferouts list. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
writeout_other_defers (struct new_cpio_header *file_hdr, int out_des)
|
writeout_other_defers (struct cpio_file_stat *file_hdr, int out_des)
|
||||||
{
|
{
|
||||||
struct deferment *d;
|
struct deferment *d;
|
||||||
struct deferment *d_prev;
|
struct deferment *d_prev;
|
||||||
@ -207,13 +205,10 @@ writeout_other_defers (struct new_cpio_header *file_hdr, int out_des)
|
|||||||
for writeout_final_defers() to call. */
|
for writeout_final_defers() to call. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
writeout_defered_file (struct new_cpio_header *header, int out_file_des)
|
writeout_defered_file (struct cpio_file_stat *header, int out_file_des)
|
||||||
{
|
{
|
||||||
int in_file_des;
|
int in_file_des;
|
||||||
struct new_cpio_header file_hdr;
|
struct cpio_file_stat file_hdr;
|
||||||
struct utimbuf times; /* For setting file times. */
|
|
||||||
/* Initialize this in case it has members we don't know to set. */
|
|
||||||
bzero (×, sizeof (struct utimbuf));
|
|
||||||
|
|
||||||
file_hdr = *header;
|
file_hdr = *header;
|
||||||
|
|
||||||
@ -222,7 +217,7 @@ writeout_defered_file (struct new_cpio_header *header, int out_file_des)
|
|||||||
O_RDONLY | O_BINARY, 0);
|
O_RDONLY | O_BINARY, 0);
|
||||||
if (in_file_des < 0)
|
if (in_file_des < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", header->c_name);
|
open_error (header->c_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,8 +226,10 @@ writeout_defered_file (struct new_cpio_header *header, int out_file_des)
|
|||||||
file_hdr.c_filesize,
|
file_hdr.c_filesize,
|
||||||
header->c_name);
|
header->c_name);
|
||||||
|
|
||||||
write_out_header (&file_hdr, out_file_des);
|
if (write_out_header (&file_hdr, out_file_des))
|
||||||
copy_files_disk_to_tape (in_file_des, out_file_des, file_hdr.c_filesize, header->c_name);
|
return;
|
||||||
|
copy_files_disk_to_tape (in_file_des, out_file_des, file_hdr.c_filesize,
|
||||||
|
header->c_name);
|
||||||
warn_if_file_changed(header->c_name, file_hdr.c_filesize, file_hdr.c_mtime);
|
warn_if_file_changed(header->c_name, file_hdr.c_filesize, file_hdr.c_mtime);
|
||||||
|
|
||||||
if (archive_format == arf_tar || archive_format == arf_ustar)
|
if (archive_format == arf_tar || archive_format == arf_ustar)
|
||||||
@ -241,21 +238,11 @@ writeout_defered_file (struct new_cpio_header *header, int out_file_des)
|
|||||||
|
|
||||||
tape_pad_output (out_file_des, file_hdr.c_filesize);
|
tape_pad_output (out_file_des, file_hdr.c_filesize);
|
||||||
|
|
||||||
if (close (in_file_des) < 0)
|
|
||||||
error (0, errno, "%s", header->c_name);
|
|
||||||
if (reset_time_flag)
|
if (reset_time_flag)
|
||||||
{
|
set_file_times (in_file_des, file_hdr.c_name, file_hdr.c_mtime,
|
||||||
times.actime = file_hdr.c_mtime;
|
file_hdr.c_mtime);
|
||||||
times.modtime = file_hdr.c_mtime;
|
if (close (in_file_des) < 0)
|
||||||
/* Debian hack: Silently ignore EROFS because reading the file
|
close_error (header->c_name);
|
||||||
won't have upset its timestamp if it's on a read-only
|
|
||||||
filesystem. This has been submitted as a suggestion to
|
|
||||||
"bug-gnu-utils@prep.ai.mit.edu". -BEM */
|
|
||||||
if (utime (file_hdr.c_name, ×) < 0
|
|
||||||
&& errno != EROFS)
|
|
||||||
error (0, errno, "%s", file_hdr.c_name);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When writing newc and crc format archives we defer multiply linked
|
/* When writing newc and crc format archives we defer multiply linked
|
||||||
@ -279,7 +266,7 @@ writeout_final_defers (int out_des)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct new_cpio_header file_hdr;
|
struct cpio_file_stat file_hdr;
|
||||||
file_hdr = d->header;
|
file_hdr = d->header;
|
||||||
file_hdr.c_filesize = 0;
|
file_hdr.c_filesize = 0;
|
||||||
write_out_header (&file_hdr, out_des);
|
write_out_header (&file_hdr, out_des);
|
||||||
@ -288,154 +275,317 @@ writeout_final_defers (int out_des)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: to_ascii could be used instead of to_oct() and to_octal() from tar,
|
||||||
|
so it should be moved to paxutils too.
|
||||||
|
Allowed values for logbase are: 1 (binary), 2, 3 (octal), 4 (hex) */
|
||||||
|
int
|
||||||
|
to_ascii (char *where, uintmax_t v, size_t digits, unsigned logbase)
|
||||||
|
{
|
||||||
|
static char codetab[] = "0123456789ABCDEF";
|
||||||
|
int i = digits;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
where[--i] = codetab[(v & ((1 << logbase) - 1))];
|
||||||
|
v >>= logbase;
|
||||||
|
}
|
||||||
|
while (i);
|
||||||
|
|
||||||
|
return v != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
field_width_error (const char *filename, const char *fieldname)
|
||||||
|
{
|
||||||
|
error (0, 0, _("%s: field width not sufficient for storing %s"),
|
||||||
|
filename, fieldname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
field_width_warning (const char *filename, const char *fieldname)
|
||||||
|
{
|
||||||
|
if (warn_option & CPIO_WARN_TRUNCATE)
|
||||||
|
error (0, 0, _("%s: truncating %s"), filename, fieldname);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
to_ascii_or_warn (char *where, uintmax_t n, size_t digits,
|
||||||
|
unsigned logbase,
|
||||||
|
const char *filename, const char *fieldname)
|
||||||
|
{
|
||||||
|
if (to_ascii (where, n, digits, logbase))
|
||||||
|
field_width_warning (filename, fieldname);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
to_ascii_or_error (char *where, uintmax_t n, size_t digits,
|
||||||
|
unsigned logbase,
|
||||||
|
const char *filename, const char *fieldname)
|
||||||
|
{
|
||||||
|
if (to_ascii (where, n, digits, logbase))
|
||||||
|
{
|
||||||
|
field_width_error (filename, fieldname);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
write_out_new_ascii_header (const char *magic_string,
|
||||||
|
struct cpio_file_stat *file_hdr, int out_des)
|
||||||
|
{
|
||||||
|
char ascii_header[110];
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = stpcpy (ascii_header, magic_string);
|
||||||
|
to_ascii_or_warn (p, file_hdr->c_ino, 8, LG_16,
|
||||||
|
file_hdr->c_name, _("inode number"));
|
||||||
|
p += 8;
|
||||||
|
to_ascii_or_warn (p, file_hdr->c_mode, 8, LG_16, file_hdr->c_name,
|
||||||
|
_("file mode"));
|
||||||
|
p += 8;
|
||||||
|
to_ascii_or_warn (p, file_hdr->c_uid, 8, LG_16, file_hdr->c_name,
|
||||||
|
_("uid"));
|
||||||
|
p += 8;
|
||||||
|
to_ascii_or_warn (p, file_hdr->c_gid, 8, LG_16, file_hdr->c_name,
|
||||||
|
_("gid"));
|
||||||
|
p += 8;
|
||||||
|
to_ascii_or_warn (p, file_hdr->c_nlink, 8, LG_16, file_hdr->c_name,
|
||||||
|
_("number of links"));
|
||||||
|
p += 8;
|
||||||
|
to_ascii_or_warn (p, file_hdr->c_mtime, 8, LG_16, file_hdr->c_name,
|
||||||
|
_("modification time"));
|
||||||
|
p += 8;
|
||||||
|
if (to_ascii_or_error (p, file_hdr->c_filesize, 8, LG_16, file_hdr->c_name,
|
||||||
|
_("file size")))
|
||||||
|
return 1;
|
||||||
|
p += 8;
|
||||||
|
if (to_ascii_or_error (p, file_hdr->c_dev_maj, 8, LG_16, file_hdr->c_name,
|
||||||
|
_("device major number")))
|
||||||
|
return 1;
|
||||||
|
p += 8;
|
||||||
|
if (to_ascii_or_error (p, file_hdr->c_dev_min, 8, LG_16, file_hdr->c_name,
|
||||||
|
_("device minor number")))
|
||||||
|
return 1;
|
||||||
|
p += 8;
|
||||||
|
if (to_ascii_or_error (p, file_hdr->c_rdev_maj, 8, LG_16, file_hdr->c_name,
|
||||||
|
_("rdev major")))
|
||||||
|
return 1;
|
||||||
|
p += 8;
|
||||||
|
if (to_ascii_or_error (p, file_hdr->c_rdev_min, 8, LG_16, file_hdr->c_name,
|
||||||
|
_("rdev minor")))
|
||||||
|
return 1;
|
||||||
|
p += 8;
|
||||||
|
if (to_ascii_or_error (p, file_hdr->c_namesize, 8, LG_16, file_hdr->c_name,
|
||||||
|
_("name size")))
|
||||||
|
return 1;
|
||||||
|
p += 8;
|
||||||
|
to_ascii (p, file_hdr->c_chksum & 0xffffffff, 8, LG_16);
|
||||||
|
|
||||||
|
tape_buffered_write (ascii_header, out_des, sizeof ascii_header);
|
||||||
|
|
||||||
|
/* Write file name to output. */
|
||||||
|
tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
|
||||||
|
tape_pad_output (out_des, file_hdr->c_namesize + sizeof ascii_header);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
write_out_old_ascii_header (dev_t dev, dev_t rdev,
|
||||||
|
struct cpio_file_stat *file_hdr, int out_des)
|
||||||
|
{
|
||||||
|
char ascii_header[76];
|
||||||
|
char *p = ascii_header;
|
||||||
|
|
||||||
|
to_ascii (p, file_hdr->c_magic, 6, LG_8);
|
||||||
|
p += 6;
|
||||||
|
to_ascii_or_warn (p, dev, 6, LG_8, file_hdr->c_name, _("device number"));
|
||||||
|
p += 6;
|
||||||
|
to_ascii_or_warn (p, file_hdr->c_ino, 6, LG_8, file_hdr->c_name,
|
||||||
|
_("inode number"));
|
||||||
|
p += 6;
|
||||||
|
to_ascii_or_warn (p, file_hdr->c_mode, 6, LG_8, file_hdr->c_name,
|
||||||
|
_("file mode"));
|
||||||
|
p += 6;
|
||||||
|
to_ascii_or_warn (p, file_hdr->c_uid, 6, LG_8, file_hdr->c_name, _("uid"));
|
||||||
|
p += 6;
|
||||||
|
to_ascii_or_warn (p, file_hdr->c_gid, 6, LG_8, file_hdr->c_name, _("gid"));
|
||||||
|
p += 6;
|
||||||
|
to_ascii_or_warn (p, file_hdr->c_nlink, 6, LG_8, file_hdr->c_name,
|
||||||
|
_("number of links"));
|
||||||
|
p += 6;
|
||||||
|
to_ascii_or_warn (p, rdev, 6, LG_8, file_hdr->c_name, _("rdev"));
|
||||||
|
p += 6;
|
||||||
|
to_ascii_or_warn (p, file_hdr->c_mtime, 11, LG_8, file_hdr->c_name,
|
||||||
|
_("modification time"));
|
||||||
|
p += 11;
|
||||||
|
if (to_ascii_or_error (p, file_hdr->c_namesize, 6, LG_8, file_hdr->c_name,
|
||||||
|
_("name size")))
|
||||||
|
return 1;
|
||||||
|
p += 6;
|
||||||
|
if (to_ascii_or_error (p, file_hdr->c_filesize, 11, LG_8, file_hdr->c_name,
|
||||||
|
_("file size")))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
tape_buffered_write (ascii_header, out_des, sizeof ascii_header);
|
||||||
|
|
||||||
|
/* Write file name to output. */
|
||||||
|
tape_buffered_write (file_hdr->c_name, out_des, file_hdr->c_namesize);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hp_compute_dev (struct cpio_file_stat *file_hdr, dev_t *pdev, dev_t *prdev)
|
||||||
|
{
|
||||||
|
/* HP/UX cpio creates archives that look just like ordinary archives,
|
||||||
|
but for devices it sets major = 0, minor = 1, and puts the
|
||||||
|
actual major/minor number in the filesize field. */
|
||||||
|
switch (file_hdr->c_mode & CP_IFMT)
|
||||||
|
{
|
||||||
|
case CP_IFCHR:
|
||||||
|
case CP_IFBLK:
|
||||||
|
#ifdef CP_IFSOCK
|
||||||
|
case CP_IFSOCK:
|
||||||
|
#endif
|
||||||
|
#ifdef CP_IFIFO
|
||||||
|
case CP_IFIFO:
|
||||||
|
#endif
|
||||||
|
file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
|
||||||
|
file_hdr->c_rdev_min);
|
||||||
|
*pdev = *prdev = makedev (0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
*pdev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
|
||||||
|
*prdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
write_out_binary_header (dev_t rdev,
|
||||||
|
struct cpio_file_stat *file_hdr, int out_des)
|
||||||
|
{
|
||||||
|
struct old_cpio_header short_hdr;
|
||||||
|
|
||||||
|
short_hdr.c_magic = 070707;
|
||||||
|
short_hdr.c_dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
|
||||||
|
|
||||||
|
if ((warn_option & CPIO_WARN_TRUNCATE) && (file_hdr->c_ino >> 16) != 0)
|
||||||
|
error (0, 0, _("%s: truncating inode number"), file_hdr->c_name);
|
||||||
|
|
||||||
|
short_hdr.c_ino = file_hdr->c_ino & 0xFFFF;
|
||||||
|
if (short_hdr.c_ino != file_hdr->c_ino)
|
||||||
|
field_width_warning (file_hdr->c_name, _("inode number"));
|
||||||
|
|
||||||
|
short_hdr.c_mode = file_hdr->c_mode & 0xFFFF;
|
||||||
|
if (short_hdr.c_mode != file_hdr->c_mode)
|
||||||
|
field_width_warning (file_hdr->c_name, _("file mode"));
|
||||||
|
|
||||||
|
short_hdr.c_uid = file_hdr->c_uid & 0xFFFF;
|
||||||
|
if (short_hdr.c_uid != file_hdr->c_uid)
|
||||||
|
field_width_warning (file_hdr->c_name, _("uid"));
|
||||||
|
|
||||||
|
short_hdr.c_gid = file_hdr->c_gid & 0xFFFF;
|
||||||
|
if (short_hdr.c_gid != file_hdr->c_gid)
|
||||||
|
field_width_warning (file_hdr->c_name, _("gid"));
|
||||||
|
|
||||||
|
short_hdr.c_nlink = file_hdr->c_nlink & 0xFFFF;
|
||||||
|
if (short_hdr.c_nlink != file_hdr->c_nlink)
|
||||||
|
field_width_warning (file_hdr->c_name, _("number of links"));
|
||||||
|
|
||||||
|
short_hdr.c_rdev = rdev;
|
||||||
|
short_hdr.c_mtimes[0] = file_hdr->c_mtime >> 16;
|
||||||
|
short_hdr.c_mtimes[1] = file_hdr->c_mtime & 0xFFFF;
|
||||||
|
|
||||||
|
short_hdr.c_namesize = file_hdr->c_namesize & 0xFFFF;
|
||||||
|
if (short_hdr.c_namesize != file_hdr->c_namesize)
|
||||||
|
{
|
||||||
|
field_width_error (file_hdr->c_name, _("name size"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
short_hdr.c_filesizes[0] = file_hdr->c_filesize >> 16;
|
||||||
|
short_hdr.c_filesizes[1] = file_hdr->c_filesize & 0xFFFF;
|
||||||
|
|
||||||
|
if (((off_t)short_hdr.c_filesizes[0] << 16) + short_hdr.c_filesizes[1]
|
||||||
|
!= file_hdr->c_filesize)
|
||||||
|
{
|
||||||
|
field_width_error (file_hdr->c_name, _("file size"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output the file header. */
|
||||||
|
tape_buffered_write ((char *) &short_hdr, out_des, 26);
|
||||||
|
|
||||||
|
/* Write file name to output. */
|
||||||
|
tape_buffered_write (file_hdr->c_name, out_des, file_hdr->c_namesize);
|
||||||
|
|
||||||
|
tape_pad_output (out_des, file_hdr->c_namesize + 26);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Write out header FILE_HDR, including the file name, to file
|
/* Write out header FILE_HDR, including the file name, to file
|
||||||
descriptor OUT_DES. */
|
descriptor OUT_DES. */
|
||||||
|
|
||||||
void
|
int
|
||||||
write_out_header (struct new_cpio_header *file_hdr, int out_des)
|
write_out_header (struct cpio_file_stat *file_hdr, int out_des)
|
||||||
{
|
{
|
||||||
if (archive_format == arf_newascii || archive_format == arf_crcascii)
|
dev_t dev;
|
||||||
|
dev_t rdev;
|
||||||
|
|
||||||
|
switch (archive_format)
|
||||||
{
|
{
|
||||||
char ascii_header[112];
|
case arf_newascii:
|
||||||
char *magic_string;
|
return write_out_new_ascii_header ("070701", file_hdr, out_des);
|
||||||
|
|
||||||
if (archive_format == arf_crcascii)
|
case arf_crcascii:
|
||||||
magic_string = "070702";
|
return write_out_new_ascii_header ("070702", file_hdr, out_des);
|
||||||
else
|
|
||||||
magic_string = "070701";
|
case arf_oldascii:
|
||||||
sprintf (ascii_header,
|
return write_out_old_ascii_header (makedev (file_hdr->c_dev_maj,
|
||||||
"%6s%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx",
|
file_hdr->c_dev_min),
|
||||||
magic_string,
|
makedev (file_hdr->c_rdev_maj,
|
||||||
file_hdr->c_ino, file_hdr->c_mode, file_hdr->c_uid,
|
file_hdr->c_rdev_min),
|
||||||
file_hdr->c_gid, file_hdr->c_nlink, file_hdr->c_mtime,
|
file_hdr, out_des);
|
||||||
file_hdr->c_filesize, file_hdr->c_dev_maj, file_hdr->c_dev_min,
|
|
||||||
file_hdr->c_rdev_maj, file_hdr->c_rdev_min, file_hdr->c_namesize,
|
case arf_hpoldascii:
|
||||||
file_hdr->c_chksum);
|
hp_compute_dev (file_hdr, &dev, &rdev);
|
||||||
tape_buffered_write (ascii_header, out_des, 110L);
|
return write_out_old_ascii_header (dev, rdev, file_hdr, out_des);
|
||||||
|
|
||||||
/* Write file name to output. */
|
case arf_tar:
|
||||||
tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
|
case arf_ustar:
|
||||||
tape_pad_output (out_des, file_hdr->c_namesize + 110);
|
if (is_tar_filename_too_long (file_hdr->c_name))
|
||||||
}
|
|
||||||
else if (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
|
|
||||||
{
|
|
||||||
char ascii_header[78];
|
|
||||||
dev_t dev;
|
|
||||||
dev_t rdev;
|
|
||||||
|
|
||||||
if (archive_format == arf_oldascii)
|
|
||||||
{
|
{
|
||||||
dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
|
error (0, 0, _("%s: file name too long"), file_hdr->c_name);
|
||||||
rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
|
return 1;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* HP/UX cpio creates archives that look just like ordinary archives,
|
|
||||||
but for devices it sets major = 0, minor = 1, and puts the
|
|
||||||
actual major/minor number in the filesize field. */
|
|
||||||
switch (file_hdr->c_mode & CP_IFMT)
|
|
||||||
{
|
|
||||||
case CP_IFCHR:
|
|
||||||
case CP_IFBLK:
|
|
||||||
#ifdef CP_IFSOCK
|
|
||||||
case CP_IFSOCK:
|
|
||||||
#endif
|
|
||||||
#ifdef CP_IFIFO
|
|
||||||
case CP_IFIFO:
|
|
||||||
#endif
|
|
||||||
file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
|
|
||||||
file_hdr->c_rdev_min);
|
|
||||||
rdev = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
|
|
||||||
rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
write_out_tar_header (file_hdr, out_des); /* FIXME: No error checking */
|
||||||
|
return 0;
|
||||||
|
|
||||||
if ((warn_option & CPIO_WARN_TRUNCATE) && (file_hdr->c_ino >> 16) != 0)
|
case arf_binary:
|
||||||
error (0, 0, _("%s: truncating inode number"), file_hdr->c_name);
|
return write_out_binary_header (makedev (file_hdr->c_rdev_maj,
|
||||||
|
file_hdr->c_rdev_min),
|
||||||
|
file_hdr, out_des);
|
||||||
|
|
||||||
/* Debian hack: The type of dev_t has changed in glibc. Fixed output
|
case arf_hpbinary:
|
||||||
to ensure that a long int is passed to sprintf. This has been
|
hp_compute_dev (file_hdr, &dev, &rdev);
|
||||||
reported to "bug-gnu-utils@prep.ai.mit.edu". (1998/5/26) -BEM */
|
/* FIXME: dev ignored. Should it be? */
|
||||||
sprintf (ascii_header,
|
return write_out_binary_header (rdev, file_hdr, out_des);
|
||||||
"%06ho%06lo%06lo%06lo%06lo%06lo%06lo%06lo%011lo%06lo%011lo",
|
|
||||||
file_hdr->c_magic & 0xFFFF, (long) dev & 0xFFFF,
|
|
||||||
file_hdr->c_ino & 0xFFFF, file_hdr->c_mode & 0xFFFF,
|
|
||||||
file_hdr->c_uid & 0xFFFF, file_hdr->c_gid & 0xFFFF,
|
|
||||||
file_hdr->c_nlink & 0xFFFF, (long) rdev & 0xFFFF,
|
|
||||||
file_hdr->c_mtime, file_hdr->c_namesize & 0xFFFF,
|
|
||||||
file_hdr->c_filesize);
|
|
||||||
tape_buffered_write (ascii_header, out_des, 76L);
|
|
||||||
|
|
||||||
/* Write file name to output. */
|
default:
|
||||||
tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
|
abort ();
|
||||||
}
|
}
|
||||||
else if (archive_format == arf_tar || archive_format == arf_ustar)
|
}
|
||||||
{
|
|
||||||
write_out_tar_header (file_hdr, out_des);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct old_cpio_header short_hdr;
|
|
||||||
|
|
||||||
short_hdr.c_magic = 070707;
|
static void
|
||||||
short_hdr.c_dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
|
assign_string (char **pvar, char *value)
|
||||||
|
{
|
||||||
if ((warn_option & CPIO_WARN_TRUNCATE) && (file_hdr->c_ino >> 16) != 0)
|
char *p = xrealloc (*pvar, strlen (value) + 1);
|
||||||
error (0, 0, _("%s: truncating inode number"), file_hdr->c_name);
|
strcpy (p, value);
|
||||||
|
*pvar = p;
|
||||||
short_hdr.c_ino = file_hdr->c_ino & 0xFFFF;
|
|
||||||
short_hdr.c_mode = file_hdr->c_mode & 0xFFFF;
|
|
||||||
short_hdr.c_uid = file_hdr->c_uid & 0xFFFF;
|
|
||||||
short_hdr.c_gid = file_hdr->c_gid & 0xFFFF;
|
|
||||||
short_hdr.c_nlink = file_hdr->c_nlink & 0xFFFF;
|
|
||||||
if (archive_format != arf_hpbinary)
|
|
||||||
short_hdr.c_rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (file_hdr->c_mode & CP_IFMT)
|
|
||||||
{
|
|
||||||
/* HP/UX cpio creates archives that look just like ordinary
|
|
||||||
archives, but for devices it sets major = 0, minor = 1, and
|
|
||||||
puts the actual major/minor number in the filesize field. */
|
|
||||||
case CP_IFCHR:
|
|
||||||
case CP_IFBLK:
|
|
||||||
#ifdef CP_IFSOCK
|
|
||||||
case CP_IFSOCK:
|
|
||||||
#endif
|
|
||||||
#ifdef CP_IFIFO
|
|
||||||
case CP_IFIFO:
|
|
||||||
#endif
|
|
||||||
file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
|
|
||||||
file_hdr->c_rdev_min);
|
|
||||||
short_hdr.c_rdev = makedev (0, 1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
short_hdr.c_rdev = makedev (file_hdr->c_rdev_maj,
|
|
||||||
file_hdr->c_rdev_min);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
short_hdr.c_mtimes[0] = file_hdr->c_mtime >> 16;
|
|
||||||
short_hdr.c_mtimes[1] = file_hdr->c_mtime & 0xFFFF;
|
|
||||||
|
|
||||||
short_hdr.c_namesize = file_hdr->c_namesize & 0xFFFF;
|
|
||||||
|
|
||||||
short_hdr.c_filesizes[0] = file_hdr->c_filesize >> 16;
|
|
||||||
short_hdr.c_filesizes[1] = file_hdr->c_filesize & 0xFFFF;
|
|
||||||
|
|
||||||
/* Output the file header. */
|
|
||||||
tape_buffered_write ((char *) &short_hdr, out_des, 26L);
|
|
||||||
|
|
||||||
/* Write file name to output. */
|
|
||||||
tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
|
|
||||||
|
|
||||||
tape_pad_output (out_des, file_hdr->c_namesize + 26);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a list of file names from the standard input
|
/* Read a list of file names from the standard input
|
||||||
@ -447,17 +597,14 @@ process_copy_out ()
|
|||||||
{
|
{
|
||||||
int res; /* Result of functions. */
|
int res; /* Result of functions. */
|
||||||
dynamic_string input_name; /* Name of file read from stdin. */
|
dynamic_string input_name; /* Name of file read from stdin. */
|
||||||
struct utimbuf times; /* For resetting file times after copy. */
|
|
||||||
struct stat file_stat; /* Stat record for file. */
|
struct stat file_stat; /* Stat record for file. */
|
||||||
struct new_cpio_header file_hdr; /* Output header information. */
|
struct cpio_file_stat file_hdr; /* Output header information. */
|
||||||
int in_file_des; /* Source file descriptor. */
|
int in_file_des; /* Source file descriptor. */
|
||||||
int out_file_des; /* Output file descriptor. */
|
int out_file_des; /* Output file descriptor. */
|
||||||
char *p;
|
char *orig_file_name = NULL;
|
||||||
|
|
||||||
/* Initialize the copy out. */
|
/* Initialize the copy out. */
|
||||||
ds_init (&input_name, 128);
|
ds_init (&input_name, 128);
|
||||||
/* Initialize this in case it has members we don't know to set. */
|
|
||||||
bzero (×, sizeof (struct utimbuf));
|
|
||||||
file_hdr.c_magic = 070707;
|
file_hdr.c_magic = 070707;
|
||||||
|
|
||||||
/* Check whether the output file might be a tape. */
|
/* Check whether the output file might be a tape. */
|
||||||
@ -497,55 +644,11 @@ process_copy_out ()
|
|||||||
|
|
||||||
/* Process next file. */
|
/* Process next file. */
|
||||||
if ((*xstat) (input_name.ds_string, &file_stat) < 0)
|
if ((*xstat) (input_name.ds_string, &file_stat) < 0)
|
||||||
error (0, errno, "%s", input_name.ds_string);
|
stat_error (input_name.ds_string);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Set values in output header. */
|
/* Set values in output header. */
|
||||||
file_hdr.c_dev_maj = major (file_stat.st_dev);
|
stat_to_cpio (&file_hdr, &file_stat);
|
||||||
file_hdr.c_dev_min = minor (file_stat.st_dev);
|
|
||||||
file_hdr.c_ino = file_stat.st_ino;
|
|
||||||
/* For POSIX systems that don't define the S_IF macros,
|
|
||||||
we can't assume that S_ISfoo means the standard Unix
|
|
||||||
S_IFfoo bit(s) are set. So do it manually, with a
|
|
||||||
different name. Bleah. */
|
|
||||||
file_hdr.c_mode = (file_stat.st_mode & 07777);
|
|
||||||
if (S_ISREG (file_stat.st_mode))
|
|
||||||
file_hdr.c_mode |= CP_IFREG;
|
|
||||||
else if (S_ISDIR (file_stat.st_mode))
|
|
||||||
file_hdr.c_mode |= CP_IFDIR;
|
|
||||||
#ifdef S_ISBLK
|
|
||||||
else if (S_ISBLK (file_stat.st_mode))
|
|
||||||
file_hdr.c_mode |= CP_IFBLK;
|
|
||||||
#endif
|
|
||||||
#ifdef S_ISCHR
|
|
||||||
else if (S_ISCHR (file_stat.st_mode))
|
|
||||||
file_hdr.c_mode |= CP_IFCHR;
|
|
||||||
#endif
|
|
||||||
#ifdef S_ISFIFO
|
|
||||||
else if (S_ISFIFO (file_stat.st_mode))
|
|
||||||
file_hdr.c_mode |= CP_IFIFO;
|
|
||||||
#endif
|
|
||||||
#ifdef S_ISLNK
|
|
||||||
else if (S_ISLNK (file_stat.st_mode))
|
|
||||||
file_hdr.c_mode |= CP_IFLNK;
|
|
||||||
#endif
|
|
||||||
#ifdef S_ISSOCK
|
|
||||||
else if (S_ISSOCK (file_stat.st_mode))
|
|
||||||
file_hdr.c_mode |= CP_IFSOCK;
|
|
||||||
#endif
|
|
||||||
#ifdef S_ISNWK
|
|
||||||
else if (S_ISNWK (file_stat.st_mode))
|
|
||||||
file_hdr.c_mode |= CP_IFNWK;
|
|
||||||
#endif
|
|
||||||
file_hdr.c_uid = file_stat.st_uid;
|
|
||||||
file_hdr.c_gid = file_stat.st_gid;
|
|
||||||
file_hdr.c_nlink = file_stat.st_nlink;
|
|
||||||
file_hdr.c_rdev_maj = major (file_stat.st_rdev);
|
|
||||||
file_hdr.c_rdev_min = minor (file_stat.st_rdev);
|
|
||||||
file_hdr.c_mtime = file_stat.st_mtime;
|
|
||||||
file_hdr.c_filesize = file_stat.st_size;
|
|
||||||
file_hdr.c_chksum = 0;
|
|
||||||
file_hdr.c_tar_linkname = NULL;
|
|
||||||
|
|
||||||
if (archive_format == arf_tar || archive_format == arf_ustar)
|
if (archive_format == arf_tar || archive_format == arf_ustar)
|
||||||
{
|
{
|
||||||
@ -562,17 +665,12 @@ process_copy_out ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Strip leading `./' from the filename. */
|
assign_string (&orig_file_name, input_name.ds_string);
|
||||||
p = input_name.ds_string;
|
cpio_safer_name_suffix (input_name.ds_string, false,
|
||||||
while (*p == '.' && *(p + 1) == '/')
|
!no_abs_paths_flag, true);
|
||||||
{
|
|
||||||
++p;
|
|
||||||
while (*p == '/')
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
#ifndef HPUX_CDF
|
#ifndef HPUX_CDF
|
||||||
file_hdr.c_name = p;
|
file_hdr.c_name = input_name.ds_string;
|
||||||
file_hdr.c_namesize = strlen (p) + 1;
|
file_hdr.c_namesize = strlen (input_name.ds_string) + 1;
|
||||||
#else
|
#else
|
||||||
if ( (archive_format != arf_tar) && (archive_format != arf_ustar) )
|
if ( (archive_format != arf_tar) && (archive_format != arf_ustar) )
|
||||||
{
|
{
|
||||||
@ -581,7 +679,7 @@ process_copy_out ()
|
|||||||
properly recreate the directory as hidden (in case the
|
properly recreate the directory as hidden (in case the
|
||||||
files of a directory go into the archive before the
|
files of a directory go into the archive before the
|
||||||
directory itself (e.g from "find ... -depth ... | cpio")). */
|
directory itself (e.g from "find ... -depth ... | cpio")). */
|
||||||
file_hdr.c_name = add_cdf_double_slashes (p);
|
file_hdr.c_name = add_cdf_double_slashes (input_name.ds_string);
|
||||||
file_hdr.c_namesize = strlen (file_hdr.c_name) + 1;
|
file_hdr.c_namesize = strlen (file_hdr.c_name) + 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -589,18 +687,11 @@ process_copy_out ()
|
|||||||
/* We don't mark CDF's in tar files. We assume the "hidden"
|
/* We don't mark CDF's in tar files. We assume the "hidden"
|
||||||
directory will always go into the archive before any of
|
directory will always go into the archive before any of
|
||||||
its files. */
|
its files. */
|
||||||
file_hdr.c_name = p;
|
file_hdr.c_name = input_name.ds_string;
|
||||||
file_hdr.c_namesize = strlen (p) + 1;
|
file_hdr.c_namesize = strlen (input_name.ds_string) + 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if ((archive_format == arf_tar || archive_format == arf_ustar)
|
|
||||||
&& is_tar_filename_too_long (file_hdr.c_name))
|
|
||||||
{
|
|
||||||
error (0, 0, _("%s: file name too long"),
|
|
||||||
file_hdr.c_name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy the named file to the output. */
|
/* Copy the named file to the output. */
|
||||||
switch (file_hdr.c_mode & CP_IFMT)
|
switch (file_hdr.c_mode & CP_IFMT)
|
||||||
{
|
{
|
||||||
@ -613,7 +704,8 @@ process_copy_out ()
|
|||||||
file_hdr.c_dev_min)))
|
file_hdr.c_dev_min)))
|
||||||
{
|
{
|
||||||
file_hdr.c_tar_linkname = otherfile;
|
file_hdr.c_tar_linkname = otherfile;
|
||||||
write_out_header (&file_hdr, out_file_des);
|
if (write_out_header (&file_hdr, out_file_des))
|
||||||
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -630,50 +722,45 @@ process_copy_out ()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in_file_des = open (input_name.ds_string,
|
in_file_des = open (orig_file_name,
|
||||||
O_RDONLY | O_BINARY, 0);
|
O_RDONLY | O_BINARY, 0);
|
||||||
if (in_file_des < 0)
|
if (in_file_des < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", input_name.ds_string);
|
open_error (orig_file_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (archive_format == arf_crcascii)
|
if (archive_format == arf_crcascii)
|
||||||
file_hdr.c_chksum = read_for_checksum (in_file_des,
|
file_hdr.c_chksum = read_for_checksum (in_file_des,
|
||||||
file_hdr.c_filesize,
|
file_hdr.c_filesize,
|
||||||
input_name.ds_string);
|
orig_file_name);
|
||||||
|
|
||||||
write_out_header (&file_hdr, out_file_des);
|
if (write_out_header (&file_hdr, out_file_des))
|
||||||
copy_files_disk_to_tape (in_file_des, out_file_des, file_hdr.c_filesize, input_name.ds_string);
|
continue;
|
||||||
warn_if_file_changed(input_name.ds_string, file_hdr.c_filesize,
|
copy_files_disk_to_tape (in_file_des,
|
||||||
|
out_file_des, file_hdr.c_filesize,
|
||||||
|
orig_file_name);
|
||||||
|
warn_if_file_changed(orig_file_name, file_hdr.c_filesize,
|
||||||
file_hdr.c_mtime);
|
file_hdr.c_mtime);
|
||||||
|
|
||||||
if (archive_format == arf_tar || archive_format == arf_ustar)
|
if (archive_format == arf_tar || archive_format == arf_ustar)
|
||||||
add_inode (file_hdr.c_ino, file_hdr.c_name, file_hdr.c_dev_maj,
|
add_inode (file_hdr.c_ino, orig_file_name, file_hdr.c_dev_maj,
|
||||||
file_hdr.c_dev_min);
|
file_hdr.c_dev_min);
|
||||||
|
|
||||||
tape_pad_output (out_file_des, file_hdr.c_filesize);
|
tape_pad_output (out_file_des, file_hdr.c_filesize);
|
||||||
|
|
||||||
if (close (in_file_des) < 0)
|
|
||||||
error (0, errno, "%s", input_name.ds_string);
|
|
||||||
if (reset_time_flag)
|
if (reset_time_flag)
|
||||||
{
|
set_file_times (in_file_des,
|
||||||
times.actime = file_stat.st_atime;
|
orig_file_name,
|
||||||
times.modtime = file_stat.st_mtime;
|
file_stat.st_atime, file_stat.st_mtime);
|
||||||
/* Debian hack: Silently ignore EROFS because
|
if (close (in_file_des) < 0)
|
||||||
reading the file won't have upset its timestamp
|
close_error (orig_file_name);
|
||||||
if it's on a read-only filesystem. This has been
|
|
||||||
submitted as a suggestion to
|
|
||||||
"bug-gnu-utils@prep.ai.mit.edu". -BEM */
|
|
||||||
if (utime (file_hdr.c_name, ×) < 0
|
|
||||||
&& errno != EROFS)
|
|
||||||
error (0, errno, "%s", file_hdr.c_name);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_IFDIR:
|
case CP_IFDIR:
|
||||||
file_hdr.c_filesize = 0;
|
file_hdr.c_filesize = 0;
|
||||||
write_out_header (&file_hdr, out_file_des);
|
if (write_out_header (&file_hdr, out_file_des))
|
||||||
|
continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_IFCHR:
|
case CP_IFCHR:
|
||||||
@ -687,7 +774,7 @@ process_copy_out ()
|
|||||||
if (archive_format == arf_tar)
|
if (archive_format == arf_tar)
|
||||||
{
|
{
|
||||||
error (0, 0, _("%s not dumped: not a regular file"),
|
error (0, 0, _("%s not dumped: not a regular file"),
|
||||||
file_hdr.c_name);
|
orig_file_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (archive_format == arf_ustar)
|
else if (archive_format == arf_ustar)
|
||||||
@ -702,14 +789,16 @@ process_copy_out ()
|
|||||||
file_hdr.c_mode = (file_stat.st_mode & 07777);
|
file_hdr.c_mode = (file_stat.st_mode & 07777);
|
||||||
file_hdr.c_mode |= CP_IFREG;
|
file_hdr.c_mode |= CP_IFREG;
|
||||||
file_hdr.c_tar_linkname = otherfile;
|
file_hdr.c_tar_linkname = otherfile;
|
||||||
write_out_header (&file_hdr, out_file_des);
|
if (write_out_header (&file_hdr, out_file_des))
|
||||||
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
add_inode (file_hdr.c_ino, file_hdr.c_name,
|
add_inode (file_hdr.c_ino, orig_file_name,
|
||||||
file_hdr.c_dev_maj, file_hdr.c_dev_min);
|
file_hdr.c_dev_maj, file_hdr.c_dev_min);
|
||||||
}
|
}
|
||||||
file_hdr.c_filesize = 0;
|
file_hdr.c_filesize = 0;
|
||||||
write_out_header (&file_hdr, out_file_des);
|
if (write_out_header (&file_hdr, out_file_des))
|
||||||
|
continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef CP_IFLNK
|
#ifdef CP_IFLNK
|
||||||
@ -718,14 +807,18 @@ process_copy_out ()
|
|||||||
char *link_name = (char *) xmalloc (file_stat.st_size + 1);
|
char *link_name = (char *) xmalloc (file_stat.st_size + 1);
|
||||||
int link_size;
|
int link_size;
|
||||||
|
|
||||||
link_size = readlink (input_name.ds_string, link_name,
|
link_size = readlink (orig_file_name, link_name,
|
||||||
file_stat.st_size);
|
file_stat.st_size);
|
||||||
if (link_size < 0)
|
if (link_size < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", input_name.ds_string);
|
readlink_warn (orig_file_name);
|
||||||
free (link_name);
|
free (link_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
link_name[link_size] = 0;
|
||||||
|
cpio_safer_name_suffix (link_name, false,
|
||||||
|
!no_abs_paths_flag, true);
|
||||||
|
link_size = strlen (link_name);
|
||||||
file_hdr.c_filesize = link_size;
|
file_hdr.c_filesize = link_size;
|
||||||
if (archive_format == arf_tar || archive_format == arf_ustar)
|
if (archive_format == arf_tar || archive_format == arf_ustar)
|
||||||
{
|
{
|
||||||
@ -738,12 +831,14 @@ process_copy_out ()
|
|||||||
{
|
{
|
||||||
link_name[link_size] = '\0';
|
link_name[link_size] = '\0';
|
||||||
file_hdr.c_tar_linkname = link_name;
|
file_hdr.c_tar_linkname = link_name;
|
||||||
write_out_header (&file_hdr, out_file_des);
|
if (write_out_header (&file_hdr, out_file_des))
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
write_out_header (&file_hdr, out_file_des);
|
if (write_out_header (&file_hdr, out_file_des))
|
||||||
|
continue;
|
||||||
tape_buffered_write (link_name, out_file_des, link_size);
|
tape_buffered_write (link_name, out_file_des, link_size);
|
||||||
tape_pad_output (out_file_des, link_size);
|
tape_pad_output (out_file_des, link_size);
|
||||||
}
|
}
|
||||||
@ -753,16 +848,18 @@ process_copy_out ()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error (0, 0, _("%s: unknown file type"), input_name.ds_string);
|
error (0, 0, _("%s: unknown file type"), orig_file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose_flag)
|
if (verbose_flag)
|
||||||
fprintf (stderr, "%s\n", input_name.ds_string);
|
fprintf (stderr, "%s\n", orig_file_name);
|
||||||
if (dot_flag)
|
if (dot_flag)
|
||||||
fputc ('.', stderr);
|
fputc ('.', stderr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free (orig_file_name);
|
||||||
|
|
||||||
writeout_final_defers(out_file_des);
|
writeout_final_defers(out_file_des);
|
||||||
/* The collection is complete; append the trailer. */
|
/* The collection is complete; append the trailer. */
|
||||||
file_hdr.c_ino = 0;
|
file_hdr.c_ino = 0;
|
||||||
@ -779,14 +876,11 @@ process_copy_out ()
|
|||||||
|
|
||||||
file_hdr.c_filesize = 0;
|
file_hdr.c_filesize = 0;
|
||||||
file_hdr.c_namesize = 11;
|
file_hdr.c_namesize = 11;
|
||||||
file_hdr.c_name = "TRAILER!!!";
|
file_hdr.c_name = CPIO_TRAILER_NAME;
|
||||||
if (archive_format != arf_tar && archive_format != arf_ustar)
|
if (archive_format != arf_tar && archive_format != arf_ustar)
|
||||||
write_out_header (&file_hdr, out_file_des);
|
write_out_header (&file_hdr, out_file_des);
|
||||||
else
|
else
|
||||||
{
|
write_nuls_to_file (1024, out_file_des, tape_buffered_write);
|
||||||
tape_buffered_write (zeros_512, out_file_des, 512);
|
|
||||||
tape_buffered_write (zeros_512, out_file_des, 512);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill up the output block. */
|
/* Fill up the output block. */
|
||||||
tape_clear_rest_of_block (out_file_des);
|
tape_clear_rest_of_block (out_file_des);
|
||||||
|
149
src/copypass.c
149
src/copypass.c
@ -1,5 +1,6 @@
|
|||||||
/* copypass.c - cpio copy pass sub-function.
|
/* copypass.c - cpio copy pass sub-function.
|
||||||
Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004 Free Software Foundation, Inc.
|
Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004,
|
||||||
|
2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -11,9 +12,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
#include <system.h>
|
#include <system.h>
|
||||||
|
|
||||||
@ -24,11 +26,23 @@
|
|||||||
#include "cpiohdr.h"
|
#include "cpiohdr.h"
|
||||||
#include "dstring.h"
|
#include "dstring.h"
|
||||||
#include "extern.h"
|
#include "extern.h"
|
||||||
|
#include "paxlib.h"
|
||||||
|
|
||||||
#ifndef HAVE_LCHOWN
|
#ifndef HAVE_LCHOWN
|
||||||
#define lchown chown
|
# define lchown chown
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* A wrapper around set_perms using another set of arguments */
|
||||||
|
static void
|
||||||
|
set_copypass_perms (int fd, const char *name, struct stat *st)
|
||||||
|
{
|
||||||
|
struct cpio_file_stat header;
|
||||||
|
header.c_name = name;
|
||||||
|
stat_to_cpio (&header, st);
|
||||||
|
set_perms (fd, &header);
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy files listed on the standard input into directory `directory_name'.
|
/* Copy files listed on the standard input into directory `directory_name'.
|
||||||
If `link_flag', link instead of copying. */
|
If `link_flag', link instead of copying. */
|
||||||
|
|
||||||
@ -40,7 +54,6 @@ process_copy_pass ()
|
|||||||
int dirname_len; /* Length of `directory_name'. */
|
int dirname_len; /* Length of `directory_name'. */
|
||||||
int res; /* Result of functions. */
|
int res; /* Result of functions. */
|
||||||
char *slash; /* For moving past slashes in input name. */
|
char *slash; /* For moving past slashes in input name. */
|
||||||
struct utimbuf times; /* For resetting file times after copy. */
|
|
||||||
struct stat in_file_stat; /* Stat record for input file. */
|
struct stat in_file_stat; /* Stat record for input file. */
|
||||||
struct stat out_file_stat; /* Stat record for output file. */
|
struct stat out_file_stat; /* Stat record for output file. */
|
||||||
int in_file_des; /* Input file descriptor. */
|
int in_file_des; /* Input file descriptor. */
|
||||||
@ -51,6 +64,9 @@ process_copy_pass ()
|
|||||||
int cdf_char;
|
int cdf_char;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
umask (0); /* Reset umask to preserve modes of
|
||||||
|
created files */
|
||||||
|
|
||||||
/* Initialize the copy pass. */
|
/* Initialize the copy pass. */
|
||||||
dirname_len = strlen (directory_name);
|
dirname_len = strlen (directory_name);
|
||||||
ds_init (&input_name, 128);
|
ds_init (&input_name, 128);
|
||||||
@ -58,8 +74,6 @@ process_copy_pass ()
|
|||||||
strcpy (output_name.ds_string, directory_name);
|
strcpy (output_name.ds_string, directory_name);
|
||||||
output_name.ds_string[dirname_len] = '/';
|
output_name.ds_string[dirname_len] = '/';
|
||||||
output_is_seekable = true;
|
output_is_seekable = true;
|
||||||
/* Initialize this in case it has members we don't know to set. */
|
|
||||||
bzero (×, sizeof (struct utimbuf));
|
|
||||||
|
|
||||||
/* Copy files with names read from stdin. */
|
/* Copy files with names read from stdin. */
|
||||||
while (ds_fgetstr (stdin, &input_name, name_end) != NULL)
|
while (ds_fgetstr (stdin, &input_name, name_end) != NULL)
|
||||||
@ -82,7 +96,7 @@ process_copy_pass ()
|
|||||||
|
|
||||||
if ((*xstat) (input_name.ds_string, &in_file_stat) < 0)
|
if ((*xstat) (input_name.ds_string, &in_file_stat) < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", input_name.ds_string);
|
stat_error (input_name.ds_string);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +164,7 @@ process_copy_pass ()
|
|||||||
O_RDONLY | O_BINARY, 0);
|
O_RDONLY | O_BINARY, 0);
|
||||||
if (in_file_des < 0)
|
if (in_file_des < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", input_name.ds_string);
|
open_error (input_name.ds_string);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
out_file_des = open (output_name.ds_string,
|
out_file_des = open (output_name.ds_string,
|
||||||
@ -163,7 +177,7 @@ process_copy_pass ()
|
|||||||
}
|
}
|
||||||
if (out_file_des < 0)
|
if (out_file_des < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
open_error (output_name.ds_string);
|
||||||
close (in_file_des);
|
close (in_file_des);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -179,43 +193,28 @@ process_copy_pass ()
|
|||||||
write (out_file_des, "", 1);
|
write (out_file_des, "", 1);
|
||||||
delayed_seek_count = 0;
|
delayed_seek_count = 0;
|
||||||
}
|
}
|
||||||
if (close (in_file_des) < 0)
|
|
||||||
error (0, errno, "%s", input_name.ds_string);
|
|
||||||
if (close (out_file_des) < 0)
|
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
|
||||||
|
|
||||||
/* Set the attributes of the new file. */
|
set_copypass_perms (out_file_des,
|
||||||
if (!no_chown_flag)
|
output_name.ds_string, &in_file_stat);
|
||||||
if ((chown (output_name.ds_string,
|
|
||||||
set_owner_flag ? set_owner : in_file_stat.st_uid,
|
|
||||||
set_group_flag ? set_group : in_file_stat.st_gid) < 0)
|
|
||||||
&& errno != EPERM)
|
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
|
||||||
/* chown may have turned off some permissions we wanted. */
|
|
||||||
if (chmod (output_name.ds_string, in_file_stat.st_mode) < 0)
|
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
|
||||||
if (reset_time_flag)
|
if (reset_time_flag)
|
||||||
{
|
{
|
||||||
times.actime = in_file_stat.st_atime;
|
set_file_times (in_file_des,
|
||||||
times.modtime = in_file_stat.st_mtime;
|
input_name.ds_string,
|
||||||
/* Debian hack: Silently ignore EROFS because
|
in_file_stat.st_atime,
|
||||||
reading the file won't have upset its timestamp
|
in_file_stat.st_mtime);
|
||||||
if it's on a read-only filesystem. This has been
|
set_file_times (out_file_des,
|
||||||
submitted as a suggestion to
|
output_name.ds_string,
|
||||||
"bug-gnu-utils@prep.ai.mit.edu". -BEM */
|
in_file_stat.st_atime,
|
||||||
if (utime (input_name.ds_string, ×) < 0
|
in_file_stat.st_mtime);
|
||||||
&& errno != EROFS)
|
}
|
||||||
error (0, errno, "%s", input_name.ds_string);
|
|
||||||
if (utime (output_name.ds_string, ×) < 0
|
if (close (in_file_des) < 0)
|
||||||
&& errno != EROFS)
|
close_error (input_name.ds_string);
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
|
||||||
}
|
if (close (out_file_des) < 0)
|
||||||
if (retain_time_flag)
|
close_error (output_name.ds_string);
|
||||||
{
|
|
||||||
times.actime = times.modtime = in_file_stat.st_mtime;
|
|
||||||
if (utime (output_name.ds_string, ×) < 0)
|
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
|
||||||
}
|
|
||||||
warn_if_file_changed(input_name.ds_string, in_file_stat.st_size,
|
warn_if_file_changed(input_name.ds_string, in_file_stat.st_size,
|
||||||
in_file_stat.st_mtime);
|
in_file_stat.st_mtime);
|
||||||
}
|
}
|
||||||
@ -261,31 +260,11 @@ process_copy_pass ()
|
|||||||
(lstat (output_name.ds_string, &out_file_stat) != 0) ||
|
(lstat (output_name.ds_string, &out_file_stat) != 0) ||
|
||||||
!(S_ISDIR (out_file_stat.st_mode) ) )
|
!(S_ISDIR (out_file_stat.st_mode) ) )
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
stat_error (output_name.ds_string);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!no_chown_flag)
|
set_copypass_perms (-1, output_name.ds_string, &in_file_stat);
|
||||||
if ((chown (output_name.ds_string,
|
|
||||||
set_owner_flag ? set_owner : in_file_stat.st_uid,
|
|
||||||
set_group_flag ? set_group : in_file_stat.st_gid) < 0)
|
|
||||||
&& errno != EPERM)
|
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
|
||||||
/* chown may have turned off some permissions we wanted. */
|
|
||||||
if (chmod (output_name.ds_string, in_file_stat.st_mode) < 0)
|
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
|
||||||
#ifdef HPUX_CDF
|
|
||||||
if (cdf_flag)
|
|
||||||
/* Once we "hide" the directory with the chmod(),
|
|
||||||
we have to refer to it using name+ isntead of name. */
|
|
||||||
output_name.ds_string [cdf_char] = '+';
|
|
||||||
#endif
|
|
||||||
if (retain_time_flag)
|
|
||||||
{
|
|
||||||
times.actime = times.modtime = in_file_stat.st_mtime;
|
|
||||||
if (utime (output_name.ds_string, ×) < 0)
|
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (S_ISCHR (in_file_stat.st_mode) ||
|
else if (S_ISCHR (in_file_stat.st_mode) ||
|
||||||
S_ISBLK (in_file_stat.st_mode) ||
|
S_ISBLK (in_file_stat.st_mode) ||
|
||||||
@ -321,24 +300,10 @@ process_copy_pass ()
|
|||||||
}
|
}
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
mknod_error (output_name.ds_string);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!no_chown_flag)
|
set_copypass_perms (-1, output_name.ds_string, &in_file_stat);
|
||||||
if ((chown (output_name.ds_string,
|
|
||||||
set_owner_flag ? set_owner : in_file_stat.st_uid,
|
|
||||||
set_group_flag ? set_group : in_file_stat.st_gid) < 0)
|
|
||||||
&& errno != EPERM)
|
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
|
||||||
/* chown may have turned off some permissions we wanted. */
|
|
||||||
if (chmod (output_name.ds_string, in_file_stat.st_mode) < 0)
|
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
|
||||||
if (retain_time_flag)
|
|
||||||
{
|
|
||||||
times.actime = times.modtime = in_file_stat.st_mtime;
|
|
||||||
if (utime (output_name.ds_string, ×) < 0)
|
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,7 +318,7 @@ process_copy_pass ()
|
|||||||
in_file_stat.st_size);
|
in_file_stat.st_size);
|
||||||
if (link_size < 0)
|
if (link_size < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", input_name.ds_string);
|
readlink_error (input_name.ds_string);
|
||||||
free (link_name);
|
free (link_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -369,18 +334,20 @@ process_copy_pass ()
|
|||||||
}
|
}
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
symlink_error (output_name.ds_string, link_name);
|
||||||
free (link_name);
|
free (link_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the attributes of the new link. */
|
/* Set the attributes of the new link. */
|
||||||
if (!no_chown_flag)
|
if (!no_chown_flag)
|
||||||
if ((lchown (output_name.ds_string,
|
{
|
||||||
set_owner_flag ? set_owner : in_file_stat.st_uid,
|
uid_t uid = set_owner_flag ? set_owner : in_file_stat.st_uid;
|
||||||
set_group_flag ? set_group : in_file_stat.st_gid) < 0)
|
gid_t gid = set_group_flag ? set_group : in_file_stat.st_gid;
|
||||||
&& errno != EPERM)
|
if ((lchown (output_name.ds_string, uid, gid) < 0)
|
||||||
error (0, errno, "%s", output_name.ds_string);
|
&& errno != EPERM)
|
||||||
|
chown_error_details (output_name.ds_string, uid, gid);
|
||||||
|
}
|
||||||
free (link_name);
|
free (link_name);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
11
src/cpio.h
11
src/cpio.h
@ -1,5 +1,5 @@
|
|||||||
/* Extended cpio format from POSIX.1.
|
/* Extended cpio format from POSIX.1.
|
||||||
Copyright (C) 1992 Free Software Foundation, Inc.
|
Copyright (C) 1992, 2005 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -11,9 +11,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
#ifndef _CPIO_H
|
#ifndef _CPIO_H
|
||||||
|
|
||||||
@ -25,6 +26,8 @@
|
|||||||
and variable length file data.
|
and variable length file data.
|
||||||
A header for a filename "TRAILER!!!" indicates the end of the archive. */
|
A header for a filename "TRAILER!!!" indicates the end of the archive. */
|
||||||
|
|
||||||
|
#define CPIO_TRAILER_NAME "TRAILER!!!"
|
||||||
|
|
||||||
/* All the fields in the header are ISO 646 (approximately ASCII) strings
|
/* All the fields in the header are ISO 646 (approximately ASCII) strings
|
||||||
of octal numbers, left padded, not NUL terminated.
|
of octal numbers, left padded, not NUL terminated.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Extended cpio header from POSIX.1.
|
/* Extended cpio header from POSIX.1.
|
||||||
Copyright (C) 1992 Free Software Foundation, Inc.
|
Copyright (C) 1992, 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -11,9 +11,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
#ifndef _CPIOHDR_H
|
#ifndef _CPIOHDR_H
|
||||||
|
|
||||||
@ -34,9 +35,21 @@ struct old_cpio_header
|
|||||||
unsigned short c_mtimes[2];
|
unsigned short c_mtimes[2];
|
||||||
unsigned short c_namesize;
|
unsigned short c_namesize;
|
||||||
unsigned short c_filesizes[2];
|
unsigned short c_filesizes[2];
|
||||||
unsigned long c_mtime; /* Long-aligned copy of `c_mtimes'. */
|
};
|
||||||
unsigned long c_filesize; /* Long-aligned copy of `c_filesizes'. */
|
|
||||||
char *c_name;
|
struct old_ascii_header
|
||||||
|
{
|
||||||
|
char c_magic[6];
|
||||||
|
char c_dev[6];
|
||||||
|
char c_ino[6];
|
||||||
|
char c_mode[6];
|
||||||
|
char c_uid[6];
|
||||||
|
char c_gid[6];
|
||||||
|
char c_nlink[6];
|
||||||
|
char c_rdev[6];
|
||||||
|
char c_mtime[11];
|
||||||
|
char c_namesize[6];
|
||||||
|
char c_filesize[11];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* "New" portable format and CRC format:
|
/* "New" portable format and CRC format:
|
||||||
@ -47,44 +60,47 @@ struct old_cpio_header
|
|||||||
A header for a filename "TRAILER!!!" indicates the end of the archive. */
|
A header for a filename "TRAILER!!!" indicates the end of the archive. */
|
||||||
|
|
||||||
/* All the fields in the header are ISO 646 (approximately ASCII) strings
|
/* All the fields in the header are ISO 646 (approximately ASCII) strings
|
||||||
of hexadecimal numbers, left padded, not NUL terminated.
|
of hexadecimal numbers, left padded, not NUL terminated: */
|
||||||
|
|
||||||
Field Name Length in Bytes Notes
|
struct new_ascii_header
|
||||||
c_magic 6 "070701" for "new" portable format
|
{
|
||||||
"070702" for CRC format
|
char c_magic[6]; /* "070701" for "new" portable format
|
||||||
c_ino 8
|
"070702" for CRC format */
|
||||||
c_mode 8
|
char c_ino[8];
|
||||||
c_uid 8
|
char c_mode[8];
|
||||||
c_gid 8
|
char c_uid[8];
|
||||||
c_nlink 8
|
char c_gid[8];
|
||||||
c_mtime 8
|
char c_nlink[8];
|
||||||
c_filesize 8 must be 0 for FIFOs and directories
|
char c_mtime[8];
|
||||||
c_maj 8
|
char c_filesize[8]; /* must be 0 for FIFOs and directories */
|
||||||
c_min 8
|
char c_dev_maj[8];
|
||||||
c_rmaj 8 only valid for chr and blk special files
|
char c_dev_min[8];
|
||||||
c_rmin 8 only valid for chr and blk special files
|
char c_rdev_maj[8]; /* only valid for chr and blk special files */
|
||||||
c_namesize 8 count includes terminating NUL in pathname
|
char c_rdev_min[8]; /* only valid for chr and blk special files */
|
||||||
c_chksum 8 0 for "new" portable format; for CRC format
|
char c_namesize[8]; /* count includes terminating NUL in pathname */
|
||||||
the sum of all the bytes in the file */
|
char c_chksum[8]; /* 0 for "new" portable format; for CRC format
|
||||||
|
the sum of all the bytes in the file */
|
||||||
|
};
|
||||||
|
|
||||||
struct new_cpio_header
|
struct cpio_file_stat /* Internal representation of a CPIO header */
|
||||||
{
|
{
|
||||||
unsigned short c_magic;
|
unsigned short c_magic;
|
||||||
unsigned long c_ino;
|
ino_t c_ino;
|
||||||
unsigned long c_mode;
|
mode_t c_mode;
|
||||||
unsigned long c_uid;
|
uid_t c_uid;
|
||||||
unsigned long c_gid;
|
gid_t c_gid;
|
||||||
unsigned long c_nlink;
|
size_t c_nlink;
|
||||||
unsigned long c_mtime;
|
time_t c_mtime;
|
||||||
unsigned long c_filesize;
|
off_t c_filesize;
|
||||||
long c_dev_maj;
|
long c_dev_maj;
|
||||||
long c_dev_min;
|
long c_dev_min;
|
||||||
long c_rdev_maj;
|
long c_rdev_maj;
|
||||||
long c_rdev_min;
|
long c_rdev_min;
|
||||||
unsigned long c_namesize;
|
size_t c_namesize;
|
||||||
unsigned long c_chksum;
|
unsigned long c_chksum;
|
||||||
char *c_name;
|
char *c_name;
|
||||||
char *c_tar_linkname;
|
char *c_tar_linkname;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* cpiohdr.h */
|
#endif /* cpiohdr.h */
|
||||||
|
11
src/defer.c
11
src/defer.c
@ -1,5 +1,5 @@
|
|||||||
/* defer.c - handle "defered" links in newc and crc archives
|
/* defer.c - handle "defered" links in newc and crc archives
|
||||||
Copyright (C) 1993,2003,2004 Free Software Foundation, Inc.
|
Copyright (C) 1993, 2003, 2004, 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -11,9 +11,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
#include <system.h>
|
#include <system.h>
|
||||||
|
|
||||||
@ -24,7 +25,7 @@
|
|||||||
#include "defer.h"
|
#include "defer.h"
|
||||||
|
|
||||||
struct deferment *
|
struct deferment *
|
||||||
create_deferment (struct new_cpio_header *file_hdr)
|
create_deferment (struct cpio_file_stat *file_hdr)
|
||||||
{
|
{
|
||||||
struct deferment *d;
|
struct deferment *d;
|
||||||
d = (struct deferment *) xmalloc (sizeof (struct deferment) );
|
d = (struct deferment *) xmalloc (sizeof (struct deferment) );
|
||||||
|
15
src/defer.h
15
src/defer.h
@ -1,5 +1,5 @@
|
|||||||
/* defer.h
|
/* defer.h
|
||||||
Copyright (C) 1993, 2001, 2004 Free Software Foundation, Inc.
|
Copyright (C) 1993, 2001, 2004, 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -11,15 +11,16 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
struct deferment
|
struct deferment
|
||||||
{
|
{
|
||||||
struct deferment *next;
|
struct deferment *next;
|
||||||
struct new_cpio_header header;
|
struct cpio_file_stat header;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct deferment *create_deferment P_((struct new_cpio_header *file_hdr));
|
struct deferment *create_deferment (struct cpio_file_stat *file_hdr);
|
||||||
void free_deferment P_((struct deferment *d));
|
void free_deferment (struct deferment *d);
|
||||||
|
@ -11,9 +11,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
#if defined(HAVE_CONFIG_H)
|
#if defined(HAVE_CONFIG_H)
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
@ -27,13 +28,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "dstring.h"
|
#include "dstring.h"
|
||||||
|
|
||||||
#if __STDC__
|
char *xmalloc (unsigned n);
|
||||||
# define P_(s) s
|
char *xrealloc (char *p, unsigned n);
|
||||||
#else
|
|
||||||
# define P_(s) ()
|
|
||||||
#endif
|
|
||||||
char *xmalloc P_((unsigned n));
|
|
||||||
char *xrealloc P_((char *p, unsigned n));
|
|
||||||
|
|
||||||
/* Initialiaze dynamic string STRING with space for SIZE characters. */
|
/* Initialiaze dynamic string STRING with space for SIZE characters. */
|
||||||
|
|
||||||
|
@ -11,9 +11,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
#ifndef NULL
|
#ifndef NULL
|
||||||
#define NULL 0
|
#define NULL 0
|
||||||
|
155
src/extern.h
155
src/extern.h
@ -1,5 +1,5 @@
|
|||||||
/* extern.h - External declarations for cpio. Requires system.h.
|
/* extern.h - External declarations for cpio. Requires system.h.
|
||||||
Copyright (C) 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
|
Copyright (C) 1990, 1991, 1992, 2001, 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -11,15 +11,21 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
|
#include "paxlib.h"
|
||||||
|
#include "quotearg.h"
|
||||||
|
#include "quote.h"
|
||||||
|
|
||||||
enum archive_format
|
enum archive_format
|
||||||
{
|
{
|
||||||
arf_unknown, arf_binary, arf_oldascii, arf_newascii, arf_crcascii,
|
arf_unknown, arf_binary, arf_oldascii, arf_newascii, arf_crcascii,
|
||||||
arf_tar, arf_ustar, arf_hpoldascii, arf_hpbinary
|
arf_tar, arf_ustar, arf_hpoldascii, arf_hpbinary
|
||||||
};
|
};
|
||||||
|
|
||||||
extern enum archive_format archive_format;
|
extern enum archive_format archive_format;
|
||||||
extern int reset_time_flag;
|
extern int reset_time_flag;
|
||||||
extern int io_block_size;
|
extern int io_block_size;
|
||||||
@ -66,7 +72,7 @@ extern char *new_media_message_after_number;
|
|||||||
extern int archive_des;
|
extern int archive_des;
|
||||||
extern char *archive_name;
|
extern char *archive_name;
|
||||||
extern char *rsh_command_option;
|
extern char *rsh_command_option;
|
||||||
extern unsigned long crc;
|
extern unsigned int crc;
|
||||||
extern int delayed_seek_count;
|
extern int delayed_seek_count;
|
||||||
#ifdef DEBUG_CPIO
|
#ifdef DEBUG_CPIO
|
||||||
extern int debug_flag;
|
extern int debug_flag;
|
||||||
@ -81,7 +87,6 @@ extern long long input_bytes, output_bytes;
|
|||||||
#else
|
#else
|
||||||
extern long input_bytes, output_bytes;
|
extern long input_bytes, output_bytes;
|
||||||
#endif
|
#endif
|
||||||
extern char zeros_512[];
|
|
||||||
extern char *directory_name;
|
extern char *directory_name;
|
||||||
extern char **save_patterns;
|
extern char **save_patterns;
|
||||||
extern int num_patterns;
|
extern int num_patterns;
|
||||||
@ -94,38 +99,35 @@ extern char *program_name;
|
|||||||
extern int (*xstat) ();
|
extern int (*xstat) ();
|
||||||
extern void (*copy_function) ();
|
extern void (*copy_function) ();
|
||||||
|
|
||||||
#if defined PROTOTYPES || (defined __STDC__ && __STDC__)
|
|
||||||
# define P_(s) s
|
|
||||||
#else
|
|
||||||
# define P_(s) ()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* copyin.c */
|
/* copyin.c */
|
||||||
void warn_junk_bytes P_((long bytes_skipped));
|
void warn_junk_bytes (long bytes_skipped);
|
||||||
void read_in_header P_((struct new_cpio_header *file_hdr, int in_des));
|
/* FIXME: make read_* static in copyin.c */
|
||||||
void read_in_old_ascii P_((struct new_cpio_header *file_hdr, int in_des));
|
void read_in_header (struct cpio_file_stat *file_hdr, int in_des);
|
||||||
void read_in_new_ascii P_((struct new_cpio_header *file_hdr, int in_des));
|
void read_in_old_ascii (struct cpio_file_stat *file_hdr, int in_des);
|
||||||
void read_in_binary P_((struct new_cpio_header *file_hdr, int in_des));
|
void read_in_new_ascii (struct cpio_file_stat *file_hdr, int in_des);
|
||||||
void swab_array P_((char *arg, int count));
|
void read_in_binary (struct cpio_file_stat *file_hdr,
|
||||||
void process_copy_in P_((void));
|
struct old_cpio_header *short_hdr, int in_des);
|
||||||
void long_format P_((struct new_cpio_header *file_hdr, char *link_name));
|
void swab_array (char *arg, int count);
|
||||||
void print_name_with_quoting P_((char *p));
|
void process_copy_in (void);
|
||||||
|
void long_format (struct cpio_file_stat *file_hdr, char *link_name);
|
||||||
|
void print_name_with_quoting (char *p);
|
||||||
|
|
||||||
/* copyout.c */
|
/* copyout.c */
|
||||||
void write_out_header P_((struct new_cpio_header *file_hdr, int out_des));
|
int write_out_header (struct cpio_file_stat *file_hdr, int out_des);
|
||||||
void process_copy_out P_((void));
|
void process_copy_out (void);
|
||||||
|
|
||||||
/* copypass.c */
|
/* copypass.c */
|
||||||
void process_copy_pass P_((void));
|
void process_copy_pass (void);
|
||||||
int link_to_maj_min_ino P_((char *file_name, int st_dev_maj,
|
int link_to_maj_min_ino (char *file_name, int st_dev_maj,
|
||||||
int st_dev_min, int st_ino));
|
int st_dev_min, int st_ino);
|
||||||
int link_to_name P_((char *link_name, char *link_target));
|
int link_to_name (char *link_name, char *link_target);
|
||||||
|
|
||||||
/* dirname.c */
|
/* dirname.c */
|
||||||
char *dirname P_((char *path));
|
char *dirname (char *path);
|
||||||
|
|
||||||
/* filemode.c */
|
/* filemode.c */
|
||||||
void mode_string P_((unsigned int mode, char *str));
|
void mode_string (unsigned int mode, char *str);
|
||||||
|
|
||||||
/* idcache.c */
|
/* idcache.c */
|
||||||
#ifndef __MSDOS__
|
#ifndef __MSDOS__
|
||||||
@ -136,61 +138,63 @@ gid_t *getgidbyname ();
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* main.c */
|
/* main.c */
|
||||||
void process_args P_((int argc, char *argv[]));
|
void process_args (int argc, char *argv[]);
|
||||||
void initialize_buffers P_((void));
|
void initialize_buffers (void);
|
||||||
|
|
||||||
/* makepath.c */
|
/* makepath.c */
|
||||||
int make_path P_((char *argpath, int mode, int parent_mode,
|
int make_path (char *argpath, int mode, int parent_mode,
|
||||||
uid_t owner, gid_t group, char *verbose_fmt_string));
|
uid_t owner, gid_t group, char *verbose_fmt_string);
|
||||||
|
|
||||||
/* tar.c */
|
/* tar.c */
|
||||||
void write_out_tar_header P_((struct new_cpio_header *file_hdr, int out_des));
|
void write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des);
|
||||||
int null_block P_((long *block, int size));
|
int null_block (long *block, int size);
|
||||||
void read_in_tar_header P_((struct new_cpio_header *file_hdr, int in_des));
|
void read_in_tar_header (struct cpio_file_stat *file_hdr, int in_des);
|
||||||
int otoa P_((char *s, unsigned long *n));
|
int otoa (char *s, unsigned long *n);
|
||||||
int is_tar_header P_((char *buf));
|
int is_tar_header (char *buf);
|
||||||
int is_tar_filename_too_long P_((char *name));
|
int is_tar_filename_too_long (char *name);
|
||||||
|
|
||||||
/* userspec.c */
|
/* userspec.c */
|
||||||
#ifndef __MSDOS__
|
#ifndef __MSDOS__
|
||||||
char *parse_user_spec P_((char *name, uid_t *uid, gid_t *gid,
|
char *parse_user_spec (char *name, uid_t *uid, gid_t *gid,
|
||||||
char **username, char **groupname));
|
char **username, char **groupname);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* util.c */
|
/* util.c */
|
||||||
void tape_empty_output_buffer P_((int out_des));
|
void tape_empty_output_buffer (int out_des);
|
||||||
void disk_empty_output_buffer P_((int out_des));
|
void disk_empty_output_buffer (int out_des);
|
||||||
void swahw_array P_((char *ptr, int count));
|
void swahw_array (char *ptr, int count);
|
||||||
void tape_buffered_write P_((char *in_buf, int out_des, long num_bytes));
|
void tape_buffered_write (char *in_buf, int out_des, off_t num_bytes);
|
||||||
void tape_buffered_read P_((char *in_buf, int in_des, long num_bytes));
|
void tape_buffered_read (char *in_buf, int in_des, off_t num_bytes);
|
||||||
int tape_buffered_peek P_((char *peek_buf, int in_des, int num_bytes));
|
int tape_buffered_peek (char *peek_buf, int in_des, int num_bytes);
|
||||||
void tape_toss_input P_((int in_des, long num_bytes));
|
void tape_toss_input (int in_des, off_t num_bytes);
|
||||||
void copy_files_tape_to_disk P_((int in_des, int out_des, long num_bytes));
|
void copy_files_tape_to_disk (int in_des, int out_des, off_t num_bytes);
|
||||||
void copy_files_disk_to_tape P_((int in_des, int out_des, long num_bytes, char *filename));
|
void copy_files_disk_to_tape (int in_des, int out_des, off_t num_bytes, char *filename);
|
||||||
void copy_files_disk_to_disk P_((int in_des, int out_des, long num_bytes, char *filename));
|
void copy_files_disk_to_disk (int in_des, int out_des, off_t num_bytes, char *filename);
|
||||||
void warn_if_file_changed P_((char *file_name, unsigned long old_file_size,
|
void warn_if_file_changed (char *file_name, unsigned long old_file_size,
|
||||||
unsigned long old_file_mtime));
|
off_t old_file_mtime);
|
||||||
void create_all_directories P_((char *name));
|
void create_all_directories (char *name);
|
||||||
void prepare_append P_((int out_file_des));
|
void prepare_append (int out_file_des);
|
||||||
char *find_inode_file P_((unsigned long node_num,
|
char *find_inode_file (unsigned long node_num,
|
||||||
unsigned long major_num, unsigned long minor_num));
|
unsigned long major_num, unsigned long minor_num);
|
||||||
void add_inode P_((unsigned long node_num, char *file_name,
|
void add_inode (unsigned long node_num, char *file_name,
|
||||||
unsigned long major_num, unsigned long minor_num));
|
unsigned long major_num, unsigned long minor_num);
|
||||||
int open_archive P_((char *file));
|
int open_archive (char *file);
|
||||||
void tape_offline P_((int tape_des));
|
void tape_offline (int tape_des);
|
||||||
void get_next_reel P_((int tape_des));
|
void get_next_reel (int tape_des);
|
||||||
void set_new_media_message P_((char *message));
|
void set_new_media_message (char *message);
|
||||||
#if defined(__MSDOS__) && !defined(__GNUC__)
|
#if defined(__MSDOS__) && !defined(__GNUC__)
|
||||||
int chown P_((char *path, int owner, int group));
|
int chown (char *path, int owner, int group);
|
||||||
#endif
|
#endif
|
||||||
#ifdef __TURBOC__
|
#ifdef __TURBOC__
|
||||||
int utime P_((char *filename, struct utimbuf *utb));
|
int utime (char *filename, struct utimbuf *utb);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HPUX_CDF
|
#ifdef HPUX_CDF
|
||||||
char *add_cdf_double_slashes P_((char *filename));
|
char *add_cdf_double_slashes (char *filename);
|
||||||
#endif
|
#endif
|
||||||
|
void write_nuls_to_file (off_t num_bytes, int out_des,
|
||||||
#define DISK_IO_BLOCK_SIZE (512)
|
void (*writer) (char *in_buf,
|
||||||
|
int out_des, off_t num_bytes));
|
||||||
|
#define DISK_IO_BLOCK_SIZE 512
|
||||||
|
|
||||||
/* FIXME: Move to system.h? */
|
/* FIXME: Move to system.h? */
|
||||||
#ifndef SYMLINK_USES_UMASK
|
#ifndef SYMLINK_USES_UMASK
|
||||||
@ -198,3 +202,20 @@ char *add_cdf_double_slashes P_((char *filename));
|
|||||||
#else
|
#else
|
||||||
# define UMASKED_SYMLINK(name1,name2,mode) umasked_symlink(name1,name2,mode)
|
# define UMASKED_SYMLINK(name1,name2,mode) umasked_symlink(name1,name2,mode)
|
||||||
#endif /* SYMLINK_USES_UMASK */
|
#endif /* SYMLINK_USES_UMASK */
|
||||||
|
|
||||||
|
void set_perms (int fd, struct cpio_file_stat *header);
|
||||||
|
void set_file_times (int fd, const char *name, unsigned long atime,
|
||||||
|
unsigned long mtime);
|
||||||
|
void stat_to_cpio (struct cpio_file_stat *hdr, struct stat *st);
|
||||||
|
void cpio_safer_name_suffix (char *name, bool link_target,
|
||||||
|
bool absolute_names, bool strip_leading_dots);
|
||||||
|
|
||||||
|
/* FIXME: These two defines should be defined in paxutils */
|
||||||
|
#define LG_8 3
|
||||||
|
#define LG_16 4
|
||||||
|
|
||||||
|
uintmax_t from_ascii (char const *where, size_t digs, unsigned logbase);
|
||||||
|
|
||||||
|
#define FROM_OCTAL(f) from_ascii (f, sizeof f, LG_8)
|
||||||
|
#define FROM_HEX(f) from_ascii (f, sizeof f, LG_16)
|
||||||
|
|
||||||
|
@ -11,9 +11,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
@ -11,9 +11,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
/* Include sys/types.h and sys/stat.h before this file. */
|
/* Include sys/types.h and sys/stat.h before this file. */
|
||||||
|
|
||||||
|
14
src/global.c
14
src/global.c
@ -1,5 +1,5 @@
|
|||||||
/* global.c - global variables and initial values for cpio.
|
/* global.c - global variables and initial values for cpio.
|
||||||
Copyright (C) 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
|
Copyright (C) 1990, 1991, 1992, 2001, 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -11,9 +11,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
#include <system.h>
|
#include <system.h>
|
||||||
|
|
||||||
@ -139,7 +140,7 @@ char *archive_name = NULL;
|
|||||||
char *rsh_command_option = NULL;
|
char *rsh_command_option = NULL;
|
||||||
|
|
||||||
/* CRC checksum. */
|
/* CRC checksum. */
|
||||||
unsigned long crc;
|
unsigned int crc;
|
||||||
|
|
||||||
/* Input and output buffers. */
|
/* Input and output buffers. */
|
||||||
char *input_buffer, *output_buffer;
|
char *input_buffer, *output_buffer;
|
||||||
@ -165,9 +166,6 @@ long long input_bytes, output_bytes;
|
|||||||
long input_bytes, output_bytes;
|
long input_bytes, output_bytes;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 512 bytes of 0; used for various padding operations. */
|
|
||||||
char zeros_512[512];
|
|
||||||
|
|
||||||
/* Saving of argument values for later reference. */
|
/* Saving of argument values for later reference. */
|
||||||
char *directory_name = NULL;
|
char *directory_name = NULL;
|
||||||
char **save_patterns;
|
char **save_patterns;
|
||||||
|
@ -11,9 +11,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
377
src/main.c
377
src/main.c
@ -1,5 +1,6 @@
|
|||||||
/* main.c - main program and argument processing for cpio.
|
/* main.c - main program and argument processing for cpio.
|
||||||
Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004 Free Software Foundation, Inc.
|
Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004, 2005, 2006
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -11,9 +12,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
/* Written by Phil Nelson <phil@cs.wwu.edu>,
|
/* Written by Phil Nelson <phil@cs.wwu.edu>,
|
||||||
David MacKenzie <djm@gnu.ai.mit.edu>,
|
David MacKenzie <djm@gnu.ai.mit.edu>,
|
||||||
@ -21,6 +23,7 @@
|
|||||||
and Sergey Poznyakoff <gray@mirddin.farlep.net> */
|
and Sergey Poznyakoff <gray@mirddin.farlep.net> */
|
||||||
|
|
||||||
#include <system.h>
|
#include <system.h>
|
||||||
|
#include <paxlib.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -29,7 +32,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#ifdef HAVE_LOCALE_H
|
#ifdef HAVE_LOCALE_H
|
||||||
# include <locale.h>
|
# include <locale.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "filetypes.h"
|
#include "filetypes.h"
|
||||||
@ -37,10 +40,11 @@
|
|||||||
#include "dstring.h"
|
#include "dstring.h"
|
||||||
#include "extern.h"
|
#include "extern.h"
|
||||||
#include <rmt.h>
|
#include <rmt.h>
|
||||||
#include <localedir.h>
|
#include <rmt-command.h>
|
||||||
|
|
||||||
enum cpio_options {
|
enum cpio_options {
|
||||||
NO_ABSOLUTE_FILENAMES_OPTION=256,
|
NO_ABSOLUTE_FILENAMES_OPTION=256,
|
||||||
|
ABSOLUTE_FILENAMES_OPTION,
|
||||||
NO_PRESERVE_OWNER_OPTION,
|
NO_PRESERVE_OWNER_OPTION,
|
||||||
ONLY_VERIFY_CRC_OPTION,
|
ONLY_VERIFY_CRC_OPTION,
|
||||||
RENAME_BATCH_FILE_OPTION,
|
RENAME_BATCH_FILE_OPTION,
|
||||||
@ -50,8 +54,9 @@ enum cpio_options {
|
|||||||
FORCE_LOCAL_OPTION,
|
FORCE_LOCAL_OPTION,
|
||||||
DEBUG_OPTION,
|
DEBUG_OPTION,
|
||||||
BLOCK_SIZE_OPTION,
|
BLOCK_SIZE_OPTION,
|
||||||
TO_STDOUT_OPTION,
|
TO_STDOUT_OPTION,
|
||||||
|
|
||||||
|
HANG_OPTION,
|
||||||
USAGE_OPTION,
|
USAGE_OPTION,
|
||||||
LICENSE_OPTION,
|
LICENSE_OPTION,
|
||||||
VERSION_OPTION
|
VERSION_OPTION
|
||||||
@ -71,129 +76,156 @@ Examples:\n\
|
|||||||
|
|
||||||
/* Print usage error message and exit with error. */
|
/* Print usage error message and exit with error. */
|
||||||
|
|
||||||
#define USAGE_ERROR(args) do { error args; exit(2); } while (0)
|
|
||||||
#define CHECK_USAGE(cond, opt, mode_opt) \
|
#define CHECK_USAGE(cond, opt, mode_opt) \
|
||||||
if (cond) USAGE_ERROR((0, 0, _("%s is meaningless with %s"), opt, mode_opt));
|
if (cond) \
|
||||||
|
ERROR((PAXEXIT_FAILURE, 0, _("%s is meaningless with %s"), opt, mode_opt));
|
||||||
|
|
||||||
static struct argp_option options[] = {
|
static struct argp_option options[] = {
|
||||||
|
/* ********** */
|
||||||
|
#define GRID 10
|
||||||
{NULL, 0, NULL, 0,
|
{NULL, 0, NULL, 0,
|
||||||
N_("Main operation mode:"), 10},
|
N_("Main operation mode:"), GRID },
|
||||||
{"create", 'o', 0, 0,
|
{"create", 'o', 0, 0,
|
||||||
N_("Create the archive (run in copy-out mode)"), 10},
|
N_("Create the archive (run in copy-out mode)"), GRID },
|
||||||
{"extract", 'i', 0, 0,
|
{"extract", 'i', 0, 0,
|
||||||
N_("Extract files from an archive (run in copy-in mode)")},
|
N_("Extract files from an archive (run in copy-in mode)"), GRID },
|
||||||
{"pass-through", 'p', 0, 0,
|
{"pass-through", 'p', 0, 0,
|
||||||
N_("Run in copy-pass mode"), 10},
|
N_("Run in copy-pass mode"), GRID },
|
||||||
{"list", 't', 0, 0,
|
{"list", 't', 0, 0,
|
||||||
N_("Print a table of contents of the input"), 10},
|
N_("Print a table of contents of the input"), GRID },
|
||||||
|
#undef GRID
|
||||||
{NULL, 0, NULL, 0,
|
|
||||||
N_("Operation modifiers valid in any mode:"), 100},
|
|
||||||
|
|
||||||
{"file", 'F', N_("[[USER@]HOST:]FILE-NAME"), 0,
|
|
||||||
N_("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"), 110},
|
|
||||||
{"force-local", FORCE_LOCAL_OPTION, 0, 0,
|
|
||||||
N_("Archive file is local, even if its name contains colons"), 110},
|
|
||||||
{"format", 'H', N_("FORMAT"), 0,
|
|
||||||
N_("Use given archive FORMAT"), 110},
|
|
||||||
{NULL, 'B', NULL, 0,
|
|
||||||
N_("Set the I/O block size to 5120 bytes"), 110},
|
|
||||||
{"block-size", BLOCK_SIZE_OPTION, N_("BLOCK-SIZE"), 0,
|
|
||||||
N_("Set the I/O block size to BLOCK-SIZE * 512 bytes"), 110},
|
|
||||||
{NULL, 'c', NULL, 0,
|
|
||||||
N_("Use the old portable (ASCII) archive format"), 0},
|
|
||||||
{"dot", 'V', NULL, 0,
|
|
||||||
N_("Print a \".\" for each file processed"), 110},
|
|
||||||
{"io-size", 'C', N_("NUMBER"), 0,
|
|
||||||
N_("Set the I/O block size to the given NUMBER of bytes"), 110},
|
|
||||||
{"message", 'M', N_("STRING"), 0,
|
|
||||||
N_("Print STRING when the end of a volume of the backup media is reached"),
|
|
||||||
110},
|
|
||||||
{"nonmatching", 'f', 0, 0,
|
|
||||||
N_("Only copy files that do not match any of the given patterns"), 110},
|
|
||||||
{"numeric-uid-gid", 'n', 0, 0,
|
|
||||||
N_("In the verbose table of contents listing, show numeric UID and GID"),
|
|
||||||
110},
|
|
||||||
{"rsh-command", RSH_COMMAND_OPTION, N_("COMMAND"), 0,
|
|
||||||
N_("Use remote COMMAND instead of rsh"), 110},
|
|
||||||
{"quiet", QUIET_OPTION, NULL, 0,
|
|
||||||
N_("Do not print the number of blocks copied"), 110},
|
|
||||||
{"verbose", 'v', NULL, 0,
|
|
||||||
N_("Verbosely list the files processed"), 110},
|
|
||||||
#ifdef DEBUG_CPIO
|
|
||||||
{"debug", DEBUG_OPTION, NULL, 0,
|
|
||||||
N_("Enable debugging info"), 110},
|
|
||||||
#endif
|
|
||||||
{"warning", 'W', N_("FLAG"), 0,
|
|
||||||
N_("Control warning display. Currently FLAG is one of 'none', 'truncate', 'all'. Multiple options accumulate."), 110 },
|
|
||||||
|
|
||||||
/* ********** */
|
|
||||||
{NULL, 0, NULL, 0,
|
|
||||||
N_("Operation modifiers valid only in copy-in mode:"), 200},
|
|
||||||
{"pattern-file", 'E', N_("FILE"), 0,
|
|
||||||
N_("In copy-in mode, read additional patterns specifying filenames to extract or list from FILE"), 210},
|
|
||||||
{"no-absolute-filenames", NO_ABSOLUTE_FILENAMES_OPTION, 0, 0,
|
|
||||||
N_("Create all files relative to the current directory"), 210},
|
|
||||||
{"only-verify-crc", ONLY_VERIFY_CRC_OPTION, 0, 0,
|
|
||||||
N_("When reading a CRC format archive in copy-in mode, only verify the CRC's of each file in the archive, don't actually extract the files"), 210},
|
|
||||||
{"rename", 'r', 0, 0,
|
|
||||||
N_("Interactively rename files"), 210},
|
|
||||||
{"rename-batch-file", RENAME_BATCH_FILE_OPTION, N_("FILE"), OPTION_HIDDEN,
|
|
||||||
"", 210},
|
|
||||||
{"swap", 'b', NULL, 0,
|
|
||||||
N_("Swap both halfwords of words and bytes of halfwords in the data. Equivalent to -sS"), 210},
|
|
||||||
{"swap-bytes", 's', NULL, 0,
|
|
||||||
N_("Swap the bytes of each halfword in the files"), 210},
|
|
||||||
{"swap-halfwords", 'S', NULL, 0,
|
|
||||||
N_("Swap the halfwords of each word (4 bytes) in the files"),
|
|
||||||
210},
|
|
||||||
{"to-stdout", TO_STDOUT_OPTION, NULL, 0,
|
|
||||||
N_("Extract files to standard output"), 210},
|
|
||||||
|
|
||||||
/* ********** */
|
|
||||||
{NULL, 0, NULL, 0,
|
|
||||||
N_("Operation modifiers valid only in copy-out mode:"), 300},
|
|
||||||
{"append", 'A', 0, 0,
|
|
||||||
N_("Append to an existing archive."), 310 },
|
|
||||||
{NULL, 'O', N_("[[USER@]HOST:]FILE-NAME"), 0,
|
|
||||||
N_("Archive filename to use instead of standard output. Optional USER and HOST specify the user and host names in case of a remote archive"), 310},
|
|
||||||
|
|
||||||
/* ********** */
|
/* ********** */
|
||||||
|
#define GRID 100
|
||||||
{NULL, 0, NULL, 0,
|
{NULL, 0, NULL, 0,
|
||||||
N_("Operation modifiers valid only in copy-pass mode:"), 400},
|
N_("Operation modifiers valid in any mode:"), GRID },
|
||||||
|
|
||||||
|
{"file", 'F', N_("[[USER@]HOST:]FILE-NAME"), 0,
|
||||||
|
N_("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"), GRID+1 },
|
||||||
|
{"force-local", FORCE_LOCAL_OPTION, 0, 0,
|
||||||
|
N_("Archive file is local, even if its name contains colons"), GRID+1 },
|
||||||
|
{"format", 'H', N_("FORMAT"), 0,
|
||||||
|
N_("Use given archive FORMAT"), GRID+1 },
|
||||||
|
{NULL, 'B', NULL, 0,
|
||||||
|
N_("Set the I/O block size to 5120 bytes"), GRID+1 },
|
||||||
|
{"block-size", BLOCK_SIZE_OPTION, N_("BLOCK-SIZE"), 0,
|
||||||
|
N_("Set the I/O block size to BLOCK-SIZE * 512 bytes"), GRID+1 },
|
||||||
|
{NULL, 'c', NULL, 0,
|
||||||
|
N_("Use the old portable (ASCII) archive format"), GRID+1 },
|
||||||
|
{"dot", 'V', NULL, 0,
|
||||||
|
N_("Print a \".\" for each file processed"), GRID+1 },
|
||||||
|
{"io-size", 'C', N_("NUMBER"), 0,
|
||||||
|
N_("Set the I/O block size to the given NUMBER of bytes"), GRID+1 },
|
||||||
|
{"message", 'M', N_("STRING"), 0,
|
||||||
|
N_("Print STRING when the end of a volume of the backup media is reached"),
|
||||||
|
GRID+1 },
|
||||||
|
{"nonmatching", 'f', 0, 0,
|
||||||
|
N_("Only copy files that do not match any of the given patterns"), GRID+1 },
|
||||||
|
{"numeric-uid-gid", 'n', 0, 0,
|
||||||
|
N_("In the verbose table of contents listing, show numeric UID and GID"),
|
||||||
|
GRID+1 },
|
||||||
|
{"rsh-command", RSH_COMMAND_OPTION, N_("COMMAND"), 0,
|
||||||
|
N_("Use remote COMMAND instead of rsh"), GRID+1 },
|
||||||
|
{"quiet", QUIET_OPTION, NULL, 0,
|
||||||
|
N_("Do not print the number of blocks copied"), GRID+1 },
|
||||||
|
{"verbose", 'v', NULL, 0,
|
||||||
|
N_("Verbosely list the files processed"), GRID+1 },
|
||||||
|
#ifdef DEBUG_CPIO
|
||||||
|
{"debug", DEBUG_OPTION, NULL, 0,
|
||||||
|
N_("Enable debugging info"), GRID+1 },
|
||||||
|
#endif
|
||||||
|
{"warning", 'W', N_("FLAG"), 0,
|
||||||
|
N_("Control warning display. Currently FLAG is one of 'none', 'truncate', 'all'. Multiple options accumulate."), GRID+1 },
|
||||||
|
#undef GRID
|
||||||
|
|
||||||
|
/* ********** */
|
||||||
|
#define GRID 200
|
||||||
|
{NULL, 0, NULL, 0,
|
||||||
|
N_("Operation modifiers valid only in copy-in mode:"), GRID },
|
||||||
|
{"pattern-file", 'E', N_("FILE"), 0,
|
||||||
|
N_("Read additional patterns specifying filenames to extract or list from FILE"), 210},
|
||||||
|
{"only-verify-crc", ONLY_VERIFY_CRC_OPTION, 0, 0,
|
||||||
|
N_("When reading a CRC format archive, only verify the CRC's of each file in the archive, don't actually extract the files"), 210},
|
||||||
|
{"rename", 'r', 0, 0,
|
||||||
|
N_("Interactively rename files"), GRID+1 },
|
||||||
|
{"rename-batch-file", RENAME_BATCH_FILE_OPTION, N_("FILE"), OPTION_HIDDEN,
|
||||||
|
"", GRID+1 },
|
||||||
|
{"swap", 'b', NULL, 0,
|
||||||
|
N_("Swap both halfwords of words and bytes of halfwords in the data. Equivalent to -sS"), GRID+1 },
|
||||||
|
{"swap-bytes", 's', NULL, 0,
|
||||||
|
N_("Swap the bytes of each halfword in the files"), GRID+1 },
|
||||||
|
{"swap-halfwords", 'S', NULL, 0,
|
||||||
|
N_("Swap the halfwords of each word (4 bytes) in the files"),
|
||||||
|
GRID+1 },
|
||||||
|
{"to-stdout", TO_STDOUT_OPTION, NULL, 0,
|
||||||
|
N_("Extract files to standard output"), GRID+1 },
|
||||||
|
#undef GRID
|
||||||
|
|
||||||
|
/* ********** */
|
||||||
|
#define GRID 300
|
||||||
|
{NULL, 0, NULL, 0,
|
||||||
|
N_("Operation modifiers valid only in copy-out mode:"), GRID },
|
||||||
|
{"append", 'A', 0, 0,
|
||||||
|
N_("Append to an existing archive."), GRID+1 },
|
||||||
|
{NULL, 'O', N_("[[USER@]HOST:]FILE-NAME"), 0,
|
||||||
|
N_("Archive filename to use instead of standard output. Optional USER and HOST specify the user and host names in case of a remote archive"), GRID+1 },
|
||||||
|
#undef GRID
|
||||||
|
|
||||||
|
/* ********** */
|
||||||
|
#define GRID 400
|
||||||
|
{NULL, 0, NULL, 0,
|
||||||
|
N_("Operation modifiers valid only in copy-pass mode:"), GRID},
|
||||||
{"link", 'l', 0, 0,
|
{"link", 'l', 0, 0,
|
||||||
N_("Link files instead of copying them, when possible"), 410},
|
N_("Link files instead of copying them, when possible"), GRID+1 },
|
||||||
|
|
||||||
|
#undef GRID
|
||||||
|
|
||||||
/* ********** */
|
/* ********** */
|
||||||
|
#define GRID 500
|
||||||
{NULL, 0, NULL, 0,
|
{NULL, 0, NULL, 0,
|
||||||
N_("Operation modifiers valid for copy-out and copy-pass modes:"), 500},
|
N_("Operation modifiers valid in copy-in and copy-out modes:"), GRID },
|
||||||
|
{"absolute-filenames", ABSOLUTE_FILENAMES_OPTION, 0, 0,
|
||||||
|
N_("Do not strip file system prefix components from the file names"),
|
||||||
|
GRID+1 },
|
||||||
|
{"no-absolute-filenames", NO_ABSOLUTE_FILENAMES_OPTION, 0, 0,
|
||||||
|
N_("Create all files relative to the current directory"), GRID+1 },
|
||||||
|
#undef GRID
|
||||||
|
/* ********** */
|
||||||
|
#define GRID 600
|
||||||
|
{NULL, 0, NULL, 0,
|
||||||
|
N_("Operation modifiers valid in copy-out and copy-pass modes:"), GRID },
|
||||||
{"null", '0', 0, 0,
|
{"null", '0', 0, 0,
|
||||||
N_("A list of filenames is terminated by a null character instead of a newline"), 510 },
|
N_("A list of filenames is terminated by a null character instead of a newline"), GRID+1 },
|
||||||
{NULL, 'I', N_("[[USER@]HOST:]FILE-NAME"), 0,
|
{NULL, 'I', N_("[[USER@]HOST:]FILE-NAME"), 0,
|
||||||
N_("Archive filename to use instead of standard input. Optional USER and HOST specify the user and host names in case of a remote archive"), 510},
|
N_("Archive filename to use instead of standard input. Optional USER and HOST specify the user and host names in case of a remote archive"), GRID+1 },
|
||||||
{"dereference", 'L', 0, 0,
|
{"dereference", 'L', 0, 0,
|
||||||
N_("Dereference symbolic links (copy the files that they point to instead of copying the links)."), 510},
|
N_("Dereference symbolic links (copy the files that they point to instead of copying the links)."), GRID+1 },
|
||||||
{"owner", 'R', N_("[USER][:.][GROUP]"), 0,
|
{"owner", 'R', N_("[USER][:.][GROUP]"), 0,
|
||||||
N_("Set the ownership of all files created to the specified USER and/or GROUP"), 510},
|
N_("Set the ownership of all files created to the specified USER and/or GROUP"), GRID+1 },
|
||||||
{"sparse", SPARSE_OPTION, NULL, 0,
|
|
||||||
N_("Write files with large blocks of zeros as sparse files"), 510},
|
|
||||||
{"reset-access-time", 'a', NULL, 0,
|
{"reset-access-time", 'a', NULL, 0,
|
||||||
N_("Reset the access times of files after reading them"), 510},
|
N_("Reset the access times of files after reading them"), GRID+1 },
|
||||||
|
|
||||||
|
#undef GRID
|
||||||
/* ********** */
|
/* ********** */
|
||||||
|
#define GRID 700
|
||||||
{NULL, 0, NULL, 0,
|
{NULL, 0, NULL, 0,
|
||||||
N_("Operation modifiers valid for copy-in and copy-pass modes:"), 600},
|
N_("Operation modifiers valid in copy-in and copy-pass modes:"), GRID },
|
||||||
{"preserve-modification-time", 'm', 0, 0,
|
{"preserve-modification-time", 'm', 0, 0,
|
||||||
N_("Retain previous file modification times when creating files"), 610},
|
N_("Retain previous file modification times when creating files"), GRID+1 },
|
||||||
{"make-directories", 'd', 0, 0,
|
{"make-directories", 'd', 0, 0,
|
||||||
N_("Create leading directories where needed"), 610},
|
N_("Create leading directories where needed"), GRID+1 },
|
||||||
{"no-preserve-owner", NO_PRESERVE_OWNER_OPTION, 0, 0,
|
{"no-preserve-owner", NO_PRESERVE_OWNER_OPTION, 0, 0,
|
||||||
N_("Do not change the ownership of the files"), 610},
|
N_("Do not change the ownership of the files"), GRID+1 },
|
||||||
{"unconditional", 'u', NULL, 0,
|
{"unconditional", 'u', NULL, 0,
|
||||||
N_("Replace all files unconditionally"), 610},
|
N_("Replace all files unconditionally"), GRID+1 },
|
||||||
|
{"sparse", SPARSE_OPTION, NULL, 0,
|
||||||
|
N_("Write files with large blocks of zeros as sparse files"), GRID+1 },
|
||||||
|
#undef GRID
|
||||||
|
|
||||||
|
/* ********** */
|
||||||
|
#define GRID 800
|
||||||
{NULL, 0, NULL, 0,
|
{NULL, 0, NULL, 0,
|
||||||
N_("Informative options:"), 700 },
|
N_("Informative options:"), GRID },
|
||||||
|
|
||||||
{"help", '?', 0, 0, N_("Give this help list"), -1},
|
{"help", '?', 0, 0, N_("Give this help list"), -1},
|
||||||
{"usage", USAGE_OPTION, 0, 0, N_("Give a short usage message"), -1},
|
{"usage", USAGE_OPTION, 0, 0, N_("Give a short usage message"), -1},
|
||||||
@ -201,7 +233,9 @@ static struct argp_option options[] = {
|
|||||||
{"version", VERSION_OPTION, 0, 0, N_("Print program version"), -1},
|
{"version", VERSION_OPTION, 0, 0, N_("Print program version"), -1},
|
||||||
/* FIXME -V (--dot) conflicts with the default short option for
|
/* FIXME -V (--dot) conflicts with the default short option for
|
||||||
--version */
|
--version */
|
||||||
|
{"HANG", HANG_OPTION, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
|
||||||
|
N_("hang for SECS seconds (default 3600)"), 0},
|
||||||
|
#undef GRID
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -224,8 +258,8 @@ license ()
|
|||||||
" GNU General Public License for more details.\n"
|
" GNU General Public License for more details.\n"
|
||||||
"\n"
|
"\n"
|
||||||
" You should have received a copy of the GNU General Public License\n"
|
" You should have received a copy of the GNU General Public License\n"
|
||||||
" along with GNU cpio; if not, write to the Free Software\n"
|
" along with GNU cpio; if not, write to the Free Software Foundation,\n"
|
||||||
" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n\n"));
|
" Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n"));
|
||||||
exit (0);
|
exit (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,6 +303,7 @@ warn_control (char *arg)
|
|||||||
static error_t
|
static error_t
|
||||||
parse_opt (int key, char *arg, struct argp_state *state)
|
parse_opt (int key, char *arg, struct argp_state *state)
|
||||||
{
|
{
|
||||||
|
static volatile int _argp_hang;
|
||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
case '0': /* Read null-terminated filenames. */
|
case '0': /* Read null-terminated filenames. */
|
||||||
@ -301,7 +336,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
|||||||
|
|
||||||
case 'c': /* Use the old portable ASCII format. */
|
case 'c': /* Use the old portable ASCII format. */
|
||||||
if (archive_format != arf_unknown)
|
if (archive_format != arf_unknown)
|
||||||
USAGE_ERROR ((0, 0, _("Archive format multiply defined")));
|
error (0, EXIT_FAILURE, _("Archive format multiply defined"));
|
||||||
#ifdef SVR4_COMPAT
|
#ifdef SVR4_COMPAT
|
||||||
archive_format = arf_newascii; /* -H newc. */
|
archive_format = arf_newascii; /* -H newc. */
|
||||||
#else
|
#else
|
||||||
@ -333,7 +368,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
|||||||
|
|
||||||
case 'H': /* Header format name. */
|
case 'H': /* Header format name. */
|
||||||
if (archive_format != arf_unknown)
|
if (archive_format != arf_unknown)
|
||||||
USAGE_ERROR ((0, 0, _("Archive format multiply defined")));
|
error (PAXEXIT_FAILURE, 0, _("Archive format multiply defined"));
|
||||||
if (!strcasecmp (arg, "crc"))
|
if (!strcasecmp (arg, "crc"))
|
||||||
archive_format = arf_crcascii;
|
archive_format = arf_crcascii;
|
||||||
else if (!strcasecmp (arg, "newc"))
|
else if (!strcasecmp (arg, "newc"))
|
||||||
@ -358,7 +393,7 @@ crc newc odc bin ustar tar (all-caps also recognized)"), arg);
|
|||||||
|
|
||||||
case 'i': /* Copy-in mode. */
|
case 'i': /* Copy-in mode. */
|
||||||
if (copy_function != 0)
|
if (copy_function != 0)
|
||||||
USAGE_ERROR ((0, 0, _("Mode already defined")));
|
error (PAXEXIT_FAILURE, 0, _("Mode already defined"));
|
||||||
copy_function = process_copy_in;
|
copy_function = process_copy_in;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -394,17 +429,21 @@ crc newc odc bin ustar tar (all-caps also recognized)"), arg);
|
|||||||
case NO_ABSOLUTE_FILENAMES_OPTION: /* --no-absolute-filenames */
|
case NO_ABSOLUTE_FILENAMES_OPTION: /* --no-absolute-filenames */
|
||||||
no_abs_paths_flag = true;
|
no_abs_paths_flag = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ABSOLUTE_FILENAMES_OPTION: /* --absolute-filenames */
|
||||||
|
no_abs_paths_flag = false;
|
||||||
|
break;
|
||||||
|
|
||||||
case NO_PRESERVE_OWNER_OPTION: /* --no-preserve-owner */
|
case NO_PRESERVE_OWNER_OPTION: /* --no-preserve-owner */
|
||||||
if (set_owner_flag || set_group_flag)
|
if (set_owner_flag || set_group_flag)
|
||||||
USAGE_ERROR ((0, 0,
|
error (PAXEXIT_FAILURE, 0,
|
||||||
_("--no-preserve-owner cannot be used with --owner")));
|
_("--no-preserve-owner cannot be used with --owner"));
|
||||||
no_chown_flag = true;
|
no_chown_flag = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'o': /* Copy-out mode. */
|
case 'o': /* Copy-out mode. */
|
||||||
if (copy_function != 0)
|
if (copy_function != 0)
|
||||||
USAGE_ERROR ((0, 0, _("Mode already defined")));
|
error (PAXEXIT_FAILURE, 0, _("Mode already defined"));
|
||||||
copy_function = process_copy_out;
|
copy_function = process_copy_out;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -418,7 +457,7 @@ crc newc odc bin ustar tar (all-caps also recognized)"), arg);
|
|||||||
|
|
||||||
case 'p': /* Copy-pass mode. */
|
case 'p': /* Copy-pass mode. */
|
||||||
if (copy_function != 0)
|
if (copy_function != 0)
|
||||||
USAGE_ERROR ((0, 0, _("Mode already defined")));
|
error (PAXEXIT_FAILURE, 0, _("Mode already defined"));
|
||||||
copy_function = process_copy_pass;
|
copy_function = process_copy_pass;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -440,25 +479,26 @@ crc newc odc bin ustar tar (all-caps also recognized)"), arg);
|
|||||||
|
|
||||||
case 'R': /* Set the owner. */
|
case 'R': /* Set the owner. */
|
||||||
if (no_chown_flag)
|
if (no_chown_flag)
|
||||||
USAGE_ERROR ((0, 0,
|
error (PAXEXIT_FAILURE, 0,
|
||||||
_("--owner cannot be used with --no-preserve-owner")));
|
_("--owner cannot be used with --no-preserve-owner"));
|
||||||
{
|
else
|
||||||
char *e, *u, *g;
|
{
|
||||||
|
char *e, *u, *g;
|
||||||
e = parse_user_spec (arg, &set_owner, &set_group, &u, &g);
|
|
||||||
if (e)
|
e = parse_user_spec (arg, &set_owner, &set_group, &u, &g);
|
||||||
error (2, 0, "%s: %s", arg, e);
|
if (e)
|
||||||
if (u)
|
error (PAXEXIT_FAILURE, 0, "%s: %s", arg, e);
|
||||||
{
|
if (u)
|
||||||
free (u);
|
{
|
||||||
set_owner_flag = true;
|
free (u);
|
||||||
}
|
set_owner_flag = true;
|
||||||
if (g)
|
}
|
||||||
{
|
if (g)
|
||||||
free (g);
|
{
|
||||||
set_group_flag = true;
|
free (g);
|
||||||
}
|
set_group_flag = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's': /* Swap bytes. */
|
case 's': /* Swap bytes. */
|
||||||
@ -507,6 +547,12 @@ crc newc odc bin ustar tar (all-caps also recognized)"), arg);
|
|||||||
case TO_STDOUT_OPTION:
|
case TO_STDOUT_OPTION:
|
||||||
to_stdout_option = true;
|
to_stdout_option = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case HANG_OPTION:
|
||||||
|
_argp_hang = atoi (arg ? arg : "3600");
|
||||||
|
while (_argp_hang-- > 0)
|
||||||
|
sleep (1);
|
||||||
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
|
argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
|
||||||
@ -552,9 +598,9 @@ process_args (int argc, char *argv[])
|
|||||||
int index;
|
int index;
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
USAGE_ERROR ((0, 0,
|
error (PAXEXIT_FAILURE, 0,
|
||||||
_("You must specify one of -oipt options.\nTry `%s --help' or `%s --usage' for more information.\n"),
|
_("You must specify one of -oipt options.\nTry `%s --help' or `%s --usage' for more information.\n"),
|
||||||
program_name, program_name));
|
program_name, program_name);
|
||||||
|
|
||||||
xstat = lstat;
|
xstat = lstat;
|
||||||
|
|
||||||
@ -568,9 +614,9 @@ process_args (int argc, char *argv[])
|
|||||||
if (table_flag)
|
if (table_flag)
|
||||||
copy_function = process_copy_in;
|
copy_function = process_copy_in;
|
||||||
else
|
else
|
||||||
USAGE_ERROR ((0, 0,
|
error (PAXEXIT_FAILURE, 0,
|
||||||
_("You must specify one of -oipt options.\nTry `%s --help' or `%s --usage' for more information.\n"),
|
_("You must specify one of -oipt options.\nTry `%s --help' or `%s --usage' for more information.\n"),
|
||||||
program_name, program_name));
|
program_name, program_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Work around for pcc bug. */
|
/* Work around for pcc bug. */
|
||||||
@ -584,7 +630,6 @@ process_args (int argc, char *argv[])
|
|||||||
CHECK_USAGE(reset_time_flag, "--reset", "--extract");
|
CHECK_USAGE(reset_time_flag, "--reset", "--extract");
|
||||||
CHECK_USAGE(xstat != lstat, "--dereference", "--extract");
|
CHECK_USAGE(xstat != lstat, "--dereference", "--extract");
|
||||||
CHECK_USAGE(append_flag, "--append", "--extract");
|
CHECK_USAGE(append_flag, "--append", "--extract");
|
||||||
CHECK_USAGE(sparse_flag, "--sparse", "--extract");
|
|
||||||
CHECK_USAGE(output_archive_name, "-O", "--extract");
|
CHECK_USAGE(output_archive_name, "-O", "--extract");
|
||||||
if (to_stdout_option)
|
if (to_stdout_option)
|
||||||
{
|
{
|
||||||
@ -597,7 +642,8 @@ process_args (int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (archive_name && input_archive_name)
|
if (archive_name && input_archive_name)
|
||||||
USAGE_ERROR((0, 0, _("Both -I and -F are used in copy-in mode")));
|
error (PAXEXIT_FAILURE, 0,
|
||||||
|
_("Both -I and -F are used in copy-in mode"));
|
||||||
|
|
||||||
if (archive_format == arf_crcascii)
|
if (archive_format == arf_crcascii)
|
||||||
crc_i_flag = true;
|
crc_i_flag = true;
|
||||||
@ -609,7 +655,7 @@ process_args (int argc, char *argv[])
|
|||||||
else if (copy_function == copy_out)
|
else if (copy_function == copy_out)
|
||||||
{
|
{
|
||||||
if (index != argc)
|
if (index != argc)
|
||||||
USAGE_ERROR ((0, 0, _("Too many arguments")));
|
error (PAXEXIT_FAILURE, 0, _("Too many arguments"));
|
||||||
|
|
||||||
archive_des = 1;
|
archive_des = 1;
|
||||||
CHECK_USAGE(create_dir_flag, "--make-directories", "--create");
|
CHECK_USAGE(create_dir_flag, "--make-directories", "--create");
|
||||||
@ -617,24 +663,24 @@ process_args (int argc, char *argv[])
|
|||||||
CHECK_USAGE(table_flag, "--list", "--create");
|
CHECK_USAGE(table_flag, "--list", "--create");
|
||||||
CHECK_USAGE(unconditional_flag, "--unconditional", "--create");
|
CHECK_USAGE(unconditional_flag, "--unconditional", "--create");
|
||||||
CHECK_USAGE(link_flag, "--link", "--create");
|
CHECK_USAGE(link_flag, "--link", "--create");
|
||||||
|
CHECK_USAGE(sparse_flag, "--sparse", "--create");
|
||||||
CHECK_USAGE(retain_time_flag, "--preserve-modification-time",
|
CHECK_USAGE(retain_time_flag, "--preserve-modification-time",
|
||||||
"--create");
|
"--create");
|
||||||
CHECK_USAGE(no_chown_flag, "--no-preserve-owner", "--create");
|
CHECK_USAGE(no_chown_flag, "--no-preserve-owner", "--create");
|
||||||
CHECK_USAGE(set_owner_flag||set_group_flag, "--owner", "--create");
|
|
||||||
CHECK_USAGE(swap_bytes_flag, "--swap-bytes (--swap)", "--create");
|
CHECK_USAGE(swap_bytes_flag, "--swap-bytes (--swap)", "--create");
|
||||||
CHECK_USAGE(swap_halfwords_flag, "--swap-halfwords (--swap)",
|
CHECK_USAGE(swap_halfwords_flag, "--swap-halfwords (--swap)",
|
||||||
"--create");
|
"--create");
|
||||||
CHECK_USAGE(to_stdout_option, "--to-stdout", "--create");
|
CHECK_USAGE(to_stdout_option, "--to-stdout", "--create");
|
||||||
|
|
||||||
if (append_flag && !(archive_name || output_archive_name))
|
if (append_flag && !(archive_name || output_archive_name))
|
||||||
USAGE_ERROR ((0, 0,
|
error (PAXEXIT_FAILURE, 0,
|
||||||
_("--append is used but no archive file name is given (use -F or -O options")));
|
_("--append is used but no archive file name is given (use -F or -O options)"));
|
||||||
|
|
||||||
CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--create");
|
CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--create");
|
||||||
CHECK_USAGE(no_abs_paths_flag, "--no-absolute-pathnames", "--create");
|
|
||||||
CHECK_USAGE(input_archive_name, "-I", "--create");
|
CHECK_USAGE(input_archive_name, "-I", "--create");
|
||||||
if (archive_name && output_archive_name)
|
if (archive_name && output_archive_name)
|
||||||
USAGE_ERROR ((0, 0, _("Both -O and -F are used in copy-out mode")));
|
error (PAXEXIT_FAILURE, 0,
|
||||||
|
_("Both -O and -F are used in copy-out mode"));
|
||||||
|
|
||||||
if (archive_format == arf_unknown)
|
if (archive_format == arf_unknown)
|
||||||
archive_format = arf_binary;
|
archive_format = arf_binary;
|
||||||
@ -644,12 +690,14 @@ process_args (int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Copy pass. */
|
/* Copy pass. */
|
||||||
if (index != argc - 1)
|
if (index < argc - 1)
|
||||||
USAGE_ERROR ((0, 0, _("Too many arguments")));
|
error (PAXEXIT_FAILURE, 0, _("Too many arguments"));
|
||||||
|
else if (index > argc - 1)
|
||||||
|
error (PAXEXIT_FAILURE, 0, _("Not enough arguments"));
|
||||||
|
|
||||||
if (archive_format != arf_unknown)
|
if (archive_format != arf_unknown)
|
||||||
USAGE_ERROR((0, 0,
|
error (PAXEXIT_FAILURE, 0,
|
||||||
_("Archive format is not specified in copy-pass mode (use --format option)")));
|
_("Archive format is not specified in copy-pass mode (use --format option)"));
|
||||||
|
|
||||||
CHECK_USAGE(swap_bytes_flag, "--swap-bytes (--swap)", "--pass-through");
|
CHECK_USAGE(swap_bytes_flag, "--swap-bytes (--swap)", "--pass-through");
|
||||||
CHECK_USAGE(swap_halfwords_flag, "--swap-halfwords (--swap)",
|
CHECK_USAGE(swap_halfwords_flag, "--swap-halfwords (--swap)",
|
||||||
@ -660,6 +708,8 @@ process_args (int argc, char *argv[])
|
|||||||
CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--pass-through");
|
CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--pass-through");
|
||||||
CHECK_USAGE(no_abs_paths_flag, "--no-absolute-pathnames",
|
CHECK_USAGE(no_abs_paths_flag, "--no-absolute-pathnames",
|
||||||
"--pass-through");
|
"--pass-through");
|
||||||
|
CHECK_USAGE(no_abs_paths_flag, "--absolute-pathnames",
|
||||||
|
"--pass-through");
|
||||||
CHECK_USAGE(to_stdout_option, "--to-stdout", "--pass-through");
|
CHECK_USAGE(to_stdout_option, "--to-stdout", "--pass-through");
|
||||||
|
|
||||||
directory_name = argv[index];
|
directory_name = argv[index];
|
||||||
@ -668,11 +718,12 @@ process_args (int argc, char *argv[])
|
|||||||
if (archive_name)
|
if (archive_name)
|
||||||
{
|
{
|
||||||
if (copy_function != copy_in && copy_function != copy_out)
|
if (copy_function != copy_in && copy_function != copy_out)
|
||||||
USAGE_ERROR ((0, 0,
|
error (PAXEXIT_FAILURE, 0,
|
||||||
_("-F can be used only with --create or --extract")));
|
_("-F can be used only with --create or --extract"));
|
||||||
archive_des = open_archive (archive_name);
|
archive_des = open_archive (archive_name);
|
||||||
if (archive_des < 0)
|
if (archive_des < 0)
|
||||||
error (1, errno, "%s", archive_name);
|
error (PAXEXIT_FAILURE, errno, _("Cannot open %s"),
|
||||||
|
quotearg_colon (archive_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prevent SysV non-root users from giving away files inadvertantly.
|
/* Prevent SysV non-root users from giving away files inadvertantly.
|
||||||
@ -725,33 +776,19 @@ initialize_buffers ()
|
|||||||
out_buff = output_buffer;
|
out_buff = output_buffer;
|
||||||
output_size = 0;
|
output_size = 0;
|
||||||
output_bytes = 0;
|
output_bytes = 0;
|
||||||
|
|
||||||
/* Clear the block of zeros. */
|
|
||||||
bzero (zeros_512, 512);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LOCALE_H
|
|
||||||
setlocale (LC_ALL, "");
|
setlocale (LC_ALL, "");
|
||||||
#endif
|
|
||||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||||
textdomain (PACKAGE);
|
textdomain (PACKAGE);
|
||||||
|
|
||||||
program_name = argv[0];
|
program_name = argv[0];
|
||||||
umask (0);
|
|
||||||
|
|
||||||
#ifdef __TURBOC__
|
|
||||||
_fmode = O_BINARY; /* Put stdin and stdout in binary mode. */
|
|
||||||
#endif
|
|
||||||
#ifdef __EMX__ /* gcc on OS/2. */
|
|
||||||
_response (&argc, &argv);
|
|
||||||
_wildcard (&argc, &argv);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
process_args (argc, argv);
|
process_args (argc, argv);
|
||||||
|
|
||||||
initialize_buffers ();
|
initialize_buffers ();
|
||||||
|
|
||||||
(*copy_function) ();
|
(*copy_function) ();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* makepath.c -- Ensure that a directory path exists.
|
/* makepath.c -- Ensure that a directory path exists.
|
||||||
Copyright (C) 1990 Free Software Foundation, Inc.
|
Copyright (C) 1990, 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -11,9 +11,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu> and
|
/* Written by David MacKenzie <djm@gnu.ai.mit.edu> and
|
||||||
Jim Meyering <meyering@cs.utexas.edu>. */
|
Jim Meyering <meyering@cs.utexas.edu>. */
|
||||||
@ -23,46 +24,11 @@
|
|||||||
come together again in the future. */
|
come together again in the future. */
|
||||||
|
|
||||||
#include <system.h>
|
#include <system.h>
|
||||||
|
#include <paxlib.h>
|
||||||
#ifdef __GNUC__
|
|
||||||
#define alloca __builtin_alloca
|
|
||||||
#else
|
|
||||||
#ifdef HAVE_ALLOCA_H
|
|
||||||
#include <alloca.h>
|
|
||||||
#else
|
|
||||||
#ifdef _AIX
|
|
||||||
#pragma alloca
|
|
||||||
#else
|
|
||||||
char *alloca ();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#if !defined(S_ISDIR) && defined(S_IFDIR)
|
|
||||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#ifdef STDC_HEADERS
|
|
||||||
#include <stdlib.h>
|
|
||||||
#else
|
|
||||||
extern int errno;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
|
|
||||||
#include <string.h>
|
|
||||||
#ifndef index
|
|
||||||
#define index strchr
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#include <strings.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Ensure that the directory ARGPATH exists.
|
/* Ensure that the directory ARGPATH exists.
|
||||||
Remove any trailing slashes from ARGPATH before calling this function.
|
Remove any trailing slashes from ARGPATH before calling this function.
|
||||||
@ -126,7 +92,7 @@ make_path (char *argpath,
|
|||||||
slash = dirpath;
|
slash = dirpath;
|
||||||
while (*slash == '/')
|
while (*slash == '/')
|
||||||
slash++;
|
slash++;
|
||||||
while ((slash = index (slash, '/')))
|
while ((slash = strchr (slash, '/')))
|
||||||
{
|
{
|
||||||
#ifdef HPUX_CDF
|
#ifdef HPUX_CDF
|
||||||
int iscdf;
|
int iscdf;
|
||||||
@ -164,7 +130,7 @@ make_path (char *argpath,
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", dirpath);
|
chown_error_details (dirpath, owner, group);
|
||||||
retval = 1;
|
retval = 1;
|
||||||
}
|
}
|
||||||
if (re_protect)
|
if (re_protect)
|
||||||
@ -231,23 +197,23 @@ make_path (char *argpath,
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", dirpath);
|
chown_error_details (dirpath, owner, group);
|
||||||
retval = 1;
|
retval = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* chown may have turned off some permission bits we wanted. */
|
/* chown may have turned off some permission bits we wanted. */
|
||||||
if ((mode & 07000) != 0 && chmod (dirpath, mode))
|
if ((mode & 07000) != 0 && chmod (dirpath, mode))
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", dirpath);
|
chmod_error_details (dirpath, mode);
|
||||||
retval = 1;
|
retval = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the mode for leading directories didn't include owner "wx"
|
/* If the mode for leading directories didn't include owner "wx"
|
||||||
privileges, we have to reset their protections to the correct
|
privileges, we have to reset their protections to the correct
|
||||||
value. */
|
value. */
|
||||||
for (p = leading_dirs; p != NULL; p = p->next)
|
for (p = leading_dirs; p != NULL; p = p->next)
|
||||||
{
|
{
|
||||||
*(p->dirname_end) = '\0';
|
*p->dirname_end = '\0';
|
||||||
#if 0
|
#if 0
|
||||||
/* cpio always calls make_path with parent mode 0700, so
|
/* cpio always calls make_path with parent mode 0700, so
|
||||||
we don't have to do this. If we ever do have to do this,
|
we don't have to do this. If we ever do have to do this,
|
||||||
@ -255,7 +221,7 @@ make_path (char *argpath,
|
|||||||
bit so we don't break HP CDF's. */
|
bit so we don't break HP CDF's. */
|
||||||
if (chmod (dirpath, parent_mode))
|
if (chmod (dirpath, parent_mode))
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", dirpath);
|
chmod_error_details (dirpath, parent_mode);
|
||||||
retval = 1;
|
retval = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -286,12 +252,12 @@ make_path (char *argpath,
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", dirpath);
|
chown_error_details (dirpath, owner, group);
|
||||||
retval = 1;
|
retval = 1;
|
||||||
}
|
}
|
||||||
if (chmod (dirpath, mode))
|
if (chmod (dirpath, mode))
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", dirpath);
|
chmod_error_details (dirpath, mode);
|
||||||
retval = 1;
|
retval = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
63
src/tar.c
63
src/tar.c
@ -1,5 +1,5 @@
|
|||||||
/* tar.c - read in write tar headers for cpio
|
/* tar.c - read in write tar headers for cpio
|
||||||
Copyright (C) 1992, 2001, 2004 Free Software Foundation, Inc.
|
Copyright (C) 1992, 2001, 2004, 2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -11,9 +11,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
#include <system.h>
|
#include <system.h>
|
||||||
|
|
||||||
@ -112,10 +113,10 @@ to_oct (register long value, register int digits, register char *where)
|
|||||||
/* Compute and return a checksum for TAR_HDR,
|
/* Compute and return a checksum for TAR_HDR,
|
||||||
counting the checksum bytes as if they were spaces. */
|
counting the checksum bytes as if they were spaces. */
|
||||||
|
|
||||||
unsigned long
|
unsigned int
|
||||||
tar_checksum (struct tar_header *tar_hdr)
|
tar_checksum (struct tar_header *tar_hdr)
|
||||||
{
|
{
|
||||||
unsigned long sum = 0;
|
unsigned int sum = 0;
|
||||||
char *p = (char *) tar_hdr;
|
char *p = (char *) tar_hdr;
|
||||||
char *q = p + TARRECORDSIZE;
|
char *q = p + TARRECORDSIZE;
|
||||||
int i;
|
int i;
|
||||||
@ -136,13 +137,13 @@ tar_checksum (struct tar_header *tar_hdr)
|
|||||||
descriptor OUT_DES. */
|
descriptor OUT_DES. */
|
||||||
|
|
||||||
void
|
void
|
||||||
write_out_tar_header (struct new_cpio_header *file_hdr, int out_des)
|
write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des)
|
||||||
{
|
{
|
||||||
int name_len;
|
int name_len;
|
||||||
union tar_record tar_rec;
|
union tar_record tar_rec;
|
||||||
struct tar_header *tar_hdr = (struct tar_header *) &tar_rec;
|
struct tar_header *tar_hdr = (struct tar_header *) &tar_rec;
|
||||||
|
|
||||||
bzero ((char *) &tar_rec, TARRECORDSIZE);
|
memset (&tar_rec, 0, sizeof tar_rec);
|
||||||
|
|
||||||
/* process_copy_out must ensure that file_hdr->c_name is short enough,
|
/* process_copy_out must ensure that file_hdr->c_name is short enough,
|
||||||
or we will lose here. */
|
or we will lose here. */
|
||||||
@ -254,7 +255,7 @@ null_block (long *block, int size)
|
|||||||
into FILE_HDR. */
|
into FILE_HDR. */
|
||||||
|
|
||||||
void
|
void
|
||||||
read_in_tar_header (struct new_cpio_header *file_hdr, int in_des)
|
read_in_tar_header (struct cpio_file_stat *file_hdr, int in_des)
|
||||||
{
|
{
|
||||||
long bytes_skipped = 0;
|
long bytes_skipped = 0;
|
||||||
int warned = false;
|
int warned = false;
|
||||||
@ -280,7 +281,7 @@ read_in_tar_header (struct new_cpio_header *file_hdr, int in_des)
|
|||||||
if (null_block ((long *) &tar_rec, TARRECORDSIZE))
|
if (null_block ((long *) &tar_rec, TARRECORDSIZE))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
file_hdr->c_name = "TRAILER!!!";
|
file_hdr->c_name = CPIO_TRAILER_NAME;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
@ -290,7 +291,7 @@ read_in_tar_header (struct new_cpio_header *file_hdr, int in_des)
|
|||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
otoa (tar_hdr->chksum, &file_hdr->c_chksum);
|
file_hdr->c_chksum = FROM_OCTAL (tar_hdr->chksum);
|
||||||
|
|
||||||
if (file_hdr->c_chksum != tar_checksum (tar_hdr))
|
if (file_hdr->c_chksum != tar_checksum (tar_hdr))
|
||||||
{
|
{
|
||||||
@ -307,8 +308,7 @@ read_in_tar_header (struct new_cpio_header *file_hdr, int in_des)
|
|||||||
error (0, 0, _("invalid header: checksum error"));
|
error (0, 0, _("invalid header: checksum error"));
|
||||||
warned = true;
|
warned = true;
|
||||||
}
|
}
|
||||||
bcopy (((char *) &tar_rec) + 1, (char *) &tar_rec,
|
memmove (&tar_rec, ((char *) &tar_rec) + 1, TARRECORDSIZE - 1);
|
||||||
TARRECORDSIZE - 1);
|
|
||||||
tape_buffered_read (((char *) &tar_rec) + (TARRECORDSIZE - 1), in_des, 1);
|
tape_buffered_read (((char *) &tar_rec) + (TARRECORDSIZE - 1), in_des, 1);
|
||||||
++bytes_skipped;
|
++bytes_skipped;
|
||||||
continue;
|
continue;
|
||||||
@ -319,7 +319,7 @@ read_in_tar_header (struct new_cpio_header *file_hdr, int in_des)
|
|||||||
else
|
else
|
||||||
file_hdr->c_name = stash_tar_filename (tar_hdr->prefix, tar_hdr->name);
|
file_hdr->c_name = stash_tar_filename (tar_hdr->prefix, tar_hdr->name);
|
||||||
file_hdr->c_nlink = 1;
|
file_hdr->c_nlink = 1;
|
||||||
otoa (tar_hdr->mode, &file_hdr->c_mode);
|
file_hdr->c_mode = FROM_OCTAL (tar_hdr->mode);
|
||||||
file_hdr->c_mode = file_hdr->c_mode & 07777;
|
file_hdr->c_mode = file_hdr->c_mode & 07777;
|
||||||
/* Debian hack: This version of cpio uses the -n flag also to extract
|
/* Debian hack: This version of cpio uses the -n flag also to extract
|
||||||
tar archives using the numeric UID/GID instead of the user/group
|
tar archives using the numeric UID/GID instead of the user/group
|
||||||
@ -328,17 +328,17 @@ read_in_tar_header (struct new_cpio_header *file_hdr, int in_des)
|
|||||||
&& (uidp = getuidbyname (tar_hdr->uname)))
|
&& (uidp = getuidbyname (tar_hdr->uname)))
|
||||||
file_hdr->c_uid = *uidp;
|
file_hdr->c_uid = *uidp;
|
||||||
else
|
else
|
||||||
otoa (tar_hdr->uid, &file_hdr->c_uid);
|
file_hdr->c_uid = FROM_OCTAL (tar_hdr->uid);
|
||||||
|
|
||||||
if (archive_format == arf_ustar && !numeric_uid
|
if (archive_format == arf_ustar && !numeric_uid
|
||||||
&& (gidp = getgidbyname (tar_hdr->gname)))
|
&& (gidp = getgidbyname (tar_hdr->gname)))
|
||||||
file_hdr->c_gid = *gidp;
|
file_hdr->c_gid = *gidp;
|
||||||
else
|
else
|
||||||
otoa (tar_hdr->gid, &file_hdr->c_gid);
|
file_hdr->c_gid = FROM_OCTAL (tar_hdr->gid);
|
||||||
otoa (tar_hdr->size, &file_hdr->c_filesize);
|
file_hdr->c_filesize = FROM_OCTAL (tar_hdr->size);
|
||||||
otoa (tar_hdr->mtime, &file_hdr->c_mtime);
|
file_hdr->c_mtime = FROM_OCTAL (tar_hdr->mtime);
|
||||||
otoa (tar_hdr->devmajor, (unsigned long *) &file_hdr->c_rdev_maj);
|
file_hdr->c_rdev_maj = FROM_OCTAL (tar_hdr->devmajor);
|
||||||
otoa (tar_hdr->devminor, (unsigned long *) &file_hdr->c_rdev_min);
|
file_hdr->c_rdev_min = FROM_OCTAL (tar_hdr->devminor);
|
||||||
file_hdr->c_tar_linkname = NULL;
|
file_hdr->c_tar_linkname = NULL;
|
||||||
|
|
||||||
switch (tar_hdr->typeflag)
|
switch (tar_hdr->typeflag)
|
||||||
@ -409,26 +409,6 @@ read_in_tar_header (struct new_cpio_header *file_hdr, int in_des)
|
|||||||
warn_junk_bytes (bytes_skipped);
|
warn_junk_bytes (bytes_skipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the string of octal digits S into a number and store
|
|
||||||
it in *N. Return nonzero if the whole string was converted,
|
|
||||||
zero if there was something after the number.
|
|
||||||
Skip leading and trailing spaces. */
|
|
||||||
|
|
||||||
int
|
|
||||||
otoa (char *s, unsigned long *n)
|
|
||||||
{
|
|
||||||
unsigned long val = 0;
|
|
||||||
|
|
||||||
while (*s == ' ')
|
|
||||||
++s;
|
|
||||||
while (*s >= '0' && *s <= '7')
|
|
||||||
val = 8 * val + *s++ - '0';
|
|
||||||
while (*s == ' ')
|
|
||||||
++s;
|
|
||||||
*n = val;
|
|
||||||
return *s == '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return
|
/* Return
|
||||||
2 if BUF is a valid POSIX tar header (the checksum is correct
|
2 if BUF is a valid POSIX tar header (the checksum is correct
|
||||||
and it has the "ustar" magic string),
|
and it has the "ustar" magic string),
|
||||||
@ -441,7 +421,7 @@ is_tar_header (char *buf)
|
|||||||
struct tar_header *tar_hdr = (struct tar_header *) buf;
|
struct tar_header *tar_hdr = (struct tar_header *) buf;
|
||||||
unsigned long chksum;
|
unsigned long chksum;
|
||||||
|
|
||||||
otoa (tar_hdr->chksum, &chksum);
|
chksum = FROM_OCTAL (tar_hdr->chksum);
|
||||||
|
|
||||||
if (chksum != tar_checksum (tar_hdr))
|
if (chksum != tar_checksum (tar_hdr))
|
||||||
return 0;
|
return 0;
|
||||||
@ -473,7 +453,6 @@ is_tar_filename_too_long (char *name)
|
|||||||
{
|
{
|
||||||
int whole_name_len;
|
int whole_name_len;
|
||||||
int prefix_name_len;
|
int prefix_name_len;
|
||||||
char *p;
|
|
||||||
|
|
||||||
whole_name_len = strlen (name);
|
whole_name_len = strlen (name);
|
||||||
if (whole_name_len <= TARNAMESIZE)
|
if (whole_name_len <= TARNAMESIZE)
|
||||||
|
@ -14,10 +14,10 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
Library General Public License for more details.
|
Library General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
You should have received a copy of the GNU Library General
|
||||||
License along with this library; see the file COPYING.LIB. If
|
Public License along with this library; see the file COPYING.LIB.
|
||||||
not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Street, Fifth Floor, Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
#ifndef _TAR_H
|
#ifndef _TAR_H
|
||||||
|
|
||||||
|
@ -11,9 +11,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
#ifndef _TARHDR_H
|
#ifndef _TARHDR_H
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* userspec.c -- Parse a user and group string.
|
/* userspec.c -- Parse a user and group string.
|
||||||
Copyright (C) 1989, 1990, 1991, 1992, 2001, 2004 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1990, 1991, 1992, 2001,
|
||||||
|
2004, 2005 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -11,9 +12,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||||
|
|
||||||
@ -72,7 +74,7 @@ extern struct group *getgrgid (gid_t gid);
|
|||||||
otherwise return 0. */
|
otherwise return 0. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
isnumber (const char *str)
|
isnumber_p (const char *str)
|
||||||
{
|
{
|
||||||
for (; *str; str++)
|
for (; *str; str++)
|
||||||
if (!isdigit (*str))
|
if (!isdigit (*str))
|
||||||
@ -111,9 +113,9 @@ parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
|
|||||||
V_STRDUP (spec, spec_arg);
|
V_STRDUP (spec, spec_arg);
|
||||||
|
|
||||||
/* Find the separator if there is one. */
|
/* Find the separator if there is one. */
|
||||||
separator = index (spec, ':');
|
separator = strchr (spec, ':');
|
||||||
if (separator == NULL)
|
if (separator == NULL)
|
||||||
separator = index (spec, '.');
|
separator = strchr (spec, '.');
|
||||||
|
|
||||||
/* Replace separator with a NUL. */
|
/* Replace separator with a NUL. */
|
||||||
if (separator != NULL)
|
if (separator != NULL)
|
||||||
@ -136,7 +138,7 @@ parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
|
|||||||
if (pwd == NULL)
|
if (pwd == NULL)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!isnumber (u))
|
if (!isnumber_p (u))
|
||||||
error_msg = _("invalid user");
|
error_msg = _("invalid user");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -182,7 +184,7 @@ parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
|
|||||||
grp = getgrnam (g);
|
grp = getgrnam (g);
|
||||||
if (grp == NULL)
|
if (grp == NULL)
|
||||||
{
|
{
|
||||||
if (!isnumber (g))
|
if (!isnumber_p (g))
|
||||||
error_msg = _("invalid group");
|
error_msg = _("invalid group");
|
||||||
else
|
else
|
||||||
*gid = atoi (g);
|
*gid = atoi (g);
|
||||||
|
439
src/util.c
439
src/util.c
@ -1,5 +1,6 @@
|
|||||||
/* util.c - Several utility routines for cpio.
|
/* util.c - Several utility routines for cpio.
|
||||||
Copyright (C) 1990, 1991, 1992, 2001, 2004 Free Software Foundation, Inc.
|
Copyright (C) 1990, 1991, 1992, 2001, 2004,
|
||||||
|
2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -11,9 +12,10 @@
|
|||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
License along with this program; if not, write to the Free
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301 USA. */
|
||||||
|
|
||||||
#include <system.h>
|
#include <system.h>
|
||||||
|
|
||||||
@ -23,15 +25,21 @@
|
|||||||
#include "cpiohdr.h"
|
#include "cpiohdr.h"
|
||||||
#include "dstring.h"
|
#include "dstring.h"
|
||||||
#include "extern.h"
|
#include "extern.h"
|
||||||
|
#include <paxlib.h>
|
||||||
|
#include "filetypes.h"
|
||||||
|
#include <safe-read.h>
|
||||||
|
#include <full-write.h>
|
||||||
#include <rmt.h>
|
#include <rmt.h>
|
||||||
|
#include <hash.h>
|
||||||
|
#include <utimens.h>
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
#ifdef HAVE_SYS_MTIO_H
|
#ifdef HAVE_SYS_MTIO_H
|
||||||
#ifdef HAVE_SYS_IO_TRIOCTL_H
|
# ifdef HAVE_SYS_IO_TRIOCTL_H
|
||||||
#include <sys/io/trioctl.h>
|
# include <sys/io/trioctl.h>
|
||||||
#endif
|
# endif
|
||||||
#include <sys/mtio.h>
|
# include <sys/mtio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !HAVE_DECL_ERRNO
|
#if !HAVE_DECL_ERRNO
|
||||||
@ -90,6 +98,8 @@ tape_empty_output_buffer (int out_des)
|
|||||||
output_size = 0;
|
output_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sparse_write (int fildes, char *buf, unsigned int nbyte);
|
||||||
|
|
||||||
/* Write `output_size' bytes of `output_buffer' to file
|
/* Write `output_size' bytes of `output_buffer' to file
|
||||||
descriptor OUT_DES and reset `output_size' and `out_buff'.
|
descriptor OUT_DES and reset `output_size' and `out_buff'.
|
||||||
If `swapping_halfwords' or `swapping_bytes' is set,
|
If `swapping_halfwords' or `swapping_bytes' is set,
|
||||||
@ -207,7 +217,7 @@ tape_fill_input_buffer (int in_des, int num_bytes)
|
|||||||
Exit with an error if end of file is reached. */
|
Exit with an error if end of file is reached. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
disk_fill_input_buffer (int in_des, int num_bytes)
|
disk_fill_input_buffer (int in_des, off_t num_bytes)
|
||||||
{
|
{
|
||||||
in_buff = input_buffer;
|
in_buff = input_buffer;
|
||||||
num_bytes = (num_bytes < DISK_IO_BLOCK_SIZE) ? num_bytes : DISK_IO_BLOCK_SIZE;
|
num_bytes = (num_bytes < DISK_IO_BLOCK_SIZE) ? num_bytes : DISK_IO_BLOCK_SIZE;
|
||||||
@ -227,10 +237,10 @@ disk_fill_input_buffer (int in_des, int num_bytes)
|
|||||||
When `out_buff' fills up, flush it to file descriptor OUT_DES. */
|
When `out_buff' fills up, flush it to file descriptor OUT_DES. */
|
||||||
|
|
||||||
void
|
void
|
||||||
tape_buffered_write (char *in_buf, int out_des, long num_bytes)
|
tape_buffered_write (char *in_buf, int out_des, off_t num_bytes)
|
||||||
{
|
{
|
||||||
register long bytes_left = num_bytes; /* Bytes needing to be copied. */
|
off_t bytes_left = num_bytes; /* Bytes needing to be copied. */
|
||||||
register long space_left; /* Room left in output buffer. */
|
off_t space_left; /* Room left in output buffer. */
|
||||||
|
|
||||||
while (bytes_left > 0)
|
while (bytes_left > 0)
|
||||||
{
|
{
|
||||||
@ -241,7 +251,7 @@ tape_buffered_write (char *in_buf, int out_des, long num_bytes)
|
|||||||
{
|
{
|
||||||
if (bytes_left < space_left)
|
if (bytes_left < space_left)
|
||||||
space_left = bytes_left;
|
space_left = bytes_left;
|
||||||
bcopy (in_buf, out_buff, (unsigned) space_left);
|
memcpy (out_buff, in_buf, (unsigned) space_left);
|
||||||
out_buff += space_left;
|
out_buff += space_left;
|
||||||
output_size += space_left;
|
output_size += space_left;
|
||||||
in_buf += space_left;
|
in_buf += space_left;
|
||||||
@ -254,10 +264,10 @@ tape_buffered_write (char *in_buf, int out_des, long num_bytes)
|
|||||||
When `out_buff' fills up, flush it to file descriptor OUT_DES. */
|
When `out_buff' fills up, flush it to file descriptor OUT_DES. */
|
||||||
|
|
||||||
void
|
void
|
||||||
disk_buffered_write (char *in_buf, int out_des, long num_bytes)
|
disk_buffered_write (char *in_buf, int out_des, off_t num_bytes)
|
||||||
{
|
{
|
||||||
register long bytes_left = num_bytes; /* Bytes needing to be copied. */
|
off_t bytes_left = num_bytes; /* Bytes needing to be copied. */
|
||||||
register long space_left; /* Room left in output buffer. */
|
off_t space_left; /* Room left in output buffer. */
|
||||||
|
|
||||||
while (bytes_left > 0)
|
while (bytes_left > 0)
|
||||||
{
|
{
|
||||||
@ -268,7 +278,7 @@ disk_buffered_write (char *in_buf, int out_des, long num_bytes)
|
|||||||
{
|
{
|
||||||
if (bytes_left < space_left)
|
if (bytes_left < space_left)
|
||||||
space_left = bytes_left;
|
space_left = bytes_left;
|
||||||
bcopy (in_buf, out_buff, (unsigned) space_left);
|
memcpy (out_buff, in_buf, (unsigned) space_left);
|
||||||
out_buff += space_left;
|
out_buff += space_left;
|
||||||
output_size += space_left;
|
output_size += space_left;
|
||||||
in_buf += space_left;
|
in_buf += space_left;
|
||||||
@ -282,10 +292,10 @@ disk_buffered_write (char *in_buf, int out_des, long num_bytes)
|
|||||||
When `in_buff' is exhausted, refill it from file descriptor IN_DES. */
|
When `in_buff' is exhausted, refill it from file descriptor IN_DES. */
|
||||||
|
|
||||||
void
|
void
|
||||||
tape_buffered_read (char *in_buf, int in_des, long num_bytes)
|
tape_buffered_read (char *in_buf, int in_des, off_t num_bytes)
|
||||||
{
|
{
|
||||||
register long bytes_left = num_bytes; /* Bytes needing to be copied. */
|
off_t bytes_left = num_bytes; /* Bytes needing to be copied. */
|
||||||
register long space_left; /* Bytes to copy from input buffer. */
|
off_t space_left; /* Bytes to copy from input buffer. */
|
||||||
|
|
||||||
while (bytes_left > 0)
|
while (bytes_left > 0)
|
||||||
{
|
{
|
||||||
@ -295,7 +305,7 @@ tape_buffered_read (char *in_buf, int in_des, long num_bytes)
|
|||||||
space_left = bytes_left;
|
space_left = bytes_left;
|
||||||
else
|
else
|
||||||
space_left = input_size;
|
space_left = input_size;
|
||||||
bcopy (in_buff, in_buf, (unsigned) space_left);
|
memcpy (in_buf, in_buff, (unsigned) space_left);
|
||||||
in_buff += space_left;
|
in_buff += space_left;
|
||||||
in_buf += space_left;
|
in_buf += space_left;
|
||||||
input_size -= space_left;
|
input_size -= space_left;
|
||||||
@ -345,7 +355,7 @@ tape_buffered_peek (char *peek_buf, int in_des, int num_bytes)
|
|||||||
first block to make room. */
|
first block to make room. */
|
||||||
int half;
|
int half;
|
||||||
half = input_buffer_size / 2;
|
half = input_buffer_size / 2;
|
||||||
bcopy (input_buffer + half, input_buffer, half);
|
memmove (input_buffer, input_buffer + half, half);
|
||||||
in_buff = in_buff - half;
|
in_buff = in_buff - half;
|
||||||
append_buf = append_buf - half;
|
append_buf = append_buf - half;
|
||||||
}
|
}
|
||||||
@ -369,17 +379,17 @@ tape_buffered_peek (char *peek_buf, int in_des, int num_bytes)
|
|||||||
got_bytes = num_bytes;
|
got_bytes = num_bytes;
|
||||||
else
|
else
|
||||||
got_bytes = input_size;
|
got_bytes = input_size;
|
||||||
bcopy (in_buff, peek_buf, (unsigned) got_bytes);
|
memcpy (peek_buf, in_buff, (unsigned) got_bytes);
|
||||||
return got_bytes;
|
return got_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip the next NUM_BYTES bytes of file descriptor IN_DES. */
|
/* Skip the next NUM_BYTES bytes of file descriptor IN_DES. */
|
||||||
|
|
||||||
void
|
void
|
||||||
tape_toss_input (int in_des, long num_bytes)
|
tape_toss_input (int in_des, off_t num_bytes)
|
||||||
{
|
{
|
||||||
register long bytes_left = num_bytes; /* Bytes needing to be copied. */
|
off_t bytes_left = num_bytes; /* Bytes needing to be copied. */
|
||||||
register long space_left; /* Bytes to copy from input buffer. */
|
off_t space_left; /* Bytes to copy from input buffer. */
|
||||||
|
|
||||||
while (bytes_left > 0)
|
while (bytes_left > 0)
|
||||||
{
|
{
|
||||||
@ -403,18 +413,19 @@ tape_toss_input (int in_des, long num_bytes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
write_nuls_to_file (long num_bytes, int out_des,
|
write_nuls_to_file (off_t num_bytes, int out_des,
|
||||||
void (*writer) (char *in_buf, int out_des, long num_bytes))
|
void (*writer) (char *in_buf, int out_des, off_t num_bytes))
|
||||||
{
|
{
|
||||||
long blocks;
|
off_t blocks;
|
||||||
long extra_bytes;
|
off_t extra_bytes;
|
||||||
long i;
|
off_t i;
|
||||||
|
static char zeros_512[512];
|
||||||
blocks = num_bytes / 512;
|
|
||||||
extra_bytes = num_bytes % 512;
|
blocks = num_bytes / sizeof zeros_512;
|
||||||
|
extra_bytes = num_bytes % sizeof zeros_512;
|
||||||
for (i = 0; i < blocks; ++i)
|
for (i = 0; i < blocks; ++i)
|
||||||
writer (zeros_512, out_des, 512);
|
writer (zeros_512, out_des, sizeof zeros_512);
|
||||||
if (extra_bytes)
|
if (extra_bytes)
|
||||||
writer (zeros_512, out_des, extra_bytes);
|
writer (zeros_512, out_des, extra_bytes);
|
||||||
}
|
}
|
||||||
@ -428,7 +439,7 @@ write_nuls_to_file (long num_bytes, int out_des,
|
|||||||
NUM_BYTES is the number of bytes to copy. */
|
NUM_BYTES is the number of bytes to copy. */
|
||||||
|
|
||||||
void
|
void
|
||||||
copy_files_tape_to_disk (int in_des, int out_des, long num_bytes)
|
copy_files_tape_to_disk (int in_des, int out_des, off_t num_bytes)
|
||||||
{
|
{
|
||||||
long size;
|
long size;
|
||||||
long k;
|
long k;
|
||||||
@ -458,13 +469,13 @@ copy_files_tape_to_disk (int in_des, int out_des, long num_bytes)
|
|||||||
NUM_BYTES is the number of bytes to copy. */
|
NUM_BYTES is the number of bytes to copy. */
|
||||||
|
|
||||||
void
|
void
|
||||||
copy_files_disk_to_tape (int in_des, int out_des, long num_bytes,
|
copy_files_disk_to_tape (int in_des, int out_des, off_t num_bytes,
|
||||||
char *filename)
|
char *filename)
|
||||||
{
|
{
|
||||||
long size;
|
long size;
|
||||||
long k;
|
long k;
|
||||||
int rc;
|
int rc;
|
||||||
long original_num_bytes;
|
off_t original_num_bytes;
|
||||||
|
|
||||||
original_num_bytes = num_bytes;
|
original_num_bytes = num_bytes;
|
||||||
|
|
||||||
@ -472,14 +483,20 @@ copy_files_disk_to_tape (int in_des, int out_des, long num_bytes,
|
|||||||
{
|
{
|
||||||
if (input_size == 0)
|
if (input_size == 0)
|
||||||
if (rc = disk_fill_input_buffer (in_des,
|
if (rc = disk_fill_input_buffer (in_des,
|
||||||
num_bytes < DISK_IO_BLOCK_SIZE ?
|
num_bytes < DISK_IO_BLOCK_SIZE ?
|
||||||
num_bytes : DISK_IO_BLOCK_SIZE))
|
num_bytes : DISK_IO_BLOCK_SIZE))
|
||||||
{
|
{
|
||||||
if (rc > 0)
|
if (rc > 0)
|
||||||
error (0, 0, _("File %s shrunk by %ld bytes, padding with zeros"),
|
{
|
||||||
filename, num_bytes);
|
char buf[UINTMAX_STRSIZE_BOUND];
|
||||||
|
error (0, 0,
|
||||||
|
ngettext ("File %s shrunk by %s byte, padding with zeros",
|
||||||
|
"File %s shrunk by %s bytes, padding with zeros",
|
||||||
|
num_bytes),
|
||||||
|
filename, STRINGIFY_BIGINT (num_bytes, buf));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
error (0, 0, _("Read error at byte %ld in file %s, padding with zeros"),
|
error (0, 0, _("Read error at byte %lld in file %s, padding with zeros"),
|
||||||
original_num_bytes - num_bytes, filename);
|
original_num_bytes - num_bytes, filename);
|
||||||
write_nuls_to_file (num_bytes, out_des, tape_buffered_write);
|
write_nuls_to_file (num_bytes, out_des, tape_buffered_write);
|
||||||
break;
|
break;
|
||||||
@ -505,12 +522,12 @@ copy_files_disk_to_tape (int in_des, int out_des, long num_bytes,
|
|||||||
NUM_BYTES is the number of bytes to copy. */
|
NUM_BYTES is the number of bytes to copy. */
|
||||||
|
|
||||||
void
|
void
|
||||||
copy_files_disk_to_disk (int in_des, int out_des, long num_bytes,
|
copy_files_disk_to_disk (int in_des, int out_des, off_t num_bytes,
|
||||||
char *filename)
|
char *filename)
|
||||||
{
|
{
|
||||||
long size;
|
long size;
|
||||||
long k;
|
long k;
|
||||||
long original_num_bytes;
|
off_t original_num_bytes;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
original_num_bytes = num_bytes;
|
original_num_bytes = num_bytes;
|
||||||
@ -520,10 +537,16 @@ copy_files_disk_to_disk (int in_des, int out_des, long num_bytes,
|
|||||||
if (rc = disk_fill_input_buffer (in_des, num_bytes))
|
if (rc = disk_fill_input_buffer (in_des, num_bytes))
|
||||||
{
|
{
|
||||||
if (rc > 0)
|
if (rc > 0)
|
||||||
error (0, 0, _("File %s shrunk by %ld bytes, padding with zeros"),
|
{
|
||||||
filename, num_bytes);
|
char buf[UINTMAX_STRSIZE_BOUND];
|
||||||
|
error (0, 0,
|
||||||
|
ngettext ("File %s shrunk by %s byte, padding with zeros",
|
||||||
|
"File %s shrunk by %s bytes, padding with zeros",
|
||||||
|
num_bytes),
|
||||||
|
filename, STRINGIFY_BIGINT (num_bytes, buf));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
error (0, 0, _("Read error at byte %ld in file %s, padding with zeros"),
|
error (0, 0, _("Read error at byte %lld in file %s, padding with zeros"),
|
||||||
original_num_bytes - num_bytes, filename);
|
original_num_bytes - num_bytes, filename);
|
||||||
write_nuls_to_file (num_bytes, out_des, disk_buffered_write);
|
write_nuls_to_file (num_bytes, out_des, disk_buffered_write);
|
||||||
break;
|
break;
|
||||||
@ -545,20 +568,23 @@ copy_files_disk_to_disk (int in_des, int out_des, long num_bytes,
|
|||||||
|
|
||||||
void
|
void
|
||||||
warn_if_file_changed (char *file_name, unsigned long old_file_size,
|
warn_if_file_changed (char *file_name, unsigned long old_file_size,
|
||||||
unsigned long old_file_mtime)
|
off_t old_file_mtime)
|
||||||
{
|
{
|
||||||
struct stat new_file_stat;
|
struct stat new_file_stat;
|
||||||
if ((*xstat) (file_name, &new_file_stat) < 0)
|
if ((*xstat) (file_name, &new_file_stat) < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", file_name);
|
stat_error (file_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only check growth, shrinkage detected in copy_files_disk_to_{disk,tape}()
|
/* Only check growth, shrinkage detected in copy_files_disk_to_{disk,tape}()
|
||||||
*/
|
*/
|
||||||
if (new_file_stat.st_size > old_file_size)
|
if (new_file_stat.st_size > old_file_size)
|
||||||
error (0, 0, _("File %s grew, %ld new bytes not copied"),
|
error (0, 0,
|
||||||
file_name, (long)(new_file_stat.st_size - old_file_size));
|
ngettext ("File %s grew, %"PRIuMAX" new byte not copied",
|
||||||
|
"File %s grew, %"PRIuMAX" new bytes not copied",
|
||||||
|
(long)(new_file_stat.st_size - old_file_size)),
|
||||||
|
file_name, (uintmax_t) (new_file_stat.st_size - old_file_size));
|
||||||
|
|
||||||
else if (new_file_stat.st_mtime != old_file_mtime)
|
else if (new_file_stat.st_mtime != old_file_mtime)
|
||||||
error (0, 0, _("File %s was modified while being copied"), file_name);
|
error (0, 0, _("File %s was modified while being copied"), file_name);
|
||||||
@ -658,82 +684,40 @@ struct inode_val
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Inode hash table. Allocated by first call to add_inode. */
|
/* Inode hash table. Allocated by first call to add_inode. */
|
||||||
static struct inode_val **hash_table = NULL;
|
static Hash_table *hash_table = NULL;
|
||||||
|
|
||||||
/* Size of current hash table. Initial size is 47. (47 = 2*22 + 3) */
|
static size_t
|
||||||
static int hash_size = 22;
|
inode_val_hasher (const void *val, size_t n_buckets)
|
||||||
|
{
|
||||||
|
const struct inode_val *ival = val;
|
||||||
|
return ival->inode % n_buckets;
|
||||||
|
}
|
||||||
|
|
||||||
/* Number of elements in current hash table. */
|
static bool
|
||||||
static int hash_num;
|
inode_val_compare (const void *val1, const void *val2)
|
||||||
|
{
|
||||||
/* Find the file name associated with NODE_NUM. If there is no file
|
const struct inode_val *ival1 = val1;
|
||||||
associated with NODE_NUM, return NULL. */
|
const struct inode_val *ival2 = val2;
|
||||||
|
return ival1->inode == ival2->inode
|
||||||
|
&& ival1->major_num == ival2->major_num
|
||||||
|
&& ival1->minor_num == ival2->minor_num;
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
find_inode_file (unsigned long node_num, unsigned long major_num,
|
find_inode_file (unsigned long node_num, unsigned long major_num,
|
||||||
unsigned long minor_num)
|
unsigned long minor_num)
|
||||||
{
|
{
|
||||||
int start; /* Initial hash location. */
|
struct inode_val sample;
|
||||||
int temp; /* Rehash search variable. */
|
struct inode_val *ival;
|
||||||
|
|
||||||
if (hash_table != NULL)
|
if (!hash_table)
|
||||||
{
|
return NULL;
|
||||||
/* Hash function is node number modulo the table size. */
|
|
||||||
start = node_num % hash_size;
|
sample.inode = node_num;
|
||||||
|
sample.major_num = major_num;
|
||||||
/* Initial look into the table. */
|
sample.minor_num = minor_num;
|
||||||
if (hash_table[start] == NULL)
|
ival = hash_lookup (hash_table, &sample);
|
||||||
return NULL;
|
return ival ? ival->file_name : NULL;
|
||||||
if (hash_table[start]->inode == node_num
|
|
||||||
&& hash_table[start]->major_num == major_num
|
|
||||||
&& hash_table[start]->minor_num == minor_num)
|
|
||||||
return hash_table[start]->file_name;
|
|
||||||
|
|
||||||
/* The home position is full with a different inode record.
|
|
||||||
Do a linear search terminated by a NULL pointer. */
|
|
||||||
for (temp = (start + 1) % hash_size;
|
|
||||||
hash_table[temp] != NULL && temp != start;
|
|
||||||
temp = (temp + 1) % hash_size)
|
|
||||||
{
|
|
||||||
if (hash_table[temp]->inode == node_num
|
|
||||||
&& hash_table[start]->major_num == major_num
|
|
||||||
&& hash_table[start]->minor_num == minor_num)
|
|
||||||
return hash_table[temp]->file_name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do the hash insert. Used in normal inserts and resizing the hash
|
|
||||||
table. It is guaranteed that there is room to insert the item.
|
|
||||||
NEW_VALUE is the pointer to the previously allocated inode, file
|
|
||||||
name association record. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
hash_insert (struct inode_val *new_value)
|
|
||||||
{
|
|
||||||
int start; /* Home position for the value. */
|
|
||||||
int temp; /* Used for rehashing. */
|
|
||||||
|
|
||||||
/* Hash function is node number modulo the table size. */
|
|
||||||
start = new_value->inode % hash_size;
|
|
||||||
|
|
||||||
/* Do the initial look into the table. */
|
|
||||||
if (hash_table[start] == NULL)
|
|
||||||
{
|
|
||||||
hash_table[start] = new_value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we get to here, the home position is full with a different inode
|
|
||||||
record. Do a linear search for the first NULL pointer and insert
|
|
||||||
the new item there. */
|
|
||||||
temp = (start + 1) % hash_size;
|
|
||||||
while (hash_table[temp] != NULL)
|
|
||||||
temp = (temp + 1) % hash_size;
|
|
||||||
|
|
||||||
/* Insert at the NULL. */
|
|
||||||
hash_table[temp] = new_value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Associate FILE_NAME with the inode NODE_NUM. (Insert into hash table.) */
|
/* Associate FILE_NAME with the inode NODE_NUM. (Insert into hash table.) */
|
||||||
@ -743,7 +727,8 @@ add_inode (unsigned long node_num, char *file_name, unsigned long major_num,
|
|||||||
unsigned long minor_num)
|
unsigned long minor_num)
|
||||||
{
|
{
|
||||||
struct inode_val *temp;
|
struct inode_val *temp;
|
||||||
|
struct inode_val *e;
|
||||||
|
|
||||||
/* Create new inode record. */
|
/* Create new inode record. */
|
||||||
temp = (struct inode_val *) xmalloc (sizeof (struct inode_val));
|
temp = (struct inode_val *) xmalloc (sizeof (struct inode_val));
|
||||||
temp->inode = node_num;
|
temp->inode = node_num;
|
||||||
@ -751,39 +736,12 @@ add_inode (unsigned long node_num, char *file_name, unsigned long major_num,
|
|||||||
temp->minor_num = minor_num;
|
temp->minor_num = minor_num;
|
||||||
temp->file_name = xstrdup (file_name);
|
temp->file_name = xstrdup (file_name);
|
||||||
|
|
||||||
/* Do we have to increase the size of (or initially allocate)
|
if (!((hash_table
|
||||||
the hash table? */
|
|| (hash_table = hash_initialize (0, 0, inode_val_hasher,
|
||||||
if (hash_num == hash_size || hash_table == NULL)
|
inode_val_compare, 0)))
|
||||||
{
|
&& (e = hash_insert (hash_table, temp))))
|
||||||
struct inode_val **old_table; /* Pointer to old table. */
|
xalloc_die ();
|
||||||
int i; /* Index for re-insert loop. */
|
/* FIXME: e is not used */
|
||||||
|
|
||||||
/* Save old table. */
|
|
||||||
old_table = hash_table;
|
|
||||||
if (old_table == NULL)
|
|
||||||
hash_num = 0;
|
|
||||||
|
|
||||||
/* Calculate new size of table and allocate it.
|
|
||||||
Sequence of table sizes is 47, 97, 197, 397, 797, 1597, 3197, 6397 ...
|
|
||||||
where 3197 and most of the sizes after 6397 are not prime. The other
|
|
||||||
numbers listed are prime. */
|
|
||||||
hash_size = 2 * hash_size + 3;
|
|
||||||
hash_table = (struct inode_val **)
|
|
||||||
xmalloc (hash_size * sizeof (struct inode_val *));
|
|
||||||
bzero (hash_table, hash_size * sizeof (struct inode_val *));
|
|
||||||
|
|
||||||
/* Insert the values from the old table into the new table. */
|
|
||||||
for (i = 0; i < hash_num; i++)
|
|
||||||
hash_insert (old_table[i]);
|
|
||||||
|
|
||||||
if (old_table != NULL)
|
|
||||||
free (old_table);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Insert the new record and increment the count of elements in the
|
|
||||||
hash table. */
|
|
||||||
hash_insert (temp);
|
|
||||||
hash_num++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -800,14 +758,14 @@ open_archive (char *file)
|
|||||||
copy_in = process_copy_in;
|
copy_in = process_copy_in;
|
||||||
|
|
||||||
if (copy_function == copy_in)
|
if (copy_function == copy_in)
|
||||||
fd = rmtopen (file, O_RDONLY | O_BINARY, 0666, rsh_command_option);
|
fd = rmtopen (file, O_RDONLY | O_BINARY, MODE_RW, rsh_command_option);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!append_flag)
|
if (!append_flag)
|
||||||
fd = rmtopen (file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666,
|
fd = rmtopen (file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, MODE_RW,
|
||||||
rsh_command_option);
|
rsh_command_option);
|
||||||
else
|
else
|
||||||
fd = rmtopen (file, O_RDWR | O_BINARY, 0666, rsh_command_option);
|
fd = rmtopen (file, O_RDWR | O_BINARY, MODE_RW, rsh_command_option);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
@ -887,7 +845,7 @@ get_next_reel (int tape_des)
|
|||||||
|
|
||||||
tape_des = open_archive (archive_name);
|
tape_des = open_archive (archive_name);
|
||||||
if (tape_des == -1)
|
if (tape_des == -1)
|
||||||
error (1, errno, "%s", archive_name);
|
open_error (archive_name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -907,7 +865,7 @@ get_next_reel (int tape_des)
|
|||||||
|
|
||||||
tape_des = open_archive (next_archive_name);
|
tape_des = open_archive (next_archive_name);
|
||||||
if (tape_des == -1)
|
if (tape_des == -1)
|
||||||
error (0, errno, "%s", next_archive_name);
|
open_error (next_archive_name);
|
||||||
}
|
}
|
||||||
while (tape_des < 0);
|
while (tape_des < 0);
|
||||||
}
|
}
|
||||||
@ -1003,9 +961,10 @@ umasked_symlink (char *name1, char *name2, int mode)
|
|||||||
|
|
||||||
/* Take an input pathname and check it for CDF's. Insert an extra
|
/* Take an input pathname and check it for CDF's. Insert an extra
|
||||||
`/' in the pathname after each "hidden" directory. If we add
|
`/' in the pathname after each "hidden" directory. If we add
|
||||||
any `/'s, return a malloced string (which it will reuse for
|
any `/'s, return a malloced string instead of the original input
|
||||||
later calls so our caller doesn't have to worry about freeing
|
string.
|
||||||
the string) instead of the original input string. */
|
FIXME: This creates a memory leak.
|
||||||
|
*/
|
||||||
|
|
||||||
char *
|
char *
|
||||||
add_cdf_double_slashes (char *input_name)
|
add_cdf_double_slashes (char *input_name)
|
||||||
@ -1055,7 +1014,7 @@ add_cdf_double_slashes (char *input_name)
|
|||||||
*p = '\0';
|
*p = '\0';
|
||||||
if ((*xstat) (input_name, &dir_stat) < 0)
|
if ((*xstat) (input_name, &dir_stat) < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", input_name);
|
stat_error (input_name);
|
||||||
return input_name;
|
return input_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1081,7 +1040,7 @@ add_cdf_double_slashes (char *input_name)
|
|||||||
*p = '\0';
|
*p = '\0';
|
||||||
if ((*xstat) (input_name, &dir_stat) < 0)
|
if ((*xstat) (input_name, &dir_stat) < 0)
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", input_name);
|
stat_error (input_name);
|
||||||
return input_name;
|
return input_name;
|
||||||
}
|
}
|
||||||
*p = '/';
|
*p = '/';
|
||||||
@ -1109,7 +1068,7 @@ islastparentcdf (char *path)
|
|||||||
int slash_count;
|
int slash_count;
|
||||||
int length; /* Length of result, not including NUL. */
|
int length; /* Length of result, not including NUL. */
|
||||||
|
|
||||||
slash = rindex (path, '/');
|
slash = strrchr (path, '/');
|
||||||
if (slash == 0)
|
if (slash == 0)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
@ -1131,9 +1090,6 @@ islastparentcdf (char *path)
|
|||||||
|
|
||||||
#define DISKBLOCKSIZE (512)
|
#define DISKBLOCKSIZE (512)
|
||||||
|
|
||||||
enum sparse_write_states { begin, in_zeros, not_in_zeros };
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
buf_all_zeros (char *buf, int bufsize)
|
buf_all_zeros (char *buf, int bufsize)
|
||||||
{
|
{
|
||||||
@ -1151,7 +1107,7 @@ int delayed_seek_count = 0;
|
|||||||
/* Write NBYTE bytes from BUF to remote tape connection FILDES.
|
/* Write NBYTE bytes from BUF to remote tape connection FILDES.
|
||||||
Return the number of bytes written on success, -1 on error. */
|
Return the number of bytes written on success, -1 on error. */
|
||||||
|
|
||||||
int
|
static int
|
||||||
sparse_write (int fildes, char *buf, unsigned int nbyte)
|
sparse_write (int fildes, char *buf, unsigned int nbyte)
|
||||||
{
|
{
|
||||||
int complete_block_count;
|
int complete_block_count;
|
||||||
@ -1162,7 +1118,7 @@ sparse_write (int fildes, char *buf, unsigned int nbyte)
|
|||||||
int lseek_rc;
|
int lseek_rc;
|
||||||
int write_rc;
|
int write_rc;
|
||||||
int i;
|
int i;
|
||||||
enum sparse_write_states state;
|
enum { begin, in_zeros, not_in_zeros } state;
|
||||||
|
|
||||||
complete_block_count = nbyte / DISKBLOCKSIZE;
|
complete_block_count = nbyte / DISKBLOCKSIZE;
|
||||||
leftover_bytes_count = nbyte % DISKBLOCKSIZE;
|
leftover_bytes_count = nbyte % DISKBLOCKSIZE;
|
||||||
@ -1192,6 +1148,7 @@ sparse_write (int fildes, char *buf, unsigned int nbyte)
|
|||||||
}
|
}
|
||||||
buf += DISKBLOCKSIZE;
|
buf += DISKBLOCKSIZE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case in_zeros :
|
case in_zeros :
|
||||||
if (buf_all_zeros (buf, DISKBLOCKSIZE))
|
if (buf_all_zeros (buf, DISKBLOCKSIZE))
|
||||||
{
|
{
|
||||||
@ -1206,6 +1163,7 @@ sparse_write (int fildes, char *buf, unsigned int nbyte)
|
|||||||
}
|
}
|
||||||
buf += DISKBLOCKSIZE;
|
buf += DISKBLOCKSIZE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case not_in_zeros :
|
case not_in_zeros :
|
||||||
if (buf_all_zeros (buf, DISKBLOCKSIZE))
|
if (buf_all_zeros (buf, DISKBLOCKSIZE))
|
||||||
{
|
{
|
||||||
@ -1228,6 +1186,7 @@ sparse_write (int fildes, char *buf, unsigned int nbyte)
|
|||||||
case in_zeros :
|
case in_zeros :
|
||||||
delayed_seek_count = seek_count;
|
delayed_seek_count = seek_count;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case not_in_zeros :
|
case not_in_zeros :
|
||||||
write_rc = write (fildes, cur_write_start, write_count);
|
write_rc = write (fildes, cur_write_start, write_count);
|
||||||
delayed_seek_count = 0;
|
delayed_seek_count = 0;
|
||||||
@ -1245,3 +1204,139 @@ sparse_write (int fildes, char *buf, unsigned int nbyte)
|
|||||||
}
|
}
|
||||||
return nbyte;
|
return nbyte;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CPIO_UID(uid) (set_owner_flag ? set_owner : (uid))
|
||||||
|
#define CPIO_GID(gid) (set_group_flag ? set_group : (gid))
|
||||||
|
|
||||||
|
void
|
||||||
|
stat_to_cpio (struct cpio_file_stat *hdr, struct stat *st)
|
||||||
|
{
|
||||||
|
hdr->c_dev_maj = major (st->st_dev);
|
||||||
|
hdr->c_dev_min = minor (st->st_dev);
|
||||||
|
hdr->c_ino = st->st_ino;
|
||||||
|
/* For POSIX systems that don't define the S_IF macros,
|
||||||
|
we can't assume that S_ISfoo means the standard Unix
|
||||||
|
S_IFfoo bit(s) are set. So do it manually, with a
|
||||||
|
different name. Bleah. */
|
||||||
|
hdr->c_mode = (st->st_mode & 07777);
|
||||||
|
if (S_ISREG (st->st_mode))
|
||||||
|
hdr->c_mode |= CP_IFREG;
|
||||||
|
else if (S_ISDIR (st->st_mode))
|
||||||
|
hdr->c_mode |= CP_IFDIR;
|
||||||
|
#ifdef S_ISBLK
|
||||||
|
else if (S_ISBLK (st->st_mode))
|
||||||
|
hdr->c_mode |= CP_IFBLK;
|
||||||
|
#endif
|
||||||
|
#ifdef S_ISCHR
|
||||||
|
else if (S_ISCHR (st->st_mode))
|
||||||
|
hdr->c_mode |= CP_IFCHR;
|
||||||
|
#endif
|
||||||
|
#ifdef S_ISFIFO
|
||||||
|
else if (S_ISFIFO (st->st_mode))
|
||||||
|
hdr->c_mode |= CP_IFIFO;
|
||||||
|
#endif
|
||||||
|
#ifdef S_ISLNK
|
||||||
|
else if (S_ISLNK (st->st_mode))
|
||||||
|
hdr->c_mode |= CP_IFLNK;
|
||||||
|
#endif
|
||||||
|
#ifdef S_ISSOCK
|
||||||
|
else if (S_ISSOCK (st->st_mode))
|
||||||
|
hdr->c_mode |= CP_IFSOCK;
|
||||||
|
#endif
|
||||||
|
#ifdef S_ISNWK
|
||||||
|
else if (S_ISNWK (st->st_mode))
|
||||||
|
hdr->c_mode |= CP_IFNWK;
|
||||||
|
#endif
|
||||||
|
hdr->c_uid = CPIO_UID (st->st_uid);
|
||||||
|
hdr->c_gid = CPIO_GID (st->st_gid);
|
||||||
|
hdr->c_nlink = st->st_nlink;
|
||||||
|
hdr->c_rdev_maj = major (st->st_rdev);
|
||||||
|
hdr->c_rdev_min = minor (st->st_rdev);
|
||||||
|
hdr->c_mtime = st->st_mtime;
|
||||||
|
hdr->c_filesize = st->st_size;
|
||||||
|
hdr->c_chksum = 0;
|
||||||
|
hdr->c_tar_linkname = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_FCHOWN
|
||||||
|
# define fchown(fd, uid, gid) (-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
fchown_or_chown (int fd, const char *name, uid_t uid, uid_t gid)
|
||||||
|
{
|
||||||
|
if (HAVE_FCHOWN && fd != -1)
|
||||||
|
return fchown (fd, uid, gid);
|
||||||
|
else
|
||||||
|
return chown (name, uid, gid);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fchmod_or_chmod (int fd, const char *name, mode_t mode)
|
||||||
|
{
|
||||||
|
if (HAVE_FCHMOD && fd != -1)
|
||||||
|
return fchmod (fd, mode);
|
||||||
|
else
|
||||||
|
return chmod(name, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_perms (int fd, struct cpio_file_stat *header)
|
||||||
|
{
|
||||||
|
if (!no_chown_flag)
|
||||||
|
{
|
||||||
|
uid_t uid = CPIO_UID (header->c_uid);
|
||||||
|
gid_t gid = CPIO_GID (header->c_gid);
|
||||||
|
if ((fchown_or_chown (fd, header->c_name, uid, gid) < 0)
|
||||||
|
&& errno != EPERM)
|
||||||
|
chown_error_details (header->c_name, uid, gid);
|
||||||
|
}
|
||||||
|
/* chown may have turned off some permissions we wanted. */
|
||||||
|
if (fchmod_or_chmod (fd, header->c_name, header->c_mode) < 0)
|
||||||
|
chmod_error_details (header->c_name, header->c_mode);
|
||||||
|
#ifdef HPUX_CDF
|
||||||
|
if ((header->c_mode & CP_IFMT) && cdf_flag)
|
||||||
|
/* Once we "hide" the directory with the chmod(),
|
||||||
|
we have to refer to it using name+ instead of name. */
|
||||||
|
file_hdr->c_name [cdf_char] = '+';
|
||||||
|
#endif
|
||||||
|
if (retain_time_flag)
|
||||||
|
set_file_times (fd, header->c_name, header->c_mtime, header->c_mtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_file_times (int fd,
|
||||||
|
const char *name, unsigned long atime, unsigned long mtime)
|
||||||
|
{
|
||||||
|
struct timespec ts[2];
|
||||||
|
|
||||||
|
memset (&ts, 0, sizeof ts);
|
||||||
|
|
||||||
|
ts[0].tv_sec = atime;
|
||||||
|
ts[1].tv_sec = mtime;
|
||||||
|
|
||||||
|
/* Silently ignore EROFS because reading the file won't have upset its
|
||||||
|
timestamp if it's on a read-only filesystem. */
|
||||||
|
if (gl_futimens (fd, name, ts) < 0 && errno != EROFS)
|
||||||
|
utime_error (name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do we have to ignore absolute paths, and if so, does the filename
|
||||||
|
have an absolute path? */
|
||||||
|
void
|
||||||
|
cpio_safer_name_suffix (char *name, bool link_target, bool absolute_names,
|
||||||
|
bool strip_leading_dots)
|
||||||
|
{
|
||||||
|
char *p = safer_name_suffix (name, link_target, absolute_names);
|
||||||
|
if (strip_leading_dots && strcmp (p, "./"))
|
||||||
|
/* strip leading `./' from the filename. */
|
||||||
|
while (*p == '.' && *(p + 1) == '/')
|
||||||
|
{
|
||||||
|
++p;
|
||||||
|
while (*p == '/')
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
if (p != name)
|
||||||
|
memmove (name, p, (size_t)(strlen (p) + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user