/* return: -1: invalid, 0: valid */ int cb_validate_svcinfo(cfg_t *cfg, cfg_opt_t *opt) { char *name; /* only validate the last svcinfo */ cfg_t *sec = cfg_opt_getnsec(opt, cfg_opt_size(opt) - 1); if(!sec) { cfg_error(cfg, "section is NULL?!"); return -1; } if (cfg_title(sec) == NULL) { cfg_error(cfg, "every svcinfo must have a name, but %d seems not", cfg_opt_size(opt) - 1); return -1; } name = cfg_getstr(sec, "name"); if(name == 0 || strlen(name) >= MAX_SVC_NAME_LEN) { cfg_error(cfg, "name option must be set for svcinfo '%s'" " or strlen(name)(%zd) >= len(%u)", cfg_title(sec), strlen(name), MAX_SVC_NAME_LEN); return -1; } if(cfg_getint(sec, "gameid") <= 0) { cfg_error(cfg, "gameid option must be set for svcinfo '%s'", cfg_title(sec)); return -1; } return 0; }
int main(void) { cfg_t *acfg, *bcfg; cfg_t *sec; acfg = create_config(); fail_unless(cfg_parse(acfg, SRC_DIR "/a.conf") == 0); bcfg = create_config(); fail_unless(cfg_parse(bcfg, SRC_DIR "/b.conf") == 0); sec = cfg_getnsec(acfg, "sec", 0); fail_unless(sec != 0); fail_unless(cfg_size(acfg, "sec") == 1); fail_unless(strcmp(cfg_title(sec), "acfg") == 0); fail_unless(cfg_getint(sec, "a") == 5); fail_unless(cfg_getint(sec, "b") == 2); sec = cfg_getnsec(bcfg, "sec", 0); fail_unless(sec != 0); fail_unless(cfg_size(bcfg, "sec") == 1); fail_unless(strcmp(cfg_title(sec), "bcfg") == 0); fail_unless(cfg_getint(sec, "a") == 1); fail_unless(cfg_getint(sec, "b") == 9); cfg_free(acfg); cfg_free(bcfg); return 0; }
/** * @brief parses a downstream {} config entry from a server { } config. * * @param cfg * * @return */ downstream_cfg_t * downstream_cfg_parse(cfg_t * cfg) { downstream_cfg_t * dscfg; assert(cfg != NULL); dscfg = downstream_cfg_new(); assert(dscfg != NULL); dscfg->name = strdup(cfg_title(cfg)); dscfg->enabled = cfg_getbool(cfg, "enabled"); dscfg->host = strdup(cfg_getstr(cfg, "addr")); dscfg->port = cfg_getint(cfg, "port"); dscfg->n_connections = cfg_getint(cfg, "connections"); dscfg->high_watermark = cfg_getint(cfg, "high-watermark"); dscfg->read_timeout.tv_sec = cfg_getnint(cfg, "read-timeout", 0); dscfg->read_timeout.tv_usec = cfg_getnint(cfg, "read-timeout", 1); dscfg->write_timeout.tv_sec = cfg_getnint(cfg, "write-timeout", 0); dscfg->write_timeout.tv_usec = cfg_getnint(cfg, "write-timeout", 1); dscfg->retry_ival.tv_sec = cfg_getnint(cfg, "retry", 0); dscfg->retry_ival.tv_usec = cfg_getnint(cfg, "retry", 1); if (dscfg->enabled == true) { _rusage.total_num_connections += dscfg->n_connections; } return dscfg; }
int main(void) { static cfg_opt_t section_opts[] = { CFG_STR("prop", 0, CFGF_NONE), CFG_END() }; cfg_opt_t opts[] = { CFG_SEC("section", section_opts, CFGF_TITLE | CFGF_MULTI), CFG_END() }; const char *config_data = "section title_one { prop = 'value_one' }\n" "section title_two { prop = 'value_two' }\n"; int rc; cfg_t *cfg = cfg_init(opts, CFGF_NONE); fail_unless(cfg); rc = cfg_parse_buf(cfg, config_data); fail_unless(rc == CFG_SUCCESS); fail_unless(cfg_addtsec(cfg, "section", "title_three")); fail_unless(cfg_size(cfg, "section") == 3); fail_unless(cfg_title(cfg_gettsec(cfg, "section", "title_three"))); /* attempt to add a pre-existing section should fail */ fail_unless(!cfg_addtsec(cfg, "section", "title_three")); cfg_free(cfg); return 0; }
// // E_ProcessInventoryDefs // // Resolves and loads all information for the inventory structures. // void E_ProcessInventoryDefs(cfg_t *cfg) { unsigned int i, numInventory; E_EDFLogPuts("\t* Processing inventory data\n"); if(!(numInventory = cfg_size(cfg, EDF_SEC_INVENTORY))) return; // allocate inheritance stack and hitlist inv_pstack = ecalloc(inventory_t **, numInventoryDefs, sizeof(inventory_t *)); // TODO: any first-time-only processing? for(i = 0; i < numInventory; i++) { cfg_t *invsec = cfg_getnsec(cfg, EDF_SEC_INVENTORY, i); const char *name = cfg_title(invsec); inventory_t *inv = E_InventoryForName(name); // reset the inheritance stack E_ResetInventoryPStack(); // add this def to the stack E_AddInventoryToPStack(inv); E_ProcessInventory(inv, invsec, cfg, true); E_EDFLogPrintf("\t\tFinished inventory %s(#%d)\n", inv->name, inv->numkey); } // free tables efree(inv_pstack); }
// // Process an individual switch // static void E_processSwitch(cfg_t *cfg) { const char *title = cfg_title(cfg); ESwitchDef *def = e_switch_namehash.objectForKey(title); const bool modified = !!def; if(!def) { def = new ESwitchDef; def->offpic = title; e_switch_namehash.addObject(def); eswitches.add(def); E_EDFLogPrintf("\t\tDefined switch %s\n", title); } else E_EDFLogPrintf("\t\tModified switch %s\n", title); auto isset = [modified, cfg](const char *field) { return !modified || cfg_size(cfg, field) > 0; }; if(isset(ITEM_SWITCH_ONPIC)) def->onpic = cfg_getstr(cfg, ITEM_SWITCH_ONPIC); if(isset(ITEM_SWITCH_ONSOUND)) def->onsound = cfg_getstr(cfg, ITEM_SWITCH_ONSOUND); if(isset(ITEM_SWITCH_OFFSOUND)) def->offsound = cfg_getstr(cfg, ITEM_SWITCH_OFFSOUND); if(isset(ITEM_SWITCH_GAMEINDEX)) def->episode = cfg_getint(cfg, ITEM_SWITCH_GAMEINDEX); }
int main(void) { static cfg_opt_t section_opts[] = { CFG_STR("prop", 0, CFGF_NONE), CFG_END() }; cfg_opt_t opts[] = { CFG_SEC("section", section_opts, CFGF_TITLE | CFGF_MULTI), CFG_END() }; const char *config_data = "section title_one { prop = 'value_one' }\n" "section title_two { prop = 'value_two' }\n" "section title_one { prop = 'value_one' }\n"; int rc; cfg_t *cfg = cfg_init(opts, CFGF_NONE); fail_unless(cfg); rc = cfg_parse_buf(cfg, config_data); fail_unless(rc == CFG_SUCCESS); cfg_rmtsec(cfg, "section", "title_two"); fail_unless(cfg_size(cfg, "section") == 1); fail_unless(strcmp(cfg_title(cfg_getnsec(cfg, "section", 0)), "title_one") == 0); cfg_free(cfg); cfg = cfg_init(opts, CFGF_NONE); fail_unless(cfg); rc = cfg_parse_buf(cfg, config_data); fail_unless(rc == CFG_SUCCESS); cfg_rmsec(cfg, "section"); fail_unless(cfg_size(cfg, "section") == 1); fail_unless(strcmp(cfg_title(cfg_getnsec(cfg, "section", 0)), "title_two") == 0); cfg_free(cfg); return 0; }
static void configfile_read_units(void) { int i, nunits; struct unit *u; nunits = cfg_size(cfg, "unit"); for (i = 0; i < nunits; i++) { int nvariants, n; cfg_t *unit; const char *name; if (!(unit = cfg_getnsec(cfg, "unit", i))) BUG(); if (!(name = cfg_title(unit))) BUG(); if (!(nvariants = cfg_size(unit, "variant"))) continue; if (!(u = unit_add(name))) continue; for (n = 0; n < nvariants; n++) { cfg_t *variant; const char *vtitle; if (!(variant = cfg_getnsec(unit, "variant", n))) BUG(); if (!(vtitle = cfg_title(variant))) BUG(); if (!strcasecmp(vtitle, "default")) add_div(u, UNIT_DEFAULT, variant); else if (!strcasecmp(vtitle, "si")) add_div(u, UNIT_SI, variant); else quit("Unknown unit variant \'%s\'\n", vtitle); } } }
static int validate_require_nonnegative(cfg_t *cfg, cfg_opt_t *opt) { if (opt->type == CFGT_INT) { long int value = cfg_opt_getnint(opt, cfg_opt_size(opt) - 1); if (value < 0) { cfg_error(cfg, "Value for option %s can't be negative in %s section \"%s\"", opt->name, cfg->name, cfg_title(cfg)); return -1; } } else if (opt->type == CFGT_FLOAT) { double value = cfg_opt_getnfloat(opt, cfg_opt_size(opt) - 1); if (value < 0.0) { cfg_error(cfg, "Value for option %s can't be negative in %s section \"%s\"", opt->name, cfg->name, cfg_title(cfg)); return -1; } } return 0; }
// // E_CollectInventory // // Pre-creates and hashes by name the inventory definitions, for purpose // of mutual and forward references. // void E_CollectInventory(cfg_t *cfg) { static int currentID = 1; unsigned int i; unsigned int numInventory; // number of inventory defs defined by the cfg inventory_t *newInvDefs = NULL; // get number of inventory definitions defined by the cfg numInventory = cfg_size(cfg, EDF_SEC_INVENTORY); // echo counts E_EDFLogPrintf("\t\t%u inventory items defined\n", numInventory); if(numInventory) { // allocate inventory structures for the new thingtypes newInvDefs = estructalloc(inventory_t, numInventory); numInventoryDefs += numInventory; // create metatables for(i = 0; i < numInventory; i++) newInvDefs[i].meta = new MetaTable("inventory"); } // build hash tables E_EDFLogPuts("\t\tBuilding inventory hash tables\n"); // cycle through the thingtypes defined in the cfg for(i = 0; i < numInventory; i++) { cfg_t *invcfg = cfg_getnsec(cfg, EDF_SEC_INVENTORY, i); const char *name = cfg_title(invcfg); // This is a new inventory, whether or not one already exists by this name // in the hash table. For subsequent addition of EDF inventory defs at // runtime, the hash table semantics of "find newest first" take care of // overriding, while not breaking objects that depend on the original // definition of the inventory type for inheritance purposes. inventory_t *inv = &newInvDefs[i]; // initialize name inv->name = estrdup(name); // add to name hash inv_namehash.addObject(inv); // create ID number and add to hash table inv->numkey = currentID++; inv_numhash.addObject(inv); } }
int filters_init(cfg_t *cfg) { filters = g_hash_table_new_full(&g_str_hash, &g_str_equal, &g_free, (GDestroyNotify)&filter_free); int index = cfg_size(cfg, "filter"); while (index--) { cfg_t *sec = cfg_getnsec(cfg, "filter", index); filter *f = filter_create(); add_filter_restrictions(f, sec); g_hash_table_insert(filters, g_strdup(cfg_title(sec)), f); } return 1; }
static void configfile_read_attrs(void) { int i, nattrs, t; nattrs = cfg_size(cfg, "attr"); for (i = 0; i < nattrs; i++) { struct unit *u; cfg_t *attr; const char *name, *description, *unit, *type; int flags = 0; if (!(attr = cfg_getnsec(cfg, "attr", i))) BUG(); if (!(name = cfg_title(attr))) BUG(); description = cfg_getstr(attr, "description"); unit = cfg_getstr(attr, "unit"); type = cfg_getstr(attr, "type"); if (!unit) quit("Attribute '%s' is missing unit specification\n", name); if (!type) quit("Attribute '%s' is missing type specification\n", name); if (!(u = unit_lookup(unit))) quit("Unknown unit \'%s\' attribute '%s'\n", unit, name); if (!strcasecmp(type, "counter")) t = ATTR_TYPE_COUNTER; else if (!strcasecmp(type, "rate")) t = ATTR_TYPE_RATE; else if (!strcasecmp(type, "percent")) t = ATTR_TYPE_PERCENT; else quit("Unknown type \'%s\' in attribute '%s'\n", type, name); if (cfg_getbool(attr, "history")) flags |= ATTR_DEF_FLAG_HISTORY; attr_def_add(name, description, u, t, flags); } }
static int cb_validate_virtual(cfg_t *cfg, cfg_opt_t *opt) { unsigned int i; for (i = 0; i < cfg_size(cfg, "virtual-package"); i++) { cfg_t *sec = cfg_opt_getnsec(opt, i); if (cfg_getstr(sec, "targets") == 0) { cfg_error(cfg, "targets must be set for " "virtual-package %s", cfg_title(sec)); return -1; } } return 0; }
int Settings::getDeviceState( int intDeviceId ) const { TelldusCore::MutexLocker locker(&mutex); if (d->var_cfg == 0) { return false; } cfg_t *cfg_device; for (int i = 0; i < cfg_size(d->var_cfg, "device"); ++i) { cfg_device = cfg_getnsec(d->var_cfg, "device", i); int deviceId = atoi(cfg_title(cfg_device)); if (deviceId == intDeviceId) { return cfg_getint(cfg_device, "state"); } } return TELLSTICK_TURNOFF; }
std::wstring Settings::getDeviceStateValue( int intDeviceId ) const { TelldusCore::MutexLocker locker(&mutex); if (d->var_cfg == 0) { return L""; } cfg_t *cfg_device; for (int i = 0; i < cfg_size(d->var_cfg, "device"); ++i) { cfg_device = cfg_getnsec(d->var_cfg, "device", i); int deviceId = atoi(cfg_title(cfg_device)); if (deviceId == intDeviceId) { std::string value(cfg_getstr(cfg_device, "stateValue")); return TelldusCore::charToWstring(value.c_str()); } } return L""; }
int cb_validate_bookmark(cfg_t *cfg, cfg_opt_t *opt) { /* only validate the last bookmark */ cfg_t *sec = cfg_opt_getnsec(opt, cfg_opt_size(opt) - 1); if(!sec) { cfg_error(cfg, "section is NULL!?"); return -1; } if(cfg_getstr(sec, "machine") == 0) { cfg_error(cfg, "machine option must be set for bookmark '%s'", cfg_title(sec)); return -1; } return 0; }
int main(void) { cfg_opt_t group_opts[] = { CFG_INT("number", 0, CFGF_NONE), CFG_INT("total", 0, CFGF_NONE), CFG_END() }; cfg_opt_t groups_opts[] = { CFG_STR("name", "Esmé", CFGF_NONE), CFG_SEC("group", group_opts, CFGF_TITLE | CFGF_MULTI), CFG_END() }; cfg_opt_t opts[] = { CFG_SEC("groups", groups_opts, CFGF_NONE), CFG_END() }; cfg_t *cfg, *sec; size_t i, j; cfg = cfg_init(opts, CFGF_NONE); if (!cfg || cfg_parse(cfg, CONF) == CFG_PARSE_ERROR) { perror("Failed parsing " CONF); return 1; } /* Iterate over the sections and print fields from each section. */ for (i = 0; i < cfg_size(cfg, "groups"); i++) { sec = cfg_getnsec(cfg, "groups", i); for (j = 0; j < cfg_size(sec, "group"); j++) { cfg_t *opt = cfg_getnsec(sec, "group", j); printf("group title: '%s'\n", cfg_title(opt)); printf("group number: %ld\n", cfg_getint(opt, "number")); printf("group total: %ld\n", cfg_getint(opt, "total")); printf("\n"); } } cfg_free(cfg); return 0; }
SyncLogEntry SyncLogger::ReadEntry(cfg_t* pEntryCFG) { // Assures that the section has been found, which means there is at least one section. assert(pEntryCFG != NULL); // TODO: Copy values string strModType = cfg_getstr(pEntryCFG, MOD_TYPE_VARNAME); if (strModType.length() != 1) { // The log entry does not meet the standard. throw OFSException("The log entry does not meet the standard", 1); } int nModNumber = atoi(cfg_title(pEntryCFG)); SyncLogEntry sle(cfg_getstr(pEntryCFG, FILE_PATH_VARNAME), cfg_getstr(pEntryCFG, MOD_TIME_VARNAME), strModType.c_str()[0], nModNumber); return sle; }
static void print_system(cfg_t *provider) { size_t i; printf("\n"); printf("system %s\n", cfg_title(provider)); print_string(provider, "username", 1); print_string(provider, "password", 1); if (cfg_size(provider, "alias")) { printf(" alias "); for (i = 0; i < cfg_size(provider, "alias"); i++) printf("%s%s", i != 0 ? ", " : "", cfg_getnstr(provider, "alias", i)); printf("\n"); } }
static void configfile_read_history(void) { int i, nhistory; nhistory = cfg_size(cfg, "history"); for (i = 0; i < nhistory; i++) { struct history_def *def; cfg_t *history; const char *name, *type; float interval; int size; if (!(history = cfg_getnsec(cfg, "history", i))) BUG(); if (!(name = cfg_title(history))) BUG(); interval = cfg_getfloat(history, "interval"); size = cfg_getint(history, "size"); type = cfg_getstr(history, "type"); if (interval == 0.0f) interval = cfg_getfloat(cfg, "read_interval"); def = history_def_alloc(name); def->hd_interval = interval; def->hd_size = size; if (!strcasecmp(type, "8bit")) def->hd_type = HISTORY_TYPE_8; else if (!strcasecmp(type, "16bit")) def->hd_type = HISTORY_TYPE_16; else if (!strcasecmp(type, "32bit")) def->hd_type = HISTORY_TYPE_32; else if (!strcasecmp(type, "64bit")) def->hd_type = HISTORY_TYPE_64; else quit("Invalid type \'%s\', must be \"(8|16|32|64)bit\"" " in history definition #%d\n", type, i+1); } }
// // E_ProcessStrings // // 03/27/05: EDF can now define custom string objects. // These are now processed first. This is extremely simple. // void E_ProcessStrings(cfg_t *cfg) { unsigned int i, numstrings = cfg_size(cfg, EDF_SEC_STRING); E_EDFLogPrintf("\t* Processing strings\n" "\t\t%d string(s) defined\n", numstrings); for(i = 0; i < numstrings; ++i) { cfg_t *sec = cfg_getnsec(cfg, EDF_SEC_STRING, i); const char *mnemonic, *value, *bex, *bexsource; int number; dehstr_t *dehstr; mnemonic = cfg_title(sec); value = cfg_getstr(sec, ITEM_STRING_VAL); number = cfg_getint(sec, ITEM_STRING_NUM); // haleyjd 09/16/07: support also assigning the value of a BEX string, // and filling this string object with the value of a BEX string bex = cfg_getstr(sec, ITEM_STRING_BEXDST); bexsource = cfg_getstr(sec, ITEM_STRING_BEXSRC); // if bexsource is a valid BEX mnemonic, the value to use becomes the // value of that BEX string rather than any specified in this string object. if((dehstr = D_GetBEXStr(bexsource))) value = *(dehstr->ppstr); E_CreateString(value, mnemonic, number); E_EDFLogPrintf("\t\tDefined string '%s' (#%d)\n" "\t\t\tvalue = '%s'\n", mnemonic, number, value); if((dehstr = D_GetBEXStr(bex))) { *(dehstr->ppstr) = estrdup(value); E_EDFLogPrintf("\t\t\tCopied to BEX string '%s'\n", bex); } } }
// // E_CountUniqueStates // // haleyjd 03/31/10: counts the number of states in a cfg which do not overwrite // any pre-existing states by virtue of having the same name. // static unsigned int E_CountUniqueStates(cfg_t *cfg, unsigned int numstates) { unsigned int i; unsigned int count = 0; // if the state name hash is empty, short-circuit for efficiency if(!state_namehash.getNumItems()) return numstates; for(i = 0; i < numstates; ++i) { cfg_t *statecfg = cfg_getnsec(cfg, EDF_SEC_FRAME, i); const char *name = cfg_title(statecfg); // if not in the name table, count it if(E_StateNumForName(name) < 0) ++count; } return count; }
bool Settings::setDeviceState( int intDeviceId, int intDeviceState, const std::wstring &strDeviceStateValue ) { TelldusCore::MutexLocker locker(&mutex); if (d->var_cfg == 0) { return false; } cfg_t *cfg_device; for (int i = 0; i < cfg_size(d->var_cfg, "device"); ++i) { cfg_device = cfg_getnsec(d->var_cfg, "device", i); int deviceId = atoi(cfg_title(cfg_device)); if (deviceId == intDeviceId) { cfg_setint(cfg_device, "state", intDeviceState); cfg_setstr(cfg_device, "stateValue", TelldusCore::wideToString(strDeviceStateValue).c_str()); FILE *fp = fopen(VAR_CONFIG_FILE, "we"); // e for setting O_CLOEXEC on the file handle if(fp == 0) { return false; } cfg_print(d->var_cfg, fp); fclose(fp); return true; } } // The device is not found in the file, we must create it manualy... FILE *fp = fopen(VAR_CONFIG_FILE, "we"); // e for setting O_CLOEXEC on the file handle if(!fp) { fprintf(stderr, "Failed to write state to %s: %s\n", VAR_CONFIG_FILE, strerror(errno)); return false; } cfg_print(d->var_cfg, fp); // Print the config-file fprintf(fp, "device %d {\n}\n", intDeviceId); // Print the new device fclose(fp); // Re-read config-file cfg_free(d->var_cfg); readVarConfig(&d->var_cfg); return false; }
int main(void) { cfg_opt_t greet_opts[] = { CFG_STR_LIST("targets", "{World}", CFGF_NONE), CFG_INT("repeat", 1, CFGF_NONE), CFG_END() }; cfg_opt_t opts[] = { CFG_SEC("greeting", greet_opts, CFGF_TITLE | CFGF_MULTI), CFG_END() }; cfg_t *cfg, *cfg_greet; int repeat; int i, j; cfg = cfg_init(opts, CFGF_NONE); cfg_set_validate_func(cfg, "greeting|repeat", validate_unsigned_int); if(cfg_parse(cfg, "hello.conf") == CFG_PARSE_ERROR) return 1; for(j = 0; j < cfg_size(cfg, "greeting"); j++) { cfg_greet = cfg_getnsec(cfg, "greeting", j); repeat = cfg_getint(cfg_greet, "repeat"); while(repeat--) { printf("%s", cfg_title(cfg_greet)); for(i = 0; i < cfg_size(cfg_greet, "targets"); i++) printf(", %s", cfg_getnstr(cfg_greet, "targets", i)); printf("!\n"); } } cfg_free(cfg); return 0; }
static void configfile_read_element_cfg(void) { int i, nelement; nelement = cfg_size(cfg, "element"); for (i = 0; i < nelement; i++) { struct element_cfg *ec; cfg_t *element; const char *name, *description; long max; if (!(element = cfg_getnsec(cfg, "element", i))) BUG(); if (!(name = cfg_title(element))) BUG(); ec = element_cfg_alloc(name); if ((description = cfg_getstr(element, "description"))) ec->ec_description = strdup(description); if ((max = cfg_getint(element, "max"))) ec->ec_rxmax = ec->ec_txmax = max; if ((max = cfg_getint(element, "rxmax"))) ec->ec_rxmax = max; if ((max = cfg_getint(element, "txmax"))) ec->ec_txmax = max; if (cfg_getbool(element, "show")) ec->ec_flags |= ELEMENT_CFG_SHOW; else ec->ec_flags |= ELEMENT_CFG_HIDE; } }
vhost_cfg_t * vhost_cfg_parse(cfg_t * cfg) { vhost_cfg_t * vcfg; cfg_t * log_cfg; cfg_t * req_log_cfg; cfg_t * err_log_cfg; cfg_t * hdr_cfg; cfg_t * default_rule_cfg; int i; int res; vcfg = vhost_cfg_new(); assert(vcfg != NULL); vcfg->server_name = strdup(cfg_title(cfg)); vcfg->ssl_cfg = ssl_cfg_parse(cfg_getsec(cfg, "ssl")); for (i = 0; i < cfg_size(cfg, "rule"); i++) { lztq_elem * elem; rule_cfg_t * rule; if (!(rule = rule_cfg_parse(cfg_getnsec(cfg, "rule", i)))) { return NULL; } elem = lztq_append(vcfg->rule_cfgs, rule, sizeof(rule), rule_cfg_free); assert(elem != NULL); } for (i = 0; i < cfg_size(cfg, "aliases"); i++) { lztq_elem * elem; char * name; assert(cfg_getnstr(cfg, "aliases", i) != NULL); name = strdup(cfg_getnstr(cfg, "aliases", i)); assert(name != NULL); elem = lztq_append(vcfg->aliases, name, strlen(name), free); assert(elem != NULL); } if (cfg_size(cfg, "strip-headers")) { vcfg->strip_hdrs = lztq_new(); assert(vcfg->strip_hdrs != NULL); for (i = 0; i < cfg_size(cfg, "strip-headers"); i++) { lztq_elem * elem; char * hdr_name; assert(cfg_getnstr(cfg, "strip-headers", i) != NULL); hdr_name = strdup(cfg_getnstr(cfg, "strip-headers", i)); assert(hdr_name != NULL); elem = lztq_append(vcfg->strip_hdrs, hdr_name, strlen(hdr_name), free); assert(elem != NULL); } } log_cfg = cfg_getsec(cfg, "logging"); hdr_cfg = cfg_getsec(cfg, "headers"); if (log_cfg) { vcfg->req_log = logger_cfg_parse(cfg_getsec(log_cfg, "request")); vcfg->err_log = logger_cfg_parse(cfg_getsec(log_cfg, "error")); } if (hdr_cfg) { vcfg->headers = headers_cfg_parse(hdr_cfg); } return vcfg; } /* vhost_cfg_parse */
void fwup_cfg_opt_to_string(cfg_opt_t *opt, struct simple_string *s) { if (!opt) return; if (opt->type == CFGT_SEC) { for (unsigned int i = 0; i < cfg_opt_size(opt); i++) { ptrdiff_t section_start_offset = s->p - s->str; cfg_t *sec = cfg_opt_getnsec(opt, i); if (is_set(CFGF_TITLE, opt->flags)) ssprintf(s, "%s \"%s\" {\n", opt->name, cfg_title(sec)); else ssprintf(s, "%s {\n", opt->name); ptrdiff_t before_offset = s->p - s->str; fwup_cfg_print(sec, s); if (s->p - s->str == before_offset && strcmp(opt->name, "task") != 0) { // Section was empty, so rewind output string. s->p = s->str + section_start_offset; } else { // Non-empty section or a "task", so close out. ssprintf(s, "}\n"); } } } else if (opt->type != CFGT_FUNC && opt->type != CFGT_NONE) { if (is_set(CFGF_LIST, opt->flags) && opt->nvalues) { ssprintf(s, "%s = {", opt->name); fwup_cfg_opt_nprint_var(opt, 0, s); for (unsigned int i = 1; i < opt->nvalues; i++) { ssprintf(s, ", "); fwup_cfg_opt_nprint_var(opt, i, s); } ssprintf(s, "}\n"); } else { // if not set, don't print if (opt->simple_value.ptr) { if (opt->type == CFGT_STR && *opt->simple_value.string == 0) return; } else { if (cfg_opt_size(opt) == 0 || (opt->type == CFGT_STR && (opt->values[0]->string == 0 || opt->values[0]->string[0] == 0))) return; } // Don't print out defaults. if (cfg_is_default(opt)) return; // Don't print assertions if (strncmp("assert-", opt->name, 7) == 0) return; // Skip host-path (see note in top comment) if (strcmp("host-path", opt->name) == 0 || strcmp("bootstrap-code-host-path", opt->name) == 0) return; ssprintf(s, "%s=", opt->name); fwup_cfg_opt_nprint_var(opt, 0, s); ssprintf(s, "\n"); } } }
/** * @brief parses a single rule from a server { vhost { rules { } } } config * * @param cfg * * @return */ rule_cfg_t * rule_cfg_parse(cfg_t * cfg) { rule_cfg_t * rcfg; const char * rname; int i; assert(cfg != NULL); rname = cfg_title(cfg); assert(rname != NULL); rcfg = rule_cfg_new(); assert(cfg != NULL); rcfg->name = strdup(rname); assert(rcfg->name != NULL); if (cfg_getstr(cfg, "uri-match")) { rcfg->type = rule_type_exact; rcfg->matchstr = strdup(cfg_getstr(cfg, "uri-match")); } else if (cfg_getstr(cfg, "uri-gmatch")) { rcfg->type = rule_type_glob; rcfg->matchstr = strdup(cfg_getstr(cfg, "uri-gmatch")); } else if (cfg_getstr(cfg, "uri-rmatch")) { rcfg->type = rule_type_regex; rcfg->matchstr = strdup(cfg_getstr(cfg, "uri-rmatch")); } else { fprintf(stderr, "Rule %s has no match statement!\n", rname); exit(EXIT_FAILURE); } rcfg->lb_method = lbstr_to_lbtype(cfg_getstr(cfg, "lb-method")); rcfg->headers = headers_cfg_parse(cfg_getsec(cfg, "headers")); rcfg->passthrough = cfg_getbool(cfg, "passthrough"); rcfg->allow_redirect = cfg_getbool(cfg, "allow-redirect"); if (cfg_getopt(cfg, "upstream-read-timeout")) { rcfg->up_read_timeout.tv_sec = cfg_getnint(cfg, "upstream-read-timeout", 0); rcfg->up_read_timeout.tv_usec = cfg_getnint(cfg, "upstream-read-timeout", 1); rcfg->has_up_read_timeout = 1; } if (cfg_getopt(cfg, "upstream-write-timeout")) { rcfg->up_write_timeout.tv_sec = cfg_getnint(cfg, "upstream-write-timeout", 0); rcfg->up_write_timeout.tv_usec = cfg_getnint(cfg, "upstream-write-timeout", 1); rcfg->has_up_write_timeout = 1; } for (i = 0; i < cfg_size(cfg, "downstreams"); i++) { lztq_elem * elem; char * ds_name; ds_name = strdup(cfg_getnstr(cfg, "downstreams", i)); assert(ds_name != NULL); elem = lztq_append(rcfg->downstreams, ds_name, strlen(ds_name), free); assert(elem != NULL); } if (rcfg->allow_redirect != 0 && cfg_size(cfg, "redirect-filter")) { /* * if the redirect option is enabled, optionally an administrator can * add a list of allowed hosts it may communicate with. */ int n_filters; n_filters = cfg_size(cfg, "redirect-filter"); assert(n_filters > 0); rcfg->redirect_filter = lztq_new(); assert(rcfg->redirect_filter != NULL); for (i = 0; i < n_filters; i++) { lztq_elem * elem; char * host_ent; host_ent = strdup(cfg_getnstr(cfg, "redirect-filter", i)); assert(host_ent != NULL); elem = lztq_append(rcfg->redirect_filter, host_ent, strlen(host_ent), free); assert(elem != NULL); } } return rcfg; } /* rule_cfg_parse */
bool TryGetSNESDevConfig(const char *fileName, const int argc, char **argv, SNESDevConfig *const config) { const Arguments arguments = ParseArguments(argc, argv); cfg_opt_t GamepadOpts[] = { CFG_BOOL(CFG_ENABLED, cfg_false, CFGF_NONE), CFG_INT(CFG_GPIO, 0, CFGF_NONE), CFG_END() }; cfg_opt_t GamepadsOpts[] = { CFG_SEC(CFG_GAMEPAD, GamepadOpts, CFGF_MULTI | CFGF_TITLE), CFG_INT_CB(CFG_GAMEPAD_TYPE, 0, CFGF_NONE, &VerifyGamepadType), CFG_INT(CFG_CLOCK_GPIO, 0, CFGF_NONE), CFG_INT(CFG_LATCH_GPIO, 0, CFGF_NONE), CFG_INT(CFG_POLL_FREQ, 0, CFGF_NONE), CFG_END() }; cfg_opt_t ButtonOpts[] = { CFG_BOOL(CFG_ENABLED, cfg_false, CFGF_NONE), CFG_INT_CB(CFG_KEY, 0, CFGF_NONE, &VerifyInputKey), CFG_INT(CFG_GPIO, 0, CFGF_NONE), CFG_END() }; cfg_opt_t ButtonsOpts[] = { CFG_SEC(CFG_BUTTON, ButtonOpts, CFGF_MULTI | CFGF_TITLE), CFG_INT(CFG_POLL_FREQ, 0, CFGF_NONE), CFG_END() }; cfg_opt_t opts[] = { CFG_SEC(CFG_GAMEPADS, GamepadsOpts, CFGF_NONE), CFG_SEC(CFG_BUTTONS, ButtonsOpts, CFGF_NONE), CFG_END() }; cfg_t *cfg; cfg = cfg_init(opts, CFGF_NOCASE); if (access(fileName, F_OK) == -1 || cfg_parse(cfg, fileName) != CFG_SUCCESS) { fprintf(stderr, "Cannot read config file %s\n", fileName); return false; } // Initialize from arguments. memset(config, 0, sizeof(SNESDevConfig)); config->RunAsDaemon = !arguments.DebugEnabled && arguments.RunAsDaemon; config->DebugEnabled = arguments.DebugEnabled; config->Verbose = config->RunAsDaemon ? 0 : arguments.Verbose; // PidFile came from argv so will be way down teh stack :-) config->PidFile = arguments.PidFile; // Parse gamepad section GamepadsConfig *gamepadsConfig = &config->Gamepads; cfg_t *gamepadsSection = cfg_getsec(cfg, CFG_GAMEPADS); gamepadsConfig->ClockGpio = (uint8_t) SafeToUnsigned(cfg_getint(gamepadsSection, CFG_CLOCK_GPIO)); gamepadsConfig->LatchGpio = (uint8_t) SafeToUnsigned(cfg_getint(gamepadsSection, CFG_LATCH_GPIO)); unsigned int pollFrequency = SafeToUnsigned(cfg_getint(gamepadsSection, CFG_POLL_FREQ)); if(pollFrequency > 0) { gamepadsConfig->PollFrequency = (unsigned int)(1000 / (double)pollFrequency); } gamepadsConfig->Type = (GamepadType)cfg_getint(gamepadsSection, CFG_GAMEPAD_TYPE); unsigned int numberOfGamepads = cfg_size(gamepadsSection, CFG_GAMEPAD); // Parse gamepads // TODO: Sort by gamepad id. for(unsigned int i = 0; i < numberOfGamepads; i++) { cfg_t *gamepadSection = cfg_getnsec(gamepadsSection, CFG_GAMEPAD, i); bool enabled = cfg_getbool(gamepadSection, CFG_ENABLED) ? true : false; if(!enabled) { continue; } GamepadConfig *gamepadConfig = gamepadsConfig->Gamepads + gamepadsConfig->Total; gamepadConfig->Id = (unsigned int) atoi(cfg_title(gamepadSection)); gamepadConfig->DataGpio = (uint8_t) SafeToUnsigned(cfg_getint(gamepadSection, CFG_GPIO)); gamepadsConfig->Total++; if(gamepadsConfig->Total > SNESDEV_MAX_GAMEPADS) { break; } } // Parse buttons section. ButtonsConfig *buttonsConfig = &config->Buttons; cfg_t *buttonsSection = cfg_getsec(cfg, CFG_BUTTONS); pollFrequency = SafeToUnsigned(cfg_getint(buttonsSection, CFG_POLL_FREQ)); if(pollFrequency > 0) { buttonsConfig->PollFrequency = (unsigned int) (1000 / (double)pollFrequency); } unsigned int numberOfButtons = cfg_size(buttonsSection, CFG_BUTTON); // Parse buttons // TODO: Sort by button id. for (unsigned int i = 0; i < numberOfButtons; i++) { cfg_t *buttonSection = cfg_getnsec(buttonsSection, CFG_BUTTON, i); bool enabled = cfg_getbool(buttonSection, CFG_ENABLED) ? true : false; if(!enabled) { continue; } ButtonConfig *buttonConfig = buttonsConfig->Buttons + buttonsConfig->Total; buttonConfig->Id = (unsigned int) atoi(cfg_title(buttonSection)); buttonConfig->Key = (InputKey) cfg_getint(buttonSection, CFG_KEY); buttonConfig->DataGpio = (uint8_t) SafeToUnsigned(cfg_getint(buttonSection, CFG_GPIO)); buttonsConfig->Total++; if(buttonsConfig->Total > SNESDEV_MAX_BUTTONS) { break; } } cfg_free(cfg); if(!ValidateConfig(config)) { return false; } return true; }
DLLIMPORT void cfg_opt_print_indent(cfg_opt_t *opt, FILE *fp, int indent) { assert(opt && fp); if(opt->type == CFGT_SEC) { cfg_t *sec; unsigned int i; for(i = 0; i < cfg_opt_size(opt); i++) { sec = cfg_opt_getnsec(opt, i); cfg_indent(fp, indent); if(is_set(CFGF_TITLE, opt->flags)) fprintf(fp, "%s \"%s\" {\n", opt->name, cfg_title(sec)); else fprintf(fp, "%s {\n", opt->name); cfg_print_indent(sec, fp, indent + 1); cfg_indent(fp, indent); fprintf(fp, "}\n"); } } else if(opt->type != CFGT_FUNC && opt->type != CFGT_NONE) { if(is_set(CFGF_LIST, opt->flags)) { unsigned int i; cfg_indent(fp, indent); fprintf(fp, "%s = {", opt->name); if(opt->nvalues) { if(opt->pf) opt->pf(opt, 0, fp); else cfg_opt_nprint_var(opt, 0, fp); for(i = 1; i < opt->nvalues; i++) { fprintf(fp, ", "); if(opt->pf) opt->pf(opt, i, fp); else cfg_opt_nprint_var(opt, i, fp); } } fprintf(fp, "}"); } else { cfg_indent(fp, indent); /* comment out the option if is not set */ if(opt->simple_value) { if(opt->type == CFGT_STR && *((char **)opt->simple_value) == 0) fprintf(fp, "# "); } else { if(cfg_opt_size(opt) == 0 || ( opt->type == CFGT_STR && (opt->values[0]->string == 0 || opt->values[0]->string[0] == 0))) fprintf(fp, "# "); } fprintf(fp, "%s = ", opt->name); if(opt->pf) opt->pf(opt, 0, fp); else cfg_opt_nprint_var(opt, 0, fp); } fprintf(fp, "\n"); } else if(opt->pf) { cfg_indent(fp, indent); opt->pf(opt, 0, fp); fprintf(fp, "\n"); } }