Home | History | Annotate | Download | only in src
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel (at) 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 #include "tool_setup.h"
     23 
     24 #ifdef CURL_DOES_CONVERSIONS
     25 
     26 #ifdef HAVE_ICONV
     27 #  include <iconv.h>
     28 #endif
     29 
     30 #include "tool_convert.h"
     31 
     32 #include "memdebug.h" /* keep this as LAST include */
     33 
     34 #ifdef HAVE_ICONV
     35 
     36 /* curl tool iconv conversion descriptors */
     37 static iconv_t inbound_cd  = (iconv_t)-1;
     38 static iconv_t outbound_cd = (iconv_t)-1;
     39 
     40 /* set default codesets for iconv */
     41 #ifndef CURL_ICONV_CODESET_OF_NETWORK
     42 #  define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
     43 #endif
     44 
     45 /*
     46  * convert_to_network() is a curl tool function to convert
     47  * from the host encoding to ASCII on non-ASCII platforms.
     48  */
     49 CURLcode convert_to_network(char *buffer, size_t length)
     50 {
     51   /* translate from the host encoding to the network encoding */
     52   char *input_ptr, *output_ptr;
     53   size_t res, in_bytes, out_bytes;
     54 
     55   /* open an iconv conversion descriptor if necessary */
     56   if(outbound_cd == (iconv_t)-1) {
     57     outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
     58                              CURL_ICONV_CODESET_OF_HOST);
     59     if(outbound_cd == (iconv_t)-1) {
     60       return CURLE_CONV_FAILED;
     61     }
     62   }
     63   /* call iconv */
     64   input_ptr = output_ptr = buffer;
     65   in_bytes = out_bytes = length;
     66   res = iconv(outbound_cd, &input_ptr,  &in_bytes,
     67               &output_ptr, &out_bytes);
     68   if((res == (size_t)-1) || (in_bytes != 0)) {
     69     return CURLE_CONV_FAILED;
     70   }
     71 
     72   return CURLE_OK;
     73 }
     74 
     75 /*
     76  * convert_from_network() is a curl tool function
     77  * for performing ASCII conversions on non-ASCII platforms.
     78  */
     79 CURLcode convert_from_network(char *buffer, size_t length)
     80 {
     81   /* translate from the network encoding to the host encoding */
     82   char *input_ptr, *output_ptr;
     83   size_t res, in_bytes, out_bytes;
     84 
     85   /* open an iconv conversion descriptor if necessary */
     86   if(inbound_cd == (iconv_t)-1) {
     87     inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
     88                             CURL_ICONV_CODESET_OF_NETWORK);
     89     if(inbound_cd == (iconv_t)-1) {
     90       return CURLE_CONV_FAILED;
     91     }
     92   }
     93   /* call iconv */
     94   input_ptr = output_ptr = buffer;
     95   in_bytes = out_bytes = length;
     96   res = iconv(inbound_cd, &input_ptr,  &in_bytes,
     97               &output_ptr, &out_bytes);
     98   if((res == (size_t)-1) || (in_bytes != 0)) {
     99     return CURLE_CONV_FAILED;
    100   }
    101 
    102   return CURLE_OK;
    103 }
    104 
    105 void convert_cleanup(void)
    106 {
    107   /* close iconv conversion descriptors */
    108   if(inbound_cd != (iconv_t)-1)
    109     (void)iconv_close(inbound_cd);
    110   if(outbound_cd != (iconv_t)-1)
    111     (void)iconv_close(outbound_cd);
    112 }
    113 
    114 #endif /* HAVE_ICONV */
    115 
    116 char convert_char(curl_infotype infotype, char this_char)
    117 {
    118 /* determine how this specific character should be displayed */
    119   switch(infotype) {
    120   case CURLINFO_DATA_IN:
    121   case CURLINFO_DATA_OUT:
    122   case CURLINFO_SSL_DATA_IN:
    123   case CURLINFO_SSL_DATA_OUT:
    124     /* data, treat as ASCII */
    125     if((this_char >= 0x20) && (this_char < 0x7f)) {
    126       /* printable ASCII hex value: convert to host encoding */
    127       (void)convert_from_network(&this_char, 1);
    128     }
    129     else {
    130       /* non-printable ASCII, use a replacement character */
    131       return UNPRINTABLE_CHAR;
    132     }
    133     /* fall through to default */
    134   default:
    135     /* treat as host encoding */
    136     if(ISPRINT(this_char)
    137        &&  (this_char != '\t')
    138        &&  (this_char != '\r')
    139        &&  (this_char != '\n')) {
    140       /* printable characters excluding tabs and line end characters */
    141       return this_char;
    142     }
    143     break;
    144   }
    145   /* non-printable, use a replacement character  */
    146   return UNPRINTABLE_CHAR;
    147 }
    148 
    149 #endif /* CURL_DOES_CONVERSIONS */
    150 
    151