tizen 2.3.1 release
[external/curl.git] / packages / OS400 / os400sys.c
index 071fa48..caeaa95 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,7 +24,7 @@
 /* OS/400 additional support. */
 
 #include "curlbuild.h"
-#include "config-os400.h"       /* Not setup.h: we only need some defines. */
+#include "config-os400.h"  /* Not curl_setup.h: we only need some defines. */
 
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <qadrt.h>
 #include <errno.h>
 
-#ifdef USE_QSOSSL
-#include <qsossl.h>
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#ifdef USE_GSKIT
+#include <gskssl.h>
+#include <qsoasync.h>
 #endif
 
 #ifdef HAVE_GSSAPI
@@ -89,14 +94,12 @@ static void
 thdbufdestroy(void * private)
 
 {
-  localkey_t i;
-  buffer_t * p;
+  if(private) {
+    buffer_t * p = (buffer_t *) private;
+    localkey_t i;
 
-  if (private) {
-    p = (buffer_t *) private;
-
-    for (i = (localkey_t) 0; i < LK_LAST; i++) {
-      if (p->buf)
+    for(i = (localkey_t) 0; i < LK_LAST; i++) {
+      if(p->buf)
         free(p->buf);
 
       p++;
@@ -111,13 +114,13 @@ static void
 terminate(void)
 
 {
-  if (Curl_thread_buffer == buffer_threaded) {
+  if(Curl_thread_buffer == buffer_threaded) {
     locbufs = pthread_getspecific(thdkey);
     pthread_setspecific(thdkey, (void *) NULL);
     pthread_key_delete(thdkey);
     }
 
-  if (Curl_thread_buffer != buffer_undef) {
+  if(Curl_thread_buffer != buffer_undef) {
     thdbufdestroy((void *) locbufs);
     locbufs = (buffer_t *) NULL;
     }
@@ -135,31 +138,31 @@ get_buffer(buffer_t * buf, long size)
   /* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long.
      Return the buffer address. */
 
-  if (size < 0)
+  if(size < 0)
     return buf->buf;
 
-  if (!buf->buf) {
-    if ((buf->buf = malloc(size)))
+  if(!buf->buf) {
+    if((buf->buf = malloc(size)))
       buf->size = size;
 
     return buf->buf;
     }
 
-  if ((unsigned long) size <= buf->size) {
+  if((unsigned long) size <= buf->size) {
     /* Shorten the buffer only if it frees a significant byte count. This
        avoids some realloc() overhead. */
 
-    if (buf->size - size < MIN_BYTE_GAIN)
+    if(buf->size - size < MIN_BYTE_GAIN)
       return buf->buf;
     }
 
   /* Resize the buffer. */
 
-  if ((cp = realloc(buf->buf, size))) {
+  if((cp = realloc(buf->buf, size))) {
     buf->buf = cp;
     buf->size = size;
     }
-  else if (size <= buf->size)
+  else if(size <= buf->size)
     cp = buf->buf;
 
   return cp;
@@ -186,16 +189,16 @@ buffer_threaded(localkey_t key, long size)
 
   bufs = (buffer_t *) pthread_getspecific(thdkey);
 
-  if (!bufs) {
-    if (size < 0)
+  if(!bufs) {
+    if(size < 0)
       return (char *) NULL;             /* No buffer yet. */
 
     /* Allocate buffer descriptors for the current thread. */
 
-    if (!(bufs = calloc((size_t) LK_LAST, sizeof *bufs)))
+    if(!(bufs = calloc((size_t) LK_LAST, sizeof *bufs)))
       return (char *) NULL;
 
-    if (pthread_setspecific(thdkey, (void *) bufs)) {
+    if(pthread_setspecific(thdkey, (void *) bufs)) {
       free(bufs);
       return (char *) NULL;
       }
@@ -217,11 +220,10 @@ buffer_undef(localkey_t key, long size)
 
   /* Determine if we can use pthread-specific data. */
 
-  if (Curl_thread_buffer == buffer_undef) {     /* If unchanged during lock. */
-    if (!pthread_key_create(&thdkey, thdbufdestroy))
+  if(Curl_thread_buffer == buffer_undef) {      /* If unchanged during lock. */
+    if(!pthread_key_create(&thdkey, thdbufdestroy))
       Curl_thread_buffer = buffer_threaded;
-    else if (!(locbufs = calloc((size_t) LK_LAST,
-                                             sizeof *locbufs))) {
+    else if(!(locbufs = calloc((size_t) LK_LAST, sizeof *locbufs))) {
       pthread_mutex_unlock(&mutex);
       return (char *) NULL;
       }
@@ -236,6 +238,28 @@ buffer_undef(localkey_t key, long size)
 }
 
 
+static char *
+set_thread_string(localkey_t key, const char * s)
+
+{
+  int i;
+  char * cp;
+
+  if(!s)
+    return (char *) NULL;
+
+  i = strlen(s) + 1;
+  cp = Curl_thread_buffer(key, MAX_CONV_EXPANSION * i + 1);
+
+  if(cp) {
+    i = QadrtConvertE2A(cp, s, MAX_CONV_EXPANSION * i, i);
+    cp[i] = '\0';
+  }
+
+  return cp;
+}
+
+
 int
 Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
               char * nodename, curl_socklen_t nodenamelen,
@@ -251,13 +275,13 @@ Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
   enodename = (char *) NULL;
   eservname = (char *) NULL;
 
-  if (nodename && nodenamelen)
-    if (!(enodename = malloc(nodenamelen)))
+  if(nodename && nodenamelen)
+    if(!(enodename = malloc(nodenamelen)))
       return EAI_MEMORY;
 
-  if (servname && servnamelen)
-    if (!(eservname = malloc(servnamelen))) {
-      if (enodename)
+  if(servname && servnamelen)
+    if(!(eservname = malloc(servnamelen))) {
+      if(enodename)
         free(enodename);
 
       return EAI_MEMORY;
@@ -266,24 +290,24 @@ Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
   status = getnameinfo(sa, salen, enodename, nodenamelen,
                        eservname, servnamelen, flags);
 
-  if (!status) {
-    if (enodename) {
+  if(!status) {
+    if(enodename) {
       i = QadrtConvertE2A(nodename, enodename,
         nodenamelen - 1, strlen(enodename));
       nodename[i] = '\0';
       }
 
-    if (eservname) {
+    if(eservname) {
       i = QadrtConvertE2A(servname, eservname,
         servnamelen - 1, strlen(eservname));
       servname[i] = '\0';
       }
     }
 
-  if (enodename)
+  if(enodename)
     free(enodename);
 
-  if (eservname)
+  if(eservname)
     free(eservname);
 
   return status;
@@ -304,21 +328,21 @@ Curl_getaddrinfo_a(const char * nodename, const char * servname,
   enodename = (char *) NULL;
   eservname = (char *) NULL;
 
-  if (nodename) {
+  if(nodename) {
     i = strlen(nodename);
 
-    if (!(enodename = malloc(i + 1)))
+    if(!(enodename = malloc(i + 1)))
       return EAI_MEMORY;
 
     i = QadrtConvertA2E(enodename, nodename, i, i);
     enodename[i] = '\0';
     }
 
-  if (servname) {
+  if(servname) {
     i = strlen(servname);
 
-    if (!(eservname = malloc(i + 1))) {
-      if (enodename)
+    if(!(eservname = malloc(i + 1))) {
+      if(enodename)
         free(enodename);
 
       return EAI_MEMORY;
@@ -330,125 +354,404 @@ Curl_getaddrinfo_a(const char * nodename, const char * servname,
 
   status = getaddrinfo(enodename, eservname, hints, res);
 
-  if (enodename)
+  if(enodename)
     free(enodename);
 
-  if (eservname)
+  if(eservname)
     free(eservname);
 
   return status;
 }
 
 
-#ifdef USE_QSOSSL
+#ifdef USE_GSKIT
+
+/* ASCII wrappers for the GSKit procedures. */
+
+/*
+ * EBCDIC --> ASCII string mapping table.
+ * Some strings returned by GSKit are dynamically allocated and automatically
+ * released when closing the handle.
+ * To provide the same functionality, we use a "private" handle that
+ * holds the GSKit handle and a list of string mappings. This will allow
+ * avoid conversion of already converted strings and releasing them upon
+ * close time.
+ */
+
+struct gskstrlist {
+  struct gskstrlist * next;
+  const char * ebcdicstr;
+  const char * asciistr;
+};
+
+struct Curl_gsk_descriptor {
+  gsk_handle h;
+  struct gskstrlist * strlist;
+};
 
-/* ASCII wrappers for the SSL procedures. */
 
 int
-Curl_SSL_Init_Application_a(SSLInitApp * init_app)
+Curl_gsk_environment_open(gsk_handle * my_env_handle)
 
 {
+  struct Curl_gsk_descriptor * p;
+  gsk_handle h;
   int rc;
-  unsigned int i;
-  SSLInitApp ia;
 
-  if (!init_app || !init_app->applicationID || !init_app->applicationIDLen)
-    return SSL_Init_Application(init_app);
+  if(!my_env_handle)
+    return GSK_OS400_ERROR_INVALID_POINTER;
+  if(!(p = (struct Curl_gsk_descriptor *) malloc(sizeof *p)))
+    return GSK_INSUFFICIENT_STORAGE;
+  p->strlist = (struct gskstrlist *) NULL;
+  if((rc = gsk_environment_open(&p->h)) != GSK_OK)
+    free(p);
+  else
+    *my_env_handle = (gsk_handle) p;
+  return rc;
+}
 
-  memcpy((char *) &ia, (char *) init_app, sizeof ia);
-  i = ia.applicationIDLen;
 
-  if (!(ia.applicationID = malloc(i + 1))) {
-    errno = ENOMEM;
-    return SSL_ERROR_IO;
-    }
+int
+Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
+                         gsk_handle * my_session_handle)
 
-  QadrtConvertA2E(ia.applicationID, init_app->applicationID, i, i);
-  ia.applicationID[i] = '\0';
-  rc = SSL_Init_Application(&ia);
-  free(ia.applicationID);
-  init_app->localCertificateLen = ia.localCertificateLen;
-  init_app->sessionType = ia.sessionType;
+{
+  struct Curl_gsk_descriptor * p;
+  gsk_handle h;
+  int rc;
+
+  if(!my_env_handle)
+    return GSK_INVALID_HANDLE;
+  if(!my_session_handle)
+    return GSK_OS400_ERROR_INVALID_POINTER;
+  h = ((struct Curl_gsk_descriptor *) my_env_handle)->h;
+  if(!(p = (struct Curl_gsk_descriptor *) malloc(sizeof *p)))
+    return GSK_INSUFFICIENT_STORAGE;
+  p->strlist = (struct gskstrlist *) NULL;
+  if((rc = gsk_secure_soc_open(h, &p->h)) != GSK_OK)
+    free(p);
+  else
+    *my_session_handle = (gsk_handle) p;
   return rc;
 }
 
 
+static void
+gsk_free_handle(struct Curl_gsk_descriptor * p)
+
+{
+  struct gskstrlist * q;
+
+  while((q = p->strlist)) {
+    p->strlist = q;
+    free((void *) q->asciistr);
+    free(q);
+  }
+  free(p);
+}
+
+
 int
-Curl_SSL_Init_a(SSLInit * init)
+Curl_gsk_environment_close(gsk_handle * my_env_handle)
 
 {
+  struct Curl_gsk_descriptor * p;
   int rc;
-  unsigned int i;
-  SSLInit ia;
 
-  if (!init || (!init->keyringFileName && !init->keyringPassword))
-    return SSL_Init(init);
+  if(!my_env_handle)
+    return GSK_OS400_ERROR_INVALID_POINTER;
+  if(!*my_env_handle)
+    return GSK_INVALID_HANDLE;
+  p = (struct Curl_gsk_descriptor *) *my_env_handle;
+  if((rc = gsk_environment_close(&p->h)) == GSK_OK) {
+    gsk_free_handle(p);
+    *my_env_handle = (gsk_handle) NULL;
+  }
+  return rc;
+}
+
 
-  memcpy((char *) &ia, (char *) init, sizeof ia);
+int
+Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)
 
-  if (ia.keyringFileName) {
-    i = strlen(ia.keyringFileName);
+{
+  struct Curl_gsk_descriptor * p;
+  int rc;
 
-    if (!(ia.keyringFileName = malloc(i + 1))) {
-      errno = ENOMEM;
-      return SSL_ERROR_IO;
-      }
+  if(!my_session_handle)
+    return GSK_OS400_ERROR_INVALID_POINTER;
+  if(!*my_session_handle)
+    return GSK_INVALID_HANDLE;
+  p = (struct Curl_gsk_descriptor *) *my_session_handle;
+  if((rc = gsk_secure_soc_close(&p->h)) == GSK_OK) {
+    gsk_free_handle(p);
+    *my_session_handle = (gsk_handle) NULL;
+  }
+  return rc;
+}
 
-    QadrtConvertA2E(ia.keyringFileName, init->keyringFileName, i, i);
-    ia.keyringFileName[i] = '\0';
-    }
 
-  if (ia.keyringPassword) {
-    i = strlen(ia.keyringPassword);
+int
+Curl_gsk_environment_init(gsk_handle my_env_handle)
 
-    if (!(ia.keyringPassword = malloc(i + 1))) {
-      if (ia.keyringFileName)
-        free(ia.keyringFileName);
+{
+  struct Curl_gsk_descriptor * p;
 
-      errno = ENOMEM;
-      return SSL_ERROR_IO;
-      }
+  if(!my_env_handle)
+    return GSK_INVALID_HANDLE;
+  p = (struct Curl_gsk_descriptor *) my_env_handle;
+  return gsk_environment_init(p->h);
+}
 
-    QadrtConvertA2E(ia.keyringPassword, init->keyringPassword, i, i);
-    ia.keyringPassword[i] = '\0';
-    }
 
-  rc = SSL_Init(&ia);
+int
+Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
+
+{
+  struct Curl_gsk_descriptor * p;
 
-  if (ia.keyringFileName)
-    free(ia.keyringFileName);
+  if(!my_session_handle)
+    return GSK_INVALID_HANDLE;
+  p = (struct Curl_gsk_descriptor *) my_session_handle;
+  return gsk_secure_soc_init(p->h);
+}
 
-  if (ia.keyringPassword)
-    free(ia.keyringPassword);
 
+int
+Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
+                                const char * buffer, int bufSize)
+
+{
+  struct Curl_gsk_descriptor * p;
+  char * ebcdicbuf;
+  int rc;
+
+  if(!my_gsk_handle)
+    return GSK_INVALID_HANDLE;
+  if(!buffer)
+    return GSK_OS400_ERROR_INVALID_POINTER;
+  if(bufSize < 0)
+    return GSK_ATTRIBUTE_INVALID_LENGTH;
+  p = (struct Curl_gsk_descriptor *) my_gsk_handle;
+  if(!bufSize)
+    bufSize = strlen(buffer);
+  if(!(ebcdicbuf = malloc(bufSize + 1)))
+      return GSK_INSUFFICIENT_STORAGE;
+  QadrtConvertA2E(ebcdicbuf, buffer, bufSize, bufSize);
+  ebcdicbuf[bufSize] = '\0';
+  rc = gsk_attribute_set_buffer(p->h, bufID, ebcdicbuf, bufSize);
+  free(ebcdicbuf);
   return rc;
 }
 
 
-char *
-Curl_SSL_Strerror_a(int sslreturnvalue, SSLErrorMsg * serrmsgp)
+int
+Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
+                            GSK_ENUM_VALUE enumValue)
 
 {
-  int i;
-  char * cp;
-  char * cp2;
+  struct Curl_gsk_descriptor * p;
 
-  cp = SSL_Strerror(sslreturnvalue, serrmsgp);
+  if(!my_gsk_handle)
+    return GSK_INVALID_HANDLE;
+  p = (struct Curl_gsk_descriptor *) my_gsk_handle;
+  return gsk_attribute_set_enum(p->h, enumID, enumValue);
+}
 
-  if (!cp)
-    return cp;
 
-  i = strlen(cp);
+int
+Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
+                                     GSK_NUM_ID numID, int numValue)
 
-  if (!(cp2 = Curl_thread_buffer(LK_SSL_ERROR, MAX_CONV_EXPANSION * i + 1)))
-    return cp2;
+{
+  struct Curl_gsk_descriptor * p;
 
-  i = QadrtConvertE2A(cp2, cp, MAX_CONV_EXPANSION * i, i);
-  cp2[i] = '\0';
-  return cp2;
+  if(!my_gsk_handle)
+    return GSK_INVALID_HANDLE;
+  p = (struct Curl_gsk_descriptor *) my_gsk_handle;
+  return gsk_attribute_set_numeric_value(p->h, numID, numValue);
+}
+
+
+int
+Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
+                                GSK_CALLBACK_ID callBackID,
+                                void * callBackAreaPtr)
+
+{
+  struct Curl_gsk_descriptor * p;
+
+  if(!my_gsk_handle)
+    return GSK_INVALID_HANDLE;
+  p = (struct Curl_gsk_descriptor *) my_gsk_handle;
+  return gsk_attribute_set_callback(p->h, callBackID, callBackAreaPtr);
+}
+
+
+static int
+cachestring(struct Curl_gsk_descriptor * p,
+            const char * ebcdicbuf, int bufsize, const char * * buffer)
+
+{
+  int rc;
+  char * asciibuf;
+  struct gskstrlist * sp;
+
+  for(sp = p->strlist; sp; sp = sp->next)
+    if(sp->ebcdicstr == ebcdicbuf)
+      break;
+  if(!sp) {
+    if(!(sp = (struct gskstrlist *) malloc(sizeof *sp)))
+      return GSK_INSUFFICIENT_STORAGE;
+    if(!(asciibuf = malloc(bufsize + 1))) {
+      free(sp);
+      return GSK_INSUFFICIENT_STORAGE;
+    }
+    QadrtConvertE2A(asciibuf, ebcdicbuf, bufsize, bufsize);
+    asciibuf[bufsize] = '\0';
+    sp->ebcdicstr = ebcdicbuf;
+    sp->asciistr = asciibuf;
+    sp->next = p->strlist;
+    p->strlist = sp;
+  }
+  *buffer = sp->asciistr;
+  return GSK_OK;
+}
+
+
+int
+Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
+                                const char * * buffer, int * bufSize)
+
+{
+  struct Curl_gsk_descriptor * p;
+  int rc;
+  const char * mybuf;
+  int mylen;
+
+  if(!my_gsk_handle)
+    return GSK_INVALID_HANDLE;
+  if(!buffer || !bufSize)
+    return GSK_OS400_ERROR_INVALID_POINTER;
+  p = (struct Curl_gsk_descriptor *) my_gsk_handle;
+  if((rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen)) != GSK_OK)
+    return rc;
+  if((rc = cachestring(p, mybuf, mylen, buffer)) == GSK_OK)
+    *bufSize = mylen;
+  return rc;
+}
+
+
+int
+Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
+                            GSK_ENUM_VALUE * enumValue)
+
+{
+  struct Curl_gsk_descriptor * p;
+
+  if(!my_gsk_handle)
+    return GSK_INVALID_HANDLE;
+  p = (struct Curl_gsk_descriptor *) my_gsk_handle;
+  return gsk_attribute_get_enum(p->h, enumID, enumValue);
+}
+
+
+int
+Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
+                                     GSK_NUM_ID numID, int * numValue)
+
+{
+  struct Curl_gsk_descriptor * p;
+
+  if(!my_gsk_handle)
+    return GSK_INVALID_HANDLE;
+  p = (struct Curl_gsk_descriptor *) my_gsk_handle;
+  return gsk_attribute_get_numeric_value(p->h, numID, numValue);
+}
+
+
+int
+Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
+                                 GSK_CERT_ID certID,
+                                 const gsk_cert_data_elem * * certDataElem,
+                                 int * certDataElementCount)
+
+{
+  struct Curl_gsk_descriptor * p;
+
+  if(!my_gsk_handle)
+    return GSK_INVALID_HANDLE;
+  p = (struct Curl_gsk_descriptor *) my_gsk_handle;
+  /* No need to convert code: text results are already in ASCII. */
+  return gsk_attribute_get_cert_info(p->h, certID,
+                                     certDataElem, certDataElementCount);
+}
+
+
+int
+Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, GSK_MISC_ID miscID)
+
+{
+  struct Curl_gsk_descriptor * p;
+
+  if(!my_session_handle)
+    return GSK_INVALID_HANDLE;
+  p = (struct Curl_gsk_descriptor *) my_session_handle;
+  return gsk_secure_soc_misc(p->h, miscID);
+}
+
+
+int
+Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char * readBuffer,
+                         int readBufSize, int * amtRead)
+
+{
+  struct Curl_gsk_descriptor * p;
+
+  if(!my_session_handle)
+    return GSK_INVALID_HANDLE;
+  p = (struct Curl_gsk_descriptor *) my_session_handle;
+  return gsk_secure_soc_read(p->h, readBuffer, readBufSize, amtRead);
 }
 
-#endif /* USE_QSOSSL */
+
+int
+Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char * writeBuffer,
+                          int writeBufSize, int * amtWritten)
+
+{
+  struct Curl_gsk_descriptor * p;
+
+  if(!my_session_handle)
+    return GSK_INVALID_HANDLE;
+  p = (struct Curl_gsk_descriptor *) my_session_handle;
+  return gsk_secure_soc_write(p->h, writeBuffer, writeBufSize, amtWritten);
+}
+
+
+const char *
+Curl_gsk_strerror_a(int gsk_return_value)
+
+{
+  return set_thread_string(LK_GSK_ERROR, gsk_strerror(gsk_return_value));
+}
+
+int
+Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
+                              int IOCompletionPort,
+                              Qso_OverlappedIO_t * communicationsArea)
+
+{
+  struct Curl_gsk_descriptor * p;
+
+  if(!my_session_handle)
+    return GSK_INVALID_HANDLE;
+  p = (struct Curl_gsk_descriptor *) my_session_handle;
+  return gsk_secure_soc_startInit(p->h, IOCompletionPort, communicationsArea);
+}
+
+#endif /* USE_GSKIT */
+
 
 
 #ifdef HAVE_GSSAPI
@@ -467,11 +770,11 @@ Curl_gss_convert_in_place(OM_uint32 * minor_status, gss_buffer_t buf)
 
   i = buf->length;
 
-  if (i) {
-    if (!(t = malloc(i))) {
+  if(i) {
+    if(!(t = malloc(i))) {
       gss_release_buffer(minor_status, buf);
 
-      if (minor_status)
+      if(minor_status)
         *minor_status = ENOMEM;
 
       return -1;
@@ -495,14 +798,14 @@ Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
   unsigned int i;
   gss_buffer_desc in;
 
-  if (!in_name || !in_name->value || !in_name->length)
+  if(!in_name || !in_name->value || !in_name->length)
     return gss_import_name(minor_status, in_name, in_name_type, out_name);
 
   memcpy((char *) &in, (char *) in_name, sizeof in);
   i = in.length;
 
-  if (!(in.value = malloc(i + 1))) {
-    if (minor_status)
+  if(!(in.value = malloc(i + 1))) {
+    if(minor_status)
       *minor_status = ENOMEM;
 
     return GSS_S_FAILURE;
@@ -527,15 +830,15 @@ Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
   rc = gss_display_status(minor_status, status_value, status_type,
                               mech_type, message_context, status_string);
 
-  if (rc != GSS_S_COMPLETE || !status_string ||
-      !status_string->length || !status_string->value)
+  if(rc != GSS_S_COMPLETE || !status_string ||
+     !status_string->length || !status_string->value)
     return rc;
 
   /* No way to allocate a buffer here, because it will be released by
      gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
      with ASCII to return it. */
 
-  if (Curl_gss_convert_in_place(minor_status, status_string))
+  if(Curl_gss_convert_in_place(minor_status, status_string))
     return GSS_S_FAILURE;
 
   return rc;
@@ -543,7 +846,8 @@ Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
 
 
 OM_uint32
-Curl_gss_init_sec_context_a(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
+Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
+                            gss_cred_id_t cred_handle,
                             gss_ctx_id_t * context_handle,
                             gss_name_t target_name, gss_OID mech_type,
                             gss_flags_t req_flags, OM_uint32 time_req,
@@ -561,12 +865,12 @@ Curl_gss_init_sec_context_a(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
 
   in.value = NULL;
 
-  if ((inp = input_token))
-    if (inp->length && inp->value) {
+  if((inp = input_token))
+    if(inp->length && inp->value) {
       i = inp->length;
 
-      if (!(in.value = malloc(i + 1))) {
-        if (minor_status)
+      if(!(in.value = malloc(i + 1))) {
+        if(minor_status)
           *minor_status = ENOMEM;
 
         return GSS_S_FAILURE;
@@ -583,10 +887,10 @@ Curl_gss_init_sec_context_a(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
                              input_chan_bindings, inp, actual_mech_type,
                              output_token, ret_flags, time_rec);
 
-  if (in.value)
+  if(in.value)
     free(in.value);
 
-  if (rc != GSS_S_COMPLETE || !output_token ||
+  if(rc != GSS_S_COMPLETE || !output_token ||
       !output_token->length || !output_token->value)
     return rc;
 
@@ -594,7 +898,7 @@ Curl_gss_init_sec_context_a(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
      gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
      with ASCII to return it. */
 
-  if (Curl_gss_convert_in_place(minor_status, output_token))
+  if(Curl_gss_convert_in_place(minor_status, output_token))
     return GSS_S_FAILURE;
 
   return rc;
@@ -611,7 +915,7 @@ Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
 
   rc = gss_delete_sec_context(minor_status, context_handle, output_token);
 
-  if (rc != GSS_S_COMPLETE || !output_token ||
+  if(rc != GSS_S_COMPLETE || !output_token ||
       !output_token->length || !output_token->value)
     return rc;
 
@@ -619,7 +923,7 @@ Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
      gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
      with ASCII to return it. */
 
-  if (Curl_gss_convert_in_place(minor_status, output_token))
+  if(Curl_gss_convert_in_place(minor_status, output_token))
     return GSS_S_FAILURE;
 
   return rc;
@@ -640,12 +944,12 @@ Curl_ldap_init_a(char * host, int port)
   char * ehost;
   void * result;
 
-  if (!host)
+  if(!host)
     return (void *) ldap_init(host, port);
 
   i = strlen(host);
 
-  if (!(ehost = malloc(i + 1)))
+  if(!(ehost = malloc(i + 1)))
     return (void *) NULL;
 
   QadrtConvertA2E(ehost, host, i, i);
@@ -667,21 +971,21 @@ Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
   edn = (char *) NULL;
   epasswd = (char *) NULL;
 
-  if (dn) {
+  if(dn) {
     i = strlen(dn);
 
-    if (!(edn = malloc(i + 1)))
+    if(!(edn = malloc(i + 1)))
       return LDAP_NO_MEMORY;
 
     QadrtConvertA2E(edn, dn, i, i);
     edn[i] = '\0';
     }
 
-  if (passwd) {
+  if(passwd) {
     i = strlen(passwd);
 
-    if (!(epasswd = malloc(i + 1))) {
-      if (edn)
+    if(!(epasswd = malloc(i + 1))) {
+      if(edn)
         free(edn);
 
       return LDAP_NO_MEMORY;
@@ -693,10 +997,10 @@ Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
 
   i = ldap_simple_bind_s(ld, edn, epasswd);
 
-  if (epasswd)
+  if(epasswd)
     free(epasswd);
 
-  if (edn)
+  if(edn)
     free(edn);
 
   return i;
@@ -720,10 +1024,10 @@ Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
   eattrs = (char * *) NULL;
   status = LDAP_SUCCESS;
 
-  if (base) {
+  if(base) {
     i = strlen(base);
 
-    if (!(ebase = malloc(i + 1)))
+    if(!(ebase = malloc(i + 1)))
       status = LDAP_NO_MEMORY;
     else {
       QadrtConvertA2E(ebase, base, i, i);
@@ -731,10 +1035,10 @@ Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
       }
     }
 
-  if (filter && status == LDAP_SUCCESS) {
+  if(filter && status == LDAP_SUCCESS) {
     i = strlen(filter);
 
-    if (!(efilter = malloc(i + 1)))
+    if(!(efilter = malloc(i + 1)))
       status = LDAP_NO_MEMORY;
     else {
       QadrtConvertA2E(efilter, filter, i, i);
@@ -742,17 +1046,17 @@ Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
       }
     }
 
-  if (attrs && status == LDAP_SUCCESS) {
-    for (i = 0; attrs[i++];)
+  if(attrs && status == LDAP_SUCCESS) {
+    for(i = 0; attrs[i++];)
       ;
 
-    if (!(eattrs = calloc(i, sizeof *eattrs)))
+    if(!(eattrs = calloc(i, sizeof *eattrs)))
       status = LDAP_NO_MEMORY;
     else {
-      for (j = 0; attrs[j]; j++) {
+      for(j = 0; attrs[j]; j++) {
         i = strlen(attrs[j]);
 
-        if (!(eattrs[j] = malloc(i + 1))) {
+        if(!(eattrs[j] = malloc(i + 1))) {
           status = LDAP_NO_MEMORY;
           break;
           }
@@ -763,22 +1067,22 @@ Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
       }
     }
 
-  if (status == LDAP_SUCCESS)
+  if(status == LDAP_SUCCESS)
     status = ldap_search_s(ld, ebase? ebase: "", scope,
                            efilter? efilter: "(objectclass=*)",
                            eattrs, attrsonly, res);
 
-  if (eattrs) {
-    for (j = 0; eattrs[j]; j++)
+  if(eattrs) {
+    for(j = 0; eattrs[j]; j++)
       free(eattrs[j]);
 
     free(eattrs);
     }
 
-  if (efilter)
+  if(efilter)
     free(efilter);
 
-  if (ebase)
+  if(ebase)
     free(ebase);
 
   return status;
@@ -789,16 +1093,15 @@ struct berval * *
 Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
 
 {
-  int i;
   char * cp;
   struct berval * * result;
 
   cp = (char *) NULL;
 
-  if (attr) {
-    i = strlen(attr);
+  if(attr) {
+    int i = strlen(attr);
 
-    if (!(cp = malloc(i + 1))) {
+    if(!(cp = malloc(i + 1))) {
       ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
                        ldap_err2string(LDAP_NO_MEMORY));
       return (struct berval * *) NULL;
@@ -810,11 +1113,11 @@ Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
 
   result = ldap_get_values_len(ld, entry, cp);
 
-  if (cp)
+  if(cp)
     free(cp);
 
-  /* Result data are binary in nature, so they haven't been converted to EBCDIC.
-     Therefore do not convert. */
+  /* Result data are binary in nature, so they haven't been
+     converted to EBCDIC. Therefore do not convert. */
 
   return result;
 }
@@ -824,23 +1127,7 @@ char *
 Curl_ldap_err2string_a(int error)
 
 {
-  int i;
-  char * cp;
-  char * cp2;
-
-  cp = ldap_err2string(error);
-
-  if (!cp)
-    return cp;
-
-  i = strlen(cp);
-
-  if (!(cp2 = Curl_thread_buffer(LK_LDAP_ERROR, MAX_CONV_EXPANSION * i + 1)))
-    return cp2;
-
-  i = QadrtConvertE2A(cp2, cp, MAX_CONV_EXPANSION * i, i);
-  cp2[i] = '\0';
-  return cp2;
+  return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
 }
 
 
@@ -854,15 +1141,16 @@ Curl_ldap_get_dn_a(void * ld, LDAPMessage * entry)
 
   cp = ldap_get_dn(ld, entry);
 
-  if (!cp)
+  if(!cp)
     return cp;
 
   i = strlen(cp);
 
-  if (!(cp2 = malloc(i + 1)))
+  if(!(cp2 = malloc(i + 1)))
     return cp2;
 
   QadrtConvertE2A(cp2, cp, i, i);
+  cp2[i] = '\0';
 
   /* No way to allocate a buffer here, because it will be released by
      ldap_memfree() and ldap_memalloc() does not exist. The solution is to
@@ -885,15 +1173,16 @@ Curl_ldap_first_attribute_a(void * ld,
 
   cp = ldap_first_attribute(ld, entry, berptr);
 
-  if (!cp)
+  if(!cp)
     return cp;
 
   i = strlen(cp);
 
-  if (!(cp2 = malloc(i + 1)))
+  if(!(cp2 = malloc(i + 1)))
     return cp2;
 
   QadrtConvertE2A(cp2, cp, i, i);
+  cp2[i] = '\0';
 
   /* No way to allocate a buffer here, because it will be released by
      ldap_memfree() and ldap_memalloc() does not exist. The solution is to
@@ -916,15 +1205,16 @@ Curl_ldap_next_attribute_a(void * ld,
 
   cp = ldap_next_attribute(ld, entry, berptr);
 
-  if (!cp)
+  if(!cp)
     return cp;
 
   i = strlen(cp);
 
-  if (!(cp2 = malloc(i + 1)))
+  if(!(cp2 = malloc(i + 1)))
     return cp2;
 
   QadrtConvertE2A(cp2, cp, i, i);
+  cp2[i] = '\0';
 
   /* No way to allocate a buffer here, because it will be released by
      ldap_memfree() and ldap_memalloc() does not exist. The solution is to
@@ -950,8 +1240,8 @@ convert_sockaddr(struct sockaddr_storage * dstaddr,
 
   /* Convert a socket address into job CCSID, if needed. */
 
-  if (!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
-      sizeof srcaddr->sa_family || srclen > sizeof *dstaddr) {
+  if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
+     sizeof srcaddr->sa_family || srclen > sizeof *dstaddr) {
     errno = EINVAL;
     return -1;
     }
@@ -984,7 +1274,7 @@ Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
 
   i = convert_sockaddr(&laddr, destaddr, addrlen);
 
-  if (i < 0)
+  if(i < 0)
     return -1;
 
   return connect(sd, (struct sockaddr *) &laddr, i);
@@ -1000,7 +1290,7 @@ Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
 
   i = convert_sockaddr(&laddr, localaddr, addrlen);
 
-  if (i < 0)
+  if(i < 0)
     return -1;
 
   return bind(sd, (struct sockaddr *) &laddr, i);
@@ -1017,7 +1307,7 @@ Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
 
   i = convert_sockaddr(&laddr, dstaddr, addrlen);
 
-  if (i < 0)
+  if(i < 0)
     return -1;
 
   return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
@@ -1036,7 +1326,7 @@ Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
   struct sockaddr_un * dstu;
   struct sockaddr_storage laddr;
 
-  if (!fromaddr || !addrlen || *addrlen <= 0)
+  if(!fromaddr || !addrlen || *addrlen <= 0)
     return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);
 
   laddrlen = sizeof laddr;
@@ -1044,7 +1334,7 @@ Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
   rcvlen = recvfrom(sd, buffer, buflen, flags,
                     (struct sockaddr *) &laddr, &laddrlen);
 
-  if (rcvlen < 0)
+  if(rcvlen < 0)
     return rcvlen;
 
   switch (laddr.ss_family) {
@@ -1057,7 +1347,7 @@ Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
     i = QadrtConvertE2A(dstu->sun_path, srcu->sun_path, i, laddrlen);
     laddrlen = i + offsetof(struct sockaddr_un, sun_path);
 
-    if (laddrlen < *addrlen)
+    if(laddrlen < *addrlen)
       dstu->sun_path[i] = '\0';
 
     break;
@@ -1066,10 +1356,10 @@ Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
     break;
 
   default:
-    if (laddrlen > *addrlen)
+    if(laddrlen > *addrlen)
       laddrlen = *addrlen;
 
-    if (laddrlen)
+    if(laddrlen)
       memcpy((char *) fromaddr, (char *) &laddr, laddrlen);
 
     break;
@@ -1078,3 +1368,79 @@ Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
   *addrlen = laddrlen;
   return rcvlen;
 }
+
+
+#ifdef HAVE_LIBZ
+const char *
+Curl_os400_zlibVersion(void)
+
+{
+  return set_thread_string(LK_ZLIB_VERSION, zlibVersion());
+}
+
+
+int
+Curl_os400_inflateInit_(z_streamp strm, const char * version, int stream_size)
+
+{
+  z_const char * msgb4 = strm->msg;
+  int ret;
+
+  ret = inflateInit(strm);
+
+  if(strm->msg != msgb4)
+    strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
+
+  return ret;
+}
+
+
+int
+Curl_os400_inflateInit2_(z_streamp strm, int windowBits,
+                                        const char * version, int stream_size)
+
+{
+  z_const char * msgb4 = strm->msg;
+  int ret;
+
+  ret = inflateInit2(strm, windowBits);
+
+  if(strm->msg != msgb4)
+    strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
+
+  return ret;
+}
+
+
+int
+Curl_os400_inflate(z_streamp strm, int flush)
+
+{
+  z_const char * msgb4 = strm->msg;
+  int ret;
+
+  ret = inflate(strm, flush);
+
+  if(strm->msg != msgb4)
+    strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
+
+  return ret;
+}
+
+
+int
+Curl_os400_inflateEnd(z_streamp strm)
+
+{
+  z_const char * msgb4 = strm->msg;
+  int ret;
+
+  ret = inflateEnd(strm);
+
+  if(strm->msg != msgb4)
+    strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
+
+  return ret;
+}
+
+#endif