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>
54 #ifndef CURL_DISABLE_LDAP
58 #include <netinet/in.h>
59 #include <arpa/inet.h>
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
71 #pragma convert(0) /* Restore EBCDIC. */
74 #define MIN_BYTE_GAIN 1024 /* Minimum gain when shortening a buffer. */
77 unsigned long size; /* Buffer size. */
78 char * buf; /* Buffer address. */
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);
86 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
87 static pthread_key_t thdkey;
88 static buffer_t * locbufs;
90 char * (* Curl_thread_buffer)(localkey_t key, long size) = buffer_undef;
94 thdbufdestroy(void * private)
101 p = (buffer_t *) private;
103 for (i = (localkey_t) 0; i < LK_LAST; i++) {
119 if (Curl_thread_buffer == buffer_threaded) {
120 locbufs = pthread_getspecific(thdkey);
121 pthread_setspecific(thdkey, (void *) NULL);
122 pthread_key_delete(thdkey);
125 if (Curl_thread_buffer != buffer_undef) {
126 thdbufdestroy((void *) locbufs);
127 locbufs = (buffer_t *) NULL;
130 Curl_thread_buffer = buffer_undef;
135 get_buffer(buffer_t * buf, long size)
140 /* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long.
141 Return the buffer address. */
147 if ((buf->buf = malloc(size)))
153 if ((unsigned long) size <= buf->size) {
154 /* Shorten the buffer only if it frees a significant byte count. This
155 avoids some realloc() overhead. */
157 if (buf->size - size < MIN_BYTE_GAIN)
161 /* Resize the buffer. */
163 if ((cp = realloc(buf->buf, size))) {
167 else if (size <= buf->size)
175 buffer_unthreaded(localkey_t key, long size)
178 return get_buffer(locbufs + key, size);
183 buffer_threaded(localkey_t key, long size)
188 /* Get the buffer for the given local key in the current thread, and
189 make sure it is at least `size'-byte long. Set `size' to < 0 to get
192 bufs = (buffer_t *) pthread_getspecific(thdkey);
196 return (char *) NULL; /* No buffer yet. */
198 /* Allocate buffer descriptors for the current thread. */
200 if (!(bufs = calloc((size_t) LK_LAST, sizeof *bufs)))
201 return (char *) NULL;
203 if (pthread_setspecific(thdkey, (void *) bufs)) {
205 return (char *) NULL;
209 return get_buffer(bufs + key, size);
214 buffer_undef(localkey_t key, long size)
217 /* Define the buffer system, get the buffer for the given local key in
218 the current thread, and make sure it is at least `size'-byte long.
219 Set `size' to < 0 to get its address only. */
221 pthread_mutex_lock(&mutex);
223 /* Determine if we can use pthread-specific data. */
225 if (Curl_thread_buffer == buffer_undef) { /* If unchanged during lock. */
226 if (!pthread_key_create(&thdkey, thdbufdestroy))
227 Curl_thread_buffer = buffer_threaded;
228 else if (!(locbufs = calloc((size_t) LK_LAST,
230 pthread_mutex_unlock(&mutex);
231 return (char *) NULL;
234 Curl_thread_buffer = buffer_unthreaded;
239 pthread_mutex_unlock(&mutex);
240 return Curl_thread_buffer(key, size);
245 Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
246 char * nodename, curl_socklen_t nodenamelen,
247 char * servname, curl_socklen_t servnamelen,
256 enodename = (char *) NULL;
257 eservname = (char *) NULL;
259 if (nodename && nodenamelen)
260 if (!(enodename = malloc(nodenamelen)))
263 if (servname && servnamelen)
264 if (!(eservname = malloc(servnamelen))) {
271 status = getnameinfo(sa, salen, enodename, nodenamelen,
272 eservname, servnamelen, flags);
276 i = QadrtConvertE2A(nodename, enodename,
277 nodenamelen - 1, strlen(enodename));
282 i = QadrtConvertE2A(servname, eservname,
283 servnamelen - 1, strlen(eservname));
299 Curl_getaddrinfo_a(const char * nodename, const char * servname,
300 const struct addrinfo * hints,
301 struct addrinfo * * res)
309 enodename = (char *) NULL;
310 eservname = (char *) NULL;
313 i = strlen(nodename);
315 if (!(enodename = malloc(i + 1)))
318 i = QadrtConvertA2E(enodename, nodename, i, i);
323 i = strlen(servname);
325 if (!(eservname = malloc(i + 1))) {
332 QadrtConvertA2E(eservname, servname, i, i);
336 status = getaddrinfo(enodename, eservname, hints, res);
350 /* ASCII wrappers for the SSL procedures. */
353 Curl_SSL_Init_Application_a(SSLInitApp * init_app)
360 if (!init_app || !init_app->applicationID || !init_app->applicationIDLen)
361 return SSL_Init_Application(init_app);
363 memcpy((char *) &ia, (char *) init_app, sizeof ia);
364 i = ia.applicationIDLen;
366 if (!(ia.applicationID = malloc(i + 1))) {
371 QadrtConvertA2E(ia.applicationID, init_app->applicationID, i, i);
372 ia.applicationID[i] = '\0';
373 rc = SSL_Init_Application(&ia);
374 free(ia.applicationID);
375 init_app->localCertificateLen = ia.localCertificateLen;
376 init_app->sessionType = ia.sessionType;
382 Curl_SSL_Init_a(SSLInit * init)
389 if (!init || (!init->keyringFileName && !init->keyringPassword))
390 return SSL_Init(init);
392 memcpy((char *) &ia, (char *) init, sizeof ia);
394 if (ia.keyringFileName) {
395 i = strlen(ia.keyringFileName);
397 if (!(ia.keyringFileName = malloc(i + 1))) {
402 QadrtConvertA2E(ia.keyringFileName, init->keyringFileName, i, i);
403 ia.keyringFileName[i] = '\0';
406 if (ia.keyringPassword) {
407 i = strlen(ia.keyringPassword);
409 if (!(ia.keyringPassword = malloc(i + 1))) {
410 if (ia.keyringFileName)
411 free(ia.keyringFileName);
417 QadrtConvertA2E(ia.keyringPassword, init->keyringPassword, i, i);
418 ia.keyringPassword[i] = '\0';
423 if (ia.keyringFileName)
424 free(ia.keyringFileName);
426 if (ia.keyringPassword)
427 free(ia.keyringPassword);
434 Curl_SSL_Strerror_a(int sslreturnvalue, SSLErrorMsg * serrmsgp)
441 cp = SSL_Strerror(sslreturnvalue, serrmsgp);
448 if (!(cp2 = Curl_thread_buffer(LK_SSL_ERROR, MAX_CONV_EXPANSION * i + 1)))
451 i = QadrtConvertE2A(cp2, cp, MAX_CONV_EXPANSION * i, i);
456 #endif /* USE_QSOSSL */
461 /* ASCII wrappers for the GSKit procedures. */
464 * EBCDIC --> ASCII string mapping table.
465 * Some strings returned by GSKit are dynamically allocated and automatically
466 * released when closing the handle.
467 * To provide the same functionality, we use a "private" handle that
468 * holds the GSKit handle and a list of string mappings. This will allow
469 * avoid conversion of already converted strings and releasing them upon
474 struct gskstrlist * next;
475 const char * ebcdicstr;
476 const char * asciistr;
479 struct Curl_gsk_descriptor {
481 struct gskstrlist * strlist;
486 Curl_gsk_environment_open(gsk_handle * my_env_handle)
489 struct Curl_gsk_descriptor * p;
494 return GSK_OS400_ERROR_INVALID_POINTER;
495 if(!(p = (struct Curl_gsk_descriptor *) malloc(sizeof *p)))
496 return GSK_INSUFFICIENT_STORAGE;
497 p->strlist = (struct gskstrlist *) NULL;
498 if((rc = gsk_environment_open(&p->h)) != GSK_OK)
501 *my_env_handle = (gsk_handle) p;
507 Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
508 gsk_handle * my_session_handle)
511 struct Curl_gsk_descriptor * p;
516 return GSK_INVALID_HANDLE;
517 if(!my_session_handle)
518 return GSK_OS400_ERROR_INVALID_POINTER;
519 h = ((struct Curl_gsk_descriptor *) my_env_handle)->h;
520 if(!(p = (struct Curl_gsk_descriptor *) malloc(sizeof *p)))
521 return GSK_INSUFFICIENT_STORAGE;
522 p->strlist = (struct gskstrlist *) NULL;
523 if((rc = gsk_secure_soc_open(h, &p->h)) != GSK_OK)
526 *my_session_handle = (gsk_handle) p;
532 gsk_free_handle(struct Curl_gsk_descriptor * p)
535 struct gskstrlist * q;
537 while ((q = p->strlist)) {
539 free((void *) q->asciistr);
547 Curl_gsk_environment_close(gsk_handle * my_env_handle)
550 struct Curl_gsk_descriptor * p;
554 return GSK_OS400_ERROR_INVALID_POINTER;
556 return GSK_INVALID_HANDLE;
557 p = (struct Curl_gsk_descriptor *) *my_env_handle;
558 if ((rc = gsk_environment_close(&p->h)) == GSK_OK) {
560 *my_env_handle = (gsk_handle) NULL;
567 Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)
570 struct Curl_gsk_descriptor * p;
573 if(!my_session_handle)
574 return GSK_OS400_ERROR_INVALID_POINTER;
575 if(!*my_session_handle)
576 return GSK_INVALID_HANDLE;
577 p = (struct Curl_gsk_descriptor *) *my_session_handle;
578 if ((rc = gsk_secure_soc_close(&p->h)) == GSK_OK) {
580 *my_session_handle = (gsk_handle) NULL;
587 Curl_gsk_environment_init(gsk_handle my_env_handle)
590 struct Curl_gsk_descriptor * p;
593 return GSK_INVALID_HANDLE;
594 p = (struct Curl_gsk_descriptor *) my_env_handle;
595 return gsk_environment_init(p->h);
600 Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
603 struct Curl_gsk_descriptor * p;
605 if(!my_session_handle)
606 return GSK_INVALID_HANDLE;
607 p = (struct Curl_gsk_descriptor *) my_session_handle;
608 return gsk_secure_soc_init(p->h);
613 Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
614 const char * buffer, int bufSize)
617 struct Curl_gsk_descriptor * p;
622 return GSK_INVALID_HANDLE;
624 return GSK_OS400_ERROR_INVALID_POINTER;
626 return GSK_ATTRIBUTE_INVALID_LENGTH;
627 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
629 bufSize = strlen(buffer);
630 if (!(ebcdicbuf = malloc(bufSize + 1)))
631 return GSK_INSUFFICIENT_STORAGE;
632 QadrtConvertA2E(ebcdicbuf, buffer, bufSize, bufSize);
633 ebcdicbuf[bufSize] = '\0';
634 rc = gsk_attribute_set_buffer(p->h, bufID, ebcdicbuf, bufSize);
641 Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
642 GSK_ENUM_VALUE enumValue)
645 struct Curl_gsk_descriptor * p;
648 return GSK_INVALID_HANDLE;
649 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
650 return gsk_attribute_set_enum(p->h, enumID, enumValue);
655 Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
656 GSK_NUM_ID numID, int numValue)
659 struct Curl_gsk_descriptor * p;
662 return GSK_INVALID_HANDLE;
663 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
664 return gsk_attribute_set_numeric_value(p->h, numID, numValue);
669 Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
670 GSK_CALLBACK_ID callBackID,
671 void * callBackAreaPtr)
674 struct Curl_gsk_descriptor * p;
677 return GSK_INVALID_HANDLE;
678 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
679 return gsk_attribute_set_callback(p->h, callBackID, callBackAreaPtr);
684 cachestring(struct Curl_gsk_descriptor * p,
685 const char * ebcdicbuf, int bufsize, const char * * buffer)
690 struct gskstrlist * sp;
692 for (sp = p->strlist; sp; sp = sp->next)
693 if(sp->ebcdicstr == ebcdicbuf)
696 if(!(sp = (struct gskstrlist *) malloc(sizeof *sp)))
697 return GSK_INSUFFICIENT_STORAGE;
698 if(!(asciibuf = malloc(bufsize + 1))) {
700 return GSK_INSUFFICIENT_STORAGE;
702 QadrtConvertE2A(asciibuf, ebcdicbuf, bufsize, bufsize);
703 asciibuf[bufsize] = '\0';
704 sp->ebcdicstr = ebcdicbuf;
705 sp->asciistr = asciibuf;
706 sp->next = p->strlist;
709 *buffer = sp->asciistr;
715 Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
716 const char * * buffer, int * bufSize)
719 struct Curl_gsk_descriptor * p;
725 return GSK_INVALID_HANDLE;
726 if(!buffer || !bufSize)
727 return GSK_OS400_ERROR_INVALID_POINTER;
728 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
729 if ((rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen)) != GSK_OK)
731 if((rc = cachestring(p, mybuf, mylen, buffer)) == GSK_OK)
738 Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
739 GSK_ENUM_VALUE * enumValue)
742 struct Curl_gsk_descriptor * p;
745 return GSK_INVALID_HANDLE;
746 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
747 return gsk_attribute_get_enum(p->h, enumID, enumValue);
752 Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
753 GSK_NUM_ID numID, int * numValue)
756 struct Curl_gsk_descriptor * p;
759 return GSK_INVALID_HANDLE;
760 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
761 return gsk_attribute_get_numeric_value(p->h, numID, numValue);
766 Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
768 const gsk_cert_data_elem * * certDataElem,
769 int * certDataElementCount)
772 struct Curl_gsk_descriptor * p;
775 return GSK_INVALID_HANDLE;
776 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
777 /* No need to convert code: text results are already in ASCII. */
778 return gsk_attribute_get_cert_info(p->h, certID,
779 certDataElem, certDataElementCount);
784 Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, GSK_MISC_ID miscID)
787 struct Curl_gsk_descriptor * p;
789 if(!my_session_handle)
790 return GSK_INVALID_HANDLE;
791 p = (struct Curl_gsk_descriptor *) my_session_handle;
792 return gsk_secure_soc_misc(p->h, miscID);
797 Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char * readBuffer,
798 int readBufSize, int * amtRead)
801 struct Curl_gsk_descriptor * p;
803 if(!my_session_handle)
804 return GSK_INVALID_HANDLE;
805 p = (struct Curl_gsk_descriptor *) my_session_handle;
806 return gsk_secure_soc_read(p->h, readBuffer, readBufSize, amtRead);
811 Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char * writeBuffer,
812 int writeBufSize, int * amtWritten)
815 struct Curl_gsk_descriptor * p;
817 if(!my_session_handle)
818 return GSK_INVALID_HANDLE;
819 p = (struct Curl_gsk_descriptor *) my_session_handle;
820 return gsk_secure_soc_write(p->h, writeBuffer, writeBufSize, amtWritten);
825 Curl_gsk_strerror_a(int gsk_return_value)
832 cp = gsk_strerror(gsk_return_value);
839 if (!(cp2 = Curl_thread_buffer(LK_GSK_ERROR, MAX_CONV_EXPANSION * i + 1)))
842 i = QadrtConvertE2A(cp2, cp, MAX_CONV_EXPANSION * i, i);
848 Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
849 int IOCompletionPort,
850 Qso_OverlappedIO_t * communicationsArea)
853 struct Curl_gsk_descriptor * p;
855 if(!my_session_handle)
856 return GSK_INVALID_HANDLE;
857 p = (struct Curl_gsk_descriptor *) my_session_handle;
858 return gsk_secure_soc_startInit(p->h, IOCompletionPort, communicationsArea);
861 #endif /* USE_GSKIT */
867 /* ASCII wrappers for the GSSAPI procedures. */
870 Curl_gss_convert_in_place(OM_uint32 * minor_status, gss_buffer_t buf)
876 /* Convert `buf' in place, from EBCDIC to ASCII.
877 If error, release the buffer and return -1. Else return 0. */
882 if (!(t = malloc(i))) {
883 gss_release_buffer(minor_status, buf);
886 *minor_status = ENOMEM;
891 QadrtConvertE2A(t, buf->value, i, i);
892 memcpy(buf->value, t, i);
901 Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
902 gss_OID in_name_type, gss_name_t * out_name)
909 if (!in_name || !in_name->value || !in_name->length)
910 return gss_import_name(minor_status, in_name, in_name_type, out_name);
912 memcpy((char *) &in, (char *) in_name, sizeof in);
915 if (!(in.value = malloc(i + 1))) {
917 *minor_status = ENOMEM;
919 return GSS_S_FAILURE;
922 QadrtConvertA2E(in.value, in_name->value, i, i);
923 ((char *) in.value)[i] = '\0';
924 rc = gss_import_name(minor_status, &in, in_name_type, out_name);
931 Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
932 int status_type, gss_OID mech_type,
933 gss_msg_ctx_t * message_context, gss_buffer_t status_string)
938 rc = gss_display_status(minor_status, status_value, status_type,
939 mech_type, message_context, status_string);
941 if (rc != GSS_S_COMPLETE || !status_string ||
942 !status_string->length || !status_string->value)
945 /* No way to allocate a buffer here, because it will be released by
946 gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
947 with ASCII to return it. */
949 if (Curl_gss_convert_in_place(minor_status, status_string))
950 return GSS_S_FAILURE;
957 Curl_gss_init_sec_context_a(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
958 gss_ctx_id_t * context_handle,
959 gss_name_t target_name, gss_OID mech_type,
960 gss_flags_t req_flags, OM_uint32 time_req,
961 gss_channel_bindings_t input_chan_bindings,
962 gss_buffer_t input_token,
963 gss_OID * actual_mech_type,
964 gss_buffer_t output_token, gss_flags_t * ret_flags,
965 OM_uint32 * time_rec)
975 if ((inp = input_token))
976 if (inp->length && inp->value) {
979 if (!(in.value = malloc(i + 1))) {
981 *minor_status = ENOMEM;
983 return GSS_S_FAILURE;
986 QadrtConvertA2E(in.value, input_token->value, i, i);
987 ((char *) in.value)[i] = '\0';
992 rc = gss_init_sec_context(minor_status, cred_handle, context_handle,
993 target_name, mech_type, req_flags, time_req,
994 input_chan_bindings, inp, actual_mech_type,
995 output_token, ret_flags, time_rec);
1000 if (rc != GSS_S_COMPLETE || !output_token ||
1001 !output_token->length || !output_token->value)
1004 /* No way to allocate a buffer here, because it will be released by
1005 gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
1006 with ASCII to return it. */
1008 if (Curl_gss_convert_in_place(minor_status, output_token))
1009 return GSS_S_FAILURE;
1016 Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
1017 gss_ctx_id_t * context_handle,
1018 gss_buffer_t output_token)
1023 rc = gss_delete_sec_context(minor_status, context_handle, output_token);
1025 if (rc != GSS_S_COMPLETE || !output_token ||
1026 !output_token->length || !output_token->value)
1029 /* No way to allocate a buffer here, because it will be released by
1030 gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
1031 with ASCII to return it. */
1033 if (Curl_gss_convert_in_place(minor_status, output_token))
1034 return GSS_S_FAILURE;
1039 #endif /* HAVE_GSSAPI */
1042 #ifndef CURL_DISABLE_LDAP
1044 /* ASCII wrappers for the LDAP procedures. */
1047 Curl_ldap_init_a(char * host, int port)
1055 return (void *) ldap_init(host, port);
1059 if (!(ehost = malloc(i + 1)))
1060 return (void *) NULL;
1062 QadrtConvertA2E(ehost, host, i, i);
1064 result = (void *) ldap_init(ehost, port);
1071 Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
1078 edn = (char *) NULL;
1079 epasswd = (char *) NULL;
1084 if (!(edn = malloc(i + 1)))
1085 return LDAP_NO_MEMORY;
1087 QadrtConvertA2E(edn, dn, i, i);
1094 if (!(epasswd = malloc(i + 1))) {
1098 return LDAP_NO_MEMORY;
1101 QadrtConvertA2E(epasswd, passwd, i, i);
1105 i = ldap_simple_bind_s(ld, edn, epasswd);
1118 Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
1119 char * * attrs, int attrsonly, LDAPMessage * * res)
1129 ebase = (char *) NULL;
1130 efilter = (char *) NULL;
1131 eattrs = (char * *) NULL;
1132 status = LDAP_SUCCESS;
1137 if (!(ebase = malloc(i + 1)))
1138 status = LDAP_NO_MEMORY;
1140 QadrtConvertA2E(ebase, base, i, i);
1145 if (filter && status == LDAP_SUCCESS) {
1148 if (!(efilter = malloc(i + 1)))
1149 status = LDAP_NO_MEMORY;
1151 QadrtConvertA2E(efilter, filter, i, i);
1156 if (attrs && status == LDAP_SUCCESS) {
1157 for (i = 0; attrs[i++];)
1160 if (!(eattrs = calloc(i, sizeof *eattrs)))
1161 status = LDAP_NO_MEMORY;
1163 for (j = 0; attrs[j]; j++) {
1164 i = strlen(attrs[j]);
1166 if (!(eattrs[j] = malloc(i + 1))) {
1167 status = LDAP_NO_MEMORY;
1171 QadrtConvertA2E(eattrs[j], attrs[j], i, i);
1172 eattrs[j][i] = '\0';
1177 if (status == LDAP_SUCCESS)
1178 status = ldap_search_s(ld, ebase? ebase: "", scope,
1179 efilter? efilter: "(objectclass=*)",
1180 eattrs, attrsonly, res);
1183 for (j = 0; eattrs[j]; j++)
1200 Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
1205 struct berval * * result;
1212 if (!(cp = malloc(i + 1))) {
1213 ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
1214 ldap_err2string(LDAP_NO_MEMORY));
1215 return (struct berval * *) NULL;
1218 QadrtConvertA2E(cp, attr, i, i);
1222 result = ldap_get_values_len(ld, entry, cp);
1227 /* Result data are binary in nature, so they haven't been converted to EBCDIC.
1228 Therefore do not convert. */
1235 Curl_ldap_err2string_a(int error)
1242 cp = ldap_err2string(error);
1249 if (!(cp2 = Curl_thread_buffer(LK_LDAP_ERROR, MAX_CONV_EXPANSION * i + 1)))
1252 i = QadrtConvertE2A(cp2, cp, MAX_CONV_EXPANSION * i, i);
1259 Curl_ldap_get_dn_a(void * ld, LDAPMessage * entry)
1266 cp = ldap_get_dn(ld, entry);
1273 if (!(cp2 = malloc(i + 1)))
1276 QadrtConvertE2A(cp2, cp, i, i);
1279 /* No way to allocate a buffer here, because it will be released by
1280 ldap_memfree() and ldap_memalloc() does not exist. The solution is to
1281 overwrite the EBCDIC buffer with ASCII to return it. */
1290 Curl_ldap_first_attribute_a(void * ld,
1291 LDAPMessage * entry, BerElement * * berptr)
1298 cp = ldap_first_attribute(ld, entry, berptr);
1305 if (!(cp2 = malloc(i + 1)))
1308 QadrtConvertE2A(cp2, cp, i, i);
1311 /* No way to allocate a buffer here, because it will be released by
1312 ldap_memfree() and ldap_memalloc() does not exist. The solution is to
1313 overwrite the EBCDIC buffer with ASCII to return it. */
1322 Curl_ldap_next_attribute_a(void * ld,
1323 LDAPMessage * entry, BerElement * berptr)
1330 cp = ldap_next_attribute(ld, entry, berptr);
1337 if (!(cp2 = malloc(i + 1)))
1340 QadrtConvertE2A(cp2, cp, i, i);
1343 /* No way to allocate a buffer here, because it will be released by
1344 ldap_memfree() and ldap_memalloc() does not exist. The solution is to
1345 overwrite the EBCDIC buffer with ASCII to return it. */
1352 #endif /* CURL_DISABLE_LDAP */
1356 convert_sockaddr(struct sockaddr_storage * dstaddr,
1357 const struct sockaddr * srcaddr, int srclen)
1360 const struct sockaddr_un * srcu;
1361 struct sockaddr_un * dstu;
1363 unsigned int dstsize;
1365 /* Convert a socket address into job CCSID, if needed. */
1367 if (!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
1368 sizeof srcaddr->sa_family || srclen > sizeof *dstaddr) {
1373 memcpy((char *) dstaddr, (char *) srcaddr, srclen);
1375 switch (srcaddr->sa_family) {
1378 srcu = (const struct sockaddr_un *) srcaddr;
1379 dstu = (struct sockaddr_un *) dstaddr;
1380 dstsize = sizeof *dstaddr - offsetof(struct sockaddr_un, sun_path);
1381 srclen -= offsetof(struct sockaddr_un, sun_path);
1382 i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen);
1383 dstu->sun_path[i] = '\0';
1384 i += offsetof(struct sockaddr_un, sun_path);
1393 Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
1397 struct sockaddr_storage laddr;
1399 i = convert_sockaddr(&laddr, destaddr, addrlen);
1404 return connect(sd, (struct sockaddr *) &laddr, i);
1409 Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
1413 struct sockaddr_storage laddr;
1415 i = convert_sockaddr(&laddr, localaddr, addrlen);
1420 return bind(sd, (struct sockaddr *) &laddr, i);
1425 Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
1426 struct sockaddr * dstaddr, int addrlen)
1430 struct sockaddr_storage laddr;
1432 i = convert_sockaddr(&laddr, dstaddr, addrlen);
1437 return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
1442 Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
1443 struct sockaddr * fromaddr, int * addrlen)
1449 const struct sockaddr_un * srcu;
1450 struct sockaddr_un * dstu;
1451 struct sockaddr_storage laddr;
1453 if (!fromaddr || !addrlen || *addrlen <= 0)
1454 return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);
1456 laddrlen = sizeof laddr;
1457 laddr.ss_family = AF_UNSPEC; /* To detect if unused. */
1458 rcvlen = recvfrom(sd, buffer, buflen, flags,
1459 (struct sockaddr *) &laddr, &laddrlen);
1464 switch (laddr.ss_family) {
1467 srcu = (const struct sockaddr_un *) &laddr;
1468 dstu = (struct sockaddr_un *) fromaddr;
1469 i = *addrlen - offsetof(struct sockaddr_un, sun_path);
1470 laddrlen -= offsetof(struct sockaddr_un, sun_path);
1471 i = QadrtConvertE2A(dstu->sun_path, srcu->sun_path, i, laddrlen);
1472 laddrlen = i + offsetof(struct sockaddr_un, sun_path);
1474 if (laddrlen < *addrlen)
1475 dstu->sun_path[i] = '\0';
1483 if (laddrlen > *addrlen)
1484 laddrlen = *addrlen;
1487 memcpy((char *) fromaddr, (char *) &laddr, laddrlen);
1492 *addrlen = laddrlen;