home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
- #ifndef lint
- char copyright[] =
- "@(#) Copyright (c) 1989 Regents of the University of California.\n\
- All rights reserved.\n";
- #endif not lint
-
- #ifndef lint
- static char sccsid[] = "@(#)mountd.c 5.14 (Berkeley) 2/26/91";
- #endif not lint
-
- #include <sys/param.h>
- #include <sys/ioctl.h>
- #include <sys/stat.h>
- #include <sys/file.h>
- #include <sys/mount.h>
- #include <sys/socket.h>
- #include <sys/errno.h>
- #include <sys/signal.h>
- #include <stdio.h>
- #include <string.h>
- #include <syslog.h>
- #include <netdb.h>
- #include <rpc/rpc.h>
- #include <rpc/pmap_clnt.h>
- #include <rpc/pmap_prot.h>
- #include <nfs/rpcv2.h>
- #include <nfs/nfsv2.h>
- #include "pathnames.h"
-
- struct ufid {
- u_short ufid_len;
- ino_t ufid_ino;
- long ufid_gen;
- };
- /*
- * Structures for keeping the mount list and export list
- */
- struct mountlist {
- struct mountlist *ml_next;
- char ml_host[RPCMNT_NAMELEN+1];
- char ml_dirp[RPCMNT_PATHLEN+1];
- };
-
- struct exportlist {
- struct exportlist *ex_next;
- struct exportlist *ex_prev;
- struct grouplist *ex_groups;
- int ex_rootuid;
- int ex_exflags;
- dev_t ex_dev;
- char ex_dirp[RPCMNT_PATHLEN+1];
- };
-
- struct grouplist {
- struct grouplist *gr_next;
- struct hostent *gr_hp;
- };
-
- /* Global defs */
- int mntsrv(), umntall_each(), xdr_fhs(), xdr_mlist(), xdr_dir(), xdr_explist();
- void add_mlist(), del_mlist(), get_exportlist(), get_mountlist();
- void send_umntall();
- struct exportlist exphead;
- struct mountlist *mlhead;
- char exname[MAXPATHLEN];
- int def_rootuid = -2;
- int root_only = 1;
- extern int errno;
- #ifdef DEBUG
- int debug = 1;
- #else
- int debug = 0;
- #endif
-
- /*
- * Mountd server for NFS mount protocol as described in:
- * NFS: Network File System Protocol Specification, RFC1094, Appendix A
- * The optional arguments are the exports file name
- * default: _PATH_EXPORTS
- * and "-n" to allow nonroot mount.
- */
- main(argc, argv)
- int argc;
- char **argv;
- {
- SVCXPRT *transp;
- int c;
- extern int optind;
- extern char *optarg;
-
- while ((c = getopt(argc, argv, "n")) != EOF)
- switch (c) {
- case 'n':
- root_only = 0;
- break;
- default:
- fprintf(stderr, "Usage: mountd [-n] [export_file]\n");
- exit(1);
- };
- argc -= optind;
- argv += optind;
- exphead.ex_next = exphead.ex_prev = (struct exportlist *)0;
- mlhead = (struct mountlist *)0;
- if (argc == 1) {
- strncpy(exname, *argv, MAXPATHLEN-1);
- exname[MAXPATHLEN-1] = '\0';
- } else
- strcpy(exname, _PATH_EXPORTS);
- openlog("mountd:", LOG_PID, LOG_DAEMON);
- get_exportlist();
- get_mountlist();
- if (debug == 0) {
- daemon(0, 0);
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- }
- signal(SIGHUP, get_exportlist);
- signal(SIGTERM, send_umntall);
- { FILE *pidfile = fopen(_PATH_MOUNTDPID, "w");
- if (pidfile != NULL) {
- fprintf(pidfile, "%d\n", getpid());
- fclose(pidfile);
- }
- }
- if ((transp = svcudp_create(RPC_ANYSOCK)) == NULL) {
- syslog(LOG_ERR, "Can't create socket");
- exit(1);
- }
- pmap_unset(RPCPROG_MNT, RPCMNT_VER1);
- if (!svc_register(transp, RPCPROG_MNT, RPCMNT_VER1, mntsrv, IPPROTO_UDP)) {
- syslog(LOG_ERR, "Can't register mount");
- exit(1);
- }
- svc_run();
- syslog(LOG_ERR, "Mountd died");
- exit(1);
- }
-
- /*
- * The mount rpc service
- */
- mntsrv(rqstp, transp)
- register struct svc_req *rqstp;
- register SVCXPRT *transp;
- {
- register struct grouplist *grp;
- register u_long **addrp;
- register struct exportlist *ep;
- nfsv2fh_t nfh;
- struct authunix_parms *ucr;
- struct stat stb;
- struct hostent *hp;
- u_long saddr;
- char dirpath[RPCMNT_PATHLEN+1];
- int bad = ENOENT;
- int omask;
- uid_t uid = -2;
-
- /* Get authorization */
- switch (rqstp->rq_cred.oa_flavor) {
- case AUTH_UNIX:
- ucr = (struct authunix_parms *)rqstp->rq_clntcred;
- uid = ucr->aup_uid;
- break;
- case AUTH_NULL:
- default:
- break;
- }
-
- saddr = transp->xp_raddr.sin_addr.s_addr;
- hp = (struct hostent *)0;
- switch (rqstp->rq_proc) {
- case NULLPROC:
- if (!svc_sendreply(transp, xdr_void, (caddr_t)0))
- syslog(LOG_ERR, "Can't send reply");
- return;
- case RPCMNT_MOUNT:
- if (uid != 0 && root_only) {
- svcerr_weakauth(transp);
- return;
- }
- if (!svc_getargs(transp, xdr_dir, dirpath)) {
- svcerr_decode(transp);
- return;
- }
-
- /* Check to see if it's a valid dirpath */
- if (stat(dirpath, &stb) < 0 || (stb.st_mode&S_IFMT) !=
- S_IFDIR) {
- if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad))
- syslog(LOG_ERR, "Can't send reply");
- return;
- }
-
- /* Check in the exports list */
- omask = sigblock(sigmask(SIGHUP));
- ep = exphead.ex_next;
- while (ep != NULL) {
- if (!strcmp(ep->ex_dirp, dirpath)) {
- grp = ep->ex_groups;
- if (grp == NULL)
- break;
-
- /* Check for a host match */
- addrp = (u_long **)grp->gr_hp->h_addr_list;
- for (;;) {
- if (**addrp == saddr)
- break;
- if (*++addrp == NULL)
- if (grp = grp->gr_next) {
- addrp = (u_long **)
- grp->gr_hp->h_addr_list;
- } else {
- bad = EACCES;
- if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad))
- syslog(LOG_ERR, "Can't send reply");
- sigsetmask(omask);
- return;
- }
- }
- hp = grp->gr_hp;
- break;
- }
- ep = ep->ex_next;
- }
- sigsetmask(omask);
- if (ep == NULL) {
- bad = EACCES;
- if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad))
- syslog(LOG_ERR, "Can't send reply");
- return;
- }
-
- /* Get the file handle */
- bzero((caddr_t)&nfh, sizeof(nfh));
- if (getfh(dirpath, (fhandle_t *)&nfh) < 0) {
- bad = errno;
- if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad))
- syslog(LOG_ERR, "Can't send reply");
- return;
- }
- if (!svc_sendreply(transp, xdr_fhs, (caddr_t)&nfh))
- syslog(LOG_ERR, "Can't send reply");
- if (hp == NULL)
- hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET);
- if (hp)
- add_mlist(hp->h_name, dirpath);
- return;
- case RPCMNT_DUMP:
- if (!svc_sendreply(transp, xdr_mlist, (caddr_t)0))
- syslog(LOG_ERR, "Can't send reply");
- return;
- case RPCMNT_UMOUNT:
- if (uid != 0 && root_only) {
- svcerr_weakauth(transp);
- return;
- }
- if (!svc_getargs(transp, xdr_dir, dirpath)) {
- svcerr_decode(transp);
- return;
- }
- if (!svc_sendreply(transp, xdr_void, (caddr_t)0))
- syslog(LOG_ERR, "Can't send reply");
- hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET);
- if (hp)
- del_mlist(hp->h_name, dirpath);
- return;
- case RPCMNT_UMNTALL:
- if (uid != 0 && root_only) {
- svcerr_weakauth(transp);
- return;
- }
- if (!svc_sendreply(transp, xdr_void, (caddr_t)0))
- syslog(LOG_ERR, "Can't send reply");
- hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET);
- if (hp)
- del_mlist(hp->h_name, (char *)0);
- return;
- case RPCMNT_EXPORT:
- if (!svc_sendreply(transp, xdr_explist, (caddr_t)0))
- syslog(LOG_ERR, "Can't send reply");
- return;
- default:
- svcerr_noproc(transp);
- return;
- }
- }
-
- /*
- * Xdr conversion for a dirpath string
- */
- xdr_dir(xdrsp, dirp)
- XDR *xdrsp;
- char *dirp;
- {
- return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN));
- }
-
- /*
- * Xdr routine to generate fhstatus
- */
- xdr_fhs(xdrsp, nfh)
- XDR *xdrsp;
- nfsv2fh_t *nfh;
- {
- int ok = 0;
-
- if (!xdr_long(xdrsp, &ok))
- return (0);
- return (xdr_opaque(xdrsp, (caddr_t)nfh, NFSX_FH));
- }
-
- xdr_mlist(xdrsp, cp)
- XDR *xdrsp;
- caddr_t cp;
- {
- register struct mountlist *mlp;
- int true = 1;
- int false = 0;
- char *strp;
-
- mlp = mlhead;
- while (mlp) {
- if (!xdr_bool(xdrsp, &true))
- return (0);
- strp = &mlp->ml_host[0];
- if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN))
- return (0);
- strp = &mlp->ml_dirp[0];
- if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN))
- return (0);
- mlp = mlp->ml_next;
- }
- if (!xdr_bool(xdrsp, &false))
- return (0);
- return (1);
- }
-
- /*
- * Xdr conversion for export list
- */
- xdr_explist(xdrsp, cp)
- XDR *xdrsp;
- caddr_t cp;
- {
- register struct exportlist *ep;
- register struct grouplist *grp;
- int true = 1;
- int false = 0;
- char *strp;
- int omask;
-
- omask = sigblock(sigmask(SIGHUP));
- ep = exphead.ex_next;
- while (ep != NULL) {
- if (!xdr_bool(xdrsp, &true))
- goto errout;
- strp = &ep->ex_dirp[0];
- if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN))
- goto errout;
- grp = ep->ex_groups;
- while (grp != NULL) {
- if (!xdr_bool(xdrsp, &true))
- goto errout;
- strp = grp->gr_hp->h_name;
- if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN))
- goto errout;
- grp = grp->gr_next;
- }
- if (!xdr_bool(xdrsp, &false))
- goto errout;
- ep = ep->ex_next;
- }
- sigsetmask(omask);
- if (!xdr_bool(xdrsp, &false))
- return (0);
- return (1);
- errout:
- sigsetmask(omask);
- return (0);
- }
-
- #define LINESIZ 10240
- char line[LINESIZ];
-
- /*
- * Get the export list
- */
- void
- get_exportlist()
- {
- register struct hostent *hp, *nhp;
- register char **addrp, **naddrp;
- register int i;
- register struct grouplist *grp;
- register struct exportlist *ep, *ep2;
- struct statfs stfsbuf;
- struct ufs_args args;
- struct stat sb;
- FILE *inf;
- char *cp, *endcp;
- char savedc;
- int len, dirplen;
- int rootuid, exflags;
- u_long saddr;
- struct exportlist *fep;
-
- /*
- * First, get rid of the old list
- */
- ep = exphead.ex_next;
- while (ep != NULL) {
- ep2 = ep;
- ep = ep->ex_next;
- free_exp(ep2);
- }
-
- /*
- * Read in the exports file and build the list, calling
- * exportfs() as we go along
- */
- exphead.ex_next = exphead.ex_prev = (struct exportlist *)0;
- if ((inf = fopen(exname, "r")) == NULL) {
- syslog(LOG_ERR, "Can't open %s", exname);
- exit(2);
- }
- while (fgets(line, LINESIZ, inf)) {
- exflags = MNT_EXPORTED;
- rootuid = def_rootuid;
- cp = line;
- nextfield(&cp, &endcp);
-
- /*
- * Get file system devno and see if an entry for this
- * file system already exists.
- */
- savedc = *endcp;
- *endcp = '\0';
- if (stat(cp, &sb) < 0 || (sb.st_mode & S_IFMT) != S_IFDIR) {
- syslog(LOG_ERR,
- "Bad Exports File, %s: %s, mountd Failed",
- cp, "Not a directory");
- exit(2);
- }
- fep = (struct exportlist *)0;
- ep = exphead.ex_next;
- while (ep) {
- if (ep->ex_dev == sb.st_dev) {
- fep = ep;
- break;
- }
- ep = ep->ex_next;
- }
- *endcp = savedc;
-
- /*
- * Create new exports list entry
- */
- len = endcp-cp;
- if (len <= RPCMNT_PATHLEN && len > 0) {
- ep = (struct exportlist *)malloc(sizeof(*ep));
- if (ep == NULL)
- goto err;
- ep->ex_next = ep->ex_prev = (struct exportlist *)0;
- ep->ex_groups = (struct grouplist *)0;
- bcopy(cp, ep->ex_dirp, len);
- ep->ex_dirp[len] = '\0';
- dirplen = len;
- } else {
- syslog(LOG_ERR, "Bad Exports File, mountd Failed");
- exit(2);
- }
- cp = endcp;
- nextfield(&cp, &endcp);
- len = endcp-cp;
- while (len > 0) {
- savedc = *endcp;
- *endcp = '\0';
- if (len > RPCMNT_NAMELEN)
- goto more;
- if (*cp == '-') {
- do_opt(cp + 1, fep, ep, &exflags, &rootuid);
- goto more;
- }
- if (isdigit(*cp)) {
- saddr = inet_addr(cp);
- if (saddr == -1 ||
- (hp = gethostbyaddr((caddr_t)&saddr,
- sizeof(saddr), AF_INET)) == NULL) {
- syslog(LOG_ERR,
- "Bad Exports File, %s: %s", cp,
- "Gethostbyaddr failed, ignored");
- goto more;
- }
- } else if ((hp = gethostbyname(cp)) == NULL) {
- syslog(LOG_ERR, "Bad Exports File, %s: %s",
- cp, "Gethostbyname failed, ignored");
- goto more;
- }
- grp = (struct grouplist *)
- malloc(sizeof(struct grouplist));
- if (grp == NULL)
- goto err;
- nhp = grp->gr_hp = (struct hostent *)
- malloc(sizeof(struct hostent));
- if (nhp == NULL)
- goto err;
- 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 == NULL)
- goto err;
- 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 == NULL)
- goto err;
- addrp = hp->h_addr_list;
- while (*addrp) {
- *naddrp = (char *)
- malloc(hp->h_length);
- if (*naddrp == NULL)
- goto err;
- bcopy(*addrp, *naddrp,
- hp->h_length);
- addrp++;
- naddrp++;
- }
- *naddrp = (char *)0;
- grp->gr_next = ep->ex_groups;
- ep->ex_groups = grp;
- more:
- cp = endcp;
- *cp = savedc;
- nextfield(&cp, &endcp);
- len = endcp - cp;
- }
- if (fep == NULL) {
- args.fspec = 0;
- args.exflags = exflags;
- args.exroot = rootuid;
- cp = (char *)0;
- while (statfs(ep->ex_dirp, &stfsbuf) < 0 ||
- mount(MOUNT_UFS, ep->ex_dirp,
- stfsbuf.f_flags|MNT_UPDATE, &args) < 0) {
- if (cp == NULL)
- cp = ep->ex_dirp + dirplen - 1;
- else
- *cp = savedc;
- /* back up over the last component */
- while (*cp == '/' && cp > ep->ex_dirp)
- cp--;
- while (*(cp - 1) != '/' && cp > ep->ex_dirp)
- cp--;
- if (cp == ep->ex_dirp) {
- syslog(LOG_WARNING,
- "Can't export %s", ep->ex_dirp);
- free_exp(ep);
- goto nextline;
- }
- savedc = *cp;
- *cp = '\0';
- }
- if (cp)
- *cp = savedc;
- ep->ex_rootuid = rootuid;
- ep->ex_exflags = exflags;
- } else {
- ep->ex_rootuid = fep->ex_rootuid;
- ep->ex_exflags = fep->ex_exflags;
- }
- ep->ex_dev = sb.st_dev;
- ep->ex_next = exphead.ex_next;
- ep->ex_prev = &exphead;
- if (ep->ex_next != NULL)
- ep->ex_next->ex_prev = ep;
- exphead.ex_next = ep;
- nextline:
- ;
- }
- fclose(inf);
- return;
- err:
- syslog(LOG_ERR, "No more memory: mountd Failed");
- exit(2);
- }
-
- /*
- * Parse out the next white space separated field
- */
- nextfield(cp, endcp)
- char **cp;
- char **endcp;
- {
- register char *p;
-
- p = *cp;
- while (*p == ' ' || *p == '\t')
- p++;
- if (*p == '\n' || *p == '\0') {
- *cp = *endcp = p;
- return;
- }
- *cp = p++;
- while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0')
- p++;
- *endcp = p;
- }
-
- /*
- * 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.
- */
- void
- 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);
- }
-