4a957d84835ae18d06329333694a7e4197870f96
[olsrd.git] / lib / pud / src / configTools.c
1 #include "configTools.h"
2
3 /* Plugin includes */
4 #include "pud.h"
5 #include "netTools.h"
6
7 /* OLSR includes */
8
9 /* System includes */
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <assert.h>
13 #include <arpa/inet.h>
14 #include <ctype.h>
15 #include <string.h>
16
17 /**
18  Read a boolean from a string
19
20  @param parameterName
21  The name of the parameter, used when reporting errors
22  @param str
23  The string to convert to a boolean
24  @param dst
25  A pointer to the location where to store the boolean upon successful conversion
26  Not touched when errors are reported.
27
28  @return
29  - true on success
30  - false otherwise
31  */
32 bool readBool(const char * parameterName, const char * str, bool * dst) {
33         bool retVal = true;
34         char * endPtr = NULL;
35         unsigned long value;
36         char * strDup = strdup(str);
37         char * c;
38
39         assert(parameterName != NULL);
40         assert(str != NULL);
41         assert(dst != NULL);
42
43         /* convert to lowercase */
44         for (c = strDup; *c != '\0'; c++) {
45                 if (isalpha(*c) && !islower(*c)) {
46                         *c = tolower(*c);
47                 }
48         }
49
50         /* try true/yes/on */
51         if (!strcmp("true", strDup) || !strcmp("yes", strDup) || !strcmp("on", strDup)) {
52                 *dst = true;
53                 goto out;
54         }
55
56         /* try false/no/off */
57         if (!strcmp("false", strDup) || !strcmp("no", strDup) || !strcmp("off", strDup)) {
58                 *dst = false;
59                 goto out;
60         }
61
62         /* try a number */
63         errno = 0;
64         value = strtoul(str, &endPtr, 10);
65
66         if (!((endPtr != str) && (*str != '\0') && (*endPtr == '\0'))) {
67                 /* invalid conversion */
68                 pudError(false, "Value of parameter %s (%s) could not be converted to a number", parameterName, str);
69                 retVal = false;
70                 goto out;
71         }
72
73         if (value > 1) {
74                 pudError(false, "Value of parameter %s (%lu) is outside of valid range 0-1", parameterName, value);
75                 retVal = false;
76                 goto out;
77         }
78
79         /* 0 = false, 1 = true */
80         *dst = (value == 1);
81
82         out: free(strDup);
83         return retVal;
84 }
85
86 /**
87  Read an unsigned char number from a string
88
89  @param parameterName
90  The name of the parameter, used when reporting errors
91  @param str
92  The string to convert to a number
93  @param dst
94  A pointer to the location where to store the number upon successful conversion
95  Not touched when errors are reported.
96
97  @return
98  - true on success
99  - false otherwise
100  */
101 bool readUC(const char * parameterName, const char * str, unsigned char * dst) {
102         char * endPtr = NULL;
103         unsigned long value;
104
105         assert(parameterName != NULL);
106         assert(str != NULL);
107         assert(dst != NULL);
108
109         errno = 0;
110         value = strtoul(str, &endPtr, 10);
111
112         if (!((endPtr != str) && (*str != '\0') && (*endPtr == '\0'))) {
113                 /* invalid conversion */
114                 pudError(false, "Value of parameter %s (%s) could not be converted to a number", parameterName, str);
115                 return false;
116         }
117
118         if (value > 255) {
119                 pudError(false, "Value of parameter %s (%lu) is outside of valid range 0-255", parameterName, value);
120                 return false;
121         }
122
123         *dst = value;
124         return true;
125 }
126
127 /**
128  Read an unsigned short number from a string
129
130  @param parameterName
131  The name of the parameter, used when reporting errors
132  @param str
133  The string to convert to a number
134  @param dst
135  A pointer to the location where to store the number upon successful conversion
136  Not touched when errors are reported.
137
138  @return
139  - true on success
140  - false otherwise
141  */
142 bool readUS(const char * parameterName, const char * str, unsigned short * dst) {
143         char * endPtr = NULL;
144         unsigned long value;
145
146         assert(parameterName != NULL);
147         assert(str != NULL);
148         assert(dst != NULL);
149
150         errno = 0;
151         value = strtoul(str, &endPtr, 10);
152
153         if (!((endPtr != str) && (*str != '\0') && (*endPtr == '\0'))) {
154                 /* invalid conversion */
155                 pudError(false, "Value of parameter %s (%s) could not be converted to a number", parameterName, str);
156                 return false;
157         }
158
159         if (value > 65535) {
160                 pudError(false, "Value of parameter %s (%lu) is outside of valid range 0-65535", parameterName, value);
161                 return false;
162         }
163
164         *dst = value;
165         return true;
166 }
167
168 /**
169  Read an unsigned long long number from a string
170
171  @param parameterName
172  The name of the parameter, used when reporting errors
173  @param str
174  The string to convert to a number
175  @param dst
176  A pointer to the location where to store the number upon successful conversion
177  Not touched when errors are reported.
178
179  @return
180  - true on success
181  - false otherwise
182  */
183 bool readULL(const char * parameterName, const char * str, unsigned long long * dst) {
184         char * endPtr = NULL;
185         unsigned long long value;
186
187         assert(parameterName != NULL);
188         assert(str != NULL);
189         assert(dst != NULL);
190
191         errno = 0;
192         value = strtoull(str, &endPtr, 10);
193
194         if (!((endPtr != str) && (*str != '\0') && (*endPtr == '\0'))) {
195                 /* invalid conversion */
196                 pudError(false, "Value of parameter %s (%s) could not be converted to a number", parameterName, str);
197                 return false;
198         }
199
200         *dst = value;
201         return true;
202 }
203
204 /**
205  Read a double number from a string
206
207  @param parameterName
208  The name of the parameter, used when reporting errors
209  @param str
210  The string to convert to a number
211  @param dst
212  A pointer to the location where to store the number upon successful conversion
213  Not touched when errors are reported.
214
215  @return
216  - true on success
217  - false otherwise
218  */
219  bool readDouble(const char * parameterName, const char * str, double * dst) {
220         char * endPtr = NULL;
221         double value;
222
223         assert(parameterName != NULL);
224         assert(str != NULL);
225         assert(dst != NULL);
226
227         errno = 0;
228         value = strtod(str, &endPtr);
229
230         if (!((endPtr != str) && (*str != '\0') && (*endPtr == '\0'))) {
231                 /* invalid conversion */
232                 pudError(false, "Value of parameter %s (%s) could not be converted to a number", parameterName, str);
233                 return false;
234         }
235
236         *dst = value;
237         return true;
238 }
239
240 /**
241  Read an (olsr_sockaddr) IP address from a string:
242  First tries to parse the value as an IPv4 address, and if not successful tries to parse it as an IPv6 address.
243  When the address wasn't set yet, the default port (portDefault) is set.
244
245  @param parameterName
246  The name of the parameter, used when reporting errors
247  @param str
248  The string to convert to an (olsr_sockaddr) IP address
249  @param portDefault
250  The default for the port (in host byte order, stored in network byte order)
251  @param dst
252  A pointer to the location where to store the (olsr_sockadd) IP address upon successful conversion.
253  Not touched when errors are reported.
254  @param dstSet
255  A pointer to the location where to store the flag that signals whether the IP address is set.
256  Not touched when errors are reported.
257
258  @return
259  - true on success
260  - false otherwise
261  */
262  bool readIPAddress(const char * parameterName, const char * str, in_port_t portDefault,
263                 union olsr_sockaddr * dst, bool * dstSet) {
264         union olsr_sockaddr ip;
265         int conversion;
266
267         assert(parameterName != NULL);
268         assert(str != NULL);
269         assert(dst != NULL);
270         assert(dstSet != NULL);
271
272         /* try IPv4 first */
273         memset(&ip, 0, sizeof(ip));
274         ip.in.sa_family = AF_INET;
275         conversion = inet_pton(ip.in.sa_family, str, &ip.in4.sin_addr);
276
277         /* now try IPv6 if IPv4 conversion was not successful */
278         if (conversion != 1) {
279                 memset(&ip, 0, sizeof(ip));
280                 ip.in.sa_family = AF_INET6;
281                 conversion = inet_pton(ip.in.sa_family, str, &ip.in6.sin6_addr);
282         }
283
284         if (conversion != 1) {
285                 pudError((conversion == -1) ? true : false,
286                 "Value of parameter %s (%s) is not an IP address", parameterName, str);
287                 return false;
288         }
289
290         if (!*dstSet) {
291                 setOlsrSockaddrPort(&ip, htons(portDefault));
292         }
293
294   setOlsrSockaddrAddr(dst, &ip);
295         *dstSet = true;
296         return true;
297 }