]> sjero.net Git - wget/blobdiff - src/http.c
[svn] Replace conaddr with socket_ip_address.
[wget] / src / http.c
index d4ee74c063f871f3f6480408f0279447ad50e66b..7be33a6343b940e9fedfc66542561888ff9fd82a 100644 (file)
@@ -192,17 +192,13 @@ parse_http_status_line (const char *line, const char **reason_phrase_ptr)
    longer, read only that much; if the file is shorter, report an error.  */
 
 static int
-post_file (int sock, void *ssl, const char *file_name, long promised_size)
+post_file (int sock, const char *file_name, long promised_size)
 {
   static char chunk[8192];
   long written = 0;
   int write_error;
   FILE *fp;
 
-  /* Only one of SOCK and SSL may be active at the same time. */
-  assert (sock > -1 || ssl != NULL);
-  assert (sock == -1 || ssl == NULL);
-
   DEBUGP (("[writing POST file %s ... ", file_name));
 
   fp = fopen (file_name, "rb");
@@ -215,12 +211,7 @@ post_file (int sock, void *ssl, const char *file_name, long promised_size)
       if (length == 0)
        break;
       towrite = WMIN (promised_size - written, length);
-#ifdef HAVE_SSL
-      if (ssl)
-       write_error = ssl_iwrite (ssl, chunk, towrite);
-      else
-#endif
-       write_error = iwrite (sock, chunk, towrite);
+      write_error = xwrite (sock, chunk, towrite, -1);
       if (write_error < 0)
        {
          fclose (fp);
@@ -344,8 +335,7 @@ http_process_set_cookie (const char *hdr, void *arg)
   /* The jar should have been created by now. */
   assert (wget_cookie_jar != NULL);
 
-  cookie_jar_process_set_cookie (wget_cookie_jar, u->host, u->port, u->path,
-                                hdr);
+  cookie_handle_set_cookie (wget_cookie_jar, u->host, u->port, u->path, hdr);
   return 1;
 }
 
@@ -353,45 +343,36 @@ http_process_set_cookie (const char *hdr, void *arg)
 /* Persistent connections.  Currently, we cache the most recently used
    connection as persistent, provided that the HTTP server agrees to
    make it such.  The persistence data is stored in the variables
-   below.  Ideally, it would be in a structure, and it should be
-   possible to cache an arbitrary fixed number of these connections.
-
-   I think the code is quite easy to extend in that direction.  */
+   below.  Ideally, it should be possible to cache an arbitrary fixed
+   number of these connections.  */
 
 /* Whether a persistent connection is active. */
-static int pc_active_p;
-/* Host and port of currently active persistent connection. */
-static struct address_list *pc_last_host_ip;
-static unsigned short pc_last_port;
+static int pconn_active;
 
-/* File descriptor of the currently active persistent connection. */
-static int pc_last_fd;
+static struct {
+  /* The socket of the connection.  */
+  int socket;
 
-#ifdef HAVE_SSL
-/* Whether a ssl handshake has occoured on this connection */
-static int pc_active_ssl;
-/* SSL connection of the currently active persistent connection. */
-static SSL *pc_last_ssl;
-#endif /* HAVE_SSL */
+  /* Host and port of the currently active persistent connection. */
+  char *host;
+  int port;
+
+  /* Whether a ssl handshake has occoured on this connection.  */
+  int ssl;
+} pconn;
 
-/* Mark the persistent connection as invalid.  This is used by the
-   CLOSE_* macros after they forcefully close a registered persistent
-   connection.  This does not close the file descriptor -- it is left
-   to the caller to do that.  (Maybe it should, though.)  */
+/* Mark the persistent connection as invalid and free the resources it
+   uses.  This is used by the CLOSE_* macros after they forcefully
+   close a registered persistent connection.  */
 
 static void
 invalidate_persistent (void)
 {
-  pc_active_p = 0;
-#ifdef HAVE_SSL
-  pc_active_ssl = 0;
-#endif /* HAVE_SSL */
-  if (pc_last_host_ip != NULL)
-    {
-      address_list_release (pc_last_host_ip);
-      pc_last_host_ip = NULL;
-    }
-  DEBUGP (("Invalidating fd %d from further reuse.\n", pc_last_fd));
+  DEBUGP (("Disabling further reuse of socket %d.\n", pconn.socket));
+  pconn_active = 0;
+  xclose (pconn.socket);
+  xfree (pconn.host);
+  xzero (pconn);
 }
 
 /* Register FD, which should be a TCP/IP connection to HOST:PORT, as
@@ -402,131 +383,109 @@ invalidate_persistent (void)
 
    If a previous connection was persistent, it is closed. */
 
-#ifdef HAVE_SSL
-static void
-register_persistent (const char *host, unsigned short port, int fd, SSL *ssl)
-{
-#else
 static void
-register_persistent (const char *host, unsigned short port, int fd)
+register_persistent (const char *host, int port, int fd, int ssl)
 {
-#endif
-  if (pc_active_p)
+  if (pconn_active)
     {
-      if (pc_last_fd == fd)
+      if (pconn.socket == fd)
        {
-         /* The connection FD is already registered.  Nothing to
-            do. */
+         /* The connection FD is already registered. */
          return;
        }
       else
        {
-         /* The old persistent connection is still active; let's
-            close it first.  This situation arises whenever a
-            persistent connection exists, but we then connect to a
-            different host, and try to register a persistent
-            connection to that one.  */
-#ifdef HAVE_SSL
-         /* The ssl disconnect has to take place before the closing
-             of pc_last_fd.  */
-         if (pc_last_ssl)
-           shutdown_ssl(pc_last_ssl);
-#endif
-         CLOSE (pc_last_fd);
+         /* The old persistent connection is still active; close it
+            first.  This situation arises whenever a persistent
+            connection exists, but we then connect to a different
+            host, and try to register a persistent connection to that
+            one.  */
          invalidate_persistent ();
        }
     }
 
-  assert (pc_last_host_ip == NULL);
-
-  /* This lookup_host cannot fail, because it has the results in the
-     cache.  */
-  pc_last_host_ip = lookup_host (host, LH_SILENT);
-  assert (pc_last_host_ip != NULL);
+  pconn_active = 1;
+  pconn.socket = fd;
+  pconn.host = xstrdup (host);
+  pconn.port = port;
+  pconn.ssl = ssl;
 
-  pc_last_port = port;
-  pc_last_fd = fd;
-  pc_active_p = 1;
-#ifdef HAVE_SSL
-  pc_last_ssl = ssl;
-  pc_active_ssl = ssl ? 1 : 0;
-#endif
-  DEBUGP (("Registered fd %d for persistent reuse.\n", fd));
+  DEBUGP (("Registered socket %d for persistent reuse.\n", fd));
 }
 
-#ifdef HAVE_SSL
-# define SHUTDOWN_SSL(ssl) do {                \
-  if (ssl)                             \
-    shutdown_ssl (ssl);                        \
-} while (0)
-#else
-# define SHUTDOWN_SSL(ssl) 
-#endif
-
 /* Return non-zero if a persistent connection is available for
    connecting to HOST:PORT.  */
 
-#ifdef HAVE_SSL
-static int
-persistent_available_p (const char *host, unsigned short port, int ssl)
-{
-#else
 static int
-persistent_available_p (const char *host, unsigned short port)
+persistent_available_p (const char *host, int port, int ssl,
+                       int *host_lookup_failed)
 {
-#endif
-  int success;
-  struct address_list *this_host_ip;
-
   /* First, check whether a persistent connection is active at all.  */
-  if (!pc_active_p)
-    return 0;
-  /* Second, check if the active connection pertains to the correct
-     (HOST, PORT) ordered pair.  */
-  if (port != pc_last_port)
+  if (!pconn_active)
     return 0;
 
-#ifdef HAVE_SSL
-  /* Second, a): check if current connection is (not) ssl, too.  This
-     test is unlikely to fail because HTTP and HTTPS typicaly use
-     different ports.  Yet it is possible, or so I [Christian
-     Fraenkel] have been told, to run HTTPS and HTTP simultaneus on
-     the same port.  */
-  if (ssl != pc_active_ssl)
+  /* If we want SSL and the last connection wasn't or vice versa,
+     don't use it.  Checking for host and port is not enough because
+     HTTP and HTTPS can apparently coexist on the same port.  */
+  if (ssl != pconn.ssl)
     return 0;
-#endif /* HAVE_SSL */
 
-  this_host_ip = lookup_host (host, LH_SILENT);
-  if (!this_host_ip)
+  /* If we're not connecting to the same port, we're not interested. */
+  if (port != pconn.port)
     return 0;
 
-  /* To equate the two host names for the purposes of persistent
-     connections, they need to share all the IP addresses in the
-     list.  */
-  success = address_list_match_all (pc_last_host_ip, this_host_ip);
-  address_list_release (this_host_ip);
-  if (!success)
-    return 0;
+  /* If the host is the same, we're in business.  If not, there is
+     still hope -- read below.  */
+  if (0 != strcasecmp (host, pconn.host))
+    {
+      /* This is somewhat evil, but works in practice: if the address
+        that pconn.socket is connected to is one of the IP addresses
+        HOST resolves to, we don't need to reconnect.  #### Is it
+        correct to do this by default?  */
+      int found;
+      ip_address ip;
+      struct address_list *al;
+
+      if (!socket_ip_address (pconn.socket, &ip, 0))
+       {
+         /* Can't get the peer's address -- something must be wrong
+            with the connection.  */
+         invalidate_persistent ();
+         return 0;
+       }
+      al = lookup_host (host, 0);
+      if (!al)
+       {
+         *host_lookup_failed = 1;
+         return 0;
+       }
+
+      found = address_list_find (al, &ip);
+      address_list_release (al);
+
+      if (!found)
+       return 0;
 
-  /* Third: check whether the connection is still open.  This is
+      /* HOST resolves to an address pconn.sock is connected to -- no
+        need to reconnect.  */
+    }
+
+  /* Finally, check whether the connection is still open.  This is
      important because most server implement a liberal (short) timeout
      on persistent connections.  Wget can of course always reconnect
      if the connection doesn't work out, but it's nicer to know in
      advance.  This test is a logical followup of the first test, but
      is "expensive" and therefore placed at the end of the list.  */
-  if (!test_socket_open (pc_last_fd))
+
+  if (!test_socket_open (pconn.socket))
     {
       /* Oops, the socket is no longer open.  Now that we know that,
          let's invalidate the persistent connection before returning
          0.  */
-      CLOSE (pc_last_fd);
-#ifdef HAVE_SSL
-      SHUTDOWN_SSL (pc_last_ssl);
-      pc_last_ssl = NULL;
-#endif
       invalidate_persistent ();
       return 0;
     }
+
   return 1;
 }
 
@@ -548,18 +507,18 @@ persistent_available_p (const char *host, unsigned short port)
 #define CLOSE_FINISH(fd) do {                  \
   if (!keep_alive)                             \
     {                                          \
-      SHUTDOWN_SSL (ssl);                      \
-      CLOSE (fd);                              \
-      if (pc_active_p && (fd) == pc_last_fd)   \
+      if (pconn_active && (fd) == pconn.socket)        \
        invalidate_persistent ();               \
+      else                                     \
+       xclose (fd);                            \
     }                                          \
 } while (0)
 
 #define CLOSE_INVALIDATE(fd) do {              \
-  SHUTDOWN_SSL (ssl);                          \
-  CLOSE (fd);                                  \
-  if (pc_active_p && (fd) == pc_last_fd)       \
+  if (pconn_active && (fd) == pconn.socket)    \
     invalidate_persistent ();                  \
+  else                                         \
+    xclose (fd);                               \
 } while (0)
 \f
 struct http_stat
