Return to README.OS400 CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / packages / OS400 |
1.1 ! misho 1: ! 2: Implementation notes: ! 3: ! 4: This is a true OS/400 implementation, not a PASE implementation (for PASE, ! 5: use AIX implementation). ! 6: ! 7: The biggest problem with OS/400 is EBCDIC. Libcurl implements an internal ! 8: conversion mechanism, but it has been designed for computers that have a ! 9: single native character set. OS/400 default native character set varies ! 10: depending on the country for which it has been localized. And more, a job ! 11: may dynamically alter its "native" character set. ! 12: Several characters that do not have fixed code in EBCDIC variants are ! 13: used in libcurl strings. As a consequence, using the existing conversion ! 14: mechanism would have lead in a localized binary library - not portable across ! 15: countries. ! 16: For this reason, and because libcurl was originally designed for ASCII based ! 17: operating systems, the current OS/400 implementation uses ASCII as internal ! 18: character set. This has been accomplished using the QADRT library and ! 19: include files, a C and system procedures ASCII wrapper library. See IBM QADRT ! 20: description for more information. ! 21: This then results in libcurl being an ASCII library: any function string ! 22: argument is taken/returned in ASCII and a C/C++ calling program built around ! 23: QADRT may use libcurl functions as on any other platform. ! 24: QADRT does not define ASCII wrappers for all C/system procedures: the ! 25: OS/400 configuration header file and an additional module (os400sys.c) define ! 26: some more of them, that are used by libcurl and that QADRT left out. ! 27: To support all the different variants of EBCDIC, non-standard wrapper ! 28: procedures have been added to libcurl on OS/400: they provide an additional ! 29: CCSID (numeric Coded Character Set ID specific to OS/400) parameter for each ! 30: string argument. String values passed to callback procedures are NOT converted, ! 31: so text gathered this way is (probably !) ASCII. ! 32: ! 33: Another OS/400 problem comes from the fact that the last fixed argument of a ! 34: vararg procedure may not be of type char, unsigned char, short or unsigned ! 35: short. Enums that are internally implemented by the C compiler as one of these ! 36: types are also forbidden. Libcurl uses enums as vararg procedure tagfields... ! 37: Happily, there is a pragma forcing enums to type "int". The original libcurl ! 38: header files are thus altered during build process to use this pragma, in ! 39: order to force libcurl enums of being type int (the pragma disposition in use ! 40: before inclusion is restored before resuming the including unit compilation). ! 41: ! 42: Secure socket layer is provided by the IBM GSKit API: unlike other SSL ! 43: implementations, GSKit is based on "certificate stores" or keyrings ! 44: rather than individual certificate/key files. Certificate stores, as well as ! 45: "certificate labels" are managed by external IBM-defined applications. ! 46: There are two ways to specify an SSL context: ! 47: - By an application identifier. ! 48: - By a keyring file pathname and (optionally) certificate label. ! 49: To identify an SSL context by application identifier, use option ! 50: SETOPT_SSLCERT to specify the application identifier. ! 51: To address an SSL context by keyring and certificate label, use CURLOPT_CAINFO ! 52: to set-up the keyring pathname, CURLOPT_SSLCERT to define the certificate label ! 53: (omitting it will cause the default certificate in keyring to be used) and ! 54: CURLOPT_KEYPASSWD to give the keyring password. If SSL is used without ! 55: defining any of these options, the default (i.e.: system) keyring is used for ! 56: server certificate validation. ! 57: ! 58: Non-standard EBCDIC wrapper prototypes are defined in an additional header ! 59: file: ccsidcurl.h. These should be self-explanatory to an OS/400-aware ! 60: designer. CCSID 0 can be used to select the current job's CCSID. ! 61: Wrapper procedures with variable arguments are described below: ! 62: ! 63: _ curl_easy_setopt_ccsid() ! 64: Variable arguments are a string pointer and a CCSID (unsigned int) for ! 65: options: ! 66: CURLOPT_ABSTRACT_UNIX_SOCKET ! 67: CURLOPT_ALTSVC ! 68: CURLOPT_CAINFO ! 69: CURLOPT_CAPATH ! 70: CURLOPT_COOKIE ! 71: CURLOPT_COOKIEFILE ! 72: CURLOPT_COOKIEJAR ! 73: CURLOPT_COOKIELIST ! 74: CURLOPT_COPYPOSTFIELDS ! 75: CURLOPT_CRLFILE ! 76: CURLOPT_CUSTOMREQUEST ! 77: CURLOPT_DEFAULT_PROTOCOL ! 78: CURLOPT_DNS_SERVERS ! 79: CURLOPT_DOH_URL ! 80: CURLOPT_EGDSOCKET ! 81: CURLOPT_ENCODING ! 82: CURLOPT_FTPPORT ! 83: CURLOPT_FTP_ACCOUNT ! 84: CURLOPT_FTP_ALTERNATIVE_TO_USER ! 85: CURLOPT_INTERFACE ! 86: CURLOPT_ISSUERCERT ! 87: CURLOPT_KEYPASSWD ! 88: CURLOPT_KRBLEVEL ! 89: CURLOPT_LOGIN_OPTIONS ! 90: CURLOPT_MAIL_AUTH ! 91: CURLOPT_MAIL_FROM ! 92: CURLOPT_NETRC_FILE ! 93: CURLOPT_NOPROXY ! 94: CURLOPT_PASSWORD ! 95: CURLOPT_PINNEDPUBLICKEY ! 96: CURLOPT_PRE_PROXY ! 97: CURLOPT_PROXY ! 98: CURLOPT_PROXYPASSWORD ! 99: CURLOPT_PROXYUSERNAME ! 100: CURLOPT_PROXYUSERPWD ! 101: CURLOPT_PROXY_CAINFO ! 102: CURLOPT_PROXY_CAPATH ! 103: CURLOPT_PROXY_CRLFILE ! 104: CURLOPT_PROXY_KEYPASSWD ! 105: CURLOPT_PROXY_PINNEDPUBLICKEY ! 106: CURLOPT_PROXY_SERVICE_NAME ! 107: CURLOPT_PROXY_SSLCERT ! 108: CURLOPT_PROXY_SSLCERTTYPE ! 109: CURLOPT_PROXY_SSLKEY ! 110: CURLOPT_PROXY_SSLKEYTYPE ! 111: CURLOPT_PROXY_SSL_CIPHER_LIST ! 112: CURLOPT_PROXY_TLS13_CIPHERS ! 113: CURLOPT_PROXY_TLSAUTH_PASSWORD ! 114: CURLOPT_PROXY_TLSAUTH_TYPE ! 115: CURLOPT_PROXY_TLSAUTH_USERNAME ! 116: CURLOPT_RANDOM_FILE ! 117: CURLOPT_RANGE ! 118: CURLOPT_REFERER ! 119: CURLOPT_REQUEST_TARGET ! 120: CURLOPT_RTSP_SESSION_UID ! 121: CURLOPT_RTSP_STREAM_URI ! 122: CURLOPT_RTSP_TRANSPORT ! 123: CURLOPT_SASL_AUTHZID ! 124: CURLOPT_SERVICE_NAME ! 125: CURLOPT_SOCKS5_GSSAPI_SERVICE ! 126: CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 ! 127: CURLOPT_SSH_KNOWNHOSTS ! 128: CURLOPT_SSH_PRIVATE_KEYFILE ! 129: CURLOPT_SSH_PUBLIC_KEYFILE ! 130: CURLOPT_SSLCERT ! 131: CURLOPT_SSLCERTTYPE ! 132: CURLOPT_SSLENGINE ! 133: CURLOPT_SSLKEY ! 134: CURLOPT_SSLKEYTYPE ! 135: CURLOPT_SSL_CIPHER_LIST ! 136: CURLOPT_TLS13_CIPHERS ! 137: CURLOPT_TLSAUTH_PASSWORD ! 138: CURLOPT_TLSAUTH_TYPE ! 139: CURLOPT_TLSAUTH_USERNAME ! 140: CURLOPT_UNIX_SOCKET_PATH ! 141: CURLOPT_URL ! 142: CURLOPT_USERAGENT ! 143: CURLOPT_USERNAME ! 144: CURLOPT_USERPWD ! 145: CURLOPT_XOAUTH2_BEARER ! 146: Else it is the same as for curl_easy_setopt(). ! 147: Note that CURLOPT_ERRORBUFFER is not in the list above, since it gives the ! 148: address of an (empty) character buffer, not the address of a string. ! 149: CURLOPT_POSTFIELDS stores the address of static binary data (of type void *) and ! 150: thus is not converted. If CURLOPT_COPYPOSTFIELDS is issued after ! 151: CURLOPT_POSTFIELDSIZE != -1, the data size is adjusted according to the ! 152: CCSID conversion result length. ! 153: ! 154: _ curl_formadd_ccsid() ! 155: In the variable argument list, string pointers should be followed by a (long) ! 156: CCSID for the following options: ! 157: CURLFORM_FILENAME ! 158: CURLFORM_CONTENTTYPE ! 159: CURLFORM_BUFFER ! 160: CURLFORM_FILE ! 161: CURLFORM_FILECONTENT ! 162: CURLFORM_COPYCONTENTS ! 163: CURLFORM_COPYNAME ! 164: CURLFORM_PTRNAME ! 165: If taken from an argument array, an additional array entry must follow each ! 166: entry containing one of the above option. This additional entry holds the CCSID ! 167: in its value field, and the option field is meaningless. ! 168: It is not possible to have a string pointer and its CCSID across a function ! 169: parameter/array boundary. ! 170: Please note that CURLFORM_PTRCONTENTS and CURLFORM_BUFFERPTR are considered ! 171: unconvertible strings and thus are NOT followed by a CCSID. ! 172: ! 173: _ curl_easy_getinfo_ccsid() ! 174: The following options are followed by a 'char * *' and a CCSID. Unlike ! 175: curl_easy_getinfo(), the value returned in the pointer should be freed after ! 176: use: ! 177: CURLINFO_EFFECTIVE_URL ! 178: CURLINFO_CONTENT_TYPE ! 179: CURLINFO_FTP_ENTRY_PATH ! 180: CURLINFO_REDIRECT_URL ! 181: CURLINFO_PRIMARY_IP ! 182: CURLINFO_RTSP_SESSION_ID ! 183: CURLINFO_LOCAL_IP ! 184: CURLINFO_SCHEME ! 185: Likewise, the following options are followed by a struct curl_slist * * and a ! 186: CCSID. ! 187: CURLINFO_SSL_ENGINES ! 188: CURLINFO_COOKIELIST ! 189: Lists returned should be released with curl_slist_free_all() after use. ! 190: Option CURLINFO_CERTINFO is followed by a struct curl_certinfo * * and a ! 191: CCSID. Returned structures should be free'ed using curl_certinfo_free_all() ! 192: after use. ! 193: Other options are processed like in curl_easy_getinfo(). ! 194: ! 195: _ curl_pushheader_bynum_cssid() and curl_pushheader_byname_ccsid() ! 196: Although the prototypes are self-explanatory, the returned string pointer ! 197: should be freed after use, as opposite to the non-ccsid versions of these ! 198: procedures. ! 199: Please note that HTTP2 is not (yet) implemented on OS/400, thus these ! 200: functions will always return NULL. ! 201: ! 202: ! 203: Standard compilation environment does support neither autotools nor make; ! 204: in fact, very few common utilities are available. As a consequence, the ! 205: config-os400.h has been coded manually and the compilation scripts are ! 206: a set of shell scripts stored in subdirectory packages/OS400. ! 207: ! 208: The "curl" command and the test environment are currently not supported on ! 209: OS/400. ! 210: ! 211: ! 212: Protocols currently implemented on OS/400: ! 213: _ DICT ! 214: _ FILE ! 215: _ FTP ! 216: _ FTPS ! 217: _ FTP with secure transmission ! 218: _ GOPHER ! 219: _ HTTP ! 220: _ HTTPS ! 221: _ IMAP ! 222: _ IMAPS ! 223: _ IMAP with secure transmission ! 224: _ LDAP ! 225: _ POP3 ! 226: _ POP3S ! 227: _ POP3 with secure transmission ! 228: _ RTSP ! 229: _ SCP if libssh2 is enabled ! 230: _ SFTP if libssh2 is enabled ! 231: _ SMTP ! 232: _ SMTPS ! 233: _ SMTP with secure transmission ! 234: _ TELNET ! 235: _ TFTP ! 236: ! 237: ! 238: ! 239: Compiling on OS/400: ! 240: ! 241: These instructions targets people who knows about OS/400, compiling, IFS and ! 242: archive extraction. Do not ask questions about these subjects if you're not ! 243: familiar with. ! 244: ! 245: _ As a prerequisite, QADRT development environment must be installed. ! 246: _ If data compression has to be supported, ZLIB development environment must ! 247: be installed. ! 248: _ Likewise, if SCP and SFTP protocols have to be compiled in, LIBSSH2 ! 249: developent environment must be installed. ! 250: _ Install the curl source directory in IFS. Do NOT install it in the ! 251: installation target directory (which defaults to /curl). ! 252: _ Enter shell (QSH) ! 253: _ Change current directory to the curl installation directory ! 254: _ Change current directory to ./packages/OS400 ! 255: _ Edit file iniscript.sh. You may want to change tunable configuration ! 256: parameters, like debug info generation, optimisation level, listing option, ! 257: target library, ZLIB/LIBSSH2 availability and location, etc. ! 258: _ Copy any file in the current directory to makelog (i.e.: ! 259: cp initscript.sh makelog): this is intended to create the makelog file with ! 260: an ASCII CCSID! ! 261: _ Enter the command "sh makefile.sh > makelog 2>&1' ! 262: _ Examine the makelog file to check for compilation errors. ! 263: ! 264: Leaving file initscript.sh unchanged, this will produce the following OS/400 ! 265: objects: ! 266: _ Library CURL. All other objects will be stored in this library. ! 267: _ Modules for all libcurl units. ! 268: _ Binding directory CURL_A, to be used at calling program link time for ! 269: statically binding the modules (specify BNDSRVPGM(QADRTTS QGLDCLNT QGLDBRDR) ! 270: when creating a program using CURL_A). ! 271: _ Service program CURL.<soname>, where <soname> is extracted from the ! 272: lib/Makefile.am VERSION variable. To be used at calling program run-time ! 273: when this program has dynamically bound curl at link time. ! 274: _ Binding directory CURL. To be used to dynamically bind libcurl when linking a ! 275: calling program. ! 276: _ Source file H. It contains all the include members needed to compile a C/C++ ! 277: module using libcurl, and an ILE/RPG /copy member for support in this ! 278: language. ! 279: _ Standard C/C++ libcurl include members in file H. ! 280: _ CCSIDCURL member in file H. This defines the non-standard EBCDIC wrappers for ! 281: C and C++. ! 282: _ CURL.INC member in file H. This defines everything needed by an ILE/RPG ! 283: program using libcurl. ! 284: _ LIBxxx modules and programs. Although the test environment is not supported ! 285: on OS/400, the libcurl test programs are compiled for manual tests. ! 286: _ IFS directory /curl/include/curl containing the C header files for IFS source ! 287: C/C++ compilation and curl.inc.rpgle for IFS source ILE/RPG compilation. ! 288: ! 289: ! 290: ! 291: Special programming consideration: ! 292: ! 293: QADRT being used, the following points must be considered: ! 294: _ If static binding is used, service program QADRTTS must be linked too. ! 295: _ The EBCDIC CCSID used by QADRT is 37 by default, NOT THE JOB'S CCSID. If ! 296: another EBCDIC CCSID is required, it must be set via a locale through a call ! 297: to setlocale_a (QADRT's setlocale() ASCII wrapper) with category LC_ALL or ! 298: LC_CTYPE, or by setting environment variable QADRT_ENV_LOCALE to the locale ! 299: object path before executing the program. ! 300: _ Do not use original source include files unless you know what you are doing. ! 301: Use the installed members instead (in /QSYS.LIB/CURL.LIB/H.FILE and ! 302: /curl/include/curl). ! 303: ! 304: ! 305: ! 306: ILE/RPG support: ! 307: ! 308: Since 95% of the OS/400 programmers use ILE/RPG exclusively, a definition ! 309: /INCLUDE member is provided for this language. To include all libcurl ! 310: definitions in an ILE/RPG module, line ! 311: ! 312: h bnddir('CURL/CURL') ! 313: ! 314: must figure in the program header, and line ! 315: ! 316: d/include curl/h,curl.inc ! 317: ! 318: in the global data section of the module's source code. ! 319: ! 320: No vararg procedure support exists in ILE/RPG: for this reason, the following ! 321: considerations apply: ! 322: _ Procedures curl_easy_setopt_long(), curl_easy_setopt_object(), ! 323: curl_easy_setopt_function() and curl_easy_setopt_offset() are all alias ! 324: prototypes to curl_easy_setopt(), but with different parameter lists. ! 325: _ Procedures curl_easy_getinfo_string(), curl_easy_getinfo_long(), ! 326: curl_easy_getinfo_double(), curl_easy_getinfo_slist(), ! 327: curl_easy_getinfo_ptr(), curl_easy_getinfo_socket() and ! 328: curl_easy_getinfo_off_t() are all alias prototypes to curl_easy_getinfo(), ! 329: but with different parameter lists. ! 330: _ Procedures curl_multi_setopt_long(), curl_multi_setopt_object(), ! 331: curl_multi_setopt_function() and curl_multi_setopt_offset() are all alias ! 332: prototypes to curl_multi_setopt(), but with different parameter lists. ! 333: _ The prototype of procedure curl_formadd() allows specifying a pointer option ! 334: and the CURLFORM_END option. This makes possible to use an option array ! 335: without any additional definition. If some specific incompatible argument ! 336: list is used in the ILE/RPG program, the latter must define a specialised ! 337: alias. The same applies to curl_formadd_ccsid() too. ! 338: ! 339: Since RPG cannot cast a long to a pointer, procedure curl_form_long_value() ! 340: is provided for that purpose: this allows storing a long value in the curl_forms ! 341: array.