feat: add support for multiple destination

This commit is contained in:
lohhiiccc 2026-03-07 16:20:58 +01:00
parent f59f984a0e
commit cba820ae7a
11 changed files with 100 additions and 10 deletions

View file

@ -9,7 +9,8 @@ enum e_cli_code {
CLI_ERROR = 1
};
enum e_cli_code
cli_parse_arguments(int argc, char **argv, t_ping_config *config);
enum e_cli_code cli_parse_arguments(int argc, char **argv,
t_ping_config *config);
void cli_config_free(t_ping_config *config);
#endif

View file

@ -3,11 +3,13 @@
#include <stdint.h>
#include <stddef.h>
#include <netinet/in.h>
typedef struct s_ping_config
{
/* Target */
char *destination;
/* Targets */
struct in_addr *destinations;
size_t nb_destinations;
/* Options */
uint64_t count;

View file

@ -10,5 +10,7 @@ enum e_cli_code error_unknown_opt(const char *current_opt);
enum e_cli_code error_invalid_arg(const char *current_opt);
enum e_cli_code error_invalid_opt(const char *current_opt);
enum e_cli_code error_duplicate_opt(const char *current_opt);
enum e_cli_code error_missing_dest(void);
enum e_cli_code error_invalid_dest(void);
#endif

View file

@ -2,8 +2,12 @@
#define CLI_INTERNAL_PARSE_UTILS
#include <stdint.h>
#include <netinet/in.h>
#include "ft_ping.h"
int cli_parse_uint64(const char *s, uint64_t *out);
int cli_parse_float(const char *s, float *out);
int cli_parse_inet_addr(const char *s, struct in_addr *out);
int cli_parse_destinations(int argc, char **argv, int optind, t_ping_config *config);
#endif

View file

@ -15,7 +15,10 @@ SRCS = $(SRC_DIR)/main.c \
$(SRC_DIR)/cli/handlers/handle_verbose.c \
$(SRC_DIR)/cli/parse_utils/parse_int.c \
$(SRC_DIR)/cli/parse_utils/parse_float.c \
$(SRC_DIR)/cli/parse_utils/parse_inet_addr.c \
$(SRC_DIR)/cli/parse_utils/parse_destinations.c \
$(SRC_DIR)/cli/parse_utils/get_optstr.c \
$(SRC_DIR)/cli/config_free.c \
$(SRC_DIR)/cli/messages/help.c \
$(SRC_DIR)/cli/messages/version.c \
$(SRC_DIR)/cli/messages/error.c \

10
src/cli/config_free.c Normal file
View file

@ -0,0 +1,10 @@
#include <stdlib.h>
#include "cli.h"
void
cli_config_free(t_ping_config *config)
{
free(config->destinations);
config->destinations = NULL;
}

View file

@ -46,6 +46,22 @@ error_duplicate_opt(const char *current_opt)
return CLI_ERROR;
}
enum e_cli_code
error_missing_dest(void)
{
dprintf(STDERR_FILENO, "%s: usage error: Destination address required\n",
CMD_NAME);
print_suggest_help();
return CLI_ERROR;
}
enum e_cli_code
error_invalid_dest(void)
{
dprintf(STDERR_FILENO, "%s: unknown host\n", CMD_NAME);
return CLI_ERROR;
}
void static inline
print_suggest_help(void)
{

View file

@ -1,3 +1,4 @@
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
@ -7,6 +8,7 @@
#include "internal/cli/messages.h"
#include "internal/cli/options.h"
#include "internal/cli/arg_handler.h"
#include "internal/cli/parse_utils.h"
/* Map -? to -h to support help shortcut */
#define HANDLE_QUESTION_MARK(opt) \
@ -42,7 +44,7 @@ cli_parse_arguments(int argc, char **argv, t_ping_config *config)
if (CLI_SUCCESS != res)
return res;
}
return CLI_SUCCESS;
return cli_parse_destinations(argc, argv, optind, config);
}
static int

View file

@ -0,0 +1,28 @@
#include <stdlib.h>
#include "cli.h"
#include "internal/cli/messages.h"
#include "internal/cli/parse_utils.h"
int
cli_parse_destinations(int argc, char **argv, int optind, t_ping_config *config)
{
if (optind >= argc)
return error_missing_dest();
config->nb_destinations = (size_t)(argc - optind);
config->destinations = malloc(config->nb_destinations * sizeof(struct in_addr));
if (NULL == config->destinations)
return CLI_ERROR;
for (int i = optind; i < argc; i++)
{
if (0 != cli_parse_inet_addr(argv[i], &config->destinations[i - optind]))
{
free(config->destinations);
config->destinations = NULL;
return error_invalid_dest();
}
}
return CLI_SUCCESS;
}

View file

@ -0,0 +1,23 @@
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
int
cli_parse_inet_addr(const char *s, struct in_addr *out)
{
struct addrinfo hints;
struct addrinfo *res;
bzero(&hints, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
if (0 != getaddrinfo(s, NULL, &hints, &res))
return 1;
struct sockaddr_in sin;
memcpy(&sin, res->ai_addr, sizeof(sin));
freeaddrinfo(res);
*out = sin.sin_addr;
return 0;
}

View file

@ -21,15 +21,14 @@ main(int argc, char **argv)
return EXIT_FAILURE;
ret = cli_parse_arguments(argc, argv, &config);
if (ret != CLI_SUCCESS)
{
free(g_prog_name.alloc);
return (ret == CLI_ERROR) ? EXIT_FAILURE : EXIT_SUCCESS;
}
goto cleanup;
printf("PING: Not yet implemented\n");
cleanup:
cli_config_free(&config);
free(g_prog_name.alloc);
return EXIT_SUCCESS;
return (ret == CLI_ERROR) ? EXIT_FAILURE : EXIT_SUCCESS;
}
static int