/*-1* Copyright (c) 2004 Ted Unangst and Todd Miller2* All rights reserved.3*4* Permission to use, copy, modify, and distribute this software for any5* purpose with or without fee is hereby granted, provided that the above6* copyright notice and this permission notice appear in all copies.7*8* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES9* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF10* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR11* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES12* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN13* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF14* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.15*16* $OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu Exp $17*/1819#include "bsd_compat.h"2021#if !HAVE_STRTONUM2223#include <errno.h>24#include <limits.h>25#include <stdlib.h>2627#define INVALID 128#define TOOSMALL 229#define TOOLARGE 33031long long32strtonum(const char *numstr, long long minval, long long maxval,33const char **errstrp)34{35long long ll = 0;36int error = 0;37char *ep;38struct errval {39const char *errstr;40int err;41} ev[4] = {42{ NULL, 0 },43{ "invalid", EINVAL },44{ "too small", ERANGE },45{ "too large", ERANGE },46};4748ev[0].err = errno;49errno = 0;50if (minval > maxval) {51error = INVALID;52} else {53ll = strtoll(numstr, &ep, 10);54if (errno == EINVAL || numstr == ep || *ep != '\0')55error = INVALID;56else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)57error = TOOSMALL;58else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)59error = TOOLARGE;60}61if (errstrp != NULL)62*errstrp = ev[error].errstr;63errno = ev[error].err;64if (error)65ll = 0;6667return (ll);68}6970#endif717273