@@ -582,9 +541,9 @@ struct http_stat
 static void
 free_hstat (struct http_stat *hs)
 {
-  FREE_MAYBE (hs->newloc);
-  FREE_MAYBE (hs->remote_time);
-  FREE_MAYBE (hs->error);
+  xfree_null (hs->newloc);
+  xfree_null (hs->remote_time);
+  xfree_null (hs->error);
 
   /* Guard against being called twice. */
   hs->newloc = NULL;
@@ -636,10 +595,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
   FILE *fp;
   int auth_tried_already;
   struct rbuf rbuf;
-#ifdef HAVE_SSL
-  static SSL_CTX *ssl_ctx = NULL;
-  SSL *ssl = NULL;
-#endif
+  int using_ssl = 0;
   char *cookies = NULL;
 
   /* Whether this connection will be kept alive after the HTTP request
@@ -662,41 +618,34 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
   char *post_content_type, *post_content_length;
   long post_data_size = 0;
 
+  int host_lookup_failed;
+
 #ifdef HAVE_SSL
-  /* initialize ssl_ctx on first run */
-  if (!ssl_ctx)
+  /* Initialize the SSL context.  After the first run, this is a
+     no-op.  */
+  switch (ssl_init ())
     {
-      uerr_t err = init_ssl (&ssl_ctx);
-      if (err != 0)
-       {
-         switch (err)
-           {
-           case SSLERRCTXCREATE:
-             /* this is fatal */
-             logprintf (LOG_NOTQUIET, _("Failed to set up an SSL context\n"));
-             ssl_printerrors ();
-             return err;
-           case SSLERRCERTFILE:
-             /* try without certfile */
-             logprintf (LOG_NOTQUIET,
-                        _("Failed to load certificates from %s\n"),
-                        opt.sslcertfile);
-             ssl_printerrors ();
-             logprintf (LOG_NOTQUIET,
-                        _("Trying without the specified certificate\n"));
-             break;
-           case SSLERRCERTKEY:
-             logprintf (LOG_NOTQUIET,
-                        _("Failed to get certificate key from %s\n"),
-                        opt.sslcertkey);
-             ssl_printerrors ();
-             logprintf (LOG_NOTQUIET,
-                        _("Trying without the specified certificate\n"));
-             break;
-           default:
-             break;
-           }
-       }
+    case SSLERRCTXCREATE:
+      /* this is fatal */
+      logprintf (LOG_NOTQUIET, _("Failed to set up an SSL context\n"));
+      return SSLERRCTXCREATE;
+    case SSLERRCERTFILE:
+      /* try without certfile */
+      logprintf (LOG_NOTQUIET,
+                _("Failed to load certificates from %s\n"),
+                opt.sslcertfile);
+      logprintf (LOG_NOTQUIET,
+                _("Trying without the specified certificate\n"));
+      break;
+    case SSLERRCERTKEY:
+      logprintf (LOG_NOTQUIET,
+                _("Failed to get certificate key from %s\n"),
+                opt.sslcertkey);
+      logprintf (LOG_NOTQUIET,
+                _("Trying without the specified certificate\n"));
+      break;
+    default:
+      break;
     }
 #endif /* HAVE_SSL */
 
@@ -733,38 +682,43 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
      server. */
   conn = proxy ? proxy : u;
 
+  host_lookup_failed = 0;
+
   /* First: establish the connection.  */
   if (inhibit_keep_alive
-      ||
-#ifndef HAVE_SSL
-      !persistent_available_p (conn->host, conn->port)
+      || !persistent_available_p (conn->host, conn->port,
+#ifdef HAVE_SSL
+                                 u->scheme == SCHEME_HTTPS
 #else
-      !persistent_available_p (conn->host, conn->port,
-                              u->scheme == SCHEME_HTTPS)
-#endif /* HAVE_SSL */
-      )
+                                 0
+#endif
+                                 , &host_lookup_failed))
     {
-      struct address_list *al = lookup_host (conn->host, 0);
-      if (!al)
+      /* In its current implementation, persistent_available_p will
+        look up conn->host in some cases.  If that lookup failed, we
+        don't need to bother with connect_to_host.  */
+      if (host_lookup_failed)
        return HOSTERR;
-      set_connection_host_name (conn->host);
-      sock = connect_to_many (al, conn->port, 0);
-      set_connection_host_name (NULL);
-      address_list_release (al);
 
-      if (sock < 0)
+      sock = connect_to_host (conn->host, conn->port);
+      if (sock == E_HOST)
+       return HOSTERR;
+      else if (sock < 0)
        return CONNECT_ERROR (errno);
 
 #ifdef HAVE_SSL
      if (conn->scheme == SCHEME_HTTPS)
-       if (connect_ssl (&ssl, ssl_ctx,sock) != 0)
-        {
-          logputs (LOG_VERBOSE, "\n");
-          logprintf (LOG_NOTQUIET, _("Unable to establish SSL connection.\n"));
-          ssl_printerrors ();
-          CLOSE (sock);
-          return CONSSLERR;
-        }
+       {
+        if (!ssl_connect (sock))
+          {
+            logputs (LOG_VERBOSE, "\n");
+            logprintf (LOG_NOTQUIET,
+                       _("Unable to establish SSL connection.\n"));
+            xclose (sock);
+            return CONSSLERR;
+          }
+        using_ssl = 1;
+       }
 #endif /* HAVE_SSL */
     }
   else
