1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2  *
3  * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * Authors: William Jon McCann <mccann@jhu.edu>
20  *
21  */
22 
23 #include "config.h"
24 
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdarg.h>
28 #include <signal.h>
29 #include <time.h>
30 #include <unistd.h>
31 
32 #include <syslog.h>
33 #ifdef WITH_SYSTEMD
34 #include <systemd/sd-daemon.h>
35 #endif
36 
37 #include <glib.h>
38 #include <glib/gstdio.h>
39 
40 #include "gdm-log.h"
41 
42 static gboolean initialized = FALSE;
43 static gboolean is_sd_booted = FALSE;
44 static gboolean debug_enabled = FALSE;
45 
46 static gint
get_syslog_priority_from_log_level(GLogLevelFlags log_level)47 get_syslog_priority_from_log_level (GLogLevelFlags log_level)
48 {
49         switch (log_level & G_LOG_LEVEL_MASK) {
50         case G_LOG_FLAG_FATAL:
51                 return LOG_EMERG;
52         case G_LOG_LEVEL_ERROR:
53                 /* fatal error - a critical error, in the syslog world */
54                 return LOG_CRIT;
55         case G_LOG_LEVEL_CRITICAL:
56                 /* critical warning - an error, in the syslog world */
57                 return LOG_ERR;
58         case G_LOG_LEVEL_WARNING:
59         case G_LOG_LEVEL_MESSAGE:
60                 return LOG_NOTICE;
61         case G_LOG_LEVEL_INFO:
62                 return LOG_INFO;
63         case G_LOG_LEVEL_DEBUG:
64         default:
65                 return LOG_DEBUG;
66         }
67 }
68 
69 static void
gdm_log_default_handler(const gchar * log_domain,GLogLevelFlags log_level,const gchar * message,gpointer unused_data)70 gdm_log_default_handler (const gchar    *log_domain,
71                          GLogLevelFlags  log_level,
72                          const gchar    *message,
73                          gpointer        unused_data)
74 {
75         int priority;
76 
77         gdm_log_init ();
78 
79         if ((log_level & G_LOG_LEVEL_MASK) == G_LOG_LEVEL_DEBUG &&
80             !debug_enabled) {
81                 return;
82         }
83 
84         /* Process the message prefix and priority */
85         priority = get_syslog_priority_from_log_level (log_level);
86 
87         if (is_sd_booted) {
88                 fprintf (stderr,
89                          "<%d>%s%s%s\n",
90                          priority,
91                          log_domain != NULL? log_domain : "",
92                          log_domain != NULL? ": " : "",
93                          message);
94                 fflush (stderr);
95         } else {
96                 syslog (priority,
97                         "%s%s%s\n",
98                         log_domain != NULL? log_domain : "",
99                         log_domain != NULL? ": " : "",
100                         message);
101         }
102 }
103 
104 void
gdm_log_toggle_debug(void)105 gdm_log_toggle_debug (void)
106 {
107         gdm_log_set_debug (!debug_enabled);
108 }
109 
110 void
gdm_log_set_debug(gboolean debug)111 gdm_log_set_debug (gboolean debug)
112 {
113         g_assert (initialized);
114         if (debug_enabled == debug) {
115                 return;
116         }
117 
118         if (debug) {
119                 debug_enabled = debug;
120                 g_debug ("Enabling debugging");
121         } else {
122                 g_debug ("Disabling debugging");
123                 debug_enabled = debug;
124         }
125 }
126 
127 void
gdm_log_init(void)128 gdm_log_init (void)
129 {
130         const char *prg_name;
131         int         options;
132 
133         if (initialized)
134                 return;
135 
136         initialized = TRUE;
137 
138 #ifdef WITH_SYSTEMD
139         is_sd_booted = sd_booted () > 0;
140 #endif
141 
142         g_log_set_default_handler (gdm_log_default_handler, NULL);
143 
144         /* Only set up syslog if !systemd, otherwise with systemd
145          * enabled, we keep the default GLib log handler which goes to
146          * stderr, which is routed to the appropriate place in the
147          * systemd service file.
148          */
149         if (!is_sd_booted) {
150                 prg_name = g_get_prgname ();
151 
152                 options = LOG_PID;
153 #ifdef LOG_PERROR
154                 options |= LOG_PERROR;
155 #endif
156 
157                 openlog (prg_name, options, LOG_DAEMON);
158         }
159 }
160 
161 void
gdm_log_shutdown(void)162 gdm_log_shutdown (void)
163 {
164         if (!initialized)
165                 return;
166         if (!is_sd_booted)
167                 closelog ();
168         initialized = FALSE;
169 }
170 
171