summaryrefslogtreecommitdiff
path: root/lib/rpmtd.h
blob: 99c94baffcf2412cf6989e688394325ddfba3c62 (plain)
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
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
#ifndef _RPMTD_H
#define _RPMTD_H

#include <rpm/rpmtypes.h>
#include <rpm/argv.h>

#ifdef __cplusplus
extern "C" {
#endif

enum rpmtdFlags_e {
    RPMTD_NONE		= 0,
    RPMTD_ALLOCED	= (1 << 0),	/* was memory allocated? */
    RPMTD_PTR_ALLOCED	= (1 << 1),	/* were array pointers allocated? */
    RPMTD_IMMUTABLE	= (1 << 2),	/* header data or modifiable? */
    RPMTD_ARGV		= (1 << 3),	/* string array is NULL-terminated? */
};

typedef rpmFlags rpmtdFlags;

/** \ingroup rpmtd
 * Container for rpm tag data (from headers or extensions).
 * @todo		Make this opaque (at least outside rpm itself)
 */
struct rpmtd_s {
    rpm_tag_t tag;	/* rpm tag of this data entry*/
    rpm_tagtype_t type;	/* data type */
    rpm_count_t count;	/* number of entries */
    rpm_data_t data;	/* pointer to actual data */
    rpmtdFlags flags;	/* flags on memory allocation etc */
    int ix;		/* iteration index */
};

/** \ingroup rpmtd
 * Create new tag data container
 * @return		New, initialized tag data container.
 */
rpmtd rpmtdNew(void);

/** \ingroup rpmtd
 * Destroy tag data container.
 * @param td		Tag data container
 * @return		NULL always
 */
rpmtd rpmtdFree(rpmtd td);
 
/** \ingroup rpmtd
 * (Re-)initialize tag data container. Contents will be zeroed out
 * and iteration index reset.
 * @param td		Tag data container
 */
void rpmtdReset(rpmtd td);

/** \ingroup rpmtd
 * Free contained data. This is always safe to call as the container knows 
 * if data was malloc'ed or not. Container is reinitialized.
 * @param td		Tag data container
 */
void rpmtdFreeData(rpmtd td);

/** \ingroup rpmtd
 * Retrieve array size of the container. For non-array types this is always 1.
 * @param td		Tag data container
 * @return		Number of entries in contained data.
 */
rpm_count_t rpmtdCount(rpmtd td);

/** \ingroup rpmtd
 * Retrieve tag of the container.
 * @param td		Tag data container
 * @return		Rpm tag.
 */
rpmTagVal rpmtdTag(rpmtd td);

/** \ingroup rpmtd
 * Retrieve type of the container.
 * @param td		Tag data container
 * @return		Rpm tag type.
 */
rpmTagType rpmtdType(rpmtd td);

/** \ingroup rpmtd
 * Retrieve class of the container.
 * @param td		Tag data container
 * @return		Rpm tag class
 */
rpmTagClass rpmtdClass(rpmtd td);

/** \ingroup rpmtd
 * Retrieve current iteration index of the container.
 * @param td		Tag data container
 * @return		Iteration index (or -1 if not iterating)
 */
int rpmtdGetIndex(rpmtd td);

/** \ingroup rpmtd
 * Set iteration index of the container.
 * If new index is out of bounds for the container, -1 is returned and
 * iteration index is left untouched. 
 * @param td		Tag data container
 * @param index		New index
 * @return		New index, or -1 if index out of bounds
 */
int rpmtdSetIndex(rpmtd td, int index);

/** \ingroup rpmtd
 * Initialize tag container for iteration
 * @param td		Tag data container
 * @return		0 on success
 */
int rpmtdInit(rpmtd td);

/** \ingroup rpmtd
 * Iterate over tag data container.
 * @param td		Tag data container
 * @return		Tag data container iterator index, -1 on termination
 */
int rpmtdNext(rpmtd td);

/** \ingroup rpmtd
 * Iterate over uint32_t type tag data container.
 * @param td		Tag data container
 * @return		Pointer to next value, NULL on termination or error
 */
uint32_t *rpmtdNextUint32(rpmtd td);

/** \ingroup rpmtd
 * Iterate over uint64_t type tag data container.
 * @param td		Tag data container
 * @return		Pointer to next value, NULL on termination or error
 */
uint64_t *rpmtdNextUint64(rpmtd td);

/** \ingroup rpmtd
 * Iterate over string / string array type tag data container.
 * @param td		Tag data container
 * @return		Pointer to next value, NULL on termination or error
 */
const char *rpmtdNextString(rpmtd td);

/** \ingroup rpmtd
 * Return char data from tag container.
 * For scalar return type, just return pointer to the integer. On array
 * types, return pointer to current iteration index. If the tag container
 * is not for char type, NULL is returned.
 * @param td		Tag data container
 * @return		Pointer to uint16_t, NULL on error
 */
char *rpmtdGetChar(rpmtd td);

/** \ingroup rpmtd
 * Return uint16_t data from tag container.
 * For scalar return type, just return pointer to the integer. On array
 * types, return pointer to current iteration index. If the tag container
 * is not for int16 type, NULL is returned.
 * @param td		Tag data container
 * @return		Pointer to uint16_t, NULL on error
 */
uint16_t * rpmtdGetUint16(rpmtd td);

/** \ingroup rpmtd
 * Return uint32_t data from tag container.
 * For scalar return type, just return pointer to the integer. On array
 * types, return pointer to current iteration index. If the tag container
 * is not for int32 type, NULL is returned.
 * @param td		Tag data container
 * @return		Pointer to uint32_t, NULL on error
 */
uint32_t * rpmtdGetUint32(rpmtd td);

/** \ingroup rpmtd
 * Return uint64_t data from tag container.
 * For scalar return type, just return pointer to the integer. On array
 * types, return pointer to current iteration index. If the tag container
 * is not for int64 type, NULL is returned.
 * @param td		Tag data container
 * @return		Pointer to uint64_t, NULL on error
 */
uint64_t * rpmtdGetUint64(rpmtd td);

/** \ingroup rpmtd
 * Return string data from tag container.
 * For string types, just return the string. On string array types,
 * return the string from current iteration index. If the tag container
 * is not for a string type, NULL is returned.
 * @param td		Tag data container
 * @return		String constant from container, NULL on error
 */
const char * rpmtdGetString(rpmtd td);

/** \ingroup rpmtd
 * Return numeric value from tag container.
 * Returns the value of numeric container (RPM_NUMERIC_CLASS) from
 * current iteration index as uint64_t regardless of its internal 
 * presentation (8/16/32/64-bit integer).
 * @param td		Tag data container
 * @return		Value of current iteration item as uint64_t,
 * 			0 for non-numeric types (error)
 */
uint64_t rpmtdGetNumber(rpmtd td);

typedef enum rpmtdFormats_e {
    RPMTD_FORMAT_STRING		= 0,	/* plain string (any type) */
    RPMTD_FORMAT_ARMOR		= 1,	/* ascii armor format (bin types) */
    RPMTD_FORMAT_BASE64		= 2,	/* base64 encoding (bin types) */
    RPMTD_FORMAT_PGPSIG		= 3,	/* pgp/gpg signature (bin types) */
    RPMTD_FORMAT_DEPFLAGS	= 4,	/* dependency flags (int types) */
    RPMTD_FORMAT_FFLAGS		= 5,	/* file flags (int types) */
    RPMTD_FORMAT_PERMS		= 6,	/* permission string (int types) */
    RPMTD_FORMAT_TRIGGERTYPE	= 7,	/* trigger types (int types) */
    RPMTD_FORMAT_XML		= 8,	/* xml format (any type) */
    RPMTD_FORMAT_OCTAL		= 9,	/* octal format (int types) */
    RPMTD_FORMAT_HEX		= 10,	/* hex format (int types) */
    RPMTD_FORMAT_DATE		= 11,	/* date format (int types) */
    RPMTD_FORMAT_DAY		= 12,	/* day format (int types) */
    RPMTD_FORMAT_SHESCAPE	= 13,	/* shell escaped (any type) */
    RPMTD_FORMAT_ARRAYSIZE	= 14,	/* size of contained array (any type) */
    RPMTD_FORMAT_DEPTYPE	= 15,	/* dependency types (int types) */
    RPMTD_FORMAT_FSTATE		= 16,	/* file states (int types) */
    RPMTD_FORMAT_VFLAGS		= 17,	/* file verify flags (int types) */
    RPMTD_FORMAT_EXPAND		= 18,	/* macro expansion (string types) */
    RPMTD_FORMAT_FSTATUS	= 19,	/* file verify status (int types) */
} rpmtdFormats;

/** \ingroup rpmtd
 * Format data from tag container to string presentation of given format.
 * Return malloced string presentation of current data in container,
 * converting from integers etc as necessary. On array types, data from
 * current iteration index is used for formatting.
 * @param td		Tag data container
 * @param fmt		Format to apply
 * @param errmsg	Error message from conversion (or NULL)
 * @return		String representation of current data (malloc'ed), 
 * 			NULL on error
 */
char *rpmtdFormat(rpmtd td, rpmtdFormats fmt, const char *errmsg);

/** \ingroup rpmtd
 * Set container tag and type.
 * For empty container, any valid tag can be set. If the container has
 * data, changing is only permitted to tag of same type. 
 * @param td		Tag data container
 * @param tag		New tag
 * @return		1 on success, 0 on error
 */
int rpmtdSetTag(rpmtd td, rpmTagVal tag);

/** \ingroup rpmtd
 * Construct tag container from uint8_t pointer.
 * Tag type is checked to be of compatible type (CHAR, INT8 or BIN). 
 * For non-array types (BIN is a special case of INT8 array) 
 * count must be exactly 1.
 * @param td		Tag data container
 * @param tag		Rpm tag to construct
 * @param data		Pointer to uint8_t (value or array)
 * @param count		Number of entries
 * @return		1 on success, 0 on error (eg wrong type)
 */
int rpmtdFromUint8(rpmtd td, rpmTagVal tag, uint8_t *data, rpm_count_t count);

/** \ingroup rpmtd
 * Construct tag container from uint16_t pointer.
 * Tag type is checked to be of INT16 type. For non-array types count
 * must be exactly 1.
 * @param td		Tag data container
 * @param tag		Rpm tag to construct
 * @param data		Pointer to uint16_t (value or array)
 * @param count		Number of entries
 * @return		1 on success, 0 on error (eg wrong type)
 */
int rpmtdFromUint16(rpmtd td, rpmTagVal tag, uint16_t *data, rpm_count_t count);

/** \ingroup rpmtd
 * Construct tag container from uint32_t pointer.
 * Tag type is checked to be of INT32 type. For non-array types count
 * must be exactly 1.
 * @param td		Tag data container
 * @param tag		Rpm tag to construct
 * @param data		Pointer to uint32_t (value or array)
 * @param count		Number of entries
 * @return		1 on success, 0 on error (eg wrong type)
 */
int rpmtdFromUint32(rpmtd td, rpmTagVal tag, uint32_t *data, rpm_count_t count);

/** \ingroup rpmtd
 * Construct tag container from uint64_t pointer.
 * Tag type is checked to be of INT64 type. For non-array types count
 * must be exactly 1.
 * @param td		Tag data container
 * @param tag		Rpm tag to construct
 * @param data		Pointer to uint64_t (value or array)
 * @param count		Number of entries
 * @return		1 on success, 0 on error (eg wrong type)
 */
int rpmtdFromUint64(rpmtd td, rpmTagVal tag, uint64_t *data, rpm_count_t count);

/** \ingroup rpmtd
 * Construct tag container from a string.
 * Tag type is checked to be of string type. 
 * @param td		Tag data container
 * @param tag		Rpm tag to construct
 * @param data		String to use
 * @return		1 on success, 0 on error (eg wrong type)
 */
int rpmtdFromString(rpmtd td, rpmTagVal tag, const char *data);

/** \ingroup rpmtd
 * Construct tag container from a string array.
 * Tag type is checked to be of string or string array type. For non-array
 * types count must be exactly 1.
 * @param td		Tag data container
 * @param tag		Rpm tag to construct
 * @param data		Pointer to string array
 * @param count		Number of entries
 * @return		1 on success, 0 on error (eg wrong type)
 */
int rpmtdFromStringArray(rpmtd td, rpmTagVal tag, const char **data, rpm_count_t count);

/** \ingroup rpmtd
 * Construct tag container from ARGV_t array.
 * Tag type is checked to be of string array type and array is checked
 * to be non-empty.
 * @param td		Tag data container
 * @param tag		Rpm tag to construct
 * @param argv		ARGV array
 * @return		1 on success, 0 on error (eg wrong type)
 */
int rpmtdFromArgv(rpmtd td, rpmTagVal tag, ARGV_t argv);

/** \ingroup rpmtd
 * Construct tag container from ARGI_t array.
 * Tag type is checked to be of integer array type and array is checked
 * to be non-empty.
 * @param td		Tag data container
 * @param tag		Rpm tag to construct
 * @param argi		ARGI array
 * @return		1 on success, 0 on error (eg wrong type)
 */
int rpmtdFromArgi(rpmtd td, rpmTagVal tag, ARGI_t argi);

/* \ingroup rpmtd
 * Perform deep copy of container.
 * Create a modifiable copy of tag data container (on string arrays each
 * string is separately allocated)
 * @todo		Only string arrays types are supported currently
 * @param td		Container to copy
 * @return		New container or NULL on error
 */
rpmtd rpmtdDup(rpmtd td);

#ifdef __cplusplus
}
#endif

#endif /* _RPMTD_H */