+ sendto(fd, BBASE(&b), BLEN(&b), 0, (struct sockaddr *)&sin, sizeof(sin));
+ T( trace(TRACE_DAEMON, "daemon: reply sent"); )
+ return;
+
+fail:
+ syslog(LOG_ERR, "couldn't respond to query");
+ T( trace(TRACE_DAEMON, "daemon: failed to answer query"); )
+}
+
+/* --- @daemon__die@ --- *
+ *
+ * Arguments: @int n@ = signal number
+ * @void *p@ = ignored
+ *
+ * Returns: Doesn't.
+ *
+ * Use: Exits the daemon.
+ */
+
+static void daemon__die(int n, void *p)
+{
+ T( trace(TRACE_DAEMON, "daemon: killed by signal %i", n); )
+ syslog(LOG_NOTICE, "killed by signal type %i", n);
+ remove(file_PID);
+ exit(0);
+}
+
+/* --- @daemon__setTimer@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Sets the interval timer up.
+ */
+
+static void daemon__wakeUp(struct timeval *tv, void *p);
+
+static void daemon__setTimer(void)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, 0);
+ tv.tv_sec += daemon__awakeEvery;
+ sel_addtimer(&daemon__sel, &daemon__timer, &tv, daemon__wakeUp, 0);
+}
+
+/* --- @daemon__rescan@ --- *
+ *
+ * Arguments: @int n@ = signal number
+ * @void *p@ = ignored
+ *
+ * Returns: ---
+ *
+ * Use: Forces a rescan of the daemon's configuration.
+ */
+
+static void daemon__rescan(int n, void *p)
+{
+ syslog(LOG_INFO, "rescanning configuration file");
+ name_end();
+ rule_end();
+ netg_end();
+ userdb_end();
+ dsa_privfree(&daemon__key);
+ userdb_init();
+ userdb_local();
+ userdb_yp();
+ netg_init();
+ rule_init();
+ name_init();
+ if (daemon__readConfig(daemon__config))
+ syslog(LOG_ERR, "error reading configuration file");
+ sel_rmtimer(&daemon__timer);
+ daemon__setTimer();
+ fwatch_update(&daemon__cwatch, daemon__config);
+ fwatch_update(&daemon__kwatch, daemon__keyfile);
+}
+
+/* --- @daemon__wakeUp@ --- *
+ *
+ * Arguments: @struct timeval *tv@ = ignored
+ * @void *p@ = ignored
+ *
+ * Returns: ---
+ *
+ * Use: Wakes up periodically to check the configuration file.
+ */
+
+static void daemon__wakeUp(struct timeval *tv, void *p)
+{
+ T( trace(TRACE_DAEMON, "daemon: interval timer"); )
+ rand_seed(RAND_GLOBAL, 160);
+ daemon__setTimer();
+ if (fwatch_update(&daemon__cwatch, daemon__config))
+ daemon__rescan(0, 0);
+ else if (fwatch_update(&daemon__kwatch, daemon__keyfile)) {
+ const char *kf = daemon__keyfile;
+ daemon__keyfile = 0;
+ daemon_readKey(kf);
+ }