vscf_data_t* gdnsd_initialize(const char* config_dir, const bool check_create_dirs) { static bool has_run = false; if(has_run) log_fatal("BUG: gdnsd_initialize() should only be called once!"); else has_run = true; // Initialize other areas of libgdnsd gdnsd_init_net(); gdnsd_rand_meta_init(); // set up config dir if(!config_dir) config_dir = GDNSD_DEFPATH_CONFIG; gdnsd_dirs[CFG] = gdnsd_realdir(config_dir, "config", false, 0); // parse config file char* cfg_file = gdnsd_resolve_path_cfg("config", NULL); vscf_data_t* cfg_root = conf_load_vscf(cfg_file); free(cfg_file); #ifndef NDEBUG // in developer debug builds, exercise clone+destroy if(cfg_root) { vscf_data_t* temp_cfg = vscf_clone(cfg_root, false); vscf_destroy(cfg_root); cfg_root = temp_cfg; } #endif // find run/state paths, possibly using config input const char* run_dir = GDNSD_DEFPATH_RUN; const char* state_dir = GDNSD_DEFPATH_STATE; if(cfg_root) { vscf_data_t* options = vscf_hash_get_data_byconstkey(cfg_root, "options", true); if(options) { if(!vscf_is_hash(options)) log_fatal("Config key 'options': wrong type (must be hash)"); CFG_DIR(options, run_dir); CFG_DIR(options, state_dir); } } // set them up if(check_create_dirs) { gdnsd_dirs[RUN] = gdnsd_realdir(run_dir, "run", true, 0750); gdnsd_dirs[STATE] = gdnsd_realdir(state_dir, "state", true, 0755); } else { gdnsd_dirs[RUN] = strdup(run_dir); gdnsd_dirs[STATE] = strdup(state_dir); } // This is just fixed at compiletime, period gdnsd_dirs[LIBEXEC] = GDNSD_DEFPATH_LIBEXEC; return cfg_root; }
bool gdmaps_test_db_exists(const char* dbfile) { bool rv = false; char* fn = gdnsd_resolve_path_cfg(dbfile, "geoip"); struct stat st; if(!stat(fn, &st) && !S_ISDIR(st.st_mode)) rv = true; free(fn); return rv; }
static const vscf_data_t* conf_load_vscf(const char* cfg_dir) { const vscf_data_t* out = NULL; gdnsd_set_config_dir(cfg_dir); char*cfg_path = gdnsd_resolve_path_cfg("config", NULL); struct stat cfg_stat; if(!stat(cfg_path, &cfg_stat)) { log_info("Loading configuration from '%s'", cfg_path); char* vscf_err; out = vscf_scan_filename(cfg_path, &vscf_err); if(!out) log_fatal("Configuration from '%s' failed: %s", cfg_path, vscf_err); if(!vscf_is_hash(out)) log_fatal("Configuration from '%s' failed: config was an array!", cfg_path); } else { log_info("No config file at '%s', using defaults + zones auto-scan", cfg_path); } free(cfg_path); return out; }
// XXX check_only could be used to optimize for the checkconf case, // so long as the optimization doesn't change the validity of the check. void zsrc_djb_load_zones(const bool check_only V_UNUSED) { djb_dir = gdnsd_resolve_path_cfg("djbdns/", NULL); zsrc_djb_sync_zones(); gdnsd_atexit_debug(unload_zones); }