- djm@cvs.openbsd.org 2011/06/17 21:44:31
     [log.c log.h monitor.c monitor.h monitor_wrap.c monitor_wrap.h sshd.c]
     make the pre-auth privsep slave log via a socketpair shared with the
     monitor rather than /var/empty/dev/log; ok dtucker@ deraadt@ markus@
diff --git a/log.c b/log.c
index 4a8239b..ad5a10b 100644
--- a/log.c
+++ b/log.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.c,v 1.41 2008/06/10 04:50:25 dtucker Exp $ */
+/* $OpenBSD: log.c,v 1.42 2011/06/17 21:44:30 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -56,6 +56,8 @@
 static int log_on_stderr = 1;
 static int log_facility = LOG_AUTH;
 static char *argv0;
+static log_handler_fn *log_handler;
+static void *log_handler_ctx;
 
 extern char *__progname;
 
@@ -260,6 +262,9 @@
 		exit(1);
 	}
 
+	log_handler = NULL;
+	log_handler_ctx = NULL;
+
 	log_on_stderr = on_stderr;
 	if (on_stderr)
 		return;
@@ -327,6 +332,23 @@
 #define MSGBUFSIZ 1024
 
 void
+set_log_handler(log_handler_fn *handler, void *ctx)
+{
+	log_handler = handler;
+	log_handler_ctx = ctx;
+}
+
+void
+do_log2(LogLevel level, const char *fmt,...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	do_log(level, fmt, args);
+	va_end(args);
+}
+
+void
 do_log(LogLevel level, const char *fmt, va_list args)
 {
 #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
@@ -337,6 +359,7 @@
 	char *txt = NULL;
 	int pri = LOG_INFO;
 	int saved_errno = errno;
+	log_handler_fn *tmp_handler;
 
 	if (level > log_level)
 		return;
@@ -375,7 +398,7 @@
 		pri = LOG_ERR;
 		break;
 	}
-	if (txt != NULL) {
+	if (txt != NULL && log_handler == NULL) {
 		snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt);
 		vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args);
 	} else {
@@ -383,7 +406,13 @@
 	}
 	strnvis(fmtbuf, msgbuf, sizeof(fmtbuf),
 	    log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS);
-	if (log_on_stderr) {
+	if (log_handler != NULL) {
+		/* Avoid recursion */
+		tmp_handler = log_handler;
+		log_handler = NULL;
+		tmp_handler(level, fmtbuf, log_handler_ctx);
+		log_handler = tmp_handler;
+	} else if (log_on_stderr) {
 		snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf);
 		write(STDERR_FILENO, msgbuf, strlen(msgbuf));
 	} else {