diff --git a/src/ChangeLog b/src/ChangeLog
index 29af7226..81cc52a7 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,16 @@
+2001-04-11  Hrvoje Niksic  <hniksic@arsdigita.com>
+
+	* url.c (parseurl): Don't strip trailing slash when u->dir is "/"
+	because that strips the *leading* slash, thus forcing relative
+	FTP retrieval.
+
+2001-04-10  Jan Prikryl  <prikryl@cg.tuwien.ac.at>
+
+	* ftp.c (getftp): Convert initial FTP directory from VMS to UNIX
+	notation for VMS servers. 
+	(ftp_retrieve_dirs): Do not prepend '/' to f->name when
+	odir is an empty string.
+
 2001-04-10  Jan Prikryl  <prikryl@cg.tuwien.ac.at>
 
 	* ftp-ls.c (ftp_parse_winnt_ls): Made the fix for AM/PM more
diff --git a/src/ftp.c b/src/ftp.c
index c7f9274d..bf50ab32 100644
--- a/src/ftp.c
+++ b/src/ftp.c
@@ -298,6 +298,29 @@ Error in server response, closing control connection.\n"));
 	  abort ();
 	  break;
 	}
+      /* VMS will report something like "PUB$DEVICE:[INITIAL.FOLDER]".
+         Convert it to "/INITIAL/FOLDER" */ 
+      if (con->rs == ST_VMS)
+        {
+          char *path = strchr (con->id, '[');
+	  char *pathend = path ? strchr (path + 1, ']') : NULL;
+	  if (!path || !pathend)
+	    DEBUGP (("Initial VMS directory not in the form [...]!\n"));
+	  else
+	    {
+	      char *idir = con->id;
+	      DEBUGP (("Preprocessing the initial VMS directory\n"));
+	      DEBUGP (("  old = '%s'\n", con->id));
+	      /* We do the conversion in-place by copying the stuff
+		 between [ and ] to the beginning, and changing dots
+		 to slashes at the same time.  */
+	      *idir++ = '/';
+	      for (++path; path < pathend; path++, idir++)
+		*idir = *path == '.' ? '/' : *path;
+	      *idir = '\0';
+	      DEBUGP (("  new = '%s'\n\n", con->id));
+	    }
+	}
       if (!opt.server_response)
 	logputs (LOG_VERBOSE, _("done.\n"));
 
@@ -361,19 +384,27 @@ Error in server response, closing control connection.\n"));
 	    {
 	      int idlen = strlen (con->id);
 	      char *ntarget = (char *)alloca (idlen + 1 + strlen (u->dir) + 1);
-	      /* pwd_len == 1 means pwd = "/" */
+	      /* idlen == 1 means con->id = "/" */
 	      sprintf (ntarget, "%s%s%s", con->id, idlen == 1 ? "" : "/",
 		       target);
+              DEBUGP (("Prepended initial PWD to relative path:\n"));
+              DEBUGP (("  old: '%s'\n  new: '%s'\n", target, ntarget));
 	      target = ntarget;
 	    }
 
-	  /* If the FTP host runs VMS, we will have to convert it to
-	     VMS style as VMS does not like leading slashes.  "VMS
-	     style" is [dir.subdir.subsubdir].  */
+	  /* If the FTP host runs VMS, we will have to convert the absolute
+             directory path in UNIX notation to absolute directory path in
+             VMS notation as VMS FTP servers do not like UNIX notation of
+             absolute paths.  "VMS notation" is [dir.subdir.subsubdir]. */
+
 	  if (con->rs == ST_VMS)
 	    {
 	      char *tmpp;
-	      char *ntarget = (char *)alloca (strlen (target) + 1);
+	      char *ntarget = (char *)alloca (strlen (target) + 2);
+	      /* We use a converted initial dir, so directories in
+                 TARGET will be separated with slashes, something like
+                 "/INITIAL/FOLDER/DIR/SUBDIR".  Convert that to
+                 "[INITIAL.FOLDER.DIR.SUBDIR]".  */
 	      strcpy (ntarget, target);
 	      assert (*ntarget == '/');
 	      *ntarget = '[';
@@ -382,6 +413,8 @@ Error in server response, closing control connection.\n"));
 		  *tmpp = '.';
 	      *tmpp++ = ']';
 	      *tmpp = '\0';
+              DEBUGP (("Changed file name to VMS syntax:\n"));
+              DEBUGP (("  Unix: '%s'\n  VMS: '%s'\n", target, ntarget));
 	      target = ntarget;
 	    }
 
@@ -1460,8 +1493,18 @@ ftp_retrieve_dirs (struct urlinfo *u, struct fileinfo *f, ccon *con)
       if (len > current_length)
 	current_container = (char *)alloca (len);
       u->dir = current_container;
-      sprintf (u->dir, "%s%s%s", odir,
-	       (*odir == '/' && !*(odir + 1)) ? "" : "/", f->name);
+      if (*odir == '\0'
+	  || (*odir == '/' && *(odir + 1) == '\0'))
+	/* If ODIR is empty or just "/", simply append f->name to
+	   ODIR.  (In the former case, to preserve u->dir being
+	   relative; in the latter case, to avoid double slash.)  */
+	sprintf (u->dir, "%s%s", odir, f->name);
+      else
+	/* Else, use a separator. */
+	sprintf (u->dir, "%s/%s", odir, f->name);
+      DEBUGP (("Composing new CWD relative to the initial directory.\n"));
+      DEBUGP (("  odir = '%s'\n  f->name = '%s'\n  u->dir = '%s'\n\n",
+	       odir, f->name, u->dir));
       if (!accdir (u->dir, ALLABS))
 	{
 	  logprintf (LOG_VERBOSE, _("\
diff --git a/src/url.c b/src/url.c
index 7e31e51e..cca3ac96 100644
--- a/src/url.c
+++ b/src/url.c
@@ -514,7 +514,7 @@ parseurl (const char *url, struct urlinfo *u, int strict)
   DEBUGP (("ndir %s\n", u->dir));
   /* Strip trailing `/'.  */
   l = strlen (u->dir);
-  if (l && u->dir[l - 1] == '/')
+  if (l > 1 && u->dir[l - 1] == '/')
     u->dir[l - 1] = '\0';
   /* Re-create the path: */
   abs_ftp = (u->proto == URLFTP && *u->dir == '/');