From 0aa10fd6cb5d2182aaa5a8614d355d85bb8b149b Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Tue, 27 Sep 2011 22:13:50 +0300 Subject: [PATCH] Changed type of WPanel::cwd (char *) and WPanel::lwd (char *) ...to WPanel::cwd_vpath (vfs_path_tr *) and WPanel::lwd_vpath (vfs_path_t *). Signed-off-by: Slava Zanko --- lib/util.c | 13 +- lib/util.h | 6 +- lib/vfs/interface.c | 17 -- lib/vfs/vfs.c | 22 ++- lib/vfs/vfs.h | 3 +- src/diffviewer/ydiff.c | 4 +- src/filemanager/boxes.c | 8 +- src/filemanager/boxes.h | 5 +- src/filemanager/cmd.c | 102 +++++++---- src/filemanager/command.c | 35 ++-- src/filemanager/file.c | 236 ++++++++++++------------ src/filemanager/file.h | 11 +- src/filemanager/filegui.c | 8 +- src/filemanager/filenot.c | 36 ++-- src/filemanager/find.c | 29 ++- src/filemanager/hotlist.c | 17 +- src/filemanager/info.c | 9 +- src/filemanager/layout.c | 22 +-- src/filemanager/layout.h | 2 +- src/filemanager/midnight.c | 68 ++++--- src/filemanager/panel.c | 354 +++++++++++++++++++++--------------- src/filemanager/panel.h | 20 +- src/filemanager/panelize.c | 32 +++- src/filemanager/tree.c | 23 +-- src/filemanager/usermenu.c | 14 +- src/main.c | 12 +- src/setup.c | 8 +- src/subshell.c | 30 ++- src/subshell.h | 2 +- tests/lib/vfs/current_dir.c | 8 +- 30 files changed, 669 insertions(+), 487 deletions(-) diff --git a/lib/util.c b/lib/util.c index 23b5a8527..9da86c364 100644 --- a/lib/util.c +++ b/lib/util.c @@ -1061,21 +1061,28 @@ convert_controls (const char *p) */ char * -diff_two_paths (const char *first, const char *second) +diff_two_paths (const vfs_path_t * vpath1, const vfs_path_t * vpath2) { char *p, *q, *r, *s, *buf = NULL; int i, j, prevlen = -1, currlen; char *my_first = NULL, *my_second = NULL; + char *path_str; - my_first = resolve_symlinks (first); + path_str = vfs_path_to_str (vpath1); + my_first = resolve_symlinks (path_str); + g_free (path_str); if (my_first == NULL) return NULL; - my_second = resolve_symlinks (second); + + path_str = vfs_path_to_str (vpath2); + my_second = resolve_symlinks (path_str); + g_free (path_str); if (my_second == NULL) { g_free (my_first); return NULL; } + for (j = 0; j < 2; j++) { p = my_first; diff --git a/lib/util.h b/lib/util.h index 077c361ee..7d12178ec 100644 --- a/lib/util.h +++ b/lib/util.h @@ -12,6 +12,8 @@ #include /* uintmax_t */ #include +#include "lib/vfs/vfs.h" + /*** typedefs(not structures) and defined constants **********************************************/ #ifndef MAXSYMLINKS @@ -128,7 +130,7 @@ char *convert_controls (const char *s); /* overwrites passwd with '\0's and frees it. */ void wipe_password (char *passwd); -char *diff_two_paths (const char *first, const char *second); +char *diff_two_paths (const vfs_path_t * vpath1, const vfs_path_t * vpath2); /* Returns the basename of fname. The result is a pointer into fname. */ const char *x_basename (const char *fname); @@ -163,7 +165,7 @@ void custom_canonicalize_pathname (char *, CANON_PATH_FLAGS); void canonicalize_pathname (char *); /* Misc Unix functions */ -int my_mkdir (const char *s, mode_t mode); +int my_mkdir (const vfs_path_t * s, mode_t mode); int my_rmdir (const char *s); #ifdef HAVE_REALPATH diff --git a/lib/vfs/interface.c b/lib/vfs/interface.c index 71da3448b..0b4567bb3 100644 --- a/lib/vfs/interface.c +++ b/lib/vfs/interface.c @@ -597,23 +597,6 @@ mc_fstat (int handle, struct stat *buf) return result; } -/* --------------------------------------------------------------------------------------------- */ -/** - * Return current directory. If it's local, reread the current directory - * from the OS. Put directory to the provided buffer. - */ - -char * -mc_get_current_wd (char *buffer, size_t size) -{ - char *cwd = _vfs_get_cwd (); - - g_strlcpy (buffer, cwd, size); - g_free (cwd); - - return buffer; -} - /* --------------------------------------------------------------------------------------------- */ vfs_path_t * diff --git a/lib/vfs/vfs.c b/lib/vfs/vfs.c index 0269ba35a..be4cdeb4e 100644 --- a/lib/vfs/vfs.c +++ b/lib/vfs/vfs.c @@ -438,7 +438,7 @@ vfs_setup_work_dir (void) { vfs_path_element_t *path_element; - g_free (_vfs_get_cwd ()); + vfs_setup_cwd (); /* FIXME: is we really need for this check? */ /* @@ -518,12 +518,12 @@ vfs_print_message (const char *msg, ...) /* --------------------------------------------------------------------------------------------- */ /** - * Return current directory. If it's local, reread the current directory - * from the OS. You must g_strdup() whatever this function returns. + * If it's local, reread the current directory + * from the OS. */ -char * -_vfs_get_cwd (void) +void +vfs_setup_cwd (void) { vfs_path_element_t *path_element; @@ -561,6 +561,18 @@ _vfs_get_cwd (void) vfs_path_free (tmp_vpath); } } +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Return current directory. If it's local, reread the current directory + * from the OS. + */ + +char * +_vfs_get_cwd (void) +{ + vfs_setup_cwd (); return vfs_path_to_str (vfs_get_raw_current_dir ()); } diff --git a/lib/vfs/vfs.h b/lib/vfs/vfs.h index 15ce3db98..d62e9efdb 100644 --- a/lib/vfs/vfs.h +++ b/lib/vfs/vfs.h @@ -265,6 +265,7 @@ void *vfs_class_data_find_by_handle (int handle); void vfs_free_handle (int handle); +void vfs_setup_cwd (void); char *_vfs_get_cwd (void); vfs_path_t *vfs_change_encoding (vfs_path_t * vpath, const char *encoding); @@ -299,7 +300,6 @@ int mc_unlink (const vfs_path_t * vpath); int mc_ctl (int fd, int ctlop, void *arg); int mc_setctl (const vfs_path_t * vpath, int ctlop, void *arg); int mc_open (const vfs_path_t * vpath, int flags, ...); -char *mc_get_current_wd (char *buffer, size_t bufsize); vfs_path_t *mc_getlocalcopy (const vfs_path_t * pathname_vpath); int mc_ungetlocalcopy (const vfs_path_t * pathname_vpath, const vfs_path_t * local_vpath, gboolean has_changed); @@ -310,4 +310,5 @@ const char *mc_tmpdir (void); /*** inline functions ****************************************************************************/ + #endif /* MC_VFS_VFS_H */ diff --git a/src/diffviewer/ydiff.c b/src/diffviewer/ydiff.c index 47c5989c8..cc2ebd147 100644 --- a/src/diffviewer/ydiff.c +++ b/src/diffviewer/ydiff.c @@ -3383,8 +3383,8 @@ dview_diff_cmd (void) panel0 = other_panel; panel1 = current_panel; } - file0 = vfs_path_build_filename (panel0->cwd, selection (panel0)->fname, NULL); - file1 = vfs_path_build_filename (panel1->cwd, selection (panel1)->fname, NULL); + file0 = vfs_path_append_new (panel0->cwd_vpath, selection (panel0)->fname, NULL); + file1 = vfs_path_append_new (panel1->cwd_vpath, selection (panel1)->fname, NULL); is_dir0 = S_ISDIR (selection (panel0)->st.st_mode); is_dir1 = S_ISDIR (selection (panel1)->st.st_mode); } diff --git a/src/filemanager/boxes.c b/src/filemanager/boxes.c index 64a4b2fdb..26374050b 100644 --- a/src/filemanager/boxes.c +++ b/src/filemanager/boxes.c @@ -1041,8 +1041,12 @@ cd_dialog (void) /* --------------------------------------------------------------------------------------------- */ void -symlink_dialog (const char *existing, const char *new, char **ret_existing, char **ret_new) +symlink_dialog (const vfs_path_t * existing_vpath, const vfs_path_t * new_vpath, + char **ret_existing, char **ret_new) { + char *existing = vfs_path_to_str (existing_vpath); + char *new = vfs_path_to_str (new_vpath); + QuickWidget quick_widgets[] = { /* 0 */ QUICK_BUTTON (50, 80, 6, 8, N_("&Cancel"), B_CANCEL, NULL), /* 1 */ QUICK_BUTTON (16, 80, 6, 8, N_("&OK"), B_ENTER, NULL), @@ -1064,6 +1068,8 @@ symlink_dialog (const char *existing, const char *new, char **ret_existing, char *ret_new = NULL; *ret_existing = NULL; } + g_free (existing); + g_free (new); } /* --------------------------------------------------------------------------------------------- */ diff --git a/src/filemanager/boxes.h b/src/filemanager/boxes.h index 2b06cb78e..734cbac67 100644 --- a/src/filemanager/boxes.h +++ b/src/filemanager/boxes.h @@ -19,13 +19,14 @@ /*** declarations of public functions ************************************************************/ int display_box (WPanel * p, char **user, char **mini, int *use_msformat, int num); -const panel_field_t *sort_box (panel_sort_info_t *info); +const panel_field_t *sort_box (panel_sort_info_t * info); void confirm_box (void); void display_bits_box (void); void configure_vfs (void); void jobs_cmd (void); char *cd_dialog (void); -void symlink_dialog (const char *existing, const char *new, char **ret_existing, char **ret_new); +void symlink_dialog (const vfs_path_t * existing_vpath, const vfs_path_t * new_vpath, + char **ret_existing, char **ret_new); char *tree_box (const char *current_dir); /*** inline functions ****************************************************************************/ diff --git a/src/filemanager/cmd.c b/src/filemanager/cmd.c index faeb67418..0a7e4f898 100644 --- a/src/filemanager/cmd.c +++ b/src/filemanager/cmd.c @@ -307,18 +307,23 @@ select_unselect_cmd (const char *title, const char *history_name, gboolean do_se /* --------------------------------------------------------------------------------------------- */ static int -compare_files (char *name1, char *name2, off_t size) +compare_files (const vfs_path_t * vpath1, const vfs_path_t * vpath2, off_t size) { int file1, file2; + char *name; int result = -1; /* Different by default */ if (size == 0) return 0; - file1 = open (name1, O_RDONLY); + name = vfs_path_to_str (vpath1); + file1 = open (name, O_RDONLY); + g_free (name); if (file1 >= 0) { - file2 = open (name2, O_RDONLY); + name = vfs_path_to_str (vpath2); + file2 = open (name, O_RDONLY); + g_free (name); if (file2 >= 0) { #ifdef HAVE_MMAP @@ -362,7 +367,6 @@ static void compare_dir (WPanel * panel, WPanel * other, enum CompareMode mode) { int i, j; - char *src_name, *dst_name; /* No marks by default */ panel->marked = 0; @@ -424,12 +428,16 @@ compare_dir (WPanel * panel, WPanel * other, enum CompareMode mode) } /* Thorough compare on, do byte-by-byte comparison */ - src_name = concat_dir_and_file (panel->cwd, source->fname); - dst_name = concat_dir_and_file (other->cwd, target->fname); - if (compare_files (src_name, dst_name, source->st.st_size)) - do_file_mark (panel, i, 1); - g_free (src_name); - g_free (dst_name); + { + vfs_path_t *src_name, *dst_name; + + src_name = vfs_path_append_new (panel->cwd_vpath, source->fname, NULL); + dst_name = vfs_path_append_new (other->cwd_vpath, target->fname, NULL); + if (compare_files (src_name, dst_name, source->st.st_size)) + do_file_mark (panel, i, 1); + vfs_path_free (src_name); + vfs_path_free (dst_name); + } } } /* for (i ...) */ } @@ -456,35 +464,41 @@ do_link (link_type_t link_type, const char *fname) } else { - char *s; - char *d; - vfs_path_t *src_vpath; + vfs_path_t *s, *d; /* suggest the full path for symlink, and either the full or relative path to the file it points to */ - s = concat_dir_and_file (current_panel->cwd, fname); + s = vfs_path_append_new (current_panel->cwd_vpath, fname, NULL); if (get_other_type () == view_listing) - d = concat_dir_and_file (other_panel->cwd, fname); + d = vfs_path_append_new (other_panel->cwd_vpath, fname, NULL); else - d = g_strdup (fname); + d = vfs_path_from_str (fname); if (link_type == LINK_SYMLINK_RELATIVE) - s = diff_two_paths (other_panel->cwd, s); + { + char *s_str; + + s_str = diff_two_paths (other_panel->cwd_vpath, s); + vfs_path_free (s); + s = vfs_path_from_str_flags (s_str, VPF_NO_CANON); + g_free (s_str); + } symlink_dialog (s, d, &dest, &src); - g_free (d); - g_free (s); + vfs_path_free (d); + vfs_path_free (s); if (!dest || !*dest || !src || !*src) goto cleanup; save_cwds_stat (); dest_vpath = vfs_path_from_str_flags (dest, VPF_NO_CANON); - src_vpath = vfs_path_from_str (src); - if (mc_symlink (dest_vpath, src_vpath) == -1) + + s = vfs_path_from_str (src); + if (mc_symlink (dest_vpath, s) == -1) message (D_ERROR, MSG_ERROR, _("symlink: %s"), unix_error_string (errno)); - vfs_path_free (src_vpath); + vfs_path_free (s); } update_panels (UP_OPTIMIZE, UP_KEEPSEL); @@ -923,7 +937,7 @@ rename_cmd_local (void) void mkdir_cmd (void) { - char *dir, *absdir; + char *dir; const char *name = ""; /* If 'on' then automatically fills name with current selected item name */ @@ -939,10 +953,11 @@ mkdir_cmd (void) if (*dir) { + vfs_path_t *absdir; if (dir[0] == '/' || dir[0] == '~') - absdir = g_strdup (dir); + absdir = vfs_path_from_str (dir); else - absdir = concat_dir_and_file (current_panel->cwd, dir); + absdir = vfs_path_append_new (current_panel->cwd_vpath, dir, NULL); save_cwds_stat (); if (my_mkdir (absdir, 0777) == 0) @@ -955,7 +970,7 @@ mkdir_cmd (void) { message (D_ERROR, MSG_ERROR, "%s", unix_error_string (errno)); } - g_free (absdir); + vfs_path_free (absdir); } g_free (dir); } @@ -1019,9 +1034,19 @@ reread_cmd (void) { panel_update_flags_t flag = UP_ONLY_CURRENT; - if (get_current_type () == view_listing && get_other_type () == view_listing - && strcmp (current_panel->cwd, other_panel->cwd) == 0) - flag = UP_OPTIMIZE; + if (get_current_type () == view_listing && get_other_type () == view_listing) + { + char *c_cwd, *o_cwd; + + c_cwd = vfs_path_to_str (current_panel->cwd_vpath); + o_cwd = vfs_path_to_str (other_panel->cwd_vpath); + + if (strcmp (c_cwd, o_cwd) == 0) + flag = UP_OPTIMIZE; + + g_free (c_cwd); + g_free (o_cwd); + } update_panels (UP_RELOAD | flag, UP_KEEPSEL); repaint_screen (); @@ -1360,7 +1385,7 @@ edit_symlink_cmd (void) if (mc_symlink (dest_vpath, p_vpath) == -1) message (D_ERROR, MSG_ERROR, _("edit symlink: %s"), unix_error_string (errno)); - vfs_path_free(dest_vpath); + vfs_path_free (dest_vpath); } update_panels (UP_OPTIMIZE, UP_KEEPSEL); repaint_screen (); @@ -1562,16 +1587,18 @@ single_dirsize_cmd (void) size_t marked = 0; uintmax_t total = 0; ComputeDirSizeUI *ui; + vfs_path_t *p; ui = compute_dir_size_create_ui (); + p = vfs_path_from_str_flags (entry->fname, VPF_NO_CANON); - if (compute_dir_size (entry->fname, ui, compute_dir_size_update_ui, - &marked, &total, TRUE) == FILE_CONT) + if (compute_dir_size (p, ui, compute_dir_size_update_ui, &marked, &total, TRUE) == FILE_CONT) { entry->st.st_size = (off_t) total; entry->f.dir_size_computed = 1; } + vfs_path_free (p); compute_dir_size_destroy_ui (ui); } @@ -1602,12 +1629,17 @@ dirsizes_cmd (void) && ((panel->dirs_marked && panel->dir.list[i].f.marked) || !panel->dirs_marked) && strcmp (panel->dir.list[i].fname, "..") != 0) { + vfs_path_t *p; size_t marked = 0; uintmax_t total = 0; + gboolean ok; - if (compute_dir_size (panel->dir.list[i].fname, - ui, compute_dir_size_update_ui, &marked, &total, - TRUE) != FILE_CONT) + p = vfs_path_from_str_flags (panel->dir.list[i].fname, VPF_NO_CANON); + ok = compute_dir_size (p, ui, compute_dir_size_update_ui, &marked, &total, + TRUE) != FILE_CONT; + vfs_path_free (p); + + if (ok) break; panel->dir.list[i].st.st_size = (off_t) total; diff --git a/src/filemanager/command.c b/src/filemanager/command.c index eed9affe1..89dddfe4f 100644 --- a/src/filemanager/command.c +++ b/src/filemanager/command.c @@ -384,14 +384,20 @@ do_cd_command (char *orig_cmd) } else if (strcmp (cmd + operand_pos, "..") == 0) { - char *dir = current_panel->cwd; - len = strlen (dir); - while (len && dir[--len] != PATH_SEP); - dir[len] = 0; - if (len) - sync_tree (dir); - else - sync_tree (PATH_SEP_STR); + char *str_path; + + if (vfs_path_elements_count (current_panel->cwd_vpath) != 1 || + strlen (vfs_path_get_by_index (current_panel->cwd_vpath, 0)->path) > 1) + { + vfs_path_t *tmp_vpath = current_panel->cwd_vpath; + + current_panel->cwd_vpath = + vfs_path_vtokens_get (tmp_vpath, 0, vfs_path_tokens_count (tmp_vpath) - 1); + vfs_path_free (tmp_vpath); + } + str_path = vfs_path_to_str (current_panel->cwd_vpath); + sync_tree (str_path); + g_free (str_path); } else if (cmd[operand_pos] == PATH_SEP) { @@ -399,11 +405,14 @@ do_cd_command (char *orig_cmd) } else { - char *old = current_panel->cwd; - char *new; - new = concat_dir_and_file (old, cmd + operand_pos); - sync_tree (new); - g_free (new); + char *str_path; + vfs_path_t *new_vpath; + + new_vpath = vfs_path_append_new (current_panel->cwd_vpath, cmd + operand_pos, NULL); + str_path = vfs_path_to_str (new_vpath); + vfs_path_free (new_vpath); + sync_tree (str_path); + g_free (str_path); } } else diff --git a/src/filemanager/file.c b/src/filemanager/file.c index c2bf618c8..42d427243 100644 --- a/src/filemanager/file.c +++ b/src/filemanager/file.c @@ -411,7 +411,8 @@ make_symlink (FileOpContext * ctx, const char *src_path, const char *dst_path) if (ctx->stable_symlinks && !g_path_is_absolute (link_target)) { - char *p, *q, *s; + char *p, *s; + vfs_path_t *q; const char *r = strrchr (src_path, PATH_SEP); @@ -419,18 +420,23 @@ make_symlink (FileOpContext * ctx, const char *src_path, const char *dst_path) { p = g_strndup (src_path, r - src_path + 1); if (g_path_is_absolute (dst_path)) - q = g_strdup (dst_path); + q = vfs_path_from_str_flags (dst_path, VPF_NO_CANON); else - q = g_strconcat (p, dst_path, (char *) NULL); - s = strrchr (q, PATH_SEP); - if (s) + q = vfs_path_build_filename (p, dst_path, (char *) NULL); + + if (vfs_path_tokens_count (q) > 1) { - s[1] = 0; + vfs_path_t *tmp_vpath1, *tmp_vpath2; + + tmp_vpath1 = vfs_path_vtokens_get (q, -1, 1); s = g_strconcat (p, link_target, (char *) NULL); g_free (p); g_strlcpy (link_target, s, sizeof (link_target)); g_free (s); - s = diff_two_paths (q, link_target); + tmp_vpath2 = vfs_path_from_str (link_target); + s = diff_two_paths (tmp_vpath1, tmp_vpath2); + vfs_path_free (tmp_vpath1); + vfs_path_free (tmp_vpath2); if (s) { g_strlcpy (link_target, s, sizeof (link_target)); @@ -439,7 +445,7 @@ make_symlink (FileOpContext * ctx, const char *src_path, const char *dst_path) } else g_free (p); - g_free (q); + vfs_path_free (q); } } link_target_vpath = vfs_path_from_str_flags (link_target, VPF_NO_CANON); @@ -476,7 +482,7 @@ make_symlink (FileOpContext * ctx, const char *src_path, const char *dst_path) goto retry_dst_symlink; } - ret: + ret: vfs_path_free (src_vpath); vfs_path_free (dst_vpath); vfs_path_free (link_target_vpath); @@ -1214,16 +1220,15 @@ panel_compute_totals (const WPanel * panel, const void *ui, if (S_ISDIR (s->st_mode)) { - char *dir_name; + vfs_path_t *p; size_t subdir_count = 0; uintmax_t subdir_bytes = 0; FileProgressStatus status; - dir_name = concat_dir_and_file (panel->cwd, panel->dir.list[i].fname); - - status = compute_dir_size (dir_name, ui, cback, - &subdir_count, &subdir_bytes, compute_symlinks); - g_free (dir_name); + p = vfs_path_append_new (panel->cwd_vpath, panel->dir.list[i].fname, NULL); + status = + compute_dir_size (p, ui, cback, &subdir_count, &subdir_bytes, compute_symlinks); + vfs_path_free (p); if (status != FILE_CONT) return FILE_ABORT; @@ -1256,14 +1261,20 @@ panel_operate_init_totals (FileOperation operation, ui = compute_dir_size_create_ui (); - if (source != NULL) - status = compute_dir_size (source, ui, compute_dir_size_update_ui, - &ctx->progress_count, &ctx->progress_bytes, - ctx->follow_links); - else + if (source == NULL) status = panel_compute_totals (panel, ui, compute_dir_size_update_ui, &ctx->progress_count, &ctx->progress_bytes, ctx->follow_links); + else + { + vfs_path_t *p; + + p = vfs_path_from_str (source); + status = compute_dir_size (p, ui, compute_dir_size_update_ui, + &ctx->progress_count, &ctx->progress_bytes, + ctx->follow_links); + vfs_path_free (p); + } compute_dir_size_destroy_ui (ui); @@ -2046,7 +2057,7 @@ copy_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con } } dest_dir_vpath = vfs_path_from_str (dest_dir); - while (my_mkdir (dest_dir, (cbuf.st_mode & ctx->umask_kill) | S_IRWXU)) + while (my_mkdir (dest_dir_vpath, (cbuf.st_mode & ctx->umask_kill) | S_IRWXU) != 0) { if (ctx->skip_all) return_status = FILE_SKIPALL; @@ -2434,16 +2445,19 @@ compute_dir_size_destroy_ui (ComputeDirSizeUI * ui) /* --------------------------------------------------------------------------------------------- */ FileProgressStatus -compute_dir_size_update_ui (const void *ui, const char *dirname) +compute_dir_size_update_ui (const void *ui, const vfs_path_t * dirname_vpath) { const ComputeDirSizeUI *this = (const ComputeDirSizeUI *) ui; int c; Gpm_Event event; + char *dirname; if (ui == NULL) return FILE_CONT; + dirname = vfs_path_to_str (dirname_vpath); label_set_text (this->dirname, str_trunc (dirname, this->dlg->cols - 6)); + g_free (dirname); event.x = -1; /* Don't show the GPM cursor */ c = tty_get_event (&event, FALSE, FALSE); @@ -2474,7 +2488,7 @@ compute_dir_size_update_ui (const void *ui, const char *dirname) */ FileProgressStatus -compute_dir_size (const char *dirname, const void *ui, +compute_dir_size (const vfs_path_t * dirname_vpath, const void *ui, compute_dir_size_callback cback, size_t * ret_marked, uintmax_t * ret_total, gboolean compute_symlinks) { @@ -2483,36 +2497,32 @@ compute_dir_size (const char *dirname, const void *ui, DIR *dir; struct dirent *dirent; FileProgressStatus ret = FILE_CONT; - vfs_path_t *vpath; - - vpath = vfs_path_from_str (dirname); if (!compute_symlinks) { - res = mc_lstat (vpath, &s); + res = mc_lstat (dirname_vpath, &s); if (res != 0) - goto ret; + return ret; /* don't scan symlink to directory */ if (S_ISLNK (s.st_mode)) { (*ret_marked)++; *ret_total += (uintmax_t) s.st_size; - goto ret; + return ret; } } - dir = mc_opendir (vpath); + dir = mc_opendir (dirname_vpath); if (dir == NULL) - goto ret; + return ret; while ((dirent = mc_readdir (dir)) != NULL) { - char *fullname; vfs_path_t *tmp_vpath; - ret = (cback != NULL) ? cback (ui, dirname) : FILE_CONT; + ret = (cback != NULL) ? cback (ui, dirname_vpath) : FILE_CONT; if (ret != FILE_CONT) break; @@ -2522,49 +2532,38 @@ compute_dir_size (const char *dirname, const void *ui, if (strcmp (dirent->d_name, "..") == 0) continue; - fullname = concat_dir_and_file (dirname, dirent->d_name); - tmp_vpath = vfs_path_from_str (fullname); + tmp_vpath = vfs_path_append_new (dirname_vpath, dirent->d_name, NULL); res = mc_lstat (tmp_vpath, &s); - - if (res != 0) + if (res == 0) { - g_free (fullname); - vfs_path_free (tmp_vpath); - continue; - } - - if (S_ISDIR (s.st_mode)) - { - size_t subdir_count = 0; - uintmax_t subdir_bytes = 0; - - ret = - compute_dir_size (fullname, ui, cback, &subdir_count, &subdir_bytes, - compute_symlinks); - - if (ret != FILE_CONT) + if (S_ISDIR (s.st_mode)) { - g_free (fullname); - vfs_path_free (tmp_vpath); - break; + size_t subdir_count = 0; + uintmax_t subdir_bytes = 0; + + ret = + compute_dir_size (tmp_vpath, ui, cback, &subdir_count, &subdir_bytes, + compute_symlinks); + + if (ret != FILE_CONT) + { + vfs_path_free (tmp_vpath); + break; + } + + *ret_marked += subdir_count; + *ret_total += subdir_bytes; + } + else + { + (*ret_marked)++; + *ret_total += (uintmax_t) s.st_size; } - - *ret_marked += subdir_count; - *ret_total += subdir_bytes; } - else - { - (*ret_marked)++; - *ret_total += (uintmax_t) s.st_size; - } - - g_free (fullname); vfs_path_free (tmp_vpath); } mc_closedir (dir); - ret: - vfs_path_free (vpath); return ret; } @@ -2591,7 +2590,8 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl char *source = NULL; #ifdef WITH_FULL_PATHS - char *source_with_path = NULL; + vfs_path_t *source_with_vpath = NULL; + char *source_with_path_str = NULL; #else #define source_with_path source #endif /* !WITH_FULL_PATHS */ @@ -2664,34 +2664,34 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl /* Show confirmation dialog */ if (operation != OP_DELETE) { - char *dest_dir; - char *dest_dir_; + char *tmp_dest_dir, *dest_dir; char *format; /* Forced single operations default to the original name */ if (force_single) - dest_dir = source; + tmp_dest_dir = g_strdup (source); else if (get_other_type () == view_listing) - dest_dir = other_panel->cwd; + tmp_dest_dir = vfs_path_to_str (other_panel->cwd_vpath); else - dest_dir = panel->cwd; + tmp_dest_dir = vfs_path_to_str (panel->cwd_vpath); /* * Add trailing backslash only when do non-local ops. * It saves user from occasional file renames (when destination * dir is deleted) */ - if (!force_single && dest_dir[0] != '\0' && dest_dir[strlen (dest_dir) - 1] != PATH_SEP) + if (!force_single && tmp_dest_dir[0] != '\0' + && tmp_dest_dir[strlen (tmp_dest_dir) - 1] != PATH_SEP) { /* add trailing separator */ - dest_dir_ = g_strconcat (dest_dir, PATH_SEP_STR, (char *) NULL); + dest_dir = g_strconcat (tmp_dest_dir, PATH_SEP_STR, (char *) NULL); + g_free (tmp_dest_dir); } else { /* just copy */ - dest_dir_ = g_strdup (dest_dir); + dest_dir = tmp_dest_dir; } - - if (dest_dir_ == NULL) + if (dest_dir == NULL) { ret_val = FALSE; goto ret_fast; @@ -2702,10 +2702,10 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl dest = file_mask_dialog (ctx, operation, source != NULL, format, source != NULL ? (void *) source - : (void *) &panel->marked, dest_dir_, &do_bg); + : (void *) &panel->marked, dest_dir, &do_bg); g_free (format); - g_free (dest_dir_); + g_free (dest_dir); if (dest == NULL || dest[0] == '\0') { @@ -2775,17 +2775,18 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl if (do_bg) { int v; + char *cwd_str; - v = do_background (ctx, g_strconcat (op_names[operation], ": ", panel->cwd, (char *) NULL)); + cwd_str = vfs_path_to_str (panel->cwd_vpath); + v = do_background (ctx, g_strconcat (op_names[operation], ": ", cwd_str, (char *) NULL)); + g_free (cwd_str); if (v == -1) message (D_ERROR, MSG_ERROR, _("Sorry, I could not put the job in background")); /* If we are the parent */ if (v == 1) { - tmp_vpath = vfs_path_from_str (panel->cwd); - mc_setctl (tmp_vpath, VFS_SETCTL_FORGET, NULL); - vfs_path_free (tmp_vpath); + mc_setctl (panel->cwd_vpath, VFS_SETCTL_FORGET, NULL); mc_setctl (dest_vpath, VFS_SETCTL_FORGET, NULL); vfs_path_free (dest_vpath); @@ -2803,10 +2804,9 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl if ((dest != NULL) && (mc_setctl (dest_vpath, VFS_SETCTL_STALE_DATA, (void *) 1))) save_dest = g_strdup (dest); - tmp_vpath = vfs_path_from_str (panel->cwd); - if ((panel->cwd[0] != '\0') && (mc_setctl (tmp_vpath, VFS_SETCTL_STALE_DATA, (void *) 1))) - save_cwd = g_strdup (panel->cwd); - vfs_path_free (tmp_vpath); + if ((vfs_path_tokens_count (panel->cwd_vpath) != 0) + && (mc_setctl (panel->cwd_vpath, VFS_SETCTL_STALE_DATA, (void *) 1))) + save_cwd = vfs_path_to_str (panel->cwd_vpath); /* Now, let's do the job */ @@ -2834,23 +2834,23 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl /* The source and src_stat variables have been initialized before */ #ifdef WITH_FULL_PATHS if (g_path_is_absolute (source)) - source_with_path = g_strdup (source); + source_with_vpath = vfs_path_from_str (source); else - source_with_path = mc_build_filename (panel->cwd, source, (char *) NULL); + source_with_vpath = vfs_path_append_new (panel->cwd_vpath, source, (char *) NULL); + source_with_path_str = vfs_path_to_str (source_with_vpath); #endif /* WITH_FULL_PATHS */ - - if (panel_operate_init_totals (operation, panel, source_with_path, ctx) == FILE_CONT) + if (panel_operate_init_totals (operation, panel, source_with_path_str, ctx) == FILE_CONT) { if (operation == OP_DELETE) { if (S_ISDIR (src_stat.st_mode)) - value = erase_dir (tctx, ctx, source_with_path); + value = erase_dir (tctx, ctx, source_with_path_str); else - value = erase_file (tctx, ctx, source_with_path); + value = erase_file (tctx, ctx, source_with_path_str); } else { - temp = transform_source (ctx, source_with_path); + temp = transform_source (ctx, source_with_path_str); if (temp == NULL) value = transform_error; else @@ -2870,24 +2870,20 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl { case OP_COPY: /* we use file_mask_op_follow_links only with OP_COPY */ - { - vfs_path_t *vpath = vfs_path_from_str (source_with_path); - ctx->stat_func (vpath, &src_stat); - vfs_path_free (vpath); - } + ctx->stat_func (source_with_vpath, &src_stat); if (S_ISDIR (src_stat.st_mode)) - value = copy_dir_dir (tctx, ctx, source_with_path, dest, + value = copy_dir_dir (tctx, ctx, source_with_path_str, dest, TRUE, FALSE, FALSE, NULL); else - value = copy_file_file (tctx, ctx, source_with_path, dest); + value = copy_file_file (tctx, ctx, source_with_path_str, dest); break; case OP_MOVE: if (S_ISDIR (src_stat.st_mode)) - value = move_dir_dir (tctx, ctx, source_with_path, dest); + value = move_dir_dir (tctx, ctx, source_with_path_str, dest); else - value = move_file_file (tctx, ctx, source_with_path, dest); + value = move_file_file (tctx, ctx, source_with_path_str, dest); break; default: @@ -2933,23 +2929,26 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl src_stat = panel->dir.list[i].st; #ifdef WITH_FULL_PATHS - g_free (source_with_path); + g_free (source_with_path_str); + vfs_path_free (source_with_vpath); if (g_path_is_absolute (source)) - source_with_path = g_strdup (source); + source_with_vpath = vfs_path_from_str (source); else - source_with_path = mc_build_filename (panel->cwd, source, (char *) NULL); + source_with_vpath = + vfs_path_append_new (panel->cwd_vpath, source, (char *) NULL); + source_with_path_str = vfs_path_to_str (source_with_vpath); #endif /* WITH_FULL_PATHS */ if (operation == OP_DELETE) { if (S_ISDIR (src_stat.st_mode)) - value = erase_dir (tctx, ctx, source_with_path); + value = erase_dir (tctx, ctx, source_with_path_str); else - value = erase_file (tctx, ctx, source_with_path); + value = erase_file (tctx, ctx, source_with_path_str); } else { - temp = transform_source (ctx, source_with_path); + temp = transform_source (ctx, source_with_path_str); if (temp == NULL) value = transform_error; @@ -2961,8 +2960,8 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl temp2 = concat_dir_and_file (repl_dest, temp); g_free (temp); g_free (repl_dest); - temp3 = source_with_path; - source_with_path = strutils_shell_unescape (source_with_path); + temp3 = source_with_path_str; + source_with_path_str = strutils_shell_unescape (source_with_path_str); g_free (temp3); temp3 = temp2; temp2 = strutils_shell_unescape (temp2); @@ -2975,23 +2974,23 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl { vfs_path_t *vpath; - vpath = vfs_path_from_str (source_with_path); + vpath = vfs_path_from_str (source_with_path_str); ctx->stat_func (vpath, &src_stat); vfs_path_free (vpath); } if (S_ISDIR (src_stat.st_mode)) - value = copy_dir_dir (tctx, ctx, source_with_path, temp2, + value = copy_dir_dir (tctx, ctx, source_with_path_str, temp2, TRUE, FALSE, FALSE, NULL); else - value = copy_file_file (tctx, ctx, source_with_path, temp2); + value = copy_file_file (tctx, ctx, source_with_path_str, temp2); free_linklist (&dest_dirs); break; case OP_MOVE: if (S_ISDIR (src_stat.st_mode)) - value = move_dir_dir (tctx, ctx, source_with_path, temp2); + value = move_dir_dir (tctx, ctx, source_with_path_str, temp2); else - value = move_file_file (tctx, ctx, source_with_path, temp2); + value = move_file_file (tctx, ctx, source_with_path_str, temp2); break; default: @@ -3047,7 +3046,8 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl free_linklist (&linklist); free_linklist (&dest_dirs); #ifdef WITH_FULL_PATHS - g_free (source_with_path); + g_free (source_with_path_str); + vfs_path_free (source_with_vpath); #endif /* WITH_FULL_PATHS */ g_free (dest); vfs_path_free (dest_vpath); diff --git a/src/filemanager/file.h b/src/filemanager/file.h index a6cc6567b..4a1d63b7a 100644 --- a/src/filemanager/file.h +++ b/src/filemanager/file.h @@ -5,7 +5,7 @@ #ifndef MC__FILE_H #define MC__FILE_H -#include /* off_t, uintmax_t */ +#include /* off_t, uintmax_t */ #include "lib/global.h" #include "lib/widget.h" @@ -16,7 +16,8 @@ /* Compute directory size */ /* callback to update status dialog */ -typedef FileProgressStatus (*compute_dir_size_callback) (const void *ui, const char *dirname); +typedef FileProgressStatus (*compute_dir_size_callback) (const void *ui, + const vfs_path_t * dirname_vpath); /*** enums ***************************************************************************************/ @@ -53,14 +54,14 @@ gboolean panel_operate (void *source_panel, FileOperation op, gboolean force_sin FileProgressStatus file_error (const char *format, const char *file); /* return value is FILE_CONT or FILE_ABORT */ -FileProgressStatus compute_dir_size (const char *dirname, const void *ui, +FileProgressStatus compute_dir_size (const vfs_path_t * dirname_vpath, const void *ui, compute_dir_size_callback cback, - size_t * ret_marked, uintmax_t *ret_total, + size_t * ret_marked, uintmax_t * ret_total, gboolean compute_symlinks); ComputeDirSizeUI *compute_dir_size_create_ui (void); void compute_dir_size_destroy_ui (ComputeDirSizeUI * ui); -FileProgressStatus compute_dir_size_update_ui (const void *ui, const char *dirname); +FileProgressStatus compute_dir_size_update_ui (const void *ui, const vfs_path_t * dirname_vpath); /*** inline functions ****************************************************************************/ #endif /* MC__FILE_H */ diff --git a/src/filemanager/filegui.c b/src/filemanager/filegui.c index d424f0fa5..5680ad884 100644 --- a/src/filemanager/filegui.c +++ b/src/filemanager/filegui.c @@ -810,15 +810,17 @@ file_progress_show_source (FileOpContext * ctx, const char *s) { #ifdef WITH_FULL_PATHS size_t i; + char *cwd_str; - i = strlen (current_panel->cwd); + cwd_str = vfs_path_to_str (current_panel->cwd_vpath); + i = strlen (cwd_str); /* We remove the full path we have added before */ - if (strncmp (s, current_panel->cwd, i) == 0) + if (strncmp (s, cwd_str, i) == 0) if (s[i] == PATH_SEP) s += i + 1; + g_free (cwd_str); #endif /* WITH_FULL_PATHS */ - label_set_text (ui->file_label[0], _("Source")); label_set_text (ui->file_string[0], truncFileString (ui, s)); } diff --git a/src/filemanager/filenot.c b/src/filemanager/filenot.c index 69422a6b2..c2e03faf0 100644 --- a/src/filemanager/filenot.c +++ b/src/filemanager/filenot.c @@ -54,15 +54,16 @@ /*** file scope functions ************************************************************************/ /* --------------------------------------------------------------------------------------------- */ -static char * -get_absolute_name (const char *file) +static vfs_path_t * +get_absolute_name (const vfs_path_t * vpath) { - char dir[MC_MAXPATHLEN]; + if (vpath == NULL) + return NULL; - if (file[0] == PATH_SEP) - return g_strdup (file); - mc_get_current_wd (dir, MC_MAXPATHLEN); - return concat_dir_and_file (dir, file); + if (*(vfs_path_get_by_index (vpath, 0)->path) == PATH_SEP) + return vfs_path_clone (vpath); + + return vfs_path_append_vpath_new (vfs_get_raw_current_dir (), vpath); } /* --------------------------------------------------------------------------------------------- */ @@ -126,13 +127,10 @@ my_mkdir_rec (char *s, mode_t mode) /* --------------------------------------------------------------------------------------------- */ int -my_mkdir (const char *s, mode_t mode) +my_mkdir (const vfs_path_t * s_vpath, mode_t mode) { int result; - char *my_s; - vfs_path_t *s_vpath; - s_vpath = vfs_path_from_str (s); result = mc_mkdir (s_vpath, mode); if (result != 0) @@ -145,15 +143,14 @@ my_mkdir (const char *s, mode_t mode) } if (result == 0) { - my_s = get_absolute_name (s); + vfs_path_t *my_s; + my_s = get_absolute_name (s_vpath); #ifdef FIXME tree_add_entry (tree, my_s); #endif - - g_free (my_s); + vfs_path_free (my_s); } - vfs_path_free (s_vpath); return result; } @@ -163,24 +160,23 @@ int my_rmdir (const char *s) { int result; - char *my_s; vfs_path_t *vpath; #ifdef FIXME WTree *tree = 0; #endif - vpath = vfs_path_from_str (s); + vpath = vfs_path_from_str_flags (s, VPF_NO_CANON); /* FIXME: Should receive a Wtree! */ result = mc_rmdir (vpath); if (result == 0) { - my_s = get_absolute_name (s); + vfs_path_t *my_s; + my_s = get_absolute_name (vpath); #ifdef FIXME tree_remove_entry (tree, my_s); #endif - - g_free (my_s); + vfs_path_free (my_s); } vfs_path_free (vpath); return result; diff --git a/src/filemanager/find.c b/src/filemanager/find.c index c3816df73..728d4cd72 100644 --- a/src/filemanager/find.c +++ b/src/filemanager/find.c @@ -672,16 +672,21 @@ find_parameters (char **start_dir, ssize_t * start_dir_len, case B_TREE: { - const char *temp_dir = in_start->buffer; + char *temp_dir; + temp_dir = in_start->buffer; if ((temp_dir[0] == '\0') || ((temp_dir[0] == '.') && (temp_dir[1] == '\0'))) - temp_dir = current_panel->cwd; + temp_dir = vfs_path_to_str (current_panel->cwd_vpath); + else + temp_dir = g_strdup (temp_dir); if (in_start_dir != INPUT_LAST_TEXT) g_free (in_start_dir); in_start_dir = tree_box (temp_dir); if (in_start_dir == NULL) - in_start_dir = g_strdup (temp_dir); + in_start_dir = temp_dir; + else + g_free (temp_dir); input_assign_text (in_start, in_start_dir); @@ -723,10 +728,10 @@ find_parameters (char **start_dir, ssize_t * start_dir_len, if (s[0] == '.' && s[1] == '\0') { - *start_dir = g_strdup (current_panel->cwd); - /* FIXME: is current_panel->cwd canonicalized? */ + *start_dir = vfs_path_to_str (current_panel->cwd_vpath); + /* FIXME: is current_panel->cwd_vpath canonicalized? */ /* relative paths will be used in panelization */ - *start_dir_len = (ssize_t) strlen (current_panel->cwd); + *start_dir_len = (ssize_t) strlen (*start_dir); g_free (s); } else if (g_path_is_absolute (s)) @@ -737,8 +742,12 @@ find_parameters (char **start_dir, ssize_t * start_dir_len, else { /* relative paths will be used in panelization */ - *start_dir = mc_build_filename (current_panel->cwd, s, (char *) NULL); - *start_dir_len = (ssize_t) strlen (current_panel->cwd); + char *cwd_str; + + cwd_str = vfs_path_to_str (current_panel->cwd_vpath); + *start_dir = mc_build_filename (cwd_str, s, (char *) NULL); + *start_dir_len = (ssize_t) strlen (cwd_str); + g_free (cwd_str); g_free (s); } @@ -1691,8 +1700,8 @@ do_find (const char *start_dir, ssize_t start_dir_len, const char *ignore_dirs, if (start_dir_len < 0) { int ret; - - strcpy (current_panel->cwd, PATH_SEP_STR); + vfs_path_free (current_panel->cwd_vpath); + current_panel->cwd_vpath = vfs_path_from_str (PATH_SEP_STR); ret = chdir (PATH_SEP_STR); } panelize_save_panel (current_panel); diff --git a/src/filemanager/hotlist.c b/src/filemanager/hotlist.c index 008d04c14..4535faf58 100644 --- a/src/filemanager/hotlist.c +++ b/src/filemanager/hotlist.c @@ -1092,7 +1092,7 @@ add_new_entry_cmd (void) int ret; /* Take current directory as default value for input fields */ - to_free = title = url = strip_password (g_strdup (current_panel->cwd), 1); + to_free = title = url = strip_password (vfs_path_to_str (current_panel->cwd_vpath), 1); ret = add_new_entry_input (_("New hotlist entry"), _("Directory label:"), _("Directory path:"), "[Hotlist]", &title, &url); @@ -1695,13 +1695,18 @@ void add2hotlist_cmd (void) { char *lc_prompt, *label; - const char *cp = _("Label for \"%s\":"); - int l = str_term_width1 (cp); - char *label_string = g_strdup (current_panel->cwd); + const char *cp = N_("Label for \"%s\":"); + int l; + char *label_string; +#ifdef ENABLE_NLS + cp = _(cp); +#endif + + l = str_term_width1 (cp); + label_string = vfs_path_to_str (current_panel->cwd_vpath); + lc_prompt = g_strdup_printf (cp, path_trunc (label_string, COLS - 2 * UX - (l + 8))); strip_password (label_string, 1); - - lc_prompt = g_strdup_printf (cp, path_trunc (current_panel->cwd, COLS - 2 * UX - (l + 8))); label = input_dialog (_("Add to hotlist"), lc_prompt, MC_HISTORY_HOTLIST_ADD, label_string); g_free (lc_prompt); diff --git a/src/filemanager/info.c b/src/filemanager/info.c index ad0283bec..a9899f827 100644 --- a/src/filemanager/info.c +++ b/src/filemanager/info.c @@ -119,7 +119,14 @@ info_show_info (struct WInfo *info) if (get_current_type () != view_listing) return; - my_statfs (&myfs_stats, current_panel->cwd); + { + char *cwd_str; + + cwd_str = vfs_path_to_str (current_panel->cwd_vpath); + my_statfs (&myfs_stats, cwd_str); + g_free (cwd_str); + } + st = current_panel->dir.list[current_panel->selected].st; /* Print only lines which fit */ diff --git a/src/filemanager/layout.c b/src/filemanager/layout.c index f49f046a4..caa87c4ff 100644 --- a/src/filemanager/layout.c +++ b/src/filemanager/layout.c @@ -43,7 +43,7 @@ #include "lib/tty/key.h" #include "lib/tty/mouse.h" #include "lib/mcconfig.h" -#include "lib/vfs/vfs.h" /* For mc_get_current_wd() */ +#include "lib/vfs/vfs.h" /* For _vfs_get_cwd () */ #include "lib/strutil.h" #include "lib/widget.h" #include "lib/event.h" @@ -967,10 +967,11 @@ set_display_type (int num, panel_view_mode_t type) /* when it's first creation (for example view_info) */ if (old_widget == NULL && type != view_listing) { - char panel_dir[MC_MAXPATHLEN]; + char *panel_dir; - mc_get_current_wd (panel_dir, sizeof (panel_dir)); + panel_dir = _vfs_get_cwd (); panels[num].last_saved_dir = g_strdup (panel_dir); + g_free (panel_dir); } switch (type) @@ -1088,8 +1089,8 @@ swap_panels (void) /* Change content and related stuff */ panelswap (dir); panelswap (active); - panelswapstr (cwd); - panelswapstr (lwd); + panelswap (cwd_vpath); + panelswap (lwd_vpath); panelswap (count); panelswap (marked); panelswap (dirs_marked); @@ -1257,11 +1258,10 @@ save_panel_dir (int idx) if ((type == view_listing) && (widget != NULL)) { WPanel *w = (WPanel *) widget; - char *widget_work_dir = w->cwd; g_free (panels[idx].last_saved_dir); /* last path no needed */ /* Because path can be nonlocal */ - panels[idx].last_saved_dir = g_strdup (widget_work_dir); + panels[idx].last_saved_dir = vfs_path_to_str (w->cwd_vpath); } } @@ -1269,7 +1269,7 @@ save_panel_dir (int idx) /** Return working dir, if it's view_listing - cwd, but for other types - last_saved_dir */ -const char * +char * get_panel_dir_for (const WPanel * widget) { int i; @@ -1279,12 +1279,12 @@ get_panel_dir_for (const WPanel * widget) break; if (i >= MAX_VIEWS) - return "."; + return g_strdup ("."); if (get_display_type (i) == view_listing) - return ((WPanel *) get_panel_widget (i))->cwd; + return vfs_path_to_str (((WPanel *) get_panel_widget (i))->cwd_vpath); - return panels[i].last_saved_dir; + return g_strdup (panels[i].last_saved_dir); } /* --------------------------------------------------------------------------------------------- */ diff --git a/src/filemanager/layout.h b/src/filemanager/layout.h index 80e0c80ae..965e91b88 100644 --- a/src/filemanager/layout.h +++ b/src/filemanager/layout.h @@ -73,7 +73,7 @@ struct Widget *get_panel_widget (int idx); struct WPanel *get_other_panel (void); void save_panel_dir (int idx); -const char *get_panel_dir_for (const struct WPanel * widget); +char *get_panel_dir_for (const struct WPanel * widget); void set_hintbar (const char *str); diff --git a/src/filemanager/midnight.c b/src/filemanager/midnight.c index 94e27a40c..b062d2392 100644 --- a/src/filemanager/midnight.c +++ b/src/filemanager/midnight.c @@ -436,7 +436,9 @@ midnight_get_title (const Dlg_head * h, size_t len) (void) h; - path = strip_home_and_password (current_panel->cwd); + p = vfs_path_to_str (current_panel->cwd_vpath); + path = strip_home_and_password (p); + g_free (p); res = gethostname (host, sizeof (host)); if (res != 0) host[0] = '\0'; @@ -478,24 +480,15 @@ check_panel_timestamp (const WPanel * panel, panel_view_mode_t mode, struct vfs_ { if (mode == view_listing) { - vfs_path_t *vpath; vfs_path_element_t *path_element; - vpath = vfs_path_from_str (panel->cwd); - path_element = vfs_path_get_by_index (vpath, -1); + path_element = vfs_path_get_by_index (panel->cwd_vpath, -1); if (path_element->class != vclass) - { - vfs_path_free (vpath); return FALSE; - } - if (vfs_getid (vpath) != id) - { - vfs_path_free (vpath); + if (vfs_getid (panel->cwd_vpath) != id) return FALSE; - } - vfs_path_free (vpath); } return TRUE; } @@ -591,7 +584,7 @@ create_panels (void) int current_index; int other_index; panel_view_mode_t current_mode, other_mode; - char original_dir[BUF_1K] = "\0"; + char *original_dir = NULL; if (boot_current_is_left) { @@ -618,7 +611,7 @@ create_panels (void) * since we may not be able to chdir to the proper * second directory later */ - mc_get_current_wd (original_dir, sizeof (original_dir) - 2); + original_dir = vfs_get_current_dir (); } vpath = vfs_path_from_str (mc_run_param0); mc_chdir (vpath); @@ -636,6 +629,7 @@ create_panels (void) mc_chdir (vpath); vfs_path_free (vpath); } + g_free (original_dir); set_display_type (other_index, other_mode); if (startup_left_mode == view_listing) @@ -675,7 +669,7 @@ put_current_path (void) if (!command_prompt) return; - cwd_path = remove_encoding_from_path (current_panel->cwd); + cwd_path = remove_encoding_from_path (current_panel->cwd_vpath); command_insert (cmdline, cwd_path, FALSE); if (cwd_path[strlen (cwd_path) - 1] != PATH_SEP) @@ -696,7 +690,7 @@ put_other_path (void) if (!command_prompt) return; - cwd_path = remove_encoding_from_path (other_panel->cwd); + cwd_path = remove_encoding_from_path (other_panel->cwd_vpath); command_insert (cmdline, cwd_path, FALSE); if (cwd_path[strlen (cwd_path) - 1] != PATH_SEP) @@ -717,7 +711,7 @@ put_link (WPanel * panel) vfs_path_t *vpath; int i; - vpath = vfs_path_build_filename (panel->cwd, selection (panel)->fname, NULL); + vpath = vfs_path_append_new (panel->cwd_vpath, selection (panel)->fname, NULL); i = mc_readlink (vpath, buffer, MC_MAXPATHLEN - 1); vfs_path_free (vpath); @@ -853,14 +847,15 @@ static void setup_dummy_mc (void) { vfs_path_t *vpath; - char d[MC_MAXPATHLEN]; + char *d; int ret; - mc_get_current_wd (d, MC_MAXPATHLEN); + d = _vfs_get_cwd (); setup_mc (); vpath = vfs_path_from_str (d); ret = mc_chdir (vpath); vfs_path_free (vpath); + g_free (d); } /* --------------------------------------------------------------------------------------------- */ @@ -882,10 +877,22 @@ done_mc (void) g_free (curr_dir); if ((current_panel != NULL) && (get_current_type () == view_listing)) - vfs_stamp_path (current_panel->cwd); + { + char *tmp_path; + + tmp_path = vfs_path_to_str (current_panel->cwd_vpath); + vfs_stamp_path (tmp_path); + g_free (tmp_path); + } if ((other_panel != NULL) && (get_other_type () == view_listing)) - vfs_stamp_path (other_panel->cwd); + { + char *tmp_path; + + tmp_path = vfs_path_to_str (other_panel->cwd_vpath); + vfs_stamp_path (tmp_path); + g_free (tmp_path); + } } /* --------------------------------------------------------------------------------------------- */ @@ -933,8 +940,7 @@ prepend_cwd_on_local (const char *filename) } vfs_path_free (vpath); - d = g_malloc (MC_MAXPATHLEN + strlen (filename) + 2); - mc_get_current_wd (d, MC_MAXPATHLEN); + d = _vfs_get_cwd (); l = strlen (d); d[l++] = PATH_SEP; strcpy (d + l, filename); @@ -1631,17 +1637,9 @@ save_cwds_stat (void) { if (panels_options.fast_reload) { - vfs_path_t *vpath; - - vpath = vfs_path_from_str (current_panel->cwd); - mc_stat (vpath, &(current_panel->dir_stat)); - vfs_path_free (vpath); + mc_stat (current_panel->cwd_vpath, &(current_panel->dir_stat)); if (get_other_type () == view_listing) - { - vpath = vfs_path_from_str (other_panel->cwd); - mc_stat (vpath, &(other_panel->dir_stat)); - vfs_path_free (vpath); - } + mc_stat (other_panel->cwd_vpath, &(other_panel->dir_stat)); } } @@ -1687,9 +1685,9 @@ do_nc (void) { create_panels_and_run_mc (); - /* destroy_dlg destroys even current_panel->cwd, so we have to save a copy :) */ + /* destroy_dlg destroys even current_panel->cwd_vpath, so we have to save a copy :) */ if (mc_args__last_wd_file != NULL && vfs_current_is_local ()) - last_wd_string = g_strdup (current_panel->cwd); + last_wd_string = vfs_path_to_str (current_panel->cwd_vpath); /* don't handle VFS timestamps for dirs opened in panels */ mc_event_destroy (MCEVENT_GROUP_CORE, "vfs_timestamp"); diff --git a/src/filemanager/panel.c b/src/filemanager/panel.c index 0871b01b3..29ac726d4 100644 --- a/src/filemanager/panel.c +++ b/src/filemanager/panel.c @@ -80,7 +80,9 @@ /* The hook list for the select file function */ hook_t *select_file_hook = NULL; +/* *INDENT-OFF* */ panelized_panel_t panelized_panel = { { NULL, 0 }, -1, { '\0' } }; +/* *INDENT-ON* */ static const char *string_file_name (file_entry *, int); static const char *string_file_size (file_entry *, int); @@ -979,7 +981,7 @@ display_mini_info (WPanel * panel) int len; lc_link_vpath = - vfs_path_build_filename (panel->cwd, panel->dir.list[panel->selected].fname, NULL); + vfs_path_append_new (panel->cwd_vpath, panel->dir.list[panel->selected].fname, NULL); len = mc_readlink (lc_link_vpath, link_target, MC_MAXPATHLEN - 1); vfs_path_free (lc_link_vpath); if (len > 0) @@ -1101,29 +1103,28 @@ show_free_space (WPanel * panel) static struct my_statfs myfs_stats; /* Old current working directory for displaying free space */ static char *old_cwd = NULL; - vfs_path_t *vpath = vfs_path_from_str (panel->cwd); + char *tmp_path; /* Don't try to stat non-local fs */ - if (!vfs_file_is_local (vpath) || !free_space) - { - vfs_path_free (vpath); + if (!vfs_file_is_local (panel->cwd_vpath) || !free_space) return; - } - vfs_path_free (vpath); - if (old_cwd == NULL || strcmp (old_cwd, panel->cwd) != 0) + tmp_path = vfs_path_to_str (panel->cwd_vpath); + if (old_cwd == NULL || strcmp (old_cwd, tmp_path) != 0) { char rpath[PATH_MAX]; init_my_statfs (); g_free (old_cwd); - old_cwd = g_strdup (panel->cwd); + old_cwd = tmp_path; + tmp_path = NULL; - if (mc_realpath (panel->cwd, rpath) == NULL) + if (mc_realpath (old_cwd, rpath) == NULL) return; my_statfs (&myfs_stats, rpath); } + g_free (tmp_path); if (myfs_stats.avail != 0 || myfs_stats.total != 0) { @@ -1180,9 +1181,15 @@ show_dir (WPanel * panel) if (panel->is_panelized) tty_printf (" %s ", _("Panelize")); else + { + char *tmp_path; + + tmp_path = vfs_path_to_str (panel->cwd_vpath); tty_printf (" %s ", - str_term_trim (strip_home_and_password (panel->cwd), + str_term_trim (strip_home_and_password (tmp_path), min (max (panel->widget.cols - 12, 0), panel->widget.cols))); + g_free (tmp_path); + } if (!panels_options.show_mini_info) { @@ -1297,12 +1304,16 @@ panel_load_history (const gchar * event_group_name, const gchar * event_name, if (ev->receiver == NULL || ev->receiver == (Widget *) p) { + char *tmp_path; + + tmp_path = vfs_path_to_str (p->cwd_vpath); if (ev->cfg != NULL) p->dir_history = history_load (ev->cfg, p->hist_name); else p->dir_history = history_get (p->hist_name); - directory_history_add (p, p->cwd); + directory_history_add (p, tmp_path); + g_free (tmp_path); } return TRUE; @@ -1364,8 +1375,12 @@ panel_destroy (WPanel * p) g_free (p->user_format); for (i = 0; i < LIST_TYPES; i++) g_free (p->user_status_format[i]); + g_free (p->dir.list); g_free (p->panel_name); + + vfs_path_free (p->lwd_vpath); + vfs_path_free (p->cwd_vpath); } /* --------------------------------------------------------------------------------------------- */ @@ -2416,7 +2431,13 @@ do_enter_on_file_entry (file_entry * fe) return 1; /* Check if the file is executable */ - full_name = concat_dir_and_file (current_panel->cwd, fe->fname); + { + char *tmp_path; + + tmp_path = vfs_path_to_str (current_panel->cwd_vpath); + full_name = concat_dir_and_file (tmp_path, fe->fname); + g_free (tmp_path); + } if (!is_exe (fe->st.st_mode) || !if_link_is_exe (full_name, fe)) { g_free (full_name); @@ -2477,19 +2498,22 @@ chdir_other_panel (WPanel * panel) char *new_dir; 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 (panel->cwd, entry->fname, (char *) NULL); + new_dir = mc_build_filename (tmp_path, entry->fname, (char *) NULL); else { - new_dir = mc_build_filename (panel->cwd, "..", (char *) NULL); - sel_entry = strrchr (panel->cwd, PATH_SEP); + new_dir = mc_build_filename (tmp_path, "..", (char *) NULL); + sel_entry = strrchr (tmp_path, PATH_SEP); } + g_free (tmp_path); change_panel (); do_cd (new_dir, cd_exact); @@ -2518,7 +2542,13 @@ panel_sync_other (const WPanel * panel) set_display_type (get_other_index (), view_listing); } - do_panel_cd (other_panel, current_panel->cwd, cd_exact); + { + 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); + } /* try to select current filename on the other panel */ if (!panel->is_panelized) @@ -2572,7 +2602,13 @@ chdir_to_readlink (WPanel * panel) if (*buffer == PATH_SEP) new_dir = g_strdup (buffer); else - new_dir = concat_dir_and_file (panel->cwd, buffer); + { + char *tmp_path; + + tmp_path = vfs_path_to_str (panel->cwd_vpath); + new_dir = concat_dir_and_file (tmp_path, buffer); + g_free (tmp_path); + } change_panel (); do_cd (new_dir, cd_exact); @@ -2843,11 +2879,11 @@ get_parent_dir_name (const char *cwd, const char *lwd) /** Wrapper for do_subshell_chdir, check for availability of subshell */ static void -subshell_chdir (const char *directory) +subshell_chdir (const vfs_path_t * vpath) { #ifdef HAVE_SUBSHELL_SUPPORT if (mc_global.tty.use_subshell && vfs_current_is_local ()) - do_subshell_chdir (directory, FALSE, TRUE); + do_subshell_chdir (vpath, FALSE, TRUE); #endif /* HAVE_SUBSHELL_SUPPORT */ } @@ -2870,23 +2906,27 @@ _do_panel_cd (WPanel * panel, const char *new_dir, enum cd_enum cd_type) new_dir++; } - olddir = g_strdup (panel->cwd); + olddir = vfs_path_to_str (panel->cwd_vpath); /* Convert *new_path to a suitable pathname, handle ~user */ if (cd_type == cd_parse_command) { - if (!strcmp (new_dir, "-")) + if (strcmp (new_dir, "-") == 0) { - strcpy (temp, panel->lwd); + char *tmp_path; + + tmp_path = vfs_path_to_str (panel->lwd_vpath); + strcpy (temp, tmp_path); new_dir = temp; + g_free (tmp_path); } } vpath = vfs_path_from_str (*new_dir ? new_dir : mc_config_get_home_dir ()); if (mc_chdir (vpath) == -1) { - strcpy (panel->cwd, olddir); + panel_set_cwd (panel, olddir); g_free (olddir); vfs_path_free (vpath); return FALSE; @@ -2894,22 +2934,30 @@ _do_panel_cd (WPanel * panel, const char *new_dir, enum cd_enum cd_type) vfs_path_free (vpath); /* Success: save previous directory, shutdown status of previous dir */ - strcpy (panel->lwd, olddir); + panel_set_lwd (panel, olddir); input_free_completions (cmdline); - mc_get_current_wd (panel->cwd, sizeof (panel->cwd) - 2); + vfs_path_free (panel->cwd_vpath); + vfs_setup_cwd (); + panel->cwd_vpath = vfs_path_clone (vfs_get_raw_current_dir ()); vfs_release_path (olddir); - subshell_chdir (panel->cwd); + subshell_chdir (panel->cwd_vpath); /* Reload current panel */ panel_clean_dir (panel); - panel->count = - do_load_dir (panel->cwd, &panel->dir, panel->sort_info.sort_field->sort_routine, - panel->sort_info.reverse, panel->sort_info.case_sensitive, - panel->sort_info.exec_first, panel->filter); - try_to_select (panel, get_parent_dir_name (panel->cwd, olddir)); + { + char *tmp_path; + + tmp_path = vfs_path_to_str (panel->cwd_vpath); + panel->count = + do_load_dir (tmp_path, &panel->dir, panel->sort_info.sort_field->sort_routine, + panel->sort_info.reverse, panel->sort_info.case_sensitive, + panel->sort_info.exec_first, panel->filter); + try_to_select (panel, get_parent_dir_name (tmp_path, olddir)); + g_free (tmp_path); + } load_hint (0); panel->dirty = 1; update_xterm_title_path (); @@ -2957,7 +3005,13 @@ directory_history_list (WPanel * panel) if (s != NULL) { if (_do_panel_cd (panel, s, cd_exact)) - directory_history_add (panel, panel->cwd); + { + char *tmp_path; + + tmp_path = vfs_path_to_str (panel->cwd_vpath); + directory_history_add (panel, tmp_path); + g_free (tmp_path); + } else message (D_ERROR, MSG_ERROR, _("Cannot change directory")); g_free (s); @@ -3182,7 +3236,6 @@ panel_key (WPanel * panel, int key) static cb_ret_t panel_callback (Widget * w, widget_msg_t msg, int parm) { - vfs_path_t *vpath; WPanel *panel = (WPanel *) w; WButtonBar *bb; @@ -3208,18 +3261,18 @@ panel_callback (Widget * w, widget_msg_t msg, int parm) state_mark = -1; current_panel = panel; panel->active = 1; - vpath = vfs_path_from_str (panel->cwd); - if (mc_chdir (vpath) != 0) + if (mc_chdir (panel->cwd_vpath) != 0) { - char *cwd = strip_password (g_strdup (panel->cwd), 1); + char *cwd; + + cwd = strip_password (vfs_path_to_str (panel->cwd_vpath), 1); message (D_ERROR, MSG_ERROR, _("Cannot chdir to \"%s\"\n%s"), cwd, unix_error_string (errno)); g_free (cwd); } else - subshell_chdir (panel->cwd); + subshell_chdir (panel->cwd_vpath); - vfs_path_free (vpath); update_xterm_title_path (); select_item (panel); show_dir (panel); @@ -3514,19 +3567,14 @@ reload_panelized (WPanel * panel) { int i, j; dir_list *list = &panel->dir; - vfs_path_t *vpath; if (panel != current_panel) - { - int ret; - - vpath = vfs_path_from_str (panel->cwd); - ret = mc_chdir (vpath); - vfs_path_free (vpath); - } + (void) mc_chdir (panel->cwd_vpath); for (i = 0, j = 0; i < panel->count; i++) { + vfs_path_t *vpath; + if (list->list[i].f.marked) { /* Unmark the file in advance. In case the following mc_lstat @@ -3539,16 +3587,15 @@ reload_panelized (WPanel * panel) } vpath = vfs_path_from_str (list->list[i].fname); if (mc_lstat (vpath, &list->list[i].st)) - { g_free (list->list[i].fname); - vfs_path_free (vpath); - continue; + else + { + if (list->list[i].f.marked) + do_file_mark (panel, i, 1); + if (j != i) + list->list[j] = list->list[i]; + j++; } - if (list->list[i].f.marked) - do_file_mark (panel, i, 1); - if (j != i) - list->list[j] = list->list[i]; - j++; vfs_path_free (vpath); } if (j == 0) @@ -3557,13 +3604,7 @@ reload_panelized (WPanel * panel) panel->count = j; if (panel != current_panel) - { - int ret; - - vpath = vfs_path_from_str (current_panel->cwd); - ret = mc_chdir (vpath); - vfs_path_free (vpath); - } + (void) mc_chdir (current_panel->cwd_vpath); } /* --------------------------------------------------------------------------------------------- */ @@ -3576,12 +3617,8 @@ update_one_panel_widget (WPanel * panel, panel_update_flags_t flags, const char if ((flags & UP_RELOAD) != 0) { - vfs_path_t *tmp_vpath; - - tmp_vpath = vfs_path_from_str (panel->cwd); panel->is_panelized = FALSE; - mc_setctl (tmp_vpath, VFS_SETCTL_FLUSH, 0); - vfs_path_free (tmp_vpath); + mc_setctl (panel->cwd_vpath, VFS_SETCTL_FLUSH, 0); memset (&(panel->dir_stat), 0, sizeof (panel->dir_stat)); } @@ -3627,51 +3664,33 @@ update_one_panel (int which, panel_update_flags_t flags, const char *current_fil /* --------------------------------------------------------------------------------------------- */ char * -remove_encoding_from_path (const char *path) +remove_encoding_from_path (const vfs_path_t * vpath) { GString *ret; - GString *tmp_path, *tmp_conv; - char *tmp; + GString *tmp_conv; + int indx; ret = g_string_new (""); tmp_conv = g_string_new (""); - tmp_path = g_string_new (path); - while ((tmp = g_strrstr (tmp_path->str, PATH_SEP_STR VFS_ENCODING_PREFIX)) != NULL) + for (indx = 0; indx < vfs_path_elements_count (vpath); indx++) { + vfs_path_element_t *path_element; GIConv converter; - char *tmp2; - - vfs_path_t *vpath = vfs_path_from_str (tmp); - vfs_path_element_t *path_element = vfs_path_get_by_index (vpath, -1); + path_element = vfs_path_get_by_index (vpath, indx); converter = - path_element->encoding != - NULL ? str_crt_conv_to (path_element->encoding) : str_cnv_to_term; - vfs_path_free (vpath); - + path_element->encoding != NULL ? + str_crt_conv_to (path_element->encoding) : str_cnv_to_term; if (converter == INVALID_CONV) converter = str_cnv_to_term; - tmp2 = tmp + 1; - while (*tmp2 != '\0' && *tmp2 != PATH_SEP) - tmp2++; - - if (*tmp2 != '\0') - { - str_vfs_convert_from (converter, tmp2, tmp_conv); - g_string_prepend (ret, tmp_conv->str); - g_string_set_size (tmp_conv, 0); - } - - g_string_set_size (tmp_path, tmp - tmp_path->str); + str_vfs_convert_from (converter, path_element->path, tmp_conv); + g_string_append (ret, tmp_conv->str); + g_string_set_size (tmp_conv, 0); str_close_conv (converter); } - - g_string_prepend (ret, tmp_path->str); - g_string_free (tmp_path, TRUE); g_string_free (tmp_conv, TRUE); - return g_string_free (ret, FALSE); } @@ -3822,6 +3841,36 @@ panel_clean_dir (WPanel * panel) clean_dir (&panel->dir, count); } +/* --------------------------------------------------------------------------------------------- */ +/** + * Set Up panel's current dir object + * + * @param panel panel object + * @param path_str string contain path + */ + +void +panel_set_cwd (WPanel * panel, const char *path_str) +{ + vfs_path_free (panel->cwd_vpath); + panel->cwd_vpath = vfs_path_from_str (path_str); +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Set Up panel's last working dir object + * + * @param panel panel object + * @param path_str string contain path + */ + +void +panel_set_lwd (WPanel * panel, const char *path_str) +{ + vfs_path_free (panel->lwd_vpath); + panel->lwd_vpath = vfs_path_from_str (path_str); +} + /* --------------------------------------------------------------------------------------------- */ /** Panel creation. * @param panel_name the name of the panel for setup retieving @@ -3847,7 +3896,7 @@ panel_new_with_dir (const char *panel_name, const char *wpath) WPanel *panel; char *section; int i, err; - char curdir[MC_MAXPATHLEN] = "\0"; + char *curdir = NULL; panel = g_new0 (WPanel, 1); @@ -3859,13 +3908,16 @@ panel_new_with_dir (const char *panel_name, const char *wpath) if (wpath != NULL) { - g_strlcpy (panel->cwd, wpath, sizeof (panel->cwd)); - mc_get_current_wd (curdir, sizeof (curdir) - 2); + curdir = _vfs_get_cwd (); + panel_set_cwd (panel, wpath); } else - mc_get_current_wd (panel->cwd, sizeof (panel->cwd) - 2); + { + vfs_setup_cwd (); + panel->cwd_vpath = vfs_path_clone (vfs_get_raw_current_dir ()); + } - strcpy (panel->lwd, "."); + panel_set_lwd (panel, "."); panel->hist_name = g_strconcat ("Dir Hist ", panel_name, (char *) NULL); /* directories history will be get later */ @@ -3917,36 +3969,36 @@ panel_new_with_dir (const char *panel_name, const char *wpath) #ifdef HAVE_CHARSET { - vfs_path_t *vpath = vfs_path_from_str (panel->cwd); - vfs_path_element_t *path_element = vfs_path_get_by_index (vpath, -1); + vfs_path_element_t *path_element; + path_element = vfs_path_get_by_index (panel->cwd_vpath, -1); if (path_element->encoding != NULL) panel->codepage = get_codepage_index (path_element->encoding); - - vfs_path_free (vpath); } #endif + if (mc_chdir (panel->cwd_vpath) != 0) { - vfs_path_t *vpath; - - vpath = vfs_path_from_str (panel->cwd); - if (mc_chdir (vpath) != 0) - { - panel->codepage = SELECT_CHARSET_NO_TRANSLATE; - mc_get_current_wd (panel->cwd, sizeof (panel->cwd) - 2); - } - vfs_path_free (vpath); + panel->codepage = SELECT_CHARSET_NO_TRANSLATE; + vfs_setup_cwd (); + vfs_path_free (panel->cwd_vpath); + panel->cwd_vpath = vfs_path_clone (vfs_get_raw_current_dir ()); } /* Load the default format */ - panel->count = - do_load_dir (panel->cwd, &panel->dir, panel->sort_info.sort_field->sort_routine, - panel->sort_info.reverse, panel->sort_info.case_sensitive, - panel->sort_info.exec_first, panel->filter); + { + char *tmp_path; + + tmp_path = vfs_path_to_str (panel->cwd_vpath); + panel->count = + do_load_dir (tmp_path, &panel->dir, panel->sort_info.sort_field->sort_routine, + panel->sort_info.reverse, panel->sort_info.case_sensitive, + panel->sort_info.exec_first, panel->filter); + g_free (tmp_path); + } /* Restore old right path */ - if (curdir[0] != '\0') + if (curdir != NULL) { vfs_path_t *vpath; @@ -3954,6 +4006,7 @@ panel_new_with_dir (const char *panel_name, const char *wpath) err = mc_chdir (vpath); vfs_path_free (vpath); } + g_free (curdir); return panel; } @@ -3964,44 +4017,53 @@ void panel_reload (WPanel * panel) { struct stat current_stat; + char *tmp_path; + gboolean ok; - if (panels_options.fast_reload && !stat (panel->cwd, ¤t_stat) - && current_stat.st_ctime == panel->dir_stat.st_ctime - && current_stat.st_mtime == panel->dir_stat.st_mtime) + 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); + g_free (tmp_path); + + if (ok) return; do { - vfs_path_t *vpath; - gboolean ok; char *last_slash; - vpath = vfs_path_from_str (panel->cwd); - ok = (mc_chdir (vpath) != -1); - vfs_path_free (vpath); - if (ok) + if (mc_chdir (panel->cwd_vpath) != -1) break; - if (panel->cwd[0] == PATH_SEP && panel->cwd[1] == 0) + tmp_path = vfs_path_to_str (panel->cwd_vpath); + if (tmp_path[0] == PATH_SEP && tmp_path[1] == 0) { panel_clean_dir (panel); panel->count = set_zero_dir (&panel->dir) ? 1 : 0; + g_free (tmp_path); return; } - last_slash = strrchr (panel->cwd, PATH_SEP); - if (!last_slash || last_slash == panel->cwd) - strcpy (panel->cwd, PATH_SEP_STR); + last_slash = strrchr (tmp_path, PATH_SEP); + if (!last_slash || last_slash == tmp_path) + { + vfs_path_free (panel->cwd_vpath); + panel->cwd_vpath = vfs_path_from_str (PATH_SEP_STR); + } else *last_slash = 0; memset (&(panel->dir_stat), 0, sizeof (panel->dir_stat)); + g_free (tmp_path); show_dir (panel); } while (TRUE); + tmp_path = vfs_path_to_str (panel->cwd_vpath); panel->count = - do_reload_dir (panel->cwd, &panel->dir, panel->sort_info.sort_field->sort_routine, + do_reload_dir (tmp_path, &panel->dir, panel->sort_info.sort_field->sort_routine, panel->count, panel->sort_info.reverse, panel->sort_info.case_sensitive, panel->sort_info.exec_first, panel->filter); + g_free (tmp_path); panel->dirty = 1; if (panel->selected >= panel->count) @@ -4227,7 +4289,13 @@ do_panel_cd (struct WPanel *panel, const char *new_dir, enum cd_enum cd_type) r = _do_panel_cd (panel, new_dir, cd_type); if (r) - directory_history_add (panel, panel->cwd); + { + char *tmp_path; + + tmp_path = vfs_path_to_str (panel->cwd_vpath); + directory_history_add (panel, tmp_path); + g_free (tmp_path); + } return r; } @@ -4323,7 +4391,7 @@ panel_change_encoding (WPanel * panel) { /* No translation */ g_free (init_translation_table (mc_global.display_codepage, mc_global.display_codepage)); - cd_path = remove_encoding_from_path (panel->cwd); + cd_path = remove_encoding_from_path (panel->cwd_vpath); do_panel_cd (panel, cd_path, cd_parse_command); g_free (cd_path); return; @@ -4341,16 +4409,12 @@ panel_change_encoding (WPanel * panel) #endif if (encoding != NULL) { - vfs_path_t *vpath = vfs_path_from_str (panel->cwd); + vfs_change_encoding (panel->cwd_vpath, encoding); - vfs_change_encoding (vpath, encoding); - - cd_path = vfs_path_to_str (vpath); + cd_path = vfs_path_to_str (panel->cwd_vpath); if (!do_panel_cd (panel, cd_path, cd_parse_command)) message (D_ERROR, MSG_ERROR, _("Cannot chdir to \"%s\""), cd_path); g_free (cd_path); - - vfs_path_free (vpath); } } @@ -4370,8 +4434,6 @@ update_panels (panel_update_flags_t flags, const char *current_file) { gboolean reload_other = (flags & UP_ONLY_CURRENT) == 0; WPanel *panel; - vfs_path_t *vpath; - int ret; update_one_panel (get_current_index (), flags, current_file); if (reload_other) @@ -4383,11 +4445,7 @@ update_panels (panel_update_flags_t flags, const char *current_file) panel = (WPanel *) get_panel_widget (get_other_index ()); if (!panel->is_panelized) - { - vpath = vfs_path_from_str (panel->cwd); - ret = mc_chdir (vpath); - vfs_path_free (vpath); - } + (void) mc_chdir (panel->cwd_vpath); } /* --------------------------------------------------------------------------------------------- */ diff --git a/src/filemanager/panel.h b/src/filemanager/panel.h index 4cff4d0fc..bd9c540ec 100644 --- a/src/filemanager/panel.h +++ b/src/filemanager/panel.h @@ -43,8 +43,8 @@ typedef enum typedef enum { - UP_OPTIMIZE = 0, - UP_RELOAD = 1, + UP_OPTIMIZE = 0, + UP_RELOAD = 1, UP_ONLY_CURRENT = 2 } panel_update_flags_t; @@ -75,9 +75,9 @@ typedef struct typedef struct panel_sort_info_struct { - gboolean reverse; /* Show listing in reverse? */ - gboolean case_sensitive; /* Listing is case sensitive? */ - gboolean exec_first; /* Show executable top in list? */ + gboolean reverse; /* Show listing in reverse? */ + gboolean case_sensitive; /* Listing is case sensitive? */ + gboolean exec_first; /* Show executable top in list? */ const panel_field_t *sort_field; } panel_sort_info_t; @@ -88,8 +88,10 @@ typedef struct WPanel int list_type; /* listing type (was view_type) */ int active; /* If panel is currently selected */ - char cwd[MC_MAXPATHLEN]; /* Current Working Directory */ - char lwd[MC_MAXPATHLEN]; /* Last Working Directory */ + vfs_path_t *cwd_vpath; + vfs_path_t *lwd_vpath; + // char cwd[MC_MAXPATHLEN]; /* Current Working Directory */ + // char lwd[MC_MAXPATHLEN]; /* Last Working Directory */ GList *dir_history; /* directory history */ char *hist_name; /* directory history name for history file */ int count; /* Number of files in dir structure */ @@ -165,7 +167,7 @@ gboolean do_panel_cd (struct WPanel *panel, const char *new_dir, enum cd_enum cd void directory_history_add (struct WPanel *panel, const char *dir); -char *remove_encoding_from_path (const char *path); +char *remove_encoding_from_path (const vfs_path_t * vpath); gsize panel_get_num_of_sortable_fields (void); const char **panel_get_sortable_fields (gsize *); @@ -174,6 +176,8 @@ const panel_field_t *panel_get_field_by_title (const char *); const panel_field_t *panel_get_field_by_title_hotkey (const char *); gsize panel_get_num_of_user_possible_fields (void); const char **panel_get_user_possible_fields (gsize *); +void panel_set_cwd (WPanel * panel, const char *path_str); +void panel_set_lwd (WPanel * panel, const char *path_str); void panel_init (void); void panel_deinit (void); diff --git a/src/filemanager/panelize.c b/src/filemanager/panelize.c index 49d4bd763..738088c9c 100644 --- a/src/filemanager/panelize.c +++ b/src/filemanager/panelize.c @@ -55,6 +55,7 @@ #include "panel.h" /* WPanel */ #include "panelize.h" +#include "panel.h" /*** global variables ****************************************************************************/ @@ -317,6 +318,18 @@ 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) { @@ -338,7 +351,7 @@ do_external_panelize (char *command) /* Clear the counters and the directory list */ panel_clean_dir (current_panel); - g_strlcpy (panelized_panel.root, current_panel->cwd, MC_MAXPATHLEN); + panelize_strlcpy (panelized_panel.root, current_panel->cwd_vpath, MC_MAXPATHLEN); if (set_zero_dir (list)) next_free++; @@ -387,7 +400,7 @@ do_external_panelize (char *command) if (list->list[0].fname[0] == PATH_SEP) { int ret; - strcpy (current_panel->cwd, PATH_SEP_STR); + panel_set_cwd (current_panel, PATH_SEP_STR); ret = chdir (PATH_SEP_STR); } } @@ -413,7 +426,7 @@ do_panelize_cd (struct WPanel *panel) clean_dir (list, panel->count); if (panelized_panel.root[0] == '\0') - g_strlcpy (panelized_panel.root, panel->cwd, MC_MAXPATHLEN); + panelize_strlcpy (panelized_panel.root, panel->cwd_vpath, MC_MAXPATHLEN); if (panelized_panel.count < 1) { @@ -428,7 +441,13 @@ do_panelize_cd (struct WPanel *panel) panel->count = panelized_panel.count; panel->is_panelized = TRUE; - panelized_same = (strcmp (panelized_panel.root, panel->cwd) == 0); + { + 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); + } for (i = 0; i < panelized_panel.count; i++) { @@ -469,7 +488,7 @@ panelize_save_panel (struct WPanel *panel) int i; dir_list *list = &panel->dir; - g_strlcpy (panelized_panel.root, panel->cwd, MC_MAXPATHLEN); + panelize_strlcpy (panelized_panel.root, panel->cwd_vpath, MC_MAXPATHLEN); if (panelized_panel.count > 0) clean_dir (&panelized_panel.list, panelized_panel.count); @@ -486,7 +505,8 @@ panelize_save_panel (struct WPanel *panel) for (i = 0; i < panel->count; i++) { panelized_panel.list.list[i].fnamelen = list->list[i].fnamelen; - panelized_panel.list.list[i].fname = g_strndup (list->list[i].fname, list->list[i].fnamelen); + panelized_panel.list.list[i].fname = + g_strndup (list->list[i].fname, list->list[i].fnamelen); panelized_panel.list.list[i].f.link_to_dir = list->list[i].f.link_to_dir; panelized_panel.list.list[i].f.stale_link = list->list[i].f.stale_link; panelized_panel.list.list[i].f.dir_size_computed = list->list[i].f.dir_size_computed; diff --git a/src/filemanager/tree.c b/src/filemanager/tree.c index a613ba0b4..cb64dd034 100644 --- a/src/filemanager/tree.c +++ b/src/filemanager/tree.c @@ -713,24 +713,27 @@ static void tree_rescan (void *data) { WTree *tree = data; - char old_dir[MC_MAXPATHLEN]; - vfs_path_t *vpath; - int ret; + char *old_dir; + vfs_path_t *vpath = NULL; + int r; - if (tree->selected_ptr == NULL || mc_get_current_wd (old_dir, MC_MAXPATHLEN) == NULL) + old_dir = vfs_get_current_dir (); + if (old_dir == NULL) return; + if (tree->selected_ptr == NULL) + goto ret; + vpath = vfs_path_from_str (tree->selected_ptr->name); if (mc_chdir (vpath) != 0) - { - vfs_path_free (vpath); - return; - } + goto ret; tree_store_rescan (vpath); vpath = vfs_path_from_str (old_dir); - ret = mc_chdir (vpath); + r = mc_chdir (vpath); + ret: vfs_path_free (vpath); + g_free (old_dir); } /* --------------------------------------------------------------------------------------------- */ @@ -836,8 +839,6 @@ tree_mkdir (WTree * tree) if (!tree->selected_ptr) return; - if (mc_get_current_wd (old_dir, MC_MAXPATHLEN) == NULL) - return; if (chdir (tree->selected_ptr->name)) return; /* FIXME diff --git a/src/filemanager/usermenu.c b/src/filemanager/usermenu.c index d90eab7d7..cfb632b54 100644 --- a/src/filemanager/usermenu.c +++ b/src/filemanager/usermenu.c @@ -260,7 +260,13 @@ test_condition (WEdit * edit_widget, char *p, int *condition) break; case 'd': p = extract_arg (p, arg, sizeof (arg)); - *condition = panel != NULL && mc_search (arg, panel->cwd, search_type) ? 1 : 0; + { + char *cwd_str; + + cwd_str = vfs_path_to_str (panel->cwd_vpath); + *condition = panel != NULL && mc_search (arg, cwd_str, search_type) ? 1 : 0; + g_free (cwd_str); + } break; case 't': p = extract_arg (p, arg, sizeof (arg)); @@ -772,12 +778,10 @@ expand_format (struct WEdit *edit_widget, char c, gboolean do_quote) char *cwd; char *qstr; - cwd = g_malloc (MC_MAXPATHLEN + 1); - if (panel) - g_strlcpy (cwd, panel->cwd, MC_MAXPATHLEN + 1); + cwd = vfs_path_to_str (panel->cwd_vpath); else - mc_get_current_wd (cwd, MC_MAXPATHLEN + 1); + cwd = vfs_get_current_dir (); qstr = (*quote_func) (cwd, 0); diff --git a/src/main.c b/src/main.c index 58a03f681..fa1e68cb7 100644 --- a/src/main.c +++ b/src/main.c @@ -272,15 +272,13 @@ do_cd (const char *new_dir, enum cd_enum exact) #if HAVE_CHARSET if (res) { - vfs_path_t *vpath = vfs_path_from_str (current_panel->cwd); - vfs_path_element_t *path_element = vfs_path_get_by_index (vpath, -1); + vfs_path_element_t *path_element; + path_element = vfs_path_get_by_index (current_panel->cwd_vpath, -1); if (path_element->encoding != NULL) current_panel->codepage = get_codepage_index (path_element->encoding); else current_panel->codepage = SELECT_CHARSET_NO_TRANSLATE; - - vfs_path_free (vpath); } #endif /* HAVE_CHARSET */ @@ -345,7 +343,11 @@ update_xterm_title_path (void) if (mc_global.tty.xterm_flag && xterm_title) { - path = strip_home_and_password (current_panel->cwd); + char *path_str; + + path_str = vfs_path_to_str (current_panel->cwd_vpath); + path = strip_home_and_password (path_str); + g_free (path_str); res = gethostname (host, sizeof (host)); if (res) { /* On success, res = 0 */ diff --git a/src/setup.c b/src/setup.c index c3e045d70..a3fc67923 100644 --- a/src/setup.c +++ b/src/setup.c @@ -790,7 +790,13 @@ save_panel_types (void) if (type == view_listing) panel_save_setup (right_panel, right_panel->panel_name); - mc_config_set_string (mc_panels_config, "Dirs", "other_dir", get_panel_dir_for (other_panel)); + { + char *dirs; + + dirs = get_panel_dir_for (other_panel); + mc_config_set_string (mc_panels_config, "Dirs", "other_dir", dirs); + g_free (dirs); + } if (current_panel != NULL) mc_config_set_string (mc_panels_config, "Dirs", "current_is_left", diff --git a/src/subshell.c b/src/subshell.c index f49adc360..2bb9b61bc 100644 --- a/src/subshell.c +++ b/src/subshell.c @@ -927,7 +927,7 @@ invoke_subshell (const char *command, int how, char **new_dir) /* Make the subshell change to MC's working directory */ if (new_dir != NULL) - do_subshell_chdir (current_panel->cwd, TRUE, TRUE); + do_subshell_chdir (current_panel->cwd_vpath, TRUE, TRUE); if (command == NULL) /* The user has done "C-o" from MC */ { @@ -953,7 +953,14 @@ invoke_subshell (const char *command, int how, char **new_dir) feed_subshell (how, FALSE); - pcwd = vfs_translate_path_n (current_panel->cwd); + { + char *cwd_str; + + cwd_str = vfs_path_to_str (current_panel->cwd_vpath); + pcwd = vfs_translate_path_n (cwd_str); + g_free (cwd_str); + } + if (new_dir && subshell_alive && strcmp (subshell_cwd, pcwd)) *new_dir = subshell_cwd; /* Make MC change to the subshell's CWD */ g_free (pcwd); @@ -1161,13 +1168,15 @@ subshell_name_quote (const char *s) /** If it actually changed the directory it returns true */ void -do_subshell_chdir (const char *directory, gboolean update_prompt, gboolean reset_prompt) +do_subshell_chdir (const vfs_path_t * vpath, gboolean update_prompt, gboolean reset_prompt) { - char *pcwd; + char *pcwd, *cwd_str; char *temp; - char *translate; + char *directory; - pcwd = vfs_translate_path_n (current_panel->cwd); + cwd_str = vfs_path_to_str (current_panel->cwd_vpath); + pcwd = vfs_translate_path_n (cwd_str); + g_free (cwd_str); if (!(subshell_state == INACTIVE && strcmp (subshell_cwd, pcwd) != 0)) { @@ -1184,10 +1193,14 @@ do_subshell_chdir (const char *directory, gboolean update_prompt, gboolean reset /* The initial space keeps this out of the command history (in bash because we set "HISTCONTROL=ignorespace") */ write_all (mc_global.tty.subshell_pty, " cd ", 4); - if (*directory) + + directory = vfs_path_to_str (vpath); + if (directory != '\0') { + char *translate; + translate = vfs_translate_path_n (directory); - if (translate) + if (translate != NULL) { temp = subshell_name_quote (translate); if (temp) @@ -1212,6 +1225,7 @@ do_subshell_chdir (const char *directory, gboolean update_prompt, gboolean reset { write_all (mc_global.tty.subshell_pty, "/", 1); } + g_free (directory); write_all (mc_global.tty.subshell_pty, "\n", 1); subshell_state = RUNNING_COMMAND; diff --git a/src/subshell.h b/src/subshell.h index e8afe0b65..54433bfa6 100644 --- a/src/subshell.h +++ b/src/subshell.h @@ -49,7 +49,7 @@ int invoke_subshell (const char *command, int how, char **new_dir); int read_subshell_prompt (void); void do_update_prompt (void); int exit_subshell (void); -void do_subshell_chdir (const char *directory, gboolean update_prompt, gboolean reset_prompt); +void do_subshell_chdir (const vfs_path_t * vpath, gboolean update_prompt, gboolean reset_prompt); void subshell_get_console_attributes (void); void sigchld_handler (int sig); diff --git a/tests/lib/vfs/current_dir.c b/tests/lib/vfs/current_dir.c index 418204591..504a55930 100644 --- a/tests/lib/vfs/current_dir.c +++ b/tests/lib/vfs/current_dir.c @@ -71,16 +71,18 @@ test_chdir (const vfs_path_t * vpath) vpath = vfs_path_from_str (cd_dir); \ mc_chdir(vpath); \ vfs_path_free (vpath); \ + buffer = _vfs_get_cwd (); \ fail_unless( \ - strcmp(etalon, mc_get_current_wd(buffer,MC_MAXPATHLEN)) == 0, \ - "\n expected(%s) doesn't equal \nto actual(%s)", etalon, buffer); + strcmp(etalon, buffer) == 0, \ + "\n expected(%s) doesn't equal \nto actual(%s)", etalon, buffer); \ + g_free (buffer); START_TEST (set_up_current_dir_url) { vfs_path_t *vpath; static struct vfs_s_subclass test_subclass; static struct vfs_class vfs_test_ops; - char buffer[MC_MAXPATHLEN]; + char *buffer; vfs_s_init_class (&vfs_test_ops, &test_subclass);