00001
00005 #include "system.h"
00006
00007 #include <rpmcli.h>
00008
00009 #include <rpmmacro.h>
00010
00011 #include "rpmdb.h"
00012
00013 #include "rpmds.h"
00014 #include "rpmfi.h"
00015
00016 #define _RPMTE_INTERNAL
00017 #include "rpmte.h"
00018
00019 #define _RPMTS_INTERNAL
00020 #include "rpmts.h"
00021
00022 #include "debug.h"
00023
00024
00025
00026
00027
00028
00029
00030
00033 typedef struct orderListIndex_s * orderListIndex;
00034
00035
00038 struct orderListIndex_s {
00039
00040 alKey pkgKey;
00041 int orIndex;
00042 };
00043
00044
00045 int _cacheDependsRC = 1;
00046
00047
00048 const char *rpmNAME = PACKAGE;
00049
00050
00051 const char *rpmEVR = VERSION;
00052
00053
00054 int rpmFLAGS = RPMSENSE_EQUAL;
00055
00062 static int intcmp(const void * a, const void * b)
00063
00064 {
00065 const int * aptr = a;
00066 const int * bptr = b;
00067 int rc = (*aptr - *bptr);
00068 return rc;
00069 }
00070
00079 static int removePackage(rpmts ts, Header h, int dboffset,
00080 alKey depends)
00081
00082
00083 {
00084 rpmte p;
00085
00086
00087 if (ts->numRemovedPackages > 0 && ts->removedPackages != NULL) {
00088
00089 if (bsearch(&dboffset, ts->removedPackages, ts->numRemovedPackages,
00090 sizeof(*ts->removedPackages), intcmp) != NULL)
00091 return 0;
00092
00093 }
00094
00095 if (ts->numRemovedPackages == ts->allocedRemovedPackages) {
00096 ts->allocedRemovedPackages += ts->delta;
00097 ts->removedPackages = xrealloc(ts->removedPackages,
00098 sizeof(ts->removedPackages) * ts->allocedRemovedPackages);
00099 }
00100
00101 if (ts->removedPackages != NULL) {
00102
00103 ts->removedPackages[ts->numRemovedPackages] = dboffset;
00104 ts->numRemovedPackages++;
00105
00106 if (ts->numRemovedPackages > 1)
00107 qsort(ts->removedPackages, ts->numRemovedPackages,
00108 sizeof(*ts->removedPackages), intcmp);
00109 }
00110
00111 if (ts->orderCount >= ts->orderAlloced) {
00112 ts->orderAlloced += (ts->orderCount - ts->orderAlloced) + ts->delta;
00113
00114 ts->order = xrealloc(ts->order, sizeof(*ts->order) * ts->orderAlloced);
00115
00116 }
00117
00118 p = rpmteNew(ts, h, TR_REMOVED, NULL, NULL, dboffset, depends);
00119
00120 ts->order[ts->orderCount] = p;
00121 ts->orderCount++;
00122
00123
00124 return 0;
00125 }
00126
00127 int rpmtsAddInstallElement(rpmts ts, Header h,
00128 fnpyKey key, int upgrade, rpmRelocation * relocs)
00129 {
00130 uint_32 tscolor = rpmtsColor(ts);
00131 uint_32 dscolor;
00132 uint_32 hcolor;
00133 rpmdbMatchIterator mi;
00134 Header oh;
00135 uint_32 ohcolor;
00136 int isSource;
00137 int duplicate = 0;
00138 rpmtsi pi; rpmte p;
00139 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00140 const char * arch;
00141 const char * os;
00142 rpmds add;
00143 rpmds obsoletes;
00144 alKey pkgKey;
00145 int xx;
00146 int ec = 0;
00147 int rc;
00148 int oc;
00149
00150
00151
00152
00153
00154 add = rpmdsThis(h, RPMTAG_REQUIRENAME, (RPMSENSE_EQUAL|RPMSENSE_LESS));
00155 arch = NULL;
00156 xx = hge(h, RPMTAG_ARCH, NULL, (void **)&arch, NULL);
00157 os = NULL;
00158 xx = hge(h, RPMTAG_OS, NULL, (void **)&os, NULL);
00159 hcolor = hGetColor(h);
00160
00161 pkgKey = RPMAL_NOMATCH;
00162 for (pi = rpmtsiInit(ts), oc = 0; (p = rpmtsiNext(pi, 0)) != NULL; oc++) {
00163 const char * parch;
00164 const char * pos;
00165 rpmds this;
00166
00167
00168 if (rpmteType(p) == TR_REMOVED)
00169 continue;
00170
00171 if (tscolor) {
00172 if (arch == NULL || (parch = rpmteA(p)) == NULL)
00173 continue;
00174 if (os == NULL || (pos = rpmteO(p)) == NULL)
00175 continue;
00176 if (strcmp(arch, parch) || strcmp(os, pos))
00177 continue;
00178 }
00179
00180 if ((this = rpmteDS(p, RPMTAG_NAME)) == NULL)
00181 continue;
00182
00183 rc = rpmdsCompare(add, this);
00184 if (rc != 0) {
00185 const char * pkgNEVR = rpmdsDNEVR(this);
00186 const char * addNEVR = rpmdsDNEVR(add);
00187 rpmMessage(RPMMESS_WARNING,
00188 _("package %s was already added, replacing with %s\n"),
00189 (pkgNEVR ? pkgNEVR + 2 : "?pkgNEVR?"),
00190 (addNEVR ? addNEVR + 2 : "?addNEVR?"));
00191 duplicate = 1;
00192 pkgKey = rpmteAddedKey(p);
00193 break;
00194 }
00195 }
00196 pi = rpmtsiFree(pi);
00197 add = rpmdsFree(add);
00198
00199 isSource = headerIsEntry(h, RPMTAG_SOURCEPACKAGE);
00200
00201 if (oc >= ts->orderAlloced) {
00202 ts->orderAlloced += (oc - ts->orderAlloced) + ts->delta;
00203
00204 ts->order = xrealloc(ts->order, ts->orderAlloced * sizeof(*ts->order));
00205
00206 }
00207
00208 p = rpmteNew(ts, h, TR_ADDED, key, relocs, -1, pkgKey);
00209
00210 if (duplicate && oc < ts->orderCount) {
00211
00212
00213 ts->order[oc] = rpmteFree(ts->order[oc]);
00214
00215
00216 }
00217
00218
00219 ts->order[oc] = p;
00220
00221 if (!duplicate) {
00222 ts->orderCount++;
00223 rpmcliPackagesTotal++;
00224 }
00225
00226 pkgKey = rpmalAdd(&ts->addedPackages, pkgKey, rpmteKey(p),
00227 rpmteDS(p, RPMTAG_PROVIDENAME),
00228 rpmteFI(p, RPMTAG_BASENAMES), tscolor);
00229 if (pkgKey == RPMAL_NOMATCH) {
00230
00231 ts->order[oc] = rpmteFree(ts->order[oc]);
00232
00233 ec = 1;
00234 goto exit;
00235 }
00236 (void) rpmteSetAddedKey(p, pkgKey);
00237
00238 if (!duplicate) {
00239 ts->numAddedPackages++;
00240 }
00241
00242 if (!upgrade)
00243 goto exit;
00244
00245
00246 if (isSource)
00247 goto exit;
00248
00249
00250 if (rpmtsGetRdb(ts) == NULL && ts->dbmode != -1) {
00251 if ((ec = rpmtsOpenDB(ts, ts->dbmode)) != 0)
00252 goto exit;
00253 }
00254
00255
00256
00257 mi = rpmtsInitIterator(ts, RPMTAG_PROVIDENAME, rpmteN(p), 0);
00258 while((oh = rpmdbNextIterator(mi)) != NULL) {
00259
00260
00261 ohcolor = hGetColor(oh);
00262 if (tscolor && hcolor && ohcolor && !(hcolor & ohcolor))
00263 continue;
00264
00265
00266 if (rpmVersionCompare(h, oh) == 0)
00267 continue;
00268
00269 xx = removePackage(ts, oh, rpmdbGetIteratorOffset(mi), pkgKey);
00270 }
00271 mi = rpmdbFreeIterator(mi);
00272
00273 obsoletes = rpmdsLink(rpmteDS(p, RPMTAG_OBSOLETENAME), "Obsoletes");
00274 obsoletes = rpmdsInit(obsoletes);
00275 if (obsoletes != NULL)
00276 while (rpmdsNext(obsoletes) >= 0) {
00277 const char * Name;
00278
00279 if ((Name = rpmdsN(obsoletes)) == NULL)
00280 continue;
00281
00282
00283 dscolor = rpmdsColor(obsoletes);
00284
00285 if (tscolor && dscolor && !(tscolor & dscolor))
00286 continue;
00287
00288
00289 if (!strcmp(rpmteN(p), Name))
00290 continue;
00291
00292 mi = rpmtsInitIterator(ts, RPMTAG_PROVIDENAME, Name, 0);
00293
00294 xx = rpmdbPruneIterator(mi,
00295 ts->removedPackages, ts->numRemovedPackages, 1);
00296
00297 while((oh = rpmdbNextIterator(mi)) != NULL) {
00298
00299 ohcolor = hGetColor(oh);
00300
00301
00302 if (tscolor && hcolor && ohcolor && !(hcolor & ohcolor))
00303 continue;
00304
00305
00306
00307
00308
00309 if (rpmdsEVR(obsoletes) == NULL
00310 || rpmdsAnyMatchesDep(oh, obsoletes, _rpmds_nopromote))
00311 #ifdef DYING
00312 if (rpmVersionCompare(h, oh))
00313 #endif
00314 xx = removePackage(ts, oh, rpmdbGetIteratorOffset(mi), pkgKey);
00315 }
00316 mi = rpmdbFreeIterator(mi);
00317 }
00318 obsoletes = rpmdsFree(obsoletes);
00319
00320 ec = 0;
00321
00322 exit:
00323 pi = rpmtsiFree(pi);
00324 return ec;
00325 }
00326
00327 int rpmtsAddEraseElement(rpmts ts, Header h, int dboffset)
00328 {
00329 return removePackage(ts, h, dboffset, RPMAL_NOMATCH);
00330 }
00331
00339 static int unsatisfiedDepend(rpmts ts, rpmds dep, int adding)
00340
00341
00342
00343
00344 {
00345 DBT * key = alloca(sizeof(*key));
00346 DBT * data = alloca(sizeof(*data));
00347 rpmdbMatchIterator mi;
00348 const char * Name;
00349 Header h;
00350 int _cacheThisRC = 1;
00351 int rc;
00352 int xx;
00353 int retrying = 0;
00354
00355 if ((Name = rpmdsN(dep)) == NULL)
00356 return 0;
00357
00358
00359
00360
00361 if (_cacheDependsRC) {
00362 dbiIndex dbi;
00363 dbi = dbiOpen(rpmtsGetRdb(ts), RPMDBI_DEPENDS, 0);
00364 if (dbi == NULL)
00365 _cacheDependsRC = 0;
00366 else {
00367 const char * DNEVR;
00368
00369 rc = -1;
00370
00371 if ((DNEVR = rpmdsDNEVR(dep)) != NULL) {
00372 DBC * dbcursor = NULL;
00373 void * datap = NULL;
00374 size_t datalen = 0;
00375 size_t DNEVRlen = strlen(DNEVR);
00376
00377 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, 0);
00378
00379 memset(key, 0, sizeof(*key));
00380 key->data = (void *) DNEVR;
00381 key->size = DNEVRlen;
00382 memset(data, 0, sizeof(*data));
00383 data->data = datap;
00384 data->size = datalen;
00385
00386 xx = dbiGet(dbi, dbcursor, key, data, DB_SET);
00387
00388 DNEVR = key->data;
00389 DNEVRlen = key->size;
00390 datap = data->data;
00391 datalen = data->size;
00392
00393
00394 if (xx == 0 && datap && datalen == 4)
00395 memcpy(&rc, datap, datalen);
00396
00397 xx = dbiCclose(dbi, dbcursor, 0);
00398 }
00399
00400
00401 if (rc >= 0) {
00402 rpmdsNotify(dep, _("(cached)"), rc);
00403 return rc;
00404 }
00405 }
00406 }
00407
00408 retry:
00409 rc = 0;
00410
00411 #if defined(DYING) || defined(__LCLINT__)
00412 { static const char noProvidesString[] = "nada";
00413 static const char * rcProvidesString = noProvidesString;
00414 int_32 Flags = rpmdsFlags(dep);
00415 const char * start;
00416 int i;
00417
00418 if (rcProvidesString == noProvidesString)
00419 rcProvidesString = rpmGetVar(RPMVAR_PROVIDES);
00420
00421 if (rcProvidesString != NULL && !(Flags & RPMSENSE_SENSEMASK)) {
00422
00423 i = strlen(Name);
00424
00425 while ((start = strstr(rcProvidesString, Name))) {
00426
00427
00428 if (xisspace(start[i]) || start[i] == '\0' || start[i] == ',') {
00429 rpmdsNotify(dep, _("(rpmrc provides)"), rc);
00430 goto exit;
00431 }
00432
00433 rcProvidesString = start + 1;
00434 }
00435 }
00436 }
00437 #endif
00438
00439
00440
00441
00442
00443
00444 if (!strncmp(Name, "rpmlib(", sizeof("rpmlib(")-1)) {
00445 if (rpmCheckRpmlibProvides(dep)) {
00446 rpmdsNotify(dep, _("(rpmlib provides)"), rc);
00447 goto exit;
00448 }
00449 goto unsatisfied;
00450 }
00451
00452
00453 if (rpmalSatisfiesDepend(ts->addedPackages, dep, NULL) != NULL) {
00454
00455
00456
00457
00458 if (_rpmds_nopromote)
00459 _cacheThisRC = 0;
00460 goto exit;
00461 }
00462
00463
00464 if (rpmtsGetRdb(ts) != NULL) {
00465
00466 if (Name[0] == '/') {
00467
00468
00469 mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, Name, 0);
00470
00471 (void) rpmdbPruneIterator(mi,
00472 ts->removedPackages, ts->numRemovedPackages, 1);
00473
00474 while ((h = rpmdbNextIterator(mi)) != NULL) {
00475 rpmdsNotify(dep, _("(db files)"), rc);
00476 mi = rpmdbFreeIterator(mi);
00477 goto exit;
00478 }
00479 mi = rpmdbFreeIterator(mi);
00480 }
00481
00482
00483 mi = rpmtsInitIterator(ts, RPMTAG_PROVIDENAME, Name, 0);
00484 (void) rpmdbPruneIterator(mi,
00485 ts->removedPackages, ts->numRemovedPackages, 1);
00486 while ((h = rpmdbNextIterator(mi)) != NULL) {
00487 if (rpmdsAnyMatchesDep(h, dep, _rpmds_nopromote)) {
00488 rpmdsNotify(dep, _("(db provides)"), rc);
00489 mi = rpmdbFreeIterator(mi);
00490 goto exit;
00491 }
00492 }
00493 mi = rpmdbFreeIterator(mi);
00494
00495 #if defined(DYING) || defined(__LCLINT__)
00496 mi = rpmtsInitIterator(ts, RPMTAG_NAME, Name, 0);
00497 (void) rpmdbPruneIterator(mi,
00498 ts->removedPackages, ts->numRemovedPackages, 1);
00499 while ((h = rpmdbNextIterator(mi)) != NULL) {
00500 if (rpmdsAnyMatchesDep(h, dep, _rpmds_nopromote)) {
00501 rpmdsNotify(dep, _("(db package)"), rc);
00502 mi = rpmdbFreeIterator(mi);
00503 goto exit;
00504 }
00505 }
00506 mi = rpmdbFreeIterator(mi);
00507 #endif
00508
00509 }
00510
00511
00512
00513
00514
00515 if (adding && !retrying && !(rpmtsFlags(ts) & RPMTRANS_FLAG_NOSUGGEST)) {
00516 if (ts->solve != NULL) {
00517 xx = (*ts->solve) (ts, dep, ts->solveData);
00518 if (xx == 0)
00519 goto exit;
00520 if (xx == -1) {
00521 retrying = 1;
00522 rpmalMakeIndex(ts->addedPackages);
00523 goto retry;
00524 }
00525 }
00526 }
00527
00528
00529 unsatisfied:
00530 rc = 1;
00531 rpmdsNotify(dep, NULL, rc);
00532
00533 exit:
00534
00535
00536
00537 if (_cacheDependsRC && _cacheThisRC) {
00538 dbiIndex dbi;
00539 dbi = dbiOpen(rpmtsGetRdb(ts), RPMDBI_DEPENDS, 0);
00540 if (dbi == NULL) {
00541 _cacheDependsRC = 0;
00542 } else {
00543 const char * DNEVR;
00544 xx = 0;
00545
00546 if ((DNEVR = rpmdsDNEVR(dep)) != NULL) {
00547 DBC * dbcursor = NULL;
00548 size_t DNEVRlen = strlen(DNEVR);
00549
00550 xx = dbiCopen(dbi, dbi->dbi_txnid, &dbcursor, DB_WRITECURSOR);
00551
00552 memset(key, 0, sizeof(*key));
00553 key->data = (void *) DNEVR;
00554 key->size = DNEVRlen;
00555 memset(data, 0, sizeof(*data));
00556 data->data = &rc;
00557 data->size = sizeof(rc);
00558
00559
00560 xx = dbiPut(dbi, dbcursor, key, data, 0);
00561
00562 xx = dbiCclose(dbi, dbcursor, DB_WRITECURSOR);
00563 }
00564
00565 if (xx)
00566 _cacheDependsRC = 0;
00567 }
00568 }
00569 return rc;
00570 }
00571
00583 static int checkPackageDeps(rpmts ts, const char * pkgNEVRA,
00584 rpmds requires, rpmds conflicts,
00585 const char * depName, uint_32 tscolor, int adding)
00586
00587
00588
00589
00590 {
00591 uint_32 dscolor;
00592 const char * Name;
00593 int rc;
00594 int ourrc = 0;
00595
00596 requires = rpmdsInit(requires);
00597 if (requires != NULL)
00598 while (!ourrc && rpmdsNext(requires) >= 0) {
00599
00600 if ((Name = rpmdsN(requires)) == NULL)
00601 continue;
00602
00603
00604 if (depName != NULL && strcmp(depName, Name))
00605 continue;
00606
00607
00608 dscolor = rpmdsColor(requires);
00609 if (tscolor && dscolor && !(tscolor & dscolor))
00610 continue;
00611
00612 rc = unsatisfiedDepend(ts, requires, adding);
00613
00614 switch (rc) {
00615 case 0:
00616 break;
00617 case 1:
00618 { fnpyKey * suggestedKeys = NULL;
00619
00620
00621 if (ts->availablePackages != NULL) {
00622 suggestedKeys = rpmalAllSatisfiesDepend(ts->availablePackages,
00623 requires, NULL);
00624 }
00625
00626
00627 rpmdsProblem(ts->probs, pkgNEVRA, requires, suggestedKeys, adding);
00628
00629 }
00630 break;
00631 case 2:
00632 default:
00633 ourrc = 1;
00634 break;
00635 }
00636 }
00637
00638 conflicts = rpmdsInit(conflicts);
00639 if (conflicts != NULL)
00640 while (!ourrc && rpmdsNext(conflicts) >= 0) {
00641
00642 if ((Name = rpmdsN(conflicts)) == NULL)
00643 continue;
00644
00645
00646 if (depName != NULL && strcmp(depName, Name))
00647 continue;
00648
00649
00650 dscolor = rpmdsColor(conflicts);
00651 if (tscolor && dscolor && !(tscolor & dscolor))
00652 continue;
00653
00654 rc = unsatisfiedDepend(ts, conflicts, adding);
00655
00656
00657 switch (rc) {
00658 case 0:
00659 rpmdsProblem(ts->probs, pkgNEVRA, conflicts, NULL, adding);
00660 break;
00661 case 1:
00662 break;
00663 case 2:
00664 default:
00665 ourrc = 1;
00666 break;
00667 }
00668 }
00669
00670 return ourrc;
00671 }
00672
00683 static int checkPackageSet(rpmts ts, const char * dep,
00684 rpmdbMatchIterator mi, int adding)
00685
00686
00687 {
00688 int scareMem = 1;
00689 Header h;
00690 int ec = 0;
00691
00692 (void) rpmdbPruneIterator(mi,
00693 ts->removedPackages, ts->numRemovedPackages, 1);
00694 while ((h = rpmdbNextIterator(mi)) != NULL) {
00695 const char * pkgNEVRA;
00696 rpmds requires, conflicts;
00697 int rc;
00698
00699 pkgNEVRA = hGetNEVRA(h, NULL);
00700 requires = rpmdsNew(h, RPMTAG_REQUIRENAME, scareMem);
00701 (void) rpmdsSetNoPromote(requires, _rpmds_nopromote);
00702 conflicts = rpmdsNew(h, RPMTAG_CONFLICTNAME, scareMem);
00703 (void) rpmdsSetNoPromote(conflicts, _rpmds_nopromote);
00704 rc = checkPackageDeps(ts, pkgNEVRA, requires, conflicts, dep, 0, adding);
00705 conflicts = rpmdsFree(conflicts);
00706 requires = rpmdsFree(requires);
00707 pkgNEVRA = _free(pkgNEVRA);
00708
00709 if (rc) {
00710 ec = 1;
00711 break;
00712 }
00713 }
00714 mi = rpmdbFreeIterator(mi);
00715
00716 return ec;
00717 }
00718
00725 static int checkDependentPackages(rpmts ts, const char * dep)
00726
00727
00728 {
00729 rpmdbMatchIterator mi;
00730 mi = rpmtsInitIterator(ts, RPMTAG_REQUIRENAME, dep, 0);
00731 return checkPackageSet(ts, dep, mi, 0);
00732 }
00733
00740 static int checkDependentConflicts(rpmts ts, const char * dep)
00741
00742
00743 {
00744 int rc = 0;
00745
00746 if (rpmtsGetRdb(ts) != NULL) {
00747 rpmdbMatchIterator mi;
00748 mi = rpmtsInitIterator(ts, RPMTAG_CONFLICTNAME, dep, 0);
00749 rc = checkPackageSet(ts, dep, mi, 1);
00750 }
00751
00752 return rc;
00753 }
00754
00755 struct badDeps_s {
00756
00757 const char * pname;
00758
00759 const char * qname;
00760 };
00761
00762 #ifdef REFERENCE
00763 static struct badDeps_s {
00764 const char * pname;
00765 const char * qname;
00766 } badDeps[] = {
00767 { "libtermcap", "bash" },
00768 { "modutils", "vixie-cron" },
00769 { "ypbind", "yp-tools" },
00770 { "ghostscript-fonts", "ghostscript" },
00771
00772 { "libgnomeprint15", "gnome-print" },
00773 { "nautilus", "nautilus-mozilla" },
00774
00775 { "arts", "kdelibs-sound" },
00776
00777 { "pango-gtkbeta-devel", "pango-gtkbeta" },
00778 { "XFree86", "Mesa" },
00779 { "compat-glibc", "db2" },
00780 { "compat-glibc", "db1" },
00781 { "pam", "initscripts" },
00782 { "initscripts", "sysklogd" },
00783
00784 { "egcs-c++", "libstdc++" },
00785
00786 { "pilot-link-devel", "pilot-link" },
00787
00788 { "pam", "pamconfig" },
00789 { NULL, NULL }
00790 };
00791 #else
00792
00793 static int badDepsInitialized = 0;
00794
00795
00796 static struct badDeps_s * badDeps = NULL;
00797 #endif
00798
00801
00802 static void freeBadDeps(void)
00803
00804
00805 {
00806 if (badDeps) {
00807 struct badDeps_s * bdp;
00808 for (bdp = badDeps; bdp->pname != NULL && bdp->qname != NULL; bdp++)
00809 bdp->pname = _free(bdp->pname);
00810 badDeps = _free(badDeps);
00811 }
00812 badDepsInitialized = 0;
00813 }
00814
00815
00824
00825 static int ignoreDep(const rpmts ts, const rpmte p, const rpmte q)
00826
00827
00828
00829
00830 {
00831 struct badDeps_s * bdp;
00832
00833 if (!badDepsInitialized) {
00834 char * s = rpmExpand("%{?_dependency_whiteout}", NULL);
00835 const char ** av = NULL;
00836 int anaconda = rpmtsFlags(ts) & RPMTRANS_FLAG_ANACONDA;
00837 int msglvl = (anaconda || (rpmtsFlags(ts) & RPMTRANS_FLAG_DEPLOOPS))
00838 ? RPMMESS_WARNING : RPMMESS_DEBUG;
00839 int ac = 0;
00840 int i;
00841
00842 if (s != NULL && *s != '\0'
00843 && !(i = poptParseArgvString(s, &ac, (const char ***)&av))
00844 && ac > 0 && av != NULL)
00845 {
00846 bdp = badDeps = xcalloc(ac+1, sizeof(*badDeps));
00847 for (i = 0; i < ac; i++, bdp++) {
00848 char * pname, * qname;
00849
00850 if (av[i] == NULL)
00851 break;
00852 pname = xstrdup(av[i]);
00853 if ((qname = strchr(pname, '>')) != NULL)
00854 *qname++ = '\0';
00855 bdp->pname = pname;
00856
00857 bdp->qname = qname;
00858
00859 rpmMessage(msglvl,
00860 _("ignore package name relation(s) [%d]\t%s -> %s\n"),
00861 i, bdp->pname, (bdp->qname ? bdp->qname : "???"));
00862 }
00863 bdp->pname = NULL;
00864 bdp->qname = NULL;
00865 }
00866 av = _free(av);
00867 s = _free(s);
00868 badDepsInitialized++;
00869 }
00870
00871
00872 if (badDeps != NULL)
00873 for (bdp = badDeps; bdp->pname != NULL && bdp->qname != NULL; bdp++) {
00874 if (!strcmp(rpmteN(p), bdp->pname) && !strcmp(rpmteN(q), bdp->qname))
00875 return 1;
00876 }
00877 return 0;
00878
00879 }
00880
00881
00887 static void markLoop( tsortInfo tsi, rpmte q)
00888
00889
00890
00891 {
00892 rpmte p;
00893
00894
00895 while (tsi != NULL && (p = tsi->tsi_suc) != NULL) {
00896 tsi = tsi->tsi_next;
00897 if (rpmteTSI(p)->tsi_chain != NULL)
00898 continue;
00899
00900 rpmteTSI(p)->tsi_chain = q;
00901
00902 if (rpmteTSI(p)->tsi_next != NULL)
00903 markLoop(rpmteTSI(p)->tsi_next, p);
00904 }
00905
00906 }
00907
00908 static inline const char * const identifyDepend(int_32 f)
00909
00910 {
00911 if (isLegacyPreReq(f))
00912 return "PreReq:";
00913 f = _notpre(f);
00914 if (f & RPMSENSE_SCRIPT_PRE)
00915 return "Requires(pre):";
00916 if (f & RPMSENSE_SCRIPT_POST)
00917 return "Requires(post):";
00918 if (f & RPMSENSE_SCRIPT_PREUN)
00919 return "Requires(preun):";
00920 if (f & RPMSENSE_SCRIPT_POSTUN)
00921 return "Requires(postun):";
00922 if (f & RPMSENSE_SCRIPT_VERIFY)
00923 return "Requires(verify):";
00924 if (f & RPMSENSE_FIND_REQUIRES)
00925 return "Requires(auto):";
00926 return "Requires:";
00927 }
00928
00941
00942
00943 static const char *
00944 zapRelation(rpmte q, rpmte p,
00945 rpmds requires,
00946 int zap, int * nzaps, int msglvl)
00947
00948 {
00949 tsortInfo tsi_prev;
00950 tsortInfo tsi;
00951 const char *dp = NULL;
00952
00953 for (tsi_prev = rpmteTSI(q), tsi = rpmteTSI(q)->tsi_next;
00954 tsi != NULL;
00955
00956
00957 tsi_prev = tsi, tsi = tsi->tsi_next)
00958
00959 {
00960 int_32 Flags;
00961
00962
00963 if (tsi->tsi_suc != p)
00964 continue;
00965
00966
00967 if (requires == NULL) continue;
00968
00969 (void) rpmdsSetIx(requires, tsi->tsi_reqx);
00970
00971 Flags = rpmdsFlags(requires);
00972
00973 dp = rpmdsNewDNEVR( identifyDepend(Flags), requires);
00974
00975
00976
00977
00978
00979 if (zap && !(Flags & RPMSENSE_PREREQ)) {
00980 rpmMessage(msglvl,
00981 _("removing %s \"%s\" from tsort relations.\n"),
00982 (rpmteNEVR(p) ? rpmteNEVR(p) : "???"), dp);
00983 rpmteTSI(p)->tsi_count--;
00984 if (tsi_prev) tsi_prev->tsi_next = tsi->tsi_next;
00985 tsi->tsi_next = NULL;
00986 tsi->tsi_suc = NULL;
00987 tsi = _free(tsi);
00988 if (nzaps)
00989 (*nzaps)++;
00990 if (zap)
00991 zap--;
00992 }
00993
00994
00995 break;
00996 }
00997 return dp;
00998 }
00999
01000
01001
01010
01011 static inline int addRelation(rpmts ts,
01012 rpmte p,
01013 unsigned char * selected,
01014 rpmds requires)
01015
01016
01017
01018 {
01019 rpmtsi qi; rpmte q;
01020 tsortInfo tsi;
01021 const char * Name;
01022 fnpyKey key;
01023 alKey pkgKey;
01024 int i = 0;
01025
01026 if ((Name = rpmdsN(requires)) == NULL)
01027 return 0;
01028
01029
01030 if (!strncmp(Name, "rpmlib(", sizeof("rpmlib(")-1))
01031 return 0;
01032
01033
01034 if (!strncmp(Name, "config(", sizeof("config(")-1))
01035 return 0;
01036
01037 pkgKey = RPMAL_NOMATCH;
01038 key = rpmalSatisfiesDepend(ts->addedPackages, requires, &pkgKey);
01039
01040
01041 if (pkgKey == RPMAL_NOMATCH)
01042 return 0;
01043
01044
01045
01046 for (qi = rpmtsiInit(ts), i = 0; (q = rpmtsiNext(qi, 0)) != NULL; i++) {
01047
01048
01049 if (rpmteType(q) == TR_REMOVED)
01050 continue;
01051
01052 if (pkgKey == rpmteAddedKey(q))
01053 break;
01054 }
01055 qi = rpmtsiFree(qi);
01056 if (q == NULL || i == ts->orderCount)
01057 return 0;
01058
01059
01060 if (ignoreDep(ts, p, q))
01061 return 0;
01062
01063
01064
01065
01066 if (selected[i] != 0)
01067 return 0;
01068
01069
01070 selected[i] = 1;
01071
01072
01073
01074 rpmteTSI(p)->tsi_count++;
01075
01076 if (rpmteDepth(p) <= rpmteDepth(q))
01077 (void) rpmteSetDepth(p, (rpmteDepth(q) + 1));
01078
01079 tsi = xcalloc(1, sizeof(*tsi));
01080 tsi->tsi_suc = p;
01081
01082 tsi->tsi_reqx = rpmdsIx(requires);
01083
01084 tsi->tsi_next = rpmteTSI(q)->tsi_next;
01085 rpmteTSI(q)->tsi_next = tsi;
01086 rpmteTSI(q)->tsi_qcnt++;
01087 return 0;
01088 }
01089
01090
01097 static int orderListIndexCmp(const void * one, const void * two)
01098 {
01099
01100 long a = (long) ((const orderListIndex)one)->pkgKey;
01101 long b = (long) ((const orderListIndex)two)->pkgKey;
01102
01103 return (a - b);
01104 }
01105
01112
01113
01114 static void addQ( rpmte p,
01115 rpmte * qp,
01116 rpmte * rp,
01117 uint_32 tscolor)
01118
01119 {
01120 uint_32 pcolor = rpmteColor(p);
01121 rpmte q, qprev;
01122 uint_32 qcolor;
01123
01124
01125 rpmteTSI(p)->tsi_reqx = 1;
01126
01127 if ((*rp) == NULL) {
01128
01129 (*rp) = (*qp) = p;
01130
01131 return;
01132 }
01133
01134
01135 for (qprev = NULL, q = (*qp);
01136 q != NULL;
01137 qprev = q, q = rpmteTSI(q)->tsi_suc)
01138 {
01139 qcolor = rpmteColor(q);
01140 if (tscolor != 0 && qcolor > pcolor)
01141 continue;
01142 if (rpmteTSI(q)->tsi_qcnt <= rpmteTSI(p)->tsi_qcnt)
01143 break;
01144 }
01145
01146 if (qprev == NULL) {
01147 rpmteTSI(p)->tsi_suc = q;
01148
01149 (*qp) = p;
01150
01151 } else if (q == NULL) {
01152 rpmteTSI(qprev)->tsi_suc = p;
01153
01154 (*rp) = p;
01155
01156 } else {
01157 rpmteTSI(p)->tsi_suc = q;
01158 rpmteTSI(qprev)->tsi_suc = p;
01159 }
01160 }
01161
01162
01163
01164
01165 int rpmtsOrder(rpmts ts)
01166 {
01167 rpmds requires;
01168 int_32 Flags;
01169 int anaconda = rpmtsFlags(ts) & RPMTRANS_FLAG_ANACONDA;
01170 rpmtsi pi; rpmte p;
01171 rpmtsi qi; rpmte q;
01172 rpmtsi ri; rpmte r;
01173 tsortInfo tsi;
01174 tsortInfo tsi_next;
01175 alKey * ordering;
01176 int orderingCount = 0;
01177 unsigned char * selected = alloca(sizeof(*selected) * (ts->orderCount + 1));
01178 int loopcheck;
01179 rpmte * newOrder;
01180 int newOrderCount = 0;
01181 orderListIndex orderList;
01182 int numOrderList;
01183 int nrescans = 10;
01184 int _printed = 0;
01185 char deptypechar;
01186 size_t tsbytes;
01187 int oType = 0;
01188 int treex;
01189 int depth;
01190 int qlen;
01191 int i, j;
01192 uint_32 tscolor = rpmtsColor(ts);
01193
01194 #ifdef DYING
01195 rpmalMakeIndex(ts->addedPackages);
01196 #endif
01197
01198 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_ORDER), 0);
01199
01200
01201 if (oType == 0)
01202 numOrderList = ts->orderCount;
01203 else {
01204 numOrderList = 0;
01205 if (oType & TR_ADDED)
01206 numOrderList += ts->numAddedPackages;
01207 if (oType & TR_REMOVED)
01208 numOrderList += ts->numRemovedPackages;
01209 }
01210 ordering = alloca(sizeof(*ordering) * (numOrderList + 1));
01211 loopcheck = numOrderList;
01212 tsbytes = 0;
01213
01214 pi = rpmtsiInit(ts);
01215 while ((p = rpmtsiNext(pi, oType)) != NULL)
01216 rpmteNewTSI(p);
01217 pi = rpmtsiFree(pi);
01218
01219
01220 rpmMessage(RPMMESS_DEBUG, _("========== recording tsort relations\n"));
01221 pi = rpmtsiInit(ts);
01222 while ((p = rpmtsiNext(pi, oType)) != NULL) {
01223
01224 if ((requires = rpmteDS(p, RPMTAG_REQUIRENAME)) == NULL)
01225 continue;
01226
01227 memset(selected, 0, sizeof(*selected) * ts->orderCount);
01228
01229
01230 selected[rpmtsiOc(pi)] = 1;
01231
01232
01233
01234
01235 requires = rpmdsInit(requires);
01236 if (requires != NULL)
01237 while (rpmdsNext(requires) >= 0) {
01238
01239 Flags = rpmdsFlags(requires);
01240
01241 switch (rpmteType(p)) {
01242 case TR_REMOVED:
01243
01244 if (isInstallPreReq(Flags)
01245 || !( isErasePreReq(Flags) || isLegacyPreReq(Flags) ) )
01246 continue;
01247 break;
01248 case TR_ADDED:
01249
01250 if (isErasePreReq(Flags)
01251 || !( isInstallPreReq(Flags) || isLegacyPreReq(Flags) ) )
01252 continue;
01253 break;
01254 }
01255
01256
01257 (void) addRelation(ts, p, selected, requires);
01258
01259 }
01260
01261
01262 requires = rpmdsInit(requires);
01263 if (requires != NULL)
01264 while (rpmdsNext(requires) >= 0) {
01265
01266 Flags = rpmdsFlags(requires);
01267
01268 switch (rpmteType(p)) {
01269 case TR_REMOVED:
01270
01271 if (isInstallPreReq(Flags)
01272 || ( isErasePreReq(Flags) || isLegacyPreReq(Flags) ) )
01273 continue;
01274 break;
01275 case TR_ADDED:
01276
01277 if (isErasePreReq(Flags)
01278 || ( isInstallPreReq(Flags) || isLegacyPreReq(Flags) ) )
01279 continue;
01280 break;
01281 }
01282
01283
01284 (void) addRelation(ts, p, selected, requires);
01285
01286 }
01287 }
01288 pi = rpmtsiFree(pi);
01289
01290
01291 treex = 0;
01292 pi = rpmtsiInit(ts);
01293 while ((p = rpmtsiNext(pi, oType)) != NULL) {
01294 int npreds;
01295
01296 npreds = rpmteTSI(p)->tsi_count;
01297
01298 (void) rpmteSetNpreds(p, npreds);
01299
01300 if (npreds == 0)
01301 (void) rpmteSetTree(p, treex++);
01302 else
01303 (void) rpmteSetTree(p, -1);
01304 #ifdef UNNECESSARY
01305 (void) rpmteSetParent(p, NULL);
01306 #endif
01307
01308 }
01309 pi = rpmtsiFree(pi);
01310
01311
01312 rpmMessage(RPMMESS_DEBUG, _("========== tsorting packages (order, #predecessors, #succesors, tree, depth)\n"));
01313
01314 rescan:
01315 if (pi != NULL) pi = rpmtsiFree(pi);
01316 q = r = NULL;
01317 qlen = 0;
01318 pi = rpmtsiInit(ts);
01319 while ((p = rpmtsiNext(pi, oType)) != NULL) {
01320
01321
01322 if (anaconda)
01323 rpmteTSI(p)->tsi_qcnt = (ts->orderCount - rpmtsiOc(pi));
01324
01325 if (rpmteTSI(p)->tsi_count != 0)
01326 continue;
01327 rpmteTSI(p)->tsi_suc = NULL;
01328 addQ(p, &q, &r, tscolor);
01329 qlen++;
01330 }
01331 pi = rpmtsiFree(pi);
01332
01333
01334 for (; q != NULL; q = rpmteTSI(q)->tsi_suc) {
01335
01336
01337 rpmteTSI(q)->tsi_reqx = 0;
01338
01339 if (oType != 0)
01340 switch (rpmteType(q)) {
01341 case TR_ADDED:
01342 if (!(oType & TR_ADDED))
01343 continue;
01344 break;
01345 case TR_REMOVED:
01346 if (!(oType & TR_REMOVED))
01347 continue;
01348 break;
01349 default:
01350 continue;
01351 break;
01352 }
01353 deptypechar = (rpmteType(q) == TR_REMOVED ? '-' : '+');
01354
01355 rpmMessage(RPMMESS_DEBUG, "%5d%5d%5d%5d%5d %*s%c%s\n",
01356 orderingCount, rpmteNpreds(q),
01357 rpmteTSI(q)->tsi_qcnt, rpmteTree(q), rpmteDepth(q),
01358 (2 * rpmteDepth(q)), "",
01359 deptypechar,
01360 (rpmteNEVR(q) ? rpmteNEVR(q) : "???"));
01361
01362 treex = rpmteTree(q);
01363 depth = rpmteDepth(q);
01364 (void) rpmteSetDegree(q, 0);
01365 tsbytes += rpmtePkgFileSize(q);
01366
01367 ordering[orderingCount] = rpmteAddedKey(q);
01368 orderingCount++;
01369 qlen--;
01370 loopcheck--;
01371
01372
01373 tsi_next = rpmteTSI(q)->tsi_next;
01374 rpmteTSI(q)->tsi_next = NULL;
01375 while ((tsi = tsi_next) != NULL) {
01376 tsi_next = tsi->tsi_next;
01377 tsi->tsi_next = NULL;
01378 p = tsi->tsi_suc;
01379 if (p && (--rpmteTSI(p)->tsi_count) <= 0) {
01380
01381 (void) rpmteSetTree(p, treex);
01382 (void) rpmteSetDepth(p, depth+1);
01383 (void) rpmteSetParent(p, q);
01384 (void) rpmteSetDegree(q, rpmteDegree(q)+1);
01385
01386
01387 rpmteTSI(p)->tsi_suc = NULL;
01388 addQ(p, &rpmteTSI(q)->tsi_suc, &r, tscolor);
01389 qlen++;
01390 }
01391 tsi = _free(tsi);
01392 }
01393 if (!_printed && loopcheck == qlen && rpmteTSI(q)->tsi_suc != NULL) {
01394 _printed++;
01395 (void) rpmtsUnorderedSuccessors(ts, orderingCount);
01396 rpmMessage(RPMMESS_DEBUG,
01397 _("========== successors only (%d bytes)\n"), (int)tsbytes);
01398
01399
01400 tsi = rpmteTSI(q);
01401 pi = rpmtsiInit(ts);
01402 while ((p = rpmtsiNext(pi, oType)) != NULL) {
01403
01404 if (rpmteTSI(p)->tsi_reqx == 0)
01405 continue;
01406 tsi->tsi_suc = p;
01407 tsi = rpmteTSI(p);
01408 }
01409 pi = rpmtsiFree(pi);
01410 tsi->tsi_suc = NULL;
01411 }
01412 }
01413
01414
01415 if (loopcheck != 0) {
01416 int nzaps;
01417
01418
01419 nzaps = 0;
01420 qi = rpmtsiInit(ts);
01421 while ((q = rpmtsiNext(qi, oType)) != NULL) {
01422 rpmteTSI(q)->tsi_chain = NULL;
01423 rpmteTSI(q)->tsi_reqx = 0;
01424
01425 if (rpmteTSI(q)->tsi_count == 0)
01426 rpmteTSI(q)->tsi_count = -1;
01427 }
01428 qi = rpmtsiFree(qi);
01429
01430
01431 qi = rpmtsiInit(ts);
01432 while ((q = rpmtsiNext(qi, oType)) != NULL) {
01433 if ((tsi = rpmteTSI(q)->tsi_next) == NULL)
01434 continue;
01435 rpmteTSI(q)->tsi_next = NULL;
01436 markLoop(tsi, q);
01437 rpmteTSI(q)->tsi_next = tsi;
01438 }
01439 qi = rpmtsiFree(qi);
01440
01441
01442 ri = rpmtsiInit(ts);
01443 while ((r = rpmtsiNext(ri, oType)) != NULL)
01444 {
01445 int printed;
01446
01447 printed = 0;
01448
01449
01450 for (q = rpmteTSI(r)->tsi_chain; q != NULL;
01451 q = rpmteTSI(q)->tsi_chain)
01452 {
01453 if (rpmteTSI(q)->tsi_reqx)
01454 break;
01455 rpmteTSI(q)->tsi_reqx = 1;
01456 }
01457
01458
01459 while ((p = q) != NULL && (q = rpmteTSI(p)->tsi_chain) != NULL) {
01460 const char * dp;
01461 char buf[4096];
01462 int msglvl = (anaconda || (rpmtsFlags(ts) & RPMTRANS_FLAG_DEPLOOPS))
01463 ? RPMMESS_WARNING : RPMMESS_DEBUG;
01464 ;
01465
01466
01467 rpmteTSI(p)->tsi_chain = NULL;
01468
01469 if (!printed) {
01470 rpmMessage(msglvl, _("LOOP:\n"));
01471 printed = 1;
01472 }
01473
01474
01475 requires = rpmteDS(p, RPMTAG_REQUIRENAME);
01476 requires = rpmdsInit(requires);
01477 if (requires == NULL)
01478 continue;
01479 dp = zapRelation(q, p, requires, 1, &nzaps, msglvl);
01480
01481
01482 buf[0] = '\0';
01483 if (rpmteNEVR(p) != NULL)
01484 (void) stpcpy(buf, rpmteNEVR(p));
01485 rpmMessage(msglvl, " %-40s %s\n", buf,
01486 (dp ? dp : "not found!?!"));
01487
01488 dp = _free(dp);
01489 }
01490
01491
01492 for (p = r, q = rpmteTSI(r)->tsi_chain; q != NULL;
01493 p = q, q = rpmteTSI(q)->tsi_chain)
01494 {
01495
01496 rpmteTSI(p)->tsi_chain = NULL;
01497 rpmteTSI(p)->tsi_reqx = 0;
01498 }
01499 }
01500 ri = rpmtsiFree(ri);
01501
01502
01503
01504 if (nzaps && nrescans-- > 0) {
01505 rpmMessage(RPMMESS_DEBUG, _("========== continuing tsort ...\n"));
01506 goto rescan;
01507 }
01508
01509
01510 rpmMessage(RPMMESS_ERROR, _("rpmtsOrder failed, %d elements remain\n"),
01511 loopcheck);
01512 return loopcheck;
01513 }
01514
01515
01516 pi = rpmtsiInit(ts);
01517 while ((p = rpmtsiNext(pi, 0)) != NULL)
01518 rpmteFreeTSI(p);
01519 pi = rpmtsiFree(pi);
01520
01521
01522
01523
01524
01525
01526
01527 orderList = xcalloc(numOrderList, sizeof(*orderList));
01528 j = 0;
01529 pi = rpmtsiInit(ts);
01530 while ((p = rpmtsiNext(pi, oType)) != NULL) {
01531
01532 switch (rpmteType(p)) {
01533 case TR_ADDED:
01534 orderList[j].pkgKey = rpmteAddedKey(p);
01535 break;
01536 case TR_REMOVED:
01537 orderList[j].pkgKey = RPMAL_NOMATCH;
01538 break;
01539 }
01540 orderList[j].orIndex = rpmtsiOc(pi);
01541 j++;
01542 }
01543 pi = rpmtsiFree(pi);
01544
01545 qsort(orderList, numOrderList, sizeof(*orderList), orderListIndexCmp);
01546
01547
01548 newOrder = xcalloc(ts->orderCount, sizeof(*newOrder));
01549
01550
01551 for (i = 0, newOrderCount = 0; i < orderingCount; i++)
01552 {
01553 struct orderListIndex_s key;
01554 orderListIndex needle;
01555
01556 key.pkgKey = ordering[i];
01557 needle = bsearch(&key, orderList, numOrderList,
01558 sizeof(key), orderListIndexCmp);
01559
01560 if (needle == NULL)
01561 continue;
01562
01563 j = needle->orIndex;
01564 if ((q = ts->order[j]) == NULL)
01565 continue;
01566
01567 newOrder[newOrderCount++] = q;
01568 ts->order[j] = NULL;
01569 if (anaconda)
01570 for (j = needle->orIndex + 1; j < ts->orderCount; j++) {
01571 if ((q = ts->order[j]) == NULL)
01572 break;
01573 if (rpmteType(q) == TR_REMOVED
01574 && rpmteDependsOnKey(q) == needle->pkgKey)
01575 {
01576 newOrder[newOrderCount++] = q;
01577 ts->order[j] = NULL;
01578 } else
01579 break;
01580 }
01581 }
01582
01583
01584 for (j = 0; j < ts->orderCount; j++) {
01585 if ((p = ts->order[j]) == NULL)
01586 continue;
01587 newOrder[newOrderCount++] = p;
01588 ts->order[j] = NULL;
01589 }
01590 assert(newOrderCount == ts->orderCount);
01591
01592
01593 ts->order = _free(ts->order);
01594
01595 ts->order = newOrder;
01596 ts->orderAlloced = ts->orderCount;
01597 orderList = _free(orderList);
01598
01599 #ifdef DYING
01600 rpmtsClean(ts);
01601 #endif
01602 freeBadDeps();
01603
01604 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_ORDER), 0);
01605
01606 return 0;
01607 }
01608
01609
01610 int rpmtsCheck(rpmts ts)
01611 {
01612 uint_32 tscolor = rpmtsColor(ts);
01613 rpmdbMatchIterator mi = NULL;
01614 rpmtsi pi = NULL; rpmte p;
01615 int closeatexit = 0;
01616 int xx;
01617 int rc;
01618
01619 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_CHECK), 0);
01620
01621
01622 if (rpmtsGetRdb(ts) == NULL && ts->dbmode != -1) {
01623 if ((rc = rpmtsOpenDB(ts, ts->dbmode)) != 0)
01624 goto exit;
01625 closeatexit = 1;
01626 }
01627
01628 ts->probs = rpmpsFree(ts->probs);
01629 ts->probs = rpmpsCreate();
01630
01631 rpmalMakeIndex(ts->addedPackages);
01632
01633
01634
01635
01636
01637 pi = rpmtsiInit(ts);
01638 while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
01639 rpmds provides;
01640
01641
01642 rpmMessage(RPMMESS_DEBUG, "========== +++ %s %s/%s 0x%x\n",
01643 rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
01644
01645 rc = checkPackageDeps(ts, rpmteNEVRA(p),
01646 rpmteDS(p, RPMTAG_REQUIRENAME),
01647 rpmteDS(p, RPMTAG_CONFLICTNAME),
01648 NULL,
01649 tscolor, 1);
01650 if (rc)
01651 goto exit;
01652
01653 rc = 0;
01654 provides = rpmteDS(p, RPMTAG_PROVIDENAME);
01655 provides = rpmdsInit(provides);
01656 if (provides != NULL)
01657 while (rpmdsNext(provides) >= 0) {
01658 const char * Name;
01659
01660 if ((Name = rpmdsN(provides)) == NULL)
01661 continue;
01662
01663
01664 if (!checkDependentConflicts(ts, Name))
01665 continue;
01666 rc = 1;
01667 break;
01668 }
01669 if (rc)
01670 goto exit;
01671 }
01672 pi = rpmtsiFree(pi);
01673
01674
01675
01676
01677 pi = rpmtsiInit(ts);
01678 while ((p = rpmtsiNext(pi, TR_REMOVED)) != NULL) {
01679 rpmds provides;
01680 rpmfi fi;
01681
01682
01683 rpmMessage(RPMMESS_DEBUG, "========== --- %s %s/%s 0x%x\n",
01684 rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
01685
01686
01687 #if defined(DYING) || defined(__LCLINT__)
01688
01689
01690 rc = checkDependentPackages(ts, rpmteN(p));
01691 if (rc)
01692 goto exit;
01693 #endif
01694
01695 rc = 0;
01696 provides = rpmteDS(p, RPMTAG_PROVIDENAME);
01697 provides = rpmdsInit(provides);
01698 if (provides != NULL)
01699 while (rpmdsNext(provides) >= 0) {
01700 const char * Name;
01701
01702 if ((Name = rpmdsN(provides)) == NULL)
01703 continue;
01704
01705
01706 if (!checkDependentPackages(ts, Name))
01707 continue;
01708 rc = 1;
01709 break;
01710 }
01711 if (rc)
01712 goto exit;
01713
01714 rc = 0;
01715 fi = rpmteFI(p, RPMTAG_BASENAMES);
01716 fi = rpmfiInit(fi, 0);
01717 while (rpmfiNext(fi) >= 0) {
01718 const char * fn = rpmfiFN(fi);
01719
01720
01721 if (!checkDependentPackages(ts, fn))
01722 continue;
01723 rc = 1;
01724 break;
01725 }
01726 if (rc)
01727 goto exit;
01728 }
01729 pi = rpmtsiFree(pi);
01730
01731 rc = 0;
01732
01733 exit:
01734 mi = rpmdbFreeIterator(mi);
01735 pi = rpmtsiFree(pi);
01736
01737 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_CHECK), 0);
01738
01739
01740 if (closeatexit)
01741 xx = rpmtsCloseDB(ts);
01742 else if (_cacheDependsRC)
01743 xx = rpmdbCloseDBI(rpmtsGetRdb(ts), RPMDBI_DEPENDS);
01744
01745 return rc;
01746 }