92 Commits

Author SHA1 Message Date
Sergey Poznyakoff
970f999818 Version 1.21 2008-12-27 11:40:31 +00:00
Sergey Poznyakoff
cd39b5a1b7 * src/xheader.c: Remove duplicate inclusion of fnmatch.h. Reported
by Jim Meyering.
2008-11-30 12:33:12 +00:00
Sergey Poznyakoff
7f6e6e6a3e Do not try to drain the input pipe before closing the archive.
* src/buffer.c (close_archive): Remove call to
sys_drain_input_pipe. Pass hit_eof as the second
argument to sys_wait_for_child.
* src/common.h (sys_drain_input_pipe): Remove
(sys_wait_for_child): Declare second argument.
* src/system.c (sys_drain_input_pipe): Remove.
(sys_wait_for_child): Take two arguments. The second one helps to
decide whether to tolerate child termination on SIGPIPE.
2008-11-25 12:33:28 +00:00
Sergey Poznyakoff
99e3a2604f * src/buffer.c (_write_volume_label): Fix typo, which prevented
`-V label -M' from working.
2008-11-03 19:15:52 +00:00
Sergey Poznyakoff
b4ec8aedf9 * NEWS, configure.ac: Version 1.20.91
* doc/tar.texi: Document transformation scope flags.
* src/common.h (transform_symlinks_option): Remove in favor of
transformation scope flags.
(XFORM_REGFILE, XFORM_LINK, XFORM_SYMLINK, XFORM_ALL): New macros.
(transform_name, transform_member_name, transform_name_fp): Take
an additional argument, specifying scope flags.
* src/create.c: Reflect changes to transform_name.
* src/extract.c (extract_link, extract_symlink): Remove calls to
transform_member_name. It is done in read_header.
* src/list.c (decode_xform): Reflect change in data type of 2nd
argument.
(transform_member_name): 2nd arg is int.
(decode_header): Transform file name and link target names.
* src/tar.c: Remove --transform-symlinks.
* src/transform.c (struct transform): New member `flags'.
(transform_flags): New variable.
(parse_transform_expr): Parse transformation scope flags. Allow to
set global flags using `flags=' syntax.
(_transform_name_to_obstack, transform_name_fp)
(transform_name): Take an additional argument, specifying scope
flags.
2008-10-30 14:13:01 +00:00
Sergey Poznyakoff
5354888e40 * src/buffer.c (short_read): Remove !read_full_records condition,
which was always false on a first record and thus disabled record
size autodetection.  Thanks Ed Leaver for the patch.
(_gnu_flush_read): Handle blocking_factor == 1.
* tests/sparsemv.at: Reflect changes to buffer.c.
* tests/sparsemvp.at: Likewise.
* tests/volsize.at: Likewise.
* NEWS: Update.
* THANKS: Add Ed Leaver.
2008-10-22 20:55:35 +00:00
Sergey Poznyakoff
57bfbbde90 * src/common.h (transform_symlinks_option): New global.
* src/create.c (dump_file0): Transform symlink targets only if
explicitly required.  Thanks Cyril Strejc for reporting the
problem.
* src/tar.c (parse_opt): New options --transform-symlinks and
--no-transform-symlinks. New alias --xform to the --transform
option.
* doc/tar.texi: Document --transform-symlinks
* NEWS: Update.
* THANKS: Update.

* src/names.c (name_gather): Use xzalloc.
* src/buffer.c (short_read): Move record size detection before
the loop.
2008-10-16 11:07:19 +00:00
Sergey Poznyakoff
7b69ee5a24 Update 2008-10-07 07:19:23 +00:00
Sergey Poznyakoff
1428b7f176 (options): Add --lzop option. 2008-10-07 07:19:09 +00:00
Sergey Poznyakoff
6901594ac4 Bugfix.
* src/checkpoint.c (checkpoint_compile_action): Add missing
`else'.
2008-10-05 09:09:16 +00:00
Sergey Poznyakoff
c78356feda Implement --no-null option.
* NEWS: Update.
* doc/tar.texi: Update.
* src/tar.c: New option --no-null.
2008-09-24 10:58:19 +00:00
Sergey Poznyakoff
60c00c18b5 Update 2008-09-23 17:07:17 +00:00
Sergey Poznyakoff
c1b55e02b1 ChangeLog 2008-09-23 17:06:43 +00:00
Sergey Poznyakoff
15abf5c4d9 Update 2008-09-18 09:46:39 +00:00
Sergey Poznyakoff
1353511226 Remove incorrect example. 2008-09-18 09:46:34 +00:00
Sergey Poznyakoff
85c7909497 Bugfixes.
* src/incremen.c (dumpdir_create0): Eliminate gcc warning.
(attach_directory): Bugfix - add missing return statement.
* THANKS: Add Enric Hernandez
2008-09-07 08:49:10 +00:00
Sergey Poznyakoff
db83069aea Update 2008-07-31 07:13:13 +00:00
Sergey Poznyakoff
dbbffde583 Fix incremental archiving of renamed directories.
* src/incremen.c (struct directory): New member `next'.  Change
type of `name'.
(dirhead, dirtail): New statics.
(make_directory): Reflect changes to struct directory.
(free_directory, attach_directory): New functions.
(dirlist_replace_prefix): New function.
(note_directory): Use attach_directory, instead of make_directory,
(find_directory, find_directory_meta): Use free_directory.
(procdir): Replace directory prefixes in directory list to avoid
marking subdirectories as renamed after renaming their parent
directory.
(append_incremental_renames): Iterate over directory list, not
hash table, to preserve logical ordering of renames.
* tests/rename04.at, tests/rename05.at: New test cases.
* tests/Makefile.am, tests/testsuite.at: Add rename04.at and
rename05.at.
* tests/atlocal.in (decho): New function.
* tests/multiv06.at: Use decho instead of echo2.
* tests/incremental.at: Raise wait interval to 2 seconds.
2008-07-31 07:12:50 +00:00
Sergey Poznyakoff
1d79c6734c Untabify 2008-07-24 18:16:51 +00:00
Sergey Poznyakoff
3af9cc0f15 Fix multivolume archive creation when volume length=record size.
* src/tar.c (decode_options): Do not allow volume length less
than record size.
* src/buffer.c (_gnu_flush_write): Compensate for the effect
of eventual flush_archive occurring in the middle of buffer
move.
Increment records_written only if _flush_write was able to write
something.
* tests/multiv06.at: New testcase.
* tests/Makefile.am, test/testsuite.at: Add tests/multiv06.at
2008-07-24 18:16:08 +00:00
Sergey Poznyakoff
c9a7297a8a * configure.ac, NEWS: Version 1.20.90
* doc/tar.texi: Document -J, --no-auto-compress, etc.
* src/buffer.c (ct_tar): New constant.
(magic): Add lzop support.  Proposed by Kevin Day
<thekevinday@gmail.com>.
(check_compressed_archive): Do not use autodetect if the
compression program was specified explicitly.
Fall back to analyzing archive name, if the autodetection fails.
* src/suffix.c: Add .lzo
* src/tar.c: New options --lzop and --no-auto-compress.
New short option -J (alias for --lzma).
2008-06-26 10:19:19 +00:00
Sergey Poznyakoff
985637ab5a Bugfixes.
* src/buffer.c (try_new_volume): Print more information with error
diagnostics.
(_gnu_flush_write): Improve error checking.  Adjust
real_s_sizeleft before calling new_volume to avoid creating
malformed multivolume headers.
* tests/delete05.at, tests/gzip.at, tests/ignfail.at,
tests/longv7.at, tests/lustar01.at, tests/lustar02.at,
tests/shortfile.at: Update to match new diagnostic wording
(see 2008-05-06).

* NEWS: Update.
2008-06-26 06:32:25 +00:00
Sergey Poznyakoff
1024343a2b Update 2008-06-14 10:17:42 +00:00
Sergey Poznyakoff
1efa1f3b43 Remove a TZ dependency.Remove a TZ dependency. 2008-06-14 10:17:34 +00:00
Sergey Poznyakoff
5f1a4f9f12 Fix typos. 2008-06-14 10:17:14 +00:00
Sergey Poznyakoff
969d2b986b Update 2008-06-14 10:16:09 +00:00
Sergey Poznyakoff
d5f2066cac (exclude): Document support for new VCS. 2008-06-14 10:16:01 +00:00
Sergey Poznyakoff
79ce0e6789 (exclude_vcs_files): Support for Bazaar, Mercurial and Darcs. 2008-06-14 10:15:25 +00:00
Sergey Poznyakoff
6a052fd5a3 Update 2008-05-05 21:33:51 +00:00
Sergey Poznyakoff
8aa729b90e (main): Reword the "delayed error" message. New wording proposed by Karl Berry. 2008-05-05 21:33:39 +00:00
Sergey Poznyakoff
057dd26a60 Update 2008-05-05 21:31:13 +00:00
Sergey Poznyakoff
b94eed6d03 Version 1.20.
* configure.ac: Raise version number to 1.20
* src/compare.c (diff_dumpdir): const.
* src/common.h (dumpdir_t,dumpdir_iter_t): New data types.
(dumpdir_create0,dumpdir_create,dumpdir_free,dumpdir_locate)
(dumpdir_first,dumpdir_next): New functions.
* src/incremen.c (dumpdir_create0,dumpdir_create,dumpdir_free)
(dumpdir_first,dumpdir_next): New functions.
(dumpdir_locate): Rewrite using binary search.
(struct directory): Change members char *contents, *icontents to
struct dumpdir *dump, *idump. All references updated.
(note_directory): Last arg is const.
* src/names.c (add_hierarchy_to_namelist): buffer is const.
* tests/incr03.at, tests/incr04.at, tests/rename02.at,
tests/rename03.at: Insert calls to sleep between creation of files
and adding them to the archive.
2008-05-05 21:30:57 +00:00
Sergey Poznyakoff
192860abb8 Update 2008-03-31 08:03:00 +00:00
Sergey Poznyakoff
c2d2e806a1 (dump_file0): Count links only for actually dumped files 2008-03-31 08:02:53 +00:00
Sergey Poznyakoff
2a89f7a0a8 * NEWS: Document --no-check-device and --check-device.
* doc/rendition.texi: Change the way FIXME-*refs are handled in
!PROOF.
* doc/intern.texi, doc/tar.texi: Update.
* doc/untabify.el: New file.
* doc/Makefile.am (EXTRA_DIST): Add untabify.el
(untabify, final, check-format, check-refs, check-fixmes)
(check-unrevised, all-check-docs, check-docs): New rules.
2008-03-27 10:11:05 +00:00
Sergey Poznyakoff
71d2a66f42 * src/common.h (check_device_option): New global.
* src/incremen.c (procdir): Use boolean and instead of bitwise
one. Patch by Jean-Louis Martineau.
Compare device numbers only if check_device_option is set.
* src/tar.c: New command line options --no-check-device and
--check-device. Proposed by Jean-Louis Martineau.
(parse_opt): Hanlde new options.
(decode_options): Initialize check_device_option to true.
2008-03-27 08:56:26 +00:00
Sergey Poznyakoff
e496c1b529 * bootstrap: Use rsync to get translations.
* doc/tar.texi: Minor change.
* lib/.cvsignore: Update
* po/.cvsignore: Update
* src/system.c: Remove include setenv.h.
* tests/atlocal.in (STAR_DATA_URL): Update.
* tests/star/README: Update URL.
2008-03-06 08:17:33 +00:00
Sergey Poznyakoff
6667fa7fb8 Update 2008-02-09 10:36:40 +00:00
Sergey Poznyakoff
a16ad3112e Fix a typo 2008-02-09 10:35:55 +00:00
Sergey Poznyakoff
7efe3850f6 * NEWS: Update.
* configure.ac: Version 1.19.90
* po/POTFILES.in: Add missing files.
* src/compare.c (verify_volume): Honor --ignore-zeros.
Proposed by Jan-Benedict Glaw.
* tests/shortfile.at (AT_KEYWORDS): Add shortfile0.
2008-02-08 14:12:22 +00:00
Sergey Poznyakoff
d0694ee604 Update the description 2008-02-08 10:32:15 +00:00
Sergey Poznyakoff
37f0faf1c0 (dump_file0): Apply transform_name to symlink targets. 2008-02-07 15:46:41 +00:00
Sergey Poznyakoff
b893aee6d2 Update 2008-02-07 15:46:28 +00:00
Sergey Poznyakoff
f60d655908 Update 2008-02-04 10:39:05 +00:00
Sergey Poznyakoff
549481a0a7 Update 2008-02-04 10:38:27 +00:00
Sergey Poznyakoff
e08afc2002 Document changes to the --transform option. 2008-02-04 10:38:18 +00:00
Sergey Poznyakoff
338591a486 Support multiple --transform options. Support semicolon-separated lists of replace expressions. 2008-02-04 10:35:20 +00:00
Paul Eggert
c0e0d06e69 * doc/tar.texi: Update Back-Cover text to reflect new GNU wording.
2007-12-17  Paul Eggert  <eggert@cs.ucla.edu>

Exit with nonzero status if a close fails on an archive.
Problem (and initial trivial fix)
* src/buffer.c (close_archive, new_volume): close_error, not close_warn.
2008-01-31 00:50:12 +00:00
Sergey Poznyakoff
6e85425618 Update 2007-12-05 09:48:37 +00:00
Sergey Poznyakoff
336519aa4f Add shortupd.at. 2007-12-05 09:45:35 +00:00
Sergey Poznyakoff
5f4d99491d (check_compressed_archive): Do not bail out if the
file is too short, set boolean flag, passed as an argument
instead.  This fixes a bug introduced on 2007-08-24. See also
tests/shortupd.at.
2007-12-05 09:45:22 +00:00
Paul Eggert
48d83be336 Don't read from name[-1].
* src/incremen.c (make_directory): Handle namelen == 0, since
find_directory_meta calls make_directory ("").
2007-11-13 07:01:26 +00:00
Sergey Poznyakoff
60d351cc5a Update 2007-11-07 08:48:39 +00:00
Sergey Poznyakoff
e33be3d0a1 Add fseeko and snprintf. 2007-11-07 08:48:28 +00:00
Sergey Poznyakoff
32562b9412 (checkout): Use URL of the gnulib CVS mirror. 2007-11-07 08:48:19 +00:00
Sergey Poznyakoff
dfd87ba1d0 (magic): Fix lzma option 2007-10-31 13:10:55 +00:00
Sergey Poznyakoff
5d4a682a55 Update 2007-10-31 12:57:04 +00:00
Sergey Poznyakoff
8e3a2a520d (sys_exec_info_script,sys_exec_checkpoint_script): pass the current blocking factor in TAR_BLOCKING_FACTOR environment variable. 2007-10-31 12:56:46 +00:00
Sergey Poznyakoff
745832a280 New actions: bell and ttyout 2007-10-31 12:56:27 +00:00
Sergey Poznyakoff
458efab23b Minor fix 2007-10-30 14:58:52 +00:00
Sergey Poznyakoff
23dcaa117f Update 2007-10-30 14:09:20 +00:00
Sergey Poznyakoff
5099ddf6cc Document --hard-dereference and --checkpoint-action options. Improve documentation of --check-links. 2007-10-30 14:09:04 +00:00
Sergey Poznyakoff
8476145508 Use texi2html and the CVS version of gendocs.sh to create HTML versions of the manual 2007-10-30 14:08:41 +00:00
Sergey Poznyakoff
362492fe70 Use texi2html and the CVS version of gendocs.sh to create HTML versions of the manual 2007-10-30 14:08:21 +00:00
Sergey Poznyakoff
7111008659 Update 2007-10-29 16:57:32 +00:00
Sergey Poznyakoff
ec4741d732 (parse_opt): New options --hard-dereference, --checkpoint-action.
(decode_options): Call checkpoint_finish_compile.
2007-10-29 16:56:56 +00:00
Sergey Poznyakoff
bed7de0271 (sys_exec_checkpoint_script): New function.
(sys_exec_info_script): Restore SIGPIPE handler.
2007-10-29 16:56:33 +00:00
Sergey Poznyakoff
eaaadcfd36 (file_count_links): do nothing if hard_dereference_option is set. 2007-10-29 16:56:13 +00:00
Sergey Poznyakoff
a8830fbb86 (enum checkpoint_style): Remove.
(checkpoint_style): Remove.
(DEFAULT_CHECKPOINT): New define.
(hard_dereference_option): New variable.
(sys_exec_checkpoint_script): New declaration.
2007-10-29 16:55:58 +00:00
Sergey Poznyakoff
848659f1c6 (checkpoint, do_checkpoint): Remove.
(_flush_write, simple_flush_read, _gnu_flush_read): Use
checkpoint_run.
2007-10-29 16:55:37 +00:00
Sergey Poznyakoff
17cbd4862c checkpoint handling 2007-10-29 16:55:16 +00:00
Sergey Poznyakoff
64ded9e702 (tar_SOURCES): add checkpoint.c 2007-10-29 16:54:51 +00:00
Sergey Poznyakoff
ccd0a527e4 Version 1.19.1 2007-10-29 16:54:38 +00:00
Sergey Poznyakoff
3f869877a4 Version 1.19.1 2007-10-29 16:53:28 +00:00
Sergey Poznyakoff
8c528937a9 Update 2007-10-29 16:53:20 +00:00
Sergey Poznyakoff
460f4ec146 Update 2007-10-29 08:53:58 +00:00
Sergey Poznyakoff
eb59c14a1f (sys_exec_info_script): Initialize buf. Problem reported by Bengt-Arne Fjellner. 2007-10-29 08:51:46 +00:00
Paul Eggert
3c4f4ca423 Avoid compiler warnings.
* src/list.c (read_header_primitive): Define two locals, to
avoid incorrect "may be used uninitialized" warnings.
* src/incremen.c (procdir): Remove decl of unused local, "len".

