[Midnightbsd-cvs] src [10339] trunk/usr.sbin/rwhod/rwhod.c: sync rwhod(8)

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Jun 3 16:01:45 EDT 2018


Revision: 10339
          http://svnweb.midnightbsd.org/src/?rev=10339
Author:   laffer1
Date:     2018-06-03 16:01:44 -0400 (Sun, 03 Jun 2018)
Log Message:
-----------
sync rwhod(8)

Modified Paths:
--------------
    trunk/usr.sbin/rwhod/Makefile
    trunk/usr.sbin/rwhod/rwhod.8
    trunk/usr.sbin/rwhod/rwhod.c

Property Changed:
----------------
    trunk/usr.sbin/rwhod/rwhod.8

Modified: trunk/usr.sbin/rwhod/Makefile
===================================================================
--- trunk/usr.sbin/rwhod/Makefile	2018-06-03 20:00:43 UTC (rev 10338)
+++ trunk/usr.sbin/rwhod/Makefile	2018-06-03 20:01:44 UTC (rev 10339)
@@ -1,5 +1,6 @@
+# $MidnightBSD$
 #	@(#)Makefile	8.1 (Berkeley) 6/6/93
-# $MidnightBSD$
+# $FreeBSD: stable/10/usr.sbin/rwhod/Makefile 202206 2010-01-13 18:17:53Z ed $
 
 PROG=	rwhod
 MAN=	rwhod.8

Modified: trunk/usr.sbin/rwhod/rwhod.8
===================================================================
--- trunk/usr.sbin/rwhod/rwhod.8	2018-06-03 20:00:43 UTC (rev 10338)
+++ trunk/usr.sbin/rwhod/rwhod.8	2018-06-03 20:01:44 UTC (rev 10339)
@@ -1,3 +1,4 @@
+.\" $MidnightBSD$
 .\" Copyright (c) 1983, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
 .\"
@@ -26,9 +27,9 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)rwhod.8	8.2 (Berkeley) 12/11/93
-.\" $MidnightBSD$
+.\" $FreeBSD: stable/10/usr.sbin/rwhod/rwhod.8 320646 2017-07-04 15:53:54Z allanjude $
 .\"
-.Dd January 21, 2010
+.Dd July 3, 2017
 .Dt RWHOD 8
 .Os
 .Sh NAME
@@ -40,6 +41,15 @@
 .Op Fl p
 .Op Fl l
 .Op Fl m Op Ar ttl
+.Sh DEPRECATION NOTICE
+.Nm
+is deprecated and will be removed from future versions of the
+.Fx
+base system.
+If
+.Nm
+is still required, it can be installed from ports or packages
+(net/bsdrcmds).
 .Sh DESCRIPTION
 The
 .Nm


Property changes on: trunk/usr.sbin/rwhod/rwhod.8
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Modified: trunk/usr.sbin/rwhod/rwhod.c
===================================================================
--- trunk/usr.sbin/rwhod/rwhod.c	2018-06-03 20:00:43 UTC (rev 10338)
+++ trunk/usr.sbin/rwhod/rwhod.c	2018-06-03 20:01:44 UTC (rev 10339)
@@ -1,6 +1,8 @@
-/*
- * Copyright (c) 1983, 1993
- *	The Regents of the University of California.  All rights reserved.
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1983, 1993 The Regents of the University of California.
+ * Copyright (c) 2013 Mariusz Zaborski <oshogbo at FreeBSD.org>
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -40,14 +42,17 @@
 #endif
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.sbin/rwhod/rwhod.c 312034 2017-01-13 08:40:58Z ngie $");
 
 #include <sys/param.h>
+#include <sys/capsicum.h>
+#include <sys/ioctl.h>
+#include <sys/procdesc.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/signal.h>
-#include <sys/ioctl.h>
 #include <sys/sysctl.h>
+#include <sys/wait.h>
 
 #include <net/if.h>
 #include <net/if_dl.h>
@@ -60,48 +65,18 @@
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <grp.h>
 #include <netdb.h>
 #include <paths.h>
+#include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <syslog.h>
 #include <timeconv.h>
+#include <utmpx.h>
 #include <unistd.h>
-#include <utmpx.h>
-#include <pwd.h>
-#include <grp.h>
 
-/*
- * This version of Berkeley's rwhod has been modified to use IP multicast
- * datagrams, under control of a new command-line option:
- *
- *	rwhod -m	causes rwhod to use IP multicast (instead of
- *			broadcast or unicast) on all interfaces that have
- *			the IFF_MULTICAST flag set in their "ifnet" structs
- *			(excluding the loopback interface).  The multicast
- *			reports are sent with a time-to-live of 1, to prevent
- *			forwarding beyond the directly-connected subnet(s).
- *
- *	rwhod -m <ttl>	causes rwhod to send IP multicast datagrams with a
- *			time-to-live of <ttl>, via a SINGLE interface rather
- *			than all interfaces.  <ttl> must be between 0 and
- *			MAX_MULTICAST_SCOPE, defined below.  Note that "-m 1"
- *			is different than "-m", in that "-m 1" specifies
- *			transmission on one interface only.
- *
- * When "-m" is used without a <ttl> argument, the program accepts multicast
- * rwhod reports from all multicast-capable interfaces.  If a <ttl> argument
- * is given, it accepts multicast reports from only one interface, the one
- * on which reports are sent (which may be controlled via the host's routing
- * table).  Regardless of the "-m" option, the program accepts broadcast or
- * unicast reports from all interfaces.  Thus, this program will hear the
- * reports of old, non-multicasting rwhods, but, if multicasting is used,
- * those old rwhods won't hear the reports generated by this program.
- *
- *                  -- Steve Deering, Stanford University, February 1989
- */
-
 #define	UNPRIV_USER		"daemon"
 #define	UNPRIV_GROUP		"daemon"
 
@@ -112,21 +87,21 @@
 #define MAX_MULTICAST_SCOPE	32	  /* "site-wide", by convention */
 
 #define INADDR_WHOD_GROUP (u_long)0xe0000103      /* 224.0.1.3 */
-					  /* (belongs in protocols/rwhod.h) */
+						  /* (belongs in protocols/rwhod.h) */
 
-int			insecure_mode;
-int			quiet_mode;
-int			iff_flag = IFF_POINTOPOINT;
-int			multicast_mode  = NO_MULTICAST;
-int			multicast_scope;
-struct sockaddr_in	multicast_addr  =
-	{ sizeof multicast_addr, AF_INET, 0, { 0 }, { 0 } };
+int	insecure_mode;
+int	quiet_mode;
+int	iff_flag = IFF_POINTOPOINT;
+int	multicast_mode = NO_MULTICAST;
+int	multicast_scope;
+struct	sockaddr_in multicast_addr =
+	{ sizeof(multicast_addr), AF_INET, 0, { 0 }, { 0 } };
 
 /*
- * Alarm interval. Don't forget to change the down time check in ruptime
+ * Sleep interval. Don't forget to change the down time check in ruptime
  * if this is changed.
  */
-#define AL_INTERVAL (3 * 60)
+#define SL_INTERVAL (3 * 60)
 
 char	myname[MAXHOSTNAMELEN];
 
@@ -137,72 +112,109 @@
  */
 struct	neighbor {
 	struct	neighbor *n_next;
-	char	*n_name;		/* interface name */
+	char		 *n_name;		/* interface name */
 	struct	sockaddr *n_addr;		/* who to send to */
-	int	n_addrlen;		/* size of address */
-	int	n_flags;		/* should forward?, interface flags */
+	int		  n_addrlen;		/* size of address */
+	int		  n_flags;		/* should forward?, interface flags */
 };
 
 struct	neighbor *neighbors;
 struct	whod mywd;
-struct	servent *sp;
+struct	servent	*sp;
 int	s;
+int	fdp;
+pid_t	pid_child_receiver;
 
 #define	WHDRSIZE	(int)(sizeof(mywd) - sizeof(mywd.wd_we))
 
-void	 run_as(uid_t *, gid_t *);
-int	 configure(int);
-void	 getboottime(int);
-void	 onalrm(int);
-void	 quit(const char *);
-void	 rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *);
-int	 verify(char *, int);
+int	configure(int so);
+void	getboottime(int signo __unused);
+void	receiver_process(void);
+void	rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo);
+void	run_as(uid_t *uid, gid_t *gid);
+void	quit(const char *msg);
+void	sender_process(void);
+int	verify(char *name, int maxlen);
 static void usage(void);
+
 #ifdef DEBUG
-char	*interval(int, char *);
-void	 Sendto(int, const void *, size_t, int, const struct sockaddr *, int);
+char	*interval(int time, char *updown);
+void	Sendto(int s, const void *buf, size_t cc, int flags,
+	    const struct sockaddr *to, int tolen);
 #define	 sendto Sendto
 #endif
 
