[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#685176: unblock: mc/3:4.8.3-5



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package 'mc'

mc/3:4.8.3-5 fixes two regressions from previous versions as per quote from 
Changelog:

  * new backported patches:
    + to fix "Garbage directory listing in ftpfs"
      (Closes: #681515, #675921).
    + to fix "hex search: can't find 00 (zeroes) in patterns".
  * mc.desktop is validated with 'desktop-file-validate' and corrected.

As long as I can recall 'ftpfs' was working correctly in Squeeze and this 
defect has a potential for data corruption.

Fixes are implemented using backported patches from newer release.

See all the changes in the attached diff.

  unblock mc/3:4.8.3-5

Thank you.

Regards,
Dmitry.
diff --git a/debian/changelog b/debian/changelog
index e3c317c..472cfc4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,19 @@
+mc (3:4.8.3-5) unstable; urgency=low
+
+  * 2800.patch is corrected to avoid crash on entering archives.
+
+ -- Dmitry Smirnov <onlyjob@member.fsf.org>  Sun, 05 Aug 2012 21:52:36 +1000
+
+mc (3:4.8.3-4) unstable; urgency=low
+
+  * new backported patches:
+    + to fix "Garbage directory listing in ftpfs"
+      (Closes: #681515, #675921).
+    + to fix "hex search: can't find 00 (zeroes) in patterns".
+  * mc.desktop is validated with 'desktop-file-validate' and corrected.
+
+ -- Dmitry Smirnov <onlyjob@member.fsf.org>  Sun, 05 Aug 2012 09:51:58 +1000
+
 mc (3:4.8.3-3) unstable; urgency=high
 
   * added new backported patch to fix issue which may cause loss of data
diff --git a/debian/mc.desktop b/debian/mc.desktop
index b50456e..f159e65 100644
--- a/debian/mc.desktop
+++ b/debian/mc.desktop
@@ -16,5 +16,4 @@ Exec=mc
 Icon=MidnightCommander
 Terminal=true
 Type=Application
-Categories=ConsoleOnly;Utility;FileManager;
-# vi: encoding=utf-8
+Categories=ConsoleOnly;Utility;FileManager;System;FileTools;
diff --git a/debian/patches/2795.patch b/debian/patches/2795.patch
new file mode 100644
index 0000000..8a9b2bc
--- /dev/null
+++ b/debian/patches/2795.patch
@@ -0,0 +1,283 @@
+Last-Update: 2012-08-05
+Author: Dmitry Smirnov <onlyjob@member.fsf.org>
+Applied-Upstream: 2.8.4
+Forwarded: not-needed
+Bug-MC: https://www.midnight-commander.org/ticket/2795
+Description: backported fix for "hex search: can't find 00 (zeroes) in patterns"
+
+--- a/lib/filehighlight/ini-file-read.c
++++ b/lib/filehighlight/ini-file-read.c
+@@ -162,7 +162,7 @@
+ 
+     mc_filter = g_new0 (mc_fhl_filter_t, 1);
+     mc_filter->type = MC_FLHGH_T_FREGEXP;
+-    mc_filter->search_condition = mc_search_new (buf->str, -1);
++    mc_filter->search_condition = mc_search_new (buf->str, buf->len);
+     mc_filter->search_condition->is_case_sensitive =
+         mc_config_get_bool (fhl->config, group_name, "extensions_case", TRUE);
+     mc_filter->search_condition->search_type = MC_SEARCH_T_REGEX;
+--- a/lib/search.h
++++ b/lib/search.h
+@@ -13,7 +13,8 @@
+ 
+ /*** typedefs(not structures) and defined constants **********************************************/
+ 
+-typedef int (*mc_search_fn) (const void *user_data, gsize char_offset);
++typedef int (*mc_search_fn) (const void *user_data, gsize char_offset, int *current_char);
++typedef int (*mc_update_fn) (const void *user_data, gsize char_offset);
+ 
+ #define MC_SEARCH__NUM_REPLACE_ARGS 64
+ 
+@@ -77,12 +78,11 @@
+     mc_search_fn search_fn;
+ 
+     /* function, used for updatin current search status. NULL if not used */
+-    mc_search_fn update_fn;
++    mc_update_fn update_fn;
+ 
+     /* type of search */
+     mc_search_type_t search_type;
+ 
+-
+     /* public output data */
+ 
+     /* some data for normal */
+--- a/lib/search/internal.h
++++ b/lib/search/internal.h
+@@ -47,7 +47,7 @@
+ 
+ gchar *mc_search__get_one_symbol (const char *, const char *, gsize, gboolean *);
+ 
+-int mc_search__get_char (mc_search_t *, const void *, gsize);
++mc_search_cbret_t mc_search__get_char (mc_search_t *, const void *, gsize, int *);
+ 
+ GString *mc_search__tolower_case_str (const char *, const char *, gsize);
+ 
+--- a/lib/search/lib.c
++++ b/lib/search/lib.c
+@@ -137,15 +137,18 @@
+ 
+ /* --------------------------------------------------------------------------------------------- */
+ 
+-int
+-mc_search__get_char (mc_search_t * lc_mc_search, const void *user_data, gsize current_pos)
++mc_search_cbret_t
++mc_search__get_char (mc_search_t * lc_mc_search, const void *user_data, gsize current_pos,
++                     int *current_char)
+ {
+-    char *data;
+-    if (lc_mc_search->search_fn)
+-        return (lc_mc_search->search_fn) (user_data, current_pos);
++    unsigned char *data;
+ 
+-    data = (char *) user_data;
+-    return (int) (unsigned char) data[current_pos];
++    if (lc_mc_search->search_fn != NULL)
++        return lc_mc_search->search_fn (user_data, current_pos, current_char);
++
++    data = (unsigned char *) user_data;
++    *current_char = (int) data[current_pos];
++    return (*current_char == 0) ? MC_SEARCH_CB_ABORT : MC_SEARCH_CB_OK;
+ }
+ 
+ /* --------------------------------------------------------------------------------------------- */
+--- a/lib/search/regex.c
++++ b/lib/search/regex.c
+@@ -259,9 +259,8 @@
+ #ifdef SEARCH_TYPE_GLIB
+     GError *error = NULL;
+ 
+-    if (!g_regex_match_full
+-        (regex, search_str->str, -1, 0, G_REGEX_MATCH_NEWLINE_ANY, &lc_mc_search->regex_match_info,
+-         &error))
++    if (!g_regex_match_full (regex, search_str->str, search_str->len, 0, G_REGEX_MATCH_NEWLINE_ANY,
++                             &lc_mc_search->regex_match_info, &error))
+     {
+         g_match_info_free (lc_mc_search->regex_match_info);
+         lc_mc_search->regex_match_info = NULL;
+@@ -278,7 +277,7 @@
+     lc_mc_search->num_results = g_match_info_get_match_count (lc_mc_search->regex_match_info);
+ #else /* SEARCH_TYPE_GLIB */
+     lc_mc_search->num_results = pcre_exec (regex, lc_mc_search->regex_match_info,
+-                                           search_str->str, search_str->len - 1, 0, 0,
++                                           search_str->str, search_str->len, 0, 0,
+                                            lc_mc_search->iovector, MC_SEARCH__NUM_REPLACE_ARGS);
+     if (lc_mc_search->num_results < 0)
+     {
+@@ -793,8 +792,8 @@
+ mc_search__run_regex (mc_search_t * lc_mc_search, const void *user_data,
+                       gsize start_search, gsize end_search, gsize * found_len)
+ {
++    mc_search_cbret_t ret = MC_SEARCH_CB_ABORT;
+     gsize current_pos, virtual_pos;
+-    int current_chr = 0;
+     gint start_pos;
+     gint end_pos;
+ 
+@@ -809,44 +808,38 @@
+         g_string_set_size (lc_mc_search->regex_buffer, 0);
+         lc_mc_search->start_buffer = current_pos;
+ 
+-        while (1)
++        while (TRUE)
+         {
+-            current_chr = mc_search__get_char (lc_mc_search, user_data, current_pos);
+-            if (current_chr == MC_SEARCH_CB_ABORT)
++            int current_chr = '\n';     /* stop search symbol */
++
++            ret = mc_search__get_char (lc_mc_search, user_data, current_pos, &current_chr);
++            if (ret == MC_SEARCH_CB_ABORT)
+                 break;
+ 
+-            if (current_chr == MC_SEARCH_CB_INVALID)
++            if (ret == MC_SEARCH_CB_INVALID)
+                 continue;
+ 
+             current_pos++;
+ 
+-            if (current_chr == MC_SEARCH_CB_SKIP)
++            if (ret == MC_SEARCH_CB_SKIP)
+                 continue;
+ 
+             virtual_pos++;
+ 
+             g_string_append_c (lc_mc_search->regex_buffer, (char) current_chr);
+ 
+-
+-            if (current_chr == 0 || (char) current_chr == '\n')
+-                break;
+-
+-            if (virtual_pos > end_search)
++            if ((char) current_chr == '\n' || virtual_pos > end_search)
+                 break;
+-
+         }
++
+         switch (mc_search__regex_found_cond (lc_mc_search, lc_mc_search->regex_buffer))
+         {
+         case COND__FOUND_OK:
+ #ifdef SEARCH_TYPE_GLIB
+             if (lc_mc_search->whole_words)
+-            {
+                 g_match_info_fetch_pos (lc_mc_search->regex_match_info, 2, &start_pos, &end_pos);
+-            }
+             else
+-            {
+                 g_match_info_fetch_pos (lc_mc_search->regex_match_info, 0, &start_pos, &end_pos);
+-            }
+ #else /* SEARCH_TYPE_GLIB */
+             if (lc_mc_search->whole_words)
+             {
+@@ -859,7 +852,7 @@
+                 end_pos = lc_mc_search->iovector[1];
+             }
+ #endif /* SEARCH_TYPE_GLIB */
+-            if (found_len)
++            if (found_len != NULL)
+                 *found_len = end_pos - start_pos;
+             lc_mc_search->normal_offset = lc_mc_search->start_buffer + start_pos;
+             return TRUE;
+@@ -870,18 +863,20 @@
+             lc_mc_search->regex_buffer = NULL;
+             return FALSE;
+         }
++
+         if ((lc_mc_search->update_fn != NULL) &&
+             ((lc_mc_search->update_fn) (user_data, current_pos) == MC_SEARCH_CB_ABORT))
+-            current_chr = MC_SEARCH_CB_ABORT;
++            ret = MC_SEARCH_CB_ABORT;
+ 
+-        if (current_chr == MC_SEARCH_CB_ABORT)
++        if (ret == MC_SEARCH_CB_ABORT)
+             break;
+     }
++
+     g_string_free (lc_mc_search->regex_buffer, TRUE);
+     lc_mc_search->regex_buffer = NULL;
+     lc_mc_search->error = MC_SEARCH_E_NOTFOUND;
+ 
+-    if (current_chr != MC_SEARCH_CB_ABORT)
++    if (ret != MC_SEARCH_CB_ABORT)
+         lc_mc_search->error_str = g_strdup (_(STR_E_NOTFOUND));
+     else
+         lc_mc_search->error_str = NULL;
+--- a/src/editor/edit-impl.h
++++ b/src/editor/edit-impl.h
+@@ -239,7 +239,8 @@
+ void edit_push_markers (WEdit * edit);
+ void edit_replace_cmd (WEdit * edit, int again);
+ void edit_search_cmd (WEdit * edit, gboolean again);
+-int edit_search_cmd_callback (const void *user_data, gsize char_offset);
++mc_search_cbret_t edit_search_cmd_callback (const void *user_data, gsize char_offset,
++                                            int *current_char);
+ void edit_complete_word_cmd (WEdit * edit);
+ void edit_get_match_keyword_cmd (WEdit * edit);
+ int edit_save_block (WEdit * edit, const char *filename, long start, long finish);
+--- a/src/editor/editcmd.c
++++ b/src/editor/editcmd.c
+@@ -2687,10 +2687,11 @@
+ 
+ /* --------------------------------------------------------------------------------------------- */
+ 
+-int
+-edit_search_cmd_callback (const void *user_data, gsize char_offset)
++mc_search_cbret_t
++edit_search_cmd_callback (const void *user_data, gsize char_offset, int *current_char)
+ {
+-    return edit_get_byte ((WEdit *) user_data, (long) char_offset);
++    *current_char = edit_get_byte ((WEdit *) user_data, (long) char_offset);
++    return MC_SEARCH_CB_OK;
+ }
+ 
+ /* --------------------------------------------------------------------------------------------- */
+--- a/src/viewer/internal.h
++++ b/src/viewer/internal.h
+@@ -321,7 +321,8 @@
+ void mcview_display_text (mcview_t *);
+ 
+ /* search.c: */
+-int mcview_search_cmd_callback (const void *user_data, gsize char_offset);
++mc_search_cbret_t mcview_search_cmd_callback (const void *user_data, gsize char_offset,
++                                              int *current_char);
+ int mcview_search_update_cmd_callback (const void *, gsize);
+ void mcview_do_search (mcview_t * view);
+ 
+--- a/src/viewer/search.c
++++ b/src/viewer/search.c
+@@ -158,19 +158,16 @@
+ /*** public functions ****************************************************************************/
+ /* --------------------------------------------------------------------------------------------- */
+ 
+-int
+-mcview_search_cmd_callback (const void *user_data, gsize char_offset)
++mc_search_cbret_t
++mcview_search_cmd_callback (const void *user_data, gsize char_offset, int *current_char)
+ {
+-    int lc_byte;
+     mcview_t *view = (mcview_t *) user_data;
+ 
+     /*    view_read_continue (view, &view->search_onechar_info); *//* AB:FIXME */
+     if (!view->text_nroff_mode)
+     {
+-        if (!mcview_get_byte (view, char_offset, &lc_byte))
+-            return MC_SEARCH_CB_OK;
+-
+-        return lc_byte;
++        mcview_get_byte (view, char_offset, current_char);
++        return MC_SEARCH_CB_OK;
+     }
+ 
+     if (view->search_numNeedSkipChar != 0)
+@@ -208,10 +205,10 @@
+         return MC_SEARCH_CB_INVALID;
+     }
+ 
+-    lc_byte = search_cb_char_buffer[search_cb_char_curr_index];
++    *current_char = search_cb_char_buffer[search_cb_char_curr_index];
+     search_cb_char_curr_index++;
+-    return (lc_byte != -1) ? (unsigned char) lc_byte : MC_SEARCH_CB_INVALID;
+ 
++    return (*current_char != -1) ? MC_SEARCH_CB_OK : MC_SEARCH_CB_INVALID;
+ }
+ 
+ /* --------------------------------------------------------------------------------------------- */
diff --git a/debian/patches/2800.patch b/debian/patches/2800.patch
new file mode 100644
index 0000000..9da69e3
--- /dev/null
+++ b/debian/patches/2800.patch
@@ -0,0 +1,376 @@
+Last-Update: 2012-08-05
+Author: Dmitry Smirnov <onlyjob@member.fsf.org>
+Applied-Upstream: 2.8.4
+Forwarded: not-needed
+Bug-MC: https://www.midnight-commander.org/ticket/2800
+Description: backported fix for "Garbage directory listing in ftpfs"
+
+--- a/lib/vfs/direntry.c
++++ b/lib/vfs/direntry.c
+@@ -1044,45 +1044,35 @@
+ /* Ook, these were functions around directory entries / inodes */
+ /* -------------------------------- superblock games -------------------------- */
+ /**
+- * get path from last VFS-element and create corresponding superblock
++ * get superlock object by vpath
+  *
+- * @param vpath source path object
+- * @param archive pointer to object for store newly created superblock
+- * @param flags flags
+- *
+- * @return path from last VFS-element
++ * @param vpath path
++ * @return superlock object or NULL if not found
+  */
+-const char *
+-vfs_s_get_path (const vfs_path_t * vpath, struct vfs_s_super **archive, int flags)
++
++struct vfs_s_super *
++vfs_get_super_by_vpath (const vfs_path_t * vpath)
+ {
+     GList *iter;
+-    const char *retval;
+-    int result = -1;
+-    struct vfs_s_super *super;
+     void *cookie = NULL;
+     const vfs_path_element_t *path_element;
+-    vfs_path_t *vpath_archive;
+     struct vfs_s_subclass *subclass;
++    struct vfs_s_super *super = NULL;
++    vfs_path_t *vpath_archive;
+ 
+     path_element = vfs_path_get_by_index (vpath, -1);
+     subclass = ((struct vfs_s_subclass *) path_element->class->data);
+-
+     if (subclass == NULL)
+         return NULL;
+ 
+     vpath_archive = vfs_path_clone (vpath);
+     vfs_path_remove_element_by_index (vpath_archive, -1);
+ 
+-    retval = (path_element->path != NULL) ? path_element->path : "";
+-
+     if (subclass->archive_check != NULL)
+     {
+         cookie = subclass->archive_check (vpath_archive);
+         if (cookie == NULL)
+-        {
+-            vfs_path_free (vpath_archive);
+-            return NULL;
+-        }
++            goto ret;
+     }
+ 
+     for (iter = subclass->supers; iter != NULL; iter = g_list_next (iter))
+@@ -1093,29 +1083,70 @@
+ 
+         /* 0 == other, 1 == same, return it, 2 == other but stop scanning */
+         i = subclass->archive_same (path_element, super, vpath_archive, cookie);
++        if (i == 1)
++            goto ret;
+         if (i != 0)
+-        {
+-            if (i == 1)
+-                goto return_success;
+             break;
+-        }
++
++        super = NULL;
+     }
+ 
++  ret:
++    vfs_path_free (vpath_archive);
++    return super;
++}
++
++/* --------------------------------------------------------------------------------------------- */
++/**
++ * get path from last VFS-element and create corresponding superblock
++ *
++ * @param vpath source path object
++ * @param archive pointer to object for store newly created superblock
++ * @param flags flags
++ *
++ * @return path from last VFS-element
++ */
++const char *
++vfs_s_get_path (const vfs_path_t * vpath, struct vfs_s_super **archive, int flags)
++{
++    const char *retval = "";
++    int result = -1;
++    struct vfs_s_super *super;
++    const vfs_path_element_t *path_element;
++    struct vfs_s_subclass *subclass;
++
++    path_element = vfs_path_get_by_index (vpath, -1);
++
++    if (path_element->path != NULL)
++        retval = path_element->path;
++
++    super = vfs_get_super_by_vpath(vpath);
++    if (super != NULL)
++        goto return_success;
++
+     if (flags & FL_NO_OPEN)
+     {
+         path_element->class->verrno = EIO;
+-        vfs_path_free (vpath_archive);
+         return NULL;
+     }
+ 
+     super = vfs_s_new_super (path_element->class);
++
++    subclass = ((struct vfs_s_subclass *) path_element->class->data);
+     if (subclass->open_archive != NULL)
++    {
++        vfs_path_t *vpath_archive;
++
++        vpath_archive = vfs_path_clone (vpath);
++        vfs_path_remove_element_by_index (vpath_archive, -1);
++
+         result = subclass->open_archive (super, vpath_archive, path_element);
++        vfs_path_free (vpath_archive);
++    }
+     if (result == -1)
+     {
+         vfs_s_free_super (path_element->class, super);
+         path_element->class->verrno = EIO;
+-        vfs_path_free (vpath_archive);
+         return NULL;
+     }
+     if (!super->name)
+@@ -1128,7 +1159,6 @@
+ 
+   return_success:
+     *archive = super;
+-    vfs_path_free (vpath_archive);
+     return retval;
+ }
+ 
+--- a/lib/vfs/interface.c
++++ b/lib/vfs/interface.c
+@@ -699,34 +699,25 @@
+     path_element = vfs_path_get_by_index (vfs_get_raw_current_dir (), -1);
+     if (vfs_path_element_valid (path_element))
+     {
++        struct vfs_s_super *super;
++
+         if (*path_element->path != '\0')
+         {
+             char *p;
+ 
+             p = strchr (path_element->path, 0) - 1;
+-            if (p != NULL && *p == PATH_SEP && p != path_element->path)
++            if (*p == PATH_SEP && p > path_element->path)
+                 *p = '\0';
+         }
+-#ifdef ENABLE_VFS_NET
+-        {
+-            struct vfs_s_subclass *subclass;
+ 
+-            subclass = (struct vfs_s_subclass *) path_element->class->data;
+-            if (subclass != NULL)
+-            {
+-                struct vfs_s_super *super = NULL;
+-
+-                (void) vfs_s_get_path (vpath, &super, 0);
+-                if (super != NULL && super->path_element != NULL)
+-                {
+-                    g_free (super->path_element->path);
+-                    super->path_element->path = g_strdup (path_element->path);
+-                }
+-            }
++        super = vfs_get_super_by_vpath (vpath);
++            if (super != NULL && super->path_element != NULL)
++        {
++            g_free (super->path_element->path);
++            super->path_element->path = g_strdup (path_element->path);
+         }
+-#endif /* ENABLE_VFS_NET */
+-
+     }
++
+     return 0;
+ 
+   error_end:
+--- a/lib/vfs/xdirentry.h
++++ b/lib/vfs/xdirentry.h
+@@ -176,6 +176,7 @@
+ /* outside interface */
+ void vfs_s_init_class (struct vfs_class *vclass, struct vfs_s_subclass *sub);
+ const char *vfs_s_get_path (const vfs_path_t * vpath, struct vfs_s_super **archive, int flags);
++struct vfs_s_super *vfs_get_super_by_vpath(const vfs_path_t * vpath);
+ 
+ void vfs_s_invalidate (struct vfs_class *me, struct vfs_s_super *super);
+ char *vfs_s_fullpath (struct vfs_class *me, struct vfs_s_inode *ino);
+--- a/src/vfs/fish/fish.c
++++ b/src/vfs/fish/fish.c
+@@ -543,7 +543,6 @@
+     if (fish_info (me, super))
+         SUP->scr_env = fish_set_env (SUP->host_flags);
+ 
+-    vfs_print_message (_("fish: Connected, home %s."), super->path_element->path);
+ #if 0
+     super->name =
+         g_strconcat ("sh://", super->path_element->user, "@", super->path_element->host, "/",
+@@ -1568,7 +1567,11 @@
+             }
+             break;
+         }
+-        name = vfs_path_element_build_pretty_path_str (super->path_element);
++
++        name =
++            g_strconcat (vfs_fish_ops.prefix, VFS_PATH_URL_DELIMITER,
++                         super->path_element->user, "@", super->path_element->host, flags, "/",
++                         super->path_element->path, (char *) NULL);
+         func (name);
+         g_free (name);
+     }
+--- a/src/vfs/ftpfs/ftpfs.c
++++ b/src/vfs/ftpfs/ftpfs.c
+@@ -219,6 +219,7 @@
+                                  * "LIST" instead
+                                  */
+     int ctl_connection_busy;
++    char *current_dir;
+ } ftp_super_data_t;
+ 
+ typedef struct
+@@ -262,6 +263,7 @@
+    c) strip trailing "/."
+  */
+ 
++static char *ftpfs_get_current_directory (struct vfs_class *me, struct vfs_s_super *super);
+ static int ftpfs_chdir_internal (struct vfs_class *me, struct vfs_s_super *super,
+                                  const char *remote_path);
+ static int ftpfs_command (struct vfs_class *me, struct vfs_s_super *super, int wait_reply,
+@@ -424,11 +426,11 @@
+     sock = ftpfs_open_socket (me, super);
+     if (sock != -1)
+     {
+-        char *cwdir = super->path_element->path;
++        char *cwdir = SUP->current_dir;
+ 
+         close (SUP->sock);
+         SUP->sock = sock;
+-        super->path_element->path = NULL;
++        SUP->current_dir = NULL;
+ 
+ 
+         if (ftpfs_login_server (me, super, super->path_element->password) != 0)
+@@ -440,7 +442,7 @@
+             return sock == COMPLETE ? 1 : 0;
+         }
+ 
+-        super->path_element->path = cwdir;
++        SUP->current_dir = cwdir;
+     }
+ 
+     return 0;
+@@ -548,6 +550,7 @@
+         ftpfs_command (me, super, NONE, "QUIT");
+         close (SUP->sock);
+     }
++    g_free (SUP->current_dir);
+     g_free (super->data);
+     super->data = NULL;
+ }
+@@ -960,6 +963,10 @@
+     }
+     while (retry_seconds != 0);
+ 
++    SUP->current_dir = ftpfs_get_current_directory (me, super);
++    if (SUP->current_dir == NULL)
++        SUP->current_dir = g_strdup (PATH_SEP_STR);
++
+     return 0;
+ }
+ 
+@@ -1012,6 +1019,55 @@
+ }
+ 
+ /* --------------------------------------------------------------------------------------------- */
++/* The returned directory should always contain a trailing slash */
++
++static char *
++ftpfs_get_current_directory (struct vfs_class *me, struct vfs_s_super *super)
++{
++    char buf[MC_MAXPATHLEN + 1];
++
++    if (ftpfs_command (me, super, NONE, "PWD") == COMPLETE &&
++        ftpfs_get_reply (me, SUP->sock, buf, sizeof (buf)) == COMPLETE)
++    {
++        char *bufp = NULL;
++        char *bufq;
++
++        for (bufq = buf; *bufq != '\0'; bufq++)
++            if (*bufq == '"')
++            {
++                if (bufp == NULL)
++                    bufp = bufq + 1;
++                else
++                {
++                    *bufq = '\0';
++
++                    if (*bufp != '\0')
++                    {
++                        if (*(bufq - 1) != '/')
++                        {
++                            *bufq++ = '/';
++                            *bufq = '\0';
++                        }
++
++                        if (*bufp == '/')
++                            return g_strdup (bufp);
++
++                        /* If the remote server is an Amiga a leading slash
++                           might be missing. MC needs it because it is used
++                           as separator between hostname and path internally. */
++                        return g_strconcat ("/", bufp, (char *) NULL);
++                    }
++
++                    break;
++                }
++            }
++    }
++
++    ftpfs_errno = EIO;
++    return NULL;
++}
++
++/* --------------------------------------------------------------------------------------------- */
+ /* Setup Passive PASV FTP connection */
+ 
+ static int
+@@ -1991,9 +2047,9 @@
+ {
+     (void) me;
+ 
+-    if (super->path_element->path == NULL)
++    if (SUP->current_dir == NULL)
+         return FALSE;
+-    return (strcmp (path, super->path_element->path) == 0);
++    return (strcmp (path, SUP->current_dir) == 0);
+ }
+ 
+ /* --------------------------------------------------------------------------------------------- */
+@@ -2014,7 +2070,11 @@
+     if (r != COMPLETE)
+         ftpfs_errno = EIO;
+     else
++    {
++        g_free (SUP->current_dir);
++        SUP->current_dir = g_strdup (remote_path);
+         SUP->cwd_deferred = 0;
++    }
+     return r;
+ }
+ 
+@@ -2188,6 +2248,7 @@
+         char *name;
+ 
+         name = vfs_path_element_build_pretty_path_str (super->path_element);
++
+         func (name);
+         g_free (name);
+     }
diff --git a/debian/patches/series b/debian/patches/series
index e1b25a7..b198108 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -22,3 +22,5 @@ fix_open_archive.patch
 fix_broken_test.patch
 fix_chown.patch
 fix_nospace.patch
+2795.patch
+2800.patch

Attachment: signature.asc
Description: This is a digitally signed message part.


Reply to: