Exemplo n.º 1
0
static int
execute_delete_command(struct update_command_journal *j,
		       WIMStruct *wim,
		       const struct wimlib_update_command *delete_cmd)
{
	int flags;
	const tchar *wim_path;
	struct wim_dentry *tree;

	flags = delete_cmd->delete_.delete_flags;
	wim_path = delete_cmd->delete_.wim_path;

	DEBUG("Deleting WIM path \"%"TS"\" (flags=%#x)", wim_path, flags);

	tree = get_dentry(wim, wim_path, WIMLIB_CASE_PLATFORM_DEFAULT);
	if (!tree) {
		/* Path to delete does not exist in the WIM. */
		if (flags & WIMLIB_DELETE_FLAG_FORCE) {
			return 0;
		} else {
			ERROR("Path \"%"TS"\" does not exist in WIM image %d",
			      wim_path, wim->current_image);
			return WIMLIB_ERR_PATH_DOES_NOT_EXIST;
		}
	}

	if (dentry_is_directory(tree) && !(flags & WIMLIB_DELETE_FLAG_RECURSIVE)) {
		ERROR("Path \"%"TS"\" in WIM image %d is a directory "
		      "but a recursive delete was not requested",
		      wim_path, wim->current_image);
		return WIMLIB_ERR_IS_DIRECTORY;
	}

	return journaled_unlink(j, tree);
}
Exemplo n.º 2
0
void set_corpus(void)
{
	char start[1024];
	struct dentry *d;

	while (scanf("%s", start)!= EOF) {
		d = get_dentry(start);
		if (!d)
			return;

		add_to_dict(d);
	}
}
Exemplo n.º 3
0
/* Rename a file or directory in the WIM.
 *
 * This returns a -errno value.
 *
 * The journal @j is optional.
 */
int
rename_wim_path(WIMStruct *wim, const tchar *from, const tchar *to,
		CASE_SENSITIVITY_TYPE case_type,
		struct update_command_journal *j)
{
	struct wim_dentry *src;
	struct wim_dentry *dst;
	struct wim_dentry *parent_of_dst;
	int ret;

	/* This rename() implementation currently only supports actual files
	 * (not alternate data streams) */

	src = get_dentry(wim, from, case_type);
	if (!src)
		return -errno;

	dst = get_dentry(wim, to, case_type);

	if (dst) {
		/* Destination file exists */

		if (src == dst) /* Same file */
			return 0;

		if (!dentry_is_directory(src)) {
			/* Cannot rename non-directory to directory. */
			if (dentry_is_directory(dst))
				return -EISDIR;
		} else {
			/* Cannot rename directory to a non-directory or a non-empty
			 * directory */
			if (!dentry_is_directory(dst))
				return -ENOTDIR;
			if (dentry_has_children(dst))
				return -ENOTEMPTY;
		}
		parent_of_dst = dst->d_parent;
	} else {
		/* Destination does not exist */
		parent_of_dst = get_parent_dentry(wim, to, case_type);
		if (!parent_of_dst)
			return -errno;

		if (!dentry_is_directory(parent_of_dst))
			return -ENOTDIR;
	}

	/* @src can't be an ancestor of @dst.  Otherwise we're unlinking @src
	 * from the tree and creating a loop...  */
	if (is_ancestor(src, parent_of_dst))
		return -EBUSY;

	if (j) {
		if (dst)
			if (journaled_unlink(j, dst))
				return -ENOMEM;
		if (journaled_unlink(j, src))
			return -ENOMEM;
		if (journaled_change_name(j, src, path_basename(to)))
			return -ENOMEM;
		if (journaled_link(j, src, parent_of_dst))
			return -ENOMEM;
	} else {
		ret = dentry_set_name(src, path_basename(to));
		if (ret)
			return -ENOMEM;
		if (dst) {
			unlink_dentry(dst);
			free_dentry_tree(dst, wim->lookup_table);
		}
		unlink_dentry(src);
		dentry_add_child(parent_of_dst, src);
	}
	if (src->_full_path)
		for_dentry_in_tree(src, free_dentry_full_path, NULL);
	return 0;
}
Exemplo n.º 4
0
static int find_thread_link (const char * name, struct shim_qstr * link,
                             struct shim_dentry ** dentptr,
                             struct shim_thread ** threadptr)
{
    const char * next, * nextnext;
    int next_len;
    int pid = parse_thread_name(name, &next, &next_len, &nextnext);
    if (pid < 0)
        return pid;

    struct shim_thread * thread = lookup_thread(pid);
    struct shim_dentry * dent = NULL;
    int ret = 0;

    if (!thread)
        return -ENOENT;

    if (!thread->in_vm) {
        ret = -ENOENT;
        goto out;
    }

    lock(&thread->lock);

    if (next_len == static_strlen("root") && !memcmp(next, "root", next_len)) {
        dent = thread->root;
        get_dentry(dent);
    }

    if (next_len == static_strlen("cwd") && !memcmp(next, "cwd", next_len)) {
        dent = thread->cwd;
        get_dentry(dent);
    }

    if (next_len == static_strlen("exe") && !memcmp(next, "exe", next_len)) {
        struct shim_handle * exec = thread->exec;
        if (!exec->dentry) {
            unlock(&thread->lock);
            ret = -EINVAL;
            goto out;
        }
        dent = exec->dentry;
        get_dentry(dent);
    }

    unlock(&thread->lock);

    if (nextnext) {
        struct shim_dentry * next_dent = NULL;

        ret = path_lookupat(dent, nextnext, 0, &next_dent, dent->fs);
        if (ret < 0)
            goto out;

        put_dentry(dent);
        dent = next_dent;
    }

    if (link) {
        int size;
        char * path = dentry_get_path(dent, true, &size);
        qstrsetstr(link, path, size);
    }

    if (dentptr) {
        get_dentry(dent);
        *dentptr = dent;
    }

    if (threadptr) {
        get_thread(thread);
        *threadptr = thread;
    }

    ret = 0;
out:
    if (dent)
        put_dentry(dent);
    if (thread)
        put_thread(thread);
    return ret;
}