diff options
Diffstat (limited to 'doc/internal/man3/OPTIONS.pod')
-rw-r--r-- | doc/internal/man3/OPTIONS.pod | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/doc/internal/man3/OPTIONS.pod b/doc/internal/man3/OPTIONS.pod new file mode 100644 index 000000000000..dbdd39a2ee64 --- /dev/null +++ b/doc/internal/man3/OPTIONS.pod @@ -0,0 +1,343 @@ +=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-2024 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 |