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 + -
显示快捷键?