svn commit: r189436 - head/lib/libarchive
Tim Kientzle
kientzle at FreeBSD.org
Thu Mar 5 21:38:54 PST 2009
Author: kientzle
Date: Fri Mar 6 05:38:53 2009
New Revision: 189436
URL: http://svn.freebsd.org/changeset/base/189436
Log:
Merge r403,702,721 from libarchive.googlecode.com: Handle odd
pathnames on Windows by mapping '\\' to '/' and converting
illegal characters to '_'.
Modified:
head/lib/libarchive/archive_write_disk.c
Modified: head/lib/libarchive/archive_write_disk.c
==============================================================================
--- head/lib/libarchive/archive_write_disk.c Fri Mar 6 05:14:55 2009 (r189435)
+++ head/lib/libarchive/archive_write_disk.c Fri Mar 6 05:38:53 2009 (r189436)
@@ -1466,6 +1466,57 @@ check_symlinks(struct archive_write_disk
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_di
return (ARCHIVE_FAILED);
}
+#ifdef _WIN32
+ cleanup_pathname_win(a);
+#endif
/* Skip leading '/'. */
if (*src == '/')
separator = *src++;
More information about the svn-src-head
mailing list