xref: /freebsd/contrib/ntp/libntp/atoint.c (revision b9f654b163bce26de79705e77b872427c9f2afa1)
1 /*
2  * atoint - convert an ascii string to a signed long, with error checking
3  */
4 #include <config.h>
5 #include <sys/types.h>
6 #include <ctype.h>
7 
8 #include "ntp_types.h"
9 #include "ntp_stdlib.h"
10 
11 int
12 atoint(
13 	const char *str,
14 	long *ival
15 	)
16 {
17 	register long u;
18 	register const char *cp;
19 	register int isneg;
20 	register int oflow_digit;
21 
22 	cp = str;
23 
24 	if (*cp == '-') {
25 		cp++;
26 		isneg = 1;
27 		oflow_digit = '8';
28 	} else {
29 		isneg = 0;
30 		oflow_digit = '7';
31 	}
32 
33 	if (*cp == '\0')
34 	    return 0;
35 
36 	u = 0;
37 	while (*cp != '\0') {
38 		if (!isdigit((unsigned char)*cp))
39 		    return 0;
40 		if (u > 214748364 || (u == 214748364 && *cp > oflow_digit))
41 		    return 0;	/* overflow */
42 		u = (u << 3) + (u << 1);
43 		u += *cp++ - '0';	/* ascii dependent */
44 	}
45 
46 	if (isneg)
47 	    *ival = -u;
48 	else
49 	    *ival = u;
50 	return 1;
51 }
52