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; }
int ext4fs_open(struct ext2_data *data, const char *filename, struct ext2fs_node **inode) { struct ext2fs_node *fdiro = NULL; int status, ret; int type; status = ext4fs_find_file(filename, &data->diropen, &fdiro, &type); if (status) goto fail; if (type != FILETYPE_REG) return -EINVAL; if (!fdiro->inode_read) { ret = ext4fs_read_inode(fdiro->data, fdiro->ino, &fdiro->inode); if (ret) goto fail; } *inode = fdiro; return 0; fail: ext4fs_free_node(fdiro, &data->diropen); return -ENOENT; }
int ext4fs_open(const char *filename) { struct ext2fs_node *fdiro = NULL; int status; int len; if (ext4fs_root == NULL) return -1; ext4fs_file = NULL; status = ext4fs_find_file(filename, &ext4fs_root->diropen, &fdiro, FILETYPE_REG); if (status == 0) goto fail; if (!fdiro->inode_read) { status = ext4fs_read_inode(fdiro->data, fdiro->ino, &fdiro->inode); if (status == 0) goto fail; } len = __le32_to_cpu(fdiro->inode.size); ext4fs_file = fdiro; return len; fail: ext4fs_free_node(fdiro, &ext4fs_root->diropen); return -1; }
static DIR *ext_opendir(struct device_d *dev, const char *pathname) { struct ext_filesystem *fs = dev->priv; struct ext4fs_dir *ext4_dir; int type, ret; ext4_dir = xzalloc(sizeof(*ext4_dir)); ret = ext4fs_find_file(pathname, &fs->data->diropen, &ext4_dir->dirnode, &type); if (ret) { free(ext4_dir); return NULL; } if (type != FILETYPE_DIRECTORY) return NULL; ext4_dir->dir.priv = ext4_dir; ret = ext4fs_read_inode(ext4_dir->dirnode->data, ext4_dir->dirnode->ino, &ext4_dir->dirnode->inode); if (ret) { ext4fs_free_node(ext4_dir->dirnode, &fs->data->diropen); free(ext4_dir); return NULL; } return &ext4_dir->dir; }
void ext4fs_close(void) { if ((ext4fs_file != NULL) && (ext4fs_root != NULL)) { ext4fs_free_node(ext4fs_file, &ext4fs_root->diropen); ext4fs_file = NULL; } if (ext4fs_root != NULL) { free(ext4fs_root); ext4fs_root = NULL; } if (ext4fs_indir1_block != NULL) { free(ext4fs_indir1_block); ext4fs_indir1_block = NULL; ext4fs_indir1_size = 0; ext4fs_indir1_blkno = -1; } if (ext4fs_indir2_block != NULL) { free(ext4fs_indir2_block); ext4fs_indir2_block = NULL; ext4fs_indir2_size = 0; ext4fs_indir2_blkno = -1; } if (ext4fs_indir3_block != NULL) { free(ext4fs_indir3_block); ext4fs_indir3_block = NULL; ext4fs_indir3_size = 0; ext4fs_indir3_blkno = -1; } }
static int ext_close(struct device_d *dev, FILE *f) { struct ext_filesystem *fs = dev->priv; ext4fs_free_node(f->inode, &fs->data->diropen); return 0; }
static int ext_closedir(struct device_d *dev, DIR *dir) { struct ext_filesystem *fs = dev->priv; struct ext4fs_dir *ext4_dir = dir->priv; ext4fs_free_node(ext4_dir->dirnode, &fs->data->diropen); free(ext4_dir); return 0; }
static int ext_stat(struct device_d *dev, const char *filename, struct stat *s) { struct ext_filesystem *fs = dev->priv; struct ext2fs_node *node; int status, ret; status = ext4fs_find_file(filename, &fs->data->diropen, &node, NULL); if (status) return -ENOENT; ret = ext4fs_read_inode(node->data, node->ino, &node->inode); if (ret) return ret; s->st_size = __le32_to_cpu(node->inode.size); s->st_mode = __le16_to_cpu(node->inode.mode); ext4fs_free_node(node, &fs->data->diropen); return 0; }
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; }