+/*
+ * This version of Berkeley's rwhod has been modified to use IP multicast
+ * datagrams, under control of a new command-line option:
+ *
+ *	rwhod -m	causes rwhod to use IP multicast (instead of
+ *			broadcast or unicast) on all interfaces that have
+ *			the IFF_MULTICAST flag set in their "ifnet" structs
+ *			(excluding the loopback interface).  The multicast
+ *			reports are sent with a time-to-live of 1, to prevent
+ *			forwarding beyond the directly-connected subnet(s).
+ *
+ *	rwhod -m <ttl>	causes rwhod to send IP multicast datagrams with a
+ *			time-to-live of <ttl>, via a SINGLE interface rather
+ *			than all interfaces.  <ttl> must be between 0 and
+ *			MAX_MULTICAST_SCOPE, defined below.  Note that "-m 1"
+ *			is different than "-m", in that "-m 1" specifies
+ *			transmission on one interface only.
+ *
+ * When "-m" is used without a <ttl> argument, the program accepts multicast
+ * rwhod reports from all multicast-capable interfaces.  If a <ttl> argument
+ * is given, it accepts multicast reports from only one interface, the one
+ * on which reports are sent (which may be controlled via the host's routing
+ * table).  Regardless of the "-m" option, the program accepts broadcast or
+ * unicast reports from all interfaces.  Thus, this program will hear the
+ * reports of old, non-multicasting rwhods, but, if multicasting is used,
+ * those old rwhods won't hear the reports generated by this program.
+ *
+ *                  -- Steve Deering, Stanford University, February 1989
+ */
 int
 main(int argc, char *argv[])
 {
-	struct sockaddr_in from;
-	struct stat st;
-	char path[64];
-	int on = 1;
+	int on;
 	char *cp;
 	struct sockaddr_in soin;
 	uid_t unpriv_uid;
 	gid_t unpriv_gid;
 
+	on = 1;
 	if (getuid())
 		errx(1, "not super user");
 
 	run_as(&unpriv_uid, &unpriv_gid);
 
-	argv++; argc--;
+	argv++;
+	argc--;
 	while (argc > 0 && *argv[0] == '-') {
 		if (strcmp(*argv, "-m") == 0) {
 			if (argc > 1 && isdigit(*(argv + 1)[0])) {
-				argv++, argc--;
+				argv++;
+				argc--;
 				multicast_mode  = SCOPED_MULTICAST;
 				multicast_scope = atoi(*argv);
-				if (multicast_scope > MAX_MULTICAST_SCOPE)
+				if (multicast_scope > MAX_MULTICAST_SCOPE) {
 					errx(1, "ttl must not exceed %u",
-					MAX_MULTICAST_SCOPE);
+					    MAX_MULTICAST_SCOPE);
+				}
+			} else {
+				multicast_mode = PER_INTERFACE_MULTICAST;
 			}
-			else multicast_mode = PER_INTERFACE_MULTICAST;
-		}
-		else if (strcmp(*argv, "-i") == 0)
+		} else if (strcmp(*argv, "-i") == 0) {
 			insecure_mode = 1;
-		else if (strcmp(*argv, "-l") == 0)
+		} else if (strcmp(*argv, "-l") == 0) {
 			quiet_mode = 1;
-		else if (strcmp(*argv, "-p") == 0)
+		} else if (strcmp(*argv, "-p") == 0) {
 			iff_flag = 0;
-		else
+		} else {
 			usage();
-		argv++, argc--;
+		}
+		argv++;
+		argc--;
 	}
 	if (argc > 0)
 		usage();
@@ -210,7 +222,7 @@
 	daemon(1, 0);
 #endif
 	(void) signal(SIGHUP, getboottime);
-	openlog("rwhod", LOG_PID, LOG_DAEMON);
+	openlog("rwhod", LOG_PID | LOG_NDELAY, LOG_DAEMON);
 	sp = getservbyname("who", "udp");
 	if (sp == NULL) {
 		syslog(LOG_ERR, "who/udp: unknown service");
@@ -227,10 +239,9 @@
 		syslog(LOG_ERR, "gethostname: %m");
 		exit(1);
 	}
-	if ((cp = index(myname, '.')) != NULL)
+	if ((cp = strchr(myname, '.')) != NULL)
 		*cp = '\0';
-	strncpy(mywd.wd_hostname, myname, sizeof(mywd.wd_hostname) - 1);
-	mywd.wd_hostname[sizeof(mywd.wd_hostname) - 1] = '\0';
+	strlcpy(mywd.wd_hostname, myname, sizeof(mywd.wd_hostname));
 	getboottime(0);
 	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
 		syslog(LOG_ERR, "socket: %m");
@@ -252,7 +263,7 @@
 		syslog(LOG_ERR, "setgid: %m");
 		exit(1);
 	}
-	if (setgroups(1, &unpriv_gid) != 0) { /* XXX BOGUS groups[0] = egid */
+	if (setgroups(1, &unpriv_gid) != 0) {	/* XXX BOGUS groups[0] = egid */
 		syslog(LOG_ERR, "setgroups: %m");
 		exit(1);
 	}
@@ -263,17 +274,110 @@
 	if (!configure(s))
 		exit(1);
 	if (!quiet_mode) {
-		signal(SIGALRM, onalrm);
-		onalrm(0);
+		pid_child_receiver = pdfork(&fdp, 0);
+		if (pid_child_receiver == 0) {
+			receiver_process();
+		} else if (pid_child_receiver > 0) {
+			sender_process();
+		} else if (pid_child_receiver == -1) {
+			if (errno == ENOSYS) {
+				syslog(LOG_ERR,
+				    "The pdfork(2) system call is not available; recompile the kernel with options PROCDESC");
+			} else {
+				syslog(LOG_ERR, "pdfork: %m");
+			}
+			exit(1);
+		}
+	} else {
+		receiver_process();
 	}
+}
+
+static void
+usage(void)
+{
+
+	fprintf(stderr, "usage: rwhod [-i] [-p] [-l] [-m [ttl]]\n");
+	exit(1);
+}
+
+void
+run_as(uid_t *uid, gid_t *gid)
+{
+	struct passwd *pw;
+	struct group *gr;
+
+	pw = getpwnam(UNPRIV_USER);
+	if (pw == NULL) {
+		syslog(LOG_ERR, "getpwnam(%s): %m", UNPRIV_USER);
+		exit(1);
+	}
+	*uid = pw->pw_uid;
+
+	gr = getgrnam(UNPRIV_GROUP);
+	if (gr == NULL) {
+		syslog(LOG_ERR, "getgrnam(%s): %m", UNPRIV_GROUP);
+		exit(1);
+	}
+	*gid = gr->gr_gid;
+}
+
+/*
+ * Check out host name for unprintables
+ * and other funnies before allowing a file
+ * to be created.  Sorry, but blanks aren't allowed.
+ */
+int
+verify(char *name, int maxlen)
+{
+	int size;
+
+	size = 0;
+	while (*name != '\0' && size < maxlen - 1) {
+		if (!isascii((unsigned char)*name) ||
+		    !(isalnum((unsigned char)*name) ||
+		    ispunct((unsigned char)*name))) {
+			return (0);
+		}
+		name++;
+		size++;
+	}
+	*name = '\0';
+	return (size > 0);
+}
+
+void
+receiver_process(void)
+{
+	struct sockaddr_in from;
+	struct stat st;
+	cap_rights_t rights;
+	char path[64];
+	int dirfd;
+	struct whod wd;
+	socklen_t len;
+	int cc, whod;
+	time_t t;
+
+	len = sizeof(from);
+	dirfd = open(".", O_RDONLY | O_DIRECTORY);
+	if (dirfd < 0) {
+		syslog(LOG_WARNING, "%s: %m", _PATH_RWHODIR);
+		exit(1);
+	}
+	cap_rights_init(&rights, CAP_CREATE, CAP_FSTAT, CAP_FTRUNCATE,
+	    CAP_LOOKUP, CAP_SEEK, CAP_WRITE);
+	if (cap_rights_limit(dirfd, &rights) < 0 && errno != ENOSYS) {
+		syslog(LOG_WARNING, "cap_rights_limit: %m");
+		exit(1);
+	}
+	if (cap_enter() < 0 && errno != ENOSYS) {
+		syslog(LOG_ERR, "cap_enter: %m");
+		exit(1);
+	}
 	for (;;) {
-		struct whod wd;
-		socklen_t len = sizeof(from);
-		int cc, whod;
-		time_t t;
-
-		cc = recvfrom(s, (char *)&wd, sizeof(struct whod), 0,
-			(struct sockaddr *)&from, &len);
+		cc = recvfrom(s, &wd, sizeof(wd), 0, (struct sockaddr *)&from,
+		    &len);
 		if (cc <= 0) {
 			if (cc < 0 && errno != EINTR)
 				syslog(LOG_WARNING, "recv: %m");
@@ -293,26 +397,32 @@
 			continue;
 		if (wd.wd_type != WHODTYPE_STATUS)
 			continue;
-		if (!verify(wd.wd_hostname, sizeof wd.wd_hostname)) {
+		if (!verify(wd.wd_hostname, sizeof(wd.wd_hostname))) {
 			syslog(LOG_WARNING, "malformed host name from %s",
 			    inet_ntoa(from.sin_addr));
 			continue;
 		}
-		(void) snprintf(path, sizeof path, "whod.%s", wd.wd_hostname);
+		(void) snprintf(path, sizeof(path), "whod.%s", wd.wd_hostname);
 		/*
 		 * Rather than truncating and growing the file each time,
 		 * use ftruncate if size is less than previous size.
 		 */
-		whod = open(path, O_WRONLY | O_CREAT, 0644);
+		whod = openat(dirfd, path, O_WRONLY | O_CREAT, 0644);
 		if (whod < 0) {
 			syslog(LOG_WARNING, "%s: %m", path);
 			continue;
 		}
+		cap_rights_init(&rights, CAP_FSTAT, CAP_FTRUNCATE, CAP_WRITE);
+		if (cap_rights_limit(whod, &rights) < 0 && errno != ENOSYS) {
+			syslog(LOG_WARNING, "cap_rights_limit: %m");
+			exit(1);
+		}
 #if ENDIAN != BIG_ENDIAN
 		{
-			int i, n = (cc - WHDRSIZE)/sizeof(struct whoent);
 			struct whoent *we;
+			int i, n;
 
+			n = (cc - WHDRSIZE) / sizeof(struct whoent);
 			/* undo header byte swapping before writing to file */
 			wd.wd_sendtime = ntohl(wd.wd_sendtime);
 			for (i = 0; i < 3; i++)
@@ -334,141 +444,104 @@
 			ftruncate(whod, cc);
 		(void) close(whod);
 	}
+	(void) close(dirfd);
 }
 
-static void
-usage()
-{
-	fprintf(stderr, "usage: rwhod [-i] [-p] [-l] [-m [ttl]]\n");
-	exit(1);
-}
-
 void
-run_as(uid, gid)
-	uid_t *uid;
-	gid_t *gid;
+sender_process(void)
 {
-	struct passwd *pw;
-	struct group *gr;
-
-	pw = getpwnam(UNPRIV_USER);
-	if (!pw) {
-		syslog(LOG_ERR, "getpwnam(%s): %m", UNPRIV_USER);
-		exit(1);
-	}
-	*uid = pw->pw_uid;
-
-	gr = getgrnam(UNPRIV_GROUP);
-	if (!gr) {
-		syslog(LOG_ERR, "getgrnam(%s): %m", UNPRIV_GROUP);
-		exit(1);
-	}
-	*gid = gr->gr_gid;
-}
-
-/*
- * Check out host name for unprintables
- * and other funnies before allowing a file
- * to be created.  Sorry, but blanks aren't allowed.
- */
-int
-verify(name, maxlen)
-	register char *name;
-	register int   maxlen;
-{
-	register int size = 0;
-
-	while (*name && size < maxlen - 1) {
-		if (!isascii(*name) || !(isalnum(*name) || ispunct(*name)))
-			return (0);
-		name++, size++;
-	}
-	*name = '\0';
-	return (size > 0);
-}
-
-void
-onalrm(int signo __unused)
-{
-	struct neighbor *np;
-	struct whoent *we = mywd.wd_we, *wend;
-	struct stat stb;
-	struct utmpx *ut;
-	static int alarmcount = 0;
+	int sendcount;
 	double avenrun[3];
 	time_t now;
-	int i, cc;
+	int i, cc, status;
+	struct utmpx *ut;
+	struct stat stb;
+	struct neighbor *np;
+	struct whoent *we, *wend;
 
-	now = time(NULL);
-	if (alarmcount % 10 == 0)
-		getboottime(0);
-	alarmcount++;
-	wend = &mywd.wd_we[1024 / sizeof(struct whoent)];
-	setutxent();
-	while ((ut = getutxent()) != NULL && we < wend) {
-		if (ut->ut_type != USER_PROCESS)
-			continue;
-		strncpy(we->we_utmp.out_line, ut->ut_line,
-		   sizeof(we->we_utmp.out_line));
-		strncpy(we->we_utmp.out_name, ut->ut_user,
-		   sizeof(we->we_utmp.out_name));
-		we->we_utmp.out_time =
-		    htonl(_time_to_time32(ut->ut_tv.tv_sec));
-		we++;
-	}
-	endutxent();
+	sendcount = 0;
+	for (;;) {
+		we = mywd.wd_we;
+		now = time(NULL);
+		if (sendcount % 10 == 0)
+			getboottime(0);
+		sendcount++;
+		wend = &mywd.wd_we[1024 / sizeof(struct whoent)];
+		setutxent();
+		while ((ut = getutxent()) != NULL && we < wend) {
+			if (ut->ut_type != USER_PROCESS)
+				continue;
+			strncpy(we->we_utmp.out_line, ut->ut_line,
+			    sizeof(we->we_utmp.out_line));
+			strncpy(we->we_utmp.out_name, ut->ut_user,
+			    sizeof(we->we_utmp.out_name));
+			we->we_utmp.out_time =
+			    htonl(_time_to_time32(ut->ut_tv.tv_sec));
+			we++;
+		}
+		endutxent();
 
-	if (chdir(_PATH_DEV)) {
-		syslog(LOG_ERR, "chdir(%s): %m", _PATH_DEV);
-		exit(1);
-	}
-	wend = we;
-	for (we = mywd.wd_we; we < wend; we++) {
-		if (stat(we->we_utmp.out_line, &stb) >= 0)
-			we->we_idle = htonl(now - stb.st_atime);
-		we++;
-	}
-	(void)getloadavg(avenrun, sizeof(avenrun)/sizeof(avenrun[0]));
-	for (i = 0; i < 3; i++)
-		mywd.wd_loadav[i] = htonl((u_long)(avenrun[i] * 100));
-	cc = (char *)wend - (char *)&mywd;
-	mywd.wd_sendtime = htonl(_time_to_time32(time(NULL)));
-	mywd.wd_vers = WHODVERSION;
-	mywd.wd_type = WHODTYPE_STATUS;
-	if (multicast_mode == SCOPED_MULTICAST) {
-		(void) sendto(s, (char *)&mywd, cc, 0,
-				(struct sockaddr *)&multicast_addr,
-				sizeof(multicast_addr));
-	}
-	else for (np = neighbors; np != NULL; np = np->n_next) {
-		if (multicast_mode == PER_INTERFACE_MULTICAST &&
-		    np->n_flags & IFF_MULTICAST) {
-			/*
-			 * Select the outgoing interface for the multicast.
-			 */
-			if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF,
-			    &(((struct sockaddr_in *)np->n_addr)->sin_addr),
-			    sizeof(struct in_addr)) < 0) {
-				syslog(LOG_ERR,
-					"setsockopt IP_MULTICAST_IF: %m");
-				exit(1);
+		if (chdir(_PATH_DEV) < 0) {
+			syslog(LOG_ERR, "chdir(%s): %m", _PATH_DEV);
+			exit(1);
+		}
+		wend = we;
+		for (we = mywd.wd_we; we < wend; we++) {
+			if (stat(we->we_utmp.out_line, &stb) >= 0)
+				we->we_idle = htonl(now - stb.st_atime);
+			we++;
+		}
+		(void) getloadavg(avenrun,
+		    sizeof(avenrun) / sizeof(avenrun[0]));
+		for (i = 0; i < 3; i++)
+			mywd.wd_loadav[i] = htonl((u_long)(avenrun[i] * 100));
+		cc = (char *)wend - (char *)&mywd;
+		mywd.wd_sendtime = htonl(_time_to_time32(time(NULL)));
+		mywd.wd_vers = WHODVERSION;
+		mywd.wd_type = WHODTYPE_STATUS;
+		if (multicast_mode == SCOPED_MULTICAST) {
+			(void) sendto(s, (char *)&mywd, cc, 0,
+			    (struct sockaddr *)&multicast_addr,
+			    sizeof(multicast_addr));
+		} else {
+			for (np = neighbors; np != NULL; np = np->n_next) {
+				if (multicast_mode == PER_INTERFACE_MULTICAST &&
+				    (np->n_flags & IFF_MULTICAST) != 0) {
+					/*
+					 * Select the outgoing interface for the
+					 * multicast.
+					 */
+					if (setsockopt(s, IPPROTO_IP,
+					    IP_MULTICAST_IF,
+					    &(((struct sockaddr_in *)np->n_addr)->sin_addr),
+					    sizeof(struct in_addr)) < 0) {
+						syslog(LOG_ERR,
+						    "setsockopt IP_MULTICAST_IF: %m");
+						exit(1);
+					}
+					(void) sendto(s, (char *)&mywd, cc, 0,
+					    (struct sockaddr *)&multicast_addr,
+					    sizeof(multicast_addr));
+				} else {
+					(void) sendto(s, (char *)&mywd, cc, 0,
+					    np->n_addr, np->n_addrlen);
+				}
 			}
-			(void) sendto(s, (char *)&mywd, cc, 0,
-				(struct sockaddr *)&multicast_addr,
-				sizeof(multicast_addr));
-		} else (void) sendto(s, (char *)&mywd, cc, 0,
-					np->n_addr, np->n_addrlen);
+		}
+		if (chdir(_PATH_RWHODIR) < 0) {
+			syslog(LOG_ERR, "chdir(%s): %m", _PATH_RWHODIR);
+			exit(1);
+		}
+		if (waitpid(pid_child_receiver, &status, WNOHANG) ==
+		    pid_child_receiver) {
+			break;
+		}
+		sleep(SL_INTERVAL);
 	}
-	if (chdir(_PATH_RWHODIR)) {
-		syslog(LOG_ERR, "chdir(%s): %m", _PATH_RWHODIR);
-		exit(1);
-	}
-	(void) alarm(AL_INTERVAL);
 }
 
 void
-getboottime(signo)
-	int signo __unused;
+getboottime(int signo __unused)
 {
 	int mib[2];
 	size_t size;
@@ -477,7 +550,7 @@
 	mib[0] = CTL_KERN;
 	mib[1] = KERN_BOOTTIME;
 	size = sizeof(tm);
-	if (sysctl(mib, 2, &tm, &size, NULL, 0) == -1) {
+	if (sysctl(mib, nitems(mib), &tm, &size, NULL, 0) == -1) {
 		syslog(LOG_ERR, "cannot get boottime: %m");
 		exit(1);
 	}
@@ -485,26 +558,25 @@
 }
 
 void
-quit(msg)
-	const char *msg;
+quit(const char *msg)
 {
+
 	syslog(LOG_ERR, "%s", msg);
 	exit(1);
 }
 
 void
-rt_xaddrs(cp, cplim, rtinfo)
-	register caddr_t cp, cplim;
-	register struct rt_addrinfo *rtinfo;
+rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo)
 {
-	register struct sockaddr *sa;
-	register int i;
+	struct sockaddr *sa;
+	int i;
 
 	memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info));
-	for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {
+	for (i = 0; i < RTAX_MAX && cp < cplim; i++) {
 		if ((rtinfo->rti_addrs & (1 << i)) == 0)
 			continue;
-		rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;
+		sa = (struct sockaddr *)cp;
+		rtinfo->rti_info[i] = sa;
 		cp += SA_SIZE(sa);
 	}
 }
@@ -514,18 +586,18 @@
  * networks which deserve status information.
  */
 int
-configure(so)
-	int so;
+configure(int so)
 {
-	register struct neighbor *np;
-	register struct if_msghdr *ifm;
-	register struct ifa_msghdr *ifam;
+	struct neighbor *np;
+	struct if_msghdr *ifm;
+	struct ifa_msghdr *ifam;
 	struct sockaddr_dl *sdl;
 	size_t needed;
-	int mib[6], flags = 0, len;
+	int mib[6], flags, lflags, len;
 	char *buf, *lim, *next;
 	struct rt_addrinfo info;
 
+	flags = 0;
 	if (multicast_mode != NO_MULTICAST) {
 		multicast_addr.sin_addr.s_addr = htonl(INADDR_WHOD_GROUP);
 		multicast_addr.sin_port = sp->s_port;
@@ -538,19 +610,19 @@
 		mreq.imr_multiaddr.s_addr = htonl(INADDR_WHOD_GROUP);
 		mreq.imr_interface.s_addr = htonl(INADDR_ANY);
 		if (setsockopt(so, IPPROTO_IP, IP_ADD_MEMBERSHIP,
-					&mreq, sizeof(mreq)) < 0) {
+		    &mreq, sizeof(mreq)) < 0) {
 			syslog(LOG_ERR,
-				"setsockopt IP_ADD_MEMBERSHIP: %m");
-			return(0);
+			    "setsockopt IP_ADD_MEMBERSHIP: %m");
+			return (0);
 		}
 		ttl = multicast_scope;
-		if (setsockopt(so, IPPROTO_IP, IP_MULTICAST_TTL,
-					&ttl, sizeof(ttl)) < 0) {
+		if (setsockopt(so, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
+		    sizeof(ttl)) < 0) {
 			syslog(LOG_ERR,
-				"setsockopt IP_MULTICAST_TTL: %m");
-			return(0);
+			    "setsockopt IP_MULTICAST_TTL: %m");
+			return (0);
 		}
-		return(1);
+		return (1);
 	}
 
 	mib[0] = CTL_NET;
@@ -559,11 +631,11 @@
 	mib[3] = AF_INET;
 	mib[4] = NET_RT_IFLIST;
 	mib[5] = 0;
-	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+	if (sysctl(mib, nitems(mib), NULL, &needed, NULL, 0) < 0)
 		quit("route-sysctl-estimate");
 	if ((buf = malloc(needed)) == NULL)
 		quit("malloc");
-	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
+	if (sysctl(mib, nitems(mib), buf, &needed, NULL, 0) < 0)
 		quit("actual retrieval of interface table");
 	lim = buf + needed;
 
@@ -575,34 +647,38 @@
 			flags = ifm->ifm_flags;
 			continue;
 		}
