📄 nfsdlib.c
字号:
* NOMANUAL*/void * nfsproc_writecache_2 ( void ) { /* Increment statistics */ nfsdServerStatus.writecacheCalls++; return ((void *) KHEAP_ALLOC(0)); }/******************************************************************************** nfsproc_write_2 -* * Writes "data" beginning "offset" bytes from the beginning of "file".* The first byte of the file is at offset zero. If the reply "status"* is NFS_OK, then the reply "attributes" contains the attributes of the* file after the write has completed. The write operation is atomic.* Data from this "WRITE" will not be mixed with data from another* client's "WRITE".* * Notes: The arguments "beginoffset" and "totalcount" are ignored and* are removed in the next protocol revision.** NOMANUAL*/attrstat * nfsproc_write_2 ( writeargs * wrArgs /* File, write data, and offset information */ ) { char * fileName; /* Name of the file to write */ attrstat * retVal; /* Return value */ int fd; /* File descriptor for file to write */ int nBytes; /* Number of bytes actually written */ int writeCount; /* Number of bytes to write */ BOOL writeError = FALSE; if ((retVal = KHEAP_ALLOC(sizeof (*retVal))) == NULL) return (NULL); if ((fileName = (char *) alloca (nfsMaxPath)) == NULL) return (NULL); /* Increment statistics */ nfsdServerStatus.writeCalls++; nfsdFhNtoh ((NFS_FILE_HANDLE *) &wrArgs->file); /* Make sure the file system is writeable */ if (nfsdFsReadOnly((NFS_FILE_HANDLE *) &wrArgs->file)) { retVal->status = NFSERR_ACCES; return (retVal); } if (nfsdFhToName ((NFS_FILE_HANDLE *) &wrArgs->file, fileName) == ERROR) { retVal->status = nfsdErrToNfs (errno); return (retVal); } if ((fd = open (fileName, O_WRONLY, 0)) == ERROR) { retVal->status = nfsdErrToNfs (errno); return (retVal); } if (lseek (fd, wrArgs->offset, SEEK_SET) != wrArgs->offset) { retVal->status = nfsdErrToNfs (errno); close (fd); return (retVal); } errno = OK; writeCount = wrArgs->data.data_len; if ((nBytes = write (fd, wrArgs->data.data_val, writeCount)) != writeCount) { if (errno == OK) { /* Try this twice to get around a dosFs bug */ writeCount -= nBytes; if (write (fd, wrArgs->data.data_val, writeCount) != writeCount) writeError = TRUE; } else writeError = TRUE; if (writeError) { retVal->status = nfsdErrToNfs (errno); close (fd); return (retVal); } } if (close (fd) == ERROR) { retVal->status = nfsdErrToNfs (errno); return (retVal); } if (nfsdFattrGet ((NFS_FILE_HANDLE *) &wrArgs->file, &retVal->attrstat_u.attributes) == ERROR) { retVal->status = nfsdErrToNfs (errno); return (retVal); } retVal->status = NFS_OK; return (retVal); }/******************************************************************************** nfsproc_create_2 - create a file* * The file "name" is created in the directory given by "dir". The* initial attributes of the new file are given by "attributes". A* reply "status" of NFS_OK indicates that the file was created, and* reply "file" and reply "attributes" are its file handle and* attributes. Any other reply "status" means that the operation failed* and no file was created.* * Notes: This routine should pass an exclusive create flag, meaning* "create the file only if it is not already there".* * NOMANUAL*/diropres * nfsproc_create_2 ( createargs * newFile /* File to create */ ) { diropres * retVal = KHEAP_ALLOC(sizeof (diropres)); /* Return value */ char * newName; /* Name of file to create */ int fd; /* File descriptor for file to create */ if (retVal == NULL) return (NULL); if ((newName = (char *) alloca (nfsMaxPath)) == NULL) return (NULL); /* Increment statistics */ nfsdServerStatus.createCalls++; /* Create the name for the new file by getting the name of the directory, * followed by "/" and the name of the new file */ nfsdFhNtoh ((NFS_FILE_HANDLE *) &newFile->where.dir); /* Make sure the file system is writeable */ if (nfsdFsReadOnly((NFS_FILE_HANDLE *) &newFile->where.dir)) { retVal->status = NFSERR_ACCES; return (retVal); } if (nfsdFhToName ((NFS_FILE_HANDLE *) &newFile->where.dir, newName) == ERROR) { retVal->status = nfsdErrToNfs (errno); return (retVal); } strcat (newName, "/"); strcat (newName, newFile->where.name); /* Check if the file has been created already */ if ((fd = open (newName, O_RDWR, 0)) != ERROR) { retVal->status = NFSERR_EXIST; close(fd); return (retVal); } /* Create the file */ if ((fd = open (newName, O_RDWR | O_CREAT, 0)) == ERROR) { retVal->status = nfsdErrToNfs (errno); return (retVal); } if (close (fd) == ERROR) { retVal->status = nfsdErrToNfs (errno); return (retVal); } /* Create its file handle */ if (nfsdFhCreate ((NFS_FILE_HANDLE *) &newFile->where.dir, newFile->where.name, (NFS_FILE_HANDLE *) &retVal->diropres_u.diropres.file) == ERROR) { retVal->status = nfsdErrToNfs (errno); return (retVal); } /* Get its attributes */ if (nfsdFattrGet ((NFS_FILE_HANDLE *) &retVal->diropres_u.diropres.file, &retVal->diropres_u.diropres.attributes) == ERROR) { retVal->status = nfsdErrToNfs (errno); return (retVal); } retVal->status = NFS_OK; nfsdFhHton ((NFS_FILE_HANDLE *) &retVal->diropres_u.diropres.file); return (retVal); }/******************************************************************************** nfsproc_remove_2 - remove a file* * The file "name" is removed from the directory given by "dir". A* reply of NFS_OK means the directory entry was removed.* * Notes: possibly non-idempotent operation.* * NOMANUAL*/nfsstat * nfsproc_remove_2 ( diropargs * removeFile /* File to be removed */ ) { nfsstat * retVal = KHEAP_ALLOC(sizeof (nfsstat)); /* Return value */ char * newName; /* Name of the file to be removed */ if (retVal == NULL) return NULL; if ((newName = (char *) alloca (nfsMaxPath)) == NULL) return (NULL); /* Increment statistics */ nfsdServerStatus.removeCalls++; /* Create the name for removed file by getting the name of the directory, * followed by "/" and the name of the new file */ nfsdFhNtoh ((NFS_FILE_HANDLE *) &removeFile->dir); /* Make sure the file system is writeable */ if (nfsdFsReadOnly((NFS_FILE_HANDLE *) &removeFile->dir)) { *retVal = NFSERR_ACCES; return (retVal); } if (nfsdFhToName ((NFS_FILE_HANDLE *) &removeFile->dir, newName) == ERROR) { *retVal = nfsdErrToNfs (errno); return (retVal); } strcat (newName, "/"); strcat (newName, removeFile->name); /* Do the removal */ if (unlink (newName) == ERROR) *retVal = nfsdErrToNfs (errno); else *retVal = NFS_OK; return (retVal); }/******************************************************************************** nfsproc_rename_2 - rename a file* * The existing file "from.name" in the directory given by "from.dir" is* renamed to "to.name" in the directory given by "to.dir". If the* reply is NFS_OK, the file was renamed. The RENAME operation is* atomic on the server; it cannot be interrupted in the middle.* * Notes: possibly non-idempotent operation.* * NOMANUAL*/nfsstat * nfsproc_rename_2 ( renameargs * names /* New and old file names */ ) { nfsstat * retVal = KHEAP_ALLOC(sizeof (nfsstat)); /* Return value */ char * oldName; /* Old file name */ char * newName; /* New file name */ /* Increment statistics */ nfsdServerStatus.renameCalls++; if (retVal == NULL) return (NULL); if ((oldName = (char *) alloca (nfsMaxPath)) == NULL) return (NULL); if ((newName = (char *) alloca (nfsMaxPath)) == NULL) return (NULL); /* Create strings for the old and new file names */ nfsdFhNtoh ((NFS_FILE_HANDLE *) &names->from.dir); nfsdFhNtoh ((NFS_FILE_HANDLE *) &names->to.dir); /* Make sure the file system is writeable */ if (nfsdFsReadOnly((NFS_FILE_HANDLE *) &names->from.dir)) { *retVal = NFSERR_ACCES; return (retVal); } if (nfsdFhToName ((NFS_FILE_HANDLE *) &names->from.dir, oldName) == ERROR) { *retVal = nfsdErrToNfs (errno); return (retVal); } strcat (oldName, "/"); strcat (oldName, names->from.name); if (nfsdFhToName ((NFS_FILE_HANDLE *) &names->to.dir, newName) == ERROR) { *retVal = nfsdErrToNfs (errno); return (retVal); } strcat (newName, "/"); strcat (newName, names->to.name); /* Do the rename() */ if (rename (oldName, newName) == ERROR) { *retVal = nfsdErrToNfs (errno); return (retVal); } else *retVal = NFS_OK; return (retVal); }/******************************************************************************** nfsproc_link_2 - create a link - not supported by VxWorks** NOMANUAL*/nfsstat * nfsproc_link_2 ( void ) { nfsstat * notSupported = KHEAP_ALLOC(sizeof (nfsstat)); *notSupported = EOPNOTSUPP; return ((nfsstat *) notSupported); }/******************************************************************************** nfsproc_symlink_2 - create a symbolic link - not supported by VxWorks** NOMANUAL*/nfsstat * nfsproc_symlink_2 ( void ) { nfsstat * notSupported = KHEAP_ALLOC(sizeof (nfsstat)); /* Increment statistics */ nfsdServerStatus.symlinkCalls++; *notSupported = EOPNOTSUPP; return ((nfsstat *) notSupported); }/******************************************************************************** nfsproc_mkdir_2 - create a directory* * The new directory "where.name" is created in the directory given by* "where.dir". The initial attributes of the new directory are given* by "attributes". A reply "status" of NFS_OK indicates that the new* directory was created, and reply "file" and reply "attributes" are* its file handle and attributes. Any other reply "status" means that* the operation failed and no directory was created.* * Notes: possibly non-idempotent operation.** NOMANUAL*/diropres * nfsproc_mkdir_2 ( createargs * crArgs ) { diropres * retVal = KHEAP_ALLOC(sizeof (diropres)); char * newName; if (retVal == NULL) return (NULL); if ((newName = (char *) alloca (nfsMaxPath)) == NULL) return (NULL); /* Increment statistics */ nfsdServerStatus.mkdirCalls++; retVal->status = NFS_OK; /* Create the string for the name of the directory to make */ nfsdFhNtoh ((NFS_FILE_HANDLE *) &crArgs->where.dir); /* Make sure the file system is writeable */ if (nfsdFsReadOnly((NFS_FILE_HANDLE *) &crArgs->where.dir)) { retVal->status = NFSERR_ACCES; return (retVal); } if (nfsdFhToName ((NFS_FILE_HANDLE *) &crArgs->where.dir, newName) == ERROR) { retVal->status = nfsdErrToNfs (errno); return (retVal); } strcat (newName, "/"); strcat (newName, crArgs->where.name); /* make the directory */ if (mkdir (newName) == ERROR) { retVal->status = nfsdErrToNfs (errno); return (retVal); } /* Create a file handle for the new directory */ if (nfsdFhCreate ((NFS_FILE_HANDLE *) &crArgs->where.dir, crArgs->where.name, (NFS_FILE_HANDLE *) &retVal->diropres_u.diropres.file) == ERROR) { retVal->status = nfsdErrToNfs (errno); return (retVal); } /* Get the file attributes for the new directory */ if (nfsdFattrGet ((NFS_FILE_HANDLE *) &retVal->diropres_u.diropres.file, &retVal->diropres_u.diropres.attributes) == ERROR) { retVal->status = nfsdErrToNfs (errno); return (retVal); } nfsdFhHton ((NFS_FILE_HANDLE *) &retVal->diropres_u.diropres.file); return (retVal); }/******************************************************************************** nfsproc_rmdir_2 - remove a directory* * The existing empty directory "name" in the directory given by "dir"* is removed. If the reply is NFS_OK, the directory was removed.* * Notes: possibly non-idempotent operation.** NOMANUAL*/nfsstat * nfsproc_rmdir_2 ( diropargs * removeDir /* Directory to remove */ ) { nfsstat * retVal = KHEAP_ALLOC(sizeof (nfsstat)); /* Return value */ char * newName; /* Path name of directory to remove */ if (retVal == NULL) return NULL; if ((newName = (char *) alloca (nfsMaxPath)) == NULL) return (NULL); /* Increment statistics */ nfsdServerStatus.rmdirCalls++; nfsdFhNtoh ((NFS_FILE_HANDLE *) &removeDir->dir); /* Make sure the file system is writeable */ if (nfsdFsReadOnly((NFS_FILE_HANDLE *) &removeDir->dir)) { *retVal = NFSERR_ACCES; return (retVal); } /* Create the name of the doomed directory */ if (nfsdFhToName ((NFS_FILE_HANDLE *) &removeDir->dir, newName) == ERROR) { *retVal = nfsdErrToNfs (errno); return (retVal); } strcat (newName, "/"); strcat (newName, removeDir->name); /* Remove it */ if (rmdir (newName) == ERROR) *retVal = nfsdErrToNfs (errno); else *retVal = NFS_OK; return (retVal); }/******************************************************************************** nfsproc_readdir_2 - read from a directory* * Returns a variable number of directory entries, with a total size of* up to "count" bytes, from the directory given by "dir". If the* returned value of "status" is NFS_OK, then it is followed by a* variable number of "entry"s. Each "entry" contains a "fileid" which* consists of a unique number to identify the file within a filesystem,* the "name" of the file, and a "cookie" which is an opaque pointer to* the next entry in the directory. The cookie is used in the next* READDIR call to get more entries starting at a given point in the* directory. The special cookie zero (all bits zero) can be used to* get the entries starting at the beginning of the directory. The* "fileid" field should be the same number as the "fileid" in the the* attributes of the file. (See section "2.3.5. fattr" under "Basic* Data Types".) The "eof" flag has a value of TRUE if there are no* more entries in the directory.* * NOMANUAL*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -