85 lines
2 KiB
C
85 lines
2 KiB
C
#include <stddef.h>
|
|
#include <string.h>
|
|
#include <getopt.h>
|
|
#include "cli.h"
|
|
#include "ft_ping.h"
|
|
#include "ft_ping_const.h"
|
|
|
|
/* Forward declatation */
|
|
static void init_config(t_ping_config *config);
|
|
static void build_long_options(struct option *long_opts, size_t nb_opts,
|
|
const t_option_descriptor *src);
|
|
static const t_option_descriptor *find_option_handler(int opt);
|
|
static int hanlde_one_option(int opt, char *optarg, t_ping_config *config);
|
|
/* ------------------- */
|
|
|
|
int
|
|
cli_parse_arguments(int argc, char **argv, t_ping_config *config)
|
|
{
|
|
struct option long_opts[g_options_len + 1];
|
|
const char *opt_str = "hVvq:c:i:t:s:W:f";
|
|
int opt;
|
|
int res;
|
|
|
|
init_config(config);
|
|
build_long_options(long_opts, g_options_len, g_options);
|
|
while (-1 != (opt = getopt_long(argc, argv, opt_str, long_opts, NULL)))
|
|
{
|
|
res = hanlde_one_option(opt, optarg, config);
|
|
if (0 != res)
|
|
return res;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
hanlde_one_option(int opt, char *optarg, t_ping_config *config)
|
|
{
|
|
const t_option_descriptor *desc = find_option_handler(opt);
|
|
int res;
|
|
|
|
if ('?' == opt)
|
|
return CLI_ERROR;
|
|
if (NULL != desc)
|
|
{
|
|
res = desc->handler(optarg, config);
|
|
if (0 != res)
|
|
return res;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
init_config(t_ping_config *config)
|
|
{
|
|
memset(config, 0, sizeof(t_ping_config));
|
|
config->count = DEFAULT_COUNT;
|
|
config->interval = DEFAULT_INTERVAL;
|
|
config->ttl = DEFAULT_TTL;
|
|
config->packet_size = DEFAULT_PACKET_SIZE;
|
|
config->timeout = DEFAULT_TIMEOUT;
|
|
}
|
|
|
|
static void
|
|
build_long_options(struct option *long_opts, size_t nb_opts,
|
|
const t_option_descriptor *src)
|
|
{
|
|
for (size_t i = 0; i < nb_opts; ++i) {
|
|
long_opts[i].name = src[i].long_opt;
|
|
long_opts[i].has_arg = src[i].has_arg;
|
|
long_opts[i].flag = NULL;
|
|
long_opts[i].val = src[i].short_opt;
|
|
}
|
|
long_opts[nb_opts] = (struct option){0};
|
|
}
|
|
|
|
static const t_option_descriptor
|
|
*find_option_handler(int opt)
|
|
{
|
|
for (size_t i = 0; i < g_options_len; ++i)
|
|
{
|
|
if (g_options[i].short_opt == opt)
|
|
return &g_options[i];
|
|
}
|
|
return NULL;
|
|
}
|