expired.
SCALAR(0x830b08c)
2007-10-18 21:36:38 +00:00
Sergey Poznyakoff
506b4db5d0 Update 2007-10-18 07:59:48 +00:00
Sergey Poznyakoff
5bfb6c5f9d (gzip): Remove compression patent warning. According to Brett Smith, the patent is expired. 2007-10-18 07:59:39 +00:00
Sergey Poznyakoff
3725b5606f Update 2007-10-17 09:12:54 +00:00
Sergey Poznyakoff
d1a7eebc30 Update 2007-10-17 09:12:03 +00:00
Sergey Poznyakoff
dfe280dcca Add Lasse Collin and Jean-Pierre Demailly. 2007-10-17 09:11:50 +00:00
Sergey Poznyakoff
620a136e74 New options --auto-compress (-a) and --lzma 2007-10-17 09:11:34 +00:00
Sergey Poznyakoff
3fb5d67b28 (set_comression_program_by_suffix): New prototype. 2007-10-17 09:11:23 +00:00
Sergey Poznyakoff
c30a794679 (magic): Add an entry for new lzma format. Proposed by Lasse Collin 2007-10-17 09:11:08 +00:00
Sergey Poznyakoff
00bb0d8f5c Add suffix.c 2007-10-17 09:10:46 +00:00
Sergey Poznyakoff
af3e05b6af New file. Determine compression algorithm by archive file name suffix. Suggested by Jean-Pierre Demailly. 2007-10-17 09:10:34 +00:00
Paul Eggert
6060d613d1 * src/utf8.c (string_ascii_p): Recode to avoid bogus GCC 4.2.1
warning about "comparison is always true due to limited range of
data type" when char is unsigned.
2007-10-13 05:49:18 +00:00
Paul Eggert
3f12066739 Adjust to recent gnulib changes.
* configure.ac: Dont' check for strerror, since gnulib now does this.
* .cvsignore: Add m4, tar-[0-9]*.
* lib/.cvsignore: Adjust to various gnulib file name changes.
Add .deps, rmt-command.h.

SCALAR(0x830b0dc)
directories.

SCALAR(0x831ad2c)
2007-10-11 22:04:44 +00:00
Sergey Poznyakoff
3b74fbfc3b Update 2007-10-10 11:04:25 +00:00
Sergey Poznyakoff
14d39a2c14 Update 2007-10-10 11:03:42 +00:00
56 changed files with 3339 additions and 985 deletions

View File

@@ -12,5 +12,7 @@ build-aux
config.*
configure
gnulib
m4
rmt
stamp-h1
tar-[0-9]*

395
ChangeLog
View File

@@ -1,3 +1,392 @@
2008-11-30 Sergey Poznyakoff <gray@gnu.org.ua>
* src/xheader.c: Remove duplicate inclusion of fnmatch.h. Reported
by Jim Meyering.
2008-11-25 Sergey Poznyakoff <gray@gnu.org.ua>
Do not try to drain the input pipe before closing the
archive.
* src/buffer.c (close_archive): Remove call to
sys_drain_input_pipe. Pass hit_eof as the second
argument to sys_wait_for_child.
* src/common.h (sys_drain_input_pipe): Remove
(sys_wait_for_child): Declare second argument.
* src/system.c (sys_drain_input_pipe): Remove.
(sys_wait_for_child): Take two arguments. The second one helps to
decide whether to tolerate child termination on SIGPIPE.
2008-11-03 Sergey Poznyakoff <gray@gnu.org.ua>
* src/buffer.c (_write_volume_label): Fix typo, which prevented
`-V label -M' from working.
2008-10-30 Sergey Poznyakoff <gray@gnu.org.ua>
* NEWS, configure.ac: Version 1.20.91
* doc/tar.texi: Document transformation scope flags.
* src/common.h (transform_symlinks_option): Remove in favor of
transformation scope flags.
(XFORM_REGFILE, XFORM_LINK, XFORM_SYMLINK, XFORM_ALL): New macros.
(transform_name, transform_member_name, transform_name_fp): Take
an additional argument, specifying scope flags.
* src/create.c: Reflect changes to transform_name.
* src/extract.c (extract_link, extract_symlink): Remove calls to
transform_member_name. It is done in read_header.
* src/list.c (decode_xform): Reflect change in data type of 2nd
argument.
(transform_member_name): 2nd arg is int.
(decode_header): Transform file name and link target names.
* src/tar.c: Remove --transform-symlinks.
* src/transform.c (struct transform): New member `flags'.
(transform_flags): New variable.
(parse_transform_expr): Parse transformation scope flags. Allow to
set global flags using `flags=' syntax.
(_transform_name_to_obstack, transform_name_fp)
(transform_name): Take an additional argument, specifying scope
flags.
2008-10-19 Sergey Poznyakoff <gray@gnu.org.ua>
* THANKS: Add Ed Leaver.
* src/buffer.c (short_read): Remove !read_full_records condition,
which was always false on a first record and thus disabled record
size autodetection. Thanks Ed Leaver for the patch.
(_gnu_flush_read): Handle blocking_factor == 1.
* tests/sparsemv.at: Reflect changes to buffer.c.
* tests/sparsemvp.at: Likewise.
* tests/volsize.at: Likewise.
* NEWS: Update.
2008-10-16 Sergey Poznyakoff <gray@gnu.org.ua>
* src/common.h (transform_symlinks_option): New global.
* src/create.c (dump_file0): Transform symlink targets only if
explicitly required. Thanks Cyril Strejc for reporting the
problem.
* src/tar.c (parse_opt): New options --transform-symlinks and
--no-transform-symlinks. New alias --xform to the --transform
option.
* doc/tar.texi: Document --transform-symlinks
* NEWS: Update.
* THANKS: Update.
* src/names.c (name_gather): Use xzalloc.
* src/buffer.c (short_read): Move record size detection before
the loop.
2008-10-07 Sergey Poznyakoff <gray@gnu.org.ua>
* src/tar.c (options): Add --lzop option.
2008-10-05 Xavier Hienne <xavier.hienne@free.fr> (tiny change)
* src/checkpoint.c (checkpoint_compile_action): Add missing
`else'.
2008-09-24 Sergey Poznyakoff <gray@gnu.org.ua>
* NEWS: Update.
* doc/tar.texi: Update.
* src/tar.c: New option --no-null.
2008-09-23 Sergey Poznyakoff <gray@gnu.org.ua>
* src/common.h (filename_terminator): Remove global.
* src/tar.c (filename_terminator): New static.
* src/names.c (name_next_elt): Do not depend on
filename_terminator, this was a leftover from 1.13.
2008-09-18 Sergey Poznyakoff <gray@gnu.org.ua>
* doc/tar.texi: Remove incorrect example.
2008-09-07 Sergey Poznyakoff <gray@gnu.org.ua>
* src/incremen.c (dumpdir_create0): Eliminate gcc warning.
(attach_directory): Bugfix - add missing return statement.
* THANKS: Add Enric Hernandez
2008-07-31 Sergey Poznyakoff <gray@gnu.org.ua>
* src/incremen.c (struct directory): New member `next'. Change
type of `name'.
(dirhead, dirtail): New statics.
(make_directory): Reflect changes to struct directory.
(free_directory, attach_directory): New functions.
(dirlist_replace_prefix): New function.
(note_directory): Use attach_directory, instead of make_directory,
(find_directory, find_directory_meta): Use free_directory.
(procdir): Replace directory prefixes in directory list to avoid
marking subdirectories as renamed after renaming their parent
directory.
(append_incremental_renames): Iterate over directory list, not
hash table, to preserve logical ordering of renames.
* tests/rename04.at, tests/rename05.at: New test cases.
* tests/Makefile.am, tests/testsuite.at: Add rename04.at and
rename05.at.
* tests/atlocal.in (decho): New function.
* tests/multiv06.at: Use decho instead of echo2.
* tests/incremental.at: Raise wait interval to 2 seconds.
2008-07-24 Sergey Poznyakoff <gray@gnu.org.ua>
* src/tar.c (decode_options): Do not allow volume length less
than record size.
* src/buffer.c (_gnu_flush_write): Compensate for the effect
of eventual flush_archive occurring in the middle of buffer
move.
Increment records_written only if _flush_write was able to write
something.
* tests/multiv06.at: New testcase.
* tests/Makefile.am, test/testsuite.at: Add tests/multiv06.at
2008-06-26 Sergey Poznyakoff <gray@gnu.org.ua>
* configure.ac, NEWS: Version 1.20.90
* doc/tar.texi: Document -J, --no-auto-compress, etc.
* src/buffer.c (ct_tar): New constant.
(magic): Add lzop support. Proposed by Kevin Day
<thekevinday@gmail.com>.
(check_compressed_archive): Do not use autodetect if the
compression program was specified explicitly.
Fall back to analyzing archive name, if the autodetection fails.
* src/suffix.c: Add .lzo
* src/tar.c: New options --lzop and --no-auto-compress.
New short option -J (alias for --lzma).
* src/buffer.c (try_new_volume): Print more information with error
diagnostics.
(_gnu_flush_write): Improve error checking. Adjust
real_s_sizeleft before calling new_volume to avoid creating
malformed multivolume headers.
* tests/delete05.at, tests/gzip.at, tests/ignfail.at,
tests/longv7.at, tests/lustar01.at, tests/lustar02.at,
tests/shortfile.at: Update to match new diagnostic wording
(see 2008-05-06).
* NEWS: Update.
2008-06-14 Sergey Poznyakoff <gray@gnu.org.ua>
* doc/tar.texi (exclude): Document support for new VCS.
* THANKS: Update.
* NEWS: Update.
* tests/multiv05.at: Fix typos.
* tests/volsize.at: Remove a TZ dependency.
2008-06-14 Dan Drake <dan@dandrake.org> (tiny change)
* src/tar.c (exclude_vcs_files): Support for Bazaar, Mercurial and
Darcs.
2008-05-06 Sergey Poznyakoff <gray@gnu.org.ua>
* src/tar.c (main): Reword the "delayed error" message. New
wording proposed by Karl Berry.
2008-02-20 Sergey Poznyakoff <gray@gnu.org.ua>
* configure.ac: Raise version number to 1.20
* src/compare.c (diff_dumpdir): const.
* src/common.h (dumpdir_t,dumpdir_iter_t): New data types.
(dumpdir_create0,dumpdir_create,dumpdir_free,dumpdir_locate)
(dumpdir_first,dumpdir_next): New functions.
* src/incremen.c (dumpdir_create0,dumpdir_create,dumpdir_free)
(dumpdir_first,dumpdir_next): New functions.
(dumpdir_locate): Rewrite using binary search.
(struct directory): Change members char *contents, *icontents to
struct dumpdir *dump, *idump. All references updated.
(note_directory): Last arg is const.
* src/names.c (add_hierarchy_to_namelist): buffer is const.
* tests/incr03.at, tests/incr04.at, tests/rename02.at,
tests/rename03.at: Insert calls to sleep between creation of files
and adding them to the archive.
2008-03-31 Sergey Poznyakoff <gray@gnu.org.ua>
* src/create.c (dump_file0): Count links only for actually dumped
files.
2008-03-27 Sergey Poznyakoff <gray@gnu.org.ua>
* NEWS: Document --no-check-device and --check-device.
* doc/rendition.texi: Change the way FIXME-*refs are handled in
!PROOF.
* doc/intern.texi, doc/tar.texi: Update.
* doc/untabify.el: New file.
* doc/Makefile.am (EXTRA_DIST): Add untabify.el
(untabify, final, check-format, check-refs, check-fixmes)
(check-unrevised, all-check-docs, check-docs): New rules.
* src/common.h (check_device_option): New global.
* src/incremen.c (procdir): Use boolean and instead of bitwise
one. Patch by Jean-Louis Martineau.
Compare device numbers only if check_device_option is set.
* src/tar.c: New command line options --no-check-device and
--check-device. Proposed by Jean-Louis Martineau.
(parse_opt): Hanlde new options.
(decode_options): Initialize check_device_option to true.
* THANKS: Update
2008-03-06 Sergey Poznyakoff <gray@gnu.org.ua>
* bootstrap: Use rsync to get translations.
* doc/tar.texi: Minor change.
* lib/.cvsignore: Update
* po/.cvsignore: Update
* src/system.c: Remove include setenv.h.
* tests/atlocal.in (STAR_DATA_URL): Update.
* tests/star/README: Update URL.
2008-02-09 Sergey Poznyakoff <gray@gnu.org.ua>
* doc/tar.texi: Fix a typo. Reported by Denis Excoffier.
2008-02-08 Sergey Poznyakoff <gray@gnu.org.ua>
* NEWS: Update.
* configure.ac: Version 1.19.90
* po/POTFILES.in: Add missing files.
* src/compare.c (verify_volume): Honor --ignore-zeros.
Proposed by Jan-Benedict Glaw.
* tests/shortfile.at (AT_KEYWORDS): Add shortfile0.
2008-02-07 Sergey Poznyakoff <gray@gnu.org.ua>
* NEWS: Update.
* src/create.c (dump_file0): Apply transform_name to symlink
targets.
2008-02-04 Sergey Poznyakoff <gray@gnu.org.ua>
* src/transform.c: Support multiple --transform options. Support
semicolon-separated lists of replace expressions.
* NEWS, tar.texi: Document changes to the --transform option.
2008-01-30 Paul Eggert <eggert@cs.ucla.edu>
* doc/tar.texi: Update Back-Cover text to reflect new GNU wording.
2007-12-17 Paul Eggert <eggert@cs.ucla.edu>
Exit with nonzero status if a close fails on an archive.
Problem (and initial trivial fix)
* src/buffer.c (close_archive, new_volume): close_error, not
close_warn.
2007-12-05 Sergey Poznyakoff <gray@gnu.org.ua>
* src/buffer.c (check_compressed_archive): Do not bail out if the
file is too short, set boolean flag, passed as an argument
instead. This fixes a bug introduced on 2007-08-24. See also
tests/shortupd.at.
* tests/Makefile.am, tests/testsuite.at: Add shortupd.at.
* tests/shortupd.at: New test.
2007-11-12 Jim Meyering <meyering@redhat.com>
Don't read from name[-1].
* src/incremen.c (make_directory): Handle namelen == 0, since
find_directory_meta calls make_directory ("").
2007-11-07 Sergey Poznyakoff <gray@gnu.org.ua>
* bootstrap (checkout): Use URL of the gnulib CVS mirror.
* gnulib.modules: Add fseeko and snprintf.
2007-10-31 Sergey Poznyakoff <gray@gnu.org.ua>
* src/checkpoint.c: New actions: bell and ttyout
* src/system.c (sys_exec_info_script)
(sys_exec_checkpoint_script): pass the current blocking factor in
TAR_BLOCKING_FACTOR environment variable.
* doc/tar.texi: Update
* NEWS: Update
2007-10-30 Sergey Poznyakoff <gray@gnu.org.ua>
* doc/Makefile.am: Use texi2html and the CVS version of gendocs.sh
to create HTML versions of the manual.
* doc/gendocs_template: Likewise.
* doc/tar.texi: Document --hard-dereference and
--checkpoint-action options. Improve documentation of
--check-links.
2007-10-29 Sergey Poznyakoff <gray@gnu.org.ua>
* NEWS: Update
* configure.ac: Version 1.19.1
* po/POTFILES.in: Add src/checkpoint.c
* src/Makefile.am (tar_SOURCES): add checkpoint.c
* src/checkpoint.c: New file - checkpoint handling.
* src/buffer.c (checkpoint, do_checkpoint): Remove.
(_flush_write, simple_flush_read, _gnu_flush_read): Use
checkpoint_run.
* src/common.h (enum checkpoint_style): Remove.
(checkpoint_style): Remove.
(DEFAULT_CHECKPOINT): New define.
(hard_dereference_option): New variable.
(sys_exec_checkpoint_script): New declaration.
* src/create.c (file_count_links): do nothing if
hard_dereference_option is set.
* src/system.c (sys_exec_checkpoint_script): New function.
(sys_exec_info_script): Restore SIGPIPE handler.
* src/tar.c: (parse_opt): New options --hard-dereference,
--checkpoint-action.
(decode_options): Call checkpoint_finish_compile.
* src/system.c (sys_exec_info_script): Initialize buf. Problem
reported by Bengt-Arne Fjellner.
2007-10-18 Jim Meyering <jim@meyering.net>
Avoid compiler warnings.
* src/list.c (read_header_primitive): Define two locals, to
avoid incorrect "may be used uninitialized" warnings.
* src/incremen.c (procdir): Remove decl of unused local, "len".
2007-10-18 Sergey Poznyakoff <gray@gnu.org.ua>
* doc/tar.texi (gzip): Remove compression patent
warning. According to Brett Smith, the patent is
expired.
2007-10-17 Sergey Poznyakoff <gray@gnu.org.ua>
* src/suffix.c: New file. Compress format detection by archive
suffix (when creating). Suggested by Jean-Pierre Demailly.
* src/Makefile.am: Add suffix.c
* src/buffer.c (magic): Add an entry for new lzma format. Proposed
by Lasse Collin.
* src/common.h (set_comression_program_by_suffix): New prototype.
* src/tar.c: New options --auto-compress (-a) and --lzma
* THANKS: Add Lasse Collin and Jean-Pierre Demailly.
* NEWS: Update
* doc/tar.texi: Update
2007-10-12 Paul Eggert <eggert@cs.ucla.edu>
* src/utf8.c (string_ascii_p): Recode to avoid bogus GCC 4.2.1
warning about "comparison is always true due to limited range of
data type" when char is unsigned.
2007-10-11 Paul Eggert <eggert@cs.ucla.edu>
Adjust to recent gnulib changes.
* configure.ac: Dont' check for strerror, since gnulib now does this.
* .cvsignore: Add m4, tar-[0-9]*.
* lib/.cvsignore: Adjust to various gnulib file name changes.
Add .deps, rmt-command.h.
2007-10-10 Sergey Poznyakoff <gray@gnu.org.ua>
* configure.ac, NEWS: Raise version number to 1.19
* tests/star/README: Update
2007-10-05 Sergey Poznyakoff <gray@gnu.org.ua>
* src/create.c (dump_regular_file): Fix file padding in case of
@@ -30,8 +419,8 @@
Implement --exclude-tag* and --exclude-cache* options for listed
incremental archives.
New option --exclude-vcs to exclude VCS-specific files and
directories.
directories.
* NEWS: Update
* doc/tar.texi: Document --exclude-vcs option
* src/common.h (exclusion_tag_warning, check_exclusion_tags): New
@@ -49,7 +438,7 @@
(scan_directory): Hanlde exclusion tags.
* src/tar.c: New option --exclude-vcs
(exclude_vcs_files): New function
2007-09-14 Paul Eggert <eggert@cs.ucla.edu>
* AUTHORS: Remove unnecessary information. Just list the

136
NEWS
View File

@@ -1,6 +1,138 @@
GNU tar NEWS - User visible changes. 2007-10-10
GNU tar NEWS - User visible changes. 2008-12-27
Please send GNU tar bug reports to <bug-tar@gnu.org>
version 1.21 - Sergey Poznyakoff, 2008-12-27
* New short option -J
A shortcut for --lzma.
* New option --lzop
* New option --no-auto-compress
Cancels the effect of previous --auto-compress (-a) option.
* New option --no-null
Cancels the effect of previous --null option.
* Compressed format recognition
If tar is unable to determine archive compression format, it falls
back to using archive suffix to determine it.
* VCS support.
Using --exclude-vcs handles also files used internally by Bazaar,
Mercurial and Darcs.
* Transformation scope flags
Name transformation expressions understand additional flags that
control type of archive members affected by them. The flags are:
- r
Apply transformation to regular archive members.
- s
Apply transformation to symbolic link targets.
- h
Apply transformation to hard link targets.
Corresponding upper-case letters negate the meaning, so that
`H' means ``do not apply transformation to hard link targets.''
The scope flags are listed in the third part of an `s' expression,
e.g.:
tar --transform 's|^|/usr/local/|S'
Default is `rsh', which means that transformations are applied to
both regular archive members and to the targets of symbolic and hard
links. If several transform expressions are used, the default flags
can be changed using `flags=' statement before the expressions, e.g.:
tar --transform 'flags=S;s|^|/usr/local/|S'
* Bugfixes
** The --null option disabled handling of tar options in list files. This
is fixed.
** Fixed record size autodetection. If detected record size differs from
the expected value (either default, or set on the command line), tar
always prints a warning if verbosity level is set to 1 or greater,
i.e. if either -t or -v option is given.
version 1.20 - Sergey Poznyakoff, 2008-04-14
* New option --auto-compress (-a)
With --create, selects compression algorithm basing on the suffix
of the archive file name.
* New option --lzma
Selects LZMA compression algorithm
* New option --hard-dereference
During archive creation, dereferences hard links and stores the files
they refer to, instead of creating usual hard link members (type '1').
* New option --checkpoint-action
This action allows to specify an action to be executed upon hitting a
checkpoint. Recognized actions are: dot, echo (the default),
echo=string, ttyout=string, exec=cmdline, and sleep=value. Any number
of `--checkpoint-action' options can be specified, the actions will be
executed in order of their appearance in the command line. See
chapter 3.8 "Checkpoints" for a complete description.
* New options --no-check-device, --check-device.
The `--no-check-device' option disables comparing device numbers during
preparatory stage of an incremental dump. This allows to avoid
creating full dumps if the device numbers change (e.g. when using an
LVM snapshot).
The `--check-device' option enables comparing device numbers. This is
the default. This option is provided to undo the effect of the previous
`--no-check-device' option, e.g. if it was set in TAR_OPTIONS
environment variable.
* The --transform option.
Any number of `--transform' options can be given in the command line.
The specified transformations will be applied in turn.
The argument to `--transform' option can be a list of replace
expressions, separated by a semicolon (as in `sed').
Filename transformations are applied to symbolic link targets
during both creation and extraction. Tar 1.19 used them only
during extraction.
For a detailed description, see chapter 6.7 "Modifying File and Member
Names".
* Info (end-of-volume) scripts
The value of the blocking factor is made available to info and
checkpoint scripts via environment variable TAR_BLOCKING_FACTOR.
* Incremental archives
Improved (sped up) extracting from incremental archives.
* Bugfixes.
** Fix bug introduced in version 1.19: tar refused to update non-existing
archives.
version 1.19 - Sergey Poznyakoff, 2007-10-10
@@ -932,7 +1064,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, 2007 Free Software Foundation, Inc.
2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GNU tar.

11
THANKS
View File

@@ -102,9 +102,11 @@ Clinton Carr clint@netcom.com
Conrad Hughes chughes@maths.tcd.ie
Constantin Belous const@cris.net
Coranth Gryphon gryphon@bur.visidyne.com
Cyril Strejc strejc@unicontrols.cz
Dale R. Worley worley@world.std.com
Dale Wiles wiles@geordi.calspan.com
Dan Bloch dan@transarc.com
Dan Drake dan@dandrake.org
Dan Reish dreish@izzy.net
Daniel Hagerty hag@gnu.org
Daniel Quinlan quinlan@pathname.com
@@ -145,12 +147,14 @@ Drew Sullivan drew@sni.ca
Drew Trieger trieger@woodstock.abbott.com
Dunstan Vavasour dev@cegelecproj.co.uk
Ed Childs echilds@bgs.com
Ed Leaver ewleaver@comcast.net
Edgar Taube et@immd8.informatik.uni-erlangen.de
Eduardo Kortright eduardo@cs.ua.edu
Eduardo V. de Rivas eddie@asterion.com
Edward Welbourne eddy@gen.cam.ac.uk
Elmar Heeb heeb@itp.ethz.ch
Elmer Fittery elmerf@ptw.com
Enric Hernandez ehernandez@notariado.org
Eric Backus ericb@lsid.hp.com
Eric Benson eb@amazon.com
Eric Blake ebb9@byu.net
@@ -217,10 +221,12 @@ Janne Snabb snabb@niksula.hut.fi
Jason R. Mastaler jason@webmaster.net
Jason Armistead Jason.Armistead@otis.com
Jay Fenlason hack@gnu.org
Jean-Louis Martineau martineau@zmanda.com
Jean-Michel Soenen soenen@lectra.fr
Jean-Ph. Martin-Flatin syj@ecmwf.int
Jean-loup Gailly jloup@chorus.fr
Jean-Loup Gailly jloup@chorus.fr
Jeff Moskow jeff@rtr.com
Jean-Ph. Martin-Flatin syj@ecmwf.int
Jean-Pierre Demailly Jean-Pierre.Demailly@ujf-grenoble.fr
Jeff Prothero jsp@betz.biostr.washington.edu
Jeff Siegel js@hornet.att.com
Jeff Sorensen sorenj@alumni.rpi.edu
@@ -290,6 +296,7 @@ Konno Hiroharu konno@pac.co.jp
Kurt Jaeger pi@lf.net
Larry Creech lcreech@lonestar.rcclub.org
Larry Schwimmer rosebud@cyclone.stanford.edu
Lasse Collin lasse.collin@tukaani.org
Laurent Caillat-Vallet caillat@noe.lyon.cemagref.fr
Laurent Sainte-Marthe smarthe@genethon.fr
Leland Lucius llucius@tiny.net

152
bootstrap
View File

@@ -49,9 +49,9 @@ Options:
--force Attempt to bootstrap even if the sources seem
not to have been checked out.
--skip-po Do not download po files.
--update-po[=LANG] Update po file(s) and exit.
--update-po Update po files and exit.
--cvs-user=USERNAME Set the CVS username to be used when accessing
the gnulib repository.
the paxutils repository.
If the file bootstrap.conf exists in the current working directory, its
contents are read as shell variables to configure the bootstrap.
@@ -69,24 +69,34 @@ checkout() {
if [ ! -d $1 ]; then
echo "$0: getting $1 files..."
case ${CVS_AUTH-pserver} in
pserver)
CVS_PREFIX=':pserver:anonymous@';;
ssh)
CVS_PREFIX="$CVS_USER${CVS_USER+@}";;
*)
echo "$0: $CVS_AUTH: Unknown CVS access method" >&2
exit 1;;
esac
case $1 in
paxutils)
case ${CVS_AUTH-pserver} in
pserver)
CVS_PREFIX=':pserver:anonymous@';;
ssh)
CVS_PREFIX="$CVS_USER${CVS_USER+@}";;
*)
echo "$0: $CVS_AUTH: Unknown CVS access method" >&2
exit 1;;
esac
case $CVS_RSH in
'') CVS_RSH=ssh; export CVS_RSH;;
case $CVS_RSH in
'') CVS_RSH=ssh; export CVS_RSH;;
esac
CVSURL=${CVS_PREFIX}cvs.savannah.gnu.org:/cvsroot/"$1"
;;
gnulib)
CVSURL=:pserver:anonymous@pserver.git.sv.gnu.org:/gnulib.git
;;
esac
trap "cleanup $1" 1 2 13 15
cvs -z3 -q -d ${CVS_PREFIX}cvs.savannah.gnu.org:/cvsroot/"$1" co $1 ||
cleanup $1
cvs -z3 -q -d $CVSURL co $1 || cleanup $1
trap - 1 2 13 15
fi
@@ -106,11 +116,13 @@ gnulib_modules=
# Any gnulib files needed that are not in modules.
gnulib_files=
# Translation Project URL, for the registry of all projects
# and for the translation-team master directory.
tp_url() {
echo "http://translationproject.org/domain/$1.html"
}
# The command to download all .po files for a specified domain into
# a specified directory. Fill in the first %s is the domain name, and
# the second with the destination directory. Use rsync's -L and -r
# options because the latest/%s directory and the .po files within are
# all symlinks.
po_download_command_format=\
"rsync -Lrtvz 'translationproject.org::tp/latest/%s/' '%s'"
extract_package_name='
/^AC_INIT(/{
@@ -213,78 +225,60 @@ echo "$0: Bootstrapping CVS $package..."
# Get translations.
get_translations() {
download_po_files() {
subdir=$1
domain=$2
po_file=$3
case $WGET_COMMAND in
'')
echo "$0: wget not available; skipping translations";;
?*)
url=`tp_url $domain`
baseurl=`expr "$url" : '\(.*\)/.*'`
echo "$0: getting translations into $subdir for $domain..." &&
case $po_file in
'') (cd $subdir && rm -f dummy `ls | sed -n '/\.gmo$/p; /\.po/p'`);;
esac &&
$WGET_COMMAND -O "$subdir/$domain.html" "$url" &&
sed -n 's|.*href="\(.*\)/\([^/][^/]*\)/'"$domain"'-\([^/"]*\)\.[^."]*\.po".*|\2:\3:\1|p' <"$subdir/$domain.html" |
sort -t: -k 1,1 -k 2,2n -k2,2 -k3,3n -k3,3 -k4,4n -k4,4 -k5,5n -k5.5 |
awk -F: '
{ if (lang && $1 != lang) print lang, ver, $3 }
{ lang = $1; ver = $2 }
END { if (lang) print lang, ver, $3 }
' | awk -v domain="$domain" -v baseurl="$baseurl" -v subdir="$subdir" \
-v po_file="$po_file" '
{
lang = $1
if (po_file && po_file != (lang ".po")) next
ver = $2
printf "{ $WGET_COMMAND -O %s/%s.po %s/%s/%s/%s-%s.%s.po &&\n", subdir, lang, baseurl, $3, lang, domain, ver, lang
printf " msgfmt -c -o /dev/null %s/%s.po || {\n", subdir, lang
printf " echo >&2 '\'"$0"': omitting translation for %s'\''\n", lang
printf " rm -f %s/%s.po; }; } &&\n", subdir, lang
}
END { print ":" }
' | WGET_COMMAND="$WGET_COMMAND" sh
;;
esac &&
ls "$subdir"/*.po 2>/dev/null |
sed 's|.*/||; s|\.po$||' >"$subdir/LINGUAS" &&
rm -f "$subdir/$domain.html"
echo "$0: getting translations into $subdir for $domain..."
cmd=`printf "$po_download_command_format" "$domain" "$subdir"`
eval "$cmd"
}
case `wget --help` in
*'--no-cache'*)
WGET_COMMAND='wget -nv --no-cache';;
*'--cache=on/off'*)
WGET_COMMAND='wget -nv --cache=off';;
*'--non-verbose'*)
WGET_COMMAND='wget -nv';;
*)
WGET_COMMAND='';;
esac
# Download .po files to $po_dir/.reference and copy only the new
# or modified ones into $po_dir. Also update $po_dir/LINGUAS.
update_po_files() {
# Directory containing primary .po files.
# Overwrite them only when we're sure a .po file is new.
po_dir=$1
domain=$2
# Download *.po files into this dir.
# Usually contains *.s1 checksum files.
ref_po_dir="$po_dir/.reference"
test -d $ref_po_dir || mkdir $ref_po_dir || return
download_po_files $ref_po_dir $domain \
&& ls "$ref_po_dir"/*.po 2>/dev/null |
sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS"
langs=`cd $ref_po_dir && echo *.po|sed 's/\.po//g'`
test "$langs" = '*' && langs=x
for po in `cd $ref_po_dir && echo *.po|sed 's/\.po//g'`; do
case $po in x) continue;; esac
new_po="$ref_po_dir/$po.po"
cksum_file="$ref_po_dir/$po.s1"
if ! test -f "$cksum_file" ||
! test -f "$po_dir/$po.po" ||
! sha1sum -c --status "$cksum_file" < "$new_po" > /dev/null; then
echo "updated $po_dir/$po.po..."
cp "$new_po" "$po_dir/$po.po" && sha1sum < "$new_po" > "$cksum_file"
fi
done
}
case $DOWNLOAD_PO in
'skip')
;;
'')
get_translations po $package || exit
if test -d po; then
update_po_files po $package || exit
fi
;;
'only')
get_translations po $package
if test -d po; then
update_po_files po $package || exit
fi
exit
;;
*.po)
get_translations po $package "$DOWNLOAD_PO"
exit
;;
*)
get_translations po $package "${DOWNLOAD_PO}.po"
exit
esac
# Get paxutils files.

View File

@@ -1,7 +1,7 @@
# Configure template for GNU tar.
# Configure template for GNU tar. -*- autoconf -*-
# Copyright (C) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 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.19], [bug-tar@gnu.org])
AC_INIT([GNU tar], [1.21], [bug-tar@gnu.org])
AC_CONFIG_SRCDIR([src/tar.c])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h:config.hin])
@@ -87,7 +87,7 @@ gl_INIT
# paxutils modules
tar_PAXUTILS
AC_CHECK_FUNCS(fsync getdtablesize lstat mkfifo readlink strerror symlink setlocale utimes)
AC_CHECK_FUNCS(fsync getdtablesize lstat mkfifo readlink symlink setlocale utimes)
AC_CHECK_DECLS([getgrgid],,, [#include <grp.h>])
AC_CHECK_DECLS([getpwuid],,, [#include <pwd.h>])
AC_CHECK_DECLS([time],,, [#include <time.h>])

View File

@@ -31,7 +31,7 @@ tar_TEXINFOS = \
snapshot.texi\
sparse.texi\
value.texi
EXTRA_DIST = gendocs_template mastermenu.el texify.sed
EXTRA_DIST = gendocs_template mastermenu.el texify.sed untabify.el
# The rendering level is anyone of PUBLISH, DISTRIB or PROOF.
# Just call `make RENDITION=PROOF [target]' if you want PROOF rendition.
@@ -46,6 +46,18 @@ header.texi: $(top_srcdir)/src/tar.h
master-menu: $(tar_TEXINFOS)
emacs -batch -l mastermenu.el -f make-master-menu $(info_TEXINFOS)
untabify:
emacs -batch -l untabify.el $(info_TEXINFOS) $(tar_TEXINFOS)
final: untabify master-menu
# Checking
check-format:
@if test -n "`cat $(info_TEXINFOS) $(tar_TEXINFOS) | tr -d -c '\t'`"; then \
echo "Sources contain tabs; run make untabify"; \
false; \
fi
check-options:
@ARGP_HELP_FMT='usage-indent=0,short-opt-col=0,long-opt-col=0,\
doc-opt-col=0,opt-doc-col=0,header-col=0,rmargin=1' \
@@ -67,6 +79,52 @@ doc-opt-col=0,opt-doc-col=0,header-col=0,rmargin=1' \
fi;\
rm report.$$$$
check-refs:
@for file in $(info_TEXINFOS) $(tar_TEXINFOS); \
do \
sed -e = $$file | \
sed -n 'N;/@FIXME-.*ref/{s/\(^[0-9][0-9]*\).*@FIXME-.*ref{\([^}]*\).*/'$$file':\1: \2/gp}'; \
done > $@-t; \
if [ -s $@-t ]; then \
echo "Unresolved cross-references:"; \
cat $@-t;\
rm $@-t; \
else \
rm -f $@-t; \
fi
check-fixmes:
@for file in $(info_TEXINFOS); \
do \
sed -e = $$file | \
sed -n 'N;/@FIXME{/{s/\(^[0-9][0-9]*\).*@FIXME{\([^}]*\).*/'$$file':\1: \2/gp}'; \
done > $@-t; \
if [ -s $@-t ]; then \
echo "Unresolved FIXMEs:"; \
cat $@-t; \
rm $@-t; \
false; \
else \
rm -f $@-t; \
fi
check-unrevised:
@grep -Hn @UNREVISED $(info_TEXINFOS) > $@-t; \
if [ -s $@-t ]; then \
echo "Unrevised nodes:"; \
cat $@-t; \
rm $@-t; \
false;\
else \
rm $@-t; \
fi
all-check-docs: check-format check-options check-refs check-fixmes check-unrevised
check-docs:
$(MAKE) -k all-check-docs
#
clean-local:
rm -rf manual
@@ -82,5 +140,5 @@ manual:
TEXINPUTS=$(srcdir):$(top_srcdir)/build-tex:$(TEXINPUTS) \
MAKEINFO="$(MAKEINFO) $(MAKEINFOFLAGS)" \
TEXI2DVI="$(TEXI2DVI) -t @finalout" \
$(GENDOCS) tar 'GNU tar manual'
$(GENDOCS) --texi2html tar 'GNU tar manual'

View File

@@ -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.3 2007/01/19 15:41:39 gray Exp $ -->
<!-- $Id: gendocs_template,v 1.5 2007/10/30 14:58:52 gray Exp $ -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
@@ -30,23 +30,40 @@
alt=" [image of the head of a GNU] "
width="129" height="122" />
</a>
<a href="/philosophy/gif.html">(no gifs due to patent problems)</a>
</p>
<hr />
The manual for %%PACKAGE%% is available in the following formats:</p>
<p>The manual for %%PACKAGE%% is available in the following formats:</p>
<ul>
<li><a href="%%PACKAGE%%.html">HTML
(%%HTML_MONO_SIZE%%K characters)</a> - entirely on one web page.</li>
(%%HTML_MONO_SIZE%%K bytes)</a> - entirely on one web page.</li>
<li><a href="html_node/index.html">HTML</a> - with one web page per
node.</li>
%%IF HTML_SECTION%%
<li><a href="html_section/index.html">HTML</a> - with one web page per
section.</li>
%%ENDIF HTML_SECTION%%
%%IF HTML_CHAPTER%%
<li><a href="html_chapter/index.html">HTML</a> - with one web page per
chapter.</li>
%%ENDIF HTML_CHAPTER%%
<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
(%%HTML_NODE_TGZ_SIZE%%K gzipped tar file)</a> -
with one web page per node.</li>
%%IF HTML_SECTION%%
<li><a href="%%PACKAGE%%.html_section.tar.gz">HTML compressed
(%%HTML_SECTION_TGZ_SIZE%%K gzipped tar file)</a> -
with one web page per section.</li>
%%ENDIF HTML_SECTION%%
%%IF HTML_CHAPTER%%
<li><a href="%%PACKAGE%%.html_chapter.tar.gz">HTML compressed
(%%HTML_CHAPTER_TGZ_SIZE%%K gzipped tar file)</a> -
with one web page per chapter.</li>
%%ENDIF HTML_CHAPTER%%
<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
@@ -99,7 +116,7 @@ permitted in any medium, provided this notice is preserved.
<p>
Updated:
<!-- timestamp start -->
$Date: 2007/01/19 15:41:39 $ $Author: gray $
$Date: 2007/10/30 14:58:52 $ $Author: gray $
<!-- timestamp end -->
</p>
</div>

View File

@@ -36,8 +36,6 @@ Archives are permitted to have more than one member with the same
member name. One way this situation can occur is if more than one
version of a file has been stored in the archive. For information
about adding new versions of a file to an archive, see @ref{update}.
@FIXME-xref{To learn more about having more than one archive member with the
same name, see -backup node, when it's written.}
In addition to entries describing archive members, an archive may
contain entries which @command{tar} itself uses to store information.
@@ -108,11 +106,11 @@ group permission could be copied from the @emph{other} permission.
The @code{uid} and @code{gid} fields are the numeric user and group
@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.
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
particular the @option{--incremental} (@option{-G}) option.}
are archived with this field specified as zero.
The @code{mtime} field is the data modification time of the file at
the time it was archived. It is the ASCII representation of the octal

View File

@@ -72,19 +72,28 @@
@ifset PROOF
@strong{<REF>} \string\ @strong{</>}
@end ifset
@ifclear PROOF
@cite{\string\}
@end ifclear
@end macro
@macro FIXME-pxref{string}
@ifset PROOF
@strong{<PXREF>} \string\ @strong{</>}
See @strong{<PXREF>} \string\ @strong{</>}
@end ifset
@ifclear PROOF
See @cite{\string\}
@end ifclear
@end macro
@macro FIXME-xref{string}
@ifset PROOF
@strong{<XREF>} \string\ @strong{</>}
See @strong{<XREF>} \string\ @strong{</>}
@end ifset
@ifclear PROOF
See @cite{\string\}
@end ifclear
@end macro
@c End of rendition.texi

File diff suppressed because it is too large Load Diff

13
doc/untabify.el Normal file
View File

@@ -0,0 +1,13 @@
;;;; Untabify the sources.
;;;; Usage: emacs -batch -l untabify.el [file ...]
(defun global-untabify (buflist)
(mapcar
(lambda (bufname)
(set-buffer (find-file bufname))
(untabify (point-min) (point-max))
(save-buffer)
(kill-buffer (current-buffer)))
buflist))
(global-untabify command-line-args-left)

View File

@@ -13,6 +13,7 @@ exclude
exitfail
fileblocks
fnmatch-gnu
fseeko
ftruncate
full-write
getdate
@@ -38,6 +39,7 @@ safe-read
save-cwd
savedir
setenv
snprintf
stat-time
stdbool
stdint

View File

@@ -1,13 +1,10 @@
.cvsignore
.deps
Makefile
Makefile.in
__fpending.c
__fpending.h
alloca.c
alloca_.h
allocsa.c
allocsa.h
allocsa.valgrind
alloca.h
alloca.in.h
argmatch.c
argmatch.h
argp-ba.c
@@ -28,24 +25,31 @@ at-func.c
backupfile.c
backupfile.h
basename.c
c-ctype.c
c-ctype.h
canonicalize-lgpl.c
canonicalize.h
charset.alias
chdir-long.c
chdir-long.h
chown.c
close-stream.c
close-stream.h
close.c
closeout.c
closeout.h
config.charset
configmake.h
creat-safer.c
dirent_.h
dirent.h
dirent.in.h
dirfd.c
dirfd.h
dirname.c
dirname.h
dup-safer.c
dup2.c
errno.in.h
error.c
error.h
exclude.c
@@ -56,31 +60,39 @@ fchdir.c
fchmodat.c
fchown-stub.c
fchownat.c
fclose.c
fcntl--.h
fcntl-safer.h
fcntl_.h
fcntl.h
fcntl.in.h
fd-safer.c
fileblocks.c
float+.h
float_.h
float.h
float.in.h
fnmatch.c
fnmatch_.h
fnmatch.h
fnmatch.in.h
fnmatch_loop.c
fpending.c
fpending.h
fseeko.c
fstatat.c
ftruncate.c
full-write.c
full-write.h
getcwd.c
getdate.c
getdate.h
getdate.y
getdelim.c
getdelim.h
getline.c
getline.h
getopt.c
getopt.h
getopt.in.h
getopt1.c
getopt_.h
getopt_int.h
getpagesize.c
getpagesize.h
gettext.h
gettime.c
@@ -94,11 +106,12 @@ imaxtostr.c
intprops.h
inttostr.c
inttostr.h
inttypes_.h
inttypes.h
inttypes.in.h
lchown.c
lchown.h
localcharset.c
localcharset.h
lseek.c
lstat.c
lstat.h
malloc.c
@@ -122,6 +135,7 @@ obstack.c
obstack.h
offtostr.c
open-safer.c
open.c
openat-die.c
openat-priv.h
openat-proc.c
@@ -141,8 +155,13 @@ quote.c
quote.h
quotearg.c
quotearg.h
rawmemchr.c
rawmemchr.valgrind
readlink.c
realloc.c
ref-add.sed
ref-add.sin
ref-del.sed
ref-del.sin
regcomp.c
regex.c
@@ -151,6 +170,7 @@ regex_internal.c
regex_internal.h
regexec.c
rmdir.c
rmt-command.h
rmt.h
rpmatch.c
rtapelib.c
@@ -166,18 +186,30 @@ savedir.h
setenv.c
setenv.h
sleep.c
snprintf.c
stat-macros.h
stat-time.h
stdbool_.h
stdint_.h
stdio_.h
stdlib_.h
stdarg.in.h
stdbool.h
stdbool.in.h
stdint.h
stdint.in.h
stdio-impl.h
stdio-write.c
stdio.h
stdio.in.h
stdlib.h
stdlib.in.h
stpcpy.c
strcasecmp.c
strchrnul.c
strchrnul.valgrind
strdup.c
streq.h
strerror.c
string_.h
string.h
string.in.h
strings.in.h
stripslash.c
strncasecmp.c
strndup.c
@@ -190,21 +222,30 @@ strtoll.c
strtoul.c
strtoull.c
strtoumax.c
sys_stat_.h
sys_time_.h
sysexits_.h
sys
sys_stat.h
sys_stat.in.h
sys_time.h
sys_time.in.h
sysexits.h
sysexits.in.h
system-ioctl.h
system.h
tempname.c
tempname.h
time_.h
time.h
time.in.h
time_r.c
timespec.h
uinttostr.c
umaxtostr.c
unistd--.h
unistd-safer.h
unistd_.h
unistd.h
unistd.in.h
unitypes.h
uniwidth
uniwidth.h
unlinkdir.c
unlinkdir.h
unlocked-io.h
@@ -219,9 +260,12 @@ version-etc-fsf.c
version-etc.c
version-etc.h
vsnprintf.c
wchar_.h
wctype_.h
wcwidth.h
wchar.h
wchar.in.h
wctype.h
wctype.in.h
wcwidth.c
write.c
xalloc-die.c
xalloc.h
xgetcwd.c
@@ -230,6 +274,7 @@ xmalloc.c
xsize.h
xstrndup.c
xstrndup.h
xstrtol-error.c
xstrtol.c
xstrtol.h
xstrtoul.c

View File

@@ -22,10 +22,13 @@
lib/argmatch.c
lib/argp-help.c
lib/argp-parse.c
lib/closeout.c
lib/error.c
lib/getopt.c
lib/obstack.c
lib/human.c
lib/obstack.c
lib/openat-die.c
lib/paxerror.c
lib/paxexit.c
lib/paxnames.c
@@ -34,6 +37,8 @@ lib/rpmatch.c
lib/rtapelib.c
lib/xalloc-die.c
lib/xmalloc.c
lib/version-etc.c
lib/xalloc-die.c
rmt/rmt.c
@@ -51,6 +56,7 @@ src/names.c
src/tar.c
src/update.c
src/xheader.c
src/checkpoint.c
# Testsuite
tests/genfile.c

View File

@@ -23,6 +23,7 @@ bin_PROGRAMS = tar
noinst_HEADERS = arith.h common.h tar.h
tar_SOURCES = \
buffer.c\
checkpoint.c\
compare.c\
create.c\
delete.c\
@@ -33,6 +34,7 @@ tar_SOURCES = \
misc.c\
names.c\
sparse.c\
suffix.c\
system.c\
tar.c\
transform.c\

File diff suppressed because it is too large Load Diff

270
src/checkpoint.c Normal file
View File

@@ -0,0 +1,270 @@
/* Checkpoint management for 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 3, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <system.h>
#include "common.h"
enum checkpoint_opcode
{
cop_dot,
cop_bell,
cop_echo,
cop_ttyout,
cop_sleep,
cop_exec
};
struct checkpoint_action
{
struct checkpoint_action *next;
enum checkpoint_opcode opcode;
union
{
time_t time;
char *command;
} v;
};
/* Checkpointing counter */
static unsigned checkpoint;
/* List of checkpoint actions */
static struct checkpoint_action *checkpoint_action, *checkpoint_action_tail;
static struct checkpoint_action *
alloc_action (enum checkpoint_opcode opcode)
{
struct checkpoint_action *p = xzalloc (sizeof *p);
if (checkpoint_action_tail)
checkpoint_action_tail->next = p;
else
checkpoint_action = p;
checkpoint_action_tail = p;
p->opcode = opcode;
return p;
}
static char *
copy_string_unquote (const char *str)
{
char *output = xstrdup (str);
size_t len = strlen (output);
if ((*output == '"' || *output == '\'')
&& output[len-1] == *output)
{
memmove (output, output+1, len-2);
output[len-2] = 0;
}
unquote_string (output);
return output;
}
void
checkpoint_compile_action (const char *str)
{
struct checkpoint_action *act;
if (strcmp (str, ".") == 0 || strcmp (str, "dot") == 0)
alloc_action (cop_dot);
else if (strcmp (str, "bell") == 0)
alloc_action (cop_bell);
else if (strcmp (str, "echo") == 0)
alloc_action (cop_echo);
else if (strncmp (str, "echo=", 5) == 0)
{
act = alloc_action (cop_echo);
act->v.command = copy_string_unquote (str + 5);
}
else if (strncmp (str, "exec=", 5) == 0)
{
act = alloc_action (cop_exec);
act->v.command = copy_string_unquote (str + 5);
}
else if (strncmp (str, "ttyout=", 7) == 0)
{
act = alloc_action (cop_ttyout);
act->v.command = copy_string_unquote (str + 7);
}
else if (strncmp (str, "sleep=", 6) == 0)
{
char *p;
time_t n = strtoul (str+6, &p, 10);
if (*p)
FATAL_ERROR ((0, 0, _("%s: not a valid timeout"), str));
act = alloc_action (cop_sleep);
act->v.time = n;
}
else
FATAL_ERROR ((0, 0, _("%s: unknown checkpoint action"), str));
}
void
checkpoint_finish_compile ()
{
if (checkpoint_option)
{
if (!checkpoint_action)
/* Provide a historical default */
checkpoint_compile_action ("echo");
}
else if (checkpoint_action)
/* Otherwise, set default checkpoint rate */
checkpoint_option = DEFAULT_CHECKPOINT;
}
char *
expand_checkpoint_string (const char *input, bool do_write, unsigned cpn)
{
const char *opstr = do_write ? gettext ("write") : gettext ("read");
size_t opstrlen = strlen (opstr);
char uintbuf[UINTMAX_STRSIZE_BOUND];
char *cps = STRINGIFY_BIGINT (cpn, uintbuf);
size_t cpslen = strlen (cps);
const char *ip;
char *op;
char *output;
size_t outlen = strlen (input); /* Initial guess */
/* Fix the initial length guess */
for (ip = input; (ip = strchr (ip, '%')) != NULL; )
{
switch (ip[1])
{
case 'u':
outlen += cpslen - 2;
break;
case 's':
outlen += opstrlen - 2;
}
ip++;
}
output = xmalloc (outlen + 1);
for (ip = input, op = output; *ip; )
{
if (*ip == '%')
{
switch (*++ip)
{
case 'u':
op = stpcpy (op, cps);
break;
case 's':
op = stpcpy (op, opstr);
break;
default:
*op++ = '%';
*op++ = *ip;
break;
}
ip++;
}
else
*op++ = *ip++;
}
*op = 0;
return output;
}
static void
run_checkpoint_actions (bool do_write)
{
struct checkpoint_action *p;
FILE *tty = NULL;
for (p = checkpoint_action; p; p = p->next)
{
switch (p->opcode)
{
case cop_dot:
fputc ('.', stdlis);
fflush (stdlis);
break;
case cop_bell:
if (!tty)
tty = fopen ("/dev/tty", "w");
if (tty)
{
fputc ('\a', tty);
fflush (tty);
}
break;
case cop_echo:
{
char *tmp;
const char *str = p->v.command;
if (!str)
{
if (do_write)
/* TRANSLATORS: This is a ``checkpoint of write operation'',
*not* ``Writing a checkpoint''.
E.g. in Spanish ``Punto de comprobaci@'on de escritura'',
*not* ``Escribiendo un punto de comprobaci@'on'' */
str = gettext ("Write checkpoint %u");
else
/* TRANSLATORS: This is a ``checkpoint of read operation'',
*not* ``Reading a checkpoint''.
E.g. in Spanish ``Punto de comprobaci@'on de lectura'',
*not* ``Leyendo un punto de comprobaci@'on'' */
str = gettext ("Read checkpoint %u");
}
tmp = expand_checkpoint_string (str, do_write, checkpoint);
WARN ((0, 0, "%s", tmp));
free (tmp);
}
break;
case cop_ttyout:
if (!tty)
tty = fopen ("/dev/tty", "w");
if (tty)
{
char *tmp = expand_checkpoint_string (p->v.command, do_write,
checkpoint);
fprintf (tty, "%s", tmp);
fflush (tty);
free (tmp);
}
break;
case cop_sleep:
sleep (p->v.time);
break;
case cop_exec:
sys_exec_checkpoint_script (p->v.command,
archive_name_cursor[0],
checkpoint);
break;
}
}
if (tty)
fclose (tty);
}
void
checkpoint_run (bool do_write)
{
if (checkpoint_option && !(++checkpoint % checkpoint_option))
run_checkpoint_actions (do_write);
}

View File

@@ -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, 2007 Free Software Foundation, Inc.
2003, 2004, 2005, 2006, 2007, 2008 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
@@ -93,9 +93,6 @@ GLOBAL enum subcommand subcommand_option;
/* Selected format for output archive. */
GLOBAL enum archive_format archive_format;
/* Either NL or NUL, as decided by the --null option. */
GLOBAL char filename_terminator;
/* Size of each record, once in blocks, once in bytes. Those two variables
are always related, the second being BLOCKSIZE times the first. They do
not have _option in their name, even if their values is derived from
@@ -130,19 +127,13 @@ GLOBAL enum backup_type backup_type;
GLOBAL bool block_number_option;
GLOBAL unsigned checkpoint_option;
enum checkpoint_style
{
checkpoint_text,
checkpoint_dot
};
GLOBAL enum checkpoint_style checkpoint_style;
#define DEFAULT_CHECKPOINT 10
/* Specified name of compression program, or "gzip" as implied by -z. */
GLOBAL const char *use_compress_program_option;
GLOBAL bool dereference_option;
GLOBAL bool hard_dereference_option;
/* Print a message if not all links are dumped */
GLOBAL int check_links_option;
@@ -194,6 +185,8 @@ GLOBAL enum old_files old_files_option;
/* Specified file name for incremental list. */
GLOBAL const char *listed_incremental_option;
/* Check device numbers when doing incremental dumps. */
GLOBAL bool check_device_option;
/* Specified mode change string. */
GLOBAL struct mode_change *mode_option;
@@ -493,8 +486,18 @@ bool rename_directory (char *src, char *dst);
void delete_archive_members (void);
/* Module incremen.c. */
typedef struct dumpdir *dumpdir_t;
typedef struct dumpdir_iter *dumpdir_iter_t;
char *get_directory_contents (char *dir_name, dev_t device);
dumpdir_t dumpdir_create0 (const char *contents, const char *cmask);
dumpdir_t dumpdir_create (const char *contents);
void dumpdir_free (dumpdir_t);
char *dumpdir_locate (dumpdir_t dump, const char *name);
char *dumpdir_next (dumpdir_iter_t itr);
char *dumpdir_first (dumpdir_t dump, int all, dumpdir_iter_t *pitr);
const char *get_directory_contents (char *dir_name, dev_t device);
const char *append_incremental_renames (const char *dump);
void read_directory_file (void);
void write_directory_file (void);
@@ -696,8 +699,7 @@ char *xheader_format_name (struct tar_stat_info *st, const char *fmt,
void sys_detect_dev_null_output (void);
void sys_save_archive_dev_ino (void);
void sys_drain_input_pipe (void);
void sys_wait_for_child (pid_t);
void sys_wait_for_child (pid_t, bool);
void sys_spawn_shell (void);
bool sys_compare_uid (struct stat *a, struct stat *b);
bool sys_compare_gid (struct stat *a, struct stat *b);
@@ -711,6 +713,9 @@ bool sys_get_archive_stat (void);
int sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st);
void sys_wait_command (void);
int sys_exec_info_script (const char **archive_name, int volume_number);
void sys_exec_checkpoint_script (const char *script_name,
const char *archive_name,
int checkpoint_number);
/* Module compare.c */
void report_difference (struct tar_stat_info *st, const char *message, ...);
@@ -729,14 +734,21 @@ 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;
#define XFORM_REGFILE 0x01
#define XFORM_LINK 0x02
#define XFORM_SYMLINK 0x04
#define XFORM_ALL (XFORM_REGFILE|XFORM_LINK|XFORM_SYMLINK)
void set_transform_expr (const char *expr);
bool transform_name (char **pinput);
bool transform_member_name (char **pinput, xform_type type);
bool transform_name_fp (char **pinput, char *(*fun)(char *, void *), void *);
bool transform_name (char **pinput, int type);
bool transform_member_name (char **pinput, int type);
bool transform_name_fp (char **pinput, int type,
char *(*fun)(char *, void *), void *);
/* Module suffix.c */
void set_comression_program_by_suffix (const char *name, const char *defprog);
/* Module checkpoint.c */
void checkpoint_compile_action (const char *str);
void checkpoint_finish_compile (void);
void checkpoint_run (bool do_write);

View File

@@ -366,7 +366,7 @@ dumpdir_cmp (const char *a, const char *b)
static void
diff_dumpdir (void)
{
char *dumpdir_buffer;
const char *dumpdir_buffer;
dev_t dev = 0;
struct stat stat_data;
@@ -597,9 +597,23 @@ verify_volume (void)
"VERIFY FAILURE: %d invalid headers detected",
counter), counter));
}
if (status == HEADER_ZERO_BLOCK || status == HEADER_END_OF_FILE)
if (status == HEADER_END_OF_FILE)
break;
if (status == HEADER_ZERO_BLOCK)
{
set_next_block_after (current_header);
if (!ignore_zeros_option)
{
char buf[UINTMAX_STRSIZE_BOUND];
status = read_header (false);
if (status == HEADER_ZERO_BLOCK)
break;
WARN ((0, 0, _("A lone zero block at %s"),
STRINGIFY_BIGINT (current_block_ordinal (), buf)));
}
}
diff_archive ();
tar_stat_destroy (&current_stat_info);
}

View File

@@ -1041,7 +1041,7 @@ dump_regular_file (int fd, struct tar_stat_info *st)
while (size_left > 0)
{
size_t bufsize, count;
mv_size_left (size_left);
blk = find_next_block ();
@@ -1422,6 +1422,8 @@ dump_hard_link (struct tar_stat_info *st)
static void
file_count_links (struct tar_stat_info *st)
{
if (hard_dereference_option)
return;
if (st->stat.st_nlink > 1)
{
struct link *duplicate;
@@ -1493,7 +1495,7 @@ dump_file0 (struct tar_stat_info *st, const char *p,
assign_string (&st->file_name,
safer_name_suffix (p, false, absolute_names_option));
transform_name (&st->file_name);
transform_name (&st->file_name, XFORM_REGFILE);
if (deref_stat (dereference_option, p, &st->stat) != 0)
{
@@ -1614,6 +1616,7 @@ dump_file0 (struct tar_stat_info *st, const char *p,
case dump_status_ok:
case dump_status_short:
mv_end ();
file_count_links (st);
break;
case dump_status_fail:
@@ -1623,8 +1626,6 @@ dump_file0 (struct tar_stat_info *st, const char *p,
abort ();
}
file_count_links (st);
ok = status == dump_status_ok;
}
@@ -1704,6 +1705,7 @@ dump_file0 (struct tar_stat_info *st, const char *p,
}
buffer[size] = '\0';
assign_string (&st->link_name, buffer);
transform_name (&st->link_name, XFORM_SYMLINK);
if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size)
write_long_link (st);
@@ -1712,7 +1714,7 @@ dump_file0 (struct tar_stat_info *st, const char *p,
header = start_header (st);
if (!header)
return;
tar_copy_str (header->header.linkname, buffer, NAME_FIELD_SIZE);
tar_copy_str (header->header.linkname, st->link_name, NAME_FIELD_SIZE);
header->header.typeflag = SYMTYPE;
finish_header (st, header, block_ordinal);
/* nothing more to do to it */

View File

@@ -917,7 +917,6 @@ extract_link (char *file_name, int typeflag)
int interdir_made = 0;
char const *link_name;
transform_member_name (&current_stat_info.link_name, xform_link);
link_name = current_stat_info.link_name;
if (! absolute_names_option && contains_dot_dot (link_name))
@@ -974,8 +973,6 @@ extract_symlink (char *file_name, int typeflag)
int status;
int interdir_made = 0;
transform_member_name (&current_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)))

View File

@@ -1,7 +1,7 @@
/* GNU dump extensions to tar.
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
2003, 2004, 2005, 2006, 2007, 2008 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
@@ -49,14 +49,23 @@ enum children
#define DIR_SET_FLAG(d,f) (d)->flags |= (f)
#define DIR_CLEAR_FLAG(d,f) (d)->flags &= ~(f)
struct dumpdir /* Dump directory listing */
{
char *contents; /* Actual contents */
size_t total; /* Total number of elements */
size_t elc; /* Number of D/N/Y elements. */
char **elv; /* Array of D/N/Y elements */
};
/* Directory attributes. */
struct directory
{
struct directory *next;
struct timespec mtime; /* Modification time */
dev_t device_number; /* device number for directory */
ino_t inode_number; /* inode number for directory */
char *contents; /* Directory contents */
char *icontents; /* Initial contents if the directory was
struct dumpdir *dump; /* Directory contents */
struct dumpdir *idump; /* Initial contents if the directory was
rescanned */
enum children children; /* What to save under this directory */
unsigned flags; /* See DIRF_ macros above */
@@ -64,9 +73,132 @@ struct directory
the original directory structure */
const char *tagfile; /* Tag file, if the directory falls under
exclusion_tag_under */
char name[1]; /* file name of directory */
char *name; /* file name of directory */
};
struct dumpdir *
dumpdir_create0 (const char *contents, const char *cmask)
{
struct dumpdir *dump;
size_t i, total, ctsize, len;
char *p;
const char *q;
for (i = 0, total = 0, ctsize = 1, q = contents; *q; total++, q += len)
{
len = strlen (q) + 1;
ctsize += len;
if (!cmask || strchr (cmask, *q))
i++;
}
dump = xmalloc (sizeof (*dump) + ctsize);
dump->contents = (char*)(dump + 1);
memcpy (dump->contents, contents, ctsize);
dump->total = total;
dump->elc = i;
dump->elv = xcalloc (i + 1, sizeof (dump->elv[0]));
for (i = 0, p = dump->contents; *p; p += strlen (p) + 1)
{
if (!cmask || strchr (cmask, *p))
dump->elv[i++] = p + 1;
}
dump->elv[i] = NULL;
return dump;
}
struct dumpdir *
dumpdir_create (const char *contents)
{
return dumpdir_create0 (contents, "YND");
}
void
dumpdir_free (struct dumpdir *dump)
{
free (dump->elv);
free (dump);
}
static int
compare_dirnames (const void *first, const void *second)
{
char const *const *name1 = first;
char const *const *name2 = second;
return strcmp (*name1, *name2);
}
/* Locate NAME in the dumpdir array DUMP.
Return pointer to the slot in DUMP->contents, or NULL if not found */
char *
dumpdir_locate (struct dumpdir *dump, const char *name)
{
char **ptr;
if (!dump)
return NULL;
ptr = bsearch (&name, dump->elv, dump->elc, sizeof (dump->elv[0]),
compare_dirnames);
return ptr ? *ptr - 1: NULL;
}
struct dumpdir_iter
{
struct dumpdir *dump; /* Dumpdir being iterated */
int all; /* Iterate over all entries, not only D/N/Y */
size_t next; /* Index of the next element */
};
char *
dumpdir_next (struct dumpdir_iter *itr)
{
size_t cur = itr->next;
char *ret = NULL;
if (itr->all)
{
ret = itr->dump->contents + cur;
if (*ret == 0)
return NULL;
itr->next += strlen (ret) + 1;
}
else if (cur < itr->dump->elc)
{
ret = itr->dump->elv[cur] - 1;
itr->next++;
}
return ret;
}
char *
dumpdir_first (struct dumpdir *dump, int all, struct dumpdir_iter **pitr)
{
struct dumpdir_iter *itr = xmalloc (sizeof (*itr));
itr->dump = dump;
itr->all = all;
itr->next = 0;
*pitr = itr;
return dumpdir_next (itr);
}
/* Return size in bytes of the dumpdir array P */
size_t
dumpdir_size (const char *p)
{
size_t totsize = 0;
while (*p)
{
size_t size = strlen (p) + 1;
totsize += size;
p += size;
}
return totsize + 1;
}
static struct directory *dirhead, *dirtail;
static Hash_table *directory_table;
static Hash_table *directory_meta_table;
@@ -118,27 +250,78 @@ static struct directory *
make_directory (const char *name)
{
size_t namelen = strlen (name);
size_t size = offsetof (struct directory, name) + namelen + 1;
struct directory *directory = xmalloc (size);
directory->contents = directory->icontents = NULL;
struct directory *directory = xmalloc (sizeof (*directory));
directory->next = NULL;
directory->dump = directory->idump = NULL;
directory->orig = NULL;
directory->flags = false;
strcpy (directory->name, name);
if (ISSLASH (directory->name[namelen-1]))
directory->name[namelen-1] = 0;
if (namelen && ISSLASH (name[namelen - 1]))
namelen--;
directory->name = xmalloc (namelen + 1);
memcpy (directory->name, name, namelen);
directory->name[namelen] = 0;
directory->tagfile = NULL;
return directory;
}
static void
free_directory (struct directory *dir)
{
free (dir->name);
free (dir);
}
static struct directory *
attach_directory (const char *name)
{
struct directory *dir = make_directory (name);
if (dirtail)
dirtail->next = dir;
else
dirhead = dir;
dirtail = dir;
return dir;
}
static void
replace_prefix (char **pname, const char *samp, size_t slen,
const char *repl, size_t rlen)
{
char *name = *pname;
size_t nlen = strlen (name);
if (nlen > slen && memcmp (name, samp, slen) == 0 && ISSLASH (name[slen]))
{
if (rlen > slen)
{
name = xrealloc (name, nlen - slen + rlen + 1);
*pname = name;
}
memmove (name + rlen, name + slen, nlen - slen + 1);
memcpy (name, repl, rlen);
}
}
void
dirlist_replace_prefix (const char *pref, const char *repl)
{
struct directory *dp;
size_t pref_len = strlen (pref);
size_t repl_len = strlen (repl);
for (dp = dirhead; dp; dp = dp->next)
replace_prefix (&dp->name, pref, pref_len, repl, repl_len);
}
/* Create and link a new directory entry for directory NAME, having a
device number DEV and an inode number INO, with NFS indicating
whether it is an NFS device and FOUND indicating whether we have
found that the directory exists. */
static struct directory *
note_directory (char const *name, struct timespec mtime,
dev_t dev, ino_t ino, bool nfs, bool found, char *contents)
dev_t dev, ino_t ino, bool nfs, bool found,
const char *contents)
{
struct directory *directory = make_directory (name);
struct directory *directory = attach_directory (name);
directory->mtime = mtime;
directory->device_number = dev;
@@ -149,13 +332,9 @@ note_directory (char const *name, struct timespec mtime,
if (found)
DIR_SET_FLAG (directory, DIRF_FOUND);
if (contents)
{
size_t size = dumpdir_size (contents);
directory->contents = xmalloc (size);
memcpy (directory->contents, contents, size);
}
directory->dump = dumpdir_create (contents);
else
directory->contents = NULL;
directory->dump = NULL;
if (! ((directory_table
|| (directory_table = hash_initialize (0, 0,
@@ -185,7 +364,7 @@ find_directory (const char *name)
{
struct directory *dir = make_directory (name);
struct directory *ret = hash_lookup (directory_table, dir);
free (dir);
free_directory (dir);
return ret;
}
}
@@ -204,7 +383,7 @@ find_directory_meta (dev_t dev, ino_t ino)
dir->device_number = dev;
dir->inode_number = ino;
ret = hash_lookup (directory_meta_table, dir);
free (dir);
free_directory (dir);
return ret;
}
}
@@ -250,7 +429,8 @@ procdir (char *name_buffer, struct stat *stat_data,
directories, consider all NFS devices as equal,
relying on the i-node to establish differences. */
if (! (((DIR_IS_NFS (directory) & nfs)
if (! ((!check_device_option
|| (DIR_IS_NFS (directory) && nfs)
|| directory->device_number == stat_data->st_dev)
&& directory->inode_number == stat_data->st_ino))
{
@@ -259,12 +439,16 @@ procdir (char *name_buffer, struct stat *stat_data,
stat_data->st_ino);
if (d)
{
if (verbose_option)
WARN ((0, 0, _("%s: Directory has been renamed from %s"),
quotearg_colon (name_buffer),
quote_n (1, d->name)));
directory->orig = d;
DIR_SET_FLAG (directory, DIRF_RENAMED);
if (strcmp (d->name, name_buffer))
{
if (verbose_option)
WARN ((0, 0, _("%s: Directory has been renamed from %s"),
quotearg_colon (name_buffer),
quote_n (1, d->name)));
directory->orig = d;
DIR_SET_FLAG (directory, DIRF_RENAMED);
dirlist_replace_prefix (d->name, name_buffer);
}
directory->children = CHANGED_CHILDREN;
}
else
@@ -299,12 +483,16 @@ procdir (char *name_buffer, struct stat *stat_data,
if (d)
{
if (verbose)
WARN ((0, 0, _("%s: Directory has been renamed from %s"),
quotearg_colon (name_buffer),
quote_n (1, d->name)));
directory->orig = d;
DIR_SET_FLAG (directory, DIRF_RENAMED);
if (strcmp (d->name, name_buffer))
{
if (verbose)
WARN ((0, 0, _("%s: Directory has been renamed from %s"),
quotearg_colon (name_buffer),
quote_n (1, d->name)));
directory->orig = d;
DIR_SET_FLAG (directory, DIRF_RENAMED);
dirlist_replace_prefix (d->name, name_buffer);
}
directory->children = CHANGED_CHILDREN;
}
else
@@ -336,8 +524,7 @@ procdir (char *name_buffer, struct stat *stat_data,
{
const char *tag_file_name;
size_t len;
switch (check_exclusion_tags (name_buffer, &tag_file_name))
{
case exclusion_tag_all:
@@ -356,13 +543,13 @@ procdir (char *name_buffer, struct stat *stat_data,
_("contents not dumped"));
directory->children = NO_CHILDREN;
break;
case exclusion_tag_under:
exclusion_tag_warning (name_buffer, tag_file_name,
_("contents not dumped"));
directory->tagfile = tag_file_name;
break;
case exclusion_tag_none:
break;
}
@@ -371,64 +558,15 @@ procdir (char *name_buffer, struct stat *stat_data,
return directory;
}
/* Locate NAME in the dumpdir array DUMP.
Return pointer to the slot in the array, or NULL if not found */
const char *
dumpdir_locate (const char *dump, const char *name)
{
if (dump)
while (*dump)
{
/* Ignore 'R' (rename) and 'X' (tempname) entries, since they break
alphabetical ordering.
They normally do not occur in dumpdirs from the snapshot files,
but this function is also used by purge_directory, which operates
on a dumpdir from the archive, hence the need for this test. */
if (!strchr ("RX", *dump))
{
int rc = strcmp (dump + 1, name);
if (rc == 0)
return dump;
if (rc > 1)
break;
}
dump += strlen (dump) + 1;
}
return NULL;
}
/* Return size in bytes of the dumpdir array P */
size_t
dumpdir_size (const char *p)
{
size_t totsize = 0;
while (*p)
{
size_t size = strlen (p) + 1;
totsize += size;
p += size;
}
return totsize + 1;
}
static int
compare_dirnames (const void *first, const void *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
build a new dumpdir template.
DIR must be returned by a previous call to savedir().
File names in DIRECTORY->contents must be sorted
File names in DIRECTORY->dump->contents must be sorted
alphabetically.
DIRECTORY->contents is replaced with the created template. Each entry is
DIRECTORY->dump is replaced with the created template. Each entry is
prefixed with ' ' if it was present in DUMP and with 'Y' otherwise. */
void
@@ -440,15 +578,15 @@ makedumpdir (struct directory *directory, const char *dir)
const char *p;
char const **array;
char *new_dump, *new_dump_ptr;
const char *dump;
struct dumpdir *dump;
if (directory->children == ALL_CHILDREN)
dump = NULL;
else if (DIR_IS_RENAMED (directory))
dump = directory->orig->icontents ?
directory->orig->icontents : directory->orig->contents;
dump = directory->orig->idump ?
directory->orig->idump : directory->orig->dump;
else
dump = directory->contents;
dump = directory->dump;
/* Count the size of DIR and the number of elements it contains */
dirsize = 0;
@@ -476,11 +614,10 @@ makedumpdir (struct directory *directory, const char *dir)
{
if (directory->tagfile)
*new_dump_ptr = strcmp (directory->tagfile, array[i]) == 0 ?
' ' : 'I';
' ' : 'I';
else
*new_dump_ptr = ' ';
new_dump_ptr++;
dump = loc + strlen (loc) + 1;
}
else if (directory->tagfile)
*new_dump_ptr++ = strcmp (directory->tagfile, array[i]) == 0 ?
@@ -493,13 +630,13 @@ makedumpdir (struct directory *directory, const char *dir)
;
}
*new_dump_ptr = 0;
directory->icontents = directory->contents;
directory->contents = new_dump;
directory->idump = directory->dump;
directory->dump = dumpdir_create0 (new_dump, NULL);
free (array);
}
/* Recursively scan the given directory. */
static char *
static const char *
scan_directory (char *dir, dev_t device)
{
char *dirp = savedir (dir); /* for scanning directory */
@@ -508,7 +645,7 @@ scan_directory (char *dir, dev_t device)
size_t name_length; /* used length in name_buffer */
struct stat stat_data;
struct directory *directory;
if (! dirp)
savedir_error (dir);
@@ -532,18 +669,20 @@ scan_directory (char *dir, dev_t device)
directory = procdir (name_buffer, &stat_data, device, NO_CHILDREN, false,
NULL);
if (dirp && directory->children != NO_CHILDREN)
{
char *entry; /* directory entry being scanned */
char *entry; /* directory entry being scanned */
size_t entrylen; /* length of directory entry */
dumpdir_iter_t itr;
makedumpdir (directory, dirp);
for (entry = directory->contents;
(entrylen = strlen (entry)) != 0;
entry += entrylen + 1)
for (entry = dumpdir_first (directory->dump, 1, &itr);
entry;
entry = dumpdir_next (itr))
{
entrylen = strlen (entry);
if (name_buffer_size <= entrylen - 1 + name_length)
{
do
@@ -590,16 +729,17 @@ scan_directory (char *dir, dev_t device)
*entry = 'Y';
}
}
free (itr);
}
free (name_buffer);
if (dirp)
free (dirp);
return directory->contents;
return directory->dump ? directory->dump->contents : NULL;
}
char *
const char *
get_directory_contents (char *dir, dev_t device)
{
return scan_directory (dir, device);
@@ -622,12 +762,9 @@ obstack_code_rename (struct obstack *stk, char *from, char *to)
obstack_grow (stk, s, strlen (s) + 1);
}
static bool
rename_handler (void *data, void *proc_data)
static void
store_rename (struct directory *dir, struct obstack *stk)
{
struct directory *dir = data;
struct obstack *stk = proc_data;
if (DIR_IS_RENAMED (dir))
{
struct directory *prev, *p;
@@ -666,7 +803,6 @@ rename_handler (void *data, void *proc_data)
obstack_code_rename (stk, "", prev->name);
}
}
return true;
}
const char *
@@ -674,8 +810,9 @@ append_incremental_renames (const char *dump)
{
struct obstack stk;
size_t size;
if (directory_table == NULL)
struct directory *dp;
if (dirhead == NULL)
return dump;
obstack_init (&stk);
@@ -687,7 +824,9 @@ append_incremental_renames (const char *dump)
else
size = 0;
hash_do_for_each (directory_table, rename_handler, &stk);
for (dp = dirhead; dp; dp = dp->next)
store_rename (dp, &stk);
if (obstack_object_size (&stk) != size)
{
obstack_1grow (&stk, 0);
@@ -1171,14 +1310,16 @@ write_directory_file_entry (void *entry, void *data)
fwrite (s, strlen (s) + 1, 1, fp);
fwrite (directory->name, strlen (directory->name) + 1, 1, fp);
if (directory->contents)
if (directory->dump)
{
char *p;
for (p = directory->contents; *p; p += strlen (p) + 1)
{
if (strchr ("YND", *p))
fwrite (p, strlen (p) + 1, 1, fp);
}
const char *p;
dumpdir_iter_t itr;
for (p = dumpdir_first (directory->dump, 0, &itr);
p;
p = dumpdir_next (itr))
fwrite (p, strlen (p) + 1, 1, fp);
free (itr);
}
fwrite ("\0\0", 2, 1, fp);
}
@@ -1366,6 +1507,7 @@ try_purge_directory (char const *directory_name)
char *current_dir;
char *cur, *arc, *p;
char *temp_stub = NULL;
struct dumpdir *dump;
if (!is_dumpdir (&current_stat_info))
return false;
@@ -1417,12 +1559,12 @@ try_purge_directory (char const *directory_name)
This is an extra safety precaution. Besides, it might be
necessary to extract from archives created with tar versions
prior to 1.19. */
if (*src)
src = safer_name_suffix (src, false, absolute_names_option);
if (*dst)
dst = safer_name_suffix (dst, false, absolute_names_option);
if (*src == 0)
src = temp_stub;
else if (*dst == 0)
@@ -1442,6 +1584,7 @@ try_purge_directory (char const *directory_name)
free (temp_stub);
/* Process deletes */
dump = dumpdir_create (current_stat_info.dumpdir);
p = NULL;
for (cur = current_dir; *cur; cur += strlen (cur) + 1)
{
@@ -1463,7 +1606,7 @@ try_purge_directory (char const *directory_name)
continue;
}
if (!(entry = dumpdir_locate (current_stat_info.dumpdir, cur))
if (!(entry = dumpdir_locate (dump, cur))
|| (*entry == 'D' && !S_ISDIR (st.st_mode))
|| (*entry == 'Y' && S_ISDIR (st.st_mode)))
{
@@ -1489,7 +1632,8 @@ try_purge_directory (char const *directory_name)
}
}
free (p);
dumpdir_free (dump);
free (current_dir);
return true;
}

View File

@@ -301,8 +301,8 @@ read_header_primitive (bool raw_extended_headers, struct tar_stat_info *info)
size_t size, written;
union block *next_long_name = 0;
union block *next_long_link = 0;
size_t next_long_name_blocks;
size_t next_long_link_blocks;
size_t next_long_name_blocks = 0;
size_t next_long_link_blocks = 0;
while (1)
{
@@ -472,11 +472,11 @@ read_header (bool raw_extended_headers)
static char *
decode_xform (char *file_name, void *data)
{
xform_type type = *(xform_type*)data;
int type = *(int*)data;
switch (type)
{
case xform_symlink:
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
@@ -484,11 +484,11 @@ decode_xform (char *file_name, void *data)
proper. */
return file_name;
case xform_link:
case XFORM_LINK:
file_name = safer_name_suffix (file_name, true, absolute_names_option);
break;
case xform_regfile:
case XFORM_REGFILE:
file_name = safer_name_suffix (file_name, false, absolute_names_option);
break;
}
@@ -505,9 +505,9 @@ decode_xform (char *file_name, void *data)
}
bool
transform_member_name (char **pinput, xform_type type)
transform_member_name (char **pinput, int type)
{
return transform_name_fp (pinput, decode_xform, &type);
return transform_name_fp (pinput, type, decode_xform, &type);
}
#define ISOCTAL(c) ((c)>='0'&&(c)<='7')
@@ -628,7 +628,16 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
stat_info->is_dumpdir = true;
}
transform_member_name (&stat_info->file_name, xform_regfile);
transform_member_name (&stat_info->file_name, XFORM_REGFILE);
switch (header->header.typeflag)
{
case SYMTYPE:
transform_member_name (&stat_info->link_name, XFORM_SYMLINK);
break;
case LNKTYPE:
transform_member_name (&stat_info->link_name, XFORM_LINK);
}
}
/* Convert buffer at WHERE0 of size DIGS from external format to

View File

@@ -289,9 +289,8 @@ static int matching_flags; /* exclude_fnmatch options */
static storage and can't be relied upon across two calls.
If CHANGE_DIRS is true, treat any entries of type NELT_CHDIR as
the request to change to the given directory. If filename_terminator
is NUL, CHANGE_DIRS is effectively always false.
the request to change to the given directory.
Entries of type NELT_FMASK cause updates of the matching_flags
value. */
struct name_elt *
@@ -301,9 +300,6 @@ name_next_elt (int change_dirs)
const char *source;
char *cursor;
if (filename_terminator == '\0')
change_dirs = 0;
while (name_index != names)
{
struct name_elt *ep;
@@ -392,9 +388,7 @@ name_gather (void)
if (allocated_size == 0)
{
allocated_size = offsetof (struct name, name) + NAME_FIELD_SIZE + 1;
buffer = xmalloc (allocated_size);
/* FIXME: This memset is overkill, and ugly... */
memset (buffer, 0, allocated_size);
buffer = xzalloc (allocated_size);
}
while ((ep = name_next_elt (0)) && ep->type == NELT_CHDIR)
@@ -734,7 +728,7 @@ static void
add_hierarchy_to_namelist (struct name *name, dev_t device)
{
char *file_name = name->name;
char *buffer = get_directory_contents (file_name, device);
const char *buffer = get_directory_contents (file_name, device);
if (! buffer)
name->dir_contents = "\0\0\0\0";
@@ -746,7 +740,7 @@ add_hierarchy_to_namelist (struct name *name, dev_t device)
: NAME_FIELD_SIZE);
char *namebuf = xmalloc (allocated_length + 1);
/* FIXME: + 2 above? */
char *string;
const char *string;
size_t string_length;
int change_dir = name->change_dir;

79
src/suffix.c Normal file
View File

@@ -0,0 +1,79 @@
/* This file is part of GNU tar.
Copyright (C) 2007 Free Software Foundation, Inc.
Written by Sergey Poznyakoff.
GNU tar is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any later
version.
GNU tar is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.
You should have received a copy of the GNU General Public License along
with GNU tar. If not, see <http://www.gnu.org/licenses/>. */
#include <system.h>
#include "common.h"
struct compression_suffix
{
const char *suffix;
size_t length;
const char *program;
};
struct compression_suffix compression_suffixes[] = {
#define S(s,p) #s, sizeof (#s) - 1, #p
{ S(gz, gzip) },
{ S(tgz, gzip) },
{ S(taz, gzip) },
{ S(Z, compress) },
{ S(taZ, compress) },
{ S(bz2, bzip2) },
{ S(tbz, bzip2) },
{ S(tbz2, bzip2) },
{ S(tz2, bzip2) },
{ S(lzma, lzma) },
{ S(tlz, lzma) },
{ S(lzo, lzop) },
#undef S
};
int nsuffixes = sizeof (compression_suffixes) /
sizeof (compression_suffixes[0]);
static const char *
find_compression_program (const char *name, const char *defprog)
{
char *suf = strrchr (name, '.');
if (suf)
{
int i;
size_t len;
suf++;
len = strlen (suf);
for (i = 0; i < nsuffixes; i++)
{
if (compression_suffixes[i].length == len
&& memcmp (compression_suffixes[i].suffix, suf, len) == 0)
return compression_suffixes[i].program;
}
}
return defprog;
}
void
set_comression_program_by_suffix (const char *name, const char *defprog)
{
const char *program = find_compression_program (name, defprog);
if (program)
use_compress_program_option = program;
}

View File

@@ -1,6 +1,7 @@
/* System-dependent calls for tar.
Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
Copyright (C) 2003, 2004, 2005, 2006, 2007,
2008 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
@@ -17,7 +18,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#include <system.h>
#include <setenv.h>
#include "common.h"
#include <rmt.h>
@@ -52,12 +52,7 @@ sys_detect_dev_null_output (void)
}
void
sys_drain_input_pipe (void)
{
}
void
sys_wait_for_child (pid_t child_pid)
sys_wait_for_child (pid_t child_pid, bool eof)
{
}
@@ -161,26 +156,8 @@ sys_detect_dev_null_output (void)
&& archive_stat.st_ino == dev_null_stat.st_ino));
}
/* Manage to fully drain a pipe we might be reading, so to not break it on
the producer after the EOF block. FIXME: one of these days, GNU tar
might become clever enough to just stop working, once there is no more
work to do, we might have to revise this area in such time. */
void
sys_drain_input_pipe (void)
{
size_t r;
if (access_mode == ACCESS_READ
&& ! _isrmt (archive)
&& (S_ISFIFO (archive_stat.st_mode) || S_ISSOCK (archive_stat.st_mode)))
while ((r = rmtread (archive, record_start->buffer, record_size)) != 0
&& r != SAFE_READ_ERROR)
continue;
}
void
sys_wait_for_child (pid_t child_pid)
sys_wait_for_child (pid_t child_pid, bool eof)
{
if (child_pid)
{
@@ -194,8 +171,11 @@ sys_wait_for_child (pid_t child_pid)
}
if (WIFSIGNALED (wait_status))
ERROR ((0, 0, _("Child died with signal %d"),
WTERMSIG (wait_status)));
{
int sig = WTERMSIG (wait_status);
if (!(!eof && sig == SIGPIPE))
ERROR ((0, 0, _("Child died with signal %d"), sig));
}
else if (WEXITSTATUS (wait_status) != 0)
ERROR ((0, 0, _("Child returned status %d"),
WEXITSTATUS (wait_status)));
@@ -773,9 +753,10 @@ sys_exec_info_script (const char **archive_name, int volume_number)
char *argv[4];
char uintbuf[UINTMAX_STRSIZE_BOUND];
int p[2];
static RETSIGTYPE (*saved_handler) (int sig);
xpipe (p);
pipe_handler = signal (SIGPIPE, SIG_IGN);
saved_handler = signal (SIGPIPE, SIG_IGN);
pid = xfork ();
@@ -785,7 +766,7 @@ sys_exec_info_script (const char **archive_name, int volume_number)
int rc;
int status;
char *buf;
char *buf = NULL;
size_t size = 0;
FILE *fp;
@@ -800,10 +781,13 @@ sys_exec_info_script (const char **archive_name, int volume_number)
while (waitpid (pid, &status, 0) == -1)
if (errno != EINTR)
{
signal (SIGPIPE, saved_handler);
waitpid_error (info_script_option);
return -1;
}
signal (SIGPIPE, saved_handler);
if (WIFEXITED (status))
{
if (WEXITSTATUS (status) == 0 && rc > 0)
@@ -821,6 +805,8 @@ sys_exec_info_script (const char **archive_name, int volume_number)
setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
setenv ("TAR_ARCHIVE", *archive_name, 1);
setenv ("TAR_VOLUME", STRINGIFY_BIGINT (volume_number, uintbuf), 1);
setenv ("TAR_BLOCKING_FACTOR",
STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
setenv ("TAR_FORMAT",
archive_format_string (current_format == DEFAULT_FORMAT ?
@@ -839,5 +825,51 @@ sys_exec_info_script (const char **archive_name, int volume_number)
exec_fatal (info_script_option);
}
void
sys_exec_checkpoint_script (const char *script_name,
const char *archive_name,
int checkpoint_number)
{
pid_t pid;
char *argv[4];
char uintbuf[UINTMAX_STRSIZE_BOUND];
pid = xfork ();
if (pid != 0)
{
/* Master */
int status;
while (waitpid (pid, &status, 0) == -1)
if (errno != EINTR)
{
waitpid_error (script_name);
break;
}
return;
}
/* Child */
setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
setenv ("TAR_ARCHIVE", archive_name, 1);
setenv ("TAR_CHECKPOINT", STRINGIFY_BIGINT (checkpoint_number, uintbuf), 1);
setenv ("TAR_BLOCKING_FACTOR",
STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
setenv ("TAR_FORMAT",
archive_format_string (current_format == DEFAULT_FORMAT ?
archive_format : current_format), 1);
argv[0] = "/bin/sh";
argv[1] = "-c";
argv[2] = (char*) script_name;
argv[3] = NULL;
execv (argv[0], argv);
exec_fatal (script_name);
}
#endif /* not MSDOS */

166
src/tar.c
View File

@@ -249,8 +249,11 @@ enum
ANCHORED_OPTION = CHAR_MAX + 1,
ATIME_PRESERVE_OPTION,
BACKUP_OPTION,
CHECK_DEVICE_OPTION,
CHECKPOINT_OPTION,
CHECKPOINT_ACTION_OPTION,
DELAY_DIRECTORY_RESTORE_OPTION,
HARD_DEREFERENCE_OPTION,
DELETE_OPTION,
EXCLUDE_CACHES_OPTION,
EXCLUDE_CACHES_UNDER_OPTION,
@@ -268,13 +271,17 @@ enum
IGNORE_FAILED_READ_OPTION,
INDEX_FILE_OPTION,
KEEP_NEWER_FILES_OPTION,
LZOP_OPTION,
MODE_OPTION,
MTIME_OPTION,
NEWER_MTIME_OPTION,
NO_ANCHORED_OPTION,
NO_AUTO_COMPRESS_OPTION,
NO_CHECK_DEVICE_OPTION,
NO_DELAY_DIRECTORY_RESTORE_OPTION,
NO_IGNORE_CASE_OPTION,
NO_IGNORE_COMMAND_ERROR_OPTION,
NO_NULL_OPTION,
NO_OVERWRITE_DIR_OPTION,
NO_QUOTE_CHARS_OPTION,
NO_RECURSION_OPTION,
@@ -345,7 +352,7 @@ The version control may be set with --backup or VERSION_CONTROL, values are:\n\n
/* NOTE:
Available option letters are DEIJQY and aeqy. Consider the following
Available option letters are DEIQY and eqy. Consider the following
assignments:
[For Solaris tar compatibility =/= Is it important at all?]
@@ -408,6 +415,12 @@ static struct argp_option options[] = {
" NUMBER defaults to 1"), GRID+1 },
{"seek", 'n', NULL, 0,
N_("archive is seekable"), GRID+1 },
{"no-check-device", NO_CHECK_DEVICE_OPTION, NULL, 0,
N_("do not check device numbers when creating incremental archives"),
GRID+1 },
{"check-device", CHECK_DEVICE_OPTION, NULL, 0,
N_("check device numbers when creating incremental archives (default)"),
GRID+1 },
#undef GRID
#define GRID 30
@@ -574,20 +587,34 @@ static struct argp_option options[] = {
N_("control pax keywords"), GRID+8 },
{"label", 'V', N_("TEXT"), 0,
N_("create archive with volume name TEXT; at list/extract time, use TEXT as a globbing pattern for volume name"), GRID+8 },
{"bzip2", 'j', 0, 0,
N_("filter the archive through bzip2"), GRID+8 },
{"gzip", 'z', 0, 0,
N_("filter the archive through gzip"), GRID+8 },
{"gunzip", 0, 0, OPTION_ALIAS, NULL, GRID+8 },
{"ungzip", 0, 0, OPTION_ALIAS, NULL, GRID+8 },
{"compress", 'Z', 0, 0,
N_("filter the archive through compress"), GRID+8 },
{"uncompress", 0, 0, OPTION_ALIAS, NULL, GRID+8 },
{"use-compress-program", USE_COMPRESS_PROGRAM_OPTION, N_("PROG"), 0,
N_("filter through PROG (must accept -d)"), GRID+8 },
#undef GRID
#define GRID 90
{NULL, 0, NULL, 0,
N_("Compression options:"), GRID },
{"auto-compress", 'a', 0, 0,
N_("use archive suffix to determine the compression program"), GRID+1 },
{"no-auto-compress", NO_AUTO_COMPRESS_OPTION, 0, 0,
N_("do not use use archive suffix to determine the compression program"),
GRID+1 },
{"bzip2", 'j', 0, 0,
N_("filter the archive through bzip2"), GRID+1 },
{"gzip", 'z', 0, 0,
N_("filter the archive through gzip"), GRID+1 },
{"gunzip", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
{"ungzip", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
{"compress", 'Z', 0, 0,
N_("filter the archive through compress"), GRID+1 },
{"uncompress", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
{"lzma", 'J', 0, 0,
N_("filter the archive through lzma"), GRID+1 },
{"lzop", LZOP_OPTION, 0, 0,
N_("filter the archive through lzop"), GRID+8 },
{"use-compress-program", USE_COMPRESS_PROGRAM_OPTION, N_("PROG"), 0,
N_("filter through PROG (must accept -d)"), GRID+1 },
#undef GRID
#define GRID 100
{NULL, 0, NULL, 0,
N_("Local file selection:"), GRID },
@@ -599,6 +626,8 @@ static struct argp_option options[] = {
N_("get names to extract or create from FILE"), GRID+1 },
{"null", NULL_OPTION, 0, 0,
N_("-T reads null-terminated names, disable -C"), GRID+1 },
{"no-null", NO_NULL_OPTION, 0, 0,
N_("disable the effect of the previous --null option"), GRID+1 },
{"unquote", UNQUOTE_OPTION, 0, 0,
N_("unquote filenames read with -T (default)"), GRID+1 },
{"no-unquote", NO_UNQUOTE_OPTION, 0, 0,
@@ -634,6 +663,8 @@ static struct argp_option options[] = {
N_("don't strip leading `/'s from file names"), GRID+1 },
{"dereference", 'h', 0, 0,
N_("follow symlinks; archive and dump the files they point to"), GRID+1 },
{"hard-dereference", HARD_DEREFERENCE_OPTION, 0, 0,
N_("follow hard links; archive and dump the files they refer to"), GRID+1 },
{"starting-file", 'K', N_("MEMBER-NAME"), 0,
N_("begin at member MEMBER-NAME in the archive"), GRID+1 },
{"newer", 'N', N_("DATE-OR-FILE"), 0,
@@ -647,7 +678,7 @@ static struct argp_option options[] = {
N_("backup before removal, override usual suffix ('~' unless overridden by environment variable SIMPLE_BACKUP_SUFFIX)"), GRID+1 },
#undef GRID
#define GRID 92
#define GRID 110
{NULL, 0, NULL, 0,
N_("File name transformations:"), GRID },
{"strip-components", STRIP_COMPONENTS_OPTION, N_("NUMBER"), 0,
@@ -655,9 +686,10 @@ static struct argp_option options[] = {
GRID+1 },
{"transform", TRANSFORM_OPTION, N_("EXPRESSION"), 0,
N_("use sed replace EXPRESSION to transform file names"), GRID+1 },
{"xform", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
#undef GRID
#define GRID 95
#define GRID 120
{NULL, 0, NULL, 0,
N_("File name matching options (affect both exclude and include patterns):"),
GRID },
@@ -679,15 +711,18 @@ static struct argp_option options[] = {
N_("wildcards match `/' (default for exclusion)"), GRID+1 },
#undef GRID
#define GRID 100
#define GRID 130
{NULL, 0, NULL, 0,
N_("Informative output:"), GRID },
{"verbose", 'v', 0, 0,
N_("verbosely list files processed"), GRID+1 },
{"checkpoint", CHECKPOINT_OPTION, N_("[.]NUMBER"), OPTION_ARG_OPTIONAL,
{"checkpoint", CHECKPOINT_OPTION, N_("NUMBER"), OPTION_ARG_OPTIONAL,
N_("display progress messages every NUMBERth record (default 10)"),
GRID+1 },
{"checkpoint-action", CHECKPOINT_ACTION_OPTION, N_("ACTION"), 0,
N_("execute ACTION on each checkpoint"),
GRID+1 },
{"check-links", 'l', 0, 0,
N_("print a message if not all links are dumped"), GRID+1 },
{"totals", TOTALS_OPTION, N_("SIGNAL"), OPTION_ARG_OPTIONAL,
@@ -720,7 +755,7 @@ static struct argp_option options[] = {
N_("disable quoting for characters from STRING"), GRID+1 },
#undef GRID
#define GRID 110
#define GRID 140
{NULL, 0, NULL, 0,
N_("Compatibility options:"), GRID },
@@ -728,7 +763,7 @@ static struct argp_option options[] = {
N_("when creating, same as --old-archive; when extracting, same as --no-same-owner"), GRID+1 },
#undef GRID
#define GRID 120
#define GRID 150
{NULL, 0, NULL, 0,
N_("Other options:"), GRID },
@@ -785,6 +820,8 @@ struct tar_args /* Variables used during option parsing */
char const *backup_suffix_string; /* --suffix option argument */
char const *version_control_string; /* --backup option argument */
bool input_files; /* True if some input files where given */
int compress_autodetect; /* True if compression autodetection should
be attempted when creating archives */
};
@@ -822,6 +859,16 @@ exclude_vcs_files ()
"=RELEASE-ID",
"=meta-update",
"=update",
/* Bazaar */
".bzr",
".bzrignore",
".bzrtags",
/* Mercurial */
".hg",
".hgignore",
".hgtags",
/* darcs */
"_darcs",
NULL
};
@@ -1002,6 +1049,9 @@ report_textual_dates (struct tar_args *args)
static volatile int _argp_hang;
/* Either NL or NUL, as decided by the --null option. */
static char filename_terminator;
enum read_file_list_state /* Result of reading file name from the list file */
{
file_list_success, /* OK, name read successfully */
@@ -1010,16 +1060,16 @@ enum read_file_list_state /* Result of reading file name from the list file */
file_list_skip /* Empty (zero-length) entry encountered, skip it */
};
/* Read from FP a sequence of characters up to FILENAME_TERMINATOR and put them
/* Read from FP a sequence of characters up to TERM and put them
into STK.
*/
static enum read_file_list_state
read_name_from_file (FILE *fp, struct obstack *stk)
read_name_from_file (FILE *fp, struct obstack *stk, int term)
{
int c;
size_t counter = 0;
for (c = getc (fp); c != EOF && c != filename_terminator; c = getc (fp))
for (c = getc (fp); c != EOF && c != term; c = getc (fp))
{
if (c == 0)
{
@@ -1100,7 +1150,8 @@ update_argv (const char *filename, struct argp_state *state)
size_t new_argc;
bool is_stdin = false;
enum read_file_list_state read_state;
int term = filename_terminator;
if (!strcmp (filename, "-"))
{
is_stdin = true;
@@ -1114,7 +1165,8 @@ update_argv (const char *filename, struct argp_state *state)
open_fatal (filename);
}
while ((read_state = read_name_from_file (fp, &argv_stk)) != file_list_end)
while ((read_state = read_name_from_file (fp, &argv_stk, term))
!= file_list_end)
{
switch (read_state)
{
@@ -1143,7 +1195,7 @@ update_argv (const char *filename, struct argp_state *state)
obstack_1grow (&argv_stk, 0);
count = 1;
/* Read rest of files using new filename terminator */
filename_terminator = 0;
term = 0;
break;
}
@@ -1160,7 +1212,7 @@ update_argv (const char *filename, struct argp_state *state)
start = obstack_finish (&argv_stk);
if (filename_terminator == 0)
if (term == 0)
for (p = start; *p; p += strlen (p) + 1)
if (p[0] == '-')
count++;
@@ -1176,7 +1228,7 @@ update_argv (const char *filename, struct argp_state *state)
for (i = state->next, p = start; *p; p += strlen (p) + 1, i++)
{
if (filename_terminator == 0 && p[0] == '-')
if (term == 0 && p[0] == '-')
state->argv[i++] = "--add-file";
state->argv[i] = p;
}
@@ -1222,6 +1274,14 @@ parse_opt (int key, char *arg, struct argp_state *state)
set_subcommand_option (CAT_SUBCOMMAND);
break;
case 'a':
args->compress_autodetect = true;
break;
case NO_AUTO_COMPRESS_OPTION:
args->compress_autodetect = false;
break;
case 'b':
{
uintmax_t u;
@@ -1292,6 +1352,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
dereference_option = true;
break;
case HARD_DEREFERENCE_OPTION:
hard_dereference_option = true;
break;
case 'i':
/* Ignore zero blocks (eofs). This can't be the default,
because Unix tar writes two blocks of zeros, then pads out
@@ -1310,6 +1374,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
set_use_compress_program_option ("bzip2");
break;
case 'J':
set_use_compress_program_option ("lzma");
break;
case 'k':
/* Don't replace existing files. */
old_files_option = KEEP_OLD_FILES;
@@ -1341,6 +1409,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
}
break;
case LZOP_OPTION:
set_use_compress_program_option ("lzop");
break;
case 'm':
touch_option = true;
break;
@@ -1514,6 +1586,14 @@ parse_opt (int key, char *arg, struct argp_state *state)
" on this platform")));
break;
case CHECK_DEVICE_OPTION:
check_device_option = true;
break;
case NO_CHECK_DEVICE_OPTION:
check_device_option = false;
break;
case CHECKPOINT_OPTION:
if (arg)
{
@@ -1521,7 +1601,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
if (*arg == '.')
{
checkpoint_style = checkpoint_dot;
checkpoint_compile_action (".");
arg++;
}
checkpoint_option = strtoul (arg, &p, 0);
@@ -1530,9 +1610,13 @@ parse_opt (int key, char *arg, struct argp_state *state)
_("--checkpoint value is not an integer")));
}
else
checkpoint_option = 10;
checkpoint_option = DEFAULT_CHECKPOINT;
break;
case CHECKPOINT_ACTION_OPTION:
checkpoint_compile_action (arg);
break;
case BACKUP_OPTION:
backup_option = true;
if (arg)
@@ -1670,6 +1754,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
filename_terminator = '\0';
break;
case NO_NULL_OPTION:
filename_terminator = '\n';
break;
case NUMERIC_OWNER_OPTION:
numeric_owner_option = true;
break;
@@ -1732,6 +1820,8 @@ parse_opt (int key, char *arg, struct argp_state *state)
/* FIXME: What it is good for? */
same_permissions_option = true;
same_order_option = true;
WARN ((0, 0, _("The --preserve option is deprecated, "
"use --preserve-permissions --preserve-order instead")));
break;
case RECORD_SIZE_OPTION:
@@ -2001,7 +2091,8 @@ decode_options (int argc, char **argv)
args.backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
args.version_control_string = 0;
args.input_files = false;
args.compress_autodetect = false;
subcommand_option = UNKNOWN_SUBCOMMAND;
archive_format = DEFAULT_FORMAT;
blocking_factor = DEFAULT_BLOCKING;
@@ -2017,6 +2108,8 @@ decode_options (int argc, char **argv)
owner_option = -1;
group_option = -1;
check_device_option = true;
/* Convert old-style tar call by exploding option element and rearranging
options accordingly. */
@@ -2253,6 +2346,13 @@ decode_options (int argc, char **argv)
else if (utc_option)
verbose_option = 2;
if (tape_length_option && tape_length_option < record_size)
USAGE_ERROR ((0, 0, _("Volume length cannot be less than record size")));
if (same_order_option && listed_incremental_option)
USAGE_ERROR ((0, 0, _("--preserve-order is not compatible with "
"--listed-incremental")));
/* Forbid using -c with no input files whatsoever. Check that `-f -',
explicit or implied, is used correctly. */
@@ -2262,6 +2362,10 @@ decode_options (int argc, char **argv)
if (!args.input_files && !files_from_option)
USAGE_ERROR ((0, 0,
_("Cowardly refusing to create an empty archive")));
if (args.compress_autodetect && archive_names
&& strcmp (archive_name_array[0], "-"))
set_comression_program_by_suffix (archive_name_array[0],
use_compress_program_option);
break;
case EXTRACT_SUBCOMMAND:
@@ -2314,6 +2418,8 @@ decode_options (int argc, char **argv)
backup_option = false;
}
checkpoint_finish_compile ();
if (verbose_option)
report_textual_dates (&args);
}
@@ -2420,7 +2526,7 @@ main (int argc, char **argv)
name_term ();
if (exit_status == TAREXIT_FAILURE)
error (0, 0, _("Error exit delayed from previous errors"));
error (0, 0, _("Exiting with failure status due to previous errors"));
if (stdlis == stdout)
close_stdout ();

View File

@@ -1,5 +1,5 @@
/* This file is part of GNU tar.
Copyright (C) 2006, 2007 Free Software Foundation, Inc.
Copyright (C) 2006, 2007, 2008 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
@@ -19,16 +19,11 @@
#include <regex.h>
#include "common.h"
static enum transform_type
enum transform_type
{
transform_none,
transform_first,
transform_global
}
transform_type = transform_none;
static unsigned match_number = 0;
static regex_t regex;
static struct obstack stk;
};
enum replace_segm_type
{
@@ -62,31 +57,56 @@ struct replace_segm
} v;
};
/* Compiled replacement expression */
static struct replace_segm *repl_head, *repl_tail;
static size_t segm_count; /* Number of elements in the above list */
struct transform
{
struct transform *next;
enum transform_type transform_type;
int flags;
unsigned match_number;
regex_t regex;
/* Compiled replacement expression */
struct replace_segm *repl_head, *repl_tail;
size_t segm_count; /* Number of elements in the above list */
};
int transform_flags = XFORM_ALL;
static struct transform *transform_head, *transform_tail;
static struct transform *
new_transform ()
{
struct transform *p = xzalloc (sizeof *p);
if (transform_tail)
transform_tail->next = p;
else
transform_head = p;
transform_tail = p;
return p;
}
static struct replace_segm *
add_segment (void)
add_segment (struct transform *tf)
{
struct replace_segm *segm = xmalloc (sizeof *segm);
segm->next = NULL;
if (repl_tail)
repl_tail->next = segm;
if (tf->repl_tail)
tf->repl_tail->next = segm;
else
repl_head = segm;
repl_tail = segm;
segm_count++;
tf->repl_head = segm;
tf->repl_tail = segm;
tf->segm_count++;
return segm;
}
static void
add_literal_segment (char *str, char *end)
add_literal_segment (struct transform *tf, char *str, char *end)
{
size_t len = end - str;
if (len)
{
struct replace_segm *segm = add_segment ();
struct replace_segm *segm = add_segment (tf);
segm->type = segm_literal;
segm->v.literal.ptr = xmalloc (len + 1);
memcpy (segm->v.literal.ptr, str, len);
@@ -96,9 +116,9 @@ add_literal_segment (char *str, char *end)
}
static void
add_char_segment (int chr)
add_char_segment (struct transform *tf, int chr)
{
struct replace_segm *segm = add_segment ();
struct replace_segm *segm = add_segment (tf);
segm->type = segm_literal;
segm->v.literal.ptr = xmalloc (2);
segm->v.literal.ptr[0] = chr;
@@ -107,41 +127,87 @@ add_char_segment (int chr)
}
static void
add_backref_segment (size_t ref)
add_backref_segment (struct transform *tf, size_t ref)
{
struct replace_segm *segm = add_segment ();
struct replace_segm *segm = add_segment (tf);
segm->type = segm_backref;
segm->v.ref = ref;
}
static void
add_case_ctl_segment (enum case_ctl_type ctl)
static int
parse_xform_flags (int *pflags, int c)
{
struct replace_segm *segm = add_segment ();
switch (c)
{
case 'r':
*pflags |= XFORM_REGFILE;
break;
case 'R':
*pflags &= ~XFORM_REGFILE;
break;
case 'h':
*pflags |= XFORM_LINK;
break;
case 'H':
*pflags &= ~XFORM_LINK;
break;
case 's':
*pflags |= XFORM_SYMLINK;
break;
case 'S':
*pflags &= ~XFORM_SYMLINK;
break;
default:
return 1;
}
return 0;
}
static void
add_case_ctl_segment (struct transform *tf, enum case_ctl_type ctl)
{
struct replace_segm *segm = add_segment (tf);
segm->type = segm_case_ctl;
segm->v.ctl = ctl;
}
void
set_transform_expr (const char *expr)
static const char *
parse_transform_expr (const char *expr)
{
int delim;
int i, j, rc;
char *str, *beg, *cur;
const char *p;
int cflags = 0;
if (transform_type == transform_none)
obstack_init (&stk);
else
{
/* Redefinition of the transform expression */
regfree (&regex);
}
struct transform *tf = new_transform ();
if (expr[0] != 's')
USAGE_ERROR ((0, 0, _("Invalid transform expression")));
{
if (strncmp (expr, "flags=", 6) == 0)
{
transform_flags = 0;
for (expr += 6; *expr; expr++)
{
if (*expr == ';')
{
expr++;
break;
}
if (parse_xform_flags (&transform_flags, *expr))
USAGE_ERROR ((0, 0, _("Unknown transform flag: %c"),
*expr));
}
return expr;
}
USAGE_ERROR ((0, 0, _("Invalid transform expression")));
}
delim = expr[1];
/* Scan regular expression */
@@ -161,12 +227,13 @@ set_transform_expr (const char *expr)
USAGE_ERROR ((0, 0, _("Invalid transform expression")));
/* Check flags */
transform_type = transform_first;
for (p = expr + j + 1; *p; p++)
tf->transform_type = transform_first;
tf->flags = transform_flags;
for (p = expr + j + 1; *p && *p != ';'; p++)
switch (*p)
{
case 'g':
transform_type = transform_global;
tf->transform_type = transform_global;
break;
case 'i':
@@ -176,33 +243,38 @@ set_transform_expr (const char *expr)
case 'x':
cflags |= REG_EXTENDED;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
match_number = strtoul (p, (char**) &p, 0);
tf->match_number = strtoul (p, (char**) &p, 0);
p--;
break;
default:
USAGE_ERROR ((0, 0, _("Unknown flag in transform expression")));
if (parse_xform_flags (&tf->flags, *p))
USAGE_ERROR ((0, 0, _("Unknown flag in transform expression: %c"),
*p));
}
if (*p == ';')
p++;
/* Extract and compile regex */
str = xmalloc (i - 1);
memcpy (str, expr + 2, i - 2);
str[i - 2] = 0;
rc = regcomp (&regex, str, cflags);
rc = regcomp (&tf->regex, str, cflags);
if (rc)
{
char errbuf[512];
regerror (rc, &regex, errbuf, sizeof (errbuf));
regerror (rc, &tf->regex, errbuf, sizeof (errbuf));
USAGE_ERROR ((0, 0, _("Invalid transform expression: %s"), errbuf));
}
if (str[0] == '^' || str[strlen (str) - 1] == '$')
transform_type = transform_first;
tf->transform_type = transform_first;
free (str);
@@ -218,91 +290,91 @@ set_transform_expr (const char *expr)
{
size_t n;
add_literal_segment (beg, cur);
add_literal_segment (tf, beg, cur);
switch (*++cur)
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
n = strtoul (cur, &cur, 10);
if (n > regex.re_nsub)
if (n > tf->regex.re_nsub)
USAGE_ERROR ((0, 0, _("Invalid transform replacement: back reference out of range")));
add_backref_segment (n);
add_backref_segment (tf, n);
break;
case '\\':
add_char_segment ('\\');
add_char_segment (tf, '\\');
cur++;
break;
case 'a':
add_char_segment ('\a');
add_char_segment (tf, '\a');
cur++;
break;
case 'b':
add_char_segment ('\b');
add_char_segment (tf, '\b');
cur++;
break;
case 'f':
add_char_segment ('\f');
add_char_segment (tf, '\f');
cur++;
break;
case 'n':
add_char_segment ('\n');
add_char_segment (tf, '\n');
cur++;
break;
case 'r':
add_char_segment ('\r');
add_char_segment (tf, '\r');
cur++;
break;
case 't':
add_char_segment ('\t');
add_char_segment (tf, '\t');
cur++;
break;
case 'v':
add_char_segment ('\v');
add_char_segment (tf, '\v');
cur++;
break;
case '&':
add_char_segment ('&');
add_char_segment (tf, '&');
cur++;
break;
case 'L':
/* Turn the replacement to lowercase until a `\U' or `\E'
is found, */
add_case_ctl_segment (ctl_locase);
add_case_ctl_segment (tf, ctl_locase);
cur++;
break;
case 'l':
/* Turn the next character to lowercase, */
add_case_ctl_segment (ctl_locase_next);
add_case_ctl_segment (tf, ctl_locase_next);
cur++;
break;
case 'U':
/* Turn the replacement to uppercase until a `\L' or `\E'
is found, */
add_case_ctl_segment (ctl_upcase);
add_case_ctl_segment (tf, ctl_upcase);
cur++;
break;
case 'u':
/* Turn the next character to uppercase, */
add_case_ctl_segment (ctl_upcase_next);
add_case_ctl_segment (tf, ctl_upcase_next);
cur++;
break;
case 'E':
/* Stop case conversion started by `\L' or `\U'. */
add_case_ctl_segment (ctl_stop);
add_case_ctl_segment (tf, ctl_stop);
cur++;
break;
@@ -312,7 +384,7 @@ set_transform_expr (const char *expr)
char buf[2];
buf[0] = '\\';
buf[1] = *cur;
add_literal_segment (buf, buf + 2);
add_literal_segment (tf, buf, buf + 2);
}
cur++;
break;
@@ -321,15 +393,23 @@ set_transform_expr (const char *expr)
}
else if (*cur == '&')
{
add_literal_segment (beg, cur);
add_backref_segment (0);
add_literal_segment (tf, beg, cur);
add_backref_segment (tf, 0);
beg = ++cur;
}
else
cur++;
}
add_literal_segment (beg, cur);
add_literal_segment (tf, beg, cur);
return p;
}
void
set_transform_expr (const char *expr)
{
while (*expr)
expr = parse_transform_expr (expr);
}
/* Run case conversion specified by CASE_CTL on array PTR of SIZE
@@ -373,8 +453,12 @@ run_case_conv (enum case_ctl_type case_ctl, char *ptr, size_t size)
return case_ctl_buffer;
}
bool
_transform_name_to_obstack (char *input)
static struct obstack stk;
static bool stk_init;
void
_single_transform_name_to_obstack (struct transform *tf, char *input)
{
regmatch_t *rmp;
int rc;
@@ -390,17 +474,14 @@ _transform_name_to_obstack (char *input)
save_ctl = ctl_stop; \
}
if (transform_type == transform_none)
return false;
rmp = xmalloc ((regex.re_nsub + 1) * sizeof (*rmp));
rmp = xmalloc ((tf->regex.re_nsub + 1) * sizeof (*rmp));
while (*input)
{
size_t disp;
char *ptr;
rc = regexec (&regex, input, regex.re_nsub + 1, rmp, 0);
rc = regexec (&tf->regex, input, tf->regex.re_nsub + 1, rmp, 0);
if (rc == 0)
{
@@ -412,14 +493,14 @@ _transform_name_to_obstack (char *input)
obstack_grow (&stk, input, rmp[0].rm_so);
nmatches++;
if (match_number && nmatches < match_number)
if (tf->match_number && nmatches < tf->match_number)
{
obstack_grow (&stk, input, disp);
input += disp;
continue;
}
for (segm = repl_head; segm; segm = segm->next)
for (segm = tf->repl_head; segm; segm = segm->next)
{
switch (segm->type)
{
@@ -485,7 +566,7 @@ _transform_name_to_obstack (char *input)
input += disp;
if (transform_type == transform_first)
if (tf->transform_type == transform_first)
{
obstack_grow (&stk, input, strlen (input));
break;
@@ -494,23 +575,46 @@ _transform_name_to_obstack (char *input)
obstack_1grow (&stk, 0);
free (rmp);
return true;
}
bool
_transform_name_to_obstack (int flags, char *input, char **output)
{
struct transform *tf;
bool alloced = false;
if (!stk_init)
{
obstack_init (&stk);
stk_init = true;
}
for (tf = transform_head; tf; tf = tf->next)
{
if (tf->flags & flags)
{
_single_transform_name_to_obstack (tf, input);
input = obstack_finish (&stk);
alloced = true;
}
}
*output = input;
return alloced;
}
bool
transform_name_fp (char **pinput, char *(*fun)(char *, void *), void *dat)
transform_name_fp (char **pinput, int flags,
char *(*fun)(char *, void *), void *dat)
{
char *str;
bool ret = _transform_name_to_obstack (*pinput);
bool ret = _transform_name_to_obstack (flags, *pinput, &str);
if (ret)
{
str = obstack_finish (&stk);
assign_string (pinput, fun ? fun (str, dat) : str);
obstack_free (&stk, str);
}
else if (fun)
{
str = *pinput;
*pinput = NULL;
assign_string (pinput, fun (str, dat));
free (str);
@@ -520,8 +624,8 @@ transform_name_fp (char **pinput, char *(*fun)(char *, void *), void *dat)
}
bool
transform_name (char **pinput)
transform_name (char **pinput, int type)
{
return transform_name_fp (pinput, NULL, NULL);
return transform_name_fp (pinput, type, NULL, NULL);
}

View File

@@ -91,7 +91,7 @@ bool
string_ascii_p (char const *p)
{
for (; *p; p++)
if (! (0 <= *p && *p <= 127))
if (*p & ~0x7f)
return false;
return true;
}

View File

@@ -25,8 +25,6 @@
#include "common.h"
#include <fnmatch.h>
static bool xheader_protected_pattern_p (char const *pattern);
static bool xheader_protected_keyword_p (char const *keyword);
static void xheader_set_single_keyword (char *) __attribute__ ((noreturn));

View File

@@ -89,6 +89,7 @@ TESTSUITE_AT = \
multiv03.at\
multiv04.at\
multiv05.at\
multiv06.at\
old.at\
options.at\
options02.at\
@@ -97,9 +98,12 @@ TESTSUITE_AT = \
rename01.at\
rename02.at\
rename03.at\
rename04.at\
rename05.at\
same-order01.at\
same-order02.at\
shortfile.at\
shortupd.at\
shortrec.at\
sparse01.at\
sparse02.at\

View File

@@ -13,7 +13,7 @@ if test -z "$TEST_DATA_DIR"; then
TEST_DATA_DIR=$abs_builddir
fi
STAR_DATA_URL=http://download.berlios.de/pub/star/testscripts
STAR_DATA_URL=ftp://ftp.berlios.de/pub/star/testscripts
if test -z "$STAR_TESTSCRIPTS"; then
STAR_TESTSCRIPTS=$TEST_DATA_DIR
fi
@@ -30,4 +30,8 @@ tarball_prereq() {
echo "$2 $3/$1" | md5sum --status --check - >/dev/null 2>&1
}
decho() {
echo $*
echo >&2 $*
}

View File

@@ -42,7 +42,7 @@ tar tf archive
to
],
[tar: tre: Not found in archive
tar: Error exit delayed from previous errors
tar: Exiting with failure status due to previous errors
])
AT_CLEANUP

View File

@@ -35,7 +35,7 @@ test $? = 2 || exit 1
[
gzip: stdin: unexpected end of file
tar: Child returned status 1
tar: Error exit delayed from previous errors
tar: Exiting with failure status due to previous errors
],
[],[])

View File

@@ -64,12 +64,12 @@ test $status = 0
[
-----
tar: file: Cannot open: Permission denied
tar: Error exit delayed from previous errors
tar: Exiting with failure status due to previous errors
-----
tar: file: Warning: Cannot open: Permission denied
-----
tar: directory: Cannot open: Permission denied
tar: Error exit delayed from previous errors
tar: Exiting with failure status due to previous errors
-----
tar: directory: Warning: Cannot open: Permission denied
])

View File

@@ -34,6 +34,8 @@ mkdir directory
genfile --file=directory/x
genfile --file=directory/y
sleep 1
tar -cf archive.1 -g db directory
mv directory/x directory/z

View File

@@ -38,6 +38,8 @@ awk 'BEGIN {
printf("NAME_PREFIX[%03d]\n", i);
}' < /dev/null | genfile --files-from -
sleep 1
echo "Initial dump"
tar cvf a0.tar -g a.sna a
mv a/b a/c

View File

@@ -44,7 +44,10 @@ sleep 1
tar cf archive --listed=list structure
tar cfv archive --listed=list structure
echo separator
sleep 1
# ReiserFS often offsets the timestamps of newly created files
# 1 second to the past. Try to compensate for it, until a better
# solution is found.
sleep 2
echo y >structure/file
tar cfv archive --listed=list structure
],

View File

@@ -39,7 +39,7 @@ tar --create \
tar tf archive.1 || exit 1
sleep 1
sleep 2
genfile --length 10240 --pattern zeros --file directory/file2

View File

@@ -40,7 +40,7 @@ tar tf archive
DIR/
],
[tar: DIR/FILE: file name is too long (max 99); not dumped
tar: Error exit delayed from previous errors
tar: Exiting with failure status due to previous errors
],
[],[],[v7])

View File

@@ -31,7 +31,7 @@ tar cf archive LONGNAME
[2],
[],
[tar: LONGNAME: file name is too long (cannot be split); not dumped
tar: Error exit delayed from previous errors
tar: Exiting with failure status due to previous errors
],[],[],[ustar])
AT_CLEANUP

View File

@@ -36,7 +36,7 @@ tar cf archive PREFIX_155
[2],
[],
[tar: PREFIX_155/: file name is too long (cannot be split); not dumped
tar: Error exit delayed from previous errors
tar: Exiting with failure status due to previous errors
],[],[],[ustar])
AT_CLEANUP

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2006, 2007 Free Software Foundation, Inc.
# Copyright (C) 2006, 2007, 2008 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
@@ -19,11 +19,11 @@
# 02110-1301, USA.
# Up to version 1.15.91 tar was unable to recognize all volumes
# given after an aout-of-sync volume.
# given after an out-of-sync volume.
# Reported by: Joerg Weilbier <gnu@weilbier.net>
# References: <200610011952.29880.gnu@weilbier.net>
AT_SETUP([Restoring after an out of sync folume])
AT_SETUP([Restoring after an out of sync volume])
AT_KEYWORDS([multivolume multiv multiv05 sync])
m4_define([FILELIST],[jeden,dwa,trzy,cztery,piec,szesc])

52
tests/multiv06.at Normal file
View File

@@ -0,0 +1,52 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2008 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# When volume size equals record size, swapping buffers in
# new_volume triggers a call to flush_archive. The size left variables
# must be corrected after that, which was not done in versions <= 1.20.
# Reported by: Marek Kielar <mkielar@go2.pl>
# References: <1907cbb6.79e32b49.48887f09.fd55@o2.pl>
AT_SETUP([Multivolumes with L=record_size])
AT_KEYWORDS([multivolume multiv multiv06])
AT_TAR_CHECK([
exec <&-
decho Creating file
genfile --length 20139 --file file
decho Creating archive
tar -c -M -L10 -b20 -farc.1 -farc.2 -farc.3 file
decho Testing archive
tar -t -M -farc.1 -farc.2 -farc.3],
[0],
[Creating file
Creating archive
Testing archive
file
],
[Creating file
Creating archive
Testing archive
],
[],[],
[gnu, pax])
AT_CLEANUP

View File

@@ -34,6 +34,8 @@ genfile --file foo/bar/file.r
mkdir foo/bar/baz
genfile --file foo/bar/baz/file.z
sleep 1
echo "Creating base archive"
tar -g incr -cf arch.1 -v foo

View File

@@ -39,6 +39,8 @@ genfile --file foo/b/fileb
mkdir foo/c
genfile --file foo/c/filec
sleep 1
echo "First dump"
echo "First dump">&2
tar -g incr -cf arch.1 -v foo 2>tmperr

83
tests/rename04.at Normal file
View File

@@ -0,0 +1,83 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2008 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# Description: Up to version 1.20, when storing a record for renamed
# directory in an incremental archive, tar incorrectly flagged all its
# subdirectories as renamed, which led to problems at archive extraction.
# References: <00a401c8ecc0$56b7ef30$6a17a8c0@inti.com>
# Reported by: Enric Hernandez <ehernandez@notariado.org>
AT_SETUP([renamed directory containing subdirectories])
AT_KEYWORDS([incremental rename04 rename])
AT_TAR_CHECK([
AT_SORT_PREREQ
decho Creating directory structure
mkdir directory
mkdir directory/subdir
genfile --file=directory/file
decho Creating initial archive
tar -cf archive.1 -g db.1 directory
decho Renaming
mv directory dir
decho Creating incremental archive
cp db.1 db.2
tar -cf archive.2 -g db.2 dir
mv dir orig
decho First restore
tar -xf archive.1 -g db.1
find directory | sort
decho Second restore
tar -xf archive.2 -g db.2
find dir | sort
],
[0],
[Creating directory structure
Creating initial archive
Renaming
Creating incremental archive
First restore
directory
directory/file
directory/subdir
Second restore
dir
dir/subdir
],
[Creating directory structure
Creating initial archive
Renaming
Creating incremental archive
First restore
Second restore
],[],[],[gnu, oldgnu, posix])
AT_CLEANUP
# End of rename04.at

81
tests/rename05.at Normal file
View File

@@ -0,0 +1,81 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2008 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# Description: A continuation of rename04.at, that checks additionally if
# renamed subdirectories are restored correctly.
AT_SETUP([renamed subdirectories])
AT_KEYWORDS([incremental rename05 rename])
AT_TAR_CHECK([
AT_SORT_PREREQ
decho Creating directory structure
mkdir directory
mkdir directory/subdir
genfile --file=directory/file
decho Creating initial archive
tar -cf archive.1 -g db.1 directory
decho Renaming
mv directory/subdir directory/subdir.0
mv directory dir
decho Creating incremental archive
cp db.1 db.2
tar -cf archive.2 -g db.2 dir
mv dir orig
decho First restore
tar -xf archive.1 -g db.1
find directory | sort
decho Second restore
tar -xf archive.2 -g db.2
find dir | sort
],
[0],
[Creating directory structure
Creating initial archive
Renaming
Creating incremental archive
First restore
directory
directory/file
directory/subdir
Second restore
dir
dir/subdir.0
],
[Creating directory structure
Creating initial archive
Renaming
Creating incremental archive
First restore
Second restore
],[],[],[gnu, oldgnu, posix])
AT_CLEANUP
# End of rename05.at

View File

@@ -24,7 +24,7 @@
# http://lists.gnu.org/archive/html/bug-tar/2007-08/msg00038.html
AT_SETUP([short input files])
AT_KEYWORDS([shortfile])
AT_KEYWORDS([shortfile shortfile0])
AT_TAR_CHECK([
genfile --length 511 --file foo || exit 5
@@ -33,7 +33,7 @@ tar tf foo
[2],
[],
[tar: This does not look like a tar archive
tar: Error exit delayed from previous errors
tar: Exiting with failure status due to previous errors
],
[],[],[gnu])

39
tests/shortupd.at Normal file
View File

@@ -0,0 +1,39 @@
# 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 3, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Fixing improper small file recognition in version 1.18 (see shortfile.at
# and ChangeLog:2007-08-24), introduced another bug: when updating a
# non-existing archive, tar-1.19 complained about its not being a tar archive
# and exited immediately, leaving the created zero-sized file after it.
#
# This bug was fixed on 2007-12-05.
#
# Reported by: Ozan @,{C}a@v{g}layan <ozancag@gmail.com>
# References: <4755A82A.9060607@gmail.com>
AT_SETUP([updating short archives])
AT_KEYWORDS([shortfile shortfile1 shortupd])
AT_TAR_CHECK([
touch foo
tar uf archive foo
],
[0])
AT_CLEANUP

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
# Copyright (C) 2005, 2006, 2007, 2008 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
@@ -35,18 +35,18 @@ echo "Pass 1: Split between data blocks"
echo "Create archive"
tar --sparse -c --record-size=512 -M -L6 -f arc.1 -f arc.2 sparsefile || exit 1
echo "Test archive"
tar -t -M -f arc.1 -f arc.2
tar --record-size=512 -t -M -f arc.1 -f arc.2
echo "Compare archive"
tar -d -M -f arc.1 -f arc.2
tar --record-size=512 -d -M -f arc.1 -f arc.2
echo "Pass 2: Split within a data block"
genfile --sparse --file sparsefile 0 ABCDEFGHIJ 1M ABCDEFGHI || AT_SKIP_TEST
echo "Create archive"
tar --sparse -c --record-size=512 -M -L6 -f arc.1 -f arc.2 sparsefile || exit 1
echo "Test archive"
tar -t -M -f arc.1 -f arc.2
tar --record-size=512 -t -M -f arc.1 -f arc.2
echo "Compare archive"
tar -d -M -f arc.1 -f arc.2
tar --record-size=512 -d -M -f arc.1 -f arc.2
],
[0],
[Pass 1: Split between data blocks

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
# Copyright (C) 2005, 2006, 2007, 2008 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
@@ -56,5 +56,7 @@ Test archive
sparsefile
Compare archive
],
[],[],[],[pax])])
[tar: Record size = 12 blocks
tar: Record size = 12 blocks
],[],[],[pax])])

View File

@@ -1,6 +1,6 @@
This directory contains scripts for testing GNU tar using
star "test archives". The archives themselves can be obtained
from http://download.berlios.de/pub/star/testscripts.
from ftp://ftp.berlios.de/pub/star/testscripts.
These tests are disabled by default. There are two ways to run
them. The simplest is by `make check-full' command. It requires wget
@@ -52,9 +52,9 @@ containing very large files (in this case -- 10 GB).
This is a test for compliance to POSIX.1-1990 tar specification. It
requires two files: ustar-all-quicktest.tar and quicktest.filelist,
(they usually reside in star/tartest directory), and `tartest' program
(they usually reside in star/testscripts directory), and `tartest' program
(also part of star distribution). The test must be run only with root
privileges, so it is a good idea to test contents of
privileges, so it is a good idea to verify the contents of
ustar-all-quicktest.tar before running it.
If `tartest' is not in your PATH, use TARTEST variable to specify its

View File

@@ -138,6 +138,8 @@ m4_include([incr04.at])
m4_include([rename01.at])
m4_include([rename02.at])
m4_include([rename03.at])
m4_include([rename04.at])
m4_include([rename05.at])
m4_include([chtype.at])
m4_include([ignfail.at])
@@ -155,6 +157,7 @@ m4_include([multiv02.at])
m4_include([multiv03.at])
m4_include([multiv04.at])
m4_include([multiv05.at])
m4_include([multiv06.at])
m4_include([old.at])
@@ -180,6 +183,7 @@ m4_include([volsize.at])
m4_include([comprec.at])
m4_include([shortfile.at])
m4_include([shortupd.at])
m4_include([truncate.at])
m4_include([grow.at])

View File

@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
# Copyright (C) 2006, 2007 Free Software Foundation, Inc.
# Copyright (C) 2006, 2007, 2008 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
@@ -36,7 +36,7 @@ AT_TARBALL_PREREQ([abc.tar],[540f196ceddcad9e7bd2f2d7533d0474])
echo Short Listing
tar tf $TEST_DATA_DIR/abc.tar
echo Verbose Listing
tar tfv $TEST_DATA_DIR/abc.tar
tar --utc -tvf $TEST_DATA_DIR/abc.tar
echo Extracted directory
tar xf $TEST_DATA_DIR/abc.tar
find abc|sort
@@ -46,11 +46,14 @@ find abc|sort
abc/not-a-file.gif
abc/CCC
Verbose Listing
V--------- 0/0 1536 2006-05-09 01:07 abc/not-a-file.gif--Volume Header--
-rw-r--r-- tom/users 0 2006-04-22 22:52 abc/CCC
V--------- 0/0 1536 2006-05-08 22:07 abc/not-a-file.gif--Volume Header--
-rw-r--r-- tom/users 0 2006-04-22 19:52 abc/CCC
Extracted directory
abc
abc/CCC
],
[tar: Record size = 5 blocks
tar: Record size = 5 blocks
])
AT_CLEANUP