Ejemplo n.º 1
0
const char *
apply_mods(const char path[], const char parent[], const char mod[],
		int for_shell)
{
	static char buf[PATH_MAX];
	int napplied = 0;

	copy_str(buf, sizeof(buf), path);
	while(*mod != '\0')
	{
		int mod_len;
		const char *const p = apply_mod(buf, parent, mod, &mod_len, for_shell);
		if(p == NULL)
		{
			break;
		}
		copy_str(buf, sizeof(buf), p);
		mod += mod_len;
		napplied++;
	}

#ifdef _WIN32
	/* This is needed to run something like explorer.exe, which isn't smart enough
	 * to understand forward slashes. */
	if(for_shell && curr_stats.shell_type != ST_CMD && napplied == 0)
	{
		to_back_slash(buf);
	}
#endif

	return buf;
}
Ejemplo n.º 2
0
/* 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
}
Ejemplo n.º 3
0
/* Applies one filename modifiers per call. */
static const char *
apply_mod(const char *path, const char *parent, const char *mod, int *mod_len,
		int for_shell)
{
	char path_buf[PATH_MAX];
	static char buf[PATH_MAX];

	snprintf(path_buf, sizeof(path_buf), "%s", path);
#ifdef _WIN32
	to_forward_slash(path_buf);
#endif

	*mod_len = 2;
	if(starts_with_lit(mod, ":p"))
		*mod_len += apply_p_mod(path_buf, parent, buf, sizeof(buf));
	else if(starts_with_lit(mod, ":~"))
		*mod_len += apply_tilde_mod(path_buf, buf, sizeof(buf));
	else if(starts_with_lit(mod, ":."))
		*mod_len += apply_dot_mod(path_buf, buf, sizeof(buf));
	else if(starts_with_lit(mod, ":h"))
		*mod_len += apply_h_mod(path_buf, buf, sizeof(buf));
#ifdef _WIN32
	else if(starts_with_lit(mod, ":u"))
		*mod_len += apply_u_mod(path_buf, buf, sizeof(buf));
#endif
	else if(starts_with_lit(mod, ":t"))
		*mod_len += apply_t_mod(path_buf, buf, sizeof(buf));
	else if(starts_with_lit(mod, ":r"))
		*mod_len += apply_r_mod(path_buf, buf, sizeof(buf));
	else if(starts_with_lit(mod, ":e"))
		*mod_len += apply_e_mod(path_buf, buf, sizeof(buf));
	else if(starts_with_lit(mod, ":s") || starts_with_lit(mod, ":gs"))
		*mod_len += apply_s_gs_mod(path_buf, mod, buf, sizeof(buf));
	else
		return NULL;

#ifdef _WIN32
	/* This is needed to run something like explorer.exe, which isn't smart enough
	 * to understand forward slashes. */
	if(for_shell && curr_stats.shell_type != ST_CMD)
	{
		if(!starts_with_lit(mod, ":s") && !starts_with_lit(mod, ":gs"))
		{
			to_back_slash(buf);
		}
	}
#endif

	return buf;
}
Ejemplo n.º 4
0
static char *
expand_directory_path(FileView *view, char *expanded, int quotes,
		const char *mod, int for_shell)
{
	const char *const modified = apply_mods(flist_get_dir(view), "/", mod, for_shell);
	char *const result = append_path_to_expanded(expanded, quotes, modified);

#ifdef _WIN32
	if(for_shell && curr_stats.shell_type == ST_CMD)
	{
		to_back_slash(result);
	}
#endif

	return result;
}
Ejemplo n.º 5
0
/* Executes file, specified by the full_path.  Changes type of slashes on
 * Windows. */
