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