xref: /freebsd-src/contrib/ntp/libntp/hextoint.c (revision 416ba5c74546f32a993436a99516d35008e9f384)
1c0b746e5SOllivier Robert /*
2c0b746e5SOllivier Robert  * hextoint - convert an ascii string in hex to an unsigned
3c0b746e5SOllivier Robert  *	      long, with error checking
4c0b746e5SOllivier Robert  */
5*2b15cb3dSCy Schubert #include <config.h>
6c0b746e5SOllivier Robert #include <ctype.h>
7c0b746e5SOllivier Robert 
8c0b746e5SOllivier Robert #include "ntp_stdlib.h"
9c0b746e5SOllivier Robert 
10c0b746e5SOllivier Robert int
hextoint(const char * str,u_long * pu)11c0b746e5SOllivier Robert hextoint(
12c0b746e5SOllivier Robert 	const char *str,
13*2b15cb3dSCy Schubert 	u_long *pu
14c0b746e5SOllivier Robert 	)
15c0b746e5SOllivier Robert {
16c0b746e5SOllivier Robert 	register u_long u;
17c0b746e5SOllivier Robert 	register const char *cp;
18c0b746e5SOllivier Robert 
19c0b746e5SOllivier Robert 	cp = str;
20c0b746e5SOllivier Robert 
21c0b746e5SOllivier Robert 	if (*cp == '\0')
22c0b746e5SOllivier Robert 		return 0;
23c0b746e5SOllivier Robert 
24c0b746e5SOllivier Robert 	u = 0;
25c0b746e5SOllivier Robert 	while (*cp != '\0') {
26*2b15cb3dSCy Schubert 		if (!isxdigit((unsigned char)*cp))
27c0b746e5SOllivier Robert 			return 0;
28*2b15cb3dSCy Schubert 		if (u & 0xF0000000)
29c0b746e5SOllivier Robert 			return 0;	/* overflow */
30c0b746e5SOllivier Robert 		u <<= 4;
31*2b15cb3dSCy Schubert 		if ('0' <= *cp && *cp <= '9')
32c0b746e5SOllivier Robert 			u += *cp++ - '0';
33*2b15cb3dSCy Schubert 		else if ('a' <= *cp && *cp <= 'f')
34c0b746e5SOllivier Robert 			u += *cp++ - 'a' + 10;
35*2b15cb3dSCy Schubert 		else if ('A' <= *cp && *cp <= 'F')
36c0b746e5SOllivier Robert 			u += *cp++ - 'A' + 10;
37*2b15cb3dSCy Schubert 		else
38*2b15cb3dSCy Schubert 			return 0;
39c0b746e5SOllivier Robert 	}
40*2b15cb3dSCy Schubert 	*pu = u;
41c0b746e5SOllivier Robert 	return 1;
42c0b746e5SOllivier Robert }
43