1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
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 http://curl.haxx.se/docs/copyright.html.
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
22 ***************************************************************************/
24 /* OS/400 additional support. */
26 #include "curlbuild.h"
27 #include "config-os400.h" /* Not curl_setup.h: we only need some defines. */
29 #include <sys/types.h>
30 #include <sys/socket.h>
58 #ifndef CURL_DISABLE_LDAP
62 #include <netinet/in.h>
63 #include <arpa/inet.h>
69 *** QADRT OS/400 ASCII runtime defines only the most used procedures, but
70 *** but a lot of them are not supported. This module implements
71 *** ASCII wrappers for those that are used by libcurl, but not
75 #pragma convert(0) /* Restore EBCDIC. */
78 #define MIN_BYTE_GAIN 1024 /* Minimum gain when shortening a buffer. */
81 unsigned long size; /* Buffer size. */
82 char * buf; /* Buffer address. */
86 static char * buffer_undef(localkey_t key, long size);
87 static char * buffer_threaded(localkey_t key, long size);
88 static char * buffer_unthreaded(localkey_t key, long size);
90 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
91 static pthread_key_t thdkey;
92 static buffer_t * locbufs;
94 char * (* Curl_thread_buffer)(localkey_t key, long size) = buffer_undef;
98 thdbufdestroy(void * private)
105 p = (buffer_t *) private;
107 for (i = (localkey_t) 0; i < LK_LAST; i++) {
123 if (Curl_thread_buffer == buffer_threaded) {
124 locbufs = pthread_getspecific(thdkey);
125 pthread_setspecific(thdkey, (void *) NULL);
126 pthread_key_delete(thdkey);
129 if (Curl_thread_buffer != buffer_undef) {
130 thdbufdestroy((void *) locbufs);
131 locbufs = (buffer_t *) NULL;
134 Curl_thread_buffer = buffer_undef;
139 get_buffer(buffer_t * buf, long size)
144 /* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long.
145 Return the buffer address. */
151 if ((buf->buf = malloc(size)))
157 if ((unsigned long) size <= buf->size) {
158 /* Shorten the buffer only if it frees a significant byte count. This
159 avoids some realloc() overhead. */
161 if (buf->size - size < MIN_BYTE_GAIN)
165 /* Resize the buffer. */
167 if ((cp = realloc(buf->buf, size))) {
171 else if (size <= buf->size)
179 buffer_unthreaded(localkey_t key, long size)
182 return get_buffer(locbufs + key, size);
187 buffer_threaded(localkey_t key, long size)
192 /* Get the buffer for the given local key in the current thread, and
193 make sure it is at least `size'-byte long. Set `size' to < 0 to get
196 bufs = (buffer_t *) pthread_getspecific(thdkey);
200 return (char *) NULL; /* No buffer yet. */
202 /* Allocate buffer descriptors for the current thread. */
204 if (!(bufs = calloc((size_t) LK_LAST, sizeof *bufs)))
205 return (char *) NULL;
207 if (pthread_setspecific(thdkey, (void *) bufs)) {
209 return (char *) NULL;
213 return get_buffer(bufs + key, size);
218 buffer_undef(localkey_t key, long size)
221 /* Define the buffer system, get the buffer for the given local key in
222 the current thread, and make sure it is at least `size'-byte long.
223 Set `size' to < 0 to get its address only. */
225 pthread_mutex_lock(&mutex);
227 /* Determine if we can use pthread-specific data. */
229 if (Curl_thread_buffer == buffer_undef) { /* If unchanged during lock. */
230 if (!pthread_key_create(&thdkey, thdbufdestroy))
231 Curl_thread_buffer = buffer_threaded;
232 else if (!(locbufs = calloc((size_t) LK_LAST,
234 pthread_mutex_unlock(&mutex);
235 return (char *) NULL;
238 Curl_thread_buffer = buffer_unthreaded;
243 pthread_mutex_unlock(&mutex);
244 return Curl_thread_buffer(key, size);
249 set_thread_string(localkey_t key, const char * s)
256 return (char *) NULL;
259 cp = Curl_thread_buffer(key, MAX_CONV_EXPANSION * i + 1);
262 i = QadrtConvertE2A(cp, s, MAX_CONV_EXPANSION * i, i);
271 Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
272 char * nodename, curl_socklen_t nodenamelen,
273 char * servname, curl_socklen_t servnamelen,
282 enodename = (char *) NULL;
283 eservname = (char *) NULL;
285 if (nodename && nodenamelen)
286 if (!(enodename = malloc(nodenamelen)))
289 if (servname && servnamelen)
290 if (!(eservname = malloc(servnamelen))) {
297 status = getnameinfo(sa, salen, enodename, nodenamelen,
298 eservname, servnamelen, flags);
302 i = QadrtConvertE2A(nodename, enodename,
303 nodenamelen - 1, strlen(enodename));
308 i = QadrtConvertE2A(servname, eservname,
309 servnamelen - 1, strlen(eservname));
325 Curl_getaddrinfo_a(const char * nodename, const char * servname,
326 const struct addrinfo * hints,
327 struct addrinfo * * res)
335 enodename = (char *) NULL;
336 eservname = (char *) NULL;
339 i = strlen(nodename);
341 if (!(enodename = malloc(i + 1)))
344 i = QadrtConvertA2E(enodename, nodename, i, i);
349 i = strlen(servname);
351 if (!(eservname = malloc(i + 1))) {
358 QadrtConvertA2E(eservname, servname, i, i);
362 status = getaddrinfo(enodename, eservname, hints, res);
376 /* ASCII wrappers for the SSL procedures. */
379 Curl_SSL_Init_Application_a(SSLInitApp * init_app)
386 if (!init_app || !init_app->applicationID || !init_app->applicationIDLen)
387 return SSL_Init_Application(init_app);
389 memcpy((char *) &ia, (char *) init_app, sizeof ia);
390 i = ia.applicationIDLen;
392 if (!(ia.applicationID = malloc(i + 1))) {
397 QadrtConvertA2E(ia.applicationID, init_app->applicationID, i, i);
398 ia.applicationID[i] = '\0';
399 rc = SSL_Init_Application(&ia);
400 free(ia.applicationID);
401 init_app->localCertificateLen = ia.localCertificateLen;
402 init_app->sessionType = ia.sessionType;
408 Curl_SSL_Init_a(SSLInit * init)
415 if (!init || (!init->keyringFileName && !init->keyringPassword))
416 return SSL_Init(init);
418 memcpy((char *) &ia, (char *) init, sizeof ia);
420 if (ia.keyringFileName) {
421 i = strlen(ia.keyringFileName);
423 if (!(ia.keyringFileName = malloc(i + 1))) {
428 QadrtConvertA2E(ia.keyringFileName, init->keyringFileName, i, i);
429 ia.keyringFileName[i] = '\0';
432 if (ia.keyringPassword) {
433 i = strlen(ia.keyringPassword);
435 if (!(ia.keyringPassword = malloc(i + 1))) {
436 if (ia.keyringFileName)
437 free(ia.keyringFileName);
443 QadrtConvertA2E(ia.keyringPassword, init->keyringPassword, i, i);
444 ia.keyringPassword[i] = '\0';
449 if (ia.keyringFileName)
450 free(ia.keyringFileName);
452 if (ia.keyringPassword)
453 free(ia.keyringPassword);
460 Curl_SSL_Strerror_a(int sslreturnvalue, SSLErrorMsg * serrmsgp)
463 return set_thread_string(LK_SSL_ERROR,
464 SSL_Strerror(sslreturnvalue, serrmsgp));
467 #endif /* USE_QSOSSL */
472 /* ASCII wrappers for the GSKit procedures. */
475 * EBCDIC --> ASCII string mapping table.
476 * Some strings returned by GSKit are dynamically allocated and automatically
477 * released when closing the handle.
478 * To provide the same functionality, we use a "private" handle that
479 * holds the GSKit handle and a list of string mappings. This will allow
480 * avoid conversion of already converted strings and releasing them upon
485 struct gskstrlist * next;
486 const char * ebcdicstr;
487 const char * asciistr;
490 struct Curl_gsk_descriptor {
492 struct gskstrlist * strlist;
497 Curl_gsk_environment_open(gsk_handle * my_env_handle)
500 struct Curl_gsk_descriptor * p;
505 return GSK_OS400_ERROR_INVALID_POINTER;
506 if(!(p = (struct Curl_gsk_descriptor *) malloc(sizeof *p)))
507 return GSK_INSUFFICIENT_STORAGE;
508 p->strlist = (struct gskstrlist *) NULL;
509 if((rc = gsk_environment_open(&p->h)) != GSK_OK)
512 *my_env_handle = (gsk_handle) p;
518 Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
519 gsk_handle * my_session_handle)
522 struct Curl_gsk_descriptor * p;
527 return GSK_INVALID_HANDLE;
528 if(!my_session_handle)
529 return GSK_OS400_ERROR_INVALID_POINTER;
530 h = ((struct Curl_gsk_descriptor *) my_env_handle)->h;
531 if(!(p = (struct Curl_gsk_descriptor *) malloc(sizeof *p)))
532 return GSK_INSUFFICIENT_STORAGE;
533 p->strlist = (struct gskstrlist *) NULL;
534 if((rc = gsk_secure_soc_open(h, &p->h)) != GSK_OK)
537 *my_session_handle = (gsk_handle) p;
543 gsk_free_handle(struct Curl_gsk_descriptor * p)
546 struct gskstrlist * q;
548 while ((q = p->strlist)) {
550 free((void *) q->asciistr);
558 Curl_gsk_environment_close(gsk_handle * my_env_handle)
561 struct Curl_gsk_descriptor * p;
565 return GSK_OS400_ERROR_INVALID_POINTER;
567 return GSK_INVALID_HANDLE;
568 p = (struct Curl_gsk_descriptor *) *my_env_handle;
569 if ((rc = gsk_environment_close(&p->h)) == GSK_OK) {
571 *my_env_handle = (gsk_handle) NULL;
578 Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)
581 struct Curl_gsk_descriptor * p;
584 if(!my_session_handle)
585 return GSK_OS400_ERROR_INVALID_POINTER;
586 if(!*my_session_handle)
587 return GSK_INVALID_HANDLE;
588 p = (struct Curl_gsk_descriptor *) *my_session_handle;
589 if ((rc = gsk_secure_soc_close(&p->h)) == GSK_OK) {
591 *my_session_handle = (gsk_handle) NULL;
598 Curl_gsk_environment_init(gsk_handle my_env_handle)
601 struct Curl_gsk_descriptor * p;
604 return GSK_INVALID_HANDLE;
605 p = (struct Curl_gsk_descriptor *) my_env_handle;
606 return gsk_environment_init(p->h);
611 Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
614 struct Curl_gsk_descriptor * p;
616 if(!my_session_handle)
617 return GSK_INVALID_HANDLE;
618 p = (struct Curl_gsk_descriptor *) my_session_handle;
619 return gsk_secure_soc_init(p->h);
624 Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
625 const char * buffer, int bufSize)
628 struct Curl_gsk_descriptor * p;
633 return GSK_INVALID_HANDLE;
635 return GSK_OS400_ERROR_INVALID_POINTER;
637 return GSK_ATTRIBUTE_INVALID_LENGTH;
638 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
640 bufSize = strlen(buffer);
641 if (!(ebcdicbuf = malloc(bufSize + 1)))
642 return GSK_INSUFFICIENT_STORAGE;
643 QadrtConvertA2E(ebcdicbuf, buffer, bufSize, bufSize);
644 ebcdicbuf[bufSize] = '\0';
645 rc = gsk_attribute_set_buffer(p->h, bufID, ebcdicbuf, bufSize);
652 Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
653 GSK_ENUM_VALUE enumValue)
656 struct Curl_gsk_descriptor * p;
659 return GSK_INVALID_HANDLE;
660 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
661 return gsk_attribute_set_enum(p->h, enumID, enumValue);
666 Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
667 GSK_NUM_ID numID, int numValue)
670 struct Curl_gsk_descriptor * p;
673 return GSK_INVALID_HANDLE;
674 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
675 return gsk_attribute_set_numeric_value(p->h, numID, numValue);
680 Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
681 GSK_CALLBACK_ID callBackID,
682 void * callBackAreaPtr)
685 struct Curl_gsk_descriptor * p;
688 return GSK_INVALID_HANDLE;
689 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
690 return gsk_attribute_set_callback(p->h, callBackID, callBackAreaPtr);
695 cachestring(struct Curl_gsk_descriptor * p,
696 const char * ebcdicbuf, int bufsize, const char * * buffer)
701 struct gskstrlist * sp;
703 for (sp = p->strlist; sp; sp = sp->next)
704 if(sp->ebcdicstr == ebcdicbuf)
707 if(!(sp = (struct gskstrlist *) malloc(sizeof *sp)))
708 return GSK_INSUFFICIENT_STORAGE;
709 if(!(asciibuf = malloc(bufsize + 1))) {
711 return GSK_INSUFFICIENT_STORAGE;
713 QadrtConvertE2A(asciibuf, ebcdicbuf, bufsize, bufsize);
714 asciibuf[bufsize] = '\0';
715 sp->ebcdicstr = ebcdicbuf;
716 sp->asciistr = asciibuf;
717 sp->next = p->strlist;
720 *buffer = sp->asciistr;
726 Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
727 const char * * buffer, int * bufSize)
730 struct Curl_gsk_descriptor * p;
736 return GSK_INVALID_HANDLE;
737 if(!buffer || !bufSize)
738 return GSK_OS400_ERROR_INVALID_POINTER;
739 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
740 if ((rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen)) != GSK_OK)
742 if((rc = cachestring(p, mybuf, mylen, buffer)) == GSK_OK)
749 Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
750 GSK_ENUM_VALUE * enumValue)
753 struct Curl_gsk_descriptor * p;
756 return GSK_INVALID_HANDLE;
757 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
758 return gsk_attribute_get_enum(p->h, enumID, enumValue);
763 Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
764 GSK_NUM_ID numID, int * numValue)
767 struct Curl_gsk_descriptor * p;
770 return GSK_INVALID_HANDLE;
771 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
772 return gsk_attribute_get_numeric_value(p->h, numID, numValue);
777 Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
779 const gsk_cert_data_elem * * certDataElem,
780 int * certDataElementCount)
783 struct Curl_gsk_descriptor * p;
786 return GSK_INVALID_HANDLE;
787 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
788 /* No need to convert code: text results are already in ASCII. */
789 return gsk_attribute_get_cert_info(p->h, certID,
790 certDataElem, certDataElementCount);
795 Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, GSK_MISC_ID miscID)
798 struct Curl_gsk_descriptor * p;
800 if(!my_session_handle)
801 return GSK_INVALID_HANDLE;
802 p = (struct Curl_gsk_descriptor *) my_session_handle;
803 return gsk_secure_soc_misc(p->h, miscID);
808 Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char * readBuffer,
809 int readBufSize, int * amtRead)
812 struct Curl_gsk_descriptor * p;
814 if(!my_session_handle)
815 return GSK_INVALID_HANDLE;
816 p = (struct Curl_gsk_descriptor *) my_session_handle;
817 return gsk_secure_soc_read(p->h, readBuffer, readBufSize, amtRead);
822 Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char * writeBuffer,
823 int writeBufSize, int * amtWritten)
826 struct Curl_gsk_descriptor * p;
828 if(!my_session_handle)
829 return GSK_INVALID_HANDLE;
830 p = (struct Curl_gsk_descriptor *) my_session_handle;
831 return gsk_secure_soc_write(p->h, writeBuffer, writeBufSize, amtWritten);
836 Curl_gsk_strerror_a(int gsk_return_value)
839 return set_thread_string(LK_GSK_ERROR, gsk_strerror(gsk_return_value));
843 Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
844 int IOCompletionPort,
845 Qso_OverlappedIO_t * communicationsArea)
848 struct Curl_gsk_descriptor * p;
850 if(!my_session_handle)
851 return GSK_INVALID_HANDLE;
852 p = (struct Curl_gsk_descriptor *) my_session_handle;
853 return gsk_secure_soc_startInit(p->h, IOCompletionPort, communicationsArea);
856 #endif /* USE_GSKIT */
862 /* ASCII wrappers for the GSSAPI procedures. */
865 Curl_gss_convert_in_place(OM_uint32 * minor_status, gss_buffer_t buf)
871 /* Convert `buf' in place, from EBCDIC to ASCII.
872 If error, release the buffer and return -1. Else return 0. */
877 if (!(t = malloc(i))) {
878 gss_release_buffer(minor_status, buf);
881 *minor_status = ENOMEM;
886 QadrtConvertE2A(t, buf->value, i, i);
887 memcpy(buf->value, t, i);
896 Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
897 gss_OID in_name_type, gss_name_t * out_name)
904 if (!in_name || !in_name->value || !in_name->length)
905 return gss_import_name(minor_status, in_name, in_name_type, out_name);
907 memcpy((char *) &in, (char *) in_name, sizeof in);
910 if (!(in.value = malloc(i + 1))) {
912 *minor_status = ENOMEM;
914 return GSS_S_FAILURE;
917 QadrtConvertA2E(in.value, in_name->value, i, i);
918 ((char *) in.value)[i] = '\0';
919 rc = gss_import_name(minor_status, &in, in_name_type, out_name);
926 Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
927 int status_type, gss_OID mech_type,
928 gss_msg_ctx_t * message_context, gss_buffer_t status_string)
933 rc = gss_display_status(minor_status, status_value, status_type,
934 mech_type, message_context, status_string);
936 if (rc != GSS_S_COMPLETE || !status_string ||
937 !status_string->length || !status_string->value)
940 /* No way to allocate a buffer here, because it will be released by
941 gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
942 with ASCII to return it. */
944 if (Curl_gss_convert_in_place(minor_status, status_string))
945 return GSS_S_FAILURE;
952 Curl_gss_init_sec_context_a(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
953 gss_ctx_id_t * context_handle,
954 gss_name_t target_name, gss_OID mech_type,
955 gss_flags_t req_flags, OM_uint32 time_req,
956 gss_channel_bindings_t input_chan_bindings,
957 gss_buffer_t input_token,
958 gss_OID * actual_mech_type,
959 gss_buffer_t output_token, gss_flags_t * ret_flags,
960 OM_uint32 * time_rec)
970 if ((inp = input_token))
971 if (inp->length && inp->value) {
974 if (!(in.value = malloc(i + 1))) {
976 *minor_status = ENOMEM;
978 return GSS_S_FAILURE;
981 QadrtConvertA2E(in.value, input_token->value, i, i);
982 ((char *) in.value)[i] = '\0';
987 rc = gss_init_sec_context(minor_status, cred_handle, context_handle,
988 target_name, mech_type, req_flags, time_req,
989 input_chan_bindings, inp, actual_mech_type,
990 output_token, ret_flags, time_rec);
995 if (rc != GSS_S_COMPLETE || !output_token ||
996 !output_token->length || !output_token->value)
999 /* No way to allocate a buffer here, because it will be released by
1000 gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
1001 with ASCII to return it. */
1003 if (Curl_gss_convert_in_place(minor_status, output_token))
1004 return GSS_S_FAILURE;
1011 Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
1012 gss_ctx_id_t * context_handle,
1013 gss_buffer_t output_token)
1018 rc = gss_delete_sec_context(minor_status, context_handle, output_token);
1020 if (rc != GSS_S_COMPLETE || !output_token ||
1021 !output_token->length || !output_token->value)
1024 /* No way to allocate a buffer here, because it will be released by
1025 gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
1026 with ASCII to return it. */
1028 if (Curl_gss_convert_in_place(minor_status, output_token))
1029 return GSS_S_FAILURE;
1034 #endif /* HAVE_GSSAPI */
1037 #ifndef CURL_DISABLE_LDAP
1039 /* ASCII wrappers for the LDAP procedures. */
1042 Curl_ldap_init_a(char * host, int port)
1050 return (void *) ldap_init(host, port);
1054 if (!(ehost = malloc(i + 1)))
1055 return (void *) NULL;
1057 QadrtConvertA2E(ehost, host, i, i);
1059 result = (void *) ldap_init(ehost, port);
1066 Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
1073 edn = (char *) NULL;
1074 epasswd = (char *) NULL;
1079 if (!(edn = malloc(i + 1)))
1080 return LDAP_NO_MEMORY;
1082 QadrtConvertA2E(edn, dn, i, i);
1089 if (!(epasswd = malloc(i + 1))) {
1093 return LDAP_NO_MEMORY;
1096 QadrtConvertA2E(epasswd, passwd, i, i);
1100 i = ldap_simple_bind_s(ld, edn, epasswd);
1113 Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
1114 char * * attrs, int attrsonly, LDAPMessage * * res)
1124 ebase = (char *) NULL;
1125 efilter = (char *) NULL;
1126 eattrs = (char * *) NULL;
1127 status = LDAP_SUCCESS;
1132 if (!(ebase = malloc(i + 1)))
1133 status = LDAP_NO_MEMORY;
1135 QadrtConvertA2E(ebase, base, i, i);
1140 if (filter && status == LDAP_SUCCESS) {
1143 if (!(efilter = malloc(i + 1)))
1144 status = LDAP_NO_MEMORY;
1146 QadrtConvertA2E(efilter, filter, i, i);
1151 if (attrs && status == LDAP_SUCCESS) {
1152 for (i = 0; attrs[i++];)
1155 if (!(eattrs = calloc(i, sizeof *eattrs)))
1156 status = LDAP_NO_MEMORY;
1158 for (j = 0; attrs[j]; j++) {
1159 i = strlen(attrs[j]);
1161 if (!(eattrs[j] = malloc(i + 1))) {
1162 status = LDAP_NO_MEMORY;
1166 QadrtConvertA2E(eattrs[j], attrs[j], i, i);
1167 eattrs[j][i] = '\0';
1172 if (status == LDAP_SUCCESS)
1173 status = ldap_search_s(ld, ebase? ebase: "", scope,
1174 efilter? efilter: "(objectclass=*)",
1175 eattrs, attrsonly, res);
1178 for (j = 0; eattrs[j]; j++)
1195 Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
1200 struct berval * * result;
1207 if (!(cp = malloc(i + 1))) {
1208 ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
1209 ldap_err2string(LDAP_NO_MEMORY));
1210 return (struct berval * *) NULL;
1213 QadrtConvertA2E(cp, attr, i, i);
1217 result = ldap_get_values_len(ld, entry, cp);
1222 /* Result data are binary in nature, so they haven't been converted to EBCDIC.
1223 Therefore do not convert. */
1230 Curl_ldap_err2string_a(int error)
1233 return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
1238 Curl_ldap_get_dn_a(void * ld, LDAPMessage * entry)
1245 cp = ldap_get_dn(ld, entry);
1252 if (!(cp2 = malloc(i + 1)))
1255 QadrtConvertE2A(cp2, cp, i, i);
1258 /* No way to allocate a buffer here, because it will be released by
1259 ldap_memfree() and ldap_memalloc() does not exist. The solution is to
1260 overwrite the EBCDIC buffer with ASCII to return it. */
1269 Curl_ldap_first_attribute_a(void * ld,
1270 LDAPMessage * entry, BerElement * * berptr)
1277 cp = ldap_first_attribute(ld, entry, berptr);
1284 if (!(cp2 = malloc(i + 1)))
1287 QadrtConvertE2A(cp2, cp, i, i);
1290 /* No way to allocate a buffer here, because it will be released by
1291 ldap_memfree() and ldap_memalloc() does not exist. The solution is to
1292 overwrite the EBCDIC buffer with ASCII to return it. */
1301 Curl_ldap_next_attribute_a(void * ld,
1302 LDAPMessage * entry, BerElement * berptr)
1309 cp = ldap_next_attribute(ld, entry, berptr);
1316 if (!(cp2 = malloc(i + 1)))
1319 QadrtConvertE2A(cp2, cp, i, i);
1322 /* No way to allocate a buffer here, because it will be released by
1323 ldap_memfree() and ldap_memalloc() does not exist. The solution is to
1324 overwrite the EBCDIC buffer with ASCII to return it. */
1331 #endif /* CURL_DISABLE_LDAP */
1335 convert_sockaddr(struct sockaddr_storage * dstaddr,
1336 const struct sockaddr * srcaddr, int srclen)
1339 const struct sockaddr_un * srcu;
1340 struct sockaddr_un * dstu;
1342 unsigned int dstsize;
1344 /* Convert a socket address into job CCSID, if needed. */
1346 if (!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
1347 sizeof srcaddr->sa_family || srclen > sizeof *dstaddr) {
1352 memcpy((char *) dstaddr, (char *) srcaddr, srclen);
1354 switch (srcaddr->sa_family) {
1357 srcu = (const struct sockaddr_un *) srcaddr;
1358 dstu = (struct sockaddr_un *) dstaddr;
1359 dstsize = sizeof *dstaddr - offsetof(struct sockaddr_un, sun_path);
1360 srclen -= offsetof(struct sockaddr_un, sun_path);
1361 i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen);
1362 dstu->sun_path[i] = '\0';
1363 i += offsetof(struct sockaddr_un, sun_path);
1372 Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
1376 struct sockaddr_storage laddr;
1378 i = convert_sockaddr(&laddr, destaddr, addrlen);
1383 return connect(sd, (struct sockaddr *) &laddr, i);
1388 Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
1392 struct sockaddr_storage laddr;
1394 i = convert_sockaddr(&laddr, localaddr, addrlen);
1399 return bind(sd, (struct sockaddr *) &laddr, i);
1404 Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
1405 struct sockaddr * dstaddr, int addrlen)
1409 struct sockaddr_storage laddr;
1411 i = convert_sockaddr(&laddr, dstaddr, addrlen);
1416 return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
1421 Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
1422 struct sockaddr * fromaddr, int * addrlen)
1428 const struct sockaddr_un * srcu;
1429 struct sockaddr_un * dstu;
1430 struct sockaddr_storage laddr;
1432 if (!fromaddr || !addrlen || *addrlen <= 0)
1433 return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);
1435 laddrlen = sizeof laddr;
1436 laddr.ss_family = AF_UNSPEC; /* To detect if unused. */
1437 rcvlen = recvfrom(sd, buffer, buflen, flags,
1438 (struct sockaddr *) &laddr, &laddrlen);
1443 switch (laddr.ss_family) {
1446 srcu = (const struct sockaddr_un *) &laddr;
1447 dstu = (struct sockaddr_un *) fromaddr;
1448 i = *addrlen - offsetof(struct sockaddr_un, sun_path);
1449 laddrlen -= offsetof(struct sockaddr_un, sun_path);
1450 i = QadrtConvertE2A(dstu->sun_path, srcu->sun_path, i, laddrlen);
1451 laddrlen = i + offsetof(struct sockaddr_un, sun_path);
1453 if (laddrlen < *addrlen)
1454 dstu->sun_path[i] = '\0';
1462 if (laddrlen > *addrlen)
1463 laddrlen = *addrlen;
1466 memcpy((char *) fromaddr, (char *) &laddr, laddrlen);
1471 *addrlen = laddrlen;
1478 Curl_os400_zlibVersion(void)
1481 return set_thread_string(LK_ZLIB_VERSION, zlibVersion());
1486 Curl_os400_inflateInit_(z_streamp strm, const char * version, int stream_size)
1489 z_const char * msgb4 = strm->msg;
1492 ret = inflateInit(strm);
1494 if(strm->msg != msgb4)
1495 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1502 Curl_os400_inflateInit2_(z_streamp strm, int windowBits,
1503 const char * version, int stream_size)
1506 z_const char * msgb4 = strm->msg;
1509 ret = inflateInit2(strm, windowBits);
1511 if(strm->msg != msgb4)
1512 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1519 Curl_os400_inflate(z_streamp strm, int flush)
1522 z_const char * msgb4 = strm->msg;
1525 ret = inflate(strm, flush);
1527 if(strm->msg != msgb4)
1528 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1535 Curl_os400_inflateEnd(z_streamp strm)
1538 z_const char * msgb4 = strm->msg;
1541 ret = inflateEnd(strm);
1543 if(strm->msg != msgb4)
1544 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);