[sword-svn] r400 - trunk/apps/InstallMgr/curl/lib

scribe at crosswire.org scribe at crosswire.org
Fri Dec 31 10:19:47 MST 2004


Author: scribe
Date: 2004-12-31 10:19:47 -0700 (Fri, 31 Dec 2004)
New Revision: 400

Added:
   trunk/apps/InstallMgr/curl/lib/hostasyn.c
   trunk/apps/InstallMgr/curl/lib/hostip4.c
   trunk/apps/InstallMgr/curl/lib/hostthre.c
   trunk/apps/InstallMgr/curl/lib/http_digest.c
   trunk/apps/InstallMgr/curl/lib/inet_ntop.c
   trunk/apps/InstallMgr/curl/lib/md5.c
   trunk/apps/InstallMgr/curl/lib/select.c
   trunk/apps/InstallMgr/curl/lib/select.h
   trunk/apps/InstallMgr/curl/lib/share.c
   trunk/apps/InstallMgr/curl/lib/strerror.c
   trunk/apps/InstallMgr/curl/lib/strerror.h
Log:


Added: trunk/apps/InstallMgr/curl/lib/hostasyn.c
===================================================================
--- trunk/apps/InstallMgr/curl/lib/hostasyn.c	2004-12-31 17:10:43 UTC (rev 399)
+++ trunk/apps/InstallMgr/curl/lib/hostasyn.c	2004-12-31 17:19:47 UTC (rev 400)
@@ -0,0 +1,174 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  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: hostasyn.c,v 1.7 2004/10/06 07:50:18 bagder Exp $
+ ***************************************************************************/
+
+#include "setup.h"
+
+#include <string.h>
+#include <errno.h>
+
+#define _REENTRANT
+
+#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
+#include <malloc.h>
+#else
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>     /* required for free() prototypes */
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>     /* for the close() proto */
+#endif
+#ifdef  VMS
+#include <in.h>
+#include <inet.h>
+#include <stdlib.h>
+#endif
+#endif
+
+#ifdef HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
+
+#ifdef WIN32
+#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"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+
+#define _MPRINTF_REPLACE /* use our functions only */
+#include <curl/mprintf.h>
+
+#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
+#include "inet_ntoa_r.h"
+#endif
+
+#include "memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/***********************************************************************
+ * Only for builds using asynchronous name resolves
+ **********************************************************************/
+#ifdef CURLRES_ASYNCH
+/*
+ * addrinfo_callback() gets called by ares, gethostbyname_thread() or
+ * getaddrinfo_thread() when we got the name resolved (or not!).
+ *
+ * If the status argument is CURL_ASYNC_SUCCESS, we might need to copy the
+ * address field since it might be freed when this function returns. This
+ * operation stores the resolved data in the DNS cache.
+ *
+ * NOTE: for IPv6 operations, Curl_addrinfo_copy() returns the same
+ * pointer it is given as argument!
+ *
+ * The storage operation locks and unlocks the DNS cache.
+ */
+static void addrinfo_callback(void *arg, /* "struct connectdata *" */
+                              int status,
+                              void *addr)
+{
+  struct connectdata *conn = (struct connectdata *)arg;
+  struct Curl_dns_entry *dns = NULL;
+
+  conn->async.status = status;
+
+  if(CURL_ASYNC_SUCCESS == status) {
+
+    /*
+     * IPv4: Curl_addrinfo_copy() copies the address and returns an allocated
+     * version.
+     *
+     * IPv6: Curl_addrinfo_copy() returns the input pointer!
+     */
+    Curl_addrinfo *ai = Curl_addrinfo_copy(addr, conn->async.port);
+    if(ai) {
+      struct SessionHandle *data = conn->data;
+
+      if(data->share)
+        Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+      dns = Curl_cache_addr(data, ai,
+                            conn->async.hostname,
+                            conn->async.port);
+      if(!dns)
+        /* failed to store, cleanup and return error */
+        Curl_freeaddrinfo(ai);
+
+      if(data->share)
+        Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+    }
+  }
+
+  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 */
+}
+
+void Curl_addrinfo4_callback(void *arg, /* "struct connectdata *" */
+                             int status,
+                             struct hostent *hostent)
+{
+  addrinfo_callback(arg, status, hostent);
+}
+
+#ifdef CURLRES_IPV6
+void Curl_addrinfo6_callback(void *arg, /* "struct connectdata *" */
+                             int status,
+                             struct addrinfo *ai)
+{
+  addrinfo_callback(arg, status, ai);
+}
+#endif
+
+#endif /* CURLRES_ASYNC */

