Merge branch 'master' of github.com:bagder/curl

This commit is contained in:
monnerat 2010-04-19 11:17:46 +02:00
commit 87fbcb4494
25 changed files with 282 additions and 225 deletions

View File

@ -7,6 +7,8 @@
Changelog
Daniel Stenberg (16 Apr 2010)
- Jerome Vouillon made the GnuTLS SSL handshake phase non-blocking.
- The recent overhaul of the SSL recv function made the GnuTLS specific code
treat a zero returned from gnutls_record_recv() as an error, and this caused
our HTTPS test cases to fail. We leave it to upper layer code to detect if

View File

@ -16,6 +16,7 @@ This release includes the following bugfixes:
o prevent needless reverse name lookups
o detect GSS on ancient Linux distros
o GnuTLS: EOF caused error when it wasn't
o GnuTLS: SSL handshake phase is non-blocking
This release includes the following known bugs:
@ -24,6 +25,6 @@ This release includes the following known bugs:
This release would not have looked like this without help, code, reports and
advice from friends like these:
Rainer Canavan, Paul Howarth
Rainer Canavan, Paul Howarth, Jerome Vouillon
Thanks! (and sorry if I forgot to mention someone)

View File

@ -255,7 +255,6 @@ static enum {
return GZIP_UNDERFLOW;
len -= 2;
data += 2;
}
*headerlen = totallen - len;

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -217,13 +217,12 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
free(eword);
if(result)
if(result) {
failf(data, "Failed sending DICT request");
else
result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
-1, NULL); /* no upload */
if(result)
return result;
}
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
-1, NULL); /* no upload */
}
else if(Curl_raw_nequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
Curl_raw_nequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
@ -265,15 +264,12 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
free(eword);
if(result)
if(result) {
failf(data, "Failed sending DICT request");
else
result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
-1, NULL); /* no upload */
if(result)
return result;
}
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
-1, NULL); /* no upload */
}
else {
@ -290,13 +286,12 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
"CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
"%s\r\n"
"QUIT\r\n", ppath);
if(result)
if(result) {
failf(data, "Failed sending DICT request");
else
result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
-1, NULL);
if(result)
return result;
}
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, -1, NULL);
}
}

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -146,7 +146,7 @@ static CURLcode file_range(struct connectdata *conn)
if(data->state.use_range && data->state.range) {
from=curlx_strtoofft(data->state.range, &ptr, 0);
while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-')))
while(*ptr && (isspace((int)*ptr) || (*ptr=='-')))
ptr++;
to=curlx_strtoofft(ptr, &ptr2, 0);
if(ptr == ptr2) {
@ -161,11 +161,10 @@ static CURLcode file_range(struct connectdata *conn)
}
else if(from < 0) {
/* -Y */
totalsize = -from;
data->req.maxdownload = -from;
data->state.resume_from = from;
DEBUGF(infof(data, "RANGE the last %" FORMAT_OFF_T " bytes\n",
totalsize));
-from));
}
else {
/* X-Y */

View File

@ -820,7 +820,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
/* resolv ip/host to ip */
rc = Curl_resolv(conn, host, 0, &h);
if(rc == CURLRESOLV_PENDING)
rc = Curl_wait_for_resolv(conn, &h);
(void)Curl_wait_for_resolv(conn, &h);
if(h) {
res = h->addr;
/* when we return from this function, we can forget about this entry
@ -1378,7 +1378,7 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
infof(data, "File already completely uploaded\n");
/* no data to transfer */
result=Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
/* Set ->transfer so that we won't get any error in
* ftp_done() because we didn't transfer anything! */
@ -1630,8 +1630,9 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
*/
rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &addr);
if(rc == CURLRESOLV_PENDING)
/* BLOCKING */
rc = Curl_wait_for_resolv(conn, &addr);
/* BLOCKING, ignores the return code but 'addr' will be NULL in
case of failure */
(void)Curl_wait_for_resolv(conn, &addr);
connectport =
(unsigned short)conn->port; /* we connect to the proxy's port */
@ -1647,7 +1648,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
rc = Curl_resolv(conn, newhost, newport, &addr);
if(rc == CURLRESOLV_PENDING)
/* BLOCKING */
rc = Curl_wait_for_resolv(conn, &addr);
(void)Curl_wait_for_resolv(conn, &addr);
connectport = newport; /* we connect to the remote port */
@ -1973,7 +1974,7 @@ static CURLcode ftp_state_post_retr_size(struct connectdata *conn,
if(ftp->downloadsize == 0) {
/* no data to transfer */
result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
infof(data, "File already completely downloaded\n");
/* Set ->transfer so that we won't get any error in ftp_done()
@ -2115,8 +2116,8 @@ static CURLcode ftp_state_stor_resp(struct connectdata *conn,
/* set the SO_SNDBUF for the secondary socket for those who need it */
Curl_sndbufset(conn->sock[SECONDARYSOCKET]);
result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
SECONDARYSOCKET, ftp->bytecountp);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
SECONDARYSOCKET, ftp->bytecountp);
state(conn, FTP_STOP);
conn->proto.ftpc.pp.pending_resp = TRUE; /* expect a server response */
@ -2229,11 +2230,8 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
infof(data, "Getting file with size: %" FORMAT_OFF_T "\n", size);
/* FTP download: */
result=Curl_setup_transfer(conn, SECONDARYSOCKET, size, FALSE,
ftp->bytecountp,
-1, NULL); /* no upload here */
if(result)
return result;
Curl_setup_transfer(conn, SECONDARYSOCKET, size, FALSE,
ftp->bytecountp, -1, NULL); /* no upload here */
conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
state(conn, FTP_STOP);
@ -3285,7 +3283,6 @@ ftp_pasv_verbose(struct connectdata *conn,
static CURLcode ftp_range(struct connectdata *conn)
{
curl_off_t from, to;
curl_off_t totalsize=-1;
char *ptr;
char *ptr2;
struct SessionHandle *data = conn->data;
@ -3293,7 +3290,7 @@ static CURLcode ftp_range(struct connectdata *conn)
if(data->state.use_range && data->state.range) {
from=curlx_strtoofft(data->state.range, &ptr, 0);
while(ptr && *ptr && (ISSPACE(*ptr) || (*ptr=='-')))
while(*ptr && (ISSPACE(*ptr) || (*ptr=='-')))
ptr++;
to=curlx_strtoofft(ptr, &ptr2, 0);
if(ptr == ptr2) {
@ -3308,16 +3305,14 @@ static CURLcode ftp_range(struct connectdata *conn)
}
else if(from < 0) {
/* -Y */
totalsize = -from;
data->req.maxdownload = -from;
data->state.resume_from = from;
DEBUGF(infof(conn->data, "FTP RANGE the last %" FORMAT_OFF_T " bytes\n",
totalsize));
-from));
}
else {
/* X-Y */
totalsize = to-from;
data->req.maxdownload = totalsize+1; /* include last byte */
data->req.maxdownload = (to-from)+1; /* include last byte */
data->state.resume_from = from;
DEBUGF(infof(conn->data, "FTP RANGE from %" FORMAT_OFF_T
" getting %" FORMAT_OFF_T " bytes\n",
@ -3393,7 +3388,7 @@ static CURLcode ftp_nextconnect(struct connectdata *conn)
if((result == CURLE_OK) && (ftp->transfer != FTPTRANSFER_BODY))
/* no data to transfer. FIX: it feels like a kludge to have this here
too! */
result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
/* end of transfer */
DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result));
@ -3820,7 +3815,7 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,
if(ftp->transfer != FTPTRANSFER_BODY)
/* no data to transfer */
result=Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
else if(!connected)
/* since we didn't connect now, we want do_more to get called */
conn->bits.do_more = TRUE;

View File

@ -182,54 +182,76 @@ static void unload_file(gnutls_datum data) {
}
/* this function does a BLOCKING SSL/TLS (re-)handshake */
/* this function does a SSL/TLS (re-)handshake */
static CURLcode handshake(struct connectdata *conn,
gnutls_session session,
int sockindex,
bool duringconnect)
bool duringconnect,
bool nonblocking)
{
struct SessionHandle *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
gnutls_session session = conn->ssl[sockindex].session;
curl_socket_t sockfd = conn->sock[sockindex];
long timeout_ms;
int rc;
if(!gtls_inited)
Curl_gtls_init();
do {
rc = gnutls_handshake(session);
int what;
if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) {
long timeout_ms = Curl_timeleft(conn, NULL, duringconnect);
while(1) {
/* check allowed time left */
timeout_ms = Curl_timeleft(conn, NULL, duringconnect);
if(timeout_ms < 0) {
/* a precaution, no need to continue if time already is up */
failf(data, "SSL connection timeout");
return CURLE_OPERATION_TIMEDOUT;
}
if(timeout_ms < 0) {
/* no need to continue if time already is up */
failf(data, "SSL connection timeout");
return CURLE_OPERATION_TIMEDOUT;
}
rc = Curl_socket_ready(conn->sock[sockindex],
conn->sock[sockindex], (int)timeout_ms);
if(rc > 0)
/* reabable or writable, go loop*/
continue;
else if(0 == rc) {
/* timeout */
failf(data, "SSL connection timeout");
return CURLE_OPERATION_TIMEDOUT;
}
else {
/* anything that gets here is fatally bad */
/* if ssl is expecting something, check if it's available. */
if(connssl->connecting_state == ssl_connect_2_reading
|| connssl->connecting_state == ssl_connect_2_writing) {
curl_socket_t writefd = ssl_connect_2_writing==
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
curl_socket_t readfd = ssl_connect_2_reading==
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
what = Curl_socket_ready(readfd, writefd,
nonblocking?0:(int)timeout_ms);
if(what < 0) {
/* fatal error */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
return CURLE_SSL_CONNECT_ERROR;
}
else if(0 == what) {
if(nonblocking) {
return CURLE_OK;
}
else {
/* timeout */
failf(data, "SSL connection timeout");
return CURLE_OPERATION_TIMEDOUT;
}
}
/* socket is readable or writable */
}
else
break;
} while(1);
if(rc < 0) {
failf(data, "gnutls_handshake() failed: %s", gnutls_strerror(rc));
return CURLE_SSL_CONNECT_ERROR;
rc = gnutls_handshake(session);
if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) {
connssl->connecting_state =
gnutls_record_get_direction(session)?
ssl_connect_2_writing:ssl_connect_2_reading;
if(nonblocking) {
return CURLE_OK;
}
} else if (rc < 0) {
failf(data, "gnutls_handshake() failed: %s", gnutls_strerror(rc));
} else {
/* Reset our connect state machine */
connssl->connecting_state = ssl_connect_1;
return CURLE_OK;
}
}
return CURLE_OK;
}
static gnutls_x509_crt_fmt do_file_type(const char *type)
@ -243,31 +265,14 @@ static gnutls_x509_crt_fmt do_file_type(const char *type)
return -1;
}
/*
* This function is called after the TCP connect has completed. Setup the TLS
* layer and do all necessary magic.
*/
CURLcode
Curl_gtls_connect(struct connectdata *conn,
int sockindex)
static CURLcode
gtls_connect_step1(struct connectdata *conn,
int sockindex)
{
static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
struct SessionHandle *data = conn->data;
gnutls_session session;
int rc;
unsigned int cert_list_size;
const gnutls_datum *chainp;
unsigned int verify_status;
gnutls_x509_crt x509_cert,x509_issuer;
gnutls_datum issuerp;
char certbuf[256]; /* big enough? */
size_t size;
unsigned int algo;
unsigned int bits;
time_t certclock;
const char *ptr;
void *ssl_sessionid;
size_t ssl_idsize;
bool sni = TRUE; /* default is SNI enabled */
@ -411,10 +416,29 @@ Curl_gtls_connect(struct connectdata *conn,
infof (data, "SSL re-using session ID\n");
}
rc = handshake(conn, session, sockindex, TRUE);
if(rc)
/* handshake() sets its own error message with failf() */
return rc;
return CURLE_OK;
}
static CURLcode
gtls_connect_step3(struct connectdata *conn,
int sockindex)
{
unsigned int cert_list_size;
const gnutls_datum *chainp;
unsigned int verify_status;
gnutls_x509_crt x509_cert,x509_issuer;
gnutls_datum issuerp;
char certbuf[256]; /* big enough? */
size_t size;
unsigned int algo;
unsigned int bits;
time_t certclock;
const char *ptr;
struct SessionHandle *data = conn->data;
gnutls_session session = conn->ssl[sockindex].session;
int rc;
int incache;
void *ssl_sessionid;
/* This function will return the peer's raw certificate (chain) as sent by
the peer. These certificates are in raw format (DER encoded for
@ -623,21 +647,89 @@ Curl_gtls_connect(struct connectdata *conn,
/* extract session ID to the allocated buffer */
gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
if(ssl_sessionid)
incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL));
if (incache) {
/* there was one before in the cache, so instead of risking that the
previous one was rejected, we just kill that and store the new */
Curl_ssl_delsessionid(conn, ssl_sessionid);
}
/* store this session id */
return Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize);
}
}
return CURLE_OK;
}
/*
* This function is called after the TCP connect has completed. Setup the TLS
* layer and do all necessary magic.
*/
/* We use connssl->connecting_state to keep track of the connection status;
there are three states: 'ssl_connect_1' (not started yet or complete),
'ssl_connect_2_reading' (waiting for data from server), and
'ssl_connect_2_writing' (waiting to be able to write).
*/
static CURLcode
gtls_connect_common(struct connectdata *conn,
int sockindex,
bool nonblocking,
bool *done)
{
int rc;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
/* Initiate the connection, if not already done */
if(ssl_connect_1==connssl->connecting_state) {
rc = gtls_connect_step1 (conn, sockindex);
if(rc)
return rc;
}
rc = handshake(conn, sockindex, TRUE, nonblocking);
if(rc)
/* handshake() sets its own error message with failf() */
return rc;
/* Finish connecting once the handshake is done */
if(ssl_connect_1==connssl->connecting_state) {
rc = gtls_connect_step3(conn, sockindex);
if(rc)
return rc;
}
*done = ssl_connect_1==connssl->connecting_state;
return CURLE_OK;
}
CURLcode
Curl_gtls_connect_nonblocking(struct connectdata *conn,
int sockindex,
bool *done)
{
return gtls_connect_common(conn, sockindex, TRUE, done);
}
CURLcode
Curl_gtls_connect(struct connectdata *conn,
int sockindex)
{
CURLcode retcode;
bool done = FALSE;
retcode = gtls_connect_common(conn, sockindex, FALSE, &done);
if(retcode)
return retcode;
DEBUGASSERT(done);
return CURLE_OK;
}
/* for documentation see Curl_ssl_send() in sslgen.h */
ssize_t Curl_gtls_send(struct connectdata *conn,
int sockindex,
@ -769,7 +861,7 @@ ssize_t Curl_gtls_recv(struct connectdata *conn, /* connection data */
if(ret == GNUTLS_E_REHANDSHAKE) {
/* BLOCKING call, this is bad but a work-around for now. Fixing this "the
proper way" takes a whole lot of work. */
CURLcode rc = handshake(conn, conn->ssl[num].session, num, FALSE);
CURLcode rc = handshake(conn, num, FALSE, FALSE);
if(rc)
/* handshake() writes error message on its own */
*curlcode = rc;

View File

@ -27,6 +27,9 @@
int Curl_gtls_init(void);
int Curl_gtls_cleanup(void);
CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex);
CURLcode Curl_gtls_connect_nonblocking(struct connectdata *conn,
int sockindex,
bool *done);
/* tell GnuTLS to close down all open information regarding connections (and
thus session ID caching etc) */
@ -52,6 +55,7 @@ int Curl_gtls_seed(struct SessionHandle *data);
#define curlssl_init Curl_gtls_init
#define curlssl_cleanup Curl_gtls_cleanup
#define curlssl_connect Curl_gtls_connect
#define curlssl_connect_nonblocking Curl_gtls_connect_nonblocking
#define curlssl_session_free(x) Curl_gtls_session_free(x)
#define curlssl_close_all Curl_gtls_close_all
#define curlssl_close Curl_gtls_close

View File

@ -1817,9 +1817,9 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done)
}
#endif
#ifdef USE_SSLEAY
/* This function is OpenSSL-specific. It should be made to query the generic
SSL layer instead. */
#if defined(USE_SSLEAY) || defined(USE_GNUTLS)
/* This function is for OpenSSL and GnuTLS only. It should be made to query
the generic SSL layer instead. */
static int https_getsock(struct connectdata *conn,
curl_socket_t *socks,
int numsocks)
@ -1844,17 +1844,6 @@ static int https_getsock(struct connectdata *conn,
return CURLE_OK;
}
#else
#ifdef USE_GNUTLS
static int https_getsock(struct connectdata *conn,
curl_socket_t *socks,
int numsocks)
{
(void)conn;
(void)socks;
(void)numsocks;
return GETSOCK_BLANK;
}
#else
#ifdef USE_NSS
static int https_getsock(struct connectdata *conn,
curl_socket_t *socks,
@ -1879,7 +1868,6 @@ static int https_getsock(struct connectdata *conn,
#endif
#endif
#endif
#endif
/*
* Curl_http_done() gets called from Curl_done() after a single HTTP request
@ -2665,14 +2653,13 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return result;
result = Curl_add_buffer_send(req_buffer, conn,
&data->info.request_size, 0, FIRSTSOCKET);
&data->info.request_size, 0, FIRSTSOCKET);
if(result)
failf(data, "Failed sending POST request");
else
/* setup variables for the upcoming transfer */
result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount,
-1, NULL);
Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
-1, NULL);
break;
}
@ -2740,10 +2727,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
failf(data, "Failed sending POST request");
else
/* setup variables for the upcoming transfer */
result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount,
FIRSTSOCKET,
&http->writebytecount);
Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount, FIRSTSOCKET,
&http->writebytecount);
if(result) {
Curl_formclean(&http->sendit); /* free that whole lot */
@ -2793,10 +2779,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
failf(data, "Failed sending PUT request");
else
/* prepare for transfer */
result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount,
postsize?FIRSTSOCKET:-1,
postsize?&http->writebytecount:NULL);
Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount, postsize?FIRSTSOCKET:-1,
postsize?&http->writebytecount:NULL);
if(result)
return result;
break;
@ -2943,11 +2928,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(result)
failf(data, "Failed sending HTTP POST request");
else
result =
Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount,
http->postdata?FIRSTSOCKET:-1,
http->postdata?&http->writebytecount:NULL);
Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount, http->postdata?FIRSTSOCKET:-1,
http->postdata?&http->writebytecount:NULL);
break;
default:
@ -2963,10 +2946,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
failf(data, "Failed sending HTTP request");
else
/* HTTP GET/HEAD download: */
result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount,
http->postdata?FIRSTSOCKET:-1,
http->postdata?&http->writebytecount:NULL);
Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
http->postdata?FIRSTSOCKET:-1,
http->postdata?&http->writebytecount:NULL);
}
if(result)
return result;

View File

@ -436,12 +436,11 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn,
if(!filesize)
/* the entire data is already transfered! */
result=Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
else
/* IMAP download */
result=Curl_setup_transfer(conn, FIRSTSOCKET, filesize, FALSE,
imap->bytecountp,
-1, NULL); /* no upload here */
Curl_setup_transfer(conn, FIRSTSOCKET, filesize, FALSE,
imap->bytecountp, -1, NULL); /* no upload here */
data->req.maxdownload = filesize;
}
@ -924,15 +923,14 @@ static CURLcode imap_parse_url_path(struct connectdata *conn)
static CURLcode imap_dophase_done(struct connectdata *conn,
bool connected)
{
CURLcode result = CURLE_OK;
struct FTP *imap = conn->data->state.proto.imap;
(void)connected;
if(imap->transfer != FTPTRANSFER_BODY)
/* no data to transfer */
result=Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
return result;
return CURLE_OK;
}
/* called from multi.c while DOing */

View File

@ -1,6 +1,6 @@
/* GSSAPI/krb5 support for FTP - loosely based on old krb4.c
*
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
* Copyright (c) 1995, 1996, 1997, 1998, 1999, 2010 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* Copyright (c) 2004 - 2009 Daniel Stenberg
* All rights reserved.
@ -163,7 +163,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
{
int ret;
char *p;
const char *host = conn->host->name;
const char *host = conn->host.name;
ssize_t nread;
curl_socklen_t l = sizeof(conn->local_addr);
struct SessionHandle *data = conn->data;

View File

@ -963,7 +963,6 @@ static int dprintf_formatf(
/* RECURSIVE USAGE */
len = curl_msnprintf(fptr, left, ".%ld", prec);
fptr += len;
left -= len;
}
if(p->flags & FLAGS_LONG)
*fptr++ = 'l';

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -370,7 +370,6 @@ int Curl_parsedate(const char *date, time_t *output)
(3 == sscanf(date, "%02d:%02d:%02d", &hournum, &minnum, &secnum))) {
/* time stamp! */
date += 8;
found = TRUE;
}
else {
val = (int)strtol(date, &end, 10);

View File

@ -311,10 +311,10 @@ static CURLcode pop3_state_user_resp(struct connectdata *conn,
failf(data, "Access denied. %c", pop3code);
result = CURLE_LOGIN_DENIED;
}
/* send PASS */
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "PASS %s",
pop3->passwd?pop3->passwd:"");
else
/* send PASS */
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "PASS %s",
pop3->passwd?pop3->passwd:"");
if(result)
return result;
@ -359,9 +359,8 @@ static CURLcode pop3_state_retr_resp(struct connectdata *conn,
}
/* POP3 download */
result=Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE,
pop3->bytecountp,
-1, NULL); /* no upload here */
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE,
pop3->bytecountp, -1, NULL); /* no upload here */
if(pp->cache) {
/* At this point there is a bunch of data in the header "cache" that is
@ -403,9 +402,8 @@ static CURLcode pop3_state_list_resp(struct connectdata *conn,
}
/* POP3 download */
result=Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE,
pop3->bytecountp,
-1, NULL); /* no upload here */
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, pop3->bytecountp,
-1, NULL); /* no upload here */
if(pp->cache) {
/* cache holds the email ID listing */
@ -863,18 +861,17 @@ static CURLcode pop3_parse_url_path(struct connectdata *conn)
static CURLcode pop3_dophase_done(struct connectdata *conn,
bool connected)
{
CURLcode result = CURLE_OK;
struct FTP *pop3 = conn->data->state.proto.pop3;
struct pop3_conn *pop3c = &conn->proto.pop3c;
(void)connected;
(void)connected;
if(pop3->transfer != FTPTRANSFER_BODY)
/* no data to transfer */
result=Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
free(pop3c->mailbox);
return result;
return CURLE_OK;
}
/* called from multi.c while DOing */

View File

@ -254,8 +254,8 @@ CURLcode Curl_rtsp(struct connectdata *conn, bool *done)
}
if(rtspreq == RTSPREQ_RECEIVE) {
result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount, -1, NULL);
Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount, -1, NULL);
return result;
}
@ -503,15 +503,9 @@ CURLcode Curl_rtsp(struct connectdata *conn, bool *done)
return result;
}
result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
&http->readbytecount,
putsize?FIRSTSOCKET:-1,
putsize?&http->writebytecount:NULL);
if(result) {
failf(data, "Failed RTSP transfer");
return result;
}
Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
putsize?FIRSTSOCKET:-1,
putsize?&http->writebytecount:NULL);
/* Increment the CSeq on success */
data->state.rtsp_next_client_CSeq++;

