rusers.c revision 121545
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 3495619Smarkm#include <sys/cdefs.h> 352345Scsgr 3695619Smarkm__FBSDID("$FreeBSD: head/usr.bin/rusers/rusers.c 121545 2003-10-26 04:57:32Z peter $"); 3795619Smarkm 382345Scsgr#include <sys/types.h> 392345Scsgr#include <sys/socket.h> 4095619Smarkm 4178455Smikeh#include <rpc/rpc.h> 4278455Smikeh#include <rpc/pmap_clnt.h> 4378455Smikeh#include <rpcsvc/rnusers.h> 4495619Smarkm 4578455Smikeh#include <arpa/inet.h> 4695619Smarkm 4727976Scharnier#include <err.h> 482345Scsgr#include <netdb.h> 492345Scsgr#include <stdio.h> 5027976Scharnier#include <stdlib.h> 5195619Smarkm#include <string.h> 5227976Scharnier#include <unistd.h> 532345Scsgr 5478455Smikeh#define MAX_INT 0x7fffffff 5578455Smikeh#define HOST_WIDTH 20 5678455Smikeh#define LINE_WIDTH 15 572345Scsgr 582345Scsgrint longopt; 592345Scsgrint allopt; 602345Scsgr 612345Scsgrstruct host_list { 6278455Smikeh struct host_list *next; 6378455Smikeh struct in_addr addr; 642345Scsgr} *hosts; 652345Scsgr 6695619Smarkmstatic int 6727976Scharniersearch_host(struct in_addr addr) 682345Scsgr{ 692345Scsgr struct host_list *hp; 708874Srgrimes 7178455Smikeh if (hosts == NULL) 7278455Smikeh return (0); 732345Scsgr 742345Scsgr for (hp = hosts; hp != NULL; hp = hp->next) { 752345Scsgr if (hp->addr.s_addr == addr.s_addr) 7678455Smikeh return (1); 772345Scsgr } 7878455Smikeh return (0); 792345Scsgr} 802345Scsgr 8195619Smarkmstatic void 8227976Scharnierremember_host(struct in_addr addr) 832345Scsgr{ 842345Scsgr struct host_list *hp; 852345Scsgr 8678455Smikeh if ((hp = (struct host_list *)malloc(sizeof(struct host_list))) == NULL) 8727976Scharnier errx(1, "no memory"); 882345Scsgr hp->addr.s_addr = addr.s_addr; 892345Scsgr hp->next = hosts; 902345Scsgr hosts = hp; 912345Scsgr} 922345Scsgr 9395619Smarkmstatic int 9474462Salfredrusers_reply(caddr_t replyp, struct sockaddr_in *raddrp) 952345Scsgr{ 9695619Smarkm u_int x; 9795619Smarkm int idle; 9878455Smikeh char date[32], idle_time[64], remote[64]; 9978455Smikeh struct hostent *hp; 10078455Smikeh utmpidlearr *up = (utmpidlearr *)replyp; 10178455Smikeh char *host; 10278455Smikeh int days, hours, minutes, seconds; 1038874Srgrimes 1042345Scsgr if (search_host(raddrp->sin_addr)) 10578455Smikeh return (0); 1062345Scsgr 10778455Smikeh if (!allopt && up->utmpidlearr_len == 0) 10878455Smikeh return (0); 1098874Srgrimes 11078455Smikeh hp = gethostbyaddr((char *)&raddrp->sin_addr.s_addr, 11178455Smikeh sizeof(struct in_addr), AF_INET); 11278455Smikeh if (hp != NULL) 11378455Smikeh host = hp->h_name; 11478455Smikeh else 11578455Smikeh host = inet_ntoa(raddrp->sin_addr); 1168874Srgrimes 11778455Smikeh if (!longopt) 11878455Smikeh printf("%-*s ", HOST_WIDTH, host); 1198874Srgrimes 12078455Smikeh for (x = 0; x < up->utmpidlearr_len; x++) { 12189572Sdillon time_t t = _int_to_time(up->utmpidlearr_val[x].ui_utmp.ut_time); 12285638Sdillon strncpy(date, &(ctime(&t)[4]), sizeof(date) - 1); 1232345Scsgr 12478455Smikeh idle = up->utmpidlearr_val[x].ui_idle; 12578455Smikeh sprintf(idle_time, " :%02d", idle); 12678455Smikeh if (idle == MAX_INT) 12778455Smikeh strcpy(idle_time, "??"); 12878455Smikeh else if (idle == 0) 12978455Smikeh strcpy(idle_time, ""); 13078455Smikeh else { 13178455Smikeh seconds = idle; 13278455Smikeh days = seconds / (60 * 60 * 24); 13378455Smikeh seconds %= (60 * 60 * 24); 13478455Smikeh hours = seconds / (60 * 60); 13578455Smikeh seconds %= (60 * 60); 13678455Smikeh minutes = seconds / 60; 13778455Smikeh seconds %= 60; 13878455Smikeh if (idle > 60) 13978455Smikeh sprintf(idle_time, "%d:%02d", minutes, seconds); 14078455Smikeh if (idle >= (60 * 60)) 14178455Smikeh sprintf(idle_time, "%d:%02d:%02d", 14278455Smikeh hours, minutes, seconds); 14378455Smikeh if (idle >= (24 * 60 * 60)) 14478455Smikeh sprintf(idle_time, "%d days, %d:%02d:%02d", 14578455Smikeh days, hours, minutes, seconds); 14678455Smikeh } 1472345Scsgr 14878455Smikeh strncpy(remote, up->utmpidlearr_val[x].ui_utmp.ut_host, 14978455Smikeh sizeof(remote) - 1); 15078455Smikeh if (strlen(remote) != 0) 15178455Smikeh sprintf(remote, "(%.16s)", 15278455Smikeh up->utmpidlearr_val[x].ui_utmp.ut_host); 1532345Scsgr 15478455Smikeh if (longopt) 15578455Smikeh printf("%-8.8s %*s:%-*.*s %-12.12s %6s %.18s\n", 15678455Smikeh up->utmpidlearr_val[x].ui_utmp.ut_name, 15778455Smikeh HOST_WIDTH, host, LINE_WIDTH, LINE_WIDTH, 15878455Smikeh up->utmpidlearr_val[x].ui_utmp.ut_line, date, 15978455Smikeh idle_time, remote ); 16078455Smikeh else 16178455Smikeh printf("%s ", 16278455Smikeh up->utmpidlearr_val[x].ui_utmp.ut_name); 16378455Smikeh } 16478455Smikeh if (!longopt) 16578455Smikeh putchar('\n'); 1668874Srgrimes 1672345Scsgr remember_host(raddrp->sin_addr); 16878455Smikeh return (0); 1692345Scsgr} 1702345Scsgr 17195619Smarkmstatic void 1722345Scsgronehost(char *host) 1732345Scsgr{ 17478455Smikeh utmpidlearr up; 17578455Smikeh CLIENT *rusers_clnt; 17678455Smikeh struct sockaddr_in addr; 17778455Smikeh struct hostent *hp; 17878455Smikeh struct timeval tv; 1798874Srgrimes 18078455Smikeh hp = gethostbyname(host); 18178455Smikeh if (hp == NULL) 18278455Smikeh errx(1, "unknown host \"%s\"", host); 1832345Scsgr 18478455Smikeh rusers_clnt = clnt_create(host, RUSERSPROG, RUSERSVERS_IDLE, "udp"); 18578455Smikeh if (rusers_clnt == NULL) 18678455Smikeh errx(1, "%s", clnt_spcreateerror("")); 1872345Scsgr 1882345Scsgr bzero((char *)&up, sizeof(up)); 18978455Smikeh tv.tv_sec = 15; /* XXX ?? */ 19021094Speter tv.tv_usec = 0; 191121545Speter if (clnt_call(rusers_clnt, RUSERSPROC_NAMES, (xdrproc_t)xdr_void, NULL, 192121545Speter (xdrproc_t)xdr_utmpidlearr, &up, tv) != RPC_SUCCESS) 19378455Smikeh errx(1, "%s", clnt_sperror(rusers_clnt, "")); 19478455Smikeh addr.sin_addr.s_addr = *(int *)hp->h_addr; 19578455Smikeh rusers_reply((caddr_t)&up, &addr); 19678456Smikeh clnt_destroy(rusers_clnt); 1972345Scsgr} 1982345Scsgr 19995619Smarkmstatic void 20095619Smarkmallhosts(void) 2012345Scsgr{ 20227976Scharnier utmpidlearr up; 2032345Scsgr enum clnt_stat clnt_stat; 2042345Scsgr 2052345Scsgr bzero((char *)&up, sizeof(up)); 20678455Smikeh clnt_stat = clnt_broadcast(RUSERSPROG, RUSERSVERS_IDLE, 207121545Speter RUSERSPROC_NAMES, (xdrproc_t)xdr_void, NULL, 208121545Speter (xdrproc_t)xdr_utmpidlearr, (char *)&up, 209121545Speter (resultproc_t)rusers_reply); 21027976Scharnier if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) 21127976Scharnier errx(1, "%s", clnt_sperrno(clnt_stat)); 2122345Scsgr} 2132345Scsgr 21427976Scharnierstatic void 21595619Smarkmusage(void) 2162345Scsgr{ 21778455Smikeh 21878455Smikeh fprintf(stderr, "usage: rusers [-la] [hosts ...]\n"); 21978455Smikeh exit(1); 2202345Scsgr} 2212345Scsgr 22227976Scharnierint 2232345Scsgrmain(int argc, char *argv[]) 2242345Scsgr{ 22578455Smikeh int ch; 2268874Srgrimes 22778455Smikeh while ((ch = getopt(argc, argv, "al")) != -1) 22878455Smikeh switch (ch) { 22978455Smikeh case 'a': 23078455Smikeh allopt++; 23178455Smikeh break; 23278455Smikeh case 'l': 23378455Smikeh longopt++; 23478455Smikeh break; 23578455Smikeh default: 23678455Smikeh usage(); 23778455Smikeh /* NOTREACHED */ 23878455Smikeh } 2392345Scsgr 24078455Smikeh setlinebuf(stdout); 2412345Scsgr if (argc == optind) 2422345Scsgr allhosts(); 2432345Scsgr else { 2442345Scsgr for (; optind < argc; optind++) 24578455Smikeh (void)onehost(argv[optind]); 2462345Scsgr } 24778455Smikeh exit(0); 2482345Scsgr} 249