Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
	}
}
Esempio n. 6
0
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;
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}
Esempio n. 9
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;
}