]> sjero.net Git - wget/blobdiff - src/ftp.c
[svn] Commit IPv6 support by Thomas Lussnig.
[wget] / src / ftp.c
index 5f18c7094824c2cda9fd54d64e05e712ad5da7ca..e02c018b8478daa89ccaa8af299f54b0123ef66e 100644 (file)
--- a/src/ftp.c
+++ b/src/ftp.c
@@ -33,9 +33,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <sys/types.h>
 #include <assert.h>
 #include <errno.h>
-#ifndef WINDOWS
-# include <netdb.h>            /* for h_errno */
-#endif
 
 #include "wget.h"
 #include "utils.h"
@@ -51,11 +48,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #ifndef errno
 extern int errno;
 #endif
-#ifndef h_errno
-# ifndef __CYGWIN__
-extern int h_errno;
-# endif
-#endif
 
 /* File where the "ls -al" listing will be saved.  */
 #define LIST_FILENAME ".listing"
@@ -127,10 +119,8 @@ getftp (struct url *u, long *len, long restval, ccon *con)
   FILE *fp;
   char *user, *passwd, *respline;
   char *tms, *tmrate;
-  struct wget_timer *timer;
-  unsigned char pasv_addr[6];
   int cmd = con->cmd;
-  int passive_mode_open = 0;
+  int pasv_mode_open = 0;
   long expected_bytes = 0L;
 
   assert (con != NULL);
@@ -158,54 +148,33 @@ getftp (struct url *u, long *len, long restval, ccon *con)
   else                         /* cmd & DO_LOGIN */
     {
       char type_char;
+      struct address_list *al;
 
       /* Login to the server: */
 
       /* First: Establish the control connection.  */
-      logprintf (LOG_VERBOSE, _("Connecting to %s:%hu... "), u->host, u->port);
-      err = make_connection (&csock, u->host, u->port);
+
+      al = lookup_host (u->host, 0);
+      if (!al)
+       return HOSTERR;
+      set_connection_host_name (u->host);
+      csock = connect_to_many (al, u->port, 0);
+      set_connection_host_name (NULL);
+      address_list_release (al);
+
+      if (csock < 0)
+       return errno == ECONNREFUSED ? CONREFUSED : CONERROR;
+
       if (cmd & LEAVE_PENDING)
        rbuf_initialize (&con->rbuf, csock);
       else
        rbuf_uninitialize (&con->rbuf);
-      switch (err)
-       {
-         /* Do not close the socket in first several cases, since it
-            wasn't created at all.  */
-       case HOSTERR:
-         logputs (LOG_VERBOSE, "\n");
-         logprintf (LOG_NOTQUIET, "%s: %s\n", u->host, herrmsg (h_errno));
-         return HOSTERR;
-         break;
-       case CONSOCKERR:
-         logputs (LOG_VERBOSE, "\n");
-         logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
-         return CONSOCKERR;
-         break;
-       case CONREFUSED:
-         logputs (LOG_VERBOSE, "\n");
-         logprintf (LOG_NOTQUIET, _("Connection to %s:%hu refused.\n"),
-                    u->host, u->port);
-         CLOSE (csock);
-         rbuf_uninitialize (&con->rbuf);
-         return CONREFUSED;
-       case CONERROR:
-         logputs (LOG_VERBOSE, "\n");
-         logprintf (LOG_NOTQUIET, "connect: %s\n", strerror (errno));
-         CLOSE (csock);
-         rbuf_uninitialize (&con->rbuf);
-         return CONERROR;
-         break;
-       default:
-         DO_NOTHING;
-         /* #### Hmm?  */
-       }
+
       /* Since this is a new connection, we may safely discard
         anything left in the buffer.  */
       rbuf_discard (&con->rbuf);
 
       /* Second: Login with proper USER/PASS sequence.  */
-      logputs (LOG_VERBOSE, _("connected!\n"));
       logprintf (LOG_VERBOSE, _("Logging in as %s ... "), user);
       if (opt.server_response)
        logputs (LOG_ALWAYS, "\n");
@@ -286,7 +255,7 @@ Error in server response, closing control connection.\n"));
          abort ();
          break;
        }
-      if (!opt.server_response)
+      if (!opt.server_response && err != FTPSRVERR)
        logputs (LOG_VERBOSE, _("done.    "));
 
       /* Fourth: Find the initial ftp directory */
