138494Sobrien/*
2174313Sobrien * Copyright (c) 1997-2006 Erez Zadok
338494Sobrien * Copyright (c) 1990 Jan-Simon Pendry
438494Sobrien * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
538494Sobrien * Copyright (c) 1990 The Regents of the University of California.
638494Sobrien * All rights reserved.
738494Sobrien *
838494Sobrien * This code is derived from software contributed to Berkeley by
938494Sobrien * Jan-Simon Pendry at Imperial College, London.
1038494Sobrien *
1138494Sobrien * Redistribution and use in source and binary forms, with or without
1238494Sobrien * modification, are permitted provided that the following conditions
1338494Sobrien * are met:
1438494Sobrien * 1. Redistributions of source code must retain the above copyright
1538494Sobrien *    notice, this list of conditions and the following disclaimer.
1638494Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1738494Sobrien *    notice, this list of conditions and the following disclaimer in the
1838494Sobrien *    documentation and/or other materials provided with the distribution.
1938494Sobrien * 3. All advertising materials mentioning features or use of this software
2042633Sobrien *    must display the following acknowledgment:
2138494Sobrien *      This product includes software developed by the University of
2238494Sobrien *      California, Berkeley and its contributors.
2338494Sobrien * 4. Neither the name of the University nor the names of its contributors
2438494Sobrien *    may be used to endorse or promote products derived from this software
2538494Sobrien *    without specific prior written permission.
2638494Sobrien *
2738494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2838494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2938494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3038494Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3138494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3238494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3338494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3438494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3538494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3638494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3738494Sobrien * SUCH DAMAGE.
3838494Sobrien *
3938494Sobrien *
40174313Sobrien * File: am-utils/amq/amq.c
4138494Sobrien *
4238494Sobrien */
4338494Sobrien
4438494Sobrien/*
4538494Sobrien * Automounter query tool
4638494Sobrien */
4738494Sobrien
4838494Sobrien#ifdef HAVE_CONFIG_H
4938494Sobrien# include <config.h>
5038494Sobrien#endif /* HAVE_CONFIG_H */
5138494Sobrien#include <am_defs.h>
5238494Sobrien#include <amq.h>
5338494Sobrien
5438494Sobrien/* locals */
5538494Sobrienstatic int flush_flag;
5638494Sobrienstatic int minfo_flag;
5738494Sobrienstatic int getpid_flag;
5838494Sobrienstatic int unmount_flag;
5938494Sobrienstatic int stats_flag;
6038494Sobrienstatic int getvers_flag;
6138494Sobrienstatic int amd_program_number = AMQ_PROGRAM;
6238494Sobrienstatic int use_tcp_flag, use_udp_flag;
6382801Sobrienstatic int getpwd_flag;
6438494Sobrienstatic char *debug_opts;
6538494Sobrienstatic char *amq_logfile;
6638494Sobrienstatic char *xlog_optstr;
6738494Sobrienstatic char localhost[] = "localhost";
6838494Sobrienstatic char *def_server = localhost;
6938494Sobrien
7038494Sobrien/* externals */
7138494Sobrienextern int optind;
7238494Sobrienextern char *optarg;
7338494Sobrien
7438494Sobrien/* structures */
7538494Sobrienenum show_opt {
7638494Sobrien  Full, Stats, Calc, Short, ShowDone
7738494Sobrien};
7838494Sobrien
7938494Sobrien
8038494Sobrien/*
8138494Sobrien * If (e) is Calc then just calculate the sizes
8238494Sobrien * Otherwise display the mount node on stdout
8338494Sobrien */
8438494Sobrienstatic void
8538494Sobrienshow_mti(amq_mount_tree *mt, enum show_opt e, int *mwid, int *dwid, int *twid)
8638494Sobrien{
8738494Sobrien  switch (e) {
8838494Sobrien  case Calc:
8938494Sobrien    {
9038494Sobrien      int mw = strlen(mt->mt_mountinfo);
9138494Sobrien      int dw = strlen(mt->mt_directory);
9238494Sobrien      int tw = strlen(mt->mt_type);
9338494Sobrien      if (mw > *mwid)
9438494Sobrien	*mwid = mw;
9538494Sobrien      if (dw > *dwid)
9638494Sobrien	*dwid = dw;
9738494Sobrien      if (tw > *twid)
9838494Sobrien	*twid = tw;
9938494Sobrien    }
10038494Sobrien  break;
10138494Sobrien
10238494Sobrien  case Full:
10338494Sobrien    {
104174313Sobrien      struct tm *tp = localtime((time_t *) ((voidp) &mt->mt_mounttime));
105174313Sobrien      printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%04d %02d:%02d:%02d\n",
10638494Sobrien	     *dwid, *dwid,
10738494Sobrien	     *mt->mt_directory ? mt->mt_directory : "/",	/* XXX */
10838494Sobrien	     *twid, *twid,
10938494Sobrien	     mt->mt_type,
11038494Sobrien	     *mwid, *mwid,
11138494Sobrien	     mt->mt_mountinfo,
11238494Sobrien	     mt->mt_mountpoint,
11338494Sobrien
11438494Sobrien	     mt->mt_mountuid,
11538494Sobrien	     mt->mt_getattr,
11638494Sobrien	     mt->mt_lookup,
11738494Sobrien	     mt->mt_readdir,
11838494Sobrien	     mt->mt_readlink,
11938494Sobrien	     mt->mt_statfs,
12038494Sobrien
12138494Sobrien	     tp->tm_mon + 1, tp->tm_mday,
122174313Sobrien	     tp->tm_year < 1900 ? tp->tm_year + 1900 : tp->tm_year,
12338494Sobrien	     tp->tm_hour, tp->tm_min, tp->tm_sec);
12438494Sobrien    }
12538494Sobrien  break;
12638494Sobrien
12738494Sobrien  case Stats:
12838494Sobrien    {
129174313Sobrien      struct tm *tp = localtime((time_t *) ((voidp) &mt->mt_mounttime));
130174313Sobrien      printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%04d\n",
13138494Sobrien	     *dwid, *dwid,
13238494Sobrien	     *mt->mt_directory ? mt->mt_directory : "/",	/* XXX */
13338494Sobrien
13438494Sobrien	     mt->mt_mountuid,
13538494Sobrien	     mt->mt_getattr,
13638494Sobrien	     mt->mt_lookup,
13738494Sobrien	     mt->mt_readdir,
13838494Sobrien	     mt->mt_readlink,
13938494Sobrien	     mt->mt_statfs,
14038494Sobrien
14138494Sobrien	     tp->tm_mon + 1, tp->tm_mday,
142174313Sobrien	     tp->tm_year < 1900 ? tp->tm_year + 1900 : tp->tm_year,
14338494Sobrien	     tp->tm_hour, tp->tm_min, tp->tm_sec);
14438494Sobrien    }
14538494Sobrien  break;
14638494Sobrien
14738494Sobrien  case Short:
14838494Sobrien    {
14938494Sobrien      printf("%-*.*s %-*.*s %-*.*s %s\n",
15038494Sobrien	     *dwid, *dwid,
15138494Sobrien	     *mt->mt_directory ? mt->mt_directory : "/",
15238494Sobrien	     *twid, *twid,
15338494Sobrien	     mt->mt_type,
15438494Sobrien	     *mwid, *mwid,
15538494Sobrien	     mt->mt_mountinfo,
15638494Sobrien	     mt->mt_mountpoint);
15738494Sobrien    }
15838494Sobrien  break;
15938494Sobrien
16038494Sobrien  default:
16138494Sobrien    break;
16238494Sobrien  }
16338494Sobrien}
16438494Sobrien
16582801Sobrien
16638494Sobrien/*
16782801Sobrien * Display a pwd data
16882801Sobrien */
16982801Sobrienstatic void
170174313Sobrienshow_pwd(amq_mount_tree *mt, char *path, size_t l, int *flag)
17182801Sobrien{
17282801Sobrien  int len;
17382801Sobrien
17482801Sobrien  while (mt) {
17582801Sobrien    len = strlen(mt->mt_mountpoint);
17682801Sobrien    if (NSTREQ(path, mt->mt_mountpoint, len) &&
17782801Sobrien	!STREQ(mt->mt_directory, mt->mt_mountpoint)) {
178174313Sobrien      char buf[MAXPATHLEN+1];	/* must be same size as 'path' */
179174313Sobrien      xstrlcpy(buf, mt->mt_directory, sizeof(buf));
180174313Sobrien      xstrlcat(buf, &path[len], sizeof(buf));
181174313Sobrien      xstrlcpy(path, buf, l);
18282801Sobrien      *flag = 1;
18382801Sobrien    }
184174313Sobrien    show_pwd(mt->mt_next, path, l, flag);
18582801Sobrien    mt = mt->mt_child;
18682801Sobrien  }
18782801Sobrien}
18882801Sobrien
18982801Sobrien
19082801Sobrien/*
19138494Sobrien * Display a mount tree.
19238494Sobrien */
19338494Sobrienstatic void
19438494Sobrienshow_mt(amq_mount_tree *mt, enum show_opt e, int *mwid, int *dwid, int *pwid)
19538494Sobrien{
19638494Sobrien  while (mt) {
19738494Sobrien    show_mti(mt, e, mwid, dwid, pwid);
19838494Sobrien    show_mt(mt->mt_next, e, mwid, dwid, pwid);
19938494Sobrien    mt = mt->mt_child;
20038494Sobrien  }
20138494Sobrien}
20238494Sobrien
20382801Sobrien
20438494Sobrienstatic void
20538494Sobrienshow_mi(amq_mount_info_list *ml, enum show_opt e, int *mwid, int *dwid, int *twid)
20638494Sobrien{
207174313Sobrien  u_int i;
20838494Sobrien
20938494Sobrien  switch (e) {
21038494Sobrien
21138494Sobrien  case Calc:
21238494Sobrien    {
21338494Sobrien      for (i = 0; i < ml->amq_mount_info_list_len; i++) {
21438494Sobrien	amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
21538494Sobrien	int mw = strlen(mi->mi_mountinfo);
21638494Sobrien	int dw = strlen(mi->mi_mountpt);
21738494Sobrien	int tw = strlen(mi->mi_type);
21838494Sobrien	if (mw > *mwid)
21938494Sobrien	  *mwid = mw;
22038494Sobrien	if (dw > *dwid)
22138494Sobrien	  *dwid = dw;
22238494Sobrien	if (tw > *twid)
22338494Sobrien	  *twid = tw;
22438494Sobrien      }
22538494Sobrien    }
22638494Sobrien  break;
22738494Sobrien
22838494Sobrien  case Full:
22938494Sobrien    {
23038494Sobrien      for (i = 0; i < ml->amq_mount_info_list_len; i++) {
23138494Sobrien	amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
23238494Sobrien	printf("%-*.*s %-*.*s %-*.*s %-3d %s is %s",
23338494Sobrien	       *mwid, *mwid, mi->mi_mountinfo,
23438494Sobrien	       *dwid, *dwid, mi->mi_mountpt,
23538494Sobrien	       *twid, *twid, mi->mi_type,
23638494Sobrien	       mi->mi_refc, mi->mi_fserver,
23738494Sobrien	       mi->mi_up > 0 ? "up" :
23838494Sobrien	       mi->mi_up < 0 ? "starting" : "down");
23938494Sobrien	if (mi->mi_error > 0) {
240174313Sobrien	  printf(" (%s)", strerror(mi->mi_error));
24138494Sobrien	} else if (mi->mi_error < 0) {
24238494Sobrien	  fputs(" (in progress)", stdout);
24338494Sobrien	}
24438494Sobrien	fputc('\n', stdout);
24538494Sobrien      }
24638494Sobrien    }
24738494Sobrien  break;
24838494Sobrien
24938494Sobrien  default:
25038494Sobrien    break;
25138494Sobrien  }
25238494Sobrien}
25338494Sobrien
25438494Sobrien
25538494Sobrien/*
25638494Sobrien * Display general mount statistics
25738494Sobrien */
25838494Sobrienstatic void
25938494Sobrienshow_ms(amq_mount_stats *ms)
26038494Sobrien{
26138494Sobrien  printf("\
26238494Sobrienrequests  stale     mount     mount     unmount\n\
26338494Sobriendeferred  fhandles  ok        failed    failed\n\
26438494Sobrien%-9d %-9d %-9d %-9d %-9d\n",
26538494Sobrien	 ms->as_drops, ms->as_stale, ms->as_mok, ms->as_merr, ms->as_uerr);
26638494Sobrien}
26738494Sobrien
26838494Sobrien
26938494Sobrien#if defined(HAVE_CLUSTER_H) && defined(HAVE_CNODEID) && defined(HAVE_GETCCENT)
27038494Sobrienstatic char *
27138494Sobriencluster_server(void)
27238494Sobrien{
27338494Sobrien  struct cct_entry *cp;
27438494Sobrien
27538494Sobrien  if (cnodeid() == 0) {
27638494Sobrien    /*
27738494Sobrien     * Not clustered
27838494Sobrien     */
27938494Sobrien    return def_server;
28038494Sobrien  }
28138494Sobrien  while (cp = getccent())
28238494Sobrien    if (cp->cnode_type == 'r')
28338494Sobrien      return cp->cnode_name;
28438494Sobrien
28538494Sobrien  return def_server;
28638494Sobrien}
28738494Sobrien#endif /* defined(HAVE_CLUSTER_H) && defined(HAVE_CNODEID) && defined(HAVE_GETCCENT) */
28838494Sobrien
28938494Sobrien
29038494Sobrien/*
29138494Sobrien * MAIN
29238494Sobrien */
29338494Sobrienint
29438494Sobrienmain(int argc, char *argv[])
29538494Sobrien{
29638494Sobrien  int opt_ch;
29738494Sobrien  int errs = 0;
29838494Sobrien  char *server;
29938494Sobrien  struct sockaddr_in server_addr;
30038494Sobrien  CLIENT *clnt = NULL;
30138494Sobrien  struct hostent *hp;
30238494Sobrien  int nodefault = 0;
30338494Sobrien  struct timeval tv;
30442633Sobrien  char *progname = NULL;
30538494Sobrien
30638494Sobrien  /*
30738494Sobrien   * Compute program name
30838494Sobrien   */
30938494Sobrien  if (argv[0]) {
31038494Sobrien    progname = strrchr(argv[0], '/');
31138494Sobrien    if (progname && progname[1])
31238494Sobrien      progname++;
31338494Sobrien    else
31438494Sobrien      progname = argv[0];
31538494Sobrien  }
31638494Sobrien  if (!progname)
31738494Sobrien    progname = "amq";
31842633Sobrien  am_set_progname(progname);
31938494Sobrien
32038494Sobrien  /*
32138494Sobrien   * Parse arguments
32238494Sobrien   */
32382801Sobrien  while ((opt_ch = getopt(argc, argv, "Hfh:l:msuvx:D:pP:TUw")) != -1)
32438494Sobrien    switch (opt_ch) {
32582801Sobrien    case 'H':
32682801Sobrien      goto show_usage;
32782801Sobrien      break;
32882801Sobrien
32938494Sobrien    case 'f':
33038494Sobrien      flush_flag = 1;
33138494Sobrien      nodefault = 1;
33238494Sobrien      break;
33338494Sobrien
33438494Sobrien    case 'h':
33538494Sobrien      def_server = optarg;
33638494Sobrien      break;
33738494Sobrien
33838494Sobrien    case 'l':
33938494Sobrien      amq_logfile = optarg;
34038494Sobrien      nodefault = 1;
34138494Sobrien      break;
34238494Sobrien
34338494Sobrien    case 'm':
34438494Sobrien      minfo_flag = 1;
34538494Sobrien      nodefault = 1;
34638494Sobrien      break;
34738494Sobrien
34838494Sobrien    case 'p':
34938494Sobrien      getpid_flag = 1;
35038494Sobrien      nodefault = 1;
35138494Sobrien      break;
35238494Sobrien
35338494Sobrien    case 's':
35438494Sobrien      stats_flag = 1;
35538494Sobrien      nodefault = 1;
35638494Sobrien      break;
35738494Sobrien
35838494Sobrien    case 'u':
35938494Sobrien      unmount_flag = 1;
36038494Sobrien      nodefault = 1;
36138494Sobrien      break;
36238494Sobrien
36338494Sobrien    case 'v':
36438494Sobrien      getvers_flag = 1;
36538494Sobrien      nodefault = 1;
36638494Sobrien      break;
36738494Sobrien
36838494Sobrien    case 'x':
36938494Sobrien      xlog_optstr = optarg;
37038494Sobrien      nodefault = 1;
37138494Sobrien      break;
37238494Sobrien
37338494Sobrien    case 'D':
37438494Sobrien      debug_opts = optarg;
37538494Sobrien      nodefault = 1;
37638494Sobrien      break;
37738494Sobrien
37838494Sobrien    case 'P':
37938494Sobrien      amd_program_number = atoi(optarg);
38038494Sobrien      break;
38138494Sobrien
38238494Sobrien    case 'T':
38338494Sobrien      use_tcp_flag = 1;
38438494Sobrien      break;
38538494Sobrien
38638494Sobrien    case 'U':
38738494Sobrien      use_udp_flag = 1;
38838494Sobrien      break;
38938494Sobrien
39082801Sobrien    case 'w':
39182801Sobrien      getpwd_flag = 1;
39282801Sobrien      break;
39382801Sobrien
39438494Sobrien    default:
39538494Sobrien      errs = 1;
39638494Sobrien      break;
39738494Sobrien    }
39838494Sobrien
39938494Sobrien  if (optind == argc) {
40038494Sobrien    if (unmount_flag)
40138494Sobrien      errs = 1;
40238494Sobrien  }
40338494Sobrien  if (errs) {
40438494Sobrien  show_usage:
40538494Sobrien    fprintf(stderr, "\
40682801SobrienUsage: %s [-fmpsvwHTU] [-h hostname] [-l log_file|\"syslog\"]\n\
40782801Sobrien\t[-x log_options] [-D debug_options]\n\
40882801Sobrien\t[-P program_number] [[-u] directory ...]\n",
40982801Sobrien	    am_get_progname()
41051300Sobrien    );
41138494Sobrien    exit(1);
41238494Sobrien  }
41338494Sobrien
41451300Sobrien
41538494Sobrien  /* set use_udp and use_tcp flags both to on if none are defined */
41638494Sobrien  if (!use_tcp_flag && !use_udp_flag)
41738494Sobrien    use_tcp_flag = use_udp_flag = 1;
41838494Sobrien
41938494Sobrien#if defined(HAVE_CLUSTER_H) && defined(HAVE_CNODEID) && defined(HAVE_GETCCENT)
42038494Sobrien  /*
42138494Sobrien   * Figure out root server of cluster
42238494Sobrien   */
42338494Sobrien  if (def_server == localhost)
42438494Sobrien    server = cluster_server();
42538494Sobrien  else
42638494Sobrien#endif /* defined(HAVE_CLUSTER_H) && defined(HAVE_CNODEID) && defined(HAVE_GETCCENT) */
42738494Sobrien    server = def_server;
42838494Sobrien
42938494Sobrien  /*
43038494Sobrien   * Get address of server
43138494Sobrien   */
43238494Sobrien  if ((hp = gethostbyname(server)) == 0 && !STREQ(server, localhost)) {
43342633Sobrien    fprintf(stderr, "%s: Can't get address of %s\n",
43442633Sobrien	    am_get_progname(), server);
43538494Sobrien    exit(1);
43638494Sobrien  }
437174313Sobrien  memset(&server_addr, 0, sizeof(server_addr));
438174313Sobrien  /* as per POSIX, sin_len need not be set (used internally by kernel) */
43938494Sobrien  server_addr.sin_family = AF_INET;
44038494Sobrien  if (hp) {
44138494Sobrien    memmove((voidp) &server_addr.sin_addr, (voidp) hp->h_addr,
44238494Sobrien	    sizeof(server_addr.sin_addr));
44338494Sobrien  } else {
44438494Sobrien    /* fake "localhost" */
44538494Sobrien    server_addr.sin_addr.s_addr = htonl(0x7f000001);
44638494Sobrien  }
44738494Sobrien
44838494Sobrien  /*
44938494Sobrien   * Create RPC endpoint
45038494Sobrien   */
45138494Sobrien  tv.tv_sec = 5;		/* 5 seconds for timeout or per retry */
45238494Sobrien  tv.tv_usec = 0;
45338494Sobrien
45482801Sobrien  if (use_tcp_flag)	/* try tcp first */
45538494Sobrien    clnt = clnt_create(server, amd_program_number, AMQ_VERSION, "tcp");
45638494Sobrien  if (!clnt && use_udp_flag) {	/* try udp next */
45738494Sobrien    clnt = clnt_create(server, amd_program_number, AMQ_VERSION, "udp");
45838494Sobrien    /* if ok, set timeout (valid for connectionless transports only) */
45938494Sobrien    if (clnt)
46038494Sobrien      clnt_control(clnt, CLSET_RETRY_TIMEOUT, (char *) &tv);
46138494Sobrien  }
46238494Sobrien  if (!clnt) {
46342633Sobrien    fprintf(stderr, "%s: ", am_get_progname());
46438494Sobrien    clnt_pcreateerror(server);
46538494Sobrien    exit(1);
46638494Sobrien  }
46738494Sobrien
46838494Sobrien  /*
46938494Sobrien   * Control debugging
47038494Sobrien   */
47138494Sobrien  if (debug_opts) {
47238494Sobrien    int *rc;
47338494Sobrien    amq_setopt opt;
47438494Sobrien    opt.as_opt = AMOPT_DEBUG;
47538494Sobrien    opt.as_str = debug_opts;
47638494Sobrien    rc = amqproc_setopt_1(&opt, clnt);
47738494Sobrien    if (rc && *rc < 0) {
47842633Sobrien      fprintf(stderr, "%s: daemon not compiled for debug\n",
47942633Sobrien	      am_get_progname());
48038494Sobrien      errs = 1;
48138494Sobrien    } else if (!rc || *rc > 0) {
48242633Sobrien      fprintf(stderr, "%s: debug setting for \"%s\" failed\n",
48342633Sobrien	      am_get_progname(), debug_opts);
48438494Sobrien      errs = 1;
48538494Sobrien    }
48638494Sobrien  }
48738494Sobrien
48838494Sobrien  /*
48938494Sobrien   * Control logging
49038494Sobrien   */
49138494Sobrien  if (xlog_optstr) {
49238494Sobrien    int *rc;
49338494Sobrien    amq_setopt opt;
49438494Sobrien    opt.as_opt = AMOPT_XLOG;
49538494Sobrien    opt.as_str = xlog_optstr;
49638494Sobrien    rc = amqproc_setopt_1(&opt, clnt);
49738494Sobrien    if (!rc || *rc) {
49842633Sobrien      fprintf(stderr, "%s: setting log level to \"%s\" failed\n",
49942633Sobrien	      am_get_progname(), xlog_optstr);
50038494Sobrien      errs = 1;
50138494Sobrien    }
50238494Sobrien  }
50338494Sobrien
50438494Sobrien  /*
50538494Sobrien   * Control log file
50638494Sobrien   */
50738494Sobrien  if (amq_logfile) {
50838494Sobrien    int *rc;
50938494Sobrien    amq_setopt opt;
51038494Sobrien    opt.as_opt = AMOPT_LOGFILE;
51138494Sobrien    opt.as_str = amq_logfile;
51238494Sobrien    rc = amqproc_setopt_1(&opt, clnt);
51338494Sobrien    if (!rc || *rc) {
51442633Sobrien      fprintf(stderr, "%s: setting logfile to \"%s\" failed\n",
51542633Sobrien	      am_get_progname(), amq_logfile);
51638494Sobrien      errs = 1;
51738494Sobrien    }
51838494Sobrien  }
51938494Sobrien
52038494Sobrien  /*
52138494Sobrien   * Flush map cache
52238494Sobrien   */
52338494Sobrien  if (flush_flag) {
52438494Sobrien    int *rc;
52538494Sobrien    amq_setopt opt;
52638494Sobrien    opt.as_opt = AMOPT_FLUSHMAPC;
52738494Sobrien    opt.as_str = "";
52838494Sobrien    rc = amqproc_setopt_1(&opt, clnt);
52938494Sobrien    if (!rc || *rc) {
53042633Sobrien      fprintf(stderr, "%s: amd on %s cannot flush the map cache\n",
53142633Sobrien	      am_get_progname(), server);
53238494Sobrien      errs = 1;
53338494Sobrien    }
53438494Sobrien  }
53538494Sobrien
53638494Sobrien  /*
53782801Sobrien   * getpwd info
53882801Sobrien   */
53982801Sobrien  if (getpwd_flag) {
54082801Sobrien    char path[MAXPATHLEN+1];
54182801Sobrien    char *wd = getcwd(path, MAXPATHLEN+1);
54282801Sobrien    amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt);
54382801Sobrien    amq_mount_tree_p mt;
544174313Sobrien    u_int i;
545174313Sobrien    int flag;
54682801Sobrien
54782801Sobrien    if (!wd) {
54882801Sobrien      perror("getcwd");
54982801Sobrien      exit(1);
55082801Sobrien    }
55182801Sobrien    for (i = 0; mlp && i < mlp->amq_mount_tree_list_len; i++) {
55282801Sobrien      mt = mlp->amq_mount_tree_list_val[i];
55382801Sobrien      while (1) {
55482801Sobrien	flag = 0;
555174313Sobrien	show_pwd(mt, path, sizeof(path), &flag);
55682801Sobrien	if (!flag) {
55782801Sobrien	  printf("%s\n", path);
55882801Sobrien	  break;
55982801Sobrien	}
56082801Sobrien      }
56182801Sobrien    }
56282801Sobrien    exit(0);
56382801Sobrien  }
56482801Sobrien
56582801Sobrien  /*
56638494Sobrien   * Mount info
56738494Sobrien   */
56838494Sobrien  if (minfo_flag) {
56938494Sobrien    int dummy;
57038494Sobrien    amq_mount_info_list *ml = amqproc_getmntfs_1(&dummy, clnt);
57138494Sobrien    if (ml) {
57238494Sobrien      int mwid = 0, dwid = 0, twid = 0;
57338494Sobrien      show_mi(ml, Calc, &mwid, &dwid, &twid);
57438494Sobrien      mwid++;
57538494Sobrien      dwid++;
57638494Sobrien      twid++;
57738494Sobrien      show_mi(ml, Full, &mwid, &dwid, &twid);
57838494Sobrien
57938494Sobrien    } else {
58042633Sobrien      fprintf(stderr, "%s: amd on %s cannot provide mount info\n",
58142633Sobrien	      am_get_progname(), server);
58238494Sobrien    }
58338494Sobrien  }
58438494Sobrien
58538494Sobrien  /*
58638494Sobrien   * Get Version
58738494Sobrien   */
58838494Sobrien  if (getvers_flag) {
58938494Sobrien    amq_string *spp = amqproc_getvers_1((voidp) 0, clnt);
59038494Sobrien    if (spp && *spp) {
59138494Sobrien      fputs(*spp, stdout);
59238494Sobrien      XFREE(*spp);
59338494Sobrien    } else {
59442633Sobrien      fprintf(stderr, "%s: failed to get version information\n",
59542633Sobrien	      am_get_progname());
59638494Sobrien      errs = 1;
59738494Sobrien    }
59838494Sobrien  }
59938494Sobrien
60038494Sobrien  /*
60138494Sobrien   * Get PID of amd
60238494Sobrien   */
60338494Sobrien  if (getpid_flag) {
60438494Sobrien    int *ip = amqproc_getpid_1((voidp) 0, clnt);
60538494Sobrien    if (ip && *ip) {
60638494Sobrien      printf("%d\n", *ip);
60738494Sobrien    } else {
60842633Sobrien      fprintf(stderr, "%s: failed to get PID of amd\n", am_get_progname());
60938494Sobrien      errs = 1;
61038494Sobrien    }
61138494Sobrien  }
61238494Sobrien
61338494Sobrien  /*
61438494Sobrien   * Apply required operation to all remaining arguments
61538494Sobrien   */
61638494Sobrien  if (optind < argc) {
61738494Sobrien    do {
61838494Sobrien      char *fs = argv[optind++];
61938494Sobrien      if (unmount_flag) {
62038494Sobrien	/*
62138494Sobrien	 * Unmount request
62238494Sobrien	 */
62338494Sobrien	amqproc_umnt_1(&fs, clnt);
62438494Sobrien      } else {
62538494Sobrien	/*
62638494Sobrien	 * Stats request
62738494Sobrien	 */
62838494Sobrien	amq_mount_tree_p *mtp = amqproc_mnttree_1(&fs, clnt);
62938494Sobrien	if (mtp) {
63038494Sobrien	  amq_mount_tree *mt = *mtp;
63138494Sobrien	  if (mt) {
63238494Sobrien	    int mwid = 0, dwid = 0, twid = 0;
63338494Sobrien	    show_mt(mt, Calc, &mwid, &dwid, &twid);
63438494Sobrien	    mwid++;
63538494Sobrien	    dwid++, twid++;
63638494Sobrien	    printf("%-*.*s Uid   Getattr Lookup RdDir   RdLnk   Statfs Mounted@\n",
63738494Sobrien		   dwid, dwid, "What");
63838494Sobrien	    show_mt(mt, Stats, &mwid, &dwid, &twid);
63938494Sobrien	  } else {
64042633Sobrien	    fprintf(stderr, "%s: %s not automounted\n", am_get_progname(), fs);
64138494Sobrien	  }
64238494Sobrien	  xdr_pri_free((XDRPROC_T_TYPE) xdr_amq_mount_tree_p, (caddr_t) mtp);
64338494Sobrien	} else {
64442633Sobrien	  fprintf(stderr, "%s: ", am_get_progname());
64538494Sobrien	  clnt_perror(clnt, server);
64638494Sobrien	  errs = 1;
64738494Sobrien	}
64838494Sobrien      }
64938494Sobrien    } while (optind < argc);
65038494Sobrien
65138494Sobrien  } else if (unmount_flag) {
65238494Sobrien    goto show_usage;
65338494Sobrien
65438494Sobrien  } else if (stats_flag) {
65538494Sobrien    amq_mount_stats *ms = amqproc_stats_1((voidp) 0, clnt);
65638494Sobrien    if (ms) {
65738494Sobrien      show_ms(ms);
65838494Sobrien    } else {
65942633Sobrien      fprintf(stderr, "%s: ", am_get_progname());
66038494Sobrien      clnt_perror(clnt, server);
66138494Sobrien      errs = 1;
66238494Sobrien    }
66338494Sobrien
66438494Sobrien  } else if (!nodefault) {
66538494Sobrien    amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt);
66638494Sobrien    if (mlp) {
66738494Sobrien      enum show_opt e = Calc;
66838494Sobrien      int mwid = 0, dwid = 0, pwid = 0;
669174313Sobrien
67038494Sobrien      while (e != ShowDone) {
671174313Sobrien	u_int i;
67238494Sobrien	for (i = 0; i < mlp->amq_mount_tree_list_len; i++) {
67338494Sobrien	  show_mt(mlp->amq_mount_tree_list_val[i],
67438494Sobrien		  e, &mwid, &dwid, &pwid);
67538494Sobrien	}
67638494Sobrien	mwid++;
67738494Sobrien	dwid++, pwid++;
67838494Sobrien	if (e == Calc)
67938494Sobrien	  e = Short;
68038494Sobrien	else if (e == Short)
68138494Sobrien	  e = ShowDone;
68238494Sobrien      }
68338494Sobrien
68438494Sobrien    } else {
68542633Sobrien      fprintf(stderr, "%s: ", am_get_progname());
68638494Sobrien      clnt_perror(clnt, server);
68738494Sobrien      errs = 1;
68838494Sobrien    }
68938494Sobrien  }
69038494Sobrien  exit(errs);
69142633Sobrien  return errs; /* should never reach here */
69238494Sobrien}
693