00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "tool_setup.h"
00023
00024 #ifdef HAVE_FCNTL_H
00025 # include <fcntl.h>
00026 #endif
00027
00028 #ifdef HAVE_UTIME_H
00029 # include <utime.h>
00030 #elif defined(HAVE_SYS_UTIME_H)
00031 # include <sys/utime.h>
00032 #endif
00033
00034 #ifdef HAVE_LOCALE_H
00035 # include <locale.h>
00036 #endif
00037
00038 #ifdef HAVE_NETINET_TCP_H
00039 # include <netinet/tcp.h>
00040 #endif
00041
00042 #ifdef __VMS
00043 # include <fabdef.h>
00044 #endif
00045
00046 #include "strcase.h"
00047
00048 #define ENABLE_CURLX_PRINTF
00049
00050 #include "curlx.h"
00051
00052 #include "tool_binmode.h"
00053 #include "tool_cfgable.h"
00054 #include "tool_cb_dbg.h"
00055 #include "tool_cb_hdr.h"
00056 #include "tool_cb_prg.h"
00057 #include "tool_cb_rea.h"
00058 #include "tool_cb_see.h"
00059 #include "tool_cb_wrt.h"
00060 #include "tool_dirhie.h"
00061 #include "tool_doswin.h"
00062 #include "tool_easysrc.h"
00063 #include "tool_getparam.h"
00064 #include "tool_helpers.h"
00065 #include "tool_homedir.h"
00066 #include "tool_libinfo.h"
00067 #include "tool_main.h"
00068 #include "tool_metalink.h"
00069 #include "tool_msgs.h"
00070 #include "tool_operate.h"
00071 #include "tool_operhlp.h"
00072 #include "tool_paramhlp.h"
00073 #include "tool_parsecfg.h"
00074 #include "tool_setopt.h"
00075 #include "tool_sleep.h"
00076 #include "tool_urlglob.h"
00077 #include "tool_util.h"
00078 #include "tool_writeenv.h"
00079 #include "tool_writeout.h"
00080 #include "tool_xattr.h"
00081 #include "tool_vms.h"
00082 #include "tool_help.h"
00083 #include "tool_hugehelp.h"
00084
00085 #include "memdebug.h"
00086
00087 #ifdef CURLDEBUG
00088
00089 CURLcode curl_easy_perform_ev(CURL *easy);
00090 #endif
00091
00092 #define CURLseparator "--_curl_--"
00093
00094 #ifndef O_BINARY
00095
00096
00097 # define O_BINARY 0
00098 #endif
00099
00100 #define CURL_CA_CERT_ERRORMSG1 \
00101 "More details here: https://curl.haxx.se/docs/sslcerts.html\n\n" \
00102 "curl performs SSL certificate verification by default, " \
00103 "using a \"bundle\"\n" \
00104 " of Certificate Authority (CA) public keys (CA certs). If the default\n" \
00105 " bundle file isn't adequate, you can specify an alternate file\n" \
00106 " using the --cacert option.\n"
00107
00108 #define CURL_CA_CERT_ERRORMSG2 \
00109 "If this HTTPS server uses a certificate signed by a CA represented in\n" \
00110 " the bundle, the certificate verification probably failed due to a\n" \
00111 " problem with the certificate (it might be expired, or the name might\n" \
00112 " not match the domain name in the URL).\n" \
00113 "If you'd like to turn off curl's verification of the certificate, use\n" \
00114 " the -k (or --insecure) option.\n"
00115
00116 static bool is_fatal_error(CURLcode code)
00117 {
00118 switch(code) {
00119
00120 case CURLE_FAILED_INIT:
00121 case CURLE_OUT_OF_MEMORY:
00122 case CURLE_UNKNOWN_OPTION:
00123 case CURLE_FUNCTION_NOT_FOUND:
00124 case CURLE_BAD_FUNCTION_ARGUMENT:
00125
00126 return TRUE;
00127 default:
00128 break;
00129 }
00130
00131
00132 return FALSE;
00133 }
00134
00135 #ifdef __VMS
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 static curl_off_t vms_realfilesize(const char *name,
00147 const struct_stat *stat_buf)
00148 {
00149 char buffer[8192];
00150 curl_off_t count;
00151 int ret_stat;
00152 FILE * file;
00153
00154
00155 file = fopen(name, "r");
00156 if(file == NULL) {
00157 return 0;
00158 }
00159 count = 0;
00160 ret_stat = 1;
00161 while(ret_stat > 0) {
00162 ret_stat = fread(buffer, 1, sizeof(buffer), file);
00163 if(ret_stat != 0)
00164 count += ret_stat;
00165 }
00166 fclose(file);
00167
00168 return count;
00169 }
00170
00171
00172
00173
00174
00175
00176
00177 static curl_off_t VmsSpecialSize(const char *name,
00178 const struct_stat *stat_buf)
00179 {
00180 switch(stat_buf->st_fab_rfm) {
00181 case FAB$C_VAR:
00182 case FAB$C_VFC:
00183 return vms_realfilesize(name, stat_buf);
00184 break;
00185 default:
00186 return stat_buf->st_size;
00187 }
00188 }
00189 #endif
00190
00191 static CURLcode operate_do(struct GlobalConfig *global,
00192 struct OperationConfig *config)
00193 {
00194 char errorbuffer[CURL_ERROR_SIZE];
00195 struct ProgressData progressbar;
00196 struct getout *urlnode;
00197
00198 struct HdrCbData hdrcbdata;
00199 struct OutStruct heads;
00200
00201 metalinkfile *mlfile_last = NULL;
00202
00203 CURL *curl = config->easy;
00204 char *httpgetfields = NULL;
00205
00206 CURLcode result = CURLE_OK;
00207 unsigned long li;
00208 bool capath_from_env;
00209
00210
00211 bool orig_noprogress = global->noprogress;
00212 bool orig_isatty = global->isatty;
00213
00214 errorbuffer[0] = '\0';
00215
00216
00217 memset(&hdrcbdata, 0, sizeof(struct HdrCbData));
00218 memset(&heads, 0, sizeof(struct OutStruct));
00219 heads.stream = stdout;
00220 heads.config = config;
00221
00222
00223
00224
00225
00226
00227
00228
00229 if(!config->url_list || !config->url_list->url) {
00230 helpf(global->errors, "no URL specified!\n");
00231 result = CURLE_FAILED_INIT;
00232 goto quit_curl;
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 capath_from_env = false;
00245 if(!config->cacert &&
00246 !config->capath &&
00247 !config->insecure_ok) {
00248 char *env;
00249 env = curlx_getenv("CURL_CA_BUNDLE");
00250 if(env) {
00251 config->cacert = strdup(env);
00252 if(!config->cacert) {
00253 curl_free(env);
00254 helpf(global->errors, "out of memory\n");
00255 result = CURLE_OUT_OF_MEMORY;
00256 goto quit_curl;
00257 }
00258 }
00259 else {
00260 env = curlx_getenv("SSL_CERT_DIR");
00261 if(env) {
00262 config->capath = strdup(env);
00263 if(!config->capath) {
00264 curl_free(env);
00265 helpf(global->errors, "out of memory\n");
00266 result = CURLE_OUT_OF_MEMORY;
00267 goto quit_curl;
00268 }
00269 capath_from_env = true;
00270 }
00271 else {
00272 env = curlx_getenv("SSL_CERT_FILE");
00273 if(env) {
00274 config->cacert = strdup(env);
00275 if(!config->cacert) {
00276 curl_free(env);
00277 helpf(global->errors, "out of memory\n");
00278 result = CURLE_OUT_OF_MEMORY;
00279 goto quit_curl;
00280 }
00281 }
00282 }
00283 }
00284
00285 if(env)
00286 curl_free(env);
00287 #ifdef WIN32
00288 else {
00289 result = FindWin32CACert(config, "curl-ca-bundle.crt");
00290 if(result)
00291 goto quit_curl;
00292 }
00293 #endif
00294 }
00295
00296 if(config->postfields) {
00297 if(config->use_httpget) {
00298
00299 httpgetfields = strdup(config->postfields);
00300 Curl_safefree(config->postfields);
00301 if(!httpgetfields) {
00302 helpf(global->errors, "out of memory\n");
00303 result = CURLE_OUT_OF_MEMORY;
00304 goto quit_curl;
00305 }
00306 if(SetHTTPrequest(config,
00307 (config->no_body?HTTPREQ_HEAD:HTTPREQ_GET),
00308 &config->httpreq)) {
00309 result = CURLE_FAILED_INIT;
00310 goto quit_curl;
00311 }
00312 }
00313 else {
00314 if(SetHTTPrequest(config, HTTPREQ_SIMPLEPOST, &config->httpreq)) {
00315 result = CURLE_FAILED_INIT;
00316 goto quit_curl;
00317 }
00318 }
00319 }
00320
00321
00322 if(config->headerfile) {
00323
00324 if(strcmp(config->headerfile, "-")) {
00325 FILE *newfile = fopen(config->headerfile, "wb");
00326 if(!newfile) {
00327 warnf(config->global, "Failed to open %s\n", config->headerfile);
00328 result = CURLE_WRITE_ERROR;
00329 goto quit_curl;
00330 }
00331 else {
00332 heads.filename = config->headerfile;
00333 heads.s_isreg = TRUE;
00334 heads.fopened = TRUE;
00335 heads.stream = newfile;
00336 }
00337 }
00338 else {
00339
00340 set_binmode(heads.stream);
00341 }
00342 }
00343
00344
00345
00346
00347
00348
00349
00350 for(urlnode = config->url_list; urlnode; urlnode = urlnode->next) {
00351
00352 unsigned long up;
00353 char *infiles;
00354 char *outfiles;
00355 unsigned long infilenum;
00356 URLGlob *inglob;
00357
00358 int metalink = 0;
00359 metalinkfile *mlfile;
00360 metalink_resource *mlres;
00361
00362 outfiles = NULL;
00363 infilenum = 1;
00364 inglob = NULL;
00365
00366 if(urlnode->flags & GETOUT_METALINK) {
00367 metalink = 1;
00368 if(mlfile_last == NULL) {
00369 mlfile_last = config->metalinkfile_list;
00370 }
00371 mlfile = mlfile_last;
00372 mlfile_last = mlfile_last->next;
00373 mlres = mlfile->resource;
00374 }
00375 else {
00376 mlfile = NULL;
00377 mlres = NULL;
00378 }
00379
00380
00381
00382 if(!urlnode->url) {
00383
00384
00385 Curl_safefree(urlnode->outfile);
00386 Curl_safefree(urlnode->infile);
00387 urlnode->flags = 0;
00388 continue;
00389 }
00390
00391
00392 if(urlnode->outfile) {
00393 outfiles = strdup(urlnode->outfile);
00394 if(!outfiles) {
00395 helpf(global->errors, "out of memory\n");
00396 result = CURLE_OUT_OF_MEMORY;
00397 break;
00398 }
00399 }
00400
00401 infiles = urlnode->infile;
00402
00403 if(!config->globoff && infiles) {
00404
00405 result = glob_url(&inglob, infiles, &infilenum,
00406 global->showerror?global->errors:NULL);
00407 if(result) {
00408 Curl_safefree(outfiles);
00409 break;
00410 }
00411 }
00412
00413
00414
00415 for(up = 0 ; up < infilenum; up++) {
00416
00417 char *uploadfile;
00418 int separator;
00419 URLGlob *urls;
00420 unsigned long urlnum;
00421
00422 uploadfile = NULL;
00423 urls = NULL;
00424 urlnum = 0;
00425
00426 if(!up && !infiles)
00427 Curl_nop_stmt;
00428 else {
00429 if(inglob) {
00430 result = glob_next_url(&uploadfile, inglob);
00431 if(result == CURLE_OUT_OF_MEMORY)
00432 helpf(global->errors, "out of memory\n");
00433 }
00434 else if(!up) {
00435 uploadfile = strdup(infiles);
00436 if(!uploadfile) {
00437 helpf(global->errors, "out of memory\n");
00438 result = CURLE_OUT_OF_MEMORY;
00439 }
00440 }
00441 else
00442 uploadfile = NULL;
00443 if(!uploadfile)
00444 break;
00445 }
00446
00447 if(metalink) {
00448
00449
00450 urlnum = count_next_metalink_resource(mlfile);
00451 }
00452 else
00453 if(!config->globoff) {
00454
00455
00456 result = glob_url(&urls, urlnode->url, &urlnum,
00457 global->showerror?global->errors:NULL);
00458 if(result) {
00459 Curl_safefree(uploadfile);
00460 break;
00461 }
00462 }
00463 else
00464 urlnum = 1;
00465
00466
00467 separator= ((!outfiles || !strcmp(outfiles, "-")) && urlnum > 1);
00468
00469
00470 for(li = 0 ; li < urlnum; li++) {
00471
00472 int infd;
00473 bool infdopen;
00474 char *outfile;
00475 struct OutStruct outs;
00476 struct InStruct input;
00477 struct timeval retrystart;
00478 curl_off_t uploadfilesize;
00479 long retry_numretries;
00480 long retry_sleep_default;
00481 long retry_sleep;
00482 char *this_url = NULL;
00483 int metalink_next_res = 0;
00484
00485 outfile = NULL;
00486 infdopen = FALSE;
00487 infd = STDIN_FILENO;
00488 uploadfilesize = -1;
00489
00490
00491 memset(&outs, 0, sizeof(struct OutStruct));
00492 outs.stream = stdout;
00493 outs.config = config;
00494
00495 if(metalink) {
00496
00497
00498 outfile = strdup(mlfile->filename);
00499 if(!outfile) {
00500 result = CURLE_OUT_OF_MEMORY;
00501 goto show_error;
00502 }
00503 this_url = strdup(mlres->url);
00504 if(!this_url) {
00505 result = CURLE_OUT_OF_MEMORY;
00506 goto show_error;
00507 }
00508 }
00509 else {
00510 if(urls) {
00511 result = glob_next_url(&this_url, urls);
00512 if(result)
00513 goto show_error;
00514 }
00515 else if(!li) {
00516 this_url = strdup(urlnode->url);
00517 if(!this_url) {
00518 result = CURLE_OUT_OF_MEMORY;
00519 goto show_error;
00520 }
00521 }
00522 else
00523 this_url = NULL;
00524 if(!this_url)
00525 break;
00526
00527 if(outfiles) {
00528 outfile = strdup(outfiles);
00529 if(!outfile) {
00530 result = CURLE_OUT_OF_MEMORY;
00531 goto show_error;
00532 }
00533 }
00534 }
00535
00536 if(((urlnode->flags&GETOUT_USEREMOTE) ||
00537 (outfile && strcmp("-", outfile))) &&
00538 (metalink || !config->use_metalink)) {
00539
00540
00541
00542
00543
00544
00545 if(!outfile) {
00546
00547 result = get_url_file_name(&outfile, this_url);
00548 if(result)
00549 goto show_error;
00550 if(!*outfile && !config->content_disposition) {
00551 helpf(global->errors, "Remote file name has no length!\n");
00552 result = CURLE_WRITE_ERROR;
00553 goto quit_urls;
00554 }
00555 }
00556 else if(urls) {
00557
00558 char *storefile = outfile;
00559 result = glob_match_url(&outfile, storefile, urls);
00560 Curl_safefree(storefile);
00561 if(result) {
00562
00563 warnf(config->global, "bad output glob!\n");
00564 goto quit_urls;
00565 }
00566 }
00567
00568
00569
00570
00571 if(config->create_dirs || metalink) {
00572 result = create_dir_hierarchy(outfile, global->errors);
00573
00574 if(result == CURLE_WRITE_ERROR)
00575 goto quit_urls;
00576 if(result) {
00577 goto show_error;
00578 }
00579 }
00580
00581 if((urlnode->flags & GETOUT_USEREMOTE)
00582 && config->content_disposition) {
00583
00584 DEBUGASSERT(!outs.filename);
00585 }
00586
00587 if(config->resume_from_current) {
00588
00589
00590 struct_stat fileinfo;
00591
00592 if(0 == stat(outfile, &fileinfo))
00593
00594 config->resume_from = fileinfo.st_size;
00595 else
00596
00597 config->resume_from = 0;
00598 }
00599
00600 if(config->resume_from) {
00601 #ifdef __VMS
00602
00603
00604 FILE *file = fopen(outfile, config->resume_from?"ab":"wb",
00605 "ctx=stm", "rfm=stmlf", "rat=cr", "mrs=0");
00606 #else
00607
00608 FILE *file = fopen(outfile, config->resume_from?"ab":"wb");
00609 #endif
00610 if(!file) {
00611 helpf(global->errors, "Can't open '%s'!\n", outfile);
00612 result = CURLE_WRITE_ERROR;
00613 goto quit_urls;
00614 }
00615 outs.fopened = TRUE;
00616 outs.stream = file;
00617 outs.init = config->resume_from;
00618 }
00619 else {
00620 outs.stream = NULL;
00621 }
00622 outs.filename = outfile;
00623 outs.s_isreg = TRUE;
00624 }
00625
00626 if(uploadfile && !stdin_upload(uploadfile)) {
00627
00628
00629
00630 struct_stat fileinfo;
00631
00632 this_url = add_file_name_to_url(curl, this_url, uploadfile);
00633 if(!this_url) {
00634 result = CURLE_OUT_OF_MEMORY;
00635 goto show_error;
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651 #ifdef __VMS
00652
00653 infd = -1;
00654 if(stat(uploadfile, &fileinfo) == 0) {
00655 fileinfo.st_size = VmsSpecialSize(uploadfile, &fileinfo);
00656 switch(fileinfo.st_fab_rfm) {
00657 case FAB$C_VAR:
00658 case FAB$C_VFC:
00659 case FAB$C_STMCR:
00660 infd = open(uploadfile, O_RDONLY | O_BINARY);
00661 break;
00662 default:
00663 infd = open(uploadfile, O_RDONLY | O_BINARY,
00664 "rfm=stmlf", "ctx=stm");
00665 }
00666 }
00667 if(infd == -1)
00668 #else
00669 infd = open(uploadfile, O_RDONLY | O_BINARY);
00670 if((infd == -1) || fstat(infd, &fileinfo))
00671 #endif
00672 {
00673 helpf(global->errors, "Can't open '%s'!\n", uploadfile);
00674 if(infd != -1) {
00675 close(infd);
00676 infd = STDIN_FILENO;
00677 }
00678 result = CURLE_READ_ERROR;
00679 goto quit_urls;
00680 }
00681 infdopen = TRUE;
00682
00683
00684 if(S_ISREG(fileinfo.st_mode))
00685 uploadfilesize = fileinfo.st_size;
00686
00687 }
00688 else if(uploadfile && stdin_upload(uploadfile)) {
00689
00690
00691 int authbits = 0;
00692 int bitcheck = 0;
00693 while(bitcheck < 32) {
00694 if(config->authtype & (1UL << bitcheck++)) {
00695 authbits++;
00696 if(authbits > 1) {
00697
00698 break;
00699 }
00700 }
00701 }
00702
00703
00704
00705
00706
00707 if(config->proxyanyauth || (authbits>1)) {
00708 warnf(config->global,
00709 "Using --anyauth or --proxy-anyauth with upload from stdin"
00710 " involves a big risk of it not working. Use a temporary"
00711 " file or a fixed auth type instead!\n");
00712 }
00713
00714 DEBUGASSERT(infdopen == FALSE);
00715 DEBUGASSERT(infd == STDIN_FILENO);
00716
00717 set_binmode(stdin);
00718 if(!strcmp(uploadfile, ".")) {
00719 if(curlx_nonblock((curl_socket_t)infd, TRUE) < 0)
00720 warnf(config->global,
00721 "fcntl failed on fd=%d: %s\n", infd, strerror(errno));
00722 }
00723 }
00724
00725 if(uploadfile && config->resume_from_current)
00726 config->resume_from = -1;
00727
00728 if(output_expected(this_url, uploadfile) && outs.stream &&
00729 isatty(fileno(outs.stream)))
00730
00731
00732 global->noprogress = global->isatty = TRUE;
00733 else {
00734
00735
00736 global->noprogress = orig_noprogress;
00737 global->isatty = orig_isatty;
00738 }
00739
00740 if(urlnum > 1 && !global->mute) {
00741 fprintf(global->errors, "\n[%lu/%lu]: %s --> %s\n",
00742 li+1, urlnum, this_url, outfile ? outfile : "<stdout>");
00743 if(separator)
00744 printf("%s%s\n", CURLseparator, this_url);
00745 }
00746 if(httpgetfields) {
00747 char *urlbuffer;
00748
00749 const char *pc = strstr(this_url, "://");
00750 char sep = '?';
00751 if(pc)
00752 pc += 3;
00753 else
00754 pc = this_url;
00755
00756 pc = strrchr(pc, '/');
00757
00758 if(pc) {
00759
00760
00761 if(strchr(pc, '?'))
00762
00763
00764 sep='&';
00765 }
00766
00767
00768
00769 if(pc)
00770 urlbuffer = aprintf("%s%c%s", this_url, sep, httpgetfields);
00771 else
00772
00773
00774
00775 urlbuffer = aprintf("%s/?%s", this_url, httpgetfields);
00776
00777 if(!urlbuffer) {
00778 result = CURLE_OUT_OF_MEMORY;
00779 goto show_error;
00780 }
00781
00782 Curl_safefree(this_url);
00783 this_url = urlbuffer;
00784 }
00785
00786 if(!global->errors)
00787 global->errors = stderr;
00788
00789 if((!outfile || !strcmp(outfile, "-")) && !config->use_ascii) {
00790
00791
00792 set_binmode(stdout);
00793 }
00794
00795 if(!config->tcp_nodelay)
00796 my_setopt(curl, CURLOPT_TCP_NODELAY, 0L);
00797
00798 if(config->tcp_fastopen)
00799 my_setopt(curl, CURLOPT_TCP_FASTOPEN, 1L);
00800
00801
00802 my_setopt(curl, CURLOPT_WRITEDATA, &outs);
00803 my_setopt(curl, CURLOPT_INTERLEAVEDATA, &outs);
00804 if(metalink || !config->use_metalink)
00805
00806 my_setopt(curl, CURLOPT_WRITEFUNCTION, tool_write_cb);
00807 #ifdef USE_METALINK
00808 else
00809
00810
00811 my_setopt(curl, CURLOPT_WRITEFUNCTION, metalink_write_cb);
00812 #endif
00813
00814
00815 input.fd = infd;
00816 input.config = config;
00817
00818
00819
00820
00821
00822
00823
00824 my_setopt(curl, CURLOPT_READDATA, &input);
00825
00826 my_setopt(curl, CURLOPT_READFUNCTION, tool_read_cb);
00827
00828
00829
00830 my_setopt(curl, CURLOPT_SEEKDATA, &input);
00831 my_setopt(curl, CURLOPT_SEEKFUNCTION, tool_seek_cb);
00832
00833 if(config->recvpersecond)
00834
00835
00836 my_setopt(curl, CURLOPT_BUFFERSIZE, (long)config->recvpersecond);
00837
00838
00839 if(uploadfilesize != -1)
00840 my_setopt(curl, CURLOPT_INFILESIZE_LARGE, uploadfilesize);
00841 my_setopt_str(curl, CURLOPT_URL, this_url);
00842 my_setopt(curl, CURLOPT_NOPROGRESS, global->noprogress?1L:0L);
00843 if(config->no_body) {
00844 my_setopt(curl, CURLOPT_NOBODY, 1L);
00845 my_setopt(curl, CURLOPT_HEADER, 1L);
00846 }
00847
00848
00849
00850 else if(!config->use_metalink)
00851 my_setopt(curl, CURLOPT_HEADER, config->include_headers?1L:0L);
00852
00853 if(config->oauth_bearer)
00854 my_setopt_str(curl, CURLOPT_XOAUTH2_BEARER, config->oauth_bearer);
00855
00856 #if !defined(CURL_DISABLE_PROXY)
00857 {
00858
00859
00860 my_setopt_str(curl, CURLOPT_PROXY, config->proxy);
00861
00862 if(config->proxy)
00863 my_setopt_enum(curl, CURLOPT_PROXYTYPE, config->proxyver);
00864
00865 my_setopt_str(curl, CURLOPT_PROXYUSERPWD, config->proxyuserpwd);
00866
00867
00868 my_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, config->proxytunnel?1L:0L);
00869
00870
00871 if(config->preproxy)
00872 my_setopt_str(curl, CURLOPT_PRE_PROXY, config->preproxy);
00873
00874
00875 if(config->proxyanyauth)
00876 my_setopt_bitmask(curl, CURLOPT_PROXYAUTH,
00877 (long)CURLAUTH_ANY);
00878 else if(config->proxynegotiate)
00879 my_setopt_bitmask(curl, CURLOPT_PROXYAUTH,
00880 (long)CURLAUTH_GSSNEGOTIATE);
00881 else if(config->proxyntlm)
00882 my_setopt_bitmask(curl, CURLOPT_PROXYAUTH,
00883 (long)CURLAUTH_NTLM);
00884 else if(config->proxydigest)
00885 my_setopt_bitmask(curl, CURLOPT_PROXYAUTH,
00886 (long)CURLAUTH_DIGEST);
00887 else if(config->proxybasic)
00888 my_setopt_bitmask(curl, CURLOPT_PROXYAUTH,
00889 (long)CURLAUTH_BASIC);
00890
00891
00892 my_setopt_str(curl, CURLOPT_NOPROXY, config->noproxy);
00893 }
00894 #endif
00895
00896 my_setopt(curl, CURLOPT_FAILONERROR, config->failonerror?1L:0L);
00897 my_setopt(curl, CURLOPT_UPLOAD, uploadfile?1L:0L);
00898 my_setopt(curl, CURLOPT_DIRLISTONLY, config->dirlistonly?1L:0L);
00899 my_setopt(curl, CURLOPT_APPEND, config->ftp_append?1L:0L);
00900
00901 if(config->netrc_opt)
00902 my_setopt_enum(curl, CURLOPT_NETRC, (long)CURL_NETRC_OPTIONAL);
00903 else if(config->netrc || config->netrc_file)
00904 my_setopt_enum(curl, CURLOPT_NETRC, (long)CURL_NETRC_REQUIRED);
00905 else
00906 my_setopt_enum(curl, CURLOPT_NETRC, (long)CURL_NETRC_IGNORED);
00907
00908 if(config->netrc_file)
00909 my_setopt_str(curl, CURLOPT_NETRC_FILE, config->netrc_file);
00910
00911 my_setopt(curl, CURLOPT_TRANSFERTEXT, config->use_ascii?1L:0L);
00912 if(config->login_options)
00913 my_setopt_str(curl, CURLOPT_LOGIN_OPTIONS, config->login_options);
00914 my_setopt_str(curl, CURLOPT_USERPWD, config->userpwd);
00915 my_setopt_str(curl, CURLOPT_RANGE, config->range);
00916 my_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
00917 my_setopt(curl, CURLOPT_TIMEOUT_MS, (long)(config->timeout * 1000));
00918
00919 if(built_in_protos & CURLPROTO_HTTP) {
00920
00921 long postRedir = 0;
00922
00923 my_setopt(curl, CURLOPT_FOLLOWLOCATION,
00924 config->followlocation?1L:0L);
00925 my_setopt(curl, CURLOPT_UNRESTRICTED_AUTH,
00926 config->unrestricted_auth?1L:0L);
00927
00928 switch(config->httpreq) {
00929 case HTTPREQ_SIMPLEPOST:
00930 my_setopt_str(curl, CURLOPT_POSTFIELDS,
00931 config->postfields);
00932 my_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE,
00933 config->postfieldsize);
00934 break;
00935 case HTTPREQ_FORMPOST:
00936 my_setopt_httppost(curl, CURLOPT_HTTPPOST, config->httppost);
00937 break;
00938 default:
00939 break;
00940 }
00941
00942 my_setopt_str(curl, CURLOPT_REFERER, config->referer);
00943 my_setopt(curl, CURLOPT_AUTOREFERER, config->autoreferer?1L:0L);
00944 my_setopt_str(curl, CURLOPT_USERAGENT, config->useragent);
00945 my_setopt_slist(curl, CURLOPT_HTTPHEADER, config->headers);
00946
00947
00948 if(config->proxyheaders) {
00949 my_setopt_slist(curl, CURLOPT_PROXYHEADER, config->proxyheaders);
00950 my_setopt(curl, CURLOPT_HEADEROPT, CURLHEADER_SEPARATE);
00951 }
00952
00953
00954 my_setopt(curl, CURLOPT_MAXREDIRS, config->maxredirs);
00955
00956 if(config->httpversion)
00957 my_setopt_enum(curl, CURLOPT_HTTP_VERSION, config->httpversion);
00958 else if(curlinfo->features & CURL_VERSION_HTTP2) {
00959 my_setopt_enum(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
00960 }
00961
00962
00963 if(config->authtype)
00964 my_setopt_bitmask(curl, CURLOPT_HTTPAUTH, (long)config->authtype);
00965
00966
00967
00968 if(config->post301)
00969 postRedir |= CURL_REDIR_POST_301;
00970 if(config->post302)
00971 postRedir |= CURL_REDIR_POST_302;
00972 if(config->post303)
00973 postRedir |= CURL_REDIR_POST_303;
00974 my_setopt(curl, CURLOPT_POSTREDIR, postRedir);
00975
00976
00977 if(config->encoding)
00978 my_setopt_str(curl, CURLOPT_ACCEPT_ENCODING, "");
00979
00980
00981 if(config->tr_encoding)
00982 my_setopt(curl, CURLOPT_TRANSFER_ENCODING, 1L);
00983
00984 }
00985
00986 my_setopt_str(curl, CURLOPT_FTPPORT, config->ftpport);
00987 my_setopt(curl, CURLOPT_LOW_SPEED_LIMIT,
00988 config->low_speed_limit);
00989 my_setopt(curl, CURLOPT_LOW_SPEED_TIME, config->low_speed_time);
00990 my_setopt(curl, CURLOPT_MAX_SEND_SPEED_LARGE,
00991 config->sendpersecond);
00992 my_setopt(curl, CURLOPT_MAX_RECV_SPEED_LARGE,
00993 config->recvpersecond);
00994
00995 if(config->use_resume)
00996 my_setopt(curl, CURLOPT_RESUME_FROM_LARGE, config->resume_from);
00997 else
00998 my_setopt(curl, CURLOPT_RESUME_FROM_LARGE, CURL_OFF_T_C(0));
00999
01000 my_setopt_str(curl, CURLOPT_KEYPASSWD, config->key_passwd);
01001 my_setopt_str(curl, CURLOPT_PROXY_KEYPASSWD, config->proxy_key_passwd);
01002
01003 if(built_in_protos & (CURLPROTO_SCP|CURLPROTO_SFTP)) {
01004
01005
01006
01007 my_setopt_str(curl, CURLOPT_SSH_PRIVATE_KEYFILE, config->key);
01008
01009 my_setopt_str(curl, CURLOPT_SSH_PUBLIC_KEYFILE, config->pubkey);
01010
01011
01012
01013 my_setopt_str(curl, CURLOPT_SSH_HOST_PUBLIC_KEY_MD5,
01014 config->hostpubmd5);
01015 }
01016
01017 if(config->cacert)
01018 my_setopt_str(curl, CURLOPT_CAINFO, config->cacert);
01019 if(config->proxy_cacert)
01020 my_setopt_str(curl, CURLOPT_PROXY_CAINFO, config->proxy_cacert);
01021 if(config->capath) {
01022 result = res_setopt_str(curl, CURLOPT_CAPATH, config->capath);
01023 if(result == CURLE_NOT_BUILT_IN) {
01024 warnf(config->global, "ignoring %s, not supported by libcurl\n",
01025 capath_from_env?
01026 "SSL_CERT_DIR environment variable":"--capath");
01027 }
01028 else if(result)
01029 goto show_error;
01030 }
01031 if(config->proxy_capath)
01032 my_setopt_str(curl, CURLOPT_PROXY_CAPATH, config->proxy_capath);
01033 else if(config->capath)
01034 my_setopt_str(curl, CURLOPT_PROXY_CAPATH, config->capath);
01035
01036 if(config->crlfile)
01037 my_setopt_str(curl, CURLOPT_CRLFILE, config->crlfile);
01038 if(config->proxy_crlfile)
01039 my_setopt_str(curl, CURLOPT_PROXY_CRLFILE, config->proxy_crlfile);
01040 else if(config->crlfile)
01041 my_setopt_str(curl, CURLOPT_PROXY_CRLFILE, config->crlfile);
01042
01043 if(config->pinnedpubkey)
01044 my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, config->pinnedpubkey);
01045
01046 if(curlinfo->features & CURL_VERSION_SSL) {
01047 my_setopt_str(curl, CURLOPT_SSLCERT, config->cert);
01048 my_setopt_str(curl, CURLOPT_PROXY_SSLCERT, config->proxy_cert);
01049 my_setopt_str(curl, CURLOPT_SSLCERTTYPE, config->cert_type);
01050 my_setopt_str(curl, CURLOPT_PROXY_SSLCERTTYPE,
01051 config->proxy_cert_type);
01052 my_setopt_str(curl, CURLOPT_SSLKEY, config->key);
01053 my_setopt_str(curl, CURLOPT_PROXY_SSLKEY, config->proxy_key);
01054 my_setopt_str(curl, CURLOPT_SSLKEYTYPE, config->key_type);
01055 my_setopt_str(curl, CURLOPT_PROXY_SSLKEYTYPE,
01056 config->proxy_key_type);
01057
01058 if(config->insecure_ok) {
01059 my_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
01060 my_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
01061 }
01062 else {
01063 my_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
01064
01065
01066 }
01067 if(config->proxy_insecure_ok) {
01068 my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 0L);
01069 my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 0L);
01070 }
01071 else {
01072 my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 1L);
01073 }
01074
01075 if(config->verifystatus)
01076 my_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 1L);
01077
01078 if(config->falsestart)
01079 my_setopt(curl, CURLOPT_SSL_FALSESTART, 1L);
01080
01081 my_setopt_enum(curl, CURLOPT_SSLVERSION, config->ssl_version);
01082 my_setopt_enum(curl, CURLOPT_PROXY_SSLVERSION,
01083 config->proxy_ssl_version);
01084 }
01085 if(config->path_as_is)
01086 my_setopt(curl, CURLOPT_PATH_AS_IS, 1L);
01087
01088 if(built_in_protos & (CURLPROTO_SCP|CURLPROTO_SFTP)) {
01089 if(!config->insecure_ok) {
01090 char *home;
01091 char *file;
01092 result = CURLE_OUT_OF_MEMORY;
01093 home = homedir();
01094 if(home) {
01095 file = aprintf("%s/%sssh/known_hosts", home, DOT_CHAR);
01096 if(file) {
01097
01098 result = res_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, file);
01099 curl_free(file);
01100 if(result == CURLE_UNKNOWN_OPTION)
01101
01102 result = CURLE_OK;
01103 }
01104 Curl_safefree(home);
01105 }
01106 if(result)
01107 goto show_error;
01108 }
01109 }
01110
01111 if(config->no_body || config->remote_time) {
01112
01113 my_setopt(curl, CURLOPT_FILETIME, 1L);
01114 }
01115
01116 my_setopt(curl, CURLOPT_CRLF, config->crlf?1L:0L);
01117 my_setopt_slist(curl, CURLOPT_QUOTE, config->quote);
01118 my_setopt_slist(curl, CURLOPT_POSTQUOTE, config->postquote);
01119 my_setopt_slist(curl, CURLOPT_PREQUOTE, config->prequote);
01120
01121 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
01122 if(config->cookie)
01123 my_setopt_str(curl, CURLOPT_COOKIE, config->cookie);
01124
01125 if(config->cookiefile)
01126 my_setopt_str(curl, CURLOPT_COOKIEFILE, config->cookiefile);
01127
01128
01129 if(config->cookiejar)
01130 my_setopt_str(curl, CURLOPT_COOKIEJAR, config->cookiejar);
01131
01132
01133 my_setopt(curl, CURLOPT_COOKIESESSION, config->cookiesession?1L:0L);
01134 #else
01135 if(config->cookie || config->cookiefile || config->cookiejar) {
01136 warnf(config->global, "cookie option(s) used even though cookie "
01137 "support is disabled!\n");
01138 return CURLE_NOT_BUILT_IN;
01139 }
01140 #endif
01141
01142 my_setopt_enum(curl, CURLOPT_TIMECONDITION, (long)config->timecond);
01143 my_setopt(curl, CURLOPT_TIMEVALUE, (long)config->condtime);
01144 my_setopt_str(curl, CURLOPT_CUSTOMREQUEST, config->customrequest);
01145 customrequest_helper(config, config->httpreq, config->customrequest);
01146 my_setopt(curl, CURLOPT_STDERR, global->errors);
01147
01148
01149 my_setopt_str(curl, CURLOPT_INTERFACE, config->iface);
01150 my_setopt_str(curl, CURLOPT_KRBLEVEL, config->krblevel);
01151
01152 progressbarinit(&progressbar, config);
01153 if((global->progressmode == CURL_PROGRESS_BAR) &&
01154 !global->noprogress && !global->mute) {
01155
01156
01157 my_setopt(curl, CURLOPT_XFERINFOFUNCTION, tool_progress_cb);
01158 my_setopt(curl, CURLOPT_XFERINFODATA, &progressbar);
01159 }
01160
01161
01162 if(config->dns_servers)
01163 my_setopt_str(curl, CURLOPT_DNS_SERVERS, config->dns_servers);
01164
01165
01166 if(config->dns_interface)
01167 my_setopt_str(curl, CURLOPT_DNS_INTERFACE, config->dns_interface);
01168 if(config->dns_ipv4_addr)
01169 my_setopt_str(curl, CURLOPT_DNS_LOCAL_IP4, config->dns_ipv4_addr);
01170 if(config->dns_ipv6_addr)
01171 my_setopt_str(curl, CURLOPT_DNS_LOCAL_IP6, config->dns_ipv6_addr);
01172
01173
01174 my_setopt_slist(curl, CURLOPT_TELNETOPTIONS, config->telnet_options);
01175
01176
01177 my_setopt_str(curl, CURLOPT_RANDOM_FILE, config->random_file);
01178 my_setopt_str(curl, CURLOPT_EGDSOCKET, config->egd_file);
01179 my_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS,
01180 (long)(config->connecttimeout * 1000));
01181
01182 if(config->cipher_list)
01183 my_setopt_str(curl, CURLOPT_SSL_CIPHER_LIST, config->cipher_list);
01184
01185 if(config->proxy_cipher_list)
01186 my_setopt_str(curl, CURLOPT_PROXY_SSL_CIPHER_LIST,
01187 config->proxy_cipher_list);
01188
01189
01190 if(config->disable_epsv)
01191
01192 my_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L);
01193
01194
01195 if(config->disable_eprt)
01196
01197 my_setopt(curl, CURLOPT_FTP_USE_EPRT, 0L);
01198
01199 if(global->tracetype != TRACE_NONE) {
01200 my_setopt(curl, CURLOPT_DEBUGFUNCTION, tool_debug_cb);
01201 my_setopt(curl, CURLOPT_DEBUGDATA, config);
01202 my_setopt(curl, CURLOPT_VERBOSE, 1L);
01203 }
01204
01205
01206 if(config->engine) {
01207 result = res_setopt_str(curl, CURLOPT_SSLENGINE, config->engine);
01208 if(result)
01209 goto show_error;
01210 }
01211
01212
01213
01214 my_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS,
01215 (long)(config->ftp_create_dirs?
01216 CURLFTP_CREATE_DIR_RETRY:
01217 CURLFTP_CREATE_DIR_NONE));
01218
01219
01220 if(config->max_filesize)
01221 my_setopt(curl, CURLOPT_MAXFILESIZE_LARGE,
01222 config->max_filesize);
01223
01224 if(4 == config->ip_version)
01225 my_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
01226 else if(6 == config->ip_version)
01227 my_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);
01228 else
01229 my_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER);
01230
01231
01232 if(config->ftp_ssl_reqd)
01233 my_setopt_enum(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
01234
01235
01236 else if(config->ftp_ssl)
01237 my_setopt_enum(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_TRY);
01238
01239
01240 else if(config->ftp_ssl_control)
01241 my_setopt_enum(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_CONTROL);
01242
01243
01244 if(config->ftp_ssl_ccc)
01245 my_setopt_enum(curl, CURLOPT_FTP_SSL_CCC,
01246 (long)config->ftp_ssl_ccc_mode);
01247
01248
01249 if(config->socks5_gssapi_nec)
01250 my_setopt_str(curl, CURLOPT_SOCKS5_GSSAPI_NEC,
01251 config->socks5_gssapi_nec);
01252
01253
01254 if(config->proxy_service_name)
01255 my_setopt_str(curl, CURLOPT_PROXY_SERVICE_NAME,
01256 config->proxy_service_name);
01257
01258
01259 if(config->service_name)
01260 my_setopt_str(curl, CURLOPT_SERVICE_NAME,
01261 config->service_name);
01262
01263
01264 my_setopt_str(curl, CURLOPT_FTP_ACCOUNT, config->ftp_account);
01265
01266 my_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, config->ignorecl?1L:0L);
01267
01268
01269 my_setopt(curl, CURLOPT_FTP_SKIP_PASV_IP, config->ftp_skip_ip?1L:0L);
01270
01271
01272 my_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long)config->ftp_filemethod);
01273
01274
01275 if(config->localport) {
01276 my_setopt(curl, CURLOPT_LOCALPORT, (long)config->localport);
01277 my_setopt_str(curl, CURLOPT_LOCALPORTRANGE,
01278 (long)config->localportrange);
01279 }
01280
01281
01282 my_setopt_str(curl, CURLOPT_FTP_ALTERNATIVE_TO_USER,
01283 config->ftp_alternative_to_user);
01284
01285
01286 if(config->disable_sessionid)
01287
01288 my_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0L);
01289
01290
01291 if(config->raw) {
01292 my_setopt(curl, CURLOPT_HTTP_CONTENT_DECODING, 0L);
01293 my_setopt(curl, CURLOPT_HTTP_TRANSFER_DECODING, 0L);
01294 }
01295
01296
01297 if(!config->nokeepalive) {
01298 my_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
01299 if(config->alivetime != 0) {
01300 my_setopt(curl, CURLOPT_TCP_KEEPIDLE, config->alivetime);
01301 my_setopt(curl, CURLOPT_TCP_KEEPINTVL, config->alivetime);
01302 }
01303 }
01304 else
01305 my_setopt(curl, CURLOPT_TCP_KEEPALIVE, 0L);
01306
01307
01308 if(config->tftp_blksize)
01309 my_setopt(curl, CURLOPT_TFTP_BLKSIZE, config->tftp_blksize);
01310
01311 if(config->mail_from)
01312 my_setopt_str(curl, CURLOPT_MAIL_FROM, config->mail_from);
01313
01314 if(config->mail_rcpt)
01315 my_setopt_slist(curl, CURLOPT_MAIL_RCPT, config->mail_rcpt);
01316
01317
01318 if(config->ftp_pret)
01319 my_setopt(curl, CURLOPT_FTP_USE_PRET, 1L);
01320
01321 if(config->proto_present)
01322 my_setopt_flags(curl, CURLOPT_PROTOCOLS, config->proto);
01323 if(config->proto_redir_present)
01324 my_setopt_flags(curl, CURLOPT_REDIR_PROTOCOLS, config->proto_redir);
01325
01326 if(config->content_disposition
01327 && (urlnode->flags & GETOUT_USEREMOTE))
01328 hdrcbdata.honor_cd_filename = TRUE;
01329 else
01330 hdrcbdata.honor_cd_filename = FALSE;
01331
01332 hdrcbdata.outs = &outs;
01333 hdrcbdata.heads = &heads;
01334
01335 my_setopt(curl, CURLOPT_HEADERFUNCTION, tool_header_cb);
01336 my_setopt(curl, CURLOPT_HEADERDATA, &hdrcbdata);
01337
01338 if(config->resolve)
01339
01340 my_setopt_slist(curl, CURLOPT_RESOLVE, config->resolve);
01341
01342 if(config->connect_to)
01343
01344 my_setopt_slist(curl, CURLOPT_CONNECT_TO, config->connect_to);
01345
01346
01347 if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP) {
01348 if(config->tls_username)
01349 my_setopt_str(curl, CURLOPT_TLSAUTH_USERNAME,
01350 config->tls_username);
01351 if(config->tls_password)
01352 my_setopt_str(curl, CURLOPT_TLSAUTH_PASSWORD,
01353 config->tls_password);
01354 if(config->tls_authtype)
01355 my_setopt_str(curl, CURLOPT_TLSAUTH_TYPE,
01356 config->tls_authtype);
01357 if(config->proxy_tls_username)
01358 my_setopt_str(curl, CURLOPT_PROXY_TLSAUTH_USERNAME,
01359 config->proxy_tls_username);
01360 if(config->proxy_tls_password)
01361 my_setopt_str(curl, CURLOPT_PROXY_TLSAUTH_PASSWORD,
01362 config->proxy_tls_password);
01363 if(config->proxy_tls_authtype)
01364 my_setopt_str(curl, CURLOPT_PROXY_TLSAUTH_TYPE,
01365 config->proxy_tls_authtype);
01366 }
01367
01368
01369 if(config->gssapi_delegation)
01370 my_setopt_str(curl, CURLOPT_GSSAPI_DELEGATION,
01371 config->gssapi_delegation);
01372
01373
01374 {
01375 long mask = (config->ssl_allow_beast ? CURLSSLOPT_ALLOW_BEAST : 0) |
01376 (config->ssl_no_revoke ? CURLSSLOPT_NO_REVOKE : 0);
01377 if(mask)
01378 my_setopt_bitmask(curl, CURLOPT_SSL_OPTIONS, mask);
01379 }
01380
01381 if(config->proxy_ssl_allow_beast)
01382 my_setopt(curl, CURLOPT_PROXY_SSL_OPTIONS,
01383 (long)CURLSSLOPT_ALLOW_BEAST);
01384
01385 if(config->mail_auth)
01386 my_setopt_str(curl, CURLOPT_MAIL_AUTH, config->mail_auth);
01387
01388
01389 if(config->sasl_ir)
01390 my_setopt(curl, CURLOPT_SASL_IR, 1L);
01391
01392 if(config->nonpn) {
01393 my_setopt(curl, CURLOPT_SSL_ENABLE_NPN, 0L);
01394 }
01395
01396 if(config->noalpn) {
01397 my_setopt(curl, CURLOPT_SSL_ENABLE_ALPN, 0L);
01398 }
01399
01400
01401 if(config->unix_socket_path)
01402 my_setopt_str(curl, CURLOPT_UNIX_SOCKET_PATH,
01403 config->unix_socket_path);
01404
01405
01406 if(config->proto_default)
01407 my_setopt_str(curl, CURLOPT_DEFAULT_PROTOCOL, config->proto_default);
01408
01409
01410 if(config->expect100timeout > 0)
01411 my_setopt_str(curl, CURLOPT_EXPECT_100_TIMEOUT_MS,
01412 (long)(config->expect100timeout*1000));
01413
01414
01415 if(config->tftp_no_options)
01416 my_setopt(curl, CURLOPT_TFTP_NO_OPTIONS, 1L);
01417
01418
01419 retry_sleep_default = (config->retry_delay) ?
01420 config->retry_delay*1000L : RETRY_SLEEP_DEFAULT;
01421
01422 retry_numretries = config->req_retry;
01423 retry_sleep = retry_sleep_default;
01424 retrystart = tvnow();
01425
01426 #ifndef CURL_DISABLE_LIBCURL_OPTION
01427 if(global->libcurl) {
01428 result = easysrc_perform();
01429 if(result)
01430 goto show_error;
01431 }
01432 #endif
01433
01434 for(;;) {
01435 #ifdef USE_METALINK
01436 if(!metalink && config->use_metalink) {
01437
01438 if(outs.metalink_parser)
01439 metalink_parser_context_delete(outs.metalink_parser);
01440 outs.metalink_parser = metalink_parser_context_new();
01441 if(outs.metalink_parser == NULL) {
01442 result = CURLE_OUT_OF_MEMORY;
01443 goto show_error;
01444 }
01445 fprintf(config->global->errors,
01446 "Metalink: parsing (%s) metalink/XML...\n", this_url);
01447 }
01448 else if(metalink)
01449 fprintf(config->global->errors,
01450 "Metalink: fetching (%s) from (%s)...\n",
01451 mlfile->filename, this_url);
01452 #endif
01453
01454 #ifdef CURLDEBUG
01455 if(config->test_event_based)
01456 result = curl_easy_perform_ev(curl);
01457 else
01458 #endif
01459 result = curl_easy_perform(curl);
01460
01461 if(!result && !outs.stream && !outs.bytes) {
01462
01463
01464
01465 long cond_unmet = 0L;
01466
01467
01468 curl_easy_getinfo(curl, CURLINFO_CONDITION_UNMET, &cond_unmet);
01469 if(!cond_unmet && !tool_create_output_file(&outs))
01470 result = CURLE_WRITE_ERROR;
01471 }
01472
01473 if(outs.is_cd_filename && outs.stream && !global->mute &&
01474 outs.filename)
01475 printf("curl: Saved to filename '%s'\n", outs.filename);
01476
01477
01478
01479 if(retry_numretries &&
01480 (!config->retry_maxtime ||
01481 (tvdiff(tvnow(), retrystart) <
01482 config->retry_maxtime*1000L)) ) {
01483 enum {
01484 RETRY_NO,
01485 RETRY_TIMEOUT,
01486 RETRY_CONNREFUSED,
01487 RETRY_HTTP,
01488 RETRY_FTP,
01489 RETRY_LAST
01490 } retry = RETRY_NO;
01491 long response;
01492 if((CURLE_OPERATION_TIMEDOUT == result) ||
01493 (CURLE_COULDNT_RESOLVE_HOST == result) ||
01494 (CURLE_COULDNT_RESOLVE_PROXY == result) ||
01495 (CURLE_FTP_ACCEPT_TIMEOUT == result))
01496
01497 retry = RETRY_TIMEOUT;
01498 else if(config->retry_connrefused &&
01499 (CURLE_COULDNT_CONNECT == result)) {
01500 long oserrno;
01501 curl_easy_getinfo(curl, CURLINFO_OS_ERRNO, &oserrno);
01502 if(ECONNREFUSED == oserrno)
01503 retry = RETRY_CONNREFUSED;
01504 }
01505 else if((CURLE_OK == result) ||
01506 (config->failonerror &&
01507 (CURLE_HTTP_RETURNED_ERROR == result))) {
01508
01509
01510
01511 char *effective_url = NULL;
01512 curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effective_url);
01513 if(effective_url &&
01514 checkprefix("http", effective_url)) {
01515
01516 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
01517
01518 switch(response) {
01519 case 500:
01520 case 502:
01521 case 503:
01522 case 504:
01523 retry = RETRY_HTTP;
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534 break;
01535 }
01536 }
01537 }
01538 else if(result) {
01539 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
01540
01541 if(response/100 == 4)
01542
01543
01544
01545
01546
01547 retry = RETRY_FTP;
01548 }
01549
01550 if(retry) {
01551 static const char * const m[]={
01552 NULL,
01553 "timeout",
01554 "connection refused",
01555 "HTTP error",
01556 "FTP error"
01557 };
01558
01559 warnf(config->global, "Transient problem: %s "
01560 "Will retry in %ld seconds. "
01561 "%ld retries left.\n",
01562 m[retry], retry_sleep/1000L, retry_numretries);
01563
01564 tool_go_sleep(retry_sleep);
01565 retry_numretries--;
01566 if(!config->retry_delay) {
01567 retry_sleep *= 2;
01568 if(retry_sleep > RETRY_SLEEP_MAX)
01569 retry_sleep = RETRY_SLEEP_MAX;
01570 }
01571 if(outs.bytes && outs.filename && outs.stream) {
01572
01573
01574 if(!global->mute)
01575 fprintf(global->errors, "Throwing away %"
01576 CURL_FORMAT_CURL_OFF_T " bytes\n",
01577 outs.bytes);
01578 fflush(outs.stream);
01579
01580 #ifdef HAVE_FTRUNCATE
01581 if(ftruncate(fileno(outs.stream), outs.init)) {
01582
01583
01584 if(!global->mute)
01585 fprintf(global->errors,
01586 "failed to truncate, exiting\n");
01587 result = CURLE_WRITE_ERROR;
01588 goto quit_urls;
01589 }
01590
01591
01592 fseek(outs.stream, 0, SEEK_END);
01593 #else
01594
01595
01596
01597
01598 fseek(outs.stream, (long)outs.init, SEEK_SET);
01599 #endif
01600 outs.bytes = 0;
01601 }
01602 continue;
01603 }
01604 }
01605 else if(metalink) {
01606
01607
01608
01609 long response;
01610 if(CURLE_OK == result) {
01611
01612
01613 char *effective_url = NULL;
01614 curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effective_url);
01615 if(effective_url &&
01616 curl_strnequal(effective_url, "http", 4)) {
01617
01618 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
01619 if(response != 200 && response != 206) {
01620 metalink_next_res = 1;
01621 fprintf(global->errors,
01622 "Metalink: fetching (%s) from (%s) FAILED "
01623 "(HTTP status code %d)\n",
01624 mlfile->filename, this_url, response);
01625 }
01626 }
01627 }
01628 else {
01629 metalink_next_res = 1;
01630 fprintf(global->errors,
01631 "Metalink: fetching (%s) from (%s) FAILED (%s)\n",
01632 mlfile->filename, this_url,
01633 (errorbuffer[0]) ?
01634 errorbuffer : curl_easy_strerror(result));
01635 }
01636 }
01637 if(metalink && !metalink_next_res)
01638 fprintf(global->errors, "Metalink: fetching (%s) from (%s) OK\n",
01639 mlfile->filename, this_url);
01640
01641
01642 break;
01643
01644 }
01645
01646 if((global->progressmode == CURL_PROGRESS_BAR) &&
01647 progressbar.calls)
01648
01649
01650 fputs("\n", progressbar.out);
01651
01652 if(config->writeout)
01653 ourWriteOut(curl, &outs, config->writeout);
01654
01655 if(config->writeenv)
01656 ourWriteEnv(curl);
01657
01658
01659
01660
01661
01662
01663
01664
01665 show_error:
01666
01667 #ifdef __VMS
01668 if(is_vms_shell()) {
01669
01670 if(!global->showerror)
01671 vms_show = VMSSTS_HIDE;
01672 }
01673 else
01674 #endif
01675 if(result && global->showerror) {
01676 fprintf(global->errors, "curl: (%d) %s\n", result, (errorbuffer[0]) ?
01677 errorbuffer : curl_easy_strerror(result));
01678 if(result == CURLE_SSL_CACERT)
01679 fprintf(global->errors, "%s%s",
01680 CURL_CA_CERT_ERRORMSG1, CURL_CA_CERT_ERRORMSG2);
01681 }
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696 quit_urls:
01697
01698
01699 if(!result && config->xattr && outs.fopened && outs.stream) {
01700 int rc = fwrite_xattr(curl, fileno(outs.stream));
01701 if(rc)
01702 warnf(config->global, "Error setting extended attributes: %s\n",
01703 strerror(errno));
01704 }
01705
01706
01707 if(outs.fopened && outs.stream) {
01708 int rc = fclose(outs.stream);
01709 if(!result && rc) {
01710
01711 result = CURLE_WRITE_ERROR;
01712 fprintf(global->errors, "(%d) Failed writing body\n", result);
01713 }
01714 }
01715 else if(!outs.s_isreg && outs.stream) {
01716
01717 int rc = fflush(outs.stream);
01718 if(!result && rc) {
01719
01720 result = CURLE_WRITE_ERROR;
01721 fprintf(global->errors, "(%d) Failed writing body\n", result);
01722 }
01723 }
01724
01725 #ifdef __AMIGA__
01726 if(!result && outs.s_isreg && outs.filename) {
01727
01728 if(strlen(url) > 78)
01729 url[79] = '\0';
01730 SetComment(outs.filename, url);
01731 }
01732 #endif
01733
01734 #ifdef HAVE_UTIME
01735
01736 if(!result && config->remote_time && outs.s_isreg && outs.filename) {
01737
01738 long filetime = -1;
01739 curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
01740 if(filetime >= 0) {
01741 struct utimbuf times;
01742 times.actime = (time_t)filetime;
01743 times.modtime = (time_t)filetime;
01744 utime(outs.filename, ×);
01745 }
01746 }
01747 #endif
01748
01749 #ifdef USE_METALINK
01750 if(!metalink && config->use_metalink && result == CURLE_OK) {
01751 int rv = parse_metalink(config, &outs, this_url);
01752 if(rv == 0)
01753 fprintf(config->global->errors, "Metalink: parsing (%s) OK\n",
01754 this_url);
01755 else if(rv == -1)
01756 fprintf(config->global->errors, "Metalink: parsing (%s) FAILED\n",
01757 this_url);
01758 }
01759 else if(metalink && result == CURLE_OK && !metalink_next_res) {
01760 int rv = metalink_check_hash(global, mlfile, outs.filename);
01761 if(rv == 0) {
01762 metalink_next_res = 1;
01763 }
01764 }
01765 #endif
01766
01767
01768 if(outs.alloc_filename)
01769 Curl_safefree(outs.filename);
01770 #ifdef USE_METALINK
01771 if(outs.metalink_parser)
01772 metalink_parser_context_delete(outs.metalink_parser);
01773 #endif
01774 memset(&outs, 0, sizeof(struct OutStruct));
01775 hdrcbdata.outs = NULL;
01776
01777
01778
01779 Curl_safefree(outfile);
01780 Curl_safefree(this_url);
01781
01782 if(infdopen)
01783 close(infd);
01784
01785 if(metalink) {
01786
01787 if(is_fatal_error(result)) {
01788 break;
01789 }
01790 if(!metalink_next_res)
01791 break;
01792 mlres = mlres->next;
01793 if(mlres == NULL)
01794
01795
01796
01797 break;
01798 }
01799 else
01800 if(urlnum > 1) {
01801
01802 if(is_fatal_error(result))
01803 break;
01804 }
01805 else if(result)
01806
01807 break;
01808
01809 }
01810
01811
01812
01813 Curl_safefree(uploadfile);
01814
01815 if(urls) {
01816
01817 glob_cleanup(urls);
01818 urls = NULL;
01819 }
01820
01821 if(infilenum > 1) {
01822
01823 if(is_fatal_error(result))
01824 break;
01825 }
01826 else if(result)
01827
01828 break;
01829
01830 }
01831
01832
01833
01834 Curl_safefree(outfiles);
01835
01836 if(inglob) {
01837
01838 glob_cleanup(inglob);
01839 inglob = NULL;
01840 }
01841
01842
01843
01844 Curl_safefree(urlnode->url);
01845 Curl_safefree(urlnode->outfile);
01846 Curl_safefree(urlnode->infile);
01847 urlnode->flags = 0;
01848
01849
01850
01851
01852 if(is_fatal_error(result) || (result && global->fail_early))
01853 goto quit_curl;
01854
01855 }
01856
01857
01858
01859
01860
01861 quit_curl:
01862
01863
01864 global->noprogress = orig_noprogress;
01865 global->isatty = orig_isatty;
01866
01867
01868 Curl_safefree(httpgetfields);
01869
01870
01871 clean_getout(config);
01872
01873 hdrcbdata.heads = NULL;
01874
01875
01876 if(heads.fopened && heads.stream)
01877 fclose(heads.stream);
01878
01879 if(heads.alloc_filename)
01880 Curl_safefree(heads.filename);
01881
01882
01883 clean_metalink(config);
01884
01885 return result;
01886 }
01887
01888 CURLcode operate(struct GlobalConfig *config, int argc, argv_item_t argv[])
01889 {
01890 CURLcode result = CURLE_OK;
01891
01892
01893 #ifdef HAVE_SETLOCALE
01894 setlocale(LC_ALL, "");
01895 #endif
01896
01897
01898 if((argc == 1) ||
01899 (!curl_strequal(argv[1], "-q") &&
01900 !curl_strequal(argv[1], "--disable"))) {
01901 parseconfig(NULL, config);
01902
01903
01904 if((argc < 2) && (!config->first->url_list)) {
01905 helpf(config->errors, NULL);
01906 result = CURLE_FAILED_INIT;
01907 }
01908 }
01909
01910 if(!result) {
01911
01912 ParameterError res = parse_args(config, argc, argv);
01913 if(res) {
01914 result = CURLE_OK;
01915
01916
01917 if(res == PARAM_HELP_REQUESTED)
01918 tool_help();
01919
01920 else if(res == PARAM_MANUAL_REQUESTED)
01921 hugehelp();
01922
01923 else if(res == PARAM_VERSION_INFO_REQUESTED)
01924 tool_version_info();
01925
01926 else if(res == PARAM_ENGINES_REQUESTED)
01927 tool_list_engines(config->easy);
01928 else if(res == PARAM_LIBCURL_UNSUPPORTED_PROTOCOL)
01929 result = CURLE_UNSUPPORTED_PROTOCOL;
01930 else
01931 result = CURLE_FAILED_INIT;
01932 }
01933 else {
01934 #ifndef CURL_DISABLE_LIBCURL_OPTION
01935 if(config->libcurl) {
01936
01937 result = easysrc_init();
01938 }
01939 #endif
01940
01941
01942 if(!result) {
01943 size_t count = 0;
01944 struct OperationConfig *operation = config->first;
01945
01946
01947 while(!result && operation) {
01948 result = get_args(operation, count++);
01949
01950 operation = operation->next;
01951 }
01952
01953
01954 config->current = config->first;
01955
01956
01957 while(!result && config->current) {
01958 result = operate_do(config, config->current);
01959
01960 config->current = config->current->next;
01961 }
01962
01963 #ifndef CURL_DISABLE_LIBCURL_OPTION
01964 if(config->libcurl) {
01965
01966 easysrc_cleanup();
01967
01968
01969 dumpeasysrc(config);
01970 }
01971 #endif
01972 }
01973 else
01974 helpf(config->errors, "out of memory\n");
01975 }
01976 }
01977
01978 return result;
01979 }