xref: /original-bsd/usr.sbin/amd/amq/amq.c (revision aa1e94d2)
1976dfacdSmckusick /*
2976dfacdSmckusick  * Copyright (c) 1990 Jan-Simon Pendry
3976dfacdSmckusick  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
4*aa1e94d2Sbostic  * Copyright (c) 1990, 1993
5*aa1e94d2Sbostic  *	The Regents of the University of California.  All rights reserved.
6976dfacdSmckusick  *
7976dfacdSmckusick  * This code is derived from software contributed to Berkeley by
8976dfacdSmckusick  * Jan-Simon Pendry at Imperial College, London.
9976dfacdSmckusick  *
10976dfacdSmckusick  * %sccs.include.redist.c%
11278f1af9Spendry  *
12*aa1e94d2Sbostic  *	@(#)amq.c	8.1 (Berkeley) 06/07/93
13278f1af9Spendry  *
143f1b4436Spendry  * $Id: amq.c,v 5.2.2.1 1992/02/09 15:09:16 jsp beta $
15278f1af9Spendry  *
16976dfacdSmckusick  */
17976dfacdSmckusick 
18976dfacdSmckusick /*
19976dfacdSmckusick  * Automounter query tool
20976dfacdSmckusick  */
21976dfacdSmckusick 
22976dfacdSmckusick #ifndef lint
23976dfacdSmckusick char copyright[] = "\
24976dfacdSmckusick @(#)Copyright (c) 1990 Jan-Simon Pendry\n\
25976dfacdSmckusick @(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\
26*aa1e94d2Sbostic @(#)Copyright (c) 1990, 1993\n\
27*aa1e94d2Sbostic 	The Regents of the University of California.  All rights reserved.\n";
28976dfacdSmckusick #endif /* not lint */
29976dfacdSmckusick 
30976dfacdSmckusick #ifndef lint
313f1b4436Spendry static char rcsid[] = "$Id: amq.c,v 5.2.2.1 1992/02/09 15:09:16 jsp beta $";
32*aa1e94d2Sbostic static char sccsid[] = "@(#)amq.c	8.1 (Berkeley) 06/07/93";
33976dfacdSmckusick #endif /* not lint */
34976dfacdSmckusick 
35976dfacdSmckusick #include "am.h"
36976dfacdSmckusick #include "amq.h"
37976dfacdSmckusick #include <stdio.h>
38976dfacdSmckusick #include <fcntl.h>
39976dfacdSmckusick #include <netdb.h>
40976dfacdSmckusick 
41fe648a93Spendry static int privsock();
42fe648a93Spendry 
43976dfacdSmckusick char *progname;
44976dfacdSmckusick static int flush_flag;
45976dfacdSmckusick static int minfo_flag;
46976dfacdSmckusick static int unmount_flag;
47976dfacdSmckusick static int stats_flag;
48fe648a93Spendry static int getvers_flag;
49976dfacdSmckusick static char *debug_opts;
50976dfacdSmckusick static char *logfile;
51fe648a93Spendry static char *mount_map;
52fe648a93Spendry static char *xlog_optstr;
53976dfacdSmckusick static char localhost[] = "localhost";
54976dfacdSmckusick static char *def_server = localhost;
55976dfacdSmckusick 
56976dfacdSmckusick extern int optind;
57976dfacdSmckusick extern char *optarg;
58976dfacdSmckusick 
59976dfacdSmckusick static struct timeval tmo = { 10, 0 };
60976dfacdSmckusick #define	TIMEOUT tmo
61976dfacdSmckusick 
62976dfacdSmckusick enum show_opt { Full, Stats, Calc, Short, ShowDone };
63976dfacdSmckusick 
64976dfacdSmckusick /*
65976dfacdSmckusick  * If (e) is Calc then just calculate the sizes
66976dfacdSmckusick  * Otherwise display the mount node on stdout
67976dfacdSmckusick  */
show_mti(mt,e,mwid,dwid,twid)68976dfacdSmckusick static void show_mti(mt, e, mwid, dwid, twid)
69976dfacdSmckusick amq_mount_tree *mt;
70976dfacdSmckusick enum show_opt e;
71976dfacdSmckusick int *mwid;
72976dfacdSmckusick int *dwid;
73976dfacdSmckusick int *twid;
74976dfacdSmckusick {
75976dfacdSmckusick 	switch (e) {
76976dfacdSmckusick 	case Calc: {
77976dfacdSmckusick 		int mw = strlen(mt->mt_mountinfo);
78976dfacdSmckusick 		int dw = strlen(mt->mt_directory);
79976dfacdSmckusick 		int tw = strlen(mt->mt_type);
80976dfacdSmckusick 		if (mw > *mwid) *mwid = mw;
81976dfacdSmckusick 		if (dw > *dwid) *dwid = dw;
82976dfacdSmckusick 		if (tw > *twid) *twid = tw;
83976dfacdSmckusick 	} break;
84976dfacdSmckusick 
85976dfacdSmckusick 	case Full: {
86fe648a93Spendry 		struct tm *tp = localtime((time_t *) &mt->mt_mounttime);
87976dfacdSmckusick printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
88976dfacdSmckusick 			*dwid, *dwid,
89976dfacdSmckusick 			*mt->mt_directory ? mt->mt_directory : "/",	/* XXX */
90976dfacdSmckusick 			*twid, *twid,
91976dfacdSmckusick 			mt->mt_type,
92976dfacdSmckusick 			*mwid, *mwid,
93976dfacdSmckusick 			mt->mt_mountinfo,
94976dfacdSmckusick 			mt->mt_mountpoint,
95976dfacdSmckusick 
96976dfacdSmckusick 			mt->mt_mountuid,
97976dfacdSmckusick 			mt->mt_getattr,
98976dfacdSmckusick 			mt->mt_lookup,
99976dfacdSmckusick 			mt->mt_readdir,
100976dfacdSmckusick 			mt->mt_readlink,
101976dfacdSmckusick 			mt->mt_statfs,
102976dfacdSmckusick 
103976dfacdSmckusick 			tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,
104976dfacdSmckusick 			tp->tm_mon+1, tp->tm_mday,
105976dfacdSmckusick 			tp->tm_hour, tp->tm_min, tp->tm_sec);
106976dfacdSmckusick 	} break;
107976dfacdSmckusick 
108976dfacdSmckusick 	case Stats: {
109fe648a93Spendry 		struct tm *tp = localtime((time_t *) &mt->mt_mounttime);
110976dfacdSmckusick printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
111976dfacdSmckusick 			*dwid, *dwid,
112976dfacdSmckusick 			*mt->mt_directory ? mt->mt_directory : "/",	/* XXX */
113976dfacdSmckusick 
114976dfacdSmckusick 			mt->mt_mountuid,
115976dfacdSmckusick 			mt->mt_getattr,
116976dfacdSmckusick 			mt->mt_lookup,
117976dfacdSmckusick 			mt->mt_readdir,
118976dfacdSmckusick 			mt->mt_readlink,
119976dfacdSmckusick 			mt->mt_statfs,
120976dfacdSmckusick 
121976dfacdSmckusick 			tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,
122976dfacdSmckusick 			tp->tm_mon+1, tp->tm_mday,
123976dfacdSmckusick 			tp->tm_hour, tp->tm_min, tp->tm_sec);
124976dfacdSmckusick 	} break;
125976dfacdSmckusick 
126976dfacdSmckusick 	case Short: {
127976dfacdSmckusick 		printf("%-*.*s %-*.*s %-*.*s %s\n",
128976dfacdSmckusick 			*dwid, *dwid,
129976dfacdSmckusick 			*mt->mt_directory ? mt->mt_directory : "/",
130976dfacdSmckusick 			*twid, *twid,
131976dfacdSmckusick 			mt->mt_type,
132976dfacdSmckusick 			*mwid, *mwid,
133976dfacdSmckusick 			mt->mt_mountinfo,
134976dfacdSmckusick 			mt->mt_mountpoint);
135976dfacdSmckusick 	} break;
136976dfacdSmckusick 	}
137976dfacdSmckusick }
138976dfacdSmckusick 
139976dfacdSmckusick /*
140976dfacdSmckusick  * Display a mount tree.
141976dfacdSmckusick  */
show_mt(mt,e,mwid,dwid,pwid)142976dfacdSmckusick static void show_mt(mt, e, mwid, dwid, pwid)
143976dfacdSmckusick amq_mount_tree *mt;
144976dfacdSmckusick enum show_opt e;
145976dfacdSmckusick int *mwid;
146976dfacdSmckusick int *dwid;
147976dfacdSmckusick int *pwid;
148976dfacdSmckusick {
149976dfacdSmckusick 	while (mt) {
150976dfacdSmckusick 		show_mti(mt, e, mwid, dwid, pwid);
151976dfacdSmckusick 		show_mt(mt->mt_next, e, mwid, dwid, pwid);
152976dfacdSmckusick 		mt = mt->mt_child;
153976dfacdSmckusick 	}
154976dfacdSmckusick }
155976dfacdSmckusick 
show_mi(ml,e,mwid,dwid,twid)156976dfacdSmckusick static void show_mi(ml, e, mwid, dwid, twid)
157976dfacdSmckusick amq_mount_info_list *ml;
158976dfacdSmckusick enum show_opt e;
159976dfacdSmckusick int *mwid;
160976dfacdSmckusick int *dwid;
161976dfacdSmckusick int *twid;
162976dfacdSmckusick {
163976dfacdSmckusick 	int i;
164976dfacdSmckusick 	switch (e) {
165976dfacdSmckusick 	case Calc: {
166976dfacdSmckusick 		for (i = 0; i < ml->amq_mount_info_list_len; i++) {
167976dfacdSmckusick 			amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
168976dfacdSmckusick 			int mw = strlen(mi->mi_mountinfo);
169976dfacdSmckusick 			int dw = strlen(mi->mi_mountpt);
170976dfacdSmckusick 			int tw = strlen(mi->mi_type);
171976dfacdSmckusick 			if (mw > *mwid) *mwid = mw;
172976dfacdSmckusick 			if (dw > *dwid) *dwid = dw;
173976dfacdSmckusick 			if (tw > *twid) *twid = tw;
174976dfacdSmckusick 		}
175976dfacdSmckusick 	} break;
176976dfacdSmckusick 
177976dfacdSmckusick 	case Full: {
178976dfacdSmckusick 		for (i = 0; i < ml->amq_mount_info_list_len; i++) {
179976dfacdSmckusick 			amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
180976dfacdSmckusick 			printf("%-*.*s %-*.*s %-*.*s %-3d %s is %s",
181976dfacdSmckusick 						*mwid, *mwid, mi->mi_mountinfo,
182976dfacdSmckusick 						*dwid, *dwid, mi->mi_mountpt,
183976dfacdSmckusick 						*twid, *twid, mi->mi_type,
184976dfacdSmckusick 						mi->mi_refc, mi->mi_fserver,
185976dfacdSmckusick 						mi->mi_up > 0 ? "up" :
186976dfacdSmckusick 						mi->mi_up < 0 ? "starting" : "down");
187976dfacdSmckusick 			if (mi->mi_error > 0) {
1881e971e65Spendry #ifdef HAS_STRERROR
1891e971e65Spendry 				printf(" (%s)", strerror(mi->mi_error));
1901e971e65Spendry #else
191976dfacdSmckusick 				extern char *sys_errlist[];
192976dfacdSmckusick 				extern int sys_nerr;
193976dfacdSmckusick 				if (mi->mi_error < sys_nerr)
194976dfacdSmckusick 					printf(" (%s)", sys_errlist[mi->mi_error]);
195976dfacdSmckusick 				else
196976dfacdSmckusick 					printf(" (Error %d)", mi->mi_error);
1971e971e65Spendry #endif
198976dfacdSmckusick 			} else if (mi->mi_error < 0) {
199976dfacdSmckusick 				fputs(" (in progress)", stdout);
200976dfacdSmckusick 			}
201976dfacdSmckusick 			fputc('\n', stdout);
202976dfacdSmckusick 		}
203976dfacdSmckusick 	} break;
204976dfacdSmckusick 	}
205976dfacdSmckusick }
206976dfacdSmckusick 
207976dfacdSmckusick /*
208976dfacdSmckusick  * Display general mount statistics
209976dfacdSmckusick  */
show_ms(ms)210976dfacdSmckusick static void show_ms(ms)
211976dfacdSmckusick amq_mount_stats *ms;
212976dfacdSmckusick {
213976dfacdSmckusick 	printf("\
214976dfacdSmckusick requests  stale     mount     mount     unmount\n\
215976dfacdSmckusick deferred  fhandles  ok        failed    failed\n\
216976dfacdSmckusick %-9d %-9d %-9d %-9d %-9d\n",
217976dfacdSmckusick 	ms->as_drops, ms->as_stale, ms->as_mok, ms->as_merr, ms->as_uerr);
218976dfacdSmckusick }
219976dfacdSmckusick 
220976dfacdSmckusick static bool_t
xdr_pri_free(xdr_args,args_ptr)221976dfacdSmckusick xdr_pri_free(xdr_args, args_ptr)
222976dfacdSmckusick xdrproc_t xdr_args;
223976dfacdSmckusick caddr_t args_ptr;
224976dfacdSmckusick {
225976dfacdSmckusick 	XDR xdr;
226976dfacdSmckusick 	xdr.x_op = XDR_FREE;
227976dfacdSmckusick 	return ((*xdr_args)(&xdr, args_ptr));
228976dfacdSmckusick }
229976dfacdSmckusick 
230976dfacdSmckusick #ifdef hpux
231976dfacdSmckusick #include <cluster.h>
cluster_server()232976dfacdSmckusick static char *cluster_server()
233976dfacdSmckusick {
234976dfacdSmckusick 	struct cct_entry *cp;
235976dfacdSmckusick 
236976dfacdSmckusick 	if (cnodeid() == 0) {
237976dfacdSmckusick 		/*
238976dfacdSmckusick 		 * Not clustered
239976dfacdSmckusick 		 */
240976dfacdSmckusick 		return def_server;
241976dfacdSmckusick 	}
242976dfacdSmckusick 
243976dfacdSmckusick 	while (cp = getccent())
244976dfacdSmckusick 		if (cp->cnode_type == 'r')
245976dfacdSmckusick 			return cp->cnode_name;
246976dfacdSmckusick 
247976dfacdSmckusick 
248976dfacdSmckusick 	return def_server;
249976dfacdSmckusick }
250976dfacdSmckusick #endif /* hpux */
251976dfacdSmckusick 
252976dfacdSmckusick /*
253976dfacdSmckusick  * MAIN
254976dfacdSmckusick  */
main(argc,argv)255976dfacdSmckusick main(argc, argv)
256976dfacdSmckusick int argc;
257976dfacdSmckusick char *argv[];
258976dfacdSmckusick {
259976dfacdSmckusick 	int opt_ch;
260976dfacdSmckusick 	int errs = 0;
261976dfacdSmckusick 	char *server;
262976dfacdSmckusick 	struct sockaddr_in server_addr;
263fe648a93Spendry 
264fe648a93Spendry 	/* In order to pass the Amd security check, we must use a priv port. */
265fe648a93Spendry 	int s;
266fe648a93Spendry 
267976dfacdSmckusick 	CLIENT *clnt;
268976dfacdSmckusick 	struct hostent *hp;
269976dfacdSmckusick 	int nodefault = 0;
270976dfacdSmckusick 
271976dfacdSmckusick 	/*
272976dfacdSmckusick 	 * Compute program name
273976dfacdSmckusick 	 */
274976dfacdSmckusick 	if (argv[0]) {
275976dfacdSmckusick 		progname = strrchr(argv[0], '/');
276976dfacdSmckusick 		if (progname && progname[1])
277976dfacdSmckusick 			progname++;
278976dfacdSmckusick 		else
279976dfacdSmckusick 			progname = argv[0];
280976dfacdSmckusick 	}
281976dfacdSmckusick 	if (!progname)
282976dfacdSmckusick 		progname = "amq";
283976dfacdSmckusick 
284976dfacdSmckusick 	/*
285976dfacdSmckusick 	 * Parse arguments
286976dfacdSmckusick 	 */
287fe648a93Spendry 	while ((opt_ch = getopt(argc, argv, "fh:l:msuvx:D:M:")) != EOF)
288976dfacdSmckusick 	switch (opt_ch) {
289976dfacdSmckusick 	case 'f':
290976dfacdSmckusick 		flush_flag = 1;
291fe648a93Spendry 		nodefault = 1;
292976dfacdSmckusick 		break;
293976dfacdSmckusick 
294976dfacdSmckusick 	case 'h':
295976dfacdSmckusick 		def_server = optarg;
296976dfacdSmckusick 		break;
297976dfacdSmckusick 
298976dfacdSmckusick 	case 'l':
299976dfacdSmckusick 		logfile = optarg;
300976dfacdSmckusick 		nodefault = 1;
301976dfacdSmckusick 		break;
302976dfacdSmckusick 
303976dfacdSmckusick 	case 'm':
304976dfacdSmckusick 		minfo_flag = 1;
305976dfacdSmckusick 		nodefault = 1;
306976dfacdSmckusick 		break;
307976dfacdSmckusick 
308976dfacdSmckusick 	case 's':
309976dfacdSmckusick 		stats_flag = 1;
310fe648a93Spendry 		nodefault = 1;
311976dfacdSmckusick 		break;
312976dfacdSmckusick 
313976dfacdSmckusick 	case 'u':
314976dfacdSmckusick 		unmount_flag = 1;
315fe648a93Spendry 		nodefault = 1;
316fe648a93Spendry 		break;
317fe648a93Spendry 
318fe648a93Spendry 	case 'v':
319fe648a93Spendry 		getvers_flag = 1;
320fe648a93Spendry 		nodefault = 1;
321976dfacdSmckusick 		break;
322976dfacdSmckusick 
323976dfacdSmckusick 	case 'x':
324fe648a93Spendry 		xlog_optstr = optarg;
325976dfacdSmckusick 		nodefault = 1;
326976dfacdSmckusick 		break;
327976dfacdSmckusick 
328976dfacdSmckusick 	case 'D':
329976dfacdSmckusick 		debug_opts = optarg;
330976dfacdSmckusick 		nodefault = 1;
331976dfacdSmckusick 		break;
332976dfacdSmckusick 
333fe648a93Spendry 	case 'M':
334fe648a93Spendry 		mount_map = optarg;
335fe648a93Spendry 		nodefault = 1;
336fe648a93Spendry 		break;
337fe648a93Spendry 
338976dfacdSmckusick 	default:
339976dfacdSmckusick 		errs = 1;
340976dfacdSmckusick 		break;
341976dfacdSmckusick 	}
342976dfacdSmckusick 
343fe648a93Spendry 	if (optind == argc) {
344fe648a93Spendry 		if (unmount_flag)
345fe648a93Spendry 			errs = 1;
346fe648a93Spendry 	}
347fe648a93Spendry 
348976dfacdSmckusick 	if (errs) {
349976dfacdSmckusick show_usage:
350976dfacdSmckusick 		fprintf(stderr, "\
351fe648a93Spendry Usage: %s [-h host] [[-f] [-m] [-v] [-s]] | [[-u] directory ...]] |\n\
352fe648a93Spendry \t[-l logfile|\"syslog\"] [-x log_flags] [-D dbg_opts] [-M mapent]\n", progname);
353976dfacdSmckusick 		exit(1);
354976dfacdSmckusick 	}
355976dfacdSmckusick 
356976dfacdSmckusick #ifdef hpux
357976dfacdSmckusick 	/*
358976dfacdSmckusick 	 * Figure out root server of cluster
359976dfacdSmckusick 	 */
360976dfacdSmckusick 	if (def_server == localhost)
361976dfacdSmckusick 		server = cluster_server();
362976dfacdSmckusick 	else
363976dfacdSmckusick #endif /* hpux */
364976dfacdSmckusick 	server = def_server;
365976dfacdSmckusick 
366976dfacdSmckusick 	/*
367976dfacdSmckusick 	 * Get address of server
368976dfacdSmckusick 	 */
369278f1af9Spendry 	if ((hp = gethostbyname(server)) == 0 && strcmp(server, localhost) != 0) {
370976dfacdSmckusick 		fprintf(stderr, "%s: Can't get address of %s\n", progname, server);
371976dfacdSmckusick 		exit(1);
372976dfacdSmckusick 	}
373976dfacdSmckusick 	bzero(&server_addr, sizeof server_addr);
374976dfacdSmckusick 	server_addr.sin_family = AF_INET;
375278f1af9Spendry 	if (hp) {
376278f1af9Spendry 		bcopy((voidp) hp->h_addr, (voidp) &server_addr.sin_addr,
377278f1af9Spendry 			sizeof(server_addr.sin_addr));
378278f1af9Spendry 	} else {
379278f1af9Spendry 		/* fake "localhost" */
380278f1af9Spendry 		server_addr.sin_addr.s_addr = htonl(0x7f000001);
381278f1af9Spendry 	}
382976dfacdSmckusick 
383976dfacdSmckusick 	/*
384976dfacdSmckusick 	 * Create RPC endpoint
385976dfacdSmckusick 	 */
3863f1b4436Spendry 	s = privsock(SOCK_STREAM);
3873f1b4436Spendry 	clnt = clnttcp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, &s, 0, 0);
3883f1b4436Spendry 	if (clnt == 0) {
3893f1b4436Spendry 		close(s);
3903f1b4436Spendry 		s = privsock(SOCK_DGRAM);
391976dfacdSmckusick 		clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, TIMEOUT, &s);
3923f1b4436Spendry 	}
393976dfacdSmckusick 	if (clnt == 0) {
394976dfacdSmckusick 		fprintf(stderr, "%s: ", progname);
395976dfacdSmckusick 		clnt_pcreateerror(server);
396976dfacdSmckusick 		exit(1);
397976dfacdSmckusick 	}
398976dfacdSmckusick 
399976dfacdSmckusick 	/*
400976dfacdSmckusick 	 * Control debugging
401976dfacdSmckusick 	 */
402976dfacdSmckusick 	if (debug_opts) {
403976dfacdSmckusick 		int *rc;
404976dfacdSmckusick 		amq_setopt opt;
405976dfacdSmckusick 		opt.as_opt = AMOPT_DEBUG;
406976dfacdSmckusick 		opt.as_str = debug_opts;
407976dfacdSmckusick 		rc = amqproc_setopt_1(&opt, clnt);
408976dfacdSmckusick 		if (rc && *rc < 0) {
409976dfacdSmckusick 			fprintf(stderr, "%s: daemon not compiled for debug", progname);
410976dfacdSmckusick 			errs = 1;
411976dfacdSmckusick 		} else if (!rc || *rc > 0) {
412976dfacdSmckusick 			fprintf(stderr, "%s: debug setting for \"%s\" failed\n", progname, debug_opts);
413976dfacdSmckusick 			errs = 1;
414976dfacdSmckusick 		}
415976dfacdSmckusick 	}
416976dfacdSmckusick 
417976dfacdSmckusick 	/*
418976dfacdSmckusick 	 * Control logging
419976dfacdSmckusick 	 */
420fe648a93Spendry 	if (xlog_optstr) {
421976dfacdSmckusick 		int *rc;
422976dfacdSmckusick 		amq_setopt opt;
423976dfacdSmckusick 		opt.as_opt = AMOPT_XLOG;
424fe648a93Spendry 		opt.as_str = xlog_optstr;
425976dfacdSmckusick 		rc = amqproc_setopt_1(&opt, clnt);
426976dfacdSmckusick 		if (!rc || *rc) {
427fe648a93Spendry 			fprintf(stderr, "%s: setting log level to \"%s\" failed\n", progname, xlog_optstr);
428976dfacdSmckusick 			errs = 1;
429976dfacdSmckusick 		}
430976dfacdSmckusick 	}
431976dfacdSmckusick 
432976dfacdSmckusick 	/*
433976dfacdSmckusick 	 * Control log file
434976dfacdSmckusick 	 */
435976dfacdSmckusick 	if (logfile) {
436976dfacdSmckusick 		int *rc;
437976dfacdSmckusick 		amq_setopt opt;
438976dfacdSmckusick 		opt.as_opt = AMOPT_LOGFILE;
439976dfacdSmckusick 		opt.as_str = logfile;
440976dfacdSmckusick 		rc = amqproc_setopt_1(&opt, clnt);
441976dfacdSmckusick 		if (!rc || *rc) {
442976dfacdSmckusick 			fprintf(stderr, "%s: setting logfile to \"%s\" failed\n", progname, logfile);
443976dfacdSmckusick 			errs = 1;
444976dfacdSmckusick 		}
445976dfacdSmckusick 	}
446976dfacdSmckusick 
447976dfacdSmckusick 	/*
448976dfacdSmckusick 	 * Flush map cache
449976dfacdSmckusick 	 */
450fe648a93Spendry 	if (flush_flag) {
451976dfacdSmckusick 		int *rc;
452976dfacdSmckusick 		amq_setopt opt;
453976dfacdSmckusick 		opt.as_opt = AMOPT_FLUSHMAPC;
454976dfacdSmckusick 		opt.as_str = "";
455976dfacdSmckusick 		rc = amqproc_setopt_1(&opt, clnt);
456976dfacdSmckusick 		if (!rc || *rc) {
457976dfacdSmckusick 			fprintf(stderr, "%s: amd on %s cannot flush the map cache\n", progname, server);
458976dfacdSmckusick 			errs = 1;
459976dfacdSmckusick 		}
460976dfacdSmckusick 	}
461976dfacdSmckusick 
462976dfacdSmckusick 	/*
463976dfacdSmckusick 	 * Mount info
464976dfacdSmckusick 	 */
465976dfacdSmckusick 	if (minfo_flag) {
466976dfacdSmckusick 		int dummy;
467976dfacdSmckusick 		amq_mount_info_list *ml = amqproc_getmntfs_1(&dummy, clnt);
468976dfacdSmckusick 		if (ml) {
469976dfacdSmckusick 			int mwid = 0, dwid = 0, twid = 0;
470976dfacdSmckusick 			show_mi(ml, Calc, &mwid, &dwid, &twid);
471976dfacdSmckusick 			mwid++; dwid++; twid++;
472976dfacdSmckusick 			show_mi(ml, Full, &mwid, &dwid, &twid);
473976dfacdSmckusick 
474976dfacdSmckusick 		} else {
475976dfacdSmckusick 			fprintf(stderr, "%s: amd on %s cannot provide mount info\n", progname, server);
476976dfacdSmckusick 		}
477976dfacdSmckusick 	}
478976dfacdSmckusick 
479976dfacdSmckusick 	/*
480fe648a93Spendry 	 * Mount map
481fe648a93Spendry 	 */
482fe648a93Spendry 	if (mount_map) {
483fe648a93Spendry 		int *rc;
484fe648a93Spendry 		do {
485fe648a93Spendry 			rc = amqproc_mount_1(&mount_map, clnt);
486fe648a93Spendry 		} while (rc && *rc < 0);
487fe648a93Spendry 		if (!rc || *rc > 0) {
488fe648a93Spendry 			if (rc)
489fe648a93Spendry 				errno = *rc;
490fe648a93Spendry 			else
491fe648a93Spendry 				errno = ETIMEDOUT;
492fe648a93Spendry 			fprintf(stderr, "%s: could not start new ", progname);
493fe648a93Spendry 			perror("autmount point");
494fe648a93Spendry 		}
495fe648a93Spendry 	}
496fe648a93Spendry 
497fe648a93Spendry 	/*
498fe648a93Spendry 	 * Get Version
499fe648a93Spendry 	 */
500fe648a93Spendry 	if (getvers_flag) {
501fe648a93Spendry 		amq_string *spp = amqproc_getvers_1((voidp) 0, clnt);
502fe648a93Spendry 		if (spp && *spp) {
503fe648a93Spendry 			printf("%s.\n", *spp);
504fe648a93Spendry 			free(*spp);
505fe648a93Spendry 		} else {
506278f1af9Spendry 			fprintf(stderr, "%s: failed to get version information\n", progname);
507fe648a93Spendry 			errs = 1;
508fe648a93Spendry 		}
509fe648a93Spendry 	}
510fe648a93Spendry 
511fe648a93Spendry 	/*
512976dfacdSmckusick 	 * Apply required operation to all remaining arguments
513976dfacdSmckusick 	 */
514976dfacdSmckusick 	if (optind < argc) {
515976dfacdSmckusick 		do {
516976dfacdSmckusick 			char *fs = argv[optind++];
517976dfacdSmckusick 			if (unmount_flag) {
518976dfacdSmckusick 				/*
519976dfacdSmckusick 				 * Unmount request
520976dfacdSmckusick 				 */
521976dfacdSmckusick 				amqproc_umnt_1(&fs, clnt);
522976dfacdSmckusick 			} else {
523976dfacdSmckusick 				/*
524976dfacdSmckusick 				 * Stats request
525976dfacdSmckusick 				 */
526976dfacdSmckusick 				amq_mount_tree_p *mtp = amqproc_mnttree_1(&fs, clnt);
527976dfacdSmckusick 				if (mtp) {
528976dfacdSmckusick 					amq_mount_tree *mt = *mtp;
529976dfacdSmckusick 					if (mt) {
530976dfacdSmckusick 						int mwid = 0, dwid = 0, twid = 0;
531976dfacdSmckusick 						show_mt(mt, Calc, &mwid, &dwid, &twid);
532976dfacdSmckusick 						mwid++; dwid++, twid++;
533976dfacdSmckusick 		printf("%-*.*s Uid   Getattr Lookup RdDir   RdLnk   Statfs Mounted@\n",
534976dfacdSmckusick 			dwid, dwid, "What");
535976dfacdSmckusick 						show_mt(mt, Stats, &mwid, &dwid, &twid);
536976dfacdSmckusick 					} else {
537976dfacdSmckusick 						fprintf(stderr, "%s: %s not automounted\n", progname, fs);
538976dfacdSmckusick 					}
539976dfacdSmckusick 					xdr_pri_free(xdr_amq_mount_tree_p, (caddr_t) mtp);
540976dfacdSmckusick 				} else {
541976dfacdSmckusick 					fprintf(stderr, "%s: ", progname);
542976dfacdSmckusick 					clnt_perror(clnt, server);
543976dfacdSmckusick 					errs = 1;
544976dfacdSmckusick 				}
545976dfacdSmckusick 			}
546976dfacdSmckusick 		} while (optind < argc);
547976dfacdSmckusick 	} else if (unmount_flag) {
548976dfacdSmckusick 		goto show_usage;
549976dfacdSmckusick 	} else if (stats_flag) {
550976dfacdSmckusick 		amq_mount_stats *ms = amqproc_stats_1((voidp) 0, clnt);
551976dfacdSmckusick 		if (ms) {
552976dfacdSmckusick 			show_ms(ms);
553976dfacdSmckusick 		} else {
554976dfacdSmckusick 			fprintf(stderr, "%s: ", progname);
555976dfacdSmckusick 			clnt_perror(clnt, server);
556976dfacdSmckusick 			errs = 1;
557976dfacdSmckusick 		}
558976dfacdSmckusick 	} else if (!nodefault) {
559976dfacdSmckusick 		amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt);
560976dfacdSmckusick 		if (mlp) {
561976dfacdSmckusick 			enum show_opt e = Calc;
562976dfacdSmckusick 			int mwid = 0, dwid = 0, pwid = 0;
563976dfacdSmckusick 			while (e != ShowDone) {
564976dfacdSmckusick 				int i;
565976dfacdSmckusick 				for (i = 0; i < mlp->amq_mount_tree_list_len; i++) {
566976dfacdSmckusick 					show_mt(mlp->amq_mount_tree_list_val[i],
567976dfacdSmckusick 						 e, &mwid, &dwid, &pwid);
568976dfacdSmckusick 				}
569976dfacdSmckusick 				mwid++; dwid++, pwid++;
570976dfacdSmckusick 				if (e == Calc) e = Short;
571976dfacdSmckusick 				else if (e == Short) e = ShowDone;
572976dfacdSmckusick 			}
573976dfacdSmckusick 		} else {
574976dfacdSmckusick 			fprintf(stderr, "%s: ", progname);
575976dfacdSmckusick 			clnt_perror(clnt, server);
576976dfacdSmckusick 			errs = 1;
577976dfacdSmckusick 		}
578976dfacdSmckusick 	}
579976dfacdSmckusick 
580976dfacdSmckusick 	exit(errs);
581976dfacdSmckusick }
582976dfacdSmckusick 
583fe648a93Spendry /*
584fe648a93Spendry  * udpresport creates a datagram socket and attempts to bind it to a
585fe648a93Spendry  * secure port.
586fe648a93Spendry  * returns: The bound socket, or -1 to indicate an error.
587fe648a93Spendry  */
inetresport(ty)5883f1b4436Spendry static int inetresport(ty)
5893f1b4436Spendry int ty;
590fe648a93Spendry {
591fe648a93Spendry 	int alport;
592fe648a93Spendry 	struct sockaddr_in addr;
593fe648a93Spendry 	int sock;
594fe648a93Spendry 
595fe648a93Spendry 	/* Use internet address family */
596fe648a93Spendry 	addr.sin_family = AF_INET;
597fe648a93Spendry 	addr.sin_addr.s_addr = INADDR_ANY;
5983f1b4436Spendry 	if ((sock = socket(AF_INET, ty, 0)) < 0)
599fe648a93Spendry 		return -1;
600fe648a93Spendry 	for (alport = IPPORT_RESERVED-1; alport > IPPORT_RESERVED/2 + 1; alport--) {
601fe648a93Spendry 		addr.sin_port = htons((u_short)alport);
602fe648a93Spendry 		if (bind(sock, (struct sockaddr *)&addr, sizeof (addr)) >= 0)
603fe648a93Spendry 			return sock;
604fe648a93Spendry 		if (errno != EADDRINUSE) {
605fe648a93Spendry 			close(sock);
606fe648a93Spendry 			return -1;
607fe648a93Spendry 		}
608fe648a93Spendry 	}
609fe648a93Spendry 	close(sock);
610fe648a93Spendry 	errno = EAGAIN;
611fe648a93Spendry 	return -1;
612fe648a93Spendry }
613fe648a93Spendry 
614fe648a93Spendry /*
6153f1b4436Spendry  * Privsock() calls inetresport() to attempt to bind a socket to a secure
6163f1b4436Spendry  * port.  If inetresport() fails, privsock returns a magic socket number which
617fe648a93Spendry  * indicates to RPC that it should make its own socket.
618fe648a93Spendry  * returns: A privileged socket # or RPC_ANYSOCK.
619fe648a93Spendry  */
privsock(ty)6203f1b4436Spendry static int privsock(ty)
6213f1b4436Spendry int ty;
622fe648a93Spendry {
6233f1b4436Spendry 	int sock = inetresport(ty);
624fe648a93Spendry 
625fe648a93Spendry 	if (sock < 0) {
626fe648a93Spendry 		errno = 0;
627fe648a93Spendry 		/* Couldn't get a secure port, let RPC make an insecure one */
628fe648a93Spendry 		sock = RPC_ANYSOCK;
629fe648a93Spendry 	}
630fe648a93Spendry 	return sock;
631fe648a93Spendry }
632fe648a93Spendry 
633976dfacdSmckusick #ifdef DEBUG
xfree(f,l,p)634976dfacdSmckusick xfree(f, l, p)
635976dfacdSmckusick char *f, *l;
636976dfacdSmckusick voidp p;
637976dfacdSmckusick {
638976dfacdSmckusick 	free(p);
639976dfacdSmckusick }
640976dfacdSmckusick #endif /* DEBUG */
641