| 1 |
$Id: README.OS400,v 1.13 2009/12/21 12:26:48 patrickm Exp $
|
| 2 |
|
| 3 |
Implementation notes:
|
| 4 |
|
| 5 |
This is a true OS/400 implementation, not a PASE implementation (for PASE,
|
| 6 |
use AIX implementation).
|
| 7 |
|
| 8 |
The biggest problem with OS/400 is EBCDIC. Libcurl implements an internal
|
| 9 |
conversion mechanism, but it has been designed for computers that have a
|
| 10 |
single native character set. OS/400 default native character set varies
|
| 11 |
depending on the country for which it has been localized. And more, a job
|
| 12 |
may dynamically alter its "native" character set.
|
| 13 |
Several characters that do not have fixed code in EBCDIC variants are
|
| 14 |
used in libcurl strings. As a consequence, using the existing conversion
|
| 15 |
mechanism would have lead in a localized binary library - not portable across
|
| 16 |
countries.
|
| 17 |
For this reason, and because libcurl was originally designed for ASCII based
|
| 18 |
operating systems, the current OS/400 implementation uses ASCII as internal
|
| 19 |
character set. This has been accomplished using the QADRT library and
|
| 20 |
include files, a C and system procedures ASCII wrapper library. See IBM QADRT
|
| 21 |
description for more information.
|
| 22 |
This then results in libcurl being an ASCII library: any function string
|
| 23 |
argument is taken/returned in ASCII and a C/C++ calling program built around
|
| 24 |
QADRT may use libcurl functions as on any other platform.
|
| 25 |
QADRT does not define ASCII wrappers for all C/system procedures: the
|
| 26 |
OS/400 configuration header file and an additional module (os400sys.c) define
|
| 27 |
some more of them, that are used by libcurl and that QADRT left out.
|
| 28 |
To support all the different variants of EBCDIC, non-standard wrapper
|
| 29 |
procedures have been added to libcurl on OS/400: they provide an additional
|
| 30 |
CCSID (numeric Coded Character Set ID specific to OS/400) parameter for each
|
| 31 |
string argument. String values passed to callback procedures are NOT converted,
|
| 32 |
so text gathered this way is (probably !) ASCII.
|
| 33 |
|
| 34 |
Another OS/400 problem comes from the fact that the last fixed argument of a
|
| 35 |
vararg procedure may not be of type char, unsigned char, short or unsigned
|
| 36 |
short. Enums that are internally implemented by the C compiler as one of these
|
| 37 |
types are also forbidden. Libcurl uses enums as vararg procedure tagfields...
|
| 38 |
Happily, there is a pragma forcing enums to type "int". The original libcurl
|
| 39 |
header files are thus altered during build process to use this pragma, in
|
| 40 |
order to force libcurl enums of being type int (the pragma disposition in use
|
| 41 |
before inclusion is restored before resuming the including unit compilation).
|
| 42 |
|
| 43 |
Three SSL implementations were present in libcurl. Nevertheless, none of them
|
| 44 |
is available on OS/400. To support SSL on OS/400, a fourth implementation has
|
| 45 |
been added (qssl.[ch]). There is no way to have different certificate stores
|
| 46 |
for CAs and for personal/application certificates/key. More, the SSL context
|
| 47 |
may be defined as an application identifier in the main certificate store,
|
| 48 |
or as a keyring file. As a consequence, the meaning of some fields have been
|
| 49 |
slightly altered:
|
| 50 |
_ The "certificate identifier" is taken from CURLOPT_SSLCERT if defined, else
|
| 51 |
from CURLOPT_CAINFO.
|
| 52 |
_ The certificate identifier is then used as an application identifier in the
|
| 53 |
main certificate store. If successful, this context is used.
|
| 54 |
_ If the previous step failed, the certificate identifier is used as the file
|
| 55 |
name of a keyring. CURLOPT_KEYPASSWD is used here as the keyring password.
|
| 56 |
_ The default ca-bundle (CURLOPT_CAINFO) is set to the main certificate store's
|
| 57 |
keyring file name: this allows to use the system global CAs by default. (In that
|
| 58 |
case, the keyring password is safely recovered from the system... IBM dixit!)
|
| 59 |
|
| 60 |
Non-standard EBCDIC wrapper prototypes are defined in an additional header
|
| 61 |
file: ccsidcurl.h. These should be self-explanatory to an OS/400-aware
|
| 62 |
designer. CCSID 0 can be used to select the current job's CCSID.
|
| 63 |
Wrapper procedures with variable arguments are described below:
|
| 64 |
|
| 65 |
_ curl_easy_setopt_ccsid()
|
| 66 |
Variable arguments are a string pointer and a CCSID (unsigned int) for
|
| 67 |
options:
|
| 68 |
CURLOPT_CAINFO
|
| 69 |
CURLOPT_CAPATH
|
| 70 |
CURLOPT_COOKIE
|
| 71 |
CURLOPT_COOKIEFILE
|
| 72 |
CURLOPT_COOKIEJAR
|
| 73 |
CURLOPT_COOKIELIST
|
| 74 |
CURLOPT_CUSTOMREQUEST
|
| 75 |
CURLOPT_EGDSOCKET
|
| 76 |
CURLOPT_ENCODING
|
| 77 |
CURLOPT_FTPPORT
|
| 78 |
CURLOPT_FTP_ACCOUNT
|
| 79 |
CURLOPT_FTP_ALTERNATIVE_TO_USER
|
| 80 |
CURLOPT_INTERFACE
|
| 81 |
CURLOPT_KEYPASSWD
|
| 82 |
CURLOPT_KRBLEVEL
|
| 83 |
CURLOPT_NETRC_FILE
|
| 84 |
CURLOPT_COPYPOSTFIELDS
|
| 85 |
CURLOPT_PROXY
|
| 86 |
CURLOPT_PROXYUSERPWD
|
| 87 |
CURLOPT_RANDOM_FILE
|
| 88 |
CURLOPT_RANGE
|
| 89 |
CURLOPT_REFERER
|
| 90 |
CURLOPT_SSH_PRIVATE_KEYFILE
|
| 91 |
CURLOPT_SSH_PUBLIC_KEYFILE
|
| 92 |
CURLOPT_SSLCERT
|
| 93 |
CURLOPT_SSLCERTTYPE
|
| 94 |
CURLOPT_SSLENGINE
|
| 95 |
CURLOPT_SSLKEY
|
| 96 |
CURLOPT_SSLKEYTYPE
|
| 97 |
CURLOPT_SSL_CIPHER_LIST
|
| 98 |
CURLOPT_URL
|
| 99 |
CURLOPT_USERAGENT
|
| 100 |
CURLOPT_USERPWD
|
| 101 |
CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
|
| 102 |
CURLOPT_CRLFILE
|
| 103 |
CURLOPT_ISSUERCERT
|
| 104 |
CURLOPT_USERNAME
|
| 105 |
CURLOPT_PASSWORD
|
| 106 |
CURLOPT_PROXYUSERNAME
|
| 107 |
CURLOPT_PROXYPASSWORD
|
| 108 |
CURLOPT_NOPROXY
|
| 109 |
CURLOPT_SOCKS5_GSSAPI_SERVICE
|
| 110 |
CURLOPT_MAIL_FROM
|
| 111 |
CURLOPT_MAIL_RCPT
|
| 112 |
Else it is the same as for curl_easy_setopt().
|
| 113 |
Note that CURLOPT_ERRORBUFFER is not in the list above, since it gives the
|
| 114 |
address of an (empty) character buffer, not the address of a string.
|
| 115 |
CURLOPT_POSTFIELDS stores the address of static binary data (of type void *) and
|
| 116 |
thus is not converted. If CURLOPT_COPYPOSTFIELDS is issued after
|
| 117 |
CURLOPT_POSTFIELDSIZE != -1, the data size is adjusted according to the
|
| 118 |
CCSID conversion result length.
|
| 119 |
|
| 120 |
_ curl_formadd_ccsid()
|
| 121 |
In the variable argument list, string pointers should be followed by a (long)
|
| 122 |
CCSID for the following options:
|
| 123 |
CURLFORM_FILENAME
|
| 124 |
CURLFORM_CONTENTTYPE
|
| 125 |
CURLFORM_BUFFER
|
| 126 |
CURLFORM_FILE
|
| 127 |
CURLFORM_FILECONTENT
|
| 128 |
CURLFORM_COPYCONTENTS
|
| 129 |
CURLFORM_COPYNAME
|
| 130 |
CURLFORM_PTRNAME
|
| 131 |
If taken from an argument array, an additional array entry must follow each
|
| 132 |
entry containing one of the above option. This additional entry holds the CCSID
|
| 133 |
in its value field, and the option field is meaningless.
|
| 134 |
It is not possible to have a string pointer and its CCSID across a function
|
| 135 |
parameter/array boundary.
|
| 136 |
Please note that CURLFORM_PTRCONTENTS and CURLFORM_BUFFERPTR are considered
|
| 137 |
unconvertible strings and thus are NOT followed by a CCSID.
|
| 138 |
|
| 139 |
_ curl_easy_getinfo_ccsid
|
| 140 |
The following options are followed by a 'char * *' and a CCSID. Unlike
|
| 141 |
curl_easy_getinfo(), the value returned in the pointer should be freed after
|
| 142 |
use:
|
| 143 |
CURLINFO_EFFECTIVE_URL
|
| 144 |
CURLINFO_CONTENT_TYPE
|
| 145 |
CURLINFO_FTP_ENTRY_PATH
|
| 146 |
Other options are processed like in curl_easy_getinfo().
|
| 147 |
|
| 148 |
Standard compilation environment does support neither autotools nor make;
|
| 149 |
in fact, very few common utilities are available. As a consequence, the
|
| 150 |
config-os400.h has been coded manually and the compilation scripts are
|
| 151 |
a set of shell scripts stored in subdirectory packages/OS400.
|
| 152 |
|
| 153 |
The "curl" command and the test environment are currently not supported on
|
| 154 |
OS/400.
|
| 155 |
|
| 156 |
|
| 157 |
Protocols currently implemented on OS/400:
|
| 158 |
_ HTTP
|
| 159 |
_ HTTPS
|
| 160 |
_ FTP
|
| 161 |
_ FTPS
|
| 162 |
_ FTP with secure transmission.
|
| 163 |
_ LDAP
|
| 164 |
_ DICT
|
| 165 |
_ TELNET
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
Compiling on OS/400:
|
| 170 |
|
| 171 |
These instructions targets people who knows about OS/400, compiling, IFS and
|
| 172 |
archive extraction. Do not ask questions about these subjects if you're not
|
| 173 |
familiar with.
|
| 174 |
|
| 175 |
_ As a prerequisite, QADRT development environment must be installed.
|
| 176 |
_ Install the curl source directory in IFS.
|
| 177 |
_ Enter shell (QSH)
|
| 178 |
_ Change current directory to the curl installation directory
|
| 179 |
_ Change current directory to ./packages/OS400
|
| 180 |
_ Edit file iniscript.sh. You may want to change tunable configuration
|
| 181 |
parameters, like debug info generation, optimisation level, listing option,
|
| 182 |
target library, etc.
|
| 183 |
_ Copy any file in the current directory to makelog (i.e.:
|
| 184 |
cp initscript.sh makelog): this is intended to create the makelog file with
|
| 185 |
an ASCII CCSID!
|
| 186 |
_ Enter the command "sh makefile.sh > makelog 2>&1'
|
| 187 |
_ Examine the makelog file to check for compilation errors.
|
| 188 |
|
| 189 |
Leaving file initscript.sh unchanged, this will produce the following OS/400
|
| 190 |
objects:
|
| 191 |
_ Library CURL. All other objects will be stored in this library.
|
| 192 |
_ Modules for all libcurl units.
|
| 193 |
_ Binding directory CURL_A, to be used at calling program link time for
|
| 194 |
statically binding the modules (specify BNDSRVPGM(QADRTTS QGLDCLNT QGLDBRDR)
|
| 195 |
when creating a program using CURL_A).
|
| 196 |
_ Service program CURL.<soname>, where <soname> is extracted from the
|
| 197 |
lib/Makefile.am VERSION variable. To be used at calling program run-time
|
| 198 |
when this program has dynamically bound curl at link time.
|
| 199 |
_ Binding directory CURL. To be used to dynamically bind libcurl when linking a
|
| 200 |
calling program.
|
| 201 |
_ Source file H. It contains all the include members needed to compile a C/C++
|
| 202 |
module using libcurl, and an ILE/RPG /copy member for support in this
|
| 203 |
language.
|
| 204 |
_ Standard C/C++ libcurl include members in file H.
|
| 205 |
_ CCSIDCURL member in file H. This defines the non-standard EBCDIC wrappers for
|
| 206 |
C and C++.
|
| 207 |
_ CURL.INC member in file H. This defines everything needed by an ILE/RPG
|
| 208 |
program using libcurl.
|
| 209 |
_ LIBxxx modules and programs. Although the test environment is not supported
|
| 210 |
on OS/400, the libcurl test programs are compiled for manual tests.
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
Special programming consideration:
|
| 215 |
|
| 216 |
QADRT being used, the following points must be considered:
|
| 217 |
_ If static binding is used, service program QADRTTS must be linked too.
|
| 218 |
_ The EBCDIC CCSID used by QADRT is 37 by default, NOT THE JOB'S CCSID. If
|
| 219 |
another EBCDIC CCSID is required, it must be set via a locale through a call
|
| 220 |
to setlocale_a (QADRT's setlocale() ASCII wrapper) with category LC_ALL or
|
| 221 |
LC_CTYPE, or by setting environment variable QADRT_ENV_LOCALE to the locale
|
| 222 |
object path before executing the program.
|
| 223 |
_ Do not use original source include files unless you know what you are doing.
|
| 224 |
Use the installed members instead (in /QSYS.LIB/CURL.LIB/H.FILE).
|
| 225 |
|
| 226 |
|
| 227 |
|
| 228 |
ILE/RPG support:
|
| 229 |
|
| 230 |
Since 95% of the OS/400 programmers use ILE/RPG exclusively, a definition
|
| 231 |
/COPY member is provided for this language. To include all libcurl
|
| 232 |
definitions in an ILE/RPG module, line
|
| 233 |
|
| 234 |
h bnddir('CURL/CURL')
|
| 235 |
|
| 236 |
must figure in the program header, and line
|
| 237 |
|
| 238 |
d/copy curl/h,curl.inc
|
| 239 |
|
| 240 |
in the global data section of the module's source code.
|
| 241 |
|
| 242 |
No vararg procedure support exists in ILE/RPG: for this reason, the following
|
| 243 |
considerations apply:
|
| 244 |
_ Procedures curl_easy_setopt_long(), curl_easy_setopt_object(),
|
| 245 |
curl_easy_setopt_function() and curl_easy_setopt_offset() are all alias
|
| 246 |
prototypes to curl_easy_setopt(), but with different parameter lists.
|
| 247 |
_ Procedures curl_easy_getinfo_string(), curl_easy_getinfo_long(),
|
| 248 |
curl_easy_getinfo_double() and curl_easy_getinfo_slist() are all alias
|
| 249 |
prototypes to curl_easy_getinfo(), but with different parameter lists.
|
| 250 |
_ Procedures curl_multi_setopt_long(), curl_multi_setopt_object(),
|
| 251 |
curl_multi_setopt_function() and curl_multi_setopt_offset() are all alias
|
| 252 |
prototypes to curl_multi_setopt(), but with different parameter lists.
|
| 253 |
_ The prototype of procedure curl_formadd() allows specifying a pointer option
|
| 254 |
and the CURLFORM_END option. This makes possible to use an option array
|
| 255 |
without any additional definition. If some specific incompatible argument
|
| 256 |
list is used in the ILE/RPG program, the latter must define a specialised
|
| 257 |
alias. The same applies to curl_formadd_ccsid() too.
|
| 258 |
|
| 259 |
Since RPG cannot cast a long to a pointer, procedure curl_form_long_value()
|
| 260 |
is provided for that purpose: this allows storing a long value in the curl_forms
|
| 261 |
array.
|