]> Dogcows Code - chaz/tar/blobdiff - src/names.c
Fix handling of files removed during incremental dumps.
[chaz/tar] / src / names.c
index eaa94d284aa7257c08970ff877155b1e3542e9aa..16566bb57aeee8f4ce5700f14f6a653eb98f20bf 100644 (file)
@@ -418,14 +418,15 @@ name_gather (void)
          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;
        }
       else if (change_dir)
-       addname (0, change_dir, NULL);
+       addname (0, change_dir, false, NULL);
     }
   else
     {
@@ -439,11 +440,11 @@ name_gather (void)
            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;
            }
        }
@@ -452,7 +453,7 @@ name_gather (void)
 
 /*  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);
 
@@ -461,8 +462,9 @@ addname (char const *string, int change_dir, struct name *parent)
   name->found_count = 0;
   name->matching_flags = matching_flags;
   name->change_dir = change_dir;
-  name->dir_contents = NULL;
+  name->directory = NULL;
   name->parent = parent;
+  name->cmdline = cmdline;
   
   *nametail = name;
   nametail = &name->next;
@@ -767,12 +769,11 @@ compare_names (struct name const *n1, struct name const *n2)
 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;
@@ -785,8 +786,7 @@ add_hierarchy_to_namelist (struct name *name, dev_t device, bool cmdline)
       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++] = '/';
@@ -813,7 +813,7 @@ add_hierarchy_to_namelist (struct name *name, dev_t device, bool cmdline)
                  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
@@ -866,8 +866,9 @@ rebase_child_list (struct name *child, struct name *parent)
       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);
     }
 }
 
@@ -887,7 +888,7 @@ collect_and_sort_names (void)
   name_gather ();
 
   if (!namelist)
-    addname (".", 0, NULL);
+    addname (".", 0, false, NULL);
 
   if (listed_incremental_option)
     {
@@ -912,10 +913,10 @@ collect_and_sort_names (void)
       read_directory_file ();
     }
   
-  for (name = namelist; name; name = next_name)
+  num_names = 0;
+  for (name = namelist; name; name = name->next, num_names++)
     {
-      next_name = name->next;
-      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 */
@@ -934,15 +935,10 @@ collect_and_sort_names (void)
       if (S_ISDIR (statbuf.st_mode))
        {
          name->found_count++;
-         if (name->found_count == 1)
-           add_hierarchy_to_namelist (name, statbuf.st_dev, true);
+         add_hierarchy_to_namelist (name, statbuf.st_dev, true);
        }
     }
 
-  num_names = 0;
-  for (name = namelist; name; name = name->next)
-    num_names++;
-
   namelist = merge_sort (namelist, num_names, compare_names);
 
   num_names = 0;
@@ -980,7 +976,8 @@ collect_and_sort_names (void)
            }
        }
       name->found_count = 0;
-      hash_insert (nametab, name);
+      if (!hash_insert (nametab, name))
+       xalloc_die ();
       prev_name = name;
       num_names++;
     }
@@ -994,7 +991,7 @@ collect_and_sort_names (void)
       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);
     }
 }
 
@@ -1035,8 +1032,8 @@ name_scan (const char *file_name)
    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;
@@ -1047,9 +1044,9 @@ name_from_list (void)
     {
       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
This page took 0.026194 seconds and 4 git commands to generate.