diff options
-rw-r--r-- | src/include/gnunet_configuration_lib.h | 18 | ||||
-rw-r--r-- | src/util/configuration.c | 126 |
2 files changed, 115 insertions, 29 deletions
diff --git a/src/include/gnunet_configuration_lib.h b/src/include/gnunet_configuration_lib.h index bba2900da..18d0f04d2 100644 --- a/src/include/gnunet_configuration_lib.h +++ b/src/include/gnunet_configuration_lib.h | |||
@@ -126,6 +126,24 @@ GNUNET_CONFIGURATION_serialize (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
126 | 126 | ||
127 | 127 | ||
128 | /** | 128 | /** |
129 | * De-serializes configuration | ||
130 | * | ||
131 | * @param cfg configuration to update | ||
132 | * @param mem the memory block of serialized configuration | ||
133 | * @param size the size of the memory block | ||
134 | * @param allow_inline set to GNUNET_YES if we recursively load configuration | ||
135 | * from inlined configurations; GNUNET_NO if not and raise warnings | ||
136 | * when we come across them | ||
137 | * @return GNUNET_OK on success, GNUNET_ERROR on error | ||
138 | */ | ||
139 | int | ||
140 | GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, | ||
141 | const char *mem, | ||
142 | const size_t size, | ||
143 | int allow_inline); | ||
144 | |||
145 | |||
146 | /** | ||
129 | * Write configuration file. | 147 | * Write configuration file. |
130 | * | 148 | * |
131 | * @param cfg configuration to write | 149 | * @param cfg configuration to write |
diff --git a/src/util/configuration.c b/src/util/configuration.c index a9697393d..fea329d75 100644 --- a/src/util/configuration.c +++ b/src/util/configuration.c | |||
@@ -140,46 +140,55 @@ GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg) | |||
140 | 140 | ||
141 | 141 | ||
142 | /** | 142 | /** |
143 | * Parse a configuration file, add all of the options in the | 143 | * De-serializes configuration |
144 | * file to the configuration environment. | ||
145 | * | 144 | * |
146 | * @param cfg configuration to update | 145 | * @param cfg configuration to update |
147 | * @param filename name of the configuration file | 146 | * @param mem the memory block of serialized configuration |
148 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | 147 | * @param size the size of the memory block |
148 | * @param allow_inline set to GNUNET_YES if we recursively load configuration | ||
149 | * from inlined configurations; GNUNET_NO if not and raise warnings | ||
150 | * when we come across them | ||
151 | * @return GNUNET_OK on success, GNUNET_ERROR on error | ||
149 | */ | 152 | */ |
150 | int | 153 | int |
151 | GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, | 154 | GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, |
152 | const char *filename) | 155 | const char *mem, |
156 | const size_t size, | ||
157 | int allow_inline) | ||
153 | { | 158 | { |
154 | int dirty; | ||
155 | char line[256]; | 159 | char line[256]; |
156 | char tag[64]; | 160 | char tag[64]; |
157 | char value[192]; | 161 | char value[192]; |
158 | FILE *fp; | 162 | char *pos; |
159 | unsigned int nr; | 163 | unsigned int nr; |
164 | size_t r_bytes; | ||
165 | size_t to_read; | ||
160 | int i; | 166 | int i; |
161 | int emptyline; | 167 | int emptyline; |
162 | int ret; | 168 | int ret; |
163 | char *section; | 169 | char *section; |
164 | char *fn; | ||
165 | 170 | ||
166 | fn = GNUNET_STRINGS_filename_expand (filename); | ||
167 | if (fn == NULL) | ||
168 | return GNUNET_SYSERR; | ||
169 | dirty = cfg->dirty; /* back up value! */ | ||
170 | if (NULL == (fp = FOPEN (fn, "r"))) | ||
171 | { | ||
172 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fopen", fn); | ||
173 | GNUNET_free (fn); | ||
174 | return GNUNET_SYSERR; | ||
175 | } | ||
176 | GNUNET_free (fn); | ||
177 | ret = GNUNET_OK; | 171 | ret = GNUNET_OK; |
178 | section = GNUNET_strdup (""); | 172 | section = GNUNET_strdup (""); |
179 | memset (line, 0, 256); | ||
180 | nr = 0; | 173 | nr = 0; |
181 | while (NULL != fgets (line, 255, fp)) | 174 | r_bytes = 0; |
175 | memset (line, 0, 256); | ||
176 | while (r_bytes < size) | ||
182 | { | 177 | { |
178 | /* fgets-like behaviour on buffer. read size is 255 bytes */ | ||
179 | to_read = size - r_bytes; | ||
180 | if (to_read > 255) | ||
181 | to_read = 255; | ||
182 | memcpy (line, mem + r_bytes, to_read); | ||
183 | line[to_read] = '\0'; | ||
184 | if (NULL != (pos = strstr (line, "\n"))) | ||
185 | { | ||
186 | pos[1] = '\0'; | ||
187 | r_bytes += (pos - line) + 1; | ||
188 | } | ||
189 | else | ||
190 | r_bytes += to_read; | ||
191 | /* fgets-like behaviour end */ | ||
183 | nr++; | 192 | nr++; |
184 | for (i = 0; i < 255; i++) | 193 | for (i = 0; i < 255; i++) |
185 | if (line[i] == '\t') | 194 | if (line[i] == '\t') |
@@ -197,10 +206,16 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
197 | i--) | 206 | i--) |
198 | line[i] = '\0'; | 207 | line[i] = '\0'; |
199 | if (1 == SSCANF (line, "@INLINE@ %191[^\n]", value)) | 208 | if (1 == SSCANF (line, "@INLINE@ %191[^\n]", value)) |
200 | { | 209 | { |
201 | /* @INLINE@ value */ | 210 | /* @INLINE@ value */ |
202 | if (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, value)) | 211 | if (GNUNET_YES == allow_inline) |
203 | ret = GNUNET_SYSERR; /* failed to parse included config */ | 212 | { |
213 | if (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, value)) | ||
214 | ret = GNUNET_SYSERR; /* failed to parse included config */ | ||
215 | } | ||
216 | else | ||
217 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
218 | "Ignoring parsing INLINE configurations as allow_inline is false\n"); | ||
204 | } | 219 | } |
205 | else if (1 == SSCANF (line, "[%99[^]]]", value)) | 220 | else if (1 == SSCANF (line, "[%99[^]]]", value)) |
206 | { | 221 | { |
@@ -241,17 +256,70 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
241 | { | 256 | { |
242 | /* parse error */ | 257 | /* parse error */ |
243 | LOG (GNUNET_ERROR_TYPE_WARNING, | 258 | LOG (GNUNET_ERROR_TYPE_WARNING, |
244 | _("Syntax error in configuration file `%s' at line %u.\n"), filename, | 259 | _("Syntax error while deserializing operation at line %u\n"), nr); |
245 | nr); | ||
246 | ret = GNUNET_SYSERR; | 260 | ret = GNUNET_SYSERR; |
247 | break; | 261 | break; |
248 | } | 262 | } |
249 | } | 263 | } |
250 | GNUNET_assert (0 == FCLOSE (fp)); | 264 | GNUNET_free (section); |
265 | GNUNET_assert (r_bytes == size); | ||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | |||
270 | /** | ||
271 | * Parse a configuration file, add all of the options in the | ||
272 | * file to the configuration environment. | ||
273 | * | ||
274 | * @param cfg configuration to update | ||
275 | * @param filename name of the configuration file | ||
276 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | ||
277 | */ | ||
278 | int | ||
279 | GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, | ||
280 | const char *filename) | ||
281 | { | ||
282 | uint64_t fs64; | ||
283 | size_t fs; | ||
284 | char *fn; | ||
285 | char *mem; | ||
286 | int dirty; | ||
287 | int ret; | ||
288 | |||
289 | fn = GNUNET_STRINGS_filename_expand (filename); | ||
290 | if (fn == NULL) | ||
291 | return GNUNET_SYSERR; | ||
292 | dirty = cfg->dirty; /* back up value! */ | ||
293 | if (GNUNET_SYSERR == | ||
294 | GNUNET_DISK_file_size (fn, &fs64, GNUNET_YES, GNUNET_YES)) | ||
295 | { | ||
296 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
297 | "Error while determining the file size of %s\n", fn); | ||
298 | GNUNET_free (fn); | ||
299 | return GNUNET_SYSERR; | ||
300 | } | ||
301 | if (fs64 > SIZE_MAX) | ||
302 | { | ||
303 | GNUNET_break (0); /* File size is more than the heap size */ | ||
304 | GNUNET_free (fn); | ||
305 | return GNUNET_SYSERR; | ||
306 | } | ||
307 | fs = fs64; | ||
308 | mem = GNUNET_malloc (fs); | ||
309 | if (fs != GNUNET_DISK_fn_read (fn, mem, fs)) | ||
310 | { | ||
311 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
312 | "Error while reading file %s\n", fn); | ||
313 | GNUNET_free (fn); | ||
314 | GNUNET_free (mem); | ||
315 | return GNUNET_SYSERR; | ||
316 | } | ||
317 | GNUNET_free (fn); | ||
318 | ret = GNUNET_CONFIGURATION_deserialize (cfg, mem, fs, GNUNET_YES); | ||
319 | GNUNET_free (mem); | ||
251 | /* restore dirty flag - anything we set in the meantime | 320 | /* restore dirty flag - anything we set in the meantime |
252 | * came from disk */ | 321 | * came from disk */ |
253 | cfg->dirty = dirty; | 322 | cfg->dirty = dirty; |
254 | GNUNET_free (section); | ||
255 | return ret; | 323 | return ret; |
256 | } | 324 | } |
257 | 325 | ||