WIP: refactor command dispacher

This commit is contained in:
lohhiiccc 2026-07-10 22:57:29 +02:00
parent 27797d1ea0
commit 6603ff3639
27 changed files with 161 additions and 237 deletions

View file

@ -3,11 +3,12 @@
#include <cli.h>
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

View file

@ -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

View file

@ -5,32 +5,14 @@
#include <cli.h>
#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

View file

@ -2,74 +2,31 @@
#define FT_SSL_OPT_H
#include <cli.h>
#include <libft_ssl.h>
#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 <digest_algos.h>
#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 <digest_algos.h>
#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);

View file

@ -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,

View file

@ -42,20 +42,23 @@ FORCE:
ft_ssl_SOURCES = \
main.c \
cmd/command_table.c \
cmd/global_option.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 \
ssl/digest/run_stdin.c \
ssl/digest/run_string.c \
ssl/digest/run_file.c \
ssl/digest/digest.c \
ssl/digest/output.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/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
ft_ssl_CPPFLAGS = \
-I $(top_srcdir)/includes \

View file

@ -0,0 +1,17 @@
#include <cli.h>
#include <stdio.h>
#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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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) \

View file

@ -1,17 +1,14 @@
#include <cli.h>
#include <stdio.h>
#include "internal/cli/option.h"
#include <libft_ssl.h>
#include <cli.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)
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);
print_commands(stdout);
return CLI_EXIT_SUCCESS;
}

View file

@ -1,5 +1,3 @@
#include <stdio.h>
#include <cli.h>
#include "compiler.h"

View file

@ -7,7 +7,6 @@
#include "ft_ssl.h"
#include "internal/cli/cli_handlers.h"
#include "internal/cli/interactive.h"
#include "internal/cli/option.h"
/* Forward declarations */

21
src/cli/print_help.c Normal file
View file

@ -0,0 +1,21 @@
#include <stdio.h>
#include <libft_ssl.h>
#include "internal/cli/option.h"
void
print_commands(FILE *out)
{
const struct command_descriptor *cmd;
fprintf(out, "\nStandard commands:\n");
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);
}

View file

@ -1,54 +1,16 @@
#include <stdio.h>
#include <string.h>
#include <libft_ssl.h>
#include "internal/cli/option.h"
#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 <digest_algos.h>
#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 <digest_algos.h>
#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++)
for (cmd = g_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);
}

View file

@ -7,8 +7,8 @@
#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/cli/command.h"
#include "internal/cli/digest_cmd.h"
#include "internal/ssl/ssl.h"
#include "version_gen.h"
@ -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;
}

22
src/cmd/global_option.c Normal file
View file

@ -0,0 +1,22 @@
#include "cli.h"
#include <bits/getopt_ext.h>
#define GLOBAL_OPTIONS_LIST \
X('h', "help", no_argument, NULL, OPT_ARG_NONE, "Display this help and exit", 0) \
X('v', "version", no_argument, NULL, OPT_ARG_NONE, "Display version informations and exit", 0)
#define X(s, l, a, h, t, d, f) + 1
enum { GLOBAL_NB_OPTS = 0 GLOBAL_OPTIONS_LIST };
#undef X
#define X(s, l, a, h, t, d, f) + (1 + (a != no_argument ? 1 : 0))
enum { GLOBAL_OPTSTR_LEN = 1 GLOBAL_OPTIONS_LIST };
#undef X
/*static*/ const struct option_descriptor g_option_ft_ssl[] = {
#define X(s, l, a, h, t, d, f) { s, l, a, h, t, d, f },
GLOBAL_OPTIONS_LIST
#undef X
};

View file

@ -4,11 +4,12 @@
#include <cli.h>
#include "internal/cmd/command.h"
#include "internal/cli/command.h"
#include "version_gen.h"
char *g_prog_name = NULL;
int
main(int argc, char **argv)
{
@ -17,6 +18,7 @@ main(int argc, char **argv)
g_prog_name = argv[0];
cli_set_prog_name(g_prog_name);
/*
if (argc < 2)
{
print_commands(stderr);
@ -40,6 +42,7 @@ main(int argc, char **argv)
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;
}

View file

@ -11,7 +11,7 @@
#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;

View file

@ -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);

View file

@ -8,7 +8,7 @@
#include "internal/ssl/ssl.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];

View file

@ -1,56 +0,0 @@
#include <stdio.h>
#include <cli.h>
#include <libft_ssl.h>
#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;
}