+/*
+ * Do the mount syscall with the update flag to push the export info into
+ * the kernel.
+ */
+int
+do_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.
+ */
+int
+get_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);
+}
+