From f7878a0246f447acdf6d27ff141062b185d7b263 Mon Sep 17 00:00:00 2001 From: lohhiiccc Date: Fri, 10 Jul 2026 22:57:29 +0200 Subject: [PATCH] refactor: rework command dispacher --- includes/internal/cli/cli_handlers.h | 11 ++- includes/internal/{cmd => cli}/command.h | 12 +-- includes/internal/{cmd => cli}/digest_cmd.h | 46 +++++----- includes/internal/cli/dispatch.h | 6 ++ includes/internal/cli/global_cmd.h | 45 +++++++++ includes/internal/cli/option.h | 87 +++++------------- includes/internal/{ssl/ssl.h => cmd/digest.h} | 10 +- src/Makefile.am | 32 ++++--- src/cli/command_table.c | 16 ++++ src/cli/dispatch.c | 79 ++++++++++++++++ src/cli/handlers/digest/handle_help.c | 17 ++++ src/cli/handlers/{ => digest}/handle_p.c | 2 +- src/cli/handlers/{ => digest}/handle_q.c | 2 +- src/cli/handlers/{ => digest}/handle_r.c | 2 +- src/cli/handlers/{ => digest}/handle_s.c | 2 +- src/cli/handlers/{ => digest}/option_map.c | 2 +- src/cli/handlers/global/option_map.c | 12 +++ src/cli/handlers/handle_help.c | 17 ++-- src/cli/handlers/handle_version.c | 2 - src/cli/parse.c | 91 ------------------- src/cli/print_help.c | 20 ++++ src/cli/{version.c => print_version.c} | 0 src/cmd/command_table.c | 54 ----------- src/{ssl => cmd/digest}/digest.c | 2 +- src/{ssl => cmd/digest}/output.c | 2 +- src/cmd/{digest_run.c => digest/run.c} | 16 ++-- src/{ssl => cmd/digest}/run_file.c | 4 +- src/{ssl => cmd/digest}/run_stdin.c | 4 +- src/{ssl => cmd/digest}/run_string.c | 4 +- src/main.c | 35 +------ src/ssl_run.c | 56 ------------ 31 files changed, 307 insertions(+), 383 deletions(-) rename includes/internal/{cmd => cli}/command.h (59%) rename includes/internal/{cmd => cli}/digest_cmd.h (81%) create mode 100644 includes/internal/cli/dispatch.h create mode 100644 includes/internal/cli/global_cmd.h rename includes/internal/{ssl/ssl.h => cmd/digest.h} (54%) create mode 100644 src/cli/command_table.c create mode 100644 src/cli/dispatch.c create mode 100644 src/cli/handlers/digest/handle_help.c rename src/cli/handlers/{ => digest}/handle_p.c (79%) rename src/cli/handlers/{ => digest}/handle_q.c (79%) rename src/cli/handlers/{ => digest}/handle_r.c (79%) rename src/cli/handlers/{ => digest}/handle_s.c (83%) rename src/cli/handlers/{ => digest}/option_map.c (88%) create mode 100644 src/cli/handlers/global/option_map.c delete mode 100644 src/cli/parse.c create mode 100644 src/cli/print_help.c rename src/cli/{version.c => print_version.c} (100%) delete mode 100644 src/cmd/command_table.c rename src/{ssl => cmd/digest}/digest.c (96%) rename src/{ssl => cmd/digest}/output.c (98%) rename src/cmd/{digest_run.c => digest/run.c} (81%) rename src/{ssl => cmd/digest}/run_file.c (79%) rename src/{ssl => cmd/digest}/run_stdin.c (95%) rename src/{ssl => cmd/digest}/run_string.c (80%) delete mode 100644 src/ssl_run.c diff --git a/includes/internal/cli/cli_handlers.h b/includes/internal/cli/cli_handlers.h index f72dcd9..1264d59 100644 --- a/includes/internal/cli/cli_handlers.h +++ b/includes/internal/cli/cli_handlers.h @@ -3,11 +3,12 @@ #include -int cli_handle_help(const char *arg, void *config); +int cli_handle_help(const char *arg, void *config_void); int cli_handle_version(const char *arg, void *config); -int cli_handle_p(const char *arg, void *config); -int cli_handle_q(const char *arg, void *config); -int cli_handle_r(const char *arg, void *config); -int cli_handle_s(const char *arg, void *config); +int digest_handle_help(const char *arg, void *config); +int digest_handle_p(const char *arg, void *config); +int digest_handle_q(const char *arg, void *config); +int digest_handle_r(const char *arg, void *config); +int digest_handle_s(const char *arg, void *config); #endif diff --git a/includes/internal/cmd/command.h b/includes/internal/cli/command.h similarity index 59% rename from includes/internal/cmd/command.h rename to includes/internal/cli/command.h index 68d9923..c622770 100644 --- a/includes/internal/cmd/command.h +++ b/includes/internal/cli/command.h @@ -12,15 +12,15 @@ enum command_category { }; struct command_descriptor { - const char *name; - enum command_category category; - const struct option_descriptor *opts; - size_t nb_opts; - const void *impl; + const char *name; + enum command_category category; + const struct option_descriptor *opts; + size_t nb_opts; + const void *impl; int (*run)(int argc, char **argv, const struct command_descriptor *self); }; const struct command_descriptor *find_command(const char *name); -void print_commands(FILE *out); +void print_commands(FILE *out); #endif diff --git a/includes/internal/cmd/digest_cmd.h b/includes/internal/cli/digest_cmd.h similarity index 81% rename from includes/internal/cmd/digest_cmd.h rename to includes/internal/cli/digest_cmd.h index d7d3582..362587f 100644 --- a/includes/internal/cmd/digest_cmd.h +++ b/includes/internal/cli/digest_cmd.h @@ -5,32 +5,14 @@ #include #include "internal/cli/cli_handlers.h" -#include "internal/cmd/command.h" +#include "internal/cli/command.h" #define DIGEST_OPTION_LIST \ - X( \ - 'h', \ - "help", \ - no_argument, \ - cli_handle_help, \ - OPT_ARG_NONE, \ - "Display this help and exit", \ - 0 \ - ) \ - X( \ - 'V', \ - "version", \ - no_argument, \ - cli_handle_version, \ - OPT_ARG_NONE, \ - "Display version information and exit", \ - 0 \ - ) \ X( \ 'p', \ "stdin", \ no_argument, \ - cli_handle_p, \ + digest_handle_p, \ OPT_ARG_NONE, \ "Echo stdin to stdout and append checksum to output", \ 0 \ @@ -39,7 +21,7 @@ 'q', \ "quiet", \ no_argument, \ - cli_handle_q, \ + digest_handle_q, \ OPT_ARG_NONE, \ "Quiet mode: only print the digest", \ 0 \ @@ -48,7 +30,7 @@ 'r', \ "reverse", \ no_argument, \ - cli_handle_r, \ + digest_handle_r, \ OPT_ARG_NONE, \ "Reverse the output format (digest then filename)", \ 0 \ @@ -57,11 +39,29 @@ 's', \ "string", \ required_argument, \ - cli_handle_s, \ + digest_handle_s, \ OPT_ARG_STRING, \ "Hash a string", \ CLI_OPT_F_REPEATABLE \ + ) \ + X( \ + 'h', \ + "help", \ + no_argument, \ + digest_handle_help, \ + OPT_ARG_NONE, \ + "Display this help and exit", \ + 0 \ ) +// X( \ +// 'V', \ +// "version", \ +// no_argument, \ +// digest_handle_version, \ +// OPT_ARG_NONE, \ +// "Display version information and exit", \ +// 0 \ +// ) #undef X #define X(short_opt, long_opt, has_arg, handler, arg_type, desc, flags) + 1 diff --git a/includes/internal/cli/dispatch.h b/includes/internal/cli/dispatch.h new file mode 100644 index 0000000..3bcb462 --- /dev/null +++ b/includes/internal/cli/dispatch.h @@ -0,0 +1,6 @@ +#ifndef FT_SSL_CLI_DISPATCH_H +#define FT_SSL_CLI_DISPATCH_H + +int ft_ssl_dispatch(int argc, char **argv); + +#endif diff --git a/includes/internal/cli/global_cmd.h b/includes/internal/cli/global_cmd.h new file mode 100644 index 0000000..76f09cb --- /dev/null +++ b/includes/internal/cli/global_cmd.h @@ -0,0 +1,45 @@ +#ifndef FT_SSL_CMD_GLOBAL_H +#define FT_SSL_CMD_GLOBAL_H + +#include +#include + +#include "internal/cli/cli_handlers.h" + +#define GLOBAL_OPTION_LIST \ + X( \ + 'h', \ + "help", \ + no_argument, \ + cli_handle_help, \ + OPT_ARG_NONE, \ + "Display this help and exit", \ + 0 \ + ) \ + X( \ + 'v', \ + "version", \ + no_argument, \ + cli_handle_version, \ + OPT_ARG_NONE, \ + "Display version information and exit", \ + 0 \ + ) + +#undef X +#define X(short_opt, long_opt, has_arg, handler, arg_type, desc, flags) + 1 +enum { GLOBAL_OPT_LEN = (0 GLOBAL_OPTION_LIST) }; + +#undef X +#define X(short_opt, long_opt, has_arg, handler, arg_type, desc, flags) \ + + (1 * (has_arg == no_argument) \ + + (2 * (has_arg == required_argument) \ + + (3 * (has_arg == optional_argument)))) +enum { GLOBAL_OPTSTR_LEN = (2 GLOBAL_OPTION_LIST) }; +/* +2 for ':' to disable getopt error messages and \0 */ + +#undef X + +extern const struct option_descriptor g_global_opts[]; + +#endif diff --git a/includes/internal/cli/option.h b/includes/internal/cli/option.h index f6c1bc3..993e097 100644 --- a/includes/internal/cli/option.h +++ b/includes/internal/cli/option.h @@ -2,74 +2,31 @@ #define FT_SSL_OPT_H #include +#include -#define FT_SSL_OPTION_LIST \ - X( \ - 'h', \ - "help", \ - no_argument, \ - cli_handle_help, \ - OPT_ARG_NONE, \ - "Display this help and exit", \ - 0 \ - ) \ - X( \ - 'V', \ - "version", \ - no_argument, \ - cli_handle_version, \ - OPT_ARG_NONE, \ - "Display version information and exit", \ - 0 \ - ) \ - X( \ - 'p', \ - "stdin", \ - no_argument, \ - cli_handle_p, \ - OPT_ARG_NONE, \ - "Echo stdin to stdout and append checksum to output", \ - 0 \ - ) \ - X( \ - 'q', \ - "quiet", \ - no_argument, \ - cli_handle_q, \ - OPT_ARG_NONE, \ - "Quiet mode: only print the digest", \ - 0 \ - ) \ - X( \ - 'r', \ - "reverse", \ - no_argument, \ - cli_handle_r, \ - OPT_ARG_NONE, \ - "Reverse the output format (digest then filename)", \ - 0 \ - ) \ - X( \ - 's', \ - "string", \ - required_argument, \ - cli_handle_s, \ - OPT_ARG_STRING, \ - "Hash a string", \ - CLI_OPT_F_REPEATABLE \ - ) +#include "internal/cli/command.h" +#include "internal/cli/digest_cmd.h" -#undef X -#define X(short_opt, long_opt, has_arg, handler, arg_type, desc, flags) + 1 -enum { FT_SSL_OPT_LEN = (0 FT_SSL_OPTION_LIST ) }; -#undef X -#define X(short_opt, long_opt, has_arg, handler, arg_type, desc, flags) \ - + (1 * (has_arg == no_argument) \ - + (2 * (has_arg == required_argument) \ - + (3 * (has_arg == optional_argument)))) -enum { FT_SSL_OPTSTR_LEN = (2 FT_SSL_OPTION_LIST) }; -/* +2 for ':' to disable getopt error messages and \0 */ +/* Forward-declare all digest algo globals */ +#define DIGEST_ALGO(lower, ds, bs) extern const struct digest_algo g_##lower; +#include +#undef DIGEST_ALGO + +static const struct command_descriptor g_commands[] = { + /* Digest commands */ +#define DIGEST_ALGO(lower, ds, bs) \ + { #lower, CMD_DIGEST, g_digest_opts, DIGEST_OPT_LEN, &g_##lower, digest_run }, +#include +#undef DIGEST_ALGO + /* Cipher commands (not yet implemented) */ + { "base64", CMD_CIPHER, NULL, 0, NULL, NULL }, + { "des", CMD_CIPHER, NULL, 0, NULL, NULL }, + { "des-ecb", CMD_CIPHER, NULL, 0, NULL, NULL }, + { "des-cbc", CMD_CIPHER, NULL, 0, NULL, NULL }, + /* Sentinel */ + { NULL, 0, NULL, 0, NULL, NULL } +}; void print_usage(const char *prog); diff --git a/includes/internal/ssl/ssl.h b/includes/internal/cmd/digest.h similarity index 54% rename from includes/internal/ssl/ssl.h rename to includes/internal/cmd/digest.h index a96b1d2..8d6a072 100644 --- a/includes/internal/ssl/ssl.h +++ b/includes/internal/cmd/digest.h @@ -1,5 +1,5 @@ -#ifndef FT_SSL_SSL_H -#define FT_SSL_SSL_H +#ifndef FT_SSL_CMD_DIGEST_ENGINE_H +#define FT_SSL_CMD_DIGEST_ENGINE_H #include @@ -8,9 +8,9 @@ #define MAX_DIGEST_SIZE 64 #define READ_BUFSIZE 4096 -int run_string(const struct digest_config *config, const char *s); -int run_file(const struct digest_config *config, const char *path); -int run_stdin(const struct digest_config *config); +int digest_run_string(const struct digest_config *config, const char *s); +int digest_run_file(const struct digest_config *config, const char *path); +int digest_run_stdin(const struct digest_config *config); int digest_stream(const struct digest_config *config, int fd, const char *label, int show_algo, int echo); void print_digest(const struct digest_config *config, const uint8_t *digest, diff --git a/src/Makefile.am b/src/Makefile.am index 2343f9c..66532ed 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,21 +41,25 @@ FORCE: ft_ssl_SOURCES = \ main.c \ - cmd/command_table.c \ - cmd/digest_run.c \ - ssl/run_stdin.c \ - ssl/run_string.c \ - ssl/run_file.c \ - ssl/digest.c \ - ssl/output.c \ - cli/version.c \ - cli/handlers/option_map.c \ - cli/handlers/handle_help.c \ + cli/dispatch.c \ + cli/command_table.c \ + cli/print_version.c \ + cli/print_help.c \ cli/handlers/handle_version.c \ - cli/handlers/handle_p.c \ - cli/handlers/handle_q.c \ - cli/handlers/handle_r.c \ - cli/handlers/handle_s.c + cli/handlers/handle_help.c \ + cli/handlers/global/option_map.c \ + cli/handlers/digest/option_map.c \ + cli/handlers/digest/handle_help.c \ + cli/handlers/digest/handle_p.c \ + cli/handlers/digest/handle_q.c \ + cli/handlers/digest/handle_r.c \ + cli/handlers/digest/handle_s.c \ + cmd/digest/run.c \ + cmd/digest/run_stdin.c \ + cmd/digest/run_string.c \ + cmd/digest/run_file.c \ + cmd/digest/digest.c \ + cmd/digest/output.c ft_ssl_CPPFLAGS = \ -I $(top_srcdir)/includes \ diff --git a/src/cli/command_table.c b/src/cli/command_table.c new file mode 100644 index 0000000..941d031 --- /dev/null +++ b/src/cli/command_table.c @@ -0,0 +1,16 @@ +#include + +#include "internal/cli/option.h" + + +const struct command_descriptor * +find_command(const char *name) +{ + const struct command_descriptor *cmd; + + for (cmd = g_commands; NULL != cmd->name; cmd++) + if (0 == strcmp(cmd->name, name)) + return cmd; + return NULL; +} + diff --git a/src/cli/dispatch.c b/src/cli/dispatch.c new file mode 100644 index 0000000..9aac2aa --- /dev/null +++ b/src/cli/dispatch.c @@ -0,0 +1,79 @@ +#include +#include +#include + +#include + +#include "internal/cli/command.h" +#include "internal/cli/dispatch.h" +#include "internal/cli/global_cmd.h" +#include "version_gen.h" + +/* Forward declarations */ +static int find_subcommand_index(int argc, char **argv); +static enum cli_code parse_global_options(char **argv, int sub_idx); +static int dispatch_command(int argc, char **argv, int sub_idx); +/* ------------------- */ + +int +ft_ssl_dispatch(int argc, char **argv) +{ + int sub_idx; + enum cli_code ret; + + sub_idx = find_subcommand_index(argc, argv); + ret = parse_global_options(argv, sub_idx); + if (CLI_SUCCESS != ret) + return ((int)CLI_ERROR == ret) ? 2 : EXIT_SUCCESS; + return dispatch_command(argc, argv, sub_idx); +} + +static int +find_subcommand_index(int argc, char **argv) +{ + int i; + + for (i = 1; i < argc; i++) + if ('-' != argv[i][0]) + return i; + return argc; +} + +static enum cli_code +parse_global_options(char **argv, int sub_idx) +{ + char opt_str[GLOBAL_OPTSTR_LEN + 1]; + struct option long_opts[GLOBAL_OPT_LEN + 1]; + + return cli_parse(sub_idx, argv, NULL, g_global_opts, GLOBAL_OPT_LEN, + opt_str, long_opts); +} + +static int +dispatch_command(int argc, char **argv, int sub_idx) +{ + const struct command_descriptor *cmd; + int ret; + + if (sub_idx >= argc) + { + print_commands(stderr); + return 2; + } + cmd = find_command(argv[sub_idx]); + if (NULL == cmd) + { + fprintf(stderr, "%s: Error: %s is an invalid command.\n", + g_prog_name, argv[sub_idx]); + print_commands(stderr); + return 2; + } + if (NULL == cmd->run) + { + fprintf(stderr, "%s: %s: not yet implemented\n", + g_prog_name, argv[sub_idx]); + return 2; + } + ret = cmd->run(argc - sub_idx, argv + sub_idx, cmd); + return ((int)CLI_ERROR == ret) ? 2 : EXIT_SUCCESS; +} diff --git a/src/cli/handlers/digest/handle_help.c b/src/cli/handlers/digest/handle_help.c new file mode 100644 index 0000000..2aaccad --- /dev/null +++ b/src/cli/handlers/digest/handle_help.c @@ -0,0 +1,17 @@ +#include +#include + +#include "compiler.h" +#include "ft_ssl.h" +#include "internal/cli/digest_cmd.h" +#include "version_gen.h" + +int +digest_handle_help(__unused const char *arg, void *config_void) +{ + struct digest_config *config = (struct digest_config *)config_void; + + printf("Usage: %s %s [OPTIONS] [FILE...]\n\n", g_prog_name, config->cmd_name); + cli_print_options(g_digest_opts, DIGEST_OPT_LEN, cli_arg_type_to_str); + return CLI_EXIT_SUCCESS; +} diff --git a/src/cli/handlers/handle_p.c b/src/cli/handlers/digest/handle_p.c similarity index 79% rename from src/cli/handlers/handle_p.c rename to src/cli/handlers/digest/handle_p.c index a79c3a2..5c243d6 100644 --- a/src/cli/handlers/handle_p.c +++ b/src/cli/handlers/digest/handle_p.c @@ -4,7 +4,7 @@ #include "internal/cli/cli_handlers.h" int -cli_handle_p(__unused const char *arg, void *config_void) +digest_handle_p(__unused const char *arg, void *config_void) { struct digest_config *config = (struct digest_config *)config_void; diff --git a/src/cli/handlers/handle_q.c b/src/cli/handlers/digest/handle_q.c similarity index 79% rename from src/cli/handlers/handle_q.c rename to src/cli/handlers/digest/handle_q.c index a22af3e..414bac8 100644 --- a/src/cli/handlers/handle_q.c +++ b/src/cli/handlers/digest/handle_q.c @@ -4,7 +4,7 @@ #include "internal/cli/cli_handlers.h" int -cli_handle_q(__unused const char *arg, void *config_void) +digest_handle_q(__unused const char *arg, void *config_void) { struct digest_config *config = (struct digest_config *)config_void; diff --git a/src/cli/handlers/handle_r.c b/src/cli/handlers/digest/handle_r.c similarity index 79% rename from src/cli/handlers/handle_r.c rename to src/cli/handlers/digest/handle_r.c index a529712..7415e78 100644 --- a/src/cli/handlers/handle_r.c +++ b/src/cli/handlers/digest/handle_r.c @@ -4,7 +4,7 @@ #include "internal/cli/cli_handlers.h" int -cli_handle_r(__unused const char *arg, void *config_void) +digest_handle_r(__unused const char *arg, void *config_void) { struct digest_config *config = (struct digest_config *)config_void; diff --git a/src/cli/handlers/handle_s.c b/src/cli/handlers/digest/handle_s.c similarity index 83% rename from src/cli/handlers/handle_s.c rename to src/cli/handlers/digest/handle_s.c index bc2302e..850c7e8 100644 --- a/src/cli/handlers/handle_s.c +++ b/src/cli/handlers/digest/handle_s.c @@ -2,7 +2,7 @@ #include "internal/cli/cli_handlers.h" int -cli_handle_s(const char *arg, void *config_void) +digest_handle_s(const char *arg, void *config_void) { struct digest_config *config = (struct digest_config *)config_void; diff --git a/src/cli/handlers/option_map.c b/src/cli/handlers/digest/option_map.c similarity index 88% rename from src/cli/handlers/option_map.c rename to src/cli/handlers/digest/option_map.c index 3f42467..318ca07 100644 --- a/src/cli/handlers/option_map.c +++ b/src/cli/handlers/digest/option_map.c @@ -1,4 +1,4 @@ -#include "internal/cmd/digest_cmd.h" +#include "internal/cli/digest_cmd.h" #undef X #define X(short_opt, long_opt, has_arg, handler, arg_type, desc, flags) \ diff --git a/src/cli/handlers/global/option_map.c b/src/cli/handlers/global/option_map.c new file mode 100644 index 0000000..c764050 --- /dev/null +++ b/src/cli/handlers/global/option_map.c @@ -0,0 +1,12 @@ +#include "internal/cli/global_cmd.h" + +#undef X +#define X(short_opt, long_opt, has_arg, handler, arg_type, desc, flags) \ + { short_opt, long_opt, has_arg, handler, arg_type, desc, flags }, + +const struct option_descriptor g_global_opts[] = { + GLOBAL_OPTION_LIST + {0, NULL, 0, NULL, OPT_ARG_NONE, NULL, 0} +}; + +#undef X diff --git a/src/cli/handlers/handle_help.c b/src/cli/handlers/handle_help.c index 972a2c8..c05b845 100644 --- a/src/cli/handlers/handle_help.c +++ b/src/cli/handlers/handle_help.c @@ -1,17 +1,18 @@ -#include #include +#include +#include + +#include "internal/cli/global_cmd.h" +#include "internal/cli/option.h" #include "compiler.h" -#include "ft_ssl.h" -#include "internal/cmd/digest_cmd.h" #include "version_gen.h" int -cli_handle_help(__unused const char *arg, void *config_void) +cli_handle_help(__unused const char *arg, __unused void *config_void) { - struct digest_config *config = (struct digest_config *)config_void; - - printf("Usage: %s %s [OPTIONS] [FILE...]\n\n", g_prog_name, config->cmd_name); - cli_print_options(g_digest_opts, DIGEST_OPT_LEN, cli_arg_type_to_str); + printf("Usage: %s [OPTIONS] [args...]\n\n", g_prog_name); + cli_print_options(g_global_opts, GLOBAL_OPT_LEN, cli_arg_type_to_str); + print_commands(stdout); return CLI_EXIT_SUCCESS; } diff --git a/src/cli/handlers/handle_version.c b/src/cli/handlers/handle_version.c index 9e64fe6..d817357 100644 --- a/src/cli/handlers/handle_version.c +++ b/src/cli/handlers/handle_version.c @@ -1,5 +1,3 @@ -#include - #include #include "compiler.h" diff --git a/src/cli/parse.c b/src/cli/parse.c deleted file mode 100644 index 3cf9a0e..0000000 --- a/src/cli/parse.c +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include -#include - -#include -#include - -#include "ft_ssl.h" -#include "internal/cli/cli_handlers.h" -#include "internal/cli/interactive.h" -#include "internal/cli/option.h" - -/* Forward declarations */ -static void init_config(struct ssl_config *config); -static const struct digest_algo *find_algo(const char *name); -static enum cli_code parse_subcommand(int argc, char **argv, int first_arg, - struct ssl_config *config); -/* ------------------- */ - -static const struct digest_algo * const s_algos[] = { -#define DIGEST_ALGO(lower, ds, bs) &g_##lower, -#include -#undef DIGEST_ALGO - NULL -}; - -enum cli_code -cli_parse_arguments(int argc, char **argv, struct ssl_config *config) -{ - char opt_str[FT_SSL_OPTSTR_LEN]; - struct option long_opts[FT_SSL_OPT_LEN + 1]; - enum cli_code ret; - - init_config(config); - ret = cli_parse(argc, argv, config, g_options, FT_SSL_OPT_LEN, opt_str, long_opts); - if (CLI_SUCCESS != ret) - return ret; - return parse_subcommand(argc, argv, optind, config); -} - -static enum cli_code -parse_subcommand(int argc, char **argv, int first_arg, - struct ssl_config *config) -{ - if (first_arg >= argc) - return run_interactive(); - config->algo = find_algo(argv[first_arg]); - if (NULL == config->algo) - { - fprintf(stderr, "%s: unknown command -- '%s'\n", argv[0], argv[first_arg]); - print_usage(argv[0]); - return CLI_ERROR; - } - config->files = argv + first_arg + 1; - config->nb_files = argc - first_arg - 1; - return CLI_SUCCESS; -} - -static const struct digest_algo * -find_algo(const char *name) -{ - size_t i; - - for (i = 0; NULL != s_algos[i]; i++) - { - if (0 == strcmp(s_algos[i]->name, name)) - return s_algos[i]; - } - return NULL; -} - -void -print_usage(const char *prog) -{ - size_t i; - - fprintf(stderr, "usage: %s {", prog); - for (i = 0; NULL != s_algos[i]; i++) - { - if (0 != i) - fprintf(stderr, "|"); - fprintf(stderr, "%s", s_algos[i]->name); - } - fprintf(stderr, "} [-pqr] [-s string] [file...]\n"); -} - -static void -init_config(struct ssl_config *config) -{ - memset(config, 0, sizeof(struct ssl_config)); -} diff --git a/src/cli/print_help.c b/src/cli/print_help.c new file mode 100644 index 0000000..184fa8f --- /dev/null +++ b/src/cli/print_help.c @@ -0,0 +1,20 @@ +#include + +#include + +#include "internal/cli/option.h" + +void +print_commands(FILE *out) +{ + const struct command_descriptor *cmd; + + fprintf(out, "\nMessage Digest commands:\n"); + for (cmd = g_commands; NULL != cmd->name; cmd++) + if (CMD_DIGEST == cmd->category) + fprintf(out, " %s\n", cmd->name); + fprintf(out, "\nCipher commands:\n"); + for (cmd = g_commands; NULL != cmd->name; cmd++) + if (CMD_CIPHER == cmd->category) + fprintf(out, " %s\n", cmd->name); +} diff --git a/src/cli/version.c b/src/cli/print_version.c similarity index 100% rename from src/cli/version.c rename to src/cli/print_version.c diff --git a/src/cmd/command_table.c b/src/cmd/command_table.c deleted file mode 100644 index 85d6757..0000000 --- a/src/cmd/command_table.c +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include - -#include - -#include "internal/cmd/command.h" -#include "internal/cmd/digest_cmd.h" - -/* Forward-declare all digest algo globals */ -#define DIGEST_ALGO(lower, ds, bs) extern const struct digest_algo g_##lower; -#include -#undef DIGEST_ALGO - -static const struct command_descriptor s_commands[] = { - /* Digest commands */ -#define DIGEST_ALGO(lower, ds, bs) \ - { #lower, CMD_DIGEST, g_digest_opts, DIGEST_OPT_LEN, &g_##lower, digest_run }, -#include -#undef DIGEST_ALGO - /* Cipher commands (not yet implemented) */ - { "base64", CMD_CIPHER, NULL, 0, NULL, NULL }, - { "des", CMD_CIPHER, NULL, 0, NULL, NULL }, - { "des-ecb", CMD_CIPHER, NULL, 0, NULL, NULL }, - { "des-cbc", CMD_CIPHER, NULL, 0, NULL, NULL }, - /* Sentinel */ - { NULL, 0, NULL, 0, NULL, NULL } -}; - -const struct command_descriptor * -find_command(const char *name) -{ - const struct command_descriptor *cmd; - - for (cmd = s_commands; NULL != cmd->name; cmd++) - if (0 == strcmp(cmd->name, name)) - return cmd; - return NULL; -} - -void -print_commands(FILE *out) -{ - const struct command_descriptor *cmd; - - fprintf(out, "\nStandard commands:\n"); - fprintf(out, "\nMessage Digest commands:\n"); - for (cmd = s_commands; NULL != cmd->name; cmd++) - if (CMD_DIGEST == cmd->category) - fprintf(out, " %s\n", cmd->name); - fprintf(out, "\nCipher commands:\n"); - for (cmd = s_commands; NULL != cmd->name; cmd++) - if (CMD_CIPHER == cmd->category) - fprintf(out, " %s\n", cmd->name); -} diff --git a/src/ssl/digest.c b/src/cmd/digest/digest.c similarity index 96% rename from src/ssl/digest.c rename to src/cmd/digest/digest.c index ff68a61..31cde51 100644 --- a/src/ssl/digest.c +++ b/src/cmd/digest/digest.c @@ -4,7 +4,7 @@ #include #include "ft_ssl.h" -#include "internal/ssl/ssl.h" +#include "internal/cmd/digest.h" /* Forward declarations */ static void process_chunk(const struct digest_config *config, union digest_ctx *ctx, diff --git a/src/ssl/output.c b/src/cmd/digest/output.c similarity index 98% rename from src/ssl/output.c rename to src/cmd/digest/output.c index 3720dd3..065cb94 100644 --- a/src/ssl/output.c +++ b/src/cmd/digest/output.c @@ -6,7 +6,7 @@ #include "compiler.h" #include "ft_ssl.h" #include "ft_ssl_flags.h" -#include "internal/ssl/ssl.h" +#include "internal/cmd/digest.h" enum fmt_mode { diff --git a/src/cmd/digest_run.c b/src/cmd/digest/run.c similarity index 81% rename from src/cmd/digest_run.c rename to src/cmd/digest/run.c index fb8b93c..7ef712d 100644 --- a/src/cmd/digest_run.c +++ b/src/cmd/digest/run.c @@ -7,9 +7,9 @@ #include "compiler.h" #include "ft_ssl.h" #include "ft_ssl_flags.h" -#include "internal/cmd/command.h" -#include "internal/cmd/digest_cmd.h" -#include "internal/ssl/ssl.h" +#include "internal/cli/command.h" +#include "internal/cli/digest_cmd.h" +#include "internal/cmd/digest.h" #include "version_gen.h" /* Forward declarations */ @@ -32,7 +32,7 @@ digest_run(int argc, char **argv, const struct command_descriptor *self) config.cmd_name = self->name; ret = cli_parse(argc, argv, &config, self->opts, self->nb_opts, - opt_str, long_opts); + opt_str, long_opts); if (CLI_SUCCESS != ret) return (int)ret; @@ -45,11 +45,11 @@ digest_run(int argc, char **argv, const struct command_descriptor *self) ret_val = (int)CLI_SUCCESS; has_input = (0 < config.nb_strings || 0 < config.nb_files); if (HAS_FLAG(config.flags, FLAG_P) || !has_input) - update_ret(&ret_val, run_stdin(&config)); + update_ret(&ret_val, digest_run_stdin(&config)); for (i = 0; i < config.nb_strings; i++) - update_ret(&ret_val, run_string(&config, config.strings[i])); + update_ret(&ret_val, digest_run_string(&config, config.strings[i])); for (i = 0; i < config.nb_files; i++) - update_ret(&ret_val, run_file(&config, config.files[i])); + update_ret(&ret_val, digest_run_file(&config, config.files[i])); return ret_val; } @@ -61,7 +61,7 @@ check_algo(const struct digest_config *config) || NULL == config->algo->final) { fprintf(stderr, "%s: %s: not yet implemented\n", - g_prog_name, config->algo->name); + g_prog_name, config->algo->name); return (int)CLI_ERROR; } return (int)CLI_SUCCESS; diff --git a/src/ssl/run_file.c b/src/cmd/digest/run_file.c similarity index 79% rename from src/ssl/run_file.c rename to src/cmd/digest/run_file.c index a7c60a3..3786401 100644 --- a/src/ssl/run_file.c +++ b/src/cmd/digest/run_file.c @@ -7,11 +7,11 @@ #include #include "ft_ssl.h" -#include "internal/ssl/ssl.h" +#include "internal/cmd/digest.h" #include "version_gen.h" int -run_file(const struct digest_config *config, const char *path) +digest_run_file(const struct digest_config *config, const char *path) { int fd; int ret; diff --git a/src/ssl/run_stdin.c b/src/cmd/digest/run_stdin.c similarity index 95% rename from src/ssl/run_stdin.c rename to src/cmd/digest/run_stdin.c index 9cd774c..ad89eb0 100644 --- a/src/ssl/run_stdin.c +++ b/src/cmd/digest/run_stdin.c @@ -8,7 +8,7 @@ #include "compiler.h" #include "ft_ssl.h" #include "ft_ssl_flags.h" -#include "internal/ssl/ssl.h" +#include "internal/cmd/digest.h" /* Forward declarations */ static int run_stdin_p(const struct digest_config *config); @@ -17,7 +17,7 @@ static ssize_t read_and_hash(const struct digest_config *config, union digest_ct /* ------------------- */ int -run_stdin(const struct digest_config *config) +digest_run_stdin(const struct digest_config *config) { if (HAS_FLAG(config->flags, FLAG_P) && !HAS_FLAG(config->flags, FLAG_Q)) return run_stdin_p(config); diff --git a/src/ssl/run_string.c b/src/cmd/digest/run_string.c similarity index 80% rename from src/ssl/run_string.c rename to src/cmd/digest/run_string.c index bc81892..aaa6d4c 100644 --- a/src/ssl/run_string.c +++ b/src/cmd/digest/run_string.c @@ -5,10 +5,10 @@ #include #include "ft_ssl.h" -#include "internal/ssl/ssl.h" +#include "internal/cmd/digest.h" int -run_string(const struct digest_config *config, const char *s) +digest_run_string(const struct digest_config *config, const char *s) { union digest_ctx ctx; uint8_t digest[MAX_DIGEST_SIZE]; diff --git a/src/main.c b/src/main.c index 5c54c94..0a21c46 100644 --- a/src/main.c +++ b/src/main.c @@ -1,10 +1,6 @@ -#include -#include -#include - #include -#include "internal/cmd/command.h" +#include "internal/cli/dispatch.h" #include "version_gen.h" char *g_prog_name = NULL; @@ -12,34 +8,7 @@ char *g_prog_name = NULL; int main(int argc, char **argv) { - const struct command_descriptor *cmd; - int ret; - g_prog_name = argv[0]; cli_set_prog_name(g_prog_name); - if (argc < 2) - { - print_commands(stderr); - return 2; - } - if (0 == strcmp(argv[1], "-h") || 0 == strcmp(argv[1], "--help")) - { - print_commands(stdout); - return EXIT_SUCCESS; - } - cmd = find_command(argv[1]); - if (NULL == cmd) - { - fprintf(stderr, "%s: Error: %s is an invalid command.\n", - argv[0], argv[1]); - print_commands(stderr); - return 2; - } - if (NULL == cmd->run) - { - fprintf(stderr, "%s: %s: not yet implemented\n", argv[0], argv[1]); - return 2; - } - ret = cmd->run(argc - 1, argv + 1, cmd); - return ((int)CLI_ERROR == ret) ? 2 : EXIT_SUCCESS; + return ft_ssl_dispatch(argc, argv); } diff --git a/src/ssl_run.c b/src/ssl_run.c deleted file mode 100644 index 9ae5c3d..0000000 --- a/src/ssl_run.c +++ /dev/null @@ -1,56 +0,0 @@ -#include - -#include -#include - -#include "compiler.h" -#include "ft_ssl.h" -#include "ft_ssl_flags.h" -#include "internal/ssl/ssl.h" -#include "version_gen.h" - -/* Forward declarations */ -static int check_algo(const struct ssl_config *config); -static inline void update_ret(int *ret, int result); -/* ------------------- */ - -int -ssl_run(const struct ssl_config *config) -{ - int ret; - int has_input; - int i; - - if (CLI_SUCCESS != check_algo(config)) - return CLI_ERROR; - ret = CLI_SUCCESS; - has_input = (0 < config->nb_strings || 0 < config->nb_files); - if (HAS_FLAG(config->flags, FLAG_P) || !has_input) - update_ret(&ret, run_stdin(config)); - for (i = 0; i < config->nb_strings; i++) - update_ret(&ret, run_string(config, config->strings[i])); - for (i = 0; i < config->nb_files; i++) - update_ret(&ret, run_file(config, config->files[i])); - return ret; -} - -static int -check_algo(const struct ssl_config *config) -{ - if (NULL == config->algo->init - || NULL == config->algo->update - || NULL == config->algo->final) - { - fprintf(stderr, "%s: %s: not yet implemented\n", - g_prog_name, config->algo->name); - return CLI_ERROR; - } - return CLI_SUCCESS; -} - -static inline void -update_ret(int *ret, int result) -{ - if (CLI_ERROR == result) - *ret = CLI_ERROR; -}