Fix semantics of -K used together with explicit member names.
This also fixes the bug reported in http://lists.gnu.org/archive/html/bug-tar/2018-12/msg00012.html * src/common.h (starting_file_option): Describe the variable. * src/names.c (add_starting_file): New function. (name_match): Ignore everything before the member indicated by the --starting-file option * src/tar.c: Use add_starting_file to handle the -K option.
This commit is contained in:
12
NEWS
12
NEWS
@@ -1,4 +1,4 @@
|
||||
GNU tar NEWS - User visible changes. 2018-04-07
|
||||
GNU tar NEWS - User visible changes. 2018-12-21
|
||||
Please send GNU tar bug reports to <bug-tar@gnu.org>
|
||||
|
||||
|
||||
@@ -15,6 +15,16 @@ recognized automatically.
|
||||
When '-a' option is in effect, zstd compression is selected if the
|
||||
destination archive name ends in '.zst' or '.tzst'.
|
||||
|
||||
* The -K option interacts properly with member names given in the command line
|
||||
|
||||
Names of members to extract can be specified along with the "-K NAME"
|
||||
option. In this case, tar will extract NAME and those of named members
|
||||
that appear in the archive after it, which is consistent with the
|
||||
semantics of the option.
|
||||
|
||||
Previous versions of tar extracted NAME, those of named members that
|
||||
appeared before it, and everything after it.
|
||||
|
||||
|
||||
version 1.30 - Sergey Poznyakoff, 2017-12-17
|
||||
|
||||
|
||||
@@ -302,6 +302,10 @@ enum hole_detection_method
|
||||
|
||||
GLOBAL enum hole_detection_method hole_detection;
|
||||
|
||||
/* The first entry in names.c:namelist specifies the member name to
|
||||
start extracting from. Set by add_starting_file() upon seeing the
|
||||
-K option.
|
||||
*/
|
||||
GLOBAL bool starting_file_option;
|
||||
|
||||
/* Specified maximum byte length of each tape volume (multiple of 1024). */
|
||||
@@ -752,6 +756,7 @@ const char *name_next (int change_dirs);
|
||||
void name_gather (void);
|
||||
struct name *addname (char const *string, int change_dir,
|
||||
bool cmdline, struct name *parent);
|
||||
void add_starting_file (char const *file_name);
|
||||
void remname (struct name *name);
|
||||
bool name_match (const char *name);
|
||||
void names_notfound (void);
|
||||
|
||||
45
src/names.c
45
src/names.c
@@ -1227,6 +1227,34 @@ addname (char const *string, int change_dir, bool cmdline, struct name *parent)
|
||||
return name;
|
||||
}
|
||||
|
||||
void
|
||||
add_starting_file (char const *file_name)
|
||||
{
|
||||
struct name *name = make_name (file_name);
|
||||
|
||||
if (starting_file_option)
|
||||
{
|
||||
struct name *head = namelist;
|
||||
remname (head);
|
||||
free_name (head);
|
||||
}
|
||||
|
||||
name->prev = NULL;
|
||||
name->next = namelist;
|
||||
namelist = name;
|
||||
if (!nametail)
|
||||
nametail = namelist;
|
||||
|
||||
name->found_count = 0;
|
||||
name->matching_flags = INCLUDE_OPTIONS;
|
||||
name->change_dir = 0;
|
||||
name->directory = NULL;
|
||||
name->parent = NULL;
|
||||
name->cmdline = true;
|
||||
|
||||
starting_file_option = true;
|
||||
}
|
||||
|
||||
/* Find a match for FILE_NAME (whose string length is LENGTH) in the name
|
||||
list. */
|
||||
static struct name *
|
||||
@@ -1283,19 +1311,22 @@ name_match (const char *file_name)
|
||||
}
|
||||
|
||||
cursor = namelist_match (file_name, length);
|
||||
if (starting_file_option)
|
||||
{
|
||||
/* If starting_file_option is set, the head of the list is the name
|
||||
of the member to start extraction from. Skip the match unless it
|
||||
is head. */
|
||||
if (cursor == namelist)
|
||||
starting_file_option = false;
|
||||
else
|
||||
cursor = NULL;
|
||||
}
|
||||
if (cursor)
|
||||
{
|
||||
if (!(ISSLASH (file_name[cursor->length]) && recursion_option)
|
||||
|| cursor->found_count == 0)
|
||||
cursor->found_count++; /* remember it matched */
|
||||
if (starting_file_option)
|
||||
{
|
||||
free (namelist);
|
||||
namelist = NULL;
|
||||
nametail = NULL;
|
||||
}
|
||||
chdir_do (cursor->change_dir);
|
||||
|
||||
/* We got a match. */
|
||||
return ISFOUND (cursor);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user