mirror of
https://github.com/openssl/openssl.git
synced 2024-12-27 06:21:43 +08:00
fecb3aae22
Reviewed-by: Tomas Mraz <tomas@openssl.org> Release: yes
344 lines
12 KiB
Plaintext
344 lines
12 KiB
Plaintext
=pod
|
|
|
|
=head1 NAME
|
|
|
|
OPTIONS, OPT_PAIR, OPT_COMMON, OPT_ERR, OPT_EOF, OPT_HELP,
|
|
opt_init, opt_progname, opt_appname, opt_getprog, opt_help,
|
|
opt_begin, opt_next, opt_flag, opt_arg, opt_unknown, opt_cipher,
|
|
opt_cipher_any, opt_cipher_silent, opt_md,
|
|
opt_int, opt_int_arg, opt_long, opt_ulong, opt_intmax, opt_uintmax,
|
|
opt_format, opt_isdir, opt_string, opt_pair,
|
|
opt_num_rest, opt_rest, opt_legacy_okay
|
|
- Option parsing for commands and tests
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
#include "opt.h"
|
|
|
|
typedef struct { ... } OPTIONS;
|
|
typedef struct { ... } OPT_PAIR;
|
|
#define OPT_COMMON
|
|
#define OPT_ERR
|
|
#define OPT_EOF
|
|
#define OPT_HELP
|
|
|
|
char *opt_init(int argc, char **argv, const OPTIONS *o);
|
|
char *opt_progname(const char *argv0);
|
|
char *opt_appname(const char *argv0);
|
|
char *opt_getprog(void);
|
|
void opt_help(const OPTIONS *list);
|
|
|
|
void opt_begin(void);
|
|
int opt_next(void);
|
|
char *opt_flag(void);
|
|
char *opt_arg(void);
|
|
char *opt_unknown(void);
|
|
int opt_cipher(const char *name, EVP_CIPHER **cipherp);
|
|
int opt_cipher_any(const char *name, EVP_CIPHER **cipherp);
|
|
int opt_cipher_silent(const char *name, EVP_CIPHER **cipherp);
|
|
int opt_md(const char *name, EVP_MD **mdp);
|
|
|
|
int opt_int(const char *value, int *result);
|
|
int opt_int_arg(void);
|
|
int opt_long(const char *value, long *result);
|
|
int opt_ulong(const char *value, unsigned long *result);
|
|
int opt_intmax(const char *value, intmax_t *result);
|
|
int opt_uintmax(const char *value, uintmax_t *result);
|
|
|
|
int opt_format(const char *s, unsigned long flags, int *result);
|
|
int opt_isdir(const char *name);
|
|
int opt_string(const char *name, const char **options);
|
|
int opt_pair(const char *name, const OPT_PAIR* pairs, int *result);
|
|
|
|
int opt_num_rest(void);
|
|
char **opt_rest(void);
|
|
|
|
int opt_legacy_okay(void);
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
The functions on this page provide a common set of option-parsing for
|
|
the OpenSSL command and the internal test programs.
|
|
It is intended to be used like the standard getopt(3) routine, except
|
|
that multi-character flag names are supported, and a variety of parsing
|
|
and other utility functions are also provided.
|
|
|
|
Programs that use this should make sure to set the appropriate C<-I>
|
|
flag.
|
|
|
|
These routines expect a global B<BIO> named B<bio_err> to point to
|
|
the equivalent of B<stderr>. This is already done in the OpenSSL
|
|
application.
|
|
|
|
=head2 Data Types
|
|
|
|
Each program should define, near the main() routine, an enumeration
|
|
that is the set of options the program accepts. For example:
|
|
|
|
typedef enum OPTION_choice {
|
|
OPT_COMMON,
|
|
OPT_YES, OPT_NAME, OPT_COUNT, OPT_OFILE,
|
|
...
|
|
} OPTION_CHOICE;
|
|
|
|
The first two lines must appear exactly as shown.
|
|
OPT_COMMON is a macro that expands to C<OPT_ERR = -1, OPT_EOF = 0, OPT_HELP>.
|
|
In addition to defining symbolic names for the constants that opt_next()
|
|
returns, it also helps guarantee that every command has a C<-help> option.
|
|
The third line is a sample
|
|
set of flags, and the closing C<typedef> name is used for error-checking
|
|
as discussed below.
|
|
By declaring the variable as an C<OPTION_CHOICE>, with the right warning
|
|
flags, the compiler could check that all specified options are handled.
|
|
|
|
The B<OPTIONS> C<typedef> specifies an option: what type of argument
|
|
it takes (if any), and an optional "help" string. It is a C<struct>
|
|
containing these fields:
|
|
|
|
const char *name;
|
|
int retval;
|
|
int valtype;
|
|
const char *helpstr;
|
|
|
|
The B<name> is the name of the option that the user would type. Options
|
|
are words prefaced with a minus sign. If the user uses two minus signs,
|
|
this is also accepted for compatibility with other GNU software. Some
|
|
names are special, and are described below.
|
|
|
|
The B<retval> is the value to return if the option is found. It should be
|
|
one of the choices in the enumeration above.
|
|
|
|
The B<valtype> defines what the option's parameter must be. It should
|
|
be chosen from the following set:
|
|
|
|
\0 No value
|
|
'-' No value
|
|
's' A text string
|
|
'/' A directory
|
|
'<' Name of file to open for input
|
|
'>' Name of file to open for output
|
|
'n' A signed number that fits in the C<int> type
|
|
'p' A positive number that fits in the C<int> type
|
|
'N' A nonnegative number that fits in the C<int> type
|
|
'M' A signed number that fits in the C<intmax_t> type
|
|
'U' An unsigned number that fits in the C<uintmax_t> type
|
|
'l' A signed number that fits in the C<long> type
|
|
'u' An unsigned number that fits in the C<unsigned long> type
|
|
'c' File in PEM, DER, or S/MIME format
|
|
'F' A file in PEM or DER format
|
|
'E' Like 'F' but also allows ENGINE
|
|
'f' Any file format
|
|
|
|
The B<helpstr> is what to display when the user uses the help option,
|
|
which should be C<"help">.
|
|
|
|
A program should declare its options right after the enumeration,
|
|
and should follow the ordering of the enumeration as this helps
|
|
readability and maintainability:
|
|
|
|
static OPTIONS my_options[] = {
|
|
{"help", OPT_HELP, '-', "Display this summary"},
|
|
{"yes", OPT_YES, '-', "Print an affirmative reply"},
|
|
{"count", OPT_COUNT, 'p', "Repeat count"},
|
|
{"output" OPT_OFILE, '>', "Output file; default is stdout"},
|
|
{NULL}
|
|
};
|
|
|
|
Note that the B<OPT_HELP> option is explicitly listed, and the list ends with
|
|
an entry of all-null's. The other two special options, B<OPT_ERR> and B<OPT_EOF>
|
|
should not appear in the array.
|
|
|
|
If the help string is too long to fit into one line, it may be continued
|
|
on multiple lines; each entry should use B<OPT_MORE_STR>, like this:
|
|
|
|
{"output" OPT_OFILE, '>', "Output file; default is stdout"},
|
|
{OPT_MORE_STR, 0, 0,
|
|
"This flag is not really needed on Unix systems"},
|
|
{OPT_MORE_STR, 0, 0,
|
|
"(Unix and descendents for the win!)"}
|
|
|
|
Each subsequent line will be indented the correct amount.
|
|
|
|
By default, the help display will include a standard prolog:
|
|
|
|
Usage: PROGRAM [options]
|
|
Valid options are:
|
|
...detailed list of options...
|
|
|
|
Sometimes there are parameters that should appear in the synopsis.
|
|
Use B<OPT_HELP_STR> as the first entry in your array:
|
|
|
|
{OPT_HELP_STR, 1, '-', Usage: %s [options] [text...]\n"}
|
|
|
|
The B<retval> and B<valtype> are ignored, and the B<helpstr> should
|
|
follow the general construction as shown. The C<%s> will get the program
|
|
name.
|
|
|
|
If a command has a large set of options, it can be useful to break them
|
|
into sections. Use the macro B<OPT_SECTION> or B<OPT_SECTION_STR>
|
|
to indicate this. The two lines below are equivalent:
|
|
|
|
OPT_SECTION("Validation"),
|
|
{OPT_SECTION_STR, 1, '-', "Validation options:\n"},
|
|
|
|
In addition to providing help about options, you can provide a description
|
|
of the parameters a command takes. These should appear at the end of
|
|
the options and are indicated by using B<OPT_PARAM_STR> or the
|
|
B<OPT_PARAMETERS> macro:
|
|
|
|
OPT_PARAMETERS()
|
|
{OPT_PARAM_STR, 1, '-', "Parameters:\n"}
|
|
|
|
Every "option" after after this should contain the parameter and
|
|
the help string:
|
|
|
|
{"text", 0, 0, "Words to display (optional)"},
|
|
|
|
=head2 Functions
|
|
|
|
The opt_init() function takes the I<argc> and I<argv> arguments given to main()
|
|
and a pointer I<o> to the list of options. It returns the simple program
|
|
name, as defined by opt_progname().
|
|
|
|
The opt_progname() function takes the full pathname C<argv[0]> in its I<arg0>
|
|
parameter and returns
|
|
the simple short name of the executable, to be used for error messages and
|
|
the like.
|
|
|
|
The opt_appname() function takes in its I<argv0> parameter
|
|
the "application" name (such
|
|
as the specific command from L<openssl(1)> and appends it to the program
|
|
name. This function should only be called once.
|
|
|
|
The opt_getprog() function returns the value set by opt_appname().
|
|
|
|
The opt_help() function takes a list of option definitions and prints a
|
|
nicely-formatted output.
|
|
|
|
The opt_begin() function, which is called automatically by opt_init(),
|
|
can be used to reset the option parsing loop.
|
|
|
|
The opt_next() function is called, once opt_init() has been called,
|
|
in a loop to fetch each option in turn. It returns -1, or B<OPT_EOF> when the
|
|
end of arguments has been reached. This is typically done like this:
|
|
|
|
prog = opt_init(argc, argv, my_options);
|
|
while ((o = opt_next()) != OPT_EOF) {
|
|
switch (o) {
|
|
case OPT_EOF:
|
|
case OPT_ERR:
|
|
opthelp:
|
|
fprintf(stderr, "%s: Use -help for summary\n", prog);
|
|
exit(1);
|
|
case OPT_HELP:
|
|
opt_help(my_options);
|
|
exit(0);
|
|
...other options...
|
|
}
|
|
}
|
|
|
|
Within the option parsing loop, the following functions may be called.
|
|
|
|
The opt_flag() function returns the most recent option name
|
|
including the preceding C<->.
|
|
|
|
The opt_arg() function returns the option's argument value, if there is one.
|
|
|
|
The opt_unknown() function returns the unknown option.
|
|
In an option list, there can be at most one option with the empty string.
|
|
This is a "wildcard" or "unknown" option. For example, it allows an
|
|
option to be be taken as digest algorithm, like C<-sha1>. The function
|
|
opt_md() takes the specified I<name> and fills in the digest into I<mdp>.
|
|
The functions opt_cipher(), opt_cipher_any() and opt_cipher_silent()
|
|
each takes the specified I<name> and fills in the cipher into I<cipherp>.
|
|
The function opt_cipher() only accepts ciphers which are not
|
|
AEAD and are not using XTS mode. The functions opt_cipher_any() and
|
|
opt_cipher_silent() accept any cipher, the latter not emitting an error
|
|
if the cipher is not located.
|
|
|
|
There are a several useful functions for parsing numbers. These are
|
|
opt_int(), opt_long(), opt_ulong(), opt_intmax(), and opt_uintmax(). They all
|
|
take C<0x> to mean hexadecimal and C<0> to mean octal, and will do the
|
|
necessary range-checking. They return 1 if successful and fill in the
|
|
C<result> pointer with the value, or 0 on error. Note that opt_next()
|
|
will also do range-check on the argument if the appropriate B<valtype>
|
|
field is specified for the option. This means that error-checking inside
|
|
the C<switch> C<case> can often be elided.
|
|
|
|
The opt_int_arg() function is a convenience abbreviation to opt_int().
|
|
It parses and returns an integer, assuming its range has been checked before.
|
|
|
|
The opt_format() function takes a string value,
|
|
such as used with the B<-informat> or similar option, and fills
|
|
the value from the constants in F<fmt.h> file.
|
|
|
|
The opt_isdir() function returns 1 if the specified I<name> is
|
|
a directory, or 0 if not.
|
|
|
|
The opt_string() function checks that I<name> appears in the
|
|
NULL-terminated array of strings. It returns 1 if found,
|
|
or prints a diagnostic and returns 0 if not.
|
|
|
|
The opt_pair() function takes a list of I<pairs>, each of which
|
|
has a text name and an integer. The specified I<name> is
|
|
found on the list, it puts the index in I<*result>, and returns
|
|
1. If not found, it returns 0.
|
|
|
|
The following functions can be used after processing all the options.
|
|
|
|
The opt_num_rest() function returns what is left.
|
|
|
|
The opt_rest() function returns a pointer to the first non-option.
|
|
If there were no parameters, it will point to the NULL that is
|
|
at the end of the standard I<argv> array.
|
|
|
|
The opt_legacy_okay() function returns true if no options have been
|
|
specified that would preclude using legacy code paths. Currently,
|
|
the various provider options preclude legacy operation. This means,
|
|
for example, that specifying both B<-provider> and B<-engine> in the
|
|
same command line will not work as expected.
|
|
|
|
=head2 Common Options
|
|
|
|
There are a few groups of options that are common to many OpenSSL programs.
|
|
These are handled with sets of macros that define common option names
|
|
and common code to handle them. The categories are identified by a
|
|
letter:
|
|
|
|
V Validation
|
|
X Extended certificate
|
|
S TLS/SSL
|
|
R Random state
|
|
|
|
The B<OPT_x_ENUM> macro is used to define the numeration values, where B<x>
|
|
is one of the letters above. The B<OPT_x_OPTIONS> macro is used to
|
|
list the set of common options, and the B<OPT_x_CASES> is used in
|
|
the C<switch> statement.
|
|
|
|
The common options are used throughout the sources for the OpenSSL commands.
|
|
They are also used with common descriptions when generating the
|
|
manpages, in the file F<doc/perlvars.pm>, which follow a similar naming
|
|
convention.
|
|
|
|
=head1 RETURN VALUES
|
|
|
|
Detailed above.
|
|
|
|
=head1 EXAMPLES
|
|
|
|
The best examples can be found in sources for the commands in the F<apps>
|
|
directory of the source tree.
|
|
A notable exception is F<apps/cmp.c> which uses this API, but does
|
|
things very differently.
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved.
|
|
|
|
Licensed under the Apache License 2.0 (the "License"). You may not use this
|
|
file except in compliance with the License. You can obtain a copy in the file
|
|
LICENSE in the source distribution or at
|
|
L<https://www.openssl.org/source/license.html>.
|
|
|
|
=cut
|