/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Attempt to create a directory recursively. We first attempt to create all * the parent directories. If we succeed, or if the directory already exists, * we return 0; otherwise we return the error code. */ int rmakdir( char *path) { int r=0; int e, l; char dir[RECLEN+1]; struct stat st; Fenter("rmakdir"); V5 "path=\"%s\"",path V; l = strlen(path); if (l > RECLEN) { V1 "### Can't handle %d-char path \"%s\"\n",l,path V; r = EINVAL; Fail; } bcopy(path,dir,l+1); while ((l > 0) && (dir[l-1] != '/')) // Trim away last field l--; while ((l > 0) && (dir[l-1] == '/')) // Trim away slash(es) l--; if (l < 1) { V5 "Reached null path." V; r = EACCES; Fail; } dir[l] = 0; V4 "Directory \"%s\"",dir V; if (stat(dir,&st) == 0) { V5 "File \"%s\" exists.",dir V; if (S_ISDIR(st.st_mode)) { // This is what we want V3 "Dir \"%s\" exists.",dir V; errno = EEXIST; Done; } V3 "File \"%s\" exists, but is not a directory.",dir V; r = ENOTDIR; Fail; } V5 "Dir \"%s\" does not exist.",dir V; if (r = rmakdir(dir)) { errno = r; V5 "Failed for \"%s\" [Err %d=%s=%s]",dir,Errinfo V; Fail; } V5 "dir=\"%s\"",dir V; if (mkdir(dir,0775) < 0) { V2 "### Can't create \"%s\" [Err %d=%s=%s]",dir,Errinfo V; r = errno; Fail; } V3 "Created \"%s\"",dir V; done: r = 0; fail: FExit; return r; }