BSD 4_3_Net_2 release
[unix-history] / usr / src / usr.sbin / amd / amq / amq.c
index 77c1329..02cc97b 100644 (file)
@@ -1,6 +1,4 @@
 /*
 /*
- * $Id: amq.c,v 5.2 90/06/23 22:20:07 jsp Rel $
- *
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  * Copyright (c) 1990 The Regents of the University of California.
  * Copyright (c) 1990 Jan-Simon Pendry
  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  * Copyright (c) 1990 The Regents of the University of California.
@@ -9,19 +7,38 @@
  * This code is derived from software contributed to Berkeley by
  * Jan-Simon Pendry at Imperial College, London.
  *
  * This code is derived from software contributed to Berkeley by
  * Jan-Simon Pendry at Imperial College, London.
  *
- * Redistribution and use in source and binary forms are permitted provided
- * that: (1) source distributions retain this entire copyright notice and
- * comment, and (2) distributions including binaries display the following
- * acknowledgement:  ``This product includes software developed by the
- * University of California, Berkeley and its contributors'' in the
- * documentation or other materials provided with the distribution and in
- * all advertising materials mentioning features or use of this software.
- * Neither the name of the University nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)amq.c       5.3 (Berkeley) 5/12/91
+ *
+ * $Id: amq.c,v 5.2.1.5 91/05/07 22:18:45 jsp Alpha $
+ *
  */
 
 /*
  */
 
 /*
@@ -37,8 +54,8 @@ char copyright[] = "\
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char rcsid[] = "$Id: amq.c,v 5.2 90/06/23 22:20:07 jsp Rel $";
-static char sccsid[] = "@(#)amq.c      5.1 (Berkeley) 6/29/90";
+static char rcsid[] = "$Id: amq.c,v 5.2.1.5 91/05/07 22:18:45 jsp Alpha $";
+static char sccsid[] = "@(#)amq.c      5.3 (Berkeley) 5/12/91";
 #endif /* not lint */
 
 #include "am.h"
 #endif /* not lint */
 
 #include "am.h"
@@ -47,14 +64,18 @@ static char sccsid[] = "@(#)amq.c   5.1 (Berkeley) 6/29/90";
 #include <fcntl.h>
 #include <netdb.h>
 
 #include <fcntl.h>
 #include <netdb.h>
 
+static int privsock();
+
 char *progname;
 static int flush_flag;
 static int minfo_flag;
 static int unmount_flag;
 static int stats_flag;
 char *progname;
 static int flush_flag;
 static int minfo_flag;
 static int unmount_flag;
 static int stats_flag;
+static int getvers_flag;
 static char *debug_opts;
 static char *logfile;
 static char *debug_opts;
 static char *logfile;
-static char *xlog_opt;
+static char *mount_map;
+static char *xlog_optstr;
 static char localhost[] = "localhost";
 static char *def_server = localhost;
 
 static char localhost[] = "localhost";
 static char *def_server = localhost;
 