@@ -773,10 +727,8 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
                 conn->host, conn->port);
       /* #### pc_last_fd should be accessed through an accessor
          function.  */
-      sock = pc_last_fd;
-#ifdef HAVE_SSL
-      ssl = pc_last_ssl;
-#endif /* HAVE_SSL */
+      sock = pconn.socket;
+      using_ssl = pconn.ssl;
       DEBUGP (("Reusing fd %d.\n", sock));
     }
 
@@ -906,14 +858,13 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
     request_keep_alive = NULL;
 
   if (opt.cookies)
-    cookies = cookie_jar_generate_cookie_header (wget_cookie_jar, u->host,
-                                                u->port, u->path,
+    cookies = cookie_header (wget_cookie_jar, u->host, u->port, u->path,
 #ifdef HAVE_SSL
-                                                u->scheme == SCHEME_HTTPS
+                            u->scheme == SCHEME_HTTPS
 #else
-                                                0
+                            0
 #endif
-                                );
+                            );
 
   if (opt.post_data || opt.post_file_name)
     {
@@ -992,42 +943,23 @@ Accept: %s\r\n\
   DEBUGP (("---request begin---\n%s", request));
 
   /* Free the temporary memory.  */
-  FREE_MAYBE (wwwauth);
-  FREE_MAYBE (proxyauth);
-  FREE_MAYBE (cookies);
+  xfree_null (wwwauth);
+  xfree_null (proxyauth);
+  xfree_null (cookies);
   xfree (full_path);
 
   /* Send the request to server.  */
-#ifdef HAVE_SSL
-  if (conn->scheme == SCHEME_HTTPS)
-    write_error = ssl_iwrite (ssl, request, strlen (request));
-  else
-#endif
-    write_error = iwrite (sock, request, strlen (request));
+  write_error = xwrite (sock, request, strlen (request), -1);
 
   if (write_error >= 0)
     {
       if (opt.post_data)
        {
          DEBUGP (("[POST data: %s]\n", opt.post_data));
-#ifdef HAVE_SSL
-         if (conn->scheme == SCHEME_HTTPS)
-           write_error = ssl_iwrite (ssl, opt.post_data, post_data_size);
-         else
-#endif
-           write_error = iwrite (sock, opt.post_data, post_data_size);
+         write_error = xwrite (sock, opt.post_data, post_data_size, -1);
        }
       else if (opt.post_file_name && post_data_size != 0)
-       {
-#ifdef HAVE_SSL
-         if (conn->scheme == SCHEME_HTTPS)
-           write_error = post_file (-1, ssl, opt.post_file_name,
-                                    post_data_size);
-         else
-#endif
-           write_error = post_file (sock, NULL, opt.post_file_name,
-                                    post_data_size);
-       }
+       write_error = post_file (sock, opt.post_file_name, post_data_size);
     }
   DEBUGP (("---request end---\n"));
 
@@ -1047,12 +979,6 @@ Accept: %s\r\n\
 
   /* Before reading anything, initialize the rbuf.  */
   rbuf_initialize (&rbuf, sock);
-#ifdef HAVE_SSL
-  if (conn->scheme == SCHEME_HTTPS)
-    rbuf.ssl = ssl;
-  else
-    rbuf.ssl = NULL;
-#endif /* HAVE_SSL */
   all_headers = NULL;
   all_length = 0;
   /* Header-fetching loop.  */
@@ -1084,8 +1010,8 @@ Accept: %s\r\n\
          logputs (LOG_VERBOSE, "\n");
          logputs (LOG_NOTQUIET, _("End of file while parsing headers.\n"));
          xfree (hdr);
-         FREE_MAYBE (type);
-         FREE_MAYBE (all_headers);
+         xfree_null (type);
+         xfree_null (all_headers);
          CLOSE_INVALIDATE (sock);
          return HEOF;
        }
@@ -1095,8 +1021,8 @@ Accept: %s\r\n\
          logprintf (LOG_NOTQUIET, _("Read error (%s) in headers.\n"),
                     strerror (errno));
          xfree (hdr);
-         FREE_MAYBE (type);
-         FREE_MAYBE (all_headers);
+         xfree_null (type);
+         xfree_null (all_headers);
          CLOSE_INVALIDATE (sock);
          return HERR;
        }
@@ -1246,17 +1172,13 @@ Accept: %s\r\n\
   if (keep_alive)
     /* The server has promised that it will not close the connection
        when we're done.  This means that we can register it.  */
-#ifndef HAVE_SSL
-    register_persistent (conn->host, conn->port, sock);
-#else
-    register_persistent (conn->host, conn->port, sock, ssl);
-#endif /* HAVE_SSL */
+    register_persistent (conn->host, conn->port, sock, using_ssl);
 
   if ((statcode == HTTP_STATUS_UNAUTHORIZED)
       && authenticate_h)
     {
       /* Authorization is required.  */
-      FREE_MAYBE (type);
+      xfree_null (type);
       type = NULL;
       free_hstat (hs);
       CLOSE_INVALIDATE (sock); /* would be CLOSE_FINISH, but there
@@ -1318,8 +1240,8 @@ Accept: %s\r\n\
                     hs->newloc ? _(" [following]") : "");
          CLOSE_INVALIDATE (sock);      /* would be CLOSE_FINISH, but there
                                           might be more bytes in the body. */
-         FREE_MAYBE (type);
-         FREE_MAYBE (all_headers);
+         xfree_null (type);
+         xfree_null (all_headers);
          return NEWLOCATION;
        }
     }
