/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2017, 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
 * are also available at https://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 *
 ***************************************************************************/

/* OS/400 additional support. */

#include <curl/curl.h>
#include "config-os400.h"  /* Not curl_setup.h: we only need some defines. */

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <pthread.h>
#include <netdb.h>
#include <qadrt.h>
#include <errno.h>

#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif

#ifdef USE_GSKIT
#include <gskssl.h>
#include <qsoasync.h>
#endif

#ifdef HAVE_GSSAPI
#include <gssapi.h>
#endif

#ifndef CURL_DISABLE_LDAP
#include <ldap.h>
#endif

#include <netinet/in.h>
#include <arpa/inet.h>

#include "os400sys.h"


/**
***     QADRT OS/400 ASCII runtime defines only the most used procedures, but
***             but a lot of them are not supported. This module implements
***             ASCII wrappers for those that are used by libcurl, but not
***             defined by QADRT.
**/

#pragma convert(0)                              /* Restore EBCDIC. */


#define MIN_BYTE_GAIN   1024    /* Minimum gain when shortening a buffer. */

typedef struct {
        unsigned long   size;                   /* Buffer size. */
        char *          buf;                    /* Buffer address. */
}               buffer_t;


static char *   buffer_undef(localkey_t key, long size);
static char *   buffer_threaded(localkey_t key, long size);
static char *   buffer_unthreaded(localkey_t key, long size);

static pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_key_t    thdkey;
static buffer_t *       locbufs;

char *  (* Curl_thread_buffer)(localkey_t key, long size) = buffer_undef;


static void
thdbufdestroy(void * private)

{
  if(private) {
    buffer_t * p = (buffer_t *) private;
    localkey_t i;

    for(i = (localkey_t) 0; i < LK_LAST; i++) {
      free(p->buf);
      p++;
      }

    free(private);
    }
}


static void
terminate(void)

{
  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) {
    thdbufdestroy((void *) locbufs);
    locbufs = (buffer_t *) NULL;
    }

  Curl_thread_buffer = buffer_undef;
}


static char *
get_buffer(buffer_t * buf, long size)

{
  char * cp;

  /* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long.
     Return the buffer address. */

  if(size < 0)
    return buf->buf;

  if(!buf->buf) {
    if((buf->buf = malloc(size)))
      buf->size = size;

    return buf->buf;
    }

  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)
      return buf->buf;
    }

  /* Resize the buffer. */

  if((cp = realloc(buf->buf, size))) {
    buf->buf = cp;
    buf->size = size;
    }
  else if(size <= buf->size)
    cp = buf->buf;

  return cp;
}


static char *
buffer_unthreaded(localkey_t key, long size)

{
  return get_buffer(locbufs + key, size);
}


static char *
buffer_threaded(localkey_t key, long size)

{
  buffer_t * bufs;

  /* Get the buffer for the given local key in the current thread, and
     make sure it is at least `size'-byte long. Set `size' to < 0 to get
     its address only. */

  bufs = (buffer_t *) pthread_getspecific(thdkey);

  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)))
      return (char *) NULL;

    if(pthread_setspecific(thdkey, (void *) bufs)) {
      free(bufs);
      return (char *) NULL;
      }
    }

  return get_buffer(bufs + key, size);
}


static char *
buffer_undef(localkey_t key, long size)

{
  /* Define the buffer system, get the buffer for the given local key in
     the current thread, and make sure it is at least `size'-byte long.
     Set `size' to < 0 to get its address only. */

  pthread_mutex_lock(&mutex);

  /* Determine if we can use pthread-specific data. */

  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))) {
      pthread_mutex_unlock(&mutex);
      return (char *) NULL;
      }
    else
        Curl_thread_buffer = buffer_unthreaded;

    atexit(terminate);
    }

  pthread_mutex_unlock(&mutex);
  return Curl_thread_buffer(key, 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,
              char * servname, curl_socklen_t servnamelen,
              int flags)

{
  char * enodename;
  char * eservname;
  int status;
  int i;

  enodename = (char *) NULL;
  eservname = (char *) NULL;

  if(nodename && nodenamelen)
    if(!(enodename = malloc(nodenamelen)))
      return EAI_MEMORY;

  if(servname && servnamelen)
    if(!(eservname = malloc(servnamelen))) {
      free(enodename);
      return EAI_MEMORY;
      }

  status = getnameinfo(sa, salen, enodename, nodenamelen,
                       eservname, servnamelen, flags);

  if(!status) {
    if(enodename) {
      i = QadrtConvertE2A(nodename, enodename,
        nodenamelen - 1, strlen(enodename));
      nodename[i] = '\0';
      }

    if(eservname) {
      i = QadrtConvertE2A(servname, eservname,
        servnamelen - 1, strlen(eservname));
      servname[i] = '\0';
      }
    }

  free(enodename);
  free(eservname);
  return status;
}


int
Curl_getaddrinfo_a(const char * nodename, const char * servname,
            const struct addrinfo * hints,
            struct addrinfo * * res)

{
  char * enodename;
  char * eservname;
  int status;
  int i;

  enodename = (char *) NULL;
  eservname = (char *) NULL;

  if(nodename) {
    i = strlen(nodename);

    if(!(enodename = malloc(i + 1)))
      return EAI_MEMORY;

    i = QadrtConvertA2E(enodename, nodename, i, i);
    enodename[i] = '\0';
    }

  if(servname) {
    i = strlen(servname);

    if(!(eservname = malloc(i + 1))) {
      free(enodename);
      return EAI_MEMORY;
      }

    QadrtConvertA2E(eservname, servname, i, i);
    eservname[i] = '\0';
    }

  status = getaddrinfo(enodename, eservname, hints, res);
  free(enodename);
  free(eservname);
  return status;
}


#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;
};


int
Curl_gsk_environment_open(gsk_handle * my_env_handle)

{
  struct Curl_gsk_descriptor * p;
  gsk_handle h;
  int rc;

  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;
}


int
Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
                         gsk_handle * my_session_handle)

{
  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_gsk_environment_close(gsk_handle * my_env_handle)

{
  struct Curl_gsk_descriptor * p;
  int rc;

  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;
}


int
Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)

{
  struct Curl_gsk_descriptor * p;
  int rc;

  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;
}


int
Curl_gsk_environment_init(gsk_handle my_env_handle)

{
  struct Curl_gsk_descriptor * p;

  if(!my_env_handle)
    return GSK_INVALID_HANDLE;
  p = (struct Curl_gsk_descriptor *) my_env_handle;
  return gsk_environment_init(p->h);
}


int
Curl_gsk_secure_soc_init(gsk_handle my_session_handle)

{
  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_init(p->h);
}


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;
}


int
Curl_gsk_attribute_set_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_set_enum(p->h, enumID, enumValue);
}


int
Curl_gsk_attribute_set_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_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);
}


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

/* ASCII wrappers for the GSSAPI procedures. */

static int
Curl_gss_convert_in_place(OM_uint32 * minor_status, gss_buffer_t buf)

{
  unsigned int i;
  char * t;

  /* Convert `buf' in place, from EBCDIC to ASCII.
     If error, release the buffer and return -1. Else return 0. */

  i = buf->length;

  if(i) {
    if(!(t = malloc(i))) {
      gss_release_buffer(minor_status, buf);

      if(minor_status)
        *minor_status = ENOMEM;

      return -1;
      }

    QadrtConvertE2A(t, buf->value, i, i);
    memcpy(buf->value, t, i);
    free(t);
    }

  return 0;
}


OM_uint32
Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
                       gss_OID in_name_type, gss_name_t * out_name)

{
  int rc;
  unsigned int i;
  gss_buffer_desc in;

  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)
      *minor_status = ENOMEM;

    return GSS_S_FAILURE;
    }

  QadrtConvertA2E(in.value, in_name->value, i, i);
  ((char *) in.value)[i] = '\0';
  rc = gss_import_name(minor_status, &in, in_name_type, out_name);
  free(in.value);
  return rc;
}


OM_uint32
Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
                   int status_type, gss_OID mech_type,
                   gss_msg_ctx_t * message_context, gss_buffer_t status_string)

{
  int rc;

  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)
    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))
    return GSS_S_FAILURE;

  return rc;
}


OM_uint32
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,
                            gss_channel_bindings_t input_chan_bindings,
                            gss_buffer_t input_token,
                            gss_OID * actual_mech_type,
                            gss_buffer_t output_token, gss_flags_t * ret_flags,
                            OM_uint32 * time_rec)

{
  int rc;
  unsigned int i;
  gss_buffer_desc in;
  gss_buffer_t inp;

  in.value = NULL;

  if((inp = input_token))
    if(inp->length && inp->value) {
      i = inp->length;

      if(!(in.value = malloc(i + 1))) {
        if(minor_status)
          *minor_status = ENOMEM;

        return GSS_S_FAILURE;
        }

      QadrtConvertA2E(in.value, input_token->value, i, i);
      ((char *) in.value)[i] = '\0';
      in.length = i;
      inp = &in;
      }

  rc = gss_init_sec_context(minor_status, cred_handle, context_handle,
                             target_name, mech_type, req_flags, time_req,
                             input_chan_bindings, inp, actual_mech_type,
                             output_token, ret_flags, time_rec);
  free(in.value);

  if(rc != GSS_S_COMPLETE || !output_token ||
      !output_token->length || !output_token->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, output_token))
    return GSS_S_FAILURE;

  return rc;
}


OM_uint32
Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
                              gss_ctx_id_t * context_handle,
                              gss_buffer_t output_token)

{
  int rc;

  rc = gss_delete_sec_context(minor_status, context_handle, output_token);

  if(rc != GSS_S_COMPLETE || !output_token ||
      !output_token->length || !output_token->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, output_token))
    return GSS_S_FAILURE;

  return rc;
}

#endif /* HAVE_GSSAPI */


#ifndef CURL_DISABLE_LDAP

/* ASCII wrappers for the LDAP procedures. */

void *
Curl_ldap_init_a(char * host, int port)

{
  unsigned int i;
  char * ehost;
  void * result;

  if(!host)
    return (void *) ldap_init(host, port);

  i = strlen(host);

  if(!(ehost = malloc(i + 1)))
    return (void *) NULL;

  QadrtConvertA2E(ehost, host, i, i);
  ehost[i] = '\0';
  result = (void *) ldap_init(ehost, port);
  free(ehost);
  return result;
}


int
Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)

{
  int i;
  char * edn;
  char * epasswd;

  edn = (char *) NULL;
  epasswd = (char *) NULL;

  if(dn) {
    i = strlen(dn);

    if(!(edn = malloc(i + 1)))
      return LDAP_NO_MEMORY;

    QadrtConvertA2E(edn, dn, i, i);
    edn[i] = '\0';
    }

  if(passwd) {
    i = strlen(passwd);

    if(!(epasswd = malloc(i + 1))) {
      free(edn);
      return LDAP_NO_MEMORY;
      }

    QadrtConvertA2E(epasswd, passwd, i, i);
    epasswd[i] = '\0';
    }

  i = ldap_simple_bind_s(ld, edn, epasswd);
  free(epasswd);
  free(edn);
  return i;
}


int
Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
                     char * * attrs, int attrsonly, LDAPMessage * * res)

{
  int i;
  int j;
  char * ebase;
  char * efilter;
  char * * eattrs;
  int status;

  ebase = (char *) NULL;
  efilter = (char *) NULL;
  eattrs = (char * *) NULL;
  status = LDAP_SUCCESS;

  if(base) {
    i = strlen(base);

    if(!(ebase = malloc(i + 1)))
      status = LDAP_NO_MEMORY;
    else {
      QadrtConvertA2E(ebase, base, i, i);
      ebase[i] = '\0';
      }
    }

  if(filter && status == LDAP_SUCCESS) {
    i = strlen(filter);

    if(!(efilter = malloc(i + 1)))
      status = LDAP_NO_MEMORY;
    else {
      QadrtConvertA2E(efilter, filter, i, i);
      efilter[i] = '\0';
      }
    }

  if(attrs && status == LDAP_SUCCESS) {
    for(i = 0; attrs[i++];)
      ;

    if(!(eattrs = calloc(i, sizeof *eattrs)))
      status = LDAP_NO_MEMORY;
    else {
      for(j = 0; attrs[j]; j++) {
        i = strlen(attrs[j]);

        if(!(eattrs[j] = malloc(i + 1))) {
          status = LDAP_NO_MEMORY;
          break;
          }

        QadrtConvertA2E(eattrs[j], attrs[j], i, i);
        eattrs[j][i] = '\0';
        }
      }
    }

  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++)
      free(eattrs[j]);

    free(eattrs);
    }

  free(efilter);
  free(ebase);
  return status;
}


struct berval * *
Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)

{
  char * cp;
  struct berval * * result;

  cp = (char *) NULL;

  if(attr) {
    int i = strlen(attr);

    if(!(cp = malloc(i + 1))) {
      ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
                       ldap_err2string(LDAP_NO_MEMORY));
      return (struct berval * *) NULL;
      }

    QadrtConvertA2E(cp, attr, i, i);
    cp[i] = '\0';
    }

  result = ldap_get_values_len(ld, entry, cp);
  free(cp);

  /* Result data are binary in nature, so they haven't been
     converted to EBCDIC. Therefore do not convert. */

  return result;
}


char *
Curl_ldap_err2string_a(int error)

{
  return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
}


char *
Curl_ldap_get_dn_a(void * ld, LDAPMessage * entry)

