diff --git a/btpd/torrent.c b/btpd/torrent.c index 9d9fa8d..c7bd33f 100644 --- a/btpd/torrent.c +++ b/btpd/torrent.c @@ -95,7 +95,7 @@ torrent_start(struct tlib *tl) if (tl->dir == NULL) return IPC_EBADTENT; - if (mkdir(tl->dir, 0777) != 0 && errno != EEXIST) { + if (mkdirs(tl->dir, 0777) != 0 && errno != EEXIST) { btpd_log(BTPD_L_ERROR, "torrent '%s': " "failed to create content dir '%s' (%s).\n", tl->name, tl->dir, strerror(errno)); diff --git a/misc/subr.c b/misc/subr.c index 70a04af..22ed6e2 100644 --- a/misc/subr.c +++ b/misc/subr.c @@ -97,24 +97,24 @@ set_blocking(int fd) } int -mkdirs(char *path) +mkdirs(char *path, int mode) { int err = 0; - char *spos = strchr(path + 1, '/'); // Must ignore the root + char *spos = strchr(path + 1, '/'); // Skip leading '/' while (spos != NULL) { *spos = '\0'; - err = mkdir(path, 0777); + err = mkdir(path, mode); *spos = '/'; - if (err != 0 && errno != EEXIST) { - err = errno; - break; - } + if (err != 0 && errno != EEXIST) + return errno; spos = strchr(spos + 1, '/'); } - return err; + if (mkdir(path, mode) != 0) + return errno; + return 0; } int @@ -130,11 +130,16 @@ vaopen(int *res, int flags, const char *fmt, va_list ap) again: fd = open(path, flags, 0666); if (fd < 0 && errno == ENOENT && (flags & O_CREAT) != 0 && !didmkdirs) { - if (mkdirs(path) == 0) { - didmkdirs = 1; - goto again; - } else - return errno; + char *rs = rindex(path, '/'); + if (rs != NULL) { + *rs = '\0'; + if (mkdirs(path, 0777) == 0) { + *rs = '/'; + didmkdirs = 1; + goto again; + } + } + return errno; } if (fd >= 0) { diff --git a/misc/subr.h b/misc/subr.h index fd9e002..25bca0d 100644 --- a/misc/subr.h +++ b/misc/subr.h @@ -10,7 +10,7 @@ int set_nonblocking(int fd); int set_blocking(int fd); -int mkdirs(char *path); +int mkdirs(char *path, int mode); __attribute__((format (printf, 3, 0))) int vaopen(int *resfd, int flags, const char *fmt, va_list ap);