summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2009-03-06 05:38:53 +0000
committerkientzle <kientzle@FreeBSD.org>2009-03-06 05:38:53 +0000
commit3d69c99b9316f975c257cc449ec11a3af8dcef26 (patch)
tree30bd97786b5dd90090aa13116dbb59a717d128c0 /lib
parent832acf54b286b99137c88bcba998c90f6a2c6a82 (diff)
downloadFreeBSD-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.c54
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++;
OpenPOWER on IntegriCloud