163 lines
3.5 KiB
C
163 lines
3.5 KiB
C
/* ************************************************************************** */
|
|
/* */
|
|
/* ::: :::::::: */
|
|
/* parsing.c :+: :+: :+: */
|
|
/* +:+ +:+ +:+ */
|
|
/* By: tomoron <tomoron@student.42angouleme.fr> +#+ +:+ +#+ */
|
|
/* +#+#+#+#+#+ +#+ */
|
|
/* Created: 2025/04/26 17:01:53 by tomoron #+# #+# */
|
|
/* Updated: 2025/08/18 15:50:29 by tomoron ### ########.fr */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
#include "includes/ft_ping.h"
|
|
|
|
int get_set_int(char *arg, t_settings *set)
|
|
{
|
|
char *tmp;
|
|
|
|
tmp = arg;
|
|
while(*tmp)
|
|
{
|
|
if(!isdigit(*tmp))
|
|
{
|
|
fprintf(stderr, "%s: invalid value (`%s' near `%s')\n", set->name, arg, tmp);
|
|
set->err = 1;
|
|
return(0);
|
|
}
|
|
tmp++;
|
|
}
|
|
return(atoi(arg));
|
|
}
|
|
|
|
double get_set_float(char *arg, t_settings *set)
|
|
{
|
|
char *tmp;
|
|
int point;
|
|
|
|
tmp = arg;
|
|
while(*tmp)
|
|
{
|
|
if((!isdigit(*tmp) && *tmp != '.') || (*tmp == '.' && point))
|
|
{
|
|
fprintf(stderr, "%s: invalid value (`%s' near `%s')\n", set->name, arg, tmp);
|
|
set->err = 1;
|
|
return(0);
|
|
}
|
|
if(*tmp == '.')
|
|
point = 1;
|
|
tmp++;
|
|
}
|
|
return(atof(arg));
|
|
}
|
|
|
|
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)
|
|
{
|
|
fprintf(stderr, "%s: option value too big: %d\n", name, set->ttl);
|
|
return(0);
|
|
}
|
|
}
|
|
if (set->interval < 0.2)
|
|
{
|
|
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);
|
|
break;
|
|
case 'h':
|
|
case '?':
|
|
show_help(set);
|
|
return (1);
|
|
default :
|
|
break ;
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|