Newer
Older
if(rc != CURLE_OK) {
failf(data,
"CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s",
(int)rc, curl_easy_strerror(rc));
}
return(rc);
#ifdef HAVE_ICONV
/* do the translation ourselves */
const char *input_ptr;
char *output_ptr;
size_t in_bytes, out_bytes, rc;
int error;
/* open an iconv conversion descriptor if necessary */
if(data->utf8_cd == (iconv_t)-1) {
data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
CURL_ICONV_CODESET_FOR_UTF8);
if(data->utf8_cd == (iconv_t)-1) {
error = ERRNO;
failf(data,
"The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
CURL_ICONV_CODESET_OF_HOST,
CURL_ICONV_CODESET_FOR_UTF8,
error, strerror(error));
return CURLE_CONV_FAILED;
}
}
/* call iconv */
input_ptr = output_ptr = buffer;
in_bytes = out_bytes = length;
rc = iconv(data->utf8_cd, &input_ptr, &in_bytes,
Daniel Stenberg
committed
if((rc == ICONV_ERROR) || (in_bytes != 0)) {
error = ERRNO;
"The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
error, strerror(error));
return CURLE_CONV_FAILED;
}
Daniel Stenberg
committed
if(output_ptr < input_ptr) {
/* null terminate the now shorter output string */
*output_ptr = 0x00;
}
#else
failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
return CURLE_CONV_REQD;
#endif /* HAVE_ICONV */
}
return CURLE_OK;
}
#endif /* CURL_DOES_CONVERSIONS */
Daniel Stenberg
committed
static CURLcode easy_connection(struct SessionHandle *data,
curl_socket_t *sfd,
struct connectdata **connp)
{
if(data == NULL)
return CURLE_BAD_FUNCTION_ARGUMENT;
/* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */
if(!data->set.connect_only) {
failf(data, "CONNECT_ONLY is required!");
return CURLE_UNSUPPORTED_PROTOCOL;
}
*sfd = Curl_getconnectinfo(data, connp);
Daniel Stenberg
committed
if(*sfd == CURL_SOCKET_BAD) {
Daniel Stenberg
committed
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
failf(data, "Failed to get recent socket");
return CURLE_UNSUPPORTED_PROTOCOL;
}
return CURLE_OK;
}
/*
* Receives data from the connected socket. Use after successful
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
* Returns CURLE_OK on success, error code on error.
*/
CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
{
curl_socket_t sfd;
CURLcode ret;
ssize_t n1;
struct connectdata *c;
struct SessionHandle *data = (struct SessionHandle *)curl;
ret = easy_connection(data, &sfd, &c);
if(ret)
return ret;
*n = 0;
ret = Curl_read(c, sfd, buffer, buflen, &n1);
Daniel Stenberg
committed
if(ret != CURLE_OK)
return ret;
Daniel Stenberg
committed
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
*n = (size_t)n1;
return CURLE_OK;
}
/*
* Sends data over the connected socket. Use after successful
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
*/
CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen,
size_t *n)
{
curl_socket_t sfd;
CURLcode ret;
ssize_t n1;
struct connectdata *c = NULL;
struct SessionHandle *data = (struct SessionHandle *)curl;
ret = easy_connection(data, &sfd, &c);
if(ret)
return ret;
*n = 0;
ret = Curl_write(c, sfd, buffer, buflen, &n1);
if(n1 == -1)
return CURLE_SEND_ERROR;
/* detect EAGAIN */
if((CURLE_OK == ret) && (0 == n1))
return CURLE_AGAIN;
*n = (size_t)n1;
return ret;
}