示例#1
0
文件: ops.c 项目: ackeack/workenv
/* Copies file/directory overwriting destination files if requested.  Returns
 * non-zero on error, otherwise zero is returned. */
static int
op_cp(void *data, const char src[], const char dst[], int overwrite)
{
#ifndef _WIN32
	char *escaped_src, *escaped_dst;
	char cmd[6 + PATH_MAX*2 + 1];
	int result;

	escaped_src = escape_filename(src, 0);
	escaped_dst = escape_filename(dst, 0);
	if(escaped_src == NULL || escaped_dst == NULL)
	{
		free(escaped_dst);
		free(escaped_src);
		return -1;
	}

	snprintf(cmd, sizeof(cmd),
			"cp %s -R " PRESERVE_FLAGS " %s %s",
			overwrite ? "" : NO_CLOBBER, escaped_src, escaped_dst);
	LOG_INFO_MSG("Running cp command: \"%s\"", cmd);
	result = background_and_wait_for_errors(cmd);

	free(escaped_dst);
	free(escaped_src);
	return result;
#else
	int ret;

	if(is_dir(src))
	{
		char cmd[6 + PATH_MAX*2 + 1];
		snprintf(cmd, sizeof(cmd), "xcopy \"%s\" \"%s\" ", src, dst);
		to_back_slash(cmd);

		if(is_vista_and_above())
			strcat(cmd, "/B ");
		if(overwrite)
		{
			strcat(cmd, "/Y ");
		}
		strcat(cmd, "/E /I /H /R > NUL");
		ret = system(cmd);
	}
	else
	{
		ret = (CopyFileA(src, dst, 0) == 0);
	}

	return ret;
#endif
}
示例#2
0
文件: ops.c 项目: ackeack/workenv
/* Moves file/directory overwriting destination files if requested.  Returns
 * non-zero on error, otherwise zero is returned. */
