rpm  5.4.10
depends.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 
7 #include <rpmio.h>
8 #include <rpmiotypes.h> /* XXX fnpyKey */
9 #include <rpmcb.h>
10 #include <rpmbf.h>
11 #include <rpmmacro.h> /* XXX rpmExpand("%{_dependency_whiteout}" */
12 #include <envvar.h>
13 #include <ugid.h> /* XXX user()/group() probes */
14 
15 #include <rpmtag.h>
16 #define _RPMDB_INTERNAL /* XXX response cache needs dbiOpen et al. */
17 #include <rpmdb.h>
18 
19 #define _RPMEVR_INTERNAL
20 #include <rpmds.h>
21 #include <rpmfi.h>
22 
23 #define _RPMTE_INTERNAL
24 #include <rpmte.h>
25 #define _RPMTS_INTERNAL
26 #include <rpmcli.h> /* XXX rpmcliPackagesTotal */
27 
28 #include "debug.h"
29 
30 /*@access tsortInfo @*/
31 /*@access rpmte @*/ /* XXX for install <-> erase associate. */
32 /*@access rpmts @*/
33 /*@access rpmDiskSpaceInfo @*/
34 
35 #define CACHE_DEPENDENCY_RESULT 1
36 #if defined(CACHE_DEPENDENCY_RESULT)
37 /*@unchecked@*/
39 #endif
40 
41 /*@observer@*/ /*@unchecked@*/
42 const char *rpmNAME = PACKAGE;
43 
44 /*@observer@*/ /*@unchecked@*/
45 const char *rpmEVR = VERSION;
46 
47 /*@unchecked@*/
49 
56 static int uintcmp(const void * a, const void * b)
57  /*@requires maxRead(a) == 0 /\ maxRead(b) == 0 @*/
58 {
59  const uint32_t * aptr = (const uint32_t *) a;
60  const uint32_t * bptr = (const uint32_t *) b;
61  int rc;
62  if (*aptr > *bptr)
63  rc = 1;
64  else if (*aptr < *bptr)
65  rc = -1;
66  else
67  rc = 0;
68  return rc;
69 }
70 
80 static int removePackage(rpmts ts, Header h, uint32_t hdrNum,
81  /*@null@*/ int * indexp,
82  /*@exposed@*/ /*@dependent@*/ /*@null@*/ alKey depends)
83  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
84  /*@modifies ts, h, *indexp, rpmGlobalMacroContext, fileSystem, internalState @*/
85 {
86  rpmte p;
87  int xx;
88 
89  /* Filter out duplicate erasures. */
90  if (ts->numRemovedPackages > 0 && ts->removedPackages != NULL) {
91  uint32_t * needle = NULL;
92  needle = (uint32_t *) bsearch(&hdrNum,
93  ts->removedPackages, ts->numRemovedPackages,
94  sizeof(*ts->removedPackages), uintcmp);
95  if (needle != NULL) {
96  /* XXX lastx should be per-call, not per-ts. */
97  if (indexp != NULL)
98  *indexp = needle - ts->removedPackages;
99  return 0;
100  }
101  }
102 
103  if (ts->rbf == NULL) {
104  static size_t n = 10000; /* XXX population estimate */
105  static double e = 1.0e-4;
106  size_t m = 0;
107  size_t k = 0;
108  rpmbfParams(n, e, &m, &k);
109  ts->rbf = rpmbfNew(m, k, 0);
110  }
111 
112  if (ts->numRemovedPackages == ts->allocedRemovedPackages) {
113  ts->allocedRemovedPackages += ts->delta;
114  /* XXX coverity #1035956 */
115  ts->removedPackages = (uint32_t *) xrealloc(ts->removedPackages,
116  sizeof(*ts->removedPackages) * ts->allocedRemovedPackages);
117  }
118 
119 assert(ts->removedPackages != NULL); /* XXX can't happen. */
120  xx = rpmbfAdd(ts->rbf, &hdrNum, sizeof(hdrNum));
121 assert(xx == 0);
122  ts->removedPackages[ts->numRemovedPackages] = hdrNum;
123  ts->numRemovedPackages++;
124  if (ts->numRemovedPackages > 1)
125  qsort(ts->removedPackages, ts->numRemovedPackages,
126  sizeof(*ts->removedPackages), uintcmp);
127 
128  if (ts->orderCount >= ts->orderAlloced) {
129  ts->orderAlloced += (ts->orderCount - ts->orderAlloced) + ts->delta;
130 /*@-type +voidabstract @*/
131  ts->order = (rpmte *) xrealloc(ts->order, sizeof(*ts->order) * ts->orderAlloced);
132 /*@=type =voidabstract @*/
133  }
134 
135  p = rpmteNew(ts, h, TR_REMOVED, NULL, NULL, hdrNum, depends);
136  ts->order[ts->orderCount] = p;
137  ts->numErasedFiles += rpmfiFC(rpmteFI(p, RPMTAG_BASENAMES));
138  if (indexp != NULL)
139  *indexp = ts->orderCount;
140  ts->orderCount++;
141 
142 /*@-nullstate@*/ /* XXX FIX: ts->order[] can be NULL. */
143  return 0;
144 /*@=nullstate@*/
145 }
146 
153 static int rpmHeadersIdentical(Header first, Header second)
154  /*@globals internalState @*/
155  /*@modifies internalState @*/
156 {
157  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
158  const char * one, * two;
159  int rc = 0;
160  int xx;
161 
162  he->tag = RPMTAG_HDRID;
163  xx = headerGet(first, he, 0);
164  one = he->p.str;
165  he->tag = RPMTAG_HDRID;
166  xx = headerGet(second, he, 0);
167  two = he->p.str;
168 
169  if (one && two)
170  rc = ((strcmp(one, two) == 0) ? 1 : 0);
171  else if (one && !two)
172  rc = 0;
173  else if (!one && two)
174  rc = 0;
175  else {
176  /* XXX Headers w/o digests case devolves to NEVR comparison. */
179  rc = rpmdsCompare(A, B);
180  (void)rpmdsFree(A);
181  A = NULL;
182  (void)rpmdsFree(B);
183  B = NULL;
184  }
185  one = _free(one);
186  two = _free(two);
187  return rc;
188 }
189 
190 /*@unchecked@*/
192 /*@unchecked@*/
194 /*@unchecked@*/
196 
205 static int rpmtsAddUpgrades(rpmts ts, rpmte p, rpmuint32_t hcolor, Header h)
206  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
207  /*@modifies ts, p, rpmGlobalMacroContext, fileSystem, internalState @*/
208 {
209  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
210  rpmuint32_t tscolor = rpmtsColor(ts);
211  alKey pkgKey = rpmteAddedKey(p);
212  rpmuint32_t ohcolor;
213  rpmmi mi;
214  Header oh;
215  int xx;
216 
217  if (_upgrade_tag == 0) {
218  const char * t = rpmExpand("%{?_upgrade_tag}", NULL);
219 /*@-mods@*/
220  _upgrade_tag = (!strcmp(t, "name") ? RPMTAG_NAME : RPMTAG_PROVIDENAME);
221 /*@=mods@*/
222  t = _free(t);
223  }
224 
225  mi = rpmtsInitIterator(ts, _upgrade_tag, rpmteN(p), 0);
226  while((oh = rpmmiNext(mi)) != NULL) {
227  int lastx;
228  rpmte q;
229 
230  /* Ignore colored packages not in our rainbow. */
231  ohcolor = hGetColor(oh);
232  if (tscolor && hcolor && ohcolor && !(hcolor & ohcolor))
233  continue;
234 
235  /* Snarf the original install tid & time from older package(s). */
236  he->tag = RPMTAG_ORIGINTID;
237  xx = headerGet(oh, he, 0);
238  if (xx && he->p.ui32p != NULL) {
239  if (p->originTid[0] == 0 || p->originTid[0] > he->p.ui32p[0]
240  || (he->c > 1 && p->originTid[0] == he->p.ui32p[0] && p->originTid[1] > he->p.ui32p[1]))
241  {
242  p->originTid[0] = he->p.ui32p[0];
243  p->originTid[1] = (he->c > 1 ? he->p.ui32p[1] : 0);
244  }
245  he->p.ptr = _free(he->p.ptr);
246  }
247  he->tag = RPMTAG_ORIGINTIME;
248  xx = headerGet(oh, he, 0);
249  if (xx && he->p.ui32p != NULL) {
250  if (p->originTime[0] == 0 || p->originTime[0] > he->p.ui32p[0]
251  || (he->c > 1 && p->originTime[0] == he->p.ui32p[0] && p->originTime[1] > he->p.ui32p[1]))
252  {
253  p->originTime[0] = he->p.ui32p[0];
254  p->originTime[1] = (he->c > 1 ? he->p.ui32p[1] : 0);
255  }
256  he->p.ptr = _free(he->p.ptr);
257  }
258 
259 #if defined(RPM_VENDOR_WINDRIVER)
260  /*
261  * If we're capable of installing multiple colors
262  * but at least one of the packages are white (0), we
263  * further verify the arch is the same (or compatible) to trigger an upgrade
264  * we do have a special case to allow upgrades of noarch w/ a arch package
265  */
266  if (tscolor && (!hcolor || !ohcolor)) {
267  const char * arch;
268  const char * oharch;
269  he->tag = RPMTAG_ARCH;
270  xx = headerGet(h, he, 0);
271  arch = (xx && he->p.str != NULL ? he->p.str : NULL);
272  he->tag = RPMTAG_ARCH;
273  xx = headerGet(oh, he, 0);
274  oharch = (xx && he->p.str != NULL ? he->p.str : NULL);
275  if (arch != NULL && oharch != NULL) {
276  if (strcmp("noarch", arch) || strcmp("noarch", oharch)) {
277  if (!_isCompatibleArch(arch, oharch)) {
278  arch = _free(arch);
279  oharch = _free(oharch);
280  continue;
281  }
282  }
283  }
284  arch = _free(arch);
285  oharch = _free(oharch);
286  }
287 #endif
288 
289  /* Skip identical packages. */
290  if (rpmHeadersIdentical(h, oh))
291  continue;
292 
293  /* Create an erasure element. */
294  lastx = -1;
295  xx = removePackage(ts, oh, rpmmiInstance(mi), &lastx, pkgKey);
296 assert(lastx >= 0 && lastx < ts->orderCount);
297  q = ts->order[lastx];
298 
299  /* Chain through upgrade flink. */
300  xx = rpmteChain(p, q, oh, "Upgrades");
301 
302 /*@-nullptrarith@*/
303  rpmlog(RPMLOG_DEBUG, D_(" upgrade erases %s\n"), rpmteNEVRA(q));
304 /*@=nullptrarith@*/
305 
306  }
307  mi = rpmmiFree(mi);
308 
309  return 0;
310 }
311 
318 static inline int chkSuffix(const char * fn, const char * suffix)
319  /*@*/
320 {
321  size_t flen = strlen(fn);
322  size_t slen = strlen(suffix);
323  return (flen > slen && !strcmp(fn + flen - slen, suffix));
324 }
325 
334 static int rpmtsEraseDebuginfo(rpmts ts, rpmte p, Header h,
335  /*@exposed@*/ /*@dependent@*/ /*@null@*/ alKey pkgKey)
336  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
337  /*@modifies ts, p, rpmGlobalMacroContext, fileSystem, internalState @*/
338 {
339  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
340  const void *keyval = NULL;
341  size_t keylen = 0;
342  size_t nrefs = 0;
343  rpmuint32_t debuginfoInstance = 0;
344  Header debuginfoHeader = NULL;
345  rpmmi mi;
346  Header oh;
347  int xx;
348 
349  /* XXX SOURCEPKGID is not populated reliably, do not use (yet). */
350  if (_debuginfo_tag == 0) {
351  const char * t = rpmExpand("%{?_debuginfo_tag}", NULL);
352 /*@-mods@*/
353  _debuginfo_tag = (*t != '\0' && !strcmp(t, "pkgid")
355 /*@=mods@*/
356  t = _free(t);
357  }
358 
359  /* Grab the retrieval key. */
360  switch (_debuginfo_tag) {
361  default: return 0; /*@notreached@*/ break;
362  case RPMTAG_SOURCERPM: keyval = rpmteSourcerpm(p); break;
363  }
364 
365  /* Count remaining members in build set, excluding -debuginfo (if any). */
366  mi = rpmtsInitIterator(ts, _debuginfo_tag, keyval, keylen);
367  xx = rpmmiPrune(mi, ts->removedPackages, ts->numRemovedPackages, 1);
368  while((oh = rpmmiNext(mi)) != NULL) {
369  /* Skip identical packages. */
370  if (rpmHeadersIdentical(h, oh))
371  continue;
372 
373  he->tag = RPMTAG_NAME;
374  xx = headerGet(oh, he, 0);
375  if (!xx || he->p.str == NULL)
376  continue;
377  /* Save the -debuginfo member. */
378  if (chkSuffix(he->p.str, "-debuginfo")) {
379  debuginfoInstance = rpmmiInstance(mi);
380  debuginfoHeader = headerLink(oh);
381  } else
382  nrefs++;
383  he->p.str = _free(he->p.str);
384  }
385  mi = rpmmiFree(mi);
386 
387  /* Remove -debuginfo package when last build member is erased. */
388  if (nrefs == 0 && debuginfoInstance > 0 && debuginfoHeader != NULL) {
389  int lastx = -1;
390  rpmte q;
391 
392  /* Create an erasure element. */
393  lastx = -1;
394  xx = removePackage(ts, debuginfoHeader, debuginfoInstance,
395  &lastx, pkgKey);
396 assert(lastx >= 0 && lastx < ts->orderCount);
397  q = ts->order[lastx];
398 
399  /* Chain through upgrade flink. */
400  /* XXX avoid assertion failure when erasing. */
401  if (pkgKey != RPMAL_NOMATCH)
402  xx = rpmteChain(p, q, oh, "Upgrades");
403 
404 /*@-nullptrarith@*/
405  rpmlog(RPMLOG_DEBUG, D_(" lastref erases %s\n"), rpmteNEVRA(q));
406 /*@=nullptrarith@*/
407 
408  }
409  (void)headerFree(debuginfoHeader);
410  debuginfoHeader = NULL;
411 
412  return (int)nrefs;
413 }
414 
422 static int rpmtsAddObsoletes(rpmts ts, rpmte p, rpmuint32_t hcolor)
423  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
424  /*@modifies ts, p, rpmGlobalMacroContext, fileSystem, internalState @*/
425 {
426  rpmuint32_t tscolor = rpmtsColor(ts);
427  alKey pkgKey = rpmteAddedKey(p);
428  rpmuint32_t ohcolor;
429  rpmds obsoletes;
430  rpmuint32_t dscolor;
431  rpmmi mi;
432  Header oh;
433  int xx;
434 
435  if (_obsolete_tag == 0) {
436  const char *t = rpmExpand("%{?_obsolete_tag}", NULL);
437 /*@-mods@*/
438  _obsolete_tag = (!strcmp(t, "name") ? RPMTAG_NAME : RPMTAG_PROVIDENAME);
439 /*@=mods@*/
440  t = _free(t);
441  }
442 
443  obsoletes = rpmdsLink(rpmteDS(p, RPMTAG_OBSOLETENAME), "Obsoletes");
444  obsoletes = rpmdsInit(obsoletes);
445  if (obsoletes != NULL)
446  while (rpmdsNext(obsoletes) >= 0) {
447  const char * Name;
448 
449  if ((Name = rpmdsN(obsoletes)) == NULL)
450  continue; /* XXX can't happen */
451 
452  /* Ignore colored obsoletes not in our rainbow. */
453 #if 0
454  /* XXX obsoletes are never colored, so this is for future devel. */
455  dscolor = rpmdsColor(obsoletes);
456 #else
457  dscolor = hcolor;
458 #endif
459  if (tscolor && dscolor && !(tscolor & dscolor))
460  continue;
461 
462  /* XXX avoid self-obsoleting packages. */
463  if (!strcmp(rpmteN(p), Name))
464  continue;
465 
466  /* Obsolete containing package if given a file, otherwise provide. */
467  if (Name[0] == '/')
468  mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, Name, 0);
469  else
470  mi = rpmtsInitIterator(ts, _obsolete_tag, Name, 0);
471 
472  xx = rpmmiPrune(mi, ts->removedPackages, ts->numRemovedPackages, 1);
473 
474  while((oh = rpmmiNext(mi)) != NULL) {
475  int lastx;
476  rpmte q;
477 
478  /* Ignore colored packages not in our rainbow. */
479  ohcolor = hGetColor(oh);
480 
481  /* XXX provides *are* colored, effectively limiting Obsoletes:
482  to matching only colored Provides: based on pkg coloring. */
483  if (tscolor && hcolor && ohcolor && !(hcolor & ohcolor))
484  /*@innercontinue@*/ continue;
485 
486  /*
487  * Rpm prior to 3.0.3 does not have versioned obsoletes.
488  * If no obsoletes version info is available, match all names.
489  */
490  if (!(rpmdsEVR(obsoletes) == NULL
491  || rpmdsAnyMatchesDep(oh, obsoletes, _rpmds_nopromote)))
492  /*@innercontinue@*/ continue;
493 
494  /* Create an erasure element. */
495  lastx = -1;
496  xx = removePackage(ts, oh, rpmmiInstance(mi), &lastx, pkgKey);
497 assert(lastx >= 0 && lastx < ts->orderCount);
498  q = ts->order[lastx];
499 
500  /* Chain through obsoletes flink. */
501  xx = rpmteChain(p, q, oh, "Obsoletes");
502 
503 /*@-nullptrarith@*/
504  rpmlog(RPMLOG_DEBUG, D_(" Obsoletes: %s\t\terases %s\n"),
505  rpmdsDNEVR(obsoletes)+2, rpmteNEVRA(q));
506 /*@=nullptrarith@*/
507  }
508  mi = rpmmiFree(mi);
509  }
510  (void)rpmdsFree(obsoletes);
511  obsoletes = NULL;
512 
513  return 0;
514 }
515 
516 #if defined(RPM_VENDOR_WINDRIVER)
517 /* Is "compat" compatible w/ arch? */
518 int _isCompatibleArch(const char * arch, const char * compat)
519 {
520  const char * compatArch = rpmExpand(compat, " %{?_", compat, "_compat_arch}", NULL);
521  const char * p, * pe, * t;
522  int match = 0;
523 
524  /* Hack to ensure iX86 being automatically compatible */
525  if (arch[0] == 'i' && arch[2] == '8' && arch[3] == '6') {
526  if ((arch[0] == compat[0]) &&
527  (arch[2] == compat[2]) &&
528  (arch[3] == compat[3]))
529  match = 1;
530 
531  if (!strcmp(compat, "x86_32"))
532  match = 1;
533  }
534 
535  for ( p = pe = compatArch ; *pe && match == 0 ; ) {
536  while (*p && xisspace(*p)) p++;
537  pe = p ; while (*pe && !xisspace(*pe)) pe++;
538  if (p == pe)
539  break;
540  t = strndup(p, (pe - p));
541  p = pe; /* Advance to next chunk */
542 rpmlog(RPMLOG_DEBUG, D_(" Comparing compat archs %s ? %s\n"), arch, t);
543  if (!strcmp(arch, t))
544  match = 1;
545  t = _free(t);
546  }
547  compatArch = _free(compatArch);
548  return match;
549 }
550 #endif
551 
553  fnpyKey key, int upgrade, rpmRelocation relocs)
554 {
555  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
556  rpmdepFlags depFlags = rpmtsDFlags(ts);
557  rpmuint32_t tscolor = rpmtsColor(ts);
558  rpmuint32_t hcolor;
559  int isSource;
560  int duplicate = 0;
561  rpmtsi pi = NULL; rpmte p;
562  const char * arch = NULL;
563  const char * os = NULL;
564  rpmds oldChk, newChk;
565  alKey pkgKey; /* addedPackages key */
566  int xx;
567  int ec = 0;
568  int rc;
569  int oc;
570 
571  hcolor = hGetColor(h);
572  pkgKey = RPMAL_NOMATCH;
573 
574  /*
575  * Always add source headers.
576  */
577  isSource =
578  (headerIsEntry(h, RPMTAG_SOURCERPM) == 0 &&
579  headerIsEntry(h, RPMTAG_ARCH) != 0);
580  if (isSource) {
581  oc = ts->orderCount;
582  goto addheader;
583  }
584 
585  /*
586  * Check platform affinity of binary packages.
587  */
588  he->tag = RPMTAG_ARCH;
589  xx = headerGet(h, he, 0);
590  arch = he->p.str;
591  he->tag = RPMTAG_OS;
592  xx = headerGet(h, he, 0);
593  os = he->p.str;
594  if (nplatpat > 1) {
595  const char * platform = NULL;
596 
597  /*
598  * If ignore arch, we just set the arch in package platform string to
599  * same as on system so that we're sure that it'll match, same goes for
600  * os as well.
601  */
602  if (rpmExpandNumeric("%{__ignore_arch}") || rpmExpandNumeric("%{__ignore_os}")) {
603  platform = rpmExpand(
604  rpmExpandNumeric("%{__ignore_arch}") ? "%{_target_cpu}" : arch,
605  "-unknown-",
606  rpmExpandNumeric("%{__ignore_os}") ? "%{_target_os}" : os,
607  NULL);
608  } else {
609  he->tag = RPMTAG_PLATFORM;
610  xx = headerGet(h, he, 0);
611  platform = he->p.str;
612  if (!xx || platform == NULL)
613  platform = rpmExpand(arch, "-unknown-", os, NULL);
614  }
615 
616  rc = rpmPlatformScore(platform, platpat, nplatpat);
617 #if defined(RPM_VENDOR_MANDRIVA)
618  /*
619  * If no match on platform tag, we'll try again with arch tag
620  * in case platform tag is inconsistent with it, which is the case
621  * for older noarch sub-packages built (mdvbz#61746).
622  */
623  if(xx && rc <= 0) {
624  platform = _free(platform);
625  platform = rpmExpand(arch, "-unknown-", os, NULL);
626  rc = rpmPlatformScore(platform, platpat, nplatpat);
627  }
628 #endif
629  if (rc <= 0) {
630  rpmps ps = rpmtsProblems(ts);
631  he->tag = RPMTAG_NVRA;
632  xx = headerGet(h, he, 0);
633 assert(he->p.str != NULL);
634 
635  rpmpsAppend(ps, RPMPROB_BADPLATFORM, he->p.str, key,
636  platform, NULL, NULL, 0);
637 
638  /* XXX problem string should be printed by caller instead. */
639  if (rpmIsVerbose()) {
640  const char * msg = rpmProblemString(rpmpsGetProblem(ps, -1));
641  rpmlog(RPMLOG_WARNING, "%s\n", msg);
642  msg = _free(msg);
643  }
644 
645  ps = rpmpsFree(ps);
646  he->p.ptr = _free(he->p.ptr);
647  ec = 1;
648  }
649  platform = _free(platform);
650  if (ec)
651  goto exit;
652  }
653 
654  /*
655  * Always install compatible binary packages.
656  */
657  if (!upgrade) {
658  oc = ts->orderCount;
659  goto addheader;
660  }
661 
662  /*
663  * Check that upgrade package is uniquely newer, replace older if necessary.
664  */
667  /* XXX can't use rpmtsiNext() filter or oc will have wrong value. */
668  for (pi = rpmtsiInit(ts), oc = 0; (p = rpmtsiNext(pi, (rpmElementType)0)) != NULL; oc++) {
669  rpmds ds;
670 
671  /* XXX Only added packages need be checked for dupes here. */
672  if (rpmteType(p) == TR_REMOVED)
673  continue;
674 
675  /* XXX Never check source header NEVRAO. */
676  if (rpmteIsSource(p))
677  continue;
678 
679  if (tscolor) {
680  const char * parch;
681  const char * pos;
682 
683  if (arch == NULL || (parch = rpmteA(p)) == NULL)
684  continue;
685 #if defined(RPM_VENDOR_WINDRIVER)
686  /* XXX hackery for alias matching. */
687  if (!_isCompatibleArch(arch, parch))
688  continue;
689 #else
690  /* XXX hackery for i[3456]86 alias matching. */
691  if (arch[0] == 'i' && arch[2] == '8' && arch[3] == '6') {
692  if (arch[0] != parch[0]) continue;
693  if (arch[2] != parch[2]) continue;
694  if (arch[3] != parch[3]) continue;
695  }
696 #endif
697  else if (strcmp(arch, parch))
698  continue;
699  if (os == NULL || (pos = rpmteO(p)) == NULL)
700  continue;
701 
702  if (strcmp(os, pos))
703  continue;
704  }
705 
706  /* OK, binary rpm's with same arch and os. Check NEVR. */
707  if ((ds = rpmteDS(p, RPMTAG_NAME)) == NULL)
708  continue; /* XXX can't happen */
709 
710  /* If newer NEVRAO already added, then skip adding older. */
711  rc = rpmdsCompare(newChk, ds);
712  if (rc != 0) {
713  const char * pkgNEVR = rpmdsDNEVR(ds);
714  const char * addNEVR = rpmdsDNEVR(oldChk);
715  if (rpmIsVerbose())
717  _("package %s was already added, skipping %s\n"),
718  (pkgNEVR ? pkgNEVR + 2 : "?pkgNEVR?"),
719  (addNEVR ? addNEVR + 2 : "?addNEVR?"));
720  ec = 1;
721  break;
722  }
723 
724  /* If older NEVRAO already added, then replace old with new. */
725  rc = rpmdsCompare(oldChk, ds);
726  if (rc != 0) {
727  const char * pkgNEVR = rpmdsDNEVR(ds);
728  const char * addNEVR = rpmdsDNEVR(newChk);
729  if (rpmIsVerbose())
731  _("package %s was already added, replacing with %s\n"),
732  (pkgNEVR ? pkgNEVR + 2 : "?pkgNEVR?"),
733  (addNEVR ? addNEVR + 2 : "?addNEVR?"));
734  duplicate = 1;
735  pkgKey = rpmteAddedKey(p);
736  break;
737  }
738  }
739  pi = rpmtsiFree(pi);
740  (void)rpmdsFree(oldChk);
741  oldChk = NULL;
742  (void)rpmdsFree(newChk);
743  newChk = NULL;
744 
745  /* If newer (or same) NEVRAO was already added, exit now. */
746  if (ec)
747  goto exit;
748 
749 addheader:
750  if (oc >= ts->orderAlloced) {
751  ts->orderAlloced += (oc - ts->orderAlloced) + ts->delta;
752 /*@-type +voidabstract @*/
753  ts->order = (rpmte *) xrealloc(ts->order, ts->orderAlloced * sizeof(*ts->order));
754 /*@=type =voidabstract @*/
755  }
756 
757  p = rpmteNew(ts, h, TR_ADDED, key, relocs, -1, pkgKey);
758 assert(p != NULL);
759 
760  if (duplicate && oc < ts->orderCount) {
761  ts->numAddedFiles -= rpmfiFC(rpmteFI(ts->order[oc], RPMTAG_BASENAMES));
762 /*@-type -unqualifiedtrans@*/
763  ts->order[oc] = rpmteFree(ts->order[oc]);
764 /*@=type =unqualifiedtrans@*/
765  }
766 
767  ts->order[oc] = p;
768  ts->numAddedFiles += rpmfiFC(rpmteFI(p, RPMTAG_BASENAMES));
769  if (!duplicate) {
770  ts->orderCount++;
772  }
773 
774  pkgKey = rpmalAdd(&ts->addedPackages, pkgKey, rpmteKey(p),
776  rpmteFI(p, RPMTAG_BASENAMES), tscolor);
777  if (pkgKey == RPMAL_NOMATCH) {
778  ts->order[oc] = rpmteFree(ts->order[oc]);
779  ts->teInstall = NULL;
780  ec = 1;
781  goto exit;
782  }
783  (void) rpmteSetAddedKey(p, pkgKey);
784 
785  if (!duplicate) {
786  ts->numAddedPackages++;
787  }
788 
789  ts->teInstall = ts->order[oc];
790 
791  /* XXX rpmgi hack: Save header in transaction element if requested. */
792  if (upgrade & 0x2)
793  (void) rpmteSetHeader(p, h);
794 
795  /* If not upgrading, then we're done. */
796  if (!(upgrade & 0x1))
797  goto exit;
798 
799  /* If source rpm, then we're done. */
800  if (isSource)
801  goto exit;
802 
803  /* Do lazy (readonly?) open of rpm database. */
804  if (rpmtsGetRdb(ts) == NULL && rpmtsDBMode(ts) != -1) {
805  if ((ec = rpmtsOpenDB(ts, rpmtsDBMode(ts)) != 0))
806  goto exit;
807  }
808 
809  /* Add upgrades to the transaction (if not disabled). */
810  if (!(depFlags & RPMDEPS_FLAG_NOUPGRADE)) {
811  /*
812  * Don't upgrade -debuginfo until build set is empty.
813  *
814  * XXX Almost, but not quite, correct since the test depends on
815  * added package arrival order.
816  * I.e. -debuginfo additions must always follow all
817  * other additions so that erasures of other members in the
818  * same build set are seen if/when included in the same transaction.
819  */
820  xx = rpmtsEraseDebuginfo(ts, p, h, pkgKey);
821  if (!chkSuffix(rpmteN(p), "-debuginfo") || xx == 0)
822  xx = rpmtsAddUpgrades(ts, p, hcolor, h);
823  }
824 
825  /* Add Obsoletes: to the transaction (if not disabled). */
826  if (!(depFlags & RPMDEPS_FLAG_NOOBSOLETES)) {
827  xx = rpmtsAddObsoletes(ts, p, hcolor);
828  }
829 
830  ec = 0;
831 
832 exit:
833  arch = _free(arch);
834  os = _free(os);
835  pi = rpmtsiFree(pi);
836  return ec;
837 }
838 
839 int rpmtsAddEraseElement(rpmts ts, Header h, uint32_t hdrNum)
840 {
841  int oc = -1;
842  int rc = removePackage(ts, h, hdrNum, &oc, RPMAL_NOMATCH);
843  if (rc == 0 && oc >= 0 && oc < ts->orderCount) {
844  (void) rpmtsEraseDebuginfo(ts, ts->order[oc], h, RPMAL_NOMATCH);
845  ts->teErase = ts->order[oc];
846  } else
847  ts->teErase = NULL;
848  return rc;
849 }
850 
851 /*@only@*/ /*@null@*/ /*@unchecked@*/
852 static char *sysinfo_path = NULL;
853 
854 /*@refcounted@*/ /*@null@*/ /*@unchecked@*/
855 static rpmds rpmlibP = NULL;
856 /*@refcounted@*/ /*@null@*/ /*@unchecked@*/
858 /*@refcounted@*/ /*@null@*/ /*@unchecked@*/
859 static rpmds getconfP = NULL;
860 /*@refcounted@*/ /*@null@*/ /*@unchecked@*/
861 static rpmds unameP = NULL;
862 
863 void rpmnsClean(void)
864  /*@globals sysinfo_path, _sysinfo_path, rpmlibP, cpuinfoP, getconfP, unameP @*/
865  /*@modifies sysinfo_path, _sysinfo_path, rpmlibP, cpuinfoP, getconfP, unameP @*/
866 {
867  (void)rpmdsFree(rpmlibP);
868  rpmlibP = NULL;
869  (void)rpmdsFree(cpuinfoP);
870  cpuinfoP = NULL;
871  (void)rpmdsFree(getconfP);
872  getconfP = NULL;
873  (void)rpmdsFree(unameP);
874  unameP = NULL;
875 /*@-observertrans@*/
877 /*@=observertrans@*/
879 }
880 
888 static int unsatisfiedDepend(rpmts ts, rpmds dep, int adding)
889  /*@globals _cacheDependsRC, rpmGlobalMacroContext, h_errno,
890  sysinfo_path, fileSystem, internalState @*/
891  /*@modifies ts, dep, _cacheDependsRC, rpmGlobalMacroContext,
892  sysinfo_path, fileSystem, internalState @*/
893 {
894  DBT * key = (DBT *) alloca(sizeof(*key));
895  DBT * data = (DBT *) alloca(sizeof(*data));
896  rpmmi mi;
897  nsType NSType;
898  const char * Name;
899  rpmuint32_t Flags;
900  Header h;
901 #if defined(CACHE_DEPENDENCY_RESULT)
902  int _cacheThisRC = 1;
903 #endif
904  int rc;
905  int xx;
906  int retries = 20;
907 
908  if ((Name = rpmdsN(dep)) == NULL)
909  return 0; /* XXX can't happen */
910  Flags = rpmdsFlags(dep);
911  NSType = rpmdsNSType(dep);
912 
913 #if defined(CACHE_DEPENDENCY_RESULT)
914  /*
915  * Check if dbiOpen/dbiPut failed (e.g. permissions), we can't cache.
916  */
917  if (_cacheDependsRC) {
918  dbiIndex dbi;
919  dbi = dbiOpen(rpmtsGetRdb(ts), RPMDBI_DEPCACHE, 0);
920  if (dbi == NULL)
921  _cacheDependsRC = 0;
922  else {
923  const char * DNEVR;
924 
925  rc = -1;
926  if ((DNEVR = rpmdsDNEVR(dep)) != NULL) {
927  DBC * dbcursor = NULL;
928  void * datap = NULL;
929  size_t datalen = 0;
930  size_t DNEVRlen = strlen(DNEVR);
931 
932  xx = dbiCopen(dbi, dbiTxnid(dbi), &dbcursor, 0);
933 
934  memset(key, 0, sizeof(*key));
935 /*@i@*/ key->data = (void *) DNEVR;
936  key->size = DNEVRlen;
937  memset(data, 0, sizeof(*data));
938  data->data = datap;
939  data->size = datalen;
940 /*@-nullstate@*/ /* FIX: data->data may be NULL */
941  xx = dbiGet(dbi, dbcursor, key, data, DB_SET);
942 /*@=nullstate@*/
943  DNEVR = (char *) key->data;
944  DNEVRlen = key->size;
945  datap = data->data;
946  datalen = data->size;
947 
948  if (xx == 0 && datap && datalen == 4)
949  memcpy(&rc, datap, datalen);
950  xx = dbiCclose(dbi, dbcursor, 0);
951  }
952 
953  if (rc >= 0) {
954  rpmdsNotify(dep, _("(cached)"), rc);
955  return rpmdsNegateRC(dep, rc);
956  }
957  }
958  }
959 #endif
960 
961 retry:
962  rc = 0; /* assume dependency is satisfied */
963 
964  /* Expand macro probe dependencies. */
965  if (NSType == RPMNS_TYPE_FUNCTION) {
966  xx = rpmExpandNumeric(Name);
967  rc = (xx ? 0 : 1);
968  if (Flags & RPMSENSE_MISSINGOK)
969  goto unsatisfied;
970  rpmdsNotify(dep, _("(function probe)"), rc);
971  goto exit;
972  }
973 
974  /* Evaluate user/group lookup probes. */
975  if (NSType == RPMNS_TYPE_USER) {
976  const char *s;
977  uid_t uid = 0;
978  s = Name; while (*s && xisdigit(*s)) s++;
979 
980  if (*s)
981  xx = unameToUid(Name, &uid);
982  else {
983  uid = strtol(Name, NULL, 10);
984  xx = (uidToUname(uid) ? 0 : -1);
985  }
986  rc = (xx >= 0 ? 0 : 1);
987  if (Flags & RPMSENSE_MISSINGOK)
988  goto unsatisfied;
989  rpmdsNotify(dep, _("(user lookup)"), rc);
990  goto exit;
991  }
992  if (NSType == RPMNS_TYPE_GROUP) {
993  const char *s;
994  gid_t gid = 0;
995  s = Name; while (*s && xisdigit(*s)) s++;
996 
997  if (*s)
998  xx = gnameToGid(Name, &gid);
999  else {
1000  gid = strtol(Name, NULL, 10);
1001  xx = (gidToGname(gid) ? 0 : -1);
1002  }
1003  rc = (xx >= 0 ? 0 : 1);
1004  if (Flags & RPMSENSE_MISSINGOK)
1005  goto unsatisfied;
1006  rpmdsNotify(dep, _("(group lookup)"), rc);
1007  goto exit;
1008  }
1009 
1010  /* Evaluate access(2) probe dependencies. */
1011  if (NSType == RPMNS_TYPE_ACCESS) {
1012  rc = rpmioAccess(Name, NULL, X_OK);
1013  if (Flags & RPMSENSE_MISSINGOK)
1014  goto unsatisfied;
1015  rpmdsNotify(dep, _("(access probe)"), rc);
1016  goto exit;
1017  }
1018 
1019  /* Evaluate mtab lookup and diskspace probe dependencies. */
1020  if (NSType == RPMNS_TYPE_MOUNTED) {
1021  const char ** fs = NULL;
1022  int nfs = 0;
1023  int i = 0;
1024 
1025  xx = rpmtsInitDSI(ts);
1026  fs = ts->filesystems;
1027  nfs = ts->filesystemCount;
1028 
1029  if (fs != NULL)
1030  for (i = 0; i < nfs; i++) {
1031  if (!strcmp(fs[i], Name))
1032  break;
1033  }
1034  rc = (i < nfs ? 0 : 1);
1035  if (Flags & RPMSENSE_MISSINGOK)
1036  goto unsatisfied;
1037  rpmdsNotify(dep, _("(mtab probe)"), rc);
1038  goto exit;
1039  }
1040 
1041  if (NSType == RPMNS_TYPE_DISKSPACE) {
1042  size_t nb = strlen(Name);
1043  rpmDiskSpaceInfo dsi = NULL;
1044  const char ** fs = NULL;
1045  size_t fslen = 0, longest = 0;
1046  int nfs = 0;
1047  int i = 0;
1048 
1049  xx = rpmtsInitDSI(ts);
1050  fs = ts->filesystems;
1051  nfs = ts->filesystemCount;
1052 
1053  if (fs != NULL)
1054  for (i = 0; i < nfs; i++) {
1055  fslen = strlen(fs[i]);
1056  if (fslen > nb)
1057  continue;
1058  if (strncmp(fs[i], Name, fslen))
1059  continue;
1060  if (fslen > 1 && Name[fslen] != '/' && Name[fslen] != '\0')
1061  continue;
1062  if (fslen < longest)
1063  continue;
1064  longest = fslen;
1065  dsi = ts->dsi + i;
1066  }
1067  if (dsi == NULL)
1068  rc = 1; /* no mounted paths !?! */
1069  else {
1070  char * end = NULL;
1071 /*@-unrecog@*/
1072  rpmuint64_t needed = strtoll(rpmdsEVR(dep), &end, 0);
1073 /*@=unrecog@*/
1074 
1075  if (end && *end) {
1076  if (strchr("Gg", end[0]) && strchr("Bb", end[1]) && !end[2])
1077  needed *= 1024 * 1024 * 1024;
1078  if (strchr("Mm", end[0]) && strchr("Bb", end[1]) && !end[2])
1079  needed *= 1024 * 1024;
1080  if (strchr("Kk", end[0]) && strchr("Bb", end[1]) && !end[2])
1081  needed *= 1024;
1082  } else
1083  needed *= 1024 * 1024; /* XXX assume Mb if no units given */
1084 
1085  needed = BLOCK_ROUND(needed, dsi->f_bsize);
1086  xx = (dsi->f_bavail - needed);
1087  if ((Flags & RPMSENSE_LESS) && xx < 0) rc = 0;
1088  else if ((Flags & RPMSENSE_GREATER) && xx > 0) rc = 0;
1089  else if ((Flags & RPMSENSE_EQUAL) && xx == 0) rc = 0;
1090  else rc = 1;
1091  }
1092  if (Flags & RPMSENSE_MISSINGOK)
1093  goto unsatisfied;
1094  rpmdsNotify(dep, _("(diskspace probe)"), rc);
1095  goto exit;
1096  }
1097 
1098  if (NSType == RPMNS_TYPE_DIGEST) {
1099  const char * EVR = rpmdsEVR(dep);
1100  const char *filename;
1101  pgpHashAlgo digestHashAlgo;
1102  FD_t fd;
1103  char *cp;
1104  pgpHashAlgo algo;
1105 
1106  filename = Name;
1107  digestHashAlgo = PGPHASHALGO_MD5;
1108  if ((cp = (char *) strchr(filename, ':')) != NULL) {
1109  if ((algo = pgpHashAlgoStringToNumber(filename, cp-filename)) != PGPHASHALGO_ERROR) {
1110  digestHashAlgo = algo;
1111  filename = cp + 1;
1112  }
1113  }
1114  rc = 1; /* XXX assume failure */
1115  fd = Fopen(filename, "r.fdio");
1116  if (fd && !Ferror(fd)) {
1117  DIGEST_CTX ctx = rpmDigestInit(digestHashAlgo, RPMDIGEST_NONE);
1118  const char * digest = NULL;
1119  size_t digestlen = 0;
1120  int asAscii = 1;
1121  size_t nbuf = 8 * BUFSIZ;
1122  char * buf = (char *) alloca(nbuf);
1123  size_t nb;
1124 
1125  while ((nb = Fread(buf, sizeof(buf[0]), nbuf, fd)) > 0)
1126  xx = rpmDigestUpdate(ctx, buf, nb);
1127  xx = Fclose(fd); fd = NULL;
1128  xx = rpmDigestFinal(ctx, &digest, &digestlen, asAscii);
1129 
1130  xx = (EVR && *EVR && digest && *digest) ? strcasecmp(EVR, digest) : -1;
1131  /* XXX only equality makes sense for digest compares */
1132  if ((Flags & RPMSENSE_EQUAL) && xx == 0) rc = 0;
1133  }
1134  if (Flags & RPMSENSE_MISSINGOK)
1135  goto unsatisfied;
1136  rpmdsNotify(dep, _("(digest probe)"), rc);
1137  goto exit;
1138  }
1139 
1140  if (NSType == RPMNS_TYPE_SIGNATURE) {
1141  const char * EVR = rpmdsEVR(dep);
1142  ARGV_t avN = NULL;
1143  ARGV_t avEVR = NULL;
1144  rpmRC res;
1145 
1146  /* Split /fn:/sig */
1147  xx = argvSplit(&avN, Name, ":");
1148 
1149  /* Split /pub:id */
1150  xx = (EVR && *EVR) ? argvSplit(&avEVR, EVR, ":") : argvAdd(&avEVR, "");
1151 
1152  res = rpmnsProbeSignature(ts, avN[0], avN[1], avEVR[0], avEVR[1], 0);
1153  rc = (res == RPMRC_OK ? 0 : 1);
1154 
1155  avN = argvFree(avN);
1156  avEVR = argvFree(avEVR);
1157 
1158  if (Flags & RPMSENSE_MISSINGOK)
1159  goto unsatisfied;
1160  rpmdsNotify(dep, _("(signature probe)"), rc);
1161  goto exit;
1162  }
1163 
1164  if (NSType == RPMNS_TYPE_VERIFY) {
1165  QVA_t qva = (QVA_t) memset(alloca(sizeof(*qva)), 0, sizeof(*qva));
1166 
1167  qva->qva_mode = 'v';
1168  qva->qva_flags = (rpmQueryFlags)
1170  rc = 0; /* assume success */
1171  if (rpmtsGetRdb(ts) != NULL) {
1172  if (!strcmp(Name, "*")) /* -Va probe */
1173  mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
1174  else if (Name[0] == '/') /* -Vf probe */
1175  mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, Name, 0);
1176  else /* -V probe */
1177  mi = rpmtsInitIterator(ts, RPMTAG_PROVIDENAME, Name, 0);
1178  while ((h = rpmmiNext(mi)) != NULL) {
1179  if (!(Name[0] == '/' || !strcmp(Name, "*")))
1180  if (!rpmdsAnyMatchesDep(h, dep, _rpmds_nopromote))
1181  continue;
1182  xx = (showVerifyPackage(qva, ts, h) ? 1 : 0);
1183  if (xx)
1184  rc = 1;
1185  }
1186  mi = rpmmiFree(mi);
1187  }
1188 
1189  if (Flags & RPMSENSE_MISSINGOK)
1190  goto unsatisfied;
1191  rpmdsNotify(dep, _("(verify probe)"), rc);
1192  goto exit;
1193  }
1194 
1195  if (NSType == RPMNS_TYPE_GNUPG) {
1196  const char * EVR = rpmdsEVR(dep);
1197  if (!(EVR && *EVR)) {
1198  static const char gnupg_pre[] = "%(%{__gpg} --batch --no-tty --quiet --verify ";
1199  static const char gnupg_post[] = " 2>/dev/null; echo $?)";
1200  const char * t = rpmExpand(gnupg_pre, Name, gnupg_post, NULL);
1201  rc = (t && t[0] == '0') ? 0 : 1;
1202  t = _free(t);
1203  }
1204  else {
1205  static const char gnupg_pre[] = "%(%{__gpg} --batch --no-tty --quiet --verify ";
1206  static const char gnupg_post[] = " 2>&1 | grep '^Primary key fingerprint:' | sed -e 's;^.*: *;;' -e 's; *;;g')";
1207  const char * t = rpmExpand(gnupg_pre, Name, gnupg_post, NULL);
1208  rc = ((Flags & RPMSENSE_EQUAL) && strcasecmp(EVR, t) == 0) ? 0 : 1;
1209  t = _free(t);
1210  }
1211  if (Flags & RPMSENSE_MISSINGOK)
1212  goto unsatisfied;
1213  rpmdsNotify(dep, _("(gnupg probe)"), rc);
1214  goto exit;
1215  }
1216 
1217  if (NSType == RPMNS_TYPE_MACRO) {
1218  static const char macro_pre[] = "%{?";
1219  static const char macro_post[] = ":0}";
1220  const char * a = rpmExpand(macro_pre, Name, macro_post, NULL);
1221 
1222  rc = (a && a[0] == '0') ? 0 : 1;
1223  a = _free(a);
1224  if (Flags & RPMSENSE_MISSINGOK)
1225  goto unsatisfied;
1226  rpmdsNotify(dep, _("(macro probe)"), rc);
1227  goto exit;
1228  }
1229 
1230  if (NSType == RPMNS_TYPE_ENVVAR) {
1231  const char * a = envGet(Name);
1232  const char * b = rpmdsEVR(dep);
1233 
1234  /* Existence test if EVR is missing/empty. */
1235  if (!(b && *b))
1236  rc = (!(a && *a));
1237  else {
1238  int sense = (a && *a) ? strcmp(a, b) : -1;
1239 
1240  if ((Flags & RPMSENSE_SENSEMASK) == RPMSENSE_NOTEQUAL)
1241  rc = (sense == 0);
1242  else if (sense < 0 && (Flags & RPMSENSE_LESS))
1243  rc = 0;
1244  else if (sense > 0 && (Flags & RPMSENSE_GREATER))
1245  rc = 0;
1246  else if (sense == 0 && (Flags & RPMSENSE_EQUAL))
1247  rc = 0;
1248  else
1249  rc = (sense != 0);
1250  }
1251 
1252  if (Flags & RPMSENSE_MISSINGOK)
1253  goto unsatisfied;
1254  rpmdsNotify(dep, _("(envvar probe)"), rc);
1255  goto exit;
1256  }
1257 
1258  if (NSType == RPMNS_TYPE_RUNNING) {
1259  char *t = NULL;
1260  pid_t pid = strtol(Name, &t, 10);
1261 
1262  if (t == NULL || *t != '\0') {
1263  const char * fn = rpmGetPath("%{_varrun}/", Name, ".pid", NULL);
1264  FD_t fd = NULL;
1265 
1266  if (fn && *fn != '%' && (fd = Fopen(fn, "r.fdio")) && !Ferror(fd)) {
1267  char buf[32];
1268  size_t nb = Fread(buf, sizeof(buf[0]), sizeof(buf), fd);
1269 
1270  if (nb > 0)
1271  pid = strtol(buf, &t, 10);
1272  } else
1273  pid = 0;
1274  if (fd != NULL)
1275  (void) Fclose(fd);
1276  fn = _free(fn);
1277  }
1278  rc = (pid > 0 ? (kill(pid, 0) < 0 && errno == ESRCH) : 1);
1279  if (Flags & RPMSENSE_MISSINGOK)
1280  goto unsatisfied;
1281  rpmdsNotify(dep, _("(running probe)"), rc);
1282  goto exit;
1283  }
1284 
1285  if (NSType == RPMNS_TYPE_SANITY) {
1286  /* XXX only the installer does not have the database open here. */
1287  rc = 1; /* assume failure */
1288  if (rpmtsGetRdb(ts) != NULL) {
1289  mi = rpmtsInitIterator(ts, RPMTAG_PROVIDENAME, Name, 0);
1290  while ((h = rpmmiNext(mi)) != NULL) {
1291  if (!rpmdsAnyMatchesDep(h, dep, _rpmds_nopromote))
1292  continue;
1293  rc = (headerIsEntry(h, RPMTAG_SANITYCHECK) == 0);
1294  if (rc == 0) {
1295  /* XXX FIXME: actually run the sanitycheck script. */
1296  break;
1297  }
1298  }
1299  mi = rpmmiFree(mi);
1300  }
1301  if (Flags & RPMSENSE_MISSINGOK)
1302  goto unsatisfied;
1303  rpmdsNotify(dep, _("(sanity probe)"), rc);
1304  goto exit;
1305  }
1306 
1307  if (NSType == RPMNS_TYPE_VCHECK) {
1308  rc = 1; /* assume failure */
1309  if (rpmtsGetRdb(ts) != NULL) {
1310  mi = rpmtsInitIterator(ts, RPMTAG_PROVIDENAME, Name, 0);
1311  while ((h = rpmmiNext(mi)) != NULL) {
1312  if (!rpmdsAnyMatchesDep(h, dep, _rpmds_nopromote))
1313  continue;
1314  rc = (headerIsEntry(h, RPMTAG_TRACK) == 0);
1315  if (rc == 0) {
1316  /* XXX FIXME: actually run the vcheck script. */
1317  break;
1318  }
1319  }
1320  mi = rpmmiFree(mi);
1321  }
1322  if (Flags & RPMSENSE_MISSINGOK)
1323  goto unsatisfied;
1324  rpmdsNotify(dep, _("(vcheck probe)"), rc);
1325  goto exit;
1326  }
1327 
1328  /* Search system configured provides. */
1329  if (sysinfo_path == NULL) {
1330  sysinfo_path = rpmExpand("%{?_rpmds_sysinfo_path}", NULL);
1331  if (!(sysinfo_path != NULL && *sysinfo_path == '/')) {
1333  sysinfo_path = xstrdup(SYSCONFIGDIR "/sysinfo");
1334  }
1335  }
1336 
1337  if (!rpmioAccess(sysinfo_path, NULL, R_OK)) {
1338 #ifdef NOTYET /* XXX just sysinfo Provides: for now. */
1339  rpmTag tagN = (Name[0] == '/' ? RPMTAG_DIRNAMES : RPMTAG_PROVIDENAME);
1340 #else
1341  rpmTag tagN = RPMTAG_PROVIDENAME;
1342 #endif
1343  rpmds P = rpmdsFromPRCO(rpmtsPRCO(ts), tagN);
1344  if (rpmdsSearch(P, dep) >= 0) {
1345  rpmdsNotify(dep, _("(sysinfo provides)"), rc);
1346  goto exit;
1347  }
1348  }
1349 
1350  /*
1351  * New features in rpm packaging implicitly add versioned dependencies
1352  * on rpmlib provides. The dependencies look like "rpmlib(YaddaYadda)".
1353  * Check those dependencies now.
1354  */
1355  if (NSType == RPMNS_TYPE_RPMLIB) {
1356  static int oneshot = -1;
1357 
1358  if (oneshot)
1359  oneshot = rpmdsRpmlib(&rpmlibP, NULL);
1360  if (rpmlibP == NULL)
1361  goto unsatisfied;
1362 
1363  if (rpmdsSearch(rpmlibP, dep) >= 0) {
1364  rpmdsNotify(dep, _("(rpmlib provides)"), rc);
1365  goto exit;
1366  }
1367  goto unsatisfied;
1368  }
1369 
1370  if (NSType == RPMNS_TYPE_CPUINFO) {
1371  static int oneshot = -1;
1372 
1373  if (oneshot && cpuinfoP == NULL)
1374  oneshot = rpmdsCpuinfo(&cpuinfoP, NULL);
1375  if (cpuinfoP == NULL)
1376  goto unsatisfied;
1377 
1378  if (rpmdsSearch(cpuinfoP, dep) >= 0) {
1379  rpmdsNotify(dep, _("(cpuinfo provides)"), rc);
1380  goto exit;
1381  }
1382  goto unsatisfied;
1383  }
1384 
1385  if (NSType == RPMNS_TYPE_GETCONF) {
1386  static int oneshot = -1;
1387 
1388  if (oneshot)
1389  oneshot = rpmdsGetconf(&getconfP, NULL);
1390  if (getconfP == NULL)
1391  goto unsatisfied;
1392 
1393  if (rpmdsSearch(getconfP, dep) >= 0) {
1394  rpmdsNotify(dep, _("(getconf provides)"), rc);
1395  goto exit;
1396  }
1397  goto unsatisfied;
1398  }
1399 
1400  if (NSType == RPMNS_TYPE_UNAME) {
1401  static int oneshot = -1;
1402 
1403  if (oneshot)
1404  oneshot = rpmdsUname(&unameP, NULL);
1405  if (unameP == NULL)
1406  goto unsatisfied;
1407 
1408  if (rpmdsSearch(unameP, dep) >= 0) {
1409  rpmdsNotify(dep, _("(uname provides)"), rc);
1410  goto exit;
1411  }
1412  goto unsatisfied;
1413  }
1414 
1415  if (NSType == RPMNS_TYPE_SONAME) {
1416  rpmds sonameP = NULL;
1417  rpmPRCO PRCO = rpmdsNewPRCO(NULL);
1418  char * fn = strcpy((char *)alloca(strlen(Name)+1), Name);
1419  int flags = 0; /* XXX RPMELF_FLAG_SKIPREQUIRES? */
1420  rpmds ds;
1421 
1422  /* XXX Only absolute paths for now. */
1423  if (*fn != '/')
1424  goto unsatisfied;
1425  fn[strlen(fn)-1] = '\0';
1426 
1427  /* Extract ELF Provides: from /path/to/DSO. */
1428  xx = rpmdsELF(fn, flags, rpmdsMergePRCO, PRCO);
1429  sonameP = rpmdsFromPRCO(PRCO, RPMTAG_PROVIDENAME);
1430  if (!(xx == 0 && sonameP != NULL))
1431  goto unsatisfied;
1432 
1433  /* Search using the original {EVR,"",Flags} from the dep set. */
1434  ds = rpmdsSingle(rpmdsTagN(dep), rpmdsEVR(dep), "", (evrFlags)Flags);
1435  xx = rpmdsSearch(sonameP, ds);
1436  (void)rpmdsFree(ds);
1437  ds = NULL;
1438  PRCO = rpmdsFreePRCO(PRCO);
1439 
1440  /* Was the dependency satisfied? */
1441  if (xx >= 0) {
1442  rpmdsNotify(dep, _("(soname provides)"), rc);
1443  goto exit;
1444  }
1445  goto unsatisfied;
1446  }
1447 
1448  /* Search added packages for the dependency. */
1449  if (rpmalSatisfiesDepend(ts->addedPackages, dep, NULL) != NULL) {
1450 #if defined(CACHE_DEPENDENCY_RESULT)
1451  /*
1452  * XXX Ick, context sensitive answers from dependency cache.
1453  * XXX Always resolve added dependencies within context to disambiguate.
1454  */
1455  if (_rpmds_nopromote)
1456  _cacheThisRC = 0;
1457 #endif
1458  goto exit;
1459  }
1460 
1461  /* XXX only the installer does not have the database open here. */
1462  if (rpmtsGetRdb(ts) != NULL) {
1463  /* XXX Always satisfy Requires: /, SuSE (others?) doesn't package "/" */
1464  if (Name[0] == '/' && Name[1] == '\0') {
1465  rpmdsNotify(dep, _("(root files)"), rc);
1466  goto exit;
1467  }
1468  if (Name[0] == '/') {
1469  mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, Name, 0);
1470  (void) rpmmiPrune(mi,
1471  ts->removedPackages, ts->numRemovedPackages, 1);
1472  while ((h = rpmmiNext(mi)) != NULL) {
1473  rpmdsNotify(dep, _("(db files)"), rc);
1474  mi = rpmmiFree(mi);
1475  goto exit;
1476  }
1477  mi = rpmmiFree(mi);
1478  }
1479 
1480  mi = rpmtsInitIterator(ts, RPMTAG_PROVIDENAME, Name, 0);
1481  (void) rpmmiPrune(mi,
1482  ts->removedPackages, ts->numRemovedPackages, 1);
1483  while ((h = rpmmiNext(mi)) != NULL) {
1484  if (rpmdsAnyMatchesDep(h, dep, _rpmds_nopromote)) {
1485  rpmdsNotify(dep, _("(db provides)"), rc);
1486  mi = rpmmiFree(mi);
1487  goto exit;
1488  }
1489  }
1490  mi = rpmmiFree(mi);
1491  }
1492 
1493  /*
1494  * Search for an unsatisfied dependency.
1495  */
1496  if (adding == 1 && retries > 0 && !(rpmtsDFlags(ts) & RPMDEPS_FLAG_NOSUGGEST)) {
1497  if (ts->solve != NULL) {
1498  xx = (*ts->solve) (ts, dep, ts->solveData);
1499  if (xx == 0)
1500  goto exit;
1501  if (xx == -1) {
1502  retries--;
1503  rpmalMakeIndex(ts->addedPackages);
1504  goto retry;
1505  }
1506  }
1507  }
1508 
1509 unsatisfied:
1510  if (Flags & RPMSENSE_MISSINGOK) {
1511  rc = 0; /* dependency is unsatisfied, but just a hint. */
1512 #if defined(CACHE_DEPENDENCY_RESULT)
1513  _cacheThisRC = 0;
1514 #endif
1515  rpmdsNotify(dep, _("(hint skipped)"), rc);
1516  } else {
1517  rc = 1; /* dependency is unsatisfied */
1518  rpmdsNotify(dep, NULL, rc);
1519  }
1520 
1521 exit:
1522  /*
1523  * If dbiOpen/dbiPut fails (e.g. permissions), we can't cache.
1524  */
1525 #if defined(CACHE_DEPENDENCY_RESULT)
1526  if (_cacheDependsRC && _cacheThisRC) {
1527  dbiIndex dbi;
1528  dbi = dbiOpen(rpmtsGetRdb(ts), RPMDBI_DEPCACHE, 0);
1529  if (dbi == NULL) {
1530  _cacheDependsRC = 0;
1531  } else {
1532  const char * DNEVR;
1533  xx = 0;
1534  if ((DNEVR = rpmdsDNEVR(dep)) != NULL) {
1535  DBC * dbcursor = NULL;
1536  size_t DNEVRlen = strlen(DNEVR);
1537 
1538  xx = dbiCopen(dbi, dbiTxnid(dbi), &dbcursor, DB_WRITECURSOR);
1539 
1540  memset(key, 0, sizeof(*key));
1541 /*@i@*/ key->data = (void *) DNEVR;
1542  key->size = DNEVRlen;
1543  memset(data, 0, sizeof(*data));
1544  data->data = &rc;
1545  data->size = sizeof(rc);
1546 
1547  /*@-compmempass@*/
1548  xx = dbiPut(dbi, dbcursor, key, data, 0);
1549  /*@=compmempass@*/
1550  xx = dbiCclose(dbi, dbcursor, DB_WRITECURSOR);
1551  }
1552  if (xx)
1553  _cacheDependsRC = 0;
1554  }
1555  }
1556 #endif
1557 
1558  return rpmdsNegateRC(dep, rc);
1559 }
1560 
1574 static int checkPackageDeps(rpmts ts, const char * pkgNEVRA,
1575  /*@null@*/ rpmds requires,
1576  /*@null@*/ rpmds conflicts,
1577  /*@null@*/ rpmds dirnames,
1578  /*@null@*/ rpmds linktos,
1579  /*@null@*/ const char * depName,
1580  rpmuint32_t tscolor, int adding)
1581  /*@globals rpmGlobalMacroContext, h_errno,
1582  fileSystem, internalState @*/
1583  /*@modifies ts, requires, conflicts, dirnames, linktos,
1584  rpmGlobalMacroContext, fileSystem, internalState */
1585 {
1586  rpmps ps = rpmtsProblems(ts);
1587  rpmuint32_t dscolor;
1588  const char * Name;
1589  int terminate = 2; /* XXX terminate if rc >= terminate */
1590  int rc;
1591  int ourrc = 0;
1592 #if defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) || defined(RPM_OPTIONAL_DIRNAME_AND_SYMLINK_DEPS) /* optional-dirname-and-symlink-deps */
1593  int dirname_deps;
1594  int symlink_deps;
1595 #endif
1596 
1597  requires = rpmdsInit(requires);
1598  if (requires != NULL)
1599  while (ourrc < terminate && rpmdsNext(requires) >= 0) {
1600 
1601  if ((Name = rpmdsN(requires)) == NULL)
1602  continue; /* XXX can't happen */
1603 
1604  /* Filter out requires that came along for the ride. */
1605  if (depName != NULL && strcmp(depName, Name))
1606  continue;
1607 
1608  /* Ignore colored requires not in our rainbow. */
1609  dscolor = rpmdsColor(requires);
1610  if (tscolor && dscolor && !(tscolor & dscolor))
1611  continue;
1612 
1613  rc = unsatisfiedDepend(ts, requires, adding);
1614 
1615  switch (rc) {
1616  case 0: /* requirements are satisfied. */
1617  /*@switchbreak@*/ break;
1618  case 1: /* requirements are not satisfied. */
1619  { fnpyKey * suggestedKeys = NULL;
1620 
1621  if (ts->availablePackages != NULL) {
1622  suggestedKeys = rpmalAllSatisfiesDepend(ts->availablePackages,
1623  requires, NULL);
1624  }
1625 
1626  rpmdsProblem(ps, pkgNEVRA, requires, suggestedKeys, adding);
1627 
1628  }
1629  ourrc = 1;
1630  /*@switchbreak@*/ break;
1631  case 2: /* something went wrong! */
1632  default:
1633  ourrc = 2;
1634  /*@switchbreak@*/ break;
1635  }
1636  }
1637 
1638  conflicts = rpmdsInit(conflicts);
1639  if (conflicts != NULL)
1640  while (ourrc < terminate && rpmdsNext(conflicts) >= 0) {
1641 
1642  if ((Name = rpmdsN(conflicts)) == NULL)
1643  continue; /* XXX can't happen */
1644 
1645  /* Filter out conflicts that came along for the ride. */
1646  if (depName != NULL && strcmp(depName, Name))
1647  continue;
1648 
1649  /* Ignore colored conflicts not in our rainbow. */
1650  dscolor = rpmdsColor(conflicts);
1651  if (tscolor && dscolor && !(tscolor & dscolor))
1652  continue;
1653 
1654  rc = unsatisfiedDepend(ts, conflicts, adding);
1655 
1656  /* 1 == unsatisfied, 0 == satsisfied */
1657  switch (rc) {
1658  case 0: /* conflicts exist. */
1659  rpmdsProblem(ps, pkgNEVRA, conflicts, NULL, adding);
1660  ourrc = 1;
1661  /*@switchbreak@*/ break;
1662  case 1: /* conflicts don't exist. */
1663  /*@switchbreak@*/ break;
1664  case 2: /* something went wrong! */
1665  default:
1666  ourrc = 2;
1667  /*@switchbreak@*/ break;
1668  }
1669  }
1670 
1671 #if defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) || defined(RPM_OPTIONAL_DIRNAME_AND_SYMLINK_DEPS) /* optional-dirname-and-symlink-deps */
1672  dirname_deps = rpmExpandNumeric("%{?_check_dirname_deps}%{?!_check_dirname_deps:1}");
1673  if (dirname_deps) {
1674 #endif
1675  dirnames = rpmdsInit(dirnames);
1676  if (dirnames != NULL)
1677  while (ourrc < terminate && rpmdsNext(dirnames) >= 0) {
1678 
1679  if ((Name = rpmdsN(dirnames)) == NULL)
1680  continue; /* XXX can't happen */
1681 
1682  /* Filter out dirnames that came along for the ride. */
1683  if (depName != NULL && strcmp(depName, Name))
1684  continue;
1685 
1686  /* Ignore colored dirnames not in our rainbow. */
1687  dscolor = rpmdsColor(dirnames);
1688  if (tscolor && dscolor && !(tscolor & dscolor))
1689  continue;
1690 
1691  rc = unsatisfiedDepend(ts, dirnames, adding);
1692 
1693  switch (rc) {
1694  case 0: /* requirements are satisfied. */
1695  /*@switchbreak@*/ break;
1696  case 1: /* requirements are not satisfied. */
1697  { fnpyKey * suggestedKeys = NULL;
1698 
1699  if (ts->availablePackages != NULL) {
1700  suggestedKeys = rpmalAllSatisfiesDepend(ts->availablePackages,
1701  dirnames, NULL);
1702  }
1703 
1704  rpmdsProblem(ps, pkgNEVRA, dirnames, suggestedKeys, adding);
1705 
1706  }
1707  ourrc = 1;
1708  /*@switchbreak@*/ break;
1709  case 2: /* something went wrong! */
1710  default:
1711  ourrc = 2;
1712  /*@switchbreak@*/ break;
1713  }
1714  }
1715 #if defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) || defined(RPM_OPTIONAL_DIRNAME_AND_SYMLINK_DEPS) /* optional-dirname-and-symlink-deps */
1716  }
1717 
1718  symlink_deps = rpmExpandNumeric("%{?_check_symlink_deps}%{?!_check_symlink_deps:1}");
1719  if (symlink_deps) {
1720 #endif
1721  linktos = rpmdsInit(linktos);
1722  if (linktos != NULL)
1723  while (ourrc < terminate && rpmdsNext(linktos) >= 0) {
1724 
1725  if ((Name = rpmdsN(linktos)) == NULL)
1726  continue; /* XXX can't happen */
1727  if (*Name == '\0') /* XXX most linktos are empty */
1728  continue;
1729 
1730  /* Filter out linktos that came along for the ride. */
1731  if (depName != NULL && strcmp(depName, Name))
1732  continue;
1733 
1734  /* Ignore colored linktos not in our rainbow. */
1735  dscolor = rpmdsColor(linktos);
1736  if (tscolor && dscolor && !(tscolor & dscolor))
1737  continue;
1738 
1739  rc = unsatisfiedDepend(ts, linktos, adding);
1740 
1741  switch (rc) {
1742  case 0: /* requirements are satisfied. */
1743  /*@switchbreak@*/ break;
1744  case 1: /* requirements are not satisfied. */
1745  { fnpyKey * suggestedKeys = NULL;
1746 
1747  if (ts->availablePackages != NULL) {
1748  suggestedKeys = rpmalAllSatisfiesDepend(ts->availablePackages,
1749  linktos, NULL);
1750  }
1751 
1752  rpmdsProblem(ps, pkgNEVRA, linktos, suggestedKeys, adding);
1753 
1754  }
1755  ourrc = 1;
1756  /*@switchbreak@*/ break;
1757  case 2: /* something went wrong! */
1758  default:
1759  ourrc = 2;
1760  /*@switchbreak@*/ break;
1761  }
1762  }
1763 #if defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) || defined(RPM_OPTIONAL_DIRNAME_AND_SYMLINK_DEPS) /* optional-dirname-and-symlink-deps */
1764  }
1765 #endif
1766 
1767  ps = rpmpsFree(ps);
1768  return ourrc;
1769 }
1770 
1781 static int checkPackageSet(rpmts ts, const char * depName,
1782  /*@only@*/ /*@null@*/ rpmmi mi, int adding)
1783  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1784  /*@modifies ts, mi, rpmGlobalMacroContext, fileSystem, internalState @*/
1785 {
1786  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
1787  rpmdepFlags depFlags = rpmtsDFlags(ts);
1788  rpmuint32_t tscolor = rpmtsColor(ts);
1789  int scareMem = 0;
1790  Header h;
1791  int terminate = 2; /* XXX terminate if rc >= terminate */
1792  int ourrc = 0;
1793 
1794  (void) rpmmiPrune(mi,
1795  ts->removedPackages, ts->numRemovedPackages, 1);
1796  while (ourrc < terminate && (h = rpmmiNext(mi)) != NULL) {
1797  rpmds requires = NULL;
1798  rpmds conflicts = NULL;
1799  rpmds dirnames = NULL;
1800  rpmds linktos = NULL;
1801  int rc;
1802 
1803  he->tag = RPMTAG_NVRA;
1804  rc = (headerGet(h, he, 0) ? 0 : 2);
1805  if (rc > ourrc)
1806  ourrc = rc;
1807  if (ourrc >= terminate) {
1808  he->p.str = _free(he->p.str);
1809  break;
1810  }
1811 
1812  if (!(depFlags & RPMDEPS_FLAG_NOREQUIRES))
1813  requires = rpmdsNew(h, RPMTAG_REQUIRENAME, scareMem);
1814  if (!(depFlags & RPMDEPS_FLAG_NOCONFLICTS))
1815  conflicts = rpmdsNew(h, RPMTAG_CONFLICTNAME, scareMem);
1816  if (!(depFlags & RPMDEPS_FLAG_NOPARENTDIRS))
1817  dirnames = rpmdsNew(h, RPMTAG_DIRNAMES, scareMem);
1818  if (!(depFlags & RPMDEPS_FLAG_NOLINKTOS))
1819  linktos = rpmdsNew(h, RPMTAG_FILELINKTOS, scareMem);
1820 
1821  (void) rpmdsSetNoPromote(requires, _rpmds_nopromote);
1822  (void) rpmdsSetNoPromote(conflicts, _rpmds_nopromote);
1823  (void) rpmdsSetNoPromote(dirnames, _rpmds_nopromote);
1824  (void) rpmdsSetNoPromote(linktos, _rpmds_nopromote);
1825 
1826  rc = checkPackageDeps(ts, he->p.str,
1827  requires, conflicts, dirnames, linktos,
1828  depName, tscolor, adding);
1829 
1830  (void)rpmdsFree(linktos);
1831  linktos = NULL;
1832  (void)rpmdsFree(dirnames);
1833  dirnames = NULL;
1834  (void)rpmdsFree(conflicts);
1835  conflicts = NULL;
1836  (void)rpmdsFree(requires);
1837  requires = NULL;
1838  he->p.str = _free(he->p.str);
1839 
1840  if (rc > ourrc)
1841  ourrc = rc;
1842  }
1843  mi = rpmmiFree(mi);
1844 
1845  return ourrc;
1846 }
1847 
1854 static int checkDependentPackages(rpmts ts, const char * depName)
1855  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1856  /*@modifies ts, rpmGlobalMacroContext, fileSystem, internalState @*/
1857 {
1858  int rc = 0;
1859 
1860  /* XXX rpmdb can be closed here, avoid error msg. */
1861  if (rpmtsGetRdb(ts) != NULL) {
1862  rpmmi mi;
1863  mi = rpmtsInitIterator(ts, RPMTAG_REQUIRENAME, depName, 0);
1864  rc = checkPackageSet(ts, depName, mi, 0);
1865  }
1866  return rc;
1867 }
1868 
1875 static int checkDependentConflicts(rpmts ts, const char * depName)
1876  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1877  /*@modifies ts, rpmGlobalMacroContext, fileSystem, internalState @*/
1878 {
1879  int rc = 0;
1880 
1881  /* XXX rpmdb can be closed here, avoid error msg. */
1882  if (rpmtsGetRdb(ts) != NULL) {
1883  rpmmi mi;
1884  mi = rpmtsInitIterator(ts, RPMTAG_CONFLICTNAME, depName, 0);
1885  rc = checkPackageSet(ts, depName, mi, 1);
1886  }
1887 
1888  return rc;
1889 }
1890 
1892 {
1893  const char * depName = NULL;
1894  rpmdepFlags depFlags = rpmtsDFlags(ts);
1895  rpmuint32_t tscolor = rpmtsColor(ts);
1896  rpmmi mi = NULL;
1897  rpmtsi pi = NULL; rpmte p;
1898  int closeatexit = 0;
1899  int xx;
1900  int terminate = 2; /* XXX terminate if rc >= terminate */
1901  int rc = 0;
1902  int ourrc = 0;
1903 
1904 if (_rpmts_debug)
1905 fprintf(stderr, "--> %s(%p) tsFlags 0x%x\n", __FUNCTION__, ts, rpmtsFlags(ts));
1906 
1907  (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_CHECK), 0);
1908 
1909  /* Do lazy, readonly, open of rpm database. */
1910  if (rpmtsGetRdb(ts) == NULL && rpmtsDBMode(ts) != -1) {
1911  rc = (rpmtsOpenDB(ts, rpmtsDBMode(ts)) ? 2 : 0);
1912  closeatexit = (rc == 0);
1913  }
1914  if (rc && (ourrc = rc) >= terminate)
1915  goto exit;
1916 
1917  ts->probs = rpmpsFree(ts->probs);
1918 
1919  rpmalMakeIndex(ts->addedPackages);
1920 
1921  /*
1922  * Look at all of the added packages and make sure their dependencies
1923  * are satisfied.
1924  */
1925  pi = rpmtsiInit(ts);
1926  while (ourrc < terminate && (p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
1927  rpmds provides, requires, conflicts, dirnames, linktos;
1928  rpmfi fi;
1929 
1930 /*@-nullpass@*/ /* FIX: rpmts{A,O} can return null. */
1931  rpmlog(RPMLOG_DEBUG, "========== +++ %s %s/%s 0x%x\n",
1932  rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
1933 /*@=nullpass@*/
1934  requires = (!(depFlags & RPMDEPS_FLAG_NOREQUIRES)
1935  ? rpmteDS(p, RPMTAG_REQUIRENAME) : NULL);
1936  conflicts = (!(depFlags & RPMDEPS_FLAG_NOCONFLICTS)
1937  ? rpmteDS(p, RPMTAG_CONFLICTNAME) : NULL);
1938  /* XXX srpm's don't have directory paths. */
1939  if (p->isSource) {
1940  dirnames = NULL;
1941  linktos = NULL;
1942  } else {
1943  dirnames = (!(depFlags & RPMDEPS_FLAG_NOPARENTDIRS)
1944  ? rpmteDS(p, RPMTAG_DIRNAMES) : NULL);
1945  linktos = (!(depFlags & RPMDEPS_FLAG_NOLINKTOS)
1946  ? rpmteDS(p, RPMTAG_FILELINKTOS) : NULL);
1947  }
1948 
1949  rc = checkPackageDeps(ts, rpmteNEVRA(p),
1950  requires, conflicts, dirnames, linktos,
1951  NULL, tscolor, 1);
1952  if (rc && (ourrc = rc) >= terminate)
1953  break;
1954 
1955  provides = rpmteDS(p, RPMTAG_PROVIDENAME);
1956  provides = rpmdsInit(provides);
1957  if (provides != NULL)
1958  while (ourrc < terminate && rpmdsNext(provides) >= 0) {
1959  depName = _free(depName);
1960  depName = xstrdup(rpmdsN(provides));
1961 
1962 #ifdef NOTYET
1963  if (rpmdsNSType(provides) == RPMNS_TYPE_ENVVAR) {
1964  const char * EVR = rpmdsEVR(provides);
1965  if (rpmdsNegateRC(provides, 0))
1966  EVR = NULL;
1967  if (envPut(depName, EVR));
1968  rc = 2;
1969  } else
1970 #endif
1971 
1972  /* Adding: check provides key against conflicts matches. */
1973  if (checkDependentConflicts(ts, depName))
1974  rc = 1;
1975  }
1976  if (rc && (ourrc = rc) >= terminate)
1977  break;
1978 
1979  fi = rpmteFI(p, RPMTAG_BASENAMES);
1980  fi = rpmfiInit(fi, 0);
1981  while (ourrc < terminate && rpmfiNext(fi) >= 0) {
1982  depName = _free(depName);
1983  depName = xstrdup(rpmfiFN(fi));
1984  /* Adding: check filename against conflicts matches. */
1985  if (checkDependentConflicts(ts, depName))
1986  rc = 1;
1987  }
1988  if (rc && (ourrc = rc) >= terminate)
1989  break;
1990  }
1991  pi = rpmtsiFree(pi);
1992  if (rc && (ourrc = rc) >= terminate)
1993  goto exit;
1994 
1995  /*
1996  * Look at the removed packages and make sure they aren't critical.
1997  */
1998  pi = rpmtsiInit(ts);
1999  while (ourrc < terminate && (p = rpmtsiNext(pi, TR_REMOVED)) != NULL) {
2000  rpmds provides;
2001  rpmfi fi;
2002 
2003 /*@-nullpass@*/ /* FIX: rpmts{A,O} can return null. */
2004  rpmlog(RPMLOG_DEBUG, "========== --- %s %s/%s 0x%x\n",
2005  rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
2006 /*@=nullpass@*/
2007 
2008  provides = rpmteDS(p, RPMTAG_PROVIDENAME);
2009  provides = rpmdsInit(provides);
2010  if (provides != NULL)
2011  while (ourrc < terminate && rpmdsNext(provides) >= 0) {
2012  depName = _free(depName);
2013  depName = xstrdup(rpmdsN(provides));
2014 
2015  /* Erasing: check provides against requiredby matches. */
2016  if (checkDependentPackages(ts, depName))
2017  rc = 1;
2018  }
2019  if (rc && (ourrc = rc) >= terminate)
2020  break;
2021 
2022  fi = rpmteFI(p, RPMTAG_BASENAMES);
2023  fi = rpmfiInit(fi, 0);
2024  while (ourrc < terminate && rpmfiNext(fi) >= 0) {
2025  depName = _free(depName);
2026  depName = xstrdup(rpmfiFN(fi));
2027  /* Erasing: check filename against requiredby matches. */
2028  if (checkDependentPackages(ts, depName))
2029  rc = 1;
2030  }
2031  if (rc && (ourrc = rc) >= terminate)
2032  break;
2033  }
2034  pi = rpmtsiFree(pi);
2035  if (rc && (ourrc = rc) >= terminate)
2036  goto exit;
2037 
2038  /*
2039  * Make sure transaction dependencies are satisfied.
2040  */
2041  { const char * tsNEVRA = "transaction dependencies";
2044  rpmds D = NULL;
2045  rpmds L = NULL;
2046  const char * dep = NULL;
2047  int adding = 2;
2048  tscolor = 0; /* XXX no coloring for transaction dependencies. */
2049  rc = checkPackageDeps(ts, tsNEVRA, R, C, D, L, dep, tscolor, adding);
2050  }
2051  if (rc && (ourrc = rc) >= terminate)
2052  goto exit;
2053 
2054 exit:
2055  mi = rpmmiFree(mi);
2056  pi = rpmtsiFree(pi);
2057  depName = _free(depName);
2058 
2059  (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_CHECK), 0);
2060 
2061  if (closeatexit)
2062  xx = rpmtsCloseDB(ts);
2063 #if defined(CACHE_DEPENDENCY_RESULT)
2064  else if (_cacheDependsRC)
2066 #endif
2067 
2068 #ifdef NOTYET
2069  /* On failed dependencies, perform the autorollback goal (if any). */
2070  { rpmps ps = rpmtsProblems(ts);
2071  if (rc || rpmpsNumProblems(ps) > 0)
2072  (void) rpmtsRollback(ts, RPMPROB_FILTER_NONE, 0, NULL);
2073  ps = rpmpsFree(ps);
2074  }
2075 #endif
2076 
2077  return ourrc;
2078 }
2079 
2080 int (*rpmtsCheck) (rpmts ts)
2081  = _rpmtsCheck;
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
static const char * suffix[]
Definition: rpmgrep.c:188
int rpmmiPrune(rpmmi mi, uint32_t *hdrNums, int nHdrNums, int sorted)
Remove items from set of package instances to iterate.
Definition: rpmdb.c:2449
evrFlags rpmdsFlags(const rpmds ds)
Return current dependency flags.
Definition: rpmds.c:691
int rpmteChain(rpmte p, rpmte q, Header oh, const char *msg)
Chain p <-> q forward/backward transaction element links.
Definition: rpmte.c:682
const char * str
Definition: rpmtag.h:72
rpmTag tag
Definition: rpmtag.h:504
rpmds rpmdsInit(rpmds ds)
Initialize dependency set iterator.
Definition: rpmds.c:943
enum rpmQueryFlags_e rpmQueryFlags
Bit(s) to control rpmQuery() operation, stored in qva_flags.
rpmuint32_t rpmteColor(rpmte te)
Retrieve color bits of transaction element.
Definition: rpmte.c:360
rpmPRCO rpmdsFreePRCO(rpmPRCO PRCO)
Free dependency set(s) container.
Definition: rpmds.c:2853
rpmtime_t rpmswExit(rpmop op, ssize_t rc)
Exit timed operation.
Definition: rpmsw.c:264
int headerIsEntry(Header h, rpmTag tag)
Check if tag is in header.
Definition: header.c:1431
nsType rpmdsNSType(const rpmds ds)
Return dependency class type.
Definition: rpmds.c:738
const char * rpmNAME
Definition: depends.c:42
enum nsType_e nsType
Dependency types.
const char * rpmProblemString(const rpmProblem prob)
Return formatted string representation of a problem.
Definition: rpmps.c:231
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:4497
rpmProblem rpmpsGetProblem(rpmps ps, int num)
Return a problem from problem set.
Definition: rpmps.c:386
rpmte rpmteFree(rpmte te)
Destroy a transaction element.
#define RPMSENSE_SENSEMASK
Definition: rpmevr.h:74
const char * rpmteSourcerpm(rpmte te)
Retrieve sourcerpm string from transaction element.
Definition: rpmte.c:556
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
static int checkDependentPackages(rpmts ts, const char *depName)
Check to-be-erased dependencies against installed requires.
Definition: depends.c:1854
uint32_t rpmmiInstance(rpmmi mi)
Return header instance for current position of rpmdb iterator.
Definition: rpmdb.c:1743
Structures used for an "rpmte" transaction element.
static rpmTag _debuginfo_tag
Definition: depends.c:193
char * xstrdup(const char *str)
Definition: rpmmalloc.c:322
rpmuint32_t * ui32p
Definition: rpmtag.h:69
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
Definition: rpmio.c:2833
int rpmtsAddInstallElement(rpmts ts, Header h, fnpyKey key, int upgrade, rpmRelocation relocs)
Add package to be installed to transaction set.
Definition: depends.c:552
DIGEST_CTX rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
Initialize digest.
Definition: digest.c:244
char * rpmGetPath(const char *path,...)
Return (malloc&#39;ed) expanded, canonicalized, file path.
Definition: macro.c:3310
rpmuint32_t hGetColor(Header h)
Return header color.
Definition: hdrNVR.c:223
int rpmdsGetconf(rpmds *dsp, const char *path)
Load getconf provides into a dependency set.
Definition: rpmds.c:2718
Structure(s) used for file info tag sets.
static int unsatisfiedDepend(rpmts ts, rpmds dep, int adding)
Check dep for an unsatisfied dependency.
Definition: depends.c:888
int headerGet(Header h, HE_t he, unsigned int flags)
Retrieve extension or tag value from a header.
Definition: header.c:2222
const char * rpmEVR
Definition: depends.c:45
int rpmPlatformScore(const char *platform, void *mi_re, int mi_nre)
Definition: rpmrc.c:653
enum pgpHashAlgo_e pgpHashAlgo
9.4.
int nplatpat
Definition: rpmrc.c:46
The Header data structure.
#define DB_SET
Definition: db_emu.h:88
char * gidToGname(gid_t gid)
Definition: ugid.c:171
alKey rpmalAdd(rpmal *alistp, alKey pkgKey, fnpyKey key, rpmds provides, rpmfi fi, rpmuint32_t tscolor)
Add package to available list.
Definition: rpmal.c:213
rpmQueryFlags qva_flags
Definition: rpmcli.h:637
#define VERSION
Definition: config.h:1270
const char * rpmteN(rpmte te)
Retrieve name string of transaction element.
Definition: rpmte.c:316
#define R_OK
Definition: system.h:219
static int checkPackageSet(rpmts ts, const char *depName, rpmmi mi, int adding)
Check dependency against installed packages.
Definition: depends.c:1781
Definition: rpmdb.c:436
int errno
rpmTag rpmdsTagN(const rpmds ds)
Return current dependency type.
Definition: rpmds.c:702
const char * rpmfiFN(rpmfi fi)
Return current file name from file info set.
Definition: rpmfi.c:163
rpmop rpmtsOp(rpmts ts, rpmtsOpX opx)
Retrieve operation timestamp from a transaction set.
Definition: pkgio.c:133
static rpmds rpmlibP
Definition: depends.c:855
static char * sysinfo_path
Definition: depends.c:852
rpmtsi rpmtsiFree(rpmtsi tsi)
Destroy transaction element iterator.
struct rpmtsi_s * rpmtsi
Transaction element iterator.
Definition: rpmte.h:25
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:22
rpmElementType rpmteType(rpmte te)
Retrieve type of transaction element.
Definition: rpmte.c:311
rpmRC rpmtsRollback(rpmts rbts, rpmprobFilterFlags ignoreSet, int running, rpmte rbte)
Rollback a failed transaction.
Definition: transaction.c:2060
const char * rpmdsDNEVR(const rpmds ds)
Return current formatted dependency string.
Definition: rpmds.c:657
const char * rpmteA(rpmte te)
Retrieve arch string of transaction element.
Definition: rpmte.c:345
struct rpmds_s * rpmds
Dependency tag sets from a header, so that a header can be discarded early.
Definition: rpmtypes.h:28
rpmPRCO rpmtsPRCO(rpmts ts)
Get transaction set dependencies.
Definition: rpmts.c:1042
struct rpmPRCO_s * rpmPRCO
Container for commonly extracted dependency set(s).
Definition: rpmtypes.h:33
rpmds rpmteDS(rpmte te, rpmTag tag)
Retrieve dependency tag set from transaction element.
Definition: rpmte.c:573
rpmds rpmdsFree(rpmds ds)
Destroy a dependency set.
static int uintcmp(const void *a, const void *b)
Compare removed package instances (qsort/bsearch).
Definition: depends.c:56
Command line option information.
Definition: rpmcli.h:634
int rpmfiFC(rpmfi fi)
Return file count from file info set.
Definition: rpmfi.c:87
static int rpmtsAddObsoletes(rpmts ts, rpmte p, rpmuint32_t hcolor)
Add Obsoletes: erasures to a transaction set.
Definition: depends.c:422
struct rpmte_s * rpmte
An element of a transaction set, i.e.
Definition: rpmtypes.h:38
static int removePackage(rpmts ts, Header h, uint32_t hdrNum, int *indexp, alKey depends)
Add removed package instance to ordered transaction set.
Definition: depends.c:80
int rpmtsInitDSI(const rpmts ts)
Initialize disk space info for each and every mounted file systems.
Definition: rpmts.c:1065
int rpmpsNumProblems(rpmps ps)
Return number of problems in set.
Definition: rpmps.c:70
int _cacheDependsRC
Definition: depends.c:38
enum evrFlags_e evrFlags
Dependency Attributes.
char * alloca()
alKey rpmteSetAddedKey(rpmte te, alKey npkgKey)
Definition: rpmte.c:520
rpmPRCO rpmdsNewPRCO(Header h)
Create dependency set(s) container.
Definition: rpmds.c:2878
#define RPMSENSE_NOTEQUAL
Definition: rpmevr.h:76
int _rpmts_debug
Definition: rpmts.c:93
enum rpmElementType_e rpmElementType
Transaction element type.
unsigned int rpmuint32_t
Definition: rpmiotypes.h:25
struct _HE_s * HE_t
Definition: rpmtag.h:58
int _rpmtsCheck(rpmts ts)
Definition: depends.c:1891
const char * rpmteNEVR(rpmte te)
Retrieve name-version-release string from transaction element.
Definition: rpmte.c:536
void * data
Definition: db_emu.h:22
void * ptr
Definition: rpmtag.h:66
void rpmnsClean(void)
Clean global name space dependency sets.
Definition: depends.c:863
int rpmDigestUpdate(DIGEST_CTX ctx, const void *data, size_t len)
Update context with next plain text buffer.
Definition: digest.c:907
rpmRC rpmnsProbeSignature(void *_ts, const char *fn, const char *sigfn, const char *pubfn, const char *pubid, int flags)
Verify OpenPGP signature on a file.
Definition: rpmns.c:323
alKey rpmteAddedKey(rpmte te)
Definition: rpmte.c:515
static rpmds unameP
Definition: depends.c:861
rpmfi rpmteFI(rpmte te, rpmTag tag)
Retrieve file info tag set from transaction element.
Definition: rpmte.c:587
int gnameToGid(const char *thisGname, gid_t *gid)
Definition: ugid.c:71
int rpmdsRpmlib(rpmds *dsp, void *tblp)
Load rpmlib provides into a dependency set.
Definition: rpmds.c:1589
static int rpmtsEraseDebuginfo(rpmts ts, rpmte p, Header h, alKey pkgKey)
Add unreferenced debuginfo erasures to a transaction set.
Definition: depends.c:334
#define DB_WRITECURSOR
Definition: db_emu.h:91
struct rpmfi_s * rpmfi
File info tag sets from a header, so that a header can be discarded early.
Definition: rpmfi.h:78
int rpmdsCompare(const rpmds A, const rpmds B)
Compare two versioned dependency ranges, looking for overlap.
Definition: rpmds.c:4347
static int rpmHeadersIdentical(Header first, Header second)
Are two headers identical?
Definition: depends.c:153
#define RPMAL_NOMATCH
Definition: rpmal.h:17
rpmTagData p
Definition: rpmtag.h:507
enum rpmdepFlags_e rpmdepFlags
Bit(s) to control rpmtsCheck() and rpmtsOrder() operation.
static int xisspace(int c)
Definition: rpmiotypes.h:446
unsigned long long rpmuint64_t
Definition: rpmiotypes.h:26
#define X_OK
Definition: system.h:217
ARGV_t argvFree(ARGV_t argv)
Destroy an argv array.
Definition: argv.c:44
int(* rpmtsCheck)(rpmts ts)
Perform dependency resolution on the transaction set.
Definition: depends.c:2080
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
int rpmioAccess(const char *FN, const char *path, int mode)
Check FN access, expanding relative paths and twiddles.
Definition: rpmio.c:3072
static rpmTag _obsolete_tag
Definition: depends.c:195
int rpmdsNext(rpmds ds)
Return next dependency set iterator index.
Definition: rpmds.c:912
Structure(s) used for dependency tag sets.
Digest private data.
Definition: digest.c:127
int rpmdbCloseDBI(rpmdb db, int tag)
Close a single database index.
Definition: rpmdb.c:839
The FD_t File Handle data structure.
rpmmi rpmtsInitIterator(const rpmts ts, rpmTag rpmtag, const void *keyp, size_t keylen)
Return transaction database iterator.
Definition: rpmts.c:212
const char * rpmteNEVRA(rpmte te)
Retrieve name-version-release.arch string from transaction element.
Definition: rpmte.c:541
int argvAdd(ARGV_t *argvp, ARGstr_t val)
Add a string to an argv array.
Definition: argv.c:199
rpmTagCount c
Definition: rpmtag.h:508
Header headerFree(Header h)
Dereference a header instance.
int rpmswEnter(rpmop op, ssize_t rc)
Enter timed operation.
Definition: rpmsw.c:248
char * rpmExpand(const char *arg,...)
Return (malloc&#39;ed) concatenated macro expansion(s).
Definition: macro.c:3117
pgpHashAlgo pgpHashAlgoStringToNumber(const char *name, size_t name_len)
Convert a hash algorithm "foo" to the internal PGPHASHALGO_FOO number.
Definition: rpmpgp.c:1623
void * alKey
An added/available package retrieval key.
Definition: rpmtypes.h:19
static int checkPackageDeps(rpmts ts, const char *pkgNEVRA, rpmds requires, rpmds conflicts, rpmds dirnames, rpmds linktos, const char *depName, rpmuint32_t tscolor, int adding)
Check added requires/conflicts against against installed+added packages.
Definition: depends.c:1574
size_t Fread(void *buf, size_t size, size_t nmemb, FD_t fd)
fread(3) clone.
Definition: rpmio.c:2412
int rpmdsAnyMatchesDep(const Header h, const rpmds req, int nopromote)
Compare package provides dependencies from header with a single dependency.
Definition: rpmds.c:4525
const char * rpmteO(rpmte te)
Retrieve os string of transaction element.
Definition: rpmte.c:350
uint32_t size
Definition: db_emu.h:23
Header rpmteSetHeader(rpmte te, Header h)
Save header into transaction element.
Definition: rpmte.c:298
#define SYSCONFIGDIR
Definition: config.h:1212
const char * rpmdsN(const rpmds ds)
Return current dependency name.
Definition: rpmds.c:668
rpmmi rpmmiFree(rpmmi mi)
Destroy rpm database iterator.
int Fclose(FD_t fd)
fclose(3) clone.
Definition: rpmio.c:2534
#define RPMDBI_DEPCACHE
Definition: rpmtag.h:481
rpmds cpuinfoP
Definition: depends.c:857
rpmte rpmtsiNext(rpmtsi tsi, rpmElementType type)
Return next transaction element of type.
Definition: rpmte.c:831
int showVerifyPackage(QVA_t qva, rpmts ts, Header h)
Display results of package verify.
Definition: verify.c:544
int rpmfiNext(rpmfi fi)
Return next file iterator index.
Definition: rpmfi.c:526
rpmps rpmpsFree(rpmps ps)
Destroy a problem set.
Header headerLink(Header h)
Reference a header instance.
#define CACHE_DEPENDENCY_RESULT
Definition: depends.c:35
rpmdb rpmtsGetRdb(rpmts ts)
Get transaction set database handle.
Definition: pkgio.c:151
const char * _sysinfo_path
Definition: rpmds.c:1743
fnpyKey rpmteKey(rpmte te)
Retrieve key from transaction element.
Definition: rpmte.c:568
enum rpmRC_e rpmRC
RPM return codes.
int Ferror(FD_t fd)
ferror(3) clone.
Definition: rpmio.c:2944
#define L(CS)
Definition: fnmatch.c:155
Definition: rpmtag.h:503
rpmfi rpmfiInit(rpmfi fi, int fx)
Initialize file iterator index.
Definition: rpmfi.c:548
rpmuint32_t rpmtsColor(rpmts ts)
Retrieve color bits of transaction set.
Definition: rpmts.c:1450
Definition: rpmte.h:31
void * platpat
Definition: rpmrc.c:44
static int xisdigit(int c)
Definition: rpmiotypes.h:437
rpmdepFlags rpmtsDFlags(rpmts ts)
Get dependency flags, i.e.
Definition: rpmts.c:1373
fnpyKey rpmalSatisfiesDepend(const rpmal al, const rpmds ds, alKey *keyp)
Check added package file lists for first package that has a provide.
Definition: rpmal.c:480
rpmds rpmdsLink(rpmds ds, const char *msg)
Reference a dependency set instance.
dbiIndex dbiOpen(rpmdb db, rpmTag tag, unsigned int flags)
Definition: rpmdb.c:223
Definition: db_emu.h:72
rpmps rpmtsProblems(rpmts ts)
Return current transaction set problems.
Definition: rpmts.c:582
struct rpmts_s * rpmts
The RPM Transaction Set.
Definition: rpmtypes.h:14
static int checkDependentConflicts(rpmts ts, const char *depName)
Check to-be-added dependencies against installed conflicts.
Definition: depends.c:1875
struct rpmQVKArguments_s * QVA_t
Definition: rpmcli.h:255
int rpmFLAGS
Definition: depends.c:48
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:647
char * uidToUname(uid_t uid)
Definition: ugid.c:135
const void * fnpyKey
Definition: rpmiotypes.h:118
Header rpmmiNext(rpmmi mi)
Return next package header from iteration.
Definition: rpmdb.c:2248
int rpmdsCpuinfo(rpmds *dsp, const char *fn)
Load /proc/cpuinfo provides into a dependency set.
Definition: rpmds.c:1323
static int rpmtsAddUpgrades(rpmts ts, rpmte p, rpmuint32_t hcolor, Header h)
Add upgrade erasures to a transaction set.
Definition: depends.c:205
int rpmcliPackagesTotal
Definition: rpminstall.c:63
static int chkSuffix(const char *fn, const char *suffix)
Check string for a suffix.
Definition: depends.c:318
#define RPMTAG_HDRID
Definition: rpmtag.h:169
int rpmdsUname(rpmds *dsp, const struct utsname *un)
Definition: rpmds.c:4120
int rpmtsAddEraseElement(rpmts ts, Header h, uint32_t hdrNum)
Add package to be erased to transaction set.
Definition: depends.c:839
int rpmdsSearch(rpmds ds, rpmds ods)
Search a sorted dependency set for an element that overlaps.
Definition: rpmds.c:1115
int argvSplit(ARGV_t *argvp, const char *str, const char *seps)
Split a string into an argv array.
Definition: argv.c:233
#define rpmIsVerbose()
Definition: rpmcb.h:21
void rpmalMakeIndex(rpmal al)
Generate index for available list.
Definition: rpmal.c:320
int rpmdsMergePRCO(void *context, rpmds ds)
Merge provides/requires/conflicts/obsoletes dependencies.
Definition: rpmds.c:2816
static rpmTag _upgrade_tag
Definition: depends.c:191
rpmuint32_t rpmdsColor(const rpmds ds)
Return current dependency color.
Definition: rpmds.c:789
int rpmtsOpenDB(rpmts ts, int dbmode)
Open the database used by the transaction.
Definition: rpmts.c:115
fnpyKey * rpmalAllSatisfiesDepend(const rpmal al, const rpmds ds, alKey *keyp)
Check added package file lists for package(s) that have a provide.
Definition: rpmal.c:391
int _rpmds_nopromote
Definition: rpmds.c:126
int rpmDigestFinal(DIGEST_CTX ctx, void *datap, size_t *lenp, int asAscii)
Return digest and destroy context.
Definition: digest.c:921
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:3212
FD_t fd
Definition: rpmspec.h:66
#define _(Text)
Definition: system.h:30
#define PACKAGE
Definition: config.h:1090
rpmtsi rpmtsiInit(rpmts ts)
Create transaction element iterator.
ARGstr_t * ARGV_t
Definition: argv.h:9
Access RPM indices using Berkeley DB interface(s).
enum rpmTag_e rpmTag
Definition: rpmtag.h:471
int unameToUid(const char *thisUname, uid_t *uid)
Definition: ugid.c:16
#define D_(Text)
Definition: system.h:485
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&#39;t promote Epoch:" flag.
Definition: rpmds.c:755
rpmte rpmteNew(const rpmts ts, Header h, rpmElementType type, fnpyKey key, rpmRelocation relocs, uint32_t dboffset, alKey pkgKey)
Create a transaction element.
Definition: rpmte.c:245
rpmtransFlags rpmtsFlags(rpmts ts)
Get transaction flags, i.e.
Definition: rpmts.c:1344
static const char * platform
Definition: rpmrc.c:41
int rpmtsDBMode(rpmts ts)
Retrieve dbmode of transaction set.
Definition: rpmts.c:1435
int rpmtsCloseDB(rpmts ts)
Close the database used by the transaction.
Definition: rpmts.c:101
#define VERIFY_ALL
Definition: rpmcli.h:249
int rpmExpandNumeric(const char *arg)
Return macro expansion as a numeric value.
Definition: macro.c:3191
rpmds rpmdsThis(Header h, rpmTag tagN, evrFlags Flags)
Create, load and initialize a dependency for this header.
Definition: rpmds.c:513
#define RPMDBI_PACKAGES
Pseudo-tags used by the rpmdb and rpmgi iterator API&#39;s.
Definition: rpmtag.h:480
#define xrealloc
Definition: system.h:36
static rpmds getconfP
Definition: depends.c:859
int rpmdsNegateRC(const rpmds ds, int rc)
Negate return code for negated comparisons.
Definition: rpmds.c:4658
int rpmteIsSource(rpmte te)
Retrieve isSource attribute of transaction element.
Definition: rpmte.c:355
struct _dbiIndex * dbiIndex
Definition: rpmdb.h:58
rpmds rpmdsFromPRCO(rpmPRCO PRCO, rpmTag tagN)
Retrieve a dependency set from container.
Definition: rpmds.c:2903