Index: conf/cupsd.conf.in
===================================================================
--- conf/cupsd.conf.in	(revision 4677)
+++ conf/cupsd.conf.in	(working copy)
@@ -28,7 +28,7 @@
 # Restrict access to configuration files...
 <Location /admin/conf>
 AuthType Basic
-AuthClass SystemGroup
+AuthClass System
 Order allow,deny
 Allow localhost
 </Location>
Index: config-scripts/cups-compiler.m4
===================================================================
--- config-scripts/cups-compiler.m4	(revision 4677)
+++ config-scripts/cups-compiler.m4	(working copy)
@@ -57,16 +57,22 @@
 	fi
 
 	AC_MSG_CHECKING(if GCC supports -fpie)
+	case $uname in
+	        Darwin*)
+			AC_MSG_RESULT(no)
+	                ;;
+	        *)
+			OLDCFLAGS="$CFLAGS"
+			CFLAGS="$CFLAGS -fpie"
+			AC_TRY_COMPILE(,,
+				OPTIM="$OPTIM -fpie"
+				LDFLAGS="$LDFLAGS -pie"
+				AC_MSG_RESULT(yes),
+				CFLAGS="$OLDCFLAGS"
+				AC_MSG_RESULT(no))
+			;;
+	esac
 
-	OLDCFLAGS="$CFLAGS"
-	CFLAGS="$CFLAGS -fpie"
-	AC_TRY_COMPILE(,,
-		OPTIM="$OPTIM -fpie"
-		LDFLAGS="$LDFLAGS -pie"
-		AC_MSG_RESULT(yes),
-		CFLAGS="$OLDCFLAGS"
-		AC_MSG_RESULT(no))
-
 	if test "x$with_optim" = x; then
 		# Add useful warning options for tracking down problems...
 		OPTIM="-Wall -Wno-format-y2k $OPTIM"
Index: cups/emit.c
===================================================================
--- cups/emit.c	(revision 4677)
+++ cups/emit.c	(working copy)
@@ -64,7 +64,7 @@
  * Local globals...
  */
 
-static const char *ppd_custom_code =
+static const char ppd_custom_code[] =
 		"pop pop pop\n"
 		"<</PageSize[5 -2 roll]/ImagingBBox null>>setpagedevice\n";
 
Index: cups/tempfile.c
===================================================================
--- cups/tempfile.c	(revision 4677)
+++ cups/tempfile.c	(working copy)
@@ -36,6 +36,7 @@
 
 #include "cups.h"
 #include "string.h"
+#include "globals.h"
 #include "debug.h"
 #include <stdlib.h>
 #include <ctype.h>
@@ -60,13 +61,13 @@
   int		fd;			/* File descriptor for temp file */
   int		tries;			/* Number of tries */
   const char	*tmpdir;		/* TMPDIR environment var */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
 #ifdef WIN32
   char		tmppath[1024];		/* Windows temporary directory */
   DWORD		curtime;		/* Current time */
 #else
   struct timeval curtime;		/* Current time */
 #endif /* WIN32 */
-  static char	*buf = NULL;		/* Buffer if you pass in NULL and 0 */
 
 
  /*
@@ -75,13 +76,13 @@
 
   if (filename == NULL)
   {
-    if (buf == NULL)
-      buf = calloc(1024, sizeof(char));
+    if (cg->temp_fd_buf == NULL)
+      cg->temp_fd_buf = calloc(1024, sizeof(char));
 
-    if (buf == NULL)
+    if (cg->temp_fd_buf == NULL)
       return (-1);
 
-    filename = buf;
+    filename = cg->temp_fd_buf;
     len      = 1024;
   }
 
@@ -183,7 +184,6 @@
              int  len)			/* I - Size of buffer */
 {
   int		fd;			/* File descriptor for temp file */
-  static char	buf[1024] = "";		/* Buffer if you pass in NULL and 0 */
 
 
  /*
@@ -192,8 +192,8 @@
 
   if (filename == NULL)
   {
-    filename = buf;
-    len      = sizeof(buf);
+    filename = _cups_globals()->temp_file_buf;
+    len      = sizeof(_cups_globals()->temp_file_buf);
   }
 
  /*
Index: cups/util.c
===================================================================
--- cups/util.c	(revision 4677)
+++ cups/util.c	(working copy)
@@ -51,6 +51,7 @@
 #include "cups.h"
 #include "language.h"
 #include "string.h"
+#include "globals.h"
 #include "debug.h"
 #include <stdlib.h>
 #include <ctype.h>
@@ -65,14 +66,6 @@
 
 
 /*
- * Local globals...
- */
-
-static http_t		*cups_server = NULL;	/* Current server connection */
-static ipp_status_t	last_error = IPP_OK;	/* Last IPP error */
-
-
-/*
  * Local functions...
  */
 
@@ -93,6 +86,7 @@
   ipp_t		*request,		/* IPP request */
 		*response;		/* IPP response */
   cups_lang_t	*language;		/* Language info */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
 
 
  /*
@@ -102,7 +96,7 @@
   if (!cups_connect(name, printer, hostname))
   {
     DEBUG_puts("Unable to connect to server!");
-    last_error = IPP_SERVICE_UNAVAILABLE;
+    cg->last_error = IPP_SERVICE_UNAVAILABLE;
     return (0);
   }
 
@@ -146,10 +140,10 @@
   * Do the request...
   */
 
-  if ((response = cupsDoRequest(cups_server, request, "/jobs/")) != NULL)
+  if ((response = cupsDoRequest(cg->http, request, "/jobs/")) != NULL)
     ippDelete(response);
 
-  return (last_error < IPP_REDIRECTION_OTHER_SITE);
+  return (cg->last_error < IPP_REDIRECTION_OTHER_SITE);
 }
 
 
@@ -170,6 +164,7 @@
   struct stat	fileinfo;		/* File information */
   int		bytes;			/* Number of bytes read/written */
   char		buffer[32768];		/* Output buffer */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
 
 
   DEBUG_printf(("cupsDoFileRequest(%p, %p, \'%s\', \'%s\')\n",
@@ -181,7 +176,7 @@
     if (request != NULL)
       ippDelete(request);
 
-    last_error = IPP_INTERNAL_ERROR;
+    cg->last_error = IPP_INTERNAL_ERROR;
     return (NULL);
   }
 
@@ -198,7 +193,7 @@
       */
 
       ippDelete(request);
-      last_error = IPP_NOT_FOUND;
+      cg->last_error = IPP_NOT_FOUND;
       return (NULL);
     }
 
@@ -213,7 +208,7 @@
       */
 
       ippDelete(request);
-      last_error = IPP_NOT_POSSIBLE;
+      cg->last_error = IPP_NOT_POSSIBLE;
       return (NULL);
     }
 
@@ -224,7 +219,7 @@
       */
 
       ippDelete(request);
-      last_error = IPP_NOT_FOUND;
+      cg->last_error = IPP_NOT_FOUND;
       return (NULL);
     }
   }
@@ -359,7 +354,11 @@
       httpFlush(http);
 
       /* Reconnect... */
-      httpReconnect(http);
+      if (httpReconnect(http))
+      {
+        status = HTTP_ERROR;
+        break;
+      }
 
       /* Upgrade with encryption... */
       httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
@@ -399,7 +398,7 @@
 	ippDelete(response);
 	response = NULL;
 
-        last_error = IPP_SERVICE_UNAVAILABLE;
+        cg->last_error = IPP_SERVICE_UNAVAILABLE;
 	break;
       }
     }
@@ -425,43 +424,43 @@
   ippDelete(request);
 
   if (response)
-    last_error = response->request.status.status_code;
+    cg->last_error = response->request.status.status_code;
   else if (status != HTTP_OK)
   {
     switch (status)
     {
       case HTTP_NOT_FOUND :
-          last_error = IPP_NOT_FOUND;
+          cg->last_error = IPP_NOT_FOUND;
 	  break;
 
       case HTTP_UNAUTHORIZED :
-          last_error = IPP_NOT_AUTHORIZED;
+          cg->last_error = IPP_NOT_AUTHORIZED;
 	  break;
 
       case HTTP_FORBIDDEN :
-          last_error = IPP_FORBIDDEN;
+          cg->last_error = IPP_FORBIDDEN;
 	  break;
 
       case HTTP_BAD_REQUEST :
-          last_error = IPP_BAD_REQUEST;
+          cg->last_error = IPP_BAD_REQUEST;
 	  break;
 
       case HTTP_REQUEST_TOO_LARGE :
-          last_error = IPP_REQUEST_VALUE;
+          cg->last_error = IPP_REQUEST_VALUE;
 	  break;
 
       case HTTP_NOT_IMPLEMENTED :
-          last_error = IPP_OPERATION_NOT_SUPPORTED;
+          cg->last_error = IPP_OPERATION_NOT_SUPPORTED;
 	  break;
 
       case HTTP_NOT_SUPPORTED :
-          last_error = IPP_VERSION_NOT_SUPPORTED;
+          cg->last_error = IPP_VERSION_NOT_SUPPORTED;
 	  break;
 
       default :
 	  DEBUG_printf(("HTTP error %d mapped to IPP_SERVICE_UNAVAILABLE!\n",
                 	status));
-	  last_error = IPP_SERVICE_UNAVAILABLE;
+	  cg->last_error = IPP_SERVICE_UNAVAILABLE;
 	  break;
     }
   }
@@ -509,11 +508,12 @@
   ipp_attribute_t *attr;		/* Current attribute */
   cups_lang_t	*language;		/* Default language */
   char		**temp;			/* Temporary pointer */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
 
 
   if (classes == NULL)
   {
-    last_error = IPP_INTERNAL_ERROR;
+    cg->last_error = IPP_INTERNAL_ERROR;
     return (0);
   }
 
@@ -524,7 +524,7 @@
   if (!cups_connect("default", NULL, NULL))
   {
     DEBUG_puts("Unable to connect to server!");
-    last_error = IPP_SERVICE_UNAVAILABLE;
+    cg->last_error = IPP_SERVICE_UNAVAILABLE;
     return (0);
   }
 
