rwho.c revision 20156
11590Srgrimes/* 21590Srgrimes * Copyright (c) 1983, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 341590Srgrimes#ifndef lint 351590Srgrimesstatic char copyright[] = 361590Srgrimes"@(#) Copyright (c) 1983, 1993\n\ 371590Srgrimes The Regents of the University of California. All rights reserved.\n"; 381590Srgrimes#endif /* not lint */ 391590Srgrimes 401590Srgrimes#ifndef lint 411590Srgrimesstatic char sccsid[] = "@(#)rwho.c 8.1 (Berkeley) 6/6/93"; 421590Srgrimes#endif /* not lint */ 431590Srgrimes 441590Srgrimes#include <sys/param.h> 451590Srgrimes#include <sys/file.h> 461590Srgrimes#include <protocols/rwhod.h> 4718485Sbde#include <dirent.h> 4820156Sache#include <locale.h> 491590Srgrimes#include <stdio.h> 5020156Sache#include <string.h> 519992Sache#include <time.h> 5220156Sache#include <utmp.h> 531590Srgrimes 541590SrgrimesDIR *dirp; 551590Srgrimes 561590Srgrimesstruct whod wd; 571590Srgrimesint utmpcmp(); 581590Srgrimes#define NUSERS 1000 591590Srgrimesstruct myutmp { 601590Srgrimes char myhost[MAXHOSTNAMELEN]; 611590Srgrimes int myidle; 621590Srgrimes struct outmp myutmp; 631590Srgrimes} myutmp[NUSERS]; 641590Srgrimesint nusers; 651590Srgrimes 661590Srgrimes#define WHDRSIZE (sizeof (wd) - sizeof (wd.wd_we)) 678874Srgrimes/* 681590Srgrimes * this macro should be shared with ruptime. 691590Srgrimes */ 701590Srgrimes#define down(w,now) ((now) - (w)->wd_recvtime > 11 * 60) 711590Srgrimes 721590Srgrimestime_t now; 731590Srgrimesint aflg; 741590Srgrimes 751590Srgrimesmain(argc, argv) 761590Srgrimes int argc; 771590Srgrimes char **argv; 781590Srgrimes{ 791590Srgrimes extern char *optarg; 801590Srgrimes extern int optind; 811590Srgrimes int ch; 8218485Sbde struct dirent *dp; 831590Srgrimes int cc, width; 841590Srgrimes register struct whod *w = &wd; 851590Srgrimes register struct whoent *we; 861590Srgrimes register struct myutmp *mp; 871590Srgrimes int f, n, i; 881590Srgrimes 8911758Sache (void) setlocale(LC_TIME, ""); 9011758Sache 911590Srgrimes while ((ch = getopt(argc, argv, "a")) != EOF) 921590Srgrimes switch((char)ch) { 931590Srgrimes case 'a': 941590Srgrimes aflg = 1; 951590Srgrimes break; 961590Srgrimes case '?': 971590Srgrimes default: 981590Srgrimes fprintf(stderr, "usage: rwho [-a]\n"); 991590Srgrimes exit(1); 1001590Srgrimes } 1011590Srgrimes if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL) { 1021590Srgrimes perror(_PATH_RWHODIR); 1031590Srgrimes exit(1); 1041590Srgrimes } 1051590Srgrimes mp = myutmp; 1061590Srgrimes (void)time(&now); 1071590Srgrimes while (dp = readdir(dirp)) { 1081590Srgrimes if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5)) 1091590Srgrimes continue; 1101590Srgrimes f = open(dp->d_name, O_RDONLY); 1111590Srgrimes if (f < 0) 1121590Srgrimes continue; 1131590Srgrimes cc = read(f, (char *)&wd, sizeof (struct whod)); 1141590Srgrimes if (cc < WHDRSIZE) { 1151590Srgrimes (void) close(f); 1161590Srgrimes continue; 1171590Srgrimes } 1181590Srgrimes if (down(w,now)) { 1191590Srgrimes (void) close(f); 1201590Srgrimes continue; 1211590Srgrimes } 1221590Srgrimes cc -= WHDRSIZE; 1231590Srgrimes we = w->wd_we; 1241590Srgrimes for (n = cc / sizeof (struct whoent); n > 0; n--) { 1251590Srgrimes if (aflg == 0 && we->we_idle >= 60*60) { 1261590Srgrimes we++; 1271590Srgrimes continue; 1281590Srgrimes } 1291590Srgrimes if (nusers >= NUSERS) { 1301590Srgrimes printf("too many users\n"); 1311590Srgrimes exit(1); 1321590Srgrimes } 1331590Srgrimes mp->myutmp = we->we_utmp; mp->myidle = we->we_idle; 1341590Srgrimes (void) strcpy(mp->myhost, w->wd_hostname); 1351590Srgrimes nusers++; we++; mp++; 1361590Srgrimes } 1371590Srgrimes (void) close(f); 1381590Srgrimes } 1391590Srgrimes qsort((char *)myutmp, nusers, sizeof (struct myutmp), utmpcmp); 1401590Srgrimes mp = myutmp; 1411590Srgrimes width = 0; 1421590Srgrimes for (i = 0; i < nusers; i++) { 1435239Sats /* append one for the blank and use 8 for the out_line */ 1445239Sats int j = strlen(mp->myhost) + 1 + 8; 1451590Srgrimes if (j > width) 1461590Srgrimes width = j; 1471590Srgrimes mp++; 1481590Srgrimes } 1491590Srgrimes mp = myutmp; 1501590Srgrimes for (i = 0; i < nusers; i++) { 1519992Sache char buf[BUFSIZ], cbuf[80]; 1529992Sache strftime(cbuf, sizeof(cbuf), "%c", localtime((time_t *)&mp->myutmp.out_time)); 15320156Sache (void)sprintf(buf, "%s:%-.*s", mp->myhost, UT_LINESIZE, mp->myutmp.out_line); 15420156Sache printf("%-*.*s %-*s %.12s", 15520156Sache UT_NAMESIZE, UT_NAMESIZE, 1561590Srgrimes mp->myutmp.out_name, 1571590Srgrimes width, 1581590Srgrimes buf, 1599992Sache cbuf + 4); 1601590Srgrimes mp->myidle /= 60; 1611590Srgrimes if (mp->myidle) { 1621590Srgrimes if (aflg) { 1631590Srgrimes if (mp->myidle >= 100*60) 1641590Srgrimes mp->myidle = 100*60 - 1; 1651590Srgrimes if (mp->myidle >= 60) 1661590Srgrimes printf(" %2d", mp->myidle / 60); 1671590Srgrimes else 1681590Srgrimes printf(" "); 1691590Srgrimes } else 1701590Srgrimes printf(" "); 1711590Srgrimes printf(":%02d", mp->myidle % 60); 1721590Srgrimes } 1731590Srgrimes printf("\n"); 1741590Srgrimes mp++; 1751590Srgrimes } 1761590Srgrimes exit(0); 1771590Srgrimes} 1781590Srgrimes 1791590Srgrimesutmpcmp(u1, u2) 1801590Srgrimes struct myutmp *u1, *u2; 1811590Srgrimes{ 1821590Srgrimes int rc; 1831590Srgrimes 18420156Sache rc = strncmp(u1->myutmp.out_name, u2->myutmp.out_name, UT_NAMESIZE); 1851590Srgrimes if (rc) 1861590Srgrimes return (rc); 18720156Sache rc = strncmp(u1->myhost, u2->myhost, UT_HOSTSIZE); 1881590Srgrimes if (rc) 1891590Srgrimes return (rc); 19020156Sache return (strncmp(u1->myutmp.out_line, u2->myutmp.out_line, UT_LINESIZE)); 1911590Srgrimes} 192