[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Bug-tar] broken --remove-files in tar-1.23
From: |
Sergey Poznyakoff |
Subject: |
Re: [Bug-tar] broken --remove-files in tar-1.23 |
Date: |
Tue, 16 Mar 2010 15:51:10 +0200 |
Alexander Kozlov <address@hidden> 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;
}
-
-