/** <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 {
int beacon_config(struct configfile *cf) { char *name, *param1; char *str = cf->buf; int beaconmode = 0; int has_fault = 0; struct beaconset *bset = calloc(1, sizeof(*bset)); bset->beacon_cycle_size = 20.0*60.0; // 20 minutes is the default while (readconfigline(cf) != NULL) { if (configline_is_comment(cf)) continue; /* Comment line, or empty line */ // It can be severely indented... str = config_SKIPSPACE(cf->buf); name = str; str = config_SKIPTEXT(str, NULL); str = config_SKIPSPACE(str); config_STRLOWER(name); param1 = str; str = config_SKIPTEXT(str, NULL); str = config_SKIPSPACE(str); if (strcmp(name, "</beacon>") == 0) break; if (strcmp(name, "cycle-size") == 0) { int v; if (config_parse_interval(param1, &v)) { // Error has_fault = 1; continue; } bset->beacon_cycle_size = (float)v; if (debug) printf("Beacon cycle size: %.2f\n", bset->beacon_cycle_size/60.0); continue; } if (strcmp(name, "beacon") == 0) { beacon_set(cf, param1, str, beaconmode, bset); } else if (strcmp(name, "beaconmode") == 0) { if (strcasecmp(param1, "both") == 0) { beaconmode = 0; } else if (strcasecmp(param1,"radio") == 0) { beaconmode = 1; } else if (strcasecmp(param1,"aprsis") == 0) { beaconmode = -1; } else { printf("%s:%d ERROR: Unknown beaconmode parameter keyword: '%s'\n", cf->name, cf->linenum, param1); has_fault = 1; } } else { printf("%s:%d ERROR: Unknown <beacon> block config keyword: '%s'\n", cf->name, cf->linenum, name); has_fault = 1; continue; } } if (has_fault) { // discard it.. free_beaconset(bset); } else { // save it.. ++bsets_count; bsets = realloc( bsets,sizeof(*bsets)*bsets_count ); bsets[bsets_count-1] = bset; if (debug > 0) { printf("<beacon> set %d defined with %d entries\n", bsets_count, bset->beacon_msgs_count); } } return has_fault; }