📄 mountlib.c
字号:
case MOUNTPROC_UMNTALL: xdr_argument = xdr_void; xdr_result = xdr_void; local = (char *(*)()) mountproc_umntall_1; break; case MOUNTPROC_EXPORT: xdr_argument = xdr_void; xdr_result = xdr_exports; local = (char *(*)()) mountproc_export_1; break; default: svcerr_noproc(transp); return; } bzero((char *)&argument, sizeof(argument)); if (!svc_getargs(transp, xdr_argument, &argument)) { svcerr_decode(transp); return; } /* Check authorization if hook exists */ if (mountdAuthHook) authorized = (*mountdAuthHook) (MOUNTPROG, MOUNTVERS, rqstp->rq_proc, transp->xp_raddr, argument); else authorized = NFS_OK; if (authorized != NFS_OK) { switch (rqstp->rq_proc) { /* there's no way to return a mount error for null, dump, * umnt, umntall, or export. Can only return an empty list. */ case MOUNTPROC_NULL: case MOUNTPROC_DUMP: case MOUNTPROC_UMNT: case MOUNTPROC_UMNTALL: case MOUNTPROC_EXPORT: result = NULL; break; /* Can return a real error for mnt */ case MOUNTPROC_MNT: result =(char *) &authorized; break; } } else result = (char *) (*local)(&argument, rqstp); if (!svc_sendreply(transp, xdr_result, result)) { svcerr_systemerr(transp); } if (!svc_freeargs(transp, xdr_argument, &argument)) { fprintf(stderr, "unable to free arguments"); exit(1); } return; }/******************************************************************************** mountproc_null_1 - do nothing* * This procedure does no work. It is made available in all RPC* services to allow server response testing and timing.* * NOMANUAL*/void * mountproc_null_1 ( void ) { return (NULL); }/******************************************************************************** mountproc_mnt_1 -* * If the reply "status" is 0, then the reply "directory" contains the* file handle for the directory "dirname". This file handle may be* used in the NFS protocol. This procedure also adds a new entry to* the mount list for this client mounting "dirname".* * NOMANUAL*/fhstatus * mountproc_mnt_1 ( dirpath * path, struct svc_req * rqstp /* Client information */ ) { static fhstatus fstatus; /* Status information to return */ NFS_FILE_HANDLE fh; /* file handle of mount point */ NFS_EXPORT_ENTRY * mntPoint = NULL; /* export entry for exported FS */ char * reducedPath; /* path after removing extra dots */ char * lastChar; /* loop variable used to reduce path */ MOUNT_CLIENT * newClient; /* info about client mounting directory */ if (strlen ((char *) path) >= nfsMaxPath) return (NULL); if ((reducedPath = (char *) alloca (nfsMaxPath)) == NULL) return (NULL); /* Reduce any pathnames that look like "/foo/bar/.." */ strcpy (reducedPath, *path); pathCondense (reducedPath); /* Any directory under a mount point is also eligible to be mounted. * If a requested directory isn't a mount point, see if any of its * parents are. */ while (strlen (reducedPath) != 0) { mntPoint = nfsExportFindByName (reducedPath); if (mntPoint == NULL) { /* Get a pointer to the last char of reducedPath, and move * to the left until you get to a slash. Replace the slash * with EOS, then see if that's a mount point. */ lastChar = reducedPath + strlen (reducedPath) - 1; while ((lastChar > reducedPath) && (*--lastChar != '/')); *lastChar = EOS; } else /* found the mount point */ break; } /* If we still didn't find a mount point, it isn't exported */ if (mntPoint == NULL) { fstatus.fhs_status = ENOENT; return (&fstatus); } memset (&fh, 0, sizeof (fh)); fh.volumeId = mntPoint->volumeId; if ((fh.inode = fh.fsId = nameToInode (fh.volumeId, *path)) == ERROR) { fstatus.fhs_status = nfsdErrToNfs (errno); return (&fstatus); } /* See if we have an entry already in the mount list for * this client/path pair. If so, then re-use it. Otherwise, * allocate a new entry. */ if (mountListFind (rqstp, path) == NULL) { newClient = KHEAP_ALLOC((sizeof (*newClient) + nfsMaxPath - 1)); if (NULL == newClient) { fstatus.fhs_status = ENOMEM; return (&fstatus); } else { bzero ((char *)newClient, (sizeof (*newClient))); } /* Set client name and directory fields of new client record */ svc_reqToHostName (rqstp, newClient->clientName); strncpy (newClient->directory, *path, nfsMaxPath - 1); /* Add to the client list */ semTake (clientsSem, WAIT_FOREVER); lstAdd (nfsClients, (NODE *) newClient); semGive (clientsSem); } /* Convert outgoing file handle to network byte order */ nfsdFhHton (&fh); memcpy (&fstatus.fhstatus_u.fhs_fhandle, &fh, FHSIZE); fstatus.fhs_status = 0; return (&fstatus); }/******************************************************************************** mountproc_dump_1 -* Returns the list of remote mounted file systems. The "mountlist"* contains one entry for each "hostname" and "directory" pair.* * NOMANUAL*/mountlist * mountproc_dump_1 ( void ) { static mountlist mountList = NULL; int lstPos = 0; MOUNT_CLIENT * mountEntry; MOUNT_CLIENT * nextEntry; char * strTbl; int nClients; semTake (clientsSem, WAIT_FOREVER); nClients = lstCount (nfsClients); /* If there are no clients, free the semaphore and memory, return NULL */ if (nClients == 0) { semGive (clientsSem); /* if mountList has been allocated, free it */ if (mountList != NULL) KHEAP_FREE ((char *)mountList); mountList = NULL; return ((mountlist *) &mountList); } if (mountList == NULL) { mountList = KHEAP_ALLOC (((nClients * (sizeof(mountbody) + nfsMaxPath + MAXHOSTNAMELEN+2)))); if (NULL != mountList) { bzero ((char *)mountList,((nClients * (sizeof(mountbody) + nfsMaxPath + MAXHOSTNAMELEN+2)))); } } else { mountList = KHEAP_REALLOC((char *)mountList, (unsigned) ((sizeof (mountbody) + nfsMaxPath + MAXHOSTNAMELEN + 2) * nClients)); } if (mountList == NULL) return ((mountlist *) &mountList); strTbl = (char *) &mountList[lstCount(nfsClients)]; for (mountEntry = (MOUNT_CLIENT *) lstFirst (nfsClients); mountEntry != NULL; mountEntry = (MOUNT_CLIENT *) lstNext ((NODE *) mountEntry)) { nextEntry = (MOUNT_CLIENT *) lstNext ((NODE *) mountEntry); mountList [lstPos].ml_hostname = strTbl; strncpy (strTbl, mountEntry->clientName, MAXHOSTNAMELEN); strTbl [MAXHOSTNAMELEN] = EOS; strTbl += strlen (strTbl) + 1; strTbl = (char *) MEM_ROUND_UP (strTbl); mountList [lstPos].ml_directory = strTbl; strncpy (strTbl, mountEntry->directory, nfsMaxPath - 1); strTbl [nfsMaxPath - 1] = EOS; strTbl += strlen (strTbl) + 1; strTbl = (char *) MEM_ROUND_UP (strTbl); if (nextEntry != NULL) mountList [lstPos].ml_next = &mountList [lstPos + 1]; else mountList [lstPos].ml_next = NULL; lstPos++; } semGive (clientsSem); return ((mountlist *) &mountList); }/******************************************************************************** mountproc_umnt_1 -* * Removes the mount list entry for the input "dirpath".* * NOMANUAL*/void * mountproc_umnt_1 ( dirpath * path, struct svc_req * rqstp /* Client information */ ) { MOUNT_CLIENT * clientEntry; /* See if we have an entry for this client/path pair * in the mount list, and if so, remove it. */ if ((clientEntry = mountListFind (rqstp, path)) != NULL) { semTake (clientsSem, WAIT_FOREVER); lstDelete (nfsClients, (NODE *) clientEntry); KHEAP_FREE (clientEntry); semGive (clientsSem); } return ((void *) TRUE); }/******************************************************************************** mountproc_umntall_1 -* Removes all of the mount list entries for this client.* * NOMANUAL*/void * mountproc_umntall_1 ( char * nothing, /* unused */ struct svc_req * rqstp /* Client information */ ) { MOUNT_CLIENT * clientEntry; char clientName [MAXHOSTNAMELEN + 1]; MOUNT_CLIENT * deleteThis; BOOL completePass = FALSE; semTake (clientsSem, WAIT_FOREVER); while (!completePass) { deleteThis = NULL; for (clientEntry = (MOUNT_CLIENT *) lstFirst (nfsClients); clientEntry != NULL; clientEntry = (MOUNT_CLIENT *) lstNext ((NODE *) clientEntry)) { svc_reqToHostName (rqstp, clientName); if (strncmp(clientName, clientEntry->clientName, MAXHOSTNAMELEN) == 0) { /* Found it */ deleteThis = clientEntry; break; } } completePass = (clientEntry == NULL); if (deleteThis) { lstDelete (nfsClients, (NODE *) deleteThis); KHEAP_FREE (deleteThis); } } semGive (clientsSem); return ((void *) TRUE); }/******************************************************************************** mountproc_export_1 -* Returns a variable number of export list entries. Each entry* contains a file system name and a list of groups that are allowed to* import it. The file system name is in "filesys", and the group name* is in the list "groups".* * NOMANUAL*/exports * mountproc_export_1 ( void ) { static exportnode * exportList = NULL; int lstPos = 0; NFS_EXPORT_ENTRY * exportEntry; NFS_EXPORT_ENTRY * nextEntry; static struct groupnode aGroup; char * strTbl; /* If there are no exported file systems, return NULL * The check for exportList removes any stale exportList that * are present */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -