xref: /third_party/curl/src/tool_help.c (revision 13498266)
1/***************************************************************************
2 *                                  _   _ ____  _
3 *  Project                     ___| | | |  _ \| |
4 *                             / __| | | | |_) | |
5 *                            | (__| |_| |  _ <| |___
6 *                             \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 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.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 * SPDX-License-Identifier: curl
22 *
23 ***************************************************************************/
24#include "tool_setup.h"
25#define ENABLE_CURLX_PRINTF
26/* use our own printf() functions */
27#include "curlx.h"
28
29#include "tool_help.h"
30#include "tool_libinfo.h"
31#include "tool_util.h"
32#include "tool_version.h"
33
34#include "memdebug.h" /* keep this as LAST include */
35
36#ifdef MSDOS
37#  define USE_WATT32
38#endif
39
40struct category_descriptors {
41  const char *opt;
42  const char *desc;
43  curlhelp_t category;
44};
45
46static const struct category_descriptors categories[] = {
47  {"auth", "Different types of authentication methods", CURLHELP_AUTH},
48  {"connection", "Low level networking operations",
49   CURLHELP_CONNECTION},
50  {"curl", "The command line tool itself", CURLHELP_CURL},
51  {"dns", "General DNS options", CURLHELP_DNS},
52  {"file", "FILE protocol options", CURLHELP_FILE},
53  {"ftp", "FTP protocol options", CURLHELP_FTP},
54  {"http", "HTTP and HTTPS protocol options", CURLHELP_HTTP},
55  {"imap", "IMAP protocol options", CURLHELP_IMAP},
56  /* important is left out because it is the default help page */
57  {"misc", "Options that don't fit into any other category", CURLHELP_MISC},
58  {"output", "Filesystem output", CURLHELP_OUTPUT},
59  {"pop3", "POP3 protocol options", CURLHELP_POP3},
60  {"post", "HTTP Post specific options", CURLHELP_POST},
61  {"proxy", "All options related to proxies", CURLHELP_PROXY},
62  {"scp", "SCP protocol options", CURLHELP_SCP},
63  {"sftp", "SFTP protocol options", CURLHELP_SFTP},
64  {"smtp", "SMTP protocol options", CURLHELP_SMTP},
65  {"ssh", "SSH protocol options", CURLHELP_SSH},
66  {"telnet", "TELNET protocol options", CURLHELP_TELNET},
67  {"tftp", "TFTP protocol options", CURLHELP_TFTP},
68  {"tls", "All TLS/SSL related options", CURLHELP_TLS},
69  {"upload", "All options for uploads",
70   CURLHELP_UPLOAD},
71  {"verbose", "Options related to any kind of command line output of curl",
72   CURLHELP_VERBOSE},
73  {NULL, NULL, CURLHELP_HIDDEN}
74};
75
76
77static void print_category(curlhelp_t category)
78{
79  unsigned int i;
80  size_t longopt = 5;
81  size_t longdesc = 5;
82
83  for(i = 0; helptext[i].opt; ++i) {
84    size_t len;
85    if(!(helptext[i].categories & category))
86      continue;
87    len = strlen(helptext[i].opt);
88    if(len > longopt)
89      longopt = len;
90    len = strlen(helptext[i].desc);
91    if(len > longdesc)
92      longdesc = len;
93  }
94  if(longopt + longdesc > 80)
95    longopt = 80 - longdesc;
96
97  for(i = 0; helptext[i].opt; ++i)
98    if(helptext[i].categories & category) {
99      printf(" %-*s %s\n", (int)longopt, helptext[i].opt, helptext[i].desc);
100    }
101}
102
103/* Prints category if found. If not, it returns 1 */
104static int get_category_content(const char *category)
105{
106  unsigned int i;
107  for(i = 0; categories[i].opt; ++i)
108    if(curl_strequal(categories[i].opt, category)) {
109      printf("%s: %s\n", categories[i].opt, categories[i].desc);
110      print_category(categories[i].category);
111      return 0;
112    }
113  return 1;
114}
115
116/* Prints all categories and their description */
117static void get_categories(void)
118{
119  unsigned int i;
120  for(i = 0; categories[i].opt; ++i)
121    printf(" %-11s %s\n", categories[i].opt, categories[i].desc);
122}
123
124
125void tool_help(char *category)
126{
127  puts("Usage: curl [options...] <url>");
128  /* If no category was provided */
129  if(!category) {
130    const char *category_note = "\nThis is not the full help, this "
131      "menu is stripped into categories.\nUse \"--help category\" to get "
132      "an overview of all categories.\nFor all options use the manual"
133      " or \"--help all\".";
134    print_category(CURLHELP_IMPORTANT);
135    puts(category_note);
136  }
137  /* Lets print everything if "all" was provided */
138  else if(curl_strequal(category, "all"))
139    /* Print everything except hidden */
140    print_category(~(CURLHELP_HIDDEN));
141  /* Lets handle the string "category" differently to not print an errormsg */
142  else if(curl_strequal(category, "category"))
143    get_categories();
144  /* Otherwise print category and handle the case if the cat was not found */
145  else if(get_category_content(category)) {
146    puts("Invalid category provided, here is a list of all categories:\n");
147    get_categories();
148  }
149  free(category);
150}
151
152static bool is_debug(void)
153{
154  const char *const *builtin;
155  for(builtin = feature_names; *builtin; ++builtin)
156    if(curl_strequal("debug", *builtin))
157      return TRUE;
158  return FALSE;
159}
160
161void tool_version_info(void)
162{
163  const char *const *builtin;
164  if(is_debug())
165    fprintf(tool_stderr, "WARNING: this libcurl is Debug-enabled, "
166            "do not use in production\n\n");
167
168  printf(CURL_ID "%s\n", curl_version());
169#ifdef CURL_PATCHSTAMP
170  printf("Release-Date: %s, security patched: %s\n",
171         LIBCURL_TIMESTAMP, CURL_PATCHSTAMP);
172#else
173  printf("Release-Date: %s\n", LIBCURL_TIMESTAMP);
174#endif
175  if(built_in_protos[0]) {
176    const char *insert = NULL;
177    /* we have ipfs and ipns support if libcurl has http support */
178    for(builtin = built_in_protos; *builtin; ++builtin) {
179      if(insert) {
180        /* update insertion so ipfs will be printed in alphabetical order */
181        if(strcmp(*builtin, "ipfs") < 0)
182          insert = *builtin;
183        else
184          break;
185      }
186      else if(!strcmp(*builtin, "http")) {
187        insert = *builtin;
188      }
189    }
190    printf("Protocols:");
191    for(builtin = built_in_protos; *builtin; ++builtin) {
192      /* Special case: do not list rtmp?* protocols.
193         They may only appear together with "rtmp" */
194      if(!curl_strnequal(*builtin, "rtmp", 4) || !builtin[0][4])
195        printf(" %s", *builtin);
196      if(insert && insert == *builtin) {
197        printf(" ipfs ipns");
198        insert = NULL;
199      }
200    }
201    puts(""); /* newline */
202  }
203  if(feature_names[0]) {
204    printf("Features:");
205    for(builtin = feature_names; *builtin; ++builtin)
206      printf(" %s", *builtin);
207    puts(""); /* newline */
208  }
209  if(strcmp(CURL_VERSION, curlinfo->version)) {
210    printf("WARNING: curl and libcurl versions do not match. "
211           "Functionality may be affected.\n");
212  }
213}
214
215void tool_list_engines(void)
216{
217  CURL *curl = curl_easy_init();
218  struct curl_slist *engines = NULL;
219
220  /* Get the list of engines */
221  curl_easy_getinfo(curl, CURLINFO_SSL_ENGINES, &engines);
222
223  puts("Build-time engines:");
224  if(engines) {
225    for(; engines; engines = engines->next)
226      printf("  %s\n", engines->data);
227  }
228  else {
229    puts("  <none>");
230  }
231
232  /* Cleanup the list of engines */
233  curl_slist_free_all(engines);
234  curl_easy_cleanup(curl);
235}
236