void validate_setup(void) { cfg_opt_t *opt = 0; static cfg_opt_t action_opts[] = { CFG_INT("speed", 0, CFGF_NONE), CFG_STR("name", 0, CFGF_NONE), CFG_INT("xspeed", 0, CFGF_NONE), CFG_END() }; static cfg_opt_t multi_opts[] = { CFG_INT_LIST("speeds", 0, CFGF_NONE), CFG_SEC("options", action_opts, CFGF_NONE), CFG_END() }; cfg_opt_t opts[] = { CFG_STR_LIST("ip-address", 0, CFGF_NONE), CFG_INT_CB("action", ACTION_NONE, CFGF_NONE, parse_action), CFG_SEC("options", action_opts, CFGF_NONE), CFG_SEC("multi_options", multi_opts, CFGF_MULTI), CFG_END() }; cfg = cfg_init(opts, 0); cfg_set_validate_func(cfg, "ip-address", validate_ip); fail_unless(cfg_set_validate_func(cfg, "ip-address", validate_ip) == validate_ip); opt = cfg_getopt(cfg, "ip-address"); fail_unless(opt != 0); fail_unless(opt->validcb == validate_ip); cfg_set_validate_func(cfg, "options", validate_action); fail_unless(cfg_set_validate_func(cfg, "options", validate_action) == validate_action); opt = cfg_getopt(cfg, "options"); fail_unless(opt != 0); fail_unless(opt->validcb == validate_action); cfg_set_validate_func(cfg, "options|speed", validate_speed); fail_unless(cfg_set_validate_func(cfg, "options|speed", validate_speed) == validate_speed); opt = cfg_getopt(cfg, "options|speed"); fail_unless(opt != 0); fail_unless(opt->validcb == validate_speed); cfg_set_validate_func(cfg, "multi_options|speeds", validate_speed); fail_unless(cfg_set_validate_func(cfg, "multi_options|speeds", validate_speed) == validate_speed); cfg_set_validate_func(cfg, "multi_options|options|xspeed", validate_speed); fail_unless(cfg_set_validate_func(cfg, "multi_options|options|xspeed", validate_speed) == validate_speed); /* Validate callbacks for *set*() functions, i.e. not when parsing file content */ cfg_set_validate_func2(cfg, "multi_options|speed", validate_speed2); cfg_set_validate_func2(cfg, "multi_options|options|name", validate_name2); }
cfg_t *parse_conf(const char *filename) { cfg_opt_t bookmark_opts[] = { CFG_STR("host", 0, CFGF_NODEFAULT), CFG_INT("port", 21, CFGF_NONE), CFG_STR("login", "anonymous", CFGF_NONE), CFG_STR("password", "anonymous@", CFGF_NONE), CFG_STR("directory", 0, CFGF_NONE), CFG_END() }; cfg_opt_t opts[] = { CFG_SEC("bookmark", bookmark_opts, CFGF_MULTI | CFGF_TITLE), CFG_BOOL("reverse-dns", cfg_true, CFGF_NONE), CFG_BOOL("passive-mode", cfg_false, CFGF_NONE), CFG_BOOL("remote-completion", cfg_true, CFGF_NONE), CFG_FUNC("alias", conf_alias), CFG_STR_LIST("xterm-terminals", "{xterm, rxvt}", CFGF_NONE), CFG_INT_CB("auto-create-bookmark", ACB_YES, CFGF_NONE, conf_parse_acb), CFG_FUNC("include-file", cfg_include), CFG_END() }; cfg_t *cfg = cfg_init(opts, CFGF_NONE); cfg_set_validate_func(cfg, "bookmark|port", conf_validate_port); cfg_set_validate_func(cfg, "bookmark", conf_validate_bookmark); switch(cfg_parse(cfg, filename)) { case CFG_FILE_ERROR: printf("warning: configuration file '%s' could not be read: %s\n", filename, strerror(errno)); printf("continuing with default values...\n\n"); case CFG_SUCCESS: break; case CFG_PARSE_ERROR: return 0; } return cfg; }
/* Forward */ static int cb_loglevel(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result); /* general section structure */ static cfg_opt_t sec_general[] = { CFG_STR("uid", "nobody", CFGF_NONE), CFG_STR("admin_password", NULL, CFGF_NONE), CFG_STR("logfile", STATEDIR "/log/" PACKAGE ".log", CFGF_NONE), CFG_STR("db_path", STATEDIR "/cache/" PACKAGE "/songs3.db", CFGF_NONE), CFG_INT("db_pragma_cache_size", -1, CFGF_NONE), CFG_STR("db_pragma_journal_mode", NULL, CFGF_NONE), CFG_INT("db_pragma_synchronous", -1, CFGF_NONE), CFG_INT_CB("loglevel", E_LOG, CFGF_NONE, &cb_loglevel), CFG_BOOL("ipv6", cfg_true, CFGF_NONE), CFG_STR("cache_path", STATEDIR "/cache/" PACKAGE "/cache.db", CFGF_NONE), CFG_INT("cache_daap_threshold", 1000, CFGF_NONE), CFG_END() }; /* library section structure */ static cfg_opt_t sec_library[] = { CFG_STR("name", "My Music on %h", CFGF_NONE), CFG_INT("port", 3689, CFGF_NONE), CFG_STR("password", NULL, CFGF_NONE), CFG_STR_LIST("directories", NULL, CFGF_NONE), CFG_STR_LIST("podcasts", NULL, CFGF_NONE), CFG_STR_LIST("audiobooks", NULL, CFGF_NONE),
int configuration(struct app_parent *app_p, const char *configfile, char **policy_file, char **syslog_ident, int *syslog_flags, int *syslog_facility) { unsigned int i, j; struct tq_listener_s *p_listener = NULL; struct tq_service_s *p_service = NULL; char *buf = NULL; cfg_t *cfg; cfg_t *syslog_sec; unsigned n_listener, n_services; int ret; static cfg_opt_t syslog_opts[] = { CFG_STR("ident", NULL, CFGF_NONE), CFG_INT_CB("facility", NONE, CFGF_NONE, &cb_syslog_facility), CFG_INT_LIST_CB("options", NULL, CFGF_NONE, &cb_syslog_options), CFG_END() }; static cfg_opt_t service_opts[] = { CFG_INT_CB("type", NONE, CFGF_NONE, &cb_service_type), CFG_STR("uri", 0, CFGF_NONE), CFG_INT("threads", 4, CFGF_NONE), CFG_END() }; static cfg_opt_t listener_opts[] = { CFG_STR("bindaddress", 0, CFGF_NONE), CFG_INT("port", 9001, CFGF_NONE), CFG_INT("backlog", 1024, CFGF_NONE), CFG_STR("cert", 0, CFGF_NONE), CFG_STR("key", 0, CFGF_NONE), CFG_STR("cafile", 0, CFGF_NONE), CFG_STR("capath", 0, CFGF_NONE), CFG_STR("crlpath", 0, CFGF_NONE), CFG_STR("password", 0, CFGF_NONE), CFG_STR("cipherlist", 0, CFGF_NONE), CFG_INT_CB("clientauth", NONE, CFGF_NONE, &cb_answer), CFG_INT_CB("rfc3820", NONE, CFGF_NONE, &cb_answer), CFG_STR("whitelist", 0, CFGF_NONE), CFG_STR("blacklist", 0, CFGF_NONE), CFG_SEC("service", service_opts, CFGF_MULTI), CFG_END() }; cfg_opt_t opts[] = { CFG_INT_CB("debug", NONE, CFGF_NONE, &cb_answer), CFG_STR("policyfile", 0, CFGF_NONE), CFG_SEC("syslog", syslog_opts, CFGF_NONE), CFG_SEC("listener", listener_opts, CFGF_MULTI), CFG_END() }; cfg = cfg_init(opts, CFGF_NOCASE); /* set a validating callback function for bookmark sections */ /* cfg_set_validate_func(cfg, "bookmark", &cb_validate_bookmark); */ ret = cfg_parse(cfg, configfile); if (ret == CFG_FILE_ERROR) { fprintf(stderr, "Error: could not open or read the configuration file " "\"%s\".\n", configfile); return GA_BAD; } else if (ret == CFG_PARSE_ERROR) { fprintf(stderr, "Error: parse error in the configuration file " "\"%s\".\n", configfile); return GA_BAD; } /* Generic */ app_p->debug = cfg_getint(cfg, "debug"); if (app_p->debug == MAYBE || app_p->debug == OPTIONAL) { printf("Overriding debug setting to 'yes'\n"); app_p->debug = YES; } else if (app_p->debug == YES) { printf("= Service running in DEBUG mode =\n"); } /* XACML Rules file */ *policy_file = strdup(cfg_getstr(cfg, "policyfile")); if (*policy_file == NULL) { fprintf(stderr, "Error: no \"policyfile\" set in the configuration file\n"); return GA_BAD; } else { if (app_p->verbose) { printf("Using XACML Policy file: \"%s\"\n", *policy_file); } } /* Syslog */ syslog_sec = cfg_getsec(cfg, "syslog"); if (syslog_sec == NULL) { fprintf(stderr, "Error: no \"syslog\" section found in the " "configuration file \"%s\"\n", configfile); } else { *syslog_ident = strdup(cfg_getstr(syslog_sec, "ident")); *syslog_facility = cfg_getint(syslog_sec, "facility"); if (app_p->debug == YES) { printf("found syslog\n"); printf(" ident = %s\n", cfg_getstr(syslog_sec, "ident")); printf(" facility = %ld\n", cfg_getint(syslog_sec, "facility")); printf("BUG\n"); for (i = 0; i < cfg_size(syslog_sec, "options"); i++) { printf("options[%d] == %ld\n", i, cfg_getnint(syslog_sec, "options", i)); } printf("BUG\n"); } /* Hardwired the settings */ *syslog_flags = LOG_PID|LOG_NDELAY; if (app_p->verbose > 1) { *syslog_flags |= LOG_PERROR; } } /* Listeners */ n_listener = cfg_size(cfg, "listener"); if (app_p->verbose) { printf("%d configured listeners:\n", n_listener); } for (i = 0; i < n_listener; i++) { cfg_t *ls = cfg_getnsec(cfg, "listener", i); if (ls == NULL) { goto cleanup; } p_listener = malloc(sizeof(struct tq_listener_s)); if (p_listener == NULL) { fprintf(stderr, "Error: memory allocation problem, couldn't allocate %lu bytes\n", sizeof(struct tq_listener_s)); goto cleanup; } memset(p_listener, 0, sizeof(struct tq_listener_s)); TAILQ_INIT(&(p_listener->services_head)); /* Settings */ STRDUP_OR_GOTO_CLEANUP(p_listener->bindip, cfg_getstr(ls, "bindaddress")); p_listener->port = (short)cfg_getint(ls, "port"); p_listener->backlog = (short)cfg_getint(ls, "backlog"); STRDUP_OR_GOTO_CLEANUP(p_listener->cert, cfg_getstr(ls, "cert")); STRDUP_OR_GOTO_CLEANUP(p_listener->key, cfg_getstr(ls, "key")); STRDUP_OR_GOTO_CLEANUP(p_listener->cafile, cfg_getstr(ls, "cafile")); STRDUP_OR_GOTO_CLEANUP(p_listener->capath, cfg_getstr(ls, "capath")); STRDUP_OR_GOTO_CLEANUP(p_listener->crlpath, cfg_getstr(ls, "crlpath")); STRDUP_OR_GOTO_CLEANUP(p_listener->cipherlist, cfg_getstr(ls, "cipherlist") ? cfg_getstr(ls, "cipherlist") : "HIGH"); STRDUP_OR_GOTO_CLEANUP(p_listener->cert_password, cfg_getstr(ls, "password")); STRDUP_OR_GOTO_CLEANUP(p_listener->whitelist_path, cfg_getstr(ls, "whitelist")); STRDUP_OR_GOTO_CLEANUP(p_listener->blacklist_path, cfg_getstr(ls, "blacklist")); p_listener->clientauth = (short)cfg_getint(ls, "clientauth"); p_listener->rfc3820 = (short)cfg_getint(ls, "rfc3820"); /* Normalizer */ if (p_listener->clientauth == MAYBE) p_listener->clientauth = OPTIONAL; if (p_listener->rfc3820 == MAYBE || p_listener->rfc3820 == OPTIONAL) p_listener->rfc3820 = YES; /* Create evhtp_ssl_cfg_t */ if (create_evhtp_ssl_cfg_from_tq_listener(p_listener) == GA_BAD) { goto cleanup; } /* Services per listener */ n_services = cfg_size(ls, "service"); if (app_p->verbose) { printf(" %d\n", n_services); } for (j = 0; j < n_services; j++) { cfg_t *serv = cfg_getnsec(ls, "service", j); if (serv == NULL) { goto cleanup; } p_service = malloc(sizeof(struct tq_service_s)); if (p_service == NULL) { fprintf(stderr, "Error: memory allocation problem, couldn't allocate %lu bytes\n", sizeof(struct tq_service_s)); goto cleanup; } memset(p_service, 0, sizeof(struct tq_service_s)); p_service->parent_listener = p_listener; /* Thread count override in Debug mode - max is 1 worker thread */ if (app_p->debug == YES) { p_service->thread_cnt = 1; } else { p_service->thread_cnt = (short)cfg_getint(serv, "threads"); } p_service->ltype = cfg_getint(serv, "type"); p_service->uri = cfg_getstr(serv, "uri"); if (p_service->uri && p_service->uri[0] == '/') { p_service->uri = strdup(p_service->uri); } else { buf = malloc(strlen(p_service->uri) + 2); if (buf == NULL) { goto cleanup; } snprintf(buf, strlen(p_service->uri) + 2, "/%s", p_service->uri); p_service->uri = buf; } if (app_p->verbose) { printf(" uri = %s\n", p_service->uri); printf(" type = %s\n", p_service->ltype == PDP ? "PDP" : p_service->ltype == PAP ? "PAP" : p_service->ltype == PEP ? "PEP" : "unknown"); } TAILQ_INSERT_TAIL(&(p_listener->services_head), p_service, next); } TAILQ_INSERT_TAIL(&(app_p->listener_head), p_listener, next); } cfg_free(cfg); return GA_GOOD; cleanup: cfg_free(cfg); return GA_BAD; }
/* * read configuration file */ int read_config(struct program_params *pp) { static cfg_opt_t pv_opts[] = { CFG_INT("tier", 0, CFGF_NONE), CFG_FLOAT("pinningScore", 0, CFGF_NONE), CFG_STR("path", NULL, CFGF_NONE), CFG_INT_CB("maxUsedSpace", -1, CFGF_NONE, parse_size_value), CFG_END() }; static cfg_opt_t volume_opts[] = { CFG_STR("LogicalVolume", NULL, CFGF_NONE), CFG_STR("VolumeGroup", NULL, CFGF_NONE), CFG_FLOAT("timeExponent", 1.0/(2<<14), CFGF_NONE), CFG_FLOAT("hitScore", 16, CFGF_NONE), CFG_FLOAT("readMultiplier", 1, CFGF_NONE), CFG_FLOAT("writeMultiplier", 4, CFGF_NONE), CFG_INT_CB("pvmoveWait", 5*60, CFGF_NONE, parse_time_value), CFG_INT_CB("checkWait", 15*60, CFGF_NONE, parse_time_value), CFG_SEC("pv", pv_opts, CFGF_TITLE | CFGF_MULTI), CFG_END() }; cfg_opt_t opts[] = { CFG_SEC("volume", volume_opts, CFGF_TITLE | CFGF_MULTI), CFG_END() }; cfg_t *cfg; cfg = cfg_init(opts, CFGF_NONE); assert(cfg); // add verification functions cfg_set_validate_func(cfg, "volume|timeExponent", validate_require_positive); cfg_set_validate_func(cfg, "volume|hitScore", validate_require_positive); cfg_set_validate_func(cfg, "volume|readMultiplier", validate_require_nonnegative); cfg_set_validate_func(cfg, "volume|writeMultiplier", validate_require_nonnegative); cfg_set_validate_func(cfg, "volume|pv|pinningScore", validate_require_nonnegative); cfg_set_validate_func(cfg, "volume|pv|tier", validate_require_nonnegative); cfg_set_validate_func(cfg, "volume|pv|maxUsedSpace", validate_require_nonnegative); // TODO cfg_set_validate_func(cfg, "volume", validate_pv); // do they belong to volume, is there enough space switch(cfg_parse(cfg, pp->conf_file_path)) { case CFG_FILE_ERROR: fprintf(stderr, "Configuration file \"%s\" could not be read: %s\n", pp->conf_file_path, strerror(errno)); return 1; case CFG_SUCCESS: break; case CFG_PARSE_ERROR: fprintf(stderr, "Configuration file errors, aborting\n"); return 1; default: fprintf(stderr, "Internal error"); assert(0); } pp->cfg = cfg; return 0; }
/** * Parse config file options */ static gboolean parse_config_file(void) { cfg_t *cfg, *sec_as, *sec_mpd; cfg_opt_t mpd_opts[] = { CFG_STR("host", "localhost", CFGF_NONE), CFG_INT("port", 6600, CFGF_NONE), CFG_INT("timeout", 5, CFGF_NONE), CFG_INT("interval", 10, CFGF_NONE), CFG_STR("password", "", CFGF_NONE), CFG_END() }; cfg_opt_t as_opts[] = { CFG_STR("username", "", CFGF_NONE), CFG_STR("password", "", CFGF_NONE), CFG_STR("password_hash", "", CFGF_NONE), CFG_END() }; cfg_opt_t opts[] = { CFG_INT_CB("log_level", G_LOG_LEVEL_ERROR, CFGF_NONE, &cf_log_level), CFG_STR("log_file", "/var/log/scmpc.log", CFGF_NONE), CFG_STR("pid_file", "/var/run/scmpc.pid", CFGF_NONE), CFG_STR("cache_file", "/var/lib/scmpc/scmpc.cache", CFGF_NONE), CFG_INT("queue_length", 500, CFGF_NONE), CFG_INT("cache_interval", 10, CFGF_NONE), CFG_SEC("mpd", mpd_opts, CFGF_NONE), CFG_SEC("audioscrobbler", as_opts, CFGF_NONE), CFG_END() }; cfg = cfg_init(opts, CFGF_NONE); cfg_set_validate_func(cfg, "queue_length", &cf_validate_num); cfg_set_validate_func(cfg, "cache_interval", &cf_validate_num); cfg_set_validate_func(cfg, "mpd|port", &cf_validate_num); cfg_set_validate_func(cfg, "mpd|timeout", &cf_validate_num); if (parse_files(cfg) == FALSE) { cfg_free(cfg); return FALSE; } g_free(prefs.log_file); g_free(prefs.pid_file); g_free(prefs.cache_file); g_free(prefs.mpd_hostname); g_free(prefs.mpd_password); g_free(prefs.as_username); g_free(prefs.as_password); g_free(prefs.as_password_hash); prefs.log_level = cfg_getint(cfg, "log_level"); prefs.log_file = expand_tilde(cfg_getstr(cfg, "log_file")); prefs.pid_file = expand_tilde(cfg_getstr(cfg, "pid_file")); prefs.cache_file = expand_tilde(cfg_getstr(cfg, "cache_file")); prefs.queue_length = cfg_getint(cfg, "queue_length"); prefs.cache_interval = cfg_getint(cfg, "cache_interval"); sec_mpd = cfg_getsec(cfg, "mpd"); prefs.mpd_hostname = g_strdup(cfg_getstr(sec_mpd, "host")); prefs.mpd_port = cfg_getint(sec_mpd, "port"); prefs.mpd_timeout = cfg_getint(sec_mpd, "timeout"); prefs.mpd_password = g_strdup(cfg_getstr(sec_mpd, "password")); sec_as = cfg_getsec(cfg, "audioscrobbler"); prefs.as_username = g_strdup(cfg_getstr(sec_as, "username")); prefs.as_password = g_strdup(cfg_getstr(sec_as, "password")); prefs.as_password_hash = g_strdup(cfg_getstr(sec_as, "password_hash")); prefs.fork = TRUE; cfg_free(cfg); return TRUE; }
CFG_SEC(EDF_SEC_TERDELTA, edf_terdelta_opts, EDF_NSEC_FLAGS), CFG_SEC(EDF_SEC_FLOOR, edf_floor_opts, EDF_NSEC_FLAGS), CFG_SEC(EDF_SEC_MENU, edf_menu_opts, EDF_TSEC_FLAGS), CFG_SEC(EDF_SEC_FONT, edf_font_opts, EDF_TSEC_FLAGS), CFG_SEC(EDF_SEC_STRING, edf_string_opts, EDF_TSEC_FLAGS), CFG_SEC(EDF_SEC_GAMEPROPS, edf_game_opts, EDF_NSEC_FLAGS), CFG_STR(SEC_CASTORDER, 0, CFGF_LIST), CFG_STR(SEC_BOSSTYPES, 0, CFGF_LIST), CFG_INT(SEC_BOSSPROBS, 0, CFGF_LIST), // schepe CFG_SEC(EDF_SEC_FRMDELTA, edf_fdelta_opts, EDF_NSEC_FLAGS), CFG_SEC(EDF_SEC_TNGDELTA, edf_tdelta_opts, EDF_NSEC_FLAGS), CFG_SEC(EDF_SEC_SDELTA, edf_sdelta_opts, EDF_NSEC_FLAGS), CFG_INT(ITEM_D2TITLETICS, 0, CFGF_NONE), CFG_INT(ITEM_INTERPAUSE, 0, CFGF_NONE), CFG_INT(ITEM_INTERFADE, -1, CFGF_NONE), CFG_INT_CB(ITEM_INTERTL, 0, CFGF_NONE, E_TranslucCB), CFG_STR(ITEM_MN_EPISODE, NULL, CFGF_NONE), CFG_STR(ITEM_FONT_HUD, "ee_smallfont", CFGF_NONE), CFG_STR(ITEM_FONT_HUDO, "ee_hudfont", CFGF_NONE), CFG_STR(ITEM_FONT_MENU, "ee_menufont", CFGF_NONE), CFG_STR(ITEM_FONT_BMENU, "ee_bigfont", CFGF_NONE), CFG_STR(ITEM_FONT_NMENU, "ee_smallfont", CFGF_NONE), CFG_STR(ITEM_FONT_FINAL, "ee_finalefont", CFGF_NONE), CFG_STR(ITEM_FONT_INTR, "ee_smallfont", CFGF_NONE), CFG_STR(ITEM_FONT_INTRB, "ee_bigfont", CFGF_NONE), CFG_STR(ITEM_FONT_INTRBN, "ee_bignumfont", CFGF_NONE), CFG_STR(ITEM_FONT_CONS, "ee_consolefont", CFGF_NONE), CFG_FUNC("setdialect", E_SetDialect), CFG_FUNC("include", E_Include), CFG_FUNC("lumpinclude", E_LumpInclude), CFG_FUNC("include_prev", E_IncludePrev), // DEPRECATED
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; }
int main(int argc, char *argv[]) { uint8_t threadid_main = 0; pthread_key_create(&threadid_key, NULL); pthread_setspecific(threadid_key, &threadid_main); mprintf("University of Wisconsin IPMI MicroTCA System Manager\n"); if (argc > 1 && strcmp(argv[1], "--version") == 0) { mprintf("\nCompiled from %s@%s\n", (GIT_BRANCH[0] ? GIT_BRANCH : "git-archive"), (GIT_COMMIT[0] ? GIT_COMMIT : "27868b9b800d107fbb53b68c2fce207144f97a98")); if (strlen(GIT_DIRTY) > 1) mprintf("%s", GIT_DIRTY); mprintf("\n"); return 0; } /* * Parse Configuration */ cfg_opt_t opts_auth[] = { CFG_STR_LIST(const_cast<char *>("raw"), const_cast<char *>("{}"), CFGF_NONE), CFG_STR_LIST(const_cast<char *>("manage"), const_cast<char *>("{}"), CFGF_NONE), CFG_STR_LIST(const_cast<char *>("read"), const_cast<char *>("{}"), CFGF_NONE), CFG_END() }; cfg_opt_t opts_crate[] = { CFG_STR(const_cast<char *>("host"), const_cast<char *>(""), CFGF_NONE), CFG_STR(const_cast<char *>("description"), const_cast<char *>(""), CFGF_NONE), CFG_STR(const_cast<char *>("username"), const_cast<char *>(""), CFGF_NONE), CFG_STR(const_cast<char *>("password"), const_cast<char *>(""), CFGF_NONE), CFG_INT_CB(const_cast<char *>("authtype"), 0, CFGF_NONE, cfg_parse_authtype), CFG_INT_CB(const_cast<char *>("mch"), 0, CFGF_NONE, cfg_parse_MCH), CFG_BOOL(const_cast<char *>("enabled"), cfg_true, CFGF_NONE), CFG_END() }; cfg_opt_t opts_cardmodule[] = { CFG_STR(const_cast<char *>("module"), const_cast<char *>(""), CFGF_NONE), CFG_STR_LIST(const_cast<char *>("config"), const_cast<char *>("{}"), CFGF_NONE), CFG_END() }; cfg_opt_t opts[] = { CFG_SEC(const_cast<char *>("authentication"), opts_auth, CFGF_NONE), CFG_SEC(const_cast<char *>("crate"), opts_crate, CFGF_MULTI), CFG_SEC(const_cast<char *>("cardmodule"), opts_cardmodule, CFGF_MULTI), CFG_INT(const_cast<char *>("socket_port"), 4681, CFGF_NONE), CFG_INT(const_cast<char *>("ratelimit_delay"), 0, CFGF_NONE), CFG_BOOL(const_cast<char *>("daemonize"), cfg_false, CFGF_NONE), CFG_END() }; cfg_t *cfg = cfg_init(opts, CFGF_NONE); cfg_set_validate_func(cfg, "crate|host", &cfg_validate_hostname); cfg_set_validate_func(cfg, "socket_port", &cfg_validate_port); if (argc >= 2 && access(argv[1], R_OK) == 0) { if(cfg_parse(cfg, argv[1]) == CFG_PARSE_ERROR) exit(1); } else if (access(CONFIG_PATH "/" CONFIG_FILE, R_OK) == 0) { if(cfg_parse(cfg, CONFIG_PATH "/" CONFIG_FILE) == CFG_PARSE_ERROR) exit(1); } else { printf("Config file %s not found, and no argument supplied.\n", CONFIG_PATH "/" CONFIG_FILE); printf("Try: %s sysmgr.conf\n", argv[0]); exit(1); } bool crate_found = false; bool crate_enabled = false; cfg_t *cfgauth = cfg_getsec(cfg, "authentication"); for(unsigned int i = 0; i < cfg_size(cfgauth, "raw"); i++) config_authdata.raw.push_back(std::string(cfg_getnstr(cfgauth, "raw", i))); for(unsigned int i = 0; i < cfg_size(cfgauth, "manage"); i++) config_authdata.manage.push_back(std::string(cfg_getnstr(cfgauth, "manage", i))); for(unsigned int i = 0; i < cfg_size(cfgauth, "read"); i++) config_authdata.read.push_back(std::string(cfg_getnstr(cfgauth, "read", i))); for(unsigned int i = 0; i < cfg_size(cfg, "crate"); i++) { cfg_t *cfgcrate = cfg_getnsec(cfg, "crate", i); crate_found = true; enum Crate::Mfgr MCH; switch (cfg_getint(cfgcrate, "mch")) { case Crate::VADATECH: MCH = Crate::VADATECH; break; case Crate::NAT: MCH = Crate::NAT; break; } const char *user = cfg_getstr(cfgcrate, "username"); const char *pass = cfg_getstr(cfgcrate, "password"); Crate *crate = new Crate(i+1, MCH, cfg_getstr(cfgcrate, "host"), (user[0] ? user : NULL), (pass[0] ? pass : NULL), cfg_getint(cfgcrate, "authtype"), cfg_getstr(cfgcrate, "description")); bool enabled = (cfg_getbool(cfgcrate, "enabled") == cfg_true); if (enabled) crate_enabled = true; threadlocal.push_back(threadlocaldata_t(crate, enabled)); } for(unsigned int i = 0; i < cfg_size(cfg, "cardmodule"); i++) { cfg_t *cfgmodule = cfg_getnsec(cfg, "cardmodule", i); const char *module = cfg_getstr(cfgmodule, "module"); std::vector<std::string> configdata; for(unsigned int i = 0; i < cfg_size(cfgmodule, "config"); i++) configdata.push_back(std::string(cfg_getnstr(cfgmodule, "config", i))); std::string default_module_path = DEFAULT_MODULE_PATH; if (getenv("SYSMGR_MODULE_PATH") != NULL) default_module_path = getenv("SYSMGR_MODULE_PATH"); std::string modulepath = module; if (modulepath.find("/") == std::string::npos) modulepath = default_module_path +"/"+ modulepath; cardmodule_t cm; cm.dl_addr = dlopen(modulepath.c_str(), RTLD_NOW|RTLD_GLOBAL); if (cm.dl_addr == NULL) { printf("Error loading module %s:\n\t%s\n", module, dlerror()); exit(2); } void *sym; #define LOAD_SYM(name, type) \ sym = dlsym(cm.dl_addr, #name); \ if (sym == NULL) { \ mprintf("Error loading module %s " type " " #name ":\n\t%s\n", module, dlerror()); \ exit(2); \ } LOAD_SYM(APIVER, "variable"); cm.APIVER = *reinterpret_cast<uint32_t*>(sym); LOAD_SYM(MIN_APIVER, "variable"); cm.MIN_APIVER = *reinterpret_cast<uint32_t*>(sym); if (cm.APIVER < 2 || cm.MIN_APIVER > 2) { mprintf("Error loading module %s: Incompatible API version %u\n", module, cm.APIVER); } LOAD_SYM(initialize_module, "function"); cm.initialize_module = reinterpret_cast<bool (*)(std::vector<std::string>)>(sym); LOAD_SYM(instantiate_card, "function"); cm.instantiate_card = reinterpret_cast<Card* (*)(Crate*, std::string, void*, uint8_t)>(sym); #undef LOAD_SYM if (!cm.initialize_module(configdata)) { printf("Error loading module %s: initialize_module() returned false\n", module); exit(2); } card_modules.insert(card_modules.begin(), cm); } uint16_t port = cfg_getint(cfg, "socket_port"); config_ratelimit_delay = cfg_getint(cfg, "ratelimit_delay"); bool daemonize = (cfg_getbool(cfg, "daemonize") == cfg_true); cfg_free(cfg); if (!crate_found) { printf("No crate specified in the configuration file.\n"); exit(1); } if (!crate_enabled) { printf("No crates are enabled in the configuration file.\n"); printf("No crates to service.\n"); exit(1); } if (daemonize) { do_fork(); stdout_use_syslog = true; mprintf("University of Wisconsin IPMI MicroTCA System Manager\n"); } /* * Initialize library crypto routines before spawning threads. * This connect will fail due to hostname too long, after running the crypt init functions. * * Max Hostname Limit: 64 */ ipmi_ctx_t dummy_ipmi_ctx = ipmi_ctx_create(); if (ipmi_ctx_open_outofband_2_0(dummy_ipmi_ctx, ".................................................................", // hostname NULL, // username NULL, // password NULL, // k_g 0, // k_g_len, 4, // privilege_level 0, // cipher_suite_id 0, // session_timeout 5, // retransmission_timeout IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_OPEN_SESSION_PRIVILEGE, // workaround_flags IPMI_FLAGS_DEFAULT // flags ) == 0) { ipmi_ctx_close(dummy_ipmi_ctx); } ipmi_ctx_destroy(dummy_ipmi_ctx); /* * Instantiate Worker Threads */ for (std::vector<threadlocaldata_t>::iterator it = threadlocal.begin(); it != threadlocal.end(); it++) if (it->enabled) pthread_create(&it->thread, NULL, crate_monitor, (void *)it->crate->get_number()); #ifndef DEBUG_ONESHOT protocol_server(port); #endif for (std::vector<threadlocaldata_t>::iterator it = threadlocal.begin(); it != threadlocal.end(); it++) if (it->enabled) pthread_join(it->thread, NULL); }
int main(int argc, char **argv) { unsigned int i; cfg_t *cfg; unsigned n; int ret; cfg_opt_t proxy_opts[] = { CFG_INT("type", 0, CFGF_NONE), CFG_STR("host", 0, CFGF_NONE), CFG_STR_LIST("exclude", "{localhost, .localnet}", CFGF_NONE), CFG_INT("port", 21, CFGF_NONE), CFG_END() }; cfg_opt_t bookmark_opts[] = { CFG_STR("machine", 0, CFGF_NONE), CFG_INT("port", 21, CFGF_NONE), CFG_STR("login", 0, CFGF_NONE), CFG_STR("password", 0, CFGF_NONE), CFG_STR("directory", 0, CFGF_NONE), CFG_BOOL("passive-mode", cfg_false, CFGF_NONE), CFG_SEC("proxy", proxy_opts, CFGF_NONE), CFG_END() }; cfg_opt_t opts[] = { CFG_INT("backlog", 42, CFGF_NONE), CFG_STR("probe-device", "eth2", CFGF_NONE), CFG_SEC("bookmark", bookmark_opts, CFGF_MULTI | CFGF_TITLE), CFG_FLOAT_LIST("delays", "{3.567e2, 0.2, -47.11}", CFGF_NONE), CFG_FUNC("func", &cb_func), CFG_INT_CB("ask-quit", 3, CFGF_NONE, &cb_verify_ask), CFG_INT_LIST_CB("ask-quit-array", "{maybe, yes, no}", CFGF_NONE, &cb_verify_ask), CFG_FUNC("include", &cfg_include), CFG_END() }; #ifndef _WIN32 /* for some reason, MS Visual C++ chokes on this (?) */ printf("Using %s\n\n", confuse_copyright); #endif cfg = cfg_init(opts, CFGF_NOCASE); /* set a validating callback function for bookmark sections */ cfg_set_validate_func(cfg, "bookmark", &cb_validate_bookmark); ret = cfg_parse(cfg, argc > 1 ? argv[1] : "test.conf"); printf("ret == %d\n", ret); if(ret == CFG_FILE_ERROR) { perror("test.conf"); return 1; } else if(ret == CFG_PARSE_ERROR) { fprintf(stderr, "parse error\n"); return 2; } printf("backlog == %ld\n", cfg_getint(cfg, "backlog")); printf("probe device is %s\n", cfg_getstr(cfg, "probe-device")); cfg_setstr(cfg, "probe-device", "lo"); printf("probe device is %s\n", cfg_getstr(cfg, "probe-device")); n = cfg_size(cfg, "bookmark"); printf("%d configured bookmarks:\n", n); for(i = 0; i < n; i++) { cfg_t *pxy; cfg_t *bm = cfg_getnsec(cfg, "bookmark", i); printf(" bookmark #%u (%s):\n", i+1, cfg_title(bm)); printf(" machine = %s\n", cfg_getstr(bm, "machine")); printf(" port = %d\n", (int)cfg_getint(bm, "port")); printf(" login = %s\n", cfg_getstr(bm, "login")); printf(" passive-mode = %s\n", cfg_getbool(bm, "passive-mode") ? "true" : "false"); printf(" directory = %s\n", cfg_getstr(bm, "directory")); printf(" password = %s\n", cfg_getstr(bm, "password")); pxy = cfg_getsec(bm, "proxy"); if(pxy) { int j, m; if(cfg_getstr(pxy, "host") == 0) { printf(" no proxy host is set, setting it to 'localhost'...\n"); /* For sections without CFGF_MULTI flag set, there is * also an extended syntax to get an option in a * subsection: */ cfg_setstr(bm, "proxy|host", "localhost"); } printf(" proxy host is %s\n", cfg_getstr(pxy, "host")); printf(" proxy type is %ld\n", cfg_getint(pxy, "type")); printf(" proxy port is %ld\n", cfg_getint(pxy, "port")); m = cfg_size(pxy, "exclude"); printf(" got %d hosts to exclude from proxying:\n", m); for(j = 0; j < m; j++) { printf(" exclude %s\n", cfg_getnstr(pxy, "exclude", j)); } } else printf(" no proxy settings configured\n"); } printf("delays are (%d):\n", cfg_size(cfg, "delays")); for(i = 0; i < cfg_size(cfg, "delays"); i++) printf(" %G\n", cfg_getnfloat(cfg, "delays", i)); printf("ask-quit == %ld\n", cfg_getint(cfg, "ask-quit")); /* Using cfg_setint(), the integer value for the option ask-quit * is not verified by the value parsing callback. * * cfg_setint(cfg, "ask-quit", 4); printf("ask-quit == %ld\n", cfg_getint(cfg, "ask-quit")); */ /* The following commented line will generate a failed assertion * and abort, since the option "foo" is not declared * * printf("foo == %ld\n", cfg_getint(cfg, "foo")); */ cfg_addlist(cfg, "ask-quit-array", 2, 1, 2); for(i = 0; i < cfg_size(cfg, "ask-quit-array"); i++) printf("ask-quit-array[%d] == %ld\n", i, cfg_getnint(cfg, "ask-quit-array", i)); /* print the parsed values to another file */ { FILE *fp = fopen("test.conf.out", "w"); cfg_set_print_func(cfg, "func", print_func); cfg_set_print_func(cfg, "ask-quit", print_ask); cfg_set_print_func(cfg, "ask-quit-array", print_ask); cfg_print(cfg, fp); fclose(fp); } cfg_free(cfg); return 0; }