X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fconfiguration.c;h=cb6932b1536afc800af7cffc8aacee3a724b3e14;hb=c4e9ba925ffd758aaa3feee2ccfc0b76f26fe207;hp=8444c2d7d0ce6bba4f2c2bc43334119ddaae122d;hpb=62b5f9d7d649be845774ed4d876deb586f538c74;p=oweals%2Fgnunet.git diff --git a/src/util/configuration.c b/src/util/configuration.c index 8444c2d7d..cb6932b15 100644 --- a/src/util/configuration.c +++ b/src/util/configuration.c @@ -1,22 +1,22 @@ /* This file is part of GNUnet. - (C) 2006, 2007, 2008, 2009, 2013 Christian Grothoff (and other contributing authors) + Copyright (C) 2006, 2007, 2008, 2009, 2013 GNUnet e.V. - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + Affero General Public License for more details. - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ /** * @file src/util/configuration.c @@ -25,18 +25,21 @@ */ #include "platform.h" -#include "gnunet_util_lib.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_strings_lib.h" +#include "gnunet_configuration_lib.h" +#include "gnunet_disk_lib.h" -#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) +#define LOG(kind, ...) GNUNET_log_from (kind, "util", __VA_ARGS__) -#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) +#define LOG_STRERROR_FILE(kind, syscall, filename) \ + GNUNET_log_from_strerror_file (kind, "util", syscall, filename) /** * @brief configuration entry */ struct ConfigEntry { - /** * This is a linked list. */ @@ -92,7 +95,6 @@ struct GNUNET_CONFIGURATION_Handle * #GNUNET_SYSERR on error (i.e. last save failed) */ int dirty; - }; @@ -136,22 +138,54 @@ GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg) } +/** + * Parse a configuration file @a filename and run the function + * @a cb with the resulting configuration object. Then free the + * configuration object and return the status value from @a cb. + * + * @param filename configuration to parse, NULL for "default" + * @param cb function to run + * @param cb_cls closure for @a cb + * @return #GNUNET_SYSERR if parsing the configuration failed, + * otherwise return value from @a cb. + */ +int +GNUNET_CONFIGURATION_parse_and_run (const char *filename, + GNUNET_CONFIGURATION_Callback cb, + void *cb_cls) +{ + struct GNUNET_CONFIGURATION_Handle *cfg; + int ret; + + cfg = GNUNET_CONFIGURATION_create (); + if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, filename)) + { + GNUNET_break (0); + GNUNET_CONFIGURATION_destroy (cfg); + return GNUNET_SYSERR; + } + ret = cb (cb_cls, cfg); + GNUNET_CONFIGURATION_destroy (cfg); + return ret; +} + + /** * De-serializes configuration * * @param cfg configuration to update * @param mem the memory block of serialized configuration * @param size the size of the memory block - * @param allow_inline set to #GNUNET_YES if we recursively load configuration - * from inlined configurations; #GNUNET_NO if not and raise warnings + * @param basedir set to path from which we recursively load configuration + * from inlined configurations; NULL if not and raise warnings * when we come across them * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ int GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, - const char *mem, - const size_t size, - int allow_inline) + const char *mem, + size_t size, + const char *basedir) { char *line; char *line_orig; @@ -168,7 +202,6 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, char *tag; char *value; - LOG (GNUNET_ERROR_TYPE_DEBUG, "Deserializing config file\n"); ret = GNUNET_OK; section = GNUNET_strdup (""); nr = 0; @@ -187,7 +220,8 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, } else { - line_orig = GNUNET_strndup (&mem[r_bytes], line_size = (pos - &mem[r_bytes])); + line_orig = + GNUNET_strndup (&mem[r_bytes], line_size = (pos - &mem[r_bytes])); r_bytes += line_size + 1; } line = line_orig; @@ -209,50 +243,52 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, continue; /* remove tailing whitespace */ - for (i = line_size - 1; (i >= 1) && (isspace ((unsigned char) line[i]));i--) + for (i = line_size - 1; (i >= 1) && (isspace ((unsigned char) line[i])); + i--) line[i] = '\0'; /* remove leading whitespace */ - for (; line[0] != '\0' && (isspace ((unsigned char) line[0])); line++); + for (; line[0] != '\0' && (isspace ((unsigned char) line[0])); line++) + ; /* ignore comments */ - if ( ('#' == line[0]) || ('%' == line[0]) ) + if (('#' == line[0]) || ('%' == line[0])) continue; /* handle special "@INLINE@" directive */ - if (0 == strncasecmp (line, - "@INLINE@ ", - strlen ("@INLINE@ "))) + if (0 == strncasecmp (line, "@INLINE@ ", strlen ("@INLINE@ "))) { /* @INLINE@ value */ value = &line[strlen ("@INLINE@ ")]; - if (GNUNET_YES == allow_inline) + if (NULL != basedir) { - if (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, value)) - { - ret = GNUNET_SYSERR; /* failed to parse included config */ - break; - } + char *fn; + + GNUNET_asprintf (&fn, "%s/%s", basedir, value); + if (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, fn)) + { + GNUNET_free (fn); + ret = GNUNET_SYSERR; /* failed to parse included config */ + break; + } + GNUNET_free (fn); } else { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Ignoring parsing @INLINE@ configurations, not allowed!\n"); - ret = GNUNET_SYSERR; - break; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Ignoring parsing @INLINE@ configurations, not allowed!\n"); + ret = GNUNET_SYSERR; + break; } continue; } - if ( ('[' == line[0]) && (']' == line[line_size - 1]) ) + if (('[' == line[0]) && (']' == line[line_size - 1])) { /* [value] */ line[line_size - 1] = '\0'; value = &line[1]; GNUNET_free (section); section = GNUNET_strdup (value); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Config section `%s'\n", - section); continue; } if (NULL != (eq = strchr (line, '='))) @@ -260,40 +296,40 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, /* tag = value */ tag = GNUNET_strndup (line, eq - line); /* remove tailing whitespace */ - for (i = strlen (tag) - 1; (i >= 1) && (isspace ((unsigned char) tag[i]));i--) - tag[i] = '\0'; + for (i = strlen (tag) - 1; (i >= 1) && (isspace ((unsigned char) tag[i])); + i--) + tag[i] = '\0'; /* Strip whitespace */ value = eq + 1; while (isspace ((unsigned char) value[0])) - value++; - for (i = strlen (value) - 1; (i >= 1) && (isspace ((unsigned char) value[i]));i--) - value[i] = '\0'; + value++; + for (i = strlen (value) - 1; + (i >= 1) && (isspace ((unsigned char) value[i])); + i--) + value[i] = '\0'; /* remove quotes */ i = 0; - if ( ('"' == value[0]) && - ('"' == value[strlen (value) - 1]) ) + if (('"' == value[0]) && ('"' == value[strlen (value) - 1])) { - value[strlen (value) - 1] = '\0'; - value++; + value[strlen (value) - 1] = '\0'; + value++; } - LOG (GNUNET_ERROR_TYPE_DEBUG, "Config value %s=\"%s\"\n", tag, value); GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, &value[i]); GNUNET_free (tag); continue; } /* parse error */ LOG (GNUNET_ERROR_TYPE_WARNING, - _("Syntax error while deserializing in line %u\n"), - nr); + _ ("Syntax error while deserializing in line %u\n"), + nr); ret = GNUNET_SYSERR; break; } - LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished deserializing config\n"); GNUNET_free_non_null (line_orig); GNUNET_free (section); - GNUNET_assert ( (GNUNET_OK != ret) || (r_bytes == size) ); + GNUNET_assert ((GNUNET_OK != ret) || (r_bytes == size)); return ret; } @@ -314,46 +350,47 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, size_t fs; char *fn; char *mem; + char *endsep; int dirty; int ret; + ssize_t sret; - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Asked to parse config file `%s'\n", - filename); fn = GNUNET_STRINGS_filename_expand (filename); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Config file name expanded to `%s'\n", - fn); - if (fn == NULL) + LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to parse config file `%s'\n", fn); + if (NULL == fn) return GNUNET_SYSERR; - dirty = cfg->dirty; /* back up value! */ + dirty = cfg->dirty; /* back up value! */ if (GNUNET_SYSERR == GNUNET_DISK_file_size (fn, &fs64, GNUNET_YES, GNUNET_YES)) { LOG (GNUNET_ERROR_TYPE_WARNING, - "Error while determining the file size of %s\n", fn); + "Error while determining the file size of `%s'\n", + fn); GNUNET_free (fn); return GNUNET_SYSERR; } if (fs64 > SIZE_MAX) { - GNUNET_break (0); /* File size is more than the heap size */ + GNUNET_break (0); /* File size is more than the heap size */ GNUNET_free (fn); return GNUNET_SYSERR; } fs = fs64; mem = GNUNET_malloc (fs); - if (fs != GNUNET_DISK_fn_read (fn, mem, fs)) + sret = GNUNET_DISK_fn_read (fn, mem, fs); + if ((sret < 0) || (fs != (size_t) sret)) { - LOG (GNUNET_ERROR_TYPE_WARNING, - "Error while reading file %s\n", fn); + LOG (GNUNET_ERROR_TYPE_WARNING, _ ("Error while reading file `%s'\n"), fn); GNUNET_free (fn); GNUNET_free (mem); return GNUNET_SYSERR; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Deserializing contents of file `%s'\n", fn); + endsep = strrchr (fn, (int) '/'); + if (NULL != endsep) + *endsep = '\0'; + ret = GNUNET_CONFIGURATION_deserialize (cfg, mem, fs, fn); GNUNET_free (fn); - ret = GNUNET_CONFIGURATION_deserialize (cfg, mem, fs, GNUNET_YES); GNUNET_free (mem); /* restore dirty flag - anything we set in the meantime * came from disk */ @@ -386,7 +423,7 @@ GNUNET_CONFIGURATION_is_dirty (const struct GNUNET_CONFIGURATION_Handle *cfg) */ char * GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg, - size_t *size) + size_t *size) { struct ConfigSection *sec; struct ConfigEntry *ent; @@ -394,11 +431,9 @@ GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg, char *cbuf; char *val; char *pos; - int len; size_t m_size; size_t c_size; - /* Pass1 : calculate the buffer size required */ m_size = 0; for (sec = cfg->sections; NULL != sec; sec = sec->next) @@ -409,16 +444,16 @@ GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg, { if (NULL != ent->val) { - /* if val has any '\n' then they occupy +1 character as '\n'->'\\','n' */ - pos = ent->val; - while (NULL != (pos = strstr (pos, "\n"))) - { - m_size++; - pos++; - } - /* For each key = value pair we need to add 4 characters (2 - spaces and 1 equal-to character and 1 new line) */ - m_size += strlen (ent->key) + strlen (ent->val) + 4; + /* if val has any '\n' then they occupy +1 character as '\n'->'\\','n' */ + pos = ent->val; + while (NULL != (pos = strstr (pos, "\n"))) + { + m_size++; + pos++; + } + /* For each key = value pair we need to add 4 characters (2 + spaces and 1 equal-to character and 1 new line) */ + m_size += strlen (ent->key) + strlen (ent->val) + 4; } } /* A new line after section end */ @@ -432,32 +467,34 @@ GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg, *size = c_size; while (NULL != sec) { + int len; + len = GNUNET_asprintf (&cbuf, "[%s]\n", sec->name); GNUNET_assert (0 < len); - memcpy (mem + c_size, cbuf, len); + GNUNET_memcpy (mem + c_size, cbuf, len); c_size += len; GNUNET_free (cbuf); for (ent = sec->entries; NULL != ent; ent = ent->next) { if (NULL != ent->val) { - val = GNUNET_malloc (strlen (ent->val) * 2 + 1); - strcpy (val, ent->val); + val = GNUNET_malloc (strlen (ent->val) * 2 + 1); + strcpy (val, ent->val); while (NULL != (pos = strstr (val, "\n"))) { memmove (&pos[2], &pos[1], strlen (&pos[1])); pos[0] = '\\'; pos[1] = 'n'; } - len = GNUNET_asprintf (&cbuf, "%s = %s\n", ent->key, val); - GNUNET_free (val); - memcpy (mem + c_size, cbuf, len); - c_size += len; - GNUNET_free (cbuf); + len = GNUNET_asprintf (&cbuf, "%s = %s\n", ent->key, val); + GNUNET_free (val); + GNUNET_memcpy (mem + c_size, cbuf, len); + c_size += len; + GNUNET_free (cbuf); } } - memcpy (mem + c_size, "\n", 1); - c_size ++; + GNUNET_memcpy (mem + c_size, "\n", 1); + c_size++; sec = sec->next; } GNUNET_assert (c_size == m_size); @@ -480,6 +517,7 @@ GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg, char *fn; char *cfg_buf; size_t size; + ssize_t sret; fn = GNUNET_STRINGS_filename_expand (filename); if (fn == NULL) @@ -490,22 +528,26 @@ GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg, return GNUNET_SYSERR; } cfg_buf = GNUNET_CONFIGURATION_serialize (cfg, &size); - if (size != GNUNET_DISK_fn_write (fn, cfg_buf, size, - GNUNET_DISK_PERM_USER_READ - | GNUNET_DISK_PERM_USER_WRITE - | GNUNET_DISK_PERM_GROUP_READ - | GNUNET_DISK_PERM_GROUP_WRITE)) + sret = GNUNET_DISK_fn_write (fn, + cfg_buf, + size, + GNUNET_DISK_PERM_USER_READ + | GNUNET_DISK_PERM_USER_WRITE + | GNUNET_DISK_PERM_GROUP_READ + | GNUNET_DISK_PERM_GROUP_WRITE); + if ((sret < 0) || (size != (size_t) sret)) { GNUNET_free (fn); GNUNET_free (cfg_buf); LOG (GNUNET_ERROR_TYPE_WARNING, - "Writing configration to file: %s failed\n", filename); - cfg->dirty = GNUNET_SYSERR; /* last write failed */ + "Writing configuration to file `%s' failed\n", + filename); + cfg->dirty = GNUNET_SYSERR; /* last write failed */ return GNUNET_SYSERR; } GNUNET_free (fn); GNUNET_free (cfg_buf); - cfg->dirty = GNUNET_NO; /* last write succeeded */ + cfg->dirty = GNUNET_NO; /* last write succeeded */ return GNUNET_OK; } @@ -528,7 +570,7 @@ GNUNET_CONFIGURATION_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg, for (spos = cfg->sections; NULL != spos; spos = spos->next) for (epos = spos->entries; NULL != epos; epos = epos->next) if (NULL != epos->val) - iter (iter_cls, spos->name, epos->key, epos->val); + iter (iter_cls, spos->name, epos->key, epos->val); } @@ -541,11 +583,11 @@ GNUNET_CONFIGURATION_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg, * @param iter_cls closure for @a iter */ void -GNUNET_CONFIGURATION_iterate_section_values (const struct - GNUNET_CONFIGURATION_Handle *cfg, - const char *section, - GNUNET_CONFIGURATION_Iterator iter, - void *iter_cls) +GNUNET_CONFIGURATION_iterate_section_values ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + GNUNET_CONFIGURATION_Iterator iter, + void *iter_cls) { struct ConfigSection *spos; struct ConfigEntry *epos; @@ -569,10 +611,10 @@ GNUNET_CONFIGURATION_iterate_section_values (const struct * @param iter_cls closure for @a iter */ void -GNUNET_CONFIGURATION_iterate_sections (const struct GNUNET_CONFIGURATION_Handle - *cfg, - GNUNET_CONFIGURATION_Section_Iterator - iter, void *iter_cls) +GNUNET_CONFIGURATION_iterate_sections ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_CONFIGURATION_Section_Iterator iter, + void *iter_cls) { struct ConfigSection *spos; struct ConfigSection *next; @@ -676,7 +718,7 @@ GNUNET_CONFIGURATION_dup (const struct GNUNET_CONFIGURATION_Handle *cfg) */ static struct ConfigSection * find_section (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *section) + const char *section) { struct ConfigSection *pos; @@ -697,8 +739,8 @@ find_section (const struct GNUNET_CONFIGURATION_Handle *cfg, */ static struct ConfigEntry * find_entry (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *section, - const char *key) + const char *section, + const char *key) { struct ConfigSection *sec; struct ConfigEntry *pos; @@ -726,15 +768,14 @@ static void compare_entries (void *cls, const char *section, const char *option, - const char *value) + const char *value) { struct DiffHandle *dh = cls; struct ConfigEntry *entNew; entNew = find_entry (dh->cfg_default, section, option); - if ( (NULL != entNew) && - (NULL != entNew->val) && - (0 == strcmp (entNew->val, value)) ) + if ((NULL != entNew) && (NULL != entNew->val) && + (0 == strcmp (entNew->val, value))) return; GNUNET_CONFIGURATION_set_value_string (dh->cfgDiff, section, option, value); } @@ -748,8 +789,9 @@ compare_entries (void *cls, * @return configuration with only the differences, never NULL */ struct GNUNET_CONFIGURATION_Handle * -GNUNET_CONFIGURATION_get_diff (const struct GNUNET_CONFIGURATION_Handle *cfg_default, - const struct GNUNET_CONFIGURATION_Handle *cfg_new) +GNUNET_CONFIGURATION_get_diff ( + const struct GNUNET_CONFIGURATION_Handle *cfg_default, + const struct GNUNET_CONFIGURATION_Handle *cfg_new) { struct DiffHandle diffHandle; @@ -769,10 +811,10 @@ GNUNET_CONFIGURATION_get_diff (const struct GNUNET_CONFIGURATION_Handle *cfg_def * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ int -GNUNET_CONFIGURATION_write_diffs (const struct GNUNET_CONFIGURATION_Handle - *cfg_default, - const struct GNUNET_CONFIGURATION_Handle - *cfg_new, const char *filename) +GNUNET_CONFIGURATION_write_diffs ( + const struct GNUNET_CONFIGURATION_Handle *cfg_default, + const struct GNUNET_CONFIGURATION_Handle *cfg_new, + const char *filename) { int ret; struct GNUNET_CONFIGURATION_Handle *diff; @@ -794,7 +836,8 @@ GNUNET_CONFIGURATION_write_diffs (const struct GNUNET_CONFIGURATION_Handle */ void GNUNET_CONFIGURATION_set_value_string (struct GNUNET_CONFIGURATION_Handle *cfg, - const char *section, const char *option, + const char *section, + const char *option, const char *value) { struct ConfigSection *sec; @@ -843,7 +886,8 @@ GNUNET_CONFIGURATION_set_value_string (struct GNUNET_CONFIGURATION_Handle *cfg, */ void GNUNET_CONFIGURATION_set_value_number (struct GNUNET_CONFIGURATION_Handle *cfg, - const char *section, const char *option, + const char *section, + const char *option, unsigned long long number) { char s[64]; @@ -863,22 +907,25 @@ GNUNET_CONFIGURATION_set_value_number (struct GNUNET_CONFIGURATION_Handle *cfg, * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ int -GNUNET_CONFIGURATION_get_value_number (const struct GNUNET_CONFIGURATION_Handle - *cfg, const char *section, - const char *option, - unsigned long long *number) +GNUNET_CONFIGURATION_get_value_number ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + unsigned long long *number) { struct ConfigEntry *e; + char dummy[2]; if (NULL == (e = find_entry (cfg, section, option))) return GNUNET_SYSERR; if (NULL == e->val) return GNUNET_SYSERR; - if (1 != SSCANF (e->val, "%llu", number)) + if (1 != sscanf (e->val, "%llu%1s", number, dummy)) return GNUNET_SYSERR; return GNUNET_OK; } + /** * Get a configuration value that should be a floating point number. * @@ -889,24 +936,25 @@ GNUNET_CONFIGURATION_get_value_number (const struct GNUNET_CONFIGURATION_Handle * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ int -GNUNET_CONFIGURATION_get_value_float (const struct GNUNET_CONFIGURATION_Handle - *cfg, const char *section, - const char *option, - float *number) +GNUNET_CONFIGURATION_get_value_float ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + float *number) { struct ConfigEntry *e; + char dummy[2]; if (NULL == (e = find_entry (cfg, section, option))) return GNUNET_SYSERR; if (NULL == e->val) return GNUNET_SYSERR; - if (1 != SSCANF (e->val, "%f", number)) + if (1 != sscanf (e->val, "%f%1s", number, dummy)) return GNUNET_SYSERR; return GNUNET_OK; } - /** * Get a configuration value that should be a relative time. * @@ -917,18 +965,26 @@ GNUNET_CONFIGURATION_get_value_float (const struct GNUNET_CONFIGURATION_Handle * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ int -GNUNET_CONFIGURATION_get_value_time (const struct GNUNET_CONFIGURATION_Handle - *cfg, const char *section, - const char *option, - struct GNUNET_TIME_Relative *time) +GNUNET_CONFIGURATION_get_value_time ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + struct GNUNET_TIME_Relative *time) { struct ConfigEntry *e; + int ret; if (NULL == (e = find_entry (cfg, section, option))) return GNUNET_SYSERR; if (NULL == e->val) return GNUNET_SYSERR; - return GNUNET_STRINGS_fancy_time_to_relative (e->val, time); + ret = GNUNET_STRINGS_fancy_time_to_relative (e->val, time); + if (GNUNET_OK != ret) + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + section, + option, + _ ("Not a valid relative time specification")); + return ret; } @@ -942,10 +998,11 @@ GNUNET_CONFIGURATION_get_value_time (const struct GNUNET_CONFIGURATION_Handle * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ int -GNUNET_CONFIGURATION_get_value_size (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *section, - const char *option, - unsigned long long *size) +GNUNET_CONFIGURATION_get_value_size ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + unsigned long long *size) { struct ConfigEntry *e; @@ -968,19 +1025,15 @@ GNUNET_CONFIGURATION_get_value_size (const struct GNUNET_CONFIGURATION_Handle *c * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ int -GNUNET_CONFIGURATION_get_value_string (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *section, - const char *option, - char **value) +GNUNET_CONFIGURATION_get_value_string ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + char **value) { struct ConfigEntry *e; - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Asked to retrieve string `%s' in section `%s'\n", - option, - section); - if ( (NULL == (e = find_entry (cfg, section, option))) || - (NULL == e->val) ) + if ((NULL == (e = find_entry (cfg, section, option))) || (NULL == e->val)) { *value = NULL; return GNUNET_SYSERR; @@ -1003,11 +1056,12 @@ GNUNET_CONFIGURATION_get_value_string (const struct GNUNET_CONFIGURATION_Handle * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ int -GNUNET_CONFIGURATION_get_value_choice (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *section, - const char *option, - const char *const *choices, - const char **value) +GNUNET_CONFIGURATION_get_value_choice ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + const char *const *choices, + const char **value) { struct ConfigEntry *e; unsigned int i; @@ -1020,8 +1074,8 @@ GNUNET_CONFIGURATION_get_value_choice (const struct GNUNET_CONFIGURATION_Handle if (NULL == choices[i]) { LOG (GNUNET_ERROR_TYPE_ERROR, - _("Configuration value '%s' for '%s'" - " in section '%s' is not in set of legal choices\n"), + _ ("Configuration value '%s' for '%s'" + " in section '%s' is not in set of legal choices\n"), e->val, option, section); @@ -1032,6 +1086,50 @@ GNUNET_CONFIGURATION_get_value_choice (const struct GNUNET_CONFIGURATION_Handle } +/** + * Get crockford32-encoded fixed-size binary data from a configuration. + * + * @param cfg configuration to access + * @param section section to access + * @param option option to access + * @param buf where to store the decoded binary result + * @param buf_size exact number of bytes to store in @a buf + * @return #GNUNET_OK on success + * #GNUNET_NO is the value does not exist + * #GNUNET_SYSERR on decoding error + */ +int +GNUNET_CONFIGURATION_get_data (const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + void *buf, + size_t buf_size) +{ + char *enc; + int res; + size_t data_size; + + if (GNUNET_OK != + (res = + GNUNET_CONFIGURATION_get_value_string (cfg, section, option, &enc))) + return res; + data_size = (strlen (enc) * 5) / 8; + if (data_size != buf_size) + { + GNUNET_free (enc); + return GNUNET_SYSERR; + } + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (enc, strlen (enc), buf, buf_size)) + { + GNUNET_free (enc); + return GNUNET_SYSERR; + } + GNUNET_free (enc); + return GNUNET_OK; +} + + /** * Test if we have a value for a particular option * @@ -1042,7 +1140,8 @@ GNUNET_CONFIGURATION_get_value_choice (const struct GNUNET_CONFIGURATION_Handle */ int GNUNET_CONFIGURATION_have_value (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *section, const char *option) + const char *section, + const char *option) { struct ConfigEntry *e; @@ -1072,7 +1171,6 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg, char *orig, unsigned int depth) { - int i; char *prefix; char *result; char *start; @@ -1090,16 +1188,15 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg, if (depth > 128) { LOG (GNUNET_ERROR_TYPE_WARNING, - _("Recursive expansion suspected, aborting $-expansion for term `%s'\n"), + _ ( + "Recursive expansion suspected, aborting $-expansion for term `%s'\n"), orig); return orig; } - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Asked to $-expand %s\n", orig); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to $-expand %s\n", orig); if ('$' != orig[0]) { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Doesn't start with $ - not expanding\n"); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Doesn't start with $ - not expanding\n"); return orig; } erased_char = 0; @@ -1117,15 +1214,18 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg, case '}': lopen--; break; + case '{': lopen++; break; + case '\0': LOG (GNUNET_ERROR_TYPE_WARNING, - _("Missing closing `%s' in option `%s'\n"), + _ ("Missing closing `%s' in option `%s'\n"), "}", orig); return orig; + default: break; } @@ -1139,21 +1239,20 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg, { *def = '\0'; def++; - if ( ('-' == *def) || - ('=' == *def) ) + if (('-' == *def) || ('=' == *def)) def++; def = GNUNET_strdup (def); } } else { + int i; + start = &orig[1]; def = NULL; i = 0; - while ( (orig[i] != '/') && - (orig[i] != '\\') && - (orig[i] != '\0') && - (orig[i] != ' ') ) + while ((orig[i] != '/') && (orig[i] != '\\') && (orig[i] != '\0') && + (orig[i] != ' ')) i++; if (orig[i] == '\0') { @@ -1173,19 +1272,10 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg, post, def); if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, - "PATHS", - start, - &prefix)) + GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", start, &prefix)) { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Filename for `%s' is not in PATHS config section\n", - start); if (NULL == (env = getenv (start))) { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "`%s' is not an environment variable\n", - start); /* try default */ def = expand_dollar (cfg, def, depth + 1); env = def; @@ -1196,18 +1286,17 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg, if (erased_pos) *erased_pos = erased_char; LOG (GNUNET_ERROR_TYPE_WARNING, - _("Failed to expand `%s' in `%s' as it is neither found in [PATHS] nor defined as an environmental variable\n"), - start, orig); + _ ( + "Failed to expand `%s' in `%s' as it is neither found in [PATHS] nor defined as an environmental variable\n"), + start, + orig); GNUNET_free (start); return orig; } prefix = GNUNET_strdup (env); } prefix = GNUNET_CONFIGURATION_expand_dollar (cfg, prefix); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Prefix is `%s'\n", - prefix); - if ( (erased_pos) && ('}' != erased_char) ) + if ((erased_pos) && ('}' != erased_char)) { len = strlen (prefix) + 1; prefix = GNUNET_realloc (prefix, len + 1); @@ -1220,9 +1309,6 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_free_non_null (def); GNUNET_free (prefix); GNUNET_free (orig); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Expanded to `%s'\n", - result); return result; } @@ -1244,8 +1330,9 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg, * @return $-expanded string */ char * -GNUNET_CONFIGURATION_expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg, - char *orig) +GNUNET_CONFIGURATION_expand_dollar ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + char *orig) { char *dup; size_t i; @@ -1259,7 +1346,7 @@ GNUNET_CONFIGURATION_expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cf dup = expand_dollar (cfg, dup, 0); len = strlen (dup) + 1; orig = GNUNET_realloc (orig, i + len); - memcpy (orig + i, dup, len); + GNUNET_memcpy (orig + i, dup, len); GNUNET_free (dup); } return orig; @@ -1277,31 +1364,24 @@ GNUNET_CONFIGURATION_expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cf * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ int -GNUNET_CONFIGURATION_get_value_filename (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *section, - const char *option, - char **value) +GNUNET_CONFIGURATION_get_value_filename ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + char **value) { char *tmp; - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Asked to retrieve filename `%s' in section `%s'\n", - option, - section); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, section, option, &tmp)) { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Failed to retrieve filename\n"); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to retrieve filename\n"); *value = NULL; return GNUNET_SYSERR; } - LOG (GNUNET_ERROR_TYPE_DEBUG, "Retrieved filename `%s', $-expanding\n", tmp); tmp = GNUNET_CONFIGURATION_expand_dollar (cfg, tmp); - LOG (GNUNET_ERROR_TYPE_DEBUG, "Expanded to filename `%s', *nix-expanding\n", tmp); *value = GNUNET_STRINGS_filename_expand (tmp); GNUNET_free (tmp); - LOG (GNUNET_ERROR_TYPE_DEBUG, "Filename result is `%s'\n", *value); if (*value == NULL) return GNUNET_SYSERR; return GNUNET_OK; @@ -1318,16 +1398,17 @@ GNUNET_CONFIGURATION_get_value_filename (const struct GNUNET_CONFIGURATION_Handl * @return #GNUNET_YES, #GNUNET_NO or #GNUNET_SYSERR */ int -GNUNET_CONFIGURATION_get_value_yesno (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *section, - const char *option) +GNUNET_CONFIGURATION_get_value_yesno ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option) { static const char *yesno[] = { "YES", "NO", NULL }; const char *val; int ret; ret = - GNUNET_CONFIGURATION_get_value_choice (cfg, section, option, yesno, &val); + GNUNET_CONFIGURATION_get_value_choice (cfg, section, option, yesno, &val); if (ret == GNUNET_SYSERR) return ret; if (val == yesno[0]) @@ -1347,11 +1428,12 @@ GNUNET_CONFIGURATION_get_value_yesno (const struct GNUNET_CONFIGURATION_Handle * * @return number of filenames iterated over, -1 on error */ int -GNUNET_CONFIGURATION_iterate_value_filenames (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *section, - const char *option, - GNUNET_FileNameCallback cb, - void *cb_cls) +GNUNET_CONFIGURATION_iterate_value_filenames ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + GNUNET_FileNameCallback cb, + void *cb_cls) { char *list; char *pos; @@ -1381,9 +1463,11 @@ GNUNET_CONFIGURATION_iterate_value_filenames (const struct GNUNET_CONFIGURATION_ case '\\': case ' ': memmove (end, &end[1], strlen (&end[1]) + 1); + case '\0': /* illegal, but just keep it */ break; + default: /* illegal, but just ignore that there was a '/' */ break; @@ -1438,6 +1522,7 @@ escape_name (const char *value) wpos[1] = rpos[0]; wpos += 2; break; + default: wpos[0] = rpos[0]; wpos++; @@ -1477,20 +1562,23 @@ test_match (void *cls, const char *fn) * #GNUNET_SYSERR on error */ int -GNUNET_CONFIGURATION_append_value_filename (struct GNUNET_CONFIGURATION_Handle *cfg, - const char *section, - const char *option, - const char *value) +GNUNET_CONFIGURATION_append_value_filename ( + struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + const char *value) { char *escaped; char *old; char *nw; if (GNUNET_SYSERR == - GNUNET_CONFIGURATION_iterate_value_filenames (cfg, section, option, + GNUNET_CONFIGURATION_iterate_value_filenames (cfg, + section, + option, &test_match, (void *) value)) - return GNUNET_NO; /* already exists */ + return GNUNET_NO; /* already exists */ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, section, option, &old)) old = GNUNET_strdup (""); @@ -1521,10 +1609,11 @@ GNUNET_CONFIGURATION_append_value_filename (struct GNUNET_CONFIGURATION_Handle * * #GNUNET_SYSERR on error */ int -GNUNET_CONFIGURATION_remove_value_filename (struct GNUNET_CONFIGURATION_Handle - *cfg, const char *section, - const char *option, - const char *value) +GNUNET_CONFIGURATION_remove_value_filename ( + struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + const char *value) { char *list; char *pos; @@ -1554,9 +1643,11 @@ GNUNET_CONFIGURATION_remove_value_filename (struct GNUNET_CONFIGURATION_Handle case ' ': end++; break; + case '\0': /* illegal, but just keep it */ break; + default: /* illegal, but just ignore that there was a '/' */ break; @@ -1606,16 +1697,14 @@ static int parse_configuration_file (void *cls, const char *filename) { struct GNUNET_CONFIGURATION_Handle *cfg = cls; - char * ext; + char *ext; int ret; /* Examine file extension */ ext = strrchr (filename, '.'); if ((NULL == ext) || (0 != strcmp (ext, ".conf"))) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Skipping file `%s'\n", - filename); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Skipping file `%s'\n", filename); return GNUNET_OK; } @@ -1634,54 +1723,11 @@ parse_configuration_file (void *cls, const char *filename) */ int GNUNET_CONFIGURATION_load_from (struct GNUNET_CONFIGURATION_Handle *cfg, - const char *defaults_d) + const char *defaults_d) { if (GNUNET_SYSERR == GNUNET_DISK_directory_scan (defaults_d, &parse_configuration_file, cfg)) - return GNUNET_SYSERR; /* no configuration at all found */ - return GNUNET_OK; -} - - -/** - * Load configuration (starts with defaults, then loads - * system-specific configuration). - * - * @param cfg configuration to update - * @param filename name of the configuration file, NULL to load defaults - * @return #GNUNET_OK on success, #GNUNET_SYSERR on error - */ -int -GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg, - const char *filename) -{ - char *baseconfig; - char *ipath; - - ipath = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); - if (NULL == ipath) - return GNUNET_SYSERR; - baseconfig = NULL; - GNUNET_asprintf (&baseconfig, "%s%s", ipath, "config.d"); - GNUNET_free (ipath); - if (GNUNET_SYSERR == - GNUNET_DISK_directory_scan (baseconfig, &parse_configuration_file, cfg)) - { - GNUNET_free (baseconfig); - return GNUNET_SYSERR; /* no configuration at all found */ - } - GNUNET_free (baseconfig); - if ((NULL != filename) && - (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, filename))) - { - /* specified configuration not found */ - return GNUNET_SYSERR; - } - if (((GNUNET_YES != - GNUNET_CONFIGURATION_have_value (cfg, "PATHS", "DEFAULTCONFIG"))) && - (filename != NULL)) - GNUNET_CONFIGURATION_set_value_string (cfg, "PATHS", "DEFAULTCONFIG", - filename); + return GNUNET_SYSERR; /* no configuration at all found */ return GNUNET_OK; }