static int
op_mv(void *data, const char src[], const char dst[], int overwrite)
{
#ifndef _WIN32
	struct stat st;
	char *escaped_src, *escaped_dst;
	char cmd[6 + PATH_MAX*2 + 1];
	int result;

	if(lstat(dst, &st) == 0)
		return -1;

	escaped_src = escape_filename(src, 0);
	escaped_dst = escape_filename(dst, 0);
	if(escaped_src == NULL || escaped_dst == NULL)
	{
		free(escaped_dst);
		free(escaped_src);
		return -1;
	}

	snprintf(cmd, sizeof(cmd), "mv %s %s %s", overwrite ? "" : NO_CLOBBER,
			escaped_src, escaped_dst);
	free(escaped_dst);
	free(escaped_src);

	LOG_INFO_MSG("Running mv command: \"%s\"", cmd);
	if((result = background_and_wait_for_errors(cmd)) != 0)
		return result;

	if(path_starts_with(dst, cfg.trash_dir))
		add_to_trash(src, strrchr(dst, '/') + 1);
	else if(path_starts_with(src, cfg.trash_dir))
		remove_from_trash(strrchr(src, '/') + 1);
	return 0;
#else
	BOOL ret = MoveFile(src, dst);
	if(!ret && GetLastError() == 5)
	{
		int r = op_cp(data, src, dst, overwrite);
		if(r != 0)
			return r;
		return op_removesl(data, src, NULL);
	}
	return ret == 0;
#endif
}
示例#3
0
文件: utils.c 项目: jubalh/vifm
char *
expand_envvars(const char str[], int escape_vals)
{
	char *result = NULL;
	size_t len = 0;
	int prev_slash = 0;
	while(*str != '\0')
	{
		if(!prev_slash && *str == '$' && isalpha(str[1]))
		{
			char var_name[NAME_MAX];
			const char *p = str + 1;
			char *q = var_name;
			const char *var_value;

			while((isalnum(*p) || *p == '_') && q - var_name < sizeof(var_name) - 1)
				*q++ = *p++;
			*q = '\0';

			var_value = env_get(var_name);
			if(var_value != NULL)
			{
				char *escaped_var_value = NULL;
				if(escape_vals)
				{
					escaped_var_value = escape_filename(var_value, 1);
					var_value = escaped_var_value;
				}

				result = extend_string(result, var_value, &len);
				free(escaped_var_value);

				str = p;
			}
			else
			{
				str++;
			}
		}
		else
		{
			prev_slash = (*str == '\\') ? !prev_slash : 0;

			if(!prev_slash || escape_vals)
			{
				const char single_char[] = { *str, '\0' };
				result = extend_string(result, single_char, &len);
			}

			str++;
		}
	}
	if(result == NULL)
		result = strdup("");
	return result;
}
示例#4
0
文件: ops.c 项目: ackeack/workenv
static int
op_symlink(void *data, const char *src, const char *dst)
{
	char *escaped_src, *escaped_dst;
	char cmd[6 + PATH_MAX*2 + 1];
	int result;
#ifdef _WIN32
	char buf[PATH_MAX + 2];
#endif

	escaped_src = escape_filename(src, 0);
	escaped_dst = escape_filename(dst, 0);
	if(escaped_src == NULL || escaped_dst == NULL)
	{
		free(escaped_dst);
		free(escaped_src);
		return -1;
	}

#ifndef _WIN32
	snprintf(cmd, sizeof(cmd), "ln -s %s %s", escaped_src, escaped_dst);
	LOG_INFO_MSG("Running ln command: \"%s\"", cmd);
	result = background_and_wait_for_errors(cmd);
#else
	if(GetModuleFileNameA(NULL, buf, ARRAY_LEN(buf)) == 0)
	{
		free(escaped_dst);
		free(escaped_src);
		return -1;
	}

	*strrchr(buf, '\\') = '\0';
	snprintf(cmd, sizeof(cmd), "%s\\win_helper -s %s %s", buf, escaped_src,
			escaped_dst);
	result = system(cmd);
#endif

	free(escaped_dst);
	free(escaped_src);
	return result;
}
示例#5
0
文件: ops.c 项目: ackeack/workenv
static int
op_chmodr(void *data, const char *src, const char *dst)
{
	char cmd[128 + PATH_MAX];
	char *escaped;

	escaped = escape_filename(src, 0);
	snprintf(cmd, sizeof(cmd), "chmod -R %s %s", (char *)data, escaped);
	free(escaped);
	start_background_job(cmd, 0);
	return 0;
}
示例#6
0
文件: ops.c 项目: ackeack/workenv
static int
op_removesl(void *data, const char *src, const char *dst)
{
#ifndef _WIN32
	char *escaped;
	char cmd[16 + PATH_MAX];
	int result;

	escaped = escape_filename(src, 0);
	if(escaped == NULL)
		return -1;

	snprintf(cmd, sizeof(cmd), "rm -rf %s", escaped);
	LOG_INFO_MSG("Running rm command: \"%s\"", cmd);
	result = background_and_wait_for_errors(cmd);

	free(escaped);
	return result;
#else
	if(is_dir(src))
	{
		char buf[PATH_MAX];
		int err;
		int i;
		snprintf(buf, sizeof(buf), "%s%c", src, '\0');
		for(i = 0; buf[i] != '\0'; i++)
			if(buf[i] == '/')
				buf[i] = '\\';
		SHFILEOPSTRUCTA fo = {
			.hwnd = NULL,
			.wFunc = FO_DELETE,
			.pFrom = buf,
			.pTo = NULL,
			.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI,
		};
		err = SHFileOperation(&fo);
		log_msg("Error: %d", err);
		return err;
	}
	else
	{
		int ok;
		DWORD attributes = GetFileAttributesA(src);
		if(attributes & FILE_ATTRIBUTE_READONLY)
			SetFileAttributesA(src, attributes & ~FILE_ATTRIBUTE_READONLY);
		ok = DeleteFile(src);
		if(!ok)
			LOG_WERROR(GetLastError());
		return !ok;
	}
#endif
}
示例#7
0
文件: ops.c 项目: ackeack/workenv
static int
op_chmod(void *data, const char *src, const char *dst)
{
	char cmd[128 + PATH_MAX];
	char *escaped;

	escaped = escape_filename(src, 0);
	snprintf(cmd, sizeof(cmd), "chmod %s %s", (char *)data, escaped);
	free(escaped);

	LOG_INFO_MSG("Running chmod command: \"%s\"", cmd);
	return background_and_wait_for_errors(cmd);
}
示例#8
0
文件: ops.c 项目: ackeack/workenv
static int
op_rmdir(void *data, const char *src, const char *dst)
{
#ifndef _WIN32
	char cmd[128 + PATH_MAX];
	char *escaped;

	escaped = escape_filename(src, 0);
	snprintf(cmd, sizeof(cmd), "rmdir %s", escaped);
	free(escaped);
	LOG_INFO_MSG("Running rmdir command: \"%s\"", cmd);
	return background_and_wait_for_errors(cmd);
#else
	return RemoveDirectory(src) == 0;
#endif
}
示例#9
0
文件: ops.c 项目: ackeack/workenv
static int
op_mkdir(void *data, const char *src, const char *dst)
{
#ifndef _WIN32
	char cmd[128 + PATH_MAX];
	char *escaped;

	escaped = escape_filename(src, 0);
	snprintf(cmd, sizeof(cmd), "mkdir %s %s", (data == NULL) ? "" : "-p",
			escaped);
	free(escaped);
	LOG_INFO_MSG("Running mkdir command: \"%s\"", cmd);
	return background_and_wait_for_errors(cmd);
#else
	if(data == NULL)
	{
		return CreateDirectory(src, NULL) == 0;
	}
	else
	{
		char *p;
		char t;

		p = strchr(src + 2, '/');
		do
		{
			t = *p;
			*p = '\0';

			if(!is_dir(src))
			{
				if(!CreateDirectory(src, NULL))
				{
					*p = t;
					return -1;
				}
			}

			*p = t;
			if((p = strchr(p + 1, '/')) == NULL)
				p = (char *)src + strlen(src);
		}
		while(t != '\0');
		return 0;
	}
#endif
}
示例#10
0
static void
complete_with_shared(const char *server, const char *file)
{
	NET_API_STATUS res;
	size_t len = strlen(file);

	do
	{
		PSHARE_INFO_502 buf_ptr;
		DWORD er = 0, tr = 0, resume = 0;
		wchar_t *wserver = to_wide(server + 2);

		if(wserver == NULL)
		{
			show_error_msg("Memory Error", "Unable to allocate enough memory");
			return;
		}

		res = NetShareEnum(wserver, 502, (LPBYTE *)&buf_ptr, -1, &er, &tr, &resume);
		free(wserver);
		if(res == ERROR_SUCCESS || res == ERROR_MORE_DATA)
		{
			PSHARE_INFO_502 p;
			DWORD i;

			p = buf_ptr;
			for(i = 1; i <= er; i++)
			{
				char buf[512];
				WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)p->shi502_netname, -1, buf,
						sizeof(buf), NULL, NULL);
				strcat(buf, "/");
				if(strnoscmp(buf, file, len) == 0)
				{
					char *const escaped = escape_filename(buf, 1);
					vle_compl_add_match(escaped);
					free(escaped);
				}
				p++;
			}
			NetApiBufferFree(buf_ptr);
		}
	}
	while(res == ERROR_MORE_DATA);
}
示例#11
0
文件: ops.c 项目: ackeack/workenv
static int
op_chgrp(void *data, const char *src, const char *dst)
{
#ifndef _WIN32
	char cmd[10 + 32 + PATH_MAX];
	char *escaped;
	gid_t gid = (gid_t)(long)data;

	escaped = escape_filename(src, 0);
	snprintf(cmd, sizeof(cmd), "chown -fR :%u %s", gid, escaped);
	free(escaped);

	LOG_INFO_MSG("Running chgrp command: \"%s\"", cmd);
	return background_and_wait_for_errors(cmd);
#else
	return -1;
#endif
}
示例#12
0
文件: fuse.c 项目: jubalh/vifm
void
fuse_unmount_all(void)
{
	fuse_mount_t *runner;

	if(fuse_mounts == NULL)
	{
		return;
	}

	if(vifm_chdir("/") != 0)
	{
		return;
	}

	runner = fuse_mounts;
	while(runner != NULL)
	{
		char buf[14 + PATH_MAX + 1];
		char *escaped_filename;

		escaped_filename = escape_filename(runner->mount_point, 0);
		snprintf(buf, sizeof(buf), "%s %s", curr_stats.fuse_umount_cmd,
				escaped_filename);
		free(escaped_filename);

		(void)vifm_system(buf);
		if(path_exists(runner->mount_point, DEREF))
		{
			rmdir(runner->mount_point);
		}

		runner = runner->next;
	}

	leave_invalid_dir(&lwin);
	leave_invalid_dir(&rwin);
}
示例#13
0
文件: ops.c 项目: ackeack/workenv
static int
op_mkfile(void *data, const char *src, const char *dst)
{
#ifndef _WIN32
	char cmd[128 + PATH_MAX];
	char *escaped;

	escaped = escape_filename(src, 0);
	snprintf(cmd, sizeof(cmd), "touch %s", escaped);
	free(escaped);
	LOG_INFO_MSG("Running touch command: \"%s\"", cmd);
	return background_and_wait_for_errors(cmd);
#else
	HANDLE hfile;

	hfile = CreateFileA(src, 0, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
	if(hfile == INVALID_HANDLE_VALUE)
		return -1;

	CloseHandle(hfile);
	return 0;
#endif
}
示例#14
0
文件: quickview.c 项目: jubalh/vifm
/* Returns a pointer to newly allocated memory, which should be released by the
 * caller. */
static char *
get_viewer_command(const char viewer[])
{
	char *result;
	if(strchr(viewer, '%') == NULL)
	{
		char *escaped;
		FileView *view = curr_stats.preview_hint;
		if(view == NULL)
		{
			view = curr_view;
		}

		escaped = escape_filename(get_current_file_name(view), 0);
		result = format_str("%s %s", viewer, escaped);
		free(escaped);
	}
	else
	{
		result = expand_macros(viewer, NULL, NULL, 1);
	}
	return result;
}
示例#15
0
文件: macros.c 项目: langner/vifm
/* Appends the path to the expanded string with either proper escaping or
 * quoting.  Returns NULL on not enough memory error. */
static char *
append_path_to_expanded(char expanded[], int quotes, const char path[])
{
	if(quotes)
	{
		const char *const dquoted = enclose_in_dquotes(path);
		expanded = append_to_expanded(expanded, dquoted);
	}
	else
	{
		char *const escaped = escape_filename(path, 0);
		if(escaped == NULL)
		{
			show_error_msg("Memory Error", "Unable to allocate enough memory");
			free(expanded);
			return NULL;
		}

		expanded = append_to_expanded(expanded, escaped);
		free(escaped);
	}

	return expanded;
}
示例#16
0
文件: fuse.c 项目: jubalh/vifm
int
fuse_try_unmount(FileView *view)
{
	char buf[14 + PATH_MAX + 1];
	fuse_mount_t *runner, *trailer;
	int status;
	fuse_mount_t *sniffer;
	char *escaped_mount_point;

	runner = fuse_mounts;
	trailer = NULL;
	while(runner)
	{
		if(paths_are_equal(runner->mount_point, view->curr_dir))
		{
			break;
		}

		trailer = runner;
		runner = runner->next;
	}

	if(runner == NULL)
	{
		return 0;
	}

	/* we are exiting a top level dir */
	escaped_mount_point = escape_filename(runner->mount_point, 0);
	snprintf(buf, sizeof(buf), "%s %s 2> /dev/null", curr_stats.fuse_umount_cmd,
			escaped_mount_point);
	LOG_INFO_MSG("FUSE unmount command: `%s`", buf);
	free(escaped_mount_point);

	/* Have to chdir to parent temporarily, so that this DIR can be unmounted. */
	if(vifm_chdir(cfg.fuse_home) != 0)
	{
		show_error_msg("FUSE UMOUNT ERROR", "Can't chdir to FUSE home");
		return -1;
	}

	status_bar_message("FUSE unmounting selected file, please stand by..");
	status = background_and_wait_for_status(buf, 0, NULL);
	clean_status_bar();
	/* check child status */
	if(!WIFEXITED(status) || WEXITSTATUS(status))
	{
		werase(status_bar);
		show_error_msgf("FUSE UMOUNT ERROR", "Can't unmount %s.  It may be busy.",
				runner->source_file_name);
		(void)vifm_chdir(flist_get_dir(view));
		return -1;
	}

	/* remove the directory we created for the mount */
	if(path_exists(runner->mount_point, DEREF))
		rmdir(runner->mount_point);

	/* remove mount point from fuse_mount_t */
	sniffer = runner->next;
	if(trailer)
		trailer->next = sniffer ? sniffer : NULL;
	else
		fuse_mounts = sniffer;

	updir_from_mount(view, runner);
	free(runner);
	return 1;
}
示例#17
0
文件: fuse.c 项目: jubalh/vifm
/* Builds the mount command based on the file type program.
 * Accepted formats are:
 *   FUSE_MOUNT|some_mount_command %SOURCE_FILE %DESTINATION_DIR [%FOREGROUND]
 * and
 *   FUSE_MOUNT2|some_mount_command %PARAM %DESTINATION_DIR [%FOREGROUND]
 * %CLEAR is an obsolete name of %FOREGROUND.
 * Always sets value of *foreground. */
TSTATIC void
format_mount_command(const char mount_point[], const char file_name[],
		const char param[], const char format[], size_t buf_size, char buf[],
		int *foreground)
{
	char *buf_pos;
	const char *prog_pos;
	char *escaped_path;
	char *escaped_mount_point;

	*foreground = 0;

	escaped_path = escape_filename(file_name, 0);
	escaped_mount_point = escape_filename(mount_point, 0);

	buf_pos = buf;
	buf_pos[0] = '\0';

	prog_pos = after_first(format, '|');
	while(*prog_pos != '\0')
	{
		if(*prog_pos == '%')
		{
			char cmd_buf[96];
			char *cmd_pos;

			cmd_pos = cmd_buf;
			while(*prog_pos != '\0' && *prog_pos != ' ')
			{
				*cmd_pos = *prog_pos;
				if(cmd_pos - cmd_buf < sizeof(cmd_buf))
					cmd_pos++;
				prog_pos++;
			}
			*cmd_pos = '\0';

			if(!strcmp(cmd_buf, "%SOURCE_FILE"))
			{
				copy_str(buf_pos, buf_size - (buf_pos - buf), escaped_path);
				buf_pos += strlen(buf_pos);
			}
			else if(!strcmp(cmd_buf, "%PARAM"))
			{
				copy_str(buf_pos, buf_size - (buf_pos - buf), param);
				buf_pos += strlen(buf_pos);
			}
			else if(!strcmp(cmd_buf, "%DESTINATION_DIR"))
			{
				copy_str(buf_pos, buf_size - (buf_pos - buf), escaped_mount_point);
				buf_pos += strlen(buf_pos);
			}
			else if(!strcmp(cmd_buf, "%FOREGROUND") || !strcmp(cmd_buf, "%CLEAR"))
			{
				*foreground = 1;
			}
		}
		else
		{
			*buf_pos = *prog_pos;
			if(buf_pos - buf < buf_size - 1)
				buf_pos++;
			prog_pos++;
		}
	}

	*buf_pos = '\0';
	free(escaped_mount_point);
	free(escaped_path);
}
示例#18
0
文件: fuse.c 项目: jubalh/vifm
/* mount_point should be an array of at least PATH_MAX characters
 * Returns non-zero on error. */
static int
fuse_mount(FileView *view, char file_full_path[], const char param[],
		const char program[], char mount_point[])
{
	/* TODO: refactor this function fuse_mount(). */

	int mount_point_id;
	char buf[2*PATH_MAX];
	char *escaped_filename;
	int foreground;
	char errors_file[PATH_MAX];
	int status;
	int cancelled;

	escaped_filename = escape_filename(get_current_file_name(view), 0);

	mount_point_id = get_last_mount_point_id(fuse_mounts);
	do
	{
		snprintf(mount_point, PATH_MAX, "%s/%03d_%s", cfg.fuse_home,
				++mount_point_id, get_current_file_name(view));
	}
	while(path_exists(mount_point, DEREF));
	if(os_mkdir(mount_point, S_IRWXU) != 0)
	{
		free(escaped_filename);
		show_error_msg("Unable to create FUSE mount directory", mount_point);
		return -1;
	}
	free(escaped_filename);

	/* Just before running the mount,
		 I need to chdir out temporarily from any FUSE mounted
		 paths, Otherwise the fuse-zip command fails with
		 "fusermount: failed to open current directory: permission denied"
		 (this happens when mounting JARs from mounted JARs) */
	if(vifm_chdir(cfg.fuse_home) != 0)
	{
		show_error_msg("FUSE MOUNT ERROR", "Can't chdir() to FUSE home");
		return -1;
	}

	format_mount_command(mount_point, file_full_path, param, program, sizeof(buf),
			buf, &foreground);

	status_bar_message("FUSE mounting selected file, please stand by..");

	if(foreground)
	{
		def_prog_mode();
		endwin();
	}

	generate_tmp_file_name("vifm.errors", errors_file, sizeof(errors_file));

	strcat(buf, " 2> ");
	strcat(buf, errors_file);
	LOG_INFO_MSG("FUSE mount command: `%s`", buf);
	status = background_and_wait_for_status(buf, !foreground, &cancelled);

	clean_status_bar();

	/* Check child process exit status. */
	if(!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS)
	{
		FILE *ef;

		if(!WIFEXITED(status))
		{
			LOG_ERROR_MSG("FUSE mounter didn't exit!");
		}
		else
		{
			LOG_ERROR_MSG("FUSE mount command exit status: %d", WEXITSTATUS(status));
		}

		ef = os_fopen(errors_file, "r");
		if(ef == NULL)
		{
			LOG_SERROR_MSG(errno, "Failed to open temporary stderr file: %s",
					errors_file);
		}
		show_errors_from_file(ef, "FUSE mounter error");

		werase(status_bar);

		if(cancelled)
		{
			status_bar_message("FUSE mount cancelled");
			curr_stats.save_msg = 1;
		}
		else
		{
			show_error_msg("FUSE MOUNT ERROR", file_full_path);
		}

		if(unlink(errors_file) != 0)
		{
			LOG_SERROR_MSG(errno, "Error file deletion failure: %d", errors_file);
		}

		/* Remove the directory we created for the mount. */
		(void)rmdir(mount_point);

		(void)vifm_chdir(flist_get_dir(view));
		return -1;
	}
	unlink(errors_file);
	status_bar_message("FUSE mount success");

	register_mount(&fuse_mounts, file_full_path, mount_point, mount_point_id);

	return 0;
}
示例#19
0
文件: fuse.c 项目: lyuts/vifm
/*
 * mount_point should be an array of at least PATH_MAX characters
 * Returns non-zero on error.
 */
static int
fuse_mount(FileView *view, char *file_full_path, const char *param,
		const char *program, char *mount_point)
{
	/* TODO: refactor this function fuse_mount() */

	fuse_mount_t *runner = NULL;
	int mount_point_id = 0;
	fuse_mount_t *fuse_item = NULL;
	char buf[2*PATH_MAX];
	char *escaped_filename;
	int clear_before_mount = 0;
	char errors_file[PATH_MAX];
	int status;

	escaped_filename = escape_filename(get_current_file_name(view), 0);

	/* get mount_point_id + mount_point and set runner pointing to the list's
	 * tail */
	if(fuse_mounts != NULL)
	{
		runner = fuse_mounts;
		while(runner->next != NULL)
			runner = runner->next;
		mount_point_id = runner->mount_point_id;
	}
	do
	{
		snprintf(mount_point, PATH_MAX, "%s/%03d_%s", cfg.fuse_home,
				++mount_point_id, get_current_file_name(view));
	}
	while(path_exists(mount_point));
	if(make_dir(mount_point, S_IRWXU) != 0)
	{
		free(escaped_filename);
		show_error_msg("Unable to create FUSE mount directory", mount_point);
		return -1;
	}
	free(escaped_filename);

	/* Just before running the mount,
		 I need to chdir out temporarily from any FUSE mounted
		 paths, Otherwise the fuse-zip command fails with
		 "fusermount: failed to open current directory: permission denied"
		 (this happens when mounting JARs from mounted JARs) */
	if(vifm_chdir(cfg.fuse_home) != 0)
	{
		show_error_msg("FUSE MOUNT ERROR", "Can't chdir() to FUSE home");
		return -1;
	}

	clear_before_mount = format_mount_command(mount_point, file_full_path, param,
			program, sizeof(buf), buf);

	status_bar_message("FUSE mounting selected file, please stand by..");

	if(clear_before_mount)
	{
		def_prog_mode();
		endwin();
	}

	generate_tmp_file_name("vifm.errors", errors_file, sizeof(errors_file));

	strcat(buf, " 2> ");
	strcat(buf, errors_file);
	LOG_INFO_MSG("FUSE mount command: `%s`", buf);
	status = background_and_wait_for_status(buf);

	clean_status_bar();

	/* check child status */
	if(!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status)))
	{
		FILE *ef = fopen(errors_file, "r");
		print_errors(ef);
		unlink(errors_file);

		werase(status_bar);
		/* remove the directory we created for the mount */
		if(path_exists(mount_point))
			rmdir(mount_point);
		show_error_msg("FUSE MOUNT ERROR", file_full_path);
		(void)vifm_chdir(view->curr_dir);
		return -1;
	}
	unlink(errors_file);
	status_bar_message("FUSE mount success");

	fuse_item = malloc(sizeof(*fuse_item));
	copy_str(fuse_item->source_file_name, sizeof(fuse_item->source_file_name),
			file_full_path);
	strcpy(fuse_item->source_file_dir, view->curr_dir);
	canonicalize_path(mount_point, fuse_item->mount_point,
			sizeof(fuse_item->mount_point));
	fuse_item->mount_point_id = mount_point_id;
	fuse_item->next = NULL;
	if(fuse_mounts == NULL)
		fuse_mounts = fuse_item;
	else
		runner->next = fuse_item;

	return 0;
}
示例#20
0
List *list_available_extensions_in_archive_dir(Platform platform)
{
    List *result = NIL;
	DIR		   *dir;
	struct dirent *de;

    char *pf_name    = escape_filename(platform->os_name);
    char *pf_version = escape_filename(platform->os_version);
    char *pf_arch    = escape_filename(platform->arch);

	dir = AllocateDir(pginstall_archive_dir);
	while ((de = ReadDir(dir, pginstall_archive_dir)) != NULL)
	{
        pginstall_extension *ext;
        char *extname   = NULL;
        char *pgversion = NULL;
        char *os        = NULL ;
        char *version   = NULL;
        char *arch      = NULL;
        char *ptr       = NULL;

		/* must be a .tar.gz file ... */
		if (!is_extension_archive_filename(de->d_name))
			continue;

        /* extract extension name from filename */
        extname = pstrdup(de->d_name);

        if ((ptr = strstr(extname, "--")) != NULL)
        {
            *ptr = '\0';
            pgversion = ptr+2;
        }

        /* parse and check pgversion */
        if (pgversion && (ptr = strstr(pgversion, "--")) != NULL)
        {
            *ptr = '\0';
            os = ptr+2;

            if (strcmp(pgversion, PG_VERSION) != 0)
                continue;
        }

        /* parse and check os name */
        if (os && (ptr = strstr(os, "--")) != NULL)
        {
            *ptr = '\0';
            version = ptr+2;

            if (strcmp(os, pf_name) != 0)
                continue;
        }

        /* parse and check os version */
        if (version && (ptr = strstr(version, "--")) != NULL)
        {
            *ptr = '\0';
            arch = ptr+2;

            if (strcmp(version, pf_version) != 0)
                continue;
        }

        /* parse and check arc */
        if (arch && (ptr = strstr(arch, ".")) != NULL)
        {
            *ptr = '\0';

            if (strcmp(arch, pf_arch) != 0)
                continue;
        }

        ext = (pginstall_extension *)palloc(sizeof(pginstall_extension));

        ext->id          = -1;
        ext->shortname   = pstrdup(extname);
        ext->fullname    = NULL;
        ext->uri         = pstrdup(de->d_name);
        ext->description = NULL;

        result = lappend(result, ext);
	}
	FreeDir(dir);

    return result;
}
示例#21
0
/*
 * At CREATE EXTENSION time we check if the extension is already available,
 * which is driven by the presence of its control file on disk.
 *
 * If the extension is not already available, we ask the repository server for
 * it, and unpack received binary archive to the right place.
 *
 * TODO: actually talk to the repository server. Current prototype version
 * directly uses the local archive cache.
 */
void
download_and_unpack_archive(const char *extname)
{
    PlatformData platform;
    char *control_filename = get_extension_control_filename(extname);
    char *archive_filename;

    /*
     * No cache, download again each time asked: any existing control file for
     * the extension could be one we left behind from a previous version of the
     * extension's archive.
     *
     * This also means that if an extension is already provided by the
     * operating system, by installing pginstall you give preference to
     * pginstall builds.
     */
    current_platform(&platform);
    archive_filename = psprintf("%s/%s--%s--%s--%s--%s.tar.gz",
                                pginstall_archive_dir,
                                extname,
                                PG_VERSION,
                                escape_filename(platform.os_name),
                                escape_filename(platform.os_version),
                                escape_filename(platform.arch));

    /*
     * The local repository might be added to directly by the pginstall build
     * client, and pginstall.serve_from_archive_dir allows to setup the
     * pginstall.archive_dir as a local authoritative source.
     *
     * Given that, we only download an archive file when
     *
     *  1. we have a pginstall.repository
     *  2. pginstall.serve_from_archive_dir is false
     *  3. pginstall.serve_from_archive_dir is true but we don't have the
     *     needed file locally
     */
    if (pginstall_repository != NULL && strcmp(pginstall_repository, "") != 0)
    {
        if (pginstall_serve_from_archive_dir
            && access(archive_filename, R_OK) == 0)
        {
            /* no download here. */
            (void)0;
        }
        else
        {
            download_archive(archive_filename, extname, &platform);
        }
    }

    /*
     * Even if we didn't find any extension's archive file for our platform on
     * the repository server, it could be that the extension is available
     * locally either through the OS packages or maybe a local developer setup
     * (make install).
     *
     * In case when when extension control file still doesn't exists after
     * we've been communicating with the repository server, PostgreSQL will
     * issue its usual error message about a missing control file.
     */
    if (access(archive_filename, R_OK) == 0)
    {
        extract(extname, archive_filename);

        /* now rewrite the control file to "relocate" the extension */
        rewrite_control_file(extname, control_filename);
    }
    return;
}
示例#22
0
/*
 * Restore files
 */
