X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2Ftar.c;h=10224a9d4bdf21e6f62b9d1b3fcbef8d7e24c315;hb=d1f1e3a18997f3357fe946750d13ab0ce2cc21ef;hp=24b0f90bf72097c17f9dd5da1ca734397968d49c;hpb=5e0e89eac1a00a2edb87ea7b69f1f38c2b1249e1;p=chaz%2Ftar diff --git a/src/tar.c b/src/tar.c index 24b0f90..10224a9 100644 --- a/src/tar.c +++ b/src/tar.c @@ -31,8 +31,8 @@ enum backup_type get_version (); /* FIXME: We should use a conversion routine that does reasonable error - checking -- atoi doesn't. For now, punt. */ -#define intconv atoi + checking -- atol doesn't. For now, punt. */ +#define intconv atol time_t get_date (); @@ -51,16 +51,17 @@ static void usage PARAMS ((int)); /* Miscellaneous. */ /*------------------------------------------------------------------------. -| Check if STRING is the decimal representation of number, and return its | -| value. If not a decimal number, return -1. | +| 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 *string) +check_decimal (const char *string0, uintmax_t *result) { - int value = -1; + const char *string = string0; + uintmax_t value = 0; - while (*string) + do switch (*string) { case '0': @@ -73,14 +74,22 @@ check_decimal (const char *string) case '7': case '8': case '9': - value = value < 0 ? *string - '0' : 10 * value + *string - '0'; - string++; + { + uintmax_t v10 = value * 10; + uintmax_t v10d = v10 + (*string - '0'); + if (v10 / 10 != value || v10d < v10) + return 0; + value = v10d; + } break; default: - return -1; + return 0; } - return value; + while (*++string); + + *result = value; + return 1; } /*----------------------------------------------. @@ -208,6 +217,7 @@ 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'}, @@ -388,6 +398,7 @@ 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 @@ -442,13 +453,13 @@ Report bugs to .\n"), | Parse the options for tar. | `----------------------------*/ -/* Available option letters are DEHIJQY and aejnqy. Some are reserved: +/* Available option letters are DHIJQY and aejnqy. Some are reserved: y per-file gzip compression Y per-block gzip compression */ #define OPTION_STRING \ - "-01234567ABC:F:GK:L:MN:OPRST:UV:WX:Zb:cdf:g:hiklmoprstuvwxz" + "-01234567ABC:E:F:GK:L:MN:OPRST:UV:WX:Zb:cdf:g:hiklmoprstuvwxz" static void set_subcommand_option (enum subcommand subcommand) @@ -580,7 +591,7 @@ decode_options (int argc, char *const *argv) case 'b': blocking_factor = intconv (optarg); - record_size = blocking_factor * BLOCKSIZE; + record_size = blocking_factor * (size_t) BLOCKSIZE; break; case OBSOLETE_READ_FULL_RECORDS: @@ -612,6 +623,10 @@ 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) { @@ -836,10 +851,13 @@ decode_options (int argc, char *const *argv) case GROUP_OPTION: if (!gname_to_gid (optarg, &group_option)) - if (!check_decimal (optarg) >= 0) - ERROR ((TAREXIT_FAILURE, 0, _("Invalid group given on option"))); - else - group_option = check_decimal (optarg); + { + uintmax_t g; + if (!check_decimal (optarg, &g) || g != (gid_t) g) + ERROR ((TAREXIT_FAILURE, 0, _("Invalid group given on option"))); + else + group_option = g; + } break; case MODE_OPTION: @@ -862,10 +880,13 @@ decode_options (int argc, char *const *argv) case OWNER_OPTION: if (!uname_to_uid (optarg, &owner_option)) - if (!check_decimal (optarg) >= 0) - ERROR ((TAREXIT_FAILURE, 0, _("Invalid owner given on option"))); - else - owner_option = check_decimal (optarg); + { + uintmax_t u; + if (!check_decimal (optarg, &u) || u != (uid_t) u) + ERROR ((TAREXIT_FAILURE, 0, _("Invalid owner given on option"))); + else + owner_option = u; + } break; case POSIX_OPTION: