/* Names from the command call. */
static struct name *namelist; /* first name in list, if any */
-static struct name **nametail = &namelist; /* end of name list */
+static struct name *nametail; /* end of name list */
/* File name arguments are processed in two stages: first a
name_array (see below) is filled, then the names from it
buffer->next = 0;
buffer->found_count = 0;
buffer->matching_flags = matching_flags;
- buffer->dir_contents = NULL;
+ buffer->directory = NULL;
buffer->parent = NULL;
+ buffer->cmdline = true;
- namelist = buffer;
- nametail = &namelist->next;
+ namelist = nametail = buffer;
}
else if (change_dir)
- addname (0, change_dir, NULL);
+ addname (0, change_dir, false, NULL);
}
else
{
change_dir = chdir_arg (xstrdup (ep->v.name));
if (ep)
- addname (ep->v.name, change_dir, NULL);
+ addname (ep->v.name, change_dir, true, NULL);
else
{
if (change_dir != change_dir0)
- addname (0, change_dir, NULL);
+ addname (NULL, change_dir, false, NULL);
break;
}
}
/* Add a name to the namelist. */
struct name *
-addname (char const *string, int change_dir, struct name *parent)
+addname (char const *string, int change_dir, bool cmdline, struct name *parent)
{
struct name *name = make_name (string);
- name->prev = *nametail;
+ name->prev = nametail;
name->next = NULL;
name->found_count = 0;
name->matching_flags = matching_flags;
name->change_dir = change_dir;
- name->dir_contents = NULL;
+ name->directory = NULL;
name->parent = parent;
-
- *nametail = name;
- nametail = &name->next;
+ name->cmdline = cmdline;
+
+ if (nametail)
+ nametail->next = name;
+ else
+ namelist = name;
+ nametail = name;
return name;
}
if ((p = name->next) != NULL)
p->prev = name->prev;
else
- nametail = &name->prev;
+ nametail = name->prev;
}
/* Return true if and only if name FILE_NAME (from an archive) matches any
if (cursor->name[0] == 0)
{
chdir_do (cursor->change_dir);
- namelist = 0;
- nametail = &namelist;
+ namelist = NULL;
+ nametail = NULL;
return true;
}
if (starting_file_option)
{
free (namelist);
- namelist = 0;
- nametail = &namelist;
+ namelist = NULL;
+ nametail = NULL;
}
chdir_do (cursor->change_dir);
struct name const *cursor;
size_t len;
- if (test_label_option)
- return true;
if (!p->file_name || occurrence_option == 0 || p->had_trailing_slash)
return false;
len = strlen (p->file_name);
return true;
}
-static inline int
-is_pattern (const char *string)
-{
- return strchr (string, '*') || strchr (string, '[') || strchr (string, '?');
-}
-
-static void
+static int
regex_usage_warning (const char *name)
{
static int warned_once = 0;
- if (warn_regex_usage && is_pattern (name))
+ if (warn_regex_usage && fnmatch_pattern_has_wildcards (name, 0))
{
warned_once = 1;
WARN ((0, 0,
- /* TRANSLATORS: The following three msgids form a single sentence.
- */
- _("Pattern matching characters used in file names. Please,")));
- WARN ((0, 0,
- _("use --wildcards to enable pattern matching, or --no-wildcards to")));
+ _("Pattern matching characters used in file names")));
WARN ((0, 0,
- _("suppress this warning.")));
+ _("Use --wildcards to enable pattern matching,"
+ " or --no-wildcards to suppress this warning")));
}
+ return warned_once;
}
/* Print the names of things in the namelist that were not matched. */
if (!WASFOUND (cursor) && cursor->name[0])
{
regex_usage_warning (cursor->name);
- if (cursor->found_count == 0)
- ERROR ((0, 0, _("%s: Not found in archive"),
- quotearg_colon (cursor->name)));
- else
- ERROR ((0, 0, _("%s: Required occurrence not found in archive"),
- quotearg_colon (cursor->name)));
+ ERROR ((0, 0,
+ (cursor->found_count == 0) ?
+ _("%s: Not found in archive") :
+ _("%s: Required occurrence not found in archive"),
+ quotearg_colon (cursor->name)));
}
/* Don't bother freeing the name list; we're about to exit. */
- namelist = 0;
- nametail = &namelist;
+ namelist = NULL;
+ nametail = NULL;
if (same_order_option)
{
}
}
}
+
+void
+label_notfound (void)
+{
+ struct name const *cursor;
+
+ if (!namelist)
+ return;
+
+ for (cursor = namelist; cursor; cursor = cursor->next)
+ if (WASFOUND (cursor))
+ return;
+
+ if (verbose_option)
+ error (0, 0, _("Archive label mismatch"));
+ set_exit_status (TAREXIT_DIFFERS);
+
+ for (cursor = namelist; cursor; cursor = cursor->next)
+ {
+ if (regex_usage_warning (cursor->name))
+ break;
+ }
+
+ /* Don't bother freeing the name list; we're about to exit. */
+ namelist = NULL;
+ nametail = NULL;
+
+ if (same_order_option)
+ {
+ const char *name;
+
+ while ((name = name_next (1)) != NULL
+ && regex_usage_warning (name) == 0)
+ ;
+ }
+}
\f
/* Sorting name lists. */
static void
add_hierarchy_to_namelist (struct name *name, dev_t device, bool cmdline)
{
- char *file_name = name->name;
- const char *buffer = scan_directory (file_name, device, cmdline);
+ const char *buffer;
- if (! buffer)
- name->dir_contents = "\0\0\0\0";
- else
+ name_fill_directory (name, device, cmdline);
+ buffer = directory_contents (name->directory);
+ if (buffer)
{
struct name *child_head = NULL, *child_tail = NULL;
size_t name_length = name->length;
size_t string_length;
int change_dir = name->change_dir;
- name->dir_contents = buffer;
- strcpy (namebuf, file_name);
+ strcpy (namebuf, name->name);
if (! ISSLASH (namebuf[name_length - 1]))
{
namebuf[name_length++] = '/';
namebuf = xrealloc (namebuf, allocated_length + 1);
}
strcpy (namebuf + name_length, string + 1);
- np = addname (namebuf, change_dir, name);
+ np = addname (namebuf, change_dir, false, name);
if (!child_head)
child_head = np;
else
child->name = newp;
child->length = size;
- rebase_directory (child->name, old_prefix_len, child->parent->name,
- new_prefix);
+ rebase_directory (child->directory,
+ child->parent->name, old_prefix_len,
+ new_prefix, new_prefix_len);
}
}
collect_and_sort_names (void)
{
struct name *name;
- struct name *next_name, *prev_name;
+ struct name *next_name, *prev_name = NULL;
int num_names;
struct stat statbuf;
Hash_table *nametab;
name_gather ();
if (!namelist)
- addname (".", 0, NULL);
+ addname (".", 0, false, NULL);
if (listed_incremental_option)
{
_("Only one -C option is allowed with "
"--listed-incremental")));
}
- chdir_do (namelist->change_dir);
+
read_directory_file ();
}
num_names = 0;
for (name = namelist; name; name = name->next, num_names++)
{
- if (name->found_count || name->dir_contents)
+ if (name->found_count || name->directory)
continue;
if (name->matching_flags & EXCLUDE_WILDCARDS)
/* NOTE: EXCLUDE_ANCHORED is not relevant here */
prev_name = name;
num_names++;
}
- nametail = &prev_name;
+ nametail = prev_name;
hash_free (nametab);
namelist = merge_sort (namelist, num_names, compare_names_found);
for (name = namelist; name && name->name[0] == 0; name++)
;
if (name)
- name->dir_contents = append_incremental_renames (name->dir_contents);
+ append_incremental_renames (name->directory);
}
}
find and return all the non-found names in the namelist. */
struct name *gnu_list_name;
-char *
-name_from_list (void)
+struct name const *
+name_from_list ()
{
if (!gnu_list_name)
gnu_list_name = namelist;
{
gnu_list_name->found_count++;
chdir_do (gnu_list_name->change_dir);
- return gnu_list_name->name;
+ return gnu_list_name;
}
- return 0;
+ return NULL;
}
void
{
return excluded_file_name (excluded, name + FILE_SYSTEM_PREFIX_LEN (name));
}
-\f
-/* Names to avoid dumping. */
-static Hash_table *avoided_name_table;
-
-/* Remember to not archive NAME. */
-void
-add_avoided_name (char const *name)
-{
- hash_string_insert (&avoided_name_table, name);
-}
-
-/* Should NAME be avoided when archiving? */
-bool
-is_avoided_name (char const *name)
-{
- return hash_string_lookup (avoided_name_table, name);
-}
-
\f
static Hash_table *individual_file_table;