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