auto_mount.c

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

C
893
字号
		 * mount of the same file system.		 */		for (mydir = 0, dir = HEAD(struct autodir, dir_q); dir;			dir = NEXT(struct autodir, dir)) {			if (strcmp(dir->dir_name, fs->fs_mntpnt) == 0) {				mydir = 1;				if (verbose)					syslog(LOG_ERR,					"%s:%s already mounted on %s",					host, fsname, fs->fs_mntpnt);				break;			}		}		if (mydir)			continue;/* lebel - should be comparing other opts too */		m2.mnt_opts = fs->fs_opts;		has1 = hasmntopt(&m1, MNTOPT_RO) != NULL;		has2 = hasmntopt(&m2, MNTOPT_RO) != NULL;		if (has1 != has2)			continue;		has1 = hasmntopt(&m1, MNTOPT_NOSUID) != NULL;		has2 = hasmntopt(&m2, MNTOPT_NOSUID) != NULL;		if (has1 != has2)			continue;		has1 = hasmntopt(&m1, MNTOPT_SOFT) != NULL;		has2 = hasmntopt(&m2, MNTOPT_SOFT) != NULL;		if (has1 != has2)			continue;		has1 = hasmntopt(&m1, MNTOPT_INT) != NULL;		has2 = hasmntopt(&m2, MNTOPT_INT) != NULL;		if (has1 != has2)			continue;		return (fs);	}	return(0);}nfsunmount(fs)	struct filsys *fs;{	struct sockaddr_in sin;	struct timeval timeout;	CLIENT *client;	enum clnt_stat rpc_stat;	int s;	sin = fs->fs_addr;	/*	 * Port number of "fs->fs_addr" is NFS port number; make port	 * number 0, so "clntudp_create" finds port number of mount	 * service.	 */	sin.sin_port = 0;	s = RPC_ANYSOCK;	timeout.tv_usec = 0;	timeout.tv_sec = 10;	if ((client = clntudp_create(&sin, MOUNTPROG, MOUNTVERS,	    timeout, &s)) == NULL) {		syslog(LOG_WARNING, "%s:%s %s",		    fs->fs_host, fs->fs_dir,		    clnt_spcreateerror("server not responding"));		return;	}#ifdef OLDMOUNT	if (bindresvport(s, NULL))		syslog(LOG_ERR, "Warning: cannot do local bind");#endif	client->cl_auth = authunix_create_default();	timeout.tv_usec = 0;	timeout.tv_sec = 25;	rpc_stat = clnt_call(client, MOUNTPROC_UMNT, xdr_path, &fs->fs_dir,	    xdr_void, (char *)NULL, timeout);	(void) close(s);	AUTH_DESTROY(client->cl_auth);	clnt_destroy(client);	if (rpc_stat != RPC_SUCCESS)		syslog(LOG_WARNING, "%s", clnt_sperror(client, "unmount"));}enum clnt_statpingmount(hostaddr)	struct in_addr hostaddr;{	struct timeval tottime;	struct sockaddr_in server_addr;	enum clnt_stat clnt_stat;	u_long port;	static struct in_addr goodhost, deadhost;	static time_t goodtime, deadtime;	int cache_time = 60;  /* sec */	if (goodtime > time_now && hostaddr.s_addr == goodhost.s_addr)			return RPC_SUCCESS;	if (deadtime > time_now && hostaddr.s_addr == deadhost.s_addr)			return RPC_TIMEDOUT;	if (trace > 1)		fprintf(stderr, "ping %s ", inet_ntoa(hostaddr));	tottime.tv_sec = 10;	tottime.tv_usec = 0;	/* 	 * We use the pmap_rmtcall interface because the normal	 * portmapper has a wired-in 60 second timeout	 */	server_addr.sin_family = AF_INET;	server_addr.sin_addr = hostaddr;	server_addr.sin_port = 0;	clnt_stat = pmap_rmtcall(&server_addr, MOUNTPROG, MOUNTVERS, NULLPROC,			xdr_void, 0, xdr_void, 0, tottime, &port);	if (clnt_stat == RPC_SUCCESS) {		goodhost = hostaddr;		goodtime = time_now + cache_time;	} else {		deadhost = hostaddr;		deadtime = time_now + cache_time;	}	if (trace > 1)		fprintf(stderr, "%s\n", clnt_stat == RPC_SUCCESS ?			"OK" : "NO RESPONSE");	return (clnt_stat);}struct in_addr gotaddr;/* ARGSUSED */catchfirst(ignore, raddr)	struct sockaddr_in *raddr;{	gotaddr = raddr->sin_addr;	return (1);	/* first one ends search */}/* * ping a bunch of hosts at once and find out who * responds first */struct in_addrtrymany(addrs, timeout)	struct in_addr *addrs;	int timeout;{	enum clnt_stat many_cast();	enum clnt_stat clnt_stat;	if (trace > 1) {		register struct in_addr *a;		fprintf(stderr, "many_cast: ");		for (a = addrs ; a->s_addr ; a++)			fprintf(stderr, "%s ", inet_ntoa(*a));		fprintf(stderr, "\n");	}			gotaddr.s_addr = 0;	clnt_stat = many_cast(addrs, MOUNTPROG, MOUNTVERS, NULLPROC,			xdr_void, 0, xdr_void, 0, catchfirst, timeout);	if (trace > 1) {		fprintf(stderr, "many_cast: got %s\n",			(int) clnt_stat ? "no response" : inet_ntoa(gotaddr));	}	if (clnt_stat)		syslog(LOG_ERR, "trymany: servers not responding: %s",			clnt_sperrno(clnt_stat));	return (gotaddr);}nfsstatnfsmount(host, hostaddr, dir, mntpnt, opts, fsp)	char *host, *dir, *mntpnt, *opts;	struct in_addr hostaddr;	struct filsys **fsp;{	struct filsys *fs;	char remname[MAXPATHLEN];	struct mntent m;	struct nfs_gfs_mount args;	int flags;	struct sockaddr_in sin;	static struct fhstatus fhs;	struct timeval timeout;	CLIENT *client;	enum clnt_stat rpc_stat;	enum clnt_stat pingmount();	int s;	u_short port;	nfsstat status;	struct stat stbuf;	struct fs_data fsdata;	if (lstat(mntpnt, &stbuf) < 0) {		syslog(LOG_ERR, "Couldn't stat %s: %m", mntpnt);		return (NFSERR_NOENT);	}	if ((stbuf.st_mode & S_IFMT) == S_IFLNK) {		if (readlink(mntpnt, remname, sizeof remname) < 0)			return (NFSERR_NOENT);		if (remname[0] == '/') {			syslog(LOG_ERR,				"%s -> %s from %s: absolute symbolic link",				mntpnt, remname, host);			return (NFSERR_NOENT);		}	}	/*	 * get fhandle of remote path from server's mountd	 */	(void) sprintf(remname, "%s:%s", host, dir);	bzero((char *)&sin, sizeof(sin));	sin.sin_family = AF_INET;	sin.sin_addr.s_addr = hostaddr.s_addr;	timeout.tv_usec = 0;	timeout.tv_sec = mount_timeout;	s = RPC_ANYSOCK;	if ((client = clntudp_create(&sin, MOUNTPROG, MOUNTVERS,	    timeout, &s)) == NULL) {		syslog(LOG_ERR, "%s %s", remname,		    clnt_spcreateerror("server not responding"));		return (NFSERR_NOENT);	}#ifdef OLDMOUNT	if (bindresvport(s, NULL))		syslog(LOG_ERR, "Warning: cannot do local bind");#endif	client->cl_auth = authunix_create_default();	timeout.tv_usec = 0;	timeout.tv_sec = mount_timeout;	rpc_stat = clnt_call(client, MOUNTPROC_MNT, xdr_path, &dir,	    xdr_fhstatus, &fhs, timeout);	if (rpc_stat != RPC_SUCCESS) {		/*		 * Given the way "clnt_sperror" works, the "%s" immediately		 * following the "not responding" is correct.		 */		syslog(LOG_ERR, "%s server not responding%s", remname,		    clnt_sperror(client, ""));		(void) close(s);		clnt_destroy(client);		return (NFSERR_NOENT);	}	(void) close(s);	AUTH_DESTROY(client->cl_auth);	clnt_destroy(client);	if (errno = fhs.fhs_status)  {                if (errno == EACCES) {			status = NFSERR_ACCES;                } else {			syslog(LOG_ERR, "%s: %m", remname);			status = NFSERR_IO;                }                return (status);        }        	/*	 * set mount args	 */	args.fh = (fhandle_t *)&fhs.fhs_fh;	args.hostname = host;	args.flags = 0;	args.flags |= (NFSMNT_HOSTNAME | NFSMNT_INT);	args.gfs_flags = 0;	args.addr = &sin;	m.mnt_opts = opts;	args.optstr = m.mnt_opts;	args.pg_thresh = SIXTYFOUR;        args.acregmin = NFSAC_REGMIN;        args.acregmax = NFSAC_REGMAX;        args.acdirmin = NFSAC_DIRMIN;        args.acdirmax = NFSAC_DIRMAX;	/* ignore sun secure mount option */	if (hasmntopt(&m, MNTOPT_SECURE) != NULL) {		syslog(LOG_ERR, "Mount of %s on %s; secure option specified: %m", remname, mntpnt);		return (NFSERR_IO);	}	if (hasmntopt(&m, MNTOPT_SOFT) != NULL) {		args.flags |= NFSMNT_SOFT;	}	if (hasmntopt(&m, MNTOPT_INT) != NULL) {		args.flags |= NFSMNT_INT;	}	if (hasmntopt(&m, MNTOPT_NOEXEC) != NULL) {		args.gfs_flags |= M_NOEXEC;	}	if (hasmntopt(&m, MNTOPT_NOSUID) != NULL) {		args.gfs_flags |= M_NOSUID;	}	if (hasmntopt(&m, MNTOPT_NODEV) != NULL) {		args.gfs_flags |= M_NODEV;	}	if (hasmntopt(&m, MNTOPT_NOAC) != NULL) {		args.flags |= NFSMNT_NOAC;	}	if (port = nopt(&m, "port")) {		sin.sin_port = htons(port);	} else {		sin.sin_port = htons(NFS_PORT);	/* XXX should use portmapper */	}	if (args.rsize = nopt(&m, "rsize")) {		args.flags |= NFSMNT_RSIZE;	}	if (args.wsize = nopt(&m, "wsize")) {		args.flags |= NFSMNT_WSIZE;	}	if (args.timeo = nopt(&m, "timeo")) {		args.flags |= NFSMNT_TIMEO;	}	if (args.retrans = nopt(&m, "retrans")) {		args.flags |= NFSMNT_RETRANS;	}	flags = 0;	flags |= (hasmntopt(&m, MNTOPT_RO) == NULL) ? 0 : M_RONLY;	if (trace > 1) {		fprintf(stderr, "mount %s %s (%s)\n",			remname, mntpnt, opts);	}#ifdef OLDMOUNT#define MOUNT_NFS 1	if (mount(remname, mntpnt, flags, 0x05, &args)) {#else	if (mount(remname, mntpnt, flags, 0x05, &args)) {#endif		syslog(LOG_ERR, "Mount of %s on %s: %m", remname, mntpnt);		return (NFSERR_IO);	}	if (trace > 1) {		fprintf(stderr, "mount %s OK\n", remname);	}	if (*fsp)		fs = *fsp;	else {		fs = alloc_fs(host, dir, mntpnt, opts);		if (fs == NULL)			return (NFSERR_NOSPC);	}	if (getmnt(0, &fsdata, 0, NOSTAT_ONE, mntpnt) < 1) {		/* Couldn't get dev number; we'll try later */		fs->fs_dev = -1;	}	else {		/* Got it; save it away for the umount	    */		fs->fs_dev = fsdata.fd_req.dev;	}	fs->fs_type = MNTTYPE_NFS;	fs->fs_mine = 1;	fs->fs_nfsargs = args;	fs->fs_mflags = flags;	fs->fs_nfsargs.hostname = fs->fs_host;	fs->fs_nfsargs.addr = &fs->fs_addr;	fs->fs_nfsargs.fh = (fhandle_t *)&fs->fs_rootfh;	fs->fs_addr = sin;	bcopy(&fhs.fhs_fh, &fs->fs_rootfh, sizeof fs->fs_rootfh);	*fsp = fs;	return (NFS_OK);}nfsstatremount(fs)	struct filsys *fs;{	char remname[1024];	if (fs->fs_nfsargs.fh == 0) 		return nfsmount(fs->fs_host, fs->fs_addr.sin_addr, fs->fs_dir,				fs->fs_mntpnt, fs->fs_opts, &fs);	(void) sprintf(remname, "%s:%s", fs->fs_host, fs->fs_dir);	if (trace > 1) {		fprintf(stderr, "remount %s %s (%s)\n",			remname, fs->fs_mntpnt, fs->fs_opts);	}#ifdef OLDMOUNT	if (mount(remname, fs->fs_mntpnt, fs->fs_mflags, 0x05, &fs->fs_nfsargs)) {#else	if (mount(remname, fs->fs_mntpnt, fs->fs_mflags, 0x05, &fs->fs_nfsargs)) {#endif		syslog(LOG_ERR, "Remount of %s on %s: %m", remname,		    fs->fs_mntpnt);		return (NFSERR_IO);	}	if (trace > 1) {		fprintf(stderr, "remount %s OK\n", remname);	}	return (NFS_OK);}/* * Return the value of a numeric option of the form foo=x, if * option is not found or is malformed, return 0. */nopt(mnt, opt)	struct mntent *mnt;	char *opt;{	int val = 0;	char *equal;	char *str;	if (str = (char *)hasmntopt(mnt, opt)) {		if (equal = index(str, '=')) {			val = atoi(&equal[1]);		} else {			syslog(LOG_ERR, "Bad numeric option '%s'", str);		}	}	return (val);}same_opts(opts1, opts2)	char *opts1, *opts2;{	int has1, has2;	struct mntent m1, m2;	m1.mnt_opts = opts1;	m2.mnt_opts = opts2;	has1 = hasmntopt(&m1, MNTOPT_RO) != NULL;	has2 = hasmntopt(&m2, MNTOPT_RO) != NULL;	if (has1 != has2) return(0);	has1 = hasmntopt(&m1, MNTOPT_NOSUID) != NULL;	has2 = hasmntopt(&m2, MNTOPT_NOSUID) != NULL;	if (has1 != has2) return(0);	has1 = hasmntopt(&m1, MNTOPT_SOFT) != NULL;	has2 = hasmntopt(&m2, MNTOPT_SOFT) != NULL;	if (has1 != has2) return(0);	has1 = hasmntopt(&m1, MNTOPT_INT) != NULL;	has2 = hasmntopt(&m2, MNTOPT_INT) != NULL;	if (has1 != has2) return(0);	return(1);}

⌨️ 快捷键说明

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