+/* --- @fw_log@ --- *
+ *
+ * Arguments: @time_t t@ = when the connection occurred or (@-1@)
+ * @const char *fmt@ = format string to fill in
+ * @...@ = other arguments
+ *
+ * Returns: ---
+ *
+ * Use: Logs a connection.
+ */
+
+void fw_log(time_t t, const char *fmt, ...)
+{
+ struct tm *tm;
+ dstr d = DSTR_INIT;
+ va_list ap;
+
+ if (flags & FW_QUIET)
+ return;
+
+ if (t == -1)
+ t = time(0);
+ tm = localtime(&t);
+ DENSURE(&d, 64);
+ d.len += strftime(d.buf, d.sz, "%Y-%m-%d %H:%M:%S", tm);
+ DPUTC(&d, ' ');
+ va_start(ap, fmt);
+ dstr_vputf(&d, fmt, ap);
+ va_end(ap);
+ if (flags & FW_SYSLOG)
+ syslog(LOG_NOTICE, "%s", d.buf);
+ else {
+ DPUTC(&d, '\n');
+ dstr_write(&d, stderr);
+ }
+ DDESTROY(&d);
+}
+
+/* --- @fw_inc@, @fw_dec@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Increments or decrements the active thing count. `fw' won't
+ * quit while there are active things.
+ */
+
+void fw_inc(void) { flags |= FW_SET; active++; }
+void fw_dec(void) { if (active) active--; }
+
+/* --- @fw_exit@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Exits when appropriate.
+ */
+
+static void fw_exit(void)
+{
+ endpt_killall();
+ source_killall();
+}
+
+/* --- @fw_tidy@ --- *
+ *
+ * Arguments: @int n@ = signal number
+ * @void *p@ = an uninteresting argument
+ *
+ * Returns: ---
+ *
+ * Use: Handles various signals and causes a clean tidy-up.
+ */
+
+static void fw_tidy(int n, void *p)
+{
+ const char *sn = "unexpected signal (bug!)";
+ if (n == SIGTERM)
+ sn = "SIGTERM";
+ else if (n == SIGINT)
+ sn = "SIGINT";
+
+ fw_log(-1, "closing down on %s", sn);
+ fw_exit();
+}
+