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