rpm  5.4.10
formats.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 
7 #include <rpmio.h>
8 #include <rpmiotypes.h> /* XXX fnpyKey */
9 #include <rpmmacro.h> /* XXX for %_i18ndomains */
10 
11 #define _RPMTAG_INTERNAL
12 #include <rpmtag.h>
13 #include <rpmtypes.h>
14 
15 #define _RPMEVR_INTERNAL
16 #include <rpmds.h>
17 #include <rpmfi.h>
18 
19 #include "legacy.h"
20 #include "manifest.h"
21 #include "argv.h"
22 #include "fs.h"
23 
24 #include "debug.h"
25 
26 #ifdef __cplusplus
27 GENfree(rpmuint32_t *)
28 #endif /* __cplusplus */
29 
30 /*@access headerSprintfExtension @*/
31 
38 static int fsnamesTag( /*@unused@*/ Header h, HE_t he)
39  /*@globals fileSystem, internalState @*/
40  /*@modifies he, fileSystem, internalState @*/
41 {
42  const char ** list;
43 
44  if (rpmGetFilesystemList(&list, &he->c))
45  return 1;
46 
48  he->p.argv = list;
49  he->freeData = 0;
50 
51  return 0;
52 }
53 
60 static int fssizesTag(Header h, HE_t he)
61  /*@globals rpmGlobalMacroContext, h_errno,
62  fileSystem, internalState @*/
63  /*@modifies he, rpmGlobalMacroContext,
64  fileSystem, internalState @*/
65 {
66  rpmTagData fnames = { .ptr = NULL };
67  rpmTagData fsizes = { .ptr = NULL };
68  rpmTagData p;
69  rpmuint64_t *usages;
70  int numFiles;
71  int rc = 1; /* assume error */
72  int xx, yy;
73 
74  p.ptr = he->p.ptr;
75  he->tag = RPMTAG_FILESIZES;
76  xx = headerGet(h, he, 0);
77  fsizes.ptr = he->p.ptr;
78  he->tag = RPMTAG_FILEPATHS;
79  yy = headerGet(h, he, 0);
80  fnames.ptr = he->p.ptr;
81  numFiles = he->c;
82  he->p.ptr = p.ptr;
83  if (!xx || !yy) {
84  numFiles = 0;
85  fsizes.ui32p = _free(fsizes.ui32p);
86  fnames.argv = _free(fnames.argv);
87  }
88 
89  if (rpmGetFilesystemList(NULL, &he->c))
90  goto exit;
91 
92  he->t = RPM_UINT64_TYPE;
93  he->freeData = 1;
94 
95  if (fnames.ptr == NULL)
96  usages = (rpmuint64_t *) xcalloc(he->c, sizeof(*usages));
97  else
98  if (rpmGetFilesystemUsage(fnames.argv, fsizes.ui32p, numFiles, &usages, 0))
99  goto exit;
100 
101  he->p.ui64p = usages;
102  rc = 0;
103 
104 exit:
105  fnames.ptr = _free(fnames.ptr);
106  fsizes.ptr = _free(fsizes.ptr);
107 
108  return rc;
109 }
110 
117 static int fileclassTag(Header h, HE_t he)
118  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
119  /*@modifies h, he,
120  rpmGlobalMacroContext, fileSystem, internalState @*/
121 {
122  he->t = RPM_STRING_ARRAY_TYPE;
123  rpmfiBuildFClasses(h, &he->p.argv, &he->c);
124  he->freeData = 1;
125  return 0;
126 }
127 
128 #ifdef DYING
129 
135 static int filecontextsTag(Header h, HE_t he)
136  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
137  /*@modifies h, he,
138  rpmGlobalMacroContext, fileSystem, internalState @*/
139 {
140  he->t = RPM_STRING_ARRAY_TYPE;
141  rpmfiBuildFContexts(h, &he->p.argv, &he->c);
142  he->freeData = 1;
143  return 0;
144 }
145 
152 static int fscontextsTag(Header h, HE_t he)
153  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
154  /*@modifies h, he,
155  rpmGlobalMacroContext, fileSystem, internalState @*/
156 {
157  he->t = RPM_STRING_ARRAY_TYPE;
158  rpmfiBuildFSContexts(h, &he->p.argv, &he->c);
159  he->freeData = 1;
160  return 0;
161 }
162 
169 static int recontextsTag(Header h, HE_t he)
170  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
171  /*@modifies h, he,
172  rpmGlobalMacroContext, fileSystem, internalState @*/
173 {
174  he->t = RPM_STRING_ARRAY_TYPE;
175  rpmfiBuildREContexts(h, &he->p.argv, &he->c);
176  he->freeData = 1;
177  return 0;
178 }
179 #endif
180 
187 static int fileprovideTag(Header h, HE_t he)
188  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
189  /*@modifies h, he,
190  rpmGlobalMacroContext, fileSystem, internalState @*/
191 {
192  he->t = RPM_STRING_ARRAY_TYPE;
193  rpmfiBuildFDeps(h, RPMTAG_PROVIDENAME, &he->p.argv, &he->c);
194  he->freeData = 1;
195  return 0;
196 }
197 
204 static int filerequireTag(Header h, HE_t he)
205  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
206  /*@modifies h, he,
207  rpmGlobalMacroContext, fileSystem, internalState @*/
208 {
209  he->t = RPM_STRING_ARRAY_TYPE;
210  rpmfiBuildFDeps(h, RPMTAG_REQUIRENAME, &he->p.argv, &he->c);
211  he->freeData = 1;
212  return 0;
213 }
214 
221 static int missingokTag(Header h, HE_t he)
222  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
223  /*@modifies h, he,
224  rpmGlobalMacroContext, fileSystem, internalState @*/
225 {
226  rpmds ds = rpmdsNew(h, RPMTAG_REQUIRENAME, 0);
227  ARGV_t av = NULL;
228  ARGV_t argv;
229  int argc = 0;
230  char * t;
231  size_t nb = 0;
232  int i;
233 
234  if (ds == NULL)
235  return 1;
236 
237  /* Collect dependencies marked as hints. */
238  ds = rpmdsInit(ds);
239  if (ds != NULL)
240  while (rpmdsNext(ds) >= 0) {
241  int Flags = rpmdsFlags(ds);
242  const char * DNEVR;
243  if (!(Flags & RPMSENSE_MISSINGOK))
244  continue;
245  DNEVR = rpmdsDNEVR(ds);
246  if (DNEVR == NULL)
247  continue;
248  nb += sizeof(*argv) + strlen(DNEVR+2) + 1;
249  (void) argvAdd(&av, DNEVR+2);
250  argc++;
251  }
252  nb += sizeof(*argv); /* final argv NULL */
253 
254  /* Create contiguous header string array. */
255  argv = (ARGV_t) xcalloc(nb, 1);
256  t = (char *)(argv + argc);
257  for (i = 0; i < argc; i++) {
258  argv[i] = t;
259  t = stpcpy(t, av[i]);
260  *t++ = '\0';
261  }
262  av = argvFree(av);
263  (void)rpmdsFree(ds);
264  ds = NULL;
265 
266  he->t = RPM_STRING_ARRAY_TYPE;
267  he->p.argv = argv;
268  he->c = argc;
269  he->freeData = 1;
270  return 0;
271 }
272 
273 /*@-type@*/ /* FIX: cast? */
274 static struct headerSprintfExtension_s _rpmHeaderFormats[] = {
275  { HEADER_EXT_TAG, "RPMTAG_ENHANCES",
276  { .tagFunction = missingokTag } },
277  { HEADER_EXT_TAG, "RPMTAG_FILECLASS",
278  { .tagFunction = fileclassTag } },
279 #ifdef DYING
280  { HEADER_EXT_TAG, "RPMTAG_FILECONTEXTS",
281  { .tagFunction = filecontextsTag } },
282 #endif
283  { HEADER_EXT_TAG, "RPMTAG_FILEPROVIDE",
284  { .tagFunction = fileprovideTag } },
285  { HEADER_EXT_TAG, "RPMTAG_FILEREQUIRE",
286  { .tagFunction = filerequireTag } },
287 #ifdef DYING
288  { HEADER_EXT_TAG, "RPMTAG_FSCONTEXTS",
289  { .tagFunction = fscontextsTag } },
290 #endif
291  { HEADER_EXT_TAG, "RPMTAG_FSNAMES",
292  { .tagFunction = fsnamesTag } },
293  { HEADER_EXT_TAG, "RPMTAG_FSSIZES",
294  { .tagFunction = fssizesTag } },
295 #ifdef DYING
296  { HEADER_EXT_TAG, "RPMTAG_RECONTEXTS",
297  { .tagFunction = recontextsTag } },
298 #endif
299  { HEADER_EXT_TAG, "RPMTAG_SUGGESTS",
300  { .tagFunction = missingokTag } },
301  { HEADER_EXT_MORE, NULL, { (void *) &headerCompoundFormats } }
302 } ;
303 /*@=type@*/
304 
305 headerSprintfExtension rpmHeaderFormats = &_rpmHeaderFormats[0];