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 #include "strcase.h"
00025
00026 #define ENABLE_CURLX_PRINTF
00027
00028 #include "curlx.h"
00029
00030 #include "tool_binmode.h"
00031 #include "tool_cfgable.h"
00032 #include "tool_cb_prg.h"
00033 #include "tool_formparse.h"
00034 #include "tool_getparam.h"
00035 #include "tool_helpers.h"
00036 #include "tool_libinfo.h"
00037 #include "tool_metalink.h"
00038 #include "tool_msgs.h"
00039 #include "tool_paramhlp.h"
00040 #include "tool_parsecfg.h"
00041
00042 #include "memdebug.h"
00043
00044 #ifdef MSDOS
00045 # define USE_WATT32
00046 #endif
00047
00048 #define GetStr(str,val) do { \
00049 if(*(str)) { \
00050 free(*(str)); \
00051 *(str) = NULL; \
00052 } \
00053 if((val)) { \
00054 *(str) = strdup((val)); \
00055 if(!(*(str))) \
00056 return PARAM_NO_MEM; \
00057 } \
00058 } WHILE_FALSE
00059
00060 struct LongShort {
00061 const char *letter;
00062 const char *lname;
00063 bool extraparam;
00064 };
00065
00066 static const struct LongShort aliases[]= {
00067
00068
00069 {"*@", "url", TRUE},
00070 {"*4", "dns-ipv4-addr", TRUE},
00071 {"*6", "dns-ipv6-addr", TRUE},
00072 {"*a", "random-file", TRUE},
00073 {"*b", "egd-file", TRUE},
00074 {"*B", "oauth2-bearer", TRUE},
00075 {"*c", "connect-timeout", TRUE},
00076 {"*d", "ciphers", TRUE},
00077 {"*D", "dns-interface", TRUE},
00078 {"*e", "disable-epsv", FALSE},
00079 {"*E", "epsv", FALSE},
00080
00081
00082 #ifdef USE_ENVIRONMENT
00083 {"*f", "environment", FALSE},
00084 #endif
00085 {"*F", "dns-servers", TRUE},
00086 {"*g", "trace", TRUE},
00087 {"*G", "npn", FALSE},
00088 {"*h", "trace-ascii", TRUE},
00089 {"*H", "alpn", FALSE},
00090 {"*i", "limit-rate", TRUE},
00091 {"*j", "compressed", FALSE},
00092 {"*J", "tr-encoding", FALSE},
00093 {"*k", "digest", FALSE},
00094 {"*l", "negotiate", FALSE},
00095 {"*m", "ntlm", FALSE},
00096 {"*M", "ntlm-wb", FALSE},
00097 {"*n", "basic", FALSE},
00098 {"*o", "anyauth", FALSE},
00099 #ifdef USE_WATT32
00100 {"*p", "wdebug", FALSE},
00101 #endif
00102 {"*q", "ftp-create-dirs", FALSE},
00103 {"*r", "create-dirs", FALSE},
00104 {"*s", "max-redirs", TRUE},
00105 {"*t", "proxy-ntlm", FALSE},
00106 {"*u", "crlf", FALSE},
00107 {"*v", "stderr", TRUE},
00108 {"*w", "interface", TRUE},
00109 {"*x", "krb", TRUE},
00110 {"*x", "krb4", TRUE},
00111
00112 {"*y", "max-filesize", TRUE},
00113 {"*z", "disable-eprt", FALSE},
00114 {"*Z", "eprt", FALSE},
00115
00116
00117 {"*~", "xattr", FALSE},
00118 {"$a", "ftp-ssl", FALSE},
00119
00120 {"$a", "ssl", FALSE},
00121
00122 {"$b", "ftp-pasv", FALSE},
00123 {"$c", "socks5", TRUE},
00124 {"$d", "tcp-nodelay", FALSE},
00125 {"$e", "proxy-digest", FALSE},
00126 {"$f", "proxy-basic", FALSE},
00127 {"$g", "retry", TRUE},
00128 {"$V", "retry-connrefused", FALSE},
00129 {"$h", "retry-delay", TRUE},
00130 {"$i", "retry-max-time", TRUE},
00131 {"$k", "proxy-negotiate", FALSE},
00132 {"$m", "ftp-account", TRUE},
00133 {"$n", "proxy-anyauth", FALSE},
00134 {"$o", "trace-time", FALSE},
00135 {"$p", "ignore-content-length", FALSE},
00136 {"$q", "ftp-skip-pasv-ip", FALSE},
00137 {"$r", "ftp-method", TRUE},
00138 {"$s", "local-port", TRUE},
00139 {"$t", "socks4", TRUE},
00140 {"$T", "socks4a", TRUE},
00141 {"$u", "ftp-alternative-to-user", TRUE},
00142 {"$v", "ftp-ssl-reqd", FALSE},
00143
00144 {"$v", "ssl-reqd", FALSE},
00145
00146 {"$w", "sessionid", FALSE},
00147
00148 {"$x", "ftp-ssl-control", FALSE},
00149 {"$y", "ftp-ssl-ccc", FALSE},
00150 {"$j", "ftp-ssl-ccc-mode", TRUE},
00151 {"$z", "libcurl", TRUE},
00152 {"$#", "raw", FALSE},
00153 {"$0", "post301", FALSE},
00154 {"$1", "keepalive", FALSE},
00155
00156 {"$2", "socks5-hostname", TRUE},
00157 {"$3", "keepalive-time", TRUE},
00158 {"$4", "post302", FALSE},
00159 {"$5", "noproxy", TRUE},
00160 {"$7", "socks5-gssapi-nec", FALSE},
00161 {"$8", "proxy1.0", TRUE},
00162 {"$9", "tftp-blksize", TRUE},
00163 {"$A", "mail-from", TRUE},
00164 {"$B", "mail-rcpt", TRUE},
00165 {"$C", "ftp-pret", FALSE},
00166 {"$D", "proto", TRUE},
00167 {"$E", "proto-redir", TRUE},
00168 {"$F", "resolve", TRUE},
00169 {"$G", "delegation", TRUE},
00170 {"$H", "mail-auth", TRUE},
00171 {"$I", "post303", FALSE},
00172 {"$J", "metalink", FALSE},
00173 {"$K", "sasl-ir", FALSE},
00174 {"$L", "test-event", FALSE},
00175 {"$M", "unix-socket", TRUE},
00176 {"$N", "path-as-is", FALSE},
00177 {"$O", "socks5-gssapi-service", TRUE},
00178
00179
00180 {"$O", "proxy-service-name", TRUE},
00181 {"$P", "service-name", TRUE},
00182 {"$Q", "proto-default", TRUE},
00183 {"$R", "expect100-timeout", TRUE},
00184 {"$S", "tftp-no-options", FALSE},
00185 {"$U", "connect-to", TRUE},
00186 {"0", "http1.0", FALSE},
00187 {"01", "http1.1", FALSE},
00188 {"02", "http2", FALSE},
00189 {"03", "http2-prior-knowledge", FALSE},
00190 {"1", "tlsv1", FALSE},
00191 {"10", "tlsv1.0", FALSE},
00192 {"11", "tlsv1.1", FALSE},
00193 {"12", "tlsv1.2", FALSE},
00194 {"13", "tlsv1.3", FALSE},
00195 {"2", "sslv2", FALSE},
00196 {"3", "sslv3", FALSE},
00197 {"4", "ipv4", FALSE},
00198 {"6", "ipv6", FALSE},
00199 {"a", "append", FALSE},
00200 {"A", "user-agent", TRUE},
00201 {"b", "cookie", TRUE},
00202 {"B", "use-ascii", FALSE},
00203 {"c", "cookie-jar", TRUE},
00204 {"C", "continue-at", TRUE},
00205 {"d", "data", TRUE},
00206 {"dr", "data-raw", TRUE},
00207 {"da", "data-ascii", TRUE},
00208 {"db", "data-binary", TRUE},
00209 {"de", "data-urlencode", TRUE},
00210 {"D", "dump-header", TRUE},
00211 {"e", "referer", TRUE},
00212 {"E", "cert", TRUE},
00213 {"Ea", "cacert", TRUE},
00214 {"Eb", "cert-type", TRUE},
00215 {"Ec", "key", TRUE},
00216 {"Ed", "key-type", TRUE},
00217 {"Ee", "pass", TRUE},
00218 {"Ef", "engine", TRUE},
00219 {"Eg", "capath", TRUE},
00220 {"Eh", "pubkey", TRUE},
00221 {"Ei", "hostpubmd5", TRUE},
00222 {"Ej", "crlfile", TRUE},
00223 {"Ek", "tlsuser", TRUE},
00224 {"El", "tlspassword", TRUE},
00225 {"Em", "tlsauthtype", TRUE},
00226 {"En", "ssl-allow-beast", FALSE},
00227 {"Eo", "login-options", TRUE},
00228 {"Ep", "pinnedpubkey", TRUE},
00229 {"Eq", "cert-status", FALSE},
00230 {"Er", "false-start", FALSE},
00231 {"Es", "ssl-no-revoke", FALSE},
00232 {"Et", "tcp-fastopen", FALSE},
00233 {"Eu", "proxy-tlsuser", TRUE},
00234 {"Ev", "proxy-tlspassword", TRUE},
00235 {"Ew", "proxy-tlsauthtype", TRUE},
00236 {"Ex", "proxy-cert", TRUE},
00237 {"Ey", "proxy-cert-type", TRUE},
00238 {"Ez", "proxy-key", TRUE},
00239 {"E0", "proxy-key-type", TRUE},
00240 {"E1", "proxy-pass", TRUE},
00241 {"E2", "proxy-ciphers", TRUE},
00242 {"E3", "proxy-crlfile", TRUE},
00243 {"E4", "proxy-ssl-allow-beast", FALSE},
00244 {"E5", "login-options", TRUE},
00245 {"E6", "proxy-cacert", TRUE},
00246 {"E7", "proxy-capath", TRUE},
00247 {"E8", "proxy-insecure", FALSE},
00248 {"E9", "proxy-tlsv1", FALSE},
00249 {"f", "fail", FALSE},
00250 {"fa", "fail-early", FALSE},
00251 {"F", "form", TRUE},
00252 {"Fs", "form-string", TRUE},
00253 {"g", "globoff", FALSE},
00254 {"G", "get", FALSE},
00255 {"h", "help", FALSE},
00256 {"H", "header", TRUE},
00257 {"Hp", "proxy-header", TRUE},
00258 {"i", "include", FALSE},
00259 {"I", "head", FALSE},
00260 {"j", "junk-session-cookies", FALSE},
00261 {"J", "remote-header-name", FALSE},
00262 {"k", "insecure", FALSE},
00263 {"K", "config", TRUE},
00264 {"l", "list-only", FALSE},
00265 {"L", "location", FALSE},
00266 {"Lt", "location-trusted", FALSE},
00267 {"m", "max-time", TRUE},
00268 {"M", "manual", FALSE},
00269 {"n", "netrc", FALSE},
00270 {"no", "netrc-optional", FALSE},
00271 {"ne", "netrc-file", TRUE},
00272 {"N", "buffer", FALSE},
00273
00274 {"o", "output", TRUE},
00275 {"O", "remote-name", FALSE},
00276 {"Oa", "remote-name-all", FALSE},
00277 {"p", "proxytunnel", FALSE},
00278 {"P", "ftp-port", TRUE},
00279 {"q", "disable", FALSE},
00280 {"Q", "quote", TRUE},
00281 {"r", "range", TRUE},
00282 {"R", "remote-time", FALSE},
00283 {"s", "silent", FALSE},
00284 {"S", "show-error", FALSE},
00285 {"t", "telnet-option", TRUE},
00286 {"T", "upload-file", TRUE},
00287 {"u", "user", TRUE},
00288 {"U", "proxy-user", TRUE},
00289 {"v", "verbose", FALSE},
00290 {"V", "version", FALSE},
00291 {"w", "write-out", TRUE},
00292 {"x", "proxy", TRUE},
00293 {"xa", "preproxy", TRUE},
00294 {"X", "request", TRUE},
00295 {"Y", "speed-limit", TRUE},
00296 {"y", "speed-time", TRUE},
00297 {"z", "time-cond", TRUE},
00298 {"#", "progress-bar", FALSE},
00299 {":", "next", FALSE},
00300 };
00301
00302
00303
00304
00305
00306 #ifndef UNITTESTS
00307 static
00308 #endif
00309 void parse_cert_parameter(const char *cert_parameter,
00310 char **certname,
00311 char **passphrase)
00312 {
00313 size_t param_length = strlen(cert_parameter);
00314 size_t span;
00315 const char *param_place = NULL;
00316 char *certname_place = NULL;
00317 *certname = NULL;
00318 *passphrase = NULL;
00319
00320
00321 if(param_length == 0)
00322 return;
00323
00324
00325
00326
00327
00328 if(!strncmp(cert_parameter, "pkcs11:", 7) ||
00329 !strpbrk(cert_parameter, ":\\")) {
00330 *certname = strdup(cert_parameter);
00331 return;
00332 }
00333
00334 certname_place = malloc(param_length + 1);
00335 if(!certname_place)
00336 return;
00337
00338 *certname = certname_place;
00339 param_place = cert_parameter;
00340 while(*param_place) {
00341 span = strcspn(param_place, ":\\");
00342 strncpy(certname_place, param_place, span);
00343 param_place += span;
00344 certname_place += span;
00345
00346
00347 switch(*param_place) {
00348 case '\0':
00349 break;
00350 case '\\':
00351 param_place++;
00352 switch(*param_place) {
00353 case '\0':
00354 *certname_place++ = '\\';
00355 break;
00356 case '\\':
00357 *certname_place++ = '\\';
00358 param_place++;
00359 break;
00360 case ':':
00361 *certname_place++ = ':';
00362 param_place++;
00363 break;
00364 default:
00365 *certname_place++ = '\\';
00366 *certname_place++ = *param_place;
00367 param_place++;
00368 break;
00369 }
00370 break;
00371 case ':':
00372
00373
00374
00375
00376
00377 #ifdef WIN32
00378 if(param_place &&
00379 (param_place == &cert_parameter[1]) &&
00380 (cert_parameter[2] == '\\' || cert_parameter[2] == '/') &&
00381 (ISALPHA(cert_parameter[0])) ) {
00382
00383
00384
00385
00386 *certname_place++ = ':';
00387 param_place++;
00388 break;
00389 }
00390 #endif
00391
00392
00393 param_place++;
00394 if(strlen(param_place) > 0) {
00395 *passphrase = strdup(param_place);
00396 }
00397 goto done;
00398 }
00399 }
00400 done:
00401 *certname_place = '\0';
00402 }
00403
00404 static void
00405 GetFileAndPassword(char *nextarg, char **file, char **password)
00406 {
00407 char *certname, *passphrase;
00408 parse_cert_parameter(nextarg, &certname, &passphrase);
00409 Curl_safefree(*file);
00410 *file = certname;
00411 if(passphrase) {
00412 Curl_safefree(*password);
00413 *password = passphrase;
00414 }
00415 cleanarg(nextarg);
00416 }
00417
00418 ParameterError getparameter(char *flag,
00419 char *nextarg,
00420 bool *usedarg,
00421
00422 struct GlobalConfig *global,
00423 struct OperationConfig *config)
00424 {
00425 char letter;
00426 char subletter = '\0';
00427 int rc;
00428 const char *parse = NULL;
00429 unsigned int j;
00430 time_t now;
00431 int hit = -1;
00432 bool longopt = FALSE;
00433 bool singleopt = FALSE;
00434 ParameterError err;
00435 bool toggle = TRUE;
00436
00437
00438
00439 if(('-' != flag[0]) ||
00440 (('-' == flag[0]) && ('-' == flag[1]))) {
00441
00442 char *word = ('-' == flag[0]) ? flag+2 : flag;
00443 size_t fnam = strlen(word);
00444 int numhits = 0;
00445
00446 if(!strncmp(word, "no-", 3)) {
00447
00448 word += 3;
00449 toggle = FALSE;
00450 }
00451
00452 for(j = 0; j < sizeof(aliases)/sizeof(aliases[0]); j++) {
00453 if(curl_strnequal(aliases[j].lname, word, fnam)) {
00454 longopt = TRUE;
00455 numhits++;
00456 if(curl_strequal(aliases[j].lname, word)) {
00457 parse = aliases[j].letter;
00458 hit = j;
00459 numhits = 1;
00460 break;
00461 }
00462 parse = aliases[j].letter;
00463 hit = j;
00464 }
00465 }
00466 if(numhits > 1) {
00467
00468 return PARAM_OPTION_AMBIGUOUS;
00469 }
00470 if(hit < 0) {
00471 return PARAM_OPTION_UNKNOWN;
00472 }
00473 }
00474 else {
00475 flag++;
00476 hit = -1;
00477 parse = flag;
00478 }
00479
00480 do {
00481
00482
00483 if(!longopt) {
00484 letter = (char)*parse;
00485 subletter='\0';
00486 }
00487 else {
00488 letter = parse[0];
00489 subletter = parse[1];
00490 }
00491 *usedarg = FALSE;
00492
00493 if(hit < 0) {
00494 for(j = 0; j < sizeof(aliases)/sizeof(aliases[0]); j++) {
00495 if(letter == aliases[j].letter[0]) {
00496 hit = j;
00497 break;
00498 }
00499 }
00500 if(hit < 0) {
00501 return PARAM_OPTION_UNKNOWN;
00502 }
00503 }
00504
00505 if(aliases[hit].extraparam) {
00506
00507 if(!longopt && parse[1]) {
00508 nextarg = (char *)&parse[1];
00509 singleopt = TRUE;
00510 }
00511 else if(!nextarg)
00512 return PARAM_REQUIRES_PARAMETER;
00513 else
00514 *usedarg = TRUE;
00515 }
00516
00517 switch(letter) {
00518 case '*':
00519 switch(subletter) {
00520 case '4':
00521
00522 GetStr(&config->dns_ipv4_addr, nextarg);
00523 break;
00524 case '6':
00525
00526 GetStr(&config->dns_ipv6_addr, nextarg);
00527 break;
00528 case 'a':
00529 GetStr(&config->random_file, nextarg);
00530 break;
00531 case 'b':
00532 GetStr(&config->egd_file, nextarg);
00533 break;
00534 case 'B':
00535 GetStr(&config->oauth_bearer, nextarg);
00536 break;
00537 case 'c':
00538 err = str2udouble(&config->connecttimeout, nextarg);
00539 if(err)
00540 return err;
00541 break;
00542 case 'd':
00543 GetStr(&config->cipher_list, nextarg);
00544 break;
00545 case 'D':
00546
00547 GetStr(&config->dns_interface, nextarg);
00548 break;
00549 case 'e':
00550 config->disable_epsv = toggle;
00551 break;
00552 case 'E':
00553 config->disable_epsv = (!toggle)?TRUE:FALSE;
00554 break;
00555 #ifdef USE_ENVIRONMENT
00556 case 'f':
00557 config->writeenv = toggle;
00558 break;
00559 #endif
00560 case 'F':
00561
00562 GetStr(&config->dns_servers, nextarg);
00563 break;
00564 case 'g':
00565 GetStr(&global->trace_dump, nextarg);
00566 if(global->tracetype && (global->tracetype != TRACE_BIN))
00567 warnf(global, "--trace overrides an earlier trace/verbose option\n");
00568 global->tracetype = TRACE_BIN;
00569 break;
00570 case 'G':
00571 config->nonpn = (!toggle)?TRUE:FALSE;
00572 break;
00573 case 'h':
00574 GetStr(&global->trace_dump, nextarg);
00575 if(global->tracetype && (global->tracetype != TRACE_ASCII))
00576 warnf(global,
00577 "--trace-ascii overrides an earlier trace/verbose option\n");
00578 global->tracetype = TRACE_ASCII;
00579 break;
00580 case 'H':
00581 config->noalpn = (!toggle)?TRUE:FALSE;
00582 break;
00583 case 'i':
00584 {
00585
00586 char *unit;
00587 curl_off_t value = curlx_strtoofft(nextarg, &unit, 0);
00588
00589 if(!*unit)
00590 unit = (char *)"b";
00591 else if(strlen(unit) > 1)
00592 unit = (char *)"w";
00593
00594 switch(*unit) {
00595 case 'G':
00596 case 'g':
00597 value *= 1024*1024*1024;
00598 break;
00599 case 'M':
00600 case 'm':
00601 value *= 1024*1024;
00602 break;
00603 case 'K':
00604 case 'k':
00605 value *= 1024;
00606 break;
00607 case 'b':
00608 case 'B':
00609
00610 break;
00611 default:
00612 warnf(global, "unsupported rate unit. Use G, M, K or B!\n");
00613 return PARAM_BAD_USE;
00614 }
00615 config->recvpersecond = value;
00616 config->sendpersecond = value;
00617 }
00618 break;
00619
00620 case 'j':
00621 if(toggle && !(curlinfo->features & CURL_VERSION_LIBZ))
00622 return PARAM_LIBCURL_DOESNT_SUPPORT;
00623 config->encoding = toggle;
00624 break;
00625
00626 case 'J':
00627 config->tr_encoding = toggle;
00628 break;
00629
00630 case 'k':
00631 if(toggle)
00632 config->authtype |= CURLAUTH_DIGEST;
00633 else
00634 config->authtype &= ~CURLAUTH_DIGEST;
00635 break;
00636
00637 case 'l':
00638 if(toggle) {
00639 if(curlinfo->features & CURL_VERSION_SPNEGO)
00640 config->authtype |= CURLAUTH_NEGOTIATE;
00641 else
00642 return PARAM_LIBCURL_DOESNT_SUPPORT;
00643 }
00644 else
00645 config->authtype &= ~CURLAUTH_NEGOTIATE;
00646 break;
00647
00648 case 'm':
00649 if(toggle) {
00650 if(curlinfo->features & CURL_VERSION_NTLM)
00651 config->authtype |= CURLAUTH_NTLM;
00652 else
00653 return PARAM_LIBCURL_DOESNT_SUPPORT;
00654 }
00655 else
00656 config->authtype &= ~CURLAUTH_NTLM;
00657 break;
00658
00659 case 'M':
00660 if(toggle) {
00661 if(curlinfo->features & CURL_VERSION_NTLM_WB)
00662 config->authtype |= CURLAUTH_NTLM_WB;
00663 else
00664 return PARAM_LIBCURL_DOESNT_SUPPORT;
00665 }
00666 else
00667 config->authtype &= ~CURLAUTH_NTLM_WB;
00668 break;
00669
00670 case 'n':
00671 if(toggle)
00672 config->authtype |= CURLAUTH_BASIC;
00673 else
00674 config->authtype &= ~CURLAUTH_BASIC;
00675 break;
00676
00677 case 'o':
00678 if(toggle)
00679 config->authtype = CURLAUTH_ANY;
00680
00681 break;
00682
00683 #ifdef USE_WATT32
00684 case 'p':
00685 dbug_init();
00686 break;
00687 #endif
00688 case 'q':
00689 config->ftp_create_dirs = toggle;
00690 break;
00691
00692 case 'r':
00693 config->create_dirs = toggle;
00694 break;
00695
00696 case 's':
00697
00698
00699 err = str2num(&config->maxredirs, nextarg);
00700 if(err)
00701 return err;
00702 if(config->maxredirs < -1)
00703 return PARAM_BAD_NUMERIC;
00704 break;
00705
00706 case 't':
00707 if(curlinfo->features & CURL_VERSION_NTLM)
00708 config->proxyntlm = toggle;
00709 else
00710 return PARAM_LIBCURL_DOESNT_SUPPORT;
00711 break;
00712
00713 case 'u':
00714
00715 config->crlf = toggle;
00716 break;
00717
00718 case 'v':
00719 if(strcmp(nextarg, "-")) {
00720 FILE *newfile = fopen(nextarg, FOPEN_WRITETEXT);
00721 if(!newfile)
00722 warnf(global, "Failed to open %s!\n", nextarg);
00723 else {
00724 if(global->errors_fopened)
00725 fclose(global->errors);
00726 global->errors = newfile;
00727 global->errors_fopened = TRUE;
00728 }
00729 }
00730 else
00731 global->errors = stdout;
00732 break;
00733 case 'w':
00734
00735 GetStr(&config->iface, nextarg);
00736 break;
00737 case 'x':
00738
00739 if(curlinfo->features & CURL_VERSION_KERBEROS4)
00740 GetStr(&config->krblevel, nextarg);
00741 else
00742 return PARAM_LIBCURL_DOESNT_SUPPORT;
00743 break;
00744 case 'y':
00745 err = str2offset(&config->max_filesize, nextarg);
00746 if(err)
00747 return err;
00748 break;
00749 case 'z':
00750 config->disable_eprt = toggle;
00751 break;
00752 case 'Z':
00753 config->disable_eprt = (!toggle)?TRUE:FALSE;
00754 break;
00755 case '~':
00756 config->xattr = toggle;
00757 break;
00758 case '@':
00759 {
00760 struct getout *url;
00761
00762 if(!config->url_get)
00763 config->url_get = config->url_list;
00764
00765 if(config->url_get) {
00766
00767
00768 while(config->url_get && (config->url_get->flags & GETOUT_URL))
00769 config->url_get = config->url_get->next;
00770 }
00771
00772
00773
00774 if(config->url_get)
00775
00776 url = config->url_get;
00777 else
00778
00779 url = new_getout(config);
00780
00781 if(!url)
00782 return PARAM_NO_MEM;
00783 else {
00784
00785 GetStr(&url->url, nextarg);
00786 url->flags |= GETOUT_URL;
00787 }
00788 }
00789 }
00790 break;
00791 case '$':
00792 switch(subletter) {
00793 case 'a':
00794 if(toggle && !(curlinfo->features & CURL_VERSION_SSL))
00795 return PARAM_LIBCURL_DOESNT_SUPPORT;
00796 config->ftp_ssl = toggle;
00797 break;
00798 case 'b':
00799 Curl_safefree(config->ftpport);
00800 break;
00801 case 'c':
00802
00803 GetStr(&config->proxy, nextarg);
00804 config->proxyver = CURLPROXY_SOCKS5;
00805 break;
00806 case 't':
00807 GetStr(&config->proxy, nextarg);
00808 config->proxyver = CURLPROXY_SOCKS4;
00809 break;
00810 case 'T':
00811 GetStr(&config->proxy, nextarg);
00812 config->proxyver = CURLPROXY_SOCKS4A;
00813 break;
00814 case '2':
00815
00816 GetStr(&config->proxy, nextarg);
00817 config->proxyver = CURLPROXY_SOCKS5_HOSTNAME;
00818 break;
00819 case 'd':
00820 config->tcp_nodelay = toggle;
00821 break;
00822 case 'e':
00823 config->proxydigest = toggle;
00824 break;
00825 case 'f':
00826 config->proxybasic = toggle;
00827 break;
00828 case 'g':
00829 err = str2unum(&config->req_retry, nextarg);
00830 if(err)
00831 return err;
00832 break;
00833 case 'V':
00834 config->retry_connrefused = toggle;
00835 break;
00836 case 'h':
00837 err = str2unum(&config->retry_delay, nextarg);
00838 if(err)
00839 return err;
00840 break;
00841 case 'i':
00842 err = str2unum(&config->retry_maxtime, nextarg);
00843 if(err)
00844 return err;
00845 break;
00846
00847 case 'k':
00848 if(curlinfo->features & CURL_VERSION_SPNEGO)
00849 config->proxynegotiate = toggle;
00850 else
00851 return PARAM_LIBCURL_DOESNT_SUPPORT;
00852 break;
00853
00854 case 'm':
00855 GetStr(&config->ftp_account, nextarg);
00856 break;
00857 case 'n':
00858 config->proxyanyauth = toggle;
00859 break;
00860 case 'o':
00861 global->tracetime = toggle;
00862 break;
00863 case 'p':
00864 config->ignorecl = toggle;
00865 break;
00866 case 'q':
00867 config->ftp_skip_ip = toggle;
00868 break;
00869 case 'r':
00870 config->ftp_filemethod = ftpfilemethod(config, nextarg);
00871 break;
00872 case 's':
00873 rc = sscanf(nextarg, "%d - %d",
00874 &config->localport,
00875 &config->localportrange);
00876 if(!rc)
00877 return PARAM_BAD_USE;
00878 else if(rc == 1)
00879 config->localportrange = 1;
00880 else {
00881 config->localportrange -= config->localport;
00882 if(config->localportrange < 1) {
00883 warnf(global, "bad range input\n");
00884 return PARAM_BAD_USE;
00885 }
00886 }
00887 break;
00888 case 'u':
00889 GetStr(&config->ftp_alternative_to_user, nextarg);
00890 break;
00891 case 'v':
00892 if(toggle && !(curlinfo->features & CURL_VERSION_SSL))
00893 return PARAM_LIBCURL_DOESNT_SUPPORT;
00894 config->ftp_ssl_reqd = toggle;
00895 break;
00896 case 'w':
00897 config->disable_sessionid = (!toggle)?TRUE:FALSE;
00898 break;
00899 case 'x':
00900 if(toggle && !(curlinfo->features & CURL_VERSION_SSL))
00901 return PARAM_LIBCURL_DOESNT_SUPPORT;
00902 config->ftp_ssl_control = toggle;
00903 break;
00904 case 'y':
00905 config->ftp_ssl_ccc = toggle;
00906 if(!config->ftp_ssl_ccc_mode)
00907 config->ftp_ssl_ccc_mode = CURLFTPSSL_CCC_PASSIVE;
00908 break;
00909 case 'j':
00910 config->ftp_ssl_ccc = TRUE;
00911 config->ftp_ssl_ccc_mode = ftpcccmethod(config, nextarg);
00912 break;
00913 case 'z':
00914 #ifdef CURL_DISABLE_LIBCURL_OPTION
00915 warnf(global,
00916 "--libcurl option was disabled at build-time!\n");
00917 return PARAM_OPTION_UNKNOWN;
00918 #else
00919 GetStr(&global->libcurl, nextarg);
00920 break;
00921 #endif
00922 case '#':
00923 config->raw = toggle;
00924 break;
00925 case '0':
00926 config->post301 = toggle;
00927 break;
00928 case '1':
00929 config->nokeepalive = (!toggle)?TRUE:FALSE;
00930 break;
00931 case '3':
00932 err = str2unum(&config->alivetime, nextarg);
00933 if(err)
00934 return err;
00935 break;
00936 case '4':
00937 config->post302 = toggle;
00938 break;
00939 case 'I':
00940 config->post303 = toggle;
00941 break;
00942 case '5':
00943
00944 GetStr(&config->noproxy, nextarg);
00945 break;
00946 case '7':
00947 config->socks5_gssapi_nec = toggle;
00948 break;
00949 case '8':
00950
00951 GetStr(&config->proxy, nextarg);
00952 config->proxyver = CURLPROXY_HTTP_1_0;
00953 break;
00954 case '9':
00955 err = str2unum(&config->tftp_blksize, nextarg);
00956 if(err)
00957 return err;
00958 break;
00959 case 'A':
00960 GetStr(&config->mail_from, nextarg);
00961 break;
00962 case 'B':
00963
00964 err = add2list(&config->mail_rcpt, nextarg);
00965 if(err)
00966 return err;
00967 break;
00968 case 'C':
00969 config->ftp_pret = toggle;
00970 break;
00971 case 'D':
00972 config->proto_present = TRUE;
00973 if(proto2num(config, &config->proto, nextarg))
00974 return PARAM_BAD_USE;
00975 break;
00976 case 'E':
00977 config->proto_redir_present = TRUE;
00978 if(proto2num(config, &config->proto_redir, nextarg))
00979 return PARAM_BAD_USE;
00980 break;
00981 case 'F':
00982 err = add2list(&config->resolve, nextarg);
00983 if(err)
00984 return err;
00985 break;
00986 case 'G':
00987 config->gssapi_delegation = delegation(config, nextarg);
00988 break;
00989 case 'H':
00990 GetStr(&config->mail_auth, nextarg);
00991 break;
00992 case 'J':
00993 {
00994 #ifdef USE_METALINK
00995 int mlmaj, mlmin, mlpatch;
00996 metalink_get_version(&mlmaj, &mlmin, &mlpatch);
00997 if((mlmaj*10000)+(mlmin*100)+mlpatch < CURL_REQ_LIBMETALINK_VERS) {
00998 warnf(global,
00999 "--metalink option cannot be used because the version of "
01000 "the linked libmetalink library is too old. "
01001 "Required: %d.%d.%d, found %d.%d.%d\n",
01002 CURL_REQ_LIBMETALINK_MAJOR,
01003 CURL_REQ_LIBMETALINK_MINOR,
01004 CURL_REQ_LIBMETALINK_PATCH,
01005 mlmaj, mlmin, mlpatch);
01006 return PARAM_BAD_USE;
01007 }
01008 else
01009 config->use_metalink = toggle;
01010 #else
01011 warnf(global, "--metalink option is ignored because the binary is "
01012 "built without the Metalink support.\n");
01013 #endif
01014 break;
01015 }
01016 case 'K':
01017 config->sasl_ir = toggle;
01018 break;
01019 case 'L':
01020 #ifdef CURLDEBUG
01021 config->test_event_based = toggle;
01022 #else
01023 warnf(global, "--test-event is ignored unless a debug build!\n");
01024 #endif
01025 break;
01026 case 'M':
01027 GetStr(&config->unix_socket_path, nextarg);
01028 break;
01029 case 'N':
01030 config->path_as_is = toggle;
01031 break;
01032 case 'O':
01033 GetStr(&config->proxy_service_name, nextarg);
01034 break;
01035 case 'P':
01036 GetStr(&config->service_name, nextarg);
01037 break;
01038 case 'Q':
01039 GetStr(&config->proto_default, nextarg);
01040 err = check_protocol(config->proto_default);
01041 if(err)
01042 return err;
01043 break;
01044 case 'R':
01045 err = str2udouble(&config->expect100timeout, nextarg);
01046 if(err)
01047 return err;
01048 break;
01049 case 'S':
01050 config->tftp_no_options = toggle;
01051 break;
01052 case 'U':
01053 err = add2list(&config->connect_to, nextarg);
01054 if(err)
01055 return err;
01056 break;
01057 }
01058 break;
01059 case '#':
01060 if(toggle)
01061 global->progressmode = CURL_PROGRESS_BAR;
01062 else
01063 global->progressmode = CURL_PROGRESS_STATS;
01064 break;
01065 case ':':
01066 return PARAM_NEXT_OPERATION;
01067 case '0':
01068 switch(subletter) {
01069 case '\0':
01070
01071 config->httpversion = CURL_HTTP_VERSION_1_0;
01072 break;
01073 case '1':
01074
01075 config->httpversion = CURL_HTTP_VERSION_1_1;
01076 break;
01077 case '2':
01078
01079 config->httpversion = CURL_HTTP_VERSION_2_0;
01080 break;
01081 case '3':
01082
01083 config->httpversion = CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE;
01084 break;
01085 }
01086 break;
01087 case '1':
01088 switch(subletter) {
01089 case '\0':
01090
01091 config->ssl_version = CURL_SSLVERSION_TLSv1;
01092 break;
01093 case '0':
01094
01095 config->ssl_version = CURL_SSLVERSION_TLSv1_0;
01096 break;
01097 case '1':
01098
01099 config->ssl_version = CURL_SSLVERSION_TLSv1_1;
01100 break;
01101 case '2':
01102
01103 config->ssl_version = CURL_SSLVERSION_TLSv1_2;
01104 break;
01105 case '3':
01106
01107 config->ssl_version = CURL_SSLVERSION_TLSv1_3;
01108 break;
01109 }
01110 break;
01111 case '2':
01112
01113 config->ssl_version = CURL_SSLVERSION_SSLv2;
01114 break;
01115 case '3':
01116
01117 config->ssl_version = CURL_SSLVERSION_SSLv3;
01118 break;
01119 case '4':
01120
01121 config->ip_version = 4;
01122 break;
01123 case '6':
01124
01125 config->ip_version = 6;
01126 break;
01127 case 'a':
01128
01129 config->ftp_append = toggle;
01130 break;
01131 case 'A':
01132
01133 GetStr(&config->useragent, nextarg);
01134 break;
01135 case 'b':
01136 if(nextarg[0] == '@') {
01137 nextarg++;
01138 }
01139 else if(strchr(nextarg, '=')) {
01140
01141 GetStr(&config->cookie, nextarg);
01142 break;
01143 }
01144
01145 GetStr(&config->cookiefile, nextarg);
01146 break;
01147 case 'B':
01148
01149 config->use_ascii = toggle;
01150 break;
01151 case 'c':
01152
01153 GetStr(&config->cookiejar, nextarg);
01154 break;
01155 case 'C':
01156
01157 if(strcmp(nextarg, "-")) {
01158 err = str2offset(&config->resume_from, nextarg);
01159 if(err)
01160 return err;
01161 config->resume_from_current = FALSE;
01162 }
01163 else {
01164 config->resume_from_current = TRUE;
01165 config->resume_from = 0;
01166 }
01167 config->use_resume=TRUE;
01168 break;
01169 case 'd':
01170
01171 {
01172 char *postdata = NULL;
01173 FILE *file;
01174 size_t size = 0;
01175 bool raw_mode = (subletter == 'r');
01176
01177 if(subletter == 'e') {
01178
01179
01180
01181
01182
01183
01184 const char *p = strchr(nextarg, '=');
01185 size_t nlen;
01186 char is_file;
01187 if(!p)
01188
01189 p = strchr(nextarg, '@');
01190 if(p) {
01191 nlen = p - nextarg;
01192 is_file = *p++;
01193 }
01194 else {
01195
01196 nlen = is_file = 0;
01197 p = nextarg;
01198 }
01199 if('@' == is_file) {
01200
01201 if(!strcmp("-", p)) {
01202 file = stdin;
01203 set_binmode(stdin);
01204 }
01205 else {
01206 file = fopen(p, "rb");
01207 if(!file)
01208 warnf(global,
01209 "Couldn't read data from file \"%s\", this makes "
01210 "an empty POST.\n", nextarg);
01211 }
01212
01213 err = file2memory(&postdata, &size, file);
01214
01215 if(file && (file != stdin))
01216 fclose(file);
01217 if(err)
01218 return err;
01219 }
01220 else {
01221 GetStr(&postdata, p);
01222 if(postdata)
01223 size = strlen(postdata);
01224 }
01225
01226 if(!postdata) {
01227
01228
01229 postdata = strdup("");
01230 if(!postdata)
01231 return PARAM_NO_MEM;
01232 size = 0;
01233 }
01234 else {
01235 char *enc = curl_easy_escape(config->easy, postdata, (int)size);
01236 Curl_safefree(postdata);
01237 if(enc) {
01238
01239
01240 size_t outlen = nlen + strlen(enc) + 2;
01241 char *n = malloc(outlen);
01242 if(!n) {
01243 curl_free(enc);
01244 return PARAM_NO_MEM;
01245 }
01246 if(nlen > 0) {
01247 snprintf(n, outlen, "%.*s=%s", nlen, nextarg, enc);
01248 size = outlen-1;
01249 }
01250 else {
01251 strcpy(n, enc);
01252 size = outlen-2;
01253 }
01254 curl_free(enc);
01255 postdata = n;
01256 }
01257 else
01258 return PARAM_NO_MEM;
01259 }
01260 }
01261 else if('@' == *nextarg && !raw_mode) {
01262
01263
01264 nextarg++;
01265
01266 if(!strcmp("-", nextarg)) {
01267 file = stdin;
01268 if(subletter == 'b')
01269 set_binmode(stdin);
01270 }
01271 else {
01272 file = fopen(nextarg, "rb");
01273 if(!file)
01274 warnf(global, "Couldn't read data from file \"%s\", this makes "
01275 "an empty POST.\n", nextarg);
01276 }
01277
01278 if(subletter == 'b')
01279
01280 err = file2memory(&postdata, &size, file);
01281 else {
01282 err = file2string(&postdata, file);
01283 if(postdata)
01284 size = strlen(postdata);
01285 }
01286
01287 if(file && (file != stdin))
01288 fclose(file);
01289 if(err)
01290 return err;
01291
01292 if(!postdata) {
01293
01294
01295 postdata = strdup("");
01296 if(!postdata)
01297 return PARAM_NO_MEM;
01298 }
01299 }
01300 else {
01301 GetStr(&postdata, nextarg);
01302 if(postdata)
01303 size = strlen(postdata);
01304 }
01305
01306 #ifdef CURL_DOES_CONVERSIONS
01307 if(subletter != 'b') {
01308
01309 if(convert_to_network(postdata, strlen(postdata))) {
01310 Curl_safefree(postdata);
01311 return PARAM_NO_MEM;
01312 }
01313 }
01314 #endif
01315
01316 if(config->postfields) {
01317
01318
01319 char *oldpost = config->postfields;
01320 curl_off_t oldlen = config->postfieldsize;
01321 curl_off_t newlen = oldlen + curlx_uztoso(size) + 2;
01322 config->postfields = malloc((size_t)newlen);
01323 if(!config->postfields) {
01324 Curl_safefree(oldpost);
01325 Curl_safefree(postdata);
01326 return PARAM_NO_MEM;
01327 }
01328 memcpy(config->postfields, oldpost, (size_t)oldlen);
01329
01330 config->postfields[oldlen] = '\x26';
01331 memcpy(&config->postfields[oldlen+1], postdata, size);
01332 config->postfields[oldlen+1+size] = '\0';
01333 Curl_safefree(oldpost);
01334 Curl_safefree(postdata);
01335 config->postfieldsize += size+1;
01336 }
01337 else {
01338 config->postfields = postdata;
01339 config->postfieldsize = curlx_uztoso(size);
01340 }
01341 }
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351 break;
01352 case 'D':
01353
01354 GetStr(&config->headerfile, nextarg);
01355 break;
01356 case 'e':
01357 {
01358 char *ptr = strstr(nextarg, ";auto");
01359 if(ptr) {
01360
01361
01362 config->autoreferer = TRUE;
01363 *ptr = 0;
01364 }
01365 else
01366 config->autoreferer = FALSE;
01367 GetStr(&config->referer, nextarg);
01368 }
01369 break;
01370 case 'E':
01371 switch(subletter) {
01372 case '\0':
01373 GetFileAndPassword(nextarg, &config->cert, &config->key_passwd);
01374 break;
01375 case 'a':
01376
01377 GetStr(&config->cacert, nextarg);
01378 break;
01379 case 'b':
01380 GetStr(&config->cert_type, nextarg);
01381 break;
01382 case 'c':
01383 GetStr(&config->key, nextarg);
01384 break;
01385 case 'd':
01386 GetStr(&config->key_type, nextarg);
01387 break;
01388 case 'e':
01389 GetStr(&config->key_passwd, nextarg);
01390 cleanarg(nextarg);
01391 break;
01392 case 'f':
01393 GetStr(&config->engine, nextarg);
01394 if(config->engine && curl_strequal(config->engine, "list"))
01395 return PARAM_ENGINES_REQUESTED;
01396 break;
01397 case 'g':
01398
01399 GetStr(&config->capath, nextarg);
01400 break;
01401 case 'h':
01402 GetStr(&config->pubkey, nextarg);
01403 break;
01404 case 'i':
01405 GetStr(&config->hostpubmd5, nextarg);
01406 if(!config->hostpubmd5 || strlen(config->hostpubmd5) != 32)
01407 return PARAM_BAD_USE;
01408 break;
01409 case 'j':
01410
01411 GetStr(&config->crlfile, nextarg);
01412 break;
01413 case 'k':
01414 if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP)
01415 GetStr(&config->tls_username, nextarg);
01416 else
01417 return PARAM_LIBCURL_DOESNT_SUPPORT;
01418 break;
01419 case 'l':
01420 if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP)
01421 GetStr(&config->tls_password, nextarg);
01422 else
01423 return PARAM_LIBCURL_DOESNT_SUPPORT;
01424 break;
01425 case 'm':
01426 if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP) {
01427 GetStr(&config->tls_authtype, nextarg);
01428 if(!curl_strequal(config->tls_authtype, "SRP"))
01429 return PARAM_LIBCURL_DOESNT_SUPPORT;
01430 }
01431 else
01432 return PARAM_LIBCURL_DOESNT_SUPPORT;
01433 break;
01434 case 'n':
01435 if(curlinfo->features & CURL_VERSION_SSL)
01436 config->ssl_allow_beast = toggle;
01437 break;
01438
01439 case 'o':
01440 GetStr(&config->login_options, nextarg);
01441 break;
01442
01443 case 'p':
01444
01445 GetStr(&config->pinnedpubkey, nextarg);
01446 break;
01447
01448 case 'q':
01449 config->verifystatus = TRUE;
01450 break;
01451
01452 case 'r':
01453 config->falsestart = TRUE;
01454 break;
01455
01456 case 's':
01457 if(curlinfo->features & CURL_VERSION_SSL)
01458 config->ssl_no_revoke = TRUE;
01459 break;
01460
01461 case 't':
01462 config->tcp_fastopen = TRUE;
01463 break;
01464
01465 case 'u':
01466 if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP)
01467 GetStr(&config->proxy_tls_username, nextarg);
01468 else
01469 return PARAM_LIBCURL_DOESNT_SUPPORT;
01470 break;
01471
01472 case 'v':
01473 if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP)
01474 GetStr(&config->proxy_tls_password, nextarg);
01475 else
01476 return PARAM_LIBCURL_DOESNT_SUPPORT;
01477 break;
01478
01479 case 'w':
01480 if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP) {
01481 GetStr(&config->proxy_tls_authtype, nextarg);
01482 if(!curl_strequal(config->proxy_tls_authtype, "SRP"))
01483 return PARAM_LIBCURL_DOESNT_SUPPORT;
01484 }
01485 else
01486 return PARAM_LIBCURL_DOESNT_SUPPORT;
01487 break;
01488
01489 case 'x':
01490 GetFileAndPassword(nextarg, &config->proxy_cert,
01491 &config->proxy_key_passwd);
01492 break;
01493
01494 case 'y':
01495 GetStr(&config->proxy_cert_type, nextarg);
01496 break;
01497
01498 case 'z':
01499 GetStr(&config->proxy_key, nextarg);
01500 break;
01501
01502 case '0':
01503 GetStr(&config->proxy_key_type, nextarg);
01504 break;
01505
01506 case '1':
01507 GetStr(&config->proxy_key_passwd, nextarg);
01508 cleanarg(nextarg);
01509 break;
01510
01511 case '2':
01512 GetStr(&config->proxy_cipher_list, nextarg);
01513 break;
01514
01515 case '3':
01516
01517 GetStr(&config->proxy_crlfile, nextarg);
01518 break;
01519
01520 case '4':
01521 if(curlinfo->features & CURL_VERSION_SSL)
01522 config->proxy_ssl_allow_beast = toggle;
01523 break;
01524
01525 case '5':
01526 GetStr(&config->login_options, nextarg);
01527 break;
01528
01529 case '6':
01530
01531 GetStr(&config->proxy_cacert, nextarg);
01532 break;
01533
01534 case '7':
01535
01536 GetStr(&config->proxy_capath, nextarg);
01537 break;
01538
01539 case '8':
01540 config->proxy_insecure_ok = toggle;
01541 break;
01542
01543 case '9':
01544
01545 config->proxy_ssl_version = CURL_SSLVERSION_TLSv1;
01546 break;
01547
01548 default:
01549 return PARAM_OPTION_UNKNOWN;
01550 }
01551 break;
01552 case 'f':
01553 switch(subletter) {
01554 case 'a':
01555 global->fail_early = toggle;
01556 break;
01557 default:
01558
01559 config->failonerror = toggle;
01560 }
01561 break;
01562 case 'F':
01563
01564
01565 if(formparse(config,
01566 nextarg,
01567 &config->httppost,
01568 &config->last_post,
01569 (subletter=='s')?TRUE:FALSE))
01570 return PARAM_BAD_USE;
01571 if(SetHTTPrequest(config, HTTPREQ_FORMPOST, &config->httpreq))
01572 return PARAM_BAD_USE;
01573 break;
01574
01575 case 'g':
01576 config->globoff = toggle;
01577 break;
01578
01579 case 'G':
01580 config->use_httpget = TRUE;
01581 break;
01582
01583 case 'h':
01584 if(toggle) {
01585 return PARAM_HELP_REQUESTED;
01586 }
01587
01588 break;
01589 case 'H':
01590
01591 if(subletter == 'p')
01592 err = add2list(&config->proxyheaders, nextarg);
01593 else
01594 err = add2list(&config->headers, nextarg);
01595 if(err)
01596 return err;
01597 break;
01598 case 'i':
01599 config->include_headers = toggle;
01600
01601 break;
01602 case 'j':
01603 config->cookiesession = toggle;
01604 break;
01605 case 'I':
01606
01607
01608
01609 config->no_body = toggle;
01610 if(SetHTTPrequest(config,
01611 (config->no_body)?HTTPREQ_HEAD:HTTPREQ_GET,
01612 &config->httpreq))
01613 return PARAM_BAD_USE;
01614 break;
01615 case 'J':
01616 if(config->include_headers) {
01617 warnf(global,
01618 "--include and --remote-header-name cannot be combined.\n");
01619 return PARAM_BAD_USE;
01620 }
01621 config->content_disposition = toggle;
01622 break;
01623 case 'k':
01624 config->insecure_ok = toggle;
01625 break;
01626 case 'K':
01627 if(parseconfig(nextarg, global))
01628 warnf(global, "error trying read config from the '%s' file\n",
01629 nextarg);
01630 break;
01631 case 'l':
01632 config->dirlistonly = toggle;
01633 break;
01634 case 'L':
01635 config->followlocation = toggle;
01636 switch(subletter) {
01637 case 't':
01638
01639
01640 config->unrestricted_auth = toggle;
01641 break;
01642 }
01643 break;
01644 case 'm':
01645
01646 err = str2udouble(&config->timeout, nextarg);
01647 if(err)
01648 return err;
01649 break;
01650 case 'M':
01651 if(toggle) {
01652 #ifdef USE_MANUAL
01653 return PARAM_MANUAL_REQUESTED;
01654 #else
01655 warnf(global,
01656 "built-in manual was disabled at build-time!\n");
01657 return PARAM_OPTION_UNKNOWN;
01658 #endif
01659 }
01660 break;
01661 case 'n':
01662 switch(subletter) {
01663 case 'o':
01664
01665 config->netrc_opt = toggle;
01666 break;
01667 case 'e':
01668 GetStr(&config->netrc_file, nextarg);
01669 break;
01670 default:
01671
01672
01673 config->netrc = toggle;
01674 break;
01675 }
01676 break;
01677 case 'N':
01678
01679
01680 if(longopt)
01681 config->nobuffer = (!toggle)?TRUE:FALSE;
01682 else
01683 config->nobuffer = toggle;
01684 break;
01685 case 'O':
01686 if(subletter == 'a') {
01687 config->default_node_flags = toggle?GETOUT_USEREMOTE:0;
01688 break;
01689 }
01690
01691 case 'o':
01692
01693 {
01694 struct getout *url;
01695 if(!config->url_out)
01696 config->url_out = config->url_list;
01697 if(config->url_out) {
01698
01699
01700 while(config->url_out && (config->url_out->flags & GETOUT_OUTFILE))
01701 config->url_out = config->url_out->next;
01702 }
01703
01704
01705
01706 if(config->url_out)
01707
01708 url = config->url_out;
01709 else
01710
01711 url = new_getout(config);
01712
01713 if(!url)
01714 return PARAM_NO_MEM;
01715 else {
01716
01717 if('o' == letter) {
01718 GetStr(&url->outfile, nextarg);
01719 url->flags &= ~GETOUT_USEREMOTE;
01720 }
01721 else {
01722 url->outfile = NULL;
01723 if(toggle)
01724 url->flags |= GETOUT_USEREMOTE;
01725 else
01726 url->flags &= ~GETOUT_USEREMOTE;
01727 }
01728 url->flags |= GETOUT_OUTFILE;
01729 }
01730 }
01731 break;
01732 case 'P':
01733
01734
01735
01736
01737
01738 GetStr(&config->ftpport, nextarg);
01739 break;
01740 case 'p':
01741
01742 config->proxytunnel = toggle;
01743 break;
01744
01745 case 'q':
01746
01747 break;
01748 case 'Q':
01749
01750 switch(nextarg[0]) {
01751 case '-':
01752
01753 nextarg++;
01754 err = add2list(&config->postquote, nextarg);
01755 break;
01756 case '+':
01757
01758 nextarg++;
01759 err = add2list(&config->prequote, nextarg);
01760 break;
01761 default:
01762 err = add2list(&config->quote, nextarg);
01763 break;
01764 }
01765 if(err)
01766 return err;
01767 break;
01768 case 'r':
01769
01770
01771
01772
01773 if(ISDIGIT(*nextarg) && !strchr(nextarg, '-')) {
01774 char buffer[32];
01775 curl_off_t off;
01776 warnf(global,
01777 "A specified range MUST include at least one dash (-). "
01778 "Appending one for you!\n");
01779 off = curlx_strtoofft(nextarg, NULL, 10);
01780 snprintf(buffer, sizeof(buffer), "%" CURL_FORMAT_CURL_OFF_T "-", off);
01781 Curl_safefree(config->range);
01782 config->range = strdup(buffer);
01783 if(!config->range)
01784 return PARAM_NO_MEM;
01785 }
01786 {
01787
01788 char *tmp_range;
01789 tmp_range = nextarg;
01790 while(*tmp_range != '\0') {
01791 if(!ISDIGIT(*tmp_range) && *tmp_range != '-' && *tmp_range != ',') {
01792 warnf(global, "Invalid character is found in given range. "
01793 "A specified range MUST have only digits in "
01794 "\'start\'-\'stop\'. The server's response to this "
01795 "request is uncertain.\n");
01796 break;
01797 }
01798 tmp_range++;
01799 }
01800
01801 GetStr(&config->range, nextarg);
01802 }
01803 break;
01804 case 'R':
01805
01806 config->remote_time = toggle;
01807 break;
01808 case 's':
01809
01810 if(toggle)
01811 global->mute = global->noprogress = TRUE;
01812 else
01813 global->mute = global->noprogress = FALSE;
01814 if(global->showerror < 0)
01815
01816
01817
01818 global->showerror = (!toggle)?TRUE:FALSE;
01819 break;
01820 case 'S':
01821
01822 global->showerror = toggle?1:0;
01823 break;
01824 case 't':
01825
01826 err = add2list(&config->telnet_options, nextarg);
01827 if(err)
01828 return err;
01829 break;
01830 case 'T':
01831
01832 {
01833 struct getout *url;
01834 if(!config->url_out)
01835 config->url_out = config->url_list;
01836 if(config->url_out) {
01837
01838
01839 while(config->url_out && (config->url_out->flags & GETOUT_UPLOAD))
01840 config->url_out = config->url_out->next;
01841 }
01842
01843
01844
01845 if(config->url_out)
01846
01847 url = config->url_out;
01848 else
01849
01850 url = new_getout(config);
01851
01852 if(!url)
01853 return PARAM_NO_MEM;
01854 else {
01855 url->flags |= GETOUT_UPLOAD;
01856 if(!*nextarg)
01857 url->flags |= GETOUT_NOUPLOAD;
01858 else {
01859
01860 GetStr(&url->infile, nextarg);
01861 }
01862 }
01863 }
01864 break;
01865 case 'u':
01866
01867 GetStr(&config->userpwd, nextarg);
01868 cleanarg(nextarg);
01869 break;
01870 case 'U':
01871
01872 GetStr(&config->proxyuserpwd, nextarg);
01873 cleanarg(nextarg);
01874 break;
01875 case 'v':
01876 if(toggle) {
01877
01878 Curl_safefree(global->trace_dump);
01879 global->trace_dump = strdup("%");
01880 if(!global->trace_dump)
01881 return PARAM_NO_MEM;
01882 if(global->tracetype && (global->tracetype != TRACE_PLAIN))
01883 warnf(global,
01884 "-v, --verbose overrides an earlier trace/verbose option\n");
01885 global->tracetype = TRACE_PLAIN;
01886 }
01887 else
01888
01889 global->tracetype = TRACE_NONE;
01890 break;
01891 case 'V':
01892 if(toggle)
01893 return PARAM_VERSION_INFO_REQUESTED;
01894 break;
01895
01896 case 'w':
01897
01898 if('@' == *nextarg) {
01899
01900
01901 FILE *file;
01902 const char *fname;
01903 nextarg++;
01904 if(!strcmp("-", nextarg)) {
01905 fname = "<stdin>";
01906 file = stdin;
01907 }
01908 else {
01909 fname = nextarg;
01910 file = fopen(nextarg, FOPEN_READTEXT);
01911 }
01912 err = file2string(&config->writeout, file);
01913 if(file && (file != stdin))
01914 fclose(file);
01915 if(err)
01916 return err;
01917 if(!config->writeout)
01918 warnf(global, "Failed to read %s", fname);
01919 }
01920 else
01921 GetStr(&config->writeout, nextarg);
01922 break;
01923 case 'x':
01924 switch(subletter) {
01925 case 'a':
01926 GetStr(&config->preproxy, nextarg);
01927 break;
01928 default:
01929
01930 GetStr(&config->proxy, nextarg);
01931 config->proxyver = CURLPROXY_HTTP;
01932 break;
01933 }
01934 break;
01935 case 'X':
01936
01937 GetStr(&config->customrequest, nextarg);
01938 break;
01939 case 'y':
01940
01941 err = str2unum(&config->low_speed_time, nextarg);
01942 if(err)
01943 return err;
01944 if(!config->low_speed_limit)
01945 config->low_speed_limit = 1;
01946 break;
01947 case 'Y':
01948
01949 err = str2unum(&config->low_speed_limit, nextarg);
01950 if(err)
01951 return err;
01952 if(!config->low_speed_time)
01953 config->low_speed_time = 30;
01954 break;
01955 case 'z':
01956 switch(*nextarg) {
01957 case '+':
01958 nextarg++;
01959
01960 default:
01961
01962 config->timecond = CURL_TIMECOND_IFMODSINCE;
01963 break;
01964 case '-':
01965
01966 config->timecond = CURL_TIMECOND_IFUNMODSINCE;
01967 nextarg++;
01968 break;
01969 case '=':
01970
01971 config->timecond = CURL_TIMECOND_LASTMOD;
01972 nextarg++;
01973 break;
01974 }
01975 now = time(NULL);
01976 config->condtime=curl_getdate(nextarg, &now);
01977 if(-1 == (int)config->condtime) {
01978
01979 struct_stat statbuf;
01980 if(-1 == stat(nextarg, &statbuf)) {
01981
01982 config->timecond = CURL_TIMECOND_NONE;
01983 warnf(global,
01984 "Illegal date format for -z, --timecond (and not "
01985 "a file name). Disabling time condition. "
01986 "See curl_getdate(3) for valid date syntax.\n");
01987 }
01988 else {
01989
01990 config->condtime = statbuf.st_mtime;
01991 }
01992 }
01993 break;
01994 default:
01995 return PARAM_OPTION_UNKNOWN;
01996 }
01997 hit = -1;
01998
01999 } while(!longopt && !singleopt && *++parse && !*usedarg);
02000
02001 return PARAM_OK;
02002 }
02003
02004 ParameterError parse_args(struct GlobalConfig *config, int argc,
02005 argv_item_t argv[])
02006 {
02007 int i;
02008 bool stillflags;
02009 char *orig_opt = NULL;
02010 ParameterError result = PARAM_OK;
02011 struct OperationConfig *operation = config->first;
02012
02013 for(i = 1, stillflags = TRUE; i < argc && !result; i++) {
02014 orig_opt = argv[i];
02015
02016 if(stillflags && ('-' == argv[i][0])) {
02017 char *nextarg;
02018 bool passarg;
02019 char *flag = argv[i];
02020
02021 if(!strcmp("--", argv[i]))
02022
02023
02024 stillflags = FALSE;
02025 else {
02026 nextarg = (i < (argc - 1)) ? argv[i + 1] : NULL;
02027
02028 result = getparameter(flag, nextarg, &passarg, config, operation);
02029 if(result == PARAM_NEXT_OPERATION) {
02030
02031
02032 result = PARAM_OK;
02033
02034 if(operation->url_list && operation->url_list->url) {
02035
02036 operation->next = malloc(sizeof(struct OperationConfig));
02037 if(operation->next) {
02038
02039 config_init(operation->next);
02040
02041
02042 operation->next->easy = config->easy;
02043
02044
02045 operation->next->global = config;
02046
02047
02048 config->last = operation->next;
02049
02050
02051 operation->next->prev = operation;
02052 operation = operation->next;
02053 }
02054 else
02055 result = PARAM_NO_MEM;
02056 }
02057 }
02058 else if(!result && passarg)
02059 i++;
02060 }
02061 }
02062 else {
02063 bool used;
02064
02065
02066 result = getparameter((char *)"--url", argv[i], &used, config,
02067 operation);
02068 }
02069 }
02070
02071 if(result && result != PARAM_HELP_REQUESTED &&
02072 result != PARAM_MANUAL_REQUESTED &&
02073 result != PARAM_VERSION_INFO_REQUESTED &&
02074 result != PARAM_ENGINES_REQUESTED) {
02075 const char *reason = param2text(result);
02076
02077 if(orig_opt && strcmp(":", orig_opt))
02078 helpf(config->errors, "option %s: %s\n", orig_opt, reason);
02079 else
02080 helpf(config->errors, "%s\n", reason);
02081 }
02082
02083 return result;
02084 }