* `LICENSE' that comes with the fcron source distribution.
*/
- /* $Id: log.c,v 1.14 2003-12-25 22:41:03 thib Exp $ */
+ /* $Id: log.c,v 1.15 2004-08-17 12:49:19 thib Exp $ */
/* This code is inspired by Anacron's sources of
Itai Tzur <itzur@actcom.co.il> */
#include "log.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+
static void xopenlog(void);
+char* make_msg(const char *append, char *fmt, va_list args);
+void log_syslog_str(int priority, char *msg);
+void log_console_str(char *msg);
+void log_fd_str(int fd, char *msg);
+static void log_syslog(int priority, int fd, char *fmt, va_list args);
+static void log_e(int priority, char *fmt, va_list args);
+#ifdef HAVE_LIBPAM
+static void log_pame(int priority, pam_handle_t *pamh, int pamerrno,
+ char *fmt, va_list args);
+#endif
static char truncated[] = " (truncated)";
-static int log_open=0;
+static int log_open = 0;
static void
}
-/* Construct the message string from its parts */
+/* Construct the message string from its parts, and append a string to it */
char *
-make_msg(char *fmt, va_list args)
+make_msg(const char *append, char *fmt, va_list args)
{
int len;
char *msg = NULL;
-
+
if ( (msg = calloc(1, MAX_MSG + 1)) == NULL )
return NULL;
/* There's some confusion in the documentation about what vsnprintf
* returns when the buffer overflows. Hmmm... */
len = vsnprintf(msg, MAX_MSG + 1, fmt, args);
+ if ( append != NULL ) {
+ strncat(msg, ": ", MAX_MSG-len);
+ strncat(msg, append, MAX_MSG-len);
+ len += 2 + strlen(append);
+ }
if (len >= MAX_MSG)
strcpy(msg + (MAX_MSG - 1) - sizeof(truncated), truncated);
}
-/* Log a message, described by "fmt" and "args", with the specified
- * "priority". */
-static void
-log(int priority, char *fmt, va_list args)
+/* log a simple string to syslog if needed */
+void
+log_syslog_str(int priority, char *msg)
{
- char *msg;
-
- if ( (msg = make_msg(fmt, args)) == NULL)
- return;
-
if (dosyslog) {
xopenlog();
syslog(priority, "%s", msg);
}
+}
+
+/* log a simple string to console if needed */
+void
+log_console_str(char *msg)
+{
if (foreground == 1) {
time_t t = time(NULL);
struct tm *ft;
fprintf(stderr, "%s %s\n", date, msg);
}
+}
- free(msg);
+/* log a simple string to fd if needed */
+void
+log_fd_str(int fd, char *msg)
+{
+ if ( fd >= 0 ) {
+ send(fd, msg, strlen(msg), 0);
+ send(fd, "\n", strlen("\n"), 0);
+ }
}
+/* Log a message, described by "fmt" and "args", with the specified
+ * "priority". */
+/* write it also to fd if positive, and to stderr if foreground==1 */
+static void
+log_syslog(int priority, int fd, char *fmt, va_list args)
+{
+ char *msg;
-/* Same as log(), but also appends an error description corresponding
+ if ( (msg = make_msg(NULL, fmt, args)) == NULL)
+ return;
+
+ log_syslog_str(priority, msg);
+ log_console_str(msg);
+ log_fd_str(fd, msg);
+
+ free(msg);
+}
+
+/* Same as log_syslog(), but also appends an error description corresponding
* to "errno". */
static void
log_e(int priority, char *fmt, va_list args)
saved_errno=errno;
- if ( (msg = make_msg(fmt, args)) == NULL )
+ if ( (msg = make_msg(strerror(saved_errno), fmt, args)) == NULL )
return ;
- if ( dosyslog ) {
- xopenlog();
- syslog(priority, "%s: %s", msg, strerror(saved_errno));
- }
-
- if (foreground == 1) {
- time_t t = time(NULL);
- struct tm *ft;
- char date[30];
+ log_syslog_str(priority, msg);
+ log_console_str(msg);
- ft = localtime(&t);
- date[0] = '\0';
- strftime(date, sizeof(date), "%H:%M:%S", ft);
- fprintf(stderr, "%s %s: %s\n", date, msg, strerror(saved_errno));
- }
+ free(msg);
}
#ifdef HAVE_LIBPAM
-/* Same as log(), but also appends an error description corresponding
+/* Same as log_syslog(), but also appends an error description corresponding
* to the pam_error. */
static void
log_pame(int priority, pam_handle_t *pamh, int pamerrno, char *fmt, va_list args)
{
char *msg;
- if ( (msg = make_msg(fmt, args)) == NULL )
+ if ( (msg = make_msg(pam_strerror(pamh, pamerrno), fmt, args)) == NULL )
return ;
- xopenlog();
- syslog(priority, "%s: %s", msg, pam_strerror(pamh, pamerrno));
+ log_syslog_str(priority, msg);
+ log_console_str(msg);
- if (foreground == 1) {
- time_t t = time(NULL);
- struct tm *ft;
- char date[30];
-
- ft = localtime(&t);
- date[0] = '\0';
- strftime(date, sizeof(date), "%H:%M:%S", ft);
- fprintf(stderr, "%s %s: %s\n", date, msg, pam_strerror(pamh, pamerrno));
- }
xcloselog();
+
+ free(msg);
}
#endif
va_list args;
va_start(args, fmt);
- log(EXPLAIN_LEVEL, fmt, args);
+ log_syslog(EXPLAIN_LEVEL, -1, fmt, args);
+ va_end(args);
+}
+
+/* as explain(), but also write message to fd if positive */
+void
+explain_fd(int fd, char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ log_syslog(EXPLAIN_LEVEL, fd, fmt, args);
va_end(args);
}
va_list args;
va_start(args, fmt);
- log(WARNING_LEVEL, fmt, args);
+ log_syslog(WARNING_LEVEL, -1, fmt, args);
+ va_end(args);
+}
+
+/* as warn(), but also write message to fd if positive */
+void
+warn_fd(int fd, char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ log_syslog(WARNING_LEVEL, fd, fmt, args);
va_end(args);
}
va_list args;
va_start(args, fmt);
- log(COMPLAIN_LEVEL, fmt, args);
+ log_syslog(COMPLAIN_LEVEL, -1, fmt, args);
+ va_end(args);
+}
+
+/* as error(), but also write message to fd if positive */
+void
+error_fd(int fd, char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ log_syslog(COMPLAIN_LEVEL, fd, fmt, args);
va_end(args);
}
va_list args;
va_start(args, fmt);
- log(COMPLAIN_LEVEL, fmt, args);
+ log_syslog(COMPLAIN_LEVEL, -1, fmt, args);
va_end(args);
if (getpid() == daemon_pid) error("Aborted");
}
#endif
+/* Log a "debug" level message */
void
Debug(char *fmt, ...)
{
va_list args;
va_start(args, fmt);
- log(DEBUG_LEVEL, fmt, args);
+ log_syslog(DEBUG_LEVEL, -1, fmt, args);
+ va_end(args);
+}
+
+/* write message to fd, and to syslog in "debug" level message if debug_opt */
+void
+send_msg_fd_debug(int fd, char *fmt, ...)
+{
+ char *msg;
+
+ va_list args;
+
+ va_start(args, fmt);
+
+ if ( (msg = make_msg(NULL, fmt, args)) == NULL)
+ return;
+
+ if ( debug_opt )
+ log_syslog_str(DEBUG_LEVEL, msg);
+
+ log_fd_str(fd, msg);
+
+ free(msg);
+
+ va_end(args);
+}
+
+/* write message to fd */
+void
+send_msg_fd(int fd, char *fmt, ...)
+{
+ char *msg;
+
+ va_list args;
+
+ va_start(args, fmt);
+
+ if ( (msg = make_msg(NULL, fmt, args)) == NULL)
+ return;
+
+ log_fd_str(fd, msg);
+
+ free(msg);
+
va_end(args);
}