Beispiel #1
0
void
menu_morph_into_cmdline(CmdLineSubmode submode, const char input[],
		int external)
{
	/* input might point to part of menu data. */
	char *input_copy;

	if(input[0] == '\0')
	{
		show_error_msg("Command insertion", "Ignoring empty command");
		return;
	}

	input_copy = external ? format_str("!%s", input) : strdup(input);
	if(input_copy == NULL)
	{
		show_error_msg("Error", "Not enough memory");
		return;
	}

	leave_menu_mode(0);
	enter_cmdline_mode(submode, input_copy, NULL);

	free(input_copy);
}
Beispiel #2
0
int
vim_view_file(const char filename[], int line, int column, int allow_forking)
{
	char vicmd[PATH_MAX];
	char cmd[PATH_MAX + 5];
	const char *fork_str = allow_forking ? "" : "--nofork";
	char *escaped;
	int bg;
	int result;

	cmd[0] = '\0';

	if(!path_exists(filename, DEREF))
	{
		if(path_exists(filename, NODEREF))
		{
			show_error_msg("Broken Link", "Link destination doesn't exist");
		}
		else
		{
			show_error_msg("Wrong Path", "File doesn't exist");
		}
		return 1;
	}

#ifndef _WIN32
	escaped = shell_like_escape(filename, 0);
#else
	escaped = (char *)enclose_in_dquotes(filename);
#endif

	copy_str(vicmd, sizeof(vicmd), cfg_get_vicmd(&bg));
	trim_right(vicmd);
	if(!allow_forking)
	{
		char *p = strrchr(vicmd, ' ');
		if(p != NULL && strstr(p, "remote"))
		{
			*p = '\0';
		}
	}

	if(line < 0 && column < 0)
		snprintf(cmd, sizeof(cmd), "%s %s %s", vicmd, fork_str, escaped);
	else if(column < 0)
		snprintf(cmd, sizeof(cmd), "%s %s +%d %s", vicmd, fork_str, line, escaped);
	else
		snprintf(cmd, sizeof(cmd), "%s %s \"+call cursor(%d, %d)\" %s", vicmd,
				fork_str, line, column, escaped);

#ifndef _WIN32
	free(escaped);
#endif

	result = run_vim(cmd, bg && allow_forking, allow_forking);
	curs_set(FALSE);

	return result;
}
Beispiel #3
0
pid_t
background_and_capture(char *cmd, int user_sh, FILE **out, FILE **err)
{
	pid_t pid;
	int out_pipe[2];
	int error_pipe[2];

	if(pipe(out_pipe) != 0)
	{
		show_error_msg("File pipe error", "Error creating pipe");
		return (pid_t)-1;
	}

	if(pipe(error_pipe) != 0)
	{
		show_error_msg("File pipe error", "Error creating pipe");
		close(out_pipe[0]);
		close(out_pipe[1]);
		return (pid_t)-1;
	}

	if((pid = fork()) == -1)
	{
		close(out_pipe[0]);
		close(out_pipe[1]);
		close(error_pipe[0]);
		close(error_pipe[1]);
		return (pid_t)-1;
	}

	if(pid == 0)
	{
		char *sh;

		close(out_pipe[0]);
		close(error_pipe[0]);
		if(dup2(out_pipe[1], STDOUT_FILENO) == -1)
		{
			_Exit(EXIT_FAILURE);
		}
		if(dup2(error_pipe[1], STDERR_FILENO) == -1)
		{
			_Exit(EXIT_FAILURE);
		}

		sh = user_sh ? get_execv_path(cfg.shell) : "/bin/sh";
		execvp(sh, make_execv_array(sh, cmd));
		_Exit(127);
	}

	close(out_pipe[1]);
	close(error_pipe[1]);
	*out = fdopen(out_pipe[0], "r");
	*err = fdopen(error_pipe[0], "r");

	return pid;
}
Beispiel #4
0
/* Resolve link target and either navigate inside directory link points to or
 * navigate to directory where target is located pointing cursor on
 * it (the follow_dirs flag controls behaviour). */
static void
follow_link(FileView *view, int follow_dirs)
{
	char *dir, *file;
	char full_path[PATH_MAX];
	char linkto[PATH_MAX + NAME_MAX];
	dir_entry_t *const entry = &curr_view->dir_entry[curr_view->list_pos];

	get_full_path_of(entry, sizeof(full_path), full_path);

	if(get_link_target_abs(full_path, entry->origin, linkto, sizeof(linkto)) != 0)
	{
		show_error_msg("Error", "Can't read link.");
		return;
	}

	if(!path_exists(linkto, DEREF))
	{
		show_error_msg("Broken Link",
				"Can't access link destination.  It might be broken.");
		return;
	}

	chosp(linkto);

	if(is_dir(linkto) && !follow_dirs)
	{
		dir = strdup(entry->name);
		file = NULL;
	}
	else
	{
		dir = strdup(linkto);
		remove_last_path_component(dir);

		file = get_last_path_component(linkto);
	}

	if(dir[0] != '\0')
	{
		navigate_to(view, dir);
	}

	if(file != NULL)
	{
		const int pos = find_file_pos_in_list(view, file);
		if(pos >= 0)
		{
			flist_set_pos(view, pos);
		}
	}

	free(dir);
}
Beispiel #5
0
/* Handles current content of the menu to Vim as quickfix list. */
static void
cmd_v(key_info_t key_info, keys_info_t *keys_info)
{
	int bg;
	const char *vi_cmd;
	FILE *vim_stdin;
	char *cmd;
	int i;
	int qf = 1;

	/* If both first and last lines do not contain colons, treat lines as list of
	 * file names. */
	if(strchr(menu->items[0], ':') == NULL &&
			strchr(menu->items[menu->len - 1], ':') == NULL)
	{
		qf = 0;
	}

	ui_shutdown();
	curr_stats.need_update = UT_FULL;

	vi_cmd = cfg_get_vicmd(&bg);
	if(!qf)
	{
		char *const arg = shell_like_escape("+exe 'bd!|args' "
				"join(map(getline('1','$'),'fnameescape(v:val)'))", 0);
		cmd = format_str("%s %s +argument%d -", vi_cmd, arg, menu->pos + 1);
		free(arg);
	}
	else if(menu->pos == 0)
	{
		/* For some reason +cc1 causes noisy messages on status line, so handle this
		 * case separately. */
		cmd = format_str("%s +cgetbuffer +bd! +cfirst -", vi_cmd);
	}
	else
	{
		cmd = format_str("%s +cgetbuffer +bd! +cfirst +cc%d -", vi_cmd,
				menu->pos + 1);
	}

	vim_stdin = popen(cmd, "w");
	free(cmd);

	if(vim_stdin == NULL)
	{
		recover_after_shellout();
		show_error_msg("Vim QuickFix", "Failed to send list of files to editor.");
		return;
	}

	for(i = 0; i < menu->len; ++i)
	{
		fputs(menu->items[i], vim_stdin);
		putc('\n', vim_stdin);
	}

	pclose(vim_stdin);
	recover_after_shellout();
}
Beispiel #6
0
KHandlerResponse
filelist_khandler(FileView *view, menu_data_t *m, const wchar_t keys[])
{
	if(wcscmp(keys, L"gf") == 0)
	{
		(void)goto_selected_file(m, curr_view, m->items[m->pos], 0);
		return KHR_CLOSE_MENU;
	}
	else if(wcscmp(keys, L"e") == 0)
	{
		(void)goto_selected_file(m, curr_view, m->items[m->pos], 1);
		return KHR_REFRESH_WINDOW;
	}
	else if(wcscmp(keys, L"c") == 0)
	{
		/* Insert just file name. */
		int line_num;
		const char *const rel_base = get_relative_path_base(m, view);
		char *const path = parse_file_spec(m->items[m->pos], &line_num, rel_base);
		if(path == NULL)
		{
			show_error_msg("Command insertion", "No valid filename found");
			return KHR_REFRESH_WINDOW;
		}
		menu_morph_into_cmdline(CLS_COMMAND, path, 1);
		free(path);
		return KHR_MORPHED_MENU;
	}

	return KHR_UNHANDLED;
}
Beispiel #7
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;
}
Beispiel #8
0
void
print_errors(FILE *ef)
{
	char linebuf[160];
	char buf[sizeof(linebuf)*5];

	if(ef == NULL)
		return;

	buf[0] = '\0';
	while(fgets(linebuf, sizeof(linebuf), ef) == linebuf)
	{
		if(linebuf[0] == '\n')
			continue;
		if(strlen(buf) + strlen(linebuf) + 1 >= sizeof(buf))
		{
			int skip = (prompt_error_msg("Background Process Error", buf) != 0);
			buf[0] = '\0';
			if(skip)
				break;
		}
		strcat(buf, linebuf);
	}

	if(buf[0] != '\0')
		show_error_msg("Background Process Error", buf);

	fclose(ef);
}
Beispiel #9
0
void
show_errors_from_file(FILE *ef, const char title[])
{
	char linebuf[160];
	char buf[sizeof(linebuf)*5];

	if(ef == NULL)
		return;

	buf[0] = '\0';
	while(fgets(linebuf, sizeof(linebuf), ef) == linebuf)
	{
		if(linebuf[0] == '\n')
			continue;
		if(strlen(buf) + strlen(linebuf) + 1 >= sizeof(buf))
		{
			int skip = (prompt_error_msg(title, buf) != 0);
			buf[0] = '\0';
			if(skip)
				break;
		}
		strcat(buf, linebuf);
	}

	if(buf[0] != '\0')
	{
		show_error_msg(title, buf);
	}

	fclose(ef);
}
Beispiel #10
0
void
ft_assoc_record_add_all(assoc_records_t *assocs, const assoc_records_t *src)
{
	int i;
	void *p;
	const int src_count = src->count;

	if(src_count == 0)
	{
		return;
	}

	p = reallocarray(assocs->list, assocs->count + src_count,
			sizeof(assoc_record_t));
	if(p == NULL)
	{
		show_error_msg("Memory Error", "Unable to allocate enough memory");
		return;
	}

	assocs->list = p;

	for(i = 0; i < src_count; ++i)
	{
		assocs->list[assocs->count + i].command = strdup(src->list[i].command);
		assocs->list[assocs->count + i].description =
				strdup(src->list[i].description);
		assocs->list[assocs->count + i].type = src->list[i].type;
	}

	assocs->count += src_count;
}
Beispiel #11
0
void
enter_sort_mode(view_t *active_view)
{
	if(curr_stats.load_stage < 2)
	{
		return;
	}

	if(cv_compare(active_view->custom.type))
	{
		show_error_msg("Sorting", "Sorting of comparison view can't be changed.");
		return;
	}

	view = active_view;
	descending = (view->sort[0] < 0);
	vle_mode_set(SORT_MODE, VMT_SECONDARY);

	top = 4;
	bottom = top + SK_COUNT - 1;
	curr = top + indexes[abs(view->sort[0])];
	col = 4;

	redraw_sort_dialog();
}
Beispiel #12
0
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);
}
Beispiel #13
0
/* Loads list of strings and related data into view_info_t structure from
 * specified file.  The action parameter is a title to be used for error
 * messages.  Returns non-zero on error, otherwise zero is returned. */
static int
load_view_data(view_info_t *vi, const char action[], const char file_to_view[],
		int silent)
{
	const int error = get_view_data(vi, file_to_view);

	if(error != 0 && silent)
	{
		return 1;
	}

	switch(error)
	{
		case 0:
			break;

		case 1:
			show_error_msg(action, "Can't explore a directory");
			return 1;
		case 2:
			show_error_msg(action, "Can't open file for reading");
			return 1;
		case 3:
			show_error_msg(action, "Can't get data from viewer");
			return 1;
		case 4:
			show_error_msg(action, "Nothing to explore");
			return 1;

		default:
			assert(0 && "Unhandled error code.");
			return 1;
	}

	vi->widths = reallocarray(NULL, vi->nlines, sizeof(*vi->widths));
	if(vi->widths == NULL)
	{
		free_string_array(vi->lines, vi->nlines);
		vi->lines = NULL;
		vi->nlines = 0;
		show_error_msg(action, "Not enough memory");
		return 1;
	}

	return 0;
}
Beispiel #14
0
static void
cmd_dd(key_info_t key_info, keys_info_t *keys_info)
{
	if(pass_combination_to_khandler(L"dd") && menu->len == 0)
	{
		show_error_msg("Menu is closing", "No more items in the menu");
		leave_menu_mode(1);
	}
}
Beispiel #15
0
/* Writes all menu lines into file specified as argument. */
static int
write_cmd(const cmd_info_t *cmd_info)
{
	char *const no_tilde = expand_tilde(cmd_info->argv[0]);
	if(write_file_of_lines(no_tilde, menu->items, menu->len) != 0)
	{
		show_error_msg("Failed to open output file", strerror(errno));
	}
	free(no_tilde);
	return 0;
}
Beispiel #16
0
pid_t
background_and_capture(char cmd[], int user_sh, FILE **out, FILE **err)
{
	int out_fd, out_pipe[2];
	int err_fd, err_pipe[2];
	pid_t pid;

	if(_pipe(out_pipe, 512, O_NOINHERIT) != 0)
	{
		show_error_msg("File pipe error", "Error creating pipe");
		return (pid_t)-1;
	}

	if(_pipe(err_pipe, 512, O_NOINHERIT) != 0)
	{
		show_error_msg("File pipe error", "Error creating pipe");
		close(out_pipe[0]);
		close(out_pipe[1]);
		return (pid_t)-1;
	}

	out_fd = dup(_fileno(stdout));
	err_fd = dup(_fileno(stderr));

	pid = background_and_capture_internal(cmd, user_sh, out, err, out_pipe,
			err_pipe);

	_close(out_pipe[1]);
	_close(err_pipe[1]);

	_dup2(out_fd, _fileno(stdout));
	_dup2(err_fd, _fileno(stderr));

	if(pid == (pid_t)-1)
	{
		_close(out_pipe[0]);
		_close(err_pipe[0]);
	}

	return pid;
}
Beispiel #17
0
/* Makees custom view of specified type out of menu items. */
static void
dump_into_custom_view(int very)
{
	if(menu_to_custom_view(menu, view, very) != 0)
	{
		show_error_msg("Menu transformation",
				"No valid paths discovered in menu content");
		return;
	}

	leave_menu_mode(1);
}
Beispiel #18
0
static int
key_handler(wchar_t key)
{
	const wchar_t shortcut[] = {key, L'\0'};

	if(pass_combination_to_khandler(shortcut) && menu->len == 0)
	{
		show_error_msg("No more items in the menu", "Menu will be closed");
		leave_menu_mode(1);
	}

	return 0;
}
Beispiel #19
0
/* Tries to run selection displaying error message on file type
 * inconsistency. */
static void
run_selection(FileView *view, int dont_execute)
{
	if(selection_is_consistent(view))
	{
		run_file(view, dont_execute);
	}
	else
	{
		show_error_msg("Selection error",
				"Selection cannot contain files and directories at the same time");
	}
}
Beispiel #20
0
static void
error_msg(const char *title, const char *text)
{
	job_t *job = pthread_getspecific(current_job);
	if(job == NULL)
	{
		show_error_msg(title, text);
	}
	else
	{
		(void)replace_string(&job->error, text);
	}
}
Beispiel #21
0
static void
cmd_dd(key_info_t key_info, keys_info_t *keys_info)
{
	if(menu->key_handler == NULL)
		return;

	if(menu->key_handler(menu, L"dd") > 0)
		wrefresh(menu_win);

	if(menu->len == 0)
	{
		show_error_msg("No more items in the menu", "Menu will be closed");
		leave_menu_mode();
	}
}
Beispiel #22
0
static char *
append_to_expanded(char *expanded, const char* str)
{
	char *t;

	t = realloc(expanded, strlen(expanded) + strlen(str) + 1);
	if(t == NULL)
	{
		show_error_msg("Memory Error", "Unable to allocate enough memory");
		free(expanded);
		return NULL;
	}
	strcat(t, str);
	return t;
}
Beispiel #23
0
static void
add_assoc(assoc_list_t *assoc_list, assoc_t assoc)
{
	void *p;
	p = reallocarray(assoc_list->list, assoc_list->count + 1, sizeof(assoc_t));
	if(p == NULL)
	{
		show_error_msg("Memory Error", "Unable to allocate enough memory");
		return;
	}

	assoc_list->list = p;
	assoc_list->list[assoc_list->count] = assoc;
	assoc_list->count++;
}
Beispiel #24
0
/* Runs current file entry of the view in a generic way (entering directories
 * and opening files in editors). */
static void
run_with_defaults(FileView *view)
{
	if(view->dir_entry[view->list_pos].type == FT_DIR)
	{
		open_dir(view);
	}
	else if(view->selected_files <= 1)
	{
		view_current_file(view);
	}
	else if(vim_edit_selection() != 0)
	{
		show_error_msg("Running error", "Can't edit selection");
	}
}
Beispiel #25
0
void
enter_file_info_mode(FileView *v)
{
	if(fentry_is_fake(get_current_entry(v)))
	{
		show_error_msg("File info", "Entry doesn't correspond to a file.");
		return;
	}

	vle_mode_set(FILE_INFO_MODE, VMT_PRIMARY);
	view = v;
	setup_menu();
	redraw_file_info_dialog();

	was_redraw = 0;
}
Beispiel #26
0
/* Appends str to expanded with reallocation.  Returns address of the new
 * string or NULL on reallocation error. */
static char *
append_to_expanded(char expanded[], const char str[])
{
	char *t;
	const size_t len = strlen(expanded);

	t = realloc(expanded, len + strlen(str) + 1);
	if(t == NULL)
	{
		show_error_msg("Memory Error", "Unable to allocate enough memory");
		free(expanded);
		return NULL;
	}
	strcpy(t + len, str);
	return t;
}
Beispiel #27
0
int
exec_command(const char cmd[], FileView *view, CmdInputType type)
{
	int menu;
	int backward;

	if(cmd == NULL)
	{
		return repeat_command(view, type);
	}

	menu = 0;
	backward = 0;
	switch(type)
	{
		case CIT_BSEARCH_PATTERN: backward = 1; /* Fall through. */
		case CIT_FSEARCH_PATTERN:
			return find_npattern(view, cmd, backward, 1);

		case CIT_VBSEARCH_PATTERN: backward = 1; /* Fall through. */
		case CIT_VFSEARCH_PATTERN:
			return find_vpattern(view, cmd, backward, 1);

		case CIT_VWBSEARCH_PATTERN: backward = 1; /* Fall through. */
		case CIT_VWFSEARCH_PATTERN:
			return find_vwpattern(cmd, backward);

		case CIT_MENU_COMMAND: menu = 1; /* Fall through. */
		case CIT_COMMAND:
			return execute_command(view, cmd, menu);

		case CIT_FILTER_PATTERN:
			if(view->custom.type != CV_DIFF)
			{
				local_filter_apply(view, cmd);
			}
			else
			{
				show_error_msg("Filtering", "No local filter for diff views");
			}
			return 0;

		default:
			assert(0 && "Command execution request of unknown/unexpected type.");
			return 0;
	}
}
Beispiel #28
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);
}
Beispiel #29
0
void
ft_assoc_record_add(assoc_records_t *records, const char *command,
		const char *description)
{
	void *p;
	p = reallocarray(records->list, records->count + 1, sizeof(assoc_record_t));
	if(p == NULL)
	{
		show_error_msg("Memory Error", "Unable to allocate enough memory");
		return;
	}

	records->list = p;
	records->list[records->count].command = strdup(command);
	records->list[records->count].description = strdup(description);
	records->list[records->count].type = new_records_type;
	records->count++;
}
Beispiel #30
0
void
enter_view_mode(FileView *view, int explore)
{
	char full_path[PATH_MAX];

	if(get_file_to_explore(curr_view, full_path, sizeof(full_path)) != 0)
	{
		show_error_msg("File exploring", "The file cannot be explored");
		return;
	}

	/* Either make use of abandoned view or prune it. */
	if(try_ressurect_abandoned(full_path, explore) == 0)
	{
		ui_views_update_titles();
		return;
	}

	pick_vi(explore);

	vi->view = view;
	if(load_view_data(vi, "File exploring", full_path, NOSILENT) != 0)
	{
		return;
	}

	vi->filename = strdup(full_path);

	vle_mode_set(VIEW_MODE, VMT_SECONDARY);

	if(explore)
	{
		vi->view = curr_view;
		curr_view->explore_mode = 1;
	}
	else
	{
		vi->view = other_view;
	}

	ui_views_update_titles();

	view_redraw();
}