Compare commits
71 Commits
release_1_
...
release_1_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3f04456e8 | ||
|
|
d78083e82c | ||
|
|
c8d4ceccc1 | ||
|
|
6287d3045f | ||
|
|
9d3142805b | ||
|
|
05eddc1a58 | ||
|
|
78bfbb5661 | ||
|
|
fe576585e6 | ||
|
|
080a6b2ac5 | ||
|
|
f236f33643 | ||
|
|
a4ffcfb875 | ||
|
|
967fcb9318 | ||
|
|
12b3a5d5b1 | ||
|
|
eeb610da48 | ||
|
|
749e20e6fa | ||
|
|
56f6556f94 | ||
|
|
43c5343194 | ||
|
|
250db35f17 | ||
|
|
6f929b2c89 | ||
|
|
64cddf2fbc | ||
|
|
ccdbafb276 | ||
|
|
bd222d606a | ||
|
|
94fb06f5db | ||
|
|
74d217db74 | ||
|
|
17ef61b2fd | ||
|
|
f32828d577 | ||
|
|
e67e085421 | ||
|
|
ca856c2585 | ||
|
|
18641602c1 | ||
|
|
8bdbc08a89 | ||
|
|
a5d5cc599f | ||
|
|
761895d43c | ||
|
|
5d4f057e31 | ||
|
|
7c0ba663c8 | ||
|
|
51118be241 | ||
|
|
69f5d77383 | ||
|
|
d989864712 | ||
|
|
983d328ff2 | ||
|
|
586c684815 | ||
|
|
bbf7dec45e | ||
|
|
40f79286ab | ||
|
|
ebc522d521 | ||
|
|
ad85f632c6 | ||
|
|
062b37115f | ||
|
|
6261c58ae8 | ||
|
|
427bda01a3 | ||
|
|
1d26fff0f3 | ||
|
|
bb6b92e37d | ||
|
|
8ca4064a8c | ||
|
|
5c890a6003 | ||
|
|
3705fd6452 | ||
|
|
bde442ba15 | ||
|
|
c9a8f1bc33 | ||
|
|
66e9b9cd6c | ||
|
|
b9588c4722 | ||
|
|
9a41b3b3db | ||
|
|
990e7d4437 | ||
|
|
173d3229e3 | ||
|
|
2d261da8f9 | ||
|
|
99527fa17b | ||
|
|
868ee74028 | ||
|
|
8c90bf0414 | ||
|
|
892cdea8a1 | ||
|
|
00763876f1 | ||
|
|
1a1cfaafa6 | ||
|
|
445d95be07 | ||
|
|
6fe55234c9 | ||
|
|
e24d8574a8 | ||
|
|
4da5205ed6 | ||
|
|
8241687465 | ||
|
|
8e3f3adf98 |
238
ChangeLog
238
ChangeLog
@@ -1,3 +1,198 @@
|
||||
2007-06-08 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* configure.ac, NEWS: Raise version number to 1.17
|
||||
|
||||
* doc/tar.texi, doc/intern.texi: Replace: s/filename/file name/;
|
||||
s/(ASCII|ID|BSD)/@acronym{&}/;s/"[^"]+"/``&''/
|
||||
Use `path' only when it refers to search paths, use
|
||||
`file name' otherwise.
|
||||
Fix various errors (based on patch by Benno Schulenberg)
|
||||
|
||||
* doc/tar.texi (Operation Summary): Restore alphabetical order of
|
||||
the options.
|
||||
|
||||
2007-06-02 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
Fix bug, introduced on 2007-03-30.
|
||||
|
||||
* src/common.h (xform_type): New data type
|
||||
(transform_member_name): Last argument is of xform_type type
|
||||
All callers updated
|
||||
|
||||
* src/extract.c: Update calls to transform_member_name
|
||||
* src/list.c (decode_xform): Exempt symbolic links from component
|
||||
stripping and name suffix normalization.
|
||||
|
||||
* tests/extrac07.at: Update
|
||||
|
||||
2007-05-30 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* src/xheader.c (decx): Unknown pax keywords produce a warning,
|
||||
not error.
|
||||
|
||||
2007-05-29 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* src/misc.c (set_file_atime): Use gl_futimens, not futimens,
|
||||
due to gnulib change.
|
||||
|
||||
2007-05-19 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* src/common.h (buffer_write_global_xheader): New function
|
||||
(struct xheader): Move definition to tar.h
|
||||
(extended_header): Remove global
|
||||
(xheader_init): New function
|
||||
(xheader_decode_global,xheader_store,xheader_read)
|
||||
(xheader_write_global,xheader_write,xheader_string_begin)
|
||||
(xheader_string_add,xheader_string_end): Take xhdr as first
|
||||
argument.
|
||||
* src/tar.h (struct xheader): New definition
|
||||
(struct tar_stat_info): New member xhdr (extended header).
|
||||
|
||||
* src/xheader.c (xheader_init): New function
|
||||
(xheader_decode_global,xheader_store,xheader_read)
|
||||
(xheader_write_global,xheader_write,xheader_string_begin)
|
||||
(xheader_string_add,xheader_string_end): Take xhdr as first
|
||||
argument.
|
||||
|
||||
* src/buffer.c (buffer_write_global_xheader): New function
|
||||
Update to use new xheader calls.
|
||||
|
||||
* src/compare.c, src/create.c, src/delete.c, src/list.c,
|
||||
src/sparse.c, src/tar.c, src/update.c: Global extended_header
|
||||
removed, use new xheader calls instead.
|
||||
|
||||
* tests/T-null.at: Minor fix
|
||||
* tests/atlocal.in (tarball_prereq): Discard eventual md5sum
|
||||
output.
|
||||
|
||||
2007-05-18 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* src/create.c (dump_file0): Original ctime cannot be used as a
|
||||
directory change indicator if --remove-files is given.
|
||||
|
||||
2007-04-12 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Adjust to latest Gnulib.
|
||||
* lib/.cvsignore: Add dirfd.c, dirfd.h, float+.h, mbscasecmp.c,
|
||||
stdio.h, stdio_.h, stdlib.h, stdlib_.h, time.h, time_.h, unistd.h.
|
||||
Remove exit.h, getcwd.h, mempcpy.h, memrchr.h, mkdtemp.h, stpcpy.h,
|
||||
strcase.h, strchrnul.h, strdup.h, strndup.h, strnlen.h, time_r.h,
|
||||
vsnprintf.h.
|
||||
* m4/.cvsignore: Remove localedir.h. Sort.
|
||||
|
||||
2007-04-03 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* src/common.h (closeopen): Remove decl.
|
||||
* src/misc.c: Don't include <sys/time.h>, <sys/resource.h>; no longer
|
||||
needed.
|
||||
(get_max_open_files, closeopen): Remove. All callers removed.
|
||||
(chdir_dir): Use a different technique, which doesn't rely on closing
|
||||
all open files.
|
||||
* src/tar.c (main): Don't call closeopen.
|
||||
|
||||
2007-04-04 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* NEWS: Update
|
||||
* doc/tar.texi: Update
|
||||
* src/system.c (sys_exec_info_script): Store the
|
||||
inter-communication fd in the environment variable TAR_FD
|
||||
|
||||
2007-04-03 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* src/tar.c (main): Move closeopen after decode_options to
|
||||
allow shell process substitution to work.
|
||||
* tests/extrac07.at: Expect a warning on stderr.
|
||||
|
||||
2007-03-30 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* src/common.h (transform_name_fp): Change signature
|
||||
(transform_member_name): New function
|
||||
* src/extract.c (extract_link, extract_symlink): Use
|
||||
transform_member_name instead of safer_name_suffix so that
|
||||
--transform and --strip-components affect links as well.
|
||||
* src/list.c (transform_member_name): New function
|
||||
(decode_header): Use transform_member_name
|
||||
* src/names.c (all_names_found): Remove check for matching_flags.
|
||||
* NEWS: Update
|
||||
|
||||
* TODO: Update
|
||||
* bootstrap (slurp): Remove any occurrences of $bt from the
|
||||
generated gnulib.mk
|
||||
* src/incremen.c: Do not include mkdtemp.h
|
||||
|
||||
2007-01-26 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Adjust to recent gnulib changes.
|
||||
* lib/.cvsignore: Add fchownat.c, rmt-command.h, strerror.c, string.h,
|
||||
string_.h, sys, sys_time_.h, unistd_.h, wchar_.h, wctype_.h.
|
||||
Remove localedir.h, size_max.h, xsize.h.
|
||||
* src/xheader.c: Don't include stpcpy.h; no longer needed, now that
|
||||
gnulib string.h defines stpcpy on all platforms.
|
||||
|
||||
2007-01-23 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* doc/tar.texi: Document --exclude-caches* and --exclude-tag*
|
||||
options.
|
||||
* src/common.h (exclude_caches_option): Remove
|
||||
(enum exclusion_tag_type): New data type
|
||||
(add_exclude_tag): Rename to add_exclusion_tag
|
||||
(cachedir_file_p): New prototype
|
||||
* src/create.c (struct exclude_tag): rename to exclusion_tag
|
||||
(check_exclusion_tags): New function
|
||||
(cachedir_file_p): New function (from check_cache_directory)
|
||||
(dump_dir0,dump_file0): Use check_exclusion_tags
|
||||
* src/tar.c: New options --exclude-caches-all,
|
||||
--exclude-caches-under, --exclude-tag-all, --exclude-tag-under
|
||||
* tests/exclude.at: New file
|
||||
* tests/Makefile.am (TESTSUITE_AT): Add exclude.at
|
||||
* tests/testsuite.at: Add exclude.at
|
||||
|
||||
2007-01-19 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* gnulib.modules: Require strerror
|
||||
* doc/gendocs_template: Fix typos
|
||||
* scripts/xsparse.c (expand_sparse): use ftruncate to handle the
|
||||
trailing hole
|
||||
* src/sparse.c (sparse_skip_file,pax_dump_header_1)
|
||||
(pax_decode_header): Keep track of the number of bytes
|
||||
written.
|
||||
* configure.ac: Version 1.16.2
|
||||
* NEWS: Update
|
||||
|
||||
2007-01-04 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* src/compare.c (diff_dumpdir): Compare directory contents using
|
||||
dumpdir_cmp. Do not free dumpdir_buffer, it will leave the
|
||||
incremental directory table in the inconsistent state and trigger
|
||||
full dump.
|
||||
(read_and_process): Process dumpdirs no matter what the archive
|
||||
format.
|
||||
* src/incremen.c (list_dumpdir): Minor fixes.
|
||||
|
||||
* src/compare.c (read_and_process): Fix type of "size"
|
||||
|
||||
2006-12-13 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* tests/T-null.at: Skip the test if genfile is not able to create
|
||||
the filename with an embedded newline.
|
||||
|
||||
2006-12-12 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Port to Forte Developer 7 C 5.4 and C99.
|
||||
* src/common.h (add_exclude_tag): Add decl; C99 requires this
|
||||
and Forte warns about it.
|
||||
* src/incremen.c: Include <mkdtemp.h> for mkdtemp prototype,
|
||||
for same reason.
|
||||
* src/misc.c (get_max_open_files): Rewrite to avoid code that
|
||||
Forte C complains about as being unreachable.
|
||||
* src/xheader.c (mtime_code): Rewrite to avoid Forte error
|
||||
reported by Trond Hasle Amundsen.
|
||||
|
||||
* src/incremen.c (compare_dirnames): Rewrite to avoid casts.
|
||||
* src/utf8.c (string_ascii_p): Likewise.
|
||||
* src/xheader.c (mtime_coder, volume_size_coder, volume_offset_coder):
|
||||
Likewise.
|
||||
|
||||
2006-12-08 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* bootstrap: Add paxutils files to dot_ignore.
|
||||
@@ -19,7 +214,7 @@
|
||||
Patch proposed by Jan-Benedict Glaw <jbglaw@lug-owl.de>
|
||||
* tests/truncate.at: Use genfile instead of dd, because on some
|
||||
systems /dev/zero is not available.
|
||||
|
||||
|
||||
2006-12-04 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* NEWS: Fix some race conditions with tar -x --same-owner.
|
||||
@@ -8049,31 +8244,28 @@
|
||||
time_from_oct, uid_from_oct, uintmax_from_oct): New decls.
|
||||
(print_for_mkdir): 2nd arg is now mode_t.
|
||||
|
||||
See ChangeLog.1 for earlier changes.
|
||||
-----
|
||||
|
||||
See ChangeLog.1 for earlier changes.
|
||||
|
||||
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
-----
|
||||
|
||||
This file is part of GNU tar.
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007
|
||||
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 2, or (at your option)
|
||||
any later version.
|
||||
This file is part of GNU tar.
|
||||
|
||||
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.
|
||||
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 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU tar; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
|
||||
Local Variables:
|
||||
mode: change-log
|
||||
version-control: never
|
||||
End:
|
||||
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 GNU tar; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
|
||||
33
NEWS
33
NEWS
@@ -1,7 +1,28 @@
|
||||
GNU tar NEWS - User visible changes.
|
||||
GNU tar NEWS - User visible changes. 2007-06-08
|
||||
Please send GNU tar bug reports to <bug-tar@gnu.org>
|
||||
|
||||
version 1.16.1
|
||||
version 1.17 - Sergey Poznyakoff, 2007-06-08
|
||||
|
||||
* Fix archivation of sparse files in posix mode. Previous versions padded
|
||||
sparse members with spurious zero blocks.
|
||||
|
||||
* Fix operation of --verify --listed-incremental. Version 1.16.1 produced
|
||||
a full dump when both options were given.
|
||||
|
||||
* Fix --occurence. In previous versions it continued scanning the archive
|
||||
even though all requested members has already been extracted.
|
||||
|
||||
* Scope of --transform and --strip-components options.
|
||||
|
||||
In addition to affecting regular archive members, the --transform
|
||||
option affects hard and soft link targets and the --strip-components
|
||||
option affects hard link targets as well.
|
||||
|
||||
* End-of-volume script can send the new volume name to tar by writing
|
||||
it to the file descriptor stored in the environment variable `TAR_FD'.
|
||||
|
||||
|
||||
version 1.16.1 - Sergey Poznyakoff, 2006-12-09
|
||||
|
||||
* New option --exclude-tag allows to specify "exclusion tag files", i.e.
|
||||
files whose presence in a directory means that the directory should not
|
||||
@@ -208,7 +229,7 @@ Consequently, the file pointer was set off and the next member
|
||||
was not processed correctly.
|
||||
** Previous version created invalid archives when files shrink
|
||||
during reading.
|
||||
** Compare mode (tar d) hanged when trying to compare file contents.
|
||||
** Compare mode (tar d) hung when trying to compare file contents.
|
||||
** Previous versions in certain cases failed to restore directory
|
||||
modification times.
|
||||
** When creating an archive, do not attempt to store files whose
|
||||
@@ -865,7 +886,7 @@ Versions 1.07 back to 1.00 by Jay Fenlason.
|
||||
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003,
|
||||
2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
@@ -887,4 +908,8 @@ Boston, MA 02110-1301, USA.
|
||||
Local variables:
|
||||
mode: outline
|
||||
paragraph-separate: "[ ]*$"
|
||||
eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
time-stamp-start: "changes. "
|
||||
time-stamp-format: "%:y-%02m-%02d"
|
||||
time-stamp-end: "\n"
|
||||
end:
|
||||
|
||||
6
TODO
6
TODO
@@ -1,5 +1,7 @@
|
||||
Suggestions for improving GNU tar.
|
||||
|
||||
* <45BEC0DB.8040903@unix-beratung.de>
|
||||
|
||||
* Incorporate fixes from major distributions, e.g., Debian GNU/Linux.
|
||||
|
||||
* Add support for restoring file time stamps to sub-second resolution,
|
||||
@@ -10,10 +12,6 @@ Suggestions for improving GNU tar.
|
||||
|
||||
* --append should bail out if the two archives are of different types.
|
||||
|
||||
* Add support for GNU private keywords in POSIX 1003.1-2001 headers,
|
||||
so that the GNU extensions (--incremental, --label and
|
||||
--multi-volume) may be used with POSIX archives.
|
||||
|
||||
* Add support for a 'pax' command that conforms to POSIX 1003.1-2001.
|
||||
This would unify paxutils with tar.
|
||||
|
||||
|
||||
@@ -478,7 +478,7 @@ slurp() {
|
||||
done
|
||||
if test $file = Makefile.am; then
|
||||
copied=$copied${sep}gnulib.mk; sep=$nl
|
||||
remove_intl='/^[^#].*\/intl/s/^/#/'
|
||||
remove_intl='/^[^#].*\/intl/s/^/#/;'"s,/$bt,,g"
|
||||
sed "$remove_intl" $1/$dir/$file | cmp -s - $dir/gnulib.mk || {
|
||||
echo "$0: Copying $1/$dir/$file to $dir/gnulib.mk ..." &&
|
||||
rm -f $dir/gnulib.mk &&
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Configure template for GNU tar.
|
||||
|
||||
# Copyright (C) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
# 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -18,7 +18,7 @@
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
|
||||
AC_INIT([GNU tar], [1.16.1], [bug-tar@gnu.org])
|
||||
AC_INIT([GNU tar], [1.17], [bug-tar@gnu.org])
|
||||
AC_CONFIG_SRCDIR([src/tar.c])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_HEADERS([config.h:config.hin])
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<!-- $Id: gendocs_template,v 1.2 2005/05/15 03:59:09 eggert Exp $ -->
|
||||
<!-- $Id: gendocs_template,v 1.3 2007/01/19 15:41:39 gray Exp $ -->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
|
||||
<head>
|
||||
@@ -44,10 +44,10 @@ The manual for %%PACKAGE%% is available in the following formats:</p>
|
||||
<li><a href="%%PACKAGE%%.html.gz">HTML compressed
|
||||
(%%HTML_MONO_GZ_SIZE%%K gzipped characters)</a> - entirely on
|
||||
one web page.</li>
|
||||
<li><a href="%%PACKAGE%%_html_node.tar.gz">HTML compressed
|
||||
<li><a href="%%PACKAGE%%.html_node.tar.gz">HTML compressed
|
||||
(%%HTML_NODE_TGZ_SIZE%%K gzipped tar file)</a> -
|
||||
with one web page per node.</li>
|
||||
<li><a href="%%PACKAGE%%-info.tar.gz">Info document
|
||||
<li><a href="%%PACKAGE%%.info.tar.gz">Info document
|
||||
(%%INFO_TGZ_SIZE%%K characters gzipped tar file)</a>.</li>
|
||||
<li><a href="%%PACKAGE%%.txt">ASCII text
|
||||
(%%ASCII_SIZE%%K characters)</a>.</li>
|
||||
@@ -99,7 +99,7 @@ permitted in any medium, provided this notice is preserved.
|
||||
<p>
|
||||
Updated:
|
||||
<!-- timestamp start -->
|
||||
$Date: 2005/05/15 03:59:09 $ $Author: eggert $
|
||||
$Date: 2007/01/19 15:41:39 $ $Author: gray $
|
||||
<!-- timestamp end -->
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -96,7 +96,7 @@ The @code{name} field is the file name of the file, with directory names
|
||||
@FIXME{how big a name before field overflows?}
|
||||
|
||||
The @code{mode} field provides nine bits specifying file permissions
|
||||
and three bits to specify the Set UID, Set GID, and Save Text
|
||||
and three bits to specify the Set @acronym{UID}, Set @acronym{GID}, and Save Text
|
||||
(@dfn{sticky}) modes. Values for these bits are defined above.
|
||||
When special permissions are required to create a file with a given
|
||||
mode, and the user restoring files from the archive does not hold such
|
||||
@@ -107,8 +107,8 @@ should be faked up when creating or updating an archive; e.g., the
|
||||
group permission could be copied from the @emph{other} permission.
|
||||
|
||||
The @code{uid} and @code{gid} fields are the numeric user and group
|
||||
ID of the file owners, respectively. If the operating system does
|
||||
not support numeric user or group IDs, these fields should be ignored.
|
||||
@acronym{ID} of the file owners, respectively. If the operating system does
|
||||
not support numeric user or group @acronym{ID}s, these fields should be ignored.
|
||||
|
||||
The @code{size} field is the size of the file in bytes; linked files
|
||||
are archived with this field specified as zero. @FIXME-xref{Modifiers, in
|
||||
@@ -258,7 +258,7 @@ The @code{magic} field indicates that this archive was output in
|
||||
the P1003 archive format. If this field contains @code{TMAGIC},
|
||||
the @code{uname} and @code{gname} fields will contain the ASCII
|
||||
representation of the owner and group of the file respectively.
|
||||
If found, the user and group IDs are used rather than the values in
|
||||
If found, the user and group @acronym{ID}s are used rather than the values in
|
||||
the @code{uid} and @code{gid} fields.
|
||||
|
||||
For references, see ISO/IEC 9945-1:1990 or IEEE Std 1003.1-1990, pages
|
||||
|
||||
414
doc/tar.texi
414
doc/tar.texi
@@ -35,7 +35,7 @@ This manual is for @acronym{GNU} @command{tar} (version
|
||||
from archives.
|
||||
|
||||
Copyright @copyright{} 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2001,
|
||||
2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
@@ -685,16 +685,16 @@ file system. You should have some basic understanding of directory
|
||||
structure and how files are named according to which directory they are
|
||||
in. You should understand concepts such as standard output and standard
|
||||
input, what various definitions of the term ``argument'' mean, and the
|
||||
differences between relative and absolute path names. @FIXME{and what
|
||||
differences between relative and absolute file names. @FIXME{and what
|
||||
else?}
|
||||
|
||||
@item
|
||||
This manual assumes that you are working from your own home directory
|
||||
(unless we state otherwise). In this tutorial, you will create a
|
||||
directory to practice @command{tar} commands in. When we show path names,
|
||||
we will assume that those paths are relative to your home directory.
|
||||
For example, my home directory path is @file{/home/fsf/melissa}. All of
|
||||
my examples are in a subdirectory of the directory named by that path
|
||||
directory to practice @command{tar} commands in. When we show file names,
|
||||
we will assume that those names are relative to your home directory.
|
||||
For example, my home directory is @file{/home/fsf/melissa}. All of
|
||||
my examples are in a subdirectory of the directory named by that file
|
||||
name; the subdirectory is called @file{practice}.
|
||||
|
||||
@item
|
||||
@@ -957,7 +957,7 @@ format=verbose, Verbose listing, fileutils, GNU file utilities}).
|
||||
|
||||
@item Owner name and group separated by a slash character.
|
||||
If these data are not available (for example, when listing a @samp{v7} format
|
||||
archive), numeric ID values are printed instead.
|
||||
archive), numeric @acronym{ID} values are printed instead.
|
||||
|
||||
@item Size of the file, in bytes.
|
||||
|
||||
@@ -1090,7 +1090,7 @@ is a subdirectory of your home directory.
|
||||
|
||||
Now @command{cd} to the directory named @file{practice}; @file{practice}
|
||||
is now your @dfn{working directory}. (@emph{Please note}: Although
|
||||
the full path name of this directory is
|
||||
the full file name of this directory is
|
||||
@file{/@var{homedir}/practice}, in our examples we will refer to
|
||||
this directory as @file{practice}; the @var{homedir} is presumed.
|
||||
|
||||
@@ -1459,7 +1459,7 @@ using @samp{list}. In this case, @command{tar} will only list the
|
||||
names of members you identify. For example, @w{@kbd{tar --list
|
||||
--file=afiles.tar apple}} would only print @file{apple}.
|
||||
|
||||
Because @command{tar} preserves paths, file names must be specified as
|
||||
Because @command{tar} preserves file names, these must be specified as
|
||||
they appear in the archive (i.e., relative to the directory from which
|
||||
the archive was created). Therefore, it is essential when specifying
|
||||
member names to @command{tar} that you give the exact member names.
|
||||
@@ -2502,13 +2502,42 @@ patterns in the file @var{file}. @xref{exclude}.
|
||||
@opsummary{exclude-caches}
|
||||
@item --exclude-caches
|
||||
|
||||
Automatically excludes all directories
|
||||
containing a cache directory tag. @xref{exclude}.
|
||||
Exclude from dump any directory containing a valid cache directory
|
||||
tag file, but still dump the directory node and the tag file itself.
|
||||
|
||||
@xref{exclude}.
|
||||
|
||||
@opsummary{exclude-caches-under}
|
||||
@item --exclude-caches-under
|
||||
|
||||
Exclude from dump any directory containing a valid cache directory
|
||||
tag file, but still dump the directory node itself.
|
||||
|
||||
@xref{exclude}.
|
||||
|
||||
@opsummary{exclude-caches-all}
|
||||
@item --exclude-caches-all
|
||||
|
||||
Exclude from dump any directory containing a valid cache directory
|
||||
tag file. @xref{exclude}.
|
||||
|
||||
@opsummary{exclude-tag}
|
||||
@item --exclude-tag=@var{file}
|
||||
|
||||
Exclude all directories, containing file named @var{file}. @xref{exclude}.
|
||||
Exclude from dump any directory containing file named @var{file}, but
|
||||
dump the directory node and @var{file} itself. @xref{exclude}.
|
||||
|
||||
@opsummary{exclude-tag-under}
|
||||
@item --exclude-tag-under=@var{file}
|
||||
|
||||
Exclude from dump the contents of any directory containing file
|
||||
named @var{file}, but dump the directory node itself. @xref{exclude}.
|
||||
|
||||
@opsummary{exclude-tag-all}
|
||||
@item --exclude-tag-all=@var{file}
|
||||
|
||||
Exclude from dump any directory containing file named @var{file}.
|
||||
@xref{exclude}.
|
||||
|
||||
@opsummary{file}
|
||||
@item --file=@var{archive}
|
||||
@@ -2529,7 +2558,7 @@ command-line. @xref{files}.
|
||||
@opsummary{force-local}
|
||||
@item --force-local
|
||||
|
||||
Forces @command{tar} to interpret the filename given to @option{--file}
|
||||
Forces @command{tar} to interpret the file name given to @option{--file}
|
||||
as a local file, even if it looks like a remote tape drive name.
|
||||
@xref{local and remote archives}.
|
||||
|
||||
@@ -2566,10 +2595,10 @@ Creates a @acronym{POSIX.1-2001 archive}.
|
||||
@opsummary{group}
|
||||
@item --group=@var{group}
|
||||
|
||||
Files added to the @command{tar} archive will have a group id of @var{group},
|
||||
Files added to the @command{tar} archive will have a group @acronym{ID} of @var{group},
|
||||
rather than the group from the source file. @var{group} is first decoded
|
||||
as a group symbolic name, but if this interpretation fails, it has to be
|
||||
a decimal numeric group ID. @xref{override}.
|
||||
a decimal numeric group @acronym{ID}. @xref{override}.
|
||||
|
||||
Also see the comments for the @option{--owner=@var{user}} option.
|
||||
|
||||
@@ -2618,7 +2647,7 @@ archive, which normally signals EOF. @xref{Reading}.
|
||||
@item --incremental
|
||||
@itemx -G
|
||||
|
||||
Used to inform @command{tar} that it is working with an old
|
||||
Informs @command{tar} that it is working with an old
|
||||
@acronym{GNU}-format incremental backup archive. It is intended
|
||||
primarily for backwards compatibility only. @xref{Incremental Dumps},
|
||||
for a detailed discussion of incremental archives.
|
||||
@@ -2711,15 +2740,6 @@ multi-volume @command{tar} archive. @xref{Using Multiple Tapes}.
|
||||
|
||||
(see --info-script)
|
||||
|
||||
@opsummary{seek}
|
||||
@item --seek
|
||||
@itemx -n
|
||||
|
||||
Assume that the archive media supports seeks to arbitrary
|
||||
locations. Usually @command{tar} determines automatically whether
|
||||
the archive can be seeked or not. This option is intended for use
|
||||
in cases when such recognition fails.
|
||||
|
||||
@opsummary{newer}
|
||||
@item --newer=@var{date}
|
||||
@itemx --after-date=@var{date}
|
||||
@@ -2746,9 +2766,10 @@ An exclude pattern can match any subsequence of the name's components.
|
||||
@opsummary{no-delay-directory-restore}
|
||||
@item --no-delay-directory-restore
|
||||
|
||||
Setting modification times and permissions of extracted
|
||||
directories when all files from this directory has been
|
||||
extracted. This is the default. @xref{Directory Modification Times and Permissions}.
|
||||
Modification times and permissions of extracted
|
||||
directories are set when all files from this directory have been
|
||||
extracted. This is the default.
|
||||
@xref{Directory Modification Times and Permissions}.
|
||||
|
||||
@opsummary{no-ignore-case}
|
||||
@item --no-ignore-case
|
||||
@@ -2757,7 +2778,7 @@ Use case-sensitive matching.
|
||||
|
||||
@opsummary{no-ignore-command-error}
|
||||
@item --no-ignore-command-error
|
||||
Print warnings about subprocesses terminated with a non-zero exit
|
||||
Print warnings about subprocesses that terminated with a nonzero exit
|
||||
code. @xref{Writing to an External Program}.
|
||||
|
||||
@opsummary{no-overwrite-dir}
|
||||
@@ -2812,7 +2833,7 @@ Wildcards do not match @samp{/}.
|
||||
@item --null
|
||||
|
||||
When @command{tar} is using the @option{--files-from} option, this option
|
||||
instructs @command{tar} to expect filenames terminated with @option{NUL}, so
|
||||
instructs @command{tar} to expect file names terminated with @acronym{NUL}, so
|
||||
@command{tar} can correctly work with file names that contain newlines.
|
||||
@xref{nul}.
|
||||
|
||||
@@ -2832,7 +2853,7 @@ restoring ownership of files being extracted.
|
||||
When creating an archive, it is a synonym for
|
||||
@option{--old-archive}. This behavior is for compatibility
|
||||
with previous versions of @GNUTAR{}, and will be
|
||||
removed in the future releases.
|
||||
removed in future releases.
|
||||
|
||||
@xref{Changes}, for more information.
|
||||
|
||||
@@ -2885,44 +2906,11 @@ from an archive. @xref{Overwrite Old Files}.
|
||||
Specifies that @command{tar} should use @var{user} as the owner of members
|
||||
when creating archives, instead of the user associated with the source
|
||||
file. @var{user} is first decoded as a user symbolic name, but if
|
||||
this interpretation fails, it has to be a decimal numeric user ID.
|
||||
this interpretation fails, it has to be a decimal numeric user @acronym{ID}.
|
||||
@xref{override}.
|
||||
|
||||
This option does not affect extraction from archives.
|
||||
|
||||
@opsummary{transform}
|
||||
@item --transform=@var{sed-expr}
|
||||
|
||||
Transform file or member names using @command{sed} replacement expression
|
||||
@var{sed-expr}. For example,
|
||||
|
||||
@smallexample
|
||||
$ @kbd{tar cf archive.tar --transform 's,^\./,usr/,' .}
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
will add to @file{archive} files from the current working directory,
|
||||
replacing initial @samp{./} prefix with @samp{usr/}. For the detailed
|
||||
discussion, @xref{transform}.
|
||||
|
||||
To see transformed member names in verbose listings, use
|
||||
@option{--show-transformed-names} option
|
||||
(@pxref{show-transformed-names}).
|
||||
|
||||
@opsummary{quote-chars}
|
||||
@item --quote-chars=@var{string}
|
||||
Always quote characters from @var{string}, even if the selected
|
||||
quoting style would not quote them (@pxref{quoting styles}).
|
||||
|
||||
@opsummary{quoting-style}
|
||||
@item --quoting-style=@var{style}
|
||||
Set quoting style to use when printing member and file names
|
||||
(@pxref{quoting styles}). Valid @var{style} values are:
|
||||
@code{literal}, @code{shell}, @code{shell-always}, @code{c},
|
||||
@code{escape}, @code{locale}, and @code{clocale}. Default quoting
|
||||
style is @code{escape}, unless overridden while configuring the
|
||||
package.
|
||||
|
||||
@opsummary{pax-option}
|
||||
@item --pax-option=@var{keyword-list}
|
||||
This option is meaningful only with @acronym{POSIX.1-2001} archives
|
||||
@@ -2963,6 +2951,20 @@ that number as the permissions to create the destination file.
|
||||
Specifying this option instructs @command{tar} that it should use the
|
||||
permissions directly from the archive. @xref{Setting Access Permissions}.
|
||||
|
||||
@opsummary{quote-chars}
|
||||
@item --quote-chars=@var{string}
|
||||
Always quote characters from @var{string}, even if the selected
|
||||
quoting style would not quote them (@pxref{quoting styles}).
|
||||
|
||||
@opsummary{quoting-style}
|
||||
@item --quoting-style=@var{style}
|
||||
Set quoting style to use when printing member and file names
|
||||
(@pxref{quoting styles}). Valid @var{style} values are:
|
||||
@code{literal}, @code{shell}, @code{shell-always}, @code{c},
|
||||
@code{escape}, @code{locale}, and @code{clocale}. Default quoting
|
||||
style is @code{escape}, unless overridden while configuring the
|
||||
package.
|
||||
|
||||
@opsummary{read-full-records}
|
||||
@item --read-full-records
|
||||
@itemx -B
|
||||
@@ -2979,7 +2981,7 @@ archive. @xref{Blocking Factor}.
|
||||
@opsummary{recursion}
|
||||
@item --recursion
|
||||
|
||||
With this option, @command{tar} recurses into directories.
|
||||
With this option, @command{tar} recurses into directories (default).
|
||||
@xref{recurse}.
|
||||
|
||||
@opsummary{recursive-unlink}
|
||||
@@ -3037,6 +3039,15 @@ effect only for ordinary users. @xref{Attributes}.
|
||||
|
||||
(See @option{--preserve-permissions}; @pxref{Setting Access Permissions}.)
|
||||
|
||||
@opsummary{seek}
|
||||
@item --seek
|
||||
@itemx -n
|
||||
|
||||
Assume that the archive media supports seeks to arbitrary
|
||||
locations. Usually @command{tar} determines automatically whether
|
||||
the archive can be seeked or not. This option is intended for use
|
||||
in cases when such recognition fails.
|
||||
|
||||
@opsummary{show-defaults}
|
||||
@item --show-defaults
|
||||
|
||||
@@ -3053,7 +3064,7 @@ $ tar --show-defaults
|
||||
@opsummary{show-omitted-dirs}
|
||||
@item --show-omitted-dirs
|
||||
|
||||
Instructs @command{tar} to mention directories its skipping over when
|
||||
Instructs @command{tar} to mention the directories it is skipping when
|
||||
operating on a @command{tar} archive. @xref{show-omitted-dirs}.
|
||||
|
||||
@opsummary{show-transformed-names}
|
||||
@@ -3063,8 +3074,8 @@ operating on a @command{tar} archive. @xref{show-omitted-dirs}.
|
||||
|
||||
Display file or member names after applying any transformations
|
||||
(@pxref{transform}). In particular, when used in conjunction with one of
|
||||
archive creation operations it instructs tar to list the member names
|
||||
stored in the archive, as opposed to the actual file
|
||||
the archive creation operations it instructs @command{tar} to list the
|
||||
member names stored in the archive, as opposed to the actual file
|
||||
names. @xref{listing member and file names}.
|
||||
|
||||
@opsummary{sparse}
|
||||
@@ -3077,7 +3088,7 @@ sparse files efficiently. @xref{sparse}.
|
||||
@opsummary{sparse-version}
|
||||
@item --sparse-version=@var{version}
|
||||
|
||||
Specified the @dfn{format version} to use when archiving sparse
|
||||
Specifies the @dfn{format version} to use when archiving sparse
|
||||
files. Implies @option{--sparse}. @xref{sparse}. For the description
|
||||
of the supported sparse formats, @xref{Sparse Formats}.
|
||||
|
||||
@@ -3092,8 +3103,7 @@ files in the archive until it finds one that matches @var{name}.
|
||||
@opsummary{strip-components}
|
||||
@item --strip-components=@var{number}
|
||||
Strip given @var{number} of leading components from file names before
|
||||
extraction.@footnote{This option was called @option{--strip-path} in
|
||||
version 1.14.} For example, if archive @file{archive.tar} contained
|
||||
extraction. For example, if archive @file{archive.tar} contained
|
||||
@file{/some/file/name}, then running
|
||||
|
||||
@smallexample
|
||||
@@ -3151,6 +3161,25 @@ Sets the data modification time of extracted files to the extraction time,
|
||||
rather than the data modification time stored in the archive.
|
||||
@xref{Data Modification Times}.
|
||||
|
||||
@opsummary{transform}
|
||||
@item --transform=@var{sed-expr}
|
||||
|
||||
Transform file or member names using @command{sed} replacement expression
|
||||
@var{sed-expr}. For example,
|
||||
|
||||
@smallexample
|
||||
$ @kbd{tar cf archive.tar --transform 's,^\./,usr/,' .}
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
will add to @file{archive} files from the current working directory,
|
||||
replacing initial @samp{./} prefix with @samp{usr/}. For the detailed
|
||||
discussion, @xref{transform}.
|
||||
|
||||
To see transformed member names in verbose listings, use
|
||||
@option{--show-transformed-names} option
|
||||
(@pxref{show-transformed-names}).
|
||||
|
||||
@opsummary{uncompress}
|
||||
@item --uncompress
|
||||
|
||||
@@ -3189,9 +3218,9 @@ Display file modification dates in @acronym{UTC}. This option implies
|
||||
@item --verbose
|
||||
@itemx -v
|
||||
|
||||
Specifies that @command{tar} should be more verbose about the operations its
|
||||
performing. This option can be specified multiple times for some
|
||||
operations to increase the amount of information displayed.
|
||||
Specifies that @command{tar} should be more verbose about the
|
||||
operations it is performing. This option can be specified multiple
|
||||
times for some operations to increase the amount of information displayed.
|
||||
@xref{verbose}.
|
||||
|
||||
@opsummary{verify}
|
||||
@@ -3212,7 +3241,7 @@ status, all on standard output, and then exit successfully.
|
||||
@item --volno-file=@var{file}
|
||||
|
||||
Used in conjunction with @option{--multi-volume}. @command{tar} will
|
||||
keep track of which volume of a multi-volume archive its working in
|
||||
keep track of which volume of a multi-volume archive it is working in
|
||||
@var{file}. @xref{volno-file}.
|
||||
|
||||
@opsummary{wildcards}
|
||||
@@ -3299,7 +3328,7 @@ them with the equivalent long option.
|
||||
@ref{--portability}.
|
||||
|
||||
The later usage is deprecated. It is retained for compatibility with
|
||||
the earlier versions of @GNUTAR{}. In the future releases
|
||||
the earlier versions of @GNUTAR{}. In future releases
|
||||
@option{-o} will be equivalent to @option{--no-same-owner} only.
|
||||
|
||||
@item -p @tab @ref{--preserve-permissions}.
|
||||
@@ -4359,7 +4388,7 @@ tar: Option --mtime: Treating date `yesterday' as 2006-06-20
|
||||
Specifies that @command{tar} should use @var{user} as the owner of members
|
||||
when creating archives, instead of the user associated with the source
|
||||
file. The argument @var{user} can be either an existing user symbolic
|
||||
name, or a decimal numeric user ID.
|
||||
name, or a decimal numeric user @acronym{ID}.
|
||||
|
||||
There is no value indicating a missing number, and @samp{0} usually means
|
||||
@code{root}. Some people like to force @samp{0} as the value to offer in
|
||||
@@ -4378,9 +4407,9 @@ $ @kbd{tar -c -f archive.tar --owner=root .}
|
||||
@item --group=@var{group}
|
||||
@opindex group
|
||||
|
||||
Files added to the @command{tar} archive will have a group id of @var{group},
|
||||
Files added to the @command{tar} archive will have a group @acronym{ID} of @var{group},
|
||||
rather than the group from the source file. The argument @var{group}
|
||||
can be either an existing group symbolic name, or a decimal numeric group ID.
|
||||
can be either an existing group symbolic name, or a decimal numeric group @acronym{ID}.
|
||||
@end table
|
||||
|
||||
@node Ignore Failed Read
|
||||
@@ -4432,7 +4461,7 @@ in conjunction with the @option{--extract} or @option{--list} operations.
|
||||
|
||||
The @option{--read-full-records} (@option{-B}) option is turned on by default when
|
||||
@command{tar} reads an archive from standard input, or from a remote
|
||||
machine. This is because on BSD Unix systems, attempting to read a
|
||||
machine. This is because on @acronym{BSD} Unix systems, attempting to read a
|
||||
pipe returns however much happens to be in the pipe, even if it is
|
||||
less than was requested. If this option were not enabled, @command{tar}
|
||||
would fail as soon as it read an incomplete record from the pipe.
|
||||
@@ -5606,7 +5635,7 @@ in a separate file. This file is usually named
|
||||
|
||||
@defvr {Backup variable} DIRLIST
|
||||
|
||||
A path to the file containing the list of the file systems to backup
|
||||
The name of the file that contains a list of file systems to backup
|
||||
or restore. By default it is @file{/etc/backup/dirs}.
|
||||
@end defvr
|
||||
|
||||
@@ -5624,7 +5653,7 @@ in a separate file. This file is usually named
|
||||
|
||||
@defvr {Backup variable} FILELIST
|
||||
|
||||
A path to the file containing the list of the individual files to backup
|
||||
The name of the file that contains a list of individual files to backup
|
||||
or restore. By default it is @file{/etc/backup/files}.
|
||||
@end defvr
|
||||
|
||||
@@ -5775,7 +5804,7 @@ Current backup or restore level.
|
||||
Name or IP address of the host machine being dumped or restored.
|
||||
|
||||
@item fs
|
||||
Full path name to the file system being dumped or restored.
|
||||
Full file name of the file system being dumped or restored.
|
||||
|
||||
@item fsname
|
||||
File system name with directory separators replaced with colons. This
|
||||
@@ -6198,15 +6227,15 @@ table:
|
||||
|
||||
@multitable @columnfractions 0.20 0.60
|
||||
@headitem Escape @tab Replaced with
|
||||
@item \a @tab Audible bell (ASCII 7)
|
||||
@item \b @tab Backspace (ASCII 8)
|
||||
@item \f @tab Form feed (ASCII 12)
|
||||
@item \n @tab New line (ASCII 10)
|
||||
@item \r @tab Carriage return (ASCII 13)
|
||||
@item \t @tab Horizontal tabulation (ASCII 9)
|
||||
@item \v @tab Vertical tabulation (ASCII 11)
|
||||
@item \? @tab ASCII 127
|
||||
@item \@var{n} @tab ASCII @var{n} (@var{n} should be an octal number
|
||||
@item \a @tab Audible bell (@acronym{ASCII} 7)
|
||||
@item \b @tab Backspace (@acronym{ASCII} 8)
|
||||
@item \f @tab Form feed (@acronym{ASCII} 12)
|
||||
@item \n @tab New line (@acronym{ASCII} 10)
|
||||
@item \r @tab Carriage return (@acronym{ASCII} 13)
|
||||
@item \t @tab Horizontal tabulation (@acronym{ASCII} 9)
|
||||
@item \v @tab Vertical tabulation (@acronym{ASCII} 11)
|
||||
@item \? @tab @acronym{ASCII} 127
|
||||
@item \@var{n} @tab @acronym{ASCII} @var{n} (@var{n} should be an octal number
|
||||
of up to 3 digits)
|
||||
@end multitable
|
||||
|
||||
@@ -6470,15 +6499,9 @@ called as @w{@samp{tar -c -X foo .}} and the file @file{foo} contains a
|
||||
single line @file{*.o}, no files whose names end in @file{.o} will be
|
||||
added to the archive.
|
||||
|
||||
@table @option
|
||||
@opindex exclude-caches
|
||||
@item --exclude-caches
|
||||
Causes @command{tar} to ignore directories containing a cache directory tag.
|
||||
@end table
|
||||
|
||||
@findex exclude-caches
|
||||
When creating an archive, the @option{--exclude-caches} option causes
|
||||
@command{tar} to exclude all directories that contain a @dfn{cache
|
||||
When creating an archive, the @option{--exclude-caches} option family
|
||||
causes @command{tar} to exclude all directories that contain a @dfn{cache
|
||||
directory tag}. A cache directory tag is a short file with the
|
||||
well-known name @file{CACHEDIR.TAG} and having a standard header
|
||||
specified in @url{http://www.brynosaurus.com/cachedir/spec.html}.
|
||||
@@ -6486,36 +6509,105 @@ Various applications write cache directory tags into directories they
|
||||
use to hold regenerable, non-precious data, so that such data can be
|
||||
more easily excluded from backups.
|
||||
|
||||
There are three @samp{exclude-caches} option, providing a different
|
||||
exclusion semantics:
|
||||
|
||||
@table @option
|
||||
@opindex exclude-caches
|
||||
@item --exclude-caches
|
||||
Do not archive the contents of the directory, but archive the
|
||||
directory itself and the @file{CACHEDIR.TAG} file.
|
||||
|
||||
@opindex exclude-caches-under
|
||||
@item --exclude-caches-under
|
||||
Do not archive the contents of the directory, nor the
|
||||
@file{CACHEDIR.TAG} file, archive only the directory itself.
|
||||
|
||||
@opindex exclude-caches-all
|
||||
@item --exclude-caches-all
|
||||
Omit directories containing @file{CACHEDIR.TAG} file entirely.
|
||||
@end table
|
||||
|
||||
@findex exclude-tag
|
||||
Another option, @option{--exclude-tag}, provides a generalization of
|
||||
Another option family, @option{--exclude-tag}, provides a generalization of
|
||||
this concept. It takes a single argument, a file name to look for.
|
||||
Any directory that contains this file will be excluded from the dump.
|
||||
Similarly to @samp{exclude-caches}, there are three options in this
|
||||
option family:
|
||||
|
||||
@table @option
|
||||
@opindex exclude-tag
|
||||
@item --exclude-tag=@var{file}
|
||||
Causes @command{tar} to ignore directories containing @var{file}.
|
||||
Multiple @option{--exclude-tag} options can be given.
|
||||
Do not dump the contents of the directory, but dump the
|
||||
directory itself and the @var{file}.
|
||||
|
||||
@opindex exclude-tag-under
|
||||
@item --exclude-tag-under=@var{file}
|
||||
Do not dump the contents of the directory, nor the
|
||||
@var{file}, archive only the directory itself.
|
||||
|
||||
@opindex exclude-tag-all
|
||||
@item --exclude-tag-all=@var{file}
|
||||
Omit directories containing @var{file} file entirely.
|
||||
@end table
|
||||
|
||||
For example:
|
||||
Multiple @option{--exclude-tag*} options can be given.
|
||||
|
||||
For example, given this directory:
|
||||
|
||||
@smallexample
|
||||
@group
|
||||
$ @kbd{find dir}
|
||||
dir
|
||||
dir/blues
|
||||
dir/jazz
|
||||
dir/folk
|
||||
dir/folk/tagfile
|
||||
$ @kbd{tar -cf archive.tar --exclude-tag=tagfile -v}
|
||||
dir/folk/sanjuan
|
||||
dir/folk/trote
|
||||
@end group
|
||||
@end smallexample
|
||||
|
||||
The @option{--exclude-tag} will produce the following:
|
||||
|
||||
@smallexample
|
||||
$ @kbd{tar -cf archive.tar --exclude-tag=tagfile -v dir}
|
||||
dir/
|
||||
dir/blues
|
||||
dir/jazz
|
||||
./tar: dir/folk/: contains a cache directory tag tagfile; not dumped
|
||||
$ @kbd{tar -tf archive.tar}
|
||||
dir/folk/
|
||||
tar: dir/folk/: contains a cache directory tag tagfile;
|
||||
contents not dumped
|
||||
dir/folk/tagfile
|
||||
@end smallexample
|
||||
|
||||
Both the @file{dir/folk} directory and its tagfile are preserved in
|
||||
the archive, however the rest of files in this directory are not.
|
||||
|
||||
Now, using the @option{--exclude-tag-under} option will exclude
|
||||
@file{tagfile} from the dump, while still preserving the directory
|
||||
itself, as shown in this example:
|
||||
|
||||
@smallexample
|
||||
$ @kbd{tar -cf archive.tar --exclude-tag-under=tagfile -v dir}
|
||||
dir/
|
||||
dir/blues
|
||||
dir/jazz
|
||||
dir/folk/
|
||||
./tar: dir/folk/: contains a cache directory tag tagfile;
|
||||
contents not dumped
|
||||
@end smallexample
|
||||
|
||||
Finally, using @option{--exclude-tag-all} omits the @file{dir/folk}
|
||||
directory entirely:
|
||||
|
||||
@smallexample
|
||||
$ @kbd{tar -cf archive.tar --exclude-tag-all=tagfile -v dir}
|
||||
dir/
|
||||
dir/blues
|
||||
dir/jazz
|
||||
./tar: dir/folk/: contains a cache directory tag tagfile;
|
||||
directory not dumped
|
||||
@end smallexample
|
||||
|
||||
@menu
|
||||
@@ -6531,8 +6623,8 @@ pitfalls:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
The main operating mode of @command{tar} does not act on a path name
|
||||
explicitly listed on the command line if one of its file name
|
||||
The main operating mode of @command{tar} does not act on a file name
|
||||
explicitly listed on the command line, if one of its file name
|
||||
components is excluded. In the example above, if
|
||||
you create an archive and exclude files that end with @samp{*.o}, but
|
||||
explicitly name the file @samp{dir.o/foo} after all the options have been
|
||||
@@ -6794,7 +6886,7 @@ quoting}. The characters in question are:
|
||||
@item Non-printable control characters:
|
||||
|
||||
@multitable @columnfractions 0.20 0.10 0.60
|
||||
@headitem Character @tab ASCII @tab Character name
|
||||
@headitem Character @tab @acronym{ASCII} @tab Character name
|
||||
@item \a @tab 7 @tab Audible bell
|
||||
@item \b @tab 8 @tab Backspace
|
||||
@item \f @tab 12 @tab Form feed
|
||||
@@ -6804,7 +6896,7 @@ quoting}. The characters in question are:
|
||||
@item \v @tab 11 @tab Vertical tabulation
|
||||
@end multitable
|
||||
|
||||
@item Space (ASCII 32)
|
||||
@item Space (@acronym{ASCII} 32)
|
||||
|
||||
@item Single and double quotes (@samp{'} and @samp{"})
|
||||
|
||||
@@ -7691,7 +7783,7 @@ sparse file handling and incremental archives. Unfortunately these
|
||||
features were implemented in a way incompatible with other archive
|
||||
formats.
|
||||
|
||||
Archives in @samp{gnu} format are able to hold pathnames of unlimited
|
||||
Archives in @samp{gnu} format are able to hold file names of unlimited
|
||||
length.
|
||||
|
||||
@item oldgnu
|
||||
@@ -7707,7 +7799,7 @@ are:
|
||||
@item The maximum length of a symbolic link is limited to 99 characters.
|
||||
@item It is impossible to store special files (block and character
|
||||
devices, fifos etc.)
|
||||
@item Maximum value of user or group ID is limited to 2097151 (7777777
|
||||
@item Maximum value of user or group @acronym{ID} is limited to 2097151 (7777777
|
||||
octal)
|
||||
@item V7 archives do not contain symbolic ownership information (user
|
||||
and group name of the file owner).
|
||||
@@ -7715,7 +7807,7 @@ and group name of the file owner).
|
||||
|
||||
This format has traditionally been used by Automake when producing
|
||||
Makefiles. This practice will change in the future, in the meantime,
|
||||
however this means that projects containing filenames more than 99
|
||||
however this means that projects containing file names more than 99
|
||||
characters long will not be able to use @GNUTAR{} @value{VERSION} and
|
||||
Automake prior to 1.9.
|
||||
|
||||
@@ -7726,7 +7818,7 @@ special files. However, it imposes several restrictions as well:
|
||||
|
||||
@enumerate
|
||||
@item The maximum length of a file name is limited to 256 characters,
|
||||
provided that the filename can be split at directory separator in
|
||||
provided that the file name can be split at a directory separator in
|
||||
two parts, first of them being at most 155 bytes long. So, in most
|
||||
cases the maximum file name length will be shorter than 256
|
||||
characters.
|
||||
@@ -7746,7 +7838,7 @@ currently does not produce them.
|
||||
@item posix
|
||||
Archive format defined by @acronym{POSIX.1-2001} specification. This is the
|
||||
most flexible and feature-rich format. It does not impose any
|
||||
restrictions on file sizes or filename lengths. This format is quite
|
||||
restrictions on file sizes or file name lengths. This format is quite
|
||||
recent, so not all tar implementations are able to handle it properly.
|
||||
However, this format is designed in such a way that any tar
|
||||
implementation able to read @samp{ustar} archives will be able to read
|
||||
@@ -7763,7 +7855,7 @@ The following table summarizes the limitations of each of these
|
||||
formats:
|
||||
|
||||
@multitable @columnfractions .10 .20 .20 .20 .20
|
||||
@headitem Format @tab UID @tab File Size @tab Path Name @tab Devn
|
||||
@headitem Format @tab UID @tab File Size @tab File Name @tab Devn
|
||||
@item gnu @tab 1.8e19 @tab Unlimited @tab Unlimited @tab 63
|
||||
@item oldgnu @tab 1.8e19 @tab Unlimited @tab Unlimited @tab 63
|
||||
@item v7 @tab 2097151 @tab 8GB @tab 99 @tab n/a
|
||||
@@ -8162,11 +8254,11 @@ makes quite difficult to correctly account users for the disk space
|
||||
they occupy. Also, the @code{suid} or @code{sgid} attributes of
|
||||
files are easily and silently lost when files are given away.
|
||||
|
||||
When writing an archive, @command{tar} writes the user id and user name
|
||||
separately. If it can't find a user name (because the user id is not
|
||||
When writing an archive, @command{tar} writes the user @acronym{ID} and user name
|
||||
separately. If it can't find a user name (because the user @acronym{ID} is not
|
||||
in @file{/etc/passwd}), then it does not write one. When restoring,
|
||||
it tries to look the name (if one was written) up in
|
||||
@file{/etc/passwd}. If it fails, then it uses the user id stored in
|
||||
@file{/etc/passwd}. If it fails, then it uses the user @acronym{ID} stored in
|
||||
the archive instead.
|
||||
|
||||
@opindex no-same-owner
|
||||
@@ -8279,7 +8371,7 @@ archives and archive labels) in GNU and PAX formats.}
|
||||
@subsection Portable Names
|
||||
|
||||
Use portable file and member names. A name is portable if it contains
|
||||
only ASCII letters and digits, @samp{/}, @samp{.}, @samp{_}, and
|
||||
only @acronym{ASCII} letters and digits, @samp{/}, @samp{.}, @samp{_}, and
|
||||
@samp{-}; it cannot be empty, start with @samp{-} or @samp{//}, or
|
||||
contain @samp{/-}. Avoid deep directory nesting. For portability to
|
||||
old Unix hosts, limit your file name components to 14 characters or
|
||||
@@ -8381,7 +8473,7 @@ incompatible with the current @acronym{POSIX} specification, and with
|
||||
@command{tar} programs that follow it.
|
||||
|
||||
In the majority of cases, @command{tar} will be configured to create
|
||||
this format by default. This will change in the future releases, since
|
||||
this format by default. This will change in future releases, since
|
||||
we plan to make @samp{POSIX} format the default.
|
||||
|
||||
To force creation a @GNUTAR{} archive, use option
|
||||
@@ -8428,7 +8520,7 @@ When used in extract or list mode, this option instructs tar
|
||||
to ignore any keywords matching the given @var{pattern} in the extended
|
||||
header records. In both cases, matching is performed using the pattern
|
||||
matching notation described in @acronym{POSIX 1003.2}, 3.13
|
||||
(@pxref{wildcards}). For example:
|
||||
(@pxref{wildcards}). For example:
|
||||
|
||||
@smallexample
|
||||
--pax-option delete=security.*
|
||||
@@ -8445,10 +8537,11 @@ from @var{string} after making the following substitutions:
|
||||
@multitable @columnfractions .25 .55
|
||||
@headitem Meta-character @tab Replaced By
|
||||
@item %d @tab The directory name of the file, equivalent to the
|
||||
result of the @command{dirname} utility on the translated pathname.
|
||||
@item %f @tab The filename of the file, equivalent to the result
|
||||
of the @command{basename} utility on the translated pathname.
|
||||
@item %p @tab The process ID of the @command{tar} process.
|
||||
result of the @command{dirname} utility on the translated file name.
|
||||
@item %f @tab The name of the file with the directory information
|
||||
stripped, equivalent to the result of the @command{basename} utility
|
||||
on the translated file name.
|
||||
@item %p @tab The process @acronym{ID} of the @command{tar} process.
|
||||
@item %% @tab A @samp{%} character.
|
||||
@end multitable
|
||||
|
||||
@@ -8473,7 +8566,7 @@ the following substitutions:
|
||||
@item %n @tab An integer that represents the
|
||||
sequence number of the global extended header record in the archive,
|
||||
starting at 1.
|
||||
@item %p @tab The process ID of the @command{tar} process.
|
||||
@item %p @tab The process @acronym{ID} of the @command{tar} process.
|
||||
@item %% @tab A @samp{%} character.
|
||||
@end multitable
|
||||
|
||||
@@ -8524,7 +8617,7 @@ stored in the archive.
|
||||
@subsection Checksumming Problems
|
||||
|
||||
SunOS and HP-UX @command{tar} fail to accept archives created using
|
||||
@GNUTAR{} and containing non-ASCII file names, that
|
||||
@GNUTAR{} and containing non-@acronym{ASCII} file names, that
|
||||
is, file names having characters with the eight bit set, because they
|
||||
use signed checksums, while @GNUTAR{} uses unsigned
|
||||
checksums while creating archives, as per @acronym{POSIX} standards. On
|
||||
@@ -8579,7 +8672,7 @@ choose, bear in mind that the @acronym{GNU} format uses
|
||||
two's-complement base-256 notation to store values that do not fit
|
||||
into standard @acronym{ustar} range. Such archives can generally be
|
||||
read only by a @GNUTAR{} implementation. Moreover, they sometimes
|
||||
cannot be correctly restored on another hosts even by @GNUTAR{}. For
|
||||
cannot be correctly restored on another hosts even by @GNUTAR{}. For
|
||||
example, using two's complement representation for negative time
|
||||
stamps that assumes a signed 32-bit @code{time_t} generates archives
|
||||
that are not portable to hosts with differing @code{time_t}
|
||||
@@ -8656,14 +8749,14 @@ have the following meaning:
|
||||
result of the @command{dirname} utility on its full name.
|
||||
@item %f @tab The file name of the file, equivalent to the result
|
||||
of the @command{basename} utility on its full name.
|
||||
@item %p @tab The process ID of the @command{tar} process that
|
||||
@item %p @tab The process @acronym{ID} of the @command{tar} process that
|
||||
created the archive.
|
||||
@item %n @tab Ordinal number of this particular part.
|
||||
@end multitable
|
||||
|
||||
For example, if the file @file{var/longfile} was split during archive
|
||||
creation between three volumes, and the creator @command{tar} process
|
||||
had process ID @samp{27962}, then the member names will be:
|
||||
had process @acronym{ID} @samp{27962}, then the member names will be:
|
||||
|
||||
@smallexample
|
||||
var/longfile
|
||||
@@ -8729,7 +8822,7 @@ members. Read further to learn more about them.
|
||||
Any @command{tar} implementation will be able to extract sparse members from a
|
||||
PAX archive. However, the extracted files will be @dfn{condensed},
|
||||
i.e., any zero blocks will be removed from them. When we restore such
|
||||
a condensed file to its original form, by adding zero bloks (or
|
||||
a condensed file to its original form, by adding zero blocks (or
|
||||
@dfn{holes}) back to their original locations, we call this process
|
||||
@dfn{expanding} a compressed sparse file.
|
||||
|
||||
@@ -8747,7 +8840,7 @@ additional data will be needed to restore it. If the original file
|
||||
name was @file{@var{dir}/@var{name}}, then the condensed file will be
|
||||
named @file{@var{dir}/@/GNUSparseFile.@var{n}/@/@var{name}}, where
|
||||
@var{n} is a decimal number@footnote{technically speaking, @var{n} is a
|
||||
@dfn{process ID} of the @command{tar} process which created the
|
||||
@dfn{process @acronym{ID}} of the @command{tar} process which created the
|
||||
archive (@pxref{PAX keywords}).}.
|
||||
|
||||
To expand a version 1.0 file, run @command{xsparse} as follows:
|
||||
@@ -8775,7 +8868,7 @@ name will be @file{@var{dir}/@var{name}}.
|
||||
@file{@var{name}}.
|
||||
@end enumerate
|
||||
|
||||
In the unlikely case when this algorithm does not suite your needs,
|
||||
In the unlikely case when this algorithm does not suit your needs,
|
||||
you can explicitly specify output file name as a second argument to
|
||||
the command:
|
||||
|
||||
@@ -8849,10 +8942,10 @@ An @dfn{extended header} is a special @command{tar} archive header
|
||||
that precedes an archive member and contains a set of
|
||||
@dfn{variables}, describing the member properties that cannot be
|
||||
stored in the standard @code{ustar} header. While optional for
|
||||
expanding sparse version 1.0 members, use of extended headers is
|
||||
expanding sparse version 1.0 members, the use of extended headers is
|
||||
mandatory when expanding sparse members in older sparse formats: v.0.0
|
||||
and v.0.1 (The sparse formats are described in detail in @ref{Sparse
|
||||
Formats}.) So, for this format, the question is: how to obtain
|
||||
Formats}.) So, for these formats, the question is: how to obtain
|
||||
extended headers from the archive?
|
||||
|
||||
If you use a @command{tar} implementation that does not support PAX
|
||||
@@ -8951,20 +9044,20 @@ Done
|
||||
@FIXME{Reorganize the following material}
|
||||
|
||||
The @command{cpio} archive formats, like @command{tar}, do have maximum
|
||||
pathname lengths. The binary and old ASCII formats have a max path
|
||||
length of 256, and the new ASCII and CRC ASCII formats have a max
|
||||
path length of 1024. @acronym{GNU} @command{cpio} can read and write archives
|
||||
with arbitrary pathname lengths, but other @command{cpio} implementations
|
||||
file name lengths. The binary and old @acronym{ASCII} formats have a maximum file
|
||||
length of 256, and the new @acronym{ASCII} and @acronym{CRC ASCII} formats have a max
|
||||
file length of 1024. @acronym{GNU} @command{cpio} can read and write archives
|
||||
with arbitrary file name lengths, but other @command{cpio} implementations
|
||||
may crash unexplainedly trying to read them.
|
||||
|
||||
@command{tar} handles symbolic links in the form in which it comes in BSD;
|
||||
@command{tar} handles symbolic links in the form in which it comes in @acronym{BSD};
|
||||
@command{cpio} doesn't handle symbolic links in the form in which it comes
|
||||
in System V prior to SVR4, and some vendors may have added symlinks
|
||||
to their system without enhancing @command{cpio} to know about them.
|
||||
Others may have enhanced it in a way other than the way I did it
|
||||
at Sun, and which was adopted by AT&T (and which is, I think, also
|
||||
present in the @command{cpio} that Berkeley picked up from AT&T and put
|
||||
into a later BSD release---I think I gave them my changes).
|
||||
into a later @acronym{BSD} release---I think I gave them my changes).
|
||||
|
||||
(SVR4 does some funny stuff with @command{tar}; basically, its @command{cpio}
|
||||
can handle @command{tar} format input, and write it on output, and it
|
||||
@@ -8973,16 +9066,16 @@ anything to enhance @command{tar} as a result.)
|
||||
|
||||
@command{cpio} handles special files; traditional @command{tar} doesn't.
|
||||
|
||||
@command{tar} comes with V7, System III, System V, and BSD source;
|
||||
@command{cpio} comes only with System III, System V, and later BSD
|
||||
@command{tar} comes with V7, System III, System V, and @acronym{BSD} source;
|
||||
@command{cpio} comes only with System III, System V, and later @acronym{BSD}
|
||||
(4.3-tahoe and later).
|
||||
|
||||
@command{tar}'s way of handling multiple hard links to a file can handle
|
||||
file systems that support 32-bit inumbers (e.g., the BSD file system);
|
||||
@command{cpio}s way requires you to play some games (in its "binary"
|
||||
format, i-numbers are only 16 bits, and in its "portable ASCII" format,
|
||||
they're 18 bits---it would have to play games with the "file system ID"
|
||||
field of the header to make sure that the file system ID/i-number pairs
|
||||
file systems that support 32-bit inumbers (e.g., the @acronym{BSD} file system);
|
||||
@command{cpio}s way requires you to play some games (in its ``binary''
|
||||
format, i-numbers are only 16 bits, and in its ``portable @acronym{ASCII}'' format,
|
||||
they're 18 bits---it would have to play games with the "file system @acronym{ID}"
|
||||
field of the header to make sure that the file system @acronym{ID}/i-number pairs
|
||||
of different files were always different), and I don't know which
|
||||
@command{cpio}s, if any, play those games. Those that don't might get
|
||||
confused and think two files are the same file when they're not, and
|
||||
@@ -9283,7 +9376,7 @@ that can be backspaced with the @code{MTIOCTOP} @code{ioctl}.
|
||||
This means that the @option{--append}, @option{--concatenate}, and
|
||||
@option{--delete} commands will not work on any other kind of file.
|
||||
Some media simply cannot be backspaced, which means these commands and
|
||||
options will never be able to work on them. These non-backspacing
|
||||
options will never be able to work on them. These non-backspacing
|
||||
media include pipes and cartridge tape drives.
|
||||
|
||||
Some other media can be backspaced, and @command{tar} will work on them
|
||||
@@ -9661,17 +9754,17 @@ are stored on a single physical tape.
|
||||
@xopindex{read-full-records, short description}
|
||||
@item -B
|
||||
@itemx --read-full-records
|
||||
Reblock as we read (for reading 4.2BSD pipes).
|
||||
Reblock as we read (for reading 4.2@acronym{BSD} pipes).
|
||||
|
||||
If @option{--read-full-records} is used, @command{tar}
|
||||
will not panic if an attempt to read a record from the archive does
|
||||
not return a full record. Instead, @command{tar} will keep reading
|
||||
not return a full record. Instead, @command{tar} will keep reading
|
||||
until it has obtained a full
|
||||
record.
|
||||
|
||||
This option is turned on by default when @command{tar} is reading
|
||||
an archive from standard input, or from a remote machine. This is
|
||||
because on BSD Unix systems, a read of a pipe will return however
|
||||
because on @acronym{BSD} Unix systems, a read of a pipe will return however
|
||||
much happens to be in the pipe, even if it is less than @command{tar}
|
||||
requested. If this option was not used, @command{tar} would fail as
|
||||
soon as it read an incomplete record from the pipe.
|
||||
@@ -10123,10 +10216,15 @@ Short option describing the operation @command{tar} is executing
|
||||
@item TAR_FORMAT
|
||||
Format of the archive being processed. @xref{Formats}, for a complete
|
||||
list of archive format names.
|
||||
|
||||
@vrindex TAR_FD, info script environment variable
|
||||
@item TAR_FD
|
||||
File descriptor which can be used to communicate the new volume
|
||||
name to @command{tar}.
|
||||
@end table
|
||||
|
||||
The volume script can instruct @command{tar} to use new archive name,
|
||||
by writing in to file descriptor 3 (see below for an example).
|
||||
by writing in to file descriptor @env{$TAR_FD} (see below for an example).
|
||||
|
||||
If the info script fails, @command{tar} exits; otherwise, it begins
|
||||
writing the next volume.
|
||||
@@ -10151,7 +10249,7 @@ The second method is to use the @samp{n} response to the tape-change
|
||||
prompt.
|
||||
|
||||
Finally, the most flexible approach is to use a volume script, that
|
||||
writes new archive name to the file descriptor #3. For example, the
|
||||
writes new archive name to the file descriptor @env{$TAR_FD}. For example, the
|
||||
following volume script will create a series of archive files, named
|
||||
@file{@var{archive}-@var{vol}}, where @var{archive} is the name of the
|
||||
archive being created (as given by @option{--file} option) and
|
||||
@@ -10170,7 +10268,7 @@ case $TAR_SUBCOMMAND in
|
||||
*) exit 1
|
||||
esac
|
||||
|
||||
echo $@{name:-$TAR_ARCHIVE@}-$TAR_VOLUME >&3
|
||||
echo $@{name:-$TAR_ARCHIVE@}-$TAR_VOLUME >&$TAR_FD
|
||||
@end group
|
||||
@end smallexample
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ stdbool
|
||||
stdint
|
||||
stpcpy
|
||||
strdup
|
||||
strerror
|
||||
strtol
|
||||
strtoul
|
||||
timespec
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
.deps
|
||||
.cvsignore
|
||||
Makefile
|
||||
Makefile.in
|
||||
__fpending.c
|
||||
__fpending.h
|
||||
alloca.c
|
||||
alloca.h
|
||||
alloca_.h
|
||||
allocsa.c
|
||||
allocsa.h
|
||||
@@ -29,7 +28,6 @@ at-func.c
|
||||
backupfile.c
|
||||
backupfile.h
|
||||
basename.c
|
||||
charset.alias
|
||||
chdir-long.c
|
||||
chdir-long.h
|
||||
chown.c
|
||||
@@ -38,8 +36,9 @@ close-stream.h
|
||||
closeout.c
|
||||
closeout.h
|
||||
config.charset
|
||||
configmake.h
|
||||
creat-safer.c
|
||||
dirfd.c
|
||||
dirfd.h
|
||||
dirname.c
|
||||
dirname.h
|
||||
dup-safer.c
|
||||
@@ -47,19 +46,17 @@ error.c
|
||||
error.h
|
||||
exclude.c
|
||||
exclude.h
|
||||
exit.h
|
||||
exitfail.c
|
||||
exitfail.h
|
||||
fchmodat.c
|
||||
fchown-stub.c
|
||||
fchownat.c
|
||||
fcntl--.h
|
||||
fcntl-safer.h
|
||||
fcntl.h
|
||||
fcntl_.h
|
||||
fd-safer.c
|
||||
fileblocks.c
|
||||
fnmatch.c
|
||||
fnmatch.h
|
||||
fnmatch_.h
|
||||
fnmatch_loop.c
|
||||
fstatat.c
|
||||
@@ -67,8 +64,6 @@ ftruncate.c
|
||||
full-write.c
|
||||
full-write.h
|
||||
getcwd.c
|
||||
getcwd.h
|
||||
getdate.c
|
||||
getdate.h
|
||||
getdate.y
|
||||
getdelim.c
|
||||
@@ -76,7 +71,6 @@ getdelim.h
|
||||
getline.c
|
||||
getline.h
|
||||
getopt.c
|
||||
getopt.h
|
||||
getopt1.c
|
||||
getopt_.h
|
||||
getopt_int.h
|
||||
@@ -93,29 +87,24 @@ imaxtostr.c
|
||||
intprops.h
|
||||
inttostr.c
|
||||
inttostr.h
|
||||
inttypes.h
|
||||
inttypes_.h
|
||||
lchown.c
|
||||
lchown.h
|
||||
localcharset.c
|
||||
localcharset.h
|
||||
localedir.h
|
||||
lstat.c
|
||||
lstat.h
|
||||
malloc.c
|
||||
mbchar.c
|
||||
mbchar.h
|
||||
mbscasecmp.c
|
||||
mbuiter.h
|
||||
memchr.c
|
||||
mempcpy.c
|
||||
mempcpy.h
|
||||
memrchr.c
|
||||
memrchr.h
|
||||
memset.c
|
||||
minmax.h
|
||||
mkdirat.c
|
||||
mkdtemp.c
|
||||
mkdtemp.h
|
||||
mktime.c
|
||||
modechange.c
|
||||
modechange.h
|
||||
@@ -140,9 +129,7 @@ quote.c
|
||||
quote.h
|
||||
quotearg.c
|
||||
quotearg.h
|
||||
ref-add.sed
|
||||
ref-add.sin
|
||||
ref-del.sed
|
||||
ref-del.sin
|
||||
regcomp.c
|
||||
regex.c
|
||||
@@ -165,28 +152,23 @@ savedir.c
|
||||
savedir.h
|
||||
setenv.c
|
||||
setenv.h
|
||||
size_max.h
|
||||
sleep.c
|
||||
stat-macros.h
|
||||
stat-time.h
|
||||
stat_.h
|
||||
stdbool.h
|
||||
stdbool_.h
|
||||
stdint.h
|
||||
stdint_.h
|
||||
stdio_.h
|
||||
stdlib_.h
|
||||
stpcpy.c
|
||||
stpcpy.h
|
||||
strcase.h
|
||||
strcasecmp.c
|
||||
strchrnul.c
|
||||
strchrnul.h
|
||||
strdup.c
|
||||
strdup.h
|
||||
strerror.c
|
||||
string_.h
|
||||
stripslash.c
|
||||
strncasecmp.c
|
||||
strndup.c
|
||||
strndup.h
|
||||
strnlen.c
|
||||
strnlen.h
|
||||
strnlen1.c
|
||||
strnlen1.h
|
||||
strtoimax.c
|
||||
@@ -195,19 +177,21 @@ strtoll.c
|
||||
strtoul.c
|
||||
strtoull.c
|
||||
strtoumax.c
|
||||
sysexit_.h
|
||||
sysexits.h
|
||||
sys_stat_.h
|
||||
sys_time_.h
|
||||
sysexits_.h
|
||||
system-ioctl.h
|
||||
system.h
|
||||
tempname.c
|
||||
tempname.h
|
||||
time_.h
|
||||
time_r.c
|
||||
time_r.h
|
||||
timespec.h
|
||||
uinttostr.c
|
||||
umaxtostr.c
|
||||
unistd--.h
|
||||
unistd-safer.h
|
||||
unistd_.h
|
||||
unlinkdir.c
|
||||
unlinkdir.h
|
||||
unlocked-io.h
|
||||
@@ -221,14 +205,14 @@ version-etc-fsf.c
|
||||
version-etc.c
|
||||
version-etc.h
|
||||
vsnprintf.c
|
||||
vsnprintf.h
|
||||
wchar_.h
|
||||
wctype_.h
|
||||
wcwidth.h
|
||||
xalloc-die.c
|
||||
xalloc.h
|
||||
xgetcwd.c
|
||||
xgetcwd.h
|
||||
xmalloc.c
|
||||
xsize.h
|
||||
xstrndup.c
|
||||
xstrndup.h
|
||||
xstrtol.c
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* xsparse - expands compressed sparse file images extracted from GNU tar
|
||||
archives.
|
||||
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
Written by Sergey Poznyakoff
|
||||
|
||||
@@ -302,15 +302,20 @@ expand_sparse (FILE *sfp, int ofd)
|
||||
{
|
||||
size_t size = sparse_map[i].numbytes;
|
||||
|
||||
lseek (ofd, sparse_map[i].offset, SEEK_SET);
|
||||
while (size)
|
||||
if (size == 0)
|
||||
ftruncate (ofd, sparse_map[i].offset);
|
||||
else
|
||||
{
|
||||
size_t rdsize = (size < maxbytes) ? size : maxbytes;
|
||||
if (rdsize != fread (buffer, 1, rdsize, sfp))
|
||||
die (1, "read error (%d)", errno);
|
||||
if (rdsize != write (ofd, buffer, rdsize))
|
||||
die (1, "write error (%d)", errno);
|
||||
size -= rdsize;
|
||||
lseek (ofd, sparse_map[i].offset, SEEK_SET);
|
||||
while (size)
|
||||
{
|
||||
size_t rdsize = (size < maxbytes) ? size : maxbytes;
|
||||
if (rdsize != fread (buffer, 1, rdsize, sfp))
|
||||
die (1, "read error (%d)", errno);
|
||||
if (rdsize != write (ofd, buffer, rdsize))
|
||||
die (1, "write error (%d)", errno);
|
||||
size -= rdsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
free (buffer);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
Makefile.in
|
||||
Makefile
|
||||
localedir.h
|
||||
rmt
|
||||
tar
|
||||
.deps
|
||||
.gdbinit
|
||||
Makefile
|
||||
Makefile.in
|
||||
rmt
|
||||
tar
|
||||
|
||||
24
src/buffer.c
24
src/buffer.c
@@ -121,6 +121,15 @@ static off_t save_totsize; /* total size of file we are writing, only
|
||||
static off_t save_sizeleft; /* where we are in the file we are writing,
|
||||
only valid if save_name is nonzero */
|
||||
|
||||
|
||||
static struct tar_stat_info dummy;
|
||||
|
||||
void
|
||||
buffer_write_global_xheader ()
|
||||
{
|
||||
xheader_write_global (&dummy.xhdr);
|
||||
}
|
||||
|
||||
void
|
||||
mv_begin (struct tar_stat_info *st)
|
||||
{
|
||||
@@ -1123,7 +1132,6 @@ try_new_volume ()
|
||||
{
|
||||
size_t status;
|
||||
union block *header;
|
||||
struct tar_stat_info dummy;
|
||||
int access;
|
||||
|
||||
switch (subcommand_option)
|
||||
@@ -1295,7 +1303,7 @@ static void
|
||||
_write_volume_label (const char *str)
|
||||
{
|
||||
if (archive_format == POSIX_FORMAT)
|
||||
xheader_store ("GNU.volume.label", NULL, str);
|
||||
xheader_store ("GNU.volume.label", &dummy, str);
|
||||
else
|
||||
{
|
||||
union block *label = find_next_block ();
|
||||
@@ -1412,9 +1420,9 @@ add_multi_volume_header (void)
|
||||
if (archive_format == POSIX_FORMAT)
|
||||
{
|
||||
off_t d = real_s_totsize - real_s_sizeleft;
|
||||
xheader_store ("GNU.volume.filename", NULL, real_s_name);
|
||||
xheader_store ("GNU.volume.size", NULL, &real_s_sizeleft);
|
||||
xheader_store ("GNU.volume.offset", NULL, &d);
|
||||
xheader_store ("GNU.volume.filename", &dummy, real_s_name);
|
||||
xheader_store ("GNU.volume.size", &dummy, &real_s_sizeleft);
|
||||
xheader_store ("GNU.volume.offset", &dummy, &d);
|
||||
}
|
||||
else
|
||||
gnu_add_multi_volume_header ();
|
||||
@@ -1601,7 +1609,7 @@ _gnu_flush_write (size_t buffer_level)
|
||||
if (!new_volume (ACCESS_WRITE))
|
||||
return;
|
||||
|
||||
xheader_destroy (&extended_header);
|
||||
tar_stat_destroy (&dummy);
|
||||
|
||||
increase_volume_number ();
|
||||
prev_written += bytes_written;
|
||||
@@ -1619,7 +1627,9 @@ _gnu_flush_write (size_t buffer_level)
|
||||
if (real_s_name)
|
||||
add_multi_volume_header ();
|
||||
|
||||
write_extended (true, NULL, find_next_block ());
|
||||
write_extended (true, &dummy, find_next_block ());
|
||||
tar_stat_destroy (&dummy);
|
||||
|
||||
if (real_s_name)
|
||||
add_chunk_header ();
|
||||
header = find_next_block ();
|
||||
|
||||
57
src/common.h
57
src/common.h
@@ -1,7 +1,7 @@
|
||||
/* Common declarations for the tar program.
|
||||
|
||||
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
||||
2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
@@ -150,8 +150,18 @@ GLOBAL int check_links_option;
|
||||
/* Patterns that match file names to be excluded. */
|
||||
GLOBAL struct exclude *excluded;
|
||||
|
||||
/* Exclude directories containing a cache directory tag. */
|
||||
GLOBAL bool exclude_caches_option;
|
||||
enum exclusion_tag_type
|
||||
{
|
||||
exclusion_tag_none,
|
||||
/* Exclude the directory contents, but preserve the directory
|
||||
itself and the exclusion tag file */
|
||||
exclusion_tag_contents,
|
||||
/* Exclude everything below the directory, preserving the directory
|
||||
itself */
|
||||
exclusion_tag_under,
|
||||
/* Exclude entire directory */
|
||||
exclusion_tag_all,
|
||||
};
|
||||
|
||||
/* Specified value to be put into tar file in place of stat () results, or
|
||||
just -1 if such an override should not take place. */
|
||||
@@ -406,6 +416,7 @@ void mv_end (void);
|
||||
void mv_total_size (off_t size);
|
||||
void mv_size_left (off_t size);
|
||||
|
||||
void buffer_write_global_xheader (void);
|
||||
|
||||
/* Module create.c. */
|
||||
|
||||
@@ -417,6 +428,10 @@ enum dump_status
|
||||
dump_status_not_implemented
|
||||
};
|
||||
|
||||
void add_exclusion_tag (const char *name, enum exclusion_tag_type type,
|
||||
bool (*)(const char*));
|
||||
bool cachedir_file_p (const char *name);
|
||||
|
||||
bool file_dumpable_p (struct tar_stat_info *st);
|
||||
void create_archive (void);
|
||||
void pad_archive (off_t size_left);
|
||||
@@ -498,14 +513,6 @@ enum read_header
|
||||
HEADER_FAILURE /* ill-formed header, or bad checksum */
|
||||
};
|
||||
|
||||
struct xheader
|
||||
{
|
||||
struct obstack *stk;
|
||||
size_t size;
|
||||
char *buffer;
|
||||
};
|
||||
|
||||
GLOBAL struct xheader extended_header;
|
||||
extern union block *current_header;
|
||||
extern enum archive_format current_format;
|
||||
extern size_t recent_long_name_blocks;
|
||||
@@ -578,7 +585,6 @@ void undo_last_backup (void);
|
||||
|
||||
int deref_stat (bool deref, char const *name, struct stat *buf);
|
||||
|
||||
void closeopen (void);
|
||||
int chdir_arg (char const *dir);
|
||||
void chdir_do (int dir);
|
||||
|
||||
@@ -662,23 +668,22 @@ void update_archive (void);
|
||||
|
||||
/* Module xheader.c. */
|
||||
|
||||
void xheader_init (struct xheader *xhdr);
|
||||
void xheader_decode (struct tar_stat_info *stat);
|
||||
void xheader_decode_global (void);
|
||||
void xheader_store (char const *keyword, struct tar_stat_info const *st,
|
||||
void xheader_decode_global (struct xheader *xhdr);
|
||||
void xheader_store (char const *keyword, struct tar_stat_info *st,
|
||||
void const *data);
|
||||
void xheader_read (union block *header, size_t size);
|
||||
void xheader_read (struct xheader *xhdr, union block *header, size_t size);
|
||||
void xheader_write (char type, char *name, struct xheader *xhdr);
|
||||
void xheader_write_global (void);
|
||||
void xheader_write_global (struct xheader *xhdr);
|
||||
void xheader_finish (struct xheader *hdr);
|
||||
void xheader_destroy (struct xheader *hdr);
|
||||
char *xheader_xhdr_name (struct tar_stat_info *st);
|
||||
char *xheader_ghdr_name (void);
|
||||
void xheader_write (char type, char *name, struct xheader *xhdr);
|
||||
void xheader_write_global (void);
|
||||
void xheader_set_option (char *string);
|
||||
void xheader_string_begin (void);
|
||||
void xheader_string_add (char const *s);
|
||||
bool xheader_string_end (char const *keyword);
|
||||
void xheader_string_begin (struct xheader *xhdr);
|
||||
void xheader_string_add (struct xheader *xhdr, char const *s);
|
||||
bool xheader_string_end (struct xheader *xhdr, char const *keyword);
|
||||
bool xheader_keyword_deleted_p (const char *kw);
|
||||
char *xheader_format_name (struct tar_stat_info *st, const char *fmt,
|
||||
size_t n);
|
||||
@@ -720,6 +725,14 @@ bool string_ascii_p (const char *str);
|
||||
bool utf8_convert (bool to_utf, char const *input, char **output);
|
||||
|
||||
/* Module transform.c */
|
||||
typedef enum
|
||||
{
|
||||
xform_regfile,
|
||||
xform_link,
|
||||
xform_symlink
|
||||
} xform_type;
|
||||
|
||||
void set_transform_expr (const char *expr);
|
||||
bool transform_name (char **pinput);
|
||||
bool transform_name_fp (char **pinput, char *(*fun)(char *));
|
||||
bool transform_member_name (char **pinput, xform_type type);
|
||||
bool transform_name_fp (char **pinput, char *(*fun)(char *, void *), void *);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Diff files from a tar archive.
|
||||
|
||||
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
||||
2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
Written by John Gilmore, on 1987-04-30.
|
||||
|
||||
@@ -110,27 +110,10 @@ process_rawdata (size_t bytes, char *buffer)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Directory contents, only for GNUTYPE_DUMPDIR. */
|
||||
|
||||
static char *dumpdir_cursor;
|
||||
|
||||
static int
|
||||
process_dumpdir (size_t bytes, char *buffer)
|
||||
{
|
||||
if (memcmp (buffer, dumpdir_cursor, bytes))
|
||||
{
|
||||
report_difference (¤t_stat_info, _("Contents differ"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
dumpdir_cursor += bytes;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Some other routine wants SIZE bytes in the archive. For each chunk
|
||||
of the archive, call PROCESSOR with the size of the chunk, and the
|
||||
address of the chunk it can work with. The PROCESSOR should return
|
||||
nonzero for success. It it return error once, continue skipping
|
||||
nonzero for success. Once it returns error, continue skipping
|
||||
without calling PROCESSOR anymore. */
|
||||
|
||||
static void
|
||||
@@ -138,7 +121,7 @@ read_and_process (struct tar_stat_info *st, int (*processor) (size_t, char *))
|
||||
{
|
||||
union block *data_block;
|
||||
size_t data_size;
|
||||
size_t size = st->stat.st_size;
|
||||
off_t size = st->stat.st_size;
|
||||
|
||||
mv_begin (st);
|
||||
while (size)
|
||||
@@ -345,6 +328,41 @@ diff_special (void)
|
||||
report_difference (¤t_stat_info, _("Mode differs"));
|
||||
}
|
||||
|
||||
static int
|
||||
dumpdir_cmp (const char *a, const char *b)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
while (*a)
|
||||
switch (*a)
|
||||
{
|
||||
case 'Y':
|
||||
case 'N':
|
||||
if (!strchr ("YN", *b))
|
||||
return 1;
|
||||
if (strcmp(a + 1, b + 1))
|
||||
return 1;
|
||||
len = strlen (a) + 1;
|
||||
a += len;
|
||||
b += len;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
if (strcmp(a, b))
|
||||
return 1;
|
||||
len = strlen (a) + 1;
|
||||
a += len;
|
||||
b += len;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
case 'T':
|
||||
case 'X':
|
||||
return *b;
|
||||
}
|
||||
return *b;
|
||||
}
|
||||
|
||||
static void
|
||||
diff_dumpdir (void)
|
||||
{
|
||||
@@ -366,9 +384,8 @@ diff_dumpdir (void)
|
||||
|
||||
if (dumpdir_buffer)
|
||||
{
|
||||
dumpdir_cursor = dumpdir_buffer;
|
||||
read_and_process (¤t_stat_info, process_dumpdir);
|
||||
free (dumpdir_buffer);
|
||||
if (dumpdir_cmp (current_stat_info.dumpdir, dumpdir_buffer))
|
||||
report_difference (¤t_stat_info, _("Contents differ"));
|
||||
}
|
||||
else
|
||||
read_and_process (¤t_stat_info, process_noop);
|
||||
@@ -484,10 +501,9 @@ diff_archive (void)
|
||||
break;
|
||||
|
||||
case GNUTYPE_DUMPDIR:
|
||||
diff_dumpdir ();
|
||||
/* Fall through. */
|
||||
|
||||
case DIRTYPE:
|
||||
if (is_dumpdir (¤t_stat_info))
|
||||
diff_dumpdir ();
|
||||
diff_dir ();
|
||||
break;
|
||||
|
||||
@@ -586,7 +602,6 @@ verify_volume (void)
|
||||
|
||||
diff_archive ();
|
||||
tar_stat_destroy (¤t_stat_info);
|
||||
xheader_destroy (&extended_header);
|
||||
}
|
||||
|
||||
access_mode = ACCESS_WRITE;
|
||||
|
||||
231
src/create.c
231
src/create.c
@@ -1,7 +1,7 @@
|
||||
/* Create a tar archive.
|
||||
|
||||
Copyright (C) 1985, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
||||
2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
Written by John Gilmore, on 1985-08-25.
|
||||
|
||||
@@ -34,36 +34,53 @@ struct link
|
||||
char name[1];
|
||||
};
|
||||
|
||||
struct exclude_tag
|
||||
struct exclusion_tag
|
||||
{
|
||||
const char *name;
|
||||
size_t length;
|
||||
struct exclude_tag *next;
|
||||
enum exclusion_tag_type type;
|
||||
bool (*predicate) (const char *name);
|
||||
struct exclusion_tag *next;
|
||||
};
|
||||
|
||||
static struct exclude_tag *exclude_tags;
|
||||
static struct exclusion_tag *exclusion_tags;
|
||||
|
||||
void
|
||||
add_exclude_tag (const char *name)
|
||||
add_exclusion_tag (const char *name, enum exclusion_tag_type type,
|
||||
bool (*predicate) (const char *name))
|
||||
{
|
||||
struct exclude_tag *tag = xmalloc (sizeof tag[0]);
|
||||
tag->next = exclude_tags;
|
||||
struct exclusion_tag *tag = xmalloc (sizeof tag[0]);
|
||||
tag->next = exclusion_tags;
|
||||
tag->name = name;
|
||||
tag->type = type;
|
||||
tag->predicate = predicate;
|
||||
tag->length = strlen (name);
|
||||
exclude_tags = tag;
|
||||
exclusion_tags = tag;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_exclude_tags (char *dirname)
|
||||
static void
|
||||
exclusion_tag_warning (const char *dirname, const char *tagname,
|
||||
const char *message)
|
||||
{
|
||||
if (verbose_option)
|
||||
WARN ((0, 0,
|
||||
_("%s: contains a cache directory tag %s; %s"),
|
||||
quotearg_colon (dirname),
|
||||
quotearg_n (1, tagname),
|
||||
message));
|
||||
}
|
||||
|
||||
static enum exclusion_tag_type
|
||||
check_exclusion_tags (char *dirname, const char **tag_file_name)
|
||||
{
|
||||
static char *tagname;
|
||||
static size_t tagsize;
|
||||
struct exclude_tag *tag;
|
||||
struct exclusion_tag *tag;
|
||||
size_t dlen = strlen (dirname);
|
||||
char *nptr = NULL;
|
||||
char *ret = NULL;
|
||||
|
||||
for (tag = exclude_tags; tag; tag = tag->next)
|
||||
for (tag = exclusion_tags; tag; tag = tag->next)
|
||||
{
|
||||
size_t size = dlen + tag->length + 1;
|
||||
if (size > tagsize)
|
||||
@@ -78,18 +95,45 @@ check_exclude_tags (char *dirname)
|
||||
nptr = tagname + dlen;
|
||||
}
|
||||
strcpy (nptr, tag->name);
|
||||
if (access (tagname, F_OK) == 0)
|
||||
if (access (tagname, F_OK) == 0
|
||||
&& (!tag->predicate || tag->predicate (tagname)))
|
||||
{
|
||||
if (verbose_option)
|
||||
WARN ((0, 0,
|
||||
_("%s: contains a cache directory tag %s; not dumped"),
|
||||
quotearg_colon (dirname),
|
||||
quotearg_n (1, tag->name)));
|
||||
return true;
|
||||
if (tag_file_name)
|
||||
*tag_file_name = tag->name;
|
||||
return tag->type;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return exclusion_tag_none;
|
||||
}
|
||||
|
||||
/* Exclusion predicate to test if the named file (usually "CACHEDIR.TAG")
|
||||
contains a valid header, as described at:
|
||||
http://www.brynosaurus.com/cachedir
|
||||
Applications can write this file into directories they create
|
||||
for use as caches containing purely regenerable, non-precious data,
|
||||
allowing us to avoid archiving them if --exclude-caches is specified. */
|
||||
|
||||
#define CACHEDIR_SIGNATURE "Signature: 8a477f597d28d172789f06886806bc55"
|
||||
#define CACHEDIR_SIGNATURE_SIZE (sizeof CACHEDIR_SIGNATURE - 1)
|
||||
|
||||
bool
|
||||
cachedir_file_p (const char *name)
|
||||
{
|
||||
bool tag_present = false;
|
||||
int fd = open (name, O_RDONLY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
static char tagbuf[CACHEDIR_SIGNATURE_SIZE];
|
||||
|
||||
if (read (fd, tagbuf, CACHEDIR_SIGNATURE_SIZE)
|
||||
== CACHEDIR_SIGNATURE_SIZE
|
||||
&& memcmp (tagbuf, CACHEDIR_SIGNATURE, CACHEDIR_SIGNATURE_SIZE) == 0)
|
||||
tag_present = true;
|
||||
|
||||
close (fd);
|
||||
}
|
||||
return tag_present;
|
||||
}
|
||||
|
||||
|
||||
@@ -667,10 +711,10 @@ write_extended (bool global, struct tar_stat_info *st, union block *old_header)
|
||||
char *p;
|
||||
int type;
|
||||
|
||||
if (extended_header.buffer || extended_header.stk == NULL)
|
||||
if (st->xhdr.buffer || st->xhdr.stk == NULL)
|
||||
return old_header;
|
||||
|
||||
xheader_finish (&extended_header);
|
||||
xheader_finish (&st->xhdr);
|
||||
memcpy (hp.buffer, old_header, sizeof (hp));
|
||||
if (global)
|
||||
{
|
||||
@@ -682,7 +726,7 @@ write_extended (bool global, struct tar_stat_info *st, union block *old_header)
|
||||
type = XHDTYPE;
|
||||
p = xheader_xhdr_name (st);
|
||||
}
|
||||
xheader_write (type, p, &extended_header);
|
||||
xheader_write (type, p, &st->xhdr);
|
||||
free (p);
|
||||
header = find_next_block ();
|
||||
memcpy (header, &hp.buffer, sizeof (hp.buffer));
|
||||
@@ -1043,53 +1087,13 @@ dump_regular_file (int fd, struct tar_stat_info *st)
|
||||
}
|
||||
|
||||
|
||||
/* Look in directory DIRNAME for a cache directory tag file
|
||||
with the magic name "CACHEDIR.TAG" and a standard header,
|
||||
as described at:
|
||||
http://www.brynosaurus.com/cachedir
|
||||
Applications can write this file into directories they create
|
||||
for use as caches containing purely regenerable, non-precious data,
|
||||
allowing us to avoid archiving them if --exclude-caches is specified. */
|
||||
|
||||
#define CACHEDIR_SIGNATURE "Signature: 8a477f597d28d172789f06886806bc55"
|
||||
#define CACHEDIR_SIGNATURE_SIZE (sizeof CACHEDIR_SIGNATURE - 1)
|
||||
|
||||
static bool
|
||||
check_cache_directory (char *dirname)
|
||||
{
|
||||
static char tagname[] = "CACHEDIR.TAG";
|
||||
char *tagpath;
|
||||
int fd;
|
||||
bool tag_present = false;
|
||||
|
||||
tagpath = xmalloc (strlen (dirname) + strlen (tagname) + 1);
|
||||
strcpy (tagpath, dirname);
|
||||
strcat (tagpath, tagname);
|
||||
|
||||
fd = open (tagpath, O_RDONLY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
static char tagbuf[CACHEDIR_SIGNATURE_SIZE];
|
||||
|
||||
if (read (fd, tagbuf, CACHEDIR_SIGNATURE_SIZE)
|
||||
== CACHEDIR_SIGNATURE_SIZE
|
||||
&& memcmp (tagbuf, CACHEDIR_SIGNATURE, CACHEDIR_SIGNATURE_SIZE) == 0)
|
||||
tag_present = true;
|
||||
|
||||
close (fd);
|
||||
}
|
||||
|
||||
free (tagpath);
|
||||
|
||||
return tag_present;
|
||||
}
|
||||
|
||||
static void
|
||||
dump_dir0 (char *directory,
|
||||
struct tar_stat_info *st, int top_level, dev_t parent_device)
|
||||
{
|
||||
dev_t our_device = st->stat.st_dev;
|
||||
|
||||
const char *tag_file_name;
|
||||
|
||||
if (!is_avoided_name (st->orig_file_name))
|
||||
{
|
||||
union block *blk = NULL;
|
||||
@@ -1171,34 +1175,60 @@ dump_dir0 (char *directory,
|
||||
WARN ((0, 0,
|
||||
_("%s: file is on a different filesystem; not dumped"),
|
||||
quotearg_colon (st->orig_file_name)));
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
char const *entry;
|
||||
size_t entry_len;
|
||||
char *name_buf = xstrdup (st->orig_file_name);
|
||||
size_t name_size = strlen (name_buf);
|
||||
size_t name_len = name_size;
|
||||
|
||||
/* Now output all the files in the directory. */
|
||||
/* FIXME: Should speed this up by cd-ing into the dir. */
|
||||
|
||||
for (entry = directory; (entry_len = strlen (entry)) != 0;
|
||||
entry += entry_len + 1)
|
||||
{
|
||||
if (name_size < name_len + entry_len)
|
||||
else
|
||||
{
|
||||
char *name_buf;
|
||||
size_t name_size;
|
||||
|
||||
switch (check_exclusion_tags (st->orig_file_name, &tag_file_name))
|
||||
{
|
||||
case exclusion_tag_none:
|
||||
case exclusion_tag_all:
|
||||
{
|
||||
name_size = name_len + entry_len;
|
||||
name_buf = xrealloc (name_buf, name_size + 1);
|
||||
}
|
||||
strcpy (name_buf + name_len, entry);
|
||||
if (!excluded_name (name_buf))
|
||||
dump_file (name_buf, 0, our_device);
|
||||
}
|
||||
char const *entry;
|
||||
size_t entry_len;
|
||||
size_t name_len;
|
||||
|
||||
free (name_buf);
|
||||
}
|
||||
name_buf = xstrdup (st->orig_file_name);
|
||||
name_size = name_len = strlen (name_buf);
|
||||
|
||||
/* Now output all the files in the directory. */
|
||||
/* FIXME: Should speed this up by cd-ing into the dir. */
|
||||
for (entry = directory; (entry_len = strlen (entry)) != 0;
|
||||
entry += entry_len + 1)
|
||||
{
|
||||
if (name_size < name_len + entry_len)
|
||||
{
|
||||
name_size = name_len + entry_len;
|
||||
name_buf = xrealloc (name_buf, name_size + 1);
|
||||
}
|
||||
strcpy (name_buf + name_len, entry);
|
||||
if (!excluded_name (name_buf))
|
||||
dump_file (name_buf, 0, our_device);
|
||||
}
|
||||
|
||||
free (name_buf);
|
||||
}
|
||||
break;
|
||||
|
||||
case exclusion_tag_contents:
|
||||
exclusion_tag_warning (st->orig_file_name, tag_file_name,
|
||||
_("contents not dumped"));
|
||||
name_size = strlen (st->orig_file_name) + strlen (tag_file_name) + 1;
|
||||
name_buf = xmalloc (name_size);
|
||||
strcpy (name_buf, st->orig_file_name);
|
||||
strcat (name_buf, tag_file_name);
|
||||
dump_file (name_buf, 0, our_device);
|
||||
free (name_buf);
|
||||
break;
|
||||
|
||||
case exclusion_tag_under:
|
||||
exclusion_tag_warning (st->orig_file_name, tag_file_name,
|
||||
_("contents not dumped"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure exactly one trailing slash. */
|
||||
@@ -1239,7 +1269,7 @@ create_archive (void)
|
||||
const char *p;
|
||||
|
||||
open_archive (ACCESS_WRITE);
|
||||
xheader_write_global ();
|
||||
buffer_write_global_xheader ();
|
||||
|
||||
if (incremental_option)
|
||||
{
|
||||
@@ -1544,22 +1574,18 @@ dump_file0 (struct tar_stat_info *st, const char *p,
|
||||
|
||||
if (is_dir)
|
||||
{
|
||||
const char *tag_file_name;
|
||||
ensure_slash (&st->orig_file_name);
|
||||
ensure_slash (&st->file_name);
|
||||
|
||||
if (exclude_caches_option
|
||||
&& check_cache_directory (st->orig_file_name))
|
||||
if (check_exclusion_tags (st->orig_file_name, &tag_file_name)
|
||||
== exclusion_tag_all)
|
||||
{
|
||||
if (verbose_option)
|
||||
WARN ((0, 0,
|
||||
_("%s: contains a cache directory tag; not dumped"),
|
||||
quotearg_colon (st->orig_file_name)));
|
||||
exclusion_tag_warning (st->orig_file_name, tag_file_name,
|
||||
_("directory not dumped"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (check_exclude_tags (st->orig_file_name))
|
||||
return;
|
||||
|
||||
ok = dump_dir (fd, st, top_level, parent_device);
|
||||
|
||||
/* dump_dir consumes FD if successful. */
|
||||
@@ -1619,7 +1645,10 @@ dump_file0 (struct tar_stat_info *st, const char *p,
|
||||
|
||||
if (ok)
|
||||
{
|
||||
if (timespec_cmp (get_stat_ctime (&final_stat), original_ctime) != 0
|
||||
if ((timespec_cmp (get_stat_ctime (&final_stat), original_ctime) != 0
|
||||
/* Original ctime will change if the file is a directory and
|
||||
--remove-files is given */
|
||||
&& !(remove_files_option && is_dir))
|
||||
|| original_size < final_stat.st_size)
|
||||
{
|
||||
WARN ((0, 0, _("%s: file changed as we read it"),
|
||||
|
||||
@@ -307,10 +307,10 @@ delete_archive_members (void)
|
||||
}
|
||||
/* Copy header. */
|
||||
|
||||
if (extended_header.size)
|
||||
if (current_stat_info.xhdr.size)
|
||||
{
|
||||
write_recent_bytes (extended_header.buffer,
|
||||
extended_header.size);
|
||||
write_recent_bytes (current_stat_info.xhdr.buffer,
|
||||
current_stat_info.xhdr.size);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -914,10 +914,12 @@ create_placeholder_file (char *file_name, bool is_symlink, int *interdir_made)
|
||||
static int
|
||||
extract_link (char *file_name, int typeflag)
|
||||
{
|
||||
char const *link_name = safer_name_suffix (current_stat_info.link_name,
|
||||
true, absolute_names_option);
|
||||
int interdir_made = 0;
|
||||
char const *link_name;
|
||||
|
||||
transform_member_name (¤t_stat_info.link_name, xform_link);
|
||||
link_name = current_stat_info.link_name;
|
||||
|
||||
if (! absolute_names_option && contains_dot_dot (link_name))
|
||||
return create_placeholder_file (file_name, false, &interdir_made);
|
||||
|
||||
@@ -972,6 +974,8 @@ extract_symlink (char *file_name, int typeflag)
|
||||
int status;
|
||||
int interdir_made = 0;
|
||||
|
||||
transform_member_name (¤t_stat_info.link_name, xform_symlink);
|
||||
|
||||
if (! absolute_names_option
|
||||
&& (IS_ABSOLUTE_FILE_NAME (current_stat_info.link_name)
|
||||
|| contains_dot_dot (current_stat_info.link_name)))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* GNU dump extensions to tar.
|
||||
|
||||
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
||||
2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
@@ -378,7 +378,9 @@ dumpdir_size (const char *p)
|
||||
static int
|
||||
compare_dirnames (const void *first, const void *second)
|
||||
{
|
||||
return strcmp (*(const char**)first, *(const char**)second);
|
||||
char const *const *name1 = first;
|
||||
char const *const *name2 = second;
|
||||
return strcmp (*name1, *name2);
|
||||
}
|
||||
|
||||
/* Compare dumpdir array from DIRECTORY with directory listing DIR and
|
||||
@@ -575,7 +577,7 @@ rename_handler (void *data, void *proc_data)
|
||||
{
|
||||
struct directory *prev, *p;
|
||||
|
||||
/* Detect eventual cycles and clear DIRF_RENAMED flag, so this entries
|
||||
/* Detect eventual cycles and clear DIRF_RENAMED flag, so these entries
|
||||
are ignored when hit by this function next time.
|
||||
If the chain forms a cycle, prev points to the entry DIR is renamed
|
||||
from. In this case it still retains DIRF_RENAMED flag, which will be
|
||||
@@ -1434,6 +1436,7 @@ purge_directory (char const *directory_name)
|
||||
void
|
||||
list_dumpdir (char *buffer, size_t size)
|
||||
{
|
||||
int state = 0;
|
||||
while (size)
|
||||
{
|
||||
switch (*buffer)
|
||||
@@ -1444,7 +1447,12 @@ list_dumpdir (char *buffer, size_t size)
|
||||
case 'R':
|
||||
case 'T':
|
||||
case 'X':
|
||||
fprintf (stdlis, "%c ", *buffer);
|
||||
fprintf (stdlis, "%c", *buffer);
|
||||
if (state == 0)
|
||||
{
|
||||
fprintf (stdlis, " ");
|
||||
state = 1;
|
||||
}
|
||||
buffer++;
|
||||
size--;
|
||||
break;
|
||||
@@ -1453,6 +1461,7 @@ list_dumpdir (char *buffer, size_t size)
|
||||
fputc ('\n', stdlis);
|
||||
buffer++;
|
||||
size--;
|
||||
state = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
47
src/list.c
47
src/list.c
@@ -76,7 +76,6 @@ read_and (void (*do_something) (void))
|
||||
{
|
||||
prev_status = status;
|
||||
tar_stat_destroy (¤t_stat_info);
|
||||
xheader_destroy (&extended_header);
|
||||
|
||||
status = read_header (false);
|
||||
switch (status)
|
||||
@@ -387,12 +386,16 @@ read_header_primitive (bool raw_extended_headers, struct tar_stat_info *info)
|
||||
}
|
||||
else if (header->header.typeflag == XHDTYPE
|
||||
|| header->header.typeflag == SOLARIS_XHDTYPE)
|
||||
xheader_read (header, OFF_FROM_HEADER (header->header.size));
|
||||
xheader_read (&info->xhdr, header,
|
||||
OFF_FROM_HEADER (header->header.size));
|
||||
else if (header->header.typeflag == XGLTYPE)
|
||||
{
|
||||
xheader_read (header, OFF_FROM_HEADER (header->header.size));
|
||||
xheader_decode_global ();
|
||||
xheader_destroy (&extended_header);
|
||||
struct xheader xhdr;
|
||||
memset (&xhdr, 0, sizeof xhdr);
|
||||
xheader_read (&xhdr, header,
|
||||
OFF_FROM_HEADER (header->header.size));
|
||||
xheader_decode_global (&xhdr);
|
||||
xheader_destroy (&xhdr);
|
||||
}
|
||||
|
||||
/* Loop! */
|
||||
@@ -467,9 +470,29 @@ read_header (bool raw_extended_headers)
|
||||
}
|
||||
|
||||
static char *
|
||||
decode_xform (char *file_name)
|
||||
decode_xform (char *file_name, void *data)
|
||||
{
|
||||
file_name = safer_name_suffix (file_name, false, absolute_names_option);
|
||||
xform_type type = *(xform_type*)data;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case xform_symlink:
|
||||
/* FIXME: It is not quite clear how and to which extent are the symbolic
|
||||
links subject to filename transformation. In the absence of another
|
||||
solution, symbolic links are exempt from component stripping and
|
||||
name suffix normalization, but subject to filename transformation
|
||||
proper. */
|
||||
return file_name;
|
||||
|
||||
case xform_link:
|
||||
file_name = safer_name_suffix (file_name, true, absolute_names_option);
|
||||
break;
|
||||
|
||||
case xform_regfile:
|
||||
file_name = safer_name_suffix (file_name, false, absolute_names_option);
|
||||
break;
|
||||
}
|
||||
|
||||
if (strip_name_components)
|
||||
{
|
||||
size_t prefix_len = stripped_prefix_len (file_name,
|
||||
@@ -481,6 +504,12 @@ decode_xform (char *file_name)
|
||||
return file_name;
|
||||
}
|
||||
|
||||
bool
|
||||
transform_member_name (char **pinput, xform_type type)
|
||||
{
|
||||
return transform_name_fp (pinput, decode_xform, &type);
|
||||
}
|
||||
|
||||
#define ISOCTAL(c) ((c)>='0'&&(c)<='7')
|
||||
|
||||
/* Decode things from a file HEADER block into STAT_INFO, also setting
|
||||
@@ -510,7 +539,7 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
|
||||
&& ISOCTAL (header->star_header.ctime[0])
|
||||
&& header->star_header.ctime[11] == ' ')
|
||||
format = STAR_FORMAT;
|
||||
else if (extended_header.size)
|
||||
else if (stat_info->xhdr.size)
|
||||
format = POSIX_FORMAT;
|
||||
else
|
||||
format = USTAR_FORMAT;
|
||||
@@ -599,7 +628,7 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
|
||||
stat_info->is_dumpdir = true;
|
||||
}
|
||||
|
||||
transform_name_fp (&stat_info->file_name, decode_xform);
|
||||
transform_member_name (&stat_info->file_name, xform_regfile);
|
||||
}
|
||||
|
||||
/* Convert buffer at WHERE0 of size DIGS from external format to
|
||||
|
||||
65
src/misc.c
65
src/misc.c
@@ -1,7 +1,7 @@
|
||||
/* Miscellaneous functions, not really specific to GNU tar.
|
||||
|
||||
Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2001,
|
||||
2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
@@ -18,8 +18,6 @@
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include <system.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <rmt.h>
|
||||
#include "common.h"
|
||||
#include <quotearg.h>
|
||||
@@ -518,7 +516,7 @@ set_file_atime (int fd, char const *file, struct timespec const timespec[2])
|
||||
}
|
||||
#endif
|
||||
|
||||
return futimens (fd, file, timespec);
|
||||
return gl_futimens (fd, file, timespec);
|
||||
}
|
||||
|
||||
/* A description of a working directory. */
|
||||
@@ -577,41 +575,13 @@ chdir_arg (char const *dir)
|
||||
return wds++;
|
||||
}
|
||||
|
||||
/* Return maximum number of open files */
|
||||
int
|
||||
get_max_open_files ()
|
||||
{
|
||||
#if defined _SC_OPEN_MAX
|
||||
return sysconf (_SC_OPEN_MAX);
|
||||
#elif defined RLIMIT_NOFILE
|
||||
struct rlimit rlim;
|
||||
|
||||
if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
|
||||
return rlim.rlim_max;
|
||||
#elif defined HAVE_GETDTABLESIZE
|
||||
return getdtablesize ();
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Close all descriptors, except the first three */
|
||||
void
|
||||
closeopen ()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = get_max_open_files () - 1; i > 2; i--)
|
||||
close (i);
|
||||
}
|
||||
|
||||
/* Change to directory I. If I is 0, change to the initial working
|
||||
directory; otherwise, I must be a value returned by chdir_arg. */
|
||||
void
|
||||
chdir_do (int i)
|
||||
{
|
||||
static int previous;
|
||||
static int saved_count;
|
||||
|
||||
|
||||
if (previous != i)
|
||||
{
|
||||
struct wd *prev = &wd[previous];
|
||||
@@ -619,17 +589,30 @@ chdir_do (int i)
|
||||
|
||||
if (! prev->saved)
|
||||
{
|
||||
int err = 0;
|
||||
prev->saved = 1;
|
||||
saved_count++;
|
||||
/* Make sure we still have at least one descriptor available */
|
||||
if (saved_count >= get_max_open_files () - 4)
|
||||
if (save_cwd (&prev->saved_cwd) != 0)
|
||||
err = errno;
|
||||
else if (0 <= prev->saved_cwd.desc)
|
||||
{
|
||||
/* Force restore_cwd to use chdir_long */
|
||||
prev->saved_cwd.desc = -1;
|
||||
prev->saved_cwd.name = xgetcwd ();
|
||||
/* Make sure we still have at least one descriptor available. */
|
||||
int fd1 = prev->saved_cwd.desc;
|
||||
int fd2 = dup (fd1);
|
||||
if (0 <= fd2)
|
||||
close (fd2);
|
||||
else if (errno == EMFILE)
|
||||
{
|
||||
/* Force restore_cwd to use chdir_long. */
|
||||
close (fd1);
|
||||
prev->saved_cwd.desc = -1;
|
||||
prev->saved_cwd.name = xgetcwd ();
|
||||
}
|
||||
else
|
||||
err = errno;
|
||||
}
|
||||
else if (save_cwd (&prev->saved_cwd) != 0)
|
||||
FATAL_ERROR ((0, 0, _("Cannot save working directory")));
|
||||
|
||||
if (err)
|
||||
FATAL_ERROR ((0, err, _("Cannot save working directory")));
|
||||
}
|
||||
|
||||
if (curr->saved)
|
||||
|
||||
@@ -572,8 +572,7 @@ all_names_found (struct tar_stat_info *p)
|
||||
len = strlen (p->file_name);
|
||||
for (cursor = namelist; cursor; cursor = cursor->next)
|
||||
{
|
||||
if (cursor->matching_flags /* FIXME: check this */
|
||||
|| (!WASFOUND (cursor) && cursor->name[0])
|
||||
if ((cursor->name[0] && !WASFOUND (cursor))
|
||||
|| (len >= cursor->length && ISSLASH (p->file_name[cursor->length])))
|
||||
return false;
|
||||
}
|
||||
|
||||
24
src/sparse.c
24
src/sparse.c
@@ -1,6 +1,6 @@
|
||||
/* Functions for dealing with sparse files
|
||||
|
||||
Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
@@ -466,7 +466,7 @@ sparse_skip_file (struct tar_stat_info *st)
|
||||
file.fd = -1;
|
||||
|
||||
rc = tar_sparse_decode_header (&file);
|
||||
skip_file (file.stat_info->archive_file_size);
|
||||
skip_file (file.stat_info->archive_file_size - file.dumped_size);
|
||||
return (tar_sparse_done (&file) && rc) ? dump_status_ok : dump_status_short;
|
||||
}
|
||||
|
||||
@@ -945,16 +945,19 @@ pax_dump_header_0 (struct tar_sparse_file *file)
|
||||
file->stat_info->file_name = xheader_format_name (file->stat_info,
|
||||
"%d/GNUSparseFile.%p/%f", 0);
|
||||
|
||||
xheader_string_begin ();
|
||||
xheader_string_begin (&file->stat_info->xhdr);
|
||||
for (i = 0; i < file->stat_info->sparse_map_avail; i++)
|
||||
{
|
||||
if (i)
|
||||
xheader_string_add (",");
|
||||
xheader_string_add (umaxtostr (map[i].offset, nbuf));
|
||||
xheader_string_add (",");
|
||||
xheader_string_add (umaxtostr (map[i].numbytes, nbuf));
|
||||
xheader_string_add (&file->stat_info->xhdr, ",");
|
||||
xheader_string_add (&file->stat_info->xhdr,
|
||||
umaxtostr (map[i].offset, nbuf));
|
||||
xheader_string_add (&file->stat_info->xhdr, ",");
|
||||
xheader_string_add (&file->stat_info->xhdr,
|
||||
umaxtostr (map[i].numbytes, nbuf));
|
||||
}
|
||||
if (!xheader_string_end ("GNU.sparse.map"))
|
||||
if (!xheader_string_end (&file->stat_info->xhdr,
|
||||
"GNU.sparse.map"))
|
||||
{
|
||||
free (file->stat_info->file_name);
|
||||
file->stat_info->file_name = save_file_name;
|
||||
@@ -1014,6 +1017,7 @@ pax_dump_header_1 (struct tar_sparse_file *file)
|
||||
}
|
||||
size = (size + BLOCKSIZE - 1) / BLOCKSIZE;
|
||||
file->stat_info->archive_file_size += size * BLOCKSIZE;
|
||||
file->dumped_size += size * BLOCKSIZE;
|
||||
|
||||
/* Store sparse file identification */
|
||||
xheader_store ("GNU.sparse.major", file->stat_info, NULL);
|
||||
@@ -1104,7 +1108,8 @@ pax_decode_header (struct tar_sparse_file *file)
|
||||
if (src == endp) \
|
||||
{ \
|
||||
set_next_block_after (b); \
|
||||
b = find_next_block (); \
|
||||
file->dumped_size += BLOCKSIZE; \
|
||||
b = find_next_block (); \
|
||||
src = b->buffer; \
|
||||
endp = b->buffer + BLOCKSIZE; \
|
||||
} \
|
||||
@@ -1115,6 +1120,7 @@ pax_decode_header (struct tar_sparse_file *file)
|
||||
} while (0)
|
||||
|
||||
set_next_block_after (current_header);
|
||||
file->dumped_size += BLOCKSIZE;
|
||||
blk = find_next_block ();
|
||||
p = blk->buffer;
|
||||
COPY_BUF (blk,nbuf,p);
|
||||
|
||||
@@ -826,9 +826,9 @@ sys_exec_info_script (const char **archive_name, int volume_number)
|
||||
setenv ("TAR_FORMAT",
|
||||
archive_format_string (current_format == DEFAULT_FORMAT ?
|
||||
archive_format : current_format), 1);
|
||||
setenv ("TAR_FD", STRINGIFY_BIGINT (p[PWRITE], uintbuf), 1);
|
||||
|
||||
xclose (p[PREAD]);
|
||||
xdup2 (p[PWRITE], 3);
|
||||
|
||||
argv[0] = "/bin/sh";
|
||||
argv[1] = "-c";
|
||||
|
||||
61
src/tar.c
61
src/tar.c
@@ -1,7 +1,7 @@
|
||||
/* A tar (tape archiver) program.
|
||||
|
||||
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
|
||||
2001, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
2001, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
Written by John Gilmore, starting 1985-08-25.
|
||||
|
||||
@@ -254,8 +254,12 @@ enum
|
||||
DELAY_DIRECTORY_RESTORE_OPTION,
|
||||
DELETE_OPTION,
|
||||
EXCLUDE_CACHES_OPTION,
|
||||
EXCLUDE_CACHES_UNDER_OPTION,
|
||||
EXCLUDE_CACHES_ALL_OPTION,
|
||||
EXCLUDE_OPTION,
|
||||
EXCLUDE_TAG_OPTION,
|
||||
EXCLUDE_TAG_UNDER_OPTION,
|
||||
EXCLUDE_TAG_ALL_OPTION,
|
||||
FORCE_LOCAL_OPTION,
|
||||
GROUP_OPTION,
|
||||
HANG_OPTION,
|
||||
@@ -604,9 +608,20 @@ static struct argp_option options[] = {
|
||||
{"exclude-from", 'X', N_("FILE"), 0,
|
||||
N_("exclude patterns listed in FILE"), GRID+1 },
|
||||
{"exclude-caches", EXCLUDE_CACHES_OPTION, 0, 0,
|
||||
N_("exclude directories containing a cache tag"), GRID+1 },
|
||||
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 directories containing FILE"), GRID+1 },
|
||||
N_("exclude contents of directories containing FILE, except"
|
||||
" for FILE itself"), 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 },
|
||||
{"no-recursion", NO_RECURSION_OPTION, 0, 0,
|
||||
N_("avoid descending automatically in directories"), GRID+1 },
|
||||
{"one-file-system", ONE_FILE_SYSTEM_OPTION, 0, 0,
|
||||
@@ -1163,11 +1178,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case ARGP_KEY_ARG:
|
||||
/* File name or non-parsed option, because of ARGP_IN_ORDER */
|
||||
name_add_name (arg, MAKE_INCL_OPTIONS (args));
|
||||
args->input_files = true;
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
/* File name or non-parsed option, because of ARGP_IN_ORDER */
|
||||
name_add_name (arg, MAKE_INCL_OPTIONS (args));
|
||||
args->input_files = true;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
set_subcommand_option (CAT_SUBCOMMAND);
|
||||
@@ -1507,13 +1522,32 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
||||
break;
|
||||
|
||||
case EXCLUDE_CACHES_OPTION:
|
||||
exclude_caches_option = true;
|
||||
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_TAG_OPTION:
|
||||
add_exclude_tag (arg);
|
||||
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 FORCE_LOCAL_OPTION:
|
||||
force_local_option = true;
|
||||
break;
|
||||
@@ -2268,9 +2302,6 @@ main (int argc, char **argv)
|
||||
/* Make sure we have first three descriptors available */
|
||||
stdopen ();
|
||||
|
||||
/* Close all inherited open descriptors, except for the first three */
|
||||
closeopen ();
|
||||
|
||||
/* Pre-allocate a few structures. */
|
||||
|
||||
allocated_archive_names = 10;
|
||||
@@ -2288,6 +2319,7 @@ main (int argc, char **argv)
|
||||
/* Decode options. */
|
||||
|
||||
decode_options (argc, argv);
|
||||
|
||||
name_init ();
|
||||
|
||||
/* Main command execution. */
|
||||
@@ -2376,6 +2408,7 @@ tar_stat_destroy (struct tar_stat_info *st)
|
||||
free (st->gname);
|
||||
free (st->sparse_map);
|
||||
free (st->dumpdir);
|
||||
xheader_destroy (&st->xhdr);
|
||||
memset (st, 0, sizeof (*st));
|
||||
}
|
||||
|
||||
|
||||
11
src/tar.h
11
src/tar.h
@@ -268,6 +268,14 @@ struct sp_array
|
||||
size_t numbytes;
|
||||
};
|
||||
|
||||
struct xheader
|
||||
{
|
||||
struct obstack *stk;
|
||||
size_t size;
|
||||
char *buffer;
|
||||
uintmax_t string_length;
|
||||
};
|
||||
|
||||
struct tar_stat_info
|
||||
{
|
||||
char *orig_file_name; /* name of file read from the archive header */
|
||||
@@ -301,6 +309,9 @@ struct tar_stat_info
|
||||
size_t sparse_map_size; /* Size of the sparse map */
|
||||
struct sp_array *sparse_map;
|
||||
|
||||
/* Extended headers */
|
||||
struct xheader xhdr;
|
||||
|
||||
/* For dumpdirs */
|
||||
bool is_dumpdir; /* Is the member a dumpdir? */
|
||||
bool skipped; /* The member contents is already read
|
||||
|
||||
@@ -498,21 +498,21 @@ _transform_name_to_obstack (char *input)
|
||||
}
|
||||
|
||||
bool
|
||||
transform_name_fp (char **pinput, char *(*fun)(char *))
|
||||
transform_name_fp (char **pinput, char *(*fun)(char *, void *), void *dat)
|
||||
{
|
||||
char *str;
|
||||
bool ret = _transform_name_to_obstack (*pinput);
|
||||
if (ret)
|
||||
{
|
||||
str = obstack_finish (&stk);
|
||||
assign_string (pinput, fun ? fun (str) : str);
|
||||
assign_string (pinput, fun ? fun (str, dat) : str);
|
||||
obstack_free (&stk, str);
|
||||
}
|
||||
else if (fun)
|
||||
{
|
||||
str = *pinput;
|
||||
*pinput = NULL;
|
||||
assign_string (pinput, fun (str));
|
||||
assign_string (pinput, fun (str, dat));
|
||||
free (str);
|
||||
ret = true;
|
||||
}
|
||||
@@ -522,6 +522,6 @@ transform_name_fp (char **pinput, char *(*fun)(char *))
|
||||
bool
|
||||
transform_name (char **pinput)
|
||||
{
|
||||
return transform_name_fp (pinput, NULL);
|
||||
return transform_name_fp (pinput, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ update_archive (void)
|
||||
|
||||
name_gather ();
|
||||
open_archive (ACCESS_UPDATE);
|
||||
xheader_write_global ();
|
||||
buffer_write_global_xheader ();
|
||||
|
||||
while (!found_end)
|
||||
{
|
||||
@@ -181,7 +181,6 @@ update_archive (void)
|
||||
}
|
||||
|
||||
tar_stat_destroy (¤t_stat_info);
|
||||
xheader_destroy (&extended_header);
|
||||
previous_status = status;
|
||||
}
|
||||
|
||||
|
||||
11
src/utf8.c
11
src/utf8.c
@@ -1,6 +1,6 @@
|
||||
/* Charset handling for GNU tar.
|
||||
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2004, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
@@ -28,7 +28,7 @@
|
||||
# define ICONV_CONST
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ICONV
|
||||
#ifndef HAVE_ICONV
|
||||
|
||||
# undef iconv_open
|
||||
# define iconv_open(tocode, fromcode) ((iconv_t) -1)
|
||||
@@ -39,7 +39,7 @@
|
||||
# undef iconv_close
|
||||
# define iconv_close(cd) 0
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -88,11 +88,10 @@ utf8_convert (bool to_utf, char const *input, char **output)
|
||||
|
||||
|
||||
bool
|
||||
string_ascii_p (const char *str)
|
||||
string_ascii_p (char const *p)
|
||||
{
|
||||
const unsigned char *p = (const unsigned char *)str;
|
||||
for (; *p; p++)
|
||||
if (*p > 127)
|
||||
if (! (0 <= *p && *p <= 127))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
127
src/xheader.c
127
src/xheader.c
@@ -1,6 +1,6 @@
|
||||
/* POSIX extended headers for tar.
|
||||
|
||||
Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <hash.h>
|
||||
#include <inttostr.h>
|
||||
#include <quotearg.h>
|
||||
#include <stpcpy.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@@ -35,7 +34,6 @@ static void xheader_set_single_keyword (char *) __attribute__ ((noreturn));
|
||||
/* Used by xheader_finish() */
|
||||
static void code_string (char const *string, char const *keyword,
|
||||
struct xheader *xhdr);
|
||||
static void extended_header_init (void);
|
||||
|
||||
/* Number of global headers written so far. */
|
||||
static size_t global_header_count;
|
||||
@@ -225,7 +223,7 @@ xheader_set_option (char *string)
|
||||
to the result of the basename
|
||||
utility on the translated file name.
|
||||
%p The process ID of the pax process.
|
||||
%n The value of the 3rd argument.
|
||||
%n The value of the 3rd argument.
|
||||
%% A '%' character. */
|
||||
|
||||
char *
|
||||
@@ -331,7 +329,7 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
|
||||
}
|
||||
|
||||
free (dirp);
|
||||
|
||||
|
||||
/* Do not allow it to end in a slash */
|
||||
while (q > buf && ISSLASH (q[-1]))
|
||||
q--;
|
||||
@@ -405,7 +403,7 @@ xheader_write (char type, char *name, struct xheader *xhdr)
|
||||
}
|
||||
|
||||
void
|
||||
xheader_write_global (void)
|
||||
xheader_write_global (struct xheader *xhdr)
|
||||
{
|
||||
char *name;
|
||||
struct keyword_list *kp;
|
||||
@@ -413,12 +411,11 @@ xheader_write_global (void)
|
||||
if (!keyword_global_override_list)
|
||||
return;
|
||||
|
||||
extended_header_init ();
|
||||
xheader_init (xhdr);
|
||||
for (kp = keyword_global_override_list; kp; kp = kp->next)
|
||||
code_string (kp->value, kp->pattern, &extended_header);
|
||||
xheader_finish (&extended_header);
|
||||
xheader_write (XGLTYPE, name = xheader_ghdr_name (),
|
||||
&extended_header);
|
||||
code_string (kp->value, kp->pattern, xhdr);
|
||||
xheader_finish (xhdr);
|
||||
xheader_write (XGLTYPE, name = xheader_ghdr_name (), xhdr);
|
||||
free (name);
|
||||
}
|
||||
|
||||
@@ -478,7 +475,8 @@ xheader_protected_keyword_p (const char *keyword)
|
||||
/* Decode a single extended header record, advancing *PTR to the next record.
|
||||
Return true on success, false otherwise. */
|
||||
static bool
|
||||
decode_record (char **ptr,
|
||||
decode_record (struct xheader *xhdr,
|
||||
char **ptr,
|
||||
void (*handler) (void *, char const *, char const *, size_t),
|
||||
void *data)
|
||||
{
|
||||
@@ -489,7 +487,7 @@ decode_record (char **ptr,
|
||||
char *len_lim;
|
||||
char const *keyword;
|
||||
char *nextp;
|
||||
size_t len_max = extended_header.buffer + extended_header.size - start;
|
||||
size_t len_max = xhdr->buffer + xhdr->size - start;
|
||||
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
@@ -508,7 +506,7 @@ decode_record (char **ptr,
|
||||
ERROR ((0, 0, _("Extended header length is out of allowed range")));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (len_max < len)
|
||||
{
|
||||
int len_len = len_lim - p;
|
||||
@@ -575,8 +573,8 @@ decx (void *data, char const *keyword, char const *value, size_t size)
|
||||
if (t)
|
||||
t->decoder (st, keyword, value, size);
|
||||
else
|
||||
ERROR((0, 0, _("Ignoring unknown extended header keyword `%s'"),
|
||||
keyword));
|
||||
WARN((0, 0, _("Ignoring unknown extended header keyword `%s'"),
|
||||
keyword));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -585,10 +583,10 @@ xheader_decode (struct tar_stat_info *st)
|
||||
run_override_list (keyword_global_override_list, st);
|
||||
run_override_list (global_header_override_list, st);
|
||||
|
||||
if (extended_header.size)
|
||||
if (st->xhdr.size)
|
||||
{
|
||||
char *p = extended_header.buffer + BLOCKSIZE;
|
||||
while (decode_record (&p, decx, st))
|
||||
char *p = st->xhdr.buffer + BLOCKSIZE;
|
||||
while (decode_record (&st->xhdr, &p, decx, st))
|
||||
continue;
|
||||
}
|
||||
run_override_list (keyword_override_list, st);
|
||||
@@ -603,35 +601,35 @@ decg (void *data, char const *keyword, char const *value,
|
||||
}
|
||||
|
||||
void
|
||||
xheader_decode_global (void)
|
||||
xheader_decode_global (struct xheader *xhdr)
|
||||
{
|
||||
if (extended_header.size)
|
||||
if (xhdr->size)
|
||||
{
|
||||
char *p = extended_header.buffer + BLOCKSIZE;
|
||||
char *p = xhdr->buffer + BLOCKSIZE;
|
||||
|
||||
xheader_list_destroy (&global_header_override_list);
|
||||
while (decode_record (&p, decg, &global_header_override_list))
|
||||
while (decode_record (xhdr, &p, decg, &global_header_override_list))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
extended_header_init (void)
|
||||
void
|
||||
xheader_init (struct xheader *xhdr)
|
||||
{
|
||||
if (!extended_header.stk)
|
||||
if (!xhdr->stk)
|
||||
{
|
||||
extended_header.stk = xmalloc (sizeof *extended_header.stk);
|
||||
obstack_init (extended_header.stk);
|
||||
xhdr->stk = xmalloc (sizeof *xhdr->stk);
|
||||
obstack_init (xhdr->stk);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
xheader_store (char const *keyword, struct tar_stat_info const *st,
|
||||
xheader_store (char const *keyword, struct tar_stat_info *st,
|
||||
void const *data)
|
||||
{
|
||||
struct xhdr_tab const *t;
|
||||
|
||||
if (extended_header.buffer)
|
||||
if (st->xhdr.buffer)
|
||||
return;
|
||||
t = locate_handler (keyword);
|
||||
if (!t || !t->coder)
|
||||
@@ -639,20 +637,20 @@ xheader_store (char const *keyword, struct tar_stat_info const *st,
|
||||
if (xheader_keyword_deleted_p (keyword)
|
||||
|| xheader_keyword_override_p (keyword))
|
||||
return;
|
||||
extended_header_init ();
|
||||
t->coder (st, keyword, &extended_header, data);
|
||||
xheader_init (&st->xhdr);
|
||||
t->coder (st, keyword, &st->xhdr, data);
|
||||
}
|
||||
|
||||
void
|
||||
xheader_read (union block *p, size_t size)
|
||||
xheader_read (struct xheader *xhdr, union block *p, size_t size)
|
||||
{
|
||||
size_t j = 0;
|
||||
|
||||
free (extended_header.buffer);
|
||||
xheader_init (xhdr);
|
||||
size += BLOCKSIZE;
|
||||
extended_header.size = size;
|
||||
extended_header.buffer = xmalloc (size + 1);
|
||||
extended_header.buffer[size] = '\0';
|
||||
xhdr->size = size;
|
||||
xhdr->buffer = xmalloc (size + 1);
|
||||
xhdr->buffer[size] = '\0';
|
||||
|
||||
do
|
||||
{
|
||||
@@ -661,7 +659,7 @@ xheader_read (union block *p, size_t size)
|
||||
if (len > BLOCKSIZE)
|
||||
len = BLOCKSIZE;
|
||||
|
||||
memcpy (&extended_header.buffer[j], p->buffer, len);
|
||||
memcpy (&xhdr->buffer[j], p->buffer, len);
|
||||
set_next_block_after (p);
|
||||
|
||||
p = find_next_block ();
|
||||
@@ -732,26 +730,25 @@ xheader_destroy (struct xheader *xhdr)
|
||||
|
||||
|
||||
/* Buildable strings */
|
||||
static uintmax_t string_length;
|
||||
|
||||
void
|
||||
xheader_string_begin ()
|
||||
xheader_string_begin (struct xheader *xhdr)
|
||||
{
|
||||
string_length = 0;
|
||||
xhdr->string_length = 0;
|
||||
}
|
||||
|
||||
void
|
||||
xheader_string_add (char const *s)
|
||||
xheader_string_add (struct xheader *xhdr, char const *s)
|
||||
{
|
||||
if (extended_header.buffer)
|
||||
if (xhdr->buffer)
|
||||
return;
|
||||
extended_header_init ();
|
||||
string_length += strlen (s);
|
||||
x_obstack_grow (&extended_header, s, strlen (s));
|
||||
xheader_init (xhdr);
|
||||
xhdr->string_length += strlen (s);
|
||||
x_obstack_grow (xhdr, s, strlen (s));
|
||||
}
|
||||
|
||||
bool
|
||||
xheader_string_end (char const *keyword)
|
||||
xheader_string_end (struct xheader *xhdr, char const *keyword)
|
||||
{
|
||||
uintmax_t len;
|
||||
uintmax_t p;
|
||||
@@ -761,11 +758,11 @@ xheader_string_end (char const *keyword)
|
||||
char const *np;
|
||||
char *cp;
|
||||
|
||||
if (extended_header.buffer)
|
||||
if (xhdr->buffer)
|
||||
return false;
|
||||
extended_header_init ();
|
||||
xheader_init (xhdr);
|
||||
|
||||
len = strlen (keyword) + string_length + 3; /* ' ' + '=' + '\n' */
|
||||
len = strlen (keyword) + xhdr->string_length + 3; /* ' ' + '=' + '\n' */
|
||||
|
||||
do
|
||||
{
|
||||
@@ -782,13 +779,13 @@ xheader_string_end (char const *keyword)
|
||||
ERROR ((0, 0,
|
||||
_("Generated keyword/value pair is too long (keyword=%s, length=%s)"),
|
||||
keyword, nbuf));
|
||||
obstack_free (extended_header.stk, obstack_finish (extended_header.stk));
|
||||
obstack_free (xhdr->stk, obstack_finish (xhdr->stk));
|
||||
return false;
|
||||
}
|
||||
x_obstack_blank (&extended_header, p);
|
||||
x_obstack_1grow (&extended_header, '\n');
|
||||
cp = obstack_next_free (extended_header.stk) - string_length - p - 1;
|
||||
memmove (cp + p, cp, string_length);
|
||||
x_obstack_blank (xhdr, p);
|
||||
x_obstack_1grow (xhdr, '\n');
|
||||
cp = obstack_next_free (xhdr->stk) - xhdr->string_length - p - 1;
|
||||
memmove (cp + p, cp, xhdr->string_length);
|
||||
cp = stpcpy (cp, np);
|
||||
*cp++ = ' ';
|
||||
cp = stpcpy (cp, keyword);
|
||||
@@ -954,7 +951,7 @@ decode_time (struct timespec *ts, char const *arg, char const *keyword)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
code_num (uintmax_t value, char const *keyword, struct xheader *xhdr)
|
||||
@@ -1094,8 +1091,8 @@ static void
|
||||
mtime_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void const *data)
|
||||
{
|
||||
const struct timespec mtime = data ? *(struct timespec *) data : st->mtime;
|
||||
code_time (mtime, keyword, xhdr);
|
||||
struct timespec const *mtime = data;
|
||||
code_time (mtime ? *mtime : st->mtime, keyword, xhdr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1379,8 +1376,8 @@ static void
|
||||
volume_size_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void const *data)
|
||||
{
|
||||
off_t v = *(off_t*)data;
|
||||
code_num (v, keyword, xhdr);
|
||||
off_t const *v = data;
|
||||
code_num (*v, keyword, xhdr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1398,8 +1395,8 @@ static void
|
||||
volume_offset_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void const *data)
|
||||
{
|
||||
off_t v = *(off_t*)data;
|
||||
code_num (v, keyword, xhdr);
|
||||
off_t const *v = data;
|
||||
code_num (*v, keyword, xhdr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1438,12 +1435,12 @@ sparse_major_decoder (struct tar_stat_info *st,
|
||||
if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
|
||||
st->sparse_major = u;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sparse_minor_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void const *data)
|
||||
{
|
||||
code_num (st->sparse_minor, keyword, xhdr);
|
||||
code_num (st->sparse_minor, keyword, xhdr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1456,7 +1453,7 @@ sparse_minor_decoder (struct tar_stat_info *st,
|
||||
if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
|
||||
st->sparse_minor = u;
|
||||
}
|
||||
|
||||
|
||||
struct xhdr_tab const xhdr_tab[] = {
|
||||
{ "atime", atime_coder, atime_decoder, false },
|
||||
{ "comment", dummy_coder, dummy_decoder, false },
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Makefile for GNU tar regression tests.
|
||||
|
||||
# Copyright (C) 1996, 1997, 1999, 2000, 2001, 2003, 2004, 2005,
|
||||
# 2006 Free Software Foundation, Inc.
|
||||
# 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
# François Pinard <pinard@iro.umontreal.ca>, 1988.
|
||||
# Sergey Poznyakoff <gray@mirddin.farlep.net>, 2004.
|
||||
@@ -59,6 +59,7 @@ TESTSUITE_AT = \
|
||||
delete03.at\
|
||||
delete04.at\
|
||||
delete05.at\
|
||||
exclude.at\
|
||||
extrac01.at\
|
||||
extrac02.at\
|
||||
extrac03.at\
|
||||
|
||||
@@ -31,7 +31,7 @@ echo jeden > file-list
|
||||
cat temp1 >> file-list
|
||||
|
||||
genfile -f "jeden
|
||||
dwa"
|
||||
dwa" || AT_SKIP_TEST
|
||||
genfile -f trzy
|
||||
|
||||
tar cfTv archive file-list | sort
|
||||
@@ -41,6 +41,6 @@ tar cfTv archive file-list | sort
|
||||
trzy
|
||||
],
|
||||
[tar: file-list: file name read contains nul character
|
||||
],[],[ustar]) # Testing one format is enough
|
||||
],[],[],[ustar]) # Testing one format is enough
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
@@ -27,7 +27,7 @@ tarball_prereq() {
|
||||
wget -q --directory-prefix=$3 $4/$1
|
||||
fi
|
||||
fi
|
||||
echo "$2 $3/$1" | md5sum --status --check -
|
||||
echo "$2 $3/$1" | md5sum --status --check - >/dev/null 2>&1
|
||||
}
|
||||
|
||||
|
||||
|
||||
161
tests/exclude.at
Normal file
161
tests/exclude.at
Normal file
@@ -0,0 +1,161 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
# Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
|
||||
# Test the functioning of --exclude-caches and --exclude-tag option families
|
||||
|
||||
AT_SETUP([exclude])
|
||||
AT_KEYWORDS([exclude])
|
||||
|
||||
AT_TAR_CHECK([
|
||||
mkdir dir
|
||||
echo blues > dir/blues
|
||||
echo jazz > dir/jazz
|
||||
mkdir dir/folk
|
||||
echo tagfile > dir/folk/tagfile
|
||||
echo sanjuan > dir/folk/sanjuan
|
||||
mkdir dir/rock
|
||||
echo "Signature: 8a477f597d28d172789f06886806bc55" > dir/rock/CACHEDIR.TAG
|
||||
echo "test" > dir/rock/file
|
||||
|
||||
for option in exclude-caches exclude-caches-under exclude-caches-all
|
||||
do
|
||||
echo OPTION $option
|
||||
tar -cf archive.tar --$option -v dir 2>err
|
||||
cat err
|
||||
echo ARCHIVE
|
||||
tar tf archive.tar
|
||||
done
|
||||
|
||||
for option in exclude-tag exclude-tag-under exclude-tag-all
|
||||
do
|
||||
echo OPTION $option
|
||||
tar -cf archive.tar --${option}=tagfile -v dir 2>err
|
||||
cat err
|
||||
echo ARCHIVE
|
||||
tar tf archive.tar
|
||||
done
|
||||
],
|
||||
[0],
|
||||
[OPTION exclude-caches
|
||||
dir/
|
||||
dir/blues
|
||||
dir/jazz
|
||||
dir/folk/
|
||||
dir/folk/tagfile
|
||||
dir/folk/sanjuan
|
||||
dir/rock/
|
||||
dir/rock/CACHEDIR.TAG
|
||||
tar: dir/rock/: contains a cache directory tag CACHEDIR.TAG; contents not dumped
|
||||
ARCHIVE
|
||||
dir/
|
||||
dir/blues
|
||||
dir/jazz
|
||||
dir/folk/
|
||||
dir/folk/tagfile
|
||||
dir/folk/sanjuan
|
||||
dir/rock/
|
||||
dir/rock/CACHEDIR.TAG
|
||||
OPTION exclude-caches-under
|
||||
dir/
|
||||
dir/blues
|
||||
dir/jazz
|
||||
dir/folk/
|
||||
dir/folk/tagfile
|
||||
dir/folk/sanjuan
|
||||
dir/rock/
|
||||
tar: dir/rock/: contains a cache directory tag CACHEDIR.TAG; contents not dumped
|
||||
ARCHIVE
|
||||
dir/
|
||||
dir/blues
|
||||
dir/jazz
|
||||
dir/folk/
|
||||
dir/folk/tagfile
|
||||
dir/folk/sanjuan
|
||||
dir/rock/
|
||||
OPTION exclude-caches-all
|
||||
dir/
|
||||
dir/blues
|
||||
dir/jazz
|
||||
dir/folk/
|
||||
dir/folk/tagfile
|
||||
dir/folk/sanjuan
|
||||
tar: dir/rock/: contains a cache directory tag CACHEDIR.TAG; directory not dumped
|
||||
ARCHIVE
|
||||
dir/
|
||||
dir/blues
|
||||
dir/jazz
|
||||
dir/folk/
|
||||
dir/folk/tagfile
|
||||
dir/folk/sanjuan
|
||||
OPTION exclude-tag
|
||||
dir/
|
||||
dir/blues
|
||||
dir/jazz
|
||||
dir/folk/
|
||||
dir/folk/tagfile
|
||||
dir/rock/
|
||||
dir/rock/CACHEDIR.TAG
|
||||
dir/rock/file
|
||||
tar: dir/folk/: contains a cache directory tag tagfile; contents not dumped
|
||||
ARCHIVE
|
||||
dir/
|
||||
dir/blues
|
||||
dir/jazz
|
||||
dir/folk/
|
||||
dir/folk/tagfile
|
||||
dir/rock/
|
||||
dir/rock/CACHEDIR.TAG
|
||||
dir/rock/file
|
||||
OPTION exclude-tag-under
|
||||
dir/
|
||||
dir/blues
|
||||
dir/jazz
|
||||
dir/folk/
|
||||
dir/rock/
|
||||
dir/rock/CACHEDIR.TAG
|
||||
dir/rock/file
|
||||
tar: dir/folk/: contains a cache directory tag tagfile; contents not dumped
|
||||
ARCHIVE
|
||||
dir/
|
||||
dir/blues
|
||||
dir/jazz
|
||||
dir/folk/
|
||||
dir/rock/
|
||||
dir/rock/CACHEDIR.TAG
|
||||
dir/rock/file
|
||||
OPTION exclude-tag-all
|
||||
dir/
|
||||
dir/blues
|
||||
dir/jazz
|
||||
dir/rock/
|
||||
dir/rock/CACHEDIR.TAG
|
||||
dir/rock/file
|
||||
tar: dir/folk/: contains a cache directory tag tagfile; directory not dumped
|
||||
ARCHIVE
|
||||
dir/
|
||||
dir/blues
|
||||
dir/jazz
|
||||
dir/rock/
|
||||
dir/rock/CACHEDIR.TAG
|
||||
dir/rock/file
|
||||
],
|
||||
[],[],[],[ustar])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -49,7 +49,8 @@ Create the archive
|
||||
Extract
|
||||
dir/
|
||||
dir/foo
|
||||
],[],[],[ustar]) # Testing one format is enough
|
||||
],
|
||||
[],[],[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 (C) 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -110,6 +110,8 @@ m4_include([append.at])
|
||||
m4_include([append01.at])
|
||||
m4_include([append02.at])
|
||||
|
||||
m4_include([exclude.at])
|
||||
|
||||
m4_include([delete01.at])
|
||||
m4_include([delete02.at])
|
||||
m4_include([delete03.at])
|
||||
|
||||
Reference in New Issue
Block a user