-static enum { mkdirFAIL, mkdirSUCCESS, mkdirSKIP }
-mkdirSingle(char const *path, char *end_ptr, int good_err)
-{
- *end_ptr = '\0';
- if (mkdir(path, 0700)!=-1 || errno==EEXIST) {
- *end_ptr = '/';
- return mkdirSUCCESS;
- }
- else if (errno==good_err) {
- *end_ptr = '/';
- return mkdirSKIP;
- }
- else {
- int old_errno = errno;
- WRITE_MSG(2, "mkdir('");
- WRITE_STR(2, path);
- errno = old_errno;
- perror("')");
- return mkdirFAIL;
- }
-}
-
-static char *
-rstrchr(char *str, char c)
-{
- while (*str!=c) --str;
- return str;
-}
-
-static bool
-mkdirRecursive(char const *path)
-{
- if (path[0]!='/') return false; // only absolute paths
-
- char buf[strlen(path)+1];
- char * ptr = buf + sizeof(buf) - 2;
-
- strcpy(buf, path);
-
- while (ptr>buf && (ptr = rstrchr(ptr, '/'))!=0) {
- switch (mkdirSingle(buf, ptr, ENOENT)) {
- case mkdirSUCCESS : break;
- case mkdirSKIP : --ptr; continue;
- case mkdirFAIL : return false;
- }
-
- break; // implied by mkdirSUCCESS
- }
-
- assert(ptr!=0);
- ++ptr;
-
- while ((ptr=strchr(ptr, '/'))!=0) {
- switch (mkdirSingle(buf, ptr, 0)) {
- case mkdirSKIP :
- case mkdirFAIL : return false;
- case mkdirSUCCESS : ++ptr; continue;
- }
- }
-
- return true;
-}
-