From nick@pancake.earlsfort.iol.ie  Mon Jul 10 06:01:28 2000
Return-Path: <nick@pancake.earlsfort.iol.ie>
Received: from pancake.earlsfort.iol.ie (pancake.earlsfort.iol.ie [194.125.21.11])
	by hub.freebsd.org (Postfix) with ESMTP id 1F0A737B91A
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 10 Jul 2000 06:01:27 -0700 (PDT)
	(envelope-from nick@pancake.earlsfort.iol.ie)
Received: (from nick@localhost)
	by pancake.earlsfort.iol.ie (8.9.1/8.9.1) id OAA24927;
	Mon, 10 Jul 2000 14:01:24 +0100 (IST)
Message-Id: <200007101301.OAA24927@pancake.earlsfort.iol.ie>
Date: Mon, 10 Jul 2000 14:01:24 +0100 (IST)
From: nick@iol.ie
Sender: nick@pancake.earlsfort.iol.ie
Reply-To: nick@iol.ie
To: FreeBSD-gnats-submit@freebsd.org
Subject: extra "-h" option for logger(1) to log to a remote host
X-Send-Pr-Version: 3.2

>Number:         19821
>Category:       bin
>Synopsis:       logger(1) does not log messages to a remote host.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    dwmalone
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jul 10 06:10:01 PDT 2000
>Closed-Date:    Thu Aug 17 11:53:37 PDT 2000
>Last-Modified:  Thu Aug 17 11:54:00 PDT 2000
>Originator:     Nick Hilliard
>Release:        FreeBSD 2.2.6-RELEASE i386 and onwards
>Organization:
Ireland On-Line
>Environment:

	(not relevant)

>Description:

	There are a bunch of circumstances where the ability to send
	syslog messages to a remote host is convenience.  This patch
	adds a new option to logger(1), "-h", which specifies the host
	to send the syslog message to.

>How-To-Repeat:

	(not relevant)

>Fix:

Apply the following patch.
	
--- logger.c.old	Wed Jun 30 12:04:32 1999
+++ logger.c	Wed Jun 30 12:37:40 1999
@@ -42,9 +42,15 @@
 static char sccsid[] = "@(#)logger.c	8.1 (Berkeley) 6/6/93";
 #endif
 static const char rcsid[] =
-	"$Id: logger.c,v 1.2.2.3 1997/09/15 08:32:18 jkh Exp $";
+	"$Id: logger.c,v 1.2 1998/01/29 17:28:54 nick Exp $";
 #endif /* not lint */
 
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
 #include <ctype.h>
 #include <err.h>
 #include <stdio.h>
@@ -57,8 +63,11 @@
 
 int	decode __P((char *, CODE *));
 int	pencode __P((char *));
+void	logmessage __P((int, char *, char *));
 static void	usage __P((void));
 
+#define MAXBUF 1024
+
 /*
  * logger -- read and log utility
  *
@@ -71,13 +80,13 @@
 	char *argv[];
 {
 	int ch, logflags, pri;
-	char *tag, buf[1024];
+	char *tag, *host, buf[MAXBUF];
 
-	tag = NULL;
+	host = tag = NULL;
 	pri = LOG_NOTICE;
 	logflags = 0;
 	unsetenv("TZ");
-	while ((ch = getopt(argc, argv, "f:ip:st:")) != -1)
+	while ((ch = getopt(argc, argv, "f:h:ip:st:")) != -1)
 		switch((char)ch) {
 		case 'f':		/* file to log */
 			if (freopen(optarg, "r", stdin) == NULL)
@@ -95,6 +104,9 @@
 		case 't':		/* tag */
 			tag = optarg;
 			break;
+		case 'h':
+			host = optarg;	/* hostname to deliver to */
+			break;
 		case '?':
 		default:
 			usage();
@@ -114,11 +126,11 @@
 		for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) {
 			len = strlen(*argv);
 			if (p + len > endp && p > buf) {
-				syslog(pri, "%s", buf);
+				logmessage(pri, host, buf);
 				p = buf;
 			}
 			if (len > sizeof(buf) - 1)
-				syslog(pri, "%s", *argv++);
+				logmessage(pri, host, *argv++);
 			else {
 				if (p != buf)
 					*p++ = ' ';
@@ -127,14 +139,76 @@
 			}
 		}
 		if (p != buf)
-			syslog(pri, "%s", buf);
+			logmessage(pri, host, buf);
 	} else
 		while (fgets(buf, sizeof(buf), stdin) != NULL)
