}
#endif /* __VMS */
-static CURLcode operate_init(struct Configurable *config)
-{
- /* Get a curl handle to use for all forthcoming curl transfers */
- config->easy = curl_easy_init();
- if(!config->easy) {
- helpf(config->errors, "error initializing curl easy handle\n");
- return CURLE_FAILED_INIT;
- }
-
- /* Setup proper locale from environment */
-#ifdef HAVE_SETLOCALE
- setlocale(LC_ALL, "");
-#endif
-
- return CURLE_OK;
-}
-
-static CURLcode operate_do(struct Configurable *config)
+static CURLcode operate_do(struct GlobalConfig *global,
+ struct OperationConfig *config)
{
char errorbuffer[CURL_ERROR_SIZE];
struct ProgressData progressbar;
CURL *curl = config->easy;
char *httpgetfields = NULL;
- int res = 0;
+ CURLcode res = CURLE_OK;
unsigned long li;
- bool orig_noprogress;
- bool orig_isatty;
+ /* Save the values of noprogress and isatty to restore them later on */
+ bool orig_noprogress = global->noprogress;
+ bool orig_isatty = global->isatty;
errorbuffer[0] = '\0';
+
/* default headers output stream is stdout */
memset(&hdrcbdata, 0, sizeof(struct HdrCbData));
memset(&heads, 0, sizeof(struct OutStruct));
/* Check we have a url */
if(!config->url_list || !config->url_list->url) {
- helpf(config->errors, "no URL specified!\n");
+ helpf(global->errors, "no URL specified!\n");
res = CURLE_FAILED_INIT;
goto quit_curl;
}
config->cacert = strdup(env);
if(!config->cacert) {
curl_free(env);
- helpf(config->errors, "out of memory\n");
+ helpf(global->errors, "out of memory\n");
res = CURLE_OUT_OF_MEMORY;
goto quit_curl;
}
config->capath = strdup(env);
if(!config->capath) {
curl_free(env);
- helpf(config->errors, "out of memory\n");
+ helpf(global->errors, "out of memory\n");
res = CURLE_OUT_OF_MEMORY;
goto quit_curl;
}
config->cacert = strdup(env);
if(!config->cacert) {
curl_free(env);
- helpf(config->errors, "out of memory\n");
+ helpf(global->errors, "out of memory\n");
res = CURLE_OUT_OF_MEMORY;
goto quit_curl;
}
httpgetfields = strdup(config->postfields);
Curl_safefree(config->postfields);
if(!httpgetfields) {
- helpf(config->errors, "out of memory\n");
+ helpf(global->errors, "out of memory\n");
res = CURLE_OUT_OF_MEMORY;
goto quit_curl;
}
}
}
-#ifndef CURL_DISABLE_LIBCURL_OPTION
- res = easysrc_init();
- if(res) {
- helpf(config->errors, "out of memory\n");
- goto quit_curl;
- }
-#endif
-
/* Single header file for all URLs */
if(config->headerfile) {
/* open file for output: */
}
}
- /* save the values of noprogress and isatty to restore them later on */
- orig_noprogress = config->noprogress;
- orig_isatty = config->isatty;
-
/*
** Nested loops start here.
*/
if(urlnode->outfile) {
outfiles = strdup(urlnode->outfile);
if(!outfiles) {
- helpf(config->errors, "out of memory\n");
+ helpf(global->errors, "out of memory\n");
res = CURLE_OUT_OF_MEMORY;
break;
}
if(!config->globoff && infiles) {
/* Unless explicitly shut off */
- res = glob_url(&inglob, infiles, &infilenum,
- config->showerror?config->errors:NULL);
+ res = (CURLcode) glob_url(&inglob, infiles, &infilenum,
+ global->showerror?global->errors:NULL);
if(res) {
Curl_safefree(outfiles);
break;
Curl_nop_stmt;
else {
if(inglob) {
- res = glob_next_url(&uploadfile, inglob);
+ res = (CURLcode) glob_next_url(&uploadfile, inglob);
if(res == CURLE_OUT_OF_MEMORY)
- helpf(config->errors, "out of memory\n");
+ helpf(global->errors, "out of memory\n");
}
else if(!up) {
uploadfile = strdup(infiles);
if(!uploadfile) {
- helpf(config->errors, "out of memory\n");
+ helpf(global->errors, "out of memory\n");
res = CURLE_OUT_OF_MEMORY;
}
}
if(!config->globoff) {
/* Unless explicitly shut off, we expand '{...}' and '[...]'
expressions and return total number of URLs in pattern set */
- res = glob_url(&urls, urlnode->url, &urlnum,
- config->showerror?config->errors:NULL);
+ res = (CURLcode) glob_url(&urls, urlnode->url, &urlnum,
+ global->showerror?global->errors:NULL);
if(res) {
Curl_safefree(uploadfile);
break;
}
else {
if(urls) {
- res = glob_next_url(&this_url, urls);
+ res = (CURLcode) glob_next_url(&this_url, urls);
if(res)
goto show_error;
}
if(res)
goto show_error;
if((!outfile || !*outfile) && !config->content_disposition) {
- helpf(config->errors, "Remote file name has no length!\n");
+ helpf(global->errors, "Remote file name has no length!\n");
res = CURLE_WRITE_ERROR;
goto quit_urls;
}
else if(urls) {
/* fill '#1' ... '#9' terms from URL pattern */
char *storefile = outfile;
- res = glob_match_url(&outfile, storefile, urls);
+ res = (CURLcode) glob_match_url(&outfile, storefile, urls);
Curl_safefree(storefile);
if(res) {
/* bad globbing */
file output call */
if(config->create_dirs || metalink) {
- res = create_dir_hierarchy(outfile, config->errors);
+ res = create_dir_hierarchy(outfile, global->errors);
/* create_dir_hierarchy shows error upon CURLE_WRITE_ERROR */
if(res == CURLE_WRITE_ERROR)
goto quit_urls;
FILE *file = fopen(outfile, config->resume_from?"ab":"wb");
#endif
if(!file) {
- helpf(config->errors, "Can't open '%s'!\n", outfile);
+ helpf(global->errors, "Can't open '%s'!\n", outfile);
res = CURLE_WRITE_ERROR;
goto quit_urls;
}
if((infd == -1) || fstat(infd, &fileinfo))
#endif
{
- helpf(config->errors, "Can't open '%s'!\n", uploadfile);
+ helpf(global->errors, "Can't open '%s'!\n", uploadfile);
if(infd != -1) {
close(infd);
infd = STDIN_FILENO;
if(uploadfile && config->resume_from_current)
config->resume_from = -1; /* -1 will then force get-it-yourself */
- if(output_expected(this_url, uploadfile)
- && outs.stream && isatty(fileno(outs.stream)))
+ if(output_expected(this_url, uploadfile) && outs.stream &&
+ isatty(fileno(outs.stream)))
/* we send the output to a tty, therefore we switch off the progress
meter */
- config->noprogress = config->isatty = TRUE;
+ global->noprogress = global->isatty = TRUE;
else {
/* progress meter is per download, so restore config
values */
- config->noprogress = orig_noprogress;
- config->isatty = orig_isatty;
+ global->noprogress = orig_noprogress;
+ global->isatty = orig_isatty;
}
- if(urlnum > 1 && !(config->mute)) {
- fprintf(config->errors, "\n[%lu/%lu]: %s --> %s\n",
+ if(urlnum > 1 && !global->mute) {
+ fprintf(global->errors, "\n[%lu/%lu]: %s --> %s\n",
li+1, urlnum, this_url, outfile ? outfile : "<stdout>");
if(separator)
printf("%s%s\n", CURLseparator, this_url);
this_url = urlbuffer; /* use our new URL instead! */
}
- if(!config->errors)
- config->errors = stderr;
+ if(!global->errors)
+ global->errors = stderr;
if((!outfile || !strcmp(outfile, "-")) && !config->use_ascii) {
/* We get the output to stdout and we have not got the ASCII/text
if(uploadfilesize != -1)
my_setopt(curl, CURLOPT_INFILESIZE_LARGE, uploadfilesize);
my_setopt_str(curl, CURLOPT_URL, this_url); /* what to fetch */
- my_setopt(curl, CURLOPT_NOPROGRESS, config->noprogress?1L:0L);
+ my_setopt(curl, CURLOPT_NOPROGRESS, global->noprogress?1L:0L);
if(config->no_body) {
my_setopt(curl, CURLOPT_NOBODY, 1L);
my_setopt(curl, CURLOPT_HEADER, 1L);
my_setopt_str(curl, CURLOPT_USERAGENT, config->useragent);
my_setopt_slist(curl, CURLOPT_HTTPHEADER, config->headers);
+ /* new in libcurl 7.36.0 */
+ if(config->proxyheaders) {
+ my_setopt_slist(curl, CURLOPT_PROXYHEADER, config->proxyheaders);
+ my_setopt(curl, CURLOPT_HEADEROPT, CURLHEADER_SEPARATE);
+ }
+
/* new in libcurl 7.5 */
my_setopt(curl, CURLOPT_MAXREDIRS, config->maxredirs);
my_setopt_slist(curl, CURLOPT_PREQUOTE, config->prequote);
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
- {
- /* TODO: Make this a run-time check instead of compile-time one. */
-
- if(config->cookie)
- my_setopt_str(curl, CURLOPT_COOKIE, config->cookie);
+ if(config->cookie)
+ my_setopt_str(curl, CURLOPT_COOKIE, config->cookie);
- if(config->cookiefile)
- my_setopt_str(curl, CURLOPT_COOKIEFILE, config->cookiefile);
+ if(config->cookiefile)
+ my_setopt_str(curl, CURLOPT_COOKIEFILE, config->cookiefile);
- /* new in libcurl 7.9 */
- if(config->cookiejar)
- my_setopt_str(curl, CURLOPT_COOKIEJAR, config->cookiejar);
+ /* new in libcurl 7.9 */
+ if(config->cookiejar)
+ my_setopt_str(curl, CURLOPT_COOKIEJAR, config->cookiejar);
- /* new in libcurl 7.9.7 */
- my_setopt(curl, CURLOPT_COOKIESESSION, config->cookiesession?1L:0L);
+ /* new in libcurl 7.9.7 */
+ my_setopt(curl, CURLOPT_COOKIESESSION, config->cookiesession?1L:0L);
+#else
+ if(config->cookie || config->cookiefile || config->cookiejar) {
+ warnf(config, "cookie option(s) used even though cookie support "
+ "is disabled!\n");
+ return CURLE_NOT_BUILT_IN;
}
#endif
my_setopt_enum(curl, CURLOPT_TIMECONDITION, (long)config->timecond);
my_setopt(curl, CURLOPT_TIMEVALUE, (long)config->condtime);
my_setopt_str(curl, CURLOPT_CUSTOMREQUEST, config->customrequest);
- my_setopt(curl, CURLOPT_STDERR, config->errors);
+ my_setopt(curl, CURLOPT_STDERR, global->errors);
/* three new ones in libcurl 7.3: */
my_setopt_str(curl, CURLOPT_INTERFACE, config->iface);
my_setopt_str(curl, CURLOPT_KRBLEVEL, config->krblevel);
progressbarinit(&progressbar, config);
- if((config->progressmode == CURL_PROGRESS_BAR) &&
- !config->noprogress && !config->mute) {
+ if((global->progressmode == CURL_PROGRESS_BAR) &&
+ !global->noprogress && !global->mute) {
/* we want the alternative style, then we have to implement it
ourselves! */
my_setopt(curl, CURLOPT_XFERINFOFUNCTION, tool_progress_cb);
/* disable it */
my_setopt(curl, CURLOPT_FTP_USE_EPRT, 0L);
- if(config->tracetype != TRACE_NONE) {
+ if(global->tracetype != TRACE_NONE) {
my_setopt(curl, CURLOPT_DEBUGFUNCTION, tool_debug_cb);
my_setopt(curl, CURLOPT_DEBUGDATA, config);
my_setopt(curl, CURLOPT_VERBOSE, 1L);
res = CURLE_OUT_OF_MEMORY;
goto show_error;
}
- fprintf(config->errors, "Metalink: parsing (%s) metalink/XML...\n",
- this_url);
+ fprintf(config->global->errors,
+ "Metalink: parsing (%s) metalink/XML...\n", this_url);
}
else if(metalink)
- fprintf(config->errors, "Metalink: fetching (%s) from (%s)...\n",
+ fprintf(config->global->errors,
+ "Metalink: fetching (%s) from (%s)...\n",
mlfile->filename, this_url);
#endif /* USE_METALINK */
#endif
res = curl_easy_perform(curl);
- if(outs.is_cd_filename && outs.stream && !config->mute &&
+ if(outs.is_cd_filename && outs.stream && !global->mute &&
outs.filename)
printf("curl: Saved to filename '%s'\n", outs.filename);
if(outs.bytes && outs.filename) {
/* We have written data to a output file, we truncate file
*/
- if(!config->mute)
- fprintf(config->errors, "Throwing away %"
+ if(!global->mute)
+ fprintf(global->errors, "Throwing away %"
CURL_FORMAT_CURL_OFF_T " bytes\n",
outs.bytes);
fflush(outs.stream);
if(ftruncate( fileno(outs.stream), outs.init)) {
/* when truncate fails, we can't just append as then we'll
create something strange, bail out */
- if(!config->mute)
- fprintf(config->errors,
+ if(!global->mute)
+ fprintf(global->errors,
"failed to truncate, exiting\n");
res = CURLE_WRITE_ERROR;
goto quit_urls;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
if(response != 200 && response != 206) {
metalink_next_res = 1;
- fprintf(config->errors,
+ fprintf(global->errors,
"Metalink: fetching (%s) from (%s) FAILED "
"(HTTP status code %d)\n",
mlfile->filename, this_url, response);
}
else {
metalink_next_res = 1;
- fprintf(config->errors,
+ fprintf(global->errors,
"Metalink: fetching (%s) from (%s) FAILED (%s)\n",
mlfile->filename, this_url,
(errorbuffer[0]) ?
}
}
if(metalink && !metalink_next_res)
- fprintf(config->errors, "Metalink: fetching (%s) from (%s) OK\n",
+ fprintf(global->errors, "Metalink: fetching (%s) from (%s) OK\n",
mlfile->filename, this_url);
/* In all ordinary cases, just break out of loop here */
}
- if((config->progressmode == CURL_PROGRESS_BAR) &&
+ if((global->progressmode == CURL_PROGRESS_BAR) &&
progressbar.calls)
/* if the custom progress bar has been displayed, we output a
newline here */
#ifdef __VMS
if(is_vms_shell()) {
/* VMS DCL shell behavior */
- if(!config->showerror)
+ if(!global->showerror)
vms_show = VMSSTS_HIDE;
}
else
#endif
- if(res && config->showerror) {
- fprintf(config->errors, "curl: (%d) %s\n", res, (errorbuffer[0]) ?
+ if(res && global->showerror) {
+ fprintf(global->errors, "curl: (%d) %s\n", res, (errorbuffer[0]) ?
errorbuffer : curl_easy_strerror((CURLcode)res));
if(res == CURLE_SSL_CACERT)
- fprintf(config->errors, "%s%s",
+ fprintf(global->errors, "%s%s",
CURL_CA_CERT_ERRORMSG1, CURL_CA_CERT_ERRORMSG2);
}
if(!res && rc) {
/* something went wrong in the writing process */
res = CURLE_WRITE_ERROR;
- fprintf(config->errors, "(%d) Failed writing body\n", res);
+ fprintf(global->errors, "(%d) Failed writing body\n", res);
}
}
else if(!outs.s_isreg && outs.stream) {
if(!res && rc) {
/* something went wrong in the writing process */
res = CURLE_WRITE_ERROR;
- fprintf(config->errors, "(%d) Failed writing body\n", res);
+ fprintf(global->errors, "(%d) Failed writing body\n", res);
}
}
if(!metalink && config->use_metalink && res == CURLE_OK) {
int rv = parse_metalink(config, &outs, this_url);
if(rv == 0)
- fprintf(config->errors, "Metalink: parsing (%s) OK\n", this_url);
+ fprintf(config->global->errors, "Metalink: parsing (%s) OK\n",
+ this_url);
else if(rv == -1)
- fprintf(config->errors, "Metalink: parsing (%s) FAILED\n",
+ fprintf(config->global->errors, "Metalink: parsing (%s) FAILED\n",
this_url);
}
else if(metalink && res == CURLE_OK && !metalink_next_res) {
- int rv = metalink_check_hash(config, mlfile, outs.filename);
+ int rv = metalink_check_hash(global, mlfile, outs.filename);
if(rv == 0) {
metalink_next_res = 1;
}
quit_curl:
+ /* Reset the global config variables */
+ global->noprogress = orig_noprogress;
+ global->isatty = orig_isatty;
+
/* Free function-local referenced allocated memory */
Curl_safefree(httpgetfields);
/* Free list of given URLs */
clean_getout(config);
-#ifndef CURL_DISABLE_LIBCURL_OPTION
- easysrc_cleanup();
-#endif
-
hdrcbdata.heads = NULL;
/* Close function-local opened file descriptors */
-
if(heads.fopened && heads.stream)
fclose(heads.stream);
+
if(heads.alloc_filename)
Curl_safefree(heads.filename);
-#ifndef CURL_DISABLE_LIBCURL_OPTION
- /* Dump the libcurl code if previously enabled.
- NOTE: that this function relies on config->errors amongst other things
- so not everything can be closed and cleaned before this is called */
- dumpeasysrc(config);
-#endif
-
- return (CURLcode)res;
-}
-
-static void operate_free(struct Configurable *config)
-{
- if(config->easy) {
- curl_easy_cleanup(config->easy);
- config->easy = NULL;
- }
-
/* Release metalink related resources here */
clean_metalink(config);
+
+ return res;
}
-CURLcode operate(struct Configurable *config, int argc, argv_item_t argv[])
+CURLcode operate(struct GlobalConfig *config, int argc, argv_item_t argv[])
{
CURLcode result = CURLE_OK;
- /* Initialize the easy interface */
- result = operate_init(config);
- if(result)
- return result;
+ /* Setup proper locale from environment */
+#ifdef HAVE_SETLOCALE
+ setlocale(LC_ALL, "");
+#endif
/* Parse .curlrc if necessary */
if((argc == 1) || (!curlx_strequal(argv[1], "-q"))) {
parseconfig(NULL, config); /* ignore possible failure */
/* If we had no arguments then make sure a url was specified in .curlrc */
- if((argc < 2) && (!config->url_list)) {
+ if((argc < 2) && (!config->first->url_list)) {
helpf(config->errors, NULL);
result = CURLE_FAILED_INIT;
}
else
result = CURLE_FAILED_INIT;
}
- /* Perform the main operations */
else {
- size_t count = 0;
- struct Configurable *operation = config;
+#ifndef CURL_DISABLE_LIBCURL_OPTION
+ /* Initialise the libcurl source output */
+ result = easysrc_init();
+#endif
- /* Get the required aguments for each operation */
- while(!result && operation) {
- result = get_args(operation, count++);
+ /* Perform the main operations */
+ if(!result) {
+ size_t count = 0;
+ struct OperationConfig *operation = config->first;
- operation = operation->next;
- }
+ /* Get the required aguments for each operation */
+ while(!result && operation) {
+ result = get_args(operation, count++);
+
+ operation = operation->next;
+ }
- /* Reset the operation pointer */
- operation = config;
+ /* Set the current operation pointer */
+ config->current = config->first;
- /* Perform each operation */
- while(!result && operation) {
- result = operate_do(operation);
+ /* Perform each operation */
+ while(!result && config->current) {
+ result = operate_do(config, config->current);
- operation = operation->next;
+ config->current = config->current->next;
+ }
+
+#ifndef CURL_DISABLE_LIBCURL_OPTION
+ /* Cleanup the libcurl source output */
+ easysrc_cleanup();
+
+ /* Dump the libcurl code if previously enabled */
+ dumpeasysrc(config);
+#endif
}
+ else
+ helpf(config->errors, "out of memory\n");
}
}
- /* Perform the cleanup */
- operate_free(config);
-
return result;
}