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


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:08