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 + -
显示快捷键?