00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <iconv.h>
00027 #include <string.h>
00028 #include <stdlib.h>
00029 #include <errno.h>
00030 #include <stdarg.h>
00031
00032 #pragma enum(int)
00033
00034 #include "curl.h"
00035 #include "mprintf.h"
00036 #include "slist.h"
00037 #include "urldata.h"
00038 #include "url.h"
00039 #include "getinfo.h"
00040 #include "ccsidcurl.h"
00041
00042 #include "os400sys.h"
00043
00044 #ifndef SIZE_MAX
00045 #define SIZE_MAX ((size_t) ~0)
00046 #endif
00047
00048
00049 #define ASCII_CCSID 819
00050 #define NOCONV_CCSID 65535
00051 #define ICONV_ID_SIZE 32
00052 #define ICONV_OPEN_ERROR(t) ((t).return_value == -1)
00053
00054 #define ALLOC_GRANULE 8
00055
00056
00057 static void
00058 makeOS400IconvCode(char buf[ICONV_ID_SIZE], unsigned int ccsid)
00059
00060 {
00069 ccsid &= 0xFFFF;
00070
00071 if(ccsid == NOCONV_CCSID)
00072 ccsid = ASCII_CCSID;
00073
00074 memset(buf, 0, ICONV_ID_SIZE);
00075 curl_msprintf(buf, "IBMCCSID%05u0000000", ccsid);
00076 }
00077
00078
00079 static iconv_t
00080 iconv_open_CCSID(unsigned int ccsidout, unsigned int ccsidin,
00081 unsigned int cstr)
00082
00083 {
00084 char fromcode[ICONV_ID_SIZE];
00085 char tocode[ICONV_ID_SIZE];
00086
00094 makeOS400IconvCode(fromcode, ccsidin);
00095 makeOS400IconvCode(tocode, ccsidout);
00096 memset(tocode + 13, 0, sizeof tocode - 13);
00097
00098 if(cstr)
00099 fromcode[18] = '1';
00100
00101 return iconv_open(tocode, fromcode);
00102 }
00103
00104
00105 static int
00106 convert(char * d, size_t dlen, int dccsid,
00107 const char * s, int slen, int sccsid)
00108
00109 {
00110 int i;
00111 iconv_t cd;
00112 size_t lslen;
00113
00122 if(sccsid == 65535)
00123 sccsid = ASCII_CCSID;
00124
00125 if(dccsid == 65535)
00126 dccsid = ASCII_CCSID;
00127
00128 if(sccsid == dccsid) {
00129 lslen = slen >= 0? slen: strlen(s) + 1;
00130 i = lslen < dlen? lslen: dlen;
00131
00132 if(s != d && i > 0)
00133 memcpy(d, s, i);
00134
00135 return i;
00136 }
00137
00138 if(slen < 0) {
00139 lslen = 0;
00140 cd = iconv_open_CCSID(dccsid, sccsid, 1);
00141 }
00142 else {
00143 lslen = (size_t) slen;
00144 cd = iconv_open_CCSID(dccsid, sccsid, 0);
00145 }
00146
00147 if(ICONV_OPEN_ERROR(cd))
00148 return -1;
00149
00150 i = dlen;
00151
00152 if((int) iconv(cd, (char * *) &s, &lslen, &d, &dlen) < 0)
00153 i = -1;
00154 else
00155 i -= dlen;
00156
00157 iconv_close(cd);
00158 return i;
00159 }
00160
00161
00162 static char *
00163 dynconvert(int dccsid, const char * s, int slen, int sccsid)
00164
00165 {
00166 char * d;
00167 char * cp;
00168 size_t dlen;
00169 int l;
00170 static const char nullbyte = 0;
00171
00172
00173
00174 dlen = (size_t) (slen < 0? strlen(s): slen) + 1;
00175 dlen *= MAX_CONV_EXPANSION;
00176 d = malloc(dlen);
00177
00178 if(!d)
00179 return (char *) NULL;
00180
00181 l = convert(d, dlen, dccsid, s, slen, sccsid);
00182
00183 if(l < 0) {
00184 free(d);
00185 return (char *) NULL;
00186 }
00187
00188 if(slen < 0) {
00189
00190
00191
00192
00193 int l2 = convert(d + l, dlen - l, dccsid, &nullbyte, -1, ASCII_CCSID);
00194
00195 if(l2 < 0) {
00196 free(d);
00197 return (char *) NULL;
00198 }
00199
00200 l += l2;
00201 }
00202
00203 if((size_t) l < dlen) {
00204 cp = realloc(d, l);
00205
00206 if(cp)
00207 d = cp;
00208 }
00209
00210 return d;
00211 }
00212
00213
00214 static struct curl_slist *
00215 slist_convert(int dccsid, struct curl_slist * from, int sccsid)
00216
00217 {
00218 struct curl_slist * to = (struct curl_slist *) NULL;
00219
00220 for(; from; from = from->next) {
00221 char * cp = dynconvert(dccsid, from->data, -1, sccsid);
00222
00223 if(!cp) {
00224 curl_slist_free_all(to);
00225 return (struct curl_slist *) NULL;
00226 }
00227 to = Curl_slist_append_nodup(to, cp);
00228 }
00229 return to;
00230 }
00231
00232
00233 char *
00234 curl_version_ccsid(unsigned int ccsid)
00235
00236 {
00237 int i;
00238 char * aversion;
00239 char * eversion;
00240
00241 aversion = curl_version();
00242
00243 if(!aversion)
00244 return aversion;
00245
00246 i = strlen(aversion) + 1;
00247 i *= MAX_CONV_EXPANSION;
00248
00249 if(!(eversion = Curl_thread_buffer(LK_CURL_VERSION, i)))
00250 return (char *) NULL;
00251
00252 if(convert(eversion, i, ccsid, aversion, -1, ASCII_CCSID) < 0)
00253 return (char *) NULL;
00254
00255 return eversion;
00256 }
00257
00258
00259 char *
00260 curl_easy_escape_ccsid(CURL * handle, const char * string, int length,
00261 unsigned int sccsid, unsigned int dccsid)
00262
00263 {
00264 char * s;
00265 char * d;
00266
00267 if(!string) {
00268 errno = EINVAL;
00269 return (char *) NULL;
00270 }
00271
00272 s = dynconvert(ASCII_CCSID, string, length? length: -1, sccsid);
00273
00274 if(!s)
00275 return (char *) NULL;
00276
00277 d = curl_easy_escape(handle, s, 0);
00278 free(s);
00279
00280 if(!d)
00281 return (char *) NULL;
00282
00283 s = dynconvert(dccsid, d, -1, ASCII_CCSID);
00284 free(d);
00285 return s;
00286 }
00287
00288
00289 char *
00290 curl_easy_unescape_ccsid(CURL * handle, const char * string, int length,
00291 int * outlength,
00292 unsigned int sccsid, unsigned int dccsid)
00293
00294 {
00295 char * s;
00296 char * d;
00297
00298 if(!string) {
00299 errno = EINVAL;
00300 return (char *) NULL;
00301 }
00302
00303 s = dynconvert(ASCII_CCSID, string, length? length: -1, sccsid);
00304
00305 if(!s)
00306 return (char *) NULL;
00307
00308 d = curl_easy_unescape(handle, s, 0, outlength);
00309 free(s);
00310
00311 if(!d)
00312 return (char *) NULL;
00313
00314 s = dynconvert(dccsid, d, -1, ASCII_CCSID);
00315 free(d);
00316
00317 if(s && outlength)
00318 *outlength = strlen(s);
00319
00320 return s;
00321 }
00322
00323
00324 struct curl_slist *
00325 curl_slist_append_ccsid(struct curl_slist * list,
00326 const char * data, unsigned int ccsid)
00327
00328 {
00329 char * s;
00330
00331 s = (char *) NULL;
00332
00333 if(!data)
00334 return curl_slist_append(list, data);
00335
00336 s = dynconvert(ASCII_CCSID, data, -1, ccsid);
00337
00338 if(!s)
00339 return (struct curl_slist *) NULL;
00340
00341 list = curl_slist_append(list, s);
00342 free(s);
00343 return list;
00344 }
00345
00346
00347 time_t
00348 curl_getdate_ccsid(const char * p, const time_t * unused, unsigned int ccsid)
00349
00350 {
00351 char * s;
00352 time_t t;
00353
00354 if(!p)
00355 return curl_getdate(p, unused);
00356
00357 s = dynconvert(ASCII_CCSID, p, -1, ccsid);
00358
00359 if(!s)
00360 return (time_t) -1;
00361
00362 t = curl_getdate(s, unused);
00363 free(s);
00364 return t;
00365 }
00366
00367
00368 static int
00369 convert_version_info_string(const char * * stringp,
00370 char * * bufp, int * left, unsigned int ccsid)
00371
00372 {
00373
00374
00375
00376
00377
00378 if(*stringp) {
00379 int l = convert(*bufp, *left, ccsid, *stringp, -1, ASCII_CCSID);
00380
00381 if(l <= 0)
00382 return -1;
00383
00384 *stringp = *bufp;
00385 *bufp += l;
00386 *left -= l;
00387 }
00388
00389 return 0;
00390 }
00391
00392
00393 curl_version_info_data *
00394 curl_version_info_ccsid(CURLversion stamp, unsigned int ccsid)
00395
00396 {
00397 curl_version_info_data * p;
00398 char * cp;
00399 int n;
00400 int nproto;
00401 curl_version_info_data * id;
00402
00403
00404
00405
00406
00407 #if CURLVERSION_NOW != CURLVERSION_FOURTH
00408 #error curl_version_info_data structure has changed: upgrade this procedure.
00409 #endif
00410
00411
00412
00413 if(stamp > CURLVERSION_NOW)
00414 return (curl_version_info_data *) NULL;
00415
00416 p = curl_version_info(stamp);
00417
00418 if(!p)
00419 return p;
00420
00421
00422
00423 n = 0;
00424 nproto = 0;
00425
00426 if(p->protocols) {
00427 while(p->protocols[nproto])
00428 n += strlen(p->protocols[nproto++]);
00429
00430 n += nproto++;
00431 }
00432
00433 if(p->version)
00434 n += strlen(p->version) + 1;
00435
00436 if(p->host)
00437 n += strlen(p->host) + 1;
00438
00439 if(p->ssl_version)
00440 n += strlen(p->ssl_version) + 1;
00441
00442 if(p->libz_version)
00443 n += strlen(p->libz_version) + 1;
00444
00445 if(p->ares)
00446 n += strlen(p->ares) + 1;
00447
00448 if(p->libidn)
00449 n += strlen(p->libidn) + 1;
00450
00451 if(p->libssh_version)
00452 n += strlen(p->libssh_version) + 1;
00453
00454
00455
00456 n *= MAX_CONV_EXPANSION;
00457
00458 if(nproto)
00459 n += nproto * sizeof(const char *);
00460
00461 cp = Curl_thread_buffer(LK_VERSION_INFO_DATA, n);
00462 id = (curl_version_info_data *) Curl_thread_buffer(LK_VERSION_INFO,
00463 sizeof *id);
00464
00465 if(!id || !cp)
00466 return (curl_version_info_data *) NULL;
00467
00468
00469
00470 memcpy((char *) id, (char *) p, sizeof *p);
00471
00472 if(id->protocols) {
00473 int i = nproto * sizeof id->protocols[0];
00474
00475 id->protocols = (const char * const *) cp;
00476 memcpy(cp, (char *) p->protocols, i);
00477 cp += i;
00478 n -= i;
00479
00480 for(i = 0; id->protocols[i]; i++)
00481 if(convert_version_info_string(((const char * *) id->protocols) + i,
00482 &cp, &n, ccsid))
00483 return (curl_version_info_data *) NULL;
00484 }
00485
00486 if(convert_version_info_string(&id->version, &cp, &n, ccsid))
00487 return (curl_version_info_data *) NULL;
00488
00489 if(convert_version_info_string(&id->host, &cp, &n, ccsid))
00490 return (curl_version_info_data *) NULL;
00491
00492 if(convert_version_info_string(&id->ssl_version, &cp, &n, ccsid))
00493 return (curl_version_info_data *) NULL;
00494
00495 if(convert_version_info_string(&id->libz_version, &cp, &n, ccsid))
00496 return (curl_version_info_data *) NULL;
00497
00498 if(convert_version_info_string(&id->ares, &cp, &n, ccsid))
00499 return (curl_version_info_data *) NULL;
00500
00501 if(convert_version_info_string(&id->libidn, &cp, &n, ccsid))
00502 return (curl_version_info_data *) NULL;
00503
00504 if(convert_version_info_string(&id->libssh_version, &cp, &n, ccsid))
00505 return (curl_version_info_data *) NULL;
00506
00507 return id;
00508 }
00509
00510
00511 const char *
00512 curl_easy_strerror_ccsid(CURLcode error, unsigned int ccsid)
00513
00514 {
00515 int i;
00516 const char * s;
00517 char * buf;
00518
00519 s = curl_easy_strerror(error);
00520
00521 if(!s)
00522 return s;
00523
00524 i = MAX_CONV_EXPANSION * (strlen(s) + 1);
00525
00526 if(!(buf = Curl_thread_buffer(LK_EASY_STRERROR, i)))
00527 return (const char *) NULL;
00528
00529 if(convert(buf, i, ccsid, s, -1, ASCII_CCSID) < 0)
00530 return (const char *) NULL;
00531
00532 return (const char *) buf;
00533 }
00534
00535
00536 const char *
00537 curl_share_strerror_ccsid(CURLSHcode error, unsigned int ccsid)
00538
00539 {
00540 int i;
00541 const char * s;
00542 char * buf;
00543
00544 s = curl_share_strerror(error);
00545
00546 if(!s)
00547 return s;
00548
00549 i = MAX_CONV_EXPANSION * (strlen(s) + 1);
00550
00551 if(!(buf = Curl_thread_buffer(LK_SHARE_STRERROR, i)))
00552 return (const char *) NULL;
00553
00554 if(convert(buf, i, ccsid, s, -1, ASCII_CCSID) < 0)
00555 return (const char *) NULL;
00556
00557 return (const char *) buf;
00558 }
00559
00560
00561 const char *
00562 curl_multi_strerror_ccsid(CURLMcode error, unsigned int ccsid)
00563
00564 {
00565 int i;
00566 const char * s;
00567 char * buf;
00568
00569 s = curl_multi_strerror(error);
00570
00571 if(!s)
00572 return s;
00573
00574 i = MAX_CONV_EXPANSION * (strlen(s) + 1);
00575
00576 if(!(buf = Curl_thread_buffer(LK_MULTI_STRERROR, i)))
00577 return (const char *) NULL;
00578
00579 if(convert(buf, i, ccsid, s, -1, ASCII_CCSID) < 0)
00580 return (const char *) NULL;
00581
00582 return (const char *) buf;
00583 }
00584
00585
00586 void
00587 curl_certinfo_free_all(struct curl_certinfo *info)
00588
00589 {
00590
00591 if(info) {
00592 if(info->certinfo) {
00593 int i;
00594
00595 for(i = 0; i < info->num_of_certs; i++)
00596 curl_slist_free_all(info->certinfo[i]);
00597 free((char *) info->certinfo);
00598 }
00599 free((char *) info);
00600 }
00601 }
00602
00603
00604 CURLcode
00605 curl_easy_getinfo_ccsid(CURL * curl, CURLINFO info, ...)
00606
00607 {
00608 va_list arg;
00609 void * paramp;
00610 CURLcode ret;
00611 unsigned int ccsid;
00612 char * * cpp;
00613 struct Curl_easy * data;
00614 struct curl_slist * * slp;
00615 struct curl_certinfo * cipf;
00616 struct curl_certinfo * cipt;
00617
00618
00619
00620
00621 data = (struct Curl_easy *) curl;
00622 va_start(arg, info);
00623 paramp = va_arg(arg, void *);
00624 ret = Curl_getinfo(data, info, paramp);
00625
00626 if(ret == CURLE_OK)
00627 switch ((int) info & CURLINFO_TYPEMASK) {
00628
00629 case CURLINFO_STRING:
00630 ccsid = va_arg(arg, unsigned int);
00631 cpp = (char * *) paramp;
00632
00633 if(*cpp) {
00634 *cpp = dynconvert(ccsid, *cpp, -1, ASCII_CCSID);
00635
00636 if(!*cpp)
00637 ret = CURLE_OUT_OF_MEMORY;
00638 }
00639
00640 break;
00641
00642 case CURLINFO_SLIST:
00643 ccsid = va_arg(arg, unsigned int);
00644 switch (info) {
00645 case CURLINFO_CERTINFO:
00646 cipf = *(struct curl_certinfo * *) paramp;
00647 if(cipf) {
00648 if(!(cipt = (struct curl_certinfo *) malloc(sizeof *cipt)))
00649 ret = CURLE_OUT_OF_MEMORY;
00650 else {
00651 cipt->certinfo = (struct curl_slist * *)
00652 calloc(cipf->num_of_certs +
00653 1, sizeof(struct curl_slist *));
00654 if(!cipt->certinfo)
00655 ret = CURLE_OUT_OF_MEMORY;
00656 else {
00657 int i;
00658
00659 cipt->num_of_certs = cipf->num_of_certs;
00660 for(i = 0; i < cipf->num_of_certs; i++)
00661 if(cipf->certinfo[i])
00662 if(!(cipt->certinfo[i] = slist_convert(ccsid,
00663 cipf->certinfo[i],
00664 ASCII_CCSID))) {
00665 ret = CURLE_OUT_OF_MEMORY;
00666 break;
00667 }
00668 }
00669 }
00670
00671 if(ret != CURLE_OK) {
00672 curl_certinfo_free_all(cipt);
00673 cipt = (struct curl_certinfo *) NULL;
00674 }
00675
00676 *(struct curl_certinfo * *) paramp = cipt;
00677 }
00678
00679 break;
00680
00681 case CURLINFO_TLS_SESSION:
00682 case CURLINFO_TLS_SSL_PTR:
00683 case CURLINFO_SOCKET:
00684 break;
00685
00686 default:
00687 slp = (struct curl_slist * *) paramp;
00688 if(*slp)
00689 if(!(*slp = slist_convert(ccsid, *slp, ASCII_CCSID)))
00690 ret = CURLE_OUT_OF_MEMORY;
00691 break;
00692 }
00693 }
00694
00695 va_end(arg);
00696 return ret;
00697 }
00698
00699
00700 static int
00701 Curl_is_formadd_string(CURLformoption option)
00702
00703 {
00704 switch (option) {
00705
00706 case CURLFORM_FILENAME:
00707 case CURLFORM_CONTENTTYPE:
00708 case CURLFORM_BUFFER:
00709 case CURLFORM_FILE:
00710 case CURLFORM_FILECONTENT:
00711 case CURLFORM_COPYCONTENTS:
00712 case CURLFORM_COPYNAME:
00713 return 1;
00714 }
00715
00716 return 0;
00717 }
00718
00719
00720 static void
00721 Curl_formadd_release_local(struct curl_forms * forms, int nargs, int skip)
00722
00723 {
00724 while(nargs--)
00725 if(nargs != skip)
00726 if(Curl_is_formadd_string(forms[nargs].option))
00727 if(forms[nargs].value)
00728 free((char *) forms[nargs].value);
00729
00730 free((char *) forms);
00731 }
00732
00733
00734 static int
00735 Curl_formadd_convert(struct curl_forms * forms,
00736 int formx, int lengthx, unsigned int ccsid)
00737
00738 {
00739 int l;
00740 char * cp;
00741 char * cp2;
00742
00743 if(formx < 0 || !forms[formx].value)
00744 return 0;
00745
00746 if(lengthx >= 0)
00747 l = (int) forms[lengthx].value;
00748 else
00749 l = strlen(forms[formx].value) + 1;
00750
00751 cp = malloc(MAX_CONV_EXPANSION * l);
00752
00753 if(!cp)
00754 return -1;
00755
00756 l = convert(cp, MAX_CONV_EXPANSION * l, ASCII_CCSID,
00757 forms[formx].value, l, ccsid);
00758
00759 if(l < 0) {
00760 free(cp);
00761 return -1;
00762 }
00763
00764 cp2 = realloc(cp, l);
00765
00766 if(cp2)
00767 cp = cp2;
00768
00769 forms[formx].value = cp;
00770
00771 if(lengthx >= 0)
00772 forms[lengthx].value = (char *) l;
00773
00774 return l;
00775 }
00776
00777
00778 CURLFORMcode
00779 curl_formadd_ccsid(struct curl_httppost * * httppost,
00780 struct curl_httppost * * last_post, ...)
00781
00782 {
00783 va_list arg;
00784 CURLformoption option;
00785 CURLFORMcode result;
00786 struct curl_forms * forms;
00787 struct curl_forms * lforms;
00788 struct curl_forms * tforms;
00789 unsigned int lformlen;
00790 const char * value;
00791 unsigned int ccsid;
00792 int nargs;
00793 int namex;
00794 int namelengthx;
00795 int contentx;
00796 int lengthx;
00797 unsigned int contentccsid;
00798 unsigned int nameccsid;
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817 lformlen = ALLOC_GRANULE;
00818 lforms = malloc(lformlen * sizeof *lforms);
00819
00820 if(!lforms)
00821 return CURL_FORMADD_MEMORY;
00822
00823
00824
00825
00826 result = CURL_FORMADD_OK;
00827 nargs = 0;
00828 contentx = -1;
00829 lengthx = -1;
00830 namex = -1;
00831 namelengthx = -1;
00832 forms = (struct curl_forms *) NULL;
00833 va_start(arg, last_post);
00834
00835 for(;;) {
00836
00837
00838 if(nargs >= lformlen) {
00839 lformlen += ALLOC_GRANULE;
00840 tforms = realloc(lforms, lformlen * sizeof *lforms);
00841
00842 if(!tforms) {
00843 result = CURL_FORMADD_MEMORY;
00844 break;
00845 }
00846
00847 lforms = tforms;
00848 }
00849
00850
00851
00852 if(forms) {
00853
00854
00855 option = forms->option;
00856 value = forms->value;
00857 forms++;
00858 }
00859 else {
00860
00861
00862 option = va_arg(arg, CURLformoption);
00863
00864 if(option == CURLFORM_END)
00865 break;
00866 }
00867
00868
00869
00870 switch (option) {
00871
00872 case CURLFORM_END:
00873 forms = (struct curl_forms *) NULL;
00874 continue;
00875
00876 case CURLFORM_ARRAY:
00877 if(!forms) {
00878 forms = va_arg(arg, struct curl_forms *);
00879 continue;
00880 }
00881
00882 result = CURL_FORMADD_ILLEGAL_ARRAY;
00883 break;
00884
00885 case CURLFORM_COPYNAME:
00886 option = CURLFORM_PTRNAME;
00887
00888 case CURLFORM_PTRNAME:
00889 if(namex >= 0)
00890 result = CURL_FORMADD_OPTION_TWICE;
00891
00892 namex = nargs;
00893
00894 if(!forms) {
00895 value = va_arg(arg, char *);
00896 nameccsid = (unsigned int) va_arg(arg, long);
00897 }
00898 else {
00899 nameccsid = (unsigned int) forms->value;
00900 forms++;
00901 }
00902
00903 break;
00904
00905 case CURLFORM_COPYCONTENTS:
00906 if(contentx >= 0)
00907 result = CURL_FORMADD_OPTION_TWICE;
00908
00909 contentx = nargs;
00910
00911 if(!forms) {
00912 value = va_arg(arg, char *);
00913 contentccsid = (unsigned int) va_arg(arg, long);
00914 }
00915 else {
00916 contentccsid = (unsigned int) forms->value;
00917 forms++;
00918 }
00919
00920 break;
00921
00922 case CURLFORM_PTRCONTENTS:
00923 case CURLFORM_BUFFERPTR:
00924 if(!forms)
00925 value = va_arg(arg, char *);
00926
00927 break;
00928
00929 case CURLFORM_CONTENTSLENGTH:
00930 lengthx = nargs;
00931
00932 if(!forms)
00933 value = (char *) va_arg(arg, long);
00934
00935 break;
00936
00937 case CURLFORM_CONTENTLEN:
00938 lengthx = nargs;
00939
00940 if(!forms)
00941 value = (char *) va_arg(arg, curl_off_t);
00942
00943 break;
00944
00945 case CURLFORM_NAMELENGTH:
00946 namelengthx = nargs;
00947
00948 if(!forms)
00949 value = (char *) va_arg(arg, long);
00950
00951 break;
00952
00953 case CURLFORM_BUFFERLENGTH:
00954 if(!forms)
00955 value = (char *) va_arg(arg, long);
00956
00957 break;
00958
00959 case CURLFORM_CONTENTHEADER:
00960 if(!forms)
00961 value = (char *) va_arg(arg, struct curl_slist *);
00962
00963 break;
00964
00965 case CURLFORM_STREAM:
00966 if(!forms)
00967 value = (char *) va_arg(arg, void *);
00968
00969 break;
00970
00971 case CURLFORM_CONTENTTYPE:
00972
00973
00974 if(Curl_formadd_convert(lforms, contentx, lengthx, contentccsid) < 0) {
00975 result = CURL_FORMADD_MEMORY;
00976 break;
00977 }
00978
00979 contentx = -1;
00980 lengthx = -1;
00981
00982
00983 default:
00984
00985
00986 if(!Curl_is_formadd_string(option)) {
00987 result = CURL_FORMADD_UNKNOWN_OPTION;
00988 break;
00989 }
00990
00991 if(!forms) {
00992 value = va_arg(arg, char *);
00993 ccsid = (unsigned int) va_arg(arg, long);
00994 }
00995 else {
00996 ccsid = (unsigned int) forms->value;
00997 forms++;
00998 }
00999
01000
01001
01002 lforms[nargs].value = value;
01003
01004 if(Curl_formadd_convert(lforms, nargs, -1, ccsid) < 0) {
01005 result = CURL_FORMADD_MEMORY;
01006 break;
01007 }
01008
01009 value = lforms[nargs].value;
01010 }
01011
01012 if(result != CURL_FORMADD_OK)
01013 break;
01014
01015 lforms[nargs].value = value;
01016 lforms[nargs++].option = option;
01017 }
01018
01019 va_end(arg);
01020
01021
01022
01023 if(result == CURL_FORMADD_OK && namex >= 0) {
01024 if(Curl_formadd_convert(lforms, namex, namelengthx, nameccsid) < 0)
01025 result = CURL_FORMADD_MEMORY;
01026 else
01027 lforms[namex].option = CURLFORM_COPYNAME;
01028 }
01029
01030 if(result == CURL_FORMADD_OK) {
01031 if(Curl_formadd_convert(lforms, contentx, lengthx, contentccsid) < 0)
01032 result = CURL_FORMADD_MEMORY;
01033 else
01034 contentx = -1;
01035 }
01036
01037
01038
01039 if(result == CURL_FORMADD_OK) {
01040 lforms[nargs].option = CURLFORM_END;
01041 result = curl_formadd(httppost, last_post,
01042 CURLFORM_ARRAY, lforms, CURLFORM_END);
01043 }
01044
01045
01046
01047 Curl_formadd_release_local(lforms, nargs, contentx);
01048 return result;
01049 }
01050
01051
01052 typedef struct {
01053 curl_formget_callback append;
01054 void * arg;
01055 unsigned int ccsid;
01056 } cfcdata;
01057
01058
01059 static size_t
01060 Curl_formget_callback_ccsid(void * arg, const char * buf, size_t len)
01061
01062 {
01063 cfcdata * p;
01064 char * b;
01065 int l;
01066 size_t ret;
01067
01068 p = (cfcdata *) arg;
01069
01070 if((long) len <= 0)
01071 return (*p->append)(p->arg, buf, len);
01072
01073 b = malloc(MAX_CONV_EXPANSION * len);
01074
01075 if(!b)
01076 return (size_t) -1;
01077
01078 l = convert(b, MAX_CONV_EXPANSION * len, p->ccsid, buf, len, ASCII_CCSID);
01079
01080 if(l < 0) {
01081 free(b);
01082 return (size_t) -1;
01083 }
01084
01085 ret = (*p->append)(p->arg, b, l);
01086 free(b);
01087 return ret == l? len: -1;
01088 }
01089
01090
01091 int
01092 curl_formget_ccsid(struct curl_httppost * form, void * arg,
01093 curl_formget_callback append, unsigned int ccsid)
01094
01095 {
01096 cfcdata lcfc;
01097
01098 lcfc.append = append;
01099 lcfc.arg = arg;
01100 lcfc.ccsid = ccsid;
01101 return curl_formget(form, (void *) &lcfc, Curl_formget_callback_ccsid);
01102 }
01103
01104
01105 CURLcode
01106 curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
01107
01108 {
01109 CURLcode result;
01110 va_list arg;
01111 struct Curl_easy * data;
01112 char * s;
01113 char * cp;
01114 unsigned int ccsid;
01115 curl_off_t pfsize;
01116 static char testwarn = 1;
01117
01118
01119
01120
01121
01122
01123
01124 if(testwarn) {
01125 testwarn = 0;
01126
01127 if((int) STRING_LASTZEROTERMINATED != (int) STRING_UNIX_SOCKET_PATH + 1 ||
01128 (int) STRING_LAST != (int) STRING_COPYPOSTFIELDS + 1)
01129 curl_mfprintf(stderr,
01130 "*** WARNING: curl_easy_setopt_ccsid() should be reworked ***\n");
01131 }
01132
01133 data = (struct Curl_easy *) curl;
01134 va_start(arg, tag);
01135
01136 switch (tag) {
01137
01138 case CURLOPT_CAINFO:
01139 case CURLOPT_CAPATH:
01140 case CURLOPT_COOKIE:
01141 case CURLOPT_COOKIEFILE:
01142 case CURLOPT_COOKIEJAR:
01143 case CURLOPT_COOKIELIST:
01144 case CURLOPT_CRLFILE:
01145 case CURLOPT_CUSTOMREQUEST:
01146 case CURLOPT_DEFAULT_PROTOCOL:
01147 case CURLOPT_DNS_SERVERS:
01148 case CURLOPT_EGDSOCKET:
01149 case CURLOPT_ENCODING:
01150 case CURLOPT_FTPPORT:
01151 case CURLOPT_FTP_ACCOUNT:
01152 case CURLOPT_FTP_ALTERNATIVE_TO_USER:
01153 case CURLOPT_INTERFACE:
01154 case CURLOPT_ISSUERCERT:
01155 case CURLOPT_KEYPASSWD:
01156 case CURLOPT_KRBLEVEL:
01157 case CURLOPT_LOGIN_OPTIONS:
01158 case CURLOPT_MAIL_AUTH:
01159 case CURLOPT_MAIL_FROM:
01160 case CURLOPT_NETRC_FILE:
01161 case CURLOPT_NOPROXY:
01162 case CURLOPT_PASSWORD:
01163 case CURLOPT_PINNEDPUBLICKEY:
01164 case CURLOPT_PROXY:
01165 case CURLOPT_PROXYPASSWORD:
01166 case CURLOPT_PROXYUSERNAME:
01167 case CURLOPT_PROXYUSERPWD:
01168 case CURLOPT_PROXY_CAINFO:
01169 case CURLOPT_PROXY_CAPATH:
01170 case CURLOPT_PROXY_CRLFILE:
01171 case CURLOPT_PROXY_KEYPASSWD:
01172 case CURLOPT_PROXY_PINNEDPUBLICKEY:
01173 case CURLOPT_PROXY_SERVICE_NAME:
01174 case CURLOPT_PROXY_SSLCERT:
01175 case CURLOPT_PROXY_SSLCERTTYPE:
01176 case CURLOPT_PROXY_SSLKEY:
01177 case CURLOPT_PROXY_SSLKEYTYPE:
01178 case CURLOPT_PROXY_SSL_CIPHER_LIST:
01179 case CURLOPT_PROXY_TLSAUTH_PASSWORD:
01180 case CURLOPT_PROXY_TLSAUTH_TYPE:
01181 case CURLOPT_PROXY_TLSAUTH_USERNAME:
01182 case CURLOPT_RANDOM_FILE:
01183 case CURLOPT_RANGE:
01184 case CURLOPT_REFERER:
01185 case CURLOPT_RTSP_SESSION_ID:
01186 case CURLOPT_RTSP_STREAM_URI:
01187 case CURLOPT_RTSP_TRANSPORT:
01188 case CURLOPT_SERVICE_NAME:
01189 case CURLOPT_SOCKS5_GSSAPI_SERVICE:
01190 case CURLOPT_SOCKS_PROXY:
01191 case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
01192 case CURLOPT_SSH_KNOWNHOSTS:
01193 case CURLOPT_SSH_PRIVATE_KEYFILE:
01194 case CURLOPT_SSH_PUBLIC_KEYFILE:
01195 case CURLOPT_SSLCERT:
01196 case CURLOPT_SSLCERTTYPE:
01197 case CURLOPT_SSLENGINE:
01198 case CURLOPT_SSLKEY:
01199 case CURLOPT_SSLKEYTYPE:
01200 case CURLOPT_SSL_CIPHER_LIST:
01201 case CURLOPT_TLSAUTH_PASSWORD:
01202 case CURLOPT_TLSAUTH_TYPE:
01203 case CURLOPT_TLSAUTH_USERNAME:
01204 case CURLOPT_UNIX_SOCKET_PATH:
01205 case CURLOPT_URL:
01206 case CURLOPT_USERAGENT:
01207 case CURLOPT_USERNAME:
01208 case CURLOPT_USERPWD:
01209 case CURLOPT_XOAUTH2_BEARER:
01210 s = va_arg(arg, char *);
01211 ccsid = va_arg(arg, unsigned int);
01212
01213 if(s) {
01214 s = dynconvert(ASCII_CCSID, s, -1, ccsid);
01215
01216 if(!s) {
01217 result = CURLE_OUT_OF_MEMORY;
01218 break;
01219 }
01220 }
01221
01222 result = curl_easy_setopt(curl, tag, s);
01223 free(s);
01224 break;
01225
01226 case CURLOPT_COPYPOSTFIELDS:
01227
01228
01229
01230 s = va_arg(arg, char *);
01231 ccsid = va_arg(arg, unsigned int);
01232
01233 pfsize = data->set.postfieldsize;
01234
01235 if(!s || !pfsize || ccsid == NOCONV_CCSID || ccsid == ASCII_CCSID) {
01236 result = curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, s);
01237 break;
01238 }
01239
01240 if(pfsize == -1) {
01241
01242 s = dynconvert(ASCII_CCSID, s, -1, ccsid);
01243
01244 if(!s) {
01245 result = CURLE_OUT_OF_MEMORY;
01246 break;
01247 }
01248 }
01249 else {
01250
01251 size_t len;
01252
01253 if(pfsize < 0 || pfsize > SIZE_MAX) {
01254 result = CURLE_OUT_OF_MEMORY;
01255 break;
01256 }
01257
01258 len = pfsize;
01259 pfsize = len * MAX_CONV_EXPANSION;
01260
01261 if(pfsize > SIZE_MAX)
01262 pfsize = SIZE_MAX;
01263
01264 cp = malloc(pfsize);
01265
01266 if(!cp) {
01267 result = CURLE_OUT_OF_MEMORY;
01268 break;
01269 }
01270
01271 pfsize = convert(cp, pfsize, ASCII_CCSID, s, len, ccsid);
01272
01273 if(pfsize < 0) {
01274 free(cp);
01275 result = CURLE_OUT_OF_MEMORY;
01276 break;
01277 }
01278
01279 data->set.postfieldsize = pfsize;
01280 s = cp;
01281 }
01282
01283 result = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, s);
01284 data->set.str[STRING_COPYPOSTFIELDS] = s;
01285 break;
01286
01287 case CURLOPT_ERRORBUFFER:
01288 default:
01289 result = Curl_setopt(data, tag, arg);
01290 break;
01291 }
01292
01293 va_end(arg);
01294 return result;
01295 }
01296
01297
01298 char *
01299 curl_form_long_value(long value)
01300
01301 {
01302
01303
01304 return (char *) value;
01305 }
01306
01307
01308 char *
01309 curl_pushheader_bynum_cssid(struct curl_pushheaders *h,
01310 size_t num, unsigned int ccsid)
01311
01312 {
01313 char *d = (char *) NULL;
01314 char *s = curl_pushheader_bynum(h, num);
01315
01316 if(s)
01317 d = dynconvert(ccsid, s, -1, ASCII_CCSID);
01318
01319 return d;
01320 }
01321
01322
01323 char *
01324 curl_pushheader_byname_ccsid(struct curl_pushheaders *h, const char *header,
01325 unsigned int ccsidin, unsigned int ccsidout)
01326
01327 {
01328 char *d = (char *) NULL;
01329 char *s;
01330
01331 if(header) {
01332 header = dynconvert(ASCII_CCSID, header, -1, ccsidin);
01333
01334 if(header) {
01335 s = curl_pushheader_byname(h, header);
01336 free((char *) header);
01337
01338 if(s)
01339 d = dynconvert(ccsidout, s, -1, ASCII_CCSID);
01340 }
01341 }
01342
01343 return d;
01344 }