Annotation of embedaddon/curl/packages/OS400/ccsidcurl.c, revision 1.1.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>