Added: trunk/apps/InstallMgr/curl/lib/hostip4.c
===================================================================
--- trunk/apps/InstallMgr/curl/lib/hostip4.c	2004-12-31 17:10:43 UTC (rev 399)
+++ trunk/apps/InstallMgr/curl/lib/hostip4.c	2004-12-31 17:19:47 UTC (rev 400)
@@ -0,0 +1,449 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  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: hostip4.c,v 1.12 2004/10/06 07:52:20 bagder Exp $
+ ***************************************************************************/
+
+#include "setup.h"
+
+#include <string.h>
+#include <errno.h>
+
+#define _REENTRANT
+
+#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
+#include <malloc.h>
+#else
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>     /* required for free() prototypes */
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>     /* for the close() proto */
+#endif
+#ifdef  VMS
+#include <in.h>
+#include <inet.h>
+#include <stdlib.h>
+#endif
+#endif
+
+#ifdef HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
+
+#ifdef WIN32
+#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"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+
+#define _MPRINTF_REPLACE /* use our functions only */
+#include <curl/mprintf.h>
+
+#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
+#include "inet_ntoa_r.h"
+#endif
+
+#include "memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/***********************************************************************
+ * 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.
+ */
+bool Curl_ipvalid(struct SessionHandle *data)
+{
+  if(data->set.ip_version == CURL_IPRESOLVE_V6)
+    /* an ipv6 address was requested and we can't get/use one */
+    return FALSE;
+
+  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.
+ *
+ * gethostbyname_r() is the thread-safe version of the gethostbyname()
+ * function. When we build for plain IPv4, we attempt to use this
+ * function. There are _three_ different gethostbyname_r() versions, and we
+ * detect which one this platform supports in the configure script and set up
+ * the HAVE_GETHOSTBYNAME_R_3, HAVE_GETHOSTBYNAME_R_5 or
+ * HAVE_GETHOSTBYNAME_R_6 defines accordingly. Note that HAVE_GETADDRBYNAME
+ * has the corresponding rules. This is primarily on *nix. Note that some unix
+ * flavours have thread-safe versions of the plain gethostbyname() etc.
+ *
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+                                char *hostname,
+                                int port,
+                                int *waitp)
+{
+  Curl_addrinfo *ai = NULL;
+  struct hostent *h = NULL;
+  in_addr_t in;
+  struct SessionHandle *data = conn->data;
+  struct hostent *buf = NULL;
+
+  (void)port; /* unused in IPv4 code */
+
+  *waitp = 0; /* don't wait, we act synchronously */
+
+  in=inet_addr(hostname);
+  if (in != CURL_INADDR_NONE) {
+    /* This is a dotted IP address 123.123.123.123-style */
+    return Curl_ip2addr(in, hostname, port);
+  }
+
+#if defined(HAVE_GETHOSTBYNAME_R)
+  /*
+   * gethostbyname_r() is the preferred resolve function for many platforms.
+   * Since there are three different versions of it, the following code is
+   * somewhat #ifdef-ridden.
+   */
+  else {
+    int h_errnop;
+    int res=ERANGE;
+
+    buf = (struct hostent *)calloc(CURL_HOSTENT_SIZE, 1);
+    if(!buf)
+      return NULL; /* major failure */
+    /*
+     * The clearing of the buffer is a workaround for a gethostbyname_r bug in
+     * qnx nto and it is also _required_ for some of these functions on some
+     * platforms.
+     */
+
+#ifdef HAVE_GETHOSTBYNAME_R_5
+    /* Solaris, IRIX and more */
+    (void)res; /* prevent compiler warning */
+    h = gethostbyname_r(hostname,
+                        (struct hostent *)buf,
+                        (char *)buf + sizeof(struct hostent),
+                        CURL_HOSTENT_SIZE - sizeof(struct hostent),
+                        &h_errnop);
+
+    /* If the buffer is too small, it returns NULL and sets errno to
+     * ERANGE. The errno is thread safe if this is compiled with
+     * -D_REENTRANT as then the 'errno' variable is a macro defined to get
+     * used properly for threads.
+     */
+
+    if(h) {
+      ;
+    }
+    else
+#endif /* HAVE_GETHOSTBYNAME_R_5 */
+#ifdef HAVE_GETHOSTBYNAME_R_6
+    /* Linux */
+
+    res=gethostbyname_r(hostname,
+                        (struct hostent *)buf,
+                        (char *)buf + sizeof(struct hostent),
+                        CURL_HOSTENT_SIZE - sizeof(struct hostent),
+                        &h, /* DIFFERENCE */
+                        &h_errnop);
+    /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
+     * sudden this function returns EAGAIN if the given buffer size is too
+     * small. Previous versions are known to return ERANGE for the same
+     * problem.
+     *
+     * This wouldn't be such a big problem if older versions wouldn't
+     * sometimes return EAGAIN on a common failure case. Alas, we can't
+     * assume that EAGAIN *or* ERANGE means ERANGE for any given version of
+     * glibc.
+     *
+     * For now, we do that and thus we may call the function repeatedly and
+     * fail for older glibc versions that return EAGAIN, until we run out of
+     * buffer size (step_size grows beyond CURL_HOSTENT_SIZE).
+     *
+     * If anyone has a better fix, please tell us!
+     *
+     * -------------------------------------------------------------------
+     *
+     * On October 23rd 2003, Dan C dug up more details on the mysteries of
+     * gethostbyname_r() in glibc:
+     *
+     * In glibc 2.2.5 the interface is different (this has also been
+     * discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't
+     * explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32
+     * (shipped/upgraded by Redhat 7.2) don't show this behavior!
+     *
+     * In this "buggy" version, the return code is -1 on error and 'errno'
+     * is set to the ERANGE or EAGAIN code. Note that 'errno' is not a
+     * thread-safe variable.
+     */
+
+    if(!h) /* failure */
+#endif/* HAVE_GETHOSTBYNAME_R_6 */
+#ifdef HAVE_GETHOSTBYNAME_R_3
+    /* AIX, Digital Unix/Tru64, HPUX 10, more? */
+
+    /* For AIX 4.3 or later, we don't use gethostbyname_r() at all, because of
+     * the plain fact that it does not return unique full buffers on each
+     * call, but instead several of the pointers in the hostent structs will
+     * point to the same actual data! This have the unfortunate down-side that
+     * our caching system breaks down horribly. Luckily for us though, AIX 4.3
+     * and more recent versions have a "completely thread-safe"[*] libc where
+     * all the data is stored in thread-specific memory areas making calls to
+     * the plain old gethostbyname() work fine even for multi-threaded
+     * programs.
+     *
+     * This AIX 4.3 or later detection is all made in the configure script.
+     *
+     * Troels Walsted Hansen helped us work this out on March 3rd, 2003.
+     *
+     * [*] = much later we've found out that it isn't at all "completely
+     * thread-safe", but at least the gethostbyname() function is.
+     */
+
+    if(CURL_HOSTENT_SIZE >=
+       (sizeof(struct hostent)+sizeof(struct hostent_data))) {
+
+      /* August 22nd, 2000: Albert Chin-A-Young brought an updated version
+       * that should work! September 20: Richard Prescott worked on the buffer
+       * size dilemma.
+       */
+
+      res = gethostbyname_r(hostname,
+                            (struct hostent *)buf,
+                            (struct hostent_data *)((char *)buf +
+                                                    sizeof(struct hostent)));
+      h_errnop= errno; /* we don't deal with this, but set it anyway */
+    }
+    else
+      res = -1; /* failure, too smallish buffer size */
+
+    if(!res) { /* success */
+
+      h = buf; /* result expected in h */
+
+      /* This is the worst kind of the different gethostbyname_r() interfaces.
+       * Since we don't know how big buffer this particular lookup required,
+       * we can't realloc down the huge alloc without doing closer analysis of
+       * the returned data. Thus, we always use CURL_HOSTENT_SIZE for every
+       * name lookup. Fixing this would require an extra malloc() and then
+       * calling Curl_addrinfo_copy() that subsequent realloc()s down the new
+       * memory area to the actually used amount.
+       */
+    }
+    else
+#endif /* HAVE_GETHOSTBYNAME_R_3 */
+      {
+      infof(data, "gethostbyname_r(2) failed for %s\n", hostname);
+      h = NULL; /* set return code to NULL */
+      free(buf);
+    }
+#else /* HAVE_GETHOSTBYNAME_R */
+    /*
+     * Here is code for platforms that don't have gethostbyname_r() or for
+     * which the gethostbyname() is the preferred() function.
+     */
+  else {
+    h = gethostbyname(hostname);
+    if (!h)
+      infof(data, "gethostbyname(2) failed for %s\n", hostname);
+#endif /*HAVE_GETHOSTBYNAME_R */
+  }
+
+  if(h) {
+    ai = Curl_he2ai(h, port);
+
+    if (buf) /* used a *_r() function */
+      free(buf);
+  }
+
+  return ai;
+}
+
+#endif /* CURLRES_SYNCH */
+
+/*
+ * 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.
+
+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 *ai;
+  Curl_addrinfo *prevai = NULL;
+  Curl_addrinfo *firstai = NULL;
+  struct sockaddr_in *addr;
+  int i;
+  struct in_addr *curr;
+
+  if(!he)
+    /* no input == no output! */
+    return NULL;
+
+  for(i=0; (curr = (struct in_addr *)he->h_addr_list[i]); i++) {
+
+    ai = calloc(1, sizeof(Curl_addrinfo) + sizeof(struct sockaddr_in));
+
+    if(!ai)
+      break;
+
+    if(!firstai)
+      /* store the pointer we want to return from this function */
+      firstai = ai;
+
+    if(prevai)
+      /* make the previous entry point to this */
+      prevai->ai_next = ai;
+
+    ai->ai_family = AF_INET;              /* we only support this */
+    ai->ai_socktype = SOCK_STREAM;        /* we only support this */
+    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 *) ((char*)ai + sizeof(Curl_addrinfo));
+
+    /* leave the rest of the struct filled with zero */
+
+    addr = (struct sockaddr_in *)ai->ai_addr; /* storage area for this info */
+
+    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 */

Added: trunk/apps/InstallMgr/curl/lib/hostthre.c
===================================================================
--- trunk/apps/InstallMgr/curl/lib/hostthre.c	2004-12-31 17:10:43 UTC (rev 399)
+++ trunk/apps/InstallMgr/curl/lib/hostthre.c	2004-12-31 17:19:47 UTC (rev 400)
@@ -0,0 +1,669 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  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: hostthre.c,v 1.16 2004/11/25 16:49:14 bagder Exp $
+ ***************************************************************************/
+
+#include "setup.h"
+
+#include <string.h>
+#include <errno.h>
+
+#define _REENTRANT
+
+#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
+#include <malloc.h>
+#else
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>     /* required for free() prototypes */
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>     /* for the close() proto */
+#endif
+#ifdef  VMS
+#include <in.h>
+#include <inet.h>
+#include <stdlib.h>
+#endif
+#endif
+
+#ifdef HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
+
+#ifdef WIN32
+#include <stdlib.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"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+
+#define _MPRINTF_REPLACE /* use our functions only */
+#include <curl/mprintf.h>
+
+#include "inet_ntop.h"
+
+#include "memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/***********************************************************************
+ * Only for Windows threaded name resolves builds
+ **********************************************************************/
+#ifdef CURLRES_THREADED
+
+/* This function is used to init a threaded resolve */
+static bool init_resolve_thread(struct connectdata *conn,
+                                const char *hostname, int port,
+                                const Curl_addrinfo *hints);
+
+#ifdef CURLRES_IPV4
+  #define THREAD_FUNC  gethostbyname_thread
+  #define THREAD_NAME "gethostbyname_thread"
+#else
+  #define THREAD_FUNC  getaddrinfo_thread
+  #define THREAD_NAME "getaddrinfo_thread"
+#endif
+
+#if defined(DEBUG_THREADING_GETHOSTBYNAME) || \
+    defined(DEBUG_THREADING_GETADDRINFO)
+/* If this is defined, provide tracing */
+#define TRACE(args)  \
+ do { trace_it("%u: ", __LINE__); trace_it args; } while (0)
+
+static void trace_it (const char *fmt, ...)
+{
+  static int do_trace = -1;
+  va_list args;
+
+  if (do_trace == -1) {
+    const char *env = getenv("CURL_TRACE");
+    do_trace = (env && atoi(env) > 0);
+  }
+  if (!do_trace)
+    return;
+  va_start (args, fmt);
+  vfprintf (stderr, fmt, args);
+  fflush (stderr);
+  va_end (args);
+}
+#else
+#define TRACE(x)
+#endif
+
+#ifdef DEBUG_THREADING_GETADDRINFO
+static void dump_addrinfo (struct connectdata *conn, const struct addrinfo *ai)
+{
+  TRACE(("dump_addrinfo:\n"));
+  for ( ; ai; ai = ai->ai_next) {
+    char  buf [INET6_ADDRSTRLEN];
+
+    trace_it("    fam %2d, CNAME %s, ",
+             ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
+    if (Curl_printable_address(ai, buf, sizeof(buf)))
+      trace_it("%s\n", buf);
+    else
+      trace_it("failed; %s\n", Curl_strerror(conn,WSAGetLastError()));
+  }
+}
+#endif
+
+struct thread_data {
+  HANDLE thread_hnd;
+  unsigned thread_id;
+  DWORD  thread_status;
+  curl_socket_t dummy_sock;   /* dummy for Curl_fdset() */
+  FILE *stderr_file;
+  HANDLE mutex_waiting;  /* marks that we are still waiting for a resolve */
+  HANDLE event_resolved; /* marks that the thread obtained the information */
+#ifdef CURLRES_IPV6
+  struct addrinfo hints;
+#endif
+};
+
+#if defined(CURLRES_IPV4)
+/*
+ * gethostbyname_thread() resolves a name, calls the Curl_addrinfo4_callback
+ * and then exits.
+ *
+ * For builds without ARES/ENABLE_IPV6, create a resolver thread and wait on
+ * it.
+ */
+static unsigned __stdcall gethostbyname_thread (void *arg)
+{
+  struct connectdata *conn = (struct connectdata*) arg;
+  struct thread_data *td = (struct thread_data*) conn->async.os_specific;
+  struct hostent *he;
+  int    rc = 0;
+
+  /* Duplicate the passed mutex handle.
+   * This allows us to use it even after the container gets destroyed
+   * due to a resolver timeout.
+   */
+  HANDLE mutex_waiting = NULL;
+  if (!DuplicateHandle(GetCurrentProcess(), td->mutex_waiting,
+                       GetCurrentProcess(), &mutex_waiting, 0, FALSE,
+                       DUPLICATE_SAME_ACCESS)) {
+    /* failed to duplicate the mutex, no point in continuing */
+    return 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).
+   */
+#ifndef _WIN32_WCE
+  *stderr = *td->stderr_file;
+#endif
+
+  WSASetLastError (conn->async.status = NO_DATA); /* pending status */
+  he = gethostbyname (conn->async.hostname);
+
+  /* is the thread initiator still waiting for us ? */
+  if (WaitForSingleObject(mutex_waiting, 0) == WAIT_TIMEOUT) {
+    /* yes, it is */
+
+    /* Mark that we have obtained the information, and that we are
+     * calling back with it.
+     */
+    SetEvent(td->event_resolved);
+
+    if (he) {
+      Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he);
+      rc = 1;
+    }
+    else {
+      Curl_addrinfo4_callback(conn, (int)WSAGetLastError(), NULL);
+      rc = 0;
+    }
+    TRACE(("Winsock-error %d, addr %s\n", conn->async.status,
+           he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown"));
+  }
+
+  /* clean up */
+  CloseHandle(mutex_waiting);
+
+  return (rc);
+  /* An implicit _endthreadex() here */
+}
+
+#elif defined(CURLRES_IPV6)
+
+/*
+ * getaddrinfo_thread() resolves a name, calls Curl_addrinfo6_callback and then
+ * exits.
+ *
+ * For builds without ARES, but with ENABLE_IPV6, create a resolver thread
+ * and wait on it.
+ */
+static unsigned __stdcall getaddrinfo_thread (void *arg)
+{
+  struct connectdata *conn = (struct connectdata*) arg;
+  struct thread_data *td   = (struct thread_data*) conn->async.os_specific;
+  struct addrinfo    *res;
+  char   service [NI_MAXSERV];
+  int    rc;
+
+  /* Duplicate the passed mutex handle.
+   * This allows us to use it even after the container gets destroyed
+   * due to a resolver timeout.
+   */
+  HANDLE mutex_waiting = NULL;
+  if (!DuplicateHandle(GetCurrentProcess(), td->mutex_waiting,
+                       GetCurrentProcess(), &mutex_waiting, 0, FALSE,
+                       DUPLICATE_SAME_ACCESS)) {
+    /* failed to duplicate the mutex, no point in continuing */
+    return 0;
+  }
+
+  *stderr = *td->stderr_file;
+
+  itoa(conn->async.port, service, 10);
+
+  WSASetLastError(conn->async.status = NO_DATA); /* pending status */
+
+  rc = getaddrinfo(conn->async.hostname, service, &td->hints, &res);
+
+  /* is the thread initiator still waiting for us ? */
+  if (WaitForSingleObject(mutex_waiting, 0) == WAIT_TIMEOUT) {
+    /* yes, it is */
+
+    /* 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);
+#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));
+    }
+  }
+
+  /* clean up */
+  CloseHandle(mutex_waiting);
+
+  return (rc);
+  /* An implicit _endthreadex() here */
+}
+#endif
+
+/*
+ * destroy_thread_data() cleans up async resolver data.
+ * Complementary of ares_destroy.
+ */
+static void destroy_thread_data (struct Curl_async *async)
+{
+  if (async->hostname)
+    free(async->hostname);
+
+  if (async->os_specific) {
+    struct thread_data *td = (struct thread_data*) async->os_specific;
+    curl_socket_t sock = td->dummy_sock;
+
+    if (sock != CURL_SOCKET_BAD)
+      sclose(sock);
+
+    /* destroy the synchronization objects */
+    if (td->mutex_waiting)
+      CloseHandle(td->mutex_waiting);
+    if (td->event_resolved)
+      CloseHandle(td->event_resolved);
+
+    free(async->os_specific);
+  }
+  async->hostname = NULL;
+  async->os_specific = NULL;
+}
+
+/*
+ * init_resolve_thread() starts a new thread that performs the actual
+ * resolve. This function returns before the resolve is done.
+ *
+ * Returns FALSE in case of failure, otherwise TRUE.
+ */
+static bool init_resolve_thread (struct connectdata *conn,
+                                 const char *hostname, int port,
+                                 const Curl_addrinfo *hints)
+{
+  struct thread_data *td = calloc(sizeof(*td), 1);
+
+  if (!td) {
+    SetLastError(ENOMEM);
+    return FALSE;
+  }
+
+  Curl_safefree(conn->async.hostname);
+  conn->async.hostname = strdup(hostname);
+  if (!conn->async.hostname) {
+    free(td);
+    SetLastError(ENOMEM);
+    return FALSE;
+  }
+
+  conn->async.port = port;
+  conn->async.done = FALSE;
+  conn->async.status = 0;
+  conn->async.dns = NULL;
+  conn->async.os_specific = (void*) td;
+  td->dummy_sock = CURL_SOCKET_BAD;
+
+  /* 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) {
+    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) {
+    destroy_thread_data(&conn->async);
+    SetLastError(EAGAIN);
+    return FALSE;
+  }
+
+  td->stderr_file = stderr;
+
+#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;
+#else
+  (void) hints;
+#endif
+
+  if (!td->thread_hnd) {
+     SetLastError(errno);
+     TRACE(("_beginthreadex() failed; %s\n", Curl_strerror(conn,errno)));
+     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().
+   */
+  td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0);
+  return TRUE;
+}
+
+
+/*
+ * Curl_wait_for_resolv() waits for a resolve to finish. This function should
+ * be avoided since using this risk getting the multi interface to "hang".
+ *
+ * If 'entry' is non-NULL, make it point to the resolved dns entry
+ *
+ * This is the version for resolves-in-a-thread.
+ */
+CURLcode Curl_wait_for_resolv(struct connectdata *conn,
+                              struct Curl_dns_entry **entry)
+{
+  struct thread_data   *td = (struct thread_data*) conn->async.os_specific;
+  struct SessionHandle *data = conn->data;
+  long   timeout;
+  DWORD  status, ticks;
+  CURLcode rc;
+
+  curlassert (conn && td);
+
+  /* now, see if there's a connect timeout or a regular timeout to
+     use instead of the default one */
+  timeout =
+    conn->data->set.connecttimeout ? conn->data->set.connecttimeout :
+    conn->data->set.timeout ? conn->data->set.timeout :
+    CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
+  ticks = GetTickCount();
+
+  /* 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));
+  }
+
+  TRACE(("elapsed %lu ms\n", GetTickCount()-ticks));
+
+  CloseHandle(td->thread_hnd);
+
+  if(entry)
+    *entry = conn->async.dns;
+
+  rc = CURLE_OK;
+
+  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;
+    }
+    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;
+    }
+    else
+      rc = CURLE_OPERATION_TIMEDOUT;
+  }
+
+  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);
+
+  return (rc);
+}
+
+/*
+ * Curl_is_resolved() is called repeatedly to check if a previous name resolve
+ * request has completed. It should also make sure to time-out if the
+ * operation seems to take too long.
+ */
+CURLcode Curl_is_resolved(struct connectdata *conn,
+                          struct Curl_dns_entry **entry)
+{
+  *entry = NULL;
+
+  if (conn->async.done) {
+    /* we're done */
+    destroy_thread_data(&conn->async);
+    if (!conn->async.dns) {
+      TRACE(("Curl_is_resolved(): CURLE_COULDNT_RESOLVE_HOST\n"));
+      return CURLE_COULDNT_RESOLVE_HOST;
+    }
+    *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)
+{
+  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;
+  }
+  (void) read_fd_set;
+  return CURLE_OK;
+}
+
+#ifdef CURLRES_IPV4
+/*
+ * Curl_getaddrinfo() - for Windows threading without ENABLE_IPV6.
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+                                char *hostname,
+                                int port,
+                                int *waitp)
+{
+  struct hostent *h = NULL;
+  struct SessionHandle *data = conn->data;
+  in_addr_t in;
+
+  *waitp = 0; /* don't wait, we act synchronously */
+
+  in = inet_addr(hostname);
+  if (in != CURL_INADDR_NONE)
+    /* This is a dotted IP address 123.123.123.123-style */
+    return Curl_ip2addr(in, hostname, port);
+
+  /* fire up a new resolver thread! */
+  if (init_resolve_thread(conn, hostname, port, NULL)) {
+    *waitp = TRUE;  /* please wait for the response */
+    return NULL;
+  }
+
+  /* fall-back to blocking version */
+  infof(data, "init_resolve_thread() failed for %s; %s\n",
+        hostname, Curl_strerror(conn,GetLastError()));
+
+  h = gethostbyname(hostname);
+  if (!h) {
+    infof(data, "gethostbyname(2) failed for %s:%d; %s\n",
+          hostname, port, Curl_strerror(conn,WSAGetLastError()));
+    return NULL;
+  }
+  return Curl_he2ai(h, port);
+}
+#endif /* CURLRES_IPV4 */
+
+#ifdef CURLRES_IPV6
+/*
+ * Curl_getaddrinfo() - for Windows threading IPv6 enabled
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+                                char *hostname,
+                                int port,
+                                int *waitp)
+{
+  struct addrinfo hints, *res;
+  int error;
+  char sbuf[NI_MAXSERV];
+  curl_socket_t s;
+  int pf;
+  struct SessionHandle *data = conn->data;
+
+  *waitp = FALSE; /* default to synch response */
+
+  /* see if we have an IPv6 stack */
+  s = socket(PF_INET6, SOCK_DGRAM, 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. */
+
+    pf = PF_INET;
+  }
+  else {
+    /* This seems to be an IPv6-capable stack, use PF_UNSPEC for the widest
+     * possible checks. And close the socket again.
+     */
+    sclose(s);
+
+    /*
+     * Check if a more limited name resolve has been requested.
+     */
+    switch(data->set.ip_version) {
+    case CURL_IPRESOLVE_V4:
+      pf = PF_INET;
+      break;
+    case CURL_IPRESOLVE_V6:
+      pf = PF_INET6;
+      break;
+    default:
+      pf = PF_UNSPEC;
+      break;
+    }
+  }
+
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = pf;
+  hints.ai_socktype = SOCK_STREAM;
+  hints.ai_flags = AI_CANONNAME;
+  itoa(port, sbuf, 10);
+
+  /* fire up a new resolver thread! */
+  if (init_resolve_thread(conn, hostname, port, &hints)) {
+    *waitp = TRUE;  /* please wait for the response */
+    return NULL;
+  }
+
+  /* fall-back to blocking version */
+  infof(data, "init_resolve_thread() failed for %s; %s\n",
+        hostname, Curl_strerror(conn,GetLastError()));
+
+  error = getaddrinfo(hostname, sbuf, &hints, &res);
+  if (error) {
+    infof(data, "getaddrinfo() failed for %s:%d; %s\n",
+          hostname, port, Curl_strerror(conn,WSAGetLastError()));
+    return NULL;
+  }
+  return res;
+}
+#endif /* CURLRES_IPV6 */
+#endif /* CURLRES_THREADED */

Added: trunk/apps/InstallMgr/curl/lib/http_digest.c
===================================================================
--- trunk/apps/InstallMgr/curl/lib/http_digest.c	2004-12-31 17:10:43 UTC (rev 399)
+++ trunk/apps/InstallMgr/curl/lib/http_digest.c	2004-12-31 17:19:47 UTC (rev 400)
@@ -0,0 +1,482 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  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: http_digest.c,v 1.24 2004/11/12 09:18:14 bagder Exp $
+ ***************************************************************************/
+#include "setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+/* -- WIN32 approved -- */
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "urldata.h"
+#include "sendf.h"
+#include "strequal.h"
+#include "base64.h"
+#include "md5.h"
+#include "http_digest.h"
+#include "strtok.h"
+#include "url.h" /* for Curl_safefree() */
+#include "memory.h"
+
+#define _MPRINTF_REPLACE /* use our functions only */
+#include <curl/mprintf.h>
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* Test example headers:
+
+WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
+Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598"
+
+*/
+
+CURLdigest Curl_input_digest(struct connectdata *conn,
+                             bool proxy,
+                             char *header) /* rest of the *-authenticate:
+                                              header */
+{
+  bool more = TRUE;
+  char *token = NULL;
+  char *tmp = NULL;
+  bool foundAuth = FALSE;
+  bool foundAuthInt = FALSE;
+  struct SessionHandle *data=conn->data;
+  bool before = FALSE; /* got a nonce before */
+  struct digestdata *d;
+
+  if(proxy) {
+    d = &data->state.proxydigest;
+  }
+  else {
+    d = &data->state.digest;
+  }
+
+  /* skip initial whitespaces */
+  while(*header && isspace((int)*header))
+    header++;
+
+  if(checkprefix("Digest", header)) {
+    header += strlen("Digest");
+
+    /* If we already have received a nonce, keep that in mind */
+    if(d->nonce)
+      before = TRUE;
+
+    /* clear off any former leftovers and init to defaults */
+    Curl_digest_cleanup_one(d);
+
+    while(more) {
+      char value[32];
+      char content[128];
+      size_t totlen=0;
+
+      while(*header && isspace((int)*header))
+        header++;
+
+      /* how big can these strings be? */
+      if((2 == sscanf(header, "%31[^=]=\"%127[^\"]\"",
+                      value, content)) ||
+         /* try the same scan but without quotes around the content but don't
+            include the possibly trailing comma */
+         (2 ==  sscanf(header, "%31[^=]=%127[^,]",
+                       value, content)) ) {
+        if(strequal(value, "nonce")) {
+          d->nonce = strdup(content);
+          if(!d->nonce)
+            return CURLDIGEST_NOMEM;
+        }
+        else if(strequal(value, "stale")) {
+          if(strequal(content, "true")) {
+            d->stale = TRUE;
+            d->nc = 1; /* we make a new nonce now */
+          }
+        }
+        else if(strequal(value, "realm")) {
+          d->realm = strdup(content);
+          if(!d->realm)
+            return CURLDIGEST_NOMEM;
+        }
+        else if(strequal(value, "opaque")) {
+          d->opaque = strdup(content);
+          if(!d->opaque)
+            return CURLDIGEST_NOMEM;
+        }
+        else if(strequal(value, "qop")) {
+          char *tok_buf;
+          /* tokenize the list and choose auth if possible, use a temporary
+             clone of the buffer since strtok_r() ruins it */
+          tmp = strdup(content);
+          if(!tmp)
+            return CURLDIGEST_NOMEM;
+          token = strtok_r(tmp, ",", &tok_buf);
+          while (token != NULL) {
+            if (strequal(token, "auth")) {
+              foundAuth = TRUE;
+            }
+            else if (strequal(token, "auth-int")) {
+              foundAuthInt = TRUE;
+            }
+            token = strtok_r(NULL, ",", &tok_buf);
+          }
+          free(tmp);
+          /*select only auth o auth-int. Otherwise, ignore*/
+          if (foundAuth) {
+            d->qop = strdup("auth");
+            if(!d->qop)
+              return CURLDIGEST_NOMEM;
+          }
+          else if (foundAuthInt) {
+            d->qop = strdup("auth-int");
+            if(!d->qop)
+              return CURLDIGEST_NOMEM;
+          }
+        }
+        else if(strequal(value, "algorithm")) {
+          d->algorithm = strdup(content);
+          if(!d->algorithm)
+            return CURLDIGEST_NOMEM;
+          if(strequal(content, "MD5-sess"))
+            d->algo = CURLDIGESTALGO_MD5SESS;
+          else if(strequal(content, "MD5"))
+            d->algo = CURLDIGESTALGO_MD5;
+          else
+            return CURLDIGEST_BADALGO;
+        }
+        else {
+          /* unknown specifier, ignore it! */
+        }
+        totlen = strlen(value)+strlen(content)+1;
+
+        if(header[strlen(value)+1] == '\"')
+          /* the contents were within quotes, then add 2 for them to the
+             length */
+          totlen += 2;
+      }
+      else
+        break; /* we're done here */
+
+      header += totlen;
+      if(',' == *header)
+        /* allow the list to be comma-separated */
+        header++;
+    }
+    /* We had a nonce since before, and we got another one now without
+       'stale=true'. This means we provided bad credentials in the previous
+       request */
+    if(before && !d->stale)
+      return CURLDIGEST_BAD;
+
+    /* We got this header without a nonce, that's a bad Digest line! */
+    if(!d->nonce)
+      return CURLDIGEST_BAD;
+  }
+  else
+    /* else not a digest, get out */
+    return CURLDIGEST_NONE;
+
+  return CURLDIGEST_FINE;
+}
+
+/* convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/
+static void md5_to_ascii(unsigned char *source, /* 16 bytes */
+                         unsigned char *dest) /* 33 bytes */
+{
+  int i;
+  for(i=0; i<16; i++)
+    snprintf((char *)&dest[i*2], 3, "%02x", source[i]);
+}
+
+CURLcode Curl_output_digest(struct connectdata *conn,
+                            bool proxy,
+                            unsigned char *request,
+                            unsigned char *uripath)
+{
+  /* We have a Digest setup for this, use it!  Now, to get all the details for
+     this sorted out, I must urge you dear friend to read up on the RFC2617
+     section 3.2.2, */
+  unsigned char md5buf[16]; /* 16 bytes/128 bits */
+  unsigned char request_digest[33];
+  unsigned char *md5this;
+  unsigned char *ha1;
+  unsigned char ha2[33];/* 32 digits and 1 zero byte */
+  char cnoncebuf[7];
+  char *cnonce;
+  char *tmp = NULL;
+  struct timeval now;
+
+  char **allocuserpwd;
+  char *userp;
+  char *passwdp;
+  struct auth *authp;
+
+  struct SessionHandle *data = conn->data;
+  struct digestdata *d;
+
+  if(proxy) {
+    d = &data->state.proxydigest;
+    allocuserpwd = &conn->allocptr.proxyuserpwd;
+    userp = conn->proxyuser;
+    passwdp = conn->proxypasswd;
+    authp = &data->state.authproxy;
+  }
+  else {
+    d = &data->state.digest;
+    allocuserpwd = &conn->allocptr.userpwd;
+    userp = conn->user;
+    passwdp = conn->passwd;
+    authp = &data->state.authhost;
+  }
+
+  /* not set means empty */
+  if(!userp)
+    userp=(char *)"";
+
+  if(!passwdp)
+    passwdp=(char *)"";
+
+  if(!d->nonce) {
+    authp->done = FALSE;
+    return CURLE_OK;
+  }
+  authp->done = TRUE;
+
+  if(!d->nc)
+    d->nc = 1;
+
+  if(!d->cnonce) {
+    /* Generate a cnonce */
+    now = Curl_tvnow();
+    snprintf(cnoncebuf, sizeof(cnoncebuf), "%06ld", now.tv_sec);
+    if(Curl_base64_encode(cnoncebuf, strlen(cnoncebuf), &cnonce))
+      d->cnonce = cnonce;
+    else
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  /*
+    if the algorithm is "MD5" or unspecified (which then defaults to MD5):
+
+    A1 = unq(username-value) ":" unq(realm-value) ":" passwd
+
+    if the algorithm is "MD5-sess" then:
+
+    A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd )
+         ":" unq(nonce-value) ":" unq(cnonce-value)
+  */
+
+  md5this = (unsigned char *)
+    aprintf("%s:%s:%s", userp, d->realm, passwdp);
+  if(!md5this)
+    return CURLE_OUT_OF_MEMORY;
+  Curl_md5it(md5buf, md5this);
+  free(md5this); /* free this again */
+
+  ha1 = (unsigned char *)malloc(33); /* 32 digits and 1 zero byte */
+  if(!ha1)
+    return CURLE_OUT_OF_MEMORY;
+
+  md5_to_ascii(md5buf, ha1);
+
+  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;
+  }
+
+  /*
+    If the "qop" directive's value is "auth" or is unspecified, then A2 is:
+
+      A2       = Method ":" digest-uri-value
+
+          If the "qop" value is "auth-int", then A2 is:
+
+      A2       = Method ":" digest-uri-value ":" H(entity-body)
+
+    (The "Method" value is the HTTP request method as specified in section
+    5.1.1 of RFC 2616)
+  */
+
+  md5this = (unsigned char *)aprintf("%s:%s", request, uripath);
+  if(!md5this) {
+    free(ha1);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  if (d->qop && strequal(d->qop, "auth-int")) {
+    /* We don't support auth-int at the moment. I can't see a easy way to get
+       entity-body here */
+    /* TODO: Append H(entity-body)*/
+  }
+  Curl_md5it(md5buf, md5this);
+  free(md5this); /* free this again */
+  md5_to_ascii(md5buf, ha2);
+
+  if (d->qop) {
+    md5this = (unsigned char *)aprintf("%s:%s:%08x:%s:%s:%s",
+                                       ha1,
+                                       d->nonce,
+                                       d->nc,
+                                       d->cnonce,
+                                       d->qop,
+                                       ha2);
+  }
+  else {
+    md5this = (unsigned char *)aprintf("%s:%s:%s",
+                                       ha1,
+                                       d->nonce,
+                                       ha2);
+  }
+  free(ha1);
+  if(!md5this)
+    return CURLE_OUT_OF_MEMORY;
+
+  Curl_md5it(md5buf, md5this);
+  free(md5this); /* free this again */
+  md5_to_ascii(md5buf, request_digest);
+
+  /* for test case 64 (snooped from a Mozilla 1.3a request)
+
+    Authorization: Digest username="testuser", realm="testrealm", \
+    nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
+  */
+
+  Curl_safefree(*allocuserpwd);
+
+  if (d->qop) {
+    *allocuserpwd =
+      aprintf( "%sAuthorization: Digest "
+               "username=\"%s\", "
+               "realm=\"%s\", "
+               "nonce=\"%s\", "
+               "uri=\"%s\", "
+               "cnonce=\"%s\", "
+               "nc=%08x, "
+               "qop=\"%s\", "
+               "response=\"%s\"",
+               proxy?"Proxy-":"",
+               userp,
+               d->realm,
+               d->nonce,
+               uripath, /* this is the PATH part of the URL */
+               d->cnonce,
+               d->nc,
+               d->qop,
+               request_digest);
+
+    if(strequal(d->qop, "auth"))
+      d->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0 padded
+                  which tells to the server how many times you are using the
+                  same nonce in the qop=auth mode. */
+  }
+  else {
+    *allocuserpwd =
+      aprintf( "%sAuthorization: Digest "
+               "username=\"%s\", "
+               "realm=\"%s\", "
+               "nonce=\"%s\", "
+               "uri=\"%s\", "
+               "response=\"%s\"",
+               proxy?"Proxy-":"",
+               userp,
+               d->realm,
+               d->nonce,
+               uripath, /* this is the PATH part of the URL */
+               request_digest);
+  }
+  if(!*allocuserpwd)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Add optional fields */
+  if(d->opaque) {
+    /* append opaque */
+    tmp = aprintf("%s, opaque=\"%s\"", *allocuserpwd, d->opaque);
+    if(!tmp)
+      return CURLE_OUT_OF_MEMORY;
+    free(*allocuserpwd);
+    *allocuserpwd = tmp;
+  }
+
+  if(d->algorithm) {
+    /* append algorithm */
+    tmp = aprintf("%s, algorithm=\"%s\"", *allocuserpwd, d->algorithm);
+    if(!tmp)
+      return CURLE_OUT_OF_MEMORY;
+    free(*allocuserpwd);
+    *allocuserpwd = tmp;
+  }
+
+  /* append CRLF to the userpwd header */
+  tmp = (char*) realloc(*allocuserpwd, strlen(*allocuserpwd) + 3 + 1);
+  if(!tmp)
+    return CURLE_OUT_OF_MEMORY;
+  strcat(tmp, "\r\n");
+  *allocuserpwd = tmp;
+
+  return CURLE_OK;
+}
+
+void Curl_digest_cleanup_one(struct digestdata *d)
+{
+  if(d->nonce)
+    free(d->nonce);
+  d->nonce = NULL;
+
+  if(d->cnonce)
+    free(d->cnonce);
+  d->cnonce = NULL;
+
+  if(d->realm)
+    free(d->realm);
+  d->realm = NULL;
+
+  if(d->opaque)
+    free(d->opaque);
+  d->opaque = NULL;
+
+  if(d->qop)
+    free(d->qop);
+  d->qop = NULL;
+
+  if(d->algorithm)
+    free(d->algorithm);
+  d->algorithm = NULL;
+
+  d->nc = 0;
+  d->algo = CURLDIGESTALGO_MD5; /* default algorithm */
+  d->stale = FALSE; /* default means normal, not stale */
+}
+
+
+void Curl_digest_cleanup(struct SessionHandle *data)
+{
+  Curl_digest_cleanup_one(&data->state.digest);
+  Curl_digest_cleanup_one(&data->state.proxydigest);
+}
+
+#endif

Added: trunk/apps/InstallMgr/curl/lib/inet_ntop.c
===================================================================
--- trunk/apps/InstallMgr/curl/lib/inet_ntop.c	2004-12-31 17:10:43 UTC (rev 399)
+++ trunk/apps/InstallMgr/curl/lib/inet_ntop.c	2004-12-31 17:19:47 UTC (rev 400)
@@ -0,0 +1,198 @@
+/*
+ * Original code by Paul Vixie. "curlified" by Gisle Vanem.
+ */
+
+#include "setup.h"
+
+#ifndef HAVE_INET_NTOP
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+#define _MPRINTF_REPLACE /* use our functions only */
+#include <curl/mprintf.h>
+
+#include "inet_ntop.h"
+
+#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
+/* this platform has a inet_ntoa_r() function, but no proto declared anywhere
+   so we include our own proto to make compilers happy */
+#include "inet_ntoa_r.h"
+#endif
+
+#define IN6ADDRSZ       16
+#define INADDRSZ         4
+#define INT16SZ          2
+
+#ifdef WIN32
+#define EAFNOSUPPORT    WSAEAFNOSUPPORT
+#define SET_ERRNO(e)    WSASetLastError(errno = (e))
+#else
+#define SET_ERRNO(e)    errno = e
+#endif
+
+/*
+ * Format an IPv4 address, more or less like inet_ntoa().
+ *
+ * Returns `dst' (as a const)
+ * Note:
+ *  - uses no statics
+ *  - takes a u_char* not an in_addr as input
+ */
+static const char *inet_ntop4 (const u_char *src, char *dst, size_t size)
+{
+#ifdef HAVE_INET_NTOA_R
+  return inet_ntoa_r(*(struct in_addr*)src, dst, size);
+#else
+  const char *addr = inet_ntoa(*(struct in_addr*)src);
+
+  if (strlen(addr) >= size)
+  {
+    SET_ERRNO(ENOSPC);
+    return (NULL);
+  }
+  return strcpy(dst, addr);
+#endif
+}
+
+#ifdef ENABLE_IPV6
+/*
+ * Convert IPv6 binary address into presentation (printable) format.
+ */
+static const char *inet_ntop6 (const u_char *src, char *dst, size_t size)
+{
+  /*
+   * Note that int32_t and int16_t need only be "at least" large enough
+   * to contain a value of the specified size.  On some systems, like
+   * Crays, there is no such thing as an integer variable with 16 bits.
+   * 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 *tp;
+  struct {
+    long base;
+    long len;
+  } best, cur;
+  u_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));
+  for (i = 0; i < IN6ADDRSZ; i++)
+      words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
+
+  best.base = -1;
+  cur.base  = -1;
+  for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
+  {
+    if (words[i] == 0)
+    {
+      if (cur.base == -1)
+        cur.base = i, cur.len = 1;
+      else
+        cur.len++;
+    }
+    else if (cur.base != -1)
+    {
+      if (best.base == -1 || cur.len > best.len)
+         best = cur;
+      cur.base = -1;
+    }
+  }
+  if ((cur.base != -1) && (best.base == -1 || cur.len > best.len))
+     best = cur;
+  if (best.base != -1 && best.len < 2)
+     best.base = -1;
+
+  /* Format the result.
+   */
+  tp = tmp;
+  for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
+  {
+    /* Are we inside the best run of 0x00's?
+     */
+    if (best.base != -1 && i >= best.base && i < (best.base + best.len))
+    {
+      if (i == best.base)
+         *tp++ = ':';
+      continue;
+    }
+
+    /* Are we following an initial run of 0x00s or any real hex?
+     */
+    if (i != 0)
+       *tp++ = ':';
+
+    /* Is this address an encapsulated IPv4?
+     */
+    if (i == 6 && best.base == 0 &&
+        (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
+    {
+      if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp)))
+      {
+        SET_ERRNO(ENOSPC);
+        return (NULL);
+      }
+      tp += strlen(tp);
+      break;
+    }
+    tp += snprintf(tp, 5, "%lx", words[i]);
+  }
+
+  /* Was it a trailing run of 0x00's?
+   */
+  if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
+     *tp++ = ':';
+  *tp++ = '\0';
+
+  /* Check for overflow, copy, and we're done.
+   */
+  if ((size_t)(tp - tmp) > size)
+  {
+    SET_ERRNO(ENOSPC);
+    return (NULL);
+  }
+  return strcpy (dst, tmp);
+}
+#endif  /* ENABLE_IPV6 */
+
+/*
+ * Convert a network format address to presentation format.
+ *
+ * Returns pointer to presentation format address (`dst'),
+ * Returns NULL on error (see errno).
+ */
+const 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);
+#ifdef ENABLE_IPV6
+  case AF_INET6:
+    return inet_ntop6((const u_char*)src, buf, size);
+#endif
+  default:
+    SET_ERRNO(EAFNOSUPPORT);
+    return NULL;
+  }
+}
+#endif  /* HAVE_INET_NTOP */

Added: trunk/apps/InstallMgr/curl/lib/md5.c
===================================================================
--- trunk/apps/InstallMgr/curl/lib/md5.c	2004-12-31 17:10:43 UTC (rev 399)
+++ trunk/apps/InstallMgr/curl/lib/md5.c	2004-12-31 17:19:47 UTC (rev 400)
@@ -0,0 +1,352 @@
+/***************************************************************************
+ *                                  _   _ ____  _     
+ *  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: md5.c,v 1.9 2004/12/15 01:38:25 danf Exp $
+ ***************************************************************************/
+
+#include "setup.h"
+
+#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! */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+#include <string.h>
+
+/* UINT4 defines a four byte word */
+typedef unsigned int UINT4;
+
+/* MD5 context. */
+struct md5_ctx {
+  UINT4 state[4];                                   /* state (ABCD) */
+  UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
+  unsigned char buffer[64];                         /* input buffer */
+};
+
+typedef struct md5_ctx MD5_CTX;
+
+static void MD5_Init(struct md5_ctx *);
+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.
+ */
+
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void MD5Transform(UINT4 [4], const unsigned char [64]);
+static void Encode(unsigned char *, UINT4 *, unsigned int);
+static void Decode(UINT4 *, const unsigned char *, unsigned int);
+
+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
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+static void MD5_Init(struct md5_ctx *context)
+{
+  context->count[0] = context->count[1] = 0;
+  /* Load magic initialization constants. */
+  context->state[0] = 0x67452301;
+  context->state[1] = 0xefcdab89;
+  context->state[2] = 0x98badcfe;
+  context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+  operation, processing another message block, and updating the
+  context.
+ */
+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;
+
+  /* Compute number of bytes mod 64 */
+  bufindex = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+  /* Update number of bits */
+  if ((context->count[0] += ((UINT4)inputLen << 3))
+      < ((UINT4)inputLen << 3))
+    context->count[1]++;
+  context->count[1] += ((UINT4)inputLen >> 29);
+  
+  partLen = 64 - bufindex;
+
+  /* Transform as many times as possible. */
+  if (inputLen >= partLen) {
+    memcpy((void *)&context->buffer[bufindex], (void *)input, partLen);
+    MD5Transform(context->state, context->buffer);
+    
+    for (i = partLen; i + 63 < inputLen; i += 64)
+      MD5Transform(context->state, &input[i]);
+    
+    bufindex = 0;
+  }
+  else
+    i = 0;
+
+  /* Buffer remaining input */
+  memcpy((void *)&context->buffer[bufindex], (void *)&input[i], inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+   the message digest and zeroizing the context.
+*/
+static void MD5_Final(unsigned char digest[16], /* message digest */
+                      struct md5_ctx *context) /* context */
+{
+  unsigned char bits[8];
+  unsigned int count, padLen;
+
+  /* Save number of bits */
+  Encode (bits, context->count, 8);
+
+  /* Pad out to 56 mod 64. */
+  count = (unsigned int)((context->count[0] >> 3) & 0x3f);
+  padLen = (count < 56) ? (56 - count) : (120 - count);
+  MD5_Update (context, PADDING, padLen);
+
+  /* Append length (before padding) */
+  MD5_Update (context, bits, 8);
+
+  /* Store state in digest */
+  Encode (digest, context->state, 16);
+
+  /* Zeroize sensitive information. */
+  memset ((void *)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block. */
+static void MD5Transform(UINT4 state[4],
+                         const unsigned char block[64])
+{
+  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+  Decode (x, block, 64);
+
+  /* Round 1 */
+  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
+  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+  /* Round 3 */
+  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
+  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+  /* Round 4 */
+  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+  state[0] += a;
+  state[1] += b;
+  state[2] += c;
+  state[3] += d;
+
+  /* Zeroize sensitive information. */
+  memset((void *)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+  a multiple of 4.
+ */
+static void Encode (unsigned char *output,
+                    UINT4 *input,
+                    unsigned int len)
+{
+  unsigned int i, j;
+
+  for (i = 0, j = 0; j < len; i++, j += 4) {
+    output[j] = (unsigned char)(input[i] & 0xff);
+    output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+    output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+    output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+  }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+   a multiple of 4.
+*/
+static void Decode (UINT4 *output,
+                    const unsigned char *input,
+                    unsigned int len)
+{
+  unsigned int i, j;
+
+  for (i = 0, j = 0; j < len; i++, j += 4)
+    output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+      (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
+
+#else
+/* If OpenSSL is present */
+#include <openssl/md5.h>
+#include <string.h>
+#endif
+
+#include "md5.h"
+
+void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
+                const unsigned char *input)
+{
+  MD5_CTX ctx;
+  MD5_Init(&ctx);
+  MD5_Update(&ctx, input, strlen((char *)input));
+  MD5_Final(outbuffer, &ctx);
+}
+
+#endif

Added: trunk/apps/InstallMgr/curl/lib/select.c
===================================================================
--- trunk/apps/InstallMgr/curl/lib/select.c	2004-12-31 17:10:43 UTC (rev 399)
+++ trunk/apps/InstallMgr/curl/lib/select.c	2004-12-31 17:19:47 UTC (rev 400)
@@ -0,0 +1,246 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  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: select.c,v 1.5 2004/11/20 08:57:56 bagder Exp $
+ ***************************************************************************/
+
+#include "setup.h"
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifndef HAVE_SELECT
+#error "We can't compile without select() support!"
+#endif
+
+#include "select.h"
+
+#ifdef WIN32
+#define VALID_SOCK(s) (1)  /* Win-sockets are not in range [0..FD_SETSIZE> */
+#else
+#define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
+#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)
+{
+#ifdef HAVE_POLL_FINE
+  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++;
+  }
+
+  r = poll(pfd, num, timeout_ms);
+
+  if (r < 0)
+    return -1;
+  if (r == 0)
+    return 0;
+
+  ret = 0;
+  num = 0;
+  if (readfd != CURL_SOCKET_BAD) {
+    if (pfd[num].revents & POLLIN)
+      ret |= CSELECT_IN;
+    if (pfd[num].revents & POLLERR)
+      ret |= CSELECT_ERR;
+    num++;
+  }
+  if (writefd != CURL_SOCKET_BAD) {
+    if (pfd[num].revents & POLLOUT)
+      ret |= CSELECT_OUT;
+    if (pfd[num].revents & POLLERR)
+      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;
+
+  FD_ZERO(&fds_err);
+  maxfd = -1;
+
+  FD_ZERO(&fds_read);
+  if (readfd != CURL_SOCKET_BAD) {
+    if (!VALID_SOCK(readfd)) {
+      errno = EINVAL;
+      return -1;
+    }
+    FD_SET(readfd, &fds_read);
+    FD_SET(readfd, &fds_err);
+    maxfd = readfd;
+  }
+
+  FD_ZERO(&fds_write);
+  if (writefd != CURL_SOCKET_BAD) {
+    if (!VALID_SOCK(writefd)) {
+      errno = EINVAL;
+      return -1;
+    }
+    FD_SET(writefd, &fds_write);
+    FD_SET(writefd, &fds_err);
+    if (writefd > maxfd)
+      maxfd = writefd;
+  }
+
+  r = select(maxfd + 1, &fds_read, &fds_write, &fds_err, &timeout);
+
+  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)
+{
+#ifdef HAVE_POLL_FINE
+    return poll(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;
+  int r;
+  unsigned int i;
+
+  FD_ZERO(&fds_read);
+  FD_ZERO(&fds_write);
+  FD_ZERO(&fds_err);
+  maxfd = -1;
+
+  for (i = 0; i < nfds; i++) {
+    if (ufds[i].fd == CURL_SOCKET_BAD)
+      continue;
+#ifndef WIN32  /* This is harmless and wrong on Win32 */
+    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;
+  }
+
+  r = select(maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
+
+  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++;
+  }
+
+  return r;
+#endif
+}

Added: trunk/apps/InstallMgr/curl/lib/select.h
===================================================================
--- trunk/apps/InstallMgr/curl/lib/select.h	2004-12-31 17:10:43 UTC (rev 399)
+++ trunk/apps/InstallMgr/curl/lib/select.h	2004-12-31 17:19:47 UTC (rev 400)
@@ -0,0 +1,55 @@
+#ifndef __SELECT_H
+#define __SELECT_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: select.h,v 1.3 2004/11/19 14:38:02 giva Exp $
+ ***************************************************************************/
+
+#ifdef HAVE_SYS_POLL_H
+#include <sys/poll.h>
+#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);
+
+
+#endif

Added: trunk/apps/InstallMgr/curl/lib/share.c
===================================================================
--- trunk/apps/InstallMgr/curl/lib/share.c	2004-12-31 17:10:43 UTC (rev 399)
+++ trunk/apps/InstallMgr/curl/lib/share.c	2004-12-31 17:19:47 UTC (rev 400)
@@ -0,0 +1,219 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  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: share.c,v 1.22 2004/12/05 23:59:32 bagder Exp $
+ ***************************************************************************/
+
+#include "setup.h"
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <curl/curl.h>
+#include "urldata.h"
+#include "share.h"
+#include "memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+CURLSH *
+curl_share_init(void)
+{
+  struct Curl_share *share =
+    (struct Curl_share *)malloc(sizeof(struct Curl_share));
+  if (share) {
+    memset (share, 0, sizeof(struct Curl_share));
+    share->specifier |= (1<<CURL_LOCK_DATA_SHARE);
+  }
+
+  return share;
+}
+
+CURLSHcode
+curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
+{
+  struct Curl_share *share = (struct Curl_share *)sh;
+  va_list param;
+  int type;
+  curl_lock_function lockfunc;
+  curl_unlock_function unlockfunc;
+  void *ptr;
+
+  if (share->dirty)
+    /* don't allow setting options while one or more handles are already
+       using this share */
+    return CURLSHE_IN_USE;
+
+  va_start(param, option);
+
+  switch(option) {
+  case CURLSHOPT_SHARE:
+    /* this is a type this share will share */
+    type = va_arg(param, int);
+    share->specifier |= (1<<type);
+    switch( type ) {
+    case CURL_LOCK_DATA_DNS:
+      if (!share->hostcache) {
+        share->hostcache = Curl_mk_dnscache();
+        if(!share->hostcache)
+          return CURLSHE_NOMEM;
+      }
+      break;
+
+#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 );
+        if(!share->cookies)
+          return CURLSHE_NOMEM;
+      }
+      break;
+#endif   /* CURL_DISABLE_HTTP */
+
+    case CURL_LOCK_DATA_SSL_SESSION: /* not supported (yet) */
+    case CURL_LOCK_DATA_CONNECT:     /* not supported (yet) */
+
+    default:
+      return CURLSHE_BAD_OPTION;
+    }
+    break;
+
+  case CURLSHOPT_UNSHARE:
+    /* this is a type this share will no longer share */
+    type = va_arg(param, int);
+    share->specifier &= ~(1<<type);
+    switch( type )
+    {
+      case CURL_LOCK_DATA_DNS:
+        if (share->hostcache) {
+          Curl_hash_destroy(share->hostcache);
+          share->hostcache = NULL;
+        }
+        break;
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+      case CURL_LOCK_DATA_COOKIE:
+        if (share->cookies) {
+          Curl_cookie_cleanup(share->cookies);
+          share->cookies = NULL;
+        }
+        break;
+#endif   /* CURL_DISABLE_HTTP */
+
+      case CURL_LOCK_DATA_SSL_SESSION:
+        break;
+
+      case CURL_LOCK_DATA_CONNECT:
+        break;
+
+      default:
+        return CURLSHE_BAD_OPTION;
+    }
+    break;
+
+  case CURLSHOPT_LOCKFUNC:
+    lockfunc = va_arg(param, curl_lock_function);
+    share->lockfunc = lockfunc;
+    break;
+
+  case CURLSHOPT_UNLOCKFUNC:
+    unlockfunc = va_arg(param, curl_unlock_function);
+    share->unlockfunc = unlockfunc;
+    break;
+
+  case CURLSHOPT_USERDATA:
+    ptr = va_arg(param, void *);
+    share->clientdata = ptr;
+    break;
+
+  default:
+    return CURLSHE_BAD_OPTION;
+  }
+
+  return CURLSHE_OK;
+}
+
+CURLSHcode
+curl_share_cleanup(CURLSH *sh)
+{
+  struct Curl_share *share = (struct Curl_share *)sh;
+
+  if (share == NULL)
+    return CURLSHE_INVALID;
+
+  if(share->lockfunc)
+    share->lockfunc(NULL, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE,
+                    share->clientdata);
+
+  if (share->dirty) {
+    if(share->unlockfunc)
+      share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
+    return CURLSHE_IN_USE;
+  }
+
+  if(share->hostcache)
+    Curl_hash_destroy(share->hostcache);
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+  if(share->cookies)
+    Curl_cookie_cleanup(share->cookies);
+#endif   /* CURL_DISABLE_HTTP */
+
+  if(share->unlockfunc)
+    share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
+  free(share);
+
+  return CURLSHE_OK;
+}
+
+
+CURLSHcode
+Curl_share_lock(struct SessionHandle *data, curl_lock_data type,
+                curl_lock_access accesstype)
+{
+  struct Curl_share *share = data->share;
+
+  if (share == NULL)
+    return CURLSHE_INVALID;
+
+  if(share->specifier & (1<<type)) {
+    if(share->lockfunc) /* only call this if set! */
+      share->lockfunc(data, type, accesstype, share->clientdata);
+  }
+  /* else if we don't share this, pretend successful lock */
+
+  return CURLSHE_OK;
+}
+
+CURLSHcode
+Curl_share_unlock(struct SessionHandle *data, curl_lock_data type)
+{
+  struct Curl_share *share = data->share;
+
+  if (share == NULL)
+    return CURLSHE_INVALID;
+
+  if(share->specifier & (1<<type)) {
+    if(share->unlockfunc) /* only call this if set! */
+      share->unlockfunc (data, type, share->clientdata);
+  }
+
+  return CURLSHE_OK;
+}

Added: trunk/apps/InstallMgr/curl/lib/strerror.c
===================================================================
--- trunk/apps/InstallMgr/curl/lib/strerror.c	2004-12-31 17:10:43 UTC (rev 399)
+++ trunk/apps/InstallMgr/curl/lib/strerror.c	2004-12-31 17:19:47 UTC (rev 400)
@@ -0,0 +1,686 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 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.
+ *
+ ***************************************************************************/
+
+#include "setup.h"
+
+#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
+#ifdef HAVE_POSIX_STRERROR_R
+/* seen on AIX 5100-02 gcc 2.9 */
+extern int strerror_r(int errnum, char *strerrbuf, size_t buflen);
+#else
+extern char *strerror_r(int errnum, char *buf, size_t buflen);
+#endif
+#endif
+
+const char *
+curl_easy_strerror(CURLcode error)
+{
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  switch (error) {
+  case CURLE_OK:
+    return "no error";
+
+  case CURLE_UNSUPPORTED_PROTOCOL:
+    return "unsupported protocol";
+
+  case CURLE_FAILED_INIT:
+    return "failed init";
+
+  case CURLE_URL_MALFORMAT:
+    return "URL using bad/illegal format or missing URL";
+
+  case CURLE_COULDNT_RESOLVE_PROXY:
+    return "couldnt resolve proxy name";
+
+  case CURLE_COULDNT_RESOLVE_HOST:
+    return "couldnt resolve host name";
+
+  case CURLE_COULDNT_CONNECT:
+    return "couldn't connect to server";
+
+  case CURLE_FTP_WEIRD_SERVER_REPLY:
+    return "FTP: weird server reply";
+
+  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";
+
+  case CURLE_FTP_WEIRD_USER_REPLY:
+    return "FTP: unknown USER reply";
+
+  case CURLE_FTP_WEIRD_PASV_REPLY:
+    return "FTP: unknown PASV reply";
+
+  case CURLE_FTP_WEIRD_227_FORMAT:
+    return "FTP: unknown 227 response format";
+
+  case CURLE_FTP_CANT_GET_HOST:
+    return "FTP: can't figure out the host in the PASV response";
+
+  case CURLE_FTP_CANT_RECONNECT:
+    return "FTP: can't connect to server the response code is unknown";
+
+  case CURLE_FTP_COULDNT_SET_BINARY:
+    return "FTP: couldn't set binary mode";
+
+  case CURLE_PARTIAL_FILE:
+    return "Transferred a partial file";
+
+  case CURLE_FTP_COULDNT_RETR_FILE:
+    return "FTP: couldn't retrieve (RETR failed) the specified file";
+
+  case CURLE_FTP_WRITE_ERROR:
+    return "FTP: the post-transfer acknowledge response was not OK";
+
+  case CURLE_FTP_QUOTE_ERROR:
+    return "FTP: a quote command returned error";
+
+  case CURLE_HTTP_RETURNED_ERROR:
+    return "HTTP response code said error";
+
+  case CURLE_WRITE_ERROR:
+    return "failed writing received data to disk/application";
+
+  case CURLE_FTP_COULDNT_STOR_FILE:
+    return "failed FTP upload (the STOR command)";
+
+  case CURLE_READ_ERROR:
+    return "failed to open/read local data from file/application";
+
+  case CURLE_OUT_OF_MEMORY:
+    return "out of memory";
+
+  case CURLE_OPERATION_TIMEOUTED:
+    return "a timeout was reached";
+
+  case CURLE_FTP_COULDNT_SET_ASCII:
+    return "FTP could not set ASCII mode (TYPE A)";
+
+  case CURLE_FTP_PORT_FAILED:
+    return "FTP command PORT failed";
+
+  case CURLE_FTP_COULDNT_USE_REST:
+    return "FTP command REST failed";
+
+  case CURLE_FTP_COULDNT_GET_SIZE:
+    return "FTP command SIZE failed";
+
+  case CURLE_HTTP_RANGE_ERROR:
+    return "a range was requested but the server did not deliver it";
+
+  case CURLE_HTTP_POST_ERROR:
+    return "internal problem setting up the POST";
+
+  case CURLE_SSL_CONNECT_ERROR:
+    return "SSL connect error";
+
+  case CURLE_BAD_DOWNLOAD_RESUME:
+    return "couldn't resume download";
+
+  case CURLE_FILE_COULDNT_READ_FILE:
+    return "couldn't read a file:// file";
+
+  case CURLE_LDAP_CANNOT_BIND:
+    return "LDAP: cannot bind";
+
+  case CURLE_LDAP_SEARCH_FAILED:
+    return "LDAP: search failed";
+
+  case CURLE_LIBRARY_NOT_FOUND:
+    return "a required shared library was not found";
+
+  case CURLE_FUNCTION_NOT_FOUND:
+    return "a required function in the shared library was not found";
+
+  case CURLE_ABORTED_BY_CALLBACK:
+    return "the operation was aborted by an application callback";
+
+  case CURLE_BAD_FUNCTION_ARGUMENT:
+    return "a libcurl function was given a bad argument";
+
+  case CURLE_INTERFACE_FAILED:
+    return "failed binding local connection end";
+
+  case CURLE_TOO_MANY_REDIRECTS :
+    return "number of redirects hit maximum amount";
+
+  case CURLE_UNKNOWN_TELNET_OPTION:
+    return "User specified an unknown option";
+
+  case CURLE_TELNET_OPTION_SYNTAX :
+    return "Malformed telnet option";
+
+  case CURLE_SSL_PEER_CERTIFICATE:
+    return "SSL peer certificate was not ok";
+
+  case CURLE_GOT_NOTHING:
+    return "server returned nothing (no headers, no data)";
+
+  case CURLE_SSL_ENGINE_NOTFOUND:
+    return "SSL crypto engine not found";
+
+  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";
+
+  case CURLE_RECV_ERROR:
+    return "failure when receiving data from the peer";
+
+  case CURLE_SHARE_IN_USE:
+    return "share is already in use";
+
+  case CURLE_SSL_CERTPROBLEM:
+    return "problem with the local SSL certificate";
+
+  case CURLE_SSL_CIPHER:
+    return "couldn't use specified SSL cipher";
+
+  case CURLE_SSL_CACERT:
+    return "problem with the SSL CA cert (path? access rights?)";
+
+  case CURLE_BAD_CONTENT_ENCODING:
+    return "Unrecognized HTTP Content-Encoding";
+
+  case CURLE_LDAP_INVALID_URL:
+    return "Invalid LDAP URL";
+
+  case CURLE_FILESIZE_EXCEEDED:
+    return "Maximum file size exceeded";
+
+  case CURLE_FTP_SSL_FAILED:
+    return "Requested FTP SSL level failed";
+
+  case CURLE_SEND_FAIL_REWIND:
+    return "Send failed since rewinding of the data stream 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 CURL_LAST:
+    break;
+  }
+  /*
+   * By using a switch, gcc -Wall will complain about enum values
+   * which do not appear, helping keep this function up-to-date.
+   * By using gcc -Wall -Werror, you can't forget.
+   *
+   * A table would not have the same benefit.  Most compilers will
+   * generate code very similar to a table in any case, so there
+   * is little performance gain from a table.  And something is broken
+   * for the user's application, anyways, so does it matter how fast
+   * it _doesn't_ work?
+   *
+   * The line number for the error will be near this comment, which
+   * 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";
+
+  case CURLM_BAD_EASY_HANDLE:
+    return "invalid easy handle";
+
+  case CURLM_OUT_OF_MEMORY:
+    return "out of memory";
+
+  case CURLM_INTERNAL_ERROR:
+    return "internal error";
+
+  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";
+
+  case CURLSHE_BAD_OPTION:
+    return "unknown share option";
+
+  case CURLSHE_IN_USE:
+    return "share currently in use";
+
+  case CURLSHE_INVALID:
+    return "invalid share handle";
+
+  case CURLSHE_NOMEM:
+    return "out of memory";
+
+  case CURLSHE_LAST:
+    break;
+  }
+
+  return "CURLSH unknown";
+#else
+  if (error == CURLSHE_OK)
+    return "no error";
+  else
+    return "error";
+#endif
+}
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+
+/* 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;
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  switch (err) {
+  case WSAEINTR:
+    p = "Call interrupted.";
+    break;
+  case WSAEBADF:
+    p = "Bad file";
+    break;
+  case WSAEACCES:
+    p = "Bad access";
+    break;
+  case WSAEFAULT:
+    p = "Bad argument";
+    break;
+  case WSAEINVAL:
+    p = "Invalid arguments";
+    break;
+  case WSAEMFILE:
+    p = "Out of file descriptors";
+    break;
+  case WSAEWOULDBLOCK:
+    p = "Call would block";
+    break;
+  case WSAEINPROGRESS:
+  case WSAEALREADY:
+    p = "Blocking call in progress";
+    break;
+  case WSAENOTSOCK:
+    p = "Descriptor is not a socket.";
+    break;
+  case WSAEDESTADDRREQ:
+    p = "Need destination address";
+    break;
+  case WSAEMSGSIZE:
+    p = "Bad message size";
+    break;
+  case WSAEPROTOTYPE:
+    p = "Bad protocol";
+    break;
+  case WSAENOPROTOOPT:
+    p = "Protocol option is unsupported";
+    break;
+  case WSAEPROTONOSUPPORT:
+    p = "Protocol is unsupported";
+    break;
+  case WSAESOCKTNOSUPPORT:
+    p = "Socket is unsupported";
+    break;
+  case WSAEOPNOTSUPP:
+    p = "Operation not supported";
+    break;
+  case WSAEAFNOSUPPORT:
+    p = "Address family not supported";
+    break;
+  case WSAEPFNOSUPPORT:
+    p = "Protocol family not supported";
+    break;
+  case WSAEADDRINUSE:
+    p = "Address already in use";
+    break;
+  case WSAEADDRNOTAVAIL:
+    p = "Address not available";
+    break;
+  case WSAENETDOWN:
+    p = "Network down";
+    break;
+  case WSAENETUNREACH:
+    p = "Network unreachable";
+    break;
+  case WSAENETRESET:
+    p = "Network has been reset";
+    break;
+  case WSAECONNABORTED:
+    p = "Connection was aborted";
+    break;
+  case WSAECONNRESET:
+    p = "Connection was reset";
+    break;
+  case WSAENOBUFS:
+    p = "No buffer space";
+    break;
+  case WSAEISCONN:
+    p = "Socket is already connected";
+    break;
+  case WSAENOTCONN:
+    p = "Socket is not connected";
+    break;
+  case WSAESHUTDOWN:
+    p = "Socket has been shut down";
+    break;
+  case WSAETOOMANYREFS:
+    p = "Too many references";
+    break;
+  case WSAETIMEDOUT:
+    p = "Timed out";
+    break;
+  case WSAECONNREFUSED:
+    p = "Connection refused";
+    break;
+  case WSAELOOP:
+    p = "Loop??";
+    break;
+  case WSAENAMETOOLONG:
+    p = "Name too long";
+    break;
+  case WSAEHOSTDOWN:
+    p = "Host down";
+    break;
+  case WSAEHOSTUNREACH:
+    p = "Host unreachable";
+    break;
+  case WSAENOTEMPTY:
+    p = "Not empty";
+    break;
+  case WSAEPROCLIM:
+    p = "Process limit reached";
+    break;
+  case WSAEUSERS:
+    p = "Too many users";
+    break;
+  case WSAEDQUOT:
+    p = "Bad quota";
+    break;
+  case WSAESTALE:
+    p = "Something is stale";
+    break;
+  case WSAEREMOTE:
+    p = "Remote error";
+    break;
+  case WSAEDISCON:
+    p = "Disconnected";
+    break;
+
+    /* Extended Winsock errors */
+  case WSASYSNOTREADY:
+    p = "Winsock library is not ready";
+    break;
+  case WSANOTINITIALISED:
+    p = "Winsock library not initalised";
+    break;
+  case WSAVERNOTSUPPORTED:
+    p = "Winsock version not supported.";
+    break;
+
+    /* getXbyY() errors (already handled in herrmsg):
+     * Authoritative Answer: Host not found */
+  case WSAHOST_NOT_FOUND:
+    p = "Host not found";
+    break;
+
+    /* Non-Authoritative: Host not found, or SERVERFAIL */
+  case WSATRY_AGAIN:
+    p = "Host not found, try again";
+    break;
+
+    /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+  case WSANO_RECOVERY:
+    p = "Unrecoverable error in call to nameserver";
+    break;
+
+    /* Valid name, no data record of requested type */
+  case WSANO_DATA:
+    p = "No data record of requested type";
+    break;
+
+  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__ */
+
+/*
+ * Our thread-safe and smart strerror() replacement.
+ *
+ * The 'err' argument passed in to this function MUST be a true errno number
+ * as reported on this system. We do no range checking on the number before
+ * we pass it to the "number-to-message" convertion function and there might
+ * be systems that don't do proper range checking in there themselves.
+ *
+ * We don't do range checking (on systems other than Windows) since there is
+ * no good reliable and portable way to do it.
+ */
+const char *Curl_strerror(struct connectdata *conn, int err)
+{
+  char *buf, *p;
+  size_t max;
+
+  curlassert(conn);
+  curlassert(err >= 0);
+
+  buf = conn->syserr_buf;
+  max = sizeof(conn->syserr_buf)-1;
+  *buf = '\0';
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+
+#if _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))
+      snprintf(buf, max, "Unknown error %d (%#x)", err, err);
+  }
+#endif
+#else /* not native Windows 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);
+  /* 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.*/
+#else
+  {
+    /* HAVE_GLIBC_STRERROR_R */
+    char buffer[256];
+    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 */
+    strncpy(buf, msg, max);
+  }
+#endif /* end of HAVE_GLIBC_STRERROR_R */
+#else /* HAVE_STRERROR_R */
+  strncpy(buf, strerror(err), max);
+#endif /* end of HAVE_STRERROR_R */
+#endif /* end of ! Windows */
+
+  buf[max] = '\0'; /* make sure the string is zero terminated */
+
+  /* strip trailing '\r\n' or '\n'. */
+  if ((p = strrchr(buf,'\n')) != NULL && (p - buf) >= 2)
+     *p = '\0';
+  if ((p = strrchr(buf,'\r')) != NULL && (p - buf) >= 1)
+     *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 */

Added: trunk/apps/InstallMgr/curl/lib/strerror.h
===================================================================
--- trunk/apps/InstallMgr/curl/lib/strerror.h	2004-12-31 17:10:43 UTC (rev 399)
+++ trunk/apps/InstallMgr/curl/lib/strerror.h	2004-12-31 17:19:47 UTC (rev 400)
@@ -0,0 +1,34 @@
+#ifndef __CURL_STRERROR_H
+#define __CURL_STRERROR_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: strerror.h,v 1.3 2004/10/11 17:26:24 bagder Exp $
+ ***************************************************************************/
+
+#include "urldata.h"
+
+const char *Curl_strerror (struct connectdata *conn, int err);
+
+#ifdef USE_LIBIDN
+const char *Curl_idn_strerror (struct connectdata *conn, int err);
+#endif
+
+#endif



More information about the sword-cvs mailing list