2 * FCRON - periodic command scheduler
4 * Copyright 2000-2012 Thibault Godouet <fcron@free.fr>
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.
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.
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
20 * The GNU General Public License can also be found in the file
21 * `LICENSE' that comes with the fcron source distribution.
25 /* This code is inspired by Anacron's sources of
26 Itai Tzur <itzur@actcom.co.il> */
33 #include <sys/types.h>
34 #include <sys/socket.h>
37 char debug_opt = 1; /* set to 1 if we are in debug mode */
39 char debug_opt = 0; /* set to 1 if we are in debug mode */
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);
51 static void log_pame(int priority, pam_handle_t * pamh, int pamerrno,
52 char *fmt, va_list args);
55 static char truncated[] = " (truncated)";
56 static int log_open = 0;
63 openlog(prog_name, LOG_PID, SYSLOG_FACILITY);
78 /* Construct the message string from its parts, and append a string to it */
80 make_msg(const char *append, char *fmt, va_list args)
85 if ((msg = calloc(1, MAX_MSG + 1)) == 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);
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);
97 strcpy(msg + (MAX_MSG - 1) - sizeof(truncated), truncated);
103 /* log a simple string to syslog if needed */
105 log_syslog_str(int priority, char *msg)
109 syslog(priority, "%s", msg);
114 /* log a simple string to console if needed */
116 log_console_str(char *msg)
118 if (foreground == 1) {
119 time_t t = time(NULL);
125 strftime(date, sizeof(date), "%H:%M:%S", ft);
126 fprintf(stderr, "%s %s\n", date, msg);
131 /* log a simple string to fd if needed */
133 log_fd_str(int fd, char *msg)
136 send(fd, msg, strlen(msg), 0);
137 send(fd, "\n", strlen("\n"), 0);
141 /* Log a message, described by "fmt" and "args", with the specified
143 /* write it also to fd if positive, and to stderr if foreground==1 */
145 log_syslog(int priority, int fd, char *fmt, va_list args)
149 if ((msg = make_msg(NULL, fmt, args)) == NULL)
152 log_syslog_str(priority, msg);
153 log_console_str(msg);
159 /* Same as log_syslog(), but also appends an error description corresponding
162 log_e(int priority, char *fmt, va_list args)
169 if ((msg = make_msg(strerror(saved_errno), fmt, args)) == NULL)
172 log_syslog_str(priority, msg);
173 log_console_str(msg);
180 /* Same as log_syslog(), but also appends an error description corresponding
181 * to the pam_error. */
183 log_pame(int priority, pam_handle_t * pamh, int pamerrno, char *fmt,
188 if ((msg = make_msg(pam_strerror(pamh, pamerrno), fmt, args)) == NULL)
191 log_syslog_str(priority, msg);
192 log_console_str(msg);
201 /* Log an "explain" level message */
203 explain(char *fmt, ...)
208 log_syslog(EXPLAIN_LEVEL, -1, fmt, args);
212 /* as explain(), but also write message to fd if positive */
214 explain_fd(int fd, char *fmt, ...)
219 log_syslog(EXPLAIN_LEVEL, fd, fmt, args);
224 /* Log an "explain" level message, with an error description */
226 explain_e(char *fmt, ...)
231 log_e(EXPLAIN_LEVEL, fmt, args);
236 /* Log a "warning" level message */
243 log_syslog(WARNING_LEVEL, -1, fmt, args);
247 /* as warn(), but also write message to fd if positive */
249 warn_fd(int fd, char *fmt, ...)
254 log_syslog(WARNING_LEVEL, fd, fmt, args);
259 /* Log a "warning" level message, with an error description */
261 warn_e(char *fmt, ...)
266 log_e(WARNING_LEVEL, fmt, args);
271 /* Log a "complain" level message */
273 error(char *fmt, ...)
278 log_syslog(COMPLAIN_LEVEL, -1, fmt, args);
282 /* as error(), but also write message to fd if positive */
284 error_fd(int fd, char *fmt, ...)
289 log_syslog(COMPLAIN_LEVEL, fd, fmt, args);
294 /* Log a "complain" level message, with an error description */
296 error_e(char *fmt, ...)
301 log_e(COMPLAIN_LEVEL, fmt, args);
307 /* Log a "complain" level message, with a PAM error description */
309 error_pame(pam_handle_t * pamh, int pamerrno, char *fmt, ...)
313 xcloselog(); /* PAM is likely to have used openlog() */
316 log_pame(COMPLAIN_LEVEL, pamh, pamerrno, fmt, args);
321 /* Log a "complain" level message, and exit */
328 log_syslog(COMPLAIN_LEVEL, -1, fmt, args);
330 if (getpid() == daemon_pid) {
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.");
343 /* Log a "complain" level message, with an error description, and exit */
345 die_e(char *fmt, ...)
353 log_e(COMPLAIN_LEVEL, fmt, args);
355 if (getpid() == daemon_pid) {
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.");
369 /* Log a "complain" level message, with a PAM error description, and exit */
371 die_pame(pam_handle_t * pamh, int pamerrno, char *fmt, ...)
375 xcloselog(); /* PAM is likely to have used openlog() */
378 log_pame(COMPLAIN_LEVEL, pamh, pamerrno, fmt, args);
380 pam_end(pamh, pamerrno);
381 if (getpid() == daemon_pid)
389 /* Log a "debug" level message */
391 Debug(char *fmt, ...)
396 log_syslog(DEBUG_LEVEL, -1, fmt, args);
400 /* write message to fd, and to syslog in "debug" level message if debug_opt */
402 send_msg_fd_debug(int fd, char *fmt, ...)
410 if ((msg = make_msg(NULL, fmt, args)) == NULL)
414 log_syslog_str(DEBUG_LEVEL, msg);
423 /* write message to fd */
425 send_msg_fd(int fd, char *fmt, ...)
433 if ((msg = make_msg(NULL, fmt, args)) == NULL)