📄 mountd.c
字号:
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 + -