comparison mupdf-source/thirdparty/curl/packages/OS400/os400sys.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.haxx.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 *
22 ***************************************************************************/
23
24 /* OS/400 additional support. */
25
26 #include <curl/curl.h>
27 #include "config-os400.h" /* Not curl_setup.h: we only need some defines. */
28
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <sys/un.h>
32
33 #include <stdlib.h>
34 #include <stddef.h>
35 #include <string.h>
36 #include <pthread.h>
37 #include <netdb.h>
38 #include <qadrt.h>
39 #include <errno.h>
40
41 #ifdef HAVE_ZLIB_H
42 #include <zlib.h>
43 #endif
44
45 #ifdef USE_GSKIT
46 #include <gskssl.h>
47 #include <qsoasync.h>
48 #endif
49
50 #ifdef HAVE_GSSAPI
51 #include <gssapi.h>
52 #endif
53
54 #ifndef CURL_DISABLE_LDAP
55 #include <ldap.h>
56 #endif
57
58 #include <netinet/in.h>
59 #include <arpa/inet.h>
60
61 #include "os400sys.h"
62
63
64 /**
65 *** QADRT OS/400 ASCII runtime defines only the most used procedures, but
66 *** but a lot of them are not supported. This module implements
67 *** ASCII wrappers for those that are used by libcurl, but not
68 *** defined by QADRT.
69 **/
70
71 #pragma convert(0) /* Restore EBCDIC. */
72
73
74 #define MIN_BYTE_GAIN 1024 /* Minimum gain when shortening a buffer. */
75
76 typedef struct {
77 unsigned long size; /* Buffer size. */
78 char * buf; /* Buffer address. */
79 } buffer_t;
80
81
82 static char * buffer_undef(localkey_t key, long size);
83 static char * buffer_threaded(localkey_t key, long size);
84 static char * buffer_unthreaded(localkey_t key, long size);
85
86 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
87 static pthread_key_t thdkey;
88 static buffer_t * locbufs;
89
90 char * (* Curl_thread_buffer)(localkey_t key, long size) = buffer_undef;
91
92
93 static void
94 thdbufdestroy(void * private)
95
96 {
97 if(private) {
98 buffer_t * p = (buffer_t *) private;
99 localkey_t i;
100
101 for(i = (localkey_t) 0; i < LK_LAST; i++) {
102 free(p->buf);
103 p++;
104 }
105
106 free(private);
107 }
108 }
109
110
111 static void
112 terminate(void)
113
114 {
115 if(Curl_thread_buffer == buffer_threaded) {
116 locbufs = pthread_getspecific(thdkey);
117 pthread_setspecific(thdkey, (void *) NULL);
118 pthread_key_delete(thdkey);
119 }
120
121 if(Curl_thread_buffer != buffer_undef) {
122 thdbufdestroy((void *) locbufs);
123 locbufs = (buffer_t *) NULL;
124 }
125
126 Curl_thread_buffer = buffer_undef;
127 }
128
129
130 static char *
131 get_buffer(buffer_t * buf, long size)
132
133 {
134 char * cp;
135
136 /* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long.
137 Return the buffer address. */
138
139 if(size < 0)
140 return buf->buf;
141
142 if(!buf->buf) {
143 buf->buf = malloc(size);
144 if(buf->buf)
145 buf->size = size;
146
147 return buf->buf;
148 }
149
150 if((unsigned long) size <= buf->size) {
151 /* Shorten the buffer only if it frees a significant byte count. This
152 avoids some realloc() overhead. */
153
154 if(buf->size - size < MIN_BYTE_GAIN)
155 return buf->buf;
156 }
157
158 /* Resize the buffer. */
159
160 cp = realloc(buf->buf, size);
161 if(cp) {
162 buf->buf = cp;
163 buf->size = size;
164 }
165 else if(size <= buf->size)
166 cp = buf->buf;
167
168 return cp;
169 }
170
171
172 static char *
173 buffer_unthreaded(localkey_t key, long size)
174
175 {
176 return get_buffer(locbufs + key, size);
177 }
178
179
180 static char *
181 buffer_threaded(localkey_t key, long size)
182
183 {
184 buffer_t * bufs;
185
186 /* Get the buffer for the given local key in the current thread, and
187 make sure it is at least `size'-byte long. Set `size' to < 0 to get
188 its address only. */
189
190 bufs = (buffer_t *) pthread_getspecific(thdkey);
191
192 if(!bufs) {
193 if(size < 0)
194 return (char *) NULL; /* No buffer yet. */
195
196 /* Allocate buffer descriptors for the current thread. */
197
198 bufs = calloc((size_t) LK_LAST, sizeof *bufs);
199 if(!bufs)
200 return (char *) NULL;
201
202 if(pthread_setspecific(thdkey, (void *) bufs)) {
203 free(bufs);
204 return (char *) NULL;
205 }
206 }
207
208 return get_buffer(bufs + key, size);
209 }
210
211
212 static char *
213 buffer_undef(localkey_t key, long size)
214
215 {
216 /* Define the buffer system, get the buffer for the given local key in
217 the current thread, and make sure it is at least `size'-byte long.
218 Set `size' to < 0 to get its address only. */
219
220 pthread_mutex_lock(&mutex);
221
222 /* Determine if we can use pthread-specific data. */
223
224 if(Curl_thread_buffer == buffer_undef) { /* If unchanged during lock. */
225 if(!pthread_key_create(&thdkey, thdbufdestroy))
226 Curl_thread_buffer = buffer_threaded;
227 else if(!(locbufs = calloc((size_t) LK_LAST, sizeof *locbufs))) {
228 pthread_mutex_unlock(&mutex);
229 return (char *) NULL;
230 }
231 else
232 Curl_thread_buffer = buffer_unthreaded;
233
234 atexit(terminate);
235 }
236
237 pthread_mutex_unlock(&mutex);
238 return Curl_thread_buffer(key, size);
239 }
240
241
242 static char *
243 set_thread_string(localkey_t key, const char * s)
244
245 {
246 int i;
247 char * cp;
248
249 if(!s)
250 return (char *) NULL;
251
252 i = strlen(s) + 1;
253 cp = Curl_thread_buffer(key, MAX_CONV_EXPANSION * i + 1);
254
255 if(cp) {
256 i = QadrtConvertE2A(cp, s, MAX_CONV_EXPANSION * i, i);
257 cp[i] = '\0';
258 }
259
260 return cp;
261 }
262
263
264 int
265 Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
266 char * nodename, curl_socklen_t nodenamelen,
267 char * servname, curl_socklen_t servnamelen,
268 int flags)
269
270 {
271 char *enodename = NULL;
272 char *eservname = NULL;
273 int status;
274
275 if(nodename && nodenamelen) {
276 enodename = malloc(nodenamelen);
277 if(!enodename)
278 return EAI_MEMORY;
279 }
280
281 if(servname && servnamelen) {
282 eservname = malloc(servnamelen);
283 if(!eservname) {
284 free(enodename);
285 return EAI_MEMORY;
286 }
287 }
288
289 status = getnameinfo(sa, salen, enodename, nodenamelen,
290 eservname, servnamelen, flags);
291
292 if(!status) {
293 int i;
294 if(enodename) {
295 i = QadrtConvertE2A(nodename, enodename,
296 nodenamelen - 1, strlen(enodename));
297 nodename[i] = '\0';
298 }
299
300 if(eservname) {
301 i = QadrtConvertE2A(servname, eservname,
302 servnamelen - 1, strlen(eservname));
303 servname[i] = '\0';
304 }
305 }
306
307 free(enodename);
308 free(eservname);
309 return status;
310 }
311
312
313 int
314 Curl_getaddrinfo_a(const char * nodename, const char * servname,
315 const struct addrinfo * hints,
316 struct addrinfo * * res)
317
318 {
319 char * enodename;
320 char * eservname;
321 int status;
322 int i;
323
324 enodename = (char *) NULL;
325 eservname = (char *) NULL;
326
327 if(nodename) {
328 i = strlen(nodename);
329
330 enodename = malloc(i + 1);
331 if(!enodename)
332 return EAI_MEMORY;
333
334 i = QadrtConvertA2E(enodename, nodename, i, i);
335 enodename[i] = '\0';
336 }
337
338 if(servname) {
339 i = strlen(servname);
340
341 eservname = malloc(i + 1);
342 if(!eservname) {
343 free(enodename);
344 return EAI_MEMORY;
345 }
346
347 QadrtConvertA2E(eservname, servname, i, i);
348 eservname[i] = '\0';
349 }
350
351 status = getaddrinfo(enodename, eservname, hints, res);
352 free(enodename);
353 free(eservname);
354 return status;
355 }
356
357
358 #ifdef USE_GSKIT
359
360 /* ASCII wrappers for the GSKit procedures. */
361
362 /*
363 * EBCDIC --> ASCII string mapping table.
364 * Some strings returned by GSKit are dynamically allocated and automatically
365 * released when closing the handle.
366 * To provide the same functionality, we use a "private" handle that
367 * holds the GSKit handle and a list of string mappings. This will allow
368 * avoid conversion of already converted strings and releasing them upon
369 * close time.
370 */
371
372 struct gskstrlist {
373 struct gskstrlist * next;
374 const char * ebcdicstr;
375 const char * asciistr;
376 };
377
378 struct Curl_gsk_descriptor {
379 gsk_handle h;
380 struct gskstrlist * strlist;
381 };
382
383
384 int
385 Curl_gsk_environment_open(gsk_handle * my_env_handle)
386
387 {
388 struct Curl_gsk_descriptor * p;
389 int rc;
390
391 if(!my_env_handle)
392 return GSK_OS400_ERROR_INVALID_POINTER;
393 p = (struct Curl_gsk_descriptor *) malloc(sizeof *p);
394 if(!p)
395 return GSK_INSUFFICIENT_STORAGE;
396 p->strlist = (struct gskstrlist *) NULL;
397 rc = gsk_environment_open(&p->h);
398 if(rc != GSK_OK)
399 free(p);
400 else
401 *my_env_handle = (gsk_handle) p;
402 return rc;
403 }
404
405
406 int
407 Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
408 gsk_handle * my_session_handle)
409
410 {
411 struct Curl_gsk_descriptor * p;
412 gsk_handle h;
413 int rc;
414
415 if(!my_env_handle)
416 return GSK_INVALID_HANDLE;
417 if(!my_session_handle)
418 return GSK_OS400_ERROR_INVALID_POINTER;
419 h = ((struct Curl_gsk_descriptor *) my_env_handle)->h;
420 p = (struct Curl_gsk_descriptor *) malloc(sizeof *p);
421 if(!p)
422 return GSK_INSUFFICIENT_STORAGE;
423 p->strlist = (struct gskstrlist *) NULL;
424 rc = gsk_secure_soc_open(h, &p->h);
425 if(rc != GSK_OK)
426 free(p);
427 else
428 *my_session_handle = (gsk_handle) p;
429 return rc;
430 }
431
432
433 static void
434 gsk_free_handle(struct Curl_gsk_descriptor * p)
435
436 {
437 struct gskstrlist * q;
438
439 while((q = p->strlist)) {
440 p->strlist = q;
441 free((void *) q->asciistr);
442 free(q);
443 }
444 free(p);
445 }
446
447
448 int
449 Curl_gsk_environment_close(gsk_handle * my_env_handle)
450
451 {
452 struct Curl_gsk_descriptor * p;
453 int rc;
454
455 if(!my_env_handle)
456 return GSK_OS400_ERROR_INVALID_POINTER;
457 if(!*my_env_handle)
458 return GSK_INVALID_HANDLE;
459 p = (struct Curl_gsk_descriptor *) *my_env_handle;
460 rc = gsk_environment_close(&p->h);
461 if(rc == GSK_OK) {
462 gsk_free_handle(p);
463 *my_env_handle = (gsk_handle) NULL;
464 }
465 return rc;
466 }
467
468
469 int
470 Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)
471
472 {
473 struct Curl_gsk_descriptor * p;
474 int rc;
475
476 if(!my_session_handle)
477 return GSK_OS400_ERROR_INVALID_POINTER;
478 if(!*my_session_handle)
479 return GSK_INVALID_HANDLE;
480 p = (struct Curl_gsk_descriptor *) *my_session_handle;
481 rc = gsk_secure_soc_close(&p->h);
482 if(rc == GSK_OK) {
483 gsk_free_handle(p);
484 *my_session_handle = (gsk_handle) NULL;
485 }
486 return rc;
487 }
488
489
490 int
491 Curl_gsk_environment_init(gsk_handle my_env_handle)
492
493 {
494 struct Curl_gsk_descriptor * p;
495
496 if(!my_env_handle)
497 return GSK_INVALID_HANDLE;
498 p = (struct Curl_gsk_descriptor *) my_env_handle;
499 return gsk_environment_init(p->h);
500 }
501
502
503 int
504 Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
505
506 {
507 struct Curl_gsk_descriptor * p;
508
509 if(!my_session_handle)
510 return GSK_INVALID_HANDLE;
511 p = (struct Curl_gsk_descriptor *) my_session_handle;
512 return gsk_secure_soc_init(p->h);
513 }
514
515
516 int
517 Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
518 const char * buffer, int bufSize)
519
520 {
521 struct Curl_gsk_descriptor * p;
522 char * ebcdicbuf;
523 int rc;
524
525 if(!my_gsk_handle)
526 return GSK_INVALID_HANDLE;
527 if(!buffer)
528 return GSK_OS400_ERROR_INVALID_POINTER;
529 if(bufSize < 0)
530 return GSK_ATTRIBUTE_INVALID_LENGTH;
531 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
532 if(!bufSize)
533 bufSize = strlen(buffer);
534 ebcdicbuf = malloc(bufSize + 1);
535 if(!ebcdicbuf)
536 return GSK_INSUFFICIENT_STORAGE;
537 QadrtConvertA2E(ebcdicbuf, buffer, bufSize, bufSize);
538 ebcdicbuf[bufSize] = '\0';
539 rc = gsk_attribute_set_buffer(p->h, bufID, ebcdicbuf, bufSize);
540 free(ebcdicbuf);
541 return rc;
542 }
543
544
545 int
546 Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
547 GSK_ENUM_VALUE enumValue)
548
549 {
550 struct Curl_gsk_descriptor * p;
551
552 if(!my_gsk_handle)
553 return GSK_INVALID_HANDLE;
554 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
555 return gsk_attribute_set_enum(p->h, enumID, enumValue);
556 }
557
558
559 int
560 Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
561 GSK_NUM_ID numID, int numValue)
562
563 {
564 struct Curl_gsk_descriptor * p;
565
566 if(!my_gsk_handle)
567 return GSK_INVALID_HANDLE;
568 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
569 return gsk_attribute_set_numeric_value(p->h, numID, numValue);
570 }
571
572
573 int
574 Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
575 GSK_CALLBACK_ID callBackID,
576 void * callBackAreaPtr)
577
578 {
579 struct Curl_gsk_descriptor * p;
580
581 if(!my_gsk_handle)
582 return GSK_INVALID_HANDLE;
583 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
584 return gsk_attribute_set_callback(p->h, callBackID, callBackAreaPtr);
585 }
586
587
588 static int
589 cachestring(struct Curl_gsk_descriptor * p,
590 const char * ebcdicbuf, int bufsize, const char * * buffer)
591
592 {
593 int rc;
594 char * asciibuf;
595 struct gskstrlist * sp;
596
597 for(sp = p->strlist; sp; sp = sp->next)
598 if(sp->ebcdicstr == ebcdicbuf)
599 break;
600 if(!sp) {
601 sp = (struct gskstrlist *) malloc(sizeof *sp);
602 if(!sp)
603 return GSK_INSUFFICIENT_STORAGE;
604 asciibuf = malloc(bufsize + 1);
605 if(!asciibuf) {
606 free(sp);
607 return GSK_INSUFFICIENT_STORAGE;
608 }
609 QadrtConvertE2A(asciibuf, ebcdicbuf, bufsize, bufsize);
610 asciibuf[bufsize] = '\0';
611 sp->ebcdicstr = ebcdicbuf;
612 sp->asciistr = asciibuf;
613 sp->next = p->strlist;
614 p->strlist = sp;
615 }
616 *buffer = sp->asciistr;
617 return GSK_OK;
618 }
619
620
621 int
622 Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
623 const char * * buffer, int * bufSize)
624
625 {
626 struct Curl_gsk_descriptor * p;
627 int rc;
628 const char * mybuf;
629 int mylen;
630
631 if(!my_gsk_handle)
632 return GSK_INVALID_HANDLE;
633 if(!buffer || !bufSize)
634 return GSK_OS400_ERROR_INVALID_POINTER;
635 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
636 rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen);
637 if(rc != GSK_OK)
638 return rc;
639 rc = cachestring(p, mybuf, mylen, buffer);
640 if(rc == GSK_OK)
641 *bufSize = mylen;
642 return rc;
643 }
644
645
646 int
647 Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
648 GSK_ENUM_VALUE * enumValue)
649
650 {
651 struct Curl_gsk_descriptor * p;
652
653 if(!my_gsk_handle)
654 return GSK_INVALID_HANDLE;
655 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
656 return gsk_attribute_get_enum(p->h, enumID, enumValue);
657 }
658
659
660 int
661 Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
662 GSK_NUM_ID numID, int * numValue)
663
664 {
665 struct Curl_gsk_descriptor * p;
666
667 if(!my_gsk_handle)
668 return GSK_INVALID_HANDLE;
669 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
670 return gsk_attribute_get_numeric_value(p->h, numID, numValue);
671 }
672
673
674 int
675 Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
676 GSK_CERT_ID certID,
677 const gsk_cert_data_elem * * certDataElem,
678 int * certDataElementCount)
679
680 {
681 struct Curl_gsk_descriptor * p;
682
683 if(!my_gsk_handle)
684 return GSK_INVALID_HANDLE;
685 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
686 /* No need to convert code: text results are already in ASCII. */
687 return gsk_attribute_get_cert_info(p->h, certID,
688 certDataElem, certDataElementCount);
689 }
690
691
692 int
693 Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, GSK_MISC_ID miscID)
694
695 {
696 struct Curl_gsk_descriptor * p;
697
698 if(!my_session_handle)
699 return GSK_INVALID_HANDLE;
700 p = (struct Curl_gsk_descriptor *) my_session_handle;
701 return gsk_secure_soc_misc(p->h, miscID);
702 }
703
704
705 int
706 Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char * readBuffer,
707 int readBufSize, int * amtRead)
708
709 {
710 struct Curl_gsk_descriptor * p;
711
712 if(!my_session_handle)
713 return GSK_INVALID_HANDLE;
714 p = (struct Curl_gsk_descriptor *) my_session_handle;
715 return gsk_secure_soc_read(p->h, readBuffer, readBufSize, amtRead);
716 }
717
718
719 int
720 Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char * writeBuffer,
721 int writeBufSize, int * amtWritten)
722
723 {
724 struct Curl_gsk_descriptor * p;
725
726 if(!my_session_handle)
727 return GSK_INVALID_HANDLE;
728 p = (struct Curl_gsk_descriptor *) my_session_handle;
729 return gsk_secure_soc_write(p->h, writeBuffer, writeBufSize, amtWritten);
730 }
731
732
733 const char *
734 Curl_gsk_strerror_a(int gsk_return_value)
735
736 {
737 return set_thread_string(LK_GSK_ERROR, gsk_strerror(gsk_return_value));
738 }
739
740 int
741 Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
742 int IOCompletionPort,
743 Qso_OverlappedIO_t * communicationsArea)
744
745 {
746 struct Curl_gsk_descriptor * p;
747
748 if(!my_session_handle)
749 return GSK_INVALID_HANDLE;
750 p = (struct Curl_gsk_descriptor *) my_session_handle;
751 return gsk_secure_soc_startInit(p->h, IOCompletionPort, communicationsArea);
752 }
753
754 #endif /* USE_GSKIT */
755
756
757
758 #ifdef HAVE_GSSAPI
759
760 /* ASCII wrappers for the GSSAPI procedures. */
761
762 static int
763 Curl_gss_convert_in_place(OM_uint32 * minor_status, gss_buffer_t buf)
764
765 {
766 unsigned int i = buf->length;
767
768 /* Convert `buf' in place, from EBCDIC to ASCII.
769 If error, release the buffer and return -1. Else return 0. */
770
771 if(i) {
772 char *t = malloc(i);
773 if(!t) {
774 gss_release_buffer(minor_status, buf);
775
776 if(minor_status)
777 *minor_status = ENOMEM;
778
779 return -1;
780 }
781
782 QadrtConvertE2A(t, buf->value, i, i);
783 memcpy(buf->value, t, i);
784 free(t);
785 }
786
787 return 0;
788 }
789
790
791 OM_uint32
792 Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
793 gss_OID in_name_type, gss_name_t * out_name)
794
795 {
796 int rc;
797 unsigned int i;
798 gss_buffer_desc in;
799
800 if(!in_name || !in_name->value || !in_name->length)
801 return gss_import_name(minor_status, in_name, in_name_type, out_name);
802
803 memcpy((char *) &in, (char *) in_name, sizeof in);
804 i = in.length;
805
806 in.value = malloc(i + 1);
807 if(!in.value) {
808 if(minor_status)
809 *minor_status = ENOMEM;
810
811 return GSS_S_FAILURE;
812 }
813
814 QadrtConvertA2E(in.value, in_name->value, i, i);
815 ((char *) in.value)[i] = '\0';
816 rc = gss_import_name(minor_status, &in, in_name_type, out_name);
817 free(in.value);
818 return rc;
819 }
820
821
822 OM_uint32
823 Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
824 int status_type, gss_OID mech_type,
825 gss_msg_ctx_t * message_context, gss_buffer_t status_string)
826
827 {
828 int rc;
829
830 rc = gss_display_status(minor_status, status_value, status_type,
831 mech_type, message_context, status_string);
832
833 if(rc != GSS_S_COMPLETE || !status_string ||
834 !status_string->length || !status_string->value)
835 return rc;
836
837 /* No way to allocate a buffer here, because it will be released by
838 gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
839 with ASCII to return it. */
840
841 if(Curl_gss_convert_in_place(minor_status, status_string))
842 return GSS_S_FAILURE;
843
844 return rc;
845 }
846
847
848 OM_uint32
849 Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
850 gss_cred_id_t cred_handle,
851 gss_ctx_id_t * context_handle,
852 gss_name_t target_name, gss_OID mech_type,
853 gss_flags_t req_flags, OM_uint32 time_req,
854 gss_channel_bindings_t input_chan_bindings,
855 gss_buffer_t input_token,
856 gss_OID * actual_mech_type,
857 gss_buffer_t output_token, gss_flags_t * ret_flags,
858 OM_uint32 * time_rec)
859
860 {
861 int rc;
862 gss_buffer_desc in;
863 gss_buffer_t inp;
864
865 in.value = NULL;
866 inp = input_token;
867
868 if(inp) {
869 if(inp->length && inp->value) {
870 unsigned int i = inp->length;
871
872 in.value = malloc(i + 1);
873 if(!in.value) {
874 if(minor_status)
875 *minor_status = ENOMEM;
876
877 return GSS_S_FAILURE;
878 }
879
880 QadrtConvertA2E(in.value, input_token->value, i, i);
881 ((char *) in.value)[i] = '\0';
882 in.length = i;
883 inp = &in;
884 }
885 }
886
887 rc = gss_init_sec_context(minor_status, cred_handle, context_handle,
888 target_name, mech_type, req_flags, time_req,
889 input_chan_bindings, inp, actual_mech_type,
890 output_token, ret_flags, time_rec);
891 free(in.value);
892
893 if(rc != GSS_S_COMPLETE || !output_token ||
894 !output_token->length || !output_token->value)
895 return rc;
896
897 /* No way to allocate a buffer here, because it will be released by
898 gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
899 with ASCII to return it. */
900
901 if(Curl_gss_convert_in_place(minor_status, output_token))
902 return GSS_S_FAILURE;
903
904 return rc;
905 }
906
907
908 OM_uint32
909 Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
910 gss_ctx_id_t * context_handle,
911 gss_buffer_t output_token)
912
913 {
914 int rc;
915
916 rc = gss_delete_sec_context(minor_status, context_handle, output_token);
917
918 if(rc != GSS_S_COMPLETE || !output_token ||
919 !output_token->length || !output_token->value)
920 return rc;
921
922 /* No way to allocate a buffer here, because it will be released by
923 gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
924 with ASCII to return it. */
925
926 if(Curl_gss_convert_in_place(minor_status, output_token))
927 return GSS_S_FAILURE;
928
929 return rc;
930 }
931
932 #endif /* HAVE_GSSAPI */
933
934
935 #ifndef CURL_DISABLE_LDAP
936
937 /* ASCII wrappers for the LDAP procedures. */
938
939 void *
940 Curl_ldap_init_a(char * host, int port)
941
942 {
943 unsigned int i;
944 char * ehost;
945 void * result;
946
947 if(!host)
948 return (void *) ldap_init(host, port);
949
950 i = strlen(host);
951
952 ehost = malloc(i + 1);
953 if(!ehost)
954 return (void *) NULL;
955
956 QadrtConvertA2E(ehost, host, i, i);
957 ehost[i] = '\0';
958 result = (void *) ldap_init(ehost, port);
959 free(ehost);
960 return result;
961 }
962
963
964 int
965 Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
966
967 {
968 int i;
969 char * edn;
970 char * epasswd;
971
972 edn = (char *) NULL;
973 epasswd = (char *) NULL;
974
975 if(dn) {
976 i = strlen(dn);
977
978 edn = malloc(i + 1);
979 if(!edn)
980 return LDAP_NO_MEMORY;
981
982 QadrtConvertA2E(edn, dn, i, i);
983 edn[i] = '\0';
984 }
985
986 if(passwd) {
987 i = strlen(passwd);
988
989 epasswd = malloc(i + 1);
990 if(!epasswd) {
991 free(edn);
992 return LDAP_NO_MEMORY;
993 }
994
995 QadrtConvertA2E(epasswd, passwd, i, i);
996 epasswd[i] = '\0';
997 }
998
999 i = ldap_simple_bind_s(ld, edn, epasswd);
1000 free(epasswd);
1001 free(edn);
1002 return i;
1003 }
1004
1005
1006 int
1007 Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
1008 char * * attrs, int attrsonly, LDAPMessage * * res)
1009
1010 {
1011 int i;
1012 int j;
1013 char * ebase;
1014 char * efilter;
1015 char * * eattrs;
1016 int status;
1017
1018 ebase = (char *) NULL;
1019 efilter = (char *) NULL;
1020 eattrs = (char * *) NULL;
1021 status = LDAP_SUCCESS;
1022
1023 if(base) {
1024 i = strlen(base);
1025
1026 ebase = malloc(i + 1);
1027 if(!ebase)
1028 status = LDAP_NO_MEMORY;
1029 else {
1030 QadrtConvertA2E(ebase, base, i, i);
1031 ebase[i] = '\0';
1032 }
1033 }
1034
1035 if(filter && status == LDAP_SUCCESS) {
1036 i = strlen(filter);
1037
1038 efilter = malloc(i + 1);
1039 if(!efilter)
1040 status = LDAP_NO_MEMORY;
1041 else {
1042 QadrtConvertA2E(efilter, filter, i, i);
1043 efilter[i] = '\0';
1044 }
1045 }
1046
1047 if(attrs && status == LDAP_SUCCESS) {
1048 for(i = 0; attrs[i++];)
1049 ;
1050
1051 eattrs = calloc(i, sizeof *eattrs);
1052 if(!eattrs)
1053 status = LDAP_NO_MEMORY;
1054 else {
1055 for(j = 0; attrs[j]; j++) {
1056 i = strlen(attrs[j]);
1057
1058 eattrs[j] = malloc(i + 1);
1059 if(!eattrs[j]) {
1060 status = LDAP_NO_MEMORY;
1061 break;
1062 }
1063
1064 QadrtConvertA2E(eattrs[j], attrs[j], i, i);
1065 eattrs[j][i] = '\0';
1066 }
1067 }
1068 }
1069
1070 if(status == LDAP_SUCCESS)
1071 status = ldap_search_s(ld, ebase? ebase: "", scope,
1072 efilter? efilter: "(objectclass=*)",
1073 eattrs, attrsonly, res);
1074
1075 if(eattrs) {
1076 for(j = 0; eattrs[j]; j++)
1077 free(eattrs[j]);
1078
1079 free(eattrs);
1080 }
1081
1082 free(efilter);
1083 free(ebase);
1084 return status;
1085 }
1086
1087
1088 struct berval * *
1089 Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
1090
1091 {
1092 char * cp;
1093 struct berval * * result;
1094
1095 cp = (char *) NULL;
1096
1097 if(attr) {
1098 int i = strlen(attr);
1099
1100 cp = malloc(i + 1);
1101 if(!cp) {
1102 ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
1103 ldap_err2string(LDAP_NO_MEMORY));
1104 return (struct berval * *) NULL;
1105 }
1106
1107 QadrtConvertA2E(cp, attr, i, i);
1108 cp[i] = '\0';
1109 }
1110
1111 result = ldap_get_values_len(ld, entry, cp);
1112 free(cp);
1113
1114 /* Result data are binary in nature, so they haven't been
1115 converted to EBCDIC. Therefore do not convert. */
1116
1117 return result;
1118 }
1119
1120
1121 char *
1122 Curl_ldap_err2string_a(int error)
1123
1124 {
1125 return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
1126 }
1127
1128
1129 char *
1130 Curl_ldap_get_dn_a(void * ld, LDAPMessage * entry)
1131
1132 {
1133 int i;
1134 char * cp;
1135 char * cp2;
1136
1137 cp = ldap_get_dn(ld, entry);
1138
1139 if(!cp)
1140 return cp;
1141
1142 i = strlen(cp);
1143
1144 cp2 = malloc(i + 1);
1145 if(!cp2)
1146 return cp2;
1147
1148 QadrtConvertE2A(cp2, cp, i, i);
1149 cp2[i] = '\0';
1150
1151 /* No way to allocate a buffer here, because it will be released by
1152 ldap_memfree() and ldap_memalloc() does not exist. The solution is to
1153 overwrite the EBCDIC buffer with ASCII to return it. */
1154
1155 strcpy(cp, cp2);
1156 free(cp2);
1157 return cp;
1158 }
1159
1160
1161 char *
1162 Curl_ldap_first_attribute_a(void * ld,
1163 LDAPMessage * entry, BerElement * * berptr)
1164
1165 {
1166 int i;
1167 char * cp;
1168 char * cp2;
1169
1170 cp = ldap_first_attribute(ld, entry, berptr);
1171
1172 if(!cp)
1173 return cp;
1174
1175 i = strlen(cp);
1176
1177 cp2 = malloc(i + 1);
1178 if(!cp2)
1179 return cp2;
1180
1181 QadrtConvertE2A(cp2, cp, i, i);
1182 cp2[i] = '\0';
1183
1184 /* No way to allocate a buffer here, because it will be released by
1185 ldap_memfree() and ldap_memalloc() does not exist. The solution is to
1186 overwrite the EBCDIC buffer with ASCII to return it. */
1187
1188 strcpy(cp, cp2);
1189 free(cp2);
1190 return cp;
1191 }
1192
1193
1194 char *
1195 Curl_ldap_next_attribute_a(void * ld,
1196 LDAPMessage * entry, BerElement * berptr)
1197
1198 {
1199 int i;
1200 char * cp;
1201 char * cp2;
1202
1203 cp = ldap_next_attribute(ld, entry, berptr);
1204
1205 if(!cp)
1206 return cp;
1207
1208 i = strlen(cp);
1209
1210 cp2 = malloc(i + 1);
1211 if(!cp2)
1212 return cp2;
1213
1214 QadrtConvertE2A(cp2, cp, i, i);
1215 cp2[i] = '\0';
1216
1217 /* No way to allocate a buffer here, because it will be released by
1218 ldap_memfree() and ldap_memalloc() does not exist. The solution is to
1219 overwrite the EBCDIC buffer with ASCII to return it. */
1220
1221 strcpy(cp, cp2);
1222 free(cp2);
1223 return cp;
1224 }
1225
1226 #endif /* CURL_DISABLE_LDAP */
1227
1228
1229 static int
1230 convert_sockaddr(struct sockaddr_storage * dstaddr,
1231 const struct sockaddr * srcaddr, int srclen)
1232
1233 {
1234 const struct sockaddr_un * srcu;
1235 struct sockaddr_un * dstu;
1236 unsigned int i;
1237 unsigned int dstsize;
1238
1239 /* Convert a socket address into job CCSID, if needed. */
1240
1241 if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
1242 sizeof srcaddr->sa_family || srclen > sizeof *dstaddr) {
1243 errno = EINVAL;
1244 return -1;
1245 }
1246
1247 memcpy((char *) dstaddr, (char *) srcaddr, srclen);
1248
1249 switch (srcaddr->sa_family) {
1250
1251 case AF_UNIX:
1252 srcu = (const struct sockaddr_un *) srcaddr;
1253 dstu = (struct sockaddr_un *) dstaddr;
1254 dstsize = sizeof *dstaddr - offsetof(struct sockaddr_un, sun_path);
1255 srclen -= offsetof(struct sockaddr_un, sun_path);
1256 i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen);
1257 dstu->sun_path[i] = '\0';
1258 i += offsetof(struct sockaddr_un, sun_path);
1259 srclen = i;
1260 }
1261
1262 return srclen;
1263 }
1264
1265
1266 int
1267 Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
1268
1269 {
1270 int i;
1271 struct sockaddr_storage laddr;
1272
1273 i = convert_sockaddr(&laddr, destaddr, addrlen);
1274
1275 if(i < 0)
1276 return -1;
1277
1278 return connect(sd, (struct sockaddr *) &laddr, i);
1279 }
1280
1281
1282 int
1283 Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
1284
1285 {
1286 int i;
1287 struct sockaddr_storage laddr;
1288
1289 i = convert_sockaddr(&laddr, localaddr, addrlen);
1290
1291 if(i < 0)
1292 return -1;
1293
1294 return bind(sd, (struct sockaddr *) &laddr, i);
1295 }
1296
1297
1298 int
1299 Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
1300 struct sockaddr * dstaddr, int addrlen)
1301
1302 {
1303 int i;
1304 struct sockaddr_storage laddr;
1305
1306 i = convert_sockaddr(&laddr, dstaddr, addrlen);
1307
1308 if(i < 0)
1309 return -1;
1310
1311 return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
1312 }
1313
1314
1315 int
1316 Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
1317 struct sockaddr * fromaddr, int * addrlen)
1318
1319 {
1320 int i;
1321 int rcvlen;
1322 int laddrlen;
1323 const struct sockaddr_un * srcu;
1324 struct sockaddr_un * dstu;
1325 struct sockaddr_storage laddr;
1326
1327 if(!fromaddr || !addrlen || *addrlen <= 0)
1328 return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);
1329
1330 laddrlen = sizeof laddr;
1331 laddr.ss_family = AF_UNSPEC; /* To detect if unused. */
1332 rcvlen = recvfrom(sd, buffer, buflen, flags,
1333 (struct sockaddr *) &laddr, &laddrlen);
1334
1335 if(rcvlen < 0)
1336 return rcvlen;
1337
1338 switch (laddr.ss_family) {
1339
1340 case AF_UNIX:
1341 srcu = (const struct sockaddr_un *) &laddr;
1342 dstu = (struct sockaddr_un *) fromaddr;
1343 i = *addrlen - offsetof(struct sockaddr_un, sun_path);
1344 laddrlen -= offsetof(struct sockaddr_un, sun_path);
1345 i = QadrtConvertE2A(dstu->sun_path, srcu->sun_path, i, laddrlen);
1346 laddrlen = i + offsetof(struct sockaddr_un, sun_path);
1347
1348 if(laddrlen < *addrlen)
1349 dstu->sun_path[i] = '\0';
1350
1351 break;
1352
1353 case AF_UNSPEC:
1354 break;
1355
1356 default:
1357 if(laddrlen > *addrlen)
1358 laddrlen = *addrlen;
1359
1360 if(laddrlen)
1361 memcpy((char *) fromaddr, (char *) &laddr, laddrlen);
1362
1363 break;
1364 }
1365
1366 *addrlen = laddrlen;
1367 return rcvlen;
1368 }
1369
1370
1371 #ifdef HAVE_LIBZ
1372 const char *
1373 Curl_os400_zlibVersion(void)
1374
1375 {
1376 return set_thread_string(LK_ZLIB_VERSION, zlibVersion());
1377 }
1378
1379
1380 int
1381 Curl_os400_inflateInit_(z_streamp strm, const char * version, int stream_size)
1382
1383 {
1384 z_const char * msgb4 = strm->msg;
1385 int ret;
1386
1387 ret = inflateInit(strm);
1388
1389 if(strm->msg != msgb4)
1390 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1391
1392 return ret;
1393 }
1394
1395
1396 int
1397 Curl_os400_inflateInit2_(z_streamp strm, int windowBits,
1398 const char * version, int stream_size)
1399
1400 {
1401 z_const char * msgb4 = strm->msg;
1402 int ret;
1403
1404 ret = inflateInit2(strm, windowBits);
1405
1406 if(strm->msg != msgb4)
1407 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1408
1409 return ret;
1410 }
1411
1412
1413 int
1414 Curl_os400_inflate(z_streamp strm, int flush)
1415
1416 {
1417 z_const char * msgb4 = strm->msg;
1418 int ret;
1419
1420 ret = inflate(strm, flush);
1421
1422 if(strm->msg != msgb4)
1423 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1424
1425 return ret;
1426 }
1427
1428
1429 int
1430 Curl_os400_inflateEnd(z_streamp strm)
1431
1432 {
1433 z_const char * msgb4 = strm->msg;
1434 int ret;
1435
1436 ret = inflateEnd(strm);
1437
1438 if(strm->msg != msgb4)
1439 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1440
1441 return ret;
1442 }
1443
1444 #endif