xref: /original-bsd/usr.bin/rwho/rwho.c (revision 1364b7d2)
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.4 (Berkeley) 05/11/89";
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 /*
48  * this macro should be shared with ruptime.
49  */
50 #define	down(w,now)	((now) - (w)->wd_recvtime > 11 * 60)
51 
52 char	*ctime(), *strcpy();
53 time_t	now;
54 int	aflg;
55 
56 main(argc, argv)
57 	int argc;
58 	char **argv;
59 {
60 	extern char *optarg;
61 	extern int optind;
62 	int ch;
63 	struct direct *dp;
64 	int cc, width;
65 	register struct whod *w = &wd;
66 	register struct whoent *we;
67 	register struct myutmp *mp;
68 	int f, n, i;
69 	time_t time();
70 
71 	while ((ch = getopt(argc, argv, "a")) != EOF)
72 		switch((char)ch) {
73 		case 'a':
74 			aflg = 1;
75 			break;
76 		case '?':
77 		default:
78 			fprintf(stderr, "usage: rwho [-a]\n");
79 			exit(1);
80 		}
81 	if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL) {
82 		perror(_PATH_RWHODIR);
83 		exit(1);
84 	}
85 	mp = myutmp;
86 	(void)time(&now);
87 	while (dp = readdir(dirp)) {
88 		if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5))
89 			continue;
90 		f = open(dp->d_name, O_RDONLY);
91 		if (f < 0)
92 			continue;
93 		cc = read(f, (char *)&wd, sizeof (struct whod));
94 		if (cc < WHDRSIZE) {
95 			(void) close(f);
96 			continue;
97 		}
98 		if (down(w,now)) {
99 			(void) close(f);
100 			continue;
101 		}
102 		cc -= WHDRSIZE;
103 		we = w->wd_we;
104 		for (n = cc / sizeof (struct whoent); n > 0; n--) {
105 			if (aflg == 0 && we->we_idle >= 60*60) {
106 				we++;
107 				continue;
108 			}
109 			if (nusers >= NUSERS) {
110 				printf("too many users\n");
111 				exit(1);
112 			}
113 			mp->myutmp = we->we_utmp; mp->myidle = we->we_idle;
114 			(void) strcpy(mp->myhost, w->wd_hostname);
115 			nusers++; we++; mp++;
116 		}
117 		(void) close(f);
118 	}
119 	qsort((char *)myutmp, nusers, sizeof (struct myutmp), utmpcmp);
120 	mp = myutmp;
121 	width = 0;
122 	for (i = 0; i < nusers; i++) {
123 		int j = strlen(mp->myhost) + 1 + strlen(mp->myutmp.out_line);
124 		if (j > width)
125 			width = j;
126 		mp++;
127 	}
128 	mp = myutmp;
129 	for (i = 0; i < nusers; i++) {
130 		char buf[BUFSIZ];
131 		(void)sprintf(buf, "%s:%s", mp->myhost, mp->myutmp.out_line);
132 		printf("%-8.8s %-*s %.12s",
133 		   mp->myutmp.out_name,
134 		   width,
135 		   buf,
136 		   ctime((time_t *)&mp->myutmp.out_time)+4);
137 		mp->myidle /= 60;
138 		if (mp->myidle) {
139 			if (aflg) {
140 				if (mp->myidle >= 100*60)
141 					mp->myidle = 100*60 - 1;
142 				if (mp->myidle >= 60)
143 					printf(" %2d", mp->myidle / 60);
144 				else
145 					printf("   ");
146 			} else
147 				printf(" ");
148 			printf(":%02d", mp->myidle % 60);
149 		}
150 		printf("\n");
151 		mp++;
152 	}
153 	exit(0);
154 }
155 
156 utmpcmp(u1, u2)
157 	struct myutmp *u1, *u2;
158 {
159 	int rc;
160 
161 	rc = strncmp(u1->myutmp.out_name, u2->myutmp.out_name, 8);
162 	if (rc)
163 		return (rc);
164 	rc = strncmp(u1->myhost, u2->myhost, 8);
165 	if (rc)
166 		return (rc);
167 	return (strncmp(u1->myutmp.out_line, u2->myutmp.out_line, 8));
168 }
169