]>
git.saurik.com Git - apt.git/blob - apt-pkg/algorithms.cc
9b37385bf87ae59b3179604ca87b69ad28c06660
   1 // -*- mode: cpp; mode: fold -*- 
   3 // $Id: algorithms.cc,v 1.44 2002/11/28 18:49:16 jgg Exp $ 
   4 /* ###################################################################### 
   6    Algorithms - A set of misc algorithms 
   8    The pkgProblemResolver class has become insanely complex and 
   9    very sophisticated, it handles every test case I have thrown at it 
  10    to my satisfaction. Understanding exactly why all the steps the class 
  11    does are required is difficult and changing though not very risky 
  12    may result in other cases not working. 
  14    ##################################################################### */ 
  16 // Include Files                                                        /*{{{*/ 
  18 #pragma implementation "apt-pkg/algorithms.h" 
  20 #include <apt-pkg/algorithms.h> 
  21 #include <apt-pkg/error.h> 
  22 #include <apt-pkg/configuration.h> 
  23 #include <apt-pkg/sptr.h> 
  31 pkgProblemResolver 
*pkgProblemResolver::This 
= 0; 
  33 // Simulate::Simulate - Constructor                                     /*{{{*/ 
  34 // --------------------------------------------------------------------- 
  35 /* The legacy translations here of input Pkg iterators is obsolete,  
  36    this is not necessary since the pkgCaches are fully shared now. */ 
  37 pkgSimulate::pkgSimulate(pkgDepCache 
*Cache
) : pkgPackageManager(Cache
), 
  39                             Sim(&Cache
->GetCache(),&iPolicy
) 
  42    Flags 
= new unsigned char[Cache
->Head().PackageCount
]; 
  43    memset(Flags
,0,sizeof(*Flags
)*Cache
->Head().PackageCount
); 
  45    // Fake a filename so as not to activate the media swapping 
  46    string Jnk 
= "SIMULATE"; 
  47    for (unsigned int I 
= 0; I 
!= Cache
->Head().PackageCount
; I
++) 
  51 // Simulate::Describe - Describe a package                              /*{{{*/ 
  52 // --------------------------------------------------------------------- 
  53 /* Parameter Now == true gives both current and available varsion, 
  54    Parameter Now == false gives only the available package version */ 
  55 void pkgSimulate::Describe(PkgIterator Pkg
,ostream 
&out
,bool Now
) 
  63       Ver 
= Pkg
.CurrentVer(); 
  64       if (Ver
.end() == false) 
  65          out 
<< " [" << Ver
.VerStr() << ']'; 
  68    Ver 
= Sim
[Pkg
].CandidateVerIter(Sim
); 
  69    if (Ver
.end() == true) 
  72    out 
<< " (" << Ver
.VerStr() << ' ' << Ver
.RelStr() << ')'; 
  75 // Simulate::Install - Simulate unpacking of a package                  /*{{{*/ 
  76 // --------------------------------------------------------------------- 
  78 bool pkgSimulate::Install(PkgIterator iPkg
,string 
/*File*/) 
  81    PkgIterator Pkg 
= Sim
.FindPkg(iPkg
.Name()); 
  85    Describe(Pkg
,cout
,true); 
  86    Sim
.MarkInstall(Pkg
,false); 
  88    // Look for broken conflicts+predepends. 
  89    for (PkgIterator I 
= Sim
.PkgBegin(); I
.end() == false; I
++) 
  91       if (Sim
[I
].InstallVer 
== 0) 
  94       for (DepIterator D 
= Sim
[I
].InstVerIter(Sim
).DependsList(); D
.end() == false;) 
  99          if (Start
->Type 
== pkgCache::Dep::Conflicts 
|| 
 100              Start
->Type 
== pkgCache::Dep::Obsoletes 
|| 
 101              End
->Type 
== pkgCache::Dep::PreDepends
) 
 103             if ((Sim
[End
] & pkgDepCache::DepGInstall
) == 0) 
 105                cout 
<< " [" << I
.Name() << " on " << Start
.TargetPkg().Name() << ']'; 
 106                if (Start
->Type 
== pkgCache::Dep::Conflicts
) 
 107                   _error
->Error("Fatal, conflicts violated %s",I
.Name()); 
 113    if (Sim
.BrokenCount() != 0) 
 120 // Simulate::Configure - Simulate configuration of a Package            /*{{{*/ 
 121 // --------------------------------------------------------------------- 
 122 /* This is not an acurate simulation of relatity, we should really not 
 123    install the package.. For some investigations it may be necessary  
 125 bool pkgSimulate::Configure(PkgIterator iPkg
) 
 127    // Adapt the iterator 
 128    PkgIterator Pkg 
= Sim
.FindPkg(iPkg
.Name()); 
 131 //   Sim.MarkInstall(Pkg,false); 
 132    if (Sim
[Pkg
].InstBroken() == true) 
 134       cout 
<< "Conf " << Pkg
.Name() << " broken" << endl
; 
 138       // Print out each package and the failed dependencies 
 139       for (pkgCache::DepIterator D 
= Sim
[Pkg
].InstVerIter(Sim
).DependsList(); D
.end() == false; D
++) 
 141          if (Sim
.IsImportantDep(D
) == false ||  
 142              (Sim
[D
] & pkgDepCache::DepInstall
) != 0) 
 145          if (D
->Type 
== pkgCache::Dep::Obsoletes
) 
 146             cout 
<< " Obsoletes:" << D
.TargetPkg().Name(); 
 147          else if (D
->Type 
== pkgCache::Dep::Conflicts
) 
 148             cout 
<< " Conflicts:" << D
.TargetPkg().Name(); 
 150             cout 
<< " Depends:" << D
.TargetPkg().Name(); 
 154       _error
->Error("Conf Broken %s",Pkg
.Name()); 
 159       Describe(Pkg
,cout
,false); 
 162    if (Sim
.BrokenCount() != 0) 
 170 // Simulate::Remove - Simulate the removal of a package                 /*{{{*/ 
 171 // --------------------------------------------------------------------- 
 173 bool pkgSimulate::Remove(PkgIterator iPkg
,bool Purge
) 
 175    // Adapt the iterator 
 176    PkgIterator Pkg 
= Sim
.FindPkg(iPkg
.Name()); 
 184    Describe(Pkg
,cout
,false); 
 186    if (Sim
.BrokenCount() != 0) 
 194 // Simulate::ShortBreaks - Print out a short line describing all breaks /*{{{*/ 
 195 // --------------------------------------------------------------------- 
 197 void pkgSimulate::ShortBreaks() 
 200    for (PkgIterator I 
= Sim
.PkgBegin(); I
.end() == false; I
++) 
 202       if (Sim
[I
].InstBroken() == true) 
 204          if (Flags
[I
->ID
] == 0) 
 205             cout 
<< I
.Name() << ' '; 
 207             cout << I.Name() << "! ";*/ 
 213 // ApplyStatus - Adjust for non-ok packages                             /*{{{*/ 
 214 // --------------------------------------------------------------------- 
 215 /* We attempt to change the state of the all packages that have failed 
 216    installation toward their real state. The ordering code will perform  
 217    the necessary calculations to deal with the problems. */ 
 218 bool pkgApplyStatus(pkgDepCache 
&Cache
) 
 220    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 222       if (I
->VersionList 
== 0) 
 225       // Only choice for a ReInstReq package is to reinstall 
 226       if (I
->InstState 
== pkgCache::State::ReInstReq 
|| 
 227           I
->InstState 
== pkgCache::State::HoldReInstReq
) 
 229          if (I
->CurrentVer 
!= 0 && I
.CurrentVer().Downloadable() == true) 
 233             // Is this right? Will dpkg choke on an upgrade? 
 234             if (Cache
[I
].CandidateVer 
!= 0 && 
 235                  Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true) 
 236                Cache
.MarkInstall(I
); 
 238                return _error
->Error(_("The package %s needs to be reinstalled, " 
 239                                     "but I can't find an archive for it."),I
.Name()); 
 245       switch (I
->CurrentState
) 
 247          /* This means installation failed somehow - it does not need to be 
 248             re-unpacked (probably) */ 
 249          case pkgCache::State::UnPacked
: 
 250          case pkgCache::State::HalfConfigured
: 
 251          if ((I
->CurrentVer 
!= 0 && I
.CurrentVer().Downloadable() == true) || 
 252              I
.State() != pkgCache::PkgIterator::NeedsUnpack
) 
 256             if (Cache
[I
].CandidateVer 
!= 0 && 
 257                  Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true) 
 258                Cache
.MarkInstall(I
); 
 264          // This means removal failed 
 265          case pkgCache::State::HalfInstalled
: 
 270          if (I
->InstState 
!= pkgCache::State::Ok
) 
 271             return _error
->Error("The package %s is not ok and I " 
 272                                  "don't know how to fix it!",I
.Name()); 
 278 // FixBroken - Fix broken packages                                      /*{{{*/ 
 279 // --------------------------------------------------------------------- 
 280 /* This autoinstalls every broken package and then runs the problem resolver 
 282 bool pkgFixBroken(pkgDepCache 
&Cache
) 
 284    // Auto upgrade all broken packages 
 285    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 286       if (Cache
[I
].NowBroken() == true) 
 287          Cache
.MarkInstall(I
,true); 
 289    /* Fix packages that are in a NeedArchive state but don't have a 
 290       downloadable install version */ 
 291    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 293       if (I
.State() != pkgCache::PkgIterator::NeedsUnpack 
|| 
 294           Cache
[I
].Delete() == true) 
 297       if (Cache
[I
].InstVerIter(Cache
).Downloadable() == false) 
 300       Cache
