]> Dogcows Code - chaz/tar/blobdiff - src/names.c
Include full-write.h.
[chaz/tar] / src / names.c
index 72b928003cf8f516f64232e6cc7a47c84e5e2007..202b64dbdebd1a32e023369090d29cf52b820bcb 100644 (file)
@@ -1,5 +1,5 @@
 /* Various processing of names.
-   Copyright 1988, 92, 94, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
+   Copyright 1988,92,94,96,97,98,99,2000, 2001 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
@@ -330,7 +330,7 @@ name_next (int change_dirs)
       /* Zap trailing slashes.  */
 
       cursor = name_buffer + strlen (name_buffer) - 1;
-      while (cursor > name_buffer && *cursor == '/')
+      while (cursor > name_buffer && ISSLASH (*cursor))
        *cursor-- = '\0';
 
       if (chdir_flag)
@@ -487,6 +487,31 @@ addname (char const *string, int change_dir)
   return name;
 }
 
+/* Find a match for PATH (whose string length is LENGTH) in the name
+   list.  */
+static struct name *
+namelist_match (char const *path, size_t length)
+{
+  struct name *p;
+
+  for (p = namelist; p; p = p->next)
+    {
+      /* If first chars don't match, quick skip.  */
+
+      if (p->firstch && p->name[0] != path[0])
+       continue;
+
+      if (p->regexp
+         ? fnmatch (p->name, path, recursion_option) == 0
+         : (p->length <= length
+            && (path[p->length] == '\0' || ISSLASH (path[p->length]))
+            && memcmp (path, p->name, p->length) == 0))
+       return p;
+    }
+
+  return 0;
+}
+
 /* Return true if and only if name PATH (from an archive) matches any
    name from the namelist.  */
 int
@@ -509,32 +534,20 @@ name_match (const char *path)
          return ! files_from_option;
        }
 
-      for (; cursor; cursor = cursor->next)
+      cursor = namelist_match (path, length);
+      if (cursor)
        {
-         /* If first chars don't match, quick skip.  */
-
-         if (cursor->firstch && cursor->name[0] != path[0])
-           continue;
-
-         if (cursor->regexp
-             ? fnmatch (cursor->name, path, FNM_LEADING_DIR) == 0
-             : (cursor->length <= length
-                && (path[cursor->length] == '\0'
-                    || path[cursor->length] == '/')
-                && memcmp (path, cursor->name, cursor->length) == 0))
+         cursor->found = 1; /* remember it matched */
+         if (starting_file_option)
            {
-             cursor->found = 1; /* remember it matched */
-             if (starting_file_option)
-               {
-                 free (namelist);
-                 namelist = 0;
-                 nametail = &namelist;
-               }
-             chdir_do (cursor->change_dir);
-  
-             /* We got a match.  */
-             return 1;
+             free (namelist);
+             namelist = 0;
+             nametail = &namelist;
            }
+         chdir_do (cursor->change_dir);
+  
+         /* We got a match.  */
+         return 1;
        }
 
       /* Filename from archive not found in namelist.  If we have the whole
@@ -557,25 +570,14 @@ name_match (const char *path)
 void
 names_notfound (void)
 {
-  struct name *cursor;
-  struct name *next;
-
-  for (cursor = namelist; cursor; cursor = next)
-    {
-      next = cursor->next;
-      if (!cursor->found && !cursor->fake)
-       ERROR ((0, 0, _("%s: Not found in archive"),
-               quotearg_colon (cursor->name)));
+  struct name const *cursor;
 
-      /* We could free the list, but the process is about to die anyway, so
-        save some CPU time.  Amigas and other similarly broken software
-        will need to waste the time, though.  */
+  for (cursor = namelist; cursor; cursor = cursor->next)
+    if (!cursor->found && !cursor->fake)
+      ERROR ((0, 0, _("%s: Not found in archive"),
+             quotearg_colon (cursor->name)));
 
-#ifdef amiga
-      if (!same_order_option)
-       free (cursor);
-#endif
-    }
+  /* Don't bother freeing the name list; we're about to exit.  */
   namelist = 0;
   nametail = &namelist;
 
@@ -677,15 +679,14 @@ compare_names (struct name const *n1, struct name const *n2)
 }
 \f
 /* Add all the dirs under NAME, which names a directory, to the namelist.
-   DIRSIZE is the size of the directory, or -1 if not known.
    If any of the files is a directory, recurse on the subdirectory.
    DEVICE is the device not to leave, if the -l option is specified.  */
 
 static void
-add_hierarchy_to_namelist (struct name *name, off_t dirsize, dev_t device)
+add_hierarchy_to_namelist (struct name *name, dev_t device)
 {
   char *path = name->name;
-  char *buffer = get_directory_contents (path, dirsize, device);
+  char *buffer = get_directory_contents (path, device);
 
   if (! buffer)
     name->dir_contents = "\0\0\0\0";
@@ -703,7 +704,7 @@ add_hierarchy_to_namelist (struct name *name, off_t dirsize, dev_t device)
 
       name->dir_contents = buffer;
       strcpy (name_buffer, path);
-      if (name_buffer[name_length - 1] != '/')
+      if (! ISSLASH (name_buffer[name_length - 1]))
        {
          name_buffer[name_length++] = '/';
          name_buffer[name_length] = '\0';
@@ -722,7 +723,7 @@ add_hierarchy_to_namelist (struct name *name, off_t dirsize, dev_t device)
                }
              strcpy (name_buffer + name_length, string + 1);
              add_hierarchy_to_namelist (addname (name_buffer, change_dir),
-                                        -1, device);
+                                        device);
            }
        }
 
@@ -769,7 +770,7 @@ collect_and_sort_names (void)
       if (S_ISDIR (statbuf.st_mode))
        {
          name->found = 1;
-         add_hierarchy_to_namelist (name, statbuf.st_size, statbuf.st_dev);
+         add_hierarchy_to_namelist (name, statbuf.st_dev);
        }
     }
 
@@ -793,33 +794,16 @@ name_scan (const char *path)
 
   while (1)
     {
-      struct name *cursor = namelist;
-
-      if (!cursor)
-       return 0;
-
-      for (; cursor; cursor = cursor->next)
-       {
-         /* If first chars don't match, quick skip.  */
-
-         if (cursor->firstch && cursor->name[0] != path[0])
-           continue;
-
-         if (cursor->regexp
-             ? fnmatch (cursor->name, path, FNM_LEADING_DIR) == 0
-             : (cursor->length <= length
-                && (path[cursor->length] == '\0'
-                    || path[cursor->length] == '/')
-                && memcmp (path, cursor->name, cursor->length) == 0))
-           return cursor;      /* we got a match */
-       }
+      struct name *cursor = namelist_match (path, length);
+      if (cursor)
+       return cursor;
 
       /* 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)
+      if (same_order_option && namelist && namelist->found)
        {
          name_gather ();       /* read one more */
          if (namelist->found)
@@ -868,7 +852,7 @@ new_name (const char *path, const char *name)
 {
   size_t pathlen = strlen (path);
   size_t namesize = strlen (name) + 1;
-  int slash = pathlen && path[pathlen - 1] != '/';
+  int slash = pathlen && ! ISSLASH (path[pathlen - 1]);
   char *buffer = xmalloc (pathlen + slash + namesize);
   memcpy (buffer, path, pathlen);
   buffer[pathlen] = '/';
@@ -886,7 +870,7 @@ excluded_name (char const *name)
   name += FILESYSTEM_PREFIX_LEN (name);
 
   if (excluded_filename (excluded_with_slash, name,
-                        FNM_FILE_NAME | FNM_LEADING_DIR))
+                        FNM_FILE_NAME | recursion_option))
     return 1;
 
   for (p = name; *p; p++)
This page took 0.028414 seconds and 4 git commands to generate.