1 // -*- mode: cpp; mode: fold -*-
3 // $Id: algorithms.cc,v 1.44 2002/11/28 18:49:16 jgg Exp $
4 /* ######################################################################
6 Algorithms - A set of misc algorithms
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.
14 ##################################################################### */
16 // Include Files /*{{{*/
19 #include <apt-pkg/algorithms.h>
20 #include <apt-pkg/error.h>
21 #include <apt-pkg/configuration.h>
22 #include <apt-pkg/version.h>
23 #include <apt-pkg/sptr.h>
24 #include <apt-pkg/acquire-item.h>
25 #include <apt-pkg/edsp.h>
26 #include <apt-pkg/sourcelist.h>
27 #include <apt-pkg/fileutl.h>
28 #include <apt-pkg/progress.h>
30 #include <sys/types.h>
40 pkgProblemResolver
*pkgProblemResolver::This
= 0;
42 // Simulate::Simulate - Constructor /*{{{*/
43 // ---------------------------------------------------------------------
44 /* The legacy translations here of input Pkg iterators is obsolete,
45 this is not necessary since the pkgCaches are fully shared now. */
46 pkgSimulate::pkgSimulate(pkgDepCache
*Cache
) : pkgPackageManager(Cache
),
48 Sim(&Cache
->GetCache(),&iPolicy
),
52 Flags
= new unsigned char[Cache
->Head().PackageCount
];
53 memset(Flags
,0,sizeof(*Flags
)*Cache
->Head().PackageCount
);
55 // Fake a filename so as not to activate the media swapping
56 string Jnk
= "SIMULATE";
57 for (unsigned int I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
61 // Simulate::~Simulate - Destructor /*{{{*/
62 pkgSimulate::~pkgSimulate()
67 // Simulate::Describe - Describe a package /*{{{*/
68 // ---------------------------------------------------------------------
69 /* Parameter Current == true displays the current package version,
70 Parameter Candidate == true displays the candidate package version */
71 void pkgSimulate::Describe(PkgIterator Pkg
,ostream
&out
,bool Current
,bool Candidate
)
75 out
<< Pkg
.FullName(true);
79 Ver
= Pkg
.CurrentVer();
80 if (Ver
.end() == false)
81 out
<< " [" << Ver
.VerStr() << ']';
84 if (Candidate
== true)
86 Ver
= Sim
[Pkg
].CandidateVerIter(Sim
);
87 if (Ver
.end() == true)
90 out
<< " (" << Ver
.VerStr() << ' ' << Ver
.RelStr() << ')';
94 // Simulate::Install - Simulate unpacking of a package /*{{{*/
95 // ---------------------------------------------------------------------
97 bool pkgSimulate::Install(PkgIterator iPkg
,string
/*File*/)
100 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name(), iPkg
.Arch());
104 Describe(Pkg
,cout
,true,true);
105 Sim
.MarkInstall(Pkg
,false);
107 // Look for broken conflicts+predepends.
108 for (PkgIterator I
= Sim
.PkgBegin(); I
.end() == false; ++I
)
110 if (Sim
[I
].InstallVer
== 0)
113 for (DepIterator D
= Sim
[I
].InstVerIter(Sim
).DependsList(); D
.end() == false;)
118 if (Start
.IsNegative() == true ||
119 End
->Type
== pkgCache::Dep::PreDepends
)
121 if ((Sim
[End
] & pkgDepCache::DepGInstall
) == 0)
123 cout
<< " [" << I
.FullName(false) << " on " << Start
.TargetPkg().FullName(false) << ']';
124 if (Start
->Type
== pkgCache::Dep::Conflicts
)
125 _error
->Error("Fatal, conflicts violated %s",I
.FullName(false).c_str());
131 if (Sim
.BrokenCount() != 0)
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
143 bool pkgSimulate::Configure(PkgIterator iPkg
)
145 // Adapt the iterator
146 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name(), iPkg
.Arch());
150 if (Sim
[Pkg
].InstBroken() == true)
152 cout
<< "Conf " << Pkg
.FullName(false) << " broken" << endl
;
156 // Print out each package and the failed dependencies
157 for (pkgCache::DepIterator D
= Sim
[Pkg
].InstVerIter(Sim
).DependsList(); D
.end() == false; ++D
)
159 if (Sim
.IsImportantDep(D
) == false ||
160 (Sim
[D
] & pkgDepCache::DepInstall
) != 0)
163 if (D
->Type
== pkgCache::Dep::Obsoletes
)
164 cout
<< " Obsoletes:" << D
.TargetPkg().FullName(false);
165 else if (D
->Type
== pkgCache::Dep::Conflicts
)
166 cout
<< " Conflicts:" << D
.TargetPkg().FullName(false);
167 else if (D
->Type
== pkgCache::Dep::DpkgBreaks
)
168 cout
<< " Breaks:" << D
.TargetPkg().FullName(false);
170 cout
<< " Depends:" << D
.TargetPkg().FullName(false);
174 _error
->Error("Conf Broken %s",Pkg
.FullName(false).c_str());
179 Describe(Pkg
,cout
,false,true);
182 if (Sim
.BrokenCount() != 0)
190 // Simulate::Remove - Simulate the removal of a package /*{{{*/
191 // ---------------------------------------------------------------------
193 bool pkgSimulate::Remove(PkgIterator iPkg
,bool Purge
)
195 // Adapt the iterator
196 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name(), iPkg
.Arch());
205 Describe(Pkg
,cout
,true,false);
207 if (Sim
.BrokenCount() != 0)
215 // Simulate::ShortBreaks - Print out a short line describing all breaks /*{{{*/
216 // ---------------------------------------------------------------------
218 void pkgSimulate::ShortBreaks()
221 for (PkgIterator I
= Sim
.PkgBegin(); I
.end() == false; ++I
)
223 if (Sim
[I
].InstBroken() == true)
225 if (Flags
[I
->ID
] == 0)
226 cout
<< I
.FullName(false) << ' ';
228 cout << I.Name() << "! ";*/
234 // ApplyStatus - Adjust for non-ok packages /*{{{*/
235 // ---------------------------------------------------------------------
236 /* We attempt to change the state of the all packages that have failed
237 installation toward their real state. The ordering code will perform
238 the necessary calculations to deal with the problems. */
239 bool pkgApplyStatus(pkgDepCache
&Cache
)
241 pkgDepCache::ActionGroup
group(Cache
);
243 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
245 if (I
->VersionList
== 0)
248 // Only choice for a ReInstReq package is to reinstall
249 if (I
->InstState
== pkgCache::State::ReInstReq
||
250 I
->InstState
== pkgCache::State::HoldReInstReq
)
252 if (I
->CurrentVer
!= 0 && I
.CurrentVer().Downloadable() == true)
253 Cache
.MarkKeep(I
, false, false);
256 // Is this right? Will dpkg choke on an upgrade?
257 if (Cache
[I
].CandidateVer
!= 0 &&
258 Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true)
259 Cache
.MarkInstall(I
, false, 0, false);
261 return _error
->Error(_("The package %s needs to be reinstalled, "
262 "but I can't find an archive for it."),I
.FullName(true).c_str());
268 switch (I
->CurrentState
)
270 /* This means installation failed somehow - it does not need to be
271 re-unpacked (probably) */
272 case pkgCache::State::UnPacked
:
273 case pkgCache::State::HalfConfigured
:
274 case pkgCache::State::TriggersAwaited
:
275 case pkgCache::State::TriggersPending
:
276 if ((I
->CurrentVer
!= 0 && I
.CurrentVer().Downloadable() == true) ||
277 I
.State() != pkgCache::PkgIterator::NeedsUnpack
)
278 Cache
.MarkKeep(I
, false, false);
281 if (Cache
[I
].CandidateVer
!= 0 &&
282 Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true)
283 Cache
.MarkInstall(I
, true, 0, false);
289 // This means removal failed
290 case pkgCache::State::HalfInstalled
:
295 if (I
->InstState
!= pkgCache::State::Ok
)
296 return _error
->Error("The package %s is not ok and I "
297 "don't know how to fix it!",I
.FullName(false).c_str());
303 // FixBroken - Fix broken packages /*{{{*/
304 // ---------------------------------------------------------------------
305 /* This autoinstalls every broken package and then runs the problem resolver
307 bool pkgFixBroken(pkgDepCache
&Cache
)
309 pkgDepCache::ActionGroup
group(Cache
);
311 // Auto upgrade all broken packages
312 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
313 if (Cache
[I
].NowBroken() == true)
314 Cache
.MarkInstall(I
, true, 0, false);
316 /* Fix packages that are in a NeedArchive state but don't have a
317 downloadable install version */
318 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
320 if (I
.State() != pkgCache::PkgIterator::NeedsUnpack
||
321 Cache
[I
].Delete() == true)
324 if (Cache
[I
].InstVerIter(Cache
).Downloadable() == false)
327 Cache
.MarkInstall(I
, true, 0, false);
330 pkgProblemResolver
Fix(&Cache
);
331 return Fix
.Resolve(true);
334 // DistUpgrade - Distribution upgrade /*{{{*/
335 // ---------------------------------------------------------------------
336 /* This autoinstalls every package and then force installs every
337 pre-existing package. This creates the initial set of conditions which
338 most likely contain problems because too many things were installed.
340 The problem resolver is used to resolve the problems.
342 bool pkgDistUpgrade(pkgDepCache
&Cache
)
344 std::string
const solver
= _config
->Find("APT::Solver", "internal");
345 if (solver
!= "internal") {
346 OpTextProgress
Prog(*_config
);
347 return EDSP::ResolveExternal(solver
.c_str(), Cache
, false, true, false, &Prog
);
350 pkgDepCache::ActionGroup
group(Cache
);
352 /* Upgrade all installed packages first without autoinst to help the resolver
353 in versioned or-groups to upgrade the old solver instead of installing
354 a new one (if the old solver is not the first one [anymore]) */
355 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
356 if (I
->CurrentVer
!= 0)
357 Cache
.MarkInstall(I
, false, 0, false);
359 /* Auto upgrade all installed packages, this provides the basis
360 for the installation */
361 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
362 if (I
->CurrentVer
!= 0)
363 Cache
.MarkInstall(I
, true, 0, false);
365 /* Now, auto upgrade all essential packages - this ensures that
366 the essential packages are present and working */
367 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
368 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
369 Cache
.MarkInstall(I
, true, 0, false);
371 /* We do it again over all previously installed packages to force
372 conflict resolution on them all. */
373 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
374 if (I
->CurrentVer
!= 0)
375 Cache
.MarkInstall(I
, false, 0, false);
377 pkgProblemResolver
Fix(&Cache
);
379 // Hold back held packages.
380 if (_config
->FindB("APT::Ignore-Hold",false) == false)
382 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
384 if (I
->SelectedState
== pkgCache::State::Hold
)
387 Cache
.MarkKeep(I
, false, false);
392 return Fix
.Resolve();
395 // AllUpgrade - Upgrade as many packages as possible /*{{{*/
396 // ---------------------------------------------------------------------
397 /* Right now the system must be consistent before this can be called.
398 It also will not change packages marked for install, it only tries
399 to install packages not marked for install */
400 bool pkgAllUpgrade(pkgDepCache
&Cache
)
402 std::string
const solver
= _config
->Find("APT::Solver", "internal");
403 if (solver
!= "internal") {
404 OpTextProgress
Prog(*_config
);
405 return EDSP::ResolveExternal(solver
.c_str(), Cache
, true, false, false, &Prog
);
408 pkgDepCache::ActionGroup
group(Cache
);
410 pkgProblemResolver
Fix(&Cache
);
412 if (Cache
.BrokenCount() != 0)
415 // Upgrade all installed packages
416 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
418 if (Cache
[I
].Install() == true)
421 if (_config
->FindB("APT::Ignore-Hold",false) == false)
422 if (I
->SelectedState
== pkgCache::State::Hold
)
425 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
426 Cache
.MarkInstall(I
, false, 0, false);
429 return Fix
.ResolveByKeep();
432 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
433 // ---------------------------------------------------------------------
434 /* This simply goes over the entire set of packages and tries to keep
435 each package marked for upgrade. If a conflict is generated then
436 the package is restored. */
437 bool pkgMinimizeUpgrade(pkgDepCache
&Cache
)
439 pkgDepCache::ActionGroup
group(Cache
);
441 if (Cache
.BrokenCount() != 0)
444 // We loop for 10 tries to get the minimal set size.
446 unsigned int Count
= 0;
450 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
453 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
456 // Keep it and see if that is OK
457 Cache
.MarkKeep(I
, false, false);
458 if (Cache
.BrokenCount() != 0)
459 Cache
.MarkInstall(I
, false, 0, false);
462 // If keep didnt actually do anything then there was no change..
463 if (Cache
[I
].Upgrade() == false)
469 while (Change
== true && Count
< 10);
471 if (Cache
.BrokenCount() != 0)
472 return _error
->Error("Internal Error in pkgMinimizeUpgrade");
477 // ProblemResolver::pkgProblemResolver - Constructor /*{{{*/
478 // ---------------------------------------------------------------------
480 pkgProblemResolver::pkgProblemResolver(pkgDepCache
*pCache
) : d(NULL
), Cache(*pCache
)
483 unsigned long Size
= Cache
.Head().PackageCount
;
484 Scores
= new int[Size
];
485 Flags
= new unsigned char[Size
];
486 memset(Flags
,0,sizeof(*Flags
)*Size
);
488 // Set debug to true to see its decision logic
489 Debug
= _config
->FindB("Debug::pkgProblemResolver",false);
492 // ProblemResolver::~pkgProblemResolver - Destructor /*{{{*/
493 // ---------------------------------------------------------------------
495 pkgProblemResolver::~pkgProblemResolver()
501 // ProblemResolver::ScoreSort - Sort the list by score /*{{{*/
502 // ---------------------------------------------------------------------
504 int pkgProblemResolver::ScoreSort(const void *a
,const void *b
)
506 Package
const **A
= (Package
const **)a
;
507 Package
const **B
= (Package
const **)b
;
508 if (This
->Scores
[(*A
)->ID
] > This
->Scores
[(*B
)->ID
])
510 if (This
->Scores
[(*A
)->ID
] < This
->Scores
[(*B
)->ID
])
515 // ProblemResolver::MakeScores - Make the score table /*{{{*/
516 // ---------------------------------------------------------------------
518 void pkgProblemResolver::MakeScores()
520 unsigned long Size
= Cache
.Head().PackageCount
;
521 memset(Scores
,0,sizeof(*Scores
)*Size
);
523 // Important Required Standard Optional Extra
526 _config
->FindI("pkgProblemResolver::Scores::Important",3),
527 _config
->FindI("pkgProblemResolver::Scores::Required",2),
528 _config
->FindI("pkgProblemResolver::Scores::Standard",1),
529 _config
->FindI("pkgProblemResolver::Scores::Optional",-1),
530 _config
->FindI("pkgProblemResolver::Scores::Extra",-2)
532 int PrioEssentials
= _config
->FindI("pkgProblemResolver::Scores::Essentials",100);
533 int PrioInstalledAndNotObsolete
= _config
->FindI("pkgProblemResolver::Scores::NotObsolete",1);
534 int PrioDepends
= _config
->FindI("pkgProblemResolver::Scores::Depends",1);
535 int PrioRecommends
= _config
->FindI("pkgProblemResolver::Scores::Recommends",1);
536 int AddProtected
= _config
->FindI("pkgProblemResolver::Scores::AddProtected",10000);
537 int AddEssential
= _config
->FindI("pkgProblemResolver::Scores::AddEssential",5000);
539 if (_config
->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
540 clog
<< "Settings used to calculate pkgProblemResolver::Scores::" << endl
541 << " Important => " << PrioMap
[1] << endl
542 << " Required => " << PrioMap
[2] << endl
543 << " Standard => " << PrioMap
[3] << endl
544 << " Optional => " << PrioMap
[4] << endl
545 << " Extra => " << PrioMap
[5] << endl
546 << " Essentials => " << PrioEssentials
<< endl
547 << " InstalledAndNotObsolete => " << PrioInstalledAndNotObsolete
<< endl
548 << " Depends => " << PrioDepends
<< endl
549 << " Recommends => " << PrioRecommends
<< endl
550 << " AddProtected => " << AddProtected
<< endl
551 << " AddEssential => " << AddEssential
<< endl
;
553 // Generate the base scores for a package based on its properties
554 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
556 if (Cache
[I
].InstallVer
== 0)
559 int &Score
= Scores
[I
->ID
];
561 /* This is arbitrary, it should be high enough to elevate an
562 essantial package above most other packages but low enough
563 to allow an obsolete essential packages to be removed by
564 a conflicts on a powerfull normal package (ie libc6) */
565 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
566 || (I
->Flags
& pkgCache::Flag::Important
) == pkgCache::Flag::Important
)
567 Score
+= PrioEssentials
;
569 // We transform the priority
570 if (Cache
[I
].InstVerIter(Cache
)->Priority
<= 5)
571 Score
+= PrioMap
[Cache
[I
].InstVerIter(Cache
)->Priority
];
573 /* This helps to fix oddball problems with conflicting packages
574 on the same level. We enhance the score of installed packages
575 if those are not obsolete
577 if (I
->CurrentVer
!= 0 && Cache
[I
].CandidateVer
!= 0 && Cache
[I
].CandidateVerIter(Cache
).Downloadable())
578 Score
+= PrioInstalledAndNotObsolete
;
581 // Now that we have the base scores we go and propogate dependencies
582 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
584 if (Cache
[I
].InstallVer
== 0)
587 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false; ++D
)
589 if (D
->Type
== pkgCache::Dep::Depends
||
590 D
->Type
== pkgCache::Dep::PreDepends
)
591 Scores
[D
.TargetPkg()->ID
] += PrioDepends
;
592 else if (D
->Type
== pkgCache::Dep::Recommends
)
593 Scores
[D
.TargetPkg()->ID
] += PrioRecommends
;
597 // Copy the scores to advoid additive looping
598 SPtrArray
<int> OldScores
= new int[Size
];
599 memcpy(OldScores
,Scores
,sizeof(*Scores
)*Size
);
601 /* Now we cause 1 level of dependency inheritance, that is we add the
602 score of the packages that depend on the target Package. This
603 fortifies high scoring packages */
604 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
606 if (Cache
[I
].InstallVer
== 0)
609 for (pkgCache::DepIterator D
= I
.RevDependsList(); D
.end() == false; ++D
)
611 // Only do it for the install version
612 if ((pkgCache::Version
*)D
.ParentVer() != Cache
[D
.ParentPkg()].InstallVer
||
613 (D
->Type
!= pkgCache::Dep::Depends
&&
614 D
->Type
!= pkgCache::Dep::PreDepends
&&
615 D
->Type
!= pkgCache::Dep::Recommends
))
618 Scores
[I
->ID
] += abs(OldScores
[D
.ParentPkg()->ID
]);
622 /* Now we propogate along provides. This makes the packages that
623 provide important packages extremely important */
624 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
626 for (pkgCache::PrvIterator P
= I
.ProvidesList(); P
.end() == false; ++P
)
628 // Only do it once per package
629 if ((pkgCache::Version
*)P
.OwnerVer() != Cache
[P
.OwnerPkg()].InstallVer
)
631 Scores
[P
.OwnerPkg()->ID
] += abs(Scores
[I
->ID
] - OldScores
[I
->ID
]);
635 /* Protected things are pushed really high up. This number should put them
636 ahead of everything */
637 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
639 if ((Flags
[I
->ID
] & Protected
) != 0)
640 Scores
[I
->ID
] += AddProtected
;
641 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
||
642 (I
->Flags
& pkgCache::Flag::Important
) == pkgCache::Flag::Important
)
643 Scores
[I
->ID
] += AddEssential
;
647 // ProblemResolver::DoUpgrade - Attempt to upgrade this package /*{{{*/
648 // ---------------------------------------------------------------------
649 /* This goes through and tries to reinstall packages to make this package
651 bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg
)
653 pkgDepCache::ActionGroup
group(Cache
);
655 if ((Flags
[Pkg
->ID
] & Upgradable
) == 0 || Cache
[Pkg
].Upgradable() == false)
657 if ((Flags
[Pkg
->ID
] & Protected
) == Protected
)
660 Flags
[Pkg
->ID
] &= ~Upgradable
;
662 bool WasKept
= Cache
[Pkg
].Keep();
663 Cache
.MarkInstall(Pkg
, false, 0, false);
665 // This must be a virtual package or something like that.
666 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
669 // Isolate the problem dependency
671 for (pkgCache::DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
673 // Compute a single dependency element (glob or)
674 pkgCache::DepIterator Start
= D
;
675 pkgCache::DepIterator End
= D
;
676 for (bool LastOR
= true; D
.end() == false && LastOR
== true;)
678 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
684 // We only worry about critical deps.
685 if (End
.IsCritical() != true)
688 // Iterate over all the members in the or group
692 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
695 // Do not change protected packages
696 PkgIterator P
= Start
.SmartTargetPkg();
697 if ((Flags
[P
->ID
] & Protected
) == Protected
)
700 clog
<< " Reinst Failed because of protected " << P
.FullName(false) << endl
;
705 // Upgrade the package if the candidate version will fix the problem.
706 if ((Cache
[Start
] & pkgDepCache::DepCVer
) == pkgDepCache::DepCVer
)
708 if (DoUpgrade(P
) == false)
711 clog
<< " Reinst Failed because of " << P
.FullName(false) << endl
;
722 /* We let the algorithm deal with conflicts on its next iteration,
723 it is much smarter than us */
724 if (Start
.IsNegative() == true)
728 clog
<< " Reinst Failed early because of " << Start
.TargetPkg().FullName(false) << endl
;
741 // Undo our operations - it might be smart to undo everything this did..
745 Cache
.MarkKeep(Pkg
, false, false);
747 Cache
.MarkDelete(Pkg
);
752 clog
<< " Re-Instated " << Pkg
.FullName(false) << endl
;
756 // ProblemResolver::Resolve - calls a resolver to fix the situation /*{{{*/
757 // ---------------------------------------------------------------------
759 bool pkgProblemResolver::Resolve(bool BrokenFix
)
761 std::string
const solver
= _config
->Find("APT::Solver", "internal");
762 if (solver
!= "internal") {
763 OpTextProgress
Prog(*_config
);
764 return EDSP::ResolveExternal(solver
.c_str(), Cache
, false, false, false, &Prog
);
766 return ResolveInternal(BrokenFix
);
769 // ProblemResolver::ResolveInternal - Run the resolution pass /*{{{*/
770 // ---------------------------------------------------------------------
771 /* This routines works by calculating a score for each package. The score
772 is derived by considering the package's priority and all reverse
773 dependents giving an integer that reflects the amount of breakage that
774 adjusting the package will inflict.
776 It goes from highest score to lowest and corrects all of the breaks by
777 keeping or removing the dependant packages. If that fails then it removes
778 the package itself and goes on. The routine should be able to intelligently
779 go from any broken state to a fixed state.
781 The BrokenFix flag enables a mode where the algorithm tries to
782 upgrade packages to advoid problems. */
783 bool pkgProblemResolver::ResolveInternal(bool const BrokenFix
)
785 pkgDepCache::ActionGroup
group(Cache
);
787 // Record which packages are marked for install
792 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
794 if (Cache
[I
].Install() == true)
795 Flags
[I
->ID
] |= PreInstalled
;
798 if (Cache
[I
].InstBroken() == true && BrokenFix
== true)
800 Cache
.MarkInstall(I
, false, 0, false);
801 if (Cache
[I
].Install() == true)
805 Flags
[I
->ID
] &= ~PreInstalled
;
807 Flags
[I
->ID
] |= Upgradable
;
810 while (Again
== true);
813 clog
<< "Starting" << endl
;
817 unsigned long const Size
= Cache
.Head().PackageCount
;
819 /* We have to order the packages so that the broken fixing pass
820 operates from highest score to lowest. This prevents problems when
821 high score packages cause the removal of lower score packages that
822 would cause the removal of even lower score packages. */
823 SPtrArray
<pkgCache::Package
*> PList
= new pkgCache::Package
*[Size
];
824 pkgCache::Package
**PEnd
= PList
;
825 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
828 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
830 if (_config
->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
832 clog
<< "Show Scores" << endl
;
833 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
834 if (Scores
[(*K
)->ID
] != 0)
836 pkgCache::PkgIterator
Pkg(Cache
,*K
);
837 clog
<< Scores
[(*K
)->ID
] << ' ' << Pkg
<< std::endl
;
842 clog
<< "Starting 2" << endl
;
844 /* Now consider all broken packages. For each broken package we either
845 remove the package or fix it's problem. We do this once, it should
846 not be possible for a loop to form (that is a < b < c and fixing b by
847 changing a breaks c) */
849 bool const TryFixByInstall
= _config
->FindB("pkgProblemResolver::FixByInstall", true);
850 for (int Counter
= 0; Counter
!= 10 && Change
== true; Counter
++)
853 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
855 pkgCache::PkgIterator
I(Cache
,*K
);
857 /* We attempt to install this and see if any breaks result,
858 this takes care of some strange cases */
859 if (Cache
[I
].CandidateVer
!= Cache
[I
].InstallVer
&&
860 I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0 &&
861 (Flags
[I
->ID
] & PreInstalled
) != 0 &&
862 (Flags
[I
->ID
] & Protected
) == 0 &&
863 (Flags
[I
->ID
] & ReInstateTried
) == 0)
866 clog
<< " Try to Re-Instate (" << Counter
<< ") " << I
.FullName(false) << endl
;
867 unsigned long OldBreaks
= Cache
.BrokenCount();
868 pkgCache::Version
*OldVer
= Cache
[I
].InstallVer
;
869 Flags
[I
->ID
] &= ReInstateTried
;
871 Cache
.MarkInstall(I
, false, 0, false);
872 if (Cache
[I
].InstBroken() == true ||
873 OldBreaks
< Cache
.BrokenCount())
878 Cache
.MarkKeep(I
, false, false);
882 clog
<< "Re-Instated " << I
.FullName(false) << " (" << OldBreaks
<< " vs " << Cache
.BrokenCount() << ')' << endl
;
885 if (Cache
[I
].InstallVer
== 0 || Cache
[I
].InstBroken() == false)
889 clog
<< "Investigating (" << Counter
<< ") " << I
<< endl
;
891 // Isolate the problem dependency
892 PackageKill KillList
[100];
893 PackageKill
*LEnd
= KillList
;
895 pkgCache::DepIterator Start
;
896 pkgCache::DepIterator End
;
897 PackageKill
*OldEnd
= LEnd
;
899 enum {OrRemove
,OrKeep
} OrOp
= OrRemove
;
900 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList();
901 D
.end() == false || InOr
== true;)
903 // Compute a single dependency element (glob or)
907 if (InOr
== true && OldEnd
== LEnd
)
909 if (OrOp
== OrRemove
)
911 if ((Flags
[I
->ID
] & Protected
) != Protected
)
914 clog
<< " Or group remove for " << I
.FullName(false) << endl
;
919 else if (OrOp
== OrKeep
)
922 clog
<< " Or group keep for " << I
.FullName(false) << endl
;
923 Cache
.MarkKeep(I
, false, false);
928 /* We do an extra loop (as above) to finalize the or group
933 if (Start
.end() == true)
936 // We only worry about critical deps.
937 if (End
.IsCritical() != true)
946 // We only worry about critical deps.
947 if (Start
.IsCritical() != true)
952 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
959 clog
<< "Broken " << Start
<< endl
;
961 /* Look across the version list. If there are no possible
962 targets then we keep the package and bail. This is necessary
963 if a package has a dep on another package that cant be found */
964 SPtrArray
<pkgCache::Version
*> VList
= Start
.AllTargets();
965 if (*VList
== 0 && (Flags
[I
->ID
] & Protected
) != Protected
&&
966 Start
.IsNegative() == false &&
967 Cache
[I
].NowBroken() == false)
971 /* No keep choice because the keep being OK could be the
972 result of another element in the OR group! */
977 Cache
.MarkKeep(I
, false, false);
982 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
984 pkgCache::VerIterator
Ver(Cache
,*V
);
985 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
987 /* This is a conflicts, and the version we are looking
988 at is not the currently selected version of the
989 package, which means it is not necessary to
991 if (Cache
[Pkg
].InstallVer
!= Ver
&& Start
.IsNegative() == true)
994 clog
<< " Conflicts//Breaks against version "
995 << Ver
.VerStr() << " for " << Pkg
.Name()
996 << " but that is not InstVer, ignoring"
1002 clog
<< " Considering " << Pkg
.FullName(false) << ' ' << (int)Scores
[Pkg
->ID
] <<
1003 " as a solution to " << I
.FullName(false) << ' ' << (int)Scores
[I
->ID
] << endl
;
1005 /* Try to fix the package under consideration rather than
1006 fiddle with the VList package */
1007 if (Scores
[I
->ID
] <= Scores
[Pkg
->ID
] ||
1008 ((Cache
[Start
] & pkgDepCache::DepNow
) == 0 &&
1009 End
.IsNegative() == false))
1011 // Try a little harder to fix protected packages..
1012 if ((Flags
[I
->ID
] & Protected
) == Protected
)
1014 if (DoUpgrade(Pkg
) == true)
1016 if (Scores
[Pkg
->ID
] > Scores
[I
->ID
])
1017 Scores
[Pkg
->ID
] = Scores
[I
->ID
];
1024 /* See if a keep will do, unless the package is protected,
1025 then installing it will be necessary */
1026 bool Installed
= Cache
[I
].Install();
1027 Cache
.MarkKeep(I
, false, false);
1028 if (Cache
[I
].InstBroken() == false)
1030 // Unwind operation will be keep now
1031 if (OrOp
== OrRemove
)
1035 if (InOr
== true && Installed
== true)
1036 Cache
.MarkInstall(I
, false, 0, false);
1039 clog
<< " Holding Back " << I
.FullName(false) << " rather than change " << Start
.TargetPkg().FullName(false) << endl
;
1043 if (BrokenFix
== false || DoUpgrade(I
) == false)
1045 // Consider other options
1046 if (InOr
== false || Cache
[I
].Garbage
== true)
1049 clog
<< " Removing " << I
.FullName(false) << " rather than change " << Start
.TargetPkg().FullName(false) << endl
;
1050 Cache
.MarkDelete(I
);
1051 if (Counter
> 1 && Scores
[Pkg
->ID
] > Scores
[I
->ID
])
1052 Scores
[I
->ID
] = Scores
[Pkg
->ID
];
1054 else if (TryFixByInstall
== true &&
1055 Start
.TargetPkg()->CurrentVer
== 0 &&
1056 Cache
[Start
.TargetPkg()].Delete() == false &&
1057 (Flags
[Start
.TargetPkg()->ID
] & ToRemove
) != ToRemove
&&
1058 Cache
.GetCandidateVer(Start
.TargetPkg()).end() == false)
1060 /* Before removing or keeping the package with the broken dependency
1061 try instead to install the first not previously installed package
1062 solving this dependency. This helps every time a previous solver
1063 is removed by the resolver because of a conflict or alike but it is
1064 dangerous as it could trigger new breaks/conflicts… */
1066 clog
<< " Try Installing " << Start
.TargetPkg() << " before changing " << I
.FullName(false) << std::endl
;
1067 unsigned long const OldBroken
= Cache
.BrokenCount();
1068 Cache
.MarkInstall(Start
.TargetPkg(), true, 1, false);
1069 // FIXME: we should undo the complete MarkInstall process here
1070 if (Cache
[Start
.TargetPkg()].InstBroken() == true || Cache
.BrokenCount() > OldBroken
)
1071 Cache
.MarkDelete(Start
.TargetPkg(), false, 1, false);
1082 if (Start
->Type
== pkgCache::Dep::DpkgBreaks
)
1084 // first, try upgradring the package, if that
1085 // does not help, the breaks goes onto the
1088 // FIXME: use DoUpgrade(Pkg) instead?
1089 if (Cache
[End
] & pkgDepCache::DepGCVer
)
1092 clog
<< " Upgrading " << Pkg
.FullName(false) << " due to Breaks field in " << I
.FullName(false) << endl
;
1093 Cache
.MarkInstall(Pkg
, false, 0, false);
1098 // Skip adding to the kill list if it is protected
1099 if ((Flags
[Pkg
->ID
] & Protected
) != 0)
1103 clog
<< " Added " << Pkg
.FullName(false) << " to the remove list" << endl
;
1109 if (Start
.IsNegative() == false)
1114 // Hm, nothing can possibly satisify this dep. Nuke it.
1115 if (VList
[0] == 0 &&
1116 Start
.IsNegative() == false &&
1117 (Flags
[I
->ID
] & Protected
) != Protected
)
1119 bool Installed
= Cache
[I
].Install();
1121 if (Cache
[I
].InstBroken() == false)
1123 // Unwind operation will be keep now
1124 if (OrOp
== OrRemove
)
1128 if (InOr
== true && Installed
== true)
1129 Cache
.MarkInstall(I
, false, 0, false);
1132 clog
<< " Holding Back " << I
.FullName(false) << " because I can't find " << Start
.TargetPkg().FullName(false) << endl
;
1137 clog
<< " Removing " << I
.FullName(false) << " because I can't find " << Start
.TargetPkg().FullName(false) << endl
;
1139 Cache
.MarkDelete(I
);
1154 // Apply the kill list now
1155 if (Cache
[I
].InstallVer
!= 0)
1157 for (PackageKill
*J
= KillList
; J
!= LEnd
; J
++)
1160 if ((Cache
[J
->Dep
] & pkgDepCache::DepGNow
) == 0)
1162 if (J
->Dep
.IsNegative() == true)
1165 clog
<< " Fixing " << I
.FullName(false) << " via remove of " << J
->Pkg
.FullName(false) << endl
;
1166 Cache
.MarkDelete(J
->Pkg
);
1172 clog
<< " Fixing " << I
.FullName(false) << " via keep of " << J
->Pkg
.FullName(false) << endl
;
1173 Cache
.MarkKeep(J
->Pkg
, false, false);
1178 if (Scores
[I
->ID
] > Scores
[J
->Pkg
->ID
])
1179 Scores
[J
->Pkg
->ID
] = Scores
[I
->ID
];
1187 clog
<< "Done" << endl
;
1189 if (Cache
.BrokenCount() != 0)
1191 // See if this is the result of a hold
1192 pkgCache::PkgIterator I
= Cache
.PkgBegin();
1193 for (;I
.end() != true; ++I
)
1195 if (Cache
[I
].InstBroken() == false)
1197 if ((Flags
[I
->ID
] & Protected
) != Protected
)
1198 return _error
->Error(_("Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages."));
1200 return _error
->Error(_("Unable to correct problems, you have held broken packages."));
1203 // set the auto-flags (mvo: I'm not sure if we _really_ need this)
1204 pkgCache::PkgIterator I
= Cache
.PkgBegin();
1205 for (;I
.end() != true; ++I
) {
1206 if (Cache
[I
].NewInstall() && !(Flags
[I
->ID
] & PreInstalled
)) {
1207 if(_config
->FindI("Debug::pkgAutoRemove",false)) {
1208 std::clog
<< "Resolve installed new pkg: " << I
.FullName(false)
1209 << " (now marking it as auto)" << std::endl
;
1211 Cache
[I
].Flags
|= pkgCache::Flag::Auto
;
1219 // ProblemResolver::BreaksInstOrPolicy - Check if the given pkg is broken/*{{{*/
1220 // ---------------------------------------------------------------------
1221 /* This checks if the given package is broken either by a hard dependency
1222 (InstBroken()) or by introducing a new policy breakage e.g. new
1223 unsatisfied recommends for a package that was in "policy-good" state
1225 Note that this is not perfect as it will ignore further breakage
1226 for already broken policy (recommends)
1228 bool pkgProblemResolver::InstOrNewPolicyBroken(pkgCache::PkgIterator I
)
1230 // a broken install is always a problem
1231 if (Cache
[I
].InstBroken() == true)
1234 std::clog
<< " Dependencies are not satisfied for " << I
<< std::endl
;
1238 // a newly broken policy (recommends/suggests) is a problem
1239 if (Cache
[I
].NowPolicyBroken() == false &&
1240 Cache
[I
].InstPolicyBroken() == true)
1243 std::clog
<< " Policy breaks with upgrade of " << I
<< std::endl
;
1250 // ProblemResolver::ResolveByKeep - Resolve problems using keep /*{{{*/
1251 // ---------------------------------------------------------------------
1252 /* This is the work horse of the soft upgrade routine. It is very gental
1253 in that it does not install or remove any packages. It is assumed that the
1254 system was non-broken previously. */
1255 bool pkgProblemResolver::ResolveByKeep()
1257 std::string
const solver
= _config
->Find("APT::Solver", "internal");
1258 if (solver
!= "internal") {
1259 OpTextProgress
Prog(*_config
);
1260 return EDSP::ResolveExternal(solver
.c_str(), Cache
, true, false, false, &Prog
);
1262 return ResolveByKeepInternal();
1265 // ProblemResolver::ResolveByKeepInternal - Resolve problems using keep /*{{{*/
1266 // ---------------------------------------------------------------------
1267 /* This is the work horse of the soft upgrade routine. It is very gental
1268 in that it does not install or remove any packages. It is assumed that the
1269 system was non-broken previously. */
1270 bool pkgProblemResolver::ResolveByKeepInternal()
1272 pkgDepCache::ActionGroup
group(Cache
);
1274 unsigned long Size
= Cache
.Head().PackageCount
;
1278 /* We have to order the packages so that the broken fixing pass
1279 operates from highest score to lowest. This prevents problems when
1280 high score packages cause the removal of lower score packages that
1281 would cause the removal of even lower score packages. */
1282 pkgCache::Package
**PList
= new pkgCache::Package
*[Size
];
1283 pkgCache::Package
**PEnd
= PList
;
1284 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
1287 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
1289 if (_config
->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
1291 clog
<< "Show Scores" << endl
;
1292 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
1293 if (Scores
[(*K
)->ID
] != 0)
1295 pkgCache::PkgIterator
Pkg(Cache
,*K
);
1296 clog
<< Scores
[(*K
)->ID
] << ' ' << Pkg
<< std::endl
;
1301 clog
<< "Entering ResolveByKeep" << endl
;
1303 // Consider each broken package
1304 pkgCache::Package
**LastStop
= 0;
1305 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
1307 pkgCache::PkgIterator
I(Cache
,*K
);
1309 if (Cache
[I
].InstallVer
== 0)
1312 if (InstOrNewPolicyBroken(I
) == false)
1315 /* Keep the package. If this works then great, otherwise we have
1316 to be significantly more agressive and manipulate its dependencies */
1317 if ((Flags
[I
->ID
] & Protected
) == 0)
1320 clog
<< "Keeping package " << I
.FullName(false) << endl
;
1321 Cache
.MarkKeep(I
, false, false);
1322 if (InstOrNewPolicyBroken(I
) == false)
1329 // Isolate the problem dependencies
1330 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
1334 D
.GlobOr(Start
,End
);
1336 // We only worry about critical deps.
1337 if (End
.IsCritical() != true)
1341 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
1344 /* Hm, the group is broken.. I suppose the best thing to do is to
1345 is to try every combination of keep/not-keep for the set, but thats
1346 slow, and this never happens, just be conservative and assume the
1347 list of ors is in preference and keep till it starts to work. */
1351 clog
<< "Package " << I
.FullName(false) << " " << Start
<< endl
;
1353 // Look at all the possible provides on this package
1354 SPtrArray
<pkgCache::Version
*> VList
= Start
.AllTargets();
1355 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
1357 pkgCache::VerIterator
Ver(Cache
,*V
);
1358 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
1360 // It is not keepable
1361 if (Cache
[Pkg
].InstallVer
== 0 ||
1362 Pkg
->CurrentVer
== 0)
1365 if ((Flags
[I
->ID
] & Protected
) == 0)
1368 clog
<< " Keeping Package " << Pkg
.FullName(false) << " due to " << Start
.DepType() << endl
;
1369 Cache
.MarkKeep(Pkg
, false, false);
1372 if (InstOrNewPolicyBroken(I
) == false)
1376 if (InstOrNewPolicyBroken(I
) == false)
1384 if (InstOrNewPolicyBroken(I
) == false)
1388 if (InstOrNewPolicyBroken(I
) == true)
1393 return _error
->Error("Internal Error, pkgProblemResolver::ResolveByKeep is looping on package %s.",I
.FullName(false).c_str());
1401 // ProblemResolver::InstallProtect - Install all protected packages /*{{{*/
1402 // ---------------------------------------------------------------------
1403 /* This is used to make sure protected packages are installed */
1404 void pkgProblemResolver::InstallProtect()
1406 pkgDepCache::ActionGroup
group(Cache
);
1408 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
1410 if ((Flags
[I
->ID
] & Protected
) == Protected
)
1412 if ((Flags
[I
->ID
] & ToRemove
) == ToRemove
)
1413 Cache
.MarkDelete(I
);
1416 // preserve the information whether the package was auto
1417 // or manually installed
1418 bool autoInst
= (Cache
[I
].Flags
& pkgCache::Flag::Auto
);
1419 Cache
.MarkInstall(I
, false, 0, !autoInst
);
1425 // PrioSortList - Sort a list of versions by priority /*{{{*/
1426 // ---------------------------------------------------------------------
1427 /* This is ment to be used in conjunction with AllTargets to get a list
1428 of versions ordered by preference. */
1429 static pkgCache
*PrioCache
;
1430 static int PrioComp(const void *A
,const void *B
)
1432 pkgCache::VerIterator
L(*PrioCache
,*(pkgCache::Version
**)A
);
1433 pkgCache::VerIterator
R(*PrioCache
,*(pkgCache::Version
**)B
);
1435 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
&&
1436 (R
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
1438 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
&&
1439 (R
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
1442 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Important
) == pkgCache::Flag::Important
&&
1443 (R
.ParentPkg()->Flags
& pkgCache::Flag::Important
) != pkgCache::Flag::Important
)
1445 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Important
) != pkgCache::Flag::Important
&&
1446 (R
.ParentPkg()->Flags
& pkgCache::Flag::Important
) == pkgCache::Flag::Important
)
1449 if (L
->Priority
!= R
->Priority
)
1450 return R
->Priority
- L
->Priority
;
1451 return strcmp(L
.ParentPkg().Name(),R
.ParentPkg().Name());
1453 void pkgPrioSortList(pkgCache
&Cache
,pkgCache::Version
**List
)
1455 unsigned long Count
= 0;
1457 for (pkgCache::Version
**I
= List
; *I
!= 0; I
++)
1459 qsort(List
,Count
,sizeof(*List
),PrioComp
);
1462 // ListUpdate - construct Fetcher and update the cache files /*{{{*/
1463 // ---------------------------------------------------------------------
1464 /* This is a simple wrapper to update the cache. it will fetch stuff
1465 * from the network (or any other sources defined in sources.list)
1467 bool ListUpdate(pkgAcquireStatus
&Stat
,
1468 pkgSourceList
&List
,
1472 if (Fetcher
.Setup(&Stat
, _config
->FindDir("Dir::State::Lists")) == false)
1475 // Populate it with the source selection
1476 if (List
.GetIndexes(&Fetcher
) == false)
1479 return AcquireUpdate(Fetcher
, PulseInterval
, true);
1482 // AcquireUpdate - take Fetcher and update the cache files /*{{{*/
1483 // ---------------------------------------------------------------------
1484 /* This is a simple wrapper to update the cache with a provided acquire
1485 * If you only need control over Status and the used SourcesList use
1486 * ListUpdate method instead.
1488 bool AcquireUpdate(pkgAcquire
&Fetcher
, int const PulseInterval
,
1489 bool const RunUpdateScripts
, bool const ListCleanup
)
1492 if (RunUpdateScripts
== true)
1493 RunScripts("APT::Update::Pre-Invoke");
1495 pkgAcquire::RunResult res
;
1496 if(PulseInterval
> 0)
1497 res
= Fetcher
.Run(PulseInterval
);
1499 res
= Fetcher
.Run();
1501 if (res
== pkgAcquire::Failed
)
1504 bool Failed
= false;
1505 bool TransientNetworkFailure
= false;
1506 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin();
1507 I
!= Fetcher
.ItemsEnd(); ++I
)
1509 if ((*I
)->Status
== pkgAcquire::Item::StatDone
)
1514 ::URI
uri((*I
)->DescURI());
1516 uri
.Password
.clear();
1517 string descUri
= string(uri
);
1518 _error
->Warning(_("Failed to fetch %s %s\n"), descUri
.c_str(),
1519 (*I
)->ErrorText
.c_str());
1521 if ((*I
)->Status
== pkgAcquire::Item::StatTransientNetworkError
)
1523 TransientNetworkFailure
= true;
1530 // Clean out any old list files
1531 // Keep "APT::Get::List-Cleanup" name for compatibility, but
1532 // this is really a global option for the APT library now
1533 if (!TransientNetworkFailure
&& !Failed
&& ListCleanup
== true &&
1534 (_config
->FindB("APT::Get::List-Cleanup",true) == true &&
1535 _config
->FindB("APT::List-Cleanup",true) == true))
1537 if (Fetcher
.Clean(_config
->FindDir("Dir::State::lists")) == false ||
1538 Fetcher
.Clean(_config
->FindDir("Dir::State::lists") + "partial/") == false)
1539 // something went wrong with the clean
1543 if (TransientNetworkFailure
== true)
1544 _error
->Warning(_("Some index files failed to download. They have been ignored, or old ones used instead."));
1545 else if (Failed
== true)
1546 return _error
->Error(_("Some index files failed to download. They have been ignored, or old ones used instead."));
1549 // Run the success scripts if all was fine
1550 if (RunUpdateScripts
== true)
1552 if(!TransientNetworkFailure
&& !Failed
)
1553 RunScripts("APT::Update::Post-Invoke-Success");
1555 // Run the other scripts
1556 RunScripts("APT::Update::Post-Invoke");