1149749Sdes/* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */ 2149749Sdes 3149749Sdes/* 4149749Sdes * Copyright (c) 2004 Ted Unangst and Todd Miller 5149749Sdes * All rights reserved. 6149749Sdes * 7149749Sdes * Permission to use, copy, modify, and distribute this software for any 8149749Sdes * purpose with or without fee is hereby granted, provided that the above 9149749Sdes * copyright notice and this permission notice appear in all copies. 10149749Sdes * 11149749Sdes * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12149749Sdes * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13149749Sdes * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14149749Sdes * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15149749Sdes * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16149749Sdes * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17149749Sdes * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18149749Sdes */ 19149749Sdes 20157016Sdes/* OPENBSD ORIGINAL: lib/libc/stdlib/strtonum.c */ 21157016Sdes 22149749Sdes#include "includes.h" 23162852Sdes 24149749Sdes#ifndef HAVE_STRTONUM 25162852Sdes#include <stdlib.h> 26149749Sdes#include <limits.h> 27162852Sdes#include <errno.h> 28149749Sdes 29149749Sdes#define INVALID 1 30149749Sdes#define TOOSMALL 2 31149749Sdes#define TOOLARGE 3 32149749Sdes 33149749Sdeslong long 34149749Sdesstrtonum(const char *numstr, long long minval, long long maxval, 35149749Sdes const char **errstrp) 36149749Sdes{ 37149749Sdes long long ll = 0; 38149749Sdes char *ep; 39149749Sdes int error = 0; 40149749Sdes struct errval { 41149749Sdes const char *errstr; 42149749Sdes int err; 43149749Sdes } ev[4] = { 44149749Sdes { NULL, 0 }, 45149749Sdes { "invalid", EINVAL }, 46149749Sdes { "too small", ERANGE }, 47149749Sdes { "too large", ERANGE }, 48149749Sdes }; 49149749Sdes 50149749Sdes ev[0].err = errno; 51149749Sdes errno = 0; 52149749Sdes if (minval > maxval) 53149749Sdes error = INVALID; 54149749Sdes else { 55149749Sdes ll = strtoll(numstr, &ep, 10); 56149749Sdes if (numstr == ep || *ep != '\0') 57149749Sdes error = INVALID; 58149749Sdes else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) 59149749Sdes error = TOOSMALL; 60149749Sdes else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) 61149749Sdes error = TOOLARGE; 62149749Sdes } 63149749Sdes if (errstrp != NULL) 64149749Sdes *errstrp = ev[error].errstr; 65149749Sdes errno = ev[error].err; 66149749Sdes if (error) 67149749Sdes ll = 0; 68149749Sdes 69149749Sdes return (ll); 70149749Sdes} 71149749Sdes 72149749Sdes#endif /* HAVE_STRTONUM */ 73