+#include "color.h"
+
+/** The internal state of the daemon. */
+struct daemon {
+ /** See \ref daemon_flags. */
+ unsigned flags;
+ /** Set by \ref daemon_set_logfile(). */
+ char *logfile_name;
+ /** Current loglevel, see \ref daemon_set_loglevel(). */
+ int loglevel;
+
+ /** Used by \ref server_uptime() and \ref uptime_str(). */
+ time_t startuptime;
+ /** The file pointer if the logfile is open. */
+ FILE *logfile;
+ /** Used by para_log() if \p DF_LOG_HOSTNAME is set. */
+ char *hostname;
+ /** Used for colored log messages. */
+ char log_colors[NUM_LOGLEVELS][COLOR_MAXLEN];
+};
+
+static struct daemon the_daemon, *me = &the_daemon;
+
+/**
+ * Activate default log colors.
+ *
+ * This should be called early if color support is wanted.
+ */
+void daemon_set_default_log_colors(void)
+{
+ int i;
+ static const char *default_log_colors[NUM_LOGLEVELS] = {
+ [LL_DEBUG] = "normal",
+ [LL_INFO] = "normal",
+ [LL_NOTICE] = "normal",
+ [LL_WARNING] = "yellow",
+ [LL_ERROR] = "red",
+ [LL_CRIT] = "magenta bold",
+ [LL_EMERG] = "red bold",
+ };
+ for (i = 0; i < NUM_LOGLEVELS; i++)
+ color_parse_or_die(default_log_colors[i], me->log_colors[i]);
+}
+
+/**
+ * Set the color for one loglevel.
+ *
+ * \param arg The loglevel/color specifier.
+ *
+ * \a arg must be of the form "ll:[fg [bg]] [attr]".
+ *
+ * \return 1 On success, -1 on errors.
+ */
+void daemon_set_log_color_or_die(char const *arg)
+{
+ char *p = strchr(arg, ':');
+ int ret, ll;
+
+ if (!p)
+ goto err;
+ ret = get_loglevel_by_name(arg);
+ if (ret < 0)
+ goto err;
+ ll = ret;
+ p++;
+ color_parse_or_die(p, me->log_colors[ll]);
+ return;
+err:
+ PARA_EMERG_LOG("%s: color syntax error\n", arg);
+ exit(EXIT_FAILURE);
+}
+
+/**
+ * Init or change the name of the log file.
+ *
+ * \param logfile_name The full path of the logfile.
+ */
+void daemon_set_logfile(char *logfile_name)
+{
+ free(me->logfile_name);
+ me->logfile_name = NULL;
+ if (logfile_name)
+ me->logfile_name = para_strdup(logfile_name);
+}
+
+/**
+ * Suppress log messages with severity lower than the given loglevel.
+ *
+ * \param loglevel The smallest level that should be logged.
+ */
+void daemon_set_loglevel(char *loglevel)
+{
+ int ret = get_loglevel_by_name(loglevel);
+
+ assert(ret >= 0);
+ me->loglevel = ret;
+}
+
+/**
+ * Set one of the daemon config flags.
+ *
+ * \param flag The flag to set.
+ *
+ * \sa \ref daemon_flags.
+ */
+void daemon_set_flag(unsigned flag)
+{
+ me->flags |= flag;
+}
+
+/**
+ * Clear one of the daemon config flags.
+ *
+ * \param flag The flag to clear.
+ *
+ * \sa \ref daemon_flags.
+ */
+void daemon_clear_flag(unsigned flag)
+{
+ me->flags &= ~flag;
+}
+
+static bool daemon_test_flag(unsigned flag)
+{
+ return me->flags & flag;
+}