瀏覽代碼

Merge recent gnulib changes, and remove some lint.

Paul Eggert 21 年之前
父節點
當前提交
2bda83b48d
共有 26 個文件被更改,包括 880 次插入703 次删除
  1. 186 32
      ChangeLog
  2. 9 7
      bootstrap
  3. 3 1
      configure.ac
  4. 6 2
      lib/.cvsignore
  5. 8 2
      lib/Makefile.am
  6. 6 3
      m4/.cvsignore
  7. 21 21
      src/buffer.c
  8. 36 20
      src/common.h
  9. 14 13
      src/compare.c
  10. 152 151
      src/create.c
  11. 23 23
      src/extract.c
  12. 22 20
      src/incremen.c
  13. 19 14
      src/list.c
  14. 12 16
      src/misc.c
  15. 16 16
      src/names.c
  16. 20 18
      src/rmt.c
  17. 4 4
      src/rmt.h
  18. 39 24
      src/rtapelib.c
  19. 71 70
      src/sparse.c
  20. 42 78
      src/system.c
  21. 34 28
      src/tar.c
  22. 6 6
      src/update.c
  23. 23 33
      src/utf8.c
  24. 84 80
      src/xheader.c
  25. 3 2
      tests/genfile.c
  26. 21 19
      tests/mksparse.c

+ 186 - 32
ChangeLog

@@ -1,3 +1,157 @@
+2004-04-04  Paul Eggert  <[email protected]>
+
+	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  <[email protected]>
 2004-04-04  Sergey Poznyakoff  <[email protected]>
 
 
 	* NEWS: Updated
 	* NEWS: Updated
@@ -11,7 +165,7 @@
 	* tests/multiv02.sh: New file
 	* tests/multiv02.sh: New file
 	* tests/Makefile.am: Add sparse01.sh and multiv02.sh
 	* tests/Makefile.am: Add sparse01.sh and multiv02.sh
 	* tests/longv7.sh: Added missing call to 'after'
 	* tests/longv7.sh: Added missing call to 'after'
-	
+
 	* src/common.h: Added missing prototypes
 	* src/common.h: Added missing prototypes
 	* src/compare.c (diff_archive): Use is_sparse member
 	* src/compare.c (diff_archive): Use is_sparse member
 	instead of GNUTYPE_SPARSE.
 	instead of GNUTYPE_SPARSE.
@@ -49,7 +203,7 @@
 	(sparse_numbytes_decoder): Removed unused variable
 	(sparse_numbytes_decoder): Removed unused variable
 	* src/.cvsignore: Added .gdbinit
 	* src/.cvsignore: Added .gdbinit
 	* THANKS: Added Mads Martin Joergensen
 	* THANKS: Added Mads Martin Joergensen
-	
+
 2004-03-26  Sergey Poznyakoff  <[email protected]>
 2004-03-26  Sergey Poznyakoff  <[email protected]>
 
 
 	* src/create.c (write_long_name): Do not allow more than
 	* 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,
 	which is grossly wrong, since even if new_volume() below succeeds,
 	the subsequent call to rmtread will overwrite the chunk of data
 	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
 	* src/system.c (sys_child_open_for_uncompress): Minor stylistic
 	fix.
 	fix.
 	* tests/star/multi-fail.sh: New test.
 	* tests/star/multi-fail.sh: New test.
 	* tests/Makefile.am: Added multi-fail.sh
 	* tests/Makefile.am: Added multi-fail.sh
 	* tests/star/README: Updated
 	* tests/star/README: Updated
-	
+
 2004-02-29  Sergey Poznyakoff  <[email protected]>
 2004-02-29  Sergey Poznyakoff  <[email protected]>
 
 
 	* NEWS: Updated
 	* NEWS: Updated
@@ -116,7 +270,7 @@
 	* src/extract.c: Handle --keep-newer-files option
 	* src/extract.c: Handle --keep-newer-files option
 	* src/list.c (tartime): Print UTC if --utc was given.
 	* src/list.c (tartime): Print UTC if --utc was given.
 	* src/tar.c: New options: --utc and keep-newer-files
 	* src/tar.c: New options: --utc and keep-newer-files
-	
+
 	* tests/Makefile.am: Added new tests
 	* tests/Makefile.am: Added new tests
 	* tests/after: Rewritten
 	* tests/after: Rewritten
 	* tests/before: Rewritten
 	* tests/before: Rewritten
@@ -130,7 +284,7 @@
 	* tests/options.sh: Likewise
 	* tests/options.sh: Likewise
 	* tests/version.sh: Likewise
 	* tests/version.sh: Likewise
 	* tests/volume.sh: Likewise
 	* tests/volume.sh: Likewise
-	
+
 	* tests/star: New directory
 	* tests/star: New directory
 	* tests/star/README: New file
 	* tests/star/README: New file
 	* tests/star/gtarfail.sh: New file
 	* tests/star/gtarfail.sh: New file
@@ -171,7 +325,7 @@
 
 
 	Added UTF-8 support. Finished global extended header
 	Added UTF-8 support. Finished global extended header
 	support.
 	support.
-	
+
 	* NEWS: Minor fix
 	* NEWS: Minor fix
 	* configure.ac: Detect libiconv
 	* configure.ac: Detect libiconv
 	* src/utf8.c: New file. Conversions to and from utf-8.
 	* src/utf8.c: New file. Conversions to and from utf-8.
@@ -188,7 +342,7 @@
 	missing gettext markers
 	missing gettext markers
 	(decode_record): Rewritten using caller-provided handler and
 	(decode_record): Rewritten using caller-provided handler and
 	data closure.
 	data closure.
-	* tests/listed01.sh: Give credit to Andreas Schuldei.	
+	* tests/listed01.sh: Give credit to Andreas Schuldei.
 
 
 2004-02-21  Sergey Poznyakoff  <[email protected]>
 2004-02-21  Sergey Poznyakoff  <[email protected]>
 
 
@@ -198,8 +352,8 @@
 	<[email protected]>.
 	<[email protected]>.
 
 
 	This is due to the condition
 	This is due to the condition
-     
-          (0 < top_level || !incremental_option) 
+
+	  (0 < top_level || !incremental_option)
 
 
 	Removing it makes incremental backups work for individual
 	Removing it makes incremental backups work for individual
 	files as well as for directories. On the other hand, it does
 	files as well as for directories. On the other hand, it does
@@ -217,7 +371,7 @@
 
 
 	      (!incremental_option)
 	      (!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
 	1) when incremental_option==1
 	This means incremental backup in progress. In this case dump_file
 	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,
 	irrelevant, and its removal won't alter the behavior of tar,
 	*except* that it will enable incremental backups on individual
 	*except* that it will enable incremental backups on individual
 	files, which is the wanted effect.
 	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
 	In this case the condition yields true and its removal does not
 	affect the functionality.
 	affect the functionality.
 
 
@@ -245,7 +399,7 @@
 	* tests/listed01.sh: New test. Check listed incremental
 	* tests/listed01.sh: New test. Check listed incremental
 	backups on individual files.
 	backups on individual files.
 	* tests/Makefile.am: Added listed01.sh
 	* tests/Makefile.am: Added listed01.sh
-	
+
 2004-02-20  Sergey Poznyakoff  <[email protected]>
 2004-02-20  Sergey Poznyakoff  <[email protected]>
 
 
 	* src/common.h (simple_finish_header,start_private_header): New
 	* src/common.h (simple_finish_header,start_private_header): New
@@ -269,7 +423,7 @@
 
 
 	* src/update.c (update_archive): Write global extended header if
 	* src/update.c (update_archive): Write global extended header if
 	constructed.
 	constructed.
-	* src/xheader.c (xheader_format_name): Bugfix. 
+	* src/xheader.c (xheader_format_name): Bugfix.
 	(xheader_xhdr_name): Changed the default extended header name
 	(xheader_xhdr_name): Changed the default extended header name
 	to '%d/PaxHeaders.%p/%f', as POSIX requires.
 	to '%d/PaxHeaders.%p/%f', as POSIX requires.
 	(xheader_ghdr_name): Removed unused argument.
 	(xheader_ghdr_name): Removed unused argument.
@@ -281,25 +435,25 @@
 	unconditionally.
 	unconditionally.
 	* src/list.c (decode_header): Likewise.
 	* src/list.c (decode_header): Likewise.
 	* src/incremen.c (sort_obstack): Fixed typo in the comment
 	* src/incremen.c (sort_obstack): Fixed typo in the comment
-	
+
 	* doc/tar.texi: Document new default for extended
 	* doc/tar.texi: Document new default for extended
 	header names.
 	header names.
-	
+
 	* tests/before: Accept an optional list of allowed archive
 	* tests/before: Accept an optional list of allowed archive
 	formats. Exit with the status 77 if the current archive
 	formats. Exit with the status 77 if the current archive
 	format does not match any of them.
 	format does not match any of them.
 	* tests/delete03.sh: Require gnu, oldgnu or posix format
 	* tests/delete03.sh: Require gnu, oldgnu or posix format
 	* tests/incremen.sh: Require gnu or oldgnu format
 	* tests/incremen.sh: Require gnu or oldgnu format
 	* tests/multiv01.sh: Likewise
 	* tests/multiv01.sh: Likewise
-	
+
 2004-02-20  Sergey Poznyakoff  <[email protected]>
 2004-02-20  Sergey Poznyakoff  <[email protected]>
-	
+
 	* doc/tar.texi (Option Summary): Documented --pax-option
 	* doc/tar.texi (Option Summary): Documented --pax-option
 	* src/tar.c: Likewise.
 	* src/tar.c: Likewise.
 	* NEWS: Likewise.
 	* NEWS: Likewise.
 	* src/create.c (to_chars): Added a comment.
 	* src/create.c (to_chars): Added a comment.
 	* src/tar.h: Comment to GNU_FORMAT
 	* src/tar.h: Comment to GNU_FORMAT
-	
+
 2004-02-18  Sergey Poznyakoff  <[email protected]>
 2004-02-18  Sergey Poznyakoff  <[email protected]>
 
 
 	* README: Updated
 	* README: Updated
@@ -313,17 +467,17 @@
 	* src/tar.c: New option --pax-option (equivalent to -o option
 	* src/tar.c: New option --pax-option (equivalent to -o option
 	of pax).
 	of pax).
 	* src/xheader.c: Implement pax -o option. Fixed misleading
 	* 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
 	* src/incremen.c: Minor fixes
 	* m4/.cvsignore: Updated
 	* m4/.cvsignore: Updated
-	
+
 2004-02-17  Sergey Poznyakoff  <[email protected]>
 2004-02-17  Sergey Poznyakoff  <[email protected]>
 
 
 	* src/incremen.c: Removed accumulator stuff in favor of obstack.
 	* src/incremen.c: Removed accumulator stuff in favor of obstack.
 	(get_directory_contents): Split into two functions
 	(get_directory_contents): Split into two functions
 	* src/update.c: Minor changes
 	* src/update.c: Minor changes
 	* doc/tar.texi: Fixed typo
 	* doc/tar.texi: Fixed typo
-	
+
 2004-02-15  Paul Eggert  <[email protected]>
 2004-02-15  Paul Eggert  <[email protected]>
 
 
 	Fix Debian bug 230872, originally reported by Jeff King in
 	Fix Debian bug 230872, originally reported by Jeff King in
@@ -863,15 +1017,15 @@
 
 
 2003-09-03  Sergey Poznyakoff  <[email protected]>
 2003-09-03  Sergey Poznyakoff  <[email protected]>
 
 
-        * 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  <[email protected]>
 2003-09-01  Paul Eggert  <[email protected]>
 
 

+ 9 - 7
bootstrap

@@ -2,7 +2,7 @@
 
 
 # Bootstrap 'tar' from CVS.
 # 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
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
@@ -42,10 +42,10 @@ usage() {
  --no-po                      Do not download po files.
  --no-po                      Do not download po files.
 
 
 Running without arguments will suffice in most cases. It is equivalent
 Running without arguments will suffice in most cases. It is equivalent
-to 
+to
 
 
     ./bootstrap --cvs-auth=ext --cvs-user=anoncvs
     ./bootstrap --cvs-auth=ext --cvs-user=anoncvs
-    
+
 EOF
 EOF
 }
 }
 
 
@@ -84,7 +84,7 @@ build_cvs_prefix() {
        CVS_RSH=ssh
        CVS_RSH=ssh
        export CVS_RSH
        export CVS_RSH
     fi
     fi
-  fi 
+  fi
 }
 }
 
 
 # Get gnulib files.
 # Get gnulib files.
@@ -96,15 +96,15 @@ case ${GNULIB_SRCDIR--} in
 
 
     trap exit 1 2 13 15
     trap exit 1 2 13 15
     trap 'rm -fr gnulib; exit 1' 0
     trap 'rm -fr gnulib; exit 1' 0
-    
+
     case "${CVS_AUTH--}" in
     case "${CVS_AUTH--}" in
     -)       build_cvs_prefix ext anoncvs;;
     -)       build_cvs_prefix ext anoncvs;;
     pserver) build_cvs_prefix $CVS_AUTH ${CVS_USER:-anoncvs};;
     pserver) build_cvs_prefix $CVS_AUTH ${CVS_USER:-anoncvs};;
     gserver|server)
     gserver|server)
-             build_cvs_prefix $CVS_AUTH ${CVS_USER--};;
+	     build_cvs_prefix $CVS_AUTH ${CVS_USER--};;
     ext)     build_cvs_prefix $CVS_AUTH ${CVS_USER--};;
     ext)     build_cvs_prefix $CVS_AUTH ${CVS_USER--};;
     *)       echo "$0: Unknown CVS access method" >&2
     *)       echo "$0: Unknown CVS access method" >&2
-             exit 1;;
+	     exit 1;;
     esac
     esac
     if [ "${CVS_AUTH--}" = "pserver" ]; then
     if [ "${CVS_AUTH--}" = "pserver" ]; then
       cvs -d ${CVS_PREFIX}subversions.gnu.org:/cvsroot/gnulib login || exit
       cvs -d ${CVS_PREFIX}subversions.gnu.org:/cvsroot/gnulib login || exit
@@ -133,6 +133,7 @@ getdate
 getline
 getline
 getopt
 getopt
 gettext
 gettext
+gettime
 hash
 hash
 human
 human
 lchown
 lchown
@@ -149,6 +150,7 @@ stdbool
 stpcpy
 stpcpy
 strtol
 strtol
 strtoul
 strtoul
+timespec
 unlocked-io
 unlocked-io
 utime
 utime
 xalloc
 xalloc

+ 3 - 1
configure.ac

@@ -119,6 +119,7 @@ gl_FUNC_STRTOIMAX
 gl_FUNC_STRTOUMAX
 gl_FUNC_STRTOUMAX
 gl_GETDATE
 gl_GETDATE
 gl_GETOPT
 gl_GETOPT
+gl_GETTIME
 gl_HASH
 gl_HASH
 gl_HUMAN
 gl_HUMAN
 gl_MODECHANGE
 gl_MODECHANGE
@@ -132,6 +133,7 @@ gl_SAVE_CWD
 gl_SAVEDIR
 gl_SAVEDIR
 gl_STRCASE
 gl_STRCASE
 gl_TIME_R
 gl_TIME_R
+gl_TIMESPEC
 gl_XALLOC
 gl_XALLOC
 gl_XGETCWD
 gl_XGETCWD
 gl_XSTRTOL
 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/types.h>
 #include <sys/stat.h>])
 #include <sys/stat.h>])
- 
+
 # Save and restore LIBS so e.g., -lrt, isn't added to it.  Otherwise, *all*
 # 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
 # programs in the package would end up linked with that potentially-shared
 # library, inducing unnecessary run-time overhead.
 # library, inducing unnecessary run-time overhead.

+ 6 - 2
lib/.cvsignore

@@ -37,7 +37,10 @@ getndelim2.h
 getopt.c
 getopt.c
 getopt.h
 getopt.h
 getopt1.c
 getopt1.c
+getopt_int.h
 gettext.h
 gettext.h
+gettime.c
+gettimeofday.c
 hash.c
 hash.c
 hash.h
 hash.h
 human.c
 human.c
@@ -68,6 +71,8 @@ savedir.c
 savedir.h
 savedir.h
 stdbool.h
 stdbool.h
 stdbool_.h
 stdbool_.h
+stpcpy.c
+stpcpy.h
 strcase.h
 strcase.h
 strcasecmp.c
 strcasecmp.c
 stripslash.c
 stripslash.c
@@ -78,10 +83,9 @@ strtoll.c
 strtoul.c
 strtoul.c
 strtoull.c
 strtoull.c
 strtoumax.c
 strtoumax.c
-stpcpy.c
-stpcpy.h
 time_r.c
 time_r.c
 time_r.h
 time_r.h
+timespec.h
 unlocked-io.h
 unlocked-io.h
 utime.c
 utime.c
 xalloc.h
 xalloc.h

+ 8 - 2
lib/Makefile.am

@@ -1,7 +1,7 @@
 # Makefile for GNU tar library.
 # 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
 ## This program is free software; you can redistribute it and/or modify
 ## it under the terms of the GNU General Public License as published by
 ## it under the terms of the GNU General Public License as published by
@@ -103,6 +103,9 @@ libtar_a_SOURCES += getopt.h getopt.c getopt1.c
 # gettext
 # gettext
 libtar_a_SOURCES += gettext.h
 libtar_a_SOURCES += gettext.h
 
 
+# gettime
+libtar_a_SOURCES += gettime.c
+
 # hash
 # hash
 libtar_a_SOURCES += hash.h hash.c
 libtar_a_SOURCES += hash.h hash.c
 
 
@@ -121,6 +124,9 @@ libtar_a_SOURCES += pathmax.h
 # time_r
 # time_r
 EXTRA_DIST += time_r.h
 EXTRA_DIST += time_r.h
 
 
+# timespec
+libtar_a_SOURCES += timespec.h
+
 # quote
 # quote
 libtar_a_SOURCES += quote.h quote.c
 libtar_a_SOURCES += quote.h quote.c
 
 

+ 6 - 3
m4/.cvsignore

@@ -4,6 +4,7 @@ alloca.m4
 backupfile.m4
 backupfile.m4
 bison.m4
 bison.m4
 chown.m4
 chown.m4
+clock_time.m4
 codeset.m4
 codeset.m4
 d-ino.m4
 d-ino.m4
 dirname.m4
 dirname.m4
@@ -21,6 +22,8 @@ getline.m4
 getndelim2.m4
 getndelim2.m4
 getopt.m4
 getopt.m4
 gettext.m4
 gettext.m4
+gettime.m4
+gettimeofday.m4
 glibc21.m4
 glibc21.m4
 hash.m4
 hash.m4
 human.m4
 human.m4
@@ -39,7 +42,6 @@ lib-link.m4
 lib-prefix.m4
 lib-prefix.m4
 longdouble.m4
 longdouble.m4
 longlong.m4
 longlong.m4
-malloc.m4
 mbrtowc.m4
 mbrtowc.m4
 mbstate_t.m4
 mbstate_t.m4
 memset.m4
 memset.m4
@@ -54,7 +56,6 @@ printf-posix.m4
 progtest.m4
 progtest.m4
 quote.m4
 quote.m4
 quotearg.m4
 quotearg.m4
-realloc.m4
 restrict.m4
 restrict.m4
 rmdir.m4
 rmdir.m4
 safe-read.m4
 safe-read.m4
@@ -64,8 +65,10 @@ savedir.m4
 signed.m4
 signed.m4
 size_max.m4
 size_max.m4
 ssize_t.m4
 ssize_t.m4
+st_mtim.m4
 stdbool.m4
 stdbool.m4
 stdint_h.m4
 stdint_h.m4
+stpcpy.m4
 strcase.m4
 strcase.m4
 strerror_r.m4
 strerror_r.m4
 strtoimax.m4
 strtoimax.m4
@@ -74,8 +77,8 @@ strtoll.m4
 strtoul.m4
 strtoul.m4
 strtoull.m4
 strtoull.m4
 strtoumax.m4
 strtoumax.m4
-stpcpy.m4
 time_r.m4
 time_r.m4
+timespec.m4
 tm_gmtoff.m4
 tm_gmtoff.m4
 uintmax_t.m4
 uintmax_t.m4
 ulonglong.m4
 ulonglong.m4

+ 21 - 21
src/buffer.c

@@ -75,7 +75,7 @@ static int checkpoint;
    Declared in update.c
    Declared in update.c
 
 
    As least EXTERN like this one as possible. (?? --gray)
    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;
 extern bool time_to_start_writing;
 
 
@@ -109,7 +109,7 @@ static off_t real_s_sizeleft;
 /* Functions.  */
 /* Functions.  */
 
 
 void
 void
-clear_read_error_count ()
+clear_read_error_count (void)
 {
 {
   read_error_count = 0;
   read_error_count = 0;
 }
 }
@@ -600,7 +600,7 @@ archive_read_error (void)
 }
 }
 
 
 static void
 static void
-short_read (ssize_t status)
+short_read (size_t status)
 {
 {
   size_t left;			/* bytes left */
   size_t left;			/* bytes left */
   char *more;			/* pointer to next byte to read */
   char *more;			/* pointer to next byte to read */
@@ -612,23 +612,23 @@ short_read (ssize_t status)
 	 || (left && status && read_full_records_option))
 	 || (left && status && read_full_records_option))
     {
     {
       if (status)
       if (status)
-	while ((status = rmtread (archive, more, left)) < 0)
+	while ((status = rmtread (archive, more, left)) == SAFE_READ_ERROR)
 	  archive_read_error ();
 	  archive_read_error ();
 
 
       if (status == 0)
       if (status == 0)
 	{
 	{
 	  char buf[UINTMAX_STRSIZE_BOUND];
 	  char buf[UINTMAX_STRSIZE_BOUND];
-	  
+
 	  WARN((0, 0, _("Read %s bytes from %s"),
 	  WARN((0, 0, _("Read %s bytes from %s"),
 		STRINGIFY_BIGINT (record_size - left, buf),
 		STRINGIFY_BIGINT (record_size - left, buf),
 		*archive_name_cursor));
 		*archive_name_cursor));
 	  break;
 	  break;
 	}
 	}
-  
+
       if (! read_full_records_option)
       if (! read_full_records_option)
 	{
 	{
 	  unsigned long rest = record_size - left;
 	  unsigned long rest = record_size - left;
-	  
+
 	  FATAL_ERROR ((0, 0,
 	  FATAL_ERROR ((0, 0,
 			ngettext ("Unaligned block (%lu byte) in archive",
 			ngettext ("Unaligned block (%lu byte) in archive",
 				  "Unaligned block (%lu bytes) in archive",
 				  "Unaligned block (%lu bytes) in archive",
@@ -646,7 +646,7 @@ short_read (ssize_t status)
      about the problem.  */
      about the problem.  */
 
 
   if (!read_full_records_option && verbose_option > 1
   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;
       unsigned long rsize = (record_size - left) / BLOCKSIZE;
       WARN ((0, 0,
       WARN ((0, 0,
@@ -664,7 +664,7 @@ short_read (ssize_t status)
 void
 void
 flush_read (void)
 flush_read (void)
 {
 {
-  ssize_t status;		/* result from system call */
+  size_t status;		/* result from system call */
 
 
   if (checkpoint_option && !(++checkpoint % 10))
   if (checkpoint_option && !(++checkpoint % 10))
     WARN ((0, 0, _("Read checkpoint %d"), checkpoint));
     WARN ((0, 0, _("Read checkpoint %d"), checkpoint));
@@ -711,9 +711,9 @@ flush_read (void)
      This is incorrect since even if new_volume() succeeds, the
      This is incorrect since even if new_volume() succeeds, the
      subsequent call to rmtread will overwrite the chunk of data
      subsequent call to rmtread will overwrite the chunk of data
      already read in the buffer, so the processing will fail */
      already read in the buffer, so the processing will fail */
-        
+
   if ((status == 0
   if ((status == 0
-       || (status < 0 && errno == ENOSPC))
+       || (status == SAFE_READ_ERROR && errno == ENOSPC))
       && multi_volume_option)
       && multi_volume_option)
     {
     {
       union block *cursor;
       union block *cursor;
@@ -734,12 +734,12 @@ flush_read (void)
 	  break;
 	  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 ();
 	archive_read_error ();
-      
+
       if (status != record_size)
       if (status != record_size)
-	short_read (status); 
+	short_read (status);
 
 
       cursor = record_start;
       cursor = record_start;
 
 
@@ -807,7 +807,7 @@ flush_read (void)
       records_read++;
       records_read++;
       return;
       return;
     }
     }
-  else if (status < 0)
+  else if (status == SAFE_READ_ERROR)
     {
     {
       archive_read_error ();
       archive_read_error ();
       goto error_loop;		/* try again */
       goto error_loop;		/* try again */
@@ -897,7 +897,7 @@ close_archive (void)
     flush_archive ();
     flush_archive ();
 
 
   sys_drain_input_pipe ();
   sys_drain_input_pipe ();
-  
+
   if (verify_option)
   if (verify_option)
     verify_volume ();
     verify_volume ();
 
 
@@ -905,7 +905,7 @@ close_archive (void)
     close_warn (*archive_name_cursor);
     close_warn (*archive_name_cursor);
 
 
   sys_wait_for_child (child_pid);
   sys_wait_for_child (child_pid);
-  
+
   tar_stat_destroy (&current_stat_info);
   tar_stat_destroy (&current_stat_info);
   if (save_name)
   if (save_name)
     free (save_name);
     free (save_name);
@@ -957,7 +957,7 @@ closeout_volume_number (void)
    Return nonzero on success.
    Return nonzero on success.
 */
 */
 static bool
 static bool
-new_volume (enum access_mode access)
+new_volume (enum access_mode mode)
 {
 {
   static FILE *read_file;
   static FILE *read_file;
   static int looped;
   static int looped;
@@ -1086,7 +1086,7 @@ new_volume (enum access_mode access)
     archive = rmtopen (*archive_name_cursor, O_RDWR | O_CREAT, MODE_RW,
     archive = rmtopen (*archive_name_cursor, O_RDWR | O_CREAT, MODE_RW,
 		       rsh_command_option);
 		       rsh_command_option);
   else
   else
-    switch (access)
+    switch (mode)
       {
       {
       case ACCESS_READ:
       case ACCESS_READ:
 	archive = rmtopen (*archive_name_cursor, O_RDONLY, MODE_RW,
 	archive = rmtopen (*archive_name_cursor, O_RDONLY, MODE_RW,
@@ -1109,7 +1109,7 @@ new_volume (enum access_mode access)
   if (archive < 0)
   if (archive < 0)
     {
     {
       open_warn (*archive_name_cursor);
       open_warn (*archive_name_cursor);
-      if (!verify_option && access == ACCESS_WRITE && backup_option)
+      if (!verify_option && mode == ACCESS_WRITE && backup_option)
 	undo_last_backup ();
 	undo_last_backup ();
       goto tryagain;
       goto tryagain;
     }
     }

+ 36 - 20
src/common.h

@@ -1,7 +1,7 @@
 /* Common declarations for the tar program.
 /* Common declarations for the tar program.
 
 
    Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
    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
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    under the terms of the GNU General Public License as published by the
@@ -85,6 +85,7 @@ GLOBAL int exit_status;
 #include <modechange.h>
 #include <modechange.h>
 #include <quote.h>
 #include <quote.h>
 #include <safe-read.h>
 #include <safe-read.h>
+#include <timespec.h>
 
 
 /* Log base 2 of common values.  */
 /* Log base 2 of common values.  */
 #define LG_8 3
 #define LG_8 3
@@ -189,7 +190,7 @@ enum old_files
   OVERWRITE_OLD_FILES,        /* --overwrite */
   OVERWRITE_OLD_FILES,        /* --overwrite */
   UNLINK_FIRST_OLD_FILES,     /* --unlink-first */
   UNLINK_FIRST_OLD_FILES,     /* --unlink-first */
   KEEP_OLD_FILES,             /* --keep-old-files */
   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;
 GLOBAL enum old_files old_files_option;
 
 
@@ -201,13 +202,23 @@ GLOBAL struct mode_change *mode_option;
 
 
 GLOBAL bool multi_volume_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.  */
    non-existing option, for making the code clearer, elsewhere.  */
 #define newer_ctime_option newer_mtime_option
 #define newer_ctime_option newer_mtime_option
 
 
 /* Specified threshold date and time.  Files having an older time stamp
 /* Specified threshold date and time.  Files having an older time stamp
    do not get archived (also see after_date_option above).  */
    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.  */
 /* Zero if there is no recursion, otherwise FNM_LEADING_DIR.  */
 GLOBAL int recursion_option;
 GLOBAL int recursion_option;
@@ -367,7 +378,7 @@ enum dump_status
     dump_status_not_implemented
     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 create_archive (void);
 void pad_archive (off_t size_left);
 void pad_archive (off_t size_left);
 void dump_file (char *, int, dev_t);
 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 (char const *);
 void read_error_details (char const *, off_t, size_t);
 void read_error_details (char const *, off_t, size_t);
 void read_fatal (char const *) __attribute__ ((noreturn));
 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_warn_details (char const *, off_t, size_t);
 void read_diag_details (char const *name, off_t offset, size_t size);
 void read_diag_details (char const *name, off_t offset, size_t size);
 void readlink_error (char const *);
 void readlink_error (char const *);
@@ -559,7 +570,7 @@ void unlink_error (char const *);
 void utime_error (char const *);
 void utime_error (char const *);
 void waitpid_error (char const *);
 void waitpid_error (char const *);
 void write_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 (char const *) __attribute__ ((noreturn));
 void write_fatal_details (char const *, ssize_t, size_t)
 void write_fatal_details (char const *, ssize_t, size_t)
      __attribute__ ((noreturn));
      __attribute__ ((noreturn));
@@ -572,13 +583,13 @@ void xpipe (int[2]);
 extern struct name *gnu_list_name;
 extern struct name *gnu_list_name;
 
 
 void gid_to_gname (gid_t, char **gname);
 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);
 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 init_names (void);
 void name_add (const char *);
 void name_add (const char *);
-void name_init (int, char *const *);
+void name_init (void);
 void name_term (void);
 void name_term (void);
 char *name_next (int);
 char *name_next (int);
 void name_close (void);
 void name_close (void);
@@ -609,6 +620,8 @@ bool contains_dot_dot (char const *);
 
 
 /* Module tar.c.  */
 /* Module tar.c.  */
 
 
+void usage (int);
+
 int confirm (const char *, const char *);
 int confirm (const char *, const char *);
 void request_stdin (const char *);
 void request_stdin (const char *);
 
 
@@ -634,11 +647,13 @@ void xheader_finish (struct xheader *);
 void xheader_destroy (struct xheader *);
 void xheader_destroy (struct xheader *);
 char *xheader_xhdr_name (struct tar_stat_info *st);
 char *xheader_xhdr_name (struct tar_stat_info *st);
 char *xheader_ghdr_name (void);
 char *xheader_ghdr_name (void);
+void xheader_write (char, char *, struct xheader *);
+void xheader_write_global (void);
 void xheader_set_option (char *string);
 void xheader_set_option (char *string);
 
 
 /* Module system.c */
 /* 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_detect_dev_null_output (void);
 void sys_save_archive_dev_ino (void);
 void sys_save_archive_dev_ino (void);
 void sys_drain_input_pipe (void);
 void sys_drain_input_pipe (void);
@@ -652,7 +667,8 @@ int sys_truncate (int fd);
 void sys_reset_uid_gid (void);
 void sys_reset_uid_gid (void);
 pid_t sys_child_open_for_compress (void);
 pid_t sys_child_open_for_compress (void);
 pid_t sys_child_open_for_uncompress (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);
 bool sys_get_archive_stat (void);
 void sys_reset_uid_gid (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, ...);
 void report_difference (struct tar_stat_info *st, const char *message, ...);
 
 
 /* Module sparse.c */
 /* 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 */
 /* Module utf8.c */
 bool string_ascii_p (const char *str);
 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);

+ 14 - 13
src/compare.c

@@ -1,7 +1,7 @@
 /* Diff files from a tar archive.
 /* Diff files from a tar archive.
 
 
    Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
    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.
    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,
 /* Sigh about something that differs by writing a MESSAGE to stdlis,
    given MESSAGE is nonzero.  Also set the exit status if not already.  */
    given MESSAGE is nonzero.  Also set the exit status if not already.  */
 void
 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)
   if (fmt)
     {
     {
@@ -74,35 +75,34 @@ report_difference (struct tar_stat_info *st, const char *fmt, ...)
       va_end (ap);
       va_end (ap);
       fprintf (stdlis, "\n");
       fprintf (stdlis, "\n");
     }
     }
-  
+
   if (exit_status == TAREXIT_SUCCESS)
   if (exit_status == TAREXIT_SUCCESS)
     exit_status = TAREXIT_DIFFERS;
     exit_status = TAREXIT_DIFFERS;
 }
 }
 
 
 /* Take a buffer returned by read_and_process and do nothing with it.  */
 /* Take a buffer returned by read_and_process and do nothing with it.  */
 static int
 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;
   return 1;
 }
 }
 
 
 static int
 static int
 process_rawdata (size_t bytes, char *buffer)
 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 != bytes)
     {
     {
-      if (status < 0)
+      if (status == SAFE_READ_ERROR)
 	{
 	{
 	  read_error (current_stat_info.file_name);
 	  read_error (current_stat_info.file_name);
 	  report_difference (&current_stat_info, NULL);
 	  report_difference (&current_stat_info, NULL);
 	}
 	}
       else
       else
 	{
 	{
-	  report_difference (&current_stat_info, 
+	  report_difference (&current_stat_info,
 			     ngettext ("Could only read %lu of %lu byte",
 			     ngettext ("Could only read %lu of %lu byte",
 				       "Could only read %lu of %lu bytes",
 				       "Could only read %lu of %lu bytes",
 				       bytes),
 				       bytes),
@@ -308,19 +308,20 @@ diff_archive (void)
 
 
     case LNKTYPE:
     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;
 	  break;
 	if (!get_stat_data (current_stat_info.link_name, &link_data))
 	if (!get_stat_data (current_stat_info.link_name, &link_data))
 	  break;
 	  break;
-	if (!sys_compare_links (&stat_data, &link_data))
+	if (!sys_compare_links (&file_data, &link_data))
 	  report_difference (&current_stat_info,
 	  report_difference (&current_stat_info,
 			     _("Not linked to %s"),
 			     _("Not linked to %s"),
 			     quote (current_stat_info.link_name));
 			     quote (current_stat_info.link_name));
       }
       }
       break;
       break;
-      
+
 #ifdef HAVE_READLINK
 #ifdef HAVE_READLINK
     case SYMTYPE:
     case SYMTYPE:
       {
       {

+ 152 - 151
src/create.c

@@ -337,11 +337,11 @@ string_to_chars (char *str, char *p, size_t s)
    b) current archive is /dev/null */
    b) current archive is /dev/null */
 
 
 bool
 bool
-file_dumpable_p (struct tar_stat_info *stat)
+file_dumpable_p (struct tar_stat_info *st)
 {
 {
   return !(dev_null_output
   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;
   time_t t;
   union block *header = find_next_block ();
   union block *header = find_next_block ();
-  
+
   memset (header->buffer, 0, sizeof (union block));
   memset (header->buffer, 0, sizeof (union block));
 
 
   tar_copy_str (header->header.name, name, NAME_FIELD_SIZE);
   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
 /* Create a new header and store there at most NAME_FIELD_SIZE bytes of
    the file name */
    the file name */
 
 
-static union block * 
+static union block *
 write_short_name (struct tar_stat_info *st)
 write_short_name (struct tar_stat_info *st)
 {
 {
   union block *header = find_next_block ();
   union block *header = find_next_block ();
@@ -464,7 +464,7 @@ write_ustar_long_name (const char *name)
 	     PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1));
 	     PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1));
       return NULL;
       return NULL;
     }
     }
-  
+
   i = split_long_name (name, length);
   i = split_long_name (name, length);
   if (i == 0 || length - i - 1 > NAME_FIELD_SIZE)
   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));
   memset (header->buffer, 0, sizeof (header->buffer));
   memcpy (header->header.prefix, name, i);
   memcpy (header->header.prefix, name, i);
   memcpy (header->header.name, name + i + 1, length - i - 1);
   memcpy (header->header.name, name + i + 1, length - i - 1);
-  
+
   return header;
   return header;
 }
 }
 
 
@@ -499,7 +499,7 @@ write_long_link (struct tar_stat_info *st)
 	     _("%s: link name is too long; not dumped"),
 	     _("%s: link name is too long; not dumped"),
 	     quotearg_colon (st->link_name)));
 	     quotearg_colon (st->link_name)));
 	    break;
 	    break;
-      
+
     case OLDGNU_FORMAT:
     case OLDGNU_FORMAT:
     case GNU_FORMAT:
     case GNU_FORMAT:
       write_gnu_long_link (st, st->link_name, GNUTYPE_LONGLINK);
       write_gnu_long_link (st, st->link_name, GNUTYPE_LONGLINK);
@@ -528,11 +528,11 @@ write_long_name (struct tar_stat_info *st)
 	  return NULL;
 	  return NULL;
 	}
 	}
       break;
       break;
-      
+
     case USTAR_FORMAT:
     case USTAR_FORMAT:
     case STAR_FORMAT:
     case STAR_FORMAT:
       return write_ustar_long_name (st->file_name);
       return write_ustar_long_name (st->file_name);
-      
+
     case OLDGNU_FORMAT:
     case OLDGNU_FORMAT:
     case GNU_FORMAT:
     case GNU_FORMAT:
       write_gnu_long_link (st, st->file_name, GNUTYPE_LONGNAME);
       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);
   return write_short_name (st);
 }
 }
-		       
+
 static union block *
 static union block *
 write_extended (struct tar_stat_info *st, union block *old_header)
 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;
   char *p;
 
 
   if (extended_header.buffer || extended_header.stk == NULL)
   if (extended_header.buffer || extended_header.stk == NULL)
-    return old_header; 
-  
+    return old_header;
+
   xheader_finish (&extended_header);
   xheader_finish (&extended_header);
   memcpy (hp.buffer, old_header, sizeof (hp));
   memcpy (hp.buffer, old_header, sizeof (hp));
   p = xheader_xhdr_name (st);
   p = xheader_xhdr_name (st);
@@ -563,7 +563,7 @@ write_extended (struct tar_stat_info *st, union block *old_header)
   return header;
   return header;
 }
 }
 
 
-static union block * 
+static union block *
 write_header_name (struct tar_stat_info *st)
 write_header_name (struct tar_stat_info *st)
 {
 {
   if (archive_format == POSIX_FORMAT && !string_ascii_p (st->file_name))
   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);
     xheader_store ("uid", st, NULL);
   else
   else
     UID_TO_CHARS (st->stat.st_uid, header->header.uid);
     UID_TO_CHARS (st->stat.st_uid, header->header.uid);
-  
+
   if (st->stat.st_gid > MAXOCTAL7 && archive_format == POSIX_FORMAT)
   if (st->stat.st_gid > MAXOCTAL7 && archive_format == POSIX_FORMAT)
     xheader_store ("gid", st, NULL);
     xheader_store ("gid", st, NULL);
   else
   else
@@ -669,7 +669,7 @@ start_header (struct tar_stat_info *st)
       MAJOR_TO_CHARS (0, header->header.devmajor);
       MAJOR_TO_CHARS (0, header->header.devmajor);
       MINOR_TO_CHARS (0, header->header.devminor);
       MINOR_TO_CHARS (0, header->header.devminor);
     }
     }
-  
+
   if (archive_format == POSIX_FORMAT)
   if (archive_format == POSIX_FORMAT)
     {
     {
       xheader_store ("atime", st, NULL);
       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);
       uid_to_uname (st->stat.st_uid, &st->uname);
       gid_to_gname (st->stat.st_gid, &st->gname);
       gid_to_gname (st->stat.st_gid, &st->gname);
-      
+
       if (archive_format == POSIX_FORMAT
       if (archive_format == POSIX_FORMAT
 	  && (strlen (st->uname) > UNAME_FIELD_SIZE
 	  && (strlen (st->uname) > UNAME_FIELD_SIZE
 	      || !string_ascii_p (st->uname)))
 	      || !string_ascii_p (st->uname)))
@@ -802,40 +802,40 @@ pad_archive (off_t size_left)
       set_next_block_after (blk);
       set_next_block_after (blk);
       size_left -= BLOCKSIZE;
       size_left -= BLOCKSIZE;
     }
     }
-}  
+}
 
 
 static enum dump_status
 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;
   off_t block_ordinal;
   union block *blk;
   union block *blk;
-  
+
   block_ordinal = current_block_ordinal ();
   block_ordinal = current_block_ordinal ();
-  blk = start_header (stat);
+  blk = start_header (st);
   if (!blk)
   if (!blk)
     return dump_status_fail;
     return dump_status_fail;
 
 
   /* Mark contiguous files, if we support them.  */
   /* 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;
     blk->header.typeflag = CONTTYPE;
 
 
-  finish_header (stat, blk, block_ordinal);
+  finish_header (st, blk, block_ordinal);
 
 
   while (size_left > 0)
   while (size_left > 0)
     {
     {
       size_t bufsize, count;
       size_t bufsize, count;
-      
+
       if (multi_volume_option)
       if (multi_volume_option)
 	{
 	{
-	  assign_string (&save_name, stat->file_name);
+	  assign_string (&save_name, st->file_name);
 	  save_sizeleft = size_left;
 	  save_sizeleft = size_left;
-	  save_totsize = stat->stat.st_size;
+	  save_totsize = st->stat.st_size;
 	}
 	}
       blk = find_next_block ();
       blk = find_next_block ();
-      
+
       bufsize = available_space_after (blk);
       bufsize = available_space_after (blk);
-      
+
       if (size_left < bufsize)
       if (size_left < bufsize)
 	{
 	{
 	  /* Last read -- zero out area beyond.  */
 	  /* Last read -- zero out area beyond.  */
@@ -844,12 +844,12 @@ dump_regular_file (int fd, struct tar_stat_info *stat)
 	  if (count)
 	  if (count)
 	    memset (blk->buffer + size_left, 0, BLOCKSIZE - count);
 	    memset (blk->buffer + size_left, 0, BLOCKSIZE - count);
 	}
 	}
-      
+
       count = (fd < 0) ? bufsize : safe_read (fd, blk->buffer, bufsize);
       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);
 	  pad_archive (size_left);
 	  return dump_status_short;
 	  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",
 		 ngettext ("%s: File shrank by %s byte; padding with zeros",
 			   "%s: File shrank by %s bytes; padding with zeros",
 			   "%s: File shrank by %s bytes; padding with zeros",
 			   size_left),
 			   size_left),
-		 quotearg_colon (stat->orig_file_name),
+		 quotearg_colon (st->orig_file_name),
 		 STRINGIFY_BIGINT (size_left, buf)));
 		 STRINGIFY_BIGINT (size_left, buf)));
 	  if (! ignore_failed_read_option)
 	  if (! ignore_failed_read_option)
 	    exit_status = TAREXIT_FAILURE;
 	    exit_status = TAREXIT_FAILURE;
@@ -876,7 +876,7 @@ dump_regular_file (int fd, struct tar_stat_info *stat)
   return dump_status_ok;
   return dump_status_ok;
 }
 }
 
 
-void
+static void
 dump_regular_finish (int fd, struct tar_stat_info *st, time_t original_ctime)
 dump_regular_finish (int fd, struct tar_stat_info *st, time_t original_ctime)
 {
 {
   if (fd >= 0)
   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,
 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;
       union block *blk = NULL;
       off_t block_ordinal = current_block_ordinal ();
       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)
       if (!blk)
 	return;
 	return;
-	  
+
       if (incremental_option)
       if (incremental_option)
 	blk->header.typeflag = GNUTYPE_DUMPDIR;
 	blk->header.typeflag = GNUTYPE_DUMPDIR;
       else /* if (standard_option) */
       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 we're gnudumping, we aren't done yet so don't close it.  */
 
 
       if (!incremental_option)
       if (!incremental_option)
-	finish_header (stat, blk, block_ordinal);
+	finish_header (st, blk, block_ordinal);
       else if (gnu_list_name->dir_contents)
       else if (gnu_list_name->dir_contents)
 	{
 	{
 	  off_t size_left;
 	  off_t size_left;
@@ -935,8 +935,8 @@ dump_dir0 (char *directory,
 	  size_t bufsize;
 	  size_t bufsize;
 	  ssize_t count;
 	  ssize_t count;
 	  const char *buffer, *p_buffer;
 	  const char *buffer, *p_buffer;
-	  off_t block_ordinal = current_block_ordinal ();
-	  
+
+	  block_ordinal = current_block_ordinal ();
 	  buffer = gnu_list_name->dir_contents; /* FOO */
 	  buffer = gnu_list_name->dir_contents; /* FOO */
 	  totsize = 0;
 	  totsize = 0;
 	  if (buffer)
 	  if (buffer)
@@ -948,14 +948,14 @@ dump_dir0 (char *directory,
 	      }
 	      }
 	  totsize++;
 	  totsize++;
 	  OFF_TO_CHARS (totsize, blk->header.size);
 	  OFF_TO_CHARS (totsize, blk->header.size);
-	  finish_header (stat, blk, block_ordinal); 
+	  finish_header (st, blk, block_ordinal);
 	  p_buffer = buffer;
 	  p_buffer = buffer;
 	  size_left = totsize;
 	  size_left = totsize;
 	  while (size_left > 0)
 	  while (size_left > 0)
 	    {
 	    {
 	      if (multi_volume_option)
 	      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_sizeleft = size_left;
 		  save_totsize = totsize;
 		  save_totsize = totsize;
 		}
 		}
@@ -984,25 +984,25 @@ dump_dir0 (char *directory,
 
 
   if (one_file_system_option
   if (one_file_system_option
       && !top_level
       && !top_level
-      && parent_device != stat->stat.st_dev)
+      && parent_device != st->stat.st_dev)
     {
     {
       if (verbose_option)
       if (verbose_option)
 	WARN ((0, 0,
 	WARN ((0, 0,
 	       _("%s: file is on a different filesystem; not dumped"),
 	       _("%s: file is on a different filesystem; not dumped"),
-	       quotearg_colon (stat->orig_file_name)));
+	       quotearg_colon (st->orig_file_name)));
       return;
       return;
     }
     }
 
 
   {
   {
     char const *entry;
     char const *entry;
     size_t entry_len;
     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_size = strlen (name_buf);
     size_t name_len = name_size;
     size_t name_len = name_size;
-    
+
     /* Now output all the files in the directory.  */
     /* Now output all the files in the directory.  */
     /* FIXME: Should speed this up by cd-ing into the dir.  */
     /* FIXME: Should speed this up by cd-ing into the dir.  */
-    
+
     for (entry = directory; (entry_len = strlen (entry)) != 0;
     for (entry = directory; (entry_len = strlen (entry)) != 0;
 	 entry += entry_len + 1)
 	 entry += entry_len + 1)
       {
       {
@@ -1015,7 +1015,7 @@ dump_dir0 (char *directory,
 	if (!excluded_name (name_buf))
 	if (!excluded_name (name_buf))
 	  dump_file (name_buf, 0, our_device);
 	  dump_file (name_buf, 0, our_device);
       }
       }
-    
+
     free (name_buf);
     free (name_buf);
   }
   }
 }
 }
@@ -1033,22 +1033,22 @@ ensure_slash (char **pstr)
   (*pstr)[len] = '\0';
   (*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;
   char *directory;
 
 
-  directory = savedir (stat->orig_file_name);
+  directory = savedir (st->orig_file_name);
   if (!directory)
   if (!directory)
     {
     {
-      savedir_diag (stat->orig_file_name);
+      savedir_diag (st->orig_file_name);
       return false;
       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);
   free (directory);
   return true;
   return true;
@@ -1064,7 +1064,7 @@ create_archive (void)
 
 
   open_archive (ACCESS_WRITE);
   open_archive (ACCESS_WRITE);
   xheader_write_global ();
   xheader_write_global ();
-  
+
   if (incremental_option)
   if (incremental_option)
     {
     {
       size_t buffer_size = 1000;
       size_t buffer_size = 1000;
@@ -1131,8 +1131,9 @@ create_archive (void)
 static unsigned
 static unsigned
 hash_link (void const *entry, unsigned n_buckets)
 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.  */
 /* 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
 /* Try to dump stat as a hard link to another file in the archive. If
    succeeded returns true */
    succeeded returns true */
 static bool
 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 lp;
-      struct link *dup;
+      struct link *duplicate;
       off_t block_ordinal;
       off_t block_ordinal;
       union block *blk;
       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.  */
 	  /* 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 ();
 	  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))
 	  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)
 	  if (!blk)
 	    return true;
 	    return true;
 	  tar_copy_str (blk->header.linkname, link_name, NAME_FIELD_SIZE);
 	  tar_copy_str (blk->header.linkname, link_name, NAME_FIELD_SIZE);
 
 
 	  blk->header.typeflag = LNKTYPE;
 	  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;
 	  return true;
 	}
 	}
@@ -1207,25 +1208,25 @@ dump_hard_link (struct tar_stat_info *stat)
 }
 }
 
 
 static void
 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)
       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
       if (! ((link_table
 	      || (link_table = hash_initialize (0, 0, hash_link,
 	      || (link_table = hash_initialize (0, 0, hash_link,
 						compare_links, 0)))
 						compare_links, 0)))
-	     && (dup = hash_insert (link_table, lp))))
+	     && (duplicate = hash_insert (link_table, lp))))
 	xalloc_die ();
 	xalloc_die ();
 
 
-      if (dup != lp)
+      if (duplicate != lp)
 	abort ();
 	abort ();
       lp->nlink--;
       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
 /* For each dumped file, check if all its links were dumped. Emit
    warnings if it is not so. */
    warnings if it is not so. */
 void
 void
-check_links ()
+check_links (void)
 {
 {
   struct link *lp;
   struct link *lp;
 
 
@@ -1261,8 +1262,8 @@ check_links ()
 /* FIXME: One should make sure that for *every* path leading to setting
 /* FIXME: One should make sure that for *every* path leading to setting
    exit_status to failure, a clear diagnostic has been issued.  */
    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)
 	    int top_level, dev_t parent_device)
 {
 {
   union block *header;
   union block *header;
@@ -1270,26 +1271,26 @@ dump_file0 (struct tar_stat_info *stat, char *p,
   time_t original_ctime;
   time_t original_ctime;
   struct utimbuf restore_times;
   struct utimbuf restore_times;
   off_t block_ordinal = -1;
   off_t block_ordinal = -1;
-  
+
   if (interactive_option && !confirm ("add", p))
   if (interactive_option && !confirm ("add", p))
     return;
     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);
       stat_diag (p);
       return;
       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
 #ifdef S_ISHIDDEN
-  if (S_ISHIDDEN (stat->stat.st_mode))
+  if (S_ISHIDDEN (st->stat.st_mode))
     {
     {
       char *new = (char *) alloca (strlen (p) + 2);
       char *new = (char *) alloca (strlen (p) + 2);
       if (new)
       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
   /* See if we want only new files, and check if this one is too old to
      put in the archive.  */
      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 */
       if (0 < top_level) /* equivalent to !incremental_option */
 	WARN ((0, 0, _("%s: file is unchanged; not dumped"),
 	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.  */
   /* 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"),
       WARN ((0, 0, _("%s: file is the archive; not dumped"),
 	     quotearg_colon (p)));
 	     quotearg_colon (p)));
       return;
       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)
       if (atime_preserve_option)
 	utime (p, &restore_times);
 	utime (p, &restore_times);
       return;
       return;
@@ -1335,49 +1336,49 @@ dump_file0 (struct tar_stat_info *stat, char *p,
   else
   else
     {
     {
       /* Check for multiple links.  */
       /* Check for multiple links.  */
-      if (dump_hard_link (stat))
+      if (dump_hard_link (st))
 	return;
 	return;
-      
+
       /* This is not a link to a previously dumped file, so dump it.  */
       /* 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;
 	  int fd;
 	  enum dump_status status;
 	  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);
 			 O_RDONLY | O_BINARY);
 	      if (fd < 0)
 	      if (fd < 0)
 		{
 		{
 		  if (!top_level && errno == ENOENT)
 		  if (!top_level && errno == ENOENT)
 		    WARN ((0, 0, _("%s: File removed before we read it"),
 		    WARN ((0, 0, _("%s: File removed before we read it"),
-			   quotearg_colon (stat->orig_file_name)));
+			   quotearg_colon (st->orig_file_name)));
 		  else
 		  else
-		    open_diag (stat->orig_file_name);
+		    open_diag (st->orig_file_name);
 		  return;
 		  return;
 		}
 		}
 	    }
 	    }
 	  else
 	  else
 	    fd = -1;
 	    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)
 	      if (status == dump_status_not_implemented)
-		status = dump_regular_file (fd, stat);
+		status = dump_regular_file (fd, st);
 	    }
 	    }
 	  else
 	  else
-	    status = dump_regular_file (fd, stat);
+	    status = dump_regular_file (fd, st);
 
 
 	  switch (status)
 	  switch (status)
 	    {
 	    {
 	    case dump_status_ok:
 	    case dump_status_ok:
 	      if (multi_volume_option)
 	      if (multi_volume_option)
 		assign_string (&save_name, 0);
 		assign_string (&save_name, 0);
-	      dump_regular_finish (fd, stat, original_ctime);
+	      dump_regular_finish (fd, st, original_ctime);
 	      break;
 	      break;
 
 
 	    case dump_status_short:
 	    case dump_status_short:
@@ -1385,7 +1386,7 @@ dump_file0 (struct tar_stat_info *stat, char *p,
 		assign_string (&save_name, 0);
 		assign_string (&save_name, 0);
 	      close (fd);
 	      close (fd);
 	      break;
 	      break;
-      
+
 	    case dump_status_fail:
 	    case dump_status_fail:
 	      close (fd);
 	      close (fd);
 	      return;
 	      return;
@@ -1395,17 +1396,17 @@ dump_file0 (struct tar_stat_info *stat, char *p,
 	    }
 	    }
 
 
 	  if (atime_preserve_option)
 	  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;
 	  return;
 	}
 	}
 #ifdef HAVE_READLINK
 #ifdef HAVE_READLINK
-      else if (S_ISLNK (stat->stat.st_mode))
+      else if (S_ISLNK (st->stat.st_mode))
 	{
 	{
 	  char *buffer;
 	  char *buffer;
 	  int size;
 	  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 ();
 	    xalloc_die ();
 	  buffer = (char *) alloca (linklen + 1);
 	  buffer = (char *) alloca (linklen + 1);
 	  size = readlink (p, buffer, linklen + 1);
 	  size = readlink (p, buffer, linklen + 1);
@@ -1415,18 +1416,18 @@ dump_file0 (struct tar_stat_info *stat, char *p,
 	      return;
 	      return;
 	    }
 	    }
 	  buffer[size] = '\0';
 	  buffer[size] = '\0';
-	  assign_string (&stat->link_name, buffer);
+	  assign_string (&st->link_name, buffer);
 	  if (size > NAME_FIELD_SIZE)
 	  if (size > NAME_FIELD_SIZE)
-	    write_long_link (stat);
+	    write_long_link (st);
 
 
 	  block_ordinal = current_block_ordinal ();
 	  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)
 	  if (!header)
 	    return;
 	    return;
 	  tar_copy_str (header->header.linkname, buffer, NAME_FIELD_SIZE);
 	  tar_copy_str (header->header.linkname, buffer, NAME_FIELD_SIZE);
 	  header->header.typeflag = SYMTYPE;
 	  header->header.typeflag = SYMTYPE;
-	  finish_header (stat, header, block_ordinal);
+	  finish_header (st, header, block_ordinal);
 	  /* nothing more to do to it */
 	  /* nothing more to do to it */
 
 
 	  if (remove_files_option)
 	  if (remove_files_option)
@@ -1434,22 +1435,22 @@ dump_file0 (struct tar_stat_info *stat, char *p,
 	      if (unlink (p) == -1)
 	      if (unlink (p) == -1)
 		unlink_error (p);
 		unlink_error (p);
 	    }
 	    }
-	  file_count_links (stat);
+	  file_count_links (st);
 	  return;
 	  return;
 	}
 	}
 #endif
 #endif
-      else if (S_ISCHR (stat->stat.st_mode))
+      else if (S_ISCHR (st->stat.st_mode))
 	type = CHRTYPE;
 	type = CHRTYPE;
-      else if (S_ISBLK (stat->stat.st_mode))
+      else if (S_ISBLK (st->stat.st_mode))
 	type = BLKTYPE;
 	type = BLKTYPE;
-      else if (S_ISFIFO (stat->stat.st_mode))
+      else if (S_ISFIFO (st->stat.st_mode))
 	type = FIFOTYPE;
 	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)));
 	  WARN ((0, 0, _("%s: socket ignored"), quotearg_colon (p)));
 	  return;
 	  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)));
 	  WARN ((0, 0, _("%s: door ignored"), quotearg_colon (p)));
 	  return;
 	  return;
@@ -1468,21 +1469,21 @@ dump_file0 (struct tar_stat_info *stat, char *p,
     }
     }
 
 
   block_ordinal = current_block_ordinal ();
   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)
   if (!header)
     return;
     return;
   header->header.typeflag = type;
   header->header.typeflag = type;
 
 
   if (type != FIFOTYPE)
   if (type != FIFOTYPE)
     {
     {
-      MAJOR_TO_CHARS (major (stat->stat.st_rdev),
+      MAJOR_TO_CHARS (major (st->stat.st_rdev),
 		      header->header.devmajor);
 		      header->header.devmajor);
-      MINOR_TO_CHARS (minor (stat->stat.st_rdev),
+      MINOR_TO_CHARS (minor (st->stat.st_rdev),
 		      header->header.devminor);
 		      header->header.devminor);
     }
     }
 
 
-  finish_header (stat, header, block_ordinal);
+  finish_header (st, header, block_ordinal);
   if (remove_files_option)
   if (remove_files_option)
     {
     {
       if (unlink (p) == -1)
       if (unlink (p) == -1)
@@ -1493,8 +1494,8 @@ dump_file0 (struct tar_stat_info *stat, char *p,
 void
 void
 dump_file (char *p, int top_level, dev_t parent_device)
 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);
 }
 }

+ 23 - 23
src/extract.c

@@ -1,7 +1,7 @@
 /* Extract files from a tar archive.
 /* Extract files from a tar archive.
 
 
    Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000,
    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.
    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
 /* 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
    out to be the same as this directory, e.g. due to ".." or symbolic
    links.  *DIR_STAT_INFO is the status of the directory.  */
    links.  *DIR_STAT_INFO is the status of the directory.  */
 static void
 static void
-repair_delayed_set_stat (char const *dir_name,
+repair_delayed_set_stat (char const *dir,
 			 struct stat const *dir_stat_info)
 			 struct stat const *dir_stat_info)
 {
 {
   struct delayed_set_stat *data;
   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"),
   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
 /* After a file/link/symlink/directory creation has failed, see if
@@ -361,7 +361,7 @@ make_directories (char *file_name)
   int invert_permissions;
   int invert_permissions;
   int status;
   int status;
 
 
-  
+
   for (cursor = cursor0; *cursor; cursor++)
   for (cursor = cursor0; *cursor; cursor++)
     {
     {
       if (! ISSLASH (*cursor))
       if (! ISSLASH (*cursor))
@@ -423,25 +423,25 @@ static bool
 file_newer_p (const char *file_name, struct tar_stat_info *tar_stat)
 file_newer_p (const char *file_name, struct tar_stat_info *tar_stat)
 {
 {
   struct stat st;
   struct stat st;
-	    
+
   if (stat (file_name, &st))
   if (stat (file_name, &st))
     {
     {
       stat_warn (file_name);
       stat_warn (file_name);
       return true; /* Be on the safe side */
       return true; /* Be on the safe side */
     }
     }
   if (!S_ISDIR (st.st_mode)
   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 true;
     }
     }
   return false;
   return false;
-}  
+}
 
 
 /* Prepare to extract a file.
 /* Prepare to extract a file.
    Return zero if extraction should not proceed.  */
    Return zero if extraction should not proceed.  */
 
 
 static int
 static int
-prepare_to_extract (char const *file_name, bool directory)
+prepare_to_extract (char const *file_name)
 {
 {
   if (to_stdout_option)
   if (to_stdout_option)
     return 0;
     return 0;
@@ -460,7 +460,7 @@ prepare_to_extract (char const *file_name, bool directory)
     case KEEP_NEWER_FILES:
     case KEEP_NEWER_FILES:
       if (file_newer_p (file_name, &current_stat_info))
       if (file_newer_p (file_name, &current_stat_info))
 	{
 	{
-	  WARN ((0, 0, _("Current `%s' is newer"), file_name)); 
+	  WARN ((0, 0, _("Current `%s' is newer"), file_name));
 	  return 0;
 	  return 0;
 	}
 	}
       break;
       break;
@@ -480,7 +480,7 @@ static int
 maybe_recoverable (char *file_name, int *interdir_made)
 maybe_recoverable (char *file_name, int *interdir_made)
 {
 {
   int e = errno;
   int e = errno;
-  
+
   if (*interdir_made)
   if (*interdir_made)
     return 0;
     return 0;
 
 
@@ -501,7 +501,7 @@ maybe_recoverable (char *file_name, int *interdir_made)
 	      return 0;
 	      return 0;
 	    }
 	    }
 	  /* FALL THROUGH */
 	  /* FALL THROUGH */
-	    
+
 	case DEFAULT_OLD_FILES:
 	case DEFAULT_OLD_FILES:
 	case NO_OVERWRITE_DIR_OLD_FILES:
 	case NO_OVERWRITE_DIR_OLD_FILES:
 	case OVERWRITE_OLD_FILES:
 	case OVERWRITE_OLD_FILES:
@@ -628,7 +628,7 @@ extract_archive (void)
 	}
 	}
       file_name += prefix_len;
       file_name += prefix_len;
     }
     }
-  
+
   apply_nonancestor_delayed_set_stat (file_name, 0);
   apply_nonancestor_delayed_set_stat (file_name, 0);
 
 
   /* Take a safety backup of a previously existing file.  */
   /* Take a safety backup of a previously existing file.  */
@@ -648,7 +648,7 @@ extract_archive (void)
   /* KLUDGE */
   /* KLUDGE */
   typeflag = sparse_member_p (&current_stat_info) ?
   typeflag = sparse_member_p (&current_stat_info) ?
                   GNUTYPE_SPARSE : current_header->header.typeflag;
                   GNUTYPE_SPARSE : current_header->header.typeflag;
-  
+
   switch (typeflag)
   switch (typeflag)
     {
     {
     case GNUTYPE_SPARSE:
     case GNUTYPE_SPARSE:
@@ -679,7 +679,7 @@ extract_archive (void)
 	  goto extract_file;
 	  goto extract_file;
 	}
 	}
 
 
-      if (! prepare_to_extract (file_name, 0))
+      if (! prepare_to_extract (file_name))
 	{
 	{
 	  skip_member ();
 	  skip_member ();
 	  if (backup_option)
 	  if (backup_option)
@@ -794,7 +794,7 @@ extract_archive (void)
 
 
     case SYMTYPE:
     case SYMTYPE:
 #ifdef HAVE_SYMLINK
 #ifdef HAVE_SYMLINK
-      if (! prepare_to_extract (file_name, 0))
+      if (! prepare_to_extract (file_name))
 	break;
 	break;
 
 
       if (absolute_names_option
       if (absolute_names_option
@@ -878,7 +878,7 @@ extract_archive (void)
 	      status = 0;
 	      status = 0;
 	    }
 	    }
 	}
 	}
-  
+
       if (status != 0 && backup_option)
       if (status != 0 && backup_option)
 	undo_last_backup ();
 	undo_last_backup ();
       break;
       break;
@@ -899,7 +899,7 @@ extract_archive (void)
 #endif
 #endif
 
 
     case LNKTYPE:
     case LNKTYPE:
-      if (! prepare_to_extract (file_name, 0))
+      if (! prepare_to_extract (file_name))
 	break;
 	break;
 
 
     again_link:
     again_link:
@@ -922,7 +922,7 @@ extract_archive (void)
 		    && ds->ino == st1.st_ino
 		    && ds->ino == st1.st_ino
 		    && ds->mtime == st1.st_mtime)
 		    && ds->mtime == st1.st_mtime)
 		  {
 		  {
-		    struct string_list *p = 
+		    struct string_list *p =
 		      xmalloc (offsetof (struct string_list, string)
 		      xmalloc (offsetof (struct string_list, string)
 			       + strlen (file_name) + 1);
 			       + strlen (file_name) + 1);
 		    strcpy (p->string, file_name);
 		    strcpy (p->string, file_name);
@@ -963,7 +963,7 @@ extract_archive (void)
 
 
 #if S_IFCHR || S_IFBLK
 #if S_IFCHR || S_IFBLK
     make_node:
     make_node:
-      if (! prepare_to_extract (file_name, 0))
+      if (! prepare_to_extract (file_name))
 	break;
 	break;
 
 
       status = mknod (file_name, current_stat_info.stat.st_mode,
       status = mknod (file_name, current_stat_info.stat.st_mode,
@@ -984,7 +984,7 @@ extract_archive (void)
 
 
 #if HAVE_MKFIFO || defined mkfifo
 #if HAVE_MKFIFO || defined mkfifo
     case FIFOTYPE:
     case FIFOTYPE:
-      if (! prepare_to_extract (file_name, 0))
+      if (! prepare_to_extract (file_name))
 	break;
 	break;
 
 
       while (status = mkfifo (file_name, current_stat_info.stat.st_mode),
       while (status = mkfifo (file_name, current_stat_info.stat.st_mode),
@@ -1021,7 +1021,7 @@ extract_archive (void)
 	       | (we_are_root ? 0 : MODE_WXUSR))
 	       | (we_are_root ? 0 : MODE_WXUSR))
 	      & MODE_RWX);
 	      & MODE_RWX);
 
 
-      status = prepare_to_extract (file_name, 1);
+      status = prepare_to_extract (file_name);
       if (status == 0)
       if (status == 0)
 	break;
 	break;
       if (status < 0)
       if (status < 0)
@@ -1053,7 +1053,7 @@ extract_archive (void)
 		}
 		}
 	      errno = EEXIST;
 	      errno = EEXIST;
 	    }
 	    }
-	
+
 	  if (maybe_recoverable (file_name, &interdir_made))
 	  if (maybe_recoverable (file_name, &interdir_made))
 	    goto again_dir;
 	    goto again_dir;
 
 

+ 22 - 20
src/incremen.c

@@ -145,7 +145,7 @@ scan_path (struct obstack *stk, char *path, dev_t device)
 
 
   directory = find_directory (path);
   directory = find_directory (path);
   children = directory ? directory->children : CHANGED_CHILDREN;
   children = directory ? directory->children : CHANGED_CHILDREN;
-  
+
   if (dirp && children != NO_CHILDREN)
   if (dirp && children != NO_CHILDREN)
     for (entry = dirp;
     for (entry = dirp;
 	 (entrylen = strlen (entry)) != 0;
 	 (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);
 	    name_buffer = xrealloc (name_buffer, name_buffer_size + 2);
 	  }
 	  }
 	strcpy (name_buffer + name_length, entry);
 	strcpy (name_buffer + name_length, entry);
-	
+
 	if (excluded_name (name_buffer))
 	if (excluded_name (name_buffer))
 	  obstack_1grow (stk, 'N');
 	  obstack_1grow (stk, 'N');
 	else
 	else
 	  {
 	  {
 	    struct stat stat_data;
 	    struct stat stat_data;
-	    
+
 	    if (deref_stat (dereference_option, name_buffer, &stat_data))
 	    if (deref_stat (dereference_option, name_buffer, &stat_data))
 	      {
 	      {
 		stat_diag (name_buffer);
 		stat_diag (name_buffer);
 		continue;
 		continue;
 	      }
 	      }
-	    
+
 	    if (S_ISDIR (stat_data.st_mode))
 	    if (S_ISDIR (stat_data.st_mode))
 	      {
 	      {
 		bool nfs = NFS_FILE_STAT (stat_data);
 		bool nfs = NFS_FILE_STAT (stat_data);
-		
+
 		if ((directory = find_directory (name_buffer)) != NULL)
 		if ((directory = find_directory (name_buffer)) != NULL)
 		  {
 		  {
 		    /* With NFS, the same file can have two different devices
 		    /* 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
 		       To avoid spurious incremental redumping of
 		       directories, consider all NFS devices as equal,
 		       directories, consider all NFS devices as equal,
 		       relying on the i-node to establish differences.  */
 		       relying on the i-node to establish differences.  */
-		    
+
 		    if (! (((directory->nfs & nfs)
 		    if (! (((directory->nfs & nfs)
 			    || directory->device_number == stat_data.st_dev)
 			    || directory->device_number == stat_data.st_dev)
 			   && directory->inode_number == stat_data.st_ino))
 			   && 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);
 						stat_data.st_ino, nfs, 1);
 		    directory->children =
 		    directory->children =
 		      ((listed_incremental_option
 		      ((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
 		       ? ALL_CHILDREN
 		       : CHANGED_CHILDREN);
 		       : CHANGED_CHILDREN);
 		  }
 		  }
-		
+
 		if (one_file_system_option && device != stat_data.st_dev)
 		if (one_file_system_option && device != stat_data.st_dev)
 		  directory->children = NO_CHILDREN;
 		  directory->children = NO_CHILDREN;
 		else if (children == ALL_CHILDREN)
 		else if (children == ALL_CHILDREN)
@@ -239,19 +239,18 @@ scan_path (struct obstack *stk, char *path, dev_t device)
 
 
 	    else
 	    else
 	      if (children == CHANGED_CHILDREN
 	      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');
 		obstack_1grow (stk, 'N');
 	      else
 	      else
 		obstack_1grow (stk, 'Y');
 		obstack_1grow (stk, 'Y');
 	  }
 	  }
-	
+
 	obstack_grow (stk, entry, entrylen + 1);
 	obstack_grow (stk, entry, entrylen + 1);
       }
       }
 
 
   obstack_grow (stk, "\000\000", 2);
   obstack_grow (stk, "\000\000", 2);
-  
+
   free (name_buffer);
   free (name_buffer);
   if (dirp)
   if (dirp)
     free (dirp);
     free (dirp);
@@ -267,16 +266,16 @@ sort_obstack (struct obstack *stk)
   char *buffer;
   char *buffer;
   char **array;
   char **array;
   char **array_cursor;
   char **array_cursor;
-  
+
   counter = 0;
   counter = 0;
   for (cursor = pointer; *cursor; cursor += strlen (cursor) + 1)
   for (cursor = pointer; *cursor; cursor += strlen (cursor) + 1)
     counter++;
     counter++;
-  
+
   if (!counter)
   if (!counter)
     return NULL;
     return NULL;
 
 
   array = obstack_alloc (stk, sizeof (char *) * (counter + 1));
   array = obstack_alloc (stk, sizeof (char *) * (counter + 1));
-  
+
   array_cursor = array;
   array_cursor = array;
   for (cursor = pointer; *cursor; cursor += strlen (cursor) + 1)
   for (cursor = pointer; *cursor; cursor += strlen (cursor) + 1)
     *array_cursor++ = cursor;
     *array_cursor++ = cursor;
@@ -290,7 +289,7 @@ sort_obstack (struct obstack *stk)
   for (array_cursor = array; *array_cursor; array_cursor++)
   for (array_cursor = array; *array_cursor; array_cursor++)
     {
     {
       char *string = *array_cursor;
       char *string = *array_cursor;
-      
+
       while ((*cursor++ = *string++))
       while ((*cursor++ = *string++))
 	continue;
 	continue;
     }
     }
@@ -357,7 +356,10 @@ read_directory_file (void)
 	ERROR ((0, 0, "%s:1: %s", quotearg_colon (listed_incremental_option),
 	ERROR ((0, 0, "%s:1: %s", quotearg_colon (listed_incremental_option),
 		_("Time stamp out of range")));
 		_("Time stamp out of range")));
       else
       else
-	newer_mtime_option = t;
+	{
+	  newer_mtime_option.tv_sec = t;
+	  newer_mtime_option.tv_nsec = 0;
+	}
 
 
       while (0 < (n = getline (&buf, &bufsize, fp)))
       while (0 < (n = getline (&buf, &bufsize, fp)))
 	{
 	{

+ 19 - 14
src/list.c

@@ -1,7 +1,7 @@
 /* List a tar archive, with support routines for reading a tar archive.
 /* List a tar archive, with support routines for reading a tar archive.
 
 
    Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000,
    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.
    Written by John Gilmore, on 1985-08-26.
 
 
@@ -20,7 +20,7 @@
    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 
 /* Define to non-zero for forcing old ctime format instead of ISO format.  */
 /* 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 "system.h"
 #include <quotearg.h>
 #include <quotearg.h>
@@ -78,7 +78,7 @@ read_and (void (*do_something) (void))
       prev_status = status;
       prev_status = status;
       tar_stat_destroy (&current_stat_info);
       tar_stat_destroy (&current_stat_info);
       xheader_destroy (&extended_header);
       xheader_destroy (&extended_header);
-      
+
       status = read_header (false);
       status = read_header (false);
       switch (status)
       switch (status)
 	{
 	{
@@ -92,12 +92,17 @@ read_and (void (*do_something) (void))
 	     Ensure incoming names are null terminated.  */
 	     Ensure incoming names are null terminated.  */
 
 
 	  if (! name_match (current_stat_info.file_name)
 	  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
 		  /* FIXME: We get mtime now, and again later; this causes
 		     duplicate diagnostics if header.mtime is bogus.  */
 		     duplicate diagnostics if header.mtime is bogus.  */
 		  && ((current_stat_info.stat.st_mtime
 		  && ((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))
 	      || excluded_name (current_stat_info.file_name))
 	    {
 	    {
 	      switch (current_header->header.typeflag)
 	      switch (current_header->header.typeflag)
@@ -356,7 +361,7 @@ read_header (bool raw_extended_headers)
 		xalloc_die ();
 		xalloc_die ();
 
 
 	      header_copy = xmalloc (size + 1);
 	      header_copy = xmalloc (size + 1);
-	      
+
 	      if (header->header.typeflag == GNUTYPE_LONGNAME)
 	      if (header->header.typeflag == GNUTYPE_LONGNAME)
 		{
 		{
 		  if (next_long_name)
 		  if (next_long_name)
@@ -371,7 +376,7 @@ read_header (bool raw_extended_headers)
 		  next_long_link = header_copy;
 		  next_long_link = header_copy;
 		  next_long_link_blocks = size / BLOCKSIZE;
 		  next_long_link_blocks = size / BLOCKSIZE;
 		}
 		}
-	      
+
 	      set_next_block_after (header);
 	      set_next_block_after (header);
 	      *header_copy = *header;
 	      *header_copy = *header;
 	      bp = header_copy->buffer + BLOCKSIZE;
 	      bp = header_copy->buffer + BLOCKSIZE;
@@ -387,7 +392,7 @@ read_header (bool raw_extended_headers)
 		  written = available_space_after (data_block);
 		  written = available_space_after (data_block);
 		  if (written > size)
 		  if (written > size)
 		    written = size;
 		    written = size;
-		  
+
 		  memcpy (bp, data_block->buffer, written);
 		  memcpy (bp, data_block->buffer, written);
 		  bp += written;
 		  bp += written;
 		  set_next_block_after ((union block *)
 		  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_read (header, OFF_FROM_HEADER (header->header.size));
 	      xheader_decode_global ();
 	      xheader_decode_global ();
 	    }
 	    }
-      
+
 	  /* Loop!  */
 	  /* Loop!  */
 
 
 	}
 	}
@@ -520,7 +525,7 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
   assign_string (&stat_info->gname, header->header.gname);
   assign_string (&stat_info->gname, header->header.gname);
   stat_info->devmajor = MAJOR_FROM_HEADER (header->header.devmajor);
   stat_info->devmajor = MAJOR_FROM_HEADER (header->header.devmajor);
   stat_info->devminor = MINOR_FROM_HEADER (header->header.devminor);
   stat_info->devminor = MINOR_FROM_HEADER (header->header.devminor);
-  
+
   stat_info->stat.st_atime = start_time;
   stat_info->stat.st_atime = start_time;
   stat_info->stat.st_ctime = 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))
 	      || !gname_to_gid (header->header.gname, &stat_info->stat.st_gid))
 	    stat_info->stat.st_gid = GID_FROM_HEADER (header->header.gid);
 	    stat_info->stat.st_gid = GID_FROM_HEADER (header->header.gid);
 	}
 	}
-      
+
       switch (header->header.typeflag)
       switch (header->header.typeflag)
 	{
 	{
 	case BLKTYPE:
 	case BLKTYPE:
@@ -961,7 +966,7 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
   char modes[11];
   char modes[11];
   char const *time_stamp;
   char const *time_stamp;
   char *temp_name = st->orig_file_name ? st->orig_file_name : st->file_name;
   char *temp_name = st->orig_file_name ? st->orig_file_name : st->file_name;
-  
+
   /* These hold formatted ints.  */
   /* These hold formatted ints.  */
   char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND];
   char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND];
   char *user, *group;
   char *user, *group;
@@ -1108,7 +1113,7 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
 	  strcat (size,
 	  strcat (size,
 		  STRINGIFY_BIGINT (minor (st->stat.st_rdev), uintbuf));
 		  STRINGIFY_BIGINT (minor (st->stat.st_rdev), uintbuf));
 	  break;
 	  break;
-	  
+
 	default:
 	default:
 	  /* st->stat.st_size keeps stored file size */
 	  /* st->stat.st_size keeps stored file size */
 	  strcpy (size, STRINGIFY_BIGINT (st->stat.st_size, uintbuf));
 	  strcpy (size, STRINGIFY_BIGINT (st->stat.st_size, uintbuf));

+ 12 - 16
src/misc.c

@@ -1,7 +1,7 @@
 /* Miscellaneous functions, not really specific to GNU tar.
 /* Miscellaneous functions, not really specific to GNU tar.
 
 
    Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2001,
    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
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    under the terms of the GNU General Public License as published by the
@@ -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.
 /* Check if PATH already exists and make a backup of it right now.
    Return success (nonzero) only if the backup is either unneeded, or
    Return success (nonzero) only if the backup is either unneeded, or
    successful.  For now, directories are considered to never need
    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
 bool
-maybe_backup_file (const char *path, int archive)
+maybe_backup_file (const char *path, int this_is_the_archive)
 {
 {
   struct stat file_stat;
   struct stat file_stat;
 
 
   /* Check if we really need to backup the file.  */
   /* Check if we really need to backup the file.  */
 
 
-  if (archive && _remdev (path))
+  if (this_is_the_archive && _remdev (path))
     return true;
     return true;
 
 
   if (stat (path, &file_stat))
   if (stat (path, &file_stat))
@@ -355,7 +356,8 @@ maybe_backup_file (const char *path, int archive)
   if (S_ISDIR (file_stat.st_mode))
   if (S_ISDIR (file_stat.st_mode))
     return true;
     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;
     return true;
 
 
   assign_string (&before_backup_name, path);
   assign_string (&before_backup_name, path);
@@ -586,12 +588,6 @@ close_error (char const *name)
   call_arg_error ("close", name);
   call_arg_error ("close", name);
 }
 }
 
 
-void
-close_fatal (char const *name)
-{
-  call_arg_fatal ("close", name);
-}
-
 void
 void
 close_warn (char const *name)
 close_warn (char const *name)
 {
 {
@@ -875,16 +871,16 @@ write_error (char const *name)
 }
 }
 
 
 void
 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);
     write_error (name);
   else
   else
     ERROR ((0, 0,
     ERROR ((0, 0,
 	    ngettext ("%s: Wrote only %lu of %lu byte",
 	    ngettext ("%s: Wrote only %lu of %lu byte",
 		      "%s: Wrote only %lu of %lu bytes",
 		      "%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
 void

+ 16 - 16
src/names.c

@@ -1,7 +1,7 @@
 /* Various processing of names.
 /* Various processing of names.
 
 
    Copyright (C) 1988, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001,
    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
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    under the terms of the GNU General Public License as published by the
@@ -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.  */
 /* Given UNAME, set the corresponding UID and return 1, or else, return 0.  */
 int
 int
-uname_to_uid (char *uname, uid_t *uidp)
+uname_to_uid (char const *uname, uid_t *uidp)
 {
 {
   struct passwd *passwd;
   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.  */
 /* Given GNAME, set the corresponding GID and return 1, or else, return 0.  */
 int
 int
-gname_to_gid (char *gname, gid_t *gidp)
+gname_to_gid (char const *gname, gid_t *gidp)
 {
 {
   struct group *group;
   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
 /* Set up to gather file names for tar.  They can either come from a
    file or were saved from decoding arguments.  */
    file or were saved from decoding arguments.  */
 void
 void
-name_init (int argc, char *const *argv)
+name_init (void)
 {
 {
   name_buffer = xmalloc (NAME_FIELD_SIZE + 2);
   name_buffer = xmalloc (NAME_FIELD_SIZE + 2);
   name_buffer_length = NAME_FIELD_SIZE;
   name_buffer_length = NAME_FIELD_SIZE;
@@ -639,7 +639,7 @@ names_notfound (void)
 	  ERROR ((0, 0, _("%s: Required occurrence not found in archive"),
 	  ERROR ((0, 0, _("%s: Required occurrence not found in archive"),
 		  quotearg_colon (cursor->name)));
 		  quotearg_colon (cursor->name)));
       }
       }
-  
+
   /* Don't bother freeing the name list; we're about to exit.  */
   /* Don't bother freeing the name list; we're about to exit.  */
   namelist = 0;
   namelist = 0;
   nametail = &namelist;
   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
       size_t allocated_length = (name_length >= NAME_FIELD_SIZE
 				 ? name_length + NAME_FIELD_SIZE
 				 ? name_length + NAME_FIELD_SIZE
 				 : NAME_FIELD_SIZE);
 				 : NAME_FIELD_SIZE);
-      char *name_buffer = xmalloc (allocated_length + 1);
+      char *namebuf = xmalloc (allocated_length + 1);
 				/* FIXME: + 2 above?  */
 				/* FIXME: + 2 above?  */
       char *string;
       char *string;
       size_t string_length;
       size_t string_length;
       int change_dir = name->change_dir;
       int change_dir = name->change_dir;
 
 
       name->dir_contents = buffer;
       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)
       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);
 		  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);
 					 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]))
           if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2]))
 	    prefix_len = p + 2 - file_name;
 	    prefix_len = p + 2 - file_name;
-	  
+
 	  do
 	  do
 	    {
 	    {
 	      char c = *p++;
 	      char c = *p++;
@@ -1067,7 +1067,7 @@ safer_name_suffix (char const *file_name, bool link_target)
 	  };
 	  };
 	  WARN ((0, 0, _(diagnostic[link_target])));
 	  WARN ((0, 0, _(diagnostic[link_target])));
 	}
 	}
-      
+
       p = ".";
       p = ".";
     }
     }
 
 

+ 20 - 18
src/rmt.c

@@ -1,7 +1,7 @@
 /* Remote connection server.
 /* 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
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    under the terms of the GNU General Public License as published by the
@@ -117,12 +117,12 @@ get_string (char *string)
 {
 {
   int counter;
   int counter;
 
 
-  for (counter = 0; counter < STRING_SIZE; counter++)
+  for (counter = 0; ; counter++)
     {
     {
       if (safe_read (STDIN_FILENO, string + counter, 1) != 1)
       if (safe_read (STDIN_FILENO, string + counter, 1) != 1)
 	exit (EXIT_SUCCESS);
 	exit (EXIT_SUCCESS);
 
 
-      if (string[counter] == '\n')
+      if (string[counter] == '\n' || counter == STRING_SIZE - 1)
 	break;
 	break;
     }
     }
   string[counter] = '\0';
   string[counter] = '\0';
@@ -179,11 +179,11 @@ decode_oflag (char const *oflag_string)
   char *oflag_num_end;
   char *oflag_num_end;
   int numeric_oflag = strtol (oflag_string, &oflag_num_end, 10);
   int numeric_oflag = strtol (oflag_string, &oflag_num_end, 10);
   int symbolic_oflag = 0;
   int symbolic_oflag = 0;
-  
+
   oflag_string = oflag_num_end;
   oflag_string = oflag_num_end;
   while (ISSPACE ((unsigned char) *oflag_string))
   while (ISSPACE ((unsigned char) *oflag_string))
     oflag_string++;
     oflag_string++;
-    
+
   do
   do
     {
     {
       struct name_value_pair { char const *name; int value; };
       struct name_value_pair { char const *name; int value; };
@@ -247,6 +247,8 @@ static struct option const long_opts[] =
   {0, 0, 0, 0}
   {0, 0, 0, 0}
 };
 };
 
 
+static void usage (int) __attribute__ ((noreturn));
+
 static void
 static void
 usage (int status)
 usage (int status)
 {
 {
@@ -272,7 +274,7 @@ int
 main (int argc, char *const *argv)
 main (int argc, char *const *argv)
 {
 {
   char command;
   char command;
-  ssize_t status;
+  size_t status;
 
 
   /* FIXME: Localization is meaningless, unless --help and --version are
   /* FIXME: Localization is meaningless, unless --help and --version are
      locally used.  Localization would be best accomplished by the calling
      locally used.  Localization would be best accomplished by the calling
@@ -287,14 +289,14 @@ main (int argc, char *const *argv)
     {
     {
     default:
     default:
       usage (EXIT_FAILURE);
       usage (EXIT_FAILURE);
-      
+
     case 'h':
     case 'h':
       usage (EXIT_SUCCESS);
       usage (EXIT_SUCCESS);
-      
+
     case 'v':
     case 'v':
       {
       {
 	printf ("rmt (%s) %s\n%s\n", PACKAGE_NAME, PACKAGE_VERSION,
 	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 (_("\
 	puts (_("\
 This program comes with NO WARRANTY, to the extent permitted by law.\n\
 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\
 You may redistribute it under the terms of the GNU General Public License;\n\
@@ -421,7 +423,7 @@ top:
 	do
 	do
 	  *--p = '0' + (int) (count % 10);
 	  *--p = '0' + (int) (count % 10);
 	while ((count /= 10) != 0);
 	while ((count /= 10) != 0);
-	
+
 	DEBUG1 ("rmtd: A %s\n", p);
 	DEBUG1 ("rmtd: A %s\n", p);
 
 
 	sprintf (reply_buffer, "A%s\n", p);
 	sprintf (reply_buffer, "A%s\n", p);
@@ -444,7 +446,7 @@ top:
 	  {
 	  {
 	    status = safe_read (STDIN_FILENO, &record_buffer[counter],
 	    status = safe_read (STDIN_FILENO, &record_buffer[counter],
 				size - counter);
 				size - counter);
-	    if (status <= 0)
+	    if (status == SAFE_READ_ERROR || status == 0)
 	      {
 	      {
 		DEBUG (_("rmtd: Premature eof\n"));
 		DEBUG (_("rmtd: Premature eof\n"));
 
 
@@ -453,7 +455,7 @@ top:
 	      }
 	      }
 	  }
 	  }
 	status = full_write (tape, record_buffer, size);
 	status = full_write (tape, record_buffer, size);
-	if (status < 0)
+	if (status != size)
 	  goto ioerror;
 	  goto ioerror;
 	goto respond;
 	goto respond;
       }
       }
@@ -469,9 +471,9 @@ top:
 	size = atol (count_string);
 	size = atol (count_string);
 	prepare_input_buffer (-1, size);
 	prepare_input_buffer (-1, size);
 	status = safe_read (tape, record_buffer, size);
 	status = safe_read (tape, record_buffer, size);
-	if (status < 0)
+	if (status == SAFE_READ_ERROR)
 	  goto ioerror;
 	  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, reply_buffer, strlen (reply_buffer));
 	full_write (STDOUT_FILENO, record_buffer, status);
 	full_write (STDOUT_FILENO, record_buffer, status);
 	goto top;
 	goto top;
@@ -496,13 +498,13 @@ top:
 	  /* Parse count_string, taking care to check for overflow.
 	  /* Parse count_string, taking care to check for overflow.
 	     We can't use standard functions,
 	     We can't use standard functions,
 	     since off_t might be longer than long.  */
 	     since off_t might be longer than long.  */
-	  
+
 	  for (p = count_string;  *p == ' ' || *p == '\t';  p++)
 	  for (p = count_string;  *p == ' ' || *p == '\t';  p++)
 	    continue;
 	    continue;
-	  
+
 	  negative = *p == '-';
 	  negative = *p == '-';
 	  p += negative || *p == '+';
 	  p += negative || *p == '+';
-	  
+
 	  for (;;)
 	  for (;;)
 	    {
 	    {
 	      int digit = *p++ - '0';
 	      int digit = *p++ - '0';

+ 4 - 4
src/rmt.h

@@ -1,7 +1,7 @@
 /* Definitions for communicating with a remote tape drive.
 /* 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
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    it under the terms of the GNU General Public License as published by
@@ -21,8 +21,8 @@ extern char *rmt_path__;
 
 
 int rmt_open__ (const char *, int, int, const char *);
 int rmt_open__ (const char *, int, int, const char *);
 int rmt_close__ (int);
 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);
 off_t rmt_lseek__ (int, off_t, int);
 int rmt_ioctl__ (int, int, char *);
 int rmt_ioctl__ (int, int, char *);
 
 

+ 39 - 24
src/rtapelib.c

@@ -1,7 +1,7 @@
 /* Functions for communicating with a remote tape drive.
 /* Functions for communicating with a remote tape drive.
 
 
-   Copyright 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001 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
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    it under the terms of the GNU General Public License as published by
@@ -163,8 +163,6 @@ get_status_string (int handle, char *command_buffer)
 
 
   if (*cursor == 'E' || *cursor == 'F')
   if (*cursor == 'E' || *cursor == 'F')
     {
     {
-      errno = atoi (cursor + 1);
-
       /* Skip the error message line.  */
       /* Skip the error message line.  */
 
 
       /* FIXME: there is better to do than merely ignoring error messages
       /* FIXME: there is better to do than merely ignoring error messages
@@ -178,6 +176,8 @@ get_status_string (int handle, char *command_buffer)
 	    break;
 	    break;
       }
       }
 
 
+      errno = atoi (cursor + 1);
+
       if (*cursor == 'F')
       if (*cursor == 'F')
 	_rmt_shutdown (handle, errno);
 	_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
 /* Read and return the status from remote tape connection HANDLE.  If
    an error occurred, return -1 and set errno.  */
    an error occurred, return -1 and set errno.  */
-static long
+static long int
 get_status (int handle)
 get_status (int handle)
 {
 {
   char command_buffer[COMMAND_BUFFER_SIZE];
   char command_buffer[COMMAND_BUFFER_SIZE];
   const char *status = get_status_string (handle, command_buffer);
   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
 static off_t
@@ -226,10 +233,10 @@ get_status_off (int handle)
 
 
       for (;  *status == ' ' || *status == '\t';  status++)
       for (;  *status == ' ' || *status == '\t';  status++)
 	continue;
 	continue;
-      
+
       negative = *status == '-';
       negative = *status == '-';
       status += negative || *status == '+';
       status += negative || *status == '+';
-      
+
       for (;;)
       for (;;)
 	{
 	{
 	  int digit = *status++ - '0';
 	  int digit = *status++ - '0';
@@ -533,7 +540,7 @@ rmt_open__ (const char *path, int open_mode, int bias, const char *remote_shell)
 int
 int
 rmt_close__ (int handle)
 rmt_close__ (int handle)
 {
 {
-  int status;
+  long int status;
 
 
   if (do_command (handle, "C\n") == -1)
   if (do_command (handle, "C\n") == -1)
     return -1;
     return -1;
@@ -544,26 +551,27 @@ rmt_close__ (int handle)
 }
 }
 
 
 /* Read up to LENGTH bytes into BUFFER from remote tape connection 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)
 rmt_read__ (int handle, char *buffer, size_t length)
 {
 {
   char command_buffer[COMMAND_BUFFER_SIZE];
   char command_buffer[COMMAND_BUFFER_SIZE];
-  ssize_t status, rlen;
+  size_t status;
+  size_t rlen;
   size_t counter;
   size_t counter;
 
 
   sprintf (command_buffer, "R%lu\n", (unsigned long) length);
   sprintf (command_buffer, "R%lu\n", (unsigned long) length);
   if (do_command (handle, command_buffer) == -1
   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)
   for (counter = 0; counter < status; counter += rlen, buffer += rlen)
     {
     {
       rlen = safe_read (READ_SIDE (handle), buffer, status - counter);
       rlen = safe_read (READ_SIDE (handle), buffer, status - counter);
-      if (rlen <= 0)
+      if (rlen == SAFE_READ_ERROR || rlen == 0)
 	{
 	{
 	  _rmt_shutdown (handle, EIO);
 	  _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.
 /* 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)
 rmt_write__ (int handle, char *buffer, size_t length)
 {
 {
   char command_buffer[COMMAND_BUFFER_SIZE];
   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);
   sprintf (command_buffer, "W%lu\n", (unsigned long) length);
   if (do_command (handle, command_buffer) == -1)
   if (do_command (handle, command_buffer) == -1)
-    return -1;
+    return 0;
 
 
   pipe_handler = signal (SIGPIPE, SIG_IGN);
   pipe_handler = signal (SIGPIPE, SIG_IGN);
   written = full_write (WRITE_SIDE (handle), buffer, length);
   written = full_write (WRITE_SIDE (handle), buffer, length);
   signal (SIGPIPE, pipe_handler);
   signal (SIGPIPE, pipe_handler);
   if (written == length)
   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.  */
   /* Write error.  */
 
 
   _rmt_shutdown (handle, EIO);
   _rmt_shutdown (handle, EIO);
-  return -1;
+  return written;
 }
 }
 
 
 /* Perform an imitation lseek operation on remote tape connection
 /* 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
 		       : (uintmax_t) ((struct mtop *) argument)->mt_count);
 		       : (uintmax_t) ((struct mtop *) argument)->mt_count);
 	char *p = operand_buffer + sizeof operand_buffer;
 	char *p = operand_buffer + sizeof operand_buffer;
-	
+
         *--p = 0;
         *--p = 0;
 	do
 	do
 	  *--p = '0' + (int) (u % 10);
 	  *--p = '0' + (int) (u % 10);
@@ -671,7 +686,7 @@ rmt_ioctl__ (int handle, int operation, char *argument)
     case MTIOCGET:
     case MTIOCGET:
       {
       {
 	ssize_t status;
 	ssize_t status;
-	ssize_t counter;
+	size_t counter;
 
 
 	/* Grab the status and read it directly into the structure.  This
 	/* Grab the status and read it directly into the structure.  This
 	   assumes that the status buffer is not padded and that 2 shorts
 	   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)
 	for (; status > 0; status -= counter, argument += counter)
 	  {
 	  {
 	    counter = safe_read (READ_SIDE (handle), argument, status);
 	    counter = safe_read (READ_SIDE (handle), argument, status);
-	    if (counter <= 0)
+	    if (counter == SAFE_READ_ERROR || counter == 0)
 	      {
 	      {
 		_rmt_shutdown (handle, EIO);
 		_rmt_shutdown (handle, EIO);
 		return -1;
 		return -1;

+ 71 - 70
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
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    under the terms of the GNU General Public License as published by the
@@ -39,8 +39,8 @@ struct tar_sparse_optab
   bool (*decode_header) (struct tar_sparse_file *);
   bool (*decode_header) (struct tar_sparse_file *);
   bool (*scan_block) (struct tar_sparse_file *, enum sparse_scan_state,
   bool (*scan_block) (struct tar_sparse_file *, enum sparse_scan_state,
 		      void *);
 		      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
 struct tar_sparse_file
@@ -89,18 +89,18 @@ tar_sparse_scan (struct tar_sparse_file *file, enum sparse_scan_state state,
 }
 }
 
 
 static bool
 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)
   if (file->optab->dump_region)
-    return file->optab->dump_region (file, index);
+    return file->optab->dump_region (file, i);
   return false;
   return false;
 }
 }
 
 
 static bool
 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)
   if (file->optab->extract_region)
-    return file->optab->extract_region (file, index);
+    return file->optab->extract_region (file, i);
   return false;
   return false;
 }
 }
 
 
@@ -191,11 +191,12 @@ sparse_scan_file (struct tar_sparse_file *file)
 
 
   file->stat_info->sparse_map_size = 0;
   file->stat_info->sparse_map_size = 0;
   file->stat_info->archive_file_size = 0;
   file->stat_info->archive_file_size = 0;
-  
+
   if (!tar_sparse_scan (file, scan_begin, NULL))
   if (!tar_sparse_scan (file, scan_begin, NULL))
     return false;
     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 */
       /* Analize the block */
       if (zero_block_p (buffer, count))
       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))
 	  if (!tar_sparse_scan (file, scan_block, buffer))
 	    return false;
 	    return false;
 	}
 	}
-      
+
       offset += count;
       offset += count;
       clear_block (buffer);
       clear_block (buffer);
     }
     }
-      
+
   if (sp.numbytes == 0)
   if (sp.numbytes == 0)
     sp.offset = offset;
     sp.offset = offset;
 
 
@@ -255,7 +256,7 @@ sparse_select_optab (struct tar_sparse_file *file)
     case STAR_FORMAT:
     case STAR_FORMAT:
       file->optab = &star_optab;
       file->optab = &star_optab;
       break;
       break;
-	
+
     default:
     default:
       return false;
       return false;
     }
     }
@@ -263,28 +264,28 @@ sparse_select_optab (struct tar_sparse_file *file)
 }
 }
 
 
 static bool
 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;
   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))
 		       SEEK_SET))
     return false;
     return false;
 
 
   while (bytes_left > 0)
   while (bytes_left > 0)
     {
     {
       size_t bufsize = (bytes_left > BLOCKSIZE) ? BLOCKSIZE : bytes_left;
       size_t bufsize = (bytes_left > BLOCKSIZE) ? BLOCKSIZE : bytes_left;
-      off_t bytes_read;
-      
+      size_t bytes_read;
+
       blk = find_next_block ();
       blk = find_next_block ();
       memset (blk->buffer, 0, BLOCKSIZE);
       memset (blk->buffer, 0, BLOCKSIZE);
       bytes_read = safe_read (file->fd, blk->buffer, bufsize);
       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,
           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,
 	                         - bytes_left,
 	             bufsize);
 	             bufsize);
 	  return false;
 	  return false;
@@ -299,15 +300,15 @@ sparse_dump_region (struct tar_sparse_file *file, size_t index)
 }
 }
 
 
 static bool
 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;
   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))
 		       SEEK_SET))
     return false;
     return false;
 
 
-  write_size = file->stat_info->sparse_map[index].numbytes;
+  write_size = file->stat_info->sparse_map[i].numbytes;
 
 
   if (write_size == 0)
   if (write_size == 0)
     {
     {
@@ -343,12 +344,12 @@ sparse_extract_region (struct tar_sparse_file *file, size_t index)
 
 
 /* Interface functions */
 /* Interface functions */
 enum dump_status
 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;
   bool rc;
   struct tar_sparse_file file;
   struct tar_sparse_file file;
 
 
-  file.stat_info = stat;
+  file.stat_info = st;
   file.fd = fd;
   file.fd = fd;
 
 
   if (!sparse_select_optab (&file)
   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 */
 /* Returns true if the file represented by stat is a sparse one */
 bool
 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
 bool
-sparse_member_p (struct tar_stat_info *stat)
+sparse_member_p (struct tar_stat_info *st)
 {
 {
   struct tar_sparse_file file;
   struct tar_sparse_file file;
-  
+
   if (!sparse_select_optab (&file))
   if (!sparse_select_optab (&file))
     return false;
     return false;
-  file.stat_info = stat;
+  file.stat_info = st;
   return tar_sparse_member_p (&file);
   return tar_sparse_member_p (&file);
 }
 }
 
 
 bool
 bool
-sparse_fixup_header (struct tar_stat_info *stat)
+sparse_fixup_header (struct tar_stat_info *st)
 {
 {
   struct tar_sparse_file file;
   struct tar_sparse_file file;
-  
+
   if (!sparse_select_optab (&file))
   if (!sparse_select_optab (&file))
     return false;
     return false;
-  file.stat_info = stat;
+  file.stat_info = st;
   return tar_sparse_fixup_header (&file);
   return tar_sparse_fixup_header (&file);
 }
 }
 
 
 enum dump_status
 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;
   bool rc = true;
   struct tar_sparse_file file;
   struct tar_sparse_file file;
   size_t i;
   size_t i;
-  
-  file.stat_info = stat;
+
+  file.stat_info = st;
   file.fd = fd;
   file.fd = fd;
 
 
   if (!sparse_select_optab (&file)
   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
 enum dump_status
-sparse_skip_file (struct tar_stat_info *stat)
+sparse_skip_file (struct tar_stat_info *st)
 {
 {
   bool rc = true;
   bool rc = true;
   struct tar_sparse_file file;
   struct tar_sparse_file file;
-  
-  file.stat_info = stat;
+
+  file.stat_info = st;
   file.fd = -1;
   file.fd = -1;
 
 
   if (!sparse_select_optab (&file)
   if (!sparse_select_optab (&file)
@@ -445,23 +446,23 @@ sparse_skip_file (struct tar_stat_info *stat)
 
 
 
 
 static char diff_buffer[BLOCKSIZE];
 static char diff_buffer[BLOCKSIZE];
-		   
+
 static bool
 static bool
 check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
 check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
 {
 {
   if (!lseek_or_error (file, beg, SEEK_SET))
   if (!lseek_or_error (file, beg, SEEK_SET))
     return false;
     return false;
-  
+
   while (beg < end)
   while (beg < end)
     {
     {
       size_t bytes_read;
       size_t bytes_read;
       size_t rdsize = end - beg;
       size_t rdsize = end - beg;
-      
+
       if (rdsize > BLOCKSIZE)
       if (rdsize > BLOCKSIZE)
 	rdsize = BLOCKSIZE;
 	rdsize = BLOCKSIZE;
       clear_block (diff_buffer);
       clear_block (diff_buffer);
       bytes_read = safe_read (file->fd, diff_buffer, rdsize);
       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,
           read_diag_details (file->stat_info->orig_file_name,
 	                     beg,
 	                     beg,
@@ -481,19 +482,19 @@ check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
 }
 }
 
 
 static bool
 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;
   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))
 		       SEEK_SET))
     return false;
     return false;
-  size_left = file->stat_info->sparse_map[index].numbytes;
+  size_left = file->stat_info->sparse_map[i].numbytes;
   while (size_left > 0)
   while (size_left > 0)
     {
     {
       size_t bytes_read;
       size_t bytes_read;
       size_t rdsize = (size_left > BLOCKSIZE) ? BLOCKSIZE : size_left;
       size_t rdsize = (size_left > BLOCKSIZE) ? BLOCKSIZE : size_left;
-      
+
       union block *blk = find_next_block ();
       union block *blk = find_next_block ();
       if (!blk)
       if (!blk)
 	{
 	{
@@ -502,11 +503,11 @@ check_data_region (struct tar_sparse_file *file, size_t index)
 	}
 	}
       set_next_block_after (blk);
       set_next_block_after (blk);
       bytes_read = safe_read (file->fd, diff_buffer, rdsize);
       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,
           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,
 			         - size_left,
 			     rdsize);
 			     rdsize);
 	  return false;
 	  return false;
@@ -523,14 +524,14 @@ check_data_region (struct tar_sparse_file *file, size_t index)
 }
 }
 
 
 bool
 bool
-sparse_diff_file (int fd, struct tar_stat_info *stat)
+sparse_diff_file (int fd, struct tar_stat_info *st)
 {
 {
   bool rc = true;
   bool rc = true;
   struct tar_sparse_file file;
   struct tar_sparse_file file;
   size_t i;
   size_t i;
   off_t offset = 0;
   off_t offset = 0;
-  
-  file.stat_info = stat;
+
+  file.stat_info = st;
   file.fd = fd;
   file.fd = fd;
 
 
   if (!sparse_select_optab (&file)
   if (!sparse_select_optab (&file)
@@ -554,14 +555,14 @@ sparse_diff_file (int fd, struct tar_stat_info *stat)
   return rc;
   return rc;
 }
 }
 
 
-     
+
 /* Old GNU Format. The sparse file information is stored in the
 /* Old GNU Format. The sparse file information is stored in the
    oldgnu_header in the following manner:
    oldgnu_header in the following manner:
 
 
    The header is marked with type 'S'. Its `size' field contains
    The header is marked with type 'S'. Its `size' field contains
    the cumulative size of all non-empty blocks of the file. The
    the cumulative size of all non-empty blocks of the file. The
    actual file size is stored in `realsize' member of oldgnu_header.
    actual file size is stored in `realsize' member of oldgnu_header.
-   
+
    The map of the file is stored in a list of `struct sparse'.
    The map of the file is stored in a list of `struct sparse'.
    Each struct contains offset to the block of data and its
    Each struct contains offset to the block of data and its
    size (both as octal numbers). The first file header contains
    size (both as octal numbers). The first file header contains
@@ -581,13 +582,13 @@ enum oldgnu_add_status
   };
   };
 
 
 static bool
 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;
   return current_header->header.typeflag == GNUTYPE_SPARSE;
 }
 }
 
 
 /* Add a sparse item to the sparse file and its obstack */
 /* 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)
 oldgnu_add_sparse (struct tar_sparse_file *file, struct sparse *s)
 {
 {
   struct sp_array sp;
   struct sp_array sp;
@@ -624,7 +625,7 @@ oldgnu_get_sparse_info (struct tar_sparse_file *file)
   union block *h = current_header;
   union block *h = current_header;
   int ext_p;
   int ext_p;
   static enum oldgnu_add_status rc;
   static enum oldgnu_add_status rc;
-  
+
   file->stat_info->sparse_map_size = 0;
   file->stat_info->sparse_map_size = 0;
   for (i = 0; i < SPARSES_IN_OLDGNU_HEADER; i++)
   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 ();
   off_t block_ordinal = current_block_ordinal ();
   union block *blk;
   union block *blk;
   size_t i;
   size_t i;
-    
+
   blk = start_header (file->stat_info);
   blk = start_header (file->stat_info);
   blk->header.typeflag = GNUTYPE_SPARSE;
   blk->header.typeflag = GNUTYPE_SPARSE;
   if (file->stat_info->sparse_map_avail > SPARSES_IN_OLDGNU_HEADER)
   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);
 			    SPARSES_IN_OLDGNU_HEADER);
   blk->oldgnu_header.isextended = i < file->stat_info->sparse_map_avail;
   blk->oldgnu_header.isextended = i < file->stat_info->sparse_map_avail;
   finish_header (file->stat_info, blk, block_ordinal);
   finish_header (file->stat_info, blk, block_ordinal);
-  
+
   while (i < file->stat_info->sparse_map_avail)
   while (i < file->stat_info->sparse_map_avail)
     {
     {
       blk = find_next_block ();
       blk = find_next_block ();
@@ -726,7 +727,7 @@ static struct tar_sparse_optab oldgnu_optab = {
 /* Star */
 /* Star */
 
 
 static bool
 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;
   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;
   union block *h = current_header;
   int ext_p;
   int ext_p;
   static enum oldgnu_add_status rc;
   static enum oldgnu_add_status rc;
-  
+
   file->stat_info->sparse_map_size = 0;
   file->stat_info->sparse_map_size = 0;
 
 
   if (h->star_in_header.prefix[0] == '\0'
   if (h->star_in_header.prefix[0] == '\0'
@@ -799,7 +800,7 @@ static struct tar_sparse_optab star_optab = {
   star_fixup_header,
   star_fixup_header,
   star_get_sparse_info,
   star_get_sparse_info,
   NULL,  /* No scan_block function */
   NULL,  /* No scan_block function */
-  NULL, /* No dump region function */ 
+  NULL, /* No dump region function */
   sparse_extract_region,
   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.offset", file->stat_info, &i);
       xheader_store ("GNU.sparse.numbytes", file->stat_info, &i);
       xheader_store ("GNU.sparse.numbytes", file->stat_info, &i);
     }
     }
-  
+
   blk = start_header (file->stat_info);
   blk = start_header (file->stat_info);
   /* Store the effective (shrunken) file size */
   /* Store the effective (shrunken) file size */
   OFF_TO_CHARS (file->stat_info->archive_file_size, blk->header.size);
   OFF_TO_CHARS (file->stat_info->archive_file_size, blk->header.size);

+ 42 - 78
src/system.c

@@ -1,6 +1,6 @@
 /* System-dependent calls for tar.
 /* 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
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    under the terms of the GNU General Public License as published by the
@@ -23,46 +23,33 @@
 #include <signal.h>
 #include <signal.h>
 
 
 void
 void
-sys_stat_nanoseconds(struct tar_stat_info *stat)
+sys_stat_nanoseconds (struct tar_stat_info *st)
 {
 {
 #if defined(HAVE_STRUCT_STAT_ST_SPARE1)
 #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)
 #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)
 #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)
 #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
 #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
 #endif
 }
 }
 
 
 #if MSDOS
 #if MSDOS
 
 
 bool
 bool
-sys_get_archive_stat ()
+sys_get_archive_stat (void)
 {
 {
   return 0;
   return 0;
 }
 }
@@ -74,12 +61,12 @@ sys_file_is_archive (struct tar_stat_info *p)
 }
 }
 
 
 void
 void
-sys_save_archive_dev_ino ()
+sys_save_archive_dev_ino (void)
 {
 {
 }
 }
 
 
 void
 void
-sys_detect_dev_null_output ()
+sys_detect_dev_null_output (void)
 {
 {
   static char const dev_null[] = "nul";
   static char const dev_null[] = "nul";
 
 
@@ -88,7 +75,7 @@ sys_detect_dev_null_output ()
 }
 }
 
 
 void
 void
-sys_drain_input_pipe ()
+sys_drain_input_pipe (void)
 {
 {
 }
 }
 
 
@@ -98,7 +85,7 @@ sys_wait_for_child (pid_t child_pid)
 }
 }
 
 
 void
 void
-sys_spawn_shell ()
+sys_spawn_shell (void)
 {
 {
   spawnl (P_WAIT, getenv ("COMSPEC"), "-", 0);
   spawnl (P_WAIT, getenv ("COMSPEC"), "-", 0);
 }
 }
@@ -132,25 +119,14 @@ sys_truncate (int fd)
 }
 }
 
 
 void
 void
-sys_reset_uid_gid ()
+sys_reset_uid_gid (void)
 {
 {
 }
 }
 
 
-ssize_t
+size_t
 sys_write_archive_buffer (void)
 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.  */
 /* 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 */
 static struct stat archive_stat; /* stat block for archive file */
 
 
 bool
 bool
-sys_get_archive_stat ()
+sys_get_archive_stat (void)
 {
 {
   return fstat (archive, &archive_stat) == 0;
   return fstat (archive, &archive_stat) == 0;
 }
 }
-    
+
 bool
 bool
 sys_file_is_archive (struct tar_stat_info *p)
 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 */
 /* Save archive file inode and device numbers */
 void
 void
-sys_save_archive_dev_ino ()
+sys_save_archive_dev_ino (void)
 {
 {
   if (!_isrmt (archive) && S_ISREG (archive_stat.st_mode))
   if (!_isrmt (archive) && S_ISREG (archive_stat.st_mode))
     {
     {
@@ -200,7 +176,7 @@ sys_save_archive_dev_ino ()
 
 
 /* Detect if outputting to "/dev/null".  */
 /* Detect if outputting to "/dev/null".  */
 void
 void
-sys_detect_dev_null_output ()
+sys_detect_dev_null_output (void)
 {
 {
   static char const dev_null[] = "/dev/null";
   static char const dev_null[] = "/dev/null";
   struct stat dev_null_stat;
   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.  */
    work to do, we might have to revise this area in such time.  */
 
 
 void
 void
-sys_drain_input_pipe ()
+sys_drain_input_pipe (void)
 {
 {
+  size_t r;
+
   if (access_mode == ACCESS_READ
   if (access_mode == ACCESS_READ
       && ! _isrmt (archive)
       && ! _isrmt (archive)
       && (S_ISFIFO (archive_stat.st_mode) || S_ISSOCK (archive_stat.st_mode)))
       && (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;
       continue;
 }
 }
 
 
@@ -252,7 +231,7 @@ sys_wait_for_child (pid_t child_pid)
 }
 }
 
 
 void
 void
-sys_spawn_shell ()
+sys_spawn_shell (void)
 {
 {
   pid_t child;
   pid_t child;
   const char *shell = getenv ("SHELL");
   const char *shell = getenv ("SHELL");
@@ -303,7 +282,7 @@ sys_truncate (int fd)
 }
 }
 
 
 void
 void
-sys_reset_uid_gid ()
+sys_reset_uid_gid (void)
 {
 {
   setuid (getuid ());
   setuid (getuid ());
   setgid (getgid ());
   setgid (getgid ());
@@ -322,24 +301,10 @@ is_regular_file (const char *name)
     return errno == ENOENT;
     return errno == ENOENT;
 }
 }
 
 
-ssize_t
+size_t
 sys_write_archive_buffer (void)
 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() */
 #define	PREAD 0			/* read file descriptor from pipe() */
@@ -471,7 +436,7 @@ sys_child_open_for_compress (void)
 
 
   while (1)
   while (1)
     {
     {
-      ssize_t status = 0;
+      size_t status = 0;
       char *cursor;
       char *cursor;
       size_t length;
       size_t length;
 
 
@@ -484,13 +449,12 @@ sys_child_open_for_compress (void)
 	  size_t size = record_size - length;
 	  size_t size = record_size - length;
 
 
 	  status = safe_read (STDIN_FILENO, cursor, size);
 	  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;
 	    break;
 	}
 	}
 
 
-      if (status < 0)
-	read_fatal (use_compress_program_option);
-
       /* Copy the record.  */
       /* Copy the record.  */
 
 
       if (status == 0)
       if (status == 0)
@@ -628,13 +592,13 @@ sys_child_open_for_uncompress (void)
       char *cursor;
       char *cursor;
       size_t maximum;
       size_t maximum;
       size_t count;
       size_t count;
-      ssize_t status;
+      size_t status;
 
 
       clear_read_error_count ();
       clear_read_error_count ();
 
 
     error_loop:
     error_loop:
       status = rmtread (archive, record_start->buffer, record_size);
       status = rmtread (archive, record_start->buffer, record_size);
-      if (status < 0)
+      if (status == SAFE_READ_ERROR)
 	{
 	{
 	  archive_read_error ();
 	  archive_read_error ();
 	  goto error_loop;
 	  goto error_loop;

+ 34 - 28
src/tar.c

@@ -1,7 +1,7 @@
 /* A tar (tape archiver) program.
 /* A tar (tape archiver) program.
 
 
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
    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.
    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},
   {"volno-file", required_argument, 0, VOLNO_FILE_OPTION},
   {"wildcards", no_argument, 0, WILDCARDS_OPTION},
   {"wildcards", no_argument, 0, WILDCARDS_OPTION},
   {"wildcards-match-slash", no_argument, 0, WILDCARDS_MATCH_SLASH_OPTION},
   {"wildcards-match-slash", no_argument, 0, WILDCARDS_MATCH_SLASH_OPTION},
-  
+
   {0, 0, 0, 0}
   {0, 0, 0, 0}
 };
 };
 
 
@@ -519,7 +519,7 @@ Compatibility options:\n\
   -o                                 when creating, same as --old-archive\n\
   -o                                 when creating, same as --old-archive\n\
                                      when extracting, same as --no-same-owner\n"),
                                      when extracting, same as --no-same-owner\n"),
              stdout);
              stdout);
-      
+
       fputs (_("\
       fputs (_("\
 \n\
 \n\
 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\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;
   blocking_factor = DEFAULT_BLOCKING;
   record_size = DEFAULT_BLOCKING * BLOCKSIZE;
   record_size = DEFAULT_BLOCKING * BLOCKSIZE;
   excluded = new_exclude ();
   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;
   recursion_option = FNM_LEADING_DIR;
 
 
   owner_option = -1;
   owner_option = -1;
@@ -823,7 +824,7 @@ decode_options (int argc, char **argv)
 	/* Fall through.  */
 	/* Fall through.  */
 
 
       case NEWER_MTIME_OPTION:
       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")));
 	  USAGE_ERROR ((0, 0, _("More than one threshold date")));
 
 
 	if (FILESYSTEM_PREFIX_LEN (optarg) != 0
 	if (FILESYSTEM_PREFIX_LEN (optarg) != 0
@@ -836,14 +837,17 @@ decode_options (int argc, char **argv)
 		stat_error (optarg);
 		stat_error (optarg);
 		USAGE_ERROR ((0, 0, _("Date file not found")));
 		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
 	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
 	    else
 	      textual_date_option = optarg;
 	      textual_date_option = optarg;
 	  }
 	  }
@@ -912,7 +916,7 @@ decode_options (int argc, char **argv)
       case UTC_OPTION:
       case UTC_OPTION:
 	utc_option = true;
 	utc_option = true;
 	break;
 	break;
-	
+
       case 'v':
       case 'v':
 	verbose_option++;
 	verbose_option++;
 	break;
 	break;
@@ -990,7 +994,7 @@ decode_options (int argc, char **argv)
       case FORMAT_OPTION:
       case FORMAT_OPTION:
 	set_archive_format (optarg);
 	set_archive_format (optarg);
 	break;
 	break;
-	
+
       case INDEX_FILE_OPTION:
       case INDEX_FILE_OPTION:
 	index_file_name = optarg;
 	index_file_name = optarg;
 	break;
 	break;
@@ -1006,7 +1010,7 @@ decode_options (int argc, char **argv)
       case KEEP_NEWER_FILES_OPTION:
       case KEEP_NEWER_FILES_OPTION:
 	old_files_option = KEEP_NEWER_FILES;
 	old_files_option = KEEP_NEWER_FILES;
 	break;
 	break;
-	
+
       case GROUP_OPTION:
       case GROUP_OPTION:
 	if (! (strlen (optarg) < GNAME_FIELD_SIZE
 	if (! (strlen (optarg) < GNAME_FIELD_SIZE
 	       && gname_to_gid (optarg, &group_option)))
 	       && gname_to_gid (optarg, &group_option)))
@@ -1072,7 +1076,7 @@ decode_options (int argc, char **argv)
 			    _("Invalid number")));
 			    _("Invalid number")));
 	  }
 	  }
 	break;
 	break;
-	
+
       case OVERWRITE_OPTION:
       case OVERWRITE_OPTION:
 	old_files_option = OVERWRITE_OLD_FILES;
 	old_files_option = OVERWRITE_OLD_FILES;
 	break;
 	break;
@@ -1095,7 +1099,7 @@ decode_options (int argc, char **argv)
 	pax_option++;
 	pax_option++;
 	xheader_set_option (optarg);
 	xheader_set_option (optarg);
 	break;
 	break;
-			    
+
       case POSIX_OPTION:
       case POSIX_OPTION:
 	set_archive_format ("posix");
 	set_archive_format ("posix");
 	break;
 	break;
@@ -1148,7 +1152,7 @@ decode_options (int argc, char **argv)
 	  strip_path_elements = u;
 	  strip_path_elements = u;
 	}
 	}
 	break;
 	break;
-	
+
       case SUFFIX_OPTION:
       case SUFFIX_OPTION:
 	backup_option = true;
 	backup_option = true;
 	backup_suffix_string = optarg;
 	backup_suffix_string = optarg;
@@ -1157,7 +1161,7 @@ decode_options (int argc, char **argv)
       case TOTALS_OPTION:
       case TOTALS_OPTION:
 	totals_option = true;
 	totals_option = true;
 	break;
 	break;
-	
+
       case USE_COMPRESS_PROGRAM_OPTION:
       case USE_COMPRESS_PROGRAM_OPTION:
 	set_use_compress_program_option (optarg);
 	set_use_compress_program_option (optarg);
 	break;
 	break;
@@ -1285,7 +1289,7 @@ decode_options (int argc, char **argv)
   if (show_version)
   if (show_version)
     {
     {
       printf ("tar (%s) %s\n%s\n", PACKAGE_NAME, PACKAGE_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 (_("\
       puts (_("\
 This program comes with NO WARRANTY, to the extent permitted by law.\n\
 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\
 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
       else
 	archive_format = DEFAULT_ARCHIVE_FORMAT;
 	archive_format = DEFAULT_ARCHIVE_FORMAT;
     }
     }
-  
+
   if (volume_label_option && subcommand_option == CREATE_SUBCOMMAND)
   if (volume_label_option && subcommand_option == CREATE_SUBCOMMAND)
     assert_format (FORMAT_MASK (OLDGNU_FORMAT)
     assert_format (FORMAT_MASK (OLDGNU_FORMAT)
 		   | FORMAT_MASK (GNU_FORMAT));
 		   | FORMAT_MASK (GNU_FORMAT));
@@ -1316,12 +1320,12 @@ see the file named COPYING for details."));
 
 
   if (incremental_option || multi_volume_option)
   if (incremental_option || multi_volume_option)
     assert_format (FORMAT_MASK (OLDGNU_FORMAT) | FORMAT_MASK (GNU_FORMAT));
     assert_format (FORMAT_MASK (OLDGNU_FORMAT) | FORMAT_MASK (GNU_FORMAT));
-		   
+
   if (sparse_option)
   if (sparse_option)
     assert_format (FORMAT_MASK (OLDGNU_FORMAT)
     assert_format (FORMAT_MASK (OLDGNU_FORMAT)
 		   | FORMAT_MASK (GNU_FORMAT)
 		   | FORMAT_MASK (GNU_FORMAT)
 		   | FORMAT_MASK (POSIX_FORMAT));
 		   | FORMAT_MASK (POSIX_FORMAT));
-  
+
   if (occurrence_option)
   if (occurrence_option)
     {
     {
       if (!input_files && !files_from_option)
       if (!input_files && !files_from_option)
@@ -1353,7 +1357,7 @@ see the file named COPYING for details."));
 		  _("Multiple archive files require `-M' option")));
 		  _("Multiple archive files require `-M' option")));
 
 
   if (listed_incremental_option
   if (listed_incremental_option
-      && newer_mtime_option != TYPE_MINIMUM (time_t))
+      && NEWER_OPTION_INITIALIZED (newer_mtime_option))
     USAGE_ERROR ((0, 0,
     USAGE_ERROR ((0, 0,
 		  _("Cannot combine --listed-incremental with --newer")));
 		  _("Cannot combine --listed-incremental with --newer")));
 
 
@@ -1403,7 +1407,7 @@ see the file named COPYING for details."));
 	  || subcommand_option != DIFF_SUBCOMMAND
 	  || subcommand_option != DIFF_SUBCOMMAND
 	  || subcommand_option != LIST_SUBCOMMAND))
 	  || subcommand_option != LIST_SUBCOMMAND))
     USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives")));
     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 ready to unlink hierarchies, so we are for simpler files.  */
   if (recursive_unlink_option)
   if (recursive_unlink_option)
     old_files_option = UNLINK_FIRST_OLD_FILES;
     old_files_option = UNLINK_FIRST_OLD_FILES;
@@ -1455,10 +1459,12 @@ see the file named COPYING for details."));
 
 
   if (verbose_option && textual_date_option)
   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)
       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.  */
 
 
   decode_options (argc, argv);
   decode_options (argc, argv);
-  name_init (argc, argv);
+  name_init ();
 
 
   /* Main command execution.  */
   /* Main command execution.  */
 
 
@@ -1575,7 +1581,7 @@ tar_stat_init (struct tar_stat_info *st)
 {
 {
   memset (st, 0, sizeof (*st));
   memset (st, 0, sizeof (*st));
 }
 }
-     
+
 void
 void
 tar_stat_destroy (struct tar_stat_info *st)
 tar_stat_destroy (struct tar_stat_info *st)
 {
 {

+ 6 - 6
src/update.c

@@ -1,7 +1,7 @@
 /* Update a tar archive.
 /* 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
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    under the terms of the GNU General Public License as published by the
@@ -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
 /* 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
    stuff to the tape.  This involves seeking back one record and
    re-writing the current record (which has been changed).
    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;
 bool time_to_start_writing;
 
 
@@ -66,7 +66,7 @@ append_file (char *path)
 	{
 	{
 	  union block *start = find_next_block ();
 	  union block *start = find_next_block ();
 	  size_t buffer_size = available_space_after (start);
 	  size_t buffer_size = available_space_after (start);
-	  ssize_t status;
+	  size_t status;
 	  char buf[UINTMAX_STRSIZE_BOUND];
 	  char buf[UINTMAX_STRSIZE_BOUND];
 
 
 	  if (bytes_left < buffer_size)
 	  if (bytes_left < buffer_size)
@@ -78,7 +78,7 @@ append_file (char *path)
 	    }
 	    }
 
 
 	  status = safe_read (handle, start->buffer, buffer_size);
 	  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,
 	    read_fatal_details (path, stat_data.st_size - bytes_left,
 				buffer_size);
 				buffer_size);
 	  if (status == 0)
 	  if (status == 0)
@@ -111,7 +111,7 @@ update_archive (void)
   name_gather ();
   name_gather ();
   open_archive (ACCESS_UPDATE);
   open_archive (ACCESS_UPDATE);
   xheader_write_global ();
   xheader_write_global ();
-  
+
   while (!found_end)
   while (!found_end)
     {
     {
       enum read_header status = read_header (false);
       enum read_header status = read_header (false);

+ 23 - 33
src/utf8.c

@@ -23,11 +23,13 @@
 # include <iconv.h>
 # include <iconv.h>
 #endif
 #endif
 
 
+#ifdef HAVE_LIBICONV
+
 struct langtab
 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
 /* 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",    "TW", "big5"},            /* Chinese */
   { "zh",    NULL, "gb2312"},          /* Chinese */
   { "zh",    NULL, "gb2312"},          /* Chinese */
   { "zu",    NULL, NULL},              /* Zulu */
   { "zu",    NULL, NULL},              /* Zulu */
-  { NULL }
+  { NULL,    NULL, NULL}
 };
 };
 
 
 /* Given the language and (optionally) territory code, return the
 /* Given the language and (optionally) territory code, return the
    default character set for that language. See notes above. */
    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)
   if (!lang)
     return NULL;
     return NULL;
   for (p = langtab; p->lang; p++)
   for (p = langtab; p->lang; p++)
     if (strcasecmp (p->lang, lang) == 0
     if (strcasecmp (p->lang, lang) == 0
-	&& (terr == NULL 
+	&& (terr == NULL
 	    || p->terr == NULL
 	    || p->terr == NULL
 	    || !strcasecmp (p->terr, terr) == 0))
 	    || !strcasecmp (p->terr, terr) == 0))
       return p->charset;
       return p->charset;
@@ -239,7 +241,7 @@ charset_lookup (char *lang, char *terr)
 }
 }
 
 
 static const char *
 static const char *
-get_input_charset ()
+get_input_charset (void)
 {
 {
   const char *charset = NULL;
   const char *charset = NULL;
   char *tmp;
   char *tmp;
@@ -268,30 +270,18 @@ get_input_charset ()
   return charset;
   return charset;
 }
 }
 
 
+#else /* !defined HAVE_LIBICONV */
 
 
-
-#ifndef HAVE_LIBICONV
-
-iconv_t
-iconv_open (const char *tocode, const char *fromcode)
-{
-  return (iconv_t)(-1);
-}
+# undef iconv_open
+# define iconv_open(tocode, fromcode) ((iconv_t) -1)
 
 
-size_t
-iconv (iconv_t cd, ICONV_CONST char **inbuf, size_t *inbytesleft,
-       char **outbuf, size_t *outbytesleft)
-{
-  return 0;
-}
+# undef iconv
+# define iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft) ((size_t) 0)
 
 
-int
-iconv_close (iconv_t cd)
-{
-  return 0;
-}
+# undef iconv_close
+# define iconv_close(cd) 0
 
 
-#endif /* !HAVE_LIBICONV */
+#endif /* !defined HAVE_LIBICONV */
 
 
 
 
 
 
@@ -310,11 +300,11 @@ utf8_init (bool to_utf)
     }
     }
   return conv_desc[(int) to_utf];
   return conv_desc[(int) to_utf];
 }
 }
-		  
+
 bool
 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;
   char *ob;
   size_t inlen;
   size_t inlen;
   size_t outlen;
   size_t outlen;
@@ -332,7 +322,7 @@ utf8_convert(bool to_utf, const char *input, char **output)
   inlen = strlen (input) + 1;
   inlen = strlen (input) + 1;
   outlen = inlen * MB_LEN_MAX + 1;
   outlen = inlen * MB_LEN_MAX + 1;
   ob = *output = xmalloc (outlen);
   ob = *output = xmalloc (outlen);
-  ib = input;
+  ib = (char ICONV_CONST *) input;
   rc = iconv (cd, &ib, &inlen, &ob, &outlen);
   rc = iconv (cd, &ib, &inlen, &ob, &outlen);
   *ob = 0;
   *ob = 0;
   return rc != -1;
   return rc != -1;

+ 84 - 80
src/xheader.c

@@ -18,6 +18,7 @@
 
 
 #include "system.h"
 #include "system.h"
 
 
+#include <fnmatch.h>
 #include <hash.h>
 #include <hash.h>
 #include <quotearg.h>
 #include <quotearg.h>
 #include <xstrtol.h>
 #include <xstrtol.h>
@@ -30,13 +31,14 @@
 
 
 #include <fnmatch.h>
 #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() */
 /* Used by xheader_finish() */
 static void code_string (char const *string, char const *keyword,
 static void code_string (char const *string, char const *keyword,
 			 struct xheader *xhdr);
 			 struct xheader *xhdr);
-static void extended_header_init ();
+static void extended_header_init (void);
 
 
 /* Number of global headers written so far. */
 /* Number of global headers written so far. */
 static size_t global_header_count;
 static size_t global_header_count;
@@ -80,7 +82,7 @@ static char *exthdr_name;
 /* Template for the name field of a 'g' type header */
 /* Template for the name field of a 'g' type header */
 static char *globexthdr_name;
 static char *globexthdr_name;
 
 
-bool
+static bool
 xheader_keyword_deleted_p (const char *kw)
 xheader_keyword_deleted_p (const char *kw)
 {
 {
   struct keyword_list *kp;
   struct keyword_list *kp;
@@ -91,7 +93,7 @@ xheader_keyword_deleted_p (const char *kw)
   return false;
   return false;
 }
 }
 
 
-bool
+static bool
 xheader_keyword_override_p (const char *keyword)
 xheader_keyword_override_p (const char *keyword)
 {
 {
   struct keyword_list *kp;
   struct keyword_list *kp;
@@ -102,7 +104,7 @@ xheader_keyword_override_p (const char *keyword)
   return false;
   return false;
 }
 }
 
 
