📄 nfsdrv.c
字号:
nfsExportFree (&nfsExportBody); return (status); }/********************************************************************************* nfsDevShow - display the mounted NFS devices** This routine displays the device names and their associated NFS file systems.** EXAMPLE:* .CS* -> nfsDevShow* device name file system* ----------- -----------* /yuba1/ yuba:/yuba1* /wrs1/ wrs:/wrs1* .CE** RETURNS: N/A*/void nfsDevShow (void) { char fileSysName [MAX_FILENAME_LENGTH]; DEV_HDR *pDev0 = NULL; DEV_HDR *pDev1; printf ("%-20.20s %-50.50s\n", "device name", "file system"); printf ("%-20.20s %-50.50s\n", "-----------", "-----------"); /* get entries from the I/O system's device list */ while ((pDev1 = iosNextDevGet (pDev0)) != NULL) { if (pDev1->drvNum == nfsDrvNum) { /* found an nfs device, print information */ (void) strcpy (fileSysName, ((NFS_DEV *) pDev1)->host); (void) strcat (fileSysName, ":"); (void) strcat (fileSysName, ((NFS_DEV *) pDev1)->fileSystem); printf ("%-20.20s %-50.50s\n", pDev1->name, fileSysName); } pDev0 = pDev1; } }/********************************************************************************* nfsUnmount - unmount an NFS device** This routine unmounts file systems that were previously mounted via NFS.** RETURNS: OK, or ERROR if <localName> is not an NFS device or cannot* be mounted.* * SEE ALSO: nfsMount()*/STATUS nfsUnmount ( char *localName /* local of nfs device */ ) { FAST NFS_DEV *pNfsDev; char *dummy; /* find the device in the I/O system */ if ((pNfsDev = (NFS_DEV *) iosDevFind (localName, &dummy)) == NULL) return (ERROR); /* make sure device is an nfs driver and the names match exactly */ if ((pNfsDev->devHdr.drvNum != nfsDrvNum) || (strcmp (pNfsDev->devHdr.name, localName) != 0)) { errnoSet (S_nfsDrv_NOT_AN_NFS_DEVICE); return (ERROR); } /* perform an nfs unmount of the directory */ if (nfsDirUnmount (pNfsDev->host, pNfsDev->fileSystem) == ERROR) return (ERROR); /* delete the device from the I/O system */ iosDevDelete ((DEV_HDR *) pNfsDev); free ((char *) pNfsDev); return (OK); }/********************************************************************************* nfsDevListGet - create list of all the NFS devices in the system** This routine fills the array <nfsDevlist> up to <listSize>, with handles to* NFS devices currently in the system.** RETURNS: The number of entries filled in the <nfsDevList> array.* * SEE ALSO: nfsDevInfoGet()*/int nfsDevListGet ( unsigned long nfsDevList[], /* NFS dev list of handles */ int listSize /* number of elements available in the list */ ) { int numMounted; DEV_HDR * pDev0 = NULL; DEV_HDR * pDev1; /* Collect information of all the NFS currently mounted. */ numMounted = 0; while ((numMounted < listSize) && ((pDev1 = iosNextDevGet (pDev0)) != NULL)) { if (pDev1->drvNum == nfsDrvNum) { /* found an nfs device, save pointer to the device */ nfsDevList [numMounted] = (unsigned long) pDev1; numMounted++; } pDev0 = pDev1; } return (numMounted); }/********************************************************************************* nfsDevInfoGet - read configuration information from the requested NFS device** This routine accesses the NFS device specified in the parameter <nfsDevHandle>* and fills in the structure pointed to by <pnfsInfo>.** RETURNS: OK if <pnfsInfo> information is valid, otherwise ERROR.* * SEE ALSO: nfsDevListGet()*/STATUS nfsDevInfoGet ( unsigned long nfsDevHandle, /* NFS device handle */ NFS_DEV_INFO * pnfsInfo /* ptr to struct to hold config info */ ) { NFS_DEV *pnfsDev; DEV_HDR *pDev0; DEV_HDR *pDev1; if (pnfsInfo == NULL) return (ERROR); /* Intialize pointer variables */ pnfsDev = NULL; pDev0 = NULL; /* Verify that the device is still in the list of devices */ while ((pDev1 = iosNextDevGet (pDev0)) != NULL) { if (pDev1 == (DEV_HDR *) nfsDevHandle) { pnfsDev = (NFS_DEV *) pDev1; break; /* Found Device */ } pDev0 = pDev1; } if (pnfsDev != NULL) { strcpy (pnfsInfo->hostName, pnfsDev->host); strcpy (pnfsInfo->remFileSys, pnfsDev->fileSystem); strcpy (pnfsInfo->locFileSys, pnfsDev->devHdr.name); return (OK); } return (ERROR); }/* routines supplied to the I/O system *//********************************************************************************* nfsCreate - create a remote NFS file** Returns an open nfs file descriptor.** Used for creating files only, not directories.* Called only by the I/O system.** To give the file a particular mode (UNIX chmod() style), use nfsOpen().** RETURNS: Pointer to NFS file descriptor, or ERROR.*/LOCAL int nfsCreate ( NFS_DEV *pNfsDev, /* pointer to nfs device */ char *fileName, /* nfs file name (relative to mount point) */ int mode /* mode (O_RDONLY, O_WRONLY, or O_RDWR) */ ) { /* file descriptor mode legality is checked for in nfsOpen */ /* don't allow null filenames */ if (fileName [0] == EOS) { errnoSet (S_ioLib_NO_FILENAME); return (ERROR); } /* open the file being created, give the file default UNIX file permissions */ return (nfsOpen (pNfsDev, fileName , O_CREAT | O_TRUNC | mode, DEFAULT_FILE_PERM)); }/********************************************************************************* nfsDelete - delete a remote file** Deletes a file on a remote system.* Called only by the I/O system.** RETURNS: OK or ERROR.*/LOCAL int nfsDelete ( NFS_DEV *pNfsDev, /* pointer to nfs device */ char *fileName /* remote file name */ ) { /* don't allow null filenames */ if (fileName [0] == EOS) { errnoSet (S_ioLib_NO_FILENAME); return (ERROR); } return (nfsFileRemove (pNfsDev->host, &pNfsDev->fileHandle, fileName)); }/********************************************************************************* nfsOpen - open an NFS file** This routine opens the remote file.* Called only by the I/O system.** RETURNS: pointer to open network file descriptor || FOLLOW_LINK || ERROR*/LOCAL int nfsOpen ( NFS_DEV *pNfsDev, /* pointer to nfs device */ char *fileName, /* remote file or directory name to open */ int flags, /* O_RDONLY, O_WRONLY, or O_RDWR and O_CREAT */ int mode /* UNIX chmod style */ ) { int status = OK; char fullName [PATH_MAX + 1]; /* full file or directory name */ FAST NFS_FD *nfsFd; diropres dirResult; /* directory info returned via nfs */ int retVal; nfs_fh dirHandle; /* file's directory file handle */ int openMode = flags & FD_MODE; /* mode to open file with (O_RDONLY, O_WRONLY, or O_RDWR */ /* NFS permissions */ int filePermissions; /* permissions of the opened file */ int requestPerms = 0; /* requested file permissions */ char machineName [AUTH_UNIX_FIELD_LEN]; int uid; /* user ID */ int gid; /* group ID */ int nGids; /* number of groups */ int gids [MAX_GRPS]; /* array of group IDs */ BOOL correctPerms = FALSE; /* set to TRUE if perms match */ BOOL sameUid = FALSE; /* set to TRUE if users match */ BOOL sameGid = FALSE; /* set to TRUE if groups match */ if ( (openMode != O_RDONLY) && (openMode != O_WRONLY) && (openMode != O_RDWR)) { errnoSet (S_nfsDrv_BAD_FLAG_MODE); return (ERROR); } if (fileName [0] == EOS) { if (flags & O_CREAT) { errnoSet (S_nfsDrv_CREATE_NO_FILE_NAME); return (ERROR); } (void) strcpy (fullName, "."); } else (void) strcpy (fullName, fileName); /* truncate file */ if (flags & O_TRUNC) { retVal = nfsDelete (pNfsDev, fullName); if ( (retVal == ERROR) && !(flags & O_CREAT)) return (ERROR); else if (retVal == FOLLOW_LINK) { (void) strcpy (fileName, fullName); return (FOLLOW_LINK); } } if ( (flags & O_CREAT) || (flags & O_TRUNC)) /* create file or directory */ { retVal = nfsLookUpByName (pNfsDev->host, fullName, &pNfsDev->fileHandle, &dirResult, &dirHandle); if (retVal == FOLLOW_LINK) { (void) strcpy (fileName, fullName); return (FOLLOW_LINK); } status = nfsThingCreate (pNfsDev->host, fullName, &pNfsDev->fileHandle, &dirResult, &dirHandle, (u_int)mode); } else /* open existing file or directory */ { status = nfsLookUpByName (pNfsDev->host, fullName, &pNfsDev->fileHandle, &dirResult, &dirHandle); } /* Check file permissions */ filePermissions = dirResult.diropres_u.diropres.attributes.mode; switch (openMode) { case O_RDONLY: requestPerms = 4; break; case O_WRONLY: requestPerms = 2; break; case O_RDWR: requestPerms = 6; break; } /* Check if uid and gid match file uid and gid */ nfsAuthUnixGet (machineName, &uid, &gid, &nGids, gids); sameUid = (uid == dirResult.diropres_u.diropres.attributes.uid ? TRUE : FALSE); if (gid == dirResult.diropres_u.diropres.attributes.gid) sameGid = TRUE; else while (nGids) if (gids [--nGids] == dirResult.diropres_u.diropres.attributes.gid) { sameGid = TRUE; break; } /* Check "other" permissions */ if (!sameGid && !sameUid && ((filePermissions & requestPerms) == requestPerms)) correctPerms = TRUE; /* check group permissions */ else if (sameGid && ((filePermissions & (requestPerms << 3)) == (requestPerms << 3))) correctPerms = TRUE; /* check user permissions */ else if (sameUid && ((filePermissions & (requestPerms << 6)) == (requestPerms << 6))) correctPerms = TRUE; else { errno = EACCES; return (ERROR); } /* * If the name returned by nfsLookUpByName doesn't start with a * slash, then nfsLookUpByName has changed the name to the link, but the * name no longer includes the name of the correct device. If you pass * this to iosDevFind, it returns a path on the default device, which is * wrong (unless, of course, you get lucky and you are in fact looking * for something on the default device). So, need to prepend the name of * the NFS device if fullName doesn't include it already. */ if (status == FOLLOW_LINK) { if (fullName [0] != '/') { pathCat (pNfsDev->devHdr.name, fullName, fileName); } else { (void) strcpy (fileName, fullName); } } if (status != OK) return (status); if ((nfsFd = (NFS_FD *) malloc (sizeof (NFS_FD) + nfsCacheSize)) == NULL) return (ERROR); /* fill in file descriptor with newly retrieved information */ bcopy ((char *) &dirResult.diropres_u.diropres.file, (char *) &nfsFd->fileHandle, sizeof (nfs_fh)); bcopy ((char *) &dirHandle, (char *) &nfsFd->dirHandle, sizeof (nfs_fh)); bcopy ((char *) &dirResult.diropres_u.diropres.attributes, (char *) &nfsFd->fileAttr, sizeof (fattr)); nfsFd->fileCurByte = 0; nfsFd->mode = openMode; nfsFd->cacheValid = FALSE; nfsFd->cacheBuf = (char *) ((u_int) nfsFd + sizeof (NFS_FD)); nfsFd->cacheCurByte = nfsFd->cacheBuf; nfsFd->cacheDirty = FALSE; nfsFd->cacheBytesLeft = 0; nfsFd->nfsDev = pNfsDev; semMInit (&nfsFd->nfsFdSem, mutexOptionsNfsDrv); return ((int) nfsFd); }/********************************************************************************* nfsClose - close a remote file** Called only by the I/O system.** RETURNS: OK or ERROR if file failed to flush*/LOCAL STATUS nfsClose ( FAST NFS_FD *nfsFd /* nfs file descriptor */ ) { int status = OK; semTake (&nfsFd->nfsFdSem, WAIT_FOREVER); if (nfsFd->cacheDirty) status = nfsCacheFlush (nfsFd); semTerminate (&nfsFd->nfsFdSem); /* terminate nfs fd semaphore */ free ((char *) nfsFd); /* close client if "auto close" is selected */ if (nfsAutoClose) nfsClientClose (); return (status == ERROR ? ERROR : OK); }/********************************************************************************* nfsRead - read bytes from remote file** nfsRead reads the specified number of bytes from the open NFS* file and puts them into a buffer. Bytes are read starting* from the point marked by the file pointer. The file pointer is then* updated to point immediately after the last character that was read.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -