1156707Sandre/*- 2156707Sandre * Copyright (c) 2004 Ted Unangst and Todd Miller 3156707Sandre * All rights reserved. 4156707Sandre * 5156707Sandre * Permission to use, copy, modify, and distribute this software for any 6156707Sandre * purpose with or without fee is hereby granted, provided that the above 7156707Sandre * copyright notice and this permission notice appear in all copies. 8156707Sandre * 9156707Sandre * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10156707Sandre * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11156707Sandre * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12156707Sandre * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13156707Sandre * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14156707Sandre * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15156707Sandre * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16156707Sandre * 17156707Sandre * $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ 18156707Sandre */ 19156707Sandre 20156707Sandre#include <sys/cdefs.h> 21156707Sandre__FBSDID("$FreeBSD$"); 22156707Sandre 23156707Sandre#include <errno.h> 24156707Sandre#include <limits.h> 25156707Sandre#include <stdlib.h> 26156707Sandre 27156707Sandre#define INVALID 1 28156707Sandre#define TOOSMALL 2 29156707Sandre#define TOOLARGE 3 30156707Sandre 31156707Sandrelong long 32156707Sandrestrtonum(const char *numstr, long long minval, long long maxval, 33156707Sandre const char **errstrp) 34156707Sandre{ 35156707Sandre long long ll = 0; 36156707Sandre char *ep; 37156707Sandre int error = 0; 38156707Sandre struct errval { 39156707Sandre const char *errstr; 40156707Sandre int err; 41156707Sandre } ev[4] = { 42156707Sandre { NULL, 0 }, 43156707Sandre { "invalid", EINVAL }, 44156707Sandre { "too small", ERANGE }, 45156707Sandre { "too large", ERANGE }, 46156707Sandre }; 47156707Sandre 48156707Sandre ev[0].err = errno; 49156707Sandre errno = 0; 50156707Sandre if (minval > maxval) 51156707Sandre error = INVALID; 52156707Sandre else { 53156707Sandre ll = strtoll(numstr, &ep, 10); 54156716Sache if (errno == EINVAL || numstr == ep || *ep != '\0') 55156707Sandre error = INVALID; 56156707Sandre else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) 57156707Sandre error = TOOSMALL; 58156707Sandre else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) 59156707Sandre error = TOOLARGE; 60156707Sandre } 61156707Sandre if (errstrp != NULL) 62156707Sandre *errstrp = ev[error].errstr; 63156707Sandre errno = ev[error].err; 64156707Sandre if (error) 65156707Sandre ll = 0; 66156707Sandre 67156707Sandre return (ll); 68156707Sandre} 69