/** Do the cron action and wait for result exit value */ static void* win_do_cron(void* ATTR_UNUSED(arg)) { int mynum=65; char* cronaction; log_thread_set(&mynum); cronaction = lookup_reg_str("Software\\Unbound", "CronAction"); if(cronaction && strlen(cronaction)>0) { STARTUPINFO sinfo; PROCESS_INFORMATION pinfo; memset(&pinfo, 0, sizeof(pinfo)); memset(&sinfo, 0, sizeof(sinfo)); sinfo.cb = sizeof(sinfo); verbose(VERB_ALGO, "cronaction: %s", cronaction); if(!CreateProcess(NULL, cronaction, NULL, NULL, 0, CREATE_NO_WINDOW, NULL, NULL, &sinfo, &pinfo)) log_err("CreateProcess error"); else { waitforit(&pinfo); CloseHandle(pinfo.hProcess); CloseHandle(pinfo.hThread); } } free(cronaction); /* stop self */ CloseHandle(cron_thread); cron_thread = NULL; return NULL; }
char* get_registry_unbound_control(void) { char buf[1024]; char* ubdir = lookup_reg_str("Software\\Unbound", "InstallLocation"); char* cfg; if(!ubdir) return NULL; cfg = lookup_reg_str("Software\\Unbound", "ConfigFile"); if(!cfg) { free(ubdir); return NULL; } /* spaces in path need quotes in result */ snprintf(buf, sizeof(buf), "\"%s\\unbound-control.exe\" -c \"%s\"", ubdir, cfg); free(ubdir); free(cfg); return strdup(buf); }
/** * Perform root anchor update if so configured, by calling that process */ static void call_root_update(void) { char* rootanchor; rootanchor = lookup_reg_str("Software\\Unbound", "RootAnchor"); if(rootanchor && strlen(rootanchor)>0) { STARTUPINFO sinfo; PROCESS_INFORMATION pinfo; memset(&pinfo, 0, sizeof(pinfo)); memset(&sinfo, 0, sizeof(sinfo)); sinfo.cb = sizeof(sinfo); verbose(VERB_ALGO, "rootanchor: %s", rootanchor); report_status(SERVICE_START_PENDING, NO_ERROR, 8000); if(!CreateProcess(NULL, rootanchor, NULL, NULL, 0, CREATE_NO_WINDOW, NULL, NULL, &sinfo, &pinfo)) log_err("CreateProcess error for unbound-anchor.exe"); else { waitforubanchor(&pinfo); CloseHandle(pinfo.hProcess); CloseHandle(pinfo.hThread); } } free(rootanchor); }
/** * Init service. Keeps calling status pending to tell service control * manager that this process is not hanging. * @param r: restart, true on restart * @param d: daemon returned here. * @param c: config file returned here. * @return false if failed. */ static int service_init(struct svr** d, struct cfg** c) { struct cfg* cfg = NULL; struct svr* svr = NULL; if(!service_cfgfile) { char* newf = lookup_reg_str("Software\\DnssecTrigger", "ConfigFile"); if(newf) service_cfgfile = newf; else service_cfgfile = strdup(CONFIGFILE); if(!service_cfgfile) fatal_exit("out of memory"); } /* create config */ cfg = cfg_create(service_cfgfile); if(!cfg) return 0; report_status(SERVICE_START_PENDING, NO_ERROR, 2800); /* create daemon */ svr = svr_create(cfg); if(!svr) return 0; report_status(SERVICE_START_PENDING, NO_ERROR, 2600); verbose(VERB_QUERY, "winservice - apply settings"); /* apply settings and init */ verbosity = cfg->verbosity + service_cmdline_verbose; log_init(cfg->logfile, cfg->use_syslog, cfg->chroot); report_status(SERVICE_START_PENDING, NO_ERROR, 2400); hook_resolv_localhost(cfg); report_status(SERVICE_START_PENDING, NO_ERROR, 2300); *d = svr; *c = cfg; return 1; }
/** * Init service. Keeps calling status pending to tell service control * manager that this process is not hanging. * @param r: restart, true on restart * @param d: daemon returned here. * @param c: config file returned here. * @return false if failed. */ static int service_init(int r, struct daemon** d, struct config_file** c) { struct config_file* cfg = NULL; struct daemon* daemon = NULL; if(!service_cfgfile) { char* newf = lookup_reg_str("Software\\Unbound", "ConfigFile"); if(newf) service_cfgfile = newf; else service_cfgfile = strdup(CONFIGFILE); if(!service_cfgfile) fatal_exit("out of memory"); } /* create daemon */ if(r) daemon = *d; else daemon = daemon_init(); if(!daemon) return 0; if(!r) report_status(SERVICE_START_PENDING, NO_ERROR, 2800); /* read config */ cfg = config_create(); if(!cfg) return 0; if(!config_read(cfg, service_cfgfile, daemon->chroot)) { if(errno != ENOENT) { log_err("error in config file"); return 0; } log_warn("could not open config file, using defaults"); } if(!r) report_status(SERVICE_START_PENDING, NO_ERROR, 2600); verbose(VERB_QUERY, "winservice - apply settings"); /* apply settings and init */ verbosity = cfg->verbosity + service_cmdline_verbose; if(cfg->directory && cfg->directory[0]) { if(chdir(cfg->directory)) { log_err("could not chdir to %s: %s", cfg->directory, strerror(errno)); if(errno != ENOENT) return 0; log_warn("could not change directory - continuing"); } else verbose(VERB_QUERY, "chdir to %s", cfg->directory); } log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir); if(!r) report_status(SERVICE_START_PENDING, NO_ERROR, 2400); verbose(VERB_QUERY, "winservice - apply cfg"); daemon_apply_cfg(daemon, cfg); if(!r) report_status(SERVICE_START_PENDING, NO_ERROR, 2300); if(!(daemon->rc = daemon_remote_create(cfg))) { log_err("could not set up remote-control"); daemon_delete(daemon); config_delete(cfg); return 0; } /* open ports */ /* keep reporting that we are busy starting */ if(!r) report_status(SERVICE_START_PENDING, NO_ERROR, 2200); verbose(VERB_QUERY, "winservice - open ports"); if(!daemon_open_shared_ports(daemon)) return 0; verbose(VERB_QUERY, "winservice - ports opened"); if(!r) report_status(SERVICE_START_PENDING, NO_ERROR, 2000); *d = daemon; *c = cfg; return 1; }