rwhod.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 652 行 · 第 1/2 页

C
652
字号
#ifndef lintstatic char sccsid[] = "@(#)rwhod.c	4.2	(ULTRIX)	10/12/90";#endif/************************************************************************ *									* *			Copyright (c) 1985,1988 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ *			Modification History * * 09-Jun-89	scott *	Add code to turn off audit for rwhod. * * 09-Jun-88	map *	Changed signal handlers to void. * * 15-Jan-88	lp *	Make broadcast drain input whenever it wakes up. * * 19-Aug-87  logcher *	Added broadcast mode to avoid idle loop caused by constantly *	listening to the line.  Motivation from diskless, when a  *	client can mount the server's /usr/spool/rwho and run with *	broadcast mode. * * 12-Feb-87  rr *	Added currently undocumented switch which is listen only mode *	so that we can choose not to clutter up the network with our *	packets but we can hear everyone elses. Rich Hyde gave me the *	fixes. Really trivial. * 16-Sep-85  larry -- Larry Cohen *	Add 43bsd alpha tape changes for subnet routing	 *	and get correct broadcast address *	Also sends messages to syslog * ************************************************************************/#include <sys/types.h>#include <sys/socket.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/file.h>#include <sys/audit.h>#ifdef mips#include <sys/fixpoint.h>#endif#include <net/if.h>#include <netinet/in.h>#include <nlist.h>#include <stdio.h>#include <signal.h>#include <errno.h>#include <utmp.h>#include <ctype.h>#include <netdb.h>#include <syslog.h>#include <protocols/rwhod.h>#ifdef lint#define DEBUG#endif/* * Alarm interval. Don't forget to change the down time check in ruptime * if this is changed. */#define AL_INTERVAL ((2 * 60)+RANDOM(-5,5))	/* don't forget that srand(seed) is set elsewhere in the program */	/* RANDOM(a,b) gives random # in interval [a,b] */#define RANDOM(a,b)	((a)+(rand() % ((b)-(a)+1)))struct	sockaddr_in sin = { AF_INET };extern	errno;char	myname[MAXHOSTNAMELEN];struct	nlist nl[] = {#define	NL_AVENRUN	0	{ "_avenrun" },#define	NL_BOOTTIME	1	{ "_boottime" },	0};/* * We communicate with each neighbor in * a list constructed at the time we're * started up.  Neighbors are currently * directly connected via a hardware interface. */struct	neighbor {	struct	neighbor *n_next;	char	*n_name;		/* interface name */	char	*n_addr;		/* who to send to */	int	n_addrlen;		/* size of address */	int	n_flags;		/* should forward?, interface flags */};struct	neighbor *neighbors;struct	whod mywd;struct	servent *sp;int	s, utmpf, kmemf = -1;#define	WHDRSIZE	(sizeof (mywd) - sizeof (mywd.wd_we))#define	RWHODIR		"/usr/spool/rwho"void	onalrm();char	*strcpy(), *malloc();long	lseek();void	getkmem();struct	in_addr inet_makeaddr();int port;int listenmode = 0;	/* listen to incoming traffic only */int broadcastmode = 0;	/* broadcast only, do not listen */main(argc, argv)int argc;char *argv[];{	struct sockaddr_in from;	char path[64];	int on = 1;	struct hostent *hp;	struct stat st;	char *cp;	extern char *index(); 	/* turn off audit for rwhod */	audcntl ( SET_PROC_ACNTL, (char *)0, 0, AUDIT_OFF, 0 );	if (getuid()) {		fprintf(stderr, "rwhod: not super user\n");		exit(1);	} 	if ((argc > 1) && (strcmp("-l", argv[1])) == 0) {		 argc--;		 argv++;		 listenmode = 1;	} 	if ((argc > 1) && (strcmp("-b", argv[1])) == 0) {		 argc--;		 argv++;		 broadcastmode = 1;	}	if (listenmode && broadcastmode) {		 listenmode = 0;		 broadcastmode = 0;	}	sp = getservbyname("who", "udp");	if (sp == 0) {		fprintf(stderr, "rwhod: udp/who: unknown service\n");		exit(1);	}	bzero((char *)&sin, sizeof(sin));	sin.sin_family = NULL;	port = sin.sin_port = sp->s_port;	endservent();#ifdef DEBUG	printf("family=%d, port=%d\n", sin.sin_family, ntohs(sin.sin_port));#endif#ifndef DEBUG	if (fork())		exit(0);	{ int s;	  for (s = 0; s < 10; s++)		(void) close(s);	  (void) open("/", 0);	  (void) dup2(0, 1);	  (void) dup2(0, 2);	  s = open("/dev/tty", 2);	  if (s >= 0) {		ioctl(s, TIOCNOTTY, 0);		(void) close(s);	  }	}#endif /* NOT DEBUG */	(void) chdir("/dev");	(void) signal(SIGHUP, getkmem);	openlog("rwhod", LOG_PID);	/*	 * Establish host name as returned by system.	 */	if (gethostname(myname, sizeof (myname) - 1) < 0) {		syslog(LOG_ERR, "gethostname: %m");		exit(1);	}	{		/* set random seed using sum of bytes in name of machine */		/* high probability that each machine will start off at a */		/* different seed! */		register int i,sum;		for (sum=i=0;i<sizeof(myname);i++) sum += myname[i];		srand(time(0)*sum);	}	/* strip domain name */	if ((cp = index(myname, '.')) != NULL)		*cp = '\0';	strncpy(mywd.wd_hostname, myname, sizeof (myname) - 1);	utmpf = open("/etc/utmp", O_RDONLY);	if (utmpf < 0) {		(void) close(creat("/etc/utmp", 0644));		utmpf = open("/etc/utmp", O_RDONLY);	}	if (utmpf < 0) {		syslog(LOG_ERR, "/etc/utmp: %m");		exit(1);	}	getkmem();	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {		syslog(LOG_ERR, "socket: %m");		exit(1);	}	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {		syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");		exit(1);	}	hp = gethostbyname(myname);	if (hp == NULL) {		syslog(LOG_ERR, "%s: don't know my own name", myname);		exit(1);	}	if (bind(s, &sin, sizeof (sin)) < 0) {		syslog(LOG_ERR, "bind: %m");		exit(1);	}	if (!configure(s))		exit(1);	/*	 * If not in listen-only mode, call signal(onalrm) to sleep	 * until awakened by alarm.  Make first onalrm call.	 */	if (! listenmode ) {		 signal(SIGALRM, onalrm);		 onalrm();	}	/*	 * Loop to listen for incoming packets.	 */	for (;;) {		struct whod wd;		int cc, whod, len = sizeof (from);		cc = recvfrom(s, (char *)&wd, sizeof (struct whod), 0,			&from, &len);		/*		 * When -b is specified do not save info in /usr/spool/rwho		 * The read of the socket is still needed so UDP counters		 * don't show lots of dropped packets.		 */		if (broadcastmode)			continue;		if (cc <= 0) {			if (cc < 0 && errno != EINTR)				syslog(LOG_WARNING, "recv: %m");			continue;		}		if (from.sin_port != port) {			syslog(LOG_WARNING, "%d: bad from port",				ntohs(from.sin_port));			continue;		}#ifdef notdef		if (gethostbyname(wd.wd_hostname) == 0) {			syslog(LOG_WARNING, "%s: unknown host",				wd.wd_hostname);			continue;		}#endif		if (wd.wd_vers != WHODVERSION)			continue;		if (wd.wd_type != WHODTYPE_STATUS)			continue;		/* strip domain name from incoming packets */		if ((cp = index(wd.wd_hostname, '.')) != NULL)			*cp = '\0';		if (!verify(wd.wd_hostname)) {			syslog(LOG_WARNING, "malformed host name from %x",				from.sin_addr);			continue;		}		(void) sprintf(path, "%s/whod.%s", RWHODIR, 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);		if (whod < 0) {			syslog(LOG_WARNING, "%s: %m", path);			continue;		}#if vax || pdp11 || mips		{			int i, n = (cc - WHDRSIZE)/sizeof(struct whoent);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?