diff --git a/lib/Makefile.am b/lib/Makefile.am
index b2971a28..cbd71075 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -41,7 +41,6 @@ noinst_HEADERS = \
libtar_a_SOURCES = \
paxerror.c paxexit-status.c paxlib.h paxnames.c \
- prepargs.c prepargs.h \
rtapelib.c \
rmt.h \
stdopen.c stdopen.h \
diff --git a/lib/prepargs.c b/lib/prepargs.c
deleted file mode 100644
index 0c85bd44..00000000
--- a/lib/prepargs.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Parse arguments from a string and prepend them to an argv.
- Copyright 1999-2001, 2007, 2013-2014 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see . */
-
-/* Written by Paul Eggert . */
-
-#ifdef HAVE_CONFIG_H
-# include
-#endif
-#include "prepargs.h"
-#include
-#include
-
-#if HAVE_STRING_H
-# include
-#endif
-
-#include
-
-/* Find the white-space-separated options specified by OPTIONS, and
- using BUF to store copies of these options, set ARGV[0], ARGV[1],
- etc. to the option copies. Return the number N of options found.
- Do not set ARGV[N]. If ARGV is null, do not store ARGV[0]
- etc. Backslash can be used to escape whitespace (and backslashes). */
-static int
-prepend_args (char const *options, char *buf, char **argv)
-{
- char const *o = options;
- char *b = buf;
- int n = 0;
-
- for (;;)
- {
- while (isspace ((unsigned char) *o))
- o++;
- if (!*o)
- return n;
- if (argv)
- argv[n] = b;
- n++;
-
- do
- if ((*b++ = *o++) == '\\' && *o)
- b[-1] = *o++;
- while (*o && ! isspace ((unsigned char) *o));
-
- *b++ = '\0';
- }
-}
-
-/* Prepend the whitespace-separated options in OPTIONS to the argument
- vector of a main program with argument count *PARGC and argument
- vector *PARGV. */
-void
-prepend_default_options (char const *options, int *pargc, char ***pargv)
-{
- if (options)
- {
- char *buf = xmalloc (strlen (options) + 1);
- int prepended = prepend_args (options, buf, (char **) 0);
- int argc = *pargc;
- char * const *argv = *pargv;
- char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp);
- *pargc = prepended + argc;
- *pargv = pp;
- *pp++ = *argv++;
- pp += prepend_args (options, buf, pp);
- while ((*pp++ = *argv++))
- continue;
- }
-}
diff --git a/lib/prepargs.h b/lib/prepargs.h
deleted file mode 100644
index ce93ea87..00000000
--- a/lib/prepargs.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* Parse arguments from a string and prepend them to an argv. */
-
-void prepend_default_options (char const *, int *, char ***);
diff --git a/src/common.h b/src/common.h
index e7911f4b..b2f9c71a 100644
--- a/src/common.h
+++ b/src/common.h
@@ -777,7 +777,26 @@ const char *subcommand_string (enum subcommand c);
void set_exit_status (int val);
void request_stdin (const char *option);
-void more_options (int argc, char **argv);
+
+/* Where an option comes from: */
+enum option_source
+ {
+ OPTS_ENVIRON, /* Environment variable TAR_OPTIONS */
+ OPTS_COMMAND_LINE, /* Command line */
+ OPTS_FILE /* File supplied by --files-from */
+ };
+
+/* Option location */
+struct option_locus
+{
+ enum option_source source; /* Option origin */
+ char const *name; /* File or variable name */
+ size_t line; /* Number of input line if source is OPTS_FILE */
+ struct option_locus *prev; /* Previous occurrence of the option of same
+ class */
+};
+
+void more_options (int argc, char **argv, struct option_locus *loc);
/* Module update.c. */
diff --git a/src/names.c b/src/names.c
index 22118b76..78ad86e7 100644
--- a/src/names.c
+++ b/src/names.c
@@ -227,6 +227,7 @@ struct name_elt /* A name_array element. */
struct /* File, if type == NELT_FILE */
{
const char *name;/* File name */
+ size_t line; /* Input line number */
int term; /* File name terminator in the list */
bool verbatim; /* Verbatim handling of file names: no white-space
trimming, no option processing */
@@ -321,6 +322,7 @@ name_add_file (const char *name, int term, bool verbatim, int matflags)
ep->type = NELT_FILE;
ep->v.file.name = name;
+ ep->v.file.line = 0;
ep->v.file.term = term;
ep->v.file.verbatim = verbatim;
ep->v.file.fp = NULL;
@@ -430,6 +432,7 @@ read_name_from_file (struct name_elt *ent)
FILE *fp = ent->v.file.fp;
int term = ent->v.file.term;
+ ++ent->v.file.line;
for (c = getc (fp); c != EOF && c != term; c = getc (fp))
{
if (counter == name_buffer_length)
@@ -454,11 +457,12 @@ read_name_from_file (struct name_elt *ent)
}
static int
-handle_option (const char *str)
+handle_option (const char *str, struct name_elt const *ent)
{
struct wordsplit ws;
int i;
-
+ struct option_locus loc;
+
while (*str && isspace (*str))
++str;
if (*str != '-')
@@ -469,7 +473,10 @@ handle_option (const char *str)
FATAL_ERROR ((0, 0, _("cannot split string '%s': %s"),
str, wordsplit_strerror (&ws)));
ws.ws_wordv[0] = program_invocation_short_name;
- more_options (ws.ws_wordc+ws.ws_offs, ws.ws_wordv);
+ loc.source = OPTS_FILE;
+ loc.name = ent->v.file.name;
+ loc.line = ent->v.file.line;
+ more_options (ws.ws_wordc+ws.ws_offs, ws.ws_wordv, &loc);
for (i = 0; i < ws.ws_wordc+ws.ws_offs; i++)
ws.ws_wordv[i] = NULL;
@@ -515,7 +522,7 @@ read_next_name (struct name_elt *ent, struct name_elt *ret)
case file_list_success:
if (unquote_option)
unquote_string (name_buffer);
- if (!ent->v.file.verbatim && handle_option (name_buffer) == 0)
+ if (!ent->v.file.verbatim && handle_option (name_buffer, ent) == 0)
{
name_list_adjust ();
return 1;
diff --git a/src/tar.c b/src/tar.c
index f8dd1a74..0036a187 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -45,7 +45,8 @@
#include
#include
#include
-#include
+#include
+#include
#include
#include
#include
@@ -911,6 +912,8 @@ enum wildcards
struct tar_args /* Variables used during option parsing */
{
+ struct option_locus *loc;
+
struct textual_date *textual_date; /* Keeps the arguments to --newer-mtime
and/or --date option if they are
textual dates */
@@ -1009,7 +1012,93 @@ format_default_settings (void)
#endif
);
}
+
+static void
+option_conflict_error (const char *a, const char *b)
+{
+ /* TRANSLATORS: Both %s in this statement are replaced with
+ option names. */
+ USAGE_ERROR ((0, 0, _("'%s' cannot be used with '%s'"), a, b));
+}
+
+/* Classes of options that can conflict: */
+enum option_class
+ {
+ OC_COMPRESS, /* Compress options: -JjZz, -I, etc. */
+ OC_OCCURRENCE, /* --occurrence */
+ OC_LISTED_INCREMENTAL, /* --listed-incremental */
+ OC_NEWER, /* --newer, --newer-mtime, --after-date */
+ OC_VERIFY, /* --verify */
+ OC_STARTING_FILE, /* --starting-file */
+ OC_SAME_ORDER, /* --same-order */
+ OC_ONE_TOP_LEVEL, /* --one-top-level */
+ OC_ABSOLUTE_NAMES, /* --absolute-names */
+ OC_OLD_FILES, /* --keep-old-files, --overwrite, etc. */
+ OC_MAX
+ };
+/* Table of locations of potentially conflicting options. Two options can
+ conflict only if they procede from the command line. Otherwise, options
+ in command line silently override those defined in TAR_OPTIONS. */
+static struct option_locus *option_class[OC_MAX];
+
+/* Save location of an option of class ID. Return location of a previous
+ occurrence of an option of that class, or NULL. */
+static struct option_locus *
+optloc_save (unsigned int id, struct option_locus *loc)
+{
+ struct option_locus *optloc;
+ char *p;
+ size_t s;
+
+ if (id >= sizeof (option_class) / sizeof (option_class[0]))
+ abort ();
+ s = sizeof (*loc);
+ if (loc->name)
+ s += strlen (loc->name) + 1;
+ optloc = xmalloc (s);
+ if (loc->name)
+ {
+ p = (char*) optloc + sizeof (*loc);
+ strcpy (p, loc->name);
+ optloc->name = p;
+ }
+ else
+ optloc->name = NULL;
+ optloc->source = loc->source;
+ optloc->line = loc->line;
+ optloc->prev = option_class[id];
+ option_class[id] = optloc;
+ return optloc->prev;
+}
+
+/* Return location of a recent option of class ID */
+static struct option_locus *
+optloc_lookup (int id)
+{
+ return option_class[id];
+}
+
+/* Return true if the latest occurrence of option ID was in the command line */
+int
+option_set_in_cl (int id)
+{
+ struct option_locus *loc = optloc_lookup (id);
+ if (!loc)
+ return 0;
+ return loc->source == OPTS_COMMAND_LINE;
+}
+
+/* Compare two option locations */
+int
+optloc_eq (struct option_locus *a, struct option_locus *b)
+{
+ if (a->source != b->source)
+ return 0;
+ if (a->source == OPTS_COMMAND_LINE)
+ return 1;
+ return strcmp (a->name, b->name) == 0;
+}
static void
set_subcommand_option (enum subcommand subcommand)
@@ -1023,10 +1112,12 @@ set_subcommand_option (enum subcommand subcommand)
}
static void
-set_use_compress_program_option (const char *string)
+set_use_compress_program_option (const char *string, struct option_locus *loc)
{
+ struct option_locus *p = optloc_save (OC_COMPRESS, loc);
if (use_compress_program_option
- && strcmp (use_compress_program_option, string) != 0)
+ && strcmp (use_compress_program_option, string) != 0
+ && p->source == OPTS_COMMAND_LINE)
USAGE_ERROR ((0, 0, _("Conflicting compression options")));
use_compress_program_option = string;
@@ -1366,12 +1457,33 @@ static int sort_mode_flag[] = {
};
ARGMATCH_VERIFY (sort_mode_arg, sort_mode_flag);
+
+void
+set_old_files_option (int code, struct option_locus *loc)
+{
+ struct option_locus *prev;
+ static char *code_to_opt[] = {
+ "--overwrite-dir",
+ "--no-overwrite-dir",
+ "--overwrite",
+ "--unlink-first",
+ "--keep-old-files",
+ "--skip-old-files",
+ "--keep-newer-files"
+ };
+ prev = optloc_save (OC_OLD_FILES, loc);
+ if (prev && optloc_eq (loc, prev) && code != old_files_option)
+ option_conflict_error (code_to_opt[code], code_to_opt[old_files_option]);
+
+ old_files_option = code;
+}
+
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
struct tar_args *args = state->input;
-
+
switch (key)
{
case ARGP_KEY_ARG:
@@ -1449,6 +1561,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'g':
+ optloc_save (OC_LISTED_INCREMENTAL, args->loc);
listed_incremental_option = arg;
after_date_option = true;
/* Fall through. */
@@ -1479,19 +1592,20 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'j':
- set_use_compress_program_option (BZIP2_PROGRAM);
+ set_use_compress_program_option (BZIP2_PROGRAM, args->loc);
break;
case 'J':
- set_use_compress_program_option (XZ_PROGRAM);
+ set_use_compress_program_option (XZ_PROGRAM, args->loc);
break;
case 'k':
/* Don't replace existing files. */
- old_files_option = KEEP_OLD_FILES;
+ set_old_files_option (KEEP_OLD_FILES, args->loc);
break;
case 'K':
+ optloc_save (OC_STARTING_FILE, args->loc);
starting_file_option = true;
addname (arg, 0, true, NULL);
break;
@@ -1503,6 +1617,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case ONE_TOP_LEVEL_OPTION:
+ optloc_save (OC_ONE_TOP_LEVEL, args->loc);
one_top_level_option = true;
one_top_level_dir = arg;
break;
@@ -1537,15 +1652,15 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case LZIP_OPTION:
- set_use_compress_program_option (LZIP_PROGRAM);
+ set_use_compress_program_option (LZIP_PROGRAM, args->loc);
break;
case LZMA_OPTION:
- set_use_compress_program_option (LZMA_PROGRAM);
+ set_use_compress_program_option (LZMA_PROGRAM, args->loc);
break;
case LZOP_OPTION:
- set_use_compress_program_option (LZOP_PROGRAM);
+ set_use_compress_program_option (LZOP_PROGRAM, args->loc);
break;
case 'm':
@@ -1582,6 +1697,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
get_date_or_file (args,
key == NEWER_MTIME_OPTION ? "--newer-mtime"
: "--after-date", arg, &newer_mtime_option);
+ optloc_save (OC_NEWER, args->loc);
break;
case 'o':
@@ -1597,6 +1713,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'P':
+ optloc_save (OC_ABSOLUTE_NAMES, args->loc);
absolute_names_option = true;
break;
@@ -1617,7 +1734,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
case 's':
/* Names to extract are sorted. */
-
+ optloc_save (OC_SAME_ORDER, args->loc);
same_order_option = true;
break;
@@ -1626,7 +1743,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case SKIP_OLD_FILES_OPTION:
- old_files_option = SKIP_OLD_FILES;
+ set_old_files_option (SKIP_OLD_FILES, args->loc);
break;
case SPARSE_VERSION_OPTION:
@@ -1668,7 +1785,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'U':
- old_files_option = UNLINK_FIRST_OLD_FILES;
+ set_old_files_option (UNLINK_FIRST_OLD_FILES, args->loc);
break;
case UTC_OPTION:
@@ -1689,6 +1806,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'W':
+ optloc_save (OC_VERIFY, args->loc);
verify_option = true;
break;
@@ -1707,11 +1825,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'z':
- set_use_compress_program_option (GZIP_PROGRAM);
+ set_use_compress_program_option (GZIP_PROGRAM, args->loc);
break;
case 'Z':
- set_use_compress_program_option (COMPRESS_PROGRAM);
+ set_use_compress_program_option (COMPRESS_PROGRAM, args->loc);
break;
case ANCHORED_OPTION:
@@ -1859,7 +1977,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case KEEP_NEWER_FILES_OPTION:
- old_files_option = KEEP_NEWER_FILES;
+ set_old_files_option (KEEP_NEWER_FILES, args->loc);
break;
case GROUP_OPTION:
@@ -1899,7 +2017,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case NO_OVERWRITE_DIR_OPTION:
- old_files_option = NO_OVERWRITE_DIR_OLD_FILES;
+ set_old_files_option (NO_OVERWRITE_DIR_OLD_FILES, args->loc);
break;
case NO_QUOTE_CHARS_OPTION:
@@ -1930,6 +2048,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case OCCURRENCE_OPTION:
+ optloc_save (OC_OCCURRENCE, args->loc);
if (!arg)
occurrence_option = 1;
else
@@ -1948,11 +2067,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case OVERWRITE_DIR_OPTION:
- old_files_option = DEFAULT_OLD_FILES;
+ set_old_files_option (DEFAULT_OLD_FILES, args->loc);
break;
case OVERWRITE_OPTION:
- old_files_option = OVERWRITE_OLD_FILES;
+ set_old_files_option (OVERWRITE_OLD_FILES, args->loc);
break;
case OWNER_OPTION:
@@ -1994,6 +2113,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
case PRESERVE_OPTION:
/* FIXME: What it is good for? */
+ optloc_save (OC_SAME_ORDER, args->loc);
same_permissions_option = true;
same_order_option = true;
WARN ((0, 0, _("The --preserve option is deprecated, "
@@ -2097,7 +2217,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'I':
- set_use_compress_program_option (arg);
+ set_use_compress_program_option (arg, args->loc);
break;
case VOLNO_FILE_OPTION:
@@ -2248,6 +2368,14 @@ parse_opt (int key, char *arg, struct argp_state *state)
#endif /* not DEVICE_PREFIX */
+ case ARGP_KEY_ERROR:
+ if (args->loc->source == OPTS_FILE)
+ error (0, 0, _("%s:%lu: location of the error"), args->loc->name,
+ (unsigned long) args->loc->line);
+ else if (args->loc->source == OPTS_ENVIRON)
+ error (0, 0, _("error parsing %s"), args->loc->name);
+ exit (EX_USAGE);
+
default:
return ARGP_ERR_UNKNOWN;
}
@@ -2320,19 +2448,47 @@ static int subcommand_class[] = {
static struct tar_args args;
-static void
-option_conflict_error (const char *a, const char *b)
+void
+more_options (int argc, char **argv, struct option_locus *loc)
{
- /* TRANSLATORS: Both %s in this statement are replaced with
- option names. */
- USAGE_ERROR ((0, 0, _("'%s' cannot be used with '%s'"), a, b));
+ int idx;
+
+ args.loc = loc;
+ if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_EXIT, &idx, &args))
+ abort (); /* shouldn't happen */
+ if (loc->source == OPTS_ENVIRON && args.input_files)
+ USAGE_ERROR ((0, 0, _("non-option arguments in %s"), loc->name));
+}
+
+void
+parse_default_options ()
+{
+ char *opts = getenv ("TAR_OPTIONS");
+ struct wordsplit ws;
+ struct option_locus loc = { OPTS_ENVIRON, "TAR_OPTIONS", 0 };
+
+ if (!opts)
+ return;
+
+ ws.ws_offs = 1;
+ if (wordsplit (opts, &ws, WRDSF_DEFFLAGS|WRDSF_DOOFFS))
+ FATAL_ERROR ((0, 0, _("cannot split TAR_OPTIONS: %s"),
+ wordsplit_strerror (&ws)));
+ if (ws.ws_wordc)
+ {
+ ws.ws_wordv[0] = program_invocation_short_name;
+ more_options (ws.ws_offs + ws.ws_wordc, ws.ws_wordv, &loc);
+ }
+
+ wordsplit_free (&ws);
}
static void
decode_options (int argc, char **argv)
{
int idx;
-
+ struct option_locus loc = { OPTS_COMMAND_LINE };
+
argp_version_setup ("tar", tar_authors);
/* Set some default option values. */
@@ -2429,9 +2585,9 @@ decode_options (int argc, char **argv)
}
/* Parse all options and non-options as they appear. */
+ parse_default_options ();
- prepend_default_options (getenv ("TAR_OPTIONS"), &argc, &argv);
-
+ args.loc = &loc;
if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &idx, &args))
exit (TAREXIT_FAILURE);
@@ -2493,10 +2649,15 @@ decode_options (int argc, char **argv)
USAGE_ERROR ((0, 0,
_("--occurrence is meaningless without a file list")));
if (!IS_SUBCOMMAND_CLASS (SUBCL_OCCUR))
- option_conflict_error ("--occurrence",
- subcommand_string (subcommand_option));
+ {
+ if (option_set_in_cl (OC_OCCURRENCE))
+ option_conflict_error ("--occurrence",
+ subcommand_string (subcommand_option));
+ else
+ occurrence_option = 0;
+ }
}
-
+
if (archive_names == 0)
{
/* If no archive file name given, try TAPE from the environment, or
@@ -2516,7 +2677,16 @@ decode_options (int argc, char **argv)
if (listed_incremental_option
&& NEWER_OPTION_INITIALIZED (newer_mtime_option))
- option_conflict_error ("--listed-incremental", "--newer");
+ {
+ struct option_locus *listed_loc = optloc_lookup (OC_LISTED_INCREMENTAL);
+ struct option_locus *newer_loc = optloc_lookup (OC_NEWER);
+ if (optloc_eq (listed_loc, newer_loc))
+ option_conflict_error ("--listed-incremental", "--newer");
+ else if (listed_loc->source == OPTS_COMMAND_LINE)
+ listed_incremental_option = NULL;
+ else
+ memset (&newer_mtime_option, 0, sizeof (newer_mtime_option));
+ }
if (incremental_level != -1 && !listed_incremental_option)
WARN ((0, 0,
@@ -2554,8 +2724,13 @@ decode_options (int argc, char **argv)
if (use_compress_program_option)
USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
if (!IS_SUBCOMMAND_CLASS (SUBCL_WRITE))
- option_conflict_error ("--verify",
- subcommand_string (subcommand_option));
+ {
+ if (option_set_in_cl (OC_VERIFY))
+ option_conflict_error ("--verify",
+ subcommand_string (subcommand_option));
+ else
+ verify_option = false;
+ }
}
if (use_compress_program_option)
@@ -2595,21 +2770,43 @@ decode_options (int argc, char **argv)
USAGE_ERROR ((0, 0, _("--xattrs can be used only on POSIX archives")));
if (starting_file_option && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
- option_conflict_error ("--starting-file",
- subcommand_string (subcommand_option));
+ {
+ if (option_set_in_cl (OC_STARTING_FILE))
+ option_conflict_error ("--starting-file",
+ subcommand_string (subcommand_option));
+ else
+ starting_file_option = false;
+ }
if (same_order_option && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
- option_conflict_error ("--same-order",
- subcommand_string (subcommand_option));
+ {
+ if (option_set_in_cl (OC_SAME_ORDER))
+ option_conflict_error ("--same-order",
+ subcommand_string (subcommand_option));
+ else
+ same_order_option = false;
+ }
if (one_top_level_option)
{
char *base;
if (absolute_names_option)
- option_conflict_error ("--one-top-level", "--absolute-names");
+ {
+ struct option_locus *one_top_level_loc =
+ optloc_lookup (OC_ONE_TOP_LEVEL);
+ struct option_locus *absolute_names_loc =
+ optloc_lookup (OC_ABSOLUTE_NAMES);
+
+ if (optloc_eq (one_top_level_loc, absolute_names_loc))
+ option_conflict_error ("--one-top-level", "--absolute-names");
+ else if (one_top_level_loc->source == OPTS_COMMAND_LINE)
+ absolute_names_option = false;
+ else
+ one_top_level_option = false;
+ }
- if (!one_top_level_dir)
+ if (one_top_level_option && !one_top_level_dir)
{
/* If the user wants to guarantee that everything is under one
directory, determine its name now and let it be created later. */
@@ -2655,7 +2852,18 @@ decode_options (int argc, char **argv)
USAGE_ERROR ((0, 0, _("Volume length cannot be less than record size")));
if (same_order_option && listed_incremental_option)
- option_conflict_error ("--preserve-order", "--listed-incremental");
+ {
+ struct option_locus *preserve_order_loc = optloc_lookup (OC_SAME_ORDER);
+ struct option_locus *listed_incremental_loc =
+ optloc_lookup (OC_LISTED_INCREMENTAL);
+
+ if (optloc_eq (preserve_order_loc, listed_incremental_loc))
+ option_conflict_error ("--preserve-order", "--listed-incremental");
+ else if (preserve_order_loc->source == OPTS_COMMAND_LINE)
+ listed_incremental_option = false;
+ else
+ same_order_option = false;
+ }
/* Forbid using -c with no input files whatsoever. Check that '-f -',
explicit or implied, is used correctly. */
@@ -2728,14 +2936,6 @@ decode_options (int argc, char **argv)
report_textual_dates (&args);
}
-void
-more_options (int argc, char **argv)
-{
- int idx;
- if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER,
- &idx, &args))
- exit (TAREXIT_FAILURE);
-}
/* Tar proper. */