+static void list_md_fn(const EVP_MD *m,
+ const char *from, const char *to, void *arg)
+{
+ if (m)
+ BIO_printf(arg, "%s\n", EVP_MD_name(m));
+ else {
+ if (!from)
+ from = "<undefined>";
+ if (!to)
+ to = "<undefined>";
+ BIO_printf((BIO *)arg, "%s => %s\n", from, to);
+ }
+}
+
+/* Unified enum for help and list commands. */
+typedef enum HELPLIST_CHOICE {
+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+ OPT_COMMANDS, OPT_DIGEST_COMMANDS,
+ OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS,
+ OPT_PK_ALGORITHMS, OPT_DISABLED
+} HELPLIST_CHOICE;
+
+OPTIONS list_options[] = {
+ {"help", OPT_HELP, '-', "Display this summary"},
+ {"commands", OPT_COMMANDS, '-', "List of standard commands"},
+ {"digest-commands", OPT_DIGEST_COMMANDS, '-',
+ "List of message digest commands"},
+ {"digest-algorithms", OPT_DIGEST_ALGORITHMS, '-',
+ "List of message digest algorithms"},
+ {"cipher-commands", OPT_CIPHER_COMMANDS, '-', "List of cipher commands"},
+ {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-',
+ "List of cipher algorithms"},
+ {"public-key-algorithms", OPT_PK_ALGORITHMS, '-',
+ "List of public key algorithms"},
+ {"disabled", OPT_DISABLED, '-',
+ "List of disabled features"},
+ {NULL}
+};
+
+int list_main(int argc, char **argv)
+{
+ char *prog;
+ HELPLIST_CHOICE o;
+ int done = 0;
+
+ prog = opt_init(argc, argv, list_options);
+ while ((o = opt_next()) != OPT_EOF) {
+ switch (o) {
+ case OPT_EOF: /* Never hit, but suppresses warning */
+ case OPT_ERR:
+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+ return 1;
+ case OPT_HELP:
+ opt_help(list_options);
+ break;
+ case OPT_COMMANDS:
+ list_type(FT_general);
+ break;
+ case OPT_DIGEST_COMMANDS:
+ list_type(FT_md);
+ break;
+ case OPT_DIGEST_ALGORITHMS:
+ EVP_MD_do_all_sorted(list_md_fn, bio_out);
+ break;
+ case OPT_CIPHER_COMMANDS:
+ list_type(FT_cipher);
+ break;
+ case OPT_CIPHER_ALGORITHMS:
+ EVP_CIPHER_do_all_sorted(list_cipher_fn, bio_out);
+ break;
+ case OPT_PK_ALGORITHMS:
+ list_pkey();
+ break;
+ case OPT_DISABLED:
+ list_disabled();
+ break;
+ }
+ done = 1;
+ }
+
+ if (!done) {
+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+ return 1;
+ }
+
+ return 0;
+}
+
+OPTIONS help_options[] = {
+ {"help", OPT_HELP, '-', "Display this summary"},
+ {NULL}
+};
+
+int help_main(int argc, char **argv)
+{
+ FUNCTION *fp;
+ int i, nl;
+ FUNC_TYPE tp;
+ char *prog;
+ HELPLIST_CHOICE o;
+
+ prog = opt_init(argc, argv, help_options);
+ while ((o = opt_next()) != OPT_EOF) {
+ switch (o) {
+ default:
+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+ return 1;
+ case OPT_HELP:
+ opt_help(help_options);
+ return 0;
+ }
+ }
+ argc = opt_num_rest();
+ argv = opt_rest();
+
+ if (argc != 0) {
+ BIO_printf(bio_err, "Usage: %s\n", prog);
+ return 1;
+ }
+
+ BIO_printf(bio_err, "\nStandard commands");
+ i = 0;
+ tp = FT_none;
+ for (fp = functions; fp->name != NULL; fp++) {
+ nl = 0;
+ if (((i++) % COLUMNS) == 0) {
+ BIO_printf(bio_err, "\n");
+ nl = 1;
+ }
+ if (fp->type != tp) {
+ tp = fp->type;
+ if (!nl)
+ BIO_printf(bio_err, "\n");
+ if (tp == FT_md) {
+ i = 1;
+ BIO_printf(bio_err,
+ "\nMessage Digest commands (see the `dgst' command for more details)\n");
+ } else if (tp == FT_cipher) {
+ i = 1;
+ BIO_printf(bio_err,
+ "\nCipher commands (see the `enc' command for more details)\n");
+ }
+ }
+ BIO_printf(bio_err, FORMAT, fp->name);
+ }
+ BIO_printf(bio_err, "\n\n");
+ return 0;
+}
+
+int exit_main(int argc, char **argv)
+{
+ return EXIT_THE_PROGRAM;
+}
+
+static void list_type(FUNC_TYPE ft)
+{
+ FUNCTION *fp;
+ int i = 0;
+
+ for (fp = functions; fp->name != NULL; fp++)
+ if (fp->type == ft) {
+ if ((i++ % COLUMNS) == 0)
+ BIO_printf(bio_out, "\n");
+ BIO_printf(bio_out, FORMAT, fp->name);
+ }
+ BIO_printf(bio_out, "\n");
+}