-		if ((flags & IFF_UP) == 0 ||
-		    (flags & (((multicast_mode == PER_INTERFACE_MULTICAST) ?
-				IFF_MULTICAST : 0) |
-				IFF_BROADCAST|iff_flag)) == 0)
+		if ((flags & IFF_UP) == 0)
 			continue;
+		lflags = IFF_BROADCAST | iff_flag;
+		if (multicast_mode == PER_INTERFACE_MULTICAST)
+			lflags |= IFF_MULTICAST;
+		if ((flags & lflags) == 0)
+			continue;
 		if (ifm->ifm_type != RTM_NEWADDR)
 			quit("out of sync parsing NET_RT_IFLIST");
 		ifam = (struct ifa_msghdr *)ifm;
 		info.rti_addrs = ifam->ifam_addrs;
 		rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam,
-			&info);
+		    &info);
 		/* gag, wish we could get rid of Internet dependencies */
-#define dstaddr	info.rti_info[RTAX_BRD]
-#define ifaddr info.rti_info[RTAX_IFA]
-#define IPADDR_SA(x) ((struct sockaddr_in *)(x))->sin_addr.s_addr
-#define PORT_SA(x) ((struct sockaddr_in *)(x))->sin_port
+#define	dstaddr		info.rti_info[RTAX_BRD]
+#define	ifaddr		info.rti_info[RTAX_IFA]
+#define	IPADDR_SA(x)	((struct sockaddr_in *)(x))->sin_addr.s_addr
+#define	PORT_SA(x)	((struct sockaddr_in *)(x))->sin_port
 		if (dstaddr == 0 || dstaddr->sa_family != AF_INET)
 			continue;
 		PORT_SA(dstaddr) = sp->s_port;
-		for (np = neighbors; np != NULL; np = np->n_next)
+		for (np = neighbors; np != NULL; np = np->n_next) {
 			if (memcmp(sdl->sdl_data, np->n_name,
-				   sdl->sdl_nlen) == 0 &&
-			    IPADDR_SA(np->n_addr) == IPADDR_SA(dstaddr))
+			    sdl->sdl_nlen) == 0 &&
+			    IPADDR_SA(np->n_addr) == IPADDR_SA(dstaddr)) {
 				break;
+			}
+		}
 		if (np != NULL)
 			continue;
 		len = sizeof(*np) + dstaddr->sa_len + sdl->sdl_nlen + 1;
-		np = (struct neighbor *)malloc(len);
+		np = malloc(len);
 		if (np == NULL)
 			quit("malloc of neighbor structure");
 		memset(np, 0, len);
@@ -613,17 +689,17 @@
 		memcpy((char *)np->n_addr, (char *)dstaddr, np->n_addrlen);
 		memcpy(np->n_name, sdl->sdl_data, sdl->sdl_nlen);
 		if (multicast_mode == PER_INTERFACE_MULTICAST &&
-		    (flags & IFF_MULTICAST) &&
-		   !(flags & IFF_LOOPBACK)) {
+		    (flags & IFF_MULTICAST) != 0 &&
+		    (flags & IFF_LOOPBACK) == 0) {
 			struct ip_mreq mreq;
 
 			memcpy((char *)np->n_addr, (char *)ifaddr,
-				np->n_addrlen);
+			    np->n_addrlen);
 			mreq.imr_multiaddr.s_addr = htonl(INADDR_WHOD_GROUP);
 			mreq.imr_interface.s_addr =
