rwhod.c

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

C
652
字号
			struct whoent *we;			/* undo header byte swapping before writing to file */			wd.wd_sendtime = ntohl(wd.wd_sendtime);			for (i = 0; i < 3; i++)				wd.wd_loadav[i] = ntohl(wd.wd_loadav[i]);			wd.wd_boottime = ntohl(wd.wd_boottime);			we = wd.wd_we;			for (i = 0; i < n; i++) {				we->we_idle = ntohl(we->we_idle);				we->we_utmp.out_time =				    ntohl(we->we_utmp.out_time);				we++;			}		}#endif		(void) time(&wd.wd_recvtime);		(void) write(whod, (char *)&wd, cc);		if (fstat(whod, &st) < 0 || st.st_size > cc)			ftruncate(whod, cc);		(void) close(whod);	}}/* * Check out host name for unprintables * and other funnies before allowing a file * to be created.  Sorry, but blanks aren't allowed. */verify(name)	register char *name;{	register int size = 0;	while (*name) {		if (!isascii(*name) || !(isalnum(*name) || ispunct(*name)))			return (0);		if (isupper(*name))			*name = tolower(*name);		name++, size++;	}	return (size > 0);}int	utmptime;int	utmpent;int	utmpsize = 0;struct	utmp *utmp;int	alarmcount;voidonalrm(){	register int i;	struct stat stb;	register struct whoent *we = mywd.wd_we, *wlast;	int cc;#ifdef vax	double avenrun[3];#endif#ifdef mips	fix avenrun[3];#endif	time_t now = time(0);	register struct neighbor *np;	if (alarmcount % 10 == 0)		getkmem();	alarmcount++;	(void) fstat(utmpf, &stb);	if ((stb.st_mtime != utmptime) || (stb.st_size > utmpsize)) {		utmptime = stb.st_mtime;		if (stb.st_size > utmpsize) {			utmpsize = stb.st_size + 10 * sizeof(struct utmp);			if (utmp)				utmp = (struct utmp *)realloc(utmp, utmpsize);			else				utmp = (struct utmp *)malloc(utmpsize);			if (! utmp) {				fprintf(stderr, "rwhod: malloc failed\n");				utmpsize = 0;				goto done;			}		}		(void) lseek(utmpf, (long)0, L_SET);		cc = read(utmpf, (char *)utmp, stb.st_size);		if (cc < 0) {			perror("/etc/utmp");			goto done;		}		wlast = &mywd.wd_we[1024 / sizeof (struct whoent) - 1];		utmpent = cc / sizeof (struct utmp);		for (i = 0; i < utmpent; i++)			if (utmp[i].ut_name[0]) {				bcopy(utmp[i].ut_line, we->we_utmp.out_line,				   sizeof (utmp[i].ut_line));				bcopy(utmp[i].ut_name, we->we_utmp.out_name,				   sizeof (utmp[i].ut_name));				we->we_utmp.out_time = htonl(utmp[i].ut_time);				if (we >= wlast)					break;				we++;			}		utmpent = we - mywd.wd_we;	}	we = mywd.wd_we;	for (i = 0; i < utmpent; i++) {		if (stat(we->we_utmp.out_line, &stb) >= 0)			we->we_idle = htonl(now - stb.st_atime);		we++;	}	(void) lseek(kmemf, (long)nl[NL_AVENRUN].n_value, L_SET);	(void) read(kmemf, (char *)avenrun, sizeof (avenrun));	for (i = 0; i < 3; i++)#ifdef vax		mywd.wd_loadav[i] = htonl((u_long)(avenrun[i] * 100));#endif#ifdef mips		mywd.wd_loadav[i] = htonl((u_long)(FIX_TO_DBL(avenrun[i]) * 100));#endif	cc = (char *)we - (char *)&mywd;	mywd.wd_sendtime = htonl(time(0));	mywd.wd_vers = WHODVERSION;	mywd.wd_type = WHODTYPE_STATUS;	for (np = neighbors; np != NULL; np = np->n_next) {		(void) sendto(s, (char *)&mywd, cc, 0,			np->n_addr, np->n_addrlen);#ifdef DEBUG		(void) lsendto(s, (char *)&mywd, cc, 0,			np->n_addr, np->n_addrlen);#endif	}done:	(void) alarm(AL_INTERVAL);}voidgetkmem(){	static ino_t vmunixino;	static time_t vmunixctime;	struct stat sb;	if (stat("/vmunix", &sb) < 0) {		if (vmunixctime)			return;	} else {		if (sb.st_ctime == vmunixctime && sb.st_ino == vmunixino)			return;		vmunixctime = sb.st_ctime;		vmunixino= sb.st_ino;	}	if (kmemf >= 0)		(void) close(kmemf);loop:	if (nlist("/vmunix", nl)) {		syslog(LOG_WARNING, "/vmunix namelist botch");		sleep(300);		goto loop;	}	kmemf = open("/dev/kmem", O_RDONLY);	if (kmemf < 0) {		syslog(LOG_ERR, "/dev/kmem: %m");		exit(1);	}	(void) lseek(kmemf, (long)nl[NL_BOOTTIME].n_value, L_SET);	(void) read(kmemf, (char *)&mywd.wd_boottime,	    sizeof (mywd.wd_boottime));	mywd.wd_boottime = htonl(mywd.wd_boottime);}/* * Figure out device configuration and select * networks which deserve status information. */configure(s)	int s;{	char buf[BUFSIZ];	struct ifconf ifc;	struct ifreq ifreq, *ifr;	struct sockaddr_in *sin;	register struct neighbor *np;	int n;	ifc.ifc_len = sizeof (buf);	ifc.ifc_buf = buf;	if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {		syslog(LOG_ERR, "ioctl (get interface configuration)");		return (0);	}	ifr = ifc.ifc_req;	for (n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifr++) {		for (np = neighbors; np != NULL; np = np->n_next)			if (np->n_name &&			    strcmp(ifr->ifr_name, np->n_name) == 0)				break;		if (np != NULL)			continue;		ifreq = *ifr;		np = (struct neighbor *)malloc(sizeof (*np));		if (np == NULL)			continue;		np->n_name = malloc(strlen(ifr->ifr_name) + 1);		if (np->n_name == NULL) {			free((char *)np);			continue;		}		strcpy(np->n_name, ifr->ifr_name);#ifdef DEBUG	printf("configure, name: %s\n", np->n_name);#endif		np->n_addrlen = sizeof (ifr->ifr_addr);		np->n_addr = malloc(np->n_addrlen);		if (np->n_addr == NULL) {			free(np->n_name);			free((char *)np);			continue;		}		bcopy((char *)&ifr->ifr_addr, np->n_addr, np->n_addrlen);		if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {			syslog(LOG_ERR, "ioctl (get interface flags)");			free((char *)np);			continue;		}		if ((ifreq.ifr_flags & IFF_UP) == 0 ||		    (ifreq.ifr_flags & (IFF_BROADCAST|IFF_POINTOPOINT)) == 0) {			free((char *)np);			continue;		}		np->n_flags = ifreq.ifr_flags;		if (np->n_flags & IFF_POINTOPOINT) {			if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {				syslog(LOG_ERR, "ioctl (get dstaddr)");				free((char *)np);				continue;			}			/* we assume addresses are all the same size */			bcopy((char *)&ifreq.ifr_dstaddr,			  np->n_addr, np->n_addrlen);		}		if (np->n_flags & IFF_BROADCAST) {			if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {				syslog(LOG_ERR, "ioctl (get broadaddr)");				free((char *)np);				continue;			}			/* we assume addresses are all the same size */			bcopy((char *)&ifreq.ifr_broadaddr,			  np->n_addr, np->n_addrlen);		}		/* gag, wish we could get rid of Internet dependencies */		sin = (struct sockaddr_in *)np->n_addr;		sin->sin_port = port;		np->n_next = neighbors;		neighbors = np;	}	return (1);}#ifdef DEBUGlsendto(s, buf, cc, flags, to, tolen)	int s;	char *buf;	int cc, flags;	char *to;	int tolen;{	register struct whod *w = (struct whod *)buf;	register struct whoent *we;	struct sockaddr_in *sin = (struct sockaddr_in *)to;	char *interval();	printf("sendto %x.%d\n", ntohl(sin->sin_addr), ntohs(sin->sin_port));	printf("hostname %s %s\n", w->wd_hostname,	   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);	cc -= WHDRSIZE;	for (we = w->wd_we, cc /= sizeof (struct whoent); cc > 0; cc--, we++) {		time_t t = 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);		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 >= 60)				printf(" %2d", we->we_idle / 60);			else				printf("   ");			printf(":%02d", we->we_idle % 60);		}		printf("\n");	}}char *interval(time, updown)	int time;	char *updown;{	static char resbuf[32];	int days, hours, minutes;	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)		(void) sprintf(resbuf, "%s %2d+%02d:%02d",		    updown, days, hours, minutes);	else		(void) sprintf(resbuf, "%s    %2d:%02d",		    updown, hours, minutes);	return (resbuf);}#endif

⌨️ 快捷键说明

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