1 // Include Files                                                        /*{{{*/ 
   4 #include <apt-pkg/algorithms.h> 
   5 #include <apt-pkg/configuration.h> 
   6 #include <apt-pkg/edsp.h> 
   7 #include <apt-pkg/error.h> 
   8 #include <apt-pkg/progress.h> 
   9 #include <apt-pkg/upgrade.h> 
  10 #include <apt-pkg/depcache.h> 
  11 #include <apt-pkg/pkgcache.h> 
  12 #include <apt-pkg/cacheiterators.h> 
  19 // DistUpgrade - Distribution upgrade                                   /*{{{*/ 
  20 // --------------------------------------------------------------------- 
  21 /* This autoinstalls every package and then force installs every  
  22    pre-existing package. This creates the initial set of conditions which  
  23    most likely contain problems because too many things were installed. 
  25    The problem resolver is used to resolve the problems. 
  27 static bool pkgDistUpgrade(pkgDepCache 
&Cache
, OpProgress 
* const Progress
) 
  29    std::string 
const solver 
= _config
->Find("APT::Solver", "internal"); 
  30    if (solver 
!= "internal") 
  31       return EDSP::ResolveExternal(solver
.c_str(), Cache
, false, true, false, Progress
); 
  34       Progress
->OverallProgress(0, 100, 1, _("Calculating upgrade")); 
  36    pkgDepCache::ActionGroup 
group(Cache
); 
  38    /* Upgrade all installed packages first without autoinst to help the resolver 
  39       in versioned or-groups to upgrade the old solver instead of installing 
  40       a new one (if the old solver is not the first one [anymore]) */ 
  41    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; ++I
) 
  42       if (I
->CurrentVer 
!= 0) 
  43          Cache
.MarkInstall(I
, false, 0, false); 
  46       Progress
->Progress(10); 
  48    /* Auto upgrade all installed packages, this provides the basis  
  49       for the installation */ 
  50    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; ++I
) 
  51       if (I
->CurrentVer 
!= 0) 
  52          Cache
.MarkInstall(I
, true, 0, false); 
  55       Progress
->Progress(50); 
  57    /* Now, install each essential package which is not installed 
  58       (and not provided by another package in the same name group) */ 
  59    std::string essential 
= _config
->Find("pkgCacheGen::Essential", "all"); 
  60    if (essential 
== "all") 
  62       for (pkgCache::GrpIterator G 
= Cache
.GrpBegin(); G
.end() == false; ++G
) 
  64          bool isEssential 
= false; 
  65          bool instEssential 
= false; 
  66          for (pkgCache::PkgIterator P 
= G
.PackageList(); P
.end() == false; P 
= G
.NextPkg(P
)) 
  68             if ((P
->Flags 
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
) 
  71             if (Cache
[P
].Install() == true) 
  77          if (isEssential 
== false || instEssential 
== true) 
  79          pkgCache::PkgIterator P 
= G
.FindPreferredPkg(); 
  80          Cache
.MarkInstall(P
, true, 0, false); 
  83    else if (essential 
!= "none") 
  84       for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; ++I
) 
  85          if ((I
->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
) 
  86             Cache
.MarkInstall(I
, true, 0, false); 
  89       Progress
->Progress(55); 
  91    /* We do it again over all previously installed packages to force  
  92       conflict resolution on them all. */ 
  93    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; ++I
) 
  94       if (I
->CurrentVer 
!= 0) 
  95          Cache
.MarkInstall(I
, false, 0, false); 
  98       Progress
->Progress(65); 
 100    pkgProblemResolver 
Fix(&Cache
); 
 102    if (Progress 
!= NULL
) 
 103       Progress
->Progress(95); 
 105    // Hold back held packages. 
 106    if (_config
->FindB("APT::Ignore-Hold",false) == false) 
 108       for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; ++I
) 
 110          if (I
->SelectedState 
== pkgCache::State::Hold
) 
 113             Cache
.MarkKeep(I
, false, false); 
 118    bool const success 
= Fix
.Resolve(false, Progress
); 
 119    if (Progress 
!= NULL
) 
 123 bool pkgDistUpgrade(pkgDepCache 
&Cache
) 
 125    return pkgDistUpgrade(Cache
, NULL
); 
 128 // AllUpgradeNoNewPackages - Upgrade but no removals or new pkgs        /*{{{*/ 
 129 static bool pkgAllUpgradeNoNewPackages(pkgDepCache 
&Cache
, OpProgress 
* const Progress
) 
 131    std::string 
const solver 
= _config
->Find("APT::Solver", "internal"); 
 132    if (solver 
!= "internal") 
 133       return EDSP::ResolveExternal(solver
.c_str(), Cache
, true, false, false, Progress
); 
 135    if (Progress 
!= NULL
) 
 136       Progress
->OverallProgress(0, 100, 1, _("Calculating upgrade")); 
 138    pkgDepCache::ActionGroup 
group(Cache
); 
 140    pkgProblemResolver 
Fix(&Cache
); 
 142    if (Cache
.BrokenCount() != 0) 
 145    // Upgrade all installed packages 
 146    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; ++I
) 
 148       if (Cache
[I
].Install() == true) 
 151       if (_config
->FindB("APT::Ignore-Hold",false) == false) 
 152          if (I
->SelectedState 
== pkgCache::State::Hold
) 
 155       if (I
->CurrentVer 
!= 0 && Cache
[I
].InstallVer 
!= 0) 
 156          Cache
.MarkInstall(I
, false, 0, false); 
 159    if (Progress 
!= NULL
) 
 160       Progress
