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