Annotation of src/usr.bin/rusers/rusers.c, Revision 1.1
1.1 ! deraadt 1: /*-
! 2: * Copyright (c) 1993 John Brezak
! 3: * All rights reserved.
! 4: *
! 5: * Redistribution and use in source and binary forms, with or without
! 6: * modification, are permitted provided that the following conditions
! 7: * are met:
! 8: * 1. Redistributions of source code must retain the above copyright
! 9: * notice, this list of conditions and the following disclaimer.
! 10: * 2. Redistributions in binary form must reproduce the above copyright
! 11: * notice, this list of conditions and the following disclaimer in the
! 12: * documentation and/or other materials provided with the distribution.
! 13: * 3. The name of the author may not be used to endorse or promote products
! 14: * derived from this software without specific prior written permission.
! 15: *
! 16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
! 17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! 18: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
! 19: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
! 20: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
! 21: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
! 22: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
! 24: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
! 25: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 26: * POSSIBILITY OF SUCH DAMAGE.
! 27: */
! 28:
! 29: #ifndef lint
! 30: static char rcsid[] = "$Id: rusers.c,v 1.10 1993/12/10 19:33:58 jtc Exp $";
! 31: #endif /* not lint */
! 32:
! 33: #include <sys/types.h>
! 34: #include <sys/param.h>
! 35: #include <sys/socket.h>
! 36: #include <netdb.h>
! 37: #include <stdio.h>
! 38: #include <strings.h>
! 39: #include <rpc/rpc.h>
! 40: #include <arpa/inet.h>
! 41: #include <utmp.h>
! 42: #include <stdlib.h>
! 43:
! 44: /*
! 45: * For now we only try version 2 of the protocol. The current
! 46: * version is 3 (rusers.h), but only Solaris and NetBSD seem
! 47: * to support it currently.
! 48: */
! 49: #include <rpcsvc/rnusers.h> /* Old version */
! 50:
! 51: #define MAX_INT 0x7fffffff
! 52: #define HOST_WIDTH 20
! 53: #define LINE_WIDTH 8
! 54: char *argv0;
! 55:
! 56: struct timeval timeout = { 25, 0 };
! 57: int longopt;
! 58: int allopt;
! 59:
! 60: struct host_list {
! 61: struct host_list *next;
! 62: struct in_addr addr;
! 63: } *hosts;
! 64:
! 65: int
! 66: search_host(struct in_addr addr)
! 67: {
! 68: struct host_list *hp;
! 69:
! 70: if (!hosts)
! 71: return(0);
! 72:
! 73: for (hp = hosts; hp != NULL; hp = hp->next) {
! 74: if (hp->addr.s_addr == addr.s_addr)
! 75: return(1);
! 76: }
! 77: return(0);
! 78: }
! 79:
! 80: void
! 81: remember_host(struct in_addr addr)
! 82: {
! 83: struct host_list *hp;
! 84:
! 85: if (!(hp = (struct host_list *)malloc(sizeof(struct host_list)))) {
! 86: fprintf(stderr, "%s: no memory.\n", argv0);
! 87: exit(1);
! 88: }
! 89: hp->addr.s_addr = addr.s_addr;
! 90: hp->next = hosts;
! 91: hosts = hp;
! 92: }
! 93:
! 94: int
! 95: rusers_reply(char *replyp, struct sockaddr_in *raddrp)
! 96: {
! 97: int x, idle;
! 98: char date[32], idle_time[64], remote[64], local[64];
! 99: struct hostent *hp;
! 100: struct utmpidlearr *up = (struct utmpidlearr *)replyp;
! 101: char *host;
! 102: int days, hours, minutes, seconds;
! 103:
! 104: if (search_host(raddrp->sin_addr))
! 105: return(0);
! 106:
! 107: if (!allopt && !up->uia_cnt)
! 108: return(0);
! 109:
! 110: hp = gethostbyaddr((char *)&raddrp->sin_addr.s_addr,
! 111: sizeof(struct in_addr), AF_INET);
! 112: if (hp)
! 113: host = hp->h_name;
! 114: else
! 115: host = inet_ntoa(raddrp->sin_addr);
! 116:
! 117: if (!longopt)
! 118: printf("%-*.*s ", HOST_WIDTH, HOST_WIDTH, host);
! 119:
! 120: for (x = 0; x < up->uia_cnt; x++) {
! 121: strncpy(date,
! 122: &(ctime((time_t *)&(up->uia_arr[x]->ui_utmp.ut_time))[4]),
! 123: sizeof(date)-1);
! 124:
! 125: idle = up->uia_arr[x]->ui_idle;
! 126: sprintf(idle_time, " :%02d", idle);
! 127: if (idle == MAX_INT)
! 128: strcpy(idle_time, "??");
! 129: else if (idle == 0)
! 130: strcpy(idle_time, "");
! 131: else {
! 132: seconds = idle;
! 133: days = seconds/(60*60*24);
! 134: seconds %= (60*60*24);
! 135: hours = seconds/(60*60);
! 136: seconds %= (60*60);
! 137: minutes = seconds/60;
! 138: seconds %= 60;
! 139: if (idle > 60)
! 140: sprintf(idle_time, "%2d:%02d",
! 141: minutes, seconds);
! 142: if (idle >= (60*60))
! 143: sprintf(idle_time, "%2d:%02d:%02d",
! 144: hours, minutes, seconds);
! 145: if (idle >= (24*60*60))
! 146: sprintf(idle_time, "%d days, %d:%02d:%02d",
! 147: days, hours, minutes, seconds);
! 148: }
! 149:
! 150: strncpy(remote, up->uia_arr[x]->ui_utmp.ut_host,
! 151: sizeof(remote)-1);
! 152: if (strlen(remote) != 0)
! 153: sprintf(remote, "(%.16s)",
! 154: up->uia_arr[x]->ui_utmp.ut_host);
! 155:
! 156: if (longopt) {
! 157: strncpy(local, host, sizeof(local));
! 158: local[HOST_WIDTH + LINE_WIDTH + 1 -
! 159: strlen(up->uia_arr[x]->ui_utmp.ut_line) - 1] = 0;
! 160: strcat(local, ":");
! 161: strcat(local, up->uia_arr[x]->ui_utmp.ut_line);
! 162:
! 163: printf("%-8.8s %-*.*s %-12.12s %8s %.18s\n",
! 164: up->uia_arr[x]->ui_utmp.ut_name,
! 165: HOST_WIDTH+LINE_WIDTH+1, HOST_WIDTH+LINE_WIDTH+1, local,
! 166: date,
! 167: idle_time,
! 168: remote);
! 169: } else
! 170: printf("%0.8s ",
! 171: up->uia_arr[x]->ui_utmp.ut_name);
! 172: }
! 173: if (!longopt)
! 174: putchar('\n');
! 175:
! 176: remember_host(raddrp->sin_addr);
! 177: return(0);
! 178: }
! 179:
! 180: void
! 181: onehost(char *host)
! 182: {
! 183: struct utmpidlearr up;
! 184: CLIENT *rusers_clnt;
! 185: struct sockaddr_in addr;
! 186: struct hostent *hp;
! 187:
! 188: hp = gethostbyname(host);
! 189: if (hp == NULL) {
! 190: fprintf(stderr, "%s: unknown host \"%s\"\n",
! 191: argv0, host);
! 192: exit(1);
! 193: }
! 194:
! 195: rusers_clnt = clnt_create(host, RUSERSPROG, RUSERSVERS_IDLE, "udp");
! 196: if (rusers_clnt == NULL) {
! 197: clnt_pcreateerror(argv0);
! 198: exit(1);
! 199: }
! 200:
! 201: bzero((char *)&up, sizeof(up));
! 202: if (clnt_call(rusers_clnt, RUSERSPROC_NAMES, xdr_void, NULL,
! 203: xdr_utmpidlearr, &up, timeout) != RPC_SUCCESS) {
! 204: clnt_perror(rusers_clnt, argv0);
! 205: exit(1);
! 206: }
! 207: addr.sin_addr.s_addr = *(int *)hp->h_addr;
! 208: rusers_reply((char *)&up, &addr);
! 209: }
! 210:
! 211: void
! 212: allhosts(void)
! 213: {
! 214: struct utmpidlearr up;
! 215: enum clnt_stat clnt_stat;
! 216:
! 217: bzero((char *)&up, sizeof(up));
! 218: clnt_stat = clnt_broadcast(RUSERSPROG, RUSERSVERS_IDLE,
! 219: RUSERSPROC_NAMES, xdr_void, NULL, xdr_utmpidlearr,
! 220: &up, rusers_reply);
! 221: if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) {
! 222: fprintf(stderr, "%s: %s\n", argv0, clnt_sperrno(clnt_stat));
! 223: exit(1);
! 224: }
! 225: }
! 226:
! 227: void usage(void)
! 228: {
! 229: fprintf(stderr, "Usage: %s [-la] [hosts ...]\n", argv0);
! 230: exit(1);
! 231: }
! 232:
! 233: void main(int argc, char *argv[])
! 234: {
! 235: int ch;
! 236: extern int optind;
! 237:
! 238: if (!(argv0 = rindex(argv[0], '/')))
! 239: argv0 = argv[0];
! 240: else
! 241: argv0++;
! 242:
! 243:
! 244: while ((ch = getopt(argc, argv, "al")) != -1)
! 245: switch (ch) {
! 246: case 'a':
! 247: allopt++;
! 248: break;
! 249: case 'l':
! 250: longopt++;
! 251: break;
! 252: default:
! 253: usage();
! 254: /*NOTREACHED*/
! 255: }
! 256:
! 257: setlinebuf(stdout);
! 258: if (argc == optind)
! 259: allhosts();
! 260: else {
! 261: for (; optind < argc; optind++)
! 262: (void) onehost(argv[optind]);
! 263: }
! 264: exit(0);
! 265: }