int ext4fs_find_file(const char *currpath, struct ext2fs_node *currroot, struct ext2fs_node **currfound, int *foundtype) { char fpath[strlen(currpath) + 1]; char *name = fpath; char *next; int type = FILETYPE_DIRECTORY; struct ext2fs_node *currnode = currroot; struct ext2fs_node *oldnode = currroot; int ret = 0; strncpy(fpath, currpath, strlen(currpath) + 1); /* Remove all leading slashes. */ while (*name == '/') name++; if (!*name) { *currfound = currnode; goto out; } for (;;) { /* Extract the actual part from the pathname. */ next = strchr(name, '/'); if (next) { /* Remove all leading slashes. */ while (*next == '/') *(next++) = '\0'; } if (type != FILETYPE_DIRECTORY) { ext4fs_free_node(currnode, currroot); return -ENOENT; } oldnode = currnode; /* Iterate over the directory. */ ret = ext4fs_iterate_dir(currnode, name, &currnode, &type); if (ret) return ret; ext4fs_free_node(oldnode, currroot); /* Found the node! */ if (!next || *next == '\0') { *currfound = currnode; goto out; } name = next; } out: if (foundtype) *foundtype = type; return ret; }
static int ext4fs_find_file1(const char *currpath, struct ext2fs_node *currroot, struct ext2fs_node **currfound, int *foundtype) { char fpath[strlen(currpath) + 1]; char *name = fpath; char *next; int status; int type = FILETYPE_DIRECTORY; struct ext2fs_node *currnode = currroot; struct ext2fs_node *oldnode = currroot; strncpy(fpath, currpath, strlen(currpath) + 1); /* Remove all leading slashes. */ while (*name == '/') name++; if (!*name) { *currfound = currnode; return 1; } for (;;) { int found; /* Extract the actual part from the pathname. */ next = strchr(name, '/'); if (next) { /* Remove all leading slashes. */ while (*next == '/') *(next++) = '\0'; } if (type != FILETYPE_DIRECTORY) { ext4fs_free_node(currnode, currroot); return 0; } oldnode = currnode; /* Iterate over the directory. */ found = ext4fs_iterate_dir(currnode, name, &currnode, &type); if (found == 0) return 0; if (found == -1) break; /* Read in the symlink and follow it. */ if (type == FILETYPE_SYMLINK) { char *symlink; /* Test if the symlink does not loop. */ if (++symlinknest == 8) { ext4fs_free_node(currnode, currroot); ext4fs_free_node(oldnode, currroot); return 0; } symlink = ext4fs_read_symlink(currnode); ext4fs_free_node(currnode, currroot); if (!symlink) { ext4fs_free_node(oldnode, currroot); return 0; } debug("Got symlink >%s<\n", symlink); if (symlink[0] == '/') { ext4fs_free_node(oldnode, currroot); oldnode = &ext4fs_root->diropen; } /* Lookup the node the symlink points to. */ status = ext4fs_find_file1(symlink, oldnode, &currnode, &type); free(symlink); if (status == 0) { ext4fs_free_node(oldnode, currroot); return 0; } } ext4fs_free_node(oldnode, currroot); /* Found the node! */ if (!next || *next == '\0') { *currfound = currnode; *foundtype = type; return 1; } name = next; } return -1; }