xref: /minix/minix/lib/libhgfs/attr.c (revision 9f988b79)
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(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  *===========================================================================*/
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