18. Command line tool
18.1 sync
18.2 glob posts
- 18.3 -h option
18.4 --proxycommand
18.5 UTF-8 filenames in Content-Disposition
18.6 Option to make -Z merge lined based outputs on stdout
Globbing support for -d and -F, as in 'curl -d "name=foo[0-9]" URL'.
This is easily scripted though.
-18.3 -h option
-
- Support "curl -h --insecure" etc to output the manpage section for the
- --insecure command line option in the terminal. Should be possible to work
- with either long or short versions of command line options.
-
18.4 --proxycommand
Allow the user to make curl run a command and use its stdio to make requests
retain their values and meaning even after --next.
The following options are global: `%GLOBALS`.
+
+# ALL OPTIONS
c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
SPDX-License-Identifier: curl
Long: help
-Arg: <category>
+Arg: <subject>
Short: h
Help: Get help for commands
Category: important curl
- verbose
Example:
- --help all
+ - --help --insecure
+ - --help -f
---
# `--help`
-Usage help. List all curl command line options within the given **category**.
+Usage help. Provide help for the subject given as an optional argument.
If no argument is provided, curl displays the most important command line
arguments.
-For category **all**, curl displays help for all options.
+The argument can either be a **category** or a **command line option**. When a
+category is provided, curl shows all command line options within the given
+category. Specify category `all` to list all available options.
-If **category** is specified, curl displays all available help categories.
+If `category` is specified, curl displays all available help categories.
+
+If the provided subject is instead an existing command line option, specified
+either in its short form with a single dash and a single letter, or in the
+long form with two dashes and a longer name, curl displays a help text for
+that option in the terminal.
+
+The help output is extensive for some options.
+
+If the provided command line option is not known, curl says so.
#
###########################################################################
-# Yeah, I know, probably 1000 other persons already wrote a script like
-# this, but I'll tell ya:
-
-# THEY DON'T FIT ME :-)
-
-# Get readme file as parameter:
-
if($ARGV[0] eq "-c") {
$c=1;
shift @ARGV;
*/
#ifdef USE_MANUAL
#include "tool_hugehelp.h"
+#include "tool_help.h"
+
HEAD
;
if($c) {
(void) opaque;
free(ptr);
}
+
+#define HEADERLEN 10
+
/* Decompress and send to stdout a gzip-compressed buffer */
void hugehelp(void)
{
unsigned char *buf;
- int status, headerlen;
+ int status;
z_stream z;
/* Make sure no gzip options are set */
if(hugehelpgz[3] & 0xfe)
return;
- headerlen = 10;
memset(&z, 0, sizeof(z_stream));
z.zalloc = (alloc_func)zalloc_func;
z.zfree = (free_func)zfree_func;
- z.avail_in = (unsigned int)(sizeof(hugehelpgz) - headerlen);
- z.next_in = (unsigned char *)hugehelpgz + headerlen;
+ z.avail_in = (unsigned int)(sizeof(hugehelpgz) - HEADERLEN);
+ z.next_in = (unsigned char *)hugehelpgz + HEADERLEN;
if(inflateInit2(&z, -MAX_WBITS) != Z_OK)
return;
break;
}
else
- break; /* Error */
+ break; /* error */
+ }
+ free(buf);
+ }
+ inflateEnd(&z);
+}
+/* Show the help text for the 'arg' curl argument on stdout */
+void showhelp(const char *trigger, const char *arg, const char *endarg)
+{
+ unsigned char *buf;
+ int status;
+ z_stream z;
+ struct scan_ctx ctx;
+ inithelpscan(&ctx, trigger, arg, endarg);
+
+ /* Make sure no gzip options are set */
+ if(hugehelpgz[3] & 0xfe)
+ return;
+
+ memset(&z, 0, sizeof(z_stream));
+ z.zalloc = (alloc_func)zalloc_func;
+ z.zfree = (free_func)zfree_func;
+ z.avail_in = (unsigned int)(sizeof(hugehelpgz) - HEADERLEN);
+ z.next_in = (unsigned char *)hugehelpgz + HEADERLEN;
+
+ if(inflateInit2(&z, -MAX_WBITS) != Z_OK)
+ return;
+
+ buf = malloc(BUF_SIZE);
+ if(buf) {
+ while(1) {
+ z.avail_out = BUF_SIZE;
+ z.next_out = buf;
+ status = inflate(&z, Z_SYNC_FLUSH);
+ if(status == Z_OK || status == Z_STREAM_END) {
+ size_t len = BUF_SIZE - z.avail_out;
+ if(!helpscan(buf, len, &ctx))
+ break;
+ if(status == Z_STREAM_END)
+ break;
+ }
+ else
+ break; /* error */
}
free(buf);
}
while(curlman[i])
puts(curlman[i++]);
}
+
+/* Show the help text for the 'arg' curl argument on stdout */
+void showhelp(const char *trigger, const char *arg, const char *endarg)
+{
+ int i = 0;
+ struct scan_ctx ctx;
+ inithelpscan(&ctx, trigger, arg, endarg);
+ while(curlman[i]) {
+ size_t len = strlen(curlman[i]);
+ if(!helpscan((unsigned char *)curlman[i], len, &ctx) ||
+ !helpscan((unsigned char *)"\\n", 1, &ctx))
+ break;
+ i++;
+ }
+}
ENDLINE
;
return PARAM_OK;
}
-/* one enum for every command line option. The name is the verbatim long
- option name, but in uppercase with periods and minuses replaced with
- underscores using a "C_" prefix. */
-typedef enum {
- C_ABSTRACT_UNIX_SOCKET,
- C_ALPN,
- C_ALT_SVC,
- C_ANYAUTH,
- C_APPEND,
- C_AWS_SIGV4,
- C_BASIC,
- C_BUFFER,
- C_CA_NATIVE,
- C_CACERT,
- C_CAPATH,
- C_CERT,
- C_CERT_STATUS,
- C_CERT_TYPE,
- C_CIPHERS,
- C_CLOBBER,
- C_COMPRESSED,
- C_COMPRESSED_SSH,
- C_CONFIG,
- C_CONNECT_TIMEOUT,
- C_CONNECT_TO,
- C_CONTINUE_AT,
- C_COOKIE,
- C_COOKIE_JAR,
- C_CREATE_DIRS,
- C_CREATE_FILE_MODE,
- C_CRLF,
- C_CRLFILE,
- C_CURVES,
- C_DATA,
- C_DATA_ASCII,
- C_DATA_BINARY,
- C_DATA_RAW,
- C_DATA_URLENCODE,
- C_DELEGATION,
- C_DIGEST,
- C_DISABLE,
- C_DISABLE_EPRT,
- C_DISABLE_EPSV,
- C_DISALLOW_USERNAME_IN_URL,
- C_DNS_INTERFACE,
- C_DNS_IPV4_ADDR,
- C_DNS_IPV6_ADDR,
- C_DNS_SERVERS,
- C_DOH_CERT_STATUS,
- C_DOH_INSECURE,
- C_DOH_URL,
- C_DUMP_CA_EMBED,
- C_DUMP_HEADER,
- C_ECH,
- C_EGD_FILE,
- C_ENGINE,
- C_EPRT,
- C_EPSV,
- C_ETAG_COMPARE,
- C_ETAG_SAVE,
- C_EXPECT100_TIMEOUT,
- C_FAIL,
- C_FAIL_EARLY,
- C_FAIL_WITH_BODY,
- C_FALSE_START,
- C_FORM,
- C_FORM_ESCAPE,
- C_FORM_STRING,
- C_FTP_ACCOUNT,
- C_FTP_ALTERNATIVE_TO_USER,
- C_FTP_CREATE_DIRS,
- C_FTP_METHOD,
- C_FTP_PASV,
- C_FTP_PORT,
- C_FTP_PRET,
- C_FTP_SKIP_PASV_IP,
- C_FTP_SSL,
- C_FTP_SSL_CCC,
- C_FTP_SSL_CCC_MODE,
- C_FTP_SSL_CONTROL,
- C_FTP_SSL_REQD,
- C_GET,
- C_GLOBOFF,
- C_HAPPY_EYEBALLS_TIMEOUT_MS,
- C_HAPROXY_CLIENTIP,
- C_HAPROXY_PROTOCOL,
- C_HEAD,
- C_HEADER,
- C_HELP,
- C_HOSTPUBMD5,
- C_HOSTPUBSHA256,
- C_HSTS,
- C_HTTP0_9,
- C_HTTP1_0,
- C_HTTP1_1,
- C_HTTP2,
- C_HTTP2_PRIOR_KNOWLEDGE,
- C_HTTP3,
- C_HTTP3_ONLY,
- C_IGNORE_CONTENT_LENGTH,
- C_INCLUDE,
- C_INSECURE,
- C_INTERFACE,
- C_IPFS_GATEWAY,
- C_IPV4,
- C_IPV6,
- C_JSON,
- C_JUNK_SESSION_COOKIES,
- C_KEEPALIVE,
- C_KEEPALIVE_CNT,
- C_KEEPALIVE_TIME,
- C_KEY,
- C_KEY_TYPE,
- C_KRB,
- C_KRB4,
- C_LIBCURL,
- C_LIMIT_RATE,
- C_LIST_ONLY,
- C_LOCAL_PORT,
- C_LOCATION,
- C_LOCATION_TRUSTED,
- C_LOGIN_OPTIONS,
- C_MAIL_AUTH,
- C_MAIL_FROM,
- C_MAIL_RCPT,
- C_MAIL_RCPT_ALLOWFAILS,
- C_MANUAL,
- C_MAX_FILESIZE,
- C_MAX_REDIRS,
- C_MAX_TIME,
- C_METALINK,
- C_MPTCP,
- C_NEGOTIATE,
- C_NETRC,
- C_NETRC_FILE,
- C_NETRC_OPTIONAL,
- C_NEXT,
- C_NOPROXY,
- C_NPN,
- C_NTLM,
- C_NTLM_WB,
- C_OAUTH2_BEARER,
- C_OUTPUT,
- C_OUTPUT_DIR,
- C_PARALLEL,
- C_PARALLEL_IMMEDIATE,
- C_PARALLEL_MAX,
- C_PASS,
- C_PATH_AS_IS,
- C_PINNEDPUBKEY,
- C_POST301,
- C_POST302,
- C_POST303,
- C_PREPROXY,
- C_PROGRESS_BAR,
- C_PROGRESS_METER,
- C_PROTO,
- C_PROTO_DEFAULT,
- C_PROTO_REDIR,
- C_PROXY,
- C_PROXY_ANYAUTH,
- C_PROXY_BASIC,
- C_PROXY_CA_NATIVE,
- C_PROXY_CACERT,
- C_PROXY_CAPATH,
- C_PROXY_CERT,
- C_PROXY_CERT_TYPE,
- C_PROXY_CIPHERS,
- C_PROXY_CRLFILE,
- C_PROXY_DIGEST,
- C_PROXY_HEADER,
- C_PROXY_HTTP2,
- C_PROXY_INSECURE,
- C_PROXY_KEY,
- C_PROXY_KEY_TYPE,
- C_PROXY_NEGOTIATE,
- C_PROXY_NTLM,
- C_PROXY_PASS,
- C_PROXY_PINNEDPUBKEY,
- C_PROXY_SERVICE_NAME,
- C_PROXY_SSL_ALLOW_BEAST,
- C_PROXY_SSL_AUTO_CLIENT_CERT,
- C_PROXY_TLS13_CIPHERS,
- C_PROXY_TLSAUTHTYPE,
- C_PROXY_TLSPASSWORD,
- C_PROXY_TLSUSER,
- C_PROXY_TLSV1,
- C_PROXY_USER,
- C_PROXY1_0,
- C_PROXYTUNNEL,
- C_PUBKEY,
- C_QUOTE,
- C_RANDOM_FILE,
- C_RANGE,
- C_RATE,
- C_RAW,
- C_REFERER,
- C_REMOTE_HEADER_NAME,
- C_REMOTE_NAME,
- C_REMOTE_NAME_ALL,
- C_REMOTE_TIME,
- C_REMOVE_ON_ERROR,
- C_REQUEST,
- C_REQUEST_TARGET,
- C_RESOLVE,
- C_RETRY,
- C_RETRY_ALL_ERRORS,
- C_RETRY_CONNREFUSED,
- C_RETRY_DELAY,
- C_RETRY_MAX_TIME,
- C_SASL_AUTHZID,
- C_SASL_IR,
- C_SERVICE_NAME,
- C_SESSIONID,
- C_SHOW_ERROR,
- C_SHOW_HEADERS,
- C_SILENT,
- C_SOCKS4,
- C_SOCKS4A,
- C_SOCKS5,
- C_SOCKS5_BASIC,
- C_SOCKS5_GSSAPI,
- C_SOCKS5_GSSAPI_NEC,
- C_SOCKS5_GSSAPI_SERVICE,
- C_SOCKS5_HOSTNAME,
- C_SPEED_LIMIT,
- C_SPEED_TIME,
- C_SSL,
- C_SSL_ALLOW_BEAST,
- C_SSL_AUTO_CLIENT_CERT,
- C_SSL_NO_REVOKE,
- C_SSL_REQD,
- C_SSL_REVOKE_BEST_EFFORT,
- C_SSLV2,
- C_SSLV3,
- C_STDERR,
- C_STYLED_OUTPUT,
- C_SUPPRESS_CONNECT_HEADERS,
- C_TCP_FASTOPEN,
- C_TCP_NODELAY,
- C_TELNET_OPTION,
- C_TEST_EVENT,
- C_TFTP_BLKSIZE,
- C_TFTP_NO_OPTIONS,
- C_TIME_COND,
- C_TLS_MAX,
- C_TLS13_CIPHERS,
- C_TLSAUTHTYPE,
- C_TLSPASSWORD,
- C_TLSUSER,
- C_TLSV1,
- C_TLSV1_0,
- C_TLSV1_1,
- C_TLSV1_2,
- C_TLSV1_3,
- C_TR_ENCODING,
- C_TRACE,
- C_TRACE_ASCII,
- C_TRACE_CONFIG,
- C_TRACE_IDS,
- C_TRACE_TIME,
- C_IP_TOS,
- C_UNIX_SOCKET,
- C_UPLOAD_FILE,
- C_URL,
- C_URL_QUERY,
- C_USE_ASCII,
- C_USER,
- C_USER_AGENT,
- C_VARIABLE,
- C_VERBOSE,
- C_VERSION,
- C_VLAN_PRIORITY,
- C_WDEBUG,
- C_WRITE_OUT,
- C_XATTR
-} cmdline_t;
-
-struct LongShort {
- const char *lname; /* long name option */
- enum {
- ARG_NONE, /* stand-alone but not a boolean */
- ARG_BOOL, /* accepts a --no-[name] prefix */
- ARG_STRG, /* requires an argument */
- ARG_FILE /* requires an argument, usually a filename */
- } desc;
- char letter; /* short name option or ' ' */
- cmdline_t cmd;
-};
-
/* this array MUST be alphasorted based on the 'lname' */
static const struct LongShort aliases[]= {
{"abstract-unix-socket", ARG_FILE, ' ', C_ABSTRACT_UNIX_SOCKET},
- {"alpn", ARG_BOOL, ' ', C_ALPN},
+ {"alpn", ARG_BOOL|ARG_NO, ' ', C_ALPN},
{"alt-svc", ARG_STRG, ' ', C_ALT_SVC},
{"anyauth", ARG_BOOL, ' ', C_ANYAUTH},
{"append", ARG_BOOL, 'a', C_APPEND},
{"aws-sigv4", ARG_STRG, ' ', C_AWS_SIGV4},
{"basic", ARG_BOOL, ' ', C_BASIC},
- {"buffer", ARG_BOOL, 'N', C_BUFFER},
+ {"buffer", ARG_BOOL|ARG_NO, 'N', C_BUFFER},
{"ca-native", ARG_BOOL, ' ', C_CA_NATIVE},
{"cacert", ARG_FILE, ' ', C_CACERT},
{"capath", ARG_FILE, ' ', C_CAPATH},
{"cert-status", ARG_BOOL, ' ', C_CERT_STATUS},
{"cert-type", ARG_STRG, ' ', C_CERT_TYPE},
{"ciphers", ARG_STRG, ' ', C_CIPHERS},
- {"clobber", ARG_BOOL, ' ', C_CLOBBER},
+ {"clobber", ARG_BOOL|ARG_NO, ' ', C_CLOBBER},
{"compressed", ARG_BOOL, ' ', C_COMPRESSED},
{"compressed-ssh", ARG_BOOL, ' ', C_COMPRESSED_SSH},
{"config", ARG_FILE, 'K', C_CONFIG},
{"ipv6", ARG_NONE, '6', C_IPV6},
{"json", ARG_STRG, ' ', C_JSON},
{"junk-session-cookies", ARG_BOOL, 'j', C_JUNK_SESSION_COOKIES},
- {"keepalive", ARG_BOOL, ' ', C_KEEPALIVE},
+ {"keepalive", ARG_BOOL|ARG_NO, ' ', C_KEEPALIVE},
{"keepalive-cnt", ARG_STRG, ' ', C_KEEPALIVE_CNT},
{"keepalive-time", ARG_STRG, ' ', C_KEEPALIVE_TIME},
{"key", ARG_FILE, ' ', C_KEY},
{"netrc-optional", ARG_BOOL, ' ', C_NETRC_OPTIONAL},
{"next", ARG_NONE, ':', C_NEXT},
{"noproxy", ARG_STRG, ' ', C_NOPROXY},
- {"npn", ARG_BOOL, ' ', C_NPN},
+ {"npn", ARG_BOOL|ARG_NO, ' ', C_NPN},
{"ntlm", ARG_BOOL, ' ', C_NTLM},
{"ntlm-wb", ARG_BOOL, ' ', C_NTLM_WB},
{"oauth2-bearer", ARG_STRG, ' ', C_OAUTH2_BEARER},
{"post303", ARG_BOOL, ' ', C_POST303},
{"preproxy", ARG_STRG, ' ', C_PREPROXY},
{"progress-bar", ARG_BOOL, '#', C_PROGRESS_BAR},
- {"progress-meter", ARG_BOOL, ' ', C_PROGRESS_METER},
+ {"progress-meter", ARG_BOOL|ARG_NO, ' ', C_PROGRESS_METER},
{"proto", ARG_STRG, ' ', C_PROTO},
{"proto-default", ARG_STRG, ' ', C_PROTO_DEFAULT},
{"proto-redir", ARG_STRG, ' ', C_PROTO_REDIR},
{"sasl-authzid", ARG_STRG, ' ', C_SASL_AUTHZID},
{"sasl-ir", ARG_BOOL, ' ', C_SASL_IR},
{"service-name", ARG_STRG, ' ', C_SERVICE_NAME},
- {"sessionid", ARG_BOOL, ' ', C_SESSIONID},
+ {"sessionid", ARG_BOOL|ARG_NO, ' ', C_SESSIONID},
{"show-error", ARG_BOOL, 'S', C_SHOW_ERROR},
{"show-headers", ARG_BOOL, 'i', C_SHOW_HEADERS},
{"silent", ARG_BOOL, 's', C_SILENT},
return strcmp(aa->lname, bb->lname);
}
-static const struct LongShort *single(char letter)
+const struct LongShort *findshortopt(char letter)
{
static const struct LongShort *singles[128 - ' ']; /* ASCII => pointer */
static bool singles_done = FALSE;
return err;
}
+const struct LongShort *findlongopt(const char *opt)
+{
+ struct LongShort key;
+ key.lname = opt;
+
+ return bsearch(&key, aliases, sizeof(aliases)/sizeof(aliases[0]),
+ sizeof(aliases[0]), findarg);
+}
+
ParameterError getparameter(const char *flag, /* f or -long-flag */
char *nextarg, /* NULL if unset */
const char *word = ('-' == flag[0]) ? flag + 2 : flag;
bool noflagged = FALSE;
bool expand = FALSE;
- struct LongShort key;
if(!strncmp(word, "no-", 3)) {
/* disable this option but ignore the "no-" part when looking for it */
word += 7;
expand = TRUE;
}
- key.lname = word;
- a = bsearch(&key, aliases, sizeof(aliases)/sizeof(aliases[0]),
- sizeof(aliases[0]), findarg);
+ a = findlongopt(word);
if(a) {
longopt = TRUE;
}
err = PARAM_OPTION_UNKNOWN;
goto error;
}
- if(noflagged && (a->desc != ARG_BOOL)) {
+ if(noflagged && (ARGTYPE(a->desc) != ARG_BOOL)) {
/* --no- prefixed an option that is not boolean! */
err = PARAM_NO_NOT_BOOLEAN;
goto error;
struct curlx_dynbuf nbuf;
bool replaced;
- if((a->desc != ARG_STRG) &&
- (a->desc != ARG_FILE)) {
+ if((ARGTYPE(a->desc) != ARG_STRG) &&
+ (ARGTYPE(a->desc) != ARG_FILE)) {
/* --expand on an option that is not a string or a filename */
err = PARAM_EXPAND_ERROR;
goto error;
cmdline_t cmd;
if(!longopt && !a) {
- a = single(*parse);
+ a = findshortopt(*parse);
if(!a) {
err = PARAM_OPTION_UNKNOWN;
break;
}
}
letter = a->letter;
- cmd = a->cmd;
- if(a->desc >= ARG_STRG) {
+ cmd = (cmdline_t)a->cmd;
+ if(ARGTYPE(a->desc) >= ARG_STRG) {
/* this option requires an extra parameter */
if(!longopt && parse[1]) {
nextarg = (char *)&parse[1]; /* this is the actual extra parameter */
*usedarg = TRUE; /* mark it as used */
}
- if((a->desc == ARG_FILE) &&
+ if((ARGTYPE(a->desc) == ARG_FILE) &&
(nextarg[0] == '-') && nextarg[1]) {
/* if the filename looks like a command line option */
warnf(global, "The filename argument '%s' looks like a flag.",
nextarg);
}
}
- else if((a->desc == ARG_NONE) && !toggle) {
+ else if((ARGTYPE(a->desc) == ARG_NONE) && !toggle) {
err = PARAM_NO_PREFIX;
break;
}
***************************************************************************/
#include "tool_setup.h"
+/* one enum for every command line option. The name is the verbatim long
+ option name, but in uppercase with periods and minuses replaced with
+ underscores using a "C_" prefix. */
+typedef enum {
+ C_ABSTRACT_UNIX_SOCKET,
+ C_ALPN,
+ C_ALT_SVC,
+ C_ANYAUTH,
+ C_APPEND,
+ C_AWS_SIGV4,
+ C_BASIC,
+ C_BUFFER,
+ C_CA_NATIVE,
+ C_CACERT,
+ C_CAPATH,
+ C_CERT,
+ C_CERT_STATUS,
+ C_CERT_TYPE,
+ C_CIPHERS,
+ C_CLOBBER,
+ C_COMPRESSED,
+ C_COMPRESSED_SSH,
+ C_CONFIG,
+ C_CONNECT_TIMEOUT,
+ C_CONNECT_TO,
+ C_CONTINUE_AT,
+ C_COOKIE,
+ C_COOKIE_JAR,
+ C_CREATE_DIRS,
+ C_CREATE_FILE_MODE,
+ C_CRLF,
+ C_CRLFILE,
+ C_CURVES,
+ C_DATA,
+ C_DATA_ASCII,
+ C_DATA_BINARY,
+ C_DATA_RAW,
+ C_DATA_URLENCODE,
+ C_DELEGATION,
+ C_DIGEST,
+ C_DISABLE,
+ C_DISABLE_EPRT,
+ C_DISABLE_EPSV,
+ C_DISALLOW_USERNAME_IN_URL,
+ C_DNS_INTERFACE,
+ C_DNS_IPV4_ADDR,
+ C_DNS_IPV6_ADDR,
+ C_DNS_SERVERS,
+ C_DOH_CERT_STATUS,
+ C_DOH_INSECURE,
+ C_DOH_URL,
+ C_DUMP_CA_EMBED,
+ C_DUMP_HEADER,
+ C_ECH,
+ C_EGD_FILE,
+ C_ENGINE,
+ C_EPRT,
+ C_EPSV,
+ C_ETAG_COMPARE,
+ C_ETAG_SAVE,
+ C_EXPECT100_TIMEOUT,
+ C_FAIL,
+ C_FAIL_EARLY,
+ C_FAIL_WITH_BODY,
+ C_FALSE_START,
+ C_FORM,
+ C_FORM_ESCAPE,
+ C_FORM_STRING,
+ C_FTP_ACCOUNT,
+ C_FTP_ALTERNATIVE_TO_USER,
+ C_FTP_CREATE_DIRS,
+ C_FTP_METHOD,
+ C_FTP_PASV,
+ C_FTP_PORT,
+ C_FTP_PRET,
+ C_FTP_SKIP_PASV_IP,
+ C_FTP_SSL,
+ C_FTP_SSL_CCC,
+ C_FTP_SSL_CCC_MODE,
+ C_FTP_SSL_CONTROL,
+ C_FTP_SSL_REQD,
+ C_GET,
+ C_GLOBOFF,
+ C_HAPPY_EYEBALLS_TIMEOUT_MS,
+ C_HAPROXY_CLIENTIP,
+ C_HAPROXY_PROTOCOL,
+ C_HEAD,
+ C_HEADER,
+ C_HELP,
+ C_HOSTPUBMD5,
+ C_HOSTPUBSHA256,
+ C_HSTS,
+ C_HTTP0_9,
+ C_HTTP1_0,
+ C_HTTP1_1,
+ C_HTTP2,
+ C_HTTP2_PRIOR_KNOWLEDGE,
+ C_HTTP3,
+ C_HTTP3_ONLY,
+ C_IGNORE_CONTENT_LENGTH,
+ C_INCLUDE,
+ C_INSECURE,
+ C_INTERFACE,
+ C_IPFS_GATEWAY,
+ C_IPV4,
+ C_IPV6,
+ C_JSON,
+ C_JUNK_SESSION_COOKIES,
+ C_KEEPALIVE,
+ C_KEEPALIVE_CNT,
+ C_KEEPALIVE_TIME,
+ C_KEY,
+ C_KEY_TYPE,
+ C_KRB,
+ C_KRB4,
+ C_LIBCURL,
+ C_LIMIT_RATE,
+ C_LIST_ONLY,
+ C_LOCAL_PORT,
+ C_LOCATION,
+ C_LOCATION_TRUSTED,
+ C_LOGIN_OPTIONS,
+ C_MAIL_AUTH,
+ C_MAIL_FROM,
+ C_MAIL_RCPT,
+ C_MAIL_RCPT_ALLOWFAILS,
+ C_MANUAL,
+ C_MAX_FILESIZE,
+ C_MAX_REDIRS,
+ C_MAX_TIME,
+ C_METALINK,
+ C_MPTCP,
+ C_NEGOTIATE,
+ C_NETRC,
+ C_NETRC_FILE,
+ C_NETRC_OPTIONAL,
+ C_NEXT,
+ C_NOPROXY,
+ C_NPN,
+ C_NTLM,
+ C_NTLM_WB,
+ C_OAUTH2_BEARER,
+ C_OUTPUT,
+ C_OUTPUT_DIR,
+ C_PARALLEL,
+ C_PARALLEL_IMMEDIATE,
+ C_PARALLEL_MAX,
+ C_PASS,
+ C_PATH_AS_IS,
+ C_PINNEDPUBKEY,
+ C_POST301,
+ C_POST302,
+ C_POST303,
+ C_PREPROXY,
+ C_PROGRESS_BAR,
+ C_PROGRESS_METER,
+ C_PROTO,
+ C_PROTO_DEFAULT,
+ C_PROTO_REDIR,
+ C_PROXY,
+ C_PROXY_ANYAUTH,
+ C_PROXY_BASIC,
+ C_PROXY_CA_NATIVE,
+ C_PROXY_CACERT,
+ C_PROXY_CAPATH,
+ C_PROXY_CERT,
+ C_PROXY_CERT_TYPE,
+ C_PROXY_CIPHERS,
+ C_PROXY_CRLFILE,
+ C_PROXY_DIGEST,
+ C_PROXY_HEADER,
+ C_PROXY_HTTP2,
+ C_PROXY_INSECURE,
+ C_PROXY_KEY,
+ C_PROXY_KEY_TYPE,
+ C_PROXY_NEGOTIATE,
+ C_PROXY_NTLM,
+ C_PROXY_PASS,
+ C_PROXY_PINNEDPUBKEY,
+ C_PROXY_SERVICE_NAME,
+ C_PROXY_SSL_ALLOW_BEAST,
+ C_PROXY_SSL_AUTO_CLIENT_CERT,
+ C_PROXY_TLS13_CIPHERS,
+ C_PROXY_TLSAUTHTYPE,
+ C_PROXY_TLSPASSWORD,
+ C_PROXY_TLSUSER,
+ C_PROXY_TLSV1,
+ C_PROXY_USER,
+ C_PROXY1_0,
+ C_PROXYTUNNEL,
+ C_PUBKEY,
+ C_QUOTE,
+ C_RANDOM_FILE,
+ C_RANGE,
+ C_RATE,
+ C_RAW,
+ C_REFERER,
+ C_REMOTE_HEADER_NAME,
+ C_REMOTE_NAME,
+ C_REMOTE_NAME_ALL,
+ C_REMOTE_TIME,
+ C_REMOVE_ON_ERROR,
+ C_REQUEST,
+ C_REQUEST_TARGET,
+ C_RESOLVE,
+ C_RETRY,
+ C_RETRY_ALL_ERRORS,
+ C_RETRY_CONNREFUSED,
+ C_RETRY_DELAY,
+ C_RETRY_MAX_TIME,
+ C_SASL_AUTHZID,
+ C_SASL_IR,
+ C_SERVICE_NAME,
+ C_SESSIONID,
+ C_SHOW_ERROR,
+ C_SHOW_HEADERS,
+ C_SILENT,
+ C_SOCKS4,
+ C_SOCKS4A,
+ C_SOCKS5,
+ C_SOCKS5_BASIC,
+ C_SOCKS5_GSSAPI,
+ C_SOCKS5_GSSAPI_NEC,
+ C_SOCKS5_GSSAPI_SERVICE,
+ C_SOCKS5_HOSTNAME,
+ C_SPEED_LIMIT,
+ C_SPEED_TIME,
+ C_SSL,
+ C_SSL_ALLOW_BEAST,
+ C_SSL_AUTO_CLIENT_CERT,
+ C_SSL_NO_REVOKE,
+ C_SSL_REQD,
+ C_SSL_REVOKE_BEST_EFFORT,
+ C_SSLV2,
+ C_SSLV3,
+ C_STDERR,
+ C_STYLED_OUTPUT,
+ C_SUPPRESS_CONNECT_HEADERS,
+ C_TCP_FASTOPEN,
+ C_TCP_NODELAY,
+ C_TELNET_OPTION,
+ C_TEST_EVENT,
+ C_TFTP_BLKSIZE,
+ C_TFTP_NO_OPTIONS,
+ C_TIME_COND,
+ C_TLS_MAX,
+ C_TLS13_CIPHERS,
+ C_TLSAUTHTYPE,
+ C_TLSPASSWORD,
+ C_TLSUSER,
+ C_TLSV1,
+ C_TLSV1_0,
+ C_TLSV1_1,
+ C_TLSV1_2,
+ C_TLSV1_3,
+ C_TR_ENCODING,
+ C_TRACE,
+ C_TRACE_ASCII,
+ C_TRACE_CONFIG,
+ C_TRACE_IDS,
+ C_TRACE_TIME,
+ C_IP_TOS,
+ C_UNIX_SOCKET,
+ C_UPLOAD_FILE,
+ C_URL,
+ C_URL_QUERY,
+ C_USE_ASCII,
+ C_USER,
+ C_USER_AGENT,
+ C_VARIABLE,
+ C_VERBOSE,
+ C_VERSION,
+ C_VLAN_PRIORITY,
+ C_WDEBUG,
+ C_WRITE_OUT,
+ C_XATTR
+} cmdline_t;
+
+#define ARG_NONE 0 /* stand-alone but not a boolean */
+#define ARG_BOOL 1 /* accepts a --no-[name] prefix */
+#define ARG_STRG 2 /* requires an argument */
+#define ARG_FILE 3 /* requires an argument, usually a filename */
+
+#define ARG_TYPEMASK 0x03
+#define ARGTYPE(x) ((x) & ARG_TYPEMASK)
+
+#define ARG_NO 0x80 /* set if the option is documented as --no-* */
+
+struct LongShort {
+ const char *lname; /* long name option */
+ unsigned char desc; /* type, see ARG_* */
+ char letter; /* short name option or ' ' */
+ unsigned short cmd;
+};
+
typedef enum {
PARAM_OK = 0,
PARAM_OPTION_AMBIGUOUS,
struct GlobalConfig;
struct OperationConfig;
+const struct LongShort *findlongopt(const char *opt);
+const struct LongShort *findshortopt(char letter);
+
ParameterError getparameter(const char *flag, char *nextarg,
argv_item_t cleararg,
bool *usedarg,
#include "tool_util.h"
#include "tool_version.h"
#include "tool_cb_prg.h"
+#include "tool_hugehelp.h"
+#include "tool_getparam.h"
#include "terminal.h"
#include "memdebug.h" /* keep this as LAST include */
}
}
+#ifdef USE_MANUAL
+
+void inithelpscan(struct scan_ctx *ctx,
+ const char *trigger,
+ const char *arg,
+ const char *endarg)
+{
+ ctx->trigger = trigger;
+ ctx->tlen = strlen(trigger);
+ ctx->arg = arg;
+ ctx->flen = strlen(arg);
+ ctx->endarg = endarg;
+ ctx->elen = strlen(endarg);
+ DEBUGASSERT((ctx->elen < sizeof(ctx->rbuf)) ||
+ (ctx->flen < sizeof(ctx->rbuf)));
+ ctx->show = 0;
+ ctx->olen = 0;
+ memset(ctx->rbuf, 0, sizeof(ctx->rbuf));
+}
+
+bool helpscan(unsigned char *buf, size_t len, struct scan_ctx *ctx)
+{
+ size_t i;
+ for(i = 0; i < len; i++) {
+ if(!ctx->show) {
+ /* wait for the trigger */
+ memmove(&ctx->rbuf[0], &ctx->rbuf[1], ctx->tlen - 1);
+ ctx->rbuf[ctx->tlen - 1] = buf[i];
+ if(!memcmp(ctx->rbuf, ctx->trigger, ctx->tlen))
+ ctx->show++;
+ continue;
+ }
+ /* past the trigger */
+ if(ctx->show == 1) {
+ memmove(&ctx->rbuf[0], &ctx->rbuf[1], ctx->flen - 1);
+ ctx->rbuf[ctx->flen - 1] = buf[i];
+ if(!memcmp(ctx->rbuf, ctx->arg, ctx->flen)) {
+ /* match, now output until endarg */
+ fputs(&ctx->arg[1], stdout);
+ ctx->show++;
+ }
+ continue;
+ }
+ /* show until the end */
+ memmove(&ctx->rbuf[0], &ctx->rbuf[1], ctx->elen - 1);
+ ctx->rbuf[ctx->elen - 1] = buf[i];
+ if(!memcmp(ctx->rbuf, ctx->endarg, ctx->elen))
+ return FALSE;
+
+ if(buf[i] == '\n') {
+ DEBUGASSERT(ctx->olen < sizeof(ctx->obuf));
+ ctx->obuf[ctx->olen++] = 0;
+ ctx->olen = 0;
+ puts(ctx->obuf);
+ }
+ else
+ ctx->obuf[ctx->olen++] = buf[i];
+ }
+ return TRUE;
+}
+
+#endif
void tool_help(char *category)
{
unsigned int cols = get_terminal_columns();
- puts("Usage: curl [options...] <url>");
/* If no category was provided */
if(!category) {
const char *category_note = "\nThis is not the full help; this "
"menu is split into categories.\nUse \"--help category\" to get "
"an overview of all categories, which are:";
- const char *category_note2 = "For all options use the manual"
- " or \"--help all\".";
+ const char *category_note2 =
+ "Use \"--help all\" to list all options"
+#ifdef USE_MANUAL
+ "\nUse \"--help [option]\" to view documentation for a given option"
+#endif
+ ;
+ puts("Usage: curl [options...] <url>");
print_category(CURLHELP_IMPORTANT, cols);
puts(category_note);
get_categories_list(cols);
/* Lets handle the string "category" differently to not print an errormsg */
else if(curl_strequal(category, "category"))
get_categories();
+ else if(category[0] == '-') {
+#ifdef USE_MANUAL
+ /* command line option help */
+ const struct LongShort *a = NULL;
+ if(category[1] == '-') {
+ char *lookup = &category[2];
+ bool noflagged = FALSE;
+ if(!strncmp(lookup, "no-", 3)) {
+ lookup += 3;
+ noflagged = TRUE;
+ }
+ a = findlongopt(lookup);
+ if(noflagged && (ARGTYPE(a->desc) != ARG_BOOL))
+ /* a --no- prefix for a non-boolean is not specifying a proper
+ option */
+ a = NULL;
+ }
+ else if(!category[2])
+ a = findshortopt(category[1]);
+ if(!a) {
+ fprintf(tool_stderr, "Incorrect option name to show help for,"
+ " see curl -h\n");
+ }
+ else {
+ char cmdbuf[80];
+ if(a->letter != ' ')
+ msnprintf(cmdbuf, sizeof(cmdbuf), "\n -%c, --", a->letter);
+ else if(a->desc & ARG_NO)
+ msnprintf(cmdbuf, sizeof(cmdbuf), "\n --no-%s", a->lname);
+ else
+ msnprintf(cmdbuf, sizeof(cmdbuf), "\n %s", category);
+ if(a->cmd == C_XATTR)
+ /* this is the last option, which then ends when FILES starts */
+ showhelp("\nALL OPTIONS\n", cmdbuf, "\nFILES");
+ else
+ showhelp("\nALL OPTIONS\n", cmdbuf, "\n -");
+ }
+#else
+ fprintf(tool_stderr, "Cannot comply. "
+ "This curl was built without built-in manual\n");
+#endif
+ }
/* Otherwise print category and handle the case if the cat was not found */
else if(get_category_content(category, cols)) {
puts("Unknown category provided, here is a list of all categories:\n");
void tool_help(char *category);
void tool_list_engines(void);
void tool_version_info(void);
+struct scan_ctx {
+ const char *trigger;
+ size_t tlen;
+ const char *arg;
+ size_t flen;
+ const char *endarg;
+ size_t elen;
+ size_t olen;
+ char rbuf[40];
+ char obuf[80];
+ unsigned char show; /* start as at 0.
+ trigger match moves it to 1
+ arg match moves it to 2
+ endarg stops the search */
+};
+void inithelpscan(struct scan_ctx *ctx, const char *trigger,
+ const char *arg, const char *endarg);
+bool helpscan(unsigned char *buf, size_t len, struct scan_ctx *ctx);
struct helptxt {
const char *opt;
void hugehelp(void)
{
- puts("This is a silly replacement for the actual file.");
+ puts("built-in manual was disabled at build-time");
+}
+
+void showhelp(const char *arg, const char *endarg)
+{
+ (void)arg;
+ (void)endarg;
+ hugehelp();
}
***************************************************************************/
#include "tool_setup.h"
+void showhelp(const char *trigger, const char *arg, const char *endarg);
+
#ifdef USE_MANUAL
void hugehelp(void);
#else
{"-H, --header <header/@file>",
"Pass custom header(s) to server",
CURLHELP_HTTP | CURLHELP_IMAP | CURLHELP_SMTP},
- {"-h, --help <category>",
+ {"-h, --help <subject>",
"Get help for commands",
CURLHELP_IMPORTANT | CURLHELP_CURL},
{" --hostpubmd5 <md5>",
test1486.pl \
test1488.pl \
test1544.pl \
+ test1707.pl \
test971.pl
EXTRA_DIST = \
\
test1680 test1681 test1682 test1683 \
\
-test1700 test1701 test1702 test1703 test1704 test1705 test1706 \
+test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 \
+test1708 test1709 test1710 \
\
test1800 test1801 \
\
#
# Client-side
<client>
+<features>
+manual
+</features>
<server>
none
</server>
Usage: curl [options...] <url>
-d, --data <data> HTTP POST data
-f, --fail Fail fast with no output on HTTP errors
- -h, --help <category> Get help for commands
+ -h, --help <subject> Get help for commands
-o, --output <file> Write to file instead of stdout
-O, --remote-name Write output to file named as remote file
-i, --show-headers Show response headers in output
auth, connection, curl, deprecated, dns, file, ftp, global, http, imap, ldap,
output, pop3, post, proxy, scp, sftp, smtp, ssh, telnet, tftp, timeout, tls,
upload, verbose.
-For all options use the manual or "--help all".
+Use "--help all" to list all options
+Use "--help [option]" to view documentation for a given option
</stdout>
</verify>
</testcase>
0
</errorcode>
<stdout mode="text">
-Usage: curl [options...] <url>
Unknown category provided, here is a list of all categories:
auth Authentication methods
0
</errorcode>
<stdout mode="text">
-Usage: curl [options...] <url>
file: FILE protocol
--create-file-mode <mode> File mode for created files
-I, --head Show document info only
0
</errorcode>
<stdout mode="text">
-Usage: curl [options...] <url>
file: FILE protocol
--create-file-mode <mode> File mode for created files
-I, --head Show document info only
--- /dev/null
+<testcase>
+<info>
+<keywords>
+curl
+</keywords>
+</info>
+
+#
+# Client-side
+<client>
+<features>
+manual
+</features>
+<server>
+none
+</server>
+
+<name>
+Verify curl -h --insecure
+</name>
+
+<command type="perl">
+%SRCDIR/test1707.pl %CURL --insecure %LOGDIR/help%TESTNUMBER ../docs/cmdline-opts/curl.txt
+</command>
+</client>
+
+</testcase>
--- /dev/null
+<testcase>
+<info>
+<keywords>
+curl
+</keywords>
+</info>
+
+#
+# Client-side
+<client>
+<features>
+manual
+</features>
+<server>
+none
+</server>
+
+<name>
+Verify curl -h -F
+</name>
+
+<command type="perl">
+%SRCDIR/test1707.pl %CURL -F %LOGDIR/help%TESTNUMBER ../docs/cmdline-opts/curl.txt
+</command>
+</client>
+
+</testcase>
--- /dev/null
+<testcase>
+<info>
+<keywords>
+curl
+</keywords>
+</info>
+
+#
+# Client-side
+<client>
+<features>
+manual
+</features>
+<server>
+none
+</server>
+
+<name>
+Verify curl -h --badone
+</name>
+
+<command>
+-h --badone
+</command>
+</client>
+
+<verify>
+<stderr mode="text">
+Incorrect option name to show help for, see curl -h
+</stderr>
+</verify>
+</testcase>
--- /dev/null
+<testcase>
+<info>
+<keywords>
+curl
+</keywords>
+</info>
+
+#
+# Client-side
+<client>
+<features>
+manual
+</features>
+<server>
+none
+</server>
+
+<name>
+Verify curl -h --no-clobber
+</name>
+
+<command type="perl">
+%SRCDIR/test1707.pl %CURL --no-clobber %LOGDIR/help%TESTNUMBER ../docs/cmdline-opts/curl.txt
+</command>
+</client>
+
+</testcase>
--- /dev/null
+#!/usr/bin/env perl
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+#
+# This script grew out of help from Przemyslaw Iskra and Balint Szilakszi
+# a late evening in the #curl IRC channel.
+#
+
+use strict;
+use warnings;
+
+my $curl = shift @ARGV;
+my $opt = shift @ARGV;
+my $output = shift @ARGV;
+my $txt = shift @ARGV;
+
+my $longopt;
+my $shortopt;
+if($opt =~ /^--/) {
+ $longopt = $opt;
+}
+else {
+ $shortopt = $opt;
+}
+
+# first run the help command
+system("$curl -h $opt > $output");
+my @curlout;
+open(O, "<$output");
+push @curlout, <O>;
+close(O);
+
+# figure out the short+long option combo using -h all*/
+open(C, "$curl -h all|");
+if($shortopt) {
+ while(<C>) {
+ if(/^ +$opt, ([^ ]*)/) {
+ $longopt = $1;
+ last;
+ }
+ }
+}
+else {
+ while(<C>) {
+ my $f = $_;
+ if(/ $opt /) {
+ if($f =~ /^ *(-(.)), $longopt/) {
+ $shortopt = $1;
+ }
+ last;
+ }
+ }
+}
+close(C);
+
+my $fullopt;
+if($shortopt) {
+ $fullopt = "$shortopt, $longopt";
+}
+else {
+ $fullopt = $longopt;
+}
+
+open(R, "<$txt");
+my $show = 0;
+my @txtout;
+while(<R>) {
+ if(/^ $fullopt/) {
+ $show = 1;
+ }
+ elsif(/^ -/ && $show) {
+ last;
+ }
+ if($show) {
+ push @txtout, $_;
+ }
+}
+close(R);
+
+my $error;
+if(scalar(@curlout) != scalar(@txtout)) {
+ printf "curl -h $opt is %d lines, $txt says %d lines\n",
+ scalar(@curlout), scalar(@txtout);
+ $error++;
+}
+else {
+ # same size, compare line by line
+ for my $i (0 .. $#curlout) {
+ # trim CRLF from the data
+ $curlout[$i] =~ s/[\r\n]//g;
+ $txtout[$i] =~ s/[\r\n]//g;
+ if($curlout[$i] ne $txtout[$i]) {
+ printf "Line %d\n", $i;
+ printf "-h : %s\n", $curlout[$i];
+ printf "file : %s\n", $txtout[$i];
+ $error++;
+ }
+ }
+}
+exit $error;