{
  int i;
  char * cp;
  char * cp2;

  cp = ldap_get_dn(ld, entry);

  if(!cp)
    return cp;

  i = strlen(cp);

  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
     overwrite the EBCDIC buffer with ASCII to return it. */

  strcpy(cp, cp2);
  free(cp2);
  return cp;
}


char *
Curl_ldap_first_attribute_a(void * ld,
                            LDAPMessage * entry, BerElement * * berptr)

{
  int i;
  char * cp;
  char * cp2;

  cp = ldap_first_attribute(ld, entry, berptr);

  if(!cp)
    return cp;

  i = strlen(cp);

  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
     overwrite the EBCDIC buffer with ASCII to return it. */

  strcpy(cp, cp2);
  free(cp2);
  return cp;
}


char *
Curl_ldap_next_attribute_a(void * ld,
                           LDAPMessage * entry, BerElement * berptr)

{
  int i;
  char * cp;
  char * cp2;

  cp = ldap_next_attribute(ld, entry, berptr);

  if(!cp)
    return cp;

  i = strlen(cp);

  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
     overwrite the EBCDIC buffer with ASCII to return it. */

  strcpy(cp, cp2);
  free(cp2);
  return cp;
}

#endif /* CURL_DISABLE_LDAP */


static int
convert_sockaddr(struct sockaddr_storage * dstaddr,
                                const struct sockaddr * srcaddr, int srclen)

{
  const struct sockaddr_un * srcu;
  struct sockaddr_un * dstu;
  unsigned int i;
  unsigned int dstsize;

  /* Convert a socket address into job CCSID, if needed. */

  if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
     sizeof srcaddr->sa_family || srclen > sizeof *dstaddr) {
    errno = EINVAL;
    return -1;
    }

  memcpy((char *) dstaddr, (char *) srcaddr, srclen);

  switch (srcaddr->sa_family) {

  case AF_UNIX:
    srcu = (const struct sockaddr_un *) srcaddr;
    dstu = (struct sockaddr_un *) dstaddr;
    dstsize = sizeof *dstaddr - offsetof(struct sockaddr_un, sun_path);
    srclen -= offsetof(struct sockaddr_un, sun_path);
    i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen);
    dstu->sun_path[i] = '\0';
    i += offsetof(struct sockaddr_un, sun_path);
    srclen = i;
    }

  return srclen;
}


int
Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)

{
  int i;
  struct sockaddr_storage laddr;

  i = convert_sockaddr(&laddr, destaddr, addrlen);

  if(i < 0)
    return -1;

  return connect(sd, (struct sockaddr *) &laddr, i);
}


int
Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)

{
  int i;
  struct sockaddr_storage laddr;

  i = convert_sockaddr(&laddr, localaddr, addrlen);

  if(i < 0)
    return -1;

  return bind(sd, (struct sockaddr *) &laddr, i);
}


int
Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
                                struct sockaddr * dstaddr, int addrlen)

{
  int i;
  struct sockaddr_storage laddr;

  i = convert_sockaddr(&laddr, dstaddr, addrlen);

  if(i < 0)
    return -1;

  return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
}


int
Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
                                struct sockaddr * fromaddr, int * addrlen)

{
  int i;
  int rcvlen;
  int laddrlen;
  const struct sockaddr_un * srcu;
  struct sockaddr_un * dstu;
  struct sockaddr_storage laddr;

  if(!fromaddr || !addrlen || *addrlen <= 0)
    return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);

  laddrlen = sizeof laddr;
  laddr.ss_family = AF_UNSPEC;          /* To detect if unused. */
  rcvlen = recvfrom(sd, buffer, buflen, flags,
                    (struct sockaddr *) &laddr, &laddrlen);

  if(rcvlen < 0)
    return rcvlen;

  switch (laddr.ss_family) {

  case AF_UNIX:
    srcu = (const struct sockaddr_un *) &laddr;
    dstu = (struct sockaddr_un *) fromaddr;
    i = *addrlen - offsetof(struct sockaddr_un, sun_path);
    laddrlen -= offsetof(struct sockaddr_un, sun_path);
    i = QadrtConvertE2A(dstu->sun_path, srcu->sun_path, i, laddrlen);
    laddrlen = i + offsetof(struct sockaddr_un, sun_path);

    if(laddrlen < *addrlen)
      dstu->sun_path[i] = '\0';

    break;

  case AF_UNSPEC:
    break;

  default:
    if(laddrlen > *addrlen)
      laddrlen = *addrlen;

    if(laddrlen)
      memcpy((char *) fromaddr, (char *) &laddr, laddrlen);

    break;
    }

  *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
