OSDN Git Service

should make recursive directory
authorKoji Arai <jca02266@gmail.com>
Thu, 26 Jun 2008 07:47:44 +0000 (16:47 +0900)
committerKoji Arai <jca02266@gmail.com>
Thu, 26 Jun 2008 07:47:20 +0000 (16:47 +0900)
ar.c
extract.c
header.c
pathlib.c
prototypes.h

diff --git a/ar.c b/ar.c
index aeee5b7..822339d 100644 (file)
--- a/ar.c
+++ b/ar.c
@@ -504,17 +504,6 @@ op_extract(int cmd, char *archive_file, int argc, char **argv)
     if (arcfile == NULL)
         error("Can't open archive '%s'", archive_file);
 
-    /* change directory to extract dir */
-    if (cmd == 'x' && opts.outdir) {
-        if (mkdir(opts.outdir, 0777) == -1) {
-            if (errno != EEXIST)
-                error("cannot make directory \"%s\"", opts.outdir);
-        }
-
-        if (chdir(opts.outdir) == -1)
-            error("cannot change directory \"%s\"", opts.outdir);
-    }
-
     while (read_header(arcfile, &h)) {
 
         found = search(argc, argv, h.filename);
index 75722d2..3096561 100644 (file)
--- a/extract.c
+++ b/extract.c
@@ -44,38 +44,44 @@ void
 extract_to_file(struct lzh_istream *rp, struct lzh_header *h)
 {
     FILE *outfile;
+    char filename[1024];
+
+    if (opts.outdir)
+        makepath(filename, sizeof(filename),
+                 opts.outdir, h->filename, NULL);
+    else
+        string_copy(filename, h->filename, sizeof(filename));
 
     if (memcmp(h->method, "-lhd-", sizeof(h->method)) == 0) {
         /* directory */
-        if (mkdir(h->filename, 0777) == -1) {
-            if (errno != EEXIST)
-                error("cannot make directory \"%s\"", opts.outdir);
-        }
         if (opts.quiet < 2)
-            printf("Extracting %s ", h->filename);
+            printf("Extracting %s\n", filename);
         return;
     }
 
     /* create regular file */
-    if (file_exists(h->filename)) {
+    if (file_exists(filename)) {
         if (!opts.force_extract) {
-            message("'%s' has been already exist. skip", h->filename);
+            message("'%s' has been already exist. skip", filename);
             skip(rp->fp, h);
             return;
         }
     }
-    while ((outfile = fopen(h->filename, "wb")) == NULL) {
-        fprintf(stderr, "Can't open %s\n");
-        fprintf(stderr, "New filename: ", h->filename);
-        if (get_line(h->filename, sizeof(h->filename)) == 0) {
-            fprintf(stderr, "Not extracted\n");
-            skip(rp->fp, h);
-            return;
-        }
-        h->namelen = strlen(h->filename);
+
+    if (mkdir_parent(filename) == -1) {
+        if (errno != EEXIST)
+            error("cannot make directory \"%s\"", opts.outdir);
+    }
+
+    outfile = fopen(filename, "wb");
+    if (outfile == NULL) {
+        fprintf(stderr, "Can't open %s (skip)\n", filename);
+
+        skip(rp->fp, h);
+        return;
     }
     if (opts.quiet < 2)
-        printf("Extracting %s ", h->filename);
+        printf("Extracting %s ", filename);
 
     extract(rp, outfile, h);
     fclose(outfile);
@@ -85,7 +91,7 @@ extract_to_file(struct lzh_istream *rp, struct lzh_header *h)
         struct utimbuf ut;
 
         ut.actime = ut.modtime = h->mtime;
-        utime(h->filename, &ut);
+        utime(filename, &ut);
     }
 
     if (opts.quiet < 2)
index c46b33e..8c55064 100644 (file)
--- a/header.c
+++ b/header.c
@@ -579,7 +579,7 @@ write_header_lv1(FILE *fp, struct lzh_header *h)
     char *dirname, *fname;
     int dirnamelen;
 
-    fname  = xbasename(h->filename);
+    fname  = basename(h->filename);
     dirname   = h->filename;
     dirnamelen = fname - dirname;
     h->namelen = strlen(fname);
@@ -664,7 +664,7 @@ write_header_lv2(FILE *fp, struct lzh_header *h)
     crcptr = &buf[pos];
     put_header(buf, &pos, 2, 0); /* crc (dummy) */
 
-    fname = xbasename(h->filename);
+    fname = basename(h->filename);
     len = strlen(fname);
 
     put_header(buf, &pos, 2, 3 + len);
index c4ad315..3732e19 100644 (file)
--- a/pathlib.c
+++ b/pathlib.c
@@ -23,8 +23,6 @@
 */
 
 #include <string.h>
-#define HAVE_BASENAME 0
-#define HAVE_DIRNAME 1
 
 int
 path_addsep(char *path, size_t size)
@@ -39,9 +37,8 @@ path_addsep(char *path, size_t size)
     return len;
 }
 
-#if !HAVE_BASENAME
 char *
-xbasename(char *path)
+basename(char *path)
 {
     char *p1, *p2;
     int len;
@@ -62,19 +59,18 @@ xbasename(char *path)
 
     return p2;
 }
-#endif /* !HAVE_BASENAME */
 
-#if !HAVE_DIRNAME
 char *
 dirname(char *path)
 {
     char *p1, *p2;
     int len;
-    static char current[] = ".";
 
     len = strlen(path);
-    if (len == 0)
-        return current;
+    if (len == 0) {
+        strcpy(path, ".");
+        return path;
+    }
     if (len == 1 && path[0] == '/')
         return path;
     if (path[len-1] == '/')
@@ -89,12 +85,12 @@ dirname(char *path)
         p2++;
     *p2 = '\0';
 
-    if (path[0] == '\0')
-        return current;
-
+    if (path[0] == '\0') {
+        strcpy(path, ".");
+        return path;
+    }
     return path;
 }
-#endif /* !HAVE_DIRNAME */
 
 int
 makepath(char *dest, int dest_size,
@@ -143,6 +139,45 @@ makepath(char *dest, int dest_size,
     return p - dest;   /* result string length */
 }
 
+#include <sys/stat.h>
+#include <errno.h>
+
+int
+mkdir_p(char *dir, mode_t mode)
+{
+    int ret;
+
+    if (strcmp(dir, "/") == 0)
+        return 0;
+
+    if (mkdir(dir, mode) == -1) {
+        if (errno == ENOENT) {
+            char *parent = dirname(strdup(dir));
+
+            ret = mkdir_p(parent, mode);
+            free(parent);
+
+            if (ret == -1)
+                return -1;
+        }
+
+        return mkdir(dir, mode);
+    }
+}
+
+int
+mkdir_parent(char *file)
+{
+    char *parent;
+    int ret;
+
+    parent = dirname(strdup(file));
+    ret = mkdir_p(parent, 0777);
+    free(parent);
+
+    return ret;
+}
+
 #ifdef DEBUG
 
 #include <stdio.h>
index cd688c7..a218feb 100644 (file)
@@ -49,8 +49,11 @@ char *next_field P_((char *s));
 char *strip_space P_((char *s));
 /* pathlib.c */
 int path_addsep P_((char *path, size_t size));
-char *xbasename P_((char *path));
+char *basename P_((char *path));
+char *dirname P_((char *path));
 int makepath P_((char *dest, int dest_size, char *dir, char *file, char *ext));
+int mkdir_p P_((char *dir, mode_t mode));
+int mkdir_parent P_((char *file));
 /* filelib.c */
 int file_exists P_((char *file));
 int file_mtime P_((char *file, time_t *t));