📄 mountlib.c
字号:
/* 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) free (mountList); return (NULL); } if (mountList == NULL) mountList = calloc (nClients, sizeof (mountbody) + PATH_MAX + MAXHOSTNAMELEN + 2); else mountList = realloc (mountList, (sizeof (mountbody) + PATH_MAX + MAXHOSTNAMELEN + 2) * nClients); if (mountList == NULL) return (NULL); 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, PATH_MAX); strTbl [PATH_MAX] = 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; char clientName [MAXHOSTNAMELEN + 1]; semTake (clientsSem, WAIT_FOREVER); 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) && strncmp (*path, clientEntry->directory, PATH_MAX)) { lstDelete (nfsClients, (NODE *) clientEntry); break; } } 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); } } 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 */ if (lstCount (mountPoints) == 0) return (&exportList); if (exportList == NULL) { exportList = calloc (mountdNExports, sizeof (exportnode) + PATH_MAX); if (exportList == NULL) return (&exportList); } strTbl = (char *) &exportList[mountdNExports]; /* Bogus group information */ aGroup.gr_name = NULL; aGroup.gr_next = NULL; semTake (mountSem, WAIT_FOREVER); for (exportEntry = (NFS_EXPORT_ENTRY *) lstFirst (mountPoints); exportEntry != NULL; exportEntry = (NFS_EXPORT_ENTRY *) lstNext ((NODE *) exportEntry)) { nextEntry = (NFS_EXPORT_ENTRY *) lstNext ((NODE *) exportEntry); exportList [lstPos].ex_dir = strTbl; strncpy (strTbl, exportEntry->dirName, PATH_MAX); strTbl += strlen (strTbl); *strTbl++ = EOS; exportList [lstPos].ex_groups = NULL; if (nextEntry != NULL) exportList [lstPos].ex_next = &exportList [lstPos + 1]; else exportList [lstPos].ex_next = NULL; lstPos++; } semGive (mountSem); return ((exports *) &exportList); }/******************************************************************************** nfsExport - specify a file system to be NFS exported** This routine makes a file system available for mounting by a client.* The client should be in the local host table (see hostAdd()),* although this is not required.* * The <id> parameter can either be set to a specific value, or to 0.* If it is set to 0, an ID number is assigned sequentially.* Every time a file system is exported, it must have the same ID* number, or clients currently mounting the file system will not be* able to access files.** To display a list of exported file systems, use:* .CS* -> nfsExportShow "localhost"* .CE* * RETURNS: OK, or ERROR if the file system could not be exported.** SEE ALSO: nfsLib, nfsExportShow(), nfsUnexport()*/STATUS nfsExport ( char * directory, /* Directory to export - FS must support NFS */ int id, /* ID number for file system */ BOOL readOnly, /* TRUE if file system is exported read-only */ int options /* Reserved for future use - set to 0 */ ) { NFS_EXPORT_ENTRY * exportFs; /* The file system to be exported */ int exportDirFd; /* File descriptor for the exported dir */ struct stat statInfo; /* information from fstat() call */ /* If this is the first mountpoint, initialize the list */ if (mountPoints == NULL) { if ((mountPoints = malloc (sizeof (*mountPoints))) == NULL) return (ERROR); if ((mountSem = semMCreate (SEM_Q_PRIORITY)) == NULL) { free (mountPoints); return (ERROR); } lstInit (mountPoints); } /* Create the export point */ if ((exportFs = malloc (sizeof (*exportFs))) == NULL) return (ERROR); if ((exportDirFd = open (directory, O_RDONLY, 0666)) == ERROR) { free (exportFs); return (ERROR); } /* Set up the NFS_EXPORT_ENTRY structure */ strncpy (exportFs->dirName, directory, PATH_MAX); exportFs->dirFd = exportDirFd; /* Set the ID number for the exported system */ if (id == 0) exportFs->volumeId = fsIdNumber++; else exportFs->volumeId = id; exportFs->readOnly = readOnly; /* Add it to the list */ semTake (mountSem, WAIT_FOREVER); lstAdd (mountPoints, (NODE *) exportFs); semGive (mountSem); if (fstat (exportDirFd, &statInfo) != OK) return (ERROR); else { nfsHashTblSet (exportFs->dirName, exportFs->volumeId, statInfo.st_dev); } if ((exportFs->fsId = nameToInode (exportFs->volumeId, directory)) == ERROR) { free (exportFs); close (exportDirFd); return (ERROR); } return (OK); }/******************************************************************************** nfsUnexport - remove a file system from the list of exported file systems** This routine removes a file system from the list of file systems* exported from the target. Any client attempting to mount a file* system that is not exported will receive an error (NFSERR_ACCESS).* * RETURNS: OK, or ERROR if the file system could not be removed from* the exports list.* * ERRNO: ENOENT** SEE ALSO: nfsLib, nfsExportShow(), nfsExport()*/STATUS nfsUnexport ( char * dirName /* Name of the directory to unexport */ ) { NFS_EXPORT_ENTRY * mntPoint; /* Mount point from mountPoints list */ /* Make sure there's a list of file systems */ if (mountPoints == NULL) return (ERROR); /* Find it and take it off the list */ if ((mntPoint = nfsExportFindByName (dirName)) != NULL) { semTake (mountSem, WAIT_FOREVER); lstDelete (mountPoints, (NODE *) mntPoint); nfsHashTblUnset (mntPoint->dirName, mntPoint->volumeId); semGive (mountSem); free (mntPoint); return (OK); } else { /* Didn't find it, set errno and return ERROR */ semGive (mountSem); errno = ENOENT; return (ERROR); } }/******************************************************************************** nfsExportFindByName - find a pointer to an exported file system** Given a directory name, return a pointer to the corresponding* NFS_EXPORT_ENTRY structure.* * RETURNS: OK, or NULL if the file system could not be found.* * NOMANUAL */NFS_EXPORT_ENTRY * nfsExportFindByName ( char * dirName /* name of file system to find */ ) { NFS_EXPORT_ENTRY * mntPoint = NULL; /* mount point from mountPoints list */ char matchName [PATH_MAX]; /* fs name to find */ /* Make sure the list exists */ if (mountPoints == NULL) return (NULL); /* Make sure matchName doesn't have ending slash */ strcpy (matchName, dirName); if (matchName[strlen (matchName) - 1] == '/') matchName[strlen (matchName) - 1] = EOS; /* Search through the list */ semTake (mountSem, WAIT_FOREVER); for (mntPoint = (NFS_EXPORT_ENTRY *) lstFirst (mountPoints); mntPoint != NULL; mntPoint = (NFS_EXPORT_ENTRY *) lstNext ((NODE *) mntPoint)) { if (strcmp(mntPoint->dirName, matchName) == 0) { /* Found it, give the semaphore and return */ semGive (mountSem); return (mntPoint); } } /* Didn't find a match, return NULL */ semGive (mountSem); return (NULL); }/******************************************************************************** nfsExportFindById - find a pointer to an exported file system* * Given a directory ID number, return a pointer to the corresponding* NFS_EXPORT_ENTRY structure.* * RETURNS: OK, or NULL if the file system could not be found.* * NOMANUAL*/NFS_EXPORT_ENTRY * nfsExportFindById ( int volumeId /* volume ID number */ ) { NFS_EXPORT_ENTRY * mntPoint; /* mount point from mountPoints list */ /* Make sure the list exists */ if (mountPoints == NULL) return (NULL); /* Search through the list */ semTake (mountSem, WAIT_FOREVER); for (mntPoint = (NFS_EXPORT_ENTRY *) lstFirst (mountPoints); mntPoint != NULL; mntPoint = (NFS_EXPORT_ENTRY *) lstNext ((NODE *) mntPoint)) { if (volumeId == mntPoint->volumeId) { /* Found it, give the semaphore and return */ semGive (mountSem); return (mntPoint); } } /* Didn't find a match, return NULL */ semGive (mountSem); return (NULL); }/******************************************************************************** nameToInode - file name to inode number* * Given a file name, return the inode number associated with it.* * RETURNS: the inode number for the file descriptor, or ERROR.** NOMANUAL*/int nameToInode ( int mntId, /* mount id */ char * fileName /* name of the file */ ) { int fd; /* File descriptor */ int inode; /* inode of file */ if ((fd = open (fileName, O_RDONLY, 0)) == ERROR) return (ERROR); else { inode = nfsNmLkupIns (mntId, fileName); } close (fd); return (inode); }/******************************************************************************** svc_reqToHostName - convert svc_req struct to host name* * Given a pointer to a svc_req structure, fill in a string with the* host name of the client associated with that svc_req structure.* The calling routine is responsible for allocating space for the* name string, which should be NAME_MAX characters long.** RETURNS: A pointer to the name of the client.* * NOMANUAL*/LOCAL char * svc_reqToHostName ( struct svc_req * rqstp, /* Client information */ char * hostName /* String to fill in with client name */ ) { /* Convert the callers address to a host name. If hostGetByAddr() * returns ERROR, convert the address to a numeric string */ if (hostGetByAddr (rqstp->rq_xprt->xp_raddr.sin_addr.s_addr, hostName)!= OK) inet_ntoa_b (rqstp->rq_xprt->xp_raddr.sin_addr, hostName); return (hostName); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -