1 // -*- mode: cpp; mode: fold -*- 
   3 // $Id: depcache.cc,v 1.25 2001/05/27 05:36:04 jgg Exp $ 
   4 /* ###################################################################### 
   6    Dependency Cache - Caches Dependency information. 
   8    ##################################################################### */ 
  10 // Include Files                                                        /*{{{*/ 
  13 #include <apt-pkg/depcache.h> 
  14 #include <apt-pkg/version.h> 
  15 #include <apt-pkg/versionmatch.h> 
  16 #include <apt-pkg/error.h> 
  17 #include <apt-pkg/sptr.h> 
  18 #include <apt-pkg/algorithms.h> 
  19 #include <apt-pkg/fileutl.h> 
  20 #include <apt-pkg/strutl.h> 
  21 #include <apt-pkg/configuration.h> 
  22 #include <apt-pkg/aptconfiguration.h> 
  23 #include <apt-pkg/pkgsystem.h> 
  24 #include <apt-pkg/tagfile.h> 
  25 #include <apt-pkg/progress.h> 
  26 #include <apt-pkg/cacheset.h> 
  40 // helper for Install-Recommends-Sections and Never-MarkAuto-Sections   /*{{{*/ 
  42 ConfigValueInSubTree(const char* SubTree
, const char *needle
) 
  44    Configuration::Item 
const *Opts
; 
  45    Opts 
= _config
->Tree(SubTree
); 
  46    if (Opts 
!= 0 && Opts
->Child 
!= 0) 
  49       for (; Opts 
!= 0; Opts 
= Opts
->Next
) 
  51          if (Opts
->Value
.empty() == true) 
  53          if (strcmp(needle
, Opts
->Value
.c_str()) == 0) 
  60 pkgDepCache::ActionGroup::ActionGroup(pkgDepCache 
&cache
) :             /*{{{*/ 
  61   cache(cache
), released(false) 
  66 void pkgDepCache::ActionGroup::release() 
  70       if(cache
.group_level 
== 0) 
  71         std::cerr 
<< "W: Unbalanced action groups, expect badness" << std::endl
; 
  76           if(cache
.group_level 
== 0) 
  84 pkgDepCache::ActionGroup::~ActionGroup() 
  89 // DepCache::pkgDepCache - Constructors                                 /*{{{*/ 
  90 // --------------------------------------------------------------------- 
  92 pkgDepCache::pkgDepCache(pkgCache 
*pCache
,Policy 
*Plcy
) : 
  93   group_level(0), Cache(pCache
), PkgState(0), DepState(0) 
  95    DebugMarker 
= _config
->FindB("Debug::pkgDepCache::Marker", false); 
  96    DebugAutoInstall 
= _config
->FindB("Debug::pkgDepCache::AutoInstall", false); 
 100       delLocalPolicy 
= LocalPolicy 
= new Policy
; 
 103 // DepCache::~pkgDepCache - Destructor                                  /*{{{*/ 
 104 // --------------------------------------------------------------------- 
 106 pkgDepCache::~pkgDepCache() 
 110    delete delLocalPolicy
; 
 113 // DepCache::Init - Generate the initial extra structures.              /*{{{*/ 
 114 // --------------------------------------------------------------------- 
 115 /* This allocats the extension buffers and initializes them. */ 
 116 bool pkgDepCache::Init(OpProgress 
*Prog
) 
 118    // Suppress mark updates during this operation (just in case) and 
 119    // run a mark operation when Init terminates. 
 120    ActionGroup 
actions(*this); 
 124    PkgState 
= new StateCache
[Head().PackageCount
]; 
 125    DepState 
= new unsigned char[Head().DependsCount
]; 
 126    memset(PkgState
,0,sizeof(*PkgState
)*Head().PackageCount
); 
 127    memset(DepState
,0,sizeof(*DepState
)*Head().DependsCount
);  
 131       Prog
->OverallProgress(0,2*Head().PackageCount
,Head().PackageCount
, 
 132                             _("Building dependency tree")); 
 133       Prog
->SubProgress(Head().PackageCount
,_("Candidate versions")); 
 136    /* Set the current state of everything. In this state all of the 
 137       packages are kept exactly as is. See AllUpgrade */ 
 139    for (PkgIterator I 
= PkgBegin(); I
.end() != true; ++I
, ++Done
) 
 141       if (Prog 
!= 0 && Done%20 
== 0) 
 142          Prog
->Progress(Done
); 
 144       // Find the proper cache slot 
 145       StateCache 
&State 
= PkgState
[I
->ID
]; 
 148       // Figure out the install version 
 149       State
.CandidateVer 
= GetCandidateVer(I
); 
 150       State
.InstallVer 
= I
.CurrentVer(); 
 151       State
.Mode 
= ModeKeep
; 
 153       State
.Update(I
,*this); 
 159       Prog
->OverallProgress(Head().PackageCount
,2*Head().PackageCount
, 
 161                             _("Building dependency tree")); 
 162       Prog
->SubProgress(Head().PackageCount
,_("Dependency generation")); 
 173 bool pkgDepCache::readStateFile(OpProgress 
*Prog
)                       /*{{{*/ 
 176    string 
