Annotation of embedaddon/curl/packages/OS400/os400sys.c, revision 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 = ∈
! 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>