113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci#include "tool_setup.h" 2513498266Sopenharmony_ci#define ENABLE_CURLX_PRINTF 2613498266Sopenharmony_ci/* use our own printf() functions */ 2713498266Sopenharmony_ci#include "curlx.h" 2813498266Sopenharmony_ci 2913498266Sopenharmony_ci#include "tool_help.h" 3013498266Sopenharmony_ci#include "tool_libinfo.h" 3113498266Sopenharmony_ci#include "tool_util.h" 3213498266Sopenharmony_ci#include "tool_version.h" 3313498266Sopenharmony_ci 3413498266Sopenharmony_ci#include "memdebug.h" /* keep this as LAST include */ 3513498266Sopenharmony_ci 3613498266Sopenharmony_ci#ifdef MSDOS 3713498266Sopenharmony_ci# define USE_WATT32 3813498266Sopenharmony_ci#endif 3913498266Sopenharmony_ci 4013498266Sopenharmony_cistruct category_descriptors { 4113498266Sopenharmony_ci const char *opt; 4213498266Sopenharmony_ci const char *desc; 4313498266Sopenharmony_ci curlhelp_t category; 4413498266Sopenharmony_ci}; 4513498266Sopenharmony_ci 4613498266Sopenharmony_cistatic const struct category_descriptors categories[] = { 4713498266Sopenharmony_ci {"auth", "Different types of authentication methods", CURLHELP_AUTH}, 4813498266Sopenharmony_ci {"connection", "Low level networking operations", 4913498266Sopenharmony_ci CURLHELP_CONNECTION}, 5013498266Sopenharmony_ci {"curl", "The command line tool itself", CURLHELP_CURL}, 5113498266Sopenharmony_ci {"dns", "General DNS options", CURLHELP_DNS}, 5213498266Sopenharmony_ci {"file", "FILE protocol options", CURLHELP_FILE}, 5313498266Sopenharmony_ci {"ftp", "FTP protocol options", CURLHELP_FTP}, 5413498266Sopenharmony_ci {"http", "HTTP and HTTPS protocol options", CURLHELP_HTTP}, 5513498266Sopenharmony_ci {"imap", "IMAP protocol options", CURLHELP_IMAP}, 5613498266Sopenharmony_ci /* important is left out because it is the default help page */ 5713498266Sopenharmony_ci {"misc", "Options that don't fit into any other category", CURLHELP_MISC}, 5813498266Sopenharmony_ci {"output", "Filesystem output", CURLHELP_OUTPUT}, 5913498266Sopenharmony_ci {"pop3", "POP3 protocol options", CURLHELP_POP3}, 6013498266Sopenharmony_ci {"post", "HTTP Post specific options", CURLHELP_POST}, 6113498266Sopenharmony_ci {"proxy", "All options related to proxies", CURLHELP_PROXY}, 6213498266Sopenharmony_ci {"scp", "SCP protocol options", CURLHELP_SCP}, 6313498266Sopenharmony_ci {"sftp", "SFTP protocol options", CURLHELP_SFTP}, 6413498266Sopenharmony_ci {"smtp", "SMTP protocol options", CURLHELP_SMTP}, 6513498266Sopenharmony_ci {"ssh", "SSH protocol options", CURLHELP_SSH}, 6613498266Sopenharmony_ci {"telnet", "TELNET protocol options", CURLHELP_TELNET}, 6713498266Sopenharmony_ci {"tftp", "TFTP protocol options", CURLHELP_TFTP}, 6813498266Sopenharmony_ci {"tls", "All TLS/SSL related options", CURLHELP_TLS}, 6913498266Sopenharmony_ci {"upload", "All options for uploads", 7013498266Sopenharmony_ci CURLHELP_UPLOAD}, 7113498266Sopenharmony_ci {"verbose", "Options related to any kind of command line output of curl", 7213498266Sopenharmony_ci CURLHELP_VERBOSE}, 7313498266Sopenharmony_ci {NULL, NULL, CURLHELP_HIDDEN} 7413498266Sopenharmony_ci}; 7513498266Sopenharmony_ci 7613498266Sopenharmony_ci 7713498266Sopenharmony_cistatic void print_category(curlhelp_t category) 7813498266Sopenharmony_ci{ 7913498266Sopenharmony_ci unsigned int i; 8013498266Sopenharmony_ci size_t longopt = 5; 8113498266Sopenharmony_ci size_t longdesc = 5; 8213498266Sopenharmony_ci 8313498266Sopenharmony_ci for(i = 0; helptext[i].opt; ++i) { 8413498266Sopenharmony_ci size_t len; 8513498266Sopenharmony_ci if(!(helptext[i].categories & category)) 8613498266Sopenharmony_ci continue; 8713498266Sopenharmony_ci len = strlen(helptext[i].opt); 8813498266Sopenharmony_ci if(len > longopt) 8913498266Sopenharmony_ci longopt = len; 9013498266Sopenharmony_ci len = strlen(helptext[i].desc); 9113498266Sopenharmony_ci if(len > longdesc) 9213498266Sopenharmony_ci longdesc = len; 9313498266Sopenharmony_ci } 9413498266Sopenharmony_ci if(longopt + longdesc > 80) 9513498266Sopenharmony_ci longopt = 80 - longdesc; 9613498266Sopenharmony_ci 9713498266Sopenharmony_ci for(i = 0; helptext[i].opt; ++i) 9813498266Sopenharmony_ci if(helptext[i].categories & category) { 9913498266Sopenharmony_ci printf(" %-*s %s\n", (int)longopt, helptext[i].opt, helptext[i].desc); 10013498266Sopenharmony_ci } 10113498266Sopenharmony_ci} 10213498266Sopenharmony_ci 10313498266Sopenharmony_ci/* Prints category if found. If not, it returns 1 */ 10413498266Sopenharmony_cistatic int get_category_content(const char *category) 10513498266Sopenharmony_ci{ 10613498266Sopenharmony_ci unsigned int i; 10713498266Sopenharmony_ci for(i = 0; categories[i].opt; ++i) 10813498266Sopenharmony_ci if(curl_strequal(categories[i].opt, category)) { 10913498266Sopenharmony_ci printf("%s: %s\n", categories[i].opt, categories[i].desc); 11013498266Sopenharmony_ci print_category(categories[i].category); 11113498266Sopenharmony_ci return 0; 11213498266Sopenharmony_ci } 11313498266Sopenharmony_ci return 1; 11413498266Sopenharmony_ci} 11513498266Sopenharmony_ci 11613498266Sopenharmony_ci/* Prints all categories and their description */ 11713498266Sopenharmony_cistatic void get_categories(void) 11813498266Sopenharmony_ci{ 11913498266Sopenharmony_ci unsigned int i; 12013498266Sopenharmony_ci for(i = 0; categories[i].opt; ++i) 12113498266Sopenharmony_ci printf(" %-11s %s\n", categories[i].opt, categories[i].desc); 12213498266Sopenharmony_ci} 12313498266Sopenharmony_ci 12413498266Sopenharmony_ci 12513498266Sopenharmony_civoid tool_help(char *category) 12613498266Sopenharmony_ci{ 12713498266Sopenharmony_ci puts("Usage: curl [options...] <url>"); 12813498266Sopenharmony_ci /* If no category was provided */ 12913498266Sopenharmony_ci if(!category) { 13013498266Sopenharmony_ci const char *category_note = "\nThis is not the full help, this " 13113498266Sopenharmony_ci "menu is stripped into categories.\nUse \"--help category\" to get " 13213498266Sopenharmony_ci "an overview of all categories.\nFor all options use the manual" 13313498266Sopenharmony_ci " or \"--help all\"."; 13413498266Sopenharmony_ci print_category(CURLHELP_IMPORTANT); 13513498266Sopenharmony_ci puts(category_note); 13613498266Sopenharmony_ci } 13713498266Sopenharmony_ci /* Lets print everything if "all" was provided */ 13813498266Sopenharmony_ci else if(curl_strequal(category, "all")) 13913498266Sopenharmony_ci /* Print everything except hidden */ 14013498266Sopenharmony_ci print_category(~(CURLHELP_HIDDEN)); 14113498266Sopenharmony_ci /* Lets handle the string "category" differently to not print an errormsg */ 14213498266Sopenharmony_ci else if(curl_strequal(category, "category")) 14313498266Sopenharmony_ci get_categories(); 14413498266Sopenharmony_ci /* Otherwise print category and handle the case if the cat was not found */ 14513498266Sopenharmony_ci else if(get_category_content(category)) { 14613498266Sopenharmony_ci puts("Invalid category provided, here is a list of all categories:\n"); 14713498266Sopenharmony_ci get_categories(); 14813498266Sopenharmony_ci } 14913498266Sopenharmony_ci free(category); 15013498266Sopenharmony_ci} 15113498266Sopenharmony_ci 15213498266Sopenharmony_cistatic bool is_debug(void) 15313498266Sopenharmony_ci{ 15413498266Sopenharmony_ci const char *const *builtin; 15513498266Sopenharmony_ci for(builtin = feature_names; *builtin; ++builtin) 15613498266Sopenharmony_ci if(curl_strequal("debug", *builtin)) 15713498266Sopenharmony_ci return TRUE; 15813498266Sopenharmony_ci return FALSE; 15913498266Sopenharmony_ci} 16013498266Sopenharmony_ci 16113498266Sopenharmony_civoid tool_version_info(void) 16213498266Sopenharmony_ci{ 16313498266Sopenharmony_ci const char *const *builtin; 16413498266Sopenharmony_ci if(is_debug()) 16513498266Sopenharmony_ci fprintf(tool_stderr, "WARNING: this libcurl is Debug-enabled, " 16613498266Sopenharmony_ci "do not use in production\n\n"); 16713498266Sopenharmony_ci 16813498266Sopenharmony_ci printf(CURL_ID "%s\n", curl_version()); 16913498266Sopenharmony_ci#ifdef CURL_PATCHSTAMP 17013498266Sopenharmony_ci printf("Release-Date: %s, security patched: %s\n", 17113498266Sopenharmony_ci LIBCURL_TIMESTAMP, CURL_PATCHSTAMP); 17213498266Sopenharmony_ci#else 17313498266Sopenharmony_ci printf("Release-Date: %s\n", LIBCURL_TIMESTAMP); 17413498266Sopenharmony_ci#endif 17513498266Sopenharmony_ci if(built_in_protos[0]) { 17613498266Sopenharmony_ci const char *insert = NULL; 17713498266Sopenharmony_ci /* we have ipfs and ipns support if libcurl has http support */ 17813498266Sopenharmony_ci for(builtin = built_in_protos; *builtin; ++builtin) { 17913498266Sopenharmony_ci if(insert) { 18013498266Sopenharmony_ci /* update insertion so ipfs will be printed in alphabetical order */ 18113498266Sopenharmony_ci if(strcmp(*builtin, "ipfs") < 0) 18213498266Sopenharmony_ci insert = *builtin; 18313498266Sopenharmony_ci else 18413498266Sopenharmony_ci break; 18513498266Sopenharmony_ci } 18613498266Sopenharmony_ci else if(!strcmp(*builtin, "http")) { 18713498266Sopenharmony_ci insert = *builtin; 18813498266Sopenharmony_ci } 18913498266Sopenharmony_ci } 19013498266Sopenharmony_ci printf("Protocols:"); 19113498266Sopenharmony_ci for(builtin = built_in_protos; *builtin; ++builtin) { 19213498266Sopenharmony_ci /* Special case: do not list rtmp?* protocols. 19313498266Sopenharmony_ci They may only appear together with "rtmp" */ 19413498266Sopenharmony_ci if(!curl_strnequal(*builtin, "rtmp", 4) || !builtin[0][4]) 19513498266Sopenharmony_ci printf(" %s", *builtin); 19613498266Sopenharmony_ci if(insert && insert == *builtin) { 19713498266Sopenharmony_ci printf(" ipfs ipns"); 19813498266Sopenharmony_ci insert = NULL; 19913498266Sopenharmony_ci } 20013498266Sopenharmony_ci } 20113498266Sopenharmony_ci puts(""); /* newline */ 20213498266Sopenharmony_ci } 20313498266Sopenharmony_ci if(feature_names[0]) { 20413498266Sopenharmony_ci printf("Features:"); 20513498266Sopenharmony_ci for(builtin = feature_names; *builtin; ++builtin) 20613498266Sopenharmony_ci printf(" %s", *builtin); 20713498266Sopenharmony_ci puts(""); /* newline */ 20813498266Sopenharmony_ci } 20913498266Sopenharmony_ci if(strcmp(CURL_VERSION, curlinfo->version)) { 21013498266Sopenharmony_ci printf("WARNING: curl and libcurl versions do not match. " 21113498266Sopenharmony_ci "Functionality may be affected.\n"); 21213498266Sopenharmony_ci } 21313498266Sopenharmony_ci} 21413498266Sopenharmony_ci 21513498266Sopenharmony_civoid tool_list_engines(void) 21613498266Sopenharmony_ci{ 21713498266Sopenharmony_ci CURL *curl = curl_easy_init(); 21813498266Sopenharmony_ci struct curl_slist *engines = NULL; 21913498266Sopenharmony_ci 22013498266Sopenharmony_ci /* Get the list of engines */ 22113498266Sopenharmony_ci curl_easy_getinfo(curl, CURLINFO_SSL_ENGINES, &engines); 22213498266Sopenharmony_ci 22313498266Sopenharmony_ci puts("Build-time engines:"); 22413498266Sopenharmony_ci if(engines) { 22513498266Sopenharmony_ci for(; engines; engines = engines->next) 22613498266Sopenharmony_ci printf(" %s\n", engines->data); 22713498266Sopenharmony_ci } 22813498266Sopenharmony_ci else { 22913498266Sopenharmony_ci puts(" <none>"); 23013498266Sopenharmony_ci } 23113498266Sopenharmony_ci 23213498266Sopenharmony_ci /* Cleanup the list of engines */ 23313498266Sopenharmony_ci curl_slist_free_all(engines); 23413498266Sopenharmony_ci curl_easy_cleanup(curl); 23513498266Sopenharmony_ci} 236