bool restore_cmd(UAContext *ua, const char *cmd)
{
   RESTORE_CTX rx;                    /* restore context */
   POOL_MEM buf;
   JOBRES *job;
   int i;
   JCR *jcr = ua->jcr;
   char *escaped_bsr_name = NULL;
   char *escaped_where_name = NULL;
   char *strip_prefix, *add_prefix, *add_suffix, *regexp;
   strip_prefix = add_prefix = add_suffix = regexp = NULL;

   memset(&rx, 0, sizeof(rx));
   rx.path = get_pool_memory(PM_FNAME);
   rx.fname = get_pool_memory(PM_FNAME);
   rx.JobIds = get_pool_memory(PM_FNAME);
   rx.JobIds[0] = 0;
   rx.BaseJobIds = get_pool_memory(PM_FNAME);
   rx.query = get_pool_memory(PM_FNAME);
   rx.bsr = new_bsr();

   i = find_arg_with_value(ua, "comment");
   if (i >= 0) {
      rx.comment = ua->argv[i];
      if (!is_comment_legal(ua, rx.comment)) {
         goto bail_out;
      }
   }

   i = find_arg_with_value(ua, "backupformat");
   if (i >= 0) {
      rx.backup_format = ua->argv[i];
   }

   i = find_arg_with_value(ua, "where");
   if (i >= 0) {
      rx.where = ua->argv[i];
   }

   i = find_arg_with_value(ua, "replace");
   if (i >= 0) {
      rx.replace = ua->argv[i];
   }

   i = find_arg_with_value(ua, "pluginoptions");
   if (i >= 0) {
      rx.plugin_options = ua->argv[i];
   }

   i = find_arg_with_value(ua, "strip_prefix");
   if (i >= 0) {
      strip_prefix = ua->argv[i];
   }

   i = find_arg_with_value(ua, "add_prefix");
   if (i >= 0) {
      add_prefix = ua->argv[i];
   }

   i = find_arg_with_value(ua, "add_suffix");
   if (i >= 0) {
      add_suffix = ua->argv[i];
   }

   i = find_arg_with_value(ua, "regexwhere");
   if (i >= 0) {
      rx.RegexWhere = ua->argv[i];
   }

   if (strip_prefix || add_suffix || add_prefix) {
      int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
      regexp = (char *)bmalloc(len * sizeof(char));

      bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
      rx.RegexWhere = regexp;
   }

   /* TODO: add acl for regexwhere ? */

   if (rx.RegexWhere) {
      if (!acl_access_ok(ua, Where_ACL, rx.RegexWhere, true)) {
         ua->error_msg(_("\"RegexWhere\" specification not authorized.\n"));
         goto bail_out;
      }
   }

   if (rx.where) {
      if (!acl_access_ok(ua, Where_ACL, rx.where, true)) {
         ua->error_msg(_("\"where\" specification not authorized.\n"));
         goto bail_out;
      }
   }

   if (!open_client_db(ua, true)) {
      goto bail_out;
   }

   /* Ensure there is at least one Restore Job */
   LockRes();
   foreach_res(job, R_JOB) {
      if (job->JobType == JT_RESTORE) {
         if (!rx.restore_job) {
            rx.restore_job = job;
         }
         rx.restore_jobs++;
      }
   }
   UnlockRes();
   if (!rx.restore_jobs) {
      ua->error_msg(_(
         "No Restore Job Resource found in bareos-dir.conf.\n"
         "You must create at least one before running this command.\n"));
      goto bail_out;
   }

   /*
    * Request user to select JobIds or files by various different methods
    *  last 20 jobs, where File saved, most recent backup, ...
    *  In the end, a list of files are pumped into
    *  add_findex()
    */
   switch (user_select_jobids_or_files(ua, &rx)) {
   case 0:                            /* error */
      goto bail_out;
   case 1:                            /* selected by jobid */
      get_and_display_basejobs(ua, &rx);
      if (!build_directory_tree(ua, &rx)) {
         ua->send_msg(_("Restore not done.\n"));
         goto bail_out;
      }
      break;
   case 2:                            /* selected by filename, no tree needed */
      break;
   }

   if (rx.bsr->JobId) {
      char ed1[50];
      if (!complete_bsr(ua, rx.bsr)) {   /* find Vol, SessId, SessTime from JobIds */
         ua->error_msg(_("Unable to construct a valid BSR. Cannot continue.\n"));
         goto bail_out;
      }
      if (!(rx.selected_files = write_bsr_file(ua, rx))) {
         ua->warning_msg(_("No files selected to be restored.\n"));
         goto bail_out;
      }
      display_bsr_info(ua, rx);          /* display vols needed, etc */

      if (rx.selected_files==1) {
         ua->info_msg(_("\n1 file selected to be restored.\n\n"));
      } else {
         ua->info_msg(_("\n%s files selected to be restored.\n\n"),
            edit_uint64_with_commas(rx.selected_files, ed1));
      }
   } else {
      ua->warning_msg(_("No files selected to be restored.\n"));
      goto bail_out;
   }

   if (rx.restore_jobs == 1) {
      job = rx.restore_job;
   } else {
      job = get_restore_job(ua);
   }
   if (!job) {
      goto bail_out;
   }

   if (!get_client_name(ua, &rx)) {
      goto bail_out;
   }
   if (!rx.ClientName) {
      ua->error_msg(_("No Client resource found!\n"));
      goto bail_out;
   }
   if (!get_restore_client_name(ua, rx)) {
      goto bail_out;
   }

   escaped_bsr_name = escape_filename(jcr->RestoreBootstrap);

   Mmsg(ua->cmd,
        "run job=\"%s\" client=\"%s\" restoreclient=\"%s\" storage=\"%s\""
        " bootstrap=\"%s\" files=%u catalog=\"%s\"",
        job->name(), rx.ClientName, rx.RestoreClientName,
        rx.store?rx.store->name():"",
        escaped_bsr_name ? escaped_bsr_name : jcr->RestoreBootstrap,
        rx.selected_files, ua->catalog->name());

   /*
    * Build run command
    */
   if (rx.backup_format) {
      Mmsg(buf, " backupformat=%s", rx.backup_format);
      pm_strcat(ua->cmd, buf);
   }

   pm_strcpy(buf, "");
   if (rx.RegexWhere) {
      escaped_where_name = escape_filename(rx.RegexWhere);
      Mmsg(buf, " regexwhere=\"%s\"",
           escaped_where_name ? escaped_where_name : rx.RegexWhere);

   } else if (rx.where) {
      escaped_where_name = escape_filename(rx.where);
      Mmsg(buf," where=\"%s\"",
           escaped_where_name ? escaped_where_name : rx.where);
   }
   pm_strcat(ua->cmd, buf);

   if (rx.replace) {
      Mmsg(buf, " replace=%s", rx.replace);
      pm_strcat(ua->cmd, buf);
   }

   if (rx.plugin_options) {
      Mmsg(buf, " pluginoptions=%s", rx.plugin_options);
      pm_strcat(ua->cmd, buf);
   }

   if (rx.comment) {
      Mmsg(buf, " comment=\"%s\"", rx.comment);
      pm_strcat(ua->cmd, buf);
   }

   if (escaped_bsr_name != NULL) {
      bfree(escaped_bsr_name);
   }

   if (escaped_where_name != NULL) {
      bfree(escaped_where_name);
   }

   if (regexp) {
      bfree(regexp);
   }

   if (find_arg(ua, NT_("yes")) > 0) {
      pm_strcat(ua->cmd, " yes");    /* pass it on to the run command */
   }

   Dmsg1(200, "Submitting: %s\n", ua->cmd);

   /*
    * Transfer jobids to jcr to for picking up restore objects
    */
   jcr->JobIds = rx.JobIds;
   rx.JobIds = NULL;

   parse_ua_args(ua);
   run_cmd(ua, ua->cmd);
   free_rx(&rx);
   garbage_collect_memory();       /* release unused memory */
   return true;

bail_out:
   if (escaped_bsr_name != NULL) {
      bfree(escaped_bsr_name);
   }

   if (escaped_where_name != NULL) {
      bfree(escaped_where_name);
   }

   if (regexp) {
      bfree(regexp);
   }

   free_rx(&rx);
   garbage_collect_memory();       /* release unused memory */
   return false;
}
示例#23
0
/*
 * Complete the word at or before point,
 * 'what_to_do' says what to do with the completion.
 * \t   means do standard completion.
 * `?' means list the possible completions.
 * `*' means insert all of the possible completions.
 * `!' means to do standard completion, and list all possible completions if
 * there is more than one.
 *
 * Note: '*' support is not implemented
 *       '!' could never be invoked
 */
