dba8a8
diff --git a/src/ftp.c b/src/ftp.c
dba8a8
index 2be2c76..345718f 100644
dba8a8
--- a/src/ftp.c
dba8a8
+++ b/src/ftp.c
dba8a8
@@ -234,14 +234,15 @@ print_length (wgint size, wgint start, bool authoritative)
dba8a8
   logputs (LOG_VERBOSE, !authoritative ? _(" (unauthoritative)\n") : "\n");
dba8a8
 }
dba8a8
 
dba8a8
-static uerr_t ftp_get_listing (struct url *, ccon *, struct fileinfo **);
dba8a8
+static uerr_t ftp_get_listing (struct url *, struct url *, ccon *, struct fileinfo **);
dba8a8
 
dba8a8
 /* Retrieves a file with denoted parameters through opening an FTP
dba8a8
    connection to the server.  It always closes the data connection,
dba8a8
    and closes the control connection in case of error.  If warc_tmp
dba8a8
    is non-NULL, the downloaded data will be written there as well.  */
dba8a8
 static uerr_t
dba8a8
-getftp (struct url *u, wgint passed_expected_bytes, wgint *qtyread,
dba8a8
+getftp (struct url *u, struct url *original_url,
dba8a8
+        wgint passed_expected_bytes, wgint *qtyread,
dba8a8
         wgint restval, ccon *con, int count, FILE *warc_tmp)
dba8a8
 {
dba8a8
   int csock, dtsock, local_sock, res;
dba8a8
@@ -944,7 +945,7 @@ Error in server response, closing control connection.\n"));
dba8a8
 	  bool exists = false;
dba8a8
 	  uerr_t res;
dba8a8
 	  struct fileinfo *f;
dba8a8
-	  res = ftp_get_listing (u, con, &f);
dba8a8
+	  res = ftp_get_listing (u, original_url, con, &f);
dba8a8
 	  /* Set the DO_RETR command flag again, because it gets unset when
dba8a8
 	     calling ftp_get_listing() and would otherwise cause an assertion
dba8a8
 	     failure earlier on when this function gets repeatedly called
dba8a8
@@ -1392,7 +1393,8 @@ Error in server response, closing control connection.\n"));
dba8a8
    This loop either gets commands from con, or (if ON_YOUR_OWN is
dba8a8
    set), makes them up to retrieve the file given by the URL.  */
dba8a8
 static uerr_t
dba8a8
-ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_file)
dba8a8
+ftp_loop_internal (struct url *u, struct url *original_url, struct fileinfo *f,
dba8a8
+        ccon *con, char **local_file)
dba8a8
 {
dba8a8
   int count, orig_lp;
dba8a8
   wgint restval, len = 0, qtyread = 0;
dba8a8
@@ -1415,7 +1417,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_fi
dba8a8
   else
dba8a8
     {
dba8a8
       /* URL-derived file.  Consider "-O file" name. */
dba8a8
-      con->target = url_file_name (u, NULL);
dba8a8
+      con->target = url_file_name (opt.trustservernames || !original_url ? u : original_url, NULL);
dba8a8
       if (!opt.output_document)
dba8a8
         locf = con->target;
dba8a8
       else
dba8a8
@@ -1524,7 +1526,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_fi
dba8a8
 
dba8a8
       /* If we are working on a WARC record, getftp should also write
dba8a8
          to the warc_tmp file. */
dba8a8
-      err = getftp (u, len, &qtyread, restval, con, count, warc_tmp);
dba8a8
+      err = getftp (u, original_url, len, &qtyread, restval, con, count, warc_tmp);
dba8a8
 
dba8a8
       if (con->csock == -1)
dba8a8
         con->st &= ~DONE_CWD;
dba8a8
@@ -1677,7 +1679,8 @@ Removing file due to --delete-after in ftp_loop_internal():\n"));
dba8a8
 /* Return the directory listing in a reusable format.  The directory
dba8a8
    is specifed in u->dir.  */
dba8a8
 static uerr_t
dba8a8
-ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
dba8a8
+ftp_get_listing (struct url *u, struct url *original_url, ccon *con,
dba8a8
+                 struct fileinfo **f)
dba8a8
 {
dba8a8
   uerr_t err;
dba8a8
   char *uf;                     /* url file name */
dba8a8
@@ -1698,7 +1701,7 @@ ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
dba8a8
 
dba8a8
   con->target = xstrdup (lf);
dba8a8
   xfree (lf);
dba8a8
-  err = ftp_loop_internal (u, NULL, con, NULL);
dba8a8
+  err = ftp_loop_internal (u, original_url, NULL, con, NULL);
dba8a8
   lf = xstrdup (con->target);
dba8a8
   xfree (con->target);
dba8a8
   con->target = old_target;
dba8a8
@@ -1721,8 +1724,9 @@ ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
dba8a8
   return err;
dba8a8
 }
dba8a8
 
dba8a8
-static uerr_t ftp_retrieve_dirs (struct url *, struct fileinfo *, ccon *);
dba8a8
-static uerr_t ftp_retrieve_glob (struct url *, ccon *, int);
dba8a8
+static uerr_t ftp_retrieve_dirs (struct url *, struct url *,
dba8a8
+                                 struct fileinfo *, ccon *);
dba8a8
+static uerr_t ftp_retrieve_glob (struct url *, struct url *, ccon *, int);
dba8a8
 static struct fileinfo *delelement (struct fileinfo *, struct fileinfo **);
dba8a8
 static void freefileinfo (struct fileinfo *f);
dba8a8
 
dba8a8
@@ -1734,7 +1738,8 @@ static void freefileinfo (struct fileinfo *f);
dba8a8
    If opt.recursive is set, after all files have been retrieved,
dba8a8
    ftp_retrieve_dirs will be called to retrieve the directories.  */
dba8a8
 static uerr_t
dba8a8
-ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
dba8a8
+ftp_retrieve_list (struct url *u, struct url *original_url,
dba8a8
+                   struct fileinfo *f, ccon *con)
dba8a8
 {
dba8a8
   static int depth = 0;
dba8a8
   uerr_t err;
dba8a8
@@ -1893,7 +1898,9 @@ Already have correct symlink %s -> %s\n\n"),
dba8a8
           else                /* opt.retr_symlinks */
dba8a8
             {
dba8a8
               if (dlthis)
dba8a8
-                err = ftp_loop_internal (u, f, con, NULL);
dba8a8
+                {
dba8a8
+                  err = ftp_loop_internal (u, original_url, f, con, NULL);
dba8a8
+                }
dba8a8
             } /* opt.retr_symlinks */
dba8a8
           break;
dba8a8
         case FT_DIRECTORY:
dba8a8
@@ -1904,7 +1911,9 @@ Already have correct symlink %s -> %s\n\n"),
dba8a8
         case FT_PLAINFILE:
dba8a8
           /* Call the retrieve loop.  */
dba8a8
           if (dlthis)
dba8a8
-            err = ftp_loop_internal (u, f, con, NULL);
dba8a8
+            {
dba8a8
+              err = ftp_loop_internal (u, original_url, f, con, NULL);
dba8a8
+            }
dba8a8
           break;
dba8a8
         case FT_UNKNOWN:
dba8a8
           logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
dba8a8
@@ -1969,7 +1978,7 @@ Already have correct symlink %s -> %s\n\n"),
dba8a8
   /* We do not want to call ftp_retrieve_dirs here */
dba8a8
   if (opt.recursive &&
dba8a8
       !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
dba8a8
-    err = ftp_retrieve_dirs (u, orig, con);
dba8a8
+    err = ftp_retrieve_dirs (u, original_url, orig, con);
dba8a8
   else if (opt.recursive)
dba8a8
     DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
dba8a8
              depth, opt.reclevel));
dba8a8
@@ -1982,7 +1991,8 @@ Already have correct symlink %s -> %s\n\n"),
dba8a8
    ftp_retrieve_glob on each directory entry.  The function knows
dba8a8
    about excluded directories.  */
dba8a8
 static uerr_t
dba8a8
-ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
dba8a8
+ftp_retrieve_dirs (struct url *u, struct url *original_url,
dba8a8
+                   struct fileinfo *f, ccon *con)
dba8a8
 {
dba8a8
   char *container = NULL;
dba8a8
   int container_size = 0;
dba8a8
@@ -2032,7 +2042,7 @@ Not descending to %s as it is excluded/not-included.\n"),
dba8a8
       odir = xstrdup (u->dir);  /* because url_set_dir will free
dba8a8
                                    u->dir. */
dba8a8
       url_set_dir (u, newdir);
dba8a8
-      ftp_retrieve_glob (u, con, GLOB_GETALL);
dba8a8
+      ftp_retrieve_glob (u, original_url, con, GLOB_GETALL);
dba8a8
       url_set_dir (u, odir);
dba8a8
       xfree (odir);
dba8a8
 
dba8a8
@@ -2091,14 +2101,15 @@ is_invalid_entry (struct fileinfo *f)
dba8a8
    GLOB_GLOBALL, use globbing; if it's GLOB_GETALL, download the whole
dba8a8
    directory.  */
dba8a8
 static uerr_t
dba8a8
-ftp_retrieve_glob (struct url *u, ccon *con, int action)
dba8a8
+ftp_retrieve_glob (struct url *u, struct url *original_url,
dba8a8
+                   ccon *con, int action)
dba8a8
 {
dba8a8
   struct fileinfo *f, *start;
dba8a8
   uerr_t res;
dba8a8
 
dba8a8
   con->cmd |= LEAVE_PENDING;
dba8a8
 
dba8a8
-  res = ftp_get_listing (u, con, &start;;
dba8a8
+  res = ftp_get_listing (u, original_url, con, &start;;
dba8a8
   if (res != RETROK)
dba8a8
     return res;
dba8a8
   /* First: weed out that do not conform the global rules given in
dba8a8
@@ -2194,7 +2205,7 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
dba8a8
   if (start)
dba8a8
     {
dba8a8
       /* Just get everything.  */
dba8a8
-      res = ftp_retrieve_list (u, start, con);
dba8a8
+      res = ftp_retrieve_list (u, original_url, start, con);
dba8a8
     }
dba8a8
   else
dba8a8
     {
dba8a8
@@ -2210,7 +2221,7 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
dba8a8
         {
dba8a8
           /* Let's try retrieving it anyway.  */
dba8a8
           con->st |= ON_YOUR_OWN;
dba8a8
-          res = ftp_loop_internal (u, NULL, con, NULL);
dba8a8
+          res = ftp_loop_internal (u, original_url, NULL, con, NULL);
dba8a8
           return res;
dba8a8
         }
dba8a8
 
dba8a8
@@ -2230,8 +2241,8 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
dba8a8
    of URL.  Inherently, its capabilities are limited on what can be
dba8a8
    encoded into a URL.  */
dba8a8
 uerr_t
dba8a8
-ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
dba8a8
-          bool recursive, bool glob)
dba8a8
+ftp_loop (struct url *u, struct url *original_url, char **local_file, int *dt,
dba8a8
+          struct url *proxy, bool recursive, bool glob)
dba8a8
 {
dba8a8
   ccon con;                     /* FTP connection */
dba8a8
   uerr_t res;
dba8a8
@@ -2252,16 +2263,17 @@ ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
dba8a8
   if (!*u->file && !recursive)
dba8a8
     {
dba8a8
       struct fileinfo *f;
dba8a8
-      res = ftp_get_listing (u, &con, &f);
dba8a8
+      res = ftp_get_listing (u, original_url, &con, &f);
dba8a8
 
dba8a8
       if (res == RETROK)
dba8a8
         {
dba8a8
           if (opt.htmlify && !opt.spider)
dba8a8
             {
dba8a8
+              struct url *url_file = opt.trustservernames ? u : original_url;
dba8a8
               char *filename = (opt.output_document
dba8a8
                                 ? xstrdup (opt.output_document)
dba8a8
                                 : (con.target ? xstrdup (con.target)
dba8a8
-                                   : url_file_name (u, NULL)));
dba8a8
+                                   : url_file_name (url_file, NULL)));
dba8a8
               res = ftp_index (filename, u, f);
dba8a8
               if (res == FTPOK && opt.verbose)
dba8a8
                 {
dba8a8
@@ -2306,11 +2318,13 @@ ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
dba8a8
           /* ftp_retrieve_glob is a catch-all function that gets called
dba8a8
              if we need globbing, time-stamping, recursion or preserve
dba8a8
              permissions.  Its third argument is just what we really need.  */
dba8a8
-          res = ftp_retrieve_glob (u, &con,
dba8a8
+          res = ftp_retrieve_glob (u, original_url, &con,
dba8a8
                                    ispattern ? GLOB_GLOBALL : GLOB_GETONE);
dba8a8
         }
dba8a8
       else
dba8a8
-        res = ftp_loop_internal (u, NULL, &con, local_file);
dba8a8
+        {
dba8a8
+          res = ftp_loop_internal (u, original_url, NULL, &con, local_file);
dba8a8
+        }
dba8a8
     }
dba8a8
   if (res == FTPOK)
dba8a8
     res = RETROK;
dba8a8
diff --git a/src/ftp.h b/src/ftp.h
dba8a8
index be00d88..2abc9c0 100644
dba8a8
--- a/src/ftp.h
dba8a8
+++ b/src/ftp.h
dba8a8
@@ -129,7 +129,8 @@ enum wget_ftp_fstatus
dba8a8
 };
dba8a8
 
dba8a8
 struct fileinfo *ftp_parse_ls (const char *, const enum stype);
dba8a8
-uerr_t ftp_loop (struct url *, char **, int *, struct url *, bool, bool);
dba8a8
+uerr_t ftp_loop (struct url *, struct url *, char **, int *, struct url *,
dba8a8
+                 bool, bool);
dba8a8
 
dba8a8
 uerr_t ftp_index (const char *, struct url *, struct fileinfo *);
dba8a8
 
dba8a8
diff --git a/src/retr.c b/src/retr.c
dba8a8
index 66624dc..21fad56 100644
dba8a8
--- a/src/retr.c
dba8a8
+++ b/src/retr.c
dba8a8
@@ -794,7 +794,8 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
dba8a8
       if (redirection_count)
dba8a8
         oldrec = glob = false;
dba8a8
 
dba8a8
-      result = ftp_loop (u, &local_file, dt, proxy_url, recursive, glob);
dba8a8
+      result = ftp_loop (u, orig_parsed, &local_file, dt, proxy_url,
dba8a8
+                         recursive, glob);
dba8a8
       recursive = oldrec;
dba8a8
 
dba8a8
       /* There is a possibility of having HTTP being redirected to