Compare commits
75 Commits
release_1_
...
release_1_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20b55f0679 | ||
|
|
35b292ac4b | ||
|
|
61cd3fd268 | ||
|
|
3010818f36 | ||
|
|
733e2741b1 | ||
|
|
195a25316c | ||
|
|
74e3b497c4 | ||
|
|
29f652871e | ||
|
|
13d04fe6ae | ||
|
|
8d31493c99 | ||
|
|
752b447f3e | ||
|
|
a3aa7003ea | ||
|
|
143dc63ffa | ||
|
|
c0fb0740fa | ||
|
|
6ac0dd1d73 | ||
|
|
160fb9abd2 | ||
|
|
f6ad0e4af2 | ||
|
|
e4b246c14a | ||
|
|
2a7c84b4a9 | ||
|
|
da7845c656 | ||
|
|
8980ecd62d | ||
|
|
63f2e969dd | ||
|
|
445293654d | ||
|
|
b5f581e637 | ||
|
|
0f26331b17 | ||
|
|
196fef9b40 | ||
|
|
68dd249987 | ||
|
|
4cf2af4500 | ||
|
|
cadc43ace5 | ||
|
|
239441b5df | ||
|
|
0a93c16c62 | ||
|
|
5dd490e7f1 | ||
|
|
68e9ab4966 | ||
|
|
b684326e69 | ||
|
|
589ba77faf | ||
|
|
6ea9e62bb3 | ||
|
|
d02c81df15 | ||
|
|
e426787454 | ||
|
|
e6fcc73efa | ||
|
|
6167c23e22 | ||
|
|
5e2a1d5b38 | ||
|
|
4aebc943bb | ||
|
|
1a615a41f5 | ||
|
|
cdf41c383f | ||
|
|
a65086c71c | ||
|
|
ae23a57d70 | ||
|
|
c440a92627 | ||
|
|
aa9676dcad | ||
|
|
6cb94e37a9 | ||
|
|
232a7258c3 | ||
|
|
429bd311b7 | ||
|
|
eb621c67cf | ||
|
|
21f86195b7 | ||
|
|
fe3b106cb3 | ||
|
|
3828942550 | ||
|
|
d95457e007 | ||
|
|
da06935f6e | ||
|
|
15c02c2b9d | ||
|
|
0c4aa85e6c | ||
|
|
731b7b07de | ||
|
|
4eb1484dce | ||
|
|
1847ec67ce | ||
|
|
9c2b57232e | ||
|
|
55fb2fc38f | ||
|
|
5a9ac8312e | ||
|
|
7bf812579c | ||
|
|
1209e0ebff | ||
|
|
e7b6f8e3ae | ||
|
|
586a6263e9 | ||
|
|
ec94fbdf45 | ||
|
|
c48f4e8f6c | ||
|
|
e7c99a4dd1 | ||
|
|
e9ddc08da0 | ||
|
|
163e96a0e6 | ||
|
|
0e0a852e91 |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -23,13 +23,8 @@ config.h.in
|
||||
config.log
|
||||
config.status
|
||||
configure
|
||||
gnu/*.h
|
||||
gnu/*/
|
||||
gnu/.gitignore
|
||||
gnu/charset.alias
|
||||
gnulib
|
||||
gnu
|
||||
libtool
|
||||
m4
|
||||
paxutils
|
||||
rmt
|
||||
stamp-h1
|
||||
|
||||
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
[submodule "gnulib"]
|
||||
path = gnulib
|
||||
url = git://git.sv.gnu.org/gnulib.git
|
||||
[submodule "paxutils"]
|
||||
path = paxutils
|
||||
url = git://git.sv.gnu.org/paxutils.git
|
||||
@@ -3186,7 +3186,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
Reported by Jeffrey Goldberg.
|
||||
|
||||
* rmt.h (_remdev): A filename is not remote if the colon is
|
||||
preceeded by a slash, to take care of `/:/' which is a shorthand
|
||||
preceded by a slash, to take care of `/:/' which is a shorthand
|
||||
for `/.../<CELL-NAME>/fs' on OSF's Distributing Computing
|
||||
Environment (DCE) and Distributed File System (DFS).
|
||||
Reported by Travis L. Priest.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Main Makefile for GNU tar.
|
||||
|
||||
# Copyright 1994-1997, 1999-2001, 2003, 2007, 2009, 2013-2014 Free
|
||||
# Copyright 1994-1997, 1999-2001, 2003, 2007, 2009, 2013-2014, 2016 Free
|
||||
# Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
@@ -26,7 +26,7 @@ dist-hook:
|
||||
$(MAKE) changelog_dir=$(distdir) ChangeLog
|
||||
-rm -f $(distdir).cpio
|
||||
find $(distdir) | cpio -Hcrc -o | \
|
||||
GZIP=$(GZIP_ENV) gzip -c > $(distdir).cpio.gz
|
||||
eval GZIP= gzip $(GZIP_ENV) -c > $(distdir).cpio.gz
|
||||
|
||||
distclean-local:
|
||||
-rm -f $(distdir).cpio.gz
|
||||
|
||||
90
NEWS
90
NEWS
@@ -1,6 +1,88 @@
|
||||
GNU tar NEWS - User visible changes. 2014-07-27
|
||||
GNU tar NEWS - User visible changes. 2016-05-16
|
||||
Please send GNU tar bug reports to <bug-tar@gnu.org>
|
||||
|
||||
|
||||
version 1.29 - Sergey Poznyakoff, 2016-05-16
|
||||
|
||||
* New options: --verbatim-files-from, --no-verbatim-files-from
|
||||
|
||||
The --verbatim-files-from option instructs tar to treat each line read
|
||||
from a file list as a file name, even if it starts with a dash.
|
||||
|
||||
File lists are supplied with the --files-from (-T) option. By
|
||||
default, each line read from a file list is first stripped off the
|
||||
leading and trailing whitespace and, if the result begins with a dash,
|
||||
it is treated as tar command line option.
|
||||
|
||||
Use the --verbatim-files-from option to disable this special handling.
|
||||
This facilitates the use of tar with file lists created automatically
|
||||
(e.g. by find(1) command).
|
||||
|
||||
This option affects all --files-from options that occur after it in
|
||||
the command line. Its effect is reverted by the
|
||||
--no-verbatim-files-from option.
|
||||
|
||||
* --null option reads file names verbatim
|
||||
|
||||
The --null option implies --verbatim-files-from. I.e. each line
|
||||
read from null-delimited file lists is treated as a file name.
|
||||
|
||||
This restores the documented behavior, which was broken in version
|
||||
1.27.
|
||||
|
||||
* New options: --owner-map=FILE and --group-map=FILE
|
||||
|
||||
These two options provide fine-grained control over what user/group
|
||||
names (or IDs) should be mapped when adding files to archive.
|
||||
|
||||
For both options, FILE is a plain text file with user or group
|
||||
mappings. Empty lines are ignored. Comments are introduced with
|
||||
# sign (unless quoted) and extend to the end of the corresponding
|
||||
line. Each non-empty line defines translation for a single UID (GID).
|
||||
It must consist of two fields, delimited by any amount of whitespace:
|
||||
|
||||
OLDNAME NEWNAME[:NEWID]
|
||||
|
||||
OLDNAME is either a valid user (group) name or a ID prefixed with +. Unless
|
||||
NEWID is supplied, NEWNAME must also be either a valid name or a
|
||||
+ID. Otherwise, both NEWNAME and NEWID need not be listed in the
|
||||
system user database.
|
||||
|
||||
* New option --clamp-mtime
|
||||
|
||||
The new --clamp-mtime option changes the behavior of --mtime to only
|
||||
use the time specified if the file mtime is newer than the given time.
|
||||
The --clamp-mtime option can only be used together with --mtime.
|
||||
|
||||
Typical use case is to make builds reproducible: to loose less
|
||||
information, it's better to keep the original date of an archive,
|
||||
except for files modified during the build process. In that case, using
|
||||
reference (and thus reproducible) timestamps for the latter is good
|
||||
enough.
|
||||
|
||||
See <https://wiki.debian.org/ReproducibleBuilds> for more information.
|
||||
|
||||
* Deprecated --preserve option removed
|
||||
|
||||
* Sparse file detection
|
||||
|
||||
Tar now uses SEEK_DATA/SEEK_HOLE on systems that support it. This
|
||||
allows for considerable speed-up in sparse-file detection.
|
||||
|
||||
New option --hole-detection is provided, that allows the user to
|
||||
select the algorithm used for hole detection. Available arguments
|
||||
are:
|
||||
|
||||
--hole-detection=seek
|
||||
Use lseek(2) SEEK_DATA and SEEK_HOLE "whence" parameters.
|
||||
|
||||
--hole-detection=raw
|
||||
Scan entire file before storing it to determine where holes
|
||||
are located.
|
||||
|
||||
The default is to use "seek" whenever possible, and fall back to
|
||||
"raw" otherwise.
|
||||
|
||||
|
||||
version 1.28, 2014-07-28
|
||||
|
||||
@@ -369,7 +451,7 @@ Modification times in ustar header blocks of extended headers
|
||||
are set to mtimes of the corresponding archive members. This
|
||||
can be overridden by the
|
||||
|
||||
--pax-opion='exthdr.mtime=STRING'
|
||||
--pax-option='exthdr.mtime=STRING'
|
||||
|
||||
command line option. The STRING is either number of seconds since
|
||||
the Epoch or a "Time reference" (see below).
|
||||
@@ -379,7 +461,7 @@ headers are set to the time when tar was invoked.
|
||||
|
||||
This can be overridden by the
|
||||
|
||||
--pax-opion='globexthdr.mtime=STRING'
|
||||
--pax-option='globexthdr.mtime=STRING'
|
||||
|
||||
command line option. The STRING is either number of seconds since
|
||||
the Epoch or a "Time reference" (see below).
|
||||
@@ -1505,7 +1587,7 @@ Versions 1.07 back to 1.00 by Jay Fenlason.
|
||||
|
||||
|
||||
|
||||
Copyright 1994-2001, 2003-2010, 2013-2014 Free Software Foundation, Inc.
|
||||
Copyright 1994-2001, 2003-2010, 2013-2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
5
README
5
README
@@ -23,7 +23,6 @@ GNU 'tar' is derived from John Gilmore's public domain 'tar'.
|
||||
See file 'ABOUT-NLS' for how to customize this program to your language.
|
||||
See file 'COPYING' for copying conditions.
|
||||
See file 'INSTALL' for compilation and installation instructions.
|
||||
See file 'PORTS' for various ports of GNU tar to non-Unix systems.
|
||||
See file 'NEWS' for a list of major changes in the current release.
|
||||
See file 'THANKS' for a list of contributors.
|
||||
|
||||
@@ -222,8 +221,8 @@ and share your findings by writing to <bug-tar@gnu.org>.
|
||||
|
||||
* Copying
|
||||
|
||||
Copyright 1990-1992, 1994, 1997-2001, 2003-2004, 2007, 2012-2014 Free
|
||||
Software Foundation, Inc.
|
||||
Copyright 1990-1992, 1994, 1997-2001, 2003-2004, 2007, 2012-2014, 2016
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
45
README-alpha
45
README-alpha
@@ -23,46 +23,19 @@ suggest using test version 1.3.5 (or later, if one becomes available).
|
||||
Valgrind <http://valgrind.org/> is also highly recommended, if
|
||||
Valgrind supports your architecture.
|
||||
|
||||
Before building the package, run "bootstrap". It obtains various
|
||||
additional files from the CVS repository and the Translation Project
|
||||
site and prepares the source directory for building.
|
||||
Before building the package, run "bootstrap". It will obtain gnulib
|
||||
and paxutils files from their Git repositories on Savannah. Then, it will
|
||||
fetch the po files from tar page at Translation Project, and, finally, it
|
||||
will start autoconfiguration process. Simply running bootstrap without
|
||||
arguments should do in most cases.
|
||||
|
||||
When run without arguments, bootstrap will try to obtain gnulib and
|
||||
paxutils files from their corresponding CVS repositories on Savannah
|
||||
using anonymous SSH access. Then, it will fetch the po files from tar
|
||||
page at Translation Project, and, finally, it will start autoconfiguration
|
||||
process. Simply running it without arguments should do in most cases.
|
||||
Several options allow to control the behavior of bootstrap:
|
||||
|
||||
--gnulib-srcdir=DIRNAME Specify the local directory where gnulib
|
||||
sources reside. Use this if you already
|
||||
have gnulib sources on your machine, and
|
||||
do not want to waste your bandwidth dowloading
|
||||
them again.
|
||||
|
||||
--paxutils-srcdir=DIRNAME Specify the local directory where paxutils
|
||||
sources reside. Use this if you already
|
||||
have paxutils sources on your machine, and
|
||||
do not want to waste your bandwidth dowloading
|
||||
them again.
|
||||
|
||||
--cvs-auth=METHOD Set the CVS access method used for downloading
|
||||
gnulib files. METHOD is one of the keywords
|
||||
accepted by cvs -d option (see info cvs
|
||||
repository).
|
||||
|
||||
--cvs-user=USERNAME Set the CVS username to be used when accessing
|
||||
the gnulib repository.
|
||||
|
||||
--no-po Do not download po files.
|
||||
|
||||
Notice also that when using CVS authentication method "ext", bootstrap
|
||||
will set the variable CVS_RSH to "ssh", unless it is already set to
|
||||
some other value.
|
||||
Bootstrap reads its configuration from file bootstrap.conf located on the
|
||||
top of tar source tree. Several options are provided that modify its
|
||||
behavior. Run 'bootstrap --help' for a list.
|
||||
|
||||
|
||||
|
||||
Copyright 2001, 2003-2005, 2007, 2013-2014 Free Software Foundation,
|
||||
Copyright 2001, 2003-2005, 2007, 2013-2016 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -12,7 +12,6 @@ version.
|
||||
- Autoconf <http://www.gnu.org/software/autoconf/>
|
||||
- M4 <http://www.gnu.org/software/m4/>
|
||||
- Texinfo <http://www.gnu.org/software/texinfo>
|
||||
- Gnulib <http://www.gnu.org/software/gnulib>
|
||||
- Git <http://git.or.cz>
|
||||
|
||||
* Bootstrapping
|
||||
@@ -33,23 +32,14 @@ Once done, proceed as described in the file README (section
|
||||
INSTALLATION).
|
||||
|
||||
Normally you will have to run bootstrap only once. However, if you
|
||||
intend to hack on GNU tar, you might need to run it again later. In
|
||||
this case, you will probably want to save some time and bandwidth by
|
||||
avoiding downloading the same files again. If so, create in GNU tar
|
||||
root directory the file named '.bootstrap' with the following
|
||||
contents:
|
||||
|
||||
--gnulib-srcdir=$HOME/gnulib
|
||||
|
||||
Replace '$HOME/gnulib' with the actual directory where the Gnulib
|
||||
sources reside.
|
||||
|
||||
For more information about 'bootstrap', run 'bootstrap --help'.
|
||||
intend to hack on GNU tar, you might need to run it again later.
|
||||
There are lots of options that you may find useful in this case.
|
||||
See 'bootstrap --help' for a detailed list.
|
||||
|
||||
|
||||
* Copyright information
|
||||
|
||||
Copyright 2007-2009, 2013-2014 Free Software Foundation, Inc.
|
||||
Copyright 2007-2009, 2013-2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
7
THANKS
7
THANKS
@@ -78,6 +78,7 @@ Cesar Romani romani@ifm.uni-hamburg.de
|
||||
Chad Hurwitz churritz@cts.com
|
||||
Chance Reschke creschke@usra.edu
|
||||
Charles Fu ccwf@klab.caltech.edu
|
||||
Charles McGarvey chazmcgarvey@brokenzipper.com
|
||||
Charles Lopes Charles.Lopes@infm.ulst.ac.uk
|
||||
Charles M. Hannum mycroft@gnu.org
|
||||
Chip Salzenberg tct!chip
|
||||
@@ -107,6 +108,7 @@ Conrad Hughes chughes@maths.tcd.ie
|
||||
Constantin Belous const@cris.net
|
||||
Coranth Gryphon gryphon@bur.visidyne.com
|
||||
Cyril Strejc strejc@unicontrols.cz
|
||||
Dagobert Michelsen dam@opencsw.org
|
||||
Dale R. Worley worley@world.std.com
|
||||
Dale Wiles wiles@geordi.calspan.com
|
||||
Dan Bloch dan@transarc.com
|
||||
@@ -114,6 +116,7 @@ Dan Drake dan@dandrake.org
|
||||
Dan Reish dreish@izzy.net
|
||||
Daniel Hagerty hag@gnu.org
|
||||
Daniel Quinlan quinlan@pathname.com
|
||||
Daniel Kahn Gillmor dkg@fifthhorseman.net
|
||||
Daniel R. Guilderson d.guilderson@ma30.bull.com
|
||||
Daniel S. Barclay daniel@compass-da.com
|
||||
Daniel Trinkle trinkle@cs.purdue.edu
|
||||
@@ -140,6 +143,7 @@ Demizu Noritoshi nori-d@is.aist-nara.ac.jp
|
||||
Denis Excoffier denis.excoffier@free.fr
|
||||
Denis Fortin fortin@acm.org
|
||||
Dennis Pixton dennis@math.binghamton.edu
|
||||
Derek Terveer dt@hawkmoon.mn.org
|
||||
Dick Streefland dicks@tasking.nl
|
||||
Dietmar Braun dietmar@highway.bertelsmann.de
|
||||
Dimitri Bougoulias opus@hol.gr
|
||||
@@ -172,6 +176,7 @@ Erik D. Frederick edf@deckard.mc.duke.edu
|
||||
Esa Karell karell@cs.helsinki.fi
|
||||
Ezra Peisach epeisach@mit.edu
|
||||
Fabio d'Alessi cars@civ.bio.unipd.it
|
||||
Flavio Poletti polettix@gmail.com
|
||||
Frank Heckenbach frank@g-n-u.de
|
||||
Frank Koenen koenfr@lidp.com
|
||||
Franz-Werner Gergen gergen@edvulx.mpi-stuttgart.mpg.de
|
||||
@@ -202,6 +207,7 @@ Helmut Waitzmann Helmut.Waitzmann@web.de
|
||||
Henrik Bakman hb@csd.uu.se
|
||||
Hernan Prieto Schmidt hernan@pea.usp.br
|
||||
Hiroyuki Bessho bsh@grotto.iijnet.or.jp
|
||||
Holger Levsen holger@layer-acht.org
|
||||
Holger Teutsch holger@hotbso.rhein-main.de
|
||||
Hugh Secker-Walker hugh@ear.mit.edu
|
||||
Hunyue Yau hunyue.yau@picksys.com
|
||||
@@ -240,6 +246,7 @@ Jeffrey Goldberg J.Goldberg@cranfield.ac.uk
|
||||
Jeffrey Mark Siskind Qobi@emba.uvm.edu
|
||||
Jeffrey W. Parker jwpkr@mcs.com
|
||||
Jens Henrik Jensen recjhl@mediator.uni-c.dk
|
||||
Jérémy Bobbio lunar@debian.org
|
||||
Jim Blandy jimb@totoro.cs.oberlin.edu
|
||||
Jim Clausing jac@postbox.acs.ohio-state.edu
|
||||
Jim Farrell jwf@platinum.com
|
||||
|
||||
3
TODO
3
TODO
@@ -45,7 +45,8 @@ Suggestions for improving GNU tar.
|
||||
|
||||
* Copyright notice
|
||||
|
||||
Copyright 2003-2004, 2007, 2013-2014 Free Software Foundation, Inc.
|
||||
Copyright 2003-2004, 2007, 2013-2014, 2016 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
44
acinclude.m4
44
acinclude.m4
@@ -1,6 +1,6 @@
|
||||
dnl Special Autoconf macros for GNU tar -*- autoconf -*-
|
||||
|
||||
dnl Copyright 2009, 2013-2014 Free Software Foundation, Inc.
|
||||
dnl Copyright 2009, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
dnl
|
||||
dnl This file is part of GNU tar.
|
||||
dnl
|
||||
@@ -40,37 +40,23 @@ AC_DEFUN([TAR_HEADERS_ATTR_XATTR_H],
|
||||
# First check for <sys/xattr.h>
|
||||
AC_CHECK_HEADERS([sys/xattr.h])
|
||||
AM_CONDITIONAL([TAR_COND_XATTR_H],[test "$ac_cv_header_sys_xattr_h" = yes])
|
||||
AM_CONDITIONAL([TAR_LIB_ATTR],[false])
|
||||
if test "$ac_cv_header_sys_xattr_h" = yes; then
|
||||
AC_CHECK_FUNCS(getxattr fgetxattr lgetxattr \
|
||||
setxattr fsetxattr lsetxattr \
|
||||
listxattr flistxattr llistxattr,
|
||||
# only when functions are present
|
||||
AC_DEFINE([HAVE_SYS_XATTR_H], [1],
|
||||
[define to 1 if we have <sys/xattr.h> header])
|
||||
if test "$with_xattrs" != no; then
|
||||
AC_DEFINE([HAVE_XATTRS],,[Define when we have working linux xattrs.])
|
||||
fi
|
||||
)
|
||||
fi
|
||||
|
||||
# If <sys/xattr.h> is not found, then check for <attr/xattr.h>
|
||||
if test "$ac_cv_header_sys_xattr_h" != yes; then
|
||||
AC_CHECK_HEADERS([attr/xattr.h])
|
||||
AM_CONDITIONAL([TAR_COND_XATTR_H],[test "$ac_cv_header_attr_xattr_h" = yes])
|
||||
AC_CHECK_LIB([attr],[fgetxattr])
|
||||
AM_CONDITIONAL([TAR_LIB_ATTR],[test "$ac_cv_lib_attr_fgetxattr" = yes])
|
||||
if test "$ac_cv_header_attr_xattr_h" = yes; then
|
||||
AC_CHECK_FUNCS(getxattr fgetxattr lgetxattr \
|
||||
setxattr fsetxattr lsetxattr \
|
||||
listxattr flistxattr llistxattr,
|
||||
# only when functions are present
|
||||
AC_DEFINE([HAVE_ATTR_XATTR_H], [1],
|
||||
[define to 1 if we have <attr/xattr.h> header])
|
||||
if test "$with_xattrs" != no; then
|
||||
AC_DEFINE([HAVE_XATTRS],,[Define when we have working linux xattrs.])
|
||||
fi
|
||||
)
|
||||
fi
|
||||
|
||||
if test "$with_xattrs" != no; then
|
||||
for i in getxattr fgetxattr lgetxattr \
|
||||
setxattr fsetxattr lsetxattr \
|
||||
listxattr flistxattr llistxattr
|
||||
do
|
||||
AC_SEARCH_LIBS($i, attr)
|
||||
eval found=\$ac_cv_search_$i
|
||||
test "$found" = "no" && break
|
||||
done
|
||||
|
||||
if test "$found" != no; then
|
||||
AC_DEFINE([HAVE_XATTRS],,[Define when we have working linux xattrs.])
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Bootstrap configuration for GNU tar.
|
||||
|
||||
# Copyright 2006-2009, 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2006-2009, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
@@ -26,10 +26,6 @@ avoided_gnulib_modules='
|
||||
--avoid=lock
|
||||
'
|
||||
|
||||
# gnulib modules used by this package.
|
||||
gnulib_modules="$avoided_gnulib_modules
|
||||
`grep '^[^#]' gnulib.modules`
|
||||
"
|
||||
|
||||
# Additional xgettext options to use. Use "\\\newline" to break lines.
|
||||
XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\
|
||||
@@ -71,3 +67,60 @@ test -f ChangeLog || cat > ChangeLog <<EOT
|
||||
This file is a placeholder. It will be replaced with the actual ChangeLog
|
||||
by make dist. Run make ChangeLog if you wish to create it earlier.
|
||||
EOT
|
||||
|
||||
git submodule init
|
||||
git submodule update
|
||||
PAXUTILS=paxutils
|
||||
|
||||
# gnulib modules used by this package.
|
||||
gnulib_modules="$avoided_gnulib_modules
|
||||
`grep -h '^[^#]' gnulib.modules $PAXUTILS/gnulib.modules`
|
||||
"
|
||||
|
||||
# copy_files srcdir dstdir
|
||||
copy_files() {
|
||||
for file in `cat $1/DISTFILES`
|
||||
do
|
||||
case $file in
|
||||
"#*") continue;;
|
||||
esac
|
||||
dst=`echo $file | sed 's^.*/^^'`
|
||||
if [ $# -eq 3 ]; then
|
||||
case $dst in
|
||||
${3}*) ;;
|
||||
*) dst=${3}$dst;;
|
||||
esac
|
||||
fi
|
||||
if [ "$2" = '.' ]; then
|
||||
ln -sf $1/$file $2
|
||||
else
|
||||
symlink_to_dir "$1" "$file" "$2/$dst" || exit
|
||||
fi
|
||||
# FIXME ignorefile $2 $dst
|
||||
done
|
||||
}
|
||||
|
||||
# Import from paxutils
|
||||
copy_files ${PAXUTILS} .
|
||||
copy_files ${PAXUTILS}/am m4
|
||||
|
||||
echo "$0: Creating m4/paxutils.m4"
|
||||
(echo "# This file is generated automatically. Please, do not edit."
|
||||
echo "#"
|
||||
echo "AC_DEFUN([${package}_PAXUTILS],["
|
||||
cat ${PAXUTILS}/am/DISTFILES | sed '/^#/d;s/\(.*\)\.m4/pu_\1/' | tr a-z A-Z
|
||||
echo "])") > ./m4/paxutils.m4
|
||||
#FIXME ignorefile m4 paxutils.m4
|
||||
|
||||
if [ -d rmt ]; then
|
||||
:
|
||||
else
|
||||
mkdir rmt
|
||||
fi
|
||||
|
||||
for dir in doc rmt lib tests
|
||||
do
|
||||
copy_files ${PAXUTILS}/$dir $dir
|
||||
done
|
||||
|
||||
copy_files ${PAXUTILS}/paxlib lib pax
|
||||
|
||||
11
configure.ac
11
configure.ac
@@ -1,6 +1,6 @@
|
||||
# Configure template for GNU tar. -*- autoconf -*-
|
||||
|
||||
# Copyright 1991, 1994-2010, 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 1991, 1994-2010, 2013-2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
AC_INIT([GNU tar], [1.28], [bug-tar@gnu.org])
|
||||
AC_INIT([GNU tar], [1.29], [bug-tar@gnu.org])
|
||||
AC_CONFIG_SRCDIR([src/tar.c])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
@@ -150,6 +150,7 @@ if test "$gl_gcc_warnings" = yes; then
|
||||
nw="$nw -Winline" # It's OK to not inline.
|
||||
nw="$nw -Wstrict-overflow" # It's OK to optimize strictly.
|
||||
nw="$nw -Wsuggest-attribute=pure" # Too many warnings for now.
|
||||
nw="$nw -Wstack-protector"
|
||||
|
||||
gl_MANYWARN_ALL_GCC([ws])
|
||||
gl_MANYWARN_COMPLEMENT([ws], [$ws], [$nw])
|
||||
@@ -160,9 +161,10 @@ if test "$gl_gcc_warnings" = yes; then
|
||||
gl_WARN_ADD([-Wno-type-limits]) # It's OK to optimize based on types.
|
||||
gl_WARN_ADD([-Wno-unused-parameter]) # Too many warnings for now
|
||||
gl_WARN_ADD([-Wno-format-nonliteral])
|
||||
|
||||
|
||||
gl_WARN_ADD([-fdiagnostics-show-option])
|
||||
gl_WARN_ADD([-funit-at-a-time])
|
||||
|
||||
|
||||
AC_SUBST([WARN_CFLAGS])
|
||||
|
||||
@@ -204,8 +206,7 @@ fi
|
||||
|
||||
TAR_HEADERS_ATTR_XATTR_H
|
||||
|
||||
AC_CHECK_FUNCS_ONCE([fchmod fchown fsync lstat mkfifo readlink symlink grantpt])
|
||||
AM_CONDITIONAL([TAR_COND_GRANTPT], [test $ac_cv_func_grantpt = yes])
|
||||
AC_CHECK_FUNCS_ONCE([fchmod fchown fsync lstat mkfifo readlink symlink])
|
||||
|
||||
AC_CHECK_DECLS([getgrgid],,, [#include <grp.h>])
|
||||
AC_CHECK_DECLS([getpwuid],,, [#include <pwd.h>])
|
||||
|
||||
2
doc/.gitignore
vendored
2
doc/.gitignore
vendored
@@ -1,7 +1,6 @@
|
||||
genfile.texi
|
||||
header.texi
|
||||
manual
|
||||
parse-datetime.texi
|
||||
stamp-vti
|
||||
tar.aux
|
||||
tar.cp
|
||||
@@ -24,3 +23,4 @@ tar.toc
|
||||
tar.tp
|
||||
tar.vr
|
||||
version.texi
|
||||
/parse-datetime.texi
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Makefile for GNU tar documentation.
|
||||
|
||||
# Copyright 1994-1997, 1999-2001, 2003, 2006-2007, 2013-2014 Free
|
||||
# Copyright 1994-1997, 1999-2001, 2003, 2006-2007, 2013-2014, 2016 Free
|
||||
# Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@c This is part of the paxutils manual.
|
||||
@c Copyright (C) 2006-2007, 2014 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 2006-2007, 2014, 2016 Free Software Foundation, Inc.
|
||||
@c Written by Sergey Poznyakoff
|
||||
@c This file is distributed under GFDL 1.1 or any later version
|
||||
@c published by the Free Software Foundation.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
@c hence no sectioning command or @node.
|
||||
|
||||
@display
|
||||
Copyright @copyright{} 2000-2002, 2007-2008, 2014 Free Software
|
||||
Copyright @copyright{} 2000-2002, 2007-2008, 2014, 2016 Free Software
|
||||
Foundation, Inc.
|
||||
@uref{http://fsf.org/}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ Please send broken links and other corrections (or suggestions) to
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Copyright 2004, 2013-2014 Free Software Foundation, Inc.,
|
||||
Copyright 2004, 2013-2014, 2016 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02111, USA
|
||||
<br />
|
||||
Verbatim copying and distribution of this entire article is
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@c This is part of the paxutils manual.
|
||||
@c Copyright (C) 2006, 2014 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 2006, 2014, 2016 Free Software Foundation, Inc.
|
||||
@c This file is distributed under GFDL 1.1 or any later version
|
||||
@c published by the Free Software Foundation.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
;;; mastermenu.el --- Redefinition of texinfo-master-menu-list
|
||||
|
||||
;; Copyright 2006-2007, 2013-2014 Free Software Foundation, Inc.
|
||||
;; Copyright 2006-2007, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Sergey Poznyakoff
|
||||
;; Maintainer: bug-tar@gnu.org
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@c This is part of GNU tar manual.
|
||||
@c Copyright 1992, 1994-1997, 1999-2004, 2006, 2013-2014 Free Software
|
||||
@c Foundation, Inc.
|
||||
@c Copyright 1992, 1994-1997, 1999-2004, 2006, 2013-2014, 2016 Free
|
||||
@c Software Foundation, Inc.
|
||||
@c See file tar.texi for copying conditions.
|
||||
|
||||
@c This file contains support for 'renditions' by Fran@,{c}ois Pinard
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@c This is part of the paxutils manual.
|
||||
@c Copyright (C) 2005, 2007, 2014 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 2005, 2007, 2014, 2016 Free Software Foundation, Inc.
|
||||
@c Written by Sergey Poznyakoff
|
||||
@c This file is distributed under GFDL 1.1 or any later version
|
||||
@c published by the Free Software Foundation.
|
||||
@@ -116,7 +116,7 @@ epoch. These are followed by arbitrary number of directory records.
|
||||
particular directory. Parts of a directory record are delimited with
|
||||
@acronym{ASCII} 0 characters. The following table describes each
|
||||
part. The @dfn{Number} type in this table stands for a decimal integer
|
||||
in @acronym{ASCII} notation. (Negative values are preceeded with a "-"
|
||||
in @acronym{ASCII} notation. (Negative values are preceded with a "-"
|
||||
character, while positive values have no leading punctuation.)
|
||||
|
||||
@multitable @columnfractions 0.25 0.15 0.6
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@c This is part of the paxutils manual.
|
||||
@c Copyright (C) 2006, 2014 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 2006, 2014, 2016 Free Software Foundation, Inc.
|
||||
@c This file is distributed under GFDL 1.1 or any later version
|
||||
@c published by the Free Software Foundation.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@c This is part of the paxutils manual.
|
||||
@c Copyright (C) 2007, 2014 Free Software Foundation, Inc.
|
||||
@c Copyright (C) 2007, 2014, 2016 Free Software Foundation, Inc.
|
||||
@c This file is distributed under GFDL 1.1 or any later version
|
||||
@c published by the Free Software Foundation.
|
||||
|
||||
|
||||
185
doc/tar.1
185
doc/tar.1
@@ -1,5 +1,5 @@
|
||||
.\" This file is part of GNU tar. -*- nroff -*-
|
||||
.\" Copyright 2013-2014 Free Software Foundation, Inc.
|
||||
.\" Copyright 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
.\"
|
||||
.\" GNU tar is free software; you can redistribute it and/or modify
|
||||
.\" 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 with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
.TH TAR 1 "February 22, 2014" "TAR" "GNU TAR Manual"
|
||||
.TH TAR 1 "March 23, 2016" "TAR" "GNU TAR Manual"
|
||||
.SH NAME
|
||||
tar \- an archiving utility
|
||||
.SH SYNOPSIS
|
||||
@@ -37,7 +37,7 @@ tar \- an archiving utility
|
||||
\fBtar\fR \fB\-x\fR [\fB\-f\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIMEMBER\fR...]
|
||||
.SS GNU-style usage
|
||||
.sp
|
||||
\fBtar\fR {\fB\-\-catenate\fR|\fB\-\-concatenate} [\fIOPTIONS\fR] \fIARCHIVE\fR \fIARCHIVE\fR
|
||||
\fBtar\fR {\fB\-\-catenate\fR|\fB\-\-concatenate\fR} [\fIOPTIONS\fR] \fIARCHIVE\fR \fIARCHIVE\fR
|
||||
.sp
|
||||
\fBtar\fR \fB\-\-create\fR [\fB\-\-file\fR \fIARCHIVE\fR] [\fIOPTIONS\fR] [\fIFILE\fR...]
|
||||
.sp
|
||||
@@ -175,7 +175,7 @@ resulting archive might be unusable with non-GNU implementations of
|
||||
\fBtar\fR. Notice also that when more than one archive is given, the
|
||||
members from archives other than the first one will be accessible in
|
||||
the resulting archive only if using the \fB\-i\fR
|
||||
(\fB\-\-ignore\-zeros) option.
|
||||
(\fB\-\-ignore\-zeros\fR) option.
|
||||
|
||||
Compressed archives cannot be concatenated.
|
||||
.TP
|
||||
@@ -198,7 +198,7 @@ short option equivalent.
|
||||
.TP
|
||||
\fB\-r\fR, \fB\-\-append\fR
|
||||
Append files to the end of an archive. Arguments have the same
|
||||
meaning as for \fB\-c\fR (\fB\-\-create).
|
||||
meaning as for \fB\-c\fR (\fB\-\-create\fR).
|
||||
.TP
|
||||
\fB\-t\fR, \fB\-\-list\fR
|
||||
List the contents of an archive. Arguments are optional. When given,
|
||||
@@ -259,6 +259,12 @@ When listing or extracting, the actual contents of \fIFILE\fR is not
|
||||
inspected, it is needed only due to syntactical requirements. It is
|
||||
therefore common practice to use \fB/dev/null\fR in its place.
|
||||
.TP
|
||||
\fB\-\-hole\-detection\fR=\fIMETHOD\fR
|
||||
Use \fIMETHOD\fR to detect holes in sparse files. This option implies
|
||||
\fB\-\-sparse\fR. Valid values for \fIMETHOD\fR are \fBseek\fR and
|
||||
\fBraw\fR. Default is \fBseek\fR with fallback to \fBraw\fR when not
|
||||
applicable.
|
||||
.TP
|
||||
\fB\-G\fR, \fB\-\-incremental\fR
|
||||
Handle old GNU-format incremental backups.
|
||||
.TP
|
||||
@@ -291,7 +297,7 @@ Process only the \fIN\fRth occurrence of each file in the
|
||||
archive. This option is valid only when used with one of the
|
||||
following subcommands: \fB\-\-delete\fR, \fB\-\-diff\fR,
|
||||
\fB\-\-extract\fR or \fB\-\-list\fR and when a list of files is given
|
||||
either on the command line or via the \fB\-\fRT option. The default
|
||||
either on the command line or via the \fB\-T\fR option. The default
|
||||
\fIN\fR is \fB1\fR.
|
||||
.TP
|
||||
\fB\-\-restrict\fR
|
||||
@@ -347,6 +353,9 @@ Recursively remove all files in the directory prior to extracting it.
|
||||
\fB\-\-remove\-files\fR
|
||||
Remove files from disk after adding them to the archive.
|
||||
.TP
|
||||
\fB\-\-skip\-old\-files
|
||||
Don't replace existing files when extracting, silently skip over them.
|
||||
.TP
|
||||
\fB\-U\fR, \fB\-\-unlink\-first\fR
|
||||
Remove each file prior to extracting over it.
|
||||
.TP
|
||||
@@ -464,15 +473,40 @@ Delay setting modification times and permissions of extracted
|
||||
directories until the end of extraction. Use this option when
|
||||
extracting from an archive which has unusual member ordering.
|
||||
.TP
|
||||
\fB\-\-group\fR=\fINAME\fR
|
||||
Force \fINAME\fR as group for added files.
|
||||
\fB\-\-group\fR=\fINAME\fR[:\fIGID\fR]
|
||||
Force \fINAME\fR as group for added files. If \fIGID\fR is not
|
||||
supplied, \fINAME\fR can be either a user name or numeric GID. In
|
||||
this case the missing part (GID or name) will be inferred from the
|
||||
current host's group database.
|
||||
|
||||
When used with \fB\-\-group\-map\fR=\fIFILE\fR, affects only those
|
||||
files whose owner group is not listed in \fIFILE\fR.
|
||||
.TP
|
||||
\fB\-\-group\-map\fR=\fIFILE\fR
|
||||
Read group translation map from \fIFILE\fR. Empty lines are ignored.
|
||||
Comments are introduced with \fB#\fR sign and extend to the end of line.
|
||||
Each non-empty line in \fIFILE\fR defines translation for a single
|
||||
group. It must consist of two fields, delimited by any amount of whitespace:
|
||||
|
||||
.EX
|
||||
\fIOLDGRP\fR \fINEWGRP\fR[\fB:\fINEWGID\fR]
|
||||
.EE
|
||||
|
||||
\fIOLDGRP\fR is either a valid group name or a GID prefixed with
|
||||
\fB+\fR. Unless \fINEWGID\fR is supplied, \fINEWGRP\fR must also be
|
||||
either a valid group name or a \fB+\fIGID\fR. Otherwise, both
|
||||
\fINEWGRP\fR and \fINEWGID\fR need not be listed in the system group
|
||||
database.
|
||||
|
||||
As a result, each input file with owner group \fIOLDGRP\fR will be
|
||||
stored in archive with owner group \fINEWGRP\fR and GID \fINEWGID\fR.
|
||||
.TP
|
||||
\fB\-\-mode\fR=\fICHANGES\fR
|
||||
Force symbolic mode \fICHANGES\fR for added files.
|
||||
.TP
|
||||
\fB\-\-mtime\fR=\fIDATE-OR-FILE\fR
|
||||
Set mtime for added files. \fIDATE-OR-FILE\fR is either a date/time
|
||||
in almost arbitrary formate, or the name of an existing file. In the
|
||||
in almost arbitrary format, or the name of an existing file. In the
|
||||
latter case the mtime of that file will be used.
|
||||
.TP
|
||||
\fB\-m\fR, \fB\-\-touch\fR
|
||||
@@ -491,8 +525,33 @@ Apply the user's umask when extracting permissions from the archive
|
||||
\fB\-\-numeric\-owner\fR
|
||||
Always use numbers for user/group names.
|
||||
.TP
|
||||
\fB\-\-owner\fR=\fINAME\fR
|
||||
Force \fINAME\fR as owner for added files.
|
||||
\fB\-\-owner\fR=\fINAME\fR[:\fIUID\fR]
|
||||
Force \fINAME\fR as owner for added files. If \fIUID\fR is not
|
||||
supplied, \fINAME\fR can be either a user name or numeric UID. In
|
||||
this case the missing part (UID or name) will be inferred from the
|
||||
current host's user database.
|
||||
|
||||
When used with \fB\-\-owner\-map\fR=\fIFILE\fR, affects only those
|
||||
files whose owner is not listed in \fIFILE\fR.
|
||||
.TP
|
||||
\fB\-\-owner\-map\fR=\fIFILE\fR
|
||||
Read owner translation map from \fIFILE\fR. Empty lines are ignored.
|
||||
Comments are introduced with \fB#\fR sign and extend to the end of line.
|
||||
Each non-empty line in \fIFILE\fR defines translation for a single
|
||||
UID. It must consist of two fields, delimited by any amount of whitespace:
|
||||
|
||||
.EX
|
||||
\fIOLDUSR\fR \fINEWUSR\fR[\fB:\fINEWUID\fR]
|
||||
.EE
|
||||
|
||||
\fIOLDUSR\fR is either a valid user name or a UID prefixed with
|
||||
\fB+\fR. Unless \fINEWUID\fR is supplied, \fINEWUSR\fR must also be
|
||||
either a valid user name or a \fB+\fIUID\fR. Otherwise, both
|
||||
\fINEWUSR\fR and \fINEWUID\fR need not be listed in the system user
|
||||
database.
|
||||
|
||||
As a result, each input file owned by \fIOLDUSR\fR will be
|
||||
stored in archive with owner name \fINEWUSR\fR and UID \fINEWUID\fR.
|
||||
.TP
|
||||
\fB\-p\fR, \fB\-\-preserve\-permissions\fR, \fB\-\-same\-permissions\fR
|
||||
extract information about file permissions (default for superuser)
|
||||
@@ -524,6 +583,34 @@ Using \fB\-\-sort=inode\fR reduces the number of disk seeks made when
|
||||
creating the archive and thus can considerably speed up archivation.
|
||||
This sorting order is supported only if the underlying system provides
|
||||
the necessary information.
|
||||
.SS Extended file attributes
|
||||
.TP
|
||||
.B \-\-acls
|
||||
Enable POSIX ACLs support.
|
||||
.TP
|
||||
.B \-\-no\-acls
|
||||
Disable POSIX ACLs support.
|
||||
.TP
|
||||
.B \-\-selinux
|
||||
Enable SELinux context support.
|
||||
.TP
|
||||
.B \-\-no-selinux
|
||||
Disable SELinux context support.
|
||||
.TP
|
||||
.B \-\-xattrs
|
||||
Enable extended attributes support.
|
||||
.TP
|
||||
.B \-\-no\-xattrs
|
||||
Disable extended attributes support.
|
||||
.TP
|
||||
.BI \-\-xattrs\-exclude= PATTERN
|
||||
Specify the exclude pattern for xattr keys. \fIPATTERN\fR is a POSIX
|
||||
regular expression, e.g. \fB\-\-xattrs\-exclude='^user\.'\fR, to exclude
|
||||
attributes from the user namespace.
|
||||
.TP
|
||||
.BI \-\-xattrs\-include= PATTERN
|
||||
Specify the include pattern for xattr keys. \fIPATTERN\fR is a POSIX
|
||||
regular expression.
|
||||
.SS Device selection and switching
|
||||
.TP
|
||||
\fB\-f\fR, \fB\-\-file\fR=\fIARCHIVE\fR
|
||||
@@ -557,7 +644,7 @@ instead. You can do so by giving the following command line option:
|
||||
--rsh-command=/usr/bin/ssh
|
||||
.EE
|
||||
|
||||
The remote mashine should have the
|
||||
The remote machine should have the
|
||||
.BR rmt (8)
|
||||
command installed. If its pathname does not match \fBtar\fR's
|
||||
default, you can inform \fBtar\fR about the correct pathname using the
|
||||
@@ -567,7 +654,7 @@ option.
|
||||
\fB\-\-force\-local\fR
|
||||
Archive file is local even if it has a colon.
|
||||
.TP
|
||||
\fB\-\fRF, \fB\-\-info\-script\fR=\fICOMMAND\fR, \fB\-\-new\-volume\-script\fR=\fICOMMAND\fR
|
||||
\fB\-F\fR, \fB\-\-info\-script\fR=\fICOMMAND\fR, \fB\-\-new\-volume\-script\fR=\fICOMMAND\fR
|
||||
Run \fICOMMAND\fR at the end of each tape (implies \fB\-M\fR). The
|
||||
command can include arguments. When started, it will inherit \fBtar\fR's
|
||||
environment plus the following variables:
|
||||
@@ -609,7 +696,7 @@ If the info script fails, \fBtar\fR exits; otherwise, it begins writing
|
||||
the next volume.
|
||||
.RE
|
||||
.TP
|
||||
\fB\-L\fR, \fB\-\-tape\-length\fR=\fN\fR
|
||||
\fB\-L\fR, \fB\-\-tape\-length\fR=\fIN\fR
|
||||
Change tape after writing \fIN\fRx1024 bytes. If \fIN\fR is followed
|
||||
by a size suffix (see the subsection
|
||||
.B Size suffixes
|
||||
@@ -703,7 +790,7 @@ use \fITEXT\fR as a globbing pattern for volume name.
|
||||
\fB\-a\fR, \fB\-\-auto\-compress\fR
|
||||
Use archive suffix to determine the compression program.
|
||||
.TP
|
||||
\fB\-\fRI, \fB\-\-use\-compress\-program\fI=\fICOMMAND\fR
|
||||
\fB\-I\fR, \fB\-\-use\-compress\-program\fI=\fICOMMAND\fR
|
||||
Filter data through \fICOMMAND\fR. It must accept the \fB\-d\fR
|
||||
option, for decompression. The argument can contain command line
|
||||
options.
|
||||
@@ -735,7 +822,7 @@ Do not use archive suffix to determine the compression program.
|
||||
Filter the archive through
|
||||
.BR gzip (1).
|
||||
.TP
|
||||
\fB\-\fRZ, \fB\-\-compress\fR, \fB\-\-uncompress\fR
|
||||
\fB\-Z\fR, \fB\-\-compress\fR, \fB\-\-uncompress\fR
|
||||
Filter the archive through
|
||||
.BR compress (1).
|
||||
.SS Local file selection
|
||||
@@ -768,7 +855,8 @@ environment variable. If it is not set, \fBexisting\fR is assumed.
|
||||
.RE
|
||||
.TP
|
||||
\fB\-C\fR, \fB\-\-directory\fR=\fIDIR\fR
|
||||
Change to directory DIR.
|
||||
Change to \fIDIR\fR before performing any operations. This option is
|
||||
order-sensitive, i.e. it affects all options that follow.
|
||||
.TP
|
||||
\fB\-\-exclude\fR=\fIPATTERN\fR
|
||||
Exclude files matching \fIPATTERN\fR, a
|
||||
@@ -841,9 +929,27 @@ Avoid descending automatically in directories.
|
||||
\fB\-\-no\-unquote\fR
|
||||
Do not unquote input file or member names.
|
||||
.TP
|
||||
\fB\-\-no\-verbatim\-files\-from\fR
|
||||
Treat each line read from a file list as if it were supplied in the
|
||||
command line. I.e., leading and trailing whitespace is removed and,
|
||||
if the resulting string begins with a dash, it is treated as \fBtar\fR
|
||||
command line option.
|
||||
|
||||
This is the default behavior. The \fB\-\-no\-verbatim\-files\-from\fR
|
||||
option is provided as a way to restore it after
|
||||
\fB\-\-verbatim\-files\-from\fR option.
|
||||
|
||||
This option is positional: it affects all \fB\-\-files\-from\fR
|
||||
options that occur after it in, until \fB\-\-verbatim\-files\-from\fR
|
||||
option or end of line, whichever occurs first.
|
||||
|
||||
It is implied by the \fB\-\-no\-null\fR option.
|
||||
.TP
|
||||
\fB\-\-null\fR
|
||||
Instruct subsequent \fB\-T\fR options to read null-terminated names,
|
||||
disable handling of the \fB\-C\fR option read from the file.
|
||||
Instruct subsequent \fB\-T\fR options to read null-terminated names
|
||||
verbatim (disables special handling of names that start with a dash).
|
||||
|
||||
See also \fB\-\-verbatim\-files\-from\fR.
|
||||
.TP
|
||||
\fB\-N\fR, \fB\-\-newer\fR=\fIDATE\fR, \fB\-\-after\-date\fR=\fIDATE\fR
|
||||
Only store files newer than DATE. If \fIDATE\fR starts with \fB/\fR
|
||||
@@ -865,10 +971,43 @@ unless overridden by environment variable \fBSIMPLE_BACKUP_SUFFIX\fR.
|
||||
.TP
|
||||
\fB\-T\fR, \fB\-\-files\-from\fR=\fIFILE\fR
|
||||
Get names to extract or create from \fIFILE\fR.
|
||||
|
||||
Unless specified otherwise, the \fIFILE\fR must contain a list of
|
||||
names separated by ASCII \fBLF\fR (i.e. one name per line). The
|
||||
names read are handled the same way as command line arguments. They
|
||||
undergo quote removal and word splitting, and any string that starts
|
||||
with a \fB\-\fR is handled as \fBtar\fR command line option.
|
||||
|
||||
If this behavior is undesirable, it can be turned off using the
|
||||
\fB\-\-verbatim\-files\-from\fR option.
|
||||
|
||||
The \fB\-\-null\fR option instructs \fBtar\fR that the names in
|
||||
\fIFILE\fR are separated by ASCII \fBNUL\fR character, instead of
|
||||
\fBLF\fR. It is useful if the list is generated by
|
||||
.BR find (1)
|
||||
.B \-print0
|
||||
predicate.
|
||||
.TP
|
||||
\fB\-\-unquote\fR
|
||||
Unquote file or member names (default).
|
||||
.TP
|
||||
\fB\-\-verbatim\-files\-from\fR
|
||||
Treat each line obtained from a file list as a file name, even if it
|
||||
starts with a dash. File lists are supplied with the
|
||||
\fB\-\-files\-from\fR (\fB\-T\fR) option. The default behavior is to
|
||||
handle names supplied in file lists as if they were typed in the
|
||||
command line, i.e. any names starting with a dash are treated as
|
||||
\fBtar\fR options. The \fB\-\-verbatim\-files\-from\fR option
|
||||
disables this behavior.
|
||||
|
||||
This option affects all \fB\-\-files\-from\fR options that occur after
|
||||
it in the command line. Its effect is reverted by the
|
||||
\fB\-\-no\-verbatim\-files\-from} option.
|
||||
|
||||
This option is implied by the \fB\-\-null\fR option.
|
||||
|
||||
See also \fB\-\-add\-file\fR.
|
||||
.TP
|
||||
\fB\-X\fR, \fB\-\-exclude\-from\fR=\fIFILE\fR
|
||||
Exclude files matching patterns listed in FILE.
|
||||
.SS File name transformations
|
||||
@@ -876,7 +1015,7 @@ Exclude files matching patterns listed in FILE.
|
||||
\fB\-\-strip\-components\fR=\fINUMBER\fR
|
||||
Strip \fINUMBER\fR leading components from file names on extraction.
|
||||
.TP
|
||||
\fB\-\-transform\fR=\fIEXPRESSION\dR, \fB\-\-xform\fR=\fIEXPRESSION\fR
|
||||
\fB\-\-transform\fR=\fIEXPRESSION\fR, \fB\-\-xform\fR=\fIEXPRESSION\fR
|
||||
Use sed replace \fIEXPRESSION\fR to transform file names.
|
||||
.SS File name matching options
|
||||
These options affect both exclude and include patterns.
|
||||
@@ -912,6 +1051,9 @@ Display progress messages every \fIN\fRth record (default 10).
|
||||
\fB\-\-checkpoint\-action\fR=\fIACTION\fR
|
||||
Run \fIACTION\fR on each checkpoint.
|
||||
.TP
|
||||
\fB\-\-clamp\-mtime\fR
|
||||
Only set time when the file is more recent than what was given with \-\-mtime.
|
||||
.TP
|
||||
\fB\-\-full\-time\fR
|
||||
Print file time to its full resolution.
|
||||
.TP
|
||||
@@ -1021,6 +1163,9 @@ Keywords applicable for \fBtar --create\fR:
|
||||
.HP
|
||||
Keywords applicable for \fBtar --extract\fR:
|
||||
.TP
|
||||
.B existing\-file
|
||||
"%s: skipping existing file"
|
||||
.TP
|
||||
.B timestamp
|
||||
"%s: implausibly old time stamp %s"
|
||||
.br
|
||||
|
||||
900
doc/tar.texi
900
doc/tar.texi
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
# Copyright 2006-2007, 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2006-2007, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@c This is part of GNU tar manual.
|
||||
@c Copyright 1992, 1994-1997, 1999-2006, 2013-2014 Free Software
|
||||
@c Copyright 1992, 1994-1997, 1999-2006, 2013-2014, 2016 Free Software
|
||||
@c Foundation, Inc.
|
||||
@c See file tar.texi for copying conditions.
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# Make the subset of Gnulib that GNU tar needs.
|
||||
include gnulib.mk
|
||||
AM_CFLAGS += $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS)
|
||||
1
gnulib
Submodule
1
gnulib
Submodule
Submodule gnulib added at 1029a81122
@@ -18,8 +18,8 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
acl
|
||||
alloca
|
||||
areadlinkat-with-size
|
||||
argmatch
|
||||
argp
|
||||
argp-version-etc
|
||||
@@ -37,6 +37,7 @@ fchownat
|
||||
fcntl-h
|
||||
fdopendir
|
||||
fdutimensat
|
||||
file-has-acl
|
||||
fileblocks
|
||||
fnmatch-gnu
|
||||
fprintftime
|
||||
@@ -65,8 +66,6 @@ modechange
|
||||
obstack
|
||||
openat
|
||||
parse-datetime
|
||||
posix_openpt
|
||||
ptsname
|
||||
priv-set
|
||||
progname
|
||||
quote
|
||||
@@ -92,10 +91,10 @@ strtoul
|
||||
strtoumax
|
||||
symlinkat
|
||||
timespec
|
||||
timespec-sub
|
||||
unlinkat
|
||||
unlinkdir
|
||||
unlocked-io
|
||||
unlockpt
|
||||
utimensat
|
||||
version-etc-fsf
|
||||
xalloc
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Makefile for GNU tar library. -*- Makefile -*-
|
||||
|
||||
# Copyright 1994-1997, 1999-2001, 2003-2007, 2009-2010, 2013-2014 Free
|
||||
# Software Foundation, Inc.
|
||||
# Copyright 1994-1997, 1999-2001, 2003-2007, 2009-2010, 2013-2014, 2016
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
@@ -41,7 +41,6 @@ noinst_HEADERS = \
|
||||
|
||||
libtar_a_SOURCES = \
|
||||
paxerror.c paxexit-status.c paxlib.h paxnames.c \
|
||||
prepargs.c prepargs.h \
|
||||
rtapelib.c \
|
||||
rmt.h \
|
||||
stdopen.c stdopen.h \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Replacement <attr/xattr.h> for platforms that lack it.
|
||||
Copyright 2012-2014 Free Software Foundation, Inc.
|
||||
Copyright 2012-2014, 2016 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
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
/* Parse arguments from a string and prepend them to an argv.
|
||||
Copyright 1999-2001, 2007, 2013-2014 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 3, 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, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paul Eggert <eggert@twinsun.com>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "prepargs.h"
|
||||
#include <sys/types.h>
|
||||
#include <xalloc.h>
|
||||
|
||||
#if HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
/* Find the white-space-separated options specified by OPTIONS, and
|
||||
using BUF to store copies of these options, set ARGV[0], ARGV[1],
|
||||
etc. to the option copies. Return the number N of options found.
|
||||
Do not set ARGV[N]. If ARGV is null, do not store ARGV[0]
|
||||
etc. Backslash can be used to escape whitespace (and backslashes). */
|
||||
static int
|
||||
prepend_args (char const *options, char *buf, char **argv)
|
||||
{
|
||||
char const *o = options;
|
||||
char *b = buf;
|
||||
int n = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
while (isspace ((unsigned char) *o))
|
||||
o++;
|
||||
if (!*o)
|
||||
return n;
|
||||
if (argv)
|
||||
argv[n] = b;
|
||||
n++;
|
||||
|
||||
do
|
||||
if ((*b++ = *o++) == '\\' && *o)
|
||||
b[-1] = *o++;
|
||||
while (*o && ! isspace ((unsigned char) *o));
|
||||
|
||||
*b++ = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepend the whitespace-separated options in OPTIONS to the argument
|
||||
vector of a main program with argument count *PARGC and argument
|
||||
vector *PARGV. */
|
||||
void
|
||||
prepend_default_options (char const *options, int *pargc, char ***pargv)
|
||||
{
|
||||
if (options)
|
||||
{
|
||||
char *buf = xmalloc (strlen (options) + 1);
|
||||
int prepended = prepend_args (options, buf, (char **) 0);
|
||||
int argc = *pargc;
|
||||
char * const *argv = *pargv;
|
||||
char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp);
|
||||
*pargc = prepended + argc;
|
||||
*pargv = pp;
|
||||
*pp++ = *argv++;
|
||||
pp += prepend_args (options, buf, pp);
|
||||
while ((*pp++ = *argv++))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
/* Parse arguments from a string and prepend them to an argv. */
|
||||
|
||||
void prepend_default_options (char const *, int *, char ***);
|
||||
@@ -1,6 +1,6 @@
|
||||
/* stdopen.c - ensure that the three standard file descriptors are in use
|
||||
|
||||
Copyright 2005, 2007, 2013-2014 Free Software Foundation, Inc.
|
||||
Copyright 2005, 2007, 2013-2014, 2016 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* wordsplit - a word splitter
|
||||
Copyright (C) 2009-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 2009-2014, 2016 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
|
||||
@@ -61,7 +61,7 @@ _wsplt_alloc_die (struct wordsplit *wsp)
|
||||
abort ();
|
||||
}
|
||||
|
||||
static void __attribute__ ((__format__ (__printf__, 1, 2)))
|
||||
static void __WORDSPLIT_ATTRIBUTE_FORMAT ((__printf__, 1, 2))
|
||||
_wsplt_error (const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@@ -221,7 +221,7 @@ struct wordsplit_node
|
||||
{
|
||||
struct wordsplit_node *prev; /* Previous element */
|
||||
struct wordsplit_node *next; /* Next element */
|
||||
int flags; /* Node flags */
|
||||
unsigned flags; /* Node flags */
|
||||
union
|
||||
{
|
||||
struct
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* wordsplit - a word splitter
|
||||
Copyright (C) 2009-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 2009-2014, 2016 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
|
||||
@@ -22,6 +22,12 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#if 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
|
||||
# define __WORDSPLIT_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
|
||||
#else
|
||||
# define __WORDSPLIT_ATTRIBUTE_FORMAT(spec) /* empty */
|
||||
#endif
|
||||
|
||||
struct wordsplit
|
||||
{
|
||||
size_t ws_wordc;
|
||||
@@ -34,9 +40,9 @@ struct wordsplit
|
||||
const char *ws_escape;
|
||||
void (*ws_alloc_die) (struct wordsplit * wsp);
|
||||
void (*ws_error) (const char *, ...)
|
||||
__attribute__ ((__format__ (__printf__, 1, 2)));
|
||||
__WORDSPLIT_ATTRIBUTE_FORMAT ((__printf__, 1, 2));
|
||||
void (*ws_debug) (const char *, ...)
|
||||
__attribute__ ((__format__ (__printf__, 1, 2)));
|
||||
__WORDSPLIT_ATTRIBUTE_FORMAT ((__printf__, 1, 2));
|
||||
|
||||
const char **ws_env;
|
||||
const char *(*ws_getvar) (const char *, size_t, void *);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* openat-style fd-relative functions for operating with extended file
|
||||
attributes.
|
||||
|
||||
Copyright 2012-2014 Free Software Foundation, Inc.
|
||||
Copyright 2012-2014, 2016 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
|
||||
@@ -31,6 +31,8 @@
|
||||
|
||||
#include "openat-priv.h"
|
||||
|
||||
#ifdef HAVE_XATTRS
|
||||
|
||||
/* setxattrat */
|
||||
#define AT_FUNC_NAME setxattrat
|
||||
#define AT_FUNC_F1 setxattr
|
||||
@@ -108,3 +110,5 @@
|
||||
#undef AT_FUNC_RESULT
|
||||
#undef AT_FUNC_POST_FILE_PARAM_DECLS
|
||||
#undef AT_FUNC_POST_FILE_ARGS
|
||||
|
||||
#endif /* HAVE_XATTRS */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Prototypes for openat-style fd-relative functions for operating with
|
||||
extended file attributes.
|
||||
|
||||
Copyright 2012-2014 Free Software Foundation, Inc.
|
||||
Copyright 2012-2014, 2016 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
|
||||
|
||||
1
paxutils
Submodule
1
paxutils
Submodule
Submodule paxutils added at ec72abd9dd
2
po/.gitignore
vendored
2
po/.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
/Makevars.template~
|
||||
/Makefile.in.in~
|
||||
*.gmo
|
||||
*.mo
|
||||
*.po
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# List of files which contain translatable strings.
|
||||
|
||||
# Copyright 1996, 1999-2000, 2003-2005, 2007, 2013-2014 Free Software
|
||||
# Foundation, Inc.
|
||||
# Copyright 1996, 1999-2000, 2003-2005, 2007, 2013-2014, 2016 Free
|
||||
# Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Make GNU tar scripts.
|
||||
|
||||
# Copyright 2004, 2006-2007, 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2004, 2006-2007, 2013-2014, 2016 Free Software Foundation,
|
||||
# Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ SLEEP_MESSAGE="`awk '
|
||||
}' /dev/null`"
|
||||
|
||||
|
||||
# Copyright 2004, 2007, 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2004, 2007, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#! /bin/sh
|
||||
# Make backups.
|
||||
|
||||
# Copyright 2004-2006, 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2004-2006, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
# interested parties that a tape for the next volume of the backup needs to
|
||||
# be put in the tape drive.
|
||||
|
||||
# Copyright 2004-2005, 2010, 2012-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2004-2005, 2010, 2012-2014, 2016 Free Software Foundation,
|
||||
# Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#! /bin/sh
|
||||
# Restore backups.
|
||||
|
||||
# Copyright 2004, 2006, 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2004, 2006, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /usr/bin/perl -w
|
||||
# Display and edit the 'dev' field in tar's snapshots
|
||||
# Copyright 2007, 2011, 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2007, 2011, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
# concatenates a GNU tar multi-volume archive into a single tar archive.
|
||||
# Author: Bruno Haible <bruno@clisp.org>, Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
# Copyright 2004-2005, 2010, 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2004-2005, 2010, 2013-2014, 2016 Free Software Foundation,
|
||||
# Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/* xsparse - expands compressed sparse file images extracted from GNU tar
|
||||
archives.
|
||||
|
||||
Copyright 2006-2007, 2010, 2013-2014 Free Software Foundation, Inc.
|
||||
Copyright 2006-2007, 2010, 2013-2014, 2016 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Makefile for GNU tar sources.
|
||||
|
||||
# Copyright 1994-1997, 1999-2001, 2003, 2006-2007, 2009, 2013-2014 Free
|
||||
# Software Foundation, Inc.
|
||||
# Copyright 1994-1997, 1999-2001, 2003, 2006-2007, 2009, 2013-2014, 2016
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
@@ -33,6 +33,7 @@ tar_SOURCES = \
|
||||
xheader.c\
|
||||
incremen.c\
|
||||
list.c\
|
||||
map.c\
|
||||
misc.c\
|
||||
names.c\
|
||||
sparse.c\
|
||||
@@ -52,7 +53,3 @@ AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
|
||||
LDADD = ../lib/libtar.a ../gnu/libgnu.a $(LIBINTL) $(LIBICONV)
|
||||
|
||||
tar_LDADD = $(LIBS) $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS) $(LIB_SELINUX)
|
||||
|
||||
if TAR_LIB_ATTR
|
||||
tar_LDADD += -lattr
|
||||
endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Long integers, for GNU tar.
|
||||
Copyright 1999, 2007, 2013-2014 Free Software Foundation, Inc.
|
||||
Copyright 1999, 2007, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
70
src/buffer.c
70
src/buffer.c
@@ -1,6 +1,6 @@
|
||||
/* Buffer management for tar.
|
||||
|
||||
Copyright 1988, 1992-1994, 1996-1997, 1999-2010, 2013-2014 Free
|
||||
Copyright 1988, 1992-1994, 1996-1997, 1999-2010, 2013-2014, 2016 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
@@ -391,7 +391,10 @@ check_compressed_archive (bool *pshort)
|
||||
/* Restore global values */
|
||||
read_full_records = sfr;
|
||||
|
||||
if (tar_checksum (record_start, true) == HEADER_SUCCESS)
|
||||
if ((strcmp (record_start->header.magic, TMAGIC) == 0 ||
|
||||
strcmp (record_start->buffer + offsetof (struct posix_header, magic),
|
||||
OLDGNU_MAGIC) == 0) &&
|
||||
tar_checksum (record_start, true) == HEADER_SUCCESS)
|
||||
/* Probably a valid header */
|
||||
return ct_tar;
|
||||
|
||||
@@ -495,7 +498,7 @@ print_stats (FILE *fp, const char *text, tarlong numbytes)
|
||||
char abbr[LONGEST_HUMAN_READABLE + 1];
|
||||
char rate[LONGEST_HUMAN_READABLE + 1];
|
||||
int n = 0;
|
||||
|
||||
|
||||
int human_opts = human_autoscale | human_base_1024 | human_SI | human_B;
|
||||
|
||||
if (text && text[0])
|
||||
@@ -512,12 +515,12 @@ print_stats (FILE *fp, const char *text, tarlong numbytes)
|
||||
before each data item (bytes read, written, deleted, in that order).
|
||||
EOR is a delimiter to output after each item (used only if deleting
|
||||
from the archive), EOL is a delimiter to add at the end of the output
|
||||
line. */
|
||||
line. */
|
||||
int
|
||||
format_total_stats (FILE *fp, const char **formats, int eor, int eol)
|
||||
format_total_stats (FILE *fp, char const *const *formats, int eor, int eol)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
||||
switch (subcommand_option)
|
||||
{
|
||||
case CREATE_SUBCOMMAND:
|
||||
@@ -536,7 +539,7 @@ format_total_stats (FILE *fp, const char **formats, int eor, int eol)
|
||||
|
||||
fputc (eor, fp);
|
||||
n++;
|
||||
|
||||
|
||||
n += print_stats (fp, formats[TF_WRITE],
|
||||
prev_written + bytes_written);
|
||||
|
||||
@@ -570,7 +573,7 @@ format_total_stats (FILE *fp, const char **formats, int eor, int eol)
|
||||
return n;
|
||||
}
|
||||
|
||||
const char *default_total_format[] = {
|
||||
static char const *const default_total_format[] = {
|
||||
N_("Total bytes read"),
|
||||
/* Amanda 2.4.1p1 looks for "Total bytes written: [0-9][0-9]*". */
|
||||
N_("Total bytes written"),
|
||||
@@ -980,18 +983,28 @@ short_read (size_t status)
|
||||
void
|
||||
flush_archive (void)
|
||||
{
|
||||
size_t buffer_level = current_block->buffer - record_start->buffer;
|
||||
record_start_block += record_end - record_start;
|
||||
current_block = record_start;
|
||||
record_end = record_start + blocking_factor;
|
||||
|
||||
size_t buffer_level;
|
||||
|
||||
if (access_mode == ACCESS_READ && time_to_start_writing)
|
||||
{
|
||||
access_mode = ACCESS_WRITE;
|
||||
time_to_start_writing = false;
|
||||
backspace_output ();
|
||||
if (record_end - record_start < blocking_factor)
|
||||
{
|
||||
memset (record_end, 0,
|
||||
(blocking_factor - (record_end - record_start))
|
||||
* BLOCKSIZE);
|
||||
record_end = record_start + blocking_factor;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
buffer_level = current_block->buffer - record_start->buffer;
|
||||
record_start_block += record_end - record_start;
|
||||
current_block = record_start;
|
||||
record_end = record_start + blocking_factor;
|
||||
|
||||
switch (access_mode)
|
||||
{
|
||||
case ACCESS_READ:
|
||||
@@ -1031,7 +1044,7 @@ backspace_output (void)
|
||||
|
||||
/* Seek back to the beginning of this record and start writing there. */
|
||||
|
||||
position -= record_size;
|
||||
position -= record_end->buffer - record_start->buffer;
|
||||
if (position < 0)
|
||||
position = 0;
|
||||
if (rmtlseek (archive, position, SEEK_SET) != position)
|
||||
@@ -1112,6 +1125,16 @@ close_archive (void)
|
||||
bufmap_free (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
write_fatal_details (char const *name, ssize_t status, size_t size)
|
||||
{
|
||||
write_error_details (name, status, size);
|
||||
if (rmtclose (archive) != 0)
|
||||
close_error (*archive_name_cursor);
|
||||
sys_wait_for_child (child_pid, false);
|
||||
fatal_exit ();
|
||||
}
|
||||
|
||||
/* Called to initialize the global volume number. */
|
||||
void
|
||||
init_volume_number (void)
|
||||
@@ -1406,7 +1429,10 @@ try_new_volume (void)
|
||||
|
||||
header = find_next_block ();
|
||||
if (!header)
|
||||
return false;
|
||||
{
|
||||
WARN ((0, 0, _("This does not look like a tar archive")));
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (header->header.typeflag)
|
||||
{
|
||||
@@ -1416,7 +1442,7 @@ try_new_volume (void)
|
||||
if (read_header (&header, &dummy, read_header_x_global)
|
||||
!= HEADER_SUCCESS_EXTENDED)
|
||||
{
|
||||
ERROR ((0, 0, _("This does not look like a tar archive")));
|
||||
WARN ((0, 0, _("This does not look like a tar archive")));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1445,7 +1471,7 @@ try_new_volume (void)
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR ((0, 0, _("This does not look like a tar archive")));
|
||||
WARN ((0, 0, _("This does not look like a tar archive")));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@@ -1480,8 +1506,14 @@ try_new_volume (void)
|
||||
if (bufmap_head)
|
||||
{
|
||||
uintmax_t s;
|
||||
if (!continued_file_name
|
||||
|| strcmp (continued_file_name, bufmap_head->file_name))
|
||||
if (!continued_file_name)
|
||||
{
|
||||
WARN ((0, 0, _("%s is not continued on this volume"),
|
||||
quote (bufmap_head->file_name)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strcmp (continued_file_name, bufmap_head->file_name))
|
||||
{
|
||||
if ((archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
|
||||
&& strlen (bufmap_head->file_name) >= NAME_FIELD_SIZE
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Checkpoint management for tar.
|
||||
|
||||
Copyright 2007, 2013-2014 Free Software Foundation, Inc.
|
||||
Copyright 2007, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
84
src/common.h
84
src/common.h
@@ -1,6 +1,6 @@
|
||||
/* Common declarations for the tar program.
|
||||
|
||||
Copyright 1988, 1992-1994, 1996-1997, 1999-2010, 2012-2014 Free
|
||||
Copyright 1988, 1992-1994, 1996-1997, 1999-2010, 2012-2016 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
@@ -211,13 +211,20 @@ GLOBAL bool multi_volume_option;
|
||||
do not get archived (also see after_date_option above). */
|
||||
GLOBAL struct timespec newer_mtime_option;
|
||||
|
||||
/* If true, override actual mtime (see below) */
|
||||
GLOBAL bool set_mtime_option;
|
||||
/* Value to be put in mtime header field instead of the actual mtime */
|
||||
enum set_mtime_option_mode
|
||||
{
|
||||
USE_FILE_MTIME,
|
||||
FORCE_MTIME,
|
||||
CLAMP_MTIME,
|
||||
};
|
||||
|
||||
/* Override actual mtime if set to FORCE_MTIME or CLAMP_MTIME */
|
||||
GLOBAL enum set_mtime_option_mode set_mtime_option;
|
||||
/* Value to use when forcing or clamping the mtime header field. */
|
||||
GLOBAL struct timespec mtime_option;
|
||||
|
||||
/* Return true if newer_mtime_option is initialized. */
|
||||
#define NEWER_OPTION_INITIALIZED(opt) (0 <= (opt).tv_nsec)
|
||||
/* Return true if mtime_option or newer_mtime_option is initialized. */
|
||||
#define TIME_OPTION_INITIALIZED(opt) (0 <= (opt).tv_nsec)
|
||||
|
||||
/* Return true if the struct stat ST's M time is less than
|
||||
newer_mtime_option. */
|
||||
@@ -280,6 +287,15 @@ GLOBAL bool sparse_option;
|
||||
GLOBAL unsigned tar_sparse_major;
|
||||
GLOBAL unsigned tar_sparse_minor;
|
||||
|
||||
enum hole_detection_method
|
||||
{
|
||||
HOLE_DETECTION_DEFAULT,
|
||||
HOLE_DETECTION_RAW,
|
||||
HOLE_DETECTION_SEEK
|
||||
};
|
||||
|
||||
GLOBAL enum hole_detection_method hole_detection;
|
||||
|
||||
GLOBAL bool starting_file_option;
|
||||
|
||||
/* Specified maximum byte length of each tape volume (multiple of 1024). */
|
||||
@@ -399,9 +415,8 @@ GLOBAL bool show_transformed_names_option;
|
||||
set for incremental archives. */
|
||||
GLOBAL bool delay_directory_restore_option;
|
||||
|
||||
/* Warn about implicit use of the wildcards in command line arguments.
|
||||
(Default for tar prior to 1.15.91, but changed afterwards */
|
||||
GLOBAL bool warn_regex_usage;
|
||||
/* When set, tar will not refuse to create empty archives */
|
||||
GLOBAL bool files_from_option;
|
||||
|
||||
/* Declarations for each module. */
|
||||
|
||||
@@ -453,7 +468,7 @@ void set_start_time (void);
|
||||
#define TF_READ 0
|
||||
#define TF_WRITE 1
|
||||
#define TF_DELETED 2
|
||||
int format_total_stats (FILE *fp, const char **formats, int eor, int eol);
|
||||
int format_total_stats (FILE *fp, char const *const *formats, int eor, int eol);
|
||||
void print_total_stats (void);
|
||||
|
||||
void mv_begin_write (const char *file_name, off_t totsize, off_t sizeleft);
|
||||
@@ -523,6 +538,8 @@ void extract_archive (void);
|
||||
void extract_finish (void);
|
||||
bool rename_directory (char *src, char *dst);
|
||||
|
||||
void remove_delayed_set_stat (const char *fname);
|
||||
|
||||
/* Module delete.c. */
|
||||
|
||||
void delete_archive_members (void);
|
||||
@@ -618,8 +635,6 @@ typedef struct namebuf *namebuf_t;
|
||||
namebuf_t namebuf_create (const char *dir);
|
||||
void namebuf_free (namebuf_t buf);
|
||||
char *namebuf_name (namebuf_t buf, const char *name);
|
||||
void namebuf_add_dir (namebuf_t buf, const char *name);
|
||||
char *namebuf_finish (namebuf_t buf);
|
||||
|
||||
const char *tar_dirname (void);
|
||||
|
||||
@@ -723,9 +738,7 @@ void uid_to_uname (uid_t uid, char **uname);
|
||||
int uname_to_uid (char const *uname, uid_t *puid);
|
||||
|
||||
void name_init (void);
|
||||
void name_add_name (const char *name, int matching_flags);
|
||||
void name_add_dir (const char *name);
|
||||
void name_add_file (const char *name, int term);
|
||||
void name_add_name (const char *name);
|
||||
void name_term (void);
|
||||
const char *name_next (int change_dirs);
|
||||
void name_gather (void);
|
||||
@@ -739,7 +752,7 @@ void collect_and_sort_names (void);
|
||||
struct name *name_scan (const char *name);
|
||||
struct name const *name_from_list (void);
|
||||
void blank_name_list (void);
|
||||
char *new_name (const char *dir_name, const char *name);
|
||||
char *make_file_name (const char *dir_name, const char *name);
|
||||
size_t stripped_prefix_len (char const *file_name, size_t num);
|
||||
bool all_names_found (struct tar_stat_info *st);
|
||||
|
||||
@@ -748,10 +761,12 @@ bool is_avoided_name (char const *name);
|
||||
|
||||
bool contains_dot_dot (char const *name);
|
||||
|
||||
#define ISFOUND(c) ((occurrence_option == 0) ? (c)->found_count : \
|
||||
(c)->found_count == occurrence_option)
|
||||
#define WASFOUND(c) ((occurrence_option == 0) ? (c)->found_count : \
|
||||
(c)->found_count >= occurrence_option)
|
||||
#define ISFOUND(c) (occurrence_option == 0 \
|
||||
? (c)->found_count != 0 \
|
||||
: (c)->found_count == occurrence_option)
|
||||
#define WASFOUND(c) (occurrence_option == 0 \
|
||||
? (c)->found_count != 0 \
|
||||
: (c)->found_count >= occurrence_option)
|
||||
|
||||
/* Module tar.c. */
|
||||
|
||||
@@ -769,7 +784,26 @@ const char *subcommand_string (enum subcommand c);
|
||||
void set_exit_status (int val);
|
||||
|
||||
void request_stdin (const char *option);
|
||||
void more_options (int argc, char **argv);
|
||||
|
||||
/* Where an option comes from: */
|
||||
enum option_source
|
||||
{
|
||||
OPTS_ENVIRON, /* Environment variable TAR_OPTIONS */
|
||||
OPTS_COMMAND_LINE, /* Command line */
|
||||
OPTS_FILE /* File supplied by --files-from */
|
||||
};
|
||||
|
||||
/* Option location */
|
||||
struct option_locus
|
||||
{
|
||||
enum option_source source; /* Option origin */
|
||||
char const *name; /* File or variable name */
|
||||
size_t line; /* Number of input line if source is OPTS_FILE */
|
||||
struct option_locus *prev; /* Previous occurrence of the option of same
|
||||
class */
|
||||
};
|
||||
|
||||
void more_options (int argc, char **argv, struct option_locus *loc);
|
||||
|
||||
/* Module update.c. */
|
||||
|
||||
@@ -926,9 +960,15 @@ extern void (*fatal_exit_hook) (void);
|
||||
|
||||
void excfile_add (const char *name, int flags);
|
||||
void info_attach_exclist (struct tar_stat_info *dir);
|
||||
void info_cleanup_exclist (struct tar_stat_info *dir);
|
||||
void info_free_exclist (struct tar_stat_info *dir);
|
||||
bool excluded_name (char const *name, struct tar_stat_info *st);
|
||||
void exclude_vcs_ignores (void);
|
||||
|
||||
/* Module map.c */
|
||||
void owner_map_read (char const *name);
|
||||
int owner_map_translate (uid_t uid, uid_t *new_uid, char const **new_name);
|
||||
void group_map_read (char const *file);
|
||||
int group_map_translate (gid_t gid, gid_t *new_gid, char const **new_name);
|
||||
|
||||
|
||||
_GL_INLINE_HEADER_END
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Diff files from a tar archive.
|
||||
|
||||
Copyright 1988, 1992-1994, 1996-1997, 1999-2001, 2003-2007,
|
||||
2009-2010, 2012-2014 Free Software Foundation, Inc.
|
||||
2009-2010, 2012-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -270,11 +270,12 @@ diff_link (void)
|
||||
static void
|
||||
diff_symlink (void)
|
||||
{
|
||||
char buf[1024];
|
||||
size_t len = strlen (current_stat_info.link_name);
|
||||
char *linkbuf = alloca (len + 1);
|
||||
char *linkbuf = len < sizeof buf ? buf : xmalloc (len + 1);
|
||||
|
||||
int status = readlinkat (chdir_fd, current_stat_info.file_name,
|
||||
linkbuf, len + 1);
|
||||
ssize_t status = readlinkat (chdir_fd, current_stat_info.file_name,
|
||||
linkbuf, len + 1);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
@@ -285,8 +286,11 @@ diff_symlink (void)
|
||||
report_difference (¤t_stat_info, NULL);
|
||||
}
|
||||
else if (status != len
|
||||
|| strncmp (current_stat_info.link_name, linkbuf, len) != 0)
|
||||
|| memcmp (current_stat_info.link_name, linkbuf, len) != 0)
|
||||
report_difference (¤t_stat_info, _("Symlink differs"));
|
||||
|
||||
if (linkbuf != buf)
|
||||
free (linkbuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
67
src/create.c
67
src/create.c
@@ -1,7 +1,7 @@
|
||||
/* Create a tar archive.
|
||||
|
||||
Copyright 1985, 1992-1994, 1996-1997, 1999-2001, 2003-2007,
|
||||
2009-2010, 2012-2014 Free Software Foundation, Inc.
|
||||
2009-2010, 2012-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <system.h>
|
||||
|
||||
#include <areadlink.h>
|
||||
#include <quotearg.h>
|
||||
|
||||
#include "common.h"
|
||||
@@ -706,7 +707,7 @@ write_extended (bool global, struct tar_stat_info *st, union block *old_header)
|
||||
{
|
||||
type = XHDTYPE;
|
||||
p = xheader_xhdr_name (st);
|
||||
t = st->stat.st_mtime;
|
||||
t = set_mtime_option ? mtime_option.tv_sec : st->stat.st_mtime;
|
||||
}
|
||||
xheader_write (type, p, t, &st->xhdr);
|
||||
free (p);
|
||||
@@ -740,17 +741,17 @@ union block *
|
||||
start_header (struct tar_stat_info *st)
|
||||
{
|
||||
union block *header;
|
||||
|
||||
char const *uname = NULL;
|
||||
char const *gname = NULL;
|
||||
|
||||
header = write_header_name (st);
|
||||
if (!header)
|
||||
return NULL;
|
||||
|
||||
/* Override some stat fields, if requested to do so. */
|
||||
owner_map_translate (st->stat.st_uid, &st->stat.st_uid, &uname);
|
||||
group_map_translate (st->stat.st_gid, &st->stat.st_gid, &gname);
|
||||
|
||||
if (owner_option != (uid_t) -1)
|
||||
st->stat.st_uid = owner_option;
|
||||
if (group_option != (gid_t) -1)
|
||||
st->stat.st_gid = group_option;
|
||||
if (mode_option)
|
||||
st->stat.st_mode =
|
||||
((st->stat.st_mode & ~MODE_ALL)
|
||||
@@ -822,7 +823,24 @@ start_header (struct tar_stat_info *st)
|
||||
}
|
||||
|
||||
{
|
||||
struct timespec mtime = set_mtime_option ? mtime_option : st->mtime;
|
||||
struct timespec mtime;
|
||||
|
||||
switch (set_mtime_option)
|
||||
{
|
||||
case USE_FILE_MTIME:
|
||||
mtime = st->mtime;
|
||||
break;
|
||||
|
||||
case FORCE_MTIME:
|
||||
mtime = mtime_option;
|
||||
break;
|
||||
|
||||
case CLAMP_MTIME:
|
||||
mtime = timespec_cmp (st->mtime, mtime_option) > 0
|
||||
? mtime_option : st->mtime;
|
||||
break;
|
||||
}
|
||||
|
||||
if (archive_format == POSIX_FORMAT)
|
||||
{
|
||||
if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec
|
||||
@@ -909,13 +927,13 @@ start_header (struct tar_stat_info *st)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (owner_name_option)
|
||||
st->uname = xstrdup (owner_name_option);
|
||||
if (uname)
|
||||
st->uname = xstrdup (uname);
|
||||
else
|
||||
uid_to_uname (st->stat.st_uid, &st->uname);
|
||||
|
||||
if (group_name_option)
|
||||
st->gname = xstrdup (group_name_option);
|
||||
if (gname)
|
||||
st->gname = xstrdup (gname);
|
||||
else
|
||||
gid_to_gname (st->stat.st_gid, &st->gname);
|
||||
|
||||
@@ -1114,7 +1132,7 @@ dump_dir0 (struct tar_stat_info *st, char const *directory)
|
||||
return;
|
||||
|
||||
info_attach_exclist (st);
|
||||
|
||||
|
||||
if (incremental_option && archive_format != POSIX_FORMAT)
|
||||
blk->header.typeflag = GNUTYPE_DUMPDIR;
|
||||
else /* if (standard_option) */
|
||||
@@ -1198,7 +1216,7 @@ dump_dir0 (struct tar_stat_info *st, char const *directory)
|
||||
char const *entry;
|
||||
size_t entry_len;
|
||||
size_t name_len;
|
||||
|
||||
|
||||
name_buf = xstrdup (st->orig_file_name);
|
||||
name_size = name_len = strlen (name_buf);
|
||||
|
||||
@@ -1472,8 +1490,8 @@ dump_hard_link (struct tar_stat_info *st)
|
||||
/* We found a link. */
|
||||
char const *link_name = safer_name_suffix (duplicate->name, true,
|
||||
absolute_names_option);
|
||||
|
||||
duplicate->nlink--;
|
||||
if (duplicate->nlink)
|
||||
duplicate->nlink--;
|
||||
|
||||
block_ordinal = current_block_ordinal ();
|
||||
assign_string (&st->link_name, link_name);
|
||||
@@ -1837,22 +1855,17 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
|
||||
#ifdef HAVE_READLINK
|
||||
else if (S_ISLNK (st->stat.st_mode))
|
||||
{
|
||||
char *buffer;
|
||||
int size;
|
||||
size_t linklen = st->stat.st_size;
|
||||
if (linklen != st->stat.st_size || linklen + 1 == 0)
|
||||
xalloc_die ();
|
||||
buffer = (char *) alloca (linklen + 1);
|
||||
size = readlinkat (parentfd, name, buffer, linklen + 1);
|
||||
if (size < 0)
|
||||
st->link_name = areadlinkat_with_size (parentfd, name, st->stat.st_size);
|
||||
if (!st->link_name)
|
||||
{
|
||||
if (errno == ENOMEM)
|
||||
xalloc_die ();
|
||||
file_removed_diag (p, top_level, readlink_diag);
|
||||
return;
|
||||
}
|
||||
buffer[size] = '\0';
|
||||
assign_string (&st->link_name, buffer);
|
||||
transform_name (&st->link_name, XFORM_SYMLINK);
|
||||
if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size)
|
||||
if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT)
|
||||
< strlen (st->link_name))
|
||||
write_long_link (st);
|
||||
|
||||
xattrs_selinux_get (parentfd, name, st, 0);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Delete entries from a tar archive.
|
||||
|
||||
Copyright 1988, 1992, 1994, 1996-1997, 2000-2001, 2003-2006, 2010,
|
||||
2013-2014 Free Software Foundation, Inc.
|
||||
2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Per-directory exclusion files for tar.
|
||||
|
||||
Copyright 2014 Free Software Foundation, Inc.
|
||||
Copyright 2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -43,7 +43,7 @@ struct excfile
|
||||
char name[1];
|
||||
};
|
||||
|
||||
struct excfile *excfile_head, *excfile_tail;
|
||||
static struct excfile *excfile_head, *excfile_tail;
|
||||
|
||||
void
|
||||
excfile_add (const char *name, int flags)
|
||||
@@ -72,7 +72,7 @@ info_attach_exclist (struct tar_stat_info *dir)
|
||||
struct excfile *file;
|
||||
struct exclist *head = NULL, *tail = NULL, *ent;
|
||||
struct vcs_ignore_file *vcsfile;
|
||||
|
||||
|
||||
if (dir->exclude_list)
|
||||
return;
|
||||
for (file = excfile_head; file; file = file->next)
|
||||
@@ -102,7 +102,7 @@ info_attach_exclist (struct tar_stat_info *dir)
|
||||
|
||||
if (vcsfile->initfn)
|
||||
vcsfile->data = vcsfile->initfn (vcsfile->data);
|
||||
|
||||
|
||||
if (add_exclude_fp (vcsfile->addfn, ex, fp,
|
||||
EXCLUDE_WILDCARDS|EXCLUDE_ANCHORED, '\n',
|
||||
vcsfile->data))
|
||||
@@ -111,7 +111,7 @@ info_attach_exclist (struct tar_stat_info *dir)
|
||||
FATAL_ERROR ((0, e, "%s", quotearg_colon (file->name)));
|
||||
}
|
||||
fclose (fp);
|
||||
|
||||
|
||||
ent = xmalloc (sizeof (*ent));
|
||||
ent->excluded = ex;
|
||||
ent->flags = file->flags == EXCL_DEFAULT
|
||||
@@ -129,34 +129,6 @@ info_attach_exclist (struct tar_stat_info *dir)
|
||||
dir->exclude_list = head;
|
||||
}
|
||||
|
||||
void
|
||||
info_cleanup_exclist (struct tar_stat_info *dir)
|
||||
{
|
||||
struct exclist *ep = dir->exclude_list;
|
||||
|
||||
while (ep)
|
||||
{
|
||||
struct exclist *next = ep->next;
|
||||
|
||||
if (ep->flags & EXCL_NON_RECURSIVE)
|
||||
{
|
||||
|
||||
/* Remove the entry */
|
||||
if (ep->prev)
|
||||
ep->prev->next = ep->next;
|
||||
else
|
||||
dir->exclude_list = ep->next;
|
||||
|
||||
if (ep->next)
|
||||
ep->next->prev = ep->prev;
|
||||
|
||||
free_exclude (ep->excluded);
|
||||
free (ep);
|
||||
}
|
||||
ep = next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
info_free_exclist (struct tar_stat_info *dir)
|
||||
{
|
||||
@@ -172,7 +144,7 @@ info_free_exclist (struct tar_stat_info *dir)
|
||||
|
||||
dir->exclude_list = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Return nonzero if file NAME is excluded. */
|
||||
bool
|
||||
@@ -183,7 +155,7 @@ excluded_name (char const *name, struct tar_stat_info *st)
|
||||
char *bname = NULL;
|
||||
bool result;
|
||||
int nr = 0;
|
||||
|
||||
|
||||
name += FILE_SYSTEM_PREFIX_LEN (name);
|
||||
|
||||
/* Try global exclusion list first */
|
||||
@@ -192,7 +164,7 @@ excluded_name (char const *name, struct tar_stat_info *st)
|
||||
|
||||
if (!st)
|
||||
return false;
|
||||
|
||||
|
||||
for (result = false; st && !result; st = st->parent, nr = EXCL_NON_RECURSIVE)
|
||||
{
|
||||
for (ep = st->exclude_list; ep; ep = ep->next)
|
||||
@@ -201,7 +173,7 @@ excluded_name (char const *name, struct tar_stat_info *st)
|
||||
continue;
|
||||
if ((result = excluded_file_name (ep->excluded, name)))
|
||||
break;
|
||||
|
||||
|
||||
if (!rname)
|
||||
{
|
||||
rname = name;
|
||||
@@ -229,8 +201,8 @@ cvs_addfn (struct exclude *ex, char const *pattern, int options, void *data)
|
||||
{
|
||||
struct wordsplit ws;
|
||||
size_t i;
|
||||
|
||||
if (wordsplit (pattern, &ws,
|
||||
|
||||
if (wordsplit (pattern, &ws,
|
||||
WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_SQUEEZE_DELIMS))
|
||||
return;
|
||||
for (i = 0; i < ws.ws_wordc; i++)
|
||||
@@ -278,22 +250,18 @@ bzr_addfn (struct exclude *ex, char const *pattern, int options, void *data)
|
||||
static void *
|
||||
hg_initfn (void *data)
|
||||
{
|
||||
int *hgopt;
|
||||
static int hg_options;
|
||||
|
||||
if (!data)
|
||||
hgopt = &hg_options;
|
||||
|
||||
int *hgopt = data ? data : &hg_options;
|
||||
*hgopt = EXCLUDE_REGEX;
|
||||
return hgopt;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hg_addfn (struct exclude *ex, char const *pattern, int options, void *data)
|
||||
{
|
||||
int *hgopt = data;
|
||||
size_t len;
|
||||
|
||||
|
||||
while (isspace (*pattern))
|
||||
++pattern;
|
||||
if (*pattern == 0 || *pattern == '#')
|
||||
@@ -318,27 +286,27 @@ hg_addfn (struct exclude *ex, char const *pattern, int options, void *data)
|
||||
|
||||
--len;
|
||||
p = xmalloc (len+1);
|
||||
memcpy (p, pattern, len);
|
||||
memcpy (p, pattern, len);
|
||||
p[len] = 0;
|
||||
pattern = p;
|
||||
exclude_add_pattern_buffer (ex, p);
|
||||
options |= FNM_LEADING_DIR|EXCLUDE_ALLOC;
|
||||
}
|
||||
|
||||
|
||||
add_exclude (ex, pattern,
|
||||
((*hgopt == EXCLUDE_REGEX)
|
||||
? (options & ~EXCLUDE_WILDCARDS)
|
||||
: (options & ~EXCLUDE_REGEX)) | *hgopt);
|
||||
}
|
||||
|
||||
struct vcs_ignore_file vcs_ignore_files[] = {
|
||||
static struct vcs_ignore_file vcs_ignore_files[] = {
|
||||
{ ".cvsignore", EXCL_NON_RECURSIVE, cvs_addfn, NULL, NULL },
|
||||
{ ".gitignore", 0, git_addfn, NULL, NULL },
|
||||
{ ".bzrignore", 0, bzr_addfn, NULL, NULL },
|
||||
{ ".hgignore", 0, hg_addfn, hg_initfn , NULL },
|
||||
{ ".hgignore", 0, hg_addfn, hg_initfn, NULL },
|
||||
{ NULL, 0, git_addfn, NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
static struct vcs_ignore_file *
|
||||
get_vcs_ignore_file (const char *name)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Exit from GNU tar.
|
||||
|
||||
Copyright 2009, 2013-2014 Free Software Foundation, Inc.
|
||||
Copyright 2009, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Extract files from a tar archive.
|
||||
|
||||
Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2014 Free
|
||||
Software Foundation, Inc.
|
||||
Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2014,
|
||||
2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -109,7 +109,7 @@ struct delayed_set_stat
|
||||
struct xattr_array *xattr_map;
|
||||
/* Length and contents of name. */
|
||||
size_t file_name_len;
|
||||
char file_name[1];
|
||||
char *file_name;
|
||||
};
|
||||
|
||||
static struct delayed_set_stat *delayed_set_stat_head;
|
||||
@@ -441,9 +441,7 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st,
|
||||
mode_t mode, int atflag)
|
||||
{
|
||||
size_t file_name_len = strlen (file_name);
|
||||
struct delayed_set_stat *data =
|
||||
xmalloc (offsetof (struct delayed_set_stat, file_name)
|
||||
+ file_name_len + 1);
|
||||
struct delayed_set_stat *data = xmalloc (sizeof (*data));
|
||||
data->next = delayed_set_stat_head;
|
||||
data->mode = mode;
|
||||
if (st)
|
||||
@@ -456,6 +454,7 @@ delay_set_stat (char const *file_name, struct tar_stat_info const *st,
|
||||
data->mtime = st->mtime;
|
||||
}
|
||||
data->file_name_len = file_name_len;
|
||||
data->file_name = xstrdup (file_name);
|
||||
data->current_mode = current_mode;
|
||||
data->current_mode_mask = current_mode_mask;
|
||||
data->interdir = ! st;
|
||||
@@ -537,6 +536,56 @@ repair_delayed_set_stat (char const *dir,
|
||||
quotearg_colon (dir)));
|
||||
}
|
||||
|
||||
static void
|
||||
free_delayed_set_stat (struct delayed_set_stat *data)
|
||||
{
|
||||
free (data->file_name);
|
||||
xheader_xattr_free (data->xattr_map, data->xattr_map_size);
|
||||
free (data->cntx_name);
|
||||
free (data->acls_a_ptr);
|
||||
free (data->acls_d_ptr);
|
||||
free (data);
|
||||
}
|
||||
|
||||
void
|
||||
remove_delayed_set_stat (const char *fname)
|
||||
{
|
||||
struct delayed_set_stat *data, *next, *prev = NULL;
|
||||
for (data = delayed_set_stat_head; data; data = next)
|
||||
{
|
||||
next = data->next;
|
||||
if (chdir_current == data->change_dir
|
||||
&& strcmp (data->file_name, fname) == 0)
|
||||
{
|
||||
free_delayed_set_stat (data);
|
||||
if (prev)
|
||||
prev->next = next;
|
||||
else
|
||||
delayed_set_stat_head = next;
|
||||
return;
|
||||
}
|
||||
else
|
||||
prev = data;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fixup_delayed_set_stat (char const *src, char const *dst)
|
||||
{
|
||||
struct delayed_set_stat *data;
|
||||
for (data = delayed_set_stat_head; data; data = data->next)
|
||||
{
|
||||
if (chdir_current == data->change_dir
|
||||
&& strcmp (data->file_name, src) == 0)
|
||||
{
|
||||
free (data->file_name);
|
||||
data->file_name = xstrdup (dst);
|
||||
data->file_name_len = strlen (dst);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* After a file/link/directory creation has failed, see if
|
||||
it's because some required directory was not present, and if so,
|
||||
create all required directories. Return zero if all the required
|
||||
@@ -846,11 +895,7 @@ apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
|
||||
}
|
||||
|
||||
delayed_set_stat_head = data->next;
|
||||
xheader_xattr_free (data->xattr_map, data->xattr_map_size);
|
||||
free (data->cntx_name);
|
||||
free (data->acls_a_ptr);
|
||||
free (data->acls_d_ptr);
|
||||
free (data);
|
||||
free_delayed_set_stat (data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1741,7 +1786,9 @@ extract_finish (void)
|
||||
bool
|
||||
rename_directory (char *src, char *dst)
|
||||
{
|
||||
if (renameat (chdir_fd, src, chdir_fd, dst) != 0)
|
||||
if (renameat (chdir_fd, src, chdir_fd, dst) == 0)
|
||||
fixup_delayed_set_stat (src, dst);
|
||||
else
|
||||
{
|
||||
int e = errno;
|
||||
bool interdir_made;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* GNU dump extensions to tar.
|
||||
|
||||
Copyright 1988, 1992-1994, 1996-1997, 1999-2001, 2003-2009, 2013-2014
|
||||
Free Software Foundation, Inc.
|
||||
Copyright 1988, 1992-1994, 1996-1997, 1999-2001, 2003-2009,
|
||||
2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -735,7 +735,7 @@ scan_directory (struct tar_stat_info *st)
|
||||
savedir_error (dir);
|
||||
|
||||
info_attach_exclist (st);
|
||||
|
||||
|
||||
tmp = xstrdup (dir);
|
||||
zap_slashes (tmp);
|
||||
|
||||
@@ -1155,11 +1155,14 @@ read_num (FILE *fp, char const *fieldname,
|
||||
}
|
||||
|
||||
if (c)
|
||||
FATAL_ERROR ((0, 0,
|
||||
_("%s: byte %s: %s %s followed by invalid byte 0x%02x"),
|
||||
quotearg_colon (listed_incremental_option),
|
||||
offtostr (ftello (fp), offbuf),
|
||||
fieldname, buf, c));
|
||||
{
|
||||
unsigned uc = c;
|
||||
FATAL_ERROR ((0, 0,
|
||||
_("%s: byte %s: %s %s followed by invalid byte 0x%02x"),
|
||||
quotearg_colon (listed_incremental_option),
|
||||
offtostr (ftello (fp), offbuf),
|
||||
fieldname, buf, uc));
|
||||
}
|
||||
|
||||
*pval = strtosysint (buf, NULL, min_val, max_val);
|
||||
conversion_errno = errno;
|
||||
@@ -1541,9 +1544,10 @@ dumpdir_ok (char *dumpdir)
|
||||
{
|
||||
if (expect && *p != expect)
|
||||
{
|
||||
unsigned char uc = *p;
|
||||
ERROR ((0, 0,
|
||||
_("Malformed dumpdir: expected '%c' but found %#3o"),
|
||||
expect, *p));
|
||||
expect, uc));
|
||||
return false;
|
||||
}
|
||||
switch (*p)
|
||||
@@ -1578,7 +1582,7 @@ dumpdir_ok (char *dumpdir)
|
||||
if (expect != 'T')
|
||||
{
|
||||
ERROR ((0, 0,
|
||||
_("Malformed dumpdir: 'T' not preceeded by 'R'")));
|
||||
_("Malformed dumpdir: 'T' not preceded by 'R'")));
|
||||
return false;
|
||||
}
|
||||
if (p[1] == 0 && !has_tempdir)
|
||||
@@ -1708,7 +1712,7 @@ try_purge_directory (char const *directory_name)
|
||||
const char *entry;
|
||||
struct stat st;
|
||||
free (p);
|
||||
p = new_name (directory_name, cur);
|
||||
p = make_file_name (directory_name, cur);
|
||||
|
||||
if (deref_stat (p, &st) != 0)
|
||||
{
|
||||
|
||||
51
src/list.c
51
src/list.c
@@ -1,6 +1,6 @@
|
||||
/* List a tar archive, with support routines for reading a tar archive.
|
||||
|
||||
Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2014 Free
|
||||
Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2016 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
@@ -124,18 +124,20 @@ enforce_one_top_level (char **pfile_name)
|
||||
for (p = file_name; *p && (ISSLASH (*p) || *p == '.'); p++)
|
||||
;
|
||||
|
||||
if (!*p)
|
||||
return;
|
||||
|
||||
if (strncmp (p, one_top_level_dir, strlen (one_top_level_dir)) == 0)
|
||||
if (*p)
|
||||
{
|
||||
int pos = strlen (one_top_level_dir);
|
||||
if (ISSLASH (p[pos]) || p[pos] == 0)
|
||||
return;
|
||||
if (strncmp (p, one_top_level_dir, pos) == 0)
|
||||
{
|
||||
if (ISSLASH (p[pos]) || p[pos] == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
*pfile_name = make_file_name (one_top_level_dir, file_name);
|
||||
normalize_filename_x (*pfile_name);
|
||||
}
|
||||
|
||||
*pfile_name = new_name (one_top_level_dir, file_name);
|
||||
normalize_filename_x (*pfile_name);
|
||||
else
|
||||
*pfile_name = xstrdup (one_top_level_dir);
|
||||
free (file_name);
|
||||
}
|
||||
|
||||
@@ -193,7 +195,7 @@ read_and (void (*do_something) (void))
|
||||
decode_header (current_header, ¤t_stat_info,
|
||||
¤t_format, 1);
|
||||
if (! name_match (current_stat_info.file_name)
|
||||
|| (NEWER_OPTION_INITIALIZED (newer_mtime_option)
|
||||
|| (TIME_OPTION_INITIALIZED (newer_mtime_option)
|
||||
/* FIXME: We get mtime now, and again later; this causes
|
||||
duplicate diagnostics if header.mtime is bogus. */
|
||||
&& ((mtime.tv_sec
|
||||
@@ -689,7 +691,6 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
|
||||
}
|
||||
}
|
||||
|
||||
stat_info->archive_file_size = stat_info->stat.st_size;
|
||||
xheader_decode (stat_info);
|
||||
|
||||
if (sparse_member_p (stat_info))
|
||||
@@ -1218,18 +1219,7 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
|
||||
&& !numeric_owner_option)
|
||||
user = st->uname;
|
||||
else
|
||||
{
|
||||
/* Try parsing it as an unsigned integer first, and as a
|
||||
uid_t if that fails. This method can list positive user
|
||||
ids that are too large to fit in a uid_t. */
|
||||
uintmax_t u = from_header (blk->header.uid,
|
||||
sizeof blk->header.uid, 0,
|
||||
0, UINTMAX_MAX,
|
||||
false, false);
|
||||
user = (u != -1
|
||||
? STRINGIFY_BIGINT (u, uform)
|
||||
: imaxtostr (UID_FROM_HEADER (blk->header.uid), uform));
|
||||
}
|
||||
user = STRINGIFY_BIGINT (st->stat.st_uid, uform);
|
||||
|
||||
if (st->gname
|
||||
&& st->gname[0]
|
||||
@@ -1237,18 +1227,7 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
|
||||
&& !numeric_owner_option)
|
||||
group = st->gname;
|
||||
else
|
||||
{
|
||||
/* Try parsing it as an unsigned integer first, and as a
|
||||
gid_t if that fails. This method can list positive group
|
||||
ids that are too large to fit in a gid_t. */
|
||||
uintmax_t g = from_header (blk->header.gid,
|
||||
sizeof blk->header.gid, 0,
|
||||
0, UINTMAX_MAX,
|
||||
false, false);
|
||||
group = (g != -1
|
||||
? STRINGIFY_BIGINT (g, gform)
|
||||
: imaxtostr (GID_FROM_HEADER (blk->header.gid), gform));
|
||||
}
|
||||
group = STRINGIFY_BIGINT (st->stat.st_gid, gform);
|
||||
|
||||
/* Format the file size or major/minor device numbers. */
|
||||
|
||||
|
||||
283
src/map.c
Normal file
283
src/map.c
Normal file
@@ -0,0 +1,283 @@
|
||||
/* Owner/group mapping for tar
|
||||
|
||||
Copyright 2015-2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
GNU tar is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GNU tar 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, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <system.h>
|
||||
#include "common.h"
|
||||
#include "wordsplit.h"
|
||||
#include <hash.h>
|
||||
#include <pwd.h>
|
||||
|
||||
struct mapentry
|
||||
{
|
||||
uintmax_t orig_id;
|
||||
uintmax_t new_id;
|
||||
char *new_name;
|
||||
};
|
||||
|
||||
static size_t
|
||||
map_hash (void const *entry, size_t nbuckets)
|
||||
{
|
||||
struct mapentry const *map = entry;
|
||||
return map->orig_id % nbuckets;
|
||||
}
|
||||
|
||||
static bool
|
||||
map_compare (void const *entry1, void const *entry2)
|
||||
{
|
||||
struct mapentry const *map1 = entry1;
|
||||
struct mapentry const *map2 = entry2;
|
||||
return map1->orig_id == map2->orig_id;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_id (uintmax_t *retval,
|
||||
char const *arg, char const *what, uintmax_t maxval,
|
||||
char const *file, unsigned line)
|
||||
{
|
||||
uintmax_t v;
|
||||
char *p;
|
||||
|
||||
errno = 0;
|
||||
v = strtoumax (arg, &p, 10);
|
||||
if (*p || errno)
|
||||
{
|
||||
error (0, 0, _("%s:%u: invalid %s: %s"), file, line, what, arg);
|
||||
return -1;
|
||||
}
|
||||
if (v > maxval)
|
||||
{
|
||||
error (0, 0, _("%s:%u: %s out of range: %s"), file, line, what, arg);
|
||||
return -1;
|
||||
}
|
||||
*retval = v;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
map_read (Hash_table **ptab, char const *file,
|
||||
uintmax_t (*name_to_id) (char const *), char const *what,
|
||||
uintmax_t maxval)
|
||||
{
|
||||
FILE *fp;
|
||||
char *buf = NULL;
|
||||
size_t bufsize = 0;
|
||||
ssize_t n;
|
||||
struct wordsplit ws;
|
||||
int wsopt;
|
||||
unsigned line;
|
||||
int err = 0;
|
||||
|
||||
fp = fopen (file, "r");
|
||||
if (!fp)
|
||||
open_fatal (file);
|
||||
|
||||
ws.ws_comment = "#";
|
||||
wsopt = WRDSF_COMMENT | WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_SQUEEZE_DELIMS
|
||||
| WRDSF_QUOTE;
|
||||
line = 0;
|
||||
while ((n = getline (&buf, &bufsize, fp)) > 0)
|
||||
{
|
||||
struct mapentry *ent;
|
||||
uintmax_t orig_id, new_id;
|
||||
char *name = NULL;
|
||||
char *colon;
|
||||
|
||||
++line;
|
||||
if (wordsplit (buf, &ws, wsopt))
|
||||
FATAL_ERROR ((0, 0, _("%s:%u: cannot split line: %s"),
|
||||
file, line, wordsplit_strerror (&ws)));
|
||||
wsopt |= WRDSF_REUSE;
|
||||
if (ws.ws_wordc == 0)
|
||||
continue;
|
||||
if (ws.ws_wordc != 2)
|
||||
{
|
||||
error (0, 0, _("%s:%u: malformed line"), file, line);
|
||||
err = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ws.ws_wordv[0][0] == '+')
|
||||
{
|
||||
if (parse_id (&orig_id, ws.ws_wordv[0]+1, what, maxval, file, line))
|
||||
{
|
||||
err = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (name_to_id)
|
||||
{
|
||||
orig_id = name_to_id (ws.ws_wordv[0]);
|
||||
if (orig_id == UINTMAX_MAX)
|
||||
{
|
||||
error (0, 0, _("%s:%u: can't obtain %s of %s"),
|
||||
file, line, what, ws.ws_wordv[0]);
|
||||
err = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
colon = strchr (ws.ws_wordv[1], ':');
|
||||
if (colon)
|
||||
{
|
||||
if (colon > ws.ws_wordv[1])
|
||||
name = ws.ws_wordv[1];
|
||||
*colon++ = 0;
|
||||
if (parse_id (&new_id, colon, what, maxval, file, line))
|
||||
{
|
||||
err = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (ws.ws_wordv[1][0] == '+')
|
||||
{
|
||||
if (parse_id (&new_id, ws.ws_wordv[1], what, maxval, file, line))
|
||||
{
|
||||
err = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
name = ws.ws_wordv[1];
|
||||
new_id = name_to_id (ws.ws_wordv[1]);
|
||||
if (new_id == UINTMAX_MAX)
|
||||
{
|
||||
error (0, 0, _("%s:%u: can't obtain %s of %s"),
|
||||
file, line, what, ws.ws_wordv[1]);
|
||||
err = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ent = xmalloc (sizeof (*ent));
|
||||
ent->orig_id = orig_id;
|
||||
ent->new_id = new_id;
|
||||
ent->new_name = name ? xstrdup (name) : NULL;
|
||||
|
||||
if (!((*ptab
|
||||
|| (*ptab = hash_initialize (0, 0, map_hash, map_compare, 0)))
|
||||
&& hash_insert (*ptab, ent)))
|
||||
xalloc_die ();
|
||||
}
|
||||
if (wsopt & WRDSF_REUSE)
|
||||
wordsplit_free (&ws);
|
||||
fclose (fp);
|
||||
if (err)
|
||||
FATAL_ERROR ((0, 0, _("errors reading map file")));
|
||||
}
|
||||
|
||||
/* UID translation */
|
||||
|
||||
static Hash_table *owner_map;
|
||||
|
||||
static uintmax_t
|
||||
name_to_uid (char const *name)
|
||||
{
|
||||
struct passwd *pw = getpwnam (name);
|
||||
return pw ? pw->pw_uid : UINTMAX_MAX;
|
||||
}
|
||||
|
||||
void
|
||||
owner_map_read (char const *file)
|
||||
{
|
||||
map_read (&owner_map, file, name_to_uid, "UID", TYPE_MAXIMUM (uid_t));
|
||||
}
|
||||
|
||||
int
|
||||
owner_map_translate (uid_t uid, uid_t *new_uid, char const **new_name)
|
||||
{
|
||||
int rc = 1;
|
||||
|
||||
if (owner_map)
|
||||
{
|
||||
struct mapentry ent, *res;
|
||||
|
||||
ent.orig_id = uid;
|
||||
res = hash_lookup (owner_map, &ent);
|
||||
if (res)
|
||||
{
|
||||
*new_uid = res->new_id;
|
||||
*new_name = res->new_name;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (owner_option != (uid_t) -1)
|
||||
{
|
||||
*new_uid = owner_option;
|
||||
rc = 0;
|
||||
}
|
||||
if (owner_name_option)
|
||||
{
|
||||
*new_name = owner_name_option;
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* GID translation */
|
||||
|
||||
static Hash_table *group_map;
|
||||
|
||||
static uintmax_t
|
||||
name_to_gid (char const *name)
|
||||
{
|
||||
struct group *gr = getgrnam (name);
|
||||
return gr ? gr->gr_gid : UINTMAX_MAX;
|
||||
}
|
||||
|
||||
void
|
||||
group_map_read (char const *file)
|
||||
{
|
||||
map_read (&group_map, file, name_to_gid, "GID", TYPE_MAXIMUM (gid_t));
|
||||
}
|
||||
|
||||
int
|
||||
group_map_translate (gid_t gid, gid_t *new_gid, char const **new_name)
|
||||
{
|
||||
int rc = 1;
|
||||
|
||||
if (group_map)
|
||||
{
|
||||
struct mapentry ent, *res;
|
||||
|
||||
ent.orig_id = gid;
|
||||
res = hash_lookup (group_map, &ent);
|
||||
if (res)
|
||||
{
|
||||
*new_gid = res->new_id;
|
||||
*new_name = res->new_name;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (group_option != (uid_t) -1)
|
||||
{
|
||||
*new_gid = group_option;
|
||||
rc = 0;
|
||||
}
|
||||
if (group_name_option)
|
||||
{
|
||||
*new_name = group_name_option;
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
24
src/misc.c
24
src/misc.c
@@ -1,7 +1,7 @@
|
||||
/* Miscellaneous functions, not really specific to GNU tar.
|
||||
|
||||
Copyright 1988, 1992, 1994-1997, 1999-2001, 2003-2007, 2009-2010,
|
||||
2012-2014 Free Software Foundation, Inc.
|
||||
2012-2014, 2016 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
|
||||
@@ -29,6 +29,8 @@
|
||||
# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
|
||||
#endif
|
||||
|
||||
static void namebuf_add_dir (namebuf_t, char const *);
|
||||
static char *namebuf_finish (namebuf_t);
|
||||
static const char *tar_getcdpath (int);
|
||||
|
||||
|
||||
@@ -586,7 +588,12 @@ safer_rmdir (const char *file_name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return unlinkat (chdir_fd, file_name, AT_REMOVEDIR);
|
||||
if (unlinkat (chdir_fd, file_name, AT_REMOVEDIR) == 0)
|
||||
{
|
||||
remove_delayed_set_stat (file_name);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Remove FILE_NAME, returning 1 on success. If FILE_NAME is a directory,
|
||||
@@ -650,7 +657,7 @@ remove_any_file (const char *file_name, enum remove_option option)
|
||||
(entrylen = strlen (entry)) != 0;
|
||||
entry += entrylen + 1)
|
||||
{
|
||||
char *file_name_buffer = new_name (file_name, entry);
|
||||
char *file_name_buffer = make_file_name (file_name, entry);
|
||||
int r = remove_any_file (file_name_buffer,
|
||||
RECURSIVE_REMOVE_OPTION);
|
||||
int e = errno;
|
||||
@@ -1106,13 +1113,6 @@ file_removed_diag (const char *name, bool top_level,
|
||||
diagfn (name);
|
||||
}
|
||||
|
||||
void
|
||||
write_fatal_details (char const *name, ssize_t status, size_t size)
|
||||
{
|
||||
write_error_details (name, status, size);
|
||||
fatal_exit ();
|
||||
}
|
||||
|
||||
/* Fork, aborting if unsuccessful. */
|
||||
pid_t
|
||||
xfork (void)
|
||||
@@ -1197,7 +1197,7 @@ namebuf_name (namebuf_t buf, const char *name)
|
||||
return buf->buffer;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
namebuf_add_dir (namebuf_t buf, const char *name)
|
||||
{
|
||||
static char dirsep[] = { DIRECTORY_SEPARATOR, 0 };
|
||||
@@ -1210,7 +1210,7 @@ namebuf_add_dir (namebuf_t buf, const char *name)
|
||||
buf->dir_length += strlen (name);
|
||||
}
|
||||
|
||||
char *
|
||||
static char *
|
||||
namebuf_finish (namebuf_t buf)
|
||||
{
|
||||
char *res = buf->buffer;
|
||||
|
||||
532
src/names.c
532
src/names.c
@@ -1,6 +1,6 @@
|
||||
/* Various processing of names.
|
||||
|
||||
Copyright 1988, 1992, 1994, 1996-2001, 2003-2007, 2009, 2013-2014
|
||||
Copyright 1988, 1992, 1994, 1996-2001, 2003-2007, 2009, 2013-2016
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
@@ -26,6 +26,401 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
static void name_add_option (int option, const char *arg);
|
||||
static void name_add_dir (const char *name);
|
||||
static void name_add_file (const char *name);
|
||||
|
||||
enum
|
||||
{
|
||||
EXCLUDE_BACKUPS_OPTION = 256,
|
||||
EXCLUDE_CACHES_OPTION,
|
||||
EXCLUDE_CACHES_UNDER_OPTION,
|
||||
EXCLUDE_CACHES_ALL_OPTION,
|
||||
EXCLUDE_OPTION,
|
||||
EXCLUDE_IGNORE_OPTION,
|
||||
EXCLUDE_IGNORE_RECURSIVE_OPTION,
|
||||
EXCLUDE_TAG_OPTION,
|
||||
EXCLUDE_TAG_UNDER_OPTION,
|
||||
EXCLUDE_TAG_ALL_OPTION,
|
||||
EXCLUDE_VCS_OPTION,
|
||||
EXCLUDE_VCS_IGNORES_OPTION,
|
||||
IGNORE_CASE_OPTION,
|
||||
NO_IGNORE_CASE_OPTION,
|
||||
ANCHORED_OPTION,
|
||||
NO_ANCHORED_OPTION,
|
||||
RECURSION_OPTION,
|
||||
NO_RECURSION_OPTION,
|
||||
UNQUOTE_OPTION,
|
||||
NO_UNQUOTE_OPTION,
|
||||
NO_VERBATIM_FILES_FROM_OPTION,
|
||||
NO_WILDCARDS_MATCH_SLASH_OPTION,
|
||||
NO_WILDCARDS_OPTION,
|
||||
NULL_OPTION,
|
||||
NO_NULL_OPTION,
|
||||
VERBATIM_FILES_FROM_OPTION,
|
||||
WILDCARDS_MATCH_SLASH_OPTION,
|
||||
WILDCARDS_OPTION
|
||||
};
|
||||
|
||||
static struct argp_option names_options[] = {
|
||||
#define GRID 100
|
||||
{NULL, 0, NULL, 0,
|
||||
N_("Local file name selection:"), GRID },
|
||||
|
||||
{"add-file", ARGP_KEY_ARG, N_("FILE"), 0,
|
||||
N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID+1 },
|
||||
{"directory", 'C', N_("DIR"), 0,
|
||||
N_("change to directory DIR"), GRID+1 },
|
||||
{"files-from", 'T', N_("FILE"), 0,
|
||||
N_("get names to extract or create from FILE"), GRID+1 },
|
||||
{"null", NULL_OPTION, 0, 0,
|
||||
N_("-T reads null-terminated names; implies --verbatim-files-from"),
|
||||
GRID+1 },
|
||||
{"no-null", NO_NULL_OPTION, 0, 0,
|
||||
N_("disable the effect of the previous --null option"), GRID+1 },
|
||||
{"unquote", UNQUOTE_OPTION, 0, 0,
|
||||
N_("unquote input file or member names (default)"), GRID+1 },
|
||||
{"no-unquote", NO_UNQUOTE_OPTION, 0, 0,
|
||||
N_("do not unquote input file or member names"), GRID+1 },
|
||||
{"verbatim-files-from", VERBATIM_FILES_FROM_OPTION, 0, 0,
|
||||
N_("-T reads file names verbatim (no option handling)"), GRID+1 },
|
||||
{"no-verbatim-files-from", NO_VERBATIM_FILES_FROM_OPTION, 0, 0,
|
||||
N_("-T treats file names starting with dash as options (default)"),
|
||||
GRID+1 },
|
||||
{"exclude", EXCLUDE_OPTION, N_("PATTERN"), 0,
|
||||
N_("exclude files, given as a PATTERN"), GRID+1 },
|
||||
{"exclude-from", 'X', N_("FILE"), 0,
|
||||
N_("exclude patterns listed in FILE"), GRID+1 },
|
||||
{"exclude-caches", EXCLUDE_CACHES_OPTION, 0, 0,
|
||||
N_("exclude contents of directories containing CACHEDIR.TAG, "
|
||||
"except for the tag file itself"), GRID+1 },
|
||||
{"exclude-caches-under", EXCLUDE_CACHES_UNDER_OPTION, 0, 0,
|
||||
N_("exclude everything under directories containing CACHEDIR.TAG"),
|
||||
GRID+1 },
|
||||
{"exclude-caches-all", EXCLUDE_CACHES_ALL_OPTION, 0, 0,
|
||||
N_("exclude directories containing CACHEDIR.TAG"), GRID+1 },
|
||||
{"exclude-tag", EXCLUDE_TAG_OPTION, N_("FILE"), 0,
|
||||
N_("exclude contents of directories containing FILE, except"
|
||||
" for FILE itself"), GRID+1 },
|
||||
{"exclude-ignore", EXCLUDE_IGNORE_OPTION, N_("FILE"), 0,
|
||||
N_("read exclude patterns for each directory from FILE, if it exists"),
|
||||
GRID+1 },
|
||||
{"exclude-ignore-recursive", EXCLUDE_IGNORE_RECURSIVE_OPTION, N_("FILE"), 0,
|
||||
N_("read exclude patterns for each directory and its subdirectories "
|
||||
"from FILE, if it exists"), GRID+1 },
|
||||
{"exclude-tag-under", EXCLUDE_TAG_UNDER_OPTION, N_("FILE"), 0,
|
||||
N_("exclude everything under directories containing FILE"), GRID+1 },
|
||||
{"exclude-tag-all", EXCLUDE_TAG_ALL_OPTION, N_("FILE"), 0,
|
||||
N_("exclude directories containing FILE"), GRID+1 },
|
||||
{"exclude-vcs", EXCLUDE_VCS_OPTION, NULL, 0,
|
||||
N_("exclude version control system directories"), GRID+1 },
|
||||
{"exclude-vcs-ignores", EXCLUDE_VCS_IGNORES_OPTION, NULL, 0,
|
||||
N_("read exclude patterns from the VCS ignore files"), GRID+1 },
|
||||
{"exclude-backups", EXCLUDE_BACKUPS_OPTION, NULL, 0,
|
||||
N_("exclude backup and lock files"), GRID+1 },
|
||||
{"recursion", RECURSION_OPTION, 0, 0,
|
||||
N_("recurse into directories (default)"), GRID+1 },
|
||||
{"no-recursion", NO_RECURSION_OPTION, 0, 0,
|
||||
N_("avoid descending automatically in directories"), GRID+1 },
|
||||
#undef GRID
|
||||
|
||||
#define GRID 120
|
||||
{NULL, 0, NULL, 0,
|
||||
N_("File name matching options (affect both exclude and include patterns):"),
|
||||
GRID },
|
||||
{"anchored", ANCHORED_OPTION, 0, 0,
|
||||
N_("patterns match file name start"), GRID+1 },
|
||||
{"no-anchored", NO_ANCHORED_OPTION, 0, 0,
|
||||
N_("patterns match after any '/' (default for exclusion)"), GRID+1 },
|
||||
{"ignore-case", IGNORE_CASE_OPTION, 0, 0,
|
||||
N_("ignore case"), GRID+1 },
|
||||
{"no-ignore-case", NO_IGNORE_CASE_OPTION, 0, 0,
|
||||
N_("case sensitive matching (default)"), GRID+1 },
|
||||
{"wildcards", WILDCARDS_OPTION, 0, 0,
|
||||
N_("use wildcards (default for exclusion)"), GRID+1 },
|
||||
{"no-wildcards", NO_WILDCARDS_OPTION, 0, 0,
|
||||
N_("verbatim string matching"), GRID+1 },
|
||||
{"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
|
||||
N_("wildcards match '/' (default for exclusion)"), GRID+1 },
|
||||
{"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
|
||||
N_("wildcards do not match '/'"), GRID+1 },
|
||||
#undef GRID
|
||||
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static bool
|
||||
is_file_selection_option (int key)
|
||||
{
|
||||
struct argp_option *p;
|
||||
|
||||
for (p = names_options;
|
||||
!(p->name == NULL && p->key == 0 && p->doc == NULL); p++)
|
||||
if (p->key == key)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Either NL or NUL, as decided by the --null option. */
|
||||
static char filename_terminator = '\n';
|
||||
/* Treat file names read from -T input verbatim */
|
||||
static bool verbatim_files_from_option;
|
||||
|
||||
static error_t
|
||||
names_parse_opt (int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 'C':
|
||||
name_add_dir (arg);
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
name_add_file (arg);
|
||||
/* Indicate we've been given -T option. This is for backward
|
||||
compatibility only, so that `tar cfT archive /dev/null will
|
||||
succeed */
|
||||
files_from_option = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (is_file_selection_option (key))
|
||||
name_add_option (key, arg);
|
||||
else
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wildcard matching settings */
|
||||
enum wildcards
|
||||
{
|
||||
default_wildcards, /* For exclusion == enable_wildcards,
|
||||
for inclusion == disable_wildcards */
|
||||
disable_wildcards,
|
||||
enable_wildcards
|
||||
};
|
||||
|
||||
static enum wildcards wildcards = default_wildcards;
|
||||
/* Wildcard settings (--wildcards/--no-wildcards) */
|
||||
static int matching_flags = 0;
|
||||
/* exclude_fnmatch options */
|
||||
static int include_anchored = EXCLUDE_ANCHORED;
|
||||
/* Pattern anchoring options used for file inclusion */
|
||||
|
||||
#define EXCLUDE_OPTIONS \
|
||||
(((wildcards != disable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
|
||||
| matching_flags \
|
||||
| recursion_option)
|
||||
|
||||
#define INCLUDE_OPTIONS \
|
||||
(((wildcards == enable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
|
||||
| include_anchored \
|
||||
| matching_flags \
|
||||
| recursion_option)
|
||||
|
||||
static char const * const vcs_file_table[] = {
|
||||
/* CVS: */
|
||||
"CVS",
|
||||
".cvsignore",
|
||||
/* RCS: */
|
||||
"RCS",
|
||||
/* SCCS: */
|
||||
"SCCS",
|
||||
/* SVN: */
|
||||
".svn",
|
||||
/* git: */
|
||||
".git",
|
||||
".gitignore",
|
||||
".gitattributes",
|
||||
".gitmodules",
|
||||
/* Arch: */
|
||||
".arch-ids",
|
||||
"{arch}",
|
||||
"=RELEASE-ID",
|
||||
"=meta-update",
|
||||
"=update",
|
||||
/* Bazaar */
|
||||
".bzr",
|
||||
".bzrignore",
|
||||
".bzrtags",
|
||||
/* Mercurial */
|
||||
".hg",
|
||||
".hgignore",
|
||||
".hgtags",
|
||||
/* darcs */
|
||||
"_darcs",
|
||||
NULL
|
||||
};
|
||||
|
||||
static char const * const backup_file_table[] = {
|
||||
".#*",
|
||||
"*~",
|
||||
"#*#",
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
add_exclude_array (char const * const * fv, int opts)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; fv[i]; i++)
|
||||
add_exclude (excluded, fv[i], opts);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_file_selection_option (int key, const char *arg)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case EXCLUDE_BACKUPS_OPTION:
|
||||
add_exclude_array (backup_file_table, EXCLUDE_WILDCARDS);
|
||||
break;
|
||||
|
||||
case EXCLUDE_OPTION:
|
||||
add_exclude (excluded, arg, EXCLUDE_OPTIONS);
|
||||
break;
|
||||
|
||||
case EXCLUDE_CACHES_OPTION:
|
||||
add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_contents,
|
||||
cachedir_file_p);
|
||||
break;
|
||||
|
||||
case EXCLUDE_CACHES_UNDER_OPTION:
|
||||
add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_under,
|
||||
cachedir_file_p);
|
||||
break;
|
||||
|
||||
case EXCLUDE_CACHES_ALL_OPTION:
|
||||
add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_all,
|
||||
cachedir_file_p);
|
||||
break;
|
||||
|
||||
case EXCLUDE_IGNORE_OPTION:
|
||||
excfile_add (arg, EXCL_NON_RECURSIVE);
|
||||
break;
|
||||
|
||||
case EXCLUDE_IGNORE_RECURSIVE_OPTION:
|
||||
excfile_add (arg, EXCL_RECURSIVE);
|
||||
break;
|
||||
|
||||
case EXCLUDE_TAG_OPTION:
|
||||
add_exclusion_tag (arg, exclusion_tag_contents, NULL);
|
||||
break;
|
||||
|
||||
case EXCLUDE_TAG_UNDER_OPTION:
|
||||
add_exclusion_tag (arg, exclusion_tag_under, NULL);
|
||||
break;
|
||||
|
||||
case EXCLUDE_TAG_ALL_OPTION:
|
||||
add_exclusion_tag (arg, exclusion_tag_all, NULL);
|
||||
break;
|
||||
|
||||
case EXCLUDE_VCS_OPTION:
|
||||
add_exclude_array (vcs_file_table, 0);
|
||||
break;
|
||||
|
||||
case EXCLUDE_VCS_IGNORES_OPTION:
|
||||
exclude_vcs_ignores ();
|
||||
break;
|
||||
|
||||
case RECURSION_OPTION:
|
||||
recursion_option = FNM_LEADING_DIR;
|
||||
break;
|
||||
|
||||
case NO_RECURSION_OPTION:
|
||||
recursion_option = 0;
|
||||
break;
|
||||
|
||||
case UNQUOTE_OPTION:
|
||||
unquote_option = true;
|
||||
break;
|
||||
|
||||
case NO_UNQUOTE_OPTION:
|
||||
unquote_option = false;
|
||||
break;
|
||||
|
||||
case NULL_OPTION:
|
||||
filename_terminator = '\0';
|
||||
verbatim_files_from_option = true;
|
||||
break;
|
||||
|
||||
case NO_NULL_OPTION:
|
||||
filename_terminator = '\n';
|
||||
verbatim_files_from_option = false;
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
if (add_exclude_file (add_exclude, excluded, arg, EXCLUDE_OPTIONS, '\n')
|
||||
!= 0)
|
||||
{
|
||||
int e = errno;
|
||||
FATAL_ERROR ((0, e, "%s", quotearg_colon (arg)));
|
||||
}
|
||||
break;
|
||||
|
||||
case ANCHORED_OPTION:
|
||||
matching_flags |= EXCLUDE_ANCHORED;
|
||||
break;
|
||||
|
||||
case NO_ANCHORED_OPTION:
|
||||
include_anchored = 0; /* Clear the default for comman line args */
|
||||
matching_flags &= ~ EXCLUDE_ANCHORED;
|
||||
break;
|
||||
|
||||
case IGNORE_CASE_OPTION:
|
||||
matching_flags |= FNM_CASEFOLD;
|
||||
break;
|
||||
|
||||
case NO_IGNORE_CASE_OPTION:
|
||||
matching_flags &= ~ FNM_CASEFOLD;
|
||||
break;
|
||||
|
||||
case WILDCARDS_OPTION:
|
||||
wildcards = enable_wildcards;
|
||||
break;
|
||||
|
||||
case NO_WILDCARDS_OPTION:
|
||||
wildcards = disable_wildcards;
|
||||
break;
|
||||
|
||||
case WILDCARDS_MATCH_SLASH_OPTION:
|
||||
matching_flags &= ~ FNM_FILE_NAME;
|
||||
break;
|
||||
|
||||
case NO_WILDCARDS_MATCH_SLASH_OPTION:
|
||||
matching_flags |= FNM_FILE_NAME;
|
||||
break;
|
||||
|
||||
case VERBATIM_FILES_FROM_OPTION:
|
||||
verbatim_files_from_option = true;
|
||||
break;
|
||||
|
||||
case NO_VERBATIM_FILES_FROM_OPTION:
|
||||
verbatim_files_from_option = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
FATAL_ERROR ((0, 0, "unhandled positional option %d", key));
|
||||
}
|
||||
}
|
||||
|
||||
static struct argp names_argp = {
|
||||
names_options,
|
||||
names_parse_opt,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
struct argp_child names_argp_children[] = {
|
||||
{ &names_argp, 0, "", 0 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/* User and group names. */
|
||||
|
||||
/* Make sure you link with the proper libraries if you are running the
|
||||
@@ -210,26 +605,36 @@ static struct name *nametail; /* end of name list */
|
||||
|
||||
/* A name_list element contains entries of three types: */
|
||||
|
||||
#define NELT_NAME 0 /* File name */
|
||||
#define NELT_CHDIR 1 /* Change directory request */
|
||||
#define NELT_FMASK 2 /* Change fnmatch options request */
|
||||
#define NELT_FILE 3 /* Read file names from that file */
|
||||
#define NELT_NOOP 4 /* No operation */
|
||||
enum nelt_type
|
||||
{
|
||||
NELT_NAME, /* File name */
|
||||
NELT_CHDIR, /* Change directory request */
|
||||
NELT_FILE, /* Read file names from that file */
|
||||
NELT_NOOP, /* No operation */
|
||||
NELT_OPTION /* Filename-selection option */
|
||||
};
|
||||
|
||||
struct name_elt /* A name_array element. */
|
||||
{
|
||||
struct name_elt *next, *prev;
|
||||
char type; /* Element type, see NELT_* constants above */
|
||||
enum nelt_type type; /* Element type, see NELT_* constants above */
|
||||
union
|
||||
{
|
||||
const char *name; /* File or directory name */
|
||||
int matching_flags;/* fnmatch options if type == NELT_FMASK */
|
||||
struct /* File, if type == NELT_FILE */
|
||||
{
|
||||
const char *name;/* File name */
|
||||
size_t line; /* Input line number */
|
||||
int term; /* File name terminator in the list */
|
||||
bool verbatim; /* Verbatim handling of file names: no white-space
|
||||
trimming, no option processing */
|
||||
FILE *fp;
|
||||
} file;
|
||||
struct
|
||||
{
|
||||
int option;
|
||||
char const *arg;
|
||||
} opt; /* NELT_OPTION */
|
||||
} v;
|
||||
};
|
||||
|
||||
@@ -276,27 +681,29 @@ name_list_advance (void)
|
||||
free (elt);
|
||||
}
|
||||
|
||||
/* Add to name_array the file NAME with fnmatch options MATCHING_FLAGS */
|
||||
|
||||
/* Add to name_array the file NAME with fnmatch options MATFLAGS */
|
||||
void
|
||||
name_add_name (const char *name, int matching_flags)
|
||||
name_add_name (const char *name)
|
||||
{
|
||||
static int prev_flags = 0; /* FIXME: Or EXCLUDE_ANCHORED? */
|
||||
struct name_elt *ep = name_elt_alloc ();
|
||||
|
||||
if (prev_flags != matching_flags)
|
||||
{
|
||||
ep->type = NELT_FMASK;
|
||||
ep->v.matching_flags = matching_flags;
|
||||
prev_flags = matching_flags;
|
||||
ep = name_elt_alloc ();
|
||||
}
|
||||
ep->type = NELT_NAME;
|
||||
ep->v.name = name;
|
||||
name_count++;
|
||||
}
|
||||
|
||||
static void
|
||||
name_add_option (int option, const char *arg)
|
||||
{
|
||||
struct name_elt *elt = name_elt_alloc ();
|
||||
elt->type = NELT_OPTION;
|
||||
elt->v.opt.option = option;
|
||||
elt->v.opt.arg = arg;
|
||||
}
|
||||
|
||||
/* Add to name_array a chdir request for the directory NAME */
|
||||
void
|
||||
static void
|
||||
name_add_dir (const char *name)
|
||||
{
|
||||
struct name_elt *ep = name_elt_alloc ();
|
||||
@@ -304,13 +711,14 @@ name_add_dir (const char *name)
|
||||
ep->v.name = name;
|
||||
}
|
||||
|
||||
void
|
||||
name_add_file (const char *name, int term)
|
||||
static void
|
||||
name_add_file (const char *name)
|
||||
{
|
||||
struct name_elt *ep = name_elt_alloc ();
|
||||
|
||||
ep->type = NELT_FILE;
|
||||
ep->v.file.name = name;
|
||||
ep->v.file.term = term;
|
||||
ep->v.file.line = 0;
|
||||
ep->v.file.fp = NULL;
|
||||
}
|
||||
|
||||
@@ -389,6 +797,15 @@ add_file_id (const char *filename)
|
||||
file_id_list = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Chop trailing slashes. */
|
||||
static void
|
||||
chopslash (char *str)
|
||||
{
|
||||
char *p = str + strlen (str) - 1;
|
||||
while (p > str && ISSLASH (*p))
|
||||
*p-- = '\0';
|
||||
}
|
||||
|
||||
enum read_file_list_state /* Result of reading file name from the list file */
|
||||
{
|
||||
@@ -409,6 +826,7 @@ read_name_from_file (struct name_elt *ent)
|
||||
FILE *fp = ent->v.file.fp;
|
||||
int term = ent->v.file.term;
|
||||
|
||||
++ent->v.file.line;
|
||||
for (c = getc (fp); c != EOF && c != term; c = getc (fp))
|
||||
{
|
||||
if (counter == name_buffer_length)
|
||||
@@ -428,16 +846,17 @@ read_name_from_file (struct name_elt *ent)
|
||||
if (counter == name_buffer_length)
|
||||
name_buffer = x2realloc (name_buffer, &name_buffer_length);
|
||||
name_buffer[counter] = 0;
|
||||
|
||||
chopslash (name_buffer);
|
||||
return (counter == 0 && c == EOF) ? file_list_end : file_list_success;
|
||||
}
|
||||
|
||||
static int
|
||||
handle_option (const char *str)
|
||||
handle_option (const char *str, struct name_elt const *ent)
|
||||
{
|
||||
struct wordsplit ws;
|
||||
int i;
|
||||
|
||||
struct option_locus loc;
|
||||
|
||||
while (*str && isspace (*str))
|
||||
++str;
|
||||
if (*str != '-')
|
||||
@@ -447,8 +866,11 @@ handle_option (const char *str)
|
||||
if (wordsplit (str, &ws, WRDSF_DEFFLAGS|WRDSF_DOOFFS))
|
||||
FATAL_ERROR ((0, 0, _("cannot split string '%s': %s"),
|
||||
str, wordsplit_strerror (&ws)));
|
||||
ws.ws_wordv[0] = program_invocation_short_name;
|
||||
more_options (ws.ws_wordc+ws.ws_offs, ws.ws_wordv);
|
||||
ws.ws_wordv[0] = (char *) program_name;
|
||||
loc.source = OPTS_FILE;
|
||||
loc.name = ent->v.file.name;
|
||||
loc.line = ent->v.file.line;
|
||||
more_options (ws.ws_wordc+ws.ws_offs, ws.ws_wordv, &loc);
|
||||
for (i = 0; i < ws.ws_wordc+ws.ws_offs; i++)
|
||||
ws.ws_wordv[i] = NULL;
|
||||
|
||||
@@ -476,6 +898,8 @@ read_next_name (struct name_elt *ent, struct name_elt *ret)
|
||||
if ((ent->v.file.fp = fopen (ent->v.file.name, "r")) == NULL)
|
||||
open_fatal (ent->v.file.name);
|
||||
}
|
||||
ent->v.file.term = filename_terminator;
|
||||
ent->v.file.verbatim = verbatim_files_from_option;
|
||||
}
|
||||
|
||||
while (1)
|
||||
@@ -494,7 +918,7 @@ read_next_name (struct name_elt *ent, struct name_elt *ret)
|
||||
case file_list_success:
|
||||
if (unquote_option)
|
||||
unquote_string (name_buffer);
|
||||
if (handle_option (name_buffer) == 0)
|
||||
if (!ent->v.file.verbatim && handle_option (name_buffer, ent) == 0)
|
||||
{
|
||||
name_list_adjust ();
|
||||
return 1;
|
||||
@@ -518,7 +942,6 @@ copy_name (struct name_elt *ep)
|
||||
{
|
||||
const char *source;
|
||||
size_t source_len;
|
||||
char *cursor;
|
||||
|
||||
source = ep->v.name;
|
||||
source_len = strlen (source);
|
||||
@@ -536,24 +959,17 @@ copy_name (struct name_elt *ep)
|
||||
name_buffer = xmalloc(name_buffer_length + 2);
|
||||
}
|
||||
strcpy (name_buffer, source);
|
||||
|
||||
/* Zap trailing slashes. */
|
||||
cursor = name_buffer + strlen (name_buffer) - 1;
|
||||
while (cursor > name_buffer && ISSLASH (*cursor))
|
||||
*cursor-- = '\0';
|
||||
chopslash (name_buffer);
|
||||
}
|
||||
|
||||
|
||||
static int matching_flags; /* exclude_fnmatch options */
|
||||
|
||||
/* Get the next NELT_NAME element from name_array. Result is in
|
||||
static storage and can't be relied upon across two calls.
|
||||
|
||||
If CHANGE_DIRS is true, treat any entries of type NELT_CHDIR as
|
||||
the request to change to the given directory.
|
||||
|
||||
Entries of type NELT_FMASK cause updates of the matching_flags
|
||||
value. */
|
||||
*/
|
||||
static struct name_elt *
|
||||
name_next_elt (int change_dirs)
|
||||
{
|
||||
@@ -568,12 +984,6 @@ name_next_elt (int change_dirs)
|
||||
name_list_advance ();
|
||||
break;
|
||||
|
||||
case NELT_FMASK:
|
||||
matching_flags = ep->v.matching_flags;
|
||||
recursion_option = matching_flags & FNM_LEADING_DIR;
|
||||
name_list_advance ();
|
||||
continue;
|
||||
|
||||
case NELT_FILE:
|
||||
if (read_next_name (ep, &entry) == 0)
|
||||
return &entry;
|
||||
@@ -595,6 +1005,11 @@ name_next_elt (int change_dirs)
|
||||
entry.v.name = name_buffer;
|
||||
name_list_advance ();
|
||||
return &entry;
|
||||
|
||||
case NELT_OPTION:
|
||||
handle_file_selection_option (ep->v.opt.option, ep->v.opt.arg);
|
||||
name_list_advance ();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -640,7 +1055,7 @@ name_gather (void)
|
||||
buffer->change_dir = change_dir;
|
||||
buffer->next = 0;
|
||||
buffer->found_count = 0;
|
||||
buffer->matching_flags = matching_flags;
|
||||
buffer->matching_flags = INCLUDE_OPTIONS;
|
||||
buffer->directory = NULL;
|
||||
buffer->parent = NULL;
|
||||
buffer->cmdline = true;
|
||||
@@ -682,7 +1097,7 @@ addname (char const *string, int change_dir, bool cmdline, struct name *parent)
|
||||
name->prev = nametail;
|
||||
name->next = NULL;
|
||||
name->found_count = 0;
|
||||
name->matching_flags = matching_flags;
|
||||
name->matching_flags = INCLUDE_OPTIONS;
|
||||
name->change_dir = change_dir;
|
||||
name->directory = NULL;
|
||||
name->parent = parent;
|
||||
@@ -817,7 +1232,10 @@ regex_usage_warning (const char *name)
|
||||
{
|
||||
static int warned_once = 0;
|
||||
|
||||
if (warn_regex_usage && fnmatch_pattern_has_wildcards (name, 0))
|
||||
/* Warn about implicit use of the wildcards in command line arguments.
|
||||
(Default for tar prior to 1.15.91, but changed afterwards) */
|
||||
if (wildcards == default_wildcards
|
||||
&& fnmatch_pattern_has_wildcards (name, 0))
|
||||
{
|
||||
warned_once = 1;
|
||||
WARN ((0, 0,
|
||||
@@ -1358,18 +1776,18 @@ blank_name_list (void)
|
||||
name->found_count = 0;
|
||||
}
|
||||
|
||||
/* Yield a newly allocated file name consisting of FILE_NAME concatenated to
|
||||
NAME, with an intervening slash if FILE_NAME does not already end in one. */
|
||||
/* Yield a newly allocated file name consisting of DIR_NAME concatenated to
|
||||
NAME, with an intervening slash if DIR_NAME does not already end in one. */
|
||||
char *
|
||||
new_name (const char *file_name, const char *name)
|
||||
make_file_name (const char *directory_name, const char *name)
|
||||
{
|
||||
size_t file_name_len = strlen (file_name);
|
||||
size_t namesize = strlen (name) + 1;
|
||||
int slash = file_name_len && ! ISSLASH (file_name[file_name_len - 1]);
|
||||
char *buffer = xmalloc (file_name_len + slash + namesize);
|
||||
memcpy (buffer, file_name, file_name_len);
|
||||
buffer[file_name_len] = '/';
|
||||
memcpy (buffer + file_name_len + slash, name, namesize);
|
||||
size_t dirlen = strlen (directory_name);
|
||||
size_t namelen = strlen (name) + 1;
|
||||
int slash = dirlen && ! ISSLASH (directory_name[dirlen - 1]);
|
||||
char *buffer = xmalloc (dirlen + slash + namelen);
|
||||
memcpy (buffer, directory_name, dirlen);
|
||||
buffer[dirlen] = '/';
|
||||
memcpy (buffer + dirlen + slash, name, namelen);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
173
src/sparse.c
173
src/sparse.c
@@ -1,6 +1,6 @@
|
||||
/* Functions for dealing with sparse files
|
||||
|
||||
Copyright 2003-2007, 2010, 2013-2014 Free Software Foundation, Inc.
|
||||
Copyright 2003-2007, 2010, 2013-2016 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
|
||||
@@ -208,9 +208,9 @@ sparse_add_map (struct tar_stat_info *st, struct sp_array const *sp)
|
||||
st->sparse_map_avail = avail + 1;
|
||||
}
|
||||
|
||||
/* Scan the sparse file and create its map */
|
||||
/* Scan the sparse file byte-by-byte and create its map. */
|
||||
static bool
|
||||
sparse_scan_file (struct tar_sparse_file *file)
|
||||
sparse_scan_file_raw (struct tar_sparse_file *file)
|
||||
{
|
||||
struct tar_stat_info *st = file->stat_info;
|
||||
int fd = file->fd;
|
||||
@@ -221,41 +221,38 @@ sparse_scan_file (struct tar_sparse_file *file)
|
||||
|
||||
st->archive_file_size = 0;
|
||||
|
||||
if (ST_NBLOCKS (st->stat) == 0)
|
||||
offset = st->stat.st_size;
|
||||
else
|
||||
if (!tar_sparse_scan (file, scan_begin, NULL))
|
||||
return false;
|
||||
|
||||
while ((count = blocking_read (fd, buffer, sizeof buffer)) != 0
|
||||
&& count != SAFE_READ_ERROR)
|
||||
{
|
||||
if (!tar_sparse_scan (file, scan_begin, NULL))
|
||||
return false;
|
||||
/* Analyze the block. */
|
||||
if (zero_block_p (buffer, count))
|
||||
{
|
||||
if (sp.numbytes)
|
||||
{
|
||||
sparse_add_map (st, &sp);
|
||||
sp.numbytes = 0;
|
||||
if (!tar_sparse_scan (file, scan_block, NULL))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sp.numbytes == 0)
|
||||
sp.offset = offset;
|
||||
sp.numbytes += count;
|
||||
st->archive_file_size += count;
|
||||
if (!tar_sparse_scan (file, scan_block, buffer))
|
||||
return false;
|
||||
}
|
||||
|
||||
while ((count = blocking_read (fd, buffer, sizeof buffer)) != 0
|
||||
&& count != SAFE_READ_ERROR)
|
||||
{
|
||||
/* Analyze the block. */
|
||||
if (zero_block_p (buffer, count))
|
||||
{
|
||||
if (sp.numbytes)
|
||||
{
|
||||
sparse_add_map (st, &sp);
|
||||
sp.numbytes = 0;
|
||||
if (!tar_sparse_scan (file, scan_block, NULL))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sp.numbytes == 0)
|
||||
sp.offset = offset;
|
||||
sp.numbytes += count;
|
||||
st->archive_file_size += count;
|
||||
if (!tar_sparse_scan (file, scan_block, buffer))
|
||||
return false;
|
||||
}
|
||||
|
||||
offset += count;
|
||||
}
|
||||
offset += count;
|
||||
}
|
||||
|
||||
/* save one more sparse segment of length 0 to indicate that
|
||||
the file ends with a hole */
|
||||
if (sp.numbytes == 0)
|
||||
sp.offset = offset;
|
||||
|
||||
@@ -264,6 +261,114 @@ sparse_scan_file (struct tar_sparse_file *file)
|
||||
return tar_sparse_scan (file, scan_end, NULL);
|
||||
}
|
||||
|
||||
static bool
|
||||
sparse_scan_file_wholesparse (struct tar_sparse_file *file)
|
||||
{
|
||||
struct tar_stat_info *st = file->stat_info;
|
||||
struct sp_array sp = {0, 0};
|
||||
|
||||
/* Note that this function is called only for truly sparse files of size >= 1
|
||||
block size (checked via ST_IS_SPARSE before). See the thread
|
||||
http://www.mail-archive.com/bug-tar@gnu.org/msg04209.html for more info */
|
||||
if (ST_NBLOCKS (st->stat) == 0)
|
||||
{
|
||||
st->archive_file_size = 0;
|
||||
sp.offset = st->stat.st_size;
|
||||
sparse_add_map (st, &sp);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef SEEK_HOLE
|
||||
/* Try to engage SEEK_HOLE/SEEK_DATA feature. */
|
||||
static bool
|
||||
sparse_scan_file_seek (struct tar_sparse_file *file)
|
||||
{
|
||||
struct tar_stat_info *st = file->stat_info;
|
||||
int fd = file->fd;
|
||||
struct sp_array sp = {0, 0};
|
||||
off_t offset = 0;
|
||||
off_t data_offset;
|
||||
off_t hole_offset;
|
||||
|
||||
st->archive_file_size = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* locate first chunk of data */
|
||||
data_offset = lseek (fd, offset, SEEK_DATA);
|
||||
|
||||
if (data_offset == (off_t)-1)
|
||||
/* ENXIO == EOF; error otherwise */
|
||||
{
|
||||
if (errno == ENXIO)
|
||||
{
|
||||
/* file ends with hole, add one more empty chunk of data */
|
||||
sp.numbytes = 0;
|
||||
sp.offset = st->stat.st_size;
|
||||
sparse_add_map (st, &sp);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
hole_offset = lseek (fd, data_offset, SEEK_HOLE);
|
||||
|
||||
/* according to specs, if FS does not fully support
|
||||
SEEK_DATA/SEEK_HOLE it may just implement kind of "wrapper" around
|
||||
classic lseek() call. We must detect it here and try to use other
|
||||
hole-detection methods. */
|
||||
if (offset == 0 /* first loop */
|
||||
&& data_offset == 0
|
||||
&& hole_offset == st->stat.st_size)
|
||||
{
|
||||
lseek (fd, 0, SEEK_SET);
|
||||
return false;
|
||||
}
|
||||
|
||||
sp.offset = data_offset;
|
||||
sp.numbytes = hole_offset - data_offset;
|
||||
sparse_add_map (st, &sp);
|
||||
|
||||
st->archive_file_size += sp.numbytes;
|
||||
offset = hole_offset;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
sparse_scan_file (struct tar_sparse_file *file)
|
||||
{
|
||||
/* always check for completely sparse files */
|
||||
if (sparse_scan_file_wholesparse (file))
|
||||
return true;
|
||||
|
||||
switch (hole_detection)
|
||||
{
|
||||
case HOLE_DETECTION_DEFAULT:
|
||||
case HOLE_DETECTION_SEEK:
|
||||
#ifdef SEEK_HOLE
|
||||
if (sparse_scan_file_seek (file))
|
||||
return true;
|
||||
#else
|
||||
if (hole_detection == HOLE_DETECTION_SEEK)
|
||||
WARN((0, 0,
|
||||
_("\"seek\" hole detection is not supported, using \"raw\".")));
|
||||
/* fall back to "raw" for this and all other files */
|
||||
hole_detection = HOLE_DETECTION_RAW;
|
||||
#endif
|
||||
case HOLE_DETECTION_RAW:
|
||||
if (sparse_scan_file_raw (file))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct tar_sparse_optab const oldgnu_optab;
|
||||
static struct tar_sparse_optab const star_optab;
|
||||
static struct tar_sparse_optab const pax_optab;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* This file is part of GNU tar.
|
||||
Copyright 2007, 2009, 2013-2014 Free Software Foundation, Inc.
|
||||
Copyright 2007, 2009, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
Written by Sergey Poznyakoff.
|
||||
|
||||
|
||||
17
src/system.c
17
src/system.c
@@ -1,6 +1,7 @@
|
||||
/* System-dependent calls for tar.
|
||||
|
||||
Copyright 2003-2008, 2010, 2013-2014 Free Software Foundation, Inc.
|
||||
Copyright 2003-2008, 2010, 2013-2014, 2016 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
|
||||
@@ -26,13 +27,14 @@
|
||||
static _Noreturn void
|
||||
xexec (const char *cmd)
|
||||
{
|
||||
struct wordsplit ws;
|
||||
char *argv[4];
|
||||
|
||||
ws.ws_env = (const char **) environ;
|
||||
if (wordsplit (cmd, &ws, (WRDSF_DEFFLAGS | WRDSF_ENV) & ~WRDSF_NOVAR))
|
||||
FATAL_ERROR ((0, 0, _("cannot split string '%s': %s"),
|
||||
cmd, wordsplit_strerror (&ws)));
|
||||
execvp (ws.ws_wordv[0], ws.ws_wordv);
|
||||
argv[0] = (char *) "/bin/sh";
|
||||
argv[1] = (char *) "-c";
|
||||
argv[2] = (char *) cmd;
|
||||
argv[3] = NULL;
|
||||
|
||||
execv ("/bin/sh", argv);
|
||||
exec_fatal (cmd);
|
||||
}
|
||||
|
||||
@@ -330,6 +332,7 @@ sys_child_open_for_compress (void)
|
||||
pid_t grandchild_pid;
|
||||
pid_t child_pid;
|
||||
|
||||
signal (SIGPIPE, SIG_IGN);
|
||||
xpipe (parent_pipe);
|
||||
child_pid = xfork ();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* GNU tar Archive Format description.
|
||||
|
||||
Copyright 1988-1989, 1991-1997, 2000-2001, 2003-2007, 2012-2014 Free
|
||||
Software Foundation, Inc.
|
||||
Copyright 1988-1989, 1991-1997, 2000-2001, 2003-2007, 2012-2014, 2016
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -327,6 +327,10 @@ struct tar_stat_info
|
||||
size_t sparse_map_size; /* Size of the sparse map */
|
||||
struct sp_array *sparse_map;
|
||||
|
||||
off_t real_size; /* The real size of sparse file */
|
||||
int real_size_set; /* True when GNU.sparse.realsize is set in
|
||||
archived file */
|
||||
|
||||
size_t xattr_map_size; /* Size of the xattr map */
|
||||
struct xattr_array *xattr_map;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* This file is part of GNU tar.
|
||||
Copyright 2006-2008, 2013-2014 Free Software Foundation, Inc.
|
||||
Copyright 2006-2008, 2013-2014, 2016 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
|
||||
@@ -378,13 +378,15 @@ parse_transform_expr (const char *expr)
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Try to be nice */
|
||||
{
|
||||
char buf[2];
|
||||
buf[0] = '\\';
|
||||
buf[1] = *cur;
|
||||
add_literal_segment (tf, buf, buf + 2);
|
||||
}
|
||||
if (*cur == delim)
|
||||
add_char_segment (tf, delim);
|
||||
else
|
||||
{
|
||||
char buf[2];
|
||||
buf[0] = '\\';
|
||||
buf[1] = *cur;
|
||||
add_literal_segment (tf, buf, buf + 2);
|
||||
}
|
||||
cur++;
|
||||
break;
|
||||
}
|
||||
|
||||
99
src/unlink.c
99
src/unlink.c
@@ -1,6 +1,6 @@
|
||||
/* Unlink files.
|
||||
|
||||
Copyright 2009, 2013-2014 Free Software Foundation, Inc.
|
||||
Copyright 2009, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -32,6 +32,10 @@ struct deferred_unlink
|
||||
entry got added to the queue */
|
||||
};
|
||||
|
||||
#define IS_CWD(p) \
|
||||
((p)->is_dir \
|
||||
&& ((p)->file_name[0] == 0 || strcmp ((p)->file_name, ".") == 0))
|
||||
|
||||
/* The unlink queue */
|
||||
static struct deferred_unlink *dunlink_head, *dunlink_tail;
|
||||
|
||||
@@ -60,6 +64,24 @@ dunlink_alloc (void)
|
||||
return p;
|
||||
}
|
||||
|
||||
static void
|
||||
dunlink_insert (struct deferred_unlink *anchor, struct deferred_unlink *p)
|
||||
{
|
||||
if (anchor)
|
||||
{
|
||||
p->next = anchor->next;
|
||||
anchor->next = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->next = dunlink_head;
|
||||
dunlink_head = p;
|
||||
}
|
||||
if (!p->next)
|
||||
dunlink_tail = p;
|
||||
dunlink_count++;
|
||||
}
|
||||
|
||||
static void
|
||||
dunlink_reclaim (struct deferred_unlink *p)
|
||||
{
|
||||
@@ -73,7 +95,7 @@ flush_deferred_unlinks (bool force)
|
||||
{
|
||||
struct deferred_unlink *p, *prev = NULL;
|
||||
int saved_chdir = chdir_current;
|
||||
|
||||
|
||||
for (p = dunlink_head; p; )
|
||||
{
|
||||
struct deferred_unlink *next = p->next;
|
||||
@@ -86,12 +108,11 @@ flush_deferred_unlinks (bool force)
|
||||
{
|
||||
const char *fname;
|
||||
|
||||
if (p->dir_idx
|
||||
&& (p->file_name[0] == 0
|
||||
|| strcmp (p->file_name, ".") == 0))
|
||||
if (p->dir_idx && IS_CWD (p))
|
||||
{
|
||||
fname = tar_dirname ();
|
||||
chdir_do (p->dir_idx - 1);
|
||||
prev = p;
|
||||
p = next;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
fname = p->file_name;
|
||||
@@ -103,16 +124,16 @@ flush_deferred_unlinks (bool force)
|
||||
case ENOENT:
|
||||
/* nothing to worry about */
|
||||
break;
|
||||
case EEXIST:
|
||||
/* OpenSolaris >=10 sets EEXIST instead of ENOTEMPTY
|
||||
if trying to remove a non-empty directory */
|
||||
case ENOTEMPTY:
|
||||
if (!force)
|
||||
{
|
||||
/* Keep the record in list, in the hope we'll
|
||||
be able to remove it later */
|
||||
prev = p;
|
||||
p = next;
|
||||
continue;
|
||||
}
|
||||
/* fall through */
|
||||
/* Keep the record in list, in the hope we'll
|
||||
be able to remove it later */
|
||||
prev = p;
|
||||
p = next;
|
||||
continue;
|
||||
|
||||
default:
|
||||
rmdir_error (fname);
|
||||
}
|
||||
@@ -139,6 +160,34 @@ flush_deferred_unlinks (bool force)
|
||||
}
|
||||
if (!dunlink_head)
|
||||
dunlink_tail = NULL;
|
||||
else if (force)
|
||||
{
|
||||
for (p = dunlink_head; p; )
|
||||
{
|
||||
struct deferred_unlink *next = p->next;
|
||||
const char *fname;
|
||||
|
||||
chdir_do (p->dir_idx);
|
||||
if (p->dir_idx && IS_CWD (p))
|
||||
{
|
||||
fname = tar_dirname ();
|
||||
chdir_do (p->dir_idx - 1);
|
||||
}
|
||||
else
|
||||
fname = p->file_name;
|
||||
|
||||
if (unlinkat (chdir_fd, fname, AT_REMOVEDIR) != 0)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
rmdir_error (fname);
|
||||
}
|
||||
dunlink_reclaim (p);
|
||||
dunlink_count--;
|
||||
p = next;
|
||||
}
|
||||
dunlink_head = dunlink_tail = NULL;
|
||||
}
|
||||
|
||||
chdir_do (saved_chdir);
|
||||
}
|
||||
|
||||
@@ -146,6 +195,7 @@ void
|
||||
finish_deferred_unlinks (void)
|
||||
{
|
||||
flush_deferred_unlinks (true);
|
||||
|
||||
while (dunlink_avail)
|
||||
{
|
||||
struct deferred_unlink *next = dunlink_avail->next;
|
||||
@@ -171,10 +221,17 @@ queue_deferred_unlink (const char *name, bool is_dir)
|
||||
p->is_dir = is_dir;
|
||||
p->records_written = records_written;
|
||||
|
||||
if (dunlink_tail)
|
||||
dunlink_tail->next = p;
|
||||
if (IS_CWD (p))
|
||||
{
|
||||
struct deferred_unlink *q, *prev;
|
||||
for (q = dunlink_head, prev = NULL; q; prev = q, q = q->next)
|
||||
if (IS_CWD (q) && q->dir_idx < p->dir_idx)
|
||||
break;
|
||||
if (q)
|
||||
dunlink_insert (prev, p);
|
||||
else
|
||||
dunlink_insert (dunlink_tail, p);
|
||||
}
|
||||
else
|
||||
dunlink_head = p;
|
||||
dunlink_tail = p;
|
||||
dunlink_count++;
|
||||
dunlink_insert (dunlink_tail, p);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Update a tar archive.
|
||||
|
||||
Copyright 1988, 1992, 1994, 1996-1997, 1999-2001, 2003-2005, 2007,
|
||||
2010, 2013-2014 Free Software Foundation, Inc.
|
||||
2010, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* Charset handling for GNU tar.
|
||||
|
||||
Copyright 2004, 2006-2007, 2013-2014 Free Software Foundation, Inc.
|
||||
Copyright 2004, 2006-2007, 2013-2014, 2016 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Warnings for GNU tar.
|
||||
|
||||
Copyright 2009, 2012-2014 Free Software Foundation, Inc.
|
||||
Copyright 2009, 2012-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Support for extended attributes.
|
||||
|
||||
Copyright (C) 2006-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 2006-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Support for extended attributes.
|
||||
|
||||
Copyright (C) 2006-2014 Free Software Foundation, Inc.
|
||||
Copyright (C) 2006-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* POSIX extended headers for tar.
|
||||
|
||||
Copyright (C) 2003-2007, 2009-2010, 2012-2014 Free Software
|
||||
Copyright (C) 2003-2007, 2009-2010, 2012-2014, 2016 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
@@ -755,6 +755,16 @@ xheader_decode (struct tar_stat_info *st)
|
||||
continue;
|
||||
}
|
||||
run_override_list (keyword_override_list, st);
|
||||
|
||||
/* The archived (effective) file size is always set directly in tar header
|
||||
field, possibly overridden by "size" extended header - in both cases,
|
||||
result is now decoded in st->stat.st_size */
|
||||
st->archive_file_size = st->stat.st_size;
|
||||
|
||||
/* The real file size (given by stat()) may be redefined for sparse
|
||||
files in "GNU.sparse.realsize" extended header */
|
||||
if (st->real_size_set)
|
||||
st->stat.st_size = st->real_size;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -803,11 +813,11 @@ xheader_store (char const *keyword, struct tar_stat_info *st,
|
||||
t = locate_handler (keyword);
|
||||
if (!t || !t->coder)
|
||||
return;
|
||||
if (xheader_keyword_deleted_p (keyword)
|
||||
|| xheader_keyword_override_p (keyword))
|
||||
if (xheader_keyword_deleted_p (keyword))
|
||||
return;
|
||||
xheader_init (&st->xhdr);
|
||||
t->coder (st, keyword, &st->xhdr, data);
|
||||
if (!xheader_keyword_override_p (keyword))
|
||||
t->coder (st, keyword, &st->xhdr, data);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1017,7 +1027,7 @@ xheader_string_end (struct xheader *xhdr, char const *keyword)
|
||||
}
|
||||
x_obstack_blank (xhdr, p);
|
||||
x_obstack_1grow (xhdr, '\n');
|
||||
cp = obstack_next_free (xhdr->stk) - xhdr->string_length - p - 1;
|
||||
cp = (char*) obstack_next_free (xhdr->stk) - xhdr->string_length - p - 1;
|
||||
memmove (cp + p, cp, xhdr->string_length);
|
||||
cp = stpcpy (cp, np);
|
||||
*cp++ = ' ';
|
||||
@@ -1360,7 +1370,10 @@ sparse_size_decoder (struct tar_stat_info *st,
|
||||
{
|
||||
uintmax_t u;
|
||||
if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
|
||||
st->stat.st_size = u;
|
||||
{
|
||||
st->real_size_set = 1;
|
||||
st->real_size = u;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1443,13 +1456,13 @@ sparse_map_decoder (struct tar_stat_info *st,
|
||||
size_t size __attribute__((unused)))
|
||||
{
|
||||
int offset = 1;
|
||||
struct sp_array e;
|
||||
|
||||
st->sparse_map_avail = 0;
|
||||
while (1)
|
||||
{
|
||||
intmax_t u;
|
||||
char *delim;
|
||||
struct sp_array e;
|
||||
|
||||
if (!ISDIGIT (*arg))
|
||||
{
|
||||
|
||||
4
tests/.gitignore
vendored
4
tests/.gitignore
vendored
@@ -8,3 +8,7 @@ argcv.c
|
||||
argcv.h
|
||||
genfile.c
|
||||
genfile
|
||||
download
|
||||
ttyemu
|
||||
checkseekhole
|
||||
ckmtime
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Makefile for GNU tar regression tests.
|
||||
|
||||
# Copyright 1996-1997, 1999-2001, 2003-2007, 2009, 2012-2013 Free Software
|
||||
# Copyright 1996-1997, 1999-2001, 2003-2007, 2009, 2012-2015 Free Software
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
@@ -43,9 +43,13 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac
|
||||
|
||||
TESTSUITE_AT = \
|
||||
T-cd.at\
|
||||
T-dir00.at\
|
||||
T-dir01.at\
|
||||
T-empty.at\
|
||||
T-null.at\
|
||||
T-null2.at\
|
||||
T-rec.at\
|
||||
T-recurse.at\
|
||||
T-zfile.at\
|
||||
T-nonl.at\
|
||||
T-mult.at\
|
||||
@@ -56,9 +60,11 @@ TESTSUITE_AT = \
|
||||
append02.at\
|
||||
append03.at\
|
||||
append04.at\
|
||||
append05.at\
|
||||
backup01.at\
|
||||
chtype.at\
|
||||
comprec.at\
|
||||
comperr.at\
|
||||
delete01.at\
|
||||
delete02.at\
|
||||
delete03.at\
|
||||
@@ -114,9 +120,10 @@ TESTSUITE_AT = \
|
||||
incr07.at\
|
||||
incr08.at\
|
||||
incr09.at\
|
||||
incr10.at\
|
||||
incr11.at\
|
||||
indexfile.at\
|
||||
ignfail.at\
|
||||
iotty.at\
|
||||
label01.at\
|
||||
label02.at\
|
||||
label03.at\
|
||||
@@ -136,6 +143,7 @@ TESTSUITE_AT = \
|
||||
lustar01.at\
|
||||
lustar02.at\
|
||||
lustar03.at\
|
||||
map.at\
|
||||
multiv01.at\
|
||||
multiv02.at\
|
||||
multiv03.at\
|
||||
@@ -144,11 +152,14 @@ TESTSUITE_AT = \
|
||||
multiv06.at\
|
||||
multiv07.at\
|
||||
multiv08.at\
|
||||
multiv09.at\
|
||||
numeric.at\
|
||||
old.at\
|
||||
onetop01.at\
|
||||
onetop02.at\
|
||||
onetop03.at\
|
||||
onetop04.at\
|
||||
onetop05.at\
|
||||
opcomp01.at\
|
||||
opcomp02.at\
|
||||
opcomp03.at\
|
||||
@@ -198,12 +209,15 @@ TESTSUITE_AT = \
|
||||
sparse02.at\
|
||||
sparse03.at\
|
||||
sparse04.at\
|
||||
sparse05.at\
|
||||
sparse06.at\
|
||||
sparsemv.at\
|
||||
sparsemvp.at\
|
||||
spmvp00.at\
|
||||
spmvp01.at\
|
||||
spmvp10.at\
|
||||
time01.at\
|
||||
time02.at\
|
||||
truncate.at\
|
||||
update.at\
|
||||
update01.at\
|
||||
@@ -215,6 +229,7 @@ TESTSUITE_AT = \
|
||||
version.at\
|
||||
xform-h.at\
|
||||
xform01.at\
|
||||
xform02.at\
|
||||
star/gtarfail.at\
|
||||
star/gtarfail2.at\
|
||||
star/multi-fail.at\
|
||||
@@ -233,6 +248,9 @@ TESTSUITE_AT = \
|
||||
selacl01.at\
|
||||
capabs_raw01.at
|
||||
|
||||
distclean-local:
|
||||
-rm -rf download
|
||||
|
||||
TESTSUITE = $(srcdir)/testsuite
|
||||
|
||||
AUTOTEST = $(AUTOM4TE) --language=autotest
|
||||
@@ -255,7 +273,7 @@ check-full:
|
||||
#check_SCRIPTS = tar
|
||||
|
||||
# Run the test suite on the *installed* tree.
|
||||
installcheck-local:
|
||||
installcheck-local: $(check_PROGRAMS)
|
||||
$(SHELL) $(TESTSUITE) $(TESTSUITEFLAGS) AUTOTEST_PATH=$(exec_prefix)/bin
|
||||
|
||||
|
||||
@@ -263,15 +281,10 @@ installcheck-local:
|
||||
## genfile ##
|
||||
## ------------ ##
|
||||
|
||||
check_PROGRAMS = genfile
|
||||
|
||||
if TAR_COND_GRANTPT
|
||||
check_PROGRAMS += ttyemu
|
||||
endif
|
||||
check_PROGRAMS = genfile checkseekhole ckmtime
|
||||
|
||||
genfile_SOURCES = genfile.c argcv.c argcv.h
|
||||
|
||||
ttyemu_SOURCES = ttyemu.c
|
||||
checkseekhole_SOURCES = checkseekhole.c
|
||||
|
||||
localedir = $(datadir)/locale
|
||||
AM_CPPFLAGS = \
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
|
||||
46
tests/T-dir00.at
Normal file
46
tests/T-dir00.at
Normal file
@@ -0,0 +1,46 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
# GNU tar is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# GNU tar 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Tar 1.27 and 1.28 did not extract files under directory members listed
|
||||
# in the file read by --file-from.
|
||||
#
|
||||
# Reported-by: Jean-Louis Martineau <martineau@zmanda.com>
|
||||
# References: <541AE02C.2050008@zmanda.com>,
|
||||
# http://lists.gnu.org/archive/html/bug-tar/2014-09/msg00006.html
|
||||
|
||||
AT_SETUP([recursive extraction from --files-from])
|
||||
AT_KEYWORDS([files-from extract T-dir T-dir00])
|
||||
AT_TAR_CHECK([
|
||||
AT_SORT_PREREQ
|
||||
mkdir dir
|
||||
genfile -f dir/file1
|
||||
genfile -f dir/file2
|
||||
tar cf archive dir
|
||||
rm -rf dir
|
||||
echo dir > list
|
||||
tar xfTv archive list | sort
|
||||
],
|
||||
[0],
|
||||
[dir/
|
||||
dir/file1
|
||||
dir/file2
|
||||
])
|
||||
AT_CLEANUP
|
||||
|
||||
46
tests/T-dir01.at
Normal file
46
tests/T-dir01.at
Normal file
@@ -0,0 +1,46 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
# GNU tar is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# GNU tar 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Tar 1.27 and 1.28 did not remove trailing slashes from file names
|
||||
# obtained with the --file-from option.
|
||||
#
|
||||
# Reported-by: Jean-Louis Martineau <martineau@zmanda.com>
|
||||
# References: <541AE02C.2050008@zmanda.com>,
|
||||
# http://lists.gnu.org/archive/html/bug-tar/2014-09/msg00006.html
|
||||
|
||||
AT_SETUP([trailing slash in --files-from])
|
||||
AT_KEYWORDS([files-from extract T-dir T-dir01])
|
||||
AT_TAR_CHECK([
|
||||
AT_SORT_PREREQ
|
||||
mkdir dir
|
||||
genfile -f dir/file1
|
||||
genfile -f dir/file2
|
||||
tar cf archive dir
|
||||
rm -rf dir
|
||||
echo dir/ > list
|
||||
tar xfTv archive list | sort
|
||||
],
|
||||
[0],
|
||||
[dir/
|
||||
dir/file1
|
||||
dir/file2
|
||||
])
|
||||
AT_CLEANUP
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2006-2007, 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2006-2007, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2006-2007, 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2006-2007, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
43
tests/T-null2.at
Normal file
43
tests/T-null2.at
Normal file
@@ -0,0 +1,43 @@
|
||||
# This file is part of test suite for GNU tar. -*- Autotest -*-
|
||||
# Copyright 2015-2016 Free Software Foundation, Inc.
|
||||
#
|
||||
# GNU tar is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# GNU tar 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
AT_SETUP([--null enables verbatim reading])
|
||||
AT_KEYWORDS([files-from null T-null2 T-verbatim])
|
||||
|
||||
# According to the docs, --null should read each line from the file
|
||||
# list verbatim. This feature was broken by commit 26538c9b (tar version
|
||||
# 1.27).
|
||||
|
||||
AT_TAR_CHECK([
|
||||
AT_DATA([file-list],[a
|
||||
-b
|
||||
--c d
|
||||
])
|
||||
|
||||
genfile -f a
|
||||
genfile -f -b
|
||||
genfile -f '--c d'
|
||||
|
||||
cat file-list | tr '\n' '\0' | tar -c -f archive -v --null -T -
|
||||
],
|
||||
[0],
|
||||
[a
|
||||
-b
|
||||
--c d
|
||||
],
|
||||
[],[],[],[ustar]) # Testing one format is enough
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
|
||||
90
tests/T-recurse.at
Normal file
90
tests/T-recurse.at
Normal file
@@ -0,0 +1,90 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2015-2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
# GNU tar is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# GNU tar 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Description: Test interaction of --recursion and --no-recursion options
|
||||
# together with --files-from option. This is complementary to recurs02.at test
|
||||
# case. References:
|
||||
# <alpine.LSU.2.11.1502201029580.29773@nerf60.vanv.qr>
|
||||
# http://lists.gnu.org/archive/html/bug-tar/2015-06/msg00006.html
|
||||
|
||||
AT_SETUP([files-from & recurse: toggle])
|
||||
AT_KEYWORDS([recurse T-recurse files-from])
|
||||
|
||||
AT_TAR_CHECK([
|
||||
mkdir directory1 directory2
|
||||
touch directory1/file directory2/file
|
||||
|
||||
AT_DATA([F1],[--no-recursion
|
||||
directory1/
|
||||
--recursion
|
||||
directory2/
|
||||
])
|
||||
|
||||
AT_DATA([F2A],[directory1/
|
||||
])
|
||||
|
||||
AT_DATA([F2B],[directory2/
|
||||
])
|
||||
|
||||
a=archive
|
||||
tar cf "$a" --files-from F1
|
||||
tar tf "$a"
|
||||
|
||||
a=archive2
|
||||
tar cf "$a" --no-recursion -T F2A --recursion -T F2B
|
||||
tar tf "$a"
|
||||
],
|
||||
[0],
|
||||
[directory1/
|
||||
directory2/
|
||||
directory2/file
|
||||
directory1/
|
||||
directory2/
|
||||
directory2/file
|
||||
])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
AT_SETUP([toggle --recursion (not) from -T])
|
||||
AT_KEYWORDS([recurse T-recurse T-recurse2 files-from])
|
||||
|
||||
AT_TAR_CHECK([
|
||||
mkdir directory1 directory2
|
||||
touch directory1/file directory2/file
|
||||
|
||||
AT_DATA([F1],[--no-recursion
|
||||
directory1/
|
||||
])
|
||||
|
||||
AT_DATA([F2],[directory2/
|
||||
])
|
||||
|
||||
tar cf archive -T F1 --recursion -T F2
|
||||
tar tf archive
|
||||
|
||||
],
|
||||
[0],
|
||||
[directory1/
|
||||
directory2/
|
||||
directory2/file
|
||||
])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2011, 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2011, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2011, 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2011, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2013, 2014 Free Software Foundation, Inc.
|
||||
# Copyright 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2004, 2006-2007, 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2004, 2006-2007, 2013-2014, 2016 Free Software Foundation,
|
||||
# Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
@@ -26,7 +27,7 @@ AT_TAR_CHECK([touch file1
|
||||
tar cf archive file1
|
||||
tar rf archive file2
|
||||
tar tf archive],
|
||||
[0],
|
||||
[0],
|
||||
[file1
|
||||
file2
|
||||
])
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2005-2007, 2013-2014 Free Software Foundation, Inc.
|
||||
# Copyright 2005-2007, 2013-2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user