From a2a8f9d7300f3a3773cb046005e0ecbc9a7080db Mon Sep 17 00:00:00 2001 From: Patrick Monnerat Date: Sun, 11 Apr 2021 19:33:09 +0200 Subject: [PATCH] os400: additional support for options metadata New functions curl_easy_option_by_name_ccsid() and curl_easy_option_get_name_ccsid() allows accessing metadata in alternate character encoding. This commit also updates curl_version_info_ccsid() to handle info version 9 and adds recent definitions to the ILE/RPG include file. Documentation updated accordingly. Reviewed-by: Jon Rumsey Closes #6574 --- packages/OS400/README.OS400 | 22 +++- packages/OS400/ccsidcurl.c | 114 ++++++++++------- packages/OS400/ccsidcurl.h | 7 +- packages/OS400/curl.inc.in | 246 ++++++++++++++++++++++++++++++++++-- 4 files changed, 321 insertions(+), 68 deletions(-) diff --git a/packages/OS400/README.OS400 b/packages/OS400/README.OS400 index 6ea4ac29e..d3ad90177 100644 --- a/packages/OS400/README.OS400 +++ b/packages/OS400/README.OS400 @@ -27,8 +27,8 @@ some more of them, that are used by libcurl and that QADRT left out. To support all the different variants of EBCDIC, non-standard wrapper procedures have been added to libcurl on OS/400: they provide an additional CCSID (numeric Coded Character Set ID specific to OS/400) parameter for each -string argument. String values passed to callback procedures are NOT converted, -so text gathered this way is (probably !) ASCII. +string argument. Callback procedures arguments giving access to strings are +NOT converted, so text gathered this way is (probably !) ASCII. Another OS/400 problem comes from the fact that the last fixed argument of a vararg procedure may not be of type char, unsigned char, short or unsigned @@ -65,6 +65,7 @@ _ curl_easy_setopt_ccsid() options: CURLOPT_ABSTRACT_UNIX_SOCKET CURLOPT_ALTSVC + CURLOPT_AWS_SIGV4 CURLOPT_CAINFO CURLOPT_CAPATH CURLOPT_COOKIE @@ -82,6 +83,7 @@ options: CURLOPT_FTPPORT CURLOPT_FTP_ACCOUNT CURLOPT_FTP_ALTERNATIVE_TO_USER + CURLOPT_HSTS CURLOPT_INTERFACE CURLOPT_ISSUERCERT CURLOPT_KEYPASSWD @@ -172,8 +174,8 @@ unconvertible strings and thus are NOT followed by a CCSID. _ curl_easy_getinfo_ccsid() The following options are followed by a 'char * *' and a CCSID. Unlike -curl_easy_getinfo(), the value returned in the pointer should be freed after -use: +curl_easy_getinfo(), the value returned in the pointer should be released with +curl_free() after use: CURLINFO_EFFECTIVE_URL CURLINFO_CONTENT_TYPE CURLINFO_FTP_ENTRY_PATH @@ -189,17 +191,23 @@ CCSID. CURLINFO_COOKIELIST Lists returned should be released with curl_slist_free_all() after use. Option CURLINFO_CERTINFO is followed by a struct curl_certinfo * * and a -CCSID. Returned structures should be free'ed using curl_certinfo_free_all() +CCSID. Returned structures should be freed with curl_certinfo_free_all() after use. Other options are processed like in curl_easy_getinfo(). _ curl_pushheader_bynum_cssid() and curl_pushheader_byname_ccsid() Although the prototypes are self-explanatory, the returned string pointer -should be freed after use, as opposite to the non-ccsid versions of these -procedures. +should be released with curl_free() after use, as opposite to the non-ccsid +versions of these procedures. Please note that HTTP2 is not (yet) implemented on OS/400, thus these functions will always return NULL. +_ curl_easy_option_by_name_ccsid() returns a pointer to an untranslated option +metadata structure. As each curl_easyoption structure holds the option name in +ASCII, the curl_easy_option_get_name_ccsid() function allows getting it in any +supported ccsid. However the caller should release the returned pointer with +curl_free() after use. + Standard compilation environment does support neither autotools nor make; in fact, very few common utilities are available. As a consequence, the diff --git a/packages/OS400/ccsidcurl.c b/packages/OS400/ccsidcurl.c index 069481dae..8b515fb8f 100644 --- a/packages/OS400/ccsidcurl.c +++ b/packages/OS400/ccsidcurl.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -343,7 +344,7 @@ curl_slist_append_ccsid(struct curl_slist *list, time_t -curl_getdate_ccsid(const char *p, const time_t * unused, unsigned int ccsid) +curl_getdate_ccsid(const char *p, const time_t *unused, unsigned int ccsid) { char *s; time_t t; @@ -363,8 +364,8 @@ curl_getdate_ccsid(const char *p, const time_t * unused, unsigned int ccsid) static int -convert_version_info_string(const char * * stringp, - char * * bufp, int *left, unsigned int ccsid) +convert_version_info_string(const char **stringp, + char **bufp, int *left, unsigned int ccsid) { /* Helper for curl_version_info_ccsid(): convert a string if defined. Result is stored in the `*left'-byte buffer at `*bufp'. @@ -394,12 +395,30 @@ curl_version_info_ccsid(CURLversion stamp, unsigned int ccsid) int n; int nproto; curl_version_info_data *id; + int i; + const char *cpp; + static const size_t charfields[] = { + offsetof(curl_version_info_data, version), + offsetof(curl_version_info_data, host), + offsetof(curl_version_info_data, ssl_version), + offsetof(curl_version_info_data, libz_version), + offsetof(curl_version_info_data, ares), + offsetof(curl_version_info_data, libidn), + offsetof(curl_version_info_data, libssh_version), + offsetof(curl_version_info_data, brotli_version), + offsetof(curl_version_info_data, nghttp2_version), + offsetof(curl_version_info_data, quic_version), + offsetof(curl_version_info_data, cainfo), + offsetof(curl_version_info_data, capath), + offsetof(curl_version_info_data, zstd_version), + offsetof(curl_version_info_data, hyper_version) + }; /* The assertion below is possible, because although the second operand is an enum member, the first is a #define. In that case, the OS/400 C compiler seems to compare string values after substitution. */ -#if CURLVERSION_NOW != CURLVERSION_FOURTH +#if CURLVERSION_NOW != CURLVERSION_NINTH #error curl_version_info_data structure has changed: upgrade this procedure. #endif @@ -425,26 +444,11 @@ curl_version_info_ccsid(CURLversion stamp, unsigned int ccsid) n += nproto++; } - if(p->version) - n += strlen(p->version) + 1; - - if(p->host) - n += strlen(p->host) + 1; - - if(p->ssl_version) - n += strlen(p->ssl_version) + 1; - - if(p->libz_version) - n += strlen(p->libz_version) + 1; - - if(p->ares) - n += strlen(p->ares) + 1; - - if(p->libidn) - n += strlen(p->libidn) + 1; - - if(p->libssh_version) - n += strlen(p->libssh_version) + 1; + for(i = 0; i < sizeof(charfields) / sizeof(charfields[0]); i++) { + cpp = (const char **) ((char *) p + charfields[i]); + if(*cpp) + n += strlen(*cpp) + 1; + } /* Allocate thread space. */ @@ -476,28 +480,13 @@ curl_version_info_ccsid(CURLversion stamp, unsigned int ccsid) if(convert_version_info_string(((const char * *) id->protocols) + i, &cp, &n, ccsid)) return (curl_version_info_data *) NULL; - } + } - if(convert_version_info_string(&id->version, &cp, &n, ccsid)) - return (curl_version_info_data *) NULL; - - if(convert_version_info_string(&id->host, &cp, &n, ccsid)) - return (curl_version_info_data *) NULL; - - if(convert_version_info_string(&id->ssl_version, &cp, &n, ccsid)) - return (curl_version_info_data *) NULL; - - if(convert_version_info_string(&id->libz_version, &cp, &n, ccsid)) - return (curl_version_info_data *) NULL; - - if(convert_version_info_string(&id->ares, &cp, &n, ccsid)) - return (curl_version_info_data *) NULL; - - if(convert_version_info_string(&id->libidn, &cp, &n, ccsid)) - return (curl_version_info_data *) NULL; - - if(convert_version_info_string(&id->libssh_version, &cp, &n, ccsid)) - return (curl_version_info_data *) NULL; + for(i = 0; i < sizeof(charfields) / sizeof(charfields[0]); i++) { + cpp = (const char **) ((char *) p + charfields[i]); + if(*cpp) + if(convert_version_info_string(cpp, &cp, &n, ccsid)) + } return id; } @@ -771,8 +760,8 @@ Curl_formadd_convert(struct curl_forms *forms, CURLFORMcode -curl_formadd_ccsid(struct curl_httppost * * httppost, - struct curl_httppost * * last_post, ...) +curl_formadd_ccsid(struct curl_httppost **httppost, + struct curl_httppost **last_post, ...) { va_list arg; CURLformoption option; @@ -1132,6 +1121,7 @@ curl_easy_setopt_ccsid(CURL *curl, CURLoption tag, ...) case CURLOPT_FTPPORT: case CURLOPT_FTP_ACCOUNT: case CURLOPT_FTP_ALTERNATIVE_TO_USER: + case CURLOPT_HSTS: case CURLOPT_INTERFACE: case CURLOPT_ISSUERCERT: case CURLOPT_KEYPASSWD: @@ -1437,3 +1427,33 @@ curl_url_set_ccsid(CURLU *handle, CURLUPart what, const char *part, free(s); return result; } + +const struct curl_easyoption * +curl_easy_option_by_name_ccsid(const char *name, unsigned int ccsid) +{ + const struct curl_easyoption *option = NULL; + + if(name) { + char *s = dynconvert(ASCII_CCSID, name, -1, ccsid); + + if(s) { + option = curl_easy_option_by_name(s); + free(s); + } + } + + return option; +} + +/* Return option name in the given ccsid. */ +const char * +curl_easy_option_get_name_ccsid(const struct curl_easyoption *option, + unsigned int ccsid) +{ + char *name = NULL; + + if(option && option->name) + name = dynconvert(ccsid, option->name, -1, ASCII_CCSID); + + return (const char *) name; +} diff --git a/packages/OS400/ccsidcurl.h b/packages/OS400/ccsidcurl.h index dd7e59eb4..959aaaabb 100644 --- a/packages/OS400/ccsidcurl.h +++ b/packages/OS400/ccsidcurl.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -89,5 +89,10 @@ CURL_EXTERN CURLUcode curl_url_get_ccsid(CURLU *handle, CURLUPart what, CURL_EXTERN CURLUcode curl_url_set_ccsid(CURLU *handle, CURLUPart what, const char *part, unsigned int flags, unsigned int ccsid); +CURL_EXTERN const struct curl_easyoption *curl_easy_option_by_name_ccsid( + const char *name, unsigned int ccsid); +CURL_EXTERN const char *curl_easy_option_get_name_ccsid( + const struct curl_easyoption *option, + unsigned int ccsid); #endif diff --git a/packages/OS400/curl.inc.in b/packages/OS400/curl.inc.in index c77e2066f..dbd30946a 100644 --- a/packages/OS400/curl.inc.in +++ b/packages/OS400/curl.inc.in @@ -140,8 +140,14 @@ d c X'01000000' d CURL_VERSION_HTTP3... d c X'02000000' - d CURL_VERSION_UNICODE... + d CURL_VERSION_ZSTD... d c X'04000000' + d CURL_VERSION_UNICODE... + d c X'08000000' + d CURL_VERSION_HSTS... + d c X'10000000' + d CURL_VERSION_GSASL... + d c X'20000000' * d CURL_HTTPPOST_FILENAME... d c X'00000001' @@ -193,6 +199,8 @@ d c X'00000020' d CURLAUTH_BEARER... d c X'00000040' + d CURLAUTH_AWS_SIGV4... + d c X'00000080' d CURLAUTH_ONLY... d c X'80000000' d CURLAUTH_ANY c X'7FFFFFEF' @@ -228,10 +236,16 @@ * d CURLOPTTYPE_LONG... d c 0 + d CURLOPTTYPE_VALUES... + d c 0 d CURLOPTTYPE_OBJECTPOINT... d c 10000 d CURLOPTTYPE_STRINGPOINT... d c 10000 + d CURLOPTTYPE_SLISTPOINT... + d c 10000 + d CURLOPTTYPE_CBPOINT... + d c 10000 d CURLOPTTYPE_FUNCTIONPOINT... d c 20000 d CURLOPTTYPE_OFF_T... @@ -404,6 +418,11 @@ d c X'00000100' d CURLU_GUESS_SCHEME... d c X'00000200' + d CURLU_NO_AUTHORITY... + d c X'00000400' + * + d CURLOT_FLAG_ALIAS... + d c X'00000001' * ************************************************************************** * Types @@ -431,8 +450,6 @@ d c 7 d CURLE_WEIRD_SERVER_REPLY... d c 8 - d CURLE_FTP_WEIRD_SERVER_REPLY... - d c 8 d CURLE_REMOTE_ACCESS_DENIED... d c 9 d CURLE_FTP_ACCEPT_FAILED... @@ -608,10 +625,14 @@ d c 95 d CURLE_QUIC_CONNECT_ERROR... d c 96 + d CURLE_PROXY... + d c 97 * /if not defined(CURL_NO_OLDIES) d CURLE_URL_MALFORMAT_USER... d c 4 + d CURLE_FTP_WEIRD_SERVER_REPLY... + d c 8 d CURLE_FTP_ACCESS_DENIED... d c 9 d CURLE_FTP_USER_PASSWORD_INCORRECT... @@ -656,12 +677,12 @@ d c 48 d CURLE_OBSOLETE... d c 50 - d CURLE_SSL_PEER_CERTIFICATE... - d c 51 d CURLE_SHARE_IN_USE... d c 57 d CURLE_SSL_CACERT... d c 60 + d CURLE_SSL_PEER_CERTIFICATE... + d c 60 d CURLE_FTP_SSL_FAILED... d c 64 d CURLE_TFTP_DISKFULL... @@ -672,6 +693,75 @@ d c 99999 /endif * + d CURLproxycode s 10i 0 based(######ptr######) Enum + d CURLPX_OK c 0 + d CURLPX_BAD_ADDRESS_TYPE... + d c 1 + d CURLPX_BAD_VERSION... + d c 2 + d CURLPX_CLOSED... + d c 3 + d CURLPX_GSSAPI... + d c 4 + d CURLPX_GSSAPI_PERMSG... + d c 5 + d CURLPX_GSSAPI_PROTECTION... + d c 6 + d CURLPX_IDENTD... + d c 7 + d CURLPX_IDENTD_DIFFER... + d c 8 + d CURLPX_LONG_HOSTNAME... + d c 9 + d CURLPX_LONG_PASSWD... + d c 10 + d CURLPX_LONG_USER... + d c 11 + d CURLPX_NO_AUTH... + d c 12 + d CURLPX_RECV_ADDRESS... + d c 13 + d CURLPX_RECV_AUTH... + d c 14 + d CURLPX_RECV_CONNECT... + d c 15 + d CURLPX_RECV_REQACK... + d c 16 + d CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED... + d c 17 + d CURLPX_REPLY_COMMAND_NOT_SUPPORTED... + d c 18 + d CURLPX_REPLY_CONNECTION_REFUSED... + d c 10 + d CURLPX_REPLY_GENERAL_SERVER_FAILURE... + d c 20 + d CURLPX_REPLY_HOST_UNREACHABLE... + d c 21 + d CURLPX_REPLY_NETWORK_UNREACHABLE... + d c 22 + d CURLPX_REPLY_NOT_ALLOWED... + d c 23 + d CURLPX_REPLY_TTL_EXPIRED... + d c 24 + d CURLPX_REPLY_UNASSIGNED... + d c 25 + d CURLPX_REQUEST_FAILED... + d c 26 + d CURLPX_RESOLVE_HOST... + d c 27 + d CURLPX_SEND_AUTH... + d c 28 + d CURLPX_SEND_CONNECT... + d c 29 + d CURLPX_SEND_REQUEST... + d c 30 + d CURLPX_UNKNOWN_FAIL... + d c 31 + d CURLPX_UNKNOWN_MODE... + d c 32 + d CURLPX_USER_REJECTED... + d c 33 + * d curlioerr s 10i 0 based(######ptr######) Enum d CURLIOE_OK c 0 d CURLIOE_UNKNOWNCMD... @@ -745,8 +835,10 @@ d c 2 d CURLKHSTAT_DEFER... d c 3 - d CURLKHSTAT_LAST... + d CURLKHSTAT_FINE_REPLACE... d c 4 + d CURLKHSTAT_LAST... + d c 5 * d curl_khmatch s 10i 0 based(######ptr######) Enum d CURLKHMATCH_OK... @@ -776,6 +868,8 @@ d c X'0004' d CURLSSLOPT_REVOKE_BEST_EFFORT... d c X'0008' + d CURLSSLOPT_NATIVE_CA... + d c X'0010' * d CURL_HET_DEFAULT... d c 200 @@ -836,10 +930,6 @@ d CURLHEADER_SEPARATE... d c X'00000001' * - d CURLALTSVC_IMMEDIATELY... - d c X'00000001' - d CURLALTSVC_ALTUSED... - d c X'00000002' d CURLALTSVC_READONLYFILE... d c X'00000004' d CURLALTSVC_H1... @@ -849,6 +939,11 @@ d CURLALTSVC_H3... d c X'00000020' * + d CURLHSTS_ENABLE... + d c X'00000001' + d CURLHSTS_READONLYFILE... + d c X'00000002' + * d CURLPROTO_HTTP... d c X'00000001' d CURLPROTO_HTTPS... @@ -905,6 +1000,10 @@ d c X'04000000' d CURLPROTO_SMBS... d c X'08000000' + d CURLPROTO_MQTT... + d c X'10000000' + d CURLPROTO_GOPHERS... + d c X'20000000' * d CURLoption s 10i 0 based(######ptr######) Enum d CURLOPT_WRITEDATA... @@ -1103,6 +1202,8 @@ d c 00111 d CURLOPT_FTP_RESPONSE_TIMEOUT... d c 00112 + d CURLOPT_SERVER_RESPONSE_TIMEOUT... Alias + d c 00112 d CURLOPT_IPRESOLVE... d c 00113 d CURLOPT_MAXFILESIZE... @@ -1456,6 +1557,18 @@ d c 40297 d CURLOPT_SSL_EC_CURVES... d c 10298 + d CURLOPT_HSTS_CTRL... + d c 00299 + d CURLOPT_HSTS... + d c 10300 + d CURLOPT_HSTSREADFUNCTION... + d c 20301 + d CURLOPT_HSTSREADDATA... + d c 10302 + d CURLOPT_HSTSWRITEFUNCTION... + d c 20303 + d CURLOPT_HSTSWRITEDATA... + d c 10304 d CURLOPT_AWS_SIG4... d c 10305 d CURLOPT_DOH_SSL_VERIFYPEER... @@ -1487,8 +1600,6 @@ d c 10063 d CURLOPT_ENCODING... d c 10102 - d CURLOPT_SERVER_RESPONSE_TIMEOUT... - d c 00112 d CURLOPT_FTP_SSL... d c 00119 d CURLOPT_POST301... @@ -1724,6 +1835,10 @@ d c 11 d CURLSSLBACKEND_MESALINK... d c 12 + d CURLSSLBACKEND_BEARSSL... + d c 13 + d CURLSSLBACKEND_RUSTLS... + d c 14 * Aliases for clones. d CURLSSLBACKEND_LIBRESSL... d c 1 @@ -1783,6 +1898,21 @@ d CURL_TIMECOND_LAST... d c 3 * + d curl_easytype s 10i 0 based(######ptr######) Enum + d CURLOT_LONG c 0 + d CURLOT_VALUES... + d c 1 + d CURLOT_OFF_T c 2 + d CURLOT_OBJECT... + d c 3 + d CURLOT_STRING... + d c 4 + d CURLOT_SLIST c 5 + d CURLOT_CBPTR c 6 + d CURLOT_BLOB c 7 + d CURLOT_FUNCTION... + d c 8 + * d CURLSHcode s 10i 0 based(######ptr######) Enum d CURLSHE_OK c 0 d CURLSHE_BAD_OPTION... @@ -1818,8 +1948,18 @@ d c 2 d CURLVERSION_FOURTH... d c 3 + d CURLVERSION_FIFTH... + d c 4 + d CURLVERSION_SIXTH... + d c 5 + d CURLVERSION_SEVENTH... + d c 6 + d CURLVERSION_HEIGHTH... + d c 7 + d CURLVERSION_NINTH... + d c 8 d CURLVERSION_NOW... - d c 3 CURLVERSION_FOURTH + d c 8 CURLVERSION_NINTH * d curlsocktype s 10i 0 based(######ptr######) Enum d CURLSOCKTYPE_IPCXN... @@ -1994,6 +2134,14 @@ d c 8 d CURLUPART_FRAGMENT... d c 9 + d CURLUPART_ZONEID... + d c 10 + * + * + d CURLSTScode s 10i 0 based(######ptr######) Enum + d CURLSTS_OK c 0 + d CURLSTS_DONE c 1 + d CURLSTS_FAIL c 2 * * Renaming CURLMsg to CURL_Msg to avoid case-insensivity name clash. * @@ -2089,6 +2237,26 @@ d iconv_ver_num... d 10i 0 d libssh_version... + d * const char * + d brotli_ver_num... + d 10u 0 + d brotli_version... + d * const char * + d nghttp2_ver_num... + d 10u 0 + d nghttp2_version... + d * const char * + d quic_version... + d * const char * + d cainfo... + d * const char * + d capath... + d * const char * + d zstd_ver_num... + d 10u 0 + d zstd_version... + d * const char * + d hyper_version... d * const char * * d curl_certinfo ds based(######ptr######) @@ -2126,6 +2294,28 @@ d b_size 10u 0 size_t d b_used 10u 0 size_t * + d curl_easyoption... + d ds based(######ptr######) + d qualified + d name * const char * + d id like(CURLoption) + d type like(curl_easytyoe) + d flags 10u 0 + * + d curl_hstsentry... + d ds based(######ptr######) + d qualified + d name * char * + d namelen 10u 0 size_t + d includeSubDomain... + d 10u 0 Bit field: 1 + d expire 10 + * + d curl_index ds based(######ptr######) + d qualified + d index 10u 0 size_t + d total 10u 0 size_t + * d curl_formget_callback... d s * based(######ptr######) procptr * @@ -2211,6 +2401,12 @@ d s * based(######ptr######) procptr * d curl_resolver_start_callback... + d s * based(######ptr######) procptr + * + d curl_hstsread_callback... + d s * based(######ptr######) procptr + * + d curl_hstswrite_callback... d s * based(######ptr######) procptr * ************************************************************************** @@ -2707,6 +2903,18 @@ d part * value options(*string) d flags 10u 0 value * + d curl_easy_option_by_name... + d pr * extproc('curl_easy_option_by_name') curl_easyoption * + d name * value option(*string) + * + d curl_easy_option_by_id... + d pr * extproc('curl_easy_option_by_id') curl_easyoption * + d id value like(CURLoption) + * + d curl_easy_option_next... + d pr * extproc('curl_easy_next') curl_easyoption * + d prev * value curl_easyoption * + * ************************************************************************** * CCSID wrapper procedure prototypes ************************************************************************** @@ -2879,6 +3087,18 @@ d what value like(CURLUPart) d part * value options(*string) d flags 10u 0 value + d ccsid 10u 0 value + * + d curl_easy_option_by_name_ccsid... + d pr * extproc( curl_easyoption * + d 'curl_easy_option_by_name_ccsid') + d name * value option(*string) + d ccsid 10u 0 value + * + d curl_easy_option_get_name_ccsid... + d pr * extproc( const char * + d 'curl_easy_option_get_name_ccsid') + d option * value curl_easyoption * d ccsid 10u 0 value * /endif