--- include/curl/curl.h	4 Sep 2005 05:16:06 -0000	1.286
+++ include/curl/curl.h	27 Nov 2005 20:49:49 -0000
@@ -316,6 +316,7 @@
   CURLE_TFTP_UNKNOWNID,          /* 72 - Unknown transfer ID */
   CURLE_TFTP_EXISTS,             /* 73 - File already exists */
   CURLE_TFTP_NOSUCHUSER,         /* 74 - No such user */
+  CURLE_NO_SOCKETS,              /* 75 - User didn't provide socket facility */
   CURL_LAST /* never use! */
 } CURLcode;
 
@@ -1195,6 +1196,12 @@
   struct curl_slist *next;
 };
 
+CURL_EXTERN void curl_global_set_mem(curl_malloc_callback m,
+                                     curl_free_callback f,
+                                     curl_realloc_callback r,
+                                     curl_strdup_callback s,
+                                     curl_calloc_callback c);
+    
 /*
  * NAME curl_slist_append()
  *
--- include/curl/easy.h	9 Nov 2004 14:02:58 -0000	1.13
+++ include/curl/easy.h	27 Nov 2005 20:49:49 -0000
@@ -22,11 +22,15 @@
  *
  * $Id: easy.h,v 1.13 2004/11/09 14:02:58 giva Exp $
  ***************************************************************************/
+
+#include "client.h"
+
 #ifdef  __cplusplus
 extern "C" {
 #endif
 
 CURL_EXTERN CURL *curl_easy_init(void);
+CURL_EXTERN CURL *curl_easy_init_c(CURLC *curlc);
 CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
 CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
 CURL_EXTERN void curl_easy_cleanup(CURL *curl);
--- lib/Makefile.am	31 Mar 2005 07:02:03 -0000	1.108
+++ lib/Makefile.am	27 Nov 2005 20:49:50 -0000
@@ -34,6 +34,8 @@
 
 CLEANFILES = $(DSP)
 
+LIBTOOL=libtool
+
 lib_LTLIBRARIES = libcurl.la
 
 # we use srcdir/include for the static global include files
--- lib/Makefile.inc	11 Nov 2005 22:04:11 -0000	1.9
+++ lib/Makefile.inc	27 Nov 2005 20:49:50 -0000
@@ -8,7 +8,7 @@
   content_encoding.c share.c http_digest.c md5.c http_negotiate.c	\
   http_ntlm.c inet_pton.c strtoofft.c strerror.c hostares.c hostasyn.c	\
   hostip4.c hostip6.c hostsyn.c hostthre.c inet_ntop.c parsedate.c	\
-  select.c gtls.c sslgen.c tftp.c
+  select.c gtls.c sslgen.c tftp.c client.c
 
 HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h	\
   progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h	\
@@ -18,6 +18,6 @@
   share.h md5.h http_digest.h http_negotiate.h http_ntlm.h ca-bundle.h	\
   inet_pton.h strtoofft.h strerror.h inet_ntop.h curlx.h memory.h	\
   setup.h transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h   \
-  gtls.h tftp.h sockaddr.h
+  gtls.h tftp.h sockaddr.h client.h
 
 
--- lib/easy.c	17 Jul 2005 12:44:11 -0000	1.73
+++ lib/easy.c	27 Nov 2005 20:49:51 -0000
@@ -169,11 +169,16 @@
 static unsigned int  initialized;
 static long          init_flags;
 
+/* This is the Curl Client that a user of curl_global_init() uses.  A
+   non-curl_global_init() user, in contrast, creates his own
+   Curl Client and passes its handle to any libcurl function that
+   needs one.  */
+CURLC * curl_global_client;
+
 /*
  * If a memory-using function (like curl_getenv) is used before
  * curl_global_init() is called, we need to have these pointers set already.
  */
-
 #ifdef _WIN32_WCE
 #define strdup _strdup
 #endif
@@ -193,12 +198,7 @@
   if (initialized)
     return CURLE_OK;
 
-  /* Setup the default memory functions here (again) */
-  Curl_cmalloc = (curl_malloc_callback)malloc;
-  Curl_cfree = (curl_free_callback)free;
-  Curl_crealloc = (curl_realloc_callback)realloc;
-  Curl_cstrdup = (curl_strdup_callback)strdup;
-  Curl_ccalloc = (curl_calloc_callback)calloc;
+  curl_global_client = curl_client_init();
 
   if (flags & CURL_GLOBAL_SSL)
     if (!Curl_ssl_init())
@@ -217,6 +217,15 @@
   idna_init();
 #endif
 
+  /* Where we didn't initialize some global facility because the user
+     told us not to, we assume that he initialized it.  So tell the client
+     to go ahead and use all the global facilities.
+  */
+  curl_client_use_global_openssl(curl_global_client);
+  curl_client_use_global_gnutls(curl_global_client);
+  curl_client_use_global_sock(curl_global_client);
+  curl_client_use_charset(curl_global_client);
+
   initialized = 1;
   init_flags  = flags;
 
@@ -243,13 +252,8 @@
 
   /* Call the actual init function first */
   code = curl_global_init(flags);
-  if (code == CURLE_OK) {
-    Curl_cmalloc = m;
-    Curl_cfree = f;
-    Curl_cstrdup = s;
-    Curl_crealloc = r;
-    Curl_ccalloc = c;
-  }
+  if (code == CURLE_OK)
+    curl_global_set_mem(m, f, r, s, c);
 
   return code;
 }
@@ -265,6 +269,10 @@
 
   Curl_global_host_cache_dtor();
 
+  curl_client_cleanup(curl_global_client);
+
+  curl_global_client = NULL;
+
   if (init_flags & CURL_GLOBAL_SSL)
     Curl_ssl_cleanup();
 
@@ -279,6 +287,17 @@
   init_flags  = 0;
 }
 
+void curl_global_set_mem(curl_malloc_callback m,
+                         curl_free_callback f, curl_realloc_callback r,
+                         curl_strdup_callback s, curl_calloc_callback c)
+{
+  Curl_cmalloc = m;
+  Curl_cfree = f;
+  Curl_cstrdup = s;
+  Curl_crealloc = r;
+  Curl_ccalloc = c;
+}
+
 /*
  * curl_easy_init() is the external interface to alloc, setup and init an
  * easy handle that is returned. If anything goes wrong, NULL is returned.
@@ -297,7 +316,20 @@
   }
 
   /* We use curl_open() with undefined URL so far */
-  res = Curl_open(&data);
+  res = Curl_open(&data, curl_global_client);
+  if(res != CURLE_OK)
+    return NULL;
+
+  return data;
+}
+
+CURL *curl_easy_init_c(CURLC *curlc)
+{
+  CURLcode res;
+  struct SessionHandle *data;
+
+  /* We use curl_open() with undefined URL so far */
+  res = Curl_open(&data, curlc);
   if(res != CURLE_OK)
     return NULL;
 
--- lib/sslgen.c	11 Aug 2005 21:41:11 -0000	1.6
+++ lib/sslgen.c	27 Nov 2005 20:49:51 -0000
@@ -196,14 +196,24 @@
 Curl_ssl_connect(struct connectdata *conn, int sockindex)
 {
 #ifdef USE_SSL
-  /* mark this is being ssl enabled from here on. */
-  conn->ssl[sockindex].use = TRUE;
+  /* We don't know how to use any SSL library without involving the library's
+     global state, so if the client hasn't set that up (or just won't
+     allow us to use it), we don't enable the connection for SSL.  But
+     otherwise we do (conn->ssl[sockindex].use). */
 
 #ifdef USE_SSLEAY
+  if(curl_client_global_openssl_ok(conn->data->client)) {
+    conn->ssl[sockindex].use = TRUE;
   return Curl_ossl_connect(conn, sockindex);
+  } else
+    return CURLE_OK;
 #else
 #ifdef USE_GNUTLS
+  if(curl_client_global_gnutls_ok(conn->data->client)) {
+    conn->ssl[sockindex].use = TRUE;
   return Curl_gtls_connect(conn, sockindex);
+  } else
+    return CURLE_OK
 #endif /* USE_GNUTLS */
 #endif /* USE_SSLEAY */
 
--- lib/ssluse.c	13 Nov 2005 23:53:14 -0000	1.136
+++ lib/ssluse.c	27 Nov 2005 20:49:52 -0000
@@ -585,7 +585,13 @@
 CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine)
 {
 #if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
-  ENGINE *e = ENGINE_by_id(engine);
+  ENGINE *e;
+  if (!curl_client_global_openssl_ok(data->client)) {
+    failf(data, "To set an SSL engine, you must initialize the OpenSSL "
+          "crypto engine facility and call curl_client_use_global_openssl()");
+    return (CURLE_SSL_ENGINE_NOTFOUND);
+  }
+  e = ENGINE_by_id(engine);
 
   if (!e) {
     failf(data, "SSL Engine '%s' not found", engine);
@@ -644,6 +650,7 @@
 #if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
   ENGINE *e;
 
+  if (curl_client_global_openssl_ok(data->client))
   for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
     list = curl_slist_append(list, ENGINE_get_id(e));
 #endif
--- lib/url.c	27 Oct 2005 22:05:38 -0000	1.481
+++ lib/url.c	27 Nov 2005 20:49:56 -0000
@@ -278,10 +278,13 @@
  *
  * @param curl is a pointer to a sessionhandle pointer that gets set by this
  * function.
+ * @param curlc is a handle for the Curl client to which this session will
+ * belong.
  * @return CURLcode
  */
 
-CURLcode Curl_open(struct SessionHandle **curl)
+CURLcode Curl_open(struct SessionHandle **curl,
+                   CURLC *curlc)
 {
   CURLcode res = CURLE_OK;
   struct SessionHandle *data;
@@ -291,6 +294,14 @@
     /* this is a very serious error */
     return CURLE_OUT_OF_MEMORY;
 
+  /* Today, we don't know any way to access socket functions except
+     through a process-global socket facility, and a Curl session is
+     useless without sockets, so if the Curl client doesn't want us to
+     use the global socket facility, we just have to fail.
+  */
+  if(!curl_client_global_sock_ok(curlc))
+    return CURLE_NO_SOCKETS;
+
 #ifdef USE_ARES
   if(ARES_SUCCESS != ares_init(&data->state.areschannel)) {
     free(data);
@@ -302,6 +313,8 @@
 
   /* We do some initial setup here, all those fields that can't be just 0 */
 
+  data->client = curlc;
+
   data->state.headerbuff=(char*)malloc(HEADERSIZE);
   if(!data->state.headerbuff)
     res = CURLE_OUT_OF_MEMORY;
@@ -2232,6 +2245,11 @@
       stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
     char *ace_hostname = NULL;
     struct SessionHandle *data = conn->data;
+    if (!curl_client_charset_ok(conn->data->client))
+      infof(data, "Cannot convert %s to ACE; you must set CHARSET "
+            "environment variable and "
+            "call curl_client_use_charset().\n");
+    else {
     int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
     infof (data, "Input domain encoded as `%s'\n",
            stringprep_locale_charset ());
@@ -2246,6 +2264,7 @@
       host->name = host->encalloc;
     }
   }
+  }
 #else
   (void)conn; /* never used */
 #endif
--- lib/url.h	17 Jul 2005 12:44:11 -0000	1.23
+++ lib/url.h	27 Nov 2005 20:49:56 -0000
@@ -29,7 +29,8 @@
  * Prototypes for library-wide functions provided by url.c
  */
 
-CURLcode Curl_open(struct SessionHandle **curl);
+CURLcode Curl_open(struct SessionHandle **curl,
+                   CURLC *curlc);
 CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
                      va_list arg);
 CURLcode Curl_close(struct SessionHandle *data); /* opposite of curl_open() */
--- lib/urldata.h	27 Oct 2005 22:05:38 -0000	1.274
+++ lib/urldata.h	27 Nov 2005 20:49:57 -0000
@@ -1091,6 +1091,8 @@
  * 'struct urlstate' instead.  */
 
 struct SessionHandle {
+  CURLC *client;               /* The Curl client to which this session
+                                  belongs */
   struct curl_hash *hostcache;
   void *multi;                 /* if non-NULL, points to the multi handle
                                   struct of which this "belongs" */
