1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate *
4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate * with the License.
8*7c478bd9Sstevel@tonic-gate *
9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate *
14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate *
20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate */
22*7c478bd9Sstevel@tonic-gate
23*7c478bd9Sstevel@tonic-gate /*
24*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
25*7c478bd9Sstevel@tonic-gate * Use is subject to license terms.
26*7c478bd9Sstevel@tonic-gate */
27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */
29*7c478bd9Sstevel@tonic-gate /*
30*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988
31*7c478bd9Sstevel@tonic-gate * The Regents of the University of California
32*7c478bd9Sstevel@tonic-gate * All Rights Reserved
33*7c478bd9Sstevel@tonic-gate *
34*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from
35*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its
36*7c478bd9Sstevel@tonic-gate * contributors.
37*7c478bd9Sstevel@tonic-gate */
38*7c478bd9Sstevel@tonic-gate
39*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
40*7c478bd9Sstevel@tonic-gate #include <stdio.h>
41*7c478bd9Sstevel@tonic-gate #include <unistd.h>
42*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
43*7c478bd9Sstevel@tonic-gate #include <netconfig.h>
44*7c478bd9Sstevel@tonic-gate #include <netdir.h>
45*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
46*7c478bd9Sstevel@tonic-gate #include <rpcsvc/rusers.h>
47*7c478bd9Sstevel@tonic-gate #include <string.h>
48*7c478bd9Sstevel@tonic-gate #include <limits.h>
49*7c478bd9Sstevel@tonic-gate
50*7c478bd9Sstevel@tonic-gate #define NMAX 12 /* These are used as field width specifiers */
51*7c478bd9Sstevel@tonic-gate #define LMAX 8 /* when printing. */
52*7c478bd9Sstevel@tonic-gate #define HMAX 16 /* "Logged in" host name. */
53*7c478bd9Sstevel@tonic-gate
54*7c478bd9Sstevel@tonic-gate #define MACHINELEN 16 /* length of machine name printed out */
55*7c478bd9Sstevel@tonic-gate #define NUMENTRIES 256
56*7c478bd9Sstevel@tonic-gate #define min(a, b) ((a) < (b) ? (a) : (b))
57*7c478bd9Sstevel@tonic-gate
58*7c478bd9Sstevel@tonic-gate struct entry {
59*7c478bd9Sstevel@tonic-gate int cnt;
60*7c478bd9Sstevel@tonic-gate int idle; /* set to INT_MAX if not present */
61*7c478bd9Sstevel@tonic-gate char *machine;
62*7c478bd9Sstevel@tonic-gate utmp_array users;
63*7c478bd9Sstevel@tonic-gate };
64*7c478bd9Sstevel@tonic-gate
65*7c478bd9Sstevel@tonic-gate static int curentry;
66*7c478bd9Sstevel@tonic-gate static int total_entries;
67*7c478bd9Sstevel@tonic-gate static struct entry *entry;
68*7c478bd9Sstevel@tonic-gate static int hflag; /* host: sort by machine name */
69*7c478bd9Sstevel@tonic-gate static int iflag; /* idle: sort by idle time */
70*7c478bd9Sstevel@tonic-gate static int uflag; /* users: sort by number of users */
71*7c478bd9Sstevel@tonic-gate static int lflag; /* print out long form */
72*7c478bd9Sstevel@tonic-gate static int aflag; /* all: list all machines */
73*7c478bd9Sstevel@tonic-gate static int dflag; /* debug: list only first n machines */
74*7c478bd9Sstevel@tonic-gate static int sorted;
75*7c478bd9Sstevel@tonic-gate static int debug;
76*7c478bd9Sstevel@tonic-gate static int debugcnt;
77*7c478bd9Sstevel@tonic-gate static char *nettype;
78*7c478bd9Sstevel@tonic-gate
79*7c478bd9Sstevel@tonic-gate static int hcompare(const struct entry *, const struct entry *);
80*7c478bd9Sstevel@tonic-gate static int icompare(const struct entry *, const struct entry *);
81*7c478bd9Sstevel@tonic-gate static int ucompare(const struct entry *, const struct entry *);
82*7c478bd9Sstevel@tonic-gate static int print_info(struct utmpidlearr *, const char *);
83*7c478bd9Sstevel@tonic-gate static int print_info_3(utmp_array *, const char *);
84*7c478bd9Sstevel@tonic-gate static int collectnames(void *, struct netbuf *, struct netconfig *);
85*7c478bd9Sstevel@tonic-gate static int collectnames_3(void *, struct netbuf *, struct netconfig *);
86*7c478bd9Sstevel@tonic-gate static void singlehost(char *);
87*7c478bd9Sstevel@tonic-gate static void printnames(void);
88*7c478bd9Sstevel@tonic-gate static void putline_2(char *, struct utmpidle *);
89*7c478bd9Sstevel@tonic-gate static void putline_3(char *, rusers_utmp *);
90*7c478bd9Sstevel@tonic-gate static void prttime(uint_t, char *);
91*7c478bd9Sstevel@tonic-gate static void usage(void);
92*7c478bd9Sstevel@tonic-gate
93*7c478bd9Sstevel@tonic-gate /*
94*7c478bd9Sstevel@tonic-gate * rusers [-ahilu] [host...]
95*7c478bd9Sstevel@tonic-gate */
96*7c478bd9Sstevel@tonic-gate int
main(int argc,char * argv[])97*7c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
98*7c478bd9Sstevel@tonic-gate {
99*7c478bd9Sstevel@tonic-gate int c;
100*7c478bd9Sstevel@tonic-gate uint_t errflag = 0;
101*7c478bd9Sstevel@tonic-gate uint_t single = 0;
102*7c478bd9Sstevel@tonic-gate struct utmpidlearr utmpidlearr;
103*7c478bd9Sstevel@tonic-gate utmp_array utmp_array_res;
104*7c478bd9Sstevel@tonic-gate
105*7c478bd9Sstevel@tonic-gate curentry = 0;
106*7c478bd9Sstevel@tonic-gate total_entries = NUMENTRIES;
107*7c478bd9Sstevel@tonic-gate entry = malloc(sizeof (struct entry) * total_entries);
108*7c478bd9Sstevel@tonic-gate
109*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, ":ad:hilun:")) != -1) {
110*7c478bd9Sstevel@tonic-gate switch (c) {
111*7c478bd9Sstevel@tonic-gate case 'a':
112*7c478bd9Sstevel@tonic-gate aflag++;
113*7c478bd9Sstevel@tonic-gate break;
114*7c478bd9Sstevel@tonic-gate case 'd':
115*7c478bd9Sstevel@tonic-gate dflag++;
116*7c478bd9Sstevel@tonic-gate debug = atoi(optarg);
117*7c478bd9Sstevel@tonic-gate (void) printf("Will collect %d responses.\n", debug);
118*7c478bd9Sstevel@tonic-gate break;
119*7c478bd9Sstevel@tonic-gate case 'h':
120*7c478bd9Sstevel@tonic-gate hflag++;
121*7c478bd9Sstevel@tonic-gate sorted++;
122*7c478bd9Sstevel@tonic-gate if (iflag || uflag)
123*7c478bd9Sstevel@tonic-gate errflag++;
124*7c478bd9Sstevel@tonic-gate break;
125*7c478bd9Sstevel@tonic-gate case 'i':
126*7c478bd9Sstevel@tonic-gate iflag++;
127*7c478bd9Sstevel@tonic-gate sorted++;
128*7c478bd9Sstevel@tonic-gate if (hflag || uflag)
129*7c478bd9Sstevel@tonic-gate errflag++;
130*7c478bd9Sstevel@tonic-gate break;
131*7c478bd9Sstevel@tonic-gate case 'u':
132*7c478bd9Sstevel@tonic-gate uflag++;
133*7c478bd9Sstevel@tonic-gate sorted++;
134*7c478bd9Sstevel@tonic-gate if (hflag || iflag)
135*7c478bd9Sstevel@tonic-gate errflag++;
136*7c478bd9Sstevel@tonic-gate break;
137*7c478bd9Sstevel@tonic-gate case 'l':
138*7c478bd9Sstevel@tonic-gate lflag++;
139*7c478bd9Sstevel@tonic-gate break;
140*7c478bd9Sstevel@tonic-gate case ':': /* required operand missing */
141*7c478bd9Sstevel@tonic-gate errflag++;
142*7c478bd9Sstevel@tonic-gate break;
143*7c478bd9Sstevel@tonic-gate case 'n':
144*7c478bd9Sstevel@tonic-gate nettype = optarg;
145*7c478bd9Sstevel@tonic-gate break;
146*7c478bd9Sstevel@tonic-gate default:
147*7c478bd9Sstevel@tonic-gate case '?': /* Unrecognized option */
148*7c478bd9Sstevel@tonic-gate errflag++;
149*7c478bd9Sstevel@tonic-gate break;
150*7c478bd9Sstevel@tonic-gate }
151*7c478bd9Sstevel@tonic-gate }
152*7c478bd9Sstevel@tonic-gate if (errflag)
153*7c478bd9Sstevel@tonic-gate usage();
154*7c478bd9Sstevel@tonic-gate
155*7c478bd9Sstevel@tonic-gate for (; optind < argc; optind++) {
156*7c478bd9Sstevel@tonic-gate single++;
157*7c478bd9Sstevel@tonic-gate singlehost(argv[optind]);
158*7c478bd9Sstevel@tonic-gate }
159*7c478bd9Sstevel@tonic-gate if (single) {
160*7c478bd9Sstevel@tonic-gate if (sorted)
161*7c478bd9Sstevel@tonic-gate printnames();
162*7c478bd9Sstevel@tonic-gate free(entry);
163*7c478bd9Sstevel@tonic-gate exit(0);
164*7c478bd9Sstevel@tonic-gate }
165*7c478bd9Sstevel@tonic-gate
166*7c478bd9Sstevel@tonic-gate if (sorted) {
167*7c478bd9Sstevel@tonic-gate (void) printf("Collecting responses...\n");
168*7c478bd9Sstevel@tonic-gate (void) fflush(stdout);
169*7c478bd9Sstevel@tonic-gate }
170*7c478bd9Sstevel@tonic-gate utmp_array_res.utmp_array_val = NULL;
171*7c478bd9Sstevel@tonic-gate utmp_array_res.utmp_array_len = 0;
172*7c478bd9Sstevel@tonic-gate (void) printf("Sending broadcast for rusersd protocol version 3...\n");
173*7c478bd9Sstevel@tonic-gate (void) rpc_broadcast(RUSERSPROG, RUSERSVERS_3,
174*7c478bd9Sstevel@tonic-gate RUSERSPROC_NAMES, (xdrproc_t)xdr_void, NULL,
175*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_utmp_array, (char *)&utmp_array_res,
176*7c478bd9Sstevel@tonic-gate (resultproc_t)collectnames_3, nettype);
177*7c478bd9Sstevel@tonic-gate utmpidlearr.uia_arr = NULL;
178*7c478bd9Sstevel@tonic-gate (void) printf("Sending broadcast for rusersd protocol version 2...\n");
179*7c478bd9Sstevel@tonic-gate (void) rpc_broadcast(RUSERSPROG, RUSERSVERS_IDLE,
180*7c478bd9Sstevel@tonic-gate RUSERSPROC_NAMES, (xdrproc_t)xdr_void, NULL,
181*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_utmpidlearr, (char *)&utmpidlearr,
182*7c478bd9Sstevel@tonic-gate (resultproc_t)collectnames, nettype);
183*7c478bd9Sstevel@tonic-gate
184*7c478bd9Sstevel@tonic-gate if (sorted)
185*7c478bd9Sstevel@tonic-gate printnames();
186*7c478bd9Sstevel@tonic-gate
187*7c478bd9Sstevel@tonic-gate free(entry);
188*7c478bd9Sstevel@tonic-gate return (0);
189*7c478bd9Sstevel@tonic-gate }
190*7c478bd9Sstevel@tonic-gate
191*7c478bd9Sstevel@tonic-gate static void
singlehost(char * name)192*7c478bd9Sstevel@tonic-gate singlehost(char *name)
193*7c478bd9Sstevel@tonic-gate {
194*7c478bd9Sstevel@tonic-gate enum clnt_stat err;
195*7c478bd9Sstevel@tonic-gate struct utmpidlearr utmpidlearr;
196*7c478bd9Sstevel@tonic-gate utmp_array utmp_array_res;
197*7c478bd9Sstevel@tonic-gate
198*7c478bd9Sstevel@tonic-gate if (curentry >= total_entries) {
199*7c478bd9Sstevel@tonic-gate struct entry *tmp;
200*7c478bd9Sstevel@tonic-gate
201*7c478bd9Sstevel@tonic-gate total_entries += NUMENTRIES;
202*7c478bd9Sstevel@tonic-gate if ((tmp = realloc(entry, sizeof (struct entry)
203*7c478bd9Sstevel@tonic-gate * total_entries)) == NULL)
204*7c478bd9Sstevel@tonic-gate return;
205*7c478bd9Sstevel@tonic-gate entry = tmp;
206*7c478bd9Sstevel@tonic-gate }
207*7c478bd9Sstevel@tonic-gate utmp_array_res.utmp_array_val = NULL;
208*7c478bd9Sstevel@tonic-gate utmp_array_res.utmp_array_len = 0;
209*7c478bd9Sstevel@tonic-gate err = rpc_call(name, RUSERSPROG, RUSERSVERS_3,
210*7c478bd9Sstevel@tonic-gate RUSERSPROC_NAMES, (xdrproc_t)xdr_void, 0,
211*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_utmp_array, (char *)&utmp_array_res,
212*7c478bd9Sstevel@tonic-gate nettype);
213*7c478bd9Sstevel@tonic-gate if (err == RPC_SUCCESS) {
214*7c478bd9Sstevel@tonic-gate (void) print_info_3(&utmp_array_res, name);
215*7c478bd9Sstevel@tonic-gate return;
216*7c478bd9Sstevel@tonic-gate }
217*7c478bd9Sstevel@tonic-gate if (err == RPC_PROGVERSMISMATCH) {
218*7c478bd9Sstevel@tonic-gate utmpidlearr.uia_arr = NULL;
219*7c478bd9Sstevel@tonic-gate err = rpc_call(name, RUSERSPROG, RUSERSVERS_IDLE,
220*7c478bd9Sstevel@tonic-gate RUSERSPROC_NAMES, (xdrproc_t)xdr_void, 0,
221*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_utmpidlearr,
222*7c478bd9Sstevel@tonic-gate (char *)&utmpidlearr, nettype);
223*7c478bd9Sstevel@tonic-gate }
224*7c478bd9Sstevel@tonic-gate if (err != RPC_SUCCESS) {
225*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: ", name);
226*7c478bd9Sstevel@tonic-gate clnt_perrno(err);
227*7c478bd9Sstevel@tonic-gate return;
228*7c478bd9Sstevel@tonic-gate }
229*7c478bd9Sstevel@tonic-gate (void) print_info(&utmpidlearr, name);
230*7c478bd9Sstevel@tonic-gate }
231*7c478bd9Sstevel@tonic-gate
232*7c478bd9Sstevel@tonic-gate /*
233*7c478bd9Sstevel@tonic-gate * Collect responses from RUSERSVERS_IDLE broadcast, convert to
234*7c478bd9Sstevel@tonic-gate * RUSERSVERS_3 format, and store in entry database.
235*7c478bd9Sstevel@tonic-gate */
236*7c478bd9Sstevel@tonic-gate static int
collectnames(void * resultsp,struct netbuf * raddrp,struct netconfig * nconf)237*7c478bd9Sstevel@tonic-gate collectnames(void *resultsp, struct netbuf *raddrp, struct netconfig *nconf)
238*7c478bd9Sstevel@tonic-gate {
239*7c478bd9Sstevel@tonic-gate struct utmpidlearr utmpidlearr;
240*7c478bd9Sstevel@tonic-gate struct entry *entryp, *lim;
241*7c478bd9Sstevel@tonic-gate struct nd_hostservlist *hs;
242*7c478bd9Sstevel@tonic-gate char host[MACHINELEN + 1];
243*7c478bd9Sstevel@tonic-gate
244*7c478bd9Sstevel@tonic-gate utmpidlearr = *(struct utmpidlearr *)resultsp;
245*7c478bd9Sstevel@tonic-gate if (utmpidlearr.uia_cnt < 1 && !aflag)
246*7c478bd9Sstevel@tonic-gate return (0);
247*7c478bd9Sstevel@tonic-gate
248*7c478bd9Sstevel@tonic-gate if (netdir_getbyaddr(nconf, &hs, raddrp)) {
249*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
250*7c478bd9Sstevel@tonic-gate netdir_perror("netdir_getbyaddr");
251*7c478bd9Sstevel@tonic-gate #endif
252*7c478bd9Sstevel@tonic-gate /* netdir routine couldn't resolve addr;just print out uaddr */
253*7c478bd9Sstevel@tonic-gate (void) sprintf(host, "%.*s", MACHINELEN,
254*7c478bd9Sstevel@tonic-gate taddr2uaddr(nconf, raddrp));
255*7c478bd9Sstevel@tonic-gate } else {
256*7c478bd9Sstevel@tonic-gate (void) sprintf(host, "%.*s", MACHINELEN,
257*7c478bd9Sstevel@tonic-gate hs->h_hostservs->h_host);
258*7c478bd9Sstevel@tonic-gate netdir_free((char *)hs, ND_HOSTSERVLIST);
259*7c478bd9Sstevel@tonic-gate }
260*7c478bd9Sstevel@tonic-gate /*
261*7c478bd9Sstevel@tonic-gate * need to realloc more space if we have more than 256 machines
262*7c478bd9Sstevel@tonic-gate * that respond to broadcast
263*7c478bd9Sstevel@tonic-gate */
264*7c478bd9Sstevel@tonic-gate if (curentry >= total_entries) {
265*7c478bd9Sstevel@tonic-gate struct entry *tmp;
266*7c478bd9Sstevel@tonic-gate
267*7c478bd9Sstevel@tonic-gate total_entries += NUMENTRIES;
268*7c478bd9Sstevel@tonic-gate if ((tmp = realloc(entry, sizeof (struct entry)
269*7c478bd9Sstevel@tonic-gate * total_entries)) == NULL)
270*7c478bd9Sstevel@tonic-gate return (1);
271*7c478bd9Sstevel@tonic-gate entry = tmp;
272*7c478bd9Sstevel@tonic-gate }
273*7c478bd9Sstevel@tonic-gate
274*7c478bd9Sstevel@tonic-gate
275*7c478bd9Sstevel@tonic-gate /*
276*7c478bd9Sstevel@tonic-gate * weed out duplicates
277*7c478bd9Sstevel@tonic-gate */
278*7c478bd9Sstevel@tonic-gate lim = entry + curentry;
279*7c478bd9Sstevel@tonic-gate for (entryp = entry; entryp < lim; entryp++) {
280*7c478bd9Sstevel@tonic-gate if (strcmp(entryp->machine, host) == 0)
281*7c478bd9Sstevel@tonic-gate return (0);
282*7c478bd9Sstevel@tonic-gate }
283*7c478bd9Sstevel@tonic-gate return (print_info((struct utmpidlearr *)resultsp, host));
284*7c478bd9Sstevel@tonic-gate }
285*7c478bd9Sstevel@tonic-gate
286*7c478bd9Sstevel@tonic-gate static int
print_info(struct utmpidlearr * utmpidlearrp,const char * name)287*7c478bd9Sstevel@tonic-gate print_info(struct utmpidlearr *utmpidlearrp, const char *name)
288*7c478bd9Sstevel@tonic-gate {
289*7c478bd9Sstevel@tonic-gate utmp_array *iconvert;
290*7c478bd9Sstevel@tonic-gate int i, cnt, minidle;
291*7c478bd9Sstevel@tonic-gate char host[MACHINELEN + 1];
292*7c478bd9Sstevel@tonic-gate char username[NMAX + 1];
293*7c478bd9Sstevel@tonic-gate
294*7c478bd9Sstevel@tonic-gate cnt = utmpidlearrp->uia_cnt;
295*7c478bd9Sstevel@tonic-gate (void) sprintf(host, "%.*s", MACHINELEN, name);
296*7c478bd9Sstevel@tonic-gate
297*7c478bd9Sstevel@tonic-gate /*
298*7c478bd9Sstevel@tonic-gate * if raw, print this entry out immediately
299*7c478bd9Sstevel@tonic-gate * otherwise store for later sorting
300*7c478bd9Sstevel@tonic-gate */
301*7c478bd9Sstevel@tonic-gate if (!sorted) {
302*7c478bd9Sstevel@tonic-gate if (lflag && (cnt > 0))
303*7c478bd9Sstevel@tonic-gate for (i = 0; i < cnt; i++)
304*7c478bd9Sstevel@tonic-gate putline_2(host, utmpidlearrp->uia_arr[i]);
305*7c478bd9Sstevel@tonic-gate else {
306*7c478bd9Sstevel@tonic-gate (void) printf("%-*.*s", MACHINELEN, MACHINELEN, host);
307*7c478bd9Sstevel@tonic-gate for (i = 0; i < cnt; i++) {
308*7c478bd9Sstevel@tonic-gate (void) strlcpy(username,
309*7c478bd9Sstevel@tonic-gate utmpidlearrp->uia_arr[i]->ui_utmp.ut_name,
310*7c478bd9Sstevel@tonic-gate NMAX + 1);
311*7c478bd9Sstevel@tonic-gate (void) printf(" %.*s", NMAX, username);
312*7c478bd9Sstevel@tonic-gate }
313*7c478bd9Sstevel@tonic-gate (void) printf("\n");
314*7c478bd9Sstevel@tonic-gate }
315*7c478bd9Sstevel@tonic-gate /* store just the name */
316*7c478bd9Sstevel@tonic-gate entry[curentry].machine = malloc(MACHINELEN + 1);
317*7c478bd9Sstevel@tonic-gate if (entry[curentry].machine == NULL) {
318*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Ran out of memory - exiting\n");
319*7c478bd9Sstevel@tonic-gate exit(1);
320*7c478bd9Sstevel@tonic-gate }
321*7c478bd9Sstevel@tonic-gate (void) strlcpy(entry[curentry].machine, name, MACHINELEN + 1);
322*7c478bd9Sstevel@tonic-gate entry[curentry++].cnt = 0;
323*7c478bd9Sstevel@tonic-gate if (dflag && (++debugcnt >= debug))
324*7c478bd9Sstevel@tonic-gate return (1);
325*7c478bd9Sstevel@tonic-gate return (0);
326*7c478bd9Sstevel@tonic-gate }
327*7c478bd9Sstevel@tonic-gate entry[curentry].machine = malloc(MACHINELEN + 1);
328*7c478bd9Sstevel@tonic-gate if (entry[curentry].machine == NULL) {
329*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Ran out of memory - exiting\n");
330*7c478bd9Sstevel@tonic-gate exit(1);
331*7c478bd9Sstevel@tonic-gate }
332*7c478bd9Sstevel@tonic-gate (void) strlcpy(entry[curentry].machine, name, MACHINELEN + 1);
333*7c478bd9Sstevel@tonic-gate entry[curentry].cnt = cnt;
334*7c478bd9Sstevel@tonic-gate iconvert = &entry[curentry].users;
335*7c478bd9Sstevel@tonic-gate iconvert->utmp_array_len = cnt;
336*7c478bd9Sstevel@tonic-gate iconvert->utmp_array_val = malloc(cnt * sizeof (rusers_utmp));
337*7c478bd9Sstevel@tonic-gate minidle = INT_MAX;
338*7c478bd9Sstevel@tonic-gate for (i = 0; i < cnt; i++) {
339*7c478bd9Sstevel@tonic-gate iconvert->utmp_array_val[i].ut_user =
340*7c478bd9Sstevel@tonic-gate strdup(utmpidlearrp->uia_arr[i]->ui_utmp.ut_name);
341*7c478bd9Sstevel@tonic-gate iconvert->utmp_array_val[i].ut_line =
342*7c478bd9Sstevel@tonic-gate strdup(utmpidlearrp->uia_arr[i]->ui_utmp.ut_line);
343*7c478bd9Sstevel@tonic-gate iconvert->utmp_array_val[i].ut_host =
344*7c478bd9Sstevel@tonic-gate strdup(utmpidlearrp->uia_arr[i]->ui_utmp.ut_host);
345*7c478bd9Sstevel@tonic-gate iconvert->utmp_array_val[i].ut_time =
346*7c478bd9Sstevel@tonic-gate utmpidlearrp->uia_arr[i]->ui_utmp.ut_time;
347*7c478bd9Sstevel@tonic-gate iconvert->utmp_array_val[i].ut_idle =
348*7c478bd9Sstevel@tonic-gate utmpidlearrp->uia_arr[i]->ui_idle;
349*7c478bd9Sstevel@tonic-gate minidle = min(minidle, utmpidlearrp->uia_arr[i]->ui_idle);
350*7c478bd9Sstevel@tonic-gate }
351*7c478bd9Sstevel@tonic-gate entry[curentry].idle = minidle;
352*7c478bd9Sstevel@tonic-gate curentry++;
353*7c478bd9Sstevel@tonic-gate if (dflag && (++debugcnt >= debug))
354*7c478bd9Sstevel@tonic-gate return (1);
355*7c478bd9Sstevel@tonic-gate return (0);
356*7c478bd9Sstevel@tonic-gate }
357*7c478bd9Sstevel@tonic-gate
358*7c478bd9Sstevel@tonic-gate
359*7c478bd9Sstevel@tonic-gate /*
360*7c478bd9Sstevel@tonic-gate * Collect responses from RUSERSVERS_3 broadcast.
361*7c478bd9Sstevel@tonic-gate */
362*7c478bd9Sstevel@tonic-gate static int
collectnames_3(void * resultsp,struct netbuf * raddrp,struct netconfig * nconf)363*7c478bd9Sstevel@tonic-gate collectnames_3(void *resultsp, struct netbuf *raddrp, struct netconfig *nconf)
364*7c478bd9Sstevel@tonic-gate {
365*7c478bd9Sstevel@tonic-gate utmp_array *uap;
366*7c478bd9Sstevel@tonic-gate struct entry *entryp, *lim;
367*7c478bd9Sstevel@tonic-gate struct nd_hostservlist *hs;
368*7c478bd9Sstevel@tonic-gate char host[MACHINELEN + 1];
369*7c478bd9Sstevel@tonic-gate
370*7c478bd9Sstevel@tonic-gate uap = (utmp_array *)resultsp;
371*7c478bd9Sstevel@tonic-gate if (uap->utmp_array_len < 1 && !aflag)
372*7c478bd9Sstevel@tonic-gate return (0);
373*7c478bd9Sstevel@tonic-gate
374*7c478bd9Sstevel@tonic-gate if (netdir_getbyaddr(nconf, &hs, raddrp)) {
375*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
376*7c478bd9Sstevel@tonic-gate netdir_perror("netdir_getbyaddr");
377*7c478bd9Sstevel@tonic-gate #endif
378*7c478bd9Sstevel@tonic-gate /* netdir routine couldn't resolve addr;just print out uaddr */
379*7c478bd9Sstevel@tonic-gate (void) sprintf(host, "%.*s", MACHINELEN,
380*7c478bd9Sstevel@tonic-gate taddr2uaddr(nconf, raddrp));
381*7c478bd9Sstevel@tonic-gate } else {
382*7c478bd9Sstevel@tonic-gate (void) sprintf(host, "%.*s", MACHINELEN,
383*7c478bd9Sstevel@tonic-gate hs->h_hostservs->h_host);
384*7c478bd9Sstevel@tonic-gate netdir_free((char *)hs, ND_HOSTSERVLIST);
385*7c478bd9Sstevel@tonic-gate }
386*7c478bd9Sstevel@tonic-gate
387*7c478bd9Sstevel@tonic-gate /*
388*7c478bd9Sstevel@tonic-gate * need to realloc more space if we have more than 256 machines
389*7c478bd9Sstevel@tonic-gate * that respond to broadcast
390*7c478bd9Sstevel@tonic-gate */
391*7c478bd9Sstevel@tonic-gate if (curentry >= total_entries) {
392*7c478bd9Sstevel@tonic-gate struct entry *tmp;
393*7c478bd9Sstevel@tonic-gate
394*7c478bd9Sstevel@tonic-gate total_entries += NUMENTRIES;
395*7c478bd9Sstevel@tonic-gate if ((tmp = realloc(entry, sizeof (struct entry)
396*7c478bd9Sstevel@tonic-gate * total_entries)) == NULL)
397*7c478bd9Sstevel@tonic-gate return (1);
398*7c478bd9Sstevel@tonic-gate entry = tmp;
399*7c478bd9Sstevel@tonic-gate }
400*7c478bd9Sstevel@tonic-gate
401*7c478bd9Sstevel@tonic-gate
402*7c478bd9Sstevel@tonic-gate /*
403*7c478bd9Sstevel@tonic-gate * weed out duplicates
404*7c478bd9Sstevel@tonic-gate */
405*7c478bd9Sstevel@tonic-gate lim = entry + curentry;
406*7c478bd9Sstevel@tonic-gate for (entryp = entry; entryp < lim; entryp++) {
407*7c478bd9Sstevel@tonic-gate if (strcmp(entryp->machine, host) == 0)
408*7c478bd9Sstevel@tonic-gate return (0);
409*7c478bd9Sstevel@tonic-gate }
410*7c478bd9Sstevel@tonic-gate return (print_info_3(uap, host));
411*7c478bd9Sstevel@tonic-gate }
412*7c478bd9Sstevel@tonic-gate
413*7c478bd9Sstevel@tonic-gate static int
print_info_3(utmp_array * uap,const char * name)414*7c478bd9Sstevel@tonic-gate print_info_3(utmp_array *uap, const char *name)
415*7c478bd9Sstevel@tonic-gate {
416*7c478bd9Sstevel@tonic-gate int i, cnt, minidle;
417*7c478bd9Sstevel@tonic-gate char host[MACHINELEN + 1];
418*7c478bd9Sstevel@tonic-gate
419*7c478bd9Sstevel@tonic-gate cnt = uap->utmp_array_len;
420*7c478bd9Sstevel@tonic-gate
421*7c478bd9Sstevel@tonic-gate (void) sprintf(host, "%.*s", MACHINELEN, name);
422*7c478bd9Sstevel@tonic-gate
423*7c478bd9Sstevel@tonic-gate /*
424*7c478bd9Sstevel@tonic-gate * if raw, print this entry out immediately
425*7c478bd9Sstevel@tonic-gate * otherwise store for later sorting
426*7c478bd9Sstevel@tonic-gate */
427*7c478bd9Sstevel@tonic-gate if (!sorted) {
428*7c478bd9Sstevel@tonic-gate if (lflag && (cnt > 0))
429*7c478bd9Sstevel@tonic-gate for (i = 0; i < cnt; i++)
430*7c478bd9Sstevel@tonic-gate putline_3(host, &uap->utmp_array_val[i]);
431*7c478bd9Sstevel@tonic-gate else {
432*7c478bd9Sstevel@tonic-gate (void) printf("%-*.*s", MACHINELEN, MACHINELEN, host);
433*7c478bd9Sstevel@tonic-gate for (i = 0; i < cnt; i++)
434*7c478bd9Sstevel@tonic-gate (void) printf(" %.*s", NMAX,
435*7c478bd9Sstevel@tonic-gate uap->utmp_array_val[i].ut_user);
436*7c478bd9Sstevel@tonic-gate (void) printf("\n");
437*7c478bd9Sstevel@tonic-gate }
438*7c478bd9Sstevel@tonic-gate /* store just the name */
439*7c478bd9Sstevel@tonic-gate entry[curentry].machine = malloc(MACHINELEN + 1);
440*7c478bd9Sstevel@tonic-gate if (entry[curentry].machine == NULL) {
441*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Ran out of memory - exiting\n");
442*7c478bd9Sstevel@tonic-gate exit(1);
443*7c478bd9Sstevel@tonic-gate }
444*7c478bd9Sstevel@tonic-gate (void) strlcpy(entry[curentry].machine, name, MACHINELEN + 1);
445*7c478bd9Sstevel@tonic-gate entry[curentry++].cnt = 0;
446*7c478bd9Sstevel@tonic-gate if (dflag && (++debugcnt >= debug))
447*7c478bd9Sstevel@tonic-gate return (1);
448*7c478bd9Sstevel@tonic-gate return (0);
449*7c478bd9Sstevel@tonic-gate }
450*7c478bd9Sstevel@tonic-gate
451*7c478bd9Sstevel@tonic-gate entry[curentry].machine = malloc(MACHINELEN + 1);
452*7c478bd9Sstevel@tonic-gate if (entry[curentry].machine == NULL) {
453*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Ran out of memory - exiting\n");
454*7c478bd9Sstevel@tonic-gate exit(1);
455*7c478bd9Sstevel@tonic-gate }
456*7c478bd9Sstevel@tonic-gate (void) strlcpy(entry[curentry].machine, name, MACHINELEN + 1);
457*7c478bd9Sstevel@tonic-gate entry[curentry].cnt = cnt;
458*7c478bd9Sstevel@tonic-gate entry[curentry].users.utmp_array_len = cnt;
459*7c478bd9Sstevel@tonic-gate entry[curentry].users.utmp_array_val = malloc(cnt *
460*7c478bd9Sstevel@tonic-gate sizeof (rusers_utmp));
461*7c478bd9Sstevel@tonic-gate minidle = INT_MAX;
462*7c478bd9Sstevel@tonic-gate for (i = 0; i < cnt; i++) {
463*7c478bd9Sstevel@tonic-gate entry[curentry].users.utmp_array_val[i].ut_user =
464*7c478bd9Sstevel@tonic-gate strdup(uap->utmp_array_val[i].ut_user);
465*7c478bd9Sstevel@tonic-gate entry[curentry].users.utmp_array_val[i].ut_line =
466*7c478bd9Sstevel@tonic-gate strdup(uap->utmp_array_val[i].ut_line);
467*7c478bd9Sstevel@tonic-gate entry[curentry].users.utmp_array_val[i].ut_host =
468*7c478bd9Sstevel@tonic-gate strdup(uap->utmp_array_val[i].ut_host);
469*7c478bd9Sstevel@tonic-gate entry[curentry].users.utmp_array_val[i].ut_time =
470*7c478bd9Sstevel@tonic-gate uap->utmp_array_val[i].ut_time;
471*7c478bd9Sstevel@tonic-gate entry[curentry].users.utmp_array_val[i].ut_idle =
472*7c478bd9Sstevel@tonic-gate uap->utmp_array_val[i].ut_idle;
473*7c478bd9Sstevel@tonic-gate minidle = min(minidle, uap->utmp_array_val[i].ut_idle);
474*7c478bd9Sstevel@tonic-gate }
475*7c478bd9Sstevel@tonic-gate entry[curentry].idle = minidle;
476*7c478bd9Sstevel@tonic-gate curentry++;
477*7c478bd9Sstevel@tonic-gate if (dflag && (++debugcnt >= debug))
478*7c478bd9Sstevel@tonic-gate return (1);
479*7c478bd9Sstevel@tonic-gate return (0);
480*7c478bd9Sstevel@tonic-gate }
481*7c478bd9Sstevel@tonic-gate
482*7c478bd9Sstevel@tonic-gate static void
printnames(void)483*7c478bd9Sstevel@tonic-gate printnames(void)
484*7c478bd9Sstevel@tonic-gate {
485*7c478bd9Sstevel@tonic-gate int i, j;
486*7c478bd9Sstevel@tonic-gate int (*compare)(const void *, const void *);
487*7c478bd9Sstevel@tonic-gate
488*7c478bd9Sstevel@tonic-gate /* the name of the machine should already be in the structure */
489*7c478bd9Sstevel@tonic-gate if (iflag)
490*7c478bd9Sstevel@tonic-gate compare = (int (*)(const void *, const void *))icompare;
491*7c478bd9Sstevel@tonic-gate else if (hflag)
492*7c478bd9Sstevel@tonic-gate compare = (int (*)(const void *, const void *))hcompare;
493*7c478bd9Sstevel@tonic-gate else
494*7c478bd9Sstevel@tonic-gate compare = (int (*)(const void *, const void *))ucompare;
495*7c478bd9Sstevel@tonic-gate qsort(entry, curentry, sizeof (struct entry), compare);
496*7c478bd9Sstevel@tonic-gate for (i = 0; i < curentry; i++) {
497*7c478bd9Sstevel@tonic-gate if (!lflag || (entry[i].cnt < 1)) {
498*7c478bd9Sstevel@tonic-gate (void) printf("%-*.*s", MACHINELEN,
499*7c478bd9Sstevel@tonic-gate MACHINELEN, entry[i].machine);
500*7c478bd9Sstevel@tonic-gate for (j = 0; j < entry[i].cnt; j++)
501*7c478bd9Sstevel@tonic-gate (void) printf(" %.*s", NMAX,
502*7c478bd9Sstevel@tonic-gate entry[i].users.utmp_array_val[j].ut_user);
503*7c478bd9Sstevel@tonic-gate (void) printf("\n");
504*7c478bd9Sstevel@tonic-gate } else {
505*7c478bd9Sstevel@tonic-gate for (j = 0; j < entry[i].cnt; j++)
506*7c478bd9Sstevel@tonic-gate putline_3(entry[i].machine,
507*7c478bd9Sstevel@tonic-gate &entry[i].users.utmp_array_val[j]);
508*7c478bd9Sstevel@tonic-gate }
509*7c478bd9Sstevel@tonic-gate }
510*7c478bd9Sstevel@tonic-gate }
511*7c478bd9Sstevel@tonic-gate
512*7c478bd9Sstevel@tonic-gate static int
hcompare(const struct entry * a,const struct entry * b)513*7c478bd9Sstevel@tonic-gate hcompare(const struct entry *a, const struct entry *b)
514*7c478bd9Sstevel@tonic-gate {
515*7c478bd9Sstevel@tonic-gate return (strcmp(a->machine, b->machine));
516*7c478bd9Sstevel@tonic-gate }
517*7c478bd9Sstevel@tonic-gate
518*7c478bd9Sstevel@tonic-gate static int
ucompare(const struct entry * a,const struct entry * b)519*7c478bd9Sstevel@tonic-gate ucompare(const struct entry *a, const struct entry *b)
520*7c478bd9Sstevel@tonic-gate {
521*7c478bd9Sstevel@tonic-gate return (b->cnt - a->cnt);
522*7c478bd9Sstevel@tonic-gate }
523*7c478bd9Sstevel@tonic-gate
524*7c478bd9Sstevel@tonic-gate static int
icompare(const struct entry * a,const struct entry * b)525*7c478bd9Sstevel@tonic-gate icompare(const struct entry *a, const struct entry *b)
526*7c478bd9Sstevel@tonic-gate {
527*7c478bd9Sstevel@tonic-gate return (a->idle - b->idle);
528*7c478bd9Sstevel@tonic-gate }
529*7c478bd9Sstevel@tonic-gate
530*7c478bd9Sstevel@tonic-gate static void
putline_2(char * host,struct utmpidle * uip)531*7c478bd9Sstevel@tonic-gate putline_2(char *host, struct utmpidle *uip)
532*7c478bd9Sstevel@tonic-gate {
533*7c478bd9Sstevel@tonic-gate char *cbuf;
534*7c478bd9Sstevel@tonic-gate struct ru_utmp *up;
535*7c478bd9Sstevel@tonic-gate char buf[100];
536*7c478bd9Sstevel@tonic-gate
537*7c478bd9Sstevel@tonic-gate up = &uip->ui_utmp;
538*7c478bd9Sstevel@tonic-gate #define NAMEMAX ((sizeof (up->ut_name) < NMAX) ? NMAX : sizeof (up->ut_name))
539*7c478bd9Sstevel@tonic-gate #define NAMEMIN ((sizeof (up->ut_name) > NMAX) ? NMAX : sizeof (up->ut_name))
540*7c478bd9Sstevel@tonic-gate /* Try and align this up nicely */
541*7c478bd9Sstevel@tonic-gate #define LINEMAX sizeof (up->ut_line)
542*7c478bd9Sstevel@tonic-gate #define HOSTMAX sizeof (up->ut_host)
543*7c478bd9Sstevel@tonic-gate /*
544*7c478bd9Sstevel@tonic-gate * We copy the strings into a buffer because they aren't strictly
545*7c478bd9Sstevel@tonic-gate * speaking strings but byte arrays (and they may not have a
546*7c478bd9Sstevel@tonic-gate * terminating NULL.
547*7c478bd9Sstevel@tonic-gate */
548*7c478bd9Sstevel@tonic-gate
549*7c478bd9Sstevel@tonic-gate (void) strncpy(buf, up->ut_name, NAMEMAX);
550*7c478bd9Sstevel@tonic-gate buf[NAMEMIN] = '\0';
551*7c478bd9Sstevel@tonic-gate (void) printf("%-*.*s ", NAMEMAX, NAMEMAX, buf);
552*7c478bd9Sstevel@tonic-gate
553*7c478bd9Sstevel@tonic-gate (void) strcpy(buf, host);
554*7c478bd9Sstevel@tonic-gate (void) strcat(buf, ":");
555*7c478bd9Sstevel@tonic-gate (void) strncat(buf, up->ut_line, LINEMAX);
556*7c478bd9Sstevel@tonic-gate buf[MACHINELEN+LINEMAX] = '\0';
557*7c478bd9Sstevel@tonic-gate (void) printf("%-*.*s", MACHINELEN+LINEMAX, MACHINELEN+LINEMAX, buf);
558*7c478bd9Sstevel@tonic-gate
559*7c478bd9Sstevel@tonic-gate cbuf = (char *)ctime(&up->ut_time);
560*7c478bd9Sstevel@tonic-gate (void) printf(" %.12s ", cbuf+4);
561*7c478bd9Sstevel@tonic-gate if (uip->ui_idle == INT_MAX)
562*7c478bd9Sstevel@tonic-gate (void) printf(" ??");
563*7c478bd9Sstevel@tonic-gate else
564*7c478bd9Sstevel@tonic-gate prttime(uip->ui_idle, "");
565*7c478bd9Sstevel@tonic-gate if (up->ut_host[0]) {
566*7c478bd9Sstevel@tonic-gate (void) strncpy(buf, up->ut_host, HOSTMAX);
567*7c478bd9Sstevel@tonic-gate buf[HOSTMAX] = '\0';
568*7c478bd9Sstevel@tonic-gate (void) printf(" (%.*s)", HOSTMAX, buf);
569*7c478bd9Sstevel@tonic-gate }
570*7c478bd9Sstevel@tonic-gate (void) putchar('\n');
571*7c478bd9Sstevel@tonic-gate }
572*7c478bd9Sstevel@tonic-gate
573*7c478bd9Sstevel@tonic-gate static void
putline_3(char * host,rusers_utmp * rup)574*7c478bd9Sstevel@tonic-gate putline_3(char *host, rusers_utmp *rup)
575*7c478bd9Sstevel@tonic-gate {
576*7c478bd9Sstevel@tonic-gate char *cbuf;
577*7c478bd9Sstevel@tonic-gate char buf[100];
578*7c478bd9Sstevel@tonic-gate
579*7c478bd9Sstevel@tonic-gate (void) printf("%-*.*s ", NMAX, NMAX, rup->ut_user);
580*7c478bd9Sstevel@tonic-gate (void) strcpy(buf, host);
581*7c478bd9Sstevel@tonic-gate (void) strcat(buf, ":");
582*7c478bd9Sstevel@tonic-gate (void) strncat(buf, rup->ut_line, LMAX);
583*7c478bd9Sstevel@tonic-gate (void) printf("%-*.*s", MACHINELEN+LMAX, MACHINELEN+LMAX, buf);
584*7c478bd9Sstevel@tonic-gate
585*7c478bd9Sstevel@tonic-gate cbuf = (char *)ctime((time_t *)&rup->ut_time);
586*7c478bd9Sstevel@tonic-gate (void) printf(" %.12s ", cbuf+4);
587*7c478bd9Sstevel@tonic-gate if (rup->ut_idle == INT_MAX)
588*7c478bd9Sstevel@tonic-gate (void) printf(" ??");
589*7c478bd9Sstevel@tonic-gate else
590*7c478bd9Sstevel@tonic-gate prttime(rup->ut_idle, "");
591*7c478bd9Sstevel@tonic-gate if (rup->ut_host[0])
592*7c478bd9Sstevel@tonic-gate (void) printf(" (%.*s)", HMAX, rup->ut_host);
593*7c478bd9Sstevel@tonic-gate (void) putchar('\n');
594*7c478bd9Sstevel@tonic-gate }
595*7c478bd9Sstevel@tonic-gate
596*7c478bd9Sstevel@tonic-gate /*
597*7c478bd9Sstevel@tonic-gate * prttime prints a time in hours and minutes.
598*7c478bd9Sstevel@tonic-gate * The character string tail is printed at the end, obvious
599*7c478bd9Sstevel@tonic-gate * strings to pass are "", " ", or "am".
600*7c478bd9Sstevel@tonic-gate */
601*7c478bd9Sstevel@tonic-gate static void
prttime(uint_t tim,char * tail)602*7c478bd9Sstevel@tonic-gate prttime(uint_t tim, char *tail)
603*7c478bd9Sstevel@tonic-gate {
604*7c478bd9Sstevel@tonic-gate int didhrs = 0;
605*7c478bd9Sstevel@tonic-gate
606*7c478bd9Sstevel@tonic-gate if (tim >= 60) {
607*7c478bd9Sstevel@tonic-gate (void) printf("%3d:", tim/60);
608*7c478bd9Sstevel@tonic-gate didhrs++;
609*7c478bd9Sstevel@tonic-gate } else {
610*7c478bd9Sstevel@tonic-gate (void) printf(" ");
611*7c478bd9Sstevel@tonic-gate }
612*7c478bd9Sstevel@tonic-gate tim %= 60;
613*7c478bd9Sstevel@tonic-gate if (tim > 0 || didhrs) {
614*7c478bd9Sstevel@tonic-gate (void) printf(didhrs && tim < 10 ? "%02d" : "%2d", tim);
615*7c478bd9Sstevel@tonic-gate } else {
616*7c478bd9Sstevel@tonic-gate (void) printf(" ");
617*7c478bd9Sstevel@tonic-gate }
618*7c478bd9Sstevel@tonic-gate (void) printf("%s", tail);
619*7c478bd9Sstevel@tonic-gate }
620*7c478bd9Sstevel@tonic-gate
621*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
622*7c478bd9Sstevel@tonic-gate /*
623*7c478bd9Sstevel@tonic-gate * for debugging
624*7c478bd9Sstevel@tonic-gate */
625*7c478bd9Sstevel@tonic-gate int
printit(int i)626*7c478bd9Sstevel@tonic-gate printit(int i)
627*7c478bd9Sstevel@tonic-gate {
628*7c478bd9Sstevel@tonic-gate int j, v;
629*7c478bd9Sstevel@tonic-gate
630*7c478bd9Sstevel@tonic-gate (void) printf("%12.12s: ", entry[i].machine);
631*7c478bd9Sstevel@tonic-gate if (entry[i].cnt) {
632*7c478bd9Sstevel@tonic-gate putline_3(entry[i].machine, &entry[i].users.utmp_array_val[0]);
633*7c478bd9Sstevel@tonic-gate for (j = 1; j < entry[i].cnt; j++) {
634*7c478bd9Sstevel@tonic-gate (void) printf("\t");
635*7c478bd9Sstevel@tonic-gate putline_3(entry[i].machine,
636*7c478bd9Sstevel@tonic-gate &entry[i].users.utmp_array_val[j]);
637*7c478bd9Sstevel@tonic-gate }
638*7c478bd9Sstevel@tonic-gate } else
639*7c478bd9Sstevel@tonic-gate (void) printf("\n");
640*7c478bd9Sstevel@tonic-gate }
641*7c478bd9Sstevel@tonic-gate #endif
642*7c478bd9Sstevel@tonic-gate
643*7c478bd9Sstevel@tonic-gate static void
usage(void)644*7c478bd9Sstevel@tonic-gate usage(void)
645*7c478bd9Sstevel@tonic-gate {
646*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Usage: rusers [-ahilu] [host ...]\n");
647*7c478bd9Sstevel@tonic-gate free(entry);
648*7c478bd9Sstevel@tonic-gate exit(1);
649*7c478bd9Sstevel@tonic-gate }
650