📄 ccsidcurl.c
字号:
va_start(arg, info); paramp = va_arg(arg, void *); ret = Curl_getinfo(data, info, paramp); if (ret != CURLE_OK || ((int) info & CURLINFO_TYPEMASK) != CURLINFO_STRING) { va_end(arg); return ret; } ccsid = va_arg(arg, unsigned int); va_end(arg); cpp = (char * *) paramp; s = *cpp; if (!s) return ret; d = dynconvert(ccsid, s, -1, ASCII_CCSID); *cpp = d; if (!d) return CURLE_OUT_OF_MEMORY; return ret;}static intCurl_is_formadd_string(CURLformoption option){ switch (option) { case CURLFORM_FILENAME: case CURLFORM_CONTENTTYPE: case CURLFORM_BUFFER: case CURLFORM_FILE: case CURLFORM_FILECONTENT: case CURLFORM_COPYCONTENTS: case CURLFORM_COPYNAME: return 1; } return 0;}static voidCurl_formadd_release_local(struct curl_forms * forms, int nargs, int skip){ while (nargs--) if (nargs != skip) if (Curl_is_formadd_string(forms[nargs].option)) if (forms[nargs].value) free((char *) forms[nargs].value); free((char *) forms);}static intCurl_formadd_convert(struct curl_forms * forms, int formx, int lengthx, unsigned int ccsid){ int l; char * cp; char * cp2; if (formx < 0 || !forms[formx].value) return 0; if (lengthx >= 0) l = (int) forms[lengthx].value; else l = strlen(forms[formx].value) + 1; cp = malloc(MAX_CONV_EXPANSION * l); if (!cp) return -1; l = convert(cp, MAX_CONV_EXPANSION * l, ASCII_CCSID, forms[formx].value, l, ccsid); if (l < 0) { free(cp); return -1; } cp2 = realloc(cp, l); /* Shorten buffer to the string size. */ if (cp2) cp = cp2; forms[formx].value = cp; if (lengthx >= 0) forms[lengthx].value = (char *) l; /* Update to length after conversion. */ return l;}CURLFORMcodecurl_formadd_ccsid(struct curl_httppost * * httppost, struct curl_httppost * * last_post, ...){ va_list arg; CURLformoption option; CURLFORMcode result; struct curl_forms * forms; struct curl_forms * lforms; struct curl_forms * tforms; unsigned int lformlen; const char * value; unsigned int ccsid; int nargs; int namex; int namelengthx; int contentx; int lengthx; unsigned int contentccsid; unsigned int nameccsid; /* A single curl_formadd() call cannot be splitted in several calls to deal with all parameters: the original parameters are thus copied to a local curl_forms array and converted to ASCII when needed. CURLFORM_PTRNAME is processed as if it were CURLFORM_COPYNAME. CURLFORM_COPYNAME and CURLFORM_NAMELENGTH occurrence order in parameters is not defined; for this reason, the actual conversion is delayed to the end of parameter processing. The same applies to CURLFORM_COPYCONTENTS/CURLFORM_CONTENTSLENGTH, but these may appear several times in the parameter list; the problem resides here in knowing which CURLFORM_CONTENTSLENGTH applies to which CURLFORM_COPYCONTENTS and when we can be sure to have both info for conversion: end of parameter list is such a point, but CURLFORM_CONTENTTYPE is also used here as a natural separator between content data definitions; this seems to be in accordance with FormAdd() behavior. */ /* Allocate the local curl_forms array. */ lformlen = ALLOC_GRANULE; lforms = (struct curl_forms *) malloc(lformlen * sizeof * lforms); if (!lforms) return CURL_FORMADD_MEMORY; /* Process the arguments, copying them into local array, latching conversion indexes and converting when needed. */ result = CURL_FORMADD_OK; nargs = 0; contentx = -1; lengthx = -1; namex = -1; namelengthx = -1; forms = (struct curl_forms *) NULL; va_start(arg, last_post); for (;;) { /* Make sure there is still room for an item in local array. */ if (nargs >= lformlen) { lformlen += ALLOC_GRANULE; tforms = (struct curl_forms *) realloc((char *) lforms, lformlen * sizeof *lforms); if (!tforms) { result = CURL_FORMADD_MEMORY; break; } lforms = tforms; } /* Get next option. */ if (forms) { /* Get option from array. */ option = forms->option; value = forms->value; forms++; } else { /* Get option from arguments. */ option = va_arg(arg, CURLformoption); if (option == CURLFORM_END) break; } /* Dispatch by option. */ switch (option) { case CURLFORM_END: forms = (struct curl_forms *) NULL; /* Leave array mode. */ continue; case CURLFORM_ARRAY: if (!forms) { forms = va_arg(arg, struct curl_forms *); continue; } result = CURL_FORMADD_ILLEGAL_ARRAY; break; case CURLFORM_COPYNAME: option = CURLFORM_PTRNAME; /* Static for now. */ case CURLFORM_PTRNAME: if (namex >= 0) result = CURL_FORMADD_OPTION_TWICE; namex = nargs; if (!forms) { value = va_arg(arg, char *); nameccsid = (unsigned int) va_arg(arg, long); } else { nameccsid = (unsigned int) forms->value; forms++; } break; case CURLFORM_COPYCONTENTS: if (contentx >= 0) result = CURL_FORMADD_OPTION_TWICE; contentx = nargs; if (!forms) { value = va_arg(arg, char *); contentccsid = (unsigned int) va_arg(arg, long); } else { contentccsid = (unsigned int) forms->value; forms++; } break; case CURLFORM_PTRCONTENTS: case CURLFORM_BUFFERPTR: if (!forms) value = va_arg(arg, char *); /* No conversion. */ break; case CURLFORM_CONTENTSLENGTH: lengthx = nargs; if (!forms) value = (char *) va_arg(arg, long); break; case CURLFORM_NAMELENGTH: namelengthx = nargs; if (!forms) value = (char *) va_arg(arg, long); break; case CURLFORM_BUFFERLENGTH: if (!forms) value = (char *) va_arg(arg, long); break; case CURLFORM_CONTENTHEADER: if (!forms) value = (char *) va_arg(arg, struct curl_slist *); break; case CURLFORM_CONTENTTYPE: /* If a previous content has been encountered, convert it now. */ if (Curl_formadd_convert(lforms, contentx, lengthx, contentccsid) < 0) { result = CURL_FORMADD_MEMORY; break; } contentx = -1; lengthx = -1; /* Fall into default. */ default: /* Must be a convertible string. */ if (!Curl_is_formadd_string(option)) { result = CURL_FORMADD_UNKNOWN_OPTION; break; } if (!forms) { value = va_arg(arg, char *); ccsid = (unsigned int) va_arg(arg, long); } else { ccsid = (unsigned int) forms->value; forms++; } /* Do the conversion. */ lforms[nargs].value = value; if (Curl_formadd_convert(lforms, nargs, -1, ccsid) < 0) { result = CURL_FORMADD_MEMORY; break; } value = lforms[nargs].value; } if (result != CURL_FORMADD_OK) break; lforms[nargs].value = value; lforms[nargs++].option = option; } va_end(arg); /* Convert the name and the last content, now that we know their lengths. */ if (result == CURL_FORMADD_OK && namex >= 0) { if (Curl_formadd_convert(lforms, namex, namelengthx, nameccsid) < 0) result = CURL_FORMADD_MEMORY; else lforms[namex].option = CURLFORM_COPYNAME; /* Force copy. */ } if (result == CURL_FORMADD_OK) { if (Curl_formadd_convert(lforms, contentx, lengthx, contentccsid) < 0) result = CURL_FORMADD_MEMORY; else contentx = -1; } /* Do the formadd with our converted parameters. */ if (result == CURL_FORMADD_OK) { lforms[nargs].option = CURLFORM_END; result = curl_formadd(httppost, last_post, CURLFORM_ARRAY, lforms, CURLFORM_END); } /* Terminate. */ Curl_formadd_release_local(lforms, nargs, contentx); return result;}typedef struct { curl_formget_callback append; void * arg; unsigned int ccsid;} cfcdata;static size_tCurl_formget_callback_ccsid(void * arg, const char * buf, size_t len){ cfcdata * p; char * b; int l; size_t ret; p = (cfcdata *) arg; if ((long) len <= 0) return (*p->append)(p->arg, buf, len); b = malloc(MAX_CONV_EXPANSION * len); if (!b) return (size_t) -1; l = convert(b, MAX_CONV_EXPANSION * len, p->ccsid, buf, len, ASCII_CCSID); if (l < 0) { free(b); return (size_t) -1; } ret = (*p->append)(p->arg, b, l); free(b); return ret == l? len: -1;}intcurl_formget_ccsid(struct curl_httppost * form, void * arg, curl_formget_callback append, unsigned int ccsid){ cfcdata lcfc; lcfc.append = append; lcfc.arg = arg; lcfc.ccsid = ccsid; return curl_formget(form, (void *) &lcfc, Curl_formget_callback_ccsid);}CURLcodecurl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...){ CURLcode result; 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 changes. We (try to) do it only once: there is no need to issue several times the same message; but since threadsafeness is not handled here, this may occur (and we don't care!). */ if (testwarn) { testwarn = 0; if ((int) STRING_LAST != (int) STRING_SSH_HOST_PUBLIC_KEY_MD5 + 1) curl_mfprintf(stderr, "*** WARNING: curl_easy_setopt_ccsid() should be reworked ***\n"); } data = (struct SessionHandle *) curl; va_start(arg, tag); switch (tag) { case CURLOPT_CAINFO: case CURLOPT_CAPATH: case CURLOPT_COOKIE: case CURLOPT_COOKIEFILE: case CURLOPT_COOKIEJAR: case CURLOPT_COOKIELIST: case CURLOPT_CUSTOMREQUEST: case CURLOPT_EGDSOCKET: case CURLOPT_ENCODING: case CURLOPT_FTPPORT: case CURLOPT_FTP_ACCOUNT: case CURLOPT_FTP_ALTERNATIVE_TO_USER: case CURLOPT_INTERFACE: case CURLOPT_KEYPASSWD: case CURLOPT_KRBLEVEL: case CURLOPT_NETRC_FILE: case CURLOPT_PROXY: case CURLOPT_PROXYUSERPWD: case CURLOPT_RANDOM_FILE: case CURLOPT_RANGE: case CURLOPT_REFERER: case CURLOPT_SSH_PRIVATE_KEYFILE: case CURLOPT_SSH_PUBLIC_KEYFILE: case CURLOPT_SSLCERT: case CURLOPT_SSLCERTTYPE: case CURLOPT_SSLENGINE: case CURLOPT_SSLKEY: case CURLOPT_SSLKEYTYPE: case CURLOPT_SSL_CIPHER_LIST: case CURLOPT_URL: case CURLOPT_USERAGENT: case CURLOPT_USERPWD: case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5: s = va_arg(arg, char *); ccsid = va_arg(arg, unsigned int); if (s) { s = dynconvert(ASCII_CCSID, s, -1, ccsid); if (!s) { result = CURLE_OUT_OF_MEMORY; break; } } result = curl_easy_setopt(curl, tag, s); if (s) free(s); 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); break; } va_end(arg); return result;}char *curl_form_long_value(long value){ /* ILE/RPG cannot cast an integer to a pointer. This procedure does it. */ return (char *) value;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -