📄 config.c
字号:
nsec.name = GNUNET_strdup (section); nsec.size = 0; nsec.entries = NULL; GNUNET_array_append (data->sections, data->ssize, nsec); sec = findSection (data, section); } ne.key = GNUNET_strdup (option); ne.val = NULL; ne.dirty_val = NULL; GNUNET_array_append (sec->entries, sec->size, ne); e = findEntry (data, section, option); } if (e->dirty_val != NULL) { if (0 == strcmp (e->dirty_val, value)) { ret = 0; } else { /* recursive update to different value -- not allowed! */ GNUNET_GE_BREAK (ectx, 0); ret = -1; } } else { e->dirty_val = GNUNET_strdup (value); i = data->lsize - 1; while (i >= 0) { if (0 != data->listeners[i].listener (data->listeners[i].ctx, data, ectx, section, option)) break; /* update refused */ i--; e = findEntry (data, section, option); /* side-effects of callback are possible! */ } e = findEntry (data, section, option); /* side-effects of callback are possible! */ if (i >= 0) { /* update refused, revert! */ GNUNET_free (e->dirty_val); e->dirty_val = NULL; i++; /* the callback that refused does not need refreshing */ while (i < data->lsize) { if (0 != data->listeners[i].listener (data->listeners[i].ctx, data, ectx, section, option)) GNUNET_GE_ASSERT (ectx, 0); /* refused the refusal!? */ e = findEntry (data, section, option); /* side-effects of callback are possible! */ i++; } ret = -1; /* error -- update refused */ } else { /* all confirmed, commit! */ if ((e->val == NULL) || (0 != strcmp (e->val, e->dirty_val))) data->dirty = 1; GNUNET_free_non_null (e->val); e->val = e->dirty_val; e->dirty_val = NULL; ret = 0; } } if (ret == -1) GNUNET_GE_LOG (ectx, GNUNET_GE_USER | GNUNET_GE_BULK | GNUNET_GE_WARNING, _ ("Setting option `%s' in section `%s' to value `%s' was refused.\n"), option, section, value); GNUNET_mutex_unlock (data->lock); return ret;}intGNUNET_GC_set_configuration_value_number (struct GNUNET_GC_Configuration *cfg, struct GNUNET_GE_Context *ectx, const char *section, const char *option, unsigned long long number){ char s[64]; GNUNET_snprintf (s, 64, "%llu", number); return GNUNET_GC_set_configuration_value_string (cfg, ectx, section, option, s);}intGNUNET_GC_get_configuration_value_number (struct GNUNET_GC_Configuration *cfg, const char *section, const char *option, unsigned long long min, unsigned long long max, unsigned long long def, unsigned long long *number){ GNUNET_GC_Entry *e; const char *val; int ret; GNUNET_mutex_lock (cfg->lock); e = findEntry (cfg, section, option); if (e != NULL) { val = (e->dirty_val != NULL) ? e->dirty_val : e->val; if (1 == SSCANF (val, "%llu", number)) { if ((*number >= min) && (*number <= max)) { ret = 0; } else { GNUNET_GE_LOG (cfg->ectx, GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_BULK, _("Configuration value '%llu' for '%s' " "in section '%s' is out of legal bounds [%llu,%llu]\n"), *number, option, section, min, max); ret = -1; /* error */ } } else { GNUNET_GE_LOG (cfg->ectx, GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_BULK, _("Configuration value '%s' for '%s'" " in section '%s' should be a number\n"), val, option, section, min, max); ret = -1; /* error */ } } else { *number = def; GNUNET_GC_set_configuration_value_number (cfg, cfg->ectx, section, option, def); ret = 1; /* default */ } GNUNET_mutex_unlock (cfg->lock); return ret;}intGNUNET_GC_get_configuration_value_string (struct GNUNET_GC_Configuration *cfg, const char *section, const char *option, const char *def, char **value){ GNUNET_GC_Entry *e; const char *val; int ret; GNUNET_mutex_lock (cfg->lock); e = findEntry (cfg, section, option); if (e != NULL) { val = (e->dirty_val != NULL) ? e->dirty_val : e->val; *value = GNUNET_strdup (val); ret = 0; } else { if (def == NULL) { GNUNET_mutex_unlock (cfg->lock); GNUNET_GE_LOG (cfg->ectx, GNUNET_GE_USER | GNUNET_GE_IMMEDIATE | GNUNET_GE_ERROR, "Configuration value for option `%s' in section `%s' required.\n", option, section); return -1; } *value = GNUNET_strdup (def); GNUNET_GC_set_configuration_value_string (cfg, cfg->ectx, section, option, def); ret = 1; /* default */ } GNUNET_mutex_unlock (cfg->lock); return ret;}intGNUNET_GC_get_configuration_value_choice (struct GNUNET_GC_Configuration *cfg, const char *section, const char *option, const char **choices, const char *def, const char **value){ GNUNET_GC_Entry *e; const char *val; int i; int ret; GNUNET_mutex_lock (cfg->lock); e = findEntry (cfg, section, option); if (e != NULL) { val = (e->dirty_val != NULL) ? e->dirty_val : e->val; i = 0; while (choices[i] != NULL) { if (0 == strcasecmp (choices[i], val)) break; i++; } if (choices[i] == NULL) { GNUNET_GE_LOG (cfg->ectx, GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_BULK, _("Configuration value '%s' for '%s'" " in section '%s' is not in set of legal choices\n"), val, option, section); ret = -1; /* error */ } else { *value = choices[i]; ret = 0; } } else { *value = def; if (def == NULL) ret = -1; else ret = 1; /* default */ } GNUNET_mutex_unlock (cfg->lock); return ret;}/** * Test if we have a value for a particular option * @return GNUNET_YES if so, GNUNET_NO if not. */intGNUNET_GC_have_configuration_value (struct GNUNET_GC_Configuration *cfg, const char *section, const char *option){ GNUNET_GC_Entry *e; int ret; GNUNET_mutex_lock (cfg->lock); e = findEntry (cfg, section, option); if (e == NULL) ret = GNUNET_NO; else ret = GNUNET_YES; GNUNET_mutex_unlock (cfg->lock); return ret;}/** * Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" * where either in the "PATHS" section or the environtment * "FOO" is set to "DIRECTORY". * * @param old string to $-expand (will be freed!) * @return $-expanded string */char *GNUNET_GC_configuration_expand_dollar (struct GNUNET_GC_Configuration *cfg, char *orig){ int i; char *prefix; char *result; const char *post; if (orig[0] != '$') return orig; i = 0; while ((orig[i] != '/') && (orig[i] != '\\') && (orig[i] != '\0')) i++; if (orig[i] == '\0') { post = ""; } else { orig[i] = '\0'; post = &orig[i + 1]; } prefix = NULL; if (GNUNET_YES == GNUNET_GC_have_configuration_value (cfg, "PATHS", &orig[1])) { if (0 != GNUNET_GC_get_configuration_value_string (cfg, "PATHS", &orig[1], NULL, &prefix)) { GNUNET_GE_BREAK (NULL, 0); return orig; } } else { const char *env = getenv (&orig[1]); if (env != NULL) { prefix = GNUNET_strdup (env); } else { orig[i] = DIR_SEPARATOR; return orig; } } result = GNUNET_malloc (strlen (prefix) + strlen (post) + 2); strcpy (result, prefix); if ((strlen (prefix) == 0) || (prefix[strlen (prefix) - 1] != DIR_SEPARATOR)) strcat (result, DIR_SEPARATOR_STR); strcat (result, post); GNUNET_free (prefix); GNUNET_free (orig); return result;}/** * Get a configuration value that should be a string. * @param def default value (use indicated by return value; * will NOT be aliased, maybe NULL) * @param value will be set to a freshly allocated configuration * value, or NULL if option is not specified and no default given * @return 0 on success, -1 on error, 1 for default */intGNUNET_GC_get_configuration_value_filename (struct GNUNET_GC_Configuration *data, const char *section, const char *option, const char *def, char **value){ int ret; char *tmp; tmp = NULL; ret = GNUNET_GC_get_configuration_value_string (data, section, option, def, &tmp); if (tmp != NULL) { tmp = GNUNET_GC_configuration_expand_dollar (data, tmp); *value = GNUNET_expand_file_name (data->ectx, tmp); GNUNET_free (tmp); } else { *value = NULL; } return ret;}intGNUNET_GC_set_configuration_value_choice (struct GNUNET_GC_Configuration *cfg, struct GNUNET_GE_Context *ectx, const char *section, const char *option, const char *choice){ return GNUNET_GC_set_configuration_value_string (cfg, ectx, section, option, choice);}intGNUNET_GC_attach_change_listener (struct GNUNET_GC_Configuration *cfg, GNUNET_GC_ChangeListener callback, void *ctx){ GNUNET_GC_Listener l; int i; int j; GNUNET_mutex_lock (cfg->lock); for (i = 0; i < cfg->ssize; i++) { GNUNET_GC_Section *s = &cfg->sections[i]; for (j = 0; j < s->size; j++) { GNUNET_GC_Entry *e = &s->entries[j]; if (0 != callback (ctx, cfg, cfg->ectx, s->name, e->key)) { GNUNET_mutex_unlock (cfg->lock); return -1; } s = &cfg->sections[i]; /* side-effects of callback are possible! */ } } l.listener = callback; l.ctx = ctx; GNUNET_array_append (cfg->listeners, cfg->lsize, l); GNUNET_mutex_unlock (cfg->lock); return 0;}intGNUNET_GC_detach_change_listener (struct GNUNET_GC_Configuration *cfg, GNUNET_GC_ChangeListener callback, void *ctx){ int i; GNUNET_GC_Listener *l; GNUNET_mutex_lock (cfg->lock); for (i = cfg->lsize - 1; i >= 0; i--) { l = &cfg->listeners[i]; if ((l->listener == callback) && (l->ctx == ctx)) { cfg->listeners[i] = cfg->listeners[cfg->lsize - 1]; GNUNET_array_grow (cfg->listeners, cfg->lsize, cfg->lsize - 1); GNUNET_mutex_unlock (cfg->lock); return 0; } } GNUNET_mutex_unlock (cfg->lock); return -1;}/** * Create a GNUNET_GC_Configuration. */GNUNET_GC_Configuration *GNUNET_GC_create (){ GNUNET_GC_Configuration *ret; ret = GNUNET_malloc (sizeof (GNUNET_GC_Configuration)); memset (ret, 0, sizeof (GNUNET_GC_Configuration)); ret->lock = GNUNET_mutex_create (GNUNET_YES); return ret;}/** * Get a configuration value that should be in a set of * "GNUNET_YES" or "GNUNET_NO". * * @param def default value (use indicated by return value; * will NOT be aliased, maybe NULL) * @return GNUNET_YES, GNUNET_NO or GNUNET_SYSERR */intGNUNET_GC_get_configuration_value_yesno (struct GNUNET_GC_Configuration *cfg, const char *section, const char *option, int def){ static const char *yesno[] = { "YES", "NO", NULL }; const char *val; int ret; ret = GNUNET_GC_get_configuration_value_choice (cfg, section, option, yesno, def == GNUNET_YES ? "YES" : "NO", &val); if (ret == -1) return GNUNET_SYSERR; if (val == yesno[0]) return GNUNET_YES; return GNUNET_NO;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -