Newer
Older
/* 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
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
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
static CURLcode easy_connection(struct SessionHandle *data,
curl_socket_t *sfd,
struct connectdata **connp)
{
CURLcode ret;
long sockfd;
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;
}
ret = Curl_getconnectinfo(data, &sockfd, connp);
if(ret != CURLE_OK)
return ret;
if(sockfd == -1) {
failf(data, "Failed to get recent socket");
return CURLE_UNSUPPORTED_PROTOCOL;
}
*sfd = (curl_socket_t)sockfd; /* we know that this is actually a socket
descriptor so the typecast is fine here */
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;
int ret1;
ssize_t n1;
struct connectdata *c;
struct SessionHandle *data = (struct SessionHandle *)curl;
ret = easy_connection(data, &sfd, &c);
if(ret)
return ret;
*n = 0;
ret1 = Curl_read(c, sfd, buffer, buflen, &n1);
if(ret1 == -1)
return CURLE_AGAIN;
if(ret1 != CURLE_OK)
return ret1;
Daniel Stenberg
committed
1100
1101
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
*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;
}