optflags: set _FORTIFY_SOURCE for preproc
[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     headerFreeIterator(hi);
86
87     return headerReload(nh, RPMTAG_HEADERIMAGE);
88 }
89
90 void headerCopyTags(Header headerFrom, Header headerTo, 
91                     const rpmTagVal * tagstocopy)
92 {
93     const rpmTagVal * 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, rpmTagVal 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, rpmTagVal 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, rpmTagVal 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, rpmTagVal tag, rpmTagType reqtype,
156                         rpm_constdata_t data, rpm_count_t size)
157 {
158     struct rpmtd_s td;
159     rpmTagType type = rpmTagGetTagType(tag);
160     rpmTagReturnType retype = rpmTagGetReturnType(tag);
161     headerPutFlags flags = HEADERPUT_APPEND; 
162     int valid = 1;
163
164     /* Basic sanity checks: type must match and there must be data to put */
165     if (type != reqtype 
166         || size < 1 || data == NULL || h == NULL) {
167         valid = 0;
168     }
169
170     /*
171      * Non-array types can't be appended to. Binary types use size
172      * for data length, for other non-array types size must be 1.
173      */
174     if (retype != RPM_ARRAY_RETURN_TYPE) {
175         flags = HEADERPUT_DEFAULT;
176         if (type != RPM_BIN_TYPE && size != 1) {
177             valid = 0;
178         }
179     }
180
181     if (valid) {
182         rpmtdReset(&td);
183         td.tag = tag;
184         td.type = type;
185         td.data = (void *) data;
186         td.count = size;
187
188         valid = headerPut(h, &td, flags);
189     }
190
191     return valid;
192 }
193         
194 int headerPutString(Header h, rpmTagVal tag, const char *val)
195 {
196     rpmTagType type = rpmTagGetTagType(tag);
197     const void *sptr = NULL;
198
199     /* string arrays expect char **, arrange that */
200     if (type == RPM_STRING_ARRAY_TYPE || type == RPM_I18NSTRING_TYPE) {
201         sptr = &val;
202     } else if (type == RPM_STRING_TYPE) {
203         sptr = val;
204     } else {
205         return 0;
206     }
207
208     return headerPutType(h, tag, type, sptr, 1);
209 }
210
211 int headerPutStringArray(Header h, rpmTagVal tag, const char **array, rpm_count_t size)
212 {
213     return headerPutType(h, tag, RPM_STRING_ARRAY_TYPE, array, size);
214 }
215
216 int headerPutChar(Header h, rpmTagVal tag, const char *val, rpm_count_t size)
217 {
218     return headerPutType(h, tag, RPM_CHAR_TYPE, val, size);
219 }
220
221 int headerPutUint8(Header h, rpmTagVal tag, const uint8_t *val, rpm_count_t size)
222 {
223     return headerPutType(h, tag, RPM_INT8_TYPE, val, size);
224 }
225
226 int headerPutUint16(Header h, rpmTagVal tag, const uint16_t *val, rpm_count_t size)
227 {
228     return headerPutType(h, tag, RPM_INT16_TYPE, val, size);
229 }
230
231 int headerPutUint32(Header h, rpmTagVal tag, const uint32_t *val, rpm_count_t size)
232 {
233     return headerPutType(h, tag, RPM_INT32_TYPE, val, size);
234 }
235
236 int headerPutUint64(Header h, rpmTagVal tag, const uint64_t *val, rpm_count_t size)
237 {
238     return headerPutType(h, tag, RPM_INT64_TYPE, val, size);
239 }
240
241 int headerPutBin(Header h, rpmTagVal tag, const uint8_t *val, rpm_count_t size)
242 {
243     return headerPutType(h, tag, RPM_BIN_TYPE, val, size);
244 }
245