/*
- * $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.
* 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 $
+ *
*/
/*
#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"
#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;
+static int getvers_flag;
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;
} 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 */
} 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 */
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;
/*
* 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;
+ nodefault = 1;
break;
case 'h':
case 's':
stats_flag = 1;
+ nodefault = 1;
break;
case 'u':
unmount_flag = 1;
+ nodefault = 1;
+ break;
+
+ case 'v':
+ getvers_flag = 1;
+ nodefault = 1;
break;
case 'x':
- xlog_opt = optarg;
+ xlog_optstr = optarg;
nodefault = 1;
break;
nodefault = 1;
break;
+ case 'M':
+ mount_map = optarg;
+ nodefault = 1;
+ break;
+
default:
errs = 1;
break;
}
+ if (optind == argc) {
+ if (unmount_flag)
+ errs = 1;
+ }
+
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);
}
/*
* 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;
- 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
*/
+ s = privsock();
clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, TIMEOUT, &s);
if (clnt == 0) {
fprintf(stderr, "%s: ", progname);
/*
* Control logging
*/
- if (xlog_opt) {
+ if (xlog_optstr) {
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) {
- 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;
}
}
/*
* Flush map cache
*/
- if (logfile) {
+ if (flush_flag) {
int *rc;
amq_setopt opt;
opt.as_opt = AMOPT_FLUSHMAPC;
}
}
+ /*
+ * 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
*/
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);
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;