/* buf should be at least PATH_MAX characters length */ static void parse_path(const char *dir, const char *path, char *buf) { strcpy(buf, path); #ifdef _WIN32 to_forward_slash(buf); #endif if(is_path_absolute(buf)) { snprintf(buf, PATH_MAX, "%s", path); } #ifdef _WIN32 else if(buf[0] == '/') { snprintf(buf, PATH_MAX, "%c:%s", dir[0], path); } #endif else { char new_path[PATH_MAX]; snprintf(new_path, sizeof(new_path), "%s/%s", dir, path); canonicalize_path(new_path, buf, PATH_MAX); } if(!is_root_dir(buf)) chosp(buf); #ifdef _WIN32 to_forward_slash(buf); #endif }
int to_canonic_path(const char path[], char buf[], size_t buf_len) { if(!is_path_absolute(path)) { char cwd[PATH_MAX]; char full_path[PATH_MAX]; if(get_cwd(cwd, sizeof(cwd)) == NULL) { /* getcwd() failed, we can't use relative path, so fail. */ LOG_SERROR_MSG(errno, "Can't get CWD"); return 1; } #ifdef _WIN32 to_forward_slash(cwd); #endif snprintf(full_path, sizeof(full_path), "%s/%s", cwd, path); canonicalize_path(full_path, buf, buf_len); } else { canonicalize_path(path, buf, buf_len); } chosp(buf); return 0; }
void generate_tmp_file_name(const char prefix[], char buf[], size_t buf_len) { snprintf(buf, buf_len, "%s/%s", get_tmpdir(), prefix); #ifdef _WIN32 to_forward_slash(buf); #endif copy_str(buf, buf_len, make_name_unique(buf)); }
/* Applies one filename modifiers per call. */ static const char * apply_mod(const char *path, const char *parent, const char *mod, int *mod_len, int for_shell) { char path_buf[PATH_MAX]; static char buf[PATH_MAX]; snprintf(path_buf, sizeof(path_buf), "%s", path); #ifdef _WIN32 to_forward_slash(path_buf); #endif *mod_len = 2; if(starts_with_lit(mod, ":p")) *mod_len += apply_p_mod(path_buf, parent, buf, sizeof(buf)); else if(starts_with_lit(mod, ":~")) *mod_len += apply_tilde_mod(path_buf, buf, sizeof(buf)); else if(starts_with_lit(mod, ":.")) *mod_len += apply_dot_mod(path_buf, buf, sizeof(buf)); else if(starts_with_lit(mod, ":h")) *mod_len += apply_h_mod(path_buf, buf, sizeof(buf)); #ifdef _WIN32 else if(starts_with_lit(mod, ":u")) *mod_len += apply_u_mod(path_buf, buf, sizeof(buf)); #endif else if(starts_with_lit(mod, ":t")) *mod_len += apply_t_mod(path_buf, buf, sizeof(buf)); else if(starts_with_lit(mod, ":r")) *mod_len += apply_r_mod(path_buf, buf, sizeof(buf)); else if(starts_with_lit(mod, ":e")) *mod_len += apply_e_mod(path_buf, buf, sizeof(buf)); else if(starts_with_lit(mod, ":s") || starts_with_lit(mod, ":gs")) *mod_len += apply_s_gs_mod(path_buf, mod, buf, sizeof(buf)); else return NULL; #ifdef _WIN32 /* This is needed to run something like explorer.exe, which isn't smart enough * to understand forward slashes. */ if(for_shell && curr_stats.shell_type != ST_CMD) { if(!starts_with_lit(mod, ":s") && !starts_with_lit(mod, ":gs")) { to_back_slash(buf); } } #endif return buf; }
/* Extracts path and line number from the spec (1 when absent from the spec). * Returns path and sets *line_num to line number, otherwise NULL is * returned. */ TSTATIC char * parse_spec(const char spec[], int *line_num) { char *path_buf; const char *colon; int colon_lookup_offset = 0; const size_t bufs_len = 2 + strlen(spec) + 1 + 1; path_buf = malloc(bufs_len); if(path_buf == NULL) { return NULL; } if(is_path_absolute(spec)) { path_buf[0] = '\0'; } else { copy_str(path_buf, bufs_len, "./"); } #ifdef _WIN32 if(is_path_absolute(spec)) { colon_lookup_offset = 2; } #endif colon = strchr(spec + colon_lookup_offset, ':'); if(colon != NULL) { strncat(path_buf, spec, colon - spec); *line_num = atoi(colon + 1); } else { strcat(path_buf, spec); *line_num = 1; } chomp(path_buf); #ifdef _WIN32 to_forward_slash(path_buf); #endif return path_buf; }
/* tries to use $APPDATA/Vifm as configuration directory */ static int try_appdata_for_conf(void) { LOG_FUNC_ENTER; #ifndef _WIN32 return 0; #else char vifm[PATH_MAX]; const char *appdata = env_get("APPDATA"); if(appdata == NULL || !is_dir(appdata)) return 0; snprintf(vifm, sizeof(vifm), "%s/Vifm", appdata); to_forward_slash(vifm); env_set(VIFM_EV, vifm); return 1; #endif }
/* tries to use directory of executable file as configuration directory */ static int try_exe_directory_for_conf(void) { LOG_FUNC_ENTER; #ifndef _WIN32 return 0; #else char exe_dir[PATH_MAX]; GetModuleFileNameA(NULL, exe_dir, sizeof(exe_dir)); to_forward_slash(exe_dir); *strrchr(exe_dir, '/') = '\0'; if(!path_exists_at(exe_dir, VIFMRC)) return 0; env_set(VIFM_EV, exe_dir); return 1; #endif }
/* tries to use USERPROFILE environment variable to find home directory */ static int try_userprofile_envvar_for_home(void) { LOG_FUNC_ENTER; #ifndef _WIN32 return 0; #else char home[PATH_MAX]; const char *userprofile = env_get("USERPROFILE"); if(userprofile == NULL || !is_dir(userprofile)) return 0; snprintf(home, sizeof(home), "%s", userprofile); to_forward_slash(home); env_set(HOME_EV, home); return 1; #endif }
/* tries to use vifmrc in directory of executable file as configuration file */ static int try_exe_directory_for_vifmrc(void) { LOG_FUNC_ENTER; #ifndef _WIN32 return 0; #else char vifmrc[PATH_MAX]; GetModuleFileNameA(NULL, vifmrc, sizeof(vifmrc)); to_forward_slash(vifmrc); *strrchr(vifmrc, '/') = '\0'; strcat(vifmrc, "/" VIFMRC); if(!path_exists(vifmrc)) return 0; env_set(MYVIFMRC_EV, vifmrc); return 1; #endif }
void ipc_send(char *data[]) { char buf[8192]; size_t len; struct sockaddr_in addr; int result; if(server) return; assert(initialized || sock != -1); if(initialized < 0) return; if(getcwd(buf, sizeof(buf)) == NULL) { LOG_ERROR_MSG("Can't get working directory"); return; } len = strlen(buf) + 1; #ifdef _WIN32 to_forward_slash(buf); #endif while(*data != NULL) { strcpy(buf + len, *data); len += strlen(*data) + 1; data++; } buf[len++] = '\0'; addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("127.0.0.1"); addr.sin_port = htons(PORT); result = sendto(sock, buf, len, 0, (struct sockaddr *)&addr, sizeof(addr)); if(result == -1) { LOG_ERROR_MSG("Can't send data over a socket"); } }
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); }
static int try_homepath_envvar_for_home(void) { LOG_FUNC_ENTER; #ifndef _WIN32 return 0; #else char home[PATH_MAX]; const char *homedrive = env_get("HOMEDRIVE"); const char *homepath = env_get("HOMEPATH"); if(homedrive == NULL || !is_dir(homedrive)) return 0; if(homepath == NULL || !is_dir(homepath)) return 0; snprintf(home, sizeof(home), "%s%s", homedrive, homepath); to_forward_slash(home); env_set(HOME_EV, home); return 1; #endif }
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 }
int main(int argc, char *argv[]) { /* TODO: refactor main() function */ char dir[PATH_MAX]; char lwin_path[PATH_MAX] = ""; char rwin_path[PATH_MAX] = ""; int lwin_handle = 0, rwin_handle = 0; int old_config; int no_configs; init_config(); if(is_in_string_array(argv + 1, argc - 1, "--logging")) { init_logger(1); } (void)setlocale(LC_ALL, ""); if(getcwd(dir, sizeof(dir)) == NULL) { perror("getcwd"); return -1; } #ifdef _WIN32 to_forward_slash(dir); #endif init_filelists(); init_registers(); set_config_paths(); reinit_logger(); init_commands(); init_builtin_functions(); update_path_env(1); if(init_status() != 0) { puts("Error during session status initialization."); return -1; } no_configs = is_in_string_array(argv + 1, argc - 1, "--no-configs"); /* Tell file type module what function to use to check availability of * external programs. */ config_filetypes(&external_command_exists); /* This should be called before loading any configuration file. */ reset_all_file_associations(curr_stats.env_type == ENVTYPE_EMULATOR_WITH_X); init_option_handlers(); old_config = is_old_config(); if(!old_config && !no_configs) read_info_file(0); ipc_pre_init(); parse_args(argc, argv, dir, lwin_path, rwin_path, &lwin_handle, &rwin_handle); ipc_init(&parse_recieved_arguments); init_background(); set_view_path(&lwin, lwin_path); set_view_path(&rwin, rwin_path); /* Force view switch when path is specified for invisible pane. */ if(lwin_path[0] != '\0' && rwin_path[0] == '\0' && curr_view != &lwin) { change_window(); } load_initial_directory(&lwin, dir); load_initial_directory(&rwin, dir); /* Force split view when two paths are specified on command-line. */ if(lwin_path[0] != '\0' && rwin_path[0] != '\0') { curr_stats.number_of_windows = 2; } /* Setup the ncurses interface. */ if(!setup_ncurses_interface()) return -1; colmgr_init(COLOR_PAIRS); init_modes(); init_undo_list(&perform_operation, NULL, &cfg.undo_levels); load_local_options(curr_view); curr_stats.load_stage = 1; if(!old_config && !no_configs) { load_scheme(); source_config(); } write_color_scheme_file(); setup_signals(); if(old_config && !no_configs) { convert_configs(); curr_stats.load_stage = 0; read_info_file(0); curr_stats.load_stage = 1; set_view_path(&lwin, lwin_path); set_view_path(&rwin, rwin_path); load_initial_directory(&lwin, dir); load_initial_directory(&rwin, dir); source_config(); } (void)create_trash_dir(cfg.trash_dir); check_path_for_file(&lwin, lwin_path, lwin_handle); check_path_for_file(&rwin, rwin_path, rwin_handle); curr_stats.load_stage = 2; exec_startup_commands(argc, argv); update_screen(UT_FULL); modes_update(); /* Update histories of the views to ensure that their current directories, * which might have been set using command-line parameters, are stored in the * history. This is not done automatically as history manipulation should be * postponed until views are fully loaded, otherwise there is no correct * information about current file and relative cursor position. */ save_view_history(&lwin, NULL, NULL, -1); save_view_history(&rwin, NULL, NULL, -1); curr_stats.load_stage = 3; main_loop(); return 0; }
void init_config(void) { cfg.num_bookmarks = 0; cfg.vim_filter = 0; cfg.show_one_window = 0; cfg.history_len = 15; (void)hist_init(&cfg.cmd_hist, cfg.history_len); (void)hist_init(&cfg.search_hist, cfg.history_len); (void)hist_init(&cfg.prompt_hist, cfg.history_len); (void)hist_init(&cfg.filter_hist, cfg.history_len); cfg.auto_execute = 0; cfg.time_format = strdup(" %m/%d %H:%M"); cfg.wrap_quick_view = 1; cfg.use_iec_prefixes = 0; cfg.undo_levels = 100; cfg.sort_numbers = 0; cfg.follow_links = 1; cfg.fast_run = 0; cfg.confirm = 1; cfg.vi_command = strdup("vim"); cfg.vi_cmd_bg = 0; cfg.vi_x_command = strdup(""); cfg.vi_x_cmd_bg = 0; cfg.use_trash = 1; { char fuse_home[PATH_MAX]; int update_stat; snprintf(fuse_home, sizeof(fuse_home), "%s/vifm_FUSE", get_tmpdir()); update_stat = set_fuse_home(fuse_home); assert(update_stat == 0); } cfg.use_term_multiplexer = 0; cfg.use_vim_help = 0; cfg.wild_menu = 0; cfg.ignore_case = 0; cfg.smart_case = 0; cfg.hl_search = 1; cfg.vifm_info = VIFMINFO_BOOKMARKS; cfg.auto_ch_pos = 1; cfg.timeout_len = 1000; cfg.scroll_off = 0; cfg.gdefault = 0; #ifndef _WIN32 cfg.slow_fs_list = strdup(""); #endif cfg.scroll_bind = 0; cfg.wrap_scan = 1; cfg.inc_search = 0; cfg.selection_is_primary = 1; cfg.tab_switches_pane = 1; cfg.last_status = 1; cfg.tab_stop = 8; cfg.ruler_format = strdup("%=%l/%S "); cfg.status_line = strdup(""); cfg.lines = INT_MIN; cfg.columns = INT_MIN; cfg.dot_dirs = DD_NONROOT_PARENT; cfg.trunc_normal_sb_msgs = 0; cfg.filter_inverted_by_default = 1; cfg.apropos_prg = strdup("apropos %a"); cfg.find_prg = strdup("find %s %a -print , " "-type d \\( ! -readable -o ! -executable \\) -prune"); cfg.grep_prg = strdup("grep -n -H -I -r %i %a %s"); cfg.locate_prg = strdup("locate %a"); #ifndef _WIN32 snprintf(cfg.log_file, sizeof(cfg.log_file), "/var/log/vifm-startup-log"); #else GetModuleFileNameA(NULL, cfg.log_file, sizeof(cfg.log_file)); to_forward_slash(cfg.log_file); *strrchr(cfg.log_file, '/') = '\0'; strcat(cfg.log_file, "/startup-log"); #endif #ifndef _WIN32 cfg.shell = strdup(env_get_def("SHELL", "sh")); #else cfg.shell = strdup(env_get_def("SHELL", "cmd")); #endif #ifndef _WIN32 /* Maximum argument length to pass to the shell */ if((cfg.max_args = sysconf(_SC_ARG_MAX)) == 0) #endif cfg.max_args = 4096; /* POSIX MINIMUM */ memset(&cfg.decorations, '\0', sizeof(cfg.decorations)); cfg.decorations[DIRECTORY][DECORATION_SUFFIX] = '/'; }