OSDN Git Service

pass the lha-test5
authorKoji Arai <jca02266@gmail.com>
Sat, 3 May 2008 06:12:20 +0000 (15:12 +0900)
committerKoji Arai <jca02266@gmail.com>
Sat, 3 May 2008 06:12:20 +0000 (15:12 +0900)
ar.c
ar.h
filelib.c
makefile
tests/lha-test5

diff --git a/ar.c b/ar.c
index ed8fcc3..35319bc 100644 (file)
--- a/ar.c
+++ b/ar.c
@@ -86,19 +86,6 @@ which_method(char *id)
     return NULL;
 }
 
-init_opts()
-{
-    opts.nocompress = 0;
-    opts.outdir = NULL;
-    opts.quiet = 0;
-    opts.header_level = 2;
-    opts.generic = 0;
-    opts.verbose = 0;
-
-    /* default is the -lh5- method */
-    opts.method   = &methods[5];
-}
-
 #define FNAME_MAX (255 - 25)    /* max strlen(filename) */
 
 int unpackable;                 /* global, set in io.c */
@@ -617,7 +604,12 @@ write_header(FILE *fp, struct lzh_header *h)
 static void
 skip(FILE *fp, struct lzh_header *h)
 {
-    fseek(fp, h->compsize, SEEK_CUR);
+    int i;
+    if (opts.archive_to_stdio)
+        for (i = 0; i < h->compsize; i++)
+            fgetc(fp);
+    else
+        fseek(fp, h->compsize, SEEK_CUR);
 }
 
 static void
@@ -807,6 +799,13 @@ extract(int to_file, struct lzh_header *h)
         }
         else {
             /* regular file */
+            if (file_exists(h->filename)) {
+                if (!opts.force_extract) {
+                    message("'%s' has been already exist. skip", h->filename);
+                    skip(arcfile, h);
+                    return;
+                }
+            }
             while ((outfile = fopen(h->filename, "wb")) == NULL) {
                 fprintf(stderr, "Can't open %s\nNew filename: ", h->filename);
                 if (get_line(h->filename, FNAME_MAX) == 0) {
@@ -967,7 +966,7 @@ parse_args(int argc, char **argv)
             {0, 0, 0, 0}
         };
 
-        c = getopt_long(argc, argv, "012go[567]q[012]vw:z",
+        c = getopt_long(argc, argv, "012fgo[567]q[012]vw:z",
                         long_options, &option_index);
 
         if (c == -1) break;     /* end of parsing options */
@@ -983,6 +982,9 @@ parse_args(int argc, char **argv)
             /* header level */
             opts.header_level = c - '0';
             break;
+        case 'f':
+            opts.force_extract = 1;
+            break;
         case 'g':
             opts.generic = 1;
             break;
@@ -1052,7 +1054,7 @@ main(int argc, char *argv[])
     struct lzh_header h;
     int arc_count;
 
-    init_opts();
+    INITIALIZE_OPTS(opts);
 
     if (argv[1] == 0)
         print_usage();
@@ -1085,6 +1087,9 @@ main(int argc, char *argv[])
 
     archive_file = argv[0];
 
+    if (strcmp(archive_file, "-") == 0)
+        opts.archive_to_stdio = 1;
+
     argv++;
     argc--;
 
@@ -1096,6 +1101,8 @@ main(int argc, char *argv[])
     switch (cmd) {
     case 'a':
     case 'c':
+        if (opts.archive_to_stdio)
+            opts.quiet = 2;
         outfile = open_tempfile();
         if (*argv == 0)
             error("archived files are not specified.");
@@ -1106,11 +1113,16 @@ main(int argc, char *argv[])
         fputc(0, outfile);      /* end of archive */
         if (ferror(outfile))
             error("Can't write");
-        remove(archive_file);
         fclose(outfile);
-        if (xrename(temp_name, archive_file) == -1)
-            error("fail to rename(): %s -> %s",temp_name,archive_file);
-
+        if (opts.archive_to_stdio) {
+            if (move_file_to_stream(temp_name, stdout) == -1)
+                error("fail to move_file_to_stream(): %s -> %s",temp_name,"stdout");
+        }
+        else {
+            unlink(archive_file);
+            if (xrename(temp_name, archive_file) == -1)
+                error("fail to rename(): %s -> %s",temp_name,archive_file);
+        }
         exit(0);
         break;
     case 'r':
@@ -1125,7 +1137,12 @@ main(int argc, char *argv[])
     case 'l':
     case 'v':
         /* Open archive. */
-        arcfile = fopen(archive_file, "rb");
+        if (opts.archive_to_stdio) {
+            arcfile = stdin;
+        }
+        else {
+            arcfile = fopen(archive_file, "rb");
+        }
         if (arcfile == NULL)
             error("Can't open archive '%s'", archive_file);
 
@@ -1216,16 +1233,16 @@ main(int argc, char *argv[])
         fputc(0, outfile);      /* end of archive */
         if (ferror(outfile))
             error("Can't write");
-        remove(archive_file);
+        if (!opts.archive_to_stdio)
+            unlink(archive_file);
         fclose(outfile);
         if (arc_count > count) {
             if (xrename(temp_name, archive_file) == -1)
                 error("fail to rename(): %s -> %s",temp_name,archive_file);
         }
-        else {
-            unlink(archive_file);
+        else
             message("The archive file \"%s\" was removed because it would be empty.", archive_file);
-        }
+
         exit(0);
     }
     return EXIT_SUCCESS;
diff --git a/ar.h b/ar.h
index 98f5a69..630c3fa 100644 (file)
--- a/ar.h
+++ b/ar.h
@@ -36,10 +36,26 @@ struct lha_opts {
     int header_level;
     int generic;
     int verbose;
+    int force_extract;
+    int archive_to_stdio;
 
     /* compress parameter */
     struct lha_method *method;
 };
+#define INITIALIZE_OPTS(opts)                   \
+    do {                                        \
+        (opts).nocompress = 0;                  \
+        (opts).outdir = NULL;                   \
+        (opts).quiet = 0;                       \
+        (opts).header_level = 2;                \
+        (opts).generic = 0;                     \
+        (opts).verbose = 0;                     \
+        (opts).force_extract = 0;               \
+        (opts).archive_to_stdio = 0;            \
+                                                \
+        /* default is the -lh5- method */       \
+        (opts).method   = &methods[5];          \
+    } while (0)
 
 /* ar.c */
 extern struct lha_opts opts;
index 7a3d165..413658b 100644 (file)
--- a/filelib.c
+++ b/filelib.c
@@ -1,4 +1,23 @@
 #include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+
+int
+file_exists(char *file)
+{
+    struct stat stbuf;
+    int ret;
+
+    ret = stat(file, &stbuf);
+    if (ret == 0)
+        return 1;
+    else if (ret == -1 && errno == ENOENT)
+        return 0;
+    else
+        error("failed to stat() for '%s'", file);
+}
 
 int
 copy_stream(FILE *from, FILE *to)
@@ -20,6 +39,27 @@ copy_stream(FILE *from, FILE *to)
 }
 
 int
+move_file_to_stream(char *from, FILE *to)
+{
+    FILE *ffp = NULL, *tfp = NULL;
+
+    if ((ffp = fopen(from, "r")) == NULL)
+       goto err;
+
+    copy_stream(ffp, to);
+
+    if (ffp) fclose(ffp);
+
+    unlink(from);
+
+    return 0;
+err:
+    if (ffp) fclose(ffp);
+
+    return -1;
+}
+
+int
 xrename(char *from, char *to)
 {
     FILE *ffp = NULL, *tfp = NULL;
index 2c6bc1a..d32049d 100644 (file)
--- a/makefile
+++ b/makefile
@@ -32,8 +32,8 @@ distclean: clean
 install: $(TARGET)
        install -m 755 olha$(EXEEXT) /usr/local/bin
 
-check: $(TARGET)
-       sh ./tests/lha-test.sh 2 10 3 4
+check: $(TARGET) randtest
+       sh ./tests/lha-test.sh 2 10 3 4 5
        sh ./test.sh
 
 t: $(TARGET)
index a08a296..e209d37 100644 (file)
@@ -3,6 +3,11 @@ message testing to treat stdin/stdout as archive file.
 
 $lha c - test-a test-b test-c > test-tmp.lzh
                                                        check $? $LINENO
+test -f ./-
+test $? -ne 0
+                                                       check $? $LINENO
+test -f ./- && rm -f ./-
+
 cat test-tmp.lzh | $lha xw=test-tmp -
                                                        check $? $LINENO
 diff -r test-1 test-tmp
@@ -10,6 +15,11 @@ diff -r test-1 test-tmp
 # output to pipe
 $lha c - test-a test-b test-c | $lha xw=test-tmp2 -
                                                        check $? $LINENO
+test -f ./-
+test $? -ne 0
+                                                       check $? $LINENO
+test -f ./- && rm -f ./-
+
 diff -r test-1 test-tmp2
                                                        check $? $LINENO
 # skip to extract existent files when archive file is stdin
@@ -22,3 +32,4 @@ diff -r test-1 test-tmp
 # 2 files will be skipped.
 test 2 = `grep skip test-stderr | wc -l`
                                                        check $? $LINENO
+cat test-stderr