Index: wget-1.11.4/src/ftp.c
===================================================================
--- wget-1.11.4.orig/src/ftp.c
+++ wget-1.11.4/src/ftp.c
@@ -1083,7 +1083,7 @@ Error in server response, closing contro
    This loop either gets commands from con, or (if ON_YOUR_OWN is
    set), makes them up to retrieve the file given by the URL.  */
 static uerr_t
-ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
+ftp_loop_internal (struct url *u, struct url *original_url, struct fileinfo *f, ccon *con)
 {
   int count, orig_lp;
   wgint restval, len = 0, qtyread = 0;
@@ -1093,7 +1093,7 @@ ftp_loop_internal (struct url *u, struct
   struct_stat st;
 
   if (!con->target)
-    con->target = url_file_name (u);
+    con->target = url_file_name (!original_url ? u : original_url);
 
   /* If the output_document was given, then this check was already done and
      the file didn't exist. Hence the !opt.output_document */
@@ -1308,7 +1308,7 @@ Removing file due to --delete-after in f
 /* Return the directory listing in a reusable format.  The directory
    is specifed in u->dir.  */
 static uerr_t
-ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
+ftp_get_listing (struct url *u, struct url *original_url, ccon *con, struct fileinfo **f)
 {
   uerr_t err;
   char *uf;                     /* url file name */
@@ -1328,7 +1328,7 @@ ftp_get_listing (struct url *u, ccon *co
   DEBUGP ((_("Using `%s' as listing tmp file.\n"), lf));
 
   con->target = lf;
-  err = ftp_loop_internal (u, NULL, con);
+  err = ftp_loop_internal (u, original_url, NULL, con);
   con->target = old_target;
 
   if (err == RETROK)
@@ -1347,8 +1347,8 @@ ftp_get_listing (struct url *u, ccon *co
   return err;
 }
 
-static uerr_t ftp_retrieve_dirs (struct url *, struct fileinfo *, ccon *);
-static uerr_t ftp_retrieve_glob (struct url *, ccon *, int);
+static uerr_t ftp_retrieve_dirs (struct url *, struct url *, struct fileinfo *, ccon *);
+static uerr_t ftp_retrieve_glob (struct url *, struct url *, ccon *, int);
 static struct fileinfo *delelement (struct fileinfo *, struct fileinfo **);
 static void freefileinfo (struct fileinfo *f);
 
@@ -1360,7 +1360,7 @@ static void freefileinfo (struct fileinf
    If opt.recursive is set, after all files have been retrieved,
    ftp_retrieve_dirs will be called to retrieve the directories.  */
 static uerr_t
-ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
+ftp_retrieve_list (struct url *u, struct url *original_url, struct fileinfo *f, ccon *con)
 {
   static int depth = 0;
   uerr_t err;
@@ -1517,7 +1517,7 @@ Already have correct symlink %s -> %s\n\
           else                /* opt.retr_symlinks */
             {
               if (dlthis)
-                err = ftp_loop_internal (u, f, con);
+                err = ftp_loop_internal (u, original_url, f, con);
             } /* opt.retr_symlinks */
           break;
         case FT_DIRECTORY:
@@ -1528,7 +1528,7 @@ Already have correct symlink %s -> %s\n\
         case FT_PLAINFILE:
           /* Call the retrieve loop.  */
           if (dlthis)
-            err = ftp_loop_internal (u, f, con);
+            err = ftp_loop_internal (u, original_url, f, con);
           break;
         case FT_UNKNOWN:
           logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
@@ -1584,7 +1584,7 @@ Already have correct symlink %s -> %s\n\
   /* We do not want to call ftp_retrieve_dirs here */
   if (opt.recursive &&
       !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
-    err = ftp_retrieve_dirs (u, orig, con);
+    err = ftp_retrieve_dirs (u, original_url, orig, con);
   else if (opt.recursive)
     DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
              depth, opt.reclevel));
@@ -1597,7 +1597,7 @@ Already have correct symlink %s -> %s\n\
    ftp_retrieve_glob on each directory entry.  The function knows
    about excluded directories.  */
 static uerr_t
-ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
+ftp_retrieve_dirs (struct url *u, struct url *original_url, struct fileinfo *f, ccon *con)
 {
   char *container = NULL;
   int container_size = 0;
@@ -1647,7 +1647,7 @@ Not descending to `%s' as it is excluded
       odir = xstrdup (u->dir);  /* because url_set_dir will free
                                    u->dir. */
       url_set_dir (u, newdir);
-      ftp_retrieve_glob (u, con, GLOB_GETALL);
+      ftp_retrieve_glob (u, original_url, con, GLOB_GETALL);
       url_set_dir (u, odir);
       xfree (odir);
 
@@ -1683,14 +1683,14 @@ has_insecure_name_p (const char *s)
    GLOB_GLOBALL, use globbing; if it's GLOB_GETALL, download the whole
    directory.  */
 static uerr_t
-ftp_retrieve_glob (struct url *u, ccon *con, int action)
+ftp_retrieve_glob (struct url *u, struct url *original_url, ccon *con, int action)
 {
   struct fileinfo *f, *start;
   uerr_t res;
 
   con->cmd |= LEAVE_PENDING;
 
-  res = ftp_get_listing (u, con, &start);
+  res = ftp_get_listing (u, original_url, con, &start);
   if (res != RETROK)
     return res;
   /* First: weed out that do not conform the global rules given in
@@ -1771,7 +1771,7 @@ ftp_retrieve_glob (struct url *u, ccon *
   if (start)
     {
       /* Just get everything.  */
-      ftp_retrieve_list (u, start, con);
+      ftp_retrieve_list (u, original_url, start, con);
     }
   else
     {
@@ -1787,7 +1787,7 @@ ftp_retrieve_glob (struct url *u, ccon *
         {
           /* Let's try retrieving it anyway.  */
           con->st |= ON_YOUR_OWN;
-          res = ftp_loop_internal (u, NULL, con);
+          res = ftp_loop_internal (u, original_url, NULL, con);
           return res;
         }
     }
@@ -1803,7 +1803,8 @@ ftp_retrieve_glob (struct url *u, ccon *
    of URL.  Inherently, its capabilities are limited on what can be
    encoded into a URL.  */
 uerr_t
-ftp_loop (struct url *u, int *dt, struct url *proxy, bool recursive, bool glob)
+ftp_loop (struct url *u, struct url *original_url, int *dt, struct url *proxy,
+          bool recursive, bool glob)
 {
   ccon con;                     /* FTP connection */
   uerr_t res;
@@ -1824,7 +1825,7 @@ ftp_loop (struct url *u, int *dt, struct
   if (!*u->file && !recursive)
     {
       struct fileinfo *f;
-      res = ftp_get_listing (u, &con, &f);
+      res = ftp_get_listing (u, original_url, &con, &f);
 
       if (res == RETROK)
         {
@@ -1878,11 +1879,11 @@ ftp_loop (struct url *u, int *dt, struct
           /* ftp_retrieve_glob is a catch-all function that gets called
              if we need globbing, time-stamping or recursion.  Its
              third argument is just what we really need.  */
-          res = ftp_retrieve_glob (u, &con,
+          res = ftp_retrieve_glob (u, original_url, &con,
                                    ispattern ? GLOB_GLOBALL : GLOB_GETONE);
         }
       else
-        res = ftp_loop_internal (u, NULL, &con);
+        res = ftp_loop_internal (u, original_url, NULL, &con);
     }
   if (res == FTPOK)
     res = RETROK;
Index: wget-1.11.4/src/ftp.h
===================================================================
--- wget-1.11.4.orig/src/ftp.h
+++ wget-1.11.4/src/ftp.h
@@ -120,7 +120,7 @@ enum wget_ftp_fstatus
 };
 
 struct fileinfo *ftp_parse_ls (const char *, const enum stype);
-uerr_t ftp_loop (struct url *, int *, struct url *, bool, bool);
+uerr_t ftp_loop (struct url *, struct url *, int *, struct url *, bool, bool);
 
 uerr_t ftp_index (const char *, struct url *, struct fileinfo *);
 
Index: wget-1.11.4/src/retr.c
===================================================================
--- wget-1.11.4.orig/src/retr.c
+++ wget-1.11.4/src/retr.c
@@ -596,7 +596,8 @@ static char *getproxy (struct url *);
    multiple points. */
 
 uerr_t
-retrieve_url (const char *origurl, char **file, char **newloc,
+retrieve_url (struct url *parsed_url, const char *origurl,
+              char **file, char **newloc,
               const char *refurl, int *dt, bool recursive)
 {
   uerr_t result;
@@ -683,7 +684,7 @@ retrieve_url (const char *origurl, char
       if (redirection_count)
         oldrec = glob = false;
 
-      result = ftp_loop (u, dt, proxy_url, recursive, glob);
+      result = ftp_loop (u, parsed_url, dt, proxy_url, recursive, glob);
       recursive = oldrec;
 
       /* There is a possibility of having HTTP being redirected to
@@ -829,6 +830,7 @@ retrieve_from_file (const char *file, bo
     {
       char *filename = NULL, *new_file = NULL;
       int dt;
+      struct url *parsed_url = NULL;
 
       if (cur_url->ignore_when_downloading)
         continue;
@@ -838,6 +840,9 @@ retrieve_from_file (const char *file, bo
           status = QUOTEXC;
           break;
         }
+
+      parsed_url = url_parse (cur_url->url->url, NULL);
+
       if ((opt.recursive || opt.page_requisites)
           && (cur_url->url->scheme != SCHEME_FTP || getproxy (cur_url->url)))
         {
@@ -852,7 +857,11 @@ retrieve_from_file (const char *file, bo
           opt.follow_ftp = old_follow_ftp;
         }
       else
-        status = retrieve_url (cur_url->url->url, &filename, &new_file, NULL, &dt, opt.recursive);
+        status = retrieve_url (parsed_url ? parsed_url : cur_url->url,
+                               cur_url->url->url, &filename,
+                               &new_file, NULL, &dt, opt.recursive);
+
+      url_free (parsed_url);
 
       if (filename && opt.delete_after && file_exists_p (filename))
         {
Index: wget-1.11.4/src/main.c
===================================================================
--- wget-1.11.4.orig/src/main.c
+++ wget-1.11.4/src/main.c
@@ -1001,7 +1001,18 @@ for details.\n\n"));
   for (t = url; *t; t++)
     {
       char *filename = NULL, *redirected_URL = NULL;
-      int dt;
+      int dt, url_err;
+      struct url *url_parsed;
+
+      url_parsed = url_parse (*t, &url_err);
+
+      if (!url_parsed)
+        {
+          char *error = url_error (url_err);
+          logprintf (LOG_NOTQUIET, "%s: %s.\n",*t, error);
+          xfree (error);
+          status = URLERROR;
+        }
 
       if ((opt.recursive || opt.page_requisites)
           && (url_scheme (*t) != SCHEME_FTP || url_uses_proxy (*t)))
@@ -1017,7 +1028,7 @@ for details.\n\n"));
           opt.follow_ftp = old_follow_ftp;
         }
       else
-        status = retrieve_url (*t, &filename, &redirected_URL, NULL, &dt, opt.recursive);
+        status = retrieve_url (url_parsed, *t, &filename, &redirected_URL, NULL, &dt, opt.recursive);
 
       if (opt.delete_after && file_exists_p(filename))
         {
@@ -1029,6 +1040,7 @@ for details.\n\n"));
 
       xfree_null (redirected_URL);
       xfree_null (filename);
+      url_free (url_parsed);
     }
 
   /* And then from the input file, if any.  */
Index: wget-1.11.4/src/recur.c
===================================================================
--- wget-1.11.4.orig/src/recur.c
+++ wget-1.11.4/src/recur.c
@@ -246,10 +246,11 @@ retrieve_tree (const char *start_url)
         }
       else
         {
-          int dt = 0;
+          int dt = 0, url_err;
           char *redirected = NULL;
+          struct url *url_parsed = url_parse (url, &url_err);
 
-          status = retrieve_url (url, &file, &redirected, referer, &dt, false);
+          status = retrieve_url (url_parsed, url, &file, &redirected, referer, &dt, false);
 
           if (html_allowed && file && status == RETROK
               && (dt & RETROKF) && (dt & TEXTHTML))
@@ -274,6 +275,7 @@ retrieve_tree (const char *start_url)
               xfree (url);
               url = redirected;
             }
+          url_free(url_parsed);
         }
 
       if (opt.spider)
Index: wget-1.11.4/src/res.c
===================================================================
--- wget-1.11.4.orig/src/res.c
+++ wget-1.11.4/src/res.c
@@ -540,13 +540,27 @@ res_retrieve_file (const char *url, char
   uerr_t err;
   char *robots_url = uri_merge (url, RES_SPECS_LOCATION);
   int saved_ts_val = opt.timestamping;
-  int saved_sp_val = opt.spider;
+  int saved_sp_val = opt.spider, url_err;
+  struct url * url_parsed;
 
   logputs (LOG_VERBOSE, _("Loading robots.txt; please ignore errors.\n"));
   *file = NULL;
   opt.timestamping = false;
   opt.spider       = false;
-  err = retrieve_url (robots_url, file, NULL, NULL, NULL, false);
+  url_parsed = url_parse (robots_url, &url_err);
+  if (!url_parsed)
+    {
+      char *error = url_error (url_err);
+      logprintf (LOG_NOTQUIET, "%s: %s.\n", robots_url, error);
+      xfree (error);
+      err = URLERROR;
+    }
+  else
+  {
+    err = retrieve_url (url_parsed, robots_url, file, NULL, NULL, NULL, false);
+    url_free(url_parsed);
+  }
+
   opt.timestamping = saved_ts_val;
   opt.spider       = saved_sp_val;  
   xfree (robots_url);
Index: wget-1.11.4/src/retr.h
===================================================================
--- wget-1.11.4.orig/src/retr.h
+++ wget-1.11.4/src/retr.h
@@ -31,6 +31,8 @@ as that of the covered work.  */
 #ifndef RETR_H
 #define RETR_H
 
+#include "url.h"
+
 /* These global vars should be made static to retr.c and exported via
    functions! */
 extern SUM_SIZE_INT total_downloaded_bytes;
@@ -51,7 +53,7 @@ typedef const char *(*hunk_terminator_t)
 char *fd_read_hunk (int, hunk_terminator_t, long, long);
 char *fd_read_line (int);
 
-uerr_t retrieve_url (const char *, char **, char **, const char *, int *, bool);
+uerr_t retrieve_url (struct url *, const char *, char **, char **, const char *, int *, bool);
 uerr_t retrieve_from_file (const char *, bool, int *);
 
 const char *retr_rate (wgint, double);
