1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.haxx.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ***************************************************************************/
22 #include "tool_setup.h"
23
24 #include "tool_panykey.h"
25 #include "tool_help.h"
26 #include "tool_libinfo.h"
27 #include "tool_version.h"
28
29 #include "memdebug.h" /* keep this as LAST include */
30
31 #ifdef MSDOS
32 # define USE_WATT32
33 #endif
34
35 /*
36 * The help output is generated with the following command
37 ---------------------------------------------------------
38
39 cd $srcroot/docs/cmdline-opts
40 ./gen.pl listhelp
41 */
42
43 struct helptxt {
44 const char *opt;
45 const char *desc;
46 };
47
48 static const struct helptxt helptext[] = {
49 {" --abstract-unix-socket <path>",
50 "Connect via abstract Unix domain socket"},
51 {" --alt-svc <file name>",
52 "Enable alt-svc with this cache file"},
53 {" --anyauth",
54 "Pick any authentication method"},
55 {"-a, --append",
56 "Append to target file when uploading"},
57 {" --basic",
58 "Use HTTP Basic Authentication"},
59 {" --cacert <file>",
60 "CA certificate to verify peer against"},
61 {" --capath <dir>",
62 "CA directory to verify peer against"},
63 {"-E, --cert <certificate[:password]>",
64 "Client certificate file and password"},
65 {" --cert-status",
66 "Verify the status of the server certificate"},
67 {" --cert-type <type>",
68 "Certificate file type (DER/PEM/ENG)"},
69 {" --ciphers <list of ciphers>",
70 "SSL ciphers to use"},
71 {" --compressed",
72 "Request compressed response"},
73 {" --compressed-ssh",
74 "Enable SSH compression"},
75 {"-K, --config <file>",
76 "Read config from a file"},
77 {" --connect-timeout <seconds>",
78 "Maximum time allowed for connection"},
79 {" --connect-to <HOST1:PORT1:HOST2:PORT2>",
80 "Connect to host"},
81 {"-C, --continue-at <offset>",
82 "Resumed transfer offset"},
83 {"-b, --cookie <data|filename>",
84 "Send cookies from string/file"},
85 {"-c, --cookie-jar <filename>",
86 "Write cookies to <filename> after operation"},
87 {" --create-dirs",
88 "Create necessary local directory hierarchy"},
89 {" --crlf",
90 "Convert LF to CRLF in upload"},
91 {" --crlfile <file>",
92 "Get a CRL list in PEM format from the given file"},
93 {"-d, --data <data>",
94 "HTTP POST data"},
95 {" --data-ascii <data>",
96 "HTTP POST ASCII data"},
97 {" --data-binary <data>",
98 "HTTP POST binary data"},
99 {" --data-raw <data>",
100 "HTTP POST data, '@' allowed"},
101 {" --data-urlencode <data>",
102 "HTTP POST data url encoded"},
103 {" --delegation <LEVEL>",
104 "GSS-API delegation permission"},
105 {" --digest",
106 "Use HTTP Digest Authentication"},
107 {"-q, --disable",
108 "Disable .curlrc"},
109 {" --disable-eprt",
110 "Inhibit using EPRT or LPRT"},
111 {" --disable-epsv",
112 "Inhibit using EPSV"},
113 {" --disallow-username-in-url",
114 "Disallow username in url"},
115 {" --dns-interface <interface>",
116 "Interface to use for DNS requests"},
117 {" --dns-ipv4-addr <address>",
118 "IPv4 address to use for DNS requests"},
119 {" --dns-ipv6-addr <address>",
120 "IPv6 address to use for DNS requests"},
121 {" --dns-servers <addresses>",
122 "DNS server addrs to use"},
123 {" --doh-url <URL>",
124 "Resolve host names over DOH"},
125 {"-D, --dump-header <filename>",
126 "Write the received headers to <filename>"},
127 {" --egd-file <file>",
128 "EGD socket path for random data"},
129 {" --engine <name>",
130 "Crypto engine to use"},
131 {" --expect100-timeout <seconds>",
132 "How long to wait for 100-continue"},
133 {"-f, --fail",
134 "Fail silently (no output at all) on HTTP errors"},
135 {" --fail-early",
136 "Fail on first transfer error, do not continue"},
137 {" --false-start",
138 "Enable TLS False Start"},
139 {"-F, --form <name=content>",
140 "Specify multipart MIME data"},
141 {" --form-string <name=string>",
142 "Specify multipart MIME data"},
143 {" --ftp-account <data>",
144 "Account data string"},
145 {" --ftp-alternative-to-user <command>",
146 "String to replace USER [name]"},
147 {" --ftp-create-dirs",
148 "Create the remote dirs if not present"},
149 {" --ftp-method <method>",
150 "Control CWD usage"},
151 {" --ftp-pasv",
152 "Use PASV/EPSV instead of PORT"},
153 {"-P, --ftp-port <address>",
154 "Use PORT instead of PASV"},
155 {" --ftp-pret",
156 "Send PRET before PASV"},
157 {" --ftp-skip-pasv-ip",
158 "Skip the IP address for PASV"},
159 {" --ftp-ssl-ccc",
160 "Send CCC after authenticating"},
161 {" --ftp-ssl-ccc-mode <active/passive>",
162 "Set CCC mode"},
163 {" --ftp-ssl-control",
164 "Require SSL/TLS for FTP login, clear for transfer"},
165 {"-G, --get",
166 "Put the post data in the URL and use GET"},
167 {"-g, --globoff",
168 "Disable URL sequences and ranges using {} and []"},
169 {" --happy-eyeballs-timeout-ms <milliseconds>",
170 "How long to wait in milliseconds for IPv6 before trying IPv4"},
171 {" --haproxy-protocol",
172 "Send HAProxy PROXY protocol v1 header"},
173 {"-I, --head",
174 "Show document info only"},
175 {"-H, --header <header/@file>",
176 "Pass custom header(s) to server"},
177 {"-h, --help",
178 "This help text"},
179 {" --hostpubmd5 <md5>",
180 "Acceptable MD5 hash of the host public key"},
181 {" --http0.9",
182 "Allow HTTP 0.9 responses"},
183 {"-0, --http1.0",
184 "Use HTTP 1.0"},
185 {" --http1.1",
186 "Use HTTP 1.1"},
187 {" --http2",
188 "Use HTTP 2"},
189 {" --http2-prior-knowledge",
190 "Use HTTP 2 without HTTP/1.1 Upgrade"},
191 {" --ignore-content-length",
192 "Ignore the size of the remote resource"},
193 {"-i, --include",
194 "Include protocol response headers in the output"},
195 {"-k, --insecure",
196 "Allow insecure server connections when using SSL"},
197 {" --interface <name>",
198 "Use network INTERFACE (or address)"},
199 {"-4, --ipv4",
200 "Resolve names to IPv4 addresses"},
201 {"-6, --ipv6",
202 "Resolve names to IPv6 addresses"},
203 {"-j, --junk-session-cookies",
204 "Ignore session cookies read from file"},
205 {" --keepalive-time <seconds>",
206 "Interval time for keepalive probes"},
207 {" --key <key>",
208 "Private key file name"},
209 {" --key-type <type>",
210 "Private key file type (DER/PEM/ENG)"},
211 {" --krb <level>",
212 "Enable Kerberos with security <level>"},
213 {" --libcurl <file>",
214 "Dump libcurl equivalent code of this command line"},
215 {" --limit-rate <speed>",
216 "Limit transfer speed to RATE"},
217 {"-l, --list-only",
218 "List only mode"},
219 {" --local-port <num/range>",
220 "Force use of RANGE for local port numbers"},
221 {"-L, --location",
222 "Follow redirects"},
223 {" --location-trusted",
224 "Like --location, and send auth to other hosts"},
225 {" --login-options <options>",
226 "Server login options"},
227 {" --mail-auth <address>",
228 "Originator address of the original email"},
229 {" --mail-from <address>",
230 "Mail from this address"},
231 {" --mail-rcpt <address>",
232 "Mail to this address"},
233 {"-M, --manual",
234 "Display the full manual"},
235 {" --max-filesize <bytes>",
236 "Maximum file size to download"},
237 {" --max-redirs <num>",
238 "Maximum number of redirects allowed"},
239 {"-m, --max-time <seconds>",
240 "Maximum time allowed for the transfer"},
241 {" --metalink",
242 "Process given URLs as metalink XML file"},
243 {" --negotiate",
244 "Use HTTP Negotiate (SPNEGO) authentication"},
245 {"-n, --netrc",
246 "Must read .netrc for user name and password"},
247 {" --netrc-file <filename>",
248 "Specify FILE for netrc"},
249 {" --netrc-optional",
250 "Use either .netrc or URL"},
251 {"-:, --next",
252 "Make next URL use its separate set of options"},
253 {" --no-alpn",
254 "Disable the ALPN TLS extension"},
255 {"-N, --no-buffer",
256 "Disable buffering of the output stream"},
257 {" --no-keepalive",
258 "Disable TCP keepalive on the connection"},
259 {" --no-npn",
260 "Disable the NPN TLS extension"},
261 {" --no-sessionid",
262 "Disable SSL session-ID reusing"},
263 {" --noproxy <no-proxy-list>",
264 "List of hosts which do not use proxy"},
265 {" --ntlm",
266 "Use HTTP NTLM authentication"},
267 {" --ntlm-wb",
268 "Use HTTP NTLM authentication with winbind"},
269 {" --oauth2-bearer <token>",
270 "OAuth 2 Bearer Token"},
271 {"-o, --output <file>",
272 "Write to file instead of stdout"},
273 {" --pass <phrase>",
274 "Pass phrase for the private key"},
275 {" --path-as-is",
276 "Do not squash .. sequences in URL path"},
277 {" --pinnedpubkey <hashes>",
278 "FILE/HASHES Public key to verify peer against"},
279 {" --post301",
280 "Do not switch to GET after following a 301"},
281 {" --post302",
282 "Do not switch to GET after following a 302"},
283 {" --post303",
284 "Do not switch to GET after following a 303"},
285 {" --preproxy [protocol://]host[:port]",
286 "Use this proxy first"},
287 {"-#, --progress-bar",
288 "Display transfer progress as a bar"},
289 {" --proto <protocols>",
290 "Enable/disable PROTOCOLS"},
291 {" --proto-default <protocol>",
292 "Use PROTOCOL for any URL missing a scheme"},
293 {" --proto-redir <protocols>",
294 "Enable/disable PROTOCOLS on redirect"},
295 {"-x, --proxy [protocol://]host[:port]",
296 "Use this proxy"},
297 {" --proxy-anyauth",
298 "Pick any proxy authentication method"},
299 {" --proxy-basic",
300 "Use Basic authentication on the proxy"},
301 {" --proxy-cacert <file>",
302 "CA certificate to verify peer against for proxy"},
303 {" --proxy-capath <dir>",
304 "CA directory to verify peer against for proxy"},
305 {" --proxy-cert <cert[:passwd]>",
306 "Set client certificate for proxy"},
307 {" --proxy-cert-type <type>",
308 "Client certificate type for HTTPS proxy"},
309 {" --proxy-ciphers <list>",
310 "SSL ciphers to use for proxy"},
311 {" --proxy-crlfile <file>",
312 "Set a CRL list for proxy"},
313 {" --proxy-digest",
314 "Use Digest authentication on the proxy"},
315 {" --proxy-header <header/@file>",
316 "Pass custom header(s) to proxy"},
317 {" --proxy-insecure",
318 "Do HTTPS proxy connections without verifying the proxy"},
319 {" --proxy-key <key>",
320 "Private key for HTTPS proxy"},
321 {" --proxy-key-type <type>",
322 "Private key file type for proxy"},
323 {" --proxy-negotiate",
324 "Use HTTP Negotiate (SPNEGO) authentication on the proxy"},
325 {" --proxy-ntlm",
326 "Use NTLM authentication on the proxy"},
327 {" --proxy-pass <phrase>",
328 "Pass phrase for the private key for HTTPS proxy"},
329 {" --proxy-pinnedpubkey <hashes>",
330 "FILE/HASHES public key to verify proxy with"},
331 {" --proxy-service-name <name>",
332 "SPNEGO proxy service name"},
333 {" --proxy-ssl-allow-beast",
334 "Allow security flaw for interop for HTTPS proxy"},
335 {" --proxy-tls13-ciphers <ciphersuite list>",
336 "TLS 1.3 proxy cipher suites"},
337 {" --proxy-tlsauthtype <type>",
338 "TLS authentication type for HTTPS proxy"},
339 {" --proxy-tlspassword <string>",
340 "TLS password for HTTPS proxy"},
341 {" --proxy-tlsuser <name>",
342 "TLS username for HTTPS proxy"},
343 {" --proxy-tlsv1",
344 "Use TLSv1 for HTTPS proxy"},
345 {"-U, --proxy-user <user:password>",
346 "Proxy user and password"},
347 {" --proxy1.0 <host[:port]>",
348 "Use HTTP/1.0 proxy on given port"},
349 {"-p, --proxytunnel",
350 "Operate through an HTTP proxy tunnel (using CONNECT)"},
351 {" --pubkey <key>",
352 "SSH Public key file name"},
353 {"-Q, --quote",
354 "Send command(s) to server before transfer"},
355 {" --random-file <file>",
356 "File for reading random data from"},
357 {"-r, --range <range>",
358 "Retrieve only the bytes within RANGE"},
359 {" --raw",
360 "Do HTTP \"raw\"; no transfer decoding"},
361 {"-e, --referer <URL>",
362 "Referrer URL"},
363 {"-J, --remote-header-name",
364 "Use the header-provided filename"},
365 {"-O, --remote-name",
366 "Write output to a file named as the remote file"},
367 {" --remote-name-all",
368 "Use the remote file name for all URLs"},
369 {"-R, --remote-time",
370 "Set the remote file's time on the local output"},
371 {"-X, --request <command>",
372 "Specify request command to use"},
373 {" --request-target",
374 "Specify the target for this request"},
375 {" --resolve <host:port:address[,address]...>",
376 "Resolve the host+port to this address"},
377 {" --retry <num>",
378 "Retry request if transient problems occur"},
379 {" --retry-connrefused",
380 "Retry on connection refused (use with --retry)"},
381 {" --retry-delay <seconds>",
382 "Wait time between retries"},
383 {" --retry-max-time <seconds>",
384 "Retry only within this period"},
385 {" --sasl-ir",
386 "Enable initial response in SASL authentication"},
387 {" --service-name <name>",
388 "SPNEGO service name"},
389 {"-S, --show-error",
390 "Show error even when -s is used"},
391 {"-s, --silent",
392 "Silent mode"},
393 {" --socks4 <host[:port]>",
394 "SOCKS4 proxy on given host + port"},
395 {" --socks4a <host[:port]>",
396 "SOCKS4a proxy on given host + port"},
397 {" --socks5 <host[:port]>",
398 "SOCKS5 proxy on given host + port"},
399 {" --socks5-basic",
400 "Enable username/password auth for SOCKS5 proxies"},
401 {" --socks5-gssapi",
402 "Enable GSS-API auth for SOCKS5 proxies"},
403 {" --socks5-gssapi-nec",
404 "Compatibility with NEC SOCKS5 server"},
405 {" --socks5-gssapi-service <name>",
406 "SOCKS5 proxy service name for GSS-API"},
407 {" --socks5-hostname <host[:port]>",
408 "SOCKS5 proxy, pass host name to proxy"},
409 {"-Y, --speed-limit <speed>",
410 "Stop transfers slower than this"},
411 {"-y, --speed-time <seconds>",
412 "Trigger 'speed-limit' abort after this time"},
413 {" --ssl",
414 "Try SSL/TLS"},
415 {" --ssl-allow-beast",
416 "Allow security flaw to improve interop"},
417 {" --ssl-no-revoke",
418 "Disable cert revocation checks (Schannel)"},
419 {" --ssl-reqd",
420 "Require SSL/TLS"},
421 {"-2, --sslv2",
422 "Use SSLv2"},
423 {"-3, --sslv3",
424 "Use SSLv3"},
425 {" --stderr",
426 "Where to redirect stderr"},
427 {" --styled-output",
428 "Enable styled output for HTTP headers"},
429 {" --suppress-connect-headers",
430 "Suppress proxy CONNECT response headers"},
431 {" --tcp-fastopen",
432 "Use TCP Fast Open"},
433 {" --tcp-nodelay",
434 "Use the TCP_NODELAY option"},
435 {"-t, --telnet-option <opt=val>",
436 "Set telnet option"},
437 {" --tftp-blksize <value>",
438 "Set TFTP BLKSIZE option"},
439 {" --tftp-no-options",
440 "Do not send any TFTP options"},
441 {"-z, --time-cond <time>",
442 "Transfer based on a time condition"},
443 {" --tls-max <VERSION>",
444 "Set maximum allowed TLS version"},
445 {" --tls13-ciphers <list of TLS 1.3 ciphersuites>",
446 "TLS 1.3 cipher suites to use"},
447 {" --tlsauthtype <type>",
448 "TLS authentication type"},
449 {" --tlspassword",
450 "TLS password"},
451 {" --tlsuser <name>",
452 "TLS user name"},
453 {"-1, --tlsv1",
454 "Use TLSv1.0 or greater"},
455 {" --tlsv1.0",
456 "Use TLSv1.0 or greater"},
457 {" --tlsv1.1",
458 "Use TLSv1.1 or greater"},
459 {" --tlsv1.2",
460 "Use TLSv1.2 or greater"},
461 {" --tlsv1.3",
462 "Use TLSv1.3 or greater"},
463 {" --tr-encoding",
464 "Request compressed transfer encoding"},
465 {" --trace <file>",
466 "Write a debug trace to FILE"},
467 {" --trace-ascii <file>",
468 "Like --trace, but without hex output"},
469 {" --trace-time",
470 "Add time stamps to trace/verbose output"},
471 {" --unix-socket <path>",
472 "Connect through this Unix domain socket"},
473 {"-T, --upload-file <file>",
474 "Transfer local FILE to destination"},
475 {" --url <url>",
476 "URL to work with"},
477 {"-B, --use-ascii",
478 "Use ASCII/text transfer"},
479 {"-u, --user <user:password>",
480 "Server user and password"},
481 {"-A, --user-agent <name>",
482 "Send User-Agent <name> to server"},
483 {"-v, --verbose",
484 "Make the operation more talkative"},
485 {"-V, --version",
486 "Show version number and quit"},
487 {"-w, --write-out <format>",
488 "Use output FORMAT after completion"},
489 {" --xattr",
490 "Store metadata in extended file attributes"},
491 { NULL, NULL }
492 };
493
494 #ifdef NETWARE
495 # define PRINT_LINES_PAUSE 23
496 #endif
497
498 #ifdef __SYMBIAN32__
499 # define PRINT_LINES_PAUSE 16
500 #endif
501
502 struct feat {
503 const char *name;
504 int bitmask;
505 };
506
507 static const struct feat feats[] = {
508 {"AsynchDNS", CURL_VERSION_ASYNCHDNS},
509 {"Debug", CURL_VERSION_DEBUG},
510 {"TrackMemory", CURL_VERSION_CURLDEBUG},
511 {"IDN", CURL_VERSION_IDN},
512 {"IPv6", CURL_VERSION_IPV6},
513 {"Largefile", CURL_VERSION_LARGEFILE},
514 {"SSPI", CURL_VERSION_SSPI},
515 {"GSS-API", CURL_VERSION_GSSAPI},
516 {"Kerberos", CURL_VERSION_KERBEROS5},
517 {"SPNEGO", CURL_VERSION_SPNEGO},
518 {"NTLM", CURL_VERSION_NTLM},
519 {"NTLM_WB", CURL_VERSION_NTLM_WB},
520 {"SSL", CURL_VERSION_SSL},
521 {"libz", CURL_VERSION_LIBZ},
522 {"brotli", CURL_VERSION_BROTLI},
523 {"CharConv", CURL_VERSION_CONV},
524 {"TLS-SRP", CURL_VERSION_TLSAUTH_SRP},
525 {"HTTP2", CURL_VERSION_HTTP2},
526 {"UnixSockets", CURL_VERSION_UNIX_SOCKETS},
527 {"HTTPS-proxy", CURL_VERSION_HTTPS_PROXY},
528 {"MultiSSL", CURL_VERSION_MULTI_SSL},
529 {"PSL", CURL_VERSION_PSL},
530 {"alt-svc", CURL_VERSION_ALTSVC},
531 };
532
tool_help(void)533 void tool_help(void)
534 {
535 int i;
536 puts("Usage: curl [options...] <url>");
537 for(i = 0; helptext[i].opt; i++) {
538 printf(" %-19s %s\n", helptext[i].opt, helptext[i].desc);
539 #ifdef PRINT_LINES_PAUSE
540 if(i && ((i % PRINT_LINES_PAUSE) == 0))
541 tool_pressanykey();
542 #endif
543 }
544 }
545
546 static int
featcomp(const void * p1,const void * p2)547 featcomp(const void *p1, const void *p2)
548 {
549 /* The arguments to this function are "pointers to pointers to char", but
550 the comparison arguments are "pointers to char", hence the following cast
551 plus dereference */
552 #ifdef HAVE_STRCASECMP
553 return strcasecmp(* (char * const *) p1, * (char * const *) p2);
554 #elif defined(HAVE_STRCMPI)
555 return strcmpi(* (char * const *) p1, * (char * const *) p2);
556 #else
557 return strcmp(* (char * const *) p1, * (char * const *) p2);
558 #endif
559 }
560
tool_version_info(void)561 void tool_version_info(void)
562 {
563 const char *const *proto;
564
565 printf(CURL_ID "%s\n", curl_version());
566 #ifdef CURL_PATCHSTAMP
567 printf("Release-Date: %s, security patched: %s\n",
568 LIBCURL_TIMESTAMP, CURL_PATCHSTAMP);
569 #else
570 printf("Release-Date: %s\n", LIBCURL_TIMESTAMP);
571 #endif
572 if(curlinfo->protocols) {
573 printf("Protocols: ");
574 for(proto = curlinfo->protocols; *proto; ++proto) {
575 printf("%s ", *proto);
576 }
577 puts(""); /* newline */
578 }
579 if(curlinfo->features) {
580 char *featp[ sizeof(feats) / sizeof(feats[0]) + 1];
581 size_t numfeat = 0;
582 unsigned int i;
583 printf("Features:");
584 for(i = 0; i < sizeof(feats)/sizeof(feats[0]); i++) {
585 if(curlinfo->features & feats[i].bitmask)
586 featp[numfeat++] = (char *)feats[i].name;
587 }
588 #ifdef USE_METALINK
589 featp[numfeat++] = (char *)"Metalink";
590 #endif
591 qsort(&featp[0], numfeat, sizeof(char *), featcomp);
592 for(i = 0; i< numfeat; i++)
593 printf(" %s", featp[i]);
594 puts(""); /* newline */
595 }
596 }
597
tool_list_engines(CURL * curl)598 void tool_list_engines(CURL *curl)
599 {
600 struct curl_slist *engines = NULL;
601
602 /* Get the list of engines */
603 curl_easy_getinfo(curl, CURLINFO_SSL_ENGINES, &engines);
604
605 puts("Build-time engines:");
606 if(engines) {
607 for(; engines; engines = engines->next)
608 printf(" %s\n", engines->data);
609 }
610 else {
611 puts(" <none>");
612 }
613
614 /* Cleanup the list of engines */
615 curl_slist_free_all(engines);
616 }
617