@@ -1341,9 +1263,9 @@ Accept: %s\r\n\
     {
       char*  last_period_in_local_filename = strrchr(*hs->local_file, '.');
 
-      if (last_period_in_local_filename == NULL ||
-         !(strcasecmp(last_period_in_local_filename, ".htm") == EQ ||
-           strcasecmp(last_period_in_local_filename, ".html") == EQ))
+      if (last_period_in_local_filename == NULL
+         || !(0 == strcasecmp (last_period_in_local_filename, ".htm")
+              || 0 == strcasecmp (last_period_in_local_filename, ".html")))
        {
          size_t  local_filename_len = strlen(*hs->local_file);
          
@@ -1389,8 +1311,8 @@ Accept: %s\r\n\
              hs->res = 0;
              /* Mark as successfully retrieved. */
              *dt |= RETROKF;
-             FREE_MAYBE (type);
-             FREE_MAYBE (all_headers);
+             xfree_null (type);
+             xfree_null (all_headers);
              CLOSE_INVALIDATE (sock);  /* would be CLOSE_FINISH, but there
                                           might be more bytes in the body. */
              return RETRUNNEEDED;
@@ -1404,8 +1326,8 @@ Accept: %s\r\n\
 \n\
 Continued download failed on this file, which conflicts with `-c'.\n\
 Refusing to truncate existing file `%s'.\n\n"), *hs->local_file);
-             FREE_MAYBE (type);
-             FREE_MAYBE (all_headers);
+             xfree_null (type);
+             xfree_null (all_headers);
              CLOSE_INVALIDATE (sock);
              return CONTNOTSUPPORTED;
            }
@@ -1420,8 +1342,8 @@ Refusing to truncate existing file `%s'.\n\n"), *hs->local_file);
     {
       /* This means the whole request was somehow misunderstood by the
         server.  Bail out.  */
-      FREE_MAYBE (type);
-      FREE_MAYBE (all_headers);
+      xfree_null (type);
+      xfree_null (all_headers);
       CLOSE_INVALIDATE (sock);
       return RANGEERR;
     }
@@ -1460,7 +1382,7 @@ Refusing to truncate existing file `%s'.\n\n"), *hs->local_file);
            logputs (LOG_VERBOSE, "\n");
        }
     }
