xref: /original-bsd/usr.bin/rwho/rwho.c (revision 183db9ee)
1 /*
2  * Copyright (c) 1983 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 char copyright[] =
20 "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
21  All rights reserved.\n";
22 #endif /* not lint */
23 
24 #ifndef lint
25 static char sccsid[] = "@(#)rwho.c	5.3 (Berkeley) 08/25/88";
26 #endif /* not lint */
27 
28 #include <sys/param.h>
29 #include <sys/dir.h>
30 #include <sys/file.h>
31 #include <protocols/rwhod.h>
32 #include <stdio.h>
33 
34 DIR	*dirp;
35 
36 struct	whod wd;
37 int	utmpcmp();
38 #define	NUSERS	1000
39 struct	myutmp {
40 	char	myhost[MAXHOSTNAMELEN];
41 	int	myidle;
42 	struct	outmp myutmp;
43 } myutmp[NUSERS];
44 int	nusers;
45 
46 #define	WHDRSIZE	(sizeof (wd) - sizeof (wd.wd_we))
47 #define	RWHODIR		"/usr/spool/rwho"
48 /*
49  * this macro should be shared with ruptime.
50  */
51 #define	down(w,now)	((now) - (w)->wd_recvtime > 11 * 60)
52 
53 char	*ctime(), *strcpy();
54 time_t	now;
55 int	aflg;
56 
57 main(argc, argv)
58 	int argc;
59 	char **argv;
60 {
61 	extern char *optarg;
62 	extern int optind;
63 	int ch;
64 	struct direct *dp;
65 	int cc, width;
66 	register struct whod *w = &wd;
67 	register struct whoent *we;
68 	register struct myutmp *mp;
69 	int f, n, i;
70 	time_t time();
71 
72 	while ((ch = getopt(argc, argv, "a")) != EOF)
73 		switch((char)ch) {
74 		case 'a':
75 			aflg = 1;
76 			break;
77 		case '?':
78 		default:
79 			fprintf(stderr, "usage: rwho [-a]\n");
80 			exit(1);
81 		}
82 	if (chdir(RWHODIR) || (dirp = opendir(".")) == NULL) {
83 		perror(RWHODIR);
84 		exit(1);
85 	}
86 	mp = myutmp;
87 	(void)time(&now);
88 	while (dp = readdir(dirp)) {
89 		if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5))
90 			continue;
91 		f = open(dp->d_name, O_RDONLY);
92 		if (f < 0)
93 			continue;
94 		cc = read(f, (char *)&wd, sizeof (struct whod));
95 		if (cc < WHDRSIZE) {
96 			(void) close(f);
97 			continue;
98 		}
99 		if (down(w,now)) {
100 			(void) close(f);
101 			continue;
102 		}
103 		cc -= WHDRSIZE;
104 		we = w->wd_we;
105 		for (n = cc / sizeof (struct whoent); n > 0; n--) {
106 			if (aflg == 0 && we->we_idle >= 60*60) {
107 				we++;
108 				continue;
109 			}
110 			if (nusers >= NUSERS) {
111 				printf("too many users\n");
112 				exit(1);
113 			}
114 			mp->myutmp = we->we_utmp; mp->myidle = we->we_idle;
115 			(void) strcpy(mp->myhost, w->wd_hostname);
116 			nusers++; we++; mp++;
117 		}
118 		(void) close(f);
119 	}
120 	qsort((char *)myutmp, nusers, sizeof (struct myutmp), utmpcmp);
121 	mp = myutmp;
122 	width = 0;
123 	for (i = 0; i < nusers; i++) {
124 		int j = strlen(mp->myhost) + 1 + strlen(mp->myutmp.out_line);
125 		if (j > width)
126 			width = j;
127 		mp++;
128 	}
129 	mp = myutmp;
130 	for (i = 0; i < nusers; i++) {
131 		char buf[BUFSIZ];
132 		(void)sprintf(buf, "%s:%s", mp->myhost, mp->myutmp.out_line);
133 		printf("%-8.8s %-*s %.12s",
134 		   mp->myutmp.out_name,
135 		   width,
136 		   buf,
137 		   ctime((time_t *)&mp->myutmp.out_time)+4);
138 		mp->myidle /= 60;
139 		if (mp->myidle) {
140 			if (aflg) {
141 				if (mp->myidle >= 100*60)
142 					mp->myidle = 100*60 - 1;
143 				if (mp->myidle >= 60)
144 					printf(" %2d", mp->myidle / 60);
145 				else
146 					printf("   ");
147 			} else
148 				printf(" ");
149 			printf(":%02d", mp->myidle % 60);
150 		}
151 		printf("\n");
152 		mp++;
153 	}
154 	exit(0);
155 }
156 
157 utmpcmp(u1, u2)
158 	struct myutmp *u1, *u2;
159 {
160 	int rc;
161 
162 	rc = strncmp(u1->myutmp.out_name, u2->myutmp.out_name, 8);
163 	if (rc)
164 		return (rc);
165 	rc = strncmp(u1->myhost, u2->myhost, 8);
166 	if (rc)
167 		return (rc);
168 	return (strncmp(u1->myutmp.out_line, u2->myutmp.out_line, 8));
169 }
170