1df930be7Sderaadt /* 2df930be7Sderaadt * Copyright (c) 1990 Jan-Simon Pendry 3df930be7Sderaadt * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 4df930be7Sderaadt * Copyright (c) 1990, 1993 5df930be7Sderaadt * The Regents of the University of California. All rights reserved. 6df930be7Sderaadt * 7df930be7Sderaadt * This code is derived from software contributed to Berkeley by 8df930be7Sderaadt * Jan-Simon Pendry at Imperial College, London. 9df930be7Sderaadt * 10df930be7Sderaadt * Redistribution and use in source and binary forms, with or without 11df930be7Sderaadt * modification, are permitted provided that the following conditions 12df930be7Sderaadt * are met: 13df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright 14df930be7Sderaadt * notice, this list of conditions and the following disclaimer. 15df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright 16df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the 17df930be7Sderaadt * documentation and/or other materials provided with the distribution. 18*29295d1cSmillert * 3. Neither the name of the University nor the names of its contributors 19df930be7Sderaadt * may be used to endorse or promote products derived from this software 20df930be7Sderaadt * without specific prior written permission. 21df930be7Sderaadt * 22df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32df930be7Sderaadt * SUCH DAMAGE. 33df930be7Sderaadt * 34df930be7Sderaadt * from: @(#)amq.c 8.1 (Berkeley) 6/7/93 35*29295d1cSmillert * $Id: amq.c,v 1.11 2003/06/02 23:36:51 millert Exp $ 36df930be7Sderaadt */ 37df930be7Sderaadt 38df930be7Sderaadt /* 39df930be7Sderaadt * Automounter query tool 40df930be7Sderaadt */ 41df930be7Sderaadt 42df930be7Sderaadt #ifndef lint 43df930be7Sderaadt char copyright[] = "\ 44df930be7Sderaadt @(#)Copyright (c) 1990 Jan-Simon Pendry\n\ 45df930be7Sderaadt @(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\ 46df930be7Sderaadt @(#)Copyright (c) 1990, 1993\n\ 47df930be7Sderaadt The Regents of the University of California. All rights reserved.\n"; 48df930be7Sderaadt #endif /* not lint */ 49df930be7Sderaadt 50df930be7Sderaadt #ifndef lint 51*29295d1cSmillert static char rcsid[] = "$Id: amq.c,v 1.11 2003/06/02 23:36:51 millert Exp $"; 52df930be7Sderaadt static char sccsid[] = "@(#)amq.c 8.1 (Berkeley) 6/7/93"; 53df930be7Sderaadt #endif /* not lint */ 54df930be7Sderaadt 55df930be7Sderaadt #include "am.h" 56df930be7Sderaadt #include "amq.h" 57df930be7Sderaadt #include <stdio.h> 58df930be7Sderaadt #include <fcntl.h> 59df930be7Sderaadt #include <netdb.h> 609ad2d6d5Spvalchev #include <unistd.h> 61df930be7Sderaadt 62072e3d80Sderaadt static int privsock(int); 63df930be7Sderaadt 64df930be7Sderaadt static int flush_flag; 65df930be7Sderaadt static int minfo_flag; 66df930be7Sderaadt static int unmount_flag; 67df930be7Sderaadt static int stats_flag; 68df930be7Sderaadt static int getvers_flag; 69df930be7Sderaadt static char *debug_opts; 70df930be7Sderaadt static char *logfile; 71df930be7Sderaadt static char *mount_map; 72df930be7Sderaadt static char *xlog_optstr; 73df930be7Sderaadt static char localhost[] = "localhost"; 74df930be7Sderaadt static char *def_server = localhost; 75df930be7Sderaadt 76df930be7Sderaadt extern int optind; 77df930be7Sderaadt extern char *optarg; 78df930be7Sderaadt 79df930be7Sderaadt static struct timeval tmo = { 10, 0 }; 80df930be7Sderaadt #define TIMEOUT tmo 81df930be7Sderaadt 82df930be7Sderaadt enum show_opt { Full, Stats, Calc, Short, ShowDone }; 83df930be7Sderaadt 84df930be7Sderaadt /* 85df930be7Sderaadt * If (e) is Calc then just calculate the sizes 86df930be7Sderaadt * Otherwise display the mount node on stdout 87df930be7Sderaadt */ 889ad2d6d5Spvalchev static void 899ad2d6d5Spvalchev show_mti(amq_mount_tree *mt, enum show_opt e, int *mwid, int *dwid, 909ad2d6d5Spvalchev int *twid) 91df930be7Sderaadt { 92df930be7Sderaadt switch (e) { 93df930be7Sderaadt case Calc: { 94df930be7Sderaadt int mw = strlen(mt->mt_mountinfo); 95df930be7Sderaadt int dw = strlen(mt->mt_directory); 96df930be7Sderaadt int tw = strlen(mt->mt_type); 97072e3d80Sderaadt 98072e3d80Sderaadt if (mw > *mwid) 99072e3d80Sderaadt *mwid = mw; 100072e3d80Sderaadt if (dw > *dwid) 101072e3d80Sderaadt *dwid = dw; 102072e3d80Sderaadt if (tw > *twid) 103072e3d80Sderaadt *twid = tw; 104072e3d80Sderaadt break; 105072e3d80Sderaadt } 106df930be7Sderaadt 107df930be7Sderaadt case Full: { 108df930be7Sderaadt struct tm *tp = localtime((time_t *) &mt->mt_mounttime); 109df930be7Sderaadt 110072e3d80Sderaadt printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d" 111072e3d80Sderaadt " %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n", 112072e3d80Sderaadt *dwid, *dwid, *mt->mt_directory ? mt->mt_directory : "/", 113072e3d80Sderaadt *twid, *twid, mt->mt_type, *mwid, *mwid, 114072e3d80Sderaadt mt->mt_mountinfo, mt->mt_mountpoint, mt->mt_mountuid, 115072e3d80Sderaadt mt->mt_getattr, mt->mt_lookup, mt->mt_readdir, 116072e3d80Sderaadt mt->mt_readlink, mt->mt_statfs, 117df930be7Sderaadt tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year, 118df930be7Sderaadt tp->tm_mon+1, tp->tm_mday, 119df930be7Sderaadt tp->tm_hour, tp->tm_min, tp->tm_sec); 120072e3d80Sderaadt break; 121072e3d80Sderaadt } 122df930be7Sderaadt 123df930be7Sderaadt case Stats: { 124df930be7Sderaadt struct tm *tp = localtime((time_t *) &mt->mt_mounttime); 125df930be7Sderaadt 126072e3d80Sderaadt printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d" 127072e3d80Sderaadt " %02d/%02d/%02d %02d:%02d:%02d\n", 128072e3d80Sderaadt *dwid, *dwid, *mt->mt_directory ? mt->mt_directory : "/", 129072e3d80Sderaadt mt->mt_mountuid, mt->mt_getattr, mt->mt_lookup, 130072e3d80Sderaadt mt->mt_readdir, mt->mt_readlink, mt->mt_statfs, 131df930be7Sderaadt tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year, 132df930be7Sderaadt tp->tm_mon+1, tp->tm_mday, 133df930be7Sderaadt tp->tm_hour, tp->tm_min, tp->tm_sec); 134072e3d80Sderaadt break; 135072e3d80Sderaadt } 136df930be7Sderaadt 137df930be7Sderaadt case Short: { 138df930be7Sderaadt printf("%-*.*s %-*.*s %-*.*s %s\n", 139072e3d80Sderaadt *dwid, *dwid, *mt->mt_directory ? mt->mt_directory : "/", 140072e3d80Sderaadt *twid, *twid, mt->mt_type, *mwid, *mwid, 141072e3d80Sderaadt mt->mt_mountinfo, mt->mt_mountpoint); 142072e3d80Sderaadt break; 143072e3d80Sderaadt } 144df930be7Sderaadt } 145df930be7Sderaadt } 146df930be7Sderaadt 147df930be7Sderaadt /* 148df930be7Sderaadt * Display a mount tree. 149df930be7Sderaadt */ 1509ad2d6d5Spvalchev static void 1519ad2d6d5Spvalchev show_mt(amq_mount_tree *mt, enum show_opt e, int *mwid, int *dwid, 1529ad2d6d5Spvalchev int *pwid) 153df930be7Sderaadt { 154df930be7Sderaadt while (mt) { 155df930be7Sderaadt show_mti(mt, e, mwid, dwid, pwid); 156df930be7Sderaadt show_mt(mt->mt_next, e, mwid, dwid, pwid); 157df930be7Sderaadt mt = mt->mt_child; 158df930be7Sderaadt } 159df930be7Sderaadt } 160df930be7Sderaadt 1619ad2d6d5Spvalchev static void 1629ad2d6d5Spvalchev show_mi(amq_mount_info_list *ml, enum show_opt e, int *mwid, 1639ad2d6d5Spvalchev int *dwid, int *twid) 164df930be7Sderaadt { 165df930be7Sderaadt int i; 1669ad2d6d5Spvalchev 167df930be7Sderaadt switch (e) { 168df930be7Sderaadt case Calc: { 169df930be7Sderaadt for (i = 0; i < ml->amq_mount_info_list_len; i++) { 170df930be7Sderaadt amq_mount_info *mi = &ml->amq_mount_info_list_val[i]; 171df930be7Sderaadt int mw = strlen(mi->mi_mountinfo); 172df930be7Sderaadt int dw = strlen(mi->mi_mountpt); 173df930be7Sderaadt int tw = strlen(mi->mi_type); 174072e3d80Sderaadt 175072e3d80Sderaadt if (mw > *mwid) 176072e3d80Sderaadt *mwid = mw; 177072e3d80Sderaadt if (dw > *dwid) 178072e3d80Sderaadt *dwid = dw; 179072e3d80Sderaadt if (tw > *twid) 180072e3d80Sderaadt *twid = tw; 181df930be7Sderaadt } 182072e3d80Sderaadt break; 183072e3d80Sderaadt } 184df930be7Sderaadt 185df930be7Sderaadt case Full: { 186df930be7Sderaadt for (i = 0; i < ml->amq_mount_info_list_len; i++) { 187df930be7Sderaadt amq_mount_info *mi = &ml->amq_mount_info_list_val[i]; 188df930be7Sderaadt printf("%-*.*s %-*.*s %-*.*s %-3d %s is %s", 189df930be7Sderaadt *mwid, *mwid, mi->mi_mountinfo, 190df930be7Sderaadt *dwid, *dwid, mi->mi_mountpt, 191df930be7Sderaadt *twid, *twid, mi->mi_type, 192df930be7Sderaadt mi->mi_refc, mi->mi_fserver, 193df930be7Sderaadt mi->mi_up > 0 ? "up" : 194df930be7Sderaadt mi->mi_up < 0 ? "starting" : "down"); 195df930be7Sderaadt if (mi->mi_error > 0) { 196df930be7Sderaadt #ifdef HAS_STRERROR 197df930be7Sderaadt printf(" (%s)", strerror(mi->mi_error)); 198df930be7Sderaadt #else 199df930be7Sderaadt extern char *sys_errlist[]; 200df930be7Sderaadt extern int sys_nerr; 201072e3d80Sderaadt 202df930be7Sderaadt if (mi->mi_error < sys_nerr) 203df930be7Sderaadt printf(" (%s)", sys_errlist[mi->mi_error]); 204df930be7Sderaadt else 205df930be7Sderaadt printf(" (Error %d)", mi->mi_error); 206df930be7Sderaadt #endif 207df930be7Sderaadt } else if (mi->mi_error < 0) { 208df930be7Sderaadt fputs(" (in progress)", stdout); 209df930be7Sderaadt } 210df930be7Sderaadt fputc('\n', stdout); 211df930be7Sderaadt } 212072e3d80Sderaadt break; 213072e3d80Sderaadt } 214df930be7Sderaadt } 215df930be7Sderaadt } 216df930be7Sderaadt 217df930be7Sderaadt /* 218df930be7Sderaadt * Display general mount statistics 219df930be7Sderaadt */ 2209ad2d6d5Spvalchev static void 2219ad2d6d5Spvalchev show_ms(amq_mount_stats *ms) 222df930be7Sderaadt { 223072e3d80Sderaadt printf("requests stale mount mount unmount\n" 224072e3d80Sderaadt "deferred fhandles ok failed failed\n" 225072e3d80Sderaadt "%-9d %-9d %-9d %-9d %-9d\n", 226df930be7Sderaadt ms->as_drops, ms->as_stale, ms->as_mok, ms->as_merr, ms->as_uerr); 227df930be7Sderaadt } 228df930be7Sderaadt 229df930be7Sderaadt static bool_t 230587ddfa4Sderaadt xdr_pri_free(xdrproc_t xdr_args, void *args_ptr) 231df930be7Sderaadt { 232df930be7Sderaadt XDR xdr; 233072e3d80Sderaadt 234df930be7Sderaadt xdr.x_op = XDR_FREE; 235df930be7Sderaadt return ((*xdr_args)(&xdr, args_ptr)); 236df930be7Sderaadt } 237df930be7Sderaadt 238df930be7Sderaadt /* 239df930be7Sderaadt * MAIN 240df930be7Sderaadt */ 2419ad2d6d5Spvalchev int 2429ad2d6d5Spvalchev main(int argc, char *argv[]) 243df930be7Sderaadt { 244072e3d80Sderaadt int nodefault = 0, opt_ch, errs = 0, s; 245df930be7Sderaadt struct sockaddr_in server_addr; 246df930be7Sderaadt struct hostent *hp; 247072e3d80Sderaadt CLIENT *clnt; 248072e3d80Sderaadt char *server; 249df930be7Sderaadt 250df930be7Sderaadt /* 251df930be7Sderaadt * Parse arguments 252df930be7Sderaadt */ 25372799b18Smillert while ((opt_ch = getopt(argc, argv, "fh:l:msuvx:D:M:")) != -1) 254df930be7Sderaadt switch (opt_ch) { 255df930be7Sderaadt case 'f': 256df930be7Sderaadt flush_flag = 1; 257df930be7Sderaadt nodefault = 1; 258df930be7Sderaadt break; 259df930be7Sderaadt 260df930be7Sderaadt case 'h': 261df930be7Sderaadt def_server = optarg; 262df930be7Sderaadt break; 263df930be7Sderaadt 264df930be7Sderaadt case 'l': 265df930be7Sderaadt logfile = optarg; 266df930be7Sderaadt nodefault = 1; 267df930be7Sderaadt break; 268df930be7Sderaadt 269df930be7Sderaadt case 'm': 270df930be7Sderaadt minfo_flag = 1; 271df930be7Sderaadt nodefault = 1; 272df930be7Sderaadt break; 273df930be7Sderaadt 274df930be7Sderaadt case 's': 275df930be7Sderaadt stats_flag = 1; 276df930be7Sderaadt nodefault = 1; 277df930be7Sderaadt break; 278df930be7Sderaadt 279df930be7Sderaadt case 'u': 280df930be7Sderaadt unmount_flag = 1; 281df930be7Sderaadt nodefault = 1; 282df930be7Sderaadt break; 283df930be7Sderaadt 284df930be7Sderaadt case 'v': 285df930be7Sderaadt getvers_flag = 1; 286df930be7Sderaadt nodefault = 1; 287df930be7Sderaadt break; 288df930be7Sderaadt 289df930be7Sderaadt case 'x': 290df930be7Sderaadt xlog_optstr = optarg; 291df930be7Sderaadt nodefault = 1; 292df930be7Sderaadt break; 293df930be7Sderaadt 294df930be7Sderaadt case 'D': 295df930be7Sderaadt debug_opts = optarg; 296df930be7Sderaadt nodefault = 1; 297df930be7Sderaadt break; 298df930be7Sderaadt 299df930be7Sderaadt case 'M': 300df930be7Sderaadt mount_map = optarg; 301df930be7Sderaadt nodefault = 1; 302df930be7Sderaadt break; 303df930be7Sderaadt 304df930be7Sderaadt default: 305df930be7Sderaadt errs = 1; 306df930be7Sderaadt break; 307df930be7Sderaadt } 308df930be7Sderaadt 309df930be7Sderaadt if (optind == argc) { 310df930be7Sderaadt if (unmount_flag) 311df930be7Sderaadt errs = 1; 312df930be7Sderaadt } 313df930be7Sderaadt 314df930be7Sderaadt if (errs) { 315df930be7Sderaadt show_usage: 316072e3d80Sderaadt fprintf(stderr, "usage: %s [-h host] [[-f] [-m] [-v] [-s]]" 317072e3d80Sderaadt " | [[-u] directory ...]] |\n" 318072e3d80Sderaadt "\t[-l logfile|\"syslog\"] [-x log_flags] " 319072e3d80Sderaadt "[-D dbg_opts] [-M mapent]\n", __progname); 320df930be7Sderaadt exit(1); 321df930be7Sderaadt } 322df930be7Sderaadt 323df930be7Sderaadt server = def_server; 324df930be7Sderaadt 325df930be7Sderaadt /* 326df930be7Sderaadt * Get address of server 327df930be7Sderaadt */ 328df930be7Sderaadt if ((hp = gethostbyname(server)) == 0 && strcmp(server, localhost) != 0) { 3299ad2d6d5Spvalchev fprintf(stderr, "%s: Can't get address of %s\n", __progname, server); 330df930be7Sderaadt exit(1); 331df930be7Sderaadt } 332df930be7Sderaadt bzero(&server_addr, sizeof server_addr); 333df930be7Sderaadt server_addr.sin_family = AF_INET; 334df930be7Sderaadt if (hp) { 3355c8362e1Spvalchev bcopy((void *)hp->h_addr, (void *)&server_addr.sin_addr, 336df930be7Sderaadt sizeof(server_addr.sin_addr)); 337df930be7Sderaadt } else { 338df930be7Sderaadt /* fake "localhost" */ 339df930be7Sderaadt server_addr.sin_addr.s_addr = htonl(0x7f000001); 340df930be7Sderaadt } 341df930be7Sderaadt 342df930be7Sderaadt /* 343df930be7Sderaadt * Create RPC endpoint 344df930be7Sderaadt */ 345df930be7Sderaadt s = privsock(SOCK_STREAM); 346df930be7Sderaadt clnt = clnttcp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, &s, 0, 0); 347df930be7Sderaadt if (clnt == 0) { 348df930be7Sderaadt close(s); 349df930be7Sderaadt s = privsock(SOCK_DGRAM); 350072e3d80Sderaadt clnt = clntudp_create(&server_addr, AMQ_PROGRAM, 351072e3d80Sderaadt AMQ_VERSION, TIMEOUT, &s); 352df930be7Sderaadt } 353df930be7Sderaadt if (clnt == 0) { 3549ad2d6d5Spvalchev fprintf(stderr, "%s: ", __progname); 355df930be7Sderaadt clnt_pcreateerror(server); 356df930be7Sderaadt exit(1); 357df930be7Sderaadt } 358df930be7Sderaadt 359df930be7Sderaadt /* 360df930be7Sderaadt * Control debugging 361df930be7Sderaadt */ 362df930be7Sderaadt if (debug_opts) { 363df930be7Sderaadt int *rc; 364df930be7Sderaadt amq_setopt opt; 365df930be7Sderaadt opt.as_opt = AMOPT_DEBUG; 366df930be7Sderaadt opt.as_str = debug_opts; 367df930be7Sderaadt rc = amqproc_setopt_1(&opt, clnt); 368df930be7Sderaadt if (rc && *rc < 0) { 369072e3d80Sderaadt fprintf(stderr, 370072e3d80Sderaadt "%s: daemon not compiled for debug", __progname); 371df930be7Sderaadt errs = 1; 372df930be7Sderaadt } else if (!rc || *rc > 0) { 373072e3d80Sderaadt fprintf(stderr, 374072e3d80Sderaadt "%s: debug setting for \"%s\" failed\n", 375072e3d80Sderaadt __progname, debug_opts); 376df930be7Sderaadt errs = 1; 377df930be7Sderaadt } 378df930be7Sderaadt } 379df930be7Sderaadt 380df930be7Sderaadt /* 381df930be7Sderaadt * Control logging 382df930be7Sderaadt */ 383df930be7Sderaadt if (xlog_optstr) { 384df930be7Sderaadt int *rc; 385df930be7Sderaadt amq_setopt opt; 386df930be7Sderaadt opt.as_opt = AMOPT_XLOG; 387df930be7Sderaadt opt.as_str = xlog_optstr; 388df930be7Sderaadt rc = amqproc_setopt_1(&opt, clnt); 389df930be7Sderaadt if (!rc || *rc) { 390072e3d80Sderaadt fprintf(stderr, "%s: setting log level to \"%s\" failed\n", 391072e3d80Sderaadt __progname, xlog_optstr); 392df930be7Sderaadt errs = 1; 393df930be7Sderaadt } 394df930be7Sderaadt } 395df930be7Sderaadt 396df930be7Sderaadt /* 397df930be7Sderaadt * Control log file 398df930be7Sderaadt */ 399df930be7Sderaadt if (logfile) { 400df930be7Sderaadt int *rc; 401df930be7Sderaadt amq_setopt opt; 402df930be7Sderaadt opt.as_opt = AMOPT_LOGFILE; 403df930be7Sderaadt opt.as_str = logfile; 404df930be7Sderaadt rc = amqproc_setopt_1(&opt, clnt); 405df930be7Sderaadt if (!rc || *rc) { 406072e3d80Sderaadt fprintf(stderr, "%s: setting logfile to \"%s\" failed\n", 407072e3d80Sderaadt __progname, logfile); 408df930be7Sderaadt errs = 1; 409df930be7Sderaadt } 410df930be7Sderaadt } 411df930be7Sderaadt 412df930be7Sderaadt /* 413df930be7Sderaadt * Flush map cache 414df930be7Sderaadt */ 415df930be7Sderaadt if (flush_flag) { 416df930be7Sderaadt int *rc; 417df930be7Sderaadt amq_setopt opt; 418df930be7Sderaadt opt.as_opt = AMOPT_FLUSHMAPC; 419df930be7Sderaadt opt.as_str = ""; 420df930be7Sderaadt rc = amqproc_setopt_1(&opt, clnt); 421df930be7Sderaadt if (!rc || *rc) { 422072e3d80Sderaadt fprintf(stderr, 423072e3d80Sderaadt "%s: amd on %s cannot flush the map cache\n", 424072e3d80Sderaadt __progname, server); 425df930be7Sderaadt errs = 1; 426df930be7Sderaadt } 427df930be7Sderaadt } 428df930be7Sderaadt 429df930be7Sderaadt /* 430df930be7Sderaadt * Mount info 431df930be7Sderaadt */ 432df930be7Sderaadt if (minfo_flag) { 433df930be7Sderaadt int dummy; 434df930be7Sderaadt amq_mount_info_list *ml = amqproc_getmntfs_1(&dummy, clnt); 435df930be7Sderaadt if (ml) { 436df930be7Sderaadt int mwid = 0, dwid = 0, twid = 0; 437df930be7Sderaadt show_mi(ml, Calc, &mwid, &dwid, &twid); 438df930be7Sderaadt mwid++; dwid++; twid++; 439df930be7Sderaadt show_mi(ml, Full, &mwid, &dwid, &twid); 440df930be7Sderaadt } else { 441072e3d80Sderaadt fprintf(stderr, "%s: amd on %s cannot provide mount info\n", 442072e3d80Sderaadt __progname, server); 443df930be7Sderaadt } 444df930be7Sderaadt } 445df930be7Sderaadt 446df930be7Sderaadt /* 447df930be7Sderaadt * Mount map 448df930be7Sderaadt */ 449df930be7Sderaadt if (mount_map) { 450df930be7Sderaadt int *rc; 451df930be7Sderaadt do { 452df930be7Sderaadt rc = amqproc_mount_1(&mount_map, clnt); 453df930be7Sderaadt } while (rc && *rc < 0); 454df930be7Sderaadt if (!rc || *rc > 0) { 455df930be7Sderaadt if (rc) 456df930be7Sderaadt errno = *rc; 457df930be7Sderaadt else 458df930be7Sderaadt errno = ETIMEDOUT; 4599ad2d6d5Spvalchev fprintf(stderr, "%s: could not start new ", __progname); 460df930be7Sderaadt perror("autmount point"); 461df930be7Sderaadt } 462df930be7Sderaadt } 463df930be7Sderaadt 464df930be7Sderaadt /* 465df930be7Sderaadt * Get Version 466df930be7Sderaadt */ 467df930be7Sderaadt if (getvers_flag) { 4685c8362e1Spvalchev amq_string *spp = amqproc_getvers_1((void *)0, clnt); 469df930be7Sderaadt if (spp && *spp) { 470df930be7Sderaadt printf("%s.\n", *spp); 471df930be7Sderaadt free(*spp); 472df930be7Sderaadt } else { 473072e3d80Sderaadt fprintf(stderr, "%s: failed to get version information\n", 474072e3d80Sderaadt __progname); 475df930be7Sderaadt errs = 1; 476df930be7Sderaadt } 477df930be7Sderaadt } 478df930be7Sderaadt 479df930be7Sderaadt /* 480df930be7Sderaadt * Apply required operation to all remaining arguments 481df930be7Sderaadt */ 482df930be7Sderaadt if (optind < argc) { 483df930be7Sderaadt do { 484df930be7Sderaadt char *fs = argv[optind++]; 485df930be7Sderaadt if (unmount_flag) { 486df930be7Sderaadt /* 487df930be7Sderaadt * Unmount request 488df930be7Sderaadt */ 489df930be7Sderaadt amqproc_umnt_1(&fs, clnt); 490df930be7Sderaadt } else { 491df930be7Sderaadt /* 492df930be7Sderaadt * Stats request 493df930be7Sderaadt */ 494df930be7Sderaadt amq_mount_tree_p *mtp = amqproc_mnttree_1(&fs, clnt); 495df930be7Sderaadt if (mtp) { 496df930be7Sderaadt amq_mount_tree *mt = *mtp; 497df930be7Sderaadt if (mt) { 498df930be7Sderaadt int mwid = 0, dwid = 0, twid = 0; 499072e3d80Sderaadt 500df930be7Sderaadt show_mt(mt, Calc, &mwid, &dwid, &twid); 501072e3d80Sderaadt mwid++; 502072e3d80Sderaadt dwid++; 503072e3d80Sderaadt twid++; 504072e3d80Sderaadt 505072e3d80Sderaadt printf("%-*.*s Uid Getattr " 506072e3d80Sderaadt "Lookup RdDir RdLnk " 507072e3d80Sderaadt "Statfs Mounted@\n", 508df930be7Sderaadt dwid, dwid, "What"); 509df930be7Sderaadt show_mt(mt, Stats, &mwid, &dwid, &twid); 510df930be7Sderaadt } else { 511072e3d80Sderaadt fprintf(stderr, 512072e3d80Sderaadt "%s: %s not automounted\n", 513072e3d80Sderaadt __progname, fs); 514df930be7Sderaadt } 515587ddfa4Sderaadt xdr_pri_free(xdr_amq_mount_tree_p, mtp); 516df930be7Sderaadt } else { 5179ad2d6d5Spvalchev fprintf(stderr, "%s: ", __progname); 518df930be7Sderaadt clnt_perror(clnt, server); 519df930be7Sderaadt errs = 1; 520df930be7Sderaadt } 521df930be7Sderaadt } 522df930be7Sderaadt } while (optind < argc); 523df930be7Sderaadt } else if (unmount_flag) { 524df930be7Sderaadt goto show_usage; 525df930be7Sderaadt } else if (stats_flag) { 5265c8362e1Spvalchev amq_mount_stats *ms = amqproc_stats_1((void *)0, clnt); 527df930be7Sderaadt if (ms) { 528df930be7Sderaadt show_ms(ms); 529df930be7Sderaadt } else { 5309ad2d6d5Spvalchev fprintf(stderr, "%s: ", __progname); 531df930be7Sderaadt clnt_perror(clnt, server); 532df930be7Sderaadt errs = 1; 533df930be7Sderaadt } 534df930be7Sderaadt } else if (!nodefault) { 5355c8362e1Spvalchev amq_mount_tree_list *mlp = amqproc_export_1((void *)0, clnt); 536df930be7Sderaadt if (mlp) { 537df930be7Sderaadt enum show_opt e = Calc; 538df930be7Sderaadt int mwid = 0, dwid = 0, pwid = 0; 539045fe502Sderaadt 540df930be7Sderaadt while (e != ShowDone) { 541df930be7Sderaadt int i; 542045fe502Sderaadt 543df930be7Sderaadt for (i = 0; i < mlp->amq_mount_tree_list_len; i++) { 544df930be7Sderaadt show_mt(mlp->amq_mount_tree_list_val[i], 545df930be7Sderaadt e, &mwid, &dwid, &pwid); 546df930be7Sderaadt } 547045fe502Sderaadt mwid++; 548045fe502Sderaadt dwid++; 549045fe502Sderaadt pwid++; 550045fe502Sderaadt if (e == Calc) 551045fe502Sderaadt e = Short; 552045fe502Sderaadt else if (e == Short) 553045fe502Sderaadt e = ShowDone; 554df930be7Sderaadt } 555df930be7Sderaadt } else { 5569ad2d6d5Spvalchev fprintf(stderr, "%s: ", __progname); 557df930be7Sderaadt clnt_perror(clnt, server); 558df930be7Sderaadt errs = 1; 559df930be7Sderaadt } 560df930be7Sderaadt } 561df930be7Sderaadt 562df930be7Sderaadt exit(errs); 563df930be7Sderaadt } 564df930be7Sderaadt 565df930be7Sderaadt /* 566df930be7Sderaadt * udpresport creates a datagram socket and attempts to bind it to a 567df930be7Sderaadt * secure port. 568df930be7Sderaadt * returns: The bound socket, or -1 to indicate an error. 569df930be7Sderaadt */ 570072e3d80Sderaadt static int 571072e3d80Sderaadt inetresport(int ty) 572df930be7Sderaadt { 573db4d2d4dSderaadt struct sockaddr_in addr; 574072e3d80Sderaadt int alport, sock; 575df930be7Sderaadt 576db4d2d4dSderaadt /* Use internet address family */ 577db4d2d4dSderaadt addr.sin_family = AF_INET; 578db4d2d4dSderaadt addr.sin_addr.s_addr = INADDR_ANY; 579db4d2d4dSderaadt if ((sock = socket(AF_INET, ty, 0)) < 0) 580db4d2d4dSderaadt return -1; 581db4d2d4dSderaadt for (alport = IPPORT_RESERVED-1; alport > IPPORT_RESERVED/2 + 1; alport--) { 582db4d2d4dSderaadt addr.sin_port = htons((u_short)alport); 583db4d2d4dSderaadt if (bind(sock, (struct sockaddr *)&addr, sizeof (addr)) >= 0) 584db4d2d4dSderaadt return sock; 585db4d2d4dSderaadt if (errno != EADDRINUSE) { 586db4d2d4dSderaadt close(sock); 587df930be7Sderaadt return -1; 588df930be7Sderaadt } 589db4d2d4dSderaadt } 590db4d2d4dSderaadt close(sock); 591db4d2d4dSderaadt errno = EAGAIN; 592db4d2d4dSderaadt return -1; 59354c16646Sderaadt } 594df930be7Sderaadt 595df930be7Sderaadt /* 596df930be7Sderaadt * Privsock() calls inetresport() to attempt to bind a socket to a secure 597df930be7Sderaadt * port. If inetresport() fails, privsock returns a magic socket number which 598df930be7Sderaadt * indicates to RPC that it should make its own socket. 599df930be7Sderaadt * returns: A privileged socket # or RPC_ANYSOCK. 600df930be7Sderaadt */ 601072e3d80Sderaadt static int 602072e3d80Sderaadt privsock(int ty) 603df930be7Sderaadt { 604df930be7Sderaadt int sock = inetresport(ty); 605df930be7Sderaadt 606df930be7Sderaadt if (sock < 0) { 607df930be7Sderaadt errno = 0; 608df930be7Sderaadt /* Couldn't get a secure port, let RPC make an insecure one */ 609df930be7Sderaadt sock = RPC_ANYSOCK; 610df930be7Sderaadt } 611df930be7Sderaadt return sock; 612df930be7Sderaadt } 613df930be7Sderaadt 614df930be7Sderaadt #ifdef DEBUG 615072e3d80Sderaadt void 616072e3d80Sderaadt xfree(char *f, char *l, void *p) 617df930be7Sderaadt { 618df930be7Sderaadt free(p); 619df930be7Sderaadt } 620df930be7Sderaadt #endif /* DEBUG */ 621