コード例 #1
0
ファイル: config.c プロジェクト: phantasea/vifm
int
cfg_set_fuse_home(const char new_value[])
{
#ifdef _WIN32
	char with_forward_slashes[strlen(new_value) + 1];
	strcpy(with_forward_slashes, new_value);
	system_to_internal_slashes(with_forward_slashes);
	new_value = with_forward_slashes;
#endif

	char canonicalized[PATH_MAX + 1];
	canonicalize_path(new_value, canonicalized, sizeof(canonicalized));

	if(!is_path_absolute(new_value))
	{
		if(cfg.fuse_home == NULL)
		{
			/* Do not leave cfg.fuse_home uninitialized. */
			cfg.fuse_home = strdup("");
		}

		show_error_msgf("Error Setting FUSE Home Directory",
				"The path is not absolute: %s", canonicalized);
		return 1;
	}

	return replace_string(&cfg.fuse_home, canonicalized);
}
コード例 #2
0
/* Navigates the view to a given dir/file combination specified by the path. */
static void
navigate_to_selected_file(FileView *view, const char path[])
{
	char name[NAME_MAX];
	char *dir = strdup(path);
	char *const last_slash = find_slashr(dir);

	if(last_slash == NULL)
	{
		copy_str(name, sizeof(name), dir);
	}
	else
	{
		*last_slash = '\0';
		copy_str(name, sizeof(name), last_slash + 1);
	}

	if(change_directory(view, dir) >= 0)
	{
		ui_sb_quick_msgf("%s", "Finding the correct directory...");

		load_dir_list(view, 0);

		(void)ensure_file_is_selected(view, name);
	}
	else
	{
		show_error_msgf("Invalid path", "Cannot change dir to \"%s\"", dir);
	}

	free(dir);
}
コード例 #3
0
int
goto_selected_file(menu_data_t *m, FileView *view, const char spec[],
		int try_open)
{
	char *path_buf;
	int line_num;

	path_buf = parse_file_spec(spec, &line_num, get_relative_path_base(m, view));
	if(path_buf == NULL)
	{
		show_error_msg("Memory Error", "Unable to allocate enough memory");
		return 1;
	}

	if(!path_exists(path_buf, NODEREF))
	{
		show_error_msgf("Missing file", "File \"%s\" doesn't exist", path_buf);
		free(path_buf);
		return 1;
	}

	if(try_open)
	{
		open_selected_file(path_buf, line_num);
	}
	else
	{
		navigate_to_selected_file(view, path_buf);
	}

	free(path_buf);
	return 0;
}
コード例 #4
0
ファイル: menus.c プロジェクト: lyuts/vifm
void
goto_selected_file(FileView *view, const char spec[], int try_open)
{
	char *path_buf;
	int line_num;

	path_buf = parse_spec(spec, &line_num);
	if(path_buf == NULL)
	{
		show_error_msg("Memory Error", "Unable to allocate enough memory");
		return;
	}

	if(access(path_buf, F_OK) == 0)
	{
		if(try_open)
		{
			open_selected_file(path_buf, line_num);
		}
		else
		{
			navigate_to_selected_file(view, path_buf);
		}
	}
	else
	{
		show_error_msgf("Missing file", "File \"%s\" doesn't exist", path_buf);
	}

	free(path_buf);
}
コード例 #5
0
ファイル: args.c プロジェクト: cosminadrianpopescu/vifm
/* Handles path command-line argument or fails with appropriate message.
 * Returns zero on successful handling, otherwise non-zero is returned. */
