home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume21 / amd / part07 / amq.c next >
Encoding:
C/C++ Source or Header  |  1990-04-10  |  11.4 KB  |  532 lines

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