Пример #1
0
void
setup_signals(void)
{
  LOG_FUNC_ENTER;

#ifndef _WIN32
	struct sigaction handle_signal_action;

	handle_signal_action.sa_handler = handle_signal;
	sigemptyset(&handle_signal_action.sa_mask);
	handle_signal_action.sa_flags = SA_RESTART;

	sigaction(SIGCHLD, &handle_signal_action, NULL);
	sigaction(SIGHUP, &handle_signal_action, NULL);
	sigaction(SIGQUIT, &handle_signal_action, NULL);
	sigaction(SIGCONT, &handle_signal_action, NULL);
	sigaction(SIGTERM, &handle_signal_action, NULL);
	sigaction(SIGWINCH, &handle_signal_action, NULL);
	signal(SIGUSR1, SIG_IGN);
	signal(SIGUSR2, SIG_IGN);
	signal(SIGALRM, SIG_IGN);
	signal(SIGTSTP, SIG_IGN);
#else
	if(!SetConsoleCtrlHandler(ctrl_handler, TRUE))
	{
		LOG_WERROR(GetLastError());
	}
#endif

	signal(SIGINT, SIG_IGN);
}
Пример #2
0
/* Returns non-zero on error, otherwise zero is returned. */
static int
run_win_executable_as_evaluated(const char full_path[])
{
	wchar_t *utf16_path;
	SHELLEXECUTEINFOW sei;

	utf16_path = utf8_to_utf16(full_path);

	memset(&sei, 0, sizeof(sei));
	sei.cbSize = sizeof(sei);
	sei.fMask = SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS;
	sei.lpVerb = L"runas";
	sei.lpFile = utf16_path;
	sei.lpParameters = NULL;
	sei.nShow = SW_SHOWNORMAL;

	if(!ShellExecuteExW(&sei))
	{
		const DWORD last_error = GetLastError();
		free(utf16_path);
		LOG_WERROR(last_error);
		return last_error != ERROR_CANCELLED;
	}

	free(utf16_path);
	CloseHandle(sei.hProcess);
	return 0;
}
Пример #3
0
/* performs properties change with support of undoing */
static void
file_attrib(char *path, DWORD add, DWORD sub, int recurse_dirs)
{
	/* FIXME: set attributes recursively. */

	DWORD attrs = GetFileAttributes(path);
	if(attrs == INVALID_FILE_ATTRIBUTES)
	{
		LOG_WERROR(GetLastError());
		return;
	}
	if(add != 0)
	{
		const size_t wadd = add;
		if(perform_operation(OP_ADDATTR, NULL, (void *)wadd, path, NULL) == 0)
		{
			add_operation(OP_ADDATTR, (void *)wadd, (void *)(~attrs & wadd), path,
					"");
		}
	}
	if(sub != 0)
	{
		const size_t wsub = sub;
		if(perform_operation(OP_SUBATTR, NULL, (void *)wsub, path, NULL) == 0)
		{
			add_operation(OP_SUBATTR, (void *)wsub, (void *)(~attrs & wsub), path,
					"");
		}
	}
}
Пример #4
0
Файл: fs.c Проект: cfillion/vifm
int
is_symlink(const char path[])
{
#ifndef _WIN32
	struct stat st;
	return os_lstat(path, &st) == 0 && S_ISLNK(st.st_mode);
#else
	char filename[PATH_MAX];
	DWORD attr;
	wchar_t *utf16_filename;
	HANDLE hfind;
	WIN32_FIND_DATAW ffd;

	attr = win_get_file_attrs(path);
	if(attr == INVALID_FILE_ATTRIBUTES)
	{
		LOG_WERROR(GetLastError());
		return 0;
	}

	if(!(attr & FILE_ATTRIBUTE_REPARSE_POINT))
	{
		return 0;
	}

	copy_str(filename, sizeof(filename), path);
	chosp(filename);

	utf16_filename = utf8_to_utf16(path);
	hfind = FindFirstFileW(utf16_filename, &ffd);
	free(utf16_filename);

	if(hfind == INVALID_HANDLE_VALUE)
	{
		LOG_WERROR(GetLastError());
		return 0;
	}

	if(!FindClose(hfind))
	{
		LOG_WERROR(GetLastError());
	}

	return ffd.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
#endif
}
Пример #5
0
static int
op_subattr(void *data, const char *src, const char *dst)
{
	const DWORD sub_mask = (size_t)data;
	const DWORD attrs = GetFileAttributesA(src);
	if(attrs == INVALID_FILE_ATTRIBUTES)
	{
		LOG_WERROR(GetLastError());
		return -1;
	}
	if(!SetFileAttributesA(src, attrs & ~sub_mask))
	{
		LOG_WERROR(GetLastError());
		return -1;
	}
	return 0;
}
Пример #6
0
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
/* Runs a Windows executable handling errors and rights elevation. */
static void
run_win_executable(char full_path[], int elevate)
{
	int running_error = 0;
	int running_error_code = NO_ERROR;
	if(elevate && is_vista_and_above())
	{
		running_error = run_win_executable_as_evaluated(full_path);
	}
	else
	{
		int returned_exit_code;
		const int error = win_exec_cmd(full_path, &returned_exit_code);
		if(error != 0 && !returned_exit_code)
		{
			if(error == ERROR_ELEVATION_REQUIRED && is_vista_and_above())
			{
				const int user_response = prompt_msg("Program running error",
						"Executable requires rights elevation. Run with elevated rights?");
				if(user_response != 0)
				{
					running_error = run_win_executable_as_evaluated(full_path);
				}
			}
			else
			{
				running_error = 1;
				running_error_code = error;
			}
		}
		update_screen(UT_FULL);
	}
	if(running_error)
	{
		char err_msg[512];
		err_msg[0] = '\0';
		if(running_error_code != NO_ERROR && FormatMessageA(
				FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
				running_error_code, 0, err_msg, sizeof(err_msg), NULL) == 0)
		{
			LOG_WERROR(GetLastError());
		}

		show_error_msgf("Program running error", "Can't run an executable%s%s",
				(err_msg[0] == '\0') ? "." : ": ", err_msg);
	}
}
Пример #8
0
void
setup_signals(void)
{
  LOG_FUNC_ENTER;

#ifndef _WIN32
	struct sigaction handle_signal_action;

	handle_signal_action.sa_handler = &handle_signal;
	sigemptyset(&handle_signal_action.sa_mask);
	handle_signal_action.sa_flags = SA_RESTART;

	/* Assumption: we work under shell with job control support.  If it's not the
	 * case, this code enables handling of terminal related signals the shell
	 * wanted us to have disabled (e.g. the app will catch Ctrl-C send to another
	 * process). */

	sigaction(SIGCHLD, &handle_signal_action, NULL);
	sigaction(SIGHUP, &handle_signal_action, NULL);
	sigaction(SIGINT, &handle_signal_action, NULL);
	sigaction(SIGQUIT, &handle_signal_action, NULL);
	sigaction(SIGCONT, &handle_signal_action, NULL);
	sigaction(SIGTERM, &handle_signal_action, NULL);
	sigaction(SIGWINCH, &handle_signal_action, NULL);
	signal(SIGUSR1, SIG_IGN);
	signal(SIGUSR2, SIG_IGN);
	signal(SIGALRM, SIG_IGN);
	signal(SIGTSTP, SIG_IGN);
#else
	if(!SetConsoleCtrlHandler(ctrl_handler, TRUE))
	{
		LOG_WERROR(GetLastError());
	}
	signal(SIGINT, SIG_IGN);
#endif
}
Пример #9
0
Файл: fs.c Проект: cfillion/vifm
int
get_link_target(const char *link, char *buf, size_t buf_len)
{
	LOG_FUNC_ENTER;

#ifndef _WIN32
	char *filename;
	ssize_t len;

	if(buf_len == 0)
	{
		return -1;
	}

	filename = strdup(link);
	chosp(filename);

	len = readlink(filename, buf, buf_len - 1);

	free(filename);

	if(len == -1)
	{
		return -1;
	}

	buf[len] = '\0';
	return 0;
#else
	char filename[PATH_MAX];
	DWORD attr;
	wchar_t *utf16_filename;
	HANDLE hfile;
	char rdb[2048];
	char *t;
	REPARSE_DATA_BUFFER *sbuf;
	WCHAR *path;

	if(!is_symlink(link))
	{
		return -1;
	}

	copy_str(filename, sizeof(filename), link);
	chosp(filename);

	utf16_filename = utf8_to_utf16(filename);
	hfile = CreateFileW(utf16_filename, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
			NULL, OPEN_EXISTING,
			FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
	free(utf16_filename);

	if(hfile == INVALID_HANDLE_VALUE)
	{
		LOG_WERROR(GetLastError());
		return -1;
	}

	if(!DeviceIoControl(hfile, FSCTL_GET_REPARSE_POINT, NULL, 0, rdb,
			sizeof(rdb), &attr, NULL))
	{
		LOG_WERROR(GetLastError());
		CloseHandle(hfile);
		return -1;
	}
	CloseHandle(hfile);

	sbuf = (REPARSE_DATA_BUFFER *)rdb;
	path = sbuf->SymbolicLinkReparseBuffer.PathBuffer;
	path[sbuf->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR) +
			sbuf->SymbolicLinkReparseBuffer.PrintNameLength/sizeof(WCHAR)] = L'\0';
	t = to_multibyte(path +
			sbuf->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR));
	if(strncmp(t, "\\??\\", 4) == 0)
		strncpy(buf, t + 4, buf_len);
	else
		strncpy(buf, t, buf_len);
	buf[buf_len - 1] = '\0';
	free(t);
	to_forward_slash(buf);
	return 0;
#endif
}
Пример #10
0
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
	}
Пример #11
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
	}