/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2008, 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.
 *
 * $Id$
 *
 ***************************************************************************/

/* OS/400 additional support. */

#include "config-os400.h"       /* Not 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 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 = (buffer_t *) 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 = (buffer_t *) 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, socklen_t salen,
              char * nodename, socklen_t nodenamelen,
              char * servname, 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;
}


int
Curl_inet_ntoa_r_a(struct in_addr internet_address,
                   char * output_buffer, int output_buffer_length)

{
  int rc;
  int i;
  char * cp;

  if (!output_buffer || output_buffer_length < 16)
    return inet_ntoa_r(internet_address, output_buffer, output_buffer_length);

  if (!(cp = malloc(output_buffer_length + 1)))
    return -1;

  rc = inet_ntoa_r(internet_address, cp, output_buffer_length);

  if (rc) {
    free(cp);
    return rc;
    }

  cp[output_buffer_length - 1] = '\0';
  i = strlen(cp);
  QadrtConvertE2A(output_buffer, cp, i, i);
  output_buffer[i] = '\0';
  free(cp);
  return rc;
}


#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 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 = (char * *) 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);

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

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

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