xref: /original-bsd/usr.bin/rwho/rwho.c (revision b3b53e97)
1 #ifndef lint
2 static char sccsid[] = "@(#)rwho.c	4.1 82/04/02";
3 #endif
4 
5 #include <sys/types.h>		/* botch in ndir.h */
6 #include <stdio.h>
7 #include <ndir.h>
8 #include <utmp.h>
9 #include "rwhod.h"
10 
11 DIR	*etc;
12 
13 struct	whod wd;
14 int	utmpcmp();
15 #define	NUSERS	1000
16 struct	myutmp {
17 	char	myhost[32];
18 	int	myidle;
19 	struct	utmp myutmp;
20 } myutmp[NUSERS];
21 int	nusers;
22 
23 #define	WHDRSIZE	(sizeof (wd) - sizeof (wd.wd_we))
24 
25 char	*ctime(), *strcpy();
26 int	now;
27 int	aflg;
28 
29 main(argc, argv)
30 	int argc;
31 	char **argv;
32 {
33 	struct direct *dp;
34 	int cc, width;
35 	register struct whod *w = &wd;
36 	register struct whoent *we;
37 	register struct myutmp *mp;
38 	int f, n, i;
39 
40 	argc--, argv++;
41 again:
42 	if (argc > 0 && !strcmp(argv[0], "-a")) {
43 		argc--, argv++;
44 		aflg++;
45 		goto again;
46 	}
47 	(void) time(&now);
48 	if (chdir("/etc") < 0) {
49 		perror("/etc");
50 		exit(1);
51 	}
52 	etc = opendir(".");
53 	if (etc == NULL) {
54 		perror("/etc");
55 		exit(1);
56 	}
57 	mp = myutmp;
58 	while (dp = readdir(etc)) {
59 		if (dp->d_ino == 0)
60 			continue;
61 		if (strncmp(dp->d_name, "whod.", 5))
62 			continue;
63 		f = open(dp->d_name, 0);
64 		if (f < 0)
65 			continue;
66 		cc = read(f, (char *)&wd, sizeof (struct whod));
67 		if (cc < WHDRSIZE) {
68 			(void) close(f);
69 			continue;
70 		}
71 		if (now - w->wd_recvtime > 5 * 60) {
72 			(void) close(f);
73 			continue;
74 		}
75 		cc -= WHDRSIZE;
76 		we = w->wd_we;
77 		for (n = cc / sizeof (struct whoent); n > 0; n--) {
78 			if (aflg == 0 && we->we_idle >= 60*60) {
79 				we++;
80 				continue;
81 			}
82 			if (nusers >= NUSERS) {
83 				printf("too many users\n");
84 				exit(1);
85 			}
86 			mp->myutmp = we->we_utmp; mp->myidle = we->we_idle;
87 			(void) strcpy(mp->myhost, w->wd_hostname);
88 			nusers++; we++; mp++;
89 		}
90 		(void) close(f);
91 	}
92 	qsort((char *)myutmp, nusers, sizeof (struct myutmp), utmpcmp);
93 	mp = myutmp;
94 	width = 0;
95 	for (i = 0; i < nusers; i++) {
96 		int j = strlen(mp->myhost) + 1 + strlen(mp->myutmp.ut_line);
97 		if (j > width)
98 			width = j;
99 		mp++;
100 	}
101 	mp = myutmp;
102 	for (i = 0; i < nusers; i++) {
103 		char buf[22];
104 		sprintf(buf, "%s:%s", mp->myhost, mp->myutmp.ut_line);
105 		printf("%-8.8s %-*s %.12s",
106 		   mp->myutmp.ut_name,
107 		   width,
108 		   buf,
109 		   ctime((time_t *)&mp->myutmp.ut_time)+4);
110 		mp->myidle /= 60;
111 		if (mp->myidle) {
112 			if (aflg) {
113 				if (mp->myidle >= 100*60)
114 					mp->myidle = 100*60 - 1;
115 				if (mp->myidle >= 60)
116 					printf(" %2d", mp->myidle / 60);
117 				else
118 					printf("   ");
119 			} else
120 				printf(" ");
121 			printf(":%02d", mp->myidle % 60);
122 		}
123 		printf("\n");
124 		mp++;
125 	}
126 	exit(0);
127 }
128 
129 utmpcmp(u1, u2)
130 	struct myutmp *u1, *u2;
131 {
132 	int rc;
133 
134 	rc = strncmp(u1->myutmp.ut_name, u2->myutmp.ut_name, 8);
135 	if (rc)
136 		return (rc);
137 	rc = strncmp(u1->myhost, u2->myhost, 8);
138 	if (rc)
139 		return (rc);
140 	return (strncmp(u1->myutmp.ut_line, u2->myutmp.ut_line, 8));
141 }
142