.MarkInstall(I
,true);       
 303    pkgProblemResolver 
Fix(&Cache
); 
 304    return Fix
.Resolve(true); 
 307 // DistUpgrade - Distribution upgrade                                   /*{{{*/ 
 308 // --------------------------------------------------------------------- 
 309 /* This autoinstalls every package and then force installs every  
 310    pre-existing package. This creates the initial set of conditions which  
 311    most likely contain problems because too many things were installed. 
 313    The problem resolver is used to resolve the problems. 
 315 bool pkgDistUpgrade(pkgDepCache 
&Cache
) 
 317    /* Auto upgrade all installed packages, this provides the basis  
 318       for the installation */ 
 319    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 320       if (I
->CurrentVer 
!= 0) 
 321          Cache
.MarkInstall(I
,true); 
 323    /* Now, auto upgrade all essential packages - this ensures that 
 324       the essential packages are present and working */ 
 325    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 326       if ((I
->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
) 
 327          Cache
.MarkInstall(I
,true); 
 329    /* We do it again over all previously installed packages to force  
 330       conflict resolution on them all. */ 
 331    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 332       if (I
->CurrentVer 
!= 0) 
 333          Cache
.MarkInstall(I
,false); 
 335    pkgProblemResolver 
Fix(&Cache
); 
 337    // Hold back held packages. 
 338    if (_config
->FindB("APT::Ignore-Hold",false) == false) 
 340       for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 342          if (I
->SelectedState 
== pkgCache::State::Hold
) 
 350    return Fix
.Resolve(); 
 353 // AllUpgrade - Upgrade as many packages as possible                    /*{{{*/ 
 354 // --------------------------------------------------------------------- 
 355 /* Right now the system must be consistent before this can be called. 
 356    It also will not change packages marked for install, it only tries 
 357    to install packages not marked for install */ 
 358 bool pkgAllUpgrade(pkgDepCache 
&Cache
) 
 360    pkgProblemResolver 
Fix(&Cache
); 
 362    if (Cache
.BrokenCount() != 0) 
 365    // Upgrade all installed packages 
 366    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 368       if (Cache
[I
].Install() == true) 
 371       if (_config
->FindB("APT::Ignore-Hold",false) == false) 
 372          if (I
->SelectedState 
== pkgCache::State::Hold
) 
 375       if (I
->CurrentVer 
!= 0 && Cache
[I
].InstallVer 
!= 0) 
 376          Cache
.MarkInstall(I
,false); 
 379    return Fix
.ResolveByKeep(); 
 382 // MinimizeUpgrade - Minimizes the set of packages to be upgraded       /*{{{*/ 
 383 // --------------------------------------------------------------------- 
 384 /* This simply goes over the entire set of packages and tries to keep  
 385    each package marked for upgrade. If a conflict is generated then  
 386    the package is restored. */ 
 387 bool pkgMinimizeUpgrade(pkgDepCache 
&Cache
) 
 389    if (Cache
.BrokenCount() != 0) 
 392    // We loop for 10 tries to get the minimal set size. 
 394    unsigned int Count 
= 0; 
 398       for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 401          if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true) 
 404          // Keep it and see if that is OK 
 406          if (Cache
.BrokenCount() != 0) 
 407             Cache
.MarkInstall(I
,false); 
 410             // If keep didnt actually do anything then there was no change.. 
 411             if (Cache
[I
].Upgrade() == false) 
 417    while (Change 
== true && Count 
< 10); 
 419    if (Cache
.BrokenCount() != 0) 
 420       return _error
->Error("Internal Error in pkgMinimizeUpgrade"); 
 426 // ProblemResolver::pkgProblemResolver - Constructor                    /*{{{*/ 
 427 // --------------------------------------------------------------------- 
 429 pkgProblemResolver::pkgProblemResolver(pkgDepCache 
*pCache
) : Cache(*pCache
) 
 432    unsigned long Size 
= Cache
.Head().PackageCount
; 
 433    Scores 
= new signed short[Size
]; 
 434    Flags 
= new unsigned char[Size
]; 
 435    memset(Flags
,0,sizeof(*Flags
)*Size
); 
 437    // Set debug to true to see its decision logic 
 438    Debug 
= _config
->FindB("Debug::pkgProblemResolver",false); 
 441 // ProblemResolver::~pkgProblemResolver - Destructor                    /*{{{*/ 
 442 // --------------------------------------------------------------------- 
 444 pkgProblemResolver::~pkgProblemResolver() 
 450 // ProblemResolver::ScoreSort - Sort the list by score                  /*{{{*/ 
 451 // --------------------------------------------------------------------- 
 453 int pkgProblemResolver::ScoreSort(const void *a
,const void *b
) 
 455    Package 
const **A 
= (Package 
const **)a
; 
 456    Package 
const **B 
= (Package 
const **)b
; 
 457    if (This
->Scores
[(*A
)->ID
] > This
->Scores
[(*B
)->ID
]) 
 459    if (This
->Scores
[(*A
)->ID
] < This
->Scores
[(*B
)->ID
]) 
 464 // ProblemResolver::MakeScores - Make the score table                   /*{{{*/ 
 465 // --------------------------------------------------------------------- 
 467 void pkgProblemResolver::MakeScores() 
 469    unsigned long Size 
= Cache
.Head().PackageCount
; 
 470    memset(Scores
,0,sizeof(*Scores
)*Size
); 
 472    // Generate the base scores for a package based on its properties 
 473    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 475       if (Cache
[I
].InstallVer 
== 0) 
 478       signed short &Score 
= Scores
[I
->ID
]; 
 480       /* This is arbitary, it should be high enough to elevate an 
 481          essantial package above most other packages but low enough 
 482          to allow an obsolete essential packages to be removed by 
 483          a conflicts on a powerfull normal package (ie libc6) */ 
 484       if ((I
->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
) 
 487       // We transform the priority 
 488       // Important Required Standard Optional Extra 
 489       signed short PrioMap
[] = {0,3,2,1,-1,-2}; 
 490       if (Cache
[I
].InstVerIter(Cache
)->Priority 
<= 5) 
 491          Score 
+= PrioMap
[Cache
[I
].InstVerIter(Cache
)->Priority
]; 
 493       /* This helps to fix oddball problems with conflicting packages 
 494          on the same level. We enhance the score of installed packages */ 
 495       if (I
->CurrentVer 
!= 0) 
 499    // Now that we have the base scores we go and propogate dependencies 
 500    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 502       if (Cache
[I
].InstallVer 
== 0) 
 505       for (pkgCache::DepIterator D 
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false; D
++) 
 507          if (D
->Type 
== pkgCache::Dep::Depends 
|| D
->Type 
== pkgCache::Dep::PreDepends
) 
 508             Scores
[D
.TargetPkg()->ID
]++; 
 512    // Copy the scores to advoid additive looping 
 513    SPtrArray
<signed short> OldScores 
= new signed short[Size
]; 
 514    memcpy(OldScores
,Scores
,sizeof(*Scores
)*Size
); 
 516    /* Now we cause 1 level of dependency inheritance, that is we add the  
 517       score of the packages that depend on the target Package. This  
 518       fortifies high scoring packages */ 
 519    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 521       if (Cache
[I
].InstallVer 
== 0) 
 524       for (pkgCache::DepIterator D 
= I
.RevDependsList(); D
.end() == false; D
++) 
 526          // Only do it for the install version 
 527          if ((pkgCache::Version 
*)D
.ParentVer() != Cache
[D
.ParentPkg()].InstallVer 
|| 
 528              (D
->Type 
!= pkgCache::Dep::Depends 
&& D
->Type 
!= pkgCache::Dep::PreDepends
)) 
 531          Scores
[I
->ID
] += abs(OldScores
[D
.ParentPkg()->ID
]); 
 535    /* Now we propogate along provides. This makes the packages that  
 536       provide important packages extremely important */ 
 537    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 539       for (pkgCache::PrvIterator P 
= I
.ProvidesList(); P
.end() == false; P
++) 
 541          // Only do it once per package 
 542          if ((pkgCache::Version 
*)P
.OwnerVer() != Cache
[P
.OwnerPkg()].InstallVer
) 
 544          Scores
[P
.OwnerPkg()->ID
] += abs(Scores
[I
->ID
] - OldScores
[I
->ID
]); 
 548    /* Protected things are pushed really high up. This number should put them 
 549       ahead of everything */ 
 550    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 552       if ((Flags
[I
->ID
] & Protected
) != 0) 
 553          Scores
[I
->ID
] += 10000; 
 554       if ((I
->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
) 
 555          Scores
[I
->ID
] += 5000; 
 559 // ProblemResolver::DoUpgrade - Attempt to upgrade this package         /*{{{*/ 
 560 // --------------------------------------------------------------------- 
 561 /* This goes through and tries to reinstall packages to make this package 
 563 bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg
) 
 565    if ((Flags
[Pkg
->ID
] & Upgradable
) == 0 || Cache
[Pkg
].Upgradable() == false) 
 567    if ((Flags
[Pkg
->ID
] & Protected
) == Protected
) 
 570    Flags
[Pkg
->ID
] &= ~Upgradable
; 
 572    bool WasKept 
= Cache
[Pkg
].Keep(); 
 573    Cache
.MarkInstall(Pkg
,false); 
 575    // This must be a virtual package or something like that. 
 576    if (Cache
[Pkg
].InstVerIter(Cache
).end() == true) 
 579    // Isolate the problem dependency 
 581    for (pkgCache::DepIterator D 
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); D
.end() == false;) 
 583       // Compute a single dependency element (glob or) 
 584       pkgCache::DepIterator Start 
= D
; 
 585       pkgCache::DepIterator End 
= D
; 
 586       unsigned char State 
= 0; 
 587       for (bool LastOR 
= true; D
.end() == false && LastOR 
== true;) 
 590          LastOR 
= (D
->CompareOp 
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
; 
 596       // We only worry about critical deps. 
 597       if (End
.IsCritical() != true) 
 600       // Iterate over all the members in the or group 
 604          if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
) 
 607          // Do not change protected packages 
 608          PkgIterator P 
= Start
.SmartTargetPkg(); 
 609          if ((Flags
[P
->ID
] & Protected
) == Protected
) 
 612                clog 
<< "    Reinst Failed because of protected " << P
.Name() << endl
; 
 617             // Upgrade the package if the candidate version will fix the problem. 
 618             if ((Cache
[Start
] & pkgDepCache::DepCVer
) == pkgDepCache::DepCVer
) 
 620                if (DoUpgrade(P
) == false) 
 623                      clog 
<< "    Reinst Failed because of " << P
.Name() << endl
; 
 634                /* We let the algorithm deal with conflicts on its next iteration, 
 635                 it is much smarter than us */ 
 636                if (Start
->Type 
== pkgCache::Dep::Conflicts 
||  
 637                    Start
->Type 
== pkgCache::Dep::Obsoletes
) 
 641                   clog 
<< "    Reinst Failed early because of " << Start
.TargetPkg().Name() << endl
; 
 654    // Undo our operations - it might be smart to undo everything this did.. 
 660          Cache
.MarkDelete(Pkg
); 
 665       clog 
<< "  Re-Instated " << Pkg
.Name() << endl
; 
 669 // ProblemResolver::Resolve - Run the resolution pass                   /*{{{*/ 
 670 // --------------------------------------------------------------------- 
 671 /* This routines works by calculating a score for each package. The score 
 672    is derived by considering the package's priority and all reverse  
 673    dependents giving an integer that reflects the amount of breakage that 
 674    adjusting the package will inflict.  
 676    It goes from highest score to lowest and corrects all of the breaks by  
 677    keeping or removing the dependant packages. If that fails then it removes 
 678    the package itself and goes on. The routine should be able to intelligently 
 679    go from any broken state to a fixed state.  
 681    The BrokenFix flag enables a mode where the algorithm tries to  
 682    upgrade packages to advoid problems. */ 
 683 bool pkgProblemResolver::Resolve(bool BrokenFix
) 
 685    unsigned long Size 
= Cache
.Head().PackageCount
; 
 687    // Record which packages are marked for install 
 692       for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 694          if (Cache
[I
].Install() == true) 
 695             Flags
[I
->ID
] |= PreInstalled
; 
 698             if (Cache
[I
].InstBroken() == true && BrokenFix 
== true) 
 700                Cache
.MarkInstall(I
,false); 
 701                if (Cache
[I
].Install() == true) 
 705             Flags
[I
->ID
] &= ~PreInstalled
; 
 707          Flags
[I
->ID
] |= Upgradable
; 
 710    while (Again 
== true); 
 713       clog 
<< "Starting" << endl
; 
 717    /* We have to order the packages so that the broken fixing pass  
 718       operates from highest score to lowest. This prevents problems when 
 719       high score packages cause the removal of lower score packages that 
 720       would cause the removal of even lower score packages. */ 
 721    SPtrArray
<pkgCache::Package 
*> PList 
= new pkgCache::Package 
*[Size
]; 
 722    pkgCache::Package 
**PEnd 
= PList
; 
 723    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 726    qsort(PList
,PEnd 
- PList
,sizeof(*PList
),&ScoreSort
); 
 728 /* for (pkgCache::Package **K = PList; K != PEnd; K++) 
 729       if (Scores[(*K)->ID] != 0) 
 731          pkgCache::PkgIterator Pkg(Cache,*K); 
 732          clog << Scores[(*K)->ID] << ' ' << Pkg.Name() << 
 733             ' ' << (pkgCache::Version *)Pkg.CurrentVer() << ' ' <<  
 734             Cache[Pkg].InstallVer << ' ' << Cache[Pkg].CandidateVer << endl; 
 738       clog 
<< "Starting 2" << endl
; 
 740    /* Now consider all broken packages. For each broken package we either 
 741       remove the package or fix it's problem. We do this once, it should 
 742       not be possible for a loop to form (that is a < b < c and fixing b by 
 743       changing a breaks c) */ 
 745    for (int Counter 
= 0; Counter 
!= 10 && Change 
== true; Counter
++) 
 748       for (pkgCache::Package 
**K 
= PList
; K 
!= PEnd
; K
++) 
 750          pkgCache::PkgIterator 
I(Cache
,*K
); 
 752          /* We attempt to install this and see if any breaks result, 
 753             this takes care of some strange cases */ 
 754          if (Cache
[I
].CandidateVer 
!= Cache
[I
].InstallVer 
&& 
 755              I
->CurrentVer 
!= 0 && Cache
[I
].InstallVer 
!= 0 && 
 756              (Flags
[I
->ID
] & PreInstalled
) != 0 && 
 757              (Flags
[I
->ID
] & Protected
) == 0 && 
 758              (Flags
[I
->ID
] & ReInstateTried
) == 0) 
 761                clog 
<< " Try to Re-Instate " << I
.Name() << endl
; 
 762             unsigned long OldBreaks 
= Cache
.BrokenCount(); 
 763             pkgCache::Version 
*OldVer 
= Cache
[I
].InstallVer
; 
 764             Flags
[I
->ID
] &= ReInstateTried
; 
 766             Cache
.MarkInstall(I
,false); 
 767             if (Cache
[I
].InstBroken() == true ||  
 768                 OldBreaks 
< Cache
.BrokenCount()) 
 777                   clog 
<< "Re-Instated " << I
.Name() << " (" << OldBreaks 
<< " vs " << Cache
.BrokenCount() << ')' << endl
; 
 780          if (Cache
[I
].InstallVer 
== 0 || Cache
[I
].InstBroken() == false) 
 784             cout 
<< "Investigating " << I
.Name() << endl
; 
 786          // Isolate the problem dependency 
 787          PackageKill KillList
[100]; 
 788          PackageKill 
*LEnd 
= KillList
; 
 790          pkgCache::DepIterator Start
; 
 791          pkgCache::DepIterator End
; 
 792          PackageKill 
*OldEnd 
= LEnd
; 
 794          enum {OrRemove
,OrKeep
} OrOp 
= OrRemove
; 
 795          for (pkgCache::DepIterator D 
= Cache
[I
].InstVerIter(Cache
).DependsList(); 
 796               D
.end() == false || InOr 
== true;) 
 798             // Compute a single dependency element (glob or) 
 804                   if (OldEnd 
== LEnd 
&& OrOp 
== OrRemove
) 
 806                      if ((Flags
[I
->ID
] & Protected
) != Protected
) 
 809                            clog 
<< "  Or group remove for " << I
.Name() << endl
; 
 814                   if (OldEnd 
== LEnd 
&& OrOp 
== OrKeep
) 
 817                         clog 
<< "  Or group keep for " << I
.Name() << endl
; 
 823                /* We do an extra loop (as above) to finalize the or group 
 828                if (Start
.end() == true) 
 831                // We only worry about critical deps. 
 832                if (End
.IsCritical() != true) 
 842             if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
) 
 849                clog 
<< "Package " << I
.Name() << " has broken dep on " << Start
.TargetPkg().Name() << endl
; 
 851             /* Look across the version list. If there are no possible 
 852                targets then we keep the package and bail. This is necessary 
 853                if a package has a dep on another package that cant be found */ 
 854             SPtrArray
<pkgCache::Version 
*> VList 
= Start
.AllTargets(); 
 855             if (*VList 
== 0 && (Flags
[I
->ID
] & Protected
) != Protected 
&& 
 856                 Start
->Type 
!= pkgCache::Dep::Conflicts 
&& 
 857                 Start
->Type 
!= pkgCache::Dep::Obsoletes 
&& 
 858                 Cache
[I
].NowBroken() == false) 
 862                   /* No keep choice because the keep being OK could be the 
 863                      result of another element in the OR group! */ 
 873             for (pkgCache::Version 
**V 
= VList
; *V 
!= 0; V
++) 
 875                pkgCache::VerIterator 
Ver(Cache
,*V
); 
 876                pkgCache::PkgIterator Pkg 
= Ver
.ParentPkg(); 
 879                   clog 
<< "  Considering " << Pkg
.Name() << ' ' << (int)Scores
[Pkg
->ID
] << 
 880                   " as a solution to " << I
.Name() << ' ' << (int)Scores
[I
->ID
] << endl
; 
 882                /* Try to fix the package under consideration rather than 
 883                   fiddle with the VList package */ 
 884                if (Scores
[I
->ID
] <= Scores
[Pkg
->ID
] || 
 885                    ((Cache
[Start
] & pkgDepCache::DepNow
) == 0 && 
 886                     End
->Type 
!= pkgCache::Dep::Conflicts 
&& 
 887                     End
->Type 
!= pkgCache::Dep::Obsoletes
)) 
 889                   // Try a little harder to fix protected packages.. 
 890                   if ((Flags
[I
->ID
] & Protected
) == Protected
) 
 892                      if (DoUpgrade(Pkg
) == true) 
 894                         if (Scores
[Pkg
->ID
] > Scores
[I
->ID
]) 
 895                            Scores
[Pkg
->ID
] = Scores
[I
->ID
]; 
 902                   /* See if a keep will do, unless the package is protected, 
 903                      then installing it will be necessary */ 
 904                   bool Installed 
= Cache
[I
].Install(); 
 906                   if (Cache
[I
].InstBroken() == false) 
 908                      // Unwind operation will be keep now 
 909                      if (OrOp 
== OrRemove
) 
 913                      if (InOr 
== true && Installed 
== true) 
 914                         Cache
.MarkInstall(I
,false); 
 917                         clog 
<< "  Holding Back " << I
.Name() << " rather than change " << Start
.TargetPkg().Name() << endl
; 
 921                      if (BrokenFix 
== false || DoUpgrade(I
) == false) 
 923                         // Consider other options 
 927                               clog 
<< "  Removing " << I
.Name() << " rather than change " << Start
.TargetPkg().Name() << endl
; 
 931                               if (Scores
[Pkg
->ID
] > Scores
[I
->ID
]) 
 932                                  Scores
[I
->ID
] = Scores
[Pkg
->ID
]; 
 944                   /* This is a conflicts, and the version we are looking 
 945                      at is not the currently selected version of the  
 946                      package, which means it is not necessary to  
 948                   if (Cache
[Pkg
].InstallVer 
!= Ver 
&& 
 949                       (Start
->Type 
== pkgCache::Dep::Conflicts 
|| 
 950                        Start
->Type 
== pkgCache::Dep::Obsoletes
)) 
 953                   // Skip adding to the kill list if it is protected 
 954                   if ((Flags
[Pkg
->ID
] & Protected
) != 0) 
 958                      clog 
<< "  Added " << Pkg
.Name() << " to the remove list" << endl
; 
 964                   if (Start
->Type 
!= pkgCache::Dep::Conflicts 
&& 
 965                       Start
->Type 
!= pkgCache::Dep::Obsoletes
) 
 970             // Hm, nothing can possibly satisify this dep. Nuke it. 
 972                 Start
->Type 
!= pkgCache::Dep::Conflicts 
&& 
 973                 Start
->Type 
!= pkgCache::Dep::Obsoletes 
&& 
 974                 (Flags
[I
->ID
] & Protected
) != Protected
) 
 976                bool Installed 
= Cache
[I
].Install(); 
 978                if (Cache
[I
].InstBroken() == false) 
 980                   // Unwind operation will be keep now 
 981                   if (OrOp 
== OrRemove
) 
 985                   if (InOr 
== true && Installed 
== true) 
 986                      Cache
.MarkInstall(I
,false); 
 989                      clog 
<< "  Holding Back " << I
.Name() << " because I can't find " << Start
.TargetPkg().Name() << endl
; 
 994                      clog 
<< "  Removing " << I
.Name() << " because I can't find " << Start
.TargetPkg().Name() << endl
; 
1011          // Apply the kill list now 
1012          if (Cache
[I
].InstallVer 
!= 0) 
1014             for (PackageKill 
*J 
= KillList
; J 
!= LEnd
; J
++) 
1017                if ((Cache
[J
->Dep
] & pkgDepCache::DepGNow
) == 0) 
1019                   if (J
->Dep
->Type 
== pkgCache::Dep::Conflicts 
||  
1020                       J
->Dep
->Type 
== pkgCache::Dep::Obsoletes
) 
1023                         clog 
<< "  Fixing " << I
.Name() << " via remove of " << J
->Pkg
.Name() << endl
; 
1024                      Cache
.MarkDelete(J
->Pkg
); 
1030                      clog 
<< "  Fixing " << I
.Name() << " via keep of " << J
->Pkg
.Name() << endl
; 
1031                   Cache
.MarkKeep(J
->Pkg
); 
1036                   if (Scores
[I
->ID
] > Scores
[J
->Pkg
->ID
])                  
1037                      Scores
[J
->Pkg
->ID
] = Scores
[I
->ID
]; 
1045       clog 
<< "Done" << endl
; 
1047    if (Cache
.BrokenCount() != 0) 
1049       // See if this is the result of a hold 
1050       pkgCache::PkgIterator I 
= Cache
.PkgBegin(); 
1051       for (;I
.end() != true; I
++) 
1053          if (Cache
[I
].InstBroken() == false) 
1055          if ((Flags
[I
->ID
] & Protected
) != Protected
) 
1056             return _error
->Error(_("Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages.")); 
1058       return _error
->Error(_("Unable to correct problems, you have held broken packages.")); 
1064 // ProblemResolver::ResolveByKeep - Resolve problems using keep         /*{{{*/ 
1065 // --------------------------------------------------------------------- 
1066 /* This is the work horse of the soft upgrade routine. It is very gental  
1067    in that it does not install or remove any packages. It is assumed that the 
1068    system was non-broken previously. */ 
1069 bool pkgProblemResolver::ResolveByKeep() 
1071    unsigned long Size 
= Cache
.Head().PackageCount
; 
1074       clog 
<< "Entering ResolveByKeep" << endl
; 
1078    /* We have to order the packages so that the broken fixing pass  
1079       operates from highest score to lowest. This prevents problems when 
1080       high score packages cause the removal of lower score packages that 
1081       would cause the removal of even lower score packages. */ 
1082    pkgCache::Package 
**PList 
= new pkgCache::Package 
*[Size
]; 
1083    pkgCache::Package 
**PEnd 
= PList
; 
1084    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
1087    qsort(PList
,PEnd 
- PList
,sizeof(*PList
),&ScoreSort
); 
1089    // Consider each broken package  
1090    pkgCache::Package 
**LastStop 
= 0; 
1091    for (pkgCache::Package 
**K 
= PList
; K 
!= PEnd
; K
++) 
1093       pkgCache::PkgIterator 
I(Cache
,*K
); 
1095       if (Cache
[I
].InstallVer 
== 0 || Cache
[I
].InstBroken() == false) 
1098       /* Keep the package. If this works then great, otherwise we have 
1099          to be significantly more agressive and manipulate its dependencies */ 
1100       if ((Flags
[I
->ID
] & Protected
) == 0) 
1103             clog 
<< "Keeping package " << I
.Name() << endl
; 
1105          if (Cache
[I
].InstBroken() == false) 
1112       // Isolate the problem dependencies 
1113       for (pkgCache::DepIterator D 
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;) 
1117          D
.GlobOr(Start
,End
); 
1119          // We only worry about critical deps. 
1120          if (End
.IsCritical() != true) 
1124          if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
) 
1127          /* Hm, the group is broken.. I suppose the best thing to do is to 
1128             is to try every combination of keep/not-keep for the set, but thats 
1129             slow, and this never happens, just be conservative and assume the 
1130             list of ors is in preference and keep till it starts to work. */ 
1134                clog 
<< "Package " << I
.Name() << " has broken dep on " << Start
.TargetPkg().Name() << endl
; 
1136             // Look at all the possible provides on this package 
1137             SPtrArray
<pkgCache::Version 
*> VList 
= Start
.AllTargets(); 
1138             for (pkgCache::Version 
**V 
= VList
; *V 
!= 0; V
++) 
1140                pkgCache::VerIterator 
Ver(Cache
,*V
); 
1141                pkgCache::PkgIterator Pkg 
= Ver
.ParentPkg(); 
1143                // It is not keepable 
1144                if (Cache
[Pkg
].InstallVer 
== 0 || 
1145                    Pkg
->CurrentVer 
== 0) 
1148                if ((Flags
[I
->ID
] & Protected
) == 0) 
1151                      clog 
<< "  Keeping Package " << Pkg
.Name() << " due to dep" << endl
; 
1152                   Cache
.MarkKeep(Pkg
); 
1155                if (Cache
[I
].InstBroken() == false) 
1159             if (Cache
[I
].InstBroken() == false) 
1167          if (Cache
[I
].InstBroken() == false) 
1171       if (Cache
[I
].InstBroken() == true) 
1176          return _error
->Error("Internal Error, pkgProblemResolver::ResolveByKeep is looping on package %s.",I
.Name()); 
1184 // ProblemResolver::InstallProtect - Install all protected packages     /*{{{*/ 
1185 // --------------------------------------------------------------------- 
1186 /* This is used to make sure protected packages are installed */ 
1187 void pkgProblemResolver::InstallProtect() 
1189    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
1191       if ((Flags
[I
->ID
] & Protected
) == Protected
) 
1193          if ((Flags
[I
->ID
] & ToRemove
) == ToRemove
) 
1194             Cache
.MarkDelete(I
); 
1196             Cache
.MarkInstall(I
,false); 
1202 // PrioSortList - Sort a list of versions by priority                   /*{{{*/ 
1203 // --------------------------------------------------------------------- 
1204 /* This is ment to be used in conjunction with AllTargets to get a list  
1205    of versions ordered by preference. */ 
1206 static pkgCache 
*PrioCache
; 
1207 static int PrioComp(const void *A
,const void *B
) 
1209    pkgCache::VerIterator 
L(*PrioCache
,*(pkgCache::Version 
**)A
); 
1210    pkgCache::VerIterator 
R(*PrioCache
,*(pkgCache::Version 
**)B
); 
1212    if ((L
.ParentPkg()->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential 
&& 
1213        (R
.ParentPkg()->Flags 
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
) 
1215    if ((L
.ParentPkg()->Flags 
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential 
&& 
1216        (R
.ParentPkg()->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
) 
1219    if (L
->Priority 
!= R
->Priority
) 
1220       return R
->Priority 
- L
->Priority
; 
1221    return strcmp(L
.ParentPkg().Name(),R
.ParentPkg().Name()); 
1223 void pkgPrioSortList(pkgCache 
&Cache
,pkgCache::Version 
**List
) 
1225    unsigned long Count 
= 0; 
1227    for (pkgCache::Version 
**I 
= List
; *I 
!= 0; I
++) 
1229    qsort(List
,Count
,sizeof(*List
),PrioComp
);