auto_node.c

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

C
705
字号
#ifndef lintstatic char *sccsid = "@(#)auto_node.c	4.1      (ULTRIX)        7/2/90";#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: *  *      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 <values.h>#include <sys/param.h>#include <sys/stat.h>#include <sys/file.h>#include <sys/time.h>#include <sys/dir.h>#include <rpc/types.h>#include <rpc/auth.h>#include <rpc/auth_unix.h>#include <rpc/xdr.h>#include <rpc/clnt.h>#include <netinet/in.h>#include <rpcsvc/yp_prot.h>#include <rpcsvc/ypclnt.h>#include "nfs_prot.h"#define NFSCLIENTtypedef nfs_fh fhandle_t;#include <sys/mount.h>#include <nfs/nfs_gfs.h>#include "automount.h"struct internal_fh {	int	fh_pid;	long	fh_time;	int	fh_num;};static int fh_cnt = 3;static right_pid = -1;static time_t right_time;struct queue fh_q_hash[FH_HASH_SIZE];new_fh(vnode)	struct vnode *vnode;{	time_t time();	register struct internal_fh *ifh =		(struct internal_fh *)(&vnode->vn_fh);	if (right_pid == -1) {		right_pid = getpid();		(void) time(&right_time);	}	ifh->fh_pid = right_pid;	ifh->fh_time = right_time;	ifh->fh_num = ++fh_cnt;	INSQUE(fh_q_hash[ifh->fh_num % FH_HASH_SIZE], vnode);}free_fh(vnode)	struct vnode *vnode;{	register struct internal_fh *ifh =		(struct internal_fh *)(&vnode->vn_fh);	REMQUE(fh_q_hash[ifh->fh_num % FH_HASH_SIZE], vnode);}struct vnode *fhtovn(fh)	nfs_fh *fh;{	register struct internal_fh *ifh = 		(struct internal_fh *)fh;	int num;	struct vnode *vnode;	if (ifh->fh_pid != right_pid || ifh->fh_time != right_time)		return ((struct vnode *)0);	num = ifh->fh_num;	vnode = HEAD(struct vnode, fh_q_hash[num % FH_HASH_SIZE]);	while (vnode) {		ifh = (struct internal_fh *)(&vnode->vn_fh);		if (num == ifh->fh_num)			return (vnode);		vnode = NEXT(struct vnode, vnode);	}	return ((struct vnode *)0);}intfileid(vnode)	struct vnode *vnode;{	register struct internal_fh *ifh =		(struct internal_fh *)(&vnode->vn_fh);	return (ifh->fh_num);}dirinit(mntpnt, map, opts, isdirect)	char *mntpnt, *map, *opts;{	struct autodir *dir;	struct filsys *fs;	register fattr *fa;	struct stat stbuf;	int mydir = 0;	struct link *link;	extern int verbose;	char *p;	for (dir = HEAD(struct autodir, dir_q); dir;	    dir = NEXT(struct autodir, dir))		if (strcmp(dir->dir_name, mntpnt) == 0)			return;	p = mntpnt + (strlen(mntpnt) - 1);	if (*p == '/')		*p = '\0';	/* trim trailing / */	if (*mntpnt != '/') {		syslog(LOG_ERR, "dir %s must start with '/'", mntpnt);		return;	}	if (check_hier(mntpnt)) {		(void) syslog(LOG_ERR, "hierarchical mountpoint: %s", mntpnt);		return;	}	/*	 * If it's a direct map then call dirinit	 * for every map entry. Try first for a local	 * file, then a YP map.	 */	if (strcmp(mntpnt, "/-") == 0) {		if (loaddirect_file(map, opts) < 0) {			(void) loaddirect_yp(map, map, opts);		}		return;	}	/*	 * Check whether there's something already mounted here	 */	for (fs = HEAD(struct filsys, fs_q); fs;		fs = NEXT(struct filsys, fs)) {		if (strcmp(fs->fs_mntpnt, mntpnt) == 0) {			(void) syslog(LOG_ERR,				"WARNING: %s:%s already mounted on %s",				fs->fs_host, fs->fs_dir, mntpnt);			break;		}	}	/*	 * Check whether the map (local file or YP) exists	 */	if (*map != '-' && access(map, R_OK) != 0) {		char *val ; int len;		if (yp_match(mydomain, map, "x",			1, &val, &len) == YPERR_MAP) {			if (verbose)				syslog(LOG_ERR, "%s: Not found", map);			return;		}	}	/*	 * Create a mount point if necessary	 */	if (stat(mntpnt, &stbuf) == 0) {		if ((stbuf.st_mode & S_IFMT) != S_IFDIR) {			syslog(LOG_ERR, "%s: Not a directory", mntpnt);			return;		}		if (verbose && !emptydir(mntpnt))			syslog(LOG_ERR, "WARNING: %s not empty!", mntpnt);	} else {		if (mkdir_r(mntpnt)) {			syslog(LOG_ERR, "Cannot create directory %s: %m", mntpnt);			return;		}		mydir = 1;	}	dir = (struct autodir *)malloc(sizeof *dir);	if (dir == NULL)		goto alloc_failed;	bzero((char *)dir, sizeof *dir);	dir->dir_name = strdup(mntpnt);	if (dir->dir_name == NULL) {		free((char *)dir);		goto alloc_failed;	}	dir->dir_map = strdup(map);	if (dir->dir_map == NULL) {		free((char *)dir->dir_name);		free((char *)dir);		goto alloc_failed;	}	dir->dir_opts = strdup(opts);	if (dir->dir_opts == NULL) {		free((char *)dir->dir_name);		free((char *)dir->dir_map);		free((char *)dir);		goto alloc_failed;	}	dir->dir_remove = mydir;	INSQUE(dir_q, dir);	new_fh(&dir->dir_vnode);	dir->dir_vnode.vn_data = (char *)dir;	fa = &dir->dir_vnode.vn_fattr;	fa->nlink = 1;	fa->uid = 0;	fa->gid = 0;	fa->size = 512;	fa->blocksize = 512;	fa->rdev = 0;	fa->blocks = 1;	fa->fsid = 0;	fa->fileid = fileid(&dir->dir_vnode);	(void) gettimeofday((struct timeval *)&fa->atime, (struct timezone *)0);	fa->mtime = fa->atime;	fa->ctime = fa->atime;	if (!isdirect) {		/* The mount point is a directory.		 * Set up links for it's "." and ".." entries.		 */		dir->dir_vnode.vn_type = VN_DIR;		fa->type = NFDIR;		fa->mode = NFSMODE_DIR + 0555;		link = makelink(dir, "." , NULL, "");		if (link == NULL)			goto alloc_failed;		link->link_death = MAXLONG;		link->link_vnode.vn_fattr.fileid = fileid(&link->link_vnode);		link = makelink(dir, "..", NULL, "");		if (link == NULL)			goto alloc_failed;		link->link_death = MAXLONG;		link->link_vnode.vn_fattr.fileid = fileid(&link->link_vnode);	} else {		/* The mount point is direct-mapped. Set it		 * up as a symlink to the real mount point.		 */		dir->dir_vnode.vn_type = VN_LINK;		fa->type = NFLNK;		fa->mode = NFSMODE_LNK + 0777;/* lebel - should be fixed  */		fa->size = 20;		link = (struct link *)malloc(sizeof *link);		if (link == NULL)			goto alloc_failed;		dir->dir_vnode.vn_data = (char *)link;		link->link_dir = dir;		link->link_name = strdup(mntpnt);		if (link->link_name == NULL) {			free((char *)link);			goto alloc_failed;		}		link->link_fs = NULL;		link->link_path = NULL;		link->link_death = 0;	}	return;alloc_failed:	syslog(LOG_ERR, "dirinit: memory allocation failed: %m");	return;}/* *  Check whether the mount point is a *  subdirectory or a parent directory *  of any previously mounted automount *  mount point. */intcheck_hier(mntpnt)	char *mntpnt;{	register struct autodir *dir;	register char *p, *q;	for (dir = TAIL(struct autodir, dir_q) ; dir ; 		dir = PREV(struct autodir, dir)) {		if (strcmp(dir->dir_map, "-null") == 0)			continue;		p = dir->dir_name;		q = mntpnt;		for (; *p == *q ; p++, q++)			if (*p == '\0')				break;		if (*p == '/' && *q == '\0')			return 1;		if (*p == '\0' && *q == '/')			return 1;		if (*p == '\0' && *q == '\0')			return 1;	}	return 0;	/* it's not a subdir or parent */}emptydir(name)	char *name;{	DIR *dirp;	struct direct *d;

⌨️ 快捷键说明

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