Merging upstream version 0.7.0 (Closes: #493243, #510888, #567617, #699414, #709777...
[debian/lxpanel.git] / plugins / weather / logutil.c
1 /**
2 * Copyright (c) 2012-2014 Piotr Sipika; see the AUTHORS file for more.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * See the COPYRIGHT file for more information.
19 */
20
21 /* Provides logging utilities */
22
23 #include "logutil.h"
24
25 #include <syslog.h>
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <sys/stat.h>
30 #include <sys/types.h>
31 #include <fcntl.h>
32 #include <string.h>
33 #include <errno.h>
34
35 static int g_Initialized = 0;
36 static LXWEATHER_LOGLEVEL g_Level = LXW_NONE;
37 static int g_FD = -1; /* -1 is syslog, 0 is std{out|err} */
38
39 /**
40 * Initializes the logging subsystem
41 *
42 * @param pczPath Path to a file to log to (can be NULL for std{out|err},
43 * or 'syslog' for syslog)
44 */
45 void
46 initializeLogUtil(const char * pczPath)
47 {
48 #ifndef DEBUG
49 return;
50 #endif
51
52 if (g_Initialized)
53 {
54 return;
55 }
56
57 if (pczPath)
58 {
59 if (strncmp(pczPath, "syslog", 6) == 0)
60 {
61 /* syslog */
62 openlog("LXWeather", LOG_NDELAY | LOG_PID, LOG_USER);
63 }
64 else if (strncmp(pczPath, "std", 3) == 0)
65 {
66 /* std{out|err} */
67 g_FD = 0;
68 }
69 else
70 {
71 /* Attempt to open this file for writing */
72 g_FD = open(pczPath,
73 O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC,
74 S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
75
76 if (g_FD < 0)
77 {
78 /* Failed */
79 fprintf(stderr, "LXWeather::initalizeLogUtil(): Failed to open %s: %s\n",
80 pczPath, strerror(errno));
81
82 /* Initialized flag is 0, so no logging will happen */
83 return;
84 }
85
86 }
87
88 }
89 else
90 {
91 /* stdout/err */
92 g_FD = 0;
93 }
94
95 g_Initialized = 1;
96 }
97
98 /**
99 * Cleans up the logging subsystem
100 *
101 */
102 void
103 cleanupLogUtil()
104 {
105 #ifndef DEBUG
106 return;
107 #endif
108
109 if (g_Initialized)
110 {
111 switch (g_FD)
112 {
113 case -1:
114 closelog();
115 break;
116
117 case 0:
118 /* std{out|err} */
119 break;
120
121 default:
122 /* Close the file */
123 close(g_FD); /* Don't care about errors */
124 }
125
126 g_Initialized = 0;
127 }
128
129 }
130
131 /**
132 * Logs the message using the specified level.
133 *
134 * @param level The level to log at
135 * @param pczMsg Message to log
136 */
137 void
138 logUtil(LXWEATHER_LOGLEVEL level, const char * pczMsg, ...)
139 {
140 #ifndef DEBUG
141 return;
142 #endif
143
144 if (g_Initialized && (level <= g_Level) && (g_Level > LXW_NONE))
145 {
146 va_list ap;
147
148 va_start(ap, pczMsg);
149
150 if (g_FD == -1)
151 {
152 int iSysLevel = (level == LXW_ERROR) ? LOG_ERR : LOG_NOTICE;
153
154 vsyslog(iSysLevel, pczMsg, ap);
155 }
156 else
157 {
158 char cBuf[1024];
159
160 pid_t myPid = getpid();
161
162 /* This is not portable, due to pid_t... */
163 size_t szBuf = snprintf(cBuf, sizeof(cBuf), "LXWeather [%ld] [%5s] ",
164 (long)myPid,
165 (level == LXW_ERROR) ? "ERROR" : "DEBUG");
166
167 szBuf += vsnprintf(cBuf + szBuf, sizeof(cBuf) - szBuf, pczMsg, ap);
168
169 szBuf += snprintf(cBuf + szBuf, sizeof(cBuf) - szBuf, "\n");
170
171 if (g_FD == 0)
172 {
173 /* std{out|err} */
174
175 if (level == LXW_ERROR)
176 {
177 fprintf(stderr, "%s", cBuf);
178 }
179 else
180 {
181 fprintf(stdout, "%s", cBuf);
182 }
183 }
184 else
185 {
186 /* write to file */
187 size_t wsz = write(g_FD, cBuf, szBuf);
188 (void) wsz; /* to prevent compile warning */
189 }
190 }
191
192 va_end(ap);
193
194 }
195
196 }
197
198 /**
199 * Sets the maximum allowed log level
200 *
201 * @param level The level to use for all messages to follow.
202 *
203 * @return Previous value of the maximum log level.
204 */
205 LXWEATHER_LOGLEVEL
206 setMaxLogLevel(LXWEATHER_LOGLEVEL level)
207 {
208 #ifndef DEBUG
209 return g_Level;
210 #endif
211
212 LXWEATHER_LOGLEVEL previous = g_Level;
213
214 if (g_Initialized && level <= LXW_ALL)
215 {
216 g_Level = level;
217 }
218
219 return previous;
220 }