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