[cmake-commits] andy committed CMakeLists.txt 1.10 1.11 amigaos.c 1.1 1.2 amigaos.h 1.1 1.2 arpa_telnet.h 1.1 1.2 base64.c 1.1 1.2 base64.h 1.1 1.2 config.h.in 1.1 1.2 connect.c 1.1 1.2 connect.h 1.1 1.2 content_encoding.c 1.1 1.2 content_encoding.h 1.1 1.2 cookie.c 1.1 1.2 cookie.h 1.1 1.2 curl.copyright 1.1 1.2 curl_memory.h 1.1 NONE curlx.h 1.1 1.2 dict.c 1.1 1.2 dict.h 1.1 1.2 easy.c 1.1 1.2 easyif.h 1.1 1.2 escape.c 1.1 1.2 escape.h 1.1 1.2 file.c 1.1 1.2 file.h 1.1 1.2 formdata.c 1.2 1.3 formdata.h 1.1 1.2 ftp.c 1.1 1.2 ftp.h 1.1 1.2 getdate.c 1.3 NONE getdate.h 1.1 NONE getenv.c 1.1 1.2 getinfo.c 1.1 1.2 getinfo.h 1.1 1.2 gtls.c 1.1 1.2 gtls.h 1.1 1.2 hash.c 1.1 1.2 hash.h 1.1 1.2 hostares.c 1.1 1.2 hostasyn.c 1.1 1.2 hostip.c 1.1 1.2 hostip.h 1.1 1.2 hostip4.c 1.1 1.2 hostip6.c 1.1 1.2 hostsyn.c 1.1 1.2 hostthre.c 1.1 1.2 http.c 1.1 1.2 http.h 1.1 1.2 http_chunks.c 1.1 1.2 http_chunks.h 1.1 1.2 http_digest.c 1.1 1.2 http_digest.h 1.1 1.2 http_negotiate.c 1.1 1.2 http_negotiate.h 1.1 1.2 http_ntlm.c 1.1 1.2 http_ntlm.h 1.1 1.2 if2ip.c 1.1 1.2 if2ip.h 1.1 1.2 inet_ntoa_r.h 1.1 1.2 inet_ntop.c 1.1 1.2 inet_ntop.h 1.1 1.2 inet_pton.c 1.2 1.3 inet_pton.h 1.1 1.2 krb4.c 1.1 1.2 krb4.h 1.1 1.2 ldap.c 1.1 1.2 ldap.h 1.1 1.2 llist.c 1.1 1.2 llist.h 1.1 1.2 md5.c 1.2 1.3 md5.h 1.1 1.2 memdebug.c 1.1 1.2 memdebug.h 1.1 1.2 memory.h 1.1 1.2 mprintf.c 1.4 1.5 multi.c 1.1 1.2 multiif.h 1.1 1.2 netrc.c 1.1 1.2 netrc.h 1.1 1.2 nwlib.c 1.1 1.2 parsedate.c 1.1 1.2 parsedate.h 1.1 1.2 progress.c 1.1 1.2 progress.h 1.1 1.2 security.c 1.1 1.2 security.h 1.1 NONE select.c 1.1 1.2 select.h 1.1 1.2 sendf.c 1.1 1.2 sendf.h 1.1 1.2 setup.h 1.1 1.2 setup_once.h 1.1 1.2 share.c 1.1 1.2 share.h 1.1 1.2 sockaddr.h 1.1 1.2 socks.c 1.1 1.2 socks.h 1.1 1.2 speedcheck.c 1.1 1.2 speedcheck.h 1.1 1.2 splay.c 1.1 1.2 splay.h 1.1 1.2 ssh.c 1.1 1.2 ssh.h 1.1 1.2 sslgen.c 1.1 1.2 sslgen.h 1.1 1.2 ssluse.c 1.1 1.2 ssluse.h 1.1 1.2 strdup.c 1.1 1.2 strdup.h 1.1 1.2 strequal.c 1.1 1.2 strequal.h 1.1 1.2 strerror.c 1.1 1.2 strerror.h 1.1 1.2 strtok.c 1.1 1.2 strtok.h 1.1 1.2 strtoofft.c 1.1 1.2 strtoofft.h 1.1 1.2 telnet.c 1.1 1.2 telnet.h 1.1 1.2 tftp.c 1.1 1.2 tftp.h 1.1 1.2 timeval.c 1.1 1.2 timeval.h 1.2 1.3 transfer.c 1.1 1.2 transfer.h 1.1 1.2 url.c 1.1 1.2 url.h 1.1 1.2 urldata.h 1.1 1.2 version.c 1.1 1.2

cmake-commits at cmake.org cmake-commits at cmake.org
Thu Mar 15 14:22:17 EST 2007


Update of /cvsroot/CMake/CMake/Utilities/cmcurl
In directory public:/mounts/ram/cvs-serv617

Modified Files:
	CMakeLists.txt amigaos.c amigaos.h arpa_telnet.h base64.c 
	base64.h config.h.in connect.c connect.h content_encoding.c 
	content_encoding.h cookie.c cookie.h curl.copyright curlx.h 
	dict.c dict.h easy.c escape.c escape.h file.c file.h 
	formdata.c formdata.h ftp.c ftp.h getenv.c getinfo.c getinfo.h 
	hash.c hash.h hostares.c hostasyn.c hostip.c hostip.h 
	hostip4.c hostip6.c hostsyn.c hostthre.c http.c http.h 
	http_chunks.c http_chunks.h http_digest.c http_digest.h 
	http_negotiate.c http_negotiate.h http_ntlm.c http_ntlm.h 
	if2ip.c if2ip.h inet_ntoa_r.h inet_ntop.c inet_ntop.h 
	inet_pton.c inet_pton.h krb4.c krb4.h ldap.c ldap.h llist.c 
	llist.h md5.c md5.h memdebug.c memdebug.h mprintf.c multi.c 
	netrc.c netrc.h nwlib.c progress.c progress.h security.c 
	sendf.c sendf.h setup.h share.c share.h speedcheck.c 
	speedcheck.h ssluse.c ssluse.h strequal.c strequal.h 
	strerror.c strerror.h strtok.c strtok.h strtoofft.c 
	strtoofft.h telnet.c telnet.h timeval.c timeval.h transfer.c 
	transfer.h url.c url.h urldata.h version.c 
Added Files:
	easyif.h gtls.c gtls.h memory.h multiif.h parsedate.c 
	parsedate.h select.c select.h setup_once.h sockaddr.h socks.c 
	socks.h splay.c splay.h ssh.c ssh.h sslgen.c sslgen.h strdup.c 
	strdup.h tftp.c tftp.h 
Removed Files:
	curl_memory.h getdate.c getdate.h security.h 
Log Message:
ENH: Update Curl to 7.16.1


Index: hostares.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/hostares.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- hostares.c	24 Jun 2005 13:00:12 -0000	1.1
+++ hostares.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,13 +24,10 @@
 #include "setup.h"
 
 #include <string.h>
-#include <errno.h>
 
-#define _REENTRANT
-
-#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
+#ifdef NEED_MALLOC_H
 #include <malloc.h>
-#else
+#endif
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -57,13 +54,12 @@
 #include <inet.h>
 #include <stdlib.h>
 #endif
-#endif
 
 #ifdef HAVE_SETJMP_H
 #include <setjmp.h>
 #endif
 
-#ifdef WIN32
+#ifdef HAVE_PROCESS_H
 #include <process.h>
 #endif
 
@@ -79,6 +75,8 @@
 #include "share.h"
 #include "strerror.h"
 #include "url.h"
+#include "multiif.h"
+#include "connect.h" /* for the Curl_sockerrno() proto */
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -87,7 +85,7 @@
 #include "inet_ntoa_r.h"
 #endif
 
-#include "curl_memory.h"
+#include "memory.h"
 
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -99,7 +97,7 @@
 #ifdef CURLRES_ARES
 
 /*
- * Curl_fdset() is called when someone from the outside world (using
+ * Curl_resolv_fdset() is called when someone from the outside world (using
  * curl_multi_fdset()) wants to get our fd_set setup and we're talking with
  * ares. The caller must make sure that this function is only called when we
  * have a working ares channel.
@@ -107,17 +105,26 @@
  * Returns: CURLE_OK always!
  */
 
-CURLcode Curl_fdset(struct connectdata *conn,
-                    fd_set *read_fd_set,
-                    fd_set *write_fd_set,
-                    int *max_fdp)
+int Curl_resolv_getsock(struct connectdata *conn,
+                        curl_socket_t *socks,
+                        int numsocks)
 
 {
-  int max = ares_fds(conn->data->state.areschannel,
-                     read_fd_set, write_fd_set);
-  *max_fdp = max;
+  struct timeval maxtime;
+  struct timeval timeout;
+  int max = ares_getsock(conn->data->state.areschannel,
+                         (int *)socks, numsocks);
 
-  return CURLE_OK;
+
+  maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
+  maxtime.tv_usec = 0;
+
+  ares_timeout(conn->data->state.areschannel, &maxtime, &timeout);
+
+  Curl_expire(conn->data,
+              (timeout.tv_sec * 1000) + (timeout.tv_usec/1000) );
+
+  return max;
 }
 
 /*
@@ -213,7 +220,7 @@
       break;
     tvp = ares_timeout(data->state.areschannel, &store, &tv);
     count = select(nfds, &read_fds, &write_fds, NULL, tvp);
-    if (count < 0 && errno != EINVAL)
+    if (count < 0 && Curl_sockerrno() != EINVAL)
       break;
 
     ares_process(data->state.areschannel, &read_fds, &write_fds);
@@ -249,7 +256,7 @@
 
     /* close the connection, since we can't return failure here without
        cleaning up this connection properly */
-    Curl_disconnect(conn);
+    conn->bits.close = TRUE;
   }
 
   return rc;
@@ -264,7 +271,7 @@
  * Curl_freeaddrinfo(), nothing else.
  */
 Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
-                                char *hostname,
+                                const char *hostname,
                                 int port,
                                 int *waitp)
 {
@@ -291,11 +298,10 @@
 
     /* areschannel is already setup in the Curl_open() function */
     ares_gethostbyname(data->state.areschannel, hostname, PF_INET,
-                       Curl_addrinfo4_callback, conn);
+                       (ares_host_callback)Curl_addrinfo4_callback, conn);
 
     *waitp = TRUE; /* please wait for the response */
   }
   return NULL; /* no struct yet */
 }
-
 #endif /* CURLRES_ARES */

Index: http_chunks.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/http_chunks.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- http_chunks.c	24 Jun 2005 13:00:12 -0000	1.1
+++ http_chunks.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,16 +1,16 @@
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -35,7 +35,8 @@
 
 #include "content_encoding.h"
 #include "http.h"
-#include "curl_memory.h"
+#include "memory.h"
+#include "easyif.h" /* for Curl_convert_to_network prototype */
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -43,7 +44,7 @@
 /* The last #include file should be: */
 #include "memdebug.h"
 
-/* 
+/*
  * Chunk format (simplified):
  *
  * <HEX SIZE>[ chunk extension ] CRLF
@@ -83,7 +84,7 @@
 
 void Curl_httpchunk_init(struct connectdata *conn)
 {
-  struct Curl_chunker *chunk = &conn->proto.http->chunk;
+  struct Curl_chunker *chunk = &conn->data->reqdata.proto.http->chunk;
   chunk->hexindex=0; /* start at 0 */
   chunk->dataleft=0; /* no data left yet! */
   chunk->state = CHUNK_HEX; /* we get hex first! */
@@ -96,6 +97,9 @@
  * client (for byte-counting and whatever).
  *
  * The states and the state-machine is further explained in the header file.
+ *
+ * This function always uses ASCII hex values to accommodate non-ASCII hosts.
+ * For example, 0x0d and 0x0a are used instead of '\r' and '\n'.
  */
 CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
                               char *datap,
@@ -103,8 +107,9 @@
                               ssize_t *wrotep)
 {
   CURLcode result=CURLE_OK;
-  struct Curl_chunker *ch = &conn->proto.http->chunk;
-  struct Curl_transfer_keeper *k = &conn->keep;
+  struct SessionHandle *data = conn->data;
+  struct Curl_chunker *ch = &data->reqdata.proto.http->chunk;
+  struct Curl_transfer_keeper *k = &data->reqdata.keep;
   size_t piece;
   size_t length = (size_t)datalen;
   size_t *wrote = (size_t *)wrotep;
@@ -114,7 +119,11 @@
   while(length) {
     switch(ch->state) {
     case CHUNK_HEX:
-      if(isxdigit((int)*datap)) {
+       /* Check for an ASCII hex digit.
+          We avoid the use of isxdigit to accommodate non-ASCII hosts. */
+       if((*datap >= 0x30 && *datap <= 0x39)    /* 0-9 */
+       || (*datap >= 0x41 && *datap <= 0x46)    /* A-F */
+       || (*datap >= 0x61 && *datap <= 0x66)) { /* a-f */
         if(ch->hexindex < MAXNUM_SIZE) {
           ch->hexbuffer[ch->hexindex] = *datap;
           datap++;
@@ -133,6 +142,17 @@
         }
         /* length and datap are unmodified */
         ch->hexbuffer[ch->hexindex]=0;
+#ifdef CURL_DOES_CONVERSIONS
+        /* convert to host encoding before calling strtoul */
+        result = Curl_convert_from_network(conn->data,
+                                           ch->hexbuffer,
+                                           ch->hexindex);
+        if(result != CURLE_OK) {
+          /* Curl_convert_from_network calls failf if unsuccessful */
+          /* Treat it as a bad hex character */
+          return(CHUNKE_ILLEGAL_HEX);
+        }
+#endif /* CURL_DOES_CONVERSIONS */
         ch->datasize=strtoul(ch->hexbuffer, NULL, 16);
         ch->state = CHUNK_POSTHEX;
       }
@@ -142,7 +162,7 @@
       /* In this state, we're waiting for CRLF to arrive. We support
          this to allow so called chunk-extensions to show up here
          before the CRLF comes. */
-      if(*datap == '\r')
+      if(*datap == 0x0d)
         ch->state = CHUNK_CR;
       length--;
       datap++;
@@ -150,13 +170,20 @@
 
     case CHUNK_CR:
       /* waiting for the LF */
-      if(*datap == '\n') {
+      if(*datap == 0x0a) {
         /* we're now expecting data to come, unless size was zero! */
         if(0 == ch->datasize) {
-          ch->state = CHUNK_STOP; /* stop reading! */
-          if(1 == length) {
-            /* This was the final byte, return right now */
-            return CHUNKE_STOP;
+          if (conn->bits.trailerHdrPresent!=TRUE) {
+            /* No Trailer: header found - revert to original Curl processing */
+            ch->state = CHUNK_STOP;
+            if (1 == length) {
+               /* This is the final byte, return right now */
+               return CHUNKE_STOP;
+            }
+          }
+          else {
+            ch->state = CHUNK_TRAILER; /* attempt to read trailers */
+            conn->trlPos=0;
           }
         }
         else
@@ -179,26 +206,26 @@
 
       /* Write the data portion available */
 #ifdef HAVE_LIBZ
-      switch (conn->keep.content_encoding) {
+      switch (data->reqdata.keep.content_encoding) {
         case IDENTITY:
 #endif
           if(!k->ignorebody)
-            result = Curl_client_write(conn->data, CLIENTWRITE_BODY, datap,
+            result = Curl_client_write(conn, CLIENTWRITE_BODY, datap,
                                        piece);
 #ifdef HAVE_LIBZ
           break;
 
-        case DEFLATE: 
-          /* update conn->keep.str to point to the chunk data. */
-          conn->keep.str = datap;
-          result = Curl_unencode_deflate_write(conn->data, &conn->keep,
+        case DEFLATE:
+          /* update data->reqdata.keep.str to point to the chunk data. */
+          data->reqdata.keep.str = datap;
+          result = Curl_unencode_deflate_write(conn, &data->reqdata.keep,
                                                (ssize_t)piece);
           break;
 
         case GZIP:
-          /* update conn->keep.str to point to the chunk data. */
-          conn->keep.str = datap;
-          result = Curl_unencode_gzip_write(conn->data, &conn->keep,
+          /* update data->reqdata.keep.str to point to the chunk data. */
+          data->reqdata.keep.str = datap;
+          result = Curl_unencode_gzip_write(conn, &data->reqdata.keep,
                                             (ssize_t)piece);
           break;
 
@@ -227,7 +254,7 @@
       break;
 
     case CHUNK_POSTCR:
-      if(*datap == '\r') {
+      if(*datap == 0x0d) {
         ch->state = CHUNK_POSTLF;
         datap++;
         length--;
@@ -237,7 +264,7 @@
       break;
 
     case CHUNK_POSTLF:
-      if(*datap == '\n') {
+      if(*datap == 0x0a) {
         /*
          * The last one before we go back to hex state and start all
          * over.
@@ -250,6 +277,75 @@
         return CHUNKE_BAD_CHUNK;
       break;
 
+    case CHUNK_TRAILER:
+      /* conn->trailer is assumed to be freed in url.c on a
+         connection basis */
+      if (conn->trlPos >= conn->trlMax) {
+        char *ptr;
+        if(conn->trlMax) {
+          conn->trlMax *= 2;
+          ptr = (char*)realloc(conn->trailer,conn->trlMax);
+        }
+        else {
+          conn->trlMax=128;
+          ptr = (char*)malloc(conn->trlMax);
+        }
+        if(!ptr)
+          return CHUNKE_OUT_OF_MEMORY;
+        conn->trailer = ptr;
+      }
+      conn->trailer[conn->trlPos++]=*datap;
+
+      if(*datap == 0x0d)
+        ch->state = CHUNK_TRAILER_CR;
+      else {
+        datap++;
+        length--;
+     }
+      break;
+
+    case CHUNK_TRAILER_CR:
+      if(*datap == 0x0d) {
+        ch->state = CHUNK_TRAILER_POSTCR;
+        datap++;
+        length--;
+      }
+      else
+        return CHUNKE_BAD_CHUNK;
+      break;
+
+    case CHUNK_TRAILER_POSTCR:
+      if (*datap == 0x0a) {
+        conn->trailer[conn->trlPos++]=0x0a;
+        conn->trailer[conn->trlPos]=0;
+        if (conn->trlPos==2) {
+          ch->state = CHUNK_STOP;
+          return CHUNKE_STOP;
+        }
+        else {
+#ifdef CURL_DOES_CONVERSIONS
+          /* Convert to host encoding before calling Curl_client_write */
+          result = Curl_convert_from_network(conn->data,
+                                             conn->trailer,
+                                             conn->trlPos);
+          if(result != CURLE_OK) {
+            /* Curl_convert_from_network calls failf if unsuccessful */
+            /* Treat it as a bad chunk */
+            return(CHUNKE_BAD_CHUNK);
+          }
+#endif /* CURL_DOES_CONVERSIONS */
+          Curl_client_write(conn, CLIENTWRITE_HEADER,
+                            conn->trailer, conn->trlPos);
+        }
+        ch->state = CHUNK_TRAILER;
+        conn->trlPos=0;
+        datap++;
+        length--;
+      }
+      else
+        return CHUNKE_BAD_CHUNK;
+      break;
+
     case CHUNK_STOP:
       /* If we arrive here, there is data left in the end of the buffer
          even if there's no more chunks to read */

Index: hostip.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/hostip.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- hostip.h	24 Jun 2005 13:00:12 -0000	1.1
+++ hostip.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,8 +26,9 @@
 #include "setup.h"
 #include "hash.h"
 
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t uint32_t
 #endif
 
 /*
@@ -55,14 +56,14 @@
 #define CURLRES_IPV4
 #endif
 
-#ifdef CURLRES_IPV4
+#if defined(CURLRES_IPV4) || defined(CURLRES_ARES)
 #if !defined(HAVE_GETHOSTBYNAME_R) || defined(CURLRES_ASYNCH)
 /* If built for ipv4 and missing gethostbyname_r(), or if using async name
    resolve, we need the Curl_addrinfo_copy() function (which itself needs the
-   Curl_hostent_relocate() function)) */
+   Curl_he2ai() function)) */
 #define CURLRES_ADDRINFO_COPY
 #endif
-#endif /* IPv4-only */
+#endif /* IPv4/ares-only */
 
 #ifndef CURLRES_ASYNCH
 #define CURLRES_SYNCH
@@ -86,6 +87,8 @@
 #define CURL_ASYNC_SUCCESS ARES_SUCCESS
 #else
 #define CURL_ASYNC_SUCCESS CURLE_OK
+#define ares_cancel(x) do {} while(0)
+#define ares_destroy(x) do {} while(0)
 #endif
 
 /*
@@ -97,25 +100,26 @@
 /* OK, so some ipv4-only include tree probably have the addrinfo struct, but
    to work even on those that don't, we provide our own look-alike! */
 struct Curl_addrinfo {
-  int     ai_flags;
-  int     ai_family;
-  int     ai_socktype;
-  int     ai_protocol;
-  size_t  ai_addrlen;
-  struct sockaddr *ai_addr;
-  char   *ai_canonname;
+  int                   ai_flags;
+  int                   ai_family;
+  int                   ai_socktype;
+  int                   ai_protocol;
+  socklen_t             ai_addrlen;   /* Follow rfc3493 struct addrinfo */
+  char                 *ai_canonname;
+  struct sockaddr      *ai_addr;
   struct Curl_addrinfo *ai_next;
 };
 typedef struct Curl_addrinfo Curl_addrinfo;
 #endif
 
 struct addrinfo;
+struct hostent;
 struct SessionHandle;
 struct connectdata;
 
 void Curl_global_host_cache_init(void);
 void Curl_global_host_cache_dtor(void);
-curl_hash *Curl_global_host_cache_get(void);
+struct curl_hash *Curl_global_host_cache_get(void);
 
 #define Curl_global_host_cache_use(__p) ((__p)->set.global_dns_cache)
 
@@ -137,7 +141,7 @@
 #define CURLRESOLV_ERROR    -1
 #define CURLRESOLV_RESOLVED  0
 #define CURLRESOLV_PENDING   1
-int Curl_resolv(struct connectdata *conn, char *hostname,
+int Curl_resolv(struct connectdata *conn, const char *hostname,
                 int port, struct Curl_dns_entry **dnsentry);
 
 /*
@@ -153,7 +157,7 @@
  * of arguments
  */
 Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
-                                char *hostname,
+                                const char *hostname,
                                 int port,
                                 int *waitp);
 
@@ -162,15 +166,19 @@
 CURLcode Curl_wait_for_resolv(struct connectdata *conn,
                               struct Curl_dns_entry **dnsentry);
 
-/* Curl_fdset() is a generic function that exists in multiple versions
-   depending on what name resolve technology we've built to use. The function
-   is called from the curl_multi_fdset() function */
-CURLcode Curl_fdset(struct connectdata *conn,
-                    fd_set *read_fd_set,
-                    fd_set *write_fd_set,
-                    int *max_fdp);
+/* Curl_resolv_getsock() is a generic function that exists in multiple
+   versions depending on what name resolve technology we've built to use. The
+   function is called from the multi_getsock() function.  'sock' is a pointer
+   to an array to hold the file descriptors, with 'numsock' being the size of
+   that array (in number of entries). This function is supposed to return
+   bitmask indicating what file descriptors (referring to array indexes in the
+   'sock' array) to wait for, read/write. */
+int Curl_resolv_getsock(struct connectdata *conn, curl_socket_t *sock,
+                        int numsocks);
+
 /* unlock a previously resolved dns entry */
-void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns);
+void Curl_resolv_unlock(struct SessionHandle *data,
+                        struct Curl_dns_entry *dns);
 
 /* for debugging purposes only: */
 void Curl_scan_cache_used(void *user, void *ptr);
@@ -179,7 +187,7 @@
 void Curl_freeaddrinfo(Curl_addrinfo *freeaddr);
 
 /* make a new dns cache and return the handle */
-curl_hash *Curl_mk_dnscache(void);
+struct curl_hash *Curl_mk_dnscache(void);
 
 /* prune old entries from the DNS cache */
 void Curl_hostcache_prune(struct SessionHandle *data);
@@ -190,41 +198,42 @@
 #ifdef CURLDEBUG
 void curl_dofreeaddrinfo(struct addrinfo *freethis,
                          int line, const char *source);
-int curl_dogetaddrinfo(char *hostname, char *service,
+int curl_dogetaddrinfo(const char *hostname, const char *service,
                        struct addrinfo *hints,
                        struct addrinfo **result,
                        int line, const char *source);
-int curl_dogetnameinfo(const struct sockaddr *sa, socklen_t salen,
-                       char *host, size_t hostlen,
-                       char *serv, size_t servlen, int flags,
+#ifdef HAVE_GETNAMEINFO
+int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
+                       GETNAMEINFO_TYPE_ARG2 salen,
+                       char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
+                       char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
+                       GETNAMEINFO_TYPE_ARG7 flags,
                        int line, const char *source);
 #endif
+#endif
 
 /* This is the callback function that is used when we build with asynch
    resolve, ipv4 */
-void Curl_addrinfo4_callback(void *arg,
-                            int status,
-                            struct hostent *hostent);
+CURLcode Curl_addrinfo4_callback(void *arg,
+                                 int status,
+                                 struct hostent *hostent);
 /* This is the callback function that is used when we build with asynch
    resolve, ipv6 */
-void Curl_addrinfo6_callback(void *arg,
-                            int status,
-                            struct addrinfo *ai);
+CURLcode Curl_addrinfo6_callback(void *arg,
+                                 int status,
+                                 struct addrinfo *ai);
 
 
-/* [ipv4 only] Creates a Curl_addrinfo struct from a numerical-only IP
+/* [ipv4/ares only] Creates a Curl_addrinfo struct from a numerical-only IP
    address */
-Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname, int port);
+Curl_addrinfo *Curl_ip2addr(in_addr_t num, const char *hostname, int port);
 
-/* [ipv4 only] Curl_he2ai() converts a struct hostent to a Curl_addrinfo chain
+/* [ipv4/ares only] Curl_he2ai() converts a struct hostent to a Curl_addrinfo chain
    and returns it */
-Curl_addrinfo *Curl_he2ai(struct hostent *, int port);
-
-/* relocate a hostent struct */
-void Curl_hostent_relocate(struct hostent *h, long offset);
+Curl_addrinfo *Curl_he2ai(const struct hostent *, int port);
 
 /* Clone a Curl_addrinfo struct, works protocol independently */
-Curl_addrinfo *Curl_addrinfo_copy(void *orig, int port);
+Curl_addrinfo *Curl_addrinfo_copy(const void *orig, int port);
 
 /*
  * Curl_printable_address() returns a printable version of the 1st address
@@ -241,7 +250,14 @@
  */
 struct Curl_dns_entry *
 Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr,
-                char *hostname, int port);
+                const char *hostname, int port);
+
+/*
+ * Curl_destroy_thread_data() cleans up async resolver data.
+ * Complementary of ares_destroy.
+ */
+struct Curl_async; /* forward-declaration */
+void Curl_destroy_thread_data(struct Curl_async *async);
 
 #ifndef INADDR_NONE
 #define CURL_INADDR_NONE (in_addr_t) ~0

Index: http_chunks.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/http_chunks.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- http_chunks.h	24 Jun 2005 13:00:12 -0000	1.1
+++ http_chunks.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,18 +1,18 @@
 #ifndef __HTTP_CHUNKS_H
 #define __HTTP_CHUNKS_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -52,8 +52,8 @@
   /* POSTCR should get a CR and nothing else, then move to POSTLF */
   CHUNK_POSTCR,
 
-  /* POSTLF should get a LF and nothing else, then move back to HEX as
-     the CRLF combination marks the end of a chunk */
+  /* POSTLF should get a LF and nothing else, then move back to HEX as the
+     CRLF combination marks the end of a chunk */
   CHUNK_POSTLF,
 
   /* This is mainly used to really mark that we're out of the game.
@@ -62,7 +62,22 @@
      buffer! */
   CHUNK_STOP,
 
+  /* At this point optional trailer headers can be found, unless the next line
+     is CRLF */
+  CHUNK_TRAILER,
+
+  /* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR.
+     Next char must be a LF */
+  CHUNK_TRAILER_CR,
+
+  /* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be
+     signalled If this is an empty trailer CHUNKE_STOP will be signalled.
+     Otherwise the trailer will be broadcasted via Curl_client_write() and the
+     next state will be CHUNK_TRAILER */
+  CHUNK_TRAILER_POSTCR,
+
   CHUNK_LAST /* never use */
+
 } ChunkyState;
 
 typedef enum {
@@ -74,6 +89,7 @@
   CHUNKE_WRITE_ERROR,
   CHUNKE_STATE_ERROR,
   CHUNKE_BAD_ENCODING,
+  CHUNKE_OUT_OF_MEMORY,
   CHUNKE_LAST
 } CHUNKcode;
 

Index: hostip.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/hostip.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- hostip.c	24 Jun 2005 13:00:12 -0000	1.1
+++ hostip.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,13 +24,10 @@
 #include "setup.h"
 
 #include <string.h>
-#include <errno.h>
 
-#define _REENTRANT
-
-#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
+#ifdef NEED_MALLOC_H
 #include <malloc.h>
-#else
+#endif
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -57,21 +54,15 @@
 #include <inet.h>
 #include <stdlib.h>
 #endif
-#endif
 
 #ifdef HAVE_SETJMP_H
 #include <setjmp.h>
 #endif
 
-#ifdef WIN32
+#ifdef HAVE_PROCESS_H
 #include <process.h>
 #endif
 
-#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
-#undef in_addr_t
-#define in_addr_t unsigned long
-#endif
-
 #include "urldata.h"
 #include "sendf.h"
 #include "hostip.h"
@@ -88,7 +79,7 @@
 #include "inet_ntoa_r.h"
 #endif
 
-#include "curl_memory.h"
+#include "memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
 
@@ -105,8 +96,7 @@
  * defined.
  *
  * CURLRES_ARES - is defined if libcurl is built to use c-ares for
- * asynchronous name resolves. It cannot have ENABLE_IPV6 defined at the same
- * time, as c-ares has no ipv6 support. This can be Windows or *nix.
+ * asynchronous name resolves. This can be Windows or *nix.
  *
  * CURLRES_THREADED - is defined if libcurl is built to run under (native)
  * Windows, and then the name resolve will be done in a new thread, and the
@@ -131,7 +121,7 @@
  */
 
 /* These two symbols are for the global DNS cache */
-static curl_hash hostname_cache;
+static struct curl_hash hostname_cache;
 static int host_cache_initialized;
 
 static void freednsentry(void *freethis);
@@ -152,7 +142,7 @@
 /*
  * Return a pointer to the global cache
  */
-curl_hash *Curl_global_host_cache_get(void)
+struct curl_hash *Curl_global_host_cache_get(void)
 {
   return &hostname_cache;
 }
@@ -174,20 +164,11 @@
 int Curl_num_addresses(const Curl_addrinfo *addr)
 {
   int i;
-  for (i = 0; addr; addr = addr->ai_next, i++);
+  for (i = 0; addr; addr = addr->ai_next, i++)
+    ;  /* empty loop */
   return i;
 }
 
-#define GET_SIN_ADDR_FROM_CURL_ADDRINFO(ai_addr, si, sin, sinaddr, ip) \
-  { \
-  union { \
-    struct si* vsi; \
-    struct sin* vsin;\
-  } vi; \
-  vi.vsi = ai_addr; \
-  ip = &(vi.vsin->sinaddr); \
-  }
-
 /*
  * Curl_printable_address() returns a printable version of the 1st address
  * given in the 'ip' argument. The result will be stored in the buf that is
@@ -198,17 +179,13 @@
 const char *Curl_printable_address(const Curl_addrinfo *ip,
                                    char *buf, size_t bufsize)
 {
+  const void *ip4 = &((const struct sockaddr_in*)ip->ai_addr)->sin_addr;
   int af = ip->ai_family;
-  const void *ip4;
 #ifdef CURLRES_IPV6
-  const void *ip6;
-  GET_SIN_ADDR_FROM_CURL_ADDRINFO(ip->ai_addr, sockaddr, sockaddr_in6,
-    sin6_addr, ip6);
+  const void *ip6 = &((const struct sockaddr_in6*)ip->ai_addr)->sin6_addr;
 #else
   const void *ip6 = NULL;
 #endif
-  GET_SIN_ADDR_FROM_CURL_ADDRINFO(ip->ai_addr, sockaddr, sockaddr_in,
-    sin_addr, ip4);
 
   return Curl_inet_ntop(af, af == AF_INET ? ip4 : ip6, buf, bufsize);
 }
@@ -218,7 +195,7 @@
  * the DNS caching.
  */
 static char *
-create_hostcache_id(char *server, int port)
+create_hostcache_id(const char *server, int port)
 {
   /* create and return the new allocated entry */
   return aprintf("%s:%d", server, port);
@@ -257,7 +234,7 @@
  * Prune the DNS cache. This assumes that a lock has already been taken.
  */
 static void
-hostcache_prune(curl_hash *hostcache, int cache_timeout, time_t now)
+hostcache_prune(struct curl_hash *hostcache, int cache_timeout, time_t now)
 {
   struct hostcache_prune_data user;
 
@@ -277,8 +254,9 @@
 {
   time_t now;
 
-  if(data->set.dns_cache_timeout == -1)
-    /* cache forever means never prune! */
+  if((data->set.dns_cache_timeout == -1) || !data->dns.hostcache)
+    /* cache forever means never prune, and NULL hostcache means
+       we can't do it */
     return;
 
   if(data->share)
@@ -287,7 +265,7 @@
   time(&now);
 
   /* Remove outdated and unused entries from the hostcache */
-  hostcache_prune(data->hostcache,
+  hostcache_prune(data->dns.hostcache,
                   data->set.dns_cache_timeout,
                   now);
 
@@ -295,6 +273,39 @@
     Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
 }
 
+static int
+remove_entry_if_stale(struct SessionHandle *data, struct Curl_dns_entry *dns)
+{
+  struct hostcache_prune_data user;
+
+  if( !dns || (data->set.dns_cache_timeout == -1) || !data->dns.hostcache)
+    /* cache forever means never prune, and NULL hostcache means
+       we can't do it */
+    return 0;
+
+  time(&user.now);
+  user.cache_timeout = data->set.dns_cache_timeout;
+
+  if ( !hostcache_timestamp_remove(&user,dns) )
+    return 0;
+
+  /* ok, we do need to clear the cache. although we need to remove just a
+     single entry we clean the entire hash, as no explicit delete function
+     is provided */
+  if(data->share)
+    Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+  Curl_hash_clean_with_criterium(data->dns.hostcache,
+                                 (void *) &user,
+                                 hostcache_timestamp_remove);
+
+  if(data->share)
+    Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+  return 1;
+}
+
+
 #ifdef HAVE_SIGSETJMP
 /* Beware this is a global and unique instance. This is used to store the
    return address that we can jump back to from inside a signal handler. This
@@ -315,7 +326,7 @@
 struct Curl_dns_entry *
 Curl_cache_addr(struct SessionHandle *data,
                 Curl_addrinfo *addr,
-                char *hostname,
+                const char *hostname,
                 int port)
 {
   char *entry_id;
@@ -332,7 +343,7 @@
   entry_len = strlen(entry_id);
 
   /* Create a new cache entry */
-  dns = (struct Curl_dns_entry *) malloc(sizeof(struct Curl_dns_entry));
+  dns = (struct Curl_dns_entry *) calloc(sizeof(struct Curl_dns_entry), 1);
   if (!dns) {
     free(entry_id);
     return NULL;
@@ -344,7 +355,8 @@
   /* Store the resolved data in our DNS cache. This function may return a
      pointer to an existing struct already present in the hash, and it may
      return the same argument we pass in. Make no assumptions. */
-  dns2 = Curl_hash_add(data->hostcache, entry_id, entry_len+1, (void *)dns);
+  dns2 = Curl_hash_add(data->dns.hostcache, entry_id, entry_len+1,
+                       (void *)dns);
   if(!dns2) {
     /* Major badness, run away. */
     free(dns);
@@ -381,31 +393,30 @@
  */
 
 int Curl_resolv(struct connectdata *conn,
-                char *hostname,
+                const char *hostname,
                 int port,
                 struct Curl_dns_entry **entry)
 {
-  char *entry_id;
+  char *entry_id = NULL;
   struct Curl_dns_entry *dns = NULL;
   size_t entry_len;
   int wait;
   struct SessionHandle *data = conn->data;
   CURLcode result;
-
-  /* default to failure */
   int rc;
   *entry = NULL;
 
 #ifdef HAVE_SIGSETJMP
   /* this allows us to time-out from the name resolver, as the timeout
      will generate a signal and we will siglongjmp() from that here */
-  if(!data->set.no_signal && sigsetjmp(curl_jmpenv, 1)) {
-    /* this is coming from a siglongjmp() */
-    failf(data, "name lookup timed out");
-    return CURLRESOLV_ERROR;
+  if(!data->set.no_signal) {
+    if (sigsetjmp(curl_jmpenv, 1)) {
+      /* this is coming from a siglongjmp() */
+      failf(data, "name lookup timed out");
+      return CURLRESOLV_ERROR;
+    }
   }
 #endif
-  rc = CURLRESOLV_ERROR;
 
   /* Create an entry id, based upon the hostname and port */
   entry_id = create_hostcache_id(hostname, port);
@@ -419,7 +430,7 @@
     Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
 
   /* See if its already in our dns cache */
-  dns = Curl_hash_pick(data->hostcache, entry_id, entry_len+1);
+  dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1);
 
   if(data->share)
     Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
@@ -427,6 +438,13 @@
   /* free the allocated entry_id again */
   free(entry_id);
 
+  /* See whether the returned entry is stale. Deliberately done after the
+     locked block */
+  if ( remove_entry_if_stale(data,dns) )
+    dns = NULL; /* the memory deallocation is being handled by the hash */
+
+  rc = CURLRESOLV_ERROR; /* default to failure */
+
   if (!dns) {
     /* The entry was not in the cache. Resolve it to IP address */
 
@@ -474,7 +492,11 @@
     }
   }
   else {
+    if(data->share)
+      Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
     dns->inuse++; /* we use it! */
+    if(data->share)
+      Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
     rc = CURLRESOLV_RESOLVED;
   }
 
@@ -516,7 +538,7 @@
 /*
  * Curl_mk_dnscache() creates a new DNS cache and returns the handle for it.
  */
-curl_hash *Curl_mk_dnscache(void)
+struct curl_hash *Curl_mk_dnscache(void)
 {
   return Curl_hash_alloc(7, freednsentry);
 }
@@ -531,10 +553,84 @@
  * returns a pointer to the malloc()ed copy. You need to call free() on the
  * returned buffer when you're done with it.
  */
-Curl_addrinfo *Curl_addrinfo_copy(void *org, int port)
+Curl_addrinfo *Curl_addrinfo_copy(const void *org, int port)
 {
-  struct hostent *orig = org;
+  const struct hostent *orig = org;
 
   return Curl_he2ai(orig, port);
 }
 #endif /* CURLRES_ADDRINFO_COPY */
+
+/***********************************************************************
+ * Only for plain-ipv4 and c-ares builds
+ **********************************************************************/
+
+#if defined(CURLRES_IPV4) || defined(CURLRES_ARES)
+/*
+ * This is a function for freeing name information in a protocol independent
+ * way.
+ */
+void Curl_freeaddrinfo(Curl_addrinfo *ai)
+{
+  Curl_addrinfo *next;
+
+  /* walk over the list and free all entries */
+  while(ai) {
+    next = ai->ai_next;
+    free(ai);
+    ai = next;
+  }
+}
+
+struct namebuf {
+  struct hostent hostentry;
+  char *h_addr_list[2];
+  struct in_addr addrentry;
+  char h_name[16]; /* 123.123.123.123 = 15 letters is maximum */
+};
+
+/*
+ * Curl_ip2addr() takes a 32bit ipv4 internet address as input parameter
+ * together with a pointer to the string version of the address, and it
+ * returns a Curl_addrinfo chain filled in correctly with information for this
+ * address/host.
+ *
+ * The input parameters ARE NOT checked for validity but they are expected
+ * to have been checked already when this is called.
+ */
+Curl_addrinfo *Curl_ip2addr(in_addr_t num, const char *hostname, int port)
+{
+  Curl_addrinfo *ai;
+  struct hostent *h;
+  struct in_addr *addrentry;
+  struct namebuf buffer;
+  struct namebuf *buf = &buffer;
+
+  h = &buf->hostentry;
+  h->h_addr_list = &buf->h_addr_list[0];
+  addrentry = &buf->addrentry;
+#ifdef _CRAYC
+  /* On UNICOS, s_addr is a bit field and for some reason assigning to it
+   * doesn't work.  There must be a better fix than this ugly hack.
+   */
+  memcpy(addrentry, &num, SIZEOF_in_addr);
+#else
+  addrentry->s_addr = num;
+#endif
+  h->h_addr_list[0] = (char*)addrentry;
+  h->h_addr_list[1] = NULL;
+  h->h_addrtype = AF_INET;
+  h->h_length = sizeof(*addrentry);
+  h->h_name = &buf->h_name[0];
+  h->h_aliases = NULL;
+
+  /* Now store the dotted version of the address */
+  snprintf((char *)h->h_name, 16, "%s", hostname);
+
+  ai = Curl_he2ai(h, port);
+
+  return ai;
+}
+#endif
+
+

Index: connect.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/connect.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- connect.c	24 Jun 2005 13:00:12 -0000	1.1
+++ connect.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -25,7 +25,9 @@
 
 #ifndef WIN32
 /* headers for non-win32 */
+#ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
+#endif
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -67,7 +69,7 @@
 #undef in_addr_t
 #define in_addr_t unsigned long
 #endif
-#ifdef  VMS
+#ifdef VMS
 #include <in.h>
 #include <inet.h>
 #endif
@@ -82,8 +84,7 @@
 #define FALSE 0
 #endif
 
-#ifdef WIN32
-#include <windows.h>
+#ifdef USE_WINSOCK
 #define EINPROGRESS WSAEINPROGRESS
 #define EWOULDBLOCK WSAEWOULDBLOCK
 #define EISCONN     WSAEISCONN
@@ -96,7 +97,12 @@
 #include "if2ip.h"
 #include "strerror.h"
 #include "connect.h"
-#include "curl_memory.h"
+#include "memory.h"
+#include "select.h"
+#include "url.h" /* for Curl_safefree() */
+#include "multiif.h"
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "inet_ntop.h"
 
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -105,18 +111,18 @@
 
 static curl_socket_t
 singleipconnect(struct connectdata *conn,
-                Curl_addrinfo *ai, /* start connecting to this */
+                const Curl_addrinfo *ai, /* start connecting to this */
                 long timeout_ms,
                 bool *connected);
 
 /*
- * Curl_ourerrno() returns the errno (or equivalent) on this platform to
- * hide platform specific for the function that calls this.
+ * Curl_sockerrno() returns the *socket-related* errno (or equivalent) on this
+ * platform to hide platform specific for the function that calls this.
  */
-int Curl_ourerrno(void)
+int Curl_sockerrno(void)
 {
-#ifdef WIN32
-  return (int)GetLastError();
+#ifdef USE_WINSOCK
+  return (int)WSAGetLastError();
 #else
   return errno;
 #endif
@@ -131,72 +137,62 @@
                   int nonblock   /* TRUE or FALSE */)
 {
 #undef SETBLOCK
+#define SETBLOCK 0
 #ifdef HAVE_O_NONBLOCK
-    {
-    /* most recent unix versions */
-    int flags;
+  /* most recent unix versions */
+  int flags;
 
-    flags = fcntl(sockfd, F_GETFL, 0);
-    if (TRUE == nonblock)
-      return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
-    else
-      return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
-    }
+  flags = fcntl(sockfd, F_GETFL, 0);
+  if (TRUE == nonblock)
+    return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
+  else
+    return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
+#undef SETBLOCK
 #define SETBLOCK 1
 #endif
 
-#ifdef HAVE_FIONBIO
-    {
-    /* older unix versions */
-    int flags;
+#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
+  /* older unix versions */
+  int flags;
 
-    flags = nonblock;
-    return ioctl(sockfd, FIONBIO, &flags);
-    }
-#ifdef SETBLOCK
-# undef SETBLOCK
-#endif
+  flags = nonblock;
+  return ioctl(sockfd, FIONBIO, &flags);
+#undef SETBLOCK
 #define SETBLOCK 2
 #endif
 
-#ifdef HAVE_IOCTLSOCKET
+#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
   /* Windows? */
   unsigned long flags;
   flags = nonblock;
+
   return ioctlsocket(sockfd, FIONBIO, &flags);
+#undef SETBLOCK
 #define SETBLOCK 3
 #endif
 
-#ifdef HAVE_IOCTLSOCKET_CASE
+#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
   /* presumably for Amiga */
   return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
-#ifdef SETBLOCK
-# undef SETBLOCK
-#endif
+#undef SETBLOCK
 #define SETBLOCK 4
 #endif
 
-#ifdef HAVE_SO_NONBLOCK
+#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
   /* BeOS */
   long b = nonblock ? 1 : 0;
   return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
-#ifdef SETBLOCK
-# undef SETBLOCK
-#endif
+#undef SETBLOCK
 #define SETBLOCK 5
 #endif
 
 #ifdef HAVE_DISABLED_NONBLOCKING
-  (void)nonblock;
-  (void)sockfd;
   return 0; /* returns success */
-#ifdef SETBLOCK
-# undef SETBLOCK
-#endif
+#undef SETBLOCK
 #define SETBLOCK 6
 #endif
 
-#ifndef SETBLOCK
+#if (SETBLOCK == 0)
 #error "no non-blocking method was found/used/set"
 #endif
 }
@@ -219,30 +215,16 @@
 int waitconnect(curl_socket_t sockfd, /* socket */
                 long timeout_msec)
 {
-  fd_set fd;
-  fd_set errfd;
-  struct timeval interval;
   int rc;
 #ifdef mpeix
   /* Call this function once now, and ignore the results. We do this to
      "clear" the error state on the socket so that we can later read it
      reliably. This is reported necessary on the MPE/iX operating system. */
-  verifyconnect(sockfd, NULL);
+  (void)verifyconnect(sockfd, NULL);
 #endif
 
   /* now select() until we get connect or timeout */
-  FD_ZERO(&fd);
-  FD_SET(sockfd, &fd);
-
-  FD_ZERO(&errfd);
-  FD_SET(sockfd, &errfd);
-
-  interval.tv_sec = (int)(timeout_msec/1000);
-  timeout_msec -= interval.tv_sec*1000;
-
-  interval.tv_usec = timeout_msec*1000;
-
-  rc = select(sockfd+1, NULL, &fd, &errfd, &interval);
+  rc = Curl_select(CURL_SOCKET_BAD, sockfd, (int)timeout_msec);
   if(-1 == rc)
     /* error, no connect here, try next */
     return WAITCONN_SELECT_ERROR;
@@ -251,7 +233,7 @@
     /* timeout, no connect today */
     return WAITCONN_TIMEOUT;
 
-  if(FD_ISSET(sockfd, &errfd))
+  if(rc & CSELECT_ERR)
     /* error condition caught */
     return WAITCONN_FDSET_ERROR;
 
@@ -262,14 +244,19 @@
 static CURLcode bindlocal(struct connectdata *conn,
                           curl_socket_t sockfd)
 {
-#ifdef HAVE_INET_NTOA
-  bool bindworked = FALSE;
   struct SessionHandle *data = conn->data;
+  struct sockaddr_in me;
+  struct sockaddr *sock = NULL;  /* bind to this address */
+  socklen_t socksize; /* size of the data sock points to */
+  unsigned short port = data->set.localport; /* use this port number, 0 for
+                                                "random" */
+  /* how many port numbers to try to bind to, increasing one at a time */
+  int portnum = data->set.localportrange;
 
   /*************************************************************
    * Select device to bind socket to
    *************************************************************/
-  if (strlen(data->set.device)<255) {
+  if (data->set.device && (strlen(data->set.device)<255) ) {
     struct Curl_dns_entry *h=NULL;
     char myhost[256] = "";
     in_addr_t in;
@@ -288,8 +275,10 @@
       if(rc == CURLRESOLV_PENDING)
         (void)Curl_wait_for_resolv(conn, &h);
 
-      if(h)
+      if(h) {
         was_iface = TRUE;
+        Curl_resolv_unlock(data, h);
+      }
     }
 
     if(!was_iface) {
@@ -301,9 +290,17 @@
       if(rc == CURLRESOLV_PENDING)
         (void)Curl_wait_for_resolv(conn, &h);
 
-      if(h)
-        /* we know data->set.device is shorter than the myhost array */
-        strcpy(myhost, data->set.device);
+      if(h) {
+        if(in == CURL_INADDR_NONE)
+          /* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */
+          Curl_inet_ntop(h->addr->ai_addr->sa_family,
+                         &((struct sockaddr_in*)h->addr->ai_addr)->sin_addr,
+                         myhost, sizeof myhost);
+        else
+          /* we know data->set.device is shorter than the myhost array */
+          strcpy(myhost, data->set.device);
+        Curl_resolv_unlock(data, h);
+      }
     }
 
     if(! *myhost) {
@@ -317,7 +314,7 @@
       return CURLE_HTTP_PORT_FAILED;
     }
 
-    infof(data, "We bind local end to %s\n", myhost);
+    infof(data, "Bind local address to %s\n", myhost);
 
 #ifdef SO_BINDTODEVICE
     /* I am not sure any other OSs than Linux that provide this feature, and
@@ -335,7 +332,7 @@
       if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
                      data->set.device, strlen(data->set.device)+1) != 0) {
         /* printf("Failed to BINDTODEVICE, socket: %d  device: %s error: %s\n",
-           sockfd, data->set.device, Curl_strerror(Curl_ourerrno())); */
+           sockfd, data->set.device, Curl_strerror(Curl_sockerrno())); */
         infof(data, "SO_BINDTODEVICE %s failed\n",
               data->set.device);
         /* This is typically "errno 1, error: Operation not permitted" if
@@ -345,59 +342,78 @@
 #endif
 
     in=inet_addr(myhost);
-    if (CURL_INADDR_NONE != in) {
+    if (CURL_INADDR_NONE == in) {
+      failf(data,"couldn't find my own IP address (%s)", myhost);
+      return CURLE_HTTP_PORT_FAILED;
+    } /* end of inet_addr */
 
-      if ( h ) {
-        Curl_addrinfo *addr = h->addr;
+    if ( h ) {
+      Curl_addrinfo *addr = h->addr;
+      sock = addr->ai_addr;
+      socksize = addr->ai_addrlen;
+    }
+    else
+      return CURLE_HTTP_PORT_FAILED;
 
-        Curl_resolv_unlock(data, h);
-        /* we don't need it anymore after this function has returned */
+  }
+  else if(port) {
+    /* if a local port number is requested but no local IP, extract the
+       address from the socket */
+    memset(&me, 0, sizeof(struct sockaddr));
+    me.sin_family = AF_INET;
+    me.sin_addr.s_addr = INADDR_ANY;
 
-        if( bind(sockfd, addr->ai_addr, (socklen_t)addr->ai_addrlen) >= 0) {
-          /* we succeeded to bind */
-#ifdef ENABLE_IPV6
-          struct sockaddr_in6 add;
-#else
-          struct sockaddr_in add;
-#endif
+    sock = (struct sockaddr *)&me;
+    socksize = sizeof(struct sockaddr);
 
-#ifdef __hpux
-          int gsize = sizeof(add);
-#else
-          socklen_t gsize = sizeof(add);
-#endif
-          bindworked = TRUE;
+  }
+  else
+    /* no local kind of binding was requested */
+    return CURLE_OK;
 
-          if(getsockname(sockfd, (struct sockaddr *) &add,
-                         &gsize)<0) {
-            failf(data, "getsockname() failed");
-            return CURLE_HTTP_PORT_FAILED;
-          }
-        }
+  do {
 
-        if(!bindworked) {
-          failf(data, "%s", Curl_strerror(conn, Curl_ourerrno()));
-          return CURLE_HTTP_PORT_FAILED;
-        }
+    /* Set port number to bind to, 0 makes the system pick one */
+    if(sock->sa_family == AF_INET)
+      ((struct sockaddr_in *)sock)->sin_port = htons(port);
+#ifdef ENABLE_IPV6
+    else
+      ((struct sockaddr_in6 *)sock)->sin6_port = htons(port);
+#endif
 
-      } /* end of if  h */
-      else {
-        failf(data,"could't find my own IP address (%s)", myhost);
+    if( bind(sockfd, sock, socksize) >= 0) {
+      /* we succeeded to bind */
+      struct Curl_sockaddr_storage add;
+      socklen_t size;
+
+      size = sizeof(add);
+      if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) {
+        failf(data, "getsockname() failed");
         return CURLE_HTTP_PORT_FAILED;
       }
-    } /* end of inet_addr */
-
-    else {
-      failf(data, "could't find my own IP address (%s)", myhost);
-      return CURLE_HTTP_PORT_FAILED;
+      /* We re-use/clobber the port variable here below */
+      if(((struct sockaddr *)&add)->sa_family == AF_INET)
+        port = ntohs(((struct sockaddr_in *)&add)->sin_port);
+#ifdef ENABLE_IPV6
+      else
+        port = ntohs(((struct sockaddr_in6 *)&add)->sin6_port);
+#endif
+      infof(data, "Local port: %d\n", port);
+      return CURLE_OK;
     }
+    if(--portnum > 0) {
+      infof(data, "Bind to local port %d failed, trying next\n", port);
+      port++; /* try next port */
+    }
+    else
+      break;
+  } while(1);
 
-    return CURLE_OK;
-
-  } /* end of device selection support */
-#endif /* end of HAVE_INET_NTOA */
-
+  data->state.os_errno = Curl_sockerrno();
+  failf(data, "bind failure: %s",
+        Curl_strerror(conn, data->state.os_errno));
   return CURLE_HTTP_PORT_FAILED;
+
 }
 
 /*
@@ -405,15 +421,10 @@
  */
 static bool verifyconnect(curl_socket_t sockfd, int *error)
 {
-  bool rc;
+  bool rc = TRUE;
 #ifdef SO_ERROR
   int err = 0;
-#ifdef __hpux
-  int errSize = sizeof(err);
-#else
   socklen_t errSize = sizeof(err);
-#endif
-
 
 #ifdef WIN32
   /*
@@ -431,12 +442,24 @@
    *
    *    Someone got to verify this on Win-NT 4.0, 2000."
    */
+
+#ifdef _WIN32_WCE
+  Sleep(0);
+#else
   SleepEx(0, FALSE);
 #endif
 
+#endif
+
   if( -1 == getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
                        (void *)&err, &errSize))
-    err = Curl_ourerrno();
+    err = Curl_sockerrno();
+
+#ifdef _WIN32_WCE
+  /* Always returns this error, bug in CE? */
+  if(WSAENOPROTOOPT==err)
+    err=0;
+#endif
 
   if ((0 == err) || (EISCONN == err))
     /* we are connected, awesome! */
@@ -449,11 +472,30 @@
 #else
   (void)sockfd;
   if (error)
-    *error = Curl_ourerrno();
+    *error = Curl_sockerrno();
 #endif
   return rc;
 }
 
+CURLcode Curl_store_ip_addr(struct connectdata *conn)
+{
+  char addrbuf[256];
+  Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf));
+
+  /* save the string */
+  Curl_safefree(conn->ip_addr_str);
+  conn->ip_addr_str = strdup(addrbuf);
+  if(!conn->ip_addr_str)
+    return CURLE_OUT_OF_MEMORY; /* FAIL */
+
+#ifdef PF_INET6
+  if(conn->ip_addr->ai_family == PF_INET6)
+    conn->bits.ipv6 = TRUE;
+#endif
+
+  return CURLE_OK;
+}
+
 /* Used within the multi interface. Try next IP address, return TRUE if no
    more address exists */
 static bool trynextip(struct connectdata *conn,
@@ -463,6 +505,11 @@
   curl_socket_t sockfd;
   Curl_addrinfo *ai;
 
+  /* first close the failed socket */
+  sclose(conn->sock[sockindex]);
+  conn->sock[sockindex] = CURL_SOCKET_BAD;
+  *connected = FALSE;
+
   if(sockindex != FIRSTSOCKET)
     return TRUE; /* no next */
 
@@ -475,6 +522,8 @@
       /* store the new socket descriptor */
       conn->sock[sockindex] = sockfd;
       conn->ip_addr = ai;
+
+      Curl_store_ip_addr(conn);
       return FALSE;
     }
     ai = ai->ai_next;
@@ -496,6 +545,7 @@
   CURLcode code = CURLE_OK;
   curl_socket_t sockfd = conn->sock[sockindex];
   long allow = DEFAULT_CONNECT_TIMEOUT;
+  long allow_total = 0;
   long has_passed;
 
   curlassert(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
@@ -503,17 +553,17 @@
   *connected = FALSE; /* a very negative world view is best */
 
   /* Evaluate in milliseconds how much time that has passed */
-  has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start);
+  has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
 
   /* subtract the most strict timeout of the ones */
   if(data->set.timeout && data->set.connecttimeout) {
     if (data->set.timeout < data->set.connecttimeout)
-      allow = data->set.timeout*1000;
+      allow_total = allow = data->set.timeout*1000;
     else
       allow = data->set.connecttimeout*1000;
   }
   else if(data->set.timeout) {
-    allow = data->set.timeout*1000;
+    allow_total = allow = data->set.timeout*1000;
   }
   else if(data->set.connecttimeout) {
     allow = data->set.connecttimeout*1000;
@@ -526,30 +576,45 @@
   }
   if(conn->bits.tcpconnect) {
     /* we are connected already! */
+    Curl_expire(data, allow_total);
     *connected = TRUE;
     return CURLE_OK;
   }
 
+  Curl_expire(data, allow);
+
   /* check for connect without timeout as we want to return immediately */
   rc = waitconnect(sockfd, 0);
 
   if(WAITCONN_CONNECTED == rc) {
-    if (verifyconnect(sockfd, NULL)) {
+    int error;
+    if (verifyconnect(sockfd, &error)) {
       /* we are connected, awesome! */
       *connected = TRUE;
       return CURLE_OK;
     }
     /* nope, not connected for real */
+    data->state.os_errno = error;
     infof(data, "Connection failed\n");
     if(trynextip(conn, sockindex, connected)) {
       code = CURLE_COULDNT_CONNECT;
     }
   }
   else if(WAITCONN_TIMEOUT != rc) {
+    int error = 0;
+
     /* nope, not connected  */
-    infof(data, "Connection failed\n");
+    if (WAITCONN_FDSET_ERROR == rc) {
+      (void)verifyconnect(sockfd, &error);
+      data->state.os_errno = error;
+      infof(data, "%s\n",Curl_strerror(conn,error));
+    }
+    else
+      infof(data, "Connection failed\n");
+
     if(trynextip(conn, sockindex, connected)) {
-      int error = Curl_ourerrno();
+      error = Curl_sockerrno();
+      data->state.os_errno = error;
       failf(data, "Failed connect to %s:%d; %s",
             conn->host.name, conn->port, Curl_strerror(conn,error));
       code = CURLE_COULDNT_CONNECT;
@@ -569,10 +634,18 @@
 #ifdef TCP_NODELAY
   struct SessionHandle *data= conn->data;
   socklen_t onoff = (socklen_t) data->set.tcp_nodelay;
-  if(setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (void *)&onoff,
+  int proto = IPPROTO_TCP;
+
+#ifdef HAVE_GETPROTOBYNAME
+  struct protoent *pe = getprotobyname("tcp");
+  if (pe)
+    proto = pe->p_proto;
+#endif
+
+  if(setsockopt(sockfd, proto, TCP_NODELAY, (void *)&onoff,
                 sizeof(onoff)) < 0)
     infof(data, "Could not set TCP_NODELAY: %s\n",
-          Curl_strerror(conn, Curl_ourerrno()));
+          Curl_strerror(conn, Curl_sockerrno()));
   else
     infof(data,"TCP_NODELAY set\n");
 #else
@@ -581,21 +654,42 @@
 #endif
 }
 
+#ifdef SO_NOSIGPIPE
+/* The preferred method on Mac OS X (10.2 and later) to prevent SIGPIPEs when
+   sending data to a dead peer (instead of relying on the 4th argument to send
+   being MSG_NOSIGNAL). Possibly also existing and in use on other BSD
+   systems? */
+static void nosigpipe(struct connectdata *conn,
+                      curl_socket_t sockfd)
+{
+  struct SessionHandle *data= conn->data;
+  int onoff = 1;
+  if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
+                sizeof(onoff)) < 0)
+    infof(data, "Could not set SO_NOSIGPIPE: %s\n",
+          Curl_strerror(conn, Curl_sockerrno()));
+}
+#else
+#define nosigpipe(x,y)
+#endif
+
 /* singleipconnect() connects to the given IP only, and it may return without
    having connected if used from the multi interface. */
 static curl_socket_t
 singleipconnect(struct connectdata *conn,
-                Curl_addrinfo *ai,
+                const Curl_addrinfo *ai,
                 long timeout_ms,
                 bool *connected)
 {
   char addr_buf[128];
   int rc;
   int error;
-  bool conected;
+  bool isconnected;
   struct SessionHandle *data = conn->data;
-  curl_socket_t sockfd = socket(ai->ai_family, ai->ai_socktype,
-                                ai->ai_protocol);
+  curl_socket_t sockfd;
+  CURLcode res;
+
+  sockfd = socket(ai->ai_family, conn->socktype, ai->ai_protocol);
   if (sockfd == CURL_SOCKET_BAD)
     return CURL_SOCKET_BAD;
 
@@ -607,21 +701,37 @@
   if(data->set.tcp_nodelay)
     tcpnodelay(conn, sockfd);
 
-  if(conn->data->set.device) {
-    /* user selected to bind the outgoing socket to a specified "device"
-       before doing connect */
-    CURLcode res = bindlocal(conn, sockfd);
-    if(res)
-      return res;
+  nosigpipe(conn, sockfd);
+
+  if(data->set.fsockopt) {
+    /* activate callback for setting socket options */
+    error = data->set.fsockopt(data->set.sockopt_client,
+                               sockfd,
+                               CURLSOCKTYPE_IPCXN);
+    if (error) {
+      sclose(sockfd); /* close the socket and bail out */
+      return CURL_SOCKET_BAD;
+    }
+  }
+
+  /* possibly bind the local end to an IP, interface or port */
+  res = bindlocal(conn, sockfd);
+  if(res) {
+    sclose(sockfd); /* close socket and bail out */
+    return CURL_SOCKET_BAD;
   }
 
   /* set socket non-blocking */
   Curl_nonblock(sockfd, TRUE);
 
-  rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
+  /* Connect TCP sockets, bind UDP */
+  if(conn->socktype == SOCK_STREAM)
+    rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
+  else
+    rc = 0;
 
   if(-1 == rc) {
-    error = Curl_ourerrno();
+    error = Curl_sockerrno();
 
     switch (error) {
     case EINPROGRESS:
@@ -639,6 +749,7 @@
       /* unknown error, fallthrough and try another address! */
       failf(data, "Failed to connect to %s: %s",
             addr_buf, Curl_strerror(conn,error));
+      data->state.os_errno = error;
       break;
     }
   }
@@ -651,9 +762,9 @@
     return sockfd;
   }
 
-  conected = verifyconnect(sockfd, &error);
+  isconnected = verifyconnect(sockfd, &error);
 
-  if(!rc && conected) {
+  if(!rc && isconnected) {
     /* we are connected, awesome! */
     *connected = TRUE; /* this is a true connect */
     infof(data, "connected\n");
@@ -661,8 +772,10 @@
   }
   else if(WAITCONN_TIMEOUT == rc)
     infof(data, "Timeout\n");
-  else
+  else {
+    data->state.os_errno = error;
     infof(data, "%s\n", Curl_strerror(conn, error));
+  }
 
   /* connect failed or timed out */
   sclose(sockfd);
@@ -677,7 +790,7 @@
  */
 
 CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
-                          struct Curl_dns_entry *remotehost, /* use this one */
+                          const struct Curl_dns_entry *remotehost, /* use this one */
                           curl_socket_t *sockconn,   /* the connected socket */
                           Curl_addrinfo **addr,      /* the one we used */
                           bool *connected)           /* really connected? */
@@ -704,7 +817,7 @@
     long has_passed;
 
     /* Evaluate in milliseconds how much time that has passed */
-    has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start);
+    has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
 
 #ifndef min
 #define min(a, b)   ((a) < (b) ? (a) : (b))
@@ -731,6 +844,7 @@
       return CURLE_OPERATION_TIMEOUTED;
     }
   }
+  Curl_expire(data, timeout_ms);
 
   /* Max time for each address */
   num_addr = Curl_num_addresses(remotehost->addr);
@@ -744,7 +858,7 @@
 
   if(data->state.used_interface == Curl_if_multi)
     /* don't hang when doing multi */
-    timeout_per_addr = timeout_ms = 0;
+    timeout_per_addr = 0;
 
   /*
    * Connecting with a Curl_addrinfo chain
@@ -771,6 +885,7 @@
   if (sockfd == CURL_SOCKET_BAD) {
     /* no good connect was made */
     *sockconn = CURL_SOCKET_BAD;
+    failf(data, "couldn't connect to host");
     return CURLE_COULDNT_CONNECT;
   }
 
@@ -784,5 +899,7 @@
   if(sockconn)
     *sockconn = sockfd;    /* the socket descriptor we've connected */
 
+  data->info.numconnects++; /* to track the number of connections made */
+
   return CURLE_OK;
 }

Index: config.h.in
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/config.h.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- config.h.in	24 Jun 2005 13:01:05 -0000	1.1
+++ config.h.in	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,4 +1,13 @@
-/* lib/config.h.in.  Generated from configure.in by autoheader.  */
+/* lib/config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* when building libcurl itself */
+#cmakedefine BUILDING_LIBCURL ${BUILDING_LIBCURL}
+
+/* to disable cookies support */
+#cmakedefine CURL_DISABLE_COOKIES ${CURL_DISABLE_COOKIES}
+
+/* to disable cryptographic authentication */
+#cmakedefine CURL_DISABLE_CRYPTO_AUTH ${CURL_DISABLE_CRYPTO_AUTH}
 
 /* to disable DICT */
 #cmakedefine CURL_DISABLE_DICT ${CURL_DISABLE_DICT}
@@ -9,9 +18,6 @@
 /* to disable FTP */
 #cmakedefine CURL_DISABLE_FTP ${CURL_DISABLE_FTP}
 
-/* to disable GOPHER */
-#cmakedefine CURL_DISABLE_GOPHER ${CURL_DISABLE_GOPHER}
-
 /* to disable HTTP */
 #cmakedefine CURL_DISABLE_HTTP ${CURL_DISABLE_HTTP}
 
@@ -21,24 +27,66 @@
 /* to disable TELNET */
 #cmakedefine CURL_DISABLE_TELNET ${CURL_DISABLE_TELNET}
 
+/* to disable TFTP */
+#cmakedefine CURL_DISABLE_TFTP ${CURL_DISABLE_TFTP}
+
+/* to disable verbose strings */
+#cmakedefine CURL_DISABLE_VERBOSE_STRINGS ${CURL_DISABLE_VERBOSE_STRINGS}
+
+/* to make a symbol visible */
+#cmakedefine CURL_EXTERN_SYMBOL ${CURL_EXTERN_SYMBOL}
+
+/* to enable hidden symbols */
+#cmakedefine CURL_HIDDEN_SYMBOLS ${CURL_HIDDEN_SYMBOLS}
+
+/* when not building a shared library */
+#cmakedefine CURL_STATICLIB ${CURL_STATICLIB}
+
 /* Set to explicitly specify we don't want to use thread-safe functions */
 #cmakedefine DISABLED_THREADSAFE ${DISABLED_THREADSAFE}
 
+/* lber dynamic library file */
+#cmakedefine DL_LBER_FILE ${DL_LBER_FILE}
+
+/* ldap dynamic library file */
+#cmakedefine DL_LDAP_FILE ${DL_LDAP_FILE}
+
 /* your Entropy Gathering Daemon socket pathname */
 #cmakedefine EGD_SOCKET ${EGD_SOCKET}
 
 /* Define if you want to enable IPv6 support */
 #cmakedefine ENABLE_IPV6 ${ENABLE_IPV6}
 
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#cmakedefine GETNAMEINFO_QUAL_ARG1 ${GETNAMEINFO_QUAL_ARG1}
+
+/* Define to the type of arg 1 for getnameinfo. */
+#cmakedefine GETNAMEINFO_TYPE_ARG1 ${GETNAMEINFO_TYPE_ARG1}
+
+/* Define to the type of arg 2 for getnameinfo. */
+#cmakedefine GETNAMEINFO_TYPE_ARG2 ${GETNAMEINFO_TYPE_ARG2}
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#cmakedefine GETNAMEINFO_TYPE_ARG46 ${GETNAMEINFO_TYPE_ARG46}
+
+/* Define to the type of arg 7 for getnameinfo. */
+#cmakedefine GETNAMEINFO_TYPE_ARG7 ${GETNAMEINFO_TYPE_ARG7}
+
 /* Define to 1 if you have the <alloca.h> header file. */
 #cmakedefine HAVE_ALLOCA_H ${HAVE_ALLOCA_H}
 
 /* Define to 1 if you have the <arpa/inet.h> header file. */
 #cmakedefine HAVE_ARPA_INET_H ${HAVE_ARPA_INET_H}
 
+/* Define to 1 if you have the <arpa/tftp.h> header file. */
+#cmakedefine HAVE_ARPA_TFTP_H ${HAVE_ARPA_TFTP_H}
+
 /* Define to 1 if you have the <assert.h> header file. */
 #cmakedefine HAVE_ASSERT_H ${HAVE_ASSERT_H}
 
+/* Define to 1 if you have the `basename' function. */
+#cmakedefine HAVE_BASENAME ${HAVE_BASENAME}
+
 /* Define to 1 if you have the `closesocket' function. */
 #cmakedefine HAVE_CLOSESOCKET ${HAVE_CLOSESOCKET}
 
@@ -60,6 +108,12 @@
 /* Define to 1 if you have the `dlopen' function. */
 #cmakedefine HAVE_DLOPEN ${HAVE_DLOPEN}
 
+/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
+#cmakedefine HAVE_ENGINE_LOAD_BUILTIN_ENGINES ${HAVE_ENGINE_LOAD_BUILTIN_ENGINES}
+
+/* Define to 1 if you have the <errno.h> header file. */
+#cmakedefine HAVE_ERRNO_H ${HAVE_ERRNO_H}
+
 /* Define to 1 if you have the <err.h> header file. */
 #cmakedefine HAVE_ERR_H ${HAVE_ERR_H}
 
@@ -69,6 +123,12 @@
 /* use FIONBIO for non-blocking sockets */
 #cmakedefine HAVE_FIONBIO ${HAVE_FIONBIO}
 
+/* Define to 1 if you have the `fork' function. */
+#cmakedefine HAVE_FORK ${HAVE_FORK}
+
+/* Define to 1 if you have the `ftruncate' function. */
+#cmakedefine HAVE_FTRUNCATE ${HAVE_FTRUNCATE}
+
 /* Define if getaddrinfo exists and works */
 #cmakedefine HAVE_GETADDRINFO ${HAVE_GETADDRINFO}
 
@@ -93,12 +153,21 @@
 /* gethostbyname_r() takes 6 args */
 #cmakedefine HAVE_GETHOSTBYNAME_R_6 ${HAVE_GETHOSTBYNAME_R_6}
 
+/* Define to 1 if you have the getnameinfo function. */
+#cmakedefine HAVE_GETNAMEINFO ${HAVE_GETNAMEINFO}
+
 /* Define to 1 if you have the `getpass_r' function. */
 #cmakedefine HAVE_GETPASS_R ${HAVE_GETPASS_R}
 
+/* Define to 1 if you have the `getprotobyname' function. */
+#cmakedefine HAVE_GETPROTOBYNAME ${HAVE_GETPROTOBYNAME}
+
 /* Define to 1 if you have the `getpwuid' function. */
 #cmakedefine HAVE_GETPWUID ${HAVE_GETPWUID}
 
+/* Define to 1 if you have the `getrlimit' function. */
+#cmakedefine HAVE_GETRLIMIT ${HAVE_GETRLIMIT}
+
 /* Define to 1 if you have the `gettimeofday' function. */
 #cmakedefine HAVE_GETTIMEOFDAY ${HAVE_GETTIMEOFDAY}
 
@@ -111,12 +180,18 @@
 /* if you have the gssapi libraries */
 #cmakedefine HAVE_GSSAPI ${HAVE_GSSAPI}
 
+/* if you have the GNU gssapi libraries */
+#cmakedefine HAVE_GSSGNU ${HAVE_GSSGNU}
+
 /* if you have the Heimdal gssapi libraries */
 #cmakedefine HAVE_GSSHEIMDAL ${HAVE_GSSHEIMDAL}
 
 /* if you have the MIT gssapi libraries */
 #cmakedefine HAVE_GSSMIT ${HAVE_GSSMIT}
 
+/* Define to 1 if you have the `idna_strerror' function. */
+#cmakedefine HAVE_IDNA_STRERROR ${HAVE_IDNA_STRERROR}
+
 /* Define to 1 if you have the `idn_free' function. */
 #cmakedefine HAVE_IDN_FREE ${HAVE_IDN_FREE}
 
@@ -159,12 +234,12 @@
 /* Define to 1 if you have the <krb.h> header file. */
 #cmakedefine HAVE_KRB_H ${HAVE_KRB_H}
 
-/* Define to 1 if you have the `crypto' library (-lcrypto). */
-#cmakedefine HAVE_LIBCRYPTO ${HAVE_LIBCRYPTO}
-
 /* Define to 1 if you have the `dl' library (-ldl). */
 #cmakedefine HAVE_LIBDL ${HAVE_LIBDL}
 
+/* Define to 1 if you have the <libgen.h> header file. */
+#cmakedefine HAVE_LIBGEN_H ${HAVE_LIBGEN_H}
+
 /* Define to 1 if you have the `idn' library (-lidn). */
 #cmakedefine HAVE_LIBIDN ${HAVE_LIBIDN}
 
@@ -177,6 +252,12 @@
 /* Define to 1 if you have the `socket' library (-lsocket). */
 #cmakedefine HAVE_LIBSOCKET ${HAVE_LIBSOCKET}
 
+/* Define to 1 if you have the `ssh2' library (-lssh2). */
+#cmakedefine HAVE_LIBSSH2 ${HAVE_LIBSSH2}
+
+/* Define to 1 if you have the <libssh2.h> header file. */
+#cmakedefine HAVE_LIBSSH2_H ${HAVE_LIBSSH2_H}
+
 /* Define to 1 if you have the `ssl' library (-lssl). */
 #cmakedefine HAVE_LIBSSL ${HAVE_LIBSSL}
 
@@ -186,18 +267,27 @@
 /* Define to 1 if you have the <limits.h> header file. */
 #cmakedefine HAVE_LIMITS_H ${HAVE_LIMITS_H}
 
+/* if your compiler supports LL */
+#cmakedefine HAVE_LL ${HAVE_LL}
+
+/* Define to 1 if you have the <locale.h> header file. */
+#cmakedefine HAVE_LOCALE_H ${HAVE_LOCALE_H}
+
 /* Define to 1 if you have the `localtime_r' function. */
 #cmakedefine HAVE_LOCALTIME_R ${HAVE_LOCALTIME_R}
 
-/* if your compiler supports 'long long' */
+/* if your compiler supports long long */
 #cmakedefine HAVE_LONGLONG ${HAVE_LONGLONG}
 
-/* Define to 1 if you have the <malloc.h> header file. */
+/* Define to 1 if you have the malloc.h header file. */
 #cmakedefine HAVE_MALLOC_H ${HAVE_MALLOC_H}
 
 /* Define to 1 if you have the <memory.h> header file. */
 #cmakedefine HAVE_MEMORY_H ${HAVE_MEMORY_H}
 
+/* Define to 1 if you have the MSG_NOSIGNAL flag. */
+#cmakedefine HAVE_MSG_NOSIGNAL ${HAVE_MSG_NOSIGNAL}
+
 /* Define to 1 if you have the <netdb.h> header file. */
 #cmakedefine HAVE_NETDB_H ${HAVE_NETDB_H}
 
@@ -210,9 +300,12 @@
 /* Define to 1 if you have the <net/if.h> header file. */
 #cmakedefine HAVE_NET_IF_H ${HAVE_NET_IF_H}
 
-/* Define if NI_WITHSCOPEID exists and works */
+/* Define to 1 if NI_WITHSCOPEID exists and works. */
 #cmakedefine HAVE_NI_WITHSCOPEID ${HAVE_NI_WITHSCOPEID}
 
+/* Defined if no inet_pton() prototype available */
+#cmakedefine HAVE_NO_INET_PTON_PROTO ${HAVE_NO_INET_PTON_PROTO}
+
 /* we have no strerror_r() proto */
 #cmakedefine HAVE_NO_STRERROR_R_DECL ${HAVE_NO_STRERROR_R_DECL}
 
@@ -228,6 +321,9 @@
 /* Define to 1 if you have the <openssl/pem.h> header file. */
 #cmakedefine HAVE_OPENSSL_PEM_H ${HAVE_OPENSSL_PEM_H}
 
+/* Define to 1 if you have the <openssl/pkcs12.h> header file. */
+#cmakedefine HAVE_OPENSSL_PKCS12_H ${HAVE_OPENSSL_PKCS12_H}
+
 /* Define to 1 if you have the <openssl/rsa.h> header file. */
 #cmakedefine HAVE_OPENSSL_RSA_H ${HAVE_OPENSSL_RSA_H}
 
@@ -246,6 +342,9 @@
 /* Define to 1 if you have the `perror' function. */
 #cmakedefine HAVE_PERROR ${HAVE_PERROR}
 
+/* Define to 1 if you have the `pipe' function. */
+#cmakedefine HAVE_PIPE ${HAVE_PIPE}
+
 /* Define to 1 if you have the `poll' function. */
 #cmakedefine HAVE_POLL ${HAVE_POLL}
 
@@ -267,15 +366,27 @@
 /* Define to 1 if you have the `RAND_status' function. */
 #cmakedefine HAVE_RAND_STATUS ${HAVE_RAND_STATUS}
 
+/* Define to 1 if you have the recv function. */
+#cmakedefine HAVE_RECV ${HAVE_RECV}
+
 /* Define to 1 if you have the <rsa.h> header file. */
 #cmakedefine HAVE_RSA_H ${HAVE_RSA_H}
 
-/* Define to 1 if you have the `select' function. */
+/* Define to 1 if you have the select function. */
 #cmakedefine HAVE_SELECT ${HAVE_SELECT}
 
+/* Define to 1 if you have the send function. */
+#cmakedefine HAVE_SEND ${HAVE_SEND}
+
 /* Define to 1 if you have the <setjmp.h> header file. */
 #cmakedefine HAVE_SETJMP_H ${HAVE_SETJMP_H}
 
+/* Define to 1 if you have the `setlocale' function. */
+#cmakedefine HAVE_SETLOCALE ${HAVE_SETLOCALE}
+
+/* Define to 1 if you have the `setrlimit' function. */
+#cmakedefine HAVE_SETRLIMIT ${HAVE_SETRLIMIT}
+
 /* Define to 1 if you have the <sgtty.h> header file. */
 #cmakedefine HAVE_SGTTY_H ${HAVE_SGTTY_H}
 
@@ -288,9 +399,18 @@
 /* Define to 1 if you have the `signal' function. */
 #cmakedefine HAVE_SIGNAL ${HAVE_SIGNAL}
 
+/* Define to 1 if you have the <signal.h> header file. */
+#cmakedefine HAVE_SIGNAL_H ${HAVE_SIGNAL_H}
+
 /* If you have sigsetjmp */
 #cmakedefine HAVE_SIGSETJMP ${HAVE_SIGSETJMP}
 
+/* Define to 1 if sig_atomic_t is an available typedef. */
+#cmakedefine HAVE_SIG_ATOMIC_T ${HAVE_SIG_ATOMIC_T}
+
+/* Define to 1 if sig_atomic_t is already defined as volatile. */
+#cmakedefine HAVE_SIG_ATOMIC_T_VOLATILE ${HAVE_SIG_ATOMIC_T_VOLATILE}
+
 /* Define to 1 if you have the `socket' function. */
 #cmakedefine HAVE_SOCKET ${HAVE_SOCKET}
 
@@ -306,6 +426,9 @@
 /* Define to 1 if you have the <stdint.h> header file. */
 #cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
 
+/* Define to 1 if you have the <stdio.h> header file. */
+#cmakedefine HAVE_STDIO_H ${HAVE_STDIO_H}
+
 /* Define to 1 if you have the <stdlib.h> header file. */
 #cmakedefine HAVE_STDLIB_H ${HAVE_STDLIB_H}
 
@@ -321,9 +444,6 @@
 /* Define to 1 if you have the `strerror_r' function. */
 #cmakedefine HAVE_STRERROR_R ${HAVE_STRERROR_R}
 
-/* Define to 1 if you have the `strftime' function. */
-#cmakedefine HAVE_STRFTIME ${HAVE_STRFTIME}
-
 /* Define to 1 if you have the `stricmp' function. */
 #cmakedefine HAVE_STRICMP ${HAVE_STRICMP}
 
@@ -348,6 +468,15 @@
 /* Define to 1 if you have the `strtoll' function. */
 #cmakedefine HAVE_STRTOLL ${HAVE_STRTOLL}
 
+/* if struct sockaddr_storage is defined */
+#cmakedefine HAVE_STRUCT_SOCKADDR_STORAGE ${HAVE_STRUCT_SOCKADDR_STORAGE}
+
+/* Define to 1 if you have the timeval struct. */
+#cmakedefine HAVE_STRUCT_TIMEVAL ${HAVE_STRUCT_TIMEVAL}
+
+/* Define to 1 if you have the <sys/filio.h> header file. */
+#cmakedefine HAVE_SYS_FILIO_H ${HAVE_SYS_FILIO_H}
+
 /* Define to 1 if you have the <sys/ioctl.h> header file. */
 #cmakedefine HAVE_SYS_IOCTL_H ${HAVE_SYS_IOCTL_H}
 
@@ -357,6 +486,9 @@
 /* Define to 1 if you have the <sys/poll.h> header file. */
 #cmakedefine HAVE_SYS_POLL_H ${HAVE_SYS_POLL_H}
 
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#cmakedefine HAVE_SYS_RESOURCE_H ${HAVE_SYS_RESOURCE_H}
+
 /* Define to 1 if you have the <sys/select.h> header file. */
 #cmakedefine HAVE_SYS_SELECT_H ${HAVE_SYS_SELECT_H}
 
@@ -378,12 +510,6 @@
 /* Define to 1 if you have the <sys/utime.h> header file. */
 #cmakedefine HAVE_SYS_UTIME_H ${HAVE_SYS_UTIME_H}
 
-/* Define to 1 if you have the `tcgetattr' function. */
-#cmakedefine HAVE_TCGETATTR ${HAVE_TCGETATTR}
-
-/* Define to 1 if you have the `tcsetattr' function. */
-#cmakedefine HAVE_TCSETATTR ${HAVE_TCSETATTR}
-
 /* Define to 1 if you have the <termios.h> header file. */
 #cmakedefine HAVE_TERMIOS_H ${HAVE_TERMIOS_H}
 
@@ -393,6 +519,12 @@
 /* Define to 1 if you have the <time.h> header file. */
 #cmakedefine HAVE_TIME_H ${HAVE_TIME_H}
 
+/* Define to 1 if you have the <tld.h> header file. */
+#cmakedefine HAVE_TLD_H ${HAVE_TLD_H}
+
+/* Define to 1 if you have the `tld_strerror' function. */
+#cmakedefine HAVE_TLD_STRERROR ${HAVE_TLD_STRERROR}
+
 /* Define to 1 if you have the `uname' function. */
 #cmakedefine HAVE_UNAME ${HAVE_UNAME}
 
@@ -405,44 +537,74 @@
 /* Define to 1 if you have the <utime.h> header file. */
 #cmakedefine HAVE_UTIME_H ${HAVE_UTIME_H}
 
-/* Define to 1 if you have the <winsock.h> header file. */
+/* Define to 1 if you have the windows.h header file. */
+#cmakedefine HAVE_WINDOWS_H ${HAVE_WINDOWS_H}
+
+/* Define to 1 if you have the winsock2.h header file. */
+#cmakedefine HAVE_WINSOCK2_H ${HAVE_WINSOCK2_H}
+
+/* Define to 1 if you have the winsock.h header file. */
 #cmakedefine HAVE_WINSOCK_H ${HAVE_WINSOCK_H}
 
 /* Define this symbol if your OS supports changing the contents of argv */
 #cmakedefine HAVE_WRITABLE_ARGV ${HAVE_WRITABLE_ARGV}
 
+/* Define to 1 if you have the ws2tcpip.h header file. */
+#cmakedefine HAVE_WS2TCPIP_H ${HAVE_WS2TCPIP_H}
+
 /* Define to 1 if you have the <x509.h> header file. */
 #cmakedefine HAVE_X509_H ${HAVE_X509_H}
 
 /* if you have the zlib.h header file */
 #cmakedefine HAVE_ZLIB_H ${HAVE_ZLIB_H}
 
+/* If you lack a fine basename() prototype */
+#cmakedefine NEED_BASENAME_PROTO ${NEED_BASENAME_PROTO}
+
+/* Define to 1 if you need the malloc.h header file even with stdlib.h */
+#cmakedefine NEED_MALLOC_H ${NEED_MALLOC_H}
+
 /* need REENTRANT defined */
 #cmakedefine NEED_REENTRANT ${NEED_REENTRANT}
 
 /* cpu-machine-OS */
-#define OS         "${OPERATING_SYSTEM}"
+#define OS "${OPERATING_SYSTEM}"
 
 /* Name of package */
-#cmakedefine PACKAGE            "${PACKAGE}"
+#cmakedefine PACKAGE "${PACKAGE}"
 
 /* Define to the address where bug reports for this package should be sent. */
-#cmakedefine PACKAGE_BUGREPORT          "${PACKAGE_BUGREPORT}"
+#cmakedefine PACKAGE_BUGREPORT "${PACKAGE_BUGREPORT}"
 
 /* Define to the full name of this package. */
-#cmakedefine PACKAGE_NAME               "${PACKAGE_NAME}"
+#cmakedefine PACKAGE_NAME "${PACKAGE_NAME}"
 
 /* Define to the full name and version of this package. */
-#cmakedefine PACKAGE_STRING             "${PACKAGE_STRING}"
+#cmakedefine PACKAGE_STRING "${PACKAGE_STRING}"
 
 /* Define to the one symbol short name of this package. */
-#cmakedefine PACKAGE_TARNAME            "${PACKAGE_TARNAME}"
+#cmakedefine PACKAGE_TARNAME "${PACKAGE_TARNAME}"
 
 /* Define to the version of this package. */
-#cmakedefine PACKAGE_VERSION            "${PACKAGE_VERSION}"
+#cmakedefine PACKAGE_VERSION "${PACKAGE_VERSION}"
 
 /* a suitable file to read random data from */
-#cmakedefine RANDOM_FILE                "${RANDOM_FILE}"
+#cmakedefine RANDOM_FILE "${RANDOM_FILE}"
+
+/* Define to the type of arg 1 for recv. */
+#cmakedefine RECV_TYPE_ARG1 ${RECV_TYPE_ARG1}
+
+/* Define to the type of arg 2 for recv. */
+#cmakedefine RECV_TYPE_ARG2 ${RECV_TYPE_ARG2}
+
+/* Define to the type of arg 3 for recv. */
+#cmakedefine RECV_TYPE_ARG3 ${RECV_TYPE_ARG3}
+
+/* Define to the type of arg 4 for recv. */
+#cmakedefine RECV_TYPE_ARG4 ${RECV_TYPE_ARG4}
+
+/* Define to the function return type for recv. */
+#cmakedefine RECV_TYPE_RETV ${RECV_TYPE_RETV}
 
 /* Define as the return type of signal handlers (`int' or `void'). */
 #cmakedefine RETSIGTYPE ${RETSIGTYPE}
@@ -456,12 +618,36 @@
 /* Define to the type of arg 5 for `select'. */
 #cmakedefine SELECT_TYPE_ARG5 ${SELECT_TYPE_ARG5}
 
-/* The size of a `curl_off_t', as computed by sizeof. */
+/* Define to the type qualifier of arg 2 for send. */
+#cmakedefine SEND_QUAL_ARG2 ${SEND_QUAL_ARG2}
+
+/* Define to the type of arg 1 for send. */
+#cmakedefine SEND_TYPE_ARG1 ${SEND_TYPE_ARG1}
+
+/* Define to the type of arg 2 for send. */
+#cmakedefine SEND_TYPE_ARG2 ${SEND_TYPE_ARG2}
+
+/* Define to the type of arg 3 for send. */
+#cmakedefine SEND_TYPE_ARG3 ${SEND_TYPE_ARG3}
+
+/* Define to the type of arg 4 for send. */
+#cmakedefine SEND_TYPE_ARG4 ${SEND_TYPE_ARG4}
+
+/* Define to the function return type for send. */
+#cmakedefine SEND_TYPE_RETV ${SEND_TYPE_RETV}
+
+/* The size of `curl_off_t', as computed by sizeof. */
 #cmakedefine SIZEOF_CURL_OFF_T ${SIZEOF_CURL_OFF_T}
 
-/* The size of a `size_t', as computed by sizeof. */
+/* The size of `long', as computed by sizeof. */
+#cmakedefine SIZEOF_LONG ${SIZEOF_LONG}
+
+/* The size of `size_t', as computed by sizeof. */
 #cmakedefine SIZEOF_SIZE_T ${SIZEOF_SIZE_T}
 
+/* The size of `time_t', as computed by sizeof. */
+#cmakedefine SIZEOF_TIME_T ${SIZEOF_TIME_T}
+
 /* Define to 1 if you have the ANSI C header files. */
 #cmakedefine STDC_HEADERS ${STDC_HEADERS}
 
@@ -471,11 +657,29 @@
 /* Define if you want to enable ares support */
 #cmakedefine USE_ARES ${USE_ARES}
 
+/* if GnuTLS is enabled */
+#cmakedefine USE_GNUTLS ${USE_GNUTLS}
+
+/* if libSSH2 is in use */
+#cmakedefine USE_LIBSSH2 ${USE_LIBSSH2}
+
 /* If you want to build curl with the built-in manual */
 #cmakedefine USE_MANUAL ${USE_MANUAL}
 
+/* if OpenSSL is in use */
+#cmakedefine USE_OPENSSL ${USE_OPENSSL}
+
+/* if SSL is enabled */
+#cmakedefine USE_SSLEAY ${USE_SSLEAY}
+
+/* to enable SSPI support */
+#cmakedefine USE_WINDOWS_SSPI ${USE_WINDOWS_SSPI}
+
 /* Version number of package */
-#cmakedefine VERSION            "${VERSION}"
+#cmakedefine VERSION "${VERSION}"
+
+/* Define to avoid automatic inclusion of winsock.h */
+#cmakedefine WIN32_LEAN_AND_MEAN ${WIN32_LEAN_AND_MEAN}
 
 /* Define to 1 if on AIX 3.
    System headers sometimes define this.
@@ -490,13 +694,16 @@
 /* Define for large files, on AIX-style hosts. */
 #cmakedefine _LARGE_FILES ${_LARGE_FILES}
 
+/* define this if you need it to compile thread-safe code */
+#cmakedefine _THREAD_SAFE ${_THREAD_SAFE}
+
 /* Define to empty if `const' does not conform to ANSI C. */
 #cmakedefine const ${const}
 
 /* type to use in place of in_addr_t if not defined */
 #cmakedefine in_addr_t ${in_addr_t}
 
-/* Define to `unsigned' if <sys/types.h> does not define. */
+/* Define to `unsigned int' if <sys/types.h> does not define. */
 #cmakedefine size_t ${size_t}
 
 /* type to use in place of socklen_t if not defined */
@@ -505,8 +712,5 @@
 /* the signed version of size_t */
 #cmakedefine ssize_t ${ssize_t}
 
-/* define if the compiler supports number 0x3627676LL */
-#cmakedefine HAVE_LONG_LONG_CONSTANT ${HAVE_LONG_LONG_CONSTANT}
-
 /* Special handling of zlib library */
 #cmakedefine CURL_SPECIAL_ZLIB_H "${CURL_SPECIAL_ZLIB_H}"

--- NEW FILE: strdup.c ---
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: strdup.c,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

#include "setup.h"
#include "strdup.h"

#ifndef HAVE_STRDUP
char *curlx_strdup(const char *str)
{
  int len;
  char *newstr;

  if (!str)
    return (char *)NULL;

  len = strlen(str);
  newstr = (char *) malloc((len+1)*sizeof(char));
  if (!newstr)
    return (char *)NULL;

  strcpy(newstr,str);

  return newstr;

}
#endif

Index: hostip6.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/hostip6.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- hostip6.c	24 Jun 2005 13:00:12 -0000	1.1
+++ hostip6.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,16 +1,16 @@
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -24,13 +24,10 @@
 #include "setup.h"
 
 #include <string.h>
-#include <errno.h>
-
-#define _REENTRANT
 
-#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
+#ifdef NEED_MALLOC_H
 #include <malloc.h>
-#else
+#endif
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -57,21 +54,15 @@
 #include <inet.h>
 #include <stdlib.h>
 #endif
-#endif
 
 #ifdef HAVE_SETJMP_H
 #include <setjmp.h>
 #endif
 
-#ifdef WIN32
+#ifdef HAVE_PROCESS_H
 #include <process.h>
 #endif
 
-#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
-#undef in_addr_t
-#define in_addr_t unsigned long
-#endif
-
 #include "urldata.h"
 #include "sendf.h"
 #include "hostip.h"
@@ -79,6 +70,8 @@
 #include "share.h"
 #include "strerror.h"
 #include "url.h"
+#include "inet_pton.h"
+#include "connect.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -87,7 +80,7 @@
 #include "inet_ntoa_r.h"
 #endif
 
-#include "curl_memory.h"
+#include "memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
 
@@ -95,6 +88,7 @@
  * Only for ipv6-enabled builds
  **********************************************************************/
 #ifdef CURLRES_IPV6
+#ifndef CURLRES_ARES
 /*
  * This is a wrapper function for freeing name information in a protocol
  * independent way. This takes care of using the appropriate underlaying
@@ -111,19 +105,20 @@
  * address. But this is an ipv6 build and then we don't copy the address, we
  * just return the same pointer!
  */
-Curl_addrinfo *Curl_addrinfo_copy(void *source, int port)
+Curl_addrinfo *Curl_addrinfo_copy(const void *orig, int port)
 {
   (void) port;
-  return source;
+  return (Curl_addrinfo*)orig;
 }
-#endif
+#endif  /* CURLRES_ASYNCH */
+#endif  /* CURLRES_ARES */
 
 #ifdef CURLDEBUG
 /* These are strictly for memory tracing and are using the same style as the
  * family otherwise present in memdebug.c. I put these ones here since they
  * require a bunch of structs I didn't wanna include in memdebug.c
  */
-int curl_dogetaddrinfo(char *hostname, char *service,
+int curl_dogetaddrinfo(const char *hostname, const char *service,
                        struct addrinfo *hints,
                        struct addrinfo **result,
                        int line, const char *source)
@@ -143,12 +138,22 @@
   return res;
 }
 
-int curl_dogetnameinfo(const struct sockaddr *sa, socklen_t salen,
-                       char *host, size_t hostlen,
-                       char *serv, size_t servlen, int flags,
+/*
+ * For CURLRES_ARS, this should be written using ares_gethostbyaddr()
+ * (ignoring the fact c-ares doesn't return 'serv').
+ */
+#ifdef HAVE_GETNAMEINFO
+int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
+                       GETNAMEINFO_TYPE_ARG2 salen,
+                       char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
+                       char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
+                       GETNAMEINFO_TYPE_ARG7 flags,
                        int line, const char *source)
 {
-  int res=(getnameinfo)(sa, salen, host, hostlen, serv, servlen, flags);
+  int res = (getnameinfo)(sa, salen,
+                          host, hostlen,
+                          serv, servlen,
+                          flags);
   if(0 == res) {
     /* success */
     if(logfile)
@@ -162,6 +167,7 @@
   }
   return res;
 }
+#endif
 
 void curl_dofreeaddrinfo(struct addrinfo *freethis,
                          int line, const char *source)
@@ -171,8 +177,7 @@
     fprintf(logfile, "ADDR %s:%d freeaddrinfo(%p)\n",
             source, line, (void *)freethis);
 }
-
-#endif
+#endif  /* CURLDEBUG */
 
 /*
  * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
@@ -191,9 +196,30 @@
   return TRUE;
 }
 
-#ifndef USE_THREADING_GETADDRINFO
+#if !defined(USE_THREADING_GETADDRINFO) && !defined(CURLRES_ARES)
+
+#ifdef DEBUG_ADDRINFO
+static void dump_addrinfo(struct connectdata *conn, const struct addrinfo *ai)
+{
+  printf("dump_addrinfo:\n");
+  for ( ; ai; ai = ai->ai_next) {
+    char  buf[INET6_ADDRSTRLEN];
+
+    printf("    fam %2d, CNAME %s, ",
+           ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
+    if (Curl_printable_address(ai, buf, sizeof(buf)))
+      printf("%s\n", buf);
+    else
+      printf("failed; %s\n", Curl_strerror(conn, Curl_sockerrno()));
+  }
+}
+#else
+#define dump_addrinfo(x,y)
+#endif
+
 /*
- * Curl_getaddrinfo() when built ipv6-enabled (non-threading version).
+ * Curl_getaddrinfo() when built ipv6-enabled (non-threading and
+ * non-ares version).
  *
  * Returns name information about the given hostname and port number. If
  * successful, the 'addrinfo' is returned and the forth argument will point to
@@ -201,13 +227,15 @@
  * Curl_freeaddrinfo(), nothing else.
  */
 Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
-                                char *hostname,
+                                const char *hostname,
                                 int port,
                                 int *waitp)
 {
   struct addrinfo hints, *res;
   int error;
   char sbuf[NI_MAXSERV];
+  char *sbufptr = NULL;
+  char addrbuf[128];
   curl_socket_t s;
   int pf;
   struct SessionHandle *data = conn->data;
@@ -216,7 +244,7 @@
 
   /* see if we have an IPv6 stack */
   s = socket(PF_INET6, SOCK_DGRAM, 0);
-  if (s < 0) {
+  if (s == CURL_SOCKET_BAD) {
     /* Some non-IPv6 stacks have been found to make very slow name resolves
      * when PF_UNSPEC is used, so thus we switch to a mere PF_INET lookup if
      * the stack seems to be a non-ipv6 one. */
@@ -244,20 +272,35 @@
       break;
     }
   }
- 
+
   memset(&hints, 0, sizeof(hints));
   hints.ai_family = pf;
-  hints.ai_socktype = SOCK_STREAM;
-  hints.ai_flags = AI_CANONNAME;
-  snprintf(sbuf, sizeof(sbuf), "%d", port);
-  error = getaddrinfo(hostname, sbuf, &hints, &res);
+  hints.ai_socktype = conn->socktype;
+
+  if((1 == Curl_inet_pton(AF_INET, hostname, addrbuf)) ||
+     (1 == Curl_inet_pton(AF_INET6, hostname, addrbuf))) {
+    /* the given address is numerical only, prevent a reverse lookup */
+    hints.ai_flags = AI_NUMERICHOST;
+  }
+#if 0 /* removed nov 8 2005 before 7.15.1 */
+  else
+    hints.ai_flags = AI_CANONNAME;
+#endif
+
+  if(port) {
+    snprintf(sbuf, sizeof(sbuf), "%d", port);
+    sbufptr=sbuf;
+  }
+  error = getaddrinfo(hostname, sbufptr, &hints, &res);
   if (error) {
-    infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);    
+    infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);
     return NULL;
   }
 
+  dump_addrinfo(conn, res);
+
   return res;
 }
-#endif /* USE_THREADING_GETADDRINFO */
+#endif /* !USE_THREADING_GETADDRINFO && !CURLRES_ARES */
 #endif /* ipv6 */
 

Index: content_encoding.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/content_encoding.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- content_encoding.c	24 Jun 2005 13:00:12 -0000	1.1
+++ content_encoding.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -32,10 +32,14 @@
 #include <curl/curl.h>
 #include "sendf.h"
 #include "content_encoding.h"
-#include "curl_memory.h"
+#include "memory.h"
 
 #include "memdebug.h"
 
+/* Comment this out if zlib is always going to be at least ver. 1.2.0.4
+   (doing so will reduce code size slightly). */
+#define OLD_ZLIB_SUPPORT 1
+
 #define DSIZ 0x10000             /* buffer size for decompressed data */
 
 #define GZIP_MAGIC_0 0x1f
@@ -49,14 +53,23 @@
 #define COMMENT      0x10 /* bit 4 set: file comment present */
 #define RESERVED     0xE0 /* bits 5..7: reserved */
 
+enum zlibState {
+  ZLIB_UNINIT,          /* uninitialized */
+  ZLIB_INIT,            /* initialized */
+  ZLIB_GZIP_HEADER,     /* reading gzip header */
+  ZLIB_GZIP_INFLATING,  /* inflating gzip stream */
+  ZLIB_INIT_GZIP        /* initialized in transparent gzip mode */
+};
+
 static CURLcode
-process_zlib_error(struct SessionHandle *data, z_stream *z)
+process_zlib_error(struct connectdata *conn, z_stream *z)
 {
+  struct SessionHandle *data = conn->data;
   if (z->msg)
-    failf (data, "Error while processing content unencoding.\n%s",
+    failf (data, "Error while processing content unencoding: %s",
            z->msg);
   else
-    failf (data, "Error while processing content unencoding.\n"
+    failf (data, "Error while processing content unencoding: "
            "Unknown failure within decompression software.");
 
   return CURLE_BAD_CONTENT_ENCODING;
@@ -66,71 +79,113 @@
 exit_zlib(z_stream *z, bool *zlib_init, CURLcode result)
 {
   inflateEnd(z);
-  *zlib_init = 0;
+  *zlib_init = ZLIB_UNINIT;
   return result;
 }
 
-CURLcode
-Curl_unencode_deflate_write(struct SessionHandle *data,
-                            struct Curl_transfer_keeper *k,
-                            ssize_t nread)
+static CURLcode
+inflate_stream(struct connectdata *conn,
+               struct Curl_transfer_keeper *k)
 {
+  int allow_restart = 1;
+  z_stream *z = &k->z;          /* zlib state structure */
+  uInt nread = z->avail_in;
+  Bytef *orig_in = z->next_in;
   int status;                   /* zlib status */
   CURLcode result = CURLE_OK;   /* Curl_client_write status */
-  char decomp[DSIZ];            /* Put the decompressed data here. */
-  z_stream *z = &k->z;          /* zlib state structure */
+  char *decomp;                 /* Put the decompressed data here. */
 
-  /* Initialize zlib? */
-  if (!k->zlib_init) {
-    z->zalloc = (alloc_func)Z_NULL;
-    z->zfree = (free_func)Z_NULL;
-    z->opaque = 0;
-    z->next_in = NULL;
-    z->avail_in = 0;
-    if (inflateInit(z) != Z_OK)
-      return process_zlib_error(data, z);
-    k->zlib_init = 1;
+  /* Dynamically allocate a buffer for decompression because it's uncommonly
+     large to hold on the stack */
+  decomp = (char*)malloc(DSIZ);
+  if (decomp == NULL) {
+    return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
   }
 
-  /* Set the compressed input when this function is called */
-  z->next_in = (Bytef *)k->str;
-  z->avail_in = (uInt)nread;
-
-  /* because the buffer size is fixed, iteratively decompress
-     and transfer to the client via client_write. */
+  /* because the buffer size is fixed, iteratively decompress and transfer to
+     the client via client_write. */
   for (;;) {
     /* (re)set buffer for decompressed output for every iteration */
-    z->next_out = (Bytef *)&decomp[0];
+    z->next_out = (Bytef *)decomp;
     z->avail_out = DSIZ;
 
     status = inflate(z, Z_SYNC_FLUSH);
     if (status == Z_OK || status == Z_STREAM_END) {
-      if (DSIZ - z->avail_out) {
-        result = Curl_client_write(data, CLIENTWRITE_BODY, decomp,
+      allow_restart = 0;
+      if(DSIZ - z->avail_out) {
+        result = Curl_client_write(conn, CLIENTWRITE_BODY, decomp,
                                    DSIZ - z->avail_out);
         /* if !CURLE_OK, clean up, return */
-        if (result)
+        if (result) {
+          free(decomp);
           return exit_zlib(z, &k->zlib_init, result);
+        }
       }
 
-      /* Done?; clean up, return */
+      /* Done? clean up, return */
       if (status == Z_STREAM_END) {
+        free(decomp);
         if (inflateEnd(z) == Z_OK)
           return exit_zlib(z, &k->zlib_init, result);
         else
-          return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z));
+          return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
       }
 
       /* Done with these bytes, exit */
-      if (status == Z_OK && z->avail_in == 0 && z->avail_out > 0)
+      if (status == Z_OK && z->avail_in == 0) {
+        free(decomp);
         return result;
+      }
+    }
+    else if (allow_restart && status == Z_DATA_ERROR) {
+      /* some servers seem to not generate zlib headers, so this is an attempt
+         to fix and continue anyway */
+
+      inflateReset(z);
+      if (inflateInit2(z, -MAX_WBITS) != Z_OK) {
+        return process_zlib_error(conn, z);
+      }
+      z->next_in = orig_in;
+      z->avail_in = nread;
+      allow_restart = 0;
+      continue;
     }
     else {                      /* Error; exit loop, handle below */
-      return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z));
+      free(decomp);
+      return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
     }
   }
+  /* Will never get here */
 }
 
+CURLcode
+Curl_unencode_deflate_write(struct connectdata *conn,
+                            struct Curl_transfer_keeper *k,
+                            ssize_t nread)
+{
+  z_stream *z = &k->z;          /* zlib state structure */
+
+  /* Initialize zlib? */
+  if (k->zlib_init == ZLIB_UNINIT) {
+    z->zalloc = (alloc_func)Z_NULL;
+    z->zfree = (free_func)Z_NULL;
+    z->opaque = 0;
+    z->next_in = NULL;
+    z->avail_in = 0;
+    if (inflateInit(z) != Z_OK)
+      return process_zlib_error(conn, z);
+    k->zlib_init = ZLIB_INIT;
+  }
+
+  /* Set the compressed input when this function is called */
+  z->next_in = (Bytef *)k->str;
+  z->avail_in = (uInt)nread;
+
+  /* Now uncompress the data */
+  return inflate_stream(conn, k);
+}
+
+#ifdef OLD_ZLIB_SUPPORT
 /* Skip over the gzip header */
 static enum {
   GZIP_OK,
@@ -172,6 +227,7 @@
       return GZIP_UNDERFLOW;
 
     len -= (extra_len + 2);
+    data += (extra_len + 2);
   }
 
   if (flags & ORIG_NAME) {
@@ -213,38 +269,67 @@
   *headerlen = totallen - len;
   return GZIP_OK;
 }
+#endif
 
 CURLcode
-Curl_unencode_gzip_write(struct SessionHandle *data,
+Curl_unencode_gzip_write(struct connectdata *conn,
                          struct Curl_transfer_keeper *k,
                          ssize_t nread)
 {
-  int status;                   /* zlib status */
-  CURLcode result = CURLE_OK;   /* Curl_client_write status */
-  char decomp[DSIZ];            /* Put the decompressed data here. */
   z_stream *z = &k->z;          /* zlib state structure */
 
   /* Initialize zlib? */
-  if (!k->zlib_init) {
+  if (k->zlib_init == ZLIB_UNINIT) {
     z->zalloc = (alloc_func)Z_NULL;
     z->zfree = (free_func)Z_NULL;
     z->opaque = 0;
     z->next_in = NULL;
     z->avail_in = 0;
-    if (inflateInit2(z, -MAX_WBITS) != Z_OK)
-      return process_zlib_error(data, z);
-    k->zlib_init = 1;   /* Initial call state */
+
+    if (strcmp(zlibVersion(), "1.2.0.4") >= 0) {
+        /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */
+        if (inflateInit2(z, MAX_WBITS+32) != Z_OK) {
+          return process_zlib_error(conn, z);
+        }
+        k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */
+
+    } else {
+        /* we must parse the gzip header ourselves */
+        if (inflateInit2(z, -MAX_WBITS) != Z_OK) {
+          return process_zlib_error(conn, z);
+        }
+        k->zlib_init = ZLIB_INIT;   /* Initial call state */
+    }
   }
 
+  if (k->zlib_init == ZLIB_INIT_GZIP) {
+     /* Let zlib handle the gzip decompression entirely */
+     z->next_in = (Bytef *)k->str;
+     z->avail_in = (uInt)nread;
+     /* Now uncompress the data */
+     return inflate_stream(conn, k);
+  }
+
+#ifndef OLD_ZLIB_SUPPORT
+  /* Support for old zlib versions is compiled away and we are running with
+     an old version, so return an error. */
+  return exit_zlib(z, &k->zlib_init, CURLE_FUNCTION_NOT_FOUND);
+
+#else
   /* This next mess is to get around the potential case where there isn't
    * enough data passed in to skip over the gzip header.  If that happens, we
    * malloc a block and copy what we have then wait for the next call.  If
    * there still isn't enough (this is definitely a worst-case scenario), we
    * make the block bigger, copy the next part in and keep waiting.
+   *
+   * This is only required with zlib versions < 1.2.0.4 as newer versions
+   * can handle the gzip header themselves.
    */
 
+  switch (k->zlib_init) {
   /* Skip over gzip header? */
-  if (k->zlib_init == 1) {
+  case ZLIB_INIT:
+  {
     /* Initial call state */
     ssize_t hlen;
 
@@ -252,7 +337,7 @@
     case GZIP_OK:
       z->next_in = (Bytef *)k->str + hlen;
       z->avail_in = (uInt)(nread - hlen);
-      k->zlib_init = 3; /* Inflating stream state */
+      k->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */
       break;
 
     case GZIP_UNDERFLOW:
@@ -269,17 +354,20 @@
         return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
       }
       memcpy(z->next_in, k->str, z->avail_in);
-      k->zlib_init = 2;   /* Need more gzip header data state */
+      k->zlib_init = ZLIB_GZIP_HEADER;   /* Need more gzip header data state */
       /* We don't have any data to inflate yet */
       return CURLE_OK;
 
     case GZIP_BAD:
     default:
-      return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z));
+      return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
     }
 
   }
-  else if (k->zlib_init == 2) {
+  break;
+
+  case ZLIB_GZIP_HEADER:
+  {
     /* Need more gzip header data state */
     ssize_t hlen;
     unsigned char *oldblock = z->next_in;
@@ -300,7 +388,7 @@
       /* Don't point into the malloced block since we just freed it */
       z->next_in = (Bytef *)k->str + hlen + nread - z->avail_in;
       z->avail_in = (uInt)(z->avail_in - hlen);
-      k->zlib_init = 3;   /* Inflating stream state */
+      k->zlib_init = ZLIB_GZIP_INFLATING;   /* Inflating stream state */
       break;
 
     case GZIP_UNDERFLOW:
@@ -310,14 +398,18 @@
     case GZIP_BAD:
     default:
       free(z->next_in);
-      return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z));
+      return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
     }
 
   }
-  else {
+  break;
+
+  case ZLIB_GZIP_INFLATING:
+  default:
     /* Inflating stream state */
     z->next_in = (Bytef *)k->str;
     z->avail_in = (uInt)nread;
+    break;
   }
 
   if (z->avail_in == 0) {
@@ -325,39 +417,8 @@
     return CURLE_OK;
   }
 
-  /* because the buffer size is fixed, iteratively decompress and transfer to
-     the client via client_write. */
-  for (;;) {
-    /* (re)set buffer for decompressed output for every iteration */
-    z->next_out = (Bytef *)&decomp[0];
-    z->avail_out = DSIZ;
-
-    status = inflate(z, Z_SYNC_FLUSH);
-    if (status == Z_OK || status == Z_STREAM_END) {
-      if(DSIZ - z->avail_out) {
-        result = Curl_client_write(data, CLIENTWRITE_BODY, decomp,
-                                   DSIZ - z->avail_out);
-        /* if !CURLE_OK, clean up, return */
-        if (result)
-          return exit_zlib(z, &k->zlib_init, result);
-      }
-
-      /* Done?; clean up, return */
-      /* We should really check the gzip CRC here */
-      if (status == Z_STREAM_END) {
-        if (inflateEnd(z) == Z_OK)
-          return exit_zlib(z, &k->zlib_init, result);
-        else
-          return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z));
-      }
-
-      /* Done with these bytes, exit */
-      if (status == Z_OK && z->avail_in == 0 && z->avail_out > 0)
-        return result;
-    }
-    else {                      /* Error; exit loop, handle below */
-      return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z));
-    }
-  }
+  /* We've parsed the header, now uncompress the data */
+  return inflate_stream(conn, k);
+#endif
 }
 #endif /* HAVE_LIBZ */

--- NEW FILE: strdup.h ---
/***************************************************************************
 *                                  _   _ ____  _     
 *  Project                     ___| | | |  _ \| |    
 *                             / __| | | | |_) | |    
 *                            | (__| |_| |  _ <| |___ 
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 * 
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: strdup.h,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

#ifndef _CURL_STRDUP_H
#define _CURL_STRDUP_H

#include "setup.h"

#ifndef HAVE_STRDUP
extern char *curlx_strdup(const char *str);
#endif

#endif


Index: curl.copyright
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/curl.copyright,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- curl.copyright	24 Jun 2005 13:01:05 -0000	1.1
+++ curl.copyright	15 Mar 2007 19:22:13 -0000	1.2
@@ -4,7 +4,7 @@
 
 COPYRIGHT AND PERMISSION NOTICE
 
-Copyright (c) 1996 - 2004, Daniel Stenberg, <daniel at haxx.se>.
+Copyright (c) 1996 - 2007, Daniel Stenberg, <daniel at haxx.se>.
 
 All rights reserved.
 

Index: multi.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/multi.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- multi.c	24 Jun 2005 13:00:12 -0000	1.1
+++ multi.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -42,7 +42,11 @@
 #include "url.h"
 #include "connect.h"
[...2114 lines suppressed...]
+      for(i=0; i < easy->numsocks; i++) {
+        curl_socket_t s = easy->sockets[i];
+        struct Curl_sh_entry *entry =
+          Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
+
+        fprintf(stderr, "%d ", (int)s);
+        if(!entry) {
+          fprintf(stderr, "INTERNAL CONFUSION\n");
+          continue;
+        }
+        fprintf(stderr, "[%s %s] ",
+                entry->action&CURL_POLL_IN?"RECVING":"",
+                entry->action&CURL_POLL_OUT?"SENDING":"");
+      }
+      if(easy->numsocks)
+        fprintf(stderr, "\n");
+    }
+  }
+}
+#endif


Index: http_negotiate.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/http_negotiate.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- http_negotiate.c	24 Jun 2005 13:00:12 -0000	1.1
+++ http_negotiate.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -34,14 +34,13 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <ctype.h>
-#include <errno.h>
 
 #include "urldata.h"
 #include "sendf.h"
 #include "strequal.h"
 #include "base64.h"
 #include "http_negotiate.h"
-#include "curl_memory.h"
+#include "memory.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -111,7 +110,7 @@
     gss_release_buffer(&min_stat, &status_string);
   } while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
 
-  infof(conn->data, buf);
+  infof(conn->data, "%s", buf);
 }
 
 int Curl_input_negotiate(struct connectdata *conn, char *header)
@@ -125,7 +124,7 @@
   bool gss;
   const char* protocol;
 
-  while(*header && isspace((int)*header))
+  while(*header && ISSPACE(*header))
     header++;
   if(checkprefix("GSS-Negotiate", header)) {
     protocol = "GSS-Negotiate";
@@ -161,17 +160,12 @@
     return ret;
 
   header += strlen(neg_ctx->protocol);
-  while(*header && isspace((int)*header))
+  while(*header && ISSPACE(*header))
     header++;
 
   len = strlen(header);
   if (len > 0) {
-    int rawlen;
-    input_token.length = (len+3)/4 * 3;
-    input_token.value = malloc(input_token.length);
-    if (input_token.value == NULL)
-      return ENOMEM;
-    rawlen = Curl_base64_decode(header, input_token.value);
+    int rawlen = Curl_base64_decode(header, (unsigned char **)&input_token.value);
     if (rawlen < 0)
       return -1;
     input_token.length = rawlen;
@@ -211,7 +205,7 @@
           input_token.length = mechTokenLength;
           free(mechToken);
           mechToken = NULL;
-          infof(conn->data, "Parse SPNEGO Target Token succeded\n");
+          infof(conn->data, "Parse SPNEGO Target Token succeeded\n");
         }
     }
 #endif
@@ -292,11 +286,12 @@
       neg_ctx->output_token.length = spnegoTokenLength;
       free(spnegoToken);
       spnegoToken = NULL;
-      infof(conn->data, "Make SPNEGO Initial Token succeded\n");
+      infof(conn->data, "Make SPNEGO Initial Token succeeded\n");
     }
   }
 #endif
-  len = Curl_base64_encode(neg_ctx->output_token.value,
+  len = Curl_base64_encode(conn->data,
+                           neg_ctx->output_token.value,
                            neg_ctx->output_token.length,
                            &encoded);
 

Index: ldap.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/ldap.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ldap.c	24 Jun 2005 13:00:12 -0000	1.1
+++ ldap.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -3,9 +3,9 @@
  *  Project         ___| | | |  _ \| |
  *                 / __| | | | |_) | |
  *                | (__| |_| |  _ <| |___
- *                \___|\___/|_| \_\_____|
+ *                 \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -30,14 +30,19 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <ctype.h>
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
+#endif
+#ifdef NEED_MALLOC_H
+#include <malloc.h>
+#endif
 #include <errno.h>
 
 #if defined(WIN32)
-# include <windows.h>
-# include <malloc.h>
-# include <WinLdap.h>
+# include <winldap.h>
 #endif
 
 #ifdef HAVE_UNISTD_H
@@ -56,7 +61,8 @@
 #include "strequal.h"
 #include "strtok.h"
 #include "ldap.h"
-#include "curl_memory.h"
+#include "memory.h"
+#include "base64.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -64,7 +70,8 @@
 #include "memdebug.h"
 
 /* WLdap32.dll functions are *not* stdcall. Must call these via __cdecl
- * pointers in case libcurl was compiled as fastcall (-Gr).
+ * pointers in case libcurl was compiled as fastcall (cl -Gr). Watcom
+ * uses fastcall by default.
  */
 #if !defined(WIN32) && !defined(__cdecl)
 #define __cdecl
@@ -73,8 +80,17 @@
 #ifndef LDAP_SIZELIMIT_EXCEEDED
 #define LDAP_SIZELIMIT_EXCEEDED 4
 #endif
+#ifndef LDAP_VERSION2
+#define LDAP_VERSION2 2
+#endif
+#ifndef LDAP_VERSION3
+#define LDAP_VERSION3 3
+#endif
+#ifndef LDAP_OPT_PROTOCOL_VERSION
+#define LDAP_OPT_PROTOCOL_VERSION 0x0011
+#endif
 
-#define DLOPEN_MODE   RTLD_LAZY  /*! assume all dlopen() implementations have 
+#define DLOPEN_MODE   RTLD_LAZY  /*! assume all dlopen() implementations have
                                    this */
 
 #if defined(RTLD_LAZY_GLOBAL)    /* It turns out some systems use this: */
@@ -99,43 +115,60 @@
 #undef HAVE_LIBDL
 #endif
 
+/* 
+ * We use this ZERO_NULL to avoid picky compiler warnings,
+ * when assigning a NULL pointer to a function pointer var.
+ */
+
+#define ZERO_NULL 0
+
 typedef void * (*dynafunc)(void *input);
 
 /***********************************************************************
  */
+#if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL) || defined(WIN32)
 static void *libldap = NULL;
-#ifndef WIN32
+#if defined(DL_LBER_FILE)
 static void *liblber = NULL;
 #endif
+#endif
+
+struct bv {
+  unsigned long bv_len;
+  char  *bv_val;
+};
 
 static int DynaOpen(const char **mod_name)
 {
 #if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL)
   if (libldap == NULL) {
     /*
-     * libldap.so should be able to resolve its dependency on
-     * liblber.so automatically, but since it does not we will
+     * libldap.so can normally resolve its dependency on liblber.so
+     * automatically, but in broken installation it does not so
      * handle it here by opening liblber.so as global.
      */
-    *mod_name = "liblber.so";
+#ifdef DL_LBER_FILE
+    *mod_name = DL_LBER_FILE;
     liblber = dlopen(*mod_name, DLOPEN_MODE);
+    if (!liblber)
+      return 0;
+#endif
 
     /* Assume loading libldap.so will fail if loading of liblber.so failed
      */
-    if (liblber)  {
-      *mod_name = "libldap.so";
-      libldap = dlopen(*mod_name, RTLD_LAZY);
-    }
+    *mod_name = DL_LDAP_FILE;
+    libldap = dlopen(*mod_name, RTLD_LAZY);
   }
-  return (libldap != NULL && liblber != NULL);
+  return (libldap != NULL);
 
 #elif defined(WIN32)
-  *mod_name = "wldap32.dll";
+  *mod_name = DL_LDAP_FILE;
   if (!libldap)
     libldap = (void*)LoadLibrary(*mod_name);
   return (libldap != NULL);
 
 #else
+  *mod_name = "";
   return (0);
 #endif
 }
@@ -147,10 +180,12 @@
     dlclose(libldap);
     libldap=NULL;
   }
+#ifdef DL_LBER_FILE
   if (liblber) {
     dlclose(liblber);
     liblber=NULL;
   }
+#endif
 #elif defined(WIN32)
   if (libldap) {
     FreeLibrary ((HMODULE)libldap);
@@ -161,7 +196,7 @@
 
 static dynafunc DynaGetFunction(const char *name)
 {
-  dynafunc func = (dynafunc)NULL;
+  dynafunc func = (dynafunc)ZERO_NULL;
 
 #if defined(HAVE_DLOPEN) || defined(HAVE_LIBDL)
   if (libldap) {
@@ -175,6 +210,8 @@
   if (libldap) {
     func = (dynafunc)GetProcAddress((HINSTANCE)libldap, name);
   }
+#else
+  (void) name;
 #endif
   return func;
 }
@@ -214,7 +251,7 @@
 #endif
 
 
-CURLcode Curl_ldap(struct connectdata *conn)
+CURLcode Curl_ldap(struct connectdata *conn, bool *done)
 {
   CURLcode status = CURLE_OK;
   int rc = 0;
@@ -233,10 +270,11 @@
   char  *(__cdecl *ldap_get_dn)(void *, void *);
   char  *(__cdecl *ldap_first_attribute)(void *, void *, void **);
   char  *(__cdecl *ldap_next_attribute)(void *, void *, void *);
-  char **(__cdecl *ldap_get_values)(void *, void *, const char *);
-  void   (__cdecl *ldap_value_free)(char **);
+  void **(__cdecl *ldap_get_values_len)(void *, void *, const char *);
+  void   (__cdecl *ldap_value_free_len)(void **);
   void   (__cdecl *ldap_memfree)(void *);
   void   (__cdecl *ber_free)(void *, int);
+  int    (__cdecl *ldap_set_option)(void *, int, void *);
 
   void *server;
   LDAPURLDesc *ludp = NULL;
@@ -245,7 +283,11 @@
   void *entryIterator;     /*! type should be 'LDAPMessage *' */
   int num = 0;
   struct SessionHandle *data=conn->data;
+  int ldap_proto;
+  char *val_b64;
+  size_t val_b64_sz;
 
+  *done = TRUE; /* unconditionally */
   infof(data, "LDAP local: %s\n", data->change.url);
 
   if (!DynaOpen(&mod_name)) {
@@ -256,25 +298,30 @@
   /* The types are needed because ANSI C distinguishes between
    * pointer-to-object (data) and pointer-to-function.
    */
-  DYNA_GET_FUNCTION(void *(*)(char *, int), ldap_init);
-  DYNA_GET_FUNCTION(int (*)(void *, char *, char *), ldap_simple_bind_s);
-  DYNA_GET_FUNCTION(int (*)(void *), ldap_unbind_s);
+  DYNA_GET_FUNCTION(void *(__cdecl *)(char *, int), ldap_init);
+  DYNA_GET_FUNCTION(int (__cdecl *)(void *, char *, char *),
+                    ldap_simple_bind_s);
+  DYNA_GET_FUNCTION(int (__cdecl *)(void *), ldap_unbind_s);
 #ifndef WIN32
   DYNA_GET_FUNCTION(int (*)(char *, LDAPURLDesc **), ldap_url_parse);
   DYNA_GET_FUNCTION(void (*)(void *), ldap_free_urldesc);
 #endif
-  DYNA_GET_FUNCTION(int (*)(void *, char *, int, char *, char **, int,
-                            void **), ldap_search_s);
-  DYNA_GET_FUNCTION(void *(*)(void *, void *), ldap_first_entry);
-  DYNA_GET_FUNCTION(void *(*)(void *, void *), ldap_next_entry);
-  DYNA_GET_FUNCTION(char *(*)(int), ldap_err2string);
-  DYNA_GET_FUNCTION(char *(*)(void *, void *), ldap_get_dn);
-  DYNA_GET_FUNCTION(char *(*)(void *, void *, void **), ldap_first_attribute);
-  DYNA_GET_FUNCTION(char *(*)(void *, void *, void *), ldap_next_attribute);
-  DYNA_GET_FUNCTION(char **(*)(void *, void *, const char *), ldap_get_values);
-  DYNA_GET_FUNCTION(void (*)(char **), ldap_value_free);
-  DYNA_GET_FUNCTION(void (*)(void *), ldap_memfree);
-  DYNA_GET_FUNCTION(void (*)(void *, int), ber_free);
+  DYNA_GET_FUNCTION(int (__cdecl *)(void *, char *, int, char *, char **, int,
+                                    void **), ldap_search_s);
+  DYNA_GET_FUNCTION(void *(__cdecl *)(void *, void *), ldap_first_entry);
+  DYNA_GET_FUNCTION(void *(__cdecl *)(void *, void *), ldap_next_entry);
+  DYNA_GET_FUNCTION(char *(__cdecl *)(int), ldap_err2string);
+  DYNA_GET_FUNCTION(char *(__cdecl *)(void *, void *), ldap_get_dn);
+  DYNA_GET_FUNCTION(char *(__cdecl *)(void *, void *, void **),
+                    ldap_first_attribute);
+  DYNA_GET_FUNCTION(char *(__cdecl *)(void *, void *, void *),
+                    ldap_next_attribute);
+  DYNA_GET_FUNCTION(void **(__cdecl *)(void *, void *, const char *),
+                    ldap_get_values_len);
+  DYNA_GET_FUNCTION(void (__cdecl *)(void **), ldap_value_free_len);
+  DYNA_GET_FUNCTION(void (__cdecl *)(void *), ldap_memfree);
+  DYNA_GET_FUNCTION(void (__cdecl *)(void *, int), ber_free);
+  DYNA_GET_FUNCTION(int (__cdecl *)(void *, int, void *), ldap_set_option);
 
   server = (*ldap_init)(conn->host.name, (int)conn->port);
   if (server == NULL) {
@@ -284,10 +331,19 @@
     goto quit;
   }
 
+  ldap_proto = LDAP_VERSION3;
+  (*ldap_set_option)(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
   rc = (*ldap_simple_bind_s)(server,
                              conn->bits.user_passwd ? conn->user : NULL,
                              conn->bits.user_passwd ? conn->passwd : NULL);
   if (rc != 0) {
+    ldap_proto = LDAP_VERSION2;
+    (*ldap_set_option)(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
+    rc = (*ldap_simple_bind_s)(server,
+                               conn->bits.user_passwd ? conn->user : NULL,
+                               conn->bits.user_passwd ? conn->passwd : NULL);
+  }
+  if (rc != 0) {
      failf(data, "LDAP local: %s", (*ldap_err2string)(rc));
      status = CURLE_LDAP_CANNOT_BIND;
      goto quit;
@@ -323,35 +379,51 @@
     char  *dn = (*ldap_get_dn)(server, entryIterator);
     int i;
 
-    Curl_client_write(data, CLIENTWRITE_BODY, (char *)"DN: ", 4);
-    Curl_client_write(data, CLIENTWRITE_BODY, (char *)dn, 0);
-    Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
+    Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
+    Curl_client_write(conn, CLIENTWRITE_BODY, (char *)dn, 0);
+    Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
 
     for (attribute = (*ldap_first_attribute)(server, entryIterator, &ber);
          attribute;
          attribute = (*ldap_next_attribute)(server, entryIterator, ber))
     {
-      char **vals = (*ldap_get_values)(server, entryIterator, attribute);
+      struct bv **vals = (struct bv **)
+        (*ldap_get_values_len)(server, entryIterator, attribute);
 
       if (vals != NULL)
       {
         for (i = 0; (vals[i] != NULL); i++)
         {
-          Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1);
-          Curl_client_write(data, CLIENTWRITE_BODY, (char*) attribute, 0);
-          Curl_client_write(data, CLIENTWRITE_BODY, (char *)": ", 2);
-          Curl_client_write(data, CLIENTWRITE_BODY, vals[i], 0);
-          Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0);
+          Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
+          Curl_client_write(conn, CLIENTWRITE_BODY, (char *) attribute, 0);
+          Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
+          if ((strlen(attribute) > 7) &&
+              (strcmp(";binary",
+                      (char *)attribute +
+                      (strlen((char *)attribute) - 7)) == 0)) {
+            /* Binary attribute, encode to base64. */
+            val_b64_sz = Curl_base64_encode(conn->data,
+                                            vals[i]->bv_val,
+                                            vals[i]->bv_len,
+                                            &val_b64);
+            if (val_b64_sz > 0) {
+              Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz);
+              free(val_b64);
+            }
+          } else
+            Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val,
+                              vals[i]->bv_len);
+          Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
         }
 
         /* Free memory used to store values */
-        (*ldap_value_free)(vals);
+        (*ldap_value_free_len)((void **)vals);
       }
-      Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
+      Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
 
       (*ldap_memfree)(attribute);
-      (*ldap_memfree)(dn);
     }
+    (*ldap_memfree)(dn);
     if (ber)
        (*ber_free)(ber, 0);
   }
@@ -368,7 +440,8 @@
   DynaClose();
 
   /* no data to transfer */
-  Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+  Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+  conn->bits.close = TRUE;
 
   return status;
 }
@@ -436,36 +509,36 @@
 /*
  * Unescape the LDAP-URL components
  */
-static bool unescape_elements (LDAPURLDesc *ludp)
+static bool unescape_elements (void *data, LDAPURLDesc *ludp)
 {
   int i;
 
   if (ludp->lud_filter) {
-    ludp->lud_filter = curl_unescape(ludp->lud_filter, 0);
+    ludp->lud_filter = curl_easy_unescape(data, ludp->lud_filter, 0, NULL);
     if (!ludp->lud_filter)
        return (FALSE);
   }
 
   for (i = 0; ludp->lud_attrs && ludp->lud_attrs[i]; i++) {
-    ludp->lud_attrs[i] = curl_unescape(ludp->lud_attrs[i], 0);
+    ludp->lud_attrs[i] = curl_easy_unescape(data, ludp->lud_attrs[i], 0, NULL);
     if (!ludp->lud_attrs[i])
        return (FALSE);
   }
 
   for (i = 0; ludp->lud_exts && ludp->lud_exts[i]; i++) {
-    ludp->lud_exts[i] = curl_unescape(ludp->lud_exts[i], 0);
+    ludp->lud_exts[i] = curl_easy_unescape(data, ludp->lud_exts[i], 0, NULL);
     if (!ludp->lud_exts[i])
        return (FALSE);
   }
 
   if (ludp->lud_dn) {
     char *dn = ludp->lud_dn;
-    char *new_dn = curl_unescape(dn, 0);
+    char *new_dn = curl_easy_unescape(data, dn, 0, NULL);
 
     free(dn);
+    ludp->lud_dn = new_dn;
     if (!new_dn)
        return (FALSE);
-    ludp->lud_dn = new_dn;
   }
   return (TRUE);
 }
@@ -477,8 +550,10 @@
  *
  * <hostname> already known from 'conn->host.name'.
  * <port>     already known from 'conn->remote_port'.
- * extract the rest from 'conn->path+1'. All fields are optional. e.g.
- *   ldap://<hostname>:<port>/?<attributes>?<scope>?<filter> yields ludp->lud_dn = "".
+ * extract the rest from 'conn->data->reqdata.path+1'. All fields are optional.
+ * e.g.
+ *   ldap://<hostname>:<port>/?<attributes>?<scope>?<filter>
+ * yields ludp->lud_dn = "".
  *
  * Ref. http://developer.netscape.com/docs/manuals/dirsdk/csdk30/url.htm#2831915
  */
@@ -487,7 +562,9 @@
   char *p, *q;
   int i;
 
-  if (!conn->path || conn->path[0] != '/' ||
+  if (!conn->data ||
+      !conn->data->reqdata.path ||
+       conn->data->reqdata.path[0] != '/' ||
       !checkprefix(conn->protostr, conn->data->change.url))
      return LDAP_INVALID_SYNTAX;
 
@@ -497,13 +574,13 @@
 
   /* parse DN (Distinguished Name).
    */
-  ludp->lud_dn = strdup(conn->path+1);
+  ludp->lud_dn = strdup(conn->data->reqdata.path+1);
   if (!ludp->lud_dn)
      return LDAP_NO_MEMORY;
 
   p = strchr(ludp->lud_dn, '?');
-  LDAP_TRACE (("DN '%.*s'\n", p ? (size_t)(p-ludp->lud_dn) : strlen(ludp->lud_dn),
-               ludp->lud_dn));
+  LDAP_TRACE (("DN '%.*s'\n", p ? (size_t)(p-ludp->lud_dn) :
+               strlen(ludp->lud_dn), ludp->lud_dn));
 
   if (!p)
      goto success;
@@ -571,7 +648,7 @@
       LDAP_TRACE (("exts[%d] '%s'\n", i, ludp->lud_exts[i]));
 
 success:
-  if (!unescape_elements(ludp))
+  if (!unescape_elements(conn->data, ludp))
      return LDAP_NO_MEMORY;
   return LDAP_SUCCESS;
 }

Index: ldap.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/ldap.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ldap.h	24 Jun 2005 13:00:12 -0000	1.1
+++ ldap.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -2,18 +2,18 @@
 #define __LDAP_H
 
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -24,6 +24,6 @@
  * $Id$
  ***************************************************************************/
 #ifndef CURL_DISABLE_LDAP
-CURLcode Curl_ldap(struct connectdata *conn);
+CURLcode Curl_ldap(struct connectdata *conn, bool *done);
 #endif
 #endif /* __LDAP_H */

Index: inet_ntop.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/inet_ntop.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- inet_ntop.c	24 Jun 2005 13:00:12 -0000	1.1
+++ inet_ntop.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,4 +1,20 @@
 /*
+ * Copyright (C) 1996-2001  Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
  * Original code by Paul Vixie. "curlified" by Gisle Vanem.
  */
 
@@ -39,7 +55,7 @@
 #define INADDRSZ         4
 #define INT16SZ          2
 
-#ifdef WIN32
+#ifdef USE_WINSOCK
 #define EAFNOSUPPORT    WSAEAFNOSUPPORT
 #define SET_ERRNO(e)    WSASetLastError(errno = (e))
 #else
@@ -52,20 +68,21 @@
  * Returns `dst' (as a const)
  * Note:
  *  - uses no statics
- *  - takes a u_char* not an in_addr as input
+ *  - takes a unsigned char* not an in_addr as input
  */
-static const char *inet_ntop4 (const u_char *src, char *dst, size_t size)
+static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size)
 {
-#ifdef HAVE_INET_NTOA_R
+#if defined(HAVE_INET_NTOA_R_2_ARGS)
+  const char *ptr;
+  curlassert(size >= 16);
+  ptr = inet_ntoa_r(*(struct in_addr*)src, dst);
+  return (char *)memmove(dst, ptr, strlen(ptr)+1);
+
+#elif defined(HAVE_INET_NTOA_R)
   return inet_ntoa_r(*(struct in_addr*)src, dst, size);
+
 #else
-  union {
-    const u_char* uch;
-    const struct in_addr* iad;
-  } srcaddr;
-  const char *addr;
-  srcaddr.uch = src;
-  addr = inet_ntoa(*srcaddr.iad);
+  const char *addr = inet_ntoa(*(struct in_addr*)src);
 
   if (strlen(addr) >= size)
   {
@@ -80,7 +97,7 @@
 /*
  * Convert IPv6 binary address into presentation (printable) format.
  */
-static const char *inet_ntop6 (const u_char *src, char *dst, size_t size)
+static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
 {
   /*
    * Note that int32_t and int16_t need only be "at least" large enough
@@ -89,25 +106,28 @@
    * Keep this in mind if you think this function should have been coded
    * to use pointer overlays.  All the world's not a VAX.
    */
-  char  tmp [sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
+  char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
   char *tp;
   struct {
     long base;
     long len;
   } best, cur;
-  u_long words [IN6ADDRSZ / INT16SZ];
-  int    i;
+  unsigned long words[IN6ADDRSZ / INT16SZ];
+  int i;
 
   /* Preprocess:
    *  Copy the input (bytewise) array into a wordwise array.
    *  Find the longest run of 0x00's in src[] for :: shorthanding.
    */
-  memset(words, 0, sizeof(words));
+  memset(words, '\0', sizeof(words));
   for (i = 0; i < IN6ADDRSZ; i++)
       words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
 
   best.base = -1;
   cur.base  = -1;
+  best.len = 0;
+  cur.len = 0;
+
   for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
   {
     if (words[i] == 0)
@@ -184,17 +204,17 @@
 /*
  * Convert a network format address to presentation format.
  *
- * Returns pointer to presentation format address (`dst'),
+ * Returns pointer to presentation format address (`buf'),
  * Returns NULL on error (see errno).
  */
-const char *Curl_inet_ntop(int af, const void *src, char *buf, size_t size)
+char *Curl_inet_ntop(int af, const void *src, char *buf, size_t size)
 {
   switch (af) {
   case AF_INET:
-    return inet_ntop4((const u_char*)src, buf, size);
+    return inet_ntop4((const unsigned char*)src, buf, size);
 #ifdef ENABLE_IPV6
   case AF_INET6:
-    return inet_ntop6((const u_char*)src, buf, size);
+    return inet_ntop6((const unsigned char*)src, buf, size);
 #endif
   default:
     SET_ERRNO(EAFNOSUPPORT);

Index: http_ntlm.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/http_ntlm.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- http_ntlm.c	24 Jun 2005 13:00:12 -0000	1.1
+++ http_ntlm.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,11 +27,15 @@
    http://davenport.sourceforge.net/ntlm.html
    http://www.innovation.ch/java/ntlm.html
[...1024 lines suppressed...]
+
+
+void
+Curl_ntlm_cleanup(struct connectdata *conn)
+{
+#ifdef USE_WINDOWS_SSPI
+  ntlm_sspi_cleanup(&conn->ntlm);
+  ntlm_sspi_cleanup(&conn->proxyntlm);
+  if (s_hSecDll != NULL) {
+    FreeLibrary(s_hSecDll);
+    s_hSecDll = NULL;
+    s_pSecFn = NULL;
+  }
+#else
+  (void)conn;
+#endif
+}
+
+#endif /* USE_NTLM */
 #endif /* !CURL_DISABLE_HTTP */

Index: content_encoding.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/content_encoding.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- content_encoding.h	24 Jun 2005 13:00:12 -0000	1.1
+++ content_encoding.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,16 +1,16 @@
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -31,11 +31,11 @@
 #define ALL_CONTENT_ENCODINGS "identity"
 #endif
 
-CURLcode Curl_unencode_deflate_write(struct SessionHandle *data, 
-                                     struct Curl_transfer_keeper *k, 
+CURLcode Curl_unencode_deflate_write(struct connectdata *conn,
+                                     struct Curl_transfer_keeper *k,
                                      ssize_t nread);
 
 CURLcode
-Curl_unencode_gzip_write(struct SessionHandle *data, 
+Curl_unencode_gzip_write(struct connectdata *conn,
                          struct Curl_transfer_keeper *k,
                          ssize_t nread);

Index: inet_ntop.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/inet_ntop.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- inet_ntop.h	24 Jun 2005 13:00:12 -0000	1.1
+++ inet_ntop.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -25,13 +25,13 @@
 
 #include "setup.h"
 
+char *Curl_inet_ntop(int af, const void *addr, char *buf, size_t size);
+
 #ifdef HAVE_INET_NTOP
-#define Curl_inet_ntop(af,addr,buf,size) inet_ntop(af,addr,buf,size)
 #ifdef HAVE_ARPA_INET_H
 #include <arpa/inet.h>
 #endif
-#else
-const char *Curl_inet_ntop(int af, const void *addr, char *buf, size_t size);
+#define Curl_inet_ntop(af,addr,buf,size) inet_ntop(af,addr,buf,size)
 #endif
 
 #endif /* __INET_NTOP_H */

Index: http_ntlm.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/http_ntlm.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- http_ntlm.h	24 Jun 2005 13:00:12 -0000	1.1
+++ http_ntlm.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,18 +1,18 @@
 #ifndef __HTTP_NTLM_H
 #define __HTTP_NTLM_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -38,7 +38,10 @@
 /* this is for creating ntlm header output */
 CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
 
-void Curl_ntlm_cleanup(struct SessionHandle *data);
+void Curl_ntlm_cleanup(struct connectdata *conn);
+#ifndef USE_NTLM
+#define Curl_ntlm_cleanup(x)
+#endif
 
 
 /* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */

Index: strerror.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/strerror.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- strerror.h	24 Jun 2005 13:00:13 -0000	1.1
+++ strerror.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,10 +1,10 @@
 #ifndef __CURL_STRERROR_H
 #define __CURL_STRERROR_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
@@ -12,7 +12,7 @@
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -27,4 +27,8 @@
 
 const char *Curl_strerror (struct connectdata *conn, int err);
 
+#ifdef USE_LIBIDN
+const char *Curl_idn_strerror (struct connectdata *conn, int err);
+#endif
+
 #endif

Index: timeval.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/timeval.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- timeval.h	17 Jan 2006 15:21:45 -0000	1.2
+++ timeval.h	15 Mar 2007 19:22:13 -0000	1.3
@@ -1,18 +1,18 @@
 #ifndef __TIMEVAL_H
 #define __TIMEVAL_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -30,21 +30,23 @@
 
 #include "setup.h"
 
-#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#ifdef TIME_WITH_SYS_TIME
 #include <time.h>
+#endif
 #else
-#include <sys/time.h>
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
 #endif
 
-#ifndef HAVE_GETTIMEOFDAY
-#if !defined(_WINSOCKAPI_) && !defined(__WATCOMC__) && !defined(__MINGW32__) && !defined(_AMIGASF) && \
-    !defined(__LCC__)
+#ifndef HAVE_STRUCT_TIMEVAL
 struct timeval {
  long tv_sec;
  long tv_usec;
 };
 #endif
-#endif
 
 struct timeval curlx_tvnow(void);
 

Index: http_digest.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/http_digest.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- http_digest.h	24 Jun 2005 13:00:12 -0000	1.1
+++ http_digest.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,18 +1,18 @@
 #ifndef __HTTP_DIGEST_H
 #define __HTTP_DIGEST_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -47,7 +47,12 @@
                             bool proxy,
                             unsigned char *request,
                             unsigned char *uripath);
-void Curl_digest_cleanup(struct SessionHandle *data);
 void Curl_digest_cleanup_one(struct digestdata *dig);
 
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+void Curl_digest_cleanup(struct SessionHandle *data);
+#else
+#define Curl_digest_cleanup(x) do {} while(0)
+#endif
+
 #endif

Index: timeval.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/timeval.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- timeval.c	24 Jun 2005 13:00:13 -0000	1.1
+++ timeval.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -53,9 +53,9 @@
    ** of multimedia apis offer a better time resolution
    ** of 1ms.Need to link against winmm.lib for this
    **/
-  unsigned long Ticks;
-  unsigned long Sec;
-  unsigned long Usec;
+  unsigned long Ticks = 0;
+  unsigned long Sec =0;
+  unsigned long Usec = 0;
   Ticks = timeGetTime();
 
   Sec = Ticks/1000;

Index: escape.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/escape.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- escape.c	24 Jun 2005 13:00:12 -0000	1.1
+++ escape.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -31,7 +31,10 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include "curl_memory.h"
+#include "memory.h"
+/* urldata.h and easyif.h are included for Curl_convert_... prototypes */
+#include "urldata.h"
+#include "easyif.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -39,16 +42,32 @@
 /* The last #include file should be: */
 #include "memdebug.h"
 
+/* for ABI-compatibility with previous versions */
 char *curl_escape(const char *string, int inlength)
 {
+  return curl_easy_escape(NULL, string, inlength);
+}
+
+/* for ABI-compatibility with previous versions */
+char *curl_unescape(const char *string, int length)
+{
+  return curl_easy_unescape(NULL, string, length, NULL);
+}
+
+char *curl_easy_escape(CURL *handle, const char *string, int inlength)
+{
   size_t alloc = (inlength?(size_t)inlength:strlen(string))+1;
   char *ns;
-  char *testing_ptr;
+  char *testing_ptr = NULL;
   unsigned char in;
   size_t newlen = alloc;
   int strindex=0;
   size_t length;
 
+#ifndef CURL_DOES_CONVERSIONS
+  /* avoid compiler warnings */
+  (void)handle;
+#endif
   ns = malloc(alloc);
   if(!ns)
     return NULL;
@@ -72,6 +91,17 @@
           ns = testing_ptr;
         }
       }
+
+#ifdef CURL_DOES_CONVERSIONS
+/* escape sequences are always in ASCII so convert them on non-ASCII hosts */
+      if (!handle ||
+          (Curl_convert_to_network(handle, &in, 1) != CURLE_OK)) {
+        /* Curl_convert_to_network calls failf if unsuccessful */
+        free(ns);
+        return NULL;
+      }
+#endif /* CURL_DOES_CONVERSIONS */
+
       snprintf(&ns[strindex], 4, "%%%02X", in);
 
       strindex+=3;
@@ -86,11 +116,8 @@
   return ns;
 }
 
-#define ishex(in) ((in >= 'a' && in <= 'f') || \
-                   (in >= 'A' && in <= 'F') || \
-                   (in >= '0' && in <= '9'))
-
-char *curl_unescape(const char *string, int length)
+char *curl_easy_unescape(CURL *handle, const char *string, int length,
+                         int *olen)
 {
   int alloc = (length?length:(int)strlen(string))+1;
   char *ns = malloc(alloc);
@@ -98,12 +125,16 @@
   int strindex=0;
   long hex;
 
+#ifndef CURL_DOES_CONVERSIONS
+  /* avoid compiler warnings */
+  (void)handle;
+#endif
   if( !ns )
     return NULL;
 
   while(--alloc > 0) {
     in = *string;
-    if(('%' == in) && ishex(string[1]) && ishex(string[2])) {
+    if(('%' == in) && ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
       /* this is two hexadecimal digits following a '%' */
       char hexstr[3];
       char *ptr;
@@ -114,6 +145,17 @@
       hex = strtol(hexstr, &ptr, 16);
 
       in = (unsigned char)hex; /* this long is never bigger than 255 anyway */
+
+#ifdef CURL_DOES_CONVERSIONS
+/* escape sequences are always in ASCII so convert them on non-ASCII hosts */
+      if (!handle ||
+          (Curl_convert_from_network(handle, &in, 1) != CURLE_OK)) {
+        /* Curl_convert_from_network calls failf if unsuccessful */
+        free(ns);
+        return NULL;
+      }
+#endif /* CURL_DOES_CONVERSIONS */
+
       string+=2;
       alloc-=2;
     }
@@ -122,6 +164,10 @@
     string++;
   }
   ns[strindex]=0; /* terminate it */
+
+  if(olen)
+    /* store output size */
+    *olen = strindex;
   return ns;
 }
 

Index: strerror.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/strerror.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- strerror.c	24 Jun 2005 13:00:13 -0000	1.1
+++ strerror.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,16 +1,16 @@
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 2004 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -18,21 +18,32 @@
  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  * KIND, either express or implied.
  *
+ * $Id$
  ***************************************************************************/
 
 #include "setup.h"
 
+#ifdef HAVE_STRERROR_R
+#if !defined(HAVE_POSIX_STRERROR_R) && !defined(HAVE_GLIBC_STRERROR_R)
+#error "you MUST have either POSIX or glibc strerror_r if strerror_r is found"
+#endif /* !POSIX && !glibc */
+#endif /* HAVE_STRERROR_R */
+
 #include <curl/curl.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 
+#ifdef USE_LIBIDN
+#include <idna.h>
+#endif
+
 #include "strerror.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
 
-#ifdef HAVE_NO_STRERROR_R_DECL
+#if defined(HAVE_STRERROR_R) && defined(HAVE_NO_STRERROR_R_DECL)
 #ifdef HAVE_POSIX_STRERROR_R
 /* seen on AIX 5100-02 gcc 2.9 */
 extern int strerror_r(int errnum, char *strerrbuf, size_t buflen);
@@ -44,6 +55,7 @@
 const char *
 curl_easy_strerror(CURLcode error)
 {
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
   switch (error) {
   case CURLE_OK:
     return "no error";
@@ -58,13 +70,13 @@
     return "URL using bad/illegal format or missing URL";
 
   case CURLE_COULDNT_RESOLVE_PROXY:
-    return "couldnt resolve proxy";
+    return "couldn't resolve proxy name";
 
   case CURLE_COULDNT_RESOLVE_HOST:
-    return "couldnt resolve host";
+    return "couldn't resolve host name";
 
   case CURLE_COULDNT_CONNECT:
-    return "couldn't connect";
+    return "couldn't connect to server";
 
   case CURLE_FTP_WEIRD_SERVER_REPLY:
     return "FTP: weird server reply";
@@ -72,9 +84,6 @@
   case CURLE_FTP_ACCESS_DENIED:
     return "FTP: access denied";
 
-  case CURLE_FTP_USER_PASSWORD_INCORRECT:
-    return "FTP: user and/or password incorrect";
-
   case CURLE_FTP_WEIRD_PASS_REPLY:
     return "FTP: unknown PASS reply";
 
@@ -121,7 +130,11 @@
     return "failed to open/read local data from file/application";
 
   case CURLE_OUT_OF_MEMORY:
+#ifdef CURL_DOES_CONVERSIONS
+    return "conversion failed -or- out of memory";
+#else
     return "out of memory";
+#endif /* CURL_DOES_CONVERSIONS */
 
   case CURLE_OPERATION_TIMEOUTED:
     return "a timeout was reached";
@@ -147,8 +160,8 @@
   case CURLE_SSL_CONNECT_ERROR:
     return "SSL connect error";
 
-  case CURLE_FTP_BAD_DOWNLOAD_RESUME:
-    return "couldn't resume FTP download";
+  case CURLE_BAD_DOWNLOAD_RESUME:
+    return "couldn't resume download";
 
   case CURLE_FILE_COULDNT_READ_FILE:
     return "couldn't read a file:// file";
@@ -195,6 +208,9 @@
   case CURLE_SSL_ENGINE_SETFAILED:
     return "can not set SSL crypto engine as default";
 
+  case CURLE_SSL_ENGINE_INITFAILED:
+    return "failed to initialise SSL crypto engine";
+
   case CURLE_SEND_ERROR:
     return "failed sending data to the peer";
 
@@ -211,6 +227,9 @@
     return "couldn't use specified SSL cipher";
 
   case CURLE_SSL_CACERT:
+    return "peer certificate cannot be authenticated with known CA certificates";
+
+  case CURLE_SSL_CACERT_BADFILE:
     return "problem with the SSL CA cert (path? access rights?)";
 
   case CURLE_BAD_CONTENT_ENCODING:
@@ -225,11 +244,55 @@
   case CURLE_FTP_SSL_FAILED:
     return "Requested FTP SSL level failed";
 
-  case CURLE_URL_MALFORMAT_USER: /* not used by current libcurl */
-  case CURLE_MALFORMAT_USER:     /* not used by current libcurl */
-  case CURLE_BAD_CALLING_ORDER:  /* not used by current libcurl */
-  case CURLE_BAD_PASSWORD_ENTERED:/* not used by current libcurl */
-  case CURLE_OBSOLETE:           /* not used by current libcurl */
+  case CURLE_SSL_SHUTDOWN_FAILED:
+    return "Failed to shut down the SSL connection";
+
+  case CURLE_SEND_FAIL_REWIND:
+    return "Send failed since rewinding of the data stream failed";
+
+  case CURLE_LOGIN_DENIED:
+    return "FTP: login denied";
+
+  case CURLE_TFTP_NOTFOUND:
+    return "TFTP: File Not Found";
+
+  case CURLE_TFTP_PERM:
+    return "TFTP: Access Violation";
+
+  case CURLE_TFTP_DISKFULL:
+    return "TFTP: Disk full or allocation exceeded";
+
+  case CURLE_TFTP_ILLEGAL:
+    return "TFTP: Illegal operation";
+
+  case CURLE_TFTP_UNKNOWNID:
+    return "TFTP: Unknown transfer ID";
+
+  case CURLE_TFTP_EXISTS:
+    return "TFTP: File already exists";
+
+  case CURLE_TFTP_NOSUCHUSER:
+    return "TFTP: No such user";
+
+  case CURLE_CONV_FAILED:
+    return "conversion failed";
+
+  case CURLE_CONV_REQD:
+    return "caller must register CURLOPT_CONV_ callback options";
+
+  case CURLE_REMOTE_FILE_NOT_FOUND:
+    return "Remote file not found";
+
+  case CURLE_SSH:
+    return "Error in the SSH layer";
+
+    /* error codes not used by current libcurl */
+  case CURLE_URL_MALFORMAT_USER:
+  case CURLE_FTP_USER_PASSWORD_INCORRECT:
+  case CURLE_MALFORMAT_USER:
+  case CURLE_BAD_CALLING_ORDER:
+  case CURLE_BAD_PASSWORD_ENTERED:
+  case CURLE_OBSOLETE:
   case CURL_LAST:
     break;
   }
@@ -248,18 +311,25 @@
    * is why it is here, and not at the start of the switch.
    */
   return "unknown error";
+#else
+  if (error == CURLE_OK)
+    return "no error";
+  else
+    return "error";
+#endif
 }
 
 const char *
 curl_multi_strerror(CURLMcode error)
 {
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
   switch (error) {
   case CURLM_CALL_MULTI_PERFORM:
     return "please call curl_multi_perform() soon";
-    
+
   case CURLM_OK:
     return "no error";
-    
+
   case CURLM_BAD_HANDLE:
     return "invalid multi handle";
 
@@ -272,16 +342,29 @@
   case CURLM_INTERNAL_ERROR:
     return "internal error";
 
+  case CURLM_BAD_SOCKET:
+    return "invalid socket argument";
+
+  case CURLM_UNKNOWN_OPTION:
+    return "unknown option";
+
   case CURLM_LAST:
     break;
   }
 
   return "unknown error";
+#else
+  if (error == CURLM_OK)
+    return "no error";
+  else
+    return "error";
+#endif
 }
 
 const char *
 curl_share_strerror(CURLSHcode error)
 {
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
   switch (error) {
   case CURLSHE_OK:
     return "no error";
@@ -303,17 +386,24 @@
   }
 
   return "CURLSH unknown";
+#else
+  if (error == CURLSHE_OK)
+    return "no error";
+  else
+    return "error";
+#endif
 }
 
-#if defined(WIN32) && !defined(__CYGWIN__)
+#ifdef USE_WINSOCK
 
 /* This function handles most / all (?) Winsock errors cURL is able to produce.
  */
 static const char *
 get_winsock_error (int err, char *buf, size_t len)
 {
-  char *p;
+  const char *p;
 
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
   switch (err) {
   case WSAEINTR:
     p = "Call interrupted.";
@@ -442,16 +532,17 @@
   case WSAEREMOTE:
     p = "Remote error";
     break;
+#ifdef WSAEDISCON  /* missing in SalfordC! */
   case WSAEDISCON:
     p = "Disconnected";
     break;
-
+#endif
     /* Extended Winsock errors */
   case WSASYSNOTREADY:
     p = "Winsock library is not ready";
     break;
   case WSANOTINITIALISED:
-    p = "Winsock library not initalised";
+    p = "Winsock library not initialised";
     break;
   case WSAVERNOTSUPPORTED:
     p = "Winsock version not supported.";
@@ -481,11 +572,17 @@
   default:
     return NULL;
   }
+#else
+  if (error == CURLE_OK)
+    return NULL;
+  else
+    p = "error";
+#endif
   strncpy (buf, p, len);
   buf [len-1] = '\0';
   return buf;
 }
-#endif   /* WIN32 && !__CYGWIN__ */
+#endif   /* USE_WINSOCK */
 
 /*
  * Our thread-safe and smart strerror() replacement.
@@ -510,24 +607,38 @@
   max = sizeof(conn->syserr_buf)-1;
   *buf = '\0';
 
-#if defined(WIN32) && !defined(__CYGWIN__)
+#ifdef USE_WINSOCK
+
+#ifdef _WIN32_WCE
+  buf[0]=0;
+  {
+    wchar_t wbuf[256];
+
+    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
+                  LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL);
+    wcstombs(buf,wbuf,max);
+  }
+
+#else
+
   /* 'sys_nerr' is the maximum errno number, it is not widely portable */
   if (err >= 0 && err < sys_nerr)
     strncpy(buf, strerror(err), max);
   else {
-    if (!get_winsock_error (err, buf, max) &&
-        !FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
-                        LANG_NEUTRAL, buf, max, NULL))
+    if (!get_winsock_error(err, buf, max) &&
+        !FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
+                       LANG_NEUTRAL, buf, (DWORD)max, NULL))
       snprintf(buf, max, "Unknown error %d (%#x)", err, err);
   }
-#else /* not native Windows coming up */
-    
+#endif
+#else /* not USE_WINSOCK coming up */
+
   /* These should be atomic and hopefully thread-safe */
 #ifdef HAVE_STRERROR_R
   /* There are two different APIs for strerror_r(). The POSIX and the GLIBC
      versions. */
 #ifdef HAVE_POSIX_STRERROR_R
-  strerror_r(err, buf, max); 
+  strerror_r(err, buf, max);
   /* this may set errno to ERANGE if insufficient storage was supplied via
      'strerrbuf' and 'buflen' to contain the generated message string, or
      EINVAL if the value of 'errnum' is not a valid error number.*/
@@ -538,25 +649,17 @@
     char *msg = strerror_r(err, buffer, sizeof(buffer));
     /* this version of strerror_r() only *might* use the buffer we pass to
        the function, but it always returns the error message as a pointer,
-       so we must copy that string unconditionally */
-    if ( !msg )
-      {
-      msg = "Unknown System Error";
-      }
-    strncpy(buf, msg, max);
+       so we must copy that string unconditionally (if non-NULL) */
+    if(msg)
+      strncpy(buf, msg, max);
+    else
+      snprintf(buf, max, "Unknown error %d", err);
   }
 #endif /* end of HAVE_GLIBC_STRERROR_R */
 #else /* HAVE_STRERROR_R */
-  {
-    char *msg = strerror(err);
-    if ( !msg )
-      {
-      msg = "Unknown System Error";
-      }
-    strncpy(buf, msg, max);
-  }
+  strncpy(buf, strerror(err), max);
 #endif /* end of HAVE_STRERROR_R */
-#endif /* end of ! Windows */
+#endif /* end of ! USE_WINSOCK */
 
   buf[max] = '\0'; /* make sure the string is zero terminated */
 
@@ -567,3 +670,79 @@
      *p = '\0';
   return buf;
 }
+
+#ifdef USE_LIBIDN
+/*
+ * Return error-string for libidn status as returned from idna_to_ascii_lz().
+ */
+const char *Curl_idn_strerror (struct connectdata *conn, int err)
+{
+#ifdef HAVE_IDNA_STRERROR
+  (void)conn;
+  return idna_strerror((Idna_rc) err);
+#else
+  const char *str;
+  char *buf;
+  size_t max;
+
+  curlassert(conn);
+
+  buf = conn->syserr_buf;
+  max = sizeof(conn->syserr_buf)-1;
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  switch ((Idna_rc)err) {
+    case IDNA_SUCCESS:
+      str = "No error";
+      break;
+    case IDNA_STRINGPREP_ERROR:
+      str = "Error in string preparation";
+      break;
+    case IDNA_PUNYCODE_ERROR:
+      str = "Error in Punycode operation";
+      break;
+    case IDNA_CONTAINS_NON_LDH:
+      str = "Illegal ASCII characters";
+      break;
+    case IDNA_CONTAINS_MINUS:
+      str = "Contains minus";
+      break;
+    case IDNA_INVALID_LENGTH:
+      str = "Invalid output length";
+      break;
+    case IDNA_NO_ACE_PREFIX:
+      str = "No ACE prefix (\"xn--\")";
+      break;
+    case IDNA_ROUNDTRIP_VERIFY_ERROR:
+      str = "Roundtrip verify error";
+      break;
+    case IDNA_CONTAINS_ACE_PREFIX:
+      str = "Already have ACE prefix (\"xn--\")";
+      break;
+    case IDNA_ICONV_ERROR:
+      str = "Locale conversion failed";
+      break;
+    case IDNA_MALLOC_ERROR:
+      str = "Allocation failed";
+      break;
+    case IDNA_DLOPEN_ERROR:
+      str = "dlopen() error";
+      break;
+    default:
+      snprintf(buf, max, "error %d", (int)err);
+      str = NULL;
+      break;
+  }
+#else
+  if ((Idna_rc)err == IDNA_SUCCESS)
+    str = "No error";
+  else
+    str = "error";
+#endif
+  if (str)
+    strncpy(buf, str, max);
+  buf[max] = '\0';
+  return (buf);
+#endif
+}
+#endif  /* USE_LIBIDN */

Index: escape.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/escape.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- escape.h	24 Jun 2005 13:00:12 -0000	1.1
+++ escape.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -2,18 +2,18 @@
 #define __ESCAPE_H
 
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -26,7 +26,5 @@
 /* Escape and unescape URL encoding in strings. The functions return a new
  * allocated string or NULL if an error occurred.  */
 
-char *curl_escape(const char *string, int length);
-char *curl_unescape(const char *string, int length);
 
 #endif

Index: http_digest.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/http_digest.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- http_digest.c	24 Jun 2005 13:00:12 -0000	1.1
+++ http_digest.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -22,7 +22,7 @@
  ***************************************************************************/
 #include "setup.h"
 
-#ifndef CURL_DISABLE_HTTP
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
 /* -- WIN32 approved -- */
 #include <stdio.h>
 #include <string.h>
@@ -38,7 +38,8 @@
 #include "http_digest.h"
 #include "strtok.h"
 #include "url.h" /* for Curl_safefree() */
-#include "curl_memory.h"
+#include "memory.h"
+#include "easyif.h" /* included for Curl_convert_... prototypes */
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -59,8 +60,8 @@
                                               header */
 {
   bool more = TRUE;
-  char *token;
-  char *tmp;
+  char *token = NULL;
+  char *tmp = NULL;
   bool foundAuth = FALSE;
   bool foundAuthInt = FALSE;
   struct SessionHandle *data=conn->data;
@@ -75,7 +76,7 @@
   }
 
   /* skip initial whitespaces */
-  while(*header && isspace((int)*header))
+  while(*header && ISSPACE(*header))
     header++;
 
   if(checkprefix("Digest", header)) {
@@ -91,9 +92,9 @@
     while(more) {
       char value[32];
       char content[128];
-      size_t totlen;
+      size_t totlen=0;
 
-      while(*header && isspace((int)*header))
+      while(*header && ISSPACE(*header))
         header++;
 
       /* how big can these strings be? */
@@ -224,7 +225,7 @@
   unsigned char ha2[33];/* 32 digits and 1 zero byte */
   char cnoncebuf[7];
   char *cnonce;
-  char *tmp;
+  char *tmp = NULL;
   struct timeval now;
 
   char **allocuserpwd;
@@ -234,6 +235,21 @@
 
   struct SessionHandle *data = conn->data;
   struct digestdata *d;
+#ifdef CURL_DOES_CONVERSIONS
+  CURLcode rc;
+/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines.
+   It converts digest text to ASCII so the MD5 will be correct for 
+   what ultimately goes over the network.
+*/
+#define CURL_OUTPUT_DIGEST_CONV(a, b) \
+  rc = Curl_convert_to_network(a, (char *)b, strlen((const char*)b)); \
+  if (rc != CURLE_OK) { \
+    free(b); \
+    return rc; \
+  }
+#else
+#define CURL_OUTPUT_DIGEST_CONV(a, b)
+#endif /* CURL_DOES_CONVERSIONS */
 
   if(proxy) {
     d = &data->state.proxydigest;
@@ -270,7 +286,7 @@
     /* Generate a cnonce */
     now = Curl_tvnow();
     snprintf(cnoncebuf, sizeof(cnoncebuf), "%06ld", now.tv_sec);
-    if(Curl_base64_encode(cnoncebuf, strlen(cnoncebuf), &cnonce))
+    if(Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf), &cnonce))
       d->cnonce = cnonce;
     else
       return CURLE_OUT_OF_MEMORY;
@@ -291,6 +307,8 @@
     aprintf("%s:%s:%s", userp, d->realm, passwdp);
   if(!md5this)
     return CURLE_OUT_OF_MEMORY;
+
+  CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
   Curl_md5it(md5buf, md5this);
   free(md5this); /* free this again */
 
@@ -303,10 +321,12 @@
   if(d->algo == CURLDIGESTALGO_MD5SESS) {
     /* nonce and cnonce are OUTSIDE the hash */
     tmp = aprintf("%s:%s:%s", ha1, d->nonce, d->cnonce);
-    free(ha1);
     if(!tmp)
       return CURLE_OUT_OF_MEMORY;
-    ha1 = (unsigned char *)tmp;
+    CURL_OUTPUT_DIGEST_CONV(data, tmp); /* convert on non-ASCII machines */
+    Curl_md5it(md5buf, (unsigned char *)tmp);
+    free(tmp); /* free this again */
+    md5_to_ascii(md5buf, ha1);
   }
 
   /*
@@ -333,6 +353,7 @@
        entity-body here */
     /* TODO: Append H(entity-body)*/
   }
+  CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
   Curl_md5it(md5buf, md5this);
   free(md5this); /* free this again */
   md5_to_ascii(md5buf, ha2);
@@ -356,6 +377,7 @@
   if(!md5this)
     return CURLE_OUT_OF_MEMORY;
 
+  CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
   Curl_md5it(md5buf, md5this);
   free(md5this); /* free this again */
   md5_to_ascii(md5buf, request_digest);

Index: hostsyn.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/hostsyn.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- hostsyn.c	24 Jun 2005 13:00:12 -0000	1.1
+++ hostsyn.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,16 +1,16 @@
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -24,13 +24,10 @@
 #include "setup.h"
 
 #include <string.h>
-#include <errno.h>
-
-#define _REENTRANT
 
-#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
+#ifdef NEED_MALLOC_H
 #include <malloc.h>
-#else
+#endif
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -57,21 +54,15 @@
 #include <inet.h>
 #include <stdlib.h>
 #endif
-#endif
 
 #ifdef HAVE_SETJMP_H
 #include <setjmp.h>
 #endif
 
-#ifdef WIN32
+#ifdef HAVE_PROCESS_H
 #include <process.h>
 #endif
 
-#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
-#undef in_addr_t
-#define in_addr_t unsigned long
-#endif
-
 #include "urldata.h"
 #include "sendf.h"
 #include "hostip.h"
@@ -87,7 +78,7 @@
 #include "inet_ntoa_r.h"
 #endif
 
-#include "curl_memory.h"
+#include "memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
 
@@ -133,17 +124,15 @@
  * It is present here to keep #ifdefs out from multi.c
  */
 
-CURLcode Curl_fdset(struct connectdata *conn,
-                    fd_set *read_fd_set,
-                    fd_set *write_fd_set,
-                    int *max_fdp)
+int Curl_resolv_getsock(struct connectdata *conn,
+                        curl_socket_t *sock,
+                        int numsocks)
 {
   (void)conn;
-  (void)read_fd_set;
-  (void)write_fd_set;
-  (void)max_fdp;
+  (void)sock;
+  (void)numsocks;
 
-  return CURLE_OK;
+  return 0; /* no bits since we don't use any socks */
 }
 
 #endif /* truly sync */

Index: nwlib.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/nwlib.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- nwlib.c	24 Jun 2005 13:00:12 -0000	1.1
+++ nwlib.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -30,7 +30,7 @@
 #include <nks/thread.h>
 #include <nks/synch.h>
 
-#include "curl_memory.h"
+#include "memory.h"
 #include "memdebug.h"
 
 typedef struct

--- NEW FILE: parsedate.c ---
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: parsedate.c,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/
/*
  A brief summary of the date string formats this parser groks:

  RFC 2616 3.3.1

  Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
  Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
  Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format

  we support dates without week day name:

  06 Nov 1994 08:49:37 GMT
  06-Nov-94 08:49:37 GMT
  Nov  6 08:49:37 1994

  without the time zone:

  06 Nov 1994 08:49:37
  06-Nov-94 08:49:37

  weird order:

  1994 Nov 6 08:49:37  (GNU date fails)
  GMT 08:49:37 06-Nov-94 Sunday
  94 6 Nov 08:49:37    (GNU date fails)

  time left out:

  1994 Nov 6
  06-Nov-94
  Sun Nov 6 94

  unusual separators:

  1994.Nov.6
  Sun/Nov/6/94/GMT

  commonly used time zone names:

  Sun, 06 Nov 1994 08:49:37 CET
  06 Nov 1994 08:49:37 EST

  time zones specified using RFC822 style:

  Sun, 12 Sep 2004 15:05:58 -0700
  Sat, 11 Sep 2004 21:32:11 +0200

  compact numerical date strings:

  20040912 15:05:58 -0700
  20040911 +0200

*/
#include "setup.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>

#ifdef HAVE_STDLIB_H
#include <stdlib.h> /* for strtol() */
#endif

#include <curl/curl.h>

static time_t Curl_parsedate(const char *date);

const char * const Curl_wkday[] =
{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
static const char * const weekday[] =
{ "Monday", "Tuesday", "Wednesday", "Thursday",
  "Friday", "Saturday", "Sunday" };
const char * const Curl_month[]=
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

struct tzinfo {
  const char *name;
  int offset; /* +/- in minutes */
};

/* Here's a bunch of frequently used time zone names. These were supported
   by the old getdate parser. */
#define tDAYZONE -60       /* offset for daylight savings time */
static const struct tzinfo tz[]= {
  {"GMT", 0},              /* Greenwich Mean */
  {"UTC", 0},              /* Universal (Coordinated) */
  {"WET", 0},              /* Western European */
  {"BST", 0 tDAYZONE},     /* British Summer */
  {"WAT", 60},             /* West Africa */
  {"AST", 240},            /* Atlantic Standard */
  {"ADT", 240 tDAYZONE},   /* Atlantic Daylight */
  {"EST", 300},            /* Eastern Standard */
  {"EDT", 300 tDAYZONE},   /* Eastern Daylight */
  {"CST", 360},            /* Central Standard */
  {"CDT", 360 tDAYZONE},   /* Central Daylight */
  {"MST", 420},            /* Mountain Standard */
  {"MDT", 420 tDAYZONE},   /* Mountain Daylight */
  {"PST", 480},            /* Pacific Standard */
  {"PDT", 480 tDAYZONE},   /* Pacific Daylight */
  {"YST", 540},            /* Yukon Standard */
  {"YDT", 540 tDAYZONE},   /* Yukon Daylight */
  {"HST", 600},            /* Hawaii Standard */
  {"HDT", 600 tDAYZONE},   /* Hawaii Daylight */
  {"CAT", 600},            /* Central Alaska */
  {"AHST", 600},           /* Alaska-Hawaii Standard */
  {"NT",  660},            /* Nome */
  {"IDLW", 720},           /* International Date Line West */
  {"CET", -60},            /* Central European */
  {"MET", -60},            /* Middle European */
  {"MEWT", -60},           /* Middle European Winter */
  {"MEST", -60 tDAYZONE},  /* Middle European Summer */
  {"CEST", -60 tDAYZONE},  /* Central European Summer */
  {"MESZ", -60 tDAYZONE},  /* Middle European Summer */
  {"FWT", -60},            /* French Winter */
  {"FST", -60 tDAYZONE},   /* French Summer */
  {"EET", -120},           /* Eastern Europe, USSR Zone 1 */
  {"WAST", -420},          /* West Australian Standard */
  {"WADT", -420 tDAYZONE}, /* West Australian Daylight */
  {"CCT", -480},           /* China Coast, USSR Zone 7 */
  {"JST", -540},           /* Japan Standard, USSR Zone 8 */
  {"EAST", -600},          /* Eastern Australian Standard */
  {"EADT", -600 tDAYZONE}, /* Eastern Australian Daylight */
  {"GST", -600},           /* Guam Standard, USSR Zone 9 */
  {"NZT", -720},           /* New Zealand */
  {"NZST", -720},          /* New Zealand Standard */
  {"NZDT", -720 tDAYZONE}, /* New Zealand Daylight */
  {"IDLE", -720},          /* International Date Line East */
};

/* returns:
   -1 no day
   0 monday - 6 sunday
*/

static int checkday(char *check, size_t len)
{
  int i;
  const char * const *what;
  bool found= FALSE;
  if(len > 3)
    what = &weekday[0];
  else
    what = &Curl_wkday[0];
  for(i=0; i<7; i++) {
    if(curl_strequal(check, what[0])) {
      found=TRUE;
      break;
    }
    what++;
  }
  return found?i:-1;
}

static int checkmonth(char *check)
{
  int i;
  const char * const *what;
  bool found= FALSE;

  what = &Curl_month[0];
  for(i=0; i<12; i++) {
    if(curl_strequal(check, what[0])) {
      found=TRUE;
      break;
    }
    what++;
  }
  return found?i:-1; /* return the offset or -1, no real offset is -1 */
}

/* return the time zone offset between GMT and the input one, in number
   of seconds or -1 if the timezone wasn't found/legal */

static int checktz(char *check)
{
  unsigned int i;
  const struct tzinfo *what;
  bool found= FALSE;

  what = tz;
  for(i=0; i< sizeof(tz)/sizeof(tz[0]); i++) {
    if(curl_strequal(check, what->name)) {
      found=TRUE;
      break;
    }
    what++;
  }
  return found?what->offset*60:-1;
}

static void skip(const char **date)
{
  /* skip everything that aren't letters or digits */
  while(**date && !ISALNUM(**date))
    (*date)++;
}

enum assume {
  DATE_MDAY,
  DATE_YEAR,
  DATE_TIME
};

static time_t Curl_parsedate(const char *date)
{
  time_t t = 0;
  int wdaynum=-1;  /* day of the week number, 0-6 (mon-sun) */
  int monnum=-1;   /* month of the year number, 0-11 */
  int mdaynum=-1; /* day of month, 1 - 31 */
  int hournum=-1;
  int minnum=-1;
  int secnum=-1;
  int yearnum=-1;
  int tzoff=-1;
  struct tm tm;
  enum assume dignext = DATE_MDAY;
  const char *indate = date; /* save the original pointer */
  int part = 0; /* max 6 parts */

  while(*date && (part < 6)) {
    bool found=FALSE;

    skip(&date);

    if(ISALPHA(*date)) {
      /* a name coming up */
      char buf[32]="";
      size_t len;
      sscanf(date, "%31[A-Za-z]", buf);
      len = strlen(buf);

      if(wdaynum == -1) {
        wdaynum = checkday(buf, len);
        if(wdaynum != -1)
          found = TRUE;
      }
      if(!found && (monnum == -1)) {
        monnum = checkmonth(buf);
        if(monnum != -1)
          found = TRUE;
      }

      if(!found && (tzoff == -1)) {
        /* this just must be a time zone string */
        tzoff = checktz(buf);
        if(tzoff != -1)
          found = TRUE;
      }

      if(!found)
        return -1; /* bad string */

      date += len;
    }
    else if(ISDIGIT(*date)) {
      /* a digit */
      int val;
      char *end;
      if((secnum == -1) &&
         (3 == sscanf(date, "%02d:%02d:%02d", &hournum, &minnum, &secnum))) {
        /* time stamp! */
        date += 8;
        found = TRUE;
      }
      else {
        val = (int)strtol(date, &end, 10);

        if((tzoff == -1) &&
           ((end - date) == 4) &&
           (val < 1300) &&
           (indate< date) &&
           ((date[-1] == '+' || date[-1] == '-'))) {
          /* four digits and a value less than 1300 and it is preceeded with
             a plus or minus. This is a time zone indication. */
          found = TRUE;
          tzoff = (val/100 * 60 + val%100)*60;

          /* the + and - prefix indicates the local time compared to GMT,
             this we need ther reversed math to get what we want */
          tzoff = date[-1]=='+'?-tzoff:tzoff;
        }

        if(((end - date) == 8) &&
           (yearnum == -1) &&
           (monnum == -1) &&
           (mdaynum == -1)) {
          /* 8 digits, no year, month or day yet. This is YYYYMMDD */
          found = TRUE;
          yearnum = val/10000;
          monnum = (val%10000)/100-1; /* month is 0 - 11 */
          mdaynum = val%100;
        }

        if(!found && (dignext == DATE_MDAY) && (mdaynum == -1)) {
          if((val > 0) && (val<32)) {
            mdaynum = val;
            found = TRUE;
          }
          dignext = DATE_YEAR;
        }

        if(!found && (dignext == DATE_YEAR) && (yearnum == -1)) {
          yearnum = val;
          found = TRUE;
          if(yearnum < 1900) {
            if (yearnum > 70)
              yearnum += 1900;
            else
              yearnum += 2000;
          }
          if(mdaynum == -1)
            dignext = DATE_MDAY;
        }

        if(!found)
          return -1;

        date = end;
      }
    }

    part++;
  }

  if(-1 == secnum)
    secnum = minnum = hournum = 0; /* no time, make it zero */

  if((-1 == mdaynum) ||
     (-1 == monnum) ||
     (-1 == yearnum))
    /* lacks vital info, fail */
    return -1;

#if SIZEOF_TIME_T < 5
  /* 32 bit time_t can only hold dates to the beginning of 2038 */
  if(yearnum > 2037)
    return 0x7fffffff;
#endif

  tm.tm_sec = secnum;
  tm.tm_min = minnum;
  tm.tm_hour = hournum;
  tm.tm_mday = mdaynum;
  tm.tm_mon = monnum;
  tm.tm_year = yearnum - 1900;
  tm.tm_wday = 0;
  tm.tm_yday = 0;
  tm.tm_isdst = 0;

  /* mktime() returns a time_t. time_t is often 32 bits, even on many
     architectures that feature 64 bit 'long'.

     Some systems have 64 bit time_t and deal with years beyond 2038. However,
     even some of the systems with 64 bit time_t returns -1 for dates beyond
     03:14:07 UTC, January 19, 2038. (Such as AIX 5100-06)
  */
  t = mktime(&tm);

  /* time zone adjust (cast t to int to compare to negative one) */
  if(-1 != (int)t) {
    struct tm *gmt;
    long delta;
    time_t t2;

#ifdef HAVE_GMTIME_R
    /* thread-safe version */
    struct tm keeptime2;
    gmt = (struct tm *)gmtime_r(&t, &keeptime2);
    if(!gmt)
      return -1; /* illegal date/time */
    t2 = mktime(gmt);
#else
    /* It seems that at least the MSVC version of mktime() doesn't work
       properly if it gets the 'gmt' pointer passed in (which is a pointer
       returned from gmtime() pointing to static memory), so instead we copy
       the tm struct to a local struct and pass a pointer to that struct as
       input to mktime(). */
    struct tm gmt2;
    gmt = gmtime(&t); /* use gmtime_r() if available */
    if(!gmt)
      return -1; /* illegal date/time */
    gmt2 = *gmt;
    t2 = mktime(&gmt2);
#endif

    /* Add the time zone diff (between the given timezone and GMT) and the
       diff between the local time zone and GMT. */
    delta = (long)((tzoff!=-1?tzoff:0) + (t - t2));

    if((delta>0) && (t + delta < t))
      return -1; /* time_t overflow */

    t += delta;
  }

  return t;
}

time_t curl_getdate(const char *p, const time_t *now)
{
  (void)now;
  return Curl_parsedate(p);
}

Index: share.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/share.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- share.c	24 Jun 2005 13:00:12 -0000	1.1
+++ share.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -28,7 +28,7 @@
 #include <curl/curl.h>
 #include "urldata.h"
 #include "share.h"
-#include "curl_memory.h"
+#include "memory.h"
 
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -77,7 +77,7 @@
       }
       break;
 
-#ifndef CURL_DISABLE_HTTP
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
     case CURL_LOCK_DATA_COOKIE:
       if (!share->cookies) {
         share->cookies = Curl_cookie_init(NULL, NULL, NULL, TRUE );
@@ -108,7 +108,7 @@
         }
         break;
 
-#ifndef CURL_DISABLE_HTTP
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
       case CURL_LOCK_DATA_COOKIE:
         if (share->cookies) {
           Curl_cookie_cleanup(share->cookies);
@@ -171,7 +171,7 @@
   if(share->hostcache)
     Curl_hash_destroy(share->hostcache);
 
-#ifndef CURL_DISABLE_HTTP
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
   if(share->cookies)
     Curl_cookie_cleanup(share->cookies);
 #endif   /* CURL_DISABLE_HTTP */

--- NEW FILE: parsedate.h ---
#ifndef __PARSEDATE_H
#define __PARSEDATEL_H
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: parsedate.h,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/
extern const char * const Curl_wkday[7];
extern const char * const Curl_month[12];

#endif

--- NEW FILE: sockaddr.h ---
#ifndef __SOCKADDR_H
#define __SOCKADDR_H
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: sockaddr.h,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

#include "setup.h"

#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
struct Curl_sockaddr_storage {
  struct sockaddr_storage buffer;
};
#else
struct Curl_sockaddr_storage {
  char buffer[256];   /* this should be big enough to fit a lot */
};
#endif

#endif /* __SOCKADDR_H */



Index: hostthre.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/hostthre.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- hostthre.c	24 Jun 2005 13:00:12 -0000	1.1
+++ hostthre.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,11 +26,9 @@
 #include <string.h>
 #include <errno.h>
 
-#define _REENTRANT
-
-#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
+#ifdef NEED_MALLOC_H
 #include <malloc.h>
-#else
+#endif
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -57,13 +55,12 @@
 #include <inet.h>
 #include <stdlib.h>
 #endif
-#endif
 
 #ifdef HAVE_SETJMP_H
 #include <setjmp.h>
 #endif
 
-#ifdef WIN32
+#ifdef HAVE_PROCESS_H
 #include <process.h>
 #endif
 
@@ -79,16 +76,21 @@
 #include "share.h"
 #include "strerror.h"
 #include "url.h"
+#include "multiif.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
 
 #include "inet_ntop.h"
 
-#include "curl_memory.h"
+#include "memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
 
+#if defined(_MSC_VER) && defined(CURL_NO__BEGINTHREADEX)
+#pragma message ("No _beginthreadex() available in this RTL")
+#endif
+
 /***********************************************************************
  * Only for Windows threaded name resolves builds
  **********************************************************************/
@@ -154,13 +156,126 @@
   HANDLE thread_hnd;
   unsigned thread_id;
   DWORD  thread_status;
-  curl_socket_t dummy_sock;   /* dummy for Curl_fdset() */
-  FILE *stderr_file;
+  curl_socket_t dummy_sock;   /* dummy for Curl_resolv_fdset() */
+  HANDLE mutex_waiting;  /* marks that we are still waiting for a resolve */
+  HANDLE event_resolved; /* marks that the thread obtained the information */
+  HANDLE event_thread_started; /* marks that the thread has initialized and
+                                  started */
+  HANDLE mutex_terminate; /* serializes access to flag_terminate */
+  HANDLE event_terminate; /* flag for thread to terminate instead of calling
+                             callbacks */
 #ifdef CURLRES_IPV6
   struct addrinfo hints;
 #endif
 };
 
+/* Data for synchronization between resolver thread and its parent */
+struct thread_sync_data {
+  HANDLE mutex_waiting;   /* thread_data.mutex_waiting duplicate */
+  HANDLE mutex_terminate; /* thread_data.mutex_terminate duplicate */
+  HANDLE event_terminate; /* thread_data.event_terminate duplicate */
+  char * hostname;        /* hostname to resolve, Curl_async.hostname
+                             duplicate */
+};
+
+/* Destroy resolver thread synchronization data */
+static
+void destroy_thread_sync_data(struct thread_sync_data * tsd)
+{
+  if (tsd->hostname) {
+    free(tsd->hostname);
+    tsd->hostname = NULL;
+  }
+  if (tsd->event_terminate) {
+    CloseHandle(tsd->event_terminate);
+    tsd->event_terminate = NULL;
+  }
+  if (tsd->mutex_terminate) {
+    CloseHandle(tsd->mutex_terminate);
+    tsd->mutex_terminate = NULL;
+  }
+  if (tsd->mutex_waiting) {
+    CloseHandle(tsd->mutex_waiting);
+    tsd->mutex_waiting = NULL;
+  }
+}
+
+/* Initialize resolver thread synchronization data */
+static
+BOOL init_thread_sync_data(struct thread_data * td,
+                           char * hostname,
+                           struct thread_sync_data * tsd)
+{
+  HANDLE curr_proc = GetCurrentProcess();
+
+  memset(tsd, 0, sizeof(*tsd));
+  if (!DuplicateHandle(curr_proc, td->mutex_waiting,
+                       curr_proc, &tsd->mutex_waiting, 0, FALSE,
+                       DUPLICATE_SAME_ACCESS)) {
+    /* failed to duplicate the mutex, no point in continuing */
+    destroy_thread_sync_data(tsd);
+    return FALSE;
+  }
+  if (!DuplicateHandle(curr_proc, td->mutex_terminate,
+                       curr_proc, &tsd->mutex_terminate, 0, FALSE,
+                       DUPLICATE_SAME_ACCESS)) {
+    /* failed to duplicate the mutex, no point in continuing */
+    destroy_thread_sync_data(tsd);
+    return FALSE;
+  }
+  if (!DuplicateHandle(curr_proc, td->event_terminate,
+                       curr_proc, &tsd->event_terminate, 0, FALSE,
+                       DUPLICATE_SAME_ACCESS)) {
+    /* failed to duplicate the event, no point in continuing */
+    destroy_thread_sync_data(tsd);
+    return FALSE;
+  }
+  /* Copying hostname string because original can be destroyed by parent
+   * thread during gethostbyname execution.
+   */
+  tsd->hostname = strdup(hostname);
+  if (!tsd->hostname) {
+    /* Memory allocation failed */
+    destroy_thread_sync_data(tsd);
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/* acquire resolver thread synchronization */
+static
+BOOL acquire_thread_sync(struct thread_sync_data * tsd)
+{
+  /* is the thread initiator still waiting for us ? */
+  if (WaitForSingleObject(tsd->mutex_waiting, 0) == WAIT_TIMEOUT) {
+    /* yes, it is */
+
+    /* Waiting access to event_terminate */
+    if (WaitForSingleObject(tsd->mutex_terminate, INFINITE) != WAIT_OBJECT_0) {
+      /* Something went wrong - now just ignoring */
+    }
+    else {
+      if (WaitForSingleObject(tsd->event_terminate, 0) != WAIT_TIMEOUT) {
+        /* Parent thread signaled us to terminate.
+         * This means that all data in conn->async is now destroyed
+         * and we cannot use it.
+         */
+      }
+      else {
+        return TRUE;
+      }
+    }
+  }
+  return FALSE;
+}
+
+/* release resolver thread synchronization */
+static
+void release_thread_sync(struct thread_sync_data * tsd)
+{
+  ReleaseMutex(tsd->mutex_terminate);
+}
+
 #if defined(CURLRES_IPV4)
 /*
  * gethostbyname_thread() resolves a name, calls the Curl_addrinfo4_callback
@@ -174,26 +289,45 @@
   struct connectdata *conn = (struct connectdata*) arg;
   struct thread_data *td = (struct thread_data*) conn->async.os_specific;
   struct hostent *he;
-  int    rc;
+  int    rc = 0;
 
-  /* Sharing the same _iob[] element with our parent thread should
-   * hopefully make printouts synchronised. I'm not sure it works
-   * with a static runtime lib (MSVC's libc.lib).
+  /* Duplicate the passed mutex and event handles.
+   * This allows us to use it even after the container gets destroyed
+   * due to a resolver timeout.
    */
-  *stderr = *td->stderr_file;
+  struct thread_sync_data tsd = { 0,0,0,NULL };
+  if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) {
+    /* thread synchronization data initialization failed */
+    return (unsigned)-1;
+  }
 
   WSASetLastError (conn->async.status = NO_DATA); /* pending status */
-  he = gethostbyname (conn->async.hostname);
-  if (he) {
-    Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he);
-    rc = 1;
-  }
-  else {
-    Curl_addrinfo4_callback(conn, (int)WSAGetLastError(), NULL);
-    rc = 0;
+
+  /* Signaling that we have initialized all copies of data and handles we
+     need */
+  SetEvent(td->event_thread_started);
+
+  he = gethostbyname (tsd.hostname);
+
+  /* is parent thread waiting for us and are we able to access conn members? */
+  if (acquire_thread_sync(&tsd)) {
+    /* Mark that we have obtained the information, and that we are calling
+     * back with it. */
+    SetEvent(td->event_resolved);
+    if (he) {
+      rc = Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he);
+    }
+    else {
+      rc = Curl_addrinfo4_callback(conn, (int)WSAGetLastError(), NULL);
+    }
+    TRACE(("Winsock-error %d, addr %s\n", conn->async.status,
+           he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown"));
+    release_thread_sync(&tsd);
   }
-  TRACE(("Winsock-error %d, addr %s\n", conn->async.status,
-         he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown"));
+
+  /* clean up */
+  destroy_thread_sync_data(&tsd);
+
   return (rc);
   /* An implicit _endthreadex() here */
 }
@@ -214,44 +348,99 @@
   struct addrinfo    *res;
   char   service [NI_MAXSERV];
   int    rc;
+  struct addrinfo hints = td->hints;
 
-  *stderr = *td->stderr_file;
+  /* Duplicate the passed mutex handle.
+   * This allows us to use it even after the container gets destroyed
+   * due to a resolver timeout.
+   */
+  struct thread_sync_data tsd = { 0,0,0,NULL };
+  if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) {
+    /* thread synchronization data initialization failed */
+    return -1;
+  }
 
   itoa(conn->async.port, service, 10);
 
   WSASetLastError(conn->async.status = NO_DATA); /* pending status */
 
-  rc = getaddrinfo(conn->async.hostname, service, &td->hints, &res);
+  /* Signaling that we have initialized all copies of data and handles we
+     need */
+  SetEvent(td->event_thread_started);
 
-  if (rc == 0) {
+  rc = getaddrinfo(tsd.hostname, service, &hints, &res);
+
+  /* is parent thread waiting for us and are we able to access conn members? */
+  if (acquire_thread_sync(&tsd)) {
+    /* Mark that we have obtained the information, and that we are calling
+       back with it. */
+    SetEvent(td->event_resolved);
+
+    if (rc == 0) {
 #ifdef DEBUG_THREADING_GETADDRINFO
-    dump_addrinfo (conn, res);
+      dump_addrinfo (conn, res);
 #endif
-    Curl_addrinfo6_callback(conn, CURL_ASYNC_SUCCESS, res);
-  }
-  else {
-    Curl_addrinfo6_callback(conn, (int)WSAGetLastError(), NULL);
-    TRACE(("Winsock-error %d, no address\n", conn->async.status));
+      rc = Curl_addrinfo6_callback(conn, CURL_ASYNC_SUCCESS, res);
+    }
+    else {
+      rc = Curl_addrinfo6_callback(conn, (int)WSAGetLastError(), NULL);
+      TRACE(("Winsock-error %d, no address\n", conn->async.status));
+    }
+    release_thread_sync(&tsd);
   }
+
+  /* clean up */
+  destroy_thread_sync_data(&tsd);
+
   return (rc);
   /* An implicit _endthreadex() here */
 }
 #endif
 
 /*
- * destroy_thread_data() cleans up async resolver data.
+ * Curl_destroy_thread_data() cleans up async resolver data and thread handle.
  * Complementary of ares_destroy.
  */
-static void destroy_thread_data (struct Curl_async *async)
+void Curl_destroy_thread_data (struct Curl_async *async)
 {
   if (async->hostname)
     free(async->hostname);
 
   if (async->os_specific) {
-    curl_socket_t sock = ((const struct thread_data*)async->os_specific)->dummy_sock;
+    struct thread_data *td = (struct thread_data*) async->os_specific;
+    curl_socket_t sock = td->dummy_sock;
+
+    if (td->mutex_terminate && td->event_terminate) {
+      /* Signaling resolver thread to terminate */
+      if (WaitForSingleObject(td->mutex_terminate, INFINITE) == WAIT_OBJECT_0) {
+        SetEvent(td->event_terminate);
+        ReleaseMutex(td->mutex_terminate);
+      }
+      else {
+        /* Something went wrong - just ignoring it */
+      }
+    }
+
+    if (td->mutex_terminate)
+      CloseHandle(td->mutex_terminate);
+    if (td->event_terminate)
+      CloseHandle(td->event_terminate);
+    if (td->event_thread_started)
+      CloseHandle(td->event_thread_started);
 
     if (sock != CURL_SOCKET_BAD)
       sclose(sock);
+
+    /* destroy the synchronization objects */
+    if (td->mutex_waiting)
+      CloseHandle(td->mutex_waiting);
+    td->mutex_waiting = NULL;
+    if (td->event_resolved)
+      CloseHandle(td->event_resolved);
+
+    if (td->thread_hnd)
+      CloseHandle(td->thread_hnd);
+
     free(async->os_specific);
   }
   async->hostname = NULL;
@@ -269,6 +458,7 @@
                                  const Curl_addrinfo *hints)
 {
   struct thread_data *td = calloc(sizeof(*td), 1);
+  HANDLE thread_and_event[2] = {0};
 
   if (!td) {
     SetLastError(ENOMEM);
@@ -288,11 +478,62 @@
   conn->async.status = 0;
   conn->async.dns = NULL;
   conn->async.os_specific = (void*) td;
-
   td->dummy_sock = CURL_SOCKET_BAD;
-  td->stderr_file = stderr;
+
+  /* Create the mutex used to inform the resolver thread that we're
+   * still waiting, and take initial ownership.
+   */
+  td->mutex_waiting = CreateMutex(NULL, TRUE, NULL);
+  if (td->mutex_waiting == NULL) {
+    Curl_destroy_thread_data(&conn->async);
+    SetLastError(EAGAIN);
+    return FALSE;
+  }
+
+  /* Create the event that the thread uses to inform us that it's
+   * done resolving. Do not signal it.
+   */
+  td->event_resolved = CreateEvent(NULL, TRUE, FALSE, NULL);
+  if (td->event_resolved == NULL) {
+    Curl_destroy_thread_data(&conn->async);
+    SetLastError(EAGAIN);
+    return FALSE;
+  }
+  /* Create the mutex used to serialize access to event_terminated
+   * between us and resolver thread.
+   */
+  td->mutex_terminate = CreateMutex(NULL, FALSE, NULL);
+  if (td->mutex_terminate == NULL) {
+    Curl_destroy_thread_data(&conn->async);
+    SetLastError(EAGAIN);
+    return FALSE;
+  }
+  /* Create the event used to signal thread that it should terminate.
+   */
+  td->event_terminate = CreateEvent(NULL, TRUE, FALSE, NULL);
+  if (td->event_terminate == NULL) {
+    Curl_destroy_thread_data(&conn->async);
+    SetLastError(EAGAIN);
+    return FALSE;
+  }
+  /* Create the event used by thread to inform it has initialized its own data.
+   */
+  td->event_thread_started = CreateEvent(NULL, TRUE, FALSE, NULL);
+  if (td->event_thread_started == NULL) {
+    Curl_destroy_thread_data(&conn->async);
+    SetLastError(EAGAIN);
+    return FALSE;
+  }
+
+#ifdef _WIN32_WCE
+  td->thread_hnd = (HANDLE) CreateThread(NULL, 0,
+                                         (LPTHREAD_START_ROUTINE) THREAD_FUNC,
+                                         conn, 0, &td->thread_id);
+#else
   td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, THREAD_FUNC,
                                            conn, 0, &td->thread_id);
+#endif
+
 #ifdef CURLRES_IPV6
   curlassert(hints);
   td->hints = *hints;
@@ -301,14 +542,30 @@
 #endif
 
   if (!td->thread_hnd) {
+#ifdef _WIN32_WCE
+     TRACE(("CreateThread() failed; %s\n", Curl_strerror(conn,GetLastError())));
+#else
      SetLastError(errno);
      TRACE(("_beginthreadex() failed; %s\n", Curl_strerror(conn,errno)));
-     destroy_thread_data(&conn->async);
+#endif
+     Curl_destroy_thread_data(&conn->async);
      return FALSE;
   }
-  /* This socket is only to keep Curl_fdset() and select() happy; should never
-   * become signalled for read/write since it's unbound but Windows needs
-   * atleast 1 socket in select().
+  /* Waiting until the thread will initialize its data or it will exit due errors.
+   */
+  thread_and_event[0] = td->thread_hnd;
+  thread_and_event[1] = td->event_thread_started;
+  if (WaitForMultipleObjects(sizeof(thread_and_event) /
+                             sizeof(thread_and_event[0]),
+                             (const HANDLE*)thread_and_event, FALSE,
+                             INFINITE) == WAIT_FAILED) {
+    /* The resolver thread has been created,
+     * most probably it works now - ignoring this "minor" error
+     */
+  }
+  /* This socket is only to keep Curl_resolv_fdset() and select() happy;
+   * should never become signalled for read/write since it's unbound but
+   * Windows needs atleast 1 socket in select().
    */
   td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0);
   return TRUE;
@@ -341,28 +598,49 @@
     conn->data->set.timeout ? conn->data->set.timeout :
     CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
   ticks = GetTickCount();
-  (void)ticks;
 
-  status = WaitForSingleObject(td->thread_hnd, 1000UL*timeout);
-  if (status == WAIT_OBJECT_0 || status == WAIT_ABANDONED) {
-     /* Thread finished before timeout; propagate Winsock error to this thread.
-      * 'conn->async.done = TRUE' is set in Curl_addrinfo4/6_callback().
-      */
-     WSASetLastError(conn->async.status);
-     GetExitCodeThread(td->thread_hnd, &td->thread_status);
-     TRACE(("%s() status %lu, thread retval %lu, ",
-            THREAD_NAME, status, td->thread_status));
+  /* wait for the thread to resolve the name */
+  status = WaitForSingleObject(td->event_resolved, 1000UL*timeout);
+
+  /* mark that we are now done waiting */
+  ReleaseMutex(td->mutex_waiting);
+
+  /* close our handle to the mutex, no point in hanging on to it */
+  CloseHandle(td->mutex_waiting);
+  td->mutex_waiting = NULL;
+
+  /* close the event handle, it's useless now */
+  CloseHandle(td->event_resolved);
+  td->event_resolved = NULL;
+
+  /* has the resolver thread succeeded in resolving our query ? */
+  if (status == WAIT_OBJECT_0) {
+    /* wait for the thread to exit, it's in the callback sequence */
+    if (WaitForSingleObject(td->thread_hnd, 5000) == WAIT_TIMEOUT) {
+      TerminateThread(td->thread_hnd, 0);
+      conn->async.done = TRUE;
+      td->thread_status = (DWORD)-1;
+      TRACE(("%s() thread stuck?!, ", THREAD_NAME));
+    }
+    else {
+      /* Thread finished before timeout; propagate Winsock error to this
+       * thread.  'conn->async.done = TRUE' is set in
+       * Curl_addrinfo4/6_callback().
+       */
+      WSASetLastError(conn->async.status);
+      GetExitCodeThread(td->thread_hnd, &td->thread_status);
+      TRACE(("%s() status %lu, thread retval %lu, ",
+             THREAD_NAME, status, td->thread_status));
+    }
   }
   else {
-     conn->async.done = TRUE;
-     td->thread_status = (DWORD)-1;
-     TRACE(("%s() timeout, ", THREAD_NAME));
+    conn->async.done = TRUE;
+    td->thread_status = (DWORD)-1;
+    TRACE(("%s() timeout, ", THREAD_NAME));
   }
 
   TRACE(("elapsed %lu ms\n", GetTickCount()-ticks));
 
-  CloseHandle(td->thread_hnd);
-
   if(entry)
     *entry = conn->async.dns;
 
@@ -370,25 +648,34 @@
 
   if (!conn->async.dns) {
     /* a name was not resolved */
-    if (td->thread_status == (DWORD)-1 || conn->async.status == NO_DATA) {
-      failf(data, "Resolving host timed out: %s", conn->host.name);
-      rc = CURLE_OPERATION_TIMEDOUT;
+    if (td->thread_status == CURLE_OUT_OF_MEMORY) {
+      rc = CURLE_OUT_OF_MEMORY;
+      failf(data, "Could not resolve host: %s", curl_easy_strerror(rc));
     }
     else if(conn->async.done) {
-      failf(data, "Could not resolve host: %s; %s",
-            conn->host.name, Curl_strerror(conn,conn->async.status));
-      rc = CURLE_COULDNT_RESOLVE_HOST;
+      if(conn->bits.httpproxy) {
+        failf(data, "Could not resolve proxy: %s; %s",
+              conn->proxy.dispname, Curl_strerror(conn, conn->async.status));
+        rc = CURLE_COULDNT_RESOLVE_PROXY;
+      }
+      else {
+        failf(data, "Could not resolve host: %s; %s",
+              conn->host.name, Curl_strerror(conn, conn->async.status));
+        rc = CURLE_COULDNT_RESOLVE_HOST;
+      }
+    }
+    else if (td->thread_status == (DWORD)-1 || conn->async.status == NO_DATA) {
+      failf(data, "Resolving host timed out: %s", conn->host.name);
+      rc = CURLE_OPERATION_TIMEDOUT;
     }
     else
       rc = CURLE_OPERATION_TIMEDOUT;
   }
 
-  destroy_thread_data(&conn->async);
+  Curl_destroy_thread_data(&conn->async);
 
-  if(CURLE_OK != rc)
-    /* close the connection, since we must not return failure from here
-       without cleaning up this connection properly */
-    Curl_disconnect(conn);
+  if(!conn->async.dns)
+    conn->bits.close = TRUE;
 
   return (rc);
 }
@@ -405,7 +692,7 @@
 
   if (conn->async.done) {
     /* we're done */
-    destroy_thread_data(&conn->async);
+    Curl_destroy_thread_data(&conn->async);
     if (!conn->async.dns) {
       TRACE(("Curl_is_resolved(): CURLE_COULDNT_RESOLVE_HOST\n"));
       return CURLE_COULDNT_RESOLVE_HOST;
@@ -413,25 +700,25 @@
     *entry = conn->async.dns;
     TRACE(("resolved okay, dns %p\n", *entry));
   }
-  else
-    TRACE(("not yet\n"));
   return CURLE_OK;
 }
 
-CURLcode Curl_fdset(struct connectdata *conn,
-                    fd_set *read_fd_set,
-                    fd_set *write_fd_set,
-                    int *max_fdp)
+int Curl_resolv_getsock(struct connectdata *conn,
+                        curl_socket_t *socks,
+                        int numsocks)
 {
   const struct thread_data *td =
     (const struct thread_data *) conn->async.os_specific;
 
   if (td && td->dummy_sock != CURL_SOCKET_BAD) {
-    FD_SET(td->dummy_sock,write_fd_set);
-    *max_fdp = td->dummy_sock;
+    if(numsocks) {
+      /* return one socket waiting for writable, even though this is just
+         a dummy */
+      socks[0] = td->dummy_sock;
+      return GETSOCK_WRITESOCK(0);
+    }
   }
-  (void) read_fd_set;
-  return CURLE_OK;
+  return 0;
 }
 
 #ifdef CURLRES_IPV4
@@ -439,11 +726,11 @@
  * Curl_getaddrinfo() - for Windows threading without ENABLE_IPV6.
  */
 Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
-                                char *hostname,
+                                const char *hostname,
                                 int port,
                                 int *waitp)
 {
-  struct hostent *h;
+  struct hostent *h = NULL;
   struct SessionHandle *data = conn->data;
   in_addr_t in;
 
@@ -461,8 +748,8 @@
   }
 
   /* fall-back to blocking version */
-  infof(data, "init_resolve_thread() failed for %s; code %lu\n",
-        hostname, GetLastError());
+  infof(data, "init_resolve_thread() failed for %s; %s\n",
+        hostname, Curl_strerror(conn,GetLastError()));
 
   h = gethostbyname(hostname);
   if (!h) {
@@ -479,7 +766,7 @@
  * Curl_getaddrinfo() - for Windows threading IPv6 enabled
  */
 Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
-                                char *hostname,
+                                const char *hostname,
                                 int port,
                                 int *waitp)
 {
@@ -525,8 +812,10 @@
 
   memset(&hints, 0, sizeof(hints));
   hints.ai_family = pf;
-  hints.ai_socktype = SOCK_STREAM;
+  hints.ai_socktype = conn->socktype;
+#if 0 /* removed nov 8 2005 before 7.15.1 */
   hints.ai_flags = AI_CANONNAME;
+#endif
   itoa(port, sbuf, 10);
 
   /* fire up a new resolver thread! */
@@ -536,8 +825,8 @@
   }
 
   /* fall-back to blocking version */
-  infof(data, "init_resolve_thread() failed for %s; code %lu\n",
-        hostname, GetLastError());
+  infof(data, "init_resolve_thread() failed for %s; %s\n",
+        hostname, Curl_strerror(conn,GetLastError()));
 
   error = getaddrinfo(hostname, sbuf, &hints, &res);
   if (error) {

Index: share.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/share.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- share.h	24 Jun 2005 13:00:13 -0000	1.1
+++ share.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -2,18 +2,18 @@
 #define __CURL_SHARE_H
 
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -28,28 +28,29 @@
 #include <curl/curl.h>
 #include "cookie.h"
 
+/* SalfordC says "A structure member may not be volatile". Hence:
+ */
+#ifdef __SALFORDC__
+#define CURL_VOLATILE
+#else
+#define CURL_VOLATILE volatile
+#endif
+
 /* this struct is libcurl-private, don't export details */
 struct Curl_share {
   unsigned int specifier;
-  volatile unsigned int dirty;
-  
+  CURL_VOLATILE unsigned int dirty;
+
   curl_lock_function lockfunc;
   curl_unlock_function unlockfunc;
   void *clientdata;
 
-  curl_hash *hostcache;
+  struct curl_hash *hostcache;
   struct CookieInfo *cookies;
 };
 
-CURLSHcode Curl_share_lock (
-    struct SessionHandle *, 
-    curl_lock_data,
-    curl_lock_access
-    );
-
-CURLSHcode Curl_share_unlock (
-    struct SessionHandle *, 
-    curl_lock_data
-    );
+CURLSHcode Curl_share_lock (struct SessionHandle *, curl_lock_data,
+                            curl_lock_access);
+CURLSHcode Curl_share_unlock (struct SessionHandle *, curl_lock_data);
 
 #endif /* __CURL_SHARE_H */

Index: hash.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/hash.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- hash.h	24 Jun 2005 13:00:12 -0000	1.1
+++ hash.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -31,30 +31,31 @@
 
 typedef void (*curl_hash_dtor)(void *);
 
-typedef struct _curl_hash {
-  curl_llist     **table;
+struct curl_hash {
+  struct curl_llist **table;
   curl_hash_dtor   dtor;
-  int              slots;
-  size_t           size;
-} curl_hash;
+  int slots;
+  size_t size;
+};
 
-typedef struct _curl_hash_element {
+struct curl_hash_element {
   void   *ptr;
   char   *key;
   size_t key_len;
-} curl_hash_element;
+};
 
 
-int Curl_hash_init(curl_hash *, int, curl_hash_dtor);
-curl_hash *Curl_hash_alloc(int, curl_hash_dtor);
-void *Curl_hash_add(curl_hash *, char *, size_t, void *);
-int Curl_hash_delete(curl_hash *h, char *key, size_t key_len);
-void *Curl_hash_pick(curl_hash *, char *, size_t);
-void Curl_hash_apply(curl_hash *h, void *user,
+int Curl_hash_init(struct curl_hash *, int, curl_hash_dtor);
+struct curl_hash *Curl_hash_alloc(int, curl_hash_dtor);
+void *Curl_hash_add(struct curl_hash *, char *, size_t, void *);
+int Curl_hash_delete(struct curl_hash *h, char *key, size_t key_len);
+void *Curl_hash_pick(struct curl_hash *, char *, size_t);
+void Curl_hash_apply(struct curl_hash *h, void *user,
                      void (*cb)(void *user, void *ptr));
-int Curl_hash_count(curl_hash *h);
-void Curl_hash_clean(curl_hash *h);
-void Curl_hash_clean_with_criterium(curl_hash *h, void *user, int (*comp)(void *, void *));
-void Curl_hash_destroy(curl_hash *h);
+int Curl_hash_count(struct curl_hash *h);
+void Curl_hash_clean(struct curl_hash *h);
+void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
+                                    int (*comp)(void *, void *));
+void Curl_hash_destroy(struct curl_hash *h);
 
 #endif

Index: hash.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/hash.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- hash.c	24 Jun 2005 13:00:12 -0000	1.1
+++ hash.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -28,7 +28,7 @@
 
 #include "hash.h"
 #include "llist.h"
-#include "curl_memory.h"
+#include "memory.h"
 
 /* this must be the last include file */
 #include "memdebug.h"
@@ -50,12 +50,11 @@
 static void
 hash_element_dtor(void *user, void *element)
 {
-  curl_hash         *h = (curl_hash *) user;
-  curl_hash_element *e = (curl_hash_element *) element;
+  struct curl_hash *h = (struct curl_hash *) user;
+  struct curl_hash_element *e = (struct curl_hash_element *) element;
 
-  if (e->key) {
+  if (e->key)
     free(e->key);
-  }
 
   h->dtor(e->ptr);
 
@@ -64,7 +63,7 @@
 
 /* return 1 on error, 0 is fine */
 int
-Curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor)
+Curl_hash_init(struct curl_hash *h, int slots, curl_hash_dtor dtor)
 {
   int i;
 
@@ -72,7 +71,7 @@
   h->size = 0;
   h->slots = slots;
 
-  h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *));
+  h->table = (struct curl_llist **) malloc(slots * sizeof(struct curl_llist *));
   if(h->table) {
     for (i = 0; i < slots; ++i) {
       h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor);
@@ -89,12 +88,12 @@
     return 1; /* failure */
 }
 
-curl_hash *
+struct curl_hash *
 Curl_hash_alloc(int slots, curl_hash_dtor dtor)
 {
-  curl_hash *h;
+  struct curl_hash *h;
 
-  h = (curl_hash *) malloc(sizeof(curl_hash));
+  h = (struct curl_hash *) malloc(sizeof(struct curl_hash));
   if (h) {
     if(Curl_hash_init(h, slots, dtor)) {
       /* failure */
@@ -118,15 +117,18 @@
   return 0;
 }
 
-static curl_hash_element *
+static struct curl_hash_element *
 mk_hash_element(char *key, size_t key_len, const void *p)
 {
-  curl_hash_element *he =
-    (curl_hash_element *) malloc(sizeof(curl_hash_element));
+  struct curl_hash_element *he =
+    (struct curl_hash_element *) malloc(sizeof(struct curl_hash_element));
 
   if(he) {
-    char *dup = strdup(key);
+    char *dup = malloc(key_len);
     if(dup) {
+      /* copy the key */
+      memcpy(dup, key, key_len);
+
       he->key = dup;
       he->key_len = key_len;
       he->ptr = (void *) p;
@@ -147,14 +149,14 @@
 /* Return the data in the hash. If there already was a match in the hash,
    that data is returned. */
 void *
-Curl_hash_add(curl_hash *h, char *key, size_t key_len, void *p)
+Curl_hash_add(struct curl_hash *h, char *key, size_t key_len, void *p)
 {
-  curl_hash_element  *he;
-  curl_llist_element *le;
-  curl_llist *l = FETCH_LIST(h, key, key_len);
+  struct curl_hash_element  *he;
+  struct curl_llist_element *le;
+  struct curl_llist *l = FETCH_LIST(h, key, key_len);
 
   for (le = l->head; le; le = le->next) {
-    he = (curl_hash_element *) le->ptr;
+    he = (struct curl_hash_element *) le->ptr;
     if (hash_key_compare(he->key, he->key_len, key, key_len)) {
       h->dtor(p);     /* remove the NEW entry */
       return he->ptr; /* return the EXISTING entry */
@@ -180,16 +182,31 @@
   return NULL; /* failure */
 }
 
+/* remove the identified hash entry, returns non-zero on failure */
+int Curl_hash_delete(struct curl_hash *h, char *key, size_t key_len)
+{
+  struct curl_llist_element *le;
+  struct curl_hash_element  *he;
+  struct curl_llist *l = FETCH_LIST(h, key, key_len);
+
+  for (le = l->head; le; le = le->next) {
+    he = le->ptr;
+    if (hash_key_compare(he->key, he->key_len, key, key_len)) {
+      Curl_llist_remove(l, le, (void *) h);
+      return 0;
+    }
+  }
+  return 1;
+}
+
 void *
-Curl_hash_pick(curl_hash *h, char *key, size_t key_len)
+Curl_hash_pick(struct curl_hash *h, char *key, size_t key_len)
 {
-  curl_llist_element *le;
-  curl_hash_element  *he;
-  curl_llist *l = FETCH_LIST(h, key, key_len);
+  struct curl_llist_element *le;
+  struct curl_hash_element  *he;
+  struct curl_llist *l = FETCH_LIST(h, key, key_len);
 
-  for (le = l->head;
-       le;
-       le = le->next) {
+  for (le = l->head; le; le = le->next) {
     he = le->ptr;
     if (hash_key_compare(he->key, he->key_len, key, key_len)) {
       return he->ptr;
@@ -204,7 +221,7 @@
 Curl_hash_apply(curl_hash *h, void *user,
                 void (*cb)(void *user, void *ptr))
 {
-  curl_llist_element  *le;
+  struct curl_llist_element  *le;
   int                  i;
 
   for (i = 0; i < h->slots; ++i) {
@@ -219,7 +236,7 @@
 #endif
 
 void
-Curl_hash_clean(curl_hash *h)
+Curl_hash_clean(struct curl_hash *h)
 {
   int i;
 
@@ -231,19 +248,19 @@
 }
 
 void
-Curl_hash_clean_with_criterium(curl_hash *h, void *user,
+Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
                                int (*comp)(void *, void *))
 {
-  curl_llist_element *le;
-  curl_llist_element *lnext;
-  curl_llist *list;
+  struct curl_llist_element *le;
+  struct curl_llist_element *lnext;
+  struct curl_llist *list;
   int i;
 
   for (i = 0; i < h->slots; ++i) {
     list = h->table[i];
     le = list->head; /* get first list entry */
     while(le) {
-      curl_hash_element *he = le->ptr;
+      struct curl_hash_element *he = le->ptr;
       lnext = le->next;
       /* ask the callback function if we shall remove this entry or not */
       if (comp(user, he->ptr)) {
@@ -256,7 +273,7 @@
 }
 
 void
-Curl_hash_destroy(curl_hash *h)
+Curl_hash_destroy(struct curl_hash *h)
 {
   if (!h)
     return;
@@ -265,3 +282,34 @@
   free(h);
 }
 
+#if 0 /* useful function for debugging hashes and their contents */
+void Curl_hash_print(struct curl_hash *h,
+                     void (*func)(void *))
+{
+  int i;
+  struct curl_llist_element *le;
+  struct curl_llist *list;
+  struct curl_hash_element  *he;
+  if (!h)
+    return;
+
+  fprintf(stderr, "=Hash dump=\n");
+
+  for (i = 0; i < h->slots; i++) {
+    list = h->table[i];
+    le = list->head; /* get first list entry */
+    if(le) {
+      fprintf(stderr, "index %d:", i);
+      while(le) {
+        he = le->ptr;
+        if(func)
+          func(he->ptr);
+        else
+          fprintf(stderr, " [%p]", he->ptr);
+        le = le->next;
+      }
+      fprintf(stderr, "\n");
+    }
+  }
+}
+#endif

Index: ftp.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/ftp.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ftp.h	24 Jun 2005 13:00:12 -0000	1.1
+++ ftp.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,18 +1,18 @@
 #ifndef __FTP_H
 #define __FTP_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -24,14 +24,20 @@
  ***************************************************************************/
 
 #ifndef CURL_DISABLE_FTP
-CURLcode Curl_ftp(struct connectdata *conn);
-CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode);
-CURLcode Curl_ftp_connect(struct connectdata *conn);
+CURLcode Curl_ftp(struct connectdata *conn, bool *done);
+CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode, bool premature);
+CURLcode Curl_ftp_connect(struct connectdata *conn, bool *done);
 CURLcode Curl_ftp_disconnect(struct connectdata *conn);
 CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
+CURLcode Curl_nbftpsendf(struct connectdata *, const char *fmt, ...);
 CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
                              int *ftpcode);
 CURLcode Curl_ftp_nextconnect(struct connectdata *conn);
-#endif
-
-#endif
+CURLcode Curl_ftp_multi_statemach(struct connectdata *conn, bool *done);
+int Curl_ftp_getsock(struct connectdata *conn,
+                     curl_socket_t *socks,
+                     int numsocks);
+CURLcode Curl_ftp_doing(struct connectdata *conn,
+                        bool *dophase_done);
+#endif /* CURL_DISABLE_FTP */
+#endif /* __FTP_H */

Index: if2ip.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/if2ip.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- if2ip.h	24 Jun 2005 13:00:12 -0000	1.1
+++ if2ip.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,13 +24,11 @@
  ***************************************************************************/
 #include "setup.h"
 
-#if !defined(WIN32) && !defined(__BEOS__) && !defined(__CYGWIN32__) && \
-    !defined(__riscos__) && !defined(__INTERIX)
-extern char *Curl_if2ip(const char *interface, char *buf, int buf_size);
-#else
-#define Curl_if2ip(a,b,c) NULL
-#endif
+extern char *Curl_if2ip(const char *interf, char *buf, int buf_size);
+
 #ifdef __INTERIX
+#include <sys/socket.h>
+
 /* Nedelcho Stanev's work-around for SFU 3.0 */
 struct ifreq {
 #define IFNAMSIZ 16

Index: if2ip.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/if2ip.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- if2ip.c	24 Jun 2005 13:00:12 -0000	1.1
+++ if2ip.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -31,8 +31,15 @@
 #include <unistd.h>
 #endif
 
-#if !defined(WIN32) && !defined(__BEOS__) && !defined(__CYGWIN32__) && \
-    !defined(__riscos__) && !defined(__INTERIX) && !defined(NETWARE)
+#include "if2ip.h"
+
+/*
+ * This test can probably be simplified to #if defined(SIOCGIFADDR) and
+ * moved after the following includes.
+ */
+#if !defined(WIN32) && !defined(__BEOS__) && !defined(__CYGWIN__) && \
+    !defined(__riscos__) && !defined(__INTERIX) && !defined(NETWARE) && \
+    !defined(_AMIGASF) && !defined(__minix)
 
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
@@ -55,7 +62,6 @@
 #include <sys/ioctl.h>
 #endif
 
-/* -- if2ip() -- */
 #ifdef HAVE_NETDB_H
 #include <netdb.h>
 #endif
@@ -64,16 +70,12 @@
 #include <sys/sockio.h>
 #endif
 
-#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
-#include "inet_ntoa_r.h"
-#endif
-
-#ifdef  VMS
+#ifdef VMS
 #include <inet.h>
 #endif
 
-#include "if2ip.h"
-#include "curl_memory.h"
+#include "inet_ntop.h"
+#include "memory.h"
 
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -100,7 +102,7 @@
       return NULL; /* this can't be a fine interface name */
     memcpy(req.ifr_name, interface, len+1);
     req.ifr_addr.sa_family = AF_INET;
-#ifdef  IOCTL_3_ARGS
+#ifdef IOCTL_3_ARGS
     if (SYS_ERROR == ioctl(dummy, SIOCGIFADDR, &req)) {
 #else
     if (SYS_ERROR == ioctl(dummy, SIOCGIFADDR, &req, sizeof(req))) {
@@ -111,19 +113,9 @@
     else {
       struct in_addr in;
 
-      union {
-        struct sockaddr_in *sin;
-        struct sockaddr *s;
-      } soadd;
-
-      soadd.s = &req.ifr_dstaddr;
-      memcpy(&in, &(soadd.sin->sin_addr.s_addr), sizeof(in));
-#if defined(HAVE_INET_NTOA_R)
-      ip = inet_ntoa_r(in,buf,buf_size);
-#else
-      ip = strncpy(buf,inet_ntoa(in),buf_size);
-      ip[buf_size - 1] = 0;
-#endif
+      struct sockaddr_in *s = (struct sockaddr_in *)&req.ifr_dstaddr;
+      memcpy(&in, &s->sin_addr, sizeof(in));
+      ip = (char *) Curl_inet_ntop(s->sin_family, &in, buf, buf_size);
     }
     sclose(dummy);
   }
@@ -132,9 +124,9 @@
 
 /* -- end of if2ip() -- */
 #else
-char *Curl_if2ip(const char *interface, char *buf, int buf_size)
+char *Curl_if2ip(const char *interf, char *buf, int buf_size)
 {
-    (void) interface;
+    (void) interf;
     (void) buf;
     (void) buf_size;
     return NULL;

Index: ftp.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/ftp.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ftp.c	24 Jun 2005 13:00:12 -0000	1.1
+++ ftp.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -29,18 +29,14 @@
 #include <stdlib.h>
 #include <stdarg.h>
[...5309 lines suppressed...]
- * The input argument is already checked for validity.
- * Performs a 3rd party transfer between two remote hosts.
- */
-static CURLcode ftp_3rdparty(struct connectdata *conn)
-{
-  CURLcode retcode;
-
-  conn->proto.ftp->ctl_valid = conn->sec_conn->proto.ftp->ctl_valid = TRUE;
-  conn->size = conn->sec_conn->size = -1;
-
-  retcode = ftp_3rdparty_pretransfer(conn);
-  if (!retcode)
-    retcode = ftp_3rdparty_transfer(conn);
+    freedirs(conn);
 
-  return retcode;
+  return result;
 }
 
 #endif /* CURL_DISABLE_FTP */

--- curl_memory.h DELETED ---

Index: progress.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/progress.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- progress.h	24 Jun 2005 13:00:12 -0000	1.1
+++ progress.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,10 +1,10 @@
 #ifndef __PROGRESS_H
 #define __PROGRESS_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
@@ -12,7 +12,7 @@
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -37,7 +37,7 @@
   TIMER_REDIRECT,
   TIMER_LAST /* must be last */
 } timerid;
-  
+
 void Curl_pgrsDone(struct connectdata *);
 void Curl_pgrsStartNow(struct SessionHandle *data);
 void Curl_pgrsSetDownloadSize(struct SessionHandle *data, curl_off_t size);

Index: progress.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/progress.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- progress.c	24 Jun 2005 13:00:12 -0000	1.1
+++ progress.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -139,10 +139,8 @@
   struct SessionHandle *data = conn->data;
   data->progress.lastshow=0;
   Curl_pgrsUpdate(conn); /* the final (forced) update */
-  if(!(data->progress.flags & PGRS_HIDE) &&
-     !data->progress.callback)
-    /* only output if we don't use a progress callback and we're not hidden */
-    fprintf(data->set.err, "\n");
+
+  data->progress.speeder_c = 0; /* reset the progress meter display */
 }
 
 /* reset all times except redirect */
@@ -254,11 +252,11 @@
          even when not displayed! */
   else if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
     if (!data->progress.callback) {
-      if(conn->resume_from)
+      if(data->reqdata.resume_from)
         fprintf(data->set.err,
                 "** Resuming transfer from byte position %" FORMAT_OFF_T
                 "\n",
-                conn->resume_from);
+                data->reqdata.resume_from);
       fprintf(data->set.err,
               "  %% Total    %% Received %% Xferd  Average Speed   Time    Time     Time  Current\n"
               "                                 Dload  Upload   Total   Spent    Left  Speed\n");
@@ -328,7 +326,7 @@
       curl_off_t amount = data->progress.speeder[nowindex]-
         data->progress.speeder[checkindex];
 
-      if(amount > 0xffffffff/1000)
+      if(amount > 4294967 /* 0xffffffff/1000 */)
         /* the 'amount' value is bigger than would fit in 32 bits if
            multiplied with 1000, so we use the double math for this */
         data->progress.current_speed = (curl_off_t)

Index: cookie.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/cookie.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cookie.c	24 Jun 2005 13:00:12 -0000	1.1
+++ cookie.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -80,25 +80,30 @@
 
 #include "setup.h"
 
-#ifndef CURL_DISABLE_HTTP
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
+
+#define _MPRINTF_REPLACE /* without this on windows OS we get undefined reference to snprintf */
+#include <curl/mprintf.h>
 
 #include "urldata.h"
 #include "cookie.h"
-#include "getdate.h"
 #include "strequal.h"
 #include "strtok.h"
 #include "sendf.h"
-#include "curl_memory.h"
+#include "memory.h"
+#include "share.h"
+#include "strtoofft.h"
 
 /* The last #include file should be: */
 #ifdef CURLDEBUG
 #include "memdebug.h"
 #endif
 
+#define my_isspace(x) ((x == ' ') || (x == '\t'))
+
 static void freecookie(struct Cookie *co)
 {
   if(co->expirestr)
@@ -111,6 +116,10 @@
     free(co->name);
   if(co->value)
     free(co->value);
+  if(co->maxage)
+    free(co->maxage);
+  if(co->version)
+    free(co->version);
 
   free(co);
 }
@@ -126,6 +135,27 @@
   return (bool)strequal(little, bigone+biglen-littlelen);
 }
 
+/*
+ * Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
+ */
+void Curl_cookie_loadfiles(struct SessionHandle *data)
+{
+  struct curl_slist *list = data->change.cookielist;
+  if(list) {
+    Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+    while(list) {
+      data->cookies = Curl_cookie_init(data,
+                                       list->data,
+                                       data->cookies,
+                                       data->set.cookiesession);
+      list = list->next;
+    }
+    Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+    curl_slist_free_all(data->change.cookielist); /* clean up list */
+    data->change.cookielist = NULL; /* don't do this again! */
+  }
+}
+
 /****************************************************************************
  *
  * Curl_cookie_add()
@@ -156,7 +186,7 @@
   struct Cookie *co;
   struct Cookie *lastc=NULL;
   time_t now = time(NULL);
-  bool replace_old;
+  bool replace_old = FALSE;
   bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */
 
   /* First, alloc and init a new struct for it */
@@ -176,7 +206,7 @@
 
     semiptr=strchr(lineptr, ';'); /* first, find a semicolon */
 
-    while(*lineptr && isspace((int)*lineptr))
+    while(*lineptr && my_isspace(*lineptr))
       lineptr++;
 
     ptr = lineptr;
@@ -199,14 +229,14 @@
 
           /* Strip off trailing whitespace from the 'what' */
           size_t len=strlen(what);
-          while(len && isspace((int)what[len-1])) {
+          while(len && my_isspace(what[len-1])) {
             what[len-1]=0;
             len--;
           }
 
           /* Skip leading whitespace from the 'what' */
           whatptr=what;
-          while(isspace((int)*whatptr)) {
+          while(my_isspace(*whatptr)) {
             whatptr++;
           }
 
@@ -305,7 +335,7 @@
               break;
             }
             co->expires =
-              atoi((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0]) + now;
+              atoi((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0]) + (long)now;
           }
           else if(strequal("expires", name)) {
             co->expirestr=strdup(whatptr);
@@ -348,7 +378,7 @@
       }
 
       ptr=semiptr+1;
-      while(ptr && *ptr && isspace((int)*ptr))
+      while(ptr && *ptr && my_isspace(*ptr))
         ptr++;
       semiptr=strchr(ptr, ';'); /* now, find the next semicolon */
 
@@ -466,7 +496,7 @@
         co->secure = (bool)strequal(ptr, "TRUE");
         break;
       case 4:
-        co->expires = atoi(ptr);
+        co->expires = curlx_strtoofft(ptr, NULL, 10);
         break;
       case 5:
         co->name = strdup(ptr);
@@ -647,6 +677,10 @@
     fp = stdin;
     fromfile=FALSE;
   }
+  else if(file && !*file) {
+    /* points to a "" string */
+    fp = NULL;
+  }
   else
     fp = file?fopen(file, "r"):NULL;
 
@@ -668,7 +702,7 @@
           lineptr=line;
           headerline=FALSE;
         }
-        while(*lineptr && isspace((int)*lineptr))
+        while(*lineptr && my_isspace(*lineptr))
           lineptr++;
 
         Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL);
@@ -699,68 +733,85 @@
 struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
                                    char *host, char *path, bool secure)
 {
-   struct Cookie *newco;
-   struct Cookie *co;
-   time_t now = time(NULL);
-   struct Cookie *mainco=NULL;
+  struct Cookie *newco;
+  struct Cookie *co;
+  time_t now = time(NULL);
+  struct Cookie *mainco=NULL;
 
-   if(!c || !c->cookies)
-      return NULL; /* no cookie struct or no cookies in the struct */
+  if(!c || !c->cookies)
+    return NULL; /* no cookie struct or no cookies in the struct */
 
-   co = c->cookies;
+  co = c->cookies;
 
-   while(co) {
-     /* only process this cookie if it is not expired or had no expire
-        date AND that if the cookie requires we're secure we must only
-        continue if we are! */
-     if( (co->expires<=0 || (co->expires> now)) &&
-         (co->secure?secure:TRUE) ) {
+  while(co) {
+    /* only process this cookie if it is not expired or had no expire
+       date AND that if the cookie requires we're secure we must only
+       continue if we are! */
+    if( (co->expires<=0 || (co->expires> now)) &&
+        (co->secure?secure:TRUE) ) {
 
-       /* now check if the domain is correct */
-       if(!co->domain ||
-          (co->tailmatch && tailmatch(co->domain, host)) ||
-          (!co->tailmatch && strequal(host, co->domain)) ) {
-         /* the right part of the host matches the domain stuff in the
-            cookie data */
+      /* now check if the domain is correct */
+      if(!co->domain ||
+         (co->tailmatch && tailmatch(co->domain, host)) ||
+         (!co->tailmatch && strequal(host, co->domain)) ) {
+        /* the right part of the host matches the domain stuff in the
+           cookie data */
 
-         /* now check the left part of the path with the cookies path
-            requirement */
-         if(!co->path ||
-            checkprefix(co->path, path) ) {
+        /* now check the left part of the path with the cookies path
+           requirement */
+        if(!co->path ||
+           /* not using checkprefix() because matching should be
+              case-sensitive */
+           !strncmp(co->path, path, strlen(co->path)) ) {
 
-           /* and now, we know this is a match and we should create an
-              entry for the return-linked-list */
+          /* and now, we know this is a match and we should create an
+             entry for the return-linked-list */
 
-           newco = (struct Cookie *)malloc(sizeof(struct Cookie));
-           if(newco) {
-             /* first, copy the whole source cookie: */
-             memcpy(newco, co, sizeof(struct Cookie));
+          newco = (struct Cookie *)malloc(sizeof(struct Cookie));
+          if(newco) {
+            /* first, copy the whole source cookie: */
+            memcpy(newco, co, sizeof(struct Cookie));
 
-             /* then modify our next */
-             newco->next = mainco;
+            /* then modify our next */
+            newco->next = mainco;
 
-             /* point the main to us */
-             mainco = newco;
-           }
-           else {
-              /* failure, clear up the allocated chain and return NULL */
-             while(mainco) {
-               co = mainco->next;
-               free(mainco);
-               mainco = co;
-             }
+            /* point the main to us */
+            mainco = newco;
+          }
+          else {
+            /* failure, clear up the allocated chain and return NULL */
+            while(mainco) {
+              co = mainco->next;
+              free(mainco);
+              mainco = co;
+            }
 
-             return NULL;
-           }
-         }
-       }
-     }
-     co = co->next;
-   }
+            return NULL;
+          }
+        }
+      }
+    }
+    co = co->next;
+  }
 
-   return mainco; /* return the new list */
+  return mainco; /* return the new list */
 }
 
+/*****************************************************************************
+ *
+ * Curl_cookie_clearall()
+ *
+ * Clear all existing cookies and reset the counter.
+ *
+ ****************************************************************************/
+void Curl_cookie_clearall(struct CookieInfo *cookies)
+{
+  if(cookies) {
+    Curl_cookie_freelist(cookies->cookies);
+    cookies->cookies = NULL;
+    cookies->numcookies = 0;
+  }
+}
 
 /*****************************************************************************
  *
@@ -772,17 +823,56 @@
 
 void Curl_cookie_freelist(struct Cookie *co)
 {
-   struct Cookie *next;
-   if(co) {
-      while(co) {
-         next = co->next;
-         free(co); /* we only free the struct since the "members" are all
+  struct Cookie *next;
+  if(co) {
+    while(co) {
+      next = co->next;
+      free(co); /* we only free the struct since the "members" are all
                       just copied! */
-         co = next;
-      }
-   }
+      co = next;
+    }
+  }
 }
 
+
+/*****************************************************************************
+ *
+ * Curl_cookie_clearsess()
+ *
+ * Free all session cookies in the cookies list.
+ *
+ ****************************************************************************/
+void Curl_cookie_clearsess(struct CookieInfo *cookies)
+{
+  struct Cookie *first, *curr, *next, *prev = NULL;
+
+  if(!cookies->cookies)
+    return;
+
+  first = curr = prev = cookies->cookies;
+
+  for(; curr; curr = next) {
+    next = curr->next;
+    if(!curr->expires) {
+      if(first == curr)
+        first = next;
+
+      if(prev == curr)
+        prev = next;
+      else
+        prev->next = next;
+
+      free(curr);
+      cookies->numcookies--;
+    }
+    else
+      prev = curr;
+  }
+
+  cookies->cookies = first;
+}
+
+
 /*****************************************************************************
  *
  * Curl_cookie_cleanup()
@@ -792,20 +882,48 @@
  ****************************************************************************/
 void Curl_cookie_cleanup(struct CookieInfo *c)
 {
-   struct Cookie *co;
-   struct Cookie *next;
-   if(c) {
-      if(c->filename)
-         free(c->filename);
-      co = c->cookies;
+  struct Cookie *co;
+  struct Cookie *next;
+  if(c) {
+    if(c->filename)
+      free(c->filename);
+    co = c->cookies;
 
-      while(co) {
-         next = co->next;
-         freecookie(co);
-         co = next;
-      }
-      free(c); /* free the base struct as well */
-   }
+    while(co) {
+      next = co->next;
+      freecookie(co);
+      co = next;
+    }
+    free(c); /* free the base struct as well */
+  }
+}
+
+/* get_netscape_format()
+ *
+ * Formats a string for Netscape output file, w/o a newline at the end.
+ *
+ * Function returns a char * to a formatted line. Has to be free()d
+*/
+static char *get_netscape_format(const struct Cookie *co)
+{
+  return aprintf(
+    "%s%s\t" /* domain */
+    "%s\t"   /* tailmatch */
+    "%s\t"   /* path */
+    "%s\t"   /* secure */
+    "%" FORMAT_OFF_T "\t"   /* expires */
+    "%s\t"   /* name */
+    "%s",    /* value */
+    /* Make sure all domains are prefixed with a dot if they allow
+       tailmatching. This is Mozilla-style. */
+    (co->tailmatch && co->domain && co->domain[0] != '.')? ".":"",
+    co->domain?co->domain:"unknown",
+    co->tailmatch?"TRUE":"FALSE",
+    co->path?co->path:"/",
+    co->secure?"TRUE":"FALSE",
+    co->expires,
+    co->name,
+    co->value?co->value:"");
 }
 
 /*
@@ -839,33 +957,22 @@
   }
 
   if(c) {
+    char *format_ptr;
+
     fputs("# Netscape HTTP Cookie File\n"
-          "# http://www.netscape.com/newsref/std/cookie_spec.html\n"
+          "# http://curlm.haxx.se/rfc/cookie_spec.html\n"
           "# This file was generated by libcurl! Edit at your own risk.\n\n",
           out);
     co = c->cookies;
 
     while(co) {
-      fprintf(out,
-              "%s%s\t" /* domain */
-              "%s\t" /* tailmatch */
-              "%s\t" /* path */
-              "%s\t" /* secure */
-              "%u\t" /* expires */
-              "%s\t" /* name */
-              "%s\n", /* value */
-
-              /* Make sure all domains are prefixed with a dot if they allow
-                 tailmatching. This is Mozilla-style. */
-              (co->tailmatch && co->domain && co->domain[0] != '.')? ".":"",
-              co->domain?co->domain:"unknown",
-              co->tailmatch?"TRUE":"FALSE",
-              co->path?co->path:"/",
-              co->secure?"TRUE":"FALSE",
-              (unsigned int)co->expires,
-              co->name,
-              co->value?co->value:"");
-
+      format_ptr = get_netscape_format(co);
+      if (format_ptr == NULL) {
+        fprintf(out, "#\n# Fatal libcurl error\n");
+        return 1;
+      }
+      fprintf(out, "%s\n", format_ptr);
+      free(format_ptr);
       co=co->next;
     }
   }
@@ -876,4 +983,35 @@
   return 0;
 }
 
-#endif /* CURL_DISABLE_HTTP */
+struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
+{
+  struct curl_slist *list = NULL;
+  struct curl_slist *beg;
+  struct Cookie *c;
+  char *line;
+
+  if ((data->cookies == NULL) ||
+      (data->cookies->numcookies == 0))
+    return NULL;
+
+  c = data->cookies->cookies;
+
+  beg = list;
+  while (c) {
+    /* fill the list with _all_ the cookies we know */
+    line = get_netscape_format(c);
+    if (line == NULL) {
+      /* get_netscape_format returns null only if we run out of memory */
+
+      curl_slist_free_all(beg); /* free some memory */
+      return NULL;
+    }
+    list = curl_slist_append(list, line);
+    free(line);
+    c = c->next;
+  }
+
+  return list;
+}
+
+#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_COOKIES */

Index: file.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/file.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- file.h	24 Jun 2005 13:00:12 -0000	1.1
+++ file.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -2,18 +2,18 @@
 #define __FILE_H
 
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -24,8 +24,8 @@
  * $Id$
  ***************************************************************************/
 #ifndef CURL_DISABLE_FILE
-CURLcode Curl_file(struct connectdata *);
-CURLcode Curl_file_done(struct connectdata *, CURLcode);
+CURLcode Curl_file(struct connectdata *, bool *done);
+CURLcode Curl_file_done(struct connectdata *, CURLcode, bool premature);
 CURLcode Curl_file_connect(struct connectdata *);
 #endif
 #endif

Index: cookie.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/cookie.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cookie.h	24 Jun 2005 13:00:12 -0000	1.1
+++ cookie.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,11 +24,13 @@
  ***************************************************************************/
 
 #include <stdio.h>
-#ifdef WIN32
+#if defined(WIN32)
 #include <time.h>
 #else
+#ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
+#endif
 
 #include <curl/curl.h>
 
@@ -38,7 +40,7 @@
   char *value;       /* name = <this> */
   char *path;         /* path = <this> */
   char *domain;      /* domain = <this> */
-  long expires;    /* expires = <this> */
+  curl_off_t expires;  /* expires = <this> */
   char *expirestr;   /* the plain text version */
   bool tailmatch;    /* weather we do tail-matchning of the domain name */
 
@@ -89,7 +91,17 @@
                                     char *, struct CookieInfo *, bool);
 struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool);
 void Curl_cookie_freelist(struct Cookie *);
+void Curl_cookie_clearall(struct CookieInfo *cookies);
+void Curl_cookie_clearsess(struct CookieInfo *cookies);
 void Curl_cookie_cleanup(struct CookieInfo *);
 int Curl_cookie_output(struct CookieInfo *, char *);
 
+#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
+#define Curl_cookie_list(x) NULL
+#define Curl_cookie_loadfiles(x) do { } while (0)
+#else
+struct curl_slist *Curl_cookie_list(struct SessionHandle *data);
+void Curl_cookie_loadfiles(struct SessionHandle *data);
+#endif
+
 #endif

Index: version.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/version.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- version.c	24 Jun 2005 13:00:13 -0000	1.1
+++ version.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -28,6 +28,7 @@
 
 #include <curl/curl.h>
 #include "urldata.h"
+#include "sslgen.h"
 
 #define _MPRINTF_REPLACE /* use the internal *printf() functions */
 #include <curl/mprintf.h>
@@ -40,88 +41,28 @@
 #include <stringprep.h>
 #endif
 
-#ifdef USE_SSLEAY
-static int getssl_version(char *ptr, size_t left, long *num)
-{
-
-#if (SSLEAY_VERSION_NUMBER >= 0x905000)
-  {
-    char sub[2];
-    unsigned long ssleay_value;
-    sub[1]='\0';
-    ssleay_value=SSLeay();
-    *num = (long)ssleay_value;
-    if(ssleay_value < 0x906000) {
-      ssleay_value=SSLEAY_VERSION_NUMBER;
-      sub[0]='\0';
-    }
-    else {
-      if(ssleay_value&0xff0) {
-        sub[0]=(char)((ssleay_value>>4)&0xff) + 'a' -1;
-      }
-      else
-        sub[0]='\0';
-    }
-
-    return snprintf(ptr, left, " OpenSSL/%lx.%lx.%lx%s",
-                    (ssleay_value>>28)&0xf,
-                    (ssleay_value>>20)&0xff,
-                    (ssleay_value>>12)&0xff,
-                    sub);
-  }
-
-#else
-  *num = SSLEAY_VERSION_NUMBER;
-#if (SSLEAY_VERSION_NUMBER >= 0x900000)
-  return snprintf(ptr, left, " OpenSSL/%lx.%lx.%lx",
-                  (SSLEAY_VERSION_NUMBER>>28)&0xff,
-                  (SSLEAY_VERSION_NUMBER>>20)&0xff,
-                  (SSLEAY_VERSION_NUMBER>>12)&0xf);
-#else
-  {
-    char sub[2];
-    sub[1]='\0';
-    if(SSLEAY_VERSION_NUMBER&0x0f) {
-      sub[0]=(SSLEAY_VERSION_NUMBER&0x0f) + 'a' -1;
-    }
-    else
-      sub[0]='\0';
-
-    return snprintf(ptr, left, " SSL/%x.%x.%x%s",
-                    (SSLEAY_VERSION_NUMBER>>12)&0xff,
-                    (SSLEAY_VERSION_NUMBER>>8)&0xf,
-                    (SSLEAY_VERSION_NUMBER>>4)&0xf, sub);
-  }
-#endif
+#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
+#include <iconv.h>
 #endif
-}
 
+#ifdef USE_LIBSSH2
+#include <libssh2.h>
 #endif
 
+
 char *curl_version(void)
 {
   static char version[200];
   char *ptr=version;
-  /* to prevent compier warnings, we only declare len if we have code
-     that uses it */
-#if defined(USE_SSLEAY) || defined(HAVE_LIBZ) || defined(USE_ARES) || \
-  defined(USE_LIBIDN)
-  int len;
-#endif
+  size_t len;
   size_t left = sizeof(version);
   strcpy(ptr, LIBCURL_NAME "/" LIBCURL_VERSION );
   ptr=strchr(ptr, '\0');
   left -= strlen(ptr);
-  (void)left;
 
-#ifdef USE_SSLEAY
-  {
-    long num;
-    len = getssl_version(ptr, left, &num);
-    left -= len;
-    ptr += len;
-  }
-#endif
+  len = Curl_ssl_version(ptr, left);
+  left -= len;
+  ptr += len;
 
 #ifdef HAVE_LIBZ
   len = snprintf(ptr, left, " zlib/%s", zlibVersion());
@@ -141,19 +82,35 @@
     ptr += len;
   }
 #endif
+#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
+#ifdef _LIBICONV_VERSION
+  len = snprintf(ptr, left, " iconv/%d.%d",
+                 _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255);
+#else
+  /* version unknown */
+  len = snprintf(ptr, left, " iconv");
+#endif /* _LIBICONV_VERSION */
+  left -= len;
+  ptr += len;
+#endif
+#ifdef USE_LIBSSH2
+  len = snprintf(ptr, left, " libssh2/%s", LIBSSH2_VERSION);
+  left -= len;
+  ptr += len;
+#endif
 
   return version;
 }
 
 /* data for curl_version_info */
 
-static const char *protocols[] = {
+static const char * const protocols[] = {
+#ifndef CURL_DISABLE_TFTP
+  "tftp",
+#endif
 #ifndef CURL_DISABLE_FTP
   "ftp",
 #endif
-#ifndef CURL_DISABLE_GOPHER
-  "gopher",
-#endif
 #ifndef CURL_DISABLE_TELNET
   "telnet",
 #endif
@@ -170,7 +127,7 @@
   "file",
 #endif
 
-#ifdef USE_SSLEAY
+#ifdef USE_SSL
 #ifndef CURL_DISABLE_HTTP
   "https",
 #endif
@@ -178,6 +135,12 @@
   "ftps",
 #endif
 #endif
+
+#ifdef USE_LIBSSH2
+  "scp",
+  "sftp",
+#endif
+
   NULL
 };
 
@@ -193,9 +156,14 @@
 #ifdef HAVE_KRB4
   | CURL_VERSION_KERBEROS4
 #endif
-#ifdef USE_SSLEAY
+#ifdef USE_SSL
   | CURL_VERSION_SSL
-  | CURL_VERSION_NTLM /* since this requires OpenSSL */
+#endif
+#ifdef USE_NTLM
+  | CURL_VERSION_NTLM
+#endif
+#ifdef USE_WINDOWS_SSPI
+  | CURL_VERSION_SSPI
 #endif
 #ifdef HAVE_LIBZ
   | CURL_VERSION_LIBZ
@@ -215,26 +183,31 @@
 #if defined(ENABLE_64BIT) && (SIZEOF_CURL_OFF_T > 4)
   | CURL_VERSION_LARGEFILE
 #endif
+#if defined(CURL_DOES_CONVERSIONS)
+  | CURL_VERSION_CONV
+#endif
   ,
   NULL, /* ssl_version */
-  0,    /* ssl_version_num */
+  0,    /* ssl_version_num, this is kept at zero */
   NULL, /* zlib_version */
   protocols,
   NULL, /* c-ares version */
   0,    /* c-ares version numerical */
   NULL, /* libidn version */
+  0,    /* iconv version */
+  NULL, /* ssh lib version */
 };
 
 curl_version_info_data *curl_version_info(CURLversion stamp)
 {
-#ifdef USE_SSLEAY
-  static char ssl_buffer[80];
-  long num;
-  getssl_version(ssl_buffer, sizeof(ssl_buffer), &num);
+#ifdef USE_LIBSSH2
+  static char ssh_buffer[80];
+#endif
 
+#ifdef USE_SSL
+  static char ssl_buffer[80];
+  Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer));
   version_info.ssl_version = ssl_buffer;
-  version_info.ssl_version_num = num;
-  /* SSL stuff is left zero if undefined */
 #endif
 
 #ifdef HAVE_LIBZ
@@ -255,6 +228,21 @@
   if(version_info.libidn)
     version_info.features |= CURL_VERSION_IDN;
 #endif
+
+#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
+#ifdef _LIBICONV_VERSION
+  version_info.iconv_ver_num = _LIBICONV_VERSION;
+#else
+  /* version unknown */
+  version_info.iconv_ver_num = -1;
+#endif /* _LIBICONV_VERSION */
+#endif
+
+#ifdef USE_LIBSSH2
+  snprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION);
+  version_info.libssh_version = ssh_buffer;
+#endif
+
   (void)stamp; /* avoid compiler warnings, we don't use this */
 
   return &version_info;

Index: arpa_telnet.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/arpa_telnet.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- arpa_telnet.h	24 Jun 2005 13:00:12 -0000	1.1
+++ arpa_telnet.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -39,7 +39,7 @@
 /*
  * The telnet options represented as strings
  */
-static const char *telnetoptions[]=
+static const char * const telnetoptions[]=
 {
   "BINARY",      "ECHO",           "RCP",           "SUPPRESS GO AHEAD",
   "NAME",        "STATUS",         "TIMING MARK",   "RCTE",
@@ -78,7 +78,7 @@
 /*
  * Then those numbers represented as strings:
  */
-static const char *telnetcmds[]=
+static const char * const telnetcmds[]=
 {
   "EOF",  "SUSP",  "ABORT", "EOR",  "SE",
   "NOP",  "DMARK", "BRK",   "IP",   "AO",

Index: connect.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/connect.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- connect.h	24 Jun 2005 13:00:12 -0000	1.1
+++ connect.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -31,13 +31,15 @@
                            bool *connected);
 
 CURLcode Curl_connecthost(struct connectdata *conn,
-                          struct Curl_dns_entry *host, /* connect to this */
+                          const struct Curl_dns_entry *host, /* connect to this */
                           curl_socket_t *sockconn, /* not set if error */
                           Curl_addrinfo **addr, /* the one we used */
                           bool *connected /* truly connected? */
                           );
 
-int Curl_ourerrno(void);
+int Curl_sockerrno(void);
+
+CURLcode Curl_store_ip_addr(struct connectdata *conn);
 
 #define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
 

Index: hostip4.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/hostip4.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- hostip4.c	24 Jun 2005 13:00:12 -0000	1.1
+++ hostip4.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,11 +26,9 @@
 #include <string.h>
 #include <errno.h>
 
-#define _REENTRANT
-
-#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
+#ifdef NEED_MALLOC_H
 #include <malloc.h>
-#else
+#endif
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -57,21 +55,15 @@
 #include <inet.h>
 #include <stdlib.h>
 #endif
-#endif
 
 #ifdef HAVE_SETJMP_H
 #include <setjmp.h>
 #endif
 
-#ifdef WIN32
+#ifdef HAVE_PROCESS_H
 #include <process.h>
 #endif
 
-#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
-#undef in_addr_t
-#define in_addr_t unsigned long
-#endif
-
 #include "urldata.h"
 #include "sendf.h"
 #include "hostip.h"
@@ -79,6 +71,7 @@
 #include "share.h"
 #include "strerror.h"
 #include "url.h"
+#include "inet_pton.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -87,7 +80,7 @@
 #include "inet_ntoa_r.h"
 #endif
 
-#include "curl_memory.h"
+#include "memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
 
@@ -95,23 +88,6 @@
  * Only for plain-ipv4 builds
  **********************************************************************/
 #ifdef CURLRES_IPV4 /* plain ipv4 code coming up */
-
-/*
- * This is a function for freeing name information in a protocol independent
- * way.
- */
-void Curl_freeaddrinfo(Curl_addrinfo *ai)
-{
-  Curl_addrinfo *next;
-
-  /* walk over the list and free all entries */
-  while(ai) {
-    next = ai->ai_next;
-    free(ai);
-    ai = next;
-  }
-}
-
 /*
  * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
  * been set and returns TRUE if they are OK.
@@ -125,57 +101,13 @@
   return TRUE; /* OK, proceed */
 }
 
-struct namebuf {
-  struct hostent hostentry;
-  char *h_addr_list[2];
-  struct in_addr addrentry;
-  char h_name[16]; /* 123.123.123.123 = 15 letters is maximum */
-};
-
-/*
- * Curl_ip2addr() takes a 32bit ipv4 internet address as input parameter
- * together with a pointer to the string version of the address, and it
- * returns a Curl_addrinfo chain filled in correctly with information for this
- * address/host.
- *
- * The input parameters ARE NOT checked for validity but they are expected
- * to have been checked already when this is called.
- */
-Curl_addrinfo *Curl_ip2addr(in_addr_t num, char *hostname, int port)
-{
-  Curl_addrinfo *ai;
-  struct hostent *h;
-  struct in_addr *addrentry;
-  struct namebuf buffer;
-  struct namebuf *buf = &buffer;
-
-  h = &buf->hostentry;
-  h->h_addr_list = &buf->h_addr_list[0];
-  addrentry = &buf->addrentry;
-  addrentry->s_addr = num;
-  h->h_addr_list[0] = (char*)addrentry;
-  h->h_addr_list[1] = NULL;
-  h->h_addrtype = AF_INET;
-  h->h_length = sizeof(*addrentry);
-  h->h_name = &buf->h_name[0];
-  h->h_aliases = NULL;
-
-  /* Now store the dotted version of the address */
-  snprintf((char*)(h->h_name), 16, "%s", hostname);
-
-  ai = Curl_he2ai(h, port);
-
-  return ai;
-}
-
 #ifdef CURLRES_SYNCH /* the functions below are for synchronous resolves */
 
 /*
  * Curl_getaddrinfo() - the ipv4 synchronous version.
  *
- * The original code to this function was once stolen from the Dancer source
- * code, written by Bjorn Reese, it has since been patched and modified
- * considerably.
+ * The original code to this function was from the Dancer source code, written
+ * by Bjorn Reese, it has since been patched and modified considerably.
  *
  * gethostbyname_r() is the thread-safe version of the gethostbyname()
  * function. When we build for plain IPv4, we attempt to use this
@@ -188,7 +120,7 @@
  *
  */
 Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
-                                char *hostname,
+                                const char *hostname,
                                 int port,
                                 int *waitp)
 {
@@ -202,11 +134,9 @@
 
   *waitp = 0; /* don't wait, we act synchronously */
 
-  in=inet_addr(hostname);
-  if (in != CURL_INADDR_NONE) {
+  if(1 == Curl_inet_pton(AF_INET, hostname, &in))
     /* This is a dotted IP address 123.123.123.123-style */
     return Curl_ip2addr(in, hostname, port);
-  }
 
 #if defined(HAVE_GETHOSTBYNAME_R)
   /*
@@ -370,55 +300,55 @@
 }
 
 #endif /* CURLRES_SYNCH */
+#endif /* CURLRES_IPV4 */
 
 /*
  * Curl_he2ai() translates from a hostent struct to a Curl_addrinfo struct.
  * The Curl_addrinfo is meant to work like the addrinfo struct does for IPv6
  * stacks, but for all hosts and environments.
+ *
+ *   Curl_addrinfo defined in "lib/hostip.h"
+ *
+ *     struct Curl_addrinfo {
+ *       int                   ai_flags;
+ *       int                   ai_family;
+ *       int                   ai_socktype;
+ *       int                   ai_protocol;
+ *       socklen_t             ai_addrlen;   * Follow rfc3493 struct addrinfo *
+ *       char                 *ai_canonname;
+ *       struct sockaddr      *ai_addr;
+ *       struct Curl_addrinfo *ai_next;
+ *     };
+ *
+ *   hostent defined in <netdb.h>
+ *
+ *     struct hostent {
+ *       char    *h_name;
+ *       char    **h_aliases;
+ *       int     h_addrtype;
+ *       int     h_length;
+ *       char    **h_addr_list;
+ *     };
+ *
+ *   for backward compatibility:
+ *
+ *     #define h_addr  h_addr_list[0]
+ */
 
-struct Curl_addrinfo {
-  int     ai_flags;
-  int     ai_family;
-  int     ai_socktype;
-  int     ai_protocol;
-  size_t  ai_addrlen;
-  struct sockaddr *ai_addr;
-  char   *ai_canonname;
-  struct addrinfo *ai_next;
-};
-
-struct hostent {
-  char    *h_name;        * official name of host *
-  char    **h_aliases;    * alias list *
-  int     h_addrtype;     * host address type *
-  int     h_length;       * length of address *
-  char    **h_addr_list;  * list of addresses *
-}
-#define h_addr  h_addr_list[0]  * for backward compatibility *
-
-*/
-
-Curl_addrinfo *Curl_he2ai(struct hostent *he, int port)
+Curl_addrinfo *Curl_he2ai(const struct hostent *he, int port)
 {
   Curl_addrinfo *ai;
   Curl_addrinfo *prevai = NULL;
   Curl_addrinfo *firstai = NULL;
+  struct sockaddr_in *addr;
   int i;
-
-  union {
-    struct in_addr *addr;
-    char* list;
-  } curr;
-  union {
-    struct sockaddr_in* addr_in;
-    struct sockaddr* addr;
-  } address;
+  struct in_addr *curr;
 
   if(!he)
     /* no input == no output! */
     return NULL;
 
-  for(i=0; (curr.list = he->h_addr_list[i]); i++) {
+  for(i=0; (curr = (struct in_addr *)he->h_addr_list[i]) != NULL; i++) {
 
     ai = calloc(1, sizeof(Curl_addrinfo) + sizeof(struct sockaddr_in));
 
@@ -434,23 +364,26 @@
       prevai->ai_next = ai;
 
     ai->ai_family = AF_INET;              /* we only support this */
-    ai->ai_socktype = SOCK_STREAM;        /* we only support this */
+
+    /* we return all names as STREAM, so when using this address for TFTP
+       the type must be ignored and conn->socktype be used instead! */
+    ai->ai_socktype = SOCK_STREAM;
+
     ai->ai_addrlen = sizeof(struct sockaddr_in);
     /* make the ai_addr point to the address immediately following this struct
        and use that area to store the address */
-    ai->ai_addr = (struct sockaddr *) (ai + 1);
+    ai->ai_addr = (struct sockaddr *) ((char*)ai + sizeof(Curl_addrinfo));
 
     /* leave the rest of the struct filled with zero */
 
-    address.addr = ai->ai_addr; /* storage area for this info */
+    addr = (struct sockaddr_in *)ai->ai_addr; /* storage area for this info */
 
-    memcpy((char *)&(address.addr_in->sin_addr), curr.addr, sizeof(struct in_addr));
-    address.addr_in->sin_family = he->h_addrtype;
-    address.addr_in->sin_port = htons((unsigned short)port);
+    memcpy((char *)&(addr->sin_addr), curr, sizeof(struct in_addr));
+    addr->sin_family = he->h_addrtype;
+    addr->sin_port = htons((unsigned short)port);
 
     prevai = ai;
   }
   return firstai;
 }
 
-#endif /* CURLRES_IPV4 */

Index: urldata.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/urldata.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- urldata.h	24 Jun 2005 13:00:13 -0000	1.1
+++ urldata.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -30,11 +30,12 @@
 #define PORT_FTP 21
 #define PORT_FTPS 990
[...1108 lines suppressed...]
+  struct HandleData reqdata;   /* Request-specific data */
   struct UserDefined set;      /* values set by the libcurl user */
   struct DynamicStatic change; /* possibly modified userdefined data */
 
@@ -952,9 +1327,12 @@
   struct UrlState state;       /* struct for fields used for state info and
                                   other dynamic purposes */
   struct PureInfo info;        /* stats, reports and info data */
-#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
-  ENGINE*  engine;
-#endif /* USE_SSLEAY */
+#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+  iconv_t outbound_cd;         /* for translating to the network encoding */
+  iconv_t inbound_cd;          /* for translating from the network encoding */
+  iconv_t utf8_cd;             /* for translating to UTF8 */
+#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
+  unsigned int magic;          /* set to a CURLEASY_MAGIC_NUMBER */
 };
 
 #define LIBCURL_NAME "libcurl"

Index: telnet.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/telnet.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- telnet.h	24 Jun 2005 13:00:13 -0000	1.1
+++ telnet.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -2,18 +2,18 @@
 #define __TELNET_H
 
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -24,7 +24,7 @@
  * $Id$
  ***************************************************************************/
 #ifndef CURL_DISABLE_TELNET
-CURLcode Curl_telnet(struct connectdata *conn);
-CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode);
+CURLcode Curl_telnet(struct connectdata *conn, bool *done);
+CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode, bool premature);
 #endif
 #endif

Index: memdebug.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/memdebug.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- memdebug.h	24 Jun 2005 13:00:12 -0000	1.1
+++ memdebug.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -2,18 +2,18 @@
 #ifndef _CURL_MEDEBUG_H
 #define _CURL_MEDEBUG_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -31,6 +31,8 @@
 
 #include "setup.h"
 
+#include <curl/curl.h>
+
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -48,24 +50,24 @@
 extern FILE *logfile;
 
 /* memory functions */
-void *curl_domalloc(size_t size, int line, const char *source);
-void *curl_docalloc(size_t elements, size_t size, int line, const char *source);
-void *curl_dorealloc(void *ptr, size_t size, int line, const char *source);
-void curl_dofree(void *ptr, int line, const char *source);
-char *curl_dostrdup(const char *str, int line, const char *source);
-void curl_memdebug(const char *logname);
-void curl_memlimit(long limit);
+CURL_EXTERN void *curl_domalloc(size_t size, int line, const char *source);
+CURL_EXTERN void *curl_docalloc(size_t elements, size_t size, int line, const char *source);
+CURL_EXTERN void *curl_dorealloc(void *ptr, size_t size, int line, const char *source);
+CURL_EXTERN void curl_dofree(void *ptr, int line, const char *source);
+CURL_EXTERN char *curl_dostrdup(const char *str, int line, const char *source);
+CURL_EXTERN void curl_memdebug(const char *logname);
+CURL_EXTERN void curl_memlimit(long limit);
 
 /* file descriptor manipulators */
-int curl_socket(int domain, int type, int protocol, int line , const char *);
-int curl_sclose(int sockfd, int, const char *source);
-int curl_accept(int s, void *addr, void *addrlen,
-                int line, const char *source);
+CURL_EXTERN int curl_socket(int domain, int type, int protocol, int line , const char *);
+CURL_EXTERN int curl_sclose(int sockfd, int, const char *source);
+CURL_EXTERN int curl_accept(int s, void *addr, void *addrlen,
+                            int line, const char *source);
 
 /* FILE functions */
-FILE *curl_fopen(const char *file, const char *mode, int line,
-                 const char *source);
-int curl_fclose(FILE *file, int line, const char *source);
+CURL_EXTERN FILE *curl_fopen(const char *file, const char *mode, int line,
+                             const char *source);
+CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
 
 #ifndef MEMDEBUG_NODEFINES
 
@@ -83,11 +85,26 @@
 #define accept(sock,addr,len)\
  curl_accept(sock,addr,len,__LINE__,__FILE__)
 
+#if defined(getaddrinfo) && defined(__osf__)
+/* OSF/1 and Tru64 have getaddrinfo as a define already, so we cannot define
+   our macro as for other platforms. Instead, we redefine the new name they
+   define getaddrinfo to become! */
+#define ogetaddrinfo(host,serv,hint,res) \
+  curl_dogetaddrinfo(host,serv,hint,res,__LINE__,__FILE__)
+#else
+#undef getaddrinfo
 #define getaddrinfo(host,serv,hint,res) \
   curl_dogetaddrinfo(host,serv,hint,res,__LINE__,__FILE__)
+#endif
+
+#ifdef HAVE_GETNAMEINFO
+#undef getnameinfo
 #define getnameinfo(sa,salen,host,hostlen,serv,servlen,flags) \
   curl_dogetnameinfo(sa,salen,host,hostlen,serv,servlen,flags, __LINE__, \
   __FILE__)
+#endif
+
+#undef freeaddrinfo
 #define freeaddrinfo(data) \
   curl_dofreeaddrinfo(data,__LINE__,__FILE__)
 

Index: strtoofft.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/strtoofft.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- strtoofft.h	24 Jun 2005 13:00:13 -0000	1.1
+++ strtoofft.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,10 +1,10 @@
 #ifndef _CURL_STRTOOFFT_H
 #define _CURL_STRTOOFFT_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
@@ -12,7 +12,7 @@
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -38,7 +38,7 @@
  * not, should try to emulate its functionality.  At any rate, we define
  * 'strtoofft' such that it can be used to work with curl_off_t's regardless.
  */
-#if SIZEOF_CURL_OFF_T > 4
+#if (SIZEOF_CURL_OFF_T > 4) && (SIZEOF_LONG < 8)
 #if HAVE_STRTOLL
 #define curlx_strtoofft strtoll
 #else /* HAVE_STRTOLL */
@@ -53,10 +53,21 @@
 #endif /* MSVC7 or later */
 
 #endif /* HAVE_STRTOLL */
-#else /* SIZEOF_CURL_OFF_T > 4 */
-/* simply use strtol() to get 32bit numbers */
+#else /* (SIZEOF_CURL_OFF_T > 4) && (SIZEOF_LONG < 8) */
+/* simply use strtol() to get numbers, either 32 or 64 bit */
 #define curlx_strtoofft strtol
 #endif
 
+#if defined(_MSC_VER) || defined(__WATCOMC__)
+#define CURL_LLONG_MIN 0x8000000000000000i64
+#define CURL_LLONG_MAX 0x7FFFFFFFFFFFFFFFi64
+#elif defined(HAVE_LL)
+#define CURL_LLONG_MIN 0x8000000000000000LL
+#define CURL_LLONG_MAX 0x7FFFFFFFFFFFFFFFLL
+#else
+#define CURL_LLONG_MIN 0x8000000000000000L
+#define CURL_LLONG_MAX 0x7FFFFFFFFFFFFFFFL
+#endif
+
 #endif
 

Index: telnet.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/telnet.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- telnet.c	24 Jun 2005 13:00:13 -0000	1.1
+++ telnet.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -30,10 +30,12 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <ctype.h>
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
-
-#include <errno.h>
+#endif
 
 #if defined(WIN32)
 #include <time.h>
@@ -43,7 +45,9 @@
 #include <sys/socket.h>
 #endif
 #include <netinet/in.h>
+#ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
+#endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -61,10 +65,6 @@
 #include <sys/param.h>
 #endif
 
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
 
 #endif
 
@@ -73,6 +73,7 @@
 #include "transfer.h"
 #include "sendf.h"
 #include "telnet.h"
+#include "connect.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -81,7 +82,8 @@
 #define  TELCMDS
 
 #include "arpa_telnet.h"
-#include "curl_memory.h"
+#include "memory.h"
+#include "select.h"
 
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -100,7 +102,7 @@
 #define  CURL_SB_EOF(x) (x->subpointer >= x->subend)
 #define  CURL_SB_LEN(x) (x->subend - x->subpointer)
 
-#ifdef WIN32
+#ifdef USE_WINSOCK
 typedef FARPROC WSOCK2_FUNC;
 static CURLcode check_wsock2 ( struct SessionHandle *data );
 #endif
@@ -163,13 +165,13 @@
   struct curl_slist *telnet_vars; /* Environment variables */
 
   /* suboptions */
-  char subbuffer[SUBBUFSIZE];
-  char *subpointer, *subend;      /* buffer for sub-options */
+  unsigned char subbuffer[SUBBUFSIZE];
+  unsigned char *subpointer, *subend;      /* buffer for sub-options */
 
   TelnetReceive telrcv_state;
 };
 
-#ifdef WIN32
+#ifdef USE_WINSOCK
 static CURLcode
 check_wsock2 ( struct SessionHandle *data )
 {
@@ -208,6 +210,7 @@
   return CURLE_OK;
 }
 #endif
+
 static
 CURLcode init_telnet(struct connectdata *conn)
 {
@@ -217,7 +220,7 @@
   if(!tn)
     return CURLE_OUT_OF_MEMORY;
 
-  conn->proto.telnet = (void *)tn; /* make us known */
+  conn->data->reqdata.proto.telnet = (void *)tn; /* make us known */
 
   tn->telrcv_state = CURL_TS_DATA;
 
@@ -236,7 +239,7 @@
 static void negotiate(struct connectdata *conn)
 {
   int i;
-  struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
+  struct TELNET *tn = (struct TELNET *) conn->data->reqdata.proto.telnet;
 
   for(i = 0;i < CURL_NTELOPTS;i++)
   {
@@ -259,9 +262,9 @@
     if (cmd == CURL_IAC)
     {
       if (CURL_TELCMD_OK(option))
-        Curl_infof(data, "%s IAC %s\n", direction, CURL_TELCMD(option));
+        infof(data, "%s IAC %s\n", direction, CURL_TELCMD(option));
       else
-        Curl_infof(data, "%s IAC %d\n", direction, option);
+        infof(data, "%s IAC %d\n", direction, option);
     }
     else
     {
@@ -277,12 +280,12 @@
           opt = NULL;
 
         if(opt)
-          Curl_infof(data, "%s %s %s\n", direction, fmt, opt);
+          infof(data, "%s %s %s\n", direction, fmt, opt);
         else
-          Curl_infof(data, "%s %s %d\n", direction, fmt, option);
+          infof(data, "%s %s %d\n", direction, fmt, option);
       }
       else
-        Curl_infof(data, "%s %d %d\n", direction, cmd, option);
+        infof(data, "%s %d %d\n", direction, cmd, option);
     }
   }
 }
@@ -290,12 +293,19 @@
 static void send_negotiation(struct connectdata *conn, int cmd, int option)
 {
    unsigned char buf[3];
+   ssize_t bytes_written;
+   int err;
+   struct SessionHandle *data = conn->data;
 
    buf[0] = CURL_IAC;
-   buf[1] = cmd;
-   buf[2] = option;
+   buf[1] = (unsigned char)cmd;
+   buf[2] = (unsigned char)option;
 
-   (void)swrite(conn->sock[FIRSTSOCKET], buf, 3);
+   bytes_written = swrite(conn->sock[FIRSTSOCKET], buf, 3);
+   if(bytes_written < 0) {
+     err = Curl_sockerrno();
+     failf(data,"Sending data failed (%d)",err);
+   }
 
    printoption(conn->data, "SENT", cmd, option);
 }
@@ -303,7 +313,7 @@
 static
 void set_remote_option(struct connectdata *conn, int option, int newstate)
 {
-  struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
+  struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
   if(newstate == CURL_YES)
   {
     switch(tn->him[option])
@@ -385,7 +395,7 @@
 static
 void rec_will(struct connectdata *conn, int option)
 {
-  struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
+  struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
   switch(tn->him[option])
   {
     case CURL_NO:
@@ -438,7 +448,7 @@
 static
 void rec_wont(struct connectdata *conn, int option)
 {
-  struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
+  struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
   switch(tn->him[option])
   {
     case CURL_NO:
@@ -483,7 +493,7 @@
 static void
 set_local_option(struct connectdata *conn, int option, int newstate)
 {
-  struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
+  struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
   if(newstate == CURL_YES)
   {
     switch(tn->us[option])
@@ -565,7 +575,7 @@
 static
 void rec_do(struct connectdata *conn, int option)
 {
-  struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
+  struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
   switch(tn->us[option])
   {
     case CURL_NO:
@@ -618,7 +628,7 @@
 static
 void rec_dont(struct connectdata *conn, int option)
 {
-  struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
+  struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
   switch(tn->us[option])
   {
     case CURL_NO:
@@ -672,7 +682,7 @@
   {
     if (direction)
     {
-      Curl_infof(data, "%s IAC SB ", (direction == '<')? "RCVD":"SENT");
+      infof(data, "%s IAC SB ", (direction == '<')? "RCVD":"SENT");
       if (length >= 3)
       {
         int j;
@@ -682,27 +692,27 @@
 
         if (i != CURL_IAC || j != CURL_SE)
         {
-          Curl_infof(data, "(terminated by ");
+          infof(data, "(terminated by ");
           if (CURL_TELOPT_OK(i))
-            Curl_infof(data, "%s ", CURL_TELOPT(i));
+            infof(data, "%s ", CURL_TELOPT(i));
           else if (CURL_TELCMD_OK(i))
-            Curl_infof(data, "%s ", CURL_TELCMD(i));
+            infof(data, "%s ", CURL_TELCMD(i));
           else
-            Curl_infof(data, "%d ", i);
+            infof(data, "%d ", i);
           if (CURL_TELOPT_OK(j))
-            Curl_infof(data, "%s", CURL_TELOPT(j));
+            infof(data, "%s", CURL_TELOPT(j));
           else if (CURL_TELCMD_OK(j))
-            Curl_infof(data, "%s", CURL_TELCMD(j));
+            infof(data, "%s", CURL_TELCMD(j));
           else
-            Curl_infof(data, "%d", j);
-          Curl_infof(data, ", not IAC SE!) ");
+            infof(data, "%d", j);
+          infof(data, ", not IAC SE!) ");
         }
       }
       length -= 2;
     }
     if (length < 1)
     {
-      Curl_infof(data, "(Empty suboption?)");
+      infof(data, "(Empty suboption?)");
       return;
     }
 
@@ -711,28 +721,28 @@
         case CURL_TELOPT_TTYPE:
         case CURL_TELOPT_XDISPLOC:
         case CURL_TELOPT_NEW_ENVIRON:
-          Curl_infof(data, "%s", CURL_TELOPT(pointer[0]));
+          infof(data, "%s", CURL_TELOPT(pointer[0]));
           break;
         default:
-          Curl_infof(data, "%s (unsupported)", CURL_TELOPT(pointer[0]));
+          infof(data, "%s (unsupported)", CURL_TELOPT(pointer[0]));
           break;
       }
     }
     else
-      Curl_infof(data, "%d (unknown)", pointer[i]);
+      infof(data, "%d (unknown)", pointer[i]);
 
     switch(pointer[1]) {
       case CURL_TELQUAL_IS:
-        Curl_infof(data, " IS");
+        infof(data, " IS");
         break;
       case CURL_TELQUAL_SEND:
-        Curl_infof(data, " SEND");
+        infof(data, " SEND");
         break;
       case CURL_TELQUAL_INFO:
-        Curl_infof(data, " INFO/REPLY");
+        infof(data, " INFO/REPLY");
         break;
       case CURL_TELQUAL_NAME:
-        Curl_infof(data, " NAME");
+        infof(data, " NAME");
         break;
     }
 
@@ -740,21 +750,21 @@
       case CURL_TELOPT_TTYPE:
       case CURL_TELOPT_XDISPLOC:
         pointer[length] = 0;
-        Curl_infof(data, " \"%s\"", &pointer[2]);
+        infof(data, " \"%s\"", &pointer[2]);
         break;
       case CURL_TELOPT_NEW_ENVIRON:
         if(pointer[1] == CURL_TELQUAL_IS) {
-          Curl_infof(data, " ");
+          infof(data, " ");
           for(i = 3;i < length;i++) {
             switch(pointer[i]) {
               case CURL_NEW_ENV_VAR:
-                Curl_infof(data, ", ");
+                infof(data, ", ");
                 break;
               case CURL_NEW_ENV_VALUE:
-                Curl_infof(data, " = ");
+                infof(data, " = ");
                 break;
               default:
-                Curl_infof(data, "%c", pointer[i]);
+                infof(data, "%c", pointer[i]);
                 break;
             }
           }
@@ -762,13 +772,13 @@
         break;
       default:
         for (i = 2; i < length; i++)
-          Curl_infof(data, " %.2x", pointer[i]);
+          infof(data, " %.2x", pointer[i]);
         break;
     }
 
     if (direction)
     {
-      Curl_infof(data, "\n");
+      infof(data, "\n");
     }
   }
 }
@@ -780,7 +790,7 @@
   char option_arg[256];
   char *buf;
   struct SessionHandle *data = conn->data;
-  struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
+  struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
 
   /* Add the user name as an environment variable if it
      was given on the command line */
@@ -844,12 +854,14 @@
 {
   struct curl_slist *v;
   unsigned char temp[2048];
+  ssize_t bytes_written;
   size_t len;
   size_t tmplen;
+  int err;
   char varname[128];
   char varval[128];
   struct SessionHandle *data = conn->data;
-  struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
+  struct TELNET *tn = (struct TELNET *)data->reqdata.proto.telnet;
 
   printsub(data, '<', (unsigned char *)tn->subbuffer, CURL_SB_LEN(tn)+2);
   switch (CURL_SB_GET(tn)) {
@@ -858,7 +870,11 @@
       snprintf((char *)temp, sizeof(temp),
                "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_TTYPE,
                CURL_TELQUAL_IS, tn->subopt_ttype, CURL_IAC, CURL_SE);
-      (void)swrite(conn->sock[FIRSTSOCKET], temp, len);
+      bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
+      if(bytes_written < 0) {
+        err = Curl_sockerrno();
+        failf(data,"Sending data failed (%d)",err);
+      }
       printsub(data, '>', &temp[2], len-2);
       break;
     case CURL_TELOPT_XDISPLOC:
@@ -866,7 +882,11 @@
       snprintf((char *)temp, sizeof(temp),
                "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_XDISPLOC,
                CURL_TELQUAL_IS, tn->subopt_xdisploc, CURL_IAC, CURL_SE);
-      (void)swrite(conn->sock[FIRSTSOCKET], temp, len);
+      bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
+      if(bytes_written < 0) {
+        err = Curl_sockerrno();
+        failf(data,"Sending data failed (%d)",err);
+      }
       printsub(data, '>', &temp[2], len-2);
       break;
     case CURL_TELOPT_NEW_ENVIRON:
@@ -889,7 +909,11 @@
       snprintf((char *)&temp[len], sizeof(temp) - len,
                "%c%c", CURL_IAC, CURL_SE);
       len += 2;
-      (void)swrite(conn->sock[FIRSTSOCKET], temp, len);
+      bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
+      if(bytes_written < 0) {
+        err = Curl_sockerrno();
+        failf(data,"Sending data failed (%d)",err);
+      }
       printsub(data, '>', &temp[2], len-2);
       break;
   }
@@ -904,7 +928,7 @@
   unsigned char c;
   int in = 0;
   struct SessionHandle *data = conn->data;
-  struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
+  struct TELNET *tn = (struct TELNET *)data->reqdata.proto.telnet;
 
   while(count--)
   {
@@ -919,7 +943,7 @@
           break;   /* Ignore \0 after CR */
         }
 
-        Curl_client_write(data, CLIENTWRITE_BODY, (char *)&c, 1);
+        Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&c, 1);
         continue;
 
       case CURL_TS_DATA:
@@ -933,7 +957,7 @@
           tn->telrcv_state = CURL_TS_CR;
         }
 
-        Curl_client_write(data, CLIENTWRITE_BODY, (char *)&c, 1);
+        Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&c, 1);
         continue;
 
       case CURL_TS_IAC:
@@ -957,7 +981,7 @@
           tn->telrcv_state = CURL_TS_SB;
           continue;
         case CURL_IAC:
-          Curl_client_write(data, CLIENTWRITE_BODY, (char *)&c, 1);
+          Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&c, 1);
           break;
         case CURL_DM:
         case CURL_NOP:
@@ -1014,18 +1038,15 @@
           if (c != CURL_IAC)
           {
             /*
-             * This is an error.  We only expect to get
-             * "IAC IAC" or "IAC SE".  Several things may
-             * have happend.  An IAC was not doubled, the
-             * IAC SE was left off, or another option got
-             * inserted into the suboption are all possibilities.
-             * If we assume that the IAC was not doubled,
-             * and really the IAC SE was left off, we could
-             * get into an infinate loop here.  So, instead,
-             * we terminate the suboption, and process the
-             * partial suboption if we can.
+             * This is an error.  We only expect to get "IAC IAC" or "IAC SE".
+             * Several things may have happend.  An IAC was not doubled, the
+             * IAC SE was left off, or another option got inserted into the
+             * suboption are all possibilities.  If we assume that the IAC was
+             * not doubled, and really the IAC SE was left off, we could get
+             * into an infinate loop here.  So, instead, we terminate the
+             * suboption, and process the partial suboption if we can.
              */
-            CURL_SB_ACCUM(tn, (unsigned char)CURL_IAC);
+            CURL_SB_ACCUM(tn, CURL_IAC);
             CURL_SB_ACCUM(tn, c);
             tn->subpointer -= 2;
             CURL_SB_TERM(tn);
@@ -1040,8 +1061,8 @@
         }
         else
         {
-          CURL_SB_ACCUM(tn, (unsigned char)CURL_IAC);
-          CURL_SB_ACCUM(tn, (unsigned char)CURL_SE);
+          CURL_SB_ACCUM(tn, CURL_IAC);
+          CURL_SB_ACCUM(tn, CURL_SE);
           tn->subpointer -= 2;
           CURL_SB_TERM(tn);
           suboption(conn);   /* handle sub-option */
@@ -1052,25 +1073,26 @@
   }
 }
 
-CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode status)
+CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode status, bool premature)
 {
-  struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
+  struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
   (void)status; /* unused */
+  (void)premature; /* not used */
 
   curl_slist_free_all(tn->telnet_vars);
 
-  free(conn->proto.telnet);
-  conn->proto.telnet = NULL;
+  free(conn->data->reqdata.proto.telnet);
+  conn->data->reqdata.proto.telnet = NULL;
 
   return CURLE_OK;
 }
 
-CURLcode Curl_telnet(struct connectdata *conn)
+CURLcode Curl_telnet(struct connectdata *conn, bool *done)
 {
   CURLcode code;
   struct SessionHandle *data = conn->data;
   curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
-#ifdef WIN32
+#ifdef USE_WINSOCK
   HMODULE wsock2;
   WSOCK2_FUNC close_event_func;
   WSOCK2_FUNC create_event_func;
@@ -1085,25 +1107,27 @@
   DWORD waitret;
   DWORD readfile_read;
 #else
-  fd_set readfd;
-  fd_set keepfd;
+  int interval_ms;
+  struct pollfd pfd[2];
 #endif
   ssize_t nread;
   bool keepon = TRUE;
   char *buf = data->state.buffer;
   struct TELNET *tn;
 
+  *done = TRUE; /* uncontionally */
+
   code = init_telnet(conn);
   if(code)
     return code;
 
-  tn = (struct TELNET *)conn->proto.telnet;
+  tn = (struct TELNET *)data->reqdata.proto.telnet;
 
   code = check_telnet_options(conn);
   if(code)
     return code;
 
-#ifdef WIN32
+#ifdef USE_WINSOCK
   /*
   ** This functionality only works with WinSock >= 2.0.  So,
   ** make sure have it.
@@ -1131,7 +1155,7 @@
 
   /* And WSACloseEvent */
   close_event_func = GetProcAddress(wsock2,"WSACloseEvent");
-  if (create_event_func == NULL) {
+  if (close_event_func == NULL) {
     failf(data,"failed to find WSACloseEvent function (%d)",
           GetLastError());
     FreeLibrary(wsock2);
@@ -1202,11 +1226,11 @@
     case WAIT_TIMEOUT:
     {
       unsigned char outbuf[2];
-      int out_count;
+      int out_count = 0;
       ssize_t bytes_written;
       char *buffer = buf;
 
-      for(;;) {
+      while(1) {
         if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL, &readfile_read, NULL)) {
           keepon = FALSE;
           break;
@@ -1239,7 +1263,7 @@
     case WAIT_OBJECT_0 + 1:
     {
       unsigned char outbuf[2];
-      int out_count;
+      int out_count = 0;
       ssize_t bytes_written;
       char *buffer = buf;
 
@@ -1300,36 +1324,26 @@
   close_event_func = NULL;
   event_select_func = NULL;
   enum_netevents_func = NULL;
-  (void)create_event_func;
-  (void)close_event_func;
-  (void)event_select_func;
-  (void)enum_netevents_func;
 
   /* We called LoadLibrary, so call FreeLibrary */
   if (!FreeLibrary(wsock2))
     infof(data,"FreeLibrary(wsock2) failed (%d)",GetLastError());
 #else
-  FD_ZERO (&readfd);            /* clear it */
-  FD_SET (sockfd, &readfd);
-  FD_SET (0, &readfd);
-
-  keepfd = readfd;
+  pfd[0].fd = sockfd;
+  pfd[0].events = POLLIN;
+  pfd[1].fd = 0;
+  pfd[1].events = POLLIN;
+  interval_ms = 1 * 1000;
 
   while (keepon) {
-    struct timeval interval;
-
-    readfd = keepfd;            /* set this every lap in the loop */
-    interval.tv_sec = 1;
-    interval.tv_usec = 0;
-
-    switch (select (sockfd + 1, &readfd, NULL, NULL, &interval)) {
+    switch (Curl_poll(pfd, 2, interval_ms)) {
     case -1:                    /* error, stop reading */
       keepon = FALSE;
       continue;
     case 0:                     /* timeout */
       break;
     default:                    /* read! */
-      if(FD_ISSET(0, &readfd)) { /* read from stdin */
+      if(pfd[1].revents & POLLIN) { /* read from stdin */
         unsigned char outbuf[2];
         int out_count = 0;
         ssize_t bytes_written;
@@ -1348,7 +1362,7 @@
         }
       }
 
-      if(FD_ISSET(sockfd, &readfd)) {
+      if(pfd[0].revents & POLLIN) {
         /* This OUGHT to check the return code... */
         (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
 
@@ -1382,7 +1396,7 @@
   }
 #endif
   /* mark this as "no further transfer wanted" */
-  Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+  Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
 
   return code;
 }

Index: memdebug.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/memdebug.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- memdebug.c	24 Jun 2005 13:00:12 -0000	1.1
+++ memdebug.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -6,7 +6,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -42,7 +42,7 @@
 #endif
 
 #define MEMDEBUG_NODEFINES /* don't redefine the standard functions */
-#include "curl_memory.h"
+#include "memory.h"
 #include "memdebug.h"
 
 struct memdebug {
@@ -61,25 +61,29 @@
  */
 
 #define logfile curl_debuglogfile
-FILE *curl_debuglogfile;
-static bool memlimit; /* enable memory limit */
-static long memsize;  /* set number of mallocs allowed */
+FILE *curl_debuglogfile = NULL;
+static bool memlimit = FALSE; /* enable memory limit */
+static long memsize = 0;  /* set number of mallocs allowed */
 
 /* this sets the log file name */
 void curl_memdebug(const char *logname)
 {
-  if(logname)
-    logfile = fopen(logname, "w");
-  else
-    logfile = stderr;
+  if (!logfile) {
+    if(logname)
+      logfile = fopen(logname, "w");
+    else
+      logfile = stderr;
+  }
 }
 
 /* This function sets the number of malloc() calls that should return
    successfully! */
 void curl_memlimit(long limit)
 {
-  memlimit = TRUE;
-  memsize = limit;
+  if (!memlimit) {
+    memlimit = TRUE;
+    memsize = limit;
+  }
 }
 
 /* returns TRUE if this isn't allowed! */
@@ -95,6 +99,7 @@
       if(source)
         fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n",
                 source, line, func);
+      errno = ENOMEM;
       return TRUE; /* RETURN ERROR! */
     }
     else
@@ -200,7 +205,7 @@
 
   mem=(struct memdebug *)(Curl_crealloc)(mem, size);
   if(logfile)
-    fprintf(logfile, "MEM %s:%d realloc(0x%x, %zd) = %p\n",
+    fprintf(logfile, "MEM %s:%d realloc(%p, %zd) = %p\n",
             source, line, ptr, wantedsize, mem?mem->mem:NULL);
 
   if(mem) {

--- NEW FILE: setup_once.h ---
#ifndef __SETUP_ONCE_H
#define __SETUP_ONCE_H
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: setup_once.h,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/


/********************************************************************
 *                              NOTICE                              *
 *                             ========                             *
 *                                                                  *
 *  Content of header files lib/setup_once.h and ares/setup_once.h  *
 *  must be kept in sync. Modify the other one if you change this.  *
 *                                                                  *
 ********************************************************************/


/*
 * If we have the MSG_NOSIGNAL define, make sure we use
 * it as the fourth argument of function send()
 */

#ifdef HAVE_MSG_NOSIGNAL
#define SEND_4TH_ARG MSG_NOSIGNAL
#else
#define SEND_4TH_ARG 0
#endif


/*
 * The definitions for the return type and arguments types
 * of functions recv() and send() belong and come from the
 * configuration file. Do not define them in any other place.
 *
 * HAVE_RECV is defined if you have a function named recv()
 * which is used to read incoming data from sockets. If your
 * function has another name then don't define HAVE_RECV.
 *
 * If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2,
 * RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also
 * be defined.
 *
 * HAVE_SEND is defined if you have a function named send()
 * which is used to write outgoing data on a connected socket.
 * If yours has another name then don't define HAVE_SEND.
 *
 * If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_QUAL_ARG2,
 * SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and
 * SEND_TYPE_RETV must also be defined.
 */

#ifdef HAVE_RECV
#if !defined(RECV_TYPE_ARG1) || \
    !defined(RECV_TYPE_ARG2) || \
    !defined(RECV_TYPE_ARG3) || \
    !defined(RECV_TYPE_ARG4) || \
    !defined(RECV_TYPE_RETV)
  /* */
  Error Missing_definition_of_return_and_arguments_types_of_recv
  /* */
#else
#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
                                   (RECV_TYPE_ARG2)(y), \
                                   (RECV_TYPE_ARG3)(z), \
                                   (RECV_TYPE_ARG4)(0))
#endif
#else /* HAVE_RECV */
#ifndef sread
  /* */
  Error Missing_definition_of_macro_sread
  /* */
#endif
#endif /* HAVE_RECV */

#ifdef HAVE_SEND
#if !defined(SEND_TYPE_ARG1) || \
    !defined(SEND_QUAL_ARG2) || \
    !defined(SEND_TYPE_ARG2) || \
    !defined(SEND_TYPE_ARG3) || \
    !defined(SEND_TYPE_ARG4) || \
    !defined(SEND_TYPE_RETV)
  /* */
  Error Missing_definition_of_return_and_arguments_types_of_send
  /* */
#else
#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \
                                    (SEND_TYPE_ARG2)(y), \
                                    (SEND_TYPE_ARG3)(z), \
                                    (SEND_TYPE_ARG4)(SEND_4TH_ARG))
#endif
#else /* HAVE_SEND */
#ifndef swrite
  /* */
  Error Missing_definition_of_macro_swrite
  /* */
#endif
#endif /* HAVE_SEND */


/*
 * Uppercase macro versions of ANSI/ISO is*() functions/macros which
 * avoid negative number inputs with argument byte codes > 127.
 */

#define ISSPACE(x)  (isspace((int)  ((unsigned char)x)))
#define ISDIGIT(x)  (isdigit((int)  ((unsigned char)x)))
#define ISALNUM(x)  (isalnum((int)  ((unsigned char)x)))
#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
#define ISGRAPH(x)  (isgraph((int)  ((unsigned char)x)))
#define ISALPHA(x)  (isalpha((int)  ((unsigned char)x)))
#define ISPRINT(x)  (isprint((int)  ((unsigned char)x)))


/*
 * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
 */

#ifndef HAVE_SIG_ATOMIC_T
typedef int sig_atomic_t;
#define HAVE_SIG_ATOMIC_T
#endif


/*
 * Default return type for signal handlers.
 */

#ifndef RETSIGTYPE
#define RETSIGTYPE void
#endif


#endif /* __SETUP_ONCE_H */


Index: krb4.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/krb4.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- krb4.c	24 Jun 2005 13:00:12 -0000	1.1
+++ krb4.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,14 +1,13 @@
 /* This source code was modified by Martin Hedenfalk <mhe at stacken.kth.se> for
- * use in Curl. His latest changes were done 2000-09-18.
+ * use in Curl. Martin's latest changes were done 2000-09-18.
  *
- * It has since been patched away like a madman by Daniel Stenberg
- * <daniel at haxx.se> to make it better applied to curl conditions, and to make
- * it not use globals, pollute name space and more. This source code awaits a
- * rewrite to work around the paragraph 2 in the BSD licenses as explained
- * below.
+ * It has since been patched away like a madman by Daniel Stenberg to make it
+ * better applied to curl conditions, and to make it not use globals, pollute
+ * name space and more.
  *
  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
+ * Copyright (c) 2004 - 2007 Daniel Stenberg
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,15 +35,16 @@
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.  */
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
 
 #include "setup.h"
 
 #ifndef CURL_DISABLE_FTP
 #ifdef HAVE_KRB4
 
-#include "security.h"
-#include "base64.h"
 #include <stdlib.h>
 #ifdef HAVE_NETDB_H
 #include <netdb.h>
@@ -57,10 +57,12 @@
 #include <unistd.h> /* for getpid() */
 #endif
 
+#include "urldata.h"
+#include "base64.h"
 #include "ftp.h"
 #include "sendf.h"
 #include "krb4.h"
-#include "curl_memory.h"
+#include "memory.h"
 
 #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
 #include "inet_ntoa_r.h"
@@ -199,7 +201,8 @@
 {
   int ret;
   char *p;
-  int len;
+  unsigned char *ptr;
+  size_t len;
   KTEXT_ST adat;
   MSG_DAT msg_data;
   int checksum;
@@ -220,7 +223,7 @@
   if(ret == KDC_PR_UNKNOWN)
     ret = mk_auth(d, &adat, "rcmd", host, checksum);
   if(ret) {
-    Curl_infof(data, "%s\n", krb_get_err_text(ret));
+    infof(data, "%s\n", krb_get_err_text(ret));
     return AUTH_CONTINUE;
   }
 
@@ -232,7 +235,7 @@
     if (krb_get_our_ip_for_realm(krb_realmofhost(host),
                                  &natAddr) != KSUCCESS
         && krb_get_our_ip_for_realm(NULL, &natAddr) != KSUCCESS)
-      Curl_infof(data, "Can't get address for realm %s\n",
+      infof(data, "Can't get address for realm %s\n",
                  krb_realmofhost(host));
     else {
       if (natAddr.s_addr != localaddr->sin_addr.s_addr) {
@@ -242,14 +245,14 @@
 #else
         char *ip = (char *)inet_ntoa(natAddr);
 #endif
-        Curl_infof(data, "Using NAT IP address (%s) for kerberos 4\n", ip);
+        infof(data, "Using NAT IP address (%s) for kerberos 4\n", ip);
         localaddr->sin_addr = natAddr;
       }
     }
   }
 #endif
 
-  if(Curl_base64_encode((char *)adat.dat, adat.length, &p) < 1) {
+  if(Curl_base64_encode(conn->data, (char *)adat.dat, adat.length, &p) < 1) {
     Curl_failf(data, "Out of memory base64-encoding");
     return AUTH_CONTINUE;
   }
@@ -275,11 +278,17 @@
     return AUTH_ERROR;
   }
   p += 5;
-  len = Curl_base64_decode(p, (char *)adat.dat);
-  if(len < 0) {
+  len = Curl_base64_decode(p, &ptr);
+  if(len > sizeof(adat.dat)-1) {
+    free(ptr);
+    len=0;
+  }
+  if(!len || !ptr) {
     Curl_failf(data, "Failed to decode base64 from server");
     return AUTH_ERROR;
   }
+  memcpy((char *)adat.dat, ptr, len);
+  free(ptr);
   adat.length = len;
   ret = krb_rd_safe(adat.dat, adat.length, &d->key,
                     (struct sockaddr_in *)hisctladdr,
@@ -317,10 +326,11 @@
   char *name;
   char *p;
   char passwd[100];
-  int tmp;
+  size_t tmp;
   ssize_t nread;
   int save;
   CURLcode result;
+  unsigned char *ptr;
 
   save = Curl_set_command_prot(conn, prot_private);
 
@@ -346,12 +356,18 @@
   }
 
   p += 2;
-  tmp = Curl_base64_decode(p, (char *)tkt.dat);
-  if(tmp < 0) {
+  tmp = Curl_base64_decode(p, &ptr);
+  if(tmp >= sizeof(tkt.dat)) {
+    free(ptr);
+    tmp=0;
+  }
+  if(!tmp || !ptr) {
     Curl_failf(conn->data, "Failed to decode base64 in reply.\n");
     Curl_set_command_prot(conn, save);
     return CURLE_FTP_WEIRD_SERVER_REPLY;
   }
+  memcpy((char *)tkt.dat, ptr, tmp);
+  free(ptr);
   tkt.length = tmp;
   tktcopy.length = tkt.length;
 
@@ -384,7 +400,8 @@
   memset(key, 0, sizeof(key));
   memset(schedule, 0, sizeof(schedule));
   memset(passwd, 0, sizeof(passwd));
-  if(Curl_base64_encode((char *)tktcopy.dat, tktcopy.length, &p) < 1) {
+  if(Curl_base64_encode(conn->data, (char *)tktcopy.dat, tktcopy.length, &p)
+     < 1) {
     failf(conn->data, "Out of memory base64-encoding.");
     Curl_set_command_prot(conn, save);
     return CURLE_OUT_OF_MEMORY;

Index: netrc.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/netrc.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- netrc.c	24 Jun 2005 13:00:12 -0000	1.1
+++ netrc.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,16 +1,16 @@
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -45,7 +45,7 @@
 
 #include "strequal.h"
 #include "strtok.h"
-#include "curl_memory.h"
+#include "memory.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -83,7 +83,7 @@
   FILE *file;
   int retcode=1;
   int specific_login = (login[0] != 0);
-  char *home = NULL; 
+  char *home = NULL;
   bool home_alloc = FALSE;
   bool netrc_alloc = FALSE;
   int state=NOTHING;
@@ -103,7 +103,7 @@
     char *override = curl_getenv("CURL_DEBUG_NETRC");
 
     if (override) {
-      printf("NETRC: overridden " NETRC " file: %s\n", home);
+      fprintf(stderr, "NETRC: overridden " NETRC " file: %s\n", override);
       netrcfile = override;
       netrc_alloc = TRUE;
     }
@@ -171,7 +171,7 @@
             /* and yes, this is our host! */
             state=HOSTVALID;
 #ifdef _NETRC_DEBUG
-            printf("HOST: %s\n", tok);
+            fprintf(stderr, "HOST: %s\n", tok);
 #endif
             retcode=0; /* we did find our host */
           }
@@ -188,7 +188,7 @@
             else {
               strncpy(login, tok, LOGINSIZE-1);
 #ifdef _NETRC_DEBUG
-              printf("LOGIN: %s\n", login);
+              fprintf(stderr, "LOGIN: %s\n", login);
 #endif
             }
             state_login=0;
@@ -197,7 +197,7 @@
             if (state_our_login || !specific_login) {
               strncpy(password, tok, PASSWORDSIZE-1);
 #ifdef _NETRC_DEBUG
-              printf("PASSWORD: %s\n", password);
+              fprintf(stderr, "PASSWORD: %s\n", password);
 #endif
             }
             state_password=0;


Index: inet_ntoa_r.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/inet_ntoa_r.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- inet_ntoa_r.h	24 Jun 2005 13:00:12 -0000	1.1
+++ inet_ntoa_r.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,5 +1,38 @@
 #ifndef __INET_NTOA_R_H
 #define __INET_NTOA_R_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id$
+ ***************************************************************************/
+
+#include "setup.h"
+
+#ifdef HAVE_INET_NTOA_R_2_ARGS
+/*
+ * uClibc 0.9.26 (at least) doesn't define this prototype. The buffer
+ * must be at least 16 characters long.
+ */
+char *inet_ntoa_r(const struct in_addr in, char buffer[]);
+
+#else
 /*
  * My solaris 5.6 system running gcc 2.8.1 does *not* have this prototype
  * in any system include file! Isn't that weird?
@@ -7,3 +40,5 @@
 char *inet_ntoa_r(const struct in_addr in, char *buffer, int buflen);
 
 #endif
+
+#endif

--- NEW FILE: socks.h ---
#ifndef __SOCKS_H
#define __SOCKS_H
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: socks.h,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

/*
 * This function logs in to a SOCKS4 proxy and sends the specifics to the
 * final destination server.
 */
CURLcode Curl_SOCKS4(const char *proxy_name,
                     struct connectdata *conn);

/*
 * This function logs in to a SOCKS5 proxy and sends the specifics to the
 * final destination server.
 */
CURLcode Curl_SOCKS5(const char *proxy_name,
                     const char *proxy_password,
                     struct connectdata *conn);

#endif

Index: hostasyn.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/hostasyn.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- hostasyn.c	24 Jun 2005 13:00:12 -0000	1.1
+++ hostasyn.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,13 +24,10 @@
 #include "setup.h"
 
 #include <string.h>
-#include <errno.h>
-
-#define _REENTRANT
 
-#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
+#ifdef NEED_MALLOC_H
 #include <malloc.h>
-#else
+#endif
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -57,21 +54,15 @@
 #include <inet.h>
 #include <stdlib.h>
 #endif
-#endif
 
 #ifdef HAVE_SETJMP_H
 #include <setjmp.h>
 #endif
 
-#ifdef WIN32
+#ifdef HAVE_PROCESS_H
 #include <process.h>
 #endif
 
-#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
-#undef in_addr_t
-#define in_addr_t unsigned long
-#endif
-
 #include "urldata.h"
 #include "sendf.h"
 #include "hostip.h"
@@ -87,7 +78,7 @@
 #include "inet_ntoa_r.h"
 #endif
 
-#include "curl_memory.h"
+#include "memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
 
@@ -108,21 +99,21 @@
  *
  * The storage operation locks and unlocks the DNS cache.
  */
-static void addrinfo_callback(void *arg, /* "struct connectdata *" */
-                              int status,
-                              void *addr)
+static CURLcode addrinfo_callback(void *arg, /* "struct connectdata *" */
+                                  int status,
+                                  void *addr)
 {
   struct connectdata *conn = (struct connectdata *)arg;
   struct Curl_dns_entry *dns = NULL;
+  CURLcode rc = CURLE_OK;
 
-  conn->async.done = TRUE;
   conn->async.status = status;
 
   if(CURL_ASYNC_SUCCESS == status) {
 
     /*
-     * IPv4: Curl_addrinfo_copy() copies the address and returns an allocated
-     * version.
+     * IPv4/ares: Curl_addrinfo_copy() copies the address and returns an
+     * allocated version.
      *
      * IPv6: Curl_addrinfo_copy() returns the input pointer!
      */
@@ -136,34 +127,47 @@
       dns = Curl_cache_addr(data, ai,
                             conn->async.hostname,
                             conn->async.port);
-      if(!dns)
+      if(!dns) {
         /* failed to store, cleanup and return error */
         Curl_freeaddrinfo(ai);
+        rc = CURLE_OUT_OF_MEMORY;
+      }
 
       if(data->share)
         Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
     }
+    else
+      rc = CURLE_OUT_OF_MEMORY;
   }
 
   conn->async.dns = dns;
 
+ /* Set async.done TRUE last in this function since it may be used multi-
+    threaded and once this is TRUE the other thread may read fields from the
+    async struct */
+  conn->async.done = TRUE;
+
   /* ipv4: The input hostent struct will be freed by ares when we return from
      this function */
+  return rc;
 }
 
-void Curl_addrinfo4_callback(void *arg, /* "struct connectdata *" */
-                             int status,
-                             struct hostent *hostent)
+CURLcode Curl_addrinfo4_callback(void *arg, /* "struct connectdata *" */
+                                 int status,
+                                 struct hostent *hostent)
 {
-  addrinfo_callback(arg, status, hostent);
+  return addrinfo_callback(arg, status, hostent);
 }
 
 #ifdef CURLRES_IPV6
-void Curl_addrinfo6_callback(void *arg, /* "struct connectdata *" */
-                             int status,
-                             struct addrinfo *ai)
+CURLcode Curl_addrinfo6_callback(void *arg, /* "struct connectdata *" */
+                                 int status,
+                                 struct addrinfo *ai)
 {
-  addrinfo_callback(arg, status, ai);
+ /* NOTE: for CURLRES_ARES, the 'ai' argument is really a
+  * 'struct hostent' pointer.
+  */
+  return addrinfo_callback(arg, status, ai);
 }
 #endif
 

Index: setup.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/setup.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- setup.h	24 Jun 2005 13:00:12 -0000	1.1
+++ setup.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,5 +1,5 @@
-#ifndef __SETUP_H
-#define __SETUP_H
+#ifndef __LIB_CURL_SETUP_H
+#define __LIB_CURL_SETUP_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,37 +24,104 @@
  ***************************************************************************/
 
 #ifdef HTTP_ONLY
+#define CURL_DISABLE_TFTP
 #define CURL_DISABLE_FTP
 #define CURL_DISABLE_LDAP
 #define CURL_DISABLE_TELNET
 #define CURL_DISABLE_DICT
 #define CURL_DISABLE_FILE
-#define CURL_DISABLE_GOPHER
-#endif
+#endif /* HTTP_ONLY */
 
 #if !defined(WIN32) && defined(__WIN32__)
-/* This should be a good Borland fix. Alexander J. Oss told us! */
+/* Borland fix */
+#define WIN32
+#endif
+
+#if !defined(WIN32) && defined(_WIN32)
+/* VS2005 on x64 fix */
 #define WIN32
 #endif
 
+/*
+ * Include configuration script results or hand-crafted
+ * configuration file for platforms which lack config tool.
+ */
+
 #ifdef HAVE_CONFIG_H
-#include "config.h" /* the configure script results */
+#include "config.h"
+#else
+
+/*
+#ifdef _WIN32_WCE
+#include "config-win32ce.h"
 #else
 #ifdef WIN32
-/* hand-modified win32 config.h! */
 #include "config-win32.h"
 #endif
 #endif
+*/
 
 #ifdef macintosh
-/* hand-modified MacOS config.h! */
 #include "config-mac.h"
 #endif
+
 #ifdef AMIGA
-/* hand-modified AmigaOS config.h! */
 #include "amigaos.h"
 #endif
 
+#ifdef TPF
+#include "config-tpf.h" /* hand-modified TPF config.h */
+/* change which select is used for libcurl */
+#define select(a,b,c,d,e) tpf_select_libcurl(a,b,c,d,e)
+#endif
+
+#endif /* HAVE_CONFIG_H */
+
+/*
+ * Include header files for windows builds before redefining anything.
+ * Use this preproessor block only to include or exclude windows.h,
+ * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
+ * to any other further and independant block.  Under Cygwin things work
+ * just as under linux (e.g. <sys/socket.h>) and the winsock headers should
+ * never be included when __CYGWIN__ is defined.  configure script takes
+ * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
+ * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
+ */
+
+#ifdef HAVE_WINDOWS_H
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#  endif
+#  include <windows.h>
+#  ifdef HAVE_WINSOCK2_H
+#    include <winsock2.h>
+#    ifdef HAVE_WS2TCPIP_H
+#       include <ws2tcpip.h>
+#    endif
+#  else
+#    ifdef HAVE_WINSOCK_H
+#      include <winsock.h>
+#    endif
+#  endif
+#endif
+
+/*
+ * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
+ * define USE_WINSOCK to 1 if we have and use WINSOCK  API, else
+ * undefine USE_WINSOCK.
+ */
+
+#undef USE_WINSOCK
+
+#ifdef HAVE_WINSOCK2_H
+#  define USE_WINSOCK 2
+#else
+#  ifdef HAVE_WINSOCK_H
+#    define USE_WINSOCK 1
+#  endif
+#endif
+
+
 #ifndef TRUE
 #define TRUE 1
 #endif
@@ -62,7 +129,7 @@
 #define FALSE 0
 #endif
 
-#if !defined(__cplusplus) && !defined(__BEOS__)
+#if !defined(__cplusplus) && !defined(__BEOS__) && !defined(__ECOS) && !defined(typedef_bool)
 typedef unsigned char bool;
 #define typedef_bool
 #endif
@@ -74,7 +141,7 @@
 #ifdef _MSC_VER
 #define LONG_LONG __int64
 #define ENABLE_64BIT
-#endif
+#endif /* _MSC_VER */
 #endif /* HAVE_LONGLONG */
 
 #ifndef SIZEOF_CURL_OFF_T
@@ -89,12 +156,13 @@
 #define FORMAT_OFF_T "lld"
 #else
 #define FORMAT_OFF_T "ld"
-#endif
+#endif /* SIZEOF_CURL_OFF_T */
 
-#ifdef NEED_REENTRANT
-/* Solaris machines needs _REENTRANT set for a few function prototypes and
-   things to appear in the #include files. We need to #define it before all
-   #include files */
+#ifndef _REENTRANT
+/* Solaris needs _REENTRANT set for a few function prototypes and things to
+   appear in the #include files. We need to #define it before all #include
+   files. Unixware needs it to build proper reentrant code. Others may also
+   need it. */
 #define _REENTRANT
 #endif
 
@@ -108,25 +176,34 @@
 #include <floss.h>
 #endif
 
-#if defined(HAVE_X509_H) && defined(HAVE_SSL_H) && defined(HAVE_RSA_H) && \
-defined(HAVE_PEM_H) && defined(HAVE_ERR_H) && defined(HAVE_CRYPTO_H) && \
-defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
-  /* the six important includes files all exist and so do both libs,
-     defined SSLeay usage */
-#define USE_SSLEAY 1
+#ifndef STDC_HEADERS /* no standard C headers! */
+#include <curl/stdcheaders.h>
 #endif
-#if defined(HAVE_OPENSSL_X509_H) && defined(HAVE_OPENSSL_SSL_H) && \
-defined(HAVE_OPENSSL_RSA_H) && defined(HAVE_OPENSSL_PEM_H) && \
-defined(HAVE_OPENSSL_ERR_H) && defined(HAVE_OPENSSL_CRYPTO_H) && \
-defined(HAVE_LIBSSL) && defined(HAVE_LIBCRYPTO)
-  /* the six important includes files all exist and so do both libs,
-     defined SSLeay usage */
-#define USE_SSLEAY 1
-#define USE_OPENSSL 1
+
+/*
+ * PellesC cludge section (yikes);
+ *  - It has 'ssize_t', but it is in <unistd.h>. The way the headers
+ *    on Win32 are included, forces me to include this header here.
+ *  - sys_nerr, EINTR is missing in v4.0 or older.
+ */
+#ifdef __POCC__
+  #include <sys/types.h>
+  #include <unistd.h>
+  #if (__POCC__ <= 400)
+  #define sys_nerr EILSEQ  /* for strerror.c */
+  #define EINTR    -1      /* for select.c */
+  #endif
 #endif
 
-#ifndef STDC_HEADERS /* no standard C headers! */
-#include <curl/stdcheaders.h>
+/*
+ * Salford-C cludge section (mostly borrowed from wxWidgets).
+ */
+#ifdef __SALFORDC__
+  #pragma suppress 353             /* Possible nested comments */
+  #pragma suppress 593             /* Define not used */
+  #pragma suppress 61              /* enum has no name */
+  #pragma suppress 106             /* unnamed, unused parameter */
+  #include <clib.h>
 #endif
 
 #if defined(CURLDEBUG) && defined(HAVE_ASSERT_H)
@@ -136,20 +213,22 @@
 #define curlassert(x)
 #endif
 
-#ifdef MSG_NOSIGNAL
-/* If we have the MSG_NOSIGNAL define, we make sure to use that in the forth
-   argument to send() and recv() */
-#define SEND_4TH_ARG MSG_NOSIGNAL
-#define HAVE_MSG_NOSIGNAL 1 /* we have MSG_NOSIGNAL */
+
+/* To make large file support transparent even on Windows */
+#if defined(WIN32) && (SIZEOF_CURL_OFF_T > 4)
+#include <sys/stat.h>   /* must come first before we redefine stat() */
+#include <io.h>
+#define lseek(x,y,z) _lseeki64(x, y, z)
+#define struct_stat struct _stati64
+#define stat(file,st) _stati64(file,st)
+#define fstat(fd,st) _fstati64(fd,st)
 #else
-#define SEND_4TH_ARG 0
-#endif
+#define struct_stat struct stat
+#endif /* Win32 with large file support */
 
 
-/* Below we define four functions. They should
+/* Below we define some functions. They should
    1. close a socket
-   2. read from a socket
-   3. write to a socket
 
    4. set the SIGALRM signal timeout
    5. set dir/file naming defines
@@ -157,49 +236,24 @@
 
 #ifdef WIN32
 
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN  /* Prevent including <winsock*.h> in <windows.h> */
-#endif
-
-#if (defined(ENABLE_IPV6) || defined(CURLDEBUG)) && defined(_MSC_VER) && \
-    (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0500)
-/*
- * Needed to pull in the real getaddrinfo() and not the inline version
- * in <wspiAPI.H> which doesn't support IPv6 (IPv4 only). <wspiAPI.H> is
- * included from <ws2tcpip.h> for <= 0x0500 SDKs.
- */
-#undef  _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-
-#include <winsock2.h>        /* required by telnet.c */
-
-#if defined(ENABLE_IPV6) || defined(USE_SSLEAY)
-#include <ws2tcpip.h>
-#endif
-
-#if !defined(__GNUC__) || defined(__MINGW32__)
+#if !defined(__CYGWIN__)
 #define sclose(x) closesocket(x)
-#define sread(x,y,z) recv(x,y,z, SEND_4TH_ARG)
-#define swrite(x,y,z) (size_t)send(x,y,z, SEND_4TH_ARG)
+
 #undef HAVE_ALARM
 #else
      /* gcc-for-win is still good :) */
 #define sclose(x) close(x)
-#define sread(x,y,z) recv(x,y,z, SEND_4TH_ARG)
-#define swrite(x,y,z) send(x,y,z, SEND_4TH_ARG)
 #define HAVE_ALARM
-#endif
+#endif /* !GNU or mingw */
 
 #define DIR_CHAR      "\\"
 #define DOT_CHAR      "_"
 
-#else
+#else /* WIN32 */
 
-#ifdef DJGPP
+#ifdef MSDOS  /* Watt-32 */
+#include <sys/ioctl.h>
 #define sclose(x)         close_s(x)
-#define sread(x,y,z)      read_s(x,y,z)
-#define swrite(x,y,z)     write_s(x,y,z)
 #define select(n,r,w,x,t) select_s(n,r,w,x,t)
 #define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z))
 #define IOCTL_3_ARGS
@@ -208,21 +262,17 @@
 #undef word
 #endif
 
-#else
+#else /* MSDOS */
 
 #ifdef __BEOS__
 #define sclose(x) closesocket(x)
-#define sread(x,y,z) (ssize_t)recv(x,y,z, SEND_4TH_ARG)
-#define swrite(x,y,z) (ssize_t)send(x,y,z, SEND_4TH_ARG)
-#else
+#else /* __BEOS__ */
 #define sclose(x) close(x)
-#define sread(x,y,z) recv(x,y,z, SEND_4TH_ARG)
-#define swrite(x,y,z) send(x,y,z, SEND_4TH_ARG)
-#endif
+#endif /* __BEOS__ */
 
 #define HAVE_ALARM
 
-#endif
+#endif /* MSDOS */
 
 #ifdef _AMIGASF
 #undef HAVE_ALARM
@@ -231,9 +281,11 @@
 #endif
 
 #define DIR_CHAR      "/"
+#ifndef DOT_CHAR
 #define DOT_CHAR      "."
+#endif
 
-#ifdef DJGPP
+#ifdef MSDOS
 #undef DOT_CHAR
 #define DOT_CHAR      "_"
 #endif
@@ -242,20 +294,7 @@
 int fileno( FILE *stream);
 #endif
 
-#endif
-
-/* now typedef our socket type */
-#ifdef WIN32
-typedef SOCKET curl_socket_t;
-#define CURL_SOCKET_BAD INVALID_SOCKET
-#else
-typedef int curl_socket_t;
-#define CURL_SOCKET_BAD -1
-#endif
-
-#if defined(ENABLE_IPV6) && defined(USE_ARES)
-#error "ares does not yet support IPv6. Disable IPv6 or ares and rebuild"
-#endif
+#endif /* WIN32 */
 
 #if defined(WIN32) && !defined(__CYGWIN__) && !defined(USE_ARES) && \
     !defined(__LCC__)  /* lcc-win32 doesn't have _beginthreadex() */
@@ -266,29 +305,78 @@
 #endif
 #endif
 
-#ifdef mpeix
-#define IOCTL_3_ARGS
+/* "cl -ML" or "cl -MLd" implies a single-threaded runtime library where
+   _beginthreadex() is not available */
+#if (defined(_MSC_VER) && !defined(__POCC__)) && !defined(_MT) && !defined(USE_ARES)
+#undef USE_THREADING_GETADDRINFO
+#undef USE_THREADING_GETHOSTBYNAME
+#define CURL_NO__BEGINTHREADEX
 #endif
 
-#ifndef ECONNRESET
-#ifdef WSAECONNRESET
-#define ECONNRESET WSAECONNRESET
-#else
-/* This will effectively prevent the code from working in this particular
-   aspect, but it still compile fine! */
-#define ECONNRESET 10000
+/*
+ * msvc 6.0 does not have struct sockaddr_storage and
+ * does not define IPPROTO_ESP in winsock2.h. But both
+ * are available if PSDK is properly installed.
+ */
+
+#ifdef _MSC_VER
+#if !defined(HAVE_WINSOCK2_H) || ((_MSC_VER < 1300) && !defined(IPPROTO_ESP))
+#undef HAVE_STRUCT_SOCKADDR_STORAGE
+#endif
 #endif
+
+#ifdef mpeix
+#define IOCTL_3_ARGS
 #endif
 
 #ifdef NETWARE
 #undef HAVE_ALARM
 #endif
 
-#ifdef HAVE_LIBIDN
-/* This could benefit from additional checks that some of the used/important
-   header files are present as well before we define the USE_* define. */
+#if defined(HAVE_LIBIDN) && defined(HAVE_TLD_H)
+/* The lib was present and the tld.h header (which is missing in libidn 0.3.X
+   but we only work with libidn 0.4.1 or later) */
 #define USE_LIBIDN
+#endif
+
+#ifndef SIZEOF_TIME_T
+/* assume default size of time_t to be 32 bit */
+#define SIZEOF_TIME_T 4
+#endif
+
 #define LIBIDN_REQUIRED_VERSION "0.4.1"
+
+#ifdef __UCLIBC__
+#define HAVE_INET_NTOA_R_2_ARGS 1
 #endif
 
-#endif /* __CONFIG_H */
+#if defined(USE_GNUTLS) || defined(USE_SSLEAY)
+#define USE_SSL    /* Either OpenSSL || GnuTLS */
+#endif
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_NTLM)
+#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI)
+#define USE_NTLM
+#endif
+#endif
+
+#ifdef CURLDEBUG
+#define DEBUGF(x) x
+#else
+#define DEBUGF(x)
+#endif
+
+/* non-configure builds may define CURL_WANTS_CA_BUNDLE_ENV */
+#if defined(CURL_WANTS_CA_BUNDLE_ENV) && !defined(CURL_CA_BUNDLE)
+#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")
+#endif
+
+/*
+ * Include macros and defines that should only be processed once.
+ */
+
+#ifndef __SETUP_ONCE_H
+#include "setup_once.h"
+#endif
+
+#endif /* __LIB_CURL_SETUP_H */

--- NEW FILE: multiif.h ---
#ifndef __MULTIIF_H
#define __MULTIIF_H
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: multiif.h,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

/*
 * Prototypes for library-wide functions provided by multi.c
 */
void Curl_expire(struct SessionHandle *data, long milli);

void Curl_multi_rmeasy(void *multi, CURL *data);

bool Curl_multi_canPipeline(struct Curl_multi* multi);

/* the write bits start at bit 16 for the *getsock() bitmap */
#define GETSOCK_WRITEBITSTART 16

#define GETSOCK_BLANK 0 /* no bits set */

/* set the bit for the given sock number to make the bitmap for writable */
#define GETSOCK_WRITESOCK(x) (1 << (GETSOCK_WRITEBITSTART + (x)))

/* set the bit for the given sock number to make the bitmap for readable */
#define GETSOCK_READSOCK(x) (1 << (x))

#endif /* __MULTIIF_H */

Index: curlx.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/curlx.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- curlx.h	24 Jun 2005 13:00:12 -0000	1.1
+++ curlx.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -79,7 +79,19 @@
 #ifdef ENABLE_CURLX_PRINTF
 /* If this define is set, we define all "standard" printf() functions to use
    the curlx_* version instead. It makes the source code transparant and
-   easier to understand/patch. */
+   easier to understand/patch. Undefine them first in case _MPRINTF_REPLACE
+   is set. */
+# undef printf
+# undef fprintf
+# undef sprintf
+# undef snprintf
+# undef vprintf
+# undef vfprintf
+# undef vsprintf
+# undef vsnprintf
+# undef aprintf
+# undef vaprintf
+
 # define printf curlx_mprintf
 # define fprintf curlx_mfprintf
 # define sprintf curlx_msprintf

Index: krb4.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/krb4.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- krb4.h	24 Jun 2005 13:00:12 -0000	1.1
+++ krb4.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,18 +1,18 @@
 #ifndef __KRB4_H
 #define __KRB4_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -22,6 +22,49 @@
  *
  * $Id$
  ***************************************************************************/
+
+struct Curl_sec_client_mech {
+  const char *name;
+  size_t size;
+  int (*init)(void *);
+  int (*auth)(void *, struct connectdata *);
+  void (*end)(void *);
+  int (*check_prot)(void *, int);
+  int (*overhead)(void *, int, int);
+  int (*encode)(void *, void*, int, int, void**, struct connectdata *);
+  int (*decode)(void *, void*, int, int, struct connectdata *);
+};
+
+
+#define AUTH_OK         0
+#define AUTH_CONTINUE   1
+#define AUTH_ERROR      2
+
+extern struct Curl_sec_client_mech Curl_krb4_client_mech;
+
 CURLcode Curl_krb_kauth(struct connectdata *conn);
+int Curl_sec_fflush_fd(struct connectdata *conn, int fd);
+int Curl_sec_fprintf (struct connectdata *, FILE *, const char *, ...);
+int Curl_sec_getc (struct connectdata *conn, FILE *);
+int Curl_sec_putc (struct connectdata *conn, int, FILE *);
+int Curl_sec_read (struct connectdata *conn, int, void *, int);
+int Curl_sec_read_msg (struct connectdata *conn, char *, int);
+
+int Curl_sec_vfprintf(struct connectdata *, FILE *, const char *, va_list);
+int Curl_sec_fprintf2(struct connectdata *conn, FILE *f, const char *fmt, ...);
+int Curl_sec_vfprintf2(struct connectdata *conn, FILE *, const char *, va_list);
+ssize_t Curl_sec_send(struct connectdata *conn, int, char *, int);
+int Curl_sec_write(struct connectdata *conn, int, char *, int);
+
+void Curl_sec_end (struct connectdata *);
+int Curl_sec_login (struct connectdata *);
+void Curl_sec_prot (int, char **);
+int Curl_sec_request_prot (struct connectdata *conn, const char *level);
+void Curl_sec_set_protection_level(struct connectdata *conn);
+void Curl_sec_status (void);
+
+enum protection_level Curl_set_command_prot(struct connectdata *,
+                                            enum protection_level);
+
 
 #endif

--- NEW FILE: gtls.h ---
#ifndef __GTLS_H
#define __GTLS_H
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: gtls.h,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/
int Curl_gtls_init(void);
int Curl_gtls_cleanup(void);
CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex);

/* tell GnuTLS to close down all open information regarding connections (and
   thus session ID caching etc) */
void Curl_gtls_close_all(struct SessionHandle *data);
void Curl_gtls_close(struct connectdata *conn); /* close a SSL connection */

/* return number of sent (non-SSL) bytes */
ssize_t Curl_gtls_send(struct connectdata *conn, int sockindex,
                       void *mem, size_t len);
ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
                       int num,                  /* socketindex */
                       char *buf,                /* store read data here */
                       size_t buffersize,        /* max amount to read */
                       bool *wouldblock);
void Curl_gtls_session_free(void *ptr);
size_t Curl_gtls_version(char *buffer, size_t size);
int Curl_gtls_shutdown(struct connectdata *conn, int sockindex);

#endif

Index: sendf.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/sendf.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- sendf.c	24 Jun 2005 13:00:12 -0000	1.1
+++ sendf.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -43,16 +43,25 @@
 #include <curl/curl.h>
 #include "urldata.h"
 #include "sendf.h"
-#include "connect.h" /* for the Curl_ourerrno() proto */
+#include "connect.h" /* for the Curl_sockerrno() proto */
+#include "sslgen.h"
+#include "ssh.h"
+#include "multiif.h"
 
 #define _MPRINTF_REPLACE /* use the internal *printf() functions */
 #include <curl/mprintf.h>
 
 #ifdef HAVE_KRB4
-#include "security.h"
+#include "krb4.h"
+#else
+#define Curl_sec_send(a,b,c,d) -1
+#define Curl_sec_read(a,b,c,d) -1
 #endif
+
 #include <string.h>
-#include "curl_memory.h"
+#include "memory.h"
+#include "strerror.h"
+#include "easyif.h" /* for the Curl_convert_from_network prototype */
 /* The last #include file should be: */
 #include "memdebug.h"
 
@@ -88,10 +97,10 @@
 
   new_item = (struct curl_slist *) malloc(sizeof(struct curl_slist));
   if (new_item) {
-    char *cuDup = strdup(data);
-    if(cuDup) {
+    char *dup = strdup(data);
+    if(dup) {
       new_item->next = NULL;
-      new_item->data = cuDup;
+      new_item->data = dup;
     }
     else {
       free(new_item);
@@ -132,17 +141,102 @@
   } while (next);
 }
 
+#ifdef CURL_DO_LINEEND_CONV
+/*
+ * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
+ * (\n), with special processing for CRLF sequences that are split between two
+ * blocks of data.  Remaining, bare CRs are changed to LFs.  The possibly new
+ * size of the data is returned.
+ */
+static size_t convert_lineends(struct SessionHandle *data,
+                               char *startPtr, size_t size)
+{
+  char *inPtr, *outPtr;
+
+  /* sanity check */
+  if ((startPtr == NULL) || (size < 1)) {
+    return(size);
+  }
+
+  if (data->state.prev_block_had_trailing_cr == TRUE) {
+    /* The previous block of incoming data
+       had a trailing CR, which was turned into a LF. */
+    if (*startPtr == '\n') {
+      /* This block of incoming data starts with the
+         previous block's LF so get rid of it */
+      memcpy(startPtr, startPtr+1, size-1);
+      size--;
+      /* and it wasn't a bare CR but a CRLF conversion instead */
+      data->state.crlf_conversions++;
+    }
+    data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
+  }
+
+  /* find 1st CR, if any */
+  inPtr = outPtr = memchr(startPtr, '\r', size);
+  if (inPtr) {
+    /* at least one CR, now look for CRLF */
+    while (inPtr < (startPtr+size-1)) {
+      /* note that it's size-1, so we'll never look past the last byte */
+      if (memcmp(inPtr, "\r\n", 2) == 0) {
+        /* CRLF found, bump past the CR and copy the NL */
+        inPtr++;
+        *outPtr = *inPtr;
+        /* keep track of how many CRLFs we converted */
+        data->state.crlf_conversions++;
+      }
+      else {
+        if (*inPtr == '\r') {
+          /* lone CR, move LF instead */
+          *outPtr = '\n';
+        }
+        else {
+          /* not a CRLF nor a CR, just copy whatever it is */
+          *outPtr = *inPtr;
+        }
+      }
+      outPtr++;
+      inPtr++;
+    } /* end of while loop */
+
+    if (inPtr < startPtr+size) {
+      /* handle last byte */
+      if (*inPtr == '\r') {
+        /* deal with a CR at the end of the buffer */
+        *outPtr = '\n'; /* copy a NL instead */
+        /* note that a CRLF might be split across two blocks */
+        data->state.prev_block_had_trailing_cr = TRUE;
+      }
+      else {
+        /* copy last byte */
+        *outPtr = *inPtr;
+      }
+      outPtr++;
+      inPtr++;
+    }
+    if (outPtr < startPtr+size) {
+      /* tidy up by null terminating the now shorter data */
+      *outPtr = '\0';
+    }
+    return(outPtr - startPtr);
+  }
+  return(size);
+}
+#endif /* CURL_DO_LINEEND_CONV */
+
 /* Curl_infof() is for info message along the way */
 
 void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
 {
   if(data && data->set.verbose) {
     va_list ap;
+    size_t len;
     char print_buffer[1024 + 1];
     va_start(ap, fmt);
     vsnprintf(print_buffer, 1024, fmt, ap);
     va_end(ap);
-    Curl_debug(data, CURLINFO_TEXT, print_buffer, strlen(print_buffer), NULL);
+    len = strlen(print_buffer);
+    Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
   }
 }
 
@@ -153,25 +247,24 @@
 void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
 {
   va_list ap;
+  size_t len;
   va_start(ap, fmt);
+
+  vsnprintf(data->state.buffer, BUFSIZE, fmt, ap);
+
   if(data->set.errorbuffer && !data->state.errorbuf) {
-    vsnprintf(data->set.errorbuffer, CURL_ERROR_SIZE, fmt, ap);
+    snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer);
     data->state.errorbuf = TRUE; /* wrote error string */
-
-    if(data->set.verbose) {
-      size_t len = strlen(data->set.errorbuffer);
-      bool doneit=FALSE;
-      if(len < CURL_ERROR_SIZE - 1) {
-        doneit = TRUE;
-        data->set.errorbuffer[len] = '\n';
-        data->set.errorbuffer[++len] = '\0';
-      }
-      Curl_debug(data, CURLINFO_TEXT, data->set.errorbuffer, len, NULL);
-      if(doneit)
-        /* cut off the newline again */
-        data->set.errorbuffer[--len]=0;
+  }
+  if(data->set.verbose) {
+    len = strlen(data->state.buffer);
+    if(len < BUFSIZE - 1) {
+      data->state.buffer[len] = '\n';
+      data->state.buffer[++len] = '\0';
     }
+    Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL);
   }
+
   va_end(ap);
 }
 
@@ -182,7 +275,7 @@
   struct SessionHandle *data = conn->data;
   ssize_t bytes_written;
   size_t write_len;
-  CURLcode res;
+  CURLcode res = CURLE_OK;
   char *s;
   char *sptr;
   va_list ap;
@@ -204,8 +297,7 @@
       break;
 
     if(data->set.verbose)
-      Curl_debug(data, CURLINFO_DATA_OUT, sptr, bytes_written,
-                 conn->host.dispname);
+      Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn);
 
     if((size_t)bytes_written != write_len) {
       /* if not all was written at once, we must advance the pointer, decrease
@@ -222,9 +314,40 @@
   return res;
 }
 
+static ssize_t Curl_plain_send(struct connectdata *conn,
+                               int num,
+                               void *mem,
+                               size_t len)
+{
+  curl_socket_t sockfd = conn->sock[num];
+  ssize_t bytes_written = swrite(sockfd, mem, len);
+
+  if(-1 == bytes_written) {
+    int err = Curl_sockerrno();
+
+    if(
+#ifdef WSAEWOULDBLOCK
+      /* This is how Windows does it */
+      (WSAEWOULDBLOCK == err)
+#else
+      /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
+         due to its inability to send off data without blocking. We therefor
+         treat both error codes the same here */
+      (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
+#endif
+      )
+      /* this is just a case of EWOULDBLOCK */
+      bytes_written=0;
+    else
+      failf(conn->data, "Send failure: %s",
+            Curl_strerror(conn, err));
+  }
+  return bytes_written;
+}
+
 /*
- * Curl_write() is an internal write function that sends plain (binary) data
- * to the server. Works with plain sockets, SSL or kerberos.
+ * Curl_write() is an internal write function that sends data to the
+ * server. Works with plain sockets, SCP, SSL or kerberos.
  */
 CURLcode Curl_write(struct connectdata *conn,
                     curl_socket_t sockfd,
@@ -234,84 +357,22 @@
 {
   ssize_t bytes_written;
   CURLcode retcode;
-
-#ifdef USE_SSLEAY
-  /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
-     If it is the second socket, we set num to 1. Otherwise to 0. This lets
-     us use the correct ssl handle. */
   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
-  /* SSL_write() is said to return 'int' while write() and send() returns
-     'size_t' */
-  if (conn->ssl[num].use) {
-    int err;
-    char error_buffer[120]; /* OpenSSL documents that this must be at least
-                               120 bytes long. */
-    unsigned long sslerror;
-    int rc = SSL_write(conn->ssl[num].handle, mem, (int)len);
-
-    if(rc < 0) {
-      err = SSL_get_error(conn->ssl[num].handle, rc);
 
-      switch(err) {
-      case SSL_ERROR_WANT_READ:
-      case SSL_ERROR_WANT_WRITE:
-        /* The operation did not complete; the same TLS/SSL I/O function
-           should be called again later. This is basicly an EWOULDBLOCK
-           equivalent. */
-        *written = 0;
-        return CURLE_OK;
-      case SSL_ERROR_SYSCALL:
-        failf(conn->data, "SSL_write() returned SYSCALL, errno = %d\n",
-              Curl_ourerrno());
-        return CURLE_SEND_ERROR;
-      case SSL_ERROR_SSL:
-        /*  A failure in the SSL library occurred, usually a protocol error.
-            The OpenSSL error queue contains more information on the error. */
-        sslerror = ERR_get_error();
-        failf(conn->data, "SSL_write() error: %s\n",
-              ERR_error_string(sslerror, error_buffer));
-        return CURLE_SEND_ERROR;
-      }
-      /* a true error */
-      failf(conn->data, "SSL_write() return error %d\n", err);
-      return CURLE_SEND_ERROR;
-    }
-    bytes_written = rc;
-  }
-  else {
-#else
-  (void)conn;
-#endif
-#ifdef HAVE_KRB4
-    if(conn->sec_complete) {
-      bytes_written = Curl_sec_write(conn, sockfd, mem, len);
-    }
-    else
-#endif /* HAVE_KRB4 */
-    {
-      bytes_written = (ssize_t)swrite(sockfd, mem, len);
-    }
-    if(-1 == bytes_written) {
-      int err = Curl_ourerrno();
-
-      if(
-#ifdef WSAEWOULDBLOCK
-        /* This is how Windows does it */
-        (WSAEWOULDBLOCK == err)
-#else
-        /* As pointed out by Christophe Demory on March 11 2003, errno
-           may be EWOULDBLOCK or on some systems EAGAIN when it returned
-           due to its inability to send off data without blocking. We
-           therefor treat both error codes the same here */
-        (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
-#endif
-        )
-        /* this is just a case of EWOULDBLOCK */
-        bytes_written=0;
-    }
-#ifdef USE_SSLEAY
-  }
-#endif
+  if (conn->ssl[num].use)
+    /* only TRUE if SSL enabled */
+    bytes_written = Curl_ssl_send(conn, num, mem, len);
+#ifdef USE_LIBSSH2
+  else if (conn->protocol & PROT_SCP)
+    bytes_written = Curl_scp_send(conn, num, mem, len);
+  else if (conn->protocol & PROT_SFTP)
+    bytes_written = Curl_sftp_send(conn, num, mem, len);
+#endif /* !USE_LIBSSH2 */
+  else if(conn->sec_complete)
+    /* only TRUE if krb4 enabled */
+    bytes_written = Curl_sec_send(conn, num, mem, len);
+  else
+    bytes_written = Curl_plain_send(conn, num, mem, len);
 
   *written = bytes_written;
   retcode = (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
@@ -324,23 +385,53 @@
    The bit pattern defines to what "streams" to write to. Body and/or header.
    The defines are in sendf.h of course.
  */
-CURLcode Curl_client_write(struct SessionHandle *data,
+CURLcode Curl_client_write(struct connectdata *conn,
                            int type,
                            char *ptr,
                            size_t len)
 {
+  struct SessionHandle *data = conn->data;
   size_t wrote;
 
+  if (data->state.cancelled) {
+      /* We just suck everything into a black hole */
+      return CURLE_OK;
+  }
+
   if(0 == len)
     len = strlen(ptr);
 
   if(type & CLIENTWRITE_BODY) {
-    wrote = data->set.fwrite(ptr, 1, len, data->set.out);
+    if((conn->protocol&PROT_FTP) && conn->proto.ftpc.transfertype == 'A') {
+#ifdef CURL_DOES_CONVERSIONS
+      /* convert from the network encoding */
+      size_t rc;
+      rc = Curl_convert_from_network(data, ptr, len);
+      /* Curl_convert_from_network calls failf if unsuccessful */
+      if(rc != CURLE_OK)
+        return rc;
+#endif /* CURL_DOES_CONVERSIONS */
+
+#ifdef CURL_DO_LINEEND_CONV
+      /* convert end-of-line markers */
+      len = convert_lineends(data, ptr, len);
+#endif /* CURL_DO_LINEEND_CONV */
+    }
+    /* If the previous block of data ended with CR and this block of data is
+       just a NL, then the length might be zero */
+    if (len) {
+      wrote = data->set.fwrite(ptr, 1, len, data->set.out);
+    }
+    else {
+      wrote = len;
+    }
+
     if(wrote != len) {
       failf (data, "Failed writing body");
       return CURLE_WRITE_ERROR;
     }
   }
+
   if((type & CLIENTWRITE_HEADER) &&
      (data->set.fwrite_header || data->set.writeheader) ) {
     /*
@@ -350,6 +441,9 @@
     curl_write_callback writeit=
       data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite;
 
+    /* Note: The header is in the host encoding
+       regardless of the ftp transfer mode (ASCII/Image) */
+
     wrote = writeit(ptr, 1, len, data->set.writeheader);
     if(wrote != len) {
       failf (data, "Failed writing header");
@@ -360,6 +454,10 @@
   return CURLE_OK;
 }
 
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
 /*
  * Internal read-from-socket function. This is meant to deal with plain
  * sockets, SSL sockets and kerberos sockets.
@@ -370,11 +468,15 @@
 int Curl_read(struct connectdata *conn, /* connection data */
               curl_socket_t sockfd,     /* read from this socket */
               char *buf,                /* store read data here */
-              size_t buffersize,        /* max amount to read */
+              size_t sizerequested,     /* max amount to read */
               ssize_t *n)               /* amount bytes read */
 {
   ssize_t nread;
-#ifdef USE_SSLEAY
+  size_t bytesfromsocket = 0;
+  char *buffertofill = NULL;
+  bool pipelining = (bool)(conn->data->multi &&
+                     Curl_multi_canPipeline(conn->data->multi));
+
   /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
      If it is the second socket, we set num to 1. Otherwise to 0. This lets
      us use the correct ssl handle. */
@@ -382,61 +484,75 @@
 
   *n=0; /* reset amount to zero */
 
-  if (conn->ssl[num].use) {
-    nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, (int)buffersize);
+  /* If session can pipeline, check connection buffer  */
+  if(pipelining) {
+    size_t bytestocopy = MIN(conn->buf_len - conn->read_pos, sizerequested);
 
-    if(nread < 0) {
-      /* failed SSL_read */
-      int err = SSL_get_error(conn->ssl[num].handle, (int)nread);
+    /* Copy from our master buffer first if we have some unread data there*/
+    if (bytestocopy > 0) {
+      memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
+      conn->read_pos += bytestocopy;
+      conn->bits.stream_was_rewound = FALSE;
 
-      switch(err) {
-      case SSL_ERROR_NONE: /* this is not an error */
-      case SSL_ERROR_ZERO_RETURN: /* no more data */
-        break;
-      case SSL_ERROR_WANT_READ:
-      case SSL_ERROR_WANT_WRITE:
-        /* there's data pending, re-invoke SSL_read() */
-        return -1; /* basicly EWOULDBLOCK */
-      default:
-        /* openssl/ssl.h says "look at error stack/return value/errno" */
-        {
-          char error_buffer[120]; /* OpenSSL documents that this must be at
-                                     least 120 bytes long. */
-          unsigned long sslerror = ERR_get_error();
-          failf(conn->data, "SSL read: %s, errno %d",
-                ERR_error_string(sslerror, error_buffer),
-                Curl_ourerrno() );
-        }
-        return CURLE_RECV_ERROR;
-      }
+      *n = (ssize_t)bytestocopy;
+      return CURLE_OK;
     }
+    /* If we come here, it means that there is no data to read from the buffer,
+     * so we read from the socket */
+    bytesfromsocket = MIN(sizerequested, sizeof(conn->master_buffer));
+    buffertofill = conn->master_buffer;
   }
   else {
-#else
-    (void)conn;
-#endif
-    *n=0; /* reset amount to zero */
-#ifdef HAVE_KRB4
+    bytesfromsocket = MIN((long)sizerequested, conn->data->set.buffer_size ?
+                          conn->data->set.buffer_size : BUFSIZE);
+    buffertofill = buf;
+  }
+
+  if(conn->ssl[num].use) {
+    nread = Curl_ssl_recv(conn, num, buffertofill, bytesfromsocket);
+
+    if(nread == -1) {
+      return -1; /* -1 from Curl_ssl_recv() means EWOULDBLOCK */
+    }
+  }
+#ifdef USE_LIBSSH2
+  else if (conn->protocol & PROT_SCP) {
+    nread = Curl_scp_recv(conn, num, buffertofill, bytesfromsocket);
+    /* TODO: return CURLE_OK also for nread <= 0
+             read failures and timeouts ? */
+  }
+  else if (conn->protocol & PROT_SFTP) {
+    nread = Curl_sftp_recv(conn, num, buffertofill, bytesfromsocket);
+  }
+#endif /* !USE_LIBSSH2 */
+  else {
     if(conn->sec_complete)
-      nread = Curl_sec_read(conn, sockfd, buf, buffersize);
+      nread = Curl_sec_read(conn, sockfd, buffertofill,
+                            bytesfromsocket);
     else
-#endif
-      nread = sread(sockfd, buf, buffersize);
+      nread = sread(sockfd, buffertofill, bytesfromsocket);
 
     if(-1 == nread) {
-      int err = Curl_ourerrno();
-#ifdef WIN32
+      int err = Curl_sockerrno();
+#ifdef USE_WINSOCK
       if(WSAEWOULDBLOCK == err)
 #else
       if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err))
 #endif
         return -1;
     }
+  }
 
-#ifdef USE_SSLEAY
+  if (nread >= 0) {
+    if(pipelining) {
+      memcpy(buf, conn->master_buffer, nread);
+      conn->buf_len = nread;
+      conn->read_pos = nread;
+    }
+
+    *n += nread;
   }
-#endif /* USE_SSLEAY */
-  *n = nread;
+
   return CURLE_OK;
 }
 
@@ -447,6 +563,46 @@
   static const char * const s_infotype[CURLINFO_END] = {
     "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
 
+#ifdef CURL_DOES_CONVERSIONS
+  char buf[BUFSIZE+1];
+  size_t conv_size = 0;
+
+  switch(type) {
+  case CURLINFO_HEADER_OUT:
+    /* assume output headers are ASCII */
+    /* copy the data into my buffer so the original is unchanged */
+    if (size > BUFSIZE) {
+      size = BUFSIZE; /* truncate if necessary */
+      buf[BUFSIZE] = '\0';
+    }
+    conv_size = size;
+    memcpy(buf, ptr, size);
+    /* Special processing is needed for this block if it
+     * contains both headers and data (separated by CRLFCRLF).
+     * We want to convert just the headers, leaving the data as-is.
+     */
+    if(size > 4) {
+      size_t i;
+      for(i = 0; i < size-4; i++) {
+        if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
+          /* convert everthing through this CRLFCRLF but no further */
+          conv_size = i + 4;
+          break;
+        }
+      }
+    }
+
+    Curl_convert_from_network(data, buf, conv_size);
+    /* Curl_convert_from_network calls failf if unsuccessful */
+    /* we might as well continue even if it fails...   */
+    ptr = buf; /* switch pointer to use my buffer instead */
+    break;
+  default:
+    /* leave everything else as-is */
+    break;
+  }
+#endif /* CURL_DOES_CONVERSIONS */
+
   if(data->set.fdebug)
     return (*data->set.fdebug)(data, type, ptr, size,
                                data->set.debugdata);
@@ -457,6 +613,12 @@
   case CURLINFO_HEADER_IN:
     fwrite(s_infotype[type], 2, 1, data->set.err);
     fwrite(ptr, size, 1, data->set.err);
+#ifdef CURL_DOES_CONVERSIONS
+    if(size != conv_size) {
+      /* we had untranslated data so we need an explicit newline */
+      fwrite("\n", 1, 1, data->set.err);
+    }
+#endif
     break;
   default: /* nada */
     break;
@@ -465,18 +627,22 @@
 }
 
 int Curl_debug(struct SessionHandle *data, curl_infotype type,
-               char *ptr, size_t size, char *host)
+               char *ptr, size_t size,
+               struct connectdata *conn)
 {
   int rc;
-  if(data->set.printhost && host) {
+  if(data->set.printhost && conn && conn->host.dispname) {
     char buffer[160];
     const char *t=NULL;
+    const char *w="Data";
     switch (type) {
     case CURLINFO_HEADER_IN:
+      w = "Header";
     case CURLINFO_DATA_IN:
       t = "from";
       break;
     case CURLINFO_HEADER_OUT:
+      w = "Header";
     case CURLINFO_DATA_OUT:
       t = "to";
       break;
@@ -485,7 +651,8 @@
     }
 
     if(t) {
-      snprintf(buffer, sizeof(buffer), "[Data %s %s]", t, host);
+      snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
+               conn->host.dispname);
       rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
       if(rc)
         return rc;

--- NEW FILE: memory.h ---
#ifndef _CURL_MEMORY_H
#define _CURL_MEMORY_H
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: memory.h,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

#include <curl/curl.h> /* for the typedefs */

extern curl_malloc_callback Curl_cmalloc;
extern curl_free_callback Curl_cfree;
extern curl_realloc_callback Curl_crealloc;
extern curl_strdup_callback Curl_cstrdup;
extern curl_calloc_callback Curl_ccalloc;

#ifndef CURLDEBUG
/* Only do this define-mania if we're not using the memdebug system, as that
   has preference on this magic. */
#undef strdup
#define strdup(ptr) Curl_cstrdup(ptr)
#undef malloc
#define malloc(size) Curl_cmalloc(size)
#undef calloc
#define calloc(nbelem,size) Curl_ccalloc(nbelem, size)
#undef realloc
#define realloc(ptr,size) Curl_crealloc(ptr, size)
#undef free
#define free(ptr) Curl_cfree(ptr)

#endif

#endif /* _CURL_MEMORY_H */

--- NEW FILE: gtls.c ---
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: gtls.c,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

/*
 * Source file for all GnuTLS-specific code for the TLS/SSL layer. No code
 * but sslgen.c should ever call or use these functions.
 *
 * Note: don't use the GnuTLS' *_t variable type names in this source code,
 * since they were not present in 1.0.X.
 */

#include "setup.h"
#ifdef USE_GNUTLS
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>

#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif

#include "urldata.h"
#include "sendf.h"
#include "gtls.h"
#include "sslgen.h"
#include "parsedate.h"
#include "connect.h" /* for the connect timeout */
#include "select.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "memory.h"
/* The last #include file should be: */
#include "memdebug.h"

/* Enable GnuTLS debugging by defining GTLSDEBUG */
/*#define GTLSDEBUG */

#ifdef GTLSDEBUG
static void tls_log_func(int level, const char *str)
{
    fprintf(stderr, "|<%d>| %s", level, str);
}
#endif

/*
 * Custom push and pull callback functions used by GNU TLS to read and write
 * to the socket.  These functions are simple wrappers to send() and recv()
 * (although here using the sread/swrite macros as defined by setup_once.h).
 * We use custom functions rather than the GNU TLS defaults because it allows
 * us to get specific about the fourth "flags" argument, and to use arbitrary
 * private data with gnutls_transport_set_ptr if we wish.
 */
static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)
{
  return swrite(s, buf, len);
}

static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len)
{
  return sread(s, buf, len);
}

/* Global GnuTLS init, called from Curl_ssl_init() */
int Curl_gtls_init(void)
{
  gnutls_global_init();
#ifdef GTLSDEBUG
  gnutls_global_set_log_function(tls_log_func);
  gnutls_global_set_log_level(2);
#endif
  return 1;
}

int Curl_gtls_cleanup(void)
{
  gnutls_global_deinit();
  return 1;
}

static void showtime(struct SessionHandle *data,
                     const char *text,
                     time_t stamp)
{
  struct tm *tm;
#ifdef HAVE_GMTIME_R
  struct tm buffer;
  tm = (struct tm *)gmtime_r(&stamp, &buffer);
#else
  tm = gmtime(&stamp);
#endif
  snprintf(data->state.buffer,
           BUFSIZE,
           "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT\n",
           text,
           Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
           tm->tm_mday,
           Curl_month[tm->tm_mon],
           tm->tm_year + 1900,
           tm->tm_hour,
           tm->tm_min,
           tm->tm_sec);
  infof(data, "%s", data->state.buffer);
}

/* this function does a BLOCKING SSL/TLS (re-)handshake */
static CURLcode handshake(struct connectdata *conn,
                          gnutls_session session,
                          int sockindex,
                          bool duringconnect)
{
  struct SessionHandle *data = conn->data;
  int rc;

  do {
    rc = gnutls_handshake(session);

    if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) {
      long timeout_ms = DEFAULT_CONNECT_TIMEOUT;
      long has_passed;

      if(duringconnect && data->set.connecttimeout)
        timeout_ms = data->set.connecttimeout*1000;

      if(data->set.timeout) {
        /* get the strictest timeout of the ones converted to milliseconds */
        if((data->set.timeout*1000) < timeout_ms)
          timeout_ms = data->set.timeout*1000;
      }

      /* Evaluate in milliseconds how much time that has passed */
      has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);

      /* subtract the passed time */
      timeout_ms -= has_passed;

      if(timeout_ms < 0) {
        /* a precaution, no need to continue if time already is up */
        failf(data, "SSL connection timeout");
        return CURLE_OPERATION_TIMEOUTED;
      }

      rc = Curl_select(conn->sock[sockindex],
                       conn->sock[sockindex], (int)timeout_ms);
      if(rc > 0)
        /* reabable or writable, go loop*/
        continue;
      else if(0 == rc) {
        /* timeout */
        failf(data, "SSL connection timeout");
        return CURLE_OPERATION_TIMEDOUT;
      }
      else {
        /* anything that gets here is fatally bad */
        failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
        return CURLE_SSL_CONNECT_ERROR;
      }
    }
    else
      break;
  } while(1);

  if (rc < 0) {
    failf(data, "gnutls_handshake() failed: %s", gnutls_strerror(rc));
    return CURLE_SSL_CONNECT_ERROR;
  }

  return CURLE_OK;
}

static gnutls_x509_crt_fmt do_file_type(const char *type)
{
  if(!type || !type[0])
    return GNUTLS_X509_FMT_PEM;
  if(curl_strequal(type, "PEM"))
    return GNUTLS_X509_FMT_PEM;
  if(curl_strequal(type, "DER"))
    return GNUTLS_X509_FMT_DER;
  return -1;
}


/*
 * This function is called after the TCP connect has completed. Setup the TLS
 * layer and do all necessary magic.
 */
CURLcode
Curl_gtls_connect(struct connectdata *conn,
                  int sockindex)

{
  const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
  struct SessionHandle *data = conn->data;
  gnutls_session session;
  int rc;
  unsigned int cert_list_size;
  const gnutls_datum *chainp;
  unsigned int verify_status;
  gnutls_x509_crt x509_cert;
  char certbuf[256]; /* big enough? */
  size_t size;
  unsigned int algo;
  unsigned int bits;
  time_t clock;
  const char *ptr;
  void *ssl_sessionid;
  size_t ssl_idsize;

  /* GnuTLS only supports TLSv1 (and SSLv3?) */
  if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
    failf(data, "GnuTLS does not support SSLv2");
    return CURLE_SSL_CONNECT_ERROR;
  }

  /* allocate a cred struct */
  rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred);
  if(rc < 0) {
    failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
    return CURLE_SSL_CONNECT_ERROR;
  }

  if(data->set.ssl.CAfile) {
    /* set the trusted CA cert bundle file */
    gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
                                        GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);

    rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
                                                data->set.ssl.CAfile,
                                                GNUTLS_X509_FMT_PEM);
    if(rc < 0) {
      infof(data, "error reading ca cert file %s (%s)\n",
            data->set.ssl.CAfile, gnutls_strerror(rc));
      if (data->set.ssl.verifypeer)
        return CURLE_SSL_CACERT_BADFILE;
    }
    else
      infof(data, "found %d certificates in %s\n",
            rc, data->set.ssl.CAfile);
  }

  /* Initialize TLS session as a client */
  rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
  if(rc) {
    failf(data, "gnutls_init() failed: %d", rc);
    return CURLE_SSL_CONNECT_ERROR;
  }

  /* convenient assign */
  session = conn->ssl[sockindex].session;

  /* Use default priorities */
  rc = gnutls_set_default_priority(session);
  if(rc < 0)
    return CURLE_SSL_CONNECT_ERROR;

  /* Sets the priority on the certificate types supported by gnutls. Priority
     is higher for types specified before others. After specifying the types
     you want, you must append a 0. */
  rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
  if(rc < 0)
    return CURLE_SSL_CONNECT_ERROR;

  if(data->set.cert) {
    if( gnutls_certificate_set_x509_key_file(
          conn->ssl[sockindex].cred, data->set.cert,
          data->set.key != 0 ? data->set.key : data->set.cert,
          do_file_type(data->set.cert_type) ) ) {
      failf(data, "error reading X.509 key or certificate file");
      return CURLE_SSL_CONNECT_ERROR;
    }
  }

  /* put the credentials to the current session */
  rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
                              conn->ssl[sockindex].cred);

  /* set the connection handle (file descriptor for the socket) */
  gnutls_transport_set_ptr(session,
                           (gnutls_transport_ptr)conn->sock[sockindex]);

  /* register callback functions to send and receive data. */
  gnutls_transport_set_push_function(session, Curl_gtls_push);
  gnutls_transport_set_pull_function(session, Curl_gtls_pull);

  /* lowat must be set to zero when using custom push and pull functions. */
  gnutls_transport_set_lowat(session, 0);

  /* This might be a reconnect, so we check for a session ID in the cache
     to speed up things */

  if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) {
    /* we got a session id, use it! */
    gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);

    /* Informational message */
    infof (data, "SSL re-using session ID\n");
  }

  rc = handshake(conn, session, sockindex, TRUE);
  if(rc)
    /* handshake() sets its own error message with failf() */
    return rc;

  /* This function will return the peer's raw certificate (chain) as sent by
     the peer. These certificates are in raw format (DER encoded for
     X.509). In case of a X.509 then a certificate list may be present. The
     first certificate in the list is the peer's certificate, following the
     issuer's certificate, then the issuer's issuer etc. */

  chainp = gnutls_certificate_get_peers(session, &cert_list_size);
  if(!chainp) {
    if(data->set.ssl.verifyhost) {
      failf(data, "failed to get server cert");
      return CURLE_SSL_PEER_CERTIFICATE;
    }
    infof(data, "\t common name: WARNING couldn't obtain\n");
  }

  /* This function will try to verify the peer's certificate and return its
     status (trusted, invalid etc.). The value of status should be one or more
     of the gnutls_certificate_status_t enumerated elements bitwise or'd. To
     avoid denial of service attacks some default upper limits regarding the
     certificate key size and chain size are set. To override them use
     gnutls_certificate_set_verify_limits(). */

  rc = gnutls_certificate_verify_peers2(session, &verify_status);
  if (rc < 0) {
    failf(data, "server cert verify failed: %d", rc);
    return CURLE_SSL_CONNECT_ERROR;
  }

  /* verify_status is a bitmask of gnutls_certificate_status bits */
  if(verify_status & GNUTLS_CERT_INVALID) {
    if (data->set.ssl.verifypeer) {
      failf(data, "server certificate verification failed. CAfile: %s",
            data->set.ssl.CAfile?data->set.ssl.CAfile:"none");
      return CURLE_SSL_CACERT;
    }
    else
      infof(data, "\t server certificate verification FAILED\n");
  }
  else
      infof(data, "\t server certificate verification OK\n");

  /* initialize an X.509 certificate structure. */
  gnutls_x509_crt_init(&x509_cert);

  /* convert the given DER or PEM encoded Certificate to the native
     gnutls_x509_crt_t format */
  gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);

  size=sizeof(certbuf);
  rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
                                     0, /* the first and only one */
                                     FALSE,
                                     certbuf,
                                     &size);
  if(rc) {
    infof(data, "error fetching CN from cert:%s\n",
          gnutls_strerror(rc));
  }

  /* This function will check if the given certificate's subject matches the
     given hostname. This is a basic implementation of the matching described
     in RFC2818 (HTTPS), which takes into account wildcards, and the subject
     alternative name PKIX extension. Returns non zero on success, and zero on
     failure. */
  rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);

  if(!rc) {
    if (data->set.ssl.verifyhost > 1) {
      failf(data, "SSL: certificate subject name (%s) does not match "
            "target host name '%s'", certbuf, conn->host.dispname);
      gnutls_x509_crt_deinit(x509_cert);
      return CURLE_SSL_PEER_CERTIFICATE;
    }
    else
      infof(data, "\t common name: %s (does not match '%s')\n",
            certbuf, conn->host.dispname);
  }
  else
    infof(data, "\t common name: %s (matched)\n", certbuf);

  /* Show:

  - ciphers used
  - subject
  - start date
  - expire date
  - common name
  - issuer

  */

  /* public key algorithm's parameters */
  algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
  infof(data, "\t certificate public key: %s\n",
        gnutls_pk_algorithm_get_name(algo));

  /* version of the X.509 certificate. */
  infof(data, "\t certificate version: #%d\n",
        gnutls_x509_crt_get_version(x509_cert));


  size = sizeof(certbuf);
  gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
  infof(data, "\t subject: %s\n", certbuf);

  clock = gnutls_x509_crt_get_activation_time(x509_cert);
  showtime(data, "start date", clock);

  clock = gnutls_x509_crt_get_expiration_time(x509_cert);
  showtime(data, "expire date", clock);

  size = sizeof(certbuf);
  gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
  infof(data, "\t issuer: %s\n", certbuf);

  gnutls_x509_crt_deinit(x509_cert);

  /* compression algorithm (if any) */
  ptr = gnutls_compression_get_name(gnutls_compression_get(session));
  /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
  infof(data, "\t compression: %s\n", ptr);

  /* the name of the cipher used. ie 3DES. */
  ptr = gnutls_cipher_get_name(gnutls_cipher_get(session));
  infof(data, "\t cipher: %s\n", ptr);

  /* the MAC algorithms name. ie SHA1 */
  ptr = gnutls_mac_get_name(gnutls_mac_get(session));
  infof(data, "\t MAC: %s\n", ptr);

  if(!ssl_sessionid) {
    /* this session was not previously in the cache, add it now */

    /* get the session ID data size */
    gnutls_session_get_data(session, NULL, &ssl_idsize);
    ssl_sessionid = malloc(ssl_idsize); /* get a buffer for it */

    if(ssl_sessionid) {
      /* extract session ID to the allocated buffer */
      gnutls_session_get_data(session, ssl_sessionid, &ssl_idsize);

      /* store this session id */
      return Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_idsize);
    }
  }

  return CURLE_OK;
}


/* return number of sent (non-SSL) bytes */
ssize_t Curl_gtls_send(struct connectdata *conn,
                   int sockindex,
                   void *mem,
                   size_t len)
{
  ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);

  if(rc < 0 ) {
    if(rc == GNUTLS_E_AGAIN)
      return 0; /* EWOULDBLOCK equivalent */
    rc = -1; /* generic error code for send failure */
  }

  return rc;
}

void Curl_gtls_close_all(struct SessionHandle *data)
{
  /* FIX: make the OpenSSL code more generic and use parts of it here */
  (void)data;
}

static void close_one(struct connectdata *conn,
                      int index)
{
  if(conn->ssl[index].session) {
    gnutls_bye(conn->ssl[index].session, GNUTLS_SHUT_RDWR);
    gnutls_deinit(conn->ssl[index].session);
  }
  gnutls_certificate_free_credentials(conn->ssl[index].cred);
}

void Curl_gtls_close(struct connectdata *conn)
{
  if(conn->ssl[0].use)
    close_one(conn, 0);
  if(conn->ssl[1].use)
    close_one(conn, 1);
}

/*
 * This function is called to shut down the SSL layer but keep the
 * socket open (CCC - Clear Command Channel)
 */
int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
{
  int result;
  int retval = 0;
  struct SessionHandle *data = conn->data;
  int done = 0;
  ssize_t nread;
  char buf[120];

  /* This has only been tested on the proftpd server, and the mod_tls code
     sends a close notify alert without waiting for a close notify alert in
     response. Thus we wait for a close notify alert from the server, but
     we do not send one. Let's hope other servers do the same... */

  if(conn->ssl[sockindex].session) {
    while(!done) {
      int what = Curl_select(conn->sock[sockindex],
                             CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
      if(what > 0) {
        /* Something to read, let's do it and hope that it is the close
           notify alert from the server */
        result = gnutls_record_recv(conn->ssl[sockindex].session,
                                    buf, sizeof(buf));
        switch(result) {
        case 0:
          /* This is the expected response. There was no data but only
             the close notify alert */
          done = 1;
          break;
        case GNUTLS_E_AGAIN:
        case GNUTLS_E_INTERRUPTED:
          infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n");
          break;
        default:
          retval = -1;
          done = 1;
          break;
        }
      }
      else if(0 == what) {
        /* timeout */
        failf(data, "SSL shutdown timeout");
        done = 1;
        break;
      }
      else {
        /* anything that gets here is fatally bad */
        failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
        retval = -1;
        done = 1;
      }
    }
    gnutls_deinit(conn->ssl[sockindex].session);
  }
  gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);

  conn->ssl[sockindex].session = NULL;
  conn->ssl[sockindex].use = FALSE;

  return retval;
}

/*
 * If the read would block we return -1 and set 'wouldblock' to TRUE.
 * Otherwise we return the amount of data read. Other errors should return -1
 * and set 'wouldblock' to FALSE.
 */
ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
                       int num,                  /* socketindex */
                       char *buf,                /* store read data here */
                       size_t buffersize,        /* max amount to read */
                       bool *wouldblock)
{
  ssize_t ret;

  ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize);
  if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
    *wouldblock = TRUE;
    return -1;
  }

  if(ret == GNUTLS_E_REHANDSHAKE) {
    /* BLOCKING call, this is bad but a work-around for now. Fixing this "the
       proper way" takes a whole lot of work. */
    CURLcode rc = handshake(conn, conn->ssl[num].session, num, FALSE);
    if(rc)
      /* handshake() writes error message on its own */
      return rc;
    *wouldblock = TRUE; /* then return as if this was a wouldblock */
    return -1;
  }

  *wouldblock = FALSE;
  if (!ret) {
    failf(conn->data, "Peer closed the TLS connection");
    return -1;
  }

  if (ret < 0) {
    failf(conn->data, "GnuTLS recv error (%d): %s",
          (int)ret, gnutls_strerror(ret));
    return -1;
  }

  return ret;
}

void Curl_gtls_session_free(void *ptr)
{
  free(ptr);
}

size_t Curl_gtls_version(char *buffer, size_t size)
{
  return snprintf(buffer, size, " GnuTLS/%s", gnutls_check_version(NULL));
}

#endif /* USE_GNUTLS */

Index: sendf.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/sendf.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- sendf.h	24 Jun 2005 13:00:12 -0000	1.1
+++ sendf.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,18 +1,18 @@
 #ifndef __SENDF_H
 #define __SENDF_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -28,16 +28,31 @@
 void Curl_infof(struct SessionHandle *, const char *fmt, ...);
 void Curl_failf(struct SessionHandle *, const char *fmt, ...);
 
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+#if defined(__GNUC__)
+/* This style of variable argument macros is a gcc extension */
+#define infof(x...) /*ignore*/
+#else
+/* C99 compilers could use this if we could detect them */
+/*#define infof(...) */
+/* Cast the args to void to make them a noop, side effects notwithstanding */
+#define infof (void)
+#endif
+#else
 #define infof Curl_infof
+#endif
 #define failf Curl_failf
 
 #define CLIENTWRITE_BODY   1
 #define CLIENTWRITE_HEADER 2
 #define CLIENTWRITE_BOTH   (CLIENTWRITE_BODY|CLIENTWRITE_HEADER)
 
-CURLcode Curl_client_write(struct SessionHandle *data, int type, char *ptr,
+CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr,
                            size_t len);
 
+void Curl_read_rewind(struct connectdata *conn,
+                      size_t extraBytesRead);
+
 /* internal read-function, does plain socket, SSL and krb4 */
 int Curl_read(struct connectdata *conn, curl_socket_t sockfd,
               char *buf, size_t buffersize,
@@ -50,7 +65,8 @@
 
 /* the function used to output verbose information */
 int Curl_debug(struct SessionHandle *handle, curl_infotype type,
-               char *data, size_t size, char *host);
+               char *data, size_t size,
+               struct connectdata *conn);
 
 
 #endif

Index: strtoofft.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/strtoofft.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- strtoofft.c	24 Jun 2005 13:00:13 -0000	1.1
+++ strtoofft.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,16 +1,16 @@
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -24,6 +24,14 @@
 #include "setup.h"
 #include "strtoofft.h"
 
+/*
+ * NOTE:
+ *
+ * In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we
+ * could use in case strtoll() doesn't exist...  See
+ * http://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html
+ */
+
 #ifdef NEED_CURL_STRTOLL
 #include <stdlib.h>
 #include <ctype.h>
@@ -47,7 +55,7 @@
 
   /* Skip leading whitespace. */
   end = (char *)nptr;
-  while (isspace((int)end[0])) {
+  while (ISSPACE(end[0])) {
     end++;
   }
 
@@ -111,17 +119,10 @@
     }
   }
   else {
-#ifdef HAVE_LONG_LONG_CONSTANT
-    if (is_negative)
-      value = 0x8000000000000000LL;
-    else
-      value = 0x7FFFFFFFFFFFFFFFLL;
-#else
     if (is_negative)
-      value = 0x8000000000000000L;
+      value = CURL_LLONG_MIN;
     else
-      value = 0x7FFFFFFFFFFFFFFFL;
-#endif
+      value = CURL_LLONG_MAX;
 
     errno = ERANGE;
   }

Index: getinfo.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/getinfo.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- getinfo.c	24 Jun 2005 13:00:12 -0000	1.1
+++ getinfo.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,16 +1,16 @@
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -32,13 +32,14 @@
 #include <string.h>
 #include <stdarg.h>
 #include <stdlib.h>
-#include "curl_memory.h"
+#include "memory.h"
+#include "sslgen.h"
 
 /* Make this the last #include */
 #include "memdebug.h"
 
 /*
- * This is supposed to be called in the beginning of a permform() session
+ * This is supposed to be called in the beginning of a perform() session
  * and should reset all session-info variables
  */
 CURLcode Curl_initinfo(struct SessionHandle *data)
@@ -56,13 +57,14 @@
   info->httpcode = 0;
   info->httpversion=0;
   info->filetime=-1; /* -1 is an illegal time and thus means unknown */
-  
+
   if (info->contenttype)
     free(info->contenttype);
   info->contenttype = NULL;
 
   info->header_size = 0;
   info->request_size = 0;
+  info->numconnects = 0;
   return CURLE_OK;
 }
 
@@ -72,13 +74,19 @@
   long *param_longp=NULL;
   double *param_doublep=NULL;
   char **param_charp=NULL;
+  struct curl_slist **param_slistp=NULL;
+  char buf;
+
+  if(!data)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
   va_start(arg, info);
 
   switch(info&CURLINFO_TYPEMASK) {
   default:
     return CURLE_BAD_FUNCTION_ARGUMENT;
   case CURLINFO_STRING:
-    param_charp = va_arg(arg, char **);  
+    param_charp = va_arg(arg, char **);
     if(NULL == param_charp)
       return CURLE_BAD_FUNCTION_ARGUMENT;
     break;
@@ -92,8 +100,13 @@
     if(NULL == param_doublep)
       return CURLE_BAD_FUNCTION_ARGUMENT;
     break;
+  case CURLINFO_SLIST:
+    param_slistp = va_arg(arg, struct curl_slist **);
+    if(NULL == param_slistp)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    break;
   }
-  
+
   switch(info) {
   case CURLINFO_EFFECTIVE_URL:
     *param_charp = data->change.url?data->change.url:(char *)"";
@@ -159,7 +172,7 @@
     *param_charp = data->info.contenttype;
     break;
   case CURLINFO_PRIVATE:
-    *param_charp = data->set.private;
+    *param_charp = data->set.private_data;
     break;
   case CURLINFO_HTTPAUTH_AVAIL:
     *param_longp = data->info.httpauthavail;
@@ -167,6 +180,53 @@
   case CURLINFO_PROXYAUTH_AVAIL:
     *param_longp = data->info.proxyauthavail;
     break;
+  case CURLINFO_OS_ERRNO:
+    *param_longp = data->state.os_errno;
+    break;
+  case CURLINFO_NUM_CONNECTS:
+    *param_longp = data->info.numconnects;
+    break;
+  case CURLINFO_SSL_ENGINES:
+    *param_slistp = Curl_ssl_engines_list(data);
+    break;
+  case CURLINFO_COOKIELIST:
+    *param_slistp = Curl_cookie_list(data);
+    break;
+  case CURLINFO_FTP_ENTRY_PATH:
+    /* Return the entrypath string from the most recent connection.
+       This pointer was copied from the connectdata structure by FTP.
+       The actual string may be free()ed by subsequent libcurl calls so
+       it must be copied to a safer area before the next libcurl call.
+       Callers must never free it themselves. */
+    *param_charp = data->state.most_recent_ftp_entrypath;
+    break;
+  case CURLINFO_LASTSOCKET:
+    if((data->state.lastconnect != -1) &&
+       (data->state.connc->connects[data->state.lastconnect] != NULL)) {
+      struct connectdata *c = data->state.connc->connects
+        [data->state.lastconnect];
+      *param_longp = c->sock[FIRSTSOCKET];
+      /* we have a socket connected, let's determine if the server shut down */
+      /* determine if ssl */
+      if(c->ssl[FIRSTSOCKET].use) {
+        /* use the SSL context */
+        if (!Curl_ssl_check_cxn(c))
+          *param_longp = -1;   /* FIN received */
+      }
+/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
+#ifdef MSG_PEEK
+      else {
+        /* use the socket */
+        if(recv((RECV_TYPE_ARG1)c->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
+                (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
+          *param_longp = -1;   /* FIN received */
+        }
+      }
+#endif
+    }
+    else
+      *param_longp = -1;
+    break;
   default:
     return CURLE_BAD_FUNCTION_ARGUMENT;
   }

--- NEW FILE: ssh.c ---
/***************************************************************************
*                                  _   _ ____  _
*  Project                     ___| | | |  _ \| |
*                             / __| | | | |_) | |
*                            | (__| |_| |  _ <| |___
*                             \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id: ssh.c,v 1.2 2007/03/15 19:22:13 andy Exp $
***************************************************************************/

/* #define CURL_LIBSSH2_DEBUG */

#include "setup.h"

#ifdef USE_LIBSSH2
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <limits.h>

#include <libssh2.h>
#include <libssh2_sftp.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif

#ifdef HAVE_TIME_H
#include <time.h>
#endif

#ifdef WIN32

#else /* probably some kind of unix */
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#include <sys/types.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_UTSNAME_H
#include <sys/utsname.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef  VMS
#include <in.h>
#include <inet.h>
#endif
#endif

#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
#undef in_addr_t
#define in_addr_t unsigned long
#endif

#include <curl/curl.h>
#include "urldata.h"
#include "sendf.h"
#include "easyif.h" /* for Curl_convert_... prototypes */

#include "if2ip.h"
#include "hostip.h"
#include "progress.h"
#include "transfer.h"
#include "escape.h"
#include "http.h" /* for HTTP proxy tunnel stuff */
#include "ssh.h"
#include "url.h"
#include "speedcheck.h"
#include "getinfo.h"

#include "strtoofft.h"
#include "strequal.h"
#include "sslgen.h"
#include "connect.h"
#include "strerror.h"
#include "memory.h"
#include "inet_ntop.h"
#include "select.h"
#include "parsedate.h" /* for the week day and month names */
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
#include "multiif.h"

#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
#include "inet_ntoa_r.h"
#endif

#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>

#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
#define DIRSEP '\\'
#else
#define DIRSEP '/'
#endif

#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>

/* The last #include file should be: */
#ifdef CURLDEBUG
#include "memdebug.h"
#endif

#ifndef LIBSSH2_SFTP_S_IRUSR
/* Here's a work-around for those of you who happend to run a libssh2 version
   that is 0.14 or older. We should remove this kludge as soon as we can
   require a more recent libssh2 release. */
#ifndef S_IRGRP
#define S_IRGRP  0
#endif

#ifndef S_IROTH
#define S_IROTH 0
#endif

#define LIBSSH2_SFTP_S_IRUSR S_IRUSR
#define LIBSSH2_SFTP_S_IWUSR S_IWUSR
#define LIBSSH2_SFTP_S_IRGRP S_IRGRP
#define LIBSSH2_SFTP_S_IROTH S_IROTH
#define LIBSSH2_SFTP_S_IRUSR S_IRUSR
#define LIBSSH2_SFTP_S_IWUSR S_IWUSR
#define LIBSSH2_SFTP_S_IRGRP S_IRGRP
#define LIBSSH2_SFTP_S_IROTH S_IROTH
#define LIBSSH2_SFTP_S_IFMT S_IFMT
#define LIBSSH2_SFTP_S_IFDIR S_IFDIR
#define LIBSSH2_SFTP_S_IFLNK S_IFLNK
#define LIBSSH2_SFTP_S_IFSOCK S_IFSOCK
#define LIBSSH2_SFTP_S_IFCHR S_IFCHR
#define LIBSSH2_SFTP_S_IFBLK S_IFBLK
#define LIBSSH2_SFTP_S_IXUSR S_IXUSR
#define LIBSSH2_SFTP_S_IWGRP S_IWGRP
#define LIBSSH2_SFTP_S_IXGRP S_IXGRP
#define LIBSSH2_SFTP_S_IWOTH S_IWOTH
#define LIBSSH2_SFTP_S_IXOTH S_IXOTH
#endif

static LIBSSH2_ALLOC_FUNC(libssh2_malloc);
static LIBSSH2_REALLOC_FUNC(libssh2_realloc);
static LIBSSH2_FREE_FUNC(libssh2_free);

static void
kbd_callback(const char *name, int name_len, const char *instruction,
             int instruction_len, int num_prompts,
             const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
             LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
             void **abstract)
{
  struct SSHPROTO *ssh = (struct SSHPROTO *)*abstract;

#ifdef CURL_LIBSSH2_DEBUG
  fprintf(stderr, "name=%s\n", name);
  fprintf(stderr, "name_len=%d\n", name_len);
  fprintf(stderr, "instruction=%s\n", instruction);
  fprintf(stderr, "instruction_len=%d\n", instruction_len);
  fprintf(stderr, "num_prompts=%d\n", num_prompts);
#else
  (void)name;
  (void)name_len;
  (void)instruction;
  (void)instruction_len;
#endif  /* CURL_LIBSSH2_DEBUG */
  if (num_prompts == 1) {
    responses[0].text = strdup(ssh->passwd);
    responses[0].length = strlen(ssh->passwd);
  }
  (void)prompts;
  (void)abstract;
} /* kbd_callback */

static CURLcode libssh2_error_to_CURLE(struct connectdata *conn)
{
  int errorcode;
  struct SSHPROTO *scp = conn->data->reqdata.proto.ssh;

  /* Get the libssh2 error code and string */
  errorcode = libssh2_session_last_error(scp->ssh_session, &scp->errorstr,
                                         NULL, 0);
  if (errorcode == LIBSSH2_FX_OK)
    return CURLE_OK;

  infof(conn->data, "libssh2 error %d, '%s'\n", errorcode, scp->errorstr);

  /* TODO: map some of the libssh2 errors to the more appropriate CURLcode
     error code, and possibly add a few new SSH-related one. We must however
     not return or even depend on libssh2 errors in the public libcurl API */

  return CURLE_SSH;
}

static LIBSSH2_ALLOC_FUNC(libssh2_malloc)
{
  return malloc(count);
  (void)abstract;
}

static LIBSSH2_REALLOC_FUNC(libssh2_realloc)
{
  return realloc(ptr, count);
  (void)abstract;
}

static LIBSSH2_FREE_FUNC(libssh2_free)
{
  free(ptr);
  (void)abstract;
}

static CURLcode ssh_init(struct connectdata *conn)
{
  struct SessionHandle *data = conn->data;
  struct SSHPROTO *ssh;
  if (data->reqdata.proto.ssh)
    return CURLE_OK;

  ssh = (struct SSHPROTO *)calloc(sizeof(struct SSHPROTO), 1);
  if (!ssh)
    return CURLE_OUT_OF_MEMORY;

  data->reqdata.proto.ssh = ssh;

  /* get some initial data into the ssh struct */
  ssh->bytecountp = &data->reqdata.keep.bytecount;

  /* no need to duplicate them, this connectdata struct won't change */
  ssh->user = conn->user;
  ssh->passwd = conn->passwd;

  ssh->errorstr = NULL;

  ssh->ssh_session = NULL;
  ssh->ssh_channel = NULL;
  ssh->sftp_session = NULL;
  ssh->sftp_handle = NULL;

  return CURLE_OK;
}

/*
 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
 * do protocol-specific actions at connect-time.
 */
CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
{
  int i;
  struct SSHPROTO *ssh;
  const char *fingerprint;
  const char *authlist;
  char *home;
  char rsa_pub[PATH_MAX];
  char rsa[PATH_MAX];
  char tempHome[PATH_MAX];
  curl_socket_t sock;
  char *real_path;
  char *working_path;
  int working_path_len;
  bool authed = FALSE;
  CURLcode result;
  struct SessionHandle *data = conn->data;

  rsa_pub[0] = rsa[0] = '\0';

  result = ssh_init(conn);
  if (result)
    return result;

  ssh = data->reqdata.proto.ssh;

  working_path = curl_easy_unescape(data, data->reqdata.path, 0,
                                    &working_path_len);
  if (!working_path)
    return CURLE_OUT_OF_MEMORY;

#ifdef CURL_LIBSSH2_DEBUG
  if (ssh->user) {
    infof(data, "User: %s\n", ssh->user);
  }
  if (ssh->passwd) {
    infof(data, "Password: %s\n", ssh->passwd);
  }
#endif /* CURL_LIBSSH2_DEBUG */
  sock = conn->sock[FIRSTSOCKET];
  ssh->ssh_session = libssh2_session_init_ex(libssh2_malloc, libssh2_free,
                                            libssh2_realloc, ssh);
  if (ssh->ssh_session == NULL) {
    failf(data, "Failure initialising ssh session\n");
    Curl_safefree(ssh->path);
    return CURLE_FAILED_INIT;
  }
#ifdef CURL_LIBSSH2_DEBUG
  infof(data, "SSH socket: %d\n", sock);
#endif /* CURL_LIBSSH2_DEBUG */

  if (libssh2_session_startup(ssh->ssh_session, sock)) {
    failf(data, "Failure establishing ssh session\n");
    libssh2_session_free(ssh->ssh_session);
    ssh->ssh_session = NULL;
    Curl_safefree(ssh->path);
    return CURLE_FAILED_INIT;
  }

  /*
   * Before we authenticate we should check the hostkey's fingerprint against
   * our known hosts. How that is handled (reading from file, whatever) is
   * up to us. As for know not much is implemented, besides showing how to
   * get the fingerprint.
   */
  fingerprint = libssh2_hostkey_hash(ssh->ssh_session,
                                     LIBSSH2_HOSTKEY_HASH_MD5);

#ifdef CURL_LIBSSH2_DEBUG
  /* The fingerprint points to static storage (!), don't free() it. */
  infof(data, "Fingerprint: ");
  for (i = 0; i < 16; i++) {
    infof(data, "%02X ", (unsigned char) fingerprint[i]);
  }
  infof(data, "\n");
#endif /* CURL_LIBSSH2_DEBUG */

  /* TBD - methods to check the host keys need to be done */

  /*
   * Figure out authentication methods
   * NB: As soon as we have provided a username to an openssh server we must
   * never change it later. Thus, always specify the correct username here,
   * even though the libssh2 docs kind of indicate that it should be possible
   * to get a 'generic' list (not user-specific) of authentication methods,
   * presumably with a blank username. That won't work in my experience.
   * So always specify it here.
   */
  authlist = libssh2_userauth_list(ssh->ssh_session, ssh->user,
                                   strlen(ssh->user));

  /*
   * Check the supported auth types in the order I feel is most secure with the
   * requested type of authentication
   */
  if ((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
      (strstr(authlist, "publickey") != NULL)) {
    /* To ponder about: should really the lib be messing about with the HOME
       environment variable etc? */
    home = curl_getenv("HOME");

    if (data->set.ssh_public_key)
      snprintf(rsa_pub, sizeof(rsa_pub), "%s", data->set.ssh_public_key);
    else if (home)
      snprintf(rsa_pub, sizeof(rsa_pub), "%s/.ssh/id_dsa.pub", home);

    if (data->set.ssh_private_key)
      snprintf(rsa, sizeof(rsa), "%s", data->set.ssh_private_key);
    else if (home)
      snprintf(rsa, sizeof(rsa), "%s/.ssh/id_dsa", home);

    curl_free(home);

    if (rsa_pub[0]) {
      /* The function below checks if the files exists, no need to stat() here.
      */
      if (libssh2_userauth_publickey_fromfile(ssh->ssh_session, ssh->user,
                                              rsa_pub, rsa, "") == 0) {
        authed = TRUE;
      }
    }
  }
  if (!authed &&
      (data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
      (strstr(authlist, "password") != NULL)) {
    if (!libssh2_userauth_password(ssh->ssh_session, ssh->user, ssh->passwd))
      authed = TRUE;
  }
  if (!authed && (data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
      (strstr(authlist, "hostbased") != NULL)) {
  }
  if (!authed && (data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
      && (strstr(authlist, "keyboard-interactive") != NULL)) {
    /* Authentication failed. Continue with keyboard-interactive now. */
    if (libssh2_userauth_keyboard_interactive_ex(ssh->ssh_session, ssh->user,
                                                 strlen(ssh->user),
                                                 &kbd_callback) == 0) {
      authed = TRUE;
    }
  }

  if (!authed) {
    failf(data, "Authentication failure\n");
    libssh2_session_free(ssh->ssh_session);
    ssh->ssh_session = NULL;
    Curl_safefree(ssh->path);
    return CURLE_FAILED_INIT;
  }

  /*
   * At this point we have an authenticated ssh session.
   */
  conn->sockfd = sock;
  conn->writesockfd = CURL_SOCKET_BAD;

  if (conn->protocol == PROT_SFTP) {
    /*
     * Start the libssh2 sftp session
     */
    ssh->sftp_session = libssh2_sftp_init(ssh->ssh_session);
    if (ssh->sftp_session == NULL) {
      failf(data, "Failure initialising sftp session\n");
      libssh2_sftp_shutdown(ssh->sftp_session);
      ssh->sftp_session = NULL;
      libssh2_session_free(ssh->ssh_session);
      ssh->ssh_session = NULL;
      return CURLE_FAILED_INIT;
    }

    /*
     * Get the "home" directory
     */
    i = libssh2_sftp_realpath(ssh->sftp_session, ".", tempHome, PATH_MAX-1);
    if (i > 0) {
      /* It seems that this string is not always NULL terminated */
      tempHome[i] = '\0';
      ssh->homedir = (char *)strdup(tempHome);
      if (!ssh->homedir) {
        libssh2_sftp_shutdown(ssh->sftp_session);
        ssh->sftp_session = NULL;
        libssh2_session_free(ssh->ssh_session);
        ssh->ssh_session = NULL;
        return CURLE_OUT_OF_MEMORY;
      }
    }
    else {
      /* Return the error type */
      i = libssh2_sftp_last_error(ssh->sftp_session);
      DEBUGF(infof(data, "error = %d\n", i));
    }
  }

  /* Check for /~/ , indicating realative to the users home directory */
  if (conn->protocol == PROT_SCP) {
    real_path = (char *)malloc(working_path_len+1);
    if (real_path == NULL) {
      Curl_safefree(working_path);
      libssh2_session_free(ssh->ssh_session);
      ssh->ssh_session = NULL;
      return CURLE_OUT_OF_MEMORY;
    }
    if (working_path[1] == '~')
      /* It is referenced to the home directory, so strip the leading '/' */
      memcpy(real_path, working_path+1, 1 + working_path_len-1);
    else
      memcpy(real_path, working_path, 1 + working_path_len);
  }
  else if (conn->protocol == PROT_SFTP) {
    if (working_path[1] == '~') {
      real_path = (char *)malloc(strlen(ssh->homedir) +
                                 working_path_len + 1);
      if (real_path == NULL) {
        libssh2_sftp_shutdown(ssh->sftp_session);
        ssh->sftp_session = NULL;
        libssh2_session_free(ssh->ssh_session);
        ssh->ssh_session = NULL;
        Curl_safefree(working_path);
        return CURLE_OUT_OF_MEMORY;
      }
      /* It is referenced to the home directory, so strip the leading '/' */
      memcpy(real_path, ssh->homedir, strlen(ssh->homedir));
      real_path[strlen(ssh->homedir)] = '/';
      real_path[strlen(ssh->homedir)+1] = '\0';
      if (working_path_len > 3) {
        memcpy(real_path+strlen(ssh->homedir)+1, working_path + 3,
               1 + working_path_len -3);
      }
    }
    else {
      real_path = (char *)malloc(working_path_len+1);
      if (real_path == NULL) {
        libssh2_session_free(ssh->ssh_session);
        ssh->ssh_session = NULL;
        Curl_safefree(working_path);
        return CURLE_OUT_OF_MEMORY;
      }
      memcpy(real_path, working_path, 1+working_path_len);
    }
  }
  else
    return CURLE_FAILED_INIT;

  Curl_safefree(working_path);
  ssh->path = real_path;

  *done = TRUE;
  return CURLE_OK;
}

CURLcode Curl_scp_do(struct connectdata *conn, bool *done)
{
  struct stat sb;
  struct SSHPROTO *scp = conn->data->reqdata.proto.ssh;
  CURLcode res = CURLE_OK;

  *done = TRUE; /* unconditionally */

  if (conn->data->set.upload) {
    /*
     * NOTE!!!  libssh2 requires that the destination path is a full path
     *          that includes the destination file and name OR ends in a "/" .
     *          If this is not done the destination file will be named the
     *          same name as the last directory in the path.
     */
    scp->ssh_channel = libssh2_scp_send_ex(scp->ssh_session, scp->path,
                                           LIBSSH2_SFTP_S_IRUSR|
                                           LIBSSH2_SFTP_S_IWUSR|
                                           LIBSSH2_SFTP_S_IRGRP|
                                           LIBSSH2_SFTP_S_IROTH,
                                           conn->data->set.infilesize, 0, 0);
    if (!scp->ssh_channel)
      return CURLE_FAILED_INIT;

    /* upload data */
    res = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
  }
  else {
    /*
     * We must check the remote file, if it is a directory no vaules will
     * be set in sb
     */
    curl_off_t bytecount;
    memset(&sb, 0, sizeof(struct stat));
    scp->ssh_channel = libssh2_scp_recv(scp->ssh_session, scp->path, &sb);
    if (!scp->ssh_channel) {
      if ((sb.st_mode == 0) && (sb.st_atime == 0) && (sb.st_mtime == 0) &&
          (sb.st_size == 0)) {
        /* Since sb is still empty, it is likely the file was not found */
        return CURLE_REMOTE_FILE_NOT_FOUND;
      }
      return libssh2_error_to_CURLE(conn);
    }
    /* download data */
    bytecount = (curl_off_t) sb.st_size;
    conn->data->reqdata.maxdownload =  (curl_off_t) sb.st_size;
    res = Curl_setup_transfer(conn, FIRSTSOCKET,
                              bytecount, FALSE, NULL, -1, NULL);
  }

  return res;
}

CURLcode Curl_scp_done(struct connectdata *conn, CURLcode status,
                       bool premature)
{
  struct SSHPROTO *scp = conn->data->reqdata.proto.ssh;
  (void)premature; /* not used */

  Curl_safefree(scp->path);
  scp->path = NULL;

  if (scp->ssh_channel) {
    if (libssh2_channel_close(scp->ssh_channel) < 0) {
      infof(conn->data, "Failed to stop libssh2 channel subsystem\n");
    }
  }

  if (scp->ssh_session) {
    libssh2_session_disconnect(scp->ssh_session, "Shutdown");
    libssh2_session_free(scp->ssh_session);
    scp->ssh_session = NULL;
  }

  free(conn->data->reqdata.proto.ssh);
  conn->data->reqdata.proto.ssh = NULL;
  Curl_pgrsDone(conn);

  (void)status; /* unused */

  return CURLE_OK;
}

/* return number of received (decrypted) bytes */
ssize_t Curl_scp_send(struct connectdata *conn, int sockindex,
                      void *mem, size_t len)
{
  ssize_t nwrite;

  /* libssh2_channel_write() returns int
   *
   * NOTE: we should not store nor rely on connection-related data to be
   * in the SessionHandle struct
   */
  nwrite = (ssize_t)
    libssh2_channel_write(conn->data->reqdata.proto.ssh->ssh_channel,
                          mem, len);
  (void)sockindex;
  return nwrite;
}

/*
 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
 * a regular CURLcode value.
 */
ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex,
                  char *mem, size_t len)
{
  ssize_t nread;

  /* libssh2_channel_read() returns int
   *
   * NOTE: we should not store nor rely on connection-related data to be
   * in the SessionHandle struct
   */

  nread = (ssize_t)
    libssh2_channel_read(conn->data->reqdata.proto.ssh->ssh_channel,
                         mem, len);
  (void)sockindex;
  return nread;
}

/*
 * =============== SFTP ===============
 */

CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
{
  LIBSSH2_SFTP_ATTRIBUTES attrs;
  struct SSHPROTO *sftp = conn->data->reqdata.proto.ssh;
  CURLcode res = CURLE_OK;
  struct SessionHandle *data = conn->data;
  curl_off_t bytecount = 0;
  char *buf = data->state.buffer;

  *done = TRUE; /* unconditionally */

  if (data->set.upload) {
    /*
     * NOTE!!!  libssh2 requires that the destination path is a full path
     *          that includes the destination file and name OR ends in a "/" .
     *          If this is not done the destination file will be named the
     *          same name as the last directory in the path.
     */
    sftp->sftp_handle =
      libssh2_sftp_open(sftp->sftp_session, sftp->path,
                        LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT,
                        LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
                        LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
    if (!sftp->sftp_handle)
      return CURLE_FAILED_INIT;

    /* upload data */
    res = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
  }
  else {
    if (sftp->path[strlen(sftp->path)-1] == '/') {
      /*
       * This is a directory that we are trying to get, so produce a
       * directory listing
       *
       * **BLOCKING behaviour** This should be made into a state machine and
       * get a separate function called from Curl_sftp_recv() when there is
       * data to read from the network, instead of "hanging" here.
       */
      char filename[PATH_MAX+1];
      int len, totalLen, currLen;
      char *line;

      sftp->sftp_handle =
        libssh2_sftp_opendir(sftp->sftp_session, sftp->path);
      if (!sftp->sftp_handle)
        return CURLE_SSH;

      while ((len = libssh2_sftp_readdir(sftp->sftp_handle, filename,
                                         PATH_MAX, &attrs)) > 0) {
        filename[len] = '\0';

        if (data->set.ftp_list_only) {
          if ((attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
              ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
               LIBSSH2_SFTP_S_IFDIR)) {
            infof(data, "%s\n", filename);
          }
        }
        else {
          totalLen = 80 + len;
          line = (char *)malloc(totalLen);
          if (!line)
            return CURLE_OUT_OF_MEMORY;

          if (!(attrs.flags & LIBSSH2_SFTP_ATTR_UIDGID))
            attrs.uid = attrs.gid =0;

          currLen = snprintf(line, totalLen, "----------   1 %5d %5d",
                             attrs.uid, attrs.gid);

          if (attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
            if ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
                LIBSSH2_SFTP_S_IFDIR) {
              line[0] = 'd';
            }
            else if ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
                     LIBSSH2_SFTP_S_IFLNK) {
              line[0] = 'l';
            }
            else if ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
                     LIBSSH2_SFTP_S_IFSOCK) {
              line[0] = 's';
            }
            else if ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
                     LIBSSH2_SFTP_S_IFCHR) {
              line[0] = 'c';
            }
            else if ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
                     LIBSSH2_SFTP_S_IFBLK) {
              line[0] = 'b';
            }
            if (attrs.permissions & LIBSSH2_SFTP_S_IRUSR) {
              line[1] = 'r';
            }
            if (attrs.permissions & LIBSSH2_SFTP_S_IWUSR) {
              line[2] = 'w';
            }
            if (attrs.permissions & LIBSSH2_SFTP_S_IXUSR) {
              line[3] = 'x';
            }
            if (attrs.permissions & LIBSSH2_SFTP_S_IRGRP) {
              line[4] = 'r';
            }
            if (attrs.permissions & LIBSSH2_SFTP_S_IWGRP) {
              line[5] = 'w';
            }
            if (attrs.permissions & LIBSSH2_SFTP_S_IXGRP) {
              line[6] = 'x';
            }
            if (attrs.permissions & LIBSSH2_SFTP_S_IROTH) {
              line[7] = 'r';
            }
            if (attrs.permissions & LIBSSH2_SFTP_S_IWOTH) {
              line[8] = 'w';
            }
            if (attrs.permissions & LIBSSH2_SFTP_S_IXOTH) {
              line[9] = 'x';
            }
          }
          if (attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) {
            currLen += snprintf(line+currLen, totalLen-currLen, "%11lld",
                                attrs.filesize);
          }
          if (attrs.flags & LIBSSH2_SFTP_ATTR_ACMODTIME) {
            const char *months[12] = {
              "Jan", "Feb", "Mar", "Apr", "May", "Jun",
              "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
            struct tm *nowParts;
            time_t now, remoteTime;

            now = time(NULL);
            remoteTime = (time_t)attrs.mtime;
            nowParts = localtime(&remoteTime);

            if ((time_t)attrs.mtime > (now - (3600 * 24 * 180))) {
              currLen += snprintf(line+currLen, totalLen-currLen,
                                  " %s %2d %2d:%02d", months[nowParts->tm_mon],
                                  nowParts->tm_mday, nowParts->tm_hour,
                                  nowParts->tm_min);
            }
            else {
              currLen += snprintf(line+currLen, totalLen-currLen,
                                  " %s %2d %5d", months[nowParts->tm_mon],
                                  nowParts->tm_mday, 1900+nowParts->tm_year);
            }
          }
          currLen += snprintf(line+currLen, totalLen-currLen, " %s", filename);
          if ((attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
              ((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
               LIBSSH2_SFTP_S_IFLNK)) {
            char linkPath[PATH_MAX + 1];

            snprintf(linkPath, PATH_MAX, "%s%s", sftp->path, filename);
            len = libssh2_sftp_readlink(sftp->sftp_session, linkPath, filename,
                                        PATH_MAX);
            line = realloc(line, totalLen + 4 + len);
            if (!line)
              return CURLE_OUT_OF_MEMORY;

            currLen += snprintf(line+currLen, totalLen-currLen, " -> %s",
                                filename);
          }

          currLen += snprintf(line+currLen, totalLen-currLen, "\n");
          res = Curl_client_write(conn, CLIENTWRITE_BODY, line, 0);
          free(line);
        }
      }
      libssh2_sftp_closedir(sftp->sftp_handle);
      sftp->sftp_handle = NULL;

      /* no data to transfer */
      res = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
    }
    else {
      /*
       * Work on getting the specified file
       */
      sftp->sftp_handle =
        libssh2_sftp_open(sftp->sftp_session, sftp->path, LIBSSH2_FXF_READ,
                          LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
                          LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
      if (!sftp->sftp_handle)
        return CURLE_SSH;

      if (libssh2_sftp_stat(sftp->sftp_session, sftp->path, &attrs)) {
        /*
         * libssh2_sftp_open() didn't return an error, so maybe the server
         * just doesn't support stat()
         */
        data->reqdata.size = -1;
        data->reqdata.maxdownload = -1;
      }
      else {
        data->reqdata.size = attrs.filesize;
        data->reqdata.maxdownload = attrs.filesize;
        Curl_pgrsSetDownloadSize(data, attrs.filesize);
      }

      Curl_pgrsTime(data, TIMER_STARTTRANSFER);

      /* Now download data. The libssh2 0.14 doesn't offer any way to do this
         without using this BLOCKING approach, so here's room for improvement
         once libssh2 can return EWOULDBLOCK to us. */
#if 0
      /* code left here just because this is what this function will use the
         day libssh2 is improved */
      res = Curl_setup_transfer(conn, FIRSTSOCKET,
                                bytecount, FALSE, NULL, -1, NULL);
#endif
      while (res == CURLE_OK) {
        size_t nread;
        /* NOTE: most *read() functions return ssize_t but this returns size_t
           which normally is unsigned! */
        nread = libssh2_sftp_read(data->reqdata.proto.ssh->sftp_handle,
                                  buf, BUFSIZE-1);

        if (nread > 0)
          buf[nread] = 0;

        /* this check can be changed to a <= 0 when nread is changed to a
           signed variable type */
        if ((nread == 0) || (nread == (size_t)~0))
          break;

        bytecount += nread;

        res = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
        if(res)
          return res;

        Curl_pgrsSetDownloadCounter(data, bytecount);

        if(Curl_pgrsUpdate(conn))
          res = CURLE_ABORTED_BY_CALLBACK;
        else {
          struct timeval now = Curl_tvnow();
          res = Curl_speedcheck(data, now);
        }
      }
      if(Curl_pgrsUpdate(conn))
        res = CURLE_ABORTED_BY_CALLBACK;

      /* no (more) data to transfer */
      res = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
    }
  }

  return res;
}

CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode status,
                        bool premature)
{
  struct SSHPROTO *sftp = conn->data->reqdata.proto.ssh;
  (void)premature; /* not used */

  Curl_safefree(sftp->path);
  sftp->path = NULL;

  Curl_safefree(sftp->homedir);
  sftp->homedir = NULL;

  if (sftp->sftp_handle) {
    if (libssh2_sftp_close(sftp->sftp_handle) < 0) {
      infof(conn->data, "Failed to close libssh2 file\n");
    }
  }

  if (sftp->sftp_session) {
    if (libssh2_sftp_shutdown(sftp->sftp_session) < 0) {
      infof(conn->data, "Failed to stop libssh2 sftp subsystem\n");
    }
  }

  if (sftp->ssh_channel) {
    if (libssh2_channel_close(sftp->ssh_channel) < 0) {
      infof(conn->data, "Failed to stop libssh2 channel subsystem\n");
    }
  }

  if (sftp->ssh_session) {
    libssh2_session_disconnect(sftp->ssh_session, "Shutdown");
    libssh2_session_free(sftp->ssh_session);
    sftp->ssh_session = NULL;
  }

  free(conn->data->reqdata.proto.ssh);
  conn->data->reqdata.proto.ssh = NULL;
  Curl_pgrsDone(conn);

  (void)status; /* unused */

  return CURLE_OK;
}

/* return number of received (decrypted) bytes */
ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex,
                       void *mem, size_t len)
{
  ssize_t nwrite;

  /* libssh2_sftp_write() returns size_t !*/

  nwrite = (ssize_t)
    libssh2_sftp_write(conn->data->reqdata.proto.ssh->sftp_handle, mem, len);
  (void)sockindex;
  return nwrite;
}

/*
 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
 * a regular CURLcode value.
 */
ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
                   char *mem, size_t len)
{
  ssize_t nread;

  /* libssh2_sftp_read() returns size_t !*/

  nread = (ssize_t)
    libssh2_sftp_read(conn->data->reqdata.proto.ssh->sftp_handle, mem, len);
  (void)sockindex;
  return nread;
}

#endif /* USE_LIBSSH2 */

--- NEW FILE: ssh.h ---
#ifndef __SSH_H
#define __SSH_H

/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: ssh.h,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

#ifdef USE_LIBSSH2

CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done);

CURLcode Curl_scp_do(struct connectdata *conn, bool *done);
CURLcode Curl_scp_done(struct connectdata *conn, CURLcode, bool premature);

ssize_t Curl_scp_send(struct connectdata *conn, int sockindex,
                      void *mem, size_t len);
ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex,
                      char *mem, size_t len);

CURLcode Curl_sftp_do(struct connectdata *conn, bool *done);
CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode, bool premature);

ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex,
                       void *mem, size_t len);
ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
                       char *mem, size_t len);

#endif /* USE_LIBSSH2 */

#endif /* __SSH_H */


Index: strequal.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/strequal.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- strequal.h	24 Jun 2005 13:00:13 -0000	1.1
+++ strequal.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,11 +23,7 @@
  * $Id$
  ***************************************************************************/
 
-/*
- * These two actually are public functions.
- */
-int curl_strequal(const char *first, const char *second);
-int curl_strnequal(const char *first, const char *second, size_t max);
+#include <curl/curl.h>
 
 #define strequal(a,b) curl_strequal(a,b)
 #define strnequal(a,b,c) curl_strnequal(a,b,c)
@@ -41,7 +37,7 @@
 
 #ifndef HAVE_STRLCAT
 #define strlcat(x,y,z) Curl_strlcat(x,y,z)
-size_t Curl_strlcat(char *dst, const char *src, size_t siz);
 #endif
+size_t strlcat(char *dst, const char *src, size_t siz);
 
 #endif

Index: strequal.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/strequal.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- strequal.c	24 Jun 2005 13:00:13 -0000	1.1
+++ strequal.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -28,7 +28,7 @@
 
 #include "strequal.h"
 
-#ifdef HAVE_STRCASECMP
+#if defined(HAVE_STRCASECMP) && defined(__STRICT_ANSI__)
 /* this is for "-ansi -Wall -pedantic" to stop complaining! */
 extern int (strcasecmp)(const char *s1, const char *s2);
 extern int (strncasecmp)(const char *s1, const char *s2, size_t n);
@@ -38,10 +38,10 @@
 {
 #if defined(HAVE_STRCASECMP)
   return !(strcasecmp)(first, second);
-#elif defined(HAVE_STRICMP)
-  return !(stricmp)(first, second);
 #elif defined(HAVE_STRCMPI)
   return !(strcmpi)(first, second);
+#elif defined(HAVE_STRICMP)
+  return !(stricmp)(first, second);
 #else
   while (*first && *second) {
     if (toupper(*first) != toupper(*second)) {
@@ -58,10 +58,10 @@
 {
 #if defined(HAVE_STRCASECMP)
   return !strncasecmp(first, second, max);
-#elif defined(HAVE_STRICMP)
-  return !strnicmp(first, second, max);
 #elif defined(HAVE_STRCMPI)
   return !strncmpi(first, second, max);
+#elif defined(HAVE_STRICMP)
+  return !strnicmp(first, second, max);
 #else
   while (*first && *second && max) {
     if (toupper(*first) != toupper(*second)) {

Index: security.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/security.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- security.c	24 Jun 2005 13:00:12 -0000	1.1
+++ security.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -46,7 +46,6 @@
 #define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */
 #include <curl/mprintf.h>
 
-#include "security.h"
 #include <stdlib.h>
 #include <string.h>
 #include <netdb.h>
@@ -55,17 +54,19 @@
 #include <unistd.h>
 #endif
 
+#include "urldata.h"
+#include "krb4.h"
 #include "base64.h"
 #include "sendf.h"
 #include "ftp.h"
-#include "curl_memory.h"
+#include "memory.h"
 
 /* The last #include file should be: */
 #include "memdebug.h"
 
 #define min(a, b)   ((a) < (b) ? (a) : (b))
 
-static struct {
+static const struct {
     enum protection_level level;
     const char *name;
 } level_names[] = {
@@ -80,12 +81,12 @@
 {
   int i;
   for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++)
-    if(!strncasecmp(level_names[i].name, name, strlen(name)))
+    if(curl_strnequal(level_names[i].name, name, strlen(name)))
       return level_names[i].level;
   return (enum protection_level)-1;
 }
 
-static struct Curl_sec_client_mech *mechs[] = {
+static const struct Curl_sec_client_mech * const mechs[] = {
 #ifdef KRB5
   /* not supported */
 #endif
@@ -277,6 +278,13 @@
   return tx;
 }
 
+ssize_t
+Curl_sec_send(struct connectdata *conn, int num, char *buffer, int length)
+{
+  curl_socket_t fd = conn->sock[num];
+  return (ssize_t)Curl_sec_write(conn, fd, buffer, length);
+}
+
 int
 Curl_sec_putc(struct connectdata *conn, int c, FILE *F)
 {
@@ -297,13 +305,15 @@
 Curl_sec_read_msg(struct connectdata *conn, char *s, int level)
 {
   int len;
-  char *buf;
+  unsigned char *buf;
   int code;
 
-  buf = malloc(strlen(s));
-  len = Curl_base64_decode(s + 4, buf); /* XXX */
+  len = Curl_base64_decode(s + 4, &buf); /* XXX */
+  if(len > 0)
+    len = (conn->mech->decode)(conn->app_data, buf, len, level, conn);
+  else
+    return -1;
 
-  len = (conn->mech->decode)(conn->app_data, buf, len, level, conn);
   if(len < 0) {
     free(buf);
     return -1;
@@ -314,10 +324,10 @@
   if(buf[3] == '-')
     code = 0;
   else
-    sscanf(buf, "%d", &code);
+    sscanf((char *)buf, "%d", &code);
   if(buf[len-1] == '\n')
     buf[len-1] = '\0';
-  strcpy(s, buf);
+  strcpy(s, (char *)buf);
   free(buf);
   return code;
 }
@@ -400,7 +410,7 @@
 Curl_sec_login(struct connectdata *conn)
 {
   int ret;
-  struct Curl_sec_client_mech **m;
+  const struct Curl_sec_client_mech * const *m;
   ssize_t nread;
   struct SessionHandle *data=conn->data;
   int ftpcode;

Index: transfer.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/transfer.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- transfer.h	24 Jun 2005 13:00:13 -0000	1.1
+++ transfer.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,22 +24,21 @@
  ***************************************************************************/
 CURLcode Curl_perform(struct SessionHandle *data);
 CURLcode Curl_pretransfer(struct SessionHandle *data);
-CURLcode Curl_pretransfersec(struct connectdata *conn);
+CURLcode Curl_second_connect(struct connectdata *conn);
 CURLcode Curl_posttransfer(struct SessionHandle *data);
-CURLcode Curl_follow(struct SessionHandle *data, char *newurl);
+CURLcode Curl_follow(struct SessionHandle *data, char *newurl, bool retry);
 CURLcode Curl_readwrite(struct connectdata *conn, bool *done);
-void Curl_single_fdset(struct connectdata *conn,
-                       fd_set *read_fd_set,
-                       fd_set *write_fd_set,
-                       fd_set *exc_fd_set,
-                       int *max_fd);
+int Curl_single_getsock(struct connectdata *conn,
+                        curl_socket_t *socks,
+                        int numsocks);
 CURLcode Curl_readwrite_init(struct connectdata *conn);
-
+CURLcode Curl_readrewind(struct connectdata *conn);
 CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
+bool Curl_retry_request(struct connectdata *conn, char **url);
 
 /* This sets up a forthcoming transfer */
 CURLcode
-Curl_Transfer (struct connectdata *data,
+Curl_setup_transfer (struct connectdata *data,
                int sockindex,           /* socket index to read from or -1 */
                curl_off_t size,         /* -1 if unknown at this point */
                bool getheader,          /* TRUE if header parsing is wanted */

Index: ssluse.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/ssluse.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ssluse.c	24 Jun 2005 13:00:13 -0000	1.1
+++ ssluse.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -22,8 +22,13 @@
  ***************************************************************************/
 
[...1620 lines suppressed...]
+  {
+    char sub[2];
+    sub[1]='\0';
+    if(SSLEAY_VERSION_NUMBER&0x0f) {
+      sub[0]=(SSLEAY_VERSION_NUMBER&0x0f) + 'a' -1;
+    }
+    else
+      sub[0]='\0';
+
+    return snprintf(buffer, size, " SSL/%x.%x.%x%s",
+                    (SSLEAY_VERSION_NUMBER>>12)&0xff,
+                    (SSLEAY_VERSION_NUMBER>>8)&0xf,
+                    (SSLEAY_VERSION_NUMBER>>4)&0xf, sub);
+  }
+#endif /* (SSLEAY_VERSION_NUMBER >= 0x900000) */
+#endif /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */
+
+#endif /* YASSL_VERSION */
+}
+#endif /* USE_SSLEAY */

--- security.h DELETED ---

Index: ssluse.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/ssluse.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ssluse.h	24 Jun 2005 13:00:13 -0000	1.1
+++ ssluse.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,18 +1,18 @@
 #ifndef __SSLUSE_H
 #define __SSLUSE_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -22,17 +22,50 @@
  *
  * $Id$
  ***************************************************************************/
+
+/*
+ * This header should only be needed to get included by sslgen.c and ssluse.c
+ */
+
 #include "urldata.h"
-CURLcode Curl_SSLConnect(struct connectdata *conn, int sockindex);
+CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex);
+CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn,
+                                       int sockindex,
+                                       bool *done);
+void Curl_ossl_close(struct connectdata *conn); /* close a SSL connection */
+/* tell OpenSSL to close down all open information regarding connections (and
+   thus session ID caching etc) */
+int Curl_ossl_close_all(struct SessionHandle *data);
+/* Sets an OpenSSL engine */
+CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine);
 
-void Curl_SSL_init(void);    /* Global SSL init */
-void Curl_SSL_cleanup(void); /* Global SSL cleanup */
+/* function provided for the generic SSL-layer, called when a session id
+   should be freed */
+void Curl_ossl_session_free(void *ptr);
 
-/* init the SSL session ID cache */
-CURLcode Curl_SSL_InitSessions(struct SessionHandle *, long);
-void Curl_SSL_Close(struct connectdata *conn); /* close a SSL connection */
+/* Sets engine as default for all SSL operations */
+CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data);
+
+/* Build list of OpenSSL engines */
+struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data);
+
+int Curl_ossl_init(void);
+void Curl_ossl_cleanup(void);
+
+ssize_t Curl_ossl_send(struct connectdata *conn,
+                       int sockindex,
+                       void *mem,
+                       size_t len);
+ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */
+                       int num,                  /* socketindex */
+                       char *buf,                /* store read data here */
+                       size_t buffersize,        /* max amount to read */
+                       bool *wouldblock);
+
+size_t Curl_ossl_version(char *buffer, size_t size);
+int Curl_ossl_check_cxn(struct connectdata *cxn);
+int Curl_ossl_seed(struct SessionHandle *data);
+
+int Curl_ossl_shutdown(struct connectdata *conn, int sockindex);
 
-/* tell the SSL stuff to close down all open information regarding 
-   connections (and thus session ID caching etc) */
-int Curl_SSL_Close_All(struct SessionHandle *data);
 #endif

Index: transfer.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/transfer.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- transfer.c	24 Jun 2005 13:00:13 -0000	1.1
+++ transfer.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -32,14 +32,16 @@
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
[...1952 lines suppressed...]
-    free(data->change.url);
 
-  data->change.url_alloc = TRUE;
-  data->change.url = url;
-  data->set.ftpport = data->set.source_port;
-  data->set.userpwd = data->set.source_userpwd;
-
-  /* secondary connection */
-  status = Curl_connect_host(data, &sec_conn);
-  if(CURLE_OK == status) {
-    sec_conn->data = data;
-    conn->sec_conn = sec_conn;
-  }
+  data->reqdata.size = size;
+  data->reqdata.bytecountp = bytecountp;
+  data->reqdata.writebytecountp = writecountp;
 
-  return status;
+  return CURLE_OK;
 }

Index: base64.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/base64.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- base64.c	24 Jun 2005 13:00:12 -0000	1.1
+++ base64.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -40,28 +40,27 @@
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
 
+#include "urldata.h" /* for the SessionHandle definition */
+#include "easyif.h"  /* for Curl_convert_... prototypes */
 #include "base64.h"
-#include "curl_memory.h"
+#include "memory.h"
 
 /* include memdebug.h last */
 #include "memdebug.h"
 
+/* ---- Base64 Encoding/Decoding Table --- */
+static const char table64[]=
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 static void decodeQuantum(unsigned char *dest, const char *src)
 {
   unsigned int x = 0;
   int i;
+  char *found;
+
   for(i = 0; i < 4; i++) {
-    if(src[i] >= 'A' && src[i] <= 'Z')
-      x = (x << 6) + (unsigned int)(src[i] - 'A' + 0);
-    else if(src[i] >= 'a' && src[i] <= 'z')
-      x = (x << 6) + (unsigned int)(src[i] - 'a' + 26);
-    else if(src[i] >= '0' && src[i] <= '9')
-      x = (x << 6) + (unsigned int)(src[i] - '0' + 52);
-    else if(src[i] == '+')
-      x = (x << 6) + 62;
-    else if(src[i] == '/')
-      x = (x << 6) + 63;
+    if((found = strchr(table64, src[i])))
+      x = (x << 6) + (unsigned int)(found - table64);
     else if(src[i] == '=')
       x = (x << 6);
   }
@@ -76,43 +75,63 @@
 /*
  * Curl_base64_decode()
  *
- * Given a base64 string at src, decode it into the memory pointed to by
- * dest. Returns the length of the decoded data.
+ * Given a base64 string at src, decode it and return an allocated memory in
+ * the *outptr. Returns the length of the decoded data.
  */
-size_t Curl_base64_decode(const char *src, char *dest)
+size_t Curl_base64_decode(const char *src, unsigned char **outptr)
 {
   int length = 0;
   int equalsTerm = 0;
   int i;
   int numQuantums;
   unsigned char lastQuantum[3];
-  size_t rawlen;
+  size_t rawlen=0;
+  unsigned char *newstr;
+
+  *outptr = NULL;
 
   while((src[length] != '=') && src[length])
     length++;
-  while(src[length+equalsTerm] == '=')
+  /* A maximum of two = padding characters is allowed */
+  if(src[length] == '=') {
     equalsTerm++;
-
+    if(src[length+equalsTerm] == '=')
+      equalsTerm++;
+  }
   numQuantums = (length + equalsTerm) / 4;
 
+  /* Don't allocate a buffer if the decoded length is 0 */
+  if (numQuantums <= 0)
+    return 0;
+
   rawlen = (numQuantums * 3) - equalsTerm;
 
+  /* The buffer must be large enough to make room for the last quantum
+  (which may be partially thrown out) and the zero terminator. */
+  newstr = malloc(rawlen+4);
+  if(!newstr)
+    return 0;
+
+  *outptr = newstr;
+
+  /* Decode all but the last quantum (which may not decode to a
+  multiple of 3 bytes) */
   for(i = 0; i < numQuantums - 1; i++) {
-    decodeQuantum((unsigned char *)dest, src);
-    dest += 3; src += 4;
+    decodeQuantum((unsigned char *)newstr, src);
+    newstr += 3; src += 4;
   }
 
+  /* This final decode may actually read slightly past the end of the buffer
+  if the input string is missing pad bytes.  This will almost always be
+  harmless. */
   decodeQuantum(lastQuantum, src);
   for(i = 0; i < 3 - equalsTerm; i++)
-    dest[i] = lastQuantum[i];
+    newstr[i] = lastQuantum[i];
 
+  newstr[i] = 0; /* zero terminate */
   return rawlen;
 }
 
-/* ---- Base64 Encoding --- */
-static char table64[]=
-  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
 /*
  * Curl_base64_encode()
  *
@@ -121,7 +140,8 @@
  * went wrong, -1 is returned.
  *
  */
-size_t Curl_base64_encode(const char *inp, size_t insize, char **outptr)
+size_t Curl_base64_encode(struct SessionHandle *data,
+                          const char *inp, size_t insize, char **outptr)
 {
   unsigned char ibuf[3];
   unsigned char obuf[4];
@@ -129,6 +149,9 @@
   int inputparts;
   char *output;
   char *base64data;
+#ifdef CURL_DOES_CONVERSIONS
+  char *convbuf;
+#endif
 
   char *indata = (char *)inp;
 
@@ -141,6 +164,28 @@
   if(NULL == output)
     return 0;
 
+#ifdef CURL_DOES_CONVERSIONS
+  /*
+   * The base64 data needs to be created using the network encoding
+   * not the host encoding.  And we can't change the actual input
+   * so we copy it to a buffer, translate it, and use that instead.
+   */
+  if(data) {
+    convbuf = (char*)malloc(insize);
+    if(!convbuf) {
+      return 0;
+    }
+    memcpy(convbuf, indata, insize);
+    if(CURLE_OK != Curl_convert_to_network(data, convbuf, insize)) {
+      free(convbuf);
+      return 0;
+    }
+    indata = convbuf; /* switch to the converted buffer */
+  }
+#else
+  (void)data;
+#endif
+
   while(insize > 0) {
     for (i = inputparts = 0; i < 3; i++) {
       if(insize > 0) {
@@ -153,10 +198,12 @@
         ibuf[i] = 0;
     }
 
-    obuf [0] = (ibuf [0] & 0xFC) >> 2;
-    obuf [1] = ((ibuf [0] & 0x03) << 4) | ((ibuf [1] & 0xF0) >> 4);
-    obuf [2] = ((ibuf [1] & 0x0F) << 2) | ((ibuf [2] & 0xC0) >> 6);
-    obuf [3] = ibuf [2] & 0x3F;
+    obuf[0] = (unsigned char)  ((ibuf[0] & 0xFC) >> 2);
+    obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \
+                               ((ibuf[1] & 0xF0) >> 4));
+    obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \
+                               ((ibuf[2] & 0xC0) >> 6));
+    obuf[3] = (unsigned char)   (ibuf[2] & 0x3F);
 
     switch(inputparts) {
     case 1: /* only one byte read */
@@ -183,6 +230,10 @@
   *output=0;
   *outptr = base64data; /* make it return the actual data memory */
 
+#ifdef CURL_DOES_CONVERSIONS
+  if(data)
+    free(convbuf);
+#endif
   return strlen(base64data); /* return the length of the new data */
 }
 /* ---- End of Base64 Encoding ---- */
@@ -205,14 +256,26 @@
   size_t base64Len;
   unsigned char *data;
   int dataLen;
+  struct SessionHandle *handle = NULL;
 
+#ifdef CURL_DOES_CONVERSIONS
+  /* get a Curl handle so Curl_base64_encode can translate properly */
+  handle = curl_easy_init();
+  if(handle == NULL) {
+    fprintf(stderr, "Error: curl_easy_init failed\n");
+    return 0;
+  }
+#endif
   data = (unsigned char *)suck(&dataLen);
-  base64Len = Curl_base64_encode(data, dataLen, &base64);
+  base64Len = Curl_base64_encode(handle, data, dataLen, &base64);
 
   fprintf(stderr, "%d\n", base64Len);
-  fprintf(stdout, "%s",   base64);
+  fprintf(stdout, "%s\n", base64);
 
   free(base64); free(data);
+#ifdef CURL_DOES_CONVERSIONS
+  curl_easy_cleanup(handle);
+#endif
   return 0;
 }
 #endif
@@ -235,10 +298,17 @@
   unsigned char *data;
   int dataLen;
   int i, j;
+#ifdef CURL_DOES_CONVERSIONS
+  /* get a Curl handle so main can translate properly */
+  struct SessionHandle *handle = curl_easy_init();
+  if(handle == NULL) {
+    fprintf(stderr, "Error: curl_easy_init failed\n");
+    return 0;
+  }
+#endif
 
   base64 = (char *)suck(&base64Len);
-  data = (unsigned char *)malloc(base64Len * 3/4 + 8);
-  dataLen = Curl_base64_decode(base64, data);
+  dataLen = Curl_base64_decode(base64, &data);
 
   fprintf(stderr, "%d\n", dataLen);
 
@@ -253,13 +323,21 @@
     printf(" | ");
 
     for(j=0; j < 0x10; j++)
-      if((j+i) < dataLen)
-        printf("%c", isgraph(data[i+j])?data[i+j]:'.');
-      else
+      if((j+i) < dataLen) {
+#ifdef CURL_DOES_CONVERSIONS
+        if(CURLE_OK !=
+             Curl_convert_from_network(handle, &data[i+j], (size_t)1))
+          data[i+j] = '.';
+#endif /* CURL_DOES_CONVERSIONS */
+        printf("%c", ISGRAPH(data[i+j])?data[i+j]:'.');
+      } else
         break;
     puts("");
   }
 
+#ifdef CURL_DOES_CONVERSIONS
+  curl_easy_cleanup(handle);
+#endif
   free(base64); free(data);
   return 0;
 }

--- NEW FILE: tftp.h ---
#ifndef __TFTP_H
#define __TFTP_H

/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: tftp.h,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/
#ifndef CURL_DISABLE_TFTP
CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done);
CURLcode Curl_tftp(struct connectdata *conn, bool *done);
CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode, bool premature);
#endif
#endif

--- getdate.h DELETED ---

Index: CMakeLists.txt
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/CMakeLists.txt,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- CMakeLists.txt	4 Dec 2006 22:26:40 -0000	1.10
+++ CMakeLists.txt	15 Mar 2007 19:22:13 -0000	1.11
@@ -5,7 +5,7 @@
 
 # Setup package meta-data
 SET(PACKAGE "curl")
-SET(VERSION "7.12.1")
+SET(VERSION "7.16.1")
 SET(PACKAGE_TARNAME "curl")
 SET(PACKAGE_BUGREPORT " ")
 SET(PACKAGE_NAME "curl")
@@ -38,6 +38,7 @@
 INCLUDE (CheckTypeSize)
 
 SET(libCurl_SRCS
+  #  amigaos.c - does not build on AmigaOS
   base64.c
   connect.c
   content_encoding.c
@@ -48,15 +49,15 @@
   file.c
   formdata.c
   ftp.c
-  getdate.c
   getenv.c
   getinfo.c
+  gtls.c
   hash.c
   hostares.c
   hostasyn.c
-  hostip.c
   hostip4.c
   hostip6.c
+  hostip.c
   hostsyn.c
   hostthre.c
   http.c
@@ -68,20 +69,33 @@
   inet_ntop.c
   inet_pton.c
   krb4.c
+  ldap.c
   llist.c
   md5.c
   memdebug.c
   mprintf.c
   multi.c
   netrc.c
+  # nwlib.c - Not used
+  parsedate.c
   progress.c
+  security.c
+  select.c
   sendf.c
   share.c
+  socks.c
   speedcheck.c
+  splay.c
+  ssh.c
+  sslgen.c
   ssluse.c
+  strdup.c
   strequal.c
   strerror.c
+  # strtok.c - specify later
+  strtoofft.c
   telnet.c
+  tftp.c
   timeval.c
   transfer.c
   url.c
@@ -152,13 +166,16 @@
   CHECK_LIBRARY_EXISTS_CONCAT("z"      inflateEnd   HAVE_LIBZ)
 ENDIF(NOT CURL_SPECIAL_LIBZ)
 
-#OPTION(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" OFF)
+OPTION(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ON)
 MARK_AS_ADVANCED(CMAKE_USE_OPENSSL)
 IF(CMAKE_USE_OPENSSL)
   CHECK_LIBRARY_EXISTS_CONCAT("crypto" CRYPTO_lock  HAVE_LIBCRYPTO)
   CHECK_LIBRARY_EXISTS_CONCAT("ssl"    SSL_connect  HAVE_LIBSSL)
 ENDIF(CMAKE_USE_OPENSSL)
 
+# Check for idn
+CHECK_LIBRARY_EXISTS_CONCAT("idn" idna_to_ascii_lz HAVE_LIBIDN)
+
 # Check for symbol dlopen (same as HAVE_LIBDL)
 CHECK_LIBRARY_EXISTS("${CURL_LIBS}" dlopen "" HAVE_DLOPEN)
 
@@ -202,7 +219,11 @@
 ENDMACRO(CHECK_INCLUDE_FILE_CONCAT)
 
 # Check for header files
+CHECK_INCLUDE_FILE_CONCAT("ws2tcpip.h"       HAVE_WS2TCPIP_H)
+CHECK_INCLUDE_FILE_CONCAT("winsock2.h"       HAVE_WINSOCK2_H)
 CHECK_INCLUDE_FILE_CONCAT("stdio.h"          HAVE_STDIO_H)
+CHECK_INCLUDE_FILE_CONCAT("windows.h"        HAVE_WINDOWS_H)
+CHECK_INCLUDE_FILE_CONCAT("winsock.h"        HAVE_WINSOCK_H)
 CHECK_INCLUDE_FILE_CONCAT("stddef.h"         HAVE_STDDEF_H)
 CHECK_INCLUDE_FILE_CONCAT("sys/types.h"      HAVE_SYS_TYPES_H)
 CHECK_INCLUDE_FILE_CONCAT("inttypes.h"       HAVE_INTTYPES_H)
@@ -226,6 +247,7 @@
   CHECK_INCLUDE_FILE_CONCAT("openssl/ssl.h"    HAVE_OPENSSL_SSL_H)
   CHECK_INCLUDE_FILE_CONCAT("openssl/err.h"    HAVE_OPENSSL_ERR_H)
   CHECK_INCLUDE_FILE_CONCAT("openssl/rand.h"   HAVE_OPENSSL_RAND_H)
+  CHECK_INCLUDE_FILE_CONCAT("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
 ENDIF(CMAKE_USE_OPENSSL)
 
 IF(NOT CURL_SPECIAL_LIBZ)
@@ -250,26 +272,35 @@
 CHECK_INCLUDE_FILE_CONCAT("sys/param.h"     HAVE_SYS_PARAM_H)
 CHECK_INCLUDE_FILE_CONCAT("sys/stat.h"      HAVE_SYS_STAT_H)
 CHECK_INCLUDE_FILE_CONCAT("sys/time.h"      HAVE_SYS_TIME_H)
+CHECK_INCLUDE_FILE_CONCAT("sys/resource.h"  HAVE_SYS_RESOURCE_H)
 CHECK_INCLUDE_FILE_CONCAT("termios.h"       HAVE_TERMIOS_H)
 CHECK_INCLUDE_FILE_CONCAT("termio.h"        HAVE_TERMIO_H)
 CHECK_INCLUDE_FILE_CONCAT("io.h"            HAVE_IO_H)
 CHECK_INCLUDE_FILE_CONCAT("time.h"          HAVE_TIME_H)
 CHECK_INCLUDE_FILE_CONCAT("unistd.h"        HAVE_UNISTD_H)
 CHECK_INCLUDE_FILE_CONCAT("sys/utime.h"     HAVE_SYS_UTIME_H)
-CHECK_INCLUDE_FILE_CONCAT("winsock.h"       HAVE_WINSOCK_H)
 CHECK_INCLUDE_FILE_CONCAT("sockio.h"        HAVE_SOCKIO_H)
 CHECK_INCLUDE_FILE_CONCAT("sys/sockio.h"    HAVE_SYS_SOCKIO_H)
 CHECK_INCLUDE_FILE_CONCAT("x509.h"          HAVE_X509_H)
+CHECK_INCLUDE_FILE_CONCAT("locale.h"        HAVE_LOCALE_H)
 CHECK_INCLUDE_FILE_CONCAT("setjmp.h"        HAVE_SETJMP_H)
 CHECK_INCLUDE_FILE_CONCAT("signal.h"        HAVE_SIGNAL_H)
 CHECK_INCLUDE_FILE_CONCAT("sys/ioctl.h"     HAVE_SYS_IOCTL_H)
 CHECK_INCLUDE_FILE_CONCAT("sys/utsname.h"   HAVE_SYS_UTSNAME_H)
+CHECK_INCLUDE_FILE_CONCAT("idn-free.h"      HAVE_IDN_FREE_H)
+CHECK_INCLUDE_FILE_CONCAT("idna.h"          HAVE_IDNA_H)
+CHECK_INCLUDE_FILE_CONCAT("tld.h"           HAVE_TLD_H)
+CHECK_INCLUDE_FILE_CONCAT("arpa/tftp.h"     HAVE_ARPA_TFTP_H)
+CHECK_INCLUDE_FILE_CONCAT("errno.h"         HAVE_ERRNO_H)
+CHECK_INCLUDE_FILE_CONCAT("libgen.h"        HAVE_LIBGEN_H)
+CHECK_INCLUDE_FILE_CONCAT("sys/filio.h"     HAVE_SYS_FILIO_H)
 CHECK_TYPE_SIZE(size_t  SIZEOF_SIZE_T)
 CHECK_TYPE_SIZE(ssize_t  SIZEOF_SSIZE_T)
 CHECK_TYPE_SIZE("long long"  SIZEOF_LONG_LONG)
 CHECK_TYPE_SIZE("long"  SIZEOF_LONG)
 CHECK_TYPE_SIZE("__int64"  SIZEOF___INT64)
 CHECK_TYPE_SIZE("long double"  SIZEOF_LONG_DOUBLE)
+CHECK_TYPE_SIZE("time_t"  SIZEOF_TIME_T)
 IF(NOT HAVE_SIZEOF_SSIZE_T)
   IF(SIZEOF_LONG EQUAL SIZEOF_SIZE_T)
     SET(ssize_t long)
@@ -281,11 +312,49 @@
 
 IF(HAVE_SIZEOF_LONG_LONG)
   SET(HAVE_LONGLONG 1)
+  SET(HAVE_LL 1)
 ENDIF(HAVE_SIZEOF_LONG_LONG)
 
 FIND_FILE(RANDOM_FILE urandom /dev)
 MARK_AS_ADVANCED(RANDOM_FILE)
 
+#strtoll \
+#socket \
+#select \
+#strdup \
+#strstr \
+#strtok_r \
+#uname \
+#strcasecmp \
+#stricmp \
+#strcmpi \
+#gethostbyaddr \
+#gettimeofday \
+#inet_addr \
+#inet_ntoa \
+#inet_pton \
+#perror \
+#closesocket \
+#siginterrupt \
+#sigaction \
+#signal \
+#getpass_r \
+#strlcat \
+#getpwuid \
+#geteuid \
+#dlopen \
+#utime \
+#sigsetjmp \
+#basename \
+#setlocale \
+#ftruncate \
+#pipe \
+#poll \
+#getprotobyname \
+#getrlimit \
+#setrlimit \
+#fork
+
 # Check for some functions that are used
 CHECK_SYMBOL_EXISTS(socket        "${CURL_INCLUDES}" HAVE_SOCKET)
 CHECK_SYMBOL_EXISTS(poll          "${CURL_INCLUDES}" HAVE_POLL)
@@ -338,12 +407,22 @@
 IF(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
   SET(HAVE_SIGNAL 1)
 ENDIF(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
-CHECK_SYMBOL_EXISTS(uname         "${CURL_INCLUDES}" HAVE_UNAME)
-CHECK_SYMBOL_EXISTS(strtoll       "${CURL_INCLUDES}" HAVE_STRTOLL)
-CHECK_SYMBOL_EXISTS(_strtoi64     "${CURL_INCLUDES}" HAVE__STRTOI64)
-CHECK_SYMBOL_EXISTS(strerror_r    "${CURL_INCLUDES}" HAVE_STRERROR_R)
-CHECK_SYMBOL_EXISTS(siginterrupt  "${CURL_INCLUDES}" HAVE_SIGINTERRUPT)
-CHECK_SYMBOL_EXISTS(perror        "${CURL_INCLUDES}" HAVE_PERROR)
+CHECK_SYMBOL_EXISTS(uname          "${CURL_INCLUDES}" HAVE_UNAME)
+CHECK_SYMBOL_EXISTS(strtoll        "${CURL_INCLUDES}" HAVE_STRTOLL)
+CHECK_SYMBOL_EXISTS(_strtoi64      "${CURL_INCLUDES}" HAVE__STRTOI64)
+CHECK_SYMBOL_EXISTS(strerror_r     "${CURL_INCLUDES}" HAVE_STRERROR_R)
+CHECK_SYMBOL_EXISTS(siginterrupt   "${CURL_INCLUDES}" HAVE_SIGINTERRUPT)
+CHECK_SYMBOL_EXISTS(perror         "${CURL_INCLUDES}" HAVE_PERROR)
+CHECK_SYMBOL_EXISTS(fork           "${CURL_INCLUDES}" HAVE_FORK)
+CHECK_SYMBOL_EXISTS(pipe           "${CURL_INCLUDES}" HAVE_PIPE)
+CHECK_SYMBOL_EXISTS(ftruncate      "${CURL_INCLUDES}" HAVE_FTRUNCATE)
+CHECK_SYMBOL_EXISTS(getprotobyname "${CURL_INCLUDES}" HAVE_GETPROTOBYNAME)
+CHECK_SYMBOL_EXISTS(getrlimit      "${CURL_INCLUDES}" HAVE_GETRLIMIT)
+CHECK_SYMBOL_EXISTS(idn_free       "${CURL_INCLUDES}" HAVE_IDN_FREE)
+CHECK_SYMBOL_EXISTS(idna_strerror  "${CURL_INCLUDES}" HAVE_IDNA_STRERROR)
+CHECK_SYMBOL_EXISTS(tld_strerror   "${CURL_INCLUDES}" HAVE_TLD_STRERROR)
+CHECK_SYMBOL_EXISTS(setlocale      "${CURL_INCLUDES}" HAVE_SETLOCALE)
+CHECK_SYMBOL_EXISTS(setrlimit      "${CURL_INCLUDES}" HAVE_SETRLIMIT)
 
 # only build compat strtok if we need to
 IF (NOT HAVE_STRTOK_R)
@@ -588,11 +667,14 @@
     COMPILE_FLAGS ${MPRINTF_COMPILE_FLAGS})
 ENDIF(CMAKE_COMPILER_IS_GNUCC AND APPLE)
 
+INCLUDE(CMake/OtherTests.cmake)
+
 # The rest of the build
 
 INCLUDE_DIRECTORIES(${LIBCURL_SOURCE_DIR})
 INCLUDE_DIRECTORIES(${LIBCURL_BINARY_DIR})
-ADD_DEFINITIONS(-DHAVE_CONFIG_H)
+ADD_DEFINITIONS(-DHAVE_CONFIG_H
+  -DCURL_STATICLIB)
 CONFIGURE_FILE(${LIBCURL_SOURCE_DIR}/config.h.in
   ${LIBCURL_BINARY_DIR}/config.h)
 

--- NEW FILE: sslgen.c ---
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: sslgen.c,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

/* This file is for "generic" SSL functions that all libcurl internals should
   use. It is responsible for calling the proper 'ossl' function in ssluse.c
   (OpenSSL based) or the 'gtls' function in gtls.c (GnuTLS based).

   SSL-functions in libcurl should call functions in this source file, and not
   to any specific SSL-layer.

   Curl_ssl_ - prefix for generic ones
   Curl_ossl_ - prefix for OpenSSL ones
   Curl_gtls_ - prefix for GnuTLS ones

   "SSL/TLS Strong Encryption: An Introduction"
   http://httpd.apache.org/docs-2.0/ssl/ssl_intro.html
*/

#include "setup.h"
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif

#include "urldata.h"
#define SSLGEN_C
#include "sslgen.h" /* generic SSL protos etc */
#include "ssluse.h" /* OpenSSL versions */
#include "gtls.h"   /* GnuTLS versions */
#include "sendf.h"
#include "strequal.h"
#include "url.h"
#include "memory.h"
/* The last #include file should be: */
#include "memdebug.h"

/* "global" init done? */
static bool init_ssl=FALSE;

static bool safe_strequal(char* str1, char* str2);

static bool safe_strequal(char* str1, char* str2)
{
  if(str1 && str2)
    /* both pointers point to something then compare them */
    return (bool)(0 != strequal(str1, str2));
  else
    /* if both pointers are NULL then treat them as equal */
    return (bool)(!str1 && !str2);
}

bool
Curl_ssl_config_matches(struct ssl_config_data* data,
                        struct ssl_config_data* needle)
{
  if((data->version == needle->version) &&
     (data->verifypeer == needle->verifypeer) &&
     (data->verifyhost == needle->verifyhost) &&
     safe_strequal(data->CApath, needle->CApath) &&
     safe_strequal(data->CAfile, needle->CAfile) &&
     safe_strequal(data->random_file, needle->random_file) &&
     safe_strequal(data->egdsocket, needle->egdsocket) &&
     safe_strequal(data->cipher_list, needle->cipher_list))
    return TRUE;

  return FALSE;
}

bool
Curl_clone_ssl_config(struct ssl_config_data *source,
                      struct ssl_config_data *dest)
{
  dest->verifyhost = source->verifyhost;
  dest->verifypeer = source->verifypeer;
  dest->version = source->version;

  if(source->CAfile) {
    dest->CAfile = strdup(source->CAfile);
    if(!dest->CAfile)
      return FALSE;
  }

  if(source->CApath) {
    dest->CApath = strdup(source->CApath);
    if(!dest->CApath)
      return FALSE;
  }

  if(source->cipher_list) {
    dest->cipher_list = strdup(source->cipher_list);
    if(!dest->cipher_list)
      return FALSE;
  }

  if(source->egdsocket) {
    dest->egdsocket = strdup(source->egdsocket);
    if(!dest->egdsocket)
      return FALSE;
  }

  if(source->random_file) {
    dest->random_file = strdup(source->random_file);
    if(!dest->random_file)
      return FALSE;
  }

  return TRUE;
}

void Curl_free_ssl_config(struct ssl_config_data* sslc)
{
  if(sslc->CAfile)
    free(sslc->CAfile);

  if(sslc->CApath)
    free(sslc->CApath);

  if(sslc->cipher_list)
    free(sslc->cipher_list);

  if(sslc->egdsocket)
    free(sslc->egdsocket);

  if(sslc->random_file)
    free(sslc->random_file);
}

/**
 * Global SSL init
 *
 * @retval 0 error initializing SSL
 * @retval 1 SSL initialized successfully
 */
int Curl_ssl_init(void)
{
  /* make sure this is only done once */
  if(init_ssl)
    return 1;
  init_ssl = TRUE; /* never again */

#ifdef USE_SSLEAY
  return Curl_ossl_init();
#else
#ifdef USE_GNUTLS
  return Curl_gtls_init();
#else
  /* no SSL support */
  return 1;
#endif /* USE_GNUTLS */
#endif /* USE_SSLEAY */
}


/* Global cleanup */
void Curl_ssl_cleanup(void)
{
  if(init_ssl) {
    /* only cleanup if we did a previous init */
#ifdef USE_SSLEAY
    Curl_ossl_cleanup();
#else
#ifdef USE_GNUTLS
    Curl_gtls_cleanup();
#endif /* USE_GNUTLS */
#endif /* USE_SSLEAY */
    init_ssl = FALSE;
  }
}

CURLcode
Curl_ssl_connect(struct connectdata *conn, int sockindex)
{
#ifdef USE_SSL
  /* mark this is being ssl enabled from here on. */
  conn->ssl[sockindex].use = TRUE;

#ifdef USE_SSLEAY
  return Curl_ossl_connect(conn, sockindex);
#else
#ifdef USE_GNUTLS
  return Curl_gtls_connect(conn, sockindex);
#endif /* USE_GNUTLS */
#endif /* USE_SSLEAY */

#else
  /* without SSL */
  (void)conn;
  (void)sockindex;
  return CURLE_OK;
#endif /* USE_SSL */
}

CURLcode
Curl_ssl_connect_nonblocking(struct connectdata *conn, int sockindex,
                             bool *done)
{
#if defined(USE_SSL) && defined(USE_SSLEAY)
  /* mark this is being ssl enabled from here on. */
  conn->ssl[sockindex].use = TRUE;
  return Curl_ossl_connect_nonblocking(conn, sockindex, done);

#else
  /* not implemented!
     fallback to BLOCKING call. */
  *done = TRUE;
  return Curl_ssl_connect(conn, sockindex);
#endif
}

#ifdef USE_SSL

/*
 * Check if there's a session ID for the given connection in the cache, and if
 * there's one suitable, it is provided. Returns TRUE when no entry matched.
 */
int Curl_ssl_getsessionid(struct connectdata *conn,
                          void **ssl_sessionid,
                          size_t *idsize) /* set 0 if unknown */
{
  struct curl_ssl_session *check;
  struct SessionHandle *data = conn->data;
  long i;

  if(!conn->ssl_config.sessionid)
    /* session ID re-use is disabled */
    return TRUE;

  for(i=0; i< data->set.ssl.numsessions; i++) {
    check = &data->state.session[i];
    if(!check->sessionid)
      /* not session ID means blank entry */
      continue;
    if(curl_strequal(conn->host.name, check->name) &&
       (conn->remote_port == check->remote_port) &&
       Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) {
      /* yes, we have a session ID! */
      data->state.sessionage++;            /* increase general age */
      check->age = data->state.sessionage; /* set this as used in this age */
      *ssl_sessionid = check->sessionid;
      if(idsize)
        *idsize = check->idsize;
      return FALSE;
    }
  }
  *ssl_sessionid = NULL;
  return TRUE;
}

/*
 * Kill a single session ID entry in the cache.
 */
static int kill_session(struct curl_ssl_session *session)
{
  if(session->sessionid) {
    /* defensive check */

    /* free the ID the SSL-layer specific way */
#ifdef USE_SSLEAY
    Curl_ossl_session_free(session->sessionid);
#else
    Curl_gtls_session_free(session->sessionid);
#endif
    session->sessionid=NULL;
    session->age = 0; /* fresh */

    Curl_free_ssl_config(&session->ssl_config);

    Curl_safefree(session->name);
    session->name = NULL; /* no name */

    return 0; /* ok */
  }
  else
    return 1;
}

/*
 * Store session id in the session cache. The ID passed on to this function
 * must already have been extracted and allocated the proper way for the SSL
 * layer. Curl_XXXX_session_free() will be called to free/kill the session ID
 * later on.
 */
CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
                               void *ssl_sessionid,
                               size_t idsize)
{
  int i;
  struct SessionHandle *data=conn->data; /* the mother of all structs */
  struct curl_ssl_session *store = &data->state.session[0];
  long oldest_age=data->state.session[0].age; /* zero if unused */
  char *clone_host;

  /* Even though session ID re-use might be disabled, that only disables USING
     IT. We still store it here in case the re-using is again enabled for an
     upcoming transfer */

  clone_host = strdup(conn->host.name);
  if(!clone_host)
    return CURLE_OUT_OF_MEMORY; /* bail out */

  /* Now we should add the session ID and the host name to the cache, (remove
     the oldest if necessary) */

  /* find an empty slot for us, or find the oldest */
  for(i=1; (i<data->set.ssl.numsessions) &&
        data->state.session[i].sessionid; i++) {
    if(data->state.session[i].age < oldest_age) {
      oldest_age = data->state.session[i].age;
      store = &data->state.session[i];
    }
  }
  if(i == data->set.ssl.numsessions)
    /* cache is full, we must "kill" the oldest entry! */
    kill_session(store);
  else
    store = &data->state.session[i]; /* use this slot */

  /* now init the session struct wisely */
  store->sessionid = ssl_sessionid;
  store->idsize = idsize;
  store->age = data->state.sessionage;    /* set current age */
  store->name = clone_host;               /* clone host name */
  store->remote_port = conn->remote_port; /* port number */

  if (!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config))
    return CURLE_OUT_OF_MEMORY;

  return CURLE_OK;
}


#endif

void Curl_ssl_close_all(struct SessionHandle *data)
{
#ifdef USE_SSL
  int i;
  /* kill the session ID cache */
  if(data->state.session) {
    for(i=0; i< data->set.ssl.numsessions; i++)
      /* the single-killer function handles empty table slots */
      kill_session(&data->state.session[i]);

    /* free the cache data */
    free(data->state.session);
    data->state.session = NULL;
  }
#ifdef USE_SSLEAY
  Curl_ossl_close_all(data);
#else
#ifdef USE_GNUTLS
  Curl_gtls_close_all(data);
#endif /* USE_GNUTLS */
#endif /* USE_SSLEAY */
#else /* USE_SSL */
  (void)data;
#endif /* USE_SSL */
}

void Curl_ssl_close(struct connectdata *conn)
{
  if(conn->ssl[FIRSTSOCKET].use) {
#ifdef USE_SSLEAY
    Curl_ossl_close(conn);
#else
#ifdef USE_GNUTLS
    Curl_gtls_close(conn);
#else
  (void)conn;
#endif /* USE_GNUTLS */
#endif /* USE_SSLEAY */
  }
}

CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex)
{
  if(conn->ssl[sockindex].use) {
#ifdef USE_SSLEAY
    if(Curl_ossl_shutdown(conn, sockindex))
      return CURLE_SSL_SHUTDOWN_FAILED;
#else
#ifdef USE_GNUTLS
    if(Curl_gtls_shutdown(conn, sockindex))
      return CURLE_SSL_SHUTDOWN_FAILED;
#else
    (void)conn;
    (void)sockindex;
#endif /* USE_GNUTLS */
#endif /* USE_SSLEAY */
  }
  return CURLE_OK;
}

/* Selects an (Open)SSL crypto engine
 */
CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine)
{
#ifdef USE_SSLEAY
  return Curl_ossl_set_engine(data, engine);
#else
#ifdef USE_GNUTLS
  /* FIX: add code here */
  (void)data;
  (void)engine;
  return CURLE_FAILED_INIT;
#else
  /* no SSL layer */
  (void)data;
  (void)engine;
  return CURLE_FAILED_INIT;
#endif /* USE_GNUTLS */
#endif /* USE_SSLEAY */
}

/* Selects an (Open?)SSL crypto engine
 */
CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data)
{
#ifdef USE_SSLEAY
  return Curl_ossl_set_engine_default(data);
#else
#ifdef USE_GNUTLS
  /* FIX: add code here */
  (void)data;
  return CURLE_FAILED_INIT;
#else
  /* No SSL layer */
  (void)data;
  return CURLE_FAILED_INIT;
#endif /* USE_GNUTLS */
#endif /* USE_SSLEAY */
}

/* Return list of OpenSSL crypto engine names. */
struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data)
{
#ifdef USE_SSLEAY
  return Curl_ossl_engines_list(data);
#else
#ifdef USE_GNUTLS
  /* FIX: add code here? */
  (void)data;
  return NULL;
#else
  (void)data;
  return NULL;
#endif /* USE_GNUTLS */
#endif /* USE_SSLEAY */
}

/* return number of sent (non-SSL) bytes */
ssize_t Curl_ssl_send(struct connectdata *conn,
                      int sockindex,
                      void *mem,
                      size_t len)
{
#ifdef USE_SSLEAY
  return Curl_ossl_send(conn, sockindex, mem, len);
#else
#ifdef USE_GNUTLS
  return Curl_gtls_send(conn, sockindex, mem, len);
#else
  (void)conn;
  (void)sockindex;
  (void)mem;
  (void)len;
  return 0;
#endif /* USE_GNUTLS */
#endif /* USE_SSLEAY */
}

/* return number of received (decrypted) bytes */

/*
 * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
 * a regular CURLcode value.
 */
ssize_t Curl_ssl_recv(struct connectdata *conn, /* connection data */
                      int sockindex,            /* socketindex */
                      char *mem,                /* store read data here */
                      size_t len)               /* max amount to read */
{
#ifdef USE_SSL
  ssize_t nread;
  bool block = FALSE;

#ifdef USE_SSLEAY
  nread = Curl_ossl_recv(conn, sockindex, mem, len, &block);
#else
#ifdef USE_GNUTLS
  nread = Curl_gtls_recv(conn, sockindex, mem, len, &block);
#endif /* USE_GNUTLS */
#endif /* USE_SSLEAY */
  if(nread == -1) {
    if(!block)
      return 0; /* this is a true error, not EWOULDBLOCK */
    else
      return -1;
  }

  return (int)nread;

#else /* USE_SSL */
  (void)conn;
  (void)sockindex;
  (void)mem;
  (void)len;
  return 0;
#endif /* USE_SSL */
}


/*
 * This sets up a session ID cache to the specified size. Make sure this code
 * is agnostic to what underlying SSL technology we use.
 */
CURLcode Curl_ssl_initsessions(struct SessionHandle *data, long amount)
{
#ifdef USE_SSL
  struct curl_ssl_session *session;

  if(data->state.session)
    /* this is just a precaution to prevent multiple inits */
    return CURLE_OK;

  session = (struct curl_ssl_session *)
    calloc(sizeof(struct curl_ssl_session), amount);
  if(!session)
    return CURLE_OUT_OF_MEMORY;

  /* store the info in the SSL section */
  data->set.ssl.numsessions = amount;
  data->state.session = session;
  data->state.sessionage = 1; /* this is brand new */
#else
  /* without SSL, do nothing */
  (void)data;
  (void)amount;
#endif

  return CURLE_OK;
}

size_t Curl_ssl_version(char *buffer, size_t size)
{
#ifdef USE_SSLEAY
  return Curl_ossl_version(buffer, size);
#else
#ifdef USE_GNUTLS
  return Curl_gtls_version(buffer, size);
#else
  (void)buffer;
  (void)size;
  return 0; /* no SSL support */
#endif /* USE_GNUTLS */
#endif /* USE_SSLEAY */
}


/*
 * This function tries to determine connection status.
 *
 * Return codes:
 *     1 means the connection is still in place
 *     0 means the connection has been closed
 *    -1 means the connection status is unknown
 */
int Curl_ssl_check_cxn(struct connectdata *conn)
{
#ifdef USE_SSLEAY
  return Curl_ossl_check_cxn(conn);
#else
  (void)conn;
  /* TODO: we lack implementation of this for GnuTLS */
  return -1; /* connection status unknown */
#endif /* USE_SSLEAY */
}

bool Curl_ssl_data_pending(struct connectdata *conn,
                           int connindex)
{
#ifdef USE_SSLEAY
  /* OpenSSL-specific */
  if(conn->ssl[connindex].handle)
    /* SSL is in use */
    return SSL_pending(conn->ssl[connindex].handle);
#else
  (void)conn;
  (void)connindex;
#endif
  return FALSE; /* nothing pending */

}

--- NEW FILE: splay.c ---
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1997 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: splay.c,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

#include <stdio.h>
#include <stdlib.h>

#include "splay.h"

#define compare(i,j) ((i)-(j))

/* Set this to a key value that will *NEVER* appear otherwise */
#define KEY_NOTUSED -1

/*
 * Splay using the key i (which may or may not be in the tree.) The starting
 * root is t.
 */
struct Curl_tree *Curl_splay(int i, struct Curl_tree *t)
{
  struct Curl_tree N, *l, *r, *y;
  int comp;

  if (t == NULL)
    return t;
  N.smaller = N.larger = NULL;
  l = r = &N;

  for (;;) {
    comp = compare(i, t->key);
    if (comp < 0) {
      if (t->smaller == NULL)
        break;
      if (compare(i, t->smaller->key) < 0) {
        y = t->smaller;                           /* rotate smaller */
        t->smaller = y->larger;
        y->larger = t;
        t = y;
        if (t->smaller == NULL)
          break;
      }
      r->smaller = t;                               /* link smaller */
      r = t;
      t = t->smaller;
    }
    else if (comp > 0) {
      if (t->larger == NULL)
        break;
      if (compare(i, t->larger->key) > 0) {
        y = t->larger;                          /* rotate larger */
        t->larger = y->smaller;
        y->smaller = t;
        t = y;
        if (t->larger == NULL)
          break;
      }
      l->larger = t;                              /* link larger */
      l = t;
      t = t->larger;
    }
    else
      break;
  }

  l->larger = t->smaller;                                /* assemble */
  r->smaller = t->larger;
  t->smaller = N.larger;
  t->larger = N.smaller;

  return t;
}

/* Insert key i into the tree t.  Return a pointer to the resulting tree or
   NULL if something went wrong. */
struct Curl_tree *Curl_splayinsert(int i,
                                   struct Curl_tree *t,
                                   struct Curl_tree *node)
{
  if (node == NULL)
    return t;

  if (t != NULL) {
    t = Curl_splay(i,t);
    if (compare(i, t->key)==0) {
      /* There already exists a node in the tree with the very same key. Build
         a linked list of nodes. We make the new 'node' struct the new master
         node and make the previous node the first one in the 'same' list. */

      node->same = t;
      node->key = i;
      node->smaller = t->smaller;
      node->larger = t->larger;

      t->smaller = node; /* in the sub node for this same key, we use the
                            smaller pointer to point back to the master
                            node */

      t->key = KEY_NOTUSED; /* and we set the key in the sub node to NOTUSED
                               to quickly identify this node as a subnode */

      return node; /* new root node */
    }
  }

  if (t == NULL) {
    node->smaller = node->larger = NULL;
  }
  else if (compare(i, t->key) < 0) {
    node->smaller = t->smaller;
    node->larger = t;
    t->smaller = NULL;

  }
  else {
    node->larger = t->larger;
    node->smaller = t;
    t->larger = NULL;
  }
  node->key = i;

  node->same = NULL; /* no identical node (yet) */
  return node;
}

#if 0
/* Deletes 'i' from the tree if it's there (with an exact match). Returns a
   pointer to the resulting tree.

   Function not used in libcurl.
*/
struct Curl_tree *Curl_splayremove(int i, struct Curl_tree *t,
                                   struct Curl_tree **removed)
{
  struct Curl_tree *x;

  *removed = NULL; /* default to no removed */

  if (t==NULL)
    return NULL;

  t = Curl_splay(i,t);
  if (compare(i, t->key) == 0) {               /* found it */

    /* FIRST! Check if there is a list with identical sizes */
    if((x = t->same)) {
      /* there is, pick one from the list */

      /* 'x' is the new root node */

      x->key = t->key;
      x->larger = t->larger;
      x->smaller = t->smaller;

      *removed = t;
      return x; /* new root */
    }

    if (t->smaller == NULL) {
      x = t->larger;
    }
    else {
      x = Curl_splay(i, t->smaller);
      x->larger = t->larger;
    }
    *removed = t;

    return x;
  }
  else
    return t;                         /* It wasn't there */
}
#endif

/* Finds and deletes the best-fit node from the tree. Return a pointer to the
   resulting tree.  best-fit means the node with the given or lower number */
struct Curl_tree *Curl_splaygetbest(int i, struct Curl_tree *t,
                                    struct Curl_tree **removed)
{
  struct Curl_tree *x;

  if (!t) {
    *removed = NULL; /* none removed since there was no root */
    return NULL;
  }

  t = Curl_splay(i,t);
  if(compare(i, t->key) < 0) {
    /* too big node, try the smaller chain */
    if(t->smaller)
      t=Curl_splay(t->smaller->key, t);
    else {
      /* fail */
      *removed = NULL;
      return t;
    }
  }

  if (compare(i, t->key) >= 0) {               /* found it */
    /* FIRST! Check if there is a list with identical sizes */
    x = t->same;
    if(x) {
      /* there is, pick one from the list */

      /* 'x' is the new root node */

      x->key = t->key;
      x->larger = t->larger;
      x->smaller = t->smaller;

      *removed = t;
      return x; /* new root */
    }

    if (t->smaller == NULL) {
      x = t->larger;
    }
    else {
      x = Curl_splay(i, t->smaller);
      x->larger = t->larger;
    }
    *removed = t;

    return x;
  }
  else {
    *removed = NULL; /* no match */
    return t;        /* It wasn't there */
  }
}


/* Deletes the very node we point out from the tree if it's there. Stores a
   pointer to the new resulting tree in 'newroot'.

   Returns zero on success and non-zero on errors! TODO: document error codes.
   When returning error, it does not touch the 'newroot' pointer.

   NOTE: when the last node of the tree is removed, there's no tree left so
   'newroot' will be made to point to NULL.
*/
int Curl_splayremovebyaddr(struct Curl_tree *t,
                           struct Curl_tree *remove,
                           struct Curl_tree **newroot)
{
  struct Curl_tree *x;

  if (!t || !remove)
    return 1;

  if(KEY_NOTUSED == remove->key) {
    /* Key set to NOTUSED means it is a subnode within a 'same' linked list
       and thus we can unlink it easily. The 'smaller' link of a subnode
       links to the parent node. */
    if (remove->smaller == NULL)
      return 3;

    remove->smaller->same = remove->same;
    if(remove->same)
      remove->same->smaller = remove->smaller;

    /* Ensures that double-remove gets caught. */
    remove->smaller = NULL;

    /* voila, we're done! */
    *newroot = t; /* return the same root */
    return 0;
  }

  t = Curl_splay(remove->key, t);

  /* First make sure that we got the same root node as the one we want
     to remove, as otherwise we might be trying to remove a node that
     isn't actually in the tree.

     We cannot just compare the keys here as a double remove in quick
     succession of a node with key != KEY_NOTUSED && same != NULL
     could return the same key but a different node. */
  if(t != remove)
    return 2;

  /* Check if there is a list with identical sizes, as then we're trying to
     remove the root node of a list of nodes with identical keys. */
  x = t->same;
  if(x) {
    /* 'x' is the new root node, we just make it use the root node's
       smaller/larger links */

    x->key = t->key;
    x->larger = t->larger;
    x->smaller = t->smaller;
  }
  else {
    /* Remove the root node */
    if (t->smaller == NULL)
      x = t->larger;
    else {
      x = Curl_splay(remove->key, t->smaller);
      x->larger = t->larger;
    }
  }

  *newroot = x; /* store new root pointer */

  return 0;
}

#ifdef CURLDEBUG

void Curl_splayprint(struct Curl_tree * t, int d, char output)
{
  struct Curl_tree *node;
  int i;
  int count;
  if (t == NULL)
    return;

  Curl_splayprint(t->larger, d+1, output);
  for (i=0; i<d; i++)
    if(output)
      printf("  ");

  if(output) {
    printf("%d[%d]", t->key, i);
  }

  for(count=0, node = t->same; node; node = node->same, count++)
    ;

  if(output) {
    if(count)
      printf(" [%d more]\n", count);
    else
      printf("\n");
  }

  Curl_splayprint(t->smaller, d+1, output);
}
#endif

#ifdef TEST_SPLAY

/*#define TEST2 */
#define MAX 50
#define TEST2

/* A sample use of these functions.  Start with the empty tree, insert some
   stuff into it, and then delete it */
int main(int argc, char **argv)
{
  struct Curl_tree *root, *t;
  void *ptrs[MAX];
  int adds=0;
  int rc;

  long sizes[]={
    50, 60, 50, 100, 60, 200, 120, 300, 400, 200, 256, 122, 60, 120, 200, 300,
    220, 80, 90, 50, 100, 60, 200, 120, 300, 400, 200, 256, 122, 60, 120, 200,
    300, 220, 80, 90, 50, 100, 60, 200, 120, 300, 400, 200, 256, 122, 60, 120,
    200, 300, 220, 80, 90};
  int i;
  root = NULL;              /* the empty tree */

  for (i = 0; i < MAX; i++) {
    int key;
    ptrs[i] = t = (struct Curl_tree *)malloc(sizeof(struct Curl_tree));

#ifdef TEST2
    key = sizes[i];
#elif defined(TEST1)
    key = (541*i)%1023;
#elif defined(TEST3)
    key = 100;
#endif

    t->payload = (void *)key; /* for simplicity */
    if(!t) {
      puts("out of memory!");
      return 0;
    }
    root = Curl_splayinsert(key, root, t);
  }

#if 0
  puts("Result:");
  Curl_splayprint(root, 0, 1);
#endif

#if 1
  for (i = 0; i < MAX; i++) {
    int rem = (i+7)%MAX;
    struct Curl_tree *r;
    printf("Tree look:\n");
    Curl_splayprint(root, 0, 1);
    printf("remove pointer %d, payload %d\n", rem,
           (int)((struct Curl_tree *)ptrs[rem])->payload);
    rc = Curl_splayremovebyaddr(root, (struct Curl_tree *)ptrs[rem], &root);
    if(rc)
      /* failed! */
      printf("remove %d failed!\n", rem);
  }
#endif

  return 0;
}

#endif /* TEST_SPLAY */

--- getdate.c DELETED ---

--- NEW FILE: tftp.c ---
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: tftp.c,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

#include "setup.h"

#ifndef CURL_DISABLE_TFTP
/* -- WIN32 approved -- */
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif

#if defined(WIN32)
#include <time.h>
#include <io.h>
#else
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#include <netinet/in.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <netdb.h>
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
#include <sys/ioctl.h>
#include <signal.h>

#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif


#endif

#include "urldata.h"
#include <curl/curl.h>
#include "transfer.h"
#include "sendf.h"
#include "tftp.h"
#include "progress.h"
#include "connect.h"
#include "strerror.h"
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
#include "url.h"

#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>

#include "memory.h"
#include "select.h"

/* The last #include file should be: */
#include "memdebug.h"

/* RFC2348 allows the block size to be negotiated, but we don't support that */
#define TFTP_BLOCKSIZE 512

typedef enum {
  TFTP_MODE_NETASCII=0,
  TFTP_MODE_OCTET
} tftp_mode_t;

typedef enum {
  TFTP_STATE_START=0,
  TFTP_STATE_RX,
  TFTP_STATE_TX,
  TFTP_STATE_FIN
} tftp_state_t;

typedef enum {
  TFTP_EVENT_INIT=0,
  TFTP_EVENT_RRQ = 1,
  TFTP_EVENT_WRQ = 2,
  TFTP_EVENT_DATA = 3,
  TFTP_EVENT_ACK = 4,
  TFTP_EVENT_ERROR = 5,
  TFTP_EVENT_TIMEOUT
} tftp_event_t;

typedef enum {
  TFTP_ERR_UNDEF=0,
  TFTP_ERR_NOTFOUND,
  TFTP_ERR_PERM,
  TFTP_ERR_DISKFULL,
  TFTP_ERR_ILLEGAL,
  TFTP_ERR_UNKNOWNID,
  TFTP_ERR_EXISTS,
  TFTP_ERR_NOSUCHUSER,
  TFTP_ERR_TIMEOUT,
  TFTP_ERR_NORESPONSE
} tftp_error_t;

typedef struct tftp_packet {
  unsigned char data[2 + 2 + TFTP_BLOCKSIZE];
} tftp_packet_t;

typedef struct tftp_state_data {
  tftp_state_t    state;
  tftp_mode_t     mode;
  tftp_error_t    error;
  struct connectdata      *conn;
  curl_socket_t   sockfd;
  int             retries;
  int             retry_time;
  int             retry_max;
  time_t          start_time;
  time_t          max_time;
  unsigned short  block;
  struct Curl_sockaddr_storage   local_addr;
  socklen_t       local_addrlen;
  struct Curl_sockaddr_storage   remote_addr;
  socklen_t       remote_addrlen;
  int             rbytes;
  int             sbytes;
  tftp_packet_t   rpacket;
  tftp_packet_t   spacket;
} tftp_state_data_t;


/* Forward declarations */
static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event) ;
static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event) ;
void tftp_set_timeouts(tftp_state_data_t *state) ;

/**********************************************************
 *
 * tftp_set_timeouts -
 *
 * Set timeouts based on state machine state.
 * Use user provided connect timeouts until DATA or ACK
 * packet is received, then use user-provided transfer timeouts
 *
 *
 **********************************************************/
void tftp_set_timeouts(tftp_state_data_t *state)
{

  struct SessionHandle *data = state->conn->data;
  time_t maxtime, timeout;

  time(&state->start_time);
  if(state->state == TFTP_STATE_START) {
    /* Compute drop-dead time */
    maxtime = (time_t)(data->set.connecttimeout?data->set.connecttimeout:30);
    state->max_time = state->start_time+maxtime;

    /* Set per-block timeout to total */
    timeout = maxtime ;

    /* Average restart after 5 seconds */
    state->retry_max = timeout/5;

    /* Compute the re-start interval to suit the timeout */
    state->retry_time = timeout/state->retry_max;
    if(state->retry_time<1)
      state->retry_time=1;

  }
  else {

    /* Compute drop-dead time */
    maxtime = (time_t)(data->set.timeout?data->set.timeout:3600);
    state->max_time = state->start_time+maxtime;

    /* Set per-block timeout to 10% of total */
    timeout = maxtime/10 ;

    /* Average reposting an ACK after 15 seconds */
    state->retry_max = timeout/15;
  }
  /* But bound the total number  */
  if(state->retry_max<3)
    state->retry_max=3;

  if(state->retry_max>50)
    state->retry_max=50;

  /* Compute the re-ACK interval to suit the timeout */
  state->retry_time = timeout/state->retry_max;
  if(state->retry_time<1)
    state->retry_time=1;

  infof(data, "set timeouts for state %d; Total %d, retry %d maxtry %d\n",
        state->state, (state->max_time-state->start_time),
        state->retry_time, state->retry_max);
}

/**********************************************************
 *
 * tftp_set_send_first
 *
 * Event handler for the START state
 *
 **********************************************************/

static void setpacketevent(tftp_packet_t *packet, unsigned short num)
{
  packet->data[0] = (unsigned char)(num >> 8);
  packet->data[1] = (unsigned char)(num & 0xff);
}


static void setpacketblock(tftp_packet_t *packet, unsigned short num)
{
  packet->data[2] = (unsigned char)(num >> 8);
  packet->data[3] = (unsigned char)(num & 0xff);
}

static unsigned short getrpacketevent(tftp_packet_t *packet)
{
  return (unsigned short)((packet->data[0] << 8) | packet->data[1]);
}

static unsigned short getrpacketblock(tftp_packet_t *packet)
{
  return (unsigned short)((packet->data[2] << 8) | packet->data[3]);
}

static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
{
  int sbytes;
  const char *mode = "octet";
  char *filename;
  struct SessionHandle *data = state->conn->data;
  CURLcode res = CURLE_OK;

  /* Set ascii mode if -B flag was used */
  if(data->set.prefer_ascii)
    mode = "netascii";

  switch(event) {

  case TFTP_EVENT_INIT:    /* Send the first packet out */
  case TFTP_EVENT_TIMEOUT: /* Resend the first packet out */
    /* Increment the retry counter, quit if over the limit */
    state->retries++;
    if(state->retries>state->retry_max) {
      state->error = TFTP_ERR_NORESPONSE;
      state->state = TFTP_STATE_FIN;
      return res;
    }

    if(data->set.upload) {
      /* If we are uploading, send an WRQ */
      setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
      state->conn->data->reqdata.upload_fromhere = (char *)&state->spacket.data[4];
      if(data->set.infilesize != -1)
        Curl_pgrsSetUploadSize(data, data->set.infilesize);
    }
    else {
      /* If we are downloading, send an RRQ */
      setpacketevent(&state->spacket, TFTP_EVENT_RRQ);
    }
    /* As RFC3617 describes the separator slash is not actually part of the
    file name so we skip the always-present first letter of the path string. */
    filename = curl_easy_unescape(data, &state->conn->data->reqdata.path[1], 0,
                                  NULL);
    snprintf((char *)&state->spacket.data[2],
             TFTP_BLOCKSIZE,
             "%s%c%s%c", filename, '\0',  mode, '\0');
    sbytes = 4 + (int)strlen(filename) + (int)strlen(mode);
    sbytes = sendto(state->sockfd, (void *)&state->spacket,
                    sbytes, 0,
                    state->conn->ip_addr->ai_addr,
                    state->conn->ip_addr->ai_addrlen);
    if(sbytes < 0) {
      failf(data, "%s\n", Curl_strerror(state->conn, Curl_sockerrno()));
    }
    Curl_safefree(filename);
    break;

  case TFTP_EVENT_ACK: /* Connected for transmit */
    infof(data, "%s\n", "Connected for transmit");
    state->state = TFTP_STATE_TX;
    tftp_set_timeouts(state);
    return tftp_tx(state, event);

  case TFTP_EVENT_DATA: /* connected for receive */
    infof(data, "%s\n", "Connected for receive");
    state->state = TFTP_STATE_RX;
    tftp_set_timeouts(state);
    return tftp_rx(state, event);

  case TFTP_EVENT_ERROR:
    state->state = TFTP_STATE_FIN;
    break;

  default:
    failf(state->conn->data, "tftp_send_first: internal error\n");
    break;
  }
  return res;
}

/**********************************************************
 *
 * tftp_rx
 *
 * Event handler for the RX state
 *
 **********************************************************/
static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
{
  int sbytes;
  int rblock;
  struct SessionHandle *data = state->conn->data;

  switch(event) {

  case TFTP_EVENT_DATA:

    /* Is this the block we expect? */
    rblock = getrpacketblock(&state->rpacket);
    if ((state->block+1) != rblock) {
      /* No, log it, up the retry count and fail if over the limit */
      infof(data,
            "Received unexpected DATA packet block %d\n", rblock);
      state->retries++;
      if (state->retries>state->retry_max) {
        failf(data, "tftp_rx: giving up waiting for block %d\n",
              state->block+1);
        return CURLE_TFTP_ILLEGAL;
      }
    }
    /* This is the expected block.  Reset counters and ACK it. */
    state->block = (unsigned short)rblock;
    state->retries = 0;
    setpacketevent(&state->spacket, TFTP_EVENT_ACK);
    setpacketblock(&state->spacket, state->block);
    sbytes = sendto(state->sockfd, (void *)state->spacket.data,
                    4, SEND_4TH_ARG,
                    (struct sockaddr *)&state->remote_addr,
                    state->remote_addrlen);
    if(sbytes < 0) {
      failf(data, "%s\n", Curl_strerror(state->conn, Curl_sockerrno()));
    }

    /* Check if completed (That is, a less than full packet is received) */
    if (state->rbytes < (int)sizeof(state->spacket)){
      state->state = TFTP_STATE_FIN;
    }
    else {
      state->state = TFTP_STATE_RX;
    }
    break;

  case TFTP_EVENT_TIMEOUT:
    /* Increment the retry count and fail if over the limit */
    state->retries++;
    infof(data,
          "Timeout waiting for block %d ACK.  Retries = %d\n", state->retries);
    if(state->retries > state->retry_max) {
      state->error = TFTP_ERR_TIMEOUT;
      state->state = TFTP_STATE_FIN;
    }
    else {
      /* Resend the previous ACK */
      sbytes = sendto(state->sockfd, (void *)&state->spacket,
                      4, SEND_4TH_ARG,
                      (struct sockaddr *)&state->remote_addr,
                      state->remote_addrlen);
      /* Check all sbytes were sent */
      if(sbytes<0) {
        failf(data, "%s\n", Curl_strerror(state->conn, Curl_sockerrno()));
      }
    }
    break;

  case TFTP_EVENT_ERROR:
    state->state = TFTP_STATE_FIN;
    break;

  default:
    failf(data, "%s\n", "tftp_rx: internal error");
    break;
  }
  Curl_pgrsSetDownloadCounter(data,
                              (curl_off_t) state->block*TFTP_BLOCKSIZE);
  return CURLE_OK;
}

/**********************************************************
 *
 * tftp_tx
 *
 * Event handler for the TX state
 *
 **********************************************************/
static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
{
  struct SessionHandle *data = state->conn->data;
  int sbytes;
  int rblock;
  CURLcode res = CURLE_OK;

  switch(event) {

  case TFTP_EVENT_ACK:
    /* Ack the packet */
    rblock = getrpacketblock(&state->rpacket);

    if(rblock != state->block) {
      /* This isn't the expected block.  Log it and up the retry counter */
      infof(data, "Received ACK for block %d, expecting %d\n",
            rblock, state->block);
      state->retries++;
      /* Bail out if over the maximum */
      if(state->retries>state->retry_max) {
        failf(data, "tftp_tx: giving up waiting for block %d ack",
              state->block);
        res = CURLE_SEND_ERROR;
      }
      else {
        /* Re-send the data packet */
        sbytes = sendto(state->sockfd, (void *)&state->spacket,
                        4+state->sbytes, SEND_4TH_ARG,
                        (struct sockaddr *)&state->remote_addr,
                        state->remote_addrlen);
        /* Check all sbytes were sent */
        if(sbytes<0) {
          failf(data, "%s\n", Curl_strerror(state->conn, Curl_sockerrno()));
          res = CURLE_SEND_ERROR;
        }
      }
      return res;
    }
    /* This is the expected packet.  Reset the counters and send the next
       block */
    state->block++;
    state->retries = 0;
    setpacketevent(&state->spacket, TFTP_EVENT_DATA);
    setpacketblock(&state->spacket, state->block);
    if(state->block > 1 && state->sbytes < TFTP_BLOCKSIZE) {
      state->state = TFTP_STATE_FIN;
      return CURLE_OK;
    }
    res = Curl_fillreadbuffer(state->conn, TFTP_BLOCKSIZE, &state->sbytes);
    if(res)
      return res;
    sbytes = sendto(state->sockfd, (void *)state->spacket.data,
                    4+state->sbytes, SEND_4TH_ARG,
                    (struct sockaddr *)&state->remote_addr,
                    state->remote_addrlen);
    /* Check all sbytes were sent */
    if(sbytes<0) {
      failf(data, "%s\n", Curl_strerror(state->conn, Curl_sockerrno()));
    }
    break;

  case TFTP_EVENT_TIMEOUT:
    /* Increment the retry counter and log the timeout */
    state->retries++;
    infof(data, "Timeout waiting for block %d ACK. "
          " Retries = %d\n", state->retries);
    /* Decide if we've had enough */
    if(state->retries > state->retry_max) {
      state->error = TFTP_ERR_TIMEOUT;
      state->state = TFTP_STATE_FIN;
    } else {
      /* Re-send the data packet */
      sbytes = sendto(state->sockfd, (void *)&state->spacket,
                      4+state->sbytes, SEND_4TH_ARG,
                      (struct sockaddr *)&state->remote_addr,
                      state->remote_addrlen);
      /* Check all sbytes were sent */
      if(sbytes<0) {
        failf(data, "%s\n", Curl_strerror(state->conn, Curl_sockerrno()));
      }
    }
    break;

  case TFTP_EVENT_ERROR:
    state->state = TFTP_STATE_FIN;
    break;

  default:
    failf(data, "%s\n", "tftp_tx: internal error");
    break;
  }

  /* Update the progress meter */
  Curl_pgrsSetUploadCounter(data, (curl_off_t) state->block*TFTP_BLOCKSIZE);

  return res;
}

/**********************************************************
 *
 * tftp_state_machine
 *
 * The tftp state machine event dispatcher
 *
 **********************************************************/
static CURLcode tftp_state_machine(tftp_state_data_t *state,
                                   tftp_event_t event)
{
  CURLcode res = CURLE_OK;
  struct SessionHandle *data = state->conn->data;
  switch(state->state) {
  case TFTP_STATE_START:
    DEBUGF(infof(data, "TFTP_STATE_START\n"));
    res = tftp_send_first(state, event);
    break;
  case TFTP_STATE_RX:
    DEBUGF(infof(data, "TFTP_STATE_RX\n"));
    res = tftp_rx(state, event);
    break;
  case TFTP_STATE_TX:
    DEBUGF(infof(data, "TFTP_STATE_TX\n"));
    res = tftp_tx(state, event);
    break;
  case TFTP_STATE_FIN:
    infof(data, "%s\n", "TFTP finished");
    break;
  default:
    DEBUGF(infof(data, "STATE: %d\n", state->state));
    failf(data, "%s\n", "Internal state machine error");
    res = CURLE_TFTP_ILLEGAL;
    break;
  }
  return res;
}


/**********************************************************
 *
 * Curl_tftp_connect
 *
 * The connect callback
 *
 **********************************************************/
CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done)
{
  CURLcode code;
  tftp_state_data_t     *state;
  int rc;

  state = conn->data->reqdata.proto.tftp = calloc(sizeof(tftp_state_data_t),
                                                  1);
  if(!state)
    return CURLE_OUT_OF_MEMORY;

  conn->bits.close = FALSE; /* keep it open if possible */

  state->conn = conn;
  state->sockfd = state->conn->sock[FIRSTSOCKET];
  state->state = TFTP_STATE_START;

  ((struct sockaddr *)&state->local_addr)->sa_family =
    conn->ip_addr->ai_family;

  tftp_set_timeouts(state);

  if(!conn->bits.reuse) {
    /* If not reused, bind to any interface, random UDP port. If it is reused,
     * this has already been done!
     *
     * We once used the size of the local_addr struct as the third argument for
     * bind() to better work with IPv6 or whatever size the struct could have,
     * but we learned that at least Tru64, AIX and IRIX *requires* the size of
     * that argument to match the exact size of a 'sockaddr_in' struct when
     * running IPv4-only.
     *
     * Therefore we use the size from the address we connected to, which we
     * assume uses the same IP version and thus hopefully this works for both
     * IPv4 and IPv6...
     */
    rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
              conn->ip_addr->ai_addrlen);
    if(rc) {
      failf(conn->data, "bind() failed; %s\n",
            Curl_strerror(conn, Curl_sockerrno()));
      return CURLE_COULDNT_CONNECT;
    }
  }

  Curl_pgrsStartNow(conn->data);

  *done = TRUE;
  code = CURLE_OK;
  return(code);
}

/**********************************************************
 *
 * Curl_tftp_done
 *
 * The done callback
 *
 **********************************************************/
CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode status,
                        bool premature)
{
  (void)status; /* unused */
  (void)premature; /* not used */

#if 0
  free(conn->data->reqdata.proto.tftp);
  conn->data->reqdata.proto.tftp = NULL;
#endif
  Curl_pgrsDone(conn);

  return CURLE_OK;
}


/**********************************************************
 *
 * Curl_tftp
 *
 * The do callback
 *
 * This callback handles the entire TFTP transfer
 *
 **********************************************************/

CURLcode Curl_tftp(struct connectdata *conn, bool *done)
{
  struct SessionHandle  *data = conn->data;
  tftp_state_data_t     *state =
    (tftp_state_data_t *) conn->data->reqdata.proto.tftp;
  tftp_event_t          event;
  CURLcode              code;
  int                   rc;
  struct Curl_sockaddr_storage fromaddr;
  socklen_t             fromlen;
  int                   check_time = 0;

  *done = TRUE;

  /*
    Since connections can be re-used between SessionHandles, this might be a
    connection already existing but on a fresh SessionHandle struct so we must
    make sure we have a good 'struct TFTP' to play with. For new connections,
    the struct TFTP is allocated and setup in the Curl_tftp_connect() function.
  */
  if(!state) {
    code = Curl_tftp_connect(conn, done);
    if(code)
      return code;
    state = (tftp_state_data_t *)conn->data->reqdata.proto.tftp;
  }

  /* Run the TFTP State Machine */
  for(tftp_state_machine(state, TFTP_EVENT_INIT);
      state->state != TFTP_STATE_FIN;
      tftp_state_machine(state, event) ) {

    /* Wait until ready to read or timeout occurs */
    rc=Curl_select(state->sockfd, CURL_SOCKET_BAD, state->retry_time * 1000);

    if(rc == -1) {
      /* bail out */
      int error = Curl_sockerrno();
      failf(data, "%s\n", Curl_strerror(conn, error));
      event = TFTP_EVENT_ERROR;
    }
    else if (rc==0) {
      /* A timeout occured */
      event = TFTP_EVENT_TIMEOUT;

      /* Force a look at transfer timeouts */
      check_time = 0;

    }
    else {

      /* Receive the packet */
      fromlen=sizeof(fromaddr);
      state->rbytes = recvfrom(state->sockfd,
                               (void *)&state->rpacket, sizeof(state->rpacket),
                               0, (struct sockaddr *)&fromaddr, &fromlen);
      if(state->remote_addrlen==0) {
        memcpy(&state->remote_addr, &fromaddr, fromlen);
        state->remote_addrlen = fromlen;
      }

      /* Sanity check packet length */
      if (state->rbytes < 4) {
        failf(conn->data, "Received too short packet\n");
        /* Not a timeout, but how best to handle it? */
        event = TFTP_EVENT_TIMEOUT;
      }
      else {

        /* The event is given by the TFTP packet time */
        event = (tftp_event_t)getrpacketevent(&state->rpacket);

        switch(event) {
        case TFTP_EVENT_DATA:
          /* Don't pass to the client empty or retransmitted packets */
          if (state->rbytes > 4 &&
              ((state->block+1) == getrpacketblock(&state->rpacket))) {
            code = Curl_client_write(conn, CLIENTWRITE_BODY,
                                     (char *)&state->rpacket.data[4],
                                     state->rbytes-4);
            if(code)
              return code;
          }
          break;
        case TFTP_EVENT_ERROR:
          state->error = (tftp_error_t)getrpacketblock(&state->rpacket);
          infof(conn->data, "%s\n", (char *)&state->rpacket.data[4]);
          break;
        case TFTP_EVENT_ACK:
          break;
        case TFTP_EVENT_RRQ:
        case TFTP_EVENT_WRQ:
        default:
          failf(conn->data, "%s\n", "Internal error: Unexpected packet");
          break;
        }

        /* Update the progress meter */
        if(Curl_pgrsUpdate(conn))
          return CURLE_ABORTED_BY_CALLBACK;
      }
    }

    /* Check for transfer timeout every 10 blocks, or after timeout */
    if(check_time%10==0) {
      time_t current;
      time(&current);
      if(current>state->max_time) {
        DEBUGF(infof(data, "timeout: %d > %d\n",
                     current, state->max_time));
        state->error = TFTP_ERR_TIMEOUT;
        state->state = TFTP_STATE_FIN;
      }
    }

  }

  /* Tell curl we're done */
  code = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
  if(code)
    return code;

  /* If we have encountered an error */
  if(state->error) {

    /* Translate internal error codes to curl error codes */
    switch(state->error) {
    case TFTP_ERR_NOTFOUND:
      code = CURLE_TFTP_NOTFOUND;
      break;
    case TFTP_ERR_PERM:
      code = CURLE_TFTP_PERM;
      break;
    case TFTP_ERR_DISKFULL:
      code = CURLE_TFTP_DISKFULL;
      break;
    case TFTP_ERR_ILLEGAL:
      code = CURLE_TFTP_ILLEGAL;
      break;
    case TFTP_ERR_UNKNOWNID:
      code = CURLE_TFTP_UNKNOWNID;
      break;
    case TFTP_ERR_EXISTS:
      code = CURLE_TFTP_EXISTS;
      break;
    case TFTP_ERR_NOSUCHUSER:
      code = CURLE_TFTP_NOSUCHUSER;
      break;
    case TFTP_ERR_TIMEOUT:
      code = CURLE_OPERATION_TIMEOUTED;
      break;
    case TFTP_ERR_NORESPONSE:
      code = CURLE_COULDNT_CONNECT;
      break;
    default:
      code= CURLE_ABORTED_BY_CALLBACK;
      break;
    }
  }
  else
    code = CURLE_OK;
  return code;
}
#endif

Index: base64.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/base64.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- base64.h	24 Jun 2005 13:00:12 -0000	1.1
+++ base64.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,18 +1,18 @@
 #ifndef __BASE64_H
 #define __BASE64_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -22,6 +22,7 @@
  *
  * $Id$
  ***************************************************************************/
-size_t Curl_base64_encode(const char *input, size_t size, char **str);
-size_t Curl_base64_decode(const char *source, char *dest);
+size_t Curl_base64_encode(struct SessionHandle *data,
+                          const char *input, size_t size, char **str);
+size_t Curl_base64_decode(const char *source, unsigned char **outptr);
 #endif

--- NEW FILE: splay.h ---
#ifndef __SPLAY_H
#define __SPLAY_H
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1997 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: splay.h,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

struct Curl_tree {
  struct Curl_tree *smaller; /* smaller node */
  struct Curl_tree *larger;  /* larger node */
  struct Curl_tree *same;    /* points to a node with identical key */
  int key;                   /* the "sort" key */
  void *payload;             /* data the splay code doesn't care about */
};

struct Curl_tree *Curl_splay(int i, struct Curl_tree *t);
struct Curl_tree *Curl_splayinsert(int key, struct Curl_tree *t,
                                   struct Curl_tree *newnode);
#if 0
struct Curl_tree *Curl_splayremove(int key, struct Curl_tree *t,
                                   struct Curl_tree **removed);
#endif

struct Curl_tree *Curl_splaygetbest(int key, struct Curl_tree *t,
                                    struct Curl_tree **removed);
int Curl_splayremovebyaddr(struct Curl_tree *t,
                           struct Curl_tree *remove,
                           struct Curl_tree **newroot);

#ifdef CURLDEBUG
void Curl_splayprint(struct Curl_tree * t, int d, char output);
#else
#define Curl_splayprint(x,y,z)
#endif

#endif

--- NEW FILE: sslgen.h ---
#ifndef __SSLGEN_H
#define __SSLGEN_H
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: sslgen.h,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

bool Curl_ssl_config_matches(struct ssl_config_data* data,
                             struct ssl_config_data* needle);
bool Curl_clone_ssl_config(struct ssl_config_data* source,
                           struct ssl_config_data* dest);
void Curl_free_ssl_config(struct ssl_config_data* sslc);

int Curl_ssl_init(void);
void Curl_ssl_cleanup(void);
CURLcode Curl_ssl_connect(struct connectdata *conn, int sockindex);
CURLcode Curl_ssl_connect_nonblocking(struct connectdata *conn,
                                      int sockindex,
                                      bool *done);
void Curl_ssl_close(struct connectdata *conn);
/* tell the SSL stuff to close down all open information regarding
   connections (and thus session ID caching etc) */
void Curl_ssl_close_all(struct SessionHandle *data);
CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine);
/* Sets engine as default for all SSL operations */
CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data);
ssize_t Curl_ssl_send(struct connectdata *conn,
                      int sockindex,
                      void *mem,
                      size_t len);
ssize_t Curl_ssl_recv(struct connectdata *conn, /* connection data */
                      int sockindex,            /* socketindex */
                      char *mem,                /* store read data here */
                      size_t len);              /* max amount to read */

/* init the SSL session ID cache */
CURLcode Curl_ssl_initsessions(struct SessionHandle *, long);
/* extract a session ID */
int Curl_ssl_getsessionid(struct connectdata *conn,
                          void **ssl_sessionid,
                          size_t *idsize) /* set 0 if unknown */;
/* add a new session ID */
CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
                               void *ssl_sessionid,
                               size_t idsize);


struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data);

size_t Curl_ssl_version(char *buffer, size_t size);

int Curl_ssl_check_cxn(struct connectdata *conn);

CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex);

bool Curl_ssl_data_pending(struct connectdata *conn,
                           int connindex);

#if !defined(USE_SSL) && !defined(SSLGEN_C)
/* set up blank macros for none-SSL builds */
#define Curl_ssl_close_all(x)
#endif

#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */

#endif

Index: url.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/url.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- url.h	24 Jun 2005 13:00:13 -0000	1.1
+++ url.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,25 +23,63 @@
  * $Id$
  ***************************************************************************/
 
+#include <stdarg.h> /* to make sure we have ap_list */
+
 /*
  * Prototypes for library-wide functions provided by url.c
  */
 
 CURLcode Curl_open(struct SessionHandle **curl);
-CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...);
+CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
+                     va_list arg);
 CURLcode Curl_close(struct SessionHandle *data); /* opposite of curl_open() */
 CURLcode Curl_connect(struct SessionHandle *, struct connectdata **,
-                      bool *async);
-CURLcode Curl_async_resolved(struct connectdata *conn);
-CURLcode Curl_do(struct connectdata **);
+                      bool *async, bool *protocol_connect);
+CURLcode Curl_async_resolved(struct connectdata *conn,
+                             bool *protocol_connect);
+CURLcode Curl_do(struct connectdata **, bool *done);
 CURLcode Curl_do_more(struct connectdata *);
-CURLcode Curl_done(struct connectdata **, CURLcode);
+CURLcode Curl_done(struct connectdata **, CURLcode, bool premature);
 CURLcode Curl_disconnect(struct connectdata *);
-CURLcode Curl_protocol_connect(struct connectdata *conn);
-bool Curl_ssl_config_matches(struct ssl_config_data* data,
-                             struct ssl_config_data* needle);
-bool Curl_clone_ssl_config(struct ssl_config_data* source,
-                           struct ssl_config_data* dest);
-void Curl_free_ssl_config(struct ssl_config_data* sslc);
+CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
+CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
+CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);
 void Curl_safefree(void *ptr);
+
+/* create a connection cache */
+struct conncache *Curl_mk_connc(int type, int amount);
+/* free a connection cache */
+void Curl_rm_connc(struct conncache *c);
+/* Change number of entries of a connection cache */
+CURLcode Curl_ch_connc(struct SessionHandle *data,
+                       struct conncache *c,
+                       long newamount);
+
+int Curl_protocol_getsock(struct connectdata *conn,
+                          curl_socket_t *socks,
+                          int numsocks);
+int Curl_doing_getsock(struct connectdata *conn,
+                       curl_socket_t *socks,
+                       int numsocks);
+
+void Curl_addHandleToPipeline(struct SessionHandle *handle,
+                              struct curl_llist *pipe);
+int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
+                                  struct curl_llist *pipe);
+bool Curl_isHandleAtHead(struct SessionHandle *handle,
+                         struct curl_llist *pipe);
+
+void Curl_close_connections(struct SessionHandle *data);
+
+#if 0
+CURLcode Curl_protocol_fdset(struct connectdata *conn,
+                             fd_set *read_fd_set,
+                             fd_set *write_fd_set,
+                             int *max_fdp);
+CURLcode Curl_doing_fdset(struct connectdata *conn,
+                          fd_set *read_fd_set,
+                          fd_set *write_fd_set,
+                          int *max_fdp);
+#endif
+
 #endif

Index: http.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/http.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- http.h	24 Jun 2005 13:00:12 -0000	1.1
+++ http.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -8,7 +8,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -29,14 +29,18 @@
                         const char *content); /* content string to find */
 
 /* ftp can use this as well */
-CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
-                                     int tunnelsocket,
-                                     char *hostname, int remote_port);
+CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+                           int tunnelsocket,
+                           char *hostname, int remote_port);
 
 /* protocol-specific functions set up to be called by the main engine */
-CURLcode Curl_http(struct connectdata *conn);
-CURLcode Curl_http_done(struct connectdata *, CURLcode);
-CURLcode Curl_http_connect(struct connectdata *conn);
+CURLcode Curl_http(struct connectdata *conn, bool *done);
+CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
+CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
+CURLcode Curl_https_connecting(struct connectdata *conn, bool *done);
+int Curl_https_getsock(struct connectdata *conn,
+                       curl_socket_t *socks,
+                       int numsocks);
 
 /* The following functions are defined in http_chunks.c */
 void Curl_httpchunk_init(struct connectdata *conn);
@@ -57,5 +61,25 @@
    public curl/curl.h header. */
 #define CURLAUTH_PICKNONE (1<<30) /* don't use auth */
 
+/* MAX_INITIAL_POST_SIZE indicates the number of bytes that will make the POST
+   data get included in the initial data chunk sent to the server. If the
+   data is larger than this, it will automatically get split up in multiple
+   system calls.
+
+   This value used to be fairly big (100K), but we must take into account that
+   if the server rejects the POST due for authentication reasons, this data
+   will always be uncondtionally sent and thus it may not be larger than can
+   always be afforded to send twice.
+
+   It must not be greater than 64K to work on VMS.
+*/
+#ifndef MAX_INITIAL_POST_SIZE
+#define MAX_INITIAL_POST_SIZE (64*1024)
+#endif
+
+#ifndef TINY_INITIAL_POST_SIZE
+#define TINY_INITIAL_POST_SIZE 1024
+#endif
+
 #endif
 #endif

Index: amigaos.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/amigaos.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- amigaos.c	24 Jun 2005 13:00:11 -0000	1.1
+++ amigaos.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -22,28 +22,53 @@
  ***************************************************************************/
 
 #include "amigaos.h"
-#include <stdio.h> /* for stderr */
+#include <amitcp/socketbasetags.h>
 
 struct Library *SocketBase = NULL;
+extern int errno, h_errno;
+
+#ifdef __libnix__
+#include <stabs.h>
+void __request(const char *msg);
+#else
+# define __request( msg )  Printf( msg "\n\a")
+#endif
 
 void amiga_cleanup()
 {
-  if(SocketBase)
+  if(SocketBase) {
     CloseLibrary(SocketBase);
-        
-  SocketBase = NULL;
+    SocketBase = NULL;
+  }
 }
 
 BOOL amiga_init()
 {
   if(!SocketBase)
     SocketBase = OpenLibrary("bsdsocket.library", 4);
-        
+  
   if(!SocketBase) {
-    fprintf(stderr, "No TCP/IP Stack running!\n\a");
+    __request("No TCP/IP Stack running!");
     return FALSE;
   }
-        
+  
+  if(SocketBaseTags(
+    SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
+//    SBTM_SETVAL(SBTC_HERRNOLONGPTR),     (ULONG) &h_errno,
+    SBTM_SETVAL(SBTC_LOGTAGPTR),       (ULONG) "cURL",
+  TAG_DONE)) {
+    
+    __request("SocketBaseTags ERROR");
+    return FALSE;
+  }
+  
+#ifndef __libnix__
   atexit(amiga_cleanup);
+#endif
+  
   return TRUE;
 }
+
+#ifdef __libnix__
+ADD2EXIT(amiga_cleanup,-50);
+#endif

Index: url.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/url.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- url.c	24 Jun 2005 13:00:13 -0000	1.1
+++ url.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -30,12 +30,15 @@
 #include <stdarg.h>
 #include <stdlib.h>
[...4278 lines suppressed...]
-}
-
-void Curl_free_ssl_config(struct ssl_config_data* sslc)
-{
-  if(sslc->CAfile)
-    free(sslc->CAfile);
-
-  if(sslc->CApath)
-    free(sslc->CApath);
-
-  if(sslc->cipher_list)
-    free(sslc->cipher_list);
-
-  if(sslc->egdsocket)
-    free(sslc->egdsocket);
-
-  if(sslc->random_file)
-    free(sslc->random_file);
-}
-

Index: amigaos.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/amigaos.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- amigaos.h	24 Jun 2005 13:00:12 -0000	1.1
+++ amigaos.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -32,13 +32,19 @@
 #include <proto/exec.h>
 #include <proto/dos.h>
 
-#include <bsdsocket.h>
+#include <sys/socket.h>
 
 #include "config-amigaos.h"
 
-#define select(args...) WaitSelect( args, NULL)
-#define inet_ntoa(x)    Inet_NtoA( x ## .s_addr)
-#define ioctl(a,b,c,d)  IoctlSocket( (LONG)a, (ULONG)b, (char*)c)
+#ifndef select
+# define select(args...) WaitSelect( args, NULL)
+#endif
+#ifndef inet_ntoa
+# define inet_ntoa(x)    Inet_NtoA( x ## .s_addr)
+#endif
+#ifndef ioctl
+# define ioctl(a,b,c,d)  IoctlSocket( (LONG)a, (ULONG)b, (char*)c)
+#endif
 #define _AMIGASF        1
 
 extern void amiga_cleanup();

Index: http.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/http.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- http.c	24 Jun 2005 13:00:12 -0000	1.1
+++ http.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -30,12 +30,14 @@
 #include <stdarg.h>
 #include <stdlib.h>
[...2007 lines suppressed...]
+          Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
                         &http->readbytecount,
                         http->postdata?FIRSTSOCKET:-1,
                         http->postdata?&http->writebytecount:NULL);
@@ -1976,13 +2402,13 @@
 
       /* issue the request */
       result = add_buffer_send(req_buffer, conn,
-                               &data->info.request_size);
+                               &data->info.request_size, 0, FIRSTSOCKET);
 
       if(result)
         failf(data, "Failed sending HTTP request");
       else
         /* HTTP GET/HEAD download: */
-        result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
+        result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
                                &http->readbytecount,
                                http->postdata?FIRSTSOCKET:-1,
                                http->postdata?&http->writebytecount:NULL);

Index: llist.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/llist.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- llist.c	24 Jun 2005 13:00:12 -0000	1.1
+++ llist.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,13 +27,13 @@
 #include <stdlib.h>
 
 #include "llist.h"
-#include "curl_memory.h"
+#include "memory.h"
 
 /* this must be the last include file */
 #include "memdebug.h"
 
 void
-Curl_llist_init(curl_llist *l, curl_llist_dtor dtor)
+Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor)
 {
   l->size = 0;
   l->dtor = dtor;
@@ -41,12 +41,12 @@
   l->tail = NULL;
 }
 
-curl_llist *
+struct curl_llist *
 Curl_llist_alloc(curl_llist_dtor dtor)
 {
-  curl_llist *list;
+  struct curl_llist *list;
 
-  list = (curl_llist *)malloc(sizeof(curl_llist));
+  list = (struct curl_llist *)malloc(sizeof(struct curl_llist));
   if(NULL == list)
     return NULL;
 
@@ -59,10 +59,11 @@
  * Curl_llist_insert_next() returns 1 on success and 0 on failure.
  */
 int
-Curl_llist_insert_next(curl_llist *list, curl_llist_element *e, const void *p)
+Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
+                       const void *p)
 {
-  curl_llist_element *ne =
-    (curl_llist_element *) malloc(sizeof(curl_llist_element));
+  struct curl_llist_element *ne =
+    (struct curl_llist_element *) malloc(sizeof(struct curl_llist_element));
   if(!ne)
     return 0;
 
@@ -91,7 +92,8 @@
 }
 
 int
-Curl_llist_remove(curl_llist *list, curl_llist_element *e, void *user)
+Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
+                  void *user)
 {
   if (e == NULL || list->size == 0)
     return 1;
@@ -119,7 +121,7 @@
 }
 
 void
-Curl_llist_destroy(curl_llist *list, void *user)
+Curl_llist_destroy(struct curl_llist *list, void *user)
 {
   if(list) {
     while (list->size > 0)
@@ -128,3 +130,9 @@
     free(list);
   }
 }
+
+size_t
+Curl_llist_count(struct curl_llist *list)
+{
+  return list->size;
+}

Index: getenv.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/getenv.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- getenv.c	24 Jun 2005 13:00:12 -0000	1.1
+++ getenv.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,16 +1,16 @@
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -27,24 +27,22 @@
 #include <stdlib.h>
 #include <string.h>
 
-#ifdef WIN32
-#include <windows.h>
-#endif
-
 #ifdef VMS
 #include <unixlib.h>
 #endif
 
 #include <curl/curl.h>
-#include "curl_memory.h"
+#include "memory.h"
 
 #include "memdebug.h"
 
 static
 char *GetEnv(const char *variable)
 {
+#ifdef _WIN32_WCE
+  return NULL;
+#else
 #ifdef WIN32
-  /* This shit requires windows.h (HUGE) to be included */
   char env[MAX_PATH]; /* MAX_PATH is from windef.h */
   char *temp = getenv(variable);
   env[0] = '\0';
@@ -62,6 +60,7 @@
 #endif
 #endif
   return (env && env[0])?strdup(env):NULL;
+#endif
 }
 
 char *curl_getenv(const char *v)

--- NEW FILE: socks.c ---
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: socks.c,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

#include "setup.h"

#include <string.h>

#ifdef NEED_MALLOC_H
#include <malloc.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#include "urldata.h"
#include "sendf.h"
#include "strequal.h"
#include "select.h"
#include "connect.h"
#include "timeval.h"
#include "socks.h"

/* The last #include file should be: */
#include "memdebug.h"

/*
 * Helper read-from-socket functions. Does the same as Curl_read() but it
 * blocks until all bytes amount of buffersize will be read. No more, no less.
 *
 * This is STUPID BLOCKING behaviour which we frown upon, but right now this
 * is what we have...
 */
static int blockread_all(struct connectdata *conn, /* connection data */
                         curl_socket_t sockfd,     /* read from this socket */
                         char *buf,                /* store read data here */
                         ssize_t buffersize,       /* max amount to read */
                         ssize_t *n,               /* amount bytes read */
                         long conn_timeout)        /* timeout for data wait
                                                      relative to
                                                      conn->created */
{
  ssize_t nread;
  ssize_t allread = 0;
  int result;
  struct timeval tvnow;
  long conntime;
  *n = 0;
  do {
    tvnow = Curl_tvnow();
    /* calculating how long connection is establishing */
    conntime = Curl_tvdiff(tvnow, conn->created);
    if(conntime > conn_timeout) {
      /* we already got the timeout */
      result = ~CURLE_OK;
      break;
    }
    if(Curl_select(sockfd, CURL_SOCKET_BAD,
                   (int)(conn_timeout - conntime)) <= 0) {
      result = ~CURLE_OK;
      break;
    }
    result = Curl_read(conn, sockfd, buf, buffersize, &nread);
    if(result)
      break;

    if(buffersize == nread) {
      allread += nread;
      *n = allread;
      result = CURLE_OK;
      break;
    }
    buffersize -= nread;
    buf += nread;
    allread += nread;
  } while(1);
  return result;
}

/*
* This function logs in to a SOCKS4 proxy and sends the specifics to the final
* destination server.
*
* Reference :
*   http://socks.permeo.com/protocol/socks4.protocol
*
* Note :
*   Nonsupport "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)"
*   Nonsupport "Identification Protocol (RFC1413)"
*/
CURLcode Curl_SOCKS4(const char *proxy_name,
                     struct connectdata *conn)
{
  unsigned char socksreq[262]; /* room for SOCKS4 request incl. user id */
  int result;
  CURLcode code;
  curl_socket_t sock = conn->sock[FIRSTSOCKET];
  long timeout;
  struct SessionHandle *data = conn->data;

  /* get timeout */
  if(data->set.timeout && data->set.connecttimeout) {
    if (data->set.timeout < data->set.connecttimeout)
      timeout = data->set.timeout*1000;
    else
      timeout = data->set.connecttimeout*1000;
  }
  else if(data->set.timeout)
    timeout = data->set.timeout*1000;
  else if(data->set.connecttimeout)
    timeout = data->set.connecttimeout*1000;
  else
    timeout = DEFAULT_CONNECT_TIMEOUT;

  Curl_nonblock(sock, FALSE);

  /*
   * Compose socks4 request
   *
   * Request format
   *
   *     +----+----+----+----+----+----+----+----+----+----+....+----+
   *     | VN | CD | DSTPORT |      DSTIP        | USERID       |NULL|
   *     +----+----+----+----+----+----+----+----+----+----+....+----+
   * # of bytes:  1    1      2              4           variable       1
   */

  socksreq[0] = 4; /* version (SOCKS4) */
  socksreq[1] = 1; /* connect */
  *((unsigned short*)&socksreq[2]) = htons(conn->remote_port);

  /* DNS resolve */
  {
    struct Curl_dns_entry *dns;
    Curl_addrinfo *hp=NULL;
    int rc;

    rc = Curl_resolv(conn, conn->host.name, (int)conn->remote_port, &dns);

    if(rc == CURLRESOLV_ERROR)
      return CURLE_COULDNT_RESOLVE_PROXY;

    if(rc == CURLRESOLV_PENDING)
      /* this requires that we're in "wait for resolve" state */
      rc = Curl_wait_for_resolv(conn, &dns);

    /*
     * We cannot use 'hostent' as a struct that Curl_resolv() returns.  It
     * returns a Curl_addrinfo pointer that may not always look the same.
     */
    if(dns)
      hp=dns->addr;
    if (hp) {
      char buf[64];
      unsigned short ip[4];
      Curl_printable_address(hp, buf, sizeof(buf));

      if(4 == sscanf( buf, "%hu.%hu.%hu.%hu",
                      &ip[0], &ip[1], &ip[2], &ip[3])) {
        /* Set DSTIP */
        socksreq[4] = (unsigned char)ip[0];
        socksreq[5] = (unsigned char)ip[1];
        socksreq[6] = (unsigned char)ip[2];
        socksreq[7] = (unsigned char)ip[3];
      }
      else
        hp = NULL; /* fail! */

      Curl_resolv_unlock(data, dns); /* not used anymore from now on */

    }
    if(!hp) {
      failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.",
            conn->host.name);
      return CURLE_COULDNT_RESOLVE_HOST;
    }
  }

  /*
   * This is currently not supporting "Identification Protocol (RFC1413)".
   */
  socksreq[8] = 0; /* ensure empty userid is NUL-terminated */
  if (proxy_name)
    strlcat((char*)socksreq + 8, proxy_name, sizeof(socksreq) - 8);

  /*
   * Make connection
   */
  {
    ssize_t actualread;
    ssize_t written;
    int packetsize = 9 +
      (int)strlen((char*)socksreq + 8); /* size including NUL */

    /* Send request */
    code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written);
    if ((code != CURLE_OK) || (written != packetsize)) {
      failf(data, "Failed to send SOCKS4 connect request.");
      return CURLE_COULDNT_CONNECT;
    }

    packetsize = 8; /* receive data size */

    /* Receive response */
    result = blockread_all(conn, sock, (char *)socksreq, packetsize,
                           &actualread, timeout);
    if ((result != CURLE_OK) || (actualread != packetsize)) {
      failf(data, "Failed to receive SOCKS4 connect request ack.");
      return CURLE_COULDNT_CONNECT;
    }

    /*
     * Response format
     *
     *     +----+----+----+----+----+----+----+----+
     *     | VN | CD | DSTPORT |      DSTIP        |
     *     +----+----+----+----+----+----+----+----+
     * # of bytes:  1    1      2              4
     *
     * VN is the version of the reply code and should be 0. CD is the result
     * code with one of the following values:
     *
     * 90: request granted
     * 91: request rejected or failed
     * 92: request rejected because SOCKS server cannot connect to
     *     identd on the client
     * 93: request rejected because the client program and identd
     *     report different user-ids
     */

    /* wrong version ? */
    if (socksreq[0] != 0) {
      failf(data,
            "SOCKS4 reply has wrong version, version should be 4.");
      return CURLE_COULDNT_CONNECT;
    }

    /* Result */
    switch(socksreq[1])
    {
    case 90:
      infof(data, "SOCKS4 request granted.\n");
      break;
    case 91:
      failf(data,
            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
            ", request rejected or failed.",
            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
            (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
            socksreq[1]);
      return CURLE_COULDNT_CONNECT;
    case 92:
      failf(data,
            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
            ", request rejected because SOCKS server cannot connect to "
            "identd on the client.",
            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
            (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
            socksreq[1]);
      return CURLE_COULDNT_CONNECT;
    case 93:
      failf(data,
            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
            ", request rejected because the client program and identd "
            "report different user-ids.",
            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
            (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
            socksreq[1]);
      return CURLE_COULDNT_CONNECT;
    default:
      failf(data,
            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
            ", Unknown.",
            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
            (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
            socksreq[1]);
      return CURLE_COULDNT_CONNECT;
    }
  }

  Curl_nonblock(sock, TRUE);

  return CURLE_OK; /* Proxy was successful! */
}

/*
 * This function logs in to a SOCKS5 proxy and sends the specifics to the final
 * destination server.
 */
CURLcode Curl_SOCKS5(const char *proxy_name,
                     const char *proxy_password,
                     struct connectdata *conn)
{
  /*
    According to the RFC1928, section "6.  Replies". This is what a SOCK5
    replies:

        +----+-----+-------+------+----------+----------+
        |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
        +----+-----+-------+------+----------+----------+
        | 1  |  1  | X'00' |  1   | Variable |    2     |
        +----+-----+-------+------+----------+----------+

    Where:

    o  VER    protocol version: X'05'
    o  REP    Reply field:
    o  X'00' succeeded
  */

  unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
  ssize_t actualread;
  ssize_t written;
  int result;
  CURLcode code;
  curl_socket_t sock = conn->sock[FIRSTSOCKET];
  struct SessionHandle *data = conn->data;
  long timeout;

  /* get timeout */
  if(data->set.timeout && data->set.connecttimeout) {
    if (data->set.timeout < data->set.connecttimeout)
      timeout = data->set.timeout*1000;
    else
      timeout = data->set.connecttimeout*1000;
  }
  else if(data->set.timeout)
    timeout = data->set.timeout*1000;
  else if(data->set.connecttimeout)
    timeout = data->set.connecttimeout*1000;
  else
    timeout = DEFAULT_CONNECT_TIMEOUT;

  Curl_nonblock(sock, TRUE);

  /* wait until socket gets connected */
  result = Curl_select(CURL_SOCKET_BAD, sock, (int)timeout);

  if(-1 == result) {
    failf(conn->data, "SOCKS5: no connection here");
    return CURLE_COULDNT_CONNECT;
  }
  else if(0 == result) {
    failf(conn->data, "SOCKS5: connection timeout");
    return CURLE_OPERATION_TIMEDOUT;
  }

  if(result & CSELECT_ERR) {
    failf(conn->data, "SOCKS5: error occured during connection");
    return CURLE_COULDNT_CONNECT;
  }

  socksreq[0] = 5; /* version */
  socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
  socksreq[2] = 0; /* no authentication */
  socksreq[3] = 2; /* username/password */

  Curl_nonblock(sock, FALSE);

  code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
                      &written);
  if ((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {
    failf(data, "Unable to send initial SOCKS5 request.");
    return CURLE_COULDNT_CONNECT;
  }

  Curl_nonblock(sock, TRUE);

  result = Curl_select(sock, CURL_SOCKET_BAD, (int)timeout);

  if(-1 == result) {
    failf(conn->data, "SOCKS5 nothing to read");
    return CURLE_COULDNT_CONNECT;
  }
  else if(0 == result) {
    failf(conn->data, "SOCKS5 read timeout");
    return CURLE_OPERATION_TIMEDOUT;
  }

  if(result & CSELECT_ERR) {
    failf(conn->data, "SOCKS5 read error occured");
    return CURLE_RECV_ERROR;
  }

  Curl_nonblock(sock, FALSE);

  result=blockread_all(conn, sock, (char *)socksreq, 2, &actualread, timeout);
  if ((result != CURLE_OK) || (actualread != 2)) {
    failf(data, "Unable to receive initial SOCKS5 response.");
    return CURLE_COULDNT_CONNECT;
  }

  if (socksreq[0] != 5) {
    failf(data, "Received invalid version in initial SOCKS5 response.");
    return CURLE_COULDNT_CONNECT;
  }
  if (socksreq[1] == 0) {
    /* Nothing to do, no authentication needed */
    ;
  }
  else if (socksreq[1] == 2) {
    /* Needs user name and password */
    size_t userlen, pwlen;
    int len;
    if(proxy_name && proxy_password) {
      userlen = strlen(proxy_name);
      pwlen = proxy_password?strlen(proxy_password):0;
    }
    else {
      userlen = 0;
      pwlen = 0;
    }

    /*   username/password request looks like
     * +----+------+----------+------+----------+
     * |VER | ULEN |  UNAME   | PLEN |  PASSWD  |
     * +----+------+----------+------+----------+
     * | 1  |  1   | 1 to 255 |  1   | 1 to 255 |
     * +----+------+----------+------+----------+
     */
    len = 0;
    socksreq[len++] = 1;    /* username/pw subnegotiation version */
    socksreq[len++] = (char) userlen;
    memcpy(socksreq + len, proxy_name, (int) userlen);
    len += userlen;
    socksreq[len++] = (char) pwlen;
    memcpy(socksreq + len, proxy_password, (int) pwlen);
    len += pwlen;

    code = Curl_write(conn, sock, (char *)socksreq, len, &written);
    if ((code != CURLE_OK) || (len != written)) {
      failf(data, "Failed to send SOCKS5 sub-negotiation request.");
      return CURLE_COULDNT_CONNECT;
    }

    result=blockread_all(conn, sock, (char *)socksreq, 2, &actualread,
                         timeout);
    if ((result != CURLE_OK) || (actualread != 2)) {
      failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
      return CURLE_COULDNT_CONNECT;
    }

    /* ignore the first (VER) byte */
    if (socksreq[1] != 0) { /* status */
      failf(data, "User was rejected by the SOCKS5 server (%d %d).",
            socksreq[0], socksreq[1]);
      return CURLE_COULDNT_CONNECT;
    }

    /* Everything is good so far, user was authenticated! */
  }
  else {
    /* error */
    if (socksreq[1] == 1) {
      failf(data,
            "SOCKS5 GSSAPI per-message authentication is not supported.");
      return CURLE_COULDNT_CONNECT;
    }
    else if (socksreq[1] == 255) {
      if (!proxy_name || !*proxy_name) {
        failf(data,
              "No authentication method was acceptable. (It is quite likely"
              " that the SOCKS5 server wanted a username/password, since none"
              " was supplied to the server on this connection.)");
      }
      else {
        failf(data, "No authentication method was acceptable.");
      }
      return CURLE_COULDNT_CONNECT;
    }
    else {
      failf(data,
            "Undocumented SOCKS5 mode attempted to be used by server.");
      return CURLE_COULDNT_CONNECT;
    }
  }

  /* Authentication is complete, now specify destination to the proxy */
  socksreq[0] = 5; /* version (SOCKS5) */
  socksreq[1] = 1; /* connect */
  socksreq[2] = 0; /* must be zero */
  socksreq[3] = 1; /* IPv4 = 1 */

  {
    struct Curl_dns_entry *dns;
    Curl_addrinfo *hp=NULL;
    int rc = Curl_resolv(conn, conn->host.name, (int)conn->remote_port, &dns);

    if(rc == CURLRESOLV_ERROR)
      return CURLE_COULDNT_RESOLVE_HOST;

    if(rc == CURLRESOLV_PENDING)
      /* this requires that we're in "wait for resolve" state */
      rc = Curl_wait_for_resolv(conn, &dns);

    /*
     * We cannot use 'hostent' as a struct that Curl_resolv() returns.  It
     * returns a Curl_addrinfo pointer that may not always look the same.
     */
    if(dns)
      hp=dns->addr;
    if (hp) {
      char buf[64];
      unsigned short ip[4];
      Curl_printable_address(hp, buf, sizeof(buf));

      if(4 == sscanf( buf, "%hu.%hu.%hu.%hu",
                      &ip[0], &ip[1], &ip[2], &ip[3])) {
        socksreq[4] = (unsigned char)ip[0];
        socksreq[5] = (unsigned char)ip[1];
        socksreq[6] = (unsigned char)ip[2];
        socksreq[7] = (unsigned char)ip[3];
      }
      else
        hp = NULL; /* fail! */

      Curl_resolv_unlock(data, dns); /* not used anymore from now on */
    }
    if(!hp) {
      failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.",
            conn->host.name);
      return CURLE_COULDNT_RESOLVE_HOST;
    }
  }

  *((unsigned short*)&socksreq[8]) = htons(conn->remote_port);

  {
    const int packetsize = 10;

    code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written);
    if ((code != CURLE_OK) || (written != packetsize)) {
      failf(data, "Failed to send SOCKS5 connect request.");
      return CURLE_COULDNT_CONNECT;
    }

    result = blockread_all(conn, sock, (char *)socksreq, packetsize,
                           &actualread, timeout);
    if ((result != CURLE_OK) || (actualread != packetsize)) {
      failf(data, "Failed to receive SOCKS5 connect request ack.");
      return CURLE_COULDNT_CONNECT;
    }

    if (socksreq[0] != 5) { /* version */
      failf(data,
            "SOCKS5 reply has wrong version, version should be 5.");
      return CURLE_COULDNT_CONNECT;
    }
    if (socksreq[1] != 0) { /* Anything besides 0 is an error */
        failf(data,
              "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
              (unsigned char)socksreq[4], (unsigned char)socksreq[5],
              (unsigned char)socksreq[6], (unsigned char)socksreq[7],
              (unsigned int)ntohs(*(unsigned short*)(&socksreq[8])),
              socksreq[1]);
        return CURLE_COULDNT_CONNECT;
    }
  }

  Curl_nonblock(sock, TRUE);
  return CURLE_OK; /* Proxy was successful! */
}

Index: llist.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/llist.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- llist.h	24 Jun 2005 13:00:12 -0000	1.1
+++ llist.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,18 +1,18 @@
 #ifndef __LLIST_H
 #define __LLIST_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -28,29 +28,33 @@
 
 typedef void (*curl_llist_dtor)(void *, void *);
 
-typedef struct _curl_llist_element {
+struct curl_llist_element {
   void *ptr;
 
-  struct _curl_llist_element *prev;
-  struct _curl_llist_element *next;
-} curl_llist_element;
+  struct curl_llist_element *prev;
+  struct curl_llist_element *next;
+};
 
-typedef struct _curl_llist {
-  curl_llist_element *head;
-  curl_llist_element *tail;
+struct curl_llist {
+  struct curl_llist_element *head;
+  struct curl_llist_element *tail;
 
   curl_llist_dtor dtor;
 
   size_t size;
-} curl_llist;
+};
 
-void Curl_llist_init(curl_llist *, curl_llist_dtor);
-curl_llist *Curl_llist_alloc(curl_llist_dtor);
-int Curl_llist_insert_next(curl_llist *, curl_llist_element *, const void *);
-int Curl_llist_insert_prev(curl_llist *, curl_llist_element *, const void *);
-int Curl_llist_remove(curl_llist *, curl_llist_element *, void *);
-int Curl_llist_remove_next(curl_llist *, curl_llist_element *, void *);
-size_t Curl_llist_count(curl_llist *);
-void Curl_llist_destroy(curl_llist *, void *);
+void Curl_llist_init(struct curl_llist *, curl_llist_dtor);
+struct curl_llist *Curl_llist_alloc(curl_llist_dtor);
+int Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *,
+                           const void *);
+int Curl_llist_insert_prev(struct curl_llist *, struct curl_llist_element *,
+                           const void *);
+int Curl_llist_remove(struct curl_llist *, struct curl_llist_element *,
+                      void *);
+int Curl_llist_remove_next(struct curl_llist *, struct curl_llist_element *,
+                           void *);
+size_t Curl_llist_count(struct curl_llist *);
+void Curl_llist_destroy(struct curl_llist *, void *);
 
 #endif

Index: md5.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/md5.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- md5.h	24 Jun 2005 13:00:12 -0000	1.1
+++ md5.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -24,6 +24,6 @@
  ***************************************************************************/
 
 void Curl_md5it(unsigned char *output,
-                unsigned char *input);
+                const unsigned char *input);
 
 #endif

--- NEW FILE: easyif.h ---
#ifndef __EASYIF_H
#define __EASYIF_H
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: easyif.h,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

/*
 * Prototypes for library-wide functions provided by easy.c
 */
void Curl_easy_addmulti(struct SessionHandle *data, void *multi);

void Curl_easy_initHandleData(struct SessionHandle *data);

CURLcode Curl_convert_to_network(struct SessionHandle *data,
                                 char *buffer, size_t length);
CURLcode Curl_convert_from_network(struct SessionHandle *data,
                                 char *buffer, size_t length);
CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
                                 char *buffer, size_t length);

#endif /* __EASYIF_H */

Index: md5.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/md5.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- md5.c	30 Mar 2006 18:49:56 -0000	1.2
+++ md5.c	15 Mar 2007 19:22:13 -0000	1.3
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___ 
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,7 +23,9 @@
 
 #include "setup.h"
 
-#ifndef USE_SSLEAY
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+
+#if !defined(USE_SSLEAY) || !defined(USE_OPENSSL)
 /* This code segment is only used if OpenSSL is not provided, as if it is
    we use the MD5-function provided there instead. No good duplicating
    code! */
@@ -65,7 +67,7 @@
 typedef struct md5_ctx MD5_CTX;
 
 static void MD5_Init(struct md5_ctx *);
-static void MD5_Update(struct md5_ctx *, unsigned char *, unsigned int);
+static void MD5_Update(struct md5_ctx *, const unsigned char *, unsigned int);
 static void MD5_Final(unsigned char [16], struct md5_ctx *);
 
 /* Constants for MD5Transform routine.
@@ -88,11 +90,11 @@
 #define S43 15
 #define S44 21
 
-static void MD5Transform(UINT4 [4], unsigned char [64]);
+static void MD5Transform(UINT4 [4], const unsigned char [64]);
 static void Encode(unsigned char *, UINT4 *, unsigned int);
-static void Decode(UINT4 *, unsigned char *, unsigned int);
+static void Decode(UINT4 *, const unsigned char *, unsigned int);
 
-static unsigned char PADDING[64] = {
+static const unsigned char PADDING[64] = {
   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
@@ -149,9 +151,9 @@
   operation, processing another message block, and updating the
   context.
  */
-static void MD5_Update (struct md5_ctx *context, /* context */
-                        unsigned char *input, /* input block */
-                        unsigned int inputLen)/* length of input block */
+static void MD5_Update (struct md5_ctx *context,    /* context */
+                        const unsigned char *input, /* input block */
+                        unsigned int inputLen)      /* length of input block */
 {
   unsigned int i, bufindex, partLen;
 
@@ -212,7 +214,7 @@
 
 /* MD5 basic transformation. Transforms state based on block. */
 static void MD5Transform(UINT4 state[4],
-                         unsigned char block[64])
+                         const unsigned char block[64])
 {
   UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
 
@@ -320,7 +322,7 @@
    a multiple of 4.
 */
 static void Decode (UINT4 *output,
-                    unsigned char *input,
+                    const unsigned char *input,
                     unsigned int len)
 {
   unsigned int i, j;
@@ -339,10 +341,12 @@
 #include "md5.h"
 
 void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
-                unsigned char *input)
+                const unsigned char *input)
 {
   MD5_CTX ctx;
   MD5_Init(&ctx);
   MD5_Update(&ctx, input, (unsigned int)strlen((char *)input));
   MD5_Final(outbuffer, &ctx);
 }
+
+#endif

Index: easy.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/easy.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- easy.c	24 Jun 2005 13:00:12 -0000	1.1
+++ easy.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -29,14 +29,18 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <ctype.h>
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
+#endif
 
 #include <errno.h>
 
 #include "strequal.h"
 
-#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
+#ifdef WIN32
 #include <time.h>
 #include <io.h>
 #else
@@ -44,7 +48,9 @@
 #include <sys/socket.h>
 #endif
 #include <netinet/in.h>
+#ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
+#endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -71,20 +77,37 @@
 #include "urldata.h"
 #include <curl/curl.h>
 #include "transfer.h"
-#include "ssluse.h"
+#include "sslgen.h"
 #include "url.h"
 #include "getinfo.h"
 #include "hostip.h"
 #include "share.h"
-#include "curl_memory.h"
+#include "strdup.h"
+#include "memory.h"
+#include "progress.h"
+#include "easyif.h"
+#include "sendf.h" /* for failf function prototype */
+#include <ca-bundle.h>
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
 
+#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+#include <iconv.h>
+/* set default codesets for iconv */
+#ifndef CURL_ICONV_CODESET_OF_NETWORK
+#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
+#endif
+#ifndef CURL_ICONV_CODESET_FOR_UTF8
+#define CURL_ICONV_CODESET_FOR_UTF8   "UTF-8"
+#endif
+#define ICONV_ERROR  (size_t)-1
+#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
+
 /* The last #include file should be: */
 #include "memdebug.h"
 
-#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
+#ifdef USE_WINSOCK
 /* win32_cleanup() is for win32 socket cleanup functionality, the opposite
    of win32_init() */
 static void win32_cleanup(void)
@@ -100,12 +123,12 @@
   WSADATA wsaData;
   int err;
 
-#ifdef ENABLE_IPV6
-  wVersionRequested = MAKEWORD(2, 0);
-#else
-  wVersionRequested = MAKEWORD(1, 1);
+#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
+  Error IPV6_requires_winsock2
 #endif
 
+  wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
+
   err = WSAStartup(wVersionRequested, &wsaData);
 
   if (err != 0)
@@ -160,17 +183,31 @@
 #endif  /* USE_LIBIDN */
 
 /* true globals -- for curl_global_init() and curl_global_cleanup() */
-static unsigned int  initialized = 0;
-static long          init_flags  = 0;
+static unsigned int  initialized;
+static long          init_flags;
+
+/*
+ * strdup (and other memory functions) is redefined in complicated
+ * ways, but at this point it must be defined as the system-supplied strdup
+ * so the callback pointer is initialized correctly.
+ */
+#if defined(_WIN32_WCE)
+#define system_strdup _strdup
+#elif !defined(HAVE_STRDUP)
+#define system_strdup curlx_strdup
+#else
+#define system_strdup strdup
+#endif
 
 /*
  * If a memory-using function (like curl_getenv) is used before
  * curl_global_init() is called, we need to have these pointers set already.
  */
+
 curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
 curl_free_callback Curl_cfree = (curl_free_callback)free;
 curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
-curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)strdup;
+curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
 curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
 
 /**
@@ -179,18 +216,19 @@
  */
 CURLcode curl_global_init(long flags)
 {
-  if (initialized)
+  if (initialized++)
     return CURLE_OK;
 
   /* Setup the default memory functions here (again) */
   Curl_cmalloc = (curl_malloc_callback)malloc;
   Curl_cfree = (curl_free_callback)free;
   Curl_crealloc = (curl_realloc_callback)realloc;
-  Curl_cstrdup = (curl_strdup_callback)strdup;
+  Curl_cstrdup = (curl_strdup_callback)system_strdup;
   Curl_ccalloc = (curl_calloc_callback)calloc;
 
   if (flags & CURL_GLOBAL_SSL)
-    Curl_SSL_init();
+    if (!Curl_ssl_init())
+      return CURLE_FAILED_INIT;
 
   if (flags & CURL_GLOBAL_WIN32)
     if (win32_init() != CURLE_OK)
@@ -205,7 +243,6 @@
   idna_init();
 #endif
 
-  initialized = 1;
   init_flags  = flags;
 
   return CURLE_OK;
@@ -219,7 +256,7 @@
                               curl_free_callback f, curl_realloc_callback r,
                               curl_strdup_callback s, curl_calloc_callback c)
 {
-  CURLcode code;
+  CURLcode code = CURLE_OK;
 
   /* Invalid input, return immediately */
   if (!m || !f || !r || !s || !c)
@@ -251,10 +288,13 @@
   if (!initialized)
     return;
 
+  if (--initialized)
+    return;
+
   Curl_global_host_cache_dtor();
 
   if (init_flags & CURL_GLOBAL_SSL)
-    Curl_SSL_cleanup();
+    Curl_ssl_cleanup();
 
   if (init_flags & CURL_GLOBAL_WIN32)
     win32_cleanup();
@@ -263,7 +303,6 @@
   amiga_cleanup();
 #endif
 
-  initialized = 0;
   init_flags  = 0;
 }
 
@@ -296,14 +335,10 @@
  * curl_easy_setopt() is the external interface for setting options on an
  * easy handle.
  */
-typedef int (*func_T)(void);
+
 CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
 {
   va_list arg;
-  func_T param_func;
-  long param_long;
-  void *param_obj;
-  curl_off_t param_offset;
   struct SessionHandle *data = curl;
   CURLcode ret;
 
@@ -312,38 +347,95 @@
 
   va_start(arg, tag);
 
-  /* PORTING NOTE:
-     Object pointers can't necessarily be casted to function pointers and
-     therefore we need to know what type it is and read the correct type
-     at once. This should also correct problems with different sizes of
-     the types.
-  */
-
-  if(tag < CURLOPTTYPE_OBJECTPOINT) {
-    /* This is a LONG type */
-    param_long = va_arg(arg, long);
-    ret = Curl_setopt(data, tag, param_long);
-  }
-  else if(tag < CURLOPTTYPE_FUNCTIONPOINT) {
-    /* This is a object pointer type */
-    param_obj = va_arg(arg, void *);
-    ret = Curl_setopt(data, tag, param_obj);
-  }
-  else if(tag < CURLOPTTYPE_OFF_T) {
-    /* This is a function pointer type */
-    param_func = va_arg(arg, func_T );
-    ret = Curl_setopt(data, tag, param_func);
-  }
-  else {
-    /* This is a curl_off_t type */
-    param_offset = va_arg(arg, curl_off_t);
-    ret = Curl_setopt(data, tag, param_offset);
-  }
+  ret = Curl_setopt(data, tag, arg);
 
   va_end(arg);
   return ret;
 }
 
+#ifdef CURL_MULTIEASY
+/***************************************************************************
+ * This function is still only for testing purposes. It makes a great way
+ * to run the full test suite on the multi interface instead of the easy one.
+ ***************************************************************************
+ *
+ * The *new* curl_easy_perform() is the external interface that performs a
+ * transfer previously setup.
+ *
+ * Wrapper-function that: creates a multi handle, adds the easy handle to it,
+ * runs curl_multi_perform() until the transfer is done, then detaches the
+ * easy handle, destroys the multi handle and returns the easy handle's return
+ * code. This will make everything internally use and assume multi interface.
+ */
+CURLcode curl_easy_perform(CURL *easy)
+{
+  CURLM *multi;
+  CURLMcode mcode;
+  CURLcode code = CURLE_OK;
+  int still_running;
+  struct timeval timeout;
+  int rc;
+  CURLMsg *msg;
+  fd_set fdread;
+  fd_set fdwrite;
+  fd_set fdexcep;
+  int maxfd;
+
+  if(!easy)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  multi = curl_multi_init();
+  if(!multi)
+    return CURLE_OUT_OF_MEMORY;
+
+  mcode = curl_multi_add_handle(multi, easy);
+  if(mcode) {
+    curl_multi_cleanup(multi);
+    return CURLE_FAILED_INIT;
+  }
+
+  /* we start some action by calling perform right away */
+
+  do {
+    while(CURLM_CALL_MULTI_PERFORM ==
+          curl_multi_perform(multi, &still_running));
+
+    if(!still_running)
+      break;
+
+    FD_ZERO(&fdread);
+    FD_ZERO(&fdwrite);
+    FD_ZERO(&fdexcep);
+
+    /* timeout once per second */
+    timeout.tv_sec = 1;
+    timeout.tv_usec = 0;
+
+    /* get file descriptors from the transfers */
+    curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+    rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+    if(rc == -1)
+      /* select error */
+      break;
+
+    /* timeout or data to send/receive => loop! */
+  } while(still_running);
+
+  msg = curl_multi_info_read(multi, &rc);
+  if(msg)
+    code = msg->data.result;
+
+  mcode = curl_multi_remove_handle(multi, easy);
+  /* what to do if it fails? */
+
+  mcode = curl_multi_cleanup(multi);
+  /* what to do if it fails? */
+
+  return code;
+}
+#else
 /*
  * curl_easy_perform() is the external interface that performs a transfer
  * previously setup.
@@ -358,16 +450,18 @@
   if ( ! (data->share && data->share->hostcache) ) {
 
     if (Curl_global_host_cache_use(data) &&
-        data->hostcache != Curl_global_host_cache_get()) {
-      if (data->hostcache)
-        Curl_hash_destroy(data->hostcache);
-      data->hostcache = Curl_global_host_cache_get();
+        (data->dns.hostcachetype != HCACHE_GLOBAL)) {
+      if (data->dns.hostcachetype == HCACHE_PRIVATE)
+        Curl_hash_destroy(data->dns.hostcache);
+      data->dns.hostcache = Curl_global_host_cache_get();
+      data->dns.hostcachetype = HCACHE_GLOBAL;
     }
 
-    if (!data->hostcache) {
-      data->hostcache = Curl_mk_dnscache();
+    if (!data->dns.hostcache) {
+      data->dns.hostcachetype = HCACHE_PRIVATE;
+      data->dns.hostcache = Curl_mk_dnscache();
 
-      if(!data->hostcache)
+      if(!data->dns.hostcache)
         /* While we possibly could survive and do good without a host cache,
            the fact that creating it failed indicates that things are truly
            screwed up and we should bail out! */
@@ -376,8 +470,16 @@
 
   }
 
+  if(!data->state.connc) {
+    /* oops, no connection cache, make one up */
+    data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1);
+    if(!data->state.connc)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
   return Curl_perform(data);
 }
+#endif
 
 /*
  * curl_easy_cleanup() is the external interface to cleaning/freeing the given
@@ -390,15 +492,26 @@
   if(!data)
     return;
 
-  if ( ! (data->share && data->share->hostcache) ) {
-    if ( !Curl_global_host_cache_use(data)) {
-      Curl_hash_destroy(data->hostcache);
-    }
-  }
   Curl_close(data);
 }
 
 /*
+ * Store a pointed to the multi handle within the easy handle's data struct.
+ */
+void Curl_easy_addmulti(struct SessionHandle *data,
+                        void *multi)
+{
+  data->multi = multi;
+}
+
+void Curl_easy_initHandleData(struct SessionHandle *data)
+{
+    memset(&data->reqdata, 0, sizeof(struct HandleData));
+
+    data->reqdata.maxdownload = -1;
+}
+
+/*
  * curl_easy_getinfo() is an external interface that allows an app to retrieve
  * information from a performed transfer and similar.
  */
@@ -445,21 +558,21 @@
 
     /* copy all userdefined values */
     outcurl->set = data->set;
-    outcurl->state.numconnects = data->state.numconnects;
-    outcurl->state.connects = (struct connectdata **)
-      malloc(sizeof(struct connectdata *) * outcurl->state.numconnects);
 
-    if(!outcurl->state.connects) {
+    if(data->state.used_interface == Curl_if_multi)
+      outcurl->state.connc = data->state.connc;
+    else
+      outcurl->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1);
+
+    if(!outcurl->state.connc)
       break;
-    }
 
-    memset(outcurl->state.connects, 0,
-           sizeof(struct connectdata *)*outcurl->state.numconnects);
+    outcurl->state.lastconnect = -1;
 
     outcurl->progress.flags    = data->progress.flags;
     outcurl->progress.callback = data->progress.callback;
 
-#ifndef CURL_DISABLE_HTTP
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
     if(data->cookies) {
       /* If cookies are enabled in the parent handle, we enable them
          in the clone as well! */
@@ -474,18 +587,14 @@
 #endif   /* CURL_DISABLE_HTTP */
 
     /* duplicate all values in 'change' */
+
     if(data->change.url) {
       outcurl->change.url = strdup(data->change.url);
       if(!outcurl->change.url)
         break;
       outcurl->change.url_alloc = TRUE;
     }
-    if(data->change.proxy) {
-      outcurl->change.proxy = strdup(data->change.proxy);
-      if(!outcurl->change.proxy)
-        break;
-      outcurl->change.proxy_alloc = TRUE;
-    }
+
     if(data->change.referer) {
       outcurl->change.referer = strdup(data->change.referer);
       if(!outcurl->change.referer)
@@ -499,18 +608,29 @@
       break;
 #endif
 
+#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+    outcurl->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+                                     CURL_ICONV_CODESET_OF_NETWORK);
+    outcurl->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
+                                      CURL_ICONV_CODESET_OF_HOST);
+    outcurl->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+                                  CURL_ICONV_CODESET_FOR_UTF8);
+#endif
+
+    Curl_easy_initHandleData(outcurl);
+
+    outcurl->magic = CURLEASY_MAGIC_NUMBER;
+
     fail = FALSE; /* we reach this point and thus we are OK */
 
   } while(0);
 
   if(fail) {
     if(outcurl) {
-      if(outcurl->state.connects)
-        free(outcurl->state.connects);
+      if(outcurl->state.connc->type == CONNCACHE_PRIVATE)
+        Curl_rm_connc(outcurl->state.connc);
       if(outcurl->state.headerbuff)
         free(outcurl->state.headerbuff);
-      if(outcurl->change.proxy)
-        free(outcurl->change.proxy);
       if(outcurl->change.url)
         free(outcurl->change.url);
       if(outcurl->change.referer)
@@ -531,12 +651,21 @@
 {
   struct SessionHandle *data = (struct SessionHandle *)curl;
 
+  Curl_safefree(data->reqdata.pathbuffer);
+  data->reqdata.pathbuffer=NULL;
+
+  Curl_safefree(data->reqdata.proto.generic);
+  data->reqdata.proto.generic=NULL;
+
   /* zero out UserDefined data: */
   memset(&data->set, 0, sizeof(struct UserDefined));
 
   /* zero out Progress data: */
   memset(&data->progress, 0, sizeof(struct Progress));
 
+  /* init Handle data */
+  Curl_easy_initHandleData(data);
+
   /* The remainder of these calls have been taken from Curl_open() */
 
   data->set.out = stdout; /* default output to stdout */
@@ -550,6 +679,7 @@
   data->set.fread = (curl_read_callback)fread;
 
   data->set.infilesize = -1; /* we don't know any size */
+  data->set.postfieldsize = -1;
 
   data->state.current_speed = -1; /* init to negative == impossible */
 
@@ -561,6 +691,7 @@
 
   /* make libcurl quiet by default: */
   data->set.hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */
+  data->progress.flags |= PGRS_HIDE;
 
   /* Set the default size of the SSL session ID cache */
   data->set.ssl.numsessions = 5;
@@ -580,4 +711,185 @@
   /* This is our prefered CA cert bundle since install time */
   data->set.ssl.CAfile = (char *)CURL_CA_BUNDLE;
 #endif
+
+  data->set.ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
+                                                      type */
 }
+
+#ifdef CURL_DOES_CONVERSIONS
+/*
+ * Curl_convert_to_network() is an internal function
+ * for performing ASCII conversions on non-ASCII platforms.
+ */
+CURLcode Curl_convert_to_network(struct SessionHandle *data,
+                                 char *buffer, size_t length)
+{
+  CURLcode rc;
+
+  if(data->set.convtonetwork) {
+    /* use translation callback */
+    rc = data->set.convtonetwork(buffer, length);
+    if(rc != CURLE_OK) {
+      failf(data,
+            "CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %i: %s",
+            rc, curl_easy_strerror(rc));
+    }
+    return(rc);
+  } else {
+#ifdef HAVE_ICONV
+    /* do the translation ourselves */
+    char *input_ptr, *output_ptr;
+    size_t in_bytes, out_bytes, rc;
+
+    /* open an iconv conversion descriptor if necessary */
+    if(data->outbound_cd == (iconv_t)-1) {
+      data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
+                                     CURL_ICONV_CODESET_OF_HOST);
+      if(data->outbound_cd == (iconv_t)-1) {
+        failf(data,
+              "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
+               CURL_ICONV_CODESET_OF_NETWORK,
+               CURL_ICONV_CODESET_OF_HOST,
+               errno, strerror(errno));
+        return CURLE_CONV_FAILED;
+      }
+    }
+    /* call iconv */
+    input_ptr = output_ptr = buffer;
+    in_bytes = out_bytes = length;
+    rc = iconv(data->outbound_cd, (const char**)&input_ptr, &in_bytes,
+               &output_ptr, &out_bytes);
+    if ((rc == ICONV_ERROR) || (in_bytes != 0)) {
+      failf(data,
+        "The Curl_convert_to_network iconv call failed with errno %i: %s",
+             errno, strerror(errno));
+      return CURLE_CONV_FAILED;
+    }
+#else
+    failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required");
+    return CURLE_CONV_REQD;
+#endif /* HAVE_ICONV */
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_convert_from_network() is an internal function
+ * for performing ASCII conversions on non-ASCII platforms.
+ */
+CURLcode Curl_convert_from_network(struct SessionHandle *data,
+                                      char *buffer, size_t length)
+{
+  CURLcode rc;
+
+  if(data->set.convfromnetwork) {
+    /* use translation callback */
+    rc = data->set.convfromnetwork(buffer, length);
+    if(rc != CURLE_OK) {
+      failf(data,
+            "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %i: %s",
+            rc, curl_easy_strerror(rc));
+    }
+    return(rc);
+  } else {
+#ifdef HAVE_ICONV
+    /* do the translation ourselves */
+    char *input_ptr, *output_ptr;
+    size_t in_bytes, out_bytes, rc;
+
+    /* open an iconv conversion descriptor if necessary */
+    if(data->inbound_cd == (iconv_t)-1) {
+      data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+                                    CURL_ICONV_CODESET_OF_NETWORK);
+      if(data->inbound_cd == (iconv_t)-1) {
+        failf(data,
+              "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
+               CURL_ICONV_CODESET_OF_HOST,
+               CURL_ICONV_CODESET_OF_NETWORK,
+               errno, strerror(errno));
+        return CURLE_CONV_FAILED;
+      }
+    }
+    /* call iconv */
+    input_ptr = output_ptr = buffer;
+    in_bytes = out_bytes = length;
+    rc = iconv(data->inbound_cd, (const char **)&input_ptr, &in_bytes,
+               &output_ptr, &out_bytes);
+    if ((rc == ICONV_ERROR) || (in_bytes != 0)) {
+      failf(data,
+        "The Curl_convert_from_network iconv call failed with errno %i: %s",
+             errno, strerror(errno));
+      return CURLE_CONV_FAILED;
+    }
+#else
+    failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required");
+    return CURLE_CONV_REQD;
+#endif /* HAVE_ICONV */
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_convert_from_utf8() is an internal function
+ * for performing UTF-8 conversions on non-ASCII platforms.
+ */
+CURLcode Curl_convert_from_utf8(struct SessionHandle *data,
+                                     char *buffer, size_t length)
+{
+  CURLcode rc;
+
+  if(data->set.convfromutf8) {
+    /* use translation callback */
+    rc = data->set.convfromutf8(buffer, length);
+    if(rc != CURLE_OK) {
+      failf(data,
+            "CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %i: %s",
+            rc, curl_easy_strerror(rc));
+    }
+    return(rc);
+  } else {
+#ifdef HAVE_ICONV
+    /* do the translation ourselves */
+    char *input_ptr, *output_ptr;
+    size_t in_bytes, out_bytes, rc;
+
+    /* open an iconv conversion descriptor if necessary */
+    if(data->utf8_cd == (iconv_t)-1) {
+      data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+                                 CURL_ICONV_CODESET_FOR_UTF8);
+      if(data->utf8_cd == (iconv_t)-1) {
+        failf(data,
+              "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
+               CURL_ICONV_CODESET_OF_HOST,
+               CURL_ICONV_CODESET_FOR_UTF8,
+               errno, strerror(errno));
+        return CURLE_CONV_FAILED;
+      }
+    }
+    /* call iconv */
+    input_ptr = output_ptr = buffer;
+    in_bytes = out_bytes = length;
+    rc = iconv(data->utf8_cd, (const char**)&input_ptr, &in_bytes,
+               &output_ptr, &out_bytes);
+    if ((rc == ICONV_ERROR) || (in_bytes != 0)) {
+      failf(data,
+        "The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
+             errno, strerror(errno));
+      return CURLE_CONV_FAILED;
+    }
+    if (output_ptr < input_ptr) {
+      /* null terminate the now shorter output string */
+      *output_ptr = 0x00;
+    }
+#else
+    failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
+    return CURLE_CONV_REQD;
+#endif /* HAVE_ICONV */
+  }
+
+  return CURLE_OK;
+}
+
+#endif /* CURL_DOES_CONVERSIONS */

Index: file.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/file.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- file.c	24 Jun 2005 13:00:12 -0000	1.1
+++ file.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -30,12 +30,14 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <ctype.h>
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
+#endif
 
-#include <errno.h>
-
-#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
+#ifdef WIN32
 #include <time.h>
 #include <io.h>
 #include <fcntl.h>
@@ -46,7 +48,9 @@
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
+#ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
+#endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -66,9 +70,6 @@
 #include <sys/param.h>
 #endif
 
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
 #ifdef HAVE_FCNTL_H
 #include <fcntl.h>
 #endif
@@ -85,7 +86,8 @@
 #include "getinfo.h"
 #include "transfer.h"
 #include "url.h"
-#include "curl_memory.h"
+#include "memory.h"
+#include "parsedate.h" /* for the week day and month names */
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -100,10 +102,10 @@
  */
 CURLcode Curl_file_connect(struct connectdata *conn)
 {
-  char *real_path = curl_unescape(conn->path, 0);
+  char *real_path = curl_easy_unescape(conn->data, conn->data->reqdata.path, 0, NULL);
   struct FILEPROTO *file;
   int fd;
-#if defined(WIN32) || defined(__EMX__)
+#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
   int i;
   char *actual_path;
 #endif
@@ -117,9 +119,13 @@
     return CURLE_OUT_OF_MEMORY;
   }
 
-  conn->proto.file = file;
+  if (conn->data->reqdata.proto.file) {
+    free(conn->data->reqdata.proto.file);
+  }
 
-#if defined(WIN32) || defined(__EMX__)
+  conn->data->reqdata.proto.file = file;
+
+#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
   /* If the first character is a slash, and there's
      something that looks like a drive at the beginning of
      the path, skip the slash.  If we remove the initial
@@ -143,7 +149,7 @@
     actual_path++;
   }
 
-  /* change path separators from '/' to '\\' for Windows and OS/2 */
+  /* change path separators from '/' to '\\' for DOS, Windows and OS/2 */
   for (i=0; actual_path[i] != '\0'; ++i)
     if (actual_path[i] == '/')
       actual_path[i] = '\\';
@@ -156,31 +162,31 @@
 #endif
   file->freepath = real_path; /* free this when done */
 
+  file->fd = fd;
   if(!conn->data->set.upload && (fd == -1)) {
-    failf(conn->data, "Couldn't open file %s", conn->path);
-    Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE);
+    failf(conn->data, "Couldn't open file %s", conn->data->reqdata.path);
+    Curl_file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
     return CURLE_FILE_COULDNT_READ_FILE;
   }
-  file->fd = fd;
 
   return CURLE_OK;
 }
 
-#if defined(WIN32) && (SIZEOF_CURL_OFF_T > 4)
-#define lseek(x,y,z) _lseeki64(x, y, z)
-#endif
-
 CURLcode Curl_file_done(struct connectdata *conn,
-                        CURLcode status)
+                        CURLcode status, bool premature)
 {
-  struct FILEPROTO *file = conn->proto.file;
+  struct FILEPROTO *file = conn->data->reqdata.proto.file;
   (void)status; /* not used */
+  (void)premature; /* not used */
   Curl_safefree(file->freepath);
 
+  if(file->fd != -1)
+    close(file->fd);
+
   return CURLE_OK;
 }
 
-#if defined(WIN32) || defined(__EMX__)
+#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
 #define DIRSEP '\\'
 #else
 #define DIRSEP '/'
@@ -188,7 +194,7 @@
 
 static CURLcode file_upload(struct connectdata *conn)
 {
-  struct FILEPROTO *file = conn->proto.file;
+  struct FILEPROTO *file = conn->data->reqdata.proto.file;
   char *dir = strchr(file->path, DIRSEP);
   FILE *fp;
   CURLcode res=CURLE_OK;
@@ -205,7 +211,7 @@
    */
   conn->fread = data->set.fread;
   conn->fread_in = data->set.in;
-  conn->upload_fromhere = buf;
+  conn->data->reqdata.upload_fromhere = buf;
 
   if(!dir)
     return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
@@ -227,13 +233,13 @@
     int readcount;
     res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
     if(res)
-      return res;
-
-    nread = (size_t)readcount;
+      break;
 
-    if (nread <= 0)
+    if (readcount <= 0)  /* fix questionable compare error. curlvms */
       break;
 
+    nread = (size_t)readcount;
+
     /* write the data to the target */
     nwrite = fwrite(buf, 1, nread, fp);
     if(nwrite != nread) {
@@ -266,7 +272,7 @@
  * opposed to sockets) we instead perform the whole do-operation in this
  * function.
  */
-CURLcode Curl_file(struct connectdata *conn)
+CURLcode Curl_file(struct connectdata *conn, bool *done)
 {
   /* This implementation ignores the host name in conformance with
      RFC 1738. Only local files (reachable via the standard file system)
@@ -274,7 +280,9 @@
      (via NFS, Samba, NT sharing) can be accessed through a file:// URL
   */
   CURLcode res = CURLE_OK;
-  struct stat statbuf;
+  struct_stat statbuf; /* struct_stat instead of struct stat just to allow the
+                          Windows version to have a different struct without
+                          having to redefine the simple word 'stat' */
   curl_off_t expected_size=0;
   bool fstated=FALSE;
   ssize_t nread;
@@ -284,6 +292,8 @@
   int fd;
   struct timeval now = Curl_tvnow();
 
+  *done = TRUE; /* unconditionally */
+
   Curl_readwrite_init(conn);
   Curl_initinfo(data);
   Curl_pgrsStartNow(data);
@@ -292,7 +302,7 @@
     return file_upload(conn);
 
   /* get the fd from the connection phase */
-  fd = conn->proto.file->fd;
+  fd = conn->data->reqdata.proto.file->fd;
 
   /* VMS: This only works reliable for STREAMLF files */
   if( -1 != fstat(fd, &statbuf)) {
@@ -308,40 +318,45 @@
     CURLcode result;
     snprintf(buf, sizeof(data->state.buffer),
              "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
-    result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
+    result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
     if(result)
       return result;
 
-    result = Curl_client_write(data, CLIENTWRITE_BOTH,
+    result = Curl_client_write(conn, CLIENTWRITE_BOTH,
                                (char *)"Accept-ranges: bytes\r\n", 0);
     if(result)
       return result;
 
-#ifdef HAVE_STRFTIME
     if(fstated) {
       struct tm *tm;
-      time_t cuClock = (time_t)statbuf.st_mtime;
+      time_t clock = (time_t)statbuf.st_mtime;
 #ifdef HAVE_GMTIME_R
       struct tm buffer;
-      tm = (struct tm *)gmtime_r(&cuClock, &buffer);
+      tm = (struct tm *)gmtime_r(&clock, &buffer);
 #else
-      tm = gmtime(&cuClock);
+      tm = gmtime(&clock);
 #endif
       /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
-      strftime(buf, BUFSIZE-1, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT\r\n",
-               tm);
-      result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
+      snprintf(buf, BUFSIZE-1,
+               "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
+               Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+               tm->tm_mday,
+               Curl_month[tm->tm_mon],
+               tm->tm_year + 1900,
+               tm->tm_hour,
+               tm->tm_min,
+               tm->tm_sec);
+      result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
     }
-#endif
     return result;
   }
 
-  /* Added by Dolbneff A.V & Spiridonoff A.V */
-  if (conn->resume_from <= expected_size)
-    expected_size -= conn->resume_from;
-  else
-    /* Is this error code suitable in such situation? */
-    return CURLE_FTP_BAD_DOWNLOAD_RESUME;
+  if (data->reqdata.resume_from <= expected_size)
+    expected_size -= data->reqdata.resume_from;
+  else {
+    failf(data, "failed to resume file:// transfer");
+    return CURLE_BAD_DOWNLOAD_RESUME;
+  }
 
   if (fstated && (expected_size == 0))
     return CURLE_OK;
@@ -353,8 +368,11 @@
   if(fstated)
     Curl_pgrsSetDownloadSize(data, expected_size);
 
-  if(conn->resume_from)
-    lseek(fd, conn->resume_from, SEEK_SET);
+  if(data->reqdata.resume_from) {
+    if(data->reqdata.resume_from !=
+       lseek(fd, data->reqdata.resume_from, SEEK_SET))
+      return CURLE_BAD_DOWNLOAD_RESUME;
+  }
 
   Curl_pgrsTime(data, TIMER_STARTTRANSFER);
 
@@ -369,7 +387,7 @@
 
     bytecount += nread;
 
-    res = Curl_client_write(data, CLIENTWRITE_BODY, buf, nread);
+    res = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
     if(res)
       return res;
 
@@ -383,8 +401,7 @@
   if(Curl_pgrsUpdate(conn))
     res = CURLE_ABORTED_BY_CALLBACK;
 
-  close(fd);
-
   return res;
 }
+
 #endif

Index: formdata.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/formdata.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- formdata.c	9 Mar 2006 13:20:30 -0000	1.2
+++ formdata.c	15 Mar 2007 19:22:13 -0000	1.3
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,7 +24,7 @@
 /*
   Debug the form generator stand-alone by compiling this source file with:
 
-  gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -o formdata -I../include formdata.c strequal.c
+  gcc -DHAVE_CONFIG_H -I../ -g -D_FORM_DEBUG -DCURLDEBUG -o formdata -I../include formdata.c strequal.c memdebug.c mprintf.c strerror.c
 
   run the 'formdata' executable the output should end with:
   All Tests seem to have worked ...
@@ -63,7 +63,7 @@
 Content-Disposition: attachment; filename="inet_ntoa_r.h"
 Content-Type: text/plain
 ...
-Content-Disposition: attachment; filename="Makefile.b32.resp"
+Content-Disposition: attachment; filename="Makefile.b32"
 Content-Type: text/plain
 ...
 
@@ -73,7 +73,7 @@
 Content-Disposition: attachment; filename="inet_ntoa_r.h"
 Content-Type: text/plain
 ...
-Content-Disposition: attachment; filename="Makefile.b32.resp"
+Content-Disposition: attachment; filename="Makefile.b32"
 Content-Type: text/plain
 ...
 Content-Disposition: attachment; filename="inet_ntoa_r.h"
@@ -87,7 +87,7 @@
 Content-Disposition: attachment; filename="inet_ntoa_r.h"
 Content-Type: text/plain
 ...
-Content-Disposition: attachment; filename="Makefile.b32.resp"
+Content-Disposition: attachment; filename="Makefile.b32"
 Content-Type: text/plain
 ...
 Content-Disposition: attachment; filename="inet_ntoa_r.h"
@@ -105,17 +105,24 @@
 /* Length of the random boundary string. */
 #define BOUNDARY_LENGTH 40
 
-#ifndef CURL_DISABLE_HTTP
+#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
 #include <time.h>
+#ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
+#endif
+#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
+#include <libgen.h>
+#endif
+#include "urldata.h" /* for struct SessionHandle */
+#include "easyif.h" /* for Curl_convert_... prototypes */
 #include "formdata.h"
 #include "strequal.h"
-#include "curl_memory.h"
+#include "memory.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -123,6 +130,17 @@
 /* The last #include file should be: */
 #include "memdebug.h"
 
+#endif  /* !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) */
+
+#ifndef CURL_DISABLE_HTTP
+
+#if defined(HAVE_BASENAME) && defined(NEED_BASENAME_PROTO)
+/* This system has a basename() but no prototype for it! */
+char *basename(char *path);
+#endif
+
+static size_t readfromfile(struct Form *form, char *buffer, size_t size);
+
 /* What kind of Content-Type to use on un-specified files with unrecognized
    extensions. */
 #define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream"
@@ -241,7 +259,7 @@
 static const char * ContentTypeForFilename (const char *filename,
                                             const char *prevtype)
 {
-  const char *contenttype;
+  const char *contenttype = NULL;
   unsigned int i;
   /*
    * No type was specified, we scan through a few well-known
@@ -251,7 +269,7 @@
     const char *extension;
     const char *type;
   };
-  static struct ContentType ctts[]={
+  static const struct ContentType ctts[]={
     {".gif",  "image/gif"},
     {".jpg",  "image/jpeg"},
     {".jpeg", "image/jpeg"},
@@ -374,7 +392,7 @@
   FormInfo *first_form, *current_form, *form = NULL;
   CURLFORMcode return_value = CURL_FORMADD_OK;
   const char *prevtype = NULL;
-  struct curl_httppost *post;
+  struct curl_httppost *post = NULL;
   CURLformoption option;
   struct curl_forms *forms = NULL;
   char *array_value=NULL; /* value read from an array */
@@ -436,7 +454,12 @@
        * Set the Name property.
        */
     case CURLFORM_PTRNAME:
+#ifdef CURL_DOES_CONVERSIONS
+      /* treat CURLFORM_PTR like CURLFORM_COPYNAME so we'll
+         have safe memory for the eventual conversion */
+#else
       current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
+#endif
     case CURLFORM_COPYNAME:
       if (current_form->name)
         return_value = CURL_FORMADD_OPTION_TWICE;
@@ -454,7 +477,7 @@
         return_value = CURL_FORMADD_OPTION_TWICE;
       else
         current_form->namelength =
-          array_state?(long)array_value:va_arg(params, long);
+          array_state?(long)array_value:(long)va_arg(params, long);
       break;
 
       /*
@@ -512,8 +535,8 @@
         if (current_form->value) {
           if (current_form->flags & HTTPPOST_FILENAME) {
             if (filename) {
-              if (!(current_form = AddFormInfo(strdup(filename),
-                                               NULL, current_form)))
+              if ((current_form = AddFormInfo(strdup(filename),
+                                              NULL, current_form)) == NULL)
                 return_value = CURL_FORMADD_MEMORY;
             }
             else
@@ -546,8 +569,8 @@
         if (current_form->value) {
           if (current_form->flags & HTTPPOST_BUFFER) {
             if (filename) {
-              if (!(current_form = AddFormInfo(strdup(filename),
-                                               NULL, current_form)))
+              if ((current_form = AddFormInfo(strdup(filename),
+                                              NULL, current_form)) == NULL)
                 return_value = CURL_FORMADD_MEMORY;
             }
             else
@@ -598,9 +621,9 @@
         if (current_form->contenttype) {
           if (current_form->flags & HTTPPOST_FILENAME) {
             if (contenttype) {
-              if (!(current_form = AddFormInfo(NULL,
-                                               strdup(contenttype),
-                                               current_form)))
+              if ((current_form = AddFormInfo(NULL,
+                                              strdup(contenttype),
+                                              current_form)) == NULL)
                 return_value = CURL_FORMADD_MEMORY;
             }
             else
@@ -626,15 +649,9 @@
       {
         /* this "cast increases required alignment of target type" but
            we consider it OK anyway */
-        struct curl_slist* list = 0;
-        if ( array_state )
-          {
-          memcpy(&list, &array_value, sizeof(struct curl_slist*));
-          }
-        else
-          {
-          list = va_arg(params, struct curl_slist*);
-          }
+        struct curl_slist* list = array_state?
+          (struct curl_slist*)array_value:
+          va_arg(params, struct curl_slist*);
 
         if( current_form->contentheader )
           return_value = CURL_FORMADD_OPTION_TWICE;
@@ -825,13 +842,13 @@
     *formp = newform;
 
   if (size) {
-    if(type == FORM_DATA)
+    if((type == FORM_DATA) || (type == FORM_CONTENT))
       *size += length;
     else {
       /* Since this is a file to be uploaded here, add the size of the actual
          file */
       if(!strequal("-", newform->line)) {
-        struct stat file;
+        struct_stat file;
         if(!stat(newform->line, &file)) {
           *size += file.st_size;
         }
@@ -862,10 +879,11 @@
  * Curl_formclean() is used from http.c, this cleans a built FormData linked
  * list
  */
-void Curl_formclean(struct FormData *form)
+void Curl_formclean(struct FormData **form_ptr)
 {
-  struct FormData *next;
+  struct FormData *next, *form;
 
+  form = *form_ptr;
   if(!form)
     return;
 
@@ -874,7 +892,84 @@
     free(form->line); /* free the line */
     free(form);       /* free the struct */
 
-  } while((form=next)); /* continue */
+  } while ((form = next) != NULL); /* continue */
+
+  *form_ptr = NULL;
+}
+
+#ifdef CURL_DOES_CONVERSIONS
+/*
+ * Curl_formcovert() is used from http.c, this converts any
+   form items that need to be sent in the network encoding.
+   Returns CURLE_OK on success.
+ */
+CURLcode Curl_formconvert(struct SessionHandle *data, struct FormData *form)
+{
+  struct FormData *next;
+  CURLcode rc;
+
+  if(!form)
+    return CURLE_OK;
+
+  if(!data)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  do {
+    next=form->next;  /* the following form line */
+    if (form->type == FORM_DATA) {
+      rc = Curl_convert_to_network(data, form->line, form->length);
+      /* Curl_convert_to_network calls failf if unsuccessful */
+      if (rc != CURLE_OK)
+        return rc;
+    }
+  } while ((form = next) != NULL); /* continue */
+  return CURLE_OK;
+}
+#endif /* CURL_DOES_CONVERSIONS */
+
+/*
+ * curl_formget()
+ * Serialize a curl_httppost struct.
+ * Returns 0 on success.
+ */
+int curl_formget(struct curl_httppost *form, void *arg,
+                 curl_formget_callback append)
+{
+  CURLcode rc;
+  curl_off_t size;
+  struct FormData *data, *ptr;
+
+  rc = Curl_getFormData(&data, form, NULL, &size);
+  if (rc != CURLE_OK)
+    return (int)rc;
+
+  for (ptr = data; ptr; ptr = ptr->next) {
+    if (ptr->type == FORM_FILE) {
+      char buffer[8192];
+      size_t read;
+      struct Form temp;
+
+      Curl_FormInit(&temp, ptr);
+
+      do {
+        read = readfromfile(&temp, buffer, sizeof(buffer));
+        if ((read == (size_t) -1) || (read != append(arg, buffer, read))) {
+          if (temp.fp) {
+            fclose(temp.fp);
+          }
+          Curl_formclean(&data);
+          return -1;
+        }
+      } while (read == sizeof(buffer));
+    } else {
+      if (ptr->length != append(arg, ptr->line, ptr->length)) {
+        Curl_formclean(&data);
+        return -1;
+      }
+    }
+  }
+  Curl_formclean(&data);
+  return 0;
 }
 
 /*
@@ -906,7 +1001,69 @@
       free(form->showfilename); /* free the faked file name */
     free(form);       /* free the struct */
 
-  } while((form=next)); /* continue */
+  } while ((form = next) != NULL); /* continue */
+}
+
+#ifndef HAVE_BASENAME
+/*
+  (Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004
+  Edition)
+
+  The basename() function shall take the pathname pointed to by path and
+  return a pointer to the final component of the pathname, deleting any
+  trailing '/' characters.
+
+  If the string pointed to by path consists entirely of the '/' character,
+  basename() shall return a pointer to the string "/". If the string pointed
+  to by path is exactly "//", it is implementation-defined whether '/' or "//"
+  is returned.
+
+  If path is a null pointer or points to an empty string, basename() shall
+  return a pointer to the string ".".
+
+  The basename() function may modify the string pointed to by path, and may
+  return a pointer to static storage that may then be overwritten by a
+  subsequent call to basename().
+
+  The basename() function need not be reentrant. A function that is not
+  required to be reentrant is not required to be thread-safe.
+
+*/
+static char *basename(char *path)
+{
+  /* Ignore all the details above for now and make a quick and simple
+     implementaion here */
+  char *s1;
+  char *s2;
+
+  s1=strrchr(path, '/');
+  s2=strrchr(path, '\\');
+
+  if(s1 && s2) {
+    path = (s1 > s2? s1 : s2)+1;
+  }
+  else if(s1)
+    path = s1 + 1;
+  else if(s2)
+    path = s2 + 1;
+
+  return path;
+}
+#endif
+
+static char *strippath(char *fullfile)
+{
+  char *filename;
+  char *base;
+  filename = strdup(fullfile); /* duplicate since basename() may ruin the
+                                  buffer it works on */
+  if(!filename)
+    return NULL;
+  base = strdup(basename(filename));
+
+  free(filename); /* free temporary buffer */
+
+  return base; /* returns an allocated string! */
 }
 
 /*
@@ -914,10 +1071,13 @@
  * (possibly huge) multipart formdata. The input list is in 'post', while the
  * output resulting linked lists gets stored in '*finalform'. *sizep will get
  * the total size of the whole POST.
+ * A multipart/form_data content-type is built, unless a custom content-type
+ * is passed in 'custom_content_type'.
  */
 
 CURLcode Curl_getFormData(struct FormData **finalform,
                           struct curl_httppost *post,
+                          const char *custom_content_type,
                           curl_off_t *sizep)
 {
   struct FormData *form = NULL;
@@ -941,9 +1101,11 @@
 
   /* Make the first line of the output */
   result = AddFormDataf(&form, NULL,
-                        "Content-Type: multipart/form-data;"
-                        " boundary=%s\r\n",
+                        "%s; boundary=%s\r\n",
+                        custom_content_type?custom_content_type:
+                        "Content-Type: multipart/form-data",
                         boundary);
+
   if (result) {
     free(boundary);
     return result;
@@ -966,6 +1128,10 @@
     if (result)
       break;
 
+    /* Maybe later this should be disabled when a custom_content_type is
+       passed, since Content-Disposition is not meaningful for all multipart
+       types.
+    */
     result = AddFormDataf(&form, &size,
                           "Content-Disposition: form-data; name=\"");
     if (result)
@@ -1004,22 +1170,33 @@
 
       if(post->more) {
         /* if multiple-file */
+        char *filebasename=
+          (!file->showfilename)?strippath(file->contents):NULL;
+
         result = AddFormDataf(&form, &size,
                               "\r\n--%s\r\nContent-Disposition: "
                               "attachment; filename=\"%s\"",
                               fileboundary,
                               (file->showfilename?file->showfilename:
-                               file->contents));
+                               filebasename));
+        if (filebasename)
+          free(filebasename);
         if (result)
           break;
       }
       else if((post->flags & HTTPPOST_FILENAME) ||
               (post->flags & HTTPPOST_BUFFER)) {
 
+        char *filebasename=
+          (!post->showfilename)?strippath(post->contents):NULL;
+
         result = AddFormDataf(&form, &size,
                               "; filename=\"%s\"",
                               (post->showfilename?post->showfilename:
-                               post->contents));
+                               filebasename));
+        if (filebasename)
+          free(filebasename);
+
         if (result)
           break;
       }
@@ -1042,7 +1219,7 @@
         curList = curList->next;
       }
       if (result) {
-        Curl_formclean(firstform);
+        Curl_formclean(&firstform);
         free(boundary);
         return result;
       }
@@ -1057,7 +1234,10 @@
       if(file->contenttype &&
          !checkprefix("text/", file->contenttype)) {
         /* this is not a text content, mention our binary encoding */
-        size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0);
+        result = AddFormDataf(&form, &size,
+                              "\r\nContent-Transfer-Encoding: binary");
+        if (result)
+          break;
       }
 #endif
 
@@ -1094,22 +1274,27 @@
              */
             size_t nread;
             char buffer[512];
-            while((nread = fread(buffer, 1, sizeof(buffer), fileread))) {
-              result = AddFormData(&form, FORM_DATA, buffer, nread, &size);
+            while ((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) {
+              result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size);
               if (result)
                 break;
             }
           }
 
           if (result) {
-            Curl_formclean(firstform);
+            Curl_formclean(&firstform);
             free(boundary);
             return result;
           }
 
         }
         else {
-          Curl_formclean(firstform);
+#ifdef _FORM_DEBUG
+          fprintf(stderr,
+                  "\n==> Curl_getFormData couldn't open/read \"%s\"\n",
+                  file->contents);
+#endif
+          Curl_formclean(&firstform);
           free(boundary);
           *finalform = NULL;
           return CURLE_READ_ERROR;
@@ -1118,7 +1303,7 @@
       }
       else if (post->flags & HTTPPOST_BUFFER) {
         /* include contents of buffer */
-        result = AddFormData(&form, FORM_DATA, post->buffer,
+        result = AddFormData(&form, FORM_CONTENT, post->buffer,
                              post->bufferlength, &size);
           if (result)
             break;
@@ -1126,14 +1311,14 @@
 
       else {
         /* include the contents we got */
-        result = AddFormData(&form, FORM_DATA, post->contents,
+        result = AddFormData(&form, FORM_CONTENT, post->contents,
                              post->contentslength, &size);
         if (result)
           break;
       }
-    } while((file = file->more)); /* for each specified file for this field */
+    } while ((file = file->more) != NULL); /* for each specified file for this field */
     if (result) {
-      Curl_formclean(firstform);
+      Curl_formclean(&firstform);
       free(boundary);
       return result;
     }
@@ -1149,9 +1334,9 @@
         break;
     }
 
-  } while((post=post->next)); /* for each field */
+  } while ((post = post->next) != NULL); /* for each field */
   if (result) {
-    Curl_formclean(firstform);
+    Curl_formclean(&firstform);
     free(boundary);
     return result;
   }
@@ -1161,7 +1346,7 @@
                        "\r\n--%s--\r\n",
                        boundary);
   if (result) {
-    Curl_formclean(firstform);
+    Curl_formclean(&firstform);
     free(boundary);
     return result;
   }
@@ -1198,12 +1383,12 @@
     /* this file hasn't yet been opened */
     form->fp = fopen(form->data->line, "rb"); /* b is for binary */
     if(!form->fp)
-      return -1; /* failure */
+      return (size_t)-1; /* failure */
   }
   nread = fread(buffer, 1, size, form->fp);
 
   if(nread != size) {
-    /* this is the last chunk form the file, move on */
+    /* this is the last chunk from the file, move on */
     fclose(form->fp);
     form->fp = NULL;
     form->data = form->data->next;
@@ -1232,9 +1417,13 @@
   if(!form->data)
     return 0; /* nothing, error, empty */
 
-  if(form->data->type == FORM_FILE)
-    return readfromfile(form, buffer, wantedsize);
+  if(form->data->type == FORM_FILE) {
+    gotsize = readfromfile(form, buffer, wantedsize);
 
+    if(gotsize)
+      /* If positive or -1, return. If zero, continue! */
+      return gotsize;
+  }
   do {
 
     if( (form->data->length - form->sent ) > wantedsize - gotsize) {
@@ -1256,7 +1445,7 @@
 
     form->data = form->data->next; /* advance */
 
-  } while(form->data && (form->data->type == FORM_DATA));
+  } while(form->data && (form->data->type != FORM_FILE));
   /* If we got an empty line and we have more data, we proceed to the next
      line immediately to avoid returning zero before we've reached the end.
      This is the bug reported November 22 1999 on curl 6.3. (Daniel) */
@@ -1323,7 +1512,7 @@
   char value5[] = "value for PTRCONTENTS + CONTENTSLENGTH";
   char value6[] = "value for PTRCOTNENTS + CONTENTSLENGTH + CONTENTTYPE";
   char value7[] = "inet_ntoa_r.h";
-  char value8[] = "Makefile.b32.resp";
+  char value8[] = "Makefile.b32";
   char type2[] = "image/gif";
   char type6[] = "text/plain";
   char type7[] = "text/html";
@@ -1332,7 +1521,8 @@
   int value5length = strlen(value4);
   int value6length = strlen(value5);
   int errors = 0;
-  int size;
+  CURLcode rc;
+  size_t size;
   size_t nread;
   char buffer[4096];
   struct curl_httppost *httppost=NULL;
@@ -1408,7 +1598,14 @@
                   CURLFORM_END))
     ++errors;
 
-  form=Curl_getFormData(httppost, &size);
+  rc = Curl_getFormData(&form, httppost, NULL, &size);
+  if(rc != CURLE_OK) {
+    if(rc != CURLE_READ_ERROR) {
+      const char *errortext = curl_easy_strerror(rc);
+      fprintf(stdout, "\n==> Curl_getFormData error: %s\n", errortext);
+    }
+    return 0;
+  }
 
   Curl_FormInit(&formread, form);
 
@@ -1416,7 +1613,7 @@
     nread = Curl_FormReader(buffer, 1, sizeof(buffer),
                             (FILE *)&formread);
 
-    if(-1 == nread)
+    if(nread < 1)
       break;
     fwrite(buffer, nread, 1, stdout);
   } while(1);
@@ -1430,7 +1627,7 @@
   return 0;
 }
 
-#endif
+#endif  /* _FORM_DEBUG */
 
 #else  /* CURL_DISABLE_HTTP */
 CURLFORMcode curl_formadd(struct curl_httppost **httppost,
@@ -1442,6 +1639,15 @@
   return CURL_FORMADD_DISABLED;
 }
 
+int curl_formget(struct curl_httppost *form, void *arg,
+                 curl_formget_callback append)
+{
+  (void) form;
+  (void) arg;
+  (void) append;
+  return CURL_FORMADD_DISABLED;
+}
+
 void curl_formfree(struct curl_httppost *form)
 {
   (void)form;
@@ -1450,6 +1656,8 @@
 
 #endif  /* CURL_DISABLE_HTTP */
 
+#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
+
 /*
  * Curl_FormBoundary() creates a suitable boundary string and returns an
  * allocated one. This is also used by SSL-code so it must be present even
@@ -1458,18 +1666,18 @@
 char *Curl_FormBoundary(void)
 {
   char *retstring;
-  static int randomizer=0; /* this is just so that two boundaries within
+  static int randomizer;   /* this is just so that two boundaries within
                               the same form won't be identical */
   size_t i;
 
-  static char table16[]="abcdef0123456789";
+  static const char table16[]="abcdef0123456789";
 
   retstring = (char *)malloc(BOUNDARY_LENGTH+1);
 
   if(!retstring)
     return NULL; /* failed */
 
-  srand((unsigned int)((time(NULL)+randomizer++))); /* seed */
+  srand((unsigned int)time(NULL)+randomizer++); /* seed */
 
   strcpy(retstring, "----------------------------");
 
@@ -1482,3 +1690,5 @@
 
   return retstring;
 }
+
+#endif  /* !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) */

--- NEW FILE: select.h ---
#ifndef __SELECT_H
#define __SELECT_H
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: select.h,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#elif defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
/* for Vista, use WSAPoll(). */
#include <winsock2.h>
#define CURL_HAVE_WSAPOLL
#else

#define POLLIN      0x01
#define POLLPRI     0x02
#define POLLOUT     0x04
#define POLLERR     0x08
#define POLLHUP     0x10
#define POLLNVAL    0x20

struct pollfd
{
    curl_socket_t fd;
    short   events;
    short   revents;
};

#endif

#define CSELECT_IN   0x01
#define CSELECT_OUT  0x02
#define CSELECT_ERR  0x04

int Curl_select(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms);

int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);

#ifdef TPF
int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
                       fd_set* excepts, struct timeval* tv);
#endif

#endif

Index: dict.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/dict.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dict.h	24 Jun 2005 13:00:12 -0000	1.1
+++ dict.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -2,18 +2,18 @@
 #define __DICT_H
 
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -24,7 +24,7 @@
  * $Id$
  ***************************************************************************/
 #ifndef CURL_DISABLE_DICT
-CURLcode Curl_dict(struct connectdata *conn);
+CURLcode Curl_dict(struct connectdata *conn, bool *done);
 CURLcode Curl_dict_done(struct connectdata *conn);
 #endif
 #endif

Index: speedcheck.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/speedcheck.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- speedcheck.c	24 Jun 2005 13:00:13 -0000	1.1
+++ speedcheck.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,16 +1,16 @@
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -29,6 +29,7 @@
 #include <curl/curl.h>
 #include "urldata.h"
 #include "sendf.h"
+#include "multiif.h"
 #include "speedcheck.h"
 
 void Curl_speedinit(struct SessionHandle *data)
@@ -43,13 +44,13 @@
      data->set.low_speed_time &&
      (Curl_tvlong(data->state.keeps_speed) != 0) &&
      (data->progress.current_speed < data->set.low_speed_limit)) {
+    long howlong = Curl_tvdiff(now, data->state.keeps_speed);
 
     /* We are now below the "low speed limit". If we are below it
        for "low speed time" seconds we consider that enough reason
        to abort the download. */
-    
-    if( (Curl_tvdiff(now, data->state.keeps_speed)/1000) >
-        data->set.low_speed_time) {
+
+    if( (howlong/1000) > data->set.low_speed_time) {
       /* we have been this slow for long enough, now die */
       failf(data,
             "Operation too slow. "
@@ -58,10 +59,17 @@
             data->set.low_speed_time);
       return CURLE_OPERATION_TIMEOUTED;
     }
+    Curl_expire(data, howlong);
   }
   else {
     /* we keep up the required speed all right */
     data->state.keeps_speed = now;
+
+    if(data->set.low_speed_limit)
+      /* if there is a low speed limit enabled, we set the expire timer to
+         make this connection's speed get checked again no later than when
+         this time is up */
+      Curl_expire(data, data->set.low_speed_time*1000);
   }
   return CURLE_OK;
 }

Index: inet_pton.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/inet_pton.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- inet_pton.h	24 Jun 2005 13:00:12 -0000	1.1
+++ inet_pton.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,18 +1,18 @@
 #ifndef __INET_PTON_H
 #define __INET_PTON_H
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -25,13 +25,18 @@
 
 #include "setup.h"
 
+int Curl_inet_pton(int, const char *, void *);
+
 #ifdef HAVE_INET_PTON
-#define Curl_inet_pton(x,y,z) inet_pton(x,y,z)
+
+#if defined(HAVE_NO_INET_PTON_PROTO)
+int inet_pton(int af, const char *src, void *dst);
+#endif
+
 #ifdef HAVE_ARPA_INET_H
 #include <arpa/inet.h>
 #endif
-#else
-int Curl_inet_pton(int, const char *, void *);
+#define Curl_inet_pton(x,y,z) inet_pton(x,y,z)
 #endif
 
 #endif /* __INET_PTON_H */

--- NEW FILE: select.c ---
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: select.c,v 1.2 2007/03/15 19:22:13 andy Exp $
 ***************************************************************************/

#include "setup.h"

#include <errno.h>

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif

#ifndef HAVE_SELECT
#error "We can't compile without select() support!"
#endif

#ifdef __BEOS__
/* BeOS has FD_SET defined in socket.h */
#include <socket.h>
#endif

#ifdef __MSDOS__
#include <dos.h>  /* delay() */
#endif

#include <curl/curl.h>

#include "urldata.h"
#include "connect.h"
#include "select.h"

#if defined(USE_WINSOCK) || defined(TPF)
#define VERIFY_SOCK(x)  /* sockets are not in range [0..FD_SETSIZE] */
#else
#define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
#define VERIFY_SOCK(x) do { \
  if(!VALID_SOCK(x)) { \
    errno = EINVAL; \
    return -1; \
  } \
} while(0)
#endif

/*
 * This is an internal function used for waiting for read or write
 * events on single file descriptors.  It attempts to replace select()
 * in order to avoid limits with FD_SETSIZE.
 *
 * Return values:
 *   -1 = system call error
 *    0 = timeout
 *    CSELECT_IN | CSELECT_OUT | CSELECT_ERR
 */
int Curl_select(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms)
{
#if defined(HAVE_POLL_FINE) || defined(CURL_HAVE_WSAPOLL)
  struct pollfd pfd[2];
  int num;
  int r;
  int ret;

  num = 0;
  if (readfd != CURL_SOCKET_BAD) {
    pfd[num].fd = readfd;
    pfd[num].events = POLLIN;
    num++;
  }
  if (writefd != CURL_SOCKET_BAD) {
    pfd[num].fd = writefd;
    pfd[num].events = POLLOUT;
    num++;
  }

#ifdef HAVE_POLL_FINE
  do {
    r = poll(pfd, num, timeout_ms);
  } while((r == -1) && (errno == EINTR));
#else
  r = WSAPoll(pfd, num, timeout_ms);
#endif

  if (r < 0)
    return -1;
  if (r == 0)
    return 0;

  ret = 0;
  num = 0;
  if (readfd != CURL_SOCKET_BAD) {
    if (pfd[num].revents & (POLLIN|POLLHUP))
      ret |= CSELECT_IN;
    if (pfd[num].revents & POLLERR) {
#ifdef __CYGWIN__
      /* Cygwin 1.5.21 needs this hack to pass test 160 */
      if (errno == EINPROGRESS)
        ret |= CSELECT_IN;
      else
#endif
        ret |= CSELECT_ERR;
    }
    num++;
  }
  if (writefd != CURL_SOCKET_BAD) {
    if (pfd[num].revents & POLLOUT)
      ret |= CSELECT_OUT;
    if (pfd[num].revents & (POLLERR|POLLHUP))
      ret |= CSELECT_ERR;
  }

  return ret;
#else
  struct timeval timeout;
  fd_set fds_read;
  fd_set fds_write;
  fd_set fds_err;
  curl_socket_t maxfd;
  int r;
  int ret;

  timeout.tv_sec = timeout_ms / 1000;
  timeout.tv_usec = (timeout_ms % 1000) * 1000;

  if((readfd == CURL_SOCKET_BAD) && (writefd == CURL_SOCKET_BAD)) {
    /* According to POSIX we should pass in NULL pointers if we don't want to
       wait for anything in particular but just use the timeout function.
       Windows however returns immediately if done so. I copied the MSDOS
       delay() use from src/main.c that already had this work-around. */
#ifdef WIN32
    Sleep(timeout_ms);
#elif defined(__MSDOS__)
    delay(timeout_ms);
#else
    select(0, NULL, NULL, NULL, &timeout);
#endif
    return 0;
  }

  FD_ZERO(&fds_err);
  maxfd = (curl_socket_t)-1;

  FD_ZERO(&fds_read);
  if (readfd != CURL_SOCKET_BAD) {
    VERIFY_SOCK(readfd);
    FD_SET(readfd, &fds_read);
    FD_SET(readfd, &fds_err);
    maxfd = readfd;
  }

  FD_ZERO(&fds_write);
  if (writefd != CURL_SOCKET_BAD) {
    VERIFY_SOCK(writefd);
    FD_SET(writefd, &fds_write);
    FD_SET(writefd, &fds_err);
    if (writefd > maxfd)
      maxfd = writefd;
  }

  do {
    r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, &timeout);
  } while((r == -1) && (Curl_sockerrno() == EINTR));

  if (r < 0)
    return -1;
  if (r == 0)
    return 0;

  ret = 0;
  if (readfd != CURL_SOCKET_BAD) {
    if (FD_ISSET(readfd, &fds_read))
      ret |= CSELECT_IN;
    if (FD_ISSET(readfd, &fds_err))
      ret |= CSELECT_ERR;
  }
  if (writefd != CURL_SOCKET_BAD) {
    if (FD_ISSET(writefd, &fds_write))
      ret |= CSELECT_OUT;
    if (FD_ISSET(writefd, &fds_err))
      ret |= CSELECT_ERR;
  }

  return ret;
#endif
}

/*
 * This is a wrapper around poll().  If poll() does not exist, then
 * select() is used instead.  An error is returned if select() is
 * being used and a file descriptor too large for FD_SETSIZE.
 *
 * Return values:
 *   -1 = system call error or fd >= FD_SETSIZE
 *    0 = timeout
 *    1 = number of structures with non zero revent fields
 */
int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
{
  int r;
#ifdef HAVE_POLL_FINE
  do {
    r = poll(ufds, nfds, timeout_ms);
  } while((r == -1) && (errno == EINTR));
#elif defined(CURL_HAVE_WSAPOLL)
  r = WSAPoll(ufds, nfds, timeout_ms);
#else
  struct timeval timeout;
  struct timeval *ptimeout;
  fd_set fds_read;
  fd_set fds_write;
  fd_set fds_err;
  curl_socket_t maxfd;
  unsigned int i;

  FD_ZERO(&fds_read);
  FD_ZERO(&fds_write);
  FD_ZERO(&fds_err);
  maxfd = (curl_socket_t)-1;

  for (i = 0; i < nfds; i++) {
    if (ufds[i].fd == CURL_SOCKET_BAD)
      continue;
#ifndef USE_WINSOCK  /* winsock sockets are not in range [0..FD_SETSIZE] */
    if (ufds[i].fd >= FD_SETSIZE) {
      errno = EINVAL;
      return -1;
    }
#endif
    if (ufds[i].fd > maxfd)
      maxfd = ufds[i].fd;
    if (ufds[i].events & POLLIN)
      FD_SET(ufds[i].fd, &fds_read);
    if (ufds[i].events & POLLOUT)
      FD_SET(ufds[i].fd, &fds_write);
    if (ufds[i].events & POLLERR)
      FD_SET(ufds[i].fd, &fds_err);
  }

  if (timeout_ms < 0) {
    ptimeout = NULL;      /* wait forever */
  } else {
    timeout.tv_sec = timeout_ms / 1000;
    timeout.tv_usec = (timeout_ms % 1000) * 1000;
    ptimeout = &timeout;
  }

  do {
    r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
  } while((r == -1) && (Curl_sockerrno() == EINTR));

  if (r < 0)
    return -1;
  if (r == 0)
    return 0;

  r = 0;
  for (i = 0; i < nfds; i++) {
    ufds[i].revents = 0;
    if (ufds[i].fd == CURL_SOCKET_BAD)
      continue;
    if (FD_ISSET(ufds[i].fd, &fds_read))
      ufds[i].revents |= POLLIN;
    if (FD_ISSET(ufds[i].fd, &fds_write))
      ufds[i].revents |= POLLOUT;
    if (FD_ISSET(ufds[i].fd, &fds_err))
      ufds[i].revents |= POLLERR;
    if (ufds[i].revents != 0)
      r++;
  }
#endif
  return r;
}

#ifdef TPF
/*
 * This is a replacement for select() on the TPF platform.
 * It is used whenever libcurl calls select().
 * The call below to tpf_process_signals() is required because
 * TPF's select calls are not signal interruptible.
 *
 * Return values are the same as select's.
 */
int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
                       fd_set* excepts, struct timeval* tv)
{
   int rc;

   rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
   tpf_process_signals();
   return(rc);
}
#endif /* TPF */

Index: formdata.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/formdata.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- formdata.h	24 Jun 2005 13:00:12 -0000	1.1
+++ formdata.h	15 Mar 2007 19:22:13 -0000	1.2
@@ -8,7 +8,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -25,8 +25,10 @@
  ***************************************************************************/
 
 enum formtype {
-  FORM_DATA, /* regular data */
-  FORM_FILE  /* 'line' points to a file name we should read from */
+  FORM_DATA,    /* form metadata (convert to network encoding if necessary) */
+  FORM_CONTENT, /* form content  (never convert) */
+  FORM_FILE     /* 'line' points to a file name we should read from 
+                    to create the form data (never convert) */
 };
 
 /* plain and simple linked list with lines to send */
@@ -69,6 +71,7 @@
 CURLcode
 Curl_getFormData(struct FormData **,
                  struct curl_httppost *post,
+                 const char *custom_contenttype,
                  curl_off_t *size);
 
 /* fread() emulation */
@@ -86,7 +89,9 @@
 
 char *Curl_FormBoundary(void);
 
-void Curl_formclean(struct FormData *);
+void Curl_formclean(struct FormData **);
+
+CURLcode Curl_formconvert(struct SessionHandle *, struct FormData *);
 
 #endif
 

Index: inet_pton.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/inet_pton.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- inet_pton.c	30 Mar 2006 18:49:56 -0000	1.2
+++ inet_pton.c	15 Mar 2007 19:22:13 -0000	1.3
@@ -44,7 +44,7 @@
 #define INADDRSZ         4
 #define INT16SZ          2
 
-#ifdef WIN32
+#ifdef USE_WINSOCK
 #define EAFNOSUPPORT    WSAEAFNOSUPPORT
 #endif
 
@@ -72,21 +72,21 @@
 int
 Curl_inet_pton(int af, const char *src, void *dst)
 {
-        switch (af) {
-        case AF_INET:
-                return (inet_pton4(src, dst));
+  switch (af) {
+  case AF_INET:
+    return (inet_pton4(src, (unsigned char *)dst));
 #ifdef ENABLE_IPV6
 #ifndef AF_INET6
-#define AF_INET6        AF_MAX+1        /* just to let this compile */
+#define AF_INET6        (AF_MAX+1)        /* just to let this compile */
 #endif
-        case AF_INET6:
-                return (inet_pton6(src, dst));
+  case AF_INET6:
+    return (inet_pton6(src, (unsigned char *)dst));
 #endif
-        default:
-                errno = EAFNOSUPPORT;
-                return (-1);
-        }
-        /* NOTREACHED */
+  default:
+    errno = EAFNOSUPPORT;
+    return (-1);
+  }
+  /* NOTREACHED */
 }
 
 /* int
@@ -102,40 +102,41 @@
 static int
 inet_pton4(const char *src, unsigned char *dst)
 {
-        static const char digits[] = "0123456789";
-        int saw_digit, octets, ch;
-        unsigned char tmp[INADDRSZ], *tp;
+  static const char digits[] = "0123456789";
+  int saw_digit, octets, ch;
+  unsigned char tmp[INADDRSZ], *tp;
 
-        saw_digit = 0;
-        octets = 0;
-        *(tp = tmp) = 0;
-        while ((ch = *src++) != '\0') {
-                const char *pch;
+  saw_digit = 0;
+  octets = 0;
+  tp = tmp;
+  *tp = 0;
+  while ((ch = *src++) != '\0') {
+    const char *pch;
 
-                if ((pch = strchr(digits, ch)) != NULL) {
-                        size_t new = *tp * 10 + (pch - digits);
+    if ((pch = strchr(digits, ch)) != NULL) {
+      unsigned int val = *tp * 10 + (unsigned int)(pch - digits);
 
-                        if (new > 255)
-                                return (0);
-                        *tp = (unsigned char)new;
-                        if (! saw_digit) {
-                                if (++octets > 4)
-                                        return (0);
-                                saw_digit = 1;
-                        }
-                } else if (ch == '.' && saw_digit) {
-                        if (octets == 4)
-                                return (0);
-                        *++tp = 0;
-                        saw_digit = 0;
-                } else
-                        return (0);
-        }
-        if (octets < 4)
-                return (0);
-        /* bcopy(tmp, dst, INADDRSZ); */
-        memcpy(dst, tmp, INADDRSZ);
-        return (1);
+      if (val > 255)
+        return (0);
+      *tp = val;
+      if (! saw_digit) {
+        if (++octets > 4)
+          return (0);
+        saw_digit = 1;
+      }
+    } else if (ch == '.' && saw_digit) {
+      if (octets == 4)
+        return (0);
+      *++tp = 0;
+      saw_digit = 0;
+    } else
+      return (0);
+  }
+  if (octets < 4)
+    return (0);
+  /* bcopy(tmp, dst, INADDRSZ); */
+  memcpy(dst, tmp, INADDRSZ);
+  return (1);
 }
 
 #ifdef ENABLE_IPV6
@@ -155,85 +156,85 @@
 static int
 inet_pton6(const char *src, unsigned char *dst)
 {
-        static const char xdigits_l[] = "0123456789abcdef",
-                          xdigits_u[] = "0123456789ABCDEF";
-        unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
-        const char *xdigits, *curtok;
-        int ch, saw_xdigit;
-        u_int val;
+  static const char xdigits_l[] = "0123456789abcdef",
+    xdigits_u[] = "0123456789ABCDEF";
+  unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+  const char *xdigits, *curtok;
+  int ch, saw_xdigit;
+  unsigned int val;
 
-        memset((tp = tmp), 0, IN6ADDRSZ);
-        endp = tp + IN6ADDRSZ;
-        colonp = NULL;
-        /* Leading :: requires some special handling. */
-        if (*src == ':')
-                if (*++src != ':')
-                        return (0);
-        curtok = src;
-        saw_xdigit = 0;
-        val = 0;
-        while ((ch = *src++) != '\0') {
-                const char *pch;
+  memset((tp = tmp), 0, IN6ADDRSZ);
+  endp = tp + IN6ADDRSZ;
+  colonp = NULL;
+  /* Leading :: requires some special handling. */
+  if (*src == ':')
+    if (*++src != ':')
+      return (0);
+  curtok = src;
+  saw_xdigit = 0;
+  val = 0;
+  while ((ch = *src++) != '\0') {
+    const char *pch;
 
-                if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
-                        pch = strchr((xdigits = xdigits_u), ch);
-                if (pch != NULL) {
-                        val <<= 4;
-                        val |= (pch - xdigits);
-                        if (val > 0xffff)
-                                return (0);
-                        saw_xdigit = 1;
-                        continue;
-                }
-                if (ch == ':') {
-                        curtok = src;
-                        if (!saw_xdigit) {
-                                if (colonp)
-                                        return (0);
-                                colonp = tp;
-                                continue;
-                        }
-                        if (tp + INT16SZ > endp)
-                                return (0);
-                        *tp++ = (unsigned char) (val >> 8) & 0xff;
-                        *tp++ = (unsigned char) val & 0xff;
-                        saw_xdigit = 0;
-                        val = 0;
-                        continue;
-                }
-                if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
-                    inet_pton4(curtok, tp) > 0) {
-                        tp += INADDRSZ;
-                        saw_xdigit = 0;
-                        break;  /* '\0' was seen by inet_pton4(). */
-                }
-                return (0);
-        }
-        if (saw_xdigit) {
-                if (tp + INT16SZ > endp)
-                        return (0);
-                *tp++ = (unsigned char) (val >> 8) & 0xff;
-                *tp++ = (unsigned char) val & 0xff;
-        }
-        if (colonp != NULL) {
-                /*
-                 * Since some memmove()'s erroneously fail to handle
-                 * overlapping regions, we'll do the shift by hand.
-                 */
-                const int n = tp - colonp;
-                int i;
+    if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+      pch = strchr((xdigits = xdigits_u), ch);
+    if (pch != NULL) {
+      val <<= 4;
+      val |= (pch - xdigits);
+      if (val > 0xffff)
+        return (0);
+      saw_xdigit = 1;
+      continue;
+    }
+    if (ch == ':') {
+      curtok = src;
+      if (!saw_xdigit) {
+        if (colonp)
+          return (0);
+        colonp = tp;
+        continue;
+      }
+      if (tp + INT16SZ > endp)
+        return (0);
+      *tp++ = (unsigned char) (val >> 8) & 0xff;
+      *tp++ = (unsigned char) val & 0xff;
+      saw_xdigit = 0;
+      val = 0;
+      continue;
+    }
+    if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
+        inet_pton4(curtok, tp) > 0) {
+      tp += INADDRSZ;
+      saw_xdigit = 0;
+      break;    /* '\0' was seen by inet_pton4(). */
+    }
+    return (0);
+  }
+  if (saw_xdigit) {
+    if (tp + INT16SZ > endp)
+      return (0);
+    *tp++ = (unsigned char) (val >> 8) & 0xff;
+    *tp++ = (unsigned char) val & 0xff;
+  }
+  if (colonp != NULL) {
+    /*
+     * Since some memmove()'s erroneously fail to handle
+     * overlapping regions, we'll do the shift by hand.
+     */
+    const int n = tp - colonp;
+    int i;
 
-                for (i = 1; i <= n; i++) {
-                        endp[- i] = colonp[n - i];
-                        colonp[n - i] = 0;
-                }
-                tp = endp;
-        }
-        if (tp != endp)
-                return (0);
-        /* bcopy(tmp, dst, IN6ADDRSZ); */
-        memcpy(dst, tmp, IN6ADDRSZ);
-        return (1);
+    for (i = 1; i <= n; i++) {
+      endp[- i] = colonp[n - i];
+      colonp[n - i] = 0;
+    }
+    tp = endp;
+  }
+  if (tp != endp)
+    return (0);
+  /* bcopy(tmp, dst, IN6ADDRSZ); */
+  memcpy(dst, tmp, IN6ADDRSZ);
+  return (1);
 }
 #endif /* ENABLE_IPV6 */
 


Index: dict.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/dict.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dict.c	24 Jun 2005 13:00:12 -0000	1.1
+++ dict.c	15 Mar 2007 19:22:13 -0000	1.2
@@ -1,16 +1,16 @@
 /***************************************************************************
- *                                  _   _ ____  _     
- *  Project                     ___| | | |  _ \| |    
- *                             / __| | | | |_) | |    
- *                            | (__| |_| |  _ <| |___ 
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel at haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel at haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  * are also available at http://curl.haxx.se/docs/copyright.html.
- * 
+ *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
  * furnished to do so, under the terms of the COPYING file.
@@ -23,18 +23,22 @@
 
 #include "setup.h"
 
+#ifndef CURL_DISABLE_DICT
+
 /* -- WIN32 approved -- */
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <ctype.h>
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
+#endif
 
-#include <errno.h>
-
-#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
+#ifdef WIN32
 #include <time.h>
 #include <io.h>
 #else
@@ -42,7 +46,9 @@
 #include <sys/socket.h>
 #endif
 #include <netinet/in.h>
+#ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
+#endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -79,20 +85,59 @@
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
 
-CURLcode Curl_dict(struct connectdata *conn)
+/* The last #include file should be: */
+#include "memdebug.h"
+
+static char *unescape_word(struct SessionHandle *data, char *inp)
+{
+  char *newp;
+  char *dictp;
+  char *ptr;
+  int len;
+  unsigned char byte;
+  int olen=0;
+
+  newp = curl_easy_unescape(data, inp, 0, &len);
+  if(!newp)
+    return NULL;
+
+  dictp = malloc(len*2 + 1); /* add one for terminating zero */
+  if(dictp) {
+    /* According to RFC2229 section 2.2, these letters need to be escaped with
+       \[letter] */
+    for(ptr = newp;
+        (byte = (unsigned char)*ptr) != 0;
+        ptr++) {
+      if ((byte <= 32) || (byte == 127) ||
+          (byte == '\'') || (byte == '\"') || (byte == '\\')) {
+        dictp[olen++] = '\\';
+      }
+      dictp[olen++] = byte;
+    }
+    dictp[olen]=0;
+
+    free(newp);
+  }
+  return dictp;
+}
+
+CURLcode Curl_dict(struct connectdata *conn, bool *done)
 {
   char *word;
+  char *eword;
   char *ppath;
   char *database = NULL;
   char *strategy = NULL;
   char *nthdef = NULL; /* This is not part of the protocol, but required
                           by RFC 2229 */
-  CURLcode result;
+  CURLcode result=CURLE_OK;
   struct SessionHandle *data=conn->data;
   curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
 
-  char *path = conn->path;
-  curl_off_t *bytecount = &conn->bytecount;
+  char *path = data->reqdata.path;
+  curl_off_t *bytecount = &data->reqdata.keep.bytecount;
+
+  *done = TRUE; /* unconditionally */
 
   if(conn->bits.user_passwd) {
     /* AUTH is missing */
@@ -101,7 +146,7 @@
   if (strnequal(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
       strnequal(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
       strnequal(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
-      
+
     word = strchr(path, ':');
     if (word) {
       word++;
@@ -118,7 +163,7 @@
         }
       }
     }
-      
+
     if ((word == NULL) || (*word == (char)0)) {
       failf(data, "lookup word is missing");
     }
@@ -128,31 +173,38 @@
     if ((strategy == NULL) || (*strategy == (char)0)) {
       strategy = (char *)".";
     }
-      
+
+    eword = unescape_word(data, word);
+    if(!eword)
+      return CURLE_OUT_OF_MEMORY;
+
     result = Curl_sendf(sockfd, conn,
-                        "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
+                        "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
                         "MATCH "
                         "%s "    /* database */
                         "%s "    /* strategy */
-                        "%s\n"   /* word */
-                        "QUIT\n",
-                        
+                        "%s\r\n" /* word */
+                        "QUIT\r\n",
+
                         database,
                         strategy,
-                        word
+                        eword
                         );
+
+    free(eword);
+
     if(result)
       failf(data, "Failed sending DICT request");
     else
-      result = Curl_Transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
-                             -1, NULL); /* no upload */      
+      result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
+                                   -1, NULL); /* no upload */
     if(result)
       return result;
   }
   else if (strnequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
            strnequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
            strnequal(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) {
-    
+
     word = strchr(path, ':');
     if (word) {
       word++;
@@ -165,57 +217,64 @@
         }
       }
     }
-      
+
     if ((word == NULL) || (*word == (char)0)) {
       failf(data, "lookup word is missing");
     }
     if ((database == NULL) || (*database == (char)0)) {
       database = (char *)"!";
     }
-      
+
+    eword = unescape_word(data, word);
+    if(!eword)
+      return CURLE_OUT_OF_MEMORY;
+
     result = Curl_sendf(sockfd, conn,
-                        "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
+                        "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
                         "DEFINE "
                         "%s "     /* database */
-                        "%s\n"    /* word */
-                        "QUIT\n",
+                        "%s\r\n"  /* word */
+                        "QUIT\r\n",
                         database,
-                        word);
+                        eword);
+
+    free(eword);
+
     if(result)
       failf(data, "Failed sending DICT request");
     else
-      result = Curl_Transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
-                             -1, NULL); /* no upload */
-    
+      result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
+                                   -1, NULL); /* no upload */
+
     if(result)
       return result;
-      
+
   }
   else {
-      
+
     ppath = strchr(path, '/');
     if (ppath) {
       int i;
-        
+
       ppath++;
       for (i = 0; ppath[i]; i++) {
         if (ppath[i] == ':')
           ppath[i] = ' ';
       }
       result = Curl_sendf(sockfd, conn,
-                          "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\n"
-                          "%s\n"
-                          "QUIT\n", ppath);
+                          "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+                          "%s\r\n"
+                          "QUIT\r\n", ppath);
       if(result)
         failf(data, "Failed sending DICT request");
       else
-        result = Curl_Transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
-                               -1, NULL);
+        result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
+                                     -1, NULL);
       if(result)
         return result;
     }
   }
-  (void)nthdef;
 
   return CURLE_OK;
 }
+#endif /*CURL_DISABLE_DICT*/

Index: mprintf.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Utilities/cmcurl/mprintf.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- mprintf.c	19 May 2006 19:51:05 -0000	1.4
+++ mprintf.c	15 Mar 2007 19:22:13 -0000	1.5
@@ -38,6 +38,10 @@
 #include <ctype.h>
 #include <string.h>
 
+#if defined(DJGPP) && (DJGPP_MINOR < 4)
+#undef _MPRINTF_REPLACE /* don't use x_was_used() here */
+#endif
+
 #include <curl/mprintf.h>
 
 #ifndef SIZEOF_LONG_DOUBLE
@@ -55,7 +59,7 @@
 #define ENABLE_64BIT
 #endif
 
-#include "curl_memory.h"
+#include "memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
 
@@ -75,6 +79,9 @@
 # define BOOL char
 #endif
 
+#ifdef _AMIGASF
+# undef FORMAT_INT
+#endif
 
 /* Lower-case digits.  */
 static const char lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
@@ -164,7 +171,7 @@
 static long dprintf_DollarString(char *input, char **end)
 {
   int number=0;
-  while(isdigit((int)*input)) {
+  while(ISDIGIT(*input)) {
     number *= 10;
     number += *input-'0';
     input++;
@@ -619,10 +626,10 @@
     char alt;
 
     /* Width of a field.  */
-    ssize_t width;
+    long width;
 
     /* Precision of a field.  */
-    ssize_t prec;
+    long prec;
 
     /* Decimal integer is negative.  */
     char is_neg;
@@ -759,8 +766,8 @@
           *w-- = digits[num % base];
           num /= base;
         }
-        width -= workend - w;
-        prec -= workend - w;
+        width -= (long)(workend - w);
+        prec -= (long)(workend - w);
 
         if (alt && base == 8 && prec <= 0) {
           *w-- = '0';
@@ -816,8 +823,8 @@
     case FORMAT_STRING:
             /* String.  */
       {
-        static char null[] = "(nil)";
-        char *str;
+        static const char null[] = "(nil)";
+        const char *str;
         size_t len;
 
         str = (char *) p->data.str;
@@ -830,7 +837,7 @@
             p->flags &= (~FLAGS_ALT);
           }
           else {
-            str = (char *)"";
+            str = "";
             len = 0;
           }
         }
@@ -839,7 +846,7 @@
 
         if (prec != -1 && (size_t) prec < len)
           len = prec;
-        width -= len;
+        width -= (long)len;
 
         if (p->flags & FLAGS_ALT)
           OUTCHAR('"');
@@ -869,14 +876,14 @@
           base = 16;
           digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
           alt = 1;
-          num = (unsigned long) ptr;
+          num = (size_t) ptr;
           is_neg = 0;
           goto number;
         }
         else {
           /* Write "(nil)" for a nil pointer.  */
-          static char strnil[] = "(nil)";
-          char *point;
+          static const char strnil[] = "(nil)";
+          const char *point;
 
           width -= sizeof(strnil) - 1;
           if (p->flags & FLAGS_LEFT)
@@ -933,7 +940,6 @@
           fptr += len;
           left -= len;
         }
-        (void)left;
         if (p->flags & FLAGS_LONG)
           *fptr++ = 'l';
 
@@ -1134,15 +1140,12 @@
   return retcode;
 }
 
-#if !(defined( WIN32) || defined(__UCLIBC__)) /* not needed on win32 */
-extern int fputc(int, FILE *);
-#endif
-
 int curl_mprintf(const char *format, ...)
 {
   int retcode;
   va_list ap_save; /* argument pointer */
   va_start(ap_save, format);
+
   retcode = dprintf_formatf(stdout, fputc, format, ap_save);
   va_end(ap_save);
   return retcode;



More information about the Cmake-commits mailing list