Exemplo n.º 1
0
static int ext_readlink(struct device_d *dev, const char *pathname,
		char *buf, size_t bufsiz)
{
	struct ext_filesystem *fs = dev->priv;
	struct ext2fs_node *node;
	char *symlink;
	int ret, len, type;

	ret = ext4fs_find_file(pathname, &fs->data->diropen, &node, &type);
	if (ret)
		return ret;

	if (type != FILETYPE_SYMLINK)
		return -EINVAL;

	symlink = ext4fs_read_symlink(node);
	if (!symlink)
		return -ENOENT;

	len = min(bufsiz, strlen(symlink));

	memcpy(buf, symlink, len);

	free(symlink);

	return 0;
}
Exemplo n.º 2
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;
}