1 /* $NetBSD: rwho.c,v 1.14 2003/08/07 11:15:47 agc Exp $ */ 2 3 /* 4 * Copyright (c) 1983, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 #ifndef lint 34 __COPYRIGHT("@(#) Copyright (c) 1983, 1993\n\ 35 The Regents of the University of California. All rights reserved.\n"); 36 #endif /* not lint */ 37 38 #ifndef lint 39 /*static char sccsid[] = "from: @(#)rwho.c 8.1 (Berkeley) 6/6/93";*/ 40 __RCSID("$NetBSD: rwho.c,v 1.14 2003/08/07 11:15:47 agc Exp $"); 41 #endif /* not lint */ 42 43 #include <sys/param.h> 44 #include <sys/file.h> 45 46 #include <protocols/rwhod.h> 47 48 #include <dirent.h> 49 #include <err.h> 50 #include <errno.h> 51 #include <locale.h> 52 #include <stdio.h> 53 #include <stdlib.h> 54 #include <string.h> 55 #include <time.h> 56 #include <fcntl.h> 57 #include <unistd.h> 58 59 void usage(void); 60 int utmpcmp(const void *, const void *); 61 62 DIR *dirp; 63 64 struct whod wd; 65 #define NUSERS 1000 66 struct myutmp { 67 char myhost[MAXHOSTNAMELEN]; 68 int myidle; 69 struct outmp myutmp; 70 } myutmp[NUSERS]; 71 int nusers; 72 73 #define WHDRSIZE (sizeof (wd) - sizeof (wd.wd_we)) 74 /* 75 * this macro should be shared with ruptime. 76 */ 77 #define down(w,now) ((now) - (w)->wd_recvtime > 11 * 60) 78 79 int utmpcmp __P((const void *, const void *)); 80 int main __P((int, char **)); 81 82 time_t now; 83 int aflg; 84 85 int 86 main(int argc, char **argv) 87 { 88 int ch; 89 struct dirent *dp; 90 int cc, width; 91 struct whod *w = &wd; 92 struct whoent *we; 93 struct myutmp *mp; 94 int f, n, i, nhosts; 95 96 setlocale(LC_TIME, ""); 97 98 while ((ch = getopt(argc, argv, "a")) != -1) 99 switch((char)ch) { 100 case 'a': 101 aflg = 1; 102 break; 103 case '?': 104 default: 105 usage(); 106 } 107 108 if(optind != argc) 109 usage(); 110 111 if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL) 112 err(1, "%s", _PATH_RWHODIR); 113 114 mp = myutmp; 115 nhosts = 0; 116 (void)time(&now); 117 while ((dp = readdir(dirp)) != NULL) { 118 if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5)) 119 continue; 120 f = open(dp->d_name, O_RDONLY); 121 if (f < 0) 122 continue; 123 cc = read(f, (char *)&wd, sizeof (struct whod)); 124 if (cc < WHDRSIZE) { 125 (void) close(f); 126 continue; 127 } 128 nhosts++; 129 if (down(w,now)) { 130 (void) close(f); 131 continue; 132 } 133 cc -= WHDRSIZE; 134 we = w->wd_we; 135 for (n = cc / sizeof (struct whoent); n > 0; n--) { 136 if (aflg == 0 && we->we_idle >= 60*60) { 137 we++; 138 continue; 139 } 140 if (nusers >= NUSERS) 141 err(1, "too many users"); 142 143 mp->myutmp = we->we_utmp; mp->myidle = we->we_idle; 144 (void) strcpy(mp->myhost, w->wd_hostname); 145 nusers++; we++; mp++; 146 } 147 (void) close(f); 148 } 149 if (nhosts == 0) 150 errx(0, "no hosts in %s.", _PATH_RWHODIR); 151 qsort((char *)myutmp, nusers, sizeof (struct myutmp), utmpcmp); 152 mp = myutmp; 153 width = 0; 154 for (i = 0; i < nusers; i++) { 155 int j = strlen(mp->myhost) + 1 + strlen(mp->myutmp.out_line); 156 if (j > width) 157 width = j; 158 mp++; 159 } 160 mp = myutmp; 161 for (i = 0; i < nusers; i++) { 162 char buf[BUFSIZ], cbuf[80]; 163 strftime(cbuf, sizeof(cbuf), "%c", localtime((time_t *)&mp->myutmp.out_time)); 164 /* cbuf = ctime((time_t *)&mp->myutmp.out_time); */ 165 (void)sprintf(buf, "%s:%s", mp->myhost, mp->myutmp.out_line); 166 printf("%-8.8s %-*s %.12s", 167 mp->myutmp.out_name, 168 width, 169 buf, 170 cbuf + 4); 171 mp->myidle /= 60; 172 if (mp->myidle) { 173 if (aflg) { 174 if (mp->myidle >= 100*60) 175 mp->myidle = 100*60 - 1; 176 if (mp->myidle >= 60) 177 printf(" %2d", mp->myidle / 60); 178 else 179 printf(" "); 180 } else 181 printf(" "); 182 printf(":%02d", mp->myidle % 60); 183 } 184 printf("\n"); 185 mp++; 186 } 187 exit(0); 188 } 189 190 int 191 utmpcmp(const void *v1, const void *v2) 192 { 193 const struct myutmp *u1, *u2; 194 int rc; 195 196 u1 = v1; 197 u2 = v2; 198 rc = strncmp(u1->myutmp.out_name, u2->myutmp.out_name, 8); 199 if (rc) 200 return (rc); 201 rc = strcmp(u1->myhost, u2->myhost); 202 if (rc) 203 return (rc); 204 return (strncmp(u1->myutmp.out_line, u2->myutmp.out_line, 8)); 205 } 206 207 void 208 usage(void) 209 { 210 fprintf(stderr, "usage: rwho [-a]\n"); 211 exit(1); 212 } 213