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

/* OS/400 additional support. */

#include "curlbuild.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 USE_QSOSSL
#include <qsossl.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)

{
  localkey_t i;
  buffer_t * p;

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

    for (i = (localkey_t) 0; i < LK_LAST; i++) {
      if (p->buf)
        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);
}


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))) {
      if (enodename)
        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';
      }
    }

  if (enodename)
    free(enodename);

  if (eservname)
    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))) {
      if (enodename)
        free(enodename);

      return EAI_MEMORY;
      }

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

  status = getaddrinfo(enodename, eservname, hints, res);

  if (enodename)
    free(enodename);

  if (eservname)
    free(eservname);

  return status;
}


#ifdef USE_QSOSSL

/* ASCII wrappers for the SSL procedures. */

int
Curl_SSL_Init_Application_a(SSLInitApp * init_app)

{
  int rc;
  unsigned int i;
  SSLInitApp ia;

  if (!init_app || !init_app->applicationID || !init_app->applicationIDLen)
    return SSL_Init_Application(init_app);

  memcpy((char *) &ia, (char *) init_app, sizeof ia);
  i = ia.applicationIDLen;

  if (!(ia.applicationID = malloc(i + 1))) {
    errno = ENOMEM;
    return SSL_ERROR_IO;
    }

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


int
Curl_SSL_Init_a(SSLInit * init)

{
  int rc;
  unsigned int i;
  SSLInit ia;

  if (!init || (!init->keyringFileName && !init->keyringPassword))
    return SSL_Init(init);

  memcpy((char *) &ia, (char *) init, sizeof ia);

  if (ia.keyringFileName) {
    i = strlen(ia.keyringFileName);

    if (!(ia.keyringFileName = malloc(i + 1))) {
      errno = ENOMEM;
      return SSL_ERROR_IO;
      }

    QadrtConvertA2E(ia.keyringFileName, init->keyringFileName, i, i);
    ia.keyringFileName[i] = '\0';
    }

  if (ia.keyringPassword) {
    i = strlen(ia.keyringPassword);

    if (!(ia.keyringPassword = malloc(i + 1))) {
      if (ia.keyringFileName)
        free(ia.keyringFileName);

      errno = ENOMEM;
      return SSL_ERROR_IO;
      }

    QadrtConvertA2E(ia.keyringPassword, init->keyringPassword, i, i);
    ia.keyringPassword[i] = '\0';
    }

  rc = SSL_Init(&ia);

  if (ia.keyringFileName)
    free(ia.keyringFileName);

  if (ia.keyringPassword)
    free(ia.keyringPassword);

  return rc;
}


char *
Curl_SSL_Strerror_a(int sslreturnvalue, SSLErrorMsg * serrmsgp)

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

  cp = SSL_Strerror(sslreturnvalue, serrmsgp);

  if (!cp)
    return cp;

  i = strlen(cp);

  if (!(cp2 = Curl_thread_buffer(LK_SSL_ERROR, MAX_CONV_EXPANSION * i + 1)))
    return cp2;

  i = QadrtConvertE2A(cp2, cp, MAX_CONV_EXPANSION * i, i);
  cp2[i] = '\0';
  return cp2;
}

#endif /* 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;
};


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)

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

  cp = gsk_strerror(gsk_return_value);

  if (!cp)
    return cp;

  i = strlen(cp);

  if (!(cp2 = Curl_thread_buffer(LK_GSK_ERROR, MAX_CONV_EXPANSION * i + 1)))
    return cp2;

  i = QadrtConvertE2A(cp2, cp, MAX_CONV_EXPANSION * i, i);
  cp2[i] = '\0';
  return cp2;
}

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

  if (in.value)
    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))) {
      if (edn)
        free(edn);

      return LDAP_NO_MEMORY;
      }

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

  i = ldap_simple_bind_s(ld, edn, epasswd);

  if (epasswd)
    free(epasswd);

  if (edn)
    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);
    }

  if (efilter)
    free(efilter);

  if (ebase)
    free(ebase);

  return status;
}


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 (!(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);

  if (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)

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


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