]> Dogcows Code - chaz/tar/commitdiff
(dumpdir_locate,obstack_code_rename,purge_directory): Re-implement renaming. Introduce
authorSergey Poznyakoff <gray@gnu.org.ua>
Thu, 8 Jun 2006 14:43:05 +0000 (14:43 +0000)
committerSergey Poznyakoff <gray@gnu.org.ua>
Thu, 8 Jun 2006 14:43:05 +0000 (14:43 +0000)
X control code.
(make_tmp_dir_name): Remove

src/incremen.c

index 354caf451a69a58704ddeec3b503c07657c9bc07..c0d515dd32860e9240720dc9e084b1cdea900fbc 100644 (file)
@@ -343,11 +343,12 @@ dumpdir_locate (const char *dump, const char *name)
   if (dump)
     while (*dump)
       {
-       /* Ignore 'R' (rename) entries, since they break alphabetical ordering.
+       /* Ignore 'R' (rename) and 'X' (tempname) entries, since they break
+          alphabetical ordering. 
           They normally do not occur in dumpdirs from the snapshot files,
           but this function is also used by purge_directory, which operates
           on a dumpdir from the archive, hence the need for this test. */
-       if (*dump != 'R')
+       if (!strchr ("RX", *dump))
          {
            int rc = strcmp (dump + 1, name);
            if (rc == 0)
@@ -556,49 +557,6 @@ get_directory_contents (char *dir_name, dev_t device)
 }
 
 \f
-static bool
-try_pos (char *name, int pos, const char *dumpdir)
-{
-  int i;
-  static char namechars[] =
-    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-  if (pos > 0)
-    for (i = 0; i < sizeof namechars; i++)
-      {
-       name[pos] = namechars[i];
-       if (!dumpdir_locate (dumpdir, name)
-           || try_pos (name, pos-1, dumpdir))
-         return true;
-      }
-  
-  return false;
-}
-  
-static bool
-create_temp_name (char *name, const char *dumpdir)
-{
-  size_t pos = strlen (name) - 6;
-  return try_pos (name + pos, 5, dumpdir);
-}
-
-char *
-make_tmp_dir_name (const char *name)
-{
-  char *dirname = dir_name (name);
-  char *tmp_name = NULL;
-  struct directory *dir = find_directory (dirname);
-      
-  tmp_name = new_name (dirname, "000000");
-  if (!create_temp_name (tmp_name, dir ? dir->contents : NULL))
-    {
-      free (tmp_name);
-      tmp_name = NULL;
-    }
-  free (dirname);
-  return tmp_name;
-}
-
 static void
 obstack_code_rename (struct obstack *stk, char *from, char *to)
 {
@@ -639,14 +597,17 @@ rename_handler (void *data, void *proc_data)
 
          /* Break the cycle by using a temporary name for one of its
             elements.
-            FIXME: Leave the choice of the name to the extractor. */
-         temp_name = make_tmp_dir_name (dir->name);
-         obstack_code_rename (stk, dir->name, temp_name);
+            First, create a temp name stub entry. */
+         temp_name = dir_name (dir->name);
+         obstack_1grow (stk, 'X');
+         obstack_grow (stk, temp_name, strlen (temp_name) + 1);
+
+         obstack_code_rename (stk, dir->name, "");
 
          for (p = dir; p != prev; p = p->orig)
            obstack_code_rename (stk, p->orig->name, p->name);
 
-         obstack_code_rename (stk, temp_name, prev->name);
+         obstack_code_rename (stk, "", prev->name);
        }
     }
   return true;
@@ -1173,50 +1134,160 @@ is_dumpdir (struct tar_stat_info *stat_info)
   return stat_info->is_dumpdir;
 }
 
+static bool
+dumpdir_ok (char *dumpdir)
+{
+  char *p;
+  int has_tempdir = 0;
+  int expect = 0;
+  
+  for (p = dumpdir; *p; p += strlen (p) + 1)
+    {
+      if (expect && *p != expect)
+       {
+         ERROR ((0, 0,
+                 _("Malformed dumpdir: expected '%c' but found %#3o"),
+                 expect, *p));
+         return false;
+       }
+      switch (*p)
+       {
+       case 'X':
+         if (has_tempdir)
+           {
+             ERROR ((0, 0,
+                     _("Malformed dumpdir: 'X' duplicated")));
+             return false;
+           }
+         else
+           has_tempdir = 1;
+         break;
+         
+       case 'R':
+         if (p[1] == 0)
+           {
+             if (!has_tempdir)
+               {
+                 ERROR ((0, 0,
+                         _("Malformed dumpdir: empty name in 'R'")));
+                 return false;
+               }
+             else
+               has_tempdir = 0;
+           }
+         expect = 'T';
+         break;
+           
+       case 'T':
+         if (expect != 'T')
+           {
+             ERROR ((0, 0,
+                     _("Malformed dumpdir: 'T' not preceeded by 'R'")));
+             return false;
+           }  
+         if (p[1] == 0 && !has_tempdir)
+           {
+             ERROR ((0, 0,
+                     _("Malformed dumpdir: empty name in 'T'")));
+             return false;
+           }
+         expect = 0;
+         break;
+         
+       case 'N':
+       case 'Y':
+       case 'D':
+         break;
+
+       default:
+         /* FIXME: bail out? */
+         break;
+       }
+    }
+
+  if (expect)
+    {
+      ERROR ((0, 0,
+             _("Malformed dumpdir: expected '%c' but found end of data"),
+             expect));
+      return false;
+    }
+
+  if (has_tempdir)
+    WARN ((0, 0, _("Malformed dumpdir: 'X' never used")));
+
+  return true;
+}
+      
 /* Examine the directories under directory_name and delete any
    files that were not there at the time of the back-up. */
-void
-purge_directory (char const *directory_name)
+static bool
+try_purge_directory (char const *directory_name)
 {
   char *current_dir;
   char *cur, *arc, *p;
-
+  char *temp_stub = NULL;
+  
   if (!is_dumpdir (&current_stat_info))
-    {
-      skip_member ();
-      return;
-    }
+    return false;
 
   current_dir = savedir (directory_name);
 
   if (!current_dir)
-    {
-      /* The directory doesn't exist now.  It'll be created.  In any
-        case, we don't have to delete any files out of it.  */
-
-      skip_member ();
-      return;
-    }
-
+    /* The directory doesn't exist now.  It'll be created.  In any
+       case, we don't have to delete any files out of it.  */
+    return false;
+
+  /* Verify if dump directory is sane */
+  if (!dumpdir_ok (current_stat_info.dumpdir))
+    return false;
+       
   /* Process renames */
   for (arc = current_stat_info.dumpdir; *arc; arc += strlen (arc) + 1)
     {
-      if (*arc == 'R')
+      if (*arc == 'X')
+       {
+#define TEMP_DIR_TEMPLATE "tar.XXXXXX"   
+         size_t len = strlen (arc + 1);
+         temp_stub = xrealloc (temp_stub, len + 1 + sizeof TEMP_DIR_TEMPLATE);
+         memcpy (temp_stub, arc + 1, len);
+         temp_stub[len] = '/';
+         memcpy (temp_stub + len + 1, TEMP_DIR_TEMPLATE,
+                 sizeof TEMP_DIR_TEMPLATE);
+         if (!mkdtemp (temp_stub))
+           {
+             ERROR ((0, errno,
+                     _("Cannot create temporary directory using template %s"),
+                     quote (temp_stub)));
+             free (temp_stub);
+             free (current_dir);
+             return false;
+           }
+       }
+      else if (*arc == 'R')
        {
          char *src, *dst;
          src = arc + 1;
          arc += strlen (arc) + 1;
          dst = arc + 1;
 
+         if (*src == 0)
+           src = temp_stub;
+         else if (*dst == 0)
+           dst = temp_stub;
+           
          if (!rename_directory (src, dst))
            {
+             free (temp_stub);
              free (current_dir);
              /* FIXME: Make sure purge_directory(dst) will return
                 immediately */
-             return;
+             return false;
            }
        }
     }
+
+  free (temp_stub);
   
   /* Process deletes */
   p = NULL;
@@ -1267,8 +1338,16 @@ purge_directory (char const *directory_name)
   free (p);
   
   free (current_dir);
+  return true;
 }
 
+void
+purge_directory (char const *directory_name)
+{
+  if (!try_purge_directory (directory_name))
+    skip_member ();
+}
+     
 void
 list_dumpdir (char *buffer, size_t size)
 {
@@ -1281,6 +1360,7 @@ list_dumpdir (char *buffer, size_t size)
        case 'D':
        case 'R':
        case 'T':
+       case 'X':
          fprintf (stdlis, "%c ", *buffer);
          buffer++;
          size--;
This page took 0.033209 seconds and 4 git commands to generate.