1 /* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */ 2 3 #include "inc.h" 4 5 #include <sys/stat.h> 6 7 /*===========================================================================* 8 * attr_get * 9 *===========================================================================*/ 10 void attr_get(struct sffs_attr *attr) 11 { 12 /* Get attribute information from the RPC buffer, storing the requested parts 13 * in the given attr structure. 14 */ 15 mode_t mode; 16 u32_t size_lo, size_hi; 17 18 mode = (RPC_NEXT32) ? S_IFDIR : S_IFREG; 19 20 size_lo = RPC_NEXT32; 21 size_hi = RPC_NEXT32; 22 if (attr->a_mask & SFFS_ATTR_SIZE) 23 attr->a_size = make64(size_lo, size_hi); 24 25 time_get((attr->a_mask & SFFS_ATTR_CRTIME) ? &attr->a_crtime : NULL); 26 time_get((attr->a_mask & SFFS_ATTR_ATIME) ? &attr->a_atime : NULL); 27 time_get((attr->a_mask & SFFS_ATTR_MTIME) ? &attr->a_mtime : NULL); 28 time_get((attr->a_mask & SFFS_ATTR_CTIME) ? &attr->a_ctime : NULL); 29 30 mode |= HGFS_PERM_TO_MODE(RPC_NEXT8); 31 if (attr->a_mask & SFFS_ATTR_MODE) attr->a_mode = mode; 32 } 33 34 /*===========================================================================* 35 * hgfs_getattr * 36 *===========================================================================*/ 37 int hgfs_getattr(char *path, struct sffs_attr *attr) 38 { 39 /* Get selected attributes of a file by path name. 40 */ 41 int r; 42 43 RPC_REQUEST(HGFS_REQ_GETATTR); 44 45 path_put(path); 46 47 if ((r = rpc_query()) != OK) 48 return r; 49 50 attr_get(attr); 51 52 return OK; 53 } 54 55 /*===========================================================================* 56 * hgfs_setattr * 57 *===========================================================================*/ 58 int hgfs_setattr(char *path, struct sffs_attr *attr) 59 { 60 /* Set selected attributes of a file by path name. 61 */ 62 u8_t mask; 63 64 RPC_REQUEST(HGFS_REQ_SETATTR); 65 66 /* This library implements the HGFS v1 protocol, which is largely 67 * path-oriented. This is the only method to set the file size, and thus, 68 * truncating a deleted file is not possible. This has been fixed in later 69 * HGFS protocol version (v2/v3). 70 */ 71 mask = 0; 72 if (attr->a_mask & SFFS_ATTR_MODE) mask |= HGFS_ATTR_MODE; 73 if (attr->a_mask & SFFS_ATTR_SIZE) mask |= HGFS_ATTR_SIZE; 74 if (attr->a_mask & SFFS_ATTR_CRTIME) mask |= HGFS_ATTR_CRTIME; 75 if (attr->a_mask & SFFS_ATTR_ATIME) 76 mask |= HGFS_ATTR_ATIME | HGFS_ATTR_ATIME_SET; 77 if (attr->a_mask & SFFS_ATTR_MTIME) 78 mask |= HGFS_ATTR_MTIME | HGFS_ATTR_MTIME_SET; 79 if (attr->a_mask & SFFS_ATTR_CTIME) mask |= HGFS_ATTR_CTIME; 80 81 RPC_NEXT8 = mask; 82 83 RPC_NEXT32 = !!(S_ISDIR(attr->a_mode)); 84 RPC_NEXT32 = ex64lo(attr->a_size); 85 RPC_NEXT32 = ex64hi(attr->a_size); 86 87 time_put((attr->a_mask & HGFS_ATTR_CRTIME) ? &attr->a_crtime : NULL); 88 time_put((attr->a_mask & HGFS_ATTR_ATIME) ? &attr->a_atime : NULL); 89 time_put((attr->a_mask & HGFS_ATTR_MTIME) ? &attr->a_mtime : NULL); 90 time_put((attr->a_mask & HGFS_ATTR_CTIME) ? &attr->a_ctime : NULL); 91 92 RPC_NEXT8 = HGFS_MODE_TO_PERM(attr->a_mode); 93 94 path_put(path); 95 96 return rpc_query(); 97 } 98