123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- Implementation notes:
- This is a true OS/400 ILE implementation, not a PASE implementation (for
- PASE, use AIX implementation).
- The biggest problem with OS/400 is EBCDIC. Libcurl implements an internal
- conversion mechanism, but it has been designed for computers that have a
- single native character set. OS/400 default native character set varies
- depending on the country for which it has been localized. And more, a job
- may dynamically alter its "native" character set.
- Several characters that do not have fixed code in EBCDIC variants are
- used in libcurl strings. As a consequence, using the existing conversion
- mechanism would have lead in a localized binary library - not portable across
- countries.
- For this reason, and because libcurl was originally designed for ASCII based
- operating systems, the current OS/400 implementation uses ASCII as internal
- character set. This has been accomplished using the QADRT library and
- include files, a C and system procedures ASCII wrapper library. See IBM QADRT
- description for more information.
- This then results in libcurl being an ASCII library: any function string
- argument is taken/returned in ASCII and a C/C++ calling program built around
- QADRT may use libcurl functions as on any other platform.
- QADRT does not define ASCII wrappers for all C/system procedures: the
- OS/400 configuration header file and an additional module (os400sys.c) define
- 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. 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
- short. Enums that are internally implemented by the C compiler as one of these
- types are also forbidden. Libcurl uses enums as vararg procedure tagfields...
- Happily, there is a pragma forcing enums to type "int". The original libcurl
- header files are thus altered during build process to use this pragma, in
- order to force libcurl enums of being type int (the pragma disposition in use
- before inclusion is restored before resuming the including unit compilation).
- Secure socket layer is provided by the IBM GSKit API: unlike other SSL
- implementations, GSKit is based on "certificate stores" or keyrings
- rather than individual certificate/key files. Certificate stores, as well as
- "certificate labels" are managed by external IBM-defined applications.
- There are two ways to specify an SSL context:
- - By an application identifier.
- - By a keyring file pathname and (optionally) certificate label.
- To identify an SSL context by application identifier, use option
- SETOPT_SSLCERT to specify the application identifier.
- To address an SSL context by keyring and certificate label, use CURLOPT_CAINFO
- to set-up the keyring pathname, CURLOPT_SSLCERT to define the certificate label
- (omitting it will cause the default certificate in keyring to be used) and
- CURLOPT_KEYPASSWD to give the keyring password. If SSL is used without
- defining any of these options, the default (i.e.: system) keyring is used for
- server certificate validation.
- Non-standard EBCDIC wrapper prototypes are defined in an additional header
- file: ccsidcurl.h. These should be self-explanatory to an OS/400-aware
- designer. CCSID 0 can be used to select the current job's CCSID.
- Wrapper procedures with variable arguments are described below:
- _ curl_easy_setopt_ccsid()
- Variable arguments are a string pointer and a CCSID (unsigned int) for
- options:
- CURLOPT_ABSTRACT_UNIX_SOCKET
- CURLOPT_ALTSVC
- CURLOPT_AWS_SIGV4
- CURLOPT_CAINFO
- CURLOPT_CAPATH
- CURLOPT_COOKIE
- CURLOPT_COOKIEFILE
- CURLOPT_COOKIEJAR
- CURLOPT_COOKIELIST
- CURLOPT_COPYPOSTFIELDS
- CURLOPT_CRLFILE
- CURLOPT_CUSTOMREQUEST
- CURLOPT_DEFAULT_PROTOCOL
- CURLOPT_DNS_SERVERS
- CURLOPT_DOH_URL
- CURLOPT_EGDSOCKET
- CURLOPT_ENCODING
- CURLOPT_FTPPORT
- CURLOPT_FTP_ACCOUNT
- CURLOPT_FTP_ALTERNATIVE_TO_USER
- CURLOPT_HSTS
- CURLOPT_INTERFACE
- CURLOPT_ISSUERCERT
- CURLOPT_KEYPASSWD
- CURLOPT_KRBLEVEL
- CURLOPT_LOGIN_OPTIONS
- CURLOPT_MAIL_AUTH
- CURLOPT_MAIL_FROM
- CURLOPT_NETRC_FILE
- CURLOPT_NOPROXY
- CURLOPT_PASSWORD
- CURLOPT_PINNEDPUBLICKEY
- CURLOPT_PRE_PROXY
- CURLOPT_PROTOCOLS_STR
- CURLOPT_PROXY
- CURLOPT_PROXYPASSWORD
- CURLOPT_PROXYUSERNAME
- CURLOPT_PROXYUSERPWD
- CURLOPT_PROXY_CAINFO
- CURLOPT_PROXY_CAPATH
- CURLOPT_PROXY_CRLFILE
- CURLOPT_PROXY_KEYPASSWD
- CURLOPT_PROXY_PINNEDPUBLICKEY
- CURLOPT_PROXY_SERVICE_NAME
- CURLOPT_PROXY_SSLCERT
- CURLOPT_PROXY_SSLCERTTYPE
- CURLOPT_PROXY_SSLKEY
- CURLOPT_PROXY_SSLKEYTYPE
- CURLOPT_PROXY_SSL_CIPHER_LIST
- CURLOPT_PROXY_TLS13_CIPHERS
- CURLOPT_PROXY_TLSAUTH_PASSWORD
- CURLOPT_PROXY_TLSAUTH_TYPE
- CURLOPT_PROXY_TLSAUTH_USERNAME
- CURLOPT_RANDOM_FILE
- CURLOPT_RANGE
- CURLOPT_REDIR_PROTOCOLS_STR
- CURLOPT_REFERER
- CURLOPT_REQUEST_TARGET
- CURLOPT_RTSP_SESSION_UID
- CURLOPT_RTSP_STREAM_URI
- CURLOPT_RTSP_TRANSPORT
- CURLOPT_SASL_AUTHZID
- CURLOPT_SERVICE_NAME
- CURLOPT_SOCKS5_GSSAPI_SERVICE
- CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
- CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256
- CURLOPT_SSH_KNOWNHOSTS
- CURLOPT_SSH_PRIVATE_KEYFILE
- CURLOPT_SSH_PUBLIC_KEYFILE
- CURLOPT_SSLCERT
- CURLOPT_SSLCERTTYPE
- CURLOPT_SSLENGINE
- CURLOPT_SSLKEY
- CURLOPT_SSLKEYTYPE
- CURLOPT_SSL_CIPHER_LIST
- CURLOPT_TLS13_CIPHERS
- CURLOPT_TLSAUTH_PASSWORD
- CURLOPT_TLSAUTH_TYPE
- CURLOPT_TLSAUTH_USERNAME
- CURLOPT_UNIX_SOCKET_PATH
- CURLOPT_URL
- CURLOPT_USERAGENT
- CURLOPT_USERNAME
- CURLOPT_USERPWD
- CURLOPT_XOAUTH2_BEARER
- All blob options are also supported.
- In all other cases, it ignores the ccsid parameter and behaves as
- curl_easy_setopt().
- Note that CURLOPT_ERRORBUFFER is not in the list above, since it gives the
- address of an (empty) character buffer, not the address of a string.
- CURLOPT_POSTFIELDS stores the address of static binary data (of type void *)
- and thus is not converted. If CURLOPT_COPYPOSTFIELDS is issued after
- CURLOPT_POSTFIELDSIZE != -1, the data size is adjusted according to the
- CCSID conversion result length.
- _ curl_formadd_ccsid()
- In the variable argument list, string pointers should be followed by a (long)
- CCSID for the following options:
- CURLFORM_FILENAME
- CURLFORM_CONTENTTYPE
- CURLFORM_BUFFER
- CURLFORM_FILE
- CURLFORM_FILECONTENT
- CURLFORM_COPYCONTENTS
- CURLFORM_COPYNAME
- CURLFORM_PTRNAME
- If taken from an argument array, an additional array entry must follow each
- entry containing one of the above option. This additional entry holds the CCSID
- in its value field, and the option field is meaningless.
- It is not possible to have a string pointer and its CCSID across a function
- parameter/array boundary.
- Please note that CURLFORM_PTRCONTENTS and CURLFORM_BUFFERPTR are considered
- 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 released with
- curl_free() after use:
- CURLINFO_EFFECTIVE_URL
- CURLINFO_CONTENT_TYPE
- CURLINFO_FTP_ENTRY_PATH
- CURLINFO_REDIRECT_URL
- CURLINFO_REFERER
- CURLINFO_PRIMARY_IP
- CURLINFO_RTSP_SESSION_ID
- CURLINFO_LOCAL_IP
- CURLINFO_SCHEME
- Likewise, the following options are followed by a struct curl_slist * * and a
- CCSID.
- CURLINFO_SSL_ENGINES
- 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 freed with curl_certinfo_free_all()
- after use.
- Other options are processed like in curl_easy_getinfo().
- _ curl_easy_strerror_ccsid(), curl_multi_strerror_ccsid(),
- curl_share_strerror_ccsid() and curl_url_strerror_ccsid() work as their
- non-ccsid version and return a string encoded in the additional ccsid
- parameter. These strings belong to libcurl and may not be freed by the caller.
- A subsequent call to the same procedure in the same thread invalidates the
- previous result.
- _ curl_pushheader_bynum_cssid() and curl_pushheader_byname_ccsid()
- Although the prototypes are self-explanatory, the returned string pointer
- 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.
- _ curl_easy_header_ccsid() works as its non-CCSID counterpart but requires an
- additional ccsid parameter specifying the name parameter encoding. The output
- hout parameter is kept in libcurl's encoding and should not be altered.
- _ curl_from_ccsid() and curl_to_ccsid() are string encoding conversion
- functions between ASCII (latin1) and the given CCSID. The first parameter is
- the source string, the second is the CCSID and the returned value is a pointer
- to the dynamically allocated string. These functions do not impact on Curl's
- behavior and are only provided for user convenience. After use, returned values
- must be released with curl_free().
- Standard compilation environment does support neither autotools nor make;
- in fact, very few common utilities are available. As a consequence, the
- config-os400.h has been coded manually and the compilation scripts are
- a set of shell scripts stored in subdirectory packages/OS400.
- The "curl" command and the test environment are currently not supported on
- OS/400.
- Protocols currently implemented on OS/400:
- _ DICT
- _ FILE
- _ FTP
- _ FTPS
- _ FTP with secure transmission
- _ GOPHER
- _ HTTP
- _ HTTPS
- _ IMAP
- _ IMAPS
- _ IMAP with secure transmission
- _ LDAP
- _ POP3
- _ POP3S
- _ POP3 with secure transmission
- _ RTSP
- _ SCP if libssh2 is enabled
- _ SFTP if libssh2 is enabled
- _ SMTP
- _ SMTPS
- _ SMTP with secure transmission
- _ TELNET
- _ TFTP
- Compiling on OS/400:
- These instructions targets people who knows about OS/400, compiling, IFS and
- archive extraction. Do not ask questions about these subjects if you're not
- familiar with.
- _ As a prerequisite, QADRT development environment must be installed.
- For more information on downloading and installing the QADRT development kit,
- please see https://www.ibm.com/support/pages/node/6258183
- _ If data compression has to be supported, ZLIB development environment must
- be installed.
- _ Likewise, if SCP and SFTP protocols have to be compiled in, LIBSSH2
- developent environment must be installed.
- _ Install the curl source directory in IFS. Do NOT install it in the
- installation target directory (which defaults to /curl).
- _ Enter Qshell (QSH, not PASE)
- _ Change current directory to the curl installation directory
- _ Change current directory to ./packages/OS400
- _ Edit file iniscript.sh. You may want to change tunable configuration
- parameters, like debug info generation, optimization level, listing option,
- target library, ZLIB/LIBSSH2 availability and location, etc.
- _ Copy any file in the current directory to makelog (i.e.:
- cp initscript.sh makelog): this is intended to create the makelog file with
- an ASCII CCSID!
- _ Enter the command "sh makefile.sh > makelog 2>&1"
- _ Examine the makelog file to check for compilation errors. CZM0383 warnings on
- C or system standard API come from QADRT inlining and can safely be ignored.
- Leaving file initscript.sh unchanged, this will produce the following OS/400
- objects:
- _ Library CURL. All other objects will be stored in this library.
- _ Modules for all libcurl units.
- _ Binding directory CURL_A, to be used at calling program link time for
- statically binding the modules (specify BNDSRVPGM(QADRTTS QGLDCLNT QGLDBRDR)
- when creating a program using CURL_A).
- _ Service program CURL.<soname>, where <soname> is extracted from the
- lib/Makefile.am VERSION variable. To be used at calling program run-time
- when this program has dynamically bound curl at link time.
- _ Binding directory CURL. To be used to dynamically bind libcurl when linking a
- calling program.
- _ Source file H. It contains all the include members needed to compile a C/C++
- module using libcurl, and an ILE/RPG /copy member for support in this
- language.
- _ Standard C/C++ libcurl include members in file H.
- _ CCSIDCURL member in file H. This defines the non-standard EBCDIC wrappers for
- C and C++.
- _ CURL.INC member in file H. This defines everything needed by an ILE/RPG
- program using libcurl.
- _ LIBxxx modules and programs. Although the test environment is not supported
- on OS/400, the libcurl test programs are compiled for manual tests.
- _ IFS directory /curl/include/curl containing the C header files for IFS source
- C/C++ compilation and curl.inc.rpgle for IFS source ILE/RPG compilation.
- Special programming consideration:
- QADRT being used, the following points must be considered:
- _ If static binding is used, service program QADRTTS must be linked too.
- _ The EBCDIC CCSID used by QADRT is 37 by default, NOT THE JOB'S CCSID. If
- another EBCDIC CCSID is required, it must be set via a locale through a call
- to setlocale_a (QADRT's setlocale() ASCII wrapper) with category LC_ALL or
- LC_CTYPE, or by setting environment variable QADRT_ENV_LOCALE to the locale
- object path before executing the program.
- _ Do not use original source include files unless you know what you are doing.
- Use the installed members instead (in /QSYS.LIB/CURL.LIB/H.FILE and
- /curl/include/curl).
- ILE/RPG support:
- Since most of the ILE OS/400 programmers use ILE/RPG exclusively, a
- definition /INCLUDE member is provided for this language. To include all
- libcurl definitions in an ILE/RPG module, line
- h bnddir('CURL/CURL')
- must figure in the program header, and line
- d/include curl/h,curl.inc
- in the global data section of the module's source code.
- No vararg procedure support exists in ILE/RPG: for this reason, the following
- considerations apply:
- _ Procedures curl_easy_setopt_long(), curl_easy_setopt_object(),
- curl_easy_setopt_function(), curl_easy_setopt_offset() and
- curl_easy_setopt_blob() are all alias prototypes to curl_easy_setopt(), but
- with different parameter lists.
- _ Procedures curl_easy_getinfo_string(), curl_easy_getinfo_long(),
- curl_easy_getinfo_double(), curl_easy_getinfo_slist(),
- curl_easy_getinfo_ptr(), curl_easy_getinfo_socket() and
- curl_easy_getinfo_off_t() are all alias prototypes to curl_easy_getinfo(),
- but with different parameter lists.
- _ Procedures curl_multi_setopt_long(), curl_multi_setopt_object(),
- curl_multi_setopt_function() and curl_multi_setopt_offset() are all alias
- prototypes to curl_multi_setopt(), but with different parameter lists.
- _ Procedures curl_share_setopt_int(), curl_share_setopt_ptr() and
- curl_share_setopt_proc() are all alias prototypes to curl_share_setopt,
- but with different parameter lists.
- _ Procedure curl_easy_setopt_blob_ccsid() is an alias of
- curl_easy_setopt_ccsid() supporting blob encoding conversion.
- _ The prototype of procedure curl_formadd() allows specifying a pointer option
- and the CURLFORM_END option. This makes possible to use an option array
- without any additional definition. If some specific incompatible argument
- list is used in the ILE/RPG program, the latter must define a specialised
- alias. The same applies to curl_formadd_ccsid() too.
- _ Since V7R4M0, procedure overloading is used to emulate limited "vararg-like"
- definitions of curl_easy_setopt(), curl_multi_setopt(), curl_share_setopt()
- and curl_easy_getinfo(). Blob and CCSID alternatives are NOT included in
- overloading.
- Since RPG cannot cast a long to a pointer, procedure curl_form_long_value()
- is provided for that purpose: this allows storing a long value in the
- curl_forms array. Please note the form API is deprecated and the MIME API
- should be used instead.
|