Annotation of embedaddon/curl/packages/OS400/os400sys.c, revision 1.1.1.1

1.1       misho       1: /***************************************************************************
                      2:  *                                  _   _ ____  _
                      3:  *  Project                     ___| | | |  _ \| |
                      4:  *                             / __| | | | |_) | |
                      5:  *                            | (__| |_| |  _ <| |___
                      6:  *                             \___|\___/|_| \_\_____|
                      7:  *
                      8:  * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
                      9:  *
                     10:  * This software is licensed as described in the file COPYING, which
                     11:  * you should have received as part of this distribution. The terms
                     12:  * are also available at https://curl.haxx.se/docs/copyright.html.
                     13:  *
                     14:  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
                     15:  * copies of the Software, and permit persons to whom the Software is
                     16:  * furnished to do so, under the terms of the COPYING file.
                     17:  *
                     18:  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
                     19:  * KIND, either express or implied.
                     20:  *
                     21:  *
                     22:  ***************************************************************************/
                     23: 
                     24: /* OS/400 additional support. */
                     25: 
                     26: #include <curl/curl.h>
                     27: #include "config-os400.h"  /* Not curl_setup.h: we only need some defines. */
                     28: 
                     29: #include <sys/types.h>
                     30: #include <sys/socket.h>
                     31: #include <sys/un.h>
                     32: 
                     33: #include <stdlib.h>
                     34: #include <stddef.h>
                     35: #include <string.h>
                     36: #include <pthread.h>
                     37: #include <netdb.h>
                     38: #include <qadrt.h>
                     39: #include <errno.h>
                     40: 
                     41: #ifdef HAVE_ZLIB_H
                     42: #include <zlib.h>
                     43: #endif
                     44: 
                     45: #ifdef USE_GSKIT
                     46: #include <gskssl.h>
                     47: #include <qsoasync.h>
                     48: #endif
                     49: 
                     50: #ifdef HAVE_GSSAPI
                     51: #include <gssapi.h>
                     52: #endif
                     53: 
                     54: #ifndef CURL_DISABLE_LDAP
                     55: #include <ldap.h>
                     56: #endif
                     57: 
                     58: #include <netinet/in.h>
                     59: #include <arpa/inet.h>
                     60: 
                     61: #include "os400sys.h"
                     62: 
                     63: 
                     64: /**
                     65: ***     QADRT OS/400 ASCII runtime defines only the most used procedures, but
                     66: ***             but a lot of them are not supported. This module implements
                     67: ***             ASCII wrappers for those that are used by libcurl, but not
                     68: ***             defined by QADRT.
                     69: **/
                     70: 
                     71: #pragma convert(0)                              /* Restore EBCDIC. */
                     72: 
                     73: 
                     74: #define MIN_BYTE_GAIN   1024    /* Minimum gain when shortening a buffer. */
                     75: 
                     76: typedef struct {
                     77:         unsigned long   size;                   /* Buffer size. */
                     78:         char *          buf;                    /* Buffer address. */
                     79: }               buffer_t;
                     80: 
                     81: 
                     82: static char *   buffer_undef(localkey_t key, long size);
                     83: static char *   buffer_threaded(localkey_t key, long size);
                     84: static char *   buffer_unthreaded(localkey_t key, long size);
                     85: 
                     86: static pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;
                     87: static pthread_key_t    thdkey;
                     88: static buffer_t *       locbufs;
                     89: 
                     90: char *  (* Curl_thread_buffer)(localkey_t key, long size) = buffer_undef;
                     91: 
                     92: 
                     93: static void
                     94: thdbufdestroy(void * private)
                     95: 
                     96: {
                     97:   if(private) {
                     98:     buffer_t * p = (buffer_t *) private;
                     99:     localkey_t i;
                    100: 
                    101:     for(i = (localkey_t) 0; i < LK_LAST; i++) {
                    102:       free(p->buf);
                    103:       p++;
                    104:       }
                    105: 
                    106:     free(private);
                    107:     }
                    108: }
                    109: 
                    110: 
                    111: static void
                    112: terminate(void)
                    113: 
                    114: {
                    115:   if(Curl_thread_buffer == buffer_threaded) {
                    116:     locbufs = pthread_getspecific(thdkey);
                    117:     pthread_setspecific(thdkey, (void *) NULL);
                    118:     pthread_key_delete(thdkey);
                    119:     }
                    120: 
                    121:   if(Curl_thread_buffer != buffer_undef) {
                    122:     thdbufdestroy((void *) locbufs);
                    123:     locbufs = (buffer_t *) NULL;
                    124:     }
                    125: 
                    126:   Curl_thread_buffer = buffer_undef;
                    127: }
                    128: 
                    129: 
                    130: static char *
                    131: get_buffer(buffer_t * buf, long size)
                    132: 
                    133: {
                    134:   char * cp;
                    135: 
                    136:   /* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long.
                    137:      Return the buffer address. */
                    138: 
                    139:   if(size < 0)
                    140:     return buf->buf;
                    141: 
                    142:   if(!buf->buf) {
                    143:     buf->buf = malloc(size);
                    144:     if(buf->buf)
                    145:       buf->size = size;
                    146: 
                    147:     return buf->buf;
                    148:   }
                    149: 
                    150:   if((unsigned long) size <= buf->size) {
                    151:     /* Shorten the buffer only if it frees a significant byte count. This
                    152:        avoids some realloc() overhead. */
                    153: 
                    154:     if(buf->size - size < MIN_BYTE_GAIN)
                    155:       return buf->buf;
                    156:   }
                    157: 
                    158:   /* Resize the buffer. */
                    159: 
                    160:   cp = realloc(buf->buf, size);
                    161:   if(cp) {
                    162:     buf->buf = cp;
                    163:     buf->size = size;
                    164:   }
                    165:   else if(size <= buf->size)
                    166:     cp = buf->buf;
                    167: 
                    168:   return cp;
                    169: }
                    170: 
                    171: 
                    172: static char *
                    173: buffer_unthreaded(localkey_t key, long size)
                    174: 
                    175: {
                    176:   return get_buffer(locbufs + key, size);
                    177: }
                    178: 
                    179: 
                    180: static char *
                    181: buffer_threaded(localkey_t key, long size)
                    182: 
                    183: {
                    184:   buffer_t * bufs;
                    185: 
                    186:   /* Get the buffer for the given local key in the current thread, and
                    187:      make sure it is at least `size'-byte long. Set `size' to < 0 to get
                    188:      its address only. */
                    189: 
                    190:   bufs = (buffer_t *) pthread_getspecific(thdkey);
                    191: 
                    192:   if(!bufs) {
                    193:     if(size < 0)
                    194:       return (char *) NULL;             /* No buffer yet. */
                    195: 
                    196:     /* Allocate buffer descriptors for the current thread. */
                    197: 
                    198:     bufs = calloc((size_t) LK_LAST, sizeof(*bufs));
                    199:     if(!bufs)
                    200:       return (char *) NULL;
                    201: 
                    202:     if(pthread_setspecific(thdkey, (void *) bufs)) {
                    203:       free(bufs);
                    204:       return (char *) NULL;
                    205:     }
                    206:   }
                    207: 
                    208:   return get_buffer(bufs + key, size);
                    209: }
                    210: 
                    211: 
                    212: static char *
                    213: buffer_undef(localkey_t key, long size)
                    214: 
                    215: {
                    216:   /* Define the buffer system, get the buffer for the given local key in
                    217:      the current thread, and make sure it is at least `size'-byte long.
                    218:      Set `size' to < 0 to get its address only. */
                    219: 
                    220:   pthread_mutex_lock(&mutex);
                    221: 
                    222:   /* Determine if we can use pthread-specific data. */
                    223: 
                    224:   if(Curl_thread_buffer == buffer_undef) {      /* If unchanged during lock. */
                    225:     if(!pthread_key_create(&thdkey, thdbufdestroy))
                    226:       Curl_thread_buffer = buffer_threaded;
                    227:     else if(!(locbufs = calloc((size_t) LK_LAST, sizeof(*locbufs)))) {
                    228:       pthread_mutex_unlock(&mutex);
                    229:       return (char *) NULL;
                    230:       }
                    231:     else
                    232:         Curl_thread_buffer = buffer_unthreaded;
                    233: 
                    234:     atexit(terminate);
                    235:     }
                    236: 
                    237:   pthread_mutex_unlock(&mutex);
                    238:   return Curl_thread_buffer(key, size);
                    239: }
                    240: 
                    241: 
                    242: static char *
                    243: set_thread_string(localkey_t key, const char * s)
                    244: 
                    245: {
                    246:   int i;
                    247:   char * cp;
                    248: 
                    249:   if(!s)
                    250:     return (char *) NULL;
                    251: 
                    252:   i = strlen(s) + 1;
                    253:   cp = Curl_thread_buffer(key, MAX_CONV_EXPANSION * i + 1);
                    254: 
                    255:   if(cp) {
                    256:     i = QadrtConvertE2A(cp, s, MAX_CONV_EXPANSION * i, i);
                    257:     cp[i] = '\0';
                    258:   }
                    259: 
                    260:   return cp;
                    261: }
                    262: 
                    263: 
                    264: int
                    265: Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
                    266:               char * nodename, curl_socklen_t nodenamelen,
                    267:               char * servname, curl_socklen_t servnamelen,
                    268:               int flags)
                    269: 
                    270: {
                    271:   char *enodename = NULL;
                    272:   char *eservname = NULL;
                    273:   int status;
                    274: 
                    275:   if(nodename && nodenamelen) {
                    276:     enodename = malloc(nodenamelen);
                    277:     if(!enodename)
                    278:       return EAI_MEMORY;
                    279:   }
                    280: 
                    281:   if(servname && servnamelen) {
                    282:     eservname = malloc(servnamelen);
                    283:     if(!eservname) {
                    284:       free(enodename);
                    285:       return EAI_MEMORY;
                    286:     }
                    287:   }
                    288: 
                    289:   status = getnameinfo(sa, salen, enodename, nodenamelen,
                    290:                        eservname, servnamelen, flags);
                    291: 
                    292:   if(!status) {
                    293:     int i;
                    294:     if(enodename) {
                    295:       i = QadrtConvertE2A(nodename, enodename,
                    296:         nodenamelen - 1, strlen(enodename));
                    297:       nodename[i] = '\0';
                    298:       }
                    299: 
                    300:     if(eservname) {
                    301:       i = QadrtConvertE2A(servname, eservname,
                    302:         servnamelen - 1, strlen(eservname));
                    303:       servname[i] = '\0';
                    304:       }
                    305:     }
                    306: 
                    307:   free(enodename);
                    308:   free(eservname);
                    309:   return status;
                    310: }
                    311: 
                    312: 
                    313: int
                    314: Curl_getaddrinfo_a(const char * nodename, const char * servname,
                    315:             const struct addrinfo * hints,
                    316:             struct addrinfo * * res)
                    317: 
                    318: {
                    319:   char * enodename;
                    320:   char * eservname;
                    321:   int status;
                    322:   int i;
                    323: 
                    324:   enodename = (char *) NULL;
                    325:   eservname = (char *) NULL;
                    326: 
                    327:   if(nodename) {
                    328:     i = strlen(nodename);
                    329: 
                    330:     enodename = malloc(i + 1);
                    331:     if(!enodename)
                    332:       return EAI_MEMORY;
                    333: 
                    334:     i = QadrtConvertA2E(enodename, nodename, i, i);
                    335:     enodename[i] = '\0';
                    336:   }
                    337: 
                    338:   if(servname) {
                    339:     i = strlen(servname);
                    340: 
                    341:     eservname = malloc(i + 1);
                    342:     if(!eservname) {
                    343:       free(enodename);
                    344:       return EAI_MEMORY;
                    345:     }
                    346: 
                    347:     QadrtConvertA2E(eservname, servname, i, i);
                    348:     eservname[i] = '\0';
                    349:   }
                    350: 
                    351:   status = getaddrinfo(enodename, eservname, hints, res);
                    352:   free(enodename);
                    353:   free(eservname);
                    354:   return status;
                    355: }
                    356: 
                    357: 
                    358: #ifdef USE_GSKIT
                    359: 
                    360: /* ASCII wrappers for the GSKit procedures. */
                    361: 
                    362: /*
                    363:  * EBCDIC --> ASCII string mapping table.
                    364:  * Some strings returned by GSKit are dynamically allocated and automatically
                    365:  * released when closing the handle.
                    366:  * To provide the same functionality, we use a "private" handle that
                    367:  * holds the GSKit handle and a list of string mappings. This will allow
                    368:  * avoid conversion of already converted strings and releasing them upon
                    369:  * close time.
                    370:  */
                    371: 
                    372: struct gskstrlist {
                    373:   struct gskstrlist * next;
                    374:   const char * ebcdicstr;
                    375:   const char * asciistr;
                    376: };
                    377: 
                    378: struct Curl_gsk_descriptor {
                    379:   gsk_handle h;
                    380:   struct gskstrlist * strlist;
                    381: };
                    382: 
                    383: 
                    384: int
                    385: Curl_gsk_environment_open(gsk_handle * my_env_handle)
                    386: 
                    387: {
                    388:   struct Curl_gsk_descriptor * p;
                    389:   int rc;
                    390: 
                    391:   if(!my_env_handle)
                    392:     return GSK_OS400_ERROR_INVALID_POINTER;
                    393:   p = (struct Curl_gsk_descriptor *) malloc(sizeof(*p));
                    394:   if(!p)
                    395:     return GSK_INSUFFICIENT_STORAGE;
                    396:   p->strlist = (struct gskstrlist *) NULL;
                    397:   rc = gsk_environment_open(&p->h);
                    398:   if(rc != GSK_OK)
                    399:     free(p);
                    400:   else
                    401:     *my_env_handle = (gsk_handle) p;
                    402:   return rc;
                    403: }
                    404: 
                    405: 
                    406: int
                    407: Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
                    408:                          gsk_handle * my_session_handle)
                    409: 
                    410: {
                    411:   struct Curl_gsk_descriptor * p;
                    412:   gsk_handle h;
                    413:   int rc;
                    414: 
                    415:   if(!my_env_handle)
                    416:     return GSK_INVALID_HANDLE;
                    417:   if(!my_session_handle)
                    418:     return GSK_OS400_ERROR_INVALID_POINTER;
                    419:   h = ((struct Curl_gsk_descriptor *) my_env_handle)->h;
                    420:   p = (struct Curl_gsk_descriptor *) malloc(sizeof(*p));
                    421:   if(!p)
                    422:     return GSK_INSUFFICIENT_STORAGE;
                    423:   p->strlist = (struct gskstrlist *) NULL;
                    424:   rc = gsk_secure_soc_open(h, &p->h);
                    425:   if(rc != GSK_OK)
                    426:     free(p);
                    427:   else
                    428:     *my_session_handle = (gsk_handle) p;
                    429:   return rc;
                    430: }
                    431: 
                    432: 
                    433: static void
                    434: gsk_free_handle(struct Curl_gsk_descriptor * p)
                    435: 
                    436: {
                    437:   struct gskstrlist * q;
                    438: 
                    439:   while((q = p->strlist)) {
                    440:     p->strlist = q;
                    441:     free((void *) q->asciistr);
                    442:     free(q);
                    443:   }
                    444:   free(p);
                    445: }
                    446: 
                    447: 
                    448: int
                    449: Curl_gsk_environment_close(gsk_handle * my_env_handle)
                    450: 
                    451: {
                    452:   struct Curl_gsk_descriptor * p;
                    453:   int rc;
                    454: 
                    455:   if(!my_env_handle)
                    456:     return GSK_OS400_ERROR_INVALID_POINTER;
                    457:   if(!*my_env_handle)
                    458:     return GSK_INVALID_HANDLE;
                    459:   p = (struct Curl_gsk_descriptor *) *my_env_handle;
                    460:   rc = gsk_environment_close(&p->h);
                    461:   if(rc == GSK_OK) {
                    462:     gsk_free_handle(p);
                    463:     *my_env_handle = (gsk_handle) NULL;
                    464:   }
                    465:   return rc;
                    466: }
                    467: 
                    468: 
                    469: int
                    470: Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)
                    471: 
                    472: {
                    473:   struct Curl_gsk_descriptor * p;
                    474:   int rc;
                    475: 
                    476:   if(!my_session_handle)
                    477:     return GSK_OS400_ERROR_INVALID_POINTER;
                    478:   if(!*my_session_handle)
                    479:     return GSK_INVALID_HANDLE;
                    480:   p = (struct Curl_gsk_descriptor *) *my_session_handle;
                    481:   rc = gsk_secure_soc_close(&p->h);
                    482:   if(rc == GSK_OK) {
                    483:     gsk_free_handle(p);
                    484:     *my_session_handle = (gsk_handle) NULL;
                    485:   }
                    486:   return rc;
                    487: }
                    488: 
                    489: 
                    490: int
                    491: Curl_gsk_environment_init(gsk_handle my_env_handle)
                    492: 
                    493: {
                    494:   struct Curl_gsk_descriptor * p;
                    495: 
                    496:   if(!my_env_handle)
                    497:     return GSK_INVALID_HANDLE;
                    498:   p = (struct Curl_gsk_descriptor *) my_env_handle;
                    499:   return gsk_environment_init(p->h);
                    500: }
                    501: 
                    502: 
                    503: int
                    504: Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
                    505: 
                    506: {
                    507:   struct Curl_gsk_descriptor * p;
                    508: 
                    509:   if(!my_session_handle)
                    510:     return GSK_INVALID_HANDLE;
                    511:   p = (struct Curl_gsk_descriptor *) my_session_handle;
                    512:   return gsk_secure_soc_init(p->h);
                    513: }
                    514: 
                    515: 
                    516: int
                    517: Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
                    518:                                 const char * buffer, int bufSize)
                    519: 
                    520: {
                    521:   struct Curl_gsk_descriptor * p;
                    522:   char * ebcdicbuf;
                    523:   int rc;
                    524: 
                    525:   if(!my_gsk_handle)
                    526:     return GSK_INVALID_HANDLE;
                    527:   if(!buffer)
                    528:     return GSK_OS400_ERROR_INVALID_POINTER;
                    529:   if(bufSize < 0)
                    530:     return GSK_ATTRIBUTE_INVALID_LENGTH;
                    531:   p = (struct Curl_gsk_descriptor *) my_gsk_handle;
                    532:   if(!bufSize)
                    533:     bufSize = strlen(buffer);
                    534:   ebcdicbuf = malloc(bufSize + 1);
                    535:   if(!ebcdicbuf)
                    536:     return GSK_INSUFFICIENT_STORAGE;
                    537:   QadrtConvertA2E(ebcdicbuf, buffer, bufSize, bufSize);
                    538:   ebcdicbuf[bufSize] = '\0';
                    539:   rc = gsk_attribute_set_buffer(p->h, bufID, ebcdicbuf, bufSize);
                    540:   free(ebcdicbuf);
                    541:   return rc;
                    542: }
                    543: 
                    544: 
                    545: int
                    546: Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
                    547:                             GSK_ENUM_VALUE enumValue)
                    548: 
                    549: {
                    550:   struct Curl_gsk_descriptor * p;
                    551: 
                    552:   if(!my_gsk_handle)
                    553:     return GSK_INVALID_HANDLE;
                    554:   p = (struct Curl_gsk_descriptor *) my_gsk_handle;
                    555:   return gsk_attribute_set_enum(p->h, enumID, enumValue);
                    556: }
                    557: 
                    558: 
                    559: int
                    560: Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
                    561:                                      GSK_NUM_ID numID, int numValue)
                    562: 
                    563: {
                    564:   struct Curl_gsk_descriptor * p;
                    565: 
                    566:   if(!my_gsk_handle)
                    567:     return GSK_INVALID_HANDLE;
                    568:   p = (struct Curl_gsk_descriptor *) my_gsk_handle;
                    569:   return gsk_attribute_set_numeric_value(p->h, numID, numValue);
                    570: }
                    571: 
                    572: 
                    573: int
                    574: Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
                    575:                                 GSK_CALLBACK_ID callBackID,
                    576:                                 void * callBackAreaPtr)
                    577: 
                    578: {
                    579:   struct Curl_gsk_descriptor * p;
                    580: 
                    581:   if(!my_gsk_handle)
                    582:     return GSK_INVALID_HANDLE;
                    583:   p = (struct Curl_gsk_descriptor *) my_gsk_handle;
                    584:   return gsk_attribute_set_callback(p->h, callBackID, callBackAreaPtr);
                    585: }
                    586: 
                    587: 
                    588: static int
                    589: cachestring(struct Curl_gsk_descriptor * p,
                    590:             const char * ebcdicbuf, int bufsize, const char * * buffer)
                    591: 
                    592: {
                    593:   int rc;
                    594:   char * asciibuf;
                    595:   struct gskstrlist * sp;
                    596: 
                    597:   for(sp = p->strlist; sp; sp = sp->next)
                    598:     if(sp->ebcdicstr == ebcdicbuf)
                    599:       break;
                    600:   if(!sp) {
                    601:     sp = (struct gskstrlist *) malloc(sizeof(*sp));
                    602:     if(!sp)
                    603:       return GSK_INSUFFICIENT_STORAGE;
                    604:     asciibuf = malloc(bufsize + 1);
                    605:     if(!asciibuf) {
                    606:       free(sp);
                    607:       return GSK_INSUFFICIENT_STORAGE;
                    608:     }
                    609:     QadrtConvertE2A(asciibuf, ebcdicbuf, bufsize, bufsize);
                    610:     asciibuf[bufsize] = '\0';
                    611:     sp->ebcdicstr = ebcdicbuf;
                    612:     sp->asciistr = asciibuf;
                    613:     sp->next = p->strlist;
                    614:     p->strlist = sp;
                    615:   }
                    616:   *buffer = sp->asciistr;
                    617:   return GSK_OK;
                    618: }
                    619: 
                    620: 
                    621: int
                    622: Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
                    623:                                 const char * * buffer, int * bufSize)
                    624: 
                    625: {
                    626:   struct Curl_gsk_descriptor * p;
                    627:   int rc;
                    628:   const char * mybuf;
                    629:   int mylen;
                    630: 
                    631:   if(!my_gsk_handle)
                    632:     return GSK_INVALID_HANDLE;
                    633:   if(!buffer || !bufSize)
                    634:     return GSK_OS400_ERROR_INVALID_POINTER;
                    635:   p = (struct Curl_gsk_descriptor *) my_gsk_handle;
                    636:   rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen);
                    637:   if(rc != GSK_OK)
                    638:     return rc;
                    639:   rc = cachestring(p, mybuf, mylen, buffer);
                    640:   if(rc == GSK_OK)
                    641:     *bufSize = mylen;
                    642:   return rc;
                    643: }
                    644: 
                    645: 
                    646: int
                    647: Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
                    648:                             GSK_ENUM_VALUE * enumValue)
                    649: 
                    650: {
                    651:   struct Curl_gsk_descriptor * p;
                    652: 
                    653:   if(!my_gsk_handle)
                    654:     return GSK_INVALID_HANDLE;
                    655:   p = (struct Curl_gsk_descriptor *) my_gsk_handle;
                    656:   return gsk_attribute_get_enum(p->h, enumID, enumValue);
                    657: }
                    658: 
                    659: 
                    660: int
                    661: Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
                    662:                                      GSK_NUM_ID numID, int * numValue)
                    663: 
                    664: {
                    665:   struct Curl_gsk_descriptor * p;
                    666: 
                    667:   if(!my_gsk_handle)
                    668:     return GSK_INVALID_HANDLE;
                    669:   p = (struct Curl_gsk_descriptor *) my_gsk_handle;
                    670:   return gsk_attribute_get_numeric_value(p->h, numID, numValue);
                    671: }
                    672: 
                    673: 
                    674: int
                    675: Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
                    676:                                  GSK_CERT_ID certID,
                    677:                                  const gsk_cert_data_elem * * certDataElem,
                    678:                                  int * certDataElementCount)
                    679: 
                    680: {
                    681:   struct Curl_gsk_descriptor * p;
                    682: 
                    683:   if(!my_gsk_handle)
                    684:     return GSK_INVALID_HANDLE;
                    685:   p = (struct Curl_gsk_descriptor *) my_gsk_handle;
                    686:   /* No need to convert code: text results are already in ASCII. */
                    687:   return gsk_attribute_get_cert_info(p->h, certID,
                    688:                                      certDataElem, certDataElementCount);
                    689: }
                    690: 
                    691: 
                    692: int
                    693: Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, GSK_MISC_ID miscID)
                    694: 
                    695: {
                    696:   struct Curl_gsk_descriptor * p;
                    697: 
                    698:   if(!my_session_handle)
                    699:     return GSK_INVALID_HANDLE;
                    700:   p = (struct Curl_gsk_descriptor *) my_session_handle;
                    701:   return gsk_secure_soc_misc(p->h, miscID);
                    702: }
                    703: 
                    704: 
                    705: int
                    706: Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char * readBuffer,
                    707:                          int readBufSize, int * amtRead)
                    708: 
                    709: {
                    710:   struct Curl_gsk_descriptor * p;
                    711: 
                    712:   if(!my_session_handle)
                    713:     return GSK_INVALID_HANDLE;
                    714:   p = (struct Curl_gsk_descriptor *) my_session_handle;
                    715:   return gsk_secure_soc_read(p->h, readBuffer, readBufSize, amtRead);
                    716: }
                    717: 
                    718: 
                    719: int
                    720: Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char * writeBuffer,
                    721:                           int writeBufSize, int * amtWritten)
                    722: 
                    723: {
                    724:   struct Curl_gsk_descriptor * p;
                    725: 
                    726:   if(!my_session_handle)
                    727:     return GSK_INVALID_HANDLE;
                    728:   p = (struct Curl_gsk_descriptor *) my_session_handle;
                    729:   return gsk_secure_soc_write(p->h, writeBuffer, writeBufSize, amtWritten);
                    730: }
                    731: 
                    732: 
                    733: const char *
                    734: Curl_gsk_strerror_a(int gsk_return_value)
                    735: 
                    736: {
                    737:   return set_thread_string(LK_GSK_ERROR, gsk_strerror(gsk_return_value));
                    738: }
                    739: 
                    740: int
                    741: Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
                    742:                               int IOCompletionPort,
                    743:                               Qso_OverlappedIO_t * communicationsArea)
                    744: 
                    745: {
                    746:   struct Curl_gsk_descriptor * p;
                    747: 
                    748:   if(!my_session_handle)
                    749:     return GSK_INVALID_HANDLE;
                    750:   p = (struct Curl_gsk_descriptor *) my_session_handle;
                    751:   return gsk_secure_soc_startInit(p->h, IOCompletionPort, communicationsArea);
                    752: }
                    753: 
                    754: #endif /* USE_GSKIT */
                    755: 
                    756: 
                    757: 
                    758: #ifdef HAVE_GSSAPI
                    759: 
                    760: /* ASCII wrappers for the GSSAPI procedures. */
                    761: 
                    762: static int
                    763: Curl_gss_convert_in_place(OM_uint32 * minor_status, gss_buffer_t buf)
                    764: 
                    765: {
                    766:   unsigned int i = buf->length;
                    767: 
                    768:   /* Convert `buf' in place, from EBCDIC to ASCII.
                    769:      If error, release the buffer and return -1. Else return 0. */
                    770: 
                    771:   if(i) {
                    772:     char *t = malloc(i);
                    773:     if(!t) {
                    774:       gss_release_buffer(minor_status, buf);
                    775: 
                    776:       if(minor_status)
                    777:         *minor_status = ENOMEM;
                    778: 
                    779:       return -1;
                    780:     }
                    781: 
                    782:     QadrtConvertE2A(t, buf->value, i, i);
                    783:     memcpy(buf->value, t, i);
                    784:     free(t);
                    785:   }
                    786: 
                    787:   return 0;
                    788: }
                    789: 
                    790: 
                    791: OM_uint32
                    792: Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
                    793:                        gss_OID in_name_type, gss_name_t * out_name)
                    794: 
                    795: {
                    796:   int rc;
                    797:   unsigned int i;
                    798:   gss_buffer_desc in;
                    799: 
                    800:   if(!in_name || !in_name->value || !in_name->length)
                    801:     return gss_import_name(minor_status, in_name, in_name_type, out_name);
                    802: 
                    803:   memcpy((char *) &in, (char *) in_name, sizeof(in));
                    804:   i = in.length;
                    805: 
                    806:   in.value = malloc(i + 1);
                    807:   if(!in.value) {
                    808:     if(minor_status)
                    809:       *minor_status = ENOMEM;
                    810: 
                    811:     return GSS_S_FAILURE;
                    812:   }
                    813: 
                    814:   QadrtConvertA2E(in.value, in_name->value, i, i);
                    815:   ((char *) in.value)[i] = '\0';
                    816:   rc = gss_import_name(minor_status, &in, in_name_type, out_name);
                    817:   free(in.value);
                    818:   return rc;
                    819: }
                    820: 
                    821: 
                    822: OM_uint32
                    823: Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
                    824:                    int status_type, gss_OID mech_type,
                    825:                    gss_msg_ctx_t * message_context, gss_buffer_t status_string)
                    826: 
                    827: {
                    828:   int rc;
                    829: 
                    830:   rc = gss_display_status(minor_status, status_value, status_type,
                    831:                               mech_type, message_context, status_string);
                    832: 
                    833:   if(rc != GSS_S_COMPLETE || !status_string ||
                    834:      !status_string->length || !status_string->value)
                    835:     return rc;
                    836: 
                    837:   /* No way to allocate a buffer here, because it will be released by
                    838:      gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
                    839:      with ASCII to return it. */
                    840: 
                    841:   if(Curl_gss_convert_in_place(minor_status, status_string))
                    842:     return GSS_S_FAILURE;
                    843: 
                    844:   return rc;
                    845: }
                    846: 
                    847: 
                    848: OM_uint32
                    849: Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
                    850:                             gss_cred_id_t cred_handle,
                    851:                             gss_ctx_id_t * context_handle,
                    852:                             gss_name_t target_name, gss_OID mech_type,
                    853:                             gss_flags_t req_flags, OM_uint32 time_req,
                    854:                             gss_channel_bindings_t input_chan_bindings,
                    855:                             gss_buffer_t input_token,
                    856:                             gss_OID * actual_mech_type,
                    857:                             gss_buffer_t output_token, gss_flags_t * ret_flags,
                    858:                             OM_uint32 * time_rec)
                    859: 
                    860: {
                    861:   int rc;
                    862:   gss_buffer_desc in;
                    863:   gss_buffer_t inp;
                    864: 
                    865:   in.value = NULL;
                    866:   inp = input_token;
                    867: 
                    868:   if(inp) {
                    869:     if(inp->length && inp->value) {
                    870:       unsigned int i = inp->length;
                    871: 
                    872:       in.value = malloc(i + 1);
                    873:       if(!in.value) {
                    874:         if(minor_status)
                    875:           *minor_status = ENOMEM;
                    876: 
                    877:         return GSS_S_FAILURE;
                    878:       }
                    879: 
                    880:       QadrtConvertA2E(in.value, input_token->value, i, i);
                    881:       ((char *) in.value)[i] = '\0';
                    882:       in.length = i;
                    883:       inp = &in;
                    884:     }
                    885:   }
                    886: 
                    887:   rc = gss_init_sec_context(minor_status, cred_handle, context_handle,
                    888:                              target_name, mech_type, req_flags, time_req,
                    889:                              input_chan_bindings, inp, actual_mech_type,
                    890:                              output_token, ret_flags, time_rec);
                    891:   free(in.value);
                    892: 
                    893:   if(rc != GSS_S_COMPLETE || !output_token ||
                    894:       !output_token->length || !output_token->value)
                    895:     return rc;
                    896: 
                    897:   /* No way to allocate a buffer here, because it will be released by
                    898:      gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
                    899:      with ASCII to return it. */
                    900: 
                    901:   if(Curl_gss_convert_in_place(minor_status, output_token))
                    902:     return GSS_S_FAILURE;
                    903: 
                    904:   return rc;
                    905: }
                    906: 
                    907: 
                    908: OM_uint32
                    909: Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
                    910:                               gss_ctx_id_t * context_handle,
                    911:                               gss_buffer_t output_token)
                    912: 
                    913: {
                    914:   int rc;
                    915: 
                    916:   rc = gss_delete_sec_context(minor_status, context_handle, output_token);
                    917: 
                    918:   if(rc != GSS_S_COMPLETE || !output_token ||
                    919:       !output_token->length || !output_token->value)
                    920:     return rc;
                    921: 
                    922:   /* No way to allocate a buffer here, because it will be released by
                    923:      gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
                    924:      with ASCII to return it. */
                    925: 
                    926:   if(Curl_gss_convert_in_place(minor_status, output_token))
                    927:     return GSS_S_FAILURE;
                    928: 
                    929:   return rc;
                    930: }
                    931: 
                    932: #endif /* HAVE_GSSAPI */
                    933: 
                    934: 
                    935: #ifndef CURL_DISABLE_LDAP
                    936: 
                    937: /* ASCII wrappers for the LDAP procedures. */
                    938: 
                    939: void *
                    940: Curl_ldap_init_a(char * host, int port)
                    941: 
                    942: {
                    943:   unsigned int i;
                    944:   char * ehost;
                    945:   void * result;
                    946: 
                    947:   if(!host)
                    948:     return (void *) ldap_init(host, port);
                    949: 
                    950:   i = strlen(host);
                    951: 
                    952:   ehost = malloc(i + 1);
                    953:   if(!ehost)
                    954:     return (void *) NULL;
                    955: 
                    956:   QadrtConvertA2E(ehost, host, i, i);
                    957:   ehost[i] = '\0';
                    958:   result = (void *) ldap_init(ehost, port);
                    959:   free(ehost);
                    960:   return result;
                    961: }
                    962: 
                    963: 
                    964: int
                    965: Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
                    966: 
                    967: {
                    968:   int i;
                    969:   char * edn;
                    970:   char * epasswd;
                    971: 
                    972:   edn = (char *) NULL;
                    973:   epasswd = (char *) NULL;
                    974: 
                    975:   if(dn) {
                    976:     i = strlen(dn);
                    977: 
                    978:     edn = malloc(i + 1);
                    979:     if(!edn)
                    980:       return LDAP_NO_MEMORY;
                    981: 
                    982:     QadrtConvertA2E(edn, dn, i, i);
                    983:     edn[i] = '\0';
                    984:   }
                    985: 
                    986:   if(passwd) {
                    987:     i = strlen(passwd);
                    988: 
                    989:     epasswd = malloc(i + 1);
                    990:     if(!epasswd) {
                    991:       free(edn);
                    992:       return LDAP_NO_MEMORY;
                    993:     }
                    994: 
                    995:     QadrtConvertA2E(epasswd, passwd, i, i);
                    996:     epasswd[i] = '\0';
                    997:   }
                    998: 
                    999:   i = ldap_simple_bind_s(ld, edn, epasswd);
                   1000:   free(epasswd);
                   1001:   free(edn);
                   1002:   return i;
                   1003: }
                   1004: 
                   1005: 
                   1006: int
                   1007: Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
                   1008:                      char * * attrs, int attrsonly, LDAPMessage * * res)
                   1009: 
                   1010: {
                   1011:   int i;
                   1012:   int j;
                   1013:   char * ebase;
                   1014:   char * efilter;
                   1015:   char * * eattrs;
                   1016:   int status;
                   1017: 
                   1018:   ebase = (char *) NULL;
                   1019:   efilter = (char *) NULL;
                   1020:   eattrs = (char * *) NULL;
                   1021:   status = LDAP_SUCCESS;
                   1022: 
                   1023:   if(base) {
                   1024:     i = strlen(base);
                   1025: 
                   1026:     ebase = malloc(i + 1);
                   1027:     if(!ebase)
                   1028:       status = LDAP_NO_MEMORY;
                   1029:     else {
                   1030:       QadrtConvertA2E(ebase, base, i, i);
                   1031:       ebase[i] = '\0';
                   1032:     }
                   1033:   }
                   1034: 
                   1035:   if(filter && status == LDAP_SUCCESS) {
                   1036:     i = strlen(filter);
                   1037: 
                   1038:     efilter = malloc(i + 1);
                   1039:     if(!efilter)
                   1040:       status = LDAP_NO_MEMORY;
                   1041:     else {
                   1042:       QadrtConvertA2E(efilter, filter, i, i);
                   1043:       efilter[i] = '\0';
                   1044:     }
                   1045:   }
                   1046: 
                   1047:   if(attrs && status == LDAP_SUCCESS) {
                   1048:     for(i = 0; attrs[i++];)
                   1049:       ;
                   1050: 
                   1051:     eattrs = calloc(i, sizeof(*eattrs));
                   1052:     if(!eattrs)
                   1053:       status = LDAP_NO_MEMORY;
                   1054:     else {
                   1055:       for(j = 0; attrs[j]; j++) {
                   1056:         i = strlen(attrs[j]);
                   1057: 
                   1058:         eattrs[j] = malloc(i + 1);
                   1059:         if(!eattrs[j]) {
                   1060:           status = LDAP_NO_MEMORY;
                   1061:           break;
                   1062:         }
                   1063: 
                   1064:         QadrtConvertA2E(eattrs[j], attrs[j], i, i);
                   1065:         eattrs[j][i] = '\0';
                   1066:         }
                   1067:       }
                   1068:     }
                   1069: 
                   1070:   if(status == LDAP_SUCCESS)
                   1071:     status = ldap_search_s(ld, ebase? ebase: "", scope,
                   1072:                            efilter? efilter: "(objectclass=*)",
                   1073:                            eattrs, attrsonly, res);
                   1074: 
                   1075:   if(eattrs) {
                   1076:     for(j = 0; eattrs[j]; j++)
                   1077:       free(eattrs[j]);
                   1078: 
                   1079:     free(eattrs);
                   1080:     }
                   1081: 
                   1082:   free(efilter);
                   1083:   free(ebase);
                   1084:   return status;
                   1085: }
                   1086: 
                   1087: 
                   1088: struct berval * *
                   1089: Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
                   1090: 
                   1091: {
                   1092:   char * cp;
                   1093:   struct berval * * result;
                   1094: 
                   1095:   cp = (char *) NULL;
                   1096: 
                   1097:   if(attr) {
                   1098:     int i = strlen(attr);
                   1099: 
                   1100:     cp = malloc(i + 1);
                   1101:     if(!cp) {
                   1102:       ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
                   1103:                        ldap_err2string(LDAP_NO_MEMORY));
                   1104:       return (struct berval * *) NULL;
                   1105:     }
                   1106: 
                   1107:     QadrtConvertA2E(cp, attr, i, i);
                   1108:     cp[i] = '\0';
                   1109:   }
                   1110: 
                   1111:   result = ldap_get_values_len(ld, entry, cp);
                   1112:   free(cp);
                   1113: 
                   1114:   /* Result data are binary in nature, so they haven't been
                   1115:      converted to EBCDIC. Therefore do not convert. */
                   1116: 
                   1117:   return result;
                   1118: }
                   1119: 
                   1120: 
                   1121: char *
                   1122: Curl_ldap_err2string_a(int error)
                   1123: 
                   1124: {
                   1125:   return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
                   1126: }
                   1127: 
                   1128: 
                   1129: char *
                   1130: Curl_ldap_get_dn_a(void * ld, LDAPMessage * entry)
                   1131: 
                   1132: {
                   1133:   int i;
                   1134:   char * cp;
                   1135:   char * cp2;
                   1136: 
                   1137:   cp = ldap_get_dn(ld, entry);
                   1138: 
                   1139:   if(!cp)
                   1140:     return cp;
                   1141: 
                   1142:   i = strlen(cp);
                   1143: 
                   1144:   cp2 = malloc(i + 1);
                   1145:   if(!cp2)
                   1146:     return cp2;
                   1147: 
                   1148:   QadrtConvertE2A(cp2, cp, i, i);
                   1149:   cp2[i] = '\0';
                   1150: 
                   1151:   /* No way to allocate a buffer here, because it will be released by
                   1152:      ldap_memfree() and ldap_memalloc() does not exist. The solution is to
                   1153:      overwrite the EBCDIC buffer with ASCII to return it. */
                   1154: 
                   1155:   strcpy(cp, cp2);
                   1156:   free(cp2);
                   1157:   return cp;
                   1158: }
                   1159: 
                   1160: 
                   1161: char *
                   1162: Curl_ldap_first_attribute_a(void * ld,
                   1163:                             LDAPMessage * entry, BerElement * * berptr)
                   1164: 
                   1165: {
                   1166:   int i;
                   1167:   char * cp;
                   1168:   char * cp2;
                   1169: 
                   1170:   cp = ldap_first_attribute(ld, entry, berptr);
                   1171: 
                   1172:   if(!cp)
                   1173:     return cp;
                   1174: 
                   1175:   i = strlen(cp);
                   1176: 
                   1177:   cp2 = malloc(i + 1);
                   1178:   if(!cp2)
                   1179:     return cp2;
                   1180: 
                   1181:   QadrtConvertE2A(cp2, cp, i, i);
                   1182:   cp2[i] = '\0';
                   1183: 
                   1184:   /* No way to allocate a buffer here, because it will be released by
                   1185:      ldap_memfree() and ldap_memalloc() does not exist. The solution is to
                   1186:      overwrite the EBCDIC buffer with ASCII to return it. */
                   1187: 
                   1188:   strcpy(cp, cp2);
                   1189:   free(cp2);
                   1190:   return cp;
                   1191: }
                   1192: 
                   1193: 
                   1194: char *
                   1195: Curl_ldap_next_attribute_a(void * ld,
                   1196:                            LDAPMessage * entry, BerElement * berptr)
                   1197: 
                   1198: {
                   1199:   int i;
                   1200:   char * cp;
                   1201:   char * cp2;
                   1202: 
                   1203:   cp = ldap_next_attribute(ld, entry, berptr);
                   1204: 
                   1205:   if(!cp)
                   1206:     return cp;
                   1207: 
                   1208:   i = strlen(cp);
                   1209: 
                   1210:   cp2 = malloc(i + 1);
                   1211:   if(!cp2)
                   1212:     return cp2;
                   1213: 
                   1214:   QadrtConvertE2A(cp2, cp, i, i);
                   1215:   cp2[i] = '\0';
                   1216: 
                   1217:   /* No way to allocate a buffer here, because it will be released by
                   1218:      ldap_memfree() and ldap_memalloc() does not exist. The solution is to
                   1219:      overwrite the EBCDIC buffer with ASCII to return it. */
                   1220: 
                   1221:   strcpy(cp, cp2);
                   1222:   free(cp2);
                   1223:   return cp;
                   1224: }
                   1225: 
                   1226: #endif /* CURL_DISABLE_LDAP */
                   1227: 
                   1228: 
                   1229: static int
                   1230: sockaddr2ebcdic(struct sockaddr_storage *dstaddr,
                   1231:                 const struct sockaddr *srcaddr, int srclen)
                   1232: {
                   1233:   const struct sockaddr_un *srcu;
                   1234:   struct sockaddr_un *dstu;
                   1235:   unsigned int i;
                   1236:   unsigned int dstsize;
                   1237: 
                   1238:   /* Convert a socket address to job CCSID, if needed. */
                   1239: 
                   1240:   if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
                   1241:      sizeof(srcaddr->sa_family) || srclen > sizeof(*dstaddr)) {
                   1242:     errno = EINVAL;
                   1243:     return -1;
                   1244:     }
                   1245: 
                   1246:   memcpy((char *) dstaddr, (char *) srcaddr, srclen);
                   1247: 
                   1248:   switch (srcaddr->sa_family) {
                   1249: 
                   1250:   case AF_UNIX:
                   1251:     srcu = (const struct sockaddr_un *) srcaddr;
                   1252:     dstu = (struct sockaddr_un *) dstaddr;
                   1253:     dstsize = sizeof(*dstaddr) - offsetof(struct sockaddr_un, sun_path);
                   1254:     srclen -= offsetof(struct sockaddr_un, sun_path);
                   1255:     i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen);
                   1256:     dstu->sun_path[i] = '\0';
                   1257:     srclen = i + offsetof(struct sockaddr_un, sun_path);
                   1258:     }
                   1259: 
                   1260:   return srclen;
                   1261: }
                   1262: 
                   1263: 
                   1264: static int
                   1265: sockaddr2ascii(struct sockaddr *dstaddr, int dstlen,
                   1266:                const struct sockaddr_storage *srcaddr, int srclen)
                   1267: {
                   1268:   const struct sockaddr_un *srcu;
                   1269:   struct sockaddr_un *dstu;
                   1270:   unsigned int dstsize;
                   1271: 
                   1272:   /* Convert a socket address to ASCII, if needed. */
                   1273: 
                   1274:   if(!srclen)
                   1275:     return 0;
                   1276:   if(srclen > dstlen)
                   1277:     srclen = dstlen;
                   1278:   if(!srcaddr || srclen < 0) {
                   1279:     errno = EINVAL;
                   1280:     return -1;
                   1281:     }
                   1282: 
                   1283:   memcpy((char *) dstaddr, (char *) srcaddr, srclen);
                   1284: 
                   1285:   if(srclen >= offsetof(struct sockaddr_storage, ss_family) +
                   1286:      sizeof(srcaddr->ss_family)) {
                   1287:     switch (srcaddr->ss_family) {
                   1288: 
                   1289:     case AF_UNIX:
                   1290:       srcu = (const struct sockaddr_un *) srcaddr;
                   1291:       dstu = (struct sockaddr_un *) dstaddr;
                   1292:       dstsize = dstlen - offsetof(struct sockaddr_un, sun_path);
                   1293:       srclen -= offsetof(struct sockaddr_un, sun_path);
                   1294:       if(dstsize > 0 && srclen > 0) {
                   1295:         srclen = QadrtConvertE2A(dstu->sun_path, srcu->sun_path,
                   1296:                                  dstsize - 1, srclen);
                   1297:         dstu->sun_path[srclen] = '\0';
                   1298:       }
                   1299:       srclen += offsetof(struct sockaddr_un, sun_path);
                   1300:     }
                   1301:   }
                   1302: 
                   1303:   return srclen;
                   1304: }
                   1305: 
                   1306: 
                   1307: int
                   1308: Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
                   1309: {
                   1310:   int i;
                   1311:   struct sockaddr_storage laddr;
                   1312: 
                   1313:   i = sockaddr2ebcdic(&laddr, destaddr, addrlen);
                   1314: 
                   1315:   if(i < 0)
                   1316:     return -1;
                   1317: 
                   1318:   return connect(sd, (struct sockaddr *) &laddr, i);
                   1319: }
                   1320: 
                   1321: 
                   1322: int
                   1323: Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
                   1324: {
                   1325:   int i;
                   1326:   struct sockaddr_storage laddr;
                   1327: 
                   1328:   i = sockaddr2ebcdic(&laddr, localaddr, addrlen);
                   1329: 
                   1330:   if(i < 0)
                   1331:     return -1;
                   1332: 
                   1333:   return bind(sd, (struct sockaddr *) &laddr, i);
                   1334: }
                   1335: 
                   1336: 
                   1337: int
                   1338: Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
                   1339:                                 struct sockaddr * dstaddr, int addrlen)
                   1340: {
                   1341:   int i;
                   1342:   struct sockaddr_storage laddr;
                   1343: 
                   1344:   i = sockaddr2ebcdic(&laddr, dstaddr, addrlen);
                   1345: 
                   1346:   if(i < 0)
                   1347:     return -1;
                   1348: 
                   1349:   return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
                   1350: }
                   1351: 
                   1352: 
                   1353: int
                   1354: Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
                   1355:                                 struct sockaddr * fromaddr, int * addrlen)
                   1356: {
                   1357:   int rcvlen;
                   1358:   struct sockaddr_storage laddr;
                   1359:   int laddrlen = sizeof(laddr);
                   1360: 
                   1361:   if(!fromaddr || !addrlen || *addrlen <= 0)
                   1362:     return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);
                   1363: 
                   1364:   laddr.ss_family = AF_UNSPEC;          /* To detect if unused. */
                   1365:   rcvlen = recvfrom(sd, buffer, buflen, flags,
                   1366:                     (struct sockaddr *) &laddr, &laddrlen);
                   1367: 
                   1368:   if(rcvlen < 0)
                   1369:     return rcvlen;
                   1370: 
                   1371:   if(laddr.ss_family == AF_UNSPEC)
                   1372:     laddrlen = 0;
                   1373:   else {
                   1374:     laddrlen = sockaddr2ascii(fromaddr, *addrlen, &laddr, laddrlen);
                   1375:     if(laddrlen < 0)
                   1376:       return laddrlen;
                   1377:   }
                   1378:   *addrlen = laddrlen;
                   1379:   return rcvlen;
                   1380: }
                   1381: 
                   1382: 
                   1383: int
                   1384: Curl_os400_getpeername(int sd, struct sockaddr *addr, int *addrlen)
                   1385: {
                   1386:   struct sockaddr_storage laddr;
                   1387:   int laddrlen = sizeof(laddr);
                   1388:   int retcode = getpeername(sd, (struct sockaddr *) &laddr, &laddrlen);
                   1389: 
                   1390:   if(!retcode) {
                   1391:     laddrlen = sockaddr2ascii(addr, *addrlen, &laddr, laddrlen);
                   1392:     if(laddrlen < 0)
                   1393:       return laddrlen;
                   1394:     *addrlen = laddrlen;
                   1395:   }
                   1396: 
                   1397:   return retcode;
                   1398: }
                   1399: 
                   1400: 
                   1401: int
                   1402: Curl_os400_getsockname(int sd, struct sockaddr *addr, int *addrlen)
                   1403: {
                   1404:   struct sockaddr_storage laddr;
                   1405:   int laddrlen = sizeof(laddr);
                   1406:   int retcode = getsockname(sd, (struct sockaddr *) &laddr, &laddrlen);
                   1407: 
                   1408:   if(!retcode) {
                   1409:     laddrlen = sockaddr2ascii(addr, *addrlen, &laddr, laddrlen);
                   1410:     if(laddrlen < 0)
                   1411:       return laddrlen;
                   1412:     *addrlen = laddrlen;
                   1413:   }
                   1414: 
                   1415:   return retcode;
                   1416: }
                   1417: 
                   1418: 
                   1419: #ifdef HAVE_LIBZ
                   1420: const char *
                   1421: Curl_os400_zlibVersion(void)
                   1422: 
                   1423: {
                   1424:   return set_thread_string(LK_ZLIB_VERSION, zlibVersion());
                   1425: }
                   1426: 
                   1427: 
                   1428: int
                   1429: Curl_os400_inflateInit_(z_streamp strm, const char * version, int stream_size)
                   1430: 
                   1431: {
                   1432:   z_const char * msgb4 = strm->msg;
                   1433:   int ret;
                   1434: 
                   1435:   ret = inflateInit(strm);
                   1436: 
                   1437:   if(strm->msg != msgb4)
                   1438:     strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
                   1439: 
                   1440:   return ret;
                   1441: }
                   1442: 
                   1443: 
                   1444: int
                   1445: Curl_os400_inflateInit2_(z_streamp strm, int windowBits,
                   1446:                                         const char * version, int stream_size)
                   1447: 
                   1448: {
                   1449:   z_const char * msgb4 = strm->msg;
                   1450:   int ret;
                   1451: 
                   1452:   ret = inflateInit2(strm, windowBits);
                   1453: 
                   1454:   if(strm->msg != msgb4)
                   1455:     strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
                   1456: 
                   1457:   return ret;
                   1458: }
                   1459: 
                   1460: 
                   1461: int
                   1462: Curl_os400_inflate(z_streamp strm, int flush)
                   1463: 
                   1464: {
                   1465:   z_const char * msgb4 = strm->msg;
                   1466:   int ret;
                   1467: 
                   1468:   ret = inflate(strm, flush);
                   1469: 
                   1470:   if(strm->msg != msgb4)
                   1471:     strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
                   1472: 
                   1473:   return ret;
                   1474: }
                   1475: 
                   1476: 
                   1477: int
                   1478: Curl_os400_inflateEnd(z_streamp strm)
                   1479: 
                   1480: {
                   1481:   z_const char * msgb4 = strm->msg;
                   1482:   int ret;
                   1483: 
                   1484:   ret = inflateEnd(strm);
                   1485: 
                   1486:   if(strm->msg != msgb4)
                   1487:     strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
                   1488: 
                   1489:   return ret;
                   1490: }
                   1491: 
                   1492: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>