1*2e8d1edaSArun Thomas /* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */
2*2e8d1edaSArun Thomas
3*2e8d1edaSArun Thomas /*
4*2e8d1edaSArun Thomas * Copyright (c) 2004 Ted Unangst and Todd Miller
5*2e8d1edaSArun Thomas * All rights reserved.
6*2e8d1edaSArun Thomas *
7*2e8d1edaSArun Thomas * Permission to use, copy, modify, and distribute this software for any
8*2e8d1edaSArun Thomas * purpose with or without fee is hereby granted, provided that the above
9*2e8d1edaSArun Thomas * copyright notice and this permission notice appear in all copies.
10*2e8d1edaSArun Thomas *
11*2e8d1edaSArun Thomas * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12*2e8d1edaSArun Thomas * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13*2e8d1edaSArun Thomas * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14*2e8d1edaSArun Thomas * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15*2e8d1edaSArun Thomas * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16*2e8d1edaSArun Thomas * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17*2e8d1edaSArun Thomas * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18*2e8d1edaSArun Thomas */
19*2e8d1edaSArun Thomas #if HAVE_NBTOOL_CONFIG_H
20*2e8d1edaSArun Thomas #include "nbtool_config.h"
21*2e8d1edaSArun Thomas #endif
22*2e8d1edaSArun Thomas #include <sys/cdefs.h>
23*2e8d1edaSArun Thomas __RCSID("$NetBSD: strtonum.c,v 1.2 2009/10/26 21:14:18 christos Exp $");
24*2e8d1edaSArun Thomas #include <errno.h>
25*2e8d1edaSArun Thomas #include <limits.h>
26*2e8d1edaSArun Thomas #include <stdlib.h>
27*2e8d1edaSArun Thomas
28*2e8d1edaSArun Thomas #define INVALID 1
29*2e8d1edaSArun Thomas #define TOOSMALL 2
30*2e8d1edaSArun Thomas #define TOOLARGE 3
31*2e8d1edaSArun Thomas
32*2e8d1edaSArun Thomas long long
33*2e8d1edaSArun Thomas strtonum(const char *numstr, long long minval, long long maxval,
34*2e8d1edaSArun Thomas const char **errstrp);
35*2e8d1edaSArun Thomas long long
strtonum(const char * numstr,long long minval,long long maxval,const char ** errstrp)36*2e8d1edaSArun Thomas strtonum(const char *numstr, long long minval, long long maxval,
37*2e8d1edaSArun Thomas const char **errstrp)
38*2e8d1edaSArun Thomas {
39*2e8d1edaSArun Thomas long long ll = 0;
40*2e8d1edaSArun Thomas char *ep;
41*2e8d1edaSArun Thomas int error = 0;
42*2e8d1edaSArun Thomas struct errval {
43*2e8d1edaSArun Thomas const char *errstr;
44*2e8d1edaSArun Thomas int err;
45*2e8d1edaSArun Thomas } ev[4] = {
46*2e8d1edaSArun Thomas { NULL, 0 },
47*2e8d1edaSArun Thomas { "invalid", EINVAL },
48*2e8d1edaSArun Thomas { "too small", ERANGE },
49*2e8d1edaSArun Thomas { "too large", ERANGE },
50*2e8d1edaSArun Thomas };
51*2e8d1edaSArun Thomas
52*2e8d1edaSArun Thomas ev[0].err = errno;
53*2e8d1edaSArun Thomas errno = 0;
54*2e8d1edaSArun Thomas if (minval > maxval)
55*2e8d1edaSArun Thomas error = INVALID;
56*2e8d1edaSArun Thomas else {
57*2e8d1edaSArun Thomas ll = strtoll(numstr, &ep, 10);
58*2e8d1edaSArun Thomas if (numstr == ep || *ep != '\0')
59*2e8d1edaSArun Thomas error = INVALID;
60*2e8d1edaSArun Thomas else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
61*2e8d1edaSArun Thomas error = TOOSMALL;
62*2e8d1edaSArun Thomas else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
63*2e8d1edaSArun Thomas error = TOOLARGE;
64*2e8d1edaSArun Thomas }
65*2e8d1edaSArun Thomas if (errstrp != NULL)
66*2e8d1edaSArun Thomas *errstrp = ev[error].errstr;
67*2e8d1edaSArun Thomas errno = ev[error].err;
68*2e8d1edaSArun Thomas if (error)
69*2e8d1edaSArun Thomas ll = 0;
70*2e8d1edaSArun Thomas
71*2e8d1edaSArun Thomas return (ll);
72*2e8d1edaSArun Thomas }
73*2e8d1edaSArun Thomas
74