diff --git a/src/execute.c b/src/execute.c index 602498395..33392f747 100644 --- a/src/execute.c +++ b/src/execute.c @@ -36,6 +36,7 @@ #include "lib/tty/key.h" #include "lib/tty/win.h" #include "lib/vfs/vfs.h" +#include "lib/mcconfig.h" #include "lib/util.h" #include "lib/widget.h" @@ -114,12 +115,20 @@ edition_pre_exec (void) static void do_possible_cd (const char *new_dir) { - if (!do_cd (new_dir, cd_exact)) + vfs_path_t *new_dir_vpath; + + if (*new_dir == '\0') + new_dir_vpath = vfs_path_from_str (mc_config_get_home_dir()); + else + new_dir_vpath = vfs_path_from_str (new_dir); + + if (!do_cd (new_dir_vpath, cd_exact)) message (D_ERROR, _("Warning"), _("The Commander can't change to the directory that\n" "the subshell claims you are in. Perhaps you have\n" "deleted your working directory, or given yourself\n" "extra access permissions with the \"su\" command?")); + vfs_path_free (new_dir_vpath); } #endif /* HAVE_SUBSHELL_SUPPORT */ diff --git a/src/filemanager/cmd.c b/src/filemanager/cmd.c index 65d4e069c..f454f6947 100644 --- a/src/filemanager/cmd.c +++ b/src/filemanager/cmd.c @@ -159,6 +159,8 @@ do_view_cmd (gboolean normal) /* Directories are viewed by changing to them */ if (S_ISDIR (selection (current_panel)->st.st_mode) || link_isdir (selection (current_panel))) { + vfs_path_t *fname_vpath; + if (confirm_view_dir && (current_panel->marked || current_panel->dirs_marked)) { if (query_dialog @@ -168,8 +170,10 @@ do_view_cmd (gboolean normal) return; } } - if (!do_cd (selection (current_panel)->fname, cd_exact)) + fname_vpath = vfs_path_from_str (selection (current_panel)->fname); + if (!do_cd (fname_vpath, cd_exact)) message (D_ERROR, MSG_ERROR, _("Cannot change directory")); + vfs_path_free (fname_vpath); } else { @@ -561,12 +565,19 @@ nice_cd (const char *text, const char *xtext, const char *help, if (*cd_path != PATH_SEP) { char *tmp = cd_path; + cd_path = g_strconcat (PATH_SEP_STR, tmp, (char *) NULL); g_free (tmp); } - if (!do_panel_cd (MENU_PANEL, cd_path, cd_parse_command)) - message (D_ERROR, MSG_ERROR, _("Cannot chdir to \"%s\""), cd_path); + { + vfs_path_t *cd_vpath; + + cd_vpath = vfs_path_from_str (cd_path); + if (!do_panel_cd (MENU_PANEL, cd_vpath, cd_parse_command)) + message (D_ERROR, MSG_ERROR, _("Cannot chdir to \"%s\""), cd_path); + vfs_path_free (cd_vpath); + } g_free (cd_path); g_free (machine); } @@ -1264,13 +1275,16 @@ void vfs_list (void) { char *target; + vfs_path_t *target_vpath; target = hotlist_show (LIST_VFSLIST); if (!target) return; - if (!do_cd (target, cd_exact)) + target_vpath = vfs_path_from_str (target); + if (!do_cd (target_vpath, cd_exact)) message (D_ERROR, MSG_ERROR, _("Cannot change directory")); + vfs_path_free (target_vpath); g_free (target); } #endif /* ENABLE_VFS */ diff --git a/src/filemanager/command.c b/src/filemanager/command.c index 89dddfe4f..4a6fa5db5 100644 --- a/src/filemanager/command.c +++ b/src/filemanager/command.c @@ -208,11 +208,11 @@ handle_cdpath (const char *path) *s = '\0'; if (*p != '\0') { - char *r; + vfs_path_t *r_vpath; - r = mc_build_filename (p, path, (char *) NULL); - result = do_cd (r, cd_parse_command); - g_free (r); + r_vpath = vfs_path_build_filename (p, path, NULL); + result = do_cd (r_vpath, cd_parse_command); + vfs_path_free (r_vpath); } *s = c; p = s + 1; @@ -418,10 +418,17 @@ do_cd_command (char *orig_cmd) else { char *path; + vfs_path_t *q_vpath; gboolean ok; path = examine_cd (&cmd[operand_pos]); - ok = do_cd (path, cd_parse_command); + + if (*path == '\0') + q_vpath = vfs_path_from_str (mc_config_get_home_dir()); + else + q_vpath = vfs_path_from_str (path); + + ok = do_cd (q_vpath, cd_parse_command); if (!ok) ok = handle_cdpath (path); @@ -434,6 +441,7 @@ do_cd_command (char *orig_cmd) unix_error_string (errno)); } + vfs_path_free (q_vpath); g_free (path); } } diff --git a/src/filemanager/dir.c b/src/filemanager/dir.c index e47109345..2c67f702a 100644 --- a/src/filemanager/dir.c +++ b/src/filemanager/dir.c @@ -599,17 +599,12 @@ do_load_dir (const char *path, dir_list * list, sortfn * sort, gboolean lc_rever /* --------------------------------------------------------------------------------------------- */ gboolean -if_link_is_exe (const char *full_name, const file_entry * file) +if_link_is_exe (const vfs_path_t * full_name_vpath, const file_entry * file) { struct stat b; - vfs_path_t *vpath = vfs_path_from_str (full_name); - if (S_ISLNK (file->st.st_mode) && mc_stat (vpath, &b) == 0) - { - vfs_path_free (vpath); + if (S_ISLNK (file->st.st_mode) && mc_stat (full_name_vpath, &b) == 0) return is_exe (b.st_mode); - } - vfs_path_free (vpath); return TRUE; } diff --git a/src/filemanager/dir.h b/src/filemanager/dir.h index 9acc5dbd0..bddce85c5 100644 --- a/src/filemanager/dir.h +++ b/src/filemanager/dir.h @@ -9,6 +9,7 @@ #include "lib/global.h" #include "lib/util.h" +#include "lib/vfs/vfs.h" /*** typedefs(not structures) and defined constants **********************************************/ @@ -53,7 +54,7 @@ int sort_ctime (file_entry * a, file_entry * b); int sort_size (file_entry * a, file_entry * b); int sort_inode (file_entry * a, file_entry * b); -gboolean if_link_is_exe (const char *full_name, const file_entry * file); +gboolean if_link_is_exe (const vfs_path_t * full_name, const file_entry * file); /*** inline functions ****************************************************************************/ diff --git a/src/filemanager/ext.c b/src/filemanager/ext.c index 99e8aa8c9..ba3810772 100644 --- a/src/filemanager/ext.c +++ b/src/filemanager/ext.c @@ -352,6 +352,8 @@ exec_extension (const char *filename, const char *lc_data, int *move_dir, int st else if (is_cd) { char *q; + vfs_path_t *p_vpath; + *p = 0; p = buffer; /* while (*p == ' ' && *p == '\t') @@ -363,7 +365,10 @@ exec_extension (const char *filename, const char *lc_data, int *move_dir, int st while (q >= p && (*q == ' ' || *q == '\t')) q--; q[1] = 0; - do_cd (p, cd_parse_command); + + p_vpath = vfs_path_from_str (p); + do_cd (p_vpath, cd_parse_command); + vfs_path_free (p_vpath); } else { diff --git a/src/filemanager/find.c b/src/filemanager/find.c index 28a71a086..dc73bf873 100644 --- a/src/filemanager/find.c +++ b/src/filemanager/find.c @@ -1752,14 +1752,24 @@ find_file (void) { if (dirname != NULL) { - do_cd (dirname, cd_exact); + vfs_path_t *dirname_vpath; + + dirname_vpath = vfs_path_from_str (dirname); + do_cd (dirname_vpath, cd_exact); + vfs_path_free (dirname_vpath); if (filename != NULL) try_to_select (current_panel, filename + (content != NULL ? strchr (filename + 4, ':') - filename + 1 : 4)); } else if (filename != NULL) - do_cd (filename, cd_exact); + { + vfs_path_t *filename_vpath; + + filename_vpath = vfs_path_from_str (filename); + do_cd (filename_vpath, cd_exact); + vfs_path_free (filename_vpath); + } g_free (dirname); g_free (filename); diff --git a/src/filemanager/midnight.c b/src/filemanager/midnight.c index 34c73f359..1f74fae18 100644 --- a/src/filemanager/midnight.c +++ b/src/filemanager/midnight.c @@ -151,9 +151,13 @@ treebox_cmd (void) char *sel_dir; sel_dir = tree_box (selection (current_panel)->fname); - if (sel_dir) + if (sel_dir != NULL) { - do_cd (sel_dir, cd_exact); + vfs_path_t *sel_vdir; + + sel_vdir = vfs_path_from_str (sel_dir); + do_cd (sel_vdir, cd_exact); + vfs_path_free (sel_vdir); g_free (sel_dir); } } diff --git a/src/filemanager/panel.c b/src/filemanager/panel.c index d859cf46c..942a4c8e7 100644 --- a/src/filemanager/panel.c +++ b/src/filemanager/panel.c @@ -81,7 +81,7 @@ hook_t *select_file_hook = NULL; /* *INDENT-OFF* */ -panelized_panel_t panelized_panel = { { NULL, 0 }, -1, { '\0' } }; +panelized_panel_t panelized_panel = { {NULL, 0}, -1, NULL }; /* *INDENT-ON* */ static const char *string_file_name (file_entry *, int); @@ -1145,7 +1145,7 @@ show_free_space (WPanel * panel) /* --------------------------------------------------------------------------------------------- */ /** - * Make path string for shiwing in panel's header. + * Prepare path string for showing in panel's header. * Passwords will removed, also home dir will replaced by ~ * * @param panel WPanel object @@ -1212,6 +1212,7 @@ panel_get_encoding_info_str (WPanel * panel) } /* --------------------------------------------------------------------------------------------- */ + static void show_dir (WPanel * panel) { @@ -1911,14 +1912,22 @@ maybe_cd (int move_up_dir) { if (move_up_dir) { - do_cd ("..", cd_exact); + vfs_path_t *up_dir; + + up_dir = vfs_path_from_str (".."); + do_cd (up_dir, cd_exact); + vfs_path_free (up_dir); return MSG_HANDLED; } if (S_ISDIR (selection (current_panel)->st.st_mode) || link_isdir (selection (current_panel))) { - do_cd (selection (current_panel)->fname, cd_exact); + vfs_path_t *vpath; + + vpath = vfs_path_from_str (selection (current_panel)->fname); + do_cd (vpath, cd_exact); + vfs_path_free (vpath); return MSG_HANDLED; } } @@ -1933,7 +1942,9 @@ force_maybe_cd (void) { if (cmdline->buffer[0] == '\0') { - do_cd ("..", cd_exact); + vfs_path_t *up_dir = vfs_path_from_str (".."); + do_cd (up_dir, cd_exact); + vfs_path_free (up_dir); return MSG_HANDLED; } return MSG_NOT_HANDLED; @@ -2088,29 +2099,47 @@ static void goto_parent_dir (WPanel * panel) { if (!panel->is_panelized) - do_cd ("..", cd_exact); + { + vfs_path_t *up_dir; + + up_dir = vfs_path_from_str (".."); + do_cd (up_dir, cd_exact); + vfs_path_free (up_dir); + } else { char *fname = panel->dir.list[panel->selected].fname; const char *bname; - char *dname; + vfs_path_t *dname_vpath; if (g_path_is_absolute (fname)) fname = g_strdup (fname); else - fname = mc_build_filename (panelized_panel.root, fname, (char *) NULL); + { + char *tmp_root; + + tmp_root = vfs_path_to_str (panelized_panel.root_vpath); + fname = mc_build_filename (tmp_root, fname, (char *) NULL); + g_free (tmp_root); + } bname = x_basename (fname); if (bname == fname) - dname = g_strdup ("."); + dname_vpath = vfs_path_from_str ("."); else - dname = g_strndup (fname, bname - fname); + { + char *dname; - do_cd (dname, cd_exact); + dname = g_strndup (fname, bname - fname); + dname_vpath = vfs_path_from_str (dname); + g_free (dname); + } + + do_cd (dname_vpath, cd_exact); try_to_select (panel, bname); - g_free (dname); + vfs_path_free (dname_vpath); g_free (fname); } } @@ -2147,7 +2176,11 @@ goto_child_dir (WPanel * panel) { if ((S_ISDIR (selection (panel)->st.st_mode) || link_isdir (selection (panel)))) { - do_cd (selection (panel)->fname, cd_exact); + vfs_path_t *vpath; + + vpath = vfs_path_from_str (selection (panel)->fname); + do_cd (vpath, cd_exact); + vfs_path_free (vpath); } } @@ -2484,7 +2517,8 @@ stop_search (WPanel * panel) static int do_enter_on_file_entry (file_entry * fe) { - char *full_name; + vfs_path_t *full_name_vpath; + gboolean ok; /* * Directory or link to directory - change directory. @@ -2492,8 +2526,12 @@ do_enter_on_file_entry (file_entry * fe) */ if (S_ISDIR (fe->st.st_mode) || link_isdir (fe) || (fe->st.st_mode == 0)) { - if (!do_cd (fe->fname, cd_exact)) + vfs_path_t *fname_vpath; + + fname_vpath = vfs_path_from_str (fe->fname); + if (!do_cd (fname_vpath, cd_exact)) message (D_ERROR, MSG_ERROR, _("Cannot change directory")); + vfs_path_free (fname_vpath); return 1; } @@ -2502,19 +2540,11 @@ do_enter_on_file_entry (file_entry * fe) return 1; /* Check if the file is executable */ - { - char *tmp_path; - - tmp_path = vfs_path_to_str (current_panel->cwd_vpath); - full_name = mc_build_filename (tmp_path, fe->fname, NULL); - g_free (tmp_path); - } - if (!is_exe (fe->st.st_mode) || !if_link_is_exe (full_name, fe)) - { - g_free (full_name); + full_name_vpath = vfs_path_append_new (current_panel->cwd_vpath, fe->fname, NULL); + ok = (is_exe (fe->st.st_mode) && if_link_is_exe (full_name_vpath, fe)); + vfs_path_free (full_name_vpath); + if (!ok) return 0; - } - g_free (full_name); if (confirm_execute) { @@ -2567,34 +2597,31 @@ chdir_other_panel (WPanel * panel) { const file_entry *entry = &panel->dir.list[panel->selected]; - char *new_dir; + vfs_path_t *new_dir_vpath; char *sel_entry = NULL; - char *tmp_path; if (get_other_type () != view_listing) { set_display_type (get_other_index (), view_listing); } - tmp_path = vfs_path_to_str (panel->cwd_vpath); if (S_ISDIR (entry->st.st_mode) || entry->f.link_to_dir) - new_dir = mc_build_filename (tmp_path, entry->fname, (char *) NULL); + new_dir_vpath = vfs_path_append_new (panel->cwd_vpath, entry->fname, NULL); else { - new_dir = mc_build_filename (tmp_path, "..", (char *) NULL); - sel_entry = strrchr (tmp_path, PATH_SEP); + new_dir_vpath = vfs_path_append_new (panel->cwd_vpath, "..", (char *) NULL); + sel_entry = strrchr (vfs_path_get_last_path_str (panel->cwd_vpath), PATH_SEP); } - g_free (tmp_path); change_panel (); - do_cd (new_dir, cd_exact); + do_cd (new_dir_vpath, cd_exact); + vfs_path_free (new_dir_vpath); + if (sel_entry) try_to_select (current_panel, sel_entry); change_panel (); move_down (panel); - - g_free (new_dir); } /* --------------------------------------------------------------------------------------------- */ @@ -2613,13 +2640,7 @@ panel_sync_other (const WPanel * panel) set_display_type (get_other_index (), view_listing); } - { - char *tmp_path; - - tmp_path = vfs_path_to_str (current_panel->cwd_vpath); - do_panel_cd (other_panel, tmp_path, cd_exact); - g_free (tmp_path); - } + do_panel_cd (other_panel, current_panel->cwd_vpath, cd_exact); /* try to select current filename on the other panel */ if (!panel->is_panelized) @@ -2633,62 +2654,53 @@ panel_sync_other (const WPanel * panel) static void chdir_to_readlink (WPanel * panel) { - char *new_dir; + vfs_path_t *new_dir_vpath; + char buffer[MC_MAXPATHLEN], *p; + int i; + struct stat st; + vfs_path_t *panel_fname_vpath; + gboolean ok; if (get_other_type () != view_listing) return; - if (S_ISLNK (panel->dir.list[panel->selected].st.st_mode)) + if (!S_ISLNK (panel->dir.list[panel->selected].st.st_mode)) + return; + + i = readlink (selection (panel)->fname, buffer, MC_MAXPATHLEN - 1); + if (i < 0) + return; + + panel_fname_vpath = vfs_path_from_str (selection (panel)->fname); + ok = (mc_stat (panel_fname_vpath, &st) >= 0); + vfs_path_free (panel_fname_vpath); + if (!ok) + return; + + buffer[i] = 0; + if (!S_ISDIR (st.st_mode)) { - char buffer[MC_MAXPATHLEN], *p; - int i; - struct stat st; - vfs_path_t *panel_fname_vpath = vfs_path_from_str (selection (panel)->fname); - - i = readlink (selection (panel)->fname, buffer, MC_MAXPATHLEN - 1); - if (i < 0) - { - vfs_path_free (panel_fname_vpath); - return; - } - if (mc_stat (panel_fname_vpath, &st) < 0) - { - vfs_path_free (panel_fname_vpath); - return; - } - vfs_path_free (panel_fname_vpath); - buffer[i] = 0; - if (!S_ISDIR (st.st_mode)) + p = strrchr (buffer, PATH_SEP); + if (p && !p[1]) { + *p = 0; p = strrchr (buffer, PATH_SEP); - if (p && !p[1]) - { - *p = 0; - p = strrchr (buffer, PATH_SEP); - } - if (!p) - return; - p[1] = 0; } - if (*buffer == PATH_SEP) - new_dir = g_strdup (buffer); - else - { - char *tmp_path; - - tmp_path = vfs_path_to_str (panel->cwd_vpath); - new_dir = mc_build_filename (tmp_path, buffer, NULL); - g_free (tmp_path); - } - - change_panel (); - do_cd (new_dir, cd_exact); - change_panel (); - - move_down (panel); - - g_free (new_dir); + if (!p) + return; + p[1] = 0; } + if (*buffer == PATH_SEP) + new_dir_vpath = vfs_path_from_str (buffer); + else + new_dir_vpath = vfs_path_append_new (panel->cwd_vpath, buffer, NULL); + + change_panel (); + do_cd (new_dir_vpath, cd_exact); + vfs_path_free (new_dir_vpath); + change_panel (); + + move_down (panel); } /* --------------------------------------------------------------------------------------------- */ @@ -2965,11 +2977,13 @@ subshell_chdir (const vfs_path_t * vpath) */ static gboolean -_do_panel_cd (WPanel * panel, const char *new_dir, enum cd_enum cd_type) +_do_panel_cd (WPanel * panel, const vfs_path_t * new_dir_vpath, enum cd_enum cd_type) { - vfs_path_t *vpath; char *olddir; char temp[MC_MAXPATHLEN]; + char *new_dir, *_new_dir; + + _new_dir = new_dir = vfs_path_to_str (new_dir_vpath); if (cd_type == cd_parse_command) { @@ -2993,16 +3007,14 @@ _do_panel_cd (WPanel * panel, const char *new_dir, enum cd_enum cd_type) g_free (tmp_path); } } - vpath = vfs_path_from_str (*new_dir ? new_dir : mc_config_get_home_dir ()); + g_free (_new_dir); - if (mc_chdir (vpath) == -1) + if (mc_chdir (new_dir_vpath) == -1) { panel_set_cwd (panel, olddir); g_free (olddir); - vfs_path_free (vpath); return FALSE; } - vfs_path_free (vpath); /* Success: save previous directory, shutdown status of previous dir */ panel_set_lwd (panel, olddir); @@ -3046,9 +3058,15 @@ directory_history_next (WPanel * panel) GList *nextdir; nextdir = g_list_next (panel->dir_history); + if (nextdir != NULL) + { + vfs_path_t *data_vpath; - if ((nextdir != NULL) && (_do_panel_cd (panel, (char *) nextdir->data, cd_exact))) - panel->dir_history = nextdir; + data_vpath = vfs_path_from_str ((char *) nextdir->data); + if (_do_panel_cd (panel, data_vpath, cd_exact)) + panel->dir_history = nextdir; + vfs_path_free (data_vpath); + } } /* --------------------------------------------------------------------------------------------- */ @@ -3060,8 +3078,15 @@ directory_history_prev (WPanel * panel) prevdir = g_list_previous (panel->dir_history); - if ((prevdir != NULL) && (_do_panel_cd (panel, (char *) prevdir->data, cd_exact))) - panel->dir_history = prevdir; + if (prevdir != NULL) + { + vfs_path_t *data_vpath; + + data_vpath = vfs_path_from_str ((char *) prevdir->data); + if (_do_panel_cd (panel, data_vpath, cd_exact)) + panel->dir_history = prevdir; + vfs_path_free (data_vpath); + } } /* --------------------------------------------------------------------------------------------- */ @@ -3075,7 +3100,10 @@ directory_history_list (WPanel * panel) if (s != NULL) { - if (_do_panel_cd (panel, s, cd_exact)) + vfs_path_t *s_vpath; + + s_vpath = vfs_path_from_str (s); + if (_do_panel_cd (panel, s_vpath, cd_exact)) { char *tmp_path; @@ -3085,6 +3113,7 @@ directory_history_list (WPanel * panel) } else message (D_ERROR, MSG_ERROR, _("Cannot change directory")); + vfs_path_free (s_vpath); g_free (s); } } @@ -4093,8 +4122,8 @@ panel_reload (WPanel * panel) tmp_path = vfs_path_to_str (panel->cwd_vpath); ok = (panels_options.fast_reload && stat (tmp_path, ¤t_stat) == 0 - && current_stat.st_ctime == panel->dir_stat.st_ctime - && current_stat.st_mtime == panel->dir_stat.st_mtime); + && current_stat.st_ctime == panel->dir_stat.st_ctime + && current_stat.st_mtime == panel->dir_stat.st_mtime); g_free (tmp_path); if (ok) @@ -4352,11 +4381,11 @@ do_file_mark (WPanel * panel, int idx, int mark) * Record change in the directory history. */ gboolean -do_panel_cd (struct WPanel *panel, const char *new_dir, enum cd_enum cd_type) +do_panel_cd (struct WPanel *panel, const vfs_path_t * new_dir_vpath, enum cd_enum cd_type) { gboolean r; - r = _do_panel_cd (panel, new_dir, cd_type); + r = _do_panel_cd (panel, new_dir_vpath, cd_type); if (r) { char *tmp_path; @@ -4459,9 +4488,14 @@ panel_change_encoding (WPanel * panel) if (panel->codepage == SELECT_CHARSET_NO_TRANSLATE) { /* No translation */ + vfs_path_t *cd_path_vpath; + g_free (init_translation_table (mc_global.display_codepage, mc_global.display_codepage)); cd_path = remove_encoding_from_path (panel->cwd_vpath); - do_panel_cd (panel, cd_path, cd_parse_command); + cd_path_vpath = vfs_path_from_str (cd_path); + do_panel_cd (panel, cd_path_vpath, cd_parse_command); + show_dir (panel); + vfs_path_free (cd_path_vpath); g_free (cd_path); return; } @@ -4481,7 +4515,7 @@ panel_change_encoding (WPanel * panel) vfs_change_encoding (panel->cwd_vpath, encoding); cd_path = vfs_path_to_str (panel->cwd_vpath); - if (!do_panel_cd (panel, cd_path, cd_parse_command)) + if (!do_panel_cd (panel, panel->cwd_vpath, cd_parse_command)) message (D_ERROR, MSG_ERROR, _("Cannot chdir to \"%s\""), cd_path); g_free (cd_path); } diff --git a/src/filemanager/panel.h b/src/filemanager/panel.h index 6f32e32a9..0221eb1ab 100644 --- a/src/filemanager/panel.h +++ b/src/filemanager/panel.h @@ -70,7 +70,7 @@ typedef struct { dir_list list; int count; - char root[MC_MAXPATHLEN]; + vfs_path_t *root_vpath; } panelized_panel_t; typedef struct panel_sort_info_struct @@ -161,7 +161,7 @@ void recalculate_panel_summary (WPanel * panel); void file_mark (WPanel * panel, int idx, int val); void do_file_mark (WPanel * panel, int idx, int val); -gboolean do_panel_cd (struct WPanel *panel, const char *new_dir, enum cd_enum cd_type); +gboolean do_panel_cd (struct WPanel *panel, const vfs_path_t * new_dir_vpath, enum cd_enum cd_type); void directory_history_add (struct WPanel *panel, const char *dir); diff --git a/src/filemanager/panelize.c b/src/filemanager/panelize.c index 738088c9c..a9c853841 100644 --- a/src/filemanager/panelize.c +++ b/src/filemanager/panelize.c @@ -318,18 +318,6 @@ remove_from_panelize (struct panelize *entry) /* --------------------------------------------------------------------------------------------- */ -static void -panelize_strlcpy (char *buffer, const vfs_path_t * vpath, size_t max_len) -{ - char *str_path; - - str_path = vfs_path_to_str (vpath); - g_strlcpy (buffer, str_path, max_len); - g_free (str_path); -} - -/* --------------------------------------------------------------------------------------------- */ - static void do_external_panelize (char *command) { @@ -351,7 +339,7 @@ do_external_panelize (char *command) /* Clear the counters and the directory list */ panel_clean_dir (current_panel); - panelize_strlcpy (panelized_panel.root, current_panel->cwd_vpath, MC_MAXPATHLEN); + panelize_change_root (current_panel->cwd_vpath); if (set_zero_dir (list)) next_free++; @@ -425,8 +413,8 @@ do_panelize_cd (struct WPanel *panel) gboolean panelized_same; clean_dir (list, panel->count); - if (panelized_panel.root[0] == '\0') - panelize_strlcpy (panelized_panel.root, panel->cwd_vpath, MC_MAXPATHLEN); + if (panelized_panel.root_vpath == NULL) + panelize_change_root (current_panel->cwd_vpath); if (panelized_panel.count < 1) { @@ -441,13 +429,7 @@ do_panelize_cd (struct WPanel *panel) panel->count = panelized_panel.count; panel->is_panelized = TRUE; - { - char *cwd_str; - - cwd_str = vfs_path_to_str (panel->cwd_vpath); - panelized_same = (strcmp (panelized_panel.root, cwd_str) == 0); - g_free (cwd_str); - } + panelized_same = (vfs_path_cmp (panelized_panel.root_vpath, panel->cwd_vpath) == 0); for (i = 0; i < panelized_panel.count; i++) { @@ -462,9 +444,13 @@ do_panelize_cd (struct WPanel *panel) } else { - list->list[i].fname = mc_build_filename (panelized_panel.root, - panelized_panel.list.list[i].fname, - (char *) NULL); + vfs_path_t *tmp_vpath; + + tmp_vpath = + vfs_path_append_new (panelized_panel.root_vpath, panelized_panel.list.list[i].fname, + NULL); + list->list[i].fname = vfs_path_to_str (tmp_vpath); + vfs_path_free (tmp_vpath); list->list[i].fnamelen = strlen (list->list[i].fname); } list->list[i].f.link_to_dir = panelized_panel.list.list[i].f.link_to_dir; @@ -482,13 +468,26 @@ do_panelize_cd (struct WPanel *panel) /*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ +/** + * Change root directory of panelized content. + * @param new_root - object with new path. + */ +void +panelize_change_root (const vfs_path_t * new_root) +{ + vfs_path_free (panelized_panel.root_vpath); + panelized_panel.root_vpath = vfs_path_clone (new_root); +} + +/* --------------------------------------------------------------------------------------------- */ + void panelize_save_panel (struct WPanel *panel) { int i; dir_list *list = &panel->dir; - panelize_strlcpy (panelized_panel.root, panel->cwd_vpath, MC_MAXPATHLEN); + panelize_change_root (current_panel->cwd_vpath); if (panelized_panel.count > 0) clean_dir (&panelized_panel.list, panelized_panel.count); diff --git a/src/filemanager/panelize.h b/src/filemanager/panelize.h index 13addb1b4..1cffb4ab4 100644 --- a/src/filemanager/panelize.h +++ b/src/filemanager/panelize.h @@ -23,6 +23,7 @@ void save_panelize (void); void done_panelize (void); void cd_panelize_cmd (void); void panelize_save_panel (struct WPanel *panel); +void panelize_change_root (const vfs_path_t * new_root); /*** inline functions ****************************************************************************/ #endif /* MC__PANELIZE_H */ diff --git a/src/filemanager/tree.c b/src/filemanager/tree.c index 368fb808d..c05a522de 100644 --- a/src/filemanager/tree.c +++ b/src/filemanager/tree.c @@ -606,7 +606,7 @@ tree_chdir_sel (WTree * tree) change_panel (); tmp_path = vfs_path_to_str (tree->selected_ptr->name); - if (do_cd (tmp_path, cd_exact)) + if (do_cd (tree->selected_ptr->name, cd_exact)) select_item (current_panel); else message (D_ERROR, MSG_ERROR, _("Cannot chdir to \"%s\"\n%s"), diff --git a/src/main.c b/src/main.c index fa1e68cb7..202e17e22 100644 --- a/src/main.c +++ b/src/main.c @@ -59,7 +59,7 @@ #include "filemanager/layout.h" /* command_prompt */ #include "filemanager/ext.h" /* flush_extension_file() */ #include "filemanager/command.h" /* cmdline */ -#include "filemanager/panel.h" /* panalized_panel */ +#include "filemanager/panel.h" /* panalized_panel */ #include "vfs/plugins_init.h" @@ -259,15 +259,21 @@ init_sigchld (void) /* --------------------------------------------------------------------------------------------- */ gboolean -do_cd (const char *new_dir, enum cd_enum exact) +do_cd (const vfs_path_t * new_dir_vpath, enum cd_enum exact) { gboolean res; - const char *_new_dir = new_dir; + const vfs_path_t *_new_dir_vpath = new_dir_vpath; - if (current_panel->is_panelized && _new_dir[0] == '.' && _new_dir[1] == '.' && _new_dir[2] == 0) - _new_dir = panelized_panel.root; + if (current_panel->is_panelized) + { + size_t new_vpath_len; - res = do_panel_cd (current_panel, _new_dir, exact); + new_vpath_len = vfs_path_len (new_dir_vpath); + if (vfs_path_ncmp (new_dir_vpath, panelized_panel.root_vpath, new_vpath_len) == 0) + _new_dir_vpath = panelized_panel.root_vpath; + } + + res = do_panel_cd (current_panel, _new_dir_vpath, exact); #if HAVE_CHARSET if (res) diff --git a/src/main.h b/src/main.h index b24ff2759..fae8c4653 100644 --- a/src/main.h +++ b/src/main.h @@ -6,6 +6,7 @@ #define MC__MAIN_H #include "lib/global.h" +#include "lib/vfs/vfs.h" /*** typedefs(not structures) and defined constants **********************************************/ @@ -89,7 +90,7 @@ gboolean do_load_prompt (void); int load_prompt (int fd, void *unused); #endif -gboolean do_cd (const char *new_dir, enum cd_enum cd_type); +gboolean do_cd (const vfs_path_t * new_dir_vpath, enum cd_enum cd_type); void update_xterm_title_path (void); /*** inline functions ****************************************************************************/ diff --git a/tests/src/filemanager/do_panel_cd.c b/tests/src/filemanager/do_panel_cd.c index ca6b85cf8..0395dcdd1 100644 --- a/tests/src/filemanager/do_panel_cd.c +++ b/tests/src/filemanager/do_panel_cd.c @@ -61,7 +61,7 @@ START_TEST (test_do_panel_cd_empty_mean_home) char *cwd; struct WPanel *panel; gboolean ret; - + vfs_path_t *empty_path; cmdline = command_new (0, 0, 0); @@ -70,7 +70,9 @@ START_TEST (test_do_panel_cd_empty_mean_home) panel->lwd_vpath = vfs_path_from_str("/"); panel->sort_info.sort_field = g_new0(panel_field_t,1); - ret = do_panel_cd (panel, "", cd_parse_command); + empty_path = vfs_path_from_str (mc_config_get_home_dir()); + ret = do_panel_cd (panel, empty_path, cd_parse_command); + vfs_path_free (empty_path); fail_unless(ret); cwd = vfs_path_to_str (panel->cwd_vpath); diff --git a/tests/src/filemanager/do_panel_cd_stub_env.c b/tests/src/filemanager/do_panel_cd_stub_env.c index f12f27b89..c13a5c678 100644 --- a/tests/src/filemanager/do_panel_cd_stub_env.c +++ b/tests/src/filemanager/do_panel_cd_stub_env.c @@ -48,7 +48,7 @@ command_new (int y, int x, int cols) } int -do_cd (const char *new_dir, enum cd_enum exact) +do_cd (const vfs_path_t *new_dir, enum cd_enum exact) { (void) new_dir; (void) exact; @@ -190,7 +190,7 @@ regex_command (const char *filename, const char *action, int *move_dir) } gboolean -if_link_is_exe (const char *full_name, const file_entry * file) +if_link_is_exe (const vfs_path_t *full_name, const file_entry * file) { (void) full_name; (void) file; diff --git a/tests/src/filemanager/examine_cd.c b/tests/src/filemanager/examine_cd.c index 4e758f8ab..16c68aefa 100644 --- a/tests/src/filemanager/examine_cd.c +++ b/tests/src/filemanager/examine_cd.c @@ -31,6 +31,8 @@ #include +#include "lib/global.h" +#include "lib/vfs/path.h" #include "src/filemanager/layout.h" #include "src/filemanager/midnight.h" #include "src/filemanager/tree.h" @@ -56,9 +58,9 @@ get_current_type (void) } gboolean -do_cd (const char *new_dir, enum cd_enum cd_type) +do_cd (const vfs_path_t * new_dir_vpath, enum cd_enum cd_type) { - (void) new_dir; + (void) new_dir_vpath; (void) cd_type; return TRUE;