1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2014, 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)
98 buffer_t * p = (buffer_t *) private;
101 for(i = (localkey_t) 0; i < LK_LAST; i++) {
117 if(Curl_thread_buffer == buffer_threaded) {
118 locbufs = pthread_getspecific(thdkey);
119 pthread_setspecific(thdkey, (void *) NULL);
120 pthread_key_delete(thdkey);
123 if(Curl_thread_buffer != buffer_undef) {
124 thdbufdestroy((void *) locbufs);
125 locbufs = (buffer_t *) NULL;
128 Curl_thread_buffer = buffer_undef;
133 get_buffer(buffer_t * buf, long size)
138 /* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long.
139 Return the buffer address. */
145 if((buf->buf = malloc(size)))
151 if((unsigned long) size <= buf->size) {
152 /* Shorten the buffer only if it frees a significant byte count. This
153 avoids some realloc() overhead. */
155 if(buf->size - size < MIN_BYTE_GAIN)
159 /* Resize the buffer. */
161 if((cp = realloc(buf->buf, size))) {
165 else if(size <= buf->size)
173 buffer_unthreaded(localkey_t key, long size)
176 return get_buffer(locbufs + key, size);
181 buffer_threaded(localkey_t key, long size)
186 /* Get the buffer for the given local key in the current thread, and
187 make sure it is at least `size'-byte long. Set `size' to < 0 to get
190 bufs = (buffer_t *) pthread_getspecific(thdkey);
194 return (char *) NULL; /* No buffer yet. */
196 /* Allocate buffer descriptors for the current thread. */
198 if(!(bufs = calloc((size_t) LK_LAST, sizeof *bufs)))
199 return (char *) NULL;
201 if(pthread_setspecific(thdkey, (void *) bufs)) {
203 return (char *) NULL;
207 return get_buffer(bufs + key, size);
212 buffer_undef(localkey_t key, long size)
215 /* Define the buffer system, get the buffer for the given local key in
216 the current thread, and make sure it is at least `size'-byte long.
217 Set `size' to < 0 to get its address only. */
219 pthread_mutex_lock(&mutex);
221 /* Determine if we can use pthread-specific data. */
223 if(Curl_thread_buffer == buffer_undef) { /* If unchanged during lock. */
224 if(!pthread_key_create(&thdkey, thdbufdestroy))
225 Curl_thread_buffer = buffer_threaded;
226 else if(!(locbufs = calloc((size_t) LK_LAST, sizeof *locbufs))) {
227 pthread_mutex_unlock(&mutex);
228 return (char *) NULL;
231 Curl_thread_buffer = buffer_unthreaded;
236 pthread_mutex_unlock(&mutex);
237 return Curl_thread_buffer(key, size);
242 set_thread_string(localkey_t key, const char * s)
249 return (char *) NULL;
252 cp = Curl_thread_buffer(key, MAX_CONV_EXPANSION * i + 1);
255 i = QadrtConvertE2A(cp, s, MAX_CONV_EXPANSION * i, i);
264 Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
265 char * nodename, curl_socklen_t nodenamelen,
266 char * servname, curl_socklen_t servnamelen,
275 enodename = (char *) NULL;
276 eservname = (char *) NULL;
278 if(nodename && nodenamelen)
279 if(!(enodename = malloc(nodenamelen)))
282 if(servname && servnamelen)
283 if(!(eservname = malloc(servnamelen))) {
290 status = getnameinfo(sa, salen, enodename, nodenamelen,
291 eservname, servnamelen, flags);
295 i = QadrtConvertE2A(nodename, enodename,
296 nodenamelen - 1, strlen(enodename));
301 i = QadrtConvertE2A(servname, eservname,
302 servnamelen - 1, strlen(eservname));
318 Curl_getaddrinfo_a(const char * nodename, const char * servname,
319 const struct addrinfo * hints,
320 struct addrinfo * * res)
328 enodename = (char *) NULL;
329 eservname = (char *) NULL;
332 i = strlen(nodename);
334 if(!(enodename = malloc(i + 1)))
337 i = QadrtConvertA2E(enodename, nodename, i, i);
342 i = strlen(servname);
344 if(!(eservname = malloc(i + 1))) {
351 QadrtConvertA2E(eservname, servname, i, i);
355 status = getaddrinfo(enodename, eservname, hints, res);
369 /* ASCII wrappers for the GSKit procedures. */
372 * EBCDIC --> ASCII string mapping table.
373 * Some strings returned by GSKit are dynamically allocated and automatically
374 * released when closing the handle.
375 * To provide the same functionality, we use a "private" handle that
376 * holds the GSKit handle and a list of string mappings. This will allow
377 * avoid conversion of already converted strings and releasing them upon
382 struct gskstrlist * next;
383 const char * ebcdicstr;
384 const char * asciistr;
387 struct Curl_gsk_descriptor {
389 struct gskstrlist * strlist;
394 Curl_gsk_environment_open(gsk_handle * my_env_handle)
397 struct Curl_gsk_descriptor * p;
402 return GSK_OS400_ERROR_INVALID_POINTER;
403 if(!(p = (struct Curl_gsk_descriptor *) malloc(sizeof *p)))
404 return GSK_INSUFFICIENT_STORAGE;
405 p->strlist = (struct gskstrlist *) NULL;
406 if((rc = gsk_environment_open(&p->h)) != GSK_OK)
409 *my_env_handle = (gsk_handle) p;
415 Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
416 gsk_handle * my_session_handle)
419 struct Curl_gsk_descriptor * p;
424 return GSK_INVALID_HANDLE;
425 if(!my_session_handle)
426 return GSK_OS400_ERROR_INVALID_POINTER;
427 h = ((struct Curl_gsk_descriptor *) my_env_handle)->h;
428 if(!(p = (struct Curl_gsk_descriptor *) malloc(sizeof *p)))
429 return GSK_INSUFFICIENT_STORAGE;
430 p->strlist = (struct gskstrlist *) NULL;
431 if((rc = gsk_secure_soc_open(h, &p->h)) != GSK_OK)
434 *my_session_handle = (gsk_handle) p;
440 gsk_free_handle(struct Curl_gsk_descriptor * p)
443 struct gskstrlist * q;
445 while((q = p->strlist)) {
447 free((void *) q->asciistr);
455 Curl_gsk_environment_close(gsk_handle * my_env_handle)
458 struct Curl_gsk_descriptor * p;
462 return GSK_OS400_ERROR_INVALID_POINTER;
464 return GSK_INVALID_HANDLE;
465 p = (struct Curl_gsk_descriptor *) *my_env_handle;
466 if((rc = gsk_environment_close(&p->h)) == GSK_OK) {
468 *my_env_handle = (gsk_handle) NULL;
475 Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)
478 struct Curl_gsk_descriptor * p;
481 if(!my_session_handle)
482 return GSK_OS400_ERROR_INVALID_POINTER;
483 if(!*my_session_handle)
484 return GSK_INVALID_HANDLE;
485 p = (struct Curl_gsk_descriptor *) *my_session_handle;
486 if((rc = gsk_secure_soc_close(&p->h)) == GSK_OK) {
488 *my_session_handle = (gsk_handle) NULL;
495 Curl_gsk_environment_init(gsk_handle my_env_handle)
498 struct Curl_gsk_descriptor * p;
501 return GSK_INVALID_HANDLE;
502 p = (struct Curl_gsk_descriptor *) my_env_handle;
503 return gsk_environment_init(p->h);
508 Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
511 struct Curl_gsk_descriptor * p;
513 if(!my_session_handle)
514 return GSK_INVALID_HANDLE;
515 p = (struct Curl_gsk_descriptor *) my_session_handle;
516 return gsk_secure_soc_init(p->h);
521 Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
522 const char * buffer, int bufSize)
525 struct Curl_gsk_descriptor * p;
530 return GSK_INVALID_HANDLE;
532 return GSK_OS400_ERROR_INVALID_POINTER;
534 return GSK_ATTRIBUTE_INVALID_LENGTH;
535 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
537 bufSize = strlen(buffer);
538 if(!(ebcdicbuf = malloc(bufSize + 1)))
539 return GSK_INSUFFICIENT_STORAGE;
540 QadrtConvertA2E(ebcdicbuf, buffer, bufSize, bufSize);
541 ebcdicbuf[bufSize] = '\0';
542 rc = gsk_attribute_set_buffer(p->h, bufID, ebcdicbuf, bufSize);
549 Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
550 GSK_ENUM_VALUE enumValue)
553 struct Curl_gsk_descriptor * p;
556 return GSK_INVALID_HANDLE;
557 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
558 return gsk_attribute_set_enum(p->h, enumID, enumValue);
563 Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
564 GSK_NUM_ID numID, int numValue)
567 struct Curl_gsk_descriptor * p;
570 return GSK_INVALID_HANDLE;
571 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
572 return gsk_attribute_set_numeric_value(p->h, numID, numValue);
577 Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
578 GSK_CALLBACK_ID callBackID,
579 void * callBackAreaPtr)
582 struct Curl_gsk_descriptor * p;
585 return GSK_INVALID_HANDLE;
586 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
587 return gsk_attribute_set_callback(p->h, callBackID, callBackAreaPtr);
592 cachestring(struct Curl_gsk_descriptor * p,
593 const char * ebcdicbuf, int bufsize, const char * * buffer)
598 struct gskstrlist * sp;
600 for(sp = p->strlist; sp; sp = sp->next)
601 if(sp->ebcdicstr == ebcdicbuf)
604 if(!(sp = (struct gskstrlist *) malloc(sizeof *sp)))
605 return GSK_INSUFFICIENT_STORAGE;
606 if(!(asciibuf = malloc(bufsize + 1))) {
608 return GSK_INSUFFICIENT_STORAGE;
610 QadrtConvertE2A(asciibuf, ebcdicbuf, bufsize, bufsize);
611 asciibuf[bufsize] = '\0';
612 sp->ebcdicstr = ebcdicbuf;
613 sp->asciistr = asciibuf;
614 sp->next = p->strlist;
617 *buffer = sp->asciistr;
623 Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
624 const char * * buffer, int * bufSize)
627 struct Curl_gsk_descriptor * p;
633 return GSK_INVALID_HANDLE;
634 if(!buffer || !bufSize)
635 return GSK_OS400_ERROR_INVALID_POINTER;
636 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
637 if((rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen)) != GSK_OK)
639 if((rc = cachestring(p, mybuf, mylen, buffer)) == GSK_OK)
646 Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
647 GSK_ENUM_VALUE * enumValue)
650 struct Curl_gsk_descriptor * p;
653 return GSK_INVALID_HANDLE;
654 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
655 return gsk_attribute_get_enum(p->h, enumID, enumValue);
660 Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
661 GSK_NUM_ID numID, int * numValue)
664 struct Curl_gsk_descriptor * p;
667 return GSK_INVALID_HANDLE;
668 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
669 return gsk_attribute_get_numeric_value(p->h, numID, numValue);
674 Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
676 const gsk_cert_data_elem * * certDataElem,
677 int * certDataElementCount)
680 struct Curl_gsk_descriptor * p;
683 return GSK_INVALID_HANDLE;
684 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
685 /* No need to convert code: text results are already in ASCII. */
686 return gsk_attribute_get_cert_info(p->h, certID,
687 certDataElem, certDataElementCount);
692 Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, GSK_MISC_ID miscID)
695 struct Curl_gsk_descriptor * p;
697 if(!my_session_handle)
698 return GSK_INVALID_HANDLE;
699 p = (struct Curl_gsk_descriptor *) my_session_handle;
700 return gsk_secure_soc_misc(p->h, miscID);
705 Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char * readBuffer,
706 int readBufSize, int * amtRead)
709 struct Curl_gsk_descriptor * p;
711 if(!my_session_handle)
712 return GSK_INVALID_HANDLE;
713 p = (struct Curl_gsk_descriptor *) my_session_handle;
714 return gsk_secure_soc_read(p->h, readBuffer, readBufSize, amtRead);
719 Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char * writeBuffer,
720 int writeBufSize, int * amtWritten)
723 struct Curl_gsk_descriptor * p;
725 if(!my_session_handle)
726 return GSK_INVALID_HANDLE;
727 p = (struct Curl_gsk_descriptor *) my_session_handle;
728 return gsk_secure_soc_write(p->h, writeBuffer, writeBufSize, amtWritten);
733 Curl_gsk_strerror_a(int gsk_return_value)
736 return set_thread_string(LK_GSK_ERROR, gsk_strerror(gsk_return_value));
740 Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
741 int IOCompletionPort,
742 Qso_OverlappedIO_t * communicationsArea)
745 struct Curl_gsk_descriptor * p;
747 if(!my_session_handle)
748 return GSK_INVALID_HANDLE;
749 p = (struct Curl_gsk_descriptor *) my_session_handle;
750 return gsk_secure_soc_startInit(p->h, IOCompletionPort, communicationsArea);
753 #endif /* USE_GSKIT */
759 /* ASCII wrappers for the GSSAPI procedures. */
762 Curl_gss_convert_in_place(OM_uint32 * minor_status, gss_buffer_t buf)
768 /* Convert `buf' in place, from EBCDIC to ASCII.
769 If error, release the buffer and return -1. Else return 0. */
774 if(!(t = malloc(i))) {
775 gss_release_buffer(minor_status, buf);
778 *minor_status = ENOMEM;
783 QadrtConvertE2A(t, buf->value, i, i);
784 memcpy(buf->value, t, i);
793 Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
794 gss_OID in_name_type, gss_name_t * out_name)
801 if(!in_name || !in_name->value || !in_name->length)
802 return gss_import_name(minor_status, in_name, in_name_type, out_name);
804 memcpy((char *) &in, (char *) in_name, sizeof in);
807 if(!(in.value = malloc(i + 1))) {
809 *minor_status = ENOMEM;
811 return GSS_S_FAILURE;
814 QadrtConvertA2E(in.value, in_name->value, i, i);
815 ((char *) in.value)[i] = '\0';
816 rc = gss_import_name(minor_status, &in, in_name_type, out_name);
823 Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
824 int status_type, gss_OID mech_type,
825 gss_msg_ctx_t * message_context, gss_buffer_t status_string)
830 rc = gss_display_status(minor_status, status_value, status_type,
831 mech_type, message_context, status_string);
833 if(rc != GSS_S_COMPLETE || !status_string ||
834 !status_string->length || !status_string->value)
837 /* No way to allocate a buffer here, because it will be released by
838 gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
839 with ASCII to return it. */
841 if(Curl_gss_convert_in_place(minor_status, status_string))
842 return GSS_S_FAILURE;
849 Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
850 gss_cred_id_t cred_handle,
851 gss_ctx_id_t * context_handle,
852 gss_name_t target_name, gss_OID mech_type,
853 gss_flags_t req_flags, OM_uint32 time_req,
854 gss_channel_bindings_t input_chan_bindings,
855 gss_buffer_t input_token,
856 gss_OID * actual_mech_type,
857 gss_buffer_t output_token, gss_flags_t * ret_flags,
858 OM_uint32 * time_rec)
868 if((inp = input_token))
869 if(inp->length && inp->value) {
872 if(!(in.value = malloc(i + 1))) {
874 *minor_status = ENOMEM;
876 return GSS_S_FAILURE;
879 QadrtConvertA2E(in.value, input_token->value, i, i);
880 ((char *) in.value)[i] = '\0';
885 rc = gss_init_sec_context(minor_status, cred_handle, context_handle,
886 target_name, mech_type, req_flags, time_req,
887 input_chan_bindings, inp, actual_mech_type,
888 output_token, ret_flags, time_rec);
893 if(rc != GSS_S_COMPLETE || !output_token ||
894 !output_token->length || !output_token->value)
897 /* No way to allocate a buffer here, because it will be released by
898 gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
899 with ASCII to return it. */
901 if(Curl_gss_convert_in_place(minor_status, output_token))
902 return GSS_S_FAILURE;
909 Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
910 gss_ctx_id_t * context_handle,
911 gss_buffer_t output_token)
916 rc = gss_delete_sec_context(minor_status, context_handle, output_token);
918 if(rc != GSS_S_COMPLETE || !output_token ||
919 !output_token->length || !output_token->value)
922 /* No way to allocate a buffer here, because it will be released by
923 gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
924 with ASCII to return it. */
926 if(Curl_gss_convert_in_place(minor_status, output_token))
927 return GSS_S_FAILURE;
932 #endif /* HAVE_GSSAPI */
935 #ifndef CURL_DISABLE_LDAP
937 /* ASCII wrappers for the LDAP procedures. */
940 Curl_ldap_init_a(char * host, int port)
948 return (void *) ldap_init(host, port);
952 if(!(ehost = malloc(i + 1)))
953 return (void *) NULL;
955 QadrtConvertA2E(ehost, host, i, i);
957 result = (void *) ldap_init(ehost, port);
964 Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
972 epasswd = (char *) NULL;
977 if(!(edn = malloc(i + 1)))
978 return LDAP_NO_MEMORY;
980 QadrtConvertA2E(edn, dn, i, i);
987 if(!(epasswd = malloc(i + 1))) {
991 return LDAP_NO_MEMORY;
994 QadrtConvertA2E(epasswd, passwd, i, i);
998 i = ldap_simple_bind_s(ld, edn, epasswd);
1011 Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
1012 char * * attrs, int attrsonly, LDAPMessage * * res)
1022 ebase = (char *) NULL;
1023 efilter = (char *) NULL;
1024 eattrs = (char * *) NULL;
1025 status = LDAP_SUCCESS;
1030 if(!(ebase = malloc(i + 1)))
1031 status = LDAP_NO_MEMORY;
1033 QadrtConvertA2E(ebase, base, i, i);
1038 if(filter && status == LDAP_SUCCESS) {
1041 if(!(efilter = malloc(i + 1)))
1042 status = LDAP_NO_MEMORY;
1044 QadrtConvertA2E(efilter, filter, i, i);
1049 if(attrs && status == LDAP_SUCCESS) {
1050 for(i = 0; attrs[i++];)
1053 if(!(eattrs = calloc(i, sizeof *eattrs)))
1054 status = LDAP_NO_MEMORY;
1056 for(j = 0; attrs[j]; j++) {
1057 i = strlen(attrs[j]);
1059 if(!(eattrs[j] = malloc(i + 1))) {
1060 status = LDAP_NO_MEMORY;
1064 QadrtConvertA2E(eattrs[j], attrs[j], i, i);
1065 eattrs[j][i] = '\0';
1070 if(status == LDAP_SUCCESS)
1071 status = ldap_search_s(ld, ebase? ebase: "", scope,
1072 efilter? efilter: "(objectclass=*)",
1073 eattrs, attrsonly, res);
1076 for(j = 0; eattrs[j]; j++)
1093 Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
1097 struct berval * * result;
1102 int i = strlen(attr);
1104 if(!(cp = malloc(i + 1))) {
1105 ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
1106 ldap_err2string(LDAP_NO_MEMORY));
1107 return (struct berval * *) NULL;
1110 QadrtConvertA2E(cp, attr, i, i);
1114 result = ldap_get_values_len(ld, entry, cp);
1119 /* Result data are binary in nature, so they haven't been
1120 converted to EBCDIC. Therefore do not convert. */
1127 Curl_ldap_err2string_a(int error)
1130 return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
1135 Curl_ldap_get_dn_a(void * ld, LDAPMessage * entry)
1142 cp = ldap_get_dn(ld, entry);
1149 if(!(cp2 = malloc(i + 1)))
1152 QadrtConvertE2A(cp2, cp, i, i);
1155 /* No way to allocate a buffer here, because it will be released by
1156 ldap_memfree() and ldap_memalloc() does not exist. The solution is to
1157 overwrite the EBCDIC buffer with ASCII to return it. */
1166 Curl_ldap_first_attribute_a(void * ld,
1167 LDAPMessage * entry, BerElement * * berptr)
1174 cp = ldap_first_attribute(ld, entry, berptr);
1181 if(!(cp2 = malloc(i + 1)))
1184 QadrtConvertE2A(cp2, cp, i, i);
1187 /* No way to allocate a buffer here, because it will be released by
1188 ldap_memfree() and ldap_memalloc() does not exist. The solution is to
1189 overwrite the EBCDIC buffer with ASCII to return it. */
1198 Curl_ldap_next_attribute_a(void * ld,
1199 LDAPMessage * entry, BerElement * berptr)
1206 cp = ldap_next_attribute(ld, entry, berptr);
1213 if(!(cp2 = malloc(i + 1)))
1216 QadrtConvertE2A(cp2, cp, i, i);
1219 /* No way to allocate a buffer here, because it will be released by
1220 ldap_memfree() and ldap_memalloc() does not exist. The solution is to
1221 overwrite the EBCDIC buffer with ASCII to return it. */
1228 #endif /* CURL_DISABLE_LDAP */
1232 convert_sockaddr(struct sockaddr_storage * dstaddr,
1233 const struct sockaddr * srcaddr, int srclen)
1236 const struct sockaddr_un * srcu;
1237 struct sockaddr_un * dstu;
1239 unsigned int dstsize;
1241 /* Convert a socket address into job CCSID, if needed. */
1243 if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
1244 sizeof srcaddr->sa_family || srclen > sizeof *dstaddr) {
1249 memcpy((char *) dstaddr, (char *) srcaddr, srclen);
1251 switch (srcaddr->sa_family) {
1254 srcu = (const struct sockaddr_un *) srcaddr;
1255 dstu = (struct sockaddr_un *) dstaddr;
1256 dstsize = sizeof *dstaddr - offsetof(struct sockaddr_un, sun_path);
1257 srclen -= offsetof(struct sockaddr_un, sun_path);
1258 i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen);
1259 dstu->sun_path[i] = '\0';
1260 i += offsetof(struct sockaddr_un, sun_path);
1269 Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
1273 struct sockaddr_storage laddr;
1275 i = convert_sockaddr(&laddr, destaddr, addrlen);
1280 return connect(sd, (struct sockaddr *) &laddr, i);
1285 Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
1289 struct sockaddr_storage laddr;
1291 i = convert_sockaddr(&laddr, localaddr, addrlen);
1296 return bind(sd, (struct sockaddr *) &laddr, i);
1301 Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
1302 struct sockaddr * dstaddr, int addrlen)
1306 struct sockaddr_storage laddr;
1308 i = convert_sockaddr(&laddr, dstaddr, addrlen);
1313 return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
1318 Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
1319 struct sockaddr * fromaddr, int * addrlen)
1325 const struct sockaddr_un * srcu;
1326 struct sockaddr_un * dstu;
1327 struct sockaddr_storage laddr;
1329 if(!fromaddr || !addrlen || *addrlen <= 0)
1330 return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);
1332 laddrlen = sizeof laddr;
1333 laddr.ss_family = AF_UNSPEC; /* To detect if unused. */
1334 rcvlen = recvfrom(sd, buffer, buflen, flags,
1335 (struct sockaddr *) &laddr, &laddrlen);
1340 switch (laddr.ss_family) {
1343 srcu = (const struct sockaddr_un *) &laddr;
1344 dstu = (struct sockaddr_un *) fromaddr;
1345 i = *addrlen - offsetof(struct sockaddr_un, sun_path);
1346 laddrlen -= offsetof(struct sockaddr_un, sun_path);
1347 i = QadrtConvertE2A(dstu->sun_path, srcu->sun_path, i, laddrlen);
1348 laddrlen = i + offsetof(struct sockaddr_un, sun_path);
1350 if(laddrlen < *addrlen)
1351 dstu->sun_path[i] = '\0';
1359 if(laddrlen > *addrlen)
1360 laddrlen = *addrlen;
1363 memcpy((char *) fromaddr, (char *) &laddr, laddrlen);
1368 *addrlen = laddrlen;
1375 Curl_os400_zlibVersion(void)
1378 return set_thread_string(LK_ZLIB_VERSION, zlibVersion());
1383 Curl_os400_inflateInit_(z_streamp strm, const char * version, int stream_size)
1386 z_const char * msgb4 = strm->msg;
1389 ret = inflateInit(strm);
1391 if(strm->msg != msgb4)
1392 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1399 Curl_os400_inflateInit2_(z_streamp strm, int windowBits,
1400 const char * version, int stream_size)
1403 z_const char * msgb4 = strm->msg;
1406 ret = inflateInit2(strm, windowBits);
1408 if(strm->msg != msgb4)
1409 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1416 Curl_os400_inflate(z_streamp strm, int flush)
1419 z_const char * msgb4 = strm->msg;
1422 ret = inflate(strm, flush);
1424 if(strm->msg != msgb4)
1425 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1432 Curl_os400_inflateEnd(z_streamp strm)
1435 z_const char * msgb4 = strm->msg;
1438 ret = inflateEnd(strm);
1440 if(strm->msg != msgb4)
1441 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);