rusers.c revision 21094
12345Scsgr/*- 22345Scsgr * Copyright (c) 1993, John Brezak 32345Scsgr * All rights reserved. 42345Scsgr * 52345Scsgr * Redistribution and use in source and binary forms, with or without 62345Scsgr * modification, are permitted provided that the following conditions 72345Scsgr * are met: 82345Scsgr * 1. Redistributions of source code must retain the above copyright 92345Scsgr * notice, this list of conditions and the following disclaimer. 102345Scsgr * 2. Redistributions in binary form must reproduce the above copyright 112345Scsgr * notice, this list of conditions and the following disclaimer in the 122345Scsgr * documentation and/or other materials provided with the distribution. 132345Scsgr * 3. All advertising materials mentioning features or use of this software 142345Scsgr * must display the following acknowledgement: 152345Scsgr * This product includes software developed by the University of 162345Scsgr * California, Berkeley and its contributors. 172345Scsgr * 4. Neither the name of the University nor the names of its contributors 182345Scsgr * may be used to endorse or promote products derived from this software 192345Scsgr * without specific prior written permission. 202345Scsgr * 212345Scsgr * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 222345Scsgr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 232345Scsgr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 242345Scsgr * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 252345Scsgr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 262345Scsgr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 272345Scsgr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 282345Scsgr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 292345Scsgr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 302345Scsgr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 312345Scsgr * SUCH DAMAGE. 322345Scsgr */ 332345Scsgr 342345Scsgr#ifndef lint 3521094Speterstatic char rcsid[] = "$Id: rusers.c,v 1.2 1995/05/30 06:33:28 rgrimes Exp $"; 362345Scsgr#endif /* not lint */ 372345Scsgr 382345Scsgr#include <sys/types.h> 392345Scsgr#include <sys/param.h> 402345Scsgr#include <sys/socket.h> 412345Scsgr#include <netdb.h> 422345Scsgr#include <stdio.h> 432345Scsgr#include <strings.h> 442345Scsgr#include <rpc/rpc.h> 452345Scsgr#include <arpa/inet.h> 462345Scsgr#include <rpcsvc/rnusers.h> 472345Scsgr 482345Scsgr#define MAX_INT 0x7fffffff 492345Scsgr#define HOST_WIDTH 20 502345Scsgr#define LINE_WIDTH 15 512345Scsgrchar *argv0; 522345Scsgr 532345Scsgrint longopt; 542345Scsgrint allopt; 552345Scsgr 562345Scsgrstruct host_list { 572345Scsgr struct host_list *next; 582345Scsgr struct in_addr addr; 592345Scsgr} *hosts; 602345Scsgr 612345Scsgrint search_host(struct in_addr addr) 622345Scsgr{ 632345Scsgr struct host_list *hp; 648874Srgrimes 652345Scsgr if (!hosts) 662345Scsgr return(0); 672345Scsgr 682345Scsgr for (hp = hosts; hp != NULL; hp = hp->next) { 692345Scsgr if (hp->addr.s_addr == addr.s_addr) 702345Scsgr return(1); 712345Scsgr } 722345Scsgr return(0); 732345Scsgr} 742345Scsgr 752345Scsgrvoid remember_host(struct in_addr addr) 762345Scsgr{ 772345Scsgr struct host_list *hp; 782345Scsgr 792345Scsgr if (!(hp = (struct host_list *)malloc(sizeof(struct host_list)))) { 802345Scsgr fprintf(stderr, "%s: no memory.\n", argv0); 812345Scsgr exit(1); 822345Scsgr } 832345Scsgr hp->addr.s_addr = addr.s_addr; 842345Scsgr hp->next = hosts; 852345Scsgr hosts = hp; 862345Scsgr} 872345Scsgr 882345Scsgrrusers_reply(char *replyp, struct sockaddr_in *raddrp) 892345Scsgr{ 902345Scsgr int x, idle; 912345Scsgr char date[32], idle_time[64], remote[64]; 922345Scsgr struct hostent *hp; 932345Scsgr utmpidlearr *up = (utmpidlearr *)replyp; 942345Scsgr char *host; 952345Scsgr int days, hours, minutes, seconds; 968874Srgrimes 972345Scsgr if (search_host(raddrp->sin_addr)) 982345Scsgr return(0); 992345Scsgr 1002345Scsgr if (!allopt && !up->utmpidlearr_len) 1012345Scsgr return(0); 1028874Srgrimes 1032345Scsgr hp = gethostbyaddr((char *)&raddrp->sin_addr.s_addr, 1042345Scsgr sizeof(struct in_addr), AF_INET); 1052345Scsgr if (hp) 1062345Scsgr host = hp->h_name; 1072345Scsgr else 1082345Scsgr host = inet_ntoa(raddrp->sin_addr); 1098874Srgrimes 1102345Scsgr if (!longopt) 1112345Scsgr printf("%-*s ", HOST_WIDTH, host); 1128874Srgrimes 1132345Scsgr for (x = 0; x < up->utmpidlearr_len; x++) { 1142345Scsgr strncpy(date, 1152345Scsgr &(ctime((time_t *)&(up->utmpidlearr_val[x].ui_utmp.ut_time))[4]), 1162345Scsgr sizeof(date)-1); 1172345Scsgr 1182345Scsgr idle = up->utmpidlearr_val[x].ui_idle; 1192345Scsgr sprintf(idle_time, " :%02d", idle); 1202345Scsgr if (idle == MAX_INT) 1212345Scsgr strcpy(idle_time, "??"); 1222345Scsgr else if (idle == 0) 1232345Scsgr strcpy(idle_time, ""); 1242345Scsgr else { 1252345Scsgr seconds = idle; 1262345Scsgr days = seconds/(60*60*24); 1272345Scsgr seconds %= (60*60*24); 1282345Scsgr hours = seconds/(60*60); 1292345Scsgr seconds %= (60*60); 1302345Scsgr minutes = seconds/60; 1312345Scsgr seconds %= 60; 1322345Scsgr if (idle > 60) 1332345Scsgr sprintf(idle_time, "%d:%02d", 1342345Scsgr minutes, seconds); 1352345Scsgr if (idle >= (60*60)) 1362345Scsgr sprintf(idle_time, "%d:%02d:%02d", 1372345Scsgr hours, minutes, seconds); 1382345Scsgr if (idle >= (24*60*60)) 1392345Scsgr sprintf(idle_time, "%d days, %d:%02d:%02d", 1402345Scsgr days, hours, minutes, seconds); 1412345Scsgr } 1422345Scsgr 1432345Scsgr strncpy(remote, up->utmpidlearr_val[x].ui_utmp.ut_host, sizeof(remote)-1); 1442345Scsgr if (strlen(remote) != 0) 1452345Scsgr sprintf(remote, "(%.16s)", up->utmpidlearr_val[x].ui_utmp.ut_host); 1462345Scsgr 1472345Scsgr if (longopt) 1482345Scsgr printf("%-8.8s %*s:%-*.*s %-12.12s %6s %.18s\n", 1492345Scsgr up->utmpidlearr_val[x].ui_utmp.ut_name, 1502345Scsgr HOST_WIDTH, host, 1512345Scsgr LINE_WIDTH, LINE_WIDTH, up->utmpidlearr_val[x].ui_utmp.ut_line, 1522345Scsgr date, 1532345Scsgr idle_time, 1542345Scsgr remote 1552345Scsgr ); 1562345Scsgr else 1572345Scsgr printf("%s ", 1582345Scsgr up->utmpidlearr_val[x].ui_utmp.ut_name); 1592345Scsgr } 1602345Scsgr if (!longopt) 1612345Scsgr putchar('\n'); 1628874Srgrimes 1632345Scsgr remember_host(raddrp->sin_addr); 1642345Scsgr return(0); 1652345Scsgr} 1662345Scsgr 1672345Scsgronehost(char *host) 1682345Scsgr{ 1692345Scsgr utmpidlearr up; 1702345Scsgr CLIENT *rusers_clnt; 1712345Scsgr struct sockaddr_in addr; 1722345Scsgr struct hostent *hp; 17321094Speter struct timeval tv; 1748874Srgrimes 1752345Scsgr hp = gethostbyname(host); 1762345Scsgr if (hp == NULL) { 1772345Scsgr fprintf(stderr, "%s: unknown host \"%s\"\n", 1782345Scsgr argv0, host); 1792345Scsgr exit(1); 1802345Scsgr } 1812345Scsgr 1822345Scsgr rusers_clnt = clnt_create(host, RUSERSPROG, RUSERSVERS_IDLE, "udp"); 1832345Scsgr if (rusers_clnt == NULL) { 1842345Scsgr clnt_pcreateerror(argv0); 1852345Scsgr exit(1); 1862345Scsgr } 1872345Scsgr 1882345Scsgr bzero((char *)&up, sizeof(up)); 18921094Speter tv.tv_sec = 15; /* XXX ?? */ 19021094Speter tv.tv_usec = 0; 19121094Speter if (clnt_call(rusers_clnt, RUSERSPROC_NAMES, xdr_void, NULL, xdr_utmpidlearr, &up, tv) != RPC_SUCCESS) { 1922345Scsgr clnt_perror(rusers_clnt, argv0); 1932345Scsgr exit(1); 1942345Scsgr } 1952345Scsgr addr.sin_addr.s_addr = *(int *)hp->h_addr; 1962345Scsgr rusers_reply((char *)&up, &addr); 1972345Scsgr} 1982345Scsgr 1992345Scsgrallhosts() 2002345Scsgr{ 2012345Scsgr utmpidlearr up; 2022345Scsgr enum clnt_stat clnt_stat; 2032345Scsgr 2042345Scsgr bzero((char *)&up, sizeof(up)); 2052345Scsgr clnt_stat = clnt_broadcast(RUSERSPROG, RUSERSVERS_IDLE, RUSERSPROC_NAMES, 2062345Scsgr xdr_void, NULL, 2072345Scsgr xdr_utmpidlearr, &up, rusers_reply); 2082345Scsgr if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) { 2092345Scsgr fprintf(stderr, "%s: %s\n", argv0, clnt_sperrno(clnt_stat)); 2102345Scsgr exit(1); 2112345Scsgr } 2122345Scsgr} 2132345Scsgr 2142345Scsgrusage() 2152345Scsgr{ 2162345Scsgr fprintf(stderr, "Usage: %s [-la] [hosts ...]\n", argv0); 2172345Scsgr exit(1); 2182345Scsgr} 2192345Scsgr 2202345Scsgrmain(int argc, char *argv[]) 2212345Scsgr{ 2222345Scsgr int ch; 2232345Scsgr extern int optind; 2248874Srgrimes 2252345Scsgr if (!(argv0 = rindex(argv[0], '/'))) 2262345Scsgr argv0 = argv[0]; 2272345Scsgr else 2282345Scsgr argv0++; 2292345Scsgr 2302345Scsgr 2312345Scsgr while ((ch = getopt(argc, argv, "al")) != -1) 2322345Scsgr switch (ch) { 2332345Scsgr case 'a': 2342345Scsgr allopt++; 2352345Scsgr break; 2362345Scsgr case 'l': 2372345Scsgr longopt++; 2382345Scsgr break; 2392345Scsgr default: 2402345Scsgr usage(); 2412345Scsgr /*NOTREACHED*/ 2422345Scsgr } 2432345Scsgr 2442345Scsgr setlinebuf(stdout); 2452345Scsgr if (argc == optind) 2462345Scsgr allhosts(); 2472345Scsgr else { 2482345Scsgr for (; optind < argc; optind++) 2492345Scsgr (void) onehost(argv[optind]); 2502345Scsgr } 2512345Scsgr exit(0); 2522345Scsgr} 253