Fix the --add-file option.
* src/common.h (name_more_files): New proto. (files_from_option): Remove. * src/names.c (name_more_files): New file. (names_options): Fix declaration of the add-file option. (names_parse_opt): Handle --add-file. * src/tar.c (struct tar_args): Remove the input_files member. Change all uses: use name_more_files() instead. * tests/Makefile.am: Add new test. * tests/add-file.at: New testcase. * tests/testsuite.at: Add new test.
This commit is contained in:
@@ -414,9 +414,6 @@ GLOBAL bool show_transformed_names_option;
|
||||
timestamps from archives with an unusual member order. It is automatically
|
||||
set for incremental archives. */
|
||||
GLOBAL bool delay_directory_restore_option;
|
||||
|
||||
/* When set, tar will not refuse to create empty archives */
|
||||
GLOBAL bool files_from_option;
|
||||
|
||||
/* Declarations for each module. */
|
||||
|
||||
@@ -738,6 +735,7 @@ void uid_to_uname (uid_t uid, char **uname);
|
||||
int uname_to_uid (char const *uname, uid_t *puid);
|
||||
|
||||
void name_init (void);
|
||||
bool name_more_files (void);
|
||||
void name_add_name (const char *name);
|
||||
void name_term (void);
|
||||
const char *name_next (int change_dirs);
|
||||
|
||||
24
src/names.c
24
src/names.c
@@ -32,7 +32,8 @@ static void name_add_file (const char *name);
|
||||
|
||||
enum
|
||||
{
|
||||
EXCLUDE_BACKUPS_OPTION = 256,
|
||||
ADD_FILE_OPTION = 256,
|
||||
EXCLUDE_BACKUPS_OPTION,
|
||||
EXCLUDE_CACHES_OPTION,
|
||||
EXCLUDE_CACHES_UNDER_OPTION,
|
||||
EXCLUDE_CACHES_ALL_OPTION,
|
||||
@@ -67,7 +68,7 @@ static struct argp_option names_options[] = {
|
||||
{NULL, 0, NULL, 0,
|
||||
N_("Local file name selection:"), GRID },
|
||||
|
||||
{"add-file", ARGP_KEY_ARG, N_("FILE"), 0,
|
||||
{"add-file", ADD_FILE_OPTION, N_("FILE"), 0,
|
||||
N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID+1 },
|
||||
{"directory", 'C', N_("DIR"), 0,
|
||||
N_("change to directory DIR"), GRID+1 },
|
||||
@@ -190,10 +191,10 @@ names_parse_opt (int key, char *arg, struct argp_state *state)
|
||||
|
||||
case 'T':
|
||||
name_add_file (arg);
|
||||
/* Indicate we've been given -T option. This is for backward
|
||||
compatibility only, so that `tar cfT archive /dev/null will
|
||||
succeed */
|
||||
files_from_option = true;
|
||||
break;
|
||||
|
||||
case ADD_FILE_OPTION:
|
||||
name_add_name (arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -651,8 +652,8 @@ struct name_elt /* A name_array element. */
|
||||
} v;
|
||||
};
|
||||
|
||||
static struct name_elt *name_head; /* store a list of names */
|
||||
size_t name_count; /* how many of the entries are names? */
|
||||
static struct name_elt *name_head;/* store a list of names */
|
||||
size_t name_count; /* how many of the entries are file names? */
|
||||
|
||||
static struct name_elt *
|
||||
name_elt_alloc (void)
|
||||
@@ -784,6 +785,12 @@ name_list_advance (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if there are names or options in the list */
|
||||
bool
|
||||
name_more_files (void)
|
||||
{
|
||||
return name_count > 0;
|
||||
}
|
||||
|
||||
/* Add to name_array the file NAME with fnmatch options MATFLAGS */
|
||||
void
|
||||
@@ -823,6 +830,7 @@ name_add_file (const char *name)
|
||||
ep->v.file.name = name;
|
||||
ep->v.file.line = 0;
|
||||
ep->v.file.fp = NULL;
|
||||
name_count++;
|
||||
}
|
||||
|
||||
/* Names from external name file. */
|
||||
|
||||
16
src/tar.c
16
src/tar.c
@@ -813,7 +813,6 @@ struct tar_args /* Variables used during option parsing */
|
||||
bool pax_option; /* True if --pax-option was given */
|
||||
char const *backup_suffix_string; /* --suffix option argument */
|
||||
char const *version_control_string; /* --backup option argument */
|
||||
bool input_files; /* True if some input files where given */
|
||||
int compress_autodetect; /* True if compression autodetection should
|
||||
be attempted when creating archives */
|
||||
};
|
||||
@@ -1322,7 +1321,6 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
||||
case ARGP_KEY_ARG:
|
||||
/* File name or non-parsed option, because of ARGP_IN_ORDER */
|
||||
name_add_name (arg);
|
||||
args->input_files = true;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
@@ -2179,7 +2177,7 @@ more_options (int argc, char **argv, struct option_locus *loc)
|
||||
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)
|
||||
if (loc->source == OPTS_ENVIRON && name_more_files ())
|
||||
USAGE_ERROR ((0, 0, _("non-option arguments in %s"), loc->name));
|
||||
}
|
||||
|
||||
@@ -2221,7 +2219,6 @@ decode_options (int argc, char **argv)
|
||||
args.pax_option = false;
|
||||
args.backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
|
||||
args.version_control_string = 0;
|
||||
args.input_files = false;
|
||||
args.compress_autodetect = false;
|
||||
|
||||
subcommand_option = UNKNOWN_SUBCOMMAND;
|
||||
@@ -2340,10 +2337,7 @@ decode_options (int argc, char **argv)
|
||||
|
||||
/* Handle operands after any "--" argument. */
|
||||
for (; idx < argc; idx++)
|
||||
{
|
||||
name_add_name (argv[idx]);
|
||||
args.input_files = true;
|
||||
}
|
||||
name_add_name (argv[idx]);
|
||||
|
||||
/* Derive option values and check option consistency. */
|
||||
|
||||
@@ -2365,7 +2359,7 @@ decode_options (int argc, char **argv)
|
||||
|
||||
if (occurrence_option)
|
||||
{
|
||||
if (!args.input_files)
|
||||
if (!name_more_files ())
|
||||
USAGE_ERROR ((0, 0,
|
||||
_("--occurrence is meaningless without a file list")));
|
||||
if (!IS_SUBCOMMAND_CLASS (SUBCL_OCCUR))
|
||||
@@ -2569,7 +2563,7 @@ decode_options (int argc, char **argv)
|
||||
{
|
||||
/* --test-label is silent if the user has specified the label name to
|
||||
compare against. */
|
||||
if (!args.input_files)
|
||||
if (!name_more_files ())
|
||||
verbose_option++;
|
||||
}
|
||||
else if (utc_option)
|
||||
@@ -2598,7 +2592,7 @@ decode_options (int argc, char **argv)
|
||||
switch (subcommand_option)
|
||||
{
|
||||
case CREATE_SUBCOMMAND:
|
||||
if (!args.input_files && !files_from_option)
|
||||
if (!name_more_files ())
|
||||
USAGE_ERROR ((0, 0,
|
||||
_("Cowardly refusing to create an empty archive")));
|
||||
if (args.compress_autodetect && archive_names
|
||||
|
||||
@@ -42,6 +42,7 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac
|
||||
## ------------ ##
|
||||
|
||||
TESTSUITE_AT = \
|
||||
testsuite.at\
|
||||
T-cd.at\
|
||||
T-dir00.at\
|
||||
T-dir01.at\
|
||||
@@ -54,7 +55,7 @@ TESTSUITE_AT = \
|
||||
T-nonl.at\
|
||||
T-mult.at\
|
||||
T-nest.at\
|
||||
testsuite.at\
|
||||
add-file.at\
|
||||
append.at\
|
||||
append01.at\
|
||||
append02.at\
|
||||
|
||||
67
tests/add-file.at
Normal file
67
tests/add-file.at
Normal file
@@ -0,0 +1,67 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2016 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU tar.
|
||||
#
|
||||
# GNU tar 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 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# GNU tar 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
AT_SETUP([The --add-file option])
|
||||
AT_KEYWORDS([add-file])
|
||||
|
||||
# Version 1.29 would give "tar: Cowardly refusing to create an empty archive"
|
||||
# if only --add-file arguments were used, and would give "tar: unhandled
|
||||
# positional option 0" when handling the --add-file if at least one file was
|
||||
# also given normally.
|
||||
#
|
||||
# Reported by: James Clarke <jrtc27@jrtc27.com>
|
||||
# References: <20161112000246.77013-1-jrtc27@jrtc27.com>,
|
||||
# http://lists.gnu.org/archive/html/bug-tar/2016-11/msg00013.html
|
||||
|
||||
AT_TAR_CHECK([
|
||||
genfile --file -File
|
||||
genfile --file foo
|
||||
genfile --file bar
|
||||
|
||||
echo 1:
|
||||
tar -cvf arc.tar --add-file foo --add-file -File
|
||||
|
||||
echo 2:
|
||||
tar -cvf arc.tar foo --add-file -File bar
|
||||
|
||||
|
||||
AT_DATA([input],[foo
|
||||
--add-file=-File
|
||||
bar
|
||||
])
|
||||
|
||||
echo 3:
|
||||
tar -cvf arc.tar -T input
|
||||
],
|
||||
[0],
|
||||
[1:
|
||||
foo
|
||||
-File
|
||||
2:
|
||||
foo
|
||||
-File
|
||||
bar
|
||||
3:
|
||||
foo
|
||||
-File
|
||||
bar
|
||||
])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -218,6 +218,7 @@ AT_BANNER([Positional options])
|
||||
m4_include([positional01.at])
|
||||
m4_include([positional02.at])
|
||||
m4_include([positional03.at])
|
||||
m4_include([add-file.at])
|
||||
|
||||
AT_BANNER([The -T option])
|
||||
m4_include([T-mult.at])
|
||||
|
||||
Reference in New Issue
Block a user