00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdlib.h>
00019 #include <errno.h>
00020 #include <sys/stat.h>
00021
00022 #include "misc.h"
00023 #include "str.h"
00024
00025 int mkdirp(const char *path, mode_t mode)
00026 {
00027 int errno_orig, rc = 0;
00028 char *p, *buf, c;
00029 struct stat sb;
00030
00031 if (str_isempty(path))
00032 return errno = EINVAL, -1;
00033
00034 buf = p = str_dup(path);
00035
00036 do {
00037 c = 0;
00038
00039 while (*p) {
00040 if (*p == '/') {
00041 do { ++p; } while (*p == '/');
00042 c = *p;
00043 *p = '\0';
00044 break;
00045 }
00046
00047 else
00048 ++p;
00049 }
00050
00051 if (mkdir(buf, 0777) == -1) {
00052 if (errno != EEXIST || stat(buf, &sb) == -1)
00053 goto err;
00054
00055 if (!S_ISDIR(sb.st_mode)) {
00056 errno = ENOTDIR;
00057 goto err;
00058 }
00059
00060 if (!c)
00061 goto out;
00062 }
00063
00064 if (!c) {
00065 if (chmod(buf, mode) == -1)
00066 goto err;
00067
00068 goto out;
00069 }
00070
00071 *p = c;
00072 } while (1);
00073
00074 err:
00075 rc = -1;
00076 out:
00077 errno_orig = errno;
00078 free(buf);
00079 errno = errno_orig;
00080 return rc;
00081 }