aboutsummaryrefslogtreecommitdiff
path: root/src/util/configuration.c
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2012-06-27 12:24:26 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2012-06-27 12:24:26 +0000
commitf315953dd3ec50b6cf6482834b6403680238d9da (patch)
tree4d4d5d29d345a1a62772092fc7bb5589ef3e839b /src/util/configuration.c
parentf3e6ce798c7637c4bc66a2ad0496a50f70cc1076 (diff)
downloadgnunet-f315953dd3ec50b6cf6482834b6403680238d9da.tar.gz
gnunet-f315953dd3ec50b6cf6482834b6403680238d9da.zip
configuration serialization
Diffstat (limited to 'src/util/configuration.c')
-rw-r--r--src/util/configuration.c155
1 files changed, 103 insertions, 52 deletions
diff --git a/src/util/configuration.c b/src/util/configuration.c
index 194388fa0..a9697393d 100644
--- a/src/util/configuration.c
+++ b/src/util/configuration.c
@@ -271,88 +271,139 @@ GNUNET_CONFIGURATION_is_dirty (const struct GNUNET_CONFIGURATION_Handle *cfg)
271 271
272 272
273/** 273/**
274 * Write configuration file. 274 * Serializes the given configuration.
275 * 275 *
276 * @param cfg configuration to write 276 * @param cfg configuration to serialize
277 * @param filename where to write the configuration 277 * @param size will be set to the size of the serialized memory block
278 * @return GNUNET_OK on success, GNUNET_SYSERR on error 278 * @return the memory block where the serialized configuration is
279 * present. This memory should be freed by the caller
279 */ 280 */
280int 281char *
281GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg, 282GNUNET_CONFIGURATION_serialize (struct GNUNET_CONFIGURATION_Handle *cfg,
282 const char *filename) 283 uint16_t *size)
283{ 284{
284 struct ConfigSection *sec; 285 struct ConfigSection *sec;
285 struct ConfigEntry *ent; 286 struct ConfigEntry *ent;
286 FILE *fp; 287 char *mem;
287 int error; 288 char *cbuf;
288 char *fn;
289 char *val; 289 char *val;
290 char *pos; 290 char *pos;
291 uint16_t len;
292 uint16_t m_size;
293 uint16_t c_size;
291 294
292 fn = GNUNET_STRINGS_filename_expand (filename); 295
293 if (fn == NULL) 296 /* Pass1 : calculate the buffer size required */
294 return GNUNET_SYSERR; 297 m_size = 0;
295 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn))
296 {
297 GNUNET_free (fn);
298 return GNUNET_SYSERR;
299 }
300 if (NULL == (fp = FOPEN (fn, "w")))
301 {
302 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fopen", fn);
303 GNUNET_free (fn);
304 return GNUNET_SYSERR;
305 }
306 GNUNET_free (fn);
307 error = 0;
308 sec = cfg->sections; 298 sec = cfg->sections;
309 while (sec != NULL) 299 while (NULL != sec)
310 { 300 {
311 if (0 > FPRINTF (fp, "[%s]\n", sec->name)) 301 /* For each section we need to add 3 charaters: {'[',']','\n'} */
302 m_size += strlen (sec->name) + 3;
303 ent = sec->entries;
304 while (NULL != ent)
312 { 305 {
313 error = 1; 306 if (NULL != ent->val)
314 break; 307 {
308 /* if val has any '\n' then they occupy +1 character as '\n'->'\\','n' */
309 pos = ent->val;
310 while (NULL != (pos = strstr (pos, "\n")))
311 {
312 m_size++;
313 pos++;
314 }
315 /* For each key = value pair we need to add 4 characters (2
316 spaces and 1 equal-to character and 1 new line) */
317 m_size += strlen (ent->key) + strlen (ent->val) + 4;
318 }
319 ent = ent->next;
315 } 320 }
321 /* A new line after section end */
322 m_size++;
323 sec = sec->next;
324 }
325
326 /* Pass2: Allocate memory and write the configuration to it */
327 mem = GNUNET_malloc (m_size);
328 sec = cfg->sections;
329 c_size = 0;
330 *size = c_size;
331 while (NULL != sec)
332 {
333 len = GNUNET_asprintf (&cbuf, "[%s]\n", sec->name);
334 memcpy (mem + c_size, cbuf, len);
335 c_size += len;
336 GNUNET_free (cbuf);
316 ent = sec->entries; 337 ent = sec->entries;
317 while (ent != NULL) 338 while (NULL != ent)
318 { 339 {
319 if (ent->val != NULL) 340 if (NULL != ent->val)
320 { 341 {
321 val = GNUNET_malloc (strlen (ent->val) * 2 + 1); 342 val = GNUNET_malloc (strlen (ent->val) * 2 + 1);
322 strcpy (val, ent->val); 343 strcpy (val, ent->val);
323 while (NULL != (pos = strstr (val, "\n"))) 344 while (NULL != (pos = strstr (val, "\n")))
324 { 345 {
325 memmove (&pos[2], &pos[1], strlen (&pos[1])); 346 memmove (&pos[2], &pos[1], strlen (&pos[1]));
326 pos[0] = '\\'; 347 pos[0] = '\\';
327 pos[1] = 'n'; 348 pos[1] = 'n';
328 } 349 }
329 if (0 > FPRINTF (fp, "%s = %s\n", ent->key, val)) 350 len = GNUNET_asprintf (&cbuf, "%s = %s\n", ent->key, val);
330 { 351 GNUNET_free (val);
331 error = 1; 352 memcpy (mem + c_size, cbuf, len);
332 GNUNET_free (val); 353 c_size += len;
333 break; 354 GNUNET_free (cbuf);
334 }
335 GNUNET_free (val);
336 } 355 }
337 ent = ent->next; 356 ent = ent->next;
338 } 357 }
339 if (error != 0) 358 memcpy (mem + c_size, "\n", 1);
340 break; 359 c_size ++;
341 if (0 > FPRINTF (fp, "%s\n", ""))
342 {
343 error = 1;
344 break;
345 }
346 sec = sec->next; 360 sec = sec->next;
347 } 361 }
348 if (error != 0) 362 GNUNET_assert (c_size == m_size);
349 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fprintf", filename); 363 *size = c_size;
350 GNUNET_assert (0 == FCLOSE (fp)); 364 return mem;
351 if (error != 0) 365}
366
367
368/**
369 * Write configuration file.
370 *
371 * @param cfg configuration to write
372 * @param filename where to write the configuration
373 * @return GNUNET_OK on success, GNUNET_SYSERR on error
374 */
375int
376GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg,
377 const char *filename)
378{
379 char *fn;
380 char *cfg_buf;
381 uint16_t size;
382
383 fn = GNUNET_STRINGS_filename_expand (filename);
384 if (fn == NULL)
385 return GNUNET_SYSERR;
386 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn))
387 {
388 GNUNET_free (fn);
389 return GNUNET_SYSERR;
390 }
391 cfg_buf = GNUNET_CONFIGURATION_serialize (cfg, &size);
392 if (size != GNUNET_DISK_fn_write (fn, cfg_buf, size,
393 GNUNET_DISK_PERM_USER_READ
394 | GNUNET_DISK_PERM_USER_WRITE
395 | GNUNET_DISK_PERM_GROUP_READ
396 | GNUNET_DISK_PERM_GROUP_WRITE))
352 { 397 {
398 GNUNET_free (fn);
399 GNUNET_free (cfg_buf);
400 LOG (GNUNET_ERROR_TYPE_WARNING,
401 "Writing configration to file: %s failed\n", filename);
353 cfg->dirty = GNUNET_SYSERR; /* last write failed */ 402 cfg->dirty = GNUNET_SYSERR; /* last write failed */
354 return GNUNET_SYSERR; 403 return GNUNET_SYSERR;
355 } 404 }
405 GNUNET_free (fn);
406 GNUNET_free (cfg_buf);
356 cfg->dirty = GNUNET_NO; /* last write succeeded */ 407 cfg->dirty = GNUNET_NO; /* last write succeeded */
357 return GNUNET_OK; 408 return GNUNET_OK;
358} 409}