+/* A GLogFunc to handle g_log calls. This function assumes that user_data
+ * is either NULL or a pointer to one of the debug_* configuration variables
+ * in conffile.c, indicating whether logging for this log domain is enabled.
+ *
+ * @param log_domain: the log domain, or NULL for general logging
+ * @param log_level: level, fatality, and recursion flags
+ * @param message: the message to log
+ * @param user_pointer: unused
+ */
+static void
+debug_logging_handler(const gchar *log_domain G_GNUC_UNUSED,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ char *maxlevel = NULL;
+ pcontext_t context = get_pcontext();
+
+ /* scriptutil context doesn't do any logging except for critical
+ * and error levels */
+ if (context != CONTEXT_SCRIPTUTIL) {
+ /* convert the highest level to a string and dbprintf it */
+ if (log_level & G_LOG_LEVEL_ERROR)
+ maxlevel = _("error (fatal): ");
+ else if (log_level & G_LOG_LEVEL_CRITICAL)
+ maxlevel = _("critical (fatal): ");
+ else if (log_level & G_LOG_LEVEL_WARNING)
+ maxlevel = _("warning: ");
+ else if (log_level & G_LOG_LEVEL_MESSAGE)
+ maxlevel = _("message: ");
+ else if (log_level & G_LOG_LEVEL_INFO)
+ maxlevel = _("info: ");
+ else
+ maxlevel = ""; /* no level displayed for debugging */
+
+ debug_printf("%s%s\n", maxlevel, message);
+ }
+
+ /* error and critical levels have special handling */
+ if (log_level & (G_LOG_LEVEL_ERROR|G_LOG_LEVEL_CRITICAL)) {
+ erroutput_type_t local_erroutput;
+
+ /* Calculate a local version of erroutput_type, based on the
+ * context if the process has not set erroutput_type explicitly */
+ if (!(erroutput_type & ERR_FROM_CONTEXT)) {
+ local_erroutput = erroutput_type;
+ } else {
+ switch (context) {
+ case CONTEXT_SCRIPTUTIL:
+ local_erroutput = ERR_INTERACTIVE;
+ break;
+
+ case CONTEXT_DAEMON:
+ local_erroutput = ERR_INTERACTIVE
+ | ERR_AMANDALOG
+ | ERR_SYSLOG;
+ break;
+
+ case CONTEXT_CMDLINE:
+ case CONTEXT_DEFAULT:
+ default:
+ local_erroutput = ERR_INTERACTIVE;
+ break;
+ }
+ }
+
+ if (local_erroutput & ERR_AMANDALOG && logerror_fn != NULL)
+ (*logerror_fn)((char *)message); /* discard 'const' */
+
+ if (local_erroutput & ERR_SYSLOG) {
+#ifdef LOG_AUTH
+ openlog(get_pname(), LOG_PID, LOG_AUTH);
+#else
+ openlog(get_pname(), LOG_PID, 0);
+#endif
+ syslog(LOG_NOTICE, "%s", message);
+ closelog();
+ }
+
+ if (local_erroutput & ERR_INTERACTIVE) {
+ g_fprintf(stderr, "%s: %s\n", get_pname(), message);
+ fflush(stderr);
+ }
+
+#ifdef HAVE_GLIBC_BACKTRACE
+ /* try logging a traceback to the debug log */
+ if (db_fd != -1) {
+ void *stack[32];
+ int naddrs;
+ naddrs = backtrace(stack, sizeof(stack)/sizeof(*stack));
+ backtrace_symbols_fd(stack, naddrs, db_fd);
+ }
+#endif