// recursive helper for uio_mountTreeAddMountInfo // Pre: *start != '\0' // returns the MountTree for the location at the end of the path, if // that falls within this tree. If not, returns NULL. static inline uio_MountTree * uio_mountTreeAddMountInfoRecTreeSub(uio_Repository *repository, uio_MountTree **tree, uio_MountInfo *mountInfo, const char *start, const char *end, uio_MountLocation location, const uio_MountInfo *relative) { uio_PathComp *comp, *lastComp; int depth; comp = (*tree)->comps; if (strncmp(comp->name, start, end - start) != 0 || comp->name[end - start] != '\0') { // first component does not match; this is not the correct subTree return NULL; } depth = 1; // try to match all components of the directory path to this subTree. while (1) { getNextPath0Component(&start, &end); lastComp = comp; comp = comp->next; if (comp == NULL) break; if (*start == '\0') { // end of the path reached // We need to split up the components and insert a new // MountTree here. uio_MountTree *newTree; newTree = uio_splitMountTree(tree, lastComp, depth); // Add mountInfo to each of the MountTrees below newTree. uio_mountTreeAddMountInfoLocAll(repository, newTree, mountInfo, 0, location, relative); return newTree; } if (strncmp(comp->name, start, end - start) != 0 || comp->name[end - start] != '\0') { // Some, but not all components matched; we need to split // up the components and add a new subTree here for the // (non-matching) rest of the path. uio_MountTree *newTree; newTree = uio_splitMountTree(tree, lastComp, depth); // A new Tree is added at the split-point. return uio_mountTreeAddNewSubTree(repository, newTree, start, mountInfo, lastComp, location, relative); } getNextPath0Component(&start, &end); depth++; } // All components matched. We can recurse to the next subdir. return uio_mountTreeAddMountInfoRecTree(repository, *tree, mountInfo, start, end, lastComp, location, relative); }
// resTree may point to top // pPath may point to path void uio_findMountTree(uio_MountTree *top, const char *path, uio_MountTree **resTree, const char **pPath) { const char *start, *end, *pathFromTree; uio_MountTree *tree, *sub; uio_PathComp *comp; getFirstPath0Component(path, &start, &end); tree = top; while(1) { if (*start == '\0') { *resTree = tree; *pPath = start; return; } pathFromTree = start; sub = tree->subTrees; while(1) { if (sub == NULL) { // No matching sub Dirs found. So we report back the current // dir. *resTree = tree; *pPath = pathFromTree; return; } comp = sub->comps; if (strncmp(comp->name, start, end - start) == 0 && comp->name[end - start] == '\0') break; sub = sub->next; } // Found a Sub dir which matches at least partially. while (1) { getNextPath0Component(&start, &end); comp = comp->next; if (comp == NULL) break; if (*start == '\0' || strncmp(comp->name, start, end - start) != 0 || comp->name[end - start] != '\0') { // either the path ends here, or the path in the tree does. // either way, the last Tree is the one we want. *resTree = tree; *pPath = pathFromTree; return; } } // all components matched until the next MountTree tree = sub; } }
// make a list of uio_PathComps from a path string uio_PathComp * uio_makePathComps(const char *path, uio_PathComp *upComp) { const char *start, *end; char *str; uio_PathComp *result; uio_PathComp **compPtr; // Where to put the next PathComp compPtr = &result; getFirstPath0Component(path, &start, &end); while (*start != '\0') { str = uio_malloc(end - start + 1); memcpy(str, start, end - start); str[end - start] = '\0'; *compPtr = uio_PathComp_new(str, end - start, upComp); upComp = *compPtr; compPtr = &(*compPtr)->next; getNextPath0Component(&start, &end); } *compPtr = NULL; return result; }