@@ -88,7 +109,7 @@ int *twid;
        } break;
 
        case Full: {
        } break;
 
        case Full: {
-               struct tm *tp = localtime(&mt->mt_mounttime);
+               struct tm *tp = localtime((time_t *) &mt->mt_mounttime);
 printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
                        *dwid, *dwid,
                        *mt->mt_directory ? mt->mt_directory : "/",     /* XXX */
 printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
                        *dwid, *dwid,
                        *mt->mt_directory ? mt->mt_directory : "/",     /* XXX */
@@ -111,7 +132,7 @@ printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d
        } break;
 
        case Stats: {
        } break;
 
        case Stats: {
-               struct tm *tp = localtime(&mt->mt_mounttime);
+               struct tm *tp = localtime((time_t *) &mt->mt_mounttime);
 printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
                        *dwid, *dwid,
                        *mt->mt_directory ? mt->mt_directory : "/",     /* XXX */
 printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
                        *dwid, *dwid,
                        *mt->mt_directory ? mt->mt_directory : "/",     /* XXX */
@@ -261,7 +282,10 @@ char *argv[];
        int errs = 0;
        char *server;
        struct sockaddr_in server_addr;
        int errs = 0;
        char *server;
        struct sockaddr_in server_addr;
-       int s = RPC_ANYSOCK;
+
+       /* In order to pass the Amd security check, we must use a priv port. */
+       int s;
+
        CLIENT *clnt;
        struct hostent *hp;
        int nodefault = 0;
        CLIENT *clnt;
        struct hostent *hp;
        int nodefault = 0;
@@ -282,10 +306,11 @@ char *argv[];
        /*
         * Parse arguments
         */
        /*
         * Parse arguments
         */
-       while ((opt_ch = getopt(argc, argv, "fh:l:msux:D:")) != EOF)
+       while ((opt_ch = getopt(argc, argv, "fh:l:msuvx:D:M:")) != EOF)
        switch (opt_ch) {
        case 'f':
                flush_flag = 1;
        switch (opt_ch) {
        case 'f':
                flush_flag = 1;
+               nodefault = 1;
                break;
 
        case 'h':
                break;
 
        case 'h':
@@ -304,14 +329,21 @@ char *argv[];
 
        case 's':
                stats_flag = 1;
 
        case 's':
                stats_flag = 1;
+               nodefault = 1;
                break;
 
        case 'u':
                unmount_flag = 1;
                break;
 
        case 'u':
                unmount_flag = 1;
+               nodefault = 1;
+               break;
+
+       case 'v':
+               getvers_flag = 1;
+               nodefault = 1;
                break;
 
        case 'x':
                break;
 
        case 'x':
-               xlog_opt = optarg;
+               xlog_optstr = optarg;
                nodefault = 1;
                break;
 
                nodefault = 1;
                break;
 
@@ -320,16 +352,26 @@ char *argv[];
                nodefault = 1;
                break;
 
                nodefault = 1;
                break;
 
+       case 'M':
+               mount_map = optarg;
+               nodefault = 1;
+               break;
+
        default:
                errs = 1;
                break;
        }
 
        default:
                errs = 1;
                break;
        }
 
+       if (optind == argc) {
+               if (unmount_flag)
+                       errs = 1;
+       }
+       
        if (errs) {
 show_usage:
                fprintf(stderr, "\
        if (errs) {
 show_usage:
                fprintf(stderr, "\
-Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\
-\t[-l logfile|\"syslog\"] [-x log_flags] [-D dbg_opts]\n", progname);
+Usage: %s [-h host] [[-f] [-m] [-v] [-s]] | [[-u] directory ...]] |\n\
+\t[-l logfile|\"syslog\"] [-x log_flags] [-D dbg_opts] [-M mapent]\n", progname);
                exit(1);
        }
 
                exit(1);
        }
 
@@ -346,17 +388,24 @@ Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\
        /*
         * Get address of server
         */
        /*
         * Get address of server
         */
-       if ((hp = gethostbyname(server)) == 0) {
+       if ((hp = gethostbyname(server)) == 0 && strcmp(server, localhost) != 0) {
                fprintf(stderr, "%s: Can't get address of %s\n", progname, server);
                exit(1);
        }
        bzero(&server_addr, sizeof server_addr);
        server_addr.sin_family = AF_INET;
                fprintf(stderr, "%s: Can't get address of %s\n", progname, server);
                exit(1);
        }
        bzero(&server_addr, sizeof server_addr);
        server_addr.sin_family = AF_INET;
-       server_addr.sin_addr = *(struct in_addr *) hp->h_addr;
+       if (hp) {
+               bcopy((voidp) hp->h_addr, (voidp) &server_addr.sin_addr,
+                       sizeof(server_addr.sin_addr));
+       } else {
+               /* fake "localhost" */
+               server_addr.sin_addr.s_addr = htonl(0x7f000001);
+       }
 
        /*
         * Create RPC endpoint
         */
 
        /*
         * Create RPC endpoint
         */
+       s = privsock();
        clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, TIMEOUT, &s);
        if (clnt == 0) {
                fprintf(stderr, "%s: ", progname);
        clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, TIMEOUT, &s);
        if (clnt == 0) {
                fprintf(stderr, "%s: ", progname);
@@ -385,14 +434,14 @@ Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\
        /*
         * Control logging
         */
        /*
         * Control logging
         */
-       if (xlog_opt) {
+       if (xlog_optstr) {
                int *rc;
                amq_setopt opt;
                opt.as_opt = AMOPT_XLOG;
                int *rc;
                amq_setopt opt;
                opt.as_opt = AMOPT_XLOG;
-               opt.as_str = xlog_opt;
+               opt.as_str = xlog_optstr;
                rc = amqproc_setopt_1(&opt, clnt);
                if (!rc || *rc) {
                rc = amqproc_setopt_1(&opt, clnt);
                if (!rc || *rc) {
-                       fprintf(stderr, "%s: setting log level to \"%s\" failed\n", progname, xlog_opt);
+                       fprintf(stderr, "%s: setting log level to \"%s\" failed\n", progname, xlog_optstr);
                        errs = 1;
                }
        }
                        errs = 1;
                }
        }
@@ -415,7 +464,7 @@ Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\
        /*
         * Flush map cache
         */
        /*
         * Flush map cache
         */
-       if (logfile) {
+       if (flush_flag) {
                int *rc;
                amq_setopt opt;
                opt.as_opt = AMOPT_FLUSHMAPC;
                int *rc;
                amq_setopt opt;
                opt.as_opt = AMOPT_FLUSHMAPC;
@@ -444,6 +493,38 @@ Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\
                }
        }
 
                }
        }
 
+       /*
+        * Mount map
+        */
+       if (mount_map) {
+               int *rc;
+               do {
+                       rc = amqproc_mount_1(&mount_map, clnt);
+               } while (rc && *rc < 0);
+               if (!rc || *rc > 0) {
+                       if (rc)
+                               errno = *rc;
+                       else
+                               errno = ETIMEDOUT;
+                       fprintf(stderr, "%s: could not start new ", progname);
+                       perror("autmount point");
+               }
+       }
+
+       /*
+        * Get Version
+        */
+       if (getvers_flag) {
+               amq_string *spp = amqproc_getvers_1((voidp) 0, clnt);
+               if (spp && *spp) {
+                       printf("%s.\n", *spp);
+                       free(*spp);
+               } else {
+                       fprintf(stderr, "%s: failed to get version information\n", progname);
+                       errs = 1;
+               }
+       }
+
        /*
         * Apply required operation to all remaining arguments
         */
        /*
         * Apply required operation to all remaining arguments
         */
@@ -466,12 +547,6 @@ Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\
                                                int mwid = 0, dwid = 0, twid = 0;
                                                show_mt(mt, Calc, &mwid, &dwid, &twid);
                                                mwid++; dwid++, twid++;
                                                int mwid = 0, dwid = 0, twid = 0;
                                                show_mt(mt, Calc, &mwid, &dwid, &twid);
                                                mwid++; dwid++, twid++;
-#ifdef notdef
-               printf("\t%s\n%-*.*s %-*.*s %-*.*s %s\n",
-               "Uid   Getattr Lookup RdDir   RdLnk   Statfs Mounted@",
-                     dwid, dwid, "What", twid, twid, "Type", mwid, mwid, "Info", "Where");
-                                               show_mt(mt, Full, &mwid, &dwid, &twid);
-#endif /* notdef */
                printf("%-*.*s Uid   Getattr Lookup RdDir   RdLnk   Statfs Mounted@\n",
                        dwid, dwid, "What");
                                                show_mt(mt, Stats, &mwid, &dwid, &twid);
                printf("%-*.*s Uid   Getattr Lookup RdDir   RdLnk   Statfs Mounted@\n",
                        dwid, dwid, "What");
                                                show_mt(mt, Stats, &mwid, &dwid, &twid);
@@ -522,6 +597,54 @@ Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\
        exit(errs);
 }
 
        exit(errs);
 }
 
+/*
+ * udpresport creates a datagram socket and attempts to bind it to a 
+ * secure port.
+ * returns: The bound socket, or -1 to indicate an error.
+ */
+static int udpresport()
+{
+       int alport;
+       struct sockaddr_in addr;
+       int sock;
+
+       /* Use internet address family */
+       addr.sin_family = AF_INET;
+       addr.sin_addr.s_addr = INADDR_ANY;
+       if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+               return -1;
+       for (alport = IPPORT_RESERVED-1; alport > IPPORT_RESERVED/2 + 1; alport--) {
+               addr.sin_port = htons((u_short)alport);
+               if (bind(sock, (struct sockaddr *)&addr, sizeof (addr)) >= 0)
+                       return sock;
+               if (errno != EADDRINUSE) {
+                       close(sock);
+                       return -1;
+               }
+       }
+       close(sock);
+       errno = EAGAIN;
+       return -1;
+}
+
+/*
+ * Privsock() calls udpresport() to attempt to bind a socket to a secure
+ * port.  If udpresport() fails, privsock returns a magic socket number which
+ * indicates to RPC that it should make its own socket.
+ * returns: A privileged socket # or RPC_ANYSOCK.
+ */
+static int privsock()
+{
+       int sock = udpresport();
+
+       if (sock < 0) {
+               errno = 0;
+               /* Couldn't get a secure port, let RPC make an insecure one */
+               sock = RPC_ANYSOCK;
+       }
+       return sock;
+}
+
 #ifdef DEBUG
 xfree(f, l, p)
 char *f, *l;
 #ifdef DEBUG
 xfree(f, l, p)
 char *f, *l;