static Path* walkto(char *a, char **lastp) { char *els[Nels], *path; int nels; Path *p; path = fsname(a); nels = gettokens(path, els, Nels, "/"); if(nels < 1){ free(path); error("invalid path"); } if(catcherror()){ free(path); error("walkpath: %r"); } if(lastp != nil){ p = walkpath(fs->root, els, nels-1); *lastp = a + strlen(a) - strlen(els[nels-1]); }else p = walkpath(fs->root, els, nels); free(path); noerror(); if(verb) print("walked to %H\n", p->f[p->nf-1]); return p; }
static int walkpath(const char *root, dirwalk_action action, unsigned char mask) { char child[FILENAME_MAX+1]; struct dirent *ent; DIR *dh; if (NULL == (dh = opendir(root))) { return -1; } while (NULL != (ent = readdir(dh))) { if (0 == strncmp("..", ent->d_name, 3)) { continue; } if (0 == strncmp(".", ent->d_name, 2)) { continue; } snprintf(child, FILENAME_MAX, "%s/%s", root, ent->d_name); if (mask | ent->d_type) { if (-1 == action(child)) { break; } } if (DT_DIR == ent->d_type && (!(FT_NODESCEND | mask))) { if (-1 == walkpath(child, action, mask)) { break; } } } if (-1 == closedir(dh)) { return -1; } return 0; }
/* * walkdir goes through every directory entry under root and calls action on * every entry matching the mask. */ int walkdir(const char *root, dirwalk_action action, unsigned char mask) { struct stat st; char *rootdup = NULL; size_t rootlen; int ret = -1; unsigned char type; if (-1 == stat(root, &st)) { return -1; } type = stat_mode_to_dt_type(st.st_mode); if (mask | type) { if (0 != (ret = action(root))) { return ret; } } if (DT_DIR == type) { rootlen = strnlen(root, FILENAME_MAX); rootdup = strndup(root, FILENAME_MAX); if (NULL == rootdup) { return -1; } if ('/' == rootdup[rootlen-1]) { rootdup[rootlen-1] = 0; } ret = walkpath(rootdup, action, mask); } free(rootdup); return ret; }