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, install each essential package which is not installed
366 (and not provided by another package in the same name group) */
367 std::string essential
= _config
->Find("pkgCacheGen::Essential", "all");
368 if (essential
== "all")
370 for (pkgCache::GrpIterator G
= Cache
.GrpBegin(); G
.end() == false; ++G
)
372 bool isEssential
= false;
373 bool instEssential
= false;
374 for (pkgCache::PkgIterator P
= G
.PackageList(); P
.end() == false; P
= G
.NextPkg(P
))
376 if ((P
->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
379 if (Cache
[P
].Install() == true)
381 instEssential
= true;
385 if (isEssential
== false || instEssential
== true)
387 pkgCache::PkgIterator P
= G
.FindPreferredPkg();
388 Cache
.MarkInstall(P
, true, 0, false);
391 else if (essential
!= "none")
392 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
393 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
394 Cache
.MarkInstall(I
, true, 0, false);
396 /* We do it again over all previously installed packages to force
397 conflict resolution on them all. */
398 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
399 if (I
->CurrentVer
!= 0)
400 Cache
.MarkInstall(I
, false, 0, false);
402 pkgProblemResolver
Fix(&Cache
);
404 // Hold back held packages.
405 if (_config
->FindB("APT::Ignore-Hold",false) == false)
407 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
409 if (I
->SelectedState
== pkgCache::State::Hold
)
412 Cache
.MarkKeep(I
, false, false);
417 return Fix
.Resolve();
420 // AllUpgrade - Upgrade as many packages as possible /*{{{*/
421 // ---------------------------------------------------------------------
422 /* Right now the system must be consistent before this can be called.
423 It also will not change packages marked for install, it only tries
424 to install packages not marked for install */
425 bool pkgAllUpgrade(pkgDepCache
&Cache
)
427 std::string
const solver
= _config
->Find("APT::Solver", "internal");
428 if (solver
!= "internal") {
429 OpTextProgress
Prog(*_config
);
430 return EDSP::ResolveExternal(solver
.c_str(), Cache
, true, false, false, &Prog
);
433 pkgDepCache::ActionGroup
group(Cache
);
435 pkgProblemResolver
Fix(&Cache
);
437 if (Cache
.BrokenCount() != 0)
440 // Upgrade all installed packages
441 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
443 if (Cache
[I
].Install() == true)
446 if (_config
->FindB("APT::Ignore-Hold",false) == false)
447 if (I
->SelectedState
== pkgCache::State::Hold
)
450 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
451 Cache
.MarkInstall(I
, false, 0, false);
454 return Fix
.ResolveByKeep();
457 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
458 // ---------------------------------------------------------------------
459 /* This simply goes over the entire set of packages and tries to keep
460 each package marked for upgrade. If a conflict is generated then
461 the package is restored. */
462 bool pkgMinimizeUpgrade(pkgDepCache
&Cache
)
464 pkgDepCache::ActionGroup
group(Cache
);
466 if (Cache
.BrokenCount() != 0)
469 // We loop for 10 tries to get the minimal set size.
471 unsigned int Count
= 0;
475 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
478 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
481 // Keep it and see if that is OK
482 Cache
.MarkKeep(I
, false, false);
483 if (Cache
.BrokenCount() != 0)
484 Cache
.MarkInstall(I
, false, 0, false);
487 // If keep didnt actually do anything then there was no change..
488 if (Cache
[I
].Upgrade() == false)
494 while (Change
== true && Count
< 10);
496 if (Cache
.BrokenCount() != 0)
497 return _error
->Error("Internal Error in pkgMinimizeUpgrade");
502 // ProblemResolver::pkgProblemResolver - Constructor /*{{{*/
503 // ---------------------------------------------------------------------
505 pkgProblemResolver::pkgProblemResolver(pkgDepCache
*pCache
) : d(NULL
), Cache(*pCache
)
508 unsigned long Size
= Cache
.Head().PackageCount
;
509 Scores
= new int[Size
];
510 Flags
= new unsigned char[Size
];
511 memset(Flags
,0,sizeof(*Flags
)*Size
);
513 // Set debug to true to see its decision logic
514 Debug
= _config
->FindB("Debug::pkgProblemResolver",false);
517 // ProblemResolver::~pkgProblemResolver - Destructor /*{{{*/
518 // ---------------------------------------------------------------------
520 pkgProblemResolver::~pkgProblemResolver()
526 // ProblemResolver::ScoreSort - Sort the list by score /*{{{*/
527 // ---------------------------------------------------------------------
529 int pkgProblemResolver::ScoreSort(const void *a
,const void *b
)
531 Package
const **A
= (Package
const **)a
;
532 Package
const **B
= (Package
const **)b
;
533 if (This
->Scores
[(*A
)->ID
] > This
->Scores
[(*B
)->ID
])
535 if (This
->Scores
[(*A
)->ID
] < This
->Scores
[(*B
)->ID
])
540 // ProblemResolver::MakeScores - Make the score table /*{{{*/
541 // ---------------------------------------------------------------------
543 void pkgProblemResolver::MakeScores()
545 unsigned long Size
= Cache
.Head().PackageCount
;
546 memset(Scores
,0,sizeof(*Scores
)*Size
);
548 // Important Required Standard Optional Extra
551 _config
->FindI("pkgProblemResolver::Scores::Important",3),
552 _config
->FindI("pkgProblemResolver::Scores::Required",2),
553 _config
->FindI("pkgProblemResolver::Scores::Standard",1),
554 _config
->FindI("pkgProblemResolver::Scores::Optional",-1),
555 _config
->FindI("pkgProblemResolver::Scores::Extra",-2)
557 int PrioEssentials
= _config
->FindI("pkgProblemResolver::Scores::Essentials",100);
558 int PrioInstalledAndNotObsolete
= _config
->FindI("pkgProblemResolver::Scores::NotObsolete",1);
559 int PrioDepends
= _config
->FindI("pkgProblemResolver::Scores::Depends",1);
560 int PrioRecommends
= _config
->FindI("pkgProblemResolver::Scores::Recommends",1);
561 int AddProtected
= _config
->FindI("pkgProblemResolver::Scores::AddProtected",10000);
562 int AddEssential
= _config
->FindI("pkgProblemResolver::Scores::AddEssential",5000);
564 if (_config
->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
565 clog
<< "Settings used to calculate pkgProblemResolver::Scores::" << endl
566 << " Important => " << PrioMap
[1] << endl
567 << " Required => " << PrioMap
[2] << endl
568 << " Standard => " << PrioMap
[3] << endl
569 << " Optional => " << PrioMap
[4] << endl
570 << " Extra => " << PrioMap
[5] << endl
571 << " Essentials => " << PrioEssentials
<< endl
572 << " InstalledAndNotObsolete => " << PrioInstalledAndNotObsolete
<< endl
573 << " Depends => " << PrioDepends
<< endl
574 << " Recommends => " << PrioRecommends
<< endl
575 << " AddProtected => " << AddProtected
<< endl
576 << " AddEssential => " << AddEssential
<< endl
;
578 // Generate the base scores for a package based on its properties
579 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
581 if (Cache
[I
].InstallVer
== 0)
584 int &Score
= Scores
[I
->ID
];
586 /* This is arbitrary, it should be high enough to elevate an
587 essantial package above most other packages but low enough
588 to allow an obsolete essential packages to be removed by
589 a conflicts on a powerfull normal package (ie libc6) */
590 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
591 || (I
->Flags
& pkgCache::Flag::Important
) == pkgCache::Flag::Important
)
592 Score
+= PrioEssentials
;
594 // We transform the priority
595 if (Cache
[I
].InstVerIter(Cache
)->Priority
<= 5)
596 Score
+= PrioMap
[Cache
[I
].InstVerIter(Cache
)->Priority
];
598 /* This helps to fix oddball problems with conflicting packages
599 on the same level. We enhance the score of installed packages
600 if those are not obsolete
602 if (I
->CurrentVer
!= 0 && Cache
[I
].CandidateVer
!= 0 && Cache
[I
].CandidateVerIter(Cache
).Downloadable())
603 Score
+= PrioInstalledAndNotObsolete
;
606 // Now that we have the base scores we go and propogate dependencies
607 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
609 if (Cache
[I
].InstallVer
== 0)
612 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false; ++D
)
614 if (D
->Type
== pkgCache::Dep::Depends
||
615 D
->Type
== pkgCache::Dep::PreDepends
)
616 Scores
[D
.TargetPkg()->ID
] += PrioDepends
;
617 else if (D
->Type
== pkgCache::Dep::Recommends
)
618 Scores
[D
.TargetPkg()->ID
] += PrioRecommends
;
622 // Copy the scores to advoid additive looping
623 SPtrArray
<int> OldScores
= new int[Size
];
624 memcpy(OldScores
,Scores
,sizeof(*Scores
)*Size
);
626 /* Now we cause 1 level of dependency inheritance, that is we add the
627 score of the packages that depend on the target Package. This
628 fortifies high scoring packages */
629 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
631 if (Cache
[I
].InstallVer
== 0)
634 for (pkgCache::DepIterator D
= I
.RevDependsList(); D
.end() == false; ++D
)
636 // Only do it for the install version
637 if ((pkgCache::Version
*)D
.ParentVer() != Cache
[D
.ParentPkg()].InstallVer
||
638 (D
->Type
!= pkgCache::Dep::Depends
&&
639 D
->Type
!= pkgCache::Dep::PreDepends
&&
640 D
->Type
!= pkgCache::Dep::Recommends
))
643 Scores
[I
->ID
] += abs(OldScores
[D
.ParentPkg()->ID
]);
647 /* Now we propogate along provides. This makes the packages that
648 provide important packages extremely important */
649 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
651 for (pkgCache::PrvIterator P
= I
.ProvidesList(); P
.end() == false; ++P
)
653 // Only do it once per package
654 if ((pkgCache::Version
*)P
.OwnerVer() != Cache
[P
.OwnerPkg()].InstallVer
)
656 Scores
[P
.OwnerPkg()->ID
] += abs(Scores
[I
->ID
] - OldScores
[I
->ID
]);
660 /* Protected things are pushed really high up. This number should put them
661 ahead of everything */
662 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
664 if ((Flags
[I
->ID
] & Protected
) != 0)
665 Scores
[I
->ID
] += AddProtected
;
666 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
||
667 (I
->Flags
& pkgCache::Flag::Important
) == pkgCache::Flag::Important
)
668 Scores
[I
->ID
] += AddEssential
;
672 // ProblemResolver::DoUpgrade - Attempt to upgrade this package /*{{{*/
673 // ---------------------------------------------------------------------
674 /* This goes through and tries to reinstall packages to make this package
676 bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg
)
678 pkgDepCache::ActionGroup
group(Cache
);
680 if ((Flags
[Pkg
->ID
] & Upgradable
) == 0 || Cache
[Pkg
].Upgradable() == false)
682 if ((Flags
[Pkg
->ID
] & Protected
) == Protected
)
685 Flags
[Pkg
->ID
] &= ~Upgradable
;
687 bool WasKept
= Cache
[Pkg
].Keep();
688 Cache
.MarkInstall(Pkg
, false, 0, false);
690 // This must be a virtual package or something like that.
691 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
694 // Isolate the problem dependency
696 for (pkgCache::DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
698 // Compute a single dependency element (glob or)
699 pkgCache::DepIterator Start
= D
;
700 pkgCache::DepIterator End
= D
;
701 for (bool LastOR
= true; D
.end() == false && LastOR
== true;)
703 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
709 // We only worry about critical deps.
710 if (End
.IsCritical() != true)
713 // Iterate over all the members in the or group
717 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
720 // Do not change protected packages
721 PkgIterator P
= Start
.SmartTargetPkg();
722 if ((Flags
[P
->ID
] & Protected
) == Protected
)
725 clog
<< " Reinst Failed because of protected " << P
.FullName(false) << endl
;
730 // Upgrade the package if the candidate version will fix the problem.
731 if ((Cache
[Start
] & pkgDepCache::DepCVer
) == pkgDepCache::DepCVer
)
733 if (DoUpgrade(P
) == false)
736 clog
<< " Reinst Failed because of " << P
.FullName(false) << endl
;
747 /* We let the algorithm deal with conflicts on its next iteration,
748 it is much smarter than us */
749 if (Start
.IsNegative() == true)
753 clog
<< " Reinst Failed early because of " << Start
.TargetPkg().FullName(false) << endl
;
766 // Undo our operations - it might be smart to undo everything this did..
770 Cache
.MarkKeep(Pkg
, false, false);
772 Cache
.MarkDelete(Pkg
);
777 clog
<< " Re-Instated " << Pkg
.FullName(false) << endl
;
781 // ProblemResolver::Resolve - calls a resolver to fix the situation /*{{{*/
782 // ---------------------------------------------------------------------
784 bool pkgProblemResolver::Resolve(bool BrokenFix
)
786 std::string
const solver
= _config
->Find("APT::Solver", "internal");
787 if (solver
!= "internal") {
788 OpTextProgress
Prog(*_config
);
789 return EDSP::ResolveExternal(solver
.c_str(), Cache
, false, false, false, &Prog
);
791 return ResolveInternal(BrokenFix
);
794 // ProblemResolver::ResolveInternal - Run the resolution pass /*{{{*/
795 // ---------------------------------------------------------------------
796 /* This routines works by calculating a score for each package. The score
797 is derived by considering the package's priority and all reverse
798 dependents giving an integer that reflects the amount of breakage that
799 adjusting the package will inflict.
801 It goes from highest score to lowest and corrects all of the breaks by
802 keeping or removing the dependant packages. If that fails then it removes
803 the package itself and goes on. The routine should be able to intelligently
804 go from any broken state to a fixed state.
806 The BrokenFix flag enables a mode where the algorithm tries to
807 upgrade packages to advoid problems. */
808 bool pkgProblemResolver::ResolveInternal(bool const BrokenFix
)
810 pkgDepCache::ActionGroup
group(Cache
);
812 // Record which packages are marked for install
817 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
819 if (Cache
[I
].Install() == true)
820 Flags
[I
->ID
] |= PreInstalled
;
823 if (Cache
[I
].InstBroken() == true && BrokenFix
== true)
825 Cache
.MarkInstall(I
, false, 0, false);
826 if (Cache
[I
].Install() == true)
830 Flags
[I
->ID
] &= ~PreInstalled
;
832 Flags
[I
->ID
] |= Upgradable
;
835 while (Again
== true);
838 clog
<< "Starting" << endl
;
842 unsigned long const Size
= Cache
.Head().PackageCount
;
844 /* We have to order the packages so that the broken fixing pass
845 operates from highest score to lowest. This prevents problems when
846 high score packages cause the removal of lower score packages that
847 would cause the removal of even lower score packages. */
848 SPtrArray
<pkgCache::Package
*> PList
= new pkgCache::Package
*[Size
];
849 pkgCache::Package
**PEnd
= PList
;
850 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
853 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
855 if (_config
->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
857 clog
<< "Show Scores" << endl
;
858 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
859 if (Scores
[(*K
)->ID
] != 0)
861 pkgCache::PkgIterator
Pkg(Cache
,*K
);
862 clog
<< Scores
[(*K
)->ID
] << ' ' << Pkg
<< std::endl
;
867 clog
<< "Starting 2" << endl
;
869 /* Now consider all broken packages. For each broken package we either
870 remove the package or fix it's problem. We do this once, it should
871 not be possible for a loop to form (that is a < b < c and fixing b by
872 changing a breaks c) */
874 bool const TryFixByInstall
= _config
->FindB("pkgProblemResolver::FixByInstall", true);
875 for (int Counter
= 0; Counter
!= 10 && Change
== true; Counter
++)
878 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
880 pkgCache::PkgIterator
I(Cache
,*K
);
882 /* We attempt to install this and see if any breaks result,
883 this takes care of some strange cases */
884 if (Cache
[I
].CandidateVer
!= Cache
[I
].InstallVer
&&
885 I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0 &&
886 (Flags
[I
->ID
] & PreInstalled
) != 0 &&
887 (Flags
[I
->ID
] & Protected
) == 0 &&
888 (Flags
[I
->ID
] & ReInstateTried
) == 0)
891 clog
<< " Try to Re-Instate (" << Counter
<< ") " << I
.FullName(false) << endl
;
892 unsigned long OldBreaks
= Cache
.BrokenCount();
893 pkgCache::Version
*OldVer
= Cache
[I
].InstallVer
;
894 Flags
[I
->ID
] &= ReInstateTried
;
896 Cache
.MarkInstall(I
, false, 0, false);
897 if (Cache
[I
].InstBroken() == true ||
898 OldBreaks
< Cache
.BrokenCount())
903 Cache
.MarkKeep(I
, false, false);
907 clog
<< "Re-Instated " << I
.FullName(false) << " (" << OldBreaks
<< " vs " << Cache
.BrokenCount() << ')' << endl
;
910 if (Cache
[I
].InstallVer
== 0 || Cache
[I
].InstBroken() == false)
914 clog
<< "Investigating (" << Counter
<< ") " << I
<< endl
;
916 // Isolate the problem dependency
917 PackageKill KillList
[100];
918 PackageKill
*LEnd
= KillList
;
920 pkgCache::DepIterator Start
;
921 pkgCache::DepIterator End
;
922 PackageKill
*OldEnd
= LEnd
;
924 enum {OrRemove
,OrKeep
} OrOp
= OrRemove
;
925 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList();
926 D
.end() == false || InOr
== true;)
928 // Compute a single dependency element (glob or)
932 if (InOr
== true && OldEnd
== LEnd
)
934 if (OrOp
== OrRemove
)
936 if ((Flags
[I
->ID
] & Protected
) != Protected
)
939 clog
<< " Or group remove for " << I
.FullName(false) << endl
;
944 else if (OrOp
== OrKeep
)
947 clog
<< " Or group keep for " << I
.FullName(false) << endl
;
948 Cache
.MarkKeep(I
, false, false);
953 /* We do an extra loop (as above) to finalize the or group
958 if (Start
.end() == true)
961 // We only worry about critical deps.
962 if (End
.IsCritical() != true)
971 // We only worry about critical deps.
972 if (Start
.IsCritical() != true)
977 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
984 clog
<< "Broken " << Start
<< endl
;
986 /* Look across the version list. If there are no possible
987 targets then we keep the package and bail. This is necessary
988 if a package has a dep on another package that cant be found */
989 SPtrArray
<pkgCache::Version
*> VList
= Start
.AllTargets();
990 if (*VList
== 0 && (Flags
[I
->ID
] & Protected
) != Protected
&&
991 Start
.IsNegative() == false &&
992 Cache
[I
].NowBroken() == false)
996 /* No keep choice because the keep being OK could be the
997 result of another element in the OR group! */
1002 Cache
.MarkKeep(I
, false, false);
1007 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
1009 pkgCache::VerIterator
Ver(Cache
,*V
);
1010 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
1012 /* This is a conflicts, and the version we are looking
1013 at is not the currently selected version of the
1014 package, which means it is not necessary to
1016 if (Cache
[Pkg
].InstallVer
!= Ver
&& Start
.IsNegative() == true)
1019 clog
<< " Conflicts//Breaks against version "
1020 << Ver
.VerStr() << " for " << Pkg
.Name()
1021 << " but that is not InstVer, ignoring"
1027 clog
<< " Considering " << Pkg
.FullName(false) << ' ' << (int)Scores
[Pkg
->ID
] <<
1028 " as a solution to " << I
.FullName(false) << ' ' << (int)Scores
[I
->ID
] << endl
;
1030 /* Try to fix the package under consideration rather than
1031 fiddle with the VList package */
1032 if (Scores
[I
->ID
] <= Scores
[Pkg
->ID
] ||
1033 ((Cache
[Start
] & pkgDepCache::DepNow
) == 0 &&
1034 End
.IsNegative() == false))
1036 // Try a little harder to fix protected packages..
1037 if ((Flags
[I
->ID
] & Protected
) == Protected
)
1039 if (DoUpgrade(Pkg
) == true)
1041 if (Scores
[Pkg
->ID
] > Scores
[I
->ID
])
1042 Scores
[Pkg
->ID
] = Scores
[I
->ID
];
1049 /* See if a keep will do, unless the package is protected,
1050 then installing it will be necessary */
1051 bool Installed
= Cache
[I
].Install();
1052 Cache
.MarkKeep(I
, false, false);
1053 if (Cache
[I
].InstBroken() == false)
1055 // Unwind operation will be keep now
1056 if (OrOp
== OrRemove
)
1060 if (InOr
== true && Installed
== true)
1061 Cache
.MarkInstall(I
, false, 0, false);
1064 clog
<< " Holding Back " << I
.FullName(false) << " rather than change " << Start
.TargetPkg().FullName(false) << endl
;
1068 if (BrokenFix
== false || DoUpgrade(I
) == false)
1070 // Consider other options
1071 if (InOr
== false || Cache
[I
].Garbage
== true)
1074 clog
<< " Removing " << I
.FullName(false) << " rather than change " << Start
.TargetPkg().FullName(false) << endl
;
1075 Cache
.MarkDelete(I
);
1076 if (Counter
> 1 && Scores
[Pkg
->ID
] > Scores
[I
->ID
])
1077 Scores
[I
->ID
] = Scores
[Pkg
->ID
];
1079 else if (TryFixByInstall
== true &&
1080 Start
.TargetPkg()->CurrentVer
== 0 &&
1081 Cache
[Start
.TargetPkg()].Delete() == false &&
1082 (Flags
[Start
.TargetPkg()->ID
] & ToRemove
) != ToRemove
&&
1083 Cache
.GetCandidateVer(Start
.TargetPkg()).end() == false)
1085 /* Before removing or keeping the package with the broken dependency
1086 try instead to install the first not previously installed package
1087 solving this dependency. This helps every time a previous solver
1088 is removed by the resolver because of a conflict or alike but it is
1089 dangerous as it could trigger new breaks/conflicts… */
1091 clog
<< " Try Installing " << Start
.TargetPkg() << " before changing " << I
.FullName(false) << std::endl
;
1092 unsigned long const OldBroken
= Cache
.BrokenCount();
1093 Cache
.MarkInstall(Start
.TargetPkg(), true, 1, false);
1094 // FIXME: we should undo the complete MarkInstall process here
1095 if (Cache
[Start
.TargetPkg()].InstBroken() == true || Cache
.BrokenCount() > OldBroken
)
1096 Cache
.MarkDelete(Start
.TargetPkg(), false, 1, false);
1107 if (Start
->Type
== pkgCache::Dep::DpkgBreaks
)
1109 // first, try upgradring the package, if that
1110 // does not help, the breaks goes onto the
1113 // FIXME: use DoUpgrade(Pkg) instead?
1114 if (Cache
[End
] & pkgDepCache::DepGCVer
)
1117 clog
<< " Upgrading " << Pkg
.FullName(false) << " due to Breaks field in " << I
.FullName(false) << endl
;
1118 Cache
.MarkInstall(Pkg
, false, 0, false);
1123 // Skip adding to the kill list if it is protected
1124 if ((Flags
[Pkg
->ID
] & Protected
) != 0)
1128 clog
<< " Added " << Pkg
.FullName(false) << " to the remove list" << endl
;
1134 if (Start
.IsNegative() == false)
1139 // Hm, nothing can possibly satisify this dep. Nuke it.
1140 if (VList
[0] == 0 &&
1141 Start
.IsNegative() == false &&
1142 (Flags
[I
->ID
] & Protected
) != Protected
)
1144 bool Installed
= Cache
[I
].Install();
1146 if (Cache
[I
].InstBroken() == false)
1148 // Unwind operation will be keep now
1149 if (OrOp
== OrRemove
)
1153 if (InOr
== true && Installed
== true)
1154 Cache
.MarkInstall(I
, false, 0, false);
1157 clog
<< " Holding Back " << I
.FullName(false) << " because I can't find " << Start
.TargetPkg().FullName(false) << endl
;
1162 clog
<< " Removing " << I
.FullName(false) << " because I can't find " << Start
.TargetPkg().FullName(false) << endl
;
1164 Cache
.MarkDelete(I
);
1179 // Apply the kill list now
1180 if (Cache
[I
].InstallVer
!= 0)
1182 for (PackageKill
*J
= KillList
; J
!= LEnd
; J
++)
1185 if ((Cache
[J
->Dep
] & pkgDepCache::DepGNow
) == 0)
1187 if (J
->Dep
.IsNegative() == true)
1190 clog
<< " Fixing " << I
.FullName(false) << " via remove of " << J
->Pkg
.FullName(false) << endl
;
1191 Cache
.MarkDelete(J
->Pkg
);
1197 clog
<< " Fixing " << I
.FullName(false) << " via keep of " << J
->Pkg
.FullName(false) << endl
;
1198 Cache
.MarkKeep(J
->Pkg
, false, false);
1203 if (Scores
[I
->ID
] > Scores
[J
->Pkg
->ID
])
1204 Scores
[J
->Pkg
->ID
] = Scores
[I
->ID
];
1212 clog
<< "Done" << endl
;
1214 if (Cache
.BrokenCount() != 0)
1216 // See if this is the result of a hold
1217 pkgCache::PkgIterator I
= Cache
.PkgBegin();
1218 for (;I
.end() != true; ++I
)
1220 if (Cache
[I
].InstBroken() == false)
1222 if ((Flags
[I
->ID
] & Protected
) != Protected
)
1223 return _error
->Error(_("Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages."));
1225 return _error
->Error(_("Unable to correct problems, you have held broken packages."));
1228 // set the auto-flags (mvo: I'm not sure if we _really_ need this)
1229 pkgCache::PkgIterator I
= Cache
.PkgBegin();
1230 for (;I
.end() != true; ++I
) {
1231 if (Cache
[I
].NewInstall() && !(Flags
[I
->ID
] & PreInstalled
)) {
1232 if(_config
->FindI("Debug::pkgAutoRemove",false)) {
1233 std::clog
<< "Resolve installed new pkg: " << I
.FullName(false)
1234 << " (now marking it as auto)" << std::endl
;
1236 Cache
[I
].Flags
|= pkgCache::Flag::Auto
;
1244 // ProblemResolver::BreaksInstOrPolicy - Check if the given pkg is broken/*{{{*/
1245 // ---------------------------------------------------------------------
1246 /* This checks if the given package is broken either by a hard dependency
1247 (InstBroken()) or by introducing a new policy breakage e.g. new
1248 unsatisfied recommends for a package that was in "policy-good" state
1250 Note that this is not perfect as it will ignore further breakage
1251 for already broken policy (recommends)
1253 bool pkgProblemResolver::InstOrNewPolicyBroken(pkgCache::PkgIterator I
)
1255 // a broken install is always a problem
1256 if (Cache
[I
].InstBroken() == true)
1259 std::clog
<< " Dependencies are not satisfied for " << I
<< std::endl
;
1263 // a newly broken policy (recommends/suggests) is a problem
1264 if (Cache
[I
].NowPolicyBroken() == false &&
1265 Cache
[I
].InstPolicyBroken() == true)
1268 std::clog
<< " Policy breaks with upgrade of " << I
<< std::endl
;
1275 // ProblemResolver::ResolveByKeep - Resolve problems using keep /*{{{*/
1276 // ---------------------------------------------------------------------
1277 /* This is the work horse of the soft upgrade routine. It is very gental
1278 in that it does not install or remove any packages. It is assumed that the
1279 system was non-broken previously. */
1280 bool pkgProblemResolver::ResolveByKeep()
1282 std::string
const solver
= _config
->Find("APT::Solver", "internal");
1283 if (solver
!= "internal") {
1284 OpTextProgress
Prog(*_config
);
1285 return EDSP::ResolveExternal(solver
.c_str(), Cache
, true, false, false, &Prog
);
1287 return ResolveByKeepInternal();
1290 // ProblemResolver::ResolveByKeepInternal - Resolve problems using keep /*{{{*/
1291 // ---------------------------------------------------------------------
1292 /* This is the work horse of the soft upgrade routine. It is very gental
1293 in that it does not install or remove any packages. It is assumed that the
1294 system was non-broken previously. */
1295 bool pkgProblemResolver::ResolveByKeepInternal()
1297 pkgDepCache::ActionGroup
group(Cache
);
1299 unsigned long Size
= Cache
.Head().PackageCount
;
1303 /* We have to order the packages so that the broken fixing pass
1304 operates from highest score to lowest. This prevents problems when
1305 high score packages cause the removal of lower score packages that
1306 would cause the removal of even lower score packages. */
1307 pkgCache::Package
**PList
= new pkgCache::Package
*[Size
];
1308 pkgCache::Package
**PEnd
= PList
;
1309 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
1312 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
1314 if (_config
->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
1316 clog
<< "Show Scores" << endl
;
1317 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
1318 if (Scores
[(*K
)->ID
] != 0)
1320 pkgCache::PkgIterator
Pkg(Cache
,*K
);
1321 clog
<< Scores
[(*K
)->ID
] << ' ' << Pkg
<< std::endl
;
1326 clog
<< "Entering ResolveByKeep" << endl
;
1328 // Consider each broken package
1329 pkgCache::Package
**LastStop
= 0;
1330 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
1332 pkgCache::PkgIterator
I(Cache
,*K
);
1334 if (Cache
[I
].InstallVer
== 0)
1337 if (InstOrNewPolicyBroken(I
) == false)
1340 /* Keep the package. If this works then great, otherwise we have
1341 to be significantly more agressive and manipulate its dependencies */
1342 if ((Flags
[I
->ID
] & Protected
) == 0)
1345 clog
<< "Keeping package " << I
.FullName(false) << endl
;
1346 Cache
.MarkKeep(I
, false, false);
1347 if (InstOrNewPolicyBroken(I
) == false)
1354 // Isolate the problem dependencies
1355 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
1359 D
.GlobOr(Start
,End
);
1361 // We only worry about critical deps.
1362 if (End
.IsCritical() != true)
1366 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
1369 /* Hm, the group is broken.. I suppose the best thing to do is to
1370 is to try every combination of keep/not-keep for the set, but thats
1371 slow, and this never happens, just be conservative and assume the
1372 list of ors is in preference and keep till it starts to work. */
1376 clog
<< "Package " << I
.FullName(false) << " " << Start
<< endl
;
1378 // Look at all the possible provides on this package
1379 SPtrArray
<pkgCache::Version
*> VList
= Start
.AllTargets();
1380 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
1382 pkgCache::VerIterator
Ver(Cache
,*V
);
1383 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
1385 // It is not keepable
1386 if (Cache
[Pkg
].InstallVer
== 0 ||
1387 Pkg
->CurrentVer
== 0)
1390 if ((Flags
[I
->ID
] & Protected
) == 0)
1393 clog
<< " Keeping Package " << Pkg
.FullName(false) << " due to " << Start
.DepType() << endl
;
1394 Cache
.MarkKeep(Pkg
, false, false);
1397 if (InstOrNewPolicyBroken(I
) == false)
1401 if (InstOrNewPolicyBroken(I
) == false)
1409 if (InstOrNewPolicyBroken(I
) == false)
1413 if (InstOrNewPolicyBroken(I
) == true)
1418 return _error
->Error("Internal Error, pkgProblemResolver::ResolveByKeep is looping on package %s.",I
.FullName(false).c_str());
1426 // ProblemResolver::InstallProtect - Install all protected packages /*{{{*/
1427 // ---------------------------------------------------------------------
1428 /* This is used to make sure protected packages are installed */
1429 void pkgProblemResolver::InstallProtect()
1431 pkgDepCache::ActionGroup
group(Cache
);
1433 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
1435 if ((Flags
[I
->ID
] & Protected
) == Protected
)
1437 if ((Flags
[I
->ID
] & ToRemove
) == ToRemove
)
1438 Cache
.MarkDelete(I
);
1441 // preserve the information whether the package was auto
1442 // or manually installed
1443 bool autoInst
= (Cache
[I
].Flags
& pkgCache::Flag::Auto
);
1444 Cache
.MarkInstall(I
, false, 0, !autoInst
);
1450 // PrioSortList - Sort a list of versions by priority /*{{{*/
1451 // ---------------------------------------------------------------------
1452 /* This is ment to be used in conjunction with AllTargets to get a list
1453 of versions ordered by preference. */
1454 static pkgCache
*PrioCache
;
1455 static int PrioComp(const void *A
,const void *B
)
1457 pkgCache::VerIterator
L(*PrioCache
,*(pkgCache::Version
**)A
);
1458 pkgCache::VerIterator
R(*PrioCache
,*(pkgCache::Version
**)B
);
1460 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
&&
1461 (R
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
1463 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
&&
1464 (R
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
1467 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Important
) == pkgCache::Flag::Important
&&
1468 (R
.ParentPkg()->Flags
& pkgCache::Flag::Important
) != pkgCache::Flag::Important
)
1470 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Important
) != pkgCache::Flag::Important
&&
1471 (R
.ParentPkg()->Flags
& pkgCache::Flag::Important
) == pkgCache::Flag::Important
)
1474 if (L
->Priority
!= R
->Priority
)
1475 return R
->Priority
- L
->Priority
;
1476 return strcmp(L
.ParentPkg().Name(),R
.ParentPkg().Name());
1478 void pkgPrioSortList(pkgCache
&Cache
,pkgCache::Version
**List
)
1480 unsigned long Count
= 0;
1482 for (pkgCache::Version
**I
= List
; *I
!= 0; I
++)
1484 qsort(List
,Count
,sizeof(*List
),PrioComp
);
1487 // ListUpdate - construct Fetcher and update the cache files /*{{{*/
1488 // ---------------------------------------------------------------------
1489 /* This is a simple wrapper to update the cache. it will fetch stuff
1490 * from the network (or any other sources defined in sources.list)
1492 bool ListUpdate(pkgAcquireStatus
&Stat
,
1493 pkgSourceList
&List
,
1497 if (Fetcher
.Setup(&Stat
, _config
->FindDir("Dir::State::Lists")) == false)
1500 // Populate it with the source selection
1501 if (List
.GetIndexes(&Fetcher
) == false)
1504 return AcquireUpdate(Fetcher
, PulseInterval
, true);
1507 // AcquireUpdate - take Fetcher and update the cache files /*{{{*/
1508 // ---------------------------------------------------------------------
1509 /* This is a simple wrapper to update the cache with a provided acquire
1510 * If you only need control over Status and the used SourcesList use
1511 * ListUpdate method instead.
1513 bool AcquireUpdate(pkgAcquire
&Fetcher
, int const PulseInterval
,
1514 bool const RunUpdateScripts
, bool const ListCleanup
)
1517 if (RunUpdateScripts
== true)
1518 RunScripts("APT::Update::Pre-Invoke");
1520 pkgAcquire::RunResult res
;
1521 if(PulseInterval
> 0)
1522 res
= Fetcher
.Run(PulseInterval
);
1524 res
= Fetcher
.Run();
1526 if (res
== pkgAcquire::Failed
)
1529 bool Failed
= false;
1530 bool TransientNetworkFailure
= false;
1531 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin();
1532 I
!= Fetcher
.ItemsEnd(); ++I
)
1534 if ((*I
)->Status
== pkgAcquire::Item::StatDone
)
1539 ::URI
uri((*I
)->DescURI());
1541 uri
.Password
.clear();
1542 string descUri
= string(uri
);
1543 _error
->Warning(_("Failed to fetch %s %s\n"), descUri
.c_str(),
1544 (*I
)->ErrorText
.c_str());
1546 if ((*I
)->Status
== pkgAcquire::Item::StatTransientNetworkError
)
1548 TransientNetworkFailure
= true;
1555 // Clean out any old list files
1556 // Keep "APT::Get::List-Cleanup" name for compatibility, but
1557 // this is really a global option for the APT library now
1558 if (!TransientNetworkFailure
&& !Failed
&& ListCleanup
== true &&
1559 (_config
->FindB("APT::Get::List-Cleanup",true) == true &&
1560 _config
->FindB("APT::List-Cleanup",true) == true))
1562 if (Fetcher
.Clean(_config
->FindDir("Dir::State::lists")) == false ||
1563 Fetcher
.Clean(_config
->FindDir("Dir::State::lists") + "partial/") == false)
1564 // something went wrong with the clean
1568 if (TransientNetworkFailure
== true)
1569 _error
->Warning(_("Some index files failed to download. They have been ignored, or old ones used instead."));
1570 else if (Failed
== true)
1571 return _error
->Error(_("Some index files failed to download. They have been ignored, or old ones used instead."));
1574 // Run the success scripts if all was fine
1575 if (RunUpdateScripts
== true)
1577 if(!TransientNetworkFailure
&& !Failed
)
1578 RunScripts("APT::Update::Post-Invoke-Success");
1580 // Run the other scripts
1581 RunScripts("APT::Update::Post-Invoke");