Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/external/curl/packages/OS400/os400sys.c
2066 views
1
/***************************************************************************
2
* _ _ ____ _
3
* Project ___| | | | _ \| |
4
* / __| | | | |_) | |
5
* | (__| |_| | _ <| |___
6
* \___|\___/|_| \_\_____|
7
*
8
* Copyright (C) Daniel Stenberg, <[email protected]>, 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.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
* SPDX-License-Identifier: curl
22
*
23
*
24
***************************************************************************/
25
26
/* OS/400 additional support. */
27
28
#include <curl/curl.h>
29
#include "config-os400.h" /* Not curl_setup.h: we only need some defines. */
30
31
#include <sys/types.h>
32
#include <sys/socket.h>
33
#include <sys/un.h>
34
35
#include <stdlib.h>
36
#include <stddef.h>
37
#include <string.h>
38
#include <pthread.h>
39
#include <netdb.h>
40
#include <qadrt.h>
41
#include <errno.h>
42
43
#ifdef HAVE_LIBZ
44
#include <zlib.h>
45
#endif
46
47
#ifdef HAVE_GSSAPI
48
#include <gssapi.h>
49
#endif
50
51
#ifndef CURL_DISABLE_LDAP
52
#include <ldap.h>
53
#endif
54
55
#include <netinet/in.h>
56
#include <arpa/inet.h>
57
58
#include "os400sys.h"
59
60
/**
61
*** QADRT OS/400 ASCII runtime defines only the most used procedures, but a
62
*** lot of them are not supported. This module implements ASCII wrappers for
63
*** those that are used by libcurl, but not defined by QADRT.
64
**/
65
66
#pragma convert(0) /* Restore EBCDIC. */
67
68
#define MIN_BYTE_GAIN 1024 /* Minimum gain when shortening a buffer. */
69
70
struct buffer_t {
71
unsigned long size; /* Buffer size. */
72
char *buf; /* Buffer address. */
73
};
74
75
76
static char *buffer_undef(localkey_t key, long size);
77
static char *buffer_threaded(localkey_t key, long size);
78
static char *buffer_unthreaded(localkey_t key, long size);
79
80
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
81
static pthread_key_t thdkey;
82
static struct buffer_t *locbufs;
83
84
char *(*Curl_thread_buffer)(localkey_t key, long size) = buffer_undef;
85
86
static void thdbufdestroy(void *private)
87
{
88
if(private) {
89
struct buffer_t *p = (struct buffer_t *) private;
90
localkey_t i;
91
92
for(i = (localkey_t) 0; i < LK_LAST; i++) {
93
free(p->buf);
94
p++;
95
}
96
97
free(private);
98
}
99
}
100
101
102
static void
103
terminate(void)
104
{
105
if(Curl_thread_buffer == buffer_threaded) {
106
locbufs = pthread_getspecific(thdkey);
107
pthread_setspecific(thdkey, (void *) NULL);
108
pthread_key_delete(thdkey);
109
}
110
111
if(Curl_thread_buffer != buffer_undef) {
112
thdbufdestroy((void *) locbufs);
113
locbufs = (struct buffer_t *) NULL;
114
}
115
116
Curl_thread_buffer = buffer_undef;
117
}
118
119
120
static char *
121
get_buffer(struct buffer_t *buf, long size)
122
{
123
char *cp;
124
125
/* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long.
126
Return the buffer address. */
127
128
if(size < 0)
129
return buf->buf;
130
131
if(!buf->buf) {
132
buf->buf = malloc(size);
133
if(buf->buf)
134
buf->size = size;
135
136
return buf->buf;
137
}
138
139
if((unsigned long) size <= buf->size) {
140
/* Shorten the buffer only if it frees a significant byte count. This
141
avoids some realloc() overhead. */
142
143
if(buf->size - size < MIN_BYTE_GAIN)
144
return buf->buf;
145
}
146
147
/* Resize the buffer. */
148
149
cp = realloc(buf->buf, size);
150
if(cp) {
151
buf->buf = cp;
152
buf->size = size;
153
}
154
else if(size <= buf->size)
155
cp = buf->buf;
156
157
return cp;
158
}
159
160
161
static char *
162
buffer_unthreaded(localkey_t key, long size)
163
{
164
return get_buffer(locbufs + key, size);
165
}
166
167
168
static char *
169
buffer_threaded(localkey_t key, long size)
170
{
171
struct buffer_t *bufs;
172
173
/* Get the buffer for the given local key in the current thread, and
174
make sure it is at least `size'-byte long. Set `size' to < 0 to get
175
its address only. */
176
177
bufs = (struct buffer_t *) pthread_getspecific(thdkey);
178
179
if(!bufs) {
180
if(size < 0)
181
return (char *) NULL; /* No buffer yet. */
182
183
/* Allocate buffer descriptors for the current thread. */
184
185
bufs = calloc((size_t) LK_LAST, sizeof(*bufs));
186
if(!bufs)
187
return (char *) NULL;
188
189
if(pthread_setspecific(thdkey, (void *) bufs)) {
190
free(bufs);
191
return (char *) NULL;
192
}
193
}
194
195
return get_buffer(bufs + key, size);
196
}
197
198
199
static char *
200
buffer_undef(localkey_t key, long size)
201
{
202
/* Define the buffer system, get the buffer for the given local key in
203
the current thread, and make sure it is at least `size'-byte long.
204
Set `size' to < 0 to get its address only. */
205
206
pthread_mutex_lock(&mutex);
207
208
/* Determine if we can use pthread-specific data. */
209
210
if(Curl_thread_buffer == buffer_undef) { /* If unchanged during lock. */
211
if(!pthread_key_create(&thdkey, thdbufdestroy))
212
Curl_thread_buffer = buffer_threaded;
213
else {
214
locbufs = calloc((size_t) LK_LAST, sizeof(*locbufs));
215
if(!locbufs) {
216
pthread_mutex_unlock(&mutex);
217
return (char *) NULL;
218
}
219
else
220
Curl_thread_buffer = buffer_unthreaded;
221
}
222
223
atexit(terminate);
224
}
225
226
pthread_mutex_unlock(&mutex);
227
return Curl_thread_buffer(key, size);
228
}
229
230
231
static char *
232
set_thread_string(localkey_t key, const char *s)
233
{
234
int i;
235
char *cp;
236
237
if(!s)
238
return (char *) NULL;
239
240
i = strlen(s) + 1;
241
cp = Curl_thread_buffer(key, MAX_CONV_EXPANSION * i + 1);
242
243
if(cp) {
244
i = QadrtConvertE2A(cp, s, MAX_CONV_EXPANSION * i, i);
245
cp[i] = '\0';
246
}
247
248
return cp;
249
}
250
251
252
int
253
Curl_getnameinfo_a(const struct sockaddr *sa, socklen_t salen,
254
char *nodename, socklen_t nodenamelen,
255
char *servname, socklen_t servnamelen,
256
int flags)
257
{
258
char *enodename = NULL;
259
char *eservname = NULL;
260
int status;
261
262
if(nodename && nodenamelen) {
263
enodename = malloc(nodenamelen);
264
if(!enodename)
265
return EAI_MEMORY;
266
}
267
268
if(servname && servnamelen) {
269
eservname = malloc(servnamelen);
270
if(!eservname) {
271
free(enodename);
272
return EAI_MEMORY;
273
}
274
}
275
276
status = getnameinfo(sa, salen, enodename, nodenamelen,
277
eservname, servnamelen, flags);
278
279
if(!status) {
280
int i;
281
if(enodename) {
282
i = QadrtConvertE2A(nodename, enodename,
283
nodenamelen - 1, strlen(enodename));
284
nodename[i] = '\0';
285
}
286
287
if(eservname) {
288
i = QadrtConvertE2A(servname, eservname,
289
servnamelen - 1, strlen(eservname));
290
servname[i] = '\0';
291
}
292
}
293
294
free(enodename);
295
free(eservname);
296
return status;
297
}
298
299
int
300
Curl_getaddrinfo_a(const char *nodename, const char *servname,
301
const struct addrinfo *hints,
302
struct addrinfo **res)
303
{
304
char *enodename;
305
char *eservname;
306
int status;
307
int i;
308
309
enodename = (char *) NULL;
310
eservname = (char *) NULL;
311
312
if(nodename) {
313
i = strlen(nodename);
314
315
enodename = malloc(i + 1);
316
if(!enodename)
317
return EAI_MEMORY;
318
319
i = QadrtConvertA2E(enodename, nodename, i, i);
320
enodename[i] = '\0';
321
}
322
323
if(servname) {
324
i = strlen(servname);
325
326
eservname = malloc(i + 1);
327
if(!eservname) {
328
free(enodename);
329
return EAI_MEMORY;
330
}
331
332
QadrtConvertA2E(eservname, servname, i, i);
333
eservname[i] = '\0';
334
}
335
336
status = getaddrinfo(enodename, eservname, hints, res);
337
free(enodename);
338
free(eservname);
339
return status;
340
}
341
342
#ifdef HAVE_GSSAPI
343
344
/* ASCII wrappers for the GSSAPI procedures. */
345
346
static int
347
Curl_gss_convert_in_place(OM_uint32 *minor_status, gss_buffer_t buf)
348
{
349
unsigned int i = buf->length;
350
351
/* Convert `buf' in place, from EBCDIC to ASCII.
352
If error, release the buffer and return -1. Else return 0. */
353
354
if(i) {
355
char *t = malloc(i);
356
if(!t) {
357
gss_release_buffer(minor_status, buf);
358
359
if(minor_status)
360
/* !checksrc! disable ERRNOVAR 1 */
361
*minor_status = ENOMEM;
362
363
return -1;
364
}
365
366
QadrtConvertE2A(t, buf->value, i, i);
367
memcpy(buf->value, t, i);
368
free(t);
369
}
370
371
return 0;
372
}
373
374
375
OM_uint32
376
Curl_gss_import_name_a(OM_uint32 *minor_status, gss_buffer_t in_name,
377
gss_OID in_name_type, gss_name_t *out_name)
378
{
379
OM_uint32 rc;
380
unsigned int i;
381
gss_buffer_desc in;
382
383
if(!in_name || !in_name->value || !in_name->length)
384
return gss_import_name(minor_status, in_name, in_name_type, out_name);
385
386
memcpy((char *) &in, (char *) in_name, sizeof(in));
387
i = in.length;
388
389
in.value = malloc(i + 1);
390
if(!in.value) {
391
if(minor_status)
392
/* !checksrc! disable ERRNOVAR 1 */
393
*minor_status = ENOMEM;
394
395
return GSS_S_FAILURE;
396
}
397
398
QadrtConvertA2E(in.value, in_name->value, i, i);
399
((char *) in.value)[i] = '\0';
400
rc = gss_import_name(minor_status, &in, in_name_type, out_name);
401
free(in.value);
402
return rc;
403
}
404
405
OM_uint32
406
Curl_gss_display_status_a(OM_uint32 *minor_status, OM_uint32 status_value,
407
int status_type, gss_OID mech_type,
408
gss_msg_ctx_t *message_context,
409
gss_buffer_t status_string)
410
{
411
int rc;
412
413
rc = gss_display_status(minor_status, status_value, status_type,
414
mech_type, message_context, status_string);
415
416
if(rc != GSS_S_COMPLETE || !status_string ||
417
!status_string->length || !status_string->value)
418
return rc;
419
420
/* No way to allocate a buffer here, because it will be released by
421
gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
422
with ASCII to return it. */
423
424
if(Curl_gss_convert_in_place(minor_status, status_string))
425
return GSS_S_FAILURE;
426
427
return rc;
428
}
429
430
OM_uint32
431
Curl_gss_init_sec_context_a(OM_uint32 *minor_status,
432
gss_cred_id_t cred_handle,
433
gss_ctx_id_t *context_handle,
434
gss_name_t target_name, gss_OID mech_type,
435
gss_flags_t req_flags, OM_uint32 time_req,
436
gss_channel_bindings_t input_chan_bindings,
437
gss_buffer_t input_token,
438
gss_OID *actual_mech_type,
439
gss_buffer_t output_token, gss_flags_t *ret_flags,
440
OM_uint32 *time_rec)
441
{
442
int rc;
443
gss_buffer_desc in;
444
gss_buffer_t inp;
445
446
in.value = NULL;
447
inp = input_token;
448
449
if(inp) {
450
if(inp->length && inp->value) {
451
unsigned int i = inp->length;
452
453
in.value = malloc(i + 1);
454
if(!in.value) {
455
if(minor_status)
456
/* !checksrc! disable ERRNOVAR 1 */
457
*minor_status = ENOMEM;
458
459
return GSS_S_FAILURE;
460
}
461
462
QadrtConvertA2E(in.value, input_token->value, i, i);
463
((char *) in.value)[i] = '\0';
464
in.length = i;
465
inp = &in;
466
}
467
}
468
469
rc = gss_init_sec_context(minor_status, cred_handle, context_handle,
470
target_name, mech_type, req_flags, time_req,
471
input_chan_bindings, inp, actual_mech_type,
472
output_token, ret_flags, time_rec);
473
free(in.value);
474
475
if(rc != GSS_S_COMPLETE || !output_token ||
476
!output_token->length || !output_token->value)
477
return rc;
478
479
/* No way to allocate a buffer here, because it will be released by
480
gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
481
with ASCII to return it. */
482
483
if(Curl_gss_convert_in_place(minor_status, output_token))
484
return GSS_S_FAILURE;
485
486
return rc;
487
}
488
489
490
OM_uint32
491
Curl_gss_delete_sec_context_a(OM_uint32 *minor_status,
492
gss_ctx_id_t *context_handle,
493
gss_buffer_t output_token)
494
{
495
OM_uint32 rc;
496
497
rc = gss_delete_sec_context(minor_status, context_handle, output_token);
498
499
if(rc != GSS_S_COMPLETE || !output_token ||
500
!output_token->length || !output_token->value)
501
return rc;
502
503
/* No way to allocate a buffer here, because it will be released by
504
gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
505
with ASCII to return it. */
506
507
if(Curl_gss_convert_in_place(minor_status, output_token))
508
return GSS_S_FAILURE;
509
510
return rc;
511
}
512
513
#endif /* HAVE_GSSAPI */
514
515
#ifndef CURL_DISABLE_LDAP
516
517
/* ASCII wrappers for the LDAP procedures. */
518
519
void *
520
Curl_ldap_init_a(char *host, int port)
521
{
522
size_t i;
523
char *ehost;
524
void *result;
525
526
if(!host)
527
return (void *) ldap_init(host, port);
528
529
i = strlen(host);
530
531
ehost = malloc(i + 1);
532
if(!ehost)
533
return (void *) NULL;
534
535
QadrtConvertA2E(ehost, host, i, i);
536
ehost[i] = '\0';
537
result = (void *) ldap_init(ehost, port);
538
free(ehost);
539
return result;
540
}
541
542
int
543
Curl_ldap_simple_bind_s_a(void *ld, char *dn, char *passwd)
544
{
545
int i;
546
char *edn;
547
char *epasswd;
548
549
edn = (char *) NULL;
550
epasswd = (char *) NULL;
551
552
if(dn) {
553
i = strlen(dn);
554
555
edn = malloc(i + 1);
556
if(!edn)
557
return LDAP_NO_MEMORY;
558
559
QadrtConvertA2E(edn, dn, i, i);
560
edn[i] = '\0';
561
}
562
563
if(passwd) {
564
i = strlen(passwd);
565
566
epasswd = malloc(i + 1);
567
if(!epasswd) {
568
free(edn);
569
return LDAP_NO_MEMORY;
570
}
571
572
QadrtConvertA2E(epasswd, passwd, i, i);
573
epasswd[i] = '\0';
574
}
575
576
i = ldap_simple_bind_s(ld, edn, epasswd);
577
free(epasswd);
578
free(edn);
579
return i;
580
}
581
582
int
583
Curl_ldap_search_s_a(void *ld, char *base, int scope, char *filter,
584
char **attrs, int attrsonly, LDAPMessage **res)
585
{
586
int i;
587
int j;
588
char *ebase;
589
char *efilter;
590
char **eattrs;
591
int status;
592
593
ebase = (char *) NULL;
594
efilter = (char *) NULL;
595
eattrs = (char **) NULL;
596
status = LDAP_SUCCESS;
597
598
if(base) {
599
i = strlen(base);
600
601
ebase = malloc(i + 1);
602
if(!ebase)
603
status = LDAP_NO_MEMORY;
604
else {
605
QadrtConvertA2E(ebase, base, i, i);
606
ebase[i] = '\0';
607
}
608
}
609
610
if(filter && status == LDAP_SUCCESS) {
611
i = strlen(filter);
612
613
efilter = malloc(i + 1);
614
if(!efilter)
615
status = LDAP_NO_MEMORY;
616
else {
617
QadrtConvertA2E(efilter, filter, i, i);
618
efilter[i] = '\0';
619
}
620
}
621
622
if(attrs && status == LDAP_SUCCESS) {
623
for(i = 0; attrs[i++];)
624
;
625
626
eattrs = calloc(i, sizeof(*eattrs));
627
if(!eattrs)
628
status = LDAP_NO_MEMORY;
629
else {
630
for(j = 0; attrs[j]; j++) {
631
i = strlen(attrs[j]);
632
633
eattrs[j] = malloc(i + 1);
634
if(!eattrs[j]) {
635
status = LDAP_NO_MEMORY;
636
break;
637
}
638
639
QadrtConvertA2E(eattrs[j], attrs[j], i, i);
640
eattrs[j][i] = '\0';
641
}
642
}
643
}
644
645
if(status == LDAP_SUCCESS)
646
status = ldap_search_s(ld, ebase ? ebase : "", scope,
647
efilter ? efilter : "(objectclass=*)",
648
eattrs, attrsonly, res);
649
650
if(eattrs) {
651
for(j = 0; eattrs[j]; j++)
652
free(eattrs[j]);
653
654
free(eattrs);
655
}
656
657
free(efilter);
658
free(ebase);
659
return status;
660
}
661
662
663
struct berval **
664
Curl_ldap_get_values_len_a(void *ld, LDAPMessage *entry, const char *attr)
665
{
666
char *cp;
667
struct berval **result;
668
669
cp = (char *) NULL;
670
671
if(attr) {
672
int i = strlen(attr);
673
674
cp = malloc(i + 1);
675
if(!cp) {
676
ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
677
ldap_err2string(LDAP_NO_MEMORY));
678
return (struct berval **) NULL;
679
}
680
681
QadrtConvertA2E(cp, attr, i, i);
682
cp[i] = '\0';
683
}
684
685
result = ldap_get_values_len(ld, entry, cp);
686
free(cp);
687
688
/* Result data are binary in nature, so they haven't been
689
converted to EBCDIC. Therefore do not convert. */
690
691
return result;
692
}
693
694
char *
695
Curl_ldap_err2string_a(int error)
696
{
697
return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
698
}
699
700
char *
701
Curl_ldap_get_dn_a(void *ld, LDAPMessage *entry)
702
{
703
int i;
704
char *cp;
705
char *cp2;
706
707
cp = ldap_get_dn(ld, entry);
708
709
if(!cp)
710
return cp;
711
712
i = strlen(cp);
713
714
cp2 = malloc(i + 1);
715
if(!cp2)
716
return cp2;
717
718
QadrtConvertE2A(cp2, cp, i, i);
719
cp2[i] = '\0';
720
721
/* No way to allocate a buffer here, because it will be released by
722
ldap_memfree() and ldap_memalloc() does not exist. The solution is to
723
overwrite the EBCDIC buffer with ASCII to return it. */
724
725
strcpy(cp, cp2);
726
free(cp2);
727
return cp;
728
}
729
730
char *
731
Curl_ldap_first_attribute_a(void *ld,
732
LDAPMessage *entry, BerElement **berptr)
733
{
734
int i;
735
char *cp;
736
char *cp2;
737
738
cp = ldap_first_attribute(ld, entry, berptr);
739
740
if(!cp)
741
return cp;
742
743
i = strlen(cp);
744
745
cp2 = malloc(i + 1);
746
if(!cp2)
747
return cp2;
748
749
QadrtConvertE2A(cp2, cp, i, i);
750
cp2[i] = '\0';
751
752
/* No way to allocate a buffer here, because it will be released by
753
ldap_memfree() and ldap_memalloc() does not exist. The solution is to
754
overwrite the EBCDIC buffer with ASCII to return it. */
755
756
strcpy(cp, cp2);
757
free(cp2);
758
return cp;
759
}
760
761
char *
762
Curl_ldap_next_attribute_a(void *ld,
763
LDAPMessage *entry, BerElement *berptr)
764
{
765
int i;
766
char *cp;
767
char *cp2;
768
769
cp = ldap_next_attribute(ld, entry, berptr);
770
771
if(!cp)
772
return cp;
773
774
i = strlen(cp);
775
776
cp2 = malloc(i + 1);
777
if(!cp2)
778
return cp2;
779
780
QadrtConvertE2A(cp2, cp, i, i);
781
cp2[i] = '\0';
782
783
/* No way to allocate a buffer here, because it will be released by
784
ldap_memfree() and ldap_memalloc() does not exist. The solution is to
785
overwrite the EBCDIC buffer with ASCII to return it. */
786
787
strcpy(cp, cp2);
788
free(cp2);
789
return cp;
790
}
791
792
#endif /* CURL_DISABLE_LDAP */
793
794
static int
795
sockaddr2ebcdic(struct sockaddr_storage *dstaddr,
796
const struct sockaddr *srcaddr, int srclen)
797
{
798
const struct sockaddr_un *srcu;
799
struct sockaddr_un *dstu;
800
unsigned int i;
801
unsigned int dstsize;
802
803
/* Convert a socket address to job CCSID, if needed. */
804
805
if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
806
sizeof(srcaddr->sa_family) || srclen > sizeof(*dstaddr)) {
807
/* !checksrc! disable ERRNOVAR 1 */
808
errno = EINVAL;
809
return -1;
810
}
811
812
memcpy((char *) dstaddr, (char *) srcaddr, srclen);
813
814
switch(srcaddr->sa_family) {
815
816
case AF_UNIX:
817
srcu = (const struct sockaddr_un *) srcaddr;
818
dstu = (struct sockaddr_un *) dstaddr;
819
dstsize = sizeof(*dstaddr) - offsetof(struct sockaddr_un, sun_path);
820
srclen -= offsetof(struct sockaddr_un, sun_path);
821
i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen);
822
dstu->sun_path[i] = '\0';
823
srclen = i + offsetof(struct sockaddr_un, sun_path);
824
}
825
826
return srclen;
827
}
828
829
830
static int
831
sockaddr2ascii(struct sockaddr *dstaddr, int dstlen,
832
const struct sockaddr_storage *srcaddr, int srclen)
833
{
834
const struct sockaddr_un *srcu;
835
struct sockaddr_un *dstu;
836
unsigned int dstsize;
837
838
/* Convert a socket address to ASCII, if needed. */
839
840
if(!srclen)
841
return 0;
842
if(srclen > dstlen)
843
srclen = dstlen;
844
if(!srcaddr || srclen < 0) {
845
/* !checksrc! disable ERRNOVAR 1 */
846
errno = EINVAL;
847
return -1;
848
}
849
850
memcpy((char *) dstaddr, (char *) srcaddr, srclen);
851
852
if(srclen >= offsetof(struct sockaddr_storage, ss_family) +
853
sizeof(srcaddr->ss_family)) {
854
switch(srcaddr->ss_family) {
855
856
case AF_UNIX:
857
srcu = (const struct sockaddr_un *) srcaddr;
858
dstu = (struct sockaddr_un *) dstaddr;
859
dstsize = dstlen - offsetof(struct sockaddr_un, sun_path);
860
srclen -= offsetof(struct sockaddr_un, sun_path);
861
if(dstsize > 0 && srclen > 0) {
862
srclen = QadrtConvertE2A(dstu->sun_path, srcu->sun_path,
863
dstsize - 1, srclen);
864
dstu->sun_path[srclen] = '\0';
865
}
866
srclen += offsetof(struct sockaddr_un, sun_path);
867
}
868
}
869
870
return srclen;
871
}
872
873
int
874
Curl_os400_connect(int sd, struct sockaddr *destaddr, int addrlen)
875
{
876
int i;
877
struct sockaddr_storage laddr;
878
879
i = sockaddr2ebcdic(&laddr, destaddr, addrlen);
880
881
if(i < 0)
882
return -1;
883
884
return connect(sd, (struct sockaddr *) &laddr, i);
885
}
886
887
int
888
Curl_os400_bind(int sd, struct sockaddr *localaddr, int addrlen)
889
{
890
int i;
891
struct sockaddr_storage laddr;
892
893
i = sockaddr2ebcdic(&laddr, localaddr, addrlen);
894
895
if(i < 0)
896
return -1;
897
898
return bind(sd, (struct sockaddr *) &laddr, i);
899
}
900
901
int
902
Curl_os400_sendto(int sd, char *buffer, int buflen, int flags,
903
const struct sockaddr *dstaddr, int addrlen)
904
{
905
int i;
906
struct sockaddr_storage laddr;
907
908
i = sockaddr2ebcdic(&laddr, dstaddr, addrlen);
909
910
if(i < 0)
911
return -1;
912
913
return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
914
}
915
916
int
917
Curl_os400_recvfrom(int sd, char *buffer, int buflen, int flags,
918
struct sockaddr *fromaddr, int *addrlen)
919
{
920
int rcvlen;
921
struct sockaddr_storage laddr;
922
int laddrlen = sizeof(laddr);
923
924
if(!fromaddr || !addrlen || *addrlen <= 0)
925
return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);
926
927
laddr.ss_family = AF_UNSPEC; /* To detect if unused. */
928
rcvlen = recvfrom(sd, buffer, buflen, flags,
929
(struct sockaddr *) &laddr, &laddrlen);
930
931
if(rcvlen < 0)
932
return rcvlen;
933
934
if(laddr.ss_family == AF_UNSPEC)
935
laddrlen = 0;
936
else {
937
laddrlen = sockaddr2ascii(fromaddr, *addrlen, &laddr, laddrlen);
938
if(laddrlen < 0)
939
return laddrlen;
940
}
941
*addrlen = laddrlen;
942
return rcvlen;
943
}
944
945
int
946
Curl_os400_getpeername(int sd, struct sockaddr *addr, int *addrlen)
947
{
948
struct sockaddr_storage laddr;
949
int laddrlen = sizeof(laddr);
950
int retcode = getpeername(sd, (struct sockaddr *) &laddr, &laddrlen);
951
952
if(!retcode) {
953
laddrlen = sockaddr2ascii(addr, *addrlen, &laddr, laddrlen);
954
if(laddrlen < 0)
955
return laddrlen;
956
*addrlen = laddrlen;
957
}
958
959
return retcode;
960
}
961
962
int
963
Curl_os400_getsockname(int sd, struct sockaddr *addr, int *addrlen)
964
{
965
struct sockaddr_storage laddr;
966
int laddrlen = sizeof(laddr);
967
int retcode = getsockname(sd, (struct sockaddr *) &laddr, &laddrlen);
968
969
if(!retcode) {
970
laddrlen = sockaddr2ascii(addr, *addrlen, &laddr, laddrlen);
971
if(laddrlen < 0)
972
return laddrlen;
973
*addrlen = laddrlen;
974
}
975
976
return retcode;
977
}
978
979
980
#ifdef HAVE_LIBZ
981
const char *
982
Curl_os400_zlibVersion(void)
983
{
984
return set_thread_string(LK_ZLIB_VERSION, zlibVersion());
985
}
986
987
988
int
989
Curl_os400_inflateInit_(z_streamp strm, const char *version, int stream_size)
990
{
991
z_const char *msgb4 = strm->msg;
992
int ret;
993
994
ret = inflateInit(strm);
995
996
if(strm->msg != msgb4)
997
strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
998
999
return ret;
1000
}
1001
1002
int
1003
Curl_os400_inflateInit2_(z_streamp strm, int windowBits,
1004
const char *version, int stream_size)
1005
{
1006
z_const char *msgb4 = strm->msg;
1007
int ret;
1008
1009
ret = inflateInit2(strm, windowBits);
1010
1011
if(strm->msg != msgb4)
1012
strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1013
1014
return ret;
1015
}
1016
1017
int
1018
Curl_os400_inflate(z_streamp strm, int flush)
1019
{
1020
z_const char *msgb4 = strm->msg;
1021
int ret;
1022
1023
ret = inflate(strm, flush);
1024
1025
if(strm->msg != msgb4)
1026
strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1027
1028
return ret;
1029
}
1030
1031
int
1032
Curl_os400_inflateEnd(z_streamp strm)
1033
{
1034
z_const char *msgb4 = strm->msg;
1035
int ret;
1036
1037
ret = inflateEnd(strm);
1038
1039
if(strm->msg != msgb4)
1040
strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1041
1042
return ret;
1043
}
1044
1045
#endif
1046
1047