Return to ccsidcurl.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / packages / OS400 |
1.1 ! misho 1: /*************************************************************************** ! 2: * _ _ ____ _ ! 3: * Project ___| | | | _ \| | ! 4: * / __| | | | |_) | | ! 5: * | (__| |_| | _ <| |___ ! 6: * \___|\___/|_| \_\_____| ! 7: * ! 8: * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. ! 9: * ! 10: * This software is licensed as described in the file COPYING, which ! 11: * you should have received as part of this distribution. The terms ! 12: * are also available at https://curl.haxx.se/docs/copyright.html. ! 13: * ! 14: * You may opt to use, copy, modify, merge, publish, distribute and/or sell ! 15: * copies of the Software, and permit persons to whom the Software is ! 16: * furnished to do so, under the terms of the COPYING file. ! 17: * ! 18: * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY ! 19: * KIND, either express or implied. ! 20: * ! 21: * ! 22: ***************************************************************************/ ! 23: ! 24: /* CCSID API wrappers for OS/400. */ ! 25: ! 26: #include <iconv.h> ! 27: #include <string.h> ! 28: #include <stdlib.h> ! 29: #include <errno.h> ! 30: #include <stdarg.h> ! 31: ! 32: #pragma enum(int) ! 33: ! 34: #include "curl.h" ! 35: #include "mprintf.h" ! 36: #include "slist.h" ! 37: #include "urldata.h" ! 38: #include "url.h" ! 39: #include "setopt.h" ! 40: #include "getinfo.h" ! 41: #include "ccsidcurl.h" ! 42: ! 43: #include "os400sys.h" ! 44: ! 45: #ifndef SIZE_MAX ! 46: #define SIZE_MAX ((size_t) ~0) /* Is unsigned on OS/400. */ ! 47: #endif ! 48: ! 49: ! 50: #define ASCII_CCSID 819 /* Use ISO-8859-1 as ASCII. */ ! 51: #define NOCONV_CCSID 65535 /* No conversion. */ ! 52: #define ICONV_ID_SIZE 32 /* Size of iconv_open() code identifier. */ ! 53: #define ICONV_OPEN_ERROR(t) ((t).return_value == -1) ! 54: ! 55: #define ALLOC_GRANULE 8 /* Alloc. granule for curl_formadd_ccsid(). */ ! 56: ! 57: ! 58: static void ! 59: makeOS400IconvCode(char buf[ICONV_ID_SIZE], unsigned int ccsid) ! 60: ! 61: { ! 62: /** ! 63: *** Convert a CCSID to the corresponding IBM iconv_open() character ! 64: *** code identifier. ! 65: *** This code is specific to the OS400 implementation of the iconv library. ! 66: *** CCSID 65535 (no conversion) is replaced by the ASCII CCSID. ! 67: *** CCSID 0 is interpreted by the OS400 as the job's CCSID. ! 68: **/ ! 69: ! 70: ccsid &= 0xFFFF; ! 71: ! 72: if(ccsid == NOCONV_CCSID) ! 73: ccsid = ASCII_CCSID; ! 74: ! 75: memset(buf, 0, ICONV_ID_SIZE); ! 76: curl_msprintf(buf, "IBMCCSID%05u0000000", ccsid); ! 77: } ! 78: ! 79: ! 80: static iconv_t ! 81: iconv_open_CCSID(unsigned int ccsidout, unsigned int ccsidin, ! 82: unsigned int cstr) ! 83: ! 84: { ! 85: char fromcode[ICONV_ID_SIZE]; ! 86: char tocode[ICONV_ID_SIZE]; ! 87: ! 88: /** ! 89: *** Like iconv_open(), but character codes are given as CCSIDs. ! 90: *** If `cstr' is non-zero, conversion is set up to stop whenever a ! 91: *** null character is encountered. ! 92: *** See iconv_open() IBM description in "National Language Support API". ! 93: **/ ! 94: ! 95: makeOS400IconvCode(fromcode, ccsidin); ! 96: makeOS400IconvCode(tocode, ccsidout); ! 97: memset(tocode + 13, 0, sizeof(tocode) - 13); /* Dest. code id format. */ ! 98: ! 99: if(cstr) ! 100: fromcode[18] = '1'; /* Set null-terminator flag. */ ! 101: ! 102: return iconv_open(tocode, fromcode); ! 103: } ! 104: ! 105: ! 106: static int ! 107: convert(char *d, size_t dlen, int dccsid, ! 108: const char *s, int slen, int sccsid) ! 109: ! 110: { ! 111: int i; ! 112: iconv_t cd; ! 113: size_t lslen; ! 114: ! 115: /** ! 116: *** Convert `sccsid'-coded `slen'-data bytes at `s' into `dccsid'-coded ! 117: *** data stored in the `dlen'-byte buffer at `d'. ! 118: *** If `slen' < 0, source string is null-terminated. ! 119: *** CCSID 65535 (no conversion) is replaced by the ASCII CCSID. ! 120: *** Return the converted destination byte count, or -1 if error. ! 121: **/ ! 122: ! 123: if(sccsid == 65535) ! 124: sccsid = ASCII_CCSID; ! 125: ! 126: if(dccsid == 65535) ! 127: dccsid = ASCII_CCSID; ! 128: ! 129: if(sccsid == dccsid) { ! 130: lslen = slen >= 0? slen: strlen(s) + 1; ! 131: i = lslen < dlen? lslen: dlen; ! 132: ! 133: if(s != d && i > 0) ! 134: memcpy(d, s, i); ! 135: ! 136: return i; ! 137: } ! 138: ! 139: if(slen < 0) { ! 140: lslen = 0; ! 141: cd = iconv_open_CCSID(dccsid, sccsid, 1); ! 142: } ! 143: else { ! 144: lslen = (size_t) slen; ! 145: cd = iconv_open_CCSID(dccsid, sccsid, 0); ! 146: } ! 147: ! 148: if(ICONV_OPEN_ERROR(cd)) ! 149: return -1; ! 150: ! 151: i = dlen; ! 152: ! 153: if((int) iconv(cd, (char * *) &s, &lslen, &d, &dlen) < 0) ! 154: i = -1; ! 155: else ! 156: i -= dlen; ! 157: ! 158: iconv_close(cd); ! 159: return i; ! 160: } ! 161: ! 162: ! 163: static char * ! 164: dynconvert(int dccsid, const char *s, int slen, int sccsid) ! 165: ! 166: { ! 167: char *d; ! 168: char *cp; ! 169: size_t dlen; ! 170: int l; ! 171: static const char nullbyte = 0; ! 172: ! 173: /* Like convert, but the destination is allocated and returned. */ ! 174: ! 175: dlen = (size_t) (slen < 0? strlen(s): slen) + 1; ! 176: dlen *= MAX_CONV_EXPANSION; /* Allow some expansion. */ ! 177: d = malloc(dlen); ! 178: ! 179: if(!d) ! 180: return (char *) NULL; ! 181: ! 182: l = convert(d, dlen, dccsid, s, slen, sccsid); ! 183: ! 184: if(l < 0) { ! 185: free(d); ! 186: return (char *) NULL; ! 187: } ! 188: ! 189: if(slen < 0) { ! 190: /* Need to null-terminate even when source length is given. ! 191: Since destination code size is unknown, use a conversion to generate ! 192: terminator. */ ! 193: ! 194: int l2 = convert(d + l, dlen - l, dccsid, &nullbyte, -1, ASCII_CCSID); ! 195: ! 196: if(l2 < 0) { ! 197: free(d); ! 198: return (char *) NULL; ! 199: } ! 200: ! 201: l += l2; ! 202: } ! 203: ! 204: if((size_t) l < dlen) { ! 205: cp = realloc(d, l); /* Shorten to minimum needed. */ ! 206: ! 207: if(cp) ! 208: d = cp; ! 209: } ! 210: ! 211: return d; ! 212: } ! 213: ! 214: ! 215: static struct curl_slist * ! 216: slist_convert(int dccsid, struct curl_slist *from, int sccsid) ! 217: ! 218: { ! 219: struct curl_slist *to = (struct curl_slist *) NULL; ! 220: ! 221: for(; from; from = from->next) { ! 222: struct curl_slist *nl; ! 223: char *cp = dynconvert(dccsid, from->data, -1, sccsid); ! 224: ! 225: if(!cp) { ! 226: curl_slist_free_all(to); ! 227: return (struct curl_slist *) NULL; ! 228: } ! 229: nl = Curl_slist_append_nodup(to, cp); ! 230: if(!nl) { ! 231: curl_slist_free_all(to); ! 232: free(cp); ! 233: return NULL; ! 234: } ! 235: to = nl; ! 236: } ! 237: return to; ! 238: } ! 239: ! 240: ! 241: char * ! 242: curl_version_ccsid(unsigned int ccsid) ! 243: ! 244: { ! 245: int i; ! 246: char *aversion; ! 247: char *eversion; ! 248: ! 249: aversion = curl_version(); ! 250: ! 251: if(!aversion) ! 252: return aversion; ! 253: ! 254: i = strlen(aversion) + 1; ! 255: i *= MAX_CONV_EXPANSION; ! 256: ! 257: eversion = Curl_thread_buffer(LK_CURL_VERSION, i); ! 258: if(!eversion) ! 259: return (char *) NULL; ! 260: ! 261: if(convert(eversion, i, ccsid, aversion, -1, ASCII_CCSID) < 0) ! 262: return (char *) NULL; ! 263: ! 264: return eversion; ! 265: } ! 266: ! 267: ! 268: char * ! 269: curl_easy_escape_ccsid(CURL *handle, const char *string, int length, ! 270: unsigned int sccsid, unsigned int dccsid) ! 271: ! 272: { ! 273: char *s; ! 274: char *d; ! 275: ! 276: if(!string) { ! 277: errno = EINVAL; ! 278: return (char *) NULL; ! 279: } ! 280: ! 281: s = dynconvert(ASCII_CCSID, string, length? length: -1, sccsid); ! 282: ! 283: if(!s) ! 284: return (char *) NULL; ! 285: ! 286: d = curl_easy_escape(handle, s, 0); ! 287: free(s); ! 288: ! 289: if(!d) ! 290: return (char *) NULL; ! 291: ! 292: s = dynconvert(dccsid, d, -1, ASCII_CCSID); ! 293: free(d); ! 294: return s; ! 295: } ! 296: ! 297: ! 298: char * ! 299: curl_easy_unescape_ccsid(CURL *handle, const char *string, int length, ! 300: int *outlength, ! 301: unsigned int sccsid, unsigned int dccsid) ! 302: ! 303: { ! 304: char *s; ! 305: char *d; ! 306: ! 307: if(!string) { ! 308: errno = EINVAL; ! 309: return (char *) NULL; ! 310: } ! 311: ! 312: s = dynconvert(ASCII_CCSID, string, length? length: -1, sccsid); ! 313: ! 314: if(!s) ! 315: return (char *) NULL; ! 316: ! 317: d = curl_easy_unescape(handle, s, 0, outlength); ! 318: free(s); ! 319: ! 320: if(!d) ! 321: return (char *) NULL; ! 322: ! 323: s = dynconvert(dccsid, d, -1, ASCII_CCSID); ! 324: free(d); ! 325: ! 326: if(s && outlength) ! 327: *outlength = strlen(s); ! 328: ! 329: return s; ! 330: } ! 331: ! 332: ! 333: struct curl_slist * ! 334: curl_slist_append_ccsid(struct curl_slist *list, ! 335: const char *data, unsigned int ccsid) ! 336: ! 337: { ! 338: char *s; ! 339: ! 340: s = (char *) NULL; ! 341: ! 342: if(!data) ! 343: return curl_slist_append(list, data); ! 344: ! 345: s = dynconvert(ASCII_CCSID, data, -1, ccsid); ! 346: ! 347: if(!s) ! 348: return (struct curl_slist *) NULL; ! 349: ! 350: list = curl_slist_append(list, s); ! 351: free(s); ! 352: return list; ! 353: } ! 354: ! 355: ! 356: time_t ! 357: curl_getdate_ccsid(const char *p, const time_t * unused, unsigned int ccsid) ! 358: ! 359: { ! 360: char *s; ! 361: time_t t; ! 362: ! 363: if(!p) ! 364: return curl_getdate(p, unused); ! 365: ! 366: s = dynconvert(ASCII_CCSID, p, -1, ccsid); ! 367: ! 368: if(!s) ! 369: return (time_t) -1; ! 370: ! 371: t = curl_getdate(s, unused); ! 372: free(s); ! 373: return t; ! 374: } ! 375: ! 376: ! 377: static int ! 378: convert_version_info_string(const char * * stringp, ! 379: char * * bufp, int *left, unsigned int ccsid) ! 380: ! 381: { ! 382: /* Helper for curl_version_info_ccsid(): convert a string if defined. ! 383: Result is stored in the `*left'-byte buffer at `*bufp'. ! 384: `*bufp' and `*left' are updated accordingly. ! 385: Return 0 if ok, else -1. */ ! 386: ! 387: if(*stringp) { ! 388: int l = convert(*bufp, *left, ccsid, *stringp, -1, ASCII_CCSID); ! 389: ! 390: if(l <= 0) ! 391: return -1; ! 392: ! 393: *stringp = *bufp; ! 394: *bufp += l; ! 395: *left -= l; ! 396: } ! 397: ! 398: return 0; ! 399: } ! 400: ! 401: ! 402: curl_version_info_data * ! 403: curl_version_info_ccsid(CURLversion stamp, unsigned int ccsid) ! 404: ! 405: { ! 406: curl_version_info_data * p; ! 407: char *cp; ! 408: int n; ! 409: int nproto; ! 410: curl_version_info_data * id; ! 411: ! 412: /* The assertion below is possible, because although the second operand ! 413: is an enum member, the first is a #define. In that case, the OS/400 C ! 414: compiler seems to compare string values after substitution. */ ! 415: ! 416: #if CURLVERSION_NOW != CURLVERSION_FOURTH ! 417: #error curl_version_info_data structure has changed: upgrade this procedure. ! 418: #endif ! 419: ! 420: /* If caller has been compiled with a new version, error. */ ! 421: ! 422: if(stamp > CURLVERSION_NOW) ! 423: return (curl_version_info_data *) NULL; ! 424: ! 425: p = curl_version_info(stamp); ! 426: ! 427: if(!p) ! 428: return p; ! 429: ! 430: /* Measure thread space needed. */ ! 431: ! 432: n = 0; ! 433: nproto = 0; ! 434: ! 435: if(p->protocols) { ! 436: while(p->protocols[nproto]) ! 437: n += strlen(p->protocols[nproto++]); ! 438: ! 439: n += nproto++; ! 440: } ! 441: ! 442: if(p->version) ! 443: n += strlen(p->version) + 1; ! 444: ! 445: if(p->host) ! 446: n += strlen(p->host) + 1; ! 447: ! 448: if(p->ssl_version) ! 449: n += strlen(p->ssl_version) + 1; ! 450: ! 451: if(p->libz_version) ! 452: n += strlen(p->libz_version) + 1; ! 453: ! 454: if(p->ares) ! 455: n += strlen(p->ares) + 1; ! 456: ! 457: if(p->libidn) ! 458: n += strlen(p->libidn) + 1; ! 459: ! 460: if(p->libssh_version) ! 461: n += strlen(p->libssh_version) + 1; ! 462: ! 463: /* Allocate thread space. */ ! 464: ! 465: n *= MAX_CONV_EXPANSION; ! 466: ! 467: if(nproto) ! 468: n += nproto * sizeof(const char *); ! 469: ! 470: cp = Curl_thread_buffer(LK_VERSION_INFO_DATA, n); ! 471: id = (curl_version_info_data *) Curl_thread_buffer(LK_VERSION_INFO, ! 472: sizeof(*id)); ! 473: ! 474: if(!id || !cp) ! 475: return (curl_version_info_data *) NULL; ! 476: ! 477: /* Copy data and convert strings. */ ! 478: ! 479: memcpy((char *) id, (char *) p, sizeof(*p)); ! 480: ! 481: if(id->protocols) { ! 482: int i = nproto * sizeof(id->protocols[0]); ! 483: ! 484: id->protocols = (const char * const *) cp; ! 485: memcpy(cp, (char *) p->protocols, i); ! 486: cp += i; ! 487: n -= i; ! 488: ! 489: for(i = 0; id->protocols[i]; i++) ! 490: if(convert_version_info_string(((const char * *) id->protocols) + i, ! 491: &cp, &n, ccsid)) ! 492: return (curl_version_info_data *) NULL; ! 493: } ! 494: ! 495: if(convert_version_info_string(&id->version, &cp, &n, ccsid)) ! 496: return (curl_version_info_data *) NULL; ! 497: ! 498: if(convert_version_info_string(&id->host, &cp, &n, ccsid)) ! 499: return (curl_version_info_data *) NULL; ! 500: ! 501: if(convert_version_info_string(&id->ssl_version, &cp, &n, ccsid)) ! 502: return (curl_version_info_data *) NULL; ! 503: ! 504: if(convert_version_info_string(&id->libz_version, &cp, &n, ccsid)) ! 505: return (curl_version_info_data *) NULL; ! 506: ! 507: if(convert_version_info_string(&id->ares, &cp, &n, ccsid)) ! 508: return (curl_version_info_data *) NULL; ! 509: ! 510: if(convert_version_info_string(&id->libidn, &cp, &n, ccsid)) ! 511: return (curl_version_info_data *) NULL; ! 512: ! 513: if(convert_version_info_string(&id->libssh_version, &cp, &n, ccsid)) ! 514: return (curl_version_info_data *) NULL; ! 515: ! 516: return id; ! 517: } ! 518: ! 519: ! 520: const char * ! 521: curl_easy_strerror_ccsid(CURLcode error, unsigned int ccsid) ! 522: ! 523: { ! 524: int i; ! 525: const char *s; ! 526: char *buf; ! 527: ! 528: s = curl_easy_strerror(error); ! 529: ! 530: if(!s) ! 531: return s; ! 532: ! 533: i = MAX_CONV_EXPANSION * (strlen(s) + 1); ! 534: ! 535: buf = Curl_thread_buffer(LK_EASY_STRERROR, i); ! 536: if(!buf) ! 537: return (const char *) NULL; ! 538: ! 539: if(convert(buf, i, ccsid, s, -1, ASCII_CCSID) < 0) ! 540: return (const char *) NULL; ! 541: ! 542: return (const char *) buf; ! 543: } ! 544: ! 545: ! 546: const char * ! 547: curl_share_strerror_ccsid(CURLSHcode error, unsigned int ccsid) ! 548: ! 549: { ! 550: int i; ! 551: const char *s; ! 552: char *buf; ! 553: ! 554: s = curl_share_strerror(error); ! 555: ! 556: if(!s) ! 557: return s; ! 558: ! 559: i = MAX_CONV_EXPANSION * (strlen(s) + 1); ! 560: ! 561: buf = Curl_thread_buffer(LK_SHARE_STRERROR, i); ! 562: if(!buf) ! 563: return (const char *) NULL; ! 564: ! 565: if(convert(buf, i, ccsid, s, -1, ASCII_CCSID) < 0) ! 566: return (const char *) NULL; ! 567: ! 568: return (const char *) buf; ! 569: } ! 570: ! 571: ! 572: const char * ! 573: curl_multi_strerror_ccsid(CURLMcode error, unsigned int ccsid) ! 574: ! 575: { ! 576: int i; ! 577: const char *s; ! 578: char *buf; ! 579: ! 580: s = curl_multi_strerror(error); ! 581: ! 582: if(!s) ! 583: return s; ! 584: ! 585: i = MAX_CONV_EXPANSION * (strlen(s) + 1); ! 586: ! 587: buf = Curl_thread_buffer(LK_MULTI_STRERROR, i); ! 588: if(!buf) ! 589: return (const char *) NULL; ! 590: ! 591: if(convert(buf, i, ccsid, s, -1, ASCII_CCSID) < 0) ! 592: return (const char *) NULL; ! 593: ! 594: return (const char *) buf; ! 595: } ! 596: ! 597: ! 598: void ! 599: curl_certinfo_free_all(struct curl_certinfo *info) ! 600: ! 601: { ! 602: /* Free all memory used by certificate info. */ ! 603: if(info) { ! 604: if(info->certinfo) { ! 605: int i; ! 606: ! 607: for(i = 0; i < info->num_of_certs; i++) ! 608: curl_slist_free_all(info->certinfo[i]); ! 609: free((char *) info->certinfo); ! 610: } ! 611: free((char *) info); ! 612: } ! 613: } ! 614: ! 615: ! 616: CURLcode ! 617: curl_easy_getinfo_ccsid(CURL *curl, CURLINFO info, ...) ! 618: ! 619: { ! 620: va_list arg; ! 621: void *paramp; ! 622: CURLcode ret; ! 623: struct Curl_easy * data; ! 624: ! 625: /* WARNING: unlike curl_easy_getinfo(), the strings returned by this ! 626: procedure have to be free'ed. */ ! 627: ! 628: data = (struct Curl_easy *) curl; ! 629: va_start(arg, info); ! 630: paramp = va_arg(arg, void *); ! 631: ret = Curl_getinfo(data, info, paramp); ! 632: ! 633: if(ret == CURLE_OK) { ! 634: unsigned int ccsid; ! 635: char **cpp; ! 636: struct curl_slist **slp; ! 637: struct curl_certinfo *cipf; ! 638: struct curl_certinfo *cipt; ! 639: ! 640: switch((int) info & CURLINFO_TYPEMASK) { ! 641: ! 642: case CURLINFO_STRING: ! 643: ccsid = va_arg(arg, unsigned int); ! 644: cpp = (char * *) paramp; ! 645: ! 646: if(*cpp) { ! 647: *cpp = dynconvert(ccsid, *cpp, -1, ASCII_CCSID); ! 648: ! 649: if(!*cpp) ! 650: ret = CURLE_OUT_OF_MEMORY; ! 651: } ! 652: ! 653: break; ! 654: ! 655: case CURLINFO_SLIST: ! 656: ccsid = va_arg(arg, unsigned int); ! 657: switch(info) { ! 658: case CURLINFO_CERTINFO: ! 659: cipf = *(struct curl_certinfo * *) paramp; ! 660: if(cipf) { ! 661: cipt = (struct curl_certinfo *) malloc(sizeof(*cipt)); ! 662: if(!cipt) ! 663: ret = CURLE_OUT_OF_MEMORY; ! 664: else { ! 665: cipt->certinfo = (struct curl_slist **) ! 666: calloc(cipf->num_of_certs + ! 667: 1, sizeof(struct curl_slist *)); ! 668: if(!cipt->certinfo) ! 669: ret = CURLE_OUT_OF_MEMORY; ! 670: else { ! 671: int i; ! 672: ! 673: cipt->num_of_certs = cipf->num_of_certs; ! 674: for(i = 0; i < cipf->num_of_certs; i++) ! 675: if(cipf->certinfo[i]) ! 676: if(!(cipt->certinfo[i] = slist_convert(ccsid, ! 677: cipf->certinfo[i], ! 678: ASCII_CCSID))) { ! 679: ret = CURLE_OUT_OF_MEMORY; ! 680: break; ! 681: } ! 682: } ! 683: } ! 684: ! 685: if(ret != CURLE_OK) { ! 686: curl_certinfo_free_all(cipt); ! 687: cipt = (struct curl_certinfo *) NULL; ! 688: } ! 689: ! 690: *(struct curl_certinfo * *) paramp = cipt; ! 691: } ! 692: ! 693: break; ! 694: ! 695: case CURLINFO_TLS_SESSION: ! 696: case CURLINFO_TLS_SSL_PTR: ! 697: case CURLINFO_SOCKET: ! 698: break; ! 699: ! 700: default: ! 701: slp = (struct curl_slist **) paramp; ! 702: if(*slp) { ! 703: *slp = slist_convert(ccsid, *slp, ASCII_CCSID); ! 704: if(!*slp) ! 705: ret = CURLE_OUT_OF_MEMORY; ! 706: } ! 707: break; ! 708: } ! 709: } ! 710: } ! 711: ! 712: va_end(arg); ! 713: return ret; ! 714: } ! 715: ! 716: ! 717: static int ! 718: Curl_is_formadd_string(CURLformoption option) ! 719: ! 720: { ! 721: switch(option) { ! 722: ! 723: case CURLFORM_FILENAME: ! 724: case CURLFORM_CONTENTTYPE: ! 725: case CURLFORM_BUFFER: ! 726: case CURLFORM_FILE: ! 727: case CURLFORM_FILECONTENT: ! 728: case CURLFORM_COPYCONTENTS: ! 729: case CURLFORM_COPYNAME: ! 730: return 1; ! 731: } ! 732: ! 733: return 0; ! 734: } ! 735: ! 736: ! 737: static void ! 738: Curl_formadd_release_local(struct curl_forms * forms, int nargs, int skip) ! 739: ! 740: { ! 741: while(nargs--) ! 742: if(nargs != skip) ! 743: if(Curl_is_formadd_string(forms[nargs].option)) ! 744: if(forms[nargs].value) ! 745: free((char *) forms[nargs].value); ! 746: ! 747: free((char *) forms); ! 748: } ! 749: ! 750: ! 751: static int ! 752: Curl_formadd_convert(struct curl_forms * forms, ! 753: int formx, int lengthx, unsigned int ccsid) ! 754: ! 755: { ! 756: int l; ! 757: char *cp; ! 758: char *cp2; ! 759: ! 760: if(formx < 0 || !forms[formx].value) ! 761: return 0; ! 762: ! 763: if(lengthx >= 0) ! 764: l = (int) forms[lengthx].value; ! 765: else ! 766: l = strlen(forms[formx].value) + 1; ! 767: ! 768: cp = malloc(MAX_CONV_EXPANSION * l); ! 769: ! 770: if(!cp) ! 771: return -1; ! 772: ! 773: l = convert(cp, MAX_CONV_EXPANSION * l, ASCII_CCSID, ! 774: forms[formx].value, l, ccsid); ! 775: ! 776: if(l < 0) { ! 777: free(cp); ! 778: return -1; ! 779: } ! 780: ! 781: cp2 = realloc(cp, l); /* Shorten buffer to the string size. */ ! 782: ! 783: if(cp2) ! 784: cp = cp2; ! 785: ! 786: forms[formx].value = cp; ! 787: ! 788: if(lengthx >= 0) ! 789: forms[lengthx].value = (char *) l; /* Update length after conversion. */ ! 790: ! 791: return l; ! 792: } ! 793: ! 794: ! 795: CURLFORMcode ! 796: curl_formadd_ccsid(struct curl_httppost * * httppost, ! 797: struct curl_httppost * * last_post, ...) ! 798: ! 799: { ! 800: va_list arg; ! 801: CURLformoption option; ! 802: CURLFORMcode result; ! 803: struct curl_forms * forms; ! 804: struct curl_forms * lforms; ! 805: struct curl_forms * tforms; ! 806: unsigned int lformlen; ! 807: const char *value; ! 808: unsigned int ccsid; ! 809: int nargs; ! 810: int namex; ! 811: int namelengthx; ! 812: int contentx; ! 813: int lengthx; ! 814: unsigned int contentccsid; ! 815: unsigned int nameccsid; ! 816: ! 817: /* A single curl_formadd() call cannot be split in several calls to deal ! 818: with all parameters: the original parameters are thus copied to a local ! 819: curl_forms array and converted to ASCII when needed. ! 820: CURLFORM_PTRNAME is processed as if it were CURLFORM_COPYNAME. ! 821: CURLFORM_COPYNAME and CURLFORM_NAMELENGTH occurrence order in ! 822: parameters is not defined; for this reason, the actual conversion is ! 823: delayed to the end of parameter processing. The same applies to ! 824: CURLFORM_COPYCONTENTS/CURLFORM_CONTENTSLENGTH, but these may appear ! 825: several times in the parameter list; the problem resides here in knowing ! 826: which CURLFORM_CONTENTSLENGTH applies to which CURLFORM_COPYCONTENTS and ! 827: when we can be sure to have both info for conversion: end of parameter ! 828: list is such a point, but CURLFORM_CONTENTTYPE is also used here as a ! 829: natural separator between content data definitions; this seems to be ! 830: in accordance with FormAdd() behavior. */ ! 831: ! 832: /* Allocate the local curl_forms array. */ ! 833: ! 834: lformlen = ALLOC_GRANULE; ! 835: lforms = malloc(lformlen * sizeof(*lforms)); ! 836: ! 837: if(!lforms) ! 838: return CURL_FORMADD_MEMORY; ! 839: ! 840: /* Process the arguments, copying them into local array, latching conversion ! 841: indexes and converting when needed. */ ! 842: ! 843: result = CURL_FORMADD_OK; ! 844: nargs = 0; ! 845: contentx = -1; ! 846: lengthx = -1; ! 847: namex = -1; ! 848: namelengthx = -1; ! 849: forms = (struct curl_forms *) NULL; ! 850: va_start(arg, last_post); ! 851: ! 852: for(;;) { ! 853: /* Make sure there is still room for an item in local array. */ ! 854: ! 855: if(nargs >= lformlen) { ! 856: lformlen += ALLOC_GRANULE; ! 857: tforms = realloc(lforms, lformlen * sizeof(*lforms)); ! 858: ! 859: if(!tforms) { ! 860: result = CURL_FORMADD_MEMORY; ! 861: break; ! 862: } ! 863: ! 864: lforms = tforms; ! 865: } ! 866: ! 867: /* Get next option. */ ! 868: ! 869: if(forms) { ! 870: /* Get option from array. */ ! 871: ! 872: option = forms->option; ! 873: value = forms->value; ! 874: forms++; ! 875: } ! 876: else { ! 877: /* Get option from arguments. */ ! 878: ! 879: option = va_arg(arg, CURLformoption); ! 880: ! 881: if(option == CURLFORM_END) ! 882: break; ! 883: } ! 884: ! 885: /* Dispatch by option. */ ! 886: ! 887: switch(option) { ! 888: ! 889: case CURLFORM_END: ! 890: forms = (struct curl_forms *) NULL; /* Leave array mode. */ ! 891: continue; ! 892: ! 893: case CURLFORM_ARRAY: ! 894: if(!forms) { ! 895: forms = va_arg(arg, struct curl_forms *); ! 896: continue; ! 897: } ! 898: ! 899: result = CURL_FORMADD_ILLEGAL_ARRAY; ! 900: break; ! 901: ! 902: case CURLFORM_COPYNAME: ! 903: option = CURLFORM_PTRNAME; /* Static for now. */ ! 904: ! 905: case CURLFORM_PTRNAME: ! 906: if(namex >= 0) ! 907: result = CURL_FORMADD_OPTION_TWICE; ! 908: ! 909: namex = nargs; ! 910: ! 911: if(!forms) { ! 912: value = va_arg(arg, char *); ! 913: nameccsid = (unsigned int) va_arg(arg, long); ! 914: } ! 915: else { ! 916: nameccsid = (unsigned int) forms->value; ! 917: forms++; ! 918: } ! 919: ! 920: break; ! 921: ! 922: case CURLFORM_COPYCONTENTS: ! 923: if(contentx >= 0) ! 924: result = CURL_FORMADD_OPTION_TWICE; ! 925: ! 926: contentx = nargs; ! 927: ! 928: if(!forms) { ! 929: value = va_arg(arg, char *); ! 930: contentccsid = (unsigned int) va_arg(arg, long); ! 931: } ! 932: else { ! 933: contentccsid = (unsigned int) forms->value; ! 934: forms++; ! 935: } ! 936: ! 937: break; ! 938: ! 939: case CURLFORM_PTRCONTENTS: ! 940: case CURLFORM_BUFFERPTR: ! 941: if(!forms) ! 942: value = va_arg(arg, char *); /* No conversion. */ ! 943: ! 944: break; ! 945: ! 946: case CURLFORM_CONTENTSLENGTH: ! 947: lengthx = nargs; ! 948: ! 949: if(!forms) ! 950: value = (char *) va_arg(arg, long); ! 951: ! 952: break; ! 953: ! 954: case CURLFORM_CONTENTLEN: ! 955: lengthx = nargs; ! 956: ! 957: if(!forms) ! 958: value = (char *) va_arg(arg, curl_off_t); ! 959: ! 960: break; ! 961: ! 962: case CURLFORM_NAMELENGTH: ! 963: namelengthx = nargs; ! 964: ! 965: if(!forms) ! 966: value = (char *) va_arg(arg, long); ! 967: ! 968: break; ! 969: ! 970: case CURLFORM_BUFFERLENGTH: ! 971: if(!forms) ! 972: value = (char *) va_arg(arg, long); ! 973: ! 974: break; ! 975: ! 976: case CURLFORM_CONTENTHEADER: ! 977: if(!forms) ! 978: value = (char *) va_arg(arg, struct curl_slist *); ! 979: ! 980: break; ! 981: ! 982: case CURLFORM_STREAM: ! 983: if(!forms) ! 984: value = (char *) va_arg(arg, void *); ! 985: ! 986: break; ! 987: ! 988: case CURLFORM_CONTENTTYPE: ! 989: /* If a previous content has been encountered, convert it now. */ ! 990: ! 991: if(Curl_formadd_convert(lforms, contentx, lengthx, contentccsid) < 0) { ! 992: result = CURL_FORMADD_MEMORY; ! 993: break; ! 994: } ! 995: ! 996: contentx = -1; ! 997: lengthx = -1; ! 998: /* Fall into default. */ ! 999: ! 1000: default: ! 1001: /* Must be a convertible string. */ ! 1002: ! 1003: if(!Curl_is_formadd_string(option)) { ! 1004: result = CURL_FORMADD_UNKNOWN_OPTION; ! 1005: break; ! 1006: } ! 1007: ! 1008: if(!forms) { ! 1009: value = va_arg(arg, char *); ! 1010: ccsid = (unsigned int) va_arg(arg, long); ! 1011: } ! 1012: else { ! 1013: ccsid = (unsigned int) forms->value; ! 1014: forms++; ! 1015: } ! 1016: ! 1017: /* Do the conversion. */ ! 1018: ! 1019: lforms[nargs].value = value; ! 1020: ! 1021: if(Curl_formadd_convert(lforms, nargs, -1, ccsid) < 0) { ! 1022: result = CURL_FORMADD_MEMORY; ! 1023: break; ! 1024: } ! 1025: ! 1026: value = lforms[nargs].value; ! 1027: } ! 1028: ! 1029: if(result != CURL_FORMADD_OK) ! 1030: break; ! 1031: ! 1032: lforms[nargs].value = value; ! 1033: lforms[nargs++].option = option; ! 1034: } ! 1035: ! 1036: va_end(arg); ! 1037: ! 1038: /* Convert the name and the last content, now that we know their lengths. */ ! 1039: ! 1040: if(result == CURL_FORMADD_OK && namex >= 0) { ! 1041: if(Curl_formadd_convert(lforms, namex, namelengthx, nameccsid) < 0) ! 1042: result = CURL_FORMADD_MEMORY; ! 1043: else ! 1044: lforms[namex].option = CURLFORM_COPYNAME; /* Force copy. */ ! 1045: } ! 1046: ! 1047: if(result == CURL_FORMADD_OK) { ! 1048: if(Curl_formadd_convert(lforms, contentx, lengthx, contentccsid) < 0) ! 1049: result = CURL_FORMADD_MEMORY; ! 1050: else ! 1051: contentx = -1; ! 1052: } ! 1053: ! 1054: /* Do the formadd with our converted parameters. */ ! 1055: ! 1056: if(result == CURL_FORMADD_OK) { ! 1057: lforms[nargs].option = CURLFORM_END; ! 1058: result = curl_formadd(httppost, last_post, ! 1059: CURLFORM_ARRAY, lforms, CURLFORM_END); ! 1060: } ! 1061: ! 1062: /* Terminate. */ ! 1063: ! 1064: Curl_formadd_release_local(lforms, nargs, contentx); ! 1065: return result; ! 1066: } ! 1067: ! 1068: ! 1069: typedef struct { ! 1070: curl_formget_callback append; ! 1071: void * arg; ! 1072: unsigned int ccsid; ! 1073: } cfcdata; ! 1074: ! 1075: ! 1076: static size_t ! 1077: Curl_formget_callback_ccsid(void *arg, const char *buf, size_t len) ! 1078: ! 1079: { ! 1080: cfcdata * p; ! 1081: char *b; ! 1082: int l; ! 1083: size_t ret; ! 1084: ! 1085: p = (cfcdata *) arg; ! 1086: ! 1087: if((long) len <= 0) ! 1088: return (*p->append)(p->arg, buf, len); ! 1089: ! 1090: b = malloc(MAX_CONV_EXPANSION * len); ! 1091: ! 1092: if(!b) ! 1093: return (size_t) -1; ! 1094: ! 1095: l = convert(b, MAX_CONV_EXPANSION * len, p->ccsid, buf, len, ASCII_CCSID); ! 1096: ! 1097: if(l < 0) { ! 1098: free(b); ! 1099: return (size_t) -1; ! 1100: } ! 1101: ! 1102: ret = (*p->append)(p->arg, b, l); ! 1103: free(b); ! 1104: return ret == l? len: -1; ! 1105: } ! 1106: ! 1107: ! 1108: int ! 1109: curl_formget_ccsid(struct curl_httppost *form, void *arg, ! 1110: curl_formget_callback append, unsigned int ccsid) ! 1111: ! 1112: { ! 1113: cfcdata lcfc; ! 1114: ! 1115: lcfc.append = append; ! 1116: lcfc.arg = arg; ! 1117: lcfc.ccsid = ccsid; ! 1118: return curl_formget(form, (void *) &lcfc, Curl_formget_callback_ccsid); ! 1119: } ! 1120: ! 1121: ! 1122: CURLcode ! 1123: curl_easy_setopt_ccsid(CURL *curl, CURLoption tag, ...) ! 1124: ! 1125: { ! 1126: CURLcode result; ! 1127: va_list arg; ! 1128: struct Curl_easy *data; ! 1129: char *s; ! 1130: char *cp; ! 1131: unsigned int ccsid; ! 1132: curl_off_t pfsize; ! 1133: ! 1134: data = (struct Curl_easy *) curl; ! 1135: va_start(arg, tag); ! 1136: ! 1137: switch(tag) { ! 1138: ! 1139: case CURLOPT_ABSTRACT_UNIX_SOCKET: ! 1140: case CURLOPT_ALTSVC: ! 1141: case CURLOPT_CAINFO: ! 1142: case CURLOPT_CAPATH: ! 1143: case CURLOPT_COOKIE: ! 1144: case CURLOPT_COOKIEFILE: ! 1145: case CURLOPT_COOKIEJAR: ! 1146: case CURLOPT_COOKIELIST: ! 1147: case CURLOPT_CRLFILE: ! 1148: case CURLOPT_CUSTOMREQUEST: ! 1149: case CURLOPT_DEFAULT_PROTOCOL: ! 1150: case CURLOPT_DNS_SERVERS: ! 1151: case CURLOPT_DNS_INTERFACE: ! 1152: case CURLOPT_DNS_LOCAL_IP4: ! 1153: case CURLOPT_DNS_LOCAL_IP6: ! 1154: case CURLOPT_DOH_URL: ! 1155: case CURLOPT_EGDSOCKET: ! 1156: case CURLOPT_ENCODING: ! 1157: case CURLOPT_FTPPORT: ! 1158: case CURLOPT_FTP_ACCOUNT: ! 1159: case CURLOPT_FTP_ALTERNATIVE_TO_USER: ! 1160: case CURLOPT_INTERFACE: ! 1161: case CURLOPT_ISSUERCERT: ! 1162: case CURLOPT_KEYPASSWD: ! 1163: case CURLOPT_KRBLEVEL: ! 1164: case CURLOPT_LOGIN_OPTIONS: ! 1165: case CURLOPT_MAIL_AUTH: ! 1166: case CURLOPT_MAIL_FROM: ! 1167: case CURLOPT_NETRC_FILE: ! 1168: case CURLOPT_NOPROXY: ! 1169: case CURLOPT_PASSWORD: ! 1170: case CURLOPT_PINNEDPUBLICKEY: ! 1171: case CURLOPT_PRE_PROXY: ! 1172: case CURLOPT_PROXY: ! 1173: case CURLOPT_PROXYPASSWORD: ! 1174: case CURLOPT_PROXYUSERNAME: ! 1175: case CURLOPT_PROXYUSERPWD: ! 1176: case CURLOPT_PROXY_CAINFO: ! 1177: case CURLOPT_PROXY_CAPATH: ! 1178: case CURLOPT_PROXY_CRLFILE: ! 1179: case CURLOPT_PROXY_KEYPASSWD: ! 1180: case CURLOPT_PROXY_PINNEDPUBLICKEY: ! 1181: case CURLOPT_PROXY_SERVICE_NAME: ! 1182: case CURLOPT_PROXY_SSLCERT: ! 1183: case CURLOPT_PROXY_SSLCERTTYPE: ! 1184: case CURLOPT_PROXY_SSLKEY: ! 1185: case CURLOPT_PROXY_SSLKEYTYPE: ! 1186: case CURLOPT_PROXY_SSL_CIPHER_LIST: ! 1187: case CURLOPT_PROXY_TLS13_CIPHERS: ! 1188: case CURLOPT_PROXY_TLSAUTH_PASSWORD: ! 1189: case CURLOPT_PROXY_TLSAUTH_TYPE: ! 1190: case CURLOPT_PROXY_TLSAUTH_USERNAME: ! 1191: case CURLOPT_RANDOM_FILE: ! 1192: case CURLOPT_RANGE: ! 1193: case CURLOPT_REFERER: ! 1194: case CURLOPT_REQUEST_TARGET: ! 1195: case CURLOPT_RTSP_SESSION_ID: ! 1196: case CURLOPT_RTSP_STREAM_URI: ! 1197: case CURLOPT_RTSP_TRANSPORT: ! 1198: case CURLOPT_SASL_AUTHZID: ! 1199: case CURLOPT_SERVICE_NAME: ! 1200: case CURLOPT_SOCKS5_GSSAPI_SERVICE: ! 1201: case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5: ! 1202: case CURLOPT_SSH_KNOWNHOSTS: ! 1203: case CURLOPT_SSH_PRIVATE_KEYFILE: ! 1204: case CURLOPT_SSH_PUBLIC_KEYFILE: ! 1205: case CURLOPT_SSLCERT: ! 1206: case CURLOPT_SSLCERTTYPE: ! 1207: case CURLOPT_SSLENGINE: ! 1208: case CURLOPT_SSLKEY: ! 1209: case CURLOPT_SSLKEYTYPE: ! 1210: case CURLOPT_SSL_CIPHER_LIST: ! 1211: case CURLOPT_TLS13_CIPHERS: ! 1212: case CURLOPT_TLSAUTH_PASSWORD: ! 1213: case CURLOPT_TLSAUTH_TYPE: ! 1214: case CURLOPT_TLSAUTH_USERNAME: ! 1215: case CURLOPT_UNIX_SOCKET_PATH: ! 1216: case CURLOPT_URL: ! 1217: case CURLOPT_USERAGENT: ! 1218: case CURLOPT_USERNAME: ! 1219: case CURLOPT_USERPWD: ! 1220: case CURLOPT_XOAUTH2_BEARER: ! 1221: s = va_arg(arg, char *); ! 1222: ccsid = va_arg(arg, unsigned int); ! 1223: ! 1224: if(s) { ! 1225: s = dynconvert(ASCII_CCSID, s, -1, ccsid); ! 1226: ! 1227: if(!s) { ! 1228: result = CURLE_OUT_OF_MEMORY; ! 1229: break; ! 1230: } ! 1231: } ! 1232: ! 1233: result = curl_easy_setopt(curl, tag, s); ! 1234: free(s); ! 1235: break; ! 1236: ! 1237: case CURLOPT_COPYPOSTFIELDS: ! 1238: /* Special case: byte count may have been given by CURLOPT_POSTFIELDSIZE ! 1239: prior to this call. In this case, convert the given byte count and ! 1240: replace the length according to the conversion result. */ ! 1241: s = va_arg(arg, char *); ! 1242: ccsid = va_arg(arg, unsigned int); ! 1243: ! 1244: pfsize = data->set.postfieldsize; ! 1245: ! 1246: if(!s || !pfsize || ccsid == NOCONV_CCSID || ccsid == ASCII_CCSID) { ! 1247: result = curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, s); ! 1248: break; ! 1249: } ! 1250: ! 1251: if(pfsize == -1) { ! 1252: /* Data is null-terminated. */ ! 1253: s = dynconvert(ASCII_CCSID, s, -1, ccsid); ! 1254: ! 1255: if(!s) { ! 1256: result = CURLE_OUT_OF_MEMORY; ! 1257: break; ! 1258: } ! 1259: } ! 1260: else { ! 1261: /* Data length specified. */ ! 1262: size_t len; ! 1263: ! 1264: if(pfsize < 0 || pfsize > SIZE_MAX) { ! 1265: result = CURLE_OUT_OF_MEMORY; ! 1266: break; ! 1267: } ! 1268: ! 1269: len = pfsize; ! 1270: pfsize = len * MAX_CONV_EXPANSION; ! 1271: ! 1272: if(pfsize > SIZE_MAX) ! 1273: pfsize = SIZE_MAX; ! 1274: ! 1275: cp = malloc(pfsize); ! 1276: ! 1277: if(!cp) { ! 1278: result = CURLE_OUT_OF_MEMORY; ! 1279: break; ! 1280: } ! 1281: ! 1282: pfsize = convert(cp, pfsize, ASCII_CCSID, s, len, ccsid); ! 1283: ! 1284: if(pfsize < 0) { ! 1285: free(cp); ! 1286: result = CURLE_OUT_OF_MEMORY; ! 1287: break; ! 1288: } ! 1289: ! 1290: data->set.postfieldsize = pfsize; /* Replace data size. */ ! 1291: s = cp; ! 1292: } ! 1293: ! 1294: result = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, s); ! 1295: data->set.str[STRING_COPYPOSTFIELDS] = s; /* Give to library. */ ! 1296: break; ! 1297: ! 1298: case CURLOPT_ERRORBUFFER: /* This is an output buffer. */ ! 1299: default: ! 1300: result = Curl_vsetopt(curl, tag, arg); ! 1301: break; ! 1302: } ! 1303: ! 1304: va_end(arg); ! 1305: return result; ! 1306: } ! 1307: ! 1308: ! 1309: char * ! 1310: curl_form_long_value(long value) ! 1311: ! 1312: { ! 1313: /* ILE/RPG cannot cast an integer to a pointer. This procedure does it. */ ! 1314: ! 1315: return (char *) value; ! 1316: } ! 1317: ! 1318: ! 1319: char * ! 1320: curl_pushheader_bynum_cssid(struct curl_pushheaders *h, ! 1321: size_t num, unsigned int ccsid) ! 1322: ! 1323: { ! 1324: char *d = (char *) NULL; ! 1325: char *s = curl_pushheader_bynum(h, num); ! 1326: ! 1327: if(s) ! 1328: d = dynconvert(ccsid, s, -1, ASCII_CCSID); ! 1329: ! 1330: return d; ! 1331: } ! 1332: ! 1333: ! 1334: char * ! 1335: curl_pushheader_byname_ccsid(struct curl_pushheaders *h, const char *header, ! 1336: unsigned int ccsidin, unsigned int ccsidout) ! 1337: ! 1338: { ! 1339: char *d = (char *) NULL; ! 1340: ! 1341: if(header) { ! 1342: header = dynconvert(ASCII_CCSID, header, -1, ccsidin); ! 1343: ! 1344: if(header) { ! 1345: char *s = curl_pushheader_byname(h, header); ! 1346: free((char *) header); ! 1347: ! 1348: if(s) ! 1349: d = dynconvert(ccsidout, s, -1, ASCII_CCSID); ! 1350: } ! 1351: } ! 1352: ! 1353: return d; ! 1354: } ! 1355: ! 1356: static CURLcode ! 1357: mime_string_call(curl_mimepart *part, const char *string, unsigned int ccsid, ! 1358: CURLcode (*mimefunc)(curl_mimepart *part, const char *string)) ! 1359: ! 1360: { ! 1361: char *s = (char *) NULL; ! 1362: CURLcode result; ! 1363: ! 1364: if(!string) ! 1365: return mimefunc(part, string); ! 1366: s = dynconvert(ASCII_CCSID, string, -1, ccsid); ! 1367: if(!s) ! 1368: return CURLE_OUT_OF_MEMORY; ! 1369: ! 1370: result = mimefunc(part, s); ! 1371: free(s); ! 1372: return result; ! 1373: } ! 1374: ! 1375: CURLcode ! 1376: curl_mime_name_ccsid(curl_mimepart *part, const char *name, unsigned int ccsid) ! 1377: ! 1378: { ! 1379: return mime_string_call(part, name, ccsid, curl_mime_name); ! 1380: } ! 1381: ! 1382: CURLcode ! 1383: curl_mime_filename_ccsid(curl_mimepart *part, ! 1384: const char *filename, unsigned int ccsid) ! 1385: ! 1386: { ! 1387: return mime_string_call(part, filename, ccsid, curl_mime_filename); ! 1388: } ! 1389: ! 1390: CURLcode ! 1391: curl_mime_type_ccsid(curl_mimepart *part, ! 1392: const char *mimetype, unsigned int ccsid) ! 1393: ! 1394: { ! 1395: return mime_string_call(part, mimetype, ccsid, curl_mime_type); ! 1396: } ! 1397: ! 1398: CURLcode ! 1399: curl_mime_encoder_ccsid(curl_mimepart *part, ! 1400: const char *encoding, unsigned int ccsid) ! 1401: ! 1402: { ! 1403: return mime_string_call(part, encoding, ccsid, curl_mime_encoder); ! 1404: } ! 1405: ! 1406: CURLcode ! 1407: curl_mime_filedata_ccsid(curl_mimepart *part, ! 1408: const char *filename, unsigned int ccsid) ! 1409: ! 1410: { ! 1411: return mime_string_call(part, filename, ccsid, curl_mime_filedata); ! 1412: } ! 1413: ! 1414: CURLcode ! 1415: curl_mime_data_ccsid(curl_mimepart *part, ! 1416: const char *data, size_t datasize, unsigned int ccsid) ! 1417: ! 1418: { ! 1419: char *s = (char *) NULL; ! 1420: CURLcode result; ! 1421: ! 1422: if(!data) ! 1423: return curl_mime_data(part, data, datasize); ! 1424: s = dynconvert(ASCII_CCSID, data, datasize, ccsid); ! 1425: if(!s) ! 1426: return CURLE_OUT_OF_MEMORY; ! 1427: ! 1428: result = curl_mime_data(part, s, datasize); ! 1429: free(s); ! 1430: return result; ! 1431: } ! 1432: ! 1433: CURLUcode ! 1434: curl_url_get_ccsid(CURLU *handle, CURLUPart what, char **part, ! 1435: unsigned int flags, unsigned int ccsid) ! 1436: ! 1437: { ! 1438: char *s = (char *)NULL; ! 1439: CURLUcode result; ! 1440: ! 1441: if(!part) ! 1442: return CURLUE_BAD_PARTPOINTER; ! 1443: ! 1444: *part = (char *)NULL; ! 1445: result = curl_url_get(handle, what, &s, flags); ! 1446: if(result == CURLUE_OK) { ! 1447: if(s) { ! 1448: *part = dynconvert(ccsid, s, -1, ASCII_CCSID); ! 1449: if(!*part) ! 1450: result = CURLUE_OUT_OF_MEMORY; ! 1451: } ! 1452: } ! 1453: if(s) ! 1454: free(s); ! 1455: return result; ! 1456: } ! 1457: ! 1458: CURLUcode ! 1459: curl_url_set_ccsid(CURLU *handle, CURLUPart what, const char *part, ! 1460: unsigned int flags, unsigned int ccsid) ! 1461: ! 1462: { ! 1463: char *s = (char *)NULL; ! 1464: CURLUcode result; ! 1465: ! 1466: if(part) { ! 1467: s = dynconvert(ASCII_CCSID, part, -1, ccsid); ! 1468: if(!s) ! 1469: return CURLUE_OUT_OF_MEMORY; ! 1470: } ! 1471: result = curl_url_set(handle, what, s, flags); ! 1472: if(s) ! 1473: free(s); ! 1474: return result; ! 1475: }