Parsing.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* DEBUG: section 03 Configuration File Parsing */
10 
11 #include "squid.h"
12 #include "cache_cf.h"
13 #include "compat/strtoll.h"
14 #include "ConfigParser.h"
15 #include "Debug.h"
16 #include "globals.h"
17 #include "Parsing.h"
18 
19 /*
20  * These functions is the same as atoi/l/f, except that they check for errors
21  */
22 
23 double
24 xatof(const char *token)
25 {
26  char *end = NULL;
27  double ret = strtod(token, &end);
28 
29  if (ret == 0 && end == token) {
30  debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: No digits were found in the input value '" << token << "'.");
31  self_destruct();
32  }
33 
34  if (*end) {
35  debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Invalid value: '" << token << "' is supposed to be a number.");
36  self_destruct();
37  }
38 
39  return ret;
40 }
41 
42 int
43 xatoi(const char *token)
44 {
45  int64_t input = xatoll(token, 10);
46  int ret = (int) input;
47 
48  if (input != static_cast<int64_t>(ret)) {
49  debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'int'.");
50  self_destruct();
51  }
52 
53  return ret;
54 }
55 
56 unsigned int
57 xatoui(const char *token, char eov)
58 {
59  int64_t input = xatoll(token, 10, eov);
60  if (input < 0) {
61  debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The input value '" << token << "' cannot be less than 0.");
62  self_destruct();
63  }
64 
65  unsigned int ret = (unsigned int) input;
66  if (input != static_cast<int64_t>(ret)) {
67  debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'unsigned int'.");
68  self_destruct();
69  }
70 
71  return ret;
72 }
73 
74 long
75 xatol(const char *token)
76 {
77  int64_t input = xatoll(token, 10);
78  long ret = (long) input;
79 
80  if (input != static_cast<int64_t>(ret)) {
81  debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'long'.");
82  self_destruct();
83  }
84 
85  return ret;
86 }
87 
88 int64_t
89 xatoll(const char *token, int base, char eov)
90 {
91  char *end = NULL;
92  int64_t ret = strtoll(token, &end, base);
93 
94  if (end == token) {
95  debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: No digits were found in the input value '" << token << "'.");
96  self_destruct();
97  }
98 
99  if (*end != eov) {
100  debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Invalid value: '" << token << "' is supposed to be a number.");
101  self_destruct();
102  }
103 
104  return ret;
105 }
106 
107 unsigned short
108 xatos(const char *token)
109 {
110  long port = xatol(token);
111 
112  if (port < 0) {
113  debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' cannot be less than 0.");
114  self_destruct();
115  }
116 
117  if (port & ~0xFFFF) {
118  debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'short'.");
119  self_destruct();
120  }
121 
122  return port;
123 }
124 
125 int64_t
127 {
128  char *token = ConfigParser::NextToken();
129  if (!token) {
130  self_destruct();
131  return -1; // not reachable
132  }
133 
134  return xatoll(token, 10);
135 }
136 
137 /*
138  * This function is different from others (e.g., GetInteger64, GetShort)
139  * because it supports octal and hexadecimal numbers
140  */
141 int
143 {
144  char *token = ConfigParser::NextToken();
145  int i;
146 
147  if (!token) {
148  self_destruct();
149  return -1; // not reachable
150  }
151 
152  // The conversion must honor 0 and 0x prefixes, which are important for things like umask
153  int64_t ret = xatoll(token, 0);
154 
155  i = (int) ret;
156  if (ret != static_cast<int64_t>(i)) {
157  debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'int'.");
158  self_destruct();
159  }
160 
161  return i;
162 }
163 
164 /*
165  * This function is similar as GetInteger() but the token might contain
166  * the percentage symbol (%) and we check whether the value is in the range
167  * of [0, 100]
168  * So, we accept two types of input: 1. XX% or 2. XX , 0<=XX<=100
169  * unless the limit parameter is set to false.
170  */
171 double
172 GetPercentage(bool limit)
173 {
174  char *token = ConfigParser::NextToken();
175 
176  if (!token) {
177  debugs(3, DBG_CRITICAL, "FATAL: A percentage value is missing.");
178  self_destruct();
179  return 0.0; // not reachable
180  }
181 
182  //if there is a % in the end of the digits, we remove it and go on.
183  char* end = &token[strlen(token)-1];
184  if (*end == '%') {
185  *end = '\0';
186  }
187 
188  int p = xatoi(token);
189 
190  if (p < 0 || (limit && p > 100)) {
191  debugs(3, DBG_CRITICAL, "FATAL: The value '" << token << "' is out of range. A percentage should be within [0, 100].");
192  self_destruct();
193  }
194 
195  return static_cast<double>(p) / 100.0;
196 }
197 
198 unsigned short
199 GetShort(void)
200 {
201  char *token = ConfigParser::NextToken();
202  if (!token) {
203  self_destruct();
204  return 0; // not reachable
205  }
206 
207  return xatos(token);
208 }
209 
210 bool
211 StringToInt(const char *s, int &result, const char **p, int base)
212 {
213  if (s) {
214  char *ptr = 0;
215  const int h = (int) strtol(s, &ptr, base);
216 
217  if (ptr != s && ptr) {
218  result = h;
219 
220  if (p)
221  *p = ptr;
222 
223  return true;
224  }
225  }
226 
227  return false;
228 }
229 
230 bool
231 StringToInt64(const char *s, int64_t &result, const char **p, int base)
232 {
233  if (s) {
234  char *ptr = 0;
235  const int64_t h = (int64_t) strtoll(s, &ptr, base);
236 
237  if (ptr != s && ptr) {
238  result = h;
239 
240  if (p)
241  *p = ptr;
242 
243  return true;
244  }
245  }
246 
247  return false;
248 }
249 
250 bool
251 GetHostWithPort(char *token, Ip::Address *ipa)
252 {
253  char *t;
254  char *host;
255  char *tmp;
256  unsigned short port;
257 
258  host = NULL;
259  port = 0;
260 
261  if (*token == '[') {
262  /* [host]:port */
263  host = token + 1;
264  t = strchr(host, ']');
265  if (!t)
266  return false;
267  *t = '\0';
268  ++t;
269  if (*t != ':')
270  return false;
271  port = xatos(t + 1);
272  } else if ((t = strchr(token, ':'))) {
273  /* host:port */
274  host = token;
275  *t = '\0';
276  port = xatos(t + 1);
277 
278  if (0 == port)
279  return false;
280  } else if (strtol(token, &tmp, 10) && !*tmp) {
281  port = xatos(token);
282  } else {
283  host = token;
284  port = 0;
285  }
286 
287  if (NULL == host)
288  ipa->setAnyAddr();
289  else if ( ipa->GetHostByName(host) ) /* dont use ipcache. Accept either FQDN or IPA. */
290  (void) 0;
291  else
292  return false;
293 
294  /* port MUST be set after the IPA lookup/conversion is performed. */
295  ipa->port(port);
296 
297  return true;
298 }
299 
int xatoi(const char *token)
Definition: Parsing.cc:43
int GetInteger(void)
Definition: Parsing.cc:142
unsigned short GetShort(void)
Definition: Parsing.cc:199
unsigned int xatoui(const char *token, char eov)
Definition: Parsing.cc:57
void self_destruct(void)
Definition: cache_cf.cc:255
int i
Definition: membanger.c:49
long xatol(const char *token)
Definition: Parsing.cc:75
#define DBG_CRITICAL
Definition: Debug.h:44
int64_t xatoll(const char *token, int base, char eov)
Definition: Parsing.cc:89
char * p
Definition: membanger.c:43
#define DBG_PARSE_NOTE(x)
Definition: Debug.h:49
bool StringToInt(const char *s, int &result, const char **p, int base)
Definition: Parsing.cc:211
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:123
#define DBG_IMPORTANT
Definition: Debug.h:45
static char * NextToken()
static int port
Definition: ldap_backend.cc:69
unsigned short xatos(const char *token)
Definition: Parsing.cc:108
bool StringToInt64(const char *s, int64_t &result, const char **p, int base)
Definition: Parsing.cc:231
unsigned short port() const
Definition: Address.cc:786
bool SIGHDLR int STUB void int
Definition: stub_tools.cc:68
bool GetHostByName(const char *s)
Definition: Address.cc:372
double GetPercentage(bool limit)
Definition: Parsing.cc:172
void setAnyAddr()
NOTE: Does NOT clear the Port stored. Ony the Address and Type.
Definition: Address.cc:170
bool GetHostWithPort(char *token, Ip::Address *ipa)
Definition: Parsing.cc:251
int64_t strtoll(const char *nptr, char **endptr, int base)
Definition: strtoll.c:81
double xatof(const char *token)
Definition: Parsing.cc:24
int64_t GetInteger64(void)
Definition: Parsing.cc:126
#define NULL
Definition: types.h:166

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors