⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 amq.c

📁 早期freebsd实现
💻 C
字号:
/* * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990, 1993 *	The Regents of the University of California.  All rights reserved. * * 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, 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	8.1 (Berkeley) 6/7/93 * * $Id: amq.c,v 5.2.2.1 1992/02/09 15:09:16 jsp beta $ * *//* * Automounter query tool */#ifndef lintchar copyright[] = "\@(#)Copyright (c) 1990 Jan-Simon Pendry\n\@(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\@(#)Copyright (c) 1990, 1993\n\	The Regents of the University of California.  All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char rcsid[] = "$Id: amq.c,v 5.2.2.1 1992/02/09 15:09:16 jsp beta $";static char sccsid[] = "@(#)amq.c	8.1 (Berkeley) 6/7/93";#endif /* not lint */#include "am.h"#include "amq.h"#include <stdio.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 *mount_map;static char *xlog_optstr;static char localhost[] = "localhost";static char *def_server = localhost;extern int optind;extern char *optarg;static struct timeval tmo = { 10, 0 };#define	TIMEOUT tmoenum show_opt { Full, Stats, Calc, Short, ShowDone };/* * If (e) is Calc then just calculate the sizes * Otherwise display the mount node on stdout */static void show_mti(mt, e, mwid, dwid, twid)amq_mount_tree *mt;enum show_opt e;int *mwid;int *dwid;int *twid;{	switch (e) {	case Calc: {		int mw = strlen(mt->mt_mountinfo);		int dw = strlen(mt->mt_directory);		int tw = strlen(mt->mt_type);		if (mw > *mwid) *mwid = mw;		if (dw > *dwid) *dwid = dw;		if (tw > *twid) *twid = tw;	} break;	case Full: {		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 */			*twid, *twid,			mt->mt_type,			*mwid, *mwid, 			mt->mt_mountinfo,			mt->mt_mountpoint,			mt->mt_mountuid,			mt->mt_getattr,			mt->mt_lookup,			mt->mt_readdir,			mt->mt_readlink,			mt->mt_statfs,			tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,			tp->tm_mon+1, tp->tm_mday,			tp->tm_hour, tp->tm_min, tp->tm_sec);	} break;	case Stats: {		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 */			mt->mt_mountuid,			mt->mt_getattr,			mt->mt_lookup,			mt->mt_readdir,			mt->mt_readlink,			mt->mt_statfs,			tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,			tp->tm_mon+1, tp->tm_mday,			tp->tm_hour, tp->tm_min, tp->tm_sec);	} break;	case Short: {		printf("%-*.*s %-*.*s %-*.*s %s\n",			*dwid, *dwid,			*mt->mt_directory ? mt->mt_directory : "/",			*twid, *twid,			mt->mt_type,			*mwid, *mwid,			mt->mt_mountinfo,			mt->mt_mountpoint);	} break;	}}/* * Display a mount tree. */static void show_mt(mt, e, mwid, dwid, pwid)amq_mount_tree *mt;enum show_opt e;int *mwid;int *dwid;int *pwid;{	while (mt) {		show_mti(mt, e, mwid, dwid, pwid);		show_mt(mt->mt_next, e, mwid, dwid, pwid);		mt = mt->mt_child;	}}static void show_mi(ml, e, mwid, dwid, twid)amq_mount_info_list *ml;enum show_opt e;int *mwid;int *dwid;int *twid;{	int i;	switch (e) {	case Calc: {		for (i = 0; i < ml->amq_mount_info_list_len; i++) {			amq_mount_info *mi = &ml->amq_mount_info_list_val[i];			int mw = strlen(mi->mi_mountinfo);			int dw = strlen(mi->mi_mountpt);			int tw = strlen(mi->mi_type);			if (mw > *mwid) *mwid = mw;			if (dw > *dwid) *dwid = dw;			if (tw > *twid) *twid = tw;		}	} break;	case Full: {		for (i = 0; i < ml->amq_mount_info_list_len; i++) {			amq_mount_info *mi = &ml->amq_mount_info_list_val[i];			printf("%-*.*s %-*.*s %-*.*s %-3d %s is %s",						*mwid, *mwid, mi->mi_mountinfo,						*dwid, *dwid, mi->mi_mountpt,						*twid, *twid, mi->mi_type,						mi->mi_refc, mi->mi_fserver,						mi->mi_up > 0 ? "up" :						mi->mi_up < 0 ? "starting" : "down");			if (mi->mi_error > 0) {#ifdef HAS_STRERROR				printf(" (%s)", strerror(mi->mi_error));#else				extern char *sys_errlist[];				extern int sys_nerr;				if (mi->mi_error < sys_nerr)					printf(" (%s)", sys_errlist[mi->mi_error]);				else					printf(" (Error %d)", mi->mi_error);#endif			} else if (mi->mi_error < 0) {				fputs(" (in progress)", stdout);			}			fputc('\n', stdout);		}	} break;	}}/* * Display general mount statistics */static void show_ms(ms)amq_mount_stats *ms;{	printf("\requests  stale     mount     mount     unmount\n\deferred  fhandles  ok        failed    failed\n\%-9d %-9d %-9d %-9d %-9d\n",	ms->as_drops, ms->as_stale, ms->as_mok, ms->as_merr, ms->as_uerr);}static bool_txdr_pri_free(xdr_args, args_ptr)xdrproc_t xdr_args;caddr_t args_ptr;{	XDR xdr;	xdr.x_op = XDR_FREE;	return ((*xdr_args)(&xdr, args_ptr));}#ifdef hpux#include <cluster.h>static char *cluster_server(){	struct cct_entry *cp;	if (cnodeid() == 0) {		/*		 * Not clustered		 */		return def_server;	}	while (cp = getccent())		if (cp->cnode_type == 'r')			return cp->cnode_name;	return def_server;}#endif /* hpux *//* * MAIN */main(argc, argv)int argc;char *argv[];{	int opt_ch;	int errs = 0;	char *server;	struct sockaddr_in server_addr;	/* In order to pass the Amd security check, we must use a priv port. */	int s;	CLIENT *clnt;	struct hostent *hp;	int nodefault = 0;	/*	 * Compute program name	 */	if (argv[0]) {		progname = strrchr(argv[0], '/');		if (progname && progname[1])			progname++;		else			progname = argv[0];	}	if (!progname)		progname = "amq";	/*	 * Parse arguments	 */	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':		def_server = optarg;		break;	case 'l':		logfile = optarg;		nodefault = 1;		break;	case 'm':		minfo_flag = 1;		nodefault = 1;		break;	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_optstr = optarg;		nodefault = 1;		break;	case 'D':		debug_opts = optarg;		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] [-v] [-s]] | [[-u] directory ...]] |\n\\t[-l logfile|\"syslog\"] [-x log_flags] [-D dbg_opts] [-M mapent]\n", progname);		exit(1);	}#ifdef hpux	/*	 * Figure out root server of cluster	 */	if (def_server == localhost)		server = cluster_server();	else#endif /* hpux */	server = def_server;	/*	 * Get address of server	 */	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;	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(SOCK_STREAM);	clnt = clnttcp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, &s, 0, 0);	if (clnt == 0) {		close(s);		s = privsock(SOCK_DGRAM);		clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, TIMEOUT, &s);	}	if (clnt == 0) {		fprintf(stderr, "%s: ", progname);		clnt_pcreateerror(server);		exit(1);	}	/*	 * Control debugging	 */	if (debug_opts) {		int *rc;		amq_setopt opt;		opt.as_opt = AMOPT_DEBUG;		opt.as_str = debug_opts;		rc = amqproc_setopt_1(&opt, clnt);		if (rc && *rc < 0) {			fprintf(stderr, "%s: daemon not compiled for debug", progname);			errs = 1;		} else if (!rc || *rc > 0) {			fprintf(stderr, "%s: debug setting for \"%s\" failed\n", progname, debug_opts);			errs = 1;		}	}	/*	 * Control logging	 */	if (xlog_optstr) {		int *rc;		amq_setopt opt;		opt.as_opt = AMOPT_XLOG;		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_optstr);			errs = 1;		}	}	/*	 * Control log file	 */	if (logfile) {		int *rc;		amq_setopt opt;		opt.as_opt = AMOPT_LOGFILE;		opt.as_str = logfile;		rc = amqproc_setopt_1(&opt, clnt);		if (!rc || *rc) {			fprintf(stderr, "%s: setting logfile to \"%s\" failed\n", progname, logfile);			errs = 1;		}	}	/*	 * Flush map cache	 */	if (flush_flag) {		int *rc;		amq_setopt opt;		opt.as_opt = AMOPT_FLUSHMAPC;		opt.as_str = "";		rc = amqproc_setopt_1(&opt, clnt);		if (!rc || *rc) {			fprintf(stderr, "%s: amd on %s cannot flush the map cache\n", progname, server);			errs = 1;		}	}	/*	 * Mount info	 */	if (minfo_flag) {		int dummy;		amq_mount_info_list *ml = amqproc_getmntfs_1(&dummy, clnt);		if (ml) {			int mwid = 0, dwid = 0, twid = 0;			show_mi(ml, Calc, &mwid, &dwid, &twid);			mwid++; dwid++; twid++;			show_mi(ml, Full, &mwid, &dwid, &twid);		} else {			fprintf(stderr, "%s: amd on %s cannot provide mount info\n", progname, server);		}	}	/*	 * 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	 */	if (optind < argc) {		do {			char *fs = argv[optind++];			if (unmount_flag) {				/*				 * Unmount request				 */				amqproc_umnt_1(&fs, clnt);			} else {				/*				 * Stats request				 */				amq_mount_tree_p *mtp = amqproc_mnttree_1(&fs, clnt);				if (mtp) {					amq_mount_tree *mt = *mtp;					if (mt) {						int mwid = 0, dwid = 0, twid = 0;						show_mt(mt, Calc, &mwid, &dwid, &twid);						mwid++; dwid++, twid++;		printf("%-*.*s Uid   Getattr Lookup RdDir   RdLnk   Statfs Mounted@\n",			dwid, dwid, "What");						show_mt(mt, Stats, &mwid, &dwid, &twid);					} else {						fprintf(stderr, "%s: %s not automounted\n", progname, fs);					}					xdr_pri_free(xdr_amq_mount_tree_p, (caddr_t) mtp);				} else {					fprintf(stderr, "%s: ", progname);					clnt_perror(clnt, server);					errs = 1;				}			}		} while (optind < argc);	} else if (unmount_flag) {		goto show_usage;	} else if (stats_flag) {		amq_mount_stats *ms = amqproc_stats_1((voidp) 0, clnt);		if (ms) {			show_ms(ms);		} else {			fprintf(stderr, "%s: ", progname);			clnt_perror(clnt, server);			errs = 1;		}	} else if (!nodefault) {		amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt);		if (mlp) {			enum show_opt e = Calc;			int mwid = 0, dwid = 0, pwid = 0;			while (e != ShowDone) {				int i;				for (i = 0; i < mlp->amq_mount_tree_list_len; i++) {					show_mt(mlp->amq_mount_tree_list_val[i],						 e, &mwid, &dwid, &pwid);				}				mwid++; dwid++, pwid++;				if (e == Calc) e = Short;				else if (e == Short) e = ShowDone;			}		} else {			fprintf(stderr, "%s: ", progname);			clnt_perror(clnt, server);			errs = 1;		}	}	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 inetresport(ty)int ty;{	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, ty, 0)) < 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 inetresport() to attempt to bind a socket to a secure * port.  If inetresport() 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(ty)int ty;{	int sock = inetresport(ty);	if (sock < 0) {		errno = 0;		/* Couldn't get a secure port, let RPC make an insecure one */		sock = RPC_ANYSOCK;	}	return sock;}#ifdef DEBUGxfree(f, l, p)char *f, *l;voidp p;{	free(p);}#endif /* DEBUG */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -