1433d6423SLionel Sambuc /* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */
2433d6423SLionel Sambuc
3433d6423SLionel Sambuc #include "inc.h"
4433d6423SLionel Sambuc
5433d6423SLionel Sambuc #include <sys/stat.h>
6433d6423SLionel Sambuc
7433d6423SLionel Sambuc /*===========================================================================*
8433d6423SLionel Sambuc * attr_get *
9433d6423SLionel Sambuc *===========================================================================*/
attr_get(struct sffs_attr * attr)10433d6423SLionel Sambuc void attr_get(struct sffs_attr *attr)
11433d6423SLionel Sambuc {
12433d6423SLionel Sambuc /* Get attribute information from the RPC buffer, storing the requested parts
13433d6423SLionel Sambuc * in the given attr structure.
14433d6423SLionel Sambuc */
15433d6423SLionel Sambuc mode_t mode;
16433d6423SLionel Sambuc u32_t size_lo, size_hi;
17433d6423SLionel Sambuc
18433d6423SLionel Sambuc mode = (RPC_NEXT32) ? S_IFDIR : S_IFREG;
19433d6423SLionel Sambuc
20433d6423SLionel Sambuc size_lo = RPC_NEXT32;
21433d6423SLionel Sambuc size_hi = RPC_NEXT32;
22433d6423SLionel Sambuc if (attr->a_mask & SFFS_ATTR_SIZE)
23433d6423SLionel Sambuc attr->a_size = make64(size_lo, size_hi);
24433d6423SLionel Sambuc
25433d6423SLionel Sambuc time_get((attr->a_mask & SFFS_ATTR_CRTIME) ? &attr->a_crtime : NULL);
26433d6423SLionel Sambuc time_get((attr->a_mask & SFFS_ATTR_ATIME) ? &attr->a_atime : NULL);
27433d6423SLionel Sambuc time_get((attr->a_mask & SFFS_ATTR_MTIME) ? &attr->a_mtime : NULL);
28433d6423SLionel Sambuc time_get((attr->a_mask & SFFS_ATTR_CTIME) ? &attr->a_ctime : NULL);
29433d6423SLionel Sambuc
30433d6423SLionel Sambuc mode |= HGFS_PERM_TO_MODE(RPC_NEXT8);
31433d6423SLionel Sambuc if (attr->a_mask & SFFS_ATTR_MODE) attr->a_mode = mode;
32433d6423SLionel Sambuc }
33433d6423SLionel Sambuc
34433d6423SLionel Sambuc /*===========================================================================*
35433d6423SLionel Sambuc * hgfs_getattr *
36433d6423SLionel Sambuc *===========================================================================*/
hgfs_getattr(const char * path,struct sffs_attr * attr)37*94e65446SDavid van Moolenbroek int hgfs_getattr(const char *path, struct sffs_attr *attr)
38433d6423SLionel Sambuc {
39433d6423SLionel Sambuc /* Get selected attributes of a file by path name.
40433d6423SLionel Sambuc */
41433d6423SLionel Sambuc int r;
42433d6423SLionel Sambuc
43433d6423SLionel Sambuc RPC_REQUEST(HGFS_REQ_GETATTR);
44433d6423SLionel Sambuc
45433d6423SLionel Sambuc path_put(path);
46433d6423SLionel Sambuc
47433d6423SLionel Sambuc if ((r = rpc_query()) != OK)
48433d6423SLionel Sambuc return r;
49433d6423SLionel Sambuc
50433d6423SLionel Sambuc attr_get(attr);
51433d6423SLionel Sambuc
52433d6423SLionel Sambuc return OK;
53433d6423SLionel Sambuc }
54433d6423SLionel Sambuc
55433d6423SLionel Sambuc /*===========================================================================*
56433d6423SLionel Sambuc * hgfs_setattr *
57433d6423SLionel Sambuc *===========================================================================*/
hgfs_setattr(const char * path,struct sffs_attr * attr)58*94e65446SDavid van Moolenbroek int hgfs_setattr(const char *path, struct sffs_attr *attr)
59433d6423SLionel Sambuc {
60433d6423SLionel Sambuc /* Set selected attributes of a file by path name.
61433d6423SLionel Sambuc */
62433d6423SLionel Sambuc u8_t mask;
63433d6423SLionel Sambuc
64433d6423SLionel Sambuc RPC_REQUEST(HGFS_REQ_SETATTR);
65433d6423SLionel Sambuc
66433d6423SLionel Sambuc /* This library implements the HGFS v1 protocol, which is largely
67433d6423SLionel Sambuc * path-oriented. This is the only method to set the file size, and thus,
68433d6423SLionel Sambuc * truncating a deleted file is not possible. This has been fixed in later
69433d6423SLionel Sambuc * HGFS protocol version (v2/v3).
70433d6423SLionel Sambuc */
71433d6423SLionel Sambuc mask = 0;
72433d6423SLionel Sambuc if (attr->a_mask & SFFS_ATTR_MODE) mask |= HGFS_ATTR_MODE;
73433d6423SLionel Sambuc if (attr->a_mask & SFFS_ATTR_SIZE) mask |= HGFS_ATTR_SIZE;
74433d6423SLionel Sambuc if (attr->a_mask & SFFS_ATTR_CRTIME) mask |= HGFS_ATTR_CRTIME;
75433d6423SLionel Sambuc if (attr->a_mask & SFFS_ATTR_ATIME)
76433d6423SLionel Sambuc mask |= HGFS_ATTR_ATIME | HGFS_ATTR_ATIME_SET;
77433d6423SLionel Sambuc if (attr->a_mask & SFFS_ATTR_MTIME)
78433d6423SLionel Sambuc mask |= HGFS_ATTR_MTIME | HGFS_ATTR_MTIME_SET;
79433d6423SLionel Sambuc if (attr->a_mask & SFFS_ATTR_CTIME) mask |= HGFS_ATTR_CTIME;
80433d6423SLionel Sambuc
81433d6423SLionel Sambuc RPC_NEXT8 = mask;
82433d6423SLionel Sambuc
83433d6423SLionel Sambuc RPC_NEXT32 = !!(S_ISDIR(attr->a_mode));
84433d6423SLionel Sambuc RPC_NEXT32 = ex64lo(attr->a_size);
85433d6423SLionel Sambuc RPC_NEXT32 = ex64hi(attr->a_size);
86433d6423SLionel Sambuc
87433d6423SLionel Sambuc time_put((attr->a_mask & HGFS_ATTR_CRTIME) ? &attr->a_crtime : NULL);
88433d6423SLionel Sambuc time_put((attr->a_mask & HGFS_ATTR_ATIME) ? &attr->a_atime : NULL);
89433d6423SLionel Sambuc time_put((attr->a_mask & HGFS_ATTR_MTIME) ? &attr->a_mtime : NULL);
90433d6423SLionel Sambuc time_put((attr->a_mask & HGFS_ATTR_CTIME) ? &attr->a_ctime : NULL);
91433d6423SLionel Sambuc
92433d6423SLionel Sambuc RPC_NEXT8 = HGFS_MODE_TO_PERM(attr->a_mode);
93433d6423SLionel Sambuc
94433d6423SLionel Sambuc path_put(path);
95433d6423SLionel Sambuc
96433d6423SLionel Sambuc return rpc_query();
97433d6423SLionel Sambuc }
98