static int module_init(void) { struct sa laddr_udp, laddr_http; struct pl addr; uint32_t port; int err; /* UDP bind address */ if (conf_get(restund_conf(), "status_udp_addr", &addr)) pl_set_str(&addr, "127.0.0.1"); if (conf_get_u32(restund_conf(), "status_udp_port", &port)) port = 33000; err = sa_set(&laddr_udp, &addr, port); if (err) { restund_error("status: bad udp bind address: %r:%u", &addr, port); goto out; } /* HTTP bind address */ if (conf_get(restund_conf(), "status_http_addr", &addr)) pl_set_str(&addr, "127.0.0.1"); if (conf_get_u32(restund_conf(), "status_http_port", &port)) port = 8080; err = sa_set(&laddr_http, &addr, port); if (err) { restund_error("status: bad http bind address: %r:%u", &addr, port); goto out; } err = udp_listen(&stg.us, &laddr_udp, udp_recv, NULL); if (err) { restund_warning("status: udp_listen: %m\n", err); goto out; } err = httpd_alloc(&stg.httpd, &laddr_http, httpd_handler); if (err) { restund_warning("status: httpd: %m\n", err); goto out; } stg.start = time(NULL); restund_debug("status: module loaded (udp=%J http=%J)\n", &laddr_udp, &laddr_http); out: if (err) { stg.us = mem_deref(stg.us); stg.httpd = mem_deref(stg.httpd); } return err; }
/* Copied from resrules.c -- _get_actions */ static void _get_actions_ccs(const char *base, resource_t * res) { char xpath[256]; int idx = 0; char *act, *ret; int interval, timeout, depth; do { /* setting these to -1 prevents overwriting with 0 */ interval = -1; depth = -1; act = NULL; timeout = -1; /* XXX check */ snprintf(xpath, sizeof(xpath), "%s/action[%d]/@name", base, ++idx); if (conf_get(xpath, &act) != 0) break; /* XXX check */ snprintf(xpath, sizeof(xpath), "%s/action[%d]/@timeout", base, idx); if (conf_get(xpath, &ret) == 0 && ret) { timeout = expand_time(ret); if (timeout < 0) timeout = 0; free(ret); } /* XXX check */ snprintf(xpath, sizeof(xpath), "%s/action[%d]/@interval", base, idx); if (conf_get(xpath, &ret) == 0 && ret) { interval = expand_time(ret); if (interval < 0) interval = 0; free(ret); } if (!strcmp(act, "status") || !strcmp(act, "monitor")) { /* XXX check */ snprintf(xpath, sizeof(xpath), "%s/action[%d]/@depth", base, idx); if (conf_get(xpath, &ret) == 0 && ret) { /* XXX check/strtol */ depth = atoi(ret); if (depth < 0) depth = 0; /* XXX originally unfinished comment here (wildcard?) */ if (ret[0] == '*') depth = -1; free(ret); } } if (store_action(&res->r_actions, act, depth, timeout, interval) != 0) free(act); } while (1); }
static int module_init(void) { int err = 0; #ifdef MODULE_CONF struct pl pl; if (!conf_get(conf_cur(), "opus_application", &pl)) { if (!pl_strcasecmp(&pl, "voip")) opus.app = OPUS_APPLICATION_VOIP; else if (!pl_strcasecmp(&pl, "audio")) opus.app = OPUS_APPLICATION_AUDIO; else { DEBUG_WARNING("unknown application: %r\n", &pl); } } if (!conf_get(conf_cur(), "opus_bandwidth", &pl)) { if (!pl_strcasecmp(&pl, "narrowband")) opus.bandwidth = OPUS_BANDWIDTH_NARROWBAND; else if (!pl_strcasecmp(&pl, "mediumband")) opus.bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; else if (!pl_strcasecmp(&pl, "wideband")) opus.bandwidth = OPUS_BANDWIDTH_WIDEBAND; else if (!pl_strcasecmp(&pl, "superwideband")) opus.bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; else if (!pl_strcasecmp(&pl, "fullband")) opus.bandwidth = OPUS_BANDWIDTH_FULLBAND; else { DEBUG_WARNING("unknown bandwidth: %r\n", &pl); } } conf_get_u32(conf_cur(), "opus_complexity", &opus.complex); conf_get_u32(conf_cur(), "opus_bitrate", &opus.bitrate); conf_get_bool(conf_cur(), "opus_vbr", &opus.vbr); #endif err |= aucodec_register(&codecv[0], NULL, "opus", 48000, 2, NULL, alloc, encode, decode, NULL); err |= aucodec_register(&codecv[1], NULL, "opus", 48000, 1, NULL, alloc, encode, decode, NULL); #if 0 err |= aucodec_register(&codecv[2], NULL, "opus", 32000, 1, NULL, alloc, encode, decode, NULL); #endif return err; }
// Returns: Whether connection is successful AND if tables are already present int lpg_init(struct logger_t* logger) { // TODO: We assume that the database has been correctly set up struct configuration_t* c = logger->config; lg_psql.hostaddr = conf_get(c, "logging", "host"); lg_psql.port = conf_get(c, "logging", "port"); lg_psql.dbname = conf_get(c, "logging", "dbname"); lg_psql.user = conf_get(c, "logging", "dbuser"); lg_psql.pw = conf_get(c, "logging", "dbuser"); return 1; }
/*! \brief Event loop listening for signals and remote commands. */ static void event_loop(server_t *server) { uint8_t buf[KNOT_WIRE_MAX_PKTSIZE]; size_t buflen = sizeof(buf); /* Read control socket configuration. */ conf_val_t listen_val = conf_get(conf(), C_CTL, C_LISTEN); conf_val_t rundir_val = conf_get(conf(), C_SRV, C_RUNDIR); char *rundir = conf_abs_path(&rundir_val, NULL); struct sockaddr_storage addr = conf_addr(&listen_val, rundir); free(rundir); /* Bind to control interface (error logging is inside the function. */ int remote = remote_bind(&addr); sigset_t empty; (void)sigemptyset(&empty); /* Run event loop. */ for (;;) { int ret = remote_poll(remote, &empty); /* Events. */ if (ret > 0) { ret = remote_process(server, &addr, remote, buf, buflen); if (ret == KNOT_CTL_STOP) { break; } } /* Interrupts. */ if (sig_req_stop) { break; } if (sig_req_reload) { sig_req_reload = false; server_reload(server, conf()->filename); } } server_stop(server); /* Close remote control interface. */ remote_unbind(&addr, remote); /* Wait for server to finish. */ server_wait(server); }
static void reload_handler(struct mbuf *mb) { bool dbg = force_debug; struct conf *lconf; struct pl opt; int err; (void)mb; err = conf_alloc(&lconf, configfile); if (err) { restund_error("error loading configuration: %s: %m\n", configfile, err); return; } conf = mem_deref(conf); conf = lconf; if (!conf_get(conf, "debug", &opt) && !pl_strcasecmp(&opt, "yes")) dbg = true; restund_log_enable_debug(dbg); restund_info("configuration reloaded from %s (debug%s)\n", configfile, dbg ? " enabled" : " disabled"); }
int conf_get_vidsz(const struct conf *conf, const char *name, struct vidsz *sz) { struct pl r, w, h; int err; err = conf_get(conf, name, &r); if (err) return err; w.l = h.l = 0; err = re_regex(r.p, r.l, "[0-9]+x[0-9]+", &w, &h); if (err) return err; if (pl_isset(&w) && pl_isset(&h)) { sz->w = pl_u32(&w); sz->h = pl_u32(&h); } /* check resolution */ if (sz->w & 0x1 || sz->h & 0x1) { warning("conf: %s: should be multiple of 2 (%u x %u)\n", name, sz->w, sz->h); return EINVAL; } return 0; }
static int conf_get_vidfmt(const struct conf *conf, const char *name, int *fmtp) { struct pl pl; int fmt; int err; err = conf_get(conf, name, &pl); if (err) return err; for (fmt=0; fmt<VID_FMT_N; fmt++) { const char *str = vidfmt_name(fmt); if (0 == pl_strcasecmp(&pl, str)) { *fmtp = fmt; return 0; } } warning("config: %s: pixel format not supported (%r)\n", name, &pl); return ENOENT; }
int module_init(const struct conf *conf) { struct pl path; int err; if (!conf) return EINVAL; if (conf_get(conf, "module_path", &path)) pl_set_str(&path, "."); err = conf_apply(conf, "module", module_handler, &path); if (err) return err; err = conf_apply(conf, "module_tmp", module_tmp_handler, &path); if (err) return err; err = conf_apply(conf, "module_app", module_app_handler, &path); if (err) return err; return 0; }
static int module_init(void) { struct pl pl; int err; if (0 == conf_get(conf_cur(), "pcp_server", &pl)) { err = sa_decode(&pcp_srv, pl.p, pl.l); if (err) return err; } else { err = net_default_gateway_get(net_af(baresip_network()), &pcp_srv); if (err) return err; sa_set_port(&pcp_srv, PCP_PORT_SRV); } info("pcp: using PCP server at %J\n", &pcp_srv); #if 1 /* todo: if multiple applications are listening on port 5350 then this will not work */ err = pcp_listen(&lsnr, &pcp_srv, pcp_msg_handler, 0); if (err) { info("pcp: could not enable listener: %m\n", err); err = 0; } #endif return mnat_register(&mnat, "pcp", NULL, session_alloc, media_alloc, NULL); }
static void do_conf() { char c = 0; char line[64]; int args, id, num, gain, min, max; struct chan *channel; gets(line); args = sscanf(line, "%c %u %u %i %i", &c, &num, &gain, &min, &max); if (args > 0) { id = CHANNEL_ID(c); if (id >= CHANNELS) NOK(); else if (args == 1) { channel = conf_get(id); printf("%c %u %u %i %i\n", c, channel->num, channel->gain, channel->min, channel->max); } else { int tmp; input_stop(); channel = conf_get(id); tmp = channel->gain; channel->num = limit(num, 0, AD_CHANNELS); if (args >= 3) { channel->gain = limit(gain, AD_GAIN_MIN, AD_GAIN_MAX); if (tmp != channel->gain) input_calibrate(id); } if (args == 4) { max = limit(min, 0, AD_VMAX); min = limit(-min, AD_VMIN, 0); channel->min = min; channel->max = max; } else if (args >= 5) { channel->min = limit(min, AD_VMIN, AD_VMAX); channel->max = limit(max, channel->min, AD_VMAX); } printf("ok %c %u %u %i %i\n", c, channel->num, channel->gain, channel->min, channel->max); input_start(); } } else NOK(); }
gboolean server_start(conf_t *conf) { struct sigaction sa; /* Handle signals. * SIGUSR1 is sent when the X server is ready. */ sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sa.sa_handler = server_callback; sigaction(SIGUSR1,&sa,NULL); /* TODO: fix cmd */ char *cmd[] = { "Xnest", conf_get(conf,"display"), NULL, NULL, NULL }; if (strcmp(conf_get(conf, "authentication"), "none") != 0) { cmd[2] = "-auth"; cmd[3] = conf_get(conf,"auth_file"); } GError *error = NULL; gboolean spawn_successful = g_spawn_async( NULL, cmd, NULL, G_SPAWN_SEARCH_PATH, child_setup, NULL, &server_pid, &error); if (!spawn_successful) { g_warning("Spawn X failed: %s\n", error->message); return FALSE; } if (!server_startup(SERVER_TIMEOUT)) { g_warning("Could not start X, server timed out."); return FALSE; } return TRUE; }
static int dnsproxy_fwd(int state, knot_pkt_t *pkt, struct query_data *qdata, void *ctx) { if (pkt == NULL || qdata == NULL || ctx == NULL) { return KNOT_STATE_FAIL; } /* If not already satisfied. */ if (state == KNOT_STATE_DONE) { return state; } struct dnsproxy *proxy = ctx; /* Create a forwarding request. */ struct knot_requestor re; knot_requestor_init(&re, qdata->mm); struct capture_param param; param.sink = pkt; int ret = knot_requestor_overlay(&re, LAYER_CAPTURE, ¶m); if (ret != KNOT_EOK) { return KNOT_STATE_FAIL; } bool is_tcp = net_is_connected(qdata->param->socket); struct knot_request *req; req = knot_request_make(re.mm, (const struct sockaddr *)&proxy->remote, NULL, qdata->query, is_tcp ? 0 : KNOT_RQ_UDP); if (req == NULL) { return state; /* Ignore, not enough memory. */ } /* Forward request. */ ret = knot_requestor_enqueue(&re, req); if (ret == KNOT_EOK) { conf_val_t val = conf_get(conf(), C_SRV, C_TCP_HSHAKE_TIMEOUT); struct timeval tv = { conf_int(&val), 0 }; ret = knot_requestor_exec(&re, &tv); } else { knot_request_free(re.mm, req); } knot_requestor_clear(&re); /* Check result. */ if (ret != KNOT_EOK) { qdata->rcode = KNOT_RCODE_SERVFAIL; return KNOT_STATE_FAIL; /* Forwarding failed, SERVFAIL. */ } return KNOT_STATE_DONE; }
int logger_create(struct configuration_t* config) { if (global_logger) { msg(MSG_ERROR, "Logging module has already been created!"); return -1; } global_logger = (struct logger_t*)malloc(sizeof(struct logger_t)); global_logger->config = config; // check with logger to instantiate const char* logger = conf_get(config, "logging", "type"); if (!logger) { msg(MSG_FATAL, "No logger type given in configuration file!"); return -1; } if (!strcmp(logger, "truman")) { global_logger->init = lt_init; global_logger->deinit = lt_deinit; global_logger->create_log = lt_create_log; global_logger->finish_log = lt_finish_log; global_logger->log = lt_log_text; global_logger->log_struct = lt_log_struct; } else if (!strcmp(logger, "sqlite")) { global_logger->init = lsq_init; global_logger->deinit = lsq_deinit; global_logger->create_log = lsq_create_log; global_logger->finish_log = lsq_finish_log; global_logger->log = lsq_log_text; global_logger->log_struct = lsq_log_struct; } else if (!strcmp(logger,"postgresql")) { global_logger->init = lpg_init; global_logger->deinit = lpg_deinit; global_logger->create_log = lpg_create_log; global_logger->finish_log = lpg_finish_log; global_logger->log = lpg_log_text; global_logger->log_struct = lpg_log_struct; } else { msg(MSG_FATAL, "Unknown subsystem defined in configuration. Maybe even undefined!"); free(global_logger); global_logger= NULL; return -1; } return global_logger->init(global_logger); }
static int module_init(void) { struct pl pl; if (conf_get(conf_cur(), "video_selfview", &pl)) return 0; if (0 == pl_strcasecmp(&pl, "window")) vidfilt_register(&selfview_win); else if (0 == pl_strcasecmp(&pl, "pip")) vidfilt_register(&selfview_pip); return 0; }
int conf_get_sa(const struct conf *conf, const char *name, struct sa *sa) { struct pl opt; int err; if (!conf || !name || !sa) return EINVAL; err = conf_get(conf, name, &opt); if (err) return err; return sa_decode(sa, opt.p, opt.l); }
static int module_init(void) { struct pl pl = PL("pip"); (void)conf_get(conf_cur(), "video_selfview", &pl); if (0 == pl_strcasecmp(&pl, "window")) vidfilt_register(&selfview_win); else if (0 == pl_strcasecmp(&pl, "pip")) vidfilt_register(&selfview_pip); (void)conf_get_vidsz(conf_cur(), "selfview_size", &selfview_size); return 0; }
/** * Get the value of a configuration item string * * @param conf Configuration object * @param name Name of config item key * @param str Value of config item, if present * @param size Size of string to store value * * @return 0 if success, otherwise errorcode */ int conf_get_str(const struct conf *conf, const char *name, char *str, size_t size) { struct pl pl; int err; if (!conf || !name || !str || !size) return EINVAL; err = conf_get(conf, name, &pl); if (err) return err; return pl_strcpy(&pl, str, size); }
/************************************************************************************************** DB_CONNECT Connect to the database. **************************************************************************************************/ void db_connect(void) { const char *user = conf_get(&Conf, "db-user", NULL); const char *host = conf_get(&Conf, "db-host", NULL); const char *database = conf_get(&Conf, "database", NULL); const char *password = conf_get(&Conf, "db-password", NULL); /* If db- vars aren't present, try mysql- for backwards compatibility */ if (!user) user = conf_get(&Conf, "mysql-user", NULL); if (!host) host = conf_get(&Conf, "mysql-host", NULL); if (!password) password = conf_get(&Conf, "mysql-password", NULL); if (!password) password = conf_get(&Conf, "mysql-pass", NULL); sql_open(user, password, host, database); Verbose(_("connected to %s, database \"%s\""), host, database); }
/** * Get the numeric value of a configuration item * * @param conf Configuration object * @param name Name of config item key * @param num Returned numeric value of config item, if present * * @return 0 if success, otherwise errorcode */ int conf_get_u32(const struct conf *conf, const char *name, uint32_t *num) { struct pl pl; int err; if (!conf || !name || !num) return EINVAL; err = conf_get(conf, name, &pl); if (err) return err; *num = pl_u32(&pl); return 0; }
/************************************************************************************************** CONF_SET_LOGGING Sets the logging type and opens the syslog connection if necessary. **************************************************************************************************/ void conf_set_logging(void) { char *logtype; /* logtype is preset to LOG_DAEMON unless overridden */ logtype = STRDUP(conf_get(&Conf, "log", NULL)); strtolower(logtype); if (err_file) { if (err_file != stderr && err_file != stdout) fclose(err_file); err_file = NULL; } else { closelog(); } if (!strcasecmp(logtype, "stderr")) { err_file = stderr; closelog(); } else if (!strcasecmp(logtype, "stdout")) { err_file = stdout; closelog(); } else if (!strcasecmp(logtype, "log_daemon")) error_init(NULL, LOG_DAEMON); else if (!strcasecmp(logtype, "log_local0")) error_init(NULL, LOG_LOCAL0); else if (!strcasecmp(logtype, "log_local1")) error_init(NULL, LOG_LOCAL1); else if (!strcasecmp(logtype, "log_local2")) error_init(NULL, LOG_LOCAL2); else if (!strcasecmp(logtype, "log_local3")) error_init(NULL, LOG_LOCAL3); else if (!strcasecmp(logtype, "log_local4")) error_init(NULL, LOG_LOCAL4); else if (!strcasecmp(logtype, "log_local5")) error_init(NULL, LOG_LOCAL5); else if (!strcasecmp(logtype, "log_local6")) error_init(NULL, LOG_LOCAL6); else if (!strcasecmp(logtype, "log_local7")) error_init(NULL, LOG_LOCAL7); else { FILE *fp; if (!(fp = fopen(logtype, "a"))) Warn("%s: %s: %s", opt_conf, logtype, _("Error opening log file")); err_file = fp; closelog(); } RELEASE(logtype); }
/** @brief AutoBuilder Entry Point @param argc Number of arguments passed through argv @param argv String representation of arguments passed to the application @return EXIT_SUCCESS on success or a non-zero integer on failure. **/ int main (int argc, char ** argv) { conf_t conf; conf_err_t cerr; opt_t opt; opt_err_t oerr; const char *db_type, *db_host, *db_port, *db_user, *db_pass, *db_db; /* Parse the command line */ oerr = opt_init(&opt, argc, argv, 1); if (oerr != OPT_OK) { fprintf (stderr, "%s\n", SHORT_HELP); opt_destroy (&opt); return EXIT_FAILURE; } if (opt.help) { fprintf (stderr, "%s\n", HELP_TXT); return EXIT_SUCCESS; } /* Parse the configuration */ cerr = conf_init (&conf, opt.conf); if (cerr != CONF_OK) { fprintf (stderr, "Configuration Error: %s", conf_get_err (&conf)); conf_destroy (&conf); opt_destroy (&opt); return EXIT_FAILURE; } /* Read Database Options */ db_type = conf_get (&conf, "DB_TYPE"); db_host = conf_get (&conf, "DB_HOST"); db_port = conf_get (&conf, "DB_PORT"); db_user = conf_get (&conf, "DB_USER"); db_pass = conf_get (&conf, "DB_PASS"); db_db = conf_get (&conf, "DB_DB"); /* Connect to the database */ //db_connect (db_type, db_host, db_port, db_user, db_pass, db_db); /* Cleanup */ conf_destroy (&conf); opt_destroy (&opt); return EXIT_SUCCESS; }
/** * Load a module by name or by filename * * @param name Module name incl/excl extension, excluding module path * * @return 0 if success, otherwise errorcode * * example: "foo" * example: "foo.so" */ int module_load(const char *name) { char filename[256]; struct pl path, pl_name; int err; if (!str_isset(name)) return EINVAL; append_extension(filename, sizeof(filename), name); pl_set_str(&pl_name, filename); if (conf_get(conf_cur(), "module_path", &path)) pl_set_str(&path, "."); err = load_module(NULL, &path, &pl_name); return err; }
int conf_get_csv(const struct conf *conf, const char *name, char *str1, size_t sz1, char *str2, size_t sz2) { struct pl r, pl1, pl2 = pl_null; int err; err = conf_get(conf, name, &r); if (err) return err; /* note: second value may be quoted */ err = re_regex(r.p, r.l, "[^,]+,[~]*", &pl1, &pl2); if (err) return err; (void)pl_strcpy(&pl1, str1, sz1); if (pl_isset(&pl2)) (void)pl_strcpy(&pl2, str2, sz2); return 0; }
static int conf_get_aufmt(const struct conf *conf, const char *name, int *fmtp) { struct pl pl; int fmt; int err; err = conf_get(conf, name, &pl); if (err) return err; fmt = resolve_aufmt(&pl); if (fmt == -1) { warning("config: %s: sample format not supported" " (%r)\n", name, &pl); return EINVAL; } *fmtp = fmt; return 0; }
// returns: 1 if creation was successful, 0 if not int lpg_create_log(struct logger_t* logger) { const char* testmode = conf_get(logger->config, "logging", "testmode"); if (strcmp(testmode,"0") == 0) { char update_trumanbox_runtime_id[1000] = "update trumanbox_settings set value = value+1 where key = 'CURRENT_SAMPLE'"; if (!execute_statement(update_trumanbox_runtime_id)) return 0; //char set_current_id[1000] = "update trumanbox_settings set value = (select t.value from trumanbox_settings t where t.key = 'SAMPLE_COUNTER') where key = 'CURRENT_SAMPLE'"; //if (!execute_statement(set_current_id)) // return 0; char new_malware_dataset[1000] = "insert into malwaresamples (id,beginlogging) values ((select t.value from trumanbox_settings t where t.key = 'CURRENT_SAMPLE'), (select current_timestamp))"; if (!execute_statement(new_malware_dataset)) return 0; } else { char set_current_id[1000] = "update trumanbox_settings set value = -1 where key = 'CURRENT_SAMPLE'"; if(!execute_statement(set_current_id)) return 0; } return 1; // by default, all tables are already created }
void conf_merge(conf_t *to, conf_t *from) { GError *error = NULL; gsize length; gchar **keys; gchar *key; int i = 0; keys = g_key_file_get_keys(from,"enter",&length,&error); if (keys) { while (i<length) { key = keys[i++]; gchar *value = conf_get(from,key); conf_set(to,key,value); } g_strfreev(keys); } if (error) { g_error_free(error); } }
/** * Get the boolean value of a configuration item * * @param conf Configuration object * @param name Name of config item key * @param val Returned boolean value of config item, if present * * @return 0 if success, otherwise errorcode */ int conf_get_bool(const struct conf *conf, const char *name, bool *val) { struct pl pl; int err; if (!conf || !name || !val) return EINVAL; err = conf_get(conf, name, &pl); if (err) return err; if (!pl_strcasecmp(&pl, "true")) *val = true; else if (!pl_strcasecmp(&pl, "yes")) *val = true; else if (!pl_strcasecmp(&pl, "1")) *val = true; else *val = false; return 0; }
int read_conf(_list *list) { FILE *fp = NULL; _conf_item *conf_item = NULL; char conf_line[LINE_SIZE] = {'\0'}; fp = fopen(CONFIGPATH, "r"); if(fp == NULL){ printf("open failed\n the errno number is %d\n", errno); } while(fgets(conf_line, LINE_SIZE, fp)){ conf_item = (_conf_item *)malloc(sizeof(_conf_item)); memset(conf_item, 0x00, sizeof(_conf_item)); conf_get(conf_line, conf_item); if(list->head == NULL){ list->head = conf_item; list->tail = conf_item; }else{ list->tail->next = conf_item; list->tail = conf_item; } } return 0; }
int conf_get_range(const struct conf *conf, const char *name, struct range *rng) { struct pl r, min, max; uint32_t v; int err; err = conf_get(conf, name, &r); if (err) return err; err = re_regex(r.p, r.l, "[0-9]+-[0-9]+", &min, &max); if (err) { /* fallback to non-range numeric value */ err = conf_get_u32(conf, name, &v); if (err) { warning("conf: %s: could not parse range: (%r)\n", name, &r); return err; } rng->min = rng->max = v; return err; } rng->min = pl_u32(&min); rng->max = pl_u32(&max); if (rng->min > rng->max) { warning("conf: %s: invalid range (%u - %u)\n", name, rng->min, rng->max); return EINVAL; } return 0; }