-  FREE_MAYBE (type);
+  xfree_null (type);
   type = NULL;                 /* We don't need it any more.  */
 
   /* Return if we have no intention of further downloading.  */
@@ -1469,8 +1391,8 @@ Refusing to truncate existing file `%s'.\n\n"), *hs->local_file);
       /* In case the caller cares to look...  */
       hs->len = 0L;
       hs->res = 0;
-      FREE_MAYBE (type);
-      FREE_MAYBE (all_headers);
+      xfree_null (type);
+      xfree_null (all_headers);
       CLOSE_INVALIDATE (sock); /* would be CLOSE_FINISH, but there
                                   might be more bytes in the body. */
       return RETRFINISHED;
@@ -1488,7 +1410,7 @@ Refusing to truncate existing file `%s'.\n\n"), *hs->local_file);
          logprintf (LOG_NOTQUIET, "%s: %s\n", *hs->local_file, strerror (errno));
          CLOSE_INVALIDATE (sock); /* would be CLOSE_FINISH, but there
                                      might be more bytes in the body. */
-         FREE_MAYBE (all_headers);
+         xfree_null (all_headers);
          return FOPENERR;
        }
     }
@@ -1552,7 +1474,7 @@ Refusing to truncate existing file `%s'.\n\n"), *hs->local_file);
     if (flush_res == EOF)
       hs->res = -2;
   }
-  FREE_MAYBE (all_headers);
+  xfree_null (all_headers);
   if (hs->res == -2)
     return FWRITEERR;
   return RETRFINISHED;
@@ -1637,14 +1559,14 @@ File `%s' already there, will not retrieve.\n"), *hstat.local_file);
       if (has_html_suffix_p (*hstat.local_file))
        *dt |= TEXTHTML;
 
