aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authormonnerat <pm@datasphere.ch>2010-04-19 11:17:46 +0200
committermonnerat <pm@datasphere.ch>2010-04-19 11:17:46 +0200
commit87fbcb4494dc942e38396e71a3c9c633d779a8f1 (patch)
tree94faaf04a76802292534bbab0713a8706703d081 /lib
parent4bfe07640c93f8dfd3af4bb76c8346ef4a129cc8 (diff)
parent5d93525f30e8b2a422644b4ec09a82ebf04283cd (diff)
Merge branch 'master' of github.com:bagder/curl
Diffstat (limited to 'lib')
-rw-r--r--lib/content_encoding.c1
-rw-r--r--lib/dict.c31
-rw-r--r--lib/file.c7
-rw-r--r--lib/ftp.c37
-rw-r--r--lib/gtls.c212
-rw-r--r--lib/gtls.h4
-rw-r--r--lib/http.c54
-rw-r--r--lib/imap.c12
-rw-r--r--lib/krb5.c4
-rw-r--r--lib/mprintf.c1
-rw-r--r--lib/parsedate.c3
-rw-r--r--lib/pop3.c25
-rw-r--r--lib/rtsp.c16
-rw-r--r--lib/smtp.c12
-rw-r--r--lib/socks.c9
-rw-r--r--lib/ssh.c20
-rw-r--r--lib/tftp.c22
-rw-r--r--lib/transfer.c12
-rw-r--r--lib/transfer.h4
-rw-r--r--lib/url.c5
-rw-r--r--lib/urldata.h1
-rw-r--r--lib/version.c6
22 files changed, 276 insertions, 222 deletions
diff --git a/lib/content_encoding.c b/lib/content_encoding.c
index 69aa7bcc6..a7511af7e 100644
--- a/lib/content_encoding.c
+++ b/lib/content_encoding.c
@@ -255,7 +255,6 @@ static enum {
return GZIP_UNDERFLOW;
len -= 2;
- data += 2;
}
*headerlen = totallen - len;
diff --git a/lib/dict.c b/lib/dict.c
index 1deab76ec..d86923a9f 100644
--- a/lib/dict.c
+++ b/lib/dict.c
@@ -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);
}
}
diff --git a/lib/file.c b/lib/file.c
index 6c14ee8e6..91176aa11 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -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 */
diff --git a/lib/ftp.c b/lib/ftp.c
index f821d124d..95e2a1200 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -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;
diff --git a/lib/gtls.c b/lib/gtls.c
index 92d780530..4f5edaf78 100644
--- a/lib/gtls.c
+++ b/lib/gtls.c
@@ -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);
- return CURLE_OK;
+ 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;
+ }
+ }
}
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,20 +647,88 @@ 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,
@@ -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;
diff --git a/lib/gtls.h b/lib/gtls.h
index 9fe618a32..da3489bc3 100644
--- a/lib/gtls.h
+++ b/lib/gtls.h
@@ -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
diff --git a/lib/http.c b/lib/http.c
index 7ffc34d49..cfc09cd5e 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -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;
diff --git a/lib/imap.c b/lib/imap.c
index f7b895dde..cdadd1713 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -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 */
diff --git a/lib/krb5.c b/lib/krb5.c
index 92f2b7155..9fb44f2d7 100644
--- a/lib/krb5.c
+++ b/lib/krb5.c
@@ -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;
diff --git a/lib/mprintf.c b/lib/mprintf.c
index 1d93c5828..536c0c247 100644
--- a/lib/mprintf.c
+++ b/lib/mprintf.c
@@ -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';
diff --git a/lib/parsedate.c b/lib/parsedate.c
index 8e26f1c7e..26f7d84ce 100644
--- a/lib/parsedate.c
+++ b/lib/parsedate.c
@@ -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);
diff --git a/lib/pop3.c b/lib/pop3.c
index 4894f3c44..4d79eebb2 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -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 */
diff --git a/lib/rtsp.c b/lib/rtsp.c
index 8cc200bda..032f58f7e 100644
--- a/lib/rtsp.c
+++ b/lib/rtsp.c
@@ -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++;
diff --git a/lib/smtp.c b/lib/smtp.c
index 0974ecfb0..185bd4bde 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -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 */
diff --git a/lib/socks.c b/lib/socks.c
index eb7956798..df301ecec 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -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
diff --git a/lib/ssh.c b/lib/ssh.c
index ff5994b44..e4e5767c7 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -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;
diff --git a/lib/tftp.c b/lib/tftp.c
index dc21c542c..3c288b66e 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -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 */
}
diff --git a/lib/transfer.c b/lib/transfer.c
index 2d504050c..92a59d038 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -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;
}
diff --git a/lib/transfer.h b/lib/transfer.h
index 4c2bc9e02..790e1e3ef 100644
--- a/lib/transfer.h
+++ b/lib/transfer.h
@@ -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 */
diff --git a/lib/url.c b/lib/url.c
index 6dc267204..a84e69d35 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -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;
diff --git a/lib/urldata.h b/lib/urldata.h
index ad172d66a..02233b685 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -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;
diff --git a/lib/version.c b/lib/version.c
index aa86e3902..86cb113d7 100644
--- a/lib/version.c
+++ b/lib/version.c
@@ -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;