static void
execute_file(const char full_path[], int elevate)
{
#ifndef _WIN32
	char *const escaped = shell_like_escape(full_path, 0);
	shellout(escaped, PAUSE_ALWAYS, 1);
	free(escaped);
#else
	char *const dquoted_full_path = strdup(enclose_in_dquotes(full_path));

	to_back_slash(dquoted_full_path);
	run_win_executable(dquoted_full_path, elevate);

	free(dquoted_full_path);
#endif
}
Ejemplo n.º 6
0
/* Adds a path to PATH environment variable. */
static void
add_to_path(const char *path)
{
	const char *old_path;
	char *new_path;

	old_path = env_get("PATH");
	new_path = malloc(strlen(path) + 1 + strlen(old_path) + 1);

#ifndef _WIN32
	sprintf(new_path, "%s:%s", path, old_path);
#else
	sprintf(new_path, "%s;%s", path, old_path);
	to_back_slash(new_path);
#endif
	env_set("PATH", new_path);

	free(new_path);
}
Ejemplo n.º 7
0
TSTATIC char *
append_selected_files(FileView *view, char expanded[], int under_cursor,
		int quotes, const char mod[], int for_shell)
{
	const PathType type = (view == other_view)
	                    ? PT_FULL
	                    : (flist_custom_active(view) ? PT_REL : PT_NAME);
#ifdef _WIN32
	size_t old_len = strlen(expanded);
#endif

	if(view->selected_files && !under_cursor)
	{
		int n = 0;
		dir_entry_t *entry = NULL;
		while(iter_selected_entries(view, &entry))
		{
			expanded = append_entry(view, expanded, type, entry, quotes, mod,
					for_shell);

			if(++n != view->selected_files)
			{
				expanded = append_to_expanded(expanded, " ");
			}
		}
	}
	else
	{
		expanded = append_entry(view, expanded, type, get_current_entry(view),
				quotes, mod, for_shell);
	}

#ifdef _WIN32
	if(for_shell && curr_stats.shell_type == ST_CMD)
	{
		to_back_slash(expanded + old_len);
	}
#endif

	return expanded;
}
Ejemplo n.º 8
0
/* Expands content of a register specified by the key argument considering
 * filename-modifiers.  If key is unknown, falls back to the default register.
 * Sets *well_formed to non-zero for valid value of the key.  Reallocates the
 * expanded string and returns result (possibly NULL). */
