diff options
author | kientzle <kientzle@FreeBSD.org> | 2009-03-06 05:38:53 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2009-03-06 05:38:53 +0000 |
commit | 3d69c99b9316f975c257cc449ec11a3af8dcef26 (patch) | |
tree | 30bd97786b5dd90090aa13116dbb59a717d128c0 /lib | |
parent | 832acf54b286b99137c88bcba998c90f6a2c6a82 (diff) | |
download | FreeBSD-src-3d69c99b9316f975c257cc449ec11a3af8dcef26.zip FreeBSD-src-3d69c99b9316f975c257cc449ec11a3af8dcef26.tar.gz |
Merge r403,702,721 from libarchive.googlecode.com: Handle odd
pathnames on Windows by mapping '\\' to '/' and converting
illegal characters to '_'.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libarchive/archive_write_disk.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/libarchive/archive_write_disk.c b/lib/libarchive/archive_write_disk.c index b684150..ab43c3f 100644 --- a/lib/libarchive/archive_write_disk.c +++ b/lib/libarchive/archive_write_disk.c @@ -1466,6 +1466,57 @@ check_symlinks(struct archive_write_disk *a) return (ARCHIVE_OK); } +#ifdef _WIN32 +/* + * 1. Convert a path separator from '\' to '/' . + * We shouldn't check multi-byte character directly because some + * character-set have been using the '\' character for a part of + * its multibyte character code. + * 2. Replace unusable characters in Windows with underscore('_'). + * See also : http://msdn.microsoft.com/en-us/library/aa365247.aspx + */ +static void +cleanup_pathname_win(struct archive_write_disk *a) +{ + wchar_t wc; + char *p; + size_t alen, l; + + alen = 0; + l = 0; + for (p = a->name; *p != '\0'; p++) { + ++alen; + if (*p == '\\') + l = 1; + /* Rewrite the path name if its character is a unusable. */ + if (*p == ':' || *p == '*' || *p == '?' || *p == '"' || + *p == '<' || *p == '>' || *p == '|') + *p = '_'; + } + if (alen == 0 || l == 0) + return; + /* + * Convert path separator. + */ + p = a->name; + while (*p != '\0' && alen) { + l = mbtowc(&wc, p, alen); + if (l == -1) { + while (*p != '\0') { + if (*p == '\\') + *p = '/'; + ++p; + } + break; + } + if (l == 1 && wc == L'\\') + *p = '/'; + p += l; + alen -= l; + } +} +#endif + /* * Canonicalize the pathname. In particular, this strips duplicate * '/' characters, '.' elements, and trailing '/'. It also raises an @@ -1485,6 +1536,9 @@ cleanup_pathname(struct archive_write_disk *a) return (ARCHIVE_FAILED); } +#ifdef _WIN32 + cleanup_pathname_win(a); +#endif /* Skip leading '/'. */ if (*src == '/') separator = *src++; |