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
This commit is contained in:
Patrick Monnerat 2021-04-11 19:33:09 +02:00 committed by Daniel Stenberg
parent 3fb6e5a010
commit a2a8f9d730
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
4 changed files with 321 additions and 68 deletions

View File

@ -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

View File

@ -26,6 +26,7 @@
#include <iconv.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include <stdarg.h>
@ -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;
}

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, 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

View File

@ -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