int
fn_complete(EditLine *el,
	char *(*complet_func)(const char *, int),
	char **(*attempted_completion_function)(const char *, int, int),
	const wchar_t *word_break, const wchar_t *special_prefixes,
	const char *(*app_func)(const char *), size_t query_items,
	int *completion_type, int *over, int *point, int *end)
{
	const LineInfoW *li;
	wchar_t *temp;
	char **matches;
	size_t len;
	int what_to_do = '\t';
	int retval = CC_NORM;

	if (el->el_state.lastcmd == el->el_state.thiscmd)
		what_to_do = '?';

	/* readline's rl_complete() has to be told what we did... */
	if (completion_type != NULL)
		*completion_type = what_to_do;

	if (!complet_func)
		complet_func = fn_filename_completion_function;
	if (!app_func)
		app_func = append_char_function;

	li = el_wline(el);
	temp = find_word_to_complete(li->cursor,
	    li->buffer, word_break, special_prefixes, &len);
	if (temp == NULL)
		goto out;

	/* these can be used by function called in completion_matches() */
	/* or (*attempted_completion_function)() */
	if (point != NULL)
		*point = (int)(li->cursor - li->buffer);
	if (end != NULL)
		*end = (int)(li->lastchar - li->buffer);

	if (attempted_completion_function) {
		int cur_off = (int)(li->cursor - li->buffer);
		matches = (*attempted_completion_function)(
		    ct_encode_string(temp, &el->el_scratch),
		    cur_off - (int)len, cur_off);
	} else
		matches = NULL;
	if (!attempted_completion_function ||
	    (over != NULL && !*over && !matches))
		matches = completion_matches(
		    ct_encode_string(temp, &el->el_scratch), complet_func);

	if (over != NULL)
		*over = 0;

	if (matches) {
		int i;
		size_t matches_num, maxlen, match_len, match_display=1;
		int single_match = matches[2] == NULL &&
			(matches[1] == NULL || strcmp(matches[0], matches[1]) == 0);

		retval = CC_REFRESH;

		if (matches[0][0] != '\0') {
			el_deletestr(el, (int) len);
			if (single_match) {
				/*
				 * We found exact match. Add a space after
				 * it, unless we do filename completion and the
				 * object is a directory. Also do necessary escape quoting
				 */
				char *escaped_completion = escape_filename(el, matches[0]);
				if (escaped_completion == NULL)
					goto out;
				el_winsertstr(el,
					ct_decode_string(escaped_completion, &el->el_scratch));
				el_winsertstr(el,
						ct_decode_string((*app_func)(escaped_completion),
							&el->el_scratch));
				free(escaped_completion);
			} else {
				/*
				 * Only replace the completed string with common part of
				 * possible matches if there is possible completion.
				 */
				el_winsertstr(el,
					ct_decode_string(matches[0], &el->el_scratch));
			}
		}


		if (!single_match && (what_to_do == '!' || what_to_do == '?')) {
			/*
			 * More than one match and requested to list possible
			 * matches.
			 */

			for(i = 1, maxlen = 0; matches[i]; i++) {
				match_len = strlen(matches[i]);
				if (match_len > maxlen)
					maxlen = match_len;
			}
			/* matches[1] through matches[i-1] are available */
			matches_num = (size_t)(i - 1);

			/* newline to get on next line from command line */
			(void)fprintf(el->el_outfile, "\n");

			/*
			 * If there are too many items, ask user for display
			 * confirmation.
			 */
			if (matches_num > query_items) {
				(void)fprintf(el->el_outfile,
				    "Display all %zu possibilities? (y or n) ",
				    matches_num);
				(void)fflush(el->el_outfile);
				if (getc(stdin) != 'y')
					match_display = 0;
				(void)fprintf(el->el_outfile, "\n");
			}

			if (match_display) {
				/*
				 * Interface of this function requires the
				 * strings be matches[1..num-1] for compat.
				 * We have matches_num strings not counting
				 * the prefix in matches[0], so we need to
				 * add 1 to matches_num for the call.
				 */
				fn_display_match_list(el, matches,
				    matches_num+1, maxlen, app_func);
			}
			retval = CC_REDISPLAY;
		} else if (matches[0][0]) {
			/*
			 * There was some common match, but the name was
			 * not complete enough. Next tab will print possible
			 * completions.
			 */
			el_beep(el);
		} else {
			/* lcd is not a valid object - further specification */
			/* is needed */
			el_beep(el);
			retval = CC_NORM;
		}

		/* free elements of array and the array itself */
		for (i = 0; matches[i]; i++)
			el_free(matches[i]);
		el_free(matches);
		matches = NULL;
	}

out:
	el_free(temp);
	return retval;
}