feat/command-dispatch: introduce generic command dispatch #1
5 changed files with 171 additions and 13 deletions
|
|
@ -3,8 +3,6 @@
|
||||||
|
|
||||||
#include <cli.h>
|
#include <cli.h>
|
||||||
|
|
||||||
extern const struct option_descriptor g_options[];
|
|
||||||
|
|
||||||
int cli_handle_help(const char *arg, void *config);
|
int cli_handle_help(const char *arg, void *config);
|
||||||
int cli_handle_version(const char *arg, void *config);
|
int cli_handle_version(const char *arg, void *config);
|
||||||
int cli_handle_p(const char *arg, void *config);
|
int cli_handle_p(const char *arg, void *config);
|
||||||
|
|
|
||||||
84
includes/internal/cmd/digest_cmd.h
Normal file
84
includes/internal/cmd/digest_cmd.h
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
#ifndef FT_SSL_CMD_DIGEST_H
|
||||||
|
#define FT_SSL_CMD_DIGEST_H
|
||||||
|
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <cli.h>
|
||||||
|
|
||||||
|
#include "internal/cli/cli_handlers.h"
|
||||||
|
#include "internal/cmd/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, \
|
||||||
|
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 \
|
||||||
|
)
|
||||||
|
|
||||||
|
#undef X
|
||||||
|
#define X(short_opt, long_opt, has_arg, handler, arg_type, desc, flags) + 1
|
||||||
|
enum { DIGEST_OPT_LEN = (0 DIGEST_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 { DIGEST_OPTSTR_LEN = (2 DIGEST_OPTION_LIST) };
|
||||||
|
/* +2 for ':' to disable getopt error messages and \0 */
|
||||||
|
|
||||||
|
#undef X
|
||||||
|
|
||||||
|
extern const struct option_descriptor g_digest_opts[];
|
||||||
|
int digest_run(int argc, char **argv,
|
||||||
|
const struct command_descriptor *self);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -1,15 +1,17 @@
|
||||||
#include <cli.h>
|
#include <cli.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
|
#include "ft_ssl.h"
|
||||||
|
#include "internal/cmd/digest_cmd.h"
|
||||||
#include "version_gen.h"
|
#include "version_gen.h"
|
||||||
#include "internal/cli/option.h"
|
|
||||||
#include "internal/cli/cli_handlers.h"
|
|
||||||
|
|
||||||
int
|
int
|
||||||
cli_handle_help(__unused const char *arg, __unused void *config_void)
|
cli_handle_help(__unused const char *arg, void *config_void)
|
||||||
{
|
{
|
||||||
print_usage(g_prog_name);
|
struct digest_config *config = (struct digest_config *)config_void;
|
||||||
printf("\n");
|
|
||||||
cli_print_options(g_options, FT_SSL_OPT_LEN, cli_arg_type_to_str);
|
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;
|
return CLI_EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
#include "internal/cli/cli_handlers.h"
|
#include "internal/cmd/digest_cmd.h"
|
||||||
#include "internal/cli/option.h"
|
|
||||||
|
|
||||||
#undef X
|
#undef X
|
||||||
#define X(short_opt, long_opt, has_arg, handler, arg_type, desc, flags) \
|
#define X(short_opt, long_opt, has_arg, handler, arg_type, desc, flags) \
|
||||||
{ 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_options[] = {
|
const struct option_descriptor g_digest_opts[] = {
|
||||||
FT_SSL_OPTION_LIST
|
DIGEST_OPTION_LIST
|
||||||
{0, NULL, 0, NULL, OPT_ARG_NONE, NULL, 0 }
|
{0, NULL, 0, NULL, OPT_ARG_NONE, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef X
|
#undef X
|
||||||
|
|
|
||||||
75
src/cmd/digest_run.c
Normal file
75
src/cmd/digest_run.c
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <cli.h>
|
||||||
|
#include <libft_ssl.h>
|
||||||
|
|
||||||
|
#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 "version_gen.h"
|
||||||
|
|
||||||
|
/* Forward declarations */
|
||||||
|
static int check_algo(const struct digest_config *config);
|
||||||
|
static void update_ret(int *ret, int result);
|
||||||
|
/* ------------------- */
|
||||||
|
|
||||||
|
int
|
||||||
|
digest_run(int argc, char **argv, const struct command_descriptor *self)
|
||||||
|
{
|
||||||
|
struct digest_config config = {0};
|
||||||
|
char opt_str[DIGEST_OPTSTR_LEN + 1];
|
||||||
|
struct option long_opts[DIGEST_OPT_LEN + 1];
|
||||||
|
enum cli_code ret;
|
||||||
|
int ret_val;
|
||||||
|
int has_input;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
config.algo = (const struct digest_algo *)self->impl;
|
||||||
|
config.cmd_name = self->name;
|
||||||
|
|
||||||
|
ret = cli_parse(argc, argv, &config, self->opts, self->nb_opts,
|
||||||
|
opt_str, long_opts);
|
||||||
|
if (CLI_SUCCESS != ret)
|
||||||
|
return (int)ret;
|
||||||
|
|
||||||
|
config.files = argv + optind;
|
||||||
|
config.nb_files = argc - optind;
|
||||||
|
|
||||||
|
if (CLI_SUCCESS != check_algo(&config))
|
||||||
|
return (int)CLI_ERROR;
|
||||||
|
|
||||||
|
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));
|
||||||
|
for (i = 0; i < config.nb_strings; i++)
|
||||||
|
update_ret(&ret_val, run_string(&config, config.strings[i]));
|
||||||
|
for (i = 0; i < config.nb_files; i++)
|
||||||
|
update_ret(&ret_val, run_file(&config, config.files[i]));
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_algo(const struct digest_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 (int)CLI_ERROR;
|
||||||
|
}
|
||||||
|
return (int)CLI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_ret(int *ret, int result)
|
||||||
|
{
|
||||||
|
if ((int)CLI_ERROR == result)
|
||||||
|
*ret = (int)CLI_ERROR;
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue