⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mount_nfs.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#ifndef lintstatic  char sccsid[] = "@(#)mount_nfs.c 1.1 92/07/30 Copyright Sun Micro"; #endif/* *  mount_nfs.c - procedural interface to the NFS mount operation * * Copyright (c) 1985 Sun Microsystems, Inc. */# define NFSCLIENT#include <sys/param.h>#include <rpc/rpc.h>#include <rpc/pmap_prot.h>#include <sys/errno.h>#include <sys/time.h>#include <nfs/nfs.h>#include <sys/mount.h>#include <rpcsvc/mount.h>#include <sys/socket.h>#include <sys/stat.h>#include <netdb.h>#include <stdio.h>#include <mntent.h>#include <sys/vfs.h>#define MAXSLEEP 1  /* in seconds */char *sys_errlist[];int sys_nerr;/* * mount_nfs - mount a file system using NFS * * Returns: 0 if OK, 1 if error.   * 	The "error" string returns the error message. */mount_nfs(fsname, dir, error)	char *fsname;	char *dir;	char *error;{	struct sockaddr_in sin;	struct hostent *hp;	struct fhstatus fhs;	char host[256];	char *path;	int s = -1;	struct timeval timeout;	CLIENT *client;	enum clnt_stat rpc_stat;	int printed1 = 0;	int printed2 = 0;	unsigned winks = 0;  /* seconds of sleep time */	extern errno;	struct mntent mnt;	char *index();	FILE *mnted;	struct nfs_args args;	path = index(fsname, ':');	if (path==NULL) {		errprintf(error,"No host name in %s\n", fsname);		return(1);	}	*path++ = '\0';	strcpy(host,fsname);	path[-1] = ':';	if (*path == '\0') {	     /*	      * handle the special case of importing a root file system	      */	      strcpy(path,"/");	}	/*	 * Get server's address	 */	if ((hp = gethostbyname(host)) == NULL) {		errprintf(error,		    "mount %s: %s not in hosts database\n", fsname, host);		return (1);	}	/*	 * get fhandle of remote path from server's mountd.	 * We have to use short timeouts since otherwise our incoming	 * RPC call will time out.	 */	do {		bzero(&sin, sizeof(sin));		bcopy(hp->h_addr, (char *) & sin.sin_addr, hp->h_length);		sin.sin_family = AF_INET;		timeout.tv_usec = 0;		timeout.tv_sec = 5;		s = -1;		do {		    if (sin.sin_port==0) {		    	/*			 * Ask portmapper for port number since			 * the standard pmap_getport has too long a timeout			 */			int ps = -1;			struct pmap parms;			short port;			sin.sin_port = htons(PMAPPORT);			client = clntudp_create(&sin, PMAPPROG, PMAPVERS,				timeout, &ps);			if (client==NULL) {			    if (winks < MAXSLEEP)				winks++;			    else {			      errprintf(error,			          "can not map port for %s\n", host);			      return(1);			    }			    sleep(winks);			    sin.sin_port = 0;			    continue;			}			parms.pm_prog = MOUNTPROG;			parms.pm_vers = MOUNTVERS;			parms.pm_prot = IPPROTO_UDP;			parms.pm_port = 0;			if (clnt_call(client, PMAPPROC_GETPORT, xdr_pmap,			    &parms, xdr_u_short, &port, timeout)			       != RPC_SUCCESS) {			    if (winks < MAXSLEEP)				winks++;			    else {			      errprintf(error,			          "%s not responding to port map request\n", 				   host);			      clnt_destroy(client);			      return(1);			    }			    if (!printed1++) {				fprintf(stderr,			    "rexd portmap: %s not responding", host);				clnt_perror(client,"");				fprintf(stderr,"\r");			    }			    sleep(winks);			    clnt_destroy(client);			    client = NULL;			    close(ps);			    sin.sin_port = 0;			    continue;			}			sin.sin_port = ntohs(port);			clnt_destroy(client);			close(ps);		    }		    if ((client = clntudp_create(&sin,			    MOUNTPROG, MOUNTVERS, timeout, &s)) == NULL) {			if (winks < MAXSLEEP)				winks++;			else {			  if (rpc_createerr.cf_stat == RPC_PROGNOTREGISTERED)			      errprintf(error,			          "%s is not running a mount daemon\n", host);			  else			  	errprintf(error,				  "%s not responding to mount request\n", 				    host);			  return(1);			}			sleep(winks);			if (!printed1++) {				fprintf(stderr,			    "rexd mount: %s not responding", host);				clnt_pcreateerror("");				fprintf(stderr,"\r");			}		    }		} while (client == NULL);		client->cl_auth = authunix_create_default();		timeout.tv_usec = 0;		timeout.tv_sec = 25;		rpc_stat = clnt_call(client, MOUNTPROC_MNT, xdr_path, &path,		    xdr_fhstatus, &fhs, timeout);		if (rpc_stat != RPC_SUCCESS) {			if (!printed2++) {				fprintf(stderr,				    "rexd mount: %s not responding", host);				clnt_perror(client, "");				fprintf(stderr,"\r");			}		}		close(s);		clnt_destroy(client);	} while (rpc_stat == RPC_TIMEDOUT || fhs.fhs_status == ETIMEDOUT);	if (rpc_stat != RPC_SUCCESS || fhs.fhs_status) {		errno = fhs.fhs_status;		if (errno == EACCES) {			errprintf(error,			  "rexd mount: not in export list for %s\n",			    fsname);		}		return (1);	}	if (printed1 || printed2) {		fprintf(stderr, "rexd mount: %s OK\n", host);		fprintf(stderr,"\r");	}	/*	 * remote mount the fhandle on the local path.	 * We have to mount it soft otherwise the incoming RPC will time out.	 */	sin.sin_port = htons(NFS_PORT);	args.addr = &sin;	args.fh = (caddr_t) &fhs.fhs_fh;	args.flags = NFSMNT_HOSTNAME | NFSMNT_SOFT;	args.hostname = host;	if (mount("nfs", dir, M_NOSUID | M_NEWTYPE, &args) < 0) {		errprintf(error,"unable to mount %s on %s: %s\n",			fsname, dir, 			errno > sys_nerr ? "unknown error" : 			        sys_errlist[errno]);		return (1);	}	/*	 * update /etc/mtab	 */	mnt.mnt_fsname = fsname;	mnt.mnt_dir = dir;	mnt.mnt_type = MNTTYPE_NFS;	mnt.mnt_opts = "rw,noquota,soft";	mnt.mnt_freq = 0;	mnt.mnt_passno = 0;	newmtab(&mnt, (char *)NULL);	return (0);}#define UNMOUNTTRIES 6/* * umount_nfs - unmount a file system when finished */umount_nfs(fsname, dir)	char *fsname, *dir;{	char *p, *index();	struct sockaddr_in sin;	struct hostent *hp;	int s = -1;	struct timeval timeout;	CLIENT *client;	enum clnt_stat rpc_stat;	int count = 0;			/*	 * Give the filesystem time to become un-busy when unmounting.  	 * If child aborted and is takes a core dump, we may receive the	 * SIGCHLD before the core dump is completed.	 */	while (unmount(dir) == -1) {		if (errno != EBUSY) {			perror(dir);			return (1);		}		if (++count > UNMOUNTTRIES)			return (1);		sleep (10);        }	newmtab((struct mntent *)NULL, dir);	if ((p = index(fsname, ':')) == NULL)		return(1);	*p++ = 0;	if ((hp = gethostbyname(fsname)) == NULL) {		fprintf(stderr, "%s not in hosts database\n", fsname);		return(1);	}	bzero(&sin, sizeof(sin));	bcopy(hp->h_addr, (char *) & sin.sin_addr, hp->h_length);	sin.sin_family = AF_INET;	timeout.tv_usec = 0;	timeout.tv_sec = 10;	if ((client = clntudp_create(&sin, MOUNTPROG, MOUNTVERS,	    timeout, &s)) == NULL) {		clnt_pcreateerror("Warning on umount create:");		fprintf(stderr,"\r");		return(1);	}	client->cl_auth = authunix_create_default();	timeout.tv_usec = 0;	timeout.tv_sec = 25;	rpc_stat = clnt_call(client, MOUNTPROC_UMNT, xdr_path, &p,	    xdr_void, NULL, timeout);	if (rpc_stat != RPC_SUCCESS) {		clnt_perror(client, "Warning: umount:");		fprintf(stderr,"\r");		return(1);	}	return(0);}#define MAXTRIES 300newmtab(addmnt, deldir)	struct mntent *addmnt;	char *deldir;{	char *from = "/etc/omtabXXXXXX";	char *to = "/etc/nmtabXXXXXX";	FILE *fromp, *top;	int count = 0;	struct mntent *mnt;	struct stat statbuf;		mktemp(from);	while (rename(MOUNTED, from)) {		if (++count > MAXTRIES) {			fprintf(stderr, "newmtab: cat get %s lock\r\n", MOUNTED);			return;		}		sleep(1);	}	fromp = setmntent(from, "r");	mktemp(to);	top = setmntent(to, "w");	if (fromp == NULL || top == NULL) {		rename(from, MOUNTED);		fprintf(stderr, "newmtab: can't open %s or %s\r\n", from, to);		return;	}	while ((mnt = getmntent(fromp)) != NULL)		if (deldir == NULL || strcmp(mnt->mnt_dir, deldir) != 0)			addmntent(top, mnt);	if (addmnt)		addmntent(top, addmnt);	if (!fstat (fileno (fromp), &statbuf))		(void) fchmod (fileno (top), statbuf.st_mode);	endmntent(fromp);	endmntent(top);	if (rename(to, MOUNTED)) {		fprintf(stderr, "newmtab can not rename %s to %s\r\n", 			to, MOUNTED);		rename(from, MOUNTED);	}	unlink(from);}/* * parsefs - given a name of the form host:/path/name/for/file *	connect to the give host and look for the exported file system *	that matches.   * Returns: pointer to string containing the part of the pathname *	within the exported directory. *	Returns NULL on errors. */char *parsefs(fullname,error)	char *fullname;	char *error;{	char *dir, *subdir;        struct exports *ex = NULL;	int err;	int bestlen = 0;	int len, dirlen;	dir = index(fullname, ':');	if (dir == NULL) {		errprintf(error,"No host name in %s\n",fullname);		return(NULL);	}	*dir++ = '\0';	if (err = callrpc(fullname, MOUNTPROG, MOUNTVERS, MOUNTPROC_EXPORT,	    xdr_void, 0, xdr_exports, &ex)) {	    	if (err== (int)RPC_TIMEDOUT)			errprintf(error, "Host %s is not running mountd\n",				fullname);		else			errprintf(error,"RPC error %d with host %s\n",				err,fullname);		return(NULL);	}	dirlen = strlen(dir);	for (; ex; ex = ex->ex_next) {		len = strlen(ex->ex_name);		if (len > bestlen && len <= dirlen &&		    strncmp(dir, ex->ex_name, len) == 0 &&		    (dir[len] == '/' || dir[len] == '\0'))			bestlen = len;	}	if (bestlen == 0) {		errprintf(error, "%s not exported by %s\n", 			dir, fullname);		return(NULL);	}	if (dir[bestlen] == '\0')		subdir = &dir[bestlen];	else {		dir[bestlen] = '\0';		subdir = &dir[bestlen+1];	}	*--dir = ':';	return (subdir);}/* * errprintf will print a message to standard error channel, * and return the same string in the given message buffer. * We add an extra return character in case the console is in raw mode. */errprintf(s,p1,p2,p3,p4,p5,p6,p7)	char *s;{	sprintf(s,p1,p2,p3,p4,p5,p6,p7);	fprintf(stderr,"%s\r",s);}

⌨️ 快捷键说明

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