aboutsummaryrefslogtreecommitdiff
path: root/packages/OS400
diff options
context:
space:
mode:
Diffstat (limited to 'packages/OS400')
-rw-r--r--packages/OS400/README.OS4006
-rw-r--r--packages/OS400/ccsidcurl.c71
2 files changed, 74 insertions, 3 deletions
diff --git a/packages/OS400/README.OS400 b/packages/OS400/README.OS400
index eb5b940ac..3dad3ab5d 100644
--- a/packages/OS400/README.OS400
+++ b/packages/OS400/README.OS400
@@ -81,7 +81,7 @@ options:
CURLOPT_KEYPASSWD
CURLOPT_KRBLEVEL
CURLOPT_NETRC_FILE
- CURLOPT_POSTFIELDS
+ CURLOPT_COPYPOSTFIELDS
CURLOPT_PROXY
CURLOPT_PROXYUSERPWD
CURLOPT_RANDOM_FILE
@@ -102,6 +102,10 @@ options:
Else it is the same as for 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)
diff --git a/packages/OS400/ccsidcurl.c b/packages/OS400/ccsidcurl.c
index ad8f0fa7c..78ff74d95 100644
--- a/packages/OS400/ccsidcurl.c
+++ b/packages/OS400/ccsidcurl.c
@@ -40,8 +40,13 @@
#include "os400sys.h"
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t) ~0) /* Is unsigned on OS/400. */
+#endif
+
#define ASCII_CCSID 819 /* Use ISO-8859-1 as ASCII. */
+#define NOCONV_CCSID 65535 /* No conversion. */
#define ICONV_ID_SIZE 32 /* Size of iconv_open() code identifier. */
#define ICONV_OPEN_ERROR(t) ((t).return_value == -1)
@@ -62,7 +67,7 @@ makeOS400IconvCode(char buf[ICONV_ID_SIZE], unsigned int ccsid)
ccsid &= 0xFFFF;
- if (ccsid == 65535)
+ if (ccsid == NOCONV_CCSID)
ccsid = ASCII_CCSID;
memset(buf, 0, ICONV_ID_SIZE);
@@ -1004,7 +1009,10 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
va_list arg;
struct SessionHandle * data;
char * s;
+ char * cp;
unsigned int ccsid;
+ size_t len;
+ curl_off_t pfsize;
static char testwarn = 1;
/* Warns if this procedure has not been updated when the dupstring enum
@@ -1042,7 +1050,6 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
case CURLOPT_KEYPASSWD:
case CURLOPT_KRBLEVEL:
case CURLOPT_NETRC_FILE:
- case CURLOPT_POSTFIELDS:
case CURLOPT_PROXY:
case CURLOPT_PROXYUSERPWD:
case CURLOPT_RANDOM_FILE:
@@ -1079,6 +1086,66 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
break;
+ case CURLOPT_COPYPOSTFIELDS:
+ /* Special case: byte count may have been given by CURLOPT_POSTFIELDSIZE
+ prior to this call. In this case, convert the given byte count and
+ replace the length according to the conversion result. */
+ s = va_arg(arg, char *);
+ ccsid = va_arg(arg, unsigned int);
+
+ pfsize = data->set.postfieldsize;
+
+ if (!s || !pfsize || ccsid == NOCONV_CCSID || ccsid == ASCII_CCSID) {
+ result = curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, s);
+ break;
+ }
+
+ if (pfsize == -1) {
+ /* Data is null-terminated. */
+ s = dynconvert(ASCII_CCSID, s, -1, ccsid);
+
+ if (!s) {
+ result = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+ }
+ else {
+ /* Data length specified. */
+
+ if (pfsize < 0 || pfsize > SIZE_MAX) {
+ result = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+
+ len = pfsize;
+ pfsize = len * MAX_CONV_EXPANSION;
+
+ if (pfsize > SIZE_MAX)
+ pfsize = SIZE_MAX;
+
+ cp = malloc(pfsize);
+
+ if (!cp) {
+ result = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+
+ pfsize = convert(cp, pfsize, ASCII_CCSID, s, len, ccsid);
+
+ if (pfsize < 0) {
+ free(cp);
+ result = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+
+ data->set.postfieldsize = pfsize; /* Replace data size. */
+ s = cp;
+ }
+
+ result = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, s);
+ data->set.str[STRING_COPYPOSTFIELDS] = s; /* Give to library. */
+ break;
+
case CURLOPT_ERRORBUFFER: /* This is an output buffer. */
default:
result = Curl_setopt(data, tag, arg);