home *** CD-ROM | disk | FTP | other *** search
- /*
- * mountd.c --
- * Mount daemon program for PC NFS. Runs on top of the net daemon
- * (netd.c). This is a partial implementation of the UNIX mount
- * daemon mountd(8c).
- *
- * Author:
- * See-Mong Tan, 6/12/88]
- */
-
- #include "common.h"
-
- static void expreply (struct svc_req *, SVCXPRT *);
-
- /*
- * bool_t mountd_init() --
- * Mount daemon initialization. Creates and registers transport
- * handle, and sets exports in the file EXPORTS.
- */
- bool_t mountd_init()
- {
- int sock;
- struct sockaddr_in addr;
- SVCXPRT *transp;
-
- addr.sin_family = AF_INET;
- addr.sin_port = htons(MOUNTPORT);
- addr.sin_addr.s_addr = INADDR_ANY;
- if ((sock = sock_create(SOCK_DGRAM, IPPROTO_UDP, &addr)) < 0) {
- (void) fprintf (stderr, "mountd: cannot get mount socket");
- sock_close(sock);
- return FALSE;
- }
- if ((transp = svcudp_create(sock, 0)) == (SVCXPRT *) NULL) {
- (void) fprintf (stderr, "mountd: cannot create udp handle");
- sock_close(sock);
- return FALSE;
- }
- if (! svc_register(transp, MOUNTPROG, MOUNTVERS, mountd_dispatch,
- IPPROTO_UDP)) {
- (void) fprintf(stderr, "mountd: cannot register transport\n");
- sock_close(sock);
- return FALSE;
- }
- if (! exps_parse()) {
- (void) fprintf(stderr, "mountd: cannot parse exports file\n");
- sock_close(sock);
- return FALSE;
- }
-
- return TRUE;
- }
-
- /*
- * void mountd_dispatch(struct svc_req *req, SVCXPRT *xprt) --
- * Dispatch routine for the mount daemon.
- */
- void mountd_dispatch(req, xprt)
- struct svc_req *req;
- SVCXPRT *xprt;
- {
- #if DEBUG
- static char *names[] = {"NULL", "MNT", "DUMP", "UMNT", "UMNTALL",
- "EXPORT", "EXPORTALL", "<invalid>"};
- DBGPRT1 (mountd, ">>> MOUNTPROC_%s", names[(req->rq_proc >
- MOUNTPROC_EXPORTALL) ? MOUNTPROC_EXPORTALL+1 : req->rq_proc]);
- #endif
-
- switch((int) req->rq_proc) {
-
- case NULLPROC: /* "ping" the mount daemon */
- if (! svc_sendreply(xprt, xdr_void, 0)) {
- (void) fprintf(stderr, "mountd: cannot send reply\n");
- return;
- }
- break;
-
- case MOUNTPROC_MNT: mount(req, xprt); break;
- case MOUNTPROC_UMNT: unmount(req, xprt); break;
- case MOUNTPROC_EXPORT: expreply(req, xprt); break;
- case MOUNTPROC_DUMP:
- case MOUNTPROC_UMNTALL:
- case MOUNTPROC_EXPORTALL:
-
- default:
- svcerr_noproc(xprt);
- }
- }
-
- /*
- * void mount(struct svc_req *req, SVCXPRT *xprt) --
- * Services a mount request
- */
- void mount(req, xprt)
- struct svc_req *req;
- SVCXPRT *xprt;
- {
- char *path = NULL, *hostname;
- struct fhstatus fhs; /* file handle status */
- struct sockaddr_in addr;
-
- if (! svc_getargs(xprt, xdr_path, &path)) {
- DBGPRT0 (mountd, "cannot decode mount path");
- svcerr_decode(xprt);
- return;
- }
- DBGPRT1 (mountd, "path: %s", path);
- addr = *(svc_getcaller(xprt));
- if (! exps_isclnt(path, addr.sin_addr.s_addr)) {
- DBGPRT0 (mountd, "access denied");
- fhs.fhs_status = NFSERR_ACCES;
- }
- else if (! mntpntofh(path, &(fhs.fhs_fh))) {
- DBGPRT0 (mountd, "illegal path");
- fhs.fhs_status = (int) NFSERR_NOENT;
- }
- else
- fhs.fhs_status = (int) NFS_OK;
-
- /* reply to caller */
- if (! svc_sendreply(xprt, xdr_fhstatus, &fhs))
- (void) fprintf(stderr, "mount: cannot reply to mount req\n");
-
- svc_freeargs(xprt, xdr_path, &path);
- }
-
- /*
- * void unmount(struct svc_req *req, SVCXPRT *xprt) --
- * Unmount a filesystem.
- */
- void unmount(req, xprt)
- struct svc_req *req;
- SVCXPRT *xprt;
- {
- char *path = NULL;
- fhandle_t fh;
-
- if (! svc_getargs(xprt, xdr_path, &path)) {
- DBGPRT0 (mountd, "unmount: cannot decode");
- svcerr_decode(xprt);
- return;
- }
- DBGPRT1 (mountd, "unmounting %s", path);
- if (! mntpntofh(path, &fh))
- DBGPRT0 (mountd, "unmount: not in mount list");
-
- if (! svc_sendreply(xprt, xdr_void, NULL)) {
- (void) fprintf(stderr, "unmount: cannot send reply\n");
- }
- svc_freeargs(xprt, xdr_path, &path);
- }
-
- /*
- * void expreply(struct svc_req *req, SVCXPRT *xprt) --
- * Services an exports request
- */
- void expreply(req, xprt)
- struct svc_req *req;
- SVCXPRT *xprt;
- {
- struct exports *exp_list;
-
- exp_list = exps_get ();
-
- /* reply to caller */
- if (! svc_sendreply(xprt, xdr_exports, &exp_list))
- (void) fprintf(stderr, "mount: cannot reply to export req\n");
- }
-
- /*
- * bool_t mntpntofh(char *path, fhandle_t *fhp) --
- * Checks that path matches something in the export list and
- * converts the path name to file status handle.
- */
- bool_t mntpntofh(path, fhp)
- char *path;
- fhandle_t *fhp;
- {
- Exports *ptr;
-
- if ((ptr = exps_isexport(path)) == NULL) { /* not in list */
- DBGPRT1 (mountd, "path \"%s\" not in export list", path);
- return FALSE;
- }
- /* anything in export list should already be in directory tree cache */
- *fhp = pntofh (path);
- return TRUE;
- }
-
-