-void
+static void
 xheader_list_append (struct keyword_list **root, char const *kw,
 xheader_list_append (struct keyword_list **root, char const *kw,
 		     char const *value)
 		     char const *value)
 {
 {
@@ -113,7 +115,7 @@ xheader_list_append (struct keyword_list **root, char const *kw,
   *root = kp;
   *root = kp;
 }
 }
 
 
-void
+static void
 xheader_list_destroy (struct keyword_list **root)
 xheader_list_destroy (struct keyword_list **root)
 {
 {
   if (root)
   if (root)
@@ -130,15 +132,14 @@ xheader_list_destroy (struct keyword_list **root)
       *root = NULL;
       *root = NULL;
     }
     }
 }
 }
-	  
-  
-void
+
+static void
 xheader_set_single_keyword (char *kw)
 xheader_set_single_keyword (char *kw)
 {
 {
   USAGE_ERROR ((0, 0, _("Keyword %s is unknown or not yet imlemented"), 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)
 xheader_set_keyword_equal (char *kw, char *eq)
 {
 {
   bool global = true;
   bool global = true;
@@ -157,7 +158,7 @@ xheader_set_keyword_equal (char *kw, char *eq)
 
 
   for (p = eq + 1; *p && isspace (*p); p++)
   for (p = eq + 1; *p && isspace (*p); p++)
     ;
     ;
-  
+
   if (strcmp (kw, "delete") == 0)
   if (strcmp (kw, "delete") == 0)
     {
     {
       if (xheader_protected_pattern_p (p))
       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);
   size_t len = strlen (fmt);
   char *q;
   char *q;
   const char *p;
   const char *p;
-  char *dirname = NULL;
-  char *basename = NULL;
+  char *dir = NULL;
+  char *base = NULL;
   char pidbuf[64];
   char pidbuf[64];
   char nbuf[64];
   char nbuf[64];
-  
+
   for (p = fmt; *p && (p = strchr (p, '%')); )
   for (p = fmt; *p && (p = strchr (p, '%')); )
     {
     {
       switch (p[1])
       switch (p[1])
@@ -248,25 +249,24 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, bool allow_n)
 	case 'd':
 	case 'd':
 	  if (st)
 	  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;
 	  break;
-	      
+
 	case 'f':
 	case 'f':
 	  if (st)
 	  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;
 	  break;
-	      
+
 	case 'p':
 	case 'p':
 	  to_decimal (getpid (), pidbuf, sizeof pidbuf);
 	  to_decimal (getpid (), pidbuf, sizeof pidbuf);
 	  len += strlen (pidbuf) - 1;
 	  len += strlen (pidbuf) - 1;
 	  break;
 	  break;
-	  
+
 	case 'n':
 	case 'n':
 	  if (allow_n)
 	  if (allow_n)
 	    {
 	    {
@@ -277,7 +277,7 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, bool allow_n)
 	}
 	}
       p++;
       p++;
     }
     }
-  
+
   buf = xmalloc (len + 1);
   buf = xmalloc (len + 1);
   for (q = buf, p = fmt; *p; )
   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++;
 	      *q++ = *p++;
 	      p++;
 	      p++;
 	      break;
 	      break;
-	      
+
 	    case 'd':
 	    case 'd':
-	      if (dirname)
-		q = stpcpy (q, dirname);
+	      if (dir)
+		q = stpcpy (q, dir);
 	      p += 2;
 	      p += 2;
 	      break;
 	      break;
-	      
+
 	    case 'f':
 	    case 'f':
-	      if (basename)
-		q = stpcpy (q, basename);
+	      if (base)
+		q = stpcpy (q, base);
 	      p += 2;
 	      p += 2;
 	      break;
 	      break;
-	      
+
 	    case 'p':
 	    case 'p':
 	      q = stpcpy (q, pidbuf);
 	      q = stpcpy (q, pidbuf);
 	      p += 2;
 	      p += 2;
@@ -314,7 +314,7 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, bool allow_n)
 		  p += 2;
 		  p += 2;
 		}
 		}
 	      /* else fall through */
 	      /* else fall through */
-	      
+
 	    default:
 	    default:
 	      *q++ = *p++;
 	      *q++ = *p++;
 	      if (*p)
 	      if (*p)
@@ -343,7 +343,7 @@ xheader_xhdr_name (struct tar_stat_info *st)
 #define GLOBAL_HEADER_TEMPLATE "/GlobalHead.%p.%n"
 #define GLOBAL_HEADER_TEMPLATE "/GlobalHead.%p.%n"
 
 
 char *
 char *
-xheader_ghdr_name ()
+xheader_ghdr_name (void)
 {
 {
   if (!globexthdr_name)
   if (!globexthdr_name)
     {
     {
@@ -366,7 +366,7 @@ xheader_write (char type, char *name, struct xheader *xhdr)
   union block *header;
   union block *header;
   size_t size;
   size_t size;
   char *p;
   char *p;
-  
+
   size = xhdr->size;
   size = xhdr->size;
   header = start_private_header (name, size);
   header = start_private_header (name, size);
   header->header.typeflag = type;
   header->header.typeflag = type;
@@ -374,11 +374,11 @@ xheader_write (char type, char *name, struct xheader *xhdr)
   simple_finish_header (header);
   simple_finish_header (header);
 
 
   p = xhdr->buffer;
   p = xhdr->buffer;
-  
+
   do
   do
     {
     {
       size_t len;
       size_t len;
-      
+
       header = find_next_block ();
       header = find_next_block ();
       len = BLOCKSIZE;
       len = BLOCKSIZE;
       if (len > size)
       if (len > size)
@@ -392,17 +392,17 @@ xheader_write (char type, char *name, struct xheader *xhdr)
     }
     }
   while (size > 0);
   while (size > 0);
   xheader_destroy (xhdr);
   xheader_destroy (xhdr);
-}  
+}
 
 
 void
 void
-xheader_write_global ()
+xheader_write_global (void)
 {
 {
   char *name;
   char *name;
   struct keyword_list *kp;
   struct keyword_list *kp;
 
 
   if (!keyword_global_override_list)
   if (!keyword_global_override_list)
     return;
     return;
-  
+
   extended_header_init ();
   extended_header_init ();
   for (kp = keyword_global_override_list; kp; kp = kp->next)
   for (kp = keyword_global_override_list; kp; kp = kp->next)
     code_string (kp->value, kp->pattern, &extended_header);
     code_string (kp->value, kp->pattern, &extended_header);
@@ -444,7 +444,7 @@ locate_handler (char const *keyword)
   return NULL;
   return NULL;
 }
 }
 
 
-bool
+static bool
 xheader_protected_pattern_p (const char *pattern)
 xheader_protected_pattern_p (const char *pattern)
 {
 {
   struct xhdr_tab const *p;
   struct xhdr_tab const *p;
@@ -455,7 +455,7 @@ xheader_protected_pattern_p (const char *pattern)
   return false;
   return false;
 }
 }
 
 
-bool
+static bool
 xheader_protected_keyword_p (const char *keyword)
 xheader_protected_keyword_p (const char *keyword)
 {
 {
   struct xhdr_tab const *p;
   struct xhdr_tab const *p;
@@ -534,7 +534,7 @@ decx (void *data, char const *keyword, char const *value)
   if (xheader_keyword_deleted_p (keyword)
   if (xheader_keyword_deleted_p (keyword)
       || xheader_keyword_override_p (keyword))
       || xheader_keyword_override_p (keyword))
     return;
     return;
-  
+
   t = locate_handler (keyword);
   t = locate_handler (keyword);
   if (t)
   if (t)
     t->decoder (st, value);
     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 (keyword_global_override_list, st);
   run_override_list (global_header_override_list, st);
   run_override_list (global_header_override_list, st);
-  
+
   if (extended_header.size)
   if (extended_header.size)
     {
     {
       char *p = extended_header.buffer + BLOCKSIZE;
       char *p = extended_header.buffer + BLOCKSIZE;
       char *endp = &extended_header.buffer[extended_header.size-1];
       char *endp = &extended_header.buffer[extended_header.size-1];
-      
+
       while (p < endp)
       while (p < endp)
 	if (!decode_record (&p, decx, st))
 	if (!decode_record (&p, decx, st))
 	  break;
 	  break;
@@ -566,7 +566,7 @@ decg (void *data, char const *keyword, char const *value)
 }
 }
 
 
 void
 void
-xheader_decode_global ()
+xheader_decode_global (void)
 {
 {
   if (extended_header.size)
   if (extended_header.size)
     {
     {
@@ -581,7 +581,7 @@ xheader_decode_global ()
 }
 }
 
 
 static void
 static void
-extended_header_init ()
+extended_header_init (void)
 {
 {
   if (!extended_header.stk)
   if (!extended_header.stk)
     {
     {
@@ -594,7 +594,7 @@ void
 xheader_store (char const *keyword, struct tar_stat_info const *st, void *data)
 xheader_store (char const *keyword, struct tar_stat_info const *st, void *data)
 {
 {
   struct xhdr_tab const *t;
   struct xhdr_tab const *t;
-  
+
   if (extended_header.buffer)
   if (extended_header.buffer)
     return;
     return;
   t = locate_handler (keyword);
   t = locate_handler (keyword);
@@ -625,7 +625,7 @@ xheader_read (union block *p, size_t size)
 
 
       if (len > BLOCKSIZE)
       if (len > BLOCKSIZE)
 	len = BLOCKSIZE;
 	len = BLOCKSIZE;
-      
+
       memcpy (&extended_header.buffer[j], p->buffer, len);
       memcpy (&extended_header.buffer[j], p->buffer, len);
       set_next_block_after (p);
       set_next_block_after (p);
 
 
@@ -783,19 +783,22 @@ code_num (uintmax_t value, char const *keyword, struct xheader *xhdr)
 }
 }
 
 
 static void
 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
 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
 static void
 atime_coder (struct tar_stat_info const *st, char const *keyword,
 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);
   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
 static void
 gid_coder (struct tar_stat_info const *st, char const *keyword,
 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);
   code_num (st->stat.st_gid, keyword, xhdr);
 }
 }
@@ -823,7 +826,7 @@ gid_decoder (struct tar_stat_info *st, char const *arg)
 
 
 static void
 static void
 gname_coder (struct tar_stat_info const *st, char const *keyword,
 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);
   code_string (st->gname, keyword, xhdr);
 }
 }
@@ -836,7 +839,7 @@ gname_decoder (struct tar_stat_info *st, char const *arg)
 
 
 static void
 static void
 linkpath_coder (struct tar_stat_info const *st, char const *keyword,
 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);
   code_string (st->link_name, keyword, xhdr);
 }
 }
@@ -849,7 +852,7 @@ linkpath_decoder (struct tar_stat_info *st, char const *arg)
 
 
 static void
 static void
 ctime_coder (struct tar_stat_info const *st, char const *keyword,
 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);
   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
 static void
 mtime_coder (struct tar_stat_info const *st, char const *keyword,
 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);
   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
 static void
 path_coder (struct tar_stat_info const *st, char const *keyword,
 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);
   code_string (st->file_name, keyword, xhdr);
 }
 }
@@ -890,7 +893,7 @@ path_decoder (struct tar_stat_info *st, char const *arg)
 
 
 static void
 static void
 size_coder (struct tar_stat_info const *st, char const *keyword,
 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);
   code_num (st->stat.st_size, keyword, xhdr);
 }
 }
@@ -905,7 +908,7 @@ size_decoder (struct tar_stat_info *st, char const *arg)
 
 
 static void
 static void
 uid_coder (struct tar_stat_info const *st, char const *keyword,
 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);
   code_num (st->stat.st_uid, keyword, xhdr);
 }
 }
@@ -920,7 +923,7 @@ uid_decoder (struct tar_stat_info *st, char const *arg)
 
 
 static void
 static void
 uname_coder (struct tar_stat_info const *st, char const *keyword,
 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);
   code_string (st->uname, keyword, xhdr);
 }
 }
@@ -948,7 +951,8 @@ sparse_size_decoder (struct tar_stat_info *st, char const *arg)
 
 
 static void
 static void
 sparse_numblocks_coder (struct tar_stat_info const *st, char const *keyword,
 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);
   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[] = {
 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 */
   /* Sparse file handling */
   { "GNU.sparse.size",       sparse_size_coder, sparse_size_decoder, true },
   { "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
   /* The next directory entry actually contains the names of files
      that were in the directory at the time the dump was made.
      that were in the directory at the time the dump was made.
      Supersedes GNUTYPE_DUMPDIR header type.  */
      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.
   /* Keeps the tape/volume header. May be present only in the global headers.
      Equivalent to GNUTYPE_VOLHDR.  */
      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.
   /* These may be present in a first global header of the archive.
      They provide the same functionality as GNUTYPE_MULTIVOL header.
      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
      otherwise kept in the size field of a multivolume header.  The
      GNU.volume.offset keeps the offset of the start of this volume,
      GNU.volume.offset keeps the offset of the start of this volume,
      otherwise kept in oldgnu_header.offset.  */
      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
 #endif
 
 
-  { NULL, NULL, NULL }
+  { NULL, NULL, NULL, false }
 };
 };

+ 3 - 2
tests/genfile.c

@@ -1,6 +1,6 @@
 /* Generate a file containing some preset patterns.
 /* 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.
    Foundation, Inc.
 
 
    François Pinard <[email protected]>, 1995.
    François Pinard <[email protected]>, 1995.
@@ -54,7 +54,8 @@ static int file_length = 0;
 static enum pattern pattern = DEFAULT_PATTERN;
 static enum pattern pattern = DEFAULT_PATTERN;
 
 
 /* Explain how to use the program, then get out.  */
 /* Explain how to use the program, then get out.  */
-void
+static void usage (int) __attribute__ ((noreturn));
+static void
 usage (int status)
 usage (int status)
 {
 {
   if (status != EXIT_SUCCESS)
   if (status != EXIT_SUCCESS)

+ 21 - 19
tests/mksparse.c

@@ -30,8 +30,10 @@ char *progname;
 char *buffer;
 char *buffer;
 size_t buffer_size;
 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;
   va_list ap;
 
 
@@ -40,12 +42,13 @@ die (char *fmt, ...)
   vfprintf (stderr, fmt, ap);
   vfprintf (stderr, fmt, ap);
   va_end (ap);
   va_end (ap);
   fprintf (stderr, "\n");
   fprintf (stderr, "\n");
+  exit (1);
 }
 }
 
 
-void
+static void
 mkhole (int fd, off_t displ)
 mkhole (int fd, off_t displ)
 {
 {
-  if (displ = lseek (fd, displ, SEEK_CUR) == -1)
+  if (lseek (fd, displ, SEEK_CUR) == -1)
     {
     {
       perror ("lseek");
       perror ("lseek");
       exit (1);
       exit (1);
@@ -53,11 +56,9 @@ mkhole (int fd, off_t displ)
   ftruncate (fd, lseek (fd, 0, SEEK_CUR));
   ftruncate (fd, lseek (fd, 0, SEEK_CUR));
 }
 }
 
 
-void
+static void
 mksparse (int fd, off_t displ, char *marks)
 mksparse (int fd, off_t displ, char *marks)
 {
 {
-  int i;
-
   for (; *marks; marks++)
   for (; *marks; marks++)
     {
     {
       memset (buffer, *marks, buffer_size);
       memset (buffer, *marks, buffer_size);
@@ -66,7 +67,7 @@ mksparse (int fd, off_t displ, char *marks)
 	  perror ("write");
 	  perror ("write");
 	  exit (1);
 	  exit (1);
 	}
 	}
-      
+
       if (lseek (fd, displ, SEEK_CUR) == -1)
       if (lseek (fd, displ, SEEK_CUR) == -1)
 	{
 	{
 	  perror ("lseek");
 	  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");
   printf ("Usage: mksparse filename blocksize disp letters [disp letters...] [disp]\n");
   exit (1);
   exit (1);
 }
 }
 
 
-int
+static int
 xlat_suffix (off_t *vp, char *p)
 xlat_suffix (off_t *vp, char *p)
 {
 {
   if (p[1])
   if (p[1])
@@ -92,7 +94,7 @@ xlat_suffix (off_t *vp, char *p)
     case 'g':
     case 'g':
     case 'G':
     case 'G':
       *vp *= 1024;
       *vp *= 1024;
-      
+
     case 'm':
     case 'm':
     case 'M':
     case 'M':
       *vp *= 1024;
       *vp *= 1024;
@@ -107,7 +109,7 @@ xlat_suffix (off_t *vp, char *p)
     }
     }
   return 0;
   return 0;
 }
 }
-    
+
 int
 int
 main (int argc, char **argv)
 main (int argc, char **argv)
 {
 {
@@ -115,20 +117,20 @@ main (int argc, char **argv)
   int fd;
   int fd;
   char *p;
   char *p;
   off_t n;
   off_t n;
-  
+
   progname = strrchr (argv[0], '/');
   progname = strrchr (argv[0], '/');
   if (progname)
   if (progname)
     progname++;
     progname++;
   else
   else
     progname = argv[0];
     progname = argv[0];
-  
+
   if (argc < 4)
   if (argc < 4)
     usage ();
     usage ();
 
 
   fd = open (argv[1], O_CREAT|O_TRUNC|O_RDWR, 0644);
   fd = open (argv[1], O_CREAT|O_TRUNC|O_RDWR, 0644);
   if (fd < 0)
   if (fd < 0)
     die ("cannot open %s", argv[1]);
     die ("cannot open %s", argv[1]);
-  
+
   n = strtoul (argv[2], &p, 0);
   n = strtoul (argv[2], &p, 0);
   if (n <= 0 || (*p && xlat_suffix (&n, p)))
   if (n <= 0 || (*p && xlat_suffix (&n, p)))
     die ("Invalid buffer size: %s", argv[2]);
     die ("Invalid buffer size: %s", argv[2]);
@@ -136,11 +138,11 @@ main (int argc, char **argv)
   buffer = malloc (buffer_size);
   buffer = malloc (buffer_size);
   if (!buffer)
   if (!buffer)
     die ("Not enough memory");
     die ("Not enough memory");
-  
+
   for (i = 3; i < argc; i += 2)
   for (i = 3; i < argc; i += 2)
     {
     {
       off_t displ;
       off_t displ;
-      
+
       displ = strtoul (argv[i], &p, 0);
       displ = strtoul (argv[i], &p, 0);
       if (displ < 0 || (*p && xlat_suffix (&displ, p)))
       if (displ < 0 || (*p && xlat_suffix (&displ, p)))
 	die ("Invalid displacement: %s", argv[i]);
 	die ("Invalid displacement: %s", argv[i]);
@@ -153,7 +155,7 @@ main (int argc, char **argv)
       else
       else
 	mksparse (fd, displ, argv[i+1]);
 	mksparse (fd, displ, argv[i+1]);
     }
     }
-      
+
   close(fd);
   close(fd);
   return 0;
   return 0;
 }
 }