Newer
Older
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* Copyright (C) 1998 - 2011, 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
* are also available at http://curl.haxx.se/docs/copyright.html.
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
***************************************************************************/
#include "setup.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <time.h>
#include <io.h>
#else
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#endif
#ifdef HAVE_SYS_TIME_H
#ifdef HAVE_NETDB_H
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifndef HAVE_SOCKET
#error "We can't compile without socket() support!"
#endif
#endif /* WIN32 */
#ifdef USE_LIBIDN
#include <idna.h>
#include <stringprep.h>
#ifdef HAVE_IDN_FREE_H
#include <idn-free.h>
#else
/* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */
void idn_free (void *ptr);
#endif
#ifndef HAVE_IDN_FREE
/* if idn_free() was not found in this version of libidn use free() instead */
#define idn_free(x) (free)(x)
#endif
#elif defined(USE_WIN32_IDN)
/* prototype for curl_win32_idn_to_ascii() */
int curl_win32_idn_to_ascii(const char *in, char **out);
#include "urldata.h"
#include "netrc.h"
#include "formdata.h"
Daniel Stenberg
committed
#include "sslgen.h"
Daniel Stenberg
committed
#include "transfer.h"
#include "sendf.h"
#include "progress.h"
#include "cookie.h"
#include "strerror.h"
#include "escape.h"
Daniel Stenberg
committed
#include "content_encoding.h"
#include "http_negotiate.h"
Daniel Stenberg
committed
#include "multiif.h"
#include "easyif.h"
Daniel Stenberg
committed
#include "speedcheck.h"
Daniel Stenberg
committed
#include "rawstr.h"
/* And now for the protocols */
#include "ftp.h"
#include "dict.h"
#include "telnet.h"
#include "tftp.h"
Daniel Stenberg
committed
#include "curl_ldap.h"
#include "imap.h"
Daniel Stenberg
committed
#include "url.h"
#include "inet_ntop.h"
Daniel Stenberg
committed
#include "socks.h"
Daniel Stenberg
committed
#include "rtsp.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
#include "memdebug.h"
/* Local static prototypes */
static long ConnectionKillOne(struct SessionHandle *data);
static void conn_free(struct connectdata *conn);
static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
Patrick Monnerat
committed
/*
* Protocol table.
*/
static const struct Curl_handler * const protocols[] = {
Patrick Monnerat
committed
#ifndef CURL_DISABLE_HTTP
&Curl_handler_http,
#endif
#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
&Curl_handler_https,
#endif
#ifndef CURL_DISABLE_FTP
&Curl_handler_ftp,
#endif
#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
&Curl_handler_ftps,
#endif
#ifndef CURL_DISABLE_TELNET
&Curl_handler_telnet,
#endif
#ifndef CURL_DISABLE_DICT
&Curl_handler_dict,
#endif
Patrick Monnerat
committed
&Curl_handler_ldap,
#if !defined(CURL_DISABLE_LDAPS) && \
((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
(!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
Patrick Monnerat
committed
&Curl_handler_ldaps,
#endif
Patrick Monnerat
committed
#ifndef CURL_DISABLE_FILE
&Curl_handler_file,
#endif
#ifndef CURL_DISABLE_TFTP
&Curl_handler_tftp,
#endif
#ifdef USE_LIBSSH2
&Curl_handler_scp,
&Curl_handler_sftp,
#endif
#ifndef CURL_DISABLE_IMAP
&Curl_handler_imap,
#ifdef USE_SSL
&Curl_handler_imaps,
#endif
#endif
#ifndef CURL_DISABLE_POP3
&Curl_handler_pop3,
#ifdef USE_SSL
&Curl_handler_pop3s,
#endif
#endif
#ifndef CURL_DISABLE_SMTP
&Curl_handler_smtp,
#ifdef USE_SSL
&Curl_handler_smtps,
#endif
#endif
Daniel Stenberg
committed
#ifndef CURL_DISABLE_RTSP
&Curl_handler_rtsp,
#endif
#ifndef CURL_DISABLE_GOPHER
&Curl_handler_gopher,
#endif
#ifdef USE_LIBRTMP
&Curl_handler_rtmp,
&Curl_handler_rtmpt,
&Curl_handler_rtmpe,
&Curl_handler_rtmpte,
&Curl_handler_rtmps,
&Curl_handler_rtmpts,
#endif
Patrick Monnerat
committed
(struct Curl_handler *) NULL
};
/*
* Dummy handler for undefined protocol schemes.
*/
static const struct Curl_handler Curl_handler_dummy = {
Patrick Monnerat
committed
"<no protocol>", /* scheme */
ZERO_NULL, /* setup_connection */
ZERO_NULL, /* do_it */
ZERO_NULL, /* done */
ZERO_NULL, /* do_more */
ZERO_NULL, /* connect_it */
ZERO_NULL, /* connecting */
ZERO_NULL, /* doing */
ZERO_NULL, /* proto_getsock */
ZERO_NULL, /* doing_getsock */
Daniel Stenberg
committed
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
Patrick Monnerat
committed
0, /* defport */
Patrick Monnerat
committed
};
void Curl_safefree(void *ptr)
{
if(ptr)
free(ptr);
}
static void close_connections(struct SessionHandle *data)
{
/* Loop through all open connections and kill them one by one */
}
Daniel Stenberg
committed
void Curl_freeset(struct SessionHandle * data)
{
/* Free all dynamic strings stored in the data->set substructure. */
enum dupstring i;
for(i=(enum dupstring)0; i < STRING_LAST; i++)
Daniel Stenberg
committed
Curl_safefree(data->set.str[i]);
}
static CURLcode setstropt(char **charp, char * s)
Daniel Stenberg
committed
{
/* Release the previous storage at `charp' and replace by a dynamic storage
copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
Daniel Stenberg
committed
if(*charp) {
Daniel Stenberg
committed
free(*charp);
*charp = (char *) NULL;
}
Daniel Stenberg
committed
if(s) {
Daniel Stenberg
committed
s = strdup(s);
Daniel Stenberg
committed
if(!s)
Daniel Stenberg
committed
return CURLE_OUT_OF_MEMORY;
*charp = s;
}
return CURLE_OK;
}
Daniel Stenberg
committed
static CURLcode setstropt_userpwd(char *option, char **user_storage,
char **pwd_storage)
{
char* separator;
CURLcode result = CURLE_OK;
Daniel Stenberg
committed
if(!option) {
/* we treat a NULL passed in as a hint to clear existing info */
Curl_safefree(*user_storage);
*user_storage = (char *) NULL;
Curl_safefree(*pwd_storage);
*pwd_storage = (char *) NULL;
return CURLE_OK;
}
Daniel Stenberg
committed
separator = strchr(option, ':');
if(separator != NULL) {
Daniel Stenberg
committed
/* store username part of option */
char * p;
size_t username_len = (size_t)(separator-option);
p = malloc(username_len+1);
if(!p)
result = CURLE_OUT_OF_MEMORY;
else {
memcpy(p, option, username_len);
p[username_len] = '\0';
Curl_safefree(*user_storage);
*user_storage = p;
}
/* store password part of option */
if(result == CURLE_OK)
Daniel Stenberg
committed
result = setstropt(pwd_storage, separator+1);
}
else {
result = setstropt(user_storage, option);
}
return result;
}
Daniel Stenberg
committed
CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src)
{
Daniel Stenberg
committed
enum dupstring i;
/* Copy src->set into dst->set first, then deal with the strings
afterwards */
dst->set = src->set;
/* clear all string pointers first */
memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
/* duplicate all strings */
for(i=(enum dupstring)0; i< STRING_LAST; i++) {
r = setstropt(&dst->set.str[i], src->set.str[i]);
Daniel Stenberg
committed
if(r != CURLE_OK)
Daniel Stenberg
committed
break;
}
/* If a failure occurred, freeing has to be performed externally. */
return r;
}
/*
* This is the internal function curl_easy_cleanup() calls. This should
* cleanup and free all resources associated with this sessionhandle.
*
* NOTE: if we ever add something that attempts to write to a socket or
* similar here, we must ignore SIGPIPE first. It is currently only done
* when curl_easy_perform() is invoked.
*/
Daniel Stenberg
committed
CURLcode Curl_close(struct SessionHandle *data)
struct Curl_multi *m = data->multi;
Daniel Stenberg
committed
/* only for debugging, scan through all connections and see if there's a
pipe reference still identifying this handle */
if(data->state.connc && data->state.connc->type == CONNCACHE_MULTI) {
struct conncache *c = data->state.connc;
struct curl_llist *pipeline;
Daniel Stenberg
committed
struct curl_llist_element *curr;
struct connectdata *connptr;
for(i=0; i< c->num; i++) {
connptr = c->connects[i];
if(!connptr)
continue;
pipeline = connptr->send_pipe;
if(pipeline) {
for(curr = pipeline->head; curr; curr=curr->next) {
Daniel Stenberg
committed
if(data == (struct SessionHandle *) curr->ptr) {
fprintf(stderr,
"problem we %p are still in send pipe for %p done %d\n",
data, connptr, (int)connptr->bits.done);
Daniel Stenberg
committed
}
}
}
pipeline = connptr->recv_pipe;
if(pipeline) {
for(curr = pipeline->head; curr; curr=curr->next) {
Daniel Stenberg
committed
if(data == (struct SessionHandle *) curr->ptr) {
fprintf(stderr,
"problem we %p are still in recv pipe for %p done %d\n",
data, connptr, (int)connptr->bits.done);
Daniel Stenberg
committed
}
}
}
pipeline = connptr->done_pipe;
if(pipeline) {
for(curr = pipeline->head; curr; curr=curr->next) {
if(data == (struct SessionHandle *) curr->ptr) {
fprintf(stderr,
"problem we %p are still in done pipe for %p done %d\n",
data, connptr, (int)connptr->bits.done);
}
}
}
Daniel Stenberg
committed
pipeline = connptr->pend_pipe;
if(pipeline) {
for(curr = pipeline->head; curr; curr=curr->next) {
Daniel Stenberg
committed
if(data == (struct SessionHandle *) curr->ptr) {
fprintf(stderr,
"problem we %p are still in pend pipe for %p done %d\n",
data, connptr, (int)connptr->bits.done);
Daniel Stenberg
committed
}
}
}
Daniel Stenberg
committed
}
}
#endif
Curl_expire(data, 0); /* shut off timers */
if(m)
/* This handle is still part of a multi handle, take care of this first
and detach this handle from there. */
curl_multi_remove_handle(data->multi, data);
/* Destroy the timeout list that is held in the easy handle. It is
/normally/ done by curl_multi_remove_handle() but this is "just in
case" */
if(data->state.timeoutlist) {
Curl_llist_destroy(data->state.timeoutlist, NULL);
data->state.timeoutlist = NULL;
}
Daniel Stenberg
committed
data->magic = 0; /* force a clear AFTER the possibly enforced removal from
the multi handle, since that function uses the magic
field! */
Daniel Stenberg
committed
if(data->state.connc) {
Daniel Stenberg
committed
if(data->state.connc->type == CONNCACHE_PRIVATE) {
/* close all connections still alive that are in the private connection
cache, as we no longer have the pointer left to the shared one. */
close_connections(data);
Daniel Stenberg
committed
/* free the connection cache if allocated privately */
Curl_rm_connc(data->state.connc);
Daniel Stenberg
committed
}
}
if(data->state.shared_conn) {
Daniel Stenberg
committed
/* marked to be used by a pending connection so we can't kill this handle
just yet */
data->state.closed = TRUE;
return CURLE_OK;
}
if(data->dns.hostcachetype == HCACHE_PRIVATE) {
Curl_hash_destroy(data->dns.hostcache);
data->dns.hostcachetype = HCACHE_NONE;
data->dns.hostcache = NULL;
}
Daniel Stenberg
committed
Daniel Stenberg
committed
if(data->state.rangestringalloc)
free(data->state.range);
Daniel Stenberg
committed
/* Free the pathbuffer */
Daniel Stenberg
committed
Curl_safefree(data->state.pathbuffer);
Curl_safefree(data->state.proto.generic);
/* Close down all open SSL info and sessions */
Daniel Stenberg
committed
Curl_ssl_close_all(data);
Daniel Stenberg
committed
Curl_safefree(data->state.first_host);
Curl_safefree(data->state.scratch);
Daniel Stenberg
committed
Curl_ssl_free_certinfo(data);
Daniel Stenberg
committed
if(data->change.referer_alloc)
free(data->change.referer);
Daniel Stenberg
committed
if(data->change.url_alloc)
free(data->change.url);
Curl_safefree(data->state.headerbuff);
Curl_flush_cookies(data, 1);
Curl_digest_cleanup(data);
Curl_safefree(data->info.contenttype);
Daniel Stenberg
committed
Curl_safefree(data->info.wouldredirect);
Daniel Stenberg
committed
/* this destroys the channel and we cannot use it anymore after this */
Curl_resolver_cleanup(data->state.resolver);
Daniel Stenberg
committed
Daniel Stenberg
committed
/* No longer a dirty share, if it exists */
Daniel Stenberg
committed
if(data->share) {
Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
Daniel Stenberg
committed
data->share->dirty--;
Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
}
Daniel Stenberg
committed
Daniel Stenberg
committed
Curl_freeset(data);
/* create a connection cache of a private or multi type */
struct conncache *Curl_mk_connc(int type,
{
/* It is subject for debate how many default connections to have for a multi
connection cache... */
struct conncache *c;
Daniel Stenberg
committed
if(type == CONNCACHE_PRIVATE) {
if(default_amount > max_amount)
default_amount = max_amount;
c = calloc(1, sizeof(struct conncache));
if(!c)
return NULL;
if(!c->connects) {
free(c);
return NULL;
}
c->num = default_amount;
return c;
}
/* Change number of entries of a connection cache */
CURLcode Curl_ch_connc(struct SessionHandle *data,
struct conncache *c,
long newamount)
{
struct connectdata **newptr;
if(newamount < 1)
newamount = 1; /* we better have at least one entry */
if(!c) {
/* we get a NULL pointer passed in as connection cache, which means that
there is no cache created for this SessionHandle just yet, we create a
brand new with the requested size.
*/
data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, newamount);
if(!data->state.connc)
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
}
if(newamount < c->num) {
/* Since this number is *decreased* from the existing number, we must
close the possibly open connections that live on the indexes that
are being removed!
NOTE: for conncache_multi cases we must make sure that we only
close handles not in use.
*/
for(i=newamount; i< c->num; i++)
Curl_disconnect(c->connects[i], /* dead_connection */ FALSE);
/* If the most recent connection is no longer valid, mark it
invalid. */
if(data->state.lastconnect <= newamount)
data->state.lastconnect = -1;
}
if(newamount > 0) {
newptr = realloc(c->connects, sizeof(struct connectdata *) * newamount);
if(!newptr)
/* we closed a few connections in vain, but so what? */
return CURLE_OUT_OF_MEMORY;
/* nullify the newly added pointers */
for(i=c->num; i<newamount; i++)
newptr[i] = NULL;
c->connects = newptr;
c->num = newamount;
}
/* we no longer support less than 1 as size for the connection cache, and
I'm not sure it ever worked to set it to zero */
return CURLE_OK;
}
/* Free a connection cache. This is called from Curl_close() and
curl_multi_cleanup(). */
void Curl_rm_connc(struct conncache *c)
{
if(c->connects) {
for(i = 0; i < c->num; ++i)
conn_free(c->connects[i]);
free(c->connects);
}
free(c);
}
/*
* Initialize the UserDefined fields within a SessionHandle.
* This may be safely called on a new or existing SessionHandle.
*/
CURLcode Curl_init_userdefined(struct UserDefined *set)
{
CURLcode res = CURLE_OK;
set->out = stdout; /* default output to stdout */
set->in = stdin; /* default input from stdin */
set->err = stderr; /* default stderr to stderr */
/* use fwrite as default function to store output */
set->fwrite_func = (curl_write_callback)fwrite;
/* use fread as default function to read input */
set->fread_func = (curl_read_callback)fread;
set->is_fread_set = 0;
set->is_fwrite_set = 0;
set->seek_func = ZERO_NULL;
set->seek_client = ZERO_NULL;
/* conversion callbacks for non-ASCII hosts */
set->convfromnetwork = ZERO_NULL;
set->convtonetwork = ZERO_NULL;
set->convfromutf8 = ZERO_NULL;
set->infilesize = -1; /* we don't know any size */
set->postfieldsize = -1; /* unknown size */
set->maxredirs = -1; /* allow any amount by default */
set->httpreq = HTTPREQ_GET; /* Default HTTP request */
Daniel Stenberg
committed
set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */
set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
Daniel Stenberg
committed
set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */
set->ftp_filemethod = FTPFILE_MULTICWD;
set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
/* Set the default size of the SSL session ID cache */
set->ssl.numsessions = 5;
set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */
set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
set->httpauth = CURLAUTH_BASIC; /* defaults to basic */
set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
/* make libcurl quiet by default: */
set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
/*
* libcurl 7.10 introduced SSL verification *by default*! This needs to be
* switched off unless wanted.
*/
set->ssl.verifypeer = TRUE;
set->ssl.verifyhost = 2;
#ifdef USE_TLS_SRP
set->ssl.authtype = CURL_TLSAUTH_NONE;
#endif
set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
type */
set->ssl.sessionid = TRUE; /* session ID caching enabled by default */
set->new_file_perms = 0644; /* Default permissions */
set->new_directory_perms = 0755; /* Default permissions */
/* for the *protocols fields we don't use the CURLPROTO_ALL convenience
define since we internally only use the lower 16 bits for the passed
in bitmask to not conflict with the private bits */
set->allowed_protocols = CURLPROTO_ALL;
set->redir_protocols =
CURLPROTO_ALL & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
/*
* disallow unprotected protection negotiation NEC reference implementation
* seem not to follow rfc1961 section 4.3/4.4
*/
set->socks5_gssapi_nec = FALSE;
/* set default gssapi service name */
res = setstropt(&set->str[STRING_SOCKS5_GSSAPI_SERVICE],
(char *) CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE);
if(res != CURLE_OK)
return res;
#endif
/* This is our preferred CA cert bundle/path since install time */
#if defined(CURL_CA_BUNDLE)
res = setstropt(&set->str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE);
#elif defined(CURL_CA_PATH)
res = setstropt(&set->str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH);
#endif
set->wildcardmatch = FALSE;
set->chunk_bgn = ZERO_NULL;
set->chunk_end = ZERO_NULL;
return res;
}
Daniel Stenberg
committed
/**
* Curl_open()
*
* @param curl is a pointer to a sessionhandle pointer that gets set by this
* function.
* @return CURLcode
*/
Daniel Stenberg
committed
CURLcode Curl_open(struct SessionHandle **curl)
CURLcode res = CURLE_OK;
Daniel Stenberg
committed
struct SessionHandle *data;
/* Very simple start-up: alloc the struct, init it with zeroes and return */
data = calloc(1, sizeof(struct SessionHandle));
Daniel Stenberg
committed
/* this is a very serious error */
DEBUGF(fprintf(stderr, "Error: calloc of SessionHandle failed\n"));
Daniel Stenberg
committed
return CURLE_OUT_OF_MEMORY;
data->magic = CURLEASY_MAGIC_NUMBER;
status = Curl_resolver_init(&data->state.resolver);
if(status) {
DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
Daniel Stenberg
committed
free(data);
Daniel Stenberg
committed
}
Daniel Stenberg
committed
/* We do some initial setup here, all those fields that can't be just 0 */
data->state.headerbuff = malloc(HEADERSIZE);
if(!data->state.headerbuff) {
DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
res = CURLE_OUT_OF_MEMORY;
else {
Curl_easy_initHandleData(data);
res = Curl_init_userdefined(&data->set);
Daniel Stenberg
committed
data->state.headersize=HEADERSIZE;
/* most recent connection is not yet defined */
data->state.lastconnect = -1;
data->progress.flags |= PGRS_HIDE;
data->state.current_speed = -1; /* init to negative == impossible */
Daniel Stenberg
committed
data->wildcard.state = CURLWC_INIT;
data->wildcard.filelist = NULL;
data->set.fnmatch = ZERO_NULL;
/* This no longer creates a connection cache here. It is instead made on
the first call to curl_easy_perform() or when the handle is added to a
multi stack. */
}
if(res) {
Curl_resolver_cleanup(data->state.resolver);
if(data->state.headerbuff)
free(data->state.headerbuff);
Daniel Stenberg
committed
Curl_freeset(data);
free(data);
data = NULL;
}
else
*curl = data;
CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
va_list param)
char *argptr;
Daniel Stenberg
committed
CURLcode result = CURLE_OK;
#ifndef CURL_DISABLE_HTTP
curl_off_t bigsize;
#endif
switch(option) {
Sterling Hughes
committed
case CURLOPT_DNS_CACHE_TIMEOUT:
data->set.dns_cache_timeout = va_arg(param, long);
Sterling Hughes
committed
break;
{
/* remember we want this enabled */
long use_cache = va_arg(param, long);
data->set.global_dns_cache = (bool)(0 != use_cache);
}
break;
case CURLOPT_SSL_CIPHER_LIST:
/* set a list of cipher we want to use in the SSL connection */
result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST],
case CURLOPT_RANDOM_FILE:
/*
* This is the path name to a file that contains random data to seed
* the random SSL stuff with. The file is only used for reading.
*/
result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
break;
case CURLOPT_EGDSOCKET:
/*
* The Entropy Gathering Daemon socket pathname
*/
result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
break;
case CURLOPT_MAXCONNECTS:
/*
* Set the absolute number of maximum simultaneous alive connection that
* libcurl is allowed to have.
*/
result = Curl_ch_connc(data, data->state.connc, va_arg(param, long));
break;
case CURLOPT_FORBID_REUSE:
/*
* When this transfer is done, it must not be left to be reused by a
* subsequent transfer but shall be closed immediately.
*/
data->set.reuse_forbid = (bool)(0 != va_arg(param, long));
break;
case CURLOPT_FRESH_CONNECT:
/*
* This transfer shall not use a previously cached connection but
* should be made with a fresh new connect!
*/
data->set.reuse_fresh = (bool)(0 != va_arg(param, long));
/*
* Verbose means infof() calls that give a lot of information about
* the connection and transfer procedures as well as internal choices.
*/
/*
* Set to include the header in the general data output stream.
*/
data->set.include_header = (bool)(0 != va_arg(param, long));
/*
* Shut off the internal supported progress meter
*/
data->set.hide_progress = (bool)(0 != va_arg(param, long));
Daniel Stenberg
committed
if(data->set.hide_progress)
else
data->progress.flags &= ~PGRS_HIDE;
/*
* Do not include the body part in the output data stream.
*/
data->set.opt_no_body = (bool)(0 != va_arg(param, long));
break;
case CURLOPT_FAILONERROR:
/*
* Don't output the >=300 error code HTML-page, but instead only
* return error.
*/
data->set.http_fail_on_error = (bool)(0 != va_arg(param, long));
case CURLOPT_PUT:
* We want to sent data to the remote host. If this is HTTP, that equals
* using the PUT request.
Daniel Stenberg
committed
if(data->set.upload) {
/* If this is HTTP, PUT is what's needed to "upload" */
Daniel Stenberg
committed
data->set.httpreq = HTTPREQ_PUT;
Daniel Stenberg
committed
data->set.opt_no_body = FALSE; /* this is implied */
}
else
Daniel Stenberg
committed
/* In HTTP, the opposite of upload is GET (unless NOBODY is true as
then this can be changed to HEAD later on) */
data->set.httpreq = HTTPREQ_GET;
/*
* Try to get the file time of the remote document. The time will
* later (possibly) become available using curl_easy_getinfo().
*/
data->set.get_filetime = (bool)(0 != va_arg(param, long));
case CURLOPT_FTP_CREATE_MISSING_DIRS:
/*
* An FTP option that modifies an upload to create missing directories on
* the server.
switch(va_arg(param, long)) {
case 0:
data->set.ftp_create_missing_dirs = 0;
break;
case 1:
data->set.ftp_create_missing_dirs = 1;
break;
case 2:
data->set.ftp_create_missing_dirs = 2;
break;
default:
/* reserve other values for future use */
result = CURLE_UNKNOWN_OPTION;
break;
case CURLOPT_SERVER_RESPONSE_TIMEOUT:
* Option that specifies how quickly an server response must be obtained
* before it is considered failure. For pingpong protocols.
data->set.server_response_timeout = va_arg( param , long ) * 1000;
Daniel Stenberg
committed
case CURLOPT_TFTP_BLKSIZE:
/*
* TFTP option that specifies the block size to use for data transmission
*/
data->set.tftp_blksize = va_arg(param, long);
break;
case CURLOPT_DIRLISTONLY:
* An option that changes the command to one that asks for a list
* only, no file info details.
*/
data->set.ftp_list_only = (bool)(0 != va_arg(param, long));
case CURLOPT_APPEND:
* We want to upload and append to an existing file.
data->set.ftp_append = (bool)(0 != va_arg(param, long));
case CURLOPT_FTP_FILEMETHOD:
/*