]> sjero.net Git - wget/blobdiff - src/ftp.c
[svn] Merge of fix for bugs 20341 and 20410.
[wget] / src / ftp.c
index 0d903d35fcf41ce6c0ba920f92a6b957f4bafe90..2e32c1f03d04b45e9f723706d8e8d7ac1567925d 100644 (file)
--- a/src/ftp.c
+++ b/src/ftp.c
@@ -1,12 +1,11 @@
 /* File Transfer Protocol support.
-   Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001
-   Free Software Foundation, Inc.
+   Copyright (C) 1996-2006 Free Software Foundation, Inc.
 
 This file is part of GNU Wget.
 
 GNU Wget is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
+the Free Software Foundation; either version 3 of the License, or
 (at your option) any later version.
 
 GNU Wget is distributed in the hope that it will be useful,
@@ -15,8 +14,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with Wget; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+along with Wget.  If not, see <http://www.gnu.org/licenses/>.
 
 In addition, as a special exception, the Free Software Foundation
 gives permission to link the code of its release of Wget with the
@@ -38,6 +36,7 @@ so, delete this exception statement from your version.  */
 #endif
 #include <assert.h>
 #include <errno.h>
+#include <time.h>
 
 #include "wget.h"
 #include "utils.h"
@@ -117,14 +116,14 @@ ftp_do_pasv (int csock, ip_address *addr, int *port)
   /* If our control connection is over IPv6, then we first try EPSV and then 
    * LPSV if the former is not supported. If the control connection is over 
    * IPv4, we simply issue the good old PASV request. */
-  switch (addr->type)
+  switch (addr->family)
     {
-    case IPV4_ADDRESS:
+    case AF_INET:
       if (!opt.server_response)
         logputs (LOG_VERBOSE, "==> PASV ... ");
       err = ftp_pasv (csock, addr, port);
       break;
-    case IPV6_ADDRESS:
+    case AF_INET6:
       if (!opt.server_response)
         logputs (LOG_VERBOSE, "==> EPSV ... ");
       err = ftp_epsv (csock, addr, port);
@@ -160,14 +159,14 @@ ftp_do_port (int csock, int *local_sock)
   /* If our control connection is over IPv6, then we first try EPRT and then 
    * LPRT if the former is not supported. If the control connection is over 
    * IPv4, we simply issue the good old PORT request. */
-  switch (cip.type)
+  switch (cip.family)
     {
-    case IPV4_ADDRESS:
+    case AF_INET:
       if (!opt.server_response)
         logputs (LOG_VERBOSE, "==> PORT ... ");
       err = ftp_port (csock, local_sock);
       break;
-    case IPV6_ADDRESS:
+    case AF_INET6:
       if (!opt.server_response)
         logputs (LOG_VERBOSE, "==> EPRT ... ");
       err = ftp_eprt (csock, local_sock);
@@ -651,8 +650,7 @@ Error in server response, closing control connection.\n"));
          if (err==FTPOK)
            {
              DEBUGP (("trying to connect to %s port %d\n", 
-                     pretty_print_address (&passive_addr),
-                     passive_port));
+                     print_address (&passive_addr), passive_port));
              dtsock = connect_to_ip (&passive_addr, passive_port, NULL);
              if (dtsock < 0)
                {
@@ -660,7 +658,7 @@ Error in server response, closing control connection.\n"));
                  fd_close (csock);
                  con->csock = -1;
                  logprintf (LOG_VERBOSE, _("couldn't connect to %s port %d: %s\n"),
-                            pretty_print_address (&passive_addr), passive_port,
+                            print_address (&passive_addr), passive_port,
                             strerror (save_errno));
                  return (retryable_socket_connect_error (save_errno)
                          ? CONERROR : CONIMPOSSIBLE);
@@ -954,7 +952,7 @@ Error in server response, closing control connection.\n"));
   if (*len)
     {
       print_length (*len, restval, true);
-      expected_bytes = *len;   /* for get_contents/show_progress */
+      expected_bytes = *len;   /* for fd_read_body's progress bar */
     }
   else if (expected_bytes)
     print_length (expected_bytes, restval, false);
@@ -969,49 +967,38 @@ Error in server response, closing control connection.\n"));
                      expected_bytes ? expected_bytes - restval : 0,
                      restval, &rd_size, len, &con->dltime, flags);
 
-  tms = time_str (NULL);
+  tms = time_str (time (NULL));
   tmrate = retr_rate (rd_size, con->dltime);
   total_download_time += con->dltime;
 
-  /* Close data connection socket.  */
-  fd_close (dtsock);
   fd_close (local_sock);
   /* Close the local file.  */
-  {
-    /* Close or flush the file.  We have to be careful to check for
-       error here.  Checking the result of fwrite() is not enough --
-       errors could go unnoticed!  */
-    int flush_res;
-    if (!output_stream || con->cmd & DO_LIST)
-      flush_res = fclose (fp);
-    else
-      flush_res = fflush (fp);
-    if (flush_res == EOF)
-      res = -2;
-  }
-
-  /* If get_contents couldn't write to fp, bail out.  */
+  if (!output_stream || con->cmd & DO_LIST)
+    fclose (fp);
+
+  /* If fd_read_body couldn't write to fp, bail out.  */
   if (res == -2)
     {
       logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
                 con->target, strerror (errno));
       fd_close (csock);
       con->csock = -1;
+      fd_close (dtsock);
       return FWRITEERR;
     }
   else if (res == -1)
     {
       logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
-                tms, tmrate, strerror (errno));
+                tms, tmrate, fd_errstr (dtsock));
       if (opt.server_response)
        logputs (LOG_ALWAYS, "\n");
     }
+  fd_close (dtsock);
 
   /* Get the server to tell us if everything is retrieved.  */
   err = ftp_response (csock, &respline);
   if (err != FTPOK)
     {
-      xfree (respline);
       /* The control connection is decidedly closed.  Print the time
         only if it hasn't already been printed.  */
       if (res != -1)
@@ -1068,6 +1055,9 @@ Error in server response, closing control connection.\n"));
             no-buffering on opt.lfile.  */
          while ((line = read_whole_line (fp)) != NULL)
            {
+             char *p = strchr (line, '\0');
+             while (p > line && (p[-1] == '\n' || p[-1] == '\r'))
+               *--p = '\0';
              logprintf (LOG_ALWAYS, "%s\n", escnonprint (line));
              xfree (line);
            }
@@ -1159,7 +1149,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
        restval = 0;
 
       /* Get the current time string.  */
-      tms = time_str (NULL);
+      tms = time_str (time (NULL));
       /* Print fetch message, if opt.verbose.  */
       if (opt.verbose)
        {
@@ -1182,7 +1172,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
        len = 0;
       err = getftp (u, &len, restval, con);
 
-      if (con->csock != -1)
+      if (con->csock == -1)
        con->st &= ~DONE_CWD;
       else
        con->st |= DONE_CWD;
@@ -1223,7 +1213,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
          /* Not as great.  */
          abort ();
        }
-      tms = time_str (NULL);
+      tms = time_str (time (NULL));
       if (!opt.spider)
         tmrate = retr_rate (len - restval, con->dltime);
 
@@ -1431,7 +1421,7 @@ ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
              tml++;
 #endif
               /* Compare file sizes only for servers that tell us correct
-                 values. Assumme sizes being equal for servers that lie
+                 values. Assume sizes being equal for servers that lie
                  about file size.  */
               cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
               eq_size = cor_val ? (local_size == f->size) : true;
@@ -1630,7 +1620,7 @@ ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
       DEBUGP (("Composing new CWD relative to the initial directory.\n"));
       DEBUGP (("  odir = '%s'\n  f->name = '%s'\n  newdir = '%s'\n\n",
               odir, f->name, newdir));
-      if (!accdir (newdir, ALLABS))
+      if (!accdir (newdir))
        {
          logprintf (LOG_VERBOSE, _("\
 Not descending to `%s' as it is excluded/not-included.\n"),
@@ -1723,12 +1713,14 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
      If we are dealing with a globbing pattern, that is.  */
   if (*u->file && (action == GLOB_GLOBALL || action == GLOB_GETONE))
     {
+      int (*matcher) (const char *, const char *, int)
+       = opt.ignore_case ? fnmatch_nocase : fnmatch;
       int matchres = 0;
 
       f = start;
       while (f)
        {
-         matchres = fnmatch (u->file, f->name, 0);
+         matchres = matcher (u->file, f->name, 0);
          if (matchres == -1)
            {
              logprintf (LOG_NOTQUIET, "%s: %s\n", con->target,
@@ -1781,7 +1773,7 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
    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)
+ftp_loop (struct url *u, int *dt, struct url *proxy, bool recursive, bool glob)
 {
   ccon con;                    /* FTP connection */
   uerr_t res;
@@ -1799,7 +1791,7 @@ ftp_loop (struct url *u, int *dt, struct url *proxy)
   /* If the file name is empty, the user probably wants a directory
      index.  We'll provide one, properly HTML-ized.  Unless
      opt.htmlify is 0, of course.  :-) */
-  if (!*u->file && !opt.recursive)
+  if (!*u->file && !recursive)
     {
       struct fileinfo *f;
       res = ftp_get_listing (u, &con, &f);
@@ -1840,7 +1832,7 @@ ftp_loop (struct url *u, int *dt, struct url *proxy)
   else
     {
       bool ispattern = false;
-      if (opt.ftp_glob)
+      if (glob)
        {
          /* Treat the URL as a pattern if the file name part of the
             URL path contains wildcards.  (Don't check for u->file
@@ -1851,7 +1843,7 @@ ftp_loop (struct url *u, int *dt, struct url *proxy)
            file_part = u->path;
          ispattern = has_wildcards_p (file_part);
        }
-      if (ispattern || opt.recursive || opt.timestamping)
+      if (ispattern || recursive || opt.timestamping)
        {
          /* ftp_retrieve_glob is a catch-all function that gets called
             if we need globbing, time-stamping or recursion.  Its