-			  ((struct sockaddr_in *)np->n_addr)->sin_addr.s_addr;
+			    ((struct sockaddr_in *)np->n_addr)->sin_addr.s_addr;
 			if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
-						&mreq, sizeof(mreq)) < 0) {
+			    &mreq, sizeof(mreq)) < 0) {
 				syslog(LOG_ERR,
 				    "setsockopt IP_ADD_MEMBERSHIP: %m");
 #if 0
@@ -630,7 +706,7 @@
 				/* Fall back to broadcast on this if. */
 				np->n_flags &= ~IFF_MULTICAST;
 #else
-				free((char *)np);
+				free(np);
 				continue;
 #endif
 			}
@@ -644,22 +720,19 @@
 
 #ifdef DEBUG
 void
-Sendto(s, buf, cc, flags, to, tolen)
-	int s;
-	const void *buf;
-	size_t cc;
-	int flags;
-	const struct sockaddr *to;
-	int tolen;
+Sendto(int s, const void *buf, size_t cc, int flags, const struct sockaddr *to,
+    int tolen)
 {
-	register struct whod *w = (struct whod *)buf;
-	register struct whoent *we;
-	struct sockaddr_in *sin = (struct sockaddr_in *)to;
+	struct whod *w;
+	struct whoent *we;
+	struct sockaddr_in *sin;
 
+	w = (struct whod *)buf;
+	sin = (struct sockaddr_in *)to;
 	printf("sendto %x.%d\n", ntohl(sin->sin_addr.s_addr),
-				 ntohs(sin->sin_port));
+	    ntohs(sin->sin_port));
 	printf("hostname %s %s\n", w->wd_hostname,
-	   interval(ntohl(w->wd_sendtime) - ntohl(w->wd_boottime), "  up"));
+	    interval(ntohl(w->wd_sendtime) - ntohl(w->wd_boottime), "  up"));
 	printf("load %4.2f, %4.2f, %4.2f\n",
 	    ntohl(w->wd_loadav[0]) / 100.0, ntohl(w->wd_loadav[1]) / 100.0,
 	    ntohl(w->wd_loadav[2]) / 100.0);
