]> git.saurik.com Git - apt.git/blame - apt-pkg/upgrade.cc
tests: don't do boundless string compares with data()
[apt.git] / apt-pkg / upgrade.cc
CommitLineData
82e369c4
MV
1// Include Files /*{{{*/
2#include <config.h>
3
4#include <apt-pkg/algorithms.h>
82e369c4 5#include <apt-pkg/configuration.h>
82e369c4 6#include <apt-pkg/edsp.h>
453b82a3 7#include <apt-pkg/error.h>
82e369c4 8#include <apt-pkg/progress.h>
453b82a3
DK
9#include <apt-pkg/upgrade.h>
10#include <apt-pkg/depcache.h>
11#include <apt-pkg/pkgcache.h>
12#include <apt-pkg/cacheiterators.h>
82e369c4 13
453b82a3 14#include <string>
82e369c4
MV
15
16#include <apti18n.h>
17 /*}}}*/
18
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.
24
25 The problem resolver is used to resolve the problems.
26 */
fa5404ab 27static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
82e369c4
MV
28{
29 std::string const solver = _config->Find("APT::Solver", "internal");
3a487cc0 30 auto const ret = EDSP::ResolveExternal(solver.c_str(), Cache, EDSP::Request::UPGRADE_ALL, Progress);
2a884c61 31 if (solver != "internal")
3a487cc0 32 return ret;
2a884c61
DK
33
34 if (Progress != NULL)
35 Progress->OverallProgress(0, 100, 1, _("Calculating upgrade"));
82e369c4
MV
36
37 pkgDepCache::ActionGroup group(Cache);
38
39 /* Upgrade all installed packages first without autoinst to help the resolver
40 in versioned or-groups to upgrade the old solver instead of installing
41 a new one (if the old solver is not the first one [anymore]) */
42 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
43 if (I->CurrentVer != 0)
44 Cache.MarkInstall(I, false, 0, false);
45
2a884c61
DK
46 if (Progress != NULL)
47 Progress->Progress(10);
48
82e369c4
MV
49 /* Auto upgrade all installed packages, this provides the basis
50 for the installation */
51 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
52 if (I->CurrentVer != 0)
53 Cache.MarkInstall(I, true, 0, false);
54
2a884c61
DK
55 if (Progress != NULL)
56 Progress->Progress(50);
57
82e369c4
MV
58 /* Now, install each essential package which is not installed
59 (and not provided by another package in the same name group) */
60 std::string essential = _config->Find("pkgCacheGen::Essential", "all");
61 if (essential == "all")
62 {
63 for (pkgCache::GrpIterator G = Cache.GrpBegin(); G.end() == false; ++G)
64 {
65 bool isEssential = false;
66 bool instEssential = false;
67 for (pkgCache::PkgIterator P = G.PackageList(); P.end() == false; P = G.NextPkg(P))
68 {
69 if ((P->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential)
70 continue;
71 isEssential = true;
72 if (Cache[P].Install() == true)
73 {
74 instEssential = true;
75 break;
76 }
77 }
78 if (isEssential == false || instEssential == true)
79 continue;
80 pkgCache::PkgIterator P = G.FindPreferredPkg();
81 Cache.MarkInstall(P, true, 0, false);
82 }
83 }
84 else if (essential != "none")
85 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
86 if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
87 Cache.MarkInstall(I, true, 0, false);
2a884c61
DK
88
89 if (Progress != NULL)
90 Progress->Progress(55);
91
82e369c4
MV
92 /* We do it again over all previously installed packages to force
93 conflict resolution on them all. */
94 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
95 if (I->CurrentVer != 0)
96 Cache.MarkInstall(I, false, 0, false);
97
2a884c61
DK
98 if (Progress != NULL)
99 Progress->Progress(65);
100
82e369c4
MV
101 pkgProblemResolver Fix(&Cache);
102
2a884c61
DK
103 if (Progress != NULL)
104 Progress->Progress(95);
105
82e369c4
MV
106 // Hold back held packages.
107 if (_config->FindB("APT::Ignore-Hold",false) == false)
108 {
109 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
110 {
111 if (I->SelectedState == pkgCache::State::Hold)
112 {
113 Fix.Protect(I);
114 Cache.MarkKeep(I, false, false);
115 }
116 }
117 }
2a884c61 118
4dc619c0 119 bool const success = Fix.ResolveInternal(false);
2a884c61
DK
120 if (Progress != NULL)
121 Progress->Done();
122 return success;
fa5404ab
DK
123}
124bool pkgDistUpgrade(pkgDepCache &Cache)
125{
126 return pkgDistUpgrade(Cache, NULL);
82e369c4
MV
127}
128 /*}}}*/
129// AllUpgradeNoNewPackages - Upgrade but no removals or new pkgs /*{{{*/
2a884c61 130static bool pkgAllUpgradeNoNewPackages(pkgDepCache &Cache, OpProgress * const Progress)
82e369c4
MV
131{
132 std::string const solver = _config->Find("APT::Solver", "internal");
3a487cc0
DK
133 constexpr auto flags = EDSP::Request::UPGRADE_ALL | EDSP::Request::FORBID_NEW_INSTALL | EDSP::Request::FORBID_REMOVE;
134 auto const ret = EDSP::ResolveExternal(solver.c_str(), Cache, flags, Progress);
2a884c61 135 if (solver != "internal")
3a487cc0 136 return ret;
2a884c61
DK
137
138 if (Progress != NULL)
139 Progress->OverallProgress(0, 100, 1, _("Calculating upgrade"));
82e369c4
MV
140
141 pkgDepCache::ActionGroup group(Cache);
82e369c4
MV
142 pkgProblemResolver Fix(&Cache);
143
82e369c4
MV
144 // Upgrade all installed packages
145 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
146 {
147 if (Cache[I].Install() == true)
148 Fix.Protect(I);
149
150 if (_config->FindB("APT::Ignore-Hold",false) == false)
151 if (I->SelectedState == pkgCache::State::Hold)
152 continue;
153
154 if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
155 Cache.MarkInstall(I, false, 0, false);
156 }
2a884c61
DK
157
158 if (Progress != NULL)
159 Progress->Progress(50);
160
161 // resolve remaining issues via keep
4dc619c0 162 bool const success = Fix.ResolveByKeepInternal();
2a884c61
DK
163 if (Progress != NULL)
164 Progress->Done();
165 return success;
82e369c4
MV
166}
167 /*}}}*/
168// AllUpgradeWithNewInstalls - Upgrade + install new packages as needed /*{{{*/
169// ---------------------------------------------------------------------
170/* Right now the system must be consistent before this can be called.
171 * Upgrade as much as possible without deleting anything (useful for
172 * stable systems)
173 */
2a884c61 174static bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache, OpProgress * const Progress)
82e369c4 175{
172947cd 176 std::string const solver = _config->Find("APT::Solver", "internal");
3a487cc0
DK
177 constexpr auto flags = EDSP::Request::UPGRADE_ALL | EDSP::Request::FORBID_REMOVE;
178 auto const ret = EDSP::ResolveExternal(solver.c_str(), Cache, flags, Progress);
2a884c61 179 if (solver != "internal")
3a487cc0 180 return ret;
2a884c61
DK
181
182 if (Progress != NULL)
183 Progress->OverallProgress(0, 100, 1, _("Calculating upgrade"));
172947cd 184
82e369c4 185 pkgDepCache::ActionGroup group(Cache);
82e369c4
MV
186 pkgProblemResolver Fix(&Cache);
187
82e369c4
MV
188 // provide the initial set of stuff we want to upgrade by marking
189 // all upgradable packages for upgrade
190 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
191 {
192 if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
193 {
194 if (_config->FindB("APT::Ignore-Hold",false) == false)
195 if (I->SelectedState == pkgCache::State::Hold)
196 continue;
197
198 Cache.MarkInstall(I, false, 0, false);
199 }
200 }
201
2a884c61
DK
202 if (Progress != NULL)
203 Progress->Progress(10);
204
82e369c4
MV
205 // then let auto-install loose
206 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
207 if (Cache[I].Install())
208 Cache.MarkInstall(I, true, 0, false);
209
2a884c61
DK
210 if (Progress != NULL)
211 Progress->Progress(50);
212
82e369c4
MV
213 // ... but it may remove stuff, we we need to clean up afterwards again
214 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
215 if (Cache[I].Delete() == true)
216 Cache.MarkKeep(I, false, false);
217
2a884c61
DK
218 if (Progress != NULL)
219 Progress->Progress(60);
220
82e369c4 221 // resolve remaining issues via keep
4dc619c0 222 bool const success = Fix.ResolveByKeepInternal();
2a884c61
DK
223 if (Progress != NULL)
224 Progress->Done();
225 return success;
82e369c4
MV
226}
227 /*}}}*/
228// AllUpgrade - Upgrade as many packages as possible /*{{{*/
229// ---------------------------------------------------------------------
230/* Right now the system must be consistent before this can be called.
231 It also will not change packages marked for install, it only tries
232 to install packages not marked for install */
fa5404ab 233static bool pkgAllUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
82e369c4 234{
2a884c61 235 return pkgAllUpgradeNoNewPackages(Cache, Progress);
fa5404ab
DK
236}
237bool pkgAllUpgrade(pkgDepCache &Cache)
238{
239 return pkgAllUpgrade(Cache, NULL);
82e369c4
MV
240}
241 /*}}}*/
242// MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
243// ---------------------------------------------------------------------
244/* This simply goes over the entire set of packages and tries to keep
245 each package marked for upgrade. If a conflict is generated then
246 the package is restored. */
247bool pkgMinimizeUpgrade(pkgDepCache &Cache)
248{
249 pkgDepCache::ActionGroup group(Cache);
250
251 if (Cache.BrokenCount() != 0)
252 return false;
253
254 // We loop for 10 tries to get the minimal set size.
255 bool Change = false;
256 unsigned int Count = 0;
257 do
258 {
259 Change = false;
260 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
261 {
262 // Not interesting
263 if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
264 continue;
265
266 // Keep it and see if that is OK
267 Cache.MarkKeep(I, false, false);
268 if (Cache.BrokenCount() != 0)
269 Cache.MarkInstall(I, false, 0, false);
270 else
271 {
1e3f4083 272 // If keep didn't actually do anything then there was no change..
82e369c4
MV
273 if (Cache[I].Upgrade() == false)
274 Change = true;
275 }
276 }
277 ++Count;
278 }
279 while (Change == true && Count < 10);
280
281 if (Cache.BrokenCount() != 0)
282 return _error->Error("Internal Error in pkgMinimizeUpgrade");
283
284 return true;
285}
286 /*}}}*/
2a884c61
DK
287// APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/
288bool APT::Upgrade::Upgrade(pkgDepCache &Cache, int mode, OpProgress * const Progress)
82e369c4 289{
586d8704 290APT_IGNORE_DEPRECATED_PUSH
67caa2e6 291 if (mode == ALLOW_EVERYTHING)
2a884c61 292 return pkgDistUpgrade(Cache, Progress);
82e369c4 293 else if ((mode & ~FORBID_REMOVE_PACKAGES) == 0)
2a884c61 294 return pkgAllUpgradeWithNewPackages(Cache, Progress);
3f506f68 295 else if ((mode & ~(FORBID_REMOVE_PACKAGES|FORBID_INSTALL_NEW_PACKAGES)) == 0)
2a884c61 296 return pkgAllUpgradeNoNewPackages(Cache, Progress);
82e369c4
MV
297 else
298 _error->Error("pkgAllUpgrade called with unsupported mode %i", mode);
586d8704 299APT_IGNORE_DEPRECATED_POP
82e369c4
MV
300 return false;
301}
302 /*}}}*/