113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci * 2413498266Sopenharmony_ci ***************************************************************************/ 2513498266Sopenharmony_ci 2613498266Sopenharmony_ci/* CCSID API wrappers for OS/400. */ 2713498266Sopenharmony_ci 2813498266Sopenharmony_ci#include <iconv.h> 2913498266Sopenharmony_ci#include <string.h> 3013498266Sopenharmony_ci#include <stdlib.h> 3113498266Sopenharmony_ci#include <stddef.h> 3213498266Sopenharmony_ci#include <errno.h> 3313498266Sopenharmony_ci#include <stdarg.h> 3413498266Sopenharmony_ci 3513498266Sopenharmony_ci#pragma enum(int) 3613498266Sopenharmony_ci 3713498266Sopenharmony_ci#include "curl.h" 3813498266Sopenharmony_ci#include "mprintf.h" 3913498266Sopenharmony_ci#include "slist.h" 4013498266Sopenharmony_ci#include "urldata.h" 4113498266Sopenharmony_ci#include "url.h" 4213498266Sopenharmony_ci#include "setopt.h" 4313498266Sopenharmony_ci#include "getinfo.h" 4413498266Sopenharmony_ci#include "ccsidcurl.h" 4513498266Sopenharmony_ci 4613498266Sopenharmony_ci#include "os400sys.h" 4713498266Sopenharmony_ci 4813498266Sopenharmony_ci#ifndef SIZE_MAX 4913498266Sopenharmony_ci#define SIZE_MAX ((size_t) ~0) /* Is unsigned on OS/400. */ 5013498266Sopenharmony_ci#endif 5113498266Sopenharmony_ci 5213498266Sopenharmony_ci 5313498266Sopenharmony_ci#define ASCII_CCSID 819 /* Use ISO-8859-1 as ASCII. */ 5413498266Sopenharmony_ci#define NOCONV_CCSID 65535 /* No conversion. */ 5513498266Sopenharmony_ci#define ICONV_ID_SIZE 32 /* Size of iconv_open() code identifier. */ 5613498266Sopenharmony_ci#define ICONV_OPEN_ERROR(t) ((t).return_value == -1) 5713498266Sopenharmony_ci 5813498266Sopenharmony_ci#define ALLOC_GRANULE 8 /* Alloc. granule for curl_formadd_ccsid(). */ 5913498266Sopenharmony_ci 6013498266Sopenharmony_ci 6113498266Sopenharmony_cistatic void 6213498266Sopenharmony_cimakeOS400IconvCode(char buf[ICONV_ID_SIZE], unsigned int ccsid) 6313498266Sopenharmony_ci{ 6413498266Sopenharmony_ci /** 6513498266Sopenharmony_ci *** Convert a CCSID to the corresponding IBM iconv_open() character 6613498266Sopenharmony_ci *** code identifier. 6713498266Sopenharmony_ci *** This code is specific to the OS400 implementation of the iconv library. 6813498266Sopenharmony_ci *** CCSID 65535 (no conversion) is replaced by the ASCII CCSID. 6913498266Sopenharmony_ci *** CCSID 0 is interpreted by the OS400 as the job's CCSID. 7013498266Sopenharmony_ci **/ 7113498266Sopenharmony_ci 7213498266Sopenharmony_ci ccsid &= 0xFFFF; 7313498266Sopenharmony_ci 7413498266Sopenharmony_ci if(ccsid == NOCONV_CCSID) 7513498266Sopenharmony_ci ccsid = ASCII_CCSID; 7613498266Sopenharmony_ci 7713498266Sopenharmony_ci memset(buf, 0, ICONV_ID_SIZE); 7813498266Sopenharmony_ci curl_msprintf(buf, "IBMCCSID%05u0000000", ccsid); 7913498266Sopenharmony_ci} 8013498266Sopenharmony_ci 8113498266Sopenharmony_ci 8213498266Sopenharmony_cistatic iconv_t 8313498266Sopenharmony_ciiconv_open_CCSID(unsigned int ccsidout, unsigned int ccsidin, 8413498266Sopenharmony_ci unsigned int cstr) 8513498266Sopenharmony_ci{ 8613498266Sopenharmony_ci char fromcode[ICONV_ID_SIZE]; 8713498266Sopenharmony_ci char tocode[ICONV_ID_SIZE]; 8813498266Sopenharmony_ci 8913498266Sopenharmony_ci /** 9013498266Sopenharmony_ci *** Like iconv_open(), but character codes are given as CCSIDs. 9113498266Sopenharmony_ci *** If `cstr' is non-zero, conversion is set up to stop whenever a 9213498266Sopenharmony_ci *** null character is encountered. 9313498266Sopenharmony_ci *** See iconv_open() IBM description in "National Language Support API". 9413498266Sopenharmony_ci **/ 9513498266Sopenharmony_ci 9613498266Sopenharmony_ci makeOS400IconvCode(fromcode, ccsidin); 9713498266Sopenharmony_ci makeOS400IconvCode(tocode, ccsidout); 9813498266Sopenharmony_ci memset(tocode + 13, 0, sizeof(tocode) - 13); /* Dest. code id format. */ 9913498266Sopenharmony_ci 10013498266Sopenharmony_ci if(cstr) 10113498266Sopenharmony_ci fromcode[18] = '1'; /* Set null-terminator flag. */ 10213498266Sopenharmony_ci 10313498266Sopenharmony_ci return iconv_open(tocode, fromcode); 10413498266Sopenharmony_ci} 10513498266Sopenharmony_ci 10613498266Sopenharmony_ci 10713498266Sopenharmony_cistatic int 10813498266Sopenharmony_ciconvert(char *d, size_t dlen, int dccsid, 10913498266Sopenharmony_ci const char *s, int slen, int sccsid) 11013498266Sopenharmony_ci{ 11113498266Sopenharmony_ci int i; 11213498266Sopenharmony_ci iconv_t cd; 11313498266Sopenharmony_ci size_t lslen; 11413498266Sopenharmony_ci 11513498266Sopenharmony_ci /** 11613498266Sopenharmony_ci *** Convert `sccsid'-coded `slen'-data bytes at `s' into `dccsid'-coded 11713498266Sopenharmony_ci *** data stored in the `dlen'-byte buffer at `d'. 11813498266Sopenharmony_ci *** If `slen' < 0, source string is null-terminated. 11913498266Sopenharmony_ci *** CCSID 65535 (no conversion) is replaced by the ASCII CCSID. 12013498266Sopenharmony_ci *** Return the converted destination byte count, or -1 if error. 12113498266Sopenharmony_ci **/ 12213498266Sopenharmony_ci 12313498266Sopenharmony_ci if(sccsid == 65535) 12413498266Sopenharmony_ci sccsid = ASCII_CCSID; 12513498266Sopenharmony_ci 12613498266Sopenharmony_ci if(dccsid == 65535) 12713498266Sopenharmony_ci dccsid = ASCII_CCSID; 12813498266Sopenharmony_ci 12913498266Sopenharmony_ci if(sccsid == dccsid) { 13013498266Sopenharmony_ci lslen = slen >= 0? slen: strlen(s) + 1; 13113498266Sopenharmony_ci i = lslen < dlen? lslen: dlen; 13213498266Sopenharmony_ci 13313498266Sopenharmony_ci if(s != d && i > 0) 13413498266Sopenharmony_ci memcpy(d, s, i); 13513498266Sopenharmony_ci 13613498266Sopenharmony_ci return i; 13713498266Sopenharmony_ci } 13813498266Sopenharmony_ci 13913498266Sopenharmony_ci if(slen < 0) { 14013498266Sopenharmony_ci lslen = 0; 14113498266Sopenharmony_ci cd = iconv_open_CCSID(dccsid, sccsid, 1); 14213498266Sopenharmony_ci } 14313498266Sopenharmony_ci else { 14413498266Sopenharmony_ci lslen = (size_t) slen; 14513498266Sopenharmony_ci cd = iconv_open_CCSID(dccsid, sccsid, 0); 14613498266Sopenharmony_ci } 14713498266Sopenharmony_ci 14813498266Sopenharmony_ci if(ICONV_OPEN_ERROR(cd)) 14913498266Sopenharmony_ci return -1; 15013498266Sopenharmony_ci 15113498266Sopenharmony_ci i = dlen; 15213498266Sopenharmony_ci 15313498266Sopenharmony_ci if((int) iconv(cd, (char * *) &s, &lslen, &d, &dlen) < 0) 15413498266Sopenharmony_ci i = -1; 15513498266Sopenharmony_ci else 15613498266Sopenharmony_ci i -= dlen; 15713498266Sopenharmony_ci 15813498266Sopenharmony_ci iconv_close(cd); 15913498266Sopenharmony_ci return i; 16013498266Sopenharmony_ci} 16113498266Sopenharmony_ci 16213498266Sopenharmony_ci 16313498266Sopenharmony_cistatic char *dynconvert(int dccsid, const char *s, int slen, int sccsid) 16413498266Sopenharmony_ci{ 16513498266Sopenharmony_ci char *d; 16613498266Sopenharmony_ci char *cp; 16713498266Sopenharmony_ci size_t dlen; 16813498266Sopenharmony_ci int l; 16913498266Sopenharmony_ci static const char nullbyte = 0; 17013498266Sopenharmony_ci 17113498266Sopenharmony_ci /* Like convert, but the destination is allocated and returned. */ 17213498266Sopenharmony_ci 17313498266Sopenharmony_ci dlen = (size_t) (slen < 0? strlen(s): slen) + 1; 17413498266Sopenharmony_ci dlen *= MAX_CONV_EXPANSION; /* Allow some expansion. */ 17513498266Sopenharmony_ci d = malloc(dlen); 17613498266Sopenharmony_ci 17713498266Sopenharmony_ci if(!d) 17813498266Sopenharmony_ci return (char *) NULL; 17913498266Sopenharmony_ci 18013498266Sopenharmony_ci l = convert(d, dlen, dccsid, s, slen, sccsid); 18113498266Sopenharmony_ci 18213498266Sopenharmony_ci if(l < 0) { 18313498266Sopenharmony_ci free(d); 18413498266Sopenharmony_ci return (char *) NULL; 18513498266Sopenharmony_ci } 18613498266Sopenharmony_ci 18713498266Sopenharmony_ci if(slen < 0) { 18813498266Sopenharmony_ci /* Need to null-terminate even when source length is given. 18913498266Sopenharmony_ci Since destination code size is unknown, use a conversion to generate 19013498266Sopenharmony_ci terminator. */ 19113498266Sopenharmony_ci 19213498266Sopenharmony_ci int l2 = convert(d + l, dlen - l, dccsid, &nullbyte, -1, ASCII_CCSID); 19313498266Sopenharmony_ci 19413498266Sopenharmony_ci if(l2 < 0) { 19513498266Sopenharmony_ci free(d); 19613498266Sopenharmony_ci return (char *) NULL; 19713498266Sopenharmony_ci } 19813498266Sopenharmony_ci 19913498266Sopenharmony_ci l += l2; 20013498266Sopenharmony_ci } 20113498266Sopenharmony_ci 20213498266Sopenharmony_ci if((size_t) l < dlen) { 20313498266Sopenharmony_ci cp = realloc(d, l); /* Shorten to minimum needed. */ 20413498266Sopenharmony_ci 20513498266Sopenharmony_ci if(cp) 20613498266Sopenharmony_ci d = cp; 20713498266Sopenharmony_ci } 20813498266Sopenharmony_ci 20913498266Sopenharmony_ci return d; 21013498266Sopenharmony_ci} 21113498266Sopenharmony_ci 21213498266Sopenharmony_ci 21313498266Sopenharmony_cistatic struct curl_slist * 21413498266Sopenharmony_cislist_convert(int dccsid, struct curl_slist *from, int sccsid) 21513498266Sopenharmony_ci{ 21613498266Sopenharmony_ci struct curl_slist *to = (struct curl_slist *) NULL; 21713498266Sopenharmony_ci 21813498266Sopenharmony_ci for(; from; from = from->next) { 21913498266Sopenharmony_ci struct curl_slist *nl; 22013498266Sopenharmony_ci char *cp = dynconvert(dccsid, from->data, -1, sccsid); 22113498266Sopenharmony_ci 22213498266Sopenharmony_ci if(!cp) { 22313498266Sopenharmony_ci curl_slist_free_all(to); 22413498266Sopenharmony_ci return (struct curl_slist *) NULL; 22513498266Sopenharmony_ci } 22613498266Sopenharmony_ci nl = Curl_slist_append_nodup(to, cp); 22713498266Sopenharmony_ci if(!nl) { 22813498266Sopenharmony_ci curl_slist_free_all(to); 22913498266Sopenharmony_ci free(cp); 23013498266Sopenharmony_ci return NULL; 23113498266Sopenharmony_ci } 23213498266Sopenharmony_ci to = nl; 23313498266Sopenharmony_ci } 23413498266Sopenharmony_ci return to; 23513498266Sopenharmony_ci} 23613498266Sopenharmony_ci 23713498266Sopenharmony_ci 23813498266Sopenharmony_cistatic char * 23913498266Sopenharmony_cikeyed_string(localkey_t key, const char *ascii, unsigned int ccsid) 24013498266Sopenharmony_ci{ 24113498266Sopenharmony_ci int i; 24213498266Sopenharmony_ci char *ebcdic; 24313498266Sopenharmony_ci 24413498266Sopenharmony_ci if(!ascii) 24513498266Sopenharmony_ci return (char *) NULL; 24613498266Sopenharmony_ci 24713498266Sopenharmony_ci i = MAX_CONV_EXPANSION * (strlen(ascii) + 1); 24813498266Sopenharmony_ci 24913498266Sopenharmony_ci ebcdic = Curl_thread_buffer(key, i); 25013498266Sopenharmony_ci if(!ebcdic) 25113498266Sopenharmony_ci return ebcdic; 25213498266Sopenharmony_ci 25313498266Sopenharmony_ci if(convert(ebcdic, i, ccsid, ascii, -1, ASCII_CCSID) < 0) 25413498266Sopenharmony_ci return (char *) NULL; 25513498266Sopenharmony_ci 25613498266Sopenharmony_ci return ebcdic; 25713498266Sopenharmony_ci} 25813498266Sopenharmony_ci 25913498266Sopenharmony_ci 26013498266Sopenharmony_ciconst char * 26113498266Sopenharmony_cicurl_to_ccsid(const char *s, unsigned int ccsid) 26213498266Sopenharmony_ci{ 26313498266Sopenharmony_ci if(s) 26413498266Sopenharmony_ci s = dynconvert(ccsid, s, -1, ASCII_CCSID); 26513498266Sopenharmony_ci return s; 26613498266Sopenharmony_ci} 26713498266Sopenharmony_ci 26813498266Sopenharmony_ci 26913498266Sopenharmony_ciconst char * 27013498266Sopenharmony_cicurl_from_ccsid(const char *s, unsigned int ccsid) 27113498266Sopenharmony_ci{ 27213498266Sopenharmony_ci if(s) 27313498266Sopenharmony_ci s = dynconvert(ASCII_CCSID, s, -1, ccsid); 27413498266Sopenharmony_ci return s; 27513498266Sopenharmony_ci} 27613498266Sopenharmony_ci 27713498266Sopenharmony_ci 27813498266Sopenharmony_cichar * 27913498266Sopenharmony_cicurl_version_ccsid(unsigned int ccsid) 28013498266Sopenharmony_ci{ 28113498266Sopenharmony_ci return keyed_string(LK_CURL_VERSION, curl_version(), ccsid); 28213498266Sopenharmony_ci} 28313498266Sopenharmony_ci 28413498266Sopenharmony_ci 28513498266Sopenharmony_cichar * 28613498266Sopenharmony_cicurl_easy_escape_ccsid(CURL *handle, const char *string, int length, 28713498266Sopenharmony_ci unsigned int sccsid, unsigned int dccsid) 28813498266Sopenharmony_ci{ 28913498266Sopenharmony_ci char *s; 29013498266Sopenharmony_ci char *d; 29113498266Sopenharmony_ci 29213498266Sopenharmony_ci if(!string) { 29313498266Sopenharmony_ci errno = EINVAL; 29413498266Sopenharmony_ci return (char *) NULL; 29513498266Sopenharmony_ci } 29613498266Sopenharmony_ci 29713498266Sopenharmony_ci s = dynconvert(ASCII_CCSID, string, length? length: -1, sccsid); 29813498266Sopenharmony_ci 29913498266Sopenharmony_ci if(!s) 30013498266Sopenharmony_ci return (char *) NULL; 30113498266Sopenharmony_ci 30213498266Sopenharmony_ci d = curl_easy_escape(handle, s, 0); 30313498266Sopenharmony_ci free(s); 30413498266Sopenharmony_ci 30513498266Sopenharmony_ci if(!d) 30613498266Sopenharmony_ci return (char *) NULL; 30713498266Sopenharmony_ci 30813498266Sopenharmony_ci s = dynconvert(dccsid, d, -1, ASCII_CCSID); 30913498266Sopenharmony_ci free(d); 31013498266Sopenharmony_ci return s; 31113498266Sopenharmony_ci} 31213498266Sopenharmony_ci 31313498266Sopenharmony_ci 31413498266Sopenharmony_cichar * 31513498266Sopenharmony_cicurl_easy_unescape_ccsid(CURL *handle, const char *string, int length, 31613498266Sopenharmony_ci int *outlength, 31713498266Sopenharmony_ci unsigned int sccsid, unsigned int dccsid) 31813498266Sopenharmony_ci{ 31913498266Sopenharmony_ci char *s; 32013498266Sopenharmony_ci char *d; 32113498266Sopenharmony_ci 32213498266Sopenharmony_ci if(!string) { 32313498266Sopenharmony_ci errno = EINVAL; 32413498266Sopenharmony_ci return (char *) NULL; 32513498266Sopenharmony_ci } 32613498266Sopenharmony_ci 32713498266Sopenharmony_ci s = dynconvert(ASCII_CCSID, string, length? length: -1, sccsid); 32813498266Sopenharmony_ci 32913498266Sopenharmony_ci if(!s) 33013498266Sopenharmony_ci return (char *) NULL; 33113498266Sopenharmony_ci 33213498266Sopenharmony_ci d = curl_easy_unescape(handle, s, 0, outlength); 33313498266Sopenharmony_ci free(s); 33413498266Sopenharmony_ci 33513498266Sopenharmony_ci if(!d) 33613498266Sopenharmony_ci return (char *) NULL; 33713498266Sopenharmony_ci 33813498266Sopenharmony_ci s = dynconvert(dccsid, d, -1, ASCII_CCSID); 33913498266Sopenharmony_ci free(d); 34013498266Sopenharmony_ci 34113498266Sopenharmony_ci if(s && outlength) 34213498266Sopenharmony_ci *outlength = strlen(s); 34313498266Sopenharmony_ci 34413498266Sopenharmony_ci return s; 34513498266Sopenharmony_ci} 34613498266Sopenharmony_ci 34713498266Sopenharmony_ci 34813498266Sopenharmony_cistruct curl_slist * 34913498266Sopenharmony_cicurl_slist_append_ccsid(struct curl_slist *list, 35013498266Sopenharmony_ci const char *data, unsigned int ccsid) 35113498266Sopenharmony_ci{ 35213498266Sopenharmony_ci char *s; 35313498266Sopenharmony_ci 35413498266Sopenharmony_ci s = (char *) NULL; 35513498266Sopenharmony_ci 35613498266Sopenharmony_ci if(!data) 35713498266Sopenharmony_ci return curl_slist_append(list, data); 35813498266Sopenharmony_ci 35913498266Sopenharmony_ci s = dynconvert(ASCII_CCSID, data, -1, ccsid); 36013498266Sopenharmony_ci 36113498266Sopenharmony_ci if(!s) 36213498266Sopenharmony_ci return (struct curl_slist *) NULL; 36313498266Sopenharmony_ci 36413498266Sopenharmony_ci list = curl_slist_append(list, s); 36513498266Sopenharmony_ci free(s); 36613498266Sopenharmony_ci return list; 36713498266Sopenharmony_ci} 36813498266Sopenharmony_ci 36913498266Sopenharmony_ci 37013498266Sopenharmony_citime_t 37113498266Sopenharmony_cicurl_getdate_ccsid(const char *p, const time_t *unused, unsigned int ccsid) 37213498266Sopenharmony_ci{ 37313498266Sopenharmony_ci char *s; 37413498266Sopenharmony_ci time_t t; 37513498266Sopenharmony_ci 37613498266Sopenharmony_ci if(!p) 37713498266Sopenharmony_ci return curl_getdate(p, unused); 37813498266Sopenharmony_ci 37913498266Sopenharmony_ci s = dynconvert(ASCII_CCSID, p, -1, ccsid); 38013498266Sopenharmony_ci 38113498266Sopenharmony_ci if(!s) 38213498266Sopenharmony_ci return (time_t) -1; 38313498266Sopenharmony_ci 38413498266Sopenharmony_ci t = curl_getdate(s, unused); 38513498266Sopenharmony_ci free(s); 38613498266Sopenharmony_ci return t; 38713498266Sopenharmony_ci} 38813498266Sopenharmony_ci 38913498266Sopenharmony_ci 39013498266Sopenharmony_cistatic int 39113498266Sopenharmony_ciconvert_version_info_string(const char **stringp, 39213498266Sopenharmony_ci char **bufp, int *left, unsigned int ccsid) 39313498266Sopenharmony_ci{ 39413498266Sopenharmony_ci /* Helper for curl_version_info_ccsid(): convert a string if defined. 39513498266Sopenharmony_ci Result is stored in the `*left'-byte buffer at `*bufp'. 39613498266Sopenharmony_ci `*bufp' and `*left' are updated accordingly. 39713498266Sopenharmony_ci Return 0 if ok, else -1. */ 39813498266Sopenharmony_ci 39913498266Sopenharmony_ci if(*stringp) { 40013498266Sopenharmony_ci int l = convert(*bufp, *left, ccsid, *stringp, -1, ASCII_CCSID); 40113498266Sopenharmony_ci 40213498266Sopenharmony_ci if(l <= 0) 40313498266Sopenharmony_ci return -1; 40413498266Sopenharmony_ci 40513498266Sopenharmony_ci *stringp = *bufp; 40613498266Sopenharmony_ci *bufp += l; 40713498266Sopenharmony_ci *left -= l; 40813498266Sopenharmony_ci } 40913498266Sopenharmony_ci 41013498266Sopenharmony_ci return 0; 41113498266Sopenharmony_ci} 41213498266Sopenharmony_ci 41313498266Sopenharmony_ci 41413498266Sopenharmony_cicurl_version_info_data * 41513498266Sopenharmony_cicurl_version_info_ccsid(CURLversion stamp, unsigned int ccsid) 41613498266Sopenharmony_ci{ 41713498266Sopenharmony_ci curl_version_info_data *p; 41813498266Sopenharmony_ci char *cp; 41913498266Sopenharmony_ci int n; 42013498266Sopenharmony_ci int nproto; 42113498266Sopenharmony_ci curl_version_info_data *id; 42213498266Sopenharmony_ci int i; 42313498266Sopenharmony_ci const char **cpp; 42413498266Sopenharmony_ci static const size_t charfields[] = { 42513498266Sopenharmony_ci offsetof(curl_version_info_data, version), 42613498266Sopenharmony_ci offsetof(curl_version_info_data, host), 42713498266Sopenharmony_ci offsetof(curl_version_info_data, ssl_version), 42813498266Sopenharmony_ci offsetof(curl_version_info_data, libz_version), 42913498266Sopenharmony_ci offsetof(curl_version_info_data, ares), 43013498266Sopenharmony_ci offsetof(curl_version_info_data, libidn), 43113498266Sopenharmony_ci offsetof(curl_version_info_data, libssh_version), 43213498266Sopenharmony_ci offsetof(curl_version_info_data, brotli_version), 43313498266Sopenharmony_ci offsetof(curl_version_info_data, nghttp2_version), 43413498266Sopenharmony_ci offsetof(curl_version_info_data, quic_version), 43513498266Sopenharmony_ci offsetof(curl_version_info_data, cainfo), 43613498266Sopenharmony_ci offsetof(curl_version_info_data, capath), 43713498266Sopenharmony_ci offsetof(curl_version_info_data, zstd_version), 43813498266Sopenharmony_ci offsetof(curl_version_info_data, hyper_version), 43913498266Sopenharmony_ci offsetof(curl_version_info_data, gsasl_version), 44013498266Sopenharmony_ci offsetof(curl_version_info_data, feature_names) 44113498266Sopenharmony_ci }; 44213498266Sopenharmony_ci 44313498266Sopenharmony_ci /* The assertion below is possible, because although the second operand 44413498266Sopenharmony_ci is an enum member, the first is a #define. In that case, the OS/400 C 44513498266Sopenharmony_ci compiler seems to compare string values after substitution. */ 44613498266Sopenharmony_ci 44713498266Sopenharmony_ci#if CURLVERSION_NOW != CURLVERSION_ELEVENTH 44813498266Sopenharmony_ci#error curl_version_info_data structure has changed: upgrade this procedure. 44913498266Sopenharmony_ci#endif 45013498266Sopenharmony_ci 45113498266Sopenharmony_ci /* If caller has been compiled with a newer version, error. */ 45213498266Sopenharmony_ci 45313498266Sopenharmony_ci if(stamp > CURLVERSION_NOW) 45413498266Sopenharmony_ci return (curl_version_info_data *) NULL; 45513498266Sopenharmony_ci 45613498266Sopenharmony_ci p = curl_version_info(stamp); 45713498266Sopenharmony_ci 45813498266Sopenharmony_ci if(!p) 45913498266Sopenharmony_ci return p; 46013498266Sopenharmony_ci 46113498266Sopenharmony_ci /* Measure thread space needed. */ 46213498266Sopenharmony_ci 46313498266Sopenharmony_ci n = 0; 46413498266Sopenharmony_ci nproto = 0; 46513498266Sopenharmony_ci 46613498266Sopenharmony_ci if(p->protocols) { 46713498266Sopenharmony_ci while(p->protocols[nproto]) 46813498266Sopenharmony_ci n += strlen(p->protocols[nproto++]); 46913498266Sopenharmony_ci 47013498266Sopenharmony_ci n += nproto++; 47113498266Sopenharmony_ci } 47213498266Sopenharmony_ci 47313498266Sopenharmony_ci for(i = 0; i < sizeof(charfields) / sizeof(charfields[0]); i++) { 47413498266Sopenharmony_ci cpp = (const char **) ((char *) p + charfields[i]); 47513498266Sopenharmony_ci if(*cpp) 47613498266Sopenharmony_ci n += strlen(*cpp) + 1; 47713498266Sopenharmony_ci } 47813498266Sopenharmony_ci 47913498266Sopenharmony_ci /* Allocate thread space. */ 48013498266Sopenharmony_ci 48113498266Sopenharmony_ci n *= MAX_CONV_EXPANSION; 48213498266Sopenharmony_ci 48313498266Sopenharmony_ci if(nproto) 48413498266Sopenharmony_ci n += nproto * sizeof(const char *); 48513498266Sopenharmony_ci 48613498266Sopenharmony_ci cp = Curl_thread_buffer(LK_VERSION_INFO_DATA, n); 48713498266Sopenharmony_ci id = (curl_version_info_data *) Curl_thread_buffer(LK_VERSION_INFO, 48813498266Sopenharmony_ci sizeof(*id)); 48913498266Sopenharmony_ci 49013498266Sopenharmony_ci if(!id || !cp) 49113498266Sopenharmony_ci return (curl_version_info_data *) NULL; 49213498266Sopenharmony_ci 49313498266Sopenharmony_ci /* Copy data and convert strings. */ 49413498266Sopenharmony_ci 49513498266Sopenharmony_ci memcpy((char *) id, (char *) p, sizeof(*p)); 49613498266Sopenharmony_ci 49713498266Sopenharmony_ci if(id->protocols) { 49813498266Sopenharmony_ci i = nproto * sizeof(id->protocols[0]); 49913498266Sopenharmony_ci 50013498266Sopenharmony_ci id->protocols = (const char * const *) cp; 50113498266Sopenharmony_ci memcpy(cp, (char *) p->protocols, i); 50213498266Sopenharmony_ci cp += i; 50313498266Sopenharmony_ci n -= i; 50413498266Sopenharmony_ci 50513498266Sopenharmony_ci for(i = 0; id->protocols[i]; i++) 50613498266Sopenharmony_ci if(convert_version_info_string(((const char * *) id->protocols) + i, 50713498266Sopenharmony_ci &cp, &n, ccsid)) 50813498266Sopenharmony_ci return (curl_version_info_data *) NULL; 50913498266Sopenharmony_ci } 51013498266Sopenharmony_ci 51113498266Sopenharmony_ci for(i = 0; i < sizeof(charfields) / sizeof(charfields[0]); i++) { 51213498266Sopenharmony_ci cpp = (const char **) ((char *) p + charfields[i]); 51313498266Sopenharmony_ci if(*cpp && convert_version_info_string(cpp, &cp, &n, ccsid)) 51413498266Sopenharmony_ci return (curl_version_info_data *) NULL; 51513498266Sopenharmony_ci } 51613498266Sopenharmony_ci 51713498266Sopenharmony_ci return id; 51813498266Sopenharmony_ci} 51913498266Sopenharmony_ci 52013498266Sopenharmony_ci 52113498266Sopenharmony_ciconst char * 52213498266Sopenharmony_cicurl_easy_strerror_ccsid(CURLcode error, unsigned int ccsid) 52313498266Sopenharmony_ci{ 52413498266Sopenharmony_ci return keyed_string(LK_EASY_STRERROR, curl_easy_strerror(error), ccsid); 52513498266Sopenharmony_ci} 52613498266Sopenharmony_ci 52713498266Sopenharmony_ci 52813498266Sopenharmony_ciconst char * 52913498266Sopenharmony_cicurl_share_strerror_ccsid(CURLSHcode error, unsigned int ccsid) 53013498266Sopenharmony_ci{ 53113498266Sopenharmony_ci return keyed_string(LK_SHARE_STRERROR, curl_share_strerror(error), ccsid); 53213498266Sopenharmony_ci} 53313498266Sopenharmony_ci 53413498266Sopenharmony_ci 53513498266Sopenharmony_ciconst char * 53613498266Sopenharmony_cicurl_multi_strerror_ccsid(CURLMcode error, unsigned int ccsid) 53713498266Sopenharmony_ci{ 53813498266Sopenharmony_ci return keyed_string(LK_MULTI_STRERROR, curl_multi_strerror(error), ccsid); 53913498266Sopenharmony_ci} 54013498266Sopenharmony_ci 54113498266Sopenharmony_ci 54213498266Sopenharmony_ciconst char * 54313498266Sopenharmony_cicurl_url_strerror_ccsid(CURLUcode error, unsigned int ccsid) 54413498266Sopenharmony_ci{ 54513498266Sopenharmony_ci return keyed_string(LK_URL_STRERROR, curl_url_strerror(error), ccsid); 54613498266Sopenharmony_ci} 54713498266Sopenharmony_ci 54813498266Sopenharmony_ci 54913498266Sopenharmony_civoid 55013498266Sopenharmony_cicurl_certinfo_free_all(struct curl_certinfo *info) 55113498266Sopenharmony_ci{ 55213498266Sopenharmony_ci /* Free all memory used by certificate info. */ 55313498266Sopenharmony_ci if(info) { 55413498266Sopenharmony_ci if(info->certinfo) { 55513498266Sopenharmony_ci int i; 55613498266Sopenharmony_ci 55713498266Sopenharmony_ci for(i = 0; i < info->num_of_certs; i++) 55813498266Sopenharmony_ci curl_slist_free_all(info->certinfo[i]); 55913498266Sopenharmony_ci free((char *) info->certinfo); 56013498266Sopenharmony_ci } 56113498266Sopenharmony_ci free((char *) info); 56213498266Sopenharmony_ci } 56313498266Sopenharmony_ci} 56413498266Sopenharmony_ci 56513498266Sopenharmony_ci 56613498266Sopenharmony_ciCURLcode 56713498266Sopenharmony_cicurl_easy_getinfo_ccsid(CURL *curl, CURLINFO info, ...) 56813498266Sopenharmony_ci{ 56913498266Sopenharmony_ci va_list arg; 57013498266Sopenharmony_ci void *paramp; 57113498266Sopenharmony_ci CURLcode ret; 57213498266Sopenharmony_ci struct Curl_easy *data; 57313498266Sopenharmony_ci 57413498266Sopenharmony_ci /* WARNING: unlike curl_easy_getinfo(), the strings returned by this 57513498266Sopenharmony_ci procedure have to be free'ed. */ 57613498266Sopenharmony_ci 57713498266Sopenharmony_ci data = (struct Curl_easy *) curl; 57813498266Sopenharmony_ci va_start(arg, info); 57913498266Sopenharmony_ci paramp = va_arg(arg, void *); 58013498266Sopenharmony_ci ret = Curl_getinfo(data, info, paramp); 58113498266Sopenharmony_ci 58213498266Sopenharmony_ci if(ret == CURLE_OK) { 58313498266Sopenharmony_ci unsigned int ccsid; 58413498266Sopenharmony_ci char **cpp; 58513498266Sopenharmony_ci struct curl_slist **slp; 58613498266Sopenharmony_ci struct curl_certinfo *cipf; 58713498266Sopenharmony_ci struct curl_certinfo *cipt; 58813498266Sopenharmony_ci 58913498266Sopenharmony_ci switch((int) info & CURLINFO_TYPEMASK) { 59013498266Sopenharmony_ci 59113498266Sopenharmony_ci case CURLINFO_STRING: 59213498266Sopenharmony_ci ccsid = va_arg(arg, unsigned int); 59313498266Sopenharmony_ci cpp = (char * *) paramp; 59413498266Sopenharmony_ci 59513498266Sopenharmony_ci if(*cpp) { 59613498266Sopenharmony_ci *cpp = dynconvert(ccsid, *cpp, -1, ASCII_CCSID); 59713498266Sopenharmony_ci 59813498266Sopenharmony_ci if(!*cpp) 59913498266Sopenharmony_ci ret = CURLE_OUT_OF_MEMORY; 60013498266Sopenharmony_ci } 60113498266Sopenharmony_ci 60213498266Sopenharmony_ci break; 60313498266Sopenharmony_ci 60413498266Sopenharmony_ci case CURLINFO_SLIST: 60513498266Sopenharmony_ci ccsid = va_arg(arg, unsigned int); 60613498266Sopenharmony_ci switch(info) { 60713498266Sopenharmony_ci case CURLINFO_CERTINFO: 60813498266Sopenharmony_ci cipf = *(struct curl_certinfo * *) paramp; 60913498266Sopenharmony_ci if(cipf) { 61013498266Sopenharmony_ci cipt = (struct curl_certinfo *) malloc(sizeof(*cipt)); 61113498266Sopenharmony_ci if(!cipt) 61213498266Sopenharmony_ci ret = CURLE_OUT_OF_MEMORY; 61313498266Sopenharmony_ci else { 61413498266Sopenharmony_ci cipt->certinfo = (struct curl_slist **) 61513498266Sopenharmony_ci calloc(cipf->num_of_certs + 61613498266Sopenharmony_ci 1, sizeof(struct curl_slist *)); 61713498266Sopenharmony_ci if(!cipt->certinfo) 61813498266Sopenharmony_ci ret = CURLE_OUT_OF_MEMORY; 61913498266Sopenharmony_ci else { 62013498266Sopenharmony_ci int i; 62113498266Sopenharmony_ci 62213498266Sopenharmony_ci cipt->num_of_certs = cipf->num_of_certs; 62313498266Sopenharmony_ci for(i = 0; i < cipf->num_of_certs; i++) 62413498266Sopenharmony_ci if(cipf->certinfo[i]) 62513498266Sopenharmony_ci if(!(cipt->certinfo[i] = slist_convert(ccsid, 62613498266Sopenharmony_ci cipf->certinfo[i], 62713498266Sopenharmony_ci ASCII_CCSID))) { 62813498266Sopenharmony_ci ret = CURLE_OUT_OF_MEMORY; 62913498266Sopenharmony_ci break; 63013498266Sopenharmony_ci } 63113498266Sopenharmony_ci } 63213498266Sopenharmony_ci } 63313498266Sopenharmony_ci 63413498266Sopenharmony_ci if(ret != CURLE_OK) { 63513498266Sopenharmony_ci curl_certinfo_free_all(cipt); 63613498266Sopenharmony_ci cipt = (struct curl_certinfo *) NULL; 63713498266Sopenharmony_ci } 63813498266Sopenharmony_ci 63913498266Sopenharmony_ci *(struct curl_certinfo * *) paramp = cipt; 64013498266Sopenharmony_ci } 64113498266Sopenharmony_ci 64213498266Sopenharmony_ci break; 64313498266Sopenharmony_ci 64413498266Sopenharmony_ci case CURLINFO_TLS_SESSION: 64513498266Sopenharmony_ci case CURLINFO_TLS_SSL_PTR: 64613498266Sopenharmony_ci case CURLINFO_SOCKET: 64713498266Sopenharmony_ci break; 64813498266Sopenharmony_ci 64913498266Sopenharmony_ci default: 65013498266Sopenharmony_ci slp = (struct curl_slist **) paramp; 65113498266Sopenharmony_ci if(*slp) { 65213498266Sopenharmony_ci *slp = slist_convert(ccsid, *slp, ASCII_CCSID); 65313498266Sopenharmony_ci if(!*slp) 65413498266Sopenharmony_ci ret = CURLE_OUT_OF_MEMORY; 65513498266Sopenharmony_ci } 65613498266Sopenharmony_ci break; 65713498266Sopenharmony_ci } 65813498266Sopenharmony_ci } 65913498266Sopenharmony_ci } 66013498266Sopenharmony_ci 66113498266Sopenharmony_ci va_end(arg); 66213498266Sopenharmony_ci return ret; 66313498266Sopenharmony_ci} 66413498266Sopenharmony_ci 66513498266Sopenharmony_ci 66613498266Sopenharmony_cistatic int 66713498266Sopenharmony_ciCurl_is_formadd_string(CURLformoption option) 66813498266Sopenharmony_ci{ 66913498266Sopenharmony_ci switch(option) { 67013498266Sopenharmony_ci 67113498266Sopenharmony_ci case CURLFORM_FILENAME: 67213498266Sopenharmony_ci case CURLFORM_CONTENTTYPE: 67313498266Sopenharmony_ci case CURLFORM_BUFFER: 67413498266Sopenharmony_ci case CURLFORM_FILE: 67513498266Sopenharmony_ci case CURLFORM_FILECONTENT: 67613498266Sopenharmony_ci case CURLFORM_COPYCONTENTS: 67713498266Sopenharmony_ci case CURLFORM_COPYNAME: 67813498266Sopenharmony_ci return 1; 67913498266Sopenharmony_ci } 68013498266Sopenharmony_ci 68113498266Sopenharmony_ci return 0; 68213498266Sopenharmony_ci} 68313498266Sopenharmony_ci 68413498266Sopenharmony_ci 68513498266Sopenharmony_cistatic void 68613498266Sopenharmony_ciCurl_formadd_release_local(struct curl_forms *forms, int nargs, int skip) 68713498266Sopenharmony_ci{ 68813498266Sopenharmony_ci while(nargs--) 68913498266Sopenharmony_ci if(nargs != skip) 69013498266Sopenharmony_ci if(Curl_is_formadd_string(forms[nargs].option)) 69113498266Sopenharmony_ci if(forms[nargs].value) 69213498266Sopenharmony_ci free((char *) forms[nargs].value); 69313498266Sopenharmony_ci 69413498266Sopenharmony_ci free((char *) forms); 69513498266Sopenharmony_ci} 69613498266Sopenharmony_ci 69713498266Sopenharmony_ci 69813498266Sopenharmony_cistatic int 69913498266Sopenharmony_ciCurl_formadd_convert(struct curl_forms *forms, 70013498266Sopenharmony_ci int formx, int lengthx, unsigned int ccsid) 70113498266Sopenharmony_ci{ 70213498266Sopenharmony_ci int l; 70313498266Sopenharmony_ci char *cp; 70413498266Sopenharmony_ci char *cp2; 70513498266Sopenharmony_ci 70613498266Sopenharmony_ci if(formx < 0 || !forms[formx].value) 70713498266Sopenharmony_ci return 0; 70813498266Sopenharmony_ci 70913498266Sopenharmony_ci if(lengthx >= 0) 71013498266Sopenharmony_ci l = (int) forms[lengthx].value; 71113498266Sopenharmony_ci else 71213498266Sopenharmony_ci l = strlen(forms[formx].value) + 1; 71313498266Sopenharmony_ci 71413498266Sopenharmony_ci cp = malloc(MAX_CONV_EXPANSION * l); 71513498266Sopenharmony_ci 71613498266Sopenharmony_ci if(!cp) 71713498266Sopenharmony_ci return -1; 71813498266Sopenharmony_ci 71913498266Sopenharmony_ci l = convert(cp, MAX_CONV_EXPANSION * l, ASCII_CCSID, 72013498266Sopenharmony_ci forms[formx].value, l, ccsid); 72113498266Sopenharmony_ci 72213498266Sopenharmony_ci if(l < 0) { 72313498266Sopenharmony_ci free(cp); 72413498266Sopenharmony_ci return -1; 72513498266Sopenharmony_ci } 72613498266Sopenharmony_ci 72713498266Sopenharmony_ci cp2 = realloc(cp, l); /* Shorten buffer to the string size. */ 72813498266Sopenharmony_ci 72913498266Sopenharmony_ci if(cp2) 73013498266Sopenharmony_ci cp = cp2; 73113498266Sopenharmony_ci 73213498266Sopenharmony_ci forms[formx].value = cp; 73313498266Sopenharmony_ci 73413498266Sopenharmony_ci if(lengthx >= 0) 73513498266Sopenharmony_ci forms[lengthx].value = (char *) l; /* Update length after conversion. */ 73613498266Sopenharmony_ci 73713498266Sopenharmony_ci return l; 73813498266Sopenharmony_ci} 73913498266Sopenharmony_ci 74013498266Sopenharmony_ci 74113498266Sopenharmony_ciCURLFORMcode 74213498266Sopenharmony_cicurl_formadd_ccsid(struct curl_httppost **httppost, 74313498266Sopenharmony_ci struct curl_httppost **last_post, ...) 74413498266Sopenharmony_ci{ 74513498266Sopenharmony_ci va_list arg; 74613498266Sopenharmony_ci CURLformoption option; 74713498266Sopenharmony_ci CURLFORMcode result; 74813498266Sopenharmony_ci struct curl_forms *forms; 74913498266Sopenharmony_ci struct curl_forms *lforms; 75013498266Sopenharmony_ci struct curl_forms *tforms; 75113498266Sopenharmony_ci unsigned int lformlen; 75213498266Sopenharmony_ci const char *value; 75313498266Sopenharmony_ci unsigned int ccsid; 75413498266Sopenharmony_ci int nargs; 75513498266Sopenharmony_ci int namex; 75613498266Sopenharmony_ci int namelengthx; 75713498266Sopenharmony_ci int contentx; 75813498266Sopenharmony_ci int lengthx; 75913498266Sopenharmony_ci unsigned int contentccsid; 76013498266Sopenharmony_ci unsigned int nameccsid; 76113498266Sopenharmony_ci 76213498266Sopenharmony_ci /* A single curl_formadd() call cannot be split in several calls to deal 76313498266Sopenharmony_ci with all parameters: the original parameters are thus copied to a local 76413498266Sopenharmony_ci curl_forms array and converted to ASCII when needed. 76513498266Sopenharmony_ci CURLFORM_PTRNAME is processed as if it were CURLFORM_COPYNAME. 76613498266Sopenharmony_ci CURLFORM_COPYNAME and CURLFORM_NAMELENGTH occurrence order in 76713498266Sopenharmony_ci parameters is not defined; for this reason, the actual conversion is 76813498266Sopenharmony_ci delayed to the end of parameter processing. The same applies to 76913498266Sopenharmony_ci CURLFORM_COPYCONTENTS/CURLFORM_CONTENTSLENGTH, but these may appear 77013498266Sopenharmony_ci several times in the parameter list; the problem resides here in knowing 77113498266Sopenharmony_ci which CURLFORM_CONTENTSLENGTH applies to which CURLFORM_COPYCONTENTS and 77213498266Sopenharmony_ci when we can be sure to have both info for conversion: end of parameter 77313498266Sopenharmony_ci list is such a point, but CURLFORM_CONTENTTYPE is also used here as a 77413498266Sopenharmony_ci natural separator between content data definitions; this seems to be 77513498266Sopenharmony_ci in accordance with FormAdd() behavior. */ 77613498266Sopenharmony_ci 77713498266Sopenharmony_ci /* Allocate the local curl_forms array. */ 77813498266Sopenharmony_ci 77913498266Sopenharmony_ci lformlen = ALLOC_GRANULE; 78013498266Sopenharmony_ci lforms = malloc(lformlen * sizeof(*lforms)); 78113498266Sopenharmony_ci 78213498266Sopenharmony_ci if(!lforms) 78313498266Sopenharmony_ci return CURL_FORMADD_MEMORY; 78413498266Sopenharmony_ci 78513498266Sopenharmony_ci /* Process the arguments, copying them into local array, latching conversion 78613498266Sopenharmony_ci indexes and converting when needed. */ 78713498266Sopenharmony_ci 78813498266Sopenharmony_ci result = CURL_FORMADD_OK; 78913498266Sopenharmony_ci nargs = 0; 79013498266Sopenharmony_ci contentx = -1; 79113498266Sopenharmony_ci lengthx = -1; 79213498266Sopenharmony_ci namex = -1; 79313498266Sopenharmony_ci namelengthx = -1; 79413498266Sopenharmony_ci forms = (struct curl_forms *) NULL; 79513498266Sopenharmony_ci va_start(arg, last_post); 79613498266Sopenharmony_ci 79713498266Sopenharmony_ci for(;;) { 79813498266Sopenharmony_ci /* Make sure there is still room for an item in local array. */ 79913498266Sopenharmony_ci 80013498266Sopenharmony_ci if(nargs >= lformlen) { 80113498266Sopenharmony_ci lformlen += ALLOC_GRANULE; 80213498266Sopenharmony_ci tforms = realloc(lforms, lformlen * sizeof(*lforms)); 80313498266Sopenharmony_ci 80413498266Sopenharmony_ci if(!tforms) { 80513498266Sopenharmony_ci result = CURL_FORMADD_MEMORY; 80613498266Sopenharmony_ci break; 80713498266Sopenharmony_ci } 80813498266Sopenharmony_ci 80913498266Sopenharmony_ci lforms = tforms; 81013498266Sopenharmony_ci } 81113498266Sopenharmony_ci 81213498266Sopenharmony_ci /* Get next option. */ 81313498266Sopenharmony_ci 81413498266Sopenharmony_ci if(forms) { 81513498266Sopenharmony_ci /* Get option from array. */ 81613498266Sopenharmony_ci 81713498266Sopenharmony_ci option = forms->option; 81813498266Sopenharmony_ci value = forms->value; 81913498266Sopenharmony_ci forms++; 82013498266Sopenharmony_ci } 82113498266Sopenharmony_ci else { 82213498266Sopenharmony_ci /* Get option from arguments. */ 82313498266Sopenharmony_ci 82413498266Sopenharmony_ci option = va_arg(arg, CURLformoption); 82513498266Sopenharmony_ci 82613498266Sopenharmony_ci if(option == CURLFORM_END) 82713498266Sopenharmony_ci break; 82813498266Sopenharmony_ci } 82913498266Sopenharmony_ci 83013498266Sopenharmony_ci /* Dispatch by option. */ 83113498266Sopenharmony_ci 83213498266Sopenharmony_ci switch(option) { 83313498266Sopenharmony_ci 83413498266Sopenharmony_ci case CURLFORM_END: 83513498266Sopenharmony_ci forms = (struct curl_forms *) NULL; /* Leave array mode. */ 83613498266Sopenharmony_ci continue; 83713498266Sopenharmony_ci 83813498266Sopenharmony_ci case CURLFORM_ARRAY: 83913498266Sopenharmony_ci if(!forms) { 84013498266Sopenharmony_ci forms = va_arg(arg, struct curl_forms *); 84113498266Sopenharmony_ci continue; 84213498266Sopenharmony_ci } 84313498266Sopenharmony_ci 84413498266Sopenharmony_ci result = CURL_FORMADD_ILLEGAL_ARRAY; 84513498266Sopenharmony_ci break; 84613498266Sopenharmony_ci 84713498266Sopenharmony_ci case CURLFORM_COPYNAME: 84813498266Sopenharmony_ci option = CURLFORM_PTRNAME; /* Static for now. */ 84913498266Sopenharmony_ci 85013498266Sopenharmony_ci case CURLFORM_PTRNAME: 85113498266Sopenharmony_ci if(namex >= 0) 85213498266Sopenharmony_ci result = CURL_FORMADD_OPTION_TWICE; 85313498266Sopenharmony_ci 85413498266Sopenharmony_ci namex = nargs; 85513498266Sopenharmony_ci 85613498266Sopenharmony_ci if(!forms) { 85713498266Sopenharmony_ci value = va_arg(arg, char *); 85813498266Sopenharmony_ci nameccsid = (unsigned int) va_arg(arg, long); 85913498266Sopenharmony_ci } 86013498266Sopenharmony_ci else { 86113498266Sopenharmony_ci nameccsid = (unsigned int) forms->value; 86213498266Sopenharmony_ci forms++; 86313498266Sopenharmony_ci } 86413498266Sopenharmony_ci 86513498266Sopenharmony_ci break; 86613498266Sopenharmony_ci 86713498266Sopenharmony_ci case CURLFORM_COPYCONTENTS: 86813498266Sopenharmony_ci if(contentx >= 0) 86913498266Sopenharmony_ci result = CURL_FORMADD_OPTION_TWICE; 87013498266Sopenharmony_ci 87113498266Sopenharmony_ci contentx = nargs; 87213498266Sopenharmony_ci 87313498266Sopenharmony_ci if(!forms) { 87413498266Sopenharmony_ci value = va_arg(arg, char *); 87513498266Sopenharmony_ci contentccsid = (unsigned int) va_arg(arg, long); 87613498266Sopenharmony_ci } 87713498266Sopenharmony_ci else { 87813498266Sopenharmony_ci contentccsid = (unsigned int) forms->value; 87913498266Sopenharmony_ci forms++; 88013498266Sopenharmony_ci } 88113498266Sopenharmony_ci 88213498266Sopenharmony_ci break; 88313498266Sopenharmony_ci 88413498266Sopenharmony_ci case CURLFORM_PTRCONTENTS: 88513498266Sopenharmony_ci case CURLFORM_BUFFERPTR: 88613498266Sopenharmony_ci if(!forms) 88713498266Sopenharmony_ci value = va_arg(arg, char *); /* No conversion. */ 88813498266Sopenharmony_ci 88913498266Sopenharmony_ci break; 89013498266Sopenharmony_ci 89113498266Sopenharmony_ci case CURLFORM_CONTENTSLENGTH: 89213498266Sopenharmony_ci lengthx = nargs; 89313498266Sopenharmony_ci 89413498266Sopenharmony_ci if(!forms) 89513498266Sopenharmony_ci value = (char *) va_arg(arg, long); 89613498266Sopenharmony_ci 89713498266Sopenharmony_ci break; 89813498266Sopenharmony_ci 89913498266Sopenharmony_ci case CURLFORM_CONTENTLEN: 90013498266Sopenharmony_ci lengthx = nargs; 90113498266Sopenharmony_ci 90213498266Sopenharmony_ci if(!forms) 90313498266Sopenharmony_ci value = (char *) va_arg(arg, curl_off_t); 90413498266Sopenharmony_ci 90513498266Sopenharmony_ci break; 90613498266Sopenharmony_ci 90713498266Sopenharmony_ci case CURLFORM_NAMELENGTH: 90813498266Sopenharmony_ci namelengthx = nargs; 90913498266Sopenharmony_ci 91013498266Sopenharmony_ci if(!forms) 91113498266Sopenharmony_ci value = (char *) va_arg(arg, long); 91213498266Sopenharmony_ci 91313498266Sopenharmony_ci break; 91413498266Sopenharmony_ci 91513498266Sopenharmony_ci case CURLFORM_BUFFERLENGTH: 91613498266Sopenharmony_ci if(!forms) 91713498266Sopenharmony_ci value = (char *) va_arg(arg, long); 91813498266Sopenharmony_ci 91913498266Sopenharmony_ci break; 92013498266Sopenharmony_ci 92113498266Sopenharmony_ci case CURLFORM_CONTENTHEADER: 92213498266Sopenharmony_ci if(!forms) 92313498266Sopenharmony_ci value = (char *) va_arg(arg, struct curl_slist *); 92413498266Sopenharmony_ci 92513498266Sopenharmony_ci break; 92613498266Sopenharmony_ci 92713498266Sopenharmony_ci case CURLFORM_STREAM: 92813498266Sopenharmony_ci if(!forms) 92913498266Sopenharmony_ci value = (char *) va_arg(arg, void *); 93013498266Sopenharmony_ci 93113498266Sopenharmony_ci break; 93213498266Sopenharmony_ci 93313498266Sopenharmony_ci case CURLFORM_CONTENTTYPE: 93413498266Sopenharmony_ci /* If a previous content has been encountered, convert it now. */ 93513498266Sopenharmony_ci 93613498266Sopenharmony_ci if(Curl_formadd_convert(lforms, contentx, lengthx, contentccsid) < 0) { 93713498266Sopenharmony_ci result = CURL_FORMADD_MEMORY; 93813498266Sopenharmony_ci break; 93913498266Sopenharmony_ci } 94013498266Sopenharmony_ci 94113498266Sopenharmony_ci contentx = -1; 94213498266Sopenharmony_ci lengthx = -1; 94313498266Sopenharmony_ci /* Fall into default. */ 94413498266Sopenharmony_ci 94513498266Sopenharmony_ci default: 94613498266Sopenharmony_ci /* Must be a convertible string. */ 94713498266Sopenharmony_ci 94813498266Sopenharmony_ci if(!Curl_is_formadd_string(option)) { 94913498266Sopenharmony_ci result = CURL_FORMADD_UNKNOWN_OPTION; 95013498266Sopenharmony_ci break; 95113498266Sopenharmony_ci } 95213498266Sopenharmony_ci 95313498266Sopenharmony_ci if(!forms) { 95413498266Sopenharmony_ci value = va_arg(arg, char *); 95513498266Sopenharmony_ci ccsid = (unsigned int) va_arg(arg, long); 95613498266Sopenharmony_ci } 95713498266Sopenharmony_ci else { 95813498266Sopenharmony_ci ccsid = (unsigned int) forms->value; 95913498266Sopenharmony_ci forms++; 96013498266Sopenharmony_ci } 96113498266Sopenharmony_ci 96213498266Sopenharmony_ci /* Do the conversion. */ 96313498266Sopenharmony_ci 96413498266Sopenharmony_ci lforms[nargs].value = value; 96513498266Sopenharmony_ci 96613498266Sopenharmony_ci if(Curl_formadd_convert(lforms, nargs, -1, ccsid) < 0) { 96713498266Sopenharmony_ci result = CURL_FORMADD_MEMORY; 96813498266Sopenharmony_ci break; 96913498266Sopenharmony_ci } 97013498266Sopenharmony_ci 97113498266Sopenharmony_ci value = lforms[nargs].value; 97213498266Sopenharmony_ci } 97313498266Sopenharmony_ci 97413498266Sopenharmony_ci if(result != CURL_FORMADD_OK) 97513498266Sopenharmony_ci break; 97613498266Sopenharmony_ci 97713498266Sopenharmony_ci lforms[nargs].value = value; 97813498266Sopenharmony_ci lforms[nargs++].option = option; 97913498266Sopenharmony_ci } 98013498266Sopenharmony_ci 98113498266Sopenharmony_ci va_end(arg); 98213498266Sopenharmony_ci 98313498266Sopenharmony_ci /* Convert the name and the last content, now that we know their lengths. */ 98413498266Sopenharmony_ci 98513498266Sopenharmony_ci if(result == CURL_FORMADD_OK && namex >= 0) { 98613498266Sopenharmony_ci if(Curl_formadd_convert(lforms, namex, namelengthx, nameccsid) < 0) 98713498266Sopenharmony_ci result = CURL_FORMADD_MEMORY; 98813498266Sopenharmony_ci else 98913498266Sopenharmony_ci lforms[namex].option = CURLFORM_COPYNAME; /* Force copy. */ 99013498266Sopenharmony_ci } 99113498266Sopenharmony_ci 99213498266Sopenharmony_ci if(result == CURL_FORMADD_OK) { 99313498266Sopenharmony_ci if(Curl_formadd_convert(lforms, contentx, lengthx, contentccsid) < 0) 99413498266Sopenharmony_ci result = CURL_FORMADD_MEMORY; 99513498266Sopenharmony_ci else 99613498266Sopenharmony_ci contentx = -1; 99713498266Sopenharmony_ci } 99813498266Sopenharmony_ci 99913498266Sopenharmony_ci /* Do the formadd with our converted parameters. */ 100013498266Sopenharmony_ci 100113498266Sopenharmony_ci if(result == CURL_FORMADD_OK) { 100213498266Sopenharmony_ci lforms[nargs].option = CURLFORM_END; 100313498266Sopenharmony_ci result = curl_formadd(httppost, last_post, 100413498266Sopenharmony_ci CURLFORM_ARRAY, lforms, CURLFORM_END); 100513498266Sopenharmony_ci } 100613498266Sopenharmony_ci 100713498266Sopenharmony_ci /* Terminate. */ 100813498266Sopenharmony_ci 100913498266Sopenharmony_ci Curl_formadd_release_local(lforms, nargs, contentx); 101013498266Sopenharmony_ci return result; 101113498266Sopenharmony_ci} 101213498266Sopenharmony_ci 101313498266Sopenharmony_ci 101413498266Sopenharmony_cistruct cfcdata { 101513498266Sopenharmony_ci curl_formget_callback append; 101613498266Sopenharmony_ci void * arg; 101713498266Sopenharmony_ci unsigned int ccsid; 101813498266Sopenharmony_ci}; 101913498266Sopenharmony_ci 102013498266Sopenharmony_ci 102113498266Sopenharmony_cistatic size_t 102213498266Sopenharmony_ciCurl_formget_callback_ccsid(void *arg, const char *buf, size_t len) 102313498266Sopenharmony_ci{ 102413498266Sopenharmony_ci struct cfcdata *p; 102513498266Sopenharmony_ci char *b; 102613498266Sopenharmony_ci int l; 102713498266Sopenharmony_ci size_t ret; 102813498266Sopenharmony_ci 102913498266Sopenharmony_ci p = (struct cfcdata *) arg; 103013498266Sopenharmony_ci 103113498266Sopenharmony_ci if((long) len <= 0) 103213498266Sopenharmony_ci return (*p->append)(p->arg, buf, len); 103313498266Sopenharmony_ci 103413498266Sopenharmony_ci b = malloc(MAX_CONV_EXPANSION * len); 103513498266Sopenharmony_ci 103613498266Sopenharmony_ci if(!b) 103713498266Sopenharmony_ci return (size_t) -1; 103813498266Sopenharmony_ci 103913498266Sopenharmony_ci l = convert(b, MAX_CONV_EXPANSION * len, p->ccsid, buf, len, ASCII_CCSID); 104013498266Sopenharmony_ci 104113498266Sopenharmony_ci if(l < 0) { 104213498266Sopenharmony_ci free(b); 104313498266Sopenharmony_ci return (size_t) -1; 104413498266Sopenharmony_ci } 104513498266Sopenharmony_ci 104613498266Sopenharmony_ci ret = (*p->append)(p->arg, b, l); 104713498266Sopenharmony_ci free(b); 104813498266Sopenharmony_ci return ret == l? len: -1; 104913498266Sopenharmony_ci} 105013498266Sopenharmony_ci 105113498266Sopenharmony_ci 105213498266Sopenharmony_ciint 105313498266Sopenharmony_cicurl_formget_ccsid(struct curl_httppost *form, void *arg, 105413498266Sopenharmony_ci curl_formget_callback append, unsigned int ccsid) 105513498266Sopenharmony_ci{ 105613498266Sopenharmony_ci struct cfcdata lcfc; 105713498266Sopenharmony_ci 105813498266Sopenharmony_ci lcfc.append = append; 105913498266Sopenharmony_ci lcfc.arg = arg; 106013498266Sopenharmony_ci lcfc.ccsid = ccsid; 106113498266Sopenharmony_ci return curl_formget(form, (void *) &lcfc, Curl_formget_callback_ccsid); 106213498266Sopenharmony_ci} 106313498266Sopenharmony_ci 106413498266Sopenharmony_ci 106513498266Sopenharmony_ciCURLcode 106613498266Sopenharmony_cicurl_easy_setopt_ccsid(CURL *easy, CURLoption tag, ...) 106713498266Sopenharmony_ci{ 106813498266Sopenharmony_ci CURLcode result; 106913498266Sopenharmony_ci va_list arg; 107013498266Sopenharmony_ci char *s; 107113498266Sopenharmony_ci char *cp = NULL; 107213498266Sopenharmony_ci unsigned int ccsid; 107313498266Sopenharmony_ci curl_off_t pfsize; 107413498266Sopenharmony_ci 107513498266Sopenharmony_ci va_start(arg, tag); 107613498266Sopenharmony_ci 107713498266Sopenharmony_ci switch(tag) { 107813498266Sopenharmony_ci 107913498266Sopenharmony_ci /* BEGIN TRANSLATABLE STRING OPTIONS */ 108013498266Sopenharmony_ci /* Keep option symbols in alphanumeric order and retain the BEGIN/END 108113498266Sopenharmony_ci armor comments. */ 108213498266Sopenharmony_ci case CURLOPT_ABSTRACT_UNIX_SOCKET: 108313498266Sopenharmony_ci case CURLOPT_ACCEPT_ENCODING: 108413498266Sopenharmony_ci case CURLOPT_ALTSVC: 108513498266Sopenharmony_ci case CURLOPT_AWS_SIGV4: 108613498266Sopenharmony_ci case CURLOPT_CAINFO: 108713498266Sopenharmony_ci case CURLOPT_CAPATH: 108813498266Sopenharmony_ci case CURLOPT_COOKIE: 108913498266Sopenharmony_ci case CURLOPT_COOKIEFILE: 109013498266Sopenharmony_ci case CURLOPT_COOKIEJAR: 109113498266Sopenharmony_ci case CURLOPT_COOKIELIST: 109213498266Sopenharmony_ci case CURLOPT_CRLFILE: 109313498266Sopenharmony_ci case CURLOPT_CUSTOMREQUEST: 109413498266Sopenharmony_ci case CURLOPT_DEFAULT_PROTOCOL: 109513498266Sopenharmony_ci case CURLOPT_DNS_INTERFACE: 109613498266Sopenharmony_ci case CURLOPT_DNS_LOCAL_IP4: 109713498266Sopenharmony_ci case CURLOPT_DNS_LOCAL_IP6: 109813498266Sopenharmony_ci case CURLOPT_DNS_SERVERS: 109913498266Sopenharmony_ci case CURLOPT_DOH_URL: 110013498266Sopenharmony_ci case CURLOPT_EGDSOCKET: 110113498266Sopenharmony_ci case CURLOPT_FTPPORT: 110213498266Sopenharmony_ci case CURLOPT_FTP_ACCOUNT: 110313498266Sopenharmony_ci case CURLOPT_FTP_ALTERNATIVE_TO_USER: 110413498266Sopenharmony_ci case CURLOPT_HAPROXY_CLIENT_IP: 110513498266Sopenharmony_ci case CURLOPT_HSTS: 110613498266Sopenharmony_ci case CURLOPT_INTERFACE: 110713498266Sopenharmony_ci case CURLOPT_ISSUERCERT: 110813498266Sopenharmony_ci case CURLOPT_KEYPASSWD: 110913498266Sopenharmony_ci case CURLOPT_KRBLEVEL: 111013498266Sopenharmony_ci case CURLOPT_LOGIN_OPTIONS: 111113498266Sopenharmony_ci case CURLOPT_MAIL_AUTH: 111213498266Sopenharmony_ci case CURLOPT_MAIL_FROM: 111313498266Sopenharmony_ci case CURLOPT_NETRC_FILE: 111413498266Sopenharmony_ci case CURLOPT_NOPROXY: 111513498266Sopenharmony_ci case CURLOPT_PASSWORD: 111613498266Sopenharmony_ci case CURLOPT_PINNEDPUBLICKEY: 111713498266Sopenharmony_ci case CURLOPT_PRE_PROXY: 111813498266Sopenharmony_ci case CURLOPT_PROTOCOLS_STR: 111913498266Sopenharmony_ci case CURLOPT_PROXY: 112013498266Sopenharmony_ci case CURLOPT_PROXYPASSWORD: 112113498266Sopenharmony_ci case CURLOPT_PROXYUSERNAME: 112213498266Sopenharmony_ci case CURLOPT_PROXYUSERPWD: 112313498266Sopenharmony_ci case CURLOPT_PROXY_CAINFO: 112413498266Sopenharmony_ci case CURLOPT_PROXY_CAPATH: 112513498266Sopenharmony_ci case CURLOPT_PROXY_CRLFILE: 112613498266Sopenharmony_ci case CURLOPT_PROXY_ISSUERCERT: 112713498266Sopenharmony_ci case CURLOPT_PROXY_KEYPASSWD: 112813498266Sopenharmony_ci case CURLOPT_PROXY_PINNEDPUBLICKEY: 112913498266Sopenharmony_ci case CURLOPT_PROXY_SERVICE_NAME: 113013498266Sopenharmony_ci case CURLOPT_PROXY_SSLCERT: 113113498266Sopenharmony_ci case CURLOPT_PROXY_SSLCERTTYPE: 113213498266Sopenharmony_ci case CURLOPT_PROXY_SSLKEY: 113313498266Sopenharmony_ci case CURLOPT_PROXY_SSLKEYTYPE: 113413498266Sopenharmony_ci case CURLOPT_PROXY_SSL_CIPHER_LIST: 113513498266Sopenharmony_ci case CURLOPT_PROXY_TLS13_CIPHERS: 113613498266Sopenharmony_ci case CURLOPT_PROXY_TLSAUTH_PASSWORD: 113713498266Sopenharmony_ci case CURLOPT_PROXY_TLSAUTH_TYPE: 113813498266Sopenharmony_ci case CURLOPT_PROXY_TLSAUTH_USERNAME: 113913498266Sopenharmony_ci case CURLOPT_RANDOM_FILE: 114013498266Sopenharmony_ci case CURLOPT_RANGE: 114113498266Sopenharmony_ci case CURLOPT_REDIR_PROTOCOLS_STR: 114213498266Sopenharmony_ci case CURLOPT_REFERER: 114313498266Sopenharmony_ci case CURLOPT_REQUEST_TARGET: 114413498266Sopenharmony_ci case CURLOPT_RTSP_SESSION_ID: 114513498266Sopenharmony_ci case CURLOPT_RTSP_STREAM_URI: 114613498266Sopenharmony_ci case CURLOPT_RTSP_TRANSPORT: 114713498266Sopenharmony_ci case CURLOPT_SASL_AUTHZID: 114813498266Sopenharmony_ci case CURLOPT_SERVICE_NAME: 114913498266Sopenharmony_ci case CURLOPT_SOCKS5_GSSAPI_SERVICE: 115013498266Sopenharmony_ci case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5: 115113498266Sopenharmony_ci case CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256: 115213498266Sopenharmony_ci case CURLOPT_SSH_KNOWNHOSTS: 115313498266Sopenharmony_ci case CURLOPT_SSH_PRIVATE_KEYFILE: 115413498266Sopenharmony_ci case CURLOPT_SSH_PUBLIC_KEYFILE: 115513498266Sopenharmony_ci case CURLOPT_SSLCERT: 115613498266Sopenharmony_ci case CURLOPT_SSLCERTTYPE: 115713498266Sopenharmony_ci case CURLOPT_SSLENGINE: 115813498266Sopenharmony_ci case CURLOPT_SSLKEY: 115913498266Sopenharmony_ci case CURLOPT_SSLKEYTYPE: 116013498266Sopenharmony_ci case CURLOPT_SSL_CIPHER_LIST: 116113498266Sopenharmony_ci case CURLOPT_SSL_EC_CURVES: 116213498266Sopenharmony_ci case CURLOPT_TLS13_CIPHERS: 116313498266Sopenharmony_ci case CURLOPT_TLSAUTH_PASSWORD: 116413498266Sopenharmony_ci case CURLOPT_TLSAUTH_TYPE: 116513498266Sopenharmony_ci case CURLOPT_TLSAUTH_USERNAME: 116613498266Sopenharmony_ci case CURLOPT_UNIX_SOCKET_PATH: 116713498266Sopenharmony_ci case CURLOPT_URL: 116813498266Sopenharmony_ci case CURLOPT_USERAGENT: 116913498266Sopenharmony_ci case CURLOPT_USERNAME: 117013498266Sopenharmony_ci case CURLOPT_USERPWD: 117113498266Sopenharmony_ci case CURLOPT_XOAUTH2_BEARER: 117213498266Sopenharmony_ci /* END TRANSLATABLE STRING OPTIONS */ 117313498266Sopenharmony_ci s = va_arg(arg, char *); 117413498266Sopenharmony_ci ccsid = va_arg(arg, unsigned int); 117513498266Sopenharmony_ci 117613498266Sopenharmony_ci if(s) { 117713498266Sopenharmony_ci s = dynconvert(ASCII_CCSID, s, -1, ccsid); 117813498266Sopenharmony_ci 117913498266Sopenharmony_ci if(!s) { 118013498266Sopenharmony_ci result = CURLE_OUT_OF_MEMORY; 118113498266Sopenharmony_ci break; 118213498266Sopenharmony_ci } 118313498266Sopenharmony_ci } 118413498266Sopenharmony_ci 118513498266Sopenharmony_ci result = curl_easy_setopt(easy, tag, s); 118613498266Sopenharmony_ci free(s); 118713498266Sopenharmony_ci break; 118813498266Sopenharmony_ci 118913498266Sopenharmony_ci case CURLOPT_COPYPOSTFIELDS: 119013498266Sopenharmony_ci /* Special case: byte count may have been given by CURLOPT_POSTFIELDSIZE 119113498266Sopenharmony_ci prior to this call. In this case, convert the given byte count and 119213498266Sopenharmony_ci replace the length according to the conversion result. */ 119313498266Sopenharmony_ci s = va_arg(arg, char *); 119413498266Sopenharmony_ci ccsid = va_arg(arg, unsigned int); 119513498266Sopenharmony_ci 119613498266Sopenharmony_ci pfsize = easy->set.postfieldsize; 119713498266Sopenharmony_ci 119813498266Sopenharmony_ci if(!s || !pfsize || ccsid == NOCONV_CCSID || ccsid == ASCII_CCSID) { 119913498266Sopenharmony_ci result = curl_easy_setopt(easy, CURLOPT_COPYPOSTFIELDS, s); 120013498266Sopenharmony_ci break; 120113498266Sopenharmony_ci } 120213498266Sopenharmony_ci 120313498266Sopenharmony_ci if(pfsize == -1) { 120413498266Sopenharmony_ci /* Data is null-terminated. */ 120513498266Sopenharmony_ci s = dynconvert(ASCII_CCSID, s, -1, ccsid); 120613498266Sopenharmony_ci 120713498266Sopenharmony_ci if(!s) { 120813498266Sopenharmony_ci result = CURLE_OUT_OF_MEMORY; 120913498266Sopenharmony_ci break; 121013498266Sopenharmony_ci } 121113498266Sopenharmony_ci } 121213498266Sopenharmony_ci else { 121313498266Sopenharmony_ci /* Data length specified. */ 121413498266Sopenharmony_ci size_t len; 121513498266Sopenharmony_ci 121613498266Sopenharmony_ci if(pfsize < 0 || pfsize > SIZE_MAX) { 121713498266Sopenharmony_ci result = CURLE_OUT_OF_MEMORY; 121813498266Sopenharmony_ci break; 121913498266Sopenharmony_ci } 122013498266Sopenharmony_ci 122113498266Sopenharmony_ci len = pfsize; 122213498266Sopenharmony_ci pfsize = len * MAX_CONV_EXPANSION; 122313498266Sopenharmony_ci 122413498266Sopenharmony_ci if(pfsize > SIZE_MAX) 122513498266Sopenharmony_ci pfsize = SIZE_MAX; 122613498266Sopenharmony_ci 122713498266Sopenharmony_ci cp = malloc(pfsize); 122813498266Sopenharmony_ci 122913498266Sopenharmony_ci if(!cp) { 123013498266Sopenharmony_ci result = CURLE_OUT_OF_MEMORY; 123113498266Sopenharmony_ci break; 123213498266Sopenharmony_ci } 123313498266Sopenharmony_ci 123413498266Sopenharmony_ci pfsize = convert(cp, pfsize, ASCII_CCSID, s, len, ccsid); 123513498266Sopenharmony_ci 123613498266Sopenharmony_ci if(pfsize < 0) { 123713498266Sopenharmony_ci result = CURLE_OUT_OF_MEMORY; 123813498266Sopenharmony_ci break; 123913498266Sopenharmony_ci } 124013498266Sopenharmony_ci 124113498266Sopenharmony_ci easy->set.postfieldsize = pfsize; /* Replace data size. */ 124213498266Sopenharmony_ci s = cp; 124313498266Sopenharmony_ci } 124413498266Sopenharmony_ci 124513498266Sopenharmony_ci result = curl_easy_setopt(easy, CURLOPT_POSTFIELDS, s); 124613498266Sopenharmony_ci easy->set.str[STRING_COPYPOSTFIELDS] = s; /* Give to library. */ 124713498266Sopenharmony_ci break; 124813498266Sopenharmony_ci 124913498266Sopenharmony_ci default: 125013498266Sopenharmony_ci if(tag / 10000 == CURLOPTTYPE_BLOB) { 125113498266Sopenharmony_ci struct curl_blob *bp = va_arg(arg, struct curl_blob *); 125213498266Sopenharmony_ci struct curl_blob blob; 125313498266Sopenharmony_ci 125413498266Sopenharmony_ci ccsid = va_arg(arg, unsigned int); 125513498266Sopenharmony_ci 125613498266Sopenharmony_ci if(bp && bp->data && bp->len && 125713498266Sopenharmony_ci ccsid != NOCONV_CCSID && ccsid != ASCII_CCSID) { 125813498266Sopenharmony_ci pfsize = (curl_off_t) bp->len * MAX_CONV_EXPANSION; 125913498266Sopenharmony_ci 126013498266Sopenharmony_ci if(pfsize > SIZE_MAX) 126113498266Sopenharmony_ci pfsize = SIZE_MAX; 126213498266Sopenharmony_ci 126313498266Sopenharmony_ci cp = malloc(pfsize); 126413498266Sopenharmony_ci 126513498266Sopenharmony_ci if(!cp) { 126613498266Sopenharmony_ci result = CURLE_OUT_OF_MEMORY; 126713498266Sopenharmony_ci break; 126813498266Sopenharmony_ci } 126913498266Sopenharmony_ci 127013498266Sopenharmony_ci pfsize = convert(cp, pfsize, ASCII_CCSID, bp->data, bp->len, ccsid); 127113498266Sopenharmony_ci 127213498266Sopenharmony_ci if(pfsize < 0) { 127313498266Sopenharmony_ci result = CURLE_OUT_OF_MEMORY; 127413498266Sopenharmony_ci break; 127513498266Sopenharmony_ci } 127613498266Sopenharmony_ci 127713498266Sopenharmony_ci blob.data = cp; 127813498266Sopenharmony_ci blob.len = pfsize; 127913498266Sopenharmony_ci blob.flags = bp->flags | CURL_BLOB_COPY; 128013498266Sopenharmony_ci bp = &blob; 128113498266Sopenharmony_ci } 128213498266Sopenharmony_ci result = curl_easy_setopt(easy, tag, &blob); 128313498266Sopenharmony_ci break; 128413498266Sopenharmony_ci } 128513498266Sopenharmony_ci FALLTHROUGH(); 128613498266Sopenharmony_ci case CURLOPT_ERRORBUFFER: /* This is an output buffer. */ 128713498266Sopenharmony_ci result = Curl_vsetopt(easy, tag, arg); 128813498266Sopenharmony_ci break; 128913498266Sopenharmony_ci } 129013498266Sopenharmony_ci 129113498266Sopenharmony_ci va_end(arg); 129213498266Sopenharmony_ci free(cp); 129313498266Sopenharmony_ci return result; 129413498266Sopenharmony_ci} 129513498266Sopenharmony_ci 129613498266Sopenharmony_ci 129713498266Sopenharmony_ci/* ILE/RPG helper functions. */ 129813498266Sopenharmony_ci 129913498266Sopenharmony_cichar * 130013498266Sopenharmony_cicurl_form_long_value(long value) 130113498266Sopenharmony_ci{ 130213498266Sopenharmony_ci /* ILE/RPG cannot cast an integer to a pointer. This procedure does it. */ 130313498266Sopenharmony_ci 130413498266Sopenharmony_ci return (char *) value; 130513498266Sopenharmony_ci} 130613498266Sopenharmony_ci 130713498266Sopenharmony_ci 130813498266Sopenharmony_ciCURLcode 130913498266Sopenharmony_cicurl_easy_setopt_RPGnum_(CURL *easy, CURLoption tag, curl_off_t arg) 131013498266Sopenharmony_ci{ 131113498266Sopenharmony_ci /* ILE/RPG procedure overloading cannot discriminate between different 131213498266Sopenharmony_ci size and/or signedness of format arguments. This provides a generic 131313498266Sopenharmony_ci wrapper that adapts size to the given tag expectation. 131413498266Sopenharmony_ci This procedure is not intended to be explicitly called from user code. */ 131513498266Sopenharmony_ci if(tag / 10000 != CURLOPTTYPE_OFF_T) 131613498266Sopenharmony_ci return curl_easy_setopt(easy, tag, (long) arg); 131713498266Sopenharmony_ci return curl_easy_setopt(easy, tag, arg); 131813498266Sopenharmony_ci} 131913498266Sopenharmony_ci 132013498266Sopenharmony_ci 132113498266Sopenharmony_ciCURLcode 132213498266Sopenharmony_cicurl_multi_setopt_RPGnum_(CURLM *multi, CURLMoption tag, curl_off_t arg) 132313498266Sopenharmony_ci{ 132413498266Sopenharmony_ci /* Likewise, for multi handle. */ 132513498266Sopenharmony_ci if(tag / 10000 != CURLOPTTYPE_OFF_T) 132613498266Sopenharmony_ci return curl_multi_setopt(multi, tag, (long) arg); 132713498266Sopenharmony_ci return curl_multi_setopt(multi, tag, arg); 132813498266Sopenharmony_ci} 132913498266Sopenharmony_ci 133013498266Sopenharmony_ci 133113498266Sopenharmony_cichar * 133213498266Sopenharmony_cicurl_pushheader_bynum_cssid(struct curl_pushheaders *h, 133313498266Sopenharmony_ci size_t num, unsigned int ccsid) 133413498266Sopenharmony_ci{ 133513498266Sopenharmony_ci char *d = (char *) NULL; 133613498266Sopenharmony_ci char *s = curl_pushheader_bynum(h, num); 133713498266Sopenharmony_ci 133813498266Sopenharmony_ci if(s) 133913498266Sopenharmony_ci d = dynconvert(ccsid, s, -1, ASCII_CCSID); 134013498266Sopenharmony_ci 134113498266Sopenharmony_ci return d; 134213498266Sopenharmony_ci} 134313498266Sopenharmony_ci 134413498266Sopenharmony_ci 134513498266Sopenharmony_cichar * 134613498266Sopenharmony_cicurl_pushheader_byname_ccsid(struct curl_pushheaders *h, const char *header, 134713498266Sopenharmony_ci unsigned int ccsidin, unsigned int ccsidout) 134813498266Sopenharmony_ci{ 134913498266Sopenharmony_ci char *d = (char *) NULL; 135013498266Sopenharmony_ci 135113498266Sopenharmony_ci if(header) { 135213498266Sopenharmony_ci header = dynconvert(ASCII_CCSID, header, -1, ccsidin); 135313498266Sopenharmony_ci 135413498266Sopenharmony_ci if(header) { 135513498266Sopenharmony_ci char *s = curl_pushheader_byname(h, header); 135613498266Sopenharmony_ci free((char *) header); 135713498266Sopenharmony_ci 135813498266Sopenharmony_ci if(s) 135913498266Sopenharmony_ci d = dynconvert(ccsidout, s, -1, ASCII_CCSID); 136013498266Sopenharmony_ci } 136113498266Sopenharmony_ci } 136213498266Sopenharmony_ci 136313498266Sopenharmony_ci return d; 136413498266Sopenharmony_ci} 136513498266Sopenharmony_ci 136613498266Sopenharmony_cistatic CURLcode 136713498266Sopenharmony_cimime_string_call(curl_mimepart *part, const char *string, unsigned int ccsid, 136813498266Sopenharmony_ci CURLcode (*mimefunc)(curl_mimepart *part, const char *string)) 136913498266Sopenharmony_ci{ 137013498266Sopenharmony_ci char *s = (char *) NULL; 137113498266Sopenharmony_ci CURLcode result; 137213498266Sopenharmony_ci 137313498266Sopenharmony_ci if(!string) 137413498266Sopenharmony_ci return mimefunc(part, string); 137513498266Sopenharmony_ci s = dynconvert(ASCII_CCSID, string, -1, ccsid); 137613498266Sopenharmony_ci if(!s) 137713498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 137813498266Sopenharmony_ci 137913498266Sopenharmony_ci result = mimefunc(part, s); 138013498266Sopenharmony_ci free(s); 138113498266Sopenharmony_ci return result; 138213498266Sopenharmony_ci} 138313498266Sopenharmony_ci 138413498266Sopenharmony_ciCURLcode 138513498266Sopenharmony_cicurl_mime_name_ccsid(curl_mimepart *part, const char *name, unsigned int ccsid) 138613498266Sopenharmony_ci{ 138713498266Sopenharmony_ci return mime_string_call(part, name, ccsid, curl_mime_name); 138813498266Sopenharmony_ci} 138913498266Sopenharmony_ci 139013498266Sopenharmony_ciCURLcode 139113498266Sopenharmony_cicurl_mime_filename_ccsid(curl_mimepart *part, 139213498266Sopenharmony_ci const char *filename, unsigned int ccsid) 139313498266Sopenharmony_ci{ 139413498266Sopenharmony_ci return mime_string_call(part, filename, ccsid, curl_mime_filename); 139513498266Sopenharmony_ci} 139613498266Sopenharmony_ci 139713498266Sopenharmony_ciCURLcode 139813498266Sopenharmony_cicurl_mime_type_ccsid(curl_mimepart *part, 139913498266Sopenharmony_ci const char *mimetype, unsigned int ccsid) 140013498266Sopenharmony_ci{ 140113498266Sopenharmony_ci return mime_string_call(part, mimetype, ccsid, curl_mime_type); 140213498266Sopenharmony_ci} 140313498266Sopenharmony_ci 140413498266Sopenharmony_ciCURLcode 140513498266Sopenharmony_cicurl_mime_encoder_ccsid(curl_mimepart *part, 140613498266Sopenharmony_ci const char *encoding, unsigned int ccsid) 140713498266Sopenharmony_ci{ 140813498266Sopenharmony_ci return mime_string_call(part, encoding, ccsid, curl_mime_encoder); 140913498266Sopenharmony_ci} 141013498266Sopenharmony_ci 141113498266Sopenharmony_ciCURLcode 141213498266Sopenharmony_cicurl_mime_filedata_ccsid(curl_mimepart *part, 141313498266Sopenharmony_ci const char *filename, unsigned int ccsid) 141413498266Sopenharmony_ci{ 141513498266Sopenharmony_ci return mime_string_call(part, filename, ccsid, curl_mime_filedata); 141613498266Sopenharmony_ci} 141713498266Sopenharmony_ci 141813498266Sopenharmony_ciCURLcode 141913498266Sopenharmony_cicurl_mime_data_ccsid(curl_mimepart *part, 142013498266Sopenharmony_ci const char *data, size_t datasize, unsigned int ccsid) 142113498266Sopenharmony_ci{ 142213498266Sopenharmony_ci char *s = (char *) NULL; 142313498266Sopenharmony_ci CURLcode result; 142413498266Sopenharmony_ci 142513498266Sopenharmony_ci if(!data) 142613498266Sopenharmony_ci return curl_mime_data(part, data, datasize); 142713498266Sopenharmony_ci s = dynconvert(ASCII_CCSID, data, datasize, ccsid); 142813498266Sopenharmony_ci if(!s) 142913498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 143013498266Sopenharmony_ci 143113498266Sopenharmony_ci result = curl_mime_data(part, s, datasize); 143213498266Sopenharmony_ci free(s); 143313498266Sopenharmony_ci return result; 143413498266Sopenharmony_ci} 143513498266Sopenharmony_ci 143613498266Sopenharmony_ciCURLUcode 143713498266Sopenharmony_cicurl_url_get_ccsid(CURLU *handle, CURLUPart what, char **part, 143813498266Sopenharmony_ci unsigned int flags, unsigned int ccsid) 143913498266Sopenharmony_ci{ 144013498266Sopenharmony_ci char *s = (char *)NULL; 144113498266Sopenharmony_ci CURLUcode result; 144213498266Sopenharmony_ci 144313498266Sopenharmony_ci if(!part) 144413498266Sopenharmony_ci return CURLUE_BAD_PARTPOINTER; 144513498266Sopenharmony_ci 144613498266Sopenharmony_ci *part = (char *)NULL; 144713498266Sopenharmony_ci result = curl_url_get(handle, what, &s, flags); 144813498266Sopenharmony_ci if(result == CURLUE_OK) { 144913498266Sopenharmony_ci if(s) { 145013498266Sopenharmony_ci *part = dynconvert(ccsid, s, -1, ASCII_CCSID); 145113498266Sopenharmony_ci if(!*part) 145213498266Sopenharmony_ci result = CURLUE_OUT_OF_MEMORY; 145313498266Sopenharmony_ci } 145413498266Sopenharmony_ci } 145513498266Sopenharmony_ci if(s) 145613498266Sopenharmony_ci free(s); 145713498266Sopenharmony_ci return result; 145813498266Sopenharmony_ci} 145913498266Sopenharmony_ci 146013498266Sopenharmony_ciCURLUcode 146113498266Sopenharmony_cicurl_url_set_ccsid(CURLU *handle, CURLUPart what, const char *part, 146213498266Sopenharmony_ci unsigned int flags, unsigned int ccsid) 146313498266Sopenharmony_ci{ 146413498266Sopenharmony_ci char *s = (char *)NULL; 146513498266Sopenharmony_ci CURLUcode result; 146613498266Sopenharmony_ci 146713498266Sopenharmony_ci if(part) { 146813498266Sopenharmony_ci s = dynconvert(ASCII_CCSID, part, -1, ccsid); 146913498266Sopenharmony_ci if(!s) 147013498266Sopenharmony_ci return CURLUE_OUT_OF_MEMORY; 147113498266Sopenharmony_ci } 147213498266Sopenharmony_ci result = curl_url_set(handle, what, s, flags); 147313498266Sopenharmony_ci if(s) 147413498266Sopenharmony_ci free(s); 147513498266Sopenharmony_ci return result; 147613498266Sopenharmony_ci} 147713498266Sopenharmony_ci 147813498266Sopenharmony_ciconst struct curl_easyoption * 147913498266Sopenharmony_cicurl_easy_option_by_name_ccsid(const char *name, unsigned int ccsid) 148013498266Sopenharmony_ci{ 148113498266Sopenharmony_ci const struct curl_easyoption *option = NULL; 148213498266Sopenharmony_ci 148313498266Sopenharmony_ci if(name) { 148413498266Sopenharmony_ci char *s = dynconvert(ASCII_CCSID, name, -1, ccsid); 148513498266Sopenharmony_ci 148613498266Sopenharmony_ci if(s) { 148713498266Sopenharmony_ci option = curl_easy_option_by_name(s); 148813498266Sopenharmony_ci free(s); 148913498266Sopenharmony_ci } 149013498266Sopenharmony_ci } 149113498266Sopenharmony_ci 149213498266Sopenharmony_ci return option; 149313498266Sopenharmony_ci} 149413498266Sopenharmony_ci 149513498266Sopenharmony_ci/* Return option name in the given ccsid. */ 149613498266Sopenharmony_ciconst char * 149713498266Sopenharmony_cicurl_easy_option_get_name_ccsid(const struct curl_easyoption *option, 149813498266Sopenharmony_ci unsigned int ccsid) 149913498266Sopenharmony_ci{ 150013498266Sopenharmony_ci char *name = NULL; 150113498266Sopenharmony_ci 150213498266Sopenharmony_ci if(option && option->name) 150313498266Sopenharmony_ci name = dynconvert(ccsid, option->name, -1, ASCII_CCSID); 150413498266Sopenharmony_ci 150513498266Sopenharmony_ci return (const char *) name; 150613498266Sopenharmony_ci} 150713498266Sopenharmony_ci 150813498266Sopenharmony_ci/* Header API CCSID support. */ 150913498266Sopenharmony_ciCURLHcode 151013498266Sopenharmony_cicurl_easy_header_ccsid(CURL *easy, const char *name, size_t index, 151113498266Sopenharmony_ci unsigned int origin, int request, 151213498266Sopenharmony_ci struct curl_header **hout, unsigned int ccsid) 151313498266Sopenharmony_ci{ 151413498266Sopenharmony_ci CURLHcode result = CURLHE_BAD_ARGUMENT; 151513498266Sopenharmony_ci 151613498266Sopenharmony_ci if(name) { 151713498266Sopenharmony_ci char *s = dynconvert(ASCII_CCSID, name, -1, ccsid); 151813498266Sopenharmony_ci 151913498266Sopenharmony_ci result = CURLHE_OUT_OF_MEMORY; 152013498266Sopenharmony_ci if(s) { 152113498266Sopenharmony_ci result = curl_easy_header(easy, s, index, origin, request, hout); 152213498266Sopenharmony_ci free(s); 152313498266Sopenharmony_ci } 152413498266Sopenharmony_ci } 152513498266Sopenharmony_ci 152613498266Sopenharmony_ci return result; 152713498266Sopenharmony_ci} 1528