@@ -666,14 +739,13 @@
 	cc -= WHDRSIZE;
 	for (we = w->wd_we, cc /= sizeof(struct whoent); cc > 0; cc--, we++) {
 		time_t t = _time32_to_time(ntohl(we->we_utmp.out_time));
-		printf("%-8.8s %s:%s %.12s",
-			we->we_utmp.out_name,
-			w->wd_hostname, we->we_utmp.out_line,
-			ctime(&t)+4);
+
+		printf("%-8.8s %s:%s %.12s", we->we_utmp.out_name,
+		    w->wd_hostname, we->we_utmp.out_line, ctime(&t) + 4);
 		we->we_idle = ntohl(we->we_idle) / 60;
-		if (we->we_idle) {
-			if (we->we_idle >= 100*60)
-				we->we_idle = 100*60 - 1;
+		if (we->we_idle != 0) {
+			if (we->we_idle >= 100 * 60)
+				we->we_idle = 100 * 60 - 1;
 			if (we->we_idle >= 60)
 				printf(" %2d", we->we_idle / 60);
 			else
@@ -685,26 +757,27 @@
 }
 
 char *
-interval(time, updown)
-	int time;
-	char *updown;
+interval(int time, char *updown)
 {
 	static char resbuf[32];
 	int days, hours, minutes;
 
-	if (time < 0 || time > 3*30*24*60*60) {
+	if (time < 0 || time > 3 * 30 * 24 * 60 * 60) {
 		(void) sprintf(resbuf, "   %s ??:??", updown);
 		return (resbuf);
 	}
 	minutes = (time + 59) / 60;		/* round to minutes */
-	hours = minutes / 60; minutes %= 60;
-	days = hours / 24; hours %= 24;
-	if (days)
+	hours = minutes / 60;
+	minutes %= 60;
+	days = hours / 24;
+	hours %= 24;
+	if (days > 0) {
 		(void) sprintf(resbuf, "%s %2d+%02d:%02d",
 		    updown, days, hours, minutes);
-	else
+	} else {
 		(void) sprintf(resbuf, "%s    %2d:%02d",
 		    updown, hours, minutes);
+	}
 	return (resbuf);
 }
 #endif



More information about the Midnightbsd-cvs mailing list