X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2Ftar.c;h=9b73de3cce8c23b9570356fd95a481de9b4fa88d;hb=6f1783ad432c0d2625d1232463987594414089fe;hp=b70ce1b63782e4fc43e2c39ccfcd7d1d9f847046;hpb=6ccb513321e760bf645f1cce09896d382a3afc0e;p=chaz%2Ftar diff --git a/src/tar.c b/src/tar.c index b70ce1b..9b73de3 100644 --- a/src/tar.c +++ b/src/tar.c @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., - 59 Place - Suite 330, Boston, MA 02111-1307, USA. */ + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "system.h" @@ -27,12 +27,7 @@ #define GLOBAL #include "common.h" -#include "backupfile.h" -enum backup_type get_version (); - -/* FIXME: We should use a conversion routine that does reasonable error - checking -- atol doesn't. For now, punt. */ -#define intconv atol +#include "xstrtol.h" time_t get_date (); @@ -50,48 +45,6 @@ static void usage PARAMS ((int)); /* Miscellaneous. */ -/*------------------------------------------------------------------------. -| Check if STRING0 is the decimal representation of number, and store its | -| value. If not a decimal number, return 0. | -`------------------------------------------------------------------------*/ - -static int -check_decimal (const char *string0, uintmax_t *result) -{ - const char *string = string0; - uintmax_t value = 0; - - do - switch (*string) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - uintmax_t v10 = value * 10; - uintmax_t v10d = v10 + (*string - '0'); - if (v10 / 10 != value || v10d < v10) - return 0; - value = v10d; - } - break; - - default: - return 0; - } - while (*++string); - - *result = value; - return 1; -} - /*----------------------------------------------. | Doesn't return if stdin already requested. | `----------------------------------------------*/ @@ -153,39 +106,40 @@ confirm (const char *message_action, const char *message_name) do it. For the others, we share the code for the equivalent short named option, the name of which is stored in the otherwise-unused `val' field of the `struct option'; for long options that have no equivalent - short option, we use nongraphic characters as pseudo short option - characters, starting at 2 and going upwards. */ - -#define BACKUP_OPTION 2 -#define DELETE_OPTION 3 -#define EXCLUDE_OPTION 4 -#define GROUP_OPTION 5 -#define MODE_OPTION 6 -#define NEWER_MTIME_OPTION 7 -#define NO_RECURSE_OPTION 8 -#define NULL_OPTION 9 -#define OWNER_OPTION 10 -#define POSIX_OPTION 11 -#define PRESERVE_OPTION 12 -#define RECORD_SIZE_OPTION 13 -#define RSH_COMMAND_OPTION 14 -#define SUFFIX_OPTION 15 -#define USE_COMPRESS_PROGRAM_OPTION 16 -#define VOLNO_FILE_OPTION 17 - -/* Some cleanup is being made in GNU tar long options. Using old names is - allowed for a while, but will also send a warning to stderr. Take old - names out in 1.14, or in summer 1997, whichever happens last. We use - nongraphic characters as pseudo short option characters, starting at 31 - and going downwards. */ - -#define OBSOLETE_ABSOLUTE_NAMES 31 -#define OBSOLETE_BLOCK_COMPRESS 30 -#define OBSOLETE_BLOCKING_FACTOR 29 -#define OBSOLETE_BLOCK_NUMBER 28 -#define OBSOLETE_READ_FULL_RECORDS 27 -#define OBSOLETE_TOUCH 26 -#define OBSOLETE_VERSION_CONTROL 25 + short option, we use non-characters as pseudo short options, + starting at CHAR_MAX + 1 and going upwards. */ + +enum +{ + BACKUP_OPTION = CHAR_MAX + 1, + DELETE_OPTION, + EXCLUDE_OPTION, + GROUP_OPTION, + MODE_OPTION, + NEWER_MTIME_OPTION, + NO_RECURSE_OPTION, + NULL_OPTION, + OWNER_OPTION, + POSIX_OPTION, + PRESERVE_OPTION, + RECORD_SIZE_OPTION, + RSH_COMMAND_OPTION, + SUFFIX_OPTION, + USE_COMPRESS_PROGRAM_OPTION, + VOLNO_FILE_OPTION, + + /* Some cleanup is being made in GNU tar long options. Using old names is + allowed for a while, but will also send a warning to stderr. Take old + names out in 1.14, or in summer 1997, whichever happens last. */ + + OBSOLETE_ABSOLUTE_NAMES, + OBSOLETE_BLOCK_COMPRESS, + OBSOLETE_BLOCKING_FACTOR, + OBSOLETE_BLOCK_NUMBER, + OBSOLETE_READ_FULL_RECORDS, + OBSOLETE_TOUCH, + OBSOLETE_VERSION_CONTROL +}; /* If nonzero, display usage information and exit. */ static int show_help = 0; @@ -205,8 +159,6 @@ struct option long_options[] = {"block-number", no_argument, NULL, 'R'}, {"block-size", required_argument, NULL, OBSOLETE_BLOCKING_FACTOR}, {"blocking-factor", required_argument, NULL, 'b'}, - {"bunzip2", no_argument, NULL, 'y'}, - {"bzip2", no_argument, NULL, 'y'}, {"catenate", no_argument, NULL, 'A'}, {"checkpoint", no_argument, &checkpoint_option, 1}, {"compare", no_argument, NULL, 'd'}, @@ -219,7 +171,6 @@ struct option long_options[] = {"dereference", no_argument, NULL, 'h'}, {"diff", no_argument, NULL, 'd'}, {"directory", required_argument, NULL, 'C'}, - {"ending-file", required_argument, NULL, 'E'}, {"exclude", required_argument, NULL, EXCLUDE_OPTION}, {"exclude-from", required_argument, NULL, 'X'}, {"extract", no_argument, NULL, 'x'}, @@ -384,7 +335,6 @@ Archive format selection:\n\ PATTERN at list/extract time, a globbing PATTERN\n\ -o, --old-archive, --portability write a V7 format archive\n\ --posix write a POSIX conformant archive\n\ - -y, --bzip2, --bunzip2 filter the archive through bzip2\n\ -z, --gzip, --ungzip filter the archive through gzip\n\ -Z, --compress, --uncompress filter the archive through compress\n\ --use-compress-program=PROG filter through PROG (must accept -d)\n"), @@ -401,7 +351,6 @@ Local file selection:\n\ -h, --dereference dump instead the files symlinks point to\n\ --no-recursion avoid descending automatically in directories\n\ -l, --one-file-system stay in local file system when creating archive\n\ - -E, --ending-file=NAME end reading the archive before file NAME\n\ -K, --starting-file=NAME begin at file NAME in the archive\n"), stdout); #if !MSDOS @@ -446,7 +395,7 @@ or a device. *This* `tar' defaults to `-f%s -b%d'.\n"), DEFAULT_ARCHIVE, DEFAULT_BLOCKING); fputs (_("\ \n\ -Report bugs to .\n"), +Report bugs to .\n"), stdout); } exit (status); @@ -456,13 +405,13 @@ Report bugs to .\n"), | Parse the options for tar. | `----------------------------*/ -/* Available option letters are DHIJQY and aejnqy. Some are reserved: +/* Available option letters are DEHIJQY and aejnqy. Some are reserved: y per-file gzip compression Y per-block gzip compression */ #define OPTION_STRING \ - "-01234567ABC:E:F:GK:L:MN:OPRST:UV:WX:Zb:cdf:g:hiklmoprstuvwxyz" + "-01234567ABC:F:GK:L:MN:OPRST:UV:WX:Zb:cdf:g:hiklmoprstuvwxz" static void set_subcommand_option (enum subcommand subcommand) @@ -490,7 +439,7 @@ decode_options (int argc, char *const *argv) int optchar; /* option letter */ int input_files; /* number of input files */ const char *backup_suffix_string; - const char *version_control_string; + const char *version_control_string = NULL; /* Set some default option values. */ @@ -503,7 +452,6 @@ decode_options (int argc, char *const *argv) group_option = -1; backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); - version_control_string = getenv ("VERSION_CONTROL"); /* Convert old-style tar call by exploding option element and rearranging options accordingly. */ @@ -595,8 +543,14 @@ decode_options (int argc, char *const *argv) /* Fall through. */ case 'b': - blocking_factor = intconv (optarg); - record_size = blocking_factor * (size_t) BLOCKSIZE; + { + long l; + if (! (xstrtol (optarg, (char **) 0, 10, &l, "") == LONGINT_OK + && l == (blocking_factor = l) + && 0 < blocking_factor + && l == (record_size = l * (size_t) BLOCKSIZE) / BLOCKSIZE)) + USAGE_ERROR ((0, 0, _("Invalid blocking factor"))); + } break; case OBSOLETE_READ_FULL_RECORDS: @@ -628,10 +582,6 @@ decode_options (int argc, char *const *argv) set_subcommand_option (DIFF_SUBCOMMAND); break; - case 'E': - ending_file_option = optarg; - break; - case 'f': if (archive_names == allocated_archive_names) { @@ -696,10 +646,15 @@ decode_options (int argc, char *const *argv) break; case 'L': - clear_tarlong (tape_length_option); - add_to_tarlong (tape_length_option, intconv (optarg)); - mult_tarlong (tape_length_option, 1024); - multi_volume_option = 1; + { + unsigned long u; + if (xstrtoul (optarg, (char **) 0, 10, &u, "") != LONG_MAX) + USAGE_ERROR ((0, 0, _("Invalid tape length"))); + clear_tarlong (tape_length_option); + add_to_tarlong (tape_length_option, u); + mult_tarlong (tape_length_option, 1024); + multi_volume_option = 1; + } break; case OBSOLETE_TOUCH: @@ -827,10 +782,6 @@ decode_options (int argc, char *const *argv) add_exclude_file (optarg); break; - case 'y': - set_use_compress_program_option ("bzip2"); - break; - case 'z': set_use_compress_program_option ("gzip"); break; @@ -863,10 +814,11 @@ decode_options (int argc, char *const *argv) && gname_to_gid (optarg, &group_option))) { uintmax_t g; - if (!check_decimal (optarg, &g) || g != (gid_t) g) - ERROR ((TAREXIT_FAILURE, 0, _("Invalid group given on option"))); - else + if (xstrtoumax (optarg, (char **) 0, 10, &g, "") == LONGINT_OK + && g == (gid_t) g) group_option = g; + else + ERROR ((TAREXIT_FAILURE, 0, _("Invalid group given on option"))); } break; @@ -893,10 +845,11 @@ decode_options (int argc, char *const *argv) && uname_to_uid (optarg, &owner_option))) { uintmax_t u; - if (!check_decimal (optarg, &u) || u != (uid_t) u) - ERROR ((TAREXIT_FAILURE, 0, _("Invalid owner given on option"))); - else + if (xstrtoumax (optarg, (char **) 0, 10, &u, "") == LONGINT_OK + && u == (uid_t) u) owner_option = u; + else + ERROR ((TAREXIT_FAILURE, 0, _("Invalid owner given on option"))); } break; @@ -920,11 +873,17 @@ decode_options (int argc, char *const *argv) break; case RECORD_SIZE_OPTION: - record_size = intconv (optarg); - if (record_size % BLOCKSIZE != 0) - USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."), - BLOCKSIZE)); - blocking_factor = record_size / BLOCKSIZE; + { + uintmax_t u; + if (! (xstrtoumax (optarg, (char **) 0, 10, &u, "") == LONG_MAX + && u == (size_t) u)) + USAGE_ERROR ((0, 0, _("Invalid record size"))); + record_size = u; + if (record_size % BLOCKSIZE != 0) + USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."), + BLOCKSIZE)); + blocking_factor = record_size / BLOCKSIZE; + } break; case RSH_COMMAND_OPTION: @@ -1030,7 +989,7 @@ decode_options (int argc, char *const *argv) printf ("tar (GNU %s) %s\n", PACKAGE, VERSION); fputs (_("\ \n\ -Copyright (C) 1988, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.\n"), +Copyright (C) 1988, 92,93,94,95,96,97,98, 1999 Free Software Foundation, Inc.\n"), stdout); fputs (_("\ This is free software; see the source for copying conditions. There is NO\n\ @@ -1130,7 +1089,7 @@ Written by John Gilmore and Jay Fenlason.\n"), simple_backup_suffix = xstrdup (backup_suffix_string); if (backup_option) - backup_type = get_version (version_control_string); + backup_type = xget_version ("--backup", version_control_string); } /* Tar proper. */