00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "curl_setup.h"
00024
00025 #ifdef CURL_DOES_CONVERSIONS
00026
00027 #include <curl/curl.h>
00028
00029 #include "non-ascii.h"
00030 #include "formdata.h"
00031 #include "sendf.h"
00032 #include "urldata.h"
00033
00034 #include "curl_memory.h"
00035
00036 #include "memdebug.h"
00037
00038 #ifdef HAVE_ICONV
00039 #include <iconv.h>
00040
00041 #ifndef CURL_ICONV_CODESET_OF_NETWORK
00042 #define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
00043 #endif
00044 #ifndef CURL_ICONV_CODESET_FOR_UTF8
00045 #define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8"
00046 #endif
00047 #define ICONV_ERROR (size_t)-1
00048 #endif
00049
00050
00051
00052
00053
00054 CURLcode Curl_convert_clone(struct Curl_easy *data,
00055 const char *indata,
00056 size_t insize,
00057 char **outbuf)
00058 {
00059 char *convbuf;
00060 CURLcode result;
00061
00062 convbuf = malloc(insize);
00063 if(!convbuf)
00064 return CURLE_OUT_OF_MEMORY;
00065
00066 memcpy(convbuf, indata, insize);
00067 result = Curl_convert_to_network(data, convbuf, insize);
00068 if(result) {
00069 free(convbuf);
00070 return result;
00071 }
00072
00073 *outbuf = convbuf;
00074
00075 return CURLE_OK;
00076 }
00077
00078
00079
00080
00081
00082 CURLcode Curl_convert_to_network(struct Curl_easy *data,
00083 char *buffer, size_t length)
00084 {
00085 if(data->set.convtonetwork) {
00086
00087 CURLcode result = data->set.convtonetwork(buffer, length);
00088 if(result) {
00089 failf(data,
00090 "CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %d: %s",
00091 (int)result, curl_easy_strerror(result));
00092 }
00093
00094 return result;
00095 }
00096 else {
00097 #ifdef HAVE_ICONV
00098
00099 char *input_ptr, *output_ptr;
00100 size_t in_bytes, out_bytes, rc;
00101 int error;
00102
00103
00104 if(data->outbound_cd == (iconv_t)-1) {
00105 data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
00106 CURL_ICONV_CODESET_OF_HOST);
00107 if(data->outbound_cd == (iconv_t)-1) {
00108 error = ERRNO;
00109 failf(data,
00110 "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
00111 CURL_ICONV_CODESET_OF_NETWORK,
00112 CURL_ICONV_CODESET_OF_HOST,
00113 error, strerror(error));
00114 return CURLE_CONV_FAILED;
00115 }
00116 }
00117
00118 input_ptr = output_ptr = buffer;
00119 in_bytes = out_bytes = length;
00120 rc = iconv(data->outbound_cd, (const char **)&input_ptr, &in_bytes,
00121 &output_ptr, &out_bytes);
00122 if((rc == ICONV_ERROR) || (in_bytes != 0)) {
00123 error = ERRNO;
00124 failf(data,
00125 "The Curl_convert_to_network iconv call failed with errno %i: %s",
00126 error, strerror(error));
00127 return CURLE_CONV_FAILED;
00128 }
00129 #else
00130 failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required");
00131 return CURLE_CONV_REQD;
00132 #endif
00133 }
00134
00135 return CURLE_OK;
00136 }
00137
00138
00139
00140
00141
00142 CURLcode Curl_convert_from_network(struct Curl_easy *data,
00143 char *buffer, size_t length)
00144 {
00145 if(data->set.convfromnetwork) {
00146
00147 CURLcode result = data->set.convfromnetwork(buffer, length);
00148 if(result) {
00149 failf(data,
00150 "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %d: %s",
00151 (int)result, curl_easy_strerror(result));
00152 }
00153
00154 return result;
00155 }
00156 else {
00157 #ifdef HAVE_ICONV
00158
00159 char *input_ptr, *output_ptr;
00160 size_t in_bytes, out_bytes, rc;
00161 int error;
00162
00163
00164 if(data->inbound_cd == (iconv_t)-1) {
00165 data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
00166 CURL_ICONV_CODESET_OF_NETWORK);
00167 if(data->inbound_cd == (iconv_t)-1) {
00168 error = ERRNO;
00169 failf(data,
00170 "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
00171 CURL_ICONV_CODESET_OF_HOST,
00172 CURL_ICONV_CODESET_OF_NETWORK,
00173 error, strerror(error));
00174 return CURLE_CONV_FAILED;
00175 }
00176 }
00177
00178 input_ptr = output_ptr = buffer;
00179 in_bytes = out_bytes = length;
00180 rc = iconv(data->inbound_cd, (const char **)&input_ptr, &in_bytes,
00181 &output_ptr, &out_bytes);
00182 if((rc == ICONV_ERROR) || (in_bytes != 0)) {
00183 error = ERRNO;
00184 failf(data,
00185 "Curl_convert_from_network iconv call failed with errno %i: %s",
00186 error, strerror(error));
00187 return CURLE_CONV_FAILED;
00188 }
00189 #else
00190 failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required");
00191 return CURLE_CONV_REQD;
00192 #endif
00193 }
00194
00195 return CURLE_OK;
00196 }
00197
00198
00199
00200
00201
00202 CURLcode Curl_convert_from_utf8(struct Curl_easy *data,
00203 char *buffer, size_t length)
00204 {
00205 if(data->set.convfromutf8) {
00206
00207 CURLcode result = data->set.convfromutf8(buffer, length);
00208 if(result) {
00209 failf(data,
00210 "CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s",
00211 (int)result, curl_easy_strerror(result));
00212 }
00213
00214 return result;
00215 }
00216 else {
00217 #ifdef HAVE_ICONV
00218
00219 const char *input_ptr;
00220 char *output_ptr;
00221 size_t in_bytes, out_bytes, rc;
00222 int error;
00223
00224
00225 if(data->utf8_cd == (iconv_t)-1) {
00226 data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
00227 CURL_ICONV_CODESET_FOR_UTF8);
00228 if(data->utf8_cd == (iconv_t)-1) {
00229 error = ERRNO;
00230 failf(data,
00231 "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
00232 CURL_ICONV_CODESET_OF_HOST,
00233 CURL_ICONV_CODESET_FOR_UTF8,
00234 error, strerror(error));
00235 return CURLE_CONV_FAILED;
00236 }
00237 }
00238
00239 input_ptr = output_ptr = buffer;
00240 in_bytes = out_bytes = length;
00241 rc = iconv(data->utf8_cd, &input_ptr, &in_bytes,
00242 &output_ptr, &out_bytes);
00243 if((rc == ICONV_ERROR) || (in_bytes != 0)) {
00244 error = ERRNO;
00245 failf(data,
00246 "The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
00247 error, strerror(error));
00248 return CURLE_CONV_FAILED;
00249 }
00250 if(output_ptr < input_ptr) {
00251
00252 *output_ptr = 0x00;
00253 }
00254 #else
00255 failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
00256 return CURLE_CONV_REQD;
00257 #endif
00258 }
00259
00260 return CURLE_OK;
00261 }
00262
00263
00264
00265
00266 void Curl_convert_init(struct Curl_easy *data)
00267 {
00268 #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
00269
00270 data->outbound_cd = (iconv_t)-1;
00271 data->inbound_cd = (iconv_t)-1;
00272 data->utf8_cd = (iconv_t)-1;
00273 #else
00274 (void)data;
00275 #endif
00276 }
00277
00278
00279
00280
00281 void Curl_convert_setup(struct Curl_easy *data)
00282 {
00283 data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
00284 CURL_ICONV_CODESET_OF_NETWORK);
00285 data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
00286 CURL_ICONV_CODESET_OF_HOST);
00287 data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
00288 CURL_ICONV_CODESET_FOR_UTF8);
00289 }
00290
00291
00292
00293
00294
00295 void Curl_convert_close(struct Curl_easy *data)
00296 {
00297 #ifdef HAVE_ICONV
00298
00299 if(data->inbound_cd != (iconv_t)-1) {
00300 iconv_close(data->inbound_cd);
00301 }
00302 if(data->outbound_cd != (iconv_t)-1) {
00303 iconv_close(data->outbound_cd);
00304 }
00305 if(data->utf8_cd != (iconv_t)-1) {
00306 iconv_close(data->utf8_cd);
00307 }
00308 #else
00309 (void)data;
00310 #endif
00311 }
00312
00313
00314
00315
00316
00317 CURLcode Curl_convert_form(struct Curl_easy *data, struct FormData *form)
00318 {
00319 CURLcode result;
00320
00321 if(!data)
00322 return CURLE_BAD_FUNCTION_ARGUMENT;
00323
00324 while(form) {
00325 if(form->type == FORM_DATA) {
00326 result = Curl_convert_to_network(data, form->line, form->length);
00327
00328 if(result)
00329 return result;
00330 }
00331
00332 form = form->next;
00333 }
00334
00335 return CURLE_OK;
00336 }
00337
00338 #endif