1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 #pragma ident "%Z%%M% %I% %E% SMI" 41 42 #include <sys/param.h> 43 44 #include <dirent.h> 45 #include <fcntl.h> 46 #include <stdio.h> 47 #include <stdlib.h> 48 #include <strings.h> 49 #include <time.h> 50 #include <unistd.h> 51 52 #include <protocols/rwhod.h> 53 54 static DIR *dirp; 55 56 static struct whod wd; 57 #define NUSERS 1000 58 static struct myutmp { 59 char myhost[32]; 60 int myidle; 61 struct outmp myutmp; 62 } myutmp[NUSERS]; 63 static int utmpcmp(const void *, const void *); 64 static int nusers; 65 66 #define WHDRSIZE (sizeof (wd) - sizeof (wd.wd_we)) 67 #define RWHODIR "/var/spool/rwho" 68 /* 69 * this macro should be shared with ruptime. 70 */ 71 #define down(w, now) ((now) - (w)->wd_recvtime > 11 * 60) 72 73 static time_t now; 74 static int aflg = 0; 75 76 int 77 main(int argc, char **argv) 78 { 79 struct dirent *dp; 80 int cc, width; 81 register struct whod *w = &wd; 82 register struct whoent *we; 83 register struct myutmp *mp; 84 int f, n, i; 85 86 argc--, argv++; 87 again: 88 if (argc > 0 && strcmp(argv[0], "-a") == 0) { 89 argc--, argv++; 90 aflg++; 91 goto again; 92 } 93 (void) time(&now); 94 if (chdir(RWHODIR) < 0) { 95 perror(RWHODIR); 96 return (EXIT_FAILURE); 97 } 98 dirp = opendir("."); 99 if (dirp == NULL) { 100 perror(RWHODIR); 101 return (EXIT_FAILURE); 102 } 103 mp = myutmp; 104 while (dp = readdir(dirp)) { 105 if (dp->d_ino == 0) 106 continue; 107 if (strncmp(dp->d_name, "whod.", 5)) 108 continue; 109 f = open(dp->d_name, 0); 110 if (f < 0) 111 continue; 112 cc = read(f, (char *)&wd, sizeof (struct whod)); 113 if (cc < WHDRSIZE) { 114 (void) close(f); 115 continue; 116 } 117 if (down(w, now)) { 118 (void) close(f); 119 continue; 120 } 121 cc -= WHDRSIZE; 122 we = w->wd_we; 123 for (n = cc / sizeof (struct whoent); n > 0; n--) { 124 if (aflg == 0 && we->we_idle >= 60*60) { 125 we++; 126 continue; 127 } 128 if (nusers >= NUSERS) { 129 (void) printf("too many users\n"); 130 return (EXIT_FAILURE); 131 } 132 mp->myutmp = we->we_utmp; mp->myidle = we->we_idle; 133 (void) strncpy(mp->myhost, w->wd_hostname, 134 sizeof (mp->myhost)); 135 nusers++; we++; mp++; 136 } 137 (void) close(f); 138 } 139 qsort((char *)myutmp, nusers, sizeof (struct myutmp), utmpcmp); 140 mp = myutmp; 141 width = 0; 142 for (i = 0; i < nusers; i++) { 143 int j = strlen(mp->myhost) + 1 + strlen(mp->myutmp.out_line); 144 if (j > width) 145 width = j; 146 mp++; 147 } 148 mp = myutmp; 149 for (i = 0; i < nusers; i++) { 150 char buf[BUFSIZ]; 151 (void) snprintf(buf, BUFSIZ, "%.*s:%.*s", 152 sizeof (mp->myhost), mp->myhost, 153 sizeof (mp->myutmp.out_line), mp->myutmp.out_line); 154 (void) printf("%-8.*s %-*s %.12s", 155 sizeof (mp->myutmp.out_name), mp->myutmp.out_name, 156 width, buf, 157 ctime((time_t *)&mp->myutmp.out_time) + 4); 158 mp->myidle /= 60; 159 if (mp->myidle) { 160 if (aflg) { 161 if (mp->myidle >= 100*60) 162 mp->myidle = 100*60 - 1; 163 if (mp->myidle >= 60) 164 (void) printf(" %2d", mp->myidle / 60); 165 else 166 (void) fputs(" ", stdout); 167 } else 168 (void) printf(" "); 169 (void) printf(":%02d", mp->myidle % 60); 170 } 171 (void) puts(""); 172 mp++; 173 } 174 return (EXIT_SUCCESS); 175 } 176 177 static int 178 utmpcmp(const void *p1, const void *p2) 179 { 180 const struct myutmp *u1 = p1, *u2 = p2; 181 int rc; 182 183 rc = strncmp(u1->myutmp.out_name, u2->myutmp.out_name, 184 sizeof (u1->myutmp.out_name)); 185 if (rc != 0) 186 return (rc); 187 rc = strncmp(u1->myhost, u2->myhost, sizeof (u1->myhost)); 188 if (rc != 0) 189 return (rc); 190 return (strncmp(u1->myutmp.out_line, u2->myutmp.out_line, 191 sizeof (u1->myutmp.out_line))); 192 } 193