Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Apr 1999 13:09:02 -0400 (EDT)
From:      Mikhail Teterin <mi@aldan.algebra.com>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/11294: direct logging to other hosts (no local syslogd)
Message-ID:  <199904231709.NAA00535@rtfm.newton>

next in thread | raw e-mail | index | archive | help

>Number:         11294
>Category:       bin
>Synopsis:       direct logging to other hosts (no local syslogd)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 23 10:10:01 PDT 1999
>Closed-Date:
>Last-Modified:
>Originator:     Mikhail Teterin
>Release:        FreeBSD 3.1-STABLE i386
>Organization:
Virtual Estates, Inc,
>Environment:

>Description:

	Currently, there is no easy way to have a working logging
	functionality without syslogd running on the local machine.
	Which may require some more resources on a machine sends
	everything out to a log server anyway.

	Also, a user may want to log something on another machine
	without accessing the local /etc/syslog.conf

	The patches below add two more calls to the syslog(3) family
	and add the `-h' option to logger(1) to take advantage of the
	feature:

		logger -h logserver "This is a test"

>How-To-Repeat:

>Fix:
	
This patches are against the latest -stable:

--- usr.bin/logger/logger.c.orig	Tue Jul 22 03:33:48 1997
+++ usr.bin/logger/logger.c	Mon Apr 12 00:40:33 1999
@@ -72,11 +72,12 @@
 {
 	int ch, logflags, pri;
-	char *tag, buf[1024];
+	char *tag, *host, buf[1024];
 
 	tag = NULL;
+	host = NULL;
 	pri = LOG_NOTICE;
 	logflags = 0;
 	unsetenv("TZ");
-	while ((ch = getopt(argc, argv, "f:ip:st:")) != -1)
+	while ((ch = getopt(argc, argv, "f:ip:st:h:")) != -1)
 		switch((char)ch) {
 		case 'f':		/* file to log */
@@ -96,4 +97,7 @@
 			tag = optarg;
 			break;
+		case 'h':
+			host = optarg;
+			break;
 		case '?':
 		default:
@@ -128,8 +132,8 @@
 		}
 		if (p != buf)
-			syslog(pri, "%s", buf);
+			syslogh(pri, host, "%s", buf);
 	} else
 		while (fgets(buf, sizeof(buf), stdin) != NULL)
-			syslog(pri, "%s", buf);
+			syslogh(pri, host, "%s", buf);
 	exit(0);
 }
--- usr.bin/logger/logger.1.orig	Tue Jul 22 03:33:47 1997
+++ usr.bin/logger/logger.1	Mon Apr 12 01:01:33 1999
@@ -72,2 +72,5 @@
 The default is ``user.notice.''
+.It Fl h Ar host
+Send the message directly to the specified host. This allows you to use
+logger on a machine with no syslogd running, for example.
 .It Fl t Ar tag 
--- lib/libc/gen/syslog.3.orig	Fri Jun  5 05:20:19 1998
+++ lib/libc/gen/syslog.3	Mon Apr 12 01:12:57 1999
@@ -39,2 +39,4 @@
 .Nm vsyslog ,
+.Nm syslogh ,
+.Nm vsyslogh ,
 .Nm openlog ,
@@ -51,2 +53,6 @@
 .Ft void
+.Fn syslogh "int priority" "const char *host" "const char *message" "..."
+.Ft void
+.Fn vsyslogh "int priority" "const char *host" "const char *message" "va_list args"
+.Ft void
 .Fn openlog "const char *ident" "int logopt" "int facility"
@@ -84,2 +90,13 @@
 .Xr varargs 3 .
+.Pp
+.Fn syslogh
+and
+.Fn vsyslogh
+send the message directly to the specified
+.Fa host ,
+allowing you to bypass
+the local syslog-daemon. If the sending fails, it will still be attempted
+to log the message locally, as if
+.Fa host
+was NULL.
 .Pp
--- /usr/src/lib/libc/gen/syslog.c.orig	Fri May  1 15:41:12 1998
+++ /usr/src/lib/libc/gen/syslog.c	Mon Apr 12 00:46:59 1999
@@ -47,2 +47,3 @@
 #include <netdb.h>
+#include <netinet/in.h>
 
@@ -108,25 +109,38 @@
 
-/*
- * syslog, vsyslog --
- *	print message on log file; output is intended for syslogd(8).
- */
-void
-#if __STDC__
-syslog(int pri, const char *fmt, ...)
-#else
-syslog(pri, fmt, va_alist)
-	int pri;
-	char *fmt;
-	va_dcl
-#endif
+static const char * logtohost(host, tbuf, cnt)
+	const char *host;
+	char *tbuf;
+	int   cnt;
 {
-	va_list ap;
+	struct hostent *hp;
+	static int finet;
+	static struct sockaddr_in addr;
+
+	/* initialize */
+	if(!finet) {
+		finet = socket(AF_INET, SOCK_DGRAM, 0);
+		if(finet == -1) {
+			finet = 0;
+			return strerror(errno);
+		}
+	}
+	if(!addr.sin_family) { 
+		struct servent *sp;
+		sp = getservbyname("syslog", "udp");
+		if(sp == NULL)
+			return "syslog/udp: unknown service";
+		addr.sin_port = sp->s_port;
+		addr.sin_family = AF_INET;
+	}
 
-#if __STDC__
-	va_start(ap, fmt);
-#else
-	va_start(ap);
-#endif
-	vsyslog(pri, fmt, ap);
-	va_end(ap);
+	hp = gethostbyname(host);
+	if(hp == NULL)
+		return hstrerror(h_errno);
+	memmove(&addr.sin_addr, hp->h_addr, hp->h_length);
+
+	if(sendto(finet, tbuf, cnt, 0, (struct sockaddr *)&addr,
+						sizeof(addr)) != cnt)
+		return strerror(errno);
+
+	return NULL; /* success */
 }
@@ -134,5 +148,6 @@
 void
-vsyslog(pri, fmt, ap)
+vsyslogh(pri, host, fmt, ap)
 	int pri;
 	register const char *fmt;
+	const char *host;
 	va_list ap;
@@ -240,2 +255,24 @@
 
+	/* If host is specified, try sending the message to it */
+	if(host) {
+		const char *err;
+		err = logtohost(host, tbuf, cnt);
+		if(err == NULL)
+			return; /* sent  successfully */
+		else if(sizeof(tbuf) - cnt > 5) {
+			/* if there is any room in tbuf, append the */
+			/* hostname and the error message from the  */
+			/* logtohost, for it to be logged locally   */
+			strncat(tbuf + cnt++ - 1, " ", 1);
+			strncat(tbuf + cnt - 1, host, sizeof(tbuf) - cnt);
+			cnt += strlen(host);
+			if(sizeof(tbuf) - cnt > 3) {
+				strncat(tbuf + cnt++ - 1, ":", 1);
+				strncat(tbuf + cnt - 1, err,
+						sizeof(tbuf) - cnt);
+				cnt += strlen(err);
+			}
+		}
+	}
+
 	/* Get connected, output the message to the local logger. */
@@ -258,3 +295,3 @@
 	 * Output the message to the console; don't worry about blocking,
-	 * if console blocks everything will.  Make sure the error reported
+	 * if console blocks, everything will.  Make sure the error reported
 	 * is the one from the syslogd failure.
@@ -276,2 +313,63 @@
 }
+
+/*
+ * syslog, vsyslog --
+ *	print message on log file; output is intended for syslogd(8).
+ */
+void
+#if __STDC__
+syslogh(int pri, const char *host, const char *fmt, ...)
+#else
+syslogh(pri, host, fmt, va_alist)
+	int pri;
+	char *fmt;
+	const char *host;
+	va_dcl
+#endif
+{
+	va_list ap;
+
+#if __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	vsyslogh(pri, host, fmt, ap);
+	va_end(ap);
+}
+
+/*
+ * syslog, vsyslog --
+ *	print message on log file; output is intended for syslogd(8).
+ */
+void
+#if __STDC__
+syslog(int pri, const char *fmt, ...)
+#else
+syslog(pri, fmt, va_alist)
+	int pri;
+	char *fmt;
+	va_dcl
+#endif
+{
+	va_list ap;
+
+#if __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	vsyslogh(pri, NULL, fmt, ap);
+	va_end(ap);
+}
+
+void
+vsyslog(pri, fmt, ap)
+	int pri;
+	register const char *fmt;
+	va_list ap;
+{
+	vsyslogh(pri, NULL, fmt, ap);
+}
+
 static void
--- sys/sys/syslog.h.orig	Mon Jul 13 02:45:17 1998
+++ sys/sys/syslog.h	Mon Apr 12 00:44:25 1999
@@ -195,4 +195,7 @@
 void	syslog __P((int, const char *, ...)) __printflike(2, 3);
 void	vsyslog __P((int, const char *, _BSD_VA_LIST_)) __printflike(2, 0);
+void	syslogh __P((int, const char *, const char *, ...)) __printflike(3, 4);
+void	vsyslogh __P((int, const char *, const char *, _BSD_VA_LIST_))
+							__printflike(3, 0);
 __END_DECLS
 

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199904231709.NAA00535>