📄 nfslib.c
字号:
** nfsExportShow - display the exported file systems of a remote host** This routine displays the file systems of a specified host and the groups* that are allowed to mount them.** EXAMPLE* .CS* -> nfsExportShow "wrs"* /d0 staff* /d1 staff eng* /d2 eng* /d3* value = 0 = 0x0* .CE** RETURNS: OK or ERROR.*/STATUS nfsExportShow ( char *hostName /* host machine to show exports for */ ) { exports nfsExports; if (hostName == NULL) { errnoSet (S_hostLib_INVALID_PARAMETER); return (ERROR); } if (nfsExportRead (hostName, &nfsExports) != OK) return (ERROR); if (nfsExports) nfsExportPrint (nfsExports); return (nfsExportFree (&nfsExports)); }/********************************************************************************* nfsLookUpByName - looks up a remote file** This routine returns information on a given file.* It takes the host name, mount handle, and file name, and returns the* file handle of the file and the file's attributes in pDirOpRes, and* the file handle of the directory that the file resides in in pDirHandle.** If the file name (directory path or filename itself) contains a symbolic* link, this routine changes the file name to incorporate the name of the link.** RETURNS: OK | ERROR | FOLLOW_LINK,* if FOLLOW_LINK, then fileName contains the name of the link** NOMANUAL*/int nfsLookUpByName ( char *hostName, char *fileName, /* name is changed if symbolic link */ nfs_fh *pMountHandle, /* these args are returned to calling routine */ FAST diropres *pDirOpRes, /* pointer to directory operation results */ nfs_fh *pDirHandle /* pointer to file's directory file handle */ ) { diropargs file; int nameCount = 0; char *nameArray [MAX_DIRNAMES]; /* ptrs to individual dir/file names * in path name */ char nameBuf [PATH_MAX + 1]; /* buffer for individual dir/file names */ char newLinkName [PATH_MAX + 1]; /* new file name if file is symb link */ char linkName [PATH_MAX + 1]; /* name of link file */ char currentDir [PATH_MAX + 1]; /* current dir for the look up's * that have been done */ if (nfsInit () != OK) return (ERROR); bzero ((char *) &file, sizeof (file)); /* parse file name, enter each directory name in the path into the array */ pathParse (fileName, nameArray, nameBuf); bcopy ((char *) pMountHandle, (char *) &file.dir, sizeof (nfs_fh)); bcopy ((char *) pMountHandle, (char *) pDirHandle, sizeof (nfs_fh)); /* start traversing file name */ while ((nameCount < MAX_DIRNAMES) && (nameArray [nameCount] != NULL)) { file.name = nameArray [nameCount]; if (nfsClientCall (hostName, NFS_PROGRAM, NFS_VERSION, NFSPROC_LOOKUP, xdr_diropargs, (char *) &file, xdr_diropres, (char *) pDirOpRes) == ERROR) { return (ERROR); } if (pDirOpRes->status != NFS_OK) { nfsErrnoSet (pDirOpRes->status); return (ERROR); } if (pDirOpRes->diropres_u.diropres.attributes.type == NFDIR) { /* save directory information */ /* Store the directory handle of the second to last entry * in the path name array. This is the directory where the * file in question (or directory in question) lives. */ if ((nameCount < MAX_DIRNAMES - 1) && (nameArray [nameCount + 1] != NULL)) { bcopy ((char *) &pDirOpRes->diropres_u.diropres.file, (char *) pDirHandle, sizeof (nfs_fh)); } /* copy directory handle for the next nfsClientCall */ bcopy ((char *) &pDirOpRes->diropres_u.diropres.file, (char *) &file.dir, sizeof (nfs_fh)); } else if (pDirOpRes->diropres_u.diropres.attributes.type == NFLNK) { /* symbolic link, get real path name */ if (nfsLinkGet (hostName, &pDirOpRes->diropres_u.diropres.file, linkName) == ERROR) { return (ERROR); } /* Change fileName to include name of link. * Concatenate the directory name, link name, * and rest of the path name following the link. */ *currentDir = EOS; if ((pathBuild (nameArray, &(nameArray [nameCount]), currentDir) == ERROR) || (pathCat (currentDir, linkName, newLinkName) == ERROR) || (pathBuild (&(nameArray [++nameCount]), (char **) NULL, newLinkName) == ERROR)) { return (ERROR); } pathCondense (newLinkName); (void) strcpy (fileName, newLinkName); return (FOLLOW_LINK); } nameCount++; /* look up next directory */ } /* while */ return (OK); }/********************************************************************************* nfsFileRemove - remove a file** RETURNS: OK or ERROR** NOMANUAL*/STATUS nfsFileRemove ( char * hostName, nfs_fh * pMountHandle, /* file handle of mount device */ char * fullFileName ) { u_int nfsProc; diropres dirResults; diropargs where; nfsstat status; int retVal; char fileName [NAME_MAX + 1]; char dirName [PATH_MAX + 1]; nfs_fh dirHandle; if (nfsInit () != OK) return (ERROR); bzero ((char *) &dirResults, sizeof (dirResults)); bzero ((char *) &status, sizeof (status)); pathSplit (fullFileName, dirName, fileName); /* * get info on the file to be removed, such as the handle of its directory * and its file type (so we know whether to delete a file or directory) * * note: some file servers will indeed delete a file with the * NFSPROC_RMDIR command */ retVal = nfsLookUpByName (hostName, fullFileName, pMountHandle, &dirResults, &dirHandle); if (retVal == FOLLOW_LINK) { return (FOLLOW_LINK); } else if (retVal == ERROR) return (ERROR); bcopy ((char *) &dirHandle, (char *) &where.dir, sizeof (nfs_fh)); where.name = fileName; switch (dirResults.diropres_u.diropres.attributes.type) { case NFREG: /* remove regular file */ case NFLNK: /* remove symbolic link */ nfsProc = NFSPROC_REMOVE; break; case NFDIR: /* remove directory */ nfsProc = NFSPROC_RMDIR; break; default: errnoSet (S_nfsLib_NFS_INAPPLICABLE_FILE_TYPE); return (ERROR); } if (nfsClientCall (hostName, NFS_PROGRAM, NFS_VERSION, nfsProc, xdr_diropargs, (char *) &where, xdr_nfsstat, (char *) &status) == ERROR) { return (ERROR); } if (status != NFS_OK) { nfsErrnoSet (status); return (ERROR); } return (OK); }/********************************************************************************* nfsRename - rename a file** RETURNS: OK or ERROR** NOMANUAL*/STATUS nfsRename ( char * hostName, nfs_fh * pMountHandle, char * oldName, nfs_fh * pOldDirHandle, char * newName ) { diropres dirResults; renameargs renameArgs; nfsstat status; char newFileName [NAME_MAX + 1]; char oldFileName [NAME_MAX + 1]; char newDirName [PATH_MAX + 1]; char oldDirName [PATH_MAX + 1]; nfs_fh dummyDirHandle; if (nfsInit () != OK) return (ERROR); if ((strlen (oldName) > PATH_MAX) || (strlen (newName) > PATH_MAX)) { errnoSet (S_ioLib_NAME_TOO_LONG); return (ERROR); } bzero ((char *) &dirResults, sizeof (dirResults)); bzero ((char *) &status, sizeof (status)); pathSplit (oldName, oldDirName, oldFileName); pathSplit (newName, newDirName, newFileName); bcopy ((char *) pOldDirHandle, (char *) &renameArgs.from.dir, sizeof (nfs_fh)); renameArgs.from.name = oldFileName; if (newDirName [0] == EOS) { /* NULL directory name */ bcopy ((char *) pMountHandle, (char *) &renameArgs.to.dir, sizeof (nfs_fh)); } else { if (nfsLookUpByName (hostName, newDirName, pMountHandle, &dirResults, &dummyDirHandle) != OK) return (ERROR); bcopy ((char *) &dirResults.diropres_u.diropres.file, (char *) &renameArgs.to.dir, sizeof (nfs_fh)); } renameArgs.to.name = newFileName; if (nfsClientCall (hostName, NFS_PROGRAM, NFS_VERSION, NFSPROC_RENAME, xdr_renameargs, (char *) &renameArgs, xdr_nfsstat, (char *) &status) == ERROR) { return (ERROR); } if (status != NFS_OK) { nfsErrnoSet (status); return (ERROR); } return (OK); }/********************************************************************************* nfsThingCreate - creates file or directory** RETURNS: OK | ERROR | FOLLOW_LINK,* if FOLLOW_LINK, then fullFileName contains the name of the link** NOMANUAL*/int nfsThingCreate ( char * hostName, char * fullFileName, /* name of thing being created */ nfs_fh * pMountHandle, /* mount device's file handle */ diropres * pDirOpRes, /* ptr to returned direc. operation results */ nfs_fh * pDirHandle, /* ptr to returned file's directory file hndl */ u_int mode /* mode that file or dir is created with * UNIX chmod style */ ) { FAST int status; char newName [PATH_MAX + 1]; /* new name if name contained a link */ char dirName [PATH_MAX + 1]; /* dir where file will be created */ char fileName[NAME_MAX + 1]; /* name of file without path */ char tmpName [PATH_MAX + 1 + 3]; /* temporary file name, * extra four chars because * it adds /../ to the * filename. */ FAST sattr *pSattr; /* ptr to attributes */ diropres lookUpResult; createargs createArgs; nfs_fh dummyDirHandle; u_int nfsProc; /* which nfs procedure to call, * depending on whether a file or * directory is made */ if (nfsInit () != OK) return (ERROR); bzero ((char *) &createArgs, sizeof (createArgs)); bzero ((char *) &lookUpResult, sizeof (lookUpResult)); bzero ((char *) pDirOpRes, sizeof (diropres)); pathSplit (fullFileName, dirName, fileName); status = nfsLookUpByName (hostName, dirName, pMountHandle, &lookUpResult, &dummyDirHandle); if (status == FOLLOW_LINK) { if ((strlen (dirName) + strlen (fileName) + 1) > PATH_MAX) { errnoSet (S_ioLib_NAME_TOO_LONG); status = ERROR; } else { pathCat (dirName, fileName, newName); (void) strcpy (fullFileName, newName); } } if (status != OK) return (status); bcopy ((char *) &lookUpResult.diropres_u.diropres.file, (char *) &createArgs.where.dir, sizeof (nfs_fh)); bcopy ((char *) &lookUpResult.diropres_u.diropres.file, (char *) pDirHandle, sizeof (nfs_fh)); createArgs.where.name = fileName; pSattr = &createArgs.attributes; if (mode == 0) /* create a file with default permissions */ pSattr->mode = NFS_FSTAT_REG | DEFAULT_FILE_PERM; else pSattr->mode = mode; /* don't set these attributes */ pSattr->uid = pSattr->gid = pSattr->size = -1; /* user ID */ pSattr->atime.seconds = pSattr->atime.useconds = -1; pSattr->mtime.seconds = pSattr->mtime.useconds = -1; if (mode & NFS_FSTAT_DIR) nfsProc = NFSPROC_MKDIR; else nfsProc = NFSPROC_CREATE; if (nfsClientCall (hostName, NFS_PROGRAM, NFS_VERSION, nfsProc, xdr_createargs, (char *) &createArgs, xdr_diropres, (char *) pDirOpRes) == ERROR) { return (ERROR); } /* * If the file created is really a symlink, then change the name and * return FOLLOW_LINK */ if (pDirOpRes->diropres_u.diropres.attributes.type == NFLNK) { strcpy (tmpName, fullFileName); /* Make a copy of fullFileName to * use with nfsLinkGet */ nfsLinkGet (hostName, &pDirOpRes->diropres_u.diropres.file, tmpName); /* * Need to replace last element of fullFileName with return value from * nfsLinkGet. Add /../newFileName to fullFileName, call * pathCondense(). */ strcpy (fullFileName, tmpName); return (FOLLOW_LINK); } if (pDirOpRes->status != NFS_OK) { nfsErrnoSet (pDirOpRes->status); return (ERROR); } return (OK); }/********************************************************************************* nfsFileWrite - write to a file** Either all characters will be written, or there is an ERROR.** RETURNS: number of characters written | ERROR** NOMANUAL*/int nfsFileWrite ( char * hostName, nfs_fh * pHandle, /* file handle of file being written to */ unsigned offset, /* current byte offset in file */ unsigned count, /* number of bytes to write */ char * data, /* data to be written (up to NFS_MAXDATA) */ fattr * pNewAttr ) { FAST unsigned nWrite = 0; /* bytes written in one nfs write */ FAST unsigned nTotalWrite = 0; /* bytes written in all writes together */ writeargs writeArgs; /* arguments to pass to nfs server */ attrstat writeResult; /* info returned from nfs server */ if (nfsInit () != OK) return (ERROR); bzero ((char *) &writeArgs, sizeof (writeArgs)); bcopy ((char *) pHandle, (char *) &writeArgs.file, sizeof (nfs_fh)); /* set offset into file where write starts */ writeArgs.offset = offset; while (nTotalWrite < count) { /* can only write up to NFS_MAXDATA bytes in one nfs write */ if (count - nTotalWrite > nfsMaxMsgLen) nWrite = nfsMaxMsgLen; else nWrite = count - nTotalWrite; writeArgs.totalcount = nWrite; writeArgs.data.data_len = nWrite;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -