Alexander Kozlov <[email protected]> ha escrit:

> $ mkdir -p a/b
> $ ln -s b a/c
> $ tar --remove-files -czf a.tar.gz a
> tar: /home/build/tmp/a: Cannot rmdir: Directory not empty
> tar: Exiting with failure status due to previous errors

Thanks for reporting. Please try the attached patch.

Regards,
Sergey

diff --git a/src/misc.c b/src/misc.c
index f81111f..ec93589 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -230,10 +230,99 @@ zap_slashes (char *name)
   return name;
 }
 
+/* Normalize NAME by resolving any relative references and
+   removing trailing slashes.  Destructive version: modifies its argument. */ 
+int
+normalize_filename_x (char *name)
+{
+  char *p, *q;
+
+  p = name;
+  if (DOUBLE_SLASH_IS_DISTINCT_ROOT && *p == '/')
+    p++;
+
+  /* Remove /./, resolve /../ and compress sequences of slashes */
+  for (q = p; *q; )
+    {
+      if (*q == '/')
+	{
+	  *p++ = *q++;
+	  while (*q == '/')
+	    q++;
+	  continue;
+	}
+      else if (p == name)
+	{
+	  if (*q == '.')
+	    {
+	      if (q[1] == '/')
+		{
+		  q += 2;
+		  continue;
+		}
+	      if (q[1] == '.' && q[2] == '/')
+		return 1;
+	    }
+	}
+      else
+	{
+	  if (*q == '.' && p[-1] == '/')
+	    {
+	      if (q[1] == '/')
+		{
+		  q += 2;
+		  while (*q == '/')
+		    q++;
+		  continue;
+		}
+	      else if (q[1] == '.' && q[2] == '/')
+		{
+		  do
+		    {
+		      --p;
+		    }
+		  while (p > name && p[-1] != '/');
+		  q += 3;
+		  continue;
+		}
+	    }
+	}
+      *p++ = *q++;
+    }
+
+  /* Remove trailing slashes */
+  while (p-1 > name && p[-1] == '/')
+    p--;
+  
+  *p = 0;
+  return 0;
+}
+
+/* Normalize NAME by resolving any relative references, removing trailing
+   slashes, and converting it to absolute file name.  Return the normalized
+   name, or NULL in case of error. */
+
 char *
 normalize_filename (const char *name)
 {
-  return zap_slashes (canonicalize_filename_mode (name, CAN_MISSING));
+  char *copy;
+
+  if (name[0] != '/')
+    {
+      copy = xgetcwd ();
+      copy = xrealloc (copy, strlen (copy) + strlen (name) + 2);
+
+      strcat (copy, "/");
+      strcat (copy, name);
+    }
+  else
+    copy = xstrdup (name);
+  if (normalize_filename_x (copy))
+    {
+      free (copy);
+      return NULL;
+    }
+  return xrealloc (copy, strlen (copy) + 1);
 }
 
 
@@ -870,5 +959,3 @@ namebuf_name (namebuf_t buf, const char *name)
   return buf->buffer;
 }
 
-
-  

Reply via email to