Annotation of embedaddon/curl/packages/OS400/ccsidcurl.c, revision 1.1
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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>