auto_look.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,000 行 · 第 1/2 页

C
1,000
字号
#ifndef lintstatic char *sccsid = "@(#)auto_look.c	4.3      (ULTRIX)        2/21/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1986 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* *	Portions of this software have been licensed to  *	Digital Equipment Company, Maynard, MA. *	Copyright (c) 1987 Sun Microsystems, Inc.  ALL RIGHTS RESERVED. *//* *	Modification History: *  *	4 Sep 90 -- condylis *		Changed getmapent_hosts() to try to query mountd's TCP *		port first when getting an export list from a host. * *      10 Nov 89 -- lebel *              Incorporated direct maps, bugfixes, metacharacter handling  *              and other fun stuff from the reference tape. * 	14 Jun 89 -- condylis *		Added copyright header. * */#include <stdio.h>#include <ctype.h>#include <syslog.h>#include <sys/types.h>#include <sys/param.h>#include <sys/time.h>#include <pwd.h>#include <netinet/in.h>#include <netdb.h>#include <rpc/types.h>#include <rpc/auth.h>#include <rpc/auth_unix.h>#include <rpc/xdr.h>#include <rpc/clnt.h>#include <rpc/svc.h>#include <rpcsvc/ypclnt.h>#include <sys/socket.h>#include "nfs_prot.h"#define NFSCLIENTtypedef nfs_fh fhandle_t;#include <rpcsvc/mount.h>#include <sys/mount.h>#include <nfs/nfs_gfs.h>#include "automount.h"struct timeval TIMEOUT = { 25, 0 };#define	MAXHOSTS 20nfsstat do_mount();void diag();void getword();void unquote();void macro_expand();extern int trace;nfsstatlookup(dir, name, vpp, cred)	struct autodir *dir;	char *name;	struct vnode **vpp;	struct authunix_parms *cred;{	struct mapent *me;	struct mapfs *mfs;	struct link *link;	struct filsys *fs;	char *linkpath;	nfsstat status;	if (name[0] == '.' &&	    (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) {		*vpp = &dir->dir_vnode;		return (NFS_OK);	}	if ((link = findlink(dir, name)) && link->link_fs) {		link->link_death = time_now + max_link_time;		link->link_fs->fs_rootfs->fs_death = time_now + max_link_time;		*vpp =  &link->link_vnode;		 return (NFS_OK);	}	me = getmapent(dir->dir_map, dir->dir_opts, name, cred);	if (me == NULL) {		if (*name == '=' && cred->aup_uid == 0) {			if (isdigit(*(name+1))) {				trace = atoi(name+1);				(void) fprintf(stderr, "automount trace = %d\n",					trace);			} else {				diag(name+1);			}		}		return (NFSERR_NOENT);	}	if (trace > 1) {		struct mapent *ms;			fprintf(stderr, "%s/ %s (%s)\n",			dir->dir_name, name, me->map_root);		for (ms = me ; ms ; ms = ms->map_next) {			fprintf(stderr, "   %s \t-%s\t",				*ms->map_mntpnt ? ms->map_mntpnt : "/",				ms->map_mntopts);			for (mfs = ms->map_fs ; mfs ; mfs = mfs->mfs_next)				fprintf(stderr, "%s:%s%s%s ",					mfs->mfs_host,					mfs->mfs_dir,					*mfs->mfs_subdir ? ":" : "",					mfs->mfs_subdir);			fprintf(stderr, "\n");		}	}	fs = NULL;	status = do_mount(dir, me, &fs, &linkpath);	if (status != NFS_OK) {		free_mapent(me);		return (status);	}	link = makelink(dir, name, fs, linkpath);	free_mapent(me);	if (link == NULL)		return (NFSERR_NOSPC);	*vpp = &link->link_vnode;	return (NFS_OK);}voiddiag(s)	char *s;{	register int i;	struct autodir *dir;	register struct vnode *vnode;	register struct link *link;	extern struct queue fh_q_hash[];	register struct filsys *fs, *nextfs;	extern int verbose;	switch (*s) {	case 'v':	/* toggle verbose */		verbose = !verbose;		syslog(LOG_ERR, "verbose %s", verbose ? "on" : "off");		break;	case 'n':	/* print vnodes */		for (i = 0; i < FH_HASH_SIZE; i++) {			vnode = HEAD(struct vnode, fh_q_hash[i]);			for (; vnode; vnode = NEXT(struct vnode, vnode)) {				if (vnode->vn_type == VN_LINK) {					link = (struct link *)vnode->vn_data;					(void) fprintf(stderr, "link: %s/ %s ",						link->link_dir->dir_name,						link->link_name);					if (link->link_path)						(void) fprintf(stderr, "-> \"%s\" ",							link->link_path);					if (link->link_fs)						(void) fprintf(stderr, "@ %s:%s ",							link->link_fs->fs_host,							link->link_fs->fs_dir);					(void) fprintf(stderr, "\t[%d]\n",						link->link_death <= 0 ? 0 :						  link->link_death - time_now);				} else {					dir = (struct autodir *)vnode->vn_data;					(void) fprintf(stderr, "dir : %s %s -%s\n",						dir->dir_name, dir->dir_map,						dir->dir_opts);				}			}		} /* end for */		break;	case 'f':	/* print fs's */		for (fs = HEAD(struct filsys, fs_q); fs; fs = nextfs) {			nextfs = NEXT(struct filsys, fs);			(void) fprintf(stderr, "%s %s:%s -%s ",				fs->fs_mntpnt, fs->fs_host, fs->fs_dir,				fs->fs_opts);			if (fs->fs_mine) {				(void) fprintf(stderr, "%x ",					fs->fs_dev & 0xFFFF);				(void) fprintf(stderr, "%d\n",					fs->fs_death > time_now ?					fs->fs_death - time_now : 0);			}			else				(void) fprintf(stderr, "\n");		} /* end for */		break;	}}struct mapent *getmapent(mapname, mapopts, key, cred)	char *mapname, *mapopts, *key;	struct authunix_parms *cred;{	FILE *fp = NULL;	char *ypline = NULL;	char *index();	struct mapent *me = NULL;	int len;	char *get_line();	char word[64], wordq[64];	char *p;	char *lp, *lq, linebuf[2048], linebufq[2048];	struct mapent *getmapent_hosts();	struct mapent *getmapent_passwd();	struct mapent *do_mapent();	if (strcmp(mapname, "-hosts") == 0)		return getmapent_hosts(mapopts, key);	if (strcmp(mapname, "-passwd") == 0)		return getmapent_passwd(mapopts, key, cred);	if ((fp = fopen(mapname, "r")) != NULL) {		/*		 * The map is in a file, and the file exists; scan it.		 */		for (;;) {			lp = get_line(fp, linebuf, sizeof linebuf);			if (lp == NULL) {				(void) fclose(fp);				return ((struct mapent *)0);			}			/* now have complete line */			lq = linebufq;			unquote(lp, lq);			getword(word, wordq, &lp, &lq, ' ');			p = &word[strlen(word) - 1];			if (*p == '/')				*p = '\0';	/* delete trailing / */			if (strcmp(word, key) == 0)				break;			if (word[0] == '*' && word[1] == '\0')				break;			if (word[0] == '+') {				me = getmapent(word+1, mapopts, key, cred);				if (me != NULL) {					(void) fclose(fp);					return me;				}			}		}		(void) fclose(fp);	} else {		/*		 * The map is a YP map, or is claimed to be a file but		 * the file does not exist; just lookup the YP entry.		 */		if (try_yp(mapname, key, &ypline, &len))			return ((struct mapent *)NULL);		/* trim the YP entry - ignore # and beyond */		if (lp = index(ypline, '#'))			*lp = '\0';		len = strlen(ypline);		if (len <= 0)			goto done;		/* trim trailing white space */		lp = &ypline[len - 1];		while (lp > ypline && isspace(*lp))			*lp-- = '\0';		if (lp == ypline)			goto done;		(void) strcpy(linebuf, ypline);		lp = linebuf;		lq = linebufq;		unquote(lp, lq);	}	/* now have correct line */	me = do_mapent(lp, lq, mapname, mapopts, key);done:	if (ypline)		free((char *)ypline);	return (me);}struct mapent *do_mapent(lp, lq, mapname, mapopts, key)	char *lp, *lq, *mapname, *mapopts, *key;{	char w[1024], wq[1024];	char *malloc();	struct mapent *me, *mp, *ms;	int err, implied;	macro_expand(key, lp, lq);	if (trace > 1)		(void) fprintf(stderr, "\"%s %s\"\n", key, lp);	getword(w, wq, &lp, &lq, ' ');	implied = *w != '/';	ms = NULL;	while (*w == '/' || implied) {		mp = me;		me = (struct mapent *)malloc(sizeof *me);		if (me == NULL)			goto alloc_failed;		bzero((char *) me, sizeof *me);		if (ms == NULL)			ms = me;		else			mp->map_next = me;				if (strcmp(w, "/") == 0 || implied)			me->map_mntpnt = strdup("");		else			me->map_mntpnt = strdup(w);		if (me->map_mntpnt == NULL)			goto alloc_failed;		if (implied)			implied = 0;		else			getword(w, wq, &lp, &lq, ' ');		if (w[0] == '-') {	/* mount options */			me->map_mntopts = strdup(w+1);			getword(w, wq, &lp, &lq, ' ');		} else			me->map_mntopts = strdup(mapopts);		if (me->map_mntopts == NULL)			goto alloc_failed;		if (w[0] == '\0') {			syslog(LOG_ERR, "map %s, key %s: bad", mapname, key);			goto bad_entry;		}		err = mfs_get(mapname, me, w, wq, &lp, &lq);		if (err < 0)			goto alloc_failed;		if (err > 0)			goto bad_entry;		me->map_next = NULL;	}	if (*key == '/') {		*w = '\0';	/* a hack for direct maps */	} else {		(void) strcpy(w, "/");		(void) strcat(w, key);	}	ms->map_root = strdup(w);	if (ms->map_root == NULL)		goto alloc_failed;	return (ms);alloc_failed:	syslog(LOG_ERR, "Memory allocation failed: %m");bad_entry:	free_mapent(ms);	return ((struct mapent *) NULL);}try_yp(map, key, ypline, yplen)	char *map, *key;	char **ypline;	int *yplen;{	int reason;	reason = yp_match(mydomain, map, key, strlen(key), ypline, yplen);	if (reason) {		if (reason == YPERR_KEY) {			/*			 * Try the default entry "*"			 */			if (yp_match(mydomain, map, "*", 1, ypline, yplen))				return 1;		} else {			syslog(LOG_ERR, "%s: %s", map, yperr_string(reason));			return 1;		}	}	return 0;}char *get_line(fp, line, linesz)	FILE *fp;	char *line;	int linesz;{	register char *p;	register int len;	p = line;	for (;;) {		if (fgets(p, linesz - (p-line), fp) == NULL)			return NULL;		/* ignore # and beyond */		if (p = index(line, '#'))			*p = '\0';		len = strlen(line);		if (len <= 0) {			p = line;			continue;		}		/* trim trailing white space */		p = &line[len - 1];		while (p > line && isspace(*p))			*p-- = '\0';		if (p == line)			continue;		/* if continued, get next line */		if (*p == '\\')			continue;		return line;	}}mfs_get(mapname, me, w, wq, lp, lq)	struct mapent *me;	char *mapname, *w, *wq, **lp, **lq;{	struct mapfs *mfs, **mfsp;	char *wlp, *wlq;	char *hl, hostlist[1024], *hlq, hostlistq[1024];	char hostname[MAXHOSTNAMELEN+1];	char dirname[MAXPATHLEN+1], subdir[MAXPATHLEN+1];	char qbuff[MAXPATHLEN+1];	mfsp = &me->map_fs;	*mfsp = NULL;	while (*w && *w != '/') {		wlp = w ; wlq = wq;		getword(hostlist, hostlistq, &wlp, &wlq, ':');		if (!*hostlist)			goto bad_entry;		getword(dirname, qbuff, &wlp, &wlq, ':');		if (!*dirname)			goto bad_entry;		*subdir = '/'; *qbuff = ' ';		getword(subdir+1, qbuff+1, &wlp, &wlq, ':');		hl = hostlist ; hlq = hostlistq;		for (;;) {			getword(hostname, qbuff, &hl, &hlq, ',');			if (!*hostname)				break;			mfs = (struct mapfs *)malloc(sizeof *mfs);			if (mfs == NULL)				return -1;			bzero(mfs, sizeof *mfs);			*mfsp = mfs;			mfsp = &mfs->mfs_next;				mfs->mfs_host = strdup(hostname);			if (mfs->mfs_host == NULL)				return -1;			mfs->mfs_dir = strdup(dirname);

⌨️ 快捷键说明

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