2 // Include Files /*{{{*/
5 #include <apt-pkg/algorithms.h>
6 #include <apt-pkg/upgrade.h>
7 #include <apt-pkg/error.h>
8 #include <apt-pkg/configuration.h>
9 #include <apt-pkg/version.h>
10 #include <apt-pkg/sptr.h>
11 #include <apt-pkg/acquire-item.h>
12 #include <apt-pkg/edsp.h>
13 #include <apt-pkg/sourcelist.h>
14 #include <apt-pkg/fileutl.h>
15 #include <apt-pkg/progress.h>
17 #include <sys/types.h>
26 // DistUpgrade - Distribution upgrade /*{{{*/
27 // ---------------------------------------------------------------------
28 /* This autoinstalls every package and then force installs every
29 pre-existing package. This creates the initial set of conditions which
30 most likely contain problems because too many things were installed.
32 The problem resolver is used to resolve the problems.
34 bool pkgDistUpgrade(pkgDepCache
&Cache
)
36 std::string
const solver
= _config
->Find("APT::Solver", "internal");
37 if (solver
!= "internal") {
38 OpTextProgress
Prog(*_config
);
39 return EDSP::ResolveExternal(solver
.c_str(), Cache
, false, true, false, &Prog
);
42 pkgDepCache::ActionGroup
group(Cache
);
44 /* Upgrade all installed packages first without autoinst to help the resolver
45 in versioned or-groups to upgrade the old solver instead of installing
46 a new one (if the old solver is not the first one [anymore]) */
47 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
48 if (I
->CurrentVer
!= 0)
49 Cache
.MarkInstall(I
, false, 0, false);
51 /* Auto upgrade all installed packages, this provides the basis
52 for the installation */
53 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
54 if (I
->CurrentVer
!= 0)
55 Cache
.MarkInstall(I
, true, 0, false);
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);
88 /* We do it again over all previously installed packages to force
89 conflict resolution on them all. */
90 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
91 if (I
->CurrentVer
!= 0)
92 Cache
.MarkInstall(I
, false, 0, false);
94 pkgProblemResolver
Fix(&Cache
);
96 // Hold back held packages.
97 if (_config
->FindB("APT::Ignore-Hold",false) == false)
99 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
101 if (I
->SelectedState
== pkgCache::State::Hold
)
104 Cache
.MarkKeep(I
, false, false);
109 return Fix
.Resolve();
112 // AllUpgradeNoNewPackages - Upgrade but no removals or new pkgs /*{{{*/
113 static bool pkgAllUpgradeNoNewPackages(pkgDepCache
&Cache
)
115 std::string
const solver
= _config
->Find("APT::Solver", "internal");
116 if (solver
!= "internal") {
117 OpTextProgress
Prog(*_config
);
118 return EDSP::ResolveExternal(solver
.c_str(), Cache
, true, false, false, &Prog
);
121 pkgDepCache::ActionGroup
group(Cache
);
123 pkgProblemResolver
Fix(&Cache
);
125 if (Cache
.BrokenCount() != 0)
128 // Upgrade all installed packages
129 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
131 if (Cache
[I
].Install() == true)
134 if (_config
->FindB("APT::Ignore-Hold",false) == false)
135 if (I
->SelectedState
== pkgCache::State::Hold
)
138 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
139 Cache
.MarkInstall(I
, false, 0, false);
142 return Fix
.ResolveByKeep();
145 // AllUpgradeWithNewInstalls - Upgrade + install new packages as needed /*{{{*/
146 // ---------------------------------------------------------------------
147 /* Right now the system must be consistent before this can be called.
148 * Upgrade as much as possible without deleting anything (useful for
151 static bool pkgAllUpgradeWithNewPackages(pkgDepCache
&Cache
)
153 pkgDepCache::ActionGroup
group(Cache
);
155 pkgProblemResolver
Fix(&Cache
);
157 if (Cache
.BrokenCount() != 0)
160 // provide the initial set of stuff we want to upgrade by marking
161 // all upgradable packages for upgrade
162 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
164 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
166 if (_config
->FindB("APT::Ignore-Hold",false) == false)
167 if (I
->SelectedState
== pkgCache::State::Hold
)
170 Cache
.MarkInstall(I
, false, 0, false);
174 // then let auto-install loose
175 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
176 if (Cache
[I
].Install())
177 Cache
.MarkInstall(I
, true, 0, false);
179 // ... but it may remove stuff, we we need to clean up afterwards again
180 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
181 if (Cache
[I
].Delete() == true)
182 Cache
.MarkKeep(I
, false, false);
184 // resolve remaining issues via keep
185 return Fix
.ResolveByKeep();
188 // AllUpgrade - Upgrade as many packages as possible /*{{{*/
189 // ---------------------------------------------------------------------
190 /* Right now the system must be consistent before this can be called.
191 It also will not change packages marked for install, it only tries
192 to install packages not marked for install */
193 bool pkgAllUpgrade(pkgDepCache
&Cache
)
195 return pkgAllUpgradeNoNewPackages(Cache
);
198 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
199 // ---------------------------------------------------------------------
200 /* This simply goes over the entire set of packages and tries to keep
201 each package marked for upgrade. If a conflict is generated then
202 the package is restored. */
203 bool pkgMinimizeUpgrade(pkgDepCache
&Cache
)
205 pkgDepCache::ActionGroup
group(Cache
);
207 if (Cache
.BrokenCount() != 0)
210 // We loop for 10 tries to get the minimal set size.
212 unsigned int Count
= 0;
216 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
219 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
222 // Keep it and see if that is OK
223 Cache
.MarkKeep(I
, false, false);
224 if (Cache
.BrokenCount() != 0)
225 Cache
.MarkInstall(I
, false, 0, false);
228 // If keep didnt actually do anything then there was no change..
229 if (Cache
[I
].Upgrade() == false)
235 while (Change
== true && Count
< 10);
237 if (Cache
.BrokenCount() != 0)
238 return _error
->Error("Internal Error in pkgMinimizeUpgrade");
243 // APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/
244 bool APT::Upgrade::Upgrade(pkgDepCache
&Cache
, int mode
)
248 return pkgDistUpgrade(Cache
);
250 else if ((mode
& ~FORBID_REMOVE_PACKAGES
) == 0)
252 return pkgAllUpgradeWithNewPackages(Cache
);
254 else if ((mode
& ~(FORBID_REMOVE_PACKAGES
|FORBID_NEW_INSTALL_PACKAGES
)) == 0)
256 return pkgAllUpgradeNoNewPackages(Cache
);
259 _error
->Error("pkgAllUpgrade called with unsupported mode %i", mode
);