1 /* grecs - Gray's Extensible Configuration System
2    Copyright (C) 2007-2016 Sergey Poznyakoff
3 
4    Grecs is free software; you can redistribute it and/or modify it
5    under the terms of the GNU General Public License as published by the
6    Free Software Foundation; either version 3 of the License, or (at your
7    option) any later version.
8 
9    Grecs is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License along
15    with Grecs. If not, see <http://www.gnu.org/licenses/>. */
16 
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20 #include <string.h>
21 #include <ctype.h>
22 #include "grecs.h"
23 
24 int
grecs_str_is_ipv4(const char * addr)25 grecs_str_is_ipv4(const char *addr)
26 {
27         int dot_count = 0;
28         int digit_count = 0;
29 
30 	for (; *addr; addr++) {
31 		if (!isascii(*addr))
32 			return 0;
33                 if (*addr == '.') {
34                         if (++dot_count > 3)
35                                 break;
36                         digit_count = 0;
37                 } else if (!(isdigit(*addr) && ++digit_count <= 3))
38                         return 0;
39         }
40 
41         return (dot_count == 3);
42 }
43 
44 int
grecs_str_is_ipv6(const char * addr)45 grecs_str_is_ipv6(const char *addr)
46 {
47         int col_count = 0; /* Number of colons */
48 	int dcol = 0;      /* Did we encounter a double-colon? */
49 	int dig_count = 0; /* Number of digits in the last group */
50 
51 	for (; *addr; addr++) {
52 		if (!isascii(*addr))
53 			return 0;
54 		else if (isxdigit(*addr)) {
55 			if (++dig_count > 4)
56 				return 0;
57 		} else if (*addr == ':') {
58 			if (col_count && dig_count == 0 && ++dcol > 1)
59 				return 0;
60 			if (++col_count > 7)
61 				return 0;
62 			dig_count = 0;
63 		} else
64 			return 0;
65 	}
66 
67 	return (col_count == 7 || dcol);
68 }
69 
70 int
grecs_str_is_num(const char * s)71 grecs_str_is_num(const char *s)
72 {
73 	for (; *s; ++s)
74 		if (!isdigit(*s))
75 			return 0;
76 	return 1;
77 }
78 
79 int
grecs_str_is_ipaddr(const char * addr)80 grecs_str_is_ipaddr(const char *addr)
81 {
82 	if (strchr (addr, '.'))
83 		return grecs_str_is_ipv4(addr);
84 	else if (strchr (addr, ':'))
85 		return grecs_str_is_ipv6(addr);
86 	return 0;
87 }
88 
89