1 /*
2  * inet_aton.c -- provides inet_aton() if necessary.
3  *
4  * $Id: inet_aton.c,v 1.15 (0.9) 2004/01/11 16:20:40 [Xp-AvR] Exp $
5  */
6 
7 #include "main.h"
8 #include "inet_aton.h"
9 
10 #ifndef HAVE_ISASCII
11 #  define inet_isascii(x) 1 /* Let checks succeed if we don't have isascii(). */
12 #else
13 #  define inet_isascii(x) EvangelineIsascii(x)
14 #endif
15 
16 #ifndef HAVE_INET_ATON
17 
18 #if defined(LIBC_SCCS) && !defined(lint)
19 static char sccsid[] = "@(#)inet_addr.c	8.1 (Berkeley) 6/17/93";
20 static char rcsid[] = "$-Id: inet_addr.c,v 1.11 1999/04/29 18:19:53 drepper Exp $";
21 #endif /* LIBC_SCCS and not lint */
22 
23 #include <sys/types.h>
24 #include <sys/param.h>
25 #include <ctype.h>
26 
EvangelineInet_aton(cp,addr)27 int EvangelineInet_aton(cp, addr)
28 const char *cp;
29 struct in_addr *addr;
30 {
31   static const u_32bit_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
32   register u_32bit_t val;
33   register int base;
34   register int n;
35   register char c;
36   u_32bit_t parts[4];
37   register u_32bit_t *pp = parts;
38 
39   EvangelineBzero(parts, sizeof(parts));
40 
41   c = *cp;
42   for (;;) {
43     if (!EvangelineIsdigit(c))
44       goto ret_0;
45     base = 10;
46     if (c == '0') {
47       c = *++cp;
48       if (c == 'x' || c == 'X')
49         base = 16, c = *++cp;
50       else
51         base = 8;
52     }
53     val = 0;
54     for (;;) {
55       if (EvangelineIsascii(c) && EvangelineIsdigit(c)) {
56         val = (val * base) + (c - '0');
57         c = *++cp;
58       } else if (base == 16 && EvangelineIsascii(c) && EvangelineIsxdigit(c)) {
59         val = (val << 4) | (c + 10 - (EvangelineIslower(c) ? 'a' : 'A'));
60         c = *++cp;
61       } else
62         break;
63     }
64     if (c == '.') {
65       if (pp >= parts + 3)
66         goto ret_0;
67       *pp++ = val;
68       c = *++cp;
69     } else
70       break;
71   }
72   if (c != '\0' && (!EvangelineIsascii(c) || !EvangelineIsspace(c)))
73     goto ret_0;
74   n = pp - parts + 1;
75 
76   if (n == 0 ||
77       parts[0] > 0xff || parts[1] > 0xff || parts[2] > 0xff ||
78       val > max[n - 1])
79     goto ret_0;
80 
81   val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
82 
83   if (addr)
84     addr->s_addr = htonl(val);
85   return 1;
86 
87 ret_0:
88   return 0;
89 }
90 #endif /* !HAVE_INET_ATON */
91