OSDN Git Service

pass the lha-test11
authorKoji Arai <jca02266@gmail.com>
Thu, 22 May 2008 14:43:28 +0000 (23:43 +0900)
committerKoji Arai <jca02266@gmail.com>
Thu, 22 May 2008 14:43:28 +0000 (23:43 +0900)
however, use the LHa for UNIX for the lha-test11 (use `lha vvv arc.lzh')

ar.c
io.c
makefile
tests/lha-test11

diff --git a/ar.c b/ar.c
index 50760b7..bbcd9b4 100644 (file)
--- a/ar.c
+++ b/ar.c
@@ -394,6 +394,10 @@ read_header_lv0(FILE *fp, char *buf, struct lzh_header *h)
     /* attrib   = */ get_header(buf, &pos, 1);
     h->level    = get_header(buf, &pos, 1); /* header level */
     h->namelen  = get_header(buf, &pos, 1);
+    if (pos + h->namelen > headersize+2) {
+        warn("path name is too long");
+        h->namelen = headersize+2-pos;
+    }
     get_string(buf, &pos, h->namelen, h->filename);
     h->filename[h->namelen] = 0;
     h->file_crc = get_header(buf, &pos, 2);
@@ -468,6 +472,8 @@ read_header_lv1(FILE *fp, char *buf, struct lzh_header *h)
     int headersize;
     int headersum;
     int ext_headersize;
+    char dirname[1024] = "";
+    int dirnamelen = 0;
     int pos = 0;
 
     headersize = get_header(buf, &pos, 1);
@@ -505,6 +511,18 @@ read_header_lv1(FILE *fp, char *buf, struct lzh_header *h)
 
         ext_type = get_header(extbuf, &extpos, 1);
         switch (ext_type) {
+        case 1:
+            /* filename header */
+            h->namelen = ext_headersize - 3;
+            get_string(extbuf, &extpos, h->namelen, h->filename);
+            h->filename[h->namelen] = 0;
+            break;
+        case 2:
+            /* dirname header */
+            dirnamelen = ext_headersize - 3;
+            get_string(extbuf, &extpos, dirnamelen, dirname);
+            dirname[dirnamelen] = 0;
+            break;
         case 0x54:
             h->mtime = get_header(extbuf, &extpos, 4);
             break;
@@ -515,6 +533,14 @@ read_header_lv1(FILE *fp, char *buf, struct lzh_header *h)
         ext_headersize = get_header(extbuf, &extpos, 2);
     }
 
+    if (dirnamelen > 0 && dirname[dirnamelen-1] != '/') {
+        dirname[dirnamelen++] = '/';
+    }
+
+    strcat(dirname, h->filename);
+    h->namelen = strlen(dirname);
+    strcpy(h->filename, dirname);
+
     return 1;                   /* success */
 }
 
@@ -663,9 +689,20 @@ write_header_lv0(FILE *fp, struct lzh_header *h)
     int headersize;
     int pos = 0;
 
-    headersize = 22 + h->namelen;
+    headersize = 22;
+    if (!opts.generic)
+        headersize += 12;       /* extended header size */
 
-    put_header(buf, &pos, 1, 0); /* dummy */
+    if (headersize + h->namelen > 255) {
+        warn("path name is too long");
+        h->namelen = 255 - headersize;
+        headersize = 255;
+    }
+    else {
+        headersize += h->namelen;
+    }
+
+    put_header(buf, &pos, 1, headersize);
     put_header(buf, &pos, 1, 0); /* dummy */
 
     put_string(buf, &pos, 5, h->method);
@@ -686,11 +723,8 @@ write_header_lv0(FILE *fp, struct lzh_header *h)
         put_header(buf, &pos, 2, 0100000);  /* mode */
         put_header(buf, &pos, 2, 0);  /* uid */
         put_header(buf, &pos, 2, 0);  /* gid */
-        headersize += pos;            /* size of ext-header (old style) */
     }
 
-    put_header_tmp(buf, 0, 1, headersize);
-
     sum = calc_headersum(buf+2, headersize);
     put_header_tmp(buf, 1, 1, sum);
 
@@ -706,10 +740,18 @@ write_header_lv1(FILE *fp, struct lzh_header *h)
     int extsize = 0;
     int pos = 0;
     int extpos;
+    char *dirname, *fname;
+    int dirnamelen;
 
-    headersize = 25 + h->namelen;
+    fname  = basename(h->filename);
+    dirname   = h->filename;
+    dirnamelen = fname - dirname;
+    h->namelen = strlen(fname);
+    printf("namelen = %d\n", h->namelen);
 
-    put_header(buf, &pos, 1, headersize);
+    headersize = 25;
+
+    put_header(buf, &pos, 1, 0); /* dummy */
     put_header(buf, &pos, 1, 0); /* dummy */
     put_string(buf, &pos, 5, h->method);
     put_header(buf, &pos, 4, h->compsize); /* packed size */
@@ -717,8 +759,14 @@ write_header_lv1(FILE *fp, struct lzh_header *h)
     put_header(buf, &pos, 4, time_t_to_ftime(h->mtime)); /* ftime */
     put_header(buf, &pos, 1, 0x20);     /* attribute */
     put_header(buf, &pos, 1, 1);        /* level */
-    put_header(buf, &pos, 1, h->namelen); /* length of pathname */
-    put_string(buf, &pos, h->namelen, h->filename);
+    if (headersize + h->namelen > 255)
+        put_header(buf, &pos, 1, 0);            /* length of pathname */
+    else {
+        put_header(buf, &pos, 1, h->namelen);   /* length of pathname */
+        put_string(buf, &pos, h->namelen, fname);
+        headersize += h->namelen;
+    }
+    put_header_tmp(buf, 0, 1, headersize); /* header size */
     put_header(buf, &pos, 2, h->file_crc);
     if (opts.generic)
         put_header(buf, &pos, 1, '\0');
@@ -730,6 +778,18 @@ write_header_lv1(FILE *fp, struct lzh_header *h)
     put_header(buf, &pos, 1, 0x54); /* time stamp */
     put_header(buf, &pos, 4, h->mtime); /* time_t */
 
+    if (h->namelen > 0) {
+        put_header(buf, &pos, 2, 3 + h->namelen);
+        put_header(buf, &pos, 1, 1); /* 0x01: filename header */
+        put_string(buf, &pos, h->namelen, fname); /* filename */
+    }
+
+    if (dirnamelen > 0) {
+        put_header(buf, &pos, 2, 3 + dirnamelen);
+        put_header(buf, &pos, 1, 2); /* 0x02: dirname header */
+        put_string(buf, &pos, dirnamelen, dirname); /* dirname */
+    }
+
     extsize = pos - extpos;
     put_header(buf, &pos, 2, 0); /* next header size (end of header) */
 
@@ -1226,6 +1286,7 @@ parse_args(int argc, char **argv)
             break;
         case 'g':
             opts.generic = 1;
+            opts.header_level = 0;
             break;
         case 'o':
             /* compress method */
diff --git a/io.c b/io.c
index f573f9d..9e172a4 100644 (file)
--- a/io.c
+++ b/io.c
@@ -40,6 +40,17 @@ message(char *fmt, ...)
 }
 
 void
+warn(char *fmt, ...)
+{
+    va_list args;
+
+    va_start(args, fmt);
+    vfprintf(stderr, fmt, args);
+    putc('\n', stderr);
+    va_end(args);
+}
+
+void
 make_crctable(void)
 {
     uint i, j, r;
index 7cc7a30..383742f 100644 (file)
--- a/makefile
+++ b/makefile
@@ -33,7 +33,7 @@ install: $(TARGET)
        install -m 755 olha$(EXEEXT) /usr/local/bin
 
 check: $(TARGET) randtest
-       sh ./tests/lha-test.sh 2 10 3 4 5 7 8 16 11
+       sh ./tests/lha-test.sh 2 10 3 4 5 7 8 16 11
        sh ./test.sh
 
 t: $(TARGET)
index d57a500..bfe5aa1 100644 (file)
@@ -78,7 +78,7 @@ test -f test-tmp1-h1/test-tmp1/$file
 test -f test-tmp1-h2/test-tmp1/$file
                                                        check $? $LINENO
 # 0x100 is never set on the header size field on level 2 header
-file=test-tmp9012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
+file=test-tmp9012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890X23456789012
 touch $file
 if [ $? -ne 0 ]; then
   echo "$FILENAME: Warning: current directory is too deep. skip this test..." >&2
@@ -94,7 +94,8 @@ else
                                                        check $? $LINENO
   $lha x test-tmp4-h2.lzh
                                                        check $? $LINENO
-  test x"`$lha vvvq test-tmp4-h2.lzh | head -1`" = x"00  2: 257(0x0101)"
+  cp test-tmp4-h2.lzh /tmp/hoge.lzh
+  test x"`lha vvvq test-tmp4-h2.lzh | head -1`" = x"00  2: 257(0x0101)"
                                                        check $? $LINENO
   test -f $file
                                                        check $? $LINENO