rpm  5.4.15
rpmds.c
Go to the documentation of this file.
1 
4 #include "system.h"
5 
6 #if defined(WITH_CPUINFO)
7 #include <cpuinfo.h>
8 #endif
9 
10 #if defined(HAVE_GELF_H) && !defined(__FreeBSD__)
11 #if LIBELF_H_LFS_CONFLICT
12 /* Some implementations of libelf.h/gelf.h are incompatible with
13  * the Large File API.
14  */
15 # undef _LARGEFILE64_SOURCE
16 # undef _LARGEFILE_SOURCE
17 # undef _FILE_OFFSET_BITS
18 # define _FILE_OFFSET_BITS 32
19 #endif
20 
21 #if defined(__LCLINT__)
22 typedef long long loff_t;
23 #endif
24 #include <gelf.h>
25 /*
26  * On Solaris, gelf.h included libelf.h, which #undef'ed the gettext
27  * convenience macro _(). Repair by repeating (from system.h) just
28  * the bits that are needed for _() to function.
29  */
30 
31 #if defined(__sun)
32 #if defined(ENABLE_NLS) && !defined(__LCLINT__)
33 # define _(Text) gettext (Text)
34 #else
35 # define _(Text) Text
36 #endif /* gettext _() fixup */
37 #endif
38 #endif /* HAVE_GELF_H */
39 
40 #if defined(HAVE_LIBELF) && !defined(HAVE_GELF_GETVERNAUX) && !defined(__FreeBSD__)
41 /* We have gelf.h and libelf, but we don't have some of the
42  * helper functions gelf_getvernaux(), gelf_getverneed(), etc.
43  * Provide our own simple versions here.
44  */
45 
46 static GElf_Verdef *gelf_getverdef(Elf_Data *data, int offset,
47  GElf_Verdef *dst)
48 {
49  return (GElf_Verdef *) ((char *) data->d_buf + offset);
50 }
51 
52 static GElf_Verdaux *gelf_getverdaux(Elf_Data *data, int offset,
53  GElf_Verdaux *dst)
54 {
55  return (GElf_Verdaux *) ((char *) data->d_buf + offset);
56 }
57 
58 static GElf_Verneed *gelf_getverneed(Elf_Data *data, int offset,
59  GElf_Verneed *dst)
60 {
61  return (GElf_Verneed *) ((char *) data->d_buf + offset);
62 }
63 
64 static GElf_Vernaux *gelf_getvernaux(Elf_Data *data, int offset,
65  GElf_Vernaux *dst)
66 {
67  return (GElf_Vernaux *) ((char *) data->d_buf + offset);
68 }
69 
70 /* Most non-Linux systems won't have SHT_GNU_verdef or SHT_GNU_verneed,
71  * but they might have something mostly-equivalent. Solaris has
72  * SHT_SUNW_{verdef,verneed}
73  */
74 #if !defined(SHT_GNU_verdef) && defined(__sun) && defined(SHT_SUNW_verdef)
75 # define SHT_GNU_verdef SHT_SUNW_verdef
76 # define SHT_GNU_verneed SHT_SUNW_verneed
77 #endif
78 
79 #endif /* HAVE_LIBELF && !HAVE_GELF_GETVERNAUX */
80 
81 #if !defined(DT_GNU_HASH)
82 #define DT_GNU_HASH 0x6ffffef5
83 #endif
84 
85 #define _RPMIOB_INTERNAL
86 #include <rpmiotypes.h>
87 #include <rpmio_internal.h> /* XXX fdGetFILE */
88 #include <rpmcb.h> /* XXX fnpyKey */
89 #include <rpmmacro.h>
90 #include <argv.h>
91 #include <set.h>
92 
93 #include <rpmtypes.h>
94 #include <rpmtag.h>
95 
96 #define _RPMDS_INTERNAL
97 #define _RPMEVR_INTERNAL
98 #define _RPMPRCO_INTERNAL
99 #include <rpmds.h>
100 
101 #include "debug.h"
102 
103 /*@access rpmns @*/
104 /*@access EVR_t @*/
105 
106 #ifdef __cplusplus
107 GENfree(evrFlags *)
108 GENfree(rpmuint32_t *)
109 GENfree(rpmint32_t *)
110 GENfree(rpmPRCO)
111 #endif /* __cplusplus */
112 
113 #define _isspace(_c) \
114  ((_c) == ' ' || (_c) == '\t' || (_c) == '\r' || (_c) == '\n')
115 
119 /*@unchecked@*/
121 
122 /*@unchecked@*/
123 int _rpmds_debug = 0;
124 
125 /*@unchecked@*/
127 
128 /*@unchecked@*/
129 /*@-exportheadervar@*/
131 /*@=exportheadervar@*/
132 
138 /*@observer@*/
139 static const char * rpmdsTagName(rpmTag tagN)
140  /*@*/
141 {
142  const char * Type;
143 
144  /* XXX Preserve existing names in debugging messages. */
145  switch (tagN) {
146  default: Type = tagName(tagN); break;
147  case RPMTAG_PROVIDENAME: Type = "Provides"; break;
148  case RPMTAG_REQUIRENAME: Type = "Requires"; break;
149  case RPMTAG_CONFLICTNAME: Type = "Conflicts"; break;
150  case RPMTAG_OBSOLETENAME: Type = "Obsoletes"; break;
151  case RPMTAG_TRIGGERNAME: Type = "Triggers"; break;
152  case RPMTAG_SUGGESTSNAME: Type = "Suggests"; break;
153  case RPMTAG_ENHANCESNAME: Type = "Enhances"; break;
154  case RPMTAG_DIRNAMES: Type = "Dirs"; break;
155  case RPMTAG_BASENAMES: Type = "Files"; break;
156  case RPMTAG_FILELINKTOS: Type = "Linktos"; break;
157  case 0: Type = "Unknown"; break;
158  }
159  return Type;
160 }
161 
162 const char * rpmdsType(const rpmds ds)
163 {
164  return rpmdsTagName(rpmdsTagN(ds));
165 }
166 
167 static void rpmdsFini(void * _ds)
168 {
169  rpmds ds = (rpmds) _ds;
170 
171  if (ds->Count > 0) {
172  ds->N = _free(ds->N);
173  ds->EVR = _free(ds->EVR);
174  ds->Flags = _free(ds->Flags);
175  (void)headerFree(ds->h);
176  ds->h = NULL;
177  }
178 
179  ds->DNEVR = _free(ds->DNEVR);
180  ds->ns.str = _free(ds->ns.str);
181  memset(&ds->ns, 0, sizeof(ds->ns));
182  ds->A = _free(ds->A);
183  ds->Color = _free(ds->Color);
184  ds->Refs = _free(ds->Refs);
185  ds->Result = _free(ds->Result);
186  ds->exclude = (miRE) mireFreeAll(ds->exclude, ds->nexclude);
187  ds->include = (miRE) mireFreeAll(ds->include, ds->ninclude);
188 }
189 
190 /*@unchecked@*/ /*@only@*/ /*@null@*/
192 
193 static rpmds rpmdsGetPool(/*@null@*/ rpmioPool pool)
194  /*@globals _rpmdsPool, fileSystem, internalState @*/
195  /*@modifies pool, _rpmdsPool, fileSystem, internalState @*/
196 {
197  rpmds ds;
198 
199  if (_rpmdsPool == NULL) {
200  _rpmdsPool = rpmioNewPool("ds", sizeof(*ds), -1, _rpmds_debug,
201  NULL, NULL, rpmdsFini);
202  pool = _rpmdsPool;
203  }
204  ds = (rpmds) rpmioGetPool(pool, sizeof(*ds));
205  memset(((char *)ds)+sizeof(ds->_item), 0, sizeof(*ds)-sizeof(ds->_item));
206  return ds;
207 }
208 
209 static /*@null@*/
210 const char ** rpmdsDupArgv(/*@null@*/ const char ** argv, int argc)
211  /*@*/
212 {
213  const char ** av;
214  size_t nb = 0;
215  int ac = 0;
216  char * t;
217 
218  if (argv == NULL)
219  return NULL;
220  for (ac = 0; ac < argc; ac++) {
221 assert(argv[ac] != NULL);
222  nb += strlen(argv[ac]) + 1;
223  }
224  nb += (ac + 1) * sizeof(*av);
225 
226  av = (const char **) xmalloc(nb);
227  t = (char *) (av + ac + 1);
228  for (ac = 0; ac < argc; ac++) {
229  av[ac] = t;
230  t = stpcpy(t, argv[ac]) + 1;
231  }
232  av[ac] = NULL;
233 /*@-nullret@*/
234  return av;
235 /*@=nullret@*/
236 }
237 
239 {
240  int scareMem = (flags & 0x1);
241  int delslash = 1;
242  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
243  rpmTag tagEVR, tagF;
244  rpmds ds = NULL;
245  const char * Type = NULL;
246  const char ** N;
247  rpmuint32_t Count;
248  int xx;
249 
250 assert(scareMem == 0); /* XXX always allocate memory */
251 
252  if (tagN == RPMTAG_NAME)
253  return rpmdsThis(h, tagN, RPMSENSE_EQUAL);
254 
255  switch (tagN) {
256  default:
257  goto exit;
258  /*@notreached@*/ break;
259  case RPMTAG_PROVIDENAME:
260  tagEVR = RPMTAG_PROVIDEVERSION;
261  tagF = RPMTAG_PROVIDEFLAGS;
262  break;
263  case RPMTAG_REQUIRENAME:
264  tagEVR = RPMTAG_REQUIREVERSION;
265  tagF = RPMTAG_REQUIREFLAGS;
266  break;
267  case RPMTAG_CONFLICTNAME:
268  tagEVR = RPMTAG_CONFLICTVERSION;
269  tagF = RPMTAG_CONFLICTFLAGS;
270  break;
271  case RPMTAG_OBSOLETENAME:
272  tagEVR = RPMTAG_OBSOLETEVERSION;
273  tagF = RPMTAG_OBSOLETEFLAGS;
274  break;
275  case RPMTAG_TRIGGERNAME:
276  tagEVR = RPMTAG_TRIGGERVERSION;
277  tagF = RPMTAG_TRIGGERFLAGS;
278  break;
279  case RPMTAG_SUGGESTSNAME:
280  tagEVR = RPMTAG_SUGGESTSVERSION;
281  tagF = RPMTAG_SUGGESTSFLAGS;
282  break;
283  case RPMTAG_ENHANCESNAME:
284  tagEVR = RPMTAG_ENHANCESVERSION;
285  tagF = RPMTAG_ENHANCESFLAGS;
286  break;
287  case RPMTAG_DIRNAMES:
288  tagEVR = (rpmTag) 0;
289  tagF = (rpmTag) 0;
290  delslash = (flags & 0x2) ? 0 : 1;
291  break;
292  case RPMTAG_BASENAMES:
293  tagEVR = RPMTAG_DIRNAMES;
294  tagF = RPMTAG_DIRINDEXES;
295  break;
296  case RPMTAG_FILELINKTOS:
297  tagEVR = RPMTAG_DIRNAMES;
298  tagF = RPMTAG_DIRINDEXES;
299  break;
300  }
301 
302  if (Type == NULL)
303  Type = rpmdsTagName(tagN);
304 
305  he->tag = tagN;
306  xx = headerGet(h, he, 0);
307  N = he->p.argv;
308  Count = he->c;
309  if (xx && N != NULL && Count > 0) {
310  ds = rpmdsGetPool(_rpmdsPool);
311  ds->Type = Type;
312  ds->h = NULL;
313  ds->i = -1;
314  ds->DNEVR = NULL;
315  ds->tagN = tagN;
316  ds->N = N;
317  ds->Count = Count;
318  ds->nopromote = _rpmds_nopromote;
319 
320  if (tagEVR > 0) {
321  he->tag = tagEVR;
322  xx = headerGet(h, he, 0);
323  ds->EVR = he->p.argv;
324  }
325  if (tagF > 0) {
326  he->tag = tagF;
327  xx = headerGet(h, he, 0);
328  ds->Flags = (evrFlags * ) he->p.ui32p;
329  }
330  {
331  he->tag = RPMTAG_ARCH;
332  xx = headerGet(h, he, 0);
333  ds->A = he->p.str;
334  }
335  {
336  he->tag = RPMTAG_BUILDTIME;
337  xx = headerGet(h, he, 0);
338  ds->BT = (he->p.ui32p ? he->p.ui32p[0] : 0);
339  he->p.ptr = _free(he->p.ptr);
340  }
341 
342  if (tagN == RPMTAG_DIRNAMES) {
343  char * dn;
344  size_t len;
345  unsigned i;
346  /* XXX Dirnames always have trailing '/', trim that here. */
347  if (delslash)
348  for (i = 0; i < Count; i++) {
349  (void) urlPath(N[i], (const char **)&dn);
350  if (dn > N[i])
351  N[i] = dn;
352  dn = (char *)N[i];
353  len = strlen(dn);
354  /* XXX don't truncate if parent is / */
355  if (len > 1 && dn[len-1] == '/')
356  dn[len-1] = '\0';
357  }
358  } else
359  if (tagN == RPMTAG_BASENAMES) {
360  const char ** av = (const char **) xcalloc(Count+1, sizeof(*av));
361  char * dn;
362  unsigned i;
363 
364  for (i = 0; i < Count; i++) {
365  (void) urlPath(ds->EVR[ds->Flags[i]], (const char **)&dn);
366  av[i] = rpmGenPath(NULL, dn, N[i]);
367  }
368  av[Count] = NULL;
369 
370 /*@-unqualifiedtrans@*/
371  N = ds->N = _free(ds->N);
372 /*@=unqualifiedtrans@*/
373  N = ds->N = rpmdsDupArgv(av, Count);
374  av = argvFree(av);
375  ds->EVR = _free(ds->EVR);
376  ds->Flags = _free(ds->Flags);
377  } else
378  if (tagN == RPMTAG_FILELINKTOS) {
379  /* XXX Construct the absolute path of the target symlink(s). */
380  const char ** av = (const char **) xcalloc(Count+1, sizeof(*av));
381  unsigned i;
382 
383  for (i = 0; i < Count; i++) {
384  if (N[i] == NULL || *N[i] == '\0')
385  av[i] = xstrdup("");
386  else if (*N[i] == '/')
387  av[i] = xstrdup(N[i]);
388  else if (ds->EVR != NULL && ds->Flags != NULL)
389  av[i] = rpmGenPath(NULL, ds->EVR[ds->Flags[i]], N[i]);
390  else
391  av[i] = xstrdup("");
392  }
393  av[Count] = NULL;
394 
395 /*@-unqualifiedtrans@*/
396  N = ds->N = _free(ds->N);
397 /*@=unqualifiedtrans@*/
398  N = ds->N = rpmdsDupArgv(av, Count);
399  av = argvFree(av);
400  ds->EVR = _free(ds->EVR);
401  ds->Flags = _free(ds->Flags);
402  }
403 
404 /*@-modfilesys@*/
405 if (_rpmds_debug < 0)
406 fprintf(stderr, "*** ds %p\t%s[%d]\n", ds, ds->Type, ds->Count);
407 /*@=modfilesys@*/
408 
409  }
410 
411 exit:
412 /*@-compdef -usereleased@*/ /* FIX: ds->Flags may be NULL */
413  /*@-nullstate@*/ /* FIX: ds->Flags may be NULL */
414  ds = rpmdsLink(ds, (ds ? ds->Type : NULL));
415  /*@=nullstate@*/
416 
417  return ds;
418 /*@=compdef =usereleased@*/
419 }
420 
421 const char * rpmdsNewN(rpmds ds)
422 {
423  rpmns ns = &ds->ns;
424  const char * Name = ds->N[ds->i];
425  int xx;
426 
427  xx = rpmnsParse(Name, ns);
428 
429 /*@-compdef -usereleased@*/ /* FIX: correct annotations for ds->ns shadow */
430  return ns->N;
431 /*@=compdef =usereleased@*/
432 }
433 
434 char * rpmdsNewDNEVR(const char * dspfx, rpmds ds)
435 {
436  const char * N = rpmdsNewN(ds);
437  const char * NS = ds->ns.NS;
438  const char * A = ds->ns.A;
439  evrFlags dsFlags = (evrFlags) 0;
440  char * tbuf, * t;
441  size_t nb = 0;
442 
443  if (dspfx) nb += strlen(dspfx) + 1;
444  if (ds->ns.str[0] == '!') nb++;
445  if (NS) nb += strlen(NS) + sizeof("()") - 1;
446  if (N) nb += strlen(N);
447  if (A) {
448  if (_rpmns_N_at_A && _rpmns_N_at_A[0])
449  nb += sizeof(_rpmns_N_at_A[0]);
450  nb += strlen(A);
451  }
452  /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
453  if (ds->Flags != NULL
454  && (dsFlags = (evrFlags) (ds->Flags[ds->i] & RPMSENSE_SENSEMASK)))
455  {
456  if (nb) nb++;
457  if (dsFlags == RPMSENSE_NOTEQUAL)
458  nb += 2;
459  else {
460  if (dsFlags & RPMSENSE_LESS) nb++;
461  if (dsFlags & RPMSENSE_GREATER) nb++;
462  if (dsFlags & RPMSENSE_EQUAL) nb++;
463  }
464  }
465 
466  ds->ns.Flags = dsFlags;
467 
468  /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
469  if (ds->EVR != NULL && ds->EVR[ds->i] && *ds->EVR[ds->i]) {
470  if (nb) nb++;
471  nb += strlen(ds->EVR[ds->i]);
472  }
473 
474  t = tbuf = (char *) xmalloc(nb + 1);
475  if (dspfx) {
476  t = stpcpy(t, dspfx);
477  *t++ = ' ';
478  }
479  if (ds->ns.str[0] == '!')
480  *t++ = '!';
481  if (NS)
482  t = stpcpy( stpcpy(t, NS), "(");
483  if (N)
484  t = stpcpy(t, N);
485  if (NS)
486  t = stpcpy(t, ")");
487  if (A) {
488  if (_rpmns_N_at_A && _rpmns_N_at_A[0])
489  *t++ = _rpmns_N_at_A[0];
490  t = stpcpy(t, A);
491  }
492 
493  /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
494  if (ds->Flags != NULL && (ds->Flags[ds->i] & RPMSENSE_SENSEMASK)) {
495  if (t != tbuf) *t++ = ' ';
496  if (dsFlags == RPMSENSE_NOTEQUAL)
497  t = stpcpy(t, "!=");
498  else {
499  if (dsFlags & RPMSENSE_LESS) *t++ = '<';
500  if (dsFlags & RPMSENSE_GREATER) *t++ = '>';
501  if (dsFlags & RPMSENSE_EQUAL) *t++ = '=';
502  }
503  }
504  /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
505  if (ds->EVR != NULL && ds->EVR[ds->i] && *ds->EVR[ds->i]) {
506  if (t != tbuf) *t++ = ' ';
507  t = stpcpy(t, ds->EVR[ds->i]);
508  }
509  *t = '\0';
510  return tbuf;
511 }
512 
514 {
515  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
516  rpmds ds = NULL;
517  const char * Type;
518  const char * Name, * V, * R;
519 #ifdef RPM_VENDOR_MANDRIVA
520  const char * D = NULL;
521 #endif
522  rpmuint32_t E;
523  const char ** N, ** EVR;
524  char * t;
525  size_t nb;
526  int xx;
527 
528  if (tagN == RPMTAG_NAME)
529  tagN = RPMTAG_PROVIDENAME;
530 
531  Type = rpmdsTagName(tagN);
532 
533  he->tag = RPMTAG_EPOCH;
534  xx = headerGet(h, he, 0);
535  E = (he->p.ui32p ? he->p.ui32p[0] : 0);
536  he->p.ptr = _free(he->p.ptr);
537 
538 #if defined(RPM_VENDOR_MANDRIVA)
539  he->tag = RPMTAG_DISTEPOCH;
540  xx = headerGet(h, he, 0);
541  D = (he->p.str ? he->p.str : NULL);
542 #endif
543 /*@-mods@*/
544  xx = headerNEVRA(h, &Name, NULL, &V, &R, NULL);
545 /*@=mods@*/
546  /* XXX segfault avoidance */
547  if (Name == NULL) Name = xstrdup("N");
548  if (V == NULL) V = xstrdup("V");
549  if (R == NULL) R = xstrdup("R");
550 
551  t = (char *) xmalloc(sizeof(*N) + strlen(Name) + 1);
552  N = (const char **) t;
553  t += sizeof(*N);
554  *t = '\0';
555  N[0] = t;
556  t = stpcpy(t, Name);
557  Name = _free(Name);
558 
559  nb = sizeof(*EVR) + 20 + strlen(V) + strlen(R) + sizeof("-");
560 #if defined(RPM_VENDOR_MANDRIVA)
561  nb += (D ? strlen(D) + sizeof(":") : 0);
562 #endif
563  t = (char *) xmalloc(nb);
564  EVR = (const char **) t;
565  t += sizeof(*EVR);
566  *t = '\0';
567  EVR[0] = t;
568  sprintf(t, "%d:", E);
569  t += strlen(t);
570  t = stpcpy( stpcpy( stpcpy( t, V), "-"), R);
571 #if defined(RPM_VENDOR_MANDRIVA)
572  if (D != NULL) {
573  t = stpcpy( stpcpy( t, ":"), D);
574  D = _free(D);
575  }
576 #endif
577  V = _free(V);
578  R = _free(R);
579 
580  ds = rpmdsGetPool(_rpmdsPool);
581  ds->Type = Type;
582  ds->tagN = tagN;
583  ds->Count = 1;
584  ds->N = N;
585  ds->EVR = EVR;
586  ds->Flags = (evrFlags *) xmalloc(sizeof(*ds->Flags)); ds->Flags[0] = Flags;
587 
588  he->tag = RPMTAG_ARCH;
589  xx = headerGet(h, he, 0);
590  ds->A = he->p.str;
591 
592  he->tag = RPMTAG_BUILDTIME;
593  xx = headerGet(h, he, 0);
594  ds->BT = (he->p.ui32p ? he->p.ui32p[0] : 0);
595  he->p.ptr = _free(he->p.ptr);
596 
597  { char pre[2];
598  pre[0] = ds->Type[0];
599  pre[1] = '\0';
600  /*@-nullstate@*/ /* LCL: ds->Type may be NULL ??? */
601  ds->i = 0; /* XXX rpmdsNewN() needs ds->i = 0, not -1 */
602 /*@i@*/ ds->DNEVR = rpmdsNewDNEVR(pre, ds);
603  /*@=nullstate@*/
604  }
605 
606  return rpmdsLink(ds, (ds ? ds->Type : NULL));
607 }
608 
609 rpmds rpmdsSingle(rpmTag tagN, const char * N, const char * EVR, evrFlags Flags)
610 {
611  rpmds ds = rpmdsGetPool(_rpmdsPool);
612  const char * Type = rpmdsTagName(tagN);
613 
614  ds->Type = Type;
615  ds->tagN = tagN;
616  ds->A = NULL;
617  { time_t now = time(NULL);
618  ds->BT = (rpmuint32_t)now;
619  }
620  ds->Count = 1;
621  /*@-assignexpose@*/
622  ds->N = (const char **) xcalloc(2, sizeof(*ds->N)); ds->N[0] = N;
623  ds->EVR = (const char **) xcalloc(2, sizeof(*ds->EVR)); ds->EVR[0] = EVR;
624  /*@=assignexpose@*/
625  ds->Flags = (evrFlags *) xmalloc(sizeof(*ds->Flags)); ds->Flags[0] = Flags;
626  { char t[2];
627  t[0] = ds->Type[0];
628  t[1] = '\0';
629  ds->i = 0; /* XXX rpmdsNewN() needs ds->i = 0, not -1 */
630 /*@i@*/ ds->DNEVR = rpmdsNewDNEVR(t, ds);
631  }
632 
633  return rpmdsLink(ds, (ds ? ds->Type : NULL));
634 }
635 
636 int rpmdsCount(const rpmds ds)
637 {
638  return (ds != NULL ? ds->Count : 0);
639 }
640 
641 int rpmdsIx(const rpmds ds)
642 {
643  return (ds != NULL ? ds->i : -1);
644 }
645 
646 int rpmdsSetIx(rpmds ds, int ix)
647 {
648  int i = -1;
649 
650  if (ds != NULL) {
651  i = ds->i;
652  ds->i = ix;
653  }
654  return i;
655 }
656 
657 const char * rpmdsDNEVR(const rpmds ds)
658 {
659  const char * DNEVR = NULL;
660 
661  if (ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count) {
662  if (ds->DNEVR != NULL)
663  DNEVR = ds->DNEVR;
664  }
665  return DNEVR;
666 }
667 
668 const char * rpmdsN(const rpmds ds)
669 {
670  const char * N = NULL;
671 
672  if (ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count) {
673 /*@-globs -mods @*/ /* FIX: correct annotations for ds->ns shadow */
674  N = (ds->ns.N ? ds->ns.N : rpmdsNewN(ds));
675 /*@=globs =mods @*/
676  }
677  return N;
678 }
679 
680 const char * rpmdsEVR(const rpmds ds)
681 {
682  const char * EVR = NULL;
683 
684  if (ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count) {
685  if (ds->EVR != NULL)
686  EVR = ds->EVR[ds->i];
687  }
688  return EVR;
689 }
690 
692 {
693  evrFlags Flags = (evrFlags) 0;
694 
695  if (ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count) {
696  if (ds->Flags != NULL)
697  Flags = ds->Flags[ds->i];
698  }
699  return Flags;
700 }
701 
703 {
704  rpmTag tagN = (rpmTag) 0;
705 
706  if (ds != NULL)
707  tagN = ds->tagN;
708  return tagN;
709 }
710 
711 const char * rpmdsA(const rpmds ds)
712 {
713  const char * A = NULL;
714 
715  if (ds != NULL)
716  A = ds->A;
717  return A;
718 }
719 
720 time_t rpmdsBT(const rpmds ds)
721 {
722  time_t BT = 0;
723  if (ds != NULL && ds->BT > 0)
724  BT = ds->BT;
725  return BT;
726 }
727 
728 time_t rpmdsSetBT(const rpmds ds, time_t BT)
729 {
730  time_t oBT = 0;
731  if (ds != NULL) {
732  oBT = (time_t)ds->BT;
733  ds->BT = (rpmuint32_t)BT;
734  }
735  return oBT;
736 }
737 
739 {
740  nsType NSType = RPMNS_TYPE_UNKNOWN;
741  if (ds != NULL)
742  NSType = ds->ns.Type;
743  return NSType;
744 }
745 
746 int rpmdsNoPromote(const rpmds ds)
747 {
748  int nopromote = 0;
749 
750  if (ds != NULL)
751  nopromote = ds->nopromote;
752  return nopromote;
753 }
754 
755 int rpmdsSetNoPromote(rpmds ds, int nopromote)
756 {
757  int onopromote = 0;
758 
759  if (ds != NULL) {
760  onopromote = ds->nopromote;
761  ds->nopromote = nopromote;
762  }
763  return onopromote;
764 }
765 
767  int (*EVRparse)(const char *evrstr, EVR_t evr))
768 {
769  void * oEVRparse = NULL;
770 
771  if (ds != NULL) {
772 /*@i@*/ oEVRparse = (void *) ds->EVRparse;
773 /*@i@*/ ds->EVRparse = EVRparse;
774  }
775  return oEVRparse;
776 }
777 
778 void * rpmdsSetEVRcmp(rpmds ds, int (*EVRcmp)(const char *a, const char *b))
779 {
780  void * oEVRcmp = NULL;
781 
782  if (ds != NULL) {
783 /*@i@*/ oEVRcmp = (void *) ds->EVRcmp;
784 /*@i@*/ ds->EVRcmp = EVRcmp;
785  }
786  return oEVRcmp;
787 }
788 
790 {
791  rpmuint32_t Color = 0;
792 
793  if (ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count) {
794  if (ds->Color != NULL)
795  Color = ds->Color[ds->i];
796  }
797  return Color;
798 }
799 
801 {
802  rpmuint32_t ocolor = 0;
803 
804  if (ds == NULL)
805  return ocolor;
806 
807  if (ds->Color == NULL && ds->Count > 0) /* XXX lazy malloc */
808  ds->Color = (rpmuint32_t *) xcalloc(ds->Count, sizeof(*ds->Color));
809 
810  if (ds->i >= 0 && ds->i < (int)ds->Count) {
811  if (ds->Color != NULL) {
812  ocolor = ds->Color[ds->i];
813  ds->Color[ds->i] = color;
814  }
815  }
816  return ocolor;
817 }
818 
819 void * rpmdsExclude(const rpmds ds)
820 {
821  return (ds != NULL ? ds->exclude : NULL);
822 }
823 
824 int rpmdsNExclude(const rpmds ds)
825 {
826  return (ds != NULL ? ds->nexclude : 0);
827 }
828 
829 void * rpmdsInclude(const rpmds ds)
830 {
831  return (ds != NULL ? ds->include : NULL);
832 }
833 
834 int rpmdsNInclude(const rpmds ds)
835 {
836  return (ds != NULL ? ds->ninclude : 0);
837 }
838 
840 {
841  rpmuint32_t Refs = 0;
842 
843  if (ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count) {
844  if (ds->Refs != NULL)
845  Refs = ds->Refs[ds->i];
846  }
847  return Refs;
848 }
849 
851 {
852  rpmuint32_t orefs = 0;
853 
854  if (ds == NULL)
855  return orefs;
856 
857  if (ds->Refs == NULL && ds->Count > 0) /* XXX lazy malloc */
858  ds->Refs = (rpmuint32_t *) xcalloc(ds->Count, sizeof(*ds->Refs));
859 
860  if (ds->i >= 0 && ds->i < (int)ds->Count) {
861  if (ds->Refs != NULL) {
862  orefs = ds->Refs[ds->i];
863  ds->Refs[ds->i] = refs;
864  }
865  }
866  return orefs;
867 }
868 
870 {
871  rpmint32_t result = 0;
872 
873  if (ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count) {
874  if (ds->Result != NULL)
875  result = ds->Result[ds->i];
876  }
877  return result;
878 }
879 
881 {
882  rpmint32_t oresult = 0;
883 
884  if (ds == NULL)
885  return oresult;
886 
887  if (ds->Result == NULL && ds->Count > 0) /* XXX lazy malloc */
888  ds->Result = (rpmint32_t *) xcalloc(ds->Count, sizeof(*ds->Result));
889 
890  if (ds->i >= 0 && ds->i < (int)ds->Count) {
891  if (ds->Result != NULL) {
892  oresult = ds->Result[ds->i];
893  ds->Result[ds->i] = result;
894  }
895  }
896  return oresult;
897 }
898 
899 void rpmdsNotify(rpmds ds, const char * where, int rc)
900 {
901  if (!(ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count))
902  return;
903  if (ds->DNEVR == NULL)
904  return;
905 
906  rpmlog(RPMLOG_DEBUG, "%9s: %-45s %-s %s\n", rpmdsTagName(ds->tagN),
907  (!strcmp(ds->DNEVR, "cached") ? ds->DNEVR : ds->DNEVR+2),
908  (rc ? _("NO ") : _("YES")),
909  (where != NULL ? where : ""));
910 }
911 
912 int rpmdsNext(/*@null@*/ rpmds ds)
913  /*@modifies ds @*/
914 {
915  int i = -1;
916 
917  if (ds != NULL && ++ds->i >= 0) {
918  if (ds->i < (int)ds->Count) {
919  char t[2];
920  i = ds->i;
921  ds->DNEVR = _free(ds->DNEVR);
922  ds->ns.str = _free(ds->ns.str);
923  memset(&ds->ns, 0, sizeof(ds->ns));
924  t[0] = ((ds->Type != NULL) ? ds->Type[0] : '\0');
925  t[1] = '\0';
926  /*@-nullstate@*/
927  /*@i@*/ ds->DNEVR = rpmdsNewDNEVR(t, ds);
928  /*@=nullstate@*/
929 
930  } else
931  ds->i = -1;
932 
933 /*@-modfilesys @*/
934 if (_rpmds_debug < 0 && i != -1 && ds->DNEVR[2] != '\0')
935 fprintf(stderr, "*** ds %p\t%s[%d]: %s\n", ds, (ds->Type ? ds->Type : "?Type?"), i, (ds->DNEVR ? ds->DNEVR : "?DNEVR?"));
936 /*@=modfilesys @*/
937 
938  }
939 
940  return i;
941 }
942 
943 rpmds rpmdsInit(/*@null@*/ rpmds ds)
944  /*@modifies ds @*/
945 {
946  if (ds != NULL)
947  ds->i = -1;
948  /*@-refcounttrans@*/
949  return ds;
950  /*@=refcounttrans@*/
951 }
952 
953 /*@null@*/
954 static rpmds rpmdsDup(const rpmds ods)
955  /*@modifies ods @*/
956 {
957  rpmds ds = rpmdsGetPool(_rpmdsPool);
958  size_t nb;
959 
960 /*@-assignexpose -castexpose @*/
961  ds->h = (ods->h != NULL ? headerLink(ods->h) : NULL);
962  ds->Type = ods->Type;
963 /*@=assignexpose =castexpose @*/
964  ds->tagN = ods->tagN;
965  ds->Count = ods->Count;
966  ds->i = ods->i;
967  ds->l = ods->l;
968  ds->u = ods->u;
969 
970  nb = (ds->Count+1) * sizeof(*ds->N);
971  ds->N = (const char **) (ds->h != NULL
972  ? memcpy(xmalloc(nb), ods->N, nb)
973  : rpmdsDupArgv(ods->N, ods->Count) );
974 
975  /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
976 assert(ods->EVR != NULL);
977 assert(ods->Flags != NULL);
978 
979  nb = (ds->Count+1) * sizeof(*ds->EVR);
980  ds->EVR = (const char **) (ds->h != NULL
981  ? memcpy(xmalloc(nb), ods->EVR, nb)
982  : rpmdsDupArgv(ods->EVR, ods->Count) );
983 
984  nb = (ds->Count * sizeof(*ds->Flags));
985  ds->Flags = (evrFlags *) (ds->h != NULL
986  ? ods->Flags
987  : memcpy(xmalloc(nb), ods->Flags, nb) );
988  ds->nopromote = ods->nopromote;
989 /*@-assignexpose@*/
990  ds->EVRcmp = ods->EVRcmp;;
991 /*@=assignexpose@*/
992 
993 /*@-compmempass@*/ /* FIX: ds->Flags is kept, not only */
994  return rpmdsLink(ds, (ds ? ds->Type : NULL));
995 /*@=compmempass@*/
996 }
997 
998 int rpmdsFind(rpmds ds, const rpmds ods)
999 {
1000  int comparison;
1001 
1002  if (ds == NULL || ods == NULL)
1003  return -1;
1004 
1005  ds->l = 0;
1006  ds->u = ds->Count;
1007  while (ds->l < ds->u) {
1008  ds->i = (ds->l + ds->u) / 2;
1009 
1010  comparison = strcmp(ods->N[ods->i], ds->N[ds->i]);
1011 
1012  /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
1013 /*@-nullderef@*/
1014  if (comparison == 0 && ods->EVR && ds->EVR)
1015  comparison = strcmp(ods->EVR[ods->i], ds->EVR[ds->i]);
1016  if (comparison == 0 && ods->Flags && ds->Flags)
1017  comparison = (ods->Flags[ods->i] - ds->Flags[ds->i]);
1018 /*@=nullderef@*/
1019 
1020  if (comparison < 0)
1021  ds->u = ds->i;
1022  else if (comparison > 0)
1023  ds->l = ds->i + 1;
1024  else
1025  return ds->i;
1026  }
1027  return -1;
1028 }
1029 
1030 int rpmdsMerge(rpmds * dsp, rpmds ods)
1031 {
1032  rpmds ds;
1033  const char ** N;
1034  const char ** EVR;
1035  evrFlags * Flags;
1036  int j;
1037 int save;
1038 
1039  if (dsp == NULL || ods == NULL)
1040  return -1;
1041 
1042  /* If not initialized yet, dup the 1st entry. */
1043  if (*dsp == NULL) {
1044  save = ods->Count;
1045  ods->Count = 1;
1046  *dsp = rpmdsDup(ods);
1047  ods->Count = save;
1048  }
1049  ds = *dsp;
1050  if (ds == NULL)
1051  return -1;
1052 
1053  /*
1054  * Add new entries.
1055  */
1056 save = ods->i;
1057  ods = rpmdsInit(ods);
1058  if (ods != NULL)
1059  while (rpmdsNext(ods) >= 0) {
1060  /*
1061  * If this entry is already present, don't bother.
1062  */
1063  if (rpmdsFind(ds, ods) >= 0)
1064  continue;
1065 
1066  /*
1067  * Insert new entry.
1068  */
1069  for (j = ds->Count; j > (int)ds->u; j--)
1070  ds->N[j] = ds->N[j-1];
1071  ds->N[ds->u] = ods->N[ods->i];
1072  N = rpmdsDupArgv(ds->N, ds->Count+1);
1073  ds->N = _free(ds->N);
1074  ds->N = N;
1075 
1076  /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
1077 /*@-nullderef -nullpass -nullptrarith @*/
1078 assert(ods->EVR != NULL);
1079 assert(ods->Flags != NULL);
1080 
1081  for (j = ds->Count; j > (int)ds->u; j--)
1082  ds->EVR[j] = ds->EVR[j-1];
1083  ds->EVR[ds->u] = ods->EVR[ods->i];
1084  EVR = rpmdsDupArgv(ds->EVR, ds->Count+1);
1085  ds->EVR = _free(ds->EVR);
1086  ds->EVR = EVR;
1087 
1088  Flags = (evrFlags *) xmalloc((ds->Count+1) * sizeof(*Flags));
1089  if (ds->u > 0)
1090  memcpy(Flags, ds->Flags, ds->u * sizeof(*Flags));
1091  if (ds->u < ds->Count)
1092  memcpy(Flags + ds->u + 1, ds->Flags + ds->u, (ds->Count - ds->u) * sizeof(*Flags));
1093  Flags[ds->u] = ods->Flags[ods->i];
1094  ds->Flags = _free(ds->Flags);
1095  ds->Flags = Flags;
1096 /*@=nullderef =nullpass =nullptrarith @*/
1097 
1098  ds->i = -1;
1099  ds->Count++;
1100 
1101  }
1102 /*@-nullderef@*/
1103 ods->i = save;
1104 /*@=nullderef@*/
1105  return 0;
1106 }
1107 
1109 {
1110  int comparison;
1111  int i, l, u;
1112 
1113  if (ds == NULL || ods == NULL)
1114  return -1;
1115 
1116  /* Binary search to find the [l,u) subset that contains N */
1117  i = -1;
1118  l = 0;
1119  u = ds->Count;
1120  while (l < u) {
1121  i = (l + u) / 2;
1122 
1123  comparison = strcmp(ods->N[ods->i], ds->N[i]);
1124 
1125  if (comparison < 0)
1126  u = i;
1127  else if (comparison > 0)
1128  l = i + 1;
1129  else {
1130  /* Set l to 1st member of set that contains N. */
1131  if (strcmp(ods->N[ods->i], ds->N[l]))
1132  l = i;
1133  while (l > 0 && !strcmp(ods->N[ods->i], ds->N[l-1]))
1134  l--;
1135  /* Set u to 1st member of set that does not contain N. */
1136  if (u >= (int)ds->Count || strcmp(ods->N[ods->i], ds->N[u]))
1137  u = i;
1138  while (++u < (int)ds->Count) {
1139  if (strcmp(ods->N[ods->i], ds->N[u]))
1140  /*@innerbreak@*/ break;
1141  }
1142  break;
1143  }
1144  }
1145 
1146  /* Check each member of [l,u) subset for ranges overlap. */
1147  i = -1;
1148  if (l < u) {
1149  int save = rpmdsSetIx(ds, l-1);
1150  while ((l = rpmdsNext(ds)) >= 0 && (l < u)) {
1151  if ((i = rpmdsCompare(ods, ds)) != 0)
1152  break;
1153  }
1154  /* Return element index that overlaps, or -1. */
1155  if (i)
1156  i = rpmdsIx(ds);
1157  else {
1158  (void) rpmdsSetIx(ds, save);
1159  i = -1;
1160  }
1161  /* Save the return value. */
1162  if (ods->Result != NULL)
1163  (void) rpmdsSetResult(ods, (i != -1 ? 1 : 0));
1164  }
1165  return i;
1166 }
1167 
1176 static void rpmdsNSAdd(/*@out@*/ rpmds *dsp, const char * NS,
1177  const char *N, const char *EVR, evrFlags Flags)
1178  /*@modifies *dsp @*/
1179 {
1180  char *t;
1181  rpmds ds;
1182  int xx;
1183 
1184  t = (char *) alloca(strlen(NS)+sizeof("()")+strlen(N));
1185  *t = '\0';
1186  (void) stpcpy( stpcpy( stpcpy( stpcpy(t, NS), "("), N), ")");
1187 
1188  ds = rpmdsSingle(RPMTAG_PROVIDENAME, t, EVR, Flags);
1189  xx = rpmdsMerge(dsp, ds);
1190  (void)rpmdsFree(ds);
1191  ds = NULL;
1192 }
1193 
1194 #if defined(WITH_CPUINFO)
1195 int rpmdsCpuinfo(rpmds *dsp, const char * fn)
1196 {
1197  const char * NS = "cpuinfo";
1198  struct cpuinfo *cip = cpuinfo_new();
1199  cpuinfo_feature_t feature;
1200  char tmp[20];
1201  union _dbswap {
1202  rpmuint32_t ui;
1203  unsigned char uc[4];
1204  };
1205  static union _dbswap orderedbytes = { .ui = 0x11223344 };
1206  const char * endian = NULL;
1207 
1208  snprintf(tmp, 19, "%d", cpuinfo_get_frequency(cip));
1209  tmp[19] = '\0';
1210  rpmdsNSAdd(dsp, NS, "cpu_MHz", tmp, RPMSENSE_PROBE|RPMSENSE_EQUAL);
1211  snprintf(tmp, 19, "%d", cpuinfo_get_cores(cip));
1212  rpmdsNSAdd(dsp, NS, "cpu_cores", tmp, RPMSENSE_PROBE|RPMSENSE_EQUAL);
1213  snprintf(tmp, 19, "%d", cpuinfo_get_threads(cip));
1214  rpmdsNSAdd(dsp, NS, "cpu_threads", tmp, RPMSENSE_PROBE|RPMSENSE_EQUAL);
1215 
1216  if(orderedbytes.uc[0] == 0x44)
1217  endian = "little";
1218  else if(orderedbytes.uc[0] == 0x11)
1219  endian = "big";
1220  else if(orderedbytes.uc[0] == 0x22)
1221  endian = "pdp";
1222  rpmdsNSAdd(dsp, NS, "endian", endian, RPMSENSE_PROBE|RPMSENSE_EQUAL);
1223 
1224  for (feature = cpuinfo_feature_common; feature != cpuinfo_feature_architecture_max; feature++) {
1225  if(feature == cpuinfo_feature_common_max)
1226  feature = cpuinfo_feature_architecture;
1227  if (cpuinfo_has_feature(cip, feature)) {
1228  const char *name = cpuinfo_string_of_feature(feature);
1229  if (name)
1230  rpmdsNSAdd(dsp, NS, name, "", RPMSENSE_PROBE);
1231  }
1232  }
1233  cpuinfo_destroy(cip);
1234 
1235  return RPMRC_OK;
1236 }
1237 
1238 #else
1239 
1240 struct cpuinfo_s {
1241 /*@observer@*/ /*@null@*/
1242  const char *name;
1243  int done;
1244  int flags;
1245 };
1246 
1247 /*@unchecked@*/
1248 static struct cpuinfo_s ctags[] = {
1249  { "processor", 0, 0 },
1250  { "Processor", 0, 1 }, /* XXX armv5 */
1251  { "vendor_id", 0, 0 },
1252  { "cpu_family", 0, 1 },
1253  { "model", 0, 1 },
1254  { "model_name", 0, 0 },
1255  { "stepping", 0, 1 },
1256  { "cpu_MHz", 0, 1 },
1257  { "CPU_implementer",0, 1 }, /* XXX armv5 */
1258  { "CPU_architecture",0, 1 }, /* XXX armv5 */
1259  { "CPU_variant", 0, 1 }, /* XXX armv5 */
1260  { "CPU_part", 0, 1 }, /* XXX armv5 */
1261  { "CPU_revision", 0, 1 }, /* XXX armv5 */
1262  { "Hardware", 0, 2 }, /* XXX armv5 */
1263  { "Revision", 0, 1 }, /* XXX armv5 */
1264  { "Serial", 0, 1 }, /* XXX armv5 */
1265  { "cache_size", 0, 1 },
1266  { "physical_id", 0, 0 },
1267  { "siblings", 0, 0 },
1268  { "core_id", 0, 0 },
1269  { "cpu_cores", 0, 0 },
1270  { "fdiv_bug", 0, 3 },
1271  { "hlt_bug", 0, 3 },
1272  { "f00f_bug", 0, 3 },
1273  { "coma_bug", 0, 3 },
1274  { "fpu", 0, 0 }, /* XXX use flags attribute instead. */
1275  { "fpu_exception", 0, 3 },
1276  { "cpuid_level", 0, 0 },
1277  { "wp", 0, 3 },
1278  { "flags", 0, 4 },
1279  { "Features", 0, 4 }, /* XXX armv5 */
1280  { "bogomips", 0, 1 },
1281  { "BogoMIPS", 0, 1 }, /* XXX armv5 */
1282  { "clflush_size", 0, 1 },
1283  { NULL, 0, -1 }
1284 };
1285 
1291 static int rpmdsCpuinfoCtagFlags(const char * name)
1292  /*@globals ctags @*/
1293  /*@modifies ctags @*/
1294 {
1295  struct cpuinfo_s * ct;
1296  int flags = -1;
1297 
1298  for (ct = ctags; ct->name != NULL; ct++) {
1299  if (strcmp(ct->name, name))
1300  continue;
1301  if (ct->done)
1302  continue;
1303  ct->done = 1; /* XXX insure single occurrence */
1304  flags = ct->flags;
1305  break;
1306  }
1307  return flags;
1308 }
1309 
1310 #define _PROC_CPUINFO "/proc/cpuinfo"
1311 
1313 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
1314 const char * _cpuinfo_path = NULL;
1315 
1316 int rpmdsCpuinfo(rpmds *dsp, const char * fn)
1317  /*@globals _cpuinfo_path, ctags @*/
1318  /*@modifies _cpuinfo_path, ctags @*/
1319 {
1320  struct cpuinfo_s * ct;
1321  const char * NS = "cpuinfo";
1322  rpmiob iob = NULL;
1323  char * f, * fe, * fend;
1324  char * g, * ge;
1325  char * t;
1326  int rc = -1;
1327  int xx;
1328 
1329 /*@-modobserver@*/
1330  if (_cpuinfo_path == NULL) {
1331  _cpuinfo_path = rpmExpand("%{?_rpmds_cpuinfo_path}", NULL);
1332  /* XXX may need to validate path existence somewhen. */
1333  if (!(_cpuinfo_path != NULL && *_cpuinfo_path == '/')) {
1334 /*@-observertrans @*/
1335  _cpuinfo_path = _free(_cpuinfo_path);
1336 /*@=observertrans @*/
1337  _cpuinfo_path = xstrdup(_PROC_CPUINFO);
1338  }
1339  }
1340 /*@=modobserver@*/
1341 
1342  if (fn == NULL)
1343  fn = _cpuinfo_path;
1344 
1345  /* Reset done variables. */
1346  for (ct = ctags; ct->name != NULL; ct++)
1347  ct->done = 0;
1348 
1349  xx = rpmiobSlurp(fn, &iob);
1350  if (!(xx == 0 && iob != NULL))
1351  goto exit;
1352 
1353  for (f = (char *)iob->b; *f != '\0'; f = fend) {
1354  /* find EOL */
1355  fe = f;
1356  while (*fe != '\0' && !(*fe == '\n' || *fe == '\r'))
1357  fe++;
1358  ge = fe;
1359  while (*fe != '\0' && (*fe == '\n' || *fe == '\r'))
1360  *fe++ = '\0';
1361  fend = fe;
1362 
1363  /* rtrim on line. */
1364  while (--ge > f && _isspace(*ge))
1365  *ge = '\0';
1366 
1367  /* ltrim on line. */
1368  while (*f && _isspace(*f))
1369  f++;
1370 
1371  /* split on ':' */
1372  fe = f;
1373  while (*fe && *fe != ':')
1374  fe++;
1375  if (*fe == '\0')
1376  continue;
1377  g = fe + 1;
1378 
1379  /* rtrim on field 1. */
1380  *fe = '\0';
1381  while (--fe > f && _isspace(*fe))
1382  *fe = '\0';
1383  if (*f == '\0')
1384  continue;
1385 
1386  /* ltrim on field 2. */
1387  while (*g && _isspace(*g))
1388  g++;
1389  if (*g == '\0')
1390  continue;
1391 
1392  for (t = f; *t != '\0'; t++) {
1393  if (_isspace(*t))
1394  *t = '_';
1395  }
1396 
1397  switch (rpmdsCpuinfoCtagFlags(f)) {
1398  case -1: /* not found */
1399  case 0: /* ignore */
1400  default:
1401  continue;
1402  /*@notreached@*/ /*@switchbreak@*/ break;
1403  case 1: /* Provides: cpuinfo(f) = g */
1404  for (t = g; *t != '\0'; t++) {
1405  if (_isspace(*t) || *t == '(' || *t == ')')
1406  *t = '_';
1407  }
1408  rpmdsNSAdd(dsp, NS, f, g, (evrFlags)(RPMSENSE_PROBE|RPMSENSE_EQUAL));
1409  /*@switchbreak@*/ break;
1410  case 2: /* Provides: cpuinfo(g) */
1411  for (t = g; *t != '\0'; t++) {
1412  if (_isspace(*t) || *t == '(' || *t == ')')
1413  *t = '_';
1414  }
1415  rpmdsNSAdd(dsp, NS, g, "", RPMSENSE_PROBE);
1416  /*@switchbreak@*/ break;
1417  case 3: /* if ("yes") Provides: cpuinfo(f) */
1418  if (!strcmp(g, "yes"))
1419  rpmdsNSAdd(dsp, NS, f, "", RPMSENSE_PROBE);
1420  /*@switchbreak@*/ break;
1421  case 4: /* Provides: cpuinfo(g[i]) */
1422  { char ** av = NULL;
1423  int i = 0;
1424  rc = poptParseArgvString(g, NULL, (const char ***)&av);
1425  if (!rc && av != NULL)
1426  while ((t = av[i++]) != NULL)
1427  rpmdsNSAdd(dsp, NS, t, "", RPMSENSE_PROBE);
1428  t = NULL;
1429  if (av != NULL)
1430  free(av);
1431  } /*@switchbreak@*/ break;
1432  }
1433  }
1434 
1435 exit:
1436  iob = rpmiobFree(iob);
1437  return rc;
1438 }
1439 #endif
1440 
1442 /*@observer@*/ /*@relnull@*/
1443  const char * featureName;
1444 /*@observer@*/ /*@relnull@*/
1445  const char * featureEVR;
1447 /*@observer@*/ /*@relnull@*/
1448  const char * featureDescription;
1449 };
1450 
1451 /*@unchecked@*/ /*@observer@*/
1453  { "rpmlib(VersionedDependencies)", "3.0.3-1",
1454  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1455  N_("PreReq:, Provides:, and Obsoletes: dependencies support versions.") },
1456  { "rpmlib(CompressedFileNames)", "3.0.4-1",
1457  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1458  N_("file name(s) stored as (dirName,baseName,dirIndex) tuple, not as path.")},
1459 #if defined(WITH_BZIP2)
1460  { "rpmlib(PayloadIsBzip2)", "3.0.5-1",
1461  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1462  N_("package payload can be compressed using bzip2.") },
1463 #endif
1464  { "rpmlib(PayloadFilesHavePrefix)", "4.0-1",
1465  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1466  N_("package payload file(s) have \"./\" prefix.") },
1467  { "rpmlib(ExplicitPackageProvide)", "4.0-1",
1468  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1469  N_("package name-version-release is not implicitly provided.") },
1470  { "rpmlib(HeaderLoadSortsTags)", "4.0.1-1",
1471  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1472  N_("header tags are always sorted after being loaded.") },
1473  { "rpmlib(ScriptletInterpreterArgs)", "4.0.3-1",
1474  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1475  N_("the scriptlet interpreter can use arguments from header.") },
1476  { "rpmlib(PartialHardlinkSets)", "4.0.4-1",
1477  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1478  N_("a hardlink file set may be installed without being complete.") },
1479  { "rpmlib(ConcurrentAccess)", "4.1-1",
1480  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1481  N_("package scriptlets may access the rpm database while installing.") },
1482 #if defined(WITH_LUA)
1483  { "rpmlib(BuiltinLuaScripts)", "4.2.2-1",
1484  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1485  N_("internal embedded lua scripts.") },
1486 #endif
1487 #if defined(WITH_AUGEAS)
1488  { "rpmlib(BuiltinAugeasScripts)", "5.3-1",
1489  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1490  N_("internal embedded Augeas.") },
1491 #endif
1492 #if defined(WITH_FICL)
1493  { "rpmlib(BuiltinFiclScripts)", "5.2-1",
1494  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1495  N_("internal embedded FICL.") },
1496 #endif
1497 #if defined(WITH_JNIEMBED)
1498  { "rpmlib(BuiltinJVMBeanShell)", "5.4.15-1",
1499  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1500  N_("internal embedded JVM BeanShell.") },
1501 #endif
1502 #if defined(WITH_GPSEE)
1503  { "rpmlib(BuiltinJavaScript)", "5.2-1",
1504  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1505  N_("internal embedded JavaScript.") },
1506 #endif
1507 #if defined(WITH_MRBEMBED)
1508  { "rpmlib(BuiltinMRubyScripts)", "5.4.15-1",
1509  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1510  N_("internal embedded Mruby scripts.") },
1511 #endif
1512 #if defined(WITH_PERLEMBED)
1513  { "rpmlib(BuiltinPerlScripts)", "5.2-1",
1514  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1515  N_("internal embedded perl scripts.") },
1516 #endif
1517 #if defined(WITH_PYTHONEMBED)
1518  { "rpmlib(BuiltinPythonScripts)", "5.2-1",
1519  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1520  N_("internal embedded python scripts.") },
1521 #endif
1522 #if defined(WITH_RUBYEMBED)
1523  { "rpmlib(BuiltinRubyScripts)", "5.2-1",
1524  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1525  N_("internal embedded Cruby scripts.") },
1526 #endif
1527 #if defined(WITH_SEMANAGE)
1528  { "rpmlib(BuiltinSpookScripts)", "5.3-1",
1529  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1530  N_("internal embedded Spook scripts.") },
1531 #endif
1532 #if defined(WITH_SQLITE)
1533  { "rpmlib(BuiltinSqlScripts)", "5.3-1",
1534  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1535  N_("internal embedded sqlite3 scripts.") },
1536 #endif
1537 #if defined(WITH_SQUIRREL)
1538  { "rpmlib(BuiltinSquirrelScripts)", "5.2-1",
1539  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1540  N_("internal embedded squirrel scripts.") },
1541 #endif
1542 #if defined(WITH_TCL)
1543  { "rpmlib(BuiltinTclScripts)", "5.2-1",
1544  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1545  N_("internal embedded tcl scripts.") },
1546 #endif
1547  { "rpmlib(HeaderTagTypeInt64)", "4.4.3-1",
1548  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1549  N_("header tag data can be of type uint64_t.") },
1550  { "rpmlib(PayloadIsUstar)", "4.4.4-1",
1551  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1552  N_("package payload can be in ustar tar archive format.") },
1553 #if defined(WITH_XZ) /* XXX should be 4.4.6, but use SuSE's 4.4.2 instead */
1554  { "rpmlib(PayloadIsLzma)", "4.4.2-1",
1555  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1556  N_("package payload can be compressed using lzma.") },
1557 #endif
1558  { "rpmlib(FileDigestParameterized)", "4.4.6-1",
1559  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1560  N_("file digests can be other than MD5.") },
1561  { "rpmlib(FileDigests)", "4.6.0-1",
1562  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1563  N_("file digests can be other than MD5.") },
1564 #if defined(SUPPORT_AR_PAYLOADS)
1565  { "rpmlib(PayloadIsAr)", "5.1-1",
1566  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1567  N_("package payload can be in ar archive format.") },
1568 #endif
1569 #if defined(WITH_XZ)
1570  { "rpmlib(PayloadIsXz)", "5.2-1",
1571  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1572  N_("package payload can be compressed using xz.") },
1573 #endif
1574  /* XXX FIXME: Alt should _NOT_ have added a tracking dependency. */
1575  { "rpmlib(SetVersions)", "4.0.4-alt98",
1576  (evrFlags)(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
1577  N_("dependencies support set/subset versions.") },
1578  { NULL, NULL, (evrFlags)0, NULL }
1579 };
1580 
1587 int rpmdsRpmlib(rpmds * dsp, void * tblp)
1588 {
1589  const struct rpmlibProvides_s * rltblp = (struct rpmlibProvides_s *) tblp;
1590  const struct rpmlibProvides_s * rlp;
1591  int xx;
1592 
1593  if (rltblp == NULL)
1594  rltblp = rpmlibProvides;
1595 
1596  for (rlp = rltblp; rlp->featureName != NULL; rlp++) {
1598  rlp->featureEVR, rlp->featureFlags);
1599  xx = rpmdsMerge(dsp, ds);
1600  (void)rpmdsFree(ds);
1601  ds = NULL;
1602  }
1603  return 0;
1604 }
1605 
1613 static int rpmdsSysinfoFile(rpmPRCO PRCO, const char * fn, rpmTag tagN)
1614  /*@globals h_errno, fileSystem, internalState @*/
1615  /*@modifies PRCO, fileSystem, internalState @*/
1616 {
1617  char buf[BUFSIZ];
1618  const char *N, *EVR;
1619  evrFlags Flags;
1620  rpmds ds;
1621  char * f, * fe;
1622  char * g, * ge;
1623  FD_t fd = NULL;
1624  FILE * fp;
1625  int rc = -1;
1626  int ln;
1627  int xx;
1628 
1629  /* XXX for now, collect Dirnames/Filelinktos in Providename */
1630  if (tagN == RPMTAG_DIRNAMES || tagN == RPMTAG_FILELINKTOS)
1631  tagN = RPMTAG_PROVIDENAME;
1632 
1633 assert(fn != NULL);
1634  fd = Fopen(fn, "r.fpio");
1635  if (fd == NULL || Ferror(fd))
1636  goto exit;
1637  fp = fdGetFILE(fd);
1638 
1639  ln = 0;
1640  if (fp != NULL)
1641  while((f = fgets(buf, (int)sizeof(buf), fp)) != NULL) {
1642  ln++;
1643 
1644  /* insure a terminator. */
1645  buf[sizeof(buf)-1] = '\0';
1646 
1647  /* ltrim on line. */
1648  while (*f && _isspace(*f))
1649  f++;
1650 
1651  /* XXX skip YAML "- " markup */
1652  if (f[0] == '-' && _isspace(f[1])) {
1653  f += sizeof("- ")-1;
1654  while (*f && _isspace(*f))
1655  f++;
1656  }
1657 
1658  /* skip empty lines and comments */
1659  if (*f == '\0' || *f == '#')
1660  continue;
1661 
1662  /* rtrim on line. */
1663  fe = f + strlen(f);
1664  while (--fe > f && _isspace(*fe))
1665  *fe = '\0';
1666 
1667  if (!(xisalnum(f[0]) || strchr("/_%!", f[0]) != NULL)) {
1668  fprintf(stderr, _("%s:%d \"%s\" has invalid name. Skipping ...\n"),
1669  fn, ln, f);
1670  continue;
1671  }
1672 
1673  /* split on ' ' or comparison operator. */
1674  fe = f;
1675  if (*f == '!') fe++;
1676  while (*fe && !_isspace(*fe) && strchr("!<=>", *fe) == NULL)
1677  fe++;
1678  while (*fe && _isspace(*fe))
1679  *fe++ = '\0';
1680 
1681  N = f;
1682  EVR = NULL;
1683  Flags = (evrFlags) 0;
1684 
1685  /* parse for non-path, versioned dependency. */
1686  if (*f != '/' && *fe != '\0') {
1687  /* parse comparison operator */
1688  g = fe;
1689  Flags = rpmEVRflags(fe, (const char **)&g);
1690  if (Flags == 0) {
1691  fprintf(stderr, _("%s:%d \"%s\" has no comparison operator. Skipping ...\n"),
1692  fn, ln, fe);
1693  continue;
1694  }
1695  *fe = '\0';
1696 
1697  /* ltrim on field 2. */
1698  while (*g && _isspace(*g))
1699  g++;
1700  if (*g == '\0') {
1701  /* XXX No EVR comparison value found. */
1702  fprintf(stderr, _("%s:%d \"%s\" has no EVR string. Skipping ...\n"),
1703  fn, ln, f);
1704  continue;
1705  }
1706 
1707  ge = g + 1;
1708  while (*ge && !_isspace(*ge))
1709  ge++;
1710 
1711  if (*ge != '\0')
1712  *ge = '\0'; /* XXX can't happen, line rtrim'ed already. */
1713 
1714  EVR = g;
1715  }
1716 
1717  if (EVR == NULL)
1718  EVR = "";
1719  Flags = (evrFlags) (Flags | RPMSENSE_PROBE);
1720  ds = rpmdsSingle(tagN, N, EVR , Flags);
1721  if (ds) { /* XXX can't happen */
1722  xx = rpmdsMergePRCO(PRCO, ds);
1723  (void)rpmdsFree(ds);
1724  ds = NULL;
1725  }
1726  }
1727  rc = 0;
1728 
1729 exit:
1730  if (fd != NULL) (void) Fclose(fd);
1731  return rc;
1732 }
1733 
1734 #if defined(RPM_VENDOR_WINDRIVER)
1735 #define _ETC_RPM_SYSINFO "%{_etcrpm}/sysinfo"
1736 #else
1737 #define _ETC_RPM_SYSINFO SYSCONFIGDIR "/sysinfo"
1738 #endif
1739 
1740 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
1741 const char *_sysinfo_path = NULL;
1742 
1743 /*@-nullassign@*/
1744 /*@unchecked@*/ /*@observer@*/ /*@relnull@*/
1745 static const char *_sysinfo_tags[] = {
1746  "Providename",
1747  "Requirename",
1748  "Conflictname",
1749  "Obsoletename",
1750  "Dirnames",
1751  "Filelinktos",
1752  NULL
1753 };
1754 /*@=nullassign@*/
1755 
1756 int rpmdsSysinfo(rpmPRCO PRCO, const char * fn)
1757  /*@globals _sysinfo_path @*/
1758  /*@modifies _sysinfo_path @*/
1759 {
1760  struct stat * st = (struct stat *) memset(alloca(sizeof(*st)), 0, sizeof(*st));
1761  int rc = -1;
1762  int xx;
1763 
1764 /*@-modobserver@*/
1765  if (_sysinfo_path == NULL) {
1766  _sysinfo_path = rpmExpand("%{?_rpmds_sysinfo_path}", NULL);
1767  /* XXX may need to validate path existence somewhen. */
1768  if (!(_sysinfo_path != NULL && *_sysinfo_path == '/')) {
1769 /*@-observertrans @*/
1770  _sysinfo_path = _free(_sysinfo_path);
1771 /*@=observertrans @*/
1772  _sysinfo_path = xstrdup(_ETC_RPM_SYSINFO);
1773  }
1774  }
1775 /*@=modobserver@*/
1776 
1777  if (fn == NULL)
1778  fn = _sysinfo_path;
1779 
1780  if (fn == NULL)
1781  goto exit;
1782 
1783  xx = Stat(fn, st);
1784  if (xx < 0)
1785  goto exit;
1786 
1787  if (S_ISDIR(st->st_mode)) {
1788  const char *dn = fn;
1789  const char **av;
1790  rpmTag tagN;
1791  rc = 0; /* assume success */
1792  for (av = _sysinfo_tags; av && *av; av++) {
1793  tagN = tagValue(*av);
1794  if ((int)tagN < 0) /* XXX FIXME: all tags are valid now */
1795  continue;
1796  fn = rpmGetPath(dn, "/", *av, NULL);
1797  st = (struct stat *) memset(st, 0, sizeof(*st));
1798  xx = Stat(fn, st);
1799  if (xx == 0 && S_ISREG(st->st_mode))
1800  rc = rpmdsSysinfoFile(PRCO, fn, tagN);
1801  fn = _free(fn);
1802  if (rc)
1803  break;
1804  }
1805  } else
1806  /* XXX for now, collect Dirnames/Filelinktos in Providename */
1807  if (S_ISREG(st->st_mode))
1808  rc = rpmdsSysinfoFile(PRCO, fn, RPMTAG_PROVIDENAME);
1809 
1810 exit:
1811  return rc;
1812 }
1813 
1814 typedef enum { SYSCONF, CONFSTR, PATHCONF } _conf_e;
1815 struct _conf_s {
1816 /*@observer@*/ /*@relnull@*/
1817  const char *name;
1818  const int call_name;
1819  const _conf_e call;
1820 };
1821 
1822 /*@unchecked@*/ /*@observer@*/
1823 static const struct _conf_s vars[] = {
1824 #ifdef _PC_LINK_MAX
1825  { "LINK_MAX", _PC_LINK_MAX, PATHCONF },
1826 #endif
1827 #ifdef _PC_LINK_MAX
1828  { "_POSIX_LINK_MAX", _PC_LINK_MAX, PATHCONF },
1829 #endif
1830 #ifdef _PC_MAX_CANON
1831  { "MAX_CANON", _PC_MAX_CANON, PATHCONF },
1832 #endif
1833 #ifdef _PC_MAX_CANON
1834  { "_POSIX_MAX_CANON", _PC_MAX_CANON, PATHCONF },
1835 #endif
1836 #ifdef _PC_MAX_INPUT
1837  { "MAX_INPUT", _PC_MAX_INPUT, PATHCONF },
1838 #endif
1839 #ifdef _PC_MAX_INPUT
1840  { "_POSIX_MAX_INPUT", _PC_MAX_INPUT, PATHCONF },
1841 #endif
1842 #ifdef _PC_NAME_MAX
1843  { "NAME_MAX", _PC_NAME_MAX, PATHCONF },
1844 #endif
1845 #ifdef _PC_NAME_MAX
1846  { "_POSIX_NAME_MAX", _PC_NAME_MAX, PATHCONF },
1847 #endif
1848 #ifdef _PC_PATH_MAX
1849  { "PATH_MAX", _PC_PATH_MAX, PATHCONF },
1850 #endif
1851 #ifdef _PC_PATH_MAX
1852  { "_POSIX_PATH_MAX", _PC_PATH_MAX, PATHCONF },
1853 #endif
1854 #ifdef _PC_PIPE_BUF
1855  { "PIPE_BUF", _PC_PIPE_BUF, PATHCONF },
1856 #endif
1857 #ifdef _PC_PIPE_BUF
1858  { "_POSIX_PIPE_BUF", _PC_PIPE_BUF, PATHCONF },
1859 #endif
1860 #ifdef _PC_SOCK_MAXBUF
1861  { "SOCK_MAXBUF", _PC_SOCK_MAXBUF, PATHCONF },
1862 #endif
1863 #ifdef _PC_ASYNC_IO
1864  { "_POSIX_ASYNC_IO", _PC_ASYNC_IO, PATHCONF },
1865 #endif
1866 #ifdef _PC_CHOWN_RESTRICTED
1867  { "_POSIX_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED, PATHCONF },
1868 #endif
1869 #ifdef _PC_NO_TRUNC
1870  { "_POSIX_NO_TRUNC", _PC_NO_TRUNC, PATHCONF },
1871 #endif
1872 #ifdef _PC_PRIO_IO
1873  { "_POSIX_PRIO_IO", _PC_PRIO_IO, PATHCONF },
1874 #endif
1875 #ifdef _PC_SYNC_IO
1876  { "_POSIX_SYNC_IO", _PC_SYNC_IO, PATHCONF },
1877 #endif
1878 #ifdef _PC_VDISABLE
1879  { "_POSIX_VDISABLE", _PC_VDISABLE, PATHCONF },
1880 #endif
1881 
1882 #ifdef _SC_ARG_MAX
1883  { "ARG_MAX", _SC_ARG_MAX, SYSCONF },
1884 #endif
1885 #ifdef _SC_ATEXIT_MAX
1886  { "ATEXIT_MAX", _SC_ATEXIT_MAX, SYSCONF },
1887 #endif
1888 #ifdef _SC_CHAR_BIT
1889  { "CHAR_BIT", _SC_CHAR_BIT, SYSCONF },
1890 #endif
1891 #ifdef _SC_CHAR_MAX
1892  { "CHAR_MAX", _SC_CHAR_MAX, SYSCONF },
1893 #endif
1894 #ifdef _SC_CHAR_MIN
1895  { "CHAR_MIN", _SC_CHAR_MIN, SYSCONF },
1896 #endif
1897 #ifdef _SC_CHILD_MAX
1898  { "CHILD_MAX", _SC_CHILD_MAX, SYSCONF },
1899 #endif
1900 #ifdef _SC_CLK_TCK
1901  { "CLK_TCK", _SC_CLK_TCK, SYSCONF },
1902 #endif
1903 #ifdef _SC_INT_MAX
1904  { "INT_MAX", _SC_INT_MAX, SYSCONF },
1905 #endif
1906 #ifdef _SC_INT_MIN
1907  { "INT_MIN", _SC_INT_MIN, SYSCONF },
1908 #endif
1909 #ifdef _SC_UIO_MAXIOV
1910  { "IOV_MAX", _SC_UIO_MAXIOV, SYSCONF },
1911 #endif
1912 #ifdef _SC_LOGIN_NAME_MAX
1913  { "LOGNAME_MAX", _SC_LOGIN_NAME_MAX, SYSCONF },
1914 #endif
1915 #ifdef _SC_LONG_BIT
1916  { "LONG_BIT", _SC_LONG_BIT, SYSCONF },
1917 #endif
1918 #ifdef _SC_MB_LEN_MAX
1919  { "MB_LEN_MAX", _SC_MB_LEN_MAX, SYSCONF },
1920 #endif
1921 #ifdef _SC_NGROUPS_MAX
1922  { "NGROUPS_MAX", _SC_NGROUPS_MAX, SYSCONF },
1923 #endif
1924 #ifdef _SC_NL_ARGMAX
1925  { "NL_ARGMAX", _SC_NL_ARGMAX, SYSCONF },
1926 #endif
1927 #ifdef _SC_NL_LANGMAX
1928  { "NL_LANGMAX", _SC_NL_LANGMAX, SYSCONF },
1929 #endif
1930 #ifdef _SC_NL_MSGMAX
1931  { "NL_MSGMAX", _SC_NL_MSGMAX, SYSCONF },
1932 #endif
1933 #ifdef _SC_NL_NMAX
1934  { "NL_NMAX", _SC_NL_NMAX, SYSCONF },
1935 #endif
1936 #ifdef _SC_NL_SETMAX
1937  { "NL_SETMAX", _SC_NL_SETMAX, SYSCONF },
1938 #endif
1939 #ifdef _SC_NL_TEXTMAX
1940  { "NL_TEXTMAX", _SC_NL_TEXTMAX, SYSCONF },
1941 #endif
1942 #ifdef _SC_GETGR_R_SIZE_MAX
1943  { "NSS_BUFLEN_GROUP", _SC_GETGR_R_SIZE_MAX, SYSCONF },
1944 #endif
1945 #ifdef _SC_GETPW_R_SIZE_MAX
1946  { "NSS_BUFLEN_PASSWD", _SC_GETPW_R_SIZE_MAX, SYSCONF },
1947 #endif
1948 #ifdef _SC_NZERO
1949  { "NZERO", _SC_NZERO, SYSCONF },
1950 #endif
1951 #ifdef _SC_OPEN_MAX
1952  { "OPEN_MAX", _SC_OPEN_MAX, SYSCONF },
1953 #endif
1954 #ifdef _SC_PAGESIZE
1955  { "PAGESIZE", _SC_PAGESIZE, SYSCONF },
1956 #endif
1957 #ifdef _SC_PAGESIZE
1958  { "PAGE_SIZE", _SC_PAGESIZE, SYSCONF },
1959 #endif
1960 #ifdef _SC_PASS_MAX
1961  { "PASS_MAX", _SC_PASS_MAX, SYSCONF },
1962 #endif
1963 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
1964  { "PTHREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS, SYSCONF },
1965 #endif
1966 #ifdef _SC_THREAD_KEYS_MAX
1967  { "PTHREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX, SYSCONF },
1968 #endif
1969 #ifdef _SC_THREAD_STACK_MIN
1970  { "PTHREAD_STACK_MIN", _SC_THREAD_STACK_MIN, SYSCONF },
1971 #endif
1972 #ifdef _SC_THREAD_THREADS_MAX
1973  { "PTHREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX, SYSCONF },
1974 #endif
1975 #ifdef _SC_SCHAR_MAX
1976  { "SCHAR_MAX", _SC_SCHAR_MAX, SYSCONF },
1977 #endif
1978 #ifdef _SC_SCHAR_MIN
1979  { "SCHAR_MIN", _SC_SCHAR_MIN, SYSCONF },
1980 #endif
1981 #ifdef _SC_SHRT_MAX
1982  { "SHRT_MAX", _SC_SHRT_MAX, SYSCONF },
1983 #endif
1984 #ifdef _SC_SHRT_MIN
1985  { "SHRT_MIN", _SC_SHRT_MIN, SYSCONF },
1986 #endif
1987 #ifdef _SC_SSIZE_MAX
1988  { "SSIZE_MAX", _SC_SSIZE_MAX, SYSCONF },
1989 #endif
1990 #ifdef _SC_TTY_NAME_MAX
1991  { "TTY_NAME_MAX", _SC_TTY_NAME_MAX, SYSCONF },
1992 #endif
1993 #ifdef _SC_TZNAME_MAX
1994  { "TZNAME_MAX", _SC_TZNAME_MAX, SYSCONF },
1995 #endif
1996 #ifdef _SC_UCHAR_MAX
1997  { "UCHAR_MAX", _SC_UCHAR_MAX, SYSCONF },
1998 #endif
1999 #ifdef _SC_UINT_MAX
2000  { "UINT_MAX", _SC_UINT_MAX, SYSCONF },
2001 #endif
2002 #ifdef _SC_UIO_MAXIOV
2003  { "UIO_MAXIOV", _SC_UIO_MAXIOV, SYSCONF },
2004 #endif
2005 #ifdef _SC_ULONG_MAX
2006  { "ULONG_MAX", _SC_ULONG_MAX, SYSCONF },
2007 #endif
2008 #ifdef _SC_USHRT_MAX
2009  { "USHRT_MAX", _SC_USHRT_MAX, SYSCONF },
2010 #endif
2011 #ifdef _SC_WORD_BIT
2012  { "WORD_BIT", _SC_WORD_BIT, SYSCONF },
2013 #endif
2014 #ifdef _SC_AVPHYS_PAGES
2015  { "_AVPHYS_PAGES", _SC_AVPHYS_PAGES, SYSCONF },
2016 #endif
2017 #ifdef _SC_NPROCESSORS_CONF
2018  { "_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF, SYSCONF },
2019 #endif
2020 #ifdef _SC_NPROCESSORS_ONLN
2021  { "_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN, SYSCONF },
2022 #endif
2023 #ifdef _SC_PHYS_PAGES
2024  { "_PHYS_PAGES", _SC_PHYS_PAGES, SYSCONF },
2025 #endif
2026 #ifdef _SC_ARG_MAX
2027  { "_POSIX_ARG_MAX", _SC_ARG_MAX, SYSCONF },
2028 #endif
2029 #ifdef _SC_ASYNCHRONOUS_IO
2030  { "_POSIX_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO, SYSCONF },
2031 #endif
2032 #ifdef _SC_CHILD_MAX
2033  { "_POSIX_CHILD_MAX", _SC_CHILD_MAX, SYSCONF },
2034 #endif
2035 #ifdef _SC_FSYNC
2036  { "_POSIX_FSYNC", _SC_FSYNC, SYSCONF },
2037 #endif
2038 #ifdef _SC_JOB_CONTROL
2039  { "_POSIX_JOB_CONTROL", _SC_JOB_CONTROL, SYSCONF },
2040 #endif
2041 #ifdef _SC_MAPPED_FILES
2042  { "_POSIX_MAPPED_FILES", _SC_MAPPED_FILES, SYSCONF },
2043 #endif
2044 #ifdef _SC_MEMLOCK
2045  { "_POSIX_MEMLOCK", _SC_MEMLOCK, SYSCONF },
2046 #endif
2047 #ifdef _SC_MEMLOCK_RANGE
2048  { "_POSIX_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE, SYSCONF },
2049 #endif
2050 #ifdef _SC_MEMORY_PROTECTION
2051  { "_POSIX_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION, SYSCONF },
2052 #endif
2053 #ifdef _SC_MESSAGE_PASSING
2054  { "_POSIX_MESSAGE_PASSING", _SC_MESSAGE_PASSING, SYSCONF },
2055 #endif
2056 #ifdef _SC_NGROUPS_MAX
2057  { "_POSIX_NGROUPS_MAX", _SC_NGROUPS_MAX, SYSCONF },
2058 #endif
2059 #ifdef _SC_OPEN_MAX
2060  { "_POSIX_OPEN_MAX", _SC_OPEN_MAX, SYSCONF },
2061 #endif
2062 #ifdef _SC_PII
2063  { "_POSIX_PII", _SC_PII, SYSCONF },
2064 #endif
2065 #ifdef _SC_PII_INTERNET
2066  { "_POSIX_PII_INTERNET", _SC_PII_INTERNET, SYSCONF },
2067 #endif
2068 #ifdef _SC_PII_INTERNET_DGRAM
2069  { "_POSIX_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM, SYSCONF },
2070 #endif
2071 #ifdef _SC_PII_INTERNET_STREAM
2072  { "_POSIX_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM, SYSCONF },
2073 #endif
2074 #ifdef _SC_PII_OSI
2075  { "_POSIX_PII_OSI", _SC_PII_OSI, SYSCONF },
2076 #endif
2077 #ifdef _SC_PII_OSI_CLTS
2078  { "_POSIX_PII_OSI_CLTS", _SC_PII_OSI_CLTS, SYSCONF },
2079 #endif
2080 #ifdef _SC_PII_OSI_COTS
2081  { "_POSIX_PII_OSI_COTS", _SC_PII_OSI_COTS, SYSCONF },
2082 #endif
2083 #ifdef _SC_PII_OSI_M
2084  { "_POSIX_PII_OSI_M", _SC_PII_OSI_M, SYSCONF },
2085 #endif
2086 #ifdef _SC_PII_SOCKET
2087  { "_POSIX_PII_SOCKET", _SC_PII_SOCKET, SYSCONF },
2088 #endif
2089 #ifdef _SC_PII_XTI
2090  { "_POSIX_PII_XTI", _SC_PII_XTI, SYSCONF },
2091 #endif
2092 #ifdef _SC_POLL
2093  { "_POSIX_POLL", _SC_POLL, SYSCONF },
2094 #endif
2095 #ifdef _SC_PRIORITIZED_IO
2096  { "_POSIX_PRIORITIZED_IO", _SC_PRIORITIZED_IO, SYSCONF },
2097 #endif
2098 #ifdef _SC_PRIORITY_SCHEDULING
2099  { "_POSIX_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING, SYSCONF },
2100 #endif
2101 #ifdef _SC_REALTIME_SIGNALS
2102  { "_POSIX_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS, SYSCONF },
2103 #endif
2104 #ifdef _SC_SAVED_IDS
2105  { "_POSIX_SAVED_IDS", _SC_SAVED_IDS, SYSCONF },
2106 #endif
2107 #ifdef _SC_SELECT
2108  { "_POSIX_SELECT", _SC_SELECT, SYSCONF },
2109 #endif
2110 #ifdef _SC_SEMAPHORES
2111  { "_POSIX_SEMAPHORES", _SC_SEMAPHORES, SYSCONF },
2112 #endif
2113 #ifdef _SC_SHARED_MEMORY_OBJECTS
2114  { "_POSIX_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS, SYSCONF },
2115 #endif
2116 #ifdef _SC_SSIZE_MAX
2117  { "_POSIX_SSIZE_MAX", _SC_SSIZE_MAX, SYSCONF },
2118 #endif
2119 #ifdef _SC_STREAM_MAX
2120  { "_POSIX_STREAM_MAX", _SC_STREAM_MAX, SYSCONF },
2121 #endif
2122 #ifdef _SC_SYNCHRONIZED_IO
2123  { "_POSIX_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO, SYSCONF },
2124 #endif
2125 #ifdef _SC_THREADS
2126  { "_POSIX_THREADS", _SC_THREADS, SYSCONF },
2127 #endif
2128 #ifdef _SC_THREAD_ATTR_STACKADDR
2129  { "_POSIX_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR, SYSCONF },
2130 #endif
2131 #ifdef _SC_THREAD_ATTR_STACKSIZE
2132  { "_POSIX_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE, SYSCONF },
2133 #endif
2134 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
2135  { "_POSIX_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING, SYSCONF },
2136 #endif
2137 #ifdef _SC_THREAD_PRIO_INHERIT
2138  { "_POSIX_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT, SYSCONF },
2139 #endif
2140 #ifdef _SC_THREAD_PRIO_PROTECT
2141  { "_POSIX_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT, SYSCONF },
2142 #endif
2143 #ifdef _SC_THREAD_PROCESS_SHARED
2144  { "_POSIX_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED, SYSCONF },
2145 #endif
2146 #ifdef _SC_THREAD_SAFE_FUNCTIONS
2147  { "_POSIX_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS, SYSCONF },
2148 #endif
2149 #ifdef _SC_TIMERS
2150  { "_POSIX_TIMERS", _SC_TIMERS, SYSCONF },
2151 #endif
2152 #ifdef _SC_TIMER_MAX
2153  { "TIMER_MAX", _SC_TIMER_MAX, SYSCONF },
2154 #endif
2155 #ifdef _SC_TZNAME_MAX
2156  { "_POSIX_TZNAME_MAX", _SC_TZNAME_MAX, SYSCONF },
2157 #endif
2158 #ifdef _SC_VERSION
2159  { "_POSIX_VERSION", _SC_VERSION, SYSCONF },
2160 #endif
2161 #ifdef _SC_T_IOV_MAX
2162  { "_T_IOV_MAX", _SC_T_IOV_MAX, SYSCONF },
2163 #endif
2164 #ifdef _SC_XOPEN_CRYPT
2165  { "_XOPEN_CRYPT", _SC_XOPEN_CRYPT, SYSCONF },
2166 #endif
2167 #ifdef _SC_XOPEN_ENH_I18N
2168  { "_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N, SYSCONF },
2169 #endif
2170 #ifdef _SC_XOPEN_LEGACY
2171  { "_XOPEN_LEGACY", _SC_XOPEN_LEGACY, SYSCONF },
2172 #endif
2173 #ifdef _SC_XOPEN_REALTIME
2174  { "_XOPEN_REALTIME", _SC_XOPEN_REALTIME, SYSCONF },
2175 #endif
2176 #ifdef _SC_XOPEN_REALTIME_THREADS
2177  { "_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS, SYSCONF },
2178 #endif
2179 #ifdef _SC_XOPEN_SHM
2180  { "_XOPEN_SHM", _SC_XOPEN_SHM, SYSCONF },
2181 #endif
2182 #ifdef _SC_XOPEN_UNIX
2183  { "_XOPEN_UNIX", _SC_XOPEN_UNIX, SYSCONF },
2184 #endif
2185 #ifdef _SC_XOPEN_VERSION
2186  { "_XOPEN_VERSION", _SC_XOPEN_VERSION, SYSCONF },
2187 #endif
2188 #ifdef _SC_XOPEN_XCU_VERSION
2189  { "_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION, SYSCONF },
2190 #endif
2191 #ifdef _SC_XOPEN_XPG2
2192  { "_XOPEN_XPG2", _SC_XOPEN_XPG2, SYSCONF },
2193 #endif
2194 #ifdef _SC_XOPEN_XPG3
2195  { "_XOPEN_XPG3", _SC_XOPEN_XPG3, SYSCONF },
2196 #endif
2197 #ifdef _SC_XOPEN_XPG4
2198  { "_XOPEN_XPG4", _SC_XOPEN_XPG4, SYSCONF },
2199 #endif
2200  /* POSIX.2 */
2201 #ifdef _SC_BC_BASE_MAX
2202  { "BC_BASE_MAX", _SC_BC_BASE_MAX, SYSCONF },
2203 #endif
2204 #ifdef _SC_BC_DIM_MAX
2205  { "BC_DIM_MAX", _SC_BC_DIM_MAX, SYSCONF },
2206 #endif
2207 #ifdef _SC_BC_SCALE_MAX
2208  { "BC_SCALE_MAX", _SC_BC_SCALE_MAX, SYSCONF },
2209 #endif
2210 #ifdef _SC_BC_STRING_MAX
2211  { "BC_STRING_MAX", _SC_BC_STRING_MAX, SYSCONF },
2212 #endif
2213 #ifdef _SC_CHARCLASS_NAME_MAX
2214  { "CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX, SYSCONF },
2215 #endif
2216 #ifdef _SC_COLL_WEIGHTS_MAX
2217  { "COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX, SYSCONF },
2218 #endif
2219 #ifdef _SC_EQUIV_CLASS_MAX
2220  { "EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX, SYSCONF },
2221 #endif
2222 #ifdef _SC_EXPR_NEST_MAX
2223  { "EXPR_NEST_MAX", _SC_EXPR_NEST_MAX, SYSCONF },
2224 #endif
2225 #ifdef _SC_LINE_MAX
2226  { "LINE_MAX", _SC_LINE_MAX, SYSCONF },
2227 #endif
2228 #ifdef _SC_BC_BASE_MAX
2229  { "POSIX2_BC_BASE_MAX", _SC_BC_BASE_MAX, SYSCONF },
2230 #endif
2231 #ifdef _SC_BC_DIM_MAX
2232  { "POSIX2_BC_DIM_MAX", _SC_BC_DIM_MAX, SYSCONF },
2233 #endif
2234 #ifdef _SC_BC_SCALE_MAX
2235  { "POSIX2_BC_SCALE_MAX", _SC_BC_SCALE_MAX, SYSCONF },
2236 #endif
2237 #ifdef _SC_BC_STRING_MAX
2238  { "POSIX2_BC_STRING_MAX", _SC_BC_STRING_MAX, SYSCONF },
2239 #endif
2240 #ifdef _SC_2_CHAR_TERM
2241  { "POSIX2_CHAR_TERM", _SC_2_CHAR_TERM, SYSCONF },
2242 #endif
2243 #ifdef _SC_COLL_WEIGHTS_MAX
2244  { "POSIX2_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX, SYSCONF },
2245 #endif
2246 #ifdef _SC_2_C_BIND
2247  { "POSIX2_C_BIND", _SC_2_C_BIND, SYSCONF },
2248 #endif
2249 #ifdef _SC_2_C_DEV
2250  { "POSIX2_C_DEV", _SC_2_C_DEV, SYSCONF },
2251 #endif
2252 #ifdef _SC_2_C_VERSION
2253  { "POSIX2_C_VERSION", _SC_2_C_VERSION, SYSCONF },
2254 #endif
2255 #ifdef _SC_EXPR_NEST_MAX
2256  { "POSIX2_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX, SYSCONF },
2257 #endif
2258 #ifdef _SC_2_FORT_DEV
2259  { "POSIX2_FORT_DEV", _SC_2_FORT_DEV, SYSCONF },
2260 #endif
2261 #ifdef _SC_2_FORT_RUN
2262  { "POSIX2_FORT_RUN", _SC_2_FORT_RUN, SYSCONF },
2263 #endif
2264 #ifdef _SC_LINE_MAX
2265  { "_POSIX2_LINE_MAX", _SC_LINE_MAX, SYSCONF },
2266 #endif
2267 #ifdef _SC_2_LOCALEDEF
2268  { "POSIX2_LOCALEDEF", _SC_2_LOCALEDEF, SYSCONF },
2269 #endif
2270 #ifdef _SC_RE_DUP_MAX
2271  { "POSIX2_RE_DUP_MAX", _SC_RE_DUP_MAX, SYSCONF },
2272 #endif
2273 #ifdef _SC_2_SW_DEV
2274  { "POSIX2_SW_DEV", _SC_2_SW_DEV, SYSCONF },
2275 #endif
2276 #ifdef _SC_2_UPE
2277  { "POSIX2_UPE", _SC_2_UPE, SYSCONF },
2278 #endif
2279 #ifdef _SC_2_VERSION
2280  { "POSIX2_VERSION", _SC_2_VERSION, SYSCONF },
2281 #endif
2282 #ifdef _SC_RE_DUP_MAX
2283  { "RE_DUP_MAX", _SC_RE_DUP_MAX, SYSCONF },
2284 #endif
2285 
2286 #ifdef _CS_PATH
2287  { "PATH", _CS_PATH, CONFSTR },
2288  { "CS_PATH", _CS_PATH, CONFSTR },
2289 #endif
2290 
2291  /* LFS */
2292 #ifdef _CS_LFS_CFLAGS
2293  { "LFS_CFLAGS", _CS_LFS_CFLAGS, CONFSTR },
2294 #endif
2295 #ifdef _CS_LFS_LDFLAGS
2296  { "LFS_LDFLAGS", _CS_LFS_LDFLAGS, CONFSTR },
2297 #endif
2298 #ifdef _CS_LFS_LIBS
2299  { "LFS_LIBS", _CS_LFS_LIBS, CONFSTR },
2300 #endif
2301 #ifdef _CS_LFS_LINTFLAGS
2302  { "LFS_LINTFLAGS", _CS_LFS_LINTFLAGS, CONFSTR },
2303 #endif
2304 #ifdef _CS_LFS64_CFLAGS
2305  { "LFS64_CFLAGS", _CS_LFS64_CFLAGS, CONFSTR },
2306 #endif
2307 #ifdef _CS_LFS64_LDFLAGS
2308  { "LFS64_LDFLAGS", _CS_LFS64_LDFLAGS, CONFSTR },
2309 #endif
2310 #ifdef _CS_LFS64_LIBS
2311  { "LFS64_LIBS", _CS_LFS64_LIBS, CONFSTR },
2312 #endif
2313 #ifdef _CS_LFS64_LINTFLAGS
2314  { "LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS, CONFSTR },
2315 #endif
2316 
2317  /* Programming environments. */
2318 #ifdef _SC_XBS5_ILP32_OFF32
2319  { "_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32, SYSCONF },
2320 #endif
2321 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
2322  { "XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS, CONFSTR },
2323 #endif
2324 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
2325  { "XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS, CONFSTR },
2326 #endif
2327 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
2328  { "XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS, CONFSTR },
2329 #endif
2330 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
2331  { "XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS, CONFSTR },
2332 #endif
2333 
2334 #ifdef _SC_XBS5_ILP32_OFFBIG
2335  { "_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG, SYSCONF },
2336 #endif
2337 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
2338  { "XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS, CONFSTR },
2339 #endif
2340 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
2341  { "XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS, CONFSTR },
2342 #endif
2343 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
2344  { "XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS, CONFSTR },
2345 #endif
2346 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
2347  { "XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS, CONFSTR },
2348 #endif
2349 
2350 #ifdef _SC_XBS5_LP64_OFF64
2351  { "_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64, SYSCONF },
2352 #endif
2353 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
2354  { "XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS, CONFSTR },
2355 #endif
2356 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
2357  { "XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS, CONFSTR },
2358 #endif
2359 #ifdef _CS_XBS5_LP64_OFF64_LIBS
2360  { "XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS, CONFSTR },
2361 #endif
2362 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
2363  { "XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS, CONFSTR },
2364 #endif
2365 
2366 #ifdef _SC_XBS5_LPBIG_OFFBIG
2367  { "_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG, SYSCONF },
2368 #endif
2369 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
2370  { "XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS, CONFSTR },
2371 #endif
2372 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
2373  { "XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS, CONFSTR },
2374 #endif
2375 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
2376  { "XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS, CONFSTR },
2377 #endif
2378 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
2379  { "XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS, CONFSTR },
2380 #endif
2381 
2382 #ifdef _SC_V6_ILP32_OFF32
2383  { "_POSIX_V6_ILP32_OFF32", _SC_V6_ILP32_OFF32, SYSCONF },
2384 #endif
2385 #ifdef _CS_POSIX_V6_ILP32_OFF32_CFLAGS
2386  { "POSIX_V6_ILP32_OFF32_CFLAGS", _CS_POSIX_V6_ILP32_OFF32_CFLAGS, CONFSTR },
2387 #endif
2388 #ifdef _CS_POSIX_V6_ILP32_OFF32_LDFLAGS
2389  { "POSIX_V6_ILP32_OFF32_LDFLAGS", _CS_POSIX_V6_ILP32_OFF32_LDFLAGS, CONFSTR },
2390 #endif
2391 #ifdef _CS_POSIX_V6_ILP32_OFF32_LIBS
2392  { "POSIX_V6_ILP32_OFF32_LIBS", _CS_POSIX_V6_ILP32_OFF32_LIBS, CONFSTR },
2393 #endif
2394 #ifdef _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS
2395  { "POSIX_V6_ILP32_OFF32_LINTFLAGS", _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS, CONFSTR },
2396 #endif
2397 
2398 #ifdef _CS_V6_WIDTH_RESTRICTED_ENVS
2399  { "_POSIX_V6_WIDTH_RESTRICTED_ENVS", _CS_V6_WIDTH_RESTRICTED_ENVS, CONFSTR },
2400 #endif
2401 
2402 #ifdef _SC_V6_ILP32_OFFBIG
2403  { "_POSIX_V6_ILP32_OFFBIG", _SC_V6_ILP32_OFFBIG, SYSCONF },
2404 #endif
2405 #ifdef _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS
2406  { "POSIX_V6_ILP32_OFFBIG_CFLAGS", _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS, CONFSTR },
2407 #endif
2408 #ifdef _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS
2409  { "POSIX_V6_ILP32_OFFBIG_LDFLAGS", _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS, CONFSTR },
2410 #endif
2411 #ifdef _CS_POSIX_V6_ILP32_OFFBIG_LIBS
2412  { "POSIX_V6_ILP32_OFFBIG_LIBS", _CS_POSIX_V6_ILP32_OFFBIG_LIBS, CONFSTR },
2413 #endif
2414 #ifdef _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS
2415  { "POSIX_V6_ILP32_OFFBIG_LINTFLAGS", _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS, CONFSTR },
2416 #endif
2417 
2418 #ifdef _SC_V6_LP64_OFF64
2419  { "_POSIX_V6_LP64_OFF64", _SC_V6_LP64_OFF64, SYSCONF },
2420 #endif
2421 #ifdef _CS_POSIX_V6_LP64_OFF64_CFLAGS
2422  { "POSIX_V6_LP64_OFF64_CFLAGS", _CS_POSIX_V6_LP64_OFF64_CFLAGS, CONFSTR },
2423 #endif
2424 #ifdef _CS_POSIX_V6_LP64_OFF64_LDFLAGS
2425  { "POSIX_V6_LP64_OFF64_LDFLAGS", _CS_POSIX_V6_LP64_OFF64_LDFLAGS, CONFSTR },
2426 #endif
2427 #ifdef _CS_POSIX_V6_LP64_OFF64_LIBS
2428  { "POSIX_V6_LP64_OFF64_LIBS", _CS_POSIX_V6_LP64_OFF64_LIBS, CONFSTR },
2429 #endif
2430 #ifdef _CS_POSIX_V6_LP64_OFF64_LINTFLAGS
2431  { "POSIX_V6_LP64_OFF64_LINTFLAGS", _CS_POSIX_V6_LP64_OFF64_LINTFLAGS, CONFSTR },
2432 #endif
2433 
2434 #ifdef _SC_V6_LPBIG_OFFBIG
2435  { "_POSIX_V6_LPBIG_OFFBIG", _SC_V6_LPBIG_OFFBIG, SYSCONF },
2436 #endif
2437 #ifdef _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS
2438  { "POSIX_V6_LPBIG_OFFBIG_CFLAGS", _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS, CONFSTR },
2439 #endif
2440 #ifdef _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS
2441  { "POSIX_V6_LPBIG_OFFBIG_LDFLAGS", _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS, CONFSTR },
2442 #endif
2443 #ifdef _CS_POSIX_V6_LPBIG_OFFBIG_LIBS
2444  { "POSIX_V6_LPBIG_OFFBIG_LIBS", _CS_POSIX_V6_LPBIG_OFFBIG_LIBS, CONFSTR },
2445 #endif
2446 #ifdef _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS
2447  { "POSIX_V6_LPBIG_OFFBIG_LINTFLAGS", _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS, CONFSTR },
2448 #endif
2449 
2450 #ifdef _SC_ADVISORY_INFO
2451  { "_POSIX_ADVISORY_INFO", _SC_ADVISORY_INFO, SYSCONF },
2452 #endif
2453 #ifdef _SC_BARRIERS
2454  { "_POSIX_BARRIERS", _SC_BARRIERS, SYSCONF },
2455 #endif
2456 #ifdef _SC_BASE
2457  { "_POSIX_BASE", _SC_BASE, SYSCONF },
2458 #endif
2459 #ifdef _SC_C_LANG_SUPPORT
2460  { "_POSIX_C_LANG_SUPPORT", _SC_C_LANG_SUPPORT, SYSCONF },
2461 #endif
2462 #ifdef _SC_C_LANG_SUPPORT_R
2463  { "_POSIX_C_LANG_SUPPORT_R", _SC_C_LANG_SUPPORT_R, SYSCONF },
2464 #endif
2465 #ifdef _SC_CLOCK_SELECTION
2466  { "_POSIX_CLOCK_SELECTION", _SC_CLOCK_SELECTION, SYSCONF },
2467 #endif
2468 #ifdef _SC_CPUTIME
2469  { "_POSIX_CPUTIME", _SC_CPUTIME, SYSCONF },
2470 #endif
2471 #ifdef _SC_THREAD_CPUTIME
2472  { "_POSIX_THREAD_CPUTIME", _SC_THREAD_CPUTIME, SYSCONF },
2473 #endif
2474 #ifdef _SC_DEVICE_SPECIFIC
2475  { "_POSIX_DEVICE_SPECIFIC", _SC_DEVICE_SPECIFIC, SYSCONF },
2476 #endif
2477 #ifdef _SC_DEVICE_SPECIFIC_R
2478  { "_POSIX_DEVICE_SPECIFIC_R", _SC_DEVICE_SPECIFIC_R, SYSCONF },
2479 #endif
2480 #ifdef _SC_FD_MGMT
2481  { "_POSIX_FD_MGMT", _SC_FD_MGMT, SYSCONF },
2482 #endif
2483 #ifdef _SC_FIFO
2484  { "_POSIX_FIFO", _SC_FIFO, SYSCONF },
2485 #endif
2486 #ifdef _SC_PIPE
2487  { "_POSIX_PIPE", _SC_PIPE, SYSCONF },
2488 #endif
2489 #ifdef _SC_FILE_ATTRIBUTES
2490  { "_POSIX_FILE_ATTRIBUTES", _SC_FILE_ATTRIBUTES, SYSCONF },
2491 #endif
2492 #ifdef _SC_FILE_LOCKING
2493  { "_POSIX_FILE_LOCKING", _SC_FILE_LOCKING, SYSCONF },
2494 #endif
2495 #ifdef _SC_FILE_SYSTEM
2496  { "_POSIX_FILE_SYSTEM", _SC_FILE_SYSTEM, SYSCONF },
2497 #endif
2498 #ifdef _SC_MONOTONIC_CLOCK
2499  { "_POSIX_MONOTONIC_CLOCK", _SC_MONOTONIC_CLOCK, SYSCONF },
2500 #endif
2501 #ifdef _SC_MULTI_PROCESS
2502  { "_POSIX_MULTI_PROCESS", _SC_MULTI_PROCESS, SYSCONF },
2503 #endif
2504 #ifdef _SC_SINGLE_PROCESS
2505  { "_POSIX_SINGLE_PROCESS", _SC_SINGLE_PROCESS, SYSCONF },
2506 #endif
2507 #ifdef _SC_NETWORKING
2508  { "_POSIX_NETWORKING", _SC_NETWORKING, SYSCONF },
2509 #endif
2510 #ifdef _SC_READER_WRITER_LOCKS
2511  { "_POSIX_READER_WRITER_LOCKS", _SC_READER_WRITER_LOCKS, SYSCONF },
2512 #endif
2513 #ifdef _SC_SPIN_LOCKS
2514  { "_POSIX_SPIN_LOCKS", _SC_SPIN_LOCKS, SYSCONF },
2515 #endif
2516 #ifdef _SC_REGEXP
2517  { "_POSIX_REGEXP", _SC_REGEXP, SYSCONF },
2518 #endif
2519 #ifdef _SC_REGEX_VERSION
2520  { "_REGEX_VERSION", _SC_REGEX_VERSION, SYSCONF },
2521 #endif
2522 #ifdef _SC_SHELL
2523  { "_POSIX_SHELL", _SC_SHELL, SYSCONF },
2524 #endif
2525 #ifdef _SC_SIGNALS
2526  { "_POSIX_SIGNALS", _SC_SIGNALS, SYSCONF },
2527 #endif
2528 #ifdef _SC_SPAWN
2529  { "_POSIX_SPAWN", _SC_SPAWN, SYSCONF },
2530 #endif
2531 #ifdef _SC_SPORADIC_SERVER
2532  { "_POSIX_SPORADIC_SERVER", _SC_SPORADIC_SERVER, SYSCONF },
2533 #endif
2534 #ifdef _SC_THREAD_SPORADIC_SERVER
2535  { "_POSIX_THREAD_SPORADIC_SERVER", _SC_THREAD_SPORADIC_SERVER, SYSCONF },
2536 #endif
2537 #ifdef _SC_SYSTEM_DATABASE
2538  { "_POSIX_SYSTEM_DATABASE", _SC_SYSTEM_DATABASE, SYSCONF },
2539 #endif
2540 #ifdef _SC_SYSTEM_DATABASE_R
2541  { "_POSIX_SYSTEM_DATABASE_R", _SC_SYSTEM_DATABASE_R, SYSCONF },
2542 #endif
2543 #ifdef _SC_TIMEOUTS
2544  { "_POSIX_TIMEOUTS", _SC_TIMEOUTS, SYSCONF },
2545 #endif
2546 #ifdef _SC_TYPED_MEMORY_OBJECTS
2547  { "_POSIX_TYPED_MEMORY_OBJECTS", _SC_TYPED_MEMORY_OBJECTS, SYSCONF },
2548 #endif
2549 #ifdef _SC_USER_GROUPS
2550  { "_POSIX_USER_GROUPS", _SC_USER_GROUPS, SYSCONF },
2551 #endif
2552 #ifdef _SC_USER_GROUPS_R
2553  { "_POSIX_USER_GROUPS_R", _SC_USER_GROUPS_R, SYSCONF },
2554 #endif
2555 #ifdef _SC_2_PBS
2556  { "POSIX2_PBS", _SC_2_PBS, SYSCONF },
2557 #endif
2558 #ifdef _SC_2_PBS_ACCOUNTING
2559  { "POSIX2_PBS_ACCOUNTING", _SC_2_PBS_ACCOUNTING, SYSCONF },
2560 #endif
2561 #ifdef _SC_2_PBS_LOCATE
2562  { "POSIX2_PBS_LOCATE", _SC_2_PBS_LOCATE, SYSCONF },
2563 #endif
2564 #ifdef _SC_2_PBS_TRACK
2565  { "POSIX2_PBS_TRACK", _SC_2_PBS_TRACK, SYSCONF },
2566 #endif
2567 #ifdef _SC_2_PBS_MESSAGE
2568  { "POSIX2_PBS_MESSAGE", _SC_2_PBS_MESSAGE, SYSCONF },
2569 #endif
2570 #ifdef _SC_SYMLOOP_MAX
2571  { "SYMLOOP_MAX", _SC_SYMLOOP_MAX, SYSCONF },
2572 #endif
2573 #ifdef _SC_STREAM_MAX
2574  { "STREAM_MAX", _SC_STREAM_MAX, SYSCONF },
2575 #endif
2576 #ifdef _SC_AIO_LISTIO_MAX
2577  { "AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX, SYSCONF },
2578 #endif
2579 #ifdef _SC_AIO_MAX
2580  { "AIO_MAX", _SC_AIO_MAX, SYSCONF },
2581 #endif
2582 #ifdef _SC_AIO_PRIO_DELTA_MAX
2583  { "AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX, SYSCONF },
2584 #endif
2585 #ifdef _SC_DELAYTIMER_MAX
2586  { "DELAYTIMER_MAX", _SC_DELAYTIMER_MAX, SYSCONF },
2587 #endif
2588 #ifdef _SC_HOST_NAME_MAX
2589  { "HOST_NAME_MAX", _SC_HOST_NAME_MAX, SYSCONF },
2590 #endif
2591 #ifdef _SC_LOGIN_NAME_MAX
2592  { "LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX, SYSCONF },
2593 #endif
2594 #ifdef _SC_MQ_OPEN_MAX
2595  { "MQ_OPEN_MAX", _SC_MQ_OPEN_MAX, SYSCONF },
2596 #endif
2597 #ifdef _SC_MQ_PRIO_MAX
2598  { "MQ_PRIO_MAX", _SC_MQ_PRIO_MAX, SYSCONF },
2599 #endif
2600 #ifdef _SC_DEVICE_IO
2601  { "_POSIX_DEVICE_IO", _SC_DEVICE_IO, SYSCONF },
2602 #endif
2603 #ifdef _SC_TRACE
2604  { "_POSIX_TRACE", _SC_TRACE, SYSCONF },
2605 #endif
2606 #ifdef _SC_TRACE_EVENT_FILTER
2607  { "_POSIX_TRACE_EVENT_FILTER", _SC_TRACE_EVENT_FILTER, SYSCONF },
2608 #endif
2609 #ifdef _SC_TRACE_INHERIT
2610  { "_POSIX_TRACE_INHERIT", _SC_TRACE_INHERIT, SYSCONF },
2611 #endif
2612 #ifdef _SC_TRACE_LOG
2613  { "_POSIX_TRACE_LOG", _SC_TRACE_LOG, SYSCONF },
2614 #endif
2615 #ifdef _SC_RTSIG_MAX
2616  { "RTSIG_MAX", _SC_RTSIG_MAX, SYSCONF },
2617 #endif
2618 #ifdef _SC_SEM_NSEMS_MAX
2619  { "SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX, SYSCONF },
2620 #endif
2621 #ifdef _SC_SEM_VALUE_MAX
2622  { "SEM_VALUE_MAX", _SC_SEM_VALUE_MAX, SYSCONF },
2623 #endif
2624 #ifdef _SC_SIGQUEUE_MAX
2625  { "SIGQUEUE_MAX", _SC_SIGQUEUE_MAX, SYSCONF },
2626 #endif
2627 #ifdef _PC_FILESIZEBITS
2628  { "FILESIZEBITS", _PC_FILESIZEBITS, PATHCONF },
2629 #endif
2630 #ifdef _PC_ALLOC_SIZE_MIN
2631  { "POSIX_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN, PATHCONF },
2632 #endif
2633 #ifdef _PC_REC_INCR_XFER_SIZE
2634  { "POSIX_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE, PATHCONF },
2635 #endif
2636 #ifdef _PC_REC_MAX_XFER_SIZE
2637  { "POSIX_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE, PATHCONF },
2638 #endif
2639 #ifdef _PC_REC_MIN_XFER_SIZE
2640  { "POSIX_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE, PATHCONF },
2641 #endif
2642 #ifdef _PC_REC_XFER_ALIGN
2643  { "POSIX_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN, PATHCONF },
2644 #endif
2645 #ifdef _PC_SYMLINK_MAX
2646  { "SYMLINK_MAX", _PC_SYMLINK_MAX, PATHCONF },
2647 #endif
2648 #ifdef _CS_GNU_LIBC_VERSION
2649  { "GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION, CONFSTR },
2650 #endif
2651 #ifdef _CS_GNU_LIBPTHREAD_VERSION
2652  { "GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION, CONFSTR },
2653 #endif
2654 #ifdef _PC_2_SYMLINKS
2655  { "POSIX2_SYMLINKS", _PC_2_SYMLINKS, PATHCONF },
2656 #endif
2657 
2658 #ifdef _SC_LEVEL1_ICACHE_SIZE
2659  { "LEVEL1_ICACHE_SIZE", _SC_LEVEL1_ICACHE_SIZE, SYSCONF },
2660 #endif
2661 #ifdef _SC_LEVEL1_ICACHE_ASSOC
2662  { "LEVEL1_ICACHE_ASSOC", _SC_LEVEL1_ICACHE_ASSOC, SYSCONF },
2663 #endif
2664 #ifdef _SC_LEVEL1_ICACHE_LINESIZE
2665  { "LEVEL1_ICACHE_LINESIZE", _SC_LEVEL1_ICACHE_LINESIZE, SYSCONF },
2666 #endif
2667 #ifdef _SC_LEVEL1_DCACHE_SIZE
2668  { "LEVEL1_DCACHE_SIZE", _SC_LEVEL1_DCACHE_SIZE, SYSCONF },
2669 #endif
2670 #ifdef _SC_LEVEL1_DCACHE_ASSOC
2671  { "LEVEL1_DCACHE_ASSOC", _SC_LEVEL1_DCACHE_ASSOC, SYSCONF },
2672 #endif
2673 #ifdef _SC_LEVEL1_DCACHE_LINESIZE
2674  { "LEVEL1_DCACHE_LINESIZE", _SC_LEVEL1_DCACHE_LINESIZE, SYSCONF },
2675 #endif
2676 #ifdef _SC_LEVEL2_CACHE_SIZE
2677  { "LEVEL2_CACHE_SIZE", _SC_LEVEL2_CACHE_SIZE, SYSCONF },
2678 #endif
2679 #ifdef _SC_LEVEL2_CACHE_ASSOC
2680  { "LEVEL2_CACHE_ASSOC", _SC_LEVEL2_CACHE_ASSOC, SYSCONF },
2681 #endif
2682 #ifdef _SC_LEVEL2_CACHE_LINESIZE
2683  { "LEVEL2_CACHE_LINESIZE", _SC_LEVEL2_CACHE_LINESIZE, SYSCONF },
2684 #endif
2685 #ifdef _SC_LEVEL3_CACHE_SIZE
2686  { "LEVEL3_CACHE_SIZE", _SC_LEVEL3_CACHE_SIZE, SYSCONF },
2687 #endif
2688 #ifdef _SC_LEVEL3_CACHE_ASSOC
2689  { "LEVEL3_CACHE_ASSOC", _SC_LEVEL3_CACHE_ASSOC, SYSCONF },
2690 #endif
2691 #ifdef _SC_LEVEL3_CACHE_LINESIZE
2692  { "LEVEL3_CACHE_LINESIZE", _SC_LEVEL3_CACHE_LINESIZE, SYSCONF },
2693 #endif
2694 #ifdef _SC_LEVEL4_CACHE_SIZE
2695  { "LEVEL4_CACHE_SIZE", _SC_LEVEL4_CACHE_SIZE, SYSCONF },
2696 #endif
2697 #ifdef _SC_LEVEL4_CACHE_ASSOC
2698  { "LEVEL4_CACHE_ASSOC", _SC_LEVEL4_CACHE_ASSOC, SYSCONF },
2699 #endif
2700 
2701 #ifdef _SC_IPV6
2702  { "IPV6", _SC_IPV6, SYSCONF },
2703 #endif
2704 #ifdef _SC_RAW_SOCKETS
2705  { "RAW_SOCKETS", _SC_RAW_SOCKETS, SYSCONF },
2706 #endif
2707 
2708  { NULL, 0, SYSCONF }
2709 };
2710 
2711 #define _GETCONF_PATH "/"
2712 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
2713 static const char *_getconf_path = NULL;
2714 
2715 int
2716 rpmdsGetconf(rpmds * dsp, const char *path)
2717  /*@globals _getconf_path @*/
2718  /*@modifies _getconf_path @*/
2719 {
2720  const struct _conf_s *c;
2721  size_t clen;
2722  long int value;
2723  const char * NS = "getconf";
2724  const char *N;
2725  char * EVR;
2726  char * t;
2727  evrFlags Flags;
2728 
2729 /*@-modobserver@*/
2730  if (_getconf_path == NULL) {
2731  _getconf_path = rpmExpand("%{?_rpmds__getconf_path}", NULL);
2732  /* XXX may need to validate path existence somewhen. */
2733  if (!(_getconf_path != NULL && *_getconf_path == '/')) {
2734 /*@-observertrans @*/
2735  _getconf_path = _free(_getconf_path);
2736 /*@=observertrans @*/
2737  _getconf_path = xstrdup(_GETCONF_PATH);
2738  }
2739  }
2740 /*@=modobserver@*/
2741 
2742  if (path == NULL)
2743  path = _getconf_path;
2744 
2745  for (c = vars; c->name != NULL; ++c) {
2746  N = c->name;
2747  EVR = NULL;
2748  switch (c->call) {
2749  case PATHCONF:
2750  value = pathconf(path, c->call_name);
2751  if (value != -1) {
2752  EVR = (char *) xmalloc(32);
2753  sprintf(EVR, "%ld", value);
2754  }
2755  /*@switchbreak@*/ break;
2756  case SYSCONF:
2757  value = sysconf(c->call_name);
2758  if (value == -1l) {
2759 #if defined(_SC_UINT_MAX) && defined(_SC_ULONG_MAX)
2760 /*@-unrecog@*/
2761  if (c->call_name == _SC_UINT_MAX
2762  || c->call_name == _SC_ULONG_MAX) {
2763  EVR = (char *) xmalloc(32);
2764  sprintf(EVR, "%lu", value);
2765  }
2766 /*@=unrecog@*/
2767 #endif
2768  } else {
2769  EVR = (char *) xmalloc(32);
2770  sprintf(EVR, "%ld", value);
2771  }
2772  /*@switchbreak@*/ break;
2773  case CONFSTR:
2774 #ifndef __CYGWIN__
2775  clen = confstr(c->call_name, (char *) NULL, 0);
2776  EVR = (char *) xmalloc(clen+1);
2777  *EVR = '\0';
2778  if (confstr (c->call_name, EVR, clen) != clen) {
2779  fprintf(stderr, "confstr: %s\n", strerror(errno));
2780  exit (EXIT_FAILURE);
2781  }
2782  EVR[clen] = '\0';
2783 #endif
2784  /*@switchbreak@*/ break;
2785  }
2786  if (EVR == NULL)
2787  continue;
2788 
2789  for (t = EVR; *t; t++) {
2790  if (*t == '\n') *t = ' ';
2791  }
2792  if (!strcmp(N, "GNU_LIBC_VERSION")
2793  || !strcmp(N, "GNU_LIBPTHREAD_VERSION"))
2794  {
2795  for (t = EVR; *t; t++) {
2796  if (*t == ' ') *t = '-';
2797  }
2798  }
2799 
2800  if (*EVR == '\0' || strchr(EVR, ' ') != NULL
2801  || (EVR[0] == '-' && strchr("0123456789", EVR[1]) == NULL))
2802  {
2803  EVR = _free(EVR);
2804  continue;
2805  }
2806 
2807  Flags = (evrFlags) (RPMSENSE_PROBE|RPMSENSE_EQUAL);
2808  rpmdsNSAdd(dsp, NS, N, EVR, Flags);
2809  EVR = _free(EVR);
2810  }
2811  return 0;
2812 }
2813 
2814 int rpmdsMergePRCO(void * context, rpmds ds)
2815 {
2816  rpmPRCO PRCO = (rpmPRCO) context;
2817  int rc = -1;
2818 
2819 /*@-modfilesys@*/
2820 if (_rpmds_debug < 0)
2821 fprintf(stderr, "*** rpmdsMergePRCO(%p, %p) %s\n", context, ds, rpmdsTagName(rpmdsTagN(ds)));
2822 /*@=modfilesys@*/
2823  switch(rpmdsTagN(ds)) {
2824  default:
2825  break;
2826  case RPMTAG_PROVIDENAME:
2827  rc = rpmdsMerge(PRCO->Pdsp, ds);
2828  break;
2829  case RPMTAG_REQUIRENAME:
2830  rc = rpmdsMerge(PRCO->Rdsp, ds);
2831  break;
2832  case RPMTAG_CONFLICTNAME:
2833  rc = rpmdsMerge(PRCO->Cdsp, ds);
2834  break;
2835  case RPMTAG_OBSOLETENAME:
2836  rc = rpmdsMerge(PRCO->Odsp, ds);
2837  break;
2838  case RPMTAG_TRIGGERNAME:
2839  rc = rpmdsMerge(PRCO->Tdsp, ds);
2840  break;
2841  case RPMTAG_DIRNAMES:
2842  rc = rpmdsMerge(PRCO->Ddsp, ds);
2843  break;
2844  case RPMTAG_FILELINKTOS:
2845  rc = rpmdsMerge(PRCO->Ldsp, ds);
2846  break;
2847  }
2848  return rc;
2849 }
2850 
2852 {
2853  if (PRCO) {
2854  (void)rpmdsFree(PRCO->my);
2855  PRCO->my = NULL;
2856  (void)rpmdsFree(PRCO->P);
2857  PRCO->P = NULL;
2858  (void)rpmdsFree(PRCO->R);
2859  PRCO->R = NULL;
2860  (void)rpmdsFree(PRCO->C);
2861  PRCO->C = NULL;
2862  (void)rpmdsFree(PRCO->O);
2863  PRCO->O = NULL;
2864  (void)rpmdsFree(PRCO->T);
2865  PRCO->T = NULL;
2866  (void)rpmdsFree(PRCO->D);
2867  PRCO->D = NULL;
2868  (void)rpmdsFree(PRCO->L);
2869  PRCO->L = NULL;
2870  memset(PRCO, 0, sizeof(*PRCO));
2871  PRCO = _free(PRCO);
2872  }
2873  return NULL;
2874 }
2875 
2877 {
2878  rpmPRCO PRCO = (rpmPRCO) xcalloc(1, sizeof(*PRCO));
2879 
2880  if (h != NULL) {
2881  static int scareMem = 0;
2882  PRCO->my = rpmdsNew(h, RPMTAG_NAME, scareMem);
2883  PRCO->P = rpmdsNew(h, RPMTAG_PROVIDENAME, scareMem);
2884  PRCO->R = rpmdsNew(h, RPMTAG_REQUIRENAME, scareMem);
2885  PRCO->C = rpmdsNew(h, RPMTAG_CONFLICTNAME, scareMem);
2886  PRCO->O = rpmdsNew(h, RPMTAG_OBSOLETENAME, scareMem);
2887  PRCO->T = rpmdsNew(h, RPMTAG_TRIGGERNAME, scareMem);
2888  PRCO->D = rpmdsNew(h, RPMTAG_DIRNAMES, scareMem);
2889  PRCO->L = rpmdsNew(h, RPMTAG_FILELINKTOS, scareMem);
2890  }
2891  PRCO->Pdsp = &PRCO->P;
2892  PRCO->Rdsp = &PRCO->R;
2893  PRCO->Cdsp = &PRCO->C;
2894  PRCO->Odsp = &PRCO->O;
2895  PRCO->Tdsp = &PRCO->T;
2896  PRCO->Ddsp = &PRCO->D;
2897  PRCO->Ldsp = &PRCO->L;
2898  return PRCO;
2899 }
2900 
2902 {
2903  /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
2904  if (PRCO != NULL)
2905  switch (tagN) {
2906  default: break;
2907  case RPMTAG_NAME: return PRCO->my; /*@notreached@*/ break;
2908  case RPMTAG_PROVIDENAME: return *PRCO->Pdsp; /*@notreached@*/ break;
2909  case RPMTAG_REQUIRENAME: return *PRCO->Rdsp; /*@notreached@*/ break;
2910  case RPMTAG_CONFLICTNAME: return *PRCO->Cdsp; /*@notreached@*/ break;
2911  case RPMTAG_OBSOLETENAME: return *PRCO->Odsp; /*@notreached@*/ break;
2912  case RPMTAG_TRIGGERNAME: return *PRCO->Tdsp; /*@notreached@*/ break;
2913  case RPMTAG_DIRNAMES: return *PRCO->Ddsp; /*@notreached@*/ break;
2914  case RPMTAG_FILELINKTOS: return *PRCO->Ldsp; /*@notreached@*/ break;
2915  }
2916  return NULL;
2917  /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
2918 }
2919 
2927 #if defined(HAVE_GELF_H) && defined(HAVE_LIBELF) && !defined(__FreeBSD__)
2928 static char * sonameDep(/*@returned@*/ char * t, const char * s, int isElf64, int isX32)
2929  /*@modifies t @*/
2930 {
2931  *t = '\0';
2932 #if !defined(__alpha__) && !defined(__sun)
2933  if (isElf64) {
2934  if (s[strlen(s)-1] != ')')
2935  (void) stpcpy( stpcpy(t, s), "()(64bit)");
2936  else
2937  (void) stpcpy( stpcpy(t, s), "(64bit)");
2938  }else
2939  if (isX32) {
2940  if (s[strlen(s)-1] != ')')
2941  (void) stpcpy( stpcpy(t, s), "()(x32bit)");
2942  else
2943  (void) stpcpy( stpcpy(t, s), "(x32bit)");
2944  } else
2945 #endif
2946  (void) stpcpy(t, s);
2947  return t;
2948 }
2949 #endif
2950 
2951 /*@-moduncon -noeffectuncon @*/
2952 int rpmdsELF(const char * fn, int flags,
2953  int (*add) (void * context, rpmds ds), void * context)
2954 {
2955 #if defined(HAVE_GELF_H) && defined(HAVE_LIBELF) && !defined(__FreeBSD__)
2956  Elf * elf;
2957  Elf_Scn * scn;
2958  Elf_Data * data;
2959  GElf_Ehdr ehdr_mem, * ehdr;
2960  GElf_Shdr shdr_mem, * shdr;
2961  GElf_Verdef def_mem, * def;
2962  GElf_Verneed need_mem, * need;
2963  GElf_Dyn dyn_mem, * dyn;
2964  unsigned int auxoffset;
2965  unsigned int offset;
2966  int fdno;
2967  int cnt2;
2968  int cnt;
2969  char buf[BUFSIZ];
2970  const char * s;
2971  int is_executable;
2972  const char * soname = NULL;
2973  rpmds ds;
2974  char * t;
2975  int xx;
2976  int isElf64;
2977  int isX32;
2978  int isDSO;
2979  int gotSONAME = 0;
2980  int gotDEBUG = 0;
2981  int gotHASH = 0;
2982  int gotGNUHASH = 0;
2983  int skipP = (flags & RPMELF_FLAG_SKIPPROVIDES);
2984  int skipR = (flags & RPMELF_FLAG_SKIPREQUIRES);
2985  static int filter_GLIBC_PRIVATE = 0;
2986  static int oneshot = 0;
2987 
2988 /*@-castfcnptr@*/
2989 if (_rpmds_debug < 0)
2990 fprintf(stderr, "*** rpmdsELF(%s, %d, %p, %p)\n", fn, flags, (void *)add, context);
2991 /*@=castfcnptr@*/
2992  if (oneshot == 0) {
2993  oneshot = 1;
2994  filter_GLIBC_PRIVATE = rpmExpandNumeric("%{?_filter_GLIBC_PRIVATE}");
2995  }
2996 
2997  /* Extract dependencies only from files with executable bit set. */
2998  { struct stat sb, * st = &sb;
2999  if (stat(fn, st) != 0)
3000  return -1;
3001  is_executable = (int)(st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH));
3002  }
3003 
3004  fdno = open(fn, O_RDONLY);
3005  if (fdno < 0)
3006  return fdno;
3007 
3008  (void) elf_version(EV_CURRENT);
3009 
3010 /*@-evalorder@*/
3011  elf = NULL;
3012  if ((elf = elf_begin (fdno, ELF_C_READ, NULL)) == NULL
3013  || elf_kind(elf) != ELF_K_ELF
3014  || (ehdr = gelf_getehdr(elf, &ehdr_mem)) == NULL
3015  || !(ehdr->e_type == ET_DYN || ehdr->e_type == ET_EXEC))
3016  goto exit;
3017 /*@=evalorder@*/
3018 
3019  isElf64 = ehdr->e_ident[EI_CLASS] == ELFCLASS64;
3020  isX32 = (ehdr->e_ident[EI_CLASS] == ELFCLASS32) && (ehdr->e_machine == EM_X86_64);
3021  isDSO = ehdr->e_type == ET_DYN;
3022 
3023  /*@-uniondef @*/
3024  scn = NULL;
3025  while ((scn = elf_nextscn(elf, scn)) != NULL) {
3026  shdr = gelf_getshdr(scn, &shdr_mem);
3027  if (shdr == NULL)
3028  break;
3029 
3030  soname = _free(soname);
3031  switch (shdr->sh_type) {
3032  default:
3033  continue;
3034  /*@notreached@*/ /*@switchbreak@*/ break;
3035  case SHT_NOTE:
3036 #if defined(HAVE_GELF_GETNOTE) /* XXX OpenIndiana & older elfutils haven't. */
3037  if (!(shdr->sh_flags & SHF_ALLOC))
3038  continue;
3039  data = NULL;
3040  while ((data = elf_getdata(scn, data)) != NULL) {
3041  GElf_Nhdr nhdr;
3042  size_t name_offset;
3043  size_t desc_offset;
3044  offset = 0;
3045  while (offset < data->d_size
3046  && (offset = gelf_getnote(data, offset,
3047  &nhdr, &name_offset, &desc_offset)) > 0)
3048  {
3049  const char *name = ((char *)data->d_buf) + name_offset;
3050  const char *desc = ((char *)data->d_buf) + desc_offset;
3051  if (memchr(name, '\0', nhdr.n_namesz) == NULL)
3052  /*@innercontinue@*/ continue;
3053  switch (nhdr.n_type) {
3054  default: /*@innercontinue@*/ continue;
3055 #if !defined(NT_GNU_BUILD_ID)
3056 #define NT_GNU_BUILD_ID 3
3057 #endif
3058  case NT_GNU_BUILD_ID:
3059  if (strcmp(name, "GNU") == 0 && nhdr.n_descsz > 0) {
3060  static const char hex[] = "0123456789abcdef";
3061  static evrFlags _Flags = (evrFlags)
3062  (RPMSENSE_EQUAL|RPMSENSE_FIND_PROVIDES);
3063  size_t i;
3064  buf[0] = '\0';
3065  t = buf;
3066  for (i = 0; i < nhdr.n_descsz; ++i) {
3067  *t++ = hex[ (((unsigned)desc[i] >> 4) & 0x0f) ];
3068  *t++ = hex[ (((unsigned)desc[i] ) & 0x0f) ];
3069  }
3070  *t = '\0';
3071  /* Add next buildid. */
3072  ds = rpmdsSingle(RPMTAG_PROVIDES, "elf(buildid)",
3073  buf, _Flags);
3074  xx = add(context, ds);
3075  (void)rpmdsFree(ds);
3076  ds = NULL;
3077  }
3078  /*@switchbreak@*/ break;
3079  }
3080  }
3081  }
3082 #endif /* defined(HAVE_GELF_GETNOTE) */
3083  /*@switchbreak@*/ break;
3084  case SHT_GNU_verdef:
3085  data = NULL;
3086  if (!skipP)
3087  while ((data = elf_getdata (scn, data)) != NULL) {
3088  offset = 0;
3089  for (cnt = (int)shdr->sh_info; --cnt >= 0; ) {
3090 
3091  def = gelf_getverdef (data, offset, &def_mem);
3092  if (def == NULL)
3093  /*@innerbreak@*/ break;
3094  auxoffset = (unsigned)(offset + def->vd_aux);
3095  for (cnt2 = (int)def->vd_cnt; --cnt2 >= 0; ) {
3096  GElf_Verdaux aux_mem, * aux;
3097 
3098  aux = gelf_getverdaux (data, auxoffset, &aux_mem);
3099  if (aux == NULL)
3100  /*@innerbreak@*/ break;
3101 
3102  s = elf_strptr(elf, shdr->sh_link, aux->vda_name);
3103  if (s == NULL)
3104  /*@innerbreak@*/ break;
3105 
3106  if (def->vd_flags & VER_FLG_BASE) {
3107  soname = _free(soname);
3108  soname = xstrdup(s);
3109  } else
3110  if (soname != NULL
3111  && !(filter_GLIBC_PRIVATE != 0
3112  && !strcmp(s, "GLIBC_PRIVATE")))
3113  {
3114  buf[0] = '\0';
3115  t = buf;
3116  t = stpcpy( stpcpy( stpcpy( stpcpy(t, soname), "("), s), ")");
3117 
3118  t++; /* XXX "foo(bar)" already in buf. */
3119 
3120  /* Add next provide dependency. */
3122  sonameDep(t, buf, isElf64, isX32),
3123  "", RPMSENSE_FIND_PROVIDES);
3124  xx = add(context, ds);
3125  (void)rpmdsFree(ds);
3126  ds = NULL;
3127  }
3128  auxoffset += aux->vda_next;
3129  }
3130  offset += def->vd_next;
3131  }
3132  }
3133  /*@switchbreak@*/ break;
3134  case SHT_GNU_verneed:
3135  data = NULL;
3136  /* Only from files with executable bit set. */
3137  if (!skipR && is_executable)
3138  while ((data = elf_getdata (scn, data)) != NULL) {
3139  offset = 0;
3140  for (cnt = (int)shdr->sh_info; --cnt >= 0; ) {
3141  need = gelf_getverneed (data, offset, &need_mem);
3142  if (need == NULL)
3143  /*@innerbreak@*/ break;
3144 
3145  s = elf_strptr(elf, shdr->sh_link, need->vn_file);
3146  if (s == NULL)
3147  /*@innerbreak@*/ break;
3148  soname = _free(soname);
3149  soname = xstrdup(s);
3150  auxoffset = (unsigned)(offset + need->vn_aux);
3151  for (cnt2 = (int)need->vn_cnt; --cnt2 >= 0; ) {
3152  GElf_Vernaux aux_mem, * aux;
3153 
3154  aux = gelf_getvernaux (data, auxoffset, &aux_mem);
3155  if (aux == NULL)
3156  /*@innerbreak@*/ break;
3157 
3158  s = elf_strptr(elf, shdr->sh_link, aux->vna_name);
3159  if (s == NULL)
3160  /*@innerbreak@*/ break;
3161 
3162  /* Filter dependencies that contain GLIBC_PRIVATE */
3163  if (soname != NULL
3164  && !(filter_GLIBC_PRIVATE != 0
3165  && !strcmp(s, "GLIBC_PRIVATE")))
3166  {
3167  buf[0] = '\0';
3168  t = buf;
3169  t = stpcpy( stpcpy( stpcpy( stpcpy(t, soname), "("), s), ")");
3170 
3171  t++; /* XXX "foo(bar)" already in buf. */
3172 
3173  /* Add next require dependency. */
3175  sonameDep(t, buf, isElf64, isX32),
3176  "", RPMSENSE_FIND_REQUIRES);
3177  xx = add(context, ds);
3178  (void)rpmdsFree(ds);
3179  ds = NULL;
3180  }
3181  auxoffset += aux->vna_next;
3182  }
3183  offset += need->vn_next;
3184  }
3185  }
3186  /*@switchbreak@*/ break;
3187  case SHT_DYNAMIC:
3188  data = NULL;
3189  while ((data = elf_getdata (scn, data)) != NULL) {
3190  for (cnt = 0; cnt < (int)(shdr->sh_size / shdr->sh_entsize); ++cnt) {
3191  dyn = gelf_getdyn (data, cnt, &dyn_mem);
3192  if (dyn == NULL)
3193  /*@innerbreak@*/ break;
3194  s = NULL;
3195  switch (dyn->d_tag) {
3196  default:
3197  /*@innercontinue@*/ continue;
3198  /*@notreached@*/ /*@switchbreak@*/ break;
3199  case DT_HASH:
3200  gotHASH= 1;
3201  /*@innercontinue@*/ continue;
3202  case DT_GNU_HASH:
3203  gotGNUHASH= 1;
3204  /*@innercontinue@*/ continue;
3205  case DT_DEBUG:
3206  gotDEBUG = 1;
3207  /*@innercontinue@*/ continue;
3208  case DT_NEEDED:
3209  /* Only from files with executable bit set. */
3210  if (skipR || !is_executable)
3211  /*@innercontinue@*/ continue;
3212  /* Add next require dependency. */
3213  s = elf_strptr(elf, shdr->sh_link, dyn->d_un.d_val);
3214 assert(s != NULL);
3215  buf[0] = '\0';
3217  sonameDep(buf, s, isElf64, isX32),
3218  "", RPMSENSE_FIND_REQUIRES);
3219  xx = add(context, ds);
3220  (void)rpmdsFree(ds);
3221  ds = NULL;
3222  /*@switchbreak@*/ break;
3223  case DT_SONAME:
3224  gotSONAME = 1;
3225  if (skipP)
3226  /*@innercontinue@*/ continue;
3227  s = elf_strptr(elf, shdr->sh_link, dyn->d_un.d_val);
3228 assert(s != NULL);
3229  /* Add next provide dependency. */
3230  buf[0] = '\0';
3232  sonameDep(buf, s, isElf64, isX32),
3233  "", RPMSENSE_FIND_PROVIDES);
3234  xx = add(context, ds);
3235  (void)rpmdsFree(ds);
3236  ds = NULL;
3237  /*@switchbreak@*/ break;
3238  }
3239  }
3240  }
3241  /*@switchbreak@*/ break;
3242  }
3243  }
3244  /*@=uniondef @*/
3245 
3246  /* For DSOs which use the .gnu_hash section and don't have a .hash
3247  * section, we need to ensure that we have a new enough glibc. */
3248  if (gotGNUHASH && !gotHASH) {
3249  ds = rpmdsSingle(RPMTAG_REQUIRENAME, "rtld(GNU_HASH)", "",
3250  RPMSENSE_FIND_REQUIRES);
3251  xx = add(context, ds);
3252  (void)rpmdsFree(ds);
3253  ds = NULL;
3254  }
3255 
3256  /* For DSO's, provide the basename of the file if DT_SONAME not found. */
3257  if (!skipP && isDSO && !gotDEBUG && !gotSONAME) {
3258  s = strrchr(fn, '/');
3259  if (s != NULL)
3260  s++;
3261  else
3262  s = fn;
3263 assert(s != NULL);
3264 
3265  /* Add next provide dependency. */
3266  buf[0] = '\0';
3268  sonameDep(buf, s, isElf64, isX32), "", RPMSENSE_FIND_PROVIDES);
3269  xx = add(context, ds);
3270  (void)rpmdsFree(ds);
3271  ds = NULL;
3272  }
3273 
3274 exit:
3275  soname = _free(soname);
3276  if (elf) (void) elf_end(elf);
3277  if (fdno >= 0)
3278  xx = close(fdno);
3279  return 0;
3280 #else
3281  return -1;
3282 #endif
3283 }
3284 /*@=moduncon =noeffectuncon @*/
3285 
3286 
3287 #if defined(RPM_VENDOR_MANDRIVA)
3288 
3294 #if defined(HAVE_GELF_H) && defined(HAVE_LIBELF) && !defined(__FreeBSD__)
3295 static char * mdvSonameDep(/*@returned@*/ char * t, const char * s, int isElf64, int devel)
3296  /*@modifies t @*/
3297 {
3298  char *tmp = t;
3299  *t = '\0';
3300  if (devel) {
3301  tmp = stpcpy(t, "devel(");
3302  }
3303 #if !defined(__alpha__) && !defined(__sun)
3304  if (!isElf64) {
3305  /* XXX: eehhk, would've been nice with consistency, mandriva legacy... :| */
3306  if (!devel && s[strlen(s)-1] != ')')
3307  (void) stpcpy( stpcpy(tmp, s), "()(64bit)");
3308  else {
3309  tmp = stpcpy(tmp, s);
3310  if (devel)
3311  tmp = strstr(t, ".so");
3312  tmp = stpcpy(tmp, "(64bit)");
3313  }
3314  }else
3315 #endif
3316  tmp = stpcpy(tmp, s);
3317  if (devel) {
3318  char *suffix = strstr(t, ".so");
3319  if (suffix)
3320  tmp = suffix;
3321  tmp = stpcpy(tmp, ")");
3322  }
3323 
3324  return t;
3325 }
3326 #endif
3327 
3337 int rpmdsSymlink(const char * fn, int flags,
3338  int (*add) (void * context, rpmds ds), void * context)
3339  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
3340  /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/;
3341 int rpmdsSymlink(const char * fn, int flags,
3342  int (*add) (void * context, rpmds ds), void * context)
3343 {
3344 #if defined(HAVE_GELF_H) && defined(HAVE_LIBELF) && !defined(__FreeBSD__)
3345  Elf * elf;
3346  Elf_Scn * scn;
3347  Elf_Data * data;
3348  GElf_Ehdr ehdr_mem, * ehdr;
3349  GElf_Shdr shdr_mem, * shdr;
3350  GElf_Dyn dyn_mem, * dyn;
3351  int fdno;
3352  int cnt;
3353  int i;
3354  char buf[BUFSIZ];
3355  const char * s;
3356  int is_executable;
3357  const char * soname = NULL;
3358  rpmds ds;
3359  int xx;
3360  int isElf64;
3361  int gotSONAME = 0;
3362  int skipP = (flags & RPMELF_FLAG_SKIPPROVIDES);
3363  int skipR = (flags & RPMELF_FLAG_SKIPREQUIRES);
3364  int lnklen;
3365  char path[MAXPATHLEN];
3366  /*
3367  * We filter out these as they come with glibc, making dependencies on
3368  * them rather redundant.
3369  */
3370  const char *filterRequires[] = {"ld-linux", "ld64-linux" "libBrokenLocale.so",
3371  "libanl.so", "libc.so", "libcidn.so", "libcrypt.so", "libdl.so", "libm.so",
3372  "libnsl.so", "libnss_compat.so", "libnss_dns.so", "libnss_files.so",
3373  "libnss_hesiod.so", "libnss_nis.so", "libnss_nisplus.so", "libpthread.so",
3374  "libresolv.so", "librt.so", "libutil.so", "libthread_db.so"};
3375  ARGV_t deps = NULL;
3376 
3377  /* Filename must end with ".so" to be devel(...) dependency. */
3378  if ((s = strrchr(fn, '.')) && strcmp(s, ".so"))
3379  return 0;
3380 
3381  if ((lnklen = readlink(fn, path, MAXPATHLEN - 1)) == -1) {
3382  warn("%s", fn);
3383  return -1;
3384  }
3385  path[lnklen] = '\0';
3386 
3387 /*@-castfcnptr@*/
3388 if (_rpmds_debug < 0)
3389 fprintf(stderr, "*** rpmdsELF(%s, %d, %p, %p)\n", fn, flags, (void *)add, context);
3390 /*@=castfcnptr@*/
3391 
3392  /* Extract dependencies only from files with executable bit set. */
3393  { struct stat sb, * st = &sb;
3394  if (lstat(fn, st) != 0)
3395  return -1;
3396  is_executable = (int)(st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH));
3397  }
3398 
3399  fdno = open(fn, O_RDONLY);
3400  if (fdno < 0)
3401  return fdno;
3402 
3403  (void) elf_version(EV_CURRENT);
3404 
3405 /*@-evalorder@*/
3406  elf = NULL;
3407  if ((elf = elf_begin (fdno, ELF_C_READ, NULL)) == NULL
3408  || elf_kind(elf) != ELF_K_ELF
3409  || (ehdr = gelf_getehdr(elf, &ehdr_mem)) == NULL
3410  || !(ehdr->e_type == ET_DYN || ehdr->e_type == ET_EXEC))
3411  goto exit;
3412 /*@=evalorder@*/
3413 
3414  isElf64 = ehdr->e_ident[EI_CLASS] == ELFCLASS64;
3415 
3416  /*@-uniondef @*/
3417  scn = NULL;
3418  while ((scn = elf_nextscn(elf, scn)) != NULL) {
3419  shdr = gelf_getshdr(scn, &shdr_mem);
3420  if (shdr == NULL)
3421  break;
3422 
3423  soname = _free(soname);
3424  switch (shdr->sh_type) {
3425  default:
3426  continue;
3427  /*@notreached@*/ /*@switchbreak@*/ break;
3428  case SHT_DYNAMIC:
3429  data = NULL;
3430  while ((data = elf_getdata (scn, data)) != NULL) {
3431  for (cnt = 0; cnt < (int)(shdr->sh_size / shdr->sh_entsize); ++cnt) {
3432  dyn = gelf_getdyn (data, cnt, &dyn_mem);
3433  if (dyn == NULL)
3434  /*@innerbreak@*/ break;
3435  s = NULL;
3436  switch (dyn->d_tag) {
3437  default:
3438  /*@innercontinue@*/ continue;
3439  /*@notreached@*/ /*@switchbreak@*/ break;
3440  case DT_NEEDED:
3441  /* Only from files with executable bit set. */
3442  if (skipR || !is_executable)
3443  /*@innercontinue@*/ continue;
3444  /* Add next require dependency. */
3445  s = elf_strptr(elf, shdr->sh_link, dyn->d_un.d_val);
3446 assert(s != NULL);
3447  buf[0] = '\0';
3448 
3449  for (i = 0; i < (int)(sizeof(filterRequires)/sizeof(filterRequires[0])); i++)
3450  if (!strncmp(s, filterRequires[i], strlen(filterRequires[i])))
3451  break;
3452 
3453  if (sizeof(filterRequires)/sizeof(filterRequires[0]) == i)
3454  argvAdd(&deps, s);
3455  /*@switchbreak@*/ break;
3456  case DT_SONAME:
3457  gotSONAME = 1;
3458  s = elf_strptr(elf, shdr->sh_link, dyn->d_un.d_val);
3459 assert(s != NULL);
3460  /* Add next provide dependency. */
3461  buf[0] = '\0';
3462 
3463  if (!skipP) {
3465  mdvSonameDep(buf, s, isElf64, 1),
3466  "", RPMSENSE_FIND_PROVIDES);
3467  xx = add(context, ds);
3468  (void)rpmdsFree(ds);
3469  ds = NULL;
3470  }
3471  /*@switchbreak@*/ break;
3472  }
3473  }
3474  }
3475  /*@switchbreak@*/ break;
3476  }
3477  }
3478  /*@=uniondef @*/
3479 
3480 exit:
3481  if (gotSONAME && !skipR)
3482  for (i = 0, cnt = argvCount(deps); i < cnt; i++) {
3484  mdvSonameDep(buf, deps[i], isElf64, 1),
3485  "", RPMSENSE_FIND_REQUIRES);
3486  xx = add(context, ds);
3487  (void)rpmdsFree(ds);
3488  ds = NULL;
3489  }
3490 
3491  deps = argvFree(deps);
3492  if (elf) (void) elf_end(elf);
3493  if (fdno > 0)
3494  xx = close(fdno);
3495  return 0;
3496 #else
3497  return -1;
3498 #endif
3499 }
3500 #endif /* RPM_VENDOR_MANDRIVA */
3501 
3502 #define _SBIN_LDCONFIG_P "/sbin/ldconfig -p"
3503 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
3504 static const char * _ldconfig_cmd = _SBIN_LDCONFIG_P;
3505 
3506 #define _LD_SO_CACHE "/etc/ld.so.cache"
3507 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
3508 static const char * _ldconfig_cache = NULL;
3509 
3510 int rpmdsLdconfig(rpmPRCO PRCO, const char * fn)
3511  /*@globals _ldconfig_cmd, _ldconfig_cache @*/
3512  /*@modifies _ldconfig_cmd, _ldconfig_cache @*/
3513 {
3514  char buf[BUFSIZ];
3515  const char *DSOfn;
3516  const char *N, *EVR;
3517  evrFlags Flags = (evrFlags) 0;
3518  rpmds ds;
3519  char * f, * fe;
3520  char * g, * ge;
3521  char * t;
3522  FILE * fp = NULL;
3523  int rc = -1;
3524  int xx;
3525 
3526  if (PRCO == NULL)
3527  return -1;
3528 
3529 /*@-modobserver@*/
3530  if (_ldconfig_cmd == NULL) {
3531  _ldconfig_cmd = rpmExpand("%{?_rpmds_ldconfig_cmd}", NULL);
3532  if (!(_ldconfig_cmd != NULL && *_ldconfig_cmd == '/')) {
3533 /*@-observertrans @*/
3534  _ldconfig_cmd = _free(_ldconfig_cmd);
3535 /*@=observertrans @*/
3536  _ldconfig_cmd = xstrdup(_SBIN_LDCONFIG_P);
3537  }
3538  }
3539 
3540  if (_ldconfig_cache == NULL) {
3541  _ldconfig_cache = rpmExpand("%{?_rpmds_ldconfig_cache}", NULL);
3542  /* XXX may need to validate path existence somewhen. */
3543  if (!(_ldconfig_cache != NULL && *_ldconfig_cache == '/')) {
3544 /*@-observertrans @*/
3545  _ldconfig_cache = _free(_ldconfig_cache);
3546 /*@=observertrans @*/
3547  _ldconfig_cache = xstrdup(_LD_SO_CACHE);
3548  }
3549  }
3550 /*@=modobserver@*/
3551 
3552  if (fn == NULL)
3553  fn = _ldconfig_cache;
3554 
3555 if (_rpmds_debug < 0)
3556 fprintf(stderr, "*** rpmdsLdconfig(%p, %s) P %p R %p C %p O %p T %p D %p L %p\n", PRCO, fn, PRCO->Pdsp, PRCO->Rdsp, PRCO->Cdsp, PRCO->Odsp, PRCO->Tdsp, PRCO->Ddsp, PRCO->Ldsp);
3557 
3558  fp = popen(_ldconfig_cmd, "r");
3559  if (fp == NULL)
3560  goto exit;
3561 
3562  while((f = fgets(buf, (int)sizeof(buf), fp)) != NULL) {
3563  EVR = NULL;
3564  /* rtrim on line. */
3565  ge = f + strlen(f);
3566  while (--ge > f && _isspace(*ge))
3567  *ge = '\0';
3568 
3569  /* ltrim on line. */
3570  while (*f && _isspace(*f))
3571  f++;
3572 
3573  /* split on '=>' */
3574  fe = f;
3575  while (*fe && !(fe[0] == '=' && fe[1] == '>'))
3576  fe++;
3577  if (*fe == '\0')
3578  continue;
3579 
3580  /* find the DSO file name. */
3581  DSOfn = fe + 2;
3582 
3583  /* ltrim on DSO file name. */
3584  while (*DSOfn && _isspace(*DSOfn))
3585  DSOfn++;
3586  if (*DSOfn == '\0')
3587  continue;
3588 
3589  /* rtrim from "=>" */
3590  if (fe > f && fe[-1] == ' ') fe[-1] = '\0';
3591  *fe++ = '\0';
3592  *fe++ = '\0';
3593  g = fe;
3594 
3595  /* ltrim on field 2. */
3596  while (*g && _isspace(*g))
3597  g++;
3598  if (*g == '\0')
3599  continue;
3600 
3601  /* split out flags */
3602  for (t = f; *t != '\0'; t++) {
3603  if (!_isspace(*t))
3604  /*@innercontinue@*/ continue;
3605  *t++ = '\0';
3606  /*@innerbreak@*/ break;
3607  }
3608  /* XXX "libc4" "ELF" "libc5" "libc6" _("unknown") */
3609  /* XXX use flags to generate soname color */
3610  /* ",64bit" ",IA-64" ",x86-64", ",64bit" are color = 2 */
3611  /* ",N32" for mips64/libn32 */
3612 
3613  /* XXX use flags and LDASSUME_KERNEL to skip sonames? */
3614  /* "Linux" "Hurd" "Solaris" "FreeBSD" "kNetBSD" N_("Unknown OS") */
3615  /* ", OS ABI: %s %d.%d.%d" */
3616 
3617  N = f;
3618  if (EVR == NULL)
3619  EVR = "";
3620  Flags = (evrFlags) (Flags | RPMSENSE_PROBE);
3621  ds = rpmdsSingle(RPMTAG_PROVIDENAME, N, EVR, Flags);
3622  xx = rpmdsMerge(PRCO->Pdsp, ds);
3623  (void)rpmdsFree(ds);
3624  ds = NULL;
3625 
3626  xx = rpmdsELF(DSOfn, 0, rpmdsMergePRCO, PRCO);
3627  }
3628  rc = 0;
3629 
3630 exit:
3631  if (fp != NULL) (void) pclose(fp);
3632  return rc;
3633 }
3634 
3635 
3636 #if defined(__sun)
3637 #define _RLD_SEARCH_PATH "/lib:/usr/lib"
3638 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
3639 static const char * _rld_search_path = NULL;
3640 
3641 /* search a colon-separated list of directories for shared objects */
3642 int rpmdsRldpath(rpmPRCO PRCO, const char * rldp)
3643  /*@globals _rld_search_path @*/
3644  /*@modifies _rld_search_path @*/
3645 {
3646  char buf[BUFSIZ];
3647  const char *N, *EVR;
3648  evrFlags Flags = 0;
3649  rpmds ds;
3650  const char * f;
3651  const char * g;
3652  int rc = -1;
3653  int xx;
3654  glob_t gl;
3655  char ** gp;
3656 
3657  if (PRCO == NULL)
3658  return -1;
3659 
3660 /*@-modobserver@*/
3661  if (_rld_search_path == NULL) {
3662  _rld_search_path = rpmExpand("%{?_rpmds_rld_search_path}", NULL);
3663  /* XXX may need to validate path existence somewhen. */
3664  if (!(_rld_search_path != NULL && *_rld_search_path == '/')) {
3665 /*@-observertrans @*/
3666  _rld_search_path = _free(_rld_search_path);
3667 /*@=observertrans @*/
3668  _rld_search_path = xstrdup(_RLD_SEARCH_PATH);
3669  }
3670  }
3671 /*@=modobserver@*/
3672 
3673  if (rldp == NULL)
3674  rldp = _rld_search_path;
3675 
3676 if (_rpmds_debug > 0)
3677 fprintf(stderr, "*** rpmdsRldpath(%p, %s) P %p R %p C %p O %p\n", PRCO, rldp, PRCO->Pdsp, PRCO->Rdsp, PRCO->Cdsp, PRCO->Odsp);
3678 
3679  f = rldp;
3680  /* move through the path, splitting on : */
3681  while (f) {
3682  EVR = NULL;
3683  g = strchr(f, ':');
3684  if (g == NULL) {
3685  strcpy(buf, f);
3686  /* this is the last element, no more :'s */
3687  f = NULL;
3688  } else {
3689  /* copy this chunk to buf */
3690  strncpy(buf, f, g - f + 1);
3691  buf[g-f] = '\0';
3692 
3693  /* get ready for next time through */
3694  f = g + 1;
3695  }
3696 
3697  if ( !(strlen(buf) > 0 && buf[0] == '/') )
3698  continue;
3699 
3700  /* XXX: danger, buffer len */
3701  /* XXX: *.so.* should be configurable via a macro */
3702  strcat(buf, "/*.so.*");
3703 
3704 if (_rpmds_debug > 0)
3705 fprintf(stderr, "*** rpmdsRldpath(%p, %s) globbing %s\n", PRCO, rldp, buf);
3706 
3707  xx = Glob(buf, 0, NULL, &gl);
3708  if (xx) /* glob error, probably GLOB_NOMATCH */
3709  continue;
3710 
3711 if (_rpmds_debug > 0)
3712 fprintf(stderr, "*** rpmdsRldpath(%p, %s) glob matched %d files\n", PRCO, rldp, gl.gl_pathc);
3713 
3714  gp = gl.gl_pathv;
3715  /* examine each match */
3716  while (gp && *gp) {
3717  const char *DSOfn;
3718  /* XXX: should probably verify that we matched a file */
3719  DSOfn = *gp;
3720  gp++;
3721  if (EVR == NULL)
3722  EVR = "";
3723 
3724  /* N needs to be basename of DSOfn */
3725  N = DSOfn + strlen(DSOfn);
3726  while (N > DSOfn && *N != '/')
3727  --N;
3728 
3729  Flags |= RPMSENSE_PROBE;
3730  ds = rpmdsSingle(RPMTAG_PROVIDENAME, N, EVR, Flags);
3731  xx = rpmdsMerge(PRCO->Pdsp, ds);
3732  (void)rpmdsFree(ds);
3733  ds = NULL;
3734 
3735  xx = rpmdsELF(DSOfn, 0, rpmdsMergePRCO, PRCO);
3736  }
3737 /*@-immediatetrans@*/
3738  Globfree(&gl);
3739 /*@=immediatetrans@*/
3740  }
3741  rc = 0;
3742 
3743  return rc;
3744 }
3745 
3746 #define _SOLARIS_CRLE "/usr/sbin/crle"
3747 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
3748 static const char * _crle_cmd = NULL;
3749 
3750 int rpmdsCrle(rpmPRCO PRCO, /*@unused@*/ const char * fn)
3751  /*@globals _crle_cmd @*/
3752  /*@modifies _crle_cmd @*/
3753 {
3754  char buf[BUFSIZ];
3755  char * f;
3756  char * g, * ge;
3757  FILE * fp = NULL;
3758  int rc = -1; /* assume failure */
3759  int xx;
3760  int found_dlp = 0;
3761 
3762  if (PRCO == NULL)
3763  return -1;
3764 
3765 /*@-modobserver@*/
3766  if (_crle_cmd == NULL) {
3767  _crle_cmd = rpmExpand("%{?_rpmds_crle_cmd}", NULL);
3768  if (!(_crle_cmd != NULL && *_crle_cmd == '/')) {
3769 /*@-observertrans @*/
3770  _crle_cmd = _free(_crle_cmd);
3771 /*@=observertrans @*/
3772  _crle_cmd = xstrdup(_SOLARIS_CRLE);
3773  }
3774  }
3775 
3776  /* XXX: we rely on _crle_cmd including the -64 arg, if ELF64 */
3777  fp = popen(_crle_cmd, "r");
3778  if (fp == NULL)
3779  return rc;
3780 
3781  /*
3782  * we want the first line that contains "(ELF):"
3783  * we cannot search for "Default Library Path (ELF):" because that
3784  * changes in non-C locales.
3785  */
3786  while((f = fgets(buf, sizeof(buf), fp)) != NULL) {
3787  if (found_dlp) /* XXX read all data? */
3788  continue;
3789 
3790  g = strstr(f, "(ELF):");
3791  if (g == NULL)
3792  continue;
3793 
3794  found_dlp = 1;
3795  f = g + (sizeof("(ELF):")-1);
3796  while (_isspace(*f))
3797  f++;
3798 
3799  /* rtrim path */
3800  ge = f + strlen(f);
3801  while (--ge > f && _isspace(*ge))
3802  *ge = '\0';
3803  }
3804  xx = pclose(fp);
3805 
3806  /* we have the loader path, let rpmdsRldpath() do the work */
3807  if (found_dlp)
3808  rc = rpmdsRldpath(PRCO, f);
3809 
3810  return rc;
3811 }
3812 #endif
3813 
3814 int rpmdsUname(rpmds *dsp, const struct utsname * un)
3815 {
3816 /*@observer@*/
3817  static const char * NS = "uname";
3818  struct utsname myun;
3819  int rc = -1;
3820  int xx;
3821 
3822  if (un == NULL) {
3823  xx = uname(&myun);
3824  if (xx != 0)
3825  goto exit;
3826  un = &myun;
3827  }
3828 
3829 /*@-type@*/
3830  /* XXX values need to be checked for EVR (i.e. no '-' character.) */
3831  if (un->sysname != NULL)
3832  rpmdsNSAdd(dsp, NS, "sysname", un->sysname, RPMSENSE_EQUAL);
3833  if (un->nodename != NULL)
3834  rpmdsNSAdd(dsp, NS, "nodename", un->nodename, RPMSENSE_EQUAL);
3835  if (un->release != NULL)
3836  rpmdsNSAdd(dsp, NS, "release", un->release, RPMSENSE_EQUAL);
3837 #if 0 /* XXX has embedded spaces */
3838  if (un->version != NULL)
3839  rpmdsNSAdd(dsp, NS, "version", un->version, RPMSENSE_EQUAL);
3840 #endif
3841  if (un->machine != NULL)
3842  rpmdsNSAdd(dsp, NS, "machine", un->machine, RPMSENSE_EQUAL);
3843 #if defined(__linux__)
3844  if (un->domainname != NULL && strcmp(un->domainname, "(none)"))
3845  rpmdsNSAdd(dsp, NS, "domainname", un->domainname, RPMSENSE_EQUAL);
3846 #endif
3847 /*@=type@*/
3848  rc = 0;
3849 
3850 exit:
3851  return rc;
3852 }
3853 
3854 #define _PERL_PROVIDES "/usr/bin/find /usr/lib/perl5 | /usr/lib/rpm/perl.prov"
3855 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
3856 static const char * _perldeps_cmd = NULL;
3857 
3858 int rpmdsPipe(rpmds * dsp, rpmTag tagN, const char * cmd)
3859  /*@globals _perldeps_cmd @*/
3860  /*@modifies _perldeps_cmd @*/
3861 {
3862  char buf[BUFSIZ];
3863  const char *N, *EVR;
3864  evrFlags Flags = (evrFlags) 0;
3865  rpmds ds;
3866  char * f, * fe;
3867  char * g, * ge;
3868  FILE * fp = NULL;
3869  const char * fn = "pipe";
3870  int rc = -1;
3871  int cmdprinted;
3872  int ln;
3873  int xx;
3874 
3875 /*@-modobserver@*/
3876  if (_perldeps_cmd == NULL) {
3877  _perldeps_cmd = rpmExpand("%{?_rpmds_perldeps_cmd}", NULL);
3878  /* XXX may need to validate path existence somewhen. */
3879  if (!(_perldeps_cmd != NULL && *_perldeps_cmd == '/')) {
3880 /*@-observertrans @*/
3881  _perldeps_cmd = _free(_perldeps_cmd);
3882 /*@=observertrans @*/
3883  _perldeps_cmd = xstrdup(_PERL_PROVIDES);
3884  }
3885  }
3886 /*@=modobserver@*/
3887 
3888  if (tagN <= 0)
3889  tagN = RPMTAG_PROVIDENAME;
3890  if (cmd == NULL)
3891  cmd = _perldeps_cmd;
3892 
3893  fp = popen(cmd, "r");
3894  if (fp == NULL)
3895  goto exit;
3896 
3897  ln = 0;
3898  cmdprinted = 0;
3899  while((f = fgets(buf, (int)sizeof(buf), fp)) != NULL) {
3900  ln++;
3901 
3902  /* insure a terminator. */
3903  buf[sizeof(buf)-1] = '\0';
3904 
3905  /* ltrim on line. */
3906  while (*f && _isspace(*f))
3907  f++;
3908 
3909  /* skip empty lines and comments */
3910  if (*f == '\0' || *f == '#')
3911  continue;
3912 
3913  /* rtrim on line. */
3914  fe = f + strlen(f);
3915  while (--fe > f && _isspace(*fe))
3916  *fe = '\0';
3917 
3918  /* split on ' ' or comparison operator. */
3919  fe = f;
3920  if (*f == '!') fe++;
3921  while (*fe && !_isspace(*fe) && strchr("!<=>", *fe) == NULL)
3922  fe++;
3923  while (*fe && _isspace(*fe))
3924  *fe++ = '\0';
3925 
3926  if (!(xisalnum(f[0]) || strchr("/_%!", f[0]) != NULL)) {
3927  if (!cmdprinted++)
3928  fprintf(stderr, _("running \"%s\" pipe command\n"), cmd);
3929  fprintf(stderr, _("%s:%d \"%s\" has invalid name. Skipping ...\n"),
3930  fn, ln, f);
3931  continue;
3932  }
3933 
3934  N = f;
3935  EVR = NULL;
3936  Flags = (evrFlags) 0;
3937 
3938  /* parse for non-path, versioned dependency. */
3939  if (*f != '/' && *fe != '\0') {
3940  /* parse comparison operator */
3941  g = fe;
3942  Flags = rpmEVRflags(fe, (const char **)&g);
3943  if (Flags == 0) {
3944  if (!cmdprinted++)
3945  fprintf(stderr, _("running \"%s\" pipe command\n"), cmd),
3946  fprintf(stderr, _("%s:%d \"%s\" has no comparison operator. Skipping ...\n"),
3947  fn, ln, fe);
3948  continue;
3949  }
3950  *fe = '\0';
3951 
3952  /* ltrim on field 2. */
3953  while (*g && _isspace(*g))
3954  g++;
3955  if (*g == '\0') {
3956  if (!cmdprinted++)
3957  fprintf(stderr, _("running \"%s\" pipe command\n"), cmd),
3958  /* XXX No EVR comparison value found. */
3959  fprintf(stderr, _("\tline %d: No EVR comparison value found.\n Skipping ..."),
3960  ln);
3961  fprintf(stderr, _("%s:%d \"%s\" has no EVR string. Skipping ...\n"),
3962  fn, ln, f);
3963  continue;
3964  }
3965 
3966  ge = g + 1;
3967  while (*ge && !_isspace(*ge))
3968  ge++;
3969 
3970  if (*ge != '\0')
3971  *ge = '\0'; /* XXX can't happen, line rtrim'ed already. */
3972 
3973  EVR = g;
3974  }
3975 
3976  if (EVR == NULL)
3977  EVR = "";
3978  Flags = (evrFlags) (Flags | RPMSENSE_PROBE);
3979  ds = rpmdsSingle(tagN, N, EVR, Flags);
3980  xx = rpmdsMerge(dsp, ds);
3981  (void)rpmdsFree(ds);
3982  ds = NULL;
3983  }
3984  rc = 0;
3985 
3986 exit:
3987  if (fp != NULL) (void) pclose(fp);
3988  return rc;
3989 }
3990 
3991 static int rpmdsNAcmp(rpmds A, rpmds B)
3992  /*@*/
3993 {
3994  const char * AN = A->ns.N;
3995  const char * AA = A->ns.A;
3996  const char * BN = B->ns.N;
3997  const char * BA = B->ns.A;
3998  int rc;
3999 
4000  if (!AA && !BA) {
4001  rc = strcmp(AN, BN);
4002  } else if (AA && !BA) {
4003  rc = strncmp(AN, BN, (AA - AN)) || BN[AA - AN];
4004  if (!rc)
4005  rc = strcmp(AA, B->A);
4006  } else if (!AA && BA) {
4007  rc = strncmp(AN, BN, (BA - BN)) || AN[BA - BN];
4008  if (!rc)
4009  rc = strcmp(BA, A->A);
4010  } else {
4011  rc = strcmp(AN, BN);
4012  }
4013  return rc;
4014 }
4015 
4016 /*@unchecked@*/ /*@only@*/ /*@null@*/
4017 const char * evr_tuple_order = NULL;
4018 
4023 /*@observer@*/
4024 static const char * rpmdsEVRorder(void)
4025  /*@globals evr_tuple_order @*/
4026  /*@modifies evr_tuple_order @*/
4027 {
4028  if (evr_tuple_order == NULL) {
4029 /*@-mods@*/
4030  evr_tuple_order = rpmExpand("%{?evr_tuple_order}", NULL);
4031 /*@=mods@*/
4032  if (evr_tuple_order == NULL || evr_tuple_order[0] == '\0') {
4033  /* XXX coverity #1035879 */
4034  evr_tuple_order = _free(evr_tuple_order);
4035  evr_tuple_order = xstrdup("EVR");
4036  }
4037  }
4038 assert(evr_tuple_order != NULL && evr_tuple_order[0] != '\0');
4039 /*@-freshtrans@*/
4040  return evr_tuple_order;
4041 /*@=freshtrans@*/
4042 }
4043 
4044 int rpmdsCompare(const rpmds A, const rpmds B)
4045 {
4046  const char *aDepend = (A->DNEVR != NULL ? xstrdup(A->DNEVR+2) : "");
4047  const char *bDepend = (B->DNEVR != NULL ? xstrdup(B->DNEVR+2) : "");
4048  EVR_t a = (EVR_t) memset(alloca(sizeof(*a)), 0, sizeof(*a));
4049  EVR_t b = (EVR_t) memset(alloca(sizeof(*a)), 0, sizeof(*a));
4050  evrFlags aFlags = A->ns.Flags;
4051  evrFlags bFlags = B->ns.Flags;
4052  int (*EVRcmp) (const char *a, const char *b);
4053  int result = 1;
4054  const char * s;
4055  int set_version = 0;
4056  int sense;
4057  int xx;
4058 
4059 assert((rpmdsFlags(A) & RPMSENSE_SENSEMASK) == A->ns.Flags);
4060 assert((rpmdsFlags(B) & RPMSENSE_SENSEMASK) == B->ns.Flags);
4061  /* Different namespaces don't overlap. */
4062  if (A->ns.Type != B->ns.Type) {
4063  result = 0;
4064  goto exit;
4065  }
4066 
4067  /* Different names (and/or name.arch's) don't overlap. */
4068  if (rpmdsNAcmp(A, B)) {
4069  result = 0;
4070  goto exit;
4071  }
4072 
4073  /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
4074 /*@-nullderef@*/
4075  if (!(A->EVR && A->Flags && B->EVR && B->Flags))
4076  goto exit;
4077 
4078  /* Same name. If either A or B is an existence test, always overlap. */
4079  if (!(aFlags && bFlags))
4080  goto exit;
4081 
4082  /* If either EVR is non-existent or empty, always overlap. */
4083  if (!(A->EVR[A->i] && *A->EVR[A->i] && B->EVR[B->i] && *B->EVR[B->i]))
4084  goto exit;
4085 
4086  /* Both AEVR and BEVR exist. */
4087  xx = (A->EVRparse ? A->EVRparse : rpmEVRparse) (A->EVR[A->i], a);
4088  xx = (B->EVRparse ? B->EVRparse : rpmEVRparse) (B->EVR[B->i], b);
4089 
4090  /* If EVRcmp is identical, use that, otherwise use default. */
4091  EVRcmp = (A->EVRcmp && B->EVRcmp && A->EVRcmp == B->EVRcmp)
4092  ? A->EVRcmp : rpmvercmp;
4093 
4094  /* Compare {A,B} [epoch:]version[-release][:distepoch] */
4095  sense = 0;
4096  for (s = rpmdsEVRorder(); *s; s++) {
4097  int ix;
4098  switch ((int)*s) {
4099  default: continue; /*@notreached@*//*@switchbreak@*/ break;
4100  case 'E':
4101  ix = RPMEVR_E;
4102  if (a->F[ix] && *a->F[ix] && b->F[ix] && *b->F[ix]) {
4103  /* XXX ALT version-set comparison */
4104  if (!strcmp(a->F[ix], "set") && !strcmp(b->F[ix], "set"))
4105  set_version = 1;
4106  /*@switchbreak@*/ break;
4107  }
4108 
4109  /* XXX Special handling for missing Epoch: tags hysteria */
4110  if (a->F[ix] && *a->F[ix] && atol(a->F[ix]) > 0) {
4111  if (!B->nopromote) {
4112  int lvl = (_rpmds_unspecified_epoch_noise
4114  rpmlog(lvl, _("The \"B\" dependency needs an epoch (assuming same epoch as \"A\")\n\tA = \"%s\"\tB = \"%s\"\n"),
4115  aDepend, bDepend);
4116  sense = 0;
4117  } else
4118  sense = 1;
4119  } else
4120  if (b->F[ix] && *b->F[ix] && atol(b->F[ix]) > 0)
4121  sense = -1;
4122  /*@switchbreak@*/ break;
4123  case 'V': ix = RPMEVR_V; /*@switchbreak@*/break;
4124  case 'T': ix = RPMEVR_T; /*@switchbreak@*/break;
4125  case 'R': ix = RPMEVR_R; /*@switchbreak@*/break;
4126  case 'D': ix = RPMEVR_D; /*@switchbreak@*/break;
4127  }
4128 #if defined(RPM_VENDOR_MANDRIVA) /* mdvbz#55810 */
4129  if(ix >= RPMEVR_R && (bFlags & (~RPMSENSE_GREATER & RPMSENSE_EQUAL))
4130  && !(ix == RPMEVR_D && (bFlags & RPMSENSE_LESS))
4131  && *(b->F[ix]) == '\0')
4132  break;
4133  if (a->F[ix] && b->F[ix])
4134 #else
4135  if (a->F[ix] && *a->F[ix] && b->F[ix] && *b->F[ix])
4136 #endif
4137  {
4138  /* XXX ALT version-set comparison */
4139  if (ix == RPMEVR_V && set_version) {
4140  set_version = 0;
4141  sense = rpmsetCmp(a->F[ix], b->F[ix]);
4142  if (sense < -1) {
4143  if (sense == -3)
4144  rpmlog(RPMLOG_WARNING, _("failed to decode %s\n"), a->F[ix]);
4145  if (sense == -4)
4146  rpmlog(RPMLOG_WARNING, _("failed to decode %s\n"), b->F[ix]);
4147  /* neither is subset of each other */
4148  sense = 0;
4149  }
4150  } else
4151  if (ix == RPMEVR_T) /* XXX twiddle-in-version "negative" compare */
4152  sense = -EVRcmp(a->F[ix], b->F[ix]);
4153  else
4154 /*@i@*/ sense = EVRcmp(a->F[ix], b->F[ix]);
4155  }
4156  if (sense)
4157  break;
4158  }
4159 
4160  a->str = _free(a->str);
4161  b->str = _free(b->str);
4162 
4163  /* Detect overlap of {A,B} range. */
4164  if (aFlags == RPMSENSE_NOTEQUAL || bFlags == RPMSENSE_NOTEQUAL) {
4165  result = (sense != 0);
4166  } else if (sense < 0 && ((aFlags & RPMSENSE_GREATER) || (bFlags & RPMSENSE_LESS))) {
4167  result = 1;
4168  } else if (sense > 0 && ((aFlags & RPMSENSE_LESS) || (bFlags & RPMSENSE_GREATER))) {
4169  result = 1;
4170  } else if (sense == 0 &&
4171  (((aFlags & RPMSENSE_EQUAL) && (bFlags & RPMSENSE_EQUAL)) ||
4172  ((aFlags & RPMSENSE_LESS) && (bFlags & RPMSENSE_LESS)) ||
4173  ((aFlags & RPMSENSE_GREATER) && (bFlags & RPMSENSE_GREATER)))) {
4174  result = 1;
4175  } else
4176  result = 0;
4177 /*@=nullderef@*/
4178 
4179 exit:
4180  if (_noisy_range_comparison_debug_message)
4181  rpmlog(RPMLOG_DEBUG, D_(" %s A %s\tB %s\n"),
4182  (result ? _("YES") : _("NO ")), aDepend, bDepend);
4183  aDepend = _free(aDepend);
4184  bDepend = _free(bDepend);
4185  return result;
4186 }
4187 
4188 int rpmdsMatch(const rpmds A, rpmds B)
4189 {
4190  int result = 0;
4191 
4192  /* If A dependency matches any in B, we're done. */
4193  if ((B = rpmdsInit(B)) != NULL)
4194  while (rpmdsNext(B) >= 0)
4195  if ((result = rpmdsCompare(A, B)))
4196  break;
4197  return result;
4198 }
4199 
4200 void rpmdsProblem(rpmps ps, const char * pkgNEVR, const rpmds ds,
4201  const fnpyKey * suggestedKeys, int adding)
4202 {
4203  const char * Name = rpmdsN(ds);
4204  const char * DNEVR = rpmdsDNEVR(ds);
4205  const char * EVR = rpmdsEVR(ds);
4207  fnpyKey key;
4208 
4209  if (ps == NULL) return;
4210 
4211  if (Name == NULL) Name = "?N?";
4212  if (EVR == NULL) EVR = "?EVR?";
4213  if (DNEVR == NULL) DNEVR = "? ?N? ?OP? ?EVR?";
4214 
4215  rpmlog(RPMLOG_DEBUG, D_("package %s has unsatisfied %s: %s\n"),
4216  pkgNEVR, ds->Type, DNEVR+2);
4217 
4218  switch ((unsigned)DNEVR[0]) {
4219  case 'C': type = RPMPROB_CONFLICT; break;
4220  default:
4221  case 'R': type = RPMPROB_REQUIRES; break;
4222  }
4223 
4224  key = (suggestedKeys ? suggestedKeys[0] : NULL);
4225  rpmpsAppend(ps, type, pkgNEVR, key, NULL, NULL, DNEVR, adding);
4226 }
4227 
4228 int rpmdsAnyMatchesDep (const Header h, const rpmds req, int nopromote)
4229 {
4230  int scareMem = 0;
4231  rpmds provides = NULL;
4232  evrFlags reqFlags = req->ns.Flags;
4233  int result = 1;
4234 
4235 assert((rpmdsFlags(req) & RPMSENSE_SENSEMASK) == req->ns.Flags);
4236  /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
4237  if (req->EVR == NULL || req->Flags == NULL)
4238  goto exit;
4239 
4240  switch(req->ns.Type) {
4241  default:
4242  /* Primary key retrieve satisfes an existence compare. */
4243  if (!reqFlags || !req->EVR[req->i] || *req->EVR[req->i] == '\0')
4244  goto exit;
4245  /*@fallthrough@*/
4246  case RPMNS_TYPE_ARCH:
4247  break;
4248  }
4249 
4250  /* Get provides information from header */
4251  provides = rpmdsInit(rpmdsNew(h, RPMTAG_PROVIDENAME, scareMem));
4252  if (provides == NULL) {
4253  result = 0;
4254  goto exit; /* XXX should never happen */
4255  }
4256  if (nopromote)
4257  (void) rpmdsSetNoPromote(provides, nopromote);
4258 
4259  /*
4260  * Rpm prior to 3.0.3 did not have versioned provides.
4261  * If no provides version info is available, match any/all requires
4262  * with same name.
4263  */
4264  if (provides->EVR == NULL)
4265  goto exit;
4266 
4267  /* If any provide matches the require, we're done. */
4268  result = 0;
4269  if (provides != NULL)
4270  while (rpmdsNext(provides) >= 0)
4271  if ((result = rpmdsCompare(provides, req)))
4272  break;
4273 
4274 exit:
4275  (void)rpmdsFree(provides);
4276  provides = NULL;
4277 
4278  return result;
4279 }
4280 
4281 int rpmdsNVRMatchesDep(const Header h, const rpmds req, int nopromote)
4282 {
4283  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
4284  const char * pkgN, * V, * R;
4285 #ifdef RPM_VENDOR_MANDRIVA
4286  const char * D;
4287  int gotD = 0;
4288 #endif
4289  rpmuint32_t E;
4290  int gotE = 0;
4291  const char * pkgEVR;
4292  char * t;
4293  evrFlags reqFlags = req->ns.Flags;
4294  evrFlags pkgFlags = RPMSENSE_EQUAL;
4295  int result = 1;
4296  rpmds pkg;
4297  size_t nb;
4298 
4299 assert((rpmdsFlags(req) & RPMSENSE_SENSEMASK) == req->ns.Flags);
4300  /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
4301  if (req->EVR == NULL || req->Flags == NULL)
4302  goto exit;
4303 
4304  if (!(reqFlags && req->EVR[req->i] && *req->EVR[req->i]))
4305  goto exit;
4306 
4307  /* Get package information from header */
4308 /*@-mods@*/
4309  (void) headerNEVRA(h, &pkgN, NULL, &V, &R, NULL);
4310 /*@=mods@*/
4311  /* XXX segfault avoidance */
4312  if (pkgN == NULL) pkgN = xstrdup("N");
4313  if (V == NULL) V = xstrdup("V");
4314  if (R == NULL) R = xstrdup("R");
4315  he->tag = RPMTAG_EPOCH;
4316  gotE = headerGet(h, he, 0);
4317  E = (he->p.ui32p ? he->p.ui32p[0] : 0);
4318  he->p.ptr = _free(he->p.ptr);
4319 
4320 #if defined(RPM_VENDOR_MANDRIVA)
4321  he->tag = RPMTAG_DISTEPOCH;
4322  gotD = headerGet(h, he, 0);
4323  D = (he->p.str ? he->p.str : NULL);
4324 #endif
4325 
4326  nb = 21 + 1 + 1;
4327  if (V) nb += strlen(V);
4328  if (R) nb += strlen(R);
4329 #if defined(RPM_VENDOR_MANDRIVA)
4330  if (gotD) nb += strlen(D) + 1;
4331 #endif
4332  pkgEVR = t = (char *) alloca(nb);
4333  *t = '\0';
4334  if (gotE) {
4335  sprintf(t, "%d:", E);
4336  t += strlen(t);
4337  }
4338  t = stpcpy( stpcpy( stpcpy(t, V) , "-") , R);
4339 #if defined(RPM_VENDOR_MANDRIVA)
4340  if (gotD) {
4341  t = stpcpy( stpcpy( t, ":"), D);
4342  D = _free(D);
4343  }
4344 #endif
4345  V = _free(V);
4346  R = _free(R);
4347 
4348  if ((pkg = rpmdsSingle(RPMTAG_PROVIDENAME, pkgN, pkgEVR, pkgFlags)) != NULL) {
4349  if (nopromote)
4350  (void) rpmdsSetNoPromote(pkg, nopromote);
4351  result = rpmdsCompare(pkg, req);
4352  (void)rpmdsFree(pkg);
4353  pkg = NULL;
4354  }
4355  pkgN = _free(pkgN);
4356 
4357 exit:
4358  return result;
4359 }
4360 
4361 int rpmdsNegateRC(const rpmds ds, int rc)
4362 {
4363  if (ds->ns.str[0] == '!')
4364  rc = (rc == 0);
4365  return rc;
4366 }
rpmds rpmdsSingle(rpmTag tagN, const char *N, const char *EVR, evrFlags Flags)
Create, load and initialize a dependency set of size 1.
Definition: rpmds.c:609
const bson * b
Definition: bson.h:280
static const char * suffix[]
Definition: rpmgrep.c:188
const _conf_e call
Definition: rpmds.c:1819
evrFlags rpmdsFlags(const rpmds ds)
Return current dependency flags.
Definition: rpmds.c:691
const char * str
Definition: rpmtag.h:73
rpmTag tag
Definition: rpmtag.h:503
const char ** argv
Definition: rpmtag.h:75
rpmds rpmdsInit(rpmds ds)
Initialize dependency set iterator.
Definition: rpmds.c:943
rpmPRCO rpmdsFreePRCO(rpmPRCO PRCO)
Free dependency set(s) container.
Definition: rpmds.c:2851
nsType rpmdsNSType(const rpmds ds)
Return dependency class type.
Definition: rpmds.c:738
const char * rpmdsType(const rpmds ds)
Return current dependency type name.
Definition: rpmds.c:162
const char const char size_t len
Definition: bson.h:823
enum nsType_e nsType
Dependency types.
static const char * rpmdsTagName(rpmTag tagN)
Return dependency set type string.
Definition: rpmds.c:139
void rpmdsProblem(rpmps ps, const char *pkgNEVR, const rpmds ds, const fnpyKey *suggestedKeys, int adding)
Report a Requires: or Conflicts: dependency problem.
Definition: rpmds.c:4200
int rpmdsNoPromote(const rpmds ds)
Return current "Don't promote Epoch:" flag.
Definition: rpmds.c:746
#define RPMELF_FLAG_SKIPREQUIRES
Definition: rpmds.h:621
#define RPMSENSE_SENSEMASK
Definition: rpmevr.h:76
void * mireFreeAll(miRE mire, int nmire)
Destroy compiled patterns.
Definition: mire.c:96
static void rpmdsFini(void *_ds)
Definition: rpmds.c:167
const char const char * cmd
Definition: mongo.h:777
void rpmpsAppend(rpmps ps, rpmProblemType type, const char *pkgNEVR, fnpyKey key, const char *dn, const char *bn, const char *altNEVR, rpmuint64_t ulong1)
Append a problem to current set of problems.
Definition: rpmps.c:123
#define EXIT_FAILURE
static int rpmdsSysinfoFile(rpmPRCO PRCO, const char *fn, rpmTag tagN)
Merge contents of a sysinfo tag file into sysinfo dependencies.
Definition: rpmds.c:1613
static int xisalnum(int c)
Definition: rpmiotypes.h:549
char * xstrdup(const char *str)
Definition: rpmmalloc.c:321
rpmuint32_t * ui32p
Definition: rpmtag.h:70
__size_t gl_pathc
Definition: glob.h:119
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
Definition: rpmio.c:2840
int rpmdsNExclude(const rpmds ds)
Return no.
Definition: rpmds.c:824
char * rpmGetPath(const char *path,...)
Return (malloc'ed) expanded, canonicalized, file path.
Definition: macro.c:3445
rpmioPool _rpmdsPool
Definition: rpmds.c:191
int rpmdsGetconf(rpmds *dsp, const char *path)
Load getconf provides into a dependency set.
Definition: rpmds.c:2716
#define _isspace(_c)
Definition: rpmds.c:113
uint8_t uc[8]
Definition: db3.c:48
int headerGet(Header h, HE_t he, unsigned int flags)
Retrieve extension or tag value from a header.
Definition: header.c:2231
int(* rpmvercmp)(const char *a, const char *b)
Segmented string compare vector.
Definition: rpmevr.c:379
const char int time
Definition: bson.h:1005
void * rpmdsInclude(const rpmds ds)
Return dependency include patterns.
Definition: rpmds.c:829
The Header data structure.
enum rpmProblemType_e rpmProblemType
Enumerate transaction set problem types.
const char * rpmdsNewN(rpmds ds)
Return N string, expanded if necessary.
Definition: rpmds.c:421
const char * evr_tuple_order
Definition: rpmds.c:4017
#define MAXPATHLEN
int Stat(const char *path, struct stat *st)
stat(2) clone.
Definition: rpmrpc.c:1361
#define RPMTAG_PROVIDES
Definition: rpmtag.h:232
void * rpmdsExclude(const rpmds ds)
Return dependency exclude patterns.
Definition: rpmds.c:819
int rpmsetCmp(const char *str1, const char *str2)
Definition: set.c:1113
#define _ETC_RPM_SYSINFO
Definition: rpmds.c:1737
void Globfree(void *_pglob)
globfree(3) clone.
Definition: rpmrpc.c:2322
rpmuint32_t rpmdsSetColor(const rpmds ds, rpmuint32_t color)
Set current dependency color.
Definition: rpmds.c:800
int errno
rpmTag rpmdsTagN(const rpmds ds)
Return current dependency type.
Definition: rpmds.c:702
evrFlags featureFlags
Definition: rpmds.c:1446
rpmiob rpmiobFree(rpmiob iob)
Destroy a I/O buffer instance.
int rpmEVRparse(const char *evrstr, EVR_t evr)
Split EVR string into epoch, version, and release components.
Definition: rpmevr.c:181
char ** gl_pathv
Definition: glob.h:120
const char * rpmdsA(const rpmds ds)
Return current dependency arch.
Definition: rpmds.c:711
struct EVR_s * EVR_t
Definition: rpmevr.h:22
static void rpmlog(int code, const char *fmt,...)
Definition: rpmlog.h:299
struct rpmps_s * rpmps
Transaction problems found while processing a transaction set/.
Definition: rpmps.h:25
const char * rpmdsDNEVR(const rpmds ds)
Return current formatted dependency string.
Definition: rpmds.c:657
int rpmdsNVRMatchesDep(const Header h, const rpmds req, int nopromote)
Compare package name-version-release from header with a single dependency.
Definition: rpmds.c:4281
struct rpmds_s * rpmds
Dependency tag sets from a header, so that a header can be discarded early.
Definition: rpmtypes.h:28
Definition: glob.h:117
struct rpmPRCO_s * rpmPRCO
Container for commonly extracted dependency set(s).
Definition: rpmtypes.h:33
time_t rpmdsSetBT(const rpmds ds, time_t BT)
Set dependency build time.
Definition: rpmds.c:728
rpmds rpmdsFree(rpmds ds)
Destroy a dependency set.
rpmsenseFlags rpmEVRflags(const char *op, const char **end)
Return comparison operator sense flags.
Definition: rpmevr.c:406
rpmTag tagValue(const char *tagstr)
Return tag value from name.
Definition: tagname.c:446
int rpmiobSlurp(const char *fn, rpmiob *iobp)
Definition: rpmiob.c:129
void * rpmdsSetEVRcmp(rpmds ds, int(*EVRcmp)(const char *a, const char *b))
Set EVR comparison function.
Definition: rpmds.c:778
static const char * _sysinfo_tags[]
Definition: rpmds.c:1745
static void rpmdsNSAdd(rpmds *dsp, const char *NS, const char *N, const char *EVR, evrFlags Flags)
Merge a single provides, wrapping N as "NS(N)".
Definition: rpmds.c:1176
int rpmdsPipe(rpmds *dsp, rpmTag tagN, const char *cmd)
Load provides from a pipe into a dependency set.
Definition: rpmds.c:3858
enum evrFlags_e evrFlags
Dependency Attributes.
char * alloca()
rpmPRCO rpmdsNewPRCO(Header h)
Create dependency set(s) container.
Definition: rpmds.c:2876
#define RPMSENSE_NOTEQUAL
Definition: rpmevr.h:78
unsigned int rpmuint32_t
Definition: rpmiotypes.h:28
struct _HE_s * HE_t
Definition: rpmtag.h:59
#define DT_GNU_HASH
Definition: rpmds.c:82
#define fdGetFILE(_fd)
Definition: rpmio.c:159
#define _SBIN_LDCONFIG_P
Definition: rpmds.c:3502
void * xcalloc(size_t nmemb, size_t size)
Definition: rpmmalloc.c:300
static const char * _getconf_path
Definition: rpmds.c:2713
void * ptr
Definition: rpmtag.h:67
rpmint32_t rpmdsResult(const rpmds ds)
Return current dependency comparison result.
Definition: rpmds.c:869
#define _LD_SO_CACHE
Definition: rpmds.c:3506
int rpmdsSysinfo(rpmPRCO PRCO, const char *fn)
Load sysinfo dependencies into a dependency set.
Definition: rpmds.c:1756
struct rpmns_s * rpmns
Definition: rpmns.h:22
time_t rpmdsBT(const rpmds ds)
Return dependency build time.
Definition: rpmds.c:720
static const union _dbswap endian
int Glob(const char *pattern, int flags, int errfunc(const char *epath, int eerrno), void *_pglob)
glob(3) clone.
Definition: rpmrpc.c:2277
rpmioItem rpmioGetPool(rpmioPool pool, size_t size)
Get unused item from pool, or alloc a new item.
Definition: rpmmalloc.c:220
#define N_(Text)
Definition: system.h:531
int rpmdsRpmlib(rpmds *dsp, void *tblp)
Load rpmlib provides into a dependency set.
Definition: rpmds.c:1587
int rpmdsCompare(const rpmds A, const rpmds B)
Compare two versioned dependency ranges, looking for overlap.
Definition: rpmds.c:4044
int argvCount(const ARGV_t argv)
Return no.
Definition: argv.c:71
int rpmdsFind(rpmds ds, const rpmds ods)
Find a dependency set element using binary search.
Definition: rpmds.c:998
const char const bson * data
Definition: mongo.h:463
rpmTagData p
Definition: rpmtag.h:506
void * rpmdsSetEVRparse(rpmds ds, int(*EVRparse)(const char *evrstr, EVR_t evr))
Definition: rpmds.c:766
ARGV_t argvFree(ARGV_t argv)
Destroy an argv array.
Definition: argv.c:44
struct miRE_s * miRE
Definition: mire.h:60
int _rpmds_debug
Definition: rpmds.c:123
void rpmdsNotify(rpmds ds, const char *where, int rc)
Notify of results of dependency match.
Definition: rpmds.c:899
const char * rpmdsEVR(const rpmds ds)
Return current dependency epoch-version-release.
Definition: rpmds.c:680
const char * tagName(rpmTag tag)
Return tag name from value.
Definition: tagname.c:436
char * memchr()
const char * name
Definition: rpmds.c:1242
const int call_name
Definition: rpmds.c:1818
static int rpmdsCpuinfoCtagFlags(const char *name)
Return dependency format to use for a cpuinfo line.
Definition: rpmds.c:1291
static const char * _ldconfig_cache
Definition: rpmds.c:3508
int rpmdsNext(rpmds ds)
Return next dependency set iterator index.
Definition: rpmds.c:912
Structure(s) used for dependency tag sets.
static const char * _perldeps_cmd
Definition: rpmds.c:3856
const char * featureEVR
Definition: rpmds.c:1445
int _rpmds_nopromote
Definition: rpmds.c:126
The FD_t File Handle data structure.
static int rpmdsNAcmp(rpmds A, rpmds B)
Definition: rpmds.c:3991
const char * rpmGenPath(const char *urlroot, const char *urlmdir, const char *urlfile)
Merge 3 args into path, any or all of which may be a url.
Definition: macro.c:3491
static struct rpmlibProvides_s rpmlibProvides[]
Definition: rpmds.c:1452
int argvAdd(ARGV_t *argvp, ARGstr_t val)
Add a string to an argv array.
Definition: argv.c:199
rpmuint32_t rpmdsSetRefs(const rpmds ds, rpmuint32_t refs)
Set current dependency file refs.
Definition: rpmds.c:850
rpmTagCount c
Definition: rpmtag.h:507
#define _GETCONF_PATH
Definition: rpmds.c:2711
Header headerFree(Header h)
Dereference a header instance.
char * rpmExpand(const char *arg,...)
Return (malloc'ed) concatenated macro expansion(s).
Definition: macro.c:3252
int rpmdsCount(const rpmds ds)
Return dependency set count.
Definition: rpmds.c:636
static struct cpuinfo_s ctags[]
Definition: rpmds.c:1248
int rpmdsAnyMatchesDep(const Header h, const rpmds req, int nopromote)
Compare package provides dependencies from header with a single dependency.
Definition: rpmds.c:4228
char * rpmdsNewDNEVR(const char *dspfx, rpmds ds)
Return new formatted dependency string.
Definition: rpmds.c:434
static rpmds rpmdsDup(const rpmds ods)
Definition: rpmds.c:954
const char * rpmdsN(const rpmds ds)
Return current dependency name.
Definition: rpmds.c:668
int Fclose(FD_t fd)
fclose(3) clone.
Definition: rpmio.c:2534
const char const bson int mongo_write_concern int flags
Definition: mongo.h:485
#define _PERL_PROVIDES
Definition: rpmds.c:3854
Header headerLink(Header h)
Reference a header instance.
static const struct _conf_s vars[]
Definition: rpmds.c:1823
const char * _sysinfo_path
Definition: rpmds.c:1741
int rpmint32_t
Definition: rpmiotypes.h:33
int Ferror(FD_t fd)
ferror(3) clone.
Definition: rpmio.c:2951
Definition: rpmtag.h:502
const char const int i
Definition: bson.h:778
const char * _cpuinfo_path
Definition: rpmds.c:1314
urltype urlPath(const char *url, const char **pathp)
Return path component of URL.
Definition: url.c:430
static int snprintf(char *buf, int nb, const char *fmt,...)
Definition: rpmps.c:220
const char const bson * key
Definition: mongo.h:717
#define _PROC_CPUINFO
Definition: rpmds.c:1310
rpmds rpmdsLink(rpmds ds, const char *msg)
Reference a dependency set instance.
const char * featureDescription
Definition: rpmds.c:1448
int _rpmds_unspecified_epoch_noise
Definition: rpmds.c:130
rpmioPool rpmioNewPool(const char *name, size_t size, int limit, int flags, char *(*dbg)(void *item), void(*init)(void *item), void(*fini)(void *item))
Create a memory pool.
Definition: rpmmalloc.c:109
int rpmdsMerge(rpmds *dsp, rpmds ods)
Merge a dependency set maintaining (N,EVR,Flags) sorted order.
Definition: rpmds.c:1030
char * stpcpy(char *dest, const char *src)
int done
Definition: rpmds.c:1243
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:756
struct rpmiob_s * rpmiob
Definition: rpmiotypes.h:60
int headerNEVRA(Header h, const char **np, const char **ep, const char **vp, const char **rp, const char **ap)
Return name, epoch, version, release, arch strings from header.
Definition: hdrNVR.c:162
const void * fnpyKey
Definition: rpmiotypes.h:134
int flags
Definition: rpmds.c:1244
int rpmdsCpuinfo(rpmds *dsp, const char *fn)
Load /proc/cpuinfo provides into a dependency set.
Definition: rpmds.c:1316
int rpmdsLdconfig(rpmPRCO PRCO, const char *fn)
Load /etc/ld.so.cache provides into a dependency set.
Definition: rpmds.c:3510
int rpmdsUname(rpmds *dsp, const struct utsname *un)
Definition: rpmds.c:3814
static const char * _ldconfig_cmd
Definition: rpmds.c:3504
int rpmdsSearch(rpmds ds, rpmds ods)
Search a sorted dependency set for an element that overlaps.
Definition: rpmds.c:1108
int rpmdsIx(const rpmds ds)
Return dependency set index.
Definition: rpmds.c:641
const char * featureName
Definition: rpmds.c:1443
int rpmdsMergePRCO(void *context, rpmds ds)
Merge provides/requires/conflicts/obsoletes dependencies.
Definition: rpmds.c:2814
int rpmdsMatch(const rpmds A, rpmds B)
Compare A against every member of B, looking for 1st match.
Definition: rpmds.c:4188
rpmuint32_t rpmdsColor(const rpmds ds)
Return current dependency color.
Definition: rpmds.c:789
static int _noisy_range_comparison_debug_message
Enable noisy range comparison debugging message?
Definition: rpmds.c:120
const char char type
Definition: bson.h:908
int rpmnsParse(const char *s, rpmns ns)
Expand and split NS(N).A string into namespace, name and arch components.
Definition: rpmns.c:242
uint32_t ui
Definition: db3.c:46
int rpmdsELF(const char *fn, int flags, int(*add)(void *context, rpmds ds), void *context)
Return a soname dependency constructed from an elf string.
Definition: rpmds.c:2952
static const char * rpmdsEVRorder(void)
Return precedence permutation string.
Definition: rpmds.c:4024
static const char * name
const char * name
Definition: rpmds.c:1817
#define _(Text)
Definition: system.h:29
#define xmalloc
Definition: system.h:32
#define RPMELF_FLAG_SKIPPROVIDES
Definition: rpmds.h:620
ARGstr_t * ARGV_t
Definition: argv.h:12
enum rpmTag_e rpmTag
Definition: rpmtag.h:470
int rpmdsNInclude(const rpmds ds)
Return no.
Definition: rpmds.c:834
rpmuint32_t rpmdsRefs(const rpmds ds)
Return current dependency file refs.
Definition: rpmds.c:839
#define D_(Text)
Definition: system.h:526
rpmds rpmdsNew(Header h, rpmTag tagN, int flags)
Create and load a dependency set.
Definition: rpmds.c:238
int rpmdsSetNoPromote(rpmds ds, int nopromote)
Set "Don't promote Epoch:" flag.
Definition: rpmds.c:755
_conf_e
Definition: rpmds.c:1814
Definition: db3.c:44
int rpmdsSetIx(rpmds ds, int ix)
Set dependency set index.
Definition: rpmds.c:646
static rpmds rpmdsGetPool(rpmioPool pool)
Definition: rpmds.c:193
int rpmExpandNumeric(const char *arg)
Return macro expansion as a numeric value.
Definition: macro.c:3326
rpmds rpmdsThis(Header h, rpmTag tagN, evrFlags Flags)
Create, load and initialize a dependency for this header.
Definition: rpmds.c:513
const char * _rpmns_N_at_A
Definition: rpmns.c:49
static const char ** rpmdsDupArgv(const char **argv, int argc)
Definition: rpmds.c:210
int rpmdsNegateRC(const rpmds ds, int rc)
Negate return code for negated comparisons.
Definition: rpmds.c:4361
rpmint32_t rpmdsSetResult(const rpmds ds, rpmint32_t result)
Set current dependency comparison result.
Definition: rpmds.c:880
int j
Definition: mongo.h:438
const char * ns
Definition: mongo.h:326
rpmds rpmdsFromPRCO(rpmPRCO PRCO, rpmTag tagN)
Retrieve a dependency set from container.
Definition: rpmds.c:2901