xref: /csrg-svn/usr.sbin/amd/amq/amq.c (revision 44628)
1*44628Smckusick /*
2*44628Smckusick  * $Id: amq.c,v 5.2 90/06/23 22:20:07 jsp Rel $
3*44628Smckusick  *
4*44628Smckusick  * Copyright (c) 1990 Jan-Simon Pendry
5*44628Smckusick  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
6*44628Smckusick  * Copyright (c) 1990 The Regents of the University of California.
7*44628Smckusick  * All rights reserved.
8*44628Smckusick  *
9*44628Smckusick  * This code is derived from software contributed to Berkeley by
10*44628Smckusick  * Jan-Simon Pendry at Imperial College, London.
11*44628Smckusick  *
12*44628Smckusick  * %sccs.include.redist.c%
13*44628Smckusick  */
14*44628Smckusick 
15*44628Smckusick /*
16*44628Smckusick  * Automounter query tool
17*44628Smckusick  */
18*44628Smckusick 
19*44628Smckusick #ifndef lint
20*44628Smckusick char copyright[] = "\
21*44628Smckusick @(#)Copyright (c) 1990 Jan-Simon Pendry\n\
22*44628Smckusick @(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\
23*44628Smckusick @(#)Copyright (c) 1990 The Regents of the University of California.\n\
24*44628Smckusick @(#)All rights reserved.\n";
25*44628Smckusick #endif /* not lint */
26*44628Smckusick 
27*44628Smckusick #ifndef lint
28*44628Smckusick static char rcsid[] = "$Id: amq.c,v 5.2 90/06/23 22:20:07 jsp Rel $";
29*44628Smckusick static char sccsid[] = "@(#)amq.c	5.1 (Berkeley) 06/29/90";
30*44628Smckusick #endif /* not lint */
31*44628Smckusick 
32*44628Smckusick #include "am.h"
33*44628Smckusick #include "amq.h"
34*44628Smckusick #include <stdio.h>
35*44628Smckusick #include <fcntl.h>
36*44628Smckusick #include <netdb.h>
37*44628Smckusick 
38*44628Smckusick char *progname;
39*44628Smckusick static int flush_flag;
40*44628Smckusick static int minfo_flag;
41*44628Smckusick static int unmount_flag;
42*44628Smckusick static int stats_flag;
43*44628Smckusick static char *debug_opts;
44*44628Smckusick static char *logfile;
45*44628Smckusick static char *xlog_opt;
46*44628Smckusick static char localhost[] = "localhost";
47*44628Smckusick static char *def_server = localhost;
48*44628Smckusick 
49*44628Smckusick extern int optind;
50*44628Smckusick extern char *optarg;
51*44628Smckusick 
52*44628Smckusick static struct timeval tmo = { 10, 0 };
53*44628Smckusick #define	TIMEOUT tmo
54*44628Smckusick 
55*44628Smckusick enum show_opt { Full, Stats, Calc, Short, ShowDone };
56*44628Smckusick 
57*44628Smckusick /*
58*44628Smckusick  * If (e) is Calc then just calculate the sizes
59*44628Smckusick  * Otherwise display the mount node on stdout
60*44628Smckusick  */
61*44628Smckusick static void show_mti(mt, e, mwid, dwid, twid)
62*44628Smckusick amq_mount_tree *mt;
63*44628Smckusick enum show_opt e;
64*44628Smckusick int *mwid;
65*44628Smckusick int *dwid;
66*44628Smckusick int *twid;
67*44628Smckusick {
68*44628Smckusick 	switch (e) {
69*44628Smckusick 	case Calc: {
70*44628Smckusick 		int mw = strlen(mt->mt_mountinfo);
71*44628Smckusick 		int dw = strlen(mt->mt_directory);
72*44628Smckusick 		int tw = strlen(mt->mt_type);
73*44628Smckusick 		if (mw > *mwid) *mwid = mw;
74*44628Smckusick 		if (dw > *dwid) *dwid = dw;
75*44628Smckusick 		if (tw > *twid) *twid = tw;
76*44628Smckusick 	} break;
77*44628Smckusick 
78*44628Smckusick 	case Full: {
79*44628Smckusick 		struct tm *tp = localtime(&mt->mt_mounttime);
80*44628Smckusick printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
81*44628Smckusick 			*dwid, *dwid,
82*44628Smckusick 			*mt->mt_directory ? mt->mt_directory : "/",	/* XXX */
83*44628Smckusick 			*twid, *twid,
84*44628Smckusick 			mt->mt_type,
85*44628Smckusick 			*mwid, *mwid,
86*44628Smckusick 			mt->mt_mountinfo,
87*44628Smckusick 			mt->mt_mountpoint,
88*44628Smckusick 
89*44628Smckusick 			mt->mt_mountuid,
90*44628Smckusick 			mt->mt_getattr,
91*44628Smckusick 			mt->mt_lookup,
92*44628Smckusick 			mt->mt_readdir,
93*44628Smckusick 			mt->mt_readlink,
94*44628Smckusick 			mt->mt_statfs,
95*44628Smckusick 
96*44628Smckusick 			tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,
97*44628Smckusick 			tp->tm_mon+1, tp->tm_mday,
98*44628Smckusick 			tp->tm_hour, tp->tm_min, tp->tm_sec);
99*44628Smckusick 	} break;
100*44628Smckusick 
101*44628Smckusick 	case Stats: {
102*44628Smckusick 		struct tm *tp = localtime(&mt->mt_mounttime);
103*44628Smckusick printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
104*44628Smckusick 			*dwid, *dwid,
105*44628Smckusick 			*mt->mt_directory ? mt->mt_directory : "/",	/* XXX */
106*44628Smckusick 
107*44628Smckusick 			mt->mt_mountuid,
108*44628Smckusick 			mt->mt_getattr,
109*44628Smckusick 			mt->mt_lookup,
110*44628Smckusick 			mt->mt_readdir,
111*44628Smckusick 			mt->mt_readlink,
112*44628Smckusick 			mt->mt_statfs,
113*44628Smckusick 
114*44628Smckusick 			tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,
115*44628Smckusick 			tp->tm_mon+1, tp->tm_mday,
116*44628Smckusick 			tp->tm_hour, tp->tm_min, tp->tm_sec);
117*44628Smckusick 	} break;
118*44628Smckusick 
119*44628Smckusick 	case Short: {
120*44628Smckusick 		printf("%-*.*s %-*.*s %-*.*s %s\n",
121*44628Smckusick 			*dwid, *dwid,
122*44628Smckusick 			*mt->mt_directory ? mt->mt_directory : "/",
123*44628Smckusick 			*twid, *twid,
124*44628Smckusick 			mt->mt_type,
125*44628Smckusick 			*mwid, *mwid,
126*44628Smckusick 			mt->mt_mountinfo,
127*44628Smckusick 			mt->mt_mountpoint);
128*44628Smckusick 	} break;
129*44628Smckusick 	}
130*44628Smckusick }
131*44628Smckusick 
132*44628Smckusick /*
133*44628Smckusick  * Display a mount tree.
134*44628Smckusick  */
135*44628Smckusick static void show_mt(mt, e, mwid, dwid, pwid)
136*44628Smckusick amq_mount_tree *mt;
137*44628Smckusick enum show_opt e;
138*44628Smckusick int *mwid;
139*44628Smckusick int *dwid;
140*44628Smckusick int *pwid;
141*44628Smckusick {
142*44628Smckusick 	while (mt) {
143*44628Smckusick 		show_mti(mt, e, mwid, dwid, pwid);
144*44628Smckusick 		show_mt(mt->mt_next, e, mwid, dwid, pwid);
145*44628Smckusick 		mt = mt->mt_child;
146*44628Smckusick 	}
147*44628Smckusick }
148*44628Smckusick 
149*44628Smckusick static void show_mi(ml, e, mwid, dwid, twid)
150*44628Smckusick amq_mount_info_list *ml;
151*44628Smckusick enum show_opt e;
152*44628Smckusick int *mwid;
153*44628Smckusick int *dwid;
154*44628Smckusick int *twid;
155*44628Smckusick {
156*44628Smckusick 	int i;
157*44628Smckusick 	switch (e) {
158*44628Smckusick 	case Calc: {
159*44628Smckusick 		for (i = 0; i < ml->amq_mount_info_list_len; i++) {
160*44628Smckusick 			amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
161*44628Smckusick 			int mw = strlen(mi->mi_mountinfo);
162*44628Smckusick 			int dw = strlen(mi->mi_mountpt);
163*44628Smckusick 			int tw = strlen(mi->mi_type);
164*44628Smckusick 			if (mw > *mwid) *mwid = mw;
165*44628Smckusick 			if (dw > *dwid) *dwid = dw;
166*44628Smckusick 			if (tw > *twid) *twid = tw;
167*44628Smckusick 		}
168*44628Smckusick 	} break;
169*44628Smckusick 
170*44628Smckusick 	case Full: {
171*44628Smckusick 		for (i = 0; i < ml->amq_mount_info_list_len; i++) {
172*44628Smckusick 			amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
173*44628Smckusick 			printf("%-*.*s %-*.*s %-*.*s %-3d %s is %s",
174*44628Smckusick 						*mwid, *mwid, mi->mi_mountinfo,
175*44628Smckusick 						*dwid, *dwid, mi->mi_mountpt,
176*44628Smckusick 						*twid, *twid, mi->mi_type,
177*44628Smckusick 						mi->mi_refc, mi->mi_fserver,
178*44628Smckusick 						mi->mi_up > 0 ? "up" :
179*44628Smckusick 						mi->mi_up < 0 ? "starting" : "down");
180*44628Smckusick 			if (mi->mi_error > 0) {
181*44628Smckusick 				extern char *sys_errlist[];
182*44628Smckusick 				extern int sys_nerr;
183*44628Smckusick 				if (mi->mi_error < sys_nerr)
184*44628Smckusick 					printf(" (%s)", sys_errlist[mi->mi_error]);
185*44628Smckusick 				else
186*44628Smckusick 					printf(" (Error %d)", mi->mi_error);
187*44628Smckusick 			} else if (mi->mi_error < 0) {
188*44628Smckusick 				fputs(" (in progress)", stdout);
189*44628Smckusick 			}
190*44628Smckusick 			fputc('\n', stdout);
191*44628Smckusick 		}
192*44628Smckusick 	} break;
193*44628Smckusick 	}
194*44628Smckusick }
195*44628Smckusick 
196*44628Smckusick /*
197*44628Smckusick  * Display general mount statistics
198*44628Smckusick  */
199*44628Smckusick static void show_ms(ms)
200*44628Smckusick amq_mount_stats *ms;
201*44628Smckusick {
202*44628Smckusick 	printf("\
203*44628Smckusick requests  stale     mount     mount     unmount\n\
204*44628Smckusick deferred  fhandles  ok        failed    failed\n\
205*44628Smckusick %-9d %-9d %-9d %-9d %-9d\n",
206*44628Smckusick 	ms->as_drops, ms->as_stale, ms->as_mok, ms->as_merr, ms->as_uerr);
207*44628Smckusick }
208*44628Smckusick 
209*44628Smckusick static bool_t
210*44628Smckusick xdr_pri_free(xdr_args, args_ptr)
211*44628Smckusick xdrproc_t xdr_args;
212*44628Smckusick caddr_t args_ptr;
213*44628Smckusick {
214*44628Smckusick 	XDR xdr;
215*44628Smckusick 	xdr.x_op = XDR_FREE;
216*44628Smckusick 	return ((*xdr_args)(&xdr, args_ptr));
217*44628Smckusick }
218*44628Smckusick 
219*44628Smckusick #ifdef hpux
220*44628Smckusick #include <cluster.h>
221*44628Smckusick static char *cluster_server()
222*44628Smckusick {
223*44628Smckusick 	struct cct_entry *cp;
224*44628Smckusick 
225*44628Smckusick 	if (cnodeid() == 0) {
226*44628Smckusick 		/*
227*44628Smckusick 		 * Not clustered
228*44628Smckusick 		 */
229*44628Smckusick 		return def_server;
230*44628Smckusick 	}
231*44628Smckusick 
232*44628Smckusick 	while (cp = getccent())
233*44628Smckusick 		if (cp->cnode_type == 'r')
234*44628Smckusick 			return cp->cnode_name;
235*44628Smckusick 
236*44628Smckusick 
237*44628Smckusick 	return def_server;
238*44628Smckusick }
239*44628Smckusick #endif /* hpux */
240*44628Smckusick 
241*44628Smckusick /*
242*44628Smckusick  * MAIN
243*44628Smckusick  */
244*44628Smckusick main(argc, argv)
245*44628Smckusick int argc;
246*44628Smckusick char *argv[];
247*44628Smckusick {
248*44628Smckusick 	int opt_ch;
249*44628Smckusick 	int errs = 0;
250*44628Smckusick 	char *server;
251*44628Smckusick 	struct sockaddr_in server_addr;
252*44628Smckusick 	int s = RPC_ANYSOCK;
253*44628Smckusick 	CLIENT *clnt;
254*44628Smckusick 	struct hostent *hp;
255*44628Smckusick 	int nodefault = 0;
256*44628Smckusick 
257*44628Smckusick 	/*
258*44628Smckusick 	 * Compute program name
259*44628Smckusick 	 */
260*44628Smckusick 	if (argv[0]) {
261*44628Smckusick 		progname = strrchr(argv[0], '/');
262*44628Smckusick 		if (progname && progname[1])
263*44628Smckusick 			progname++;
264*44628Smckusick 		else
265*44628Smckusick 			progname = argv[0];
266*44628Smckusick 	}
267*44628Smckusick 	if (!progname)
268*44628Smckusick 		progname = "amq";
269*44628Smckusick 
270*44628Smckusick 	/*
271*44628Smckusick 	 * Parse arguments
272*44628Smckusick 	 */
273*44628Smckusick 	while ((opt_ch = getopt(argc, argv, "fh:l:msux:D:")) != EOF)
274*44628Smckusick 	switch (opt_ch) {
275*44628Smckusick 	case 'f':
276*44628Smckusick 		flush_flag = 1;
277*44628Smckusick 		break;
278*44628Smckusick 
279*44628Smckusick 	case 'h':
280*44628Smckusick 		def_server = optarg;
281*44628Smckusick 		break;
282*44628Smckusick 
283*44628Smckusick 	case 'l':
284*44628Smckusick 		logfile = optarg;
285*44628Smckusick 		nodefault = 1;
286*44628Smckusick 		break;
287*44628Smckusick 
288*44628Smckusick 	case 'm':
289*44628Smckusick 		minfo_flag = 1;
290*44628Smckusick 		nodefault = 1;
291*44628Smckusick 		break;
292*44628Smckusick 
293*44628Smckusick 	case 's':
294*44628Smckusick 		stats_flag = 1;
295*44628Smckusick 		break;
296*44628Smckusick 
297*44628Smckusick 	case 'u':
298*44628Smckusick 		unmount_flag = 1;
299*44628Smckusick 		break;
300*44628Smckusick 
301*44628Smckusick 	case 'x':
302*44628Smckusick 		xlog_opt = optarg;
303*44628Smckusick 		nodefault = 1;
304*44628Smckusick 		break;
305*44628Smckusick 
306*44628Smckusick 	case 'D':
307*44628Smckusick 		debug_opts = optarg;
308*44628Smckusick 		nodefault = 1;
309*44628Smckusick 		break;
310*44628Smckusick 
311*44628Smckusick 	default:
312*44628Smckusick 		errs = 1;
313*44628Smckusick 		break;
314*44628Smckusick 	}
315*44628Smckusick 
316*44628Smckusick 	if (errs) {
317*44628Smckusick show_usage:
318*44628Smckusick 		fprintf(stderr, "\
319*44628Smckusick Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\
320*44628Smckusick \t[-l logfile|\"syslog\"] [-x log_flags] [-D dbg_opts]\n", progname);
321*44628Smckusick 		exit(1);
322*44628Smckusick 	}
323*44628Smckusick 
324*44628Smckusick #ifdef hpux
325*44628Smckusick 	/*
326*44628Smckusick 	 * Figure out root server of cluster
327*44628Smckusick 	 */
328*44628Smckusick 	if (def_server == localhost)
329*44628Smckusick 		server = cluster_server();
330*44628Smckusick 	else
331*44628Smckusick #endif /* hpux */
332*44628Smckusick 	server = def_server;
333*44628Smckusick 
334*44628Smckusick 	/*
335*44628Smckusick 	 * Get address of server
336*44628Smckusick 	 */
337*44628Smckusick 	if ((hp = gethostbyname(server)) == 0) {
338*44628Smckusick 		fprintf(stderr, "%s: Can't get address of %s\n", progname, server);
339*44628Smckusick 		exit(1);
340*44628Smckusick 	}
341*44628Smckusick 	bzero(&server_addr, sizeof server_addr);
342*44628Smckusick 	server_addr.sin_family = AF_INET;
343*44628Smckusick 	server_addr.sin_addr = *(struct in_addr *) hp->h_addr;
344*44628Smckusick 
345*44628Smckusick 	/*
346*44628Smckusick 	 * Create RPC endpoint
347*44628Smckusick 	 */
348*44628Smckusick 	clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, TIMEOUT, &s);
349*44628Smckusick 	if (clnt == 0) {
350*44628Smckusick 		fprintf(stderr, "%s: ", progname);
351*44628Smckusick 		clnt_pcreateerror(server);
352*44628Smckusick 		exit(1);
353*44628Smckusick 	}
354*44628Smckusick 
355*44628Smckusick 	/*
356*44628Smckusick 	 * Control debugging
357*44628Smckusick 	 */
358*44628Smckusick 	if (debug_opts) {
359*44628Smckusick 		int *rc;
360*44628Smckusick 		amq_setopt opt;
361*44628Smckusick 		opt.as_opt = AMOPT_DEBUG;
362*44628Smckusick 		opt.as_str = debug_opts;
363*44628Smckusick 		rc = amqproc_setopt_1(&opt, clnt);
364*44628Smckusick 		if (rc && *rc < 0) {
365*44628Smckusick 			fprintf(stderr, "%s: daemon not compiled for debug", progname);
366*44628Smckusick 			errs = 1;
367*44628Smckusick 		} else if (!rc || *rc > 0) {
368*44628Smckusick 			fprintf(stderr, "%s: debug setting for \"%s\" failed\n", progname, debug_opts);
369*44628Smckusick 			errs = 1;
370*44628Smckusick 		}
371*44628Smckusick 	}
372*44628Smckusick 
373*44628Smckusick 	/*
374*44628Smckusick 	 * Control logging
375*44628Smckusick 	 */
376*44628Smckusick 	if (xlog_opt) {
377*44628Smckusick 		int *rc;
378*44628Smckusick 		amq_setopt opt;
379*44628Smckusick 		opt.as_opt = AMOPT_XLOG;
380*44628Smckusick 		opt.as_str = xlog_opt;
381*44628Smckusick 		rc = amqproc_setopt_1(&opt, clnt);
382*44628Smckusick 		if (!rc || *rc) {
383*44628Smckusick 			fprintf(stderr, "%s: setting log level to \"%s\" failed\n", progname, xlog_opt);
384*44628Smckusick 			errs = 1;
385*44628Smckusick 		}
386*44628Smckusick 	}
387*44628Smckusick 
388*44628Smckusick 	/*
389*44628Smckusick 	 * Control log file
390*44628Smckusick 	 */
391*44628Smckusick 	if (logfile) {
392*44628Smckusick 		int *rc;
393*44628Smckusick 		amq_setopt opt;
394*44628Smckusick 		opt.as_opt = AMOPT_LOGFILE;
395*44628Smckusick 		opt.as_str = logfile;
396*44628Smckusick 		rc = amqproc_setopt_1(&opt, clnt);
397*44628Smckusick 		if (!rc || *rc) {
398*44628Smckusick 			fprintf(stderr, "%s: setting logfile to \"%s\" failed\n", progname, logfile);
399*44628Smckusick 			errs = 1;
400*44628Smckusick 		}
401*44628Smckusick 	}
402*44628Smckusick 
403*44628Smckusick 	/*
404*44628Smckusick 	 * Flush map cache
405*44628Smckusick 	 */
406*44628Smckusick 	if (logfile) {
407*44628Smckusick 		int *rc;
408*44628Smckusick 		amq_setopt opt;
409*44628Smckusick 		opt.as_opt = AMOPT_FLUSHMAPC;
410*44628Smckusick 		opt.as_str = "";
411*44628Smckusick 		rc = amqproc_setopt_1(&opt, clnt);
412*44628Smckusick 		if (!rc || *rc) {
413*44628Smckusick 			fprintf(stderr, "%s: amd on %s cannot flush the map cache\n", progname, server);
414*44628Smckusick 			errs = 1;
415*44628Smckusick 		}
416*44628Smckusick 	}
417*44628Smckusick 
418*44628Smckusick 	/*
419*44628Smckusick 	 * Mount info
420*44628Smckusick 	 */
421*44628Smckusick 	if (minfo_flag) {
422*44628Smckusick 		int dummy;
423*44628Smckusick 		amq_mount_info_list *ml = amqproc_getmntfs_1(&dummy, clnt);
424*44628Smckusick 		if (ml) {
425*44628Smckusick 			int mwid = 0, dwid = 0, twid = 0;
426*44628Smckusick 			show_mi(ml, Calc, &mwid, &dwid, &twid);
427*44628Smckusick 			mwid++; dwid++; twid++;
428*44628Smckusick 			show_mi(ml, Full, &mwid, &dwid, &twid);
429*44628Smckusick 
430*44628Smckusick 		} else {
431*44628Smckusick 			fprintf(stderr, "%s: amd on %s cannot provide mount info\n", progname, server);
432*44628Smckusick 		}
433*44628Smckusick 	}
434*44628Smckusick 
435*44628Smckusick 	/*
436*44628Smckusick 	 * Apply required operation to all remaining arguments
437*44628Smckusick 	 */
438*44628Smckusick 	if (optind < argc) {
439*44628Smckusick 		do {
440*44628Smckusick 			char *fs = argv[optind++];
441*44628Smckusick 			if (unmount_flag) {
442*44628Smckusick 				/*
443*44628Smckusick 				 * Unmount request
444*44628Smckusick 				 */
445*44628Smckusick 				amqproc_umnt_1(&fs, clnt);
446*44628Smckusick 			} else {
447*44628Smckusick 				/*
448*44628Smckusick 				 * Stats request
449*44628Smckusick 				 */
450*44628Smckusick 				amq_mount_tree_p *mtp = amqproc_mnttree_1(&fs, clnt);
451*44628Smckusick 				if (mtp) {
452*44628Smckusick 					amq_mount_tree *mt = *mtp;
453*44628Smckusick 					if (mt) {
454*44628Smckusick 						int mwid = 0, dwid = 0, twid = 0;
455*44628Smckusick 						show_mt(mt, Calc, &mwid, &dwid, &twid);
456*44628Smckusick 						mwid++; dwid++, twid++;
457*44628Smckusick #ifdef notdef
458*44628Smckusick 		printf("\t%s\n%-*.*s %-*.*s %-*.*s %s\n",
459*44628Smckusick 		"Uid   Getattr Lookup RdDir   RdLnk   Statfs Mounted@",
460*44628Smckusick 		      dwid, dwid, "What", twid, twid, "Type", mwid, mwid, "Info", "Where");
461*44628Smckusick 						show_mt(mt, Full, &mwid, &dwid, &twid);
462*44628Smckusick #endif /* notdef */
463*44628Smckusick 		printf("%-*.*s Uid   Getattr Lookup RdDir   RdLnk   Statfs Mounted@\n",
464*44628Smckusick 			dwid, dwid, "What");
465*44628Smckusick 						show_mt(mt, Stats, &mwid, &dwid, &twid);
466*44628Smckusick 					} else {
467*44628Smckusick 						fprintf(stderr, "%s: %s not automounted\n", progname, fs);
468*44628Smckusick 					}
469*44628Smckusick 					xdr_pri_free(xdr_amq_mount_tree_p, (caddr_t) mtp);
470*44628Smckusick 				} else {
471*44628Smckusick 					fprintf(stderr, "%s: ", progname);
472*44628Smckusick 					clnt_perror(clnt, server);
473*44628Smckusick 					errs = 1;
474*44628Smckusick 				}
475*44628Smckusick 			}
476*44628Smckusick 		} while (optind < argc);
477*44628Smckusick 	} else if (unmount_flag) {
478*44628Smckusick 		goto show_usage;
479*44628Smckusick 	} else if (stats_flag) {
480*44628Smckusick 		amq_mount_stats *ms = amqproc_stats_1((voidp) 0, clnt);
481*44628Smckusick 		if (ms) {
482*44628Smckusick 			show_ms(ms);
483*44628Smckusick 		} else {
484*44628Smckusick 			fprintf(stderr, "%s: ", progname);
485*44628Smckusick 			clnt_perror(clnt, server);
486*44628Smckusick 			errs = 1;
487*44628Smckusick 		}
488*44628Smckusick 	} else if (!nodefault) {
489*44628Smckusick 		amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt);
490*44628Smckusick 		if (mlp) {
491*44628Smckusick 			enum show_opt e = Calc;
492*44628Smckusick 			int mwid = 0, dwid = 0, pwid = 0;
493*44628Smckusick 			while (e != ShowDone) {
494*44628Smckusick 				int i;
495*44628Smckusick 				for (i = 0; i < mlp->amq_mount_tree_list_len; i++) {
496*44628Smckusick 					show_mt(mlp->amq_mount_tree_list_val[i],
497*44628Smckusick 						 e, &mwid, &dwid, &pwid);
498*44628Smckusick 				}
499*44628Smckusick 				mwid++; dwid++, pwid++;
500*44628Smckusick 				if (e == Calc) e = Short;
501*44628Smckusick 				else if (e == Short) e = ShowDone;
502*44628Smckusick 			}
503*44628Smckusick 		} else {
504*44628Smckusick 			fprintf(stderr, "%s: ", progname);
505*44628Smckusick 			clnt_perror(clnt, server);
506*44628Smckusick 			errs = 1;
507*44628Smckusick 		}
508*44628Smckusick 	}
509*44628Smckusick 
510*44628Smckusick 	exit(errs);
511*44628Smckusick }
512*44628Smckusick 
513*44628Smckusick #ifdef DEBUG
514*44628Smckusick xfree(f, l, p)
515*44628Smckusick char *f, *l;
516*44628Smckusick voidp p;
517*44628Smckusick {
518*44628Smckusick 	free(p);
519*44628Smckusick }
520*44628Smckusick #endif /* DEBUG */
521