const state 
= _config
->FindFile("Dir::State::extended_states"); 
 177    if(RealFileExists(state
)) { 
 178       state_file
.Open(state
, FileFd::ReadOnly
); 
 179       off_t 
const file_size 
= state_file
.Size(); 
 181          Prog
->OverallProgress(0, file_size
, 1,  
 182                                _("Reading state information")); 
 184       pkgTagFile 
tagfile(&state_file
); 
 185       pkgTagSection section
; 
 187       bool const debug_autoremove 
= _config
->FindB("Debug::pkgAutoRemove",false); 
 188       while(tagfile
.Step(section
)) { 
 189          string 
const pkgname 
= section
.FindS("Package"); 
 190          string pkgarch 
= section
.FindS("Architecture"); 
 191          if (pkgarch
.empty() == true) 
 193          pkgCache::PkgIterator pkg 
= Cache
->FindPkg(pkgname
, pkgarch
); 
 194          // Silently ignore unknown packages and packages with no actual version. 
 195          if(pkg
.end() == true || pkg
->VersionList 
== 0) 
 198          short const reason 
= section
.FindI("Auto-Installed", 0); 
 201             PkgState
[pkg
->ID
].Flags 
|= Flag::Auto
; 
 202             if (unlikely(debug_autoremove
)) 
 203                std::clog 
<< "Auto-Installed : " << pkg
.FullName() << std::endl
; 
 204             if (pkgarch 
== "any") 
 206                pkgCache::GrpIterator G 
= pkg
.Group(); 
 207                for (pkg 
= G
.NextPkg(pkg
); pkg
.end() != true; pkg 
= G
.NextPkg(pkg
)) 
 208                   if (pkg
->VersionList 
!= 0) 
 209                      PkgState
[pkg
->ID
].Flags 
|= Flag::Auto
; 
 212          amt 
+= section
.size(); 
 214             Prog
->OverallProgress(amt
, file_size
, 1,  
 215                                   _("Reading state information")); 
 218          Prog
->OverallProgress(file_size
, file_size
, 1, 
 219                                _("Reading state information")); 
 225 bool pkgDepCache::writeStateFile(OpProgress 
*prog
, bool InstalledOnly
)  /*{{{*/ 
 227    bool const debug_autoremove 
= _config
->FindB("Debug::pkgAutoRemove",false); 
 230       std::clog 
<< "pkgDepCache::writeStateFile()" << std::endl
; 
 233    string 
const state 
= _config
->FindFile("Dir::State::extended_states"); 
 235    // if it does not exist, create a empty one 
 236    if(!RealFileExists(state
))  
 238       StateFile
.Open(state
, FileFd::WriteAtomic
); 
 243    if(!StateFile
.Open(state
, FileFd::ReadOnly
)) 
 244       return _error
->Error(_("Failed to open StateFile %s"), 
 248    string 
const outfile 
= state 
+ ".tmp"; 
 249    if((OutFile 
= fopen(outfile
.c_str(),"w")) == NULL
) 
 250       return _error
->Error(_("Failed to write temporary StateFile %s"), 
 253    // first merge with the existing sections 
 254    pkgTagFile 
tagfile(&StateFile
); 
 255    pkgTagSection section
; 
 256    std::set
<string
> pkgs_seen
; 
 257    const char *nullreorderlist
[] = {0}; 
 258    while(tagfile
.Step(section
)) { 
 259          string 
const pkgname 
= section
.FindS("Package"); 
 260          string pkgarch 
= section
.FindS("Architecture"); 
 261          if (pkgarch
.empty() == true) 
 263          // Silently ignore unknown packages and packages with no actual 
 265          pkgCache::PkgIterator pkg 
= Cache
->FindPkg(pkgname
, pkgarch
); 
 266          if(pkg
.end() || pkg
.VersionList().end())  
 268          StateCache 
const &P 
= PkgState
[pkg
->ID
]; 
 269          bool newAuto 
= (P
.Flags 
& Flag::Auto
); 
 270          // skip not installed or now-removed ones if requested 
 271          if (InstalledOnly 
&& ( 
 272              (pkg
->CurrentVer 
== 0 && P
.Mode 
!= ModeInstall
) || 
 273              (pkg
->CurrentVer 
!= 0 && P
.Mode 
== ModeDelete
))) 
 275             // The section is obsolete if it contains no other tag 
 276             unsigned int const count 
= section
.Count(); 
 278                 (count 
== 2 && section
.Exists("Auto-Installed")) || 
 279                 (count 
== 3 && section
.Exists("Auto-Installed") && section
.Exists("Architecture"))) 
 284          if(_config
->FindB("Debug::pkgAutoRemove",false)) 
 285             std::clog 
<< "Update existing AutoInstall info: "  
 286                       << pkg
.FullName() << std::endl
; 
 287          TFRewriteData rewrite
[3]; 
 288          rewrite
[0].Tag 
= "Architecture"; 
 289          rewrite
[0].Rewrite 
= pkg
.Arch(); 
 290          rewrite
[0].NewTag 
= 0; 
 291          rewrite
[1].Tag 
= "Auto-Installed"; 
 292          rewrite
[1].Rewrite 
= newAuto 
? "1" : "0"; 
 293          rewrite
[1].NewTag 
= 0; 
 295          TFRewrite(OutFile
, section
, nullreorderlist
, rewrite
); 
 296          fprintf(OutFile
,"\n"); 
 297          pkgs_seen
.insert(pkg
.FullName()); 
 300    // then write the ones we have not seen yet 
 301    std::ostringstream ostr
; 
 302    for(pkgCache::PkgIterator pkg
=Cache
->PkgBegin(); !pkg
.end(); ++pkg
) { 
 303       StateCache 
const &P 
= PkgState
[pkg
->ID
]; 
 304       if(P
.Flags 
& Flag::Auto
) { 
 305          if (pkgs_seen
.find(pkg
.FullName()) != pkgs_seen
.end()) { 
 307                std::clog 
<< "Skipping already written " << pkg
.FullName() << std::endl
; 
 310          // skip not installed ones if requested 
 311          if (InstalledOnly 
&& ( 
 312              (pkg
->CurrentVer 
== 0 && P
.Mode 
!= ModeInstall
) || 
 313              (pkg
->CurrentVer 
!= 0 && P
.Mode 
== ModeDelete
))) 
 315          const char* const pkgarch 
= pkg
.Arch(); 
 316          if (strcmp(pkgarch
, "all") == 0) 
 319             std::clog 
<< "Writing new AutoInstall: " << pkg
.FullName() << std::endl
; 
 320          ostr
.str(string("")); 
 321          ostr 
<< "Package: " << pkg
.Name() 
 322               << "\nArchitecture: " << pkgarch
 
 323               << "\nAuto-Installed: 1\n\n"; 
 324          fprintf(OutFile
,"%s",ostr
.str().c_str()); 
 329    // move the outfile over the real file and set permissions 
 330    rename(outfile
.c_str(), state
.c_str()); 
 331    chmod(state
.c_str(), 0644); 
 336 // DepCache::CheckDep - Checks a single dependency                      /*{{{*/ 
 337 // --------------------------------------------------------------------- 
 338 /* This first checks the dependency against the main target package and 
 339    then walks along the package provides list and checks if each provides  
 340    will be installed then checks the provides against the dep. Res will be  
 341    set to the package which was used to satisfy the dep. */ 
 342 bool pkgDepCache::CheckDep(DepIterator Dep
,int Type
,PkgIterator 
&Res
) 
 344    Res 
= Dep
.TargetPkg(); 
 346    /* Check simple depends. A depends -should- never self match but  
 347       we allow it anyhow because dpkg does. Technically it is a packaging 
 348       bug. Conflicts may never self match */ 
 349    if (Dep
.TargetPkg() != Dep
.ParentPkg() || Dep
.IsNegative() == false) 
 351       PkgIterator Pkg 
= Dep
.TargetPkg(); 
 352       // Check the base package 
 353       if (Type 
== NowVersion 
&& Pkg
->CurrentVer 
!= 0) 
 354          if (VS().CheckDep(Pkg
.CurrentVer().VerStr(),Dep
->CompareOp
, 
 355                                  Dep
.TargetVer()) == true) 
 358       if (Type 
== InstallVersion 
&& PkgState
[Pkg
->ID
].InstallVer 
!= 0) 
 359          if (VS().CheckDep(PkgState
[Pkg
->ID
].InstVerIter(*this).VerStr(), 
 360                                  Dep
->CompareOp
,Dep
.TargetVer()) == true) 
 363       if (Type 
== CandidateVersion 
&& PkgState
[Pkg
->ID
].CandidateVer 
!= 0) 
 364          if (VS().CheckDep(PkgState
[Pkg
->ID
].CandidateVerIter(*this).VerStr(), 
 365                                  Dep
->CompareOp
,Dep
.TargetVer()) == true) 
 369    if (Dep
->Type 
== Dep::Obsoletes
) 
 372    // Check the providing packages 
 373    PrvIterator P 
= Dep
.TargetPkg().ProvidesList(); 
 374    for (; P
.end() != true; ++P
) 
 376       if (Dep
.IsIgnorable(P
) == true) 
 379       // Check if the provides is a hit 
 380       if (Type 
== NowVersion
) 
 382          if (P
.OwnerPkg().CurrentVer() != P
.OwnerVer()) 
 386       if (Type 
== InstallVersion
) 
 388          StateCache 
&State 
= PkgState
[P
.OwnerPkg()->ID
]; 
 389          if (State
.InstallVer 
!= (Version 
*)P
.OwnerVer()) 
 393       if (Type 
== CandidateVersion
) 
 395          StateCache 
&State 
= PkgState
[P
.OwnerPkg()->ID
]; 
 396          if (State
.CandidateVer 
!= (Version 
*)P
.OwnerVer()) 
 400       // Compare the versions. 
 401       if (VS().CheckDep(P
.ProvideVersion(),Dep
->CompareOp
,Dep
.TargetVer()) == true) 
 411 // DepCache::AddSizes - Add the packages sizes to the counters          /*{{{*/ 
 412 // --------------------------------------------------------------------- 
 413 /* Call with Inverse = true to preform the inverse opration */ 
 414 void pkgDepCache::AddSizes(const PkgIterator 
&Pkg
, bool const Inverse
) 
 416    StateCache 
&P 
= PkgState
[Pkg
->ID
]; 
 418    if (Pkg
->VersionList 
== 0) 
 421    if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure 
&&  
 425    // Compute the size data 
 426    if (P
.NewInstall() == true) 
 428       if (Inverse 
== false) { 
 429          iUsrSize 
+= P
.InstVerIter(*this)->InstalledSize
; 
 430          iDownloadSize 
+= P
.InstVerIter(*this)->Size
; 
 432          iUsrSize 
-= P
.InstVerIter(*this)->InstalledSize
; 
 433          iDownloadSize 
-= P
.InstVerIter(*this)->Size
; 
 439    if (Pkg
->CurrentVer 
!= 0 &&  
 440        (P
.InstallVer 
!= (Version 
*)Pkg
.CurrentVer() ||  
 441         (P
.iFlags 
& ReInstall
) == ReInstall
) && P
.InstallVer 
!= 0) 
 443       if (Inverse 
== false) { 
 444          iUsrSize 
-= Pkg
.CurrentVer()->InstalledSize
; 
 445          iUsrSize 
+= P
.InstVerIter(*this)->InstalledSize
; 
 446          iDownloadSize 
+= P
.InstVerIter(*this)->Size
; 
 448          iUsrSize 
-= P
.InstVerIter(*this)->InstalledSize
; 
 449          iUsrSize 
+= Pkg
.CurrentVer()->InstalledSize
; 
 450          iDownloadSize 
-= P
.InstVerIter(*this)->Size
; 
 456    if (Pkg
.State() == pkgCache::PkgIterator::NeedsUnpack 
&& 
 459       if (Inverse 
== false) 
 460          iDownloadSize 
+= P
.InstVerIter(*this)->Size
; 
 462          iDownloadSize 
-= P
.InstVerIter(*this)->Size
; 
 467    if (Pkg
->CurrentVer 
!= 0 && P
.InstallVer 
== 0) 
 469       if (Inverse 
== false) 
 470          iUsrSize 
-= Pkg
.CurrentVer()->InstalledSize
; 
 472          iUsrSize 
+= Pkg
.CurrentVer()->InstalledSize
; 
 477 // DepCache::AddStates - Add the package to the state counter           /*{{{*/ 
 478 // --------------------------------------------------------------------- 
 479 /* This routine is tricky to use, you must make sure that it is never  
 480    called twice for the same package. This means the Remove/Add section 
 481    should be as short as possible and not encompass any code that will  
 482    calld Remove/Add itself. Remember, dependencies can be circular so 
 483    while processing a dep for Pkg it is possible that Add/Remove 
 484    will be called on Pkg */ 
 485 void pkgDepCache::AddStates(const PkgIterator 
&Pkg
, bool const Invert
) 
 487    signed char const Add 
= (Invert 
== false) ? 1 : -1; 
 488    StateCache 
&State 
= PkgState
[Pkg
->ID
]; 
 490    // The Package is broken (either minimal dep or policy dep) 
 491    if ((State
.DepState 
& DepInstMin
) != DepInstMin
) 
 493    if ((State
.DepState 
& DepInstPolicy
) != DepInstPolicy
) 
 494       iPolicyBrokenCount 
+= Add
; 
 497    if (Pkg
.State() != PkgIterator::NeedsNothing
) 
 501    if (Pkg
->CurrentVer 
== 0) 
 503       if (State
.Mode 
== ModeDelete 
&& 
 504           (State
.iFlags 
& Purge
) == Purge 
&& Pkg
.Purge() == false) 
 507       if (State
.Mode 
== ModeInstall
) 
 512    // Installed, no upgrade 
 513    if (State
.Status 
== 0) 
 515       if (State
.Mode 
== ModeDelete
) 
 518          if ((State
.iFlags 
& ReInstall
) == ReInstall
) 
 524    // Alll 3 are possible 
 525    if (State
.Mode 
== ModeDelete
) 
 527    if (State
.Mode 
== ModeKeep
) 
 529    if (State
.Mode 
== ModeInstall
) 
 533 // DepCache::BuildGroupOrs - Generate the Or group dep data             /*{{{*/ 
 534 // --------------------------------------------------------------------- 
 535 /* The or group results are stored in the last item of the or group. This 
 536    allows easy detection of the state of a whole or'd group. */ 
 537 void pkgDepCache::BuildGroupOrs(VerIterator 
const &V
) 
 539    unsigned char Group 
= 0; 
 541    for (DepIterator D 
= V
.DependsList(); D
.end() != true; ++D
) 
 543       // Build the dependency state. 
 544       unsigned char &State 
= DepState
[D
->ID
]; 
 546       /* Invert for Conflicts. We have to do this twice to get the 
 547          right sense for a conflicts group */ 
 548       if (D
.IsNegative() == true) 
 551       // Add to the group if we are within an or.. 
 555       if ((D
->CompareOp 
& Dep::Or
) != Dep::Or
) 
 558       // Invert for Conflicts 
 559       if (D
.IsNegative() == true) 
 564 // DepCache::VersionState - Perform a pass over a dependency list       /*{{{*/ 
 565 // --------------------------------------------------------------------- 
 566 /* This is used to run over a dependency list and determine the dep 
 567    state of the list, filtering it through both a Min check and a Policy 
 568    check. The return result will have SetMin/SetPolicy low if a check 
 569    fails. It uses the DepState cache for it's computations. */ 
 570 unsigned char pkgDepCache::VersionState(DepIterator D
,unsigned char Check
, 
 571                                        unsigned char SetMin
, 
 572                                        unsigned char SetPolicy
) 
 574    unsigned char Dep 
= 0xFF; 
 576    while (D
.end() != true) 
 578       // Compute a single dependency element (glob or) 
 579       DepIterator Start 
= D
; 
 580       unsigned char State 
= 0; 
 581       for (bool LastOR 
= true; D
.end() == false && LastOR 
== true; ++D
) 
 583          State 
|= DepState
[D
->ID
]; 
 584          LastOR 
= (D
->CompareOp 
& Dep::Or
) == Dep::Or
; 
 587       // Minimum deps that must be satisfied to have a working package 
 588       if (Start
.IsCritical() == true) 
 589          if ((State 
& Check
) != Check
) 
 592       // Policy deps that must be satisfied to install the package 
 593       if (IsImportantDep(Start
) == true &&  
 594           (State 
& Check
) != Check
) 
 601 // DepCache::DependencyState - Compute the 3 results for a dep          /*{{{*/ 
 602 // --------------------------------------------------------------------- 
 603 /* This is the main dependency computation bit. It computes the 3 main 
 604    results for a dependencys, Now, Install and Candidate. Callers must 
 605    invert the result if dealing with conflicts. */ 
 606 unsigned char pkgDepCache::DependencyState(DepIterator 
&D
) 
 608    unsigned char State 
= 0; 
 610    if (CheckDep(D
,NowVersion
) == true) 
 612    if (CheckDep(D
,InstallVersion
) == true) 
 614    if (CheckDep(D
,CandidateVersion
) == true) 
 620 // DepCache::UpdateVerState - Compute the Dep member of the state       /*{{{*/ 
 621 // --------------------------------------------------------------------- 
 622 /* This determines the combined dependency representation of a package 
 623    for its two states now and install. This is done by using the pre-generated 
 624    dependency information. */ 
 625 void pkgDepCache::UpdateVerState(PkgIterator Pkg
) 
 627    // Empty deps are always true 
 628    StateCache 
&State 
= PkgState
[Pkg
->ID
]; 
 629    State
.DepState 
= 0xFF; 
 631    // Check the Current state 
 632    if (Pkg
->CurrentVer 
!= 0) 
 634       DepIterator D 
= Pkg
.CurrentVer().DependsList(); 
 635       State
.DepState 
&= VersionState(D
,DepNow
,DepNowMin
,DepNowPolicy
); 
 638    /* Check the candidate state. We do not compare against the whole as 
 639       a candidate state but check the candidate version against the  
 641    if (State
.CandidateVer 
!= 0) 
 643       DepIterator D 
= State
.CandidateVerIter(*this).DependsList(); 
 644       State
.DepState 
&= VersionState(D
,DepInstall
,DepCandMin
,DepCandPolicy
); 
 647    // Check target state which can only be current or installed 
 648    if (State
.InstallVer 
!= 0) 
 650       DepIterator D 
= State
.InstVerIter(*this).DependsList(); 
 651       State
.DepState 
&= VersionState(D
,DepInstall
,DepInstMin
,DepInstPolicy
); 
 655 // DepCache::Update - Figure out all the state information              /*{{{*/ 
 656 // --------------------------------------------------------------------- 
 657 /* This will figure out the state of all the packages and all the  
 658    dependencies based on the current policy. */ 
 659 void pkgDepCache::Update(OpProgress 
*Prog
) 
 669    // Perform the depends pass 
 671    for (PkgIterator I 
= PkgBegin(); I
.end() != true; ++I
, ++Done
) 
 673       if (Prog 
!= 0 && Done%20 
== 0) 
 674          Prog
->Progress(Done
); 
 675       for (VerIterator V 
= I
.VersionList(); V
.end() != true; ++V
) 
 677          unsigned char Group 
= 0; 
 679          for (DepIterator D 
= V
.DependsList(); D
.end() != true; ++D
) 
 681             // Build the dependency state. 
 682             unsigned char &State 
= DepState
[D
->ID
]; 
 683             State 
= DependencyState(D
); 
 685             // Add to the group if we are within an or.. 
 688             if ((D
->CompareOp 
& Dep::Or
) != Dep::Or
) 
 691             // Invert for Conflicts 
 692             if (D
.IsNegative() == true) 
 697       // Compute the package dependency state and size additions 
 704       Prog
->Progress(Done
); 
 709 // DepCache::Update - Update the deps list of a package                 /*{{{*/ 
 710 // --------------------------------------------------------------------- 
 711 /* This is a helper for update that only does the dep portion of the scan.  
 712    It is mainly meant to scan reverse dependencies. */ 
 713 void pkgDepCache::Update(DepIterator D
) 
 715    // Update the reverse deps 
 716    for (;D
.end() != true; ++D
) 
 718       unsigned char &State 
= DepState
[D
->ID
]; 
 719       State 
= DependencyState(D
); 
 721       // Invert for Conflicts 
 722       if (D
.IsNegative() == true) 
 725       RemoveStates(D
.ParentPkg()); 
 726       BuildGroupOrs(D
.ParentVer()); 
 727       UpdateVerState(D
.ParentPkg()); 
 728       AddStates(D
.ParentPkg()); 
 732 // DepCache::Update - Update the related deps of a package              /*{{{*/ 
 733 // --------------------------------------------------------------------- 
 734 /* This is called whenever the state of a package changes. It updates 
 735    all cached dependencies related to this package. */ 
 736 void pkgDepCache::Update(PkgIterator 
const &Pkg
) 
 738    // Recompute the dep of the package 
 743    // Update the reverse deps 
 744    Update(Pkg
.RevDependsList()); 
 746    // Update the provides map for the current ver 
 747    if (Pkg
->CurrentVer 
!= 0) 
 748       for (PrvIterator P 
= Pkg
.CurrentVer().ProvidesList();  
 749            P
.end() != true; ++P
) 
 750          Update(P
.ParentPkg().RevDependsList()); 
 752    // Update the provides map for the candidate ver 
 753    if (PkgState
[Pkg
->ID
].CandidateVer 
!= 0) 
 754       for (PrvIterator P 
= PkgState
[Pkg
->ID
].CandidateVerIter(*this).ProvidesList(); 
 755            P
.end() != true; ++P
) 
 756          Update(P
.ParentPkg().RevDependsList()); 
 759 // DepCache::MarkKeep - Put the package in the keep state               /*{{{*/ 
 760 // --------------------------------------------------------------------- 
 762 bool pkgDepCache::MarkKeep(PkgIterator 
const &Pkg
, bool Soft
, bool FromUser
, 
 765    if (IsModeChangeOk(ModeKeep
, Pkg
, Depth
, FromUser
) == false) 
 768    /* Reject an attempt to keep a non-source broken installed package, those 
 770    if (Pkg
.State() == PkgIterator::NeedsUnpack 
&&  
 771        Pkg
.CurrentVer().Downloadable() == false) 
 774    /* We changed the soft state all the time so the UI is a bit nicer 
 776    StateCache 
&P 
= PkgState
[Pkg
->ID
]; 
 778    // Check that it is not already kept 
 779    if (P
.Mode 
== ModeKeep
) 
 783       P
.iFlags 
|= AutoKept
; 
 785       P
.iFlags 
&= ~AutoKept
; 
 787    ActionGroup 
group(*this); 
 789 #if 0 // reseting the autoflag here means we lose the  
 790       // auto-mark information if a user selects a package for removal 
 791       // but changes  his mind then and sets it for keep again 
 792       // - this makes sense as default when all Garbage dependencies 
 793       //   are automatically marked for removal (as aptitude does). 
 794       //   setting a package for keep then makes it no longer autoinstalled 
 795       //   for all other use-case this action is rather suprising 
 796    if(FromUser 
&& !P
.Marked
) 
 797      P
.Flags 
&= ~Flag::Auto
; 
 800    if (DebugMarker 
== true) 
 801       std::clog 
<< OutputInDepth(Depth
) << "MarkKeep " << Pkg 
<< " FU=" << FromUser 
<< std::endl
; 
 807    if (Pkg
->CurrentVer 
== 0) 
 810       P
.InstallVer 
= Pkg
.CurrentVer(); 
 819 // DepCache::MarkDelete - Put the package in the delete state           /*{{{*/ 
 820 // --------------------------------------------------------------------- 
 822 bool pkgDepCache::MarkDelete(PkgIterator 
const &Pkg
, bool rPurge
, 
 823                              unsigned long Depth
, bool FromUser
) 
 825    if (IsModeChangeOk(ModeDelete
, Pkg
, Depth
, FromUser
) == false) 
 828    StateCache 
&P 
= PkgState
[Pkg
->ID
]; 
 830    // Check that it is not already marked for delete 
 831    if ((P
.Mode 
== ModeDelete 
|| P
.InstallVer 
== 0) &&  
 832        (Pkg
.Purge() == true || rPurge 
== false)) 
 835    // check if we are allowed to remove the package 
 836    if (IsDeleteOk(Pkg
,rPurge
,Depth
,FromUser
) == false) 
 839    P
.iFlags 
&= ~(AutoKept 
| Purge
); 
 843    ActionGroup 
group(*this); 
 845    if (DebugMarker 
== true) 
 846       std::clog 
<< OutputInDepth(Depth
) << (rPurge 
? "MarkPurge " : "MarkDelete ") << Pkg 
<< " FU=" << FromUser 
<< std::endl
; 
 851    if (Pkg
->CurrentVer 
== 0 && (Pkg
.Purge() == true || rPurge 
== false)) 
 864 // DepCache::IsDeleteOk - check if it is ok to remove this package      /*{{{*/ 
 865 // --------------------------------------------------------------------- 
 866 /* The default implementation tries to prevent deletion of install requests. 
 867    dpkg holds are enforced by the private IsModeChangeOk */ 
 868 bool pkgDepCache::IsDeleteOk(PkgIterator 
const &Pkg
,bool rPurge
, 
 869                               unsigned long Depth
, bool FromUser
) 
 871    if (FromUser 
== false && Pkg
->CurrentVer 
== 0) 
 873       StateCache 
&P 
= PkgState
[Pkg
->ID
]; 
 874       if (P
.InstallVer 
!= 0 && P
.Status 
== 2 && (P
.Flags 
& Flag::Auto
) != Flag::Auto
) 
 876          if (DebugMarker 
== true) 
 877             std::clog 
<< OutputInDepth(Depth
) << "Manual install request prevents MarkDelete of " << Pkg 
<< std::endl
; 
 884 // DepCache::IsModeChangeOk - check if it is ok to change the mode      /*{{{*/ 
 885 // --------------------------------------------------------------------- 
 886 /* this is used by all Mark methods on the very first line to check sanity 
 887    and prevents mode changes for packages on hold for example. 
 888    If you want to check Mode specific stuff you can use the virtual public 
 889    Is<Mode>Ok methods instead */ 
 890 char const* PrintMode(char const mode
) 
 894          case pkgDepCache::ModeInstall
: return "Install"; 
 895          case pkgDepCache::ModeKeep
: return "Keep"; 
 896          case pkgDepCache::ModeDelete
: return "Delete"; 
 897          default: return "UNKNOWN"; 
 900 bool pkgDepCache::IsModeChangeOk(ModeList 
const mode
, PkgIterator 
const &Pkg
, 
 901                                  unsigned long const Depth
, bool const FromUser
) 
 903    // we are not trying to hard… 
 904    if (unlikely(Depth 
> 100)) 
 908    if (unlikely(Pkg
.end() == true || Pkg
->VersionList 
== 0)) 
 911    // the user is always right 
 912    if (FromUser 
== true) 
 915    StateCache 
&P 
= PkgState
[Pkg
->ID
]; 
 917    // if previous state was set by user only user can reset it 
 918    if ((P
.iFlags 
& Protected
) == Protected
) 
 920       if (unlikely(DebugMarker 
== true) && P
.Mode 
!= mode
) 
 921          std::clog 
<< OutputInDepth(Depth
) << "Ignore Mark" << PrintMode(mode
) 
 922                    << " of " << Pkg 
<< " as its mode (" << PrintMode(P
.Mode
) 
 923                    << ") is protected" << std::endl
; 
 926    // enforce dpkg holds 
 927    else if (mode 
!= ModeKeep 
&& Pkg
->SelectedState 
== pkgCache::State::Hold 
&& 
 928             _config
->FindB("APT::Ignore-Hold",false) == false) 
 930       if (unlikely(DebugMarker 
== true) && P
.Mode 
!= mode
) 
 931          std::clog 
<< OutputInDepth(Depth
) << "Hold prevents Mark" << PrintMode(mode
) 
 932                    << " of " << Pkg 
<< std::endl
; 
 939 // DepCache::MarkInstall - Put the package in the install state         /*{{{*/ 
 940 // --------------------------------------------------------------------- 
 942 struct CompareProviders 
{ 
 943    pkgCache::PkgIterator 
const Pkg
; 
 944    CompareProviders(pkgCache::DepIterator 
const &Dep
) : Pkg(Dep
.TargetPkg()) {}; 
 945    //bool operator() (APT::VersionList::iterator const &AV, APT::VersionList::iterator const &BV) 
 946    bool operator() (pkgCache::VerIterator 
const &AV
, pkgCache::VerIterator 
const &BV
) 
 948       pkgCache::PkgIterator 
const A 
= AV
.ParentPkg(); 
 949       pkgCache::PkgIterator 
const B 
= BV
.ParentPkg(); 
 950       // Prefer packages in the same group as the target; e.g. foo:i386, foo:amd64 
 951       if (A
->Group 
!= B
->Group
) 
 953          if (A
->Group 
== Pkg
->Group 
&& B
->Group 
!= Pkg
->Group
) 
 955          else if (B
->Group 
== Pkg
->Group 
&& A
->Group 
!= Pkg
->Group
) 
 958       // we like essentials 
 959       if ((A
->Flags 
& pkgCache::Flag::Essential
) != (B
->Flags 
& pkgCache::Flag::Essential
)) 
 961          if ((A
->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
) 
 963          else if ((B
->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
) 
 966       if ((A
->Flags 
& pkgCache::Flag::Important
) != (B
->Flags 
& pkgCache::Flag::Important
)) 
 968          if ((A
->Flags 
& pkgCache::Flag::Important
) == pkgCache::Flag::Important
) 
 970          else if ((B
->Flags 
& pkgCache::Flag::Important
) == pkgCache::Flag::Important
) 
 973       // higher priority seems like a good idea 
 974       if (AV
->Priority 
!= BV
->Priority
) 
 975          return AV
->Priority 
< BV
->Priority
; 
 976       // prefer native architecture 
 977       if (strcmp(A
.Arch(), B
.Arch()) != 0) 
 979          if (strcmp(A
.Arch(), A
.Cache()->NativeArch()) == 0) 
 981          else if (strcmp(B
.Arch(), B
.Cache()->NativeArch()) == 0) 
 983          std::vector
<std::string
> archs 
= APT::Configuration::getArchitectures(); 
 984          for (std::vector
<std::string
>::const_iterator a 
= archs
.begin(); a 
!= archs
.end(); ++a
) 
 987             else if (*a 
== B
.Arch()) 
 990       // unable to decide… 
 991       return A
->ID 
< B
->ID
; 
 994 bool pkgDepCache::MarkInstall(PkgIterator 
const &Pkg
,bool AutoInst
, 
 995                               unsigned long Depth
, bool FromUser
, 
 996                               bool ForceImportantDeps
) 
 998    if (IsModeChangeOk(ModeInstall
, Pkg
, Depth
, FromUser
) == false) 
1001    StateCache 
&P 
= PkgState
[Pkg
->ID
]; 
1003    // See if there is even any possible instalation candidate 
1004    if (P
.CandidateVer 
== 0) 
1007    /* Check that it is not already marked for install and that it can be  
1009    if ((P
.InstPolicyBroken() == false && P
.InstBroken() == false) &&  
1010        (P
.Mode 
== ModeInstall 
|| 
1011         P
.CandidateVer 
== (Version 
*)Pkg
.CurrentVer())) 
1013       if (P
.CandidateVer 
== (Version 
*)Pkg
.CurrentVer() && P
.InstallVer 
== 0) 
1014          return MarkKeep(Pkg
, false, FromUser
, Depth
+1); 
1018    // check if we are allowed to install the package 
1019    if (IsInstallOk(Pkg
,AutoInst
,Depth
,FromUser
) == false) 
1022    ActionGroup 
group(*this); 
1023    P
.iFlags 
&= ~AutoKept
; 
1025    /* Target the candidate version and remove the autoflag. We reset the 
1026       autoflag below if this was called recursively. Otherwise the user 
1027       should have the ability to de-auto a package by changing its state */ 
1031    P
.Mode 
= ModeInstall
; 
1032    P
.InstallVer 
= P
.CandidateVer
; 
1036        // Set it to manual if it's a new install or already installed, 
1037        // but only if its not marked by the autoremover (aptitude depend on this behavior) 
1038        // or if we do automatic installation (aptitude never does it) 
1039        if(P
.Status 
== 2 || (Pkg
->CurrentVer 
!= 0 && (AutoInst 
== true || P
.Marked 
== false))) 
1040          P
.Flags 
&= ~Flag::Auto
; 
1044        // Set it to auto if this is a new install. 
1046          P
.Flags 
|= Flag::Auto
; 
1048    if (P
.CandidateVer 
== (Version 
*)Pkg
.CurrentVer()) 
1055    if (AutoInst 
== false || _config
->Find("APT::Solver", "internal") != "internal") 
1058    if (DebugMarker 
== true) 
1059       std::clog 
<< OutputInDepth(Depth
) << "MarkInstall " << Pkg 
<< " FU=" << FromUser 
<< std::endl
; 
1061    DepIterator Dep 
= P
.InstVerIter(*this).DependsList(); 
1062    for (; Dep
.end() != true;) 
1065       DepIterator Start 
= Dep
; 
1068       for (bool LastOR 
= true; Dep
.end() == false && LastOR 
== true; ++Dep
, ++Ors
) 
1070          LastOR 
= (Dep
->CompareOp 
& Dep::Or
) == Dep::Or
; 
1072          if ((DepState
[Dep
->ID
] & DepInstall
) == DepInstall
) 
1076       // Dep is satisfied okay. 
1077       if (Result 
== false) 
1080       /* Check if this dep should be consider for install. If it is a user 
1081          defined important dep and we are installed a new package then  
1082          it will be installed. Otherwise we only check for important 
1083          deps that have changed from the installed version 
1085       if (IsImportantDep(Start
) == false) 
1088       /* If we are in an or group locate the first or that can  
1089          succeed. We have already cached this.. */ 
1090       for (; Ors 
> 1 && (DepState
[Start
->ID
] & DepCVer
) != DepCVer
; --Ors
) 
1092       if (Ors 
== 1 && (DepState
[Start
->ID
] &DepCVer
) != DepCVer 
&& Start
.IsNegative() == false) 
1094          if(DebugAutoInstall 
== true) 
1095             std::clog 
<< OutputInDepth(Depth
) << Start 
<< " can't be satisfied!" << std::endl
; 
1096          if (Start
.IsCritical() == false) 
1098          // if the dependency was critical, we can't install it, so remove it again 
1099          MarkDelete(Pkg
,false,Depth 
+ 1, false); 
1103       /* Check if any ImportantDep() (but not Critical) were added 
1104        * since we installed the package.  Also check for deps that 
1105        * were satisfied in the past: for instance, if a version 
1106        * restriction in a Recommends was tightened, upgrading the 
1107        * package should follow that Recommends rather than causing the 
1108        * dependency to be removed. (bug #470115) 
1110       if (Pkg
->CurrentVer 
!= 0 && ForceImportantDeps 
== false && Start
.IsCritical() == false) 
1112          bool isNewImportantDep 
= true; 
1113          bool isPreviouslySatisfiedImportantDep 
= false; 
1114          for (DepIterator D 
= Pkg
.CurrentVer().DependsList(); D
.end() != true; ++D
) 
1116             //FIXME: Should we handle or-group better here? 
1117             // We do not check if the package we look for is part of the same or-group 
1118             // we might find while searching, but could that really be a problem? 
1119             if (D
.IsCritical() == true || IsImportantDep(D
) == false || 
1120                 Start
.TargetPkg() != D
.TargetPkg()) 
1123             isNewImportantDep 
= false; 
1125             while ((D
->CompareOp 
& Dep::Or
) != 0) 
1128             isPreviouslySatisfiedImportantDep 
= (((*this)[D
] & DepGNow
) != 0); 
1129             if (isPreviouslySatisfiedImportantDep 
== true) 
1133          if(isNewImportantDep 
== true) 
1135             if (DebugAutoInstall 
== true) 
1136                std::clog 
<< OutputInDepth(Depth
) << "new important dependency: " 
1137                          << Start
.TargetPkg().FullName() << std::endl
; 
1139          else if(isPreviouslySatisfiedImportantDep 
== true) 
1141             if (DebugAutoInstall 
== true) 
1142                std::clog 
<< OutputInDepth(Depth
) << "previously satisfied important dependency on " 
1143                          << Start
.TargetPkg().FullName() << std::endl
; 
1147             if (DebugAutoInstall 
== true) 
1148                std::clog 
<< OutputInDepth(Depth
) << "ignore old unsatisfied important dependency on " 
1149                          << Start
.TargetPkg().FullName() << std::endl
; 
1154       /* This bit is for processing the possibilty of an install/upgrade 
1155          fixing the problem for "positive" dependencies */ 
1156       if (Start
.IsNegative() == false && (DepState
[Start
->ID
] & DepCVer
) == DepCVer
) 
1158          APT::VersionList verlist
; 
1159          pkgCache::VerIterator Cand 
= PkgState
[Start
.TargetPkg()->ID
].CandidateVerIter(*this); 
1160          if (Cand
.end() == false && VS().CheckDep(Cand
.VerStr(), Start
->CompareOp
, Start
.TargetVer()) == true) 
1161             verlist
.insert(Cand
); 
1162          for (PrvIterator Prv 
= Start
.TargetPkg().ProvidesList(); Prv
.end() != true; ++Prv
) 
1164             pkgCache::VerIterator V 
= Prv
.OwnerVer(); 
1165             pkgCache::VerIterator Cand 
= PkgState
[Prv
.OwnerPkg()->ID
].CandidateVerIter(*this); 
1166             if (Cand
.end() == true || V 
!= Cand 
|| 
1167                 VS().CheckDep(Prv
.ProvideVersion(), Start
->CompareOp
, Start
.TargetVer()) == false) 
1169             verlist
.insert(Cand
); 
1171          CompareProviders 
comp(Start
); 
1172          APT::VersionList::iterator InstVer 
= std::max_element(verlist
.begin(), verlist
.end(), comp
); 
1174          if (InstVer 
!= verlist
.end()) 
1176             pkgCache::PkgIterator InstPkg 
= InstVer
.ParentPkg(); 
1177             if(DebugAutoInstall 
== true) 
1178                std::clog 
<< OutputInDepth(Depth
) << "Installing " << InstPkg
.Name() 
1179                          << " as " << Start
.DepType() << " of " << Pkg
.Name() 
1181             // now check if we should consider it a automatic dependency or not 
1182             if(Pkg
.Section() && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", Pkg
.Section())) 
1184                if(DebugAutoInstall 
== true) 
1185                   std::clog 
<< OutputInDepth(Depth
) << "Setting NOT as auto-installed (direct " 
1186                             << Start
.DepType() << " of pkg in APT::Never-MarkAuto-Sections)" << std::endl
; 
1187                MarkInstall(InstPkg
,true,Depth 
+ 1, true); 
1191                // mark automatic dependency 
1192                MarkInstall(InstPkg
,true,Depth 
+ 1, false, ForceImportantDeps
); 
1193                // Set the autoflag, after MarkInstall because MarkInstall unsets it 
1194                if (InstPkg
->CurrentVer 
== 0) 
1195                   PkgState
[InstPkg
->ID
].Flags 
|= Flag::Auto
; 
1200       /* Negative dependencies have no or-group 
1201          If the dependency isn't versioned, we try if an upgrade might solve the problem. 
1202          Otherwise we remove the offender if needed */ 
1203       else if (Start
.IsNegative() == true && Start
->Type 
!= pkgCache::Dep::Obsoletes
) 
1205          SPtrArray
<Version 
*> List 
= Start
.AllTargets(); 
1206          pkgCache::PkgIterator TrgPkg 
= Start
.TargetPkg(); 
1207          for (Version 
**I 
= List
; *I 
!= 0; I
++) 
1209             VerIterator 
Ver(*this,*I
); 
1210             PkgIterator Pkg 
= Ver
.ParentPkg(); 
1212             /* The List includes all packages providing this dependency, 
1213                even providers which are not installed, so skip them. */ 
1214             if (PkgState
[Pkg
->ID
].InstallVer 
== 0) 
1217             if ((Start
->Version 
!= 0 || TrgPkg 
!= Pkg
) && 
1218                 PkgState
[Pkg
->ID
].CandidateVer 
!= PkgState
[Pkg
->ID
].InstallVer 
&& 
1219                 PkgState
[Pkg
->ID
].CandidateVer 
!= *I 
&& 
1220                 MarkInstall(Pkg
,true,Depth 
+ 1, false, ForceImportantDeps
) == true) 
1222             else if ((Start
->Type 
== pkgCache::Dep::Conflicts 
|| Start
->Type 
== pkgCache::Dep::DpkgBreaks
) && 
1223                      MarkDelete(Pkg
,false,Depth 
+ 1, false) == false) 
1230    return Dep
.end() == true; 
1233 // DepCache::IsInstallOk - check if it is ok to install this package    /*{{{*/ 
1234 // --------------------------------------------------------------------- 
1235 /* The default implementation does nothing. 
1236    dpkg holds are enforced by the private IsModeChangeOk */ 
1237 bool pkgDepCache::IsInstallOk(PkgIterator 
const &Pkg
,bool AutoInst
, 
1238                               unsigned long Depth
, bool FromUser
) 
1243 // DepCache::SetReInstall - Set the reinstallation flag                 /*{{{*/ 
1244 // --------------------------------------------------------------------- 
1246 void pkgDepCache::SetReInstall(PkgIterator 
const &Pkg
,bool To
) 
1248    if (unlikely(Pkg
.end() == true)) 
1251    APT::PackageList pkglist
; 
1252    if (Pkg
->CurrentVer 
!= 0 && 
1253        (Pkg
.CurrentVer()-> MultiArch 
& pkgCache::Version::Same
) == pkgCache::Version::Same
) 
1255       pkgCache::GrpIterator Grp 
= Pkg
.Group(); 
1256       for (pkgCache::PkgIterator P 
= Grp
.PackageList(); P
.end() == false; P 
= Grp
.NextPkg(P
)) 
1258          if (P
->CurrentVer 
!= 0) 
1263       pkglist
.insert(Pkg
); 
1265    ActionGroup 
group(*this); 
1267    for (APT::PackageList::const_iterator Pkg 
= pkglist
.begin(); Pkg 
!= pkglist
.end(); ++Pkg
) 
1272       StateCache 
&P 
= PkgState
[Pkg
->ID
]; 
1274          P
.iFlags 
|= ReInstall
; 
1276          P
.iFlags 
&= ~ReInstall
; 
1283 // DepCache::SetCandidateVersion - Change the candidate version         /*{{{*/ 
1284 // --------------------------------------------------------------------- 
1286 void pkgDepCache::SetCandidateVersion(VerIterator TargetVer
) 
1288    pkgCache::PkgIterator Pkg 
= TargetVer
.ParentPkg(); 
1289    StateCache 
&P 
= PkgState
[Pkg
->ID
]; 
1291    if (P
.CandidateVer 
== TargetVer
) 
1294    ActionGroup 
group(*this); 
1299    if (P
.CandidateVer 
== P
.InstallVer 
&& P
.Install() == true) 
1300       P
.InstallVer 
= (Version 
*)TargetVer
; 
1301    P
.CandidateVer 
= (Version 
*)TargetVer
; 
1302    P
.Update(Pkg
,*this); 
1310 // DepCache::SetCandidateRelease - Change the candidate version         /*{{{*/ 
1311 // --------------------------------------------------------------------- 
1312 /* changes the candidate of a package and walks over all its dependencies 
1313    to check if it needs to change the candidate of the dependency, too, 
1314    to reach a installable versionstate */ 
1315 bool pkgDepCache::SetCandidateRelease(pkgCache::VerIterator TargetVer
, 
1316                                         std::string 
const &TargetRel
) 
1318    std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> > Changed
; 
1319    return SetCandidateRelease(TargetVer
, TargetRel
, Changed
); 
1321 bool pkgDepCache::SetCandidateRelease(pkgCache::VerIterator TargetVer
, 
1322                                         std::string 
const &TargetRel
, 
1323                                         std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> > &Changed
) 
1325    ActionGroup 
group(*this); 
1326    SetCandidateVersion(TargetVer
); 
1328    if (TargetRel 
== "installed" || TargetRel 
== "candidate") // both doesn't make sense in this context 
1331    pkgVersionMatch 
Match(TargetRel
, pkgVersionMatch::Release
); 
1332    // save the position of the last element we will not undo - if we have to 
1333    std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> >::iterator newChanged 
= --(Changed
.end()); 
1335    for (pkgCache::DepIterator D 
= TargetVer
.DependsList(); D
.end() == false; ++D
) 
1337       if (D
->Type 
!= pkgCache::Dep::PreDepends 
&& D
->Type 
!= pkgCache::Dep::Depends 
&& 
1338           ((D
->Type 
!= pkgCache::Dep::Recommends 
&& D
->Type 
!= pkgCache::Dep::Suggests
) || 
1339            IsImportantDep(D
) == false)) 
1342       // walk over an or-group and check if we need to do anything 
1343       // for simpilicity no or-group is handled as a or-group including one dependency 
1344       pkgCache::DepIterator Start 
= D
; 
1345       bool itsFine 
= false; 
1346       for (bool stillOr 
= true; stillOr 
== true; ++Start
) 
1348          stillOr 
= (Start
->CompareOp 
& Dep::Or
) == Dep::Or
; 
1349          pkgCache::PkgIterator 
const P 
= Start
.TargetPkg(); 
1350          // virtual packages can't be a solution 
1351          if (P
.end() == true || (P
->ProvidesList 
== 0 && P
->VersionList 
== 0)) 
1353          pkgCache::VerIterator 
const Cand 
= PkgState
[P
->ID
].CandidateVerIter(*this); 
1354          // no versioned dependency - but is it installable? 
1355          if (Start
.TargetVer() == 0 || Start
.TargetVer()[0] == '\0') 
1357             // Check if one of the providers is installable 
1358             if (P
->ProvidesList 
!= 0) 
1360                pkgCache::PrvIterator Prv 
= P
.ProvidesList(); 
1361                for (; Prv
.end() == false; ++Prv
) 
1363                   pkgCache::VerIterator 
const C 
= PkgState
[Prv
.OwnerPkg()->ID
].CandidateVerIter(*this); 
1364                   if (C
.end() == true || C 
!= Prv
.OwnerVer() || 
1365                       (VersionState(C
.DependsList(), DepInstall
, DepCandMin
, DepCandPolicy
) & DepCandMin
) != DepCandMin
) 
1369                if (Prv
.end() == true) 
1372             // no providers, so check if we have an installable candidate version 
1373             else if (Cand
.end() == true || 
1374                 (VersionState(Cand
.DependsList(), DepInstall
, DepCandMin
, DepCandPolicy
) & DepCandMin
) != DepCandMin
) 
1379          if (Cand
.end() == true) 
1381          // check if the current candidate is enough for the versioned dependency - and installable? 
1382          if (VS().CheckDep(P
.CandVersion(), Start
->CompareOp
, Start
.TargetVer()) == true && 
1383              (VersionState(Cand
.DependsList(), DepInstall
, DepCandMin
, DepCandPolicy
) & DepCandMin
) == DepCandMin
) 
1390       if (itsFine 
== true) { 
1391          // something in the or-group was fine, skip all other members 
1392          for (; (D
->CompareOp 
& Dep::Or
) == Dep::Or
; ++D
); 
1396       // walk again over the or-group and check each if a candidate switch would help 
1398       for (bool stillOr 
= true; stillOr 
== true; ++D
) 
1400          stillOr 
= (D
->CompareOp 
& Dep::Or
) == Dep::Or
; 
1401          // changing candidate will not help if the dependency is not versioned 
1402          if (D
.TargetVer() == 0 || D
.TargetVer()[0] == '\0') 
1404             if (stillOr 
== true) 
1409          pkgCache::VerIterator V
; 
1410          if (TargetRel 
== "newest") 
1411             V 
= D
.TargetPkg().VersionList(); 
1413             V 
= Match
.Find(D
.TargetPkg()); 
1415          // check if the version from this release could satisfy the dependency 
1416          if (V
.end() == true || VS().CheckDep(V
.VerStr(), D
->CompareOp
, D
.TargetVer()) == false) 
1418             if (stillOr 
== true) 
1423          pkgCache::VerIterator oldCand 
= PkgState
[D
.TargetPkg()->ID
].CandidateVerIter(*this); 
1426             // Do we already touched this Version? If so, their versioned dependencies are okay, no need to check again 
1427             for (std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> >::const_iterator c 
= Changed
.begin(); 
1428                  c 
!= Changed
.end(); ++c
) 
1430                if (c
->first
->ParentPkg 
!= V
->ParentPkg
) 
1437          if (itsFine 
== false) 
1439             // change the candidate 
1440             Changed
.push_back(make_pair(oldCand
, TargetVer
)); 
1441             if (SetCandidateRelease(V
, TargetRel
, Changed
) == false) 
1443                if (stillOr 
== false) 
1445                // undo the candidate changing 
1446                SetCandidateVersion(oldCand
); 
1453          // something in the or-group was fine, skip all other members 
1454          for (; (D
->CompareOp 
& Dep::Or
) == Dep::Or
; ++D
); 
1458       if (itsFine 
== false && (D
->Type 
== pkgCache::Dep::PreDepends 
|| D
->Type 
== pkgCache::Dep::Depends
)) 
1460          // undo all changes which aren't lead to a solution 
1461          for (std::list
<std::pair
<pkgCache::VerIterator
, pkgCache::VerIterator
> >::const_iterator c 
= ++newChanged
; 
1462               c 
!= Changed
.end(); ++c
) 
1463             SetCandidateVersion(c
->first
); 
1464          Changed
.erase(newChanged
, Changed
.end()); 
1471 // DepCache::MarkAuto - set the Auto flag for a package                 /*{{{*/ 
1472 // --------------------------------------------------------------------- 
1474 void pkgDepCache::MarkAuto(const PkgIterator 
&Pkg
, bool Auto
) 
1476   StateCache 
&state 
= PkgState
[Pkg
->ID
]; 
1478   ActionGroup 
group(*this); 
1481     state
.Flags 
|= Flag::Auto
; 
1483     state
.Flags 
&= ~Flag::Auto
; 
1486 // StateCache::Update - Compute the various static display things       /*{{{*/ 
1487 // --------------------------------------------------------------------- 
1488 /* This is called whenever the Candidate version changes. */ 
1489 void pkgDepCache::StateCache::Update(PkgIterator Pkg
,pkgCache 
&Cache
) 
1492    VerIterator Ver 
= CandidateVerIter(Cache
); 
1494    // Use a null string or the version string 
1495    if (Ver
.end() == true) 
1498       CandVersion 
= Ver
.VerStr(); 
1500    // Find the current version 
1502    if (Pkg
->CurrentVer 
!= 0) 
1503       CurVersion 
= Pkg
.CurrentVer().VerStr(); 
1505    // Strip off the epochs for display 
1506    CurVersion 
= StripEpoch(CurVersion
); 
1507    CandVersion 
= StripEpoch(CandVersion
); 
1509    // Figure out if its up or down or equal 
1510    Status 
= Ver
.CompareVer(Pkg
.CurrentVer()); 
1511    if (Pkg
->CurrentVer 
== 0 || Pkg
->VersionList 
== 0 || CandidateVer 
== 0) 
1515 // StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/ 
1516 // --------------------------------------------------------------------- 
1518 const char *pkgDepCache::StateCache::StripEpoch(const char *Ver
) 
1524    for (const char *I 
= Ver
; *I 
!= 0; I
++) 
1530 // Policy::GetCandidateVer - Returns the Candidate install version      /*{{{*/ 
1531 // --------------------------------------------------------------------- 
1532 /* The default just returns the highest available version that is not 
1533    a source and automatic. */ 
1534 pkgCache::VerIterator 
pkgDepCache::Policy::GetCandidateVer(PkgIterator 
const &Pkg
) 
1536    /* Not source/not automatic versions cannot be a candidate version  
1537       unless they are already installed */ 
1538    VerIterator 
Last(*(pkgCache 
*)this,0); 
1540    for (VerIterator I 
= Pkg
.VersionList(); I
.end() == false; ++I
) 
1542       if (Pkg
.CurrentVer() == I
) 
1545       for (VerFileIterator J 
= I
.FileList(); J
.end() == false; ++J
) 
1547          if ((J
.File()->Flags 
& Flag::NotSource
) != 0) 
1550          /* Stash the highest version of a not-automatic source, we use it 
1551             if there is nothing better */ 
1552          if ((J
.File()->Flags 
& Flag::NotAutomatic
) != 0 || 
1553              (J
.File()->Flags 
& Flag::ButAutomaticUpgrades
) != 0) 
1555             if (Last
.end() == true) 
1567 // Policy::IsImportantDep - True if the dependency is important         /*{{{*/ 
1568 // --------------------------------------------------------------------- 
1570 bool pkgDepCache::Policy::IsImportantDep(DepIterator 
const &Dep
) 
1572    if(Dep
.IsCritical()) 
1574    else if(Dep
->Type 
== pkgCache::Dep::Recommends
)  
1576       if (InstallRecommends
) 
1578       // we suport a special mode to only install-recommends for certain 
1580       // FIXME: this is a meant as a temporarly solution until the  
1581       //        recommends are cleaned up 
1582       const char *sec 
= Dep
.ParentVer().Section(); 
1583       if (sec 
&& ConfigValueInSubTree("APT::Install-Recommends-Sections", sec
)) 
1586    else if(Dep
->Type 
== pkgCache::Dep::Suggests
) 
1587       return InstallSuggests
; 
1592 // Policy::GetPriority - Get the priority of the package pin            /*{{{*/ 
1593 signed short pkgDepCache::Policy::GetPriority(pkgCache::PkgIterator 
const &Pkg
) 
1595 signed short pkgDepCache::Policy::GetPriority(pkgCache::PkgFileIterator 
const &File
) 
1598 pkgDepCache::InRootSetFunc 
*pkgDepCache::GetRootSetFunc()               /*{{{*/ 
1600   DefaultRootSetFunc 
*f 
= new DefaultRootSetFunc
; 
1601   if(f
->wasConstructedSuccessfully()) 
1610 bool pkgDepCache::MarkFollowsRecommends() 
1612   return _config
->FindB("APT::AutoRemove::RecommendsImportant", true); 
1615 bool pkgDepCache::MarkFollowsSuggests() 
1617   return _config
->FindB("APT::AutoRemove::SuggestsImportant", true); 
1620 // pkgDepCache::MarkRequired - the main mark algorithm                  /*{{{*/ 
1621 bool pkgDepCache::MarkRequired(InRootSetFunc 
&userFunc
) 
1623    if (_config
->Find("APT::Solver", "internal") != "internal") 
1626    bool follow_recommends
; 
1627    bool follow_suggests
; 
1628    bool debug_autoremove 
= _config
->FindB("Debug::pkgAutoRemove",false); 
1631    for(PkgIterator p 
= PkgBegin(); !p
.end(); ++p
) 
1633       PkgState
[p
->ID
].Marked  
= false; 
1634       PkgState
[p
->ID
].Garbage 
= false; 
1637       if(debug_autoremove 
&& PkgState
[p
->ID
].Flags 
& Flag::Auto
) 
1638          std::clog 
<< "AutoDep: " << p
.FullName() << std::endl
; 
1642    follow_recommends 
= MarkFollowsRecommends(); 
1643    follow_suggests   
= MarkFollowsSuggests(); 
1647    // do the mark part, this is the core bit of the algorithm 
1648    for(PkgIterator p 
= PkgBegin(); !p
.end(); ++p
) 
1650       if(!(PkgState
[p
->ID
].Flags 
& Flag::Auto
) || 
1651           (p
->Flags 
& Flag::Essential
) || 
1652           (p
->Flags 
& Flag::Important
) || 
1653           userFunc
.InRootSet(p
) || 
1654           // be nice even then a required package violates the policy (#583517) 
1655           // and do the full mark process also for required packages 
1656           (p
.CurrentVer().end() != true && 
1657            p
.CurrentVer()->Priority 
== pkgCache::State::Required
)) 
1659          // the package is installed (and set to keep) 
1660          if(PkgState
[p
->ID
].Keep() && !p
.CurrentVer().end()) 
1661             MarkPackage(p
, p
.CurrentVer(), 
1662                         follow_recommends
, follow_suggests
); 
1663          // the package is to be installed  
1664          else if(PkgState
[p
->ID
].Install()) 
1665             MarkPackage(p
, PkgState
[p
->ID
].InstVerIter(*this), 
1666                         follow_recommends
, follow_suggests
); 
1673 // MarkPackage - mark a single package in Mark-and-Sweep                /*{{{*/ 
1674 void pkgDepCache::MarkPackage(const pkgCache::PkgIterator 
&pkg
, 
1675                               const pkgCache::VerIterator 
&ver
, 
1676                               bool const &follow_recommends
, 
1677                               bool const &follow_suggests
) 
1679    pkgDepCache::StateCache 
&state 
= PkgState
[pkg
->ID
]; 
1681    // if we are marked already we are done 
1685    VerIterator 
const currver 
= pkg
.CurrentVer(); 
1686    VerIterator 
const instver 
= state
.InstVerIter(*this); 
1689    VerIterator 
const candver 
= state
.CandidateVerIter(*this); 
1691    // If a package was garbage-collected but is now being marked, we 
1692    // should re-select it  
1693    // For cases when a pkg is set to upgrade and this trigger the 
1694    // removal of a no-longer used dependency.  if the pkg is set to 
1695    // keep again later it will result in broken deps 
1696    if(state
.Delete() && state
.RemoveReason 
= Unused
)  
1699          mark_install(pkg
, false, false, NULL
); 
1700       else if(ver
==pkg
.CurrentVer()) 
1701          MarkKeep(pkg
, false, false); 
1703       instver
=state
.InstVerIter(*this); 
1707    // For packages that are not going to be removed, ignore versions 
1708    // other than the InstVer.  For packages that are going to be 
1709    // removed, ignore versions other than the current version. 
1710    if(!(ver 
== instver 
&& !instver
.end()) && 
1711       !(ver 
== currver 
&& instver
.end() && !ver
.end())) 
1714    bool const debug_autoremove 
= _config
->FindB("Debug::pkgAutoRemove", false); 
1716    if(debug_autoremove
) 
1718        std::clog 
<< "Marking: " << pkg
.FullName(); 
1720          std::clog 
<< " " << ver
.VerStr(); 
1722          std::clog 
<< ", Curr=" << currver
.VerStr(); 
1724          std::clog 
<< ", Inst=" << instver
.VerStr(); 
1725        std::clog 
<< std::endl
; 
1730    if(ver
.end() == true) 
1733      for(DepIterator d 
= ver
.DependsList(); !d
.end(); ++d
) 
1735         if(d
->Type 
== Dep::Depends 
|| 
1736            d
->Type 
== Dep::PreDepends 
|| 
1737            (follow_recommends 
&& 
1738             d
->Type 
== Dep::Recommends
) || 
1740             d
->Type 
== Dep::Suggests
)) 
1742            // Try all versions of this package. 
1743            for(VerIterator V 
= d
.TargetPkg().VersionList();  
1746               if(_system
->VS
->CheckDep(V
.VerStr(), d
->CompareOp
, d
.TargetVer())) 
1748                 if(debug_autoremove
) 
1750                     std::clog 
<< "Following dep: " << d
.ParentPkg().FullName() 
1751                               << " " << d
.ParentVer().VerStr() << " " 
1752                               << d
.DepType() << " " << d
.TargetPkg().FullName(); 
1753                     if((d
->CompareOp 
& ~pkgCache::Dep::Or
) != pkgCache::Dep::NoOp
) 
1755                         std::clog 
<< " (" << d
.CompType() << " " 
1756                                   << d
.TargetVer() << ")"; 
1758                     std::clog 
<< std::endl
; 
1760                  MarkPackage(V
.ParentPkg(), V
, 
1761                              follow_recommends
, follow_suggests
); 
1764            // Now try virtual packages 
1765            for(PrvIterator prv
=d
.TargetPkg().ProvidesList();  
1768               if(_system
->VS
->CheckDep(prv
.ProvideVersion(), d
->CompareOp
,  
1771                 if(debug_autoremove
) 
1773                     std::clog 
<< "Following dep: " << d
.ParentPkg().FullName() << " " 
1774                               << d
.ParentVer().VerStr() << " " 
1775                               << d
.DepType() << " " << d
.TargetPkg().FullName() << " "; 
1776                     if((d
->CompareOp 
& ~pkgCache::Dep::Or
) != pkgCache::Dep::NoOp
) 
1778                         std::clog 
<< " (" << d
.CompType() << " " 
1779                                   << d
.TargetVer() << ")"; 
1781                     std::clog 
<< ", provided by " 
1782                               << prv
.OwnerPkg().FullName() << " " 
1783                               << prv
.OwnerVer().VerStr() 
1787                  MarkPackage(prv
.OwnerPkg(), prv
.OwnerVer(), 
1788                              follow_recommends
, follow_suggests
); 
1795 bool pkgDepCache::Sweep()                                               /*{{{*/ 
1797    bool debug_autoremove 
= _config
->FindB("Debug::pkgAutoRemove",false); 
1800    for(PkgIterator p
=PkgBegin(); !p
.end(); ++p
) 
1802      StateCache 
&state
=PkgState
[p
->ID
]; 
1804      // skip required packages 
1805      if (!p
.CurrentVer().end() &&  
1806          (p
.CurrentVer()->Priority 
== pkgCache::State::Required
)) 
1809      // if it is not marked and it is installed, it's garbage  
1810      if(!state
.Marked 
&& (!p
.CurrentVer().end() || state
.Install())) 
1813         if(debug_autoremove
) 
1814            std::clog 
<< "Garbage: " << p
.FullName() << std::endl
;