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                                                        /*{{{*/ 
  17 #include <apt-pkg/algorithms.h> 
  18 #include <apt-pkg/error.h> 
  19 #include <apt-pkg/configuration.h> 
  20 #include <apt-pkg/version.h> 
  21 #include <apt-pkg/sptr.h> 
  22 #include <apt-pkg/acquire-item.h> 
  23 #include <apt-pkg/edsp.h> 
  26 #include <sys/types.h> 
  35 pkgProblemResolver 
*pkgProblemResolver::This 
= 0; 
  37 // Simulate::Simulate - Constructor                                     /*{{{*/ 
  38 // --------------------------------------------------------------------- 
  39 /* The legacy translations here of input Pkg iterators is obsolete,  
  40    this is not necessary since the pkgCaches are fully shared now. */ 
  41 pkgSimulate::pkgSimulate(pkgDepCache 
*Cache
) : pkgPackageManager(Cache
), 
  43                             Sim(&Cache
->GetCache(),&iPolicy
), 
  47    Flags 
= new unsigned char[Cache
->Head().PackageCount
]; 
  48    memset(Flags
,0,sizeof(*Flags
)*Cache
->Head().PackageCount
); 
  50    // Fake a filename so as not to activate the media swapping 
  51    string Jnk 
= "SIMULATE"; 
  52    for (unsigned int I 
= 0; I 
!= Cache
->Head().PackageCount
; I
++) 
  56 // Simulate::Describe - Describe a package                              /*{{{*/ 
  57 // --------------------------------------------------------------------- 
  58 /* Parameter Current == true displays the current package version, 
  59    Parameter Candidate == true displays the candidate package version */ 
  60 void pkgSimulate::Describe(PkgIterator Pkg
,ostream 
&out
,bool Current
,bool Candidate
) 
  64    out 
<< Pkg
.FullName(true); 
  68       Ver 
= Pkg
.CurrentVer(); 
  69       if (Ver
.end() == false) 
  70          out 
<< " [" << Ver
.VerStr() << ']'; 
  73    if (Candidate 
== true) 
  75       Ver 
= Sim
[Pkg
].CandidateVerIter(Sim
); 
  76       if (Ver
.end() == true) 
  79       out 
<< " (" << Ver
.VerStr() << ' ' << Ver
.RelStr() << ')'; 
  83 // Simulate::Install - Simulate unpacking of a package                  /*{{{*/ 
  84 // --------------------------------------------------------------------- 
  86 bool pkgSimulate::Install(PkgIterator iPkg
,string 
/*File*/) 
  89    PkgIterator Pkg 
= Sim
.FindPkg(iPkg
.Name(), iPkg
.Arch()); 
  93    Describe(Pkg
,cout
,true,true); 
  94    Sim
.MarkInstall(Pkg
,false); 
  96    // Look for broken conflicts+predepends. 
  97    for (PkgIterator I 
= Sim
.PkgBegin(); I
.end() == false; I
++) 
  99       if (Sim
[I
].InstallVer 
== 0) 
 102       for (DepIterator D 
= Sim
[I
].InstVerIter(Sim
).DependsList(); D
.end() == false;) 
 107          if (Start
->Type 
== pkgCache::Dep::Conflicts 
|| 
 108              Start
->Type 
== pkgCache::Dep::DpkgBreaks 
|| 
 109              Start
->Type 
== pkgCache::Dep::Obsoletes 
|| 
 110              End
->Type 
== pkgCache::Dep::PreDepends
) 
 112             if ((Sim
[End
] & pkgDepCache::DepGInstall
) == 0) 
 114                cout 
<< " [" << I
.FullName(false) << " on " << Start
.TargetPkg().FullName(false) << ']'; 
 115                if (Start
->Type 
== pkgCache::Dep::Conflicts
) 
 116                   _error
->Error("Fatal, conflicts violated %s",I
.FullName(false).c_str()); 
 122    if (Sim
.BrokenCount() != 0) 
 129 // Simulate::Configure - Simulate configuration of a Package            /*{{{*/ 
 130 // --------------------------------------------------------------------- 
 131 /* This is not an acurate simulation of relatity, we should really not 
 132    install the package.. For some investigations it may be necessary  
 134 bool pkgSimulate::Configure(PkgIterator iPkg
) 
 136    // Adapt the iterator 
 137    PkgIterator Pkg 
= Sim
.FindPkg(iPkg
.Name(), iPkg
.Arch()); 
 141    if (Sim
[Pkg
].InstBroken() == true) 
 143       cout 
<< "Conf " << Pkg
.FullName(false) << " broken" << endl
; 
 147       // Print out each package and the failed dependencies 
 148       for (pkgCache::DepIterator D 
= Sim
[Pkg
].InstVerIter(Sim
).DependsList(); D
.end() == false; D
++) 
 150          if (Sim
.IsImportantDep(D
) == false ||  
 151              (Sim
[D
] & pkgDepCache::DepInstall
) != 0) 
 154          if (D
->Type 
== pkgCache::Dep::Obsoletes
) 
 155             cout 
<< " Obsoletes:" << D
.TargetPkg().FullName(false); 
 156          else if (D
->Type 
== pkgCache::Dep::Conflicts
) 
 157             cout 
<< " Conflicts:" << D
.TargetPkg().FullName(false); 
 158          else if (D
->Type 
== pkgCache::Dep::DpkgBreaks
) 
 159             cout 
<< " Breaks:" << D
.TargetPkg().FullName(false); 
 161             cout 
<< " Depends:" << D
.TargetPkg().FullName(false); 
 165       _error
->Error("Conf Broken %s",Pkg
.FullName(false).c_str()); 
 170       Describe(Pkg
,cout
,false,true); 
 173    if (Sim
.BrokenCount() != 0) 
 181 // Simulate::Remove - Simulate the removal of a package                 /*{{{*/ 
 182 // --------------------------------------------------------------------- 
 184 bool pkgSimulate::Remove(PkgIterator iPkg
,bool Purge
) 
 186    // Adapt the iterator 
 187    PkgIterator Pkg 
= Sim
.FindPkg(iPkg
.Name(), iPkg
.Arch()); 
 196    Describe(Pkg
,cout
,true,false); 
 198    if (Sim
.BrokenCount() != 0) 
 206 // Simulate::ShortBreaks - Print out a short line describing all breaks /*{{{*/ 
 207 // --------------------------------------------------------------------- 
 209 void pkgSimulate::ShortBreaks() 
 212    for (PkgIterator I 
= Sim
.PkgBegin(); I
.end() == false; I
++) 
 214       if (Sim
[I
].InstBroken() == true) 
 216          if (Flags
[I
->ID
] == 0) 
 217             cout 
<< I
.FullName(false) << ' '; 
 219             cout << I.Name() << "! ";*/ 
 225 // ApplyStatus - Adjust for non-ok packages                             /*{{{*/ 
 226 // --------------------------------------------------------------------- 
 227 /* We attempt to change the state of the all packages that have failed 
 228    installation toward their real state. The ordering code will perform  
 229    the necessary calculations to deal with the problems. */ 
 230 bool pkgApplyStatus(pkgDepCache 
&Cache
) 
 232    pkgDepCache::ActionGroup 
group(Cache
); 
 234    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 236       if (I
->VersionList 
== 0) 
 239       // Only choice for a ReInstReq package is to reinstall 
 240       if (I
->InstState 
== pkgCache::State::ReInstReq 
|| 
 241           I
->InstState 
== pkgCache::State::HoldReInstReq
) 
 243          if (I
->CurrentVer 
!= 0 && I
.CurrentVer().Downloadable() == true) 
 244             Cache
.MarkKeep(I
, false, false); 
 247             // Is this right? Will dpkg choke on an upgrade? 
 248             if (Cache
[I
].CandidateVer 
!= 0 && 
 249                  Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true) 
 250                Cache
.MarkInstall(I
, false, 0, false); 
 252                return _error
->Error(_("The package %s needs to be reinstalled, " 
 253                                     "but I can't find an archive for it."),I
.FullName(true).c_str()); 
 259       switch (I
->CurrentState
) 
 261          /* This means installation failed somehow - it does not need to be 
 262             re-unpacked (probably) */ 
 263          case pkgCache::State::UnPacked
: 
 264          case pkgCache::State::HalfConfigured
: 
 265          case pkgCache::State::TriggersAwaited
: 
 266          case pkgCache::State::TriggersPending
: 
 267          if ((I
->CurrentVer 
!= 0 && I
.CurrentVer().Downloadable() == true) || 
 268              I
.State() != pkgCache::PkgIterator::NeedsUnpack
) 
 269             Cache
.MarkKeep(I
, false, false); 
 272             if (Cache
[I
].CandidateVer 
!= 0 && 
 273                  Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true) 
 274                Cache
.MarkInstall(I
, true, 0, false); 
 280          // This means removal failed 
 281          case pkgCache::State::HalfInstalled
: 
 286          if (I
->InstState 
!= pkgCache::State::Ok
) 
 287             return _error
->Error("The package %s is not ok and I " 
 288                                  "don't know how to fix it!",I
.FullName(false).c_str()); 
 294 // FixBroken - Fix broken packages                                      /*{{{*/ 
 295 // --------------------------------------------------------------------- 
 296 /* This autoinstalls every broken package and then runs the problem resolver 
 298 bool pkgFixBroken(pkgDepCache 
&Cache
) 
 300    pkgDepCache::ActionGroup 
group(Cache
); 
 302    // Auto upgrade all broken packages 
 303    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 304       if (Cache
[I
].NowBroken() == true) 
 305          Cache
.MarkInstall(I
, true, 0, false); 
 307    /* Fix packages that are in a NeedArchive state but don't have a 
 308       downloadable install version */ 
 309    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 311       if (I
.State() != pkgCache::PkgIterator::NeedsUnpack 
|| 
 312           Cache
[I
].Delete() == true) 
 315       if (Cache
[I
].InstVerIter(Cache
).Downloadable() == false) 
 318       Cache
.MarkInstall(I
, true, 0, false); 
 321    pkgProblemResolver 
Fix(&Cache
); 
 322    return Fix
.Resolve(true); 
 325 // DistUpgrade - Distribution upgrade                                   /*{{{*/ 
 326 // --------------------------------------------------------------------- 
 327 /* This autoinstalls every package and then force installs every  
 328    pre-existing package. This creates the initial set of conditions which  
 329    most likely contain problems because too many things were installed. 
 331    The problem resolver is used to resolve the problems. 
 333 bool pkgDistUpgrade(pkgDepCache 
&Cache
) 
 335    pkgDepCache::ActionGroup 
group(Cache
); 
 337    /* Upgrade all installed packages first without autoinst to help the resolver 
 338       in versioned or-groups to upgrade the old solver instead of installing 
 339       a new one (if the old solver is not the first one [anymore]) */ 
 340    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; ++I
) 
 341       if (I
->CurrentVer 
!= 0) 
 342          Cache
.MarkInstall(I
, false, 0, false); 
 344    /* Auto upgrade all installed packages, this provides the basis  
 345       for the installation */ 
 346    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 347       if (I
->CurrentVer 
!= 0) 
 348          Cache
.MarkInstall(I
, true, 0, false); 
 350    /* Now, auto upgrade all essential packages - this ensures that 
 351       the essential packages are present and working */ 
 352    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 353       if ((I
->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
) 
 354          Cache
.MarkInstall(I
, true, 0, false); 
 356    /* We do it again over all previously installed packages to force  
 357       conflict resolution on them all. */ 
 358    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 359       if (I
->CurrentVer 
!= 0) 
 360          Cache
.MarkInstall(I
, false, 0, false); 
 362    pkgProblemResolver 
Fix(&Cache
); 
 364    // Hold back held packages. 
 365    if (_config
->FindB("APT::Ignore-Hold",false) == false) 
 367       for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 369          if (I
->SelectedState 
== pkgCache::State::Hold
) 
 372             Cache
.MarkKeep(I
, false, false); 
 377    return Fix
.Resolve(); 
 380 // AllUpgrade - Upgrade as many packages as possible                    /*{{{*/ 
 381 // --------------------------------------------------------------------- 
 382 /* Right now the system must be consistent before this can be called. 
 383    It also will not change packages marked for install, it only tries 
 384    to install packages not marked for install */ 
 385 bool pkgAllUpgrade(pkgDepCache 
&Cache
) 
 387    pkgDepCache::ActionGroup 
group(Cache
); 
 389    pkgProblemResolver 
Fix(&Cache
); 
 391    if (Cache
.BrokenCount() != 0) 
 394    // Upgrade all installed packages 
 395    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 397       if (Cache
[I
].Install() == true) 
 400       if (_config
->FindB("APT::Ignore-Hold",false) == false) 
 401          if (I
->SelectedState 
== pkgCache::State::Hold
) 
 404       if (I
->CurrentVer 
!= 0 && Cache
[I
].InstallVer 
!= 0) 
 405          Cache
.MarkInstall(I
, false, 0, false); 
 408    return Fix
.ResolveByKeep(); 
 411 // MinimizeUpgrade - Minimizes the set of packages to be upgraded       /*{{{*/ 
 412 // --------------------------------------------------------------------- 
 413 /* This simply goes over the entire set of packages and tries to keep  
 414    each package marked for upgrade. If a conflict is generated then  
 415    the package is restored. */ 
 416 bool pkgMinimizeUpgrade(pkgDepCache 
&Cache
) 
 418    pkgDepCache::ActionGroup 
group(Cache
); 
 420    if (Cache
.BrokenCount() != 0) 
 423    // We loop for 10 tries to get the minimal set size. 
 425    unsigned int Count 
= 0; 
 429       for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 432          if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true) 
 435          // Keep it and see if that is OK 
 436          Cache
.MarkKeep(I
, false, false); 
 437          if (Cache
.BrokenCount() != 0) 
 438             Cache
.MarkInstall(I
, false, 0, false); 
 441             // If keep didnt actually do anything then there was no change.. 
 442             if (Cache
[I
].Upgrade() == false) 
 448    while (Change 
== true && Count 
< 10); 
 450    if (Cache
.BrokenCount() != 0) 
 451       return _error
->Error("Internal Error in pkgMinimizeUpgrade"); 
 456 // ProblemResolver::pkgProblemResolver - Constructor                    /*{{{*/ 
 457 // --------------------------------------------------------------------- 
 459 pkgProblemResolver::pkgProblemResolver(pkgDepCache 
*pCache
) : Cache(*pCache
) 
 462    unsigned long Size 
= Cache
.Head().PackageCount
; 
 463    Scores 
= new signed short[Size
]; 
 464    Flags 
= new unsigned char[Size
]; 
 465    memset(Flags
,0,sizeof(*Flags
)*Size
); 
 467    // Set debug to true to see its decision logic 
 468    Debug 
= _config
->FindB("Debug::pkgProblemResolver",false); 
 471 // ProblemResolver::~pkgProblemResolver - Destructor                    /*{{{*/ 
 472 // --------------------------------------------------------------------- 
 474 pkgProblemResolver::~pkgProblemResolver() 
 480 // ProblemResolver::ScoreSort - Sort the list by score                  /*{{{*/ 
 481 // --------------------------------------------------------------------- 
 483 int pkgProblemResolver::ScoreSort(const void *a
,const void *b
) 
 485    Package 
const **A 
= (Package 
const **)a
; 
 486    Package 
const **B 
= (Package 
const **)b
; 
 487    if (This
->Scores
[(*A
)->ID
] > This
->Scores
[(*B
)->ID
]) 
 489    if (This
->Scores
[(*A
)->ID
] < This
->Scores
[(*B
)->ID
]) 
 494 // ProblemResolver::MakeScores - Make the score table                   /*{{{*/ 
 495 // --------------------------------------------------------------------- 
 497 void pkgProblemResolver::MakeScores() 
 499    unsigned long Size 
= Cache
.Head().PackageCount
; 
 500    memset(Scores
,0,sizeof(*Scores
)*Size
); 
 502    // Important Required Standard Optional Extra 
 503    signed short PrioMap
[] = { 
 505       (signed short) _config
->FindI("pkgProblemResolver::Scores::Important",3), 
 506       (signed short) _config
->FindI("pkgProblemResolver::Scores::Required",2), 
 507       (signed short) _config
->FindI("pkgProblemResolver::Scores::Standard",1), 
 508       (signed short) _config
->FindI("pkgProblemResolver::Scores::Optional",-1), 
 509       (signed short) _config
->FindI("pkgProblemResolver::Scores::Extra",-2) 
 511    signed short PrioEssentials 
= _config
->FindI("pkgProblemResolver::Scores::Essentials",100); 
 512    signed short PrioInstalledAndNotObsolete 
= _config
->FindI("pkgProblemResolver::Scores::NotObsolete",1); 
 513    signed short PrioDepends 
= _config
->FindI("pkgProblemResolver::Scores::Depends",1); 
 514    signed short PrioRecommends 
= _config
->FindI("pkgProblemResolver::Scores::Recommends",1); 
 515    signed short AddProtected 
= _config
->FindI("pkgProblemResolver::Scores::AddProtected",10000); 
 516    signed short AddEssential 
= _config
->FindI("pkgProblemResolver::Scores::AddEssential",5000); 
 518    if (_config
->FindB("Debug::pkgProblemResolver::ShowScores",false) == true) 
 519       clog 
<< "Settings used to calculate pkgProblemResolver::Scores::" << endl
 
 520          << "  Important => " << PrioMap
[1] << endl
 
 521          << "  Required => " << PrioMap
[2] << endl
 
 522          << "  Standard => " << PrioMap
[3] << endl
 
 523          << "  Optional => " << PrioMap
[4] << endl
 
 524          << "  Extra => " << PrioMap
[5] << endl
 
 525          << "  Essentials => " << PrioEssentials 
<< endl
 
 526          << "  InstalledAndNotObsolete => " << PrioInstalledAndNotObsolete 
<< endl
 
 527          << "  Depends => " << PrioDepends 
<< endl
 
 528          << "  Recommends => " << PrioRecommends 
<< endl
 
 529          << "  AddProtected => " << AddProtected 
<< endl
 
 530          << "  AddEssential => " << AddEssential 
<< endl
; 
 532    // Generate the base scores for a package based on its properties 
 533    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 535       if (Cache
[I
].InstallVer 
== 0) 
 538       signed short &Score 
= Scores
[I
->ID
]; 
 540       /* This is arbitrary, it should be high enough to elevate an 
 541          essantial package above most other packages but low enough 
 542          to allow an obsolete essential packages to be removed by 
 543          a conflicts on a powerfull normal package (ie libc6) */ 
 544       if ((I
->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
) 
 545          Score 
+= PrioEssentials
; 
 547       // We transform the priority 
 548       if (Cache
[I
].InstVerIter(Cache
)->Priority 
<= 5) 
 549          Score 
+= PrioMap
[Cache
[I
].InstVerIter(Cache
)->Priority
]; 
 551       /* This helps to fix oddball problems with conflicting packages 
 552          on the same level. We enhance the score of installed packages  
 553          if those are not obsolete 
 555       if (I
->CurrentVer 
!= 0 && Cache
[I
].CandidateVer 
!= 0 && Cache
[I
].CandidateVerIter(Cache
).Downloadable()) 
 556          Score 
+= PrioInstalledAndNotObsolete
; 
 559    // Now that we have the base scores we go and propogate dependencies 
 560    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 562       if (Cache
[I
].InstallVer 
== 0) 
 565       for (pkgCache::DepIterator D 
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false; D
++) 
 567          if (D
->Type 
== pkgCache::Dep::Depends 
||  
 568              D
->Type 
== pkgCache::Dep::PreDepends
) 
 569             Scores
[D
.TargetPkg()->ID
] += PrioDepends
; 
 570          else if (D
->Type 
== pkgCache::Dep::Recommends
) 
 571             Scores
[D
.TargetPkg()->ID
] += PrioRecommends
; 
 575    // Copy the scores to advoid additive looping 
 576    SPtrArray
<signed short> OldScores 
= new signed short[Size
]; 
 577    memcpy(OldScores
,Scores
,sizeof(*Scores
)*Size
); 
 579    /* Now we cause 1 level of dependency inheritance, that is we add the  
 580       score of the packages that depend on the target Package. This  
 581       fortifies high scoring packages */ 
 582    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 584       if (Cache
[I
].InstallVer 
== 0) 
 587       for (pkgCache::DepIterator D 
= I
.RevDependsList(); D
.end() == false; D
++) 
 589          // Only do it for the install version 
 590          if ((pkgCache::Version 
*)D
.ParentVer() != Cache
[D
.ParentPkg()].InstallVer 
|| 
 591              (D
->Type 
!= pkgCache::Dep::Depends 
&&  
 592               D
->Type 
!= pkgCache::Dep::PreDepends 
&& 
 593               D
->Type 
!= pkgCache::Dep::Recommends
)) 
 596          Scores
[I
->ID
] += abs(OldScores
[D
.ParentPkg()->ID
]); 
 600    /* Now we propogate along provides. This makes the packages that  
 601       provide important packages extremely important */ 
 602    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 604       for (pkgCache::PrvIterator P 
= I
.ProvidesList(); P
.end() == false; P
++) 
 606          // Only do it once per package 
 607          if ((pkgCache::Version 
*)P
.OwnerVer() != Cache
[P
.OwnerPkg()].InstallVer
) 
 609          Scores
[P
.OwnerPkg()->ID
] += abs(Scores
[I
->ID
] - OldScores
[I
->ID
]); 
 613    /* Protected things are pushed really high up. This number should put them 
 614       ahead of everything */ 
 615    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 617       if ((Flags
[I
->ID
] & Protected
) != 0) 
 618          Scores
[I
->ID
] += AddProtected
; 
 619       if ((I
->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
) 
 620          Scores
[I
->ID
] += AddEssential
; 
 624 // ProblemResolver::DoUpgrade - Attempt to upgrade this package         /*{{{*/ 
 625 // --------------------------------------------------------------------- 
 626 /* This goes through and tries to reinstall packages to make this package 
 628 bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg
) 
 630    pkgDepCache::ActionGroup 
group(Cache
); 
 632    if ((Flags
[Pkg
->ID
] & Upgradable
) == 0 || Cache
[Pkg
].Upgradable() == false) 
 634    if ((Flags
[Pkg
->ID
] & Protected
) == Protected
) 
 637    Flags
[Pkg
->ID
] &= ~Upgradable
; 
 639    bool WasKept 
= Cache
[Pkg
].Keep(); 
 640    Cache
.MarkInstall(Pkg
, false, 0, false); 
 642    // This must be a virtual package or something like that. 
 643    if (Cache
[Pkg
].InstVerIter(Cache
).end() == true) 
 646    // Isolate the problem dependency 
 648    for (pkgCache::DepIterator D 
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); D
.end() == false;) 
 650       // Compute a single dependency element (glob or) 
 651       pkgCache::DepIterator Start 
= D
; 
 652       pkgCache::DepIterator End 
= D
; 
 653       unsigned char State 
= 0; 
 654       for (bool LastOR 
= true; D
.end() == false && LastOR 
== true;) 
 657          LastOR 
= (D
->CompareOp 
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
; 
 663       // We only worry about critical deps. 
 664       if (End
.IsCritical() != true) 
 667       // Iterate over all the members in the or group 
 671          if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
) 
 674          // Do not change protected packages 
 675          PkgIterator P 
= Start
.SmartTargetPkg(); 
 676          if ((Flags
[P
->ID
] & Protected
) == Protected
) 
 679                clog 
<< "    Reinst Failed because of protected " << P
.FullName(false) << endl
; 
 684             // Upgrade the package if the candidate version will fix the problem. 
 685             if ((Cache
[Start
] & pkgDepCache::DepCVer
) == pkgDepCache::DepCVer
) 
 687                if (DoUpgrade(P
) == false) 
 690                      clog 
<< "    Reinst Failed because of " << P
.FullName(false) << endl
; 
 701                /* We let the algorithm deal with conflicts on its next iteration, 
 702                 it is much smarter than us */ 
 703                if (Start
->Type 
== pkgCache::Dep::Conflicts 
||  
 704                    Start
->Type 
== pkgCache::Dep::DpkgBreaks 
||  
 705                    Start
->Type 
== pkgCache::Dep::Obsoletes
) 
 709                   clog 
<< "    Reinst Failed early because of " << Start
.TargetPkg().FullName(false) << endl
; 
 722    // Undo our operations - it might be smart to undo everything this did.. 
 726          Cache
.MarkKeep(Pkg
, false, false); 
 728          Cache
.MarkDelete(Pkg
); 
 733       clog 
<< "  Re-Instated " << Pkg
.FullName(false) << endl
; 
 737 // ProblemResolver::Resolve - calls a resolver to fix the situation     /*{{{*/ 
 738 // --------------------------------------------------------------------- 
 740 bool pkgProblemResolver::Resolve(bool BrokenFix
) 
 742    std::string 
const solver 
= _config
->Find("APT::Solver::Name", "internal"); 
 744    if (solver 
!= "internal") 
 746       int solver_in
, solver_out
; 
 747       if (EDSP::ExecuteSolver(solver
.c_str(), &solver_in
, &solver_out
) == false) 
 750       FILE* output 
= fdopen(solver_in
, "w"); 
 752          return _error
->Errno("Resolve", "fdopen on solver stdin failed"); 
 753       EDSP::WriteRequest(Cache
, output
); 
 754       EDSP::WriteScenario(Cache
, output
); 
 757       if (EDSP::ReadResponse(solver_out
, Cache
) == false) 
 758          return _error
->Error("Reading solver response failed"); 
 762    return ResolveInternal(BrokenFix
); 
 765 // ProblemResolver::ResolveInternal - Run the resolution pass           /*{{{*/ 
 766 // --------------------------------------------------------------------- 
 767 /* This routines works by calculating a score for each package. The score 
 768    is derived by considering the package's priority and all reverse  
 769    dependents giving an integer that reflects the amount of breakage that 
 770    adjusting the package will inflict.  
 772    It goes from highest score to lowest and corrects all of the breaks by  
 773    keeping or removing the dependant packages. If that fails then it removes 
 774    the package itself and goes on. The routine should be able to intelligently 
 775    go from any broken state to a fixed state.  
 777    The BrokenFix flag enables a mode where the algorithm tries to  
 778    upgrade packages to advoid problems. */ 
 779 bool pkgProblemResolver::ResolveInternal(bool const BrokenFix
) 
 781    pkgDepCache::ActionGroup 
group(Cache
); 
 783    // Record which packages are marked for install 
 788       for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 790          if (Cache
[I
].Install() == true) 
 791             Flags
[I
->ID
] |= PreInstalled
; 
 794             if (Cache
[I
].InstBroken() == true && BrokenFix 
== true) 
 796                Cache
.MarkInstall(I
, false, 0, false); 
 797                if (Cache
[I
].Install() == true) 
 801             Flags
[I
->ID
] &= ~PreInstalled
; 
 803          Flags
[I
->ID
] |= Upgradable
; 
 806    while (Again 
== true); 
 809       clog 
<< "Starting" << endl
; 
 813    unsigned long const Size 
= Cache
.Head().PackageCount
; 
 815    /* We have to order the packages so that the broken fixing pass  
 816       operates from highest score to lowest. This prevents problems when 
 817       high score packages cause the removal of lower score packages that 
 818       would cause the removal of even lower score packages. */ 
 819    SPtrArray
<pkgCache::Package 
*> PList 
= new pkgCache::Package 
*[Size
]; 
 820    pkgCache::Package 
**PEnd 
= PList
; 
 821    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
 824    qsort(PList
,PEnd 
- PList
,sizeof(*PList
),&ScoreSort
); 
 826    if (_config
->FindB("Debug::pkgProblemResolver::ShowScores",false) == true) 
 828       clog 
<< "Show Scores" << endl
; 
 829       for (pkgCache::Package 
**K 
= PList
; K 
!= PEnd
; K
++) 
 830          if (Scores
[(*K
)->ID
] != 0) 
 832            pkgCache::PkgIterator 
Pkg(Cache
,*K
); 
 833            clog 
<< Scores
[(*K
)->ID
] << ' ' << Pkg 
<< std::endl
; 
 838       clog 
<< "Starting 2" << endl
; 
 840    /* Now consider all broken packages. For each broken package we either 
 841       remove the package or fix it's problem. We do this once, it should 
 842       not be possible for a loop to form (that is a < b < c and fixing b by 
 843       changing a breaks c) */ 
 845    bool const TryFixByInstall 
= _config
->FindB("pkgProblemResolver::FixByInstall", true); 
 846    for (int Counter 
= 0; Counter 
!= 10 && Change 
== true; Counter
++) 
 849       for (pkgCache::Package 
**K 
= PList
; K 
!= PEnd
; K
++) 
 851          pkgCache::PkgIterator 
I(Cache
,*K
); 
 853          /* We attempt to install this and see if any breaks result, 
 854             this takes care of some strange cases */ 
 855          if (Cache
[I
].CandidateVer 
!= Cache
[I
].InstallVer 
&& 
 856              I
->CurrentVer 
!= 0 && Cache
[I
].InstallVer 
!= 0 && 
 857              (Flags
[I
->ID
] & PreInstalled
) != 0 && 
 858              (Flags
[I
->ID
] & Protected
) == 0 && 
 859              (Flags
[I
->ID
] & ReInstateTried
) == 0) 
 862                clog 
<< " Try to Re-Instate (" << Counter 
<< ") " << I
.FullName(false) << endl
; 
 863             unsigned long OldBreaks 
= Cache
.BrokenCount(); 
 864             pkgCache::Version 
*OldVer 
= Cache
[I
].InstallVer
; 
 865             Flags
[I
->ID
] &= ReInstateTried
; 
 867             Cache
.MarkInstall(I
, false, 0, false); 
 868             if (Cache
[I
].InstBroken() == true ||  
 869                 OldBreaks 
< Cache
.BrokenCount()) 
 874                   Cache
.MarkKeep(I
, false, false); 
 878                   clog 
<< "Re-Instated " << I
.FullName(false) << " (" << OldBreaks 
<< " vs " << Cache
.BrokenCount() << ')' << endl
; 
 881          if (Cache
[I
].InstallVer 
== 0 || Cache
[I
].InstBroken() == false) 
 885             clog 
<< "Investigating (" << Counter 
<< ") " << I 
<< endl
; 
 887          // Isolate the problem dependency 
 888          PackageKill KillList
[100]; 
 889          PackageKill 
*LEnd 
= KillList
; 
 891          pkgCache::DepIterator Start
; 
 892          pkgCache::DepIterator End
; 
 893          PackageKill 
*OldEnd 
= LEnd
; 
 895          enum {OrRemove
,OrKeep
} OrOp 
= OrRemove
; 
 896          for (pkgCache::DepIterator D 
= Cache
[I
].InstVerIter(Cache
).DependsList(); 
 897               D
.end() == false || InOr 
== true;) 
 899             // Compute a single dependency element (glob or) 
 903                if (InOr 
== true && OldEnd 
== LEnd
) 
 905                   if (OrOp 
== OrRemove
) 
 907                      if ((Flags
[I
->ID
] & Protected
) != Protected
) 
 910                            clog 
<< "  Or group remove for " << I
.FullName(false) << endl
; 
 915                   else if (OrOp 
== OrKeep
) 
 918                         clog 
<< "  Or group keep for " << I
.FullName(false) << endl
; 
 919                      Cache
.MarkKeep(I
, false, false); 
 924                /* We do an extra loop (as above) to finalize the or group 
 929                if (Start
.end() == true) 
 932                // We only worry about critical deps. 
 933                if (End
.IsCritical() != true) 
 942                // We only worry about critical deps. 
 943                if (Start
.IsCritical() != true) 
 948             if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
) 
 955                clog 
<< "Broken " << Start 
<< endl
; 
 957             /* Look across the version list. If there are no possible 
 958                targets then we keep the package and bail. This is necessary 
 959                if a package has a dep on another package that cant be found */ 
 960             SPtrArray
<pkgCache::Version 
*> VList 
= Start
.AllTargets(); 
 961             if (*VList 
== 0 && (Flags
[I
->ID
] & Protected
) != Protected 
&& 
 962                 Start
->Type 
!= pkgCache::Dep::Conflicts 
&& 
 963                 Start
->Type 
!= pkgCache::Dep::DpkgBreaks 
&& 
 964                 Start
->Type 
!= pkgCache::Dep::Obsoletes 
&& 
 965                 Cache
[I
].NowBroken() == false) 
 969                   /* No keep choice because the keep being OK could be the 
 970                      result of another element in the OR group! */ 
 975                Cache
.MarkKeep(I
, false, false); 
 980             for (pkgCache::Version 
**V 
= VList
; *V 
!= 0; V
++) 
 982                pkgCache::VerIterator 
Ver(Cache
,*V
); 
 983                pkgCache::PkgIterator Pkg 
= Ver
.ParentPkg(); 
 985                /* This is a conflicts, and the version we are looking 
 986                   at is not the currently selected version of the  
 987                   package, which means it is not necessary to  
 989                if (Cache
[Pkg
].InstallVer 
!= Ver 
&& 
 990                    (Start
->Type 
== pkgCache::Dep::Conflicts 
|| 
 991                     Start
->Type 
== pkgCache::Dep::DpkgBreaks 
|| 
 992                     Start
->Type 
== pkgCache::Dep::Obsoletes
))  
 995                      clog 
<< "  Conflicts//Breaks against version "  
 996                           << Ver
.VerStr() << " for " << Pkg
.Name()  
 997                           << " but that is not InstVer, ignoring" 
1003                   clog 
<< "  Considering " << Pkg
.FullName(false) << ' ' << (int)Scores
[Pkg
->ID
] << 
1004                   " as a solution to " << I
.FullName(false) << ' ' << (int)Scores
[I
->ID
] << endl
; 
1006                /* Try to fix the package under consideration rather than 
1007                   fiddle with the VList package */ 
1008                if (Scores
[I
->ID
] <= Scores
[Pkg
->ID
] || 
1009                    ((Cache
[Start
] & pkgDepCache::DepNow
) == 0 && 
1010                     End
->Type 
!= pkgCache::Dep::Conflicts 
&& 
1011                     End
->Type 
!= pkgCache::Dep::DpkgBreaks 
&& 
1012                     End
->Type 
!= pkgCache::Dep::Obsoletes
)) 
1014                   // Try a little harder to fix protected packages.. 
1015                   if ((Flags
[I
->ID
] & Protected
) == Protected
) 
1017                      if (DoUpgrade(Pkg
) == true) 
1019                         if (Scores
[Pkg
->ID
] > Scores
[I
->ID
]) 
1020                            Scores
[Pkg
->ID
] = Scores
[I
->ID
]; 
1027                   /* See if a keep will do, unless the package is protected, 
1028                      then installing it will be necessary */ 
1029                   bool Installed 
= Cache
[I
].Install(); 
1030                   Cache
.MarkKeep(I
, false, false); 
1031                   if (Cache
[I
].InstBroken() == false) 
1033                      // Unwind operation will be keep now 
1034                      if (OrOp 
== OrRemove
) 
1038                      if (InOr 
== true && Installed 
== true) 
1039                         Cache
.MarkInstall(I
, false, 0, false); 
1042                         clog 
<< "  Holding Back " << I
.FullName(false) << " rather than change " << Start
.TargetPkg().FullName(false) << endl
; 
1046                      if (BrokenFix 
== false || DoUpgrade(I
) == false) 
1048                         // Consider other options 
1052                               clog 
<< "  Removing " << I
.FullName(false) << " rather than change " << Start
.TargetPkg().FullName(false) << endl
; 
1053                            Cache
.MarkDelete(I
); 
1054                            if (Counter 
> 1 && Scores
[Pkg
->ID
] > Scores
[I
->ID
]) 
1055                               Scores
[I
->ID
] = Scores
[Pkg
->ID
]; 
1057                         else if (TryFixByInstall 
== true && 
1058                                  Start
.TargetPkg()->CurrentVer 
== 0 && 
1059                                  Cache
[Start
.TargetPkg()].Delete() == false && 
1060                                  (Flags
[Start
.TargetPkg()->ID
] & ToRemove
) != ToRemove 
&& 
1061                                  Cache
.GetCandidateVer(Start
.TargetPkg()).end() == false) 
1063                            /* Before removing or keeping the package with the broken dependency 
1064                               try instead to install the first not previously installed package 
1065                               solving this dependency. This helps every time a previous solver 
1066                               is removed by the resolver because of a conflict or alike but it is 
1067                               dangerous as it could trigger new breaks/conflicts… */ 
1069                               clog 
<< "  Try Installing " << Start
.TargetPkg() << " before changing " << I
.FullName(false) << std::endl
; 
1070                            unsigned long const OldBroken 
= Cache
.BrokenCount(); 
1071                            Cache
.MarkInstall(Start
.TargetPkg(), true, 1, false); 
1072                            // FIXME: we should undo the complete MarkInstall process here 
1073                            if (Cache
[Start
.TargetPkg()].InstBroken() == true || Cache
.BrokenCount() > OldBroken
) 
1074                               Cache
.MarkDelete(Start
.TargetPkg(), false, 1, false); 
1085                   if (Start
->Type 
== pkgCache::Dep::DpkgBreaks
) 
1087                      // first, try upgradring the package, if that 
1088                      // does not help, the breaks goes onto the 
1091                      // FIXME: use DoUpgrade(Pkg) instead? 
1092                      if (Cache
[End
] & pkgDepCache::DepGCVer
) 
1095                            clog 
<< "  Upgrading " << Pkg
.FullName(false) << " due to Breaks field in " << I
.FullName(false) << endl
; 
1096                         Cache
.MarkInstall(Pkg
, false, 0, false); 
1101                   // Skip adding to the kill list if it is protected 
1102                   if ((Flags
[Pkg
->ID
] & Protected
) != 0) 
1106                      clog 
<< "  Added " << Pkg
.FullName(false) << " to the remove list" << endl
; 
1112                   if (Start
->Type 
!= pkgCache::Dep::Conflicts 
&& 
1113                       Start
->Type 
!= pkgCache::Dep::Obsoletes
) 
1118             // Hm, nothing can possibly satisify this dep. Nuke it. 
1119             if (VList
[0] == 0 &&  
1120                 Start
->Type 
!= pkgCache::Dep::Conflicts 
&& 
1121                 Start
->Type 
!= pkgCache::Dep::DpkgBreaks 
&& 
1122                 Start
->Type 
!= pkgCache::Dep::Obsoletes 
&& 
1123                 (Flags
[I
->ID
] & Protected
) != Protected
) 
1125                bool Installed 
= Cache
[I
].Install(); 
1127                if (Cache
[I
].InstBroken() == false) 
1129                   // Unwind operation will be keep now 
1130                   if (OrOp 
== OrRemove
) 
1134                   if (InOr 
== true && Installed 
== true) 
1135                      Cache
.MarkInstall(I
, false, 0, false); 
1138                      clog 
<< "  Holding Back " << I
.FullName(false) << " because I can't find " << Start
.TargetPkg().FullName(false) << endl
; 
1143                      clog 
<< "  Removing " << I
.FullName(false) << " because I can't find " << Start
.TargetPkg().FullName(false) << endl
; 
1145                      Cache
.MarkDelete(I
); 
1160          // Apply the kill list now 
1161          if (Cache
[I
].InstallVer 
!= 0) 
1163             for (PackageKill 
*J 
= KillList
; J 
!= LEnd
; J
++) 
1166                if ((Cache
[J
->Dep
] & pkgDepCache::DepGNow
) == 0) 
1168                   if (J
->Dep
->Type 
== pkgCache::Dep::Conflicts 
||  
1169                       J
->Dep
->Type 
== pkgCache::Dep::DpkgBreaks 
|| 
1170                       J
->Dep
->Type 
== pkgCache::Dep::Obsoletes
) 
1173                         clog 
<< "  Fixing " << I
.FullName(false) << " via remove of " << J
->Pkg
.FullName(false) << endl
; 
1174                      Cache
.MarkDelete(J
->Pkg
); 
1180                      clog 
<< "  Fixing " << I
.FullName(false) << " via keep of " << J
->Pkg
.FullName(false) << endl
; 
1181                   Cache
.MarkKeep(J
->Pkg
, false, false); 
1186                   if (Scores
[I
->ID
] > Scores
[J
->Pkg
->ID
])                  
1187                      Scores
[J
->Pkg
->ID
] = Scores
[I
->ID
]; 
1195       clog 
<< "Done" << endl
; 
1197    if (Cache
.BrokenCount() != 0) 
1199       // See if this is the result of a hold 
1200       pkgCache::PkgIterator I 
= Cache
.PkgBegin(); 
1201       for (;I
.end() != true; I
++) 
1203          if (Cache
[I
].InstBroken() == false) 
1205          if ((Flags
[I
->ID
] & Protected
) != Protected
) 
1206             return _error
->Error(_("Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages.")); 
1208       return _error
->Error(_("Unable to correct problems, you have held broken packages.")); 
1211    // set the auto-flags (mvo: I'm not sure if we _really_ need this) 
1212    pkgCache::PkgIterator I 
= Cache
.PkgBegin(); 
1213    for (;I
.end() != true; I
++) { 
1214       if (Cache
[I
].NewInstall() && !(Flags
[I
->ID
] & PreInstalled
)) { 
1215          if(_config
->FindI("Debug::pkgAutoRemove",false)) { 
1216             std::clog 
<< "Resolve installed new pkg: " << I
.FullName(false)  
1217                       << " (now marking it as auto)" << std::endl
; 
1219          Cache
[I
].Flags 
|= pkgCache::Flag::Auto
; 
1227 // ProblemResolver::ResolveByKeep - Resolve problems using keep         /*{{{*/ 
1228 // --------------------------------------------------------------------- 
1229 /* This is the work horse of the soft upgrade routine. It is very gental  
1230    in that it does not install or remove any packages. It is assumed that the 
1231    system was non-broken previously. */ 
1232 bool pkgProblemResolver::ResolveByKeep() 
1234    pkgDepCache::ActionGroup 
group(Cache
); 
1236    unsigned long Size 
= Cache
.Head().PackageCount
; 
1240    /* We have to order the packages so that the broken fixing pass  
1241       operates from highest score to lowest. This prevents problems when 
1242       high score packages cause the removal of lower score packages that 
1243       would cause the removal of even lower score packages. */ 
1244    pkgCache::Package 
**PList 
= new pkgCache::Package 
*[Size
]; 
1245    pkgCache::Package 
**PEnd 
= PList
; 
1246    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
1249    qsort(PList
,PEnd 
- PList
,sizeof(*PList
),&ScoreSort
); 
1251    if (_config
->FindB("Debug::pkgProblemResolver::ShowScores",false) == true) 
1253       clog 
<< "Show Scores" << endl
; 
1254       for (pkgCache::Package 
**K 
= PList
; K 
!= PEnd
; K
++) 
1255          if (Scores
[(*K
)->ID
] != 0) 
1257            pkgCache::PkgIterator 
Pkg(Cache
,*K
); 
1258            clog 
<< Scores
[(*K
)->ID
] << ' ' << Pkg 
<< std::endl
; 
1263       clog 
<< "Entering ResolveByKeep" << endl
; 
1265    // Consider each broken package  
1266    pkgCache::Package 
**LastStop 
= 0; 
1267    for (pkgCache::Package 
**K 
= PList
; K 
!= PEnd
; K
++) 
1269       pkgCache::PkgIterator 
I(Cache
,*K
); 
1271       if (Cache
[I
].InstallVer 
== 0 || Cache
[I
].InstBroken() == false) 
1274       /* Keep the package. If this works then great, otherwise we have 
1275          to be significantly more agressive and manipulate its dependencies */ 
1276       if ((Flags
[I
->ID
] & Protected
) == 0) 
1279             clog 
<< "Keeping package " << I
.FullName(false) << endl
; 
1280          Cache
.MarkKeep(I
, false, false); 
1281          if (Cache
[I
].InstBroken() == false) 
1288       // Isolate the problem dependencies 
1289       for (pkgCache::DepIterator D 
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;) 
1293          D
.GlobOr(Start
,End
); 
1295          // We only worry about critical deps. 
1296          if (End
.IsCritical() != true) 
1300          if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
) 
1303          /* Hm, the group is broken.. I suppose the best thing to do is to 
1304             is to try every combination of keep/not-keep for the set, but thats 
1305             slow, and this never happens, just be conservative and assume the 
1306             list of ors is in preference and keep till it starts to work. */ 
1310                clog 
<< "Package " << I
.FullName(false) << " " << Start 
<< endl
; 
1312             // Look at all the possible provides on this package 
1313             SPtrArray
<pkgCache::Version 
*> VList 
= Start
.AllTargets(); 
1314             for (pkgCache::Version 
**V 
= VList
; *V 
!= 0; V
++) 
1316                pkgCache::VerIterator 
Ver(Cache
,*V
); 
1317                pkgCache::PkgIterator Pkg 
= Ver
.ParentPkg(); 
1319                // It is not keepable 
1320                if (Cache
[Pkg
].InstallVer 
== 0 || 
1321                    Pkg
->CurrentVer 
== 0) 
1324                if ((Flags
[I
->ID
] & Protected
) == 0) 
1327                      clog 
<< "  Keeping Package " << Pkg
.FullName(false) << " due to " << Start
.DepType() << endl
; 
1328                   Cache
.MarkKeep(Pkg
, false, false); 
1331                if (Cache
[I
].InstBroken() == false) 
1335             if (Cache
[I
].InstBroken() == false) 
1343          if (Cache
[I
].InstBroken() == false) 
1347       if (Cache
[I
].InstBroken() == true) 
1352          return _error
->Error("Internal Error, pkgProblemResolver::ResolveByKeep is looping on package %s.",I
.FullName(false).c_str()); 
1360 // ProblemResolver::InstallProtect - Install all protected packages     /*{{{*/ 
1361 // --------------------------------------------------------------------- 
1362 /* This is used to make sure protected packages are installed */ 
1363 void pkgProblemResolver::InstallProtect() 
1365    pkgDepCache::ActionGroup 
group(Cache
); 
1367    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; I
++) 
1369       if ((Flags
[I
->ID
] & Protected
) == Protected
) 
1371          if ((Flags
[I
->ID
] & ToRemove
) == ToRemove
) 
1372             Cache
.MarkDelete(I
); 
1375             // preserve the information whether the package was auto 
1376             // or manually installed 
1377             bool autoInst 
= (Cache
[I
].Flags 
& pkgCache::Flag::Auto
); 
1378             Cache
.MarkInstall(I
, false, 0, !autoInst
); 
1384 // PrioSortList - Sort a list of versions by priority                   /*{{{*/ 
1385 // --------------------------------------------------------------------- 
1386 /* This is ment to be used in conjunction with AllTargets to get a list  
1387    of versions ordered by preference. */ 
1388 static pkgCache 
*PrioCache
; 
1389 static int PrioComp(const void *A
,const void *B
) 
1391    pkgCache::VerIterator 
L(*PrioCache
,*(pkgCache::Version 
**)A
); 
1392    pkgCache::VerIterator 
R(*PrioCache
,*(pkgCache::Version 
**)B
); 
1394    if ((L
.ParentPkg()->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential 
&& 
1395        (R
.ParentPkg()->Flags 
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
) 
1397    if ((L
.ParentPkg()->Flags 
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential 
&& 
1398        (R
.ParentPkg()->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
) 
1401    if (L
->Priority 
!= R
->Priority
) 
1402       return R
->Priority 
- L
->Priority
; 
1403    return strcmp(L
.ParentPkg().Name(),R
.ParentPkg().Name()); 
1405 void pkgPrioSortList(pkgCache 
&Cache
,pkgCache::Version 
**List
) 
1407    unsigned long Count 
= 0; 
1409    for (pkgCache::Version 
**I 
= List
; *I 
!= 0; I
++) 
1411    qsort(List
,Count
,sizeof(*List
),PrioComp
); 
1414 // CacheFile::ListUpdate - update the cache files                       /*{{{*/ 
1415 // --------------------------------------------------------------------- 
1416 /* This is a simple wrapper to update the cache. it will fetch stuff 
1417  * from the network (or any other sources defined in sources.list) 
1419 bool ListUpdate(pkgAcquireStatus 
&Stat
,  
1420                 pkgSourceList 
&List
,  
1423    pkgAcquire::RunResult res
; 
1425    if (Fetcher
.Setup(&Stat
, _config
->FindDir("Dir::State::Lists")) == false) 
1428    // Populate it with the source selection 
1429    if (List
.GetIndexes(&Fetcher
) == false) 
1433    RunScripts("APT::Update::Pre-Invoke"); 
1437       res 
= Fetcher
.Run(PulseInterval
); 
1439       res 
= Fetcher
.Run(); 
1441    if (res 
== pkgAcquire::Failed
) 
1444    bool Failed 
= false; 
1445    bool TransientNetworkFailure 
= false; 
1446    for (pkgAcquire::ItemIterator I 
= Fetcher
.ItemsBegin();  
1447         I 
!= Fetcher
.ItemsEnd(); I
++) 
1449       if ((*I
)->Status 
== pkgAcquire::Item::StatDone
) 
1454       ::URI 
uri((*I
)->DescURI()); 
1456       uri
.Password
.clear(); 
1457       string descUri 
= string(uri
); 
1458       _error
->Warning(_("Failed to fetch %s  %s\n"), descUri
.c_str(), 
1459               (*I
)->ErrorText
.c_str()); 
1461       if ((*I
)->Status 
== pkgAcquire::Item::StatTransientNetworkError
)  
1463          TransientNetworkFailure 
= true; 
1470    // Clean out any old list files 
1471    // Keep "APT::Get::List-Cleanup" name for compatibility, but 
1472    // this is really a global option for the APT library now 
1473    if (!TransientNetworkFailure 
&& !Failed 
&& 
1474        (_config
->FindB("APT::Get::List-Cleanup",true) == true && 
1475         _config
->FindB("APT::List-Cleanup",true) == true)) 
1477       if (Fetcher
.Clean(_config
->FindDir("Dir::State::lists")) == false || 
1478           Fetcher
.Clean(_config
->FindDir("Dir::State::lists") + "partial/") == false) 
1479          // something went wrong with the clean 
1483    if (TransientNetworkFailure 
== true) 
1484       _error
->Warning(_("Some index files failed to download. They have been ignored, or old ones used instead.")); 
1485    else if (Failed 
== true) 
1486       return _error
->Error(_("Some index files failed to download. They have been ignored, or old ones used instead.")); 
1489    // Run the success scripts if all was fine 
1490    if(!TransientNetworkFailure 
&& !Failed
) 
1491       RunScripts("APT::Update::Post-Invoke-Success"); 
1493    // Run the other scripts 
1494    RunScripts("APT::Update::Post-Invoke");