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 *===========================================================================*/
attr_get(struct sffs_attr * attr)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 *===========================================================================*/
hgfs_getattr(const char * path,struct sffs_attr * attr)37 int hgfs_getattr(const 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 *===========================================================================*/
hgfs_setattr(const char * path,struct sffs_attr * attr)58 int hgfs_setattr(const 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