From d590e13fb1503cca40667e3fcf8b7637f658a0c0 Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Wed, 9 Nov 2011 23:08:31 +0300 Subject: [PATCH] Changed do_cd() and do_panel() functions ...to handle vfs_path_t objects. Changed panelized_panel_t.root type to vfs_path_t. Signed-off-by: Slava Zanko --- src/execute.c | 11 +- src/filemanager/cmd.c | 22 ++- src/filemanager/command.c | 18 +- src/filemanager/dir.c | 9 +- src/filemanager/dir.h | 3 +- src/filemanager/ext.c | 7 +- src/filemanager/find.c | 14 +- src/filemanager/midnight.c | 8 +- src/filemanager/panel.c | 246 +++++++++++++++------------ src/filemanager/panel.h | 4 +- src/filemanager/panelize.c | 51 +++--- src/filemanager/panelize.h | 1 + src/filemanager/tree.c | 2 +- src/main.c | 18 +- src/main.h | 3 +- tests/src/filemanager/do_panel_cd.c | 6 +- tests/src/filemanager/do_panel_cd_stub_env.c | 4 +- tests/src/filemanager/examine_cd.c | 6 +- 18 files changed, 262 insertions(+), 171 deletions(-) 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 ac2bcc16c..3aa6d44ac 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 7879cd2b9..d31a4409e 100644 --- a/src/filemanager/find.c +++ b/src/filemanager/find.c @@ -1738,14 +1738,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 a8f10242b..3b529e6fc 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 715863050..105c88e37 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); @@ -1070,7 +1070,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 @@ -1137,6 +1137,7 @@ panel_get_encoding_info_str (WPanel * panel) } /* --------------------------------------------------------------------------------------------- */ + static void show_dir (WPanel * panel) { @@ -1836,14 +1837,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; } } @@ -1858,7 +1867,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; @@ -2013,29 +2024,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 + { + char *dname; + dname = g_strndup (fname, bname - fname); + dname_vpath = vfs_path_from_str (dname); + g_free (dname); + } - do_cd (dname, cd_exact); + do_cd (dname_vpath, cd_exact); try_to_select (panel, bname); - g_free (dname); + vfs_path_free (dname_vpath); g_free (fname); } } @@ -2072,7 +2101,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); } } @@ -2409,7 +2442,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. @@ -2417,8 +2451,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; } @@ -2427,19 +2465,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) { @@ -2492,34 +2522,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); } /* --------------------------------------------------------------------------------------------- */ @@ -2538,13 +2565,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) @@ -2558,62 +2579,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)) - { - char buffer[MC_MAXPATHLEN], *p; - int i; - struct stat st; - vfs_path_t *panel_fname_vpath = vfs_path_from_str (selection (panel)->fname); + if (!S_ISLNK (panel->dir.list[panel->selected].st.st_mode)) + return; - 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)) + 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)) + { + 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); } + 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, cd_exact); - change_panel (); - - move_down (panel); + change_panel (); + do_cd (new_dir_vpath, cd_exact); + vfs_path_free (new_dir_vpath); + change_panel (); - g_free (new_dir); - } + move_down (panel); } /* --------------------------------------------------------------------------------------------- */ @@ -2849,11 +2861,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) { @@ -2877,16 +2891,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); @@ -2930,9 +2942,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); + } } /* --------------------------------------------------------------------------------------------- */ @@ -2944,8 +2962,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); + } } /* --------------------------------------------------------------------------------------------- */ @@ -2959,7 +2984,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; @@ -2969,6 +2997,7 @@ directory_history_list (WPanel * panel) } else message (D_ERROR, MSG_ERROR, _("Cannot change directory")); + vfs_path_free (s_vpath); g_free (s); } } @@ -3967,8 +3996,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) @@ -4226,11 +4255,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; @@ -4333,9 +4362,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; } @@ -4355,7 +4389,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 f45b9f343..1b8c8104f 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 @@ -159,7 +159,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 c3d6b2a48..fc05bdebe 100644 --- a/src/filemanager/panelize.c +++ b/src/filemanager/panelize.c @@ -319,18 +319,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) { int status, link_to_dir, stale_link; @@ -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 196191501..cd52378c1 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" @@ -275,15 +275,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; + + 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, exact); + res = do_panel_cd (current_panel, _new_dir_vpath, exact); #ifdef 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; -- 2.11.4.GIT