Example #1
0
/**
 * Run the daemon. 
 * @param cfgfile: the config file name.
 * @param cmdline_verbose: verbosity resulting from commandline -v.
 *    These increase verbosity as specified in the config file.
 * @param debug_mode: if set, do not daemonize.
 * @param log_default_identity: Default identity to report in logs
 */
static void 
run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, const char* log_default_identity)
{
	struct config_file* cfg = NULL;
	struct daemon* daemon = NULL;
	int done_setup = 0;

	if(!(daemon = daemon_init()))
		fatal_exit("alloc failure");
	while(!daemon->need_to_exit) {
		if(done_setup)
			verbose(VERB_OPS, "Restart of %s.", PACKAGE_STRING);
		else	verbose(VERB_OPS, "Start of %s.", PACKAGE_STRING);

		/* config stuff */
		if(!(cfg = config_create()))
			fatal_exit("Could not alloc config defaults");
		if(!config_read(cfg, cfgfile, daemon->chroot)) {
			if(errno != ENOENT)
				fatal_exit("Could not read config file: %s",
					cfgfile);
			log_warn("Continuing with default config settings");
		}
		apply_settings(daemon, cfg, cmdline_verbose, debug_mode, log_default_identity);
		if(!done_setup)
			config_lookup_uid(cfg);
	
		/* prepare */
		if(!daemon_open_shared_ports(daemon))
			fatal_exit("could not open ports");
		if(!done_setup) { 
			perform_setup(daemon, cfg, debug_mode, &cfgfile);
			done_setup = 1; 
		} else {
			/* reopen log after HUP to facilitate log rotation */
			if(!cfg->use_syslog)
				log_init(cfg->logfile, 0, cfg->chrootdir);
		}
		/* work */
		daemon_fork(daemon);

		/* clean up for restart */
		verbose(VERB_ALGO, "cleanup.");
		daemon_cleanup(daemon);
		config_delete(cfg);
	}
	verbose(VERB_ALGO, "Exit cleanup.");
	/* this unlink may not work if the pidfile is located outside
	 * of the chroot/workdir or we no longer have permissions */
	if(daemon->pidfile) {
		int fd;
		/* truncate pidfile */
		fd = open(daemon->pidfile, O_WRONLY | O_TRUNC, 0644);
		if(fd != -1)
			close(fd);
		/* delete pidfile */
		unlink(daemon->pidfile);
	}
	daemon_delete(daemon);
}
Example #2
0
/**
 * 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;
}