static void
handle_arg_or_fail(const char arg[], int select, const char dir[], args_t *args)
{
	if(handle_path_arg(arg, select, dir, args) == 0)
	{
		if(strcmp(args->lwin_path, "-") == 0 && strcmp(args->rwin_path, "-") == 0)
		{
			show_help_msg("\"-\" can be specified at most once");
			quit_on_arg_parsing(EXIT_FAILURE);
		}

		return;
	}

	if(curr_stats.load_stage == 0)
	{
		show_help_msg(arg);
		quit_on_arg_parsing(EXIT_FAILURE);
	}
#ifdef ENABLE_REMOTE_CMDS
	else
	{
		show_error_msgf("--remote error", "Invalid argument: %s", arg);
	}
#endif
}
コード例 #6
0
ファイル: color_scheme.c プロジェクト: KryDos/vifm
int
load_primary_color_scheme(const char name[])
{
	col_scheme_t prev_cs;
	char full[PATH_MAX];

	if(!color_scheme_exists(name))
	{
		show_error_msgf("Color Scheme", "Invalid color scheme name: \"%s\"", name);
		return 0;
	}

	prev_cs = cfg.cs;
	curr_stats.cs_base = DCOLOR_BASE;
	curr_stats.cs = &cfg.cs;
	cfg.cs.state = CSS_LOADING;

	snprintf(full, sizeof(full), "%s/colors/%s", cfg.config_dir, name);
	if(source_file(full) != 0)
	{
		restore_primary_color_scheme(&prev_cs);
		show_error_msgf("Color Scheme Sourcing",
				"Errors loading colors cheme: \"%s\"", name);
		cfg.cs.state = CSS_NORMAL;
		return 0;
	}
	copy_str(cfg.cs.name, sizeof(cfg.cs.name), name);
	check_color_scheme(&cfg.cs);

	update_attributes();

	if(curr_stats.load_stage >= 2 && cfg.cs.state == CSS_DEFAULTED)
	{
		restore_primary_color_scheme(&prev_cs);
		show_error_msg("Color Scheme Error", "Not supported by the terminal");
		return 0;
	}

	cfg.cs.state = CSS_NORMAL;
	return 0;
}
コード例 #7
0
int
load_primary_color_scheme(const char name[])
{
	col_scheme_t prev_cs = {};

	if(!color_scheme_exists(name))
	{
		show_error_msgf("Color Scheme", "Invalid color scheme name: \"%s\"", name);
		return 0;
	}

	assign_color_scheme(&prev_cs, &cfg.cs);
	curr_stats.cs = &cfg.cs;
	cfg.cs.state = CSS_LOADING;

	if(source_cs(name) != 0)
	{
		restore_primary_color_scheme(&prev_cs);
		show_error_msgf("Color Scheme Sourcing",
				"An error occurred on loading color scheme: \"%s\"", name);
		cfg.cs.state = CSS_NORMAL;
		return 0;
	}
	copy_str(cfg.cs.name, sizeof(cfg.cs.name), name);
	check_color_scheme(&cfg.cs);

	update_attributes();

	if(cfg.cs.state == CSS_DEFAULTED)
	{
		restore_primary_color_scheme(&prev_cs);
		show_error_msgf("Color Scheme Error",
				"\"%s\" color scheme is not supported by the terminal, restored \"%s\"",
				name, prev_cs.name);
		return 0;
	}

	free_color_scheme_highlights(&prev_cs);
	cfg.cs.state = CSS_NORMAL;
	return 0;
}
コード例 #8
0
/* Opens file specified by its path on the given line number. */
static void
open_selected_file(const char path[], int line_num)
{
	if(os_access(path, R_OK) == 0)
	{
		(void)vim_view_file(path, line_num, -1, 1);
	}
	else
	{
		show_error_msgf("Can't read file", "File \"%s\" is not readable", path);
	}
}
コード例 #9
0
ファイル: menus.c プロジェクト: lyuts/vifm
int
capture_output_to_menu(FileView *view, const char cmd[], menu_info *m)
{
	FILE *file, *err;
	char *line = NULL;
	int x;
	pid_t pid;

	LOG_INFO_MSG("Capturing output of the command to a menu: %s", cmd);

	pid = background_and_capture((char *)cmd, &file, &err);
	if(pid == (pid_t)-1)
	{
		show_error_msgf("Trouble running command", "Unable to run: %s", cmd);
		return 0;
	}

	show_progress("", 0);

	ui_cancellation_reset();
	ui_cancellation_enable();

	wait_for_data_from(pid, file, 0);

	x = 0;
	while((line = read_line(file, line)) != NULL)
	{
		char *expanded_line;
		show_progress("Loading menu", 1000);
		m->items = realloc(m->items, sizeof(char *)*(x + 1));
		expanded_line = expand_tabulation_a(line, cfg.tab_stop);
		if(expanded_line != NULL)
		{
			m->items[x++] = expanded_line;
		}

		wait_for_data_from(pid, file, 0);
	}
	m->len = x;

	ui_cancellation_disable();

	fclose(file);
	print_errors(err);

	if(ui_cancellation_requested())
	{
		append_to_string(&m->title, "(cancelled) ");
		append_to_string(&m->empty_msg, " (cancelled)");
	}

	return display_menu(m, view);
}
コード例 #10
0
ファイル: trash.c プロジェクト: cosminadrianpopescu/vifm
/* Ensures existence of trash directory.  Displays error message dialog, if
 * directory creation failed.  Returns zero on success, otherwise non-zero value
 * is returned. */
static int
create_trash_dir(const char trash_dir[])
{
	LOG_FUNC_ENTER;

	if(try_create_trash_dir(trash_dir) != 0)
	{
		show_error_msgf("Error Setting Trash Directory",
				"Could not set trash directory to %s: %s", trash_dir, strerror(errno));
		return 1;
	}

	return 0;
}
コード例 #11
0
ファイル: config.c プロジェクト: ackeack/workenv
int
set_trash_dir(const char new_value[])
{
	if(!is_path_absolute(new_value))
	{
		show_error_msgf("Error Setting Trash Directory",
				"The path is not absolute: %s", new_value);
		return 1;
	}
	if(create_trash_dir(new_value) != 0)
	{
		return 1;
	}
	snprintf(cfg.trash_dir, sizeof(cfg.trash_dir), "%s", new_value);
	return 0;
}
コード例 #12
0
ファイル: running.c プロジェクト: cfillion/vifm
/* 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);
	}
}
コード例 #13
0
ファイル: trash.c プロジェクト: cosminadrianpopescu/vifm
/* Validates trash directory specification.  Returns non-zero if it's OK,
 * otherwise zero is returned and an error message is displayed. */
static int
validate_spec(const char spec[])
{
	if(is_path_absolute(spec))
	{
		if(create_trash_dir(spec) != 0)
		{
			return 0;
		}
	}
	else if(!is_rooted_trash_dir(spec))
	{
		show_error_msgf("Error Setting Trash Directory",
				"The path specification is of incorrect format: %s", spec);
		return 0;
	}
	return 1;
}
コード例 #14
0
int
capture_output_to_menu(FileView *view, const char cmd[], int user_sh,
		menu_state_t *m)
{
	if(process_cmd_output("Loading menu", cmd, user_sh, 0, &output_handler,
				m->d) != 0)
	{
		show_error_msgf("Trouble running command", "Unable to run: %s", cmd);
		return 0;
	}

	if(ui_cancellation_requested())
	{
		append_to_string(&m->d->title, "(cancelled)");
		append_to_string(&m->d->empty_msg, " (cancelled)");
	}

	return display_menu(m, view);
}
コード例 #15
0
ファイル: config.c プロジェクト: ackeack/workenv
int
create_trash_dir(const char trash_dir[])
{
	LOG_FUNC_ENTER;

	if(is_dir_writable(trash_dir))
	{
		return 0;
	}

	if(make_dir(trash_dir, 0777) != 0)
	{
		show_error_msgf("Error Setting Trash Directory",
				"Could not set trash directory to %s: %s", trash_dir, strerror(errno));
		return 1;
	}

	return 0;
}
コード例 #16
0
ファイル: menus.c プロジェクト: lyuts/vifm
/* Navigates the view to a given dir/file combination specified by the path. */
static void
navigate_to_selected_file(FileView *view, const char path[])
{
	/* Check whether target path is directory while we don't change current
	 * working directory by invoking change_directory() function below. */
	const int dst_is_dir = is_dir(path);

	char name[NAME_MAX];
	char *dir = strdup(path);
	char *const last_slash = find_slashr(dir);

	if(last_slash == NULL)
	{
		copy_str(name, sizeof(name), dir);
	}
	else
	{
		*last_slash = '\0';
		copy_str(name, sizeof(name), last_slash + 1);
	}

	if(change_directory(view, dir) >= 0)
	{
		status_bar_message("Finding the correct directory...");
		wrefresh(status_bar);

		load_dir_list(view, 0);

		if(dst_is_dir)
		{
			strcat(name, "/");
		}
		(void)ensure_file_is_selected(view, name);
	}
	else
	{
		show_error_msgf("Invalid path", "Cannot change dir to \"%s\"", dir);
	}

	free(dir);
}
コード例 #17
0
ファイル: running.c プロジェクト: cfillion/vifm
/* Executes the cmd ignoring its output. */
static void
output_to_nowhere(const char cmd[])
{
	FILE *file, *err;
	int error;

	setup_shellout_env();
	error = (background_and_capture((char *)cmd, 1, &file, &err) == (pid_t)-1);
	cleanup_shellout_env();
	if(error)
	{
		show_error_msgf("Trouble running command", "Unable to run: %s", cmd);
		return;
	}

	/* FIXME: better way of doing this would be to redirect these streams to
	 *        /dev/null rather than closing them, but not sure about Windows (NUL
	 *        device might work). */
	fclose(file);
	fclose(err);
}
コード例 #18
0
ファイル: config.c プロジェクト: ackeack/workenv
int
set_fuse_home(const char new_value[])
{
	char canonicalized[PATH_MAX];
#ifdef _WIN32
	char with_forward_slashes[strlen(new_value) + 1];
	strcpy(with_forward_slashes, new_value);
	to_forward_slash(with_forward_slashes);
	new_value = with_forward_slashes;
#endif
	canonicalize_path(new_value, canonicalized, sizeof(canonicalized));

	if(!is_path_absolute(new_value))
	{
		show_error_msgf("Error Setting FUSE Home Directory",
				"The path is not absolute: %s", canonicalized);
		return 1;
	}

	return replace_string(&cfg.fuse_home, canonicalized);
}
コード例 #19
0
ファイル: running.c プロジェクト: cfillion/vifm
/* Executes the cmd and displays its output on the status bar. */
static void
output_to_statusbar(const char cmd[])
{
	FILE *file, *err;
	char buf[2048];
	char *lines;
	size_t len;
	int error;

	setup_shellout_env();
	error = (background_and_capture((char *)cmd, 1, &file, &err) == (pid_t)-1);
	cleanup_shellout_env();
	if(error)
	{
		show_error_msgf("Trouble running command", "Unable to run: %s", cmd);
		return;
	}

	lines = NULL;
	len = 0;
	while(fgets(buf, sizeof(buf), file) == buf)
	{
		char *p;

		chomp(buf);
		p = realloc(lines, len + 1 + strlen(buf) + 1);
		if(p != NULL)
		{
			lines = p;
			len += sprintf(lines + len, "%s%s", (len == 0) ? "": "\n", buf);
		}
	}

	fclose(file);
	fclose(err);

	status_bar_message((lines == NULL) ? "" : lines);
	free(lines);
}
コード例 #20
0
ファイル: running.c プロジェクト: cfillion/vifm
void
output_to_custom_flist(FileView *view, const char cmd[], int very)
{
	char *title;
	int error;

	title = format_str("!%s", cmd);
	flist_custom_start(view, title);
	free(title);

	setup_shellout_env();
	error = (process_cmd_output("Loading custom view", cmd, 1, &path_handler,
				view) != 0);
	cleanup_shellout_env();

	if(error)
	{
		show_error_msgf("Trouble running command", "Unable to run: %s", cmd);
		return;
	}

	flist_end_custom(view, very);
}
コード例 #21
0
char *
get_ext_command(const char beginning[], size_t line_pos, CmdInputType type)
{
	char cmd_file[PATH_MAX];
	char *cmd = NULL;

	generate_tmp_file_name("vifm.cmdline", cmd_file, sizeof(cmd_file));

	if(setup_extcmd_file(cmd_file, beginning, type) == 0)
	{
		if(vim_view_file(cmd_file, 1, line_pos, 0) == 0)
		{
			cmd = get_file_first_line(cmd_file);
		}
	}
	else
	{
		show_error_msgf("Error Creating Temporary File",
				"Could not create file %s: %s", cmd_file, strerror(errno));
	}

	unlink(cmd_file);
	return cmd;
}
コード例 #22
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;
}
コード例 #23
0
ファイル: vifm.c プロジェクト: ackeack/workenv
static void
parse_args(int argc, char *argv[], const char *dir, char *lwin_path,
		char *rwin_path, int *lwin_handle, int *rwin_handle)
{
	int x;
	int select = 0;

	(void)my_chdir(dir);

	/* Get Command Line Arguments */
	for(x = 1; x < argc; x++)
	{
		if(!strcmp(argv[x], "--select"))
		{
			select = 1;
		}
		else if(!strcmp(argv[x], "--remote"))
		{
			if(!ipc_server())
			{
				ipc_send(argv + x + 1);
				quit_on_invalid_arg();
			}
		}
		else if(!strcmp(argv[x], "-f"))
		{
			cfg.vim_filter = 1;
		}
		else if(!strcmp(argv[x], "--no-configs"))
		{
		}
		else if(!strcmp(argv[x], "--version") || !strcmp(argv[x], "-v"))
		{
			show_version_msg();
			quit_on_invalid_arg();
		}
		else if(!strcmp(argv[x], "--help") || !strcmp(argv[x], "-h"))
		{
			show_help_msg();
			quit_on_invalid_arg();
		}
		else if(!strcmp(argv[x], "--logging"))
		{
			/* do nothing, it's handeled in main() */
		}
		else if(!strcmp(argv[x], "-c"))
		{
			if(x == argc - 1)
			{
				puts("Argument missing after \"-c\"");
				quit_on_invalid_arg();
			}
			/* do nothing, it's handeled in exec_startup_commands() */
			x++;
		}
		else if(argv[x][0] == '+')
		{
			/* do nothing, it's handeled in exec_startup_commands() */
		}
		else if(path_exists(argv[x]) || is_path_absolute(argv[x]) ||
				is_root_dir(argv[x]))
		{
			if(lwin_path[0] != '\0')
			{
				parse_path(dir, argv[x], rwin_path);
				*rwin_handle = !select;
			}
			else
			{
				parse_path(dir, argv[x], lwin_path);
				*lwin_handle = !select;
			}
			select = 0;
		}
		else if(curr_stats.load_stage == 0)
		{
			show_help_msg();
			quit_on_invalid_arg();
		}
		else
		{
			show_error_msgf("--remote error", "Invalid argument: %s", argv[x]);
		}
	}
}
コード例 #24
0
ファイル: running.c プロジェクト: cfillion/vifm
static void
run_file(FileView *view, int dont_execute)
{
	/* TODO: refactor this function run_file() */

	char *typed_fname;
	const char *multi_prog_cmd;
	int undef;
	int same;
	dir_entry_t *entry;
	int no_multi_run;

	if(!view->dir_entry[view->list_pos].selected)
	{
		clean_selected_files(view);
	}

	typed_fname = get_typed_entry_fpath(get_current_entry(view));
	multi_prog_cmd = ft_get_program(typed_fname);
	free(typed_fname);

	no_multi_run = !is_multi_run_compat(view, multi_prog_cmd);
	undef = 0;
	same = 1;

	entry = NULL;
	while(iter_selected_entries(view, &entry))
	{
		char *typed_fname;
		const char *entry_prog_cmd;

		if(!path_exists_at(entry->origin, entry->name, DEREF))
		{
			show_error_msgf("Broken Link", "Destination of \"%s\" link doesn't exist",
					entry->name);
			return;
		}

		typed_fname = get_typed_entry_fpath(entry);
		entry_prog_cmd = ft_get_program(typed_fname);
		free(typed_fname);

		if(entry_prog_cmd == NULL)
		{
			++undef;
			continue;
		}

		no_multi_run += !is_multi_run_compat(view, entry_prog_cmd);
		if(multi_prog_cmd == NULL)
		{
			multi_prog_cmd = entry_prog_cmd;
		}
		else if(strcmp(entry_prog_cmd, multi_prog_cmd) != 0)
		{
			same = 0;
		}
	}

	if(!same && undef == 0 && no_multi_run)
	{
		show_error_msg("Run error", "Handlers of selected files are incompatible.");
		return;
	}
	if(undef > 0)
	{
		multi_prog_cmd = NULL;
	}

	/* Check for a filetype */
	/* vi is set as the default for any extension without a program */
	if(multi_prog_cmd == NULL)
	{
		run_with_defaults(view);
		return;
	}

	if(no_multi_run)
	{
		run_using_prog(view, multi_prog_cmd, dont_execute, 0);
	}
	else
	{
		run_selection_separately(view, dont_execute);
	}
}
コード例 #25
0
ファイル: attr_dialog_nix.c プロジェクト: francogonzaga/vifm
void
enter_attr_mode(FileView *active_view)
{
	int i;
	mode_t fmode;
	mode_t diff;
	uid_t uid = geteuid();

	if(curr_stats.load_stage < 2)
		return;

	view = active_view;
	memset(perms, 0, sizeof(perms));

	diff = 0;
	i = 0;
	while(i < view->list_rows && !view->dir_entry[i].selected)
		i++;
	file_is_dir = 0;
	if(i == view->list_rows)
	{
		i = view->list_pos;
		file_is_dir = is_dir(view->dir_entry[i].name);
	}
	fmode = view->dir_entry[i].mode;
	if(uid != 0 && view->dir_entry[i].uid != uid)
	{
		show_error_msgf("Access error", "You are not owner of %s",
				view->dir_entry[i].name);
		clean_selected_files(view);
		load_dir_list(view, 1);
		move_to_list_pos(view, view->list_pos);
		return;
	}
	while(i < view->list_rows)
	{
		if(view->dir_entry[i].selected)
		{
			diff |= (view->dir_entry[i].mode ^ fmode);
			file_is_dir = file_is_dir || is_dir(view->dir_entry[i].name);

			if(uid != 0 && view->dir_entry[i].uid != uid)
			{
				show_error_msgf("Access error", "You are not owner of %s",
						view->dir_entry[i].name);
				return;
			}
		}

		i++;
	}

	*mode = ATTR_MODE;
	clear_input_bar();
	curr_stats.use_input_bar = 0;

	perms[0] = !(diff & S_IRUSR) ? (int)(fmode & S_IRUSR) : -1;
	perms[1] = !(diff & S_IWUSR) ? (int)(fmode & S_IWUSR) : -1;
	perms[2] = !(diff & S_IXUSR) ? (int)(fmode & S_IXUSR) : -1;
	perms[3] = !(diff & S_ISUID) ? (int)(fmode & S_ISUID) : -1;
	perms[4] = !(diff & S_IRGRP) ? (int)(fmode & S_IRGRP) : -1;
	perms[5] = !(diff & S_IWGRP) ? (int)(fmode & S_IWGRP) : -1;
	perms[6] = !(diff & S_IXGRP) ? (int)(fmode & S_IXGRP) : -1;
	perms[7] = !(diff & S_ISGID) ? (int)(fmode & S_ISGID) : -1;
	perms[8] = !(diff & S_IROTH) ? (int)(fmode & S_IROTH) : -1;
	perms[9] = !(diff & S_IWOTH) ? (int)(fmode & S_IWOTH) : -1;
	perms[10] = !(diff & S_IXOTH) ? (int)(fmode & S_IXOTH) : -1;
	perms[11] = !(diff & S_ISVTX) ? (int)(fmode & S_ISVTX) : -1;
	adv_perms[0] = 0;
	adv_perms[1] = 0;
	adv_perms[2] = 0;
	memcpy(origin_perms, perms, sizeof(perms));

	top = 3;
	bottom = file_is_dir ? 18 : 16;
	curr = 3;
	permnum = 0;
	step = 1;
	while(perms[permnum] < 0 && curr <= bottom)
	{
		inc_curr();
		permnum++;
	}

	if(curr > bottom)
	{
		show_error_msg("Permissions change error",
				"Selected files have no common access state");
		leave_attr_mode();
		return;
	}

	col = 9;
	changed = 0;
	redraw_attr_dialog();
}
コード例 #26
0
void
enter_attr_mode(FileView *active_view)
{
	mode_t fmode = 0;
	mode_t diff;
	uid_t uid = geteuid();
	dir_entry_t *entry;
	int first;

	if(curr_stats.load_stage < 2)
		return;

	view = active_view;
	memset(perms, 0, sizeof(perms));

	first = 1;
	file_is_dir = 0;
	diff = 0;
	entry = NULL;
	while(iter_selection_or_current(view, &entry))
	{
		if(first)
		{
			fmode = entry->mode;
			first = 0;
		}

		diff |= (entry->mode ^ fmode);
		file_is_dir |= fentry_is_dir(entry);

		if(uid != 0 && entry->uid != uid)
		{
			show_error_msgf("Access error", "You are not owner of %s", entry->name);
			return;
		}
	}
	if(first)
	{
		show_error_msg("Permissions", "No files to process");
		return;
	}

	vle_mode_set(ATTR_MODE, VMT_SECONDARY);
	clear_input_bar();
	curr_stats.use_input_bar = 0;

	perms[0] = !(diff & S_IRUSR) ? (int)(fmode & S_IRUSR) : -1;
	perms[1] = !(diff & S_IWUSR) ? (int)(fmode & S_IWUSR) : -1;
	perms[2] = !(diff & S_IXUSR) ? (int)(fmode & S_IXUSR) : -1;
	perms[3] = !(diff & S_ISUID) ? (int)(fmode & S_ISUID) : -1;
	perms[4] = !(diff & S_IRGRP) ? (int)(fmode & S_IRGRP) : -1;
	perms[5] = !(diff & S_IWGRP) ? (int)(fmode & S_IWGRP) : -1;
	perms[6] = !(diff & S_IXGRP) ? (int)(fmode & S_IXGRP) : -1;
	perms[7] = !(diff & S_ISGID) ? (int)(fmode & S_ISGID) : -1;
	perms[8] = !(diff & S_IROTH) ? (int)(fmode & S_IROTH) : -1;
	perms[9] = !(diff & S_IWOTH) ? (int)(fmode & S_IWOTH) : -1;
	perms[10] = !(diff & S_IXOTH) ? (int)(fmode & S_IXOTH) : -1;
	perms[11] = !(diff & S_ISVTX) ? (int)(fmode & S_ISVTX) : -1;
	adv_perms[0] = 0;
	adv_perms[1] = 0;
	adv_perms[2] = 0;
	memcpy(origin_perms, perms, sizeof(perms));

	top = 3;
	bottom = file_is_dir ? 18 : 16;
	curr = 3;
	permnum = 0;
	step = 1;
	while(perms[permnum] < 0 && curr <= bottom)
	{
		inc_curr();
		permnum++;
	}

	if(curr > bottom)
	{
		show_error_msg("Permissions change error",
				"Selected files have no common access state");
		leave_attr_mode();
		return;
	}

	col = 9;
	changed = 0;
	redraw_attr_dialog();
}