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);
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);
struct utimbuf ut;
ut.actime = ut.modtime = h->mtime;
- utime(h->filename, &ut);
+ utime(filename, &ut);
}
if (opts.quiet < 2)
char *dirname, *fname;
int dirnamelen;
- fname = xbasename(h->filename);
+ fname = basename(h->filename);
dirname = h->filename;
dirnamelen = fname - dirname;
h->namelen = strlen(fname);
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);
*/
#include <string.h>
-#define HAVE_BASENAME 0
-#define HAVE_DIRNAME 1
int
path_addsep(char *path, size_t size)
return len;
}
-#if !HAVE_BASENAME
char *
-xbasename(char *path)
+basename(char *path)
{
char *p1, *p2;
int len;
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] == '/')
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,
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>
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));