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