->Progress(50); 
 162    // resolve remaining issues via keep 
 163    bool const success 
= Fix
.ResolveByKeep(Progress
); 
 164    if (Progress 
!= NULL
) 
 169 // AllUpgradeWithNewInstalls - Upgrade + install new packages as needed /*{{{*/ 
 170 // --------------------------------------------------------------------- 
 171 /* Right now the system must be consistent before this can be called. 
 172  * Upgrade as much as possible without deleting anything (useful for 
 175 static bool pkgAllUpgradeWithNewPackages(pkgDepCache 
&Cache
, OpProgress 
* const Progress
) 
 177    std::string 
const solver 
= _config
->Find("APT::Solver", "internal"); 
 178    if (solver 
!= "internal") 
 179       return EDSP::ResolveExternal(solver
.c_str(), Cache
, true, false, false, Progress
); 
 181    if (Progress 
!= NULL
) 
 182       Progress
->OverallProgress(0, 100, 1, _("Calculating upgrade")); 
 184    pkgDepCache::ActionGroup 
group(Cache
); 
 186    pkgProblemResolver 
Fix(&Cache
); 
 188    if (Cache
.BrokenCount() != 0) 
 191    // provide the initial set of stuff we want to upgrade by marking 
 192    // all upgradable packages for upgrade 
 193    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; ++I
) 
 195       if (I
->CurrentVer 
!= 0 && Cache
[I
].InstallVer 
!= 0) 
 197          if (_config
->FindB("APT::Ignore-Hold",false) == false) 
 198             if (I
->SelectedState 
== pkgCache::State::Hold
) 
 201          Cache
.MarkInstall(I
, false, 0, false); 
 205    if (Progress 
!= NULL
) 
 206       Progress
->Progress(10); 
 208    // then let auto-install loose 
 209    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; ++I
) 
 210       if (Cache
[I
].Install()) 
 211          Cache
.MarkInstall(I
, true, 0, false); 
 213    if (Progress 
!= NULL
) 
 214       Progress
->Progress(50); 
 216    // ... but it may remove stuff, we we need to clean up afterwards again 
 217    for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; ++I
) 
 218       if (Cache
[I
].Delete() == true) 
 219          Cache
.MarkKeep(I
, false, false); 
 221    if (Progress 
!= NULL
) 
 222       Progress
->Progress(60); 
 224    // resolve remaining issues via keep 
 225    bool const success 
= Fix
.ResolveByKeep(Progress
); 
 226    if (Progress 
!= NULL
) 
 231 // AllUpgrade - Upgrade as many packages as possible                    /*{{{*/ 
 232 // --------------------------------------------------------------------- 
 233 /* Right now the system must be consistent before this can be called. 
 234    It also will not change packages marked for install, it only tries 
 235    to install packages not marked for install */ 
 236 static bool pkgAllUpgrade(pkgDepCache 
&Cache
, OpProgress 
* const Progress
) 
 238    return pkgAllUpgradeNoNewPackages(Cache
, Progress
); 
 240 bool pkgAllUpgrade(pkgDepCache 
&Cache
) 
 242    return pkgAllUpgrade(Cache
, NULL
); 
 245 // MinimizeUpgrade - Minimizes the set of packages to be upgraded       /*{{{*/ 
 246 // --------------------------------------------------------------------- 
 247 /* This simply goes over the entire set of packages and tries to keep  
 248    each package marked for upgrade. If a conflict is generated then  
 249    the package is restored. */ 
 250 bool pkgMinimizeUpgrade(pkgDepCache 
&Cache
) 
 252    pkgDepCache::ActionGroup 
group(Cache
); 
 254    if (Cache
.BrokenCount() != 0) 
 257    // We loop for 10 tries to get the minimal set size. 
 259    unsigned int Count 
= 0; 
 263       for (pkgCache::PkgIterator I 
= Cache
.PkgBegin(); I
.end() == false; ++I
) 
 266          if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true) 
 269          // Keep it and see if that is OK 
 270          Cache
.MarkKeep(I
, false, false); 
 271          if (Cache
.BrokenCount() != 0) 
 272             Cache
.MarkInstall(I
, false, 0, false); 
 275             // If keep didn't actually do anything then there was no change.. 
 276             if (Cache
[I
].Upgrade() == false) 
 282    while (Change 
== true && Count 
< 10); 
 284    if (Cache
.BrokenCount() != 0) 
 285       return _error
->Error("Internal Error in pkgMinimizeUpgrade"); 
 290 // APT::Upgrade::Upgrade - Upgrade using a specific strategy            /*{{{*/ 
 291 bool APT::Upgrade::Upgrade(pkgDepCache 
&Cache
, int mode
, OpProgress 
* const Progress
) 
 293 APT_IGNORE_DEPRECATED_PUSH
 
 294    if (mode 
== ALLOW_EVERYTHING
) 
 295       return pkgDistUpgrade(Cache
, Progress
); 
 296    else if ((mode 
& ~FORBID_REMOVE_PACKAGES
) == 0) 
 297       return pkgAllUpgradeWithNewPackages(Cache
, Progress
); 
 298    else if ((mode 
& ~(FORBID_REMOVE_PACKAGES
|FORBID_INSTALL_NEW_PACKAGES
)) == 0) 
 299       return pkgAllUpgradeNoNewPackages(Cache
, Progress
); 
 301       _error
->Error("pkgAllUpgrade called with unsupported mode %i", mode
); 
 302 APT_IGNORE_DEPRECATED_POP