Ignore trailing '/' when comparing pathnames, so that
"tar -u" works again. Otherwise, "tar -u" wants to treat every dir as new and re-adds it.
This commit is contained in:
parent
007c50304b
commit
8d36aa79ef
@ -449,16 +449,39 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry)
|
||||
|
||||
/*
|
||||
* Like strcmp(), but try to be a little more aware of the fact that
|
||||
* we're comparing two paths.
|
||||
* we're comparing two paths. Right now, it just handles leading
|
||||
* "./" and trailing '/' specially, so that "a/b/" == "./a/b"
|
||||
*
|
||||
* TODO: Make this better, so that "./a//b/./c" == "a/b/c"
|
||||
* TODO: Make this better, so that "./a//b/./c/" == "a/b/c"
|
||||
* TODO: After this works, push it down into libarchive.
|
||||
* TODO: Publish the path normalization routines in libarchive so
|
||||
* that bsdtar can normalize paths and use fast strcmp() instead
|
||||
* of this.
|
||||
*/
|
||||
|
||||
int
|
||||
pathcmp(const char *a, const char *b)
|
||||
{
|
||||
/* Skip leading './' */
|
||||
if (a[0] == '.' && a[1] == '/' && a[2] != '\0')
|
||||
a += 2;
|
||||
if (b[0] == '.' && b[1] == '/' && b[2] != '\0')
|
||||
b += 2;
|
||||
return (strcmp(a, b));
|
||||
/* Find the first difference, or return (0) if none. */
|
||||
while (*a == *b) {
|
||||
if (*a == '\0')
|
||||
return (0);
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
/*
|
||||
* If one ends in '/' and the other one doesn't,
|
||||
* they're the same.
|
||||
*/
|
||||
if (a[0] == '/' && a[1] == '\0' && b[0] == '\0')
|
||||
return (0);
|
||||
if (a[0] == '\0' && b[0] == '/' && b[1] == '\0')
|
||||
return (0);
|
||||
/* They're really different, return the correct sign. */
|
||||
return (*(const unsigned char *)a - *(const unsigned char *)b);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user