1
0
Files
irix-657m-src/eoe/cmd/sun/rusers.c
2022-09-29 17:59:04 +03:00

408 lines
8.5 KiB
C

/* @(#)rusers.c 1.1 87/07/28 3.2/4.3 NFSSRC */
#ifndef lint
static char sccsid[] = "@(#)rusers.c 1.1 86/09/25 Copyr 1985 Sun Micro";
#endif
/*
* Copyright (c) 1985 by Sun Microsystems, Inc.
*/
#include <stdio.h>
#include <netdb.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <rpc/rpc.h>
#include <rpc/pmap_clnt.h>
#include <rpcsvc/rusers.h>
#include <netinet/in.h>
#include <arpa/inet.h>
struct rusers_utmp dummy;
#define NMAX sizeof(dummy.ut_name)
#define LMAX sizeof(dummy.ut_line)
#define HMAX sizeof(dummy.ut_host)
#define MACHINELEN 32 /* length of machine name printed out */
#define NUMENTRIES 200
#define MAXINT 0x7fffffff
#define min(a,b) ((a) < (b) ? (a) : (b))
struct entry {
struct in_addr addr;
int cnt;
int idle; /* set to MAXINT if not present */
char *machine;
struct utmpidle *users;
} *entry;
int numentries = NUMENTRIES; /*default number of host entries */
int curentry;
int nflag; /* caller specified number of host entires*/
int hflag; /* host: sort by machine name */
int iflag; /* idle: sort by idle time */
int uflag; /* users: sort by number of users */
int lflag; /* print out long form */
int aflag; /* all: list all machines */
int dflag; /* debug: list only first n machines */
int debug;
int vers;
int hcompare(), icompare(), ucompare();
int collectnames();
main(argc, argv)
char **argv;
{
struct utmpidlearr utmpidlearr;
enum clnt_stat clnt_stat;
int single;
single = 0;
entry = malloc (numentries * (sizeof *entry));
/* pre-allocate the default */
while (argc > 1) {
if (argv[1][0] != '-') {
single++;
singlehost(argv[1]);
}
else {
switch(argv[1][1]) {
case 'h':
hflag++;
break;
case 'a':
aflag++;
break;
case 'i':
iflag++;
break;
case 'l':
lflag++;
break;
case 'n':
nflag++;
if (argc < 3)
usage();
numentries = atoi(argv[2]);
free (entry); /* remove previous */
entry = malloc (numentries * (sizeof *entry));
argc--;
argv++;
break;
case 'u':
uflag++;
break;
case 'd':
dflag++;
if (argc < 3)
usage();
debug = atoi(argv[2]);
argc--;
argv++;
break;
default:
usage();
}
}
argv++;
argc--;
}
if (iflag + hflag + uflag > 1)
usage();
if (single > 0) {
if (iflag || hflag || uflag)
printnames();
exit(0);
}
if (iflag || hflag || uflag) {
printf("collecting responses... ");
fflush(stdout);
}
vers = RUSERSVERS_IDLE;
utmpidlearr.uia_arr = NULL;
clnt_stat = clnt_broadcast(RUSERSPROG, RUSERSVERS_IDLE,
RUSERSPROC_NAMES, xdr_void, NULL, xdr_utmpidlearr,
&utmpidlearr, collectnames);
#ifdef TESTING
fprintf(stderr, "starting second round of broadcasting\n");
#endif
vers = RUSERSVERS_ORIG;
clnt_stat = clnt_broadcast(RUSERSPROG, RUSERSVERS_ORIG,
RUSERSPROC_NAMES, xdr_void, NULL, xdr_utmparr, &utmpidlearr,
collectnames);
if (iflag || hflag || uflag)
printnames();
}
singlehost(name)
char *name;
{
struct hostent *hp;
enum clnt_stat err;
struct sockaddr_in addr;
struct utmpidlearr utmpidlearr;
vers = RUSERSVERS_ORIG;
utmpidlearr.uia_arr = NULL;
err = (enum clnt_stat)callrpc(name, RUSERSPROG, RUSERSVERS_IDLE,
RUSERSPROC_NAMES, xdr_void, 0, xdr_utmpidlearr, &utmpidlearr);
if (err == RPC_PROGVERSMISMATCH) {
if (err = (enum clnt_stat)callrpc(name, RUSERSPROG,
RUSERSVERS_ORIG, RUSERSPROC_NAMES, xdr_void, 0,
xdr_utmparr, &utmpidlearr)) {
fprintf(stderr, "rusers: %s: ", name);
clnt_perrno(err);
fprintf(stderr, "\n");
return;
}
}
else if (err == RPC_SUCCESS)
vers = RUSERSVERS_IDLE;
else {
fprintf(stderr, "rusers: %s: ", name);
clnt_perrno(err);
fprintf(stderr, "\n");
return;
}
/*
* simulate calling from clnt_broadcast
*/
hp = gethostbyname(name);
if (hp == NULL) {
fprintf(stderr, "rusers: can't find %s in hosts database\n",
name);
exit(1);
}
addr.sin_addr.s_addr = *(int *)hp->h_addr;
collectnames(&utmpidlearr, &addr);
return;
}
collectnames(resultsp, raddrp)
char *resultsp;
struct sockaddr_in *raddrp;
{
struct utmpidlearr utmpidlearr;
struct utmpidle *uip;
struct rusers_utmp *up;
static int debugcnt;
int i, cnt, minidle;
struct in_addr addr;
register struct entry *entryp, *lim;
struct utmpidle *p, *q;
struct hostent *hp;
char *host;
utmpidlearr = *(struct utmpidlearr *)resultsp;
if ((cnt = utmpidlearr.uia_cnt) < 1 && !aflag)
return(0);
/*
* weed out duplicates
*/
addr = raddrp->sin_addr;
lim = entry + curentry;
for (entryp = entry; entryp < lim; entryp++)
if (addr.s_addr == entryp->addr.s_addr)
return (0);
debugcnt++;
entry[curentry].addr = addr;
hp = gethostbyaddr((char *)&raddrp->sin_addr.s_addr,
sizeof(int),AF_INET);
if (hp == NULL)
host = inet_ntoa(addr);
else
host = hp->h_name;
/*
* if raw, print this entry out immediately
* otherwise store for later sorting
*/
if (!iflag && !hflag && !uflag) {
if (lflag)
for (i = 0; i < cnt; i++)
putline(host, utmpidlearr.uia_arr[i], vers);
else {
printf("%-*s", MACHINELEN, host);
for (i = 0; i < cnt; i++)
printf(" %.*s", NMAX,
utmpidlearr.uia_arr[i]->ui_utmp.ut_name);
printf("\n");
}
}
else {
entry[curentry].cnt = cnt;
q = (struct utmpidle *)
malloc(cnt*sizeof(struct utmpidle));
p = q;
minidle = MAXINT;
for (i = 0; i < cnt; i++) {
bcopy(utmpidlearr.uia_arr[i], q,
sizeof(struct utmpidle));
if (vers == RUSERSVERS_IDLE)
minidle = min(minidle, q->ui_idle);
q++;
}
entry[curentry].users = p;
entry[curentry].idle = minidle;
}
if (curentry >= numentries) {
fprintf(stderr, "rusers: too many hosts on network\n");
exit(1);
}
curentry++;
if (dflag && debugcnt >= debug)
return (1);
return(0);
}
printnames()
{
char *host;
struct hostent *hp;
int i, j, v;
int (*compare)();
for (i = 0; i < curentry; i++) {
hp = gethostbyaddr((char *)&entry[i].addr,sizeof(int),AF_INET);
if (hp == NULL)
host = inet_ntoa(entry[i].addr);
else
host = hp->h_name;
entry[i].machine = (char *)malloc(MACHINELEN+1);
strcpy(entry[i].machine, host);
}
if (iflag)
compare = icompare;
else if (hflag)
compare = hcompare;
else
compare = ucompare;
qsort(entry, curentry, sizeof(struct entry), compare);
printf("\n");
for (i = 0; i < curentry; i++) {
if (!lflag) {
printf("%-*.*s", MACHINELEN,
MACHINELEN, entry[i].machine);
for (j = 0; j < entry[i].cnt; j++)
printf(" %.*s", NMAX,
entry[i].users[j].ui_utmp.ut_name);
printf("\n");
}
else {
if (entry[i].idle == MAXINT)
v = RUSERSVERS_ORIG;
else
v = RUSERSVERS_IDLE;
for (j = 0; j < entry[i].cnt; j++)
putline(entry[i].machine,
&entry[i].users[j], v);
}
}
}
hcompare(a,b)
struct entry *a, *b;
{
return (strcmp(a->machine, b->machine));
}
ucompare(a,b)
struct entry *a, *b;
{
return (b->cnt - a->cnt);
}
icompare(a,b)
struct entry *a, *b;
{
return (a->idle - b->idle);
}
putline(host, uip, vers)
char *host;
struct utmpidle *uip;
int vers;
{
register char *cbuf;
struct rusers_utmp *up;
struct hostent *hp;
char buf[MAXHOSTNAMELEN+LMAX+1];
up = &uip->ui_utmp;
printf("%-*.*s ", NMAX, NMAX, up->ut_name);
strcpy(buf, host);
strcat(buf, ":");
strncat(buf, up->ut_line, LMAX);
printf("%-*s", 30, buf);
cbuf = (char *)ctime(&up->ut_time);
printf(" %.12s ", cbuf+4);
if (vers == RUSERSVERS_IDLE && uip->ui_idle != MAXINT) {
prttime(uip->ui_idle, "");
}
else
printf(" ??");
if (up->ut_host[0])
printf(" (%.*s)", HMAX, up->ut_host);
putchar('\n');
}
/*
* prttime prints a time in hours and minutes.
* The character string tail is printed at the end, obvious
* strings to pass are "", " ", or "am".
*/
prttime(tim, tail)
time_t tim;
char *tail;
{
register int didhrs = 0;
if (tim >= 60) {
printf("%3d:", tim/60);
didhrs++;
} else {
printf(" ");
}
tim %= 60;
if (tim > 0 || didhrs) {
printf(didhrs&&tim<10 ? "%02d" : "%2d", tim);
} else {
printf(" ");
}
printf("%s", tail);
}
/*
* for debugging
*/
printit(i)
{
int j, v;
printf("%12.12s: ", entry[i].machine);
if (entry[i].cnt) {
if (entry[i].idle == MAXINT)
v = RUSERSVERS_ORIG;
else
v = RUSERSVERS_IDLE;
putline(&entry[i].users[0], v);
for (j = 1; j < entry[i].cnt; j++) {
printf("\t");
putline(&entry[i].users[j], vers);
}
}
else
printf("\n");
}
usage()
{
fprintf(stderr, "Usage: rusers [-a] [-h] [-i] [-l] [-u] [host ...]\n");
exit(1);
}