1*44628Smckusick /* 2*44628Smckusick * $Id: amq.c,v 5.2 90/06/23 22:20:07 jsp Rel $ 3*44628Smckusick * 4*44628Smckusick * Copyright (c) 1990 Jan-Simon Pendry 5*44628Smckusick * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 6*44628Smckusick * Copyright (c) 1990 The Regents of the University of California. 7*44628Smckusick * All rights reserved. 8*44628Smckusick * 9*44628Smckusick * This code is derived from software contributed to Berkeley by 10*44628Smckusick * Jan-Simon Pendry at Imperial College, London. 11*44628Smckusick * 12*44628Smckusick * %sccs.include.redist.c% 13*44628Smckusick */ 14*44628Smckusick 15*44628Smckusick /* 16*44628Smckusick * Automounter query tool 17*44628Smckusick */ 18*44628Smckusick 19*44628Smckusick #ifndef lint 20*44628Smckusick char copyright[] = "\ 21*44628Smckusick @(#)Copyright (c) 1990 Jan-Simon Pendry\n\ 22*44628Smckusick @(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\ 23*44628Smckusick @(#)Copyright (c) 1990 The Regents of the University of California.\n\ 24*44628Smckusick @(#)All rights reserved.\n"; 25*44628Smckusick #endif /* not lint */ 26*44628Smckusick 27*44628Smckusick #ifndef lint 28*44628Smckusick static char rcsid[] = "$Id: amq.c,v 5.2 90/06/23 22:20:07 jsp Rel $"; 29*44628Smckusick static char sccsid[] = "@(#)amq.c 5.1 (Berkeley) 06/29/90"; 30*44628Smckusick #endif /* not lint */ 31*44628Smckusick 32*44628Smckusick #include "am.h" 33*44628Smckusick #include "amq.h" 34*44628Smckusick #include <stdio.h> 35*44628Smckusick #include <fcntl.h> 36*44628Smckusick #include <netdb.h> 37*44628Smckusick 38*44628Smckusick char *progname; 39*44628Smckusick static int flush_flag; 40*44628Smckusick static int minfo_flag; 41*44628Smckusick static int unmount_flag; 42*44628Smckusick static int stats_flag; 43*44628Smckusick static char *debug_opts; 44*44628Smckusick static char *logfile; 45*44628Smckusick static char *xlog_opt; 46*44628Smckusick static char localhost[] = "localhost"; 47*44628Smckusick static char *def_server = localhost; 48*44628Smckusick 49*44628Smckusick extern int optind; 50*44628Smckusick extern char *optarg; 51*44628Smckusick 52*44628Smckusick static struct timeval tmo = { 10, 0 }; 53*44628Smckusick #define TIMEOUT tmo 54*44628Smckusick 55*44628Smckusick enum show_opt { Full, Stats, Calc, Short, ShowDone }; 56*44628Smckusick 57*44628Smckusick /* 58*44628Smckusick * If (e) is Calc then just calculate the sizes 59*44628Smckusick * Otherwise display the mount node on stdout 60*44628Smckusick */ 61*44628Smckusick static void show_mti(mt, e, mwid, dwid, twid) 62*44628Smckusick amq_mount_tree *mt; 63*44628Smckusick enum show_opt e; 64*44628Smckusick int *mwid; 65*44628Smckusick int *dwid; 66*44628Smckusick int *twid; 67*44628Smckusick { 68*44628Smckusick switch (e) { 69*44628Smckusick case Calc: { 70*44628Smckusick int mw = strlen(mt->mt_mountinfo); 71*44628Smckusick int dw = strlen(mt->mt_directory); 72*44628Smckusick int tw = strlen(mt->mt_type); 73*44628Smckusick if (mw > *mwid) *mwid = mw; 74*44628Smckusick if (dw > *dwid) *dwid = dw; 75*44628Smckusick if (tw > *twid) *twid = tw; 76*44628Smckusick } break; 77*44628Smckusick 78*44628Smckusick case Full: { 79*44628Smckusick struct tm *tp = localtime(&mt->mt_mounttime); 80*44628Smckusick printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n", 81*44628Smckusick *dwid, *dwid, 82*44628Smckusick *mt->mt_directory ? mt->mt_directory : "/", /* XXX */ 83*44628Smckusick *twid, *twid, 84*44628Smckusick mt->mt_type, 85*44628Smckusick *mwid, *mwid, 86*44628Smckusick mt->mt_mountinfo, 87*44628Smckusick mt->mt_mountpoint, 88*44628Smckusick 89*44628Smckusick mt->mt_mountuid, 90*44628Smckusick mt->mt_getattr, 91*44628Smckusick mt->mt_lookup, 92*44628Smckusick mt->mt_readdir, 93*44628Smckusick mt->mt_readlink, 94*44628Smckusick mt->mt_statfs, 95*44628Smckusick 96*44628Smckusick tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year, 97*44628Smckusick tp->tm_mon+1, tp->tm_mday, 98*44628Smckusick tp->tm_hour, tp->tm_min, tp->tm_sec); 99*44628Smckusick } break; 100*44628Smckusick 101*44628Smckusick case Stats: { 102*44628Smckusick struct tm *tp = localtime(&mt->mt_mounttime); 103*44628Smckusick printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n", 104*44628Smckusick *dwid, *dwid, 105*44628Smckusick *mt->mt_directory ? mt->mt_directory : "/", /* XXX */ 106*44628Smckusick 107*44628Smckusick mt->mt_mountuid, 108*44628Smckusick mt->mt_getattr, 109*44628Smckusick mt->mt_lookup, 110*44628Smckusick mt->mt_readdir, 111*44628Smckusick mt->mt_readlink, 112*44628Smckusick mt->mt_statfs, 113*44628Smckusick 114*44628Smckusick tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year, 115*44628Smckusick tp->tm_mon+1, tp->tm_mday, 116*44628Smckusick tp->tm_hour, tp->tm_min, tp->tm_sec); 117*44628Smckusick } break; 118*44628Smckusick 119*44628Smckusick case Short: { 120*44628Smckusick printf("%-*.*s %-*.*s %-*.*s %s\n", 121*44628Smckusick *dwid, *dwid, 122*44628Smckusick *mt->mt_directory ? mt->mt_directory : "/", 123*44628Smckusick *twid, *twid, 124*44628Smckusick mt->mt_type, 125*44628Smckusick *mwid, *mwid, 126*44628Smckusick mt->mt_mountinfo, 127*44628Smckusick mt->mt_mountpoint); 128*44628Smckusick } break; 129*44628Smckusick } 130*44628Smckusick } 131*44628Smckusick 132*44628Smckusick /* 133*44628Smckusick * Display a mount tree. 134*44628Smckusick */ 135*44628Smckusick static void show_mt(mt, e, mwid, dwid, pwid) 136*44628Smckusick amq_mount_tree *mt; 137*44628Smckusick enum show_opt e; 138*44628Smckusick int *mwid; 139*44628Smckusick int *dwid; 140*44628Smckusick int *pwid; 141*44628Smckusick { 142*44628Smckusick while (mt) { 143*44628Smckusick show_mti(mt, e, mwid, dwid, pwid); 144*44628Smckusick show_mt(mt->mt_next, e, mwid, dwid, pwid); 145*44628Smckusick mt = mt->mt_child; 146*44628Smckusick } 147*44628Smckusick } 148*44628Smckusick 149*44628Smckusick static void show_mi(ml, e, mwid, dwid, twid) 150*44628Smckusick amq_mount_info_list *ml; 151*44628Smckusick enum show_opt e; 152*44628Smckusick int *mwid; 153*44628Smckusick int *dwid; 154*44628Smckusick int *twid; 155*44628Smckusick { 156*44628Smckusick int i; 157*44628Smckusick switch (e) { 158*44628Smckusick case Calc: { 159*44628Smckusick for (i = 0; i < ml->amq_mount_info_list_len; i++) { 160*44628Smckusick amq_mount_info *mi = &ml->amq_mount_info_list_val[i]; 161*44628Smckusick int mw = strlen(mi->mi_mountinfo); 162*44628Smckusick int dw = strlen(mi->mi_mountpt); 163*44628Smckusick int tw = strlen(mi->mi_type); 164*44628Smckusick if (mw > *mwid) *mwid = mw; 165*44628Smckusick if (dw > *dwid) *dwid = dw; 166*44628Smckusick if (tw > *twid) *twid = tw; 167*44628Smckusick } 168*44628Smckusick } break; 169*44628Smckusick 170*44628Smckusick case Full: { 171*44628Smckusick for (i = 0; i < ml->amq_mount_info_list_len; i++) { 172*44628Smckusick amq_mount_info *mi = &ml->amq_mount_info_list_val[i]; 173*44628Smckusick printf("%-*.*s %-*.*s %-*.*s %-3d %s is %s", 174*44628Smckusick *mwid, *mwid, mi->mi_mountinfo, 175*44628Smckusick *dwid, *dwid, mi->mi_mountpt, 176*44628Smckusick *twid, *twid, mi->mi_type, 177*44628Smckusick mi->mi_refc, mi->mi_fserver, 178*44628Smckusick mi->mi_up > 0 ? "up" : 179*44628Smckusick mi->mi_up < 0 ? "starting" : "down"); 180*44628Smckusick if (mi->mi_error > 0) { 181*44628Smckusick extern char *sys_errlist[]; 182*44628Smckusick extern int sys_nerr; 183*44628Smckusick if (mi->mi_error < sys_nerr) 184*44628Smckusick printf(" (%s)", sys_errlist[mi->mi_error]); 185*44628Smckusick else 186*44628Smckusick printf(" (Error %d)", mi->mi_error); 187*44628Smckusick } else if (mi->mi_error < 0) { 188*44628Smckusick fputs(" (in progress)", stdout); 189*44628Smckusick } 190*44628Smckusick fputc('\n', stdout); 191*44628Smckusick } 192*44628Smckusick } break; 193*44628Smckusick } 194*44628Smckusick } 195*44628Smckusick 196*44628Smckusick /* 197*44628Smckusick * Display general mount statistics 198*44628Smckusick */ 199*44628Smckusick static void show_ms(ms) 200*44628Smckusick amq_mount_stats *ms; 201*44628Smckusick { 202*44628Smckusick printf("\ 203*44628Smckusick requests stale mount mount unmount\n\ 204*44628Smckusick deferred fhandles ok failed failed\n\ 205*44628Smckusick %-9d %-9d %-9d %-9d %-9d\n", 206*44628Smckusick ms->as_drops, ms->as_stale, ms->as_mok, ms->as_merr, ms->as_uerr); 207*44628Smckusick } 208*44628Smckusick 209*44628Smckusick static bool_t 210*44628Smckusick xdr_pri_free(xdr_args, args_ptr) 211*44628Smckusick xdrproc_t xdr_args; 212*44628Smckusick caddr_t args_ptr; 213*44628Smckusick { 214*44628Smckusick XDR xdr; 215*44628Smckusick xdr.x_op = XDR_FREE; 216*44628Smckusick return ((*xdr_args)(&xdr, args_ptr)); 217*44628Smckusick } 218*44628Smckusick 219*44628Smckusick #ifdef hpux 220*44628Smckusick #include <cluster.h> 221*44628Smckusick static char *cluster_server() 222*44628Smckusick { 223*44628Smckusick struct cct_entry *cp; 224*44628Smckusick 225*44628Smckusick if (cnodeid() == 0) { 226*44628Smckusick /* 227*44628Smckusick * Not clustered 228*44628Smckusick */ 229*44628Smckusick return def_server; 230*44628Smckusick } 231*44628Smckusick 232*44628Smckusick while (cp = getccent()) 233*44628Smckusick if (cp->cnode_type == 'r') 234*44628Smckusick return cp->cnode_name; 235*44628Smckusick 236*44628Smckusick 237*44628Smckusick return def_server; 238*44628Smckusick } 239*44628Smckusick #endif /* hpux */ 240*44628Smckusick 241*44628Smckusick /* 242*44628Smckusick * MAIN 243*44628Smckusick */ 244*44628Smckusick main(argc, argv) 245*44628Smckusick int argc; 246*44628Smckusick char *argv[]; 247*44628Smckusick { 248*44628Smckusick int opt_ch; 249*44628Smckusick int errs = 0; 250*44628Smckusick char *server; 251*44628Smckusick struct sockaddr_in server_addr; 252*44628Smckusick int s = RPC_ANYSOCK; 253*44628Smckusick CLIENT *clnt; 254*44628Smckusick struct hostent *hp; 255*44628Smckusick int nodefault = 0; 256*44628Smckusick 257*44628Smckusick /* 258*44628Smckusick * Compute program name 259*44628Smckusick */ 260*44628Smckusick if (argv[0]) { 261*44628Smckusick progname = strrchr(argv[0], '/'); 262*44628Smckusick if (progname && progname[1]) 263*44628Smckusick progname++; 264*44628Smckusick else 265*44628Smckusick progname = argv[0]; 266*44628Smckusick } 267*44628Smckusick if (!progname) 268*44628Smckusick progname = "amq"; 269*44628Smckusick 270*44628Smckusick /* 271*44628Smckusick * Parse arguments 272*44628Smckusick */ 273*44628Smckusick while ((opt_ch = getopt(argc, argv, "fh:l:msux:D:")) != EOF) 274*44628Smckusick switch (opt_ch) { 275*44628Smckusick case 'f': 276*44628Smckusick flush_flag = 1; 277*44628Smckusick break; 278*44628Smckusick 279*44628Smckusick case 'h': 280*44628Smckusick def_server = optarg; 281*44628Smckusick break; 282*44628Smckusick 283*44628Smckusick case 'l': 284*44628Smckusick logfile = optarg; 285*44628Smckusick nodefault = 1; 286*44628Smckusick break; 287*44628Smckusick 288*44628Smckusick case 'm': 289*44628Smckusick minfo_flag = 1; 290*44628Smckusick nodefault = 1; 291*44628Smckusick break; 292*44628Smckusick 293*44628Smckusick case 's': 294*44628Smckusick stats_flag = 1; 295*44628Smckusick break; 296*44628Smckusick 297*44628Smckusick case 'u': 298*44628Smckusick unmount_flag = 1; 299*44628Smckusick break; 300*44628Smckusick 301*44628Smckusick case 'x': 302*44628Smckusick xlog_opt = optarg; 303*44628Smckusick nodefault = 1; 304*44628Smckusick break; 305*44628Smckusick 306*44628Smckusick case 'D': 307*44628Smckusick debug_opts = optarg; 308*44628Smckusick nodefault = 1; 309*44628Smckusick break; 310*44628Smckusick 311*44628Smckusick default: 312*44628Smckusick errs = 1; 313*44628Smckusick break; 314*44628Smckusick } 315*44628Smckusick 316*44628Smckusick if (errs) { 317*44628Smckusick show_usage: 318*44628Smckusick fprintf(stderr, "\ 319*44628Smckusick Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\ 320*44628Smckusick \t[-l logfile|\"syslog\"] [-x log_flags] [-D dbg_opts]\n", progname); 321*44628Smckusick exit(1); 322*44628Smckusick } 323*44628Smckusick 324*44628Smckusick #ifdef hpux 325*44628Smckusick /* 326*44628Smckusick * Figure out root server of cluster 327*44628Smckusick */ 328*44628Smckusick if (def_server == localhost) 329*44628Smckusick server = cluster_server(); 330*44628Smckusick else 331*44628Smckusick #endif /* hpux */ 332*44628Smckusick server = def_server; 333*44628Smckusick 334*44628Smckusick /* 335*44628Smckusick * Get address of server 336*44628Smckusick */ 337*44628Smckusick if ((hp = gethostbyname(server)) == 0) { 338*44628Smckusick fprintf(stderr, "%s: Can't get address of %s\n", progname, server); 339*44628Smckusick exit(1); 340*44628Smckusick } 341*44628Smckusick bzero(&server_addr, sizeof server_addr); 342*44628Smckusick server_addr.sin_family = AF_INET; 343*44628Smckusick server_addr.sin_addr = *(struct in_addr *) hp->h_addr; 344*44628Smckusick 345*44628Smckusick /* 346*44628Smckusick * Create RPC endpoint 347*44628Smckusick */ 348*44628Smckusick clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, TIMEOUT, &s); 349*44628Smckusick if (clnt == 0) { 350*44628Smckusick fprintf(stderr, "%s: ", progname); 351*44628Smckusick clnt_pcreateerror(server); 352*44628Smckusick exit(1); 353*44628Smckusick } 354*44628Smckusick 355*44628Smckusick /* 356*44628Smckusick * Control debugging 357*44628Smckusick */ 358*44628Smckusick if (debug_opts) { 359*44628Smckusick int *rc; 360*44628Smckusick amq_setopt opt; 361*44628Smckusick opt.as_opt = AMOPT_DEBUG; 362*44628Smckusick opt.as_str = debug_opts; 363*44628Smckusick rc = amqproc_setopt_1(&opt, clnt); 364*44628Smckusick if (rc && *rc < 0) { 365*44628Smckusick fprintf(stderr, "%s: daemon not compiled for debug", progname); 366*44628Smckusick errs = 1; 367*44628Smckusick } else if (!rc || *rc > 0) { 368*44628Smckusick fprintf(stderr, "%s: debug setting for \"%s\" failed\n", progname, debug_opts); 369*44628Smckusick errs = 1; 370*44628Smckusick } 371*44628Smckusick } 372*44628Smckusick 373*44628Smckusick /* 374*44628Smckusick * Control logging 375*44628Smckusick */ 376*44628Smckusick if (xlog_opt) { 377*44628Smckusick int *rc; 378*44628Smckusick amq_setopt opt; 379*44628Smckusick opt.as_opt = AMOPT_XLOG; 380*44628Smckusick opt.as_str = xlog_opt; 381*44628Smckusick rc = amqproc_setopt_1(&opt, clnt); 382*44628Smckusick if (!rc || *rc) { 383*44628Smckusick fprintf(stderr, "%s: setting log level to \"%s\" failed\n", progname, xlog_opt); 384*44628Smckusick errs = 1; 385*44628Smckusick } 386*44628Smckusick } 387*44628Smckusick 388*44628Smckusick /* 389*44628Smckusick * Control log file 390*44628Smckusick */ 391*44628Smckusick if (logfile) { 392*44628Smckusick int *rc; 393*44628Smckusick amq_setopt opt; 394*44628Smckusick opt.as_opt = AMOPT_LOGFILE; 395*44628Smckusick opt.as_str = logfile; 396*44628Smckusick rc = amqproc_setopt_1(&opt, clnt); 397*44628Smckusick if (!rc || *rc) { 398*44628Smckusick fprintf(stderr, "%s: setting logfile to \"%s\" failed\n", progname, logfile); 399*44628Smckusick errs = 1; 400*44628Smckusick } 401*44628Smckusick } 402*44628Smckusick 403*44628Smckusick /* 404*44628Smckusick * Flush map cache 405*44628Smckusick */ 406*44628Smckusick if (logfile) { 407*44628Smckusick int *rc; 408*44628Smckusick amq_setopt opt; 409*44628Smckusick opt.as_opt = AMOPT_FLUSHMAPC; 410*44628Smckusick opt.as_str = ""; 411*44628Smckusick rc = amqproc_setopt_1(&opt, clnt); 412*44628Smckusick if (!rc || *rc) { 413*44628Smckusick fprintf(stderr, "%s: amd on %s cannot flush the map cache\n", progname, server); 414*44628Smckusick errs = 1; 415*44628Smckusick } 416*44628Smckusick } 417*44628Smckusick 418*44628Smckusick /* 419*44628Smckusick * Mount info 420*44628Smckusick */ 421*44628Smckusick if (minfo_flag) { 422*44628Smckusick int dummy; 423*44628Smckusick amq_mount_info_list *ml = amqproc_getmntfs_1(&dummy, clnt); 424*44628Smckusick if (ml) { 425*44628Smckusick int mwid = 0, dwid = 0, twid = 0; 426*44628Smckusick show_mi(ml, Calc, &mwid, &dwid, &twid); 427*44628Smckusick mwid++; dwid++; twid++; 428*44628Smckusick show_mi(ml, Full, &mwid, &dwid, &twid); 429*44628Smckusick 430*44628Smckusick } else { 431*44628Smckusick fprintf(stderr, "%s: amd on %s cannot provide mount info\n", progname, server); 432*44628Smckusick } 433*44628Smckusick } 434*44628Smckusick 435*44628Smckusick /* 436*44628Smckusick * Apply required operation to all remaining arguments 437*44628Smckusick */ 438*44628Smckusick if (optind < argc) { 439*44628Smckusick do { 440*44628Smckusick char *fs = argv[optind++]; 441*44628Smckusick if (unmount_flag) { 442*44628Smckusick /* 443*44628Smckusick * Unmount request 444*44628Smckusick */ 445*44628Smckusick amqproc_umnt_1(&fs, clnt); 446*44628Smckusick } else { 447*44628Smckusick /* 448*44628Smckusick * Stats request 449*44628Smckusick */ 450*44628Smckusick amq_mount_tree_p *mtp = amqproc_mnttree_1(&fs, clnt); 451*44628Smckusick if (mtp) { 452*44628Smckusick amq_mount_tree *mt = *mtp; 453*44628Smckusick if (mt) { 454*44628Smckusick int mwid = 0, dwid = 0, twid = 0; 455*44628Smckusick show_mt(mt, Calc, &mwid, &dwid, &twid); 456*44628Smckusick mwid++; dwid++, twid++; 457*44628Smckusick #ifdef notdef 458*44628Smckusick printf("\t%s\n%-*.*s %-*.*s %-*.*s %s\n", 459*44628Smckusick "Uid Getattr Lookup RdDir RdLnk Statfs Mounted@", 460*44628Smckusick dwid, dwid, "What", twid, twid, "Type", mwid, mwid, "Info", "Where"); 461*44628Smckusick show_mt(mt, Full, &mwid, &dwid, &twid); 462*44628Smckusick #endif /* notdef */ 463*44628Smckusick printf("%-*.*s Uid Getattr Lookup RdDir RdLnk Statfs Mounted@\n", 464*44628Smckusick dwid, dwid, "What"); 465*44628Smckusick show_mt(mt, Stats, &mwid, &dwid, &twid); 466*44628Smckusick } else { 467*44628Smckusick fprintf(stderr, "%s: %s not automounted\n", progname, fs); 468*44628Smckusick } 469*44628Smckusick xdr_pri_free(xdr_amq_mount_tree_p, (caddr_t) mtp); 470*44628Smckusick } else { 471*44628Smckusick fprintf(stderr, "%s: ", progname); 472*44628Smckusick clnt_perror(clnt, server); 473*44628Smckusick errs = 1; 474*44628Smckusick } 475*44628Smckusick } 476*44628Smckusick } while (optind < argc); 477*44628Smckusick } else if (unmount_flag) { 478*44628Smckusick goto show_usage; 479*44628Smckusick } else if (stats_flag) { 480*44628Smckusick amq_mount_stats *ms = amqproc_stats_1((voidp) 0, clnt); 481*44628Smckusick if (ms) { 482*44628Smckusick show_ms(ms); 483*44628Smckusick } else { 484*44628Smckusick fprintf(stderr, "%s: ", progname); 485*44628Smckusick clnt_perror(clnt, server); 486*44628Smckusick errs = 1; 487*44628Smckusick } 488*44628Smckusick } else if (!nodefault) { 489*44628Smckusick amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt); 490*44628Smckusick if (mlp) { 491*44628Smckusick enum show_opt e = Calc; 492*44628Smckusick int mwid = 0, dwid = 0, pwid = 0; 493*44628Smckusick while (e != ShowDone) { 494*44628Smckusick int i; 495*44628Smckusick for (i = 0; i < mlp->amq_mount_tree_list_len; i++) { 496*44628Smckusick show_mt(mlp->amq_mount_tree_list_val[i], 497*44628Smckusick e, &mwid, &dwid, &pwid); 498*44628Smckusick } 499*44628Smckusick mwid++; dwid++, pwid++; 500*44628Smckusick if (e == Calc) e = Short; 501*44628Smckusick else if (e == Short) e = ShowDone; 502*44628Smckusick } 503*44628Smckusick } else { 504*44628Smckusick fprintf(stderr, "%s: ", progname); 505*44628Smckusick clnt_perror(clnt, server); 506*44628Smckusick errs = 1; 507*44628Smckusick } 508*44628Smckusick } 509*44628Smckusick 510*44628Smckusick exit(errs); 511*44628Smckusick } 512*44628Smckusick 513*44628Smckusick #ifdef DEBUG 514*44628Smckusick xfree(f, l, p) 515*44628Smckusick char *f, *l; 516*44628Smckusick voidp p; 517*44628Smckusick { 518*44628Smckusick free(p); 519*44628Smckusick } 520*44628Smckusick #endif /* DEBUG */ 521