/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2019, 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) {
    buf->buf = malloc(size);
    if(buf->buf)
      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. */

  cp = realloc(buf->buf, size);
  if(cp) {
    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. */

    bufs = calloc((size_t) LK_LAST, sizeof(*bufs));
    if(!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 = NULL;
  char *eservname = NULL;
  int status;

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

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

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

  if(!status) {
    int i;
    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);

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

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

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

    eservname = malloc(i + 1);
    if(!eservname) {
      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;
  int rc;

  if(!my_env_handle)
    return GSK_OS400_ERROR_INVALID_POINTER;
  p = (struct Curl_gsk_descriptor *) malloc(sizeof(*p));
  if(!p)
    return GSK_INSUFFICIENT_STORAGE;
  p->strlist = (struct gskstrlist *) NULL;
  rc = gsk_environment_open(&p->h);
  if(rc != 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;
  p = (struct Curl_gsk_descriptor *) malloc(sizeof(*p));
  if(!p)
    return GSK_INSUFFICIENT_STORAGE;
  p->strlist = (struct gskstrlist *) NULL;
  rc = gsk_secure_soc_open(h, &p->h);
  if(rc != 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;
  rc = gsk_environment_close(&p->h);
  if(rc == 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;
  rc = gsk_secure_soc_close(&p->h);
  if(rc == 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);
  ebcdicbuf = malloc(bufSize + 1);
  if(!ebcdicbuf)
    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) {
    sp = (struct gskstrlist *) malloc(sizeof(*sp));
    if(!sp)
      return GSK_INSUFFICIENT_STORAGE;
    asciibuf = malloc(bufsize + 1);
    if(!asciibuf) {
      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;
  rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen);
  if(rc != GSK_OK)
    return rc;
  rc = cachestring(p, mybuf, mylen, buffer);
  if(rc == 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 = buf->length;

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

  if(i) {
    char *t = malloc(i);
    if(!t) {
      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;

  in.value = malloc(i + 1);
  if(!in.value) {
    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;
  gss_buffer_desc in;
  gss_buffer_t inp;

  in.value = NULL;
  inp = input_token;

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

      in.value = malloc(i + 1);
      if(!in.value) {
        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);

  ehost = malloc(i + 1);
  if(!ehost)
    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);

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

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

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

    epasswd = malloc(i + 1);
    if(!epasswd) {
      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);

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

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

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

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

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

        eattrs[j] = malloc(i + 1);
        if(!eattrs[j]) {
          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);

    cp = malloc(i + 1);
    if(!cp) {
      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);

  cp2 = malloc(i + 1);
  if(!cp2)
    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);

  cp2 = malloc(i + 1);
  if(!cp2)
    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);

  cp2 = malloc(i + 1);
  if(!cp2)
    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
sockaddr2ebcdic(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 to 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';
    srclen = i + offsetof(struct sockaddr_un, sun_path);
    }

  return srclen;
}


static int
sockaddr2ascii(struct sockaddr *dstaddr, int dstlen,
               const struct sockaddr_storage *srcaddr, int srclen)
{
  const struct sockaddr_un *srcu;
  struct sockaddr_un *dstu;
  unsigned int dstsize;

  /* Convert a socket address to ASCII, if needed. */

  if(!srclen)
    return 0;
  if(srclen > dstlen)
    srclen = dstlen;
  if(!srcaddr || srclen < 0) {
    errno = EINVAL;
    return -1;
    }

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

  if(srclen >= offsetof(struct sockaddr_storage, ss_family) +
     sizeof(srcaddr->ss_family)) {
    switch (srcaddr->ss_family) {

    case AF_UNIX:
      srcu = (const struct sockaddr_un *) srcaddr;
      dstu = (struct sockaddr_un *) dstaddr;
      dstsize = dstlen - offsetof(struct sockaddr_un, sun_path);
      srclen -= offsetof(struct sockaddr_un, sun_path);
      if(dstsize > 0 && srclen > 0) {
        srclen = QadrtConvertE2A(dstu->sun_path, srcu->sun_path,
                                 dstsize - 1, srclen);
        dstu->sun_path[srclen] = '\0';
      }
      srclen += offsetof(struct sockaddr_un, sun_path);
    }
  }

  return srclen;
}


int
Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
{
  int i;
  struct sockaddr_storage laddr;

  i = sockaddr2ebcdic(&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 = sockaddr2ebcdic(&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 = sockaddr2ebcdic(&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 rcvlen;
  struct sockaddr_storage laddr;
  int laddrlen = sizeof(laddr);

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

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

  if(rcvlen < 0)
    return rcvlen;

  if(laddr.ss_family == AF_UNSPEC)
    laddrlen = 0;
  else {
    laddrlen = sockaddr2ascii(fromaddr, *addrlen, &laddr, laddrlen);
    if(laddrlen < 0)
      return laddrlen;
  }
  *addrlen = laddrlen;
  return rcvlen;
}


int
Curl_os400_getpeername(int sd, struct sockaddr *addr, int *addrlen)
{
  struct sockaddr_storage laddr;
  int laddrlen = sizeof(laddr);
  int retcode = getpeername(sd, (struct sockaddr *) &laddr, &laddrlen);

  if(!retcode) {
    laddrlen = sockaddr2ascii(addr, *addrlen, &laddr, laddrlen);
    if(laddrlen < 0)
      return laddrlen;
    *addrlen = laddrlen;
  }

  return retcode;
}


int
Curl_os400_getsockname(int sd, struct sockaddr *addr, int *addrlen)
{
  struct sockaddr_storage laddr;
  int laddrlen = sizeof(laddr);
  int retcode = getsockname(sd, (struct sockaddr *) &laddr, &laddrlen);

  if(!retcode) {
    laddrlen = sockaddr2ascii(addr, *addrlen, &laddr, laddrlen);
    if(laddrlen < 0)
      return laddrlen;
    *addrlen = laddrlen;
  }

  return retcode;
}


#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
