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

📄 mountd.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
			fprintf(stderr,"Got line %s\n",line);		cp = line;		nextfield(&cp, &endcp);		if (*cp == '#')			goto nextline;		/*		 * Set defaults.		 */		has_host = FALSE;		anon = def_anon;		exflags = MNT_EXPORTED;		got_nondir = 0;		opt_flags = 0;		ep = (struct exportlist *)NULL;		/*		 * Create new exports list entry		 */		len = endcp-cp;		tgrp = grp = get_grp();		while (len > 0) {			if (len > RPCMNT_NAMELEN) {			    getexp_err(ep, tgrp);			    goto nextline;			}			if (*cp == '-') {			    if (ep == (struct exportlist *)NULL) {				getexp_err(ep, tgrp);				goto nextline;			    }			    if (debug)				fprintf(stderr, "doing opt %s\n", cp);			    got_nondir = 1;			    if (do_opt(&cp, &endcp, ep, grp, &has_host,				&exflags, &anon)) {				getexp_err(ep, tgrp);				goto nextline;			    }			} else if (*cp == '/') {			    savedc = *endcp;			    *endcp = '\0';			    if (check_dirpath(cp) &&				statfs(cp, &fsb) >= 0) {				if (got_nondir) {				    syslog(LOG_ERR, "Dirs must be first");				    getexp_err(ep, tgrp);				    goto nextline;				}				if (ep) {				    if (ep->ex_fs.val[0] != fsb.f_fsid.val[0] ||					ep->ex_fs.val[1] != fsb.f_fsid.val[1]) {					getexp_err(ep, tgrp);					goto nextline;				    }				} else {				    /*				     * See if this directory is already				     * in the list.				     */				    ep = ex_search(&fsb.f_fsid);				    if (ep == (struct exportlist *)NULL) {					ep = get_exp();					ep->ex_fs = fsb.f_fsid;					ep->ex_fsdir = (char *)					    malloc(strlen(fsb.f_mntonname) + 1);					if (ep->ex_fsdir)					    strcpy(ep->ex_fsdir,						fsb.f_mntonname);					else					    out_of_mem();					if (debug)					  fprintf(stderr,					      "Making new ep fs=0x%x,0x%x\n",					      fsb.f_fsid.val[0],					      fsb.f_fsid.val[1]);				    } else if (debug)					fprintf(stderr,					    "Found ep fs=0x%x,0x%x\n",					    fsb.f_fsid.val[0],					    fsb.f_fsid.val[1]);				}				/*				 * Add dirpath to export mount point.				 */				dirp = add_expdir(&dirhead, cp, len);				dirplen = len;			    } else {				getexp_err(ep, tgrp);				goto nextline;			    }			    *endcp = savedc;			} else {			    savedc = *endcp;			    *endcp = '\0';			    got_nondir = 1;			    if (ep == (struct exportlist *)NULL) {				getexp_err(ep, tgrp);				goto nextline;			    }			    /*			     * Get the host or netgroup.			     */			    setnetgrent(cp);			    netgrp = getnetgrent(&hst, &usr, &dom);			    do {				if (has_host) {				    grp->gr_next = get_grp();				    grp = grp->gr_next;				}				if (netgrp) {				    if (get_host(hst, grp)) {					syslog(LOG_ERR, "Bad netgroup %s", cp);					getexp_err(ep, tgrp);					goto nextline;				    }				} else if (get_host(cp, grp)) {				    getexp_err(ep, tgrp);				    goto nextline;				}				has_host = TRUE;			    } while (netgrp && getnetgrent(&hst, &usr, &dom));			    endnetgrent();			    *endcp = savedc;			}			cp = endcp;			nextfield(&cp, &endcp);			len = endcp - cp;		}		if (check_options(dirhead)) {			getexp_err(ep, tgrp);			goto nextline;		}		if (!has_host) {			grp->gr_type = GT_HOST;			if (debug)				fprintf(stderr,"Adding a default entry\n");			/* add a default group and make the grp list NULL */			hpe = (struct hostent *)malloc(sizeof(struct hostent));			if (hpe == (struct hostent *)NULL)				out_of_mem();			hpe->h_name = "Default";			hpe->h_addrtype = AF_INET;			hpe->h_length = sizeof (u_long);			hpe->h_addr_list = (char **)NULL;			grp->gr_ptr.gt_hostent = hpe;		/*		 * Don't allow a network export coincide with a list of		 * host(s) on the same line.		 */		} else if ((opt_flags & OP_NET) && tgrp->gr_next) {			getexp_err(ep, tgrp);			goto nextline;		}		/*		 * Loop through hosts, pushing the exports into the kernel.		 * After loop, tgrp points to the start of the list and		 * grp points to the last entry in the list.		 */		grp = tgrp;		do {		    if (do_mount(ep, grp, exflags, &anon, dirp,			dirplen, &fsb)) {			getexp_err(ep, tgrp);			goto nextline;		    }		} while (grp->gr_next && (grp = grp->gr_next));		/*		 * Success. Update the data structures.		 */		if (has_host) {			hang_dirp(dirhead, tgrp, ep, (opt_flags & OP_ALLDIRS));			grp->gr_next = grphead;			grphead = tgrp;		} else {			hang_dirp(dirhead, (struct grouplist *)NULL, ep,			(opt_flags & OP_ALLDIRS));			free_grp(grp);		}		dirhead = (struct dirlist *)NULL;		if ((ep->ex_flag & EX_LINKED) == 0) {			ep2 = exphead;			epp = &exphead;			/*			 * Insert in the list in alphabetical order.			 */			while (ep2 && strcmp(ep2->ex_fsdir, ep->ex_fsdir) < 0) {				epp = &ep2->ex_next;				ep2 = ep2->ex_next;			}			if (ep2)				ep->ex_next = ep2;			*epp = ep;			ep->ex_flag |= EX_LINKED;		}nextline:		if (dirhead) {			free_dir(dirhead);			dirhead = (struct dirlist *)NULL;		}	}	fclose(exp_file);}/* * Allocate an export list element */struct exportlist *get_exp(){	struct exportlist *ep;	ep = (struct exportlist *)malloc(sizeof (struct exportlist));	if (ep == (struct exportlist *)NULL)		out_of_mem();	bzero((caddr_t)ep, sizeof (struct exportlist));	return (ep);}/* * Allocate a group list element */struct grouplist *get_grp(){	struct grouplist *gp;	gp = (struct grouplist *)malloc(sizeof (struct grouplist));	if (gp == (struct grouplist *)NULL)		out_of_mem();	bzero((caddr_t)gp, sizeof (struct grouplist));	return (gp);}/* * Clean up upon an error in get_exportlist(). */voidgetexp_err(ep, grp)	struct exportlist *ep;	struct grouplist *grp;{	struct grouplist *tgrp;	syslog(LOG_ERR, "Bad exports list line %s", line);	if (ep && (ep->ex_flag & EX_LINKED) == 0)		free_exp(ep);	while (grp) {		tgrp = grp;		grp = grp->gr_next;		free_grp(tgrp);	}}/* * Search the export list for a matching fs. */struct exportlist *ex_search(fsid)	fsid_t *fsid;{	struct exportlist *ep;	ep = exphead;	while (ep) {		if (ep->ex_fs.val[0] == fsid->val[0] &&		    ep->ex_fs.val[1] == fsid->val[1])			return (ep);		ep = ep->ex_next;	}	return (ep);}/* * Add a directory path to the list. */char *add_expdir(dpp, cp, len)	struct dirlist **dpp;	char *cp;	int len;{	struct dirlist *dp;	dp = (struct dirlist *)malloc(sizeof (struct dirlist) + len);	dp->dp_left = *dpp;	dp->dp_right = (struct dirlist *)NULL;	dp->dp_flag = 0;	dp->dp_hosts = (struct hostlist *)NULL;	strcpy(dp->dp_dirp, cp);	*dpp = dp;	return (dp->dp_dirp);}/* * Hang the dir list element off the dirpath binary tree as required * and update the entry for host. */voidhang_dirp(dp, grp, ep, alldirs)	struct dirlist *dp;	struct grouplist *grp;	struct exportlist *ep;	int alldirs;{	struct hostlist *hp;	struct dirlist *dp2;	if (alldirs) {		if (ep->ex_defdir)			free((caddr_t)dp);		else			ep->ex_defdir = dp;		if (grp == (struct grouplist *)NULL)			ep->ex_defdir->dp_flag |= DP_DEFSET;		else while (grp) {			hp = get_ht();			hp->ht_grp = grp;			hp->ht_next = ep->ex_defdir->dp_hosts;			ep->ex_defdir->dp_hosts = hp;			grp = grp->gr_next;		}	} else {		/*		 * Loop throught the directories adding them to the tree.		 */		while (dp) {			dp2 = dp->dp_left;			add_dlist(&ep->ex_dirl, dp, grp);			dp = dp2;		}	}}/* * Traverse the binary tree either updating a node that is already there * for the new directory or adding the new node. */voidadd_dlist(dpp, newdp, grp)	struct dirlist **dpp;	struct dirlist *newdp;	struct grouplist *grp;{	struct dirlist *dp;	struct hostlist *hp;	int cmp;	dp = *dpp;	if (dp) {		cmp = strcmp(dp->dp_dirp, newdp->dp_dirp);		if (cmp > 0) {			add_dlist(&dp->dp_left, newdp, grp);			return;		} else if (cmp < 0) {			add_dlist(&dp->dp_right, newdp, grp);			return;		} else			free((caddr_t)newdp);	} else {		dp = newdp;		dp->dp_left = (struct dirlist *)NULL;		*dpp = dp;	}	if (grp) {		/*		 * Hang all of the host(s) off of the directory point.		 */		do {			hp = get_ht();			hp->ht_grp = grp;			hp->ht_next = dp->dp_hosts;			dp->dp_hosts = hp;			grp = grp->gr_next;		} while (grp);	} else		dp->dp_flag |= DP_DEFSET;}/* * Search for a dirpath on the export point. */struct dirlist *dirp_search(dp, dirpath)	struct dirlist *dp;	char *dirpath;{	int cmp;	if (dp) {		cmp = strcmp(dp->dp_dirp, dirpath);		if (cmp > 0)			return (dirp_search(dp->dp_left, dirpath));		else if (cmp < 0)			return (dirp_search(dp->dp_right, dirpath));		else			return (dp);	}	return (dp);}/* * Scan for a host match in a directory tree. */intchk_host(dp, saddr, defsetp)	struct dirlist *dp;	u_long saddr;	int *defsetp;{	struct hostlist *hp;	struct grouplist *grp;	u_long **addrp;	if (dp) {		if (dp->dp_flag & DP_DEFSET)			*defsetp = 1;		hp = dp->dp_hosts;		while (hp) {			grp = hp->ht_grp;			switch (grp->gr_type) {			case GT_HOST:			    addrp = (u_long **)				grp->gr_ptr.gt_hostent->h_addr_list;			    while (*addrp) {				if (**addrp == saddr)				    return (1);				addrp++;			    }			    break;			case GT_NET:			    if ((saddr & grp->gr_ptr.gt_net.nt_mask) ==				grp->gr_ptr.gt_net.nt_net)				return (1);			    break;			};			hp = hp->ht_next;		}	}	return (0);}/* * Scan tree for a host that matches the address. */intscan_tree(dp, saddr)	struct dirlist *dp;	u_long saddr;{	int defset;	if (dp) {		if (scan_tree(dp->dp_left, saddr))			return (1);		if (chk_host(dp, saddr, &defset))			return (1);		if (scan_tree(dp->dp_right, saddr))			return (1);	}	return (0);}/* * Traverse the dirlist tree and free it up. */voidfree_dir(dp)	struct dirlist *dp;{	if (dp) {		free_dir(dp->dp_left);		free_dir(dp->dp_right);		free_host(dp->dp_hosts);		free((caddr_t)dp);	}}/* * Parse the option string and update fields. * Option arguments may either be -<option>=<value> or * -<option> <value> */intdo_opt(cpp, endcpp, ep, grp, has_hostp, exflagsp, cr)	char **cpp, **endcpp;	struct exportlist *ep;	struct grouplist *grp;	int *has_hostp;	int *exflagsp;	struct ucred *cr;{	char *cpoptarg, *cpoptend;	char *cp, *endcp, *cpopt, savedc, savedc2;	int allflag, usedarg;	cpopt = *cpp;	cpopt++;	cp = *endcpp;	savedc = *cp;	*cp = '\0';	while (cpopt && *cpopt) {		allflag = 1;		usedarg = -2;		if (cpoptend = index(cpopt, ',')) {			*cpoptend++ = '\0';			if (cpoptarg = index(cpopt, '='))				*cpoptarg++ = '\0';		} else {			if (cpoptarg = index(cpopt, '='))				*cpoptarg++ = '\0';			else {				*cp = savedc;				nextfield(&cp, &endcp);				**endcpp = '\0';				if (endcp > cp && *cp != '-') {					cpoptarg = cp;					savedc2 = *endcp;					*endcp = '\0';					usedarg = 0;				}			}		}		if (!strcmp(cpopt, "ro") || !strcmp(cpopt, "o")) {			*exflagsp |= MNT_EXRDONLY;		} else if (cpoptarg && (!strcmp(cpopt, "maproot") ||		    !(allflag = strcmp(cpopt, "mapall")) ||		    !strcmp(cpopt, "root") || !strcmp(cpopt, "r"))) {			usedarg++;			parsecred(cpoptarg, cr);			if (allflag == 0) {				*exflagsp |= MNT_EXPORTANON;				opt_flags |= OP_MAPALL;			} else				opt_flags |= OP_MAPROOT;		} else if (!strcmp(cpopt, "kerb") || !strcmp(cpopt, "k")) {			*exflagsp |= MNT_EXKERB;			opt_flags |= OP_KERB;		} else if (cpoptarg && (!strcmp(cpopt, "mask") ||			!strcmp(cpopt, "m"))) {			if (get_net(cpoptarg, &grp->gr_ptr.gt_net, 1)) {				syslog(LOG_ERR, "Bad mask: %s", cpoptarg);				return (1);			}			usedarg++;			opt_flags |= OP_MASK;		} else if (cpoptarg && (!strcmp(cpopt, "network") ||			!strcmp(cpopt, "n"))) {			if (grp->gr_type != GT_NULL) {				syslog(LOG_ERR, "Network/host conflict");				return (1);			} else if (get_net(cpoptarg, &grp->gr_ptr.gt_net, 0)) {				syslog(LOG_ERR, "Bad net: %s", cpoptarg);				return (1);			}			grp->gr_type = GT_NET;			*has_hostp = 1;			usedarg++;			opt_flags |= OP_NET;		} else if (!strcmp(cpopt, "alldirs")) {			opt_flags |= OP_ALLDIRS;#ifdef ISO		} else if (cpoptarg && !strcmp(cpopt, "iso")) {			if (get_isoaddr(cpoptarg, grp)) {				syslog(LOG_ERR, "Bad iso addr: %s", cpoptarg);				return (1);			}			*has_hostp = 1;			usedarg++;			opt_flags |= OP_ISO;#endif /* ISO */		} else {			syslog(LOG_ERR, "Bad opt %s", cpopt);			return (1);		}		if (usedarg >= 0) {			*endcp = savedc2;			**endcpp = savedc;			if (usedarg > 0) {				*cpp = cp;				*endcpp = endcp;			}			return (0);		}		cpopt = cpoptend;	}	**endcpp = savedc;	return (0);}/* * Translate a character string to the corresponding list of network * addresses for a hostname. */intget_host(cp, grp)	char *cp;	struct grouplist *grp;{	struct hostent *hp, *nhp;	char **addrp, **naddrp;	struct hostent t_host;	int i;	u_long saddr;	char *aptr[2];	if (grp->gr_type != GT_NULL)		return (1);	if ((hp = gethostbyname(cp)) == NULL) {		if (isdigit(*cp)) {			saddr = inet_addr(cp);			if (saddr == -1) {				syslog(LOG_ERR, "Inet_addr failed");				return (1);			}			if ((hp = gethostbyaddr((caddr_t)&saddr, sizeof (saddr),				AF_INET)) == NULL) {				hp = &t_host;				hp->h_name = cp;				hp->h_addrtype = AF_INET;				hp->h_length = sizeof (u_long);				hp->h_addr_list = aptr;				aptr[0] = (char *)&saddr;				aptr[1] = (char *)NULL;			}		} else {			syslog(LOG_ERR, "Gethostbyname failed");			return (1);		}	}	grp->gr_type = GT_HOST;	nhp = grp->gr_ptr.gt_hostent = (struct hostent *)		malloc(sizeof(struct hostent));	if (nhp == (struct hostent *)NULL)		out_of_mem();	bcopy((caddr_t)hp, (caddr_t)nhp,		sizeof(struct hostent));	i = strlen(hp->h_name)+1;	nhp->h_name = (char *)malloc(i);	if (nhp->h_name == (char *)NULL)		out_of_mem();	bcopy(hp->h_name, nhp->h_name, i);	addrp = hp->h_addr_list;	i = 1;	while (*addrp++)		i++;	naddrp = nhp->h_addr_list = (char **)		malloc(i*sizeof(char *));	if (naddrp == (char **)NULL)		out_of_mem();	addrp = hp->h_addr_list;	while (*addrp) {		*naddrp = (char *)		    malloc(hp->h_length);		if (*naddrp == (char *)NULL)		    out_of_mem();		bcopy(*addrp, *naddrp,			hp->h_length);		addrp++;		naddrp++;

⌨️ 快捷键说明

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