Merge recent gnulib changes, and remove some lint.
This commit is contained in:
218
ChangeLog
218
ChangeLog
@@ -1,3 +1,157 @@
|
||||
2004-04-04 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
Merge recent gnulib changes, and remove some lint.
|
||||
|
||||
Improve support for nanosecond-resolution time stamps.
|
||||
* bootstrap: Add gettime, timespec modules.
|
||||
* configure.ac (gl_GETTIME, gl_TIMESPEC): Add.
|
||||
* lib/.cvsignore (getopt_int.h, gettime.c, gettimeofday.c,
|
||||
timespec.h): Add.
|
||||
* lib/Makefile.am (libtar_a_SOURCES): Add gettime.c, timespec.h.
|
||||
* m4/.cvsignore: Add clock_time.m4, gettime.m4, gettimeofday.m4,
|
||||
st_mtim.m4, timespec.m4. Remove malloc.m4, realloc.m4.
|
||||
* src/common.h (newer_mtime_option): Now a struct timespec, not
|
||||
time_t. All uses changed.
|
||||
(NEWER_OPTION_INITIALIZED, OLDER_STAT_MTIME): New macros.
|
||||
* src/create.c (dump_file0): Use OLDER_STAT_TIME to compare times.
|
||||
* src/incremen.c (scan_path): Likewise.
|
||||
* src/list.c (read_and): Likewise.
|
||||
* src/list.c (read_and): Use NEWER_OPTION_INITIALIZED to decide
|
||||
whether newer_mtime_option is initialized.
|
||||
* src/tar.c (decode_options): Likewise.
|
||||
* src/tar.c (decode_options): Adjust to new signature for get_date.
|
||||
|
||||
* src/buffer.c (short_read, flush_read): Use size_t, not ssize_t, for
|
||||
result of safe_read, full_write, and similar functions.
|
||||
Detect safe_read error by comparing to SAFE_READ_ERROR;
|
||||
detect full_write error by comparing to 0.
|
||||
All uses changed.
|
||||
* src/common.h (write_error_details, sys_write_archive_buffer):
|
||||
Likewise.
|
||||
* src/misc.c (write_error_details): Likewise.
|
||||
* src/rmt.c (main): Likewise.
|
||||
* src/rmt.h (rmt_read__, rmt_write__): Likewise.
|
||||
* src/rtapelib.c (rmt_read__, rmt_write__, rmt_ioctl__): Likewise.
|
||||
* src/sparse.c (sparse_scan_file, sparse_dump_region,
|
||||
check_sparse_region, check_data_region): Likewise.
|
||||
* src/system.c (sys_write_archive_buffer, sys_drain_input_pipe,
|
||||
sys_child_open_for_compress, sys_child_open_for_uncompress): Likewise.
|
||||
* src/update.c (append_file): Likewise.
|
||||
|
||||
* src/buffer.c (clear_read_error_count): Use explicit (void)
|
||||
to indicate a function with no arguments.
|
||||
* src/create.c (check_links): Likewise.
|
||||
* src/system.c (sys_get_archive_stat, sys_save_archive_dev_ino,
|
||||
sys_detect_dev_null_output, sys_drain_input_pipe, sys_spawn_shell,
|
||||
sys_reset_uid_gid, sys_get_archive_stat, sys_save_archive_dev_ino,
|
||||
sys_detect_dev_null_output, sys_drain_input_pipe, sys_spawn_shell):
|
||||
Likewise.
|
||||
* src/utf8.c (get_input_charset): Likewise.
|
||||
* src/xheader.c (xheader_ghdr_name, xheader_write_global,
|
||||
xheader_decode_global, extended_header_init): Likewise.
|
||||
* tests/mksparse.c (usage): Likewise.
|
||||
|
||||
* src/buffer.c (new_volume): Rename local variables to avoid
|
||||
shadowing warnings.
|
||||
* src/common.h (file_dumpable_p, sys_stat_nanoseconds,
|
||||
sparse_file_p, sparse_member_p, sparse_fixup_header,
|
||||
sparse_dump_file, sparce_extract_file, sparse_skip_file,
|
||||
sparse_diff_file): Likewise.
|
||||
* src/compare.c (diff_archive): Likewise.
|
||||
* src/create.c (file_dumpable_p, dump_regular_file, dump_dir0,
|
||||
dump_dir, dump_hard_link, file_count_links, dump_file0, dump_file):
|
||||
Likewise.
|
||||
* src/extract.c (repair_delayed_set_stat): Likewise.
|
||||
* src/misc.c (maybe_backup_file, add_hierarchy_to_namelist):
|
||||
Likewise.
|
||||
* src/sparse.c (struct tar_sparse_optab, tar_sparse_dump_region,
|
||||
tar_sparse_extract_region, sparse_dump_region, sparse_extract_region,
|
||||
sparse_dump_file, sparse_file_p, sparse_member_p,
|
||||
sparse_fixup_header, sparse_extract_file, sparse_skip_file,
|
||||
check_data_region, sparse_diff_file): Likewise.
|
||||
* src/system.c (sys_stat_nanoseconds): Likewise.
|
||||
* src/xheader.c (xheader_format_name): Likewise.
|
||||
|
||||
* src/common.h (enum old_files): Remove comma before }; not portable.
|
||||
|
||||
* src/common.h (read_fatal_details): Add __attribute__ ((noreturn)).
|
||||
* src/rmt.c (usage): Likewise.
|
||||
* src/xheader.c (xheader_set_single_keyword): Likewise.
|
||||
* tests/genfile.c (usage): Likewise.
|
||||
* tests/mksparse.c (die, usage): Likewise. Also add printf attribute
|
||||
to die.
|
||||
|
||||
* src/common.h (gname_to_gid, uname_to_uid): Add const to avoid
|
||||
some gcc warnings.
|
||||
* src/names.c (uname_to_uid, gname_to_gid): Likewise.
|
||||
* src/utf8.c (struct langtab.lang, struct langtab.terr, struct
|
||||
langtab.charset, charset_lookup): Likewise.
|
||||
|
||||
* src/common.h (name_init): Remove unused args. All callers changed.
|
||||
* src/names.c (name_init): Likewise.
|
||||
|
||||
* src/common.h (usage, xheader_write, xheader_write_global,
|
||||
sys_reset_uid_gid): New decls.
|
||||
|
||||
* src/compare.c (report_difference, process_noop): Add
|
||||
__attribute__ ((unused)) for unused attributes.
|
||||
* src/sparse.c (oldgnu_sparse_member_p, star_sparse_member_p):
|
||||
Likewise.
|
||||
* src/xheader.c (dummy_coder, dummy_decoder, atime_coder,
|
||||
gid_coder, gname_coder, linkpath_coder, ctime_coder, mtime_coder,
|
||||
path_coder, size_coder, uid_coder, uname_coder,
|
||||
sparse_numblocks_coder): Likewise.
|
||||
|
||||
* src/create.c (dump_regular_finish, dump_dir0, dump_dir,
|
||||
dump_file0): Now static.
|
||||
* src/utf8.c (charset_lookup): Likewise.
|
||||
* src/xheader.c (xheader_protected_pattern_p,
|
||||
xheader_protected_keyword_p, xheader_set_single_keyword,
|
||||
xheader_keyword_deleted_p, xheader_keyword_override_p,
|
||||
xheader_list_append, xheader_list_destroy, xheader_set_keyword_equal):
|
||||
Likewise.
|
||||
* tests/genfile.c (usage): Likewise.
|
||||
* tests/mksparse.c (die, mkhole, mksparse, usage, xlat_suffix):
|
||||
Likewise.
|
||||
|
||||
* src/create.c (hash_link): Rewrite to avoid cast.
|
||||
|
||||
* src/extract.c (file_newer_p): Use parameter, not global var.
|
||||
* src/misc.c (write_error_details): Likewise.
|
||||
|
||||
* src/extract.c (prepare_to_extract): Remove directory arg; not
|
||||
used. All callers changed.
|
||||
|
||||
* src/misc.c (close_fatal): Remove; not used.
|
||||
* src/system.c (sys_utimes): Likewise.
|
||||
|
||||
* src/rmt.c (get_string): Avoid buffer overrun (off by 1 error).
|
||||
|
||||
* src/rmt.c (main): Update copyright date to 2004.
|
||||
* src/tar.c (decode_options): Likewise.
|
||||
|
||||
* src/rtapelib.c (get_status_string): Don't lose errno when
|
||||
skipping the error messages.
|
||||
(get_status): Report an error if atol returns a negative number.
|
||||
|
||||
* src/utf8.c (struct langtab, langtab, charset_lookup,
|
||||
get_input_charset) [!defined HAVE_LIBCONV]: Omit unused
|
||||
definitions.
|
||||
(iconv_open, iconv, iconv_close) [!defined HAVE_LIBCONV]:
|
||||
Use macros, not definitions, to avoid type clashes with system
|
||||
headers.
|
||||
(charset_lookup): Local var is now auto, not static.
|
||||
(utf8_convert): Use ICONV_CONST instead of const, to avoid
|
||||
type clashes.
|
||||
|
||||
* src/utf8.c (langtab): Initialize all elements of struct, to
|
||||
avoid gcc warning.
|
||||
* src/xheader.c (xhdr_tab): Likewise.
|
||||
|
||||
* src/xheader.c: Include fnmatch.h, since we use fnmatch.
|
||||
|
||||
* tests/mksparse.c (mkhole): Fix typo: bool was assigned to off_t.
|
||||
|
||||
2004-04-04 Sergey Poznyakoff <gray@Noldor.runasimi.org>
|
||||
|
||||
* NEWS: Updated
|
||||
@@ -11,7 +165,7 @@
|
||||
* tests/multiv02.sh: New file
|
||||
* tests/Makefile.am: Add sparse01.sh and multiv02.sh
|
||||
* tests/longv7.sh: Added missing call to 'after'
|
||||
|
||||
|
||||
* src/common.h: Added missing prototypes
|
||||
* src/compare.c (diff_archive): Use is_sparse member
|
||||
instead of GNUTYPE_SPARSE.
|
||||
@@ -49,7 +203,7 @@
|
||||
(sparse_numbytes_decoder): Removed unused variable
|
||||
* src/.cvsignore: Added .gdbinit
|
||||
* THANKS: Added Mads Martin Joergensen
|
||||
|
||||
|
||||
2004-03-26 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* src/create.c (write_long_name): Do not allow more than
|
||||
@@ -100,13 +254,13 @@
|
||||
|
||||
which is grossly wrong, since even if new_volume() below succeeds,
|
||||
the subsequent call to rmtread will overwrite the chunk of data
|
||||
already read in the buffer and thus spoil everything.
|
||||
already read in the buffer and thus spoil everything.
|
||||
* src/system.c (sys_child_open_for_uncompress): Minor stylistic
|
||||
fix.
|
||||
* tests/star/multi-fail.sh: New test.
|
||||
* tests/Makefile.am: Added multi-fail.sh
|
||||
* tests/star/README: Updated
|
||||
|
||||
|
||||
2004-02-29 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* NEWS: Updated
|
||||
@@ -116,7 +270,7 @@
|
||||
* src/extract.c: Handle --keep-newer-files option
|
||||
* src/list.c (tartime): Print UTC if --utc was given.
|
||||
* src/tar.c: New options: --utc and keep-newer-files
|
||||
|
||||
|
||||
* tests/Makefile.am: Added new tests
|
||||
* tests/after: Rewritten
|
||||
* tests/before: Rewritten
|
||||
@@ -130,7 +284,7 @@
|
||||
* tests/options.sh: Likewise
|
||||
* tests/version.sh: Likewise
|
||||
* tests/volume.sh: Likewise
|
||||
|
||||
|
||||
* tests/star: New directory
|
||||
* tests/star/README: New file
|
||||
* tests/star/gtarfail.sh: New file
|
||||
@@ -171,7 +325,7 @@
|
||||
|
||||
Added UTF-8 support. Finished global extended header
|
||||
support.
|
||||
|
||||
|
||||
* NEWS: Minor fix
|
||||
* configure.ac: Detect libiconv
|
||||
* src/utf8.c: New file. Conversions to and from utf-8.
|
||||
@@ -188,7 +342,7 @@
|
||||
missing gettext markers
|
||||
(decode_record): Rewritten using caller-provided handler and
|
||||
data closure.
|
||||
* tests/listed01.sh: Give credit to Andreas Schuldei.
|
||||
* tests/listed01.sh: Give credit to Andreas Schuldei.
|
||||
|
||||
2004-02-21 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
@@ -198,8 +352,8 @@
|
||||
<andreas@schuldei.org>.
|
||||
|
||||
This is due to the condition
|
||||
|
||||
(0 < top_level || !incremental_option)
|
||||
|
||||
(0 < top_level || !incremental_option)
|
||||
|
||||
Removing it makes incremental backups work for individual
|
||||
files as well as for directories. On the other hand, it does
|
||||
@@ -217,7 +371,7 @@
|
||||
|
||||
(!incremental_option)
|
||||
|
||||
Now, let's consider the effect of its removal. There are two cases:
|
||||
Now, let's consider the effect of its removal. There are two cases:
|
||||
|
||||
1) when incremental_option==1
|
||||
This means incremental backup in progress. In this case dump_file
|
||||
@@ -234,8 +388,8 @@
|
||||
irrelevant, and its removal won't alter the behavior of tar,
|
||||
*except* that it will enable incremental backups on individual
|
||||
files, which is the wanted effect.
|
||||
|
||||
2) when incremental_option==0
|
||||
|
||||
2) when incremental_option==0
|
||||
In this case the condition yields true and its removal does not
|
||||
affect the functionality.
|
||||
|
||||
@@ -245,7 +399,7 @@
|
||||
* tests/listed01.sh: New test. Check listed incremental
|
||||
backups on individual files.
|
||||
* tests/Makefile.am: Added listed01.sh
|
||||
|
||||
|
||||
2004-02-20 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* src/common.h (simple_finish_header,start_private_header): New
|
||||
@@ -269,7 +423,7 @@
|
||||
|
||||
* src/update.c (update_archive): Write global extended header if
|
||||
constructed.
|
||||
* src/xheader.c (xheader_format_name): Bugfix.
|
||||
* src/xheader.c (xheader_format_name): Bugfix.
|
||||
(xheader_xhdr_name): Changed the default extended header name
|
||||
to '%d/PaxHeaders.%p/%f', as POSIX requires.
|
||||
(xheader_ghdr_name): Removed unused argument.
|
||||
@@ -281,25 +435,25 @@
|
||||
unconditionally.
|
||||
* src/list.c (decode_header): Likewise.
|
||||
* src/incremen.c (sort_obstack): Fixed typo in the comment
|
||||
|
||||
|
||||
* doc/tar.texi: Document new default for extended
|
||||
header names.
|
||||
|
||||
|
||||
* tests/before: Accept an optional list of allowed archive
|
||||
formats. Exit with the status 77 if the current archive
|
||||
format does not match any of them.
|
||||
* tests/delete03.sh: Require gnu, oldgnu or posix format
|
||||
* tests/incremen.sh: Require gnu or oldgnu format
|
||||
* tests/multiv01.sh: Likewise
|
||||
|
||||
|
||||
2004-02-20 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
|
||||
* doc/tar.texi (Option Summary): Documented --pax-option
|
||||
* src/tar.c: Likewise.
|
||||
* NEWS: Likewise.
|
||||
* src/create.c (to_chars): Added a comment.
|
||||
* src/tar.h: Comment to GNU_FORMAT
|
||||
|
||||
|
||||
2004-02-18 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* README: Updated
|
||||
@@ -313,17 +467,17 @@
|
||||
* src/tar.c: New option --pax-option (equivalent to -o option
|
||||
of pax).
|
||||
* src/xheader.c: Implement pax -o option. Fixed misleading
|
||||
heading comment (introduced 2003-09-02).
|
||||
heading comment (introduced 2003-09-02).
|
||||
* src/incremen.c: Minor fixes
|
||||
* m4/.cvsignore: Updated
|
||||
|
||||
|
||||
2004-02-17 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* src/incremen.c: Removed accumulator stuff in favor of obstack.
|
||||
(get_directory_contents): Split into two functions
|
||||
* src/update.c: Minor changes
|
||||
* doc/tar.texi: Fixed typo
|
||||
|
||||
|
||||
2004-02-15 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
Fix Debian bug 230872, originally reported by Jeff King in
|
||||
@@ -863,15 +1017,15 @@
|
||||
|
||||
2003-09-03 Sergey Poznyakoff <gray@Mirddin.farlep.net>
|
||||
|
||||
* src/create.c (start_header): Store long file names
|
||||
in "path" keyword of an extended header if in POSIX
|
||||
mode.
|
||||
(finish_header): print header before calling write_extended().
|
||||
* src/list.c (list_archive): Always decode the header. This
|
||||
is necessary so the extended header is processed and the correct
|
||||
filename is printed no matter what the state of verbose_option.
|
||||
* src/xheader.c (xhdr_tab): Reserved GNU keywords (commented out
|
||||
for the time being).
|
||||
* src/create.c (start_header): Store long file names
|
||||
in "path" keyword of an extended header if in POSIX
|
||||
mode.
|
||||
(finish_header): print header before calling write_extended().
|
||||
* src/list.c (list_archive): Always decode the header. This
|
||||
is necessary so the extended header is processed and the correct
|
||||
filename is printed no matter what the state of verbose_option.
|
||||
* src/xheader.c (xhdr_tab): Reserved GNU keywords (commented out
|
||||
for the time being).
|
||||
|
||||
2003-09-01 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
|
||||
16
bootstrap
16
bootstrap
@@ -2,7 +2,7 @@
|
||||
|
||||
# Bootstrap 'tar' from CVS.
|
||||
|
||||
# Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2003, 2004 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
|
||||
@@ -42,10 +42,10 @@ usage() {
|
||||
--no-po Do not download po files.
|
||||
|
||||
Running without arguments will suffice in most cases. It is equivalent
|
||||
to
|
||||
to
|
||||
|
||||
./bootstrap --cvs-auth=ext --cvs-user=anoncvs
|
||||
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ build_cvs_prefix() {
|
||||
CVS_RSH=ssh
|
||||
export CVS_RSH
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Get gnulib files.
|
||||
@@ -96,15 +96,15 @@ case ${GNULIB_SRCDIR--} in
|
||||
|
||||
trap exit 1 2 13 15
|
||||
trap 'rm -fr gnulib; exit 1' 0
|
||||
|
||||
|
||||
case "${CVS_AUTH--}" in
|
||||
-) build_cvs_prefix ext anoncvs;;
|
||||
pserver) build_cvs_prefix $CVS_AUTH ${CVS_USER:-anoncvs};;
|
||||
gserver|server)
|
||||
build_cvs_prefix $CVS_AUTH ${CVS_USER--};;
|
||||
build_cvs_prefix $CVS_AUTH ${CVS_USER--};;
|
||||
ext) build_cvs_prefix $CVS_AUTH ${CVS_USER--};;
|
||||
*) echo "$0: Unknown CVS access method" >&2
|
||||
exit 1;;
|
||||
exit 1;;
|
||||
esac
|
||||
if [ "${CVS_AUTH--}" = "pserver" ]; then
|
||||
cvs -d ${CVS_PREFIX}subversions.gnu.org:/cvsroot/gnulib login || exit
|
||||
@@ -133,6 +133,7 @@ getdate
|
||||
getline
|
||||
getopt
|
||||
gettext
|
||||
gettime
|
||||
hash
|
||||
human
|
||||
lchown
|
||||
@@ -149,6 +150,7 @@ stdbool
|
||||
stpcpy
|
||||
strtol
|
||||
strtoul
|
||||
timespec
|
||||
unlocked-io
|
||||
utime
|
||||
xalloc
|
||||
|
||||
@@ -119,6 +119,7 @@ gl_FUNC_STRTOIMAX
|
||||
gl_FUNC_STRTOUMAX
|
||||
gl_GETDATE
|
||||
gl_GETOPT
|
||||
gl_GETTIME
|
||||
gl_HASH
|
||||
gl_HUMAN
|
||||
gl_MODECHANGE
|
||||
@@ -132,6 +133,7 @@ gl_SAVE_CWD
|
||||
gl_SAVEDIR
|
||||
gl_STRCASE
|
||||
gl_TIME_R
|
||||
gl_TIMESPEC
|
||||
gl_XALLOC
|
||||
gl_XGETCWD
|
||||
gl_XSTRTOL
|
||||
@@ -150,7 +152,7 @@ AC_CHECK_MEMBERS([struct stat.st_spare1, struct stat.st_atim.tv_nsec, struct sta
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>])
|
||||
|
||||
|
||||
# Save and restore LIBS so e.g., -lrt, isn't added to it. Otherwise, *all*
|
||||
# programs in the package would end up linked with that potentially-shared
|
||||
# library, inducing unnecessary run-time overhead.
|
||||
|
||||
@@ -37,7 +37,10 @@ getndelim2.h
|
||||
getopt.c
|
||||
getopt.h
|
||||
getopt1.c
|
||||
getopt_int.h
|
||||
gettext.h
|
||||
gettime.c
|
||||
gettimeofday.c
|
||||
hash.c
|
||||
hash.h
|
||||
human.c
|
||||
@@ -68,6 +71,8 @@ savedir.c
|
||||
savedir.h
|
||||
stdbool.h
|
||||
stdbool_.h
|
||||
stpcpy.c
|
||||
stpcpy.h
|
||||
strcase.h
|
||||
strcasecmp.c
|
||||
stripslash.c
|
||||
@@ -78,10 +83,9 @@ strtoll.c
|
||||
strtoul.c
|
||||
strtoull.c
|
||||
strtoumax.c
|
||||
stpcpy.c
|
||||
stpcpy.h
|
||||
time_r.c
|
||||
time_r.h
|
||||
timespec.h
|
||||
unlocked-io.h
|
||||
utime.c
|
||||
xalloc.h
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Makefile for GNU tar library.
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003 Free
|
||||
# Software Foundation, Inc.
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003, 2004
|
||||
# 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
|
||||
@@ -103,6 +103,9 @@ libtar_a_SOURCES += getopt.h getopt.c getopt1.c
|
||||
# gettext
|
||||
libtar_a_SOURCES += gettext.h
|
||||
|
||||
# gettime
|
||||
libtar_a_SOURCES += gettime.c
|
||||
|
||||
# hash
|
||||
libtar_a_SOURCES += hash.h hash.c
|
||||
|
||||
@@ -121,6 +124,9 @@ libtar_a_SOURCES += pathmax.h
|
||||
# time_r
|
||||
EXTRA_DIST += time_r.h
|
||||
|
||||
# timespec
|
||||
libtar_a_SOURCES += timespec.h
|
||||
|
||||
# quote
|
||||
libtar_a_SOURCES += quote.h quote.c
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ alloca.m4
|
||||
backupfile.m4
|
||||
bison.m4
|
||||
chown.m4
|
||||
clock_time.m4
|
||||
codeset.m4
|
||||
d-ino.m4
|
||||
dirname.m4
|
||||
@@ -21,6 +22,8 @@ getline.m4
|
||||
getndelim2.m4
|
||||
getopt.m4
|
||||
gettext.m4
|
||||
gettime.m4
|
||||
gettimeofday.m4
|
||||
glibc21.m4
|
||||
hash.m4
|
||||
human.m4
|
||||
@@ -39,7 +42,6 @@ lib-link.m4
|
||||
lib-prefix.m4
|
||||
longdouble.m4
|
||||
longlong.m4
|
||||
malloc.m4
|
||||
mbrtowc.m4
|
||||
mbstate_t.m4
|
||||
memset.m4
|
||||
@@ -54,7 +56,6 @@ printf-posix.m4
|
||||
progtest.m4
|
||||
quote.m4
|
||||
quotearg.m4
|
||||
realloc.m4
|
||||
restrict.m4
|
||||
rmdir.m4
|
||||
safe-read.m4
|
||||
@@ -64,8 +65,10 @@ savedir.m4
|
||||
signed.m4
|
||||
size_max.m4
|
||||
ssize_t.m4
|
||||
st_mtim.m4
|
||||
stdbool.m4
|
||||
stdint_h.m4
|
||||
stpcpy.m4
|
||||
strcase.m4
|
||||
strerror_r.m4
|
||||
strtoimax.m4
|
||||
@@ -74,8 +77,8 @@ strtoll.m4
|
||||
strtoul.m4
|
||||
strtoull.m4
|
||||
strtoumax.m4
|
||||
stpcpy.m4
|
||||
time_r.m4
|
||||
timespec.m4
|
||||
tm_gmtoff.m4
|
||||
uintmax_t.m4
|
||||
ulonglong.m4
|
||||
|
||||
42
src/buffer.c
42
src/buffer.c
@@ -75,7 +75,7 @@ static int checkpoint;
|
||||
Declared in update.c
|
||||
|
||||
As least EXTERN like this one as possible. (?? --gray)
|
||||
FIXME: Either eliminate it or move it to common.h.
|
||||
FIXME: Either eliminate it or move it to common.h.
|
||||
*/
|
||||
extern bool time_to_start_writing;
|
||||
|
||||
@@ -109,7 +109,7 @@ static off_t real_s_sizeleft;
|
||||
/* Functions. */
|
||||
|
||||
void
|
||||
clear_read_error_count ()
|
||||
clear_read_error_count (void)
|
||||
{
|
||||
read_error_count = 0;
|
||||
}
|
||||
@@ -600,7 +600,7 @@ archive_read_error (void)
|
||||
}
|
||||
|
||||
static void
|
||||
short_read (ssize_t status)
|
||||
short_read (size_t status)
|
||||
{
|
||||
size_t left; /* bytes left */
|
||||
char *more; /* pointer to next byte to read */
|
||||
@@ -612,23 +612,23 @@ short_read (ssize_t status)
|
||||
|| (left && status && read_full_records_option))
|
||||
{
|
||||
if (status)
|
||||
while ((status = rmtread (archive, more, left)) < 0)
|
||||
while ((status = rmtread (archive, more, left)) == SAFE_READ_ERROR)
|
||||
archive_read_error ();
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
char buf[UINTMAX_STRSIZE_BOUND];
|
||||
|
||||
|
||||
WARN((0, 0, _("Read %s bytes from %s"),
|
||||
STRINGIFY_BIGINT (record_size - left, buf),
|
||||
*archive_name_cursor));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (! read_full_records_option)
|
||||
{
|
||||
unsigned long rest = record_size - left;
|
||||
|
||||
|
||||
FATAL_ERROR ((0, 0,
|
||||
ngettext ("Unaligned block (%lu byte) in archive",
|
||||
"Unaligned block (%lu bytes) in archive",
|
||||
@@ -646,7 +646,7 @@ short_read (ssize_t status)
|
||||
about the problem. */
|
||||
|
||||
if (!read_full_records_option && verbose_option > 1
|
||||
&& record_start_block == 0 && status > 0)
|
||||
&& record_start_block == 0 && status != 0)
|
||||
{
|
||||
unsigned long rsize = (record_size - left) / BLOCKSIZE;
|
||||
WARN ((0, 0,
|
||||
@@ -664,7 +664,7 @@ short_read (ssize_t status)
|
||||
void
|
||||
flush_read (void)
|
||||
{
|
||||
ssize_t status; /* result from system call */
|
||||
size_t status; /* result from system call */
|
||||
|
||||
if (checkpoint_option && !(++checkpoint % 10))
|
||||
WARN ((0, 0, _("Read checkpoint %d"), checkpoint));
|
||||
@@ -711,9 +711,9 @@ flush_read (void)
|
||||
This is incorrect since even if new_volume() succeeds, the
|
||||
subsequent call to rmtread will overwrite the chunk of data
|
||||
already read in the buffer, so the processing will fail */
|
||||
|
||||
|
||||
if ((status == 0
|
||||
|| (status < 0 && errno == ENOSPC))
|
||||
|| (status == SAFE_READ_ERROR && errno == ENOSPC))
|
||||
&& multi_volume_option)
|
||||
{
|
||||
union block *cursor;
|
||||
@@ -734,12 +734,12 @@ flush_read (void)
|
||||
break;
|
||||
}
|
||||
|
||||
while ((status =
|
||||
rmtread (archive, record_start->buffer, record_size)) < 0)
|
||||
while ((status = rmtread (archive, record_start->buffer, record_size))
|
||||
== SAFE_READ_ERROR)
|
||||
archive_read_error ();
|
||||
|
||||
|
||||
if (status != record_size)
|
||||
short_read (status);
|
||||
short_read (status);
|
||||
|
||||
cursor = record_start;
|
||||
|
||||
@@ -807,7 +807,7 @@ flush_read (void)
|
||||
records_read++;
|
||||
return;
|
||||
}
|
||||
else if (status < 0)
|
||||
else if (status == SAFE_READ_ERROR)
|
||||
{
|
||||
archive_read_error ();
|
||||
goto error_loop; /* try again */
|
||||
@@ -897,7 +897,7 @@ close_archive (void)
|
||||
flush_archive ();
|
||||
|
||||
sys_drain_input_pipe ();
|
||||
|
||||
|
||||
if (verify_option)
|
||||
verify_volume ();
|
||||
|
||||
@@ -905,7 +905,7 @@ close_archive (void)
|
||||
close_warn (*archive_name_cursor);
|
||||
|
||||
sys_wait_for_child (child_pid);
|
||||
|
||||
|
||||
tar_stat_destroy (¤t_stat_info);
|
||||
if (save_name)
|
||||
free (save_name);
|
||||
@@ -957,7 +957,7 @@ closeout_volume_number (void)
|
||||
Return nonzero on success.
|
||||
*/
|
||||
static bool
|
||||
new_volume (enum access_mode access)
|
||||
new_volume (enum access_mode mode)
|
||||
{
|
||||
static FILE *read_file;
|
||||
static int looped;
|
||||
@@ -1086,7 +1086,7 @@ new_volume (enum access_mode access)
|
||||
archive = rmtopen (*archive_name_cursor, O_RDWR | O_CREAT, MODE_RW,
|
||||
rsh_command_option);
|
||||
else
|
||||
switch (access)
|
||||
switch (mode)
|
||||
{
|
||||
case ACCESS_READ:
|
||||
archive = rmtopen (*archive_name_cursor, O_RDONLY, MODE_RW,
|
||||
@@ -1109,7 +1109,7 @@ new_volume (enum access_mode access)
|
||||
if (archive < 0)
|
||||
{
|
||||
open_warn (*archive_name_cursor);
|
||||
if (!verify_option && access == ACCESS_WRITE && backup_option)
|
||||
if (!verify_option && mode == ACCESS_WRITE && backup_option)
|
||||
undo_last_backup ();
|
||||
goto tryagain;
|
||||
}
|
||||
|
||||
56
src/common.h
56
src/common.h
@@ -1,7 +1,7 @@
|
||||
/* Common declarations for the tar program.
|
||||
|
||||
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
||||
2003 Free Software Foundation, Inc.
|
||||
2003, 2004 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
|
||||
@@ -85,6 +85,7 @@ GLOBAL int exit_status;
|
||||
#include <modechange.h>
|
||||
#include <quote.h>
|
||||
#include <safe-read.h>
|
||||
#include <timespec.h>
|
||||
|
||||
/* Log base 2 of common values. */
|
||||
#define LG_8 3
|
||||
@@ -189,7 +190,7 @@ enum old_files
|
||||
OVERWRITE_OLD_FILES, /* --overwrite */
|
||||
UNLINK_FIRST_OLD_FILES, /* --unlink-first */
|
||||
KEEP_OLD_FILES, /* --keep-old-files */
|
||||
KEEP_NEWER_FILES, /* --keep-newer-files */
|
||||
KEEP_NEWER_FILES /* --keep-newer-files */
|
||||
};
|
||||
GLOBAL enum old_files old_files_option;
|
||||
|
||||
@@ -201,13 +202,23 @@ GLOBAL struct mode_change *mode_option;
|
||||
|
||||
GLOBAL bool multi_volume_option;
|
||||
|
||||
/* The same variable hold the time, whether mtime or ctime. Just fake a
|
||||
/* The same variable holds the time, whether mtime or ctime. Just fake a
|
||||
non-existing option, for making the code clearer, elsewhere. */
|
||||
#define newer_ctime_option newer_mtime_option
|
||||
|
||||
/* Specified threshold date and time. Files having an older time stamp
|
||||
do not get archived (also see after_date_option above). */
|
||||
GLOBAL time_t newer_mtime_option;
|
||||
GLOBAL struct timespec newer_mtime_option;
|
||||
|
||||
/* Return true if newer_mtime_option is initialized. */
|
||||
#define NEWER_OPTION_INITIALIZED(opt) (0 <= (opt).tv_nsec)
|
||||
|
||||
/* Return true if the struct stat ST's M time is less than
|
||||
newer_mtime_option. */
|
||||
#define OLDER_STAT_TIME(st, m) \
|
||||
((st).st_##m##time < newer_mtime_option.tv_sec \
|
||||
|| ((st).st_##m##time == newer_mtime_option.tv_sec \
|
||||
&& TIMESPEC_NS ((st).st_##m##tim) < newer_mtime_option.tv_nsec))
|
||||
|
||||
/* Zero if there is no recursion, otherwise FNM_LEADING_DIR. */
|
||||
GLOBAL int recursion_option;
|
||||
@@ -367,7 +378,7 @@ enum dump_status
|
||||
dump_status_not_implemented
|
||||
};
|
||||
|
||||
bool file_dumpable_p (struct tar_stat_info *stat);
|
||||
bool file_dumpable_p (struct tar_stat_info *);
|
||||
void create_archive (void);
|
||||
void pad_archive (off_t size_left);
|
||||
void dump_file (char *, int, dev_t);
|
||||
@@ -535,7 +546,7 @@ void open_diag (char const *name);
|
||||
void read_error (char const *);
|
||||
void read_error_details (char const *, off_t, size_t);
|
||||
void read_fatal (char const *) __attribute__ ((noreturn));
|
||||
void read_fatal_details (char const *, off_t, size_t);
|
||||
void read_fatal_details (char const *, off_t, size_t) __attribute__ ((noreturn));
|
||||
void read_warn_details (char const *, off_t, size_t);
|
||||
void read_diag_details (char const *name, off_t offset, size_t size);
|
||||
void readlink_error (char const *);
|
||||
@@ -559,7 +570,7 @@ void unlink_error (char const *);
|
||||
void utime_error (char const *);
|
||||
void waitpid_error (char const *);
|
||||
void write_error (char const *);
|
||||
void write_error_details (char const *, ssize_t, size_t);
|
||||
void write_error_details (char const *, size_t, size_t);
|
||||
void write_fatal (char const *) __attribute__ ((noreturn));
|
||||
void write_fatal_details (char const *, ssize_t, size_t)
|
||||
__attribute__ ((noreturn));
|
||||
@@ -572,13 +583,13 @@ void xpipe (int[2]);
|
||||
extern struct name *gnu_list_name;
|
||||
|
||||
void gid_to_gname (gid_t, char **gname);
|
||||
int gname_to_gid (char *gname, gid_t *);
|
||||
int gname_to_gid (char const *, gid_t *);
|
||||
void uid_to_uname (uid_t, char **uname);
|
||||
int uname_to_uid (char *uname, uid_t *);
|
||||
int uname_to_uid (char const *, uid_t *);
|
||||
|
||||
void init_names (void);
|
||||
void name_add (const char *);
|
||||
void name_init (int, char *const *);
|
||||
void name_init (void);
|
||||
void name_term (void);
|
||||
char *name_next (int);
|
||||
void name_close (void);
|
||||
@@ -609,6 +620,8 @@ bool contains_dot_dot (char const *);
|
||||
|
||||
/* Module tar.c. */
|
||||
|
||||
void usage (int);
|
||||
|
||||
int confirm (const char *, const char *);
|
||||
void request_stdin (const char *);
|
||||
|
||||
@@ -634,11 +647,13 @@ void xheader_finish (struct xheader *);
|
||||
void xheader_destroy (struct xheader *);
|
||||
char *xheader_xhdr_name (struct tar_stat_info *st);
|
||||
char *xheader_ghdr_name (void);
|
||||
void xheader_write (char, char *, struct xheader *);
|
||||
void xheader_write_global (void);
|
||||
void xheader_set_option (char *string);
|
||||
|
||||
/* Module system.c */
|
||||
|
||||
void sys_stat_nanoseconds (struct tar_stat_info *stat);
|
||||
void sys_stat_nanoseconds (struct tar_stat_info *);
|
||||
void sys_detect_dev_null_output (void);
|
||||
void sys_save_archive_dev_ino (void);
|
||||
void sys_drain_input_pipe (void);
|
||||
@@ -652,7 +667,8 @@ int sys_truncate (int fd);
|
||||
void sys_reset_uid_gid (void);
|
||||
pid_t sys_child_open_for_compress (void);
|
||||
pid_t sys_child_open_for_uncompress (void);
|
||||
ssize_t sys_write_archive_buffer (void);
|
||||
void sys_reset_uid_gid (void);
|
||||
size_t sys_write_archive_buffer (void);
|
||||
bool sys_get_archive_stat (void);
|
||||
void sys_reset_uid_gid (void);
|
||||
|
||||
@@ -660,14 +676,14 @@ void sys_reset_uid_gid (void);
|
||||
void report_difference (struct tar_stat_info *st, const char *message, ...);
|
||||
|
||||
/* Module sparse.c */
|
||||
bool sparse_file_p (struct tar_stat_info *stat);
|
||||
bool sparse_member_p (struct tar_stat_info *stat);
|
||||
bool sparse_fixup_header (struct tar_stat_info *stat);
|
||||
enum dump_status sparse_dump_file (int fd, struct tar_stat_info *stat);
|
||||
enum dump_status sparse_extract_file (int fd, struct tar_stat_info *stat, off_t *size);
|
||||
enum dump_status sparse_skip_file (struct tar_stat_info *stat);
|
||||
bool sparse_diff_file (int fd, struct tar_stat_info *stat);
|
||||
bool sparse_file_p (struct tar_stat_info *);
|
||||
bool sparse_member_p (struct tar_stat_info *);
|
||||
bool sparse_fixup_header (struct tar_stat_info *);
|
||||
enum dump_status sparse_dump_file (int, struct tar_stat_info *);
|
||||
enum dump_status sparse_extract_file (int, struct tar_stat_info *, off_t *);
|
||||
enum dump_status sparse_skip_file (struct tar_stat_info *);
|
||||
bool sparse_diff_file (int, struct tar_stat_info *);
|
||||
|
||||
/* Module utf8.c */
|
||||
bool string_ascii_p (const char *str);
|
||||
bool utf8_convert(bool to_utf, const char *input, char **output);
|
||||
bool utf8_convert (bool to_utf, char const *input, char **output);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Diff files from a tar archive.
|
||||
|
||||
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
||||
2003 Free Software Foundation, Inc.
|
||||
2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
Written by John Gilmore, on 1987-04-30.
|
||||
|
||||
@@ -62,7 +62,8 @@ diff_init (void)
|
||||
/* Sigh about something that differs by writing a MESSAGE to stdlis,
|
||||
given MESSAGE is nonzero. Also set the exit status if not already. */
|
||||
void
|
||||
report_difference (struct tar_stat_info *st, const char *fmt, ...)
|
||||
report_difference (struct tar_stat_info *st __attribute__ ((unused)),
|
||||
const char *fmt, ...)
|
||||
{
|
||||
if (fmt)
|
||||
{
|
||||
@@ -74,35 +75,34 @@ report_difference (struct tar_stat_info *st, const char *fmt, ...)
|
||||
va_end (ap);
|
||||
fprintf (stdlis, "\n");
|
||||
}
|
||||
|
||||
|
||||
if (exit_status == TAREXIT_SUCCESS)
|
||||
exit_status = TAREXIT_DIFFERS;
|
||||
}
|
||||
|
||||
/* Take a buffer returned by read_and_process and do nothing with it. */
|
||||
static int
|
||||
process_noop (size_t size, char *data)
|
||||
process_noop (size_t size __attribute__ ((unused)),
|
||||
char *data __attribute__ ((unused)))
|
||||
{
|
||||
/* Yes, I know. SIZE and DATA are unused in this function. Some
|
||||
compilers may even report it. That's OK, just relax! */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
process_rawdata (size_t bytes, char *buffer)
|
||||
{
|
||||
ssize_t status = safe_read (diff_handle, diff_buffer, bytes);
|
||||
size_t status = safe_read (diff_handle, diff_buffer, bytes);
|
||||
|
||||
if (status != bytes)
|
||||
{
|
||||
if (status < 0)
|
||||
if (status == SAFE_READ_ERROR)
|
||||
{
|
||||
read_error (current_stat_info.file_name);
|
||||
report_difference (¤t_stat_info, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
report_difference (¤t_stat_info,
|
||||
report_difference (¤t_stat_info,
|
||||
ngettext ("Could only read %lu of %lu byte",
|
||||
"Could only read %lu of %lu bytes",
|
||||
bytes),
|
||||
@@ -308,19 +308,20 @@ diff_archive (void)
|
||||
|
||||
case LNKTYPE:
|
||||
{
|
||||
struct stat link_data, stat_data;
|
||||
struct stat file_data;
|
||||
struct stat link_data;
|
||||
|
||||
if (!get_stat_data (current_stat_info.file_name, &stat_data))
|
||||
if (!get_stat_data (current_stat_info.file_name, &file_data))
|
||||
break;
|
||||
if (!get_stat_data (current_stat_info.link_name, &link_data))
|
||||
break;
|
||||
if (!sys_compare_links (&stat_data, &link_data))
|
||||
if (!sys_compare_links (&file_data, &link_data))
|
||||
report_difference (¤t_stat_info,
|
||||
_("Not linked to %s"),
|
||||
quote (current_stat_info.link_name));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
#ifdef HAVE_READLINK
|
||||
case SYMTYPE:
|
||||
{
|
||||
|
||||
303
src/create.c
303
src/create.c
@@ -337,11 +337,11 @@ string_to_chars (char *str, char *p, size_t s)
|
||||
b) current archive is /dev/null */
|
||||
|
||||
bool
|
||||
file_dumpable_p (struct tar_stat_info *stat)
|
||||
file_dumpable_p (struct tar_stat_info *st)
|
||||
{
|
||||
return !(dev_null_output
|
||||
|| (stat->archive_file_size == 0
|
||||
&& (stat->stat.st_mode & MODE_R) == MODE_R));
|
||||
|| (st->archive_file_size == 0
|
||||
&& (st->stat.st_mode & MODE_R) == MODE_R));
|
||||
}
|
||||
|
||||
|
||||
@@ -376,7 +376,7 @@ start_private_header (const char *name, size_t size)
|
||||
{
|
||||
time_t t;
|
||||
union block *header = find_next_block ();
|
||||
|
||||
|
||||
memset (header->buffer, 0, sizeof (union block));
|
||||
|
||||
tar_copy_str (header->header.name, name, NAME_FIELD_SIZE);
|
||||
@@ -397,7 +397,7 @@ start_private_header (const char *name, size_t size)
|
||||
/* Create a new header and store there at most NAME_FIELD_SIZE bytes of
|
||||
the file name */
|
||||
|
||||
static union block *
|
||||
static union block *
|
||||
write_short_name (struct tar_stat_info *st)
|
||||
{
|
||||
union block *header = find_next_block ();
|
||||
@@ -464,7 +464,7 @@ write_ustar_long_name (const char *name)
|
||||
PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
i = split_long_name (name, length);
|
||||
if (i == 0 || length - i - 1 > NAME_FIELD_SIZE)
|
||||
{
|
||||
@@ -478,7 +478,7 @@ write_ustar_long_name (const char *name)
|
||||
memset (header->buffer, 0, sizeof (header->buffer));
|
||||
memcpy (header->header.prefix, name, i);
|
||||
memcpy (header->header.name, name + i + 1, length - i - 1);
|
||||
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
@@ -499,7 +499,7 @@ write_long_link (struct tar_stat_info *st)
|
||||
_("%s: link name is too long; not dumped"),
|
||||
quotearg_colon (st->link_name)));
|
||||
break;
|
||||
|
||||
|
||||
case OLDGNU_FORMAT:
|
||||
case GNU_FORMAT:
|
||||
write_gnu_long_link (st, st->link_name, GNUTYPE_LONGLINK);
|
||||
@@ -528,11 +528,11 @@ write_long_name (struct tar_stat_info *st)
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case USTAR_FORMAT:
|
||||
case STAR_FORMAT:
|
||||
return write_ustar_long_name (st->file_name);
|
||||
|
||||
|
||||
case OLDGNU_FORMAT:
|
||||
case GNU_FORMAT:
|
||||
write_gnu_long_link (st, st->file_name, GNUTYPE_LONGNAME);
|
||||
@@ -543,7 +543,7 @@ write_long_name (struct tar_stat_info *st)
|
||||
}
|
||||
return write_short_name (st);
|
||||
}
|
||||
|
||||
|
||||
static union block *
|
||||
write_extended (struct tar_stat_info *st, union block *old_header)
|
||||
{
|
||||
@@ -551,8 +551,8 @@ write_extended (struct tar_stat_info *st, union block *old_header)
|
||||
char *p;
|
||||
|
||||
if (extended_header.buffer || extended_header.stk == NULL)
|
||||
return old_header;
|
||||
|
||||
return old_header;
|
||||
|
||||
xheader_finish (&extended_header);
|
||||
memcpy (hp.buffer, old_header, sizeof (hp));
|
||||
p = xheader_xhdr_name (st);
|
||||
@@ -563,7 +563,7 @@ write_extended (struct tar_stat_info *st, union block *old_header)
|
||||
return header;
|
||||
}
|
||||
|
||||
static union block *
|
||||
static union block *
|
||||
write_header_name (struct tar_stat_info *st)
|
||||
{
|
||||
if (archive_format == POSIX_FORMAT && !string_ascii_p (st->file_name))
|
||||
@@ -634,7 +634,7 @@ start_header (struct tar_stat_info *st)
|
||||
xheader_store ("uid", st, NULL);
|
||||
else
|
||||
UID_TO_CHARS (st->stat.st_uid, header->header.uid);
|
||||
|
||||
|
||||
if (st->stat.st_gid > MAXOCTAL7 && archive_format == POSIX_FORMAT)
|
||||
xheader_store ("gid", st, NULL);
|
||||
else
|
||||
@@ -669,7 +669,7 @@ start_header (struct tar_stat_info *st)
|
||||
MAJOR_TO_CHARS (0, header->header.devmajor);
|
||||
MINOR_TO_CHARS (0, header->header.devminor);
|
||||
}
|
||||
|
||||
|
||||
if (archive_format == POSIX_FORMAT)
|
||||
{
|
||||
xheader_store ("atime", st, NULL);
|
||||
@@ -713,7 +713,7 @@ start_header (struct tar_stat_info *st)
|
||||
{
|
||||
uid_to_uname (st->stat.st_uid, &st->uname);
|
||||
gid_to_gname (st->stat.st_gid, &st->gname);
|
||||
|
||||
|
||||
if (archive_format == POSIX_FORMAT
|
||||
&& (strlen (st->uname) > UNAME_FIELD_SIZE
|
||||
|| !string_ascii_p (st->uname)))
|
||||
@@ -802,40 +802,40 @@ pad_archive (off_t size_left)
|
||||
set_next_block_after (blk);
|
||||
size_left -= BLOCKSIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static enum dump_status
|
||||
dump_regular_file (int fd, struct tar_stat_info *stat)
|
||||
dump_regular_file (int fd, struct tar_stat_info *st)
|
||||
{
|
||||
off_t size_left = stat->stat.st_size;
|
||||
off_t size_left = st->stat.st_size;
|
||||
off_t block_ordinal;
|
||||
union block *blk;
|
||||
|
||||
|
||||
block_ordinal = current_block_ordinal ();
|
||||
blk = start_header (stat);
|
||||
blk = start_header (st);
|
||||
if (!blk)
|
||||
return dump_status_fail;
|
||||
|
||||
/* Mark contiguous files, if we support them. */
|
||||
if (archive_format != V7_FORMAT && S_ISCTG (stat->stat.st_mode))
|
||||
if (archive_format != V7_FORMAT && S_ISCTG (st->stat.st_mode))
|
||||
blk->header.typeflag = CONTTYPE;
|
||||
|
||||
finish_header (stat, blk, block_ordinal);
|
||||
finish_header (st, blk, block_ordinal);
|
||||
|
||||
while (size_left > 0)
|
||||
{
|
||||
size_t bufsize, count;
|
||||
|
||||
|
||||
if (multi_volume_option)
|
||||
{
|
||||
assign_string (&save_name, stat->file_name);
|
||||
assign_string (&save_name, st->file_name);
|
||||
save_sizeleft = size_left;
|
||||
save_totsize = stat->stat.st_size;
|
||||
save_totsize = st->stat.st_size;
|
||||
}
|
||||
blk = find_next_block ();
|
||||
|
||||
|
||||
bufsize = available_space_after (blk);
|
||||
|
||||
|
||||
if (size_left < bufsize)
|
||||
{
|
||||
/* Last read -- zero out area beyond. */
|
||||
@@ -844,12 +844,12 @@ dump_regular_file (int fd, struct tar_stat_info *stat)
|
||||
if (count)
|
||||
memset (blk->buffer + size_left, 0, BLOCKSIZE - count);
|
||||
}
|
||||
|
||||
|
||||
count = (fd < 0) ? bufsize : safe_read (fd, blk->buffer, bufsize);
|
||||
if (count < 0)
|
||||
if (count == SAFE_READ_ERROR)
|
||||
{
|
||||
read_diag_details (stat->orig_file_name,
|
||||
stat->stat.st_size - size_left, bufsize);
|
||||
read_diag_details (st->orig_file_name,
|
||||
st->stat.st_size - size_left, bufsize);
|
||||
pad_archive (size_left);
|
||||
return dump_status_short;
|
||||
}
|
||||
@@ -865,7 +865,7 @@ dump_regular_file (int fd, struct tar_stat_info *stat)
|
||||
ngettext ("%s: File shrank by %s byte; padding with zeros",
|
||||
"%s: File shrank by %s bytes; padding with zeros",
|
||||
size_left),
|
||||
quotearg_colon (stat->orig_file_name),
|
||||
quotearg_colon (st->orig_file_name),
|
||||
STRINGIFY_BIGINT (size_left, buf)));
|
||||
if (! ignore_failed_read_option)
|
||||
exit_status = TAREXIT_FAILURE;
|
||||
@@ -876,7 +876,7 @@ dump_regular_file (int fd, struct tar_stat_info *stat)
|
||||
return dump_status_ok;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
dump_regular_finish (int fd, struct tar_stat_info *st, time_t original_ctime)
|
||||
{
|
||||
if (fd >= 0)
|
||||
@@ -903,22 +903,22 @@ dump_regular_finish (int fd, struct tar_stat_info *st, time_t original_ctime)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
dump_dir0 (char *directory,
|
||||
struct tar_stat_info *stat, int top_level, dev_t parent_device)
|
||||
struct tar_stat_info *st, int top_level, dev_t parent_device)
|
||||
{
|
||||
dev_t our_device = stat->stat.st_dev;
|
||||
|
||||
if (!is_avoided_name (stat->orig_file_name))
|
||||
dev_t our_device = st->stat.st_dev;
|
||||
|
||||
if (!is_avoided_name (st->orig_file_name))
|
||||
{
|
||||
union block *blk = NULL;
|
||||
off_t block_ordinal = current_block_ordinal ();
|
||||
stat->stat.st_size = 0; /* force 0 size on dir */
|
||||
st->stat.st_size = 0; /* force 0 size on dir */
|
||||
|
||||
blk = start_header (stat);
|
||||
blk = start_header (st);
|
||||
if (!blk)
|
||||
return;
|
||||
|
||||
|
||||
if (incremental_option)
|
||||
blk->header.typeflag = GNUTYPE_DUMPDIR;
|
||||
else /* if (standard_option) */
|
||||
@@ -927,7 +927,7 @@ dump_dir0 (char *directory,
|
||||
/* If we're gnudumping, we aren't done yet so don't close it. */
|
||||
|
||||
if (!incremental_option)
|
||||
finish_header (stat, blk, block_ordinal);
|
||||
finish_header (st, blk, block_ordinal);
|
||||
else if (gnu_list_name->dir_contents)
|
||||
{
|
||||
off_t size_left;
|
||||
@@ -935,8 +935,8 @@ dump_dir0 (char *directory,
|
||||
size_t bufsize;
|
||||
ssize_t count;
|
||||
const char *buffer, *p_buffer;
|
||||
off_t block_ordinal = current_block_ordinal ();
|
||||
|
||||
|
||||
block_ordinal = current_block_ordinal ();
|
||||
buffer = gnu_list_name->dir_contents; /* FOO */
|
||||
totsize = 0;
|
||||
if (buffer)
|
||||
@@ -948,14 +948,14 @@ dump_dir0 (char *directory,
|
||||
}
|
||||
totsize++;
|
||||
OFF_TO_CHARS (totsize, blk->header.size);
|
||||
finish_header (stat, blk, block_ordinal);
|
||||
finish_header (st, blk, block_ordinal);
|
||||
p_buffer = buffer;
|
||||
size_left = totsize;
|
||||
while (size_left > 0)
|
||||
{
|
||||
if (multi_volume_option)
|
||||
{
|
||||
assign_string (&save_name, stat->orig_file_name);
|
||||
assign_string (&save_name, st->orig_file_name);
|
||||
save_sizeleft = size_left;
|
||||
save_totsize = totsize;
|
||||
}
|
||||
@@ -984,25 +984,25 @@ dump_dir0 (char *directory,
|
||||
|
||||
if (one_file_system_option
|
||||
&& !top_level
|
||||
&& parent_device != stat->stat.st_dev)
|
||||
&& parent_device != st->stat.st_dev)
|
||||
{
|
||||
if (verbose_option)
|
||||
WARN ((0, 0,
|
||||
_("%s: file is on a different filesystem; not dumped"),
|
||||
quotearg_colon (stat->orig_file_name)));
|
||||
quotearg_colon (st->orig_file_name)));
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
char const *entry;
|
||||
size_t entry_len;
|
||||
char *name_buf = strdup (stat->orig_file_name);
|
||||
char *name_buf = strdup (st->orig_file_name);
|
||||
size_t name_size = strlen (name_buf);
|
||||
size_t name_len = name_size;
|
||||
|
||||
|
||||
/* Now output all the files in the directory. */
|
||||
/* FIXME: Should speed this up by cd-ing into the dir. */
|
||||
|
||||
|
||||
for (entry = directory; (entry_len = strlen (entry)) != 0;
|
||||
entry += entry_len + 1)
|
||||
{
|
||||
@@ -1015,7 +1015,7 @@ dump_dir0 (char *directory,
|
||||
if (!excluded_name (name_buf))
|
||||
dump_file (name_buf, 0, our_device);
|
||||
}
|
||||
|
||||
|
||||
free (name_buf);
|
||||
}
|
||||
}
|
||||
@@ -1033,22 +1033,22 @@ ensure_slash (char **pstr)
|
||||
(*pstr)[len] = '\0';
|
||||
}
|
||||
|
||||
bool
|
||||
dump_dir (struct tar_stat_info *stat, int top_level, dev_t parent_device)
|
||||
static bool
|
||||
dump_dir (struct tar_stat_info *st, int top_level, dev_t parent_device)
|
||||
{
|
||||
char *directory;
|
||||
|
||||
directory = savedir (stat->orig_file_name);
|
||||
directory = savedir (st->orig_file_name);
|
||||
if (!directory)
|
||||
{
|
||||
savedir_diag (stat->orig_file_name);
|
||||
savedir_diag (st->orig_file_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
ensure_slash (&stat->orig_file_name);
|
||||
ensure_slash (&stat->file_name);
|
||||
ensure_slash (&st->orig_file_name);
|
||||
ensure_slash (&st->file_name);
|
||||
|
||||
dump_dir0 (directory, stat, top_level, parent_device);
|
||||
dump_dir0 (directory, st, top_level, parent_device);
|
||||
|
||||
free (directory);
|
||||
return true;
|
||||
@@ -1064,7 +1064,7 @@ create_archive (void)
|
||||
|
||||
open_archive (ACCESS_WRITE);
|
||||
xheader_write_global ();
|
||||
|
||||
|
||||
if (incremental_option)
|
||||
{
|
||||
size_t buffer_size = 1000;
|
||||
@@ -1131,8 +1131,9 @@ create_archive (void)
|
||||
static unsigned
|
||||
hash_link (void const *entry, unsigned n_buckets)
|
||||
{
|
||||
struct link const *link = entry;
|
||||
return (uintmax_t) (link->dev ^ link->ino) % n_buckets;
|
||||
struct link const *l = entry;
|
||||
uintmax_t num = l->dev ^ l->ino;
|
||||
return num % n_buckets;
|
||||
}
|
||||
|
||||
/* Compare two links for equality. */
|
||||
@@ -1164,41 +1165,41 @@ static Hash_table *link_table;
|
||||
/* Try to dump stat as a hard link to another file in the archive. If
|
||||
succeeded returns true */
|
||||
static bool
|
||||
dump_hard_link (struct tar_stat_info *stat)
|
||||
dump_hard_link (struct tar_stat_info *st)
|
||||
{
|
||||
if (link_table && stat->stat.st_nlink > 1)
|
||||
if (link_table && st->stat.st_nlink > 1)
|
||||
{
|
||||
struct link lp;
|
||||
struct link *dup;
|
||||
struct link *duplicate;
|
||||
off_t block_ordinal;
|
||||
union block *blk;
|
||||
|
||||
lp.ino = stat->stat.st_ino;
|
||||
lp.dev = stat->stat.st_dev;
|
||||
|
||||
if ((dup = hash_lookup (link_table, &lp)))
|
||||
lp.ino = st->stat.st_ino;
|
||||
lp.dev = st->stat.st_dev;
|
||||
|
||||
if ((duplicate = hash_lookup (link_table, &lp)))
|
||||
{
|
||||
/* We found a link. */
|
||||
char const *link_name = safer_name_suffix (dup->name, true);
|
||||
char const *link_name = safer_name_suffix (duplicate->name, true);
|
||||
|
||||
duplicate->nlink--;
|
||||
|
||||
dup->nlink--;
|
||||
|
||||
block_ordinal = current_block_ordinal ();
|
||||
assign_string (&stat->link_name, link_name);
|
||||
assign_string (&st->link_name, link_name);
|
||||
if (NAME_FIELD_SIZE < strlen (link_name))
|
||||
write_long_link (stat);
|
||||
|
||||
stat->stat.st_size = 0;
|
||||
blk = start_header (stat);
|
||||
write_long_link (st);
|
||||
|
||||
st->stat.st_size = 0;
|
||||
blk = start_header (st);
|
||||
if (!blk)
|
||||
return true;
|
||||
tar_copy_str (blk->header.linkname, link_name, NAME_FIELD_SIZE);
|
||||
|
||||
blk->header.typeflag = LNKTYPE;
|
||||
finish_header (stat, blk, block_ordinal);
|
||||
finish_header (st, blk, block_ordinal);
|
||||
|
||||
if (remove_files_option && unlink (stat->orig_file_name) != 0)
|
||||
unlink_error (stat->orig_file_name);
|
||||
if (remove_files_option && unlink (st->orig_file_name) != 0)
|
||||
unlink_error (st->orig_file_name);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1207,25 +1208,25 @@ dump_hard_link (struct tar_stat_info *stat)
|
||||
}
|
||||
|
||||
static void
|
||||
file_count_links (struct tar_stat_info *stat)
|
||||
file_count_links (struct tar_stat_info *st)
|
||||
{
|
||||
if (stat->stat.st_nlink > 1)
|
||||
if (st->stat.st_nlink > 1)
|
||||
{
|
||||
struct link *dup;
|
||||
struct link *duplicate;
|
||||
struct link *lp = xmalloc (offsetof (struct link, name)
|
||||
+ strlen (stat->orig_file_name) + 1);
|
||||
lp->ino = stat->stat.st_ino;
|
||||
lp->dev = stat->stat.st_dev;
|
||||
lp->nlink = stat->stat.st_nlink;
|
||||
strcpy (lp->name, stat->orig_file_name);
|
||||
+ strlen (st->orig_file_name) + 1);
|
||||
lp->ino = st->stat.st_ino;
|
||||
lp->dev = st->stat.st_dev;
|
||||
lp->nlink = st->stat.st_nlink;
|
||||
strcpy (lp->name, st->orig_file_name);
|
||||
|
||||
if (! ((link_table
|
||||
|| (link_table = hash_initialize (0, 0, hash_link,
|
||||
compare_links, 0)))
|
||||
&& (dup = hash_insert (link_table, lp))))
|
||||
&& (duplicate = hash_insert (link_table, lp))))
|
||||
xalloc_die ();
|
||||
|
||||
if (dup != lp)
|
||||
if (duplicate != lp)
|
||||
abort ();
|
||||
lp->nlink--;
|
||||
}
|
||||
@@ -1234,7 +1235,7 @@ file_count_links (struct tar_stat_info *stat)
|
||||
/* For each dumped file, check if all its links were dumped. Emit
|
||||
warnings if it is not so. */
|
||||
void
|
||||
check_links ()
|
||||
check_links (void)
|
||||
{
|
||||
struct link *lp;
|
||||
|
||||
@@ -1261,8 +1262,8 @@ check_links ()
|
||||
/* FIXME: One should make sure that for *every* path leading to setting
|
||||
exit_status to failure, a clear diagnostic has been issued. */
|
||||
|
||||
void
|
||||
dump_file0 (struct tar_stat_info *stat, char *p,
|
||||
static void
|
||||
dump_file0 (struct tar_stat_info *st, char *p,
|
||||
int top_level, dev_t parent_device)
|
||||
{
|
||||
union block *header;
|
||||
@@ -1270,26 +1271,26 @@ dump_file0 (struct tar_stat_info *stat, char *p,
|
||||
time_t original_ctime;
|
||||
struct utimbuf restore_times;
|
||||
off_t block_ordinal = -1;
|
||||
|
||||
|
||||
if (interactive_option && !confirm ("add", p))
|
||||
return;
|
||||
|
||||
assign_string (&stat->orig_file_name, p);
|
||||
assign_string (&stat->file_name, safer_name_suffix (p, false));
|
||||
assign_string (&st->orig_file_name, p);
|
||||
assign_string (&st->file_name, safer_name_suffix (p, false));
|
||||
|
||||
if (deref_stat (dereference_option, p, &stat->stat) != 0)
|
||||
if (deref_stat (dereference_option, p, &st->stat) != 0)
|
||||
{
|
||||
stat_diag (p);
|
||||
return;
|
||||
}
|
||||
stat->archive_file_size = stat->stat.st_size;
|
||||
sys_stat_nanoseconds(stat);
|
||||
original_ctime = stat->stat.st_ctime;
|
||||
restore_times.actime = stat->stat.st_atime;
|
||||
restore_times.modtime = stat->stat.st_mtime;
|
||||
st->archive_file_size = st->stat.st_size;
|
||||
sys_stat_nanoseconds (st);
|
||||
original_ctime = st->stat.st_ctime;
|
||||
restore_times.actime = st->stat.st_atime;
|
||||
restore_times.modtime = st->stat.st_mtime;
|
||||
|
||||
#ifdef S_ISHIDDEN
|
||||
if (S_ISHIDDEN (stat->stat.st_mode))
|
||||
if (S_ISHIDDEN (st->stat.st_mode))
|
||||
{
|
||||
char *new = (char *) alloca (strlen (p) + 2);
|
||||
if (new)
|
||||
@@ -1304,9 +1305,9 @@ dump_file0 (struct tar_stat_info *stat, char *p,
|
||||
/* See if we want only new files, and check if this one is too old to
|
||||
put in the archive. */
|
||||
|
||||
if (!S_ISDIR (stat->stat.st_mode)
|
||||
&& stat->stat.st_mtime < newer_mtime_option
|
||||
&& (!after_date_option || stat->stat.st_ctime < newer_ctime_option))
|
||||
if (!S_ISDIR (st->stat.st_mode)
|
||||
&& OLDER_STAT_TIME (st->stat, m)
|
||||
&& (!after_date_option || OLDER_STAT_TIME (st->stat, c)))
|
||||
{
|
||||
if (0 < top_level) /* equivalent to !incremental_option */
|
||||
WARN ((0, 0, _("%s: file is unchanged; not dumped"),
|
||||
@@ -1316,16 +1317,16 @@ dump_file0 (struct tar_stat_info *stat, char *p,
|
||||
}
|
||||
|
||||
/* See if we are trying to dump the archive. */
|
||||
if (sys_file_is_archive (stat))
|
||||
if (sys_file_is_archive (st))
|
||||
{
|
||||
WARN ((0, 0, _("%s: file is the archive; not dumped"),
|
||||
quotearg_colon (p)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (S_ISDIR (stat->stat.st_mode))
|
||||
if (S_ISDIR (st->stat.st_mode))
|
||||
{
|
||||
dump_dir (stat, top_level, parent_device);
|
||||
dump_dir (st, top_level, parent_device);
|
||||
if (atime_preserve_option)
|
||||
utime (p, &restore_times);
|
||||
return;
|
||||
@@ -1335,49 +1336,49 @@ dump_file0 (struct tar_stat_info *stat, char *p,
|
||||
else
|
||||
{
|
||||
/* Check for multiple links. */
|
||||
if (dump_hard_link (stat))
|
||||
if (dump_hard_link (st))
|
||||
return;
|
||||
|
||||
|
||||
/* This is not a link to a previously dumped file, so dump it. */
|
||||
|
||||
if (S_ISREG (stat->stat.st_mode)
|
||||
|| S_ISCTG (stat->stat.st_mode))
|
||||
if (S_ISREG (st->stat.st_mode)
|
||||
|| S_ISCTG (st->stat.st_mode))
|
||||
{
|
||||
int fd;
|
||||
enum dump_status status;
|
||||
|
||||
if (file_dumpable_p (stat))
|
||||
if (file_dumpable_p (st))
|
||||
{
|
||||
fd = open (stat->orig_file_name,
|
||||
fd = open (st->orig_file_name,
|
||||
O_RDONLY | O_BINARY);
|
||||
if (fd < 0)
|
||||
{
|
||||
if (!top_level && errno == ENOENT)
|
||||
WARN ((0, 0, _("%s: File removed before we read it"),
|
||||
quotearg_colon (stat->orig_file_name)));
|
||||
quotearg_colon (st->orig_file_name)));
|
||||
else
|
||||
open_diag (stat->orig_file_name);
|
||||
open_diag (st->orig_file_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
fd = -1;
|
||||
|
||||
if (sparse_option && sparse_file_p (stat))
|
||||
|
||||
if (sparse_option && sparse_file_p (st))
|
||||
{
|
||||
status = sparse_dump_file (fd, stat);
|
||||
status = sparse_dump_file (fd, st);
|
||||
if (status == dump_status_not_implemented)
|
||||
status = dump_regular_file (fd, stat);
|
||||
status = dump_regular_file (fd, st);
|
||||
}
|
||||
else
|
||||
status = dump_regular_file (fd, stat);
|
||||
status = dump_regular_file (fd, st);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case dump_status_ok:
|
||||
if (multi_volume_option)
|
||||
assign_string (&save_name, 0);
|
||||
dump_regular_finish (fd, stat, original_ctime);
|
||||
dump_regular_finish (fd, st, original_ctime);
|
||||
break;
|
||||
|
||||
case dump_status_short:
|
||||
@@ -1385,7 +1386,7 @@ dump_file0 (struct tar_stat_info *stat, char *p,
|
||||
assign_string (&save_name, 0);
|
||||
close (fd);
|
||||
break;
|
||||
|
||||
|
||||
case dump_status_fail:
|
||||
close (fd);
|
||||
return;
|
||||
@@ -1395,17 +1396,17 @@ dump_file0 (struct tar_stat_info *stat, char *p,
|
||||
}
|
||||
|
||||
if (atime_preserve_option)
|
||||
utime (stat->orig_file_name, &restore_times);
|
||||
file_count_links (stat);
|
||||
utime (st->orig_file_name, &restore_times);
|
||||
file_count_links (st);
|
||||
return;
|
||||
}
|
||||
#ifdef HAVE_READLINK
|
||||
else if (S_ISLNK (stat->stat.st_mode))
|
||||
else if (S_ISLNK (st->stat.st_mode))
|
||||
{
|
||||
char *buffer;
|
||||
int size;
|
||||
size_t linklen = stat->stat.st_size;
|
||||
if (linklen != stat->stat.st_size || linklen + 1 == 0)
|
||||
size_t linklen = st->stat.st_size;
|
||||
if (linklen != st->stat.st_size || linklen + 1 == 0)
|
||||
xalloc_die ();
|
||||
buffer = (char *) alloca (linklen + 1);
|
||||
size = readlink (p, buffer, linklen + 1);
|
||||
@@ -1415,18 +1416,18 @@ dump_file0 (struct tar_stat_info *stat, char *p,
|
||||
return;
|
||||
}
|
||||
buffer[size] = '\0';
|
||||
assign_string (&stat->link_name, buffer);
|
||||
assign_string (&st->link_name, buffer);
|
||||
if (size > NAME_FIELD_SIZE)
|
||||
write_long_link (stat);
|
||||
write_long_link (st);
|
||||
|
||||
block_ordinal = current_block_ordinal ();
|
||||
stat->stat.st_size = 0; /* force 0 size on symlink */
|
||||
header = start_header (stat);
|
||||
st->stat.st_size = 0; /* force 0 size on symlink */
|
||||
header = start_header (st);
|
||||
if (!header)
|
||||
return;
|
||||
tar_copy_str (header->header.linkname, buffer, NAME_FIELD_SIZE);
|
||||
header->header.typeflag = SYMTYPE;
|
||||
finish_header (stat, header, block_ordinal);
|
||||
finish_header (st, header, block_ordinal);
|
||||
/* nothing more to do to it */
|
||||
|
||||
if (remove_files_option)
|
||||
@@ -1434,22 +1435,22 @@ dump_file0 (struct tar_stat_info *stat, char *p,
|
||||
if (unlink (p) == -1)
|
||||
unlink_error (p);
|
||||
}
|
||||
file_count_links (stat);
|
||||
file_count_links (st);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
else if (S_ISCHR (stat->stat.st_mode))
|
||||
else if (S_ISCHR (st->stat.st_mode))
|
||||
type = CHRTYPE;
|
||||
else if (S_ISBLK (stat->stat.st_mode))
|
||||
else if (S_ISBLK (st->stat.st_mode))
|
||||
type = BLKTYPE;
|
||||
else if (S_ISFIFO (stat->stat.st_mode))
|
||||
else if (S_ISFIFO (st->stat.st_mode))
|
||||
type = FIFOTYPE;
|
||||
else if (S_ISSOCK (stat->stat.st_mode))
|
||||
else if (S_ISSOCK (st->stat.st_mode))
|
||||
{
|
||||
WARN ((0, 0, _("%s: socket ignored"), quotearg_colon (p)));
|
||||
return;
|
||||
}
|
||||
else if (S_ISDOOR (stat->stat.st_mode))
|
||||
else if (S_ISDOOR (st->stat.st_mode))
|
||||
{
|
||||
WARN ((0, 0, _("%s: door ignored"), quotearg_colon (p)));
|
||||
return;
|
||||
@@ -1468,21 +1469,21 @@ dump_file0 (struct tar_stat_info *stat, char *p,
|
||||
}
|
||||
|
||||
block_ordinal = current_block_ordinal ();
|
||||
stat->stat.st_size = 0; /* force 0 size */
|
||||
header = start_header (stat);
|
||||
st->stat.st_size = 0; /* force 0 size */
|
||||
header = start_header (st);
|
||||
if (!header)
|
||||
return;
|
||||
header->header.typeflag = type;
|
||||
|
||||
if (type != FIFOTYPE)
|
||||
{
|
||||
MAJOR_TO_CHARS (major (stat->stat.st_rdev),
|
||||
MAJOR_TO_CHARS (major (st->stat.st_rdev),
|
||||
header->header.devmajor);
|
||||
MINOR_TO_CHARS (minor (stat->stat.st_rdev),
|
||||
MINOR_TO_CHARS (minor (st->stat.st_rdev),
|
||||
header->header.devminor);
|
||||
}
|
||||
|
||||
finish_header (stat, header, block_ordinal);
|
||||
finish_header (st, header, block_ordinal);
|
||||
if (remove_files_option)
|
||||
{
|
||||
if (unlink (p) == -1)
|
||||
@@ -1493,8 +1494,8 @@ dump_file0 (struct tar_stat_info *stat, char *p,
|
||||
void
|
||||
dump_file (char *p, int top_level, dev_t parent_device)
|
||||
{
|
||||
struct tar_stat_info stat;
|
||||
tar_stat_init (&stat);
|
||||
dump_file0 (&stat, p, top_level, parent_device);
|
||||
tar_stat_destroy (&stat);
|
||||
struct tar_stat_info st;
|
||||
tar_stat_init (&st);
|
||||
dump_file0 (&st, p, top_level, parent_device);
|
||||
tar_stat_destroy (&st);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Extract files from a tar archive.
|
||||
|
||||
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000,
|
||||
2001, 2003 Free Software Foundation, Inc.
|
||||
2001, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
Written by John Gilmore, on 1985-11-19.
|
||||
|
||||
@@ -315,11 +315,11 @@ delay_set_stat (char const *file_name, struct stat const *stat_info,
|
||||
}
|
||||
|
||||
/* Update the delayed_set_stat info for an intermediate directory
|
||||
created on the path to DIR_NAME. The intermediate directory turned
|
||||
created on the path to DIR. The intermediate directory turned
|
||||
out to be the same as this directory, e.g. due to ".." or symbolic
|
||||
links. *DIR_STAT_INFO is the status of the directory. */
|
||||
static void
|
||||
repair_delayed_set_stat (char const *dir_name,
|
||||
repair_delayed_set_stat (char const *dir,
|
||||
struct stat const *dir_stat_info)
|
||||
{
|
||||
struct delayed_set_stat *data;
|
||||
@@ -344,7 +344,7 @@ repair_delayed_set_stat (char const *dir_name,
|
||||
}
|
||||
|
||||
ERROR ((0, 0, _("%s: Unexpected inconsistency when making directory"),
|
||||
quotearg_colon (dir_name)));
|
||||
quotearg_colon (dir)));
|
||||
}
|
||||
|
||||
/* After a file/link/symlink/directory creation has failed, see if
|
||||
@@ -361,7 +361,7 @@ make_directories (char *file_name)
|
||||
int invert_permissions;
|
||||
int status;
|
||||
|
||||
|
||||
|
||||
for (cursor = cursor0; *cursor; cursor++)
|
||||
{
|
||||
if (! ISSLASH (*cursor))
|
||||
@@ -423,25 +423,25 @@ static bool
|
||||
file_newer_p (const char *file_name, struct tar_stat_info *tar_stat)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
|
||||
if (stat (file_name, &st))
|
||||
{
|
||||
stat_warn (file_name);
|
||||
return true; /* Be on the safe side */
|
||||
}
|
||||
if (!S_ISDIR (st.st_mode)
|
||||
&& st.st_mtime >= current_stat_info.stat.st_mtime)
|
||||
&& st.st_mtime >= tar_stat->stat.st_mtime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepare to extract a file.
|
||||
Return zero if extraction should not proceed. */
|
||||
|
||||
static int
|
||||
prepare_to_extract (char const *file_name, bool directory)
|
||||
prepare_to_extract (char const *file_name)
|
||||
{
|
||||
if (to_stdout_option)
|
||||
return 0;
|
||||
@@ -460,7 +460,7 @@ prepare_to_extract (char const *file_name, bool directory)
|
||||
case KEEP_NEWER_FILES:
|
||||
if (file_newer_p (file_name, ¤t_stat_info))
|
||||
{
|
||||
WARN ((0, 0, _("Current `%s' is newer"), file_name));
|
||||
WARN ((0, 0, _("Current `%s' is newer"), file_name));
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
@@ -480,7 +480,7 @@ static int
|
||||
maybe_recoverable (char *file_name, int *interdir_made)
|
||||
{
|
||||
int e = errno;
|
||||
|
||||
|
||||
if (*interdir_made)
|
||||
return 0;
|
||||
|
||||
@@ -501,7 +501,7 @@ maybe_recoverable (char *file_name, int *interdir_made)
|
||||
return 0;
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
|
||||
|
||||
case DEFAULT_OLD_FILES:
|
||||
case NO_OVERWRITE_DIR_OLD_FILES:
|
||||
case OVERWRITE_OLD_FILES:
|
||||
@@ -628,7 +628,7 @@ extract_archive (void)
|
||||
}
|
||||
file_name += prefix_len;
|
||||
}
|
||||
|
||||
|
||||
apply_nonancestor_delayed_set_stat (file_name, 0);
|
||||
|
||||
/* Take a safety backup of a previously existing file. */
|
||||
@@ -648,7 +648,7 @@ extract_archive (void)
|
||||
/* KLUDGE */
|
||||
typeflag = sparse_member_p (¤t_stat_info) ?
|
||||
GNUTYPE_SPARSE : current_header->header.typeflag;
|
||||
|
||||
|
||||
switch (typeflag)
|
||||
{
|
||||
case GNUTYPE_SPARSE:
|
||||
@@ -679,7 +679,7 @@ extract_archive (void)
|
||||
goto extract_file;
|
||||
}
|
||||
|
||||
if (! prepare_to_extract (file_name, 0))
|
||||
if (! prepare_to_extract (file_name))
|
||||
{
|
||||
skip_member ();
|
||||
if (backup_option)
|
||||
@@ -794,7 +794,7 @@ extract_archive (void)
|
||||
|
||||
case SYMTYPE:
|
||||
#ifdef HAVE_SYMLINK
|
||||
if (! prepare_to_extract (file_name, 0))
|
||||
if (! prepare_to_extract (file_name))
|
||||
break;
|
||||
|
||||
if (absolute_names_option
|
||||
@@ -878,7 +878,7 @@ extract_archive (void)
|
||||
status = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (status != 0 && backup_option)
|
||||
undo_last_backup ();
|
||||
break;
|
||||
@@ -899,7 +899,7 @@ extract_archive (void)
|
||||
#endif
|
||||
|
||||
case LNKTYPE:
|
||||
if (! prepare_to_extract (file_name, 0))
|
||||
if (! prepare_to_extract (file_name))
|
||||
break;
|
||||
|
||||
again_link:
|
||||
@@ -922,7 +922,7 @@ extract_archive (void)
|
||||
&& ds->ino == st1.st_ino
|
||||
&& ds->mtime == st1.st_mtime)
|
||||
{
|
||||
struct string_list *p =
|
||||
struct string_list *p =
|
||||
xmalloc (offsetof (struct string_list, string)
|
||||
+ strlen (file_name) + 1);
|
||||
strcpy (p->string, file_name);
|
||||
@@ -963,7 +963,7 @@ extract_archive (void)
|
||||
|
||||
#if S_IFCHR || S_IFBLK
|
||||
make_node:
|
||||
if (! prepare_to_extract (file_name, 0))
|
||||
if (! prepare_to_extract (file_name))
|
||||
break;
|
||||
|
||||
status = mknod (file_name, current_stat_info.stat.st_mode,
|
||||
@@ -984,7 +984,7 @@ extract_archive (void)
|
||||
|
||||
#if HAVE_MKFIFO || defined mkfifo
|
||||
case FIFOTYPE:
|
||||
if (! prepare_to_extract (file_name, 0))
|
||||
if (! prepare_to_extract (file_name))
|
||||
break;
|
||||
|
||||
while (status = mkfifo (file_name, current_stat_info.stat.st_mode),
|
||||
@@ -1021,7 +1021,7 @@ extract_archive (void)
|
||||
| (we_are_root ? 0 : MODE_WXUSR))
|
||||
& MODE_RWX);
|
||||
|
||||
status = prepare_to_extract (file_name, 1);
|
||||
status = prepare_to_extract (file_name);
|
||||
if (status == 0)
|
||||
break;
|
||||
if (status < 0)
|
||||
@@ -1053,7 +1053,7 @@ extract_archive (void)
|
||||
}
|
||||
errno = EEXIST;
|
||||
}
|
||||
|
||||
|
||||
if (maybe_recoverable (file_name, &interdir_made))
|
||||
goto again_dir;
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ scan_path (struct obstack *stk, char *path, dev_t device)
|
||||
|
||||
directory = find_directory (path);
|
||||
children = directory ? directory->children : CHANGED_CHILDREN;
|
||||
|
||||
|
||||
if (dirp && children != NO_CHILDREN)
|
||||
for (entry = dirp;
|
||||
(entrylen = strlen (entry)) != 0;
|
||||
@@ -159,23 +159,23 @@ scan_path (struct obstack *stk, char *path, dev_t device)
|
||||
name_buffer = xrealloc (name_buffer, name_buffer_size + 2);
|
||||
}
|
||||
strcpy (name_buffer + name_length, entry);
|
||||
|
||||
|
||||
if (excluded_name (name_buffer))
|
||||
obstack_1grow (stk, 'N');
|
||||
else
|
||||
{
|
||||
struct stat stat_data;
|
||||
|
||||
|
||||
if (deref_stat (dereference_option, name_buffer, &stat_data))
|
||||
{
|
||||
stat_diag (name_buffer);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (S_ISDIR (stat_data.st_mode))
|
||||
{
|
||||
bool nfs = NFS_FILE_STAT (stat_data);
|
||||
|
||||
|
||||
if ((directory = find_directory (name_buffer)) != NULL)
|
||||
{
|
||||
/* With NFS, the same file can have two different devices
|
||||
@@ -184,7 +184,7 @@ scan_path (struct obstack *stk, char *path, dev_t device)
|
||||
To avoid spurious incremental redumping of
|
||||
directories, consider all NFS devices as equal,
|
||||
relying on the i-node to establish differences. */
|
||||
|
||||
|
||||
if (! (((directory->nfs & nfs)
|
||||
|| directory->device_number == stat_data.st_dev)
|
||||
&& directory->inode_number == stat_data.st_ino))
|
||||
@@ -209,13 +209,13 @@ scan_path (struct obstack *stk, char *path, dev_t device)
|
||||
stat_data.st_ino, nfs, 1);
|
||||
directory->children =
|
||||
((listed_incremental_option
|
||||
|| newer_mtime_option <= stat_data.st_mtime
|
||||
|| (after_date_option &&
|
||||
newer_ctime_option <= stat_data.st_ctime))
|
||||
|| OLDER_STAT_TIME (stat_data, m)
|
||||
|| (after_date_option
|
||||
&& OLDER_STAT_TIME (stat_data, c)))
|
||||
? ALL_CHILDREN
|
||||
: CHANGED_CHILDREN);
|
||||
}
|
||||
|
||||
|
||||
if (one_file_system_option && device != stat_data.st_dev)
|
||||
directory->children = NO_CHILDREN;
|
||||
else if (children == ALL_CHILDREN)
|
||||
@@ -239,19 +239,18 @@ scan_path (struct obstack *stk, char *path, dev_t device)
|
||||
|
||||
else
|
||||
if (children == CHANGED_CHILDREN
|
||||
&& stat_data.st_mtime < newer_mtime_option
|
||||
&& (!after_date_option
|
||||
|| stat_data.st_ctime < newer_ctime_option))
|
||||
&& OLDER_STAT_TIME (stat_data, m)
|
||||
&& (!after_date_option || OLDER_STAT_TIME (stat_data, c)))
|
||||
obstack_1grow (stk, 'N');
|
||||
else
|
||||
obstack_1grow (stk, 'Y');
|
||||
}
|
||||
|
||||
|
||||
obstack_grow (stk, entry, entrylen + 1);
|
||||
}
|
||||
|
||||
obstack_grow (stk, "\000\000", 2);
|
||||
|
||||
|
||||
free (name_buffer);
|
||||
if (dirp)
|
||||
free (dirp);
|
||||
@@ -267,16 +266,16 @@ sort_obstack (struct obstack *stk)
|
||||
char *buffer;
|
||||
char **array;
|
||||
char **array_cursor;
|
||||
|
||||
|
||||
counter = 0;
|
||||
for (cursor = pointer; *cursor; cursor += strlen (cursor) + 1)
|
||||
counter++;
|
||||
|
||||
|
||||
if (!counter)
|
||||
return NULL;
|
||||
|
||||
array = obstack_alloc (stk, sizeof (char *) * (counter + 1));
|
||||
|
||||
|
||||
array_cursor = array;
|
||||
for (cursor = pointer; *cursor; cursor += strlen (cursor) + 1)
|
||||
*array_cursor++ = cursor;
|
||||
@@ -290,7 +289,7 @@ sort_obstack (struct obstack *stk)
|
||||
for (array_cursor = array; *array_cursor; array_cursor++)
|
||||
{
|
||||
char *string = *array_cursor;
|
||||
|
||||
|
||||
while ((*cursor++ = *string++))
|
||||
continue;
|
||||
}
|
||||
@@ -357,7 +356,10 @@ read_directory_file (void)
|
||||
ERROR ((0, 0, "%s:1: %s", quotearg_colon (listed_incremental_option),
|
||||
_("Time stamp out of range")));
|
||||
else
|
||||
newer_mtime_option = t;
|
||||
{
|
||||
newer_mtime_option.tv_sec = t;
|
||||
newer_mtime_option.tv_nsec = 0;
|
||||
}
|
||||
|
||||
while (0 < (n = getline (&buf, &bufsize, fp)))
|
||||
{
|
||||
|
||||
33
src/list.c
33
src/list.c
@@ -1,7 +1,7 @@
|
||||
/* List a tar archive, with support routines for reading a tar archive.
|
||||
|
||||
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000,
|
||||
2001, 2003 Free Software Foundation, Inc.
|
||||
2001, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
Written by John Gilmore, on 1985-08-26.
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Define to non-zero for forcing old ctime format instead of ISO format. */
|
||||
#undef USE_OLD_CTIME
|
||||
#undef USE_OLD_CTIME
|
||||
|
||||
#include "system.h"
|
||||
#include <quotearg.h>
|
||||
@@ -78,7 +78,7 @@ read_and (void (*do_something) (void))
|
||||
prev_status = status;
|
||||
tar_stat_destroy (¤t_stat_info);
|
||||
xheader_destroy (&extended_header);
|
||||
|
||||
|
||||
status = read_header (false);
|
||||
switch (status)
|
||||
{
|
||||
@@ -92,12 +92,17 @@ read_and (void (*do_something) (void))
|
||||
Ensure incoming names are null terminated. */
|
||||
|
||||
if (! name_match (current_stat_info.file_name)
|
||||
|| (newer_mtime_option != TYPE_MINIMUM (time_t)
|
||||
|| (NEWER_OPTION_INITIALIZED (newer_mtime_option)
|
||||
/* FIXME: We get mtime now, and again later; this causes
|
||||
duplicate diagnostics if header.mtime is bogus. */
|
||||
&& ((current_stat_info.stat.st_mtime
|
||||
= TIME_FROM_HEADER (current_header->header.mtime))
|
||||
< newer_mtime_option))
|
||||
= TIME_FROM_HEADER (current_header->header.mtime)),
|
||||
#ifdef ST_MTIM_NSEC
|
||||
/* FIXME: Grab fractional time stamps from
|
||||
extended header. */
|
||||
current_stat_info.stat.st_mtim.ST_MTIM_NSEC = 0,
|
||||
#endif
|
||||
OLDER_STAT_TIME (current_stat_info.stat, m)))
|
||||
|| excluded_name (current_stat_info.file_name))
|
||||
{
|
||||
switch (current_header->header.typeflag)
|
||||
@@ -356,7 +361,7 @@ read_header (bool raw_extended_headers)
|
||||
xalloc_die ();
|
||||
|
||||
header_copy = xmalloc (size + 1);
|
||||
|
||||
|
||||
if (header->header.typeflag == GNUTYPE_LONGNAME)
|
||||
{
|
||||
if (next_long_name)
|
||||
@@ -371,7 +376,7 @@ read_header (bool raw_extended_headers)
|
||||
next_long_link = header_copy;
|
||||
next_long_link_blocks = size / BLOCKSIZE;
|
||||
}
|
||||
|
||||
|
||||
set_next_block_after (header);
|
||||
*header_copy = *header;
|
||||
bp = header_copy->buffer + BLOCKSIZE;
|
||||
@@ -387,7 +392,7 @@ read_header (bool raw_extended_headers)
|
||||
written = available_space_after (data_block);
|
||||
if (written > size)
|
||||
written = size;
|
||||
|
||||
|
||||
memcpy (bp, data_block->buffer, written);
|
||||
bp += written;
|
||||
set_next_block_after ((union block *)
|
||||
@@ -403,7 +408,7 @@ read_header (bool raw_extended_headers)
|
||||
xheader_read (header, OFF_FROM_HEADER (header->header.size));
|
||||
xheader_decode_global ();
|
||||
}
|
||||
|
||||
|
||||
/* Loop! */
|
||||
|
||||
}
|
||||
@@ -520,7 +525,7 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
|
||||
assign_string (&stat_info->gname, header->header.gname);
|
||||
stat_info->devmajor = MAJOR_FROM_HEADER (header->header.devmajor);
|
||||
stat_info->devminor = MINOR_FROM_HEADER (header->header.devminor);
|
||||
|
||||
|
||||
stat_info->stat.st_atime = start_time;
|
||||
stat_info->stat.st_ctime = start_time;
|
||||
|
||||
@@ -559,7 +564,7 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
|
||||
|| !gname_to_gid (header->header.gname, &stat_info->stat.st_gid))
|
||||
stat_info->stat.st_gid = GID_FROM_HEADER (header->header.gid);
|
||||
}
|
||||
|
||||
|
||||
switch (header->header.typeflag)
|
||||
{
|
||||
case BLKTYPE:
|
||||
@@ -961,7 +966,7 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
|
||||
char modes[11];
|
||||
char const *time_stamp;
|
||||
char *temp_name = st->orig_file_name ? st->orig_file_name : st->file_name;
|
||||
|
||||
|
||||
/* These hold formatted ints. */
|
||||
char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND];
|
||||
char *user, *group;
|
||||
@@ -1108,7 +1113,7 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
|
||||
strcat (size,
|
||||
STRINGIFY_BIGINT (minor (st->stat.st_rdev), uintbuf));
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
/* st->stat.st_size keeps stored file size */
|
||||
strcpy (size, STRINGIFY_BIGINT (st->stat.st_size, uintbuf));
|
||||
|
||||
28
src/misc.c
28
src/misc.c
@@ -1,7 +1,7 @@
|
||||
/* Miscellaneous functions, not really specific to GNU tar.
|
||||
|
||||
Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2001,
|
||||
2003 Free Software Foundation, Inc.
|
||||
2003, 2004 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
|
||||
@@ -331,16 +331,17 @@ remove_any_file (const char *path, enum remove_option option)
|
||||
/* Check if PATH already exists and make a backup of it right now.
|
||||
Return success (nonzero) only if the backup is either unneeded, or
|
||||
successful. For now, directories are considered to never need
|
||||
backup. If ARCHIVE is nonzero, this is the archive and so, we do
|
||||
not have to backup block or character devices, nor remote entities. */
|
||||
backup. If THIS_IS_THE_ARCHIVE is nonzero, this is the archive and
|
||||
so, we do not have to backup block or character devices, nor remote
|
||||
entities. */
|
||||
bool
|
||||
maybe_backup_file (const char *path, int archive)
|
||||
maybe_backup_file (const char *path, int this_is_the_archive)
|
||||
{
|
||||
struct stat file_stat;
|
||||
|
||||
/* Check if we really need to backup the file. */
|
||||
|
||||
if (archive && _remdev (path))
|
||||
if (this_is_the_archive && _remdev (path))
|
||||
return true;
|
||||
|
||||
if (stat (path, &file_stat))
|
||||
@@ -355,7 +356,8 @@ maybe_backup_file (const char *path, int archive)
|
||||
if (S_ISDIR (file_stat.st_mode))
|
||||
return true;
|
||||
|
||||
if (archive && (S_ISBLK (file_stat.st_mode) || S_ISCHR (file_stat.st_mode)))
|
||||
if (this_is_the_archive
|
||||
&& (S_ISBLK (file_stat.st_mode) || S_ISCHR (file_stat.st_mode)))
|
||||
return true;
|
||||
|
||||
assign_string (&before_backup_name, path);
|
||||
@@ -586,12 +588,6 @@ close_error (char const *name)
|
||||
call_arg_error ("close", name);
|
||||
}
|
||||
|
||||
void
|
||||
close_fatal (char const *name)
|
||||
{
|
||||
call_arg_fatal ("close", name);
|
||||
}
|
||||
|
||||
void
|
||||
close_warn (char const *name)
|
||||
{
|
||||
@@ -875,16 +871,16 @@ write_error (char const *name)
|
||||
}
|
||||
|
||||
void
|
||||
write_error_details (char const *name, ssize_t status, size_t size)
|
||||
write_error_details (char const *name, size_t status, size_t size)
|
||||
{
|
||||
if (status < 0)
|
||||
if (status == 0)
|
||||
write_error (name);
|
||||
else
|
||||
ERROR ((0, 0,
|
||||
ngettext ("%s: Wrote only %lu of %lu byte",
|
||||
"%s: Wrote only %lu of %lu bytes",
|
||||
record_size),
|
||||
name, (unsigned long) status, (unsigned long) record_size));
|
||||
size),
|
||||
name, (unsigned long int) status, (unsigned long int) size));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
32
src/names.c
32
src/names.c
@@ -1,7 +1,7 @@
|
||||
/* Various processing of names.
|
||||
|
||||
Copyright (C) 1988, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2003 Free Software Foundation, Inc.
|
||||
2003, 2004 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
|
||||
@@ -118,7 +118,7 @@ gid_to_gname (gid_t gid, char **gname)
|
||||
|
||||
/* Given UNAME, set the corresponding UID and return 1, or else, return 0. */
|
||||
int
|
||||
uname_to_uid (char *uname, uid_t *uidp)
|
||||
uname_to_uid (char const *uname, uid_t *uidp)
|
||||
{
|
||||
struct passwd *passwd;
|
||||
|
||||
@@ -148,7 +148,7 @@ uname_to_uid (char *uname, uid_t *uidp)
|
||||
|
||||
/* Given GNAME, set the corresponding GID and return 1, or else, return 0. */
|
||||
int
|
||||
gname_to_gid (char *gname, gid_t *gidp)
|
||||
gname_to_gid (char const *gname, gid_t *gidp)
|
||||
{
|
||||
struct group *group;
|
||||
|
||||
@@ -227,7 +227,7 @@ is_pattern (const char *string)
|
||||
/* Set up to gather file names for tar. They can either come from a
|
||||
file or were saved from decoding arguments. */
|
||||
void
|
||||
name_init (int argc, char *const *argv)
|
||||
name_init (void)
|
||||
{
|
||||
name_buffer = xmalloc (NAME_FIELD_SIZE + 2);
|
||||
name_buffer_length = NAME_FIELD_SIZE;
|
||||
@@ -639,7 +639,7 @@ names_notfound (void)
|
||||
ERROR ((0, 0, _("%s: Required occurrence not found in archive"),
|
||||
quotearg_colon (cursor->name)));
|
||||
}
|
||||
|
||||
|
||||
/* Don't bother freeing the name list; we're about to exit. */
|
||||
namelist = 0;
|
||||
nametail = &namelist;
|
||||
@@ -759,18 +759,18 @@ add_hierarchy_to_namelist (struct name *name, dev_t device)
|
||||
size_t allocated_length = (name_length >= NAME_FIELD_SIZE
|
||||
? name_length + NAME_FIELD_SIZE
|
||||
: NAME_FIELD_SIZE);
|
||||
char *name_buffer = xmalloc (allocated_length + 1);
|
||||
char *namebuf = xmalloc (allocated_length + 1);
|
||||
/* FIXME: + 2 above? */
|
||||
char *string;
|
||||
size_t string_length;
|
||||
int change_dir = name->change_dir;
|
||||
|
||||
name->dir_contents = buffer;
|
||||
strcpy (name_buffer, path);
|
||||
if (! ISSLASH (name_buffer[name_length - 1]))
|
||||
strcpy (namebuf, path);
|
||||
if (! ISSLASH (namebuf[name_length - 1]))
|
||||
{
|
||||
name_buffer[name_length++] = '/';
|
||||
name_buffer[name_length] = '\0';
|
||||
namebuf[name_length++] = '/';
|
||||
namebuf[name_length] = '\0';
|
||||
}
|
||||
|
||||
for (string = buffer; *string; string += string_length + 1)
|
||||
@@ -788,15 +788,15 @@ add_hierarchy_to_namelist (struct name *name, dev_t device)
|
||||
}
|
||||
while (allocated_length <= name_length + string_length);
|
||||
|
||||
name_buffer = xrealloc (name_buffer, allocated_length + 1);
|
||||
namebuf = xrealloc (namebuf, allocated_length + 1);
|
||||
}
|
||||
strcpy (name_buffer + name_length, string + 1);
|
||||
add_hierarchy_to_namelist (addname (name_buffer, change_dir),
|
||||
strcpy (namebuf + name_length, string + 1);
|
||||
add_hierarchy_to_namelist (addname (namebuf, change_dir),
|
||||
device);
|
||||
}
|
||||
}
|
||||
|
||||
free (name_buffer);
|
||||
free (namebuf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1023,7 +1023,7 @@ safer_name_suffix (char const *file_name, bool link_target)
|
||||
{
|
||||
if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2]))
|
||||
prefix_len = p + 2 - file_name;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
char c = *p++;
|
||||
@@ -1067,7 +1067,7 @@ safer_name_suffix (char const *file_name, bool link_target)
|
||||
};
|
||||
WARN ((0, 0, _(diagnostic[link_target])));
|
||||
}
|
||||
|
||||
|
||||
p = ".";
|
||||
}
|
||||
|
||||
|
||||
38
src/rmt.c
38
src/rmt.c
@@ -1,7 +1,7 @@
|
||||
/* Remote connection server.
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003 Free
|
||||
Software Foundation, Inc.
|
||||
Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003, 2004
|
||||
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
|
||||
@@ -117,12 +117,12 @@ get_string (char *string)
|
||||
{
|
||||
int counter;
|
||||
|
||||
for (counter = 0; counter < STRING_SIZE; counter++)
|
||||
for (counter = 0; ; counter++)
|
||||
{
|
||||
if (safe_read (STDIN_FILENO, string + counter, 1) != 1)
|
||||
exit (EXIT_SUCCESS);
|
||||
|
||||
if (string[counter] == '\n')
|
||||
if (string[counter] == '\n' || counter == STRING_SIZE - 1)
|
||||
break;
|
||||
}
|
||||
string[counter] = '\0';
|
||||
@@ -179,11 +179,11 @@ decode_oflag (char const *oflag_string)
|
||||
char *oflag_num_end;
|
||||
int numeric_oflag = strtol (oflag_string, &oflag_num_end, 10);
|
||||
int symbolic_oflag = 0;
|
||||
|
||||
|
||||
oflag_string = oflag_num_end;
|
||||
while (ISSPACE ((unsigned char) *oflag_string))
|
||||
oflag_string++;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
struct name_value_pair { char const *name; int value; };
|
||||
@@ -247,6 +247,8 @@ static struct option const long_opts[] =
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static void usage (int) __attribute__ ((noreturn));
|
||||
|
||||
static void
|
||||
usage (int status)
|
||||
{
|
||||
@@ -272,7 +274,7 @@ int
|
||||
main (int argc, char *const *argv)
|
||||
{
|
||||
char command;
|
||||
ssize_t status;
|
||||
size_t status;
|
||||
|
||||
/* FIXME: Localization is meaningless, unless --help and --version are
|
||||
locally used. Localization would be best accomplished by the calling
|
||||
@@ -287,14 +289,14 @@ main (int argc, char *const *argv)
|
||||
{
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
|
||||
|
||||
case 'h':
|
||||
usage (EXIT_SUCCESS);
|
||||
|
||||
|
||||
case 'v':
|
||||
{
|
||||
printf ("rmt (%s) %s\n%s\n", PACKAGE_NAME, PACKAGE_VERSION,
|
||||
"Copyright (C) 2003 Free Software Foundation, Inc.");
|
||||
"Copyright (C) 2004 Free Software Foundation, Inc.");
|
||||
puts (_("\
|
||||
This program comes with NO WARRANTY, to the extent permitted by law.\n\
|
||||
You may redistribute it under the terms of the GNU General Public License;\n\
|
||||
@@ -421,7 +423,7 @@ top:
|
||||
do
|
||||
*--p = '0' + (int) (count % 10);
|
||||
while ((count /= 10) != 0);
|
||||
|
||||
|
||||
DEBUG1 ("rmtd: A %s\n", p);
|
||||
|
||||
sprintf (reply_buffer, "A%s\n", p);
|
||||
@@ -444,7 +446,7 @@ top:
|
||||
{
|
||||
status = safe_read (STDIN_FILENO, &record_buffer[counter],
|
||||
size - counter);
|
||||
if (status <= 0)
|
||||
if (status == SAFE_READ_ERROR || status == 0)
|
||||
{
|
||||
DEBUG (_("rmtd: Premature eof\n"));
|
||||
|
||||
@@ -453,7 +455,7 @@ top:
|
||||
}
|
||||
}
|
||||
status = full_write (tape, record_buffer, size);
|
||||
if (status < 0)
|
||||
if (status != size)
|
||||
goto ioerror;
|
||||
goto respond;
|
||||
}
|
||||
@@ -469,9 +471,9 @@ top:
|
||||
size = atol (count_string);
|
||||
prepare_input_buffer (-1, size);
|
||||
status = safe_read (tape, record_buffer, size);
|
||||
if (status < 0)
|
||||
if (status == SAFE_READ_ERROR)
|
||||
goto ioerror;
|
||||
sprintf (reply_buffer, "A%ld\n", (long) status);
|
||||
sprintf (reply_buffer, "A%lu\n", (unsigned long int) status);
|
||||
full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer));
|
||||
full_write (STDOUT_FILENO, record_buffer, status);
|
||||
goto top;
|
||||
@@ -496,13 +498,13 @@ top:
|
||||
/* Parse count_string, taking care to check for overflow.
|
||||
We can't use standard functions,
|
||||
since off_t might be longer than long. */
|
||||
|
||||
|
||||
for (p = count_string; *p == ' ' || *p == '\t'; p++)
|
||||
continue;
|
||||
|
||||
|
||||
negative = *p == '-';
|
||||
p += negative || *p == '+';
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int digit = *p++ - '0';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Definitions for communicating with a remote tape drive.
|
||||
|
||||
Copyright (C) 1988, 1992, 1996, 1997, 2001, 2003 Free Software
|
||||
Foundation, Inc.
|
||||
Copyright (C) 1988, 1992, 1996, 1997, 2001, 2003, 2004 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
|
||||
@@ -21,8 +21,8 @@ extern char *rmt_path__;
|
||||
|
||||
int rmt_open__ (const char *, int, int, const char *);
|
||||
int rmt_close__ (int);
|
||||
ssize_t rmt_read__ (int, char *, size_t);
|
||||
ssize_t rmt_write__ (int, char *, size_t);
|
||||
size_t rmt_read__ (int, char *, size_t);
|
||||
size_t rmt_write__ (int, char *, size_t);
|
||||
off_t rmt_lseek__ (int, off_t, int);
|
||||
int rmt_ioctl__ (int, int, char *);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Functions for communicating with a remote tape drive.
|
||||
|
||||
Copyright 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001 Free Software
|
||||
Foundation, Inc.
|
||||
Copyright 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2004 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
|
||||
@@ -163,8 +163,6 @@ get_status_string (int handle, char *command_buffer)
|
||||
|
||||
if (*cursor == 'E' || *cursor == 'F')
|
||||
{
|
||||
errno = atoi (cursor + 1);
|
||||
|
||||
/* Skip the error message line. */
|
||||
|
||||
/* FIXME: there is better to do than merely ignoring error messages
|
||||
@@ -178,6 +176,8 @@ get_status_string (int handle, char *command_buffer)
|
||||
break;
|
||||
}
|
||||
|
||||
errno = atoi (cursor + 1);
|
||||
|
||||
if (*cursor == 'F')
|
||||
_rmt_shutdown (handle, errno);
|
||||
|
||||
@@ -199,12 +199,19 @@ get_status_string (int handle, char *command_buffer)
|
||||
|
||||
/* Read and return the status from remote tape connection HANDLE. If
|
||||
an error occurred, return -1 and set errno. */
|
||||
static long
|
||||
static long int
|
||||
get_status (int handle)
|
||||
{
|
||||
char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
const char *status = get_status_string (handle, command_buffer);
|
||||
return status ? atol (status) : -1L;
|
||||
if (status)
|
||||
{
|
||||
long int result = atol (status);
|
||||
if (0 <= result)
|
||||
return result;
|
||||
errno = EIO;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static off_t
|
||||
@@ -226,10 +233,10 @@ get_status_off (int handle)
|
||||
|
||||
for (; *status == ' ' || *status == '\t'; status++)
|
||||
continue;
|
||||
|
||||
|
||||
negative = *status == '-';
|
||||
status += negative || *status == '+';
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int digit = *status++ - '0';
|
||||
@@ -533,7 +540,7 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
|
||||
int
|
||||
rmt_close__ (int handle)
|
||||
{
|
||||
int status;
|
||||
long int status;
|
||||
|
||||
if (do_command (handle, "C\n") == -1)
|
||||
return -1;
|
||||
@@ -544,26 +551,27 @@ rmt_close__ (int handle)
|
||||
}
|
||||
|
||||
/* Read up to LENGTH bytes into BUFFER from remote tape connection HANDLE.
|
||||
Return the number of bytes read on success, -1 on error. */
|
||||
ssize_t
|
||||
Return the number of bytes read on success, SAFE_READ_ERROR on error. */
|
||||
size_t
|
||||
rmt_read__ (int handle, char *buffer, size_t length)
|
||||
{
|
||||
char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
ssize_t status, rlen;
|
||||
size_t status;
|
||||
size_t rlen;
|
||||
size_t counter;
|
||||
|
||||
sprintf (command_buffer, "R%lu\n", (unsigned long) length);
|
||||
if (do_command (handle, command_buffer) == -1
|
||||
|| (status = get_status (handle)) == -1)
|
||||
return -1;
|
||||
|| (status = get_status (handle)) == SAFE_READ_ERROR)
|
||||
return SAFE_READ_ERROR;
|
||||
|
||||
for (counter = 0; counter < status; counter += rlen, buffer += rlen)
|
||||
{
|
||||
rlen = safe_read (READ_SIDE (handle), buffer, status - counter);
|
||||
if (rlen <= 0)
|
||||
if (rlen == SAFE_READ_ERROR || rlen == 0)
|
||||
{
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return -1;
|
||||
return SAFE_READ_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -571,8 +579,8 @@ rmt_read__ (int handle, char *buffer, size_t length)
|
||||
}
|
||||
|
||||
/* Write LENGTH bytes from BUFFER to remote tape connection HANDLE.
|
||||
Return the number of bytes written on success, -1 on error. */
|
||||
ssize_t
|
||||
Return the number of bytes written. */
|
||||
size_t
|
||||
rmt_write__ (int handle, char *buffer, size_t length)
|
||||
{
|
||||
char command_buffer[COMMAND_BUFFER_SIZE];
|
||||
@@ -581,18 +589,25 @@ rmt_write__ (int handle, char *buffer, size_t length)
|
||||
|
||||
sprintf (command_buffer, "W%lu\n", (unsigned long) length);
|
||||
if (do_command (handle, command_buffer) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
pipe_handler = signal (SIGPIPE, SIG_IGN);
|
||||
written = full_write (WRITE_SIDE (handle), buffer, length);
|
||||
signal (SIGPIPE, pipe_handler);
|
||||
if (written == length)
|
||||
return get_status (handle);
|
||||
{
|
||||
long int r = get_status (handle);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
if (r == length)
|
||||
return length;
|
||||
written = r;
|
||||
}
|
||||
|
||||
/* Write error. */
|
||||
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return -1;
|
||||
return written;
|
||||
}
|
||||
|
||||
/* Perform an imitation lseek operation on remote tape connection
|
||||
@@ -648,7 +663,7 @@ rmt_ioctl__ (int handle, int operation, char *argument)
|
||||
? - (uintmax_t) ((struct mtop *) argument)->mt_count
|
||||
: (uintmax_t) ((struct mtop *) argument)->mt_count);
|
||||
char *p = operand_buffer + sizeof operand_buffer;
|
||||
|
||||
|
||||
*--p = 0;
|
||||
do
|
||||
*--p = '0' + (int) (u % 10);
|
||||
@@ -671,7 +686,7 @@ rmt_ioctl__ (int handle, int operation, char *argument)
|
||||
case MTIOCGET:
|
||||
{
|
||||
ssize_t status;
|
||||
ssize_t counter;
|
||||
size_t counter;
|
||||
|
||||
/* Grab the status and read it directly into the structure. This
|
||||
assumes that the status buffer is not padded and that 2 shorts
|
||||
@@ -686,7 +701,7 @@ rmt_ioctl__ (int handle, int operation, char *argument)
|
||||
for (; status > 0; status -= counter, argument += counter)
|
||||
{
|
||||
counter = safe_read (READ_SIDE (handle), argument, status);
|
||||
if (counter <= 0)
|
||||
if (counter == SAFE_READ_ERROR || counter == 0)
|
||||
{
|
||||
_rmt_shutdown (handle, EIO);
|
||||
return -1;
|
||||
|
||||
141
src/sparse.c
141
src/sparse.c
@@ -1,6 +1,6 @@
|
||||
/* Functions for dealing with sparse files
|
||||
/* Functions for dealing with sparse files
|
||||
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2004 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
|
||||
@@ -39,8 +39,8 @@ struct tar_sparse_optab
|
||||
bool (*decode_header) (struct tar_sparse_file *);
|
||||
bool (*scan_block) (struct tar_sparse_file *, enum sparse_scan_state,
|
||||
void *);
|
||||
bool (*dump_region) (struct tar_sparse_file *, size_t index);
|
||||
bool (*extract_region) (struct tar_sparse_file *, size_t index);
|
||||
bool (*dump_region) (struct tar_sparse_file *, size_t);
|
||||
bool (*extract_region) (struct tar_sparse_file *, size_t);
|
||||
};
|
||||
|
||||
struct tar_sparse_file
|
||||
@@ -89,18 +89,18 @@ tar_sparse_scan (struct tar_sparse_file *file, enum sparse_scan_state state,
|
||||
}
|
||||
|
||||
static bool
|
||||
tar_sparse_dump_region (struct tar_sparse_file *file, size_t index)
|
||||
tar_sparse_dump_region (struct tar_sparse_file *file, size_t i)
|
||||
{
|
||||
if (file->optab->dump_region)
|
||||
return file->optab->dump_region (file, index);
|
||||
return file->optab->dump_region (file, i);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
tar_sparse_extract_region (struct tar_sparse_file *file, size_t index)
|
||||
tar_sparse_extract_region (struct tar_sparse_file *file, size_t i)
|
||||
{
|
||||
if (file->optab->extract_region)
|
||||
return file->optab->extract_region (file, index);
|
||||
return file->optab->extract_region (file, i);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -191,11 +191,12 @@ sparse_scan_file (struct tar_sparse_file *file)
|
||||
|
||||
file->stat_info->sparse_map_size = 0;
|
||||
file->stat_info->archive_file_size = 0;
|
||||
|
||||
|
||||
if (!tar_sparse_scan (file, scan_begin, NULL))
|
||||
return false;
|
||||
|
||||
while ((count = safe_read (file->fd, buffer, sizeof buffer)) > 0)
|
||||
while ((count = safe_read (file->fd, buffer, sizeof buffer)) != 0
|
||||
&& count != SAFE_READ_ERROR)
|
||||
{
|
||||
/* Analize the block */
|
||||
if (zero_block_p (buffer, count))
|
||||
@@ -217,11 +218,11 @@ sparse_scan_file (struct tar_sparse_file *file)
|
||||
if (!tar_sparse_scan (file, scan_block, buffer))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
offset += count;
|
||||
clear_block (buffer);
|
||||
}
|
||||
|
||||
|
||||
if (sp.numbytes == 0)
|
||||
sp.offset = offset;
|
||||
|
||||
@@ -255,7 +256,7 @@ sparse_select_optab (struct tar_sparse_file *file)
|
||||
case STAR_FORMAT:
|
||||
file->optab = &star_optab;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -263,28 +264,28 @@ sparse_select_optab (struct tar_sparse_file *file)
|
||||
}
|
||||
|
||||
static bool
|
||||
sparse_dump_region (struct tar_sparse_file *file, size_t index)
|
||||
sparse_dump_region (struct tar_sparse_file *file, size_t i)
|
||||
{
|
||||
union block *blk;
|
||||
off_t bytes_left = file->stat_info->sparse_map[index].numbytes;
|
||||
|
||||
if (!lseek_or_error (file, file->stat_info->sparse_map[index].offset,
|
||||
off_t bytes_left = file->stat_info->sparse_map[i].numbytes;
|
||||
|
||||
if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset,
|
||||
SEEK_SET))
|
||||
return false;
|
||||
|
||||
while (bytes_left > 0)
|
||||
{
|
||||
size_t bufsize = (bytes_left > BLOCKSIZE) ? BLOCKSIZE : bytes_left;
|
||||
off_t bytes_read;
|
||||
|
||||
size_t bytes_read;
|
||||
|
||||
blk = find_next_block ();
|
||||
memset (blk->buffer, 0, BLOCKSIZE);
|
||||
bytes_read = safe_read (file->fd, blk->buffer, bufsize);
|
||||
if (bytes_read < 0)
|
||||
if (bytes_read == SAFE_READ_ERROR)
|
||||
{
|
||||
read_diag_details (file->stat_info->orig_file_name,
|
||||
file->stat_info->sparse_map[index].offset
|
||||
+ file->stat_info->sparse_map[index].numbytes
|
||||
file->stat_info->sparse_map[i].offset
|
||||
+ file->stat_info->sparse_map[i].numbytes
|
||||
- bytes_left,
|
||||
bufsize);
|
||||
return false;
|
||||
@@ -299,15 +300,15 @@ sparse_dump_region (struct tar_sparse_file *file, size_t index)
|
||||
}
|
||||
|
||||
static bool
|
||||
sparse_extract_region (struct tar_sparse_file *file, size_t index)
|
||||
sparse_extract_region (struct tar_sparse_file *file, size_t i)
|
||||
{
|
||||
size_t write_size;
|
||||
|
||||
if (!lseek_or_error (file, file->stat_info->sparse_map[index].offset,
|
||||
|
||||
if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset,
|
||||
SEEK_SET))
|
||||
return false;
|
||||
|
||||
write_size = file->stat_info->sparse_map[index].numbytes;
|
||||
write_size = file->stat_info->sparse_map[i].numbytes;
|
||||
|
||||
if (write_size == 0)
|
||||
{
|
||||
@@ -343,12 +344,12 @@ sparse_extract_region (struct tar_sparse_file *file, size_t index)
|
||||
|
||||
/* Interface functions */
|
||||
enum dump_status
|
||||
sparse_dump_file (int fd, struct tar_stat_info *stat)
|
||||
sparse_dump_file (int fd, struct tar_stat_info *st)
|
||||
{
|
||||
bool rc;
|
||||
struct tar_sparse_file file;
|
||||
|
||||
file.stat_info = stat;
|
||||
file.stat_info = st;
|
||||
file.fd = fd;
|
||||
|
||||
if (!sparse_select_optab (&file)
|
||||
@@ -375,43 +376,43 @@ sparse_dump_file (int fd, struct tar_stat_info *stat)
|
||||
|
||||
/* Returns true if the file represented by stat is a sparse one */
|
||||
bool
|
||||
sparse_file_p (struct tar_stat_info *stat)
|
||||
sparse_file_p (struct tar_stat_info *st)
|
||||
{
|
||||
return (ST_NBLOCKS (stat->stat)
|
||||
< (stat->stat.st_size / ST_NBLOCKSIZE
|
||||
+ (stat->stat.st_size % ST_NBLOCKSIZE != 0)));
|
||||
return (ST_NBLOCKS (st->stat)
|
||||
< (st->stat.st_size / ST_NBLOCKSIZE
|
||||
+ (st->stat.st_size % ST_NBLOCKSIZE != 0)));
|
||||
}
|
||||
|
||||
bool
|
||||
sparse_member_p (struct tar_stat_info *stat)
|
||||
sparse_member_p (struct tar_stat_info *st)
|
||||
{
|
||||
struct tar_sparse_file file;
|
||||
|
||||
|
||||
if (!sparse_select_optab (&file))
|
||||
return false;
|
||||
file.stat_info = stat;
|
||||
file.stat_info = st;
|
||||
return tar_sparse_member_p (&file);
|
||||
}
|
||||
|
||||
bool
|
||||
sparse_fixup_header (struct tar_stat_info *stat)
|
||||
sparse_fixup_header (struct tar_stat_info *st)
|
||||
{
|
||||
struct tar_sparse_file file;
|
||||
|
||||
|
||||
if (!sparse_select_optab (&file))
|
||||
return false;
|
||||
file.stat_info = stat;
|
||||
file.stat_info = st;
|
||||
return tar_sparse_fixup_header (&file);
|
||||
}
|
||||
|
||||
enum dump_status
|
||||
sparse_extract_file (int fd, struct tar_stat_info *stat, off_t *size)
|
||||
sparse_extract_file (int fd, struct tar_stat_info *st, off_t *size)
|
||||
{
|
||||
bool rc = true;
|
||||
struct tar_sparse_file file;
|
||||
size_t i;
|
||||
|
||||
file.stat_info = stat;
|
||||
|
||||
file.stat_info = st;
|
||||
file.fd = fd;
|
||||
|
||||
if (!sparse_select_optab (&file)
|
||||
@@ -426,12 +427,12 @@ sparse_extract_file (int fd, struct tar_stat_info *stat, off_t *size)
|
||||
}
|
||||
|
||||
enum dump_status
|
||||
sparse_skip_file (struct tar_stat_info *stat)
|
||||
sparse_skip_file (struct tar_stat_info *st)
|
||||
{
|
||||
bool rc = true;
|
||||
struct tar_sparse_file file;
|
||||
|
||||
file.stat_info = stat;
|
||||
|
||||
file.stat_info = st;
|
||||
file.fd = -1;
|
||||
|
||||
if (!sparse_select_optab (&file)
|
||||
@@ -445,23 +446,23 @@ sparse_skip_file (struct tar_stat_info *stat)
|
||||
|
||||
|
||||
static char diff_buffer[BLOCKSIZE];
|
||||
|
||||
|
||||
static bool
|
||||
check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
|
||||
{
|
||||
if (!lseek_or_error (file, beg, SEEK_SET))
|
||||
return false;
|
||||
|
||||
|
||||
while (beg < end)
|
||||
{
|
||||
size_t bytes_read;
|
||||
size_t rdsize = end - beg;
|
||||
|
||||
|
||||
if (rdsize > BLOCKSIZE)
|
||||
rdsize = BLOCKSIZE;
|
||||
clear_block (diff_buffer);
|
||||
bytes_read = safe_read (file->fd, diff_buffer, rdsize);
|
||||
if (bytes_read < 0)
|
||||
if (bytes_read == SAFE_READ_ERROR)
|
||||
{
|
||||
read_diag_details (file->stat_info->orig_file_name,
|
||||
beg,
|
||||
@@ -481,19 +482,19 @@ check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
|
||||
}
|
||||
|
||||
static bool
|
||||
check_data_region (struct tar_sparse_file *file, size_t index)
|
||||
check_data_region (struct tar_sparse_file *file, size_t i)
|
||||
{
|
||||
size_t size_left;
|
||||
|
||||
if (!lseek_or_error (file, file->stat_info->sparse_map[index].offset,
|
||||
|
||||
if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset,
|
||||
SEEK_SET))
|
||||
return false;
|
||||
size_left = file->stat_info->sparse_map[index].numbytes;
|
||||
size_left = file->stat_info->sparse_map[i].numbytes;
|
||||
while (size_left > 0)
|
||||
{
|
||||
size_t bytes_read;
|
||||
size_t rdsize = (size_left > BLOCKSIZE) ? BLOCKSIZE : size_left;
|
||||
|
||||
|
||||
union block *blk = find_next_block ();
|
||||
if (!blk)
|
||||
{
|
||||
@@ -502,11 +503,11 @@ check_data_region (struct tar_sparse_file *file, size_t index)
|
||||
}
|
||||
set_next_block_after (blk);
|
||||
bytes_read = safe_read (file->fd, diff_buffer, rdsize);
|
||||
if (bytes_read < 0)
|
||||
if (bytes_read == SAFE_READ_ERROR)
|
||||
{
|
||||
read_diag_details (file->stat_info->orig_file_name,
|
||||
file->stat_info->sparse_map[index].offset
|
||||
+ file->stat_info->sparse_map[index].numbytes
|
||||
file->stat_info->sparse_map[i].offset
|
||||
+ file->stat_info->sparse_map[i].numbytes
|
||||
- size_left,
|
||||
rdsize);
|
||||
return false;
|
||||
@@ -523,14 +524,14 @@ check_data_region (struct tar_sparse_file *file, size_t index)
|
||||
}
|
||||
|
||||
bool
|
||||
sparse_diff_file (int fd, struct tar_stat_info *stat)
|
||||
sparse_diff_file (int fd, struct tar_stat_info *st)
|
||||
{
|
||||
bool rc = true;
|
||||
struct tar_sparse_file file;
|
||||
size_t i;
|
||||
off_t offset = 0;
|
||||
|
||||
file.stat_info = stat;
|
||||
|
||||
file.stat_info = st;
|
||||
file.fd = fd;
|
||||
|
||||
if (!sparse_select_optab (&file)
|
||||
@@ -554,14 +555,14 @@ sparse_diff_file (int fd, struct tar_stat_info *stat)
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Old GNU Format. The sparse file information is stored in the
|
||||
oldgnu_header in the following manner:
|
||||
|
||||
The header is marked with type 'S'. Its `size' field contains
|
||||
the cumulative size of all non-empty blocks of the file. The
|
||||
actual file size is stored in `realsize' member of oldgnu_header.
|
||||
|
||||
|
||||
The map of the file is stored in a list of `struct sparse'.
|
||||
Each struct contains offset to the block of data and its
|
||||
size (both as octal numbers). The first file header contains
|
||||
@@ -581,13 +582,13 @@ enum oldgnu_add_status
|
||||
};
|
||||
|
||||
static bool
|
||||
oldgnu_sparse_member_p (struct tar_sparse_file *file_unused)
|
||||
oldgnu_sparse_member_p (struct tar_sparse_file *file __attribute__ ((unused)))
|
||||
{
|
||||
return current_header->header.typeflag == GNUTYPE_SPARSE;
|
||||
}
|
||||
|
||||
/* Add a sparse item to the sparse file and its obstack */
|
||||
static enum oldgnu_add_status
|
||||
static enum oldgnu_add_status
|
||||
oldgnu_add_sparse (struct tar_sparse_file *file, struct sparse *s)
|
||||
{
|
||||
struct sp_array sp;
|
||||
@@ -624,7 +625,7 @@ oldgnu_get_sparse_info (struct tar_sparse_file *file)
|
||||
union block *h = current_header;
|
||||
int ext_p;
|
||||
static enum oldgnu_add_status rc;
|
||||
|
||||
|
||||
file->stat_info->sparse_map_size = 0;
|
||||
for (i = 0; i < SPARSES_IN_OLDGNU_HEADER; i++)
|
||||
{
|
||||
@@ -676,7 +677,7 @@ oldgnu_dump_header (struct tar_sparse_file *file)
|
||||
off_t block_ordinal = current_block_ordinal ();
|
||||
union block *blk;
|
||||
size_t i;
|
||||
|
||||
|
||||
blk = start_header (file->stat_info);
|
||||
blk->header.typeflag = GNUTYPE_SPARSE;
|
||||
if (file->stat_info->sparse_map_avail > SPARSES_IN_OLDGNU_HEADER)
|
||||
@@ -693,7 +694,7 @@ oldgnu_dump_header (struct tar_sparse_file *file)
|
||||
SPARSES_IN_OLDGNU_HEADER);
|
||||
blk->oldgnu_header.isextended = i < file->stat_info->sparse_map_avail;
|
||||
finish_header (file->stat_info, blk, block_ordinal);
|
||||
|
||||
|
||||
while (i < file->stat_info->sparse_map_avail)
|
||||
{
|
||||
blk = find_next_block ();
|
||||
@@ -726,7 +727,7 @@ static struct tar_sparse_optab oldgnu_optab = {
|
||||
/* Star */
|
||||
|
||||
static bool
|
||||
star_sparse_member_p (struct tar_sparse_file *file_unused)
|
||||
star_sparse_member_p (struct tar_sparse_file *file __attribute__ ((unused)))
|
||||
{
|
||||
return current_header->header.typeflag == GNUTYPE_SPARSE;
|
||||
}
|
||||
@@ -750,7 +751,7 @@ star_get_sparse_info (struct tar_sparse_file *file)
|
||||
union block *h = current_header;
|
||||
int ext_p;
|
||||
static enum oldgnu_add_status rc;
|
||||
|
||||
|
||||
file->stat_info->sparse_map_size = 0;
|
||||
|
||||
if (h->star_in_header.prefix[0] == '\0'
|
||||
@@ -799,7 +800,7 @@ static struct tar_sparse_optab star_optab = {
|
||||
star_fixup_header,
|
||||
star_get_sparse_info,
|
||||
NULL, /* No scan_block function */
|
||||
NULL, /* No dump region function */
|
||||
NULL, /* No dump region function */
|
||||
sparse_extract_region,
|
||||
};
|
||||
|
||||
@@ -836,7 +837,7 @@ pax_dump_header (struct tar_sparse_file *file)
|
||||
xheader_store ("GNU.sparse.offset", file->stat_info, &i);
|
||||
xheader_store ("GNU.sparse.numbytes", file->stat_info, &i);
|
||||
}
|
||||
|
||||
|
||||
blk = start_header (file->stat_info);
|
||||
/* Store the effective (shrunken) file size */
|
||||
OFF_TO_CHARS (file->stat_info->archive_file_size, blk->header.size);
|
||||
|
||||
120
src/system.c
120
src/system.c
@@ -1,6 +1,6 @@
|
||||
/* System-dependent calls for tar.
|
||||
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2004 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
|
||||
@@ -23,46 +23,33 @@
|
||||
#include <signal.h>
|
||||
|
||||
void
|
||||
sys_stat_nanoseconds(struct tar_stat_info *stat)
|
||||
sys_stat_nanoseconds (struct tar_stat_info *st)
|
||||
{
|
||||
#if defined(HAVE_STRUCT_STAT_ST_SPARE1)
|
||||
stat->atime_nsec = stat->stat.st_spare1 * 1000;
|
||||
stat->mtime_nsec = stat->stat.st_spare2 * 1000;
|
||||
stat->ctime_nsec = stat->stat.st_spare3 * 1000;
|
||||
st->atime_nsec = st->stat.st_spare1 * 1000;
|
||||
st->mtime_nsec = st->stat.st_spare2 * 1000;
|
||||
st->ctime_nsec = st->stat.st_spare3 * 1000;
|
||||
#elif defined(HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC)
|
||||
stat->atime_nsec = stat->stat.st_atim.tv_nsec;
|
||||
stat->mtime_nsec = stat->stat.st_mtim.tv_nsec;
|
||||
stat->ctime_nsec = stat->stat.st_ctim.tv_nsec;
|
||||
st->atime_nsec = st->stat.st_atim.tv_nsec;
|
||||
st->mtime_nsec = st->stat.st_mtim.tv_nsec;
|
||||
st->ctime_nsec = st->stat.st_ctim.tv_nsec;
|
||||
#elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC)
|
||||
stat->atime_nsec = stat->stat.st_atimespec.tv_nsec;
|
||||
stat->mtime_nsec = stat->stat.st_mtimespec.tv_nsec;
|
||||
stat->ctime_nsec = stat->stat.st_ctimespec.tv_nsec;
|
||||
st->atime_nsec = st->stat.st_atimespec.tv_nsec;
|
||||
st->mtime_nsec = st->stat.st_mtimespec.tv_nsec;
|
||||
st->ctime_nsec = st->stat.st_ctimespec.tv_nsec;
|
||||
#elif defined(HAVE_STRUCT_STAT_ST_ATIMENSEC)
|
||||
stat->atime_nsec = stat->stat.st_atimensec;
|
||||
stat->mtime_nsec = stat->stat.st_mtimensec;
|
||||
stat->ctime_nsec = stat->stat.st_ctimensec;
|
||||
st->atime_nsec = st->stat.st_atimensec;
|
||||
st->mtime_nsec = st->stat.st_mtimensec;
|
||||
st->ctime_nsec = st->stat.st_ctimensec;
|
||||
#else
|
||||
stat->atime_nsec = stat->mtime_nsec = stat->ctime_nsec = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
sys_utimes(char *file_name, struct timeval tvp[3])
|
||||
{
|
||||
#ifdef HAVE_UTIMES
|
||||
return utimes (file_name, tvp);
|
||||
#else
|
||||
struct utimbuf utimbuf;
|
||||
utimbuf.actime = tvp[0].tv_sec;
|
||||
utimbuf.modtime = tvp[1].tv_sec;
|
||||
return utime (file_name, &utimbuf);
|
||||
st->atime_nsec = st->mtime_nsec = st->ctime_nsec = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MSDOS
|
||||
|
||||
bool
|
||||
sys_get_archive_stat ()
|
||||
sys_get_archive_stat (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -74,12 +61,12 @@ sys_file_is_archive (struct tar_stat_info *p)
|
||||
}
|
||||
|
||||
void
|
||||
sys_save_archive_dev_ino ()
|
||||
sys_save_archive_dev_ino (void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
sys_detect_dev_null_output ()
|
||||
sys_detect_dev_null_output (void)
|
||||
{
|
||||
static char const dev_null[] = "nul";
|
||||
|
||||
@@ -88,7 +75,7 @@ sys_detect_dev_null_output ()
|
||||
}
|
||||
|
||||
void
|
||||
sys_drain_input_pipe ()
|
||||
sys_drain_input_pipe (void)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -98,7 +85,7 @@ sys_wait_for_child (pid_t child_pid)
|
||||
}
|
||||
|
||||
void
|
||||
sys_spawn_shell ()
|
||||
sys_spawn_shell (void)
|
||||
{
|
||||
spawnl (P_WAIT, getenv ("COMSPEC"), "-", 0);
|
||||
}
|
||||
@@ -132,25 +119,14 @@ sys_truncate (int fd)
|
||||
}
|
||||
|
||||
void
|
||||
sys_reset_uid_gid ()
|
||||
sys_reset_uid_gid (void)
|
||||
{
|
||||
}
|
||||
|
||||
ssize_t
|
||||
size_t
|
||||
sys_write_archive_buffer (void)
|
||||
{
|
||||
ssize_t status;
|
||||
ssize_t written = 0;
|
||||
|
||||
while (0 <= (status = full_write (archive, record_start->buffer + written,
|
||||
record_size - written)))
|
||||
{
|
||||
written += status;
|
||||
if (written == record_size)
|
||||
break;
|
||||
}
|
||||
|
||||
return written ? written : status;
|
||||
return full_write (archive, record_start->buffer, record_size);
|
||||
}
|
||||
|
||||
/* Set ARCHIVE for writing, then compressing an archive. */
|
||||
@@ -174,11 +150,11 @@ extern union block *record_start; /* FIXME */
|
||||
static struct stat archive_stat; /* stat block for archive file */
|
||||
|
||||
bool
|
||||
sys_get_archive_stat ()
|
||||
sys_get_archive_stat (void)
|
||||
{
|
||||
return fstat (archive, &archive_stat) == 0;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
sys_file_is_archive (struct tar_stat_info *p)
|
||||
{
|
||||
@@ -187,7 +163,7 @@ sys_file_is_archive (struct tar_stat_info *p)
|
||||
|
||||
/* Save archive file inode and device numbers */
|
||||
void
|
||||
sys_save_archive_dev_ino ()
|
||||
sys_save_archive_dev_ino (void)
|
||||
{
|
||||
if (!_isrmt (archive) && S_ISREG (archive_stat.st_mode))
|
||||
{
|
||||
@@ -200,7 +176,7 @@ sys_save_archive_dev_ino ()
|
||||
|
||||
/* Detect if outputting to "/dev/null". */
|
||||
void
|
||||
sys_detect_dev_null_output ()
|
||||
sys_detect_dev_null_output (void)
|
||||
{
|
||||
static char const dev_null[] = "/dev/null";
|
||||
struct stat dev_null_stat;
|
||||
@@ -219,12 +195,15 @@ sys_detect_dev_null_output ()
|
||||
work to do, we might have to revise this area in such time. */
|
||||
|
||||
void
|
||||
sys_drain_input_pipe ()
|
||||
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 (rmtread (archive, record_start->buffer, record_size) > 0)
|
||||
while ((r = rmtread (archive, record_start->buffer, record_size)) != 0
|
||||
&& r != SAFE_READ_ERROR)
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -252,7 +231,7 @@ sys_wait_for_child (pid_t child_pid)
|
||||
}
|
||||
|
||||
void
|
||||
sys_spawn_shell ()
|
||||
sys_spawn_shell (void)
|
||||
{
|
||||
pid_t child;
|
||||
const char *shell = getenv ("SHELL");
|
||||
@@ -303,7 +282,7 @@ sys_truncate (int fd)
|
||||
}
|
||||
|
||||
void
|
||||
sys_reset_uid_gid ()
|
||||
sys_reset_uid_gid (void)
|
||||
{
|
||||
setuid (getuid ());
|
||||
setgid (getgid ());
|
||||
@@ -322,24 +301,10 @@ is_regular_file (const char *name)
|
||||
return errno == ENOENT;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
size_t
|
||||
sys_write_archive_buffer (void)
|
||||
{
|
||||
ssize_t status;
|
||||
ssize_t written = 0;
|
||||
|
||||
while (0 <= (status = rmtwrite (archive, record_start->buffer + written,
|
||||
record_size - written)))
|
||||
{
|
||||
written += status;
|
||||
if (written == record_size
|
||||
|| _isrmt (archive)
|
||||
|| ! (S_ISFIFO (archive_stat.st_mode)
|
||||
|| S_ISSOCK (archive_stat.st_mode)))
|
||||
break;
|
||||
}
|
||||
|
||||
return written ? written : status;
|
||||
return rmtwrite (archive, record_start->buffer, record_size);
|
||||
}
|
||||
|
||||
#define PREAD 0 /* read file descriptor from pipe() */
|
||||
@@ -471,7 +436,7 @@ sys_child_open_for_compress (void)
|
||||
|
||||
while (1)
|
||||
{
|
||||
ssize_t status = 0;
|
||||
size_t status = 0;
|
||||
char *cursor;
|
||||
size_t length;
|
||||
|
||||
@@ -484,13 +449,12 @@ sys_child_open_for_compress (void)
|
||||
size_t size = record_size - length;
|
||||
|
||||
status = safe_read (STDIN_FILENO, cursor, size);
|
||||
if (status <= 0)
|
||||
if (status == SAFE_READ_ERROR)
|
||||
read_fatal (use_compress_program_option);
|
||||
if (status == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (status < 0)
|
||||
read_fatal (use_compress_program_option);
|
||||
|
||||
/* Copy the record. */
|
||||
|
||||
if (status == 0)
|
||||
@@ -628,13 +592,13 @@ sys_child_open_for_uncompress (void)
|
||||
char *cursor;
|
||||
size_t maximum;
|
||||
size_t count;
|
||||
ssize_t status;
|
||||
size_t status;
|
||||
|
||||
clear_read_error_count ();
|
||||
|
||||
error_loop:
|
||||
status = rmtread (archive, record_start->buffer, record_size);
|
||||
if (status < 0)
|
||||
if (status == SAFE_READ_ERROR)
|
||||
{
|
||||
archive_read_error ();
|
||||
goto error_loop;
|
||||
|
||||
62
src/tar.c
62
src/tar.c
@@ -1,7 +1,7 @@
|
||||
/* A tar (tape archiver) program.
|
||||
|
||||
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
|
||||
2001, 2003 Free Software Foundation, Inc.
|
||||
2001, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
Written by John Gilmore, starting 1985-08-25.
|
||||
|
||||
@@ -335,7 +335,7 @@ static struct option long_options[] =
|
||||
{"volno-file", required_argument, 0, VOLNO_FILE_OPTION},
|
||||
{"wildcards", no_argument, 0, WILDCARDS_OPTION},
|
||||
{"wildcards-match-slash", no_argument, 0, WILDCARDS_MATCH_SLASH_OPTION},
|
||||
|
||||
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -519,7 +519,7 @@ Compatibility options:\n\
|
||||
-o when creating, same as --old-archive\n\
|
||||
when extracting, same as --no-same-owner\n"),
|
||||
stdout);
|
||||
|
||||
|
||||
fputs (_("\
|
||||
\n\
|
||||
The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
|
||||
@@ -595,7 +595,8 @@ decode_options (int argc, char **argv)
|
||||
blocking_factor = DEFAULT_BLOCKING;
|
||||
record_size = DEFAULT_BLOCKING * BLOCKSIZE;
|
||||
excluded = new_exclude ();
|
||||
newer_mtime_option = TYPE_MINIMUM (time_t);
|
||||
newer_mtime_option.tv_sec = TYPE_MINIMUM (time_t);
|
||||
newer_mtime_option.tv_nsec = -1;
|
||||
recursion_option = FNM_LEADING_DIR;
|
||||
|
||||
owner_option = -1;
|
||||
@@ -823,7 +824,7 @@ decode_options (int argc, char **argv)
|
||||
/* Fall through. */
|
||||
|
||||
case NEWER_MTIME_OPTION:
|
||||
if (newer_mtime_option != TYPE_MINIMUM (time_t))
|
||||
if (NEWER_OPTION_INITIALIZED (newer_mtime_option))
|
||||
USAGE_ERROR ((0, 0, _("More than one threshold date")));
|
||||
|
||||
if (FILESYSTEM_PREFIX_LEN (optarg) != 0
|
||||
@@ -836,14 +837,17 @@ decode_options (int argc, char **argv)
|
||||
stat_error (optarg);
|
||||
USAGE_ERROR ((0, 0, _("Date file not found")));
|
||||
}
|
||||
newer_mtime_option = st.st_mtime;
|
||||
newer_mtime_option.tv_sec = st.st_mtime;
|
||||
newer_mtime_option.tv_nsec = TIMESPEC_NS (st.st_mtim);
|
||||
}
|
||||
else
|
||||
{
|
||||
newer_mtime_option = get_date (optarg, 0);
|
||||
if (newer_mtime_option == (time_t) -1)
|
||||
WARN ((0, 0, _("Substituting %s for unknown date format %s"),
|
||||
tartime (newer_mtime_option), quote (optarg)));
|
||||
if (! get_date (&newer_mtime_option, optarg, NULL))
|
||||
{
|
||||
WARN ((0, 0, _("Substituting %s for unknown date format %s"),
|
||||
tartime (newer_mtime_option.tv_sec), quote (optarg)));
|
||||
newer_mtime_option.tv_nsec = 0;
|
||||
}
|
||||
else
|
||||
textual_date_option = optarg;
|
||||
}
|
||||
@@ -912,7 +916,7 @@ decode_options (int argc, char **argv)
|
||||
case UTC_OPTION:
|
||||
utc_option = true;
|
||||
break;
|
||||
|
||||
|
||||
case 'v':
|
||||
verbose_option++;
|
||||
break;
|
||||
@@ -990,7 +994,7 @@ decode_options (int argc, char **argv)
|
||||
case FORMAT_OPTION:
|
||||
set_archive_format (optarg);
|
||||
break;
|
||||
|
||||
|
||||
case INDEX_FILE_OPTION:
|
||||
index_file_name = optarg;
|
||||
break;
|
||||
@@ -1006,7 +1010,7 @@ decode_options (int argc, char **argv)
|
||||
case KEEP_NEWER_FILES_OPTION:
|
||||
old_files_option = KEEP_NEWER_FILES;
|
||||
break;
|
||||
|
||||
|
||||
case GROUP_OPTION:
|
||||
if (! (strlen (optarg) < GNAME_FIELD_SIZE
|
||||
&& gname_to_gid (optarg, &group_option)))
|
||||
@@ -1072,7 +1076,7 @@ decode_options (int argc, char **argv)
|
||||
_("Invalid number")));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case OVERWRITE_OPTION:
|
||||
old_files_option = OVERWRITE_OLD_FILES;
|
||||
break;
|
||||
@@ -1095,7 +1099,7 @@ decode_options (int argc, char **argv)
|
||||
pax_option++;
|
||||
xheader_set_option (optarg);
|
||||
break;
|
||||
|
||||
|
||||
case POSIX_OPTION:
|
||||
set_archive_format ("posix");
|
||||
break;
|
||||
@@ -1148,7 +1152,7 @@ decode_options (int argc, char **argv)
|
||||
strip_path_elements = u;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case SUFFIX_OPTION:
|
||||
backup_option = true;
|
||||
backup_suffix_string = optarg;
|
||||
@@ -1157,7 +1161,7 @@ decode_options (int argc, char **argv)
|
||||
case TOTALS_OPTION:
|
||||
totals_option = true;
|
||||
break;
|
||||
|
||||
|
||||
case USE_COMPRESS_PROGRAM_OPTION:
|
||||
set_use_compress_program_option (optarg);
|
||||
break;
|
||||
@@ -1285,7 +1289,7 @@ decode_options (int argc, char **argv)
|
||||
if (show_version)
|
||||
{
|
||||
printf ("tar (%s) %s\n%s\n", PACKAGE_NAME, PACKAGE_VERSION,
|
||||
"Copyright (C) 2003 Free Software Foundation, Inc.");
|
||||
"Copyright (C) 2004 Free Software Foundation, Inc.");
|
||||
puts (_("\
|
||||
This program comes with NO WARRANTY, to the extent permitted by law.\n\
|
||||
You may redistribute it under the terms of the GNU General Public License;\n\
|
||||
@@ -1308,7 +1312,7 @@ see the file named COPYING for details."));
|
||||
else
|
||||
archive_format = DEFAULT_ARCHIVE_FORMAT;
|
||||
}
|
||||
|
||||
|
||||
if (volume_label_option && subcommand_option == CREATE_SUBCOMMAND)
|
||||
assert_format (FORMAT_MASK (OLDGNU_FORMAT)
|
||||
| FORMAT_MASK (GNU_FORMAT));
|
||||
@@ -1316,12 +1320,12 @@ see the file named COPYING for details."));
|
||||
|
||||
if (incremental_option || multi_volume_option)
|
||||
assert_format (FORMAT_MASK (OLDGNU_FORMAT) | FORMAT_MASK (GNU_FORMAT));
|
||||
|
||||
|
||||
if (sparse_option)
|
||||
assert_format (FORMAT_MASK (OLDGNU_FORMAT)
|
||||
| FORMAT_MASK (GNU_FORMAT)
|
||||
| FORMAT_MASK (POSIX_FORMAT));
|
||||
|
||||
|
||||
if (occurrence_option)
|
||||
{
|
||||
if (!input_files && !files_from_option)
|
||||
@@ -1353,7 +1357,7 @@ see the file named COPYING for details."));
|
||||
_("Multiple archive files require `-M' option")));
|
||||
|
||||
if (listed_incremental_option
|
||||
&& newer_mtime_option != TYPE_MINIMUM (time_t))
|
||||
&& NEWER_OPTION_INITIALIZED (newer_mtime_option))
|
||||
USAGE_ERROR ((0, 0,
|
||||
_("Cannot combine --listed-incremental with --newer")));
|
||||
|
||||
@@ -1403,7 +1407,7 @@ see the file named COPYING for details."));
|
||||
|| subcommand_option != DIFF_SUBCOMMAND
|
||||
|| subcommand_option != LIST_SUBCOMMAND))
|
||||
USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
|
||||
|
||||
|
||||
/* If ready to unlink hierarchies, so we are for simpler files. */
|
||||
if (recursive_unlink_option)
|
||||
old_files_option = UNLINK_FIRST_OLD_FILES;
|
||||
@@ -1455,10 +1459,12 @@ see the file named COPYING for details."));
|
||||
|
||||
if (verbose_option && textual_date_option)
|
||||
{
|
||||
char const *treated_as = tartime (newer_mtime_option);
|
||||
/* FIXME: tartime should support nanoseconds, too, so that this
|
||||
comparison doesn't complain about lost nanoseconds. */
|
||||
char const *treated_as = tartime (newer_mtime_option.tv_sec);
|
||||
if (strcmp (textual_date_option, treated_as) != 0)
|
||||
WARN ((0, 0, _("Treating date `%s' as %s"),
|
||||
textual_date_option, treated_as));
|
||||
WARN ((0, 0, _("Treating date `%s' as %s + %ld nanoseconds"),
|
||||
textual_date_option, treated_as, newer_mtime_option.tv_nsec));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1499,7 +1505,7 @@ main (int argc, char **argv)
|
||||
/* Decode options. */
|
||||
|
||||
decode_options (argc, argv);
|
||||
name_init (argc, argv);
|
||||
name_init ();
|
||||
|
||||
/* Main command execution. */
|
||||
|
||||
@@ -1575,7 +1581,7 @@ tar_stat_init (struct tar_stat_info *st)
|
||||
{
|
||||
memset (st, 0, sizeof (*st));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tar_stat_destroy (struct tar_stat_info *st)
|
||||
{
|
||||
|
||||
12
src/update.c
12
src/update.c
@@ -1,7 +1,7 @@
|
||||
/* Update a tar archive.
|
||||
|
||||
Copyright (C) 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2003
|
||||
Free Software Foundation, Inc.
|
||||
Copyright (C) 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2003,
|
||||
2004 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
|
||||
@@ -33,7 +33,7 @@ extern union block *current_block;
|
||||
/* We've hit the end of the old stuff, and its time to start writing new
|
||||
stuff to the tape. This involves seeking back one record and
|
||||
re-writing the current record (which has been changed).
|
||||
FIXME: Either eliminate it or move it to common.h.
|
||||
FIXME: Either eliminate it or move it to common.h.
|
||||
*/
|
||||
bool time_to_start_writing;
|
||||
|
||||
@@ -66,7 +66,7 @@ append_file (char *path)
|
||||
{
|
||||
union block *start = find_next_block ();
|
||||
size_t buffer_size = available_space_after (start);
|
||||
ssize_t status;
|
||||
size_t status;
|
||||
char buf[UINTMAX_STRSIZE_BOUND];
|
||||
|
||||
if (bytes_left < buffer_size)
|
||||
@@ -78,7 +78,7 @@ append_file (char *path)
|
||||
}
|
||||
|
||||
status = safe_read (handle, start->buffer, buffer_size);
|
||||
if (status < 0)
|
||||
if (status == SAFE_READ_ERROR)
|
||||
read_fatal_details (path, stat_data.st_size - bytes_left,
|
||||
buffer_size);
|
||||
if (status == 0)
|
||||
@@ -111,7 +111,7 @@ update_archive (void)
|
||||
name_gather ();
|
||||
open_archive (ACCESS_UPDATE);
|
||||
xheader_write_global ();
|
||||
|
||||
|
||||
while (!found_end)
|
||||
{
|
||||
enum read_header status = read_header (false);
|
||||
|
||||
56
src/utf8.c
56
src/utf8.c
@@ -23,11 +23,13 @@
|
||||
# include <iconv.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBICONV
|
||||
|
||||
struct langtab
|
||||
{
|
||||
char *lang; /* Language code */
|
||||
char *terr; /* Territory code */
|
||||
char *charset; /* Corresponding charset */
|
||||
char const *lang; /* Language code */
|
||||
char const *terr; /* Territory code */
|
||||
char const *charset; /* Corresponding charset */
|
||||
};
|
||||
|
||||
/* The list of language codes defined in ISO 639 with the corresponding
|
||||
@@ -216,22 +218,22 @@ static struct langtab langtab[] = {
|
||||
{ "zh", "TW", "big5"}, /* Chinese */
|
||||
{ "zh", NULL, "gb2312"}, /* Chinese */
|
||||
{ "zu", NULL, NULL}, /* Zulu */
|
||||
{ NULL }
|
||||
{ NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
/* Given the language and (optionally) territory code, return the
|
||||
default character set for that language. See notes above. */
|
||||
|
||||
const char *
|
||||
charset_lookup (char *lang, char *terr)
|
||||
static char const *
|
||||
charset_lookup (char const *lang, char const *terr)
|
||||
{
|
||||
static struct langtab *p;
|
||||
struct langtab const *p;
|
||||
|
||||
if (!lang)
|
||||
return NULL;
|
||||
for (p = langtab; p->lang; p++)
|
||||
if (strcasecmp (p->lang, lang) == 0
|
||||
&& (terr == NULL
|
||||
&& (terr == NULL
|
||||
|| p->terr == NULL
|
||||
|| !strcasecmp (p->terr, terr) == 0))
|
||||
return p->charset;
|
||||
@@ -239,7 +241,7 @@ charset_lookup (char *lang, char *terr)
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_input_charset ()
|
||||
get_input_charset (void)
|
||||
{
|
||||
const char *charset = NULL;
|
||||
char *tmp;
|
||||
@@ -268,30 +270,18 @@ get_input_charset ()
|
||||
return charset;
|
||||
}
|
||||
|
||||
#else /* !defined HAVE_LIBICONV */
|
||||
|
||||
|
||||
#ifndef HAVE_LIBICONV
|
||||
# undef iconv_open
|
||||
# define iconv_open(tocode, fromcode) ((iconv_t) -1)
|
||||
|
||||
iconv_t
|
||||
iconv_open (const char *tocode, const char *fromcode)
|
||||
{
|
||||
return (iconv_t)(-1);
|
||||
}
|
||||
# undef iconv
|
||||
# define iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft) ((size_t) 0)
|
||||
|
||||
size_t
|
||||
iconv (iconv_t cd, ICONV_CONST char **inbuf, size_t *inbytesleft,
|
||||
char **outbuf, size_t *outbytesleft)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
# undef iconv_close
|
||||
# define iconv_close(cd) 0
|
||||
|
||||
int
|
||||
iconv_close (iconv_t cd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !HAVE_LIBICONV */
|
||||
#endif /* !defined HAVE_LIBICONV */
|
||||
|
||||
|
||||
|
||||
@@ -310,11 +300,11 @@ utf8_init (bool to_utf)
|
||||
}
|
||||
return conv_desc[(int) to_utf];
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
utf8_convert(bool to_utf, const char *input, char **output)
|
||||
utf8_convert (bool to_utf, char const *input, char **output)
|
||||
{
|
||||
const char *ib;
|
||||
char ICONV_CONST *ib;
|
||||
char *ob;
|
||||
size_t inlen;
|
||||
size_t outlen;
|
||||
@@ -332,7 +322,7 @@ utf8_convert(bool to_utf, const char *input, char **output)
|
||||
inlen = strlen (input) + 1;
|
||||
outlen = inlen * MB_LEN_MAX + 1;
|
||||
ob = *output = xmalloc (outlen);
|
||||
ib = input;
|
||||
ib = (char ICONV_CONST *) input;
|
||||
rc = iconv (cd, &ib, &inlen, &ob, &outlen);
|
||||
*ob = 0;
|
||||
return rc != -1;
|
||||
|
||||
164
src/xheader.c
164
src/xheader.c
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include <hash.h>
|
||||
#include <quotearg.h>
|
||||
#include <xstrtol.h>
|
||||
@@ -30,13 +31,14 @@
|
||||
|
||||
#include <fnmatch.h>
|
||||
|
||||
bool xheader_protected_pattern_p (const char *pattern);
|
||||
bool xheader_protected_keyword_p (const char *keyword);
|
||||
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));
|
||||
|
||||
/* Used by xheader_finish() */
|
||||
static void code_string (char const *string, char const *keyword,
|
||||
struct xheader *xhdr);
|
||||
static void extended_header_init ();
|
||||
static void extended_header_init (void);
|
||||
|
||||
/* Number of global headers written so far. */
|
||||
static size_t global_header_count;
|
||||
@@ -80,7 +82,7 @@ static char *exthdr_name;
|
||||
/* Template for the name field of a 'g' type header */
|
||||
static char *globexthdr_name;
|
||||
|
||||
bool
|
||||
static bool
|
||||
xheader_keyword_deleted_p (const char *kw)
|
||||
{
|
||||
struct keyword_list *kp;
|
||||
@@ -91,7 +93,7 @@ xheader_keyword_deleted_p (const char *kw)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
static bool
|
||||
xheader_keyword_override_p (const char *keyword)
|
||||
{
|
||||
struct keyword_list *kp;
|
||||
@@ -102,7 +104,7 @@ xheader_keyword_override_p (const char *keyword)
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
xheader_list_append (struct keyword_list **root, char const *kw,
|
||||
char const *value)
|
||||
{
|
||||
@@ -113,7 +115,7 @@ xheader_list_append (struct keyword_list **root, char const *kw,
|
||||
*root = kp;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
xheader_list_destroy (struct keyword_list **root)
|
||||
{
|
||||
if (root)
|
||||
@@ -130,15 +132,14 @@ xheader_list_destroy (struct keyword_list **root)
|
||||
*root = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
|
||||
static void
|
||||
xheader_set_single_keyword (char *kw)
|
||||
{
|
||||
USAGE_ERROR ((0, 0, _("Keyword %s is unknown or not yet imlemented"), kw));
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
xheader_set_keyword_equal (char *kw, char *eq)
|
||||
{
|
||||
bool global = true;
|
||||
@@ -157,7 +158,7 @@ xheader_set_keyword_equal (char *kw, char *eq)
|
||||
|
||||
for (p = eq + 1; *p && isspace (*p); p++)
|
||||
;
|
||||
|
||||
|
||||
if (strcmp (kw, "delete") == 0)
|
||||
{
|
||||
if (xheader_protected_pattern_p (p))
|
||||
@@ -232,11 +233,11 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, bool allow_n)
|
||||
size_t len = strlen (fmt);
|
||||
char *q;
|
||||
const char *p;
|
||||
char *dirname = NULL;
|
||||
char *basename = NULL;
|
||||
char *dir = NULL;
|
||||
char *base = NULL;
|
||||
char pidbuf[64];
|
||||
char nbuf[64];
|
||||
|
||||
|
||||
for (p = fmt; *p && (p = strchr (p, '%')); )
|
||||
{
|
||||
switch (p[1])
|
||||
@@ -248,25 +249,24 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, bool allow_n)
|
||||
case 'd':
|
||||
if (st)
|
||||
{
|
||||
dirname = safer_name_suffix (dir_name (st->orig_file_name),
|
||||
false);
|
||||
len += strlen (dirname) - 1;
|
||||
dir = safer_name_suffix (dir_name (st->orig_file_name), false);
|
||||
len += strlen (dir) - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'f':
|
||||
if (st)
|
||||
{
|
||||
basename = base_name (st->orig_file_name);
|
||||
len += strlen (basename) - 1;
|
||||
base = base_name (st->orig_file_name);
|
||||
len += strlen (base) - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'p':
|
||||
to_decimal (getpid (), pidbuf, sizeof pidbuf);
|
||||
len += strlen (pidbuf) - 1;
|
||||
break;
|
||||
|
||||
|
||||
case 'n':
|
||||
if (allow_n)
|
||||
{
|
||||
@@ -277,7 +277,7 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, bool allow_n)
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
|
||||
buf = xmalloc (len + 1);
|
||||
for (q = buf, p = fmt; *p; )
|
||||
{
|
||||
@@ -289,19 +289,19 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, bool allow_n)
|
||||
*q++ = *p++;
|
||||
p++;
|
||||
break;
|
||||
|
||||
|
||||
case 'd':
|
||||
if (dirname)
|
||||
q = stpcpy (q, dirname);
|
||||
if (dir)
|
||||
q = stpcpy (q, dir);
|
||||
p += 2;
|
||||
break;
|
||||
|
||||
|
||||
case 'f':
|
||||
if (basename)
|
||||
q = stpcpy (q, basename);
|
||||
if (base)
|
||||
q = stpcpy (q, base);
|
||||
p += 2;
|
||||
break;
|
||||
|
||||
|
||||
case 'p':
|
||||
q = stpcpy (q, pidbuf);
|
||||
p += 2;
|
||||
@@ -314,7 +314,7 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, bool allow_n)
|
||||
p += 2;
|
||||
}
|
||||
/* else fall through */
|
||||
|
||||
|
||||
default:
|
||||
*q++ = *p++;
|
||||
if (*p)
|
||||
@@ -343,7 +343,7 @@ xheader_xhdr_name (struct tar_stat_info *st)
|
||||
#define GLOBAL_HEADER_TEMPLATE "/GlobalHead.%p.%n"
|
||||
|
||||
char *
|
||||
xheader_ghdr_name ()
|
||||
xheader_ghdr_name (void)
|
||||
{
|
||||
if (!globexthdr_name)
|
||||
{
|
||||
@@ -366,7 +366,7 @@ xheader_write (char type, char *name, struct xheader *xhdr)
|
||||
union block *header;
|
||||
size_t size;
|
||||
char *p;
|
||||
|
||||
|
||||
size = xhdr->size;
|
||||
header = start_private_header (name, size);
|
||||
header->header.typeflag = type;
|
||||
@@ -374,11 +374,11 @@ xheader_write (char type, char *name, struct xheader *xhdr)
|
||||
simple_finish_header (header);
|
||||
|
||||
p = xhdr->buffer;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
size_t len;
|
||||
|
||||
|
||||
header = find_next_block ();
|
||||
len = BLOCKSIZE;
|
||||
if (len > size)
|
||||
@@ -392,17 +392,17 @@ xheader_write (char type, char *name, struct xheader *xhdr)
|
||||
}
|
||||
while (size > 0);
|
||||
xheader_destroy (xhdr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
xheader_write_global ()
|
||||
xheader_write_global (void)
|
||||
{
|
||||
char *name;
|
||||
struct keyword_list *kp;
|
||||
|
||||
if (!keyword_global_override_list)
|
||||
return;
|
||||
|
||||
|
||||
extended_header_init ();
|
||||
for (kp = keyword_global_override_list; kp; kp = kp->next)
|
||||
code_string (kp->value, kp->pattern, &extended_header);
|
||||
@@ -444,7 +444,7 @@ locate_handler (char const *keyword)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
static bool
|
||||
xheader_protected_pattern_p (const char *pattern)
|
||||
{
|
||||
struct xhdr_tab const *p;
|
||||
@@ -455,7 +455,7 @@ xheader_protected_pattern_p (const char *pattern)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
static bool
|
||||
xheader_protected_keyword_p (const char *keyword)
|
||||
{
|
||||
struct xhdr_tab const *p;
|
||||
@@ -534,7 +534,7 @@ decx (void *data, char const *keyword, char const *value)
|
||||
if (xheader_keyword_deleted_p (keyword)
|
||||
|| xheader_keyword_override_p (keyword))
|
||||
return;
|
||||
|
||||
|
||||
t = locate_handler (keyword);
|
||||
if (t)
|
||||
t->decoder (st, value);
|
||||
@@ -545,12 +545,12 @@ xheader_decode (struct tar_stat_info *st)
|
||||
{
|
||||
run_override_list (keyword_global_override_list, st);
|
||||
run_override_list (global_header_override_list, st);
|
||||
|
||||
|
||||
if (extended_header.size)
|
||||
{
|
||||
char *p = extended_header.buffer + BLOCKSIZE;
|
||||
char *endp = &extended_header.buffer[extended_header.size-1];
|
||||
|
||||
|
||||
while (p < endp)
|
||||
if (!decode_record (&p, decx, st))
|
||||
break;
|
||||
@@ -566,7 +566,7 @@ decg (void *data, char const *keyword, char const *value)
|
||||
}
|
||||
|
||||
void
|
||||
xheader_decode_global ()
|
||||
xheader_decode_global (void)
|
||||
{
|
||||
if (extended_header.size)
|
||||
{
|
||||
@@ -581,7 +581,7 @@ xheader_decode_global ()
|
||||
}
|
||||
|
||||
static void
|
||||
extended_header_init ()
|
||||
extended_header_init (void)
|
||||
{
|
||||
if (!extended_header.stk)
|
||||
{
|
||||
@@ -594,7 +594,7 @@ void
|
||||
xheader_store (char const *keyword, struct tar_stat_info const *st, void *data)
|
||||
{
|
||||
struct xhdr_tab const *t;
|
||||
|
||||
|
||||
if (extended_header.buffer)
|
||||
return;
|
||||
t = locate_handler (keyword);
|
||||
@@ -625,7 +625,7 @@ xheader_read (union block *p, size_t size)
|
||||
|
||||
if (len > BLOCKSIZE)
|
||||
len = BLOCKSIZE;
|
||||
|
||||
|
||||
memcpy (&extended_header.buffer[j], p->buffer, len);
|
||||
set_next_block_after (p);
|
||||
|
||||
@@ -783,19 +783,22 @@ code_num (uintmax_t value, char const *keyword, struct xheader *xhdr)
|
||||
}
|
||||
|
||||
static void
|
||||
dummy_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void *data)
|
||||
dummy_coder (struct tar_stat_info const *st __attribute__ ((unused)),
|
||||
char const *keyword __attribute__ ((unused)),
|
||||
struct xheader *xhdr __attribute__ ((unused)),
|
||||
void *data __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
dummy_decoder (struct tar_stat_info *st, char const *arg)
|
||||
dummy_decoder (struct tar_stat_info *st __attribute__ ((unused)),
|
||||
char const *arg __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
atime_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void *data)
|
||||
struct xheader *xhdr, void *data __attribute__ ((unused)))
|
||||
{
|
||||
code_time (st->stat.st_atime, st->atime_nsec, keyword, xhdr);
|
||||
}
|
||||
@@ -808,7 +811,7 @@ atime_decoder (struct tar_stat_info *st, char const *arg)
|
||||
|
||||
static void
|
||||
gid_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void *data)
|
||||
struct xheader *xhdr, void *data __attribute__ ((unused)))
|
||||
{
|
||||
code_num (st->stat.st_gid, keyword, xhdr);
|
||||
}
|
||||
@@ -823,7 +826,7 @@ gid_decoder (struct tar_stat_info *st, char const *arg)
|
||||
|
||||
static void
|
||||
gname_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void *data)
|
||||
struct xheader *xhdr, void *data __attribute__ ((unused)))
|
||||
{
|
||||
code_string (st->gname, keyword, xhdr);
|
||||
}
|
||||
@@ -836,7 +839,7 @@ gname_decoder (struct tar_stat_info *st, char const *arg)
|
||||
|
||||
static void
|
||||
linkpath_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void *data)
|
||||
struct xheader *xhdr, void *data __attribute__ ((unused)))
|
||||
{
|
||||
code_string (st->link_name, keyword, xhdr);
|
||||
}
|
||||
@@ -849,7 +852,7 @@ linkpath_decoder (struct tar_stat_info *st, char const *arg)
|
||||
|
||||
static void
|
||||
ctime_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void *data)
|
||||
struct xheader *xhdr, void *data __attribute__ ((unused)))
|
||||
{
|
||||
code_time (st->stat.st_ctime, st->ctime_nsec, keyword, xhdr);
|
||||
}
|
||||
@@ -862,7 +865,7 @@ ctime_decoder (struct tar_stat_info *st, char const *arg)
|
||||
|
||||
static void
|
||||
mtime_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void *data)
|
||||
struct xheader *xhdr, void *data __attribute__ ((unused)))
|
||||
{
|
||||
code_time (st->stat.st_mtime, st->mtime_nsec, keyword, xhdr);
|
||||
}
|
||||
@@ -875,7 +878,7 @@ mtime_decoder (struct tar_stat_info *st, char const *arg)
|
||||
|
||||
static void
|
||||
path_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void *data)
|
||||
struct xheader *xhdr, void *data __attribute__ ((unused)))
|
||||
{
|
||||
code_string (st->file_name, keyword, xhdr);
|
||||
}
|
||||
@@ -890,7 +893,7 @@ path_decoder (struct tar_stat_info *st, char const *arg)
|
||||
|
||||
static void
|
||||
size_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void *data)
|
||||
struct xheader *xhdr, void *data __attribute__ ((unused)))
|
||||
{
|
||||
code_num (st->stat.st_size, keyword, xhdr);
|
||||
}
|
||||
@@ -905,7 +908,7 @@ size_decoder (struct tar_stat_info *st, char const *arg)
|
||||
|
||||
static void
|
||||
uid_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void *data)
|
||||
struct xheader *xhdr, void *data __attribute__ ((unused)))
|
||||
{
|
||||
code_num (st->stat.st_uid, keyword, xhdr);
|
||||
}
|
||||
@@ -920,7 +923,7 @@ uid_decoder (struct tar_stat_info *st, char const *arg)
|
||||
|
||||
static void
|
||||
uname_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void *data)
|
||||
struct xheader *xhdr, void *data __attribute__ ((unused)))
|
||||
{
|
||||
code_string (st->uname, keyword, xhdr);
|
||||
}
|
||||
@@ -948,7 +951,8 @@ sparse_size_decoder (struct tar_stat_info *st, char const *arg)
|
||||
|
||||
static void
|
||||
sparse_numblocks_coder (struct tar_stat_info const *st, char const *keyword,
|
||||
struct xheader *xhdr, void *data)
|
||||
struct xheader *xhdr,
|
||||
void *data __attribute__ ((unused)))
|
||||
{
|
||||
code_num (st->sparse_map_avail, keyword, xhdr);
|
||||
}
|
||||
@@ -1007,18 +1011,18 @@ sparse_numbytes_decoder (struct tar_stat_info *st, char const *arg)
|
||||
}
|
||||
|
||||
struct xhdr_tab const xhdr_tab[] = {
|
||||
{ "atime", atime_coder, atime_decoder },
|
||||
{ "comment", dummy_coder, dummy_decoder },
|
||||
{ "charset", dummy_coder, dummy_decoder },
|
||||
{ "ctime", ctime_coder, ctime_decoder },
|
||||
{ "gid", gid_coder, gid_decoder },
|
||||
{ "gname", gname_coder, gname_decoder },
|
||||
{ "linkpath", linkpath_coder, linkpath_decoder},
|
||||
{ "mtime", mtime_coder, mtime_decoder },
|
||||
{ "path", path_coder, path_decoder },
|
||||
{ "size", size_coder, size_decoder },
|
||||
{ "uid", uid_coder, uid_decoder },
|
||||
{ "uname", uname_coder, uname_decoder },
|
||||
{ "atime", atime_coder, atime_decoder, false },
|
||||
{ "comment", dummy_coder, dummy_decoder, false },
|
||||
{ "charset", dummy_coder, dummy_decoder, false },
|
||||
{ "ctime", ctime_coder, ctime_decoder, false },
|
||||
{ "gid", gid_coder, gid_decoder, false },
|
||||
{ "gname", gname_coder, gname_decoder, false },
|
||||
{ "linkpath", linkpath_coder, linkpath_decoder, false },
|
||||
{ "mtime", mtime_coder, mtime_decoder, false },
|
||||
{ "path", path_coder, path_decoder, false },
|
||||
{ "size", size_coder, size_decoder, false },
|
||||
{ "uid", uid_coder, uid_decoder, false },
|
||||
{ "uname", uname_coder, uname_decoder, false },
|
||||
|
||||
/* Sparse file handling */
|
||||
{ "GNU.sparse.size", sparse_size_coder, sparse_size_decoder, true },
|
||||
@@ -1034,12 +1038,12 @@ struct xhdr_tab const xhdr_tab[] = {
|
||||
/* The next directory entry actually contains the names of files
|
||||
that were in the directory at the time the dump was made.
|
||||
Supersedes GNUTYPE_DUMPDIR header type. */
|
||||
{ "GNU.dump.name", dump_name_coder, dump_name_decoder },
|
||||
{ "GNU.dump.status", dump_status_coder, dump_status_decoder },
|
||||
{ "GNU.dump.name", dump_name_coder, dump_name_decoder, false },
|
||||
{ "GNU.dump.status", dump_status_coder, dump_status_decoder, false },
|
||||
|
||||
/* Keeps the tape/volume header. May be present only in the global headers.
|
||||
Equivalent to GNUTYPE_VOLHDR. */
|
||||
{ "GNU.volume.header", volume_header_coder, volume_header_decoder },
|
||||
{ "GNU.volume.header", volume_header_coder, volume_header_decoder, false },
|
||||
|
||||
/* These may be present in a first global header of the archive.
|
||||
They provide the same functionality as GNUTYPE_MULTIVOL header.
|
||||
@@ -1047,9 +1051,9 @@ struct xhdr_tab const xhdr_tab[] = {
|
||||
otherwise kept in the size field of a multivolume header. The
|
||||
GNU.volume.offset keeps the offset of the start of this volume,
|
||||
otherwise kept in oldgnu_header.offset. */
|
||||
{ "GNU.volume.size", volume_size_coder, volume_size_decoder },
|
||||
{ "GNU.volume.offset", volume_offset_coder, volume_offset_decoder },
|
||||
{ "GNU.volume.size", volume_size_coder, volume_size_decoder, false },
|
||||
{ "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, false },
|
||||
#endif
|
||||
|
||||
{ NULL, NULL, NULL }
|
||||
{ NULL, NULL, NULL, false }
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Generate a file containing some preset patterns.
|
||||
|
||||
Copyright (C) 1995, 1996, 1997, 2001, 2003 Free Software
|
||||
Copyright (C) 1995, 1996, 1997, 2001, 2003, 2004 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
François Pinard <pinard@iro.umontreal.ca>, 1995.
|
||||
@@ -54,7 +54,8 @@ static int file_length = 0;
|
||||
static enum pattern pattern = DEFAULT_PATTERN;
|
||||
|
||||
/* Explain how to use the program, then get out. */
|
||||
void
|
||||
static void usage (int) __attribute__ ((noreturn));
|
||||
static void
|
||||
usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
|
||||
@@ -30,8 +30,10 @@ char *progname;
|
||||
char *buffer;
|
||||
size_t buffer_size;
|
||||
|
||||
void
|
||||
die (char *fmt, ...)
|
||||
static void die (char const *, ...) __attribute__ ((noreturn,
|
||||
format (printf, 1, 2)));
|
||||
static void
|
||||
die (char const *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@@ -40,12 +42,13 @@ die (char *fmt, ...)
|
||||
vfprintf (stderr, fmt, ap);
|
||||
va_end (ap);
|
||||
fprintf (stderr, "\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
mkhole (int fd, off_t displ)
|
||||
{
|
||||
if (displ = lseek (fd, displ, SEEK_CUR) == -1)
|
||||
if (lseek (fd, displ, SEEK_CUR) == -1)
|
||||
{
|
||||
perror ("lseek");
|
||||
exit (1);
|
||||
@@ -53,11 +56,9 @@ mkhole (int fd, off_t displ)
|
||||
ftruncate (fd, lseek (fd, 0, SEEK_CUR));
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
mksparse (int fd, off_t displ, char *marks)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (; *marks; marks++)
|
||||
{
|
||||
memset (buffer, *marks, buffer_size);
|
||||
@@ -66,7 +67,7 @@ mksparse (int fd, off_t displ, char *marks)
|
||||
perror ("write");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
||||
if (lseek (fd, displ, SEEK_CUR) == -1)
|
||||
{
|
||||
perror ("lseek");
|
||||
@@ -75,14 +76,15 @@ mksparse (int fd, off_t displ, char *marks)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
usage ()
|
||||
static void usage (void) __attribute__ ((noreturn));
|
||||
static void
|
||||
usage (void)
|
||||
{
|
||||
printf ("Usage: mksparse filename blocksize disp letters [disp letters...] [disp]\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
xlat_suffix (off_t *vp, char *p)
|
||||
{
|
||||
if (p[1])
|
||||
@@ -92,7 +94,7 @@ xlat_suffix (off_t *vp, char *p)
|
||||
case 'g':
|
||||
case 'G':
|
||||
*vp *= 1024;
|
||||
|
||||
|
||||
case 'm':
|
||||
case 'M':
|
||||
*vp *= 1024;
|
||||
@@ -107,7 +109,7 @@ xlat_suffix (off_t *vp, char *p)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
@@ -115,20 +117,20 @@ main (int argc, char **argv)
|
||||
int fd;
|
||||
char *p;
|
||||
off_t n;
|
||||
|
||||
|
||||
progname = strrchr (argv[0], '/');
|
||||
if (progname)
|
||||
progname++;
|
||||
else
|
||||
progname = argv[0];
|
||||
|
||||
|
||||
if (argc < 4)
|
||||
usage ();
|
||||
|
||||
fd = open (argv[1], O_CREAT|O_TRUNC|O_RDWR, 0644);
|
||||
if (fd < 0)
|
||||
die ("cannot open %s", argv[1]);
|
||||
|
||||
|
||||
n = strtoul (argv[2], &p, 0);
|
||||
if (n <= 0 || (*p && xlat_suffix (&n, p)))
|
||||
die ("Invalid buffer size: %s", argv[2]);
|
||||
@@ -136,11 +138,11 @@ main (int argc, char **argv)
|
||||
buffer = malloc (buffer_size);
|
||||
if (!buffer)
|
||||
die ("Not enough memory");
|
||||
|
||||
|
||||
for (i = 3; i < argc; i += 2)
|
||||
{
|
||||
off_t displ;
|
||||
|
||||
|
||||
displ = strtoul (argv[i], &p, 0);
|
||||
if (displ < 0 || (*p && xlat_suffix (&displ, p)))
|
||||
die ("Invalid displacement: %s", argv[i]);
|
||||
@@ -153,7 +155,7 @@ main (int argc, char **argv)
|
||||
else
|
||||
mksparse (fd, displ, argv[i+1]);
|
||||
}
|
||||
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user