1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
|
/* SPDX-License-Identifier: LGPL-3.0-or-later */
/*
* xattr.h - This file is part of libsquashfs
*
* Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef SQFS_XATTR_H
#define SQFS_XATTR_H
#include "sqfs/predef.h"
/**
* @file xattr.h
*
* @brief Contains on-disk data structures for storing extended attributes.
*/
/**
* @enum SQFS_XATTR_TYPE
*
* Used by @ref sqfs_xattr_entry_t to encodes the xattr prefix.
*/
typedef enum {
SQFS_XATTR_USER = 0,
SQFS_XATTR_TRUSTED = 1,
SQFS_XATTR_SECURITY = 2,
SQFS_XATTR_FLAG_OOL = 0x100,
SQFS_XATTR_PREFIX_MASK = 0xFF,
} SQFS_XATTR_TYPE;
/**
* @struct sqfs_xattr_entry_t
*
* @brief On-disk data structure that holds a single xattr key
*
* See @ref sqfs_xattr_reader_t for an overview how SquashFS stores extended
* attributes on disk.
*/
struct sqfs_xattr_entry_t {
/**
* @brief Encodes the prefix of the key
*
* A @ref SQFS_XATTR_TYPE value. If the @ref SQFS_XATTR_FLAG_OOL is
* set, the value that follows is not actually a string but a 64 bit
* reference to the location where the value is actually stored.
*/
sqfs_u16 type;
/**
* @brief The size in bytes of the suffix string that follows
*/
sqfs_u16 size;
sqfs_u8 key[];
};
/**
* @struct sqfs_xattr_value_t
*
* @brief On-disk data structure that holds a single xattr value
*
* See @ref sqfs_xattr_reader_t for an overview how SquashFS stores extended
* attributes on disk.
*/
struct sqfs_xattr_value_t {
/**
* @brief The exact size in bytes of the value that follows
*/
sqfs_u32 size;
sqfs_u8 value[];
};
/**
* @struct sqfs_xattr_id_t
*
* @brief On-disk data structure that describes a set of key-value pairs
*
* See @ref sqfs_xattr_reader_t for an overview how SquashFS stores extended
* attributes on disk.
*/
struct sqfs_xattr_id_t {
/**
* @brief Location of the first key-value pair
*
* This is a reference, i.e. the bits 16 to 48 hold an offset that is
* added to xattr_table_start from @ref sqfs_xattr_id_table_t to get
* the location of a meta data block that contains the first key-value
* pair. The lower 16 bits store an offset into the uncompressed meta
* data block.
*/
sqfs_u64 xattr;
/**
* @brief Number of consecutive key-value pairs
*/
sqfs_u32 count;
/**
* @brief Total size of the uncompressed key-value pairs in bytes,
* including data structures used to encode them.
*/
sqfs_u32 size;
};
/**
* @struct sqfs_xattr_id_table_t
*
* @brief On-disk data structure that the super block points to
*
* Indicates the locations of the xattr key-value pairs and descriptor array.
* See @ref sqfs_xattr_reader_t for an overview how SquashFS stores extended
* attributes on disk.
*/
struct sqfs_xattr_id_table_t {
/**
* @brief The location of the first meta data block holding the key
* value pairs.
*/
sqfs_u64 xattr_table_start;
/**
* @brief The total number of descriptors (@ref sqfs_xattr_id_t)
*/
sqfs_u32 xattr_ids;
/**
* @brief Unused, alwayas set this to 0 when writing!
*/
sqfs_u32 unused;
/**
* @brief Holds the locations of the meta data blocks that contain the
* @ref sqfs_xattr_id_t descriptor array.
*/
sqfs_u64 locations[];
};
/**
* @brief sqsf_xattr_t
*
* @brief Represents a decoded xattr key-value pair
*
* On disk, xattr key and value are stored separately with respective headers,
* partially ID-encoded key and special encoding for back references. This
* struct and associated helper functions combine the fully decoded key-value
* pair for convenience.
*/
struct sqfs_xattr_t {
/**
* @brief A pointer for arranging multiple entries in a lined list
*/
sqfs_xattr_t *next;
const char *key;
const sqfs_u8 *value;
/**
* @brief The size of the value blob in bytes
*/
size_t value_len;
/**
* @brief Flexible array member that holds the key & value data
*/
sqfs_u8 data[];
};
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Resolve an xattr identifier to the coresponding prefix
*
* Like many file systems, SquashFS stores xattrs be cutting off the common
* prefix of the key string and storing an enumerator instead to save memory.
*
* This function takes an @ref SQFS_XATTR_TYPE identifier and returns the
* coresponding prefix string, including the '.' at the end that separates
* the prefix from the rest of the key.
*/
SQFS_API const char *sqfs_get_xattr_prefix(SQFS_XATTR_TYPE id);
/**
* @brief Resolve an xattr prefix into an identifier
*
* Like many file systems, SquashFS stores xattrs be cutting off the common
* prefix of the key string and storing an enumerator instead to save memory.
*
* This function takes a key and finds the enumerator value that represents
* its prefix. An error value is returned if the given prefix isn't supported.
*
* @return On success an @ref SQFS_XATTR_TYPE. If not supported, the
* @ref SQFS_ERROR_UNSUPPORTED error code.
*/
SQFS_API int sqfs_get_xattr_prefix_id(const char *key);
/**
* @brief Create a combined xattr pair struct from a key string and a value blob
*
* @memberof sqfs_xattr_t
*
* The returned struct can be released with @ref sqfs_xattr_list_free
*
* @param key A pointer to the key string
* @param value A pointer to the value blob
* @param value_len The size of the value blob in bytes
*
* @return A pointer to an sqfs_xattr_t on success, NULL on allocation failure
*/
SQFS_API sqfs_xattr_t *sqfs_xattr_create(const char *key, const sqfs_u8 *value,
size_t value_len);
/**
* @brief Create an xattr pair struct from a key ID, key string, a value blob
*
* @memberof sqfs_xattr_t
*
* Basically does the same as @ref sqfs_xattr_create, but automatically adds
* a prefix to the key, based on an xattr ID type. The returned struct can be
* released with @ref sqfs_xattr_list_free
*
* @param out Returns a pointer ot an sqfs_xattr_t on success
* @param id An @ref SQFS_XATTR_TYPE enumerator
* @param key A pointer to the key string
* @param value A pointer to the value blob
* @param value_len The size of the value blob in bytes
*
* @return A pointer to , NULL on allocation failure
*/
SQFS_API int sqfs_xattr_create_prefixed(sqfs_xattr_t **out, sqfs_u16 id,
const char *key, const sqfs_u8 *value,
size_t value_len);
/**
* @brief Create a copy of a linked list of xattr pairs
*
* @memberof sqfs_xattr_t
*
* @param list A pointer to a list of xattr entries
*
* @return A duplicate list on success, NULL on allocation failure
*/
SQFS_API sqfs_xattr_t *sqfs_xattr_list_copy(const sqfs_xattr_t *list);
/**
* @brief Free a linked list of xattr pairs
*
* @memberof sqfs_xattr_t
*
* @param list A pointer to a list of xattr entries
*/
SQFS_API void sqfs_xattr_list_free(sqfs_xattr_t *list);
#ifdef __cplusplus
}
#endif
#endif /* SQFS_XATTR_H */
|