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

📄 mountd.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	*naddrp = (char *)NULL;	if (debug)		fprintf(stderr, "got host %s\n", hp->h_name);	return (0);}/* * Free up an exports list component */voidfree_exp(ep)	struct exportlist *ep;{	if (ep->ex_defdir) {		free_host(ep->ex_defdir->dp_hosts);		free((caddr_t)ep->ex_defdir);	}	if (ep->ex_fsdir)		free(ep->ex_fsdir);	free_dir(ep->ex_dirl);	free((caddr_t)ep);}/* * Free hosts. */voidfree_host(hp)	struct hostlist *hp;{	struct hostlist *hp2;	while (hp) {		hp2 = hp;		hp = hp->ht_next;		free((caddr_t)hp2);	}}struct hostlist *get_ht(){	struct hostlist *hp;	hp = (struct hostlist *)malloc(sizeof (struct hostlist));	if (hp == (struct hostlist *)NULL)		out_of_mem();	hp->ht_next = (struct hostlist *)NULL;	return (hp);}#ifdef ISO/* * Translate an iso address. */get_isoaddr(cp, grp)	char *cp;	struct grouplist *grp;{	struct iso_addr *isop;	struct sockaddr_iso *isoaddr;	if (grp->gr_type != GT_NULL)		return (1);	if ((isop = iso_addr(cp)) == NULL) {		syslog(LOG_ERR,		    "iso_addr failed, ignored");		return (1);	}	isoaddr = (struct sockaddr_iso *)	    malloc(sizeof (struct sockaddr_iso));	if (isoaddr == (struct sockaddr_iso *)NULL)		out_of_mem();	bzero((caddr_t)isoaddr, sizeof (struct sockaddr_iso));	bcopy((caddr_t)isop, (caddr_t)&isoaddr->siso_addr,		sizeof (struct iso_addr));	isoaddr->siso_len = sizeof (struct sockaddr_iso);	isoaddr->siso_family = AF_ISO;	grp->gr_type = GT_ISO;	grp->gr_ptr.gt_isoaddr = isoaddr;	return (0);}#endif	/* ISO *//* * Out of memory, fatal */voidout_of_mem(){	syslog(LOG_ERR, "Out of memory");	exit(2);}/* * Do the mount syscall with the update flag to push the export info into * the kernel. */intdo_mount(ep, grp, exflags, anoncrp, dirp, dirplen, fsb)	struct exportlist *ep;	struct grouplist *grp;	int exflags;	struct ucred *anoncrp;	char *dirp;	int dirplen;	struct statfs *fsb;{	char *cp = (char *)NULL;	u_long **addrp;	int done;	char savedc = '\0';	struct sockaddr_in sin, imask;	union {		struct ufs_args ua;		struct iso_args ia;		struct mfs_args ma;	} args;	u_long net;	args.ua.fspec = 0;	args.ua.export.ex_flags = exflags;	args.ua.export.ex_anon = *anoncrp;	bzero((char *)&sin, sizeof(sin));	bzero((char *)&imask, sizeof(imask));	sin.sin_family = AF_INET;	sin.sin_len = sizeof(sin);	imask.sin_family = AF_INET;	imask.sin_len = sizeof(sin);	if (grp->gr_type == GT_HOST)		addrp = (u_long **)grp->gr_ptr.gt_hostent->h_addr_list;	else		addrp = (u_long **)NULL;	done = FALSE;	while (!done) {		switch (grp->gr_type) {		case GT_HOST:			if (addrp) {				sin.sin_addr.s_addr = **addrp;				args.ua.export.ex_addrlen = sizeof(sin);			} else				args.ua.export.ex_addrlen = 0;			args.ua.export.ex_addr = (struct sockaddr *)&sin;			args.ua.export.ex_masklen = 0;			break;		case GT_NET:			if (grp->gr_ptr.gt_net.nt_mask)			    imask.sin_addr.s_addr = grp->gr_ptr.gt_net.nt_mask;			else {			    net = ntohl(grp->gr_ptr.gt_net.nt_net);			    if (IN_CLASSA(net))				imask.sin_addr.s_addr = inet_addr("255.0.0.0");			    else if (IN_CLASSB(net))				imask.sin_addr.s_addr =				    inet_addr("255.255.0.0");			    else				imask.sin_addr.s_addr =				    inet_addr("255.255.255.0");			    grp->gr_ptr.gt_net.nt_mask = imask.sin_addr.s_addr;			}			sin.sin_addr.s_addr = grp->gr_ptr.gt_net.nt_net;			args.ua.export.ex_addr = (struct sockaddr *)&sin;			args.ua.export.ex_addrlen = sizeof (sin);			args.ua.export.ex_mask = (struct sockaddr *)&imask;			args.ua.export.ex_masklen = sizeof (imask);			break;#ifdef ISO		case GT_ISO:			args.ua.export.ex_addr =				(struct sockaddr *)grp->gr_ptr.gt_isoaddr;			args.ua.export.ex_addrlen =				sizeof(struct sockaddr_iso);			args.ua.export.ex_masklen = 0;			break;#endif	/* ISO */		default:			syslog(LOG_ERR, "Bad grouptype");			if (cp)				*cp = savedc;			return (1);		};		/*		 * XXX:		 * Maybe I should just use the fsb->f_mntonname path instead		 * of looping back up the dirp to the mount point??		 * Also, needs to know how to export all types of local		 * exportable file systems and not just MOUNT_UFS.		 */		while (mount(fsb->f_type, dirp,		       fsb->f_flags | MNT_UPDATE, (caddr_t)&args) < 0) {			if (cp)				*cp-- = savedc;			else				cp = dirp + dirplen - 1;			if (errno == EPERM) {				syslog(LOG_ERR,				   "Can't change attributes for %s.\n", dirp);				return (1);			}			if (opt_flags & OP_ALLDIRS) {				syslog(LOG_ERR, "Not root dir");				return (1);			}			/* back up over the last component */			while (*cp == '/' && cp > dirp)				cp--;			while (*(cp - 1) != '/' && cp > dirp)				cp--;			if (cp == dirp) {				if (debug)					fprintf(stderr,"mnt unsucc\n");				syslog(LOG_ERR, "Can't export %s", dirp);				return (1);			}			savedc = *cp;			*cp = '\0';		}		if (addrp) {			++addrp;			if (*addrp == (u_long *)NULL)				done = TRUE;		} else			done = TRUE;	}	if (cp)		*cp = savedc;	return (0);}/* * Translate a net address. */intget_net(cp, net, maskflg)	char *cp;	struct netmsk *net;	int maskflg;{	struct netent *np;	long netaddr;	struct in_addr inetaddr, inetaddr2;	char *name;	if (np = getnetbyname(cp))		inetaddr = inet_makeaddr(np->n_net, 0);	else if (isdigit(*cp)) {		if ((netaddr = inet_network(cp)) == -1)			return (1);		inetaddr = inet_makeaddr(netaddr, 0);		/*		 * Due to arbritrary subnet masks, you don't know how many		 * bits to shift the address to make it into a network,		 * however you do know how to make a network address into		 * a host with host == 0 and then compare them.		 * (What a pest)		 */		if (!maskflg) {			setnetent(0);			while (np = getnetent()) {				inetaddr2 = inet_makeaddr(np->n_net, 0);				if (inetaddr2.s_addr == inetaddr.s_addr)					break;			}			endnetent();		}	} else		return (1);	if (maskflg)		net->nt_mask = inetaddr.s_addr;	else {		if (np)			name = np->n_name;		else			name = inet_ntoa(inetaddr);		net->nt_name = (char *)malloc(strlen(name) + 1);		if (net->nt_name == (char *)NULL)			out_of_mem();		strcpy(net->nt_name, name);		net->nt_net = inetaddr.s_addr;	}	return (0);}/* * Parse out the next white space separated field */voidnextfield(cp, endcp)	char **cp;	char **endcp;{	char *p;	p = *cp;	while (*p == ' ' || *p == '\t')		p++;	if (*p == '\n' || *p == '\0')		*cp = *endcp = p;	else {		*cp = p++;		while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0')			p++;		*endcp = p;	}}/* * Get an exports file line. Skip over blank lines and handle line * continuations. */intget_line(){	char *p, *cp;	int len;	int totlen, cont_line;	/*	 * Loop around ignoring blank lines and getting all continuation lines.	 */	p = line;	totlen = 0;	do {		if (fgets(p, LINESIZ - totlen, exp_file) == NULL)			return (0);		len = strlen(p);		cp = p + len - 1;		cont_line = 0;		while (cp >= p &&		    (*cp == ' ' || *cp == '\t' || *cp == '\n' || *cp == '\\')) {			if (*cp == '\\')				cont_line = 1;			cp--;			len--;		}		*++cp = '\0';		if (len > 0) {			totlen += len;			if (totlen >= LINESIZ) {				syslog(LOG_ERR, "Exports line too long");				exit(2);			}			p = cp;		}	} while (totlen == 0 || cont_line);	return (1);}/* * Parse a description of a credential. */voidparsecred(namelist, cr)	char *namelist;	struct ucred *cr;{	char *name;	int cnt;	char *names;	struct passwd *pw;	struct group *gr;	int ngroups, groups[NGROUPS + 1];	/*	 * Set up the unpriviledged user.	 */	cr->cr_ref = 1;	cr->cr_uid = -2;	cr->cr_groups[0] = -2;	cr->cr_ngroups = 1;	/*	 * Get the user's password table entry.	 */	names = strsep(&namelist, " \t\n");	name = strsep(&names, ":");	if (isdigit(*name) || *name == '-')		pw = getpwuid(atoi(name));	else		pw = getpwnam(name);	/*	 * Credentials specified as those of a user.	 */	if (names == NULL) {		if (pw == NULL) {			syslog(LOG_ERR, "Unknown user: %s", name);			return;		}		cr->cr_uid = pw->pw_uid;		ngroups = NGROUPS + 1;		if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups))			syslog(LOG_ERR, "Too many groups");		/*		 * Convert from int's to gid_t's and compress out duplicate		 */		cr->cr_ngroups = ngroups - 1;		cr->cr_groups[0] = groups[0];		for (cnt = 2; cnt < ngroups; cnt++)			cr->cr_groups[cnt - 1] = groups[cnt];		return;	}	/*	 * Explicit credential specified as a colon separated list:	 *	uid:gid:gid:...	 */	if (pw != NULL)		cr->cr_uid = pw->pw_uid;	else if (isdigit(*name) || *name == '-')		cr->cr_uid = atoi(name);	else {		syslog(LOG_ERR, "Unknown user: %s", name);		return;	}	cr->cr_ngroups = 0;	while (names != NULL && *names != '\0' && cr->cr_ngroups < NGROUPS) {		name = strsep(&names, ":");		if (isdigit(*name) || *name == '-') {			cr->cr_groups[cr->cr_ngroups++] = atoi(name);		} else {			if ((gr = getgrnam(name)) == NULL) {				syslog(LOG_ERR, "Unknown group: %s", name);				continue;			}			cr->cr_groups[cr->cr_ngroups++] = gr->gr_gid;		}	}	if (names != NULL && *names != '\0' && cr->cr_ngroups == NGROUPS)		syslog(LOG_ERR, "Too many groups");}#define	STRSIZ	(RPCMNT_NAMELEN+RPCMNT_PATHLEN+50)/* * Routines that maintain the remote mounttab */voidget_mountlist(){	struct mountlist *mlp, **mlpp;	char *eos, *dirp;	int len;	char str[STRSIZ];	FILE *mlfile;	if ((mlfile = fopen(_PATH_RMOUNTLIST, "r")) == NULL) {		syslog(LOG_ERR, "Can't open %s", _PATH_RMOUNTLIST);		return;	}	mlpp = &mlhead;	while (fgets(str, STRSIZ, mlfile) != NULL) {		if ((dirp = index(str, '\t')) == NULL &&		    (dirp = index(str, ' ')) == NULL)			continue;		mlp = (struct mountlist *)malloc(sizeof (*mlp));		len = dirp-str;		if (len > RPCMNT_NAMELEN)			len = RPCMNT_NAMELEN;		bcopy(str, mlp->ml_host, len);		mlp->ml_host[len] = '\0';		while (*dirp == '\t' || *dirp == ' ')			dirp++;		if ((eos = index(dirp, '\t')) == NULL &&		    (eos = index(dirp, ' ')) == NULL &&		    (eos = index(dirp, '\n')) == NULL)			len = strlen(dirp);		else			len = eos-dirp;		if (len > RPCMNT_PATHLEN)			len = RPCMNT_PATHLEN;		bcopy(dirp, mlp->ml_dirp, len);		mlp->ml_dirp[len] = '\0';		mlp->ml_next = (struct mountlist *)NULL;		*mlpp = mlp;		mlpp = &mlp->ml_next;	}	fclose(mlfile);}voiddel_mlist(hostp, dirp)	char *hostp, *dirp;{	struct mountlist *mlp, **mlpp;	struct mountlist *mlp2;	FILE *mlfile;	int fnd = 0;	mlpp = &mlhead;	mlp = mlhead;	while (mlp) {		if (!strcmp(mlp->ml_host, hostp) &&		    (!dirp || !strcmp(mlp->ml_dirp, dirp))) {			fnd = 1;			mlp2 = mlp;			*mlpp = mlp = mlp->ml_next;			free((caddr_t)mlp2);		} else {			mlpp = &mlp->ml_next;			mlp = mlp->ml_next;		}	}	if (fnd) {		if ((mlfile = fopen(_PATH_RMOUNTLIST, "w")) == NULL) {			syslog(LOG_ERR,"Can't update %s", _PATH_RMOUNTLIST);			return;		}		mlp = mlhead;		while (mlp) {			fprintf(mlfile, "%s %s\n", mlp->ml_host, mlp->ml_dirp);			mlp = mlp->ml_next;		}		fclose(mlfile);	}}voidadd_mlist(hostp, dirp)	char *hostp, *dirp;{	struct mountlist *mlp, **mlpp;	FILE *mlfile;	mlpp = &mlhead;	mlp = mlhead;	while (mlp) {		if (!strcmp(mlp->ml_host, hostp) && !strcmp(mlp->ml_dirp, dirp))			return;		mlpp = &mlp->ml_next;		mlp = mlp->ml_next;	}	mlp = (struct mountlist *)malloc(sizeof (*mlp));	strncpy(mlp->ml_host, hostp, RPCMNT_NAMELEN);	mlp->ml_host[RPCMNT_NAMELEN] = '\0';	strncpy(mlp->ml_dirp, dirp, RPCMNT_PATHLEN);	mlp->ml_dirp[RPCMNT_PATHLEN] = '\0';	mlp->ml_next = (struct mountlist *)NULL;	*mlpp = mlp;	if ((mlfile = fopen(_PATH_RMOUNTLIST, "a")) == NULL) {		syslog(LOG_ERR, "Can't update %s", _PATH_RMOUNTLIST);		return;	}	fprintf(mlfile, "%s %s\n", mlp->ml_host, mlp->ml_dirp);	fclose(mlfile);}/* * This function is called via. SIGTERM when the system is going down. * It sends a broadcast RPCMNT_UMNTALL. */voidsend_umntall(){	(void) clnt_broadcast(RPCPROG_MNT, RPCMNT_VER1, RPCMNT_UMNTALL,		xdr_void, (caddr_t)0, xdr_void, (caddr_t)0, umntall_each);	exit(0);}intumntall_each(resultsp, raddr)	caddr_t resultsp;	struct sockaddr_in *raddr;{	return (1);}/* * Free up a group list. */voidfree_grp(grp)	struct grouplist *grp;{	char **addrp;	if (grp->gr_type == GT_HOST) {		if (grp->gr_ptr.gt_hostent->h_name) {			addrp = grp->gr_ptr.gt_hostent->h_addr_list;			while (addrp && *addrp)				free(*addrp++);			free((caddr_t)grp->gr_ptr.gt_hostent->h_addr_list);			free(grp->gr_ptr.gt_hostent->h_name);		}		free((caddr_t)grp->gr_ptr.gt_hostent);	} else if (grp->gr_type == GT_NET) {		if (grp->gr_ptr.gt_net.nt_name)			free(grp->gr_ptr.gt_net.nt_name);	}#ifdef ISO	else if (grp->gr_type == GT_ISO)		free((caddr_t)grp->gr_ptr.gt_isoaddr);#endif	free((caddr_t)grp);}#ifdef DEBUGvoidSYSLOG(int pri, const char *fmt, ...){	va_list ap;	va_start(ap, fmt);	vfprintf(stderr, fmt, ap);	va_end(ap);}#endif /* DEBUG *//* * Check options for consistency. */intcheck_options(dp)	struct dirlist *dp;{	if (dp == (struct dirlist *)NULL)	    return (1);	if ((opt_flags & (OP_MAPROOT | OP_MAPALL)) == (OP_MAPROOT | OP_MAPALL) ||	    (opt_flags & (OP_MAPROOT | OP_KERB)) == (OP_MAPROOT | OP_KERB) ||	    (opt_flags & (OP_MAPALL | OP_KERB)) == (OP_MAPALL | OP_KERB)) {	    syslog(LOG_ERR, "-mapall, -maproot and -kerb mutually exclusive");	    return (1);	}	if ((opt_flags & OP_MASK) && (opt_flags & OP_NET) == 0) {	    syslog(LOG_ERR, "-mask requires -net");	    return (1);	}	if ((opt_flags & (OP_NET | OP_ISO)) == (OP_NET | OP_ISO)) {	    syslog(LOG_ERR, "-net and -iso mutually exclusive");	    return (1);	}	if ((opt_flags & OP_ALLDIRS) && dp->dp_left) {	    syslog(LOG_ERR, "-alldir has multiple directories");	    return (1);	}	return (0);}/* * Check an absolute directory path for any symbolic links. Return true * if no symbolic links are found. */intcheck_dirpath(dirp)	char *dirp;{	char *cp;	int ret = 1;	struct stat sb;	cp = dirp + 1;	while (*cp && ret) {		if (*cp == '/') {			*cp = '\0';			if (lstat(dirp, &sb) < 0 ||				(sb.st_mode & S_IFMT) != S_IFDIR)				ret = 0;			*cp = '/';		}		cp++;	}	if (lstat(dirp, &sb) < 0 ||		(sb.st_mode & S_IFMT) != S_IFDIR)		ret = 0;	return (ret);}

⌨️ 快捷键说明

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