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