aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.c699
-rw-r--r--src/urlglob.c6
-rw-r--r--src/urlglob.h1
3 files changed, 395 insertions, 311 deletions
diff --git a/src/main.c b/src/main.c
index 0b050c9c5..a47d50795 100644
--- a/src/main.c
+++ b/src/main.c
@@ -39,7 +39,6 @@
#include "writeout.h"
#define CURLseparator "--_curl_--"
-#define MIMEseparator "_curl_"
/* This define make use of the "Curlseparator" as opposed to the
MIMEseparator. We might add support for the latter one in the
@@ -222,6 +221,20 @@ static void helpf(char *fmt, ...)
fprintf(stderr, "curl: try 'curl --help' for more information\n");
}
+/*
+ * A chain of these nodes contain URL to get and where to put the URL's
+ * contents.
+ */
+struct getout {
+ struct getout *next;
+ char *url;
+ char *outfile;
+ int flags;
+};
+#define GETOUT_OUTFILE (1<<0) /* set when outfile is deemed done */
+#define GETOUT_URL (1<<1) /* set when URL is deemed done */
+#define GETOUT_USEREMOTE (1<<2) /* use remote file name locally */
+
static void help(void)
{
printf(CURL_ID "%s\n"
@@ -303,9 +316,7 @@ struct Configurable {
char *referer;
long timeout;
long maxredirs;
- char *outfile;
char *headerfile;
- char remotefile;
char *ftpport;
char *iface;
unsigned short porttouse;
@@ -320,7 +331,13 @@ struct Configurable {
bool configread;
bool proxytunnel;
long conf;
- char *url;
+
+ struct getout *url_list; /* point to the first node */
+ struct getout *url_last; /* point to the last/current node */
+
+ struct getout *url_get; /* point to the node to fill in URL */
+ struct getout *url_out; /* point to the node to fill in outfile */
+
char *cert;
char *cacert;
char *cert_passwd;
@@ -426,6 +443,29 @@ static char *file2memory(FILE *file, long *size)
return NULL; /* no string */
}
+struct getout *new_getout(struct Configurable *config)
+{
+ struct getout *node =malloc(sizeof(struct getout));
+ struct getout *last= config->url_last;
+ if(node) {
+ /* clear the struct */
+ memset(node, 0, sizeof(struct getout));
+
+ /* append this new node last in the list */
+ if(last)
+ last->next = node;
+ else
+ config->url_list = node; /* first node */
+
+ /* move the last pointer */
+ config->url_last = node;
+ }
+ return node;
+}
+
+
+
+
typedef enum {
PARAM_OK,
PARAM_OPTION_AMBIGUOUS,
@@ -610,7 +650,30 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
break;
case '5':
/* the URL! */
- GetStr(&config->url, nextarg);
+ {
+ struct getout *url;
+ if(config->url_get || (config->url_get=config->url_list)) {
+ /* there's a node here, if it already is filled-in continue to find
+ an "empty" node */
+ while(config->url_get && (config->url_get->flags&GETOUT_URL))
+ config->url_get = config->url_get->next;
+ }
+
+ /* now there might or might not be an available node to fill in! */
+
+ if(config->url_get)
+ /* existing node */
+ url = config->url_get;
+ else
+ /* there was no free node, create one! */
+ url=new_getout(config);
+
+ if(url) {
+ /* fill in the URL */
+ GetStr(&url->url, nextarg);
+ url->flags |= GETOUT_URL;
+ }
+ }
break;
case '#': /* added 19990617 larsa */
config->progressmode ^= CURL_PROGRESS_BAR;
@@ -794,12 +857,37 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
config->nobuffer ^= 1;
break;
case 'o':
- /* output file */
- GetStr(&config->outfile, nextarg); /* write to this file */
- break;
case 'O':
/* output file */
- config->remotefile ^= TRUE;
+ {
+ struct getout *url;
+ if(config->url_out || (config->url_out=config->url_list)) {
+ /* there's a node here, if it already is filled-in continue to find
+ an "empty" node */
+ while(config->url_out && (config->url_out->flags&GETOUT_OUTFILE))
+ config->url_out = config->url_out->next;
+ }
+
+ /* now there might or might not be an available node to fill in! */
+
+ if(config->url_out)
+ /* existing node */
+ url = config->url_out;
+ else
+ /* there was no free node, create one! */
+ url=new_getout(config);
+
+ if(url) {
+ /* fill in the outfile */
+ if('o' == letter)
+ GetStr(&url->outfile, nextarg);
+ else {
+ url->outfile=NULL; /* leave it */
+ url->flags |= GETOUT_USEREMOTE;
+ }
+ url->flags |= GETOUT_OUTFILE;
+ }
+ }
break;
case 'P':
/* This makes the FTP sessions use PORT instead of PASV */
@@ -1253,8 +1341,6 @@ void progressbarinit(struct ProgressData *bar)
void free_config_fields(struct Configurable *config)
{
- if(config->url)
- free(config->url);
if(config->userpwd)
free(config->userpwd);
if(config->postfields)
@@ -1271,8 +1357,6 @@ void free_config_fields(struct Configurable *config)
free(config->krb4level);
if(config->headerfile)
free(config->headerfile);
- if(config->outfile)
- free(config->outfile);
if(config->ftpport)
free(config->ftpport);
if(config->infile)
@@ -1300,6 +1384,8 @@ operate(struct Configurable *config, int argc, char *argv[])
char errorbuffer[CURL_ERROR_SIZE];
char useragent[128]; /* buah, we don't want a larger default user agent */
struct ProgressData progressbar;
+ struct getout *urlnode;
+ struct getout *nextnode;
struct OutStruct outs;
struct OutStruct heads;
@@ -1323,9 +1409,6 @@ operate(struct Configurable *config, int argc, char *argv[])
int res;
int i;
- outs.stream = stdout;
- outs.config = config;
-
#ifdef MALLOCDEBUG
/* this sends all memory debug messages to a logfile named memdump */
curl_memdebug("memdump");
@@ -1356,7 +1439,7 @@ operate(struct Configurable *config, int argc, char *argv[])
return res;
}
- if ((argc < 2) && !config->url) {
+ if ((argc < 2) && !config->url_list) {
helpf(NULL);
return CURLE_FAILED_INIT;
}
@@ -1405,20 +1488,15 @@ operate(struct Configurable *config, int argc, char *argv[])
}
}
else {
- if(url) {
- helpf("only one URL is supported!\n");
- return CURLE_FAILED_INIT;
- }
- url = argv[i];
+ bool used;
+ /* just add the URL please */
+ res = getparameter("--url", argv[i], &used, config);
+ if(res)
+ return res;
}
}
- /* if no URL was specified and there was one in the config file, get that
- one */
- if(!url && config->url)
- url = config->url;
-
- if(!url) {
+ if(!config->url_list) {
helpf("no URL specified!\n");
return CURLE_FAILED_INIT;
}
@@ -1430,331 +1508,336 @@ operate(struct Configurable *config, int argc, char *argv[])
}
else
allocuseragent = TRUE;
-#if 0
- fprintf(stderr, "URL: %s PROXY: %s\n", url, config->proxy?config->proxy:"none");
-#endif
- /* expand '{...}' and '[...]' expressions and return total number of URLs
- in pattern set */
- res = glob_url(&urls, url, &urlnum);
- if(res != CURLE_OK)
- return res;
+ urlnode = config->url_list;
- /* save outfile pattern befor expansion */
- outfiles = config->outfile?strdup(config->outfile):NULL;
+ /* loop through the list of given URLs */
+ while(urlnode) {
- if (!outfiles && !config->remotefile && urlnum > 1) {
-#ifdef CURL_SEPARATORS
- /* multiple files extracted to stdout, insert separators! */
- separator = 1;
-#endif
-#ifdef MIME_SEPARATORS
- /* multiple files extracted to stdout, insert MIME separators! */
- separator = 1;
- printf("MIME-Version: 1.0\n");
- printf("Content-Type: multipart/mixed; boundary=%s\n\n", MIMEseparator);
-#endif
- }
- for (i = 0; (url = next_url(urls)); ++i) {
- if (config->outfile) {
- free(config->outfile);
- config->outfile = outfiles?strdup(outfiles):NULL;
+ /* get the full URL */
+ url=urlnode->url;
+
+ /* default output stream is stdout */
+ outs.stream = stdout;
+ outs.config = config;
+
+ /* expand '{...}' and '[...]' expressions and return total number of URLs
+ in pattern set */
+ res = glob_url(&urls, url, &urlnum);
+ if(res != CURLE_OK)
+ return res;
+
+ /* save outfile pattern before expansion */
+ outfiles = urlnode->outfile?strdup(urlnode->outfile):NULL;
+
+ if (outfiles && strequal(outfiles, "-") && urlnum > 1) {
+ /* multiple files extracted to stdout, insert separators! */
+ separator = 1;
}
+ for (i = 0; (url = next_url(urls)); ++i) {
+ char *outfile;
+ outfile = outfiles?strdup(outfiles):NULL;
+
- if (config->outfile || config->remotefile) {
- /*
- * We have specified a file name to store the result in, or we have
- * decided we want to use the remote file name.
- */
+ if((urlnode->flags&GETOUT_USEREMOTE) ||
+ (outfile && !strequal("-", outfile)) ) {
+
+ /*
+ * We have specified a file name to store the result in, or we have
+ * decided we want to use the remote file name.
+ */
- if(!config->outfile && config->remotefile) {
- /* Find and get the remote file name */
- char * pc =strstr(url, "://");
- if(pc)
- pc+=3;
- else
- pc=url;
- pc = strrchr(pc, '/');
- config->outfile = (char *) NULL == pc ? NULL : strdup(pc+1) ;
- if(!config->outfile || !strlen(config->outfile)) {
- helpf("Remote file name has no length!\n");
- return CURLE_WRITE_ERROR;
+ if(!outfile) {
+ /* Find and get the remote file name */
+ char * pc =strstr(url, "://");
+ if(pc)
+ pc+=3;
+ else
+ pc=url;
+ pc = strrchr(pc, '/');
+ outfile = (char *) NULL == pc ? NULL : strdup(pc+1) ;
+ if(!outfile) {
+ helpf("Remote file name has no length!\n");
+ return CURLE_WRITE_ERROR;
+ }
+ }
+ else {
+ /* fill '#1' ... '#9' terms from URL pattern */
+ char *storefile = outfile;
+ outfile = match_url(storefile, urls);
+ free(storefile);
}
- }
- else {
- /* fill '#1' ... '#9' terms from URL pattern */
- char *outfile = config->outfile;
- config->outfile = match_url(config->outfile, urls);
- free(outfile);
- }
- if((0 == config->resume_from) && config->use_resume) {
- /* we're told to continue where we are now, then we get the size of the
- file as it is now and open it for append instead */
- struct stat fileinfo;
+ if((0 == config->resume_from) && config->use_resume) {
+ /* we're told to continue where we are now, then we get the size of
+ the file as it is now and open it for append instead */
- if(0 == stat(config->outfile, &fileinfo)) {
- /* set offset to current file size: */
- config->resume_from = fileinfo.st_size;
+ struct stat fileinfo;
+
+ if(0 == stat(outfile, &fileinfo)) {
+ /* set offset to current file size: */
+ config->resume_from = fileinfo.st_size;
+ }
+ /* else let offset remain 0 */
}
- /* else let offset remain 0 */
- }
- if(config->resume_from) {
- /* open file for output: */
- outs.stream=(FILE *) fopen(config->outfile, config->resume_from?"ab":"wb");
- if (!outs.stream) {
- helpf("Can't open '%s'!\n", config->outfile);
- return CURLE_WRITE_ERROR;
+ if(config->resume_from) {
+ /* open file for output: */
+ outs.stream=(FILE *) fopen(outfile, config->resume_from?"ab":"wb");
+ if (!outs.stream) {
+ helpf("Can't open '%s'!\n", outfile);
+ return CURLE_WRITE_ERROR;
+ }
}
- }
- else {
- outs.filename = config->outfile;
- outs.stream = NULL; /* open when needed */
- }
- }
- if (config->infile) {
- /*
- * We have specified a file to upload
- */
- struct stat fileinfo;
-
- /* If no file name part is given in the URL, we add this file name */
- char *ptr=strstr(url, "://");
- if(ptr)
- ptr+=3;
- else
- ptr=url;
- ptr = strrchr(ptr, '/');
- if(!ptr || !strlen(++ptr)) {
- /* The URL has no file name part, add the local file name. In order to
- be able to do so, we have to create a new URL in another buffer.*/
-
- urlbuffer=(char *)malloc(strlen(url) + strlen(config->infile) + 3);
- if(!urlbuffer) {
- helpf("out of memory\n");
- return CURLE_OUT_OF_MEMORY;
+ else {
+ outs.filename = outfile;
+ outs.stream = NULL; /* open when needed */
}
+ }
+ if(config->infile) {
+ /*
+ * We have specified a file to upload
+ */
+ struct stat fileinfo;
+
+ /* If no file name part is given in the URL, we add this file name */
+ char *ptr=strstr(url, "://");
if(ptr)
- /* there is a trailing slash on the URL */
- sprintf(urlbuffer, "%s%s", url, config->infile);
+ ptr+=3;
else
- /* thers is no trailing slash on the URL */
- sprintf(urlbuffer, "%s/%s", url, config->infile);
-
- url = urlbuffer; /* use our new URL instead! */
- }
+ ptr=url;
+ ptr = strrchr(ptr, '/');
+ if(!ptr || !strlen(++ptr)) {
+ /* The URL has no file name part, add the local file name. In order
+ to be able to do so, we have to create a new URL in another
+ buffer.*/
+
+ urlbuffer=(char *)malloc(strlen(url) + strlen(config->infile) + 3);
+ if(!urlbuffer) {
+ helpf("out of memory\n");
+ return CURLE_OUT_OF_MEMORY;
+ }
+ if(ptr)
+ /* there is a trailing slash on the URL */
+ sprintf(urlbuffer, "%s%s", url, config->infile);
+ else
+ /* thers is no trailing slash on the URL */
+ sprintf(urlbuffer, "%s/%s", url, config->infile);
+
+ url = urlbuffer; /* use our new URL instead! */
+ }
- infd=(FILE *) fopen(config->infile, "rb");
- if (!infd || stat(config->infile, &fileinfo)) {
- helpf("Can't open '%s'!\n", config->infile);
- return CURLE_READ_ERROR;
- }
- infilesize=fileinfo.st_size;
+ infd=(FILE *) fopen(config->infile, "rb");
+ if (!infd || stat(config->infile, &fileinfo)) {
+ helpf("Can't open '%s'!\n", config->infile);
+ return CURLE_READ_ERROR;
+ }
+ infilesize=fileinfo.st_size;
- }
- if((config->conf&CONF_UPLOAD) &&
- config->use_resume &&
- (0==config->resume_from)) {
- config->resume_from = -1; /* -1 will then force get-it-yourself */
- }
- if(config->headerfile) {
- /* open file for output: */
- if(strcmp(config->headerfile,"-")) {
- heads.filename = config->headerfile;
- headerfilep=NULL;
}
- else
- headerfilep=stdout;
- heads.stream = headerfilep;
- heads.config = config;
- }
+ if((config->conf&CONF_UPLOAD) &&
+ config->use_resume &&
+ (0==config->resume_from)) {
+ config->resume_from = -1; /* -1 will then force get-it-yourself */
+ }
+ if(config->headerfile) {
+ /* open file for output: */
+ if(strcmp(config->headerfile,"-")) {
+ heads.filename = config->headerfile;
+ headerfilep=NULL;
+ }
+ else
+ headerfilep=stdout;
+ heads.stream = headerfilep;
+ heads.config = config;
+ }
- if(outs.stream && isatty(fileno(outs.stream)) &&
- !(config->conf&(CONF_UPLOAD|CONF_HTTPPOST)))
- /* we send the output to a tty and it isn't an upload operation,
- therefore we switch off the progress meter */
- config->conf |= CONF_NOPROGRESS;
+ if(outs.stream && isatty(fileno(outs.stream)) &&
+ !(config->conf&(CONF_UPLOAD|CONF_HTTPPOST)))
+ /* we send the output to a tty and it isn't an upload operation,
+ therefore we switch off the progress meter */
+ config->conf |= CONF_NOPROGRESS;
- if (urlnum > 1) {
- fprintf(stderr, "\n[%d/%d]: %s --> %s\n",
- i+1, urlnum, url, config->outfile ? config->outfile : "<stdout>");
- if (separator) {
-#ifdef CURL_SEPARATORS
- printf("%s%s\n", CURLseparator, url);
-#endif
-#ifdef MIME_SEPARATORS
- printf("--%s\n", MIMEseparator);
- printf("Content-ID: %s\n\n", url);
-#endif
+ if (urlnum > 1) {
+ fprintf(stderr, "\n[%d/%d]: %s --> %s\n",
+ i+1, urlnum, url, outfile ? outfile : "<stdout>");
+ if (separator)
+ printf("%s%s\n", CURLseparator, url);
}
- }
- if(!config->errors)
- config->errors = stderr;
+ if(!config->errors)
+ config->errors = stderr;
#ifdef WIN32
- if(!config->outfile && !(config->conf & CONF_GETTEXT)) {
- /* We get the output to stdout and we have not got the ASCII/text flag,
- then set stdout to be binary */
- setmode( 1, O_BINARY );
- }
+ if(!outfile && !(config->conf & CONF_GETTEXT)) {
+ /* We get the output to stdout and we have not got the ASCII/text flag,
+ then set stdout to be binary */
+ setmode( 1, O_BINARY );
+ }
#endif
- main_init();
-
- /* The new, v7-style easy-interface! */
- curl = curl_easy_init();
- if(curl) {
- curl_easy_setopt(curl, CURLOPT_FILE, (FILE *)&outs); /* where to store */
- /* what call to write: */
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
- curl_easy_setopt(curl, CURLOPT_INFILE, infd); /* for uploads */
- /* size of uploaded file: */
- curl_easy_setopt(curl, CURLOPT_INFILESIZE, infilesize);
- curl_easy_setopt(curl, CURLOPT_URL, url); /* what to fetch */
- curl_easy_setopt(curl, CURLOPT_PROXY, config->proxy); /* proxy to use */
- curl_easy_setopt(curl, CURLOPT_VERBOSE, config->conf&CONF_VERBOSE);
- curl_easy_setopt(curl, CURLOPT_HEADER, config->conf&CONF_HEADER);
- curl_easy_setopt(curl, CURLOPT_NOPROGRESS, config->conf&CONF_NOPROGRESS);
- curl_easy_setopt(curl, CURLOPT_NOBODY, config->conf&CONF_NOBODY);
- curl_easy_setopt(curl, CURLOPT_FAILONERROR,
- config->conf&CONF_FAILONERROR);
- curl_easy_setopt(curl, CURLOPT_UPLOAD, config->conf&CONF_UPLOAD);
- curl_easy_setopt(curl, CURLOPT_POST, config->conf&CONF_POST);
- curl_easy_setopt(curl, CURLOPT_FTPLISTONLY,
- config->conf&CONF_FTPLISTONLY);
- curl_easy_setopt(curl, CURLOPT_FTPAPPEND, config->conf&CONF_FTPAPPEND);
- curl_easy_setopt(curl, CURLOPT_NETRC, config->conf&CONF_NETRC);
- curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION,
- config->conf&CONF_FOLLOWLOCATION);
- curl_easy_setopt(curl, CURLOPT_TRANSFERTEXT, config->conf&CONF_GETTEXT);
- curl_easy_setopt(curl, CURLOPT_PUT, config->conf&CONF_PUT);
- curl_easy_setopt(curl, CURLOPT_MUTE, config->conf&CONF_MUTE);
- curl_easy_setopt(curl, CURLOPT_USERPWD, config->userpwd);
- curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, config->proxyuserpwd);
- curl_easy_setopt(curl, CURLOPT_RANGE, config->range);
- curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
- curl_easy_setopt(curl, CURLOPT_TIMEOUT, config->timeout);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, config->postfields);
-
- /* new in libcurl 7.2: */
- curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, config->postfieldsize);
-
- curl_easy_setopt(curl, CURLOPT_REFERER, config->referer);
- curl_easy_setopt(curl, CURLOPT_AUTOREFERER,
- config->conf&CONF_AUTO_REFERER);
- curl_easy_setopt(curl, CURLOPT_USERAGENT, config->useragent);
- curl_easy_setopt(curl, CURLOPT_FTPPORT, config->ftpport);
- curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, config->low_speed_limit);
- curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, config->low_speed_time);
- curl_easy_setopt(curl, CURLOPT_RESUME_FROM,
- config->use_resume?config->resume_from:0);
- curl_easy_setopt(curl, CURLOPT_COOKIE, config->cookie);
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, config->headers);
- curl_easy_setopt(curl, CURLOPT_HTTPPOST, config->httppost);
- curl_easy_setopt(curl, CURLOPT_SSLCERT, config->cert);
- curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, config->cert_passwd);
-
- if(config->cacert) {
- /* available from libcurl 7.5: */
- curl_easy_setopt(curl, CURLOPT_CAINFO, config->cacert);
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE);
- }
+ main_init();
+
+ curl = curl_easy_init();
+ if(curl) {
+ curl_easy_setopt(curl, CURLOPT_FILE, (FILE *)&outs); /* where to store */
+ /* what call to write: */
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
+ curl_easy_setopt(curl, CURLOPT_INFILE, infd); /* for uploads */
+ /* size of uploaded file: */
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE, infilesize);
+ curl_easy_setopt(curl, CURLOPT_URL, url); /* what to fetch */
+ curl_easy_setopt(curl, CURLOPT_PROXY, config->proxy); /* proxy to use */
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, config->conf&CONF_VERBOSE);
+ curl_easy_setopt(curl, CURLOPT_HEADER, config->conf&CONF_HEADER);
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, config->conf&CONF_NOPROGRESS);
+ curl_easy_setopt(curl, CURLOPT_NOBODY, config->conf&CONF_NOBODY);
+ curl_easy_setopt(curl, CURLOPT_FAILONERROR,
+ config->conf&CONF_FAILONERROR);
+ curl_easy_setopt(curl, CURLOPT_UPLOAD, config->conf&CONF_UPLOAD);
+ curl_easy_setopt(curl, CURLOPT_POST, config->conf&CONF_POST);
+ curl_easy_setopt(curl, CURLOPT_FTPLISTONLY,
+ config->conf&CONF_FTPLISTONLY);
+ curl_easy_setopt(curl, CURLOPT_FTPAPPEND, config->conf&CONF_FTPAPPEND);
+ curl_easy_setopt(curl, CURLOPT_NETRC, config->conf&CONF_NETRC);
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION,
+ config->conf&CONF_FOLLOWLOCATION);
+ curl_easy_setopt(curl, CURLOPT_TRANSFERTEXT, config->conf&CONF_GETTEXT);
+ curl_easy_setopt(curl, CURLOPT_PUT, config->conf&CONF_PUT);
+ curl_easy_setopt(curl, CURLOPT_MUTE, config->conf&CONF_MUTE);
+ curl_easy_setopt(curl, CURLOPT_USERPWD, config->userpwd);
+ curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, config->proxyuserpwd);
+ curl_easy_setopt(curl, CURLOPT_RANGE, config->range);
+ curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT, config->timeout);
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, config->postfields);
+
+ /* new in libcurl 7.2: */
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, config->postfieldsize);
+
+ curl_easy_setopt(curl, CURLOPT_REFERER, config->referer);
+ curl_easy_setopt(curl, CURLOPT_AUTOREFERER,
+ config->conf&CONF_AUTO_REFERER);
+ curl_easy_setopt(curl, CURLOPT_USERAGENT, config->useragent);
+ curl_easy_setopt(curl, CURLOPT_FTPPORT, config->ftpport);
+ curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, config->low_speed_limit);
+ curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, config->low_speed_time);
+ curl_easy_setopt(curl, CURLOPT_RESUME_FROM,
+ config->use_resume?config->resume_from:0);
+ curl_easy_setopt(curl, CURLOPT_COOKIE, config->cookie);
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, config->headers);
+ curl_easy_setopt(curl, CURLOPT_HTTPPOST, config->httppost);
+ curl_easy_setopt(curl, CURLOPT_SSLCERT, config->cert);
+ curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, config->cert_passwd);
+
+ if(config->cacert) {
+ /* available from libcurl 7.5: */
+ curl_easy_setopt(curl, CURLOPT_CAINFO, config->cacert);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE);
+ }
- if(config->conf&(CONF_NOBODY|CONF_USEREMOTETIME)) {
- /* no body or use remote time */
- /* new in 7.5 */
- curl_easy_setopt(curl, CURLOPT_FILETIME, TRUE);
- }
+ if(config->conf&(CONF_NOBODY|CONF_USEREMOTETIME)) {
+ /* no body or use remote time */
+ /* new in 7.5 */
+ curl_easy_setopt(curl, CURLOPT_FILETIME, TRUE);
+ }
- /* 7.5 news: */
- if (config->maxredirs)
- curl_easy_setopt(curl, CURLOPT_MAXREDIRS, config->maxredirs);
- else
- curl_easy_setopt(curl, CURLOPT_MAXREDIRS, DEFAULT_MAXREDIRS);
+ /* 7.5 news: */
+ if (config->maxredirs)
+ curl_easy_setopt(curl, CURLOPT_MAXREDIRS, config->maxredirs);
+ else
+ curl_easy_setopt(curl, CURLOPT_MAXREDIRS, DEFAULT_MAXREDIRS);
-
- curl_easy_setopt(curl, CURLOPT_CRLF, config->crlf);
- curl_easy_setopt(curl, CURLOPT_QUOTE, config->quote);
- curl_easy_setopt(curl, CURLOPT_POSTQUOTE, config->postquote);
- curl_easy_setopt(curl, CURLOPT_WRITEHEADER,
- config->headerfile?&heads:NULL);
- curl_easy_setopt(curl, CURLOPT_COOKIEFILE, config->cookiefile);
- curl_easy_setopt(curl, CURLOPT_SSLVERSION, config->ssl_version);
- curl_easy_setopt(curl, CURLOPT_TIMECONDITION, config->timecond);
- curl_easy_setopt(curl, CURLOPT_TIMEVALUE, config->condtime);
- curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, config->customrequest);
- curl_easy_setopt(curl, CURLOPT_STDERR, config->errors);
+ curl_easy_setopt(curl, CURLOPT_CRLF, config->crlf);
+ curl_easy_setopt(curl, CURLOPT_QUOTE, config->quote);
+ curl_easy_setopt(curl, CURLOPT_POSTQUOTE, config->postquote);
+ curl_easy_setopt(curl, CURLOPT_WRITEHEADER,
+ config->headerfile?&heads:NULL);
+ curl_easy_setopt(curl, CURLOPT_COOKIEFILE, config->cookiefile);
+ curl_easy_setopt(curl, CURLOPT_SSLVERSION, config->ssl_version);
+ curl_easy_setopt(curl, CURLOPT_TIMECONDITION, config->timecond);
+ curl_easy_setopt(curl, CURLOPT_TIMEVALUE, config->condtime);
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, config->customrequest);
+ curl_easy_setopt(curl, CURLOPT_STDERR, config->errors);
- /* three new ones in libcurl 7.3: */
- curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, config->proxytunnel);
- curl_easy_setopt(curl, CURLOPT_INTERFACE, config->iface);
- curl_easy_setopt(curl, CURLOPT_KRB4LEVEL, config->krb4level);
-
- if((config->progressmode == CURL_PROGRESS_BAR) &&
- !(config->conf&(CONF_NOPROGRESS|CONF_MUTE))) {
- /* we want the alternative style, then we have to implement it
- ourselves! */
- progressbarinit(&progressbar);
- curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, myprogress);
- curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &progressbar);
+ /* three new ones in libcurl 7.3: */
+ curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, config->proxytunnel);
+ curl_easy_setopt(curl, CURLOPT_INTERFACE, config->iface);
+ curl_easy_setopt(curl, CURLOPT_KRB4LEVEL, config->krb4level);
+
+ if((config->progressmode == CURL_PROGRESS_BAR) &&
+ !(config->conf&(CONF_NOPROGRESS|CONF_MUTE))) {
+ /* we want the alternative style, then we have to implement it
+ ourselves! */
+ progressbarinit(&progressbar);
+ curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, myprogress);
+ curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &progressbar);
+ }
+
+ res = curl_easy_perform(curl);
+
+ if(config->writeout) {
+ ourWriteOut(curl, config->writeout);
+ }
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+
+ if((res!=CURLE_OK) && config->showerror)
+ fprintf(config->errors, "curl: (%d) %s\n", res, errorbuffer);
}
+ else
+ fprintf(config->errors, "curl: failed to init libcurl!\n");
- res = curl_easy_perform(curl);
-
- if(config->writeout) {
- ourWriteOut(curl, config->writeout);
- }
+ main_free();
- /* always cleanup */
- curl_easy_cleanup(curl);
+ if((config->errors != stderr) &&
+ (config->errors != stdout))
+ /* it wasn't directed to stdout or stderr so close the file! */
+ fclose(config->errors);
+
+ if(config->headerfile && !headerfilep && heads.stream)
+ fclose(heads.stream);
+
+ if(urlbuffer)
+ free(urlbuffer);
+ if (outfile && !strequal(outfile, "-") && outs.stream)
+ fclose(outs.stream);
+ if (config->infile)
+ fclose(infd);
+ if(headerfilep)
+ fclose(headerfilep);
+
+ if(url)
+ free(url);
- if((res!=CURLE_OK) && config->showerror)
- fprintf(config->errors, "curl: (%d) %s\n", res, errorbuffer);
+ if(outfile)
+ free(outfile);
}
- else
- fprintf(config->errors, "curl: failed to init libcurl!\n");
+ if(outfiles)
+ free(outfiles);
- main_free();
+ /* cleanup memory used for URL globbing patterns */
+ glob_cleanup(urls);
- if((config->errors != stderr) &&
- (config->errors != stdout))
- /* it wasn't directed to stdout or stderr so close the file! */
- fclose(config->errors);
-
- if(config->headerfile && !headerfilep && heads.stream)
- fclose(heads.stream);
-
- if(urlbuffer)
- free(urlbuffer);
- if (config->outfile && outs.stream)
- fclose(outs.stream);
- if (config->infile)
- fclose(infd);
- if(headerfilep)
- fclose(headerfilep);
+ /* empty this urlnode struct */
+ if(urlnode->url)
+ free(urlnode->url);
+ if(urlnode->outfile)
+ free(urlnode->outfile);
- if(url)
- free(url);
+ /* move on to the next URL */
+ nextnode=urlnode->next;
+ free(urlnode); /* free the node */
+ urlnode = nextnode;
- }
- if(outfiles)
- free(outfiles);
-
-#ifdef MIME_SEPARATORS
- if (separator)
- printf("--%s--\n", MIMEseparator);
-#endif
+ } /* while-loop through all URLs */
if(allocuseragent)
free(config->useragent);
- /* cleanup memory used for URL globbing patterns */
- glob_cleanup(urls);
-
return res;
}
diff --git a/src/urlglob.c b/src/urlglob.c
index 0f111a92a..509c34e70 100644
--- a/src/urlglob.c
+++ b/src/urlglob.c
@@ -213,6 +213,7 @@ int glob_url(URLGlob** glob, char* url, int *urlnum)
glob_expand->size = 0;
glob_expand->urllen = strlen(url);
glob_expand->glob_buffer = glob_buffer;
+ glob_expand->beenhere=0;
*urlnum = glob_word(glob_expand, url, 1);
*glob = glob_expand;
return CURLE_OK;
@@ -240,15 +241,14 @@ void glob_cleanup(URLGlob* glob)
char *next_url(URLGlob *glob)
{
- static int beenhere = 0;
char *buf = glob->glob_buffer;
URLPattern *pat;
char *lit;
signed int i;
int carry;
- if (!beenhere)
- beenhere = 1;
+ if (!glob->beenhere)
+ glob->beenhere = 1;
else {
carry = 1;
diff --git a/src/urlglob.h b/src/urlglob.h
index a0c3c5fd2..ae86c15e7 100644
--- a/src/urlglob.h
+++ b/src/urlglob.h
@@ -50,6 +50,7 @@ typedef struct {
int size;
int urllen;
char *glob_buffer;
+ char beenhere;
} URLGlob;
int glob_url(URLGlob**, char*, int *);