#include <sys/cdefs.h>
__RCSID("$NetBSD: support.c,v 1.1 2025/02/06 19:35:28 christos Exp $");
#include <assert.h>
#include <limits.h>
#include <errno.h>
#include <netdb.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tables.h"
#include "support.h"
static bool
parse_numeric(const char *string, int *rv)
{
char *end;
long value;
errno = 0;
value = strtol(string, &end, 0);
if ((string[0] == '\0') || (*end != '\0'))
return false;
if ((errno == ERANGE) && ((value == LONG_MAX) || (value == LONG_MIN)))
return false;
if ((value > INT_MAX) || (value < INT_MIN))
return false;
*rv = (int)value;
return true;
}
bool
parse_af(const char *string, int *afp)
{
return parse_numeric_tabular(string, afp, address_families,
__arraycount(address_families));
}
bool
parse_protocol(const char *string, int *protop)
{
struct protoent *protoent;
if (parse_numeric(string, protop))
return true;
protoent = getprotobyname(string);
if (protoent == NULL)
return false;
*protop = protoent->p_proto;
return true;
}
bool
parse_socktype(const char *string, int *typep)
{
return parse_numeric_tabular(string, typep, socket_types,
__arraycount(socket_types));
}
bool
parse_numeric_tabular(const char *string, int *valuep,
const char *const *table, size_t n)
{
assert((uintmax_t)n <= (uintmax_t)INT_MAX);
if (parse_numeric(string, valuep))
return true;
for (size_t i = 0; i < n; i++)
if ((table[i] != NULL) && (strcmp(string, table[i]) == 0)) {
*valuep = (int)i;
return true;
}
return false;
}