int main(int argc, char **argv) { init_app(argc, argv, "osd"); event_init(); char *hdd_cfg = cfg_getstr("HDD_CONF_FILENAME", "etc/hdd.conf"); hdd_init(hdd_cfg); char *self_host = cfg_getstr("OSD2CLIENT_LISTEN_HOST", "*"); int self_port = cfg_getint32("OSD2CLIENT_LISTEN_PORT", 9527); rpc_client_setup(self_host, self_port, MACHINE_OSD); struct evhttp *httpd; char *listen_host = cfg_getstr("OSD2CLIENT_LISTEN_HOST", "*"); int port = cfg_getint32("OSD2CLIENT_LISTEN_PORT", 9527); httpd = evhttp_start(listen_host, port); if (httpd == NULL) { logging(LOG_ERROR, "start server error %m"); exit(1); } else { printf("Start osd at %s:%d\n", listen_host, port); } evhttp_set_cb(httpd, "/shutdown", shutdown_handler, NULL); evhttp_set_gencb(httpd, gen_handler, NULL); struct timeval five_seconds = {2,0}; struct event *update_clustermap_event= event_new(NULL, -1, EV_PERSIST, update_clustermap_from_cmgr_on_timer_cb, NULL); event_add(update_clustermap_event, &five_seconds); event_dispatch(); evhttp_free(httpd); return 0; }
static void drop_privs(void) { struct passwd *uentry = NULL; struct group *gentry = NULL; char *gid = cfg_getstr(cfg, "gid"); char *uid = cfg_getstr(cfg, "uid"); if (gid) gentry = getgrnam(gid); if (uid) uentry = getpwnam(uid); if (gentry) if (setgid(gentry->gr_gid) < 0) quit("Unable to set group id %d: %s\n", gentry->gr_gid, strerror(errno)); if (uentry) if (setuid(uentry->pw_uid) < 0) quit("Unable to set user id %d: %s\n", uentry->pw_uid, strerror(errno)); }
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 get_device_tier(struct program_params *pp, const char *lv_name, const char *dev) { cfg_t *tmp = cfg_gettsec(pp->cfg, "volume", lv_name); assert(tmp); cfg_t *pv_cfg; for (size_t i=0; i < cfg_size(tmp, "pv"); i++) { pv_cfg = cfg_getnsec(tmp, "pv", i); if (!strcmp(cfg_getstr(pv_cfg, "path"), dev)) return cfg_getint(pv_cfg, "tier"); } return -1; }
// // Process DECORATE-format states // static void E_processDecorateWepStatesRecursive(cfg_t *weaponsec, int wnum, bool recursive) { cfg_t *displaced; // 01/02/12: Process displaced sections recursively first. if((displaced = cfg_displaced(weaponsec))) E_processDecorateWepStatesRecursive(displaced, wnum, true); // haleyjd 06/22/10: Process DECORATE state block if(cfg_size(weaponsec, ITEM_WPN_STATES) > 0) { // 01/01/12: allow use of pre-existing reserved states; they must be // defined consecutively in EDF and should be flagged +decorate in order // for values inside them to be overridden by the DECORATE state block. // If this isn't being done, firststate will be null. const char *firststate = cfg_getstr(weaponsec, ITEM_WPN_FIRSTDECSTATE); const char *tempstr = cfg_getstr(weaponsec, ITEM_WPN_STATES); // recursion should process states only if firststate is valid if(!recursive || firststate) E_processDecorateWepStateList(weaponinfo[wnum], tempstr, firststate, recursive); } }
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""; }
const char * get_tier_device(struct program_params *pp, const char *lv_name, int tier) { cfg_t *tmp = cfg_gettsec(pp->cfg, "volume", lv_name); assert(tmp); cfg_t *pv_cfg; for (size_t i=0; i < cfg_size(tmp, "pv"); i++) { pv_cfg = cfg_getnsec(tmp, "pv", i); if (cfg_getint(pv_cfg, "tier") == tier) return cfg_getstr(pv_cfg, "path"); } return NULL; }
void masterconn_parselabels(void) { char *labelsstr,*p,c; labelsstr = cfg_getstr("LABELS",""); labelmask = 0; for (p=labelsstr ; *p ; p++) { c = *p; if (c>='A' && c<='Z') { labelmask |= (1 << (c-'A')); } else if (c>='a' && c<='z') { labelmask |= (1 << (c-'a')); } } free(labelsstr); }
static void write_pidfile(void) { char *pidfile = cfg_getstr(cfg, "pidfile"); FILE *pf; if (!pidfile) return; pf = fopen(pidfile, "w"); if (pf == NULL) quit("Can't open pidfile %s: %s\n", pidfile, strerror(errno)); fprintf(pf, "%i\n", getpid()); if (fclose(pf) < 0) quit("Can't close pidfile %s: %s\n", pidfile, strerror(errno)); }
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; }
/* vcd.hostinfo() */ xmlrpc_value *m_vcd_hostinfo(xmlrpc_env *env, xmlrpc_value *p, void *c) { LOG_TRACEME xmlrpc_value *response = NULL; method_init(env, p, c, VCD_CAP_INFO, 0); method_return_if_fault(env); response = xmlrpc_build_value(env, "{s:s,s:i,s:i}", "vbasedir", cfg_getstr(cfg, "vbasedir"), "cpus", sysconf(_SC_NPROCESSORS_ONLN), "memnodes", max_mem_node()+1); /* Make both cpus and memnodes here an absolute * value, not including 0, for consistency */ return response; }
int state_init() { int whethermaster = cfg_getuint32("MASTER_STATE", 1); g_virtual_ip = cfg_getstr("VIRTUAL_IP", ""); int havevip = checkvirtualip(); if( ( whethermaster && !havevip ) || ( !whethermaster && havevip ) ) { MFSLOG(LOG_ERR, "state : %d and havevip :%d conflict vip:%s\n", whethermaster, havevip, g_virtual_ip); return -1; } whethermaster ? set_state(MFS_STATE_MASTER) : set_state(MFS_STATE_SLAVE); main_timeregister(TIMEMODE_RUNALL, 2, 0, state_refresh); return 0; }
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); } }
static int testconfig(const char *buf, const char *parameter) { cfg_t *cfg = cfg_init(opts, CFGF_NONE); if (!cfg) return 0; if (cfg_parse_buf(cfg, buf) != CFG_SUCCESS) return 0; char *param = cfg_getstr(cfg, "parameter"); if (!param) return 0; if (strcmp(param, parameter) != 0) return 0; cfg_free(cfg); return 1; }
model_access_list * get_model_access_list(const char * filename){ int i; cfg_opt_t * opts = get_opt(); cfg_t *cfg; cfg = cfg_init(opts, CFGF_NONE); cfg_parse(cfg, filename); model_access_list * ma_list = (model_access_list*)malloc(sizeof(model_access_list)); char *path, *model_list_item, *query_list_item, *model_label; path = cfg_getstr(cfg,"model_list_path"); ma_list->path = (char *)malloc(sizeof(char)*strlen(path)); strcpy(ma_list->path,path); for(i=0;i< cfg_size(cfg,"model_list");i++){ model_list_item = cfg_getnstr(cfg,"model_list",i); ma_list->model_access_info[i].model_filename =(char*)malloc(sizeof(char)*strlen(model_list_item)); strcpy(ma_list->model_access_info[i].model_filename,model_list_item); model_label = cfg_getnstr(cfg,"model_label_list",i); ma_list->model_access_info[i].model_label =(char*)malloc(sizeof(char)*strlen(model_label)); strcpy(ma_list->model_access_info[i].model_label,model_label); query_list_item=cfg_getnstr(cfg,"query_list",i); ma_list->model_access_info[i].query =(char*)malloc(sizeof(char)*strlen(query_list_item)); strcpy(ma_list->model_access_info[i].query,query_list_item); } ma_list->size=i; free(cfg); return ma_list; }
int parse_family(char *filename, family_ent_t * family) { cfg_t *pcfg; memset(family, 0, sizeof(family_ent_t)); pcfg = cfg_init(family_opts, CFGF_NONE); if (cfg_parse(pcfg, filename) == CFG_PARSE_ERROR) return -1; strcpy(family->name, cfg_getstr(pcfg, "name")); family->fam_id = cfg_getint(pcfg, "fam_id"); family->fam_type = cfg_getint(pcfg, "fam_type"); family->search_prio = cfg_getint(pcfg, "search_prio"); family->prg_entry_script = get_script_by_name(cfg_getstr(pcfg, "prg_entry_script")); family->prg_exit_script = get_script_by_name(cfg_getstr(pcfg, "prg_exit_script")); family->rd_devid_script = get_script_by_name(cfg_getstr(pcfg, "rd_devid_script")); /* family->devid_mask = cfg_getint(pcfg, "devid_mask"); */ /* family->blank_value = cfg_getint(pcfg, "blank_value"); */ family->devid_mask = strtoul(cfg_getstr(pcfg, "devid_mask"), NULL, 16); family->blank_value = strtoul(cfg_getstr(pcfg, "blank_value"), NULL, 16); family->bytes_per_loc = cfg_getint(pcfg, "bytes_per_loc"); family->addr_inc = cfg_getint(pcfg, "addr_inc"); family->b_detect = cfg_getint(pcfg, "b_detect"); family->prg_entry_vpp_script = get_script_by_name(cfg_getstr(pcfg, "prg_entry_vpp_script")); family->ee_bytes_per_word = cfg_getint(pcfg, "ee_bytes_per_word"); family->ee_addr_inc = cfg_getint(pcfg, "ee_addr_inc"); family->user_id_hex_bytes = cfg_getint(pcfg, "user_id_hex_bytes"); family->user_id_bytes = cfg_getint(pcfg, "user_id_bytes"); family->prog_mem_hex_bytes = cfg_getint(pcfg, "prog_mem_hex_bytes"); family->ee_mem_hex_bytes = cfg_getint(pcfg, "ee_mem_hex_bytes"); family->prg_mem_shift = cfg_getint(pcfg, "prg_mem_shift"); family->test_memory_start = cfg_getint(pcfg, "test_memory_start"); family->test_memory_length = cfg_getint(pcfg, "test_memory_length"); family->vpp = cfg_getfloat(pcfg, "vpp"); cfg_free(pcfg); 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; } }
void src_init(cfg_t *source_cfg) { char *stream = cfg_getstr(source_cfg, "stream"); if (!stream) return; crcInit(); if (!strncmp("udp://", stream, 6)) { double chunk_duration = cfg_getfloat(source_cfg,"chunk_duration"); info("Initializing SOURCE mode: tuning to stream %s, sampling rate is " "%.2lf Hz", stream, (double)1.0/chunk_duration); init_source_ul(stream, chunk_duration); } else if (!strncmp("http://", stream, 7)) { char addr[128]; int port,i; if (sscanf(stream, "http://%127[^:]:%i", addr, &port) != 2) fatal("Unable to parse source specification %s", stream); if (ulChunkReceiverSetup(addr, port)) fatal("Unable to start the HTTP receiver to http://%s:%d", addr, port); } else fatal("Unable to parse stream specification %s", stream); napaSchedulePeriodic(NULL, 1/60.0, periodicPublishSrcLag, NULL); }
void topology_reload(void) { int fd; if (TopologyFileName) { free(TopologyFileName); } if (!cfg_isdefined("TOPOLOGY_FILENAME")) { TopologyFileName = strdup(ETC_PATH "/mfs/mfstopology.cfg"); passert(TopologyFileName); if ((fd = open(TopologyFileName,O_RDONLY))<0 && errno==ENOENT) { free(TopologyFileName); TopologyFileName = strdup(ETC_PATH "/mfstopology.cfg"); if ((fd = open(TopologyFileName,O_RDONLY))>=0) { mfs_syslog(LOG_WARNING,"default sysconf path has changed - please move mfstopology.cfg from "ETC_PATH"/ to "ETC_PATH"/mfs/"); } } if (fd>=0) { close(fd); } } else { TopologyFileName = cfg_getstr("TOPOLOGY_FILENAME",ETC_PATH "/mfs/mfstopology.cfg"); } topology_load(); }
static PyObject* build_params_dict(cfg_t *pymodule) { int k; PyObject *params_dict = PyDict_New(); if (pymodule && params_dict) { for (k = 0; k < cfg_size(pymodule, "param"); k++) { cfg_t *param; char *name, *value; PyObject *pyvalue; param = cfg_getnsec(pymodule, "param", k); name = apr_pstrdup(pool, param->title); value = apr_pstrdup(pool, cfg_getstr(param, "value")); pyvalue = PyString_FromString(value); if (name && pyvalue) { PyDict_SetItemString(params_dict, name, pyvalue); Py_DECREF(pyvalue); } } } return params_dict; }
std::wstring Settings::getStringSetting(Node type, int intNodeId, const std::wstring &name, bool parameter) const { // already locked if (d->cfg == 0) { return L""; } std::string strType = getNodeString(type); cfg_t *cfg_device; for (int i = 0; i < cfg_size(d->cfg, strType.c_str()); ++i) { cfg_device = cfg_getnsec(d->cfg, strType.c_str(), i); if (cfg_getint(cfg_device, "id") == intNodeId) { if (parameter) { cfg_device = cfg_getsec(cfg_device, "parameters"); } std::wstring setting; char *cSetting = cfg_getstr(cfg_device, TelldusCore::wideToString(name).c_str()); if (cSetting) { setting = TelldusCore::charToWstring(cSetting); } return setting; } } return L""; }
static rproxy_cfg_t * rproxy_cfg_parse_(cfg_t * cfg) { rproxy_cfg_t * rpcfg; int i; assert(cfg != NULL); rpcfg = rproxy_cfg_new(); assert(rpcfg != NULL); if (cfg_getstr(cfg, "user")) { rpcfg->user = strdup(cfg_getstr(cfg, "user")); } if (cfg_getstr(cfg, "group")) { rpcfg->group = strdup(cfg_getstr(cfg, "group")); } if (cfg_getstr(cfg, "rootdir")) { rpcfg->rootdir = strdup(cfg_getstr(cfg, "rootdir")); } rpcfg->max_nofile = cfg_getint(cfg, "max-nofile"); rpcfg->daemonize = cfg_getbool(cfg, "daemonize"); for (i = 0; i < cfg_size(cfg, "server"); i++) { lztq_elem * elem; server_cfg_t * scfg; scfg = server_cfg_parse(cfg_getnsec(cfg, "server", i)); assert(scfg != NULL); scfg->rproxy_cfg = rpcfg; elem = lztq_append(rpcfg->servers, scfg, sizeof(scfg), server_cfg_free); assert(elem != NULL); } /* set our rusage settings from the global one */ memcpy(&rpcfg->rusage, &_rusage, sizeof(rproxy_rusage_t)); return rpcfg; } /* rproxy_cfg_parse_ */
int conffile_load(char *file) { cfg_t *lib; struct passwd *pw; char *runas; int ret; cfg = cfg_init(toplvl_cfg, CFGF_NONE); ret = cfg_parse(cfg, file); if (ret == CFG_FILE_ERROR) { DPRINTF(E_FATAL, L_CONF, "Could not open config file %s\n", file); goto out_fail; } else if (ret == CFG_PARSE_ERROR) { DPRINTF(E_FATAL, L_CONF, "Parse error in config file %s\n", file); goto out_fail; } /* Resolve runas username */ runas = cfg_getstr(cfg_getsec(cfg, "general"), "uid"); pw = getpwnam(runas); if (!pw) { DPRINTF(E_FATAL, L_CONF, "Could not lookup user %s: %s\n", runas, strerror(errno)); goto out_fail; } runas_uid = pw->pw_uid; runas_gid = pw->pw_gid; lib = cfg_getsec(cfg, "library"); if (cfg_size(lib, "directories") == 0) { DPRINTF(E_FATAL, L_CONF, "No directories specified for library\n"); goto out_fail; } /* Do keyword expansion on library names */ ret = conffile_expand_libname(lib); if (ret != 0) { DPRINTF(E_FATAL, L_CONF, "Could not expand library name\n"); goto out_fail; } return 0; out_fail: cfg_free(cfg); return -1; }
static int conffile_expand_libname(cfg_t *lib) { char *libname; char *hostname; char *s; char *d; char *expanded; struct utsname sysinfo; size_t len; size_t olen; size_t hostlen; size_t verlen; int ret; libname = cfg_getstr(lib, "name"); olen = strlen(libname); /* Fast path */ s = strchr(libname, '%'); if (!s) { libhash = murmur_hash64(libname, olen, 0); return 0; } /* Grab what we need */ ret = uname(&sysinfo); if (ret != 0) { DPRINTF(E_WARN, L_CONF, "Could not get system name: %s\n", strerror(errno)); hostname = "Unknown host"; } else hostname = sysinfo.nodename; hostlen = strlen(hostname); verlen = strlen(VERSION); /* Compute expanded size */ len = olen; s = libname; while (*s) { if (*s == '%') { s++; switch (*s) { case 'h': len += hostlen; break; case 'v': len += verlen; break; } } s++; } expanded = (char *)malloc(len + 1); if (!expanded) { DPRINTF(E_FATAL, L_CONF, "Out of memory\n"); return -1; } memset(expanded, 0, len + 1); /* Do the actual expansion */ s = libname; d = expanded; while (*s) { if (*s == '%') { s++; switch (*s) { case 'h': strcat(d, hostname); d += hostlen; break; case 'v': strcat(d, VERSION); d += verlen; break; } s++; } else { *d = *s; s++; d++; } } cfg_setstr(lib, "name", expanded); libhash = murmur_hash64(expanded, strlen(expanded), 0); free(expanded); return 0; }
int main(int argc, char **argv) { int option; char *configfile; int background; int mdns_no_rsp; int mdns_no_daap; int loglevel; char *logdomains; char *logfile; char *ffid; char *pidfile; const char *gcry_version; sigset_t sigs; int sigfd; #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) struct kevent ke_sigs[4]; #endif int ret; struct option option_map[] = { { "ffid", 1, NULL, 'b' }, { "debug", 1, NULL, 'd' }, { "logdomains", 1, NULL, 'D' }, { "foreground", 0, NULL, 'f' }, { "config", 1, NULL, 'c' }, { "pidfile", 1, NULL, 'P' }, { "version", 0, NULL, 'v' }, { "mdns-no-rsp", 0, NULL, 512 }, { "mdns-no-daap", 0, NULL, 513 }, { NULL, 0, NULL, 0 } }; configfile = CONFFILE; pidfile = PIDFILE; loglevel = -1; logdomains = NULL; logfile = NULL; background = 1; ffid = NULL; mdns_no_rsp = 0; mdns_no_daap = 0; while ((option = getopt_long(argc, argv, "D:d:c:P:fb:v", option_map, NULL)) != -1) { switch (option) { case 512: mdns_no_rsp = 1; break; case 513: mdns_no_daap = 1; break; case 'b': ffid = optarg; break; case 'd': ret = safe_atoi32(optarg, &option); if (ret < 0) fprintf(stderr, "Error: loglevel must be an integer in '-d %s'\n", optarg); else loglevel = option; break; case 'D': logdomains = optarg; break; case 'f': background = 0; break; case 'c': configfile = optarg; break; case 'P': pidfile = optarg; break; case 'v': version(); return EXIT_SUCCESS; break; default: usage(argv[0]); return EXIT_FAILURE; break; } } ret = logger_init(NULL, NULL, (loglevel < 0) ? E_LOG : loglevel); if (ret != 0) { fprintf(stderr, "Could not initialize log facility\n"); return EXIT_FAILURE; } ret = conffile_load(configfile); if (ret != 0) { DPRINTF(E_FATAL, L_MAIN, "Config file errors; please fix your config\n"); logger_deinit(); return EXIT_FAILURE; } logger_deinit(); /* Reinit log facility with configfile values */ if (loglevel < 0) loglevel = cfg_getint(cfg_getsec(cfg, "general"), "loglevel"); logfile = cfg_getstr(cfg_getsec(cfg, "general"), "logfile"); ret = logger_init(logfile, logdomains, loglevel); if (ret != 0) { fprintf(stderr, "Could not reinitialize log facility with config file settings\n"); conffile_unload(); return EXIT_FAILURE; } /* Set up libevent logging callback */ event_set_log_callback(logger_libevent); DPRINTF(E_LOG, L_MAIN, "Forked Media Server Version %s taking off\n", VERSION); ret = av_lockmgr_register(ffmpeg_lockmgr); if (ret < 0) { DPRINTF(E_FATAL, L_MAIN, "Could not register ffmpeg lock manager callback\n"); ret = EXIT_FAILURE; goto ffmpeg_init_fail; } av_register_all(); #if LIBAVFORMAT_VERSION_MAJOR >= 54 || (LIBAVFORMAT_VERSION_MAJOR == 53 && LIBAVFORMAT_VERSION_MINOR >= 13) avformat_network_init(); #endif av_log_set_callback(logger_ffmpeg); #ifdef LASTFM /* Initialize libcurl */ curl_global_init(CURL_GLOBAL_DEFAULT); #endif /* Initialize libgcrypt */ gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); gcry_version = gcry_check_version(GCRYPT_VERSION); if (!gcry_version) { DPRINTF(E_FATAL, L_MAIN, "libgcrypt version mismatch\n"); ret = EXIT_FAILURE; goto gcrypt_init_fail; } /* We aren't handling anything sensitive, so give up on secure * memory, which is a scarce system resource. */ gcry_control(GCRYCTL_DISABLE_SECMEM, 0); gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); DPRINTF(E_DBG, L_MAIN, "Initialized with gcrypt %s\n", gcry_version); /* Block signals for all threads except the main one */ sigemptyset(&sigs); sigaddset(&sigs, SIGINT); sigaddset(&sigs, SIGHUP); sigaddset(&sigs, SIGCHLD); sigaddset(&sigs, SIGTERM); sigaddset(&sigs, SIGPIPE); ret = pthread_sigmask(SIG_BLOCK, &sigs, NULL); if (ret != 0) { DPRINTF(E_LOG, L_MAIN, "Error setting signal set\n"); ret = EXIT_FAILURE; goto signal_block_fail; } /* Daemonize and drop privileges */ ret = daemonize(background, pidfile); if (ret < 0) { DPRINTF(E_LOG, L_MAIN, "Could not initialize server\n"); ret = EXIT_FAILURE; goto daemon_fail; } /* Initialize libevent (after forking) */ evbase_main = event_init(); DPRINTF(E_LOG, L_MAIN, "mDNS init\n"); ret = mdns_init(); if (ret != 0) { DPRINTF(E_FATAL, L_MAIN, "mDNS init failed\n"); ret = EXIT_FAILURE; goto mdns_fail; } /* Initialize the database before starting */ DPRINTF(E_INFO, L_MAIN, "Initializing database\n"); ret = db_init(); if (ret < 0) { DPRINTF(E_FATAL, L_MAIN, "Database init failed\n"); ret = EXIT_FAILURE; goto db_fail; } /* Open a DB connection for the main thread */ ret = db_perthread_init(); if (ret < 0) { DPRINTF(E_FATAL, L_MAIN, "Could not perform perthread DB init for main\n"); ret = EXIT_FAILURE; goto db_fail; } /* Spawn worker thread */ ret = worker_init(); if (ret != 0) { DPRINTF(E_FATAL, L_MAIN, "Worker thread failed to start\n"); ret = EXIT_FAILURE; goto worker_fail; } /* Spawn cache thread */ ret = cache_init(); if (ret != 0) { DPRINTF(E_FATAL, L_MAIN, "Cache thread failed to start\n"); ret = EXIT_FAILURE; goto cache_fail; } /* Spawn file scanner thread */ ret = filescanner_init(); if (ret != 0) { DPRINTF(E_FATAL, L_MAIN, "File scanner thread failed to start\n"); ret = EXIT_FAILURE; goto filescanner_fail; } #ifdef HAVE_SPOTIFY_H /* Spawn Spotify thread */ ret = spotify_init(); if (ret < 0) { DPRINTF(E_INFO, L_MAIN, "Spotify thread not started\n");; } #endif /* Spawn player thread */ ret = player_init(); if (ret != 0) { DPRINTF(E_FATAL, L_MAIN, "Player thread failed to start\n"); ret = EXIT_FAILURE; goto player_fail; } /* Spawn HTTPd thread */ ret = httpd_init(); if (ret != 0) { DPRINTF(E_FATAL, L_MAIN, "HTTPd thread failed to start\n"); ret = EXIT_FAILURE; goto httpd_fail; } #ifdef MPD /* Spawn MPD thread */ ret = mpd_init(); if (ret != 0) { DPRINTF(E_FATAL, L_MAIN, "MPD thread failed to start\n"); ret = EXIT_FAILURE; goto mpd_fail; } #endif /* Start Remote pairing service */ ret = remote_pairing_init(); if (ret != 0) { DPRINTF(E_FATAL, L_MAIN, "Remote pairing service failed to start\n"); ret = EXIT_FAILURE; goto remote_fail; } /* Register mDNS services */ ret = register_services(ffid, mdns_no_rsp, mdns_no_daap); if (ret < 0) { ret = EXIT_FAILURE; goto mdns_reg_fail; } #if defined(__linux__) /* Set up signal fd */ sigfd = signalfd(-1, &sigs, SFD_NONBLOCK | SFD_CLOEXEC); if (sigfd < 0) { DPRINTF(E_FATAL, L_MAIN, "Could not setup signalfd: %s\n", strerror(errno)); ret = EXIT_FAILURE; goto signalfd_fail; } event_set(&sig_event, sigfd, EV_READ, signal_signalfd_cb, NULL); #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) sigfd = kqueue(); if (sigfd < 0) { DPRINTF(E_FATAL, L_MAIN, "Could not setup kqueue: %s\n", strerror(errno)); ret = EXIT_FAILURE; goto signalfd_fail; } EV_SET(&ke_sigs[0], SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); EV_SET(&ke_sigs[1], SIGTERM, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); EV_SET(&ke_sigs[2], SIGHUP, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); EV_SET(&ke_sigs[3], SIGCHLD, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); ret = kevent(sigfd, ke_sigs, 4, NULL, 0, NULL); if (ret < 0) { DPRINTF(E_FATAL, L_MAIN, "Could not register signal events: %s\n", strerror(errno)); ret = EXIT_FAILURE; goto signalfd_fail; } event_set(&sig_event, sigfd, EV_READ, signal_kqueue_cb, NULL); #endif event_base_set(evbase_main, &sig_event); event_add(&sig_event, NULL); /* Run the loop */ event_base_dispatch(evbase_main); DPRINTF(E_LOG, L_MAIN, "Stopping gracefully\n"); ret = EXIT_SUCCESS; /* * On a clean shutdown, bring mDNS down first to give a chance * to the clients to perform a clean shutdown on their end */ DPRINTF(E_LOG, L_MAIN, "mDNS deinit\n"); mdns_deinit(); signalfd_fail: mdns_reg_fail: DPRINTF(E_LOG, L_MAIN, "Remote pairing deinit\n"); remote_pairing_deinit(); remote_fail: DPRINTF(E_LOG, L_MAIN, "HTTPd deinit\n"); httpd_deinit(); httpd_fail: DPRINTF(E_LOG, L_MAIN, "TCPd deinit\n"); #ifdef MPD DPRINTF(E_LOG, L_MAIN, "MPD deinit\n"); mpd_deinit(); mpd_fail: #endif DPRINTF(E_LOG, L_MAIN, "Player deinit\n"); player_deinit(); player_fail: #ifdef HAVE_SPOTIFY_H DPRINTF(E_LOG, L_MAIN, "Spotify deinit\n"); spotify_deinit(); #endif DPRINTF(E_LOG, L_MAIN, "File scanner deinit\n"); filescanner_deinit(); filescanner_fail: DPRINTF(E_LOG, L_MAIN, "Cache deinit\n"); cache_deinit(); cache_fail: DPRINTF(E_LOG, L_MAIN, "Worker deinit\n"); worker_deinit(); worker_fail: DPRINTF(E_LOG, L_MAIN, "Database deinit\n"); db_perthread_deinit(); db_deinit(); db_fail: if (ret == EXIT_FAILURE) { DPRINTF(E_LOG, L_MAIN, "mDNS deinit\n"); mdns_deinit(); } mdns_fail: daemon_fail: if (background) { ret = seteuid(0); if (ret < 0) DPRINTF(E_LOG, L_MAIN, "seteuid() failed: %s\n", strerror(errno)); else { ret = unlink(pidfile); if (ret < 0) DPRINTF(E_LOG, L_MAIN, "Could not unlink PID file %s: %s\n", pidfile, strerror(errno)); } } signal_block_fail: gcrypt_init_fail: #ifdef LASTFM curl_global_cleanup(); #endif #if LIBAVFORMAT_VERSION_MAJOR >= 54 || (LIBAVFORMAT_VERSION_MAJOR == 53 && LIBAVFORMAT_VERSION_MINOR >= 13) avformat_network_deinit(); #endif av_lockmgr_register(NULL); ffmpeg_init_fail: DPRINTF(E_LOG, L_MAIN, "Exiting.\n"); conffile_unload(); logger_deinit(); return ret; }
static int register_services(char *ffid, int no_rsp, int no_daap) { cfg_t *lib; char *libname; char *password; char *txtrecord[10]; char records[9][128]; int port; uint32_t hash; int i; int ret; srand((unsigned int)time(NULL)); lib = cfg_getsec(cfg, "library"); libname = cfg_getstr(lib, "name"); hash = djb_hash(libname, strlen(libname)); for (i = 0; i < (sizeof(records) / sizeof(records[0])); i++) { memset(records[i], 0, 128); txtrecord[i] = records[i]; } txtrecord[9] = NULL; snprintf(txtrecord[0], 128, "txtvers=1"); snprintf(txtrecord[1], 128, "Database ID=%0X", hash); snprintf(txtrecord[2], 128, "Machine ID=%0X", hash); snprintf(txtrecord[3], 128, "Machine Name=%s", libname); snprintf(txtrecord[4], 128, "mtd-version=%s", VERSION); snprintf(txtrecord[5], 128, "iTSh Version=131073"); /* iTunes 6.0.4 */ snprintf(txtrecord[6], 128, "Version=196610"); /* iTunes 6.0.4 */ password = cfg_getstr(lib, "password"); snprintf(txtrecord[7], 128, "Password=%s", (password) ? "true" : "false"); if (ffid) snprintf(txtrecord[8], 128, "ffid=%s", ffid); else snprintf(txtrecord[8], 128, "ffid=%08x", rand()); DPRINTF(E_INFO, L_MAIN, "Registering rendezvous names\n"); port = cfg_getint(lib, "port"); /* Register web server service - disabled since we have no web interface */ /* ret = mdns_register(libname, "_http._tcp", port, txtrecord); if (ret < 0) return ret; */ /* Register RSP service */ if (!no_rsp) { ret = mdns_register(libname, "_rsp._tcp", port, txtrecord); if (ret < 0) return ret; } /* Register DAAP service */ if (!no_daap) { ret = mdns_register(libname, "_daap._tcp", port, txtrecord); if (ret < 0) return ret; } for (i = 0; i < (sizeof(records) / sizeof(records[0])); i++) { memset(records[i], 0, 128); } snprintf(txtrecord[0], 128, "txtvers=1"); snprintf(txtrecord[1], 128, "DbId=%016" PRIX64, libhash); snprintf(txtrecord[2], 128, "DvTy=iTunes"); snprintf(txtrecord[3], 128, "DvSv=2306"); /* Magic number! Yay! */ snprintf(txtrecord[4], 128, "Ver=131073"); /* iTunes 6.0.4 */ snprintf(txtrecord[5], 128, "OSsi=0x1F5"); /* Magic number! Yay! */ snprintf(txtrecord[6], 128, "CtlN=%s", libname); /* Terminator */ txtrecord[7] = NULL; /* The group name for the touch-able service advertising is a 64bit hash * but is different from the DbId in iTunes. For now we'll use a hash of * the library name for both, and we'll change that if needed. */ /* Use as scratch space for the hash */ snprintf(records[7], 128, "%016" PRIX64, libhash); /* Register touch-able service, for Remote.app */ ret = mdns_register(records[7], "_touch-able._tcp", port, txtrecord); if (ret < 0) return ret; return 0; }
static int daemonize(int background, char *pidfile) { FILE *fp; pid_t childpid; pid_t pid_ret; int fd; int ret; char *runas; if (background) { fp = fopen(pidfile, "w"); if (!fp) { DPRINTF(E_LOG, L_MAIN, "Error opening pidfile (%s): %s\n", pidfile, strerror(errno)); return -1; } fd = open("/dev/null", O_RDWR, 0); if (fd < 0) { DPRINTF(E_LOG, L_MAIN, "Error opening /dev/null: %s\n", strerror(errno)); fclose(fp); return -1; } signal(SIGTTOU, SIG_IGN); signal(SIGTTIN, SIG_IGN); signal(SIGTSTP, SIG_IGN); childpid = fork(); if (childpid > 0) exit(EXIT_SUCCESS); else if (childpid < 0) { DPRINTF(E_FATAL, L_MAIN, "Fork failed: %s\n", strerror(errno)); close(fd); fclose(fp); return -1; } pid_ret = setsid(); if (pid_ret == (pid_t) -1) { DPRINTF(E_FATAL, L_MAIN, "setsid() failed: %s\n", strerror(errno)); close(fd); fclose(fp); return -1; } logger_detach(); dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); if (fd > 2) close(fd); ret = chdir("/"); if (ret < 0) DPRINTF(E_WARN, L_MAIN, "chdir() failed: %s\n", strerror(errno)); umask(0); fprintf(fp, "%d\n", getpid()); fclose(fp); DPRINTF(E_DBG, L_MAIN, "PID: %d\n", getpid()); } if (geteuid() == (uid_t) 0) { runas = cfg_getstr(cfg_getsec(cfg, "general"), "uid"); ret = initgroups(runas, runas_gid); if (ret != 0) { DPRINTF(E_FATAL, L_MAIN, "initgroups() failed: %s\n", strerror(errno)); return -1; } ret = setegid(runas_gid); if (ret != 0) { DPRINTF(E_FATAL, L_MAIN, "setegid() failed: %s\n", strerror(errno)); return -1; } ret = seteuid(runas_uid); if (ret != 0) { DPRINTF(E_FATAL, L_MAIN, "seteuid() failed: %s\n", strerror(errno)); return -1; } } return 0; }
/* Thread: httpd */ static void serve_file(struct evhttp_request *req, char *uri) { const char *host; char *ext; char path[PATH_MAX]; char *deref; char *ctype; char *passwd; struct evbuffer *evbuf; struct evkeyvalq *headers; struct stat sb; int fd; int i; int ret; /* Check authentication */ passwd = cfg_getstr(cfg_getsec(cfg, "general"), "admin_password"); if (passwd) { DPRINTF(E_DBG, L_HTTPD, "Checking web interface authentication\n"); ret = httpd_basic_auth(req, "admin", passwd, PACKAGE " web interface"); if (ret != 0) return; DPRINTF(E_DBG, L_HTTPD, "Authentication successful\n"); } else { host = evhttp_request_get_host(req); if ((strcmp(host, "::1") != 0) && (strcmp(host, "127.0.0.1") != 0)) { DPRINTF(E_LOG, L_HTTPD, "Remote web interface request denied; no password set\n"); evhttp_send_error(req, 403, "Forbidden"); return; } } ret = snprintf(path, sizeof(path), "%s%s", WEBFACE_ROOT, uri + 1); /* skip starting '/' */ if ((ret < 0) || (ret >= sizeof(path))) { DPRINTF(E_LOG, L_HTTPD, "Request exceeds PATH_MAX: %s\n", uri); evhttp_send_error(req, HTTP_NOTFOUND, "Not Found"); return; } ret = lstat(path, &sb); if (ret < 0) { DPRINTF(E_LOG, L_HTTPD, "Could not lstat() %s: %s\n", path, strerror(errno)); evhttp_send_error(req, HTTP_NOTFOUND, "Not Found"); return; } if (S_ISDIR(sb.st_mode)) { redirect_to_index(req, uri); return; } else if (S_ISLNK(sb.st_mode)) { deref = m_realpath(path); if (!deref) { DPRINTF(E_LOG, L_HTTPD, "Could not dereference %s: %s\n", path, strerror(errno)); evhttp_send_error(req, HTTP_NOTFOUND, "Not Found"); return; } if (strlen(deref) + 1 > PATH_MAX) { DPRINTF(E_LOG, L_HTTPD, "Dereferenced path exceeds PATH_MAX: %s\n", path); evhttp_send_error(req, HTTP_NOTFOUND, "Not Found"); free(deref); return; } strcpy(path, deref); free(deref); ret = stat(path, &sb); if (ret < 0) { DPRINTF(E_LOG, L_HTTPD, "Could not stat() %s: %s\n", path, strerror(errno)); evhttp_send_error(req, HTTP_NOTFOUND, "Not Found"); return; } if (S_ISDIR(sb.st_mode)) { redirect_to_index(req, uri); return; } } if (path_is_legal(path) != 0) { evhttp_send_error(req, 403, "Forbidden"); return; } evbuf = evbuffer_new(); if (!evbuf) { DPRINTF(E_LOG, L_HTTPD, "Could not create evbuffer\n"); evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal error"); return; } fd = open(path, O_RDONLY); if (fd < 0) { DPRINTF(E_LOG, L_HTTPD, "Could not open %s: %s\n", path, strerror(errno)); evhttp_send_error(req, HTTP_NOTFOUND, "Not Found"); return; } /* FIXME: this is broken, if we ever need to serve files here, * this must be fixed. */ ret = evbuffer_read(evbuf, fd, sb.st_size); close(fd); if (ret < 0) { DPRINTF(E_LOG, L_HTTPD, "Could not read file into evbuffer\n"); evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal error"); return; } ctype = "application/octet-stream"; ext = strrchr(path, '.'); if (ext) { for (i = 0; ext2ctype[i].ext; i++) { if (strcmp(ext, ext2ctype[i].ext) == 0) { ctype = ext2ctype[i].ctype; break; } } } headers = evhttp_request_get_output_headers(req); evhttp_add_header(headers, "Content-Type", ctype); evhttp_send_reply(req, HTTP_OK, "OK", evbuf); evbuffer_free(evbuf); }
int handle_lispd_config_file() { cfg_t *cfg = 0; unsigned int i = 0; unsigned n = 0; int ret = 0; static cfg_opt_t map_server_opts[] = { CFG_STR("address", 0, CFGF_NONE), CFG_INT("key-type", 0, CFGF_NONE), CFG_STR("key", 0, CFGF_NONE), CFG_BOOL("proxy-reply", cfg_false, CFGF_NONE), CFG_BOOL("verify", cfg_false, CFGF_NONE), CFG_END() }; static cfg_opt_t db_mapping_opts[] = { CFG_STR("eid-prefix", 0, CFGF_NONE), CFG_INT("iid", -1, CFGF_NONE), CFG_STR("interface", 0, CFGF_NONE), CFG_INT("priority_v4", 0, CFGF_NONE), CFG_INT("weight_v4", 0, CFGF_NONE), CFG_INT("priority_v6", 0, CFGF_NONE), CFG_INT("weight_v6", 0, CFGF_NONE), CFG_END() }; static cfg_opt_t mc_mapping_opts[] = { CFG_STR("eid-prefix", 0, CFGF_NONE), CFG_INT("iid", 0, CFGF_NONE), CFG_STR("rloc", 0, CFGF_NONE), CFG_INT("priority", 0, CFGF_NONE), CFG_INT("weight", 0, CFGF_NONE), CFG_END() }; static cfg_opt_t petr_mapping_opts[] = { CFG_STR("address", 0, CFGF_NONE), CFG_INT("priority", 255, CFGF_NONE), CFG_INT("weight", 0, CFGF_NONE), CFG_END() }; cfg_opt_t opts[] = { CFG_SEC("database-mapping", db_mapping_opts, CFGF_MULTI), CFG_SEC("static-map-cache", mc_mapping_opts, CFGF_MULTI), CFG_SEC("map-server", map_server_opts, CFGF_MULTI), CFG_SEC("proxy-etr", petr_mapping_opts, CFGF_MULTI), CFG_INT("map-request-retries", 0, CFGF_NONE), CFG_INT("control-port", 0, CFGF_NONE), CFG_BOOL("debug", cfg_false, CFGF_NONE), CFG_STR("map-resolver", 0, CFGF_NONE), CFG_STR_LIST("proxy-itrs", 0, CFGF_NONE), CFG_END() }; /* * parse config_file */ cfg = cfg_init(opts, CFGF_NOCASE); ret = cfg_parse(cfg, config_file); if (ret == CFG_FILE_ERROR) { syslog(LOG_DAEMON, "Couldn't find config file %s, exiting...", config_file); exit(EXIT_FAILURE); } else if(ret == CFG_PARSE_ERROR) { syslog(LOG_DAEMON, "NOTE: Version 0.2.4 changed the format of the 'proxy-etr' element."); syslog(LOG_DAEMON, " Check the 'lispd.conf.example' file for an example entry in"); syslog(LOG_DAEMON, " the new format."); syslog(LOG_DAEMON, "Parse error in file %s, exiting...", config_file); exit(EXIT_FAILURE); } /* * lispd config options */ ret = cfg_getint(cfg, "map-request-retries"); if (ret != 0) map_request_retries = ret; cfg_getbool(cfg, "debug") ? (debug = 1) : (debug = 0); /* * LISP config options */ /* * handle map-resolver config */ map_resolver = cfg_getstr(cfg, "map-resolver"); if (!add_server(map_resolver, &map_resolvers)) return(0); #ifdef DEBUG syslog(LOG_DAEMON, "Added %s to map-resolver list", map_resolver); #endif /* * handle proxy-etr config */ n = cfg_size(cfg, "proxy-etr"); for(i = 0; i < n; i++) { cfg_t *petr = cfg_getnsec(cfg, "proxy-etr", i); if (!add_proxy_etr_entry(petr, &proxy_etrs)) { syslog(LOG_DAEMON, "Can't add proxy-etr %d (%s)", i, cfg_getstr(petr, "address")); } } if (!proxy_etrs){ syslog(LOG_DAEMON, "WARNING: No Proxy-ETR defined. Packets to non-LISP destinations will be forwarded natively (no LISP encapsulation). This may prevent mobility in some scenarios."); sleep(3); } /* * handle proxy-itr config */ n = cfg_size(cfg, "proxy-itrs"); for(i = 0; i < n; i++) { if ((proxy_itr = cfg_getnstr(cfg, "proxy-itrs", i)) != NULL) { if (!add_server(proxy_itr, &proxy_itrs)) continue; #ifdef DEBUG syslog(LOG_DAEMON, "Added %s to proxy-itr list", proxy_itr); #endif } } /* * handle database-mapping config */ n = cfg_size(cfg, "database-mapping"); for(i = 0; i < n; i++) { cfg_t *dm = cfg_getnsec(cfg, "database-mapping", i); if (!add_database_mapping(dm)) { syslog(LOG_DAEMON, "Can't add database-mapping %d (%s->%s)", i, cfg_getstr(dm, "eid-prefix"), cfg_getstr(dm, "interface")); } } /* * handle map-server config */ n = cfg_size(cfg, "map-server"); for(i = 0; i < n; i++) { cfg_t *ms = cfg_getnsec(cfg, "map-server", i); if (!add_map_server(cfg_getstr(ms, "address"), cfg_getint(ms, "key-type"), cfg_getstr(ms, "key"), (cfg_getbool(ms, "proxy-reply") ? 1:0), (cfg_getbool(ms, "verify") ? 1:0))) return(0); #ifdef DEBUG syslog(LOG_DAEMON, "Added %s to map-server list", cfg_getstr(ms, "address")); #endif } /* * handle static-map-cache config */ n = cfg_size(cfg, "static-map-cache"); for(i = 0; i < n; i++) { cfg_t *smc = cfg_getnsec(cfg, "static-map-cache", i); if (!add_static_map_cache_entry(smc)) { syslog(LOG_DAEMON,"Can't add static-map-cache %d (EID:%s -> RLOC:%s)", i, cfg_getstr(smc, "eid-prefix"), cfg_getstr(smc, "rloc")); } } #if (DEBUG > 3) dump_tree(AF_INET,AF4_database); dump_tree(AF_INET6,AF6_database); dump_database(); dump_map_servers(); dump_servers(map_resolvers, "map-resolvers"); dump_servers(proxy_etrs, "proxy-etrs"); dump_servers(proxy_itrs, "proxy-itrs"); dump_map_cache(); #endif cfg_free(cfg); return(0); }
int parse_device(char *filename, device_ent_t * device) { cfg_t *pcfg; int i; memset(device, 0, sizeof(device_ent_t)); pcfg = cfg_init(device_opts, CFGF_NONE); if (cfg_parse(pcfg, filename) == CFG_PARSE_ERROR) return -1; strcpy(device->part_name, cfg_getstr(pcfg, "part_name")); device->family = get_family_by_name(cfg_getstr(pcfg, "family")); device->device_id = strtoul(cfg_getstr(pcfg, "device_id"), NULL, 16); device->program_mem = cfg_getint(pcfg, "program_mem"); device->ee_mem = cfg_getint(pcfg, "ee_mem"); device->ee_addr = cfg_getint(pcfg, "ee_addr"); device->config_words = cfg_getint(pcfg, "config_words"); device->config_addr = cfg_getint(pcfg, "config_addr"); device->user_id_words = cfg_getint(pcfg, "user_id_words"); device->user_id_addr = cfg_getint(pcfg, "user_id_addr"); device->bandgap_mask = cfg_getint(pcfg, "bandgap_mask"); if (cfg_size(pcfg, "config_masks") != 8) printf("WARNING : size of \"config_masks\" array is wrong! (%d)\n", cfg_size(pcfg, "config_masks")); for (i = 0; i < 8; i++) device->config_masks[i] = (uint16_t) cfg_getnint(pcfg, "config_masks", i); if (cfg_size(pcfg, "config_blank") != 8) printf("WARNING : size of \"config_blank\" array is wrong!\n"); for (i = 0; i < 8; i++) device->config_blank[i] = (uint16_t) cfg_getnint(pcfg, "config_blank", i); device->cp_mask = cfg_getint(pcfg, "cp_mask"); device->cp_config = cfg_getint(pcfg, "cp_config"); device->osscal_save = cfg_getint(pcfg, "osscal_save"); device->ignore_address = cfg_getint(pcfg, "ignore_address"); device->vdd_min = cfg_getfloat(pcfg, "vdd_min"); device->vdd_max = cfg_getfloat(pcfg, "vdd_max"); device->vdd_erase = cfg_getfloat(pcfg, "vdd_erase"); device->calibration_words = cfg_getint(pcfg, "calibration_words"); device->chip_erase_script = get_script_by_name(cfg_getstr(pcfg, "chip_erase_script")); device->progmem_addr_set_script = get_script_by_name(cfg_getstr(pcfg, "progmem_addr_set_script")); device->progmem_addr_bytes = cfg_getint(pcfg, "progmem_addr_bytes"); device->progmem_rd_script = get_script_by_name(cfg_getstr(pcfg, "progmem_rd_script")); device->progmem_rd_words = cfg_getint(pcfg, "progmem_rd_words"); device->eerd_prep_script = get_script_by_name(cfg_getstr(pcfg, "eerd_prep_script")); device->eerd_script = get_script_by_name(cfg_getstr(pcfg, "eerd_script")); device->eerd_locations = cfg_getint(pcfg, "eerd_locations"); device->user_id_rd_prep_script = get_script_by_name(cfg_getstr(pcfg, "user_id_rd_prep_script")); device->user_id_rd_script = get_script_by_name(cfg_getstr(pcfg, "user_id_rd_script")); device->config_rd_prep_script = get_script_by_name(cfg_getstr(pcfg, "config_rd_prep_script")); device->config_rd_script = get_script_by_name(cfg_getstr(pcfg, "config_rd_script")); device->progmem_wr_prep_script = get_script_by_name(cfg_getstr(pcfg, "progmem_wr_prep_script")); device->progmem_wr_script = get_script_by_name(cfg_getstr(pcfg, "progmem_wr_script")); device->progmem_wr_words = cfg_getint(pcfg, "progmem_wr_words"); device->progmem_panel_bufs = cfg_getint(pcfg, "progmem_panel_bufs"); device->progmem_panel_offset = cfg_getint(pcfg, "progmem_panel_offset"); device->eewr_prep_script = get_script_by_name(cfg_getstr(pcfg, "eewr_prep_script")); device->eewr_script = get_script_by_name(cfg_getstr(pcfg, "eewr_script")); device->eewr_locations = cfg_getint(pcfg, "eewr_locations"); device->user_id_wr_prep_script = get_script_by_name(cfg_getstr(pcfg, "user_id_wr_prep_script")); device->user_id_wr_script = get_script_by_name(cfg_getstr(pcfg, "user_id_wr_script")); device->config_wr_prep_script = get_script_by_name(cfg_getstr(pcfg, "config_wr_prep_script")); device->config_wr_script = get_script_by_name(cfg_getstr(pcfg, "config_wr_script")); device->osccal_rd_script = get_script_by_name(cfg_getstr(pcfg, "osccal_rd_script")); device->osccal_wr_script = get_script_by_name(cfg_getstr(pcfg, "osccal_wr_script")); device->dp_mask = cfg_getint(pcfg, "dp_mask"); device->write_cfg_on_erase = cfg_getint(pcfg, "write_cfg_on_erase"); device->blank_check_skip_usr_ids = cfg_getint(pcfg, "blank_check_skip_usr_ids"); device->ignore_bytes = cfg_getint(pcfg, "ignore_bytes"); device->chip_erase_prep_script = get_script_by_name(cfg_getstr(pcfg, "chip_erase_prep_script")); device->boot_flash = cfg_getint(pcfg, "boot_flash"); device->config9_mask = cfg_getint(pcfg, "config9_mask"); device->config9_blank = cfg_getint(pcfg, "config9_blank"); device->progmem_erase_script = get_script_by_name(cfg_getstr(pcfg, "progmem_erase_script")); device->eemem_erase_script = get_script_by_name(cfg_getstr(pcfg, "eemem_erase_script")); device->configmem_erase_script = get_script_by_name(cfg_getstr(pcfg, "configmem_erase_script")); device->reserved1_erase_script = get_script_by_name(cfg_getstr(pcfg, "reserved1_erase_script")); device->reserved2_erase_script = get_script_by_name(cfg_getstr(pcfg, "reserved2_erase_script")); device->test_memory_rd_script = get_script_by_name(cfg_getstr(pcfg, "test_memory_rd_script")); device->test_memory_rd_words = cfg_getint(pcfg, "test_memory_rd_words"); device->eerow_erase_script = get_script_by_name(cfg_getstr(pcfg, "eerow_erase_script")); device->eerow_erase_words = cfg_getint(pcfg, "eerow_erase_words"); device->export_to_mplab = cfg_getint(pcfg, "export_to_mplab"); device->debug_halt_script = get_script_by_name(cfg_getstr(pcfg, "debug_halt_script")); device->debug_run_script = get_script_by_name(cfg_getstr(pcfg, "debug_run_script")); device->debug_status_script = get_script_by_name(cfg_getstr(pcfg, "debug_status_script")); device->debug_read_exec_ver_script = get_script_by_name(cfg_getstr(pcfg, "debug_read_exec_ver_script")); device->debug_single_step_script = get_script_by_name(cfg_getstr(pcfg, "debug_single_step_script")); device->debug_bulk_wr_data_script = get_script_by_name(cfg_getstr(pcfg, "debug_bulk_wr_data_script")); device->debug_bulk_rd_data_script = get_script_by_name(cfg_getstr(pcfg, "debug_bulk_rd_data_script")); device->debug_write_vector_script = get_script_by_name(cfg_getstr(pcfg, "debug_write_vector_script")); device->debug_read_vector_script = get_script_by_name(cfg_getstr(pcfg, "debug_read_vector_script")); device->debug_row_erase_script = get_script_by_name(cfg_getstr(pcfg, "debug_row_erase_script")); device->debug_row_erase_size = cfg_getint(pcfg, "debug_row_erase_size"); device->debug_reserved5_script = get_script_by_name(cfg_getstr(pcfg, "debug_reserved5_script")); device->debug_reserved6_script = get_script_by_name(cfg_getstr(pcfg, "debug_reserved6_script")); device->debug_reserved7_script = get_script_by_name(cfg_getstr(pcfg, "debug_reserved7_script")); device->debug_reserved8_script = get_script_by_name(cfg_getstr(pcfg, "debug_reserved8_script")); device->lvp_script = get_script_by_name(cfg_getstr(pcfg, "lvp_script")); cfg_free(pcfg); return 0; }