-			syslog(pri, "%s", buf);
+			logmessage(pri, host, buf);
 	exit(0);
 }
 
 /*
+ *  Send the message to syslog, either on the local host, or on a remote host
+ */
+void 
+logmessage(int pri, char *host, char *buf)
+{
+	static int sock = -1;
+	static struct sockaddr_in sin;
+
+	struct msghdr msg;
+	struct iovec iov[1];
+	ssize_t size;
+	struct in_addr in;
+	struct servent *sp;
+	struct hostent *hp = NULL;
+	char line[MAXBUF + sizeof("<nnnnnnnnnnn>")];	/* int is always < 11 chars */
+
+	if (host == NULL) {
+		syslog(pri, "%s", buf);
+		return;
+	}
+
+	if (sock == -1) {	/* set up socket stuff */
+		if ((sp = getservbyname("syslog", "udp")) == NULL)
+			warnx ("syslog/udp: unknown service");	/* not fatal */
+
+		/* resolve hostname */
+		if (!(inet_aton (host, &in)) && !(hp = gethostbyname(host))) {
+			errx (1, "unknown host: %s", host);
+		}
+		if (hp != NULL)
+			memcpy ((void *)&in.s_addr, hp->h_addr, 
+				sizeof(struct in_addr));
+
+		/* set up struct sockaddr_in */
+		sin.sin_family = AF_INET;
+		sin.sin_port = (sp == NULL ? 514 : sp->s_port);
+		memcpy ((void *)&sin.sin_addr, (void *)&in.s_addr,
+			sizeof(struct in_addr));
+
+		sock = socket (PF_INET, SOCK_DGRAM, 0);
+		if (sock < 0)
+			errx(1, "socket");
+	}
+
+	msg.msg_name = (void *)&sin;
+	msg.msg_namelen = sizeof sin;
+	msg.msg_iov = iov;
+	msg.msg_iovlen = 0;
+	msg.msg_control = 0;
+	msg.msg_controllen = 0;
+	msg.msg_flags = 0;
+
+	snprintf (line, sizeof (line) - 1, "<%d>%s", pri, buf);
+	
+	iov[msg.msg_iovlen].iov_base = line;
+	iov[msg.msg_iovlen++].iov_len = strlen(line);
+	                        
+	if (sendmsg (sock, &msg, 0) < strlen(line))
+		warnx ("sendmsg");
+}
+
+/*
  *  Decode a symbolic name to a numeric value
  */
 int
@@ -183,6 +257,6 @@
 usage()
 {
 	(void)fprintf(stderr,
-	    "usage: logger [-is] [-f file] [-p pri] [-t tag] [message ...]\n");
+	    "usage: logger [-is] [-f file] [-p pri] [-t tag] [-h host] [message ...]\n");
 	exit(1);
 }
--- logger.1.old	Wed Jun 30 12:38:27 1999
+++ logger.1	Wed Jun 30 12:42:48 1999
@@ -43,6 +43,7 @@
 .Op Fl f Ar file
 .Op Fl p Ar pri
 .Op Fl t Ar tag
+.Op Fl h Ar host
 .Op Ar message ...
 .Sh DESCRIPTION
 .Nm Logger
@@ -73,6 +74,10 @@
 .It Fl t Ar tag 
 Mark every line in the log with the specified
 .Ar tag  .
+.It Fl h Ar host 
+Send the message to the remote system 
+.Ar host
+instead of logging it locally.
 .It Ar message
 Write the message to log; if not specified, and the
 .Fl f

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->dwmalone 
Responsible-Changed-By: dwmalone 
Responsible-Changed-When: Sun Jul 16 02:39:19 PDT 2000 
Responsible-Changed-Why:  
I'll have a look at this. 
. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=19821 

From: David Malone <dwmalone@maths.tcd.ie>
To: nick@enigma.ie
Cc: FreeBSD-gnats-submit@freebsd.org, sheldon@freebsd.org
Subject: Re: bin/19821: extra "-h" option for logger(1) to log to a remote host
Date: Mon, 17 Jul 2000 00:36:49 +0100

 I've cleaned up the patch a tiny bit, and being able to log to
 remote hosts seems useful. Logger seems relatively untouched,
 so I'm not sure who would be interested in OKing this feature.
 
 	David.
 
 Index: logger.1
 ===================================================================
 RCS file: /cvs/FreeBSD-CVS/src/usr.bin/logger/logger.1,v
 retrieving revision 1.5
 diff -u -r1.5 logger.1
 --- logger.1	2000/03/26 14:39:03	1.5
 +++ logger.1	2000/07/16 22:12:41
 @@ -44,6 +44,7 @@
  .Op Fl f Ar file
  .Op Fl p Ar pri
  .Op Fl t Ar tag
 +.Op Fl h Ar host
  .Op Ar message ...
  .Sh DESCRIPTION
  .Nm Logger
 @@ -73,6 +74,10 @@
  .It Fl t Ar tag 
  Mark every line in the log with the specified
  .Ar tag  .
 +.It Fl h Ar host 
 +Send the message to the remote system 
 +.Ar host
 +instead of logging it locally.
  .It Ar message
  Write the message to log; if not specified, and the
  .Fl f
 Index: logger.c
 ===================================================================
 RCS file: /cvs/FreeBSD-CVS/src/usr.bin/logger/logger.c,v
 retrieving revision 1.5
 diff -u -r1.5 logger.c
 --- logger.c	1999/08/28 01:03:08	1.5
 +++ logger.c	2000/07/16 23:09:48
 @@ -45,8 +45,14 @@
    "$FreeBSD: src/usr.bin/logger/logger.c,v 1.5 1999/08/28 01:03:08 peter Exp $";
  #endif /* not lint */
  
 +#include <sys/types.h>
 +#include <sys/socket.h>
 +
 +#include <netinet/in.h>
 +
  #include <ctype.h>
  #include <err.h>
 +#include <netdb.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
 @@ -57,6 +63,7 @@
  
  int	decode __P((char *, CODE *));
  int	pencode __P((char *));
 +void	logmessage __P((int, char *, char *));
  static void	usage __P((void));
  
  /*
 @@ -71,13 +78,13 @@
  	char *argv[];
  {
  	int ch, logflags, pri;
 -	char *tag, buf[1024];
 +	char *tag, *host, buf[1024];
  
 -	tag = NULL;
 +	host = tag = NULL;
  	pri = LOG_NOTICE;
  	logflags = 0;
  	unsetenv("TZ");
 -	while ((ch = getopt(argc, argv, "f:ip:st:")) != -1)
 +	while ((ch = getopt(argc, argv, "f:h:ip:st:")) != -1)
  		switch((char)ch) {
  		case 'f':		/* file to log */
  			if (freopen(optarg, "r", stdin) == NULL)
 @@ -95,6 +102,9 @@
  		case 't':		/* tag */
  			tag = optarg;
  			break;
 +		case 'h':
 +			host = optarg;	/* hostname to deliver to */
 +			break;
  		case '?':
  		default:
  			usage();
 @@ -114,11 +124,11 @@
  		for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) {
  			len = strlen(*argv);
  			if (p + len > endp && p > buf) {
 -				syslog(pri, "%s", buf);
 +				logmessage(pri, host, buf);
  				p = buf;
  			}
  			if (len > sizeof(buf) - 1)
 -				syslog(pri, "%s", *argv++);
 +				logmessage(pri, host, *argv++);
  			else {
  				if (p != buf)
  					*p++ = ' ';
 @@ -127,14 +137,62 @@
  			}
  		}
  		if (p != buf)
 -			syslog(pri, "%s", buf);
 +			logmessage(pri, host, buf);
  	} else
  		while (fgets(buf, sizeof(buf), stdin) != NULL)
 -			syslog(pri, "%s", buf);
 +			logmessage(pri, host, buf);
  	exit(0);
  }
  
  /*
 + *  Send the message to syslog, either on the local host, or on a remote host
 + */
 +void 
 +logmessage(int pri, char *host, char *buf)
 +{
 +	static int sock = -1;
 +	static struct sockaddr_in sin;
 +	char *line;
 +	int len;
 +
 +	if (host == NULL) {
 +		syslog(pri, "%s", buf);
 +		return;
 +	}
 +
 +	if (sock == -1) {	/* set up socket stuff */
 +		struct servent *sp;
 +		struct hostent *hp = NULL;
 +
 +		sin.sin_family = AF_INET;
 +
 +		if ((sp = getservbyname("syslog", "udp")) == NULL)
 +			warnx ("syslog/udp: unknown service");	/* not fatal */
 +		sin.sin_port = (sp == NULL ? htons(514) : sp->s_port);
 +
 +		/* resolve hostname */
 +		if (!(inet_aton(host, &sin.sin_addr)) &&
 +		    (hp = gethostbyname(host)) == NULL)
 +			errx(1, "unknown host: %s", host);
 +		if (hp != NULL)
 +			memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
 +
 +		sock = socket(PF_INET, SOCK_DGRAM, 0);
 +		if (sock < 0)
 +			errx(1, "socket");
 +	}
 +
 +	if ((len = asprintf(&line, "<%d>%s", pri, buf)) == -1)
 +		errx(1, "asprintf");
 +
 +	if (sendto(sock, line, len, 0, (struct sockaddr *)&sin, sizeof(sin))
 +	    < len)
 +		warnx ("sendmsg");
 +
 +	free(line);
 +}
 +
 +/*
   *  Decode a symbolic name to a numeric value
   */
  int
 @@ -183,6 +241,7 @@
  usage()
  {
  	(void)fprintf(stderr,
 -	    "usage: logger [-is] [-f file] [-p pri] [-t tag] [message ...]\n");
 +	    "usage: logger [-is] [-f file] [-h host] [-p pri] [-t tag]"
 +	    " [message ...]\n");
  	exit(1);
  }
 
State-Changed-From-To: open->closed 
State-Changed-By: dwmalone 
State-Changed-When: Thu Aug 17 11:53:37 PDT 2000 
State-Changed-Why:  
MFC'ed by Paul Sabb. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=19821 
>Unformatted:
