+
+/*
+ * Parse the option string
+ */
+do_opt(cpopt, fep, ep, exflagsp, rootuidp)
+ register char *cpopt;
+ struct exportlist *fep, *ep;
+ int *exflagsp, *rootuidp;
+{
+ register char *cpoptarg, *cpoptend;
+
+ while (cpopt && *cpopt) {
+ if (cpoptend = index(cpopt, ','))
+ *cpoptend++ = '\0';
+ if (cpoptarg = index(cpopt, '='))
+ *cpoptarg++ = '\0';
+ if (!strcmp(cpopt, "ro") || !strcmp(cpopt, "o")) {
+ if (fep && (fep->ex_exflags & MNT_EXRDONLY) == 0)
+ syslog(LOG_WARNING, "ro failed for %s",
+ ep->ex_dirp);
+ else
+ *exflagsp |= MNT_EXRDONLY;
+ } else if (!strcmp(cpopt, "root") || !strcmp(cpopt, "r")) {
+ if (cpoptarg && isdigit(*cpoptarg)) {
+ *rootuidp = atoi(cpoptarg);
+ if (fep && fep->ex_rootuid != *rootuidp)
+ syslog(LOG_WARNING,
+ "uid failed for %s",
+ ep->ex_dirp);
+ } else
+ syslog(LOG_WARNING,
+ "uid failed for %s",
+ ep->ex_dirp);
+ } else
+ syslog(LOG_WARNING, "opt %s ignored for %s", cpopt,
+ ep->ex_dirp);
+ cpopt = cpoptend;
+ }
+}
+
+#define STRSIZ (RPCMNT_NAMELEN+RPCMNT_PATHLEN+50)
+/*
+ * Routines that maintain the remote mounttab
+ */
+void get_mountlist()
+{
+ register struct mountlist *mlp, **mlpp;
+ register char *eos, *dirp;
+ int len;
+ char str[STRSIZ];
+ FILE *mlfile;
+
+ if (((mlfile = fopen(_PATH_RMOUNTLIST, "r")) == NULL) &&
+ ((mlfile = fopen(_PATH_RMOUNTLIST, "w")) == NULL)) {
+ syslog(LOG_WARNING, "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 *)0;
+ *mlpp = mlp;
+ mlpp = &mlp->ml_next;
+ }
+ fclose(mlfile);
+}
+
+void del_mlist(hostp, dirp)
+ register char *hostp, *dirp;
+{
+ register struct mountlist *mlp, **mlpp;
+ 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;
+ *mlpp = mlp->ml_next;
+ free((caddr_t)mlp);
+ }
+ mlpp = &mlp->ml_next;
+ mlp = mlp->ml_next;
+ }
+ if (fnd) {
+ if ((mlfile = fopen(_PATH_RMOUNTLIST, "w")) == NULL) {
+ syslog(LOG_WARNING, "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);
+ }
+}
+
+void add_mlist(hostp, dirp)
+ register char *hostp, *dirp;
+{
+ register 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 *)0;
+ *mlpp = mlp;
+ if ((mlfile = fopen(_PATH_RMOUNTLIST, "a")) == NULL) {
+ syslog(LOG_WARNING, "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.
+ */
+send_umntall()
+{
+ (void) clnt_broadcast(RPCPROG_MNT, RPCMNT_VER1, RPCMNT_UMNTALL,
+ xdr_void, (caddr_t)0, xdr_void, (caddr_t)0, umntall_each);
+ exit();
+}
+
+umntall_each(resultsp, raddr)
+ caddr_t resultsp;
+ struct sockaddr_in *raddr;
+{
+ return (1);
+}
+
+/*
+ * Free up an exports list component
+ */
+free_exp(ep)
+ register struct exportlist *ep;
+{
+ register struct grouplist *grp;
+ register char **addrp;
+ struct grouplist *grp2;
+
+ grp = ep->ex_groups;
+ while (grp != NULL) {
+ addrp = grp->gr_hp->h_addr_list;
+ while (*addrp)
+ free(*addrp++);
+ free((caddr_t)grp->gr_hp->h_addr_list);
+ free(grp->gr_hp->h_name);
+ free((caddr_t)grp->gr_hp);
+ grp2 = grp;
+ grp = grp->gr_next;
+ free((caddr_t)grp2);
+ }
+ free((caddr_t)ep);
+}