-      FREE_MAYBE (dummy);
+      xfree_null (dummy);
       return RETROK;
     }
 
   use_ts = 0;
   if (opt.timestamping)
     {
-      boolean  local_dot_orig_file_exists = FALSE;
+      int local_dot_orig_file_exists = 0;
 
       if (opt.backup_converted)
        /* If -K is specified, we'll act on the assumption that it was specified
@@ -1671,7 +1593,7 @@ File `%s' already there, will not retrieve.\n"), *hstat.local_file);
          /* Try to stat() the .orig file. */
          if (stat (filename_plus_orig_suffix, &st) == 0)
            {
-             local_dot_orig_file_exists = TRUE;
+             local_dot_orig_file_exists = 1;
              local_filename = filename_plus_orig_suffix;
            }
        }      
@@ -1789,11 +1711,11 @@ File `%s' already there, will not retrieve.\n"), *hstat.local_file);
          printwhat (count, opt.ntry);
          continue;
          break;
-       case HOSTERR: case CONREFUSED: case PROXERR: case AUTHFAILED: 
+       case HOSTERR: case CONIMPOSSIBLE: case PROXERR: case AUTHFAILED: 
        case SSLERRCTXCREATE: case CONTNOTSUPPORTED:
          /* Fatal errors just return from the function.  */
          free_hstat (&hstat);
-         FREE_MAYBE (dummy);
+         xfree_null (dummy);
          return err;
          break;
        case FWRITEERR: case FOPENERR:
@@ -1802,7 +1724,7 @@ File `%s' already there, will not retrieve.\n"), *hstat.local_file);
          logprintf (LOG_NOTQUIET, _("Cannot write to `%s' (%s).\n"),
                     *hstat.local_file, strerror (errno));
          free_hstat (&hstat);
-         FREE_MAYBE (dummy);
+         xfree_null (dummy);
          return err;
          break;
        case CONSSLERR:
@@ -1810,7 +1732,7 @@ File `%s' already there, will not retrieve.\n"), *hstat.local_file);
          logputs (LOG_VERBOSE, "\n");
          logprintf (LOG_NOTQUIET, _("Unable to establish SSL connection.\n"));
          free_hstat (&hstat);
-         FREE_MAYBE (dummy);
+         xfree_null (dummy);
          return err;
          break;
        case NEWLOCATION:
@@ -1821,17 +1743,17 @@ File `%s' already there, will not retrieve.\n"), *hstat.local_file);
                         _("ERROR: Redirection (%d) without location.\n"),
                         hstat.statcode);
              free_hstat (&hstat);
-             FREE_MAYBE (dummy);
+             xfree_null (dummy);
              return WRONGCODE;
            }
          free_hstat (&hstat);
-         FREE_MAYBE (dummy);
+         xfree_null (dummy);
          return NEWLOCATION;
          break;
        case RETRUNNEEDED:
          /* The file was already fully retrieved. */
          free_hstat (&hstat);
-         FREE_MAYBE (dummy);
+         xfree_null (dummy);
          return RETROK;
          break;
        case RETRFINISHED:
@@ -1854,7 +1776,7 @@ File `%s' already there, will not retrieve.\n"), *hstat.local_file);
                     tms, hstat.statcode, hstat.error);
          logputs (LOG_VERBOSE, "\n");
          free_hstat (&hstat);
-         FREE_MAYBE (dummy);
+         xfree_null (dummy);
          return WRONGCODE;
        }
 
@@ -1898,7 +1820,7 @@ Last-modified header invalid -- time-stamp ignored.\n"));
 Server file no newer than local file `%s' -- not retrieving.\n\n"),
                             local_filename);
                  free_hstat (&hstat);
-                 FREE_MAYBE (dummy);
+                 xfree_null (dummy);
                  return RETROK;
                }
              else if (tml >= tmr)
@@ -1936,7 +1858,7 @@ The sizes do not match (local %ld) -- retrieving.\n"), local_size);
       if (opt.spider)
        {
          logprintf (LOG_NOTQUIET, "%d %s\n\n", hstat.statcode, hstat.error);
-         FREE_MAYBE (dummy);
+         xfree_null (dummy);
          return RETROK;
        }
 
@@ -1963,7 +1885,7 @@ The sizes do not match (local %ld) -- retrieving.\n"), local_size);
            downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
 
          free_hstat (&hstat);
-         FREE_MAYBE (dummy);
+         xfree_null (dummy);
          return RETROK;
        }
       else if (hstat.res == 0) /* No read error */
@@ -1990,7 +1912,7 @@ The sizes do not match (local %ld) -- retrieving.\n"), local_size);
                downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
              
              free_hstat (&hstat);
-             FREE_MAYBE (dummy);
+             xfree_null (dummy);
              return RETROK;
            }
          else if (hstat.len < hstat.contlen) /* meaning we lost the
@@ -2021,7 +1943,7 @@ The sizes do not match (local %ld) -- retrieving.\n"), local_size);
                downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
              
              free_hstat (&hstat);
-             FREE_MAYBE (dummy);
+             xfree_null (dummy);
              return RETROK;
            }
          else                  /* the same, but not accepted */
@@ -2328,7 +2250,7 @@ extract_header_attr (const char *au, const char *attr_name, char **ret)
        ;
       if (!*ep)
        return -1;
-      FREE_MAYBE (*ret);
+      xfree_null (*ret);
       *ret = strdupdelim (cp, ep);
       return ep - au + 1;
     }
@@ -2385,9 +2307,9 @@ digest_authentication_encode (const char *au, const char *user,
                                          options[i].variable);
          if (skip < 0)
            {
-             FREE_MAYBE (realm);
-             FREE_MAYBE (opaque);
-             FREE_MAYBE (nonce);
+             xfree_null (realm);
+             xfree_null (opaque);
+             xfree_null (nonce);
              return NULL;
            }
          else if (skip)
@@ -2420,9 +2342,9 @@ digest_authentication_encode (const char *au, const char *user,
     }
   if (!realm || !nonce || !user || !passwd || !path || !method)
     {
-      FREE_MAYBE (realm);
-      FREE_MAYBE (opaque);
-      FREE_MAYBE (nonce);
+      xfree_null (realm);
+      xfree_null (opaque);
+      xfree_null (nonce);
       return NULL;
     }
 
@@ -2527,6 +2449,4 @@ create_authorization_line (const char *au, const char *user,
 void
 http_cleanup (void)
 {
-  if (pc_last_host_ip)
-    address_list_release (pc_last_host_ip);
 }