XML * config_get_option (void * session, const char * valuename) { WFTK_SESSION * sess = session; if (sess) { if (sess->config) { return (config_find_option (sess->config, valuename)); } } return NULL; }
XML * config_find_option (XML * xml, const char * name) { int len; XML * x; char * mark = strchr (name, '.'); if (mark) len = mark - name; else len = strlen (name); x = xml_firstelem (xml); while (x) { if (!strncmp (xml_attrval (x, "name"), name, len) || !strncmp (xml_attrval (x, "id"), name, len) || !strncmp ("?", name, len)) { if (mark) { return (config_find_option (x, mark + 1)); } return (x); } x = xml_nextelem (x); } return NULL; }
/** <b>c</b>-\>key is known to be a real key. Update <b>options</b> * with <b>c</b>-\>value and return 0, or return -1 if bad value. * * Called from config_assign_line() and option_reset(). */ static int config_assign_value(const config_format_t *fmt, void *options, config_line_t *c, char **msg) { int i, ok; const config_var_t *var; void *lvalue; int *csv_int; smartlist_t *csv_str; CONFIG_CHECK(fmt, options); var = config_find_option(fmt, c->key); tor_assert(var); lvalue = STRUCT_VAR_P(options, var->var_offset); switch (var->type) { case CONFIG_TYPE_PORT: if (!strcasecmp(c->value, "auto")) { *(int *)lvalue = CFG_AUTO_PORT; break; } /* fall through */ case CONFIG_TYPE_INT: case CONFIG_TYPE_UINT: i = (int)tor_parse_long(c->value, 10, var->type==CONFIG_TYPE_INT ? INT_MIN : 0, var->type==CONFIG_TYPE_PORT ? 65535 : INT_MAX, &ok, NULL); if (!ok) { tor_asprintf(msg, "Int keyword '%s %s' is malformed or out of bounds.", c->key, c->value); return -1; } *(int *)lvalue = i; break; case CONFIG_TYPE_INTERVAL: { i = config_parse_interval(c->value, &ok); if (!ok) { tor_asprintf(msg, "Interval '%s %s' is malformed or out of bounds.", c->key, c->value); return -1; } *(int *)lvalue = i; break; } case CONFIG_TYPE_MSEC_INTERVAL: { i = config_parse_msec_interval(c->value, &ok); if (!ok) { tor_asprintf(msg, "Msec interval '%s %s' is malformed or out of bounds.", c->key, c->value); return -1; } *(int *)lvalue = i; break; } case CONFIG_TYPE_MEMUNIT: { uint64_t u64 = config_parse_memunit(c->value, &ok); if (!ok) { tor_asprintf(msg, "Value '%s %s' is malformed or out of bounds.", c->key, c->value); return -1; } *(uint64_t *)lvalue = u64; break; } case CONFIG_TYPE_BOOL: i = (int)tor_parse_long(c->value, 10, 0, 1, &ok, NULL); if (!ok) { tor_asprintf(msg, "Boolean '%s %s' expects 0 or 1.", c->key, c->value); return -1; } *(int *)lvalue = i; break; case CONFIG_TYPE_AUTOBOOL: if (!strcmp(c->value, "auto")) *(int *)lvalue = -1; else if (!strcmp(c->value, "0")) *(int *)lvalue = 0; else if (!strcmp(c->value, "1")) *(int *)lvalue = 1; else { tor_asprintf(msg, "Boolean '%s %s' expects 0, 1, or 'auto'.", c->key, c->value); return -1; } break; case CONFIG_TYPE_STRING: case CONFIG_TYPE_FILENAME: tor_free(*(char **)lvalue); *(char **)lvalue = tor_strdup(c->value); break; case CONFIG_TYPE_DOUBLE: *(double *)lvalue = atof(c->value); break; case CONFIG_TYPE_ISOTIME: if (parse_iso_time(c->value, (time_t *)lvalue)) { tor_asprintf(msg, "Invalid time '%s' for keyword '%s'", c->value, c->key); return -1; } break; case CONFIG_TYPE_ROUTERSET: if (*(routerset_t**)lvalue) { routerset_free(*(routerset_t**)lvalue); } *(routerset_t**)lvalue = routerset_new(); if (routerset_parse(*(routerset_t**)lvalue, c->value, c->key)<0) { tor_asprintf(msg, "Invalid exit list '%s' for option '%s'", c->value, c->key); return -1; } break; case CONFIG_TYPE_CSV: if (*(smartlist_t**)lvalue) { SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp)); smartlist_clear(*(smartlist_t**)lvalue); } else {
static int config_load( struct idmap_config *config, const char *filename) { char buffer[1024], *pos; FILE *file; struct config_pair pair; const struct config_option *option; int line = 0; int status = NO_ERROR; /* open the file */ file = fopen(filename, "r"); if (file == NULL) { eprintf("config_load() failed to open file '%s'\n", filename); goto out; } /* read each line */ while (fgets(buffer, sizeof(buffer), file)) { line++; /* skip whitespace */ pos = buffer; while (isspace(*pos)) pos++; /* skip comments and empty lines */ if (*pos == '#' || *pos == 0) continue; /* parse line into a key=value pair */ status = config_parse_pair(buffer, &pair); if (status) { eprintf("error on line %d: %s\n", line, buffer); break; } /* find the config_option by key */ status = config_find_option(&pair, &option); if (status) { eprintf("unrecognized option '%s' on line %d: %s\n", pair.key, line, buffer); status = ERROR_INVALID_PARAMETER; break; } if (option->type == TYPE_INT) { if (!parse_uint(pair.value, (UINT*)((char*)config + option->offset))) { status = ERROR_INVALID_PARAMETER; eprintf("expected a number on line %d: %s=\"%s\"\n", line, pair.key, pair.value); break; } } else { if (FAILED(StringCchCopyNA((char*)config + option->offset, option->max_len, pair.value, pair.value_len))) { status = ERROR_BUFFER_OVERFLOW; eprintf("overflow on line %d: %s=\"%s\"\n", line, pair.key, pair.value); break; } } } fclose(file); out: return status; }