xref: /csrg-svn/usr.sbin/amd/amq/amq.c (revision 52453)
144628Smckusick /*
244628Smckusick  * Copyright (c) 1990 Jan-Simon Pendry
344628Smckusick  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
444628Smckusick  * Copyright (c) 1990 The Regents of the University of California.
544628Smckusick  * All rights reserved.
644628Smckusick  *
744628Smckusick  * This code is derived from software contributed to Berkeley by
844628Smckusick  * Jan-Simon Pendry at Imperial College, London.
944628Smckusick  *
1044628Smckusick  * %sccs.include.redist.c%
1149686Spendry  *
12*52453Spendry  *	@(#)amq.c	5.4 (Berkeley) 02/09/92
1349686Spendry  *
14*52453Spendry  * $Id: amq.c,v 5.2.2.1 1992/02/09 15:09:16 jsp beta $
1549686Spendry  *
1644628Smckusick  */
1744628Smckusick 
1844628Smckusick /*
1944628Smckusick  * Automounter query tool
2044628Smckusick  */
2144628Smckusick 
2244628Smckusick #ifndef lint
2344628Smckusick char copyright[] = "\
2444628Smckusick @(#)Copyright (c) 1990 Jan-Simon Pendry\n\
2544628Smckusick @(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\
2644628Smckusick @(#)Copyright (c) 1990 The Regents of the University of California.\n\
2744628Smckusick @(#)All rights reserved.\n";
2844628Smckusick #endif /* not lint */
2944628Smckusick 
3044628Smckusick #ifndef lint
31*52453Spendry static char rcsid[] = "$Id: amq.c,v 5.2.2.1 1992/02/09 15:09:16 jsp beta $";
32*52453Spendry static char sccsid[] = "@(#)amq.c	5.4 (Berkeley) 02/09/92";
3344628Smckusick #endif /* not lint */
3444628Smckusick 
3544628Smckusick #include "am.h"
3644628Smckusick #include "amq.h"
3744628Smckusick #include <stdio.h>
3844628Smckusick #include <fcntl.h>
3944628Smckusick #include <netdb.h>
4044628Smckusick 
4147529Spendry static int privsock();
4247529Spendry 
4344628Smckusick char *progname;
4444628Smckusick static int flush_flag;
4544628Smckusick static int minfo_flag;
4644628Smckusick static int unmount_flag;
4744628Smckusick static int stats_flag;
4847529Spendry static int getvers_flag;
4944628Smckusick static char *debug_opts;
5044628Smckusick static char *logfile;
5147529Spendry static char *mount_map;
5247529Spendry static char *xlog_optstr;
5344628Smckusick static char localhost[] = "localhost";
5444628Smckusick static char *def_server = localhost;
5544628Smckusick 
5644628Smckusick extern int optind;
5744628Smckusick extern char *optarg;
5844628Smckusick 
5944628Smckusick static struct timeval tmo = { 10, 0 };
6044628Smckusick #define	TIMEOUT tmo
6144628Smckusick 
6244628Smckusick enum show_opt { Full, Stats, Calc, Short, ShowDone };
6344628Smckusick 
6444628Smckusick /*
6544628Smckusick  * If (e) is Calc then just calculate the sizes
6644628Smckusick  * Otherwise display the mount node on stdout
6744628Smckusick  */
6844628Smckusick static void show_mti(mt, e, mwid, dwid, twid)
6944628Smckusick amq_mount_tree *mt;
7044628Smckusick enum show_opt e;
7144628Smckusick int *mwid;
7244628Smckusick int *dwid;
7344628Smckusick int *twid;
7444628Smckusick {
7544628Smckusick 	switch (e) {
7644628Smckusick 	case Calc: {
7744628Smckusick 		int mw = strlen(mt->mt_mountinfo);
7844628Smckusick 		int dw = strlen(mt->mt_directory);
7944628Smckusick 		int tw = strlen(mt->mt_type);
8044628Smckusick 		if (mw > *mwid) *mwid = mw;
8144628Smckusick 		if (dw > *dwid) *dwid = dw;
8244628Smckusick 		if (tw > *twid) *twid = tw;
8344628Smckusick 	} break;
8444628Smckusick 
8544628Smckusick 	case Full: {
8647529Spendry 		struct tm *tp = localtime((time_t *) &mt->mt_mounttime);
8744628Smckusick printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
8844628Smckusick 			*dwid, *dwid,
8944628Smckusick 			*mt->mt_directory ? mt->mt_directory : "/",	/* XXX */
9044628Smckusick 			*twid, *twid,
9144628Smckusick 			mt->mt_type,
9244628Smckusick 			*mwid, *mwid,
9344628Smckusick 			mt->mt_mountinfo,
9444628Smckusick 			mt->mt_mountpoint,
9544628Smckusick 
9644628Smckusick 			mt->mt_mountuid,
9744628Smckusick 			mt->mt_getattr,
9844628Smckusick 			mt->mt_lookup,
9944628Smckusick 			mt->mt_readdir,
10044628Smckusick 			mt->mt_readlink,
10144628Smckusick 			mt->mt_statfs,
10244628Smckusick 
10344628Smckusick 			tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,
10444628Smckusick 			tp->tm_mon+1, tp->tm_mday,
10544628Smckusick 			tp->tm_hour, tp->tm_min, tp->tm_sec);
10644628Smckusick 	} break;
10744628Smckusick 
10844628Smckusick 	case Stats: {
10947529Spendry 		struct tm *tp = localtime((time_t *) &mt->mt_mounttime);
11044628Smckusick printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
11144628Smckusick 			*dwid, *dwid,
11244628Smckusick 			*mt->mt_directory ? mt->mt_directory : "/",	/* XXX */
11344628Smckusick 
11444628Smckusick 			mt->mt_mountuid,
11544628Smckusick 			mt->mt_getattr,
11644628Smckusick 			mt->mt_lookup,
11744628Smckusick 			mt->mt_readdir,
11844628Smckusick 			mt->mt_readlink,
11944628Smckusick 			mt->mt_statfs,
12044628Smckusick 
12144628Smckusick 			tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,
12244628Smckusick 			tp->tm_mon+1, tp->tm_mday,
12344628Smckusick 			tp->tm_hour, tp->tm_min, tp->tm_sec);
12444628Smckusick 	} break;
12544628Smckusick 
12644628Smckusick 	case Short: {
12744628Smckusick 		printf("%-*.*s %-*.*s %-*.*s %s\n",
12844628Smckusick 			*dwid, *dwid,
12944628Smckusick 			*mt->mt_directory ? mt->mt_directory : "/",
13044628Smckusick 			*twid, *twid,
13144628Smckusick 			mt->mt_type,
13244628Smckusick 			*mwid, *mwid,
13344628Smckusick 			mt->mt_mountinfo,
13444628Smckusick 			mt->mt_mountpoint);
13544628Smckusick 	} break;
13644628Smckusick 	}
13744628Smckusick }
13844628Smckusick 
13944628Smckusick /*
14044628Smckusick  * Display a mount tree.
14144628Smckusick  */
14244628Smckusick static void show_mt(mt, e, mwid, dwid, pwid)
14344628Smckusick amq_mount_tree *mt;
14444628Smckusick enum show_opt e;
14544628Smckusick int *mwid;
14644628Smckusick int *dwid;
14744628Smckusick int *pwid;
14844628Smckusick {
14944628Smckusick 	while (mt) {
15044628Smckusick 		show_mti(mt, e, mwid, dwid, pwid);
15144628Smckusick 		show_mt(mt->mt_next, e, mwid, dwid, pwid);
15244628Smckusick 		mt = mt->mt_child;
15344628Smckusick 	}
15444628Smckusick }
15544628Smckusick 
15644628Smckusick static void show_mi(ml, e, mwid, dwid, twid)
15744628Smckusick amq_mount_info_list *ml;
15844628Smckusick enum show_opt e;
15944628Smckusick int *mwid;
16044628Smckusick int *dwid;
16144628Smckusick int *twid;
16244628Smckusick {
16344628Smckusick 	int i;
16444628Smckusick 	switch (e) {
16544628Smckusick 	case Calc: {
16644628Smckusick 		for (i = 0; i < ml->amq_mount_info_list_len; i++) {
16744628Smckusick 			amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
16844628Smckusick 			int mw = strlen(mi->mi_mountinfo);
16944628Smckusick 			int dw = strlen(mi->mi_mountpt);
17044628Smckusick 			int tw = strlen(mi->mi_type);
17144628Smckusick 			if (mw > *mwid) *mwid = mw;
17244628Smckusick 			if (dw > *dwid) *dwid = dw;
17344628Smckusick 			if (tw > *twid) *twid = tw;
17444628Smckusick 		}
17544628Smckusick 	} break;
17644628Smckusick 
17744628Smckusick 	case Full: {
17844628Smckusick 		for (i = 0; i < ml->amq_mount_info_list_len; i++) {
17944628Smckusick 			amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
18044628Smckusick 			printf("%-*.*s %-*.*s %-*.*s %-3d %s is %s",
18144628Smckusick 						*mwid, *mwid, mi->mi_mountinfo,
18244628Smckusick 						*dwid, *dwid, mi->mi_mountpt,
18344628Smckusick 						*twid, *twid, mi->mi_type,
18444628Smckusick 						mi->mi_refc, mi->mi_fserver,
18544628Smckusick 						mi->mi_up > 0 ? "up" :
18644628Smckusick 						mi->mi_up < 0 ? "starting" : "down");
18744628Smckusick 			if (mi->mi_error > 0) {
18844628Smckusick 				extern char *sys_errlist[];
18944628Smckusick 				extern int sys_nerr;
19044628Smckusick 				if (mi->mi_error < sys_nerr)
19144628Smckusick 					printf(" (%s)", sys_errlist[mi->mi_error]);
19244628Smckusick 				else
19344628Smckusick 					printf(" (Error %d)", mi->mi_error);
19444628Smckusick 			} else if (mi->mi_error < 0) {
19544628Smckusick 				fputs(" (in progress)", stdout);
19644628Smckusick 			}
19744628Smckusick 			fputc('\n', stdout);
19844628Smckusick 		}
19944628Smckusick 	} break;
20044628Smckusick 	}
20144628Smckusick }
20244628Smckusick 
20344628Smckusick /*
20444628Smckusick  * Display general mount statistics
20544628Smckusick  */
20644628Smckusick static void show_ms(ms)
20744628Smckusick amq_mount_stats *ms;
20844628Smckusick {
20944628Smckusick 	printf("\
21044628Smckusick requests  stale     mount     mount     unmount\n\
21144628Smckusick deferred  fhandles  ok        failed    failed\n\
21244628Smckusick %-9d %-9d %-9d %-9d %-9d\n",
21344628Smckusick 	ms->as_drops, ms->as_stale, ms->as_mok, ms->as_merr, ms->as_uerr);
21444628Smckusick }
21544628Smckusick 
21644628Smckusick static bool_t
21744628Smckusick xdr_pri_free(xdr_args, args_ptr)
21844628Smckusick xdrproc_t xdr_args;
21944628Smckusick caddr_t args_ptr;
22044628Smckusick {
22144628Smckusick 	XDR xdr;
22244628Smckusick 	xdr.x_op = XDR_FREE;
22344628Smckusick 	return ((*xdr_args)(&xdr, args_ptr));
22444628Smckusick }
22544628Smckusick 
22644628Smckusick #ifdef hpux
22744628Smckusick #include <cluster.h>
22844628Smckusick static char *cluster_server()
22944628Smckusick {
23044628Smckusick 	struct cct_entry *cp;
23144628Smckusick 
23244628Smckusick 	if (cnodeid() == 0) {
23344628Smckusick 		/*
23444628Smckusick 		 * Not clustered
23544628Smckusick 		 */
23644628Smckusick 		return def_server;
23744628Smckusick 	}
23844628Smckusick 
23944628Smckusick 	while (cp = getccent())
24044628Smckusick 		if (cp->cnode_type == 'r')
24144628Smckusick 			return cp->cnode_name;
24244628Smckusick 
24344628Smckusick 
24444628Smckusick 	return def_server;
24544628Smckusick }
24644628Smckusick #endif /* hpux */
24744628Smckusick 
24844628Smckusick /*
24944628Smckusick  * MAIN
25044628Smckusick  */
25144628Smckusick main(argc, argv)
25244628Smckusick int argc;
25344628Smckusick char *argv[];
25444628Smckusick {
25544628Smckusick 	int opt_ch;
25644628Smckusick 	int errs = 0;
25744628Smckusick 	char *server;
25844628Smckusick 	struct sockaddr_in server_addr;
25947529Spendry 
26047529Spendry 	/* In order to pass the Amd security check, we must use a priv port. */
26147529Spendry 	int s;
26247529Spendry 
26344628Smckusick 	CLIENT *clnt;
26444628Smckusick 	struct hostent *hp;
26544628Smckusick 	int nodefault = 0;
26644628Smckusick 
26744628Smckusick 	/*
26844628Smckusick 	 * Compute program name
26944628Smckusick 	 */
27044628Smckusick 	if (argv[0]) {
27144628Smckusick 		progname = strrchr(argv[0], '/');
27244628Smckusick 		if (progname && progname[1])
27344628Smckusick 			progname++;
27444628Smckusick 		else
27544628Smckusick 			progname = argv[0];
27644628Smckusick 	}
27744628Smckusick 	if (!progname)
27844628Smckusick 		progname = "amq";
27944628Smckusick 
28044628Smckusick 	/*
28144628Smckusick 	 * Parse arguments
28244628Smckusick 	 */
28347529Spendry 	while ((opt_ch = getopt(argc, argv, "fh:l:msuvx:D:M:")) != EOF)
28444628Smckusick 	switch (opt_ch) {
28544628Smckusick 	case 'f':
28644628Smckusick 		flush_flag = 1;
28747529Spendry 		nodefault = 1;
28844628Smckusick 		break;
28944628Smckusick 
29044628Smckusick 	case 'h':
29144628Smckusick 		def_server = optarg;
29244628Smckusick 		break;
29344628Smckusick 
29444628Smckusick 	case 'l':
29544628Smckusick 		logfile = optarg;
29644628Smckusick 		nodefault = 1;
29744628Smckusick 		break;
29844628Smckusick 
29944628Smckusick 	case 'm':
30044628Smckusick 		minfo_flag = 1;
30144628Smckusick 		nodefault = 1;
30244628Smckusick 		break;
30344628Smckusick 
30444628Smckusick 	case 's':
30544628Smckusick 		stats_flag = 1;
30647529Spendry 		nodefault = 1;
30744628Smckusick 		break;
30844628Smckusick 
30944628Smckusick 	case 'u':
31044628Smckusick 		unmount_flag = 1;
31147529Spendry 		nodefault = 1;
31244628Smckusick 		break;
31344628Smckusick 
31447529Spendry 	case 'v':
31547529Spendry 		getvers_flag = 1;
31647529Spendry 		nodefault = 1;
31747529Spendry 		break;
31847529Spendry 
31944628Smckusick 	case 'x':
32047529Spendry 		xlog_optstr = optarg;
32144628Smckusick 		nodefault = 1;
32244628Smckusick 		break;
32344628Smckusick 
32444628Smckusick 	case 'D':
32544628Smckusick 		debug_opts = optarg;
32644628Smckusick 		nodefault = 1;
32744628Smckusick 		break;
32844628Smckusick 
32947529Spendry 	case 'M':
33047529Spendry 		mount_map = optarg;
33147529Spendry 		nodefault = 1;
33247529Spendry 		break;
33347529Spendry 
33444628Smckusick 	default:
33544628Smckusick 		errs = 1;
33644628Smckusick 		break;
33744628Smckusick 	}
33844628Smckusick 
33947529Spendry 	if (optind == argc) {
34047529Spendry 		if (unmount_flag)
34147529Spendry 			errs = 1;
34247529Spendry 	}
34347529Spendry 
34444628Smckusick 	if (errs) {
34544628Smckusick show_usage:
34644628Smckusick 		fprintf(stderr, "\
34747529Spendry Usage: %s [-h host] [[-f] [-m] [-v] [-s]] | [[-u] directory ...]] |\n\
34847529Spendry \t[-l logfile|\"syslog\"] [-x log_flags] [-D dbg_opts] [-M mapent]\n", progname);
34944628Smckusick 		exit(1);
35044628Smckusick 	}
35144628Smckusick 
35244628Smckusick #ifdef hpux
35344628Smckusick 	/*
35444628Smckusick 	 * Figure out root server of cluster
35544628Smckusick 	 */
35644628Smckusick 	if (def_server == localhost)
35744628Smckusick 		server = cluster_server();
35844628Smckusick 	else
35944628Smckusick #endif /* hpux */
36044628Smckusick 	server = def_server;
36144628Smckusick 
36244628Smckusick 	/*
36344628Smckusick 	 * Get address of server
36444628Smckusick 	 */
36549686Spendry 	if ((hp = gethostbyname(server)) == 0 && strcmp(server, localhost) != 0) {
36644628Smckusick 		fprintf(stderr, "%s: Can't get address of %s\n", progname, server);
36744628Smckusick 		exit(1);
36844628Smckusick 	}
36944628Smckusick 	bzero(&server_addr, sizeof server_addr);
37044628Smckusick 	server_addr.sin_family = AF_INET;
37149686Spendry 	if (hp) {
37249686Spendry 		bcopy((voidp) hp->h_addr, (voidp) &server_addr.sin_addr,
37349686Spendry 			sizeof(server_addr.sin_addr));
37449686Spendry 	} else {
37549686Spendry 		/* fake "localhost" */
37649686Spendry 		server_addr.sin_addr.s_addr = htonl(0x7f000001);
37749686Spendry 	}
37844628Smckusick 
37944628Smckusick 	/*
38044628Smckusick 	 * Create RPC endpoint
38144628Smckusick 	 */
382*52453Spendry 	s = privsock(SOCK_STREAM);
383*52453Spendry 	clnt = clnttcp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, &s, 0, 0);
38444628Smckusick 	if (clnt == 0) {
385*52453Spendry 		close(s);
386*52453Spendry 		s = privsock(SOCK_DGRAM);
387*52453Spendry 		clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, TIMEOUT, &s);
388*52453Spendry 	}
389*52453Spendry 	if (clnt == 0) {
39044628Smckusick 		fprintf(stderr, "%s: ", progname);
39144628Smckusick 		clnt_pcreateerror(server);
39244628Smckusick 		exit(1);
39344628Smckusick 	}
39444628Smckusick 
39544628Smckusick 	/*
39644628Smckusick 	 * Control debugging
39744628Smckusick 	 */
39844628Smckusick 	if (debug_opts) {
39944628Smckusick 		int *rc;
40044628Smckusick 		amq_setopt opt;
40144628Smckusick 		opt.as_opt = AMOPT_DEBUG;
40244628Smckusick 		opt.as_str = debug_opts;
40344628Smckusick 		rc = amqproc_setopt_1(&opt, clnt);
40444628Smckusick 		if (rc && *rc < 0) {
40544628Smckusick 			fprintf(stderr, "%s: daemon not compiled for debug", progname);
40644628Smckusick 			errs = 1;
40744628Smckusick 		} else if (!rc || *rc > 0) {
40844628Smckusick 			fprintf(stderr, "%s: debug setting for \"%s\" failed\n", progname, debug_opts);
40944628Smckusick 			errs = 1;
41044628Smckusick 		}
41144628Smckusick 	}
41244628Smckusick 
41344628Smckusick 	/*
41444628Smckusick 	 * Control logging
41544628Smckusick 	 */
41647529Spendry 	if (xlog_optstr) {
41744628Smckusick 		int *rc;
41844628Smckusick 		amq_setopt opt;
41944628Smckusick 		opt.as_opt = AMOPT_XLOG;
42047529Spendry 		opt.as_str = xlog_optstr;
42144628Smckusick 		rc = amqproc_setopt_1(&opt, clnt);
42244628Smckusick 		if (!rc || *rc) {
42347529Spendry 			fprintf(stderr, "%s: setting log level to \"%s\" failed\n", progname, xlog_optstr);
42444628Smckusick 			errs = 1;
42544628Smckusick 		}
42644628Smckusick 	}
42744628Smckusick 
42844628Smckusick 	/*
42944628Smckusick 	 * Control log file
43044628Smckusick 	 */
43144628Smckusick 	if (logfile) {
43244628Smckusick 		int *rc;
43344628Smckusick 		amq_setopt opt;
43444628Smckusick 		opt.as_opt = AMOPT_LOGFILE;
43544628Smckusick 		opt.as_str = logfile;
43644628Smckusick 		rc = amqproc_setopt_1(&opt, clnt);
43744628Smckusick 		if (!rc || *rc) {
43844628Smckusick 			fprintf(stderr, "%s: setting logfile to \"%s\" failed\n", progname, logfile);
43944628Smckusick 			errs = 1;
44044628Smckusick 		}
44144628Smckusick 	}
44244628Smckusick 
44344628Smckusick 	/*
44444628Smckusick 	 * Flush map cache
44544628Smckusick 	 */
44647529Spendry 	if (flush_flag) {
44744628Smckusick 		int *rc;
44844628Smckusick 		amq_setopt opt;
44944628Smckusick 		opt.as_opt = AMOPT_FLUSHMAPC;
45044628Smckusick 		opt.as_str = "";
45144628Smckusick 		rc = amqproc_setopt_1(&opt, clnt);
45244628Smckusick 		if (!rc || *rc) {
45344628Smckusick 			fprintf(stderr, "%s: amd on %s cannot flush the map cache\n", progname, server);
45444628Smckusick 			errs = 1;
45544628Smckusick 		}
45644628Smckusick 	}
45744628Smckusick 
45844628Smckusick 	/*
45944628Smckusick 	 * Mount info
46044628Smckusick 	 */
46144628Smckusick 	if (minfo_flag) {
46244628Smckusick 		int dummy;
46344628Smckusick 		amq_mount_info_list *ml = amqproc_getmntfs_1(&dummy, clnt);
46444628Smckusick 		if (ml) {
46544628Smckusick 			int mwid = 0, dwid = 0, twid = 0;
46644628Smckusick 			show_mi(ml, Calc, &mwid, &dwid, &twid);
46744628Smckusick 			mwid++; dwid++; twid++;
46844628Smckusick 			show_mi(ml, Full, &mwid, &dwid, &twid);
46944628Smckusick 
47044628Smckusick 		} else {
47144628Smckusick 			fprintf(stderr, "%s: amd on %s cannot provide mount info\n", progname, server);
47244628Smckusick 		}
47344628Smckusick 	}
47444628Smckusick 
47544628Smckusick 	/*
47647529Spendry 	 * Mount map
47747529Spendry 	 */
47847529Spendry 	if (mount_map) {
47947529Spendry 		int *rc;
48047529Spendry 		do {
48147529Spendry 			rc = amqproc_mount_1(&mount_map, clnt);
48247529Spendry 		} while (rc && *rc < 0);
48347529Spendry 		if (!rc || *rc > 0) {
48447529Spendry 			if (rc)
48547529Spendry 				errno = *rc;
48647529Spendry 			else
48747529Spendry 				errno = ETIMEDOUT;
48847529Spendry 			fprintf(stderr, "%s: could not start new ", progname);
48947529Spendry 			perror("autmount point");
49047529Spendry 		}
49147529Spendry 	}
49247529Spendry 
49347529Spendry 	/*
49447529Spendry 	 * Get Version
49547529Spendry 	 */
49647529Spendry 	if (getvers_flag) {
49747529Spendry 		amq_string *spp = amqproc_getvers_1((voidp) 0, clnt);
49847529Spendry 		if (spp && *spp) {
49947529Spendry 			printf("%s.\n", *spp);
50047529Spendry 			free(*spp);
50147529Spendry 		} else {
50249686Spendry 			fprintf(stderr, "%s: failed to get version information\n", progname);
50347529Spendry 			errs = 1;
50447529Spendry 		}
50547529Spendry 	}
50647529Spendry 
50747529Spendry 	/*
50844628Smckusick 	 * Apply required operation to all remaining arguments
50944628Smckusick 	 */
51044628Smckusick 	if (optind < argc) {
51144628Smckusick 		do {
51244628Smckusick 			char *fs = argv[optind++];
51344628Smckusick 			if (unmount_flag) {
51444628Smckusick 				/*
51544628Smckusick 				 * Unmount request
51644628Smckusick 				 */
51744628Smckusick 				amqproc_umnt_1(&fs, clnt);
51844628Smckusick 			} else {
51944628Smckusick 				/*
52044628Smckusick 				 * Stats request
52144628Smckusick 				 */
52244628Smckusick 				amq_mount_tree_p *mtp = amqproc_mnttree_1(&fs, clnt);
52344628Smckusick 				if (mtp) {
52444628Smckusick 					amq_mount_tree *mt = *mtp;
52544628Smckusick 					if (mt) {
52644628Smckusick 						int mwid = 0, dwid = 0, twid = 0;
52744628Smckusick 						show_mt(mt, Calc, &mwid, &dwid, &twid);
52844628Smckusick 						mwid++; dwid++, twid++;
52944628Smckusick 		printf("%-*.*s Uid   Getattr Lookup RdDir   RdLnk   Statfs Mounted@\n",
53044628Smckusick 			dwid, dwid, "What");
53144628Smckusick 						show_mt(mt, Stats, &mwid, &dwid, &twid);
53244628Smckusick 					} else {
53344628Smckusick 						fprintf(stderr, "%s: %s not automounted\n", progname, fs);
53444628Smckusick 					}
53544628Smckusick 					xdr_pri_free(xdr_amq_mount_tree_p, (caddr_t) mtp);
53644628Smckusick 				} else {
53744628Smckusick 					fprintf(stderr, "%s: ", progname);
53844628Smckusick 					clnt_perror(clnt, server);
53944628Smckusick 					errs = 1;
54044628Smckusick 				}
54144628Smckusick 			}
54244628Smckusick 		} while (optind < argc);
54344628Smckusick 	} else if (unmount_flag) {
54444628Smckusick 		goto show_usage;
54544628Smckusick 	} else if (stats_flag) {
54644628Smckusick 		amq_mount_stats *ms = amqproc_stats_1((voidp) 0, clnt);
54744628Smckusick 		if (ms) {
54844628Smckusick 			show_ms(ms);
54944628Smckusick 		} else {
55044628Smckusick 			fprintf(stderr, "%s: ", progname);
55144628Smckusick 			clnt_perror(clnt, server);
55244628Smckusick 			errs = 1;
55344628Smckusick 		}
55444628Smckusick 	} else if (!nodefault) {
55544628Smckusick 		amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt);
55644628Smckusick 		if (mlp) {
55744628Smckusick 			enum show_opt e = Calc;
55844628Smckusick 			int mwid = 0, dwid = 0, pwid = 0;
55944628Smckusick 			while (e != ShowDone) {
56044628Smckusick 				int i;
56144628Smckusick 				for (i = 0; i < mlp->amq_mount_tree_list_len; i++) {
56244628Smckusick 					show_mt(mlp->amq_mount_tree_list_val[i],
56344628Smckusick 						 e, &mwid, &dwid, &pwid);
56444628Smckusick 				}
56544628Smckusick 				mwid++; dwid++, pwid++;
56644628Smckusick 				if (e == Calc) e = Short;
56744628Smckusick 				else if (e == Short) e = ShowDone;
56844628Smckusick 			}
56944628Smckusick 		} else {
57044628Smckusick 			fprintf(stderr, "%s: ", progname);
57144628Smckusick 			clnt_perror(clnt, server);
57244628Smckusick 			errs = 1;
57344628Smckusick 		}
57444628Smckusick 	}
57544628Smckusick 
57644628Smckusick 	exit(errs);
57744628Smckusick }
57844628Smckusick 
57947529Spendry /*
58047529Spendry  * udpresport creates a datagram socket and attempts to bind it to a
58147529Spendry  * secure port.
58247529Spendry  * returns: The bound socket, or -1 to indicate an error.
58347529Spendry  */
584*52453Spendry static int inetresport(ty)
585*52453Spendry int ty;
58647529Spendry {
58747529Spendry 	int alport;
58847529Spendry 	struct sockaddr_in addr;
58947529Spendry 	int sock;
59047529Spendry 
59147529Spendry 	/* Use internet address family */
59247529Spendry 	addr.sin_family = AF_INET;
59347529Spendry 	addr.sin_addr.s_addr = INADDR_ANY;
594*52453Spendry 	if ((sock = socket(AF_INET, ty, 0)) < 0)
59547529Spendry 		return -1;
59647529Spendry 	for (alport = IPPORT_RESERVED-1; alport > IPPORT_RESERVED/2 + 1; alport--) {
59747529Spendry 		addr.sin_port = htons((u_short)alport);
59847529Spendry 		if (bind(sock, (struct sockaddr *)&addr, sizeof (addr)) >= 0)
59947529Spendry 			return sock;
60047529Spendry 		if (errno != EADDRINUSE) {
60147529Spendry 			close(sock);
60247529Spendry 			return -1;
60347529Spendry 		}
60447529Spendry 	}
60547529Spendry 	close(sock);
60647529Spendry 	errno = EAGAIN;
60747529Spendry 	return -1;
60847529Spendry }
60947529Spendry 
61047529Spendry /*
611*52453Spendry  * Privsock() calls inetresport() to attempt to bind a socket to a secure
612*52453Spendry  * port.  If inetresport() fails, privsock returns a magic socket number which
61347529Spendry  * indicates to RPC that it should make its own socket.
61447529Spendry  * returns: A privileged socket # or RPC_ANYSOCK.
61547529Spendry  */
616*52453Spendry static int privsock(ty)
617*52453Spendry int ty;
61847529Spendry {
619*52453Spendry 	int sock = inetresport(ty);
62047529Spendry 
62147529Spendry 	if (sock < 0) {
62247529Spendry 		errno = 0;
62347529Spendry 		/* Couldn't get a secure port, let RPC make an insecure one */
62447529Spendry 		sock = RPC_ANYSOCK;
62547529Spendry 	}
62647529Spendry 	return sock;
62747529Spendry }
62847529Spendry 
62944628Smckusick #ifdef DEBUG
63044628Smckusick xfree(f, l, p)
63144628Smckusick char *f, *l;
63244628Smckusick voidp p;
63344628Smckusick {
63444628Smckusick 	free(p);
63544628Smckusick }
63644628Smckusick #endif /* DEBUG */
637