View File

@ -840,7 +840,6 @@ static CURLcode smtp_state_data_resp(struct connectdata *conn,
int smtpcode,
smtpstate instate)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct FTP *smtp = data->state.proto.smtp;
@ -852,11 +851,11 @@ static CURLcode smtp_state_data_resp(struct connectdata *conn,
}
/* SMTP upload */
result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
FIRSTSOCKET, smtp->bytecountp);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
FIRSTSOCKET, smtp->bytecountp);
state(conn, SMTP_STOP);
return result;
return CURLE_OK;
}
/* for the POSTDATA response, which is received after the entire DATA
@ -1331,18 +1330,17 @@ static CURLcode smtp_disconnect(struct connectdata *conn)
static CURLcode smtp_dophase_done(struct connectdata *conn,
bool connected)
{
CURLcode result = CURLE_OK;
struct FTP *smtp = conn->data->state.proto.smtp;
struct smtp_conn *smtpc= &conn->proto.smtpc;
(void)connected;
if(smtp->transfer != FTPTRANSFER_BODY)
/* no data to transfer */
result=Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
free(smtpc->domain);
return result;
return CURLE_OK;
}
/* called from multi.c while DOing */

View File

@ -172,8 +172,8 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
return CURLE_COULDNT_RESOLVE_PROXY;
if(rc == CURLRESOLV_PENDING)
/* this requires that we're in "wait for resolve" state */
rc = Curl_wait_for_resolv(conn, &dns);
/* ignores the return code, but 'dns' remains NULL on failure */
(void)Curl_wait_for_resolv(conn, &dns);
/*
* We cannot use 'hostent' as a struct that Curl_resolv() returns. It
@ -597,9 +597,12 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
if(rc == CURLRESOLV_ERROR)
return CURLE_COULDNT_RESOLVE_HOST;
if(rc == CURLRESOLV_PENDING)
if(rc == CURLRESOLV_PENDING) {
/* this requires that we're in "wait for resolve" state */
rc = Curl_wait_for_resolv(conn, &dns);
if(rc)
return rc;
}
/*
* We cannot use 'hostent' as a struct that Curl_resolv() returns. It

View File

@ -1556,8 +1556,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
Curl_pgrsSetUploadSize(data, data->set.infilesize);
}
/* upload data */
result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL,
FIRSTSOCKET, NULL);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
/* not set by Curl_setup_transfer to preserve keepon bits */
conn->sockfd = conn->writesockfd;
@ -1850,7 +1849,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
sshc->readdir_longentry = NULL;
/* no data to transfer */
result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
state(conn, SSH_STOP);
break;
@ -1910,7 +1909,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
char *ptr2;
from=curlx_strtoofft(conn->data->state.range, &ptr, 0);
while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-')))
while(*ptr && (isspace((int)*ptr) || (*ptr=='-')))
ptr++;
to=curlx_strtoofft(ptr, &ptr2, 0);
if((ptr == ptr2) /* no "to" value given */
@ -1975,14 +1974,14 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
/* Setup the actual download */
if(data->req.size == 0) {
/* no data to transfer */
result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
infof(data, "File already completely downloaded\n");
state(conn, SSH_STOP);
break;
}
else {
result = Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
FALSE, NULL, -1, NULL);
Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
FALSE, NULL, -1, NULL);
/* not set by Curl_setup_transfer to preserve keepon bits */
conn->writesockfd = conn->sockfd;
@ -2107,8 +2106,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
}
/* upload data */
result = Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
FIRSTSOCKET, NULL);
Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
FIRSTSOCKET, NULL);
/* not set by Curl_setup_transfer to preserve keepon bits */
conn->sockfd = conn->writesockfd;
@ -2159,8 +2158,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
/* download data */
bytecount = (curl_off_t)sb.st_size;
data->req.maxdownload = (curl_off_t)sb.st_size;
result = Curl_setup_transfer(conn, FIRSTSOCKET,
bytecount, FALSE, NULL, -1, NULL);
Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
/* not set by Curl_setup_transfer to preserve keepon bits */
conn->writesockfd = conn->sockfd;

View File

@ -659,7 +659,6 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
4, SEND_4TH_ARG,
(struct sockaddr *)&state->remote_addr,
state->remote_addrlen);
/* Check all sbytes were sent */
if(sbytes<0) {
failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
return CURLE_SEND_ERROR;
@ -670,10 +669,10 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
case TFTP_EVENT_ERROR:
setpacketevent(&state->spacket, TFTP_EVENT_ERROR);
setpacketblock(&state->spacket, state->block);
sbytes = sendto(state->sockfd, (void *)state->spacket.data,
4, SEND_4TH_ARG,
(struct sockaddr *)&state->remote_addr,
state->remote_addrlen);
(void)sendto(state->sockfd, (void *)state->spacket.data,
4, SEND_4TH_ARG,
(struct sockaddr *)&state->remote_addr,
state->remote_addrlen);
/* don't bother with the return code, but if the socket is still up we
* should be a good TFTP client and let the server know we're done */
state->state = TFTP_STATE_FIN;
@ -798,10 +797,9 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
state->state = TFTP_STATE_FIN;
setpacketevent(&state->spacket, TFTP_EVENT_ERROR);
setpacketblock(&state->spacket, state->block);
sbytes = sendto(state->sockfd, (void *)state->spacket.data,
4, SEND_4TH_ARG,
(struct sockaddr *)&state->remote_addr,
state->remote_addrlen);
(void)sendto(state->sockfd, (void *)state->spacket.data, 4, SEND_4TH_ARG,
(struct sockaddr *)&state->remote_addr,
state->remote_addrlen);
/* don't bother with the return code, but if the socket is still up we
* should be a good TFTP client and let the server know we're done */
state->state = TFTP_STATE_FIN;
@ -1296,7 +1294,7 @@ static CURLcode tftp_easy_statemach(struct connectdata *conn)
}
/* Tell curl we're done */
result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
return(result);
}
@ -1330,7 +1328,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
*done = (bool)(state->state == TFTP_STATE_FIN);
if(*done)
/* Tell curl we're done */
result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
}
else {
/* no timeouts to handle, check our socket */
@ -1352,7 +1350,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
*done = (bool)(state->state == TFTP_STATE_FIN);
if(*done)
/* Tell curl we're done */
result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
}
/* if rc == 0, then select() timed out */
}

View File

@ -2113,9 +2113,9 @@ CURLcode Curl_perform(struct SessionHandle *data)
/* Curl_do() failed, clean up left-overs in the done-call, but note
that at some cases the conn pointer is NULL when Curl_do() failed
and the connection cache is very small so only call Curl_done() if
conn is still "alive".
*/
res2 = Curl_done(&conn, res, FALSE);
conn is still "alive". */
/* ignore return code since we already have an error to return */
(void)Curl_done(&conn, res, FALSE);
/*
* Important: 'conn' cannot be used here, since it may have been closed
@ -2169,7 +2169,7 @@ CURLcode Curl_perform(struct SessionHandle *data)
* Curl_setup_transfer() is called to setup some basic properties for the
* upcoming transfer.
*/
CURLcode
void
Curl_setup_transfer(
struct connectdata *conn, /* connection data */
int sockindex, /* socket index to read from or -1 */
@ -2214,9 +2214,8 @@ Curl_setup_transfer(
/* we want header and/or body, if neither then don't do this! */
if(k->getheader || !data->set.opt_no_body) {
if(conn->sockfd != CURL_SOCKET_BAD) {
if(conn->sockfd != CURL_SOCKET_BAD)
k->keepon |= KEEP_RECV;
}
if(conn->writesockfd != CURL_SOCKET_BAD) {
/* HTTP 1.1 magic:
@ -2246,5 +2245,4 @@ Curl_setup_transfer(
} /* if(conn->writesockfd != CURL_SOCKET_BAD) */
} /* if(k->getheader || !data->set.opt_no_body) */
return CURLE_OK;
}

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -49,7 +49,7 @@ CURLcode Curl_reconnect_request(struct connectdata **connp);
CURLcode Curl_retry_request(struct connectdata *conn, char **url);
/* This sets up a forthcoming transfer */
CURLcode
void
Curl_setup_transfer (struct connectdata *data,
int sockindex, /* socket index to read from or -1 */
curl_off_t size, /* -1 if unknown at this point */

View File

@ -4779,9 +4779,8 @@ static CURLcode create_conn(struct SessionHandle *data,
return result;
}
result = Curl_setup_transfer(conn, -1, -1, FALSE,
NULL, /* no download */
-1, NULL); /* no upload */
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
-1, NULL); /* no upload */
}
return result;

View File

@ -231,6 +231,7 @@ struct ssl_connect_data {
#ifdef USE_GNUTLS
gnutls_session session;
gnutls_certificate_credentials cred;
ssl_connect_state connecting_state;
#endif /* USE_GNUTLS */
#ifdef USE_NSS
PRFileDesc *handle;

View File

@ -107,9 +107,15 @@ char *curl_version(void)
ptr += len;
#endif
#ifdef USE_LIBSSH2
(void)snprintf(ptr, left, " libssh2/%s", CURL_LIBSSH2_VERSION);
/*
If another lib version is added below libssh2, this code would instead
have to do:
len = snprintf(ptr, left, " libssh2/%s", CURL_LIBSSH2_VERSION);
left -= len;
ptr += len;
*/
#endif
return version;

View File

@ -3247,7 +3247,7 @@ static int parseconfig(const char *filename,
break;
}
alloced_param=TRUE;
line = (char*) unslashquote(line, param);
(void)unslashquote(line, param);
}
else {
param=line; /* parameter starts here */