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>