]> granicus.if.org Git - fcron/blob - log.c
Merge remote-tracking branch 'origin/master'
[fcron] / log.c
1 /*
2  * FCRON - periodic command scheduler 
3  *
4  *  Copyright 2000-2012 Thibault Godouet <fcron@free.fr>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  * 
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  * 
20  *  The GNU General Public License can also be found in the file
21  *  `LICENSE' that comes with the fcron source distribution.
22  */
23
24
25 /* This code is inspired by Anacron's sources of
26    Itai Tzur <itzur@actcom.co.il> */
27
28
29 #include "fcron.h"
30
31 #include "log.h"
32
33 #include <sys/types.h>
34 #include <sys/socket.h>
35
36 #ifdef DEBUG
37 char debug_opt = 1;             /* set to 1 if we are in debug mode */
38 #else
39 char debug_opt = 0;             /* set to 1 if we are in debug mode */
40 #endif
41
42
43 static void xopenlog(void);
44 char *make_msg(const char *append, char *fmt, va_list args);
45 void log_syslog_str(int priority, char *msg);
46 void log_console_str(char *msg);
47 void log_fd_str(int fd, char *msg);
48 static void log_syslog(int priority, int fd, char *fmt, va_list args);
49 static void log_e(int priority, char *fmt, va_list args);
50 #ifdef HAVE_LIBPAM
51 static void log_pame(int priority, pam_handle_t * pamh, int pamerrno,
52                      char *fmt, va_list args);
53 #endif
54
55 static char truncated[] = " (truncated)";
56 static int log_open = 0;
57
58
59 static void
60 xopenlog(void)
61 {
62     if (!log_open) {
63         openlog(prog_name, LOG_PID, SYSLOG_FACILITY);
64         log_open = 1;
65     }
66 }
67
68
69 void
70 xcloselog()
71 {
72     if (log_open)
73         closelog();
74     log_open = 0;
75 }
76
77
78 /* Construct the message string from its parts, and append a string to it */
79 char *
80 make_msg(const char *append, char *fmt, va_list args)
81 {
82     int len;
83     char *msg = NULL;
84
85     if ((msg = calloc(1, MAX_MSG + 1)) == NULL)
86         return NULL;
87     /* There's some confusion in the documentation about what vsnprintf
88      * returns when the buffer overflows.  Hmmm... */
89     len = vsnprintf(msg, MAX_MSG + 1, fmt, args);
90     if (append != NULL) {
91         size_t size_to_cat = ((MAX_MSG - len) > 0) ? (MAX_MSG - len) : 0;
92         strncat(msg, ": ", size_to_cat);
93         strncat(msg, append, size_to_cat);
94         len += 2 + strlen(append);
95     }
96     if (len >= MAX_MSG)
97         strcpy(msg + (MAX_MSG - 1) - sizeof(truncated), truncated);
98
99     return msg;
100 }
101
102
103 /* log a simple string to syslog if needed */
104 void
105 log_syslog_str(int priority, char *msg)
106 {
107     if (dosyslog) {
108         xopenlog();
109         syslog(priority, "%s", msg);
110     }
111
112 }
113
114 /* log a simple string to console if needed */
115 void
116 log_console_str(char *msg)
117 {
118     if (foreground == 1) {
119         time_t t = time(NULL);
120         struct tm *ft;
121         char date[30];
122
123         ft = localtime(&t);
124         date[0] = '\0';
125         strftime(date, sizeof(date), "%H:%M:%S", ft);
126         fprintf(stderr, "%s %s\n", date, msg);
127
128     }
129 }
130
131 /* log a simple string to fd if needed */
132 void
133 log_fd_str(int fd, char *msg)
134 {
135     if (fd >= 0) {
136         send(fd, msg, strlen(msg), 0);
137         send(fd, "\n", strlen("\n"), 0);
138     }
139 }
140
141 /* Log a message, described by "fmt" and "args", with the specified 
142  * "priority". */
143 /* write it also to fd if positive, and to stderr if foreground==1 */
144 static void
145 log_syslog(int priority, int fd, char *fmt, va_list args)
146 {
147     char *msg;
148
149     if ((msg = make_msg(NULL, fmt, args)) == NULL)
150         return;
151
152     log_syslog_str(priority, msg);
153     log_console_str(msg);
154     log_fd_str(fd, msg);
155
156     Free_safe(msg);
157 }
158
159 /* Same as log_syslog(), but also appends an error description corresponding
160  * to "errno". */
161 static void
162 log_e(int priority, char *fmt, va_list args)
163 {
164     int saved_errno;
165     char *msg;
166
167     saved_errno = errno;
168
169     if ((msg = make_msg(strerror(saved_errno), fmt, args)) == NULL)
170         return;
171
172     log_syslog_str(priority, msg);
173     log_console_str(msg);
174
175     Free_safe(msg);
176 }
177
178
179 #ifdef HAVE_LIBPAM
180 /* Same as log_syslog(), but also appends an error description corresponding
181  * to the pam_error. */
182 static void
183 log_pame(int priority, pam_handle_t * pamh, int pamerrno, char *fmt,
184          va_list args)
185 {
186     char *msg;
187
188     if ((msg = make_msg(pam_strerror(pamh, pamerrno), fmt, args)) == NULL)
189         return;
190
191     log_syslog_str(priority, msg);
192     log_console_str(msg);
193
194     xcloselog();
195
196     Free_safe(msg);
197 }
198 #endif
199
200
201 /* Log an "explain" level message */
202 void
203 explain(char *fmt, ...)
204 {
205     va_list args;
206
207     va_start(args, fmt);
208     log_syslog(EXPLAIN_LEVEL, -1, fmt, args);
209     va_end(args);
210 }
211
212 /* as explain(), but also write message to fd if positive */
213 void
214 explain_fd(int fd, char *fmt, ...)
215 {
216     va_list args;
217
218     va_start(args, fmt);
219     log_syslog(EXPLAIN_LEVEL, fd, fmt, args);
220     va_end(args);
221 }
222
223
224 /* Log an "explain" level message, with an error description */
225 void
226 explain_e(char *fmt, ...)
227 {
228     va_list args;
229
230     va_start(args, fmt);
231     log_e(EXPLAIN_LEVEL, fmt, args);
232     va_end(args);
233 }
234
235
236 /* Log a "warning" level message */
237 void
238 warn(char *fmt, ...)
239 {
240     va_list args;
241
242     va_start(args, fmt);
243     log_syslog(WARNING_LEVEL, -1, fmt, args);
244     va_end(args);
245 }
246
247 /* as warn(), but also write message to fd if positive */
248 void
249 warn_fd(int fd, char *fmt, ...)
250 {
251     va_list args;
252
253     va_start(args, fmt);
254     log_syslog(WARNING_LEVEL, fd, fmt, args);
255     va_end(args);
256 }
257
258
259 /* Log a "warning" level message, with an error description */
260 void
261 warn_e(char *fmt, ...)
262 {
263     va_list args;
264
265     va_start(args, fmt);
266     log_e(WARNING_LEVEL, fmt, args);
267     va_end(args);
268 }
269
270
271 /* Log a "complain" level message */
272 void
273 error(char *fmt, ...)
274 {
275     va_list args;
276
277     va_start(args, fmt);
278     log_syslog(COMPLAIN_LEVEL, -1, fmt, args);
279     va_end(args);
280 }
281
282 /* as error(), but also write message to fd if positive */
283 void
284 error_fd(int fd, char *fmt, ...)
285 {
286     va_list args;
287
288     va_start(args, fmt);
289     log_syslog(COMPLAIN_LEVEL, fd, fmt, args);
290     va_end(args);
291 }
292
293
294 /* Log a "complain" level message, with an error description */
295 void
296 error_e(char *fmt, ...)
297 {
298     va_list args;
299
300     va_start(args, fmt);
301     log_e(COMPLAIN_LEVEL, fmt, args);
302     va_end(args);
303 }
304
305
306 #ifdef HAVE_LIBPAM
307 /* Log a "complain" level message, with a PAM error description */
308 void
309 error_pame(pam_handle_t * pamh, int pamerrno, char *fmt, ...)
310 {
311     va_list args;
312
313     xcloselog();                /* PAM is likely to have used openlog() */
314
315     va_start(args, fmt);
316     log_pame(COMPLAIN_LEVEL, pamh, pamerrno, fmt, args);
317     va_end(args);
318 }
319 #endif
320
321 /* Log a "complain" level message, and exit */
322 void
323 die(char *fmt, ...)
324 {
325     va_list args;
326
327     va_start(args, fmt);
328     log_syslog(COMPLAIN_LEVEL, -1, fmt, args);
329     va_end(args);
330     if (getpid() == daemon_pid) {
331         error("Aborted");
332     }
333     else {
334         error("fcron child aborted: this does not affect the main fcron daemon,"
335               " but this may prevent a job from being run or an email from being sent.");
336     }
337
338     exit(EXIT_ERR);
339
340 }
341
342
343 /* Log a "complain" level message, with an error description, and exit */
344 void
345 die_e(char *fmt, ...)
346 {
347     va_list args;
348     int err_no = 0;
349
350     err_no = errno;
351
352     va_start(args, fmt);
353     log_e(COMPLAIN_LEVEL, fmt, args);
354     va_end(args);
355     if (getpid() == daemon_pid) {
356         error("Aborted");
357     }
358     else {
359         error("fcron child aborted: this does not affect the main fcron daemon,"
360               " but this may prevent a job from being run or an email from being sent.");
361     }
362
363
364     exit(err_no);
365
366 }
367
368 #ifdef HAVE_LIBPAM
369 /* Log a "complain" level message, with a PAM error description, and exit */
370 void
371 die_pame(pam_handle_t * pamh, int pamerrno, char *fmt, ...)
372 {
373     va_list args;
374
375     xcloselog();                /* PAM is likely to have used openlog() */
376
377     va_start(args, fmt);
378     log_pame(COMPLAIN_LEVEL, pamh, pamerrno, fmt, args);
379     va_end(args);
380     pam_end(pamh, pamerrno);
381     if (getpid() == daemon_pid)
382         error("Aborted");
383
384     exit(EXIT_ERR);
385
386 }
387 #endif
388
389 /* Log a "debug" level message */
390 void
391 Debug(char *fmt, ...)
392 {
393     va_list args;
394
395     va_start(args, fmt);
396     log_syslog(DEBUG_LEVEL, -1, fmt, args);
397     va_end(args);
398 }
399
400 /* write message to fd, and to syslog in "debug" level message if debug_opt */
401 void
402 send_msg_fd_debug(int fd, char *fmt, ...)
403 {
404     char *msg;
405
406     va_list args;
407
408     va_start(args, fmt);
409
410     if ((msg = make_msg(NULL, fmt, args)) == NULL)
411         return;
412
413     if (debug_opt)
414         log_syslog_str(DEBUG_LEVEL, msg);
415
416     log_fd_str(fd, msg);
417
418     Free_safe(msg);
419
420     va_end(args);
421 }
422
423 /* write message to fd */
424 void
425 send_msg_fd(int fd, char *fmt, ...)
426 {
427     char *msg;
428
429     va_list args;
430
431     va_start(args, fmt);
432
433     if ((msg = make_msg(NULL, fmt, args)) == NULL)
434         return;
435
436     log_fd_str(fd, msg);
437
438     Free_safe(msg);
439
440     va_end(args);
441 }