X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Ftar.c;h=e2df10fca8cb5a98b7d5280bbbe71cb12551242a;hb=c027e039249b82c86eb947cae09a28b50dde30de;hp=f4a36ccef908ce737ff15877509ad1434368d84e;hpb=4c7a2b10b85f7a270f7ff173c30b7e56465a5cf6;p=chaz%2Ftar diff --git a/src/tar.c b/src/tar.c index f4a36cc..e2df10f 100644 --- a/src/tar.c +++ b/src/tar.c @@ -263,6 +263,7 @@ enum INDEX_FILE_OPTION, KEEP_NEWER_FILES_OPTION, MODE_OPTION, + MTIME_OPTION, NEWER_MTIME_OPTION, NO_ANCHORED_OPTION, NO_DELAY_DIRECTORY_RESTORE_OPTION, @@ -300,6 +301,7 @@ enum SHOW_DEFAULTS_OPTION, SHOW_OMITTED_DIRS_OPTION, SHOW_TRANSFORMED_NAMES_OPTION, + SPARSE_VERSION_OPTION, STRIP_COMPONENTS_OPTION, SUFFIX_OPTION, TEST_LABEL_OPTION, @@ -381,6 +383,8 @@ static struct argp_option options[] = { {"sparse", 'S', 0, 0, N_("handle sparse files efficiently"), GRID+1 }, + {"sparse-version", SPARSE_VERSION_OPTION, N_("MAJOR[.MINOR]"), 0, + N_("set version of the sparse format to use"), GRID+1}, {"incremental", 'G', 0, 0, N_("handle old GNU-format incremental backup"), GRID+1 }, {"listed-incremental", 'g', N_("FILE"), 0, @@ -399,7 +403,7 @@ static struct argp_option options[] = { #define GRID 30 {NULL, 0, NULL, 0, - N_("Overwrite control:\n"), GRID+1 }, + N_("Overwrite control:"), GRID+1 }, {"verify", 'W', 0, 0, N_("attempt to verify the archive after writing it"), GRID+1 }, @@ -444,6 +448,8 @@ static struct argp_option options[] = { N_("force NAME as owner for added files"), GRID+1 }, {"group", GROUP_OPTION, N_("NAME"), 0, N_("force NAME as group for added files"), GRID+1 }, + {"mtime", MTIME_OPTION, N_("DATE-OR-FILE"), 0, + N_("set mtime for added files from DATE-OR-FILE"), GRID+1 }, {"mode", MODE_OPTION, N_("CHANGES"), 0, N_("force (symbolic) mode CHANGES for added files"), GRID+1 }, {"atime-preserve", ATIME_PRESERVE_OPTION, @@ -608,10 +614,9 @@ static struct argp_option options[] = { N_("begin at member MEMBER-NAME in the archive"), GRID+1 }, {"newer", 'N', N_("DATE-OR-FILE"), 0, N_("only store files newer than DATE-OR-FILE"), GRID+1 }, + {"after-date", 0, 0, OPTION_ALIAS, NULL, GRID+1 }, {"newer-mtime", NEWER_MTIME_OPTION, N_("DATE"), 0, N_("compare date and time when data changed only"), GRID+1 }, - {"after-date", 'N', N_("DATE"), 0, - N_("same as -N"), GRID+1 }, {"backup", BACKUP_OPTION, N_("CONTROL"), OPTION_ARG_OPTIONAL, N_("backup before removal, choose version CONTROL"), GRID+1 }, {"suffix", SUFFIX_OPTION, N_("STRING"), 0, @@ -625,7 +630,7 @@ static struct argp_option options[] = { N_("strip NUMBER leading components from file names on extraction"), GRID+1 }, {"transform", TRANSFORM_OPTION, N_("EXPRESSION"), 0, - N_("Use sed replace EXPRESSION to transform file names"), GRID+1 }, + N_("use sed replace EXPRESSION to transform file names"), GRID+1 }, #undef GRID #define GRID 95 @@ -743,8 +748,9 @@ enum wildcards struct tar_args /* Variables used during option parsing */ { - char const *textual_date_option; /* Keeps the argument to --newer-mtime - option if it represents a textual date */ + struct textual_date *textual_date; /* Keeps the arguments to --newer-mtime + and/or --date option if they are + textual dates */ enum wildcards wildcards; /* Wildcard settings (--wildcards/ --no-wildcards) */ int matching_flags; /* exclude_fnmatch options */ @@ -876,6 +882,67 @@ set_stat_signal (const char *name) FATAL_ERROR ((0, 0, _("Unknown signal name: %s"), name)); } + +struct textual_date +{ + struct textual_date *next; + struct timespec *ts; + const char *option; + const char *date; +}; + +static void +get_date_or_file (struct tar_args *args, const char *option, + const char *str, struct timespec *ts) +{ + if (FILE_SYSTEM_PREFIX_LEN (str) != 0 + || ISSLASH (*str) + || *str == '.') + { + struct stat st; + if (deref_stat (dereference_option, str, &st) != 0) + { + stat_error (str); + USAGE_ERROR ((0, 0, _("Date sample file not found"))); + } + *ts = get_stat_mtime (&st); + } + else + { + if (! get_date (ts, str, NULL)) + { + WARN ((0, 0, _("Substituting %s for unknown date format %s"), + tartime (*ts, false), quote (str))); + ts->tv_nsec = 0; + } + else + { + struct textual_date *p = xmalloc (sizeof (*p)); + p->ts = ts; + p->option = option; + p->date = str; + p->next = args->textual_date; + args->textual_date = p; + } + } +} + +static void +report_textual_dates (struct tar_args *args) +{ + struct textual_date *p; + for (p = args->textual_date; p; ) + { + struct textual_date *next = p->next; + char const *treated_as = tartime (*p->ts, true); + if (strcmp (p->date, treated_as) != 0) + WARN ((0, 0, _("Option %s: Treating date `%s' as %s"), + p->option, p->date, treated_as)); + free (p); + p = next; + } +} + static volatile int _argp_hang; @@ -1215,6 +1282,11 @@ parse_opt (int key, char *arg, struct argp_state *state) multi_volume_option = true; break; + case MTIME_OPTION: + get_date_or_file (args, "--mtime", arg, &mtime_option); + set_mtime_option = true; + break; + case 'n': seekable_archive = true; break; @@ -1226,31 +1298,9 @@ parse_opt (int key, char *arg, struct argp_state *state) case NEWER_MTIME_OPTION: if (NEWER_OPTION_INITIALIZED (newer_mtime_option)) USAGE_ERROR ((0, 0, _("More than one threshold date"))); - - if (FILE_SYSTEM_PREFIX_LEN (arg) != 0 - || ISSLASH (*arg) - || *arg == '.') - { - struct stat st; - if (deref_stat (dereference_option, arg, &st) != 0) - { - stat_error (arg); - USAGE_ERROR ((0, 0, _("Date sample file not found"))); - } - newer_mtime_option = get_stat_mtime (&st); - } - else - { - if (! get_date (&newer_mtime_option, arg, NULL)) - { - WARN ((0, 0, _("Substituting %s for unknown date format %s"), - tartime (newer_mtime_option, false), quote (arg))); - newer_mtime_option.tv_nsec = 0; - } - else - args->textual_date_option = arg; - } - + get_date_or_file (args, + key == NEWER_MTIME_OPTION ? "--newer-mtime" + : "--after-date", arg, &newer_mtime_option); break; case 'o': @@ -1294,6 +1344,21 @@ parse_opt (int key, char *arg, struct argp_state *state) sparse_option = true; break; + case SPARSE_VERSION_OPTION: + { + char *p; + tar_sparse_major = strtoul (arg, &p, 10); + if (*p) + { + if (*p != '.') + USAGE_ERROR ((0, 0, _("Invalid sparse version value"))); + tar_sparse_minor = strtoul (p + 1, &p, 10); + if (*p) + USAGE_ERROR ((0, 0, _("Invalid sparse version value"))); + } + } + break; + case 't': set_subcommand_option (LIST_SUBCOMMAND); verbose_option++; @@ -1829,7 +1894,7 @@ decode_options (int argc, char **argv) struct tar_args args; /* Set some default option values. */ - args.textual_date_option = NULL; + args.textual_date = NULL; args.wildcards = default_wildcards; args.matching_flags = 0; args.include_anchored = EXCLUDE_ANCHORED; @@ -1838,7 +1903,7 @@ decode_options (int argc, char **argv) args.backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); args.version_control_string = 0; args.input_files = false; - + subcommand_option = UNKNOWN_SUBCOMMAND; archive_format = DEFAULT_FORMAT; blocking_factor = DEFAULT_BLOCKING; @@ -1848,7 +1913,9 @@ decode_options (int argc, char **argv) newer_mtime_option.tv_nsec = -1; recursion_option = FNM_LEADING_DIR; unquote_option = true; - + tar_sparse_major = 1; + tar_sparse_minor = 0; + owner_option = -1; group_option = -1; @@ -2146,13 +2213,8 @@ decode_options (int argc, char **argv) backup_option = false; } - if (verbose_option && args.textual_date_option) - { - char const *treated_as = tartime (newer_mtime_option, true); - if (strcmp (args.textual_date_option, treated_as) != 0) - WARN ((0, 0, _("Treating date `%s' as %s"), - args.textual_date_option, treated_as)); - } + if (verbose_option) + report_textual_dates (&args); }