@@ -562,9 +562,9 @@
   n        = 0;
   *classes = NULL;
 
-  if ((response = cupsDoRequest(cups_server, request, "/")) != NULL)
+  if ((response = cupsDoRequest(cg->http, request, "/")) != NULL)
   {
-    last_error = response->request.status.status_code;
+    cg->last_error = response->request.status.status_code;
 
     for (attr = response->attrs; attr != NULL; attr = attr->next)
       if (attr->name != NULL &&
@@ -601,7 +601,7 @@
     ippDelete(response);
   }
   else
-    last_error = IPP_BAD_REQUEST;
+    cg->last_error = IPP_BAD_REQUEST;
 
   return (n);
 }
@@ -615,6 +615,7 @@
 cupsGetDefault(void)
 {
   const char	*var;			/* Environment variable */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
 
 
  /*
@@ -636,7 +637,7 @@
   if (!cups_connect("default", NULL, NULL))
   {
     DEBUG_puts("Unable to connect to server!");
-    last_error = IPP_SERVICE_UNAVAILABLE;
+    cg->last_error = IPP_SERVICE_UNAVAILABLE;
     return (NULL);
   }
 
@@ -644,7 +645,7 @@
   * Return the default printer...
   */
 
-  return (cupsGetDefault2(cups_server));
+  return (cupsGetDefault2(cg->http));
 }
 
 
@@ -660,7 +661,7 @@
   ipp_attribute_t *attr;		/* Current attribute */
   cups_lang_t	*language;		/* Default language */
   const char	*var;			/* Environment variable */
-  static char	def_printer[256];	/* Default printer */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
 
 
  /*
@@ -711,19 +712,19 @@
 
   if ((response = cupsDoRequest(http, request, "/")) != NULL)
   {
-    last_error = response->request.status.status_code;
+    cg->last_error = response->request.status.status_code;
 
     if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL)
     {
-      strlcpy(def_printer, attr->values[0].string.text, sizeof(def_printer));
+      strlcpy(cg->def_printer, attr->values[0].string.text, sizeof(cg->def_printer));
       ippDelete(response);
-      return (def_printer);
+      return (cg->def_printer);
     }
 
     ippDelete(response);
   }
   else
-    last_error = IPP_BAD_REQUEST;
+    cg->last_error = IPP_BAD_REQUEST;
 
   return (NULL);
 }
@@ -739,6 +740,8 @@
             int        myjobs,		/* I - Only show my jobs? */
 	    int        completed)	/* I - Only show completed jobs? */
 {
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
+
  /*
   * Try to connect to the server...
   */
@@ -746,7 +749,7 @@
   if (!cups_connect("default", NULL, NULL))
   {
     DEBUG_puts("Unable to connect to server!");
-    last_error = IPP_SERVICE_UNAVAILABLE;
+    cg->last_error = IPP_SERVICE_UNAVAILABLE;
     return (-1);
   }
 
@@ -754,7 +757,7 @@
   * Return the jobs...
   */
 
-  return (cupsGetJobs2(cups_server, jobs, mydest, myjobs, completed));
+  return (cupsGetJobs2(cg->http, jobs, mydest, myjobs, completed));
 }
 
 
@@ -788,6 +791,7 @@
 		*title,			/* job-name */
 		*user;			/* job-originating-user-name */
   char		uri[HTTP_MAX_URI];	/* URI for jobs */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
   static const char * const attrs[] =	/* Requested attributes */
 		{
 		  "job-id",
@@ -806,7 +810,7 @@
 
   if (!http || !jobs)
   {
-    last_error = IPP_INTERNAL_ERROR;
+    cg->last_error = IPP_INTERNAL_ERROR;
     return (-1);
   }
 
@@ -869,7 +873,7 @@
 
   if ((response = cupsDoRequest(http, request, "/")) != NULL)
   {
-    last_error = response->request.status.status_code;
+    cg->last_error = response->request.status.status_code;
 
     for (attr = response->attrs; attr != NULL; attr = attr->next)
     {
@@ -1003,9 +1007,9 @@
     ippDelete(response);
   }
   else
-    last_error = IPP_BAD_REQUEST;
+    cg->last_error = IPP_BAD_REQUEST;
 
-  if (n == 0 && last_error >= IPP_BAD_REQUEST)
+  if (n == 0 && cg->last_error >= IPP_BAD_REQUEST)
     return (-1);
   else
     return (n);
@@ -1019,6 +1023,8 @@
 const char *				/* O - Filename for PPD file */
 cupsGetPPD(const char *name)		/* I - Printer name */
 {
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
+
  /*
   * See if we can connect to the server...
   */
@@ -1026,7 +1032,7 @@
   if (!cups_connect(name, NULL, NULL))
   {
     DEBUG_puts("Unable to connect to server!");
-    last_error = IPP_SERVICE_UNAVAILABLE;
+    cg->last_error = IPP_SERVICE_UNAVAILABLE;
     return (NULL);
   }
 
@@ -1034,7 +1040,7 @@
   * Return the PPD file...
   */
 
-  return (cupsGetPPD2(cups_server, name));
+  return (cupsGetPPD2(cg->http, name));
 }
 
 
@@ -1061,7 +1067,7 @@
 		resource[HTTP_MAX_URI];	/* Resource name */
   int		port;			/* Port number */
   http_status_t	status;			/* HTTP status from server */
-  static char	filename[HTTP_MAX_URI];	/* Local filename */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
   static const char * const requested_attrs[] =
 		{			/* Requested attributes */
 		  "printer-uri-supported",
@@ -1079,7 +1085,7 @@
 
   if (!http || !name)
   {
-    last_error = IPP_INTERNAL_ERROR;
+    cg->last_error = IPP_INTERNAL_ERROR;
     return (NULL);
   }
 
@@ -1125,7 +1131,7 @@
 
   if ((response = cupsDoRequest(http, request, "/")) != NULL)
   {
-    last_error  = response->request.status.status_code;
+    cg->last_error  = response->request.status.status_code;
     printer[0]  = '\0';
     hostname[0] = '\0';
 
@@ -1176,7 +1182,7 @@
 
   if (!printer[0])
   {
-    last_error = IPP_NOT_FOUND;
+    cg->last_error = IPP_NOT_FOUND;
     return (NULL);
   }
 
@@ -1190,7 +1196,7 @@
                                        cupsEncryption())) == NULL)
   {
     DEBUG_puts("Unable to connect to server!");
-    last_error = IPP_SERVICE_UNAVAILABLE;
+    cg->last_error = IPP_SERVICE_UNAVAILABLE;
     return (NULL);
   }
 
@@ -1198,13 +1204,13 @@
   * Get a temp file...
   */
 
-  if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
+  if ((fd = cupsTempFd(cg->ppd_filename, sizeof(cg->ppd_filename))) < 0)
   {
    /*
     * Can't open file; close the server connection and return NULL...
     */
 
-    last_error = IPP_INTERNAL_ERROR;
+    cg->last_error = IPP_INTERNAL_ERROR;
 
     if (http2 != http)
       httpClose(http2);
@@ -1234,21 +1240,21 @@
     switch (status)
     {
       case HTTP_NOT_FOUND :
-          last_error = IPP_NOT_FOUND;
+          cg->last_error = IPP_NOT_FOUND;
 	  break;
       case HTTP_ERROR :
           DEBUG_puts("Mapping HTTP error to IPP_ERROR");
-          last_error = IPP_ERROR;
+          cg->last_error = IPP_ERROR;
 	  break;
       case HTTP_UNAUTHORIZED :
-          last_error = IPP_NOT_AUTHORIZED;
+          cg->last_error = IPP_NOT_AUTHORIZED;
 	  break;
       default :
-          last_error = IPP_INTERNAL_ERROR;
+          cg->last_error = IPP_INTERNAL_ERROR;
 	  break;
     }
 
-    unlink(filename);
+    unlink(cg->ppd_filename);
 
     return (NULL);
   }
@@ -1257,7 +1263,7 @@
   * Return the PPD file...
   */
 
-  return (filename);
+  return (cg->ppd_filename);
 }
 
 
@@ -1274,11 +1280,12 @@
   ipp_attribute_t *attr;		/* Current attribute */
   cups_lang_t	*language;		/* Default language */
   char		**temp;			/* Temporary pointer */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
 
 
   if (printers == NULL)
   {
-    last_error = IPP_INTERNAL_ERROR;
+    cg->last_error = IPP_INTERNAL_ERROR;
     return (0);
   }
 
@@ -1289,7 +1296,7 @@
   if (!cups_connect("default", NULL, NULL))
   {
     DEBUG_puts("Unable to connect to server!");
-    last_error = IPP_SERVICE_UNAVAILABLE;
+    cg->last_error = IPP_SERVICE_UNAVAILABLE;
     return (0);
   }
 
@@ -1327,9 +1334,9 @@
   n         = 0;
   *printers = NULL;
 
-  if ((response = cupsDoRequest(cups_server, request, "/")) != NULL)
+  if ((response = cupsDoRequest(cg->http, request, "/")) != NULL)
   {
-    last_error = response->request.status.status_code;
+    cg->last_error = response->request.status.status_code;
 
     for (attr = response->attrs; attr != NULL; attr = attr->next)
       if (attr->name != NULL &&
@@ -1366,7 +1373,7 @@
     ippDelete(response);
   }
   else
-    last_error = IPP_BAD_REQUEST;
+    cg->last_error = IPP_BAD_REQUEST;
 
   return (n);
 }
@@ -1379,9 +1386,10 @@
 ipp_status_t				/* O - IPP error code */
 cupsLastError(void)
 {
-  return (last_error);
+  return (_cups_globals()->last_error);
 }
 
+
 /*
  * 'cupsPrintFile()' - Print a file to a printer or class.
  */
@@ -1435,6 +1443,8 @@
 					/* I - Number of options */
 	       cups_option_t *options)	/* I - Options */
 {
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
+
   DEBUG_printf(("cupsPrintFiles(name=\"%s\", num_files=%d, "
                 "files=%p, title=\"%s\", num_options=%d, options=%p)\n",
                 name, num_files, files, title, num_options, options));
@@ -1449,7 +1459,7 @@
     DEBUG_printf(("cupsPrintFiles: Unable to open connection - %s.\n",
                   strerror(errno)));
     DEBUG_puts("Unable to connect to server!");
-    last_error = IPP_SERVICE_UNAVAILABLE;
+    cg->last_error = IPP_SERVICE_UNAVAILABLE;
     return (0);
   }
 
@@ -1457,7 +1467,7 @@
   * Print the file(s)...
   */
 
-  return (cupsPrintFiles2(cups_server, name, num_files, files, title,
+  return (cupsPrintFiles2(cg->http, name, num_files, files, title,
                           num_options, options));
 }
 
@@ -1485,6 +1495,7 @@
   char		uri[HTTP_MAX_URI];	/* Printer URI */
   cups_lang_t	*language;		/* Language to use */
   int		jobid;			/* New job ID */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
 
 
   DEBUG_printf(("cupsPrintFiles(http=%p, name=\"%s\", num_files=%d, "
@@ -1565,7 +1576,7 @@
   {
     DEBUG_puts("No job ID!");
 
-    last_error = IPP_SERVICE_UNAVAILABLE;
+    cg->last_error = IPP_SERVICE_UNAVAILABLE;
 
     jobid = 0;
   }
@@ -1657,13 +1668,14 @@
              char       *hostname)	/* O - Hostname [HTTP_MAX_URI] */
 {
   char	hostbuf[HTTP_MAX_URI];		/* Name of host */
+  cups_globals_t  *cg = _cups_globals();	/* Pointer to library globals */
 
 
   DEBUG_printf(("cups_connect(\"%s\", %p, %p)\n", name, printer, hostname));
 
   if (name == NULL)
   {
-    last_error = IPP_BAD_REQUEST;
+    cg->last_error = IPP_BAD_REQUEST;
     return (NULL);
   }
 
@@ -1685,21 +1697,21 @@
   else
     printer = (char *)name;
 
-  if (cups_server != NULL)
+  if (cg->http != NULL)
   {
-    if (strcasecmp(cups_server->hostname, hostname) == 0)
+    if (strcasecmp(cg->http->hostname, hostname) == 0)
       return (printer);
 
-    httpClose(cups_server);
+    httpClose(cg->http);
   }
 
   DEBUG_printf(("connecting to %s on port %d...\n", hostname, ippPort()));
 
-  if ((cups_server = httpConnectEncrypt(hostname, ippPort(),
+  if ((cg->http = httpConnectEncrypt(hostname, ippPort(),
                                         cupsEncryption())) == NULL)
   {
     DEBUG_puts("Unable to connect to server!");
-    last_error = IPP_SERVICE_UNAVAILABLE;
+    cg->last_error = IPP_SERVICE_UNAVAILABLE;
     return (NULL);
   }
   else
Index: cups/http.c
===================================================================
--- cups/http.c	(revision 4677)
+++ cups/http.c	(working copy)
@@ -92,6 +92,7 @@
 
 #include "http.h"
 #include "debug.h"
+#include "globals.h"
 
 #ifndef WIN32
 #  include <signal.h>
@@ -703,10 +704,9 @@
 const char *				/* O - Date/time string */
 httpGetDateString(time_t t)		/* I - UNIX time */
 {
-  static char	datetime[256];		/* Date/time string */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
 
-
-  return (httpGetDateString2(t, datetime, sizeof(datetime)));
+  return (httpGetDateString2(t, cg->datetime, sizeof(cg->datetime)));
 }
 
 
Index: cups/language.c
===================================================================
--- cups/language.c	(revision 4677)
+++ cups/language.c	(working copy)
@@ -54,6 +54,7 @@
 #else
 #  include <unistd.h>
 #endif /* WIN32 */
+#include "globals.h"
 
 
 /*
@@ -73,9 +74,7 @@
  * Local globals...
  */
 
-static cups_lang_t	*lang_cache = NULL;
-					/* Language string cache */
-static const char	*lang_blank = "";
+static const char	lang_blank[] = "";
 					/* Blank constant string */
 static const char * const lang_encodings[] =
 			{		/* Encoding strings */
@@ -195,13 +194,14 @@
   int		i;			/* Looping var */
   cups_lang_t	*lang,			/* Current language */
 		*next;			/* Next language */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
 
 
  /*
   * Free all languages in the cache...
   */
 
-  for (lang = lang_cache; lang != NULL; lang = next)
+  for (lang = cg->lang_cache; lang != NULL; lang = next)
   {
    /*
     * Free all messages...
@@ -219,7 +219,7 @@
     free(lang);
   }
 
-  lang_cache = NULL;
+  cg->lang_cache = NULL;
 }
 
 
@@ -263,6 +263,8 @@
   char			*text;		/* Message text */
   cups_lang_t		*lang;		/* Current language... */
   char			*oldlocale;	/* Old locale name */
+  cups_globals_t	*cg = _cups_globals();
+  					/* Pointer to library globals */
   static const char * const locale_encodings[] =
 		{			/* Locale charset names */
 		  "ASCII",	"ISO88591",	"ISO88592",	"ISO88593",
@@ -406,6 +408,8 @@
 
 #if defined(__APPLE__)
   /* The ctype bug isn't in Apple's libc */
+  (void)locale;			/* anti-compiler-warning-code */
+  (void)oldlocale;		/* anti-compiler-warning-code */
 #elif !defined(LC_CTYPE)
   oldlocale = _cupsSaveLocale(LC_ALL, "C");
 #else
@@ -602,7 +606,7 @@
   * record...
   */
 
-  for (lang = lang_cache; lang != NULL; lang = lang->next)
+  for (lang = cg->lang_cache; lang != NULL; lang = lang->next)
     if (lang->used == 0)
       break;
 
@@ -618,8 +622,8 @@
       return (NULL);
     }
 
-    lang->next = lang_cache;
-    lang_cache = lang;
+    lang->next = cg->lang_cache;
+    cg->lang_cache = lang;
   }
 
  /*
@@ -803,15 +807,15 @@
 					/* List of localization data */
   CFStringRef		languageName;	/* Current name */
   CFStringRef		localeName;	/* Canonical from of name */
-  static char		language[32] = "";
-					/* Cached language */
+  cups_globals_t	*cg = _cups_globals();
+  					/* Pointer to library globals */
 
 
  /*
   * Only do the lookup and translation the first time.
   */
 
-  if (!language[0])
+  if (!cg->apple_language[0])
   {
     localizationList =
         CFPreferencesCopyAppValue(CFSTR("AppleLanguages"),
@@ -832,14 +836,14 @@
 
 	  if (localeName != NULL)
 	  {
-	    CFStringGetCString(localeName, language, sizeof(language),
+	    CFStringGetCString(localeName, cg->apple_language, sizeof(cg->apple_language),
 			       kCFStringEncodingASCII);
 	    CFRelease(localeName);
 
-	    if (!strcmp(language, "en"))
-	      strlcpy(language, "en_US.UTF-8", sizeof(language));
-	    else if (strchr(language, '.') == NULL)
-	      strlcat(language, ".UTF-8", sizeof(language));
+	    if (!strcmp(cg->apple_language, "en"))
+	      strlcpy(cg->apple_language, "en_US.UTF-8", sizeof(cg->apple_language));
+	    else if (strchr(cg->apple_language, '.') == NULL)
+	      strlcat(cg->apple_language, ".UTF-8", sizeof(cg->apple_language));
 	  }
         }
       }
@@ -851,15 +855,15 @@
     * If we didn't find the language, default to en_US...
     */
 
-    if (!language[0])
-      strlcpy(language, "en_US.UTF-8", sizeof(language));
+    if (!cg->apple_language[0])
+      strlcpy(cg->apple_language, "en_US.UTF-8", sizeof(cg->apple_language));
   }
 
  /*
   * Return the cached locale...
   */
 
-  return (language);
+  return (cg->apple_language);
 }
 #  else
 /*
@@ -950,15 +954,15 @@
   CFStringRef		localizationName;
 					/* Current name */
   char			buff[256];	/* Temporary buffer */
-  static const char	*language = NULL;
-					/* Cached language */
+  cups_globals_t	*cg = _cups_globals();
+  					/* Pointer to library globals */
 
 
  /*
   * Only do the lookup and translation the first time.
   */
 
-  if (language == NULL)
+  if (cg->apple_language == NULL)
   {
     localizationList =
         CFPreferencesCopyAppValue(CFSTR("AppleLanguages"),
@@ -988,7 +992,7 @@
 	    {
 	      if (strcasecmp(buff, apple_name_locale[i].name) == 0)
 	      {
-		language = apple_name_locale[i].locale;
+		cg->apple_language = apple_name_locale[i].locale;
 		break;
 	      }
 	    }
@@ -1003,15 +1007,15 @@
     * If we didn't find the language, default to en_US...
     */
 
-    if (language == NULL)
-      language = apple_name_locale[0].locale;
+    if (cg->apple_language == NULL)
+      cg->apple_language = apple_name_locale[0].locale;
   }
 
  /*
   * Return the cached locale...
   */
 
-  return (language);
+  return (cg->apple_language);
 }
 #  endif /* HAVE_CF_LOCALE_ID */
 #endif /* __APPLE__ */
@@ -1037,7 +1041,7 @@
   * Loop through the cache and return a match if found...
   */
 
-  for (lang = lang_cache; lang != NULL; lang = lang->next)
+  for (lang = _cups_globals()->lang_cache; lang != NULL; lang = lang->next)
   {
     DEBUG_printf(("cups_cache_lookup: lang=%p, language=\"%s\", encoding=%d(%s)\n",
                   lang, lang->language, lang->encoding,
Index: cups/ppd.c
===================================================================
--- cups/ppd.c	(revision 4677)
+++ cups/ppd.c	(working copy)
@@ -69,6 +69,7 @@
 #include <ctype.h>
 #include "string.h"
 #include "language.h"
+#include "globals.h"
 #include "debug.h"
 
 
@@ -95,11 +96,11 @@
 /*
  * Local globals...
  */
-
-static ppd_status_t	ppd_status = PPD_OK;
+#define	ppd_status	(_cups_globals()->ppd_status)
 					/* Status of last ppdOpen*() */
-static int		ppd_line = 0;	/* Current line number */
-static ppd_conform_t	ppd_conform = PPD_CONFORM_RELAXED;
+#define	ppd_line	(_cups_globals()->ppd_line)
+					/* Current line number */
+#define	ppd_conform	(_cups_globals()->ppd_conform)
 					/* Level of conformance required */
 
 
Index: cups/ipp.c
===================================================================
--- cups/ipp.c	(revision 4677)
+++ cups/ipp.c	(working copy)
@@ -74,6 +74,7 @@
 
 #include "ipp.h"
 #include "debug.h"
+#include "globals.h"
 #include <ctype.h>
 #include <errno.h>
 
@@ -1347,7 +1348,8 @@
 ippTimeToDate(time_t t)				/* I - UNIX time value */
 {
   struct tm		*unixdate;		/* UNIX unixdate/time info */
-  static ipp_uchar_t	date[11];		/* RFC-1903 date/time data */
+  ipp_uchar_t		*date = (_cups_globals()->date_buf);
+						/* RFC-1903 date/time data */
 
 
  /*
Index: cups/http-private.h
===================================================================
--- cups/http-private.h	(revision 4677)
+++ cups/http-private.h	(working copy)
@@ -95,6 +95,8 @@
 extern const char *hstrerror(int error);
 #  endif /* !HAVE_HSTRERROR */
 
+const char *cups_get_password(const char *prompt);
+
 #endif /* !_CUPS_HTTP_PRIVATE_H_ */
 
 /*
Index: cups/Makefile
===================================================================
--- cups/Makefile	(revision 4677)
+++ cups/Makefile	(working copy)
@@ -31,7 +31,7 @@
 #
 
 LIBOBJS	=	attr.o auth.o backchannel.o dest.o dir.o emit.o encode.o \
-		file.o getputfile.o http.o http-addr.o http-support.o \
+		file.o getputfile.o globals.o http.o http-addr.o http-support.o \
 		ipp.o ipp-support.o langprintf.o language.o mark.o \
 		md5.o md5passwd.o normalize.o options.o page.o ppd.o \
 		snprintf.o string.o tempfile.o transcode.o usersys.o util.o
Index: cups/normalize.c
===================================================================
--- cups/normalize.c	(revision 4677)
+++ cups/normalize.c	(working copy)
@@ -68,24 +68,16 @@
 #include "string.h"
 #include "transcode.h"
 #include "normalize.h"
+#include "globals.h"
 
-/*
- * Local Globals...
- */
 
-static cups_normmap_t *normmap_cache = NULL;/* Normalize Map cache */
-static cups_foldmap_t *foldmap_cache = NULL;/* Case Fold cache */
-static cups_propmap_t *propmap_cache = NULL;/* Char Prop Map Cache */
-static cups_combmap_t *combmap_cache = NULL;/* Comb Class Map Cache */
-static cups_breakmap_t *breakmap_cache = NULL;/* Line Break Map Cache */
-
 typedef struct                  /**** General Category Index Struct****/
 {
   cups_gencat_t         gencat;         /* General Category Value */
   const char            *str;           /* General Category String */
 } gencat_t;
 
-static gencat_t gencat_index[] =        /* General Category Index */
+static const gencat_t gencat_index[] =  /* General Category Index */
 {
   { CUPS_GENCAT_LU, "Lu" },     /* Letter, Uppercase */
   { CUPS_GENCAT_LL, "Ll" },     /* Letter, Lowercase */
@@ -120,7 +112,7 @@
   { 0, NULL }
 };
 
-static const char *bidicat_index[] =          /* Bidi Category Index */
+static const char * const bidicat_index[] =          /* Bidi Category Index */
 {
   "L",  /* Left-to-Right (Alpha, Syllabic, Ideographic) */
   "LRE",/* Left-to-Right Embedding (explicit) */
@@ -150,7 +142,7 @@
   const char            *str;           /* Line Break Class String */
 } break_t;
 
-static break_t break_index[] =          /* Line Break Class Index */
+static const break_t break_index[] =    /* Line Break Class Index */
 {
   { CUPS_BREAK_AI, "AI" },  /* Ambiguous (Alphabetic or Ideograph) */
   { CUPS_BREAK_AL, "AL" },  /* Ordinary Alpha/Symbol Chars (XP) */
@@ -213,22 +205,24 @@
 {
   cups_normmap_t    *nmap;      /* Unicode Normalization Map */
   cups_foldmap_t    *fmap;      /* Unicode Case Folding Map */
+  cups_globals_t    *cg = _cups_globals();
+  				/* Pointer to library globals */
 
  /*
   * See if we already have normalization maps loaded...
   */
-  if (normmap_cache)
+  if (cg->normmap_cache)
   {
-    for (nmap = normmap_cache; nmap != NULL; nmap = nmap->next)
+    for (nmap = cg->normmap_cache; nmap != NULL; nmap = nmap->next)
       nmap->used ++;
-    for (fmap = foldmap_cache; fmap != NULL; fmap = fmap->next)
+    for (fmap = cg->foldmap_cache; fmap != NULL; fmap = fmap->next)
       fmap->used ++;
-    if (combmap_cache)
-      combmap_cache->used ++;
-    if (propmap_cache)
-      propmap_cache->used ++;
-    if (breakmap_cache)
-      breakmap_cache->used ++;
+    if (cg->combmap_cache)
+      cg->combmap_cache->used ++;
+    if (cg->propmap_cache)
+      cg->propmap_cache->used ++;
+    if (cg->breakmap_cache)
+      cg->breakmap_cache->used ++;
     return (0);
   }
 
@@ -268,24 +262,26 @@
 {
   cups_normmap_t    *nmap;      /* Unicode Normalization Map */
   cups_foldmap_t    *fmap;      /* Unicode Case Folding Map */
+  cups_globals_t    *cg = _cups_globals();
+  				/* Pointer to library globals */
 
  /*
   * See if we already have normalization maps loaded...
   */
-  if (normmap_cache == NULL)
+  if (cg->normmap_cache == NULL)
     return (-1);
-  for (nmap = normmap_cache; nmap != NULL; nmap = nmap->next)
+  for (nmap = cg->normmap_cache; nmap != NULL; nmap = nmap->next)
     if (nmap->used > 0)
       nmap->used --;
-  for (fmap = foldmap_cache; fmap != NULL; fmap = fmap->next)
+  for (fmap = cg->foldmap_cache; fmap != NULL; fmap = fmap->next)
     if (fmap->used > 0)
       fmap->used --;
-  if (propmap_cache && (propmap_cache->used > 0))
-    propmap_cache->used --;
-  if (combmap_cache && (combmap_cache->used > 0))
-    combmap_cache->used --;
-  if (breakmap_cache && (breakmap_cache->used > 0))
-    breakmap_cache->used --;
+  if (cg->propmap_cache && (cg->propmap_cache->used > 0))
+    cg->propmap_cache->used --;
+  if (cg->combmap_cache && (cg->combmap_cache->used > 0))
+    cg->combmap_cache->used --;
+  if (cg->breakmap_cache && (cg->breakmap_cache->used > 0))
+    cg->breakmap_cache->used --;
   return (0);
 }
 
@@ -299,41 +295,43 @@
   cups_normmap_t    *nextnorm;  /* Next Unicode Normalization Map */
   cups_foldmap_t    *fmap;      /* Unicode Case Folding Map */
   cups_foldmap_t    *nextfold;  /* Next Unicode Case Folding Map */
+  cups_globals_t    *cg = _cups_globals();
+  				/* Pointer to library globals */
 
  /*
   * Flush all normalization maps...
   */
-  for (nmap = normmap_cache; nmap != NULL; nmap = nextnorm)
+  for (nmap = cg->normmap_cache; nmap != NULL; nmap = nextnorm)
   {
     free(nmap->uni2norm);
     nextnorm = nmap->next;
     free(nmap);
   }
-  normmap_cache = NULL;
-  for (fmap = foldmap_cache; fmap != NULL; fmap = nextfold)
+  cg->normmap_cache = NULL;
+  for (fmap = cg->foldmap_cache; fmap != NULL; fmap = nextfold)
   {
     free(fmap->uni2fold);
     nextfold = fmap->next;
     free(fmap);
   }
-  foldmap_cache = NULL;
-  if (propmap_cache)
+  cg->foldmap_cache = NULL;
+  if (cg->propmap_cache)
   {
-    free(propmap_cache->uni2prop);
-    free(propmap_cache);
-    propmap_cache = NULL;
+    free(cg->propmap_cache->uni2prop);
+    free(cg->propmap_cache);
+    cg->propmap_cache = NULL;
   }
-  if (combmap_cache)
+  if (cg->combmap_cache)
   {
-    free(combmap_cache->uni2comb);
-    free(combmap_cache);
-    combmap_cache = NULL;
+    free(cg->combmap_cache->uni2comb);
+    free(cg->combmap_cache);
+    cg->combmap_cache = NULL;
   }
-  if (breakmap_cache)
+  if (cg->breakmap_cache)
   {
-    free(breakmap_cache->uni2break);
-    free(breakmap_cache);
-    breakmap_cache = NULL;
+    free(cg->breakmap_cache->uni2break);
+    free(cg->breakmap_cache);
+    cg->breakmap_cache = NULL;
   }
   return;
 }
@@ -419,6 +417,8 @@
   cups_utf32_t  *p2;            /* Second UCS-4 string pointer */
   cups_normmap_t    *nmap;      /* Unicode Normalization Map */
   cups_normalize_t  decompose;  /* Decomposition Type */
+  cups_globals_t    *cg = _cups_globals();
+  				/* Pointer to library globals */
 
  /*
   * Check for valid arguments and clear output...
@@ -449,7 +449,7 @@
     default:
       return (-1);
   }
-  for (nmap = normmap_cache; nmap != NULL; nmap = nmap->next)
+  for (nmap = cg->normmap_cache; nmap != NULL; nmap = nmap->next)
     if (nmap->normalize == decompose)
       break;
   if (nmap == NULL)
@@ -561,7 +561,7 @@
  /*
   * Find composition map...
   */
-  for (nmap = normmap_cache; nmap != NULL; nmap = nmap->next)
+  for (nmap = cg->normmap_cache; nmap != NULL; nmap = nmap->next)
     if (nmap->normalize == CUPS_NORM_NFC)
       break;
   if (nmap == NULL)
@@ -690,6 +690,8 @@
   int           result;         /* Result Value */
   cups_ucs2_t   *mp;            /* Map char pointer */
   cups_foldmap_t    *fmap;      /* Unicode Case Folding Map */
+  cups_globals_t    *cg = _cups_globals();
+  				/* Pointer to library globals */
 
  /*
   * Check for valid arguments and clear output...
@@ -709,7 +711,7 @@
   result = cupsNormalizeMapsGet();
   if (result < 0)
     return (-1);
-  for (fmap = foldmap_cache; fmap != NULL; fmap = fmap->next)
+  for (fmap = cg->foldmap_cache; fmap != NULL; fmap = fmap->next)
     if (fmap->fold == fold)
       break;
   if (fmap == NULL)
@@ -1000,6 +1002,8 @@
   cups_gencat_t     gencat;     /* General Category Value */
   cups_propmap_t    *pmap;      /* Unicode Property Map */
   cups_prop_t       *uni2prop;  /* Unicode Char -> Properties */
+  cups_globals_t    *cg = _cups_globals();
+  				/* Pointer to library globals */
 
  /*
   * Check for valid argument...
@@ -1013,7 +1017,7 @@
   result = cupsNormalizeMapsGet();
   if (result < 0)
     return (-1);
-  pmap = propmap_cache;
+  pmap = cg->propmap_cache;
   if (pmap == NULL)
     return (-1);
 
@@ -1045,6 +1049,8 @@
   cups_bidicat_t    bidicat;    /* Bidi Category Value */
   cups_propmap_t    *pmap;      /* Unicode Property Map */
   cups_prop_t       *uni2prop;  /* Unicode Char -> Properties */
+  cups_globals_t    *cg = _cups_globals();
+  				/* Pointer to library globals */
 
  /*
   * Check for valid argument...
@@ -1058,7 +1064,7 @@
   result = cupsNormalizeMapsGet();
   if (result < 0)
     return (-1);
-  pmap = propmap_cache;
+  pmap = cg->propmap_cache;
   if (pmap == NULL)
     return (-1);
 
@@ -1092,6 +1098,8 @@
   cups_combmap_t    *cmap;      /* Unicode Combining Class Map */
   cups_combclass_t  combclass;  /* Unicode Combining Class */
   cups_comb_t       *uni2comb;  /* Unicode Char -> Combining Class */
+  cups_globals_t    *cg = _cups_globals();
+  				/* Pointer to library globals */
 
  /*
   * Check for valid argument...
@@ -1105,7 +1113,7 @@
   result = cupsNormalizeMapsGet();
   if (result < 0)
     return (-1);
-  cmap = combmap_cache;
+  cmap = cg->combmap_cache;
   if (cmap == NULL)
     return (-1);
 
@@ -1136,6 +1144,8 @@
   cups_breakmap_t   *bmap;      /* Unicode Line Break Class Map */
   cups_breakclass_t breakclass; /* Unicode Line Break Class */
   cups_ucs2_t       *uni2break; /* Unicode -> Line Break Class */
+  cups_globals_t    *cg = _cups_globals();
+  				/* Pointer to library globals */
 
  /*
   * Check for valid argument...
@@ -1149,7 +1159,7 @@
   result = cupsNormalizeMapsGet();
   if (result < 0)
     return (-1);
-  bmap = breakmap_cache;
+  bmap = cg->breakmap_cache;
   if (bmap == NULL)
     return (-1);
 
@@ -1239,11 +1249,13 @@
   FILE          *fp;            /* Normalization map file pointer */
   char          *s;             /* Line parsing pointer */
   char          line[256];      /* Line from input map file */
+  cups_globals_t  *cg = _cups_globals();
+  				/* Pointer to library globals */
 
  /*
   * See if we already have this normalization map loaded...
   */
-  for (nmap = normmap_cache; nmap != NULL; nmap = nmap->next)
+  for (nmap = cg->normmap_cache; nmap != NULL; nmap = nmap->next)
     if (nmap->normalize == normalize)
       return (0);
 
@@ -1296,8 +1308,8 @@
     fclose(fp);
     return (-1);
   }
-  nmap->next = normmap_cache;
-  normmap_cache = nmap;
+  nmap->next = cg->normmap_cache;
+  cg->normmap_cache = nmap;
   nmap->used ++;
   nmap->normalize = normalize;
   nmap->normcount = normcount;
@@ -1350,11 +1362,13 @@
   FILE          *fp;            /* Case Folding map file pointer */
   char          *s;             /* Line parsing pointer */
   char          line[256];      /* Line from input map file */
+  cups_globals_t  *cg = _cups_globals();
+  				/* Pointer to library globals */
 
  /*
   * See if we already have this case folding map loaded...
   */
-  for (fmap = foldmap_cache; fmap != NULL; fmap = fmap->next)
+  for (fmap = cg->foldmap_cache; fmap != NULL; fmap = fmap->next)
     if (fmap->fold == fold)
       return (0);
 
@@ -1403,8 +1417,8 @@
     fclose(fp);
     return (-1);
   }
-  fmap->next = foldmap_cache;
-  foldmap_cache = fmap;
+  fmap->next = cg->foldmap_cache;
+  cg->foldmap_cache = fmap;
   fmap->used ++;
   fmap->fold = fold;
   fmap->foldcount = foldcount;
@@ -1465,11 +1479,13 @@
   FILE          *fp;            /* Char Property map file pointer */
   char          *s;             /* Line parsing pointer */
   char          line[256];      /* Line from input map file */
+  cups_globals_t  *cg = _cups_globals();
+  				/* Pointer to library globals */
 
  /*
   * See if we already have this char properties map loaded...
   */
-  if ((pmap = propmap_cache) != NULL)
+  if ((pmap = cg->propmap_cache) != NULL)
     return (0);
 
  /*
@@ -1507,7 +1523,7 @@
     fclose(fp);
     return (-1);
   }
-  propmap_cache = pmap;
+  cg->propmap_cache = pmap;
   pmap->used ++;
   pmap->propcount = propcount;
   pmap->uni2prop = uni2prop;
@@ -1586,11 +1602,13 @@
   FILE          *fp;            /* Comb Class map file pointer */
   char          *s;             /* Line parsing pointer */
   char          line[256];      /* Line from input map file */
+  cups_globals_t  *cg = _cups_globals();
+  				/* Pointer to library globals */
 
  /*
   * See if we already have this combining class map loaded...
   */
-  if ((cmap = combmap_cache) != NULL)
+  if ((cmap = cg->combmap_cache) != NULL)
     return (0);
 
  /*
@@ -1628,7 +1646,7 @@
     fclose(fp);
     return (-1);
   }
-  combmap_cache = cmap;
+  cg->combmap_cache = cmap;
   cmap->used ++;
   cmap->combcount = combcount;
   cmap->uni2comb = uni2comb;
@@ -1685,11 +1703,13 @@
   FILE          *fp;            /* Comb Class map file pointer */
   char          *s;             /* Line parsing pointer */
   char          line[256];      /* Line from input map file */
+  cups_globals_t  *cg = _cups_globals();
+  				/* Pointer to library globals */
 
  /*
   * See if we already have this line break class map loaded...
   */
-  if ((bmap = breakmap_cache) != NULL)
+  if ((bmap = cg->breakmap_cache) != NULL)
     return (0);
 
  /*
@@ -1727,7 +1747,7 @@
     fclose(fp);
     return (-1);
   }
-  breakmap_cache = bmap;
+  cg->breakmap_cache = bmap;
   bmap->used ++;
   bmap->breakcount = breakcount;
   bmap->uni2break = uni2break;
Index: cups/ipp-support.c
===================================================================
--- cups/ipp-support.c	(revision 4677)
+++ cups/ipp-support.c	(working copy)
@@ -44,6 +44,7 @@
 #include "language.h"
 
 #include "ipp.h"
+#include "globals.h"
 #include "debug.h"
 #include <ctype.h>
 
@@ -52,7 +53,6 @@
  * Local globals...
  */
 
-static int	ipp_port = 0;
 static const char * const ipp_status_oks[] =	/* "OK" status codes */
 		{
 		  "successful-ok",
@@ -172,7 +172,7 @@
 const char *					/* O - Text string */
 ippErrorString(ipp_status_t error)		/* I - Error status */
 {
-  static char	unknown[255];			/* Unknown error statuses */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
 
 
  /*
@@ -192,9 +192,9 @@
   * No, build an "unknown-xxxx" error string...
   */
 
-  sprintf(unknown, "unknown-%04x", error);
+  sprintf(cg->unknown, "unknown-%04x", error);
 
-  return (unknown);
+  return (cg->unknown);
 }
 
 
@@ -234,7 +234,7 @@
 const char *				/* O - Name */
 ippOpString(ipp_op_t op)		/* I - Operation ID */
 {
-  static char	unknown[255];		/* Unknown error statuses */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
 
 
  /*
@@ -252,9 +252,9 @@
   * No, build an "unknown-xxxx" operation string...
   */
 
-  sprintf(unknown, "unknown-%04x", op);
+  sprintf(cg->unknown, "unknown-%04x", op);
 
-  return (unknown);
+  return (cg->unknown);
 }
 
 
@@ -292,16 +292,17 @@
 {
   const char	*server_port;			/* SERVER_PORT environment variable */
   struct servent *port;				/* Port number info */  
+  cups_globals_t *cg = _cups_globals();		/* Pointer to library globals */
 
 
-  if (ipp_port)
-    return (ipp_port);
+  if (cg->ipp_port)
+    return (cg->ipp_port);
   else if ((server_port = getenv("IPP_PORT")) != NULL)
-    return (ipp_port = atoi(server_port));
+    return (cg->ipp_port = atoi(server_port));
   else if ((port = getservbyname("ipp", NULL)) == NULL)
-    return (ipp_port = CUPS_DEFAULT_IPP_PORT);
+    return (cg->ipp_port = CUPS_DEFAULT_IPP_PORT);
   else
-    return (ipp_port = ntohs(port->s_port));
+    return (cg->ipp_port = ntohs(port->s_port));
 }
 
 
@@ -312,7 +313,7 @@
 void
 ippSetPort(int p)				/* I - Port number to use */
 {
-  ipp_port = p;
+  _cups_globals()->ipp_port = p;
 }
 
 
Index: cups/usersys.c
===================================================================
--- cups/usersys.c	(revision 4677)
+++ cups/usersys.c	(working copy)
@@ -45,6 +45,7 @@
 #include "cups.h"
 #include "string.h"
 #include "http-private.h"
+#include "globals.h"
 #include <stdlib.h>
 
 #ifdef WIN32
@@ -56,24 +57,10 @@
  * Local functions...
  */
 
-static const char	*cups_get_password(const char *prompt);
 static char		*cups_get_line(char *buf, int buflen, FILE *fp);
 
 
 /*
- * Local globals...
- */
-
-static http_encryption_t cups_encryption = (http_encryption_t)-1;
-static char		cups_user[65] = "",
-			cups_server[256] = "";
-static const char	*(*cups_pwdcb)(const char *) = cups_get_password;
-
-#ifdef HAVE_DOMAINSOCKETS
-char			cups_server_domainsocket[104] = "";
-#endif /* HAVE_DOMAINSOCKETS */
-
-/*
  * 'cupsEncryption()' - Get the default encryption settings...
  */
 
@@ -84,13 +71,14 @@
   char		*encryption;		/* CUPS_ENCRYPTION variable */
   const char	*home;			/* Home directory of user */
   char		line[1024];		/* Line from file */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
 
 
  /*
   * First see if we have already set the encryption stuff...
   */
 
-  if (cups_encryption == (http_encryption_t)-1)
+  if (cg->cups_encryption == (http_encryption_t)-1)
   {
    /*
     * Then see if the CUPS_ENCRYPTION environment variable is set...
@@ -154,16 +142,16 @@
     */
 
     if (strcasecmp(encryption, "never") == 0)
-      cups_encryption = HTTP_ENCRYPT_NEVER;
+      cg->cups_encryption = HTTP_ENCRYPT_NEVER;
     else if (strcasecmp(encryption, "always") == 0)
-      cups_encryption = HTTP_ENCRYPT_ALWAYS;
+      cg->cups_encryption = HTTP_ENCRYPT_ALWAYS;
     else if (strcasecmp(encryption, "required") == 0)
-      cups_encryption = HTTP_ENCRYPT_REQUIRED;
+      cg->cups_encryption = HTTP_ENCRYPT_REQUIRED;
     else
-      cups_encryption = HTTP_ENCRYPT_IF_REQUESTED;
+      cg->cups_encryption = HTTP_ENCRYPT_IF_REQUESTED;
   }
 
-  return (cups_encryption);
+  return (cg->cups_encryption);
 }
 
 
@@ -174,7 +162,7 @@
 const char *				/* O - Password */
 cupsGetPassword(const char *prompt)	/* I - Prompt string */
 {
-  return ((*cups_pwdcb)(prompt));
+  return ((*_cups_globals()->cups_pwdcb)(prompt));
 }
 
 
@@ -185,7 +173,7 @@
 void
 cupsSetEncryption(http_encryption_t e)	/* I - New encryption preference */
 {
-  cups_encryption = e;
+  _cups_globals()->cups_encryption = e;
 }
 
 
@@ -201,13 +189,14 @@
   const char	*home;			/* Home directory of user */
   char		*port;			/* Port number */
   char		line[1024];		/* Line from file */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
 
 
  /*
   * First see if we have already set the server name...
   */
 
-  if (!cups_server[0])
+  if (!cg->cups_server[0])
   {
    /*
     * Then see if the CUPS_SERVER environment variable is set...
@@ -270,18 +259,26 @@
     * Copy the server name over and set the port number, if any...
     */
 
-    strlcpy(cups_server, server, sizeof(cups_server));
+    strlcpy(cg->cups_server, server, sizeof(cg->cups_server));
 
-    if (cups_server[0] != '/' && (port = strrchr(cups_server, ':')) != NULL &&
+    if (cg->cups_server[0] != '/' && (port = strrchr(cg->cups_server, ':')) != NULL &&
         isdigit(port[1] & 255))
     {
       *port++ = '\0';
 
       ippSetPort(atoi(port));
     }
+
+#ifdef AF_UNIX
+    if (cg->cups_server[0] == '/')
+    {
+      strlcpy(cg->cups_server_domainsocket, cg->cups_server, sizeof(cg->cups_server));
+      strlcpy(cg->cups_server, "localhost", sizeof(cg->cups_server));
+    }
+#endif /* AF_UNIX */
   }
 
-  return (cups_server);
+  return (cg->cups_server);
 }
 
 
@@ -292,10 +289,12 @@
 void
 cupsSetPasswordCB(const char *(*cb)(const char *))	/* I - Callback function */
 {
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
+
   if (cb == (const char *(*)(const char *))0)
-    cups_pwdcb = cups_get_password;
+    cg->cups_pwdcb = cups_get_password;
   else
-    cups_pwdcb = cb;
+    cg->cups_pwdcb = cb;
 }
 
 
@@ -306,10 +305,12 @@
 void
 cupsSetServer(const char *server)	/* I - Server name */
 {
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
+
   if (server)
-    strlcpy(cups_server, server, sizeof(cups_server));
+    strlcpy(cg->cups_server, server, sizeof(cg->cups_server));
   else
-    cups_server[0] = '\0';
+    cg->cups_server[0] = '\0';
 }
 
 
@@ -320,10 +321,12 @@
 void
 cupsSetUser(const char *user)		/* I - User name */
 {
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
+
   if (user)
-    strlcpy(cups_user, user, sizeof(cups_user));
+    strlcpy(cg->cups_user, user, sizeof(cg->cups_user));
   else
-    cups_user[0] = '\0';
+    cg->cups_user[0] = '\0';
 }
 
 
@@ -339,23 +342,25 @@
 const char *				/* O - User name */
 cupsUser(void)
 {
-  if (!cups_user[0])
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
+
+  if (!cg->cups_user[0])
   {
     DWORD	size;		/* Size of string */
 
 
-    size = sizeof(cups_user);
-    if (!GetUserName(cups_user, &size))
+    size = sizeof(cg->cups_user);
+    if (!GetUserName(cg->cups_user, &size))
     {
      /*
       * Use the default username...
       */
 
-      strcpy(cups_user, "unknown");
+      strcpy(cg->cups_user, "unknown");
     }
   }
 
-  return (cups_user);
+  return (cg->cups_user);
 }
 
 
@@ -363,7 +368,7 @@
  * 'cups_get_password()' - Get a password from the user...
  */
 
-static const char *			/* O - Password */
+const char *			/* O - Password */
 cups_get_password(const char *prompt)	/* I - Prompt string */
 {
   return (NULL);
@@ -383,9 +388,10 @@
 cupsUser(void)
 {
   struct passwd	*pwd;			/* User/password entry */
+  cups_globals_t *cg = _cups_globals();	/* Pointer to library globals */
 
 
-  if (!cups_user[0])
+  if (!cg->cups_user[0])
   {
    /*
     * Rewind the password file...
@@ -398,7 +404,7 @@
     */
 
     if ((pwd = getpwuid(getuid())) == NULL)
-      strcpy(cups_user, "unknown");	/* Unknown user! */
+      strcpy(cg->cups_user, "unknown");	/* Unknown user! */
     else
     {
      /*
@@ -407,7 +413,7 @@
 
       setpwent();
 
-      strlcpy(cups_user, pwd->pw_name, sizeof(cups_user));
+      strlcpy(cg->cups_user, pwd->pw_name, sizeof(cg->cups_user));
     }
 
    /*
@@ -417,7 +423,7 @@
     setpwent();
   }
 
-  return (cups_user);
+  return (cg->cups_user);
 }
 
 
@@ -425,7 +431,7 @@
  * 'cups_get_password()' - Get a password from the user...
  */
 
-static const char *			/* O - Password */
+const char *				/* O - Password */
 cups_get_password(const char *prompt)	/* I - Prompt string */
 {
   return (getpass(prompt));
Index: cups/transcode.c
===================================================================
--- cups/transcode.c	(revision 4677)
+++ cups/transcode.c	(working copy)
@@ -58,16 +58,10 @@
 #include "language.h"
 #include "string.h"
 #include "transcode.h"
+#include "globals.h"
 
 
 /*
- * Local Globals...
- */
-
-static cups_cmap_t      *cmap_cache = NULL;    /* SBCS Charmap Cache */
-static cups_vmap_t      *vmap_cache = NULL;    /* VBCS Charmap Cache */
-
-/*
  * Prototypes...
  */
 
@@ -150,11 +144,13 @@
 {
   cups_cmap_t   *cmap;          /* Legacy SBCS / Unicode Charset Map */
   cups_vmap_t   *vmap;          /* Legacy VBCS / Unicode Charset Map */
+  cups_globals_t *cg = _cups_globals();
+				/* Pointer to library globals */
 
  /*
   * See if we already have this SBCS charset map loaded...
   */
-  for (cmap = cmap_cache; cmap != NULL; cmap = cmap->next)
+  for (cmap = cg->cmap_cache; cmap != NULL; cmap = cmap->next)
   {
     if (cmap->encoding == encoding)
     {
@@ -167,7 +163,7 @@
  /*
   * See if we already have this DBCS/VBCS charset map loaded...
   */
-  for (vmap = vmap_cache; vmap != NULL; vmap = vmap->next)
+  for (vmap = cg->vmap_cache; vmap != NULL; vmap = vmap->next)
   {
     if (vmap->encoding == encoding)
     {
@@ -193,11 +189,13 @@
   cups_ucs2_t   *crow;          /* Pointer to UCS-2 row in 'char2uni' */
   cups_sbcs_t   *srow;          /* Pointer to SBCS row in 'uni2char' */
   cups_vbcs_t   *vrow;          /* Pointer to VBCS row in 'uni2char' */
+  cups_globals_t *cg = _cups_globals();
+  				/* Pointer to library globals */
 
  /*
   * Loop through SBCS charset map cache, free all memory...
   */
-  for (cmap = cmap_cache; cmap != NULL; cmap = cnext)
+  for (cmap = cg->cmap_cache; cmap != NULL; cmap = cnext)
   {
     for (i = 0; i < 256; i ++)
     {
@@ -207,12 +205,12 @@
     cnext = cmap->next;
     free(cmap);
   }
-  cmap_cache = NULL;
+  cg->cmap_cache = NULL;
 
  /*
   * Loop through DBCS/VBCS charset map cache, free all memory...
   */
-  for (vmap = vmap_cache; vmap != NULL; vmap = vnext)
+  for (vmap = cg->vmap_cache; vmap != NULL; vmap = vnext)
   {
     for (i = 0; i < 256; i ++)
     {
@@ -229,7 +227,7 @@
     vnext = vmap->next;
     free(vmap);
   }
-  vmap_cache = NULL;
+  cg->vmap_cache = NULL;
   return;
 }
 
@@ -880,6 +878,8 @@
   cups_ucs2_t   *crow;          /* Pointer to UCS-2 row in 'char2uni' */
   cups_sbcs_t   *srow;          /* Pointer to SBCS row in 'uni2char' */
   char          line[256];      /* Line from charset map file */
+  cups_globals_t *cg = _cups_globals();
+				/* Pointer to library globals */
 
  /*
   * Check for valid arguments...
@@ -890,7 +890,7 @@
  /*
   * See if we already have this SBCS charset map loaded...
   */
-  for (cmap = cmap_cache; cmap != NULL; cmap = cmap->next)
+  for (cmap = cg->cmap_cache; cmap != NULL; cmap = cmap->next)
   {
     if (cmap->encoding == encoding)
     {
@@ -915,8 +915,8 @@
     fclose(fp);
     return (NULL);
   }
-  cmap->next = cmap_cache;
-  cmap_cache = cmap;
+  cmap->next = cg->cmap_cache;
+  cg->cmap_cache = cmap;
   cmap->used ++;
   cmap->encoding = encoding;
 
@@ -1019,6 +1019,8 @@
   char              line[256];  /* Line from charset map file */
   int               i;          /* Loop variable */
   int               wide;       /* 32-bit legacy char */
+  cups_globals_t    *cg = _cups_globals();
+				/* Pointer to library globals */
 
  /*
   * Check for valid arguments...
@@ -1029,7 +1031,7 @@
  /*
   * See if we already have this DBCS/VBCS charset map loaded...
   */
-  for (vmap = vmap_cache; vmap != NULL; vmap = vmap->next)
+  for (vmap = cg->vmap_cache; vmap != NULL; vmap = vmap->next)
   {
     if (vmap->encoding == encoding)
     {
@@ -1061,8 +1063,8 @@
     fclose(fp);
     return (NULL);
   }
-  vmap->next = vmap_cache;
-  vmap_cache = vmap;
+  vmap->next = cg->vmap_cache;
+  cg->vmap_cache = vmap;
   vmap->used ++;
   vmap->encoding = encoding;
 
Index: cups/globals.c
===================================================================
--- cups/globals.c	(revision 0)
+++ cups/globals.c	(revision 0)
@@ -0,0 +1,124 @@
+/*
+ * "$Id$"
+ *
+ *   Global variable access routines for the Common UNIX Printing System (CUPS).
+ *
+ * Contents:
+ *
+ *   globals_init()       - One-time initializer of globals
+ *   globals_destructor() - Frees memory allocated in _cups_globals().
+ *   _cups_globals()	  - Return a pointer to thread local storage
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdlib.h>
+#include "globals.h"
+#include "http-private.h"
+
+#ifndef HAVE_PTHREAD
+
+cups_globals_t *_cups_globals(void)
+{
+  static cups_globals_t	cups_globals = { 0 };
+  static int		cups_globals_initialized = 0;
+
+  if (!cups_globals_initialized)
+  {
+    cups_globals_initialized = 1;
+
+   /*
+    * Initialize variables that have non-zero values
+    */
+
+    cups_globals.cups_encryption = (http_encryption_t)-1;
+    cups_globals.cups_pwdcb = cups_get_password;
+
+#ifdef AF_UNIX
+    strlcpy(cups_globals.cups_server_domainsocket, CUPS_DEFAULT_DOMAINSOCKET, sizeof(cups_globals.cups_server_domainsocket));
+#endif /* AF_UNIX */
+  }
+
+  return &cups_globals;
+}
+
+#else
+
+/*
+ * Globals...
+ */
+
+static pthread_key_t	globals_key = -1;/* Thread local storage key */
+static pthread_once_t	globals_key_once = PTHREAD_ONCE_INIT;
+					/* One-time initialization object */
+
+/*
+ * Local functions...
+ */
+
+static void	globals_init();
+static void	globals_destructor(void *value);
+
+
+/*
+ * 'globals_init()' - One-time initializer of globals.
+ */
+
+static
+void globals_init()
+{
+    pthread_key_create(&globals_key, globals_destructor);
+}
+
+
+/*
+ * 'globals_destructor()' - Frees memory allocated in _cups_globals().
+ */
+
+static
+void globals_destructor(void *value)
+{
+    free(value);
+}
+
+
+/*
+ * '_cups_globals()' - Return a pointer to thread local storage
+ */
+
+cups_globals_t *_cups_globals(void)
+{
+  cups_globals_t *globals;
+
+  pthread_once(&globals_key_once, globals_init);
+
+  if ((globals = (cups_globals_t *) pthread_getspecific(globals_key)) == NULL)
+  {
+    globals = calloc(1, sizeof(cups_globals_t));
+    pthread_setspecific(globals_key, globals);
+
+   /*
+    * Initialize variables that have non-zero values
+    */
+
+    globals->cups_encryption = (http_encryption_t)-1;
+    globals->cups_pwdcb = cups_get_password;
+
+#ifdef AF_UNIX
+    strlcpy(globals->cups_server_domainsocket, CUPS_DEFAULT_DOMAINSOCKET, sizeof(globals->cups_server_domainsocket));
+#endif /* AF_UNIX */
+  }
+
+  return globals;
+}
+
+#endif	/* HAVE_PTHREAD */
+
+
+
+
+/*
+ * End of "$Id$".
+ */
Index: cups/http-addr.c
===================================================================
--- cups/http-addr.c	(revision 4677)
+++ cups/http-addr.c	(working copy)
@@ -40,6 +40,7 @@
 #include "http.h"
 #include "debug.h"
 #include "string.h"
+#include "globals.h"
 #include <stdlib.h>
 
 
@@ -275,14 +276,9 @@
   int			i;		/* Looping var */
   const char		*nameptr;	/* Pointer into name */
   unsigned		ip[4];		/* IP address components */
-  static unsigned	packed_ip[100][4];/* Packed IPv4/6 addresses */
-  static char		*packed_ptr[101];/* Pointer to packed address */
-  static struct hostent	host_ip;	/* Host entry for IP/domain address */
-#ifdef HAVE_GETADDRINFO
-  static char		h_name[1024];	/* Hostname */
-#endif /* HAVE_GETADDRINFO */
+  cups_globals_t	*cg = _cups_globals();
+  					/* Pointer to library globals */
 
-
   DEBUG_printf(("httpGetHostByName(name=\"%s\")\n", name));
 
 #if defined(__APPLE__)
@@ -312,17 +308,17 @@
     * A domain socket address, so make an AF_LOCAL entry and return it...
     */
 
-    host_ip.h_name      = (char *)name;
-    host_ip.h_aliases   = NULL;
-    host_ip.h_addrtype  = AF_LOCAL;
-    host_ip.h_length    = strlen(name) + 1;
-    host_ip.h_addr_list = packed_ptr;
-    packed_ptr[0]       = (char *)name;
-    packed_ptr[1]       = NULL;
+    cg->host_ip.h_name      = (char *)name;
+    cg->host_ip.h_aliases   = NULL;
+    cg->host_ip.h_addrtype  = AF_LOCAL;
+    cg->host_ip.h_length    = strlen(name) + 1;
+    cg->host_ip.h_addr_list = cg->packed_ptr;
+    cg->packed_ptr[0]       = (char *)name;
+    cg->packed_ptr[1]       = NULL;
 
     DEBUG_puts("httpGetHostByName: returning domain socket address...");
 
-    return (&host_ip);
+    return (&cg->host_ip);
   }
 #endif /* AF_LOCAL */
 #ifdef AF_INET6
@@ -332,22 +328,22 @@
     * A raw 128-bit IPv6 address of the form "[xxxx:xxxx:xxxx:xxxx]"
     */
 
-    host_ip.h_name      = (char *)name;
-    host_ip.h_aliases   = NULL;
-    host_ip.h_addrtype  = AF_INET6;
-    host_ip.h_length    = 16;
-    host_ip.h_addr_list = packed_ptr;
-    packed_ptr[0]       = (char *)(packed_ip[0]);
-    packed_ptr[1]       = NULL;
+    cg->host_ip.h_name      = (char *)name;
+    cg->host_ip.h_aliases   = NULL;
+    cg->host_ip.h_addrtype  = AF_INET6;
+    cg->host_ip.h_length    = 16;
+    cg->host_ip.h_addr_list = cg->packed_ptr;
+    cg->packed_ptr[0]       = (char *)(cg->packed_ip[0]);
+    cg->packed_ptr[1]       = NULL;
 
     for (i = 0, nameptr = name + 1; *nameptr && i < 4; i ++)
     {
       if (*nameptr == ']')
         break;
       else if (*nameptr == ':')
-        packed_ip[0][i] = 0;
+        cg->packed_ip[0][i] = 0;
       else
-        packed_ip[0][i] = htonl(strtoul(nameptr, (char **)&nameptr, 16));
+        cg->packed_ip[0][i] = htonl(strtoul(nameptr, (char **)&nameptr, 16));
 
       if (*nameptr == ':' || *nameptr == ']')
         nameptr ++;
@@ -355,7 +351,7 @@
 
     while (i < 4)
     {
-      packed_ip[0][i] = 0;
+      cg->packed_ip[0][i] = 0;
       i ++;
     }
 
@@ -364,7 +360,7 @@
 
     DEBUG_puts("httpGetHostByName: returning IPv6 address...");
 
-    return (&host_ip);
+    return (&cg->host_ip);
   }
 #endif /* AF_INET6 */
 
@@ -383,24 +379,24 @@
     if (ip[0] > 255 || ip[1] > 255 || ip[2] > 255 || ip[3] > 255)
       return (NULL);			/* Invalid byte ranges! */
 
-    packed_ip[0][0] = htonl(((((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) |
+    cg->packed_ip[0][0] = htonl(((((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) |
                              ip[3]));
 
    /*
     * Fill in the host entry and return it...
     */
 
-    host_ip.h_name      = (char *)name;
-    host_ip.h_aliases   = NULL;
-    host_ip.h_addrtype  = AF_INET;
-    host_ip.h_length    = 4;
-    host_ip.h_addr_list = packed_ptr;
-    packed_ptr[0]       = (char *)packed_ip[0];
-    packed_ptr[1]       = NULL;
+    cg->host_ip.h_name      = (char *)name;
+    cg->host_ip.h_aliases   = NULL;
+    cg->host_ip.h_addrtype  = AF_INET;
+    cg->host_ip.h_length    = 4;
+    cg->host_ip.h_addr_list = cg->packed_ptr;
+    cg->packed_ptr[0]       = (char *)cg->packed_ip[0];
+    cg->packed_ptr[1]       = NULL;
 
     DEBUG_puts("httpGetHostByName: returning IPv4 address...");
 
-    return (&host_ip);
+    return (&cg->host_ip);
   }
   else
 #ifdef HAVE_GETADDRINFO
@@ -456,24 +452,24 @@
       }
     }
 
-    strlcpy(h_name, current->ai_canonname, sizeof(h_name));
+    strlcpy(cg->h_name, current->ai_canonname, sizeof(cg->h_name));
 
-    host_ip.h_name      = h_name;
-    host_ip.h_aliases   = NULL;
-    host_ip.h_addrtype  = current->ai_family;
-    host_ip.h_addr_list = packed_ptr;
+    cg->host_ip.h_name      = cg->h_name;
+    cg->host_ip.h_aliases   = NULL;
+    cg->host_ip.h_addrtype  = current->ai_family;
+    cg->host_ip.h_addr_list = cg->packed_ptr;
 
     if (current->ai_family == AF_INET6)
-      host_ip.h_length = 16;
+      cg->host_ip.h_length = 16;
     else
-      host_ip.h_length = 4;
+      cg->host_ip.h_length = 4;
 
    /*
     * Convert the address info to a hostent structure...
     */
 
     for (i = 0, current = results; i < 100 && current; current = current->ai_next)
-      if (current->ai_family == host_ip.h_addrtype)
+      if (current->ai_family == cg->host_ip.h_addrtype)
       {
        /*
         * Copy this address...
@@ -482,15 +478,15 @@
         address = (http_addr_t *)(current->ai_addr);
 
         if (current->ai_family == AF_INET)
-	  memcpy((char *)packed_ip[i], (char *)&(address->ipv4.sin_addr), 4);
+	  memcpy((char *)cg->packed_ip[i], (char *)&(address->ipv4.sin_addr), 4);
 	else
-	  memcpy((char *)packed_ip[i], (char *)&(address->ipv6.sin6_addr), 16);
+	  memcpy((char *)cg->packed_ip[i], (char *)&(address->ipv6.sin6_addr), 16);
 
-	packed_ptr[i] = (char *)packed_ip[i];
+	cg->packed_ptr[i] = (char *)cg->packed_ip[i];
 	i ++;
       }
 
-    packed_ptr[i] = NULL;
+    cg->packed_ptr[i] = NULL;
 
    /*
     * Free the getaddrinfo() results and return the hostent structure...
@@ -498,7 +494,7 @@
 
     freeaddrinfo(results);
 
-    return (&host_ip);
+    return (&cg->host_ip);
   }
 #else
   {
Index: cups/globals.h
===================================================================
--- cups/globals.h	(revision 0)
+++ cups/globals.h	(revision 0)
@@ -0,0 +1,128 @@
+/*
+ * "$Id$"
+ *
+ *   Global variable definitions for the Common UNIX Printing System (CUPS).
+ *
+ */
+
+#ifndef _CUPS_GLOBALS_H_
+#  define _CUPS_GLOBALS_H_
+
+/*
+ * Include necessary headers...
+ */
+
+#include "config.h"
+#include <string.h>
+#include "http.h"
+#include "ipp.h"
+#include "ppd.h"
+#include "language.h"
+#include "normalize.h"
+#include "transcode.h"
+
+#ifdef HAVE_PTHREAD
+#include <pthread.h>
+#endif
+
+/*
+ * C++ magic...
+ */
+
+#  ifdef __cplusplus
+extern "C" {
+#  endif /* __cplusplus */
+
+
+/*
+ * To make libcups thread safe define thread safe globals (aka thread specific
+ * data) for the static variables used in the library.
+ */
+
+typedef struct 
+{
+  /* util.c */
+  http_t		*http;				/* Current server connection */
+  ipp_status_t		last_error;			/* Last IPP error */
+  char			def_printer[256];		/* Default printer */
+  char			ppd_filename[HTTP_MAX_URI];	/* Local filename */
+
+  /* usersys.c */
+  http_encryption_t	cups_encryption;		/* Encryption setting */
+  char			cups_user[65],			/* User name */
+			cups_server[256];		/* Server address */
+  const char		*(*cups_pwdcb)(const char *);	/* Password callback */
+
+#ifdef AF_UNIX
+  char			cups_server_domainsocket[104];	/* Domain socket */
+#endif /* AF_UNIX */
+
+  /* tempfile.c */
+  char			*temp_fd_buf;			/* cupsTempFd buffer */
+  char			temp_file_buf[1024];		/* cupsTempFile buffer */
+
+  /* ppd.c */
+  ppd_status_t		ppd_status;			/* Status of last ppdOpen*() */
+  int			ppd_line;			/* Current line number */
+  ppd_conform_t		ppd_conform;			/* Level of conformance required */
+
+  /* language.c */
+  cups_lang_t		*lang_cache;			/* Language string cache */
+
+#ifdef HAVE_CF_LOCALE_ID
+  char			apple_language[32];		/* Cached language */
+#else
+  const char		*apple_language;		/* Cached language */
+#endif /* HAVE_CF_LOCALE_ID */
+
+  /* ipp.c */
+  ipp_uchar_t		date_buf[11];			/* RFC-1903 date/time data */
+
+  /* ipp-support.c */
+  int			ipp_port;			/* IPP port number */
+  char			unknown[255];			/* Unknown error statuses */
+
+  /* http.c */
+  char			datetime[256];			/* date time buffer */
+
+  /* http-addr.c */
+  unsigned		packed_ip[100][4];		/* Packed IPv4/6 addresses */
+  char			*packed_ptr[101];		/* Pointer to packed address */
+  struct hostent	host_ip;			/* Host entry for IP address */
+#ifdef HAVE_GETADDRINFO
+  char			h_name[1024];			/* Hostname */
+#endif /* HAVE_GETADDRINFO */
+
+  /* normalize.c */
+  cups_normmap_t	*normmap_cache;			/* Normalize Map cache */
+  cups_foldmap_t	*foldmap_cache;			/* Case Fold cache */
+  cups_propmap_t	*propmap_cache;			/* Char Prop Map Cache */
+  cups_combmap_t	*combmap_cache;			/* Comb Class Map Cache */
+  cups_breakmap_t	*breakmap_cache;		/* Line Break Map Cache */
+
+  /* transcode.c */
+  cups_cmap_t		*cmap_cache;			/* SBCS Charmap Cache */
+  cups_vmap_t		*vmap_cache;			/* VBCS Charmap Cache */
+
+} cups_globals_t;
+
+
+/*
+ * '_cups_globals()' - Return a pointer to thread safe globals
+ */
+
+extern cups_globals_t *_cups_globals(void);
+
+
+/*
+ * C++ magic...
+ */
+
+#  ifdef __cplusplus
+}
+#  endif /* __cplusplus */
+#endif /* !_CUPS_GLOBALS_H_ */
+
+/*
+ * End of "$Id$".
+ */
Index: configure.in
===================================================================
--- configure.in	(revision 4677)
+++ configure.in	(working copy)
@@ -38,6 +38,7 @@
 sinclude(config-scripts/cups-slp.m4)
 sinclude(config-scripts/cups-ssl.m4)
 sinclude(config-scripts/cups-pam.m4)
+sinclude(config-scripts/cups-pthread.m4)
 
 MAKEDEFS="../Makedefs"
 AC_SUBST(MAKEDEFS)
Index: config.h.in
===================================================================
--- config.h.in	(revision 4677)
+++ config.h.in	(working copy)
@@ -292,7 +292,13 @@
 
 #undef HAVE_USERSEC_H
 
+/*
+ * Do we have pthread support?
+ */
 
+#undef HAVE_PTHREAD
+
+
 /*
  * Various scripting languages...
  */
