+ }
+ namelist = (struct name *) NULL;
+ namelast = (struct name *) NULL;
+
+ if (same_order_option)
+ {
+ char *name;
+
+ while (name = name_next (1), name)
+ ERROR ((0, 0, _("%s: Not found in archive"), name));
+ }
+}
+
+/*---.
+| ? |
+`---*/
+
+void
+name_expand (void)
+{
+}
+
+/*-------------------------------------------------------------------------.
+| This is like name_match, except that it returns a pointer to the name it |
+| matched, and doesn't set FOUND in structure. The caller will have to do |
+| that if it wants to. Oh, and if the namelist is empty, it returns NULL, |
+| unlike name_match, which returns TRUE. |
+`-------------------------------------------------------------------------*/
+
+struct name *
+name_scan (const char *path)
+{
+ size_t length = strlen (path);
+
+ while (1)
+ {
+ struct name *cursor = namelist;
+
+ if (!cursor)
+ return NULL; /* empty namelist is easy */
+
+ for (; cursor; cursor = cursor->next)
+ {
+ /* If first chars don't match, quick skip. */
+
+ if (cursor->firstch && cursor->name[0] != path[0])
+ continue;
+
+ /* Regular expressions. */
+
+ if (cursor->regexp)
+ {
+ if (fnmatch (cursor->name, path, FNM_LEADING_DIR) == 0)
+ return cursor; /* we got a match */
+ continue;
+ }
+
+ /* Plain Old Strings. */
+
+ if (cursor->length <= length
+ /* archive length >= specified */
+ && (path[cursor->length] == '\0'
+ || path[cursor->length] == '/')
+ /* full match on file/dirname */
+ && strncmp (path, cursor->name, cursor->length) == 0)
+ /* name compare */
+ return cursor; /* we got a match */
+ }
+
+ /* Filename from archive not found in namelist. If we have the whole
+ namelist here, just return 0. Otherwise, read the next name in and
+ compare it. If this was the last name, namelist->found will remain
+ on. If not, we loop to compare the newly read name. */
+
+ if (same_order_option && namelist->found)
+ {
+ name_gather (); /* read one more */
+ if (namelist->found)
+ return NULL;
+ }
+ else
+ return NULL;
+ }
+}
+
+/*-----------------------------------------------------------------------.
+| This returns a name from the namelist which doesn't have ->found set. |
+| It sets ->found before returning, so successive calls will find and |
+| return all the non-found names in the namelist |
+`-----------------------------------------------------------------------*/
+
+struct name *gnu_list_name = NULL;
+
+char *
+name_from_list (void)
+{
+ if (!gnu_list_name)
+ gnu_list_name = namelist;
+ while (gnu_list_name && gnu_list_name->found)
+ gnu_list_name = gnu_list_name->next;
+ if (gnu_list_name)
+ {
+ gnu_list_name->found = 1;
+ chdir_from_initial_wd (gnu_list_name->change_dir);
+ return gnu_list_name->name;
+ }
+ return NULL;
+}
+
+/*---.
+| ? |
+`---*/
+
+void
+blank_name_list (void)
+{
+ struct name *name;
+
+ gnu_list_name = 0;
+ for (name = namelist; name; name = name->next)
+ name->found = 0;
+}
+
+/*---.
+| ? |
+`---*/
+
+char *
+new_name (const char *path, const char *name)
+{
+ char *buffer = (char *) xmalloc (strlen (path) + strlen (name) + 2);
+
+ sprintf (buffer, "%s/%s", path, name);
+ return buffer;
+}
+
+/* Return nonzero if file NAME is excluded. Exclude a name if its
+ prefix matches a pattern that contains slashes, or if one of its
+ components matches a pattern that contains no slashes. */
+int
+excluded_name (char const *name)
+{
+ char const *p;
+ name += FILESYSTEM_PREFIX_LEN (name);
+
+ if (excluded_filename (excluded_with_slash, name,
+ FNM_FILE_NAME | FNM_LEADING_DIR))
+ return 1;
+
+ for (p = name; *p; p++)
+ if ((p == name || (ISSLASH (p[-1]) && !ISSLASH (p[0])))
+ && excluded_filename (excluded_without_slash, p,
+ FNM_FILE_NAME | FNM_LEADING_DIR))
+ return 1;
+
+ return 0;
+}