OSDN Git Service

Fix nesting of MULTIBYTE_FILENAME compiler switch
[lha/lha.git] / src / header.c
index be35c66..17f4b6d 100644 (file)
@@ -61,8 +61,9 @@ calc_sum(p, len)
     int len;
 {
     int sum = 0;
+    unsigned char *pc = (unsigned char*)p;
 
-    while (len--) sum += *(unsigned char*)p++;
+    while (len--) sum += *pc++;
 
     return sum & 0xff;
 }
@@ -152,8 +153,7 @@ get_longword()
 }
 
 static void
-put_longword(v)
-    long v;
+put_longword(long v)
 {
     put_byte(v);
     put_byte(v >> 8);
@@ -278,11 +278,34 @@ convert_filename(name, len, size,
         to_code_save = CODE_CAP;
         to_code = CODE_SJIS;
     }
+#endif
+
+    /* special case: if `name' has small lettter, not convert case. */
+    if (from_code == CODE_SJIS && case_to == TO_LOWER) {
+        for (i = 0; i < len; i++) {
+#ifdef MULTIBYTE_FILENAME
+            if (SJIS_FIRST_P(name[i]) && SJIS_SECOND_P(name[i+1]))
+                i++;
+            else
+#endif
+            if (islower(name[i])) {
+                case_to = NONE;
+                break;
+            }
+        }
+    }
 
+#ifdef MULTIBYTE_FILENAME
     if (from_code == CODE_SJIS && to_code == CODE_UTF8) {
-        for (i = 0; i < len; i++)
-            /* FIXME: provisionally fix for the Mac OS CoreFoundation */
-            if ((unsigned char)name[i] == LHA_PATHSEP)  name[i] = '/';
+        for (i = 0; i < len; i++) {
+            if (SJIS_FIRST_P(name[i]) && SJIS_SECOND_P(name[i+1]))
+                i++;
+            else {
+                /* FIXME: provisionally fix for the Mac OS CoreFoundation */
+                if (strchr(from_delim, name[i]))
+                    name[i] = '/';
+            }
+        }
         sjis_to_utf8(tmp, name, sizeof(tmp));
         strncpy(name, tmp, size);
         name[size-1] = 0;
@@ -305,21 +328,6 @@ convert_filename(name, len, size,
     }
 #endif
 
-    /* special case: if `name' has small lettter, not convert case. */
-    if (from_code == CODE_SJIS && case_to == TO_LOWER) {
-        for (i = 0; i < len; i++) {
-#ifdef MULTIBYTE_FILENAME
-            if (SJIS_FIRST_P(name[i]) && SJIS_SECOND_P(name[i+1]))
-                i++;
-            else
-#endif
-            if (islower(name[i])) {
-                case_to = NONE;
-                break;
-            }
-        }
-    }
-
     for (i = 0; i < len; i ++) {
 #ifdef MULTIBYTE_FILENAME
         if (from_code == CODE_EUC &&
@@ -614,10 +622,10 @@ get_extended_header(fp, hdr, header_size, hcrc)
             break;
         case 0x42:
 #if DUMP_HEADER
-            if (verbose_listing && verbose > 1) printf("     < Windows file size header>\n");
+            if (verbose_listing && verbose > 1) printf("     < 64bits file size header >\n");
 #endif
 #ifdef HAVE_UINT64_T
-            /* Windows file size header (UNLHA32 extension) */
+            /* 64bits file size header (UNLHA32 extension) */
             hdr->packed_size = get_longlongword();
             hdr->original_size = get_longlongword();
 #else
@@ -801,8 +809,8 @@ get_header_level0(fp, hdr, data)
     }
 
     get_bytes(hdr->method, 5, sizeof(hdr->method));
-    hdr->packed_size = get_longword();
-    hdr->original_size = get_longword();
+    hdr->packed_size = (unsigned long)get_longword();
+    hdr->original_size = (unsigned long)get_longword();
     hdr->unix_last_modified_stamp = generic_to_unix_stamp(get_longword());
     hdr->attribute = get_byte(); /* MS-DOS attribute */
     hdr->header_level = get_byte();
@@ -917,8 +925,8 @@ get_header_level1(fp, hdr, data)
     }
 
     get_bytes(hdr->method, 5, sizeof(hdr->method));
-    hdr->packed_size = get_longword(); /* skip size */
-    hdr->original_size = get_longword();
+    hdr->packed_size = (unsigned long)get_longword(); /* skip size */
+    hdr->original_size = (unsigned long)get_longword();
     hdr->unix_last_modified_stamp = generic_to_unix_stamp(get_longword());
     hdr->attribute = get_byte(); /* 0x20 fixed */
     hdr->header_level = get_byte();
@@ -1004,8 +1012,8 @@ get_header_level2(fp, hdr, data)
     }
 
     get_bytes(hdr->method, 5, sizeof(hdr->method));
-    hdr->packed_size = get_longword();
-    hdr->original_size = get_longword();
+    hdr->packed_size = (unsigned long)get_longword();
+    hdr->original_size = (unsigned long)get_longword();
     hdr->unix_last_modified_stamp = get_longword();
     hdr->attribute = get_byte(); /* reserved */
     hdr->header_level = get_byte();
@@ -1084,8 +1092,8 @@ get_header_level3(fp, hdr, data)
     }
 
     get_bytes(hdr->method, 5, sizeof(hdr->method));
-    hdr->packed_size = get_longword();
-    hdr->original_size = get_longword();
+    hdr->packed_size = (unsigned long)get_longword();
+    hdr->original_size = (unsigned long)get_longword();
     hdr->unix_last_modified_stamp = get_longword();
     hdr->attribute = get_byte(); /* reserved */
     hdr->header_level = get_byte();
@@ -1240,9 +1248,11 @@ seek_lha_header(fp)
     n = fread(buffer, 1, sizeof(buffer), fp);
 
     for (p = buffer; p < buffer + n; p++) {
-        if (! (p[I_METHOD]=='-' && p[I_METHOD+1]=='l' && p[I_METHOD+4]=='-'))
+        if (! (p[I_METHOD]=='-' &&
+               (p[I_METHOD+1]=='l' || p[I_METHOD+1]=='p') &&
+               p[I_METHOD+4]=='-'))
             continue;
-        /* found "-l??-" keyword (as METHOD type string) */
+        /* found "-[lp]??-" keyword (as METHOD type string) */
 
         /* level 0 or 1 header */
         if ((p[I_HEADER_LEVEL] == 0 || p[I_HEADER_LEVEL] == 1)
@@ -1328,11 +1338,16 @@ copy_path_element(char *dst, const char *src, int size)
     return i;
 }
 
-/* remove leading "xxx/../" and "./" */
+/*
+  canonicalize path
+
+  remove leading "xxx/../"
+  remove "./", "././", "././ ... ./"
+  remove duplicated "/"
+*/
 static int
-remove_dots(char *newpath, char *path, size_t size)
+canon_path(char *newpath, char *path, size_t size)
 {
-    int len;
     char *p = newpath;
 
     path = remove_leading_dots(path);
@@ -1350,6 +1365,9 @@ remove_dots(char *newpath, char *path, size_t size)
             if (size <= 1)
                 break;
         }
+
+        /* remove duplicated '/' */
+        while (*path == '/') path++;
     }
 
     /* When newpath is empty, set "." */
@@ -1380,7 +1398,7 @@ init_header(name, v_stat, hdr)
     hdr->attribute = GENERIC_ATTRIBUTE;
     hdr->header_level = header_level;
 
-    len = remove_dots(hdr->name, name, sizeof(hdr->name));
+    len = canon_path(hdr->name, name, sizeof(hdr->name));
 
     hdr->crc = 0x0000;
     hdr->extend_type = EXTEND_UNIX;