]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Simplify that clean up path name characters in Windows.
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Tue, 3 Mar 2009 07:32:55 +0000 (02:32 -0500)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Tue, 3 Mar 2009 07:32:55 +0000 (02:32 -0500)
SVN-Revision: 721

libarchive/archive_windows.h
libarchive/archive_write_disk.c

index 7c326a99a3734ad8a7cfa3fe88ba5b2bfa7e0b13..42502029dc607ea1612e88b457e6614b96895a87 100644 (file)
@@ -260,8 +260,6 @@ struct _timeval64i32 {
 
 typedef int pid_t;
 
-#define SYSTEM_PATH_CHAR       '\\'
-
 /* Message digest define */
 #if !defined(HAVE_OPENSSL_MD5_H) && !defined(HAVE_OPENSSL_SHA_H)
 typedef struct {
index 0709df7257bbdd732c199502c6dce094f8869c3a..0c8cadace1a28dcc16f0a27eb273749e5be8b4da 100644 (file)
@@ -1472,59 +1472,55 @@ check_symlinks(struct archive_write_disk *a)
        return (ARCHIVE_OK);
 }
 
-#if defined(SYSTEM_PATH_CHAR) && SYSTEM_PATH_CHAR != '/'
-/* Convert a path separator of the running system to '/' .
- * We shouldn't check multi-byte character directly because some charsets
- * are using a character of the path separator for a part of their charset.
+#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_path_separator(struct archive_write_disk *a)
+cleanup_pathname_win(struct archive_write_disk *a)
 {
-       wchar_t *ws, wpath_char;
-       size_t alen, i, l;
-       int replaced;
-       char path_char;
-
-       if ((alen = strlen(a->name)) == 0)
-               return;
-       /* pre-check to reduce malloc and free */
-       if (strchr(a->name, SYSTEM_PATH_CHAR) == NULL)
-               return;
-       path_char = SYSTEM_PATH_CHAR;
-       if (mbtowc(&wpath_char, &path_char, 1) != 1)
+       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;
-       ws = malloc((alen + 1)* sizeof(wchar_t));
-       if (ws == NULL)
-               __archive_errx(1, "Out of memory");
-       l = mbstowcs(ws, a->name, alen);
-       if (l == (size_t)-1) {
-               /* We cannot check path separator */
-               free(ws);
-               return;
-       }
-       ws[l] = L'\0';
-       replaced = 0;
-       for (i = 0; i < l; i++) {
-               if (ws[i] == wpath_char) {
-                       ws[i] = L'/';
-                       replaced = 1;
+       /*
+        * 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;
        }
-       if (replaced) {
-               char *p;
-
-               p = malloc(alen + 1);
-               if (p == NULL)
-                       __archive_errx(1, "Out of memory");
-               l = wcstombs(p, ws, alen);
-               if (l == alen)
-                       memcpy(a->name, p, l);
-               free(p);
-       }
-       free(ws);
 }
-#else
-#define cleanup_path_separator(a)      /* nothing */
 #endif
 
 /*
@@ -1539,7 +1535,6 @@ cleanup_pathname(struct archive_write_disk *a)
        char *dest, *src;
        char separator = '\0';
 
-       cleanup_path_separator(a);
        dest = src = a->name;
        if (*src == '\0') {
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -1547,6 +1542,9 @@ cleanup_pathname(struct archive_write_disk *a)
                return (ARCHIVE_FAILED);
        }
 
+#ifdef _WIN32
+       cleanup_pathname_win(a);
+#endif
        /* Skip leading '/'. */
        if (*src == '/')
                separator = *src++;
@@ -1593,22 +1591,6 @@ cleanup_pathname(struct archive_write_disk *a)
                        *dest++ = '/';
                while (*src != '\0' && *src != '/') {
                        *dest++ = *src++;
-#if defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)
-                       // If compiled for a MS-Windows platform,
-                       // rewrite characters that are unusable.
-                       //
-                       // See also:
-                       // http://msdn.microsoft.com/library/?url=/library/en-us/fileio/fs/naming_a_file.asp
-                       if (
-                               (*dest == ':') ||
-                               (*dest == '*') ||
-                               (*dest == '?') ||
-                               (*dest == '"') ||
-                               (*dest == '<') ||
-                               (*dest == '>') ||
-                               (*dest == '|')
-                       ) *dest = '_';
-#endif
                }
 
                if (*src == '\0')