rwho.c revision 35659
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 3527978Scharnierstatic const 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 4127978Scharnier#if 0 421590Srgrimesstatic char sccsid[] = "@(#)rwho.c 8.1 (Berkeley) 6/6/93"; 4327978Scharnier#endif 4427978Scharnierstatic const char rcsid[] = 4535659Ssteve "$Id: rwho.c,v 1.11 1997/08/08 12:20:24 charnier Exp $"; 461590Srgrimes#endif /* not lint */ 471590Srgrimes 481590Srgrimes#include <sys/param.h> 491590Srgrimes#include <sys/file.h> 501590Srgrimes#include <protocols/rwhod.h> 5118485Sbde#include <dirent.h> 5227978Scharnier#include <err.h> 5320156Sache#include <locale.h> 541590Srgrimes#include <stdio.h> 5527978Scharnier#include <stdlib.h> 5620156Sache#include <string.h> 579992Sache#include <time.h> 5827978Scharnier#include <unistd.h> 5920156Sache#include <utmp.h> 601590Srgrimes 611590SrgrimesDIR *dirp; 621590Srgrimes 631590Srgrimesstruct whod wd; 641590Srgrimesint utmpcmp(); 651590Srgrimes#define NUSERS 1000 661590Srgrimesstruct myutmp { 6720165Sache char myhost[sizeof(wd.wd_hostname)]; 681590Srgrimes int myidle; 691590Srgrimes struct outmp myutmp; 701590Srgrimes} myutmp[NUSERS]; 711590Srgrimesint nusers; 721590Srgrimes 731590Srgrimes#define WHDRSIZE (sizeof (wd) - sizeof (wd.wd_we)) 748874Srgrimes/* 751590Srgrimes * this macro should be shared with ruptime. 761590Srgrimes */ 771590Srgrimes#define down(w,now) ((now) - (w)->wd_recvtime > 11 * 60) 781590Srgrimes 791590Srgrimestime_t now; 801590Srgrimesint aflg; 811590Srgrimes 8227978Scharnierstatic void usage __P((void)); 8335659Ssteveint utmpcmp __P((const void *, const void *)); 8427978Scharnier 8527978Scharnierint 861590Srgrimesmain(argc, argv) 871590Srgrimes int argc; 881590Srgrimes char **argv; 891590Srgrimes{ 901590Srgrimes int ch; 9118485Sbde struct dirent *dp; 921590Srgrimes int cc, width; 931590Srgrimes register struct whod *w = &wd; 941590Srgrimes register struct whoent *we; 951590Srgrimes register struct myutmp *mp; 961590Srgrimes int f, n, i; 971590Srgrimes 9811758Sache (void) setlocale(LC_TIME, ""); 9911758Sache 10024360Simp while ((ch = getopt(argc, argv, "a")) != -1) 1011590Srgrimes switch((char)ch) { 1021590Srgrimes case 'a': 1031590Srgrimes aflg = 1; 1041590Srgrimes break; 1051590Srgrimes case '?': 1061590Srgrimes default: 10727978Scharnier usage(); 1081590Srgrimes } 10935659Ssteve argc -= optind; 11035659Ssteve argv += optind; 11135659Ssteve 11235659Ssteve if (argc != 0) 11335659Ssteve usage(); 11435659Ssteve 11527978Scharnier if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL) 11627978Scharnier err(1, "%s", _PATH_RWHODIR); 1171590Srgrimes mp = myutmp; 1181590Srgrimes (void)time(&now); 11927978Scharnier while ((dp = readdir(dirp))) { 1201590Srgrimes if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5)) 1211590Srgrimes continue; 1221590Srgrimes f = open(dp->d_name, O_RDONLY); 1231590Srgrimes if (f < 0) 1241590Srgrimes continue; 1251590Srgrimes cc = read(f, (char *)&wd, sizeof (struct whod)); 1261590Srgrimes if (cc < WHDRSIZE) { 1271590Srgrimes (void) close(f); 1281590Srgrimes continue; 1291590Srgrimes } 1301590Srgrimes if (down(w,now)) { 1311590Srgrimes (void) close(f); 1321590Srgrimes continue; 1331590Srgrimes } 1341590Srgrimes cc -= WHDRSIZE; 1351590Srgrimes we = w->wd_we; 1361590Srgrimes for (n = cc / sizeof (struct whoent); n > 0; n--) { 1371590Srgrimes if (aflg == 0 && we->we_idle >= 60*60) { 1381590Srgrimes we++; 1391590Srgrimes continue; 1401590Srgrimes } 14127978Scharnier if (nusers >= NUSERS) 14227978Scharnier errx(1, "too many users"); 1431590Srgrimes mp->myutmp = we->we_utmp; mp->myidle = we->we_idle; 1441590Srgrimes (void) strcpy(mp->myhost, w->wd_hostname); 1451590Srgrimes nusers++; we++; mp++; 1461590Srgrimes } 1471590Srgrimes (void) close(f); 1481590Srgrimes } 1491590Srgrimes qsort((char *)myutmp, nusers, sizeof (struct myutmp), utmpcmp); 1501590Srgrimes mp = myutmp; 1511590Srgrimes width = 0; 1521590Srgrimes for (i = 0; i < nusers; i++) { 1535239Sats /* append one for the blank and use 8 for the out_line */ 15420165Sache int j = strlen(mp->myhost) + 1 + sizeof(mp->myutmp.out_line); 1551590Srgrimes if (j > width) 1561590Srgrimes width = j; 1571590Srgrimes mp++; 1581590Srgrimes } 1591590Srgrimes mp = myutmp; 1601590Srgrimes for (i = 0; i < nusers; i++) { 1619992Sache char buf[BUFSIZ], cbuf[80]; 1629992Sache strftime(cbuf, sizeof(cbuf), "%c", localtime((time_t *)&mp->myutmp.out_time)); 16320165Sache (void)sprintf(buf, "%s:%-.*s", mp->myhost, 16420165Sache sizeof(mp->myutmp.out_line), mp->myutmp.out_line); 16520156Sache printf("%-*.*s %-*s %.12s", 16620165Sache UT_NAMESIZE, sizeof(mp->myutmp.out_name), 1671590Srgrimes mp->myutmp.out_name, 1681590Srgrimes width, 1691590Srgrimes buf, 1709992Sache cbuf + 4); 1711590Srgrimes mp->myidle /= 60; 1721590Srgrimes if (mp->myidle) { 1731590Srgrimes if (aflg) { 1741590Srgrimes if (mp->myidle >= 100*60) 1751590Srgrimes mp->myidle = 100*60 - 1; 1761590Srgrimes if (mp->myidle >= 60) 1771590Srgrimes printf(" %2d", mp->myidle / 60); 1781590Srgrimes else 1791590Srgrimes printf(" "); 1801590Srgrimes } else 1811590Srgrimes printf(" "); 1821590Srgrimes printf(":%02d", mp->myidle % 60); 1831590Srgrimes } 1841590Srgrimes printf("\n"); 1851590Srgrimes mp++; 1861590Srgrimes } 1871590Srgrimes exit(0); 1881590Srgrimes} 1891590Srgrimes 19027978Scharnier 19127978Scharnierstatic void 19227978Scharnierusage() 19327978Scharnier{ 19427978Scharnier fprintf(stderr, "usage: rwho [-a]\n"); 19527978Scharnier exit(1); 19627978Scharnier} 19727978Scharnier 19835659Ssteve#define MYUTMP(a) ((struct myutmp *)(a)) 19935659Ssteve 20027978Scharnierint 2011590Srgrimesutmpcmp(u1, u2) 20235659Ssteve const void *u1, *u2; 2031590Srgrimes{ 2041590Srgrimes int rc; 2051590Srgrimes 20635659Ssteve rc = strncmp(MYUTMP(u1)->myutmp.out_name, MYUTMP(u2)->myutmp.out_name, 20735659Ssteve sizeof(MYUTMP(u2)->myutmp.out_name)); 2081590Srgrimes if (rc) 2091590Srgrimes return (rc); 21035659Ssteve rc = strcmp(MYUTMP(u1)->myhost, MYUTMP(u2)->myhost); 2111590Srgrimes if (rc) 2121590Srgrimes return (rc); 21335659Ssteve return (strncmp(MYUTMP(u1)->myutmp.out_line, MYUTMP(u2)->myutmp.out_line, 21435659Ssteve sizeof(MYUTMP(u2)->myutmp.out_line))); 2151590Srgrimes} 216