rusers.c revision 74462
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 3527976Scharnierstatic const char rcsid[] = 3650477Speter "$FreeBSD: head/usr.bin/rusers/rusers.c 74462 2001-03-19 12:50:13Z alfred $"; 372345Scsgr#endif /* not lint */ 382345Scsgr 392345Scsgr#include <sys/types.h> 402345Scsgr#include <sys/param.h> 412345Scsgr#include <sys/socket.h> 4227976Scharnier#include <err.h> 432345Scsgr#include <netdb.h> 442345Scsgr#include <stdio.h> 4527976Scharnier#include <stdlib.h> 462345Scsgr#include <strings.h> 4727976Scharnier#include <unistd.h> 482345Scsgr#include <rpc/rpc.h> 4927976Scharnier#include <rpc/pmap_clnt.h> 502345Scsgr#include <arpa/inet.h> 512345Scsgr#include <rpcsvc/rnusers.h> 522345Scsgr 532345Scsgr#define MAX_INT 0x7fffffff 542345Scsgr#define HOST_WIDTH 20 552345Scsgr#define LINE_WIDTH 15 562345Scsgr 572345Scsgrint longopt; 582345Scsgrint allopt; 592345Scsgr 602345Scsgrstruct host_list { 612345Scsgr struct host_list *next; 622345Scsgr struct in_addr addr; 632345Scsgr} *hosts; 642345Scsgr 6527976Scharnierint 6627976Scharniersearch_host(struct in_addr addr) 672345Scsgr{ 682345Scsgr struct host_list *hp; 698874Srgrimes 702345Scsgr if (!hosts) 712345Scsgr return(0); 722345Scsgr 732345Scsgr for (hp = hosts; hp != NULL; hp = hp->next) { 742345Scsgr if (hp->addr.s_addr == addr.s_addr) 752345Scsgr return(1); 762345Scsgr } 772345Scsgr return(0); 782345Scsgr} 792345Scsgr 8027976Scharniervoid 8127976Scharnierremember_host(struct in_addr addr) 822345Scsgr{ 832345Scsgr struct host_list *hp; 842345Scsgr 8527976Scharnier if (!(hp = (struct host_list *)malloc(sizeof(struct host_list)))) 8627976Scharnier errx(1, "no memory"); 872345Scsgr hp->addr.s_addr = addr.s_addr; 882345Scsgr hp->next = hosts; 892345Scsgr hosts = hp; 902345Scsgr} 912345Scsgr 9227976Scharnierint 9374462Salfredrusers_reply(caddr_t replyp, struct sockaddr_in *raddrp) 942345Scsgr{ 952345Scsgr int x, idle; 962345Scsgr char date[32], idle_time[64], remote[64]; 972345Scsgr struct hostent *hp; 982345Scsgr utmpidlearr *up = (utmpidlearr *)replyp; 992345Scsgr char *host; 1002345Scsgr int days, hours, minutes, seconds; 1018874Srgrimes 1022345Scsgr if (search_host(raddrp->sin_addr)) 1032345Scsgr return(0); 1042345Scsgr 1052345Scsgr if (!allopt && !up->utmpidlearr_len) 1062345Scsgr return(0); 1078874Srgrimes 1082345Scsgr hp = gethostbyaddr((char *)&raddrp->sin_addr.s_addr, 1092345Scsgr sizeof(struct in_addr), AF_INET); 1102345Scsgr if (hp) 1112345Scsgr host = hp->h_name; 1122345Scsgr else 1132345Scsgr host = inet_ntoa(raddrp->sin_addr); 1148874Srgrimes 1152345Scsgr if (!longopt) 1162345Scsgr printf("%-*s ", HOST_WIDTH, host); 1178874Srgrimes 1182345Scsgr for (x = 0; x < up->utmpidlearr_len; x++) { 1192345Scsgr strncpy(date, 1202345Scsgr &(ctime((time_t *)&(up->utmpidlearr_val[x].ui_utmp.ut_time))[4]), 1212345Scsgr sizeof(date)-1); 1222345Scsgr 1232345Scsgr idle = up->utmpidlearr_val[x].ui_idle; 1242345Scsgr sprintf(idle_time, " :%02d", idle); 1252345Scsgr if (idle == MAX_INT) 1262345Scsgr strcpy(idle_time, "??"); 1272345Scsgr else if (idle == 0) 1282345Scsgr strcpy(idle_time, ""); 1292345Scsgr else { 1302345Scsgr seconds = idle; 1312345Scsgr days = seconds/(60*60*24); 1322345Scsgr seconds %= (60*60*24); 1332345Scsgr hours = seconds/(60*60); 1342345Scsgr seconds %= (60*60); 1352345Scsgr minutes = seconds/60; 1362345Scsgr seconds %= 60; 1372345Scsgr if (idle > 60) 1382345Scsgr sprintf(idle_time, "%d:%02d", 1392345Scsgr minutes, seconds); 1402345Scsgr if (idle >= (60*60)) 1412345Scsgr sprintf(idle_time, "%d:%02d:%02d", 1422345Scsgr hours, minutes, seconds); 1432345Scsgr if (idle >= (24*60*60)) 1442345Scsgr sprintf(idle_time, "%d days, %d:%02d:%02d", 1452345Scsgr days, hours, minutes, seconds); 1462345Scsgr } 1472345Scsgr 1482345Scsgr strncpy(remote, up->utmpidlearr_val[x].ui_utmp.ut_host, sizeof(remote)-1); 1492345Scsgr if (strlen(remote) != 0) 1502345Scsgr sprintf(remote, "(%.16s)", up->utmpidlearr_val[x].ui_utmp.ut_host); 1512345Scsgr 1522345Scsgr if (longopt) 1532345Scsgr printf("%-8.8s %*s:%-*.*s %-12.12s %6s %.18s\n", 1542345Scsgr up->utmpidlearr_val[x].ui_utmp.ut_name, 1552345Scsgr HOST_WIDTH, host, 1562345Scsgr LINE_WIDTH, LINE_WIDTH, up->utmpidlearr_val[x].ui_utmp.ut_line, 1572345Scsgr date, 1582345Scsgr idle_time, 1592345Scsgr remote 1602345Scsgr ); 1612345Scsgr else 1622345Scsgr printf("%s ", 1632345Scsgr up->utmpidlearr_val[x].ui_utmp.ut_name); 1642345Scsgr } 1652345Scsgr if (!longopt) 1662345Scsgr putchar('\n'); 1678874Srgrimes 1682345Scsgr remember_host(raddrp->sin_addr); 1692345Scsgr return(0); 1702345Scsgr} 1712345Scsgr 17227976Scharniervoid 1732345Scsgronehost(char *host) 1742345Scsgr{ 1752345Scsgr utmpidlearr up; 1762345Scsgr CLIENT *rusers_clnt; 1772345Scsgr struct sockaddr_in addr; 1782345Scsgr struct hostent *hp; 17927976Scharnier struct timeval tv; 1808874Srgrimes 1812345Scsgr hp = gethostbyname(host); 18227976Scharnier if (hp == NULL) 18327976Scharnier errx(1, "unknown host \"%s\"", host); 1842345Scsgr 1852345Scsgr rusers_clnt = clnt_create(host, RUSERSPROG, RUSERSVERS_IDLE, "udp"); 18627976Scharnier if (rusers_clnt == NULL) 18727976Scharnier errx(1, "%s", clnt_spcreateerror("")); 1882345Scsgr 1892345Scsgr bzero((char *)&up, sizeof(up)); 19021094Speter tv.tv_sec = 15; /* XXX ?? */ 19121094Speter tv.tv_usec = 0; 19227976Scharnier if (clnt_call(rusers_clnt, RUSERSPROC_NAMES, xdr_void, NULL, xdr_utmpidlearr, &up, tv) != RPC_SUCCESS) 19327976Scharnier errx(1, "%s", clnt_sperror(rusers_clnt, "")); 1942345Scsgr addr.sin_addr.s_addr = *(int *)hp->h_addr; 19574462Salfred rusers_reply((caddr_t)&up, &addr); 1962345Scsgr} 1972345Scsgr 19827976Scharniervoid 1992345Scsgrallhosts() 2002345Scsgr{ 20127976Scharnier 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, 20729469Sjkh xdr_utmpidlearr, (char *)&up, rusers_reply); 20827976Scharnier if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) 20927976Scharnier errx(1, "%s", clnt_sperrno(clnt_stat)); 2102345Scsgr} 2112345Scsgr 21227976Scharnierstatic void 2132345Scsgrusage() 2142345Scsgr{ 21527976Scharnier fprintf(stderr, "usage: rusers [-la] [hosts ...]\n"); 2162345Scsgr exit(1); 2172345Scsgr} 2182345Scsgr 21927976Scharnierint 2202345Scsgrmain(int argc, char *argv[]) 2212345Scsgr{ 2222345Scsgr int ch; 2238874Srgrimes 2242345Scsgr while ((ch = getopt(argc, argv, "al")) != -1) 2252345Scsgr switch (ch) { 2262345Scsgr case 'a': 2272345Scsgr allopt++; 2282345Scsgr break; 2292345Scsgr case 'l': 2302345Scsgr longopt++; 2312345Scsgr break; 2322345Scsgr default: 2332345Scsgr usage(); 2342345Scsgr /*NOTREACHED*/ 2352345Scsgr } 2362345Scsgr 2372345Scsgr setlinebuf(stdout); 2382345Scsgr if (argc == optind) 2392345Scsgr allhosts(); 2402345Scsgr else { 2412345Scsgr for (; optind < argc; optind++) 2422345Scsgr (void) onehost(argv[optind]); 2432345Scsgr } 2442345Scsgr exit(0); 2452345Scsgr} 246