 ef7b484e5c
			
		
	
	
		ef7b484e5c
		
	
	
	
	
		
			
			This Shared Folders File System library (libsffs) now contains all the file system logic originally in HGFS. The actual HGFS server code is now a stub that passes on all the work to libsffs. The libhgfs library is changed accordingly.
		
			
				
	
	
		
			173 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			173 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */
 | |
| 
 | |
| #include "inc.h"
 | |
| 
 | |
| #include <fcntl.h>
 | |
| #include <sys/stat.h>
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *				hgfs_open				     *
 | |
|  *===========================================================================*/
 | |
| int hgfs_open(path, flags, mode, handle)
 | |
| char *path;			/* path name to open */
 | |
| int flags;			/* open flags to use */
 | |
| int mode;			/* mode to create (user bits only) */
 | |
| sffs_file_t *handle;		/* place to store resulting handle */
 | |
| {
 | |
| /* Open a file. Store a file handle upon success.
 | |
|  */
 | |
|   int r, type;
 | |
| 
 | |
|   /* We could implement this, but that means we would have to start tracking
 | |
|    * open files in order to associate data with them. Rather not.
 | |
|    */
 | |
|   if (flags & O_APPEND) return EINVAL;
 | |
| 
 | |
|   if (flags & O_CREAT) {
 | |
|     if (flags & O_EXCL) type = HGFS_OPEN_TYPE_C;
 | |
|     else if (flags & O_TRUNC) type = HGFS_OPEN_TYPE_COT;
 | |
|     else type = HGFS_OPEN_TYPE_CO;
 | |
|   } else {
 | |
|     if (flags & O_TRUNC) type = HGFS_OPEN_TYPE_OT;
 | |
|     else type = HGFS_OPEN_TYPE_O;
 | |
|   }
 | |
| 
 | |
|   RPC_REQUEST(HGFS_REQ_OPEN);
 | |
|   RPC_NEXT32 = (flags & O_ACCMODE);
 | |
|   RPC_NEXT32 = type;
 | |
|   RPC_NEXT8 = HGFS_MODE_TO_PERM(mode);
 | |
| 
 | |
|   path_put(path);
 | |
| 
 | |
|   if ((r = rpc_query()) != OK)
 | |
| 	return r;
 | |
| 
 | |
|   *handle = (sffs_file_t)RPC_NEXT32;
 | |
| 
 | |
|   return OK;
 | |
| }
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *				hgfs_read				     *
 | |
|  *===========================================================================*/
 | |
| ssize_t hgfs_read(handle, buf, size, off)
 | |
| sffs_file_t handle;		/* handle to open file */
 | |
| char *buf;			/* data buffer or NULL */
 | |
| size_t size;			/* maximum number of bytes to read */
 | |
| u64_t off;			/* file offset */
 | |
| {
 | |
| /* Read from an open file. Upon success, return the number of bytes read.
 | |
|  */
 | |
|   int r, len, max;
 | |
| 
 | |
|   RPC_REQUEST(HGFS_REQ_READ);
 | |
|   RPC_NEXT32 = (u32_t)handle;
 | |
|   RPC_NEXT32 = ex64lo(off);
 | |
|   RPC_NEXT32 = ex64hi(off);
 | |
| 
 | |
|   max = RPC_BUF_SIZE - RPC_LEN - sizeof(u32_t);
 | |
|   RPC_NEXT32 = (size < max) ? size : max;
 | |
| 
 | |
|   if ((r = rpc_query()) != OK)
 | |
| 	return r;
 | |
| 
 | |
|   len = RPC_NEXT32;
 | |
|   if (len > max) len = max; /* sanity check */
 | |
| 
 | |
|   /* Only copy out data if we're not operating directly on the RPC buffer. */
 | |
|   if (buf != RPC_PTR)
 | |
| 	memcpy(buf, RPC_PTR, len);
 | |
| 
 | |
|   return len;
 | |
| }
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *				hgfs_write				     *
 | |
|  *===========================================================================*/
 | |
| ssize_t hgfs_write(handle, buf, len, off)
 | |
| sffs_file_t handle;		/* handle to open file */
 | |
| char *buf;			/* data buffer or NULL */
 | |
| size_t len;			/* number of bytes to write */
 | |
| u64_t off;			/* file offset */
 | |
| {
 | |
| /* Write to an open file. Upon success, return the number of bytes written.
 | |
|  */
 | |
|   int r;
 | |
| 
 | |
|   RPC_REQUEST(HGFS_REQ_WRITE);
 | |
|   RPC_NEXT32 = (u32_t)handle;
 | |
|   RPC_NEXT8 = 0;		/* append flag */
 | |
|   RPC_NEXT32 = ex64lo(off);
 | |
|   RPC_NEXT32 = ex64hi(off);
 | |
|   RPC_NEXT32 = len;
 | |
| 
 | |
|   /* Only copy in data if we're not operating directly on the RPC buffer. */
 | |
|   if (RPC_PTR != buf)
 | |
| 	memcpy(RPC_PTR, buf, len);
 | |
|   RPC_ADVANCE(len);
 | |
| 
 | |
|   if ((r = rpc_query()) != OK)
 | |
| 	return r;
 | |
| 
 | |
|   return RPC_NEXT32;
 | |
| }
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *				hgfs_close				     *
 | |
|  *===========================================================================*/
 | |
| int hgfs_close(handle)
 | |
| sffs_file_t handle;		/* handle to open file */
 | |
| {
 | |
| /* Close an open file.
 | |
|  */
 | |
| 
 | |
|   RPC_REQUEST(HGFS_REQ_CLOSE);
 | |
|   RPC_NEXT32 = (u32_t)handle;
 | |
| 
 | |
|   return rpc_query();
 | |
| }
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *				hgfs_readbuf				     *
 | |
|  *===========================================================================*/
 | |
| size_t hgfs_readbuf(ptr)
 | |
| char **ptr;
 | |
| {
 | |
| /* Return information about the read buffer, for zero-copy purposes. Store a
 | |
|  * pointer to the first byte of the read buffer, and return the maximum data
 | |
|  * size. The results are static, but must only be used directly prior to a
 | |
|  * hgfs_read() call (with a NULL data buffer address).
 | |
|  */
 | |
|   u32_t off;
 | |
| 
 | |
|   off = RPC_HDR_SIZE + sizeof(u32_t);
 | |
| 
 | |
|   RPC_RESET;
 | |
|   RPC_ADVANCE(off);
 | |
|   *ptr = RPC_PTR;
 | |
| 
 | |
|   return RPC_BUF_SIZE - off;
 | |
| }
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *				hgfs_writebuf				     *
 | |
|  *===========================================================================*/
 | |
| size_t hgfs_writebuf(ptr)
 | |
| char **ptr;
 | |
| {
 | |
| /* Return information about the write buffer, for zero-copy purposes. Store a
 | |
|  * pointer to the first byte of the write buffer, and return the maximum data
 | |
|  * size. The results are static, but must only be used immediately after a
 | |
|  * hgfs_write() call (with a NULL data buffer address).
 | |
|  */
 | |
|   u32_t off;
 | |
| 
 | |
|   off = RPC_HDR_SIZE + sizeof(u32_t) + sizeof(u8_t) + sizeof(u32_t) * 3;
 | |
| 
 | |
|   RPC_RESET;
 | |
|   RPC_ADVANCE(off);
 | |
|   *ptr = RPC_PTR;
 | |
| 
 | |
|   return RPC_BUF_SIZE - off;
 | |
| }
 |