Return to os400sys.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / packages / OS400 |
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