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