]> git.saurik.com Git - apt.git/blame - apt-pkg/algorithms.cc
add missing translated apt.8 manpages, thanks to Helge Kreutzmann.
[apt.git] / apt-pkg / algorithms.cc
CommitLineData
6c139d6e
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
b8c0f9b7 3// $Id: algorithms.cc,v 1.44 2002/11/28 18:49:16 jgg Exp $
6c139d6e
AL
4/* ######################################################################
5
6 Algorithms - A set of misc algorithms
7
0a8e3465
AL
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.
13
6c139d6e
AL
14 ##################################################################### */
15 /*}}}*/
16// Include Files /*{{{*/
ea542140
DK
17#include <config.h>
18
094a497d
AL
19#include <apt-pkg/algorithms.h>
20#include <apt-pkg/error.h>
0a8e3465 21#include <apt-pkg/configuration.h>
0a57c0f0 22#include <apt-pkg/version.h>
b2e465d6 23#include <apt-pkg/sptr.h>
760d4968 24#include <apt-pkg/acquire-item.h>
c3b85126 25#include <apt-pkg/edsp.h>
472ff00e
DK
26#include <apt-pkg/sourcelist.h>
27#include <apt-pkg/fileutl.h>
28#include <apt-pkg/progress.h>
6d38011b 29
22dcc318 30#include <sys/types.h>
152ab79e
MV
31#include <cstdlib>
32#include <algorithm>
90f057fd 33#include <iostream>
6d38011b 34#include <stdio.h>
ea542140
DK
35
36#include <apti18n.h>
6c139d6e 37 /*}}}*/
584e4558 38using namespace std;
6c139d6e
AL
39
40pkgProblemResolver *pkgProblemResolver::This = 0;
41
42// Simulate::Simulate - Constructor /*{{{*/
43// ---------------------------------------------------------------------
b2e465d6
AL
44/* The legacy translations here of input Pkg iterators is obsolete,
45 this is not necessary since the pkgCaches are fully shared now. */
46pkgSimulate::pkgSimulate(pkgDepCache *Cache) : pkgPackageManager(Cache),
47 iPolicy(Cache),
496d5c70
MV
48 Sim(&Cache->GetCache(),&iPolicy),
49 group(Sim)
6c139d6e 50{
b2e465d6
AL
51 Sim.Init(0);
52 Flags = new unsigned char[Cache->Head().PackageCount];
53 memset(Flags,0,sizeof(*Flags)*Cache->Head().PackageCount);
281daf46
AL
54
55 // Fake a filename so as not to activate the media swapping
56 string Jnk = "SIMULATE";
b2e465d6 57 for (unsigned int I = 0; I != Cache->Head().PackageCount; I++)
281daf46 58 FileNames[I] = Jnk;
6c139d6e
AL
59}
60 /*}}}*/
b270388b
MV
61// Simulate::~Simulate - Destructor /*{{{*/
62pkgSimulate::~pkgSimulate()
63{
64 delete[] Flags;
65}
66 /*}}}*/
b2e465d6
AL
67// Simulate::Describe - Describe a package /*{{{*/
68// ---------------------------------------------------------------------
3826564e
MZ
69/* Parameter Current == true displays the current package version,
70 Parameter Candidate == true displays the candidate package version */
71void pkgSimulate::Describe(PkgIterator Pkg,ostream &out,bool Current,bool Candidate)
b2e465d6
AL
72{
73 VerIterator Ver(Sim);
e59458f7 74
47f6d1b7 75 out << Pkg.FullName(true);
e59458f7 76
3826564e 77 if (Current == true)
e59458f7 78 {
b2e465d6 79 Ver = Pkg.CurrentVer();
e59458f7
AL
80 if (Ver.end() == false)
81 out << " [" << Ver.VerStr() << ']';
82 }
b2e465d6 83
3826564e
MZ
84 if (Candidate == true)
85 {
86 Ver = Sim[Pkg].CandidateVerIter(Sim);
87 if (Ver.end() == true)
88 return;
b2e465d6 89
3826564e
MZ
90 out << " (" << Ver.VerStr() << ' ' << Ver.RelStr() << ')';
91 }
b2e465d6
AL
92}
93 /*}}}*/
6c139d6e
AL
94// Simulate::Install - Simulate unpacking of a package /*{{{*/
95// ---------------------------------------------------------------------
96/* */
97bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/)
98{
99 // Adapt the iterator
803ea2a8 100 PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch());
6c139d6e
AL
101 Flags[Pkg->ID] = 1;
102
b2e465d6 103 cout << "Inst ";
3826564e 104 Describe(Pkg,cout,true,true);
6c139d6e 105 Sim.MarkInstall(Pkg,false);
803ea2a8 106
6c139d6e 107 // Look for broken conflicts+predepends.
f7f0d6c7 108 for (PkgIterator I = Sim.PkgBegin(); I.end() == false; ++I)
6c139d6e
AL
109 {
110 if (Sim[I].InstallVer == 0)
111 continue;
112
b2e465d6
AL
113 for (DepIterator D = Sim[I].InstVerIter(Sim).DependsList(); D.end() == false;)
114 {
115 DepIterator Start;
116 DepIterator End;
117 D.GlobOr(Start,End);
359e46db 118 if (Start.IsNegative() == true ||
b2e465d6 119 End->Type == pkgCache::Dep::PreDepends)
6c139d6e 120 {
b2e465d6 121 if ((Sim[End] & pkgDepCache::DepGInstall) == 0)
6c139d6e 122 {
47f6d1b7 123 cout << " [" << I.FullName(false) << " on " << Start.TargetPkg().FullName(false) << ']';
b2e465d6 124 if (Start->Type == pkgCache::Dep::Conflicts)
47f6d1b7 125 _error->Error("Fatal, conflicts violated %s",I.FullName(false).c_str());
6c139d6e 126 }
b2e465d6
AL
127 }
128 }
6c139d6e
AL
129 }
130
131 if (Sim.BrokenCount() != 0)
132 ShortBreaks();
133 else
04aa15a8 134 cout << endl;
6c139d6e
AL
135 return true;
136}
137 /*}}}*/
138// Simulate::Configure - Simulate configuration of a Package /*{{{*/
139// ---------------------------------------------------------------------
140/* This is not an acurate simulation of relatity, we should really not
141 install the package.. For some investigations it may be necessary
142 however. */
143bool pkgSimulate::Configure(PkgIterator iPkg)
144{
145 // Adapt the iterator
803ea2a8 146 PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch());
6c139d6e
AL
147
148 Flags[Pkg->ID] = 2;
803ea2a8 149
6c139d6e
AL
150 if (Sim[Pkg].InstBroken() == true)
151 {
47f6d1b7 152 cout << "Conf " << Pkg.FullName(false) << " broken" << endl;
6c139d6e
AL
153
154 Sim.Update();
155
156 // Print out each package and the failed dependencies
f7f0d6c7 157 for (pkgCache::DepIterator D = Sim[Pkg].InstVerIter(Sim).DependsList(); D.end() == false; ++D)
6c139d6e
AL
158 {
159 if (Sim.IsImportantDep(D) == false ||
160 (Sim[D] & pkgDepCache::DepInstall) != 0)
161 continue;
162
b2e465d6 163 if (D->Type == pkgCache::Dep::Obsoletes)
47f6d1b7 164 cout << " Obsoletes:" << D.TargetPkg().FullName(false);
b2e465d6 165 else if (D->Type == pkgCache::Dep::Conflicts)
47f6d1b7 166 cout << " Conflicts:" << D.TargetPkg().FullName(false);
308c7d30 167 else if (D->Type == pkgCache::Dep::DpkgBreaks)
47f6d1b7 168 cout << " Breaks:" << D.TargetPkg().FullName(false);
6c139d6e 169 else
47f6d1b7 170 cout << " Depends:" << D.TargetPkg().FullName(false);
6c139d6e 171 }
04aa15a8 172 cout << endl;
6c139d6e 173
09a10f9c 174 _error->Error("Conf Broken %s",Pkg.FullName(false).c_str());
6c139d6e
AL
175 }
176 else
b2e465d6
AL
177 {
178 cout << "Conf ";
3826564e 179 Describe(Pkg,cout,false,true);
b2e465d6 180 }
6c139d6e
AL
181
182 if (Sim.BrokenCount() != 0)
183 ShortBreaks();
184 else
04aa15a8 185 cout << endl;
6c139d6e
AL
186
187 return true;
188}
189 /*}}}*/
190// Simulate::Remove - Simulate the removal of a package /*{{{*/
191// ---------------------------------------------------------------------
192/* */
fc4b5c9f 193bool pkgSimulate::Remove(PkgIterator iPkg,bool Purge)
6c139d6e
AL
194{
195 // Adapt the iterator
803ea2a8 196 PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch());
c919ad6e
DK
197 if (Pkg.end() == true)
198 {
199 std::cerr << (Purge ? "Purg" : "Remv") << " invalid package " << iPkg.FullName() << std::endl;
200 return false;
201 }
6c139d6e
AL
202
203 Flags[Pkg->ID] = 3;
204 Sim.MarkDelete(Pkg);
803ea2a8 205
fc4b5c9f 206 if (Purge == true)
b2e465d6 207 cout << "Purg ";
fc4b5c9f 208 else
b2e465d6 209 cout << "Remv ";
3826564e 210 Describe(Pkg,cout,true,false);
6c139d6e
AL
211
212 if (Sim.BrokenCount() != 0)
213 ShortBreaks();
214 else
04aa15a8 215 cout << endl;
6c139d6e
AL
216
217 return true;
218}
219 /*}}}*/
220// Simulate::ShortBreaks - Print out a short line describing all breaks /*{{{*/
221// ---------------------------------------------------------------------
222/* */
223void pkgSimulate::ShortBreaks()
224{
04aa15a8 225 cout << " [";
f7f0d6c7 226 for (PkgIterator I = Sim.PkgBegin(); I.end() == false; ++I)
6c139d6e
AL
227 {
228 if (Sim[I].InstBroken() == true)
229 {
230 if (Flags[I->ID] == 0)
47f6d1b7 231 cout << I.FullName(false) << ' ';
6c139d6e 232/* else
04aa15a8 233 cout << I.Name() << "! ";*/
6c139d6e
AL
234 }
235 }
04aa15a8 236 cout << ']' << endl;
6c139d6e
AL
237}
238 /*}}}*/
239// ApplyStatus - Adjust for non-ok packages /*{{{*/
240// ---------------------------------------------------------------------
241/* We attempt to change the state of the all packages that have failed
242 installation toward their real state. The ordering code will perform
243 the necessary calculations to deal with the problems. */
244bool pkgApplyStatus(pkgDepCache &Cache)
245{
74a05226
MV
246 pkgDepCache::ActionGroup group(Cache);
247
f7f0d6c7 248 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
6c139d6e 249 {
e481d5b0
AL
250 if (I->VersionList == 0)
251 continue;
252
d38b7b3d
AL
253 // Only choice for a ReInstReq package is to reinstall
254 if (I->InstState == pkgCache::State::ReInstReq ||
255 I->InstState == pkgCache::State::HoldReInstReq)
256 {
5871718b 257 if (I->CurrentVer != 0 && I.CurrentVer().Downloadable() == true)
74a05226 258 Cache.MarkKeep(I, false, false);
813c8eea
AL
259 else
260 {
261 // Is this right? Will dpkg choke on an upgrade?
2a3f3893
AL
262 if (Cache[I].CandidateVer != 0 &&
263 Cache[I].CandidateVerIter(Cache).Downloadable() == true)
74a05226 264 Cache.MarkInstall(I, false, 0, false);
813c8eea 265 else
b2e465d6 266 return _error->Error(_("The package %s needs to be reinstalled, "
09a10f9c 267 "but I can't find an archive for it."),I.FullName(true).c_str());
813c8eea
AL
268 }
269
d38b7b3d
AL
270 continue;
271 }
272
6c139d6e
AL
273 switch (I->CurrentState)
274 {
813c8eea
AL
275 /* This means installation failed somehow - it does not need to be
276 re-unpacked (probably) */
b518cca6
AL
277 case pkgCache::State::UnPacked:
278 case pkgCache::State::HalfConfigured:
9d06bc80
MV
279 case pkgCache::State::TriggersAwaited:
280 case pkgCache::State::TriggersPending:
5871718b 281 if ((I->CurrentVer != 0 && I.CurrentVer().Downloadable() == true) ||
813c8eea 282 I.State() != pkgCache::PkgIterator::NeedsUnpack)
74a05226 283 Cache.MarkKeep(I, false, false);
813c8eea
AL
284 else
285 {
2a3f3893
AL
286 if (Cache[I].CandidateVer != 0 &&
287 Cache[I].CandidateVerIter(Cache).Downloadable() == true)
74a05226 288 Cache.MarkInstall(I, true, 0, false);
813c8eea 289 else
b83cad32 290 Cache.MarkDelete(I, false, 0, false);
813c8eea 291 }
6c139d6e
AL
292 break;
293
294 // This means removal failed
b518cca6 295 case pkgCache::State::HalfInstalled:
b83cad32 296 Cache.MarkDelete(I, false, 0, false);
6c139d6e
AL
297 break;
298
299 default:
b518cca6 300 if (I->InstState != pkgCache::State::Ok)
6c139d6e 301 return _error->Error("The package %s is not ok and I "
09a10f9c 302 "don't know how to fix it!",I.FullName(false).c_str());
6c139d6e
AL
303 }
304 }
305 return true;
306}
307 /*}}}*/
308// FixBroken - Fix broken packages /*{{{*/
309// ---------------------------------------------------------------------
0a8e3465
AL
310/* This autoinstalls every broken package and then runs the problem resolver
311 on the result. */
6c139d6e
AL
312bool pkgFixBroken(pkgDepCache &Cache)
313{
74a05226
MV
314 pkgDepCache::ActionGroup group(Cache);
315
6c139d6e 316 // Auto upgrade all broken packages
f7f0d6c7 317 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
6c139d6e 318 if (Cache[I].NowBroken() == true)
74a05226 319 Cache.MarkInstall(I, true, 0, false);
7e798dd7 320
6c139d6e
AL
321 /* Fix packages that are in a NeedArchive state but don't have a
322 downloadable install version */
f7f0d6c7 323 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
6c139d6e
AL
324 {
325 if (I.State() != pkgCache::PkgIterator::NeedsUnpack ||
326 Cache[I].Delete() == true)
327 continue;
328
b518cca6 329 if (Cache[I].InstVerIter(Cache).Downloadable() == false)
6c139d6e
AL
330 continue;
331
74a05226 332 Cache.MarkInstall(I, true, 0, false);
6c139d6e
AL
333 }
334
b2e465d6 335 pkgProblemResolver Fix(&Cache);
6c139d6e
AL
336 return Fix.Resolve(true);
337}
338 /*}}}*/
339// DistUpgrade - Distribution upgrade /*{{{*/
340// ---------------------------------------------------------------------
341/* This autoinstalls every package and then force installs every
342 pre-existing package. This creates the initial set of conditions which
343 most likely contain problems because too many things were installed.
344
0a8e3465 345 The problem resolver is used to resolve the problems.
6c139d6e
AL
346 */
347bool pkgDistUpgrade(pkgDepCache &Cache)
348{
98278a81 349 std::string const solver = _config->Find("APT::Solver", "internal");
b57c0e35
DK
350 if (solver != "internal") {
351 OpTextProgress Prog(*_config);
352 return EDSP::ResolveExternal(solver.c_str(), Cache, false, true, false, &Prog);
353 }
741b7da9 354
74a05226
MV
355 pkgDepCache::ActionGroup group(Cache);
356
c427b1e2
DK
357 /* Upgrade all installed packages first without autoinst to help the resolver
358 in versioned or-groups to upgrade the old solver instead of installing
359 a new one (if the old solver is not the first one [anymore]) */
360 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
361 if (I->CurrentVer != 0)
362 Cache.MarkInstall(I, false, 0, false);
363
6c139d6e
AL
364 /* Auto upgrade all installed packages, this provides the basis
365 for the installation */
f7f0d6c7 366 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
6c139d6e 367 if (I->CurrentVer != 0)
74a05226 368 Cache.MarkInstall(I, true, 0, false);
6c139d6e 369
e5a91f7e
DK
370 /* Now, install each essential package which is not installed
371 (and not provided by another package in the same name group) */
372 std::string essential = _config->Find("pkgCacheGen::Essential", "all");
373 if (essential == "all")
374 {
375 for (pkgCache::GrpIterator G = Cache.GrpBegin(); G.end() == false; ++G)
376 {
377 bool isEssential = false;
378 bool instEssential = false;
379 for (pkgCache::PkgIterator P = G.PackageList(); P.end() == false; P = G.NextPkg(P))
380 {
381 if ((P->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential)
382 continue;
383 isEssential = true;
384 if (Cache[P].Install() == true)
385 {
386 instEssential = true;
387 break;
388 }
389 }
390 if (isEssential == false || instEssential == true)
391 continue;
392 pkgCache::PkgIterator P = G.FindPreferredPkg();
393 Cache.MarkInstall(P, true, 0, false);
394 }
395 }
396 else if (essential != "none")
397 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
398 if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
399 Cache.MarkInstall(I, true, 0, false);
6c139d6e
AL
400
401 /* We do it again over all previously installed packages to force
402 conflict resolution on them all. */
f7f0d6c7 403 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
6c139d6e 404 if (I->CurrentVer != 0)
74a05226 405 Cache.MarkInstall(I, false, 0, false);
6c139d6e 406
b2e465d6 407 pkgProblemResolver Fix(&Cache);
c88edf1d 408
6c139d6e 409 // Hold back held packages.
4490f2de 410 if (_config->FindB("APT::Ignore-Hold",false) == false)
6c139d6e 411 {
f7f0d6c7 412 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
6c139d6e 413 {
c88edf1d
AL
414 if (I->SelectedState == pkgCache::State::Hold)
415 {
416 Fix.Protect(I);
74a05226 417 Cache.MarkKeep(I, false, false);
c88edf1d 418 }
6c139d6e
AL
419 }
420 }
421
422 return Fix.Resolve();
423}
424 /*}}}*/
0a8e3465
AL
425// AllUpgrade - Upgrade as many packages as possible /*{{{*/
426// ---------------------------------------------------------------------
427/* Right now the system must be consistent before this can be called.
428 It also will not change packages marked for install, it only tries
429 to install packages not marked for install */
430bool pkgAllUpgrade(pkgDepCache &Cache)
431{
98278a81 432 std::string const solver = _config->Find("APT::Solver", "internal");
b57c0e35
DK
433 if (solver != "internal") {
434 OpTextProgress Prog(*_config);
435 return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog);
436 }
741b7da9 437
74a05226
MV
438 pkgDepCache::ActionGroup group(Cache);
439
b2e465d6 440 pkgProblemResolver Fix(&Cache);
0a8e3465
AL
441
442 if (Cache.BrokenCount() != 0)
443 return false;
444
445 // Upgrade all installed packages
f7f0d6c7 446 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
0a8e3465
AL
447 {
448 if (Cache[I].Install() == true)
449 Fix.Protect(I);
450
b2e465d6 451 if (_config->FindB("APT::Ignore-Hold",false) == false)
c88edf1d
AL
452 if (I->SelectedState == pkgCache::State::Hold)
453 continue;
0a8e3465
AL
454
455 if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
74a05226 456 Cache.MarkInstall(I, false, 0, false);
0a8e3465
AL
457 }
458
459 return Fix.ResolveByKeep();
460}
461 /*}}}*/
7e798dd7
AL
462// MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
463// ---------------------------------------------------------------------
464/* This simply goes over the entire set of packages and tries to keep
465 each package marked for upgrade. If a conflict is generated then
466 the package is restored. */
467bool pkgMinimizeUpgrade(pkgDepCache &Cache)
468{
74a05226
MV
469 pkgDepCache::ActionGroup group(Cache);
470
7e798dd7
AL
471 if (Cache.BrokenCount() != 0)
472 return false;
473
abc8419e 474 // We loop for 10 tries to get the minimal set size.
7e798dd7 475 bool Change = false;
a005475e 476 unsigned int Count = 0;
7e798dd7
AL
477 do
478 {
479 Change = false;
f7f0d6c7 480 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
7e798dd7
AL
481 {
482 // Not interesting
483 if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
484 continue;
a005475e 485
7e798dd7 486 // Keep it and see if that is OK
74a05226 487 Cache.MarkKeep(I, false, false);
7e798dd7 488 if (Cache.BrokenCount() != 0)
74a05226 489 Cache.MarkInstall(I, false, 0, false);
7e798dd7 490 else
a005475e
AL
491 {
492 // If keep didnt actually do anything then there was no change..
493 if (Cache[I].Upgrade() == false)
494 Change = true;
495 }
7e798dd7 496 }
f7f0d6c7 497 ++Count;
7e798dd7 498 }
a005475e 499 while (Change == true && Count < 10);
7e798dd7
AL
500
501 if (Cache.BrokenCount() != 0)
502 return _error->Error("Internal Error in pkgMinimizeUpgrade");
503
504 return true;
505}
506 /*}}}*/
6c139d6e
AL
507// ProblemResolver::pkgProblemResolver - Constructor /*{{{*/
508// ---------------------------------------------------------------------
509/* */
dcaa1185 510pkgProblemResolver::pkgProblemResolver(pkgDepCache *pCache) : d(NULL), Cache(*pCache)
6c139d6e
AL
511{
512 // Allocate memory
b2e465d6 513 unsigned long Size = Cache.Head().PackageCount;
d0f2c87c 514 Scores = new int[Size];
6c139d6e
AL
515 Flags = new unsigned char[Size];
516 memset(Flags,0,sizeof(*Flags)*Size);
517
518 // Set debug to true to see its decision logic
0a8e3465 519 Debug = _config->FindB("Debug::pkgProblemResolver",false);
6c139d6e
AL
520}
521 /*}}}*/
b2e465d6
AL
522// ProblemResolver::~pkgProblemResolver - Destructor /*{{{*/
523// ---------------------------------------------------------------------
524/* */
525pkgProblemResolver::~pkgProblemResolver()
526{
527 delete [] Scores;
528 delete [] Flags;
529}
530 /*}}}*/
6c139d6e
AL
531// ProblemResolver::ScoreSort - Sort the list by score /*{{{*/
532// ---------------------------------------------------------------------
533/* */
534int pkgProblemResolver::ScoreSort(const void *a,const void *b)
535{
536 Package const **A = (Package const **)a;
537 Package const **B = (Package const **)b;
538 if (This->Scores[(*A)->ID] > This->Scores[(*B)->ID])
539 return -1;
540 if (This->Scores[(*A)->ID] < This->Scores[(*B)->ID])
541 return 1;
542 return 0;
543}
544 /*}}}*/
545// ProblemResolver::MakeScores - Make the score table /*{{{*/
546// ---------------------------------------------------------------------
547/* */
548void pkgProblemResolver::MakeScores()
549{
b2e465d6 550 unsigned long Size = Cache.Head().PackageCount;
6c139d6e
AL
551 memset(Scores,0,sizeof(*Scores)*Size);
552
c0751c06
MV
553 // Maps to pkgCache::State::VerPriority
554 // which is "Important Required Standard Optional Extra"
555 // (yes, that is confusing, the order of pkgCache::State::VerPriority
556 // needs to be adjusted but that requires a ABI break)
d0f2c87c 557 int PrioMap[] = {
8b4894fe 558 0,
84de0cea
MV
559 _config->FindI("pkgProblemResolver::Scores::Important",2),
560 _config->FindI("pkgProblemResolver::Scores::Required",3),
d0f2c87c
CW
561 _config->FindI("pkgProblemResolver::Scores::Standard",1),
562 _config->FindI("pkgProblemResolver::Scores::Optional",-1),
563 _config->FindI("pkgProblemResolver::Scores::Extra",-2)
8b4894fe 564 };
d0f2c87c
CW
565 int PrioEssentials = _config->FindI("pkgProblemResolver::Scores::Essentials",100);
566 int PrioInstalledAndNotObsolete = _config->FindI("pkgProblemResolver::Scores::NotObsolete",1);
567 int PrioDepends = _config->FindI("pkgProblemResolver::Scores::Depends",1);
568 int PrioRecommends = _config->FindI("pkgProblemResolver::Scores::Recommends",1);
569 int AddProtected = _config->FindI("pkgProblemResolver::Scores::AddProtected",10000);
570 int AddEssential = _config->FindI("pkgProblemResolver::Scores::AddEssential",5000);
8b4894fe
MV
571
572 if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
573 clog << "Settings used to calculate pkgProblemResolver::Scores::" << endl
84de0cea
MV
574 << " Required => " << PrioMap[pkgCache::State::Required] << endl
575 << " Important => " << PrioMap[pkgCache::State::Important] << endl
576 << " Standard => " << PrioMap[pkgCache::State::Standard] << endl
577 << " Optional => " << PrioMap[pkgCache::State::Optional] << endl
578 << " Extra => " << PrioMap[pkgCache::State::Extra] << endl
8b4894fe
MV
579 << " Essentials => " << PrioEssentials << endl
580 << " InstalledAndNotObsolete => " << PrioInstalledAndNotObsolete << endl
581 << " Depends => " << PrioDepends << endl
53391d0f 582 << " Recommends => " << PrioRecommends << endl
8b4894fe
MV
583 << " AddProtected => " << AddProtected << endl
584 << " AddEssential => " << AddEssential << endl;
585
6c139d6e 586 // Generate the base scores for a package based on its properties
f7f0d6c7 587 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
6c139d6e
AL
588 {
589 if (Cache[I].InstallVer == 0)
590 continue;
591
d0f2c87c 592 int &Score = Scores[I->ID];
6c139d6e 593
7365ff46 594 /* This is arbitrary, it should be high enough to elevate an
6c139d6e
AL
595 essantial package above most other packages but low enough
596 to allow an obsolete essential packages to be removed by
597 a conflicts on a powerfull normal package (ie libc6) */
c5200869
JAK
598 if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential
599 || (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
8b4894fe 600 Score += PrioEssentials;
6c139d6e
AL
601
602 // We transform the priority
6c139d6e
AL
603 if (Cache[I].InstVerIter(Cache)->Priority <= 5)
604 Score += PrioMap[Cache[I].InstVerIter(Cache)->Priority];
605
606 /* This helps to fix oddball problems with conflicting packages
4172c784
MV
607 on the same level. We enhance the score of installed packages
608 if those are not obsolete
609 */
020daa7b 610 if (I->CurrentVer != 0 && Cache[I].CandidateVer != 0 && Cache[I].CandidateVerIter(Cache).Downloadable())
8b4894fe 611 Score += PrioInstalledAndNotObsolete;
6c139d6e
AL
612 }
613
614 // Now that we have the base scores we go and propogate dependencies
f7f0d6c7 615 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
6c139d6e
AL
616 {
617 if (Cache[I].InstallVer == 0)
618 continue;
619
f7f0d6c7 620 for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false; ++D)
6c139d6e 621 {
3a998f6a 622 if (D->Type == pkgCache::Dep::Depends ||
53391d0f
MV
623 D->Type == pkgCache::Dep::PreDepends)
624 Scores[D.TargetPkg()->ID] += PrioDepends;
625 else if (D->Type == pkgCache::Dep::Recommends)
626 Scores[D.TargetPkg()->ID] += PrioRecommends;
6c139d6e
AL
627 }
628 }
629
630 // Copy the scores to advoid additive looping
d0f2c87c 631 SPtrArray<int> OldScores = new int[Size];
6c139d6e
AL
632 memcpy(OldScores,Scores,sizeof(*Scores)*Size);
633
634 /* Now we cause 1 level of dependency inheritance, that is we add the
635 score of the packages that depend on the target Package. This
636 fortifies high scoring packages */
f7f0d6c7 637 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
6c139d6e
AL
638 {
639 if (Cache[I].InstallVer == 0)
640 continue;
641
f7f0d6c7 642 for (pkgCache::DepIterator D = I.RevDependsList(); D.end() == false; ++D)
6c139d6e
AL
643 {
644 // Only do it for the install version
645 if ((pkgCache::Version *)D.ParentVer() != Cache[D.ParentPkg()].InstallVer ||
3a998f6a
MV
646 (D->Type != pkgCache::Dep::Depends &&
647 D->Type != pkgCache::Dep::PreDepends &&
648 D->Type != pkgCache::Dep::Recommends))
6c139d6e
AL
649 continue;
650
651 Scores[I->ID] += abs(OldScores[D.ParentPkg()->ID]);
652 }
653 }
654
655 /* Now we propogate along provides. This makes the packages that
656 provide important packages extremely important */
f7f0d6c7 657 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
6c139d6e 658 {
f7f0d6c7 659 for (pkgCache::PrvIterator P = I.ProvidesList(); P.end() == false; ++P)
6c139d6e
AL
660 {
661 // Only do it once per package
662 if ((pkgCache::Version *)P.OwnerVer() != Cache[P.OwnerPkg()].InstallVer)
663 continue;
664 Scores[P.OwnerPkg()->ID] += abs(Scores[I->ID] - OldScores[I->ID]);
665 }
666 }
667
668 /* Protected things are pushed really high up. This number should put them
669 ahead of everything */
f7f0d6c7 670 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
d2685fd6 671 {
6c139d6e 672 if ((Flags[I->ID] & Protected) != 0)
8b4894fe 673 Scores[I->ID] += AddProtected;
c5200869
JAK
674 if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential ||
675 (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
8b4894fe
MV
676 Scores[I->ID] += AddEssential;
677 }
6c139d6e
AL
678}
679 /*}}}*/
680// ProblemResolver::DoUpgrade - Attempt to upgrade this package /*{{{*/
681// ---------------------------------------------------------------------
682/* This goes through and tries to reinstall packages to make this package
683 installable */
684bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
685{
74a05226
MV
686 pkgDepCache::ActionGroup group(Cache);
687
6c139d6e
AL
688 if ((Flags[Pkg->ID] & Upgradable) == 0 || Cache[Pkg].Upgradable() == false)
689 return false;
3a486305
AL
690 if ((Flags[Pkg->ID] & Protected) == Protected)
691 return false;
0a8e3465 692
6c139d6e
AL
693 Flags[Pkg->ID] &= ~Upgradable;
694
695 bool WasKept = Cache[Pkg].Keep();
74a05226 696 Cache.MarkInstall(Pkg, false, 0, false);
6c139d6e 697
0a8e3465
AL
698 // This must be a virtual package or something like that.
699 if (Cache[Pkg].InstVerIter(Cache).end() == true)
700 return false;
701
6c139d6e
AL
702 // Isolate the problem dependency
703 bool Fail = false;
704 for (pkgCache::DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false;)
705 {
706 // Compute a single dependency element (glob or)
707 pkgCache::DepIterator Start = D;
708 pkgCache::DepIterator End = D;
4b1b89c5 709 for (bool LastOR = true; D.end() == false && LastOR == true;)
6c139d6e 710 {
b518cca6 711 LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
0284eee4 712 ++D;
6c139d6e
AL
713 if (LastOR == true)
714 End = D;
715 }
716
717 // We only worry about critical deps.
718 if (End.IsCritical() != true)
719 continue;
4b1b89c5
AL
720
721 // Iterate over all the members in the or group
722 while (1)
0a8e3465 723 {
4b1b89c5
AL
724 // Dep is ok now
725 if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
726 break;
727
728 // Do not change protected packages
729 PkgIterator P = Start.SmartTargetPkg();
730 if ((Flags[P->ID] & Protected) == Protected)
731 {
732 if (Debug == true)
47f6d1b7 733 clog << " Reinst Failed because of protected " << P.FullName(false) << endl;
4b1b89c5 734 Fail = true;
4b1b89c5 735 }
648e3cb4 736 else
6c139d6e 737 {
648e3cb4
AL
738 // Upgrade the package if the candidate version will fix the problem.
739 if ((Cache[Start] & pkgDepCache::DepCVer) == pkgDepCache::DepCVer)
740 {
741 if (DoUpgrade(P) == false)
742 {
743 if (Debug == true)
47f6d1b7 744 clog << " Reinst Failed because of " << P.FullName(false) << endl;
648e3cb4
AL
745 Fail = true;
746 }
747 else
748 {
749 Fail = false;
750 break;
751 }
752 }
753 else
4b1b89c5 754 {
648e3cb4
AL
755 /* We let the algorithm deal with conflicts on its next iteration,
756 it is much smarter than us */
359e46db 757 if (Start.IsNegative() == true)
b2e465d6 758 break;
648e3cb4 759
4b1b89c5 760 if (Debug == true)
47f6d1b7 761 clog << " Reinst Failed early because of " << Start.TargetPkg().FullName(false) << endl;
4b1b89c5 762 Fail = true;
648e3cb4 763 }
4b1b89c5 764 }
6c139d6e 765
4b1b89c5
AL
766 if (Start == End)
767 break;
f7f0d6c7 768 ++Start;
4b1b89c5
AL
769 }
770 if (Fail == true)
6c139d6e 771 break;
6c139d6e
AL
772 }
773
774 // Undo our operations - it might be smart to undo everything this did..
775 if (Fail == true)
776 {
777 if (WasKept == true)
74a05226 778 Cache.MarkKeep(Pkg, false, false);
6c139d6e 779 else
b83cad32 780 Cache.MarkDelete(Pkg, false, 0, false);
6c139d6e
AL
781 return false;
782 }
783
784 if (Debug == true)
47f6d1b7 785 clog << " Re-Instated " << Pkg.FullName(false) << endl;
6c139d6e
AL
786 return true;
787}
788 /*}}}*/
6d38011b
DK
789// ProblemResolver::Resolve - calls a resolver to fix the situation /*{{{*/
790// ---------------------------------------------------------------------
791/* */
792bool pkgProblemResolver::Resolve(bool BrokenFix)
793{
98278a81 794 std::string const solver = _config->Find("APT::Solver", "internal");
b57c0e35
DK
795 if (solver != "internal") {
796 OpTextProgress Prog(*_config);
797 return EDSP::ResolveExternal(solver.c_str(), Cache, false, false, false, &Prog);
798 }
6d38011b
DK
799 return ResolveInternal(BrokenFix);
800}
801 /*}}}*/
802// ProblemResolver::ResolveInternal - Run the resolution pass /*{{{*/
6c139d6e
AL
803// ---------------------------------------------------------------------
804/* This routines works by calculating a score for each package. The score
805 is derived by considering the package's priority and all reverse
806 dependents giving an integer that reflects the amount of breakage that
807 adjusting the package will inflict.
808
809 It goes from highest score to lowest and corrects all of the breaks by
810 keeping or removing the dependant packages. If that fails then it removes
811 the package itself and goes on. The routine should be able to intelligently
812 go from any broken state to a fixed state.
813
814 The BrokenFix flag enables a mode where the algorithm tries to
815 upgrade packages to advoid problems. */
6d38011b 816bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
6c139d6e 817{
74a05226
MV
818 pkgDepCache::ActionGroup group(Cache);
819
6c139d6e
AL
820 // Record which packages are marked for install
821 bool Again = false;
822 do
823 {
824 Again = false;
f7f0d6c7 825 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
6c139d6e
AL
826 {
827 if (Cache[I].Install() == true)
828 Flags[I->ID] |= PreInstalled;
829 else
830 {
831 if (Cache[I].InstBroken() == true && BrokenFix == true)
832 {
74a05226 833 Cache.MarkInstall(I, false, 0, false);
6c139d6e
AL
834 if (Cache[I].Install() == true)
835 Again = true;
836 }
837
838 Flags[I->ID] &= ~PreInstalled;
839 }
840 Flags[I->ID] |= Upgradable;
841 }
842 }
843 while (Again == true);
844
845 if (Debug == true)
0a8e3465 846 clog << "Starting" << endl;
6c139d6e
AL
847
848 MakeScores();
6d38011b
DK
849
850 unsigned long const Size = Cache.Head().PackageCount;
851
6c139d6e
AL
852 /* We have to order the packages so that the broken fixing pass
853 operates from highest score to lowest. This prevents problems when
854 high score packages cause the removal of lower score packages that
855 would cause the removal of even lower score packages. */
b2e465d6 856 SPtrArray<pkgCache::Package *> PList = new pkgCache::Package *[Size];
6c139d6e 857 pkgCache::Package **PEnd = PList;
f7f0d6c7 858 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
6c139d6e
AL
859 *PEnd++ = I;
860 This = this;
861 qsort(PList,PEnd - PList,sizeof(*PList),&ScoreSort);
8b4894fe
MV
862
863 if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
864 {
865 clog << "Show Scores" << endl;
866 for (pkgCache::Package **K = PList; K != PEnd; K++)
867 if (Scores[(*K)->ID] != 0)
868 {
869 pkgCache::PkgIterator Pkg(Cache,*K);
870 clog << Scores[(*K)->ID] << ' ' << Pkg << std::endl;
871 }
872 }
6c139d6e
AL
873
874 if (Debug == true)
0a8e3465 875 clog << "Starting 2" << endl;
8b4894fe 876
6c139d6e
AL
877 /* Now consider all broken packages. For each broken package we either
878 remove the package or fix it's problem. We do this once, it should
879 not be possible for a loop to form (that is a < b < c and fixing b by
880 changing a breaks c) */
881 bool Change = true;
09a10f9c 882 bool const TryFixByInstall = _config->FindB("pkgProblemResolver::FixByInstall", true);
6c139d6e
AL
883 for (int Counter = 0; Counter != 10 && Change == true; Counter++)
884 {
885 Change = false;
886 for (pkgCache::Package **K = PList; K != PEnd; K++)
887 {
888 pkgCache::PkgIterator I(Cache,*K);
889
890 /* We attempt to install this and see if any breaks result,
891 this takes care of some strange cases */
892 if (Cache[I].CandidateVer != Cache[I].InstallVer &&
893 I->CurrentVer != 0 && Cache[I].InstallVer != 0 &&
894 (Flags[I->ID] & PreInstalled) != 0 &&
0a8e3465
AL
895 (Flags[I->ID] & Protected) == 0 &&
896 (Flags[I->ID] & ReInstateTried) == 0)
6c139d6e
AL
897 {
898 if (Debug == true)
09a10f9c 899 clog << " Try to Re-Instate (" << Counter << ") " << I.FullName(false) << endl;
a6568219 900 unsigned long OldBreaks = Cache.BrokenCount();
6c139d6e 901 pkgCache::Version *OldVer = Cache[I].InstallVer;
0a8e3465
AL
902 Flags[I->ID] &= ReInstateTried;
903
74a05226 904 Cache.MarkInstall(I, false, 0, false);
6c139d6e
AL
905 if (Cache[I].InstBroken() == true ||
906 OldBreaks < Cache.BrokenCount())
907 {
908 if (OldVer == 0)
b83cad32 909 Cache.MarkDelete(I, false, 0, false);
6c139d6e 910 else
74a05226 911 Cache.MarkKeep(I, false, false);
6c139d6e
AL
912 }
913 else
914 if (Debug == true)
47f6d1b7 915 clog << "Re-Instated " << I.FullName(false) << " (" << OldBreaks << " vs " << Cache.BrokenCount() << ')' << endl;
6c139d6e
AL
916 }
917
918 if (Cache[I].InstallVer == 0 || Cache[I].InstBroken() == false)
919 continue;
920
00b47c98 921 if (Debug == true)
09a10f9c 922 clog << "Investigating (" << Counter << ") " << I << endl;
00b47c98 923
6c139d6e
AL
924 // Isolate the problem dependency
925 PackageKill KillList[100];
926 PackageKill *LEnd = KillList;
421c8d10
AL
927 bool InOr = false;
928 pkgCache::DepIterator Start;
929 pkgCache::DepIterator End;
b2e465d6 930 PackageKill *OldEnd = LEnd;
648e3cb4
AL
931
932 enum {OrRemove,OrKeep} OrOp = OrRemove;
421c8d10
AL
933 for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList();
934 D.end() == false || InOr == true;)
6c139d6e
AL
935 {
936 // Compute a single dependency element (glob or)
648e3cb4
AL
937 if (Start == End)
938 {
939 // Decide what to do
09a10f9c 940 if (InOr == true && OldEnd == LEnd)
648e3cb4 941 {
09a10f9c 942 if (OrOp == OrRemove)
70777d4b
AL
943 {
944 if ((Flags[I->ID] & Protected) != Protected)
00b47c98
AL
945 {
946 if (Debug == true)
47f6d1b7 947 clog << " Or group remove for " << I.FullName(false) << endl;
b83cad32 948 Cache.MarkDelete(I, false, 0, false);
cd14eaf2 949 Change = true;
09a10f9c
DK
950 }
951 }
952 else if (OrOp == OrKeep)
00b47c98
AL
953 {
954 if (Debug == true)
47f6d1b7 955 clog << " Or group keep for " << I.FullName(false) << endl;
74a05226 956 Cache.MarkKeep(I, false, false);
cd14eaf2 957 Change = true;
b2e465d6 958 }
648e3cb4
AL
959 }
960
b2e465d6
AL
961 /* We do an extra loop (as above) to finalize the or group
962 processing */
963 InOr = false;
648e3cb4 964 OrOp = OrRemove;
421c8d10 965 D.GlobOr(Start,End);
b2e465d6
AL
966 if (Start.end() == true)
967 break;
cd14eaf2 968
b2e465d6
AL
969 // We only worry about critical deps.
970 if (End.IsCritical() != true)
971 continue;
cd14eaf2 972
648e3cb4
AL
973 InOr = Start != End;
974 OldEnd = LEnd;
cd14eaf2 975 }
421c8d10 976 else
4cc152f9 977 {
f7f0d6c7 978 ++Start;
4cc152f9
MV
979 // We only worry about critical deps.
980 if (Start.IsCritical() != true)
981 continue;
982 }
cd14eaf2 983
6c139d6e
AL
984 // Dep is ok
985 if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
cd14eaf2
AL
986 {
987 InOr = false;
6c139d6e 988 continue;
cd14eaf2
AL
989 }
990
6c139d6e 991 if (Debug == true)
47f6d1b7 992 clog << "Broken " << Start << endl;
fcf85120
AL
993
994 /* Look across the version list. If there are no possible
995 targets then we keep the package and bail. This is necessary
996 if a package has a dep on another package that cant be found */
b2e465d6 997 SPtrArray<pkgCache::Version *> VList = Start.AllTargets();
fcf85120 998 if (*VList == 0 && (Flags[I->ID] & Protected) != Protected &&
359e46db 999 Start.IsNegative() == false &&
fcf85120 1000 Cache[I].NowBroken() == false)
648e3cb4
AL
1001 {
1002 if (InOr == true)
1003 {
1004 /* No keep choice because the keep being OK could be the
1005 result of another element in the OR group! */
1006 continue;
1007 }
1008
fcf85120 1009 Change = true;
74a05226 1010 Cache.MarkKeep(I, false, false);
fcf85120
AL
1011 break;
1012 }
1013
6c139d6e
AL
1014 bool Done = false;
1015 for (pkgCache::Version **V = VList; *V != 0; V++)
1016 {
1017 pkgCache::VerIterator Ver(Cache,*V);
1018 pkgCache::PkgIterator Pkg = Ver.ParentPkg();
a6bfe583 1019
2ba99db8
MV
1020 /* This is a conflicts, and the version we are looking
1021 at is not the currently selected version of the
1022 package, which means it is not necessary to
1023 remove/keep */
359e46db 1024 if (Cache[Pkg].InstallVer != Ver && Start.IsNegative() == true)
4429616b 1025 {
2ba99db8
MV
1026 if (Debug)
1027 clog << " Conflicts//Breaks against version "
1028 << Ver.VerStr() << " for " << Pkg.Name()
1029 << " but that is not InstVer, ignoring"
24e93662 1030 << endl;
2ba99db8 1031 continue;
4429616b
MV
1032 }
1033
6c139d6e 1034 if (Debug == true)
47f6d1b7
DK
1035 clog << " Considering " << Pkg.FullName(false) << ' ' << (int)Scores[Pkg->ID] <<
1036 " as a solution to " << I.FullName(false) << ' ' << (int)Scores[I->ID] << endl;
a6bfe583
AL
1037
1038 /* Try to fix the package under consideration rather than
1039 fiddle with the VList package */
6c139d6e 1040 if (Scores[I->ID] <= Scores[Pkg->ID] ||
421c8d10 1041 ((Cache[Start] & pkgDepCache::DepNow) == 0 &&
359e46db 1042 End.IsNegative() == false))
6c139d6e 1043 {
200f8c52 1044 // Try a little harder to fix protected packages..
3b5421b4 1045 if ((Flags[I->ID] & Protected) == Protected)
200f8c52
AL
1046 {
1047 if (DoUpgrade(Pkg) == true)
0296c633 1048 {
b2e465d6
AL
1049 if (Scores[Pkg->ID] > Scores[I->ID])
1050 Scores[Pkg->ID] = Scores[I->ID];
0296c633
AL
1051 break;
1052 }
1053
6c139d6e 1054 continue;
200f8c52
AL
1055 }
1056
1057 /* See if a keep will do, unless the package is protected,
648e3cb4
AL
1058 then installing it will be necessary */
1059 bool Installed = Cache[I].Install();
74a05226 1060 Cache.MarkKeep(I, false, false);
6c139d6e
AL
1061 if (Cache[I].InstBroken() == false)
1062 {
648e3cb4
AL
1063 // Unwind operation will be keep now
1064 if (OrOp == OrRemove)
1065 OrOp = OrKeep;
1066
1067 // Restore
1068 if (InOr == true && Installed == true)
74a05226 1069 Cache.MarkInstall(I, false, 0, false);
648e3cb4 1070
6c139d6e 1071 if (Debug == true)
47f6d1b7 1072 clog << " Holding Back " << I.FullName(false) << " rather than change " << Start.TargetPkg().FullName(false) << endl;
6c139d6e
AL
1073 }
1074 else
421c8d10 1075 {
6c139d6e
AL
1076 if (BrokenFix == false || DoUpgrade(I) == false)
1077 {
421c8d10 1078 // Consider other options
87da7451 1079 if (InOr == false || Cache[I].Garbage == true)
421c8d10 1080 {
6910a2ac 1081 if (Debug == true)
47f6d1b7 1082 clog << " Removing " << I.FullName(false) << " rather than change " << Start.TargetPkg().FullName(false) << endl;
b83cad32 1083 Cache.MarkDelete(I, false, 0, false);
6910a2ac
DK
1084 if (Counter > 1 && Scores[Pkg->ID] > Scores[I->ID])
1085 Scores[I->ID] = Scores[Pkg->ID];
d6ebeb21 1086 }
09a10f9c
DK
1087 else if (TryFixByInstall == true &&
1088 Start.TargetPkg()->CurrentVer == 0 &&
1089 Cache[Start.TargetPkg()].Delete() == false &&
a3f1a6cc 1090 (Flags[Start.TargetPkg()->ID] & ToRemove) != ToRemove &&
09a10f9c
DK
1091 Cache.GetCandidateVer(Start.TargetPkg()).end() == false)
1092 {
1093 /* Before removing or keeping the package with the broken dependency
1094 try instead to install the first not previously installed package
1095 solving this dependency. This helps every time a previous solver
1096 is removed by the resolver because of a conflict or alike but it is
1097 dangerous as it could trigger new breaks/conflicts… */
443266ef
DK
1098 if (Debug == true)
1099 clog << " Try Installing " << Start.TargetPkg() << " before changing " << I.FullName(false) << std::endl;
09a10f9c
DK
1100 unsigned long const OldBroken = Cache.BrokenCount();
1101 Cache.MarkInstall(Start.TargetPkg(), true, 1, false);
1102 // FIXME: we should undo the complete MarkInstall process here
1103 if (Cache[Start.TargetPkg()].InstBroken() == true || Cache.BrokenCount() > OldBroken)
1104 Cache.MarkDelete(Start.TargetPkg(), false, 1, false);
1105 }
0a8e3465 1106 }
6c139d6e 1107 }
b5dc9785 1108
6c139d6e
AL
1109 Change = true;
1110 Done = true;
1111 break;
1112 }
1113 else
1114 {
308c7d30
IJ
1115 if (Start->Type == pkgCache::Dep::DpkgBreaks)
1116 {
76264cb7
MV
1117 // first, try upgradring the package, if that
1118 // does not help, the breaks goes onto the
1119 // kill list
2ba99db8 1120 //
76264cb7 1121 // FIXME: use DoUpgrade(Pkg) instead?
2ba99db8 1122 if (Cache[End] & pkgDepCache::DepGCVer)
76264cb7 1123 {
308c7d30 1124 if (Debug)
47f6d1b7 1125 clog << " Upgrading " << Pkg.FullName(false) << " due to Breaks field in " << I.FullName(false) << endl;
308c7d30
IJ
1126 Cache.MarkInstall(Pkg, false, 0, false);
1127 continue;
1128 }
308c7d30
IJ
1129 }
1130
648e3cb4 1131 // Skip adding to the kill list if it is protected
6c139d6e
AL
1132 if ((Flags[Pkg->ID] & Protected) != 0)
1133 continue;
a6bfe583
AL
1134
1135 if (Debug == true)
47f6d1b7 1136 clog << " Added " << Pkg.FullName(false) << " to the remove list" << endl;
6c139d6e
AL
1137
1138 LEnd->Pkg = Pkg;
1139 LEnd->Dep = End;
1140 LEnd++;
0a8e3465 1141
b47053bd 1142 if (Start.IsNegative() == false)
6c139d6e
AL
1143 break;
1144 }
1145 }
1146
1147 // Hm, nothing can possibly satisify this dep. Nuke it.
359e46db
DK
1148 if (VList[0] == 0 &&
1149 Start.IsNegative() == false &&
648e3cb4 1150 (Flags[I->ID] & Protected) != Protected)
6c139d6e 1151 {
648e3cb4 1152 bool Installed = Cache[I].Install();
6c139d6e
AL
1153 Cache.MarkKeep(I);
1154 if (Cache[I].InstBroken() == false)
1155 {
648e3cb4
AL
1156 // Unwind operation will be keep now
1157 if (OrOp == OrRemove)
1158 OrOp = OrKeep;
1159
1160 // Restore
1161 if (InOr == true && Installed == true)
74a05226 1162 Cache.MarkInstall(I, false, 0, false);
648e3cb4 1163
6c139d6e 1164 if (Debug == true)
47f6d1b7 1165 clog << " Holding Back " << I.FullName(false) << " because I can't find " << Start.TargetPkg().FullName(false) << endl;
6c139d6e
AL
1166 }
1167 else
1168 {
1169 if (Debug == true)
47f6d1b7 1170 clog << " Removing " << I.FullName(false) << " because I can't find " << Start.TargetPkg().FullName(false) << endl;
648e3cb4 1171 if (InOr == false)
b83cad32 1172 Cache.MarkDelete(I, false, 0, false);
6c139d6e
AL
1173 }
1174
1175 Change = true;
1176 Done = true;
1177 }
1178
421c8d10
AL
1179 // Try some more
1180 if (InOr == true)
1181 continue;
1182
6c139d6e
AL
1183 if (Done == true)
1184 break;
1185 }
1186
1187 // Apply the kill list now
1188 if (Cache[I].InstallVer != 0)
648e3cb4 1189 {
6c139d6e 1190 for (PackageKill *J = KillList; J != LEnd; J++)
6c139d6e 1191 {
648e3cb4
AL
1192 Change = true;
1193 if ((Cache[J->Dep] & pkgDepCache::DepGNow) == 0)
1194 {
359e46db 1195 if (J->Dep.IsNegative() == true)
648e3cb4
AL
1196 {
1197 if (Debug == true)
47f6d1b7 1198 clog << " Fixing " << I.FullName(false) << " via remove of " << J->Pkg.FullName(false) << endl;
b83cad32 1199 Cache.MarkDelete(J->Pkg, false, 0, false);
648e3cb4
AL
1200 }
1201 }
1202 else
6c139d6e
AL
1203 {
1204 if (Debug == true)
47f6d1b7 1205 clog << " Fixing " << I.FullName(false) << " via keep of " << J->Pkg.FullName(false) << endl;
74a05226 1206 Cache.MarkKeep(J->Pkg, false, false);
6c139d6e 1207 }
b2e465d6 1208
648e3cb4 1209 if (Counter > 1)
b2e465d6
AL
1210 {
1211 if (Scores[I->ID] > Scores[J->Pkg->ID])
1212 Scores[J->Pkg->ID] = Scores[I->ID];
1213 }
648e3cb4
AL
1214 }
1215 }
1216 }
6c139d6e
AL
1217 }
1218
1219 if (Debug == true)
0a8e3465 1220 clog << "Done" << endl;
b2e465d6 1221
6c139d6e 1222 if (Cache.BrokenCount() != 0)
b5dc9785
AL
1223 {
1224 // See if this is the result of a hold
1225 pkgCache::PkgIterator I = Cache.PkgBegin();
f7f0d6c7 1226 for (;I.end() != true; ++I)
b5dc9785
AL
1227 {
1228 if (Cache[I].InstBroken() == false)
1229 continue;
1230 if ((Flags[I->ID] & Protected) != Protected)
b2e465d6 1231 return _error->Error(_("Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages."));
b5dc9785 1232 }
b2e465d6 1233 return _error->Error(_("Unable to correct problems, you have held broken packages."));
b5dc9785
AL
1234 }
1235
fce72602 1236 // set the auto-flags (mvo: I'm not sure if we _really_ need this)
80fa0d8a 1237 pkgCache::PkgIterator I = Cache.PkgBegin();
f7f0d6c7 1238 for (;I.end() != true; ++I) {
80fa0d8a 1239 if (Cache[I].NewInstall() && !(Flags[I->ID] & PreInstalled)) {
120365ce 1240 if(_config->FindI("Debug::pkgAutoRemove",false)) {
47f6d1b7 1241 std::clog << "Resolve installed new pkg: " << I.FullName(false)
120365ce
MV
1242 << " (now marking it as auto)" << std::endl;
1243 }
80fa0d8a
MV
1244 Cache[I].Flags |= pkgCache::Flag::Auto;
1245 }
1246 }
1247
1248
0a8e3465
AL
1249 return true;
1250}
1251 /*}}}*/
953b348c
MV
1252// ProblemResolver::BreaksInstOrPolicy - Check if the given pkg is broken/*{{{*/
1253// ---------------------------------------------------------------------
1254/* This checks if the given package is broken either by a hard dependency
1255 (InstBroken()) or by introducing a new policy breakage e.g. new
1256 unsatisfied recommends for a package that was in "policy-good" state
1257
1258 Note that this is not perfect as it will ignore further breakage
1259 for already broken policy (recommends)
1260*/
1261bool pkgProblemResolver::InstOrNewPolicyBroken(pkgCache::PkgIterator I)
1262{
953b348c
MV
1263 // a broken install is always a problem
1264 if (Cache[I].InstBroken() == true)
deec6474
DK
1265 {
1266 if (Debug == true)
1267 std::clog << " Dependencies are not satisfied for " << I << std::endl;
953b348c 1268 return true;
deec6474 1269 }
953b348c
MV
1270
1271 // a newly broken policy (recommends/suggests) is a problem
1272 if (Cache[I].NowPolicyBroken() == false &&
1273 Cache[I].InstPolicyBroken() == true)
deec6474
DK
1274 {
1275 if (Debug == true)
1276 std::clog << " Policy breaks with upgrade of " << I << std::endl;
953b348c 1277 return true;
deec6474
DK
1278 }
1279
953b348c
MV
1280 return false;
1281}
36a171e1 1282 /*}}}*/
0a8e3465
AL
1283// ProblemResolver::ResolveByKeep - Resolve problems using keep /*{{{*/
1284// ---------------------------------------------------------------------
1285/* This is the work horse of the soft upgrade routine. It is very gental
1286 in that it does not install or remove any packages. It is assumed that the
1287 system was non-broken previously. */
1288bool pkgProblemResolver::ResolveByKeep()
741b7da9 1289{
98278a81 1290 std::string const solver = _config->Find("APT::Solver", "internal");
b57c0e35
DK
1291 if (solver != "internal") {
1292 OpTextProgress Prog(*_config);
1293 return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog);
1294 }
741b7da9
DK
1295 return ResolveByKeepInternal();
1296}
1297 /*}}}*/
1298// ProblemResolver::ResolveByKeepInternal - Resolve problems using keep /*{{{*/
1299// ---------------------------------------------------------------------
1300/* This is the work horse of the soft upgrade routine. It is very gental
1301 in that it does not install or remove any packages. It is assumed that the
1302 system was non-broken previously. */
1303bool pkgProblemResolver::ResolveByKeepInternal()
0a8e3465 1304{
74a05226
MV
1305 pkgDepCache::ActionGroup group(Cache);
1306
b2e465d6 1307 unsigned long Size = Cache.Head().PackageCount;
0a8e3465 1308
0a8e3465
AL
1309 MakeScores();
1310
1311 /* We have to order the packages so that the broken fixing pass
1312 operates from highest score to lowest. This prevents problems when
1313 high score packages cause the removal of lower score packages that
1314 would cause the removal of even lower score packages. */
1315 pkgCache::Package **PList = new pkgCache::Package *[Size];
1316 pkgCache::Package **PEnd = PList;
f7f0d6c7 1317 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
0a8e3465
AL
1318 *PEnd++ = I;
1319 This = this;
1320 qsort(PList,PEnd - PList,sizeof(*PList),&ScoreSort);
8b4894fe
MV
1321
1322 if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
1323 {
1324 clog << "Show Scores" << endl;
1325 for (pkgCache::Package **K = PList; K != PEnd; K++)
1326 if (Scores[(*K)->ID] != 0)
1327 {
1328 pkgCache::PkgIterator Pkg(Cache,*K);
1329 clog << Scores[(*K)->ID] << ' ' << Pkg << std::endl;
1330 }
1331 }
1332
1333 if (Debug == true)
1334 clog << "Entering ResolveByKeep" << endl;
1335
0a8e3465
AL
1336 // Consider each broken package
1337 pkgCache::Package **LastStop = 0;
1338 for (pkgCache::Package **K = PList; K != PEnd; K++)
1339 {
1340 pkgCache::PkgIterator I(Cache,*K);
1341
953b348c 1342 if (Cache[I].InstallVer == 0)
0a8e3465
AL
1343 continue;
1344
953b348c
MV
1345 if (InstOrNewPolicyBroken(I) == false)
1346 continue;
1347
0a8e3465 1348 /* Keep the package. If this works then great, otherwise we have
b2e465d6 1349 to be significantly more agressive and manipulate its dependencies */
0a8e3465
AL
1350 if ((Flags[I->ID] & Protected) == 0)
1351 {
1352 if (Debug == true)
47f6d1b7 1353 clog << "Keeping package " << I.FullName(false) << endl;
74a05226 1354 Cache.MarkKeep(I, false, false);
953b348c 1355 if (InstOrNewPolicyBroken(I) == false)
0a8e3465 1356 {
b2e465d6 1357 K = PList - 1;
0a8e3465
AL
1358 continue;
1359 }
1360 }
1361
1362 // Isolate the problem dependencies
1363 for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false;)
1364 {
c5532863
AL
1365 DepIterator Start;
1366 DepIterator End;
1367 D.GlobOr(Start,End);
1368
0a8e3465
AL
1369 // We only worry about critical deps.
1370 if (End.IsCritical() != true)
1371 continue;
1372
1373 // Dep is ok
1374 if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
1375 continue;
c5532863
AL
1376
1377 /* Hm, the group is broken.. I suppose the best thing to do is to
1378 is to try every combination of keep/not-keep for the set, but thats
1379 slow, and this never happens, just be conservative and assume the
1380 list of ors is in preference and keep till it starts to work. */
1381 while (true)
0a8e3465 1382 {
c5532863 1383 if (Debug == true)
47f6d1b7 1384 clog << "Package " << I.FullName(false) << " " << Start << endl;
8b4894fe 1385
c5532863
AL
1386 // Look at all the possible provides on this package
1387 SPtrArray<pkgCache::Version *> VList = Start.AllTargets();
1388 for (pkgCache::Version **V = VList; *V != 0; V++)
0a8e3465 1389 {
c5532863
AL
1390 pkgCache::VerIterator Ver(Cache,*V);
1391 pkgCache::PkgIterator Pkg = Ver.ParentPkg();
1392
1393 // It is not keepable
1394 if (Cache[Pkg].InstallVer == 0 ||
1395 Pkg->CurrentVer == 0)
1396 continue;
1397
1398 if ((Flags[I->ID] & Protected) == 0)
1399 {
1400 if (Debug == true)
47f6d1b7 1401 clog << " Keeping Package " << Pkg.FullName(false) << " due to " << Start.DepType() << endl;
74a05226 1402 Cache.MarkKeep(Pkg, false, false);
c5532863
AL
1403 }
1404
953b348c 1405 if (InstOrNewPolicyBroken(I) == false)
c5532863 1406 break;
0a8e3465
AL
1407 }
1408
953b348c 1409 if (InstOrNewPolicyBroken(I) == false)
0a8e3465 1410 break;
0a8e3465 1411
c5532863
AL
1412 if (Start == End)
1413 break;
f7f0d6c7 1414 ++Start;
c5532863
AL
1415 }
1416
953b348c 1417 if (InstOrNewPolicyBroken(I) == false)
0a8e3465
AL
1418 break;
1419 }
1420
953b348c 1421 if (InstOrNewPolicyBroken(I) == true)
0a8e3465
AL
1422 continue;
1423
1424 // Restart again.
0291f645
JT
1425 if (K == LastStop) {
1426 // I is an iterator based off our temporary package list,
1427 // so copy the name we need before deleting the temporary list
1428 std::string const LoopingPackage = I.FullName(false);
1429 delete[] PList;
1430 return _error->Error("Internal Error, pkgProblemResolver::ResolveByKeep is looping on package %s.", LoopingPackage.c_str());
1431 }
0a8e3465 1432 LastStop = K;
b2e465d6 1433 K = PList - 1;
0291f645 1434 }
6c139d6e 1435
0291f645 1436 delete[] PList;
6c139d6e
AL
1437 return true;
1438}
1439 /*}}}*/
3b5421b4
AL
1440// ProblemResolver::InstallProtect - Install all protected packages /*{{{*/
1441// ---------------------------------------------------------------------
1442/* This is used to make sure protected packages are installed */
1443void pkgProblemResolver::InstallProtect()
1444{
74a05226
MV
1445 pkgDepCache::ActionGroup group(Cache);
1446
f7f0d6c7 1447 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
3b5421b4
AL
1448 {
1449 if ((Flags[I->ID] & Protected) == Protected)
1450 {
1451 if ((Flags[I->ID] & ToRemove) == ToRemove)
1452 Cache.MarkDelete(I);
c15f5690
MV
1453 else
1454 {
da543ed8
OS
1455 // preserve the information whether the package was auto
1456 // or manually installed
c15f5690
MV
1457 bool autoInst = (Cache[I].Flags & pkgCache::Flag::Auto);
1458 Cache.MarkInstall(I, false, 0, !autoInst);
1459 }
3b5421b4
AL
1460 }
1461 }
1462}
1463 /*}}}*/
b2e465d6
AL
1464// PrioSortList - Sort a list of versions by priority /*{{{*/
1465// ---------------------------------------------------------------------
1466/* This is ment to be used in conjunction with AllTargets to get a list
1467 of versions ordered by preference. */
1468static pkgCache *PrioCache;
1469static int PrioComp(const void *A,const void *B)
1470{
1471 pkgCache::VerIterator L(*PrioCache,*(pkgCache::Version **)A);
1472 pkgCache::VerIterator R(*PrioCache,*(pkgCache::Version **)B);
1473
1474 if ((L.ParentPkg()->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential &&
b8c0f9b7
AL
1475 (R.ParentPkg()->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential)
1476 return 1;
b2e465d6 1477 if ((L.ParentPkg()->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential &&
b8c0f9b7
AL
1478 (R.ParentPkg()->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
1479 return -1;
c5200869
JAK
1480
1481 if ((L.ParentPkg()->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important &&
1482 (R.ParentPkg()->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important)
1483 return 1;
1484 if ((L.ParentPkg()->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important &&
1485 (R.ParentPkg()->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
1486 return -1;
b2e465d6
AL
1487
1488 if (L->Priority != R->Priority)
b8c0f9b7 1489 return R->Priority - L->Priority;
b2e465d6
AL
1490 return strcmp(L.ParentPkg().Name(),R.ParentPkg().Name());
1491}
1492void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List)
1493{
1494 unsigned long Count = 0;
1495 PrioCache = &Cache;
1496 for (pkgCache::Version **I = List; *I != 0; I++)
1497 Count++;
1498 qsort(List,Count,sizeof(*List),PrioComp);
1499}
1500 /*}}}*/
db09a1c5 1501// ListUpdate - construct Fetcher and update the cache files /*{{{*/
760d4968
MV
1502// ---------------------------------------------------------------------
1503/* This is a simple wrapper to update the cache. it will fetch stuff
1504 * from the network (or any other sources defined in sources.list)
1505 */
1506bool ListUpdate(pkgAcquireStatus &Stat,
1507 pkgSourceList &List,
1508 int PulseInterval)
1509{
1cd1c398
DK
1510 pkgAcquire Fetcher;
1511 if (Fetcher.Setup(&Stat, _config->FindDir("Dir::State::Lists")) == false)
1512 return false;
760d4968
MV
1513
1514 // Populate it with the source selection
1515 if (List.GetIndexes(&Fetcher) == false)
1516 return false;
1517
db09a1c5
DK
1518 return AcquireUpdate(Fetcher, PulseInterval, true);
1519}
1520 /*}}}*/
1521// AcquireUpdate - take Fetcher and update the cache files /*{{{*/
1522// ---------------------------------------------------------------------
1523/* This is a simple wrapper to update the cache with a provided acquire
1524 * If you only need control over Status and the used SourcesList use
1525 * ListUpdate method instead.
1526 */
1527bool AcquireUpdate(pkgAcquire &Fetcher, int const PulseInterval,
1528 bool const RunUpdateScripts, bool const ListCleanup)
1529{
760d4968 1530 // Run scripts
db09a1c5
DK
1531 if (RunUpdateScripts == true)
1532 RunScripts("APT::Update::Pre-Invoke");
1533
1534 pkgAcquire::RunResult res;
1535 if(PulseInterval > 0)
760d4968
MV
1536 res = Fetcher.Run(PulseInterval);
1537 else
1538 res = Fetcher.Run();
1539
1540 if (res == pkgAcquire::Failed)
1541 return false;
1542
1543 bool Failed = false;
1544 bool TransientNetworkFailure = false;
1545 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin();
f7f0d6c7 1546 I != Fetcher.ItemsEnd(); ++I)
760d4968
MV
1547 {
1548 if ((*I)->Status == pkgAcquire::Item::StatDone)
1549 continue;
1550
1551 (*I)->Finished();
1552
70b3d263
MV
1553 ::URI uri((*I)->DescURI());
1554 uri.User.clear();
1555 uri.Password.clear();
1556 string descUri = string(uri);
4805f1cf 1557 _error->Warning(_("Failed to fetch %s %s\n"), descUri.c_str(),
760d4968
MV
1558 (*I)->ErrorText.c_str());
1559
1560 if ((*I)->Status == pkgAcquire::Item::StatTransientNetworkError)
1561 {
1562 TransientNetworkFailure = true;
1563 continue;
1564 }
1565
1566 Failed = true;
1567 }
1568
1569 // Clean out any old list files
1570 // Keep "APT::Get::List-Cleanup" name for compatibility, but
1571 // this is really a global option for the APT library now
db09a1c5 1572 if (!TransientNetworkFailure && !Failed && ListCleanup == true &&
b7c5ca8c 1573 (_config->FindB("APT::Get::List-Cleanup",true) == true &&
760d4968
MV
1574 _config->FindB("APT::List-Cleanup",true) == true))
1575 {
1576 if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
1577 Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
1578 // something went wrong with the clean
1579 return false;
1580 }
1581
1582 if (TransientNetworkFailure == true)
196c511c 1583 _error->Warning(_("Some index files failed to download. They have been ignored, or old ones used instead."));
760d4968 1584 else if (Failed == true)
196c511c 1585 return _error->Error(_("Some index files failed to download. They have been ignored, or old ones used instead."));
760d4968
MV
1586
1587
e06c72cd 1588 // Run the success scripts if all was fine
db09a1c5
DK
1589 if (RunUpdateScripts == true)
1590 {
1591 if(!TransientNetworkFailure && !Failed)
1592 RunScripts("APT::Update::Post-Invoke-Success");
e06c72cd 1593
db09a1c5
DK
1594 // Run the other scripts
1595 RunScripts("APT::Update::Post-Invoke");
1596 }
760d4968
MV
1597 return true;
1598}
1599 /*}}}*/