Merge branch 'release-0.6.6'
[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  @param base
179  The base of the number conversion: 10 for decimal, 16 for hexadecimal
180
181  @return
182  - true on success
183  - false otherwise
184  */
185 bool readULL(const char * parameterName, const char * str, unsigned long long * dst, int base) {
186         char * endPtr = NULL;
187         unsigned long long value;
188
189         assert(parameterName != NULL);
190         assert(str != NULL);
191         assert(dst != NULL);
192         assert(base > 1);
193
194         errno = 0;
195         value = strtoull(str, &endPtr, base);
196
197         if (!((endPtr != str) && (*str != '\0') && (*endPtr == '\0'))) {
198                 /* invalid conversion */
199                 pudError(false, "Value of parameter %s (%s) could not be converted to a number (base %d)", parameterName, str, base);
200                 return false;
201         }
202
203         *dst = value;
204         return true;
205 }
206
207 /**
208  Read a double number from a string
209
210  @param parameterName
211  The name of the parameter, used when reporting errors
212  @param str
213  The string to convert to a number
214  @param dst
215  A pointer to the location where to store the number upon successful conversion
216  Not touched when errors are reported.
217
218  @return
219  - true on success
220  - false otherwise
221  */
222  bool readDouble(const char * parameterName, const char * str, double * dst) {
223         char * endPtr = NULL;
224         double value;
225
226         assert(parameterName != NULL);
227         assert(str != NULL);
228         assert(dst != NULL);
229
230         errno = 0;
231         value = strtod(str, &endPtr);
232
233         if (!((endPtr != str) && (*str != '\0') && (*endPtr == '\0'))) {
234                 /* invalid conversion */
235                 pudError(false, "Value of parameter %s (%s) could not be converted to a number", parameterName, str);
236                 return false;
237         }
238
239         *dst = value;
240         return true;
241 }
242
243 /**
244  Read an (olsr_sockaddr) IP address from a string:
245  First tries to parse the value as an IPv4 address, and if not successful tries to parse it as an IPv6 address.
246  When the address wasn't set yet, the default port (portDefault) is set.
247
248  @param parameterName
249  The name of the parameter, used when reporting errors
250  @param str
251  The string to convert to an (olsr_sockaddr) IP address
252  @param portDefault
253  The default for the port (in host byte order, stored in network byte order)
254  @param dst
255  A pointer to the location where to store the (olsr_sockadd) IP address upon successful conversion.
256  Not touched when errors are reported.
257  @param dstSet
258  A pointer to the location where to store the flag that signals whether the IP address is set.
259  Not touched when errors are reported.
260
261  @return
262  - true on success
263  - false otherwise
264  */
265  bool readIPAddress(const char * parameterName, const char * str, in_port_t portDefault,
266                 union olsr_sockaddr * dst, bool * dstSet) {
267         union olsr_sockaddr ip;
268         int conversion;
269
270         assert(parameterName != NULL);
271         assert(str != NULL);
272         assert(dst != NULL);
273         assert(dstSet != NULL);
274
275         /* try IPv4 first */
276         memset(&ip, 0, sizeof(ip));
277         ip.in.sa_family = AF_INET;
278         conversion = inet_pton(ip.in.sa_family, str, &ip.in4.sin_addr);
279
280         /* now try IPv6 if IPv4 conversion was not successful */
281         if (conversion != 1) {
282                 memset(&ip, 0, sizeof(ip));
283                 ip.in.sa_family = AF_INET6;
284                 conversion = inet_pton(ip.in.sa_family, str, &ip.in6.sin6_addr);
285         }
286
287         if (conversion != 1) {
288                 pudError((conversion == -1) ? true : false,
289                 "Value of parameter %s (%s) is not an IP address", parameterName, str);
290                 return false;
291         }
292
293         if (!*dstSet) {
294                 setOlsrSockaddrPort(&ip, htons(portDefault));
295         }
296
297   setOlsrSockaddrAddr(dst, &ip);
298         *dstSet = true;
299         return true;
300 }