Commit 587b0678 authored by Andy Cedilnik's avatar Andy Cedilnik
Browse files

New Curl version 7.10.3

parent 6c61762b
......@@ -2,7 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 1.5)
PROJECT(LIBCURL C)
SET(PACKAGE "curl")
SET(VERSION "7.10.2")
SET(VERSION "7.10.3")
SET(PACKAGE_TARNAME " ")
SET(OPERATING_SYSTEM ${CMAKE_SYSTEM_NAME})
......
......@@ -61,6 +61,8 @@ static void decodeQuantum(unsigned char *dest, char *src)
x = (x << 6) + 62;
else if(src[i] == '/')
x = (x << 6) + 63;
else if(src[i] == '=')
x = (x << 6);
}
dest[2] = (unsigned char)(x & 255); x >>= 8;
......@@ -78,6 +80,7 @@ static void base64Decode(unsigned char *dest, char *src, int *rawLength)
int length = 0;
int equalsTerm = 0;
int i;
int numQuantums;
unsigned char lastQuantum[3];
while((src[length] != '=') && src[length])
......@@ -85,16 +88,18 @@ static void base64Decode(unsigned char *dest, char *src, int *rawLength)
while(src[length+equalsTerm] == '=')
equalsTerm++;
numQuantums = (length + equalsTerm) / 4;
if(rawLength)
*rawLength = (length * 3 / 4) - equalsTerm;
*rawLength = (numQuantums * 3) - equalsTerm;
for(i = 0; i < length/4 - 1; i++) {
for(i = 0; i < numQuantums - 1; i++) {
decodeQuantum(dest, src);
dest += 3; src += 4;
}
decodeQuantum(lastQuantum, src);
for(i = 0; i < 3 - equalsTerm; i++) dest[i] = lastQuantum[i];
for(i = 0; i < 3 - equalsTerm; i++)
dest[i] = lastQuantum[i];
}
......@@ -194,7 +199,8 @@ int Curl_base64_decode(const char *str, void *data)
#define TEST_NEED_SUCK
void *suck(int *);
int main(int argc, char **argv, char **envp) {
int main(int argc, char **argv, char **envp)
{
char *base64;
int base64Len;
unsigned char *data;
......@@ -220,7 +226,8 @@ int main(int argc, char **argv, char **envp) {
#define TEST_NEED_SUCK
void *suck(int *);
int main(int argc, char **argv, char **envp) {
int main(int argc, char **argv, char **envp)
{
char *base64;
int base64Len;
unsigned char *data;
......@@ -233,7 +240,6 @@ int main(int argc, char **argv, char **envp) {
fprintf(stderr, "%d\n", dataLen);
fwrite(data,1,dataLen,stdout);
free(base64); free(data);
return 0;
}
......@@ -241,7 +247,8 @@ int main(int argc, char **argv, char **envp) {
#ifdef TEST_NEED_SUCK
/* this function 'sucks' in as much as possible from stdin */
void *suck(int *lenptr) {
void *suck(int *lenptr)
{
int cursize = 8192;
unsigned char *buf = NULL;
int lastread;
......@@ -260,7 +267,6 @@ void *suck(int *lenptr) {
}
#endif
/*
* local variables:
* eval: (load-file "../curl-mode.el")
......
......@@ -176,10 +176,9 @@ int waitconnect(int sockfd, /* socket */
/* timeout, no connect today */
return 1;
if(FD_ISSET(sockfd, &errfd)) {
if(FD_ISSET(sockfd, &errfd))
/* error condition caught */
return 2;
}
/* we have a connect! */
return 0;
......@@ -380,6 +379,11 @@ CURLcode Curl_is_connected(struct connectdata *conn,
return CURLE_OPERATION_TIMEOUTED;
}
}
if(conn->bits.tcpconnect) {
/* we are connected already! */
*connected = TRUE;
return CURLE_OK;
}
/* check for connect without timeout as we want to return immediately */
rc = waitconnect(sockfd, 0);
......@@ -646,6 +650,15 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
}
}
/* The '1 == rc' comes from the waitconnect(), and not from connect().
We can be sure of this since connect() cannot return 1. */
if((1 == rc) && (data->state.used_interface == Curl_if_multi)) {
/* Timeout when running the multi interface, we return here with a
CURLE_OK return code. */
rc = 0;
break;
}
if(0 == rc) {
int err = socketerror(sockfd);
if ((0 == err) || (EISCONN == err)) {
......@@ -658,12 +671,6 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
}
if(0 != rc) {
if(data->state.used_interface == Curl_if_multi) {
/* When running the multi interface, we bail out here */
rc = 0;
break;
}
/* get a new timeout for next attempt */
after = Curl_tvnow();
timeout_ms -= Curl_tvdiff(after, before);
......
......@@ -96,7 +96,9 @@ typedef int (*curl_progress_callback)(void *clientp,
double ultotal,
double ulnow);
#define CURL_MAX_WRITE_SIZE 20480
/* Tests have proven that 20K is a very bad buffer size for uploads on
Windows, while 16K for some odd reason performed a lot better. */
#define CURL_MAX_WRITE_SIZE 16384
typedef size_t (*curl_write_callback)(char *buffer,
size_t size,
......@@ -160,7 +162,7 @@ typedef enum {
CURLE_FTP_COULDNT_RETR_FILE, /* 19 */
CURLE_FTP_WRITE_ERROR, /* 20 */
CURLE_FTP_QUOTE_ERROR, /* 21 */
CURLE_HTTP_NOT_FOUND, /* 22 */
CURLE_HTTP_RETURNED_ERROR, /* 22 */
CURLE_WRITE_ERROR, /* 23 */
CURLE_MALFORMAT_USER, /* 24 - user name is illegally specified */
CURLE_FTP_COULDNT_STOR_FILE, /* 25 - failed FTP upload */
......@@ -207,6 +209,7 @@ typedef enum {
/* Make a spelling correction for the operation timed-out define */
#define CURLE_OPERATION_TIMEDOUT CURLE_OPERATION_TIMEOUTED
#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
typedef enum {
CURLPROXY_HTTP = 0,
......@@ -610,6 +613,11 @@ typedef enum {
the response to be compressed. */
CINIT(ENCODING, OBJECTPOINT, 102),
/* Set pointer to private data */
CINIT(PRIVATE, OBJECTPOINT, 103),
/* Set aliases for HTTP 200 in the HTTP Response header */
CINIT(HTTP200ALIASES, OBJECTPOINT, 104),
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
......@@ -803,8 +811,8 @@ CURLcode curl_global_init(long flags);
void curl_global_cleanup(void);
/* This is the version number */
#define LIBCURL_VERSION "7.10.2"
#define LIBCURL_VERSION_NUM 0x070a02
#define LIBCURL_VERSION "7.10.3"
#define LIBCURL_VERSION_NUM 0x070a03
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
struct curl_slist {
......@@ -861,16 +869,13 @@ typedef enum {
CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19,
CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20,
CURLINFO_PRIVATE = CURLINFO_STRING + 21,
/* Fill in new entries here! */
CURLINFO_LASTONE = 21
CURLINFO_LASTONE = 22
} CURLINFO;
/* unfortunately, the easy.h and multi.h include files need options and info
stuff before they can be included! */
#include "easy.h" /* nothing in curl is fun without the easy stuff */
#include "multi.h"
typedef enum {
CURLCLOSEPOLICY_NONE, /* first, never use this */
......@@ -894,35 +899,56 @@ typedef enum {
* Setup defines, protos etc for the sharing stuff.
*/
/* Different types of locks that a share can aquire */
/* Different data locks for a single share */
typedef enum {
CURL_LOCK_DATA_NONE = 0,
CURL_LOCK_DATA_COOKIE = 1,
CURL_LOCK_DATA_DNS = 2,
CURL_LOCK_DATA_SSL_SESSION = 3,
CURL_LOCK_DATA_CONNECT = 4,
CURL_LOCK_DATA_LAST
} curl_lock_data;
/* Different lock access types */
typedef enum {
CURL_LOCK_TYPE_NONE = 0,
CURL_LOCK_TYPE_COOKIE = 1<<0,
CURL_LOCK_TYPE_DNS = 1<<1,
CURL_LOCK_TYPE_SSL_SESSION = 2<<1,
CURL_LOCK_TYPE_CONNECT = 2<<2,
CURL_LOCK_TYPE_LAST
} curl_lock_type;
CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */
CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */
CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */
CURL_LOCK_ACCESS_LAST /* never use */
} curl_lock_access;
typedef void (*curl_lock_function)(CURL *handle,
curl_lock_data data,
curl_lock_access access,
void *userptr);
typedef void (*curl_unlock_function)(CURL *handle,
curl_lock_data data,
void *userptr);
typedef void CURLSH;
typedef void (*curl_lock_function)(CURL *, curl_lock_type, void *);
typedef void (*curl_unlock_function)(CURL *, curl_lock_type, void *);
typedef enum {
CURLSHE_OK, /* all is fine */
CURLSHE_BAD_OPTION, /* 1 */
CURLSHE_IN_USE, /* 2 */
CURLSHE_INVALID, /* 3 */
CURLSHE_LAST /* never use */
} CURLSHcode;
typedef struct {
unsigned int specifier;
unsigned int locked;
unsigned int dirty;
curl_lock_function lockfunc;
curl_unlock_function unlockfunc;
void *clientdata;
} curl_share;
curl_share *curl_share_init (void);
CURLcode curl_share_setopt (curl_share *, curl_lock_type, int);
CURLcode curl_share_set_lock_function (curl_share *, curl_lock_function);
CURLcode curl_share_set_unlock_function (curl_share *, curl_unlock_function);
CURLcode curl_share_set_lock_data (curl_share *, void *);
CURLcode curl_share_destroy (curl_share *);
typedef enum {
CURLSHOPT_NONE, /* don't use */
CURLSHOPT_SHARE, /* specify a data type to share */
CURLSHOPT_UNSHARE, /* specify shich data type to stop sharing */
CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */
CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */
CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock
callback functions */
CURLSHOPT_LAST /* never use */
} CURLSHoption;
CURLSH *curl_share_init(void);
CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...);
CURLSHcode curl_share_cleanup(CURLSH *);
/****************************************************************************
* Structures for querying information about the curl library at runtime.
......@@ -965,4 +991,9 @@ curl_version_info_data *curl_version_info(CURLversion);
}
#endif
/* unfortunately, the easy.h and multi.h include files need options and info
stuff before they can be included! */
#include "easy.h" /* nothing in curl is fun without the easy stuff */
#include "multi.h"
#endif /* __CURL_CURL_H */
......@@ -233,13 +233,15 @@ CURLcode curl_easy_perform(CURL *curl)
{
struct SessionHandle *data = (struct SessionHandle *)curl;
if (!data->hostcache) {
if (Curl_global_host_cache_use(data)) {
data->hostcache = Curl_global_host_cache_get();
if (Curl_global_host_cache_use(data) && data->hostcache != Curl_global_host_cache_get()) {
if (data->hostcache) {
Curl_hash_destroy(data->hostcache);
}
else {
data->hostcache = Curl_hash_alloc(7, Curl_freeaddrinfo);
data->hostcache = Curl_global_host_cache_get();
}
if (!data->hostcache) {
data->hostcache = Curl_hash_alloc(7, Curl_freednsinfo);
}
return Curl_perform(data);
......
......@@ -41,6 +41,7 @@ char *curl_escape(const char *string, int length)
{
int alloc = (length?length:(int)strlen(string))+1;
char *ns = malloc(alloc);
char *testing_ptr = NULL;
unsigned char in;
int newlen = alloc;
int index=0;
......@@ -55,10 +56,15 @@ char *curl_escape(const char *string, int length)
newlen += 2; /* the size grows with two, since this'll become a %XX */
if(newlen > alloc) {
alloc *= 2;
ns = realloc(ns, alloc);
if(!ns)
testing_ptr = realloc(ns, alloc);
if(!testing_ptr) {
free( ns );
return NULL;
}
else {
ns = testing_ptr;
}
}
sprintf(&ns[index], "%%%02X", in);
index+=3;
......@@ -81,6 +87,10 @@ char *curl_unescape(const char *string, int length)
int index=0;
unsigned int hex;
if( !ns ) {
return NULL;
}
while(--alloc > 0) {
in = *string;
if('%' == in) {
......@@ -97,7 +107,6 @@ char *curl_unescape(const char *string, int length)
}
ns[index]=0; /* terminate it */
return ns;
}
void curl_free(void *p)
......
......@@ -1319,7 +1319,7 @@ int Curl_FormReader(char *buffer,
wantedsize = size * nitems;
if(!form->data)
return -1; /* nothing, error, empty */
return 0; /* nothing, error, empty */
do {
......
......@@ -173,9 +173,9 @@ static CURLcode AllowServerConnect(struct SessionHandle *data,
* response and extract the relevant return code for the invoking function.
*/
int Curl_GetFTPResponse(char *buf,
CURLcode Curl_GetFTPResponse(int *nreadp, /* return number of bytes read */
struct connectdata *conn,
int *ftpcode)
int *ftpcode) /* return the ftp-code */
{
/* Brand new implementation.
* We cannot read just one byte per read() and then go back to select()
......@@ -185,28 +185,21 @@ int Curl_GetFTPResponse(char *buf,
* line in a response or continue reading. */
int sockfd = conn->firstsocket;
int nread; /* total size read */
int perline; /* count bytes per line */
bool keepon=TRUE;
ssize_t gotbytes;
char *ptr;
int timeout = 3600; /* default timeout in seconds */
int timeout; /* timeout in seconds */
struct timeval interval;
fd_set rkeepfd;
fd_set readfd;
struct SessionHandle *data = conn->data;
char *line_start;
int code=0; /* default "error code" to return */
#define SELECT_OK 0
#define SELECT_ERROR 1 /* select() problems */
#define SELECT_TIMEOUT 2 /* took too long */
#define SELECT_MEMORY 3 /* no available memory */
#define SELECT_CALLBACK 4 /* aborted by callback */
int error = SELECT_OK;
int code=0; /* default ftp "error code" to return */
char *buf = data->state.buffer;
CURLcode result = CURLE_OK;
struct FTP *ftp = conn->proto.ftp;
struct timeval now = Curl_tvnow();
if (ftpcode)
*ftpcode = 0; /* 0 for errors */
......@@ -221,20 +214,25 @@ int Curl_GetFTPResponse(char *buf,
ptr=buf;
line_start = buf;
nread=0;
*nreadp=0;
perline=0;
keepon=TRUE;
while((nread<BUFSIZE) && (keepon && !error)) {
while((*nreadp<BUFSIZE) && (keepon && !result)) {
/* check and reset timeout value every lap */
if(data->set.timeout) {
if(data->set.timeout)
/* if timeout is requested, find out how much remaining time we have */
timeout = data->set.timeout - /* timeout time */
Curl_tvdiff(Curl_tvnow(), conn->now)/1000; /* spent time */
else
/* Even without a requested timeout, we only wait response_time
seconds for the full response to arrive before we bail out */
timeout = ftp->response_time -
Curl_tvdiff(Curl_tvnow(), now)/1000; /* spent time */
if(timeout <=0 ) {
failf(data, "Transfer aborted due to timeout");
return -SELECT_TIMEOUT; /* already too little time */
}
return CURLE_OPERATION_TIMEDOUT; /* already too little time */
}
if(!ftp->cache) {
......@@ -244,19 +242,18 @@ int Curl_GetFTPResponse(char *buf,
switch (select (sockfd+1, &readfd, NULL, NULL, &interval)) {
case -1: /* select() error, stop reading */
error = SELECT_ERROR;
failf(data, "Transfer aborted due to select() error");
result = CURLE_RECV_ERROR;
failf(data, "Transfer aborted due to select() error: %d", errno);
break;
case 0: /* timeout */
error = SELECT_TIMEOUT;
result = CURLE_OPERATION_TIMEDOUT;
failf(data, "Transfer aborted due to timeout");
break;
default:
error = SELECT_OK;
break;
}
}
if(SELECT_OK == error) {
if(CURLE_OK == result) {
/*
* This code previously didn't use the kerberos sec_read() code
* to read, but when we use Curl_read() it may do so. Do confirm
......@@ -272,8 +269,7 @@ int Curl_GetFTPResponse(char *buf,
ftp->cache_size = 0; /* zero the size just in case */
}
else {
int res = Curl_read(conn, sockfd, ptr,
BUFSIZE-nread, &gotbytes);
int res = Curl_read(conn, sockfd, ptr, BUFSIZE-*nreadp, &gotbytes);
if(res < 0)
/* EWOULDBLOCK */
continue; /* go looping again */
......@@ -286,7 +282,7 @@ int Curl_GetFTPResponse(char *buf,
;
else if(gotbytes <= 0) {
keepon = FALSE;
error = SELECT_ERROR;
result = CURLE_RECV_ERROR;
failf(data, "Connection aborted");
}
else {
......@@ -295,7 +291,7 @@ int Curl_GetFTPResponse(char *buf,
* line */
int i;
nread += gotbytes;
*nreadp += gotbytes;
for(i = 0; i < gotbytes; ptr++, i++) {
perline++;
if(*ptr=='\n') {
......@@ -315,7 +311,7 @@ int Curl_GetFTPResponse(char *buf,
result = Curl_client_write(data, CLIENTWRITE_HEADER,
line_start, perline);
if(result)
return -SELECT_CALLBACK;
return result;
#define lastline(line) (isdigit((int)line[0]) && isdigit((int)line[1]) && \
isdigit((int)line[2]) && (' ' == line[3]))
......@@ -350,13 +346,13 @@ int Curl_GetFTPResponse(char *buf,
if(ftp->cache)
memcpy(ftp->cache, line_start, ftp->cache_size);
else
return -SELECT_MEMORY; /**BANG**/
return CURLE_OUT_OF_MEMORY; /**BANG**/
}
} /* there was data */
} /* if(no error) */
} /* while there's buffer left and loop is requested */
if(!error)
if(!result)
code = atoi(buf);
#ifdef KRB4
......@@ -378,13 +374,10 @@ int Curl_GetFTPResponse(char *buf,
}
#endif
if(error)
return -error;
if(ftpcode)
*ftpcode=code; /* return the initial number like this */
return nread; /* total amount of bytes read */
return result;
}
/*
......@@ -417,6 +410,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
/* no need to duplicate them, the data struct won't change */
ftp->user = data->state.user;
ftp->passwd = data->state.passwd;
ftp->response_time = 3600; /* set default response time-out */
if (data->set.tunnel_thru_httpproxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */
......@@ -436,9 +430,9 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
/* The first thing we do is wait for the "220*" line: */
nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
if(nread < 0)
return CURLE_OPERATION_TIMEOUTED;
result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
if(result)
return result;
if(ftpcode != 220) {
failf(data, "This doesn't seem like a nice ftp-server response");
......@@ -467,9 +461,9 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
FTPSENDF(conn, "USER %s", ftp->user);
/* wait for feedback */
nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
if(nread < 0)
return CURLE_OPERATION_TIMEOUTED;
result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
if(result)
return result;
if(ftpcode == 530) {
/* 530 User ... access denied
......@@ -481,9 +475,9 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
/* 331 Password required for ...
(the server requires to send the user's password too) */
FTPSENDF(conn, "PASS %s", ftp->passwd);
nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
if(nread < 0)
return CURLE_OPERATION_TIMEOUTED;
result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
if(result)
return result;
if(ftpcode == 530) {
/* 530 Login incorrect.
......@@ -516,8 +510,11 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
/* we may need to issue a KAUTH here to have access to the files
* do it if user supplied a password
*/
if(data->state.passwd && *data->state.passwd)
Curl_krb_kauth(conn);
if(data->state.passwd && *data->state.passwd) {
result = Curl_krb_kauth(conn);
if(result)
return result;
}
#endif
}
else {
......@@ -529,9 +526,9 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
FTPSENDF(conn, "PWD", NULL);
/* wait for feedback */
nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
if(nread < 0)
return CURLE_OPERATION_TIMEOUTED;
result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
if(result)
return result;
if(ftpcode == 257) {
char *dir = (char *)malloc(nread+1);
......@@ -544,7 +541,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
The directory name can contain any character; embedded double-quotes