// Evaluate a path name, starting at the root. // On success, set *pf to the file we found // and set *pdir to the directory the file is in. // If we cannot find the file but find the directory // it should be in, set *pdir and copy the final path // element into lastelem. static int walk_path(const char *path, struct File **pdir, struct File **pf, char *lastelem) { const char *p; char name[MAXNAMELEN]; struct File *dir, *f; int r; // cprintf("entering walk path\n"); // if (*path != '/') // return -E_BAD_PATH; path = skip_slash(path); f = &super->s_root; dir = 0; name[0] = 0; if (pdir) *pdir = 0; *pf = 0; while (*path != '\0') { // cprintf("entering 2 walk path\n"); dir = f; p = path; while (*path != '/' && *path != '\0') path++; if (path - p >= MAXNAMELEN) return -E_BAD_PATH; memmove(name, p, path - p); name[path - p] = '\0'; path = skip_slash(path); if (dir->f_type != FTYPE_DIR) { cprintf("error 1\n"); return -E_NOT_FOUND; } if ((r = dir_lookup(dir, name, &f)) < 0) { if (r == -E_NOT_FOUND && *path == '\0') { if (pdir) *pdir = dir; if (lastelem) strcpy(lastelem, name); *pf = 0; } // cprintf("error 2 \n"); return r; } } if (pdir) *pdir = dir; *pf = f; return 0; }
/* Return the directory descriptor where @file should be created. */ static int mkdir_parents(const char *file) { char *copy_file; const char *path; int dd; copy_file = alloca(strlen(file) + 1); assert(copy_file); strcpy(copy_file, file); path = (copy_file[0] == '/') ? "/" : "."; dd = open(path, O_DIRECTORY); if (dd < 0) err(1, "Can't open directory `%s'", path); return _mkdir_parents(dd, skip_slash(copy_file)); }
/** * Walk down the path_stop starting at path_start. * * If path_start = "/path1" and path_stop = "/path1/path2/path3" * the callback will be called 3 times with the next args: * * 1. "/path1/path2/path3" * ^ end * ^ start * 2. "/path1/path2/path3" * ^ end * ^ start * 3. "/path1/path2/path3" * ^ end * ^ start * * path_stop has to be a subdir of path_start * or to be path_start itself. * * Both path args have to be absolute. * Trailing slashes are allowed. * NULL or empty string args are not allowed. */ static void walk_down_the_path(char* path_start, char* path_stop, void (*cb)(char* begin, char* end, void* data), void* data) { char *pos = path_stop + pathlen_without_trailing_slash(path_start); cb(path_stop, pos, data); while ((pos = skip_slash(pos))[0]) { pos = strchr(pos, DEFAULT_SLASH); if (!pos) { /* The last token without trailing slash */ cb(path_stop, path_stop + strlen(path_stop), data); return; } cb(path_stop, pos, data); } }
static int _mkdir_parents(int dd, char *file) { char *p = strchr(file, '/'); int new_dd; if (!p) { /* There is no folder to create. */ return dd; } *p = '\0'; new_dd = openat(dd, file, O_DIRECTORY); if (new_dd < 0) { if (errno == ENOENT) { if (mkdirat(dd, file, 0770)) err(1, "Can't create directory `%s'", file); new_dd = openat(dd, file, O_DIRECTORY); } if (new_dd < 0) err(1, "Can't open directory `%s'", file); } assert(!close(dd)); return _mkdir_parents(new_dd, skip_slash(p + 1)); }