case UPDATE_SUBCOMMAND:
return "-u";
- default:
- abort ();
+ case TEST_LABEL_SUBCOMMAND:
+ return "--test-label";
}
+ abort ();
}
void
{"no-auto-compress", NO_AUTO_COMPRESS_OPTION, 0, 0,
N_("do not use archive suffix to determine the compression program"),
GRID+1 },
- {"bzip2", 'j', 0, 0,
- N_("filter the archive through bzip2"), GRID+1 },
- {"gzip", 'z', 0, 0,
- N_("filter the archive through gzip"), GRID+1 },
+ {"use-compress-program", 'I', N_("PROG"), 0,
+ N_("filter through PROG (must accept -d)"), GRID+1 },
+ /* Note: docstrings for the options below are generated by tar_help_filter */
+ {"bzip2", 'j', 0, 0, NULL, GRID+1 },
+ {"gzip", 'z', 0, 0, NULL, GRID+1 },
{"gunzip", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
{"ungzip", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
- {"compress", 'Z', 0, 0,
- N_("filter the archive through compress"), GRID+1 },
+ {"compress", 'Z', 0, 0, NULL, GRID+1 },
{"uncompress", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
- {"lzma", LZMA_OPTION, 0, 0,
- N_("filter the archive through lzma"), GRID+1 },
- {"lzop", LZOP_OPTION, 0, 0,
- N_("filter the archive through lzop"), GRID+8 },
- {"xz", 'J', 0, 0,
- N_("filter the archive through xz"), GRID+8 },
- {"use-compress-program", 'I', N_("PROG"), 0,
- N_("filter through PROG (must accept -d)"), GRID+1 },
+ {"lzma", LZMA_OPTION, 0, 0, NULL, GRID+1 },
+ {"lzop", LZOP_OPTION, 0, 0, NULL, GRID+1 },
+ {"xz", 'J', 0, 0, NULL, GRID+1 },
#undef GRID
#define GRID 100
static char *
format_default_settings (void)
{
- char *s;
-
- asprintf (&s,
+ return xasprintf (
"--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s"
#ifdef REMOTE_SHELL
" --rsh-command=%s"
archive_format_string (DEFAULT_ARCHIVE_FORMAT),
DEFAULT_ARCHIVE, DEFAULT_BLOCKING,
quoting_style_args[DEFAULT_QUOTING_STYLE],
- DEFAULT_RMT_COMMAND,
+ DEFAULT_RMT_COMMAND
#ifdef REMOTE_SHELL
- REMOTE_SHELL
+ , REMOTE_SHELL
#endif
);
- return s;
}
\f
if (subcommand_option != UNKNOWN_SUBCOMMAND
&& subcommand_option != subcommand)
USAGE_ERROR ((0, 0,
- _("You may not specify more than one `-Acdtrux' option")));
+ _("You may not specify more than one `-Acdtrux' or `--test-label' option")));
subcommand_option = subcommand;
}
struct textual_date
{
struct textual_date *next;
- struct timespec *ts;
+ struct timespec ts;
const char *option;
- const char *date;
+ char *date;
};
-static void
+static int
get_date_or_file (struct tar_args *args, const char *option,
const char *str, struct timespec *ts)
{
WARN ((0, 0, _("Substituting %s for unknown date format %s"),
tartime (*ts, false), quote (str)));
ts->tv_nsec = 0;
+ return 1;
}
else
{
struct textual_date *p = xmalloc (sizeof (*p));
- p->ts = ts;
+ p->ts = *ts;
p->option = option;
- p->date = str;
+ p->date = xstrdup (str);
p->next = args->textual_date;
args->textual_date = p;
}
}
+ return 0;
}
static void
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));
+ if (verbose_option)
+ {
+ 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->date);
free (p);
p = next;
}
struct obstack stk;
char *s;
- if (key != ARGP_KEY_HELP_EXTRA)
- return (char*) text;
+ switch (key)
+ {
+ default:
+ s = (char*) text;
+ break;
+
+ case 'j':
+ s = xasprintf (_("filter the archive through %s"), BZIP2_PROGRAM);
+ break;
+
+ case 'z':
+ s = xasprintf (_("filter the archive through %s"), GZIP_PROGRAM);
+ break;
+
+ case 'Z':
+ s = xasprintf (_("filter the archive through %s"), COMPRESS_PROGRAM);
+ break;
+ case LZMA_OPTION:
+ s = xasprintf (_("filter the archive through %s"), LZMA_PROGRAM);
+ break;
+
+ case 'J':
+ s = xasprintf (_("filter the archive through %s"), XZ_PROGRAM);
+ break;
+
+ case ARGP_KEY_HELP_EXTRA:
+ obstack_init (&stk);
+ s = _("Valid arguments for the --quoting-style option are:");
+ obstack_grow (&stk, s, strlen (s));
+ obstack_grow (&stk, "\n\n", 2);
+ tar_list_quoting_styles (&stk, " ");
+ s = _("\n*This* tar defaults to:\n");
+ obstack_grow (&stk, s, strlen (s));
+ s = format_default_settings ();
+ obstack_grow (&stk, s, strlen (s));
+ obstack_1grow (&stk, '\n');
+ obstack_1grow (&stk, 0);
+ s = xstrdup (obstack_finish (&stk));
+ obstack_free (&stk, NULL);
+ }
+ return s;
+}
+\f
+static char *
+expand_pax_option (struct tar_args *targs, const char *arg)
+{
+ struct obstack stk;
+ char *res;
+
obstack_init (&stk);
- s = _("Valid arguments for the --quoting-style option are:");
- obstack_grow (&stk, s, strlen (s));
- obstack_grow (&stk, "\n\n", 2);
- tar_list_quoting_styles (&stk, " ");
- s = _("\n*This* tar defaults to:\n");
- obstack_grow (&stk, s, strlen (s));
- s = format_default_settings ();
- obstack_grow (&stk, s, strlen (s));
- obstack_1grow (&stk, '\n');
+ while (*arg)
+ {
+ size_t seglen = strcspn (arg, ",");
+ char *p = memchr (arg, '=', seglen);
+ if (p)
+ {
+ size_t len = p - arg + 1;
+ obstack_grow (&stk, arg, len);
+ len = seglen - len;
+ for (++p; *p && isspace ((unsigned char) *p); p++)
+ len--;
+ if (*p == '{' && p[len-1] == '}')
+ {
+ struct timespec ts;
+ char *tmp = xmalloc (len);
+ memcpy (tmp, p + 1, len-2);
+ tmp[len-2] = 0;
+ if (get_date_or_file (targs, "--pax-option", tmp, &ts) == 0)
+ {
+ char buf[UINTMAX_STRSIZE_BOUND], *s;
+ s = umaxtostr (ts.tv_sec, buf);
+ obstack_grow (&stk, s, strlen (s));
+ }
+ else
+ obstack_grow (&stk, p, len);
+ free (tmp);
+ }
+ else
+ obstack_grow (&stk, p, len);
+ }
+ else
+ obstack_grow (&stk, arg, seglen);
+
+ arg += seglen;
+ if (*arg)
+ {
+ obstack_1grow (&stk, *arg);
+ arg++;
+ }
+ }
obstack_1grow (&stk, 0);
- s = xstrdup (obstack_finish (&stk));
+ res = xstrdup (obstack_finish (&stk));
obstack_free (&stk, NULL);
- return s;
+ return res;
}
+
\f
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'j':
- set_use_compress_program_option ("bzip2");
+ set_use_compress_program_option (BZIP2_PROGRAM);
break;
case 'J':
- set_use_compress_program_option ("xz");
+ set_use_compress_program_option (XZ_PROGRAM);
break;
case 'k':
break;
case LZMA_OPTION:
- set_use_compress_program_option ("lzma");
+ set_use_compress_program_option (LZMA_PROGRAM);
break;
case LZOP_OPTION:
- set_use_compress_program_option ("lzop");
+ set_use_compress_program_option (LZOP_PROGRAM);
break;
case 'm':
break;
case TEST_LABEL_OPTION:
- set_subcommand_option (LIST_SUBCOMMAND);
- test_label_option = true;
+ set_subcommand_option (TEST_LABEL_SUBCOMMAND);
break;
case 'T':
break;
case 'z':
- set_use_compress_program_option ("gzip");
+ set_use_compress_program_option (GZIP_PROGRAM);
break;
case 'Z':
- set_use_compress_program_option ("compress");
+ set_use_compress_program_option (COMPRESS_PROGRAM);
break;
case ANCHORED_OPTION:
break;
case PAX_OPTION:
- args->pax_option = true;
- xheader_set_option (arg);
+ {
+ char *tmp = expand_pax_option (args, arg);
+ args->pax_option = true;
+ xheader_set_option (tmp);
+ free (tmp);
+ }
break;
case POSIX_OPTION:
old_files_option = UNLINK_FIRST_OLD_FILES;
- if (test_label_option)
+ if (subcommand_option == TEST_LABEL_SUBCOMMAND)
{
/* --test-label is silent if the user has specified the label name to
compare against. */
case EXTRACT_SUBCOMMAND:
case LIST_SUBCOMMAND:
case DIFF_SUBCOMMAND:
+ case TEST_LABEL_SUBCOMMAND:
for (archive_name_cursor = archive_name_array;
archive_name_cursor < archive_name_array + archive_names;
archive_name_cursor++)
checkpoint_finish_compile ();
- if (verbose_option)
- report_textual_dates (&args);
+ report_textual_dates (&args);
}
\f
obstack_init (&argv_stk);
/* Ensure default behavior for some signals */
- signal (SIGPIPE, SIG_DFL);
+ signal (SIGPIPE, SIG_IGN);
/* System V fork+wait does not work if SIGCHLD is ignored. */
signal (SIGCHLD, SIG_DFL);
{
case UNKNOWN_SUBCOMMAND:
USAGE_ERROR ((0, 0,
- _("You must specify one of the `-Acdtrux' options")));
+ _("You must specify one of the `-Acdtrux' or `--test-label' options")));
case CAT_SUBCOMMAND:
case UPDATE_SUBCOMMAND:
diff_init ();
read_and (diff_archive);
break;
+
+ case TEST_LABEL_SUBCOMMAND:
+ test_archive_label ();
}
if (totals_option)