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