X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Ftar.c;h=ef7652f95c4605ad5e381bfe4c537ce1840c7c8e;hb=5eecc4c994a446f00daa4aa594c57be0c0c37b59;hp=bb0abfe1d18abe039f5aeb13ddded4a324721c7c;hpb=ddb0f96f0004f26f621aba88ae41c70a4c6070fe;p=chaz%2Ftar diff --git a/src/tar.c b/src/tar.c index bb0abfe..ef7652f 100644 --- a/src/tar.c +++ b/src/tar.c @@ -162,7 +162,7 @@ archive_format_string (enum archive_format fmt) static void assert_format(unsigned fmt_mask) { - if ((FORMAT_MASK(archive_format) & fmt_mask) == 0) + if ((FORMAT_MASK (archive_format) & fmt_mask) == 0) USAGE_ERROR ((0, 0, _("GNU features wanted on incompatible archive format"))); } @@ -228,6 +228,7 @@ enum SAME_OWNER_OPTION, SHOW_DEFAULTS_OPTION, SHOW_OMITTED_DIRS_OPTION, + SHOW_STORED_NAMES_OPTION, STRIP_COMPONENTS_OPTION, SUFFIX_OPTION, TEST_LABEL_OPTION, @@ -296,6 +297,8 @@ static struct argp_option options[] = { {"concatenate", 0, 0, OPTION_ALIAS, NULL, 10}, {"delete", DELETE_OPTION, 0, 0, N_("delete from the archive (not on mag tapes!)"), 10 }, + {"test-label", TEST_LABEL_OPTION, NULL, 0, + N_("Test archive volume label and exit"), 10 }, {NULL, 0, NULL, 0, N_("Operation modifiers:"), 20}, @@ -312,9 +315,6 @@ static struct argp_option options[] = { N_("process only the NUMBERth occurrence of each file in the archive. This option is valid only in conjunction with one of the subcommands --delete, --diff, --extract or --list and when a list of files is given either on the command line or via -T option. NUMBER defaults to 1."), 21 }, {"seek", 'n', NULL, 0, N_("archive is seekable"), 21 }, - {"test-label", TEST_LABEL_OPTION, NULL, 0, - N_("List volume label and exit"), 21 }, - {NULL, 0, NULL, 0, N_("Overwrite control:"), 30}, @@ -554,6 +554,9 @@ static struct argp_option options[] = { N_("Show tar defaults"), 102 }, {"show-omitted-dirs", SHOW_OMITTED_DIRS_OPTION, 0, 0, N_("When listing or extracting, list each directory that does not match search criteria"), 102 }, + {"show-stored-names", SHOW_STORED_NAMES_OPTION, 0, 0, + N_("When creating archive in verbose mode, list member names as stored in the archive"), + 102 }, {NULL, 0, NULL, 0, N_("Compatibility options:"), 110 }, @@ -1044,7 +1047,7 @@ parse_opt (int key, char *arg, struct argp_state *state) set_subcommand_option (LIST_SUBCOMMAND); test_label_option = true; break; - + case 'T': update_argv (arg, state); /* Indicate we've been given -T option. This is for backward @@ -1317,6 +1320,10 @@ parse_opt (int key, char *arg, struct argp_state *state) show_omitted_dirs_option = true; break; + case SHOW_STORED_NAMES_OPTION: + show_stored_names_option = true; + break; + case SUFFIX_OPTION: backup_option = true; args->backup_suffix_string = arg; @@ -1660,13 +1667,22 @@ decode_options (int argc, char **argv) archive_format = DEFAULT_ARCHIVE_FORMAT; } + /* FIXME: Merge the four conditionals below */ if (volume_label_option && subcommand_option == CREATE_SUBCOMMAND) assert_format (FORMAT_MASK (OLDGNU_FORMAT) - | FORMAT_MASK (GNU_FORMAT)); + | FORMAT_MASK (GNU_FORMAT) + | FORMAT_MASK (POSIX_FORMAT)); - if (incremental_option || multi_volume_option) - assert_format (FORMAT_MASK (OLDGNU_FORMAT) | FORMAT_MASK (GNU_FORMAT)); + if (incremental_option) + assert_format (FORMAT_MASK (OLDGNU_FORMAT) + | FORMAT_MASK (GNU_FORMAT) + | FORMAT_MASK (POSIX_FORMAT)); + + if (multi_volume_option) + assert_format (FORMAT_MASK (OLDGNU_FORMAT) + | FORMAT_MASK (GNU_FORMAT) + | FORMAT_MASK (POSIX_FORMAT)); if (sparse_option) assert_format (FORMAT_MASK (OLDGNU_FORMAT) @@ -1752,8 +1768,11 @@ decode_options (int argc, char **argv) { if (multi_volume_option) USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives"))); - if (subcommand_option == UPDATE_SUBCOMMAND) + if (subcommand_option == UPDATE_SUBCOMMAND + || subcommand_option == APPEND_SUBCOMMAND) USAGE_ERROR ((0, 0, _("Cannot update compressed archives"))); + if (subcommand_option == CAT_SUBCOMMAND) + USAGE_ERROR ((0, 0, _("Cannot concatenate compressed archives"))); } /* It is no harm to use --pax-option on non-pax archives in archive @@ -1963,5 +1982,20 @@ tar_stat_destroy (struct tar_stat_info *st) free (st->uname); free (st->gname); free (st->sparse_map); + free (st->dumpdir); memset (st, 0, sizeof (*st)); } + +/* Format mask for all available formats that support nanosecond + timestamp resolution. */ +#define NS_PRECISION_FORMAT_MASK FORMAT_MASK (POSIX_FORMAT) + +/* Same as timespec_cmp, but ignore nanoseconds if current archive + format does not provide sufficient resolution. */ +int +tar_timespec_cmp (struct timespec a, struct timespec b) +{ + if (!(FORMAT_MASK (current_format) & NS_PRECISION_FORMAT_MASK)) + a.tv_nsec = b.tv_nsec = 0; + return timespec_cmp (a, b); +}