]> wimlib.net Git - wimlib/blob - include/wimlib/xattr.h
Implement basic handling of xattr streams
[wimlib] / include / wimlib / xattr.h
1 #ifndef _WIMLIB_XATTR_H
2 #define _WIMLIB_XATTR_H
3
4 #include "wimlib/endianness.h"
5 #include "wimlib/sha1.h"
6 #include "wimlib/tagged_items.h"
7 #include "wimlib/util.h"
8
9 #undef HAVE_XATTR_SUPPORT
10 #if defined(HAVE_SYS_XATTR_H) && defined(HAVE_LLISTXATTR) && \
11         defined(HAVE_LGETXATTR) && defined(HAVE_FSETXATTR)
12 #  define HAVE_XATTR_SUPPORT 1
13 #endif
14
15 /*
16  * On-disk format of an entry in an extended attribute stream (wimlib
17  * extension).  An xattr stream consists of a series of variable-length xattr
18  * entries, each of which begins with this entry header.
19  *
20  * Currently this is only used for Linux-style xattrs, but in the future we may
21  * use this for Windows-style xattrs too.
22  */
23 struct wimlib_xattr_entry {
24
25         /* length of xattr name in bytes */
26         le16 name_len;
27
28         /* reserved, must be 0 */
29         le16 reserved;
30
31         /* length of xattr value in bytes, not counting padding */
32         le32 value_len;
33
34         /* followed by the name with no terminating null */
35         char name[0];
36
37         /*
38          * directly followed by the value, zero-padded to the next 4-byte
39          * boundary if not already aligned
40          */
41         /* u8 value[0]; */
42 };
43
44 static inline size_t
45 xattr_entry_size(const struct wimlib_xattr_entry *entry)
46 {
47         return ALIGN(sizeof(*entry) + le16_to_cpu(entry->name_len) +
48                      le32_to_cpu(entry->value_len), 4);
49 }
50
51 static inline struct wimlib_xattr_entry *
52 xattr_entry_next(const struct wimlib_xattr_entry *entry)
53 {
54         return (void *)entry + xattr_entry_size(entry);
55 }
56
57 /* Currently we use the Linux limits when validating xattr names and values */
58 #define XATTR_NAME_MAX 255
59 #define XATTR_SIZE_MAX 65536
60
61 static inline bool
62 valid_xattr_entry(const struct wimlib_xattr_entry *entry, size_t avail)
63 {
64         if (avail < sizeof(*entry))
65                 return false;
66
67         if (entry->name_len == 0 ||
68             le16_to_cpu(entry->name_len) > XATTR_NAME_MAX)
69                 return false;
70
71         if (entry->reserved != 0)
72                 return false;
73
74         if (le32_to_cpu(entry->value_len) > XATTR_SIZE_MAX)
75                 return false;
76
77         return avail >= xattr_entry_size(entry);
78 }
79
80 static inline const u8 *
81 inode_get_linux_xattr_hash(const struct wim_inode *inode)
82 {
83         return inode_get_tagged_item(inode, TAG_WIMLIB_LINUX_XATTR_HASH,
84                                      SHA1_HASH_SIZE, NULL);
85 }
86
87 static inline bool
88 inode_has_linux_xattr_hash(const struct wim_inode *inode)
89 {
90         return inode_get_linux_xattr_hash(inode) != NULL;
91 }
92
93 static inline bool
94 inode_set_linux_xattr_hash(struct wim_inode *inode, const u8 *hash)
95 {
96         return inode_set_tagged_data(inode, TAG_WIMLIB_LINUX_XATTR_HASH,
97                                      hash, SHA1_HASH_SIZE);
98 }
99
100 #endif /* _WIMLIB_XATTR_H  */