@@ -298,7 +267,6 @@ Error in server response, closing control connection.\n"));
       switch (err)
        {
        case FTPRERR:
-       case FTPSRVERR :
          logputs (LOG_VERBOSE, "\n");
          logputs (LOG_NOTQUIET, _("\
 Error in server response, closing control connection.\n"));
@@ -306,6 +274,11 @@ Error in server response, closing control connection.\n"));
          rbuf_uninitialize (&con->rbuf);
          return err;
          break;
+       case FTPSRVERR :
+         /* PWD unsupported -- assume "/". */
+         FREE_MAYBE (con->id);
+         con->id = xstrdup ("/");
+         break;
        case FTPOK:
          /* Everything is OK.  */
          break;
@@ -515,12 +488,11 @@ Error in server response, closing control connection.\n"));
     {
       if (opt.ftp_pasv > 0)
        {
-         char thost[256];
-         unsigned short tport;
-
+         ip_address     passive_addr;
+         unsigned short passive_port;
          if (!opt.server_response)
            logputs (LOG_VERBOSE, "==> PASV ... ");
-         err = ftp_pasv (&con->rbuf, pasv_addr);
+         err = ftp_pasv (&con->rbuf, &passive_addr, &passive_port);
          /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
          switch (err)
            {
@@ -554,62 +526,28 @@ Error in server response, closing control connection.\n"));
            default:
              abort ();
              break;
-           }
+           }   /* switch(err) */
          if (err==FTPOK)
            {
-             sprintf (thost, "%d.%d.%d.%d",
-                      pasv_addr[0], pasv_addr[1], pasv_addr[2], pasv_addr[3]);
-             tport = (pasv_addr[4] << 8) + pasv_addr[5];
-             DEBUGP ((_("Will try connecting to %s:%hu.\n"), thost, tport));
-             err = make_connection (&dtsock, thost, tport);
-             switch (err)
+             dtsock = connect_to_one (&passive_addr, passive_port, 1);
+             if (dtsock < 0)
                {
-                 /* Do not close the socket in first several cases,
-                    since it wasn't created at all.  */
-               case HOSTERR:
-                 logputs (LOG_VERBOSE, "\n");
-                 logprintf (LOG_NOTQUIET, "%s: %s\n", thost,
-                            herrmsg (h_errno));
-                 CLOSE (csock);
-                 rbuf_uninitialize (&con->rbuf);
-                 return HOSTERR;
-                 break;
-               case CONSOCKERR:
-                 logputs (LOG_VERBOSE, "\n");
-                 logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
-                 CLOSE (csock);
-                 rbuf_uninitialize (&con->rbuf);
-                 return CONSOCKERR;
-                 break;
-               case CONREFUSED:
-                 logputs (LOG_VERBOSE, "\n");
-                 logprintf (LOG_NOTQUIET,
-                            _("Connection to %s:%hu refused.\n"),
-                            thost, tport);
-                 CLOSE (csock);
-                 rbuf_uninitialize (&con->rbuf);
-                 closeport (dtsock);
-                 return CONREFUSED;
-               case CONERROR:
-                 logputs (LOG_VERBOSE, "\n");
-                 logprintf (LOG_NOTQUIET, "connect: %s\n",
-                            strerror (errno));
+                 int save_errno = errno;
                  CLOSE (csock);
                  rbuf_uninitialize (&con->rbuf);
-                 closeport (dtsock);
-                 return CONERROR;
-                 break;
-               default:
-                 /* #### What?!  */
-                 DO_NOTHING;
+                 logprintf (LOG_VERBOSE, _("couldn't connect to %s:%hu: %s\n"),
+                            pretty_print_address (&passive_addr), passive_port,
+                            strerror (save_errno));
+                 return save_errno == ECONNREFUSED ? CONREFUSED : CONERROR;
                }
-             passive_mode_open= 1;  /* Flag to avoid accept port */
+
+             pasv_mode_open = 1;  /* Flag to avoid accept port */
              if (!opt.server_response)
                logputs (LOG_VERBOSE, _("done.    "));
            } /* err==FTP_OK */
        }
 
-      if (!passive_mode_open)   /* Try to use a port command if PASV failed */
+      if (!pasv_mode_open)   /* Try to use a port command if PASV failed */
        {
          if (!opt.server_response)
            logputs (LOG_VERBOSE, "==> PORT ... ");
@@ -652,15 +590,6 @@ Error in server response, closing control connection.\n"));
              closeport (dtsock);
              return err;
              break;
-           case HOSTERR:
-             logputs (LOG_VERBOSE, "\n");
-             logprintf (LOG_NOTQUIET, "%s: %s\n", u->host,
-                        herrmsg (h_errno));
-             CLOSE (csock);
-             closeport (dtsock);
-             rbuf_uninitialize (&con->rbuf);
-             return HOSTERR;
-             break;
            case FTPPORTERR:
              logputs (LOG_VERBOSE, "\n");
              logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
@@ -850,7 +779,7 @@ Error in server response, closing control connection.\n"));
   if (!(cmd & (DO_LIST | DO_RETR)))
     return RETRFINISHED;
 
-  if (!passive_mode_open)  /* we are not using pasive mode so we need
+  if (!pasv_mode_open)  /* we are not using pasive mode so we need
                              to accept */
     {
       /* Open the data transmission socket by calling acceptport().  */
@@ -918,13 +847,12 @@ Error in server response, closing control connection.\n"));
                   legible (expected_bytes - restval));
       logputs (LOG_VERBOSE, _(" (unauthoritative)\n"));
     }
-  timer = wtimer_new ();
+
   /* Get the contents of the document.  */
-  res = get_contents (dtsock, fp, len, restval, expected_bytes, &con->rbuf, 0);
-  con->dltime = wtimer_elapsed (timer);
-  wtimer_delete (timer);
+  res = get_contents (dtsock, fp, len, restval, expected_bytes, &con->rbuf,
+                     0, &con->dltime);
   tms = time_str (NULL);
-  tmrate = rate (*len - restval, con->dltime, 0);
+  tmrate = retr_rate (*len - restval, con->dltime, 0);
   /* Close data connection socket.  */
   closeport (dtsock);
   /* Close the local file.  */
@@ -1173,7 +1101,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
        }
       /* Time?  */
       tms = time_str (NULL);
-      tmrate = rate (len - restval, con->dltime, 0);
+      tmrate = retr_rate (len - restval, con->dltime, 0);
 
       /* If we get out of the switch above without continue'ing, we've
         successfully downloaded a file.  Remember this fact. */