]>
Commit | Line | Data |
---|---|---|
c8f4eac4 | 1 | /* |
b510f3a1 | 2 | * DEBUG: section 03 Configuration File Parsing |
c8f4eac4 | 3 | * AUTHOR: Harvest Derived |
4 | * | |
5 | * SQUID Web Proxy Cache http://www.squid-cache.org/ | |
6 | * ---------------------------------------------------------- | |
7 | * | |
8 | * Squid is the result of efforts by numerous individuals from | |
9 | * the Internet community; see the CONTRIBUTORS file for full | |
10 | * details. Many organizations have provided support for Squid's | |
11 | * development; see the SPONSORS file for full details. Squid is | |
12 | * Copyrighted (C) 2001 by the Regents of the University of | |
13 | * California; see the COPYRIGHT file for full details. Squid | |
14 | * incorporates software developed and/or copyrighted by other | |
15 | * sources; see the CREDITS file for full details. | |
16 | * | |
17 | * This program is free software; you can redistribute it and/or modify | |
18 | * it under the terms of the GNU General Public License as published by | |
19 | * the Free Software Foundation; either version 2 of the License, or | |
20 | * (at your option) any later version. | |
26ac0430 | 21 | * |
c8f4eac4 | 22 | * This program is distributed in the hope that it will be useful, |
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25 | * GNU General Public License for more details. | |
26ac0430 | 26 | * |
c8f4eac4 | 27 | * You should have received a copy of the GNU General Public License |
28 | * along with this program; if not, write to the Free Software | |
29 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
30 | * | |
31 | */ | |
32 | ||
f7f3304a | 33 | #include "squid.h" |
8a01b99e | 34 | #include "cache_cf.h" |
27bc2077 | 35 | #include "compat/strtoll.h" |
079a8480 | 36 | #include "ConfigParser.h" |
c8f4eac4 | 37 | #include "Parsing.h" |
54a063a2 TX |
38 | #include "globals.h" |
39 | #include "Debug.h" | |
c8f4eac4 | 40 | |
41 | /* | |
42 | * These functions is the same as atoi/l/f, except that they check for errors | |
43 | */ | |
44 | ||
0e656b69 | 45 | double |
46 | xatof(const char *token) | |
c8f4eac4 | 47 | { |
54a063a2 | 48 | char *end = NULL; |
0e656b69 | 49 | double ret = strtod(token, &end); |
c8f4eac4 | 50 | |
54a063a2 TX |
51 | if (ret == 0 && end == token) { |
52 | debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: No digits were found in the input value '" << token << "'."); | |
c8f4eac4 | 53 | self_destruct(); |
54a063a2 TX |
54 | } |
55 | ||
56 | if (*end) { | |
57 | debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Invalid value: '" << token << "' is supposed to be a number."); | |
58 | self_destruct(); | |
59 | } | |
c8f4eac4 | 60 | |
61 | return ret; | |
62 | } | |
63 | ||
64 | int | |
65 | xatoi(const char *token) | |
66 | { | |
54a063a2 TX |
67 | int64_t input = xatoll(token, 10); |
68 | int ret = (int) input; | |
69 | ||
70 | if (input != static_cast<int64_t>(ret)) { | |
71 | debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'int'."); | |
72 | self_destruct(); | |
73 | } | |
74 | ||
75 | return ret; | |
76 | } | |
77 | ||
78 | unsigned int | |
e398d16e | 79 | xatoui(const char *token, char eov) |
54a063a2 | 80 | { |
e398d16e | 81 | int64_t input = xatoll(token, 10, eov); |
54a063a2 TX |
82 | if (input < 0) { |
83 | debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The input value '" << token << "' cannot be less than 0."); | |
84 | self_destruct(); | |
85 | } | |
86 | ||
87 | unsigned int ret = (unsigned int) input; | |
88 | if (input != static_cast<int64_t>(ret)) { | |
89 | debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'unsigned int'."); | |
90 | self_destruct(); | |
91 | } | |
92 | ||
93 | return ret; | |
c8f4eac4 | 94 | } |
95 | ||
0e656b69 | 96 | long |
97 | xatol(const char *token) | |
98 | { | |
54a063a2 TX |
99 | int64_t input = xatoll(token, 10); |
100 | long ret = (long) input; | |
101 | ||
102 | if (input != static_cast<int64_t>(ret)) { | |
103 | debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'long'."); | |
104 | self_destruct(); | |
105 | } | |
106 | ||
107 | return ret; | |
108 | } | |
109 | ||
110 | int64_t | |
e398d16e | 111 | xatoll(const char *token, int base, char eov) |
54a063a2 TX |
112 | { |
113 | char *end = NULL; | |
114 | int64_t ret = strtoll(token, &end, base); | |
0e656b69 | 115 | |
54a063a2 TX |
116 | if (end == token) { |
117 | debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: No digits were found in the input value '" << token << "'."); | |
0e656b69 | 118 | self_destruct(); |
54a063a2 TX |
119 | } |
120 | ||
e398d16e | 121 | if (*end != eov) { |
54a063a2 TX |
122 | debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Invalid value: '" << token << "' is supposed to be a number."); |
123 | self_destruct(); | |
124 | } | |
0e656b69 | 125 | |
126 | return ret; | |
127 | } | |
128 | ||
129 | unsigned short | |
130 | xatos(const char *token) | |
131 | { | |
132 | long port = xatol(token); | |
133 | ||
54a063a2 TX |
134 | if (port < 0) { |
135 | debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' cannot be less than 0."); | |
136 | self_destruct(); | |
137 | } | |
138 | ||
139 | if (port & ~0xFFFF) { | |
140 | debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'short'."); | |
0e656b69 | 141 | self_destruct(); |
54a063a2 | 142 | } |
0e656b69 | 143 | |
144 | return port; | |
145 | } | |
146 | ||
b1fb3348 AJ |
147 | int64_t |
148 | GetInteger64(void) | |
149 | { | |
150 | char *token = strtok(NULL, w_space); | |
b1fb3348 AJ |
151 | |
152 | if (token == NULL) | |
153 | self_destruct(); | |
154 | ||
54a063a2 | 155 | return xatoll(token, 10); |
b1fb3348 AJ |
156 | } |
157 | ||
54a063a2 TX |
158 | /* |
159 | * This function is different from others (e.g., GetInteger64, GetShort) | |
160 | * because it supports octal and hexadecimal numbers | |
161 | */ | |
c8f4eac4 | 162 | int |
163 | GetInteger(void) | |
164 | { | |
079a8480 | 165 | char *token = ConfigParser::strtokFile(); |
c8f4eac4 | 166 | int i; |
167 | ||
168 | if (token == NULL) | |
169 | self_destruct(); | |
170 | ||
54a063a2 TX |
171 | // The conversion must honor 0 and 0x prefixes, which are important for things like umask |
172 | int64_t ret = xatoll(token, 0); | |
173 | ||
174 | i = (int) ret; | |
175 | if (ret != static_cast<int64_t>(i)) { | |
176 | debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'int'."); | |
c8f4eac4 | 177 | self_destruct(); |
54a063a2 | 178 | } |
c8f4eac4 | 179 | |
180 | return i; | |
181 | } | |
182 | ||
54a063a2 TX |
183 | /* |
184 | * This function is similar as GetInteger() but the token might contain | |
185 | * the percentage symbol (%) and we check whether the value is in the range | |
186 | * of [0, 100] | |
187 | * So, we accept two types of input: 1. XX% or 2. XX , 0<=XX<=100 | |
188 | */ | |
189 | int | |
190 | GetPercentage(void) | |
191 | { | |
192 | int p; | |
193 | char *token = strtok(NULL, w_space); | |
194 | ||
f5bc7b15 AJ |
195 | if (!token) { |
196 | debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: A percentage value is missing."); | |
197 | self_destruct(); | |
198 | } | |
199 | ||
54a063a2 TX |
200 | //if there is a % in the end of the digits, we remove it and go on. |
201 | char* end = &token[strlen(token)-1]; | |
202 | if (*end == '%') { | |
203 | *end = '\0'; | |
204 | } | |
205 | ||
206 | p = xatoi(token); | |
207 | ||
208 | if (p < 0 || p > 100) { | |
209 | debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is out of range. A percentage should be within [0, 100]."); | |
210 | self_destruct(); | |
211 | } | |
212 | ||
213 | return p; | |
214 | } | |
215 | ||
f45dd259 | 216 | unsigned short |
0e656b69 | 217 | GetShort(void) |
218 | { | |
219 | char *token = strtok(NULL, w_space); | |
220 | ||
221 | if (token == NULL) | |
222 | self_destruct(); | |
223 | ||
224 | return xatos(token); | |
225 | } | |
226 | ||
053b1f59 | 227 | bool |
228 | StringToInt(const char *s, int &result, const char **p, int base) | |
229 | { | |
230 | if (s) { | |
231 | char *ptr = 0; | |
232 | const int h = (int) strtol(s, &ptr, base); | |
233 | ||
234 | if (ptr != s && ptr) { | |
235 | result = h; | |
236 | ||
237 | if (p) | |
238 | *p = ptr; | |
239 | ||
240 | return true; | |
241 | } | |
242 | } | |
243 | ||
244 | return false; | |
245 | } | |
47f6e231 | 246 | |
247 | bool | |
248 | StringToInt64(const char *s, int64_t &result, const char **p, int base) | |
249 | { | |
250 | if (s) { | |
251 | char *ptr = 0; | |
252 | const int64_t h = (int64_t) strtoll(s, &ptr, base); | |
253 | ||
254 | if (ptr != s && ptr) { | |
255 | result = h; | |
256 | ||
257 | if (p) | |
258 | *p = ptr; | |
259 | ||
260 | return true; | |
261 | } | |
262 | } | |
263 | ||
264 | return false; | |
265 | } | |
82b7abe3 AJ |
266 | |
267 | bool | |
b7ac5457 | 268 | GetHostWithPort(char *token, Ip::Address *ipa) |
82b7abe3 AJ |
269 | { |
270 | char *t; | |
271 | char *host; | |
272 | char *tmp; | |
273 | unsigned short port; | |
274 | ||
275 | host = NULL; | |
276 | port = 0; | |
277 | ||
82b7abe3 AJ |
278 | if (*token == '[') { |
279 | /* [host]:port */ | |
280 | host = token + 1; | |
281 | t = strchr(host, ']'); | |
282 | if (!t) | |
283 | return false; | |
f412b2d6 FC |
284 | *t = '\0'; |
285 | ++t; | |
82b7abe3 AJ |
286 | if (*t != ':') |
287 | return false; | |
288 | port = xatos(t + 1); | |
055421ee AJ |
289 | } else if ((t = strchr(token, ':'))) { |
290 | /* host:port */ | |
291 | host = token; | |
292 | *t = '\0'; | |
293 | port = xatos(t + 1); | |
294 | ||
295 | if (0 == port) | |
296 | return false; | |
54a063a2 TX |
297 | } else if (strtol(token, &tmp, 10) && !*tmp) { |
298 | port = xatos(token); | |
055421ee AJ |
299 | } else { |
300 | host = token; | |
301 | port = 0; | |
302 | } | |
82b7abe3 AJ |
303 | |
304 | if (NULL == host) | |
4dd643d5 | 305 | ipa->setAnyAddr(); |
82b7abe3 AJ |
306 | else if ( ipa->GetHostByName(host) ) /* dont use ipcache. Accept either FQDN or IPA. */ |
307 | (void) 0; | |
308 | else | |
309 | return false; | |
310 | ||
311 | /* port MUST be set after the IPA lookup/conversion is performed. */ | |
4dd643d5 | 312 | ipa->port(port); |
82b7abe3 AJ |
313 | |
314 | return true; | |
315 | } |