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

Bug#685176: marked as done (unblock: mc/3:4.8.3-5)



Your message dated Wed, 22 Aug 2012 21:09:57 +0200
with message-id <[🔎] 20120822190957.GI13686@mraw.org>
and subject line Re: Bug#685176: unblock: mc/3:4.8.3-5
has caused the Debian Bug report #685176,
regarding unblock: mc/3:4.8.3-5
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
685176: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=685176
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
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.


--- End Message ---
--- Begin Message ---
Hello,

Dmitry Smirnov <onlyjob@member.fsf.org> (18/08/2012):
> 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

unblocked, thanks.

Mraw,
KiBi.

Attachment: signature.asc
Description: Digital signature


--- End Message ---

Reply to: