From bf2e836447a69c1e36f96f464c3bd6d55621ef09 Mon Sep 17 00:00:00 2001 From: Raphael Date: Mon, 30 Mar 2026 12:50:10 +0200 Subject: [PATCH 1/6] style(includes/macro): adding the detailled error log for debug mode only --- includes/macro.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/macro.h b/includes/macro.h index 5ac0438..cdd2318 100644 --- a/includes/macro.h +++ b/includes/macro.h @@ -6,7 +6,7 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/03/24 11:23:47 by rparodi #+# #+# */ -/* Updated: 2026/03/24 13:20:48 by rparodi ### ########.fr */ +/* Updated: 2026/03/30 12:29:28 by rparodi ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,8 +19,8 @@ # define DEBUG 0 #endif -#define ERROR_LOG(str) dprintf(2, "%sError:\t%s (%s:%d in %s)%s\n", CLR_RED, str, __FILE_NAME__, __LINE__, __FUNCTION__, CLR_RESET); +#define ERROR_LOG(str) if (DEBUG) {dprintf(2, "%sError:\t%s (%s:%d in %s)%s\n", CLR_RED, str, __FILE_NAME__, __LINE__, __FUNCTION__, CLR_RESET);} else { dprintf(2, "%s\n", str); } #define WARN_LOG(str) if (DEBUG) {dprintf(2, "%sWarning:\t%s (%s:%d in %s)%s\n", CLR_YELLOW, str, __FILE_NAME__, __LINE__, __FUNCTION__, CLR_RESET);} #define INFO_LOG(str) if (DEBUG) {dprintf(2, "%sInfo:\t%s (%s:%d in %s)%s\n", CLR_BLUE, str, __FILE_NAME__, __LINE__, __FUNCTION__, CLR_RESET);} #define DEBUG_LOG(str) if (DEBUG) {dprintf(2, "%sDebug:\t%s (%s:%d in %s)%s\n", CLR_GREY, str, __FILE_NAME__, __LINE__, __FUNCTION__, CLR_RESET);} -#define SUCCESS_LOG(str) if (DEBUG) {dprintf(2, "%sSuccess from %s:\t%s (%s:%d)%s\n", CLR_GREEN, str, __FILE_NAME__, __LINE__, __FUNCTION__, CLR_RESET);} +#define SUCCESS_LOG(str) if (DEBUG) {dprintf(2, "%sSuccess:\t%s (%s:%d in %s)%s\n", CLR_GREEN, str, __FILE_NAME__, __LINE__, __FUNCTION__, CLR_RESET);} From c50154379cb2874384d33ce2607b0b0c4b541d2e Mon Sep 17 00:00:00 2001 From: Raphael Date: Mon, 30 Mar 2026 14:03:45 +0200 Subject: [PATCH 2/6] feat(parsing/sources): adding the moving flag part --- parsing/sources/parsing.c | 132 +++++--------------------------------- 1 file changed, 16 insertions(+), 116 deletions(-) diff --git a/parsing/sources/parsing.c b/parsing/sources/parsing.c index f082553..fdae12c 100644 --- a/parsing/sources/parsing.c +++ b/parsing/sources/parsing.c @@ -6,140 +6,40 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/03/23 14:49:36 by rparodi #+# #+# */ -/* Updated: 2026/03/28 15:43:45 by rparodi ### ########.fr */ +/* Updated: 2026/03/30 12:22:07 by rparodi ### ########.fr */ /* */ /* ************************************************************************** */ #include "parsing.h" #include "macro.h" -#include -#include -#include +#include "struct.h" #include -#include -#include -#include #include -#include -const t_args _flags[] = { - {'?', "help", NULL, "print help and exit", true}, - {'W', "linger",",", "time to wait for response", false}, - {'c', "count","", "stop after replies", false}, - {'f', "flood",NULL, "flood ping", false}, - {'l', "preload",",", "send number of packages while waiting replies", false}, - {'n', "numeric",NULL, "no reverse DNS name resolution", false}, - {'p', "pattern",",", "contents of padding byte", false}, - {'q', "quiet", NULL, "reply wait in seconds", false}, - {'v', "verbose",NULL, "verbose output", true}, - {'w', "timeout",",", "reply wait in seconds", false}, - {0, "usage", NULL, "give a short usage message", false}, - {0, NULL, NULL,NULL, true}, -}; +static const char *_find_target(int argc, char **argv) { + const char *target = NULL; -static struct option *_t_args_to_getopt_long(const size_t size) { - struct option *long_options = (struct option *)calloc((size + 1), sizeof(struct option)); - if (!long_options) { - return NULL; - } - - for (size_t i = 0; i < size; i++) { - long_options[i].name = _flags[i].long_option; - long_options[i].val = _flags[i].short_option; - if (_flags[i].usage == NULL) { - long_options[i].has_arg = no_argument; - } else { - long_options[i].has_arg = required_argument; + for (int i = optind; i < argc; i++) { + if (argv[i][0] != '-') { + target = argv[i]; } - long_options[i].flag = NULL; } - long_options[size] = (struct option){0}; - return long_options; -} + if (target == NULL || target[0] == '\0') { + dprintf(2, "%s: missing host operand \n Try 'ping --help' or 'ping --usage' for more information.", argv[0]); + exit(64); + } + return (target); +} void parsing_args(int argc, char **argv, t_flags *flags) { if (argc == 1) { dprintf(2, "%s: missing host operand \n Try 'ping --help' or 'ping --usage' for more information.", argv[0]); exit(64); } - const size_t size = args_size(); - size_t j = 0; - char args[2 * size + 1]; - bzero(args, sizeof(args)); - for (size_t i = 0; i < size; i++) { - if (_flags[i].is_mandatory != false || BONUS == 1) { - args[j++] = _flags[i].short_option; - if (_flags[i].usage != NULL) - args[j++] = ':'; - } - } - - DEBUG_LOG(args); - - struct option *options = _t_args_to_getopt_long(size); - if (!options) { - ERROR_LOG(strerror(ENOMEM)); - exit(ENOMEM); - } - opterr = 1; - int opt; - while ((opt = getopt_long(argc, argv, args, options, NULL)) != -1) { - switch (opt) { - case 'v': - INFO_LOG("argument verbose"); - flags->verbose = true; - break; - case 'f': - INFO_LOG("argument flood"); - flags->flood = true; - break; - case 'n': - INFO_LOG("argument no-reverse"); - flags->reverse_dns = true; - break; - case 'c': - INFO_LOG("argument count"); - flags->count = check_num_arguments(optarg); - break; - case 'q': - INFO_LOG("argument quiet"); - flags->quiet = true; - break; - case 'w': - INFO_LOG("argument wait"); - flags->wait = check_num_arguments(optarg); - break; - case 'W': - INFO_LOG("argument timeout"); - flags->timeout = check_num_arguments(optarg); - break; - case '?': - free(options); - if (optopt != 0) { - if (isprint(optopt)) { - char invalid_option[2] = {optopt, 0}; - WARN_LOG(invalid_option); - } - dprintf(2, "Try 'ping --help' or 'ping --usage' for more information.\n"); - exit(64); - } - print_help(size); - exit(EXIT_SUCCESS); - default: - if (strcmp(options[optind - 1].name, "usage")) - print_usage(size); - else { - if (isprint(optopt)) { - char invalid_option[2] = {optopt, 0}; - WARN_LOG(invalid_option); - } - dprintf(2, "Try 'ping --help' or 'ping --usage' for more information.\n"); - exit(64); - } - } - } - free(options); + check_flags(argc, argv, flags); + check_target(_find_target(argc, argv)); + SUCCESS_LOG("PARSING finished with success"); } From 8fb5ab6f12fe14922fd7309e5ede8f6ca0f4fda9 Mon Sep 17 00:00:00 2001 From: Raphael Date: Mon, 30 Mar 2026 14:03:58 +0200 Subject: [PATCH 3/6] feat(parsing/sources): adding the target parsing part --- parsing/sources/target.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 parsing/sources/target.c diff --git a/parsing/sources/target.c b/parsing/sources/target.c new file mode 100644 index 0000000..43762b6 --- /dev/null +++ b/parsing/sources/target.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* target.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rparodi +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2026/03/30 12:09:48 by rparodi #+# #+# */ +/* Updated: 2026/03/30 12:33:54 by rparodi ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "macro.h" +#include +#include +#include +#include +#include +#include +#include + +void check_target(const char *target) { + struct addrinfo hints = {0}, *res; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_RAW; + hints.ai_protocol = IPPROTO_ICMP; + + int err = getaddrinfo(target, NULL, &hints, &res); + if (err != 0) { + ERROR_LOG("ft_ping: unknown host"); + exit(EXIT_FAILURE); + } + freeaddrinfo(res); +} From 09fe8cea87b8578338f8db47fa25866a18f47df5 Mon Sep 17 00:00:00 2001 From: Raphael Date: Mon, 30 Mar 2026 14:04:05 +0200 Subject: [PATCH 4/6] feat(parsing/sources): adding the flags parsing part --- parsing/sources/flags.c | 140 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 parsing/sources/flags.c diff --git a/parsing/sources/flags.c b/parsing/sources/flags.c new file mode 100644 index 0000000..8272652 --- /dev/null +++ b/parsing/sources/flags.c @@ -0,0 +1,140 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* flags.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rparodi +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2026/03/30 12:06:19 by rparodi #+# #+# */ +/* Updated: 2026/03/30 12:40:57 by rparodi ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "parsing.h" +#include "macro.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const t_args _flags[] = { + {'?', "help", NULL, "print help and exit", true}, + {'W', "linger",",", "time to wait for response", false}, + {'c', "count","", "stop after replies", false}, + {'f', "flood",NULL, "flood ping", false}, + {'l', "preload",",", "send number of packages while waiting replies", false}, + {'n', "numeric",NULL, "no reverse DNS name resolution", false}, + {'p', "pattern",",", "contents of padding byte", false}, + {'q', "quiet", NULL, "reply wait in seconds", false}, + {'v', "verbose",NULL, "verbose output", true}, + {'w', "timeout",",", "reply wait in seconds", false}, + {0, "usage", NULL, "give a short usage message", false}, + {0, NULL, NULL,NULL, true}, +}; + +static struct option *_t_args_to_getopt_long(const size_t size) { + struct option *long_options = (struct option *)calloc((size + 1), sizeof(struct option)); + if (!long_options) { + return NULL; + } + + for (size_t i = 0; i < size; i++) { + long_options[i].name = _flags[i].long_option; + long_options[i].val = _flags[i].short_option; + if (_flags[i].usage == NULL) { + long_options[i].has_arg = no_argument; + } else { + long_options[i].has_arg = required_argument; + } + long_options[i].flag = NULL; + } + + long_options[size] = (struct option){0}; + return long_options; +} + +void check_flags(int argc, char **argv, t_flags *flags) { + const size_t size = args_size(); + size_t j = 0; + char args[2 * size + 1]; + bzero(args, sizeof(args)); + + for (size_t i = 0; i < size; i++) { + if (_flags[i].is_mandatory != false || BONUS == 1) { + args[j++] = _flags[i].short_option; + if (_flags[i].usage != NULL) + args[j++] = ':'; + } + } + + DEBUG_LOG(args); + + struct option *options = _t_args_to_getopt_long(size); + if (!options) { + ERROR_LOG(strerror(ENOMEM)); + exit(ENOMEM); + } + opterr = 1; + int opt; + while ((opt = getopt_long(argc, argv, args, options, NULL)) != -1) { + switch (opt) { + case 'v': + INFO_LOG("argument verbose"); + flags->verbose = true; + break; + case 'f': + INFO_LOG("argument flood"); + flags->flood = true; + break; + case 'n': + INFO_LOG("argument no-reverse"); + flags->reverse_dns = true; + break; + case 'c': + INFO_LOG("argument count"); + flags->count = check_num_arguments(optarg); + break; + case 'q': + INFO_LOG("argument quiet"); + flags->quiet = true; + break; + case 'w': + INFO_LOG("argument wait"); + flags->wait = check_num_arguments(optarg); + break; + case 'W': + INFO_LOG("argument timeout"); + flags->timeout = check_num_arguments(optarg); + break; + case '?': + free(options); + if (optopt != 0) { + if (isprint(optopt)) { + char invalid_option[2] = {optopt, 0}; + WARN_LOG(invalid_option); + } + ERROR_LOG("Try 'ft_ping --help' or 'ft_ping --usage' for more information."); + exit(64); + } + print_help(size); + exit(EXIT_SUCCESS); + default: + if (strcmp(options[optind - 1].name, "usage")) + print_usage(size); + else { + if (isprint(optopt)) { + char invalid_option[2] = {optopt, 0}; + WARN_LOG(invalid_option); + } + ERROR_LOG("Try 'ft_ping --help' or 'ft_ping --usage' for more information."); + exit(64); + } + } + } + free(options); +} From a9eaeac94072d2641931d64ad82bd780d395af05 Mon Sep 17 00:00:00 2001 From: Raphael Date: Mon, 30 Mar 2026 14:04:47 +0200 Subject: [PATCH 5/6] feat(parsing/includes): adding target / flags part to the header --- parsing/includes/parsing.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/parsing/includes/parsing.h b/parsing/includes/parsing.h index 9763822..11484b2 100644 --- a/parsing/includes/parsing.h +++ b/parsing/includes/parsing.h @@ -6,7 +6,7 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/03/23 14:49:37 by rparodi #+# #+# */ -/* Updated: 2026/03/28 15:25:03 by rparodi ### ########.fr */ +/* Updated: 2026/03/30 12:19:17 by rparodi ### ########.fr */ /* */ /* ************************************************************************** */ @@ -33,6 +33,8 @@ typedef struct s_args { extern const t_args _flags[]; size_t args_size(); +uint64_t check_num_arguments(char *arg); +void check_flags(int argc, char **argv, t_flags *flags); +void check_target(const char *target); void print_help(const size_t size); void print_usage(const size_t size); -uint64_t check_num_arguments(char *arg); From 89eaf3402c7a9c0d473c09f2451838a0f4828ffd Mon Sep 17 00:00:00 2001 From: Raphael Date: Mon, 30 Mar 2026 14:05:02 +0200 Subject: [PATCH 6/6] build(parsing): adding the flags / target --- parsing/parsing.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/parsing/parsing.mk b/parsing/parsing.mk index 5bd2249..99a1367 100644 --- a/parsing/parsing.mk +++ b/parsing/parsing.mk @@ -6,7 +6,7 @@ # By: rparodi +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2023/11/12 11:05:05 by rparodi #+# #+# # -# Updated: 2026/03/28 15:15:58 by rparodi ### ########.fr # +# Updated: 2026/03/30 12:19:43 by rparodi ### ########.fr # # # # **************************************************************************** # @@ -19,6 +19,8 @@ NAME = lib$(MODULE_NAME).a SRC = sources/utils.c \ sources/help.c \ sources/usage.c \ + sources/flags.c \ + sources/target.c \ sources/parsing.c CC ?= clang