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); }
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; }
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; }
/* 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); }
/* 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(); }
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; }
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; }
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); }
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); }
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; }
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(); }
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); }
/* 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; }
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); } }
/* 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; }
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; }
/* 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); }
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; }
/* 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"); } }
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); } }
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(); } }
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; }
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++; }
/* 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"); } }
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; }
/* 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; }
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; } }
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); }
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++; }
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(); }