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