/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* parsing.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/26 17:01:53 by tomoron #+# #+# */ /* Updated: 2025/08/24 19:53:30 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "includes/ft_ping.h" int get_set_int(char *arg, t_settings *set) { long value; char *end; value = strtol(arg, &end, 10); if(*end) { fprintf(stderr, "%s: invalid value (`%s' near `%s')\n", set->name, arg, end); set->err = 1; return(0); } if(errno == ERANGE || value > INT32_MAX || value < INT32_MIN) { fprintf(stderr, "%s: option value too big : %s", set->name, arg); set->err = 1; return(0); } return((int) value); } double get_set_float(char *arg, t_settings *set) { float value; char *end; value = strtof(arg, &end); if(*end) { fprintf(stderr, "%s: invalid value (`%s' near `%s')\n", set->name, arg, end); set->err = 1; return(0); } if(errno == ERANGE) { fprintf(stderr, "%s: option value too big : %s", set->name, arg); set->err = 1; return(0); } return(value); } int check_values(t_settings *set, char *name) { if (set->setTtl) { if (set->ttl == 0) { fprintf(stderr, "%s: option value too small: %d\n", name, set->ttl); return(0); } else if (set->ttl >= 256 || set->ttl < 0) { fprintf(stderr, "%s: option value too big: %d\n", name, set->ttl); return(0); } } if (set->interval < 0.2 && set->interval >= 0) { fprintf(stderr, "%s: option value is too small: %g\n", name, set->interval); return(0); } return (1); } void init_settings(t_settings *set) { char *tmp; tmp = set->name; bzero(set, sizeof(t_settings)); set->name = tmp; set->timeout = -1; set->interval = 1; set->socket = -1; set->linger = 10; } int parse_args(int argc, char **argv, t_settings *set) { int arg; struct option opts[] = { {"count", required_argument, 0, 'c'}, {"interval", required_argument, 0, 'i'}, {"timeout", required_argument, 0, 'w'}, {"linger", required_argument, 0, 'W'}, {"ttl", required_argument , 0, 1000}, {"verbose", no_argument, &set->verbose, 1}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; for(int i = 1; i < argc; i++) { if(!strcmp(argv[i], "-?")) { show_help(set); return (1); } } unsetenv("POSIXLY_CORRECT"); init_settings(set); arg = 0; while (arg != -1) { arg = getopt_long(argc, argv, "c:i:w:W:vh", opts, NULL); switch (arg) { case 'c': set->count = get_set_int(optarg, set); break; case 'i': set->interval = get_set_float(optarg, set); break; case 'w': set->timeout = get_set_int(optarg, set); break; case 'W': set->linger = get_set_int(optarg, set); break; case 1000: set->ttl = get_set_int(optarg, set); set->setTtl = 1; break; case 'v': set->verbose = 1; break; case 'h': case '?': show_help(set); return (1); default : break ; } } if(set->err) return(1); while (optind < argc) { if (!add_host(set, argv[optind])) { set->err = 1; return (0); } optind++; } if (!set->hosts) { fprintf(stderr, "%s: missing host operand\n", set->name); set->err = 1; return (1); } if (!set->err) set->err = !check_values(set, argv[0]); return (0); }