+ return false;
+ }
+}
+
+/* Returns true if all names from the namelist were processed.
+ P is the stat_info of the most recently processed entry.
+ The decision is postponed until the next entry is read if:
+
+ 1) P ended with a slash (i.e. it was a directory)
+ 2) P matches any entry from the namelist *and* represents a subdirectory
+ or a file lying under this entry (in the terms of directory structure).
+
+ This is necessary to handle contents of directories. */
+bool
+all_names_found (struct tar_stat_info *p)
+{
+ 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);
+ for (cursor = namelist; cursor; cursor = cursor->next)
+ {
+ if ((cursor->name[0] && !WASFOUND (cursor))
+ || (len >= cursor->length && ISSLASH (p->file_name[cursor->length])))
+ return false;
+ }
+ return true;
+}
+
+static inline int
+is_pattern (const char *string)
+{
+ return strchr (string, '*') || strchr (string, '[') || strchr (string, '?');
+}
+
+static void
+regex_usage_warning (const char *name)
+{
+ static int warned_once = 0;
+
+ if (warn_regex_usage && is_pattern (name))
+ {
+ 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")));
+ WARN ((0, 0,
+ _("suppress this warning.")));