static char *
expand_register(const char curr_dir[], char expanded[], int quotes,
		const char mod[], int key, int *well_formed, int for_shell)
{
	int i;
	reg_t *reg;

	*well_formed = 1;
	reg = regs_find(tolower(key));
	if(reg == NULL)
	{
		*well_formed = 0;
		reg = regs_find(DEFAULT_REG_NAME);
		assert(reg != NULL);
		mod--;
	}

	for(i = 0; i < reg->nfiles; ++i)
	{
		const char *const modified = apply_mods(reg->files[i], curr_dir, mod,
				for_shell);
		expanded = append_path_to_expanded(expanded, quotes, modified);
		if(i != reg->nfiles - 1)
		{
			expanded = append_to_expanded(expanded, " ");
		}
	}

#ifdef _WIN32
	if(for_shell && curr_stats.shell_type == ST_CMD)
	{
		to_back_slash(expanded);
	}
#endif

	return expanded;
}
Ejemplo n.º 9
0
Archivo: ops.c Proyecto: cfillion/vifm
static int
op_removesl(ops_t *ops, void *data, const char *src, const char *dst)
{
	if(cfg.delete_prg[0] != '\0')
	{
#ifndef _WIN32
		char *escaped;
		char cmd[2*PATH_MAX + 1];
		const int cancellable = (data == NULL);

		escaped = shell_like_escape(src, 0);
		if(escaped == NULL)
		{
			return -1;
		}

		snprintf(cmd, sizeof(cmd), "%s %s", cfg.delete_prg, escaped);
		free(escaped);

		LOG_INFO_MSG("Running trash command: \"%s\"", cmd);
		return background_and_wait_for_errors(cmd, cancellable);
#else
		char cmd[PATH_MAX*2 + 1];
		snprintf(cmd, sizeof(cmd), "%s \"%s\"", cfg.delete_prg, src);
		to_back_slash(cmd);

		return os_system(cmd);
#endif
	}

	if(!cfg.use_system_calls)
	{
#ifndef _WIN32
		char *escaped;
		char cmd[16 + PATH_MAX];
		int result;
		const int cancellable = data == NULL;

		escaped = shell_like_escape(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, cancellable);

		free(escaped);
		return result;
#else
		if(is_dir(src))
		{
			char path[PATH_MAX];
			int err;

			copy_str(path, sizeof(path), src);
			to_back_slash(path);

			wchar_t *const utf16_path = utf8_to_utf16(path);

			SHFILEOPSTRUCTW fo = {
				.hwnd = NULL,
				.wFunc = FO_DELETE,
				.pFrom = utf16_path,
				.pTo = NULL,
				.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI,
			};
			err = SHFileOperationW(&fo);

			log_msg("Error: %d", err);
			free(utf16_path);

			return err;
		}
		else
		{
			int ok;
			wchar_t *const utf16_path = utf8_to_utf16(src);
			DWORD attributes = GetFileAttributesW(utf16_path);
			if(attributes & FILE_ATTRIBUTE_READONLY)
			{
				SetFileAttributesW(utf16_path, attributes & ~FILE_ATTRIBUTE_READONLY);
			}

			ok = DeleteFileW(utf16_path);
			if(!ok)
			{
				LOG_WERROR(GetLastError());
			}

			free(utf16_path);
			return !ok;
		}
#endif
	}
Ejemplo n.º 10
0
static int
op_removesl(ops_t *ops, void *data, const char *src, const char *dst)
{
	const char *const delete_prg = (ops == NULL)
	                             ? cfg.delete_prg
	                             : ops->delete_prg;
	if(delete_prg[0] != '\0')
	{
#ifndef _WIN32
		char *escaped;
		char cmd[2*PATH_MAX + 1];
		const int cancellable = (data == NULL);

		escaped = shell_like_escape(src, 0);
		if(escaped == NULL)
		{
			return -1;
		}

		snprintf(cmd, sizeof(cmd), "%s %s", delete_prg, escaped);
		free(escaped);

		LOG_INFO_MSG("Running trash command: \"%s\"", cmd);
		return run_operation_command(ops, cmd, cancellable);
#else
		char cmd[PATH_MAX*2 + 1];
		snprintf(cmd, sizeof(cmd), "%s \"%s\"", delete_prg, src);
		to_back_slash(cmd);

		return os_system(cmd);
#endif
	}

	if(!ops_uses_syscalls(ops))
	{
#ifndef _WIN32
		char *escaped;
		char cmd[16 + PATH_MAX];
		int result;
		const int cancellable = data == NULL;

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

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

		free(escaped);
		return result;
#else
		if(is_dir(src))
		{
			char path[PATH_MAX];
			int err;

			copy_str(path, sizeof(path), src);
			to_back_slash(path);

			wchar_t *utf16_path = utf8_to_utf16(path);

			/* SHFileOperationW requires pFrom to be double-nul terminated. */
			const size_t len = wcslen(utf16_path);
			utf16_path = reallocarray(utf16_path, len + 1U + 1U, sizeof(*utf16_path));
			utf16_path[len + 1U] = L'\0';

			SHFILEOPSTRUCTW fo = {
				.hwnd = NULL,
				.wFunc = FO_DELETE,
				.pFrom = utf16_path,
				.pTo = NULL,
				.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI,
			};
			err = SHFileOperationW(&fo);

			log_msg("Error: %d", err);
			free(utf16_path);

			return err;
		}
		else
		{
			int ok;
			wchar_t *const utf16_path = utf8_to_utf16(src);
			DWORD attributes = GetFileAttributesW(utf16_path);
			if(attributes & FILE_ATTRIBUTE_READONLY)
			{
				SetFileAttributesW(utf16_path, attributes & ~FILE_ATTRIBUTE_READONLY);
			}

			ok = DeleteFileW(utf16_path);
			if(!ok)
			{
				LOG_WERROR(GetLastError());
			}

			free(utf16_path);
			return !ok;
		}
#endif
	}