Use actual rpmTags in place of the old HEADER_FOO defines everywhere
[platform/upstream/rpm.git] / lib / headerutil.c
1 /** \ingroup rpmdb
2  * \file lib/hdrNVR.c
3  */
4
5 #include "system.h"
6
7 #include <rpm/rpmtypes.h>
8 #include <rpm/header.h>
9 #include <rpm/rpmstring.h>
10
11 #include "debug.h"
12
13 static int NEVRA(Header h, const char **np,
14                  uint32_t **ep, const char **vp, const char **rp,
15                  const char **ap)
16 {
17     if (np) *np = headerGetString(h, RPMTAG_NAME);
18     if (vp) *vp = headerGetString(h, RPMTAG_VERSION);
19     if (rp) *rp = headerGetString(h, RPMTAG_RELEASE);
20     if (ap) *ap = headerGetString(h, RPMTAG_ARCH);
21     if (ep) {
22         struct rpmtd_s td;
23         headerGet(h, RPMTAG_EPOCH, &td, HEADERGET_DEFAULT);
24         *ep = rpmtdGetUint32(&td);
25     }
26     return 0;
27 }
28
29 int headerNVR(Header h, const char **np, const char **vp, const char **rp)
30 {
31     return NEVRA(h, np, NULL, vp, rp, NULL);
32 }
33
34 int headerNEVRA(Header h, const char **np,
35                 uint32_t **ep, const char **vp, const char **rp,
36                 const char **ap)
37 {
38     return NEVRA(h, np, ep, vp, rp, ap);
39 }
40
41 static char *getNEVRA(Header h, rpmTag tag, const char **np)
42 {
43     if (np) *np = headerGetString(h, RPMTAG_NAME);
44     return headerGetAsString(h, tag);
45 }
46
47 char * headerGetNEVR(Header h, const char ** np)
48 {
49     return getNEVRA(h, RPMTAG_NEVR, np);
50 }
51
52 char * headerGetNEVRA(Header h, const char ** np)
53 {
54     return getNEVRA(h, RPMTAG_NEVRA, np);
55 }
56
57 char * headerGetEVR(Header h, const char ** np)
58 {
59     return getNEVRA(h, RPMTAG_EVR, np);
60 }
61
62 rpm_color_t headerGetColor(Header h)
63 {
64     return headerGetNumber(h, RPMTAG_HEADERCOLOR);
65 }
66
67 int headerIsSource(Header h)
68 {
69     return (!headerIsEntry(h, RPMTAG_SOURCERPM));
70 }
71
72 Header headerCopy(Header h)
73 {
74     Header nh = headerNew();
75     HeaderIterator hi;
76     struct rpmtd_s td;
77    
78     hi = headerInitIterator(h);
79     while (headerNext(hi, &td)) {
80         if (rpmtdCount(&td) > 0) {
81             (void) headerPut(nh, &td, HEADERPUT_DEFAULT);
82         }
83         rpmtdFreeData(&td);
84     }
85     hi = headerFreeIterator(hi);
86
87     return headerReload(nh, RPMTAG_HEADERIMAGE);
88 }
89
90 void headerCopyTags(Header headerFrom, Header headerTo, 
91                     const rpmTag * tagstocopy)
92 {
93     const rpmTag * p;
94     struct rpmtd_s td;
95
96     if (headerFrom == headerTo)
97         return;
98
99     for (p = tagstocopy; *p != 0; p++) {
100         if (headerIsEntry(headerTo, *p))
101             continue;
102         if (!headerGet(headerFrom, *p, &td, (HEADERGET_MINMEM|HEADERGET_RAW)))
103             continue;
104         (void) headerPut(headerTo, &td, HEADERPUT_DEFAULT);
105         rpmtdFreeData(&td);
106     }
107 }
108
109 char * headerGetAsString(Header h, rpmTag tag)
110 {
111     char *res = NULL;
112     struct rpmtd_s td;
113
114     if (headerGet(h, tag, &td, HEADERGET_EXT)) {
115         if (rpmtdCount(&td) == 1) {
116             res = rpmtdFormat(&td, RPMTD_FORMAT_STRING, NULL);
117         }
118         rpmtdFreeData(&td);
119     }
120     return res;
121 }
122
123 const char * headerGetString(Header h, rpmTag tag)
124 {
125     const char *res = NULL;
126     struct rpmtd_s td;
127
128     if (headerGet(h, tag, &td, HEADERGET_MINMEM)) {
129         if (rpmtdCount(&td) == 1) {
130             res = rpmtdGetString(&td);
131         }
132         rpmtdFreeData(&td);
133     }
134     return res;
135 }
136
137 uint64_t headerGetNumber(Header h, rpmTag tag)
138 {
139     uint64_t res = 0;
140     struct rpmtd_s td;
141
142     if (headerGet(h, tag, &td, HEADERGET_EXT)) {
143         if (rpmtdCount(&td) == 1) {
144             res = rpmtdGetNumber(&td);
145         }
146         rpmtdFreeData(&td);
147     }
148     return res;
149 }
150
151 /*
152  * Sanity check data types against tag table before putting. Assume
153  * append on all array-types.
154  */
155 static int headerPutType(Header h, rpmTag tag, rpmTagType reqtype,
156                         rpm_constdata_t data, rpm_count_t size)
157 {
158     struct rpmtd_s td;
159     rpmTagType type = rpmTagGetType(tag);
160     headerPutFlags flags = HEADERPUT_APPEND; 
161     int valid = 1;
162
163     /* Basic sanity checks: type must match and there must be data to put */
164     if ((type & RPM_MASK_TYPE) != reqtype 
165         || size < 1 || data == NULL || h == NULL) {
166         valid = 0;
167     }
168
169     /*
170      * Non-array types can't be appended to. Binary types use size
171      * for data length, for other non-array types size must be 1.
172      */
173     if ((type & RPM_MASK_RETURN_TYPE) != RPM_ARRAY_RETURN_TYPE) {
174         flags = HEADERPUT_DEFAULT;
175         if ((type & RPM_MASK_TYPE) != RPM_BIN_TYPE && size != 1) {
176             valid = 0;
177         }
178     }
179
180     if (valid) {
181         rpmtdReset(&td);
182         td.tag = tag;
183         td.type = type & RPM_MASK_TYPE;
184         td.data = (void *) data;
185         td.count = size;
186
187         valid = headerPut(h, &td, flags);
188     }
189
190     return valid;
191 }
192         
193 int headerPutString(Header h, rpmTag tag, const char *val)
194 {
195     rpmTagType type = rpmTagGetType(tag) & RPM_MASK_TYPE;
196     const void *sptr = NULL;
197
198     /* string arrays expect char **, arrange that */
199     if (type == RPM_STRING_ARRAY_TYPE || type == RPM_I18NSTRING_TYPE) {
200         sptr = &val;
201     } else if (type == RPM_STRING_TYPE) {
202         sptr = val;
203     } else {
204         return 0;
205     }
206
207     return headerPutType(h, tag, type, sptr, 1);
208 }
209
210 int headerPutStringArray(Header h, rpmTag tag, const char **array, rpm_count_t size)
211 {
212     return headerPutType(h, tag, RPM_STRING_ARRAY_TYPE, array, size);
213 }
214
215 int headerPutChar(Header h, rpmTag tag, const char *val, rpm_count_t size)
216 {
217     return headerPutType(h, tag, RPM_CHAR_TYPE, val, size);
218 }
219
220 int headerPutUint8(Header h, rpmTag tag, const uint8_t *val, rpm_count_t size)
221 {
222     return headerPutType(h, tag, RPM_INT8_TYPE, val, size);
223 }
224
225 int headerPutUint16(Header h, rpmTag tag, const uint16_t *val, rpm_count_t size)
226 {
227     return headerPutType(h, tag, RPM_INT16_TYPE, val, size);
228 }
229
230 int headerPutUint32(Header h, rpmTag tag, const uint32_t *val, rpm_count_t size)
231 {
232     return headerPutType(h, tag, RPM_INT32_TYPE, val, size);
233 }
234
235 int headerPutUint64(Header h, rpmTag tag, const uint64_t *val, rpm_count_t size)
236 {
237     return headerPutType(h, tag, RPM_INT64_TYPE, val, size);
238 }
239
240 int headerPutBin(Header h, rpmTag tag, const uint8_t *val, rpm_count_t size)
241 {
242     return headerPutType(h, tag, RPM_BIN_TYPE, val, size);
243 }
244