Browse Source

Merge branch '2779_broken_path_in_active_vfs_list'

* 2779_broken_path_in_active_vfs_list:
  Ticket #2779: Active VFS directories list contain incorrect current path
Slava Zanko 13 years ago
parent
commit
fcd3bea20d
6 changed files with 65 additions and 90 deletions
  1. 3 0
      lib/vfs/direntry.c
  2. 29 5
      lib/vfs/interface.c
  3. 29 0
      lib/vfs/path.c
  4. 2 0
      lib/vfs/path.h
  5. 1 21
      src/vfs/fish/fish.c
  6. 1 64
      src/vfs/ftpfs/ftpfs.c

+ 3 - 0
lib/vfs/direntry.c

@@ -1067,6 +1067,9 @@ vfs_s_get_path (const vfs_path_t * vpath, struct vfs_s_super **archive, int flag
     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);
 

+ 29 - 5
lib/vfs/interface.c

@@ -58,6 +58,7 @@
 #include "utilvfs.h"
 #include "path.h"
 #include "gc.h"
+#include "xdirentry.h"
 
 extern GString *vfs_str_buffer;
 extern struct vfs_class *current_vfs;
@@ -696,12 +697,35 @@ mc_chdir (const vfs_path_t * vpath)
 
     /* Sometimes we assume no trailing slash on cwd */
     path_element = vfs_path_get_by_index (vfs_get_raw_current_dir (), -1);
-    if (vfs_path_element_valid (path_element) && (*path_element->path != '\0'))
+    if (vfs_path_element_valid (path_element))
     {
-        char *p;
-        p = strchr (path_element->path, 0) - 1;
-        if (*p == PATH_SEP && p > path_element->path)
-            *p = 0;
+        if (*path_element->path != '\0')
+        {
+            char *p;
+
+            p = strchr (path_element->path, 0) - 1;
+            if (p != NULL && *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);
+                }
+            }
+        }
+#endif /* ENABLE_VFS_NET */
+
     }
     return 0;
 

+ 29 - 0
lib/vfs/path.c

@@ -1440,6 +1440,35 @@ vfs_path_build_url_params_str (const vfs_path_element_t * element, gboolean keep
     return g_string_free (buffer, FALSE);
 }
 
+/* --------------------------------------------------------------------------------------------- */
+/**
+ * Build pretty string representation of one path_element_t object
+ *
+ * @param element path element
+ *
+ * @return newly allocated string
+ */
+
+char *
+vfs_path_element_build_pretty_path_str (const vfs_path_element_t * element)
+{
+    char *url_params;
+    GString *pretty_path;
+
+    pretty_path = g_string_new (element->class->prefix);
+    g_string_append (pretty_path, VFS_PATH_URL_DELIMITER);
+
+    url_params = vfs_path_build_url_params_str (element, FALSE);
+    g_string_append (pretty_path, url_params);
+    g_free (url_params);
+
+    if (*element->path != PATH_SEP)
+        g_string_append_c (pretty_path, PATH_SEP);
+
+    g_string_append (pretty_path, element->path);
+    return g_string_free (pretty_path, FALSE);
+}
+
 /* --------------------------------------------------------------------------------------------- */
 /**
  * Compare two path objects as strings

+ 2 - 0
lib/vfs/path.h

@@ -83,6 +83,8 @@ char *vfs_path_serialize (const vfs_path_t * vpath, GError ** error);
 vfs_path_t *vfs_path_deserialize (const char *data, GError ** error);
 
 char *vfs_path_build_url_params_str (const vfs_path_element_t * element, gboolean keep_password);
+char *vfs_path_element_build_pretty_path_str (const vfs_path_element_t * element);
+
 size_t vfs_path_len (const vfs_path_t * vpath);
 int vfs_path_cmp (const vfs_path_t * vpath1, const vfs_path_t * vpath2);
 int vfs_path_ncmp (const vfs_path_t * vpath1, const vfs_path_t * vpath2, size_t len);

+ 1 - 21
src/vfs/fish/fish.c

@@ -403,18 +403,6 @@ fish_info (struct vfs_class *me, struct vfs_s_super *super)
 }
 
 
-/* --------------------------------------------------------------------------------------------- */
-/* The returned directory should always contain a trailing slash */
-
-static char *
-fish_getcwd (struct vfs_class *me, struct vfs_s_super *super)
-{
-    if (fish_command (me, super, WANT_STRING, "#PWD\npwd; echo '### 200'\n") == COMPLETE)
-        return g_strconcat (reply_str, "/", (char *) NULL);
-    ERRNOR (EIO, NULL);
-}
-
-
 /* --------------------------------------------------------------------------------------------- */
 
 static void
@@ -555,8 +543,6 @@ fish_open_archive_int (struct vfs_class *me, struct vfs_s_super *super)
     if (fish_info (me, super))
         SUP->scr_env = fish_set_env (SUP->host_flags);
 
-    vfs_print_message (_("fish: Setting up current directory..."));
-    super->path_element->path = fish_getcwd (me, super);
     vfs_print_message (_("fish: Connected, home %s."), super->path_element->path);
 #if 0
     super->name =
@@ -843,8 +829,6 @@ fish_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path)
     reply_code = fish_decode_reply (buffer + 4, 0);
     if (reply_code == COMPLETE)
     {
-        g_free (super->path_element->path);
-        super->path_element->path = g_strdup (remote_path);
         vfs_print_message (_("%s: done."), me->name);
         return 0;
     }
@@ -1584,11 +1568,7 @@ fish_fill_names (struct vfs_class *me, fill_names_f func)
             }
             break;
         }
-
-        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);
+        name = vfs_path_element_build_pretty_path_str (super->path_element);
         func (name);
         g_free (name);
     }

+ 1 - 64
src/vfs/ftpfs/ftpfs.c

@@ -262,7 +262,6 @@ static const char *netrcp;
    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,
@@ -961,10 +960,6 @@ ftpfs_open_archive_int (struct vfs_class *me, struct vfs_s_super *super)
     }
     while (retry_seconds != 0);
 
-    super->path_element->path = ftpfs_get_current_directory (me, super);
-    if (super->path_element->path == NULL)
-        super->path_element->path = g_strdup (PATH_SEP_STR);
-
     return 0;
 }
 
@@ -1016,57 +1011,6 @@ ftpfs_archive_same (const vfs_path_element_t * vpath_element, struct vfs_s_super
     return result;
 }
 
-/* --------------------------------------------------------------------------------------------- */
-/* 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[BUF_8K], *bufp, *bufq;
-
-    if (ftpfs_command (me, super, NONE, "PWD") == COMPLETE &&
-        ftpfs_get_reply (me, SUP->sock, buf, sizeof (buf)) == COMPLETE)
-    {
-        bufp = NULL;
-        for (bufq = buf; *bufq; bufq++)
-            if (*bufq == '"')
-            {
-                if (!bufp)
-                {
-                    bufp = bufq + 1;
-                }
-                else
-                {
-                    *bufq = 0;
-                    if (*bufp)
-                    {
-                        if (*(bufq - 1) != '/')
-                        {
-                            *bufq++ = '/';
-                            *bufq = 0;
-                        }
-                        if (*bufp == '/')
-                            return g_strdup (bufp);
-                        else
-                        {
-                            /* 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);
-                        }
-                    }
-                    else
-                    {
-                        ftpfs_errno = EIO;
-                        return NULL;
-                    }
-                }
-            }
-    }
-    ftpfs_errno = EIO;
-    return NULL;
-}
-
 /* --------------------------------------------------------------------------------------------- */
 /* Setup Passive PASV FTP connection */
 
@@ -2070,11 +2014,7 @@ ftpfs_chdir_internal (struct vfs_class *me, struct vfs_s_super *super, const cha
     if (r != COMPLETE)
         ftpfs_errno = EIO;
     else
-    {
-        g_free (super->path_element->path);
-        super->path_element->path = g_strdup (remote_path);
         SUP->cwd_deferred = 0;
-    }
     return r;
 }
 
@@ -2247,10 +2187,7 @@ ftpfs_fill_names (struct vfs_class *me, fill_names_f func)
         const struct vfs_s_super *super = (const struct vfs_s_super *) iter->data;
         char *name;
 
-        name =
-            g_strconcat (vfs_ftpfs_ops.prefix, VFS_PATH_URL_DELIMITER, super->path_element->user,
-                         "@", super->path_element->host, "/", super->path_element->path,
-                         (char *) NULL);
+        name = vfs_path_element_build_pretty_path_str (super->path_element);
         func (name);
         g_free (name);
     }