113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci * 2413498266Sopenharmony_ci ***************************************************************************/ 2513498266Sopenharmony_ci 2613498266Sopenharmony_ci/* OS/400 additional support. */ 2713498266Sopenharmony_ci 2813498266Sopenharmony_ci#include <curl/curl.h> 2913498266Sopenharmony_ci#include "config-os400.h" /* Not curl_setup.h: we only need some defines. */ 3013498266Sopenharmony_ci 3113498266Sopenharmony_ci#include <sys/types.h> 3213498266Sopenharmony_ci#include <sys/socket.h> 3313498266Sopenharmony_ci#include <sys/un.h> 3413498266Sopenharmony_ci 3513498266Sopenharmony_ci#include <stdlib.h> 3613498266Sopenharmony_ci#include <stddef.h> 3713498266Sopenharmony_ci#include <string.h> 3813498266Sopenharmony_ci#include <pthread.h> 3913498266Sopenharmony_ci#include <netdb.h> 4013498266Sopenharmony_ci#include <qadrt.h> 4113498266Sopenharmony_ci#include <errno.h> 4213498266Sopenharmony_ci 4313498266Sopenharmony_ci#ifdef HAVE_LIBZ 4413498266Sopenharmony_ci#include <zlib.h> 4513498266Sopenharmony_ci#endif 4613498266Sopenharmony_ci 4713498266Sopenharmony_ci#ifdef HAVE_GSSAPI 4813498266Sopenharmony_ci#include <gssapi.h> 4913498266Sopenharmony_ci#endif 5013498266Sopenharmony_ci 5113498266Sopenharmony_ci#ifndef CURL_DISABLE_LDAP 5213498266Sopenharmony_ci#include <ldap.h> 5313498266Sopenharmony_ci#endif 5413498266Sopenharmony_ci 5513498266Sopenharmony_ci#include <netinet/in.h> 5613498266Sopenharmony_ci#include <arpa/inet.h> 5713498266Sopenharmony_ci 5813498266Sopenharmony_ci#include "os400sys.h" 5913498266Sopenharmony_ci 6013498266Sopenharmony_ci/** 6113498266Sopenharmony_ci*** QADRT OS/400 ASCII runtime defines only the most used procedures, but a 6213498266Sopenharmony_ci*** lot of them are not supported. This module implements ASCII wrappers for 6313498266Sopenharmony_ci*** those that are used by libcurl, but not defined by QADRT. 6413498266Sopenharmony_ci**/ 6513498266Sopenharmony_ci 6613498266Sopenharmony_ci#pragma convert(0) /* Restore EBCDIC. */ 6713498266Sopenharmony_ci 6813498266Sopenharmony_ci#define MIN_BYTE_GAIN 1024 /* Minimum gain when shortening a buffer. */ 6913498266Sopenharmony_ci 7013498266Sopenharmony_cistruct buffer_t { 7113498266Sopenharmony_ci unsigned long size; /* Buffer size. */ 7213498266Sopenharmony_ci char *buf; /* Buffer address. */ 7313498266Sopenharmony_ci}; 7413498266Sopenharmony_ci 7513498266Sopenharmony_ci 7613498266Sopenharmony_cistatic char *buffer_undef(localkey_t key, long size); 7713498266Sopenharmony_cistatic char *buffer_threaded(localkey_t key, long size); 7813498266Sopenharmony_cistatic char *buffer_unthreaded(localkey_t key, long size); 7913498266Sopenharmony_ci 8013498266Sopenharmony_cistatic pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 8113498266Sopenharmony_cistatic pthread_key_t thdkey; 8213498266Sopenharmony_cistatic struct buffer_t *locbufs; 8313498266Sopenharmony_ci 8413498266Sopenharmony_cichar *(*Curl_thread_buffer)(localkey_t key, long size) = buffer_undef; 8513498266Sopenharmony_ci 8613498266Sopenharmony_cistatic void thdbufdestroy(void *private) 8713498266Sopenharmony_ci{ 8813498266Sopenharmony_ci if(private) { 8913498266Sopenharmony_ci struct buffer_t *p = (struct buffer_t *) private; 9013498266Sopenharmony_ci localkey_t i; 9113498266Sopenharmony_ci 9213498266Sopenharmony_ci for(i = (localkey_t) 0; i < LK_LAST; i++) { 9313498266Sopenharmony_ci free(p->buf); 9413498266Sopenharmony_ci p++; 9513498266Sopenharmony_ci } 9613498266Sopenharmony_ci 9713498266Sopenharmony_ci free(private); 9813498266Sopenharmony_ci } 9913498266Sopenharmony_ci} 10013498266Sopenharmony_ci 10113498266Sopenharmony_ci 10213498266Sopenharmony_cistatic void 10313498266Sopenharmony_citerminate(void) 10413498266Sopenharmony_ci{ 10513498266Sopenharmony_ci if(Curl_thread_buffer == buffer_threaded) { 10613498266Sopenharmony_ci locbufs = pthread_getspecific(thdkey); 10713498266Sopenharmony_ci pthread_setspecific(thdkey, (void *) NULL); 10813498266Sopenharmony_ci pthread_key_delete(thdkey); 10913498266Sopenharmony_ci } 11013498266Sopenharmony_ci 11113498266Sopenharmony_ci if(Curl_thread_buffer != buffer_undef) { 11213498266Sopenharmony_ci thdbufdestroy((void *) locbufs); 11313498266Sopenharmony_ci locbufs = (struct buffer_t *) NULL; 11413498266Sopenharmony_ci } 11513498266Sopenharmony_ci 11613498266Sopenharmony_ci Curl_thread_buffer = buffer_undef; 11713498266Sopenharmony_ci} 11813498266Sopenharmony_ci 11913498266Sopenharmony_ci 12013498266Sopenharmony_cistatic char * 12113498266Sopenharmony_ciget_buffer(struct buffer_t *buf, long size) 12213498266Sopenharmony_ci{ 12313498266Sopenharmony_ci char *cp; 12413498266Sopenharmony_ci 12513498266Sopenharmony_ci /* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long. 12613498266Sopenharmony_ci Return the buffer address. */ 12713498266Sopenharmony_ci 12813498266Sopenharmony_ci if(size < 0) 12913498266Sopenharmony_ci return buf->buf; 13013498266Sopenharmony_ci 13113498266Sopenharmony_ci if(!buf->buf) { 13213498266Sopenharmony_ci buf->buf = malloc(size); 13313498266Sopenharmony_ci if(buf->buf) 13413498266Sopenharmony_ci buf->size = size; 13513498266Sopenharmony_ci 13613498266Sopenharmony_ci return buf->buf; 13713498266Sopenharmony_ci } 13813498266Sopenharmony_ci 13913498266Sopenharmony_ci if((unsigned long) size <= buf->size) { 14013498266Sopenharmony_ci /* Shorten the buffer only if it frees a significant byte count. This 14113498266Sopenharmony_ci avoids some realloc() overhead. */ 14213498266Sopenharmony_ci 14313498266Sopenharmony_ci if(buf->size - size < MIN_BYTE_GAIN) 14413498266Sopenharmony_ci return buf->buf; 14513498266Sopenharmony_ci } 14613498266Sopenharmony_ci 14713498266Sopenharmony_ci /* Resize the buffer. */ 14813498266Sopenharmony_ci 14913498266Sopenharmony_ci cp = realloc(buf->buf, size); 15013498266Sopenharmony_ci if(cp) { 15113498266Sopenharmony_ci buf->buf = cp; 15213498266Sopenharmony_ci buf->size = size; 15313498266Sopenharmony_ci } 15413498266Sopenharmony_ci else if(size <= buf->size) 15513498266Sopenharmony_ci cp = buf->buf; 15613498266Sopenharmony_ci 15713498266Sopenharmony_ci return cp; 15813498266Sopenharmony_ci} 15913498266Sopenharmony_ci 16013498266Sopenharmony_ci 16113498266Sopenharmony_cistatic char * 16213498266Sopenharmony_cibuffer_unthreaded(localkey_t key, long size) 16313498266Sopenharmony_ci{ 16413498266Sopenharmony_ci return get_buffer(locbufs + key, size); 16513498266Sopenharmony_ci} 16613498266Sopenharmony_ci 16713498266Sopenharmony_ci 16813498266Sopenharmony_cistatic char * 16913498266Sopenharmony_cibuffer_threaded(localkey_t key, long size) 17013498266Sopenharmony_ci{ 17113498266Sopenharmony_ci struct buffer_t *bufs; 17213498266Sopenharmony_ci 17313498266Sopenharmony_ci /* Get the buffer for the given local key in the current thread, and 17413498266Sopenharmony_ci make sure it is at least `size'-byte long. Set `size' to < 0 to get 17513498266Sopenharmony_ci its address only. */ 17613498266Sopenharmony_ci 17713498266Sopenharmony_ci bufs = (struct buffer_t *) pthread_getspecific(thdkey); 17813498266Sopenharmony_ci 17913498266Sopenharmony_ci if(!bufs) { 18013498266Sopenharmony_ci if(size < 0) 18113498266Sopenharmony_ci return (char *) NULL; /* No buffer yet. */ 18213498266Sopenharmony_ci 18313498266Sopenharmony_ci /* Allocate buffer descriptors for the current thread. */ 18413498266Sopenharmony_ci 18513498266Sopenharmony_ci bufs = calloc((size_t) LK_LAST, sizeof(*bufs)); 18613498266Sopenharmony_ci if(!bufs) 18713498266Sopenharmony_ci return (char *) NULL; 18813498266Sopenharmony_ci 18913498266Sopenharmony_ci if(pthread_setspecific(thdkey, (void *) bufs)) { 19013498266Sopenharmony_ci free(bufs); 19113498266Sopenharmony_ci return (char *) NULL; 19213498266Sopenharmony_ci } 19313498266Sopenharmony_ci } 19413498266Sopenharmony_ci 19513498266Sopenharmony_ci return get_buffer(bufs + key, size); 19613498266Sopenharmony_ci} 19713498266Sopenharmony_ci 19813498266Sopenharmony_ci 19913498266Sopenharmony_cistatic char * 20013498266Sopenharmony_cibuffer_undef(localkey_t key, long size) 20113498266Sopenharmony_ci{ 20213498266Sopenharmony_ci /* Define the buffer system, get the buffer for the given local key in 20313498266Sopenharmony_ci the current thread, and make sure it is at least `size'-byte long. 20413498266Sopenharmony_ci Set `size' to < 0 to get its address only. */ 20513498266Sopenharmony_ci 20613498266Sopenharmony_ci pthread_mutex_lock(&mutex); 20713498266Sopenharmony_ci 20813498266Sopenharmony_ci /* Determine if we can use pthread-specific data. */ 20913498266Sopenharmony_ci 21013498266Sopenharmony_ci if(Curl_thread_buffer == buffer_undef) { /* If unchanged during lock. */ 21113498266Sopenharmony_ci if(!pthread_key_create(&thdkey, thdbufdestroy)) 21213498266Sopenharmony_ci Curl_thread_buffer = buffer_threaded; 21313498266Sopenharmony_ci else { 21413498266Sopenharmony_ci locbufs = calloc((size_t) LK_LAST, sizeof(*locbufs)); 21513498266Sopenharmony_ci if(!locbufs) { 21613498266Sopenharmony_ci pthread_mutex_unlock(&mutex); 21713498266Sopenharmony_ci return (char *) NULL; 21813498266Sopenharmony_ci } 21913498266Sopenharmony_ci else 22013498266Sopenharmony_ci Curl_thread_buffer = buffer_unthreaded; 22113498266Sopenharmony_ci } 22213498266Sopenharmony_ci 22313498266Sopenharmony_ci atexit(terminate); 22413498266Sopenharmony_ci } 22513498266Sopenharmony_ci 22613498266Sopenharmony_ci pthread_mutex_unlock(&mutex); 22713498266Sopenharmony_ci return Curl_thread_buffer(key, size); 22813498266Sopenharmony_ci} 22913498266Sopenharmony_ci 23013498266Sopenharmony_ci 23113498266Sopenharmony_cistatic char * 23213498266Sopenharmony_ciset_thread_string(localkey_t key, const char *s) 23313498266Sopenharmony_ci{ 23413498266Sopenharmony_ci int i; 23513498266Sopenharmony_ci char *cp; 23613498266Sopenharmony_ci 23713498266Sopenharmony_ci if(!s) 23813498266Sopenharmony_ci return (char *) NULL; 23913498266Sopenharmony_ci 24013498266Sopenharmony_ci i = strlen(s) + 1; 24113498266Sopenharmony_ci cp = Curl_thread_buffer(key, MAX_CONV_EXPANSION * i + 1); 24213498266Sopenharmony_ci 24313498266Sopenharmony_ci if(cp) { 24413498266Sopenharmony_ci i = QadrtConvertE2A(cp, s, MAX_CONV_EXPANSION * i, i); 24513498266Sopenharmony_ci cp[i] = '\0'; 24613498266Sopenharmony_ci } 24713498266Sopenharmony_ci 24813498266Sopenharmony_ci return cp; 24913498266Sopenharmony_ci} 25013498266Sopenharmony_ci 25113498266Sopenharmony_ci 25213498266Sopenharmony_ciint 25313498266Sopenharmony_ciCurl_getnameinfo_a(const struct sockaddr *sa, socklen_t salen, 25413498266Sopenharmony_ci char *nodename, socklen_t nodenamelen, 25513498266Sopenharmony_ci char *servname, socklen_t servnamelen, 25613498266Sopenharmony_ci int flags) 25713498266Sopenharmony_ci{ 25813498266Sopenharmony_ci char *enodename = NULL; 25913498266Sopenharmony_ci char *eservname = NULL; 26013498266Sopenharmony_ci int status; 26113498266Sopenharmony_ci 26213498266Sopenharmony_ci if(nodename && nodenamelen) { 26313498266Sopenharmony_ci enodename = malloc(nodenamelen); 26413498266Sopenharmony_ci if(!enodename) 26513498266Sopenharmony_ci return EAI_MEMORY; 26613498266Sopenharmony_ci } 26713498266Sopenharmony_ci 26813498266Sopenharmony_ci if(servname && servnamelen) { 26913498266Sopenharmony_ci eservname = malloc(servnamelen); 27013498266Sopenharmony_ci if(!eservname) { 27113498266Sopenharmony_ci free(enodename); 27213498266Sopenharmony_ci return EAI_MEMORY; 27313498266Sopenharmony_ci } 27413498266Sopenharmony_ci } 27513498266Sopenharmony_ci 27613498266Sopenharmony_ci status = getnameinfo(sa, salen, enodename, nodenamelen, 27713498266Sopenharmony_ci eservname, servnamelen, flags); 27813498266Sopenharmony_ci 27913498266Sopenharmony_ci if(!status) { 28013498266Sopenharmony_ci int i; 28113498266Sopenharmony_ci if(enodename) { 28213498266Sopenharmony_ci i = QadrtConvertE2A(nodename, enodename, 28313498266Sopenharmony_ci nodenamelen - 1, strlen(enodename)); 28413498266Sopenharmony_ci nodename[i] = '\0'; 28513498266Sopenharmony_ci } 28613498266Sopenharmony_ci 28713498266Sopenharmony_ci if(eservname) { 28813498266Sopenharmony_ci i = QadrtConvertE2A(servname, eservname, 28913498266Sopenharmony_ci servnamelen - 1, strlen(eservname)); 29013498266Sopenharmony_ci servname[i] = '\0'; 29113498266Sopenharmony_ci } 29213498266Sopenharmony_ci } 29313498266Sopenharmony_ci 29413498266Sopenharmony_ci free(enodename); 29513498266Sopenharmony_ci free(eservname); 29613498266Sopenharmony_ci return status; 29713498266Sopenharmony_ci} 29813498266Sopenharmony_ci 29913498266Sopenharmony_ciint 30013498266Sopenharmony_ciCurl_getaddrinfo_a(const char *nodename, const char *servname, 30113498266Sopenharmony_ci const struct addrinfo *hints, 30213498266Sopenharmony_ci struct addrinfo **res) 30313498266Sopenharmony_ci{ 30413498266Sopenharmony_ci char *enodename; 30513498266Sopenharmony_ci char *eservname; 30613498266Sopenharmony_ci int status; 30713498266Sopenharmony_ci int i; 30813498266Sopenharmony_ci 30913498266Sopenharmony_ci enodename = (char *) NULL; 31013498266Sopenharmony_ci eservname = (char *) NULL; 31113498266Sopenharmony_ci 31213498266Sopenharmony_ci if(nodename) { 31313498266Sopenharmony_ci i = strlen(nodename); 31413498266Sopenharmony_ci 31513498266Sopenharmony_ci enodename = malloc(i + 1); 31613498266Sopenharmony_ci if(!enodename) 31713498266Sopenharmony_ci return EAI_MEMORY; 31813498266Sopenharmony_ci 31913498266Sopenharmony_ci i = QadrtConvertA2E(enodename, nodename, i, i); 32013498266Sopenharmony_ci enodename[i] = '\0'; 32113498266Sopenharmony_ci } 32213498266Sopenharmony_ci 32313498266Sopenharmony_ci if(servname) { 32413498266Sopenharmony_ci i = strlen(servname); 32513498266Sopenharmony_ci 32613498266Sopenharmony_ci eservname = malloc(i + 1); 32713498266Sopenharmony_ci if(!eservname) { 32813498266Sopenharmony_ci free(enodename); 32913498266Sopenharmony_ci return EAI_MEMORY; 33013498266Sopenharmony_ci } 33113498266Sopenharmony_ci 33213498266Sopenharmony_ci QadrtConvertA2E(eservname, servname, i, i); 33313498266Sopenharmony_ci eservname[i] = '\0'; 33413498266Sopenharmony_ci } 33513498266Sopenharmony_ci 33613498266Sopenharmony_ci status = getaddrinfo(enodename, eservname, hints, res); 33713498266Sopenharmony_ci free(enodename); 33813498266Sopenharmony_ci free(eservname); 33913498266Sopenharmony_ci return status; 34013498266Sopenharmony_ci} 34113498266Sopenharmony_ci 34213498266Sopenharmony_ci#ifdef HAVE_GSSAPI 34313498266Sopenharmony_ci 34413498266Sopenharmony_ci/* ASCII wrappers for the GSSAPI procedures. */ 34513498266Sopenharmony_ci 34613498266Sopenharmony_cistatic int 34713498266Sopenharmony_ciCurl_gss_convert_in_place(OM_uint32 *minor_status, gss_buffer_t buf) 34813498266Sopenharmony_ci{ 34913498266Sopenharmony_ci unsigned int i = buf->length; 35013498266Sopenharmony_ci 35113498266Sopenharmony_ci /* Convert `buf' in place, from EBCDIC to ASCII. 35213498266Sopenharmony_ci If error, release the buffer and return -1. Else return 0. */ 35313498266Sopenharmony_ci 35413498266Sopenharmony_ci if(i) { 35513498266Sopenharmony_ci char *t = malloc(i); 35613498266Sopenharmony_ci if(!t) { 35713498266Sopenharmony_ci gss_release_buffer(minor_status, buf); 35813498266Sopenharmony_ci 35913498266Sopenharmony_ci if(minor_status) 36013498266Sopenharmony_ci *minor_status = ENOMEM; 36113498266Sopenharmony_ci 36213498266Sopenharmony_ci return -1; 36313498266Sopenharmony_ci } 36413498266Sopenharmony_ci 36513498266Sopenharmony_ci QadrtConvertE2A(t, buf->value, i, i); 36613498266Sopenharmony_ci memcpy(buf->value, t, i); 36713498266Sopenharmony_ci free(t); 36813498266Sopenharmony_ci } 36913498266Sopenharmony_ci 37013498266Sopenharmony_ci return 0; 37113498266Sopenharmony_ci} 37213498266Sopenharmony_ci 37313498266Sopenharmony_ci 37413498266Sopenharmony_ciOM_uint32 37513498266Sopenharmony_ciCurl_gss_import_name_a(OM_uint32 *minor_status, gss_buffer_t in_name, 37613498266Sopenharmony_ci gss_OID in_name_type, gss_name_t *out_name) 37713498266Sopenharmony_ci{ 37813498266Sopenharmony_ci OM_uint32 rc; 37913498266Sopenharmony_ci unsigned int i; 38013498266Sopenharmony_ci gss_buffer_desc in; 38113498266Sopenharmony_ci 38213498266Sopenharmony_ci if(!in_name || !in_name->value || !in_name->length) 38313498266Sopenharmony_ci return gss_import_name(minor_status, in_name, in_name_type, out_name); 38413498266Sopenharmony_ci 38513498266Sopenharmony_ci memcpy((char *) &in, (char *) in_name, sizeof(in)); 38613498266Sopenharmony_ci i = in.length; 38713498266Sopenharmony_ci 38813498266Sopenharmony_ci in.value = malloc(i + 1); 38913498266Sopenharmony_ci if(!in.value) { 39013498266Sopenharmony_ci if(minor_status) 39113498266Sopenharmony_ci *minor_status = ENOMEM; 39213498266Sopenharmony_ci 39313498266Sopenharmony_ci return GSS_S_FAILURE; 39413498266Sopenharmony_ci } 39513498266Sopenharmony_ci 39613498266Sopenharmony_ci QadrtConvertA2E(in.value, in_name->value, i, i); 39713498266Sopenharmony_ci ((char *) in.value)[i] = '\0'; 39813498266Sopenharmony_ci rc = gss_import_name(minor_status, &in, in_name_type, out_name); 39913498266Sopenharmony_ci free(in.value); 40013498266Sopenharmony_ci return rc; 40113498266Sopenharmony_ci} 40213498266Sopenharmony_ci 40313498266Sopenharmony_ciOM_uint32 40413498266Sopenharmony_ciCurl_gss_display_status_a(OM_uint32 *minor_status, OM_uint32 status_value, 40513498266Sopenharmony_ci int status_type, gss_OID mech_type, 40613498266Sopenharmony_ci gss_msg_ctx_t *message_context, 40713498266Sopenharmony_ci gss_buffer_t status_string) 40813498266Sopenharmony_ci{ 40913498266Sopenharmony_ci int rc; 41013498266Sopenharmony_ci 41113498266Sopenharmony_ci rc = gss_display_status(minor_status, status_value, status_type, 41213498266Sopenharmony_ci mech_type, message_context, status_string); 41313498266Sopenharmony_ci 41413498266Sopenharmony_ci if(rc != GSS_S_COMPLETE || !status_string || 41513498266Sopenharmony_ci !status_string->length || !status_string->value) 41613498266Sopenharmony_ci return rc; 41713498266Sopenharmony_ci 41813498266Sopenharmony_ci /* No way to allocate a buffer here, because it will be released by 41913498266Sopenharmony_ci gss_release_buffer(). The solution is to overwrite the EBCDIC buffer 42013498266Sopenharmony_ci with ASCII to return it. */ 42113498266Sopenharmony_ci 42213498266Sopenharmony_ci if(Curl_gss_convert_in_place(minor_status, status_string)) 42313498266Sopenharmony_ci return GSS_S_FAILURE; 42413498266Sopenharmony_ci 42513498266Sopenharmony_ci return rc; 42613498266Sopenharmony_ci} 42713498266Sopenharmony_ci 42813498266Sopenharmony_ciOM_uint32 42913498266Sopenharmony_ciCurl_gss_init_sec_context_a(OM_uint32 *minor_status, 43013498266Sopenharmony_ci gss_cred_id_t cred_handle, 43113498266Sopenharmony_ci gss_ctx_id_t *context_handle, 43213498266Sopenharmony_ci gss_name_t target_name, gss_OID mech_type, 43313498266Sopenharmony_ci gss_flags_t req_flags, OM_uint32 time_req, 43413498266Sopenharmony_ci gss_channel_bindings_t input_chan_bindings, 43513498266Sopenharmony_ci gss_buffer_t input_token, 43613498266Sopenharmony_ci gss_OID *actual_mech_type, 43713498266Sopenharmony_ci gss_buffer_t output_token, gss_flags_t *ret_flags, 43813498266Sopenharmony_ci OM_uint32 *time_rec) 43913498266Sopenharmony_ci{ 44013498266Sopenharmony_ci int rc; 44113498266Sopenharmony_ci gss_buffer_desc in; 44213498266Sopenharmony_ci gss_buffer_t inp; 44313498266Sopenharmony_ci 44413498266Sopenharmony_ci in.value = NULL; 44513498266Sopenharmony_ci inp = input_token; 44613498266Sopenharmony_ci 44713498266Sopenharmony_ci if(inp) { 44813498266Sopenharmony_ci if(inp->length && inp->value) { 44913498266Sopenharmony_ci unsigned int i = inp->length; 45013498266Sopenharmony_ci 45113498266Sopenharmony_ci in.value = malloc(i + 1); 45213498266Sopenharmony_ci if(!in.value) { 45313498266Sopenharmony_ci if(minor_status) 45413498266Sopenharmony_ci *minor_status = ENOMEM; 45513498266Sopenharmony_ci 45613498266Sopenharmony_ci return GSS_S_FAILURE; 45713498266Sopenharmony_ci } 45813498266Sopenharmony_ci 45913498266Sopenharmony_ci QadrtConvertA2E(in.value, input_token->value, i, i); 46013498266Sopenharmony_ci ((char *) in.value)[i] = '\0'; 46113498266Sopenharmony_ci in.length = i; 46213498266Sopenharmony_ci inp = ∈ 46313498266Sopenharmony_ci } 46413498266Sopenharmony_ci } 46513498266Sopenharmony_ci 46613498266Sopenharmony_ci rc = gss_init_sec_context(minor_status, cred_handle, context_handle, 46713498266Sopenharmony_ci target_name, mech_type, req_flags, time_req, 46813498266Sopenharmony_ci input_chan_bindings, inp, actual_mech_type, 46913498266Sopenharmony_ci output_token, ret_flags, time_rec); 47013498266Sopenharmony_ci free(in.value); 47113498266Sopenharmony_ci 47213498266Sopenharmony_ci if(rc != GSS_S_COMPLETE || !output_token || 47313498266Sopenharmony_ci !output_token->length || !output_token->value) 47413498266Sopenharmony_ci return rc; 47513498266Sopenharmony_ci 47613498266Sopenharmony_ci /* No way to allocate a buffer here, because it will be released by 47713498266Sopenharmony_ci gss_release_buffer(). The solution is to overwrite the EBCDIC buffer 47813498266Sopenharmony_ci with ASCII to return it. */ 47913498266Sopenharmony_ci 48013498266Sopenharmony_ci if(Curl_gss_convert_in_place(minor_status, output_token)) 48113498266Sopenharmony_ci return GSS_S_FAILURE; 48213498266Sopenharmony_ci 48313498266Sopenharmony_ci return rc; 48413498266Sopenharmony_ci} 48513498266Sopenharmony_ci 48613498266Sopenharmony_ci 48713498266Sopenharmony_ciOM_uint32 48813498266Sopenharmony_ciCurl_gss_delete_sec_context_a(OM_uint32 *minor_status, 48913498266Sopenharmony_ci gss_ctx_id_t *context_handle, 49013498266Sopenharmony_ci gss_buffer_t output_token) 49113498266Sopenharmony_ci{ 49213498266Sopenharmony_ci OM_uint32 rc; 49313498266Sopenharmony_ci 49413498266Sopenharmony_ci rc = gss_delete_sec_context(minor_status, context_handle, output_token); 49513498266Sopenharmony_ci 49613498266Sopenharmony_ci if(rc != GSS_S_COMPLETE || !output_token || 49713498266Sopenharmony_ci !output_token->length || !output_token->value) 49813498266Sopenharmony_ci return rc; 49913498266Sopenharmony_ci 50013498266Sopenharmony_ci /* No way to allocate a buffer here, because it will be released by 50113498266Sopenharmony_ci gss_release_buffer(). The solution is to overwrite the EBCDIC buffer 50213498266Sopenharmony_ci with ASCII to return it. */ 50313498266Sopenharmony_ci 50413498266Sopenharmony_ci if(Curl_gss_convert_in_place(minor_status, output_token)) 50513498266Sopenharmony_ci return GSS_S_FAILURE; 50613498266Sopenharmony_ci 50713498266Sopenharmony_ci return rc; 50813498266Sopenharmony_ci} 50913498266Sopenharmony_ci 51013498266Sopenharmony_ci#endif /* HAVE_GSSAPI */ 51113498266Sopenharmony_ci 51213498266Sopenharmony_ci#ifndef CURL_DISABLE_LDAP 51313498266Sopenharmony_ci 51413498266Sopenharmony_ci/* ASCII wrappers for the LDAP procedures. */ 51513498266Sopenharmony_ci 51613498266Sopenharmony_civoid * 51713498266Sopenharmony_ciCurl_ldap_init_a(char *host, int port) 51813498266Sopenharmony_ci{ 51913498266Sopenharmony_ci size_t i; 52013498266Sopenharmony_ci char *ehost; 52113498266Sopenharmony_ci void *result; 52213498266Sopenharmony_ci 52313498266Sopenharmony_ci if(!host) 52413498266Sopenharmony_ci return (void *) ldap_init(host, port); 52513498266Sopenharmony_ci 52613498266Sopenharmony_ci i = strlen(host); 52713498266Sopenharmony_ci 52813498266Sopenharmony_ci ehost = malloc(i + 1); 52913498266Sopenharmony_ci if(!ehost) 53013498266Sopenharmony_ci return (void *) NULL; 53113498266Sopenharmony_ci 53213498266Sopenharmony_ci QadrtConvertA2E(ehost, host, i, i); 53313498266Sopenharmony_ci ehost[i] = '\0'; 53413498266Sopenharmony_ci result = (void *) ldap_init(ehost, port); 53513498266Sopenharmony_ci free(ehost); 53613498266Sopenharmony_ci return result; 53713498266Sopenharmony_ci} 53813498266Sopenharmony_ci 53913498266Sopenharmony_ciint 54013498266Sopenharmony_ciCurl_ldap_simple_bind_s_a(void *ld, char *dn, char *passwd) 54113498266Sopenharmony_ci{ 54213498266Sopenharmony_ci int i; 54313498266Sopenharmony_ci char *edn; 54413498266Sopenharmony_ci char *epasswd; 54513498266Sopenharmony_ci 54613498266Sopenharmony_ci edn = (char *) NULL; 54713498266Sopenharmony_ci epasswd = (char *) NULL; 54813498266Sopenharmony_ci 54913498266Sopenharmony_ci if(dn) { 55013498266Sopenharmony_ci i = strlen(dn); 55113498266Sopenharmony_ci 55213498266Sopenharmony_ci edn = malloc(i + 1); 55313498266Sopenharmony_ci if(!edn) 55413498266Sopenharmony_ci return LDAP_NO_MEMORY; 55513498266Sopenharmony_ci 55613498266Sopenharmony_ci QadrtConvertA2E(edn, dn, i, i); 55713498266Sopenharmony_ci edn[i] = '\0'; 55813498266Sopenharmony_ci } 55913498266Sopenharmony_ci 56013498266Sopenharmony_ci if(passwd) { 56113498266Sopenharmony_ci i = strlen(passwd); 56213498266Sopenharmony_ci 56313498266Sopenharmony_ci epasswd = malloc(i + 1); 56413498266Sopenharmony_ci if(!epasswd) { 56513498266Sopenharmony_ci free(edn); 56613498266Sopenharmony_ci return LDAP_NO_MEMORY; 56713498266Sopenharmony_ci } 56813498266Sopenharmony_ci 56913498266Sopenharmony_ci QadrtConvertA2E(epasswd, passwd, i, i); 57013498266Sopenharmony_ci epasswd[i] = '\0'; 57113498266Sopenharmony_ci } 57213498266Sopenharmony_ci 57313498266Sopenharmony_ci i = ldap_simple_bind_s(ld, edn, epasswd); 57413498266Sopenharmony_ci free(epasswd); 57513498266Sopenharmony_ci free(edn); 57613498266Sopenharmony_ci return i; 57713498266Sopenharmony_ci} 57813498266Sopenharmony_ci 57913498266Sopenharmony_ciint 58013498266Sopenharmony_ciCurl_ldap_search_s_a(void *ld, char *base, int scope, char *filter, 58113498266Sopenharmony_ci char **attrs, int attrsonly, LDAPMessage **res) 58213498266Sopenharmony_ci{ 58313498266Sopenharmony_ci int i; 58413498266Sopenharmony_ci int j; 58513498266Sopenharmony_ci char *ebase; 58613498266Sopenharmony_ci char *efilter; 58713498266Sopenharmony_ci char **eattrs; 58813498266Sopenharmony_ci int status; 58913498266Sopenharmony_ci 59013498266Sopenharmony_ci ebase = (char *) NULL; 59113498266Sopenharmony_ci efilter = (char *) NULL; 59213498266Sopenharmony_ci eattrs = (char **) NULL; 59313498266Sopenharmony_ci status = LDAP_SUCCESS; 59413498266Sopenharmony_ci 59513498266Sopenharmony_ci if(base) { 59613498266Sopenharmony_ci i = strlen(base); 59713498266Sopenharmony_ci 59813498266Sopenharmony_ci ebase = malloc(i + 1); 59913498266Sopenharmony_ci if(!ebase) 60013498266Sopenharmony_ci status = LDAP_NO_MEMORY; 60113498266Sopenharmony_ci else { 60213498266Sopenharmony_ci QadrtConvertA2E(ebase, base, i, i); 60313498266Sopenharmony_ci ebase[i] = '\0'; 60413498266Sopenharmony_ci } 60513498266Sopenharmony_ci } 60613498266Sopenharmony_ci 60713498266Sopenharmony_ci if(filter && status == LDAP_SUCCESS) { 60813498266Sopenharmony_ci i = strlen(filter); 60913498266Sopenharmony_ci 61013498266Sopenharmony_ci efilter = malloc(i + 1); 61113498266Sopenharmony_ci if(!efilter) 61213498266Sopenharmony_ci status = LDAP_NO_MEMORY; 61313498266Sopenharmony_ci else { 61413498266Sopenharmony_ci QadrtConvertA2E(efilter, filter, i, i); 61513498266Sopenharmony_ci efilter[i] = '\0'; 61613498266Sopenharmony_ci } 61713498266Sopenharmony_ci } 61813498266Sopenharmony_ci 61913498266Sopenharmony_ci if(attrs && status == LDAP_SUCCESS) { 62013498266Sopenharmony_ci for(i = 0; attrs[i++];) 62113498266Sopenharmony_ci ; 62213498266Sopenharmony_ci 62313498266Sopenharmony_ci eattrs = calloc(i, sizeof(*eattrs)); 62413498266Sopenharmony_ci if(!eattrs) 62513498266Sopenharmony_ci status = LDAP_NO_MEMORY; 62613498266Sopenharmony_ci else { 62713498266Sopenharmony_ci for(j = 0; attrs[j]; j++) { 62813498266Sopenharmony_ci i = strlen(attrs[j]); 62913498266Sopenharmony_ci 63013498266Sopenharmony_ci eattrs[j] = malloc(i + 1); 63113498266Sopenharmony_ci if(!eattrs[j]) { 63213498266Sopenharmony_ci status = LDAP_NO_MEMORY; 63313498266Sopenharmony_ci break; 63413498266Sopenharmony_ci } 63513498266Sopenharmony_ci 63613498266Sopenharmony_ci QadrtConvertA2E(eattrs[j], attrs[j], i, i); 63713498266Sopenharmony_ci eattrs[j][i] = '\0'; 63813498266Sopenharmony_ci } 63913498266Sopenharmony_ci } 64013498266Sopenharmony_ci } 64113498266Sopenharmony_ci 64213498266Sopenharmony_ci if(status == LDAP_SUCCESS) 64313498266Sopenharmony_ci status = ldap_search_s(ld, ebase? ebase: "", scope, 64413498266Sopenharmony_ci efilter? efilter: "(objectclass=*)", 64513498266Sopenharmony_ci eattrs, attrsonly, res); 64613498266Sopenharmony_ci 64713498266Sopenharmony_ci if(eattrs) { 64813498266Sopenharmony_ci for(j = 0; eattrs[j]; j++) 64913498266Sopenharmony_ci free(eattrs[j]); 65013498266Sopenharmony_ci 65113498266Sopenharmony_ci free(eattrs); 65213498266Sopenharmony_ci } 65313498266Sopenharmony_ci 65413498266Sopenharmony_ci free(efilter); 65513498266Sopenharmony_ci free(ebase); 65613498266Sopenharmony_ci return status; 65713498266Sopenharmony_ci} 65813498266Sopenharmony_ci 65913498266Sopenharmony_ci 66013498266Sopenharmony_cistruct berval ** 66113498266Sopenharmony_ciCurl_ldap_get_values_len_a(void *ld, LDAPMessage *entry, const char *attr) 66213498266Sopenharmony_ci{ 66313498266Sopenharmony_ci char *cp; 66413498266Sopenharmony_ci struct berval **result; 66513498266Sopenharmony_ci 66613498266Sopenharmony_ci cp = (char *) NULL; 66713498266Sopenharmony_ci 66813498266Sopenharmony_ci if(attr) { 66913498266Sopenharmony_ci int i = strlen(attr); 67013498266Sopenharmony_ci 67113498266Sopenharmony_ci cp = malloc(i + 1); 67213498266Sopenharmony_ci if(!cp) { 67313498266Sopenharmony_ci ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL, 67413498266Sopenharmony_ci ldap_err2string(LDAP_NO_MEMORY)); 67513498266Sopenharmony_ci return (struct berval **) NULL; 67613498266Sopenharmony_ci } 67713498266Sopenharmony_ci 67813498266Sopenharmony_ci QadrtConvertA2E(cp, attr, i, i); 67913498266Sopenharmony_ci cp[i] = '\0'; 68013498266Sopenharmony_ci } 68113498266Sopenharmony_ci 68213498266Sopenharmony_ci result = ldap_get_values_len(ld, entry, cp); 68313498266Sopenharmony_ci free(cp); 68413498266Sopenharmony_ci 68513498266Sopenharmony_ci /* Result data are binary in nature, so they haven't been 68613498266Sopenharmony_ci converted to EBCDIC. Therefore do not convert. */ 68713498266Sopenharmony_ci 68813498266Sopenharmony_ci return result; 68913498266Sopenharmony_ci} 69013498266Sopenharmony_ci 69113498266Sopenharmony_cichar * 69213498266Sopenharmony_ciCurl_ldap_err2string_a(int error) 69313498266Sopenharmony_ci{ 69413498266Sopenharmony_ci return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error)); 69513498266Sopenharmony_ci} 69613498266Sopenharmony_ci 69713498266Sopenharmony_cichar * 69813498266Sopenharmony_ciCurl_ldap_get_dn_a(void *ld, LDAPMessage *entry) 69913498266Sopenharmony_ci{ 70013498266Sopenharmony_ci int i; 70113498266Sopenharmony_ci char *cp; 70213498266Sopenharmony_ci char *cp2; 70313498266Sopenharmony_ci 70413498266Sopenharmony_ci cp = ldap_get_dn(ld, entry); 70513498266Sopenharmony_ci 70613498266Sopenharmony_ci if(!cp) 70713498266Sopenharmony_ci return cp; 70813498266Sopenharmony_ci 70913498266Sopenharmony_ci i = strlen(cp); 71013498266Sopenharmony_ci 71113498266Sopenharmony_ci cp2 = malloc(i + 1); 71213498266Sopenharmony_ci if(!cp2) 71313498266Sopenharmony_ci return cp2; 71413498266Sopenharmony_ci 71513498266Sopenharmony_ci QadrtConvertE2A(cp2, cp, i, i); 71613498266Sopenharmony_ci cp2[i] = '\0'; 71713498266Sopenharmony_ci 71813498266Sopenharmony_ci /* No way to allocate a buffer here, because it will be released by 71913498266Sopenharmony_ci ldap_memfree() and ldap_memalloc() does not exist. The solution is to 72013498266Sopenharmony_ci overwrite the EBCDIC buffer with ASCII to return it. */ 72113498266Sopenharmony_ci 72213498266Sopenharmony_ci strcpy(cp, cp2); 72313498266Sopenharmony_ci free(cp2); 72413498266Sopenharmony_ci return cp; 72513498266Sopenharmony_ci} 72613498266Sopenharmony_ci 72713498266Sopenharmony_cichar * 72813498266Sopenharmony_ciCurl_ldap_first_attribute_a(void *ld, 72913498266Sopenharmony_ci LDAPMessage *entry, BerElement **berptr) 73013498266Sopenharmony_ci{ 73113498266Sopenharmony_ci int i; 73213498266Sopenharmony_ci char *cp; 73313498266Sopenharmony_ci char *cp2; 73413498266Sopenharmony_ci 73513498266Sopenharmony_ci cp = ldap_first_attribute(ld, entry, berptr); 73613498266Sopenharmony_ci 73713498266Sopenharmony_ci if(!cp) 73813498266Sopenharmony_ci return cp; 73913498266Sopenharmony_ci 74013498266Sopenharmony_ci i = strlen(cp); 74113498266Sopenharmony_ci 74213498266Sopenharmony_ci cp2 = malloc(i + 1); 74313498266Sopenharmony_ci if(!cp2) 74413498266Sopenharmony_ci return cp2; 74513498266Sopenharmony_ci 74613498266Sopenharmony_ci QadrtConvertE2A(cp2, cp, i, i); 74713498266Sopenharmony_ci cp2[i] = '\0'; 74813498266Sopenharmony_ci 74913498266Sopenharmony_ci /* No way to allocate a buffer here, because it will be released by 75013498266Sopenharmony_ci ldap_memfree() and ldap_memalloc() does not exist. The solution is to 75113498266Sopenharmony_ci overwrite the EBCDIC buffer with ASCII to return it. */ 75213498266Sopenharmony_ci 75313498266Sopenharmony_ci strcpy(cp, cp2); 75413498266Sopenharmony_ci free(cp2); 75513498266Sopenharmony_ci return cp; 75613498266Sopenharmony_ci} 75713498266Sopenharmony_ci 75813498266Sopenharmony_cichar * 75913498266Sopenharmony_ciCurl_ldap_next_attribute_a(void *ld, 76013498266Sopenharmony_ci LDAPMessage *entry, BerElement *berptr) 76113498266Sopenharmony_ci{ 76213498266Sopenharmony_ci int i; 76313498266Sopenharmony_ci char *cp; 76413498266Sopenharmony_ci char *cp2; 76513498266Sopenharmony_ci 76613498266Sopenharmony_ci cp = ldap_next_attribute(ld, entry, berptr); 76713498266Sopenharmony_ci 76813498266Sopenharmony_ci if(!cp) 76913498266Sopenharmony_ci return cp; 77013498266Sopenharmony_ci 77113498266Sopenharmony_ci i = strlen(cp); 77213498266Sopenharmony_ci 77313498266Sopenharmony_ci cp2 = malloc(i + 1); 77413498266Sopenharmony_ci if(!cp2) 77513498266Sopenharmony_ci return cp2; 77613498266Sopenharmony_ci 77713498266Sopenharmony_ci QadrtConvertE2A(cp2, cp, i, i); 77813498266Sopenharmony_ci cp2[i] = '\0'; 77913498266Sopenharmony_ci 78013498266Sopenharmony_ci /* No way to allocate a buffer here, because it will be released by 78113498266Sopenharmony_ci ldap_memfree() and ldap_memalloc() does not exist. The solution is to 78213498266Sopenharmony_ci overwrite the EBCDIC buffer with ASCII to return it. */ 78313498266Sopenharmony_ci 78413498266Sopenharmony_ci strcpy(cp, cp2); 78513498266Sopenharmony_ci free(cp2); 78613498266Sopenharmony_ci return cp; 78713498266Sopenharmony_ci} 78813498266Sopenharmony_ci 78913498266Sopenharmony_ci#endif /* CURL_DISABLE_LDAP */ 79013498266Sopenharmony_ci 79113498266Sopenharmony_cistatic int 79213498266Sopenharmony_cisockaddr2ebcdic(struct sockaddr_storage *dstaddr, 79313498266Sopenharmony_ci const struct sockaddr *srcaddr, int srclen) 79413498266Sopenharmony_ci{ 79513498266Sopenharmony_ci const struct sockaddr_un *srcu; 79613498266Sopenharmony_ci struct sockaddr_un *dstu; 79713498266Sopenharmony_ci unsigned int i; 79813498266Sopenharmony_ci unsigned int dstsize; 79913498266Sopenharmony_ci 80013498266Sopenharmony_ci /* Convert a socket address to job CCSID, if needed. */ 80113498266Sopenharmony_ci 80213498266Sopenharmony_ci if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) + 80313498266Sopenharmony_ci sizeof(srcaddr->sa_family) || srclen > sizeof(*dstaddr)) { 80413498266Sopenharmony_ci errno = EINVAL; 80513498266Sopenharmony_ci return -1; 80613498266Sopenharmony_ci } 80713498266Sopenharmony_ci 80813498266Sopenharmony_ci memcpy((char *) dstaddr, (char *) srcaddr, srclen); 80913498266Sopenharmony_ci 81013498266Sopenharmony_ci switch(srcaddr->sa_family) { 81113498266Sopenharmony_ci 81213498266Sopenharmony_ci case AF_UNIX: 81313498266Sopenharmony_ci srcu = (const struct sockaddr_un *) srcaddr; 81413498266Sopenharmony_ci dstu = (struct sockaddr_un *) dstaddr; 81513498266Sopenharmony_ci dstsize = sizeof(*dstaddr) - offsetof(struct sockaddr_un, sun_path); 81613498266Sopenharmony_ci srclen -= offsetof(struct sockaddr_un, sun_path); 81713498266Sopenharmony_ci i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen); 81813498266Sopenharmony_ci dstu->sun_path[i] = '\0'; 81913498266Sopenharmony_ci srclen = i + offsetof(struct sockaddr_un, sun_path); 82013498266Sopenharmony_ci } 82113498266Sopenharmony_ci 82213498266Sopenharmony_ci return srclen; 82313498266Sopenharmony_ci} 82413498266Sopenharmony_ci 82513498266Sopenharmony_ci 82613498266Sopenharmony_cistatic int 82713498266Sopenharmony_cisockaddr2ascii(struct sockaddr *dstaddr, int dstlen, 82813498266Sopenharmony_ci const struct sockaddr_storage *srcaddr, int srclen) 82913498266Sopenharmony_ci{ 83013498266Sopenharmony_ci const struct sockaddr_un *srcu; 83113498266Sopenharmony_ci struct sockaddr_un *dstu; 83213498266Sopenharmony_ci unsigned int dstsize; 83313498266Sopenharmony_ci 83413498266Sopenharmony_ci /* Convert a socket address to ASCII, if needed. */ 83513498266Sopenharmony_ci 83613498266Sopenharmony_ci if(!srclen) 83713498266Sopenharmony_ci return 0; 83813498266Sopenharmony_ci if(srclen > dstlen) 83913498266Sopenharmony_ci srclen = dstlen; 84013498266Sopenharmony_ci if(!srcaddr || srclen < 0) { 84113498266Sopenharmony_ci errno = EINVAL; 84213498266Sopenharmony_ci return -1; 84313498266Sopenharmony_ci } 84413498266Sopenharmony_ci 84513498266Sopenharmony_ci memcpy((char *) dstaddr, (char *) srcaddr, srclen); 84613498266Sopenharmony_ci 84713498266Sopenharmony_ci if(srclen >= offsetof(struct sockaddr_storage, ss_family) + 84813498266Sopenharmony_ci sizeof(srcaddr->ss_family)) { 84913498266Sopenharmony_ci switch(srcaddr->ss_family) { 85013498266Sopenharmony_ci 85113498266Sopenharmony_ci case AF_UNIX: 85213498266Sopenharmony_ci srcu = (const struct sockaddr_un *) srcaddr; 85313498266Sopenharmony_ci dstu = (struct sockaddr_un *) dstaddr; 85413498266Sopenharmony_ci dstsize = dstlen - offsetof(struct sockaddr_un, sun_path); 85513498266Sopenharmony_ci srclen -= offsetof(struct sockaddr_un, sun_path); 85613498266Sopenharmony_ci if(dstsize > 0 && srclen > 0) { 85713498266Sopenharmony_ci srclen = QadrtConvertE2A(dstu->sun_path, srcu->sun_path, 85813498266Sopenharmony_ci dstsize - 1, srclen); 85913498266Sopenharmony_ci dstu->sun_path[srclen] = '\0'; 86013498266Sopenharmony_ci } 86113498266Sopenharmony_ci srclen += offsetof(struct sockaddr_un, sun_path); 86213498266Sopenharmony_ci } 86313498266Sopenharmony_ci } 86413498266Sopenharmony_ci 86513498266Sopenharmony_ci return srclen; 86613498266Sopenharmony_ci} 86713498266Sopenharmony_ci 86813498266Sopenharmony_ciint 86913498266Sopenharmony_ciCurl_os400_connect(int sd, struct sockaddr *destaddr, int addrlen) 87013498266Sopenharmony_ci{ 87113498266Sopenharmony_ci int i; 87213498266Sopenharmony_ci struct sockaddr_storage laddr; 87313498266Sopenharmony_ci 87413498266Sopenharmony_ci i = sockaddr2ebcdic(&laddr, destaddr, addrlen); 87513498266Sopenharmony_ci 87613498266Sopenharmony_ci if(i < 0) 87713498266Sopenharmony_ci return -1; 87813498266Sopenharmony_ci 87913498266Sopenharmony_ci return connect(sd, (struct sockaddr *) &laddr, i); 88013498266Sopenharmony_ci} 88113498266Sopenharmony_ci 88213498266Sopenharmony_ciint 88313498266Sopenharmony_ciCurl_os400_bind(int sd, struct sockaddr *localaddr, int addrlen) 88413498266Sopenharmony_ci{ 88513498266Sopenharmony_ci int i; 88613498266Sopenharmony_ci struct sockaddr_storage laddr; 88713498266Sopenharmony_ci 88813498266Sopenharmony_ci i = sockaddr2ebcdic(&laddr, localaddr, addrlen); 88913498266Sopenharmony_ci 89013498266Sopenharmony_ci if(i < 0) 89113498266Sopenharmony_ci return -1; 89213498266Sopenharmony_ci 89313498266Sopenharmony_ci return bind(sd, (struct sockaddr *) &laddr, i); 89413498266Sopenharmony_ci} 89513498266Sopenharmony_ci 89613498266Sopenharmony_ciint 89713498266Sopenharmony_ciCurl_os400_sendto(int sd, char *buffer, int buflen, int flags, 89813498266Sopenharmony_ci const struct sockaddr *dstaddr, int addrlen) 89913498266Sopenharmony_ci{ 90013498266Sopenharmony_ci int i; 90113498266Sopenharmony_ci struct sockaddr_storage laddr; 90213498266Sopenharmony_ci 90313498266Sopenharmony_ci i = sockaddr2ebcdic(&laddr, dstaddr, addrlen); 90413498266Sopenharmony_ci 90513498266Sopenharmony_ci if(i < 0) 90613498266Sopenharmony_ci return -1; 90713498266Sopenharmony_ci 90813498266Sopenharmony_ci return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i); 90913498266Sopenharmony_ci} 91013498266Sopenharmony_ci 91113498266Sopenharmony_ciint 91213498266Sopenharmony_ciCurl_os400_recvfrom(int sd, char *buffer, int buflen, int flags, 91313498266Sopenharmony_ci struct sockaddr *fromaddr, int *addrlen) 91413498266Sopenharmony_ci{ 91513498266Sopenharmony_ci int rcvlen; 91613498266Sopenharmony_ci struct sockaddr_storage laddr; 91713498266Sopenharmony_ci int laddrlen = sizeof(laddr); 91813498266Sopenharmony_ci 91913498266Sopenharmony_ci if(!fromaddr || !addrlen || *addrlen <= 0) 92013498266Sopenharmony_ci return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen); 92113498266Sopenharmony_ci 92213498266Sopenharmony_ci laddr.ss_family = AF_UNSPEC; /* To detect if unused. */ 92313498266Sopenharmony_ci rcvlen = recvfrom(sd, buffer, buflen, flags, 92413498266Sopenharmony_ci (struct sockaddr *) &laddr, &laddrlen); 92513498266Sopenharmony_ci 92613498266Sopenharmony_ci if(rcvlen < 0) 92713498266Sopenharmony_ci return rcvlen; 92813498266Sopenharmony_ci 92913498266Sopenharmony_ci if(laddr.ss_family == AF_UNSPEC) 93013498266Sopenharmony_ci laddrlen = 0; 93113498266Sopenharmony_ci else { 93213498266Sopenharmony_ci laddrlen = sockaddr2ascii(fromaddr, *addrlen, &laddr, laddrlen); 93313498266Sopenharmony_ci if(laddrlen < 0) 93413498266Sopenharmony_ci return laddrlen; 93513498266Sopenharmony_ci } 93613498266Sopenharmony_ci *addrlen = laddrlen; 93713498266Sopenharmony_ci return rcvlen; 93813498266Sopenharmony_ci} 93913498266Sopenharmony_ci 94013498266Sopenharmony_ciint 94113498266Sopenharmony_ciCurl_os400_getpeername(int sd, struct sockaddr *addr, int *addrlen) 94213498266Sopenharmony_ci{ 94313498266Sopenharmony_ci struct sockaddr_storage laddr; 94413498266Sopenharmony_ci int laddrlen = sizeof(laddr); 94513498266Sopenharmony_ci int retcode = getpeername(sd, (struct sockaddr *) &laddr, &laddrlen); 94613498266Sopenharmony_ci 94713498266Sopenharmony_ci if(!retcode) { 94813498266Sopenharmony_ci laddrlen = sockaddr2ascii(addr, *addrlen, &laddr, laddrlen); 94913498266Sopenharmony_ci if(laddrlen < 0) 95013498266Sopenharmony_ci return laddrlen; 95113498266Sopenharmony_ci *addrlen = laddrlen; 95213498266Sopenharmony_ci } 95313498266Sopenharmony_ci 95413498266Sopenharmony_ci return retcode; 95513498266Sopenharmony_ci} 95613498266Sopenharmony_ci 95713498266Sopenharmony_ciint 95813498266Sopenharmony_ciCurl_os400_getsockname(int sd, struct sockaddr *addr, int *addrlen) 95913498266Sopenharmony_ci{ 96013498266Sopenharmony_ci struct sockaddr_storage laddr; 96113498266Sopenharmony_ci int laddrlen = sizeof(laddr); 96213498266Sopenharmony_ci int retcode = getsockname(sd, (struct sockaddr *) &laddr, &laddrlen); 96313498266Sopenharmony_ci 96413498266Sopenharmony_ci if(!retcode) { 96513498266Sopenharmony_ci laddrlen = sockaddr2ascii(addr, *addrlen, &laddr, laddrlen); 96613498266Sopenharmony_ci if(laddrlen < 0) 96713498266Sopenharmony_ci return laddrlen; 96813498266Sopenharmony_ci *addrlen = laddrlen; 96913498266Sopenharmony_ci } 97013498266Sopenharmony_ci 97113498266Sopenharmony_ci return retcode; 97213498266Sopenharmony_ci} 97313498266Sopenharmony_ci 97413498266Sopenharmony_ci 97513498266Sopenharmony_ci#ifdef HAVE_LIBZ 97613498266Sopenharmony_ciconst char * 97713498266Sopenharmony_ciCurl_os400_zlibVersion(void) 97813498266Sopenharmony_ci{ 97913498266Sopenharmony_ci return set_thread_string(LK_ZLIB_VERSION, zlibVersion()); 98013498266Sopenharmony_ci} 98113498266Sopenharmony_ci 98213498266Sopenharmony_ci 98313498266Sopenharmony_ciint 98413498266Sopenharmony_ciCurl_os400_inflateInit_(z_streamp strm, const char *version, int stream_size) 98513498266Sopenharmony_ci{ 98613498266Sopenharmony_ci z_const char *msgb4 = strm->msg; 98713498266Sopenharmony_ci int ret; 98813498266Sopenharmony_ci 98913498266Sopenharmony_ci ret = inflateInit(strm); 99013498266Sopenharmony_ci 99113498266Sopenharmony_ci if(strm->msg != msgb4) 99213498266Sopenharmony_ci strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg); 99313498266Sopenharmony_ci 99413498266Sopenharmony_ci return ret; 99513498266Sopenharmony_ci} 99613498266Sopenharmony_ci 99713498266Sopenharmony_ciint 99813498266Sopenharmony_ciCurl_os400_inflateInit2_(z_streamp strm, int windowBits, 99913498266Sopenharmony_ci const char *version, int stream_size) 100013498266Sopenharmony_ci{ 100113498266Sopenharmony_ci z_const char *msgb4 = strm->msg; 100213498266Sopenharmony_ci int ret; 100313498266Sopenharmony_ci 100413498266Sopenharmony_ci ret = inflateInit2(strm, windowBits); 100513498266Sopenharmony_ci 100613498266Sopenharmony_ci if(strm->msg != msgb4) 100713498266Sopenharmony_ci strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg); 100813498266Sopenharmony_ci 100913498266Sopenharmony_ci return ret; 101013498266Sopenharmony_ci} 101113498266Sopenharmony_ci 101213498266Sopenharmony_ciint 101313498266Sopenharmony_ciCurl_os400_inflate(z_streamp strm, int flush) 101413498266Sopenharmony_ci{ 101513498266Sopenharmony_ci z_const char *msgb4 = strm->msg; 101613498266Sopenharmony_ci int ret; 101713498266Sopenharmony_ci 101813498266Sopenharmony_ci ret = inflate(strm, flush); 101913498266Sopenharmony_ci 102013498266Sopenharmony_ci if(strm->msg != msgb4) 102113498266Sopenharmony_ci strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg); 102213498266Sopenharmony_ci 102313498266Sopenharmony_ci return ret; 102413498266Sopenharmony_ci} 102513498266Sopenharmony_ci 102613498266Sopenharmony_ciint 102713498266Sopenharmony_ciCurl_os400_inflateEnd(z_streamp strm) 102813498266Sopenharmony_ci{ 102913498266Sopenharmony_ci z_const char *msgb4 = strm->msg; 103013498266Sopenharmony_ci int ret; 103113498266Sopenharmony_ci 103213498266Sopenharmony_ci ret = inflateEnd(strm); 103313498266Sopenharmony_ci 103413498266Sopenharmony_ci if(strm->msg != msgb4) 103513498266Sopenharmony_ci strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg); 103613498266Sopenharmony_ci 103713498266Sopenharmony_ci return ret; 103813498266Sopenharmony_ci} 103913498266Sopenharmony_ci 104013498266Sopenharmony_ci#endif 1041