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