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 /*{{{*/
17 #include <apt-pkg/algorithms.h>
18 #include <apt-pkg/error.h>
19 #include <apt-pkg/configuration.h>
20 #include <apt-pkg/version.h>
21 #include <apt-pkg/sptr.h>
22 #include <apt-pkg/acquire-item.h>
23 #include <apt-pkg/edsp.h>
26 #include <sys/types.h>
35 pkgProblemResolver
*pkgProblemResolver::This
= 0;
37 // Simulate::Simulate - Constructor /*{{{*/
38 // ---------------------------------------------------------------------
39 /* The legacy translations here of input Pkg iterators is obsolete,
40 this is not necessary since the pkgCaches are fully shared now. */
41 pkgSimulate::pkgSimulate(pkgDepCache
*Cache
) : pkgPackageManager(Cache
),
43 Sim(&Cache
->GetCache(),&iPolicy
),
47 Flags
= new unsigned char[Cache
->Head().PackageCount
];
48 memset(Flags
,0,sizeof(*Flags
)*Cache
->Head().PackageCount
);
50 // Fake a filename so as not to activate the media swapping
51 string Jnk
= "SIMULATE";
52 for (unsigned int I
= 0; I
!= Cache
->Head().PackageCount
; I
++)
56 // Simulate::Describe - Describe a package /*{{{*/
57 // ---------------------------------------------------------------------
58 /* Parameter Current == true displays the current package version,
59 Parameter Candidate == true displays the candidate package version */
60 void pkgSimulate::Describe(PkgIterator Pkg
,ostream
&out
,bool Current
,bool Candidate
)
64 out
<< Pkg
.FullName(true);
68 Ver
= Pkg
.CurrentVer();
69 if (Ver
.end() == false)
70 out
<< " [" << Ver
.VerStr() << ']';
73 if (Candidate
== true)
75 Ver
= Sim
[Pkg
].CandidateVerIter(Sim
);
76 if (Ver
.end() == true)
79 out
<< " (" << Ver
.VerStr() << ' ' << Ver
.RelStr() << ')';
83 // Simulate::Install - Simulate unpacking of a package /*{{{*/
84 // ---------------------------------------------------------------------
86 bool pkgSimulate::Install(PkgIterator iPkg
,string
/*File*/)
89 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name(), iPkg
.Arch());
93 Describe(Pkg
,cout
,true,true);
94 Sim
.MarkInstall(Pkg
,false);
96 // Look for broken conflicts+predepends.
97 for (PkgIterator I
= Sim
.PkgBegin(); I
.end() == false; I
++)
99 if (Sim
[I
].InstallVer
== 0)
102 for (DepIterator D
= Sim
[I
].InstVerIter(Sim
).DependsList(); D
.end() == false;)
107 if (Start
.IsNegative() == true ||
108 End
->Type
== pkgCache::Dep::PreDepends
)
110 if ((Sim
[End
] & pkgDepCache::DepGInstall
) == 0)
112 cout
<< " [" << I
.FullName(false) << " on " << Start
.TargetPkg().FullName(false) << ']';
113 if (Start
->Type
== pkgCache::Dep::Conflicts
)
114 _error
->Error("Fatal, conflicts violated %s",I
.FullName(false).c_str());
120 if (Sim
.BrokenCount() != 0)
127 // Simulate::Configure - Simulate configuration of a Package /*{{{*/
128 // ---------------------------------------------------------------------
129 /* This is not an acurate simulation of relatity, we should really not
130 install the package.. For some investigations it may be necessary
132 bool pkgSimulate::Configure(PkgIterator iPkg
)
134 // Adapt the iterator
135 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name(), iPkg
.Arch());
139 if (Sim
[Pkg
].InstBroken() == true)
141 cout
<< "Conf " << Pkg
.FullName(false) << " broken" << endl
;
145 // Print out each package and the failed dependencies
146 for (pkgCache::DepIterator D
= Sim
[Pkg
].InstVerIter(Sim
).DependsList(); D
.end() == false; D
++)
148 if (Sim
.IsImportantDep(D
) == false ||
149 (Sim
[D
] & pkgDepCache::DepInstall
) != 0)
152 if (D
->Type
== pkgCache::Dep::Obsoletes
)
153 cout
<< " Obsoletes:" << D
.TargetPkg().FullName(false);
154 else if (D
->Type
== pkgCache::Dep::Conflicts
)
155 cout
<< " Conflicts:" << D
.TargetPkg().FullName(false);
156 else if (D
->Type
== pkgCache::Dep::DpkgBreaks
)
157 cout
<< " Breaks:" << D
.TargetPkg().FullName(false);
159 cout
<< " Depends:" << D
.TargetPkg().FullName(false);
163 _error
->Error("Conf Broken %s",Pkg
.FullName(false).c_str());
168 Describe(Pkg
,cout
,false,true);
171 if (Sim
.BrokenCount() != 0)
179 // Simulate::Remove - Simulate the removal of a package /*{{{*/
180 // ---------------------------------------------------------------------
182 bool pkgSimulate::Remove(PkgIterator iPkg
,bool Purge
)
184 // Adapt the iterator
185 PkgIterator Pkg
= Sim
.FindPkg(iPkg
.Name(), iPkg
.Arch());
194 Describe(Pkg
,cout
,true,false);
196 if (Sim
.BrokenCount() != 0)
204 // Simulate::ShortBreaks - Print out a short line describing all breaks /*{{{*/
205 // ---------------------------------------------------------------------
207 void pkgSimulate::ShortBreaks()
210 for (PkgIterator I
= Sim
.PkgBegin(); I
.end() == false; I
++)
212 if (Sim
[I
].InstBroken() == true)
214 if (Flags
[I
->ID
] == 0)
215 cout
<< I
.FullName(false) << ' ';
217 cout << I.Name() << "! ";*/
223 // ApplyStatus - Adjust for non-ok packages /*{{{*/
224 // ---------------------------------------------------------------------
225 /* We attempt to change the state of the all packages that have failed
226 installation toward their real state. The ordering code will perform
227 the necessary calculations to deal with the problems. */
228 bool pkgApplyStatus(pkgDepCache
&Cache
)
230 pkgDepCache::ActionGroup
group(Cache
);
232 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
234 if (I
->VersionList
== 0)
237 // Only choice for a ReInstReq package is to reinstall
238 if (I
->InstState
== pkgCache::State::ReInstReq
||
239 I
->InstState
== pkgCache::State::HoldReInstReq
)
241 if (I
->CurrentVer
!= 0 && I
.CurrentVer().Downloadable() == true)
242 Cache
.MarkKeep(I
, false, false);
245 // Is this right? Will dpkg choke on an upgrade?
246 if (Cache
[I
].CandidateVer
!= 0 &&
247 Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true)
248 Cache
.MarkInstall(I
, false, 0, false);
250 return _error
->Error(_("The package %s needs to be reinstalled, "
251 "but I can't find an archive for it."),I
.FullName(true).c_str());
257 switch (I
->CurrentState
)
259 /* This means installation failed somehow - it does not need to be
260 re-unpacked (probably) */
261 case pkgCache::State::UnPacked
:
262 case pkgCache::State::HalfConfigured
:
263 case pkgCache::State::TriggersAwaited
:
264 case pkgCache::State::TriggersPending
:
265 if ((I
->CurrentVer
!= 0 && I
.CurrentVer().Downloadable() == true) ||
266 I
.State() != pkgCache::PkgIterator::NeedsUnpack
)
267 Cache
.MarkKeep(I
, false, false);
270 if (Cache
[I
].CandidateVer
!= 0 &&
271 Cache
[I
].CandidateVerIter(Cache
).Downloadable() == true)
272 Cache
.MarkInstall(I
, true, 0, false);
278 // This means removal failed
279 case pkgCache::State::HalfInstalled
:
284 if (I
->InstState
!= pkgCache::State::Ok
)
285 return _error
->Error("The package %s is not ok and I "
286 "don't know how to fix it!",I
.FullName(false).c_str());
292 // FixBroken - Fix broken packages /*{{{*/
293 // ---------------------------------------------------------------------
294 /* This autoinstalls every broken package and then runs the problem resolver
296 bool pkgFixBroken(pkgDepCache
&Cache
)
298 pkgDepCache::ActionGroup
group(Cache
);
300 // Auto upgrade all broken packages
301 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
302 if (Cache
[I
].NowBroken() == true)
303 Cache
.MarkInstall(I
, true, 0, false);
305 /* Fix packages that are in a NeedArchive state but don't have a
306 downloadable install version */
307 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
309 if (I
.State() != pkgCache::PkgIterator::NeedsUnpack
||
310 Cache
[I
].Delete() == true)
313 if (Cache
[I
].InstVerIter(Cache
).Downloadable() == false)
316 Cache
.MarkInstall(I
, true, 0, false);
319 pkgProblemResolver
Fix(&Cache
);
320 return Fix
.Resolve(true);
323 // DistUpgrade - Distribution upgrade /*{{{*/
324 // ---------------------------------------------------------------------
325 /* This autoinstalls every package and then force installs every
326 pre-existing package. This creates the initial set of conditions which
327 most likely contain problems because too many things were installed.
329 The problem resolver is used to resolve the problems.
331 bool pkgDistUpgrade(pkgDepCache
&Cache
)
333 std::string
const solver
= _config
->Find("APT::Solver", "internal");
334 if (solver
!= "internal") {
335 OpTextProgress
Prog(*_config
);
336 return EDSP::ResolveExternal(solver
.c_str(), Cache
, false, true, false, &Prog
);
339 pkgDepCache::ActionGroup
group(Cache
);
341 /* Upgrade all installed packages first without autoinst to help the resolver
342 in versioned or-groups to upgrade the old solver instead of installing
343 a new one (if the old solver is not the first one [anymore]) */
344 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
345 if (I
->CurrentVer
!= 0)
346 Cache
.MarkInstall(I
, false, 0, false);
348 /* Auto upgrade all installed packages, this provides the basis
349 for the installation */
350 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
351 if (I
->CurrentVer
!= 0)
352 Cache
.MarkInstall(I
, true, 0, false);
354 /* Now, auto upgrade all essential packages - this ensures that
355 the essential packages are present and working */
356 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
357 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
358 Cache
.MarkInstall(I
, true, 0, false);
360 /* We do it again over all previously installed packages to force
361 conflict resolution on them all. */
362 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
363 if (I
->CurrentVer
!= 0)
364 Cache
.MarkInstall(I
, false, 0, false);
366 pkgProblemResolver
Fix(&Cache
);
368 // Hold back held packages.
369 if (_config
->FindB("APT::Ignore-Hold",false) == false)
371 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
373 if (I
->SelectedState
== pkgCache::State::Hold
)
376 Cache
.MarkKeep(I
, false, false);
381 return Fix
.Resolve();
384 // AllUpgrade - Upgrade as many packages as possible /*{{{*/
385 // ---------------------------------------------------------------------
386 /* Right now the system must be consistent before this can be called.
387 It also will not change packages marked for install, it only tries
388 to install packages not marked for install */
389 bool pkgAllUpgrade(pkgDepCache
&Cache
)
391 std::string
const solver
= _config
->Find("APT::Solver", "internal");
392 if (solver
!= "internal") {
393 OpTextProgress
Prog(*_config
);
394 return EDSP::ResolveExternal(solver
.c_str(), Cache
, true, false, false, &Prog
);
397 pkgDepCache::ActionGroup
group(Cache
);
399 pkgProblemResolver
Fix(&Cache
);
401 if (Cache
.BrokenCount() != 0)
404 // Upgrade all installed packages
405 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
407 if (Cache
[I
].Install() == true)
410 if (_config
->FindB("APT::Ignore-Hold",false) == false)
411 if (I
->SelectedState
== pkgCache::State::Hold
)
414 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
415 Cache
.MarkInstall(I
, false, 0, false);
418 return Fix
.ResolveByKeep();
421 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
422 // ---------------------------------------------------------------------
423 /* This simply goes over the entire set of packages and tries to keep
424 each package marked for upgrade. If a conflict is generated then
425 the package is restored. */
426 bool pkgMinimizeUpgrade(pkgDepCache
&Cache
)
428 pkgDepCache::ActionGroup
group(Cache
);
430 if (Cache
.BrokenCount() != 0)
433 // We loop for 10 tries to get the minimal set size.
435 unsigned int Count
= 0;
439 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
442 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
445 // Keep it and see if that is OK
446 Cache
.MarkKeep(I
, false, false);
447 if (Cache
.BrokenCount() != 0)
448 Cache
.MarkInstall(I
, false, 0, false);
451 // If keep didnt actually do anything then there was no change..
452 if (Cache
[I
].Upgrade() == false)
458 while (Change
== true && Count
< 10);
460 if (Cache
.BrokenCount() != 0)
461 return _error
->Error("Internal Error in pkgMinimizeUpgrade");
466 // ProblemResolver::pkgProblemResolver - Constructor /*{{{*/
467 // ---------------------------------------------------------------------
469 pkgProblemResolver::pkgProblemResolver(pkgDepCache
*pCache
) : Cache(*pCache
)
472 unsigned long Size
= Cache
.Head().PackageCount
;
473 Scores
= new signed short[Size
];
474 Flags
= new unsigned char[Size
];
475 memset(Flags
,0,sizeof(*Flags
)*Size
);
477 // Set debug to true to see its decision logic
478 Debug
= _config
->FindB("Debug::pkgProblemResolver",false);
481 // ProblemResolver::~pkgProblemResolver - Destructor /*{{{*/
482 // ---------------------------------------------------------------------
484 pkgProblemResolver::~pkgProblemResolver()
490 // ProblemResolver::ScoreSort - Sort the list by score /*{{{*/
491 // ---------------------------------------------------------------------
493 int pkgProblemResolver::ScoreSort(const void *a
,const void *b
)
495 Package
const **A
= (Package
const **)a
;
496 Package
const **B
= (Package
const **)b
;
497 if (This
->Scores
[(*A
)->ID
] > This
->Scores
[(*B
)->ID
])
499 if (This
->Scores
[(*A
)->ID
] < This
->Scores
[(*B
)->ID
])
504 // ProblemResolver::MakeScores - Make the score table /*{{{*/
505 // ---------------------------------------------------------------------
507 void pkgProblemResolver::MakeScores()
509 unsigned long Size
= Cache
.Head().PackageCount
;
510 memset(Scores
,0,sizeof(*Scores
)*Size
);
512 // Important Required Standard Optional Extra
513 signed short PrioMap
[] = {
515 (signed short) _config
->FindI("pkgProblemResolver::Scores::Important",3),
516 (signed short) _config
->FindI("pkgProblemResolver::Scores::Required",2),
517 (signed short) _config
->FindI("pkgProblemResolver::Scores::Standard",1),
518 (signed short) _config
->FindI("pkgProblemResolver::Scores::Optional",-1),
519 (signed short) _config
->FindI("pkgProblemResolver::Scores::Extra",-2)
521 signed short PrioEssentials
= _config
->FindI("pkgProblemResolver::Scores::Essentials",100);
522 signed short PrioInstalledAndNotObsolete
= _config
->FindI("pkgProblemResolver::Scores::NotObsolete",1);
523 signed short PrioDepends
= _config
->FindI("pkgProblemResolver::Scores::Depends",1);
524 signed short PrioRecommends
= _config
->FindI("pkgProblemResolver::Scores::Recommends",1);
525 signed short AddProtected
= _config
->FindI("pkgProblemResolver::Scores::AddProtected",10000);
526 signed short AddEssential
= _config
->FindI("pkgProblemResolver::Scores::AddEssential",5000);
528 if (_config
->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
529 clog
<< "Settings used to calculate pkgProblemResolver::Scores::" << endl
530 << " Important => " << PrioMap
[1] << endl
531 << " Required => " << PrioMap
[2] << endl
532 << " Standard => " << PrioMap
[3] << endl
533 << " Optional => " << PrioMap
[4] << endl
534 << " Extra => " << PrioMap
[5] << endl
535 << " Essentials => " << PrioEssentials
<< endl
536 << " InstalledAndNotObsolete => " << PrioInstalledAndNotObsolete
<< endl
537 << " Depends => " << PrioDepends
<< endl
538 << " Recommends => " << PrioRecommends
<< endl
539 << " AddProtected => " << AddProtected
<< endl
540 << " AddEssential => " << AddEssential
<< endl
;
542 // Generate the base scores for a package based on its properties
543 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
545 if (Cache
[I
].InstallVer
== 0)
548 signed short &Score
= Scores
[I
->ID
];
550 /* This is arbitrary, it should be high enough to elevate an
551 essantial package above most other packages but low enough
552 to allow an obsolete essential packages to be removed by
553 a conflicts on a powerfull normal package (ie libc6) */
554 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
555 Score
+= PrioEssentials
;
557 // We transform the priority
558 if (Cache
[I
].InstVerIter(Cache
)->Priority
<= 5)
559 Score
+= PrioMap
[Cache
[I
].InstVerIter(Cache
)->Priority
];
561 /* This helps to fix oddball problems with conflicting packages
562 on the same level. We enhance the score of installed packages
563 if those are not obsolete
565 if (I
->CurrentVer
!= 0 && Cache
[I
].CandidateVer
!= 0 && Cache
[I
].CandidateVerIter(Cache
).Downloadable())
566 Score
+= PrioInstalledAndNotObsolete
;
569 // Now that we have the base scores we go and propogate dependencies
570 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
572 if (Cache
[I
].InstallVer
== 0)
575 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false; D
++)
577 if (D
->Type
== pkgCache::Dep::Depends
||
578 D
->Type
== pkgCache::Dep::PreDepends
)
579 Scores
[D
.TargetPkg()->ID
] += PrioDepends
;
580 else if (D
->Type
== pkgCache::Dep::Recommends
)
581 Scores
[D
.TargetPkg()->ID
] += PrioRecommends
;
585 // Copy the scores to advoid additive looping
586 SPtrArray
<signed short> OldScores
= new signed short[Size
];
587 memcpy(OldScores
,Scores
,sizeof(*Scores
)*Size
);
589 /* Now we cause 1 level of dependency inheritance, that is we add the
590 score of the packages that depend on the target Package. This
591 fortifies high scoring packages */
592 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
594 if (Cache
[I
].InstallVer
== 0)
597 for (pkgCache::DepIterator D
= I
.RevDependsList(); D
.end() == false; D
++)
599 // Only do it for the install version
600 if ((pkgCache::Version
*)D
.ParentVer() != Cache
[D
.ParentPkg()].InstallVer
||
601 (D
->Type
!= pkgCache::Dep::Depends
&&
602 D
->Type
!= pkgCache::Dep::PreDepends
&&
603 D
->Type
!= pkgCache::Dep::Recommends
))
606 Scores
[I
->ID
] += abs(OldScores
[D
.ParentPkg()->ID
]);
610 /* Now we propogate along provides. This makes the packages that
611 provide important packages extremely important */
612 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
614 for (pkgCache::PrvIterator P
= I
.ProvidesList(); P
.end() == false; P
++)
616 // Only do it once per package
617 if ((pkgCache::Version
*)P
.OwnerVer() != Cache
[P
.OwnerPkg()].InstallVer
)
619 Scores
[P
.OwnerPkg()->ID
] += abs(Scores
[I
->ID
] - OldScores
[I
->ID
]);
623 /* Protected things are pushed really high up. This number should put them
624 ahead of everything */
625 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
627 if ((Flags
[I
->ID
] & Protected
) != 0)
628 Scores
[I
->ID
] += AddProtected
;
629 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
630 Scores
[I
->ID
] += AddEssential
;
634 // ProblemResolver::DoUpgrade - Attempt to upgrade this package /*{{{*/
635 // ---------------------------------------------------------------------
636 /* This goes through and tries to reinstall packages to make this package
638 bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg
)
640 pkgDepCache::ActionGroup
group(Cache
);
642 if ((Flags
[Pkg
->ID
] & Upgradable
) == 0 || Cache
[Pkg
].Upgradable() == false)
644 if ((Flags
[Pkg
->ID
] & Protected
) == Protected
)
647 Flags
[Pkg
->ID
] &= ~Upgradable
;
649 bool WasKept
= Cache
[Pkg
].Keep();
650 Cache
.MarkInstall(Pkg
, false, 0, false);
652 // This must be a virtual package or something like that.
653 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
656 // Isolate the problem dependency
658 for (pkgCache::DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
660 // Compute a single dependency element (glob or)
661 pkgCache::DepIterator Start
= D
;
662 pkgCache::DepIterator End
= D
;
663 for (bool LastOR
= true; D
.end() == false && LastOR
== true;)
665 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
671 // We only worry about critical deps.
672 if (End
.IsCritical() != true)
675 // Iterate over all the members in the or group
679 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
682 // Do not change protected packages
683 PkgIterator P
= Start
.SmartTargetPkg();
684 if ((Flags
[P
->ID
] & Protected
) == Protected
)
687 clog
<< " Reinst Failed because of protected " << P
.FullName(false) << endl
;
692 // Upgrade the package if the candidate version will fix the problem.
693 if ((Cache
[Start
] & pkgDepCache::DepCVer
) == pkgDepCache::DepCVer
)
695 if (DoUpgrade(P
) == false)
698 clog
<< " Reinst Failed because of " << P
.FullName(false) << endl
;
709 /* We let the algorithm deal with conflicts on its next iteration,
710 it is much smarter than us */
711 if (Start
.IsNegative() == true)
715 clog
<< " Reinst Failed early because of " << Start
.TargetPkg().FullName(false) << endl
;
728 // Undo our operations - it might be smart to undo everything this did..
732 Cache
.MarkKeep(Pkg
, false, false);
734 Cache
.MarkDelete(Pkg
);
739 clog
<< " Re-Instated " << Pkg
.FullName(false) << endl
;
743 // ProblemResolver::Resolve - calls a resolver to fix the situation /*{{{*/
744 // ---------------------------------------------------------------------
746 bool pkgProblemResolver::Resolve(bool BrokenFix
)
748 std::string
const solver
= _config
->Find("APT::Solver", "internal");
749 if (solver
!= "internal") {
750 OpTextProgress
Prog(*_config
);
751 return EDSP::ResolveExternal(solver
.c_str(), Cache
, false, false, false, &Prog
);
753 return ResolveInternal(BrokenFix
);
756 // ProblemResolver::ResolveInternal - Run the resolution pass /*{{{*/
757 // ---------------------------------------------------------------------
758 /* This routines works by calculating a score for each package. The score
759 is derived by considering the package's priority and all reverse
760 dependents giving an integer that reflects the amount of breakage that
761 adjusting the package will inflict.
763 It goes from highest score to lowest and corrects all of the breaks by
764 keeping or removing the dependant packages. If that fails then it removes
765 the package itself and goes on. The routine should be able to intelligently
766 go from any broken state to a fixed state.
768 The BrokenFix flag enables a mode where the algorithm tries to
769 upgrade packages to advoid problems. */
770 bool pkgProblemResolver::ResolveInternal(bool const BrokenFix
)
772 pkgDepCache::ActionGroup
group(Cache
);
774 // Record which packages are marked for install
779 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
781 if (Cache
[I
].Install() == true)
782 Flags
[I
->ID
] |= PreInstalled
;
785 if (Cache
[I
].InstBroken() == true && BrokenFix
== true)
787 Cache
.MarkInstall(I
, false, 0, false);
788 if (Cache
[I
].Install() == true)
792 Flags
[I
->ID
] &= ~PreInstalled
;
794 Flags
[I
->ID
] |= Upgradable
;
797 while (Again
== true);
800 clog
<< "Starting" << endl
;
804 unsigned long const Size
= Cache
.Head().PackageCount
;
806 /* We have to order the packages so that the broken fixing pass
807 operates from highest score to lowest. This prevents problems when
808 high score packages cause the removal of lower score packages that
809 would cause the removal of even lower score packages. */
810 SPtrArray
<pkgCache::Package
*> PList
= new pkgCache::Package
*[Size
];
811 pkgCache::Package
**PEnd
= PList
;
812 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
815 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
817 if (_config
->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
819 clog
<< "Show Scores" << endl
;
820 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
821 if (Scores
[(*K
)->ID
] != 0)
823 pkgCache::PkgIterator
Pkg(Cache
,*K
);
824 clog
<< Scores
[(*K
)->ID
] << ' ' << Pkg
<< std::endl
;
829 clog
<< "Starting 2" << endl
;
831 /* Now consider all broken packages. For each broken package we either
832 remove the package or fix it's problem. We do this once, it should
833 not be possible for a loop to form (that is a < b < c and fixing b by
834 changing a breaks c) */
836 bool const TryFixByInstall
= _config
->FindB("pkgProblemResolver::FixByInstall", true);
837 for (int Counter
= 0; Counter
!= 10 && Change
== true; Counter
++)
840 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
842 pkgCache::PkgIterator
I(Cache
,*K
);
844 /* We attempt to install this and see if any breaks result,
845 this takes care of some strange cases */
846 if (Cache
[I
].CandidateVer
!= Cache
[I
].InstallVer
&&
847 I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0 &&
848 (Flags
[I
->ID
] & PreInstalled
) != 0 &&
849 (Flags
[I
->ID
] & Protected
) == 0 &&
850 (Flags
[I
->ID
] & ReInstateTried
) == 0)
853 clog
<< " Try to Re-Instate (" << Counter
<< ") " << I
.FullName(false) << endl
;
854 unsigned long OldBreaks
= Cache
.BrokenCount();
855 pkgCache::Version
*OldVer
= Cache
[I
].InstallVer
;
856 Flags
[I
->ID
] &= ReInstateTried
;
858 Cache
.MarkInstall(I
, false, 0, false);
859 if (Cache
[I
].InstBroken() == true ||
860 OldBreaks
< Cache
.BrokenCount())
865 Cache
.MarkKeep(I
, false, false);
869 clog
<< "Re-Instated " << I
.FullName(false) << " (" << OldBreaks
<< " vs " << Cache
.BrokenCount() << ')' << endl
;
872 if (Cache
[I
].InstallVer
== 0 || Cache
[I
].InstBroken() == false)
876 clog
<< "Investigating (" << Counter
<< ") " << I
<< endl
;
878 // Isolate the problem dependency
879 PackageKill KillList
[100];
880 PackageKill
*LEnd
= KillList
;
882 pkgCache::DepIterator Start
;
883 pkgCache::DepIterator End
;
884 PackageKill
*OldEnd
= LEnd
;
886 enum {OrRemove
,OrKeep
} OrOp
= OrRemove
;
887 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList();
888 D
.end() == false || InOr
== true;)
890 // Compute a single dependency element (glob or)
894 if (InOr
== true && OldEnd
== LEnd
)
896 if (OrOp
== OrRemove
)
898 if ((Flags
[I
->ID
] & Protected
) != Protected
)
901 clog
<< " Or group remove for " << I
.FullName(false) << endl
;
906 else if (OrOp
== OrKeep
)
909 clog
<< " Or group keep for " << I
.FullName(false) << endl
;
910 Cache
.MarkKeep(I
, false, false);
915 /* We do an extra loop (as above) to finalize the or group
920 if (Start
.end() == true)
923 // We only worry about critical deps.
924 if (End
.IsCritical() != true)
933 // We only worry about critical deps.
934 if (Start
.IsCritical() != true)
939 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
946 clog
<< "Broken " << Start
<< endl
;
948 /* Look across the version list. If there are no possible
949 targets then we keep the package and bail. This is necessary
950 if a package has a dep on another package that cant be found */
951 SPtrArray
<pkgCache::Version
*> VList
= Start
.AllTargets();
952 if (*VList
== 0 && (Flags
[I
->ID
] & Protected
) != Protected
&&
953 Start
.IsNegative() == false &&
954 Cache
[I
].NowBroken() == false)
958 /* No keep choice because the keep being OK could be the
959 result of another element in the OR group! */
964 Cache
.MarkKeep(I
, false, false);
969 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
971 pkgCache::VerIterator
Ver(Cache
,*V
);
972 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
974 /* This is a conflicts, and the version we are looking
975 at is not the currently selected version of the
976 package, which means it is not necessary to
978 if (Cache
[Pkg
].InstallVer
!= Ver
&& Start
.IsNegative() == true)
981 clog
<< " Conflicts//Breaks against version "
982 << Ver
.VerStr() << " for " << Pkg
.Name()
983 << " but that is not InstVer, ignoring"
989 clog
<< " Considering " << Pkg
.FullName(false) << ' ' << (int)Scores
[Pkg
->ID
] <<
990 " as a solution to " << I
.FullName(false) << ' ' << (int)Scores
[I
->ID
] << endl
;
992 /* Try to fix the package under consideration rather than
993 fiddle with the VList package */
994 if (Scores
[I
->ID
] <= Scores
[Pkg
->ID
] ||
995 ((Cache
[Start
] & pkgDepCache::DepNow
) == 0 &&
996 End
.IsNegative() == false))
998 // Try a little harder to fix protected packages..
999 if ((Flags
[I
->ID
] & Protected
) == Protected
)
1001 if (DoUpgrade(Pkg
) == true)
1003 if (Scores
[Pkg
->ID
] > Scores
[I
->ID
])
1004 Scores
[Pkg
->ID
] = Scores
[I
->ID
];
1011 /* See if a keep will do, unless the package is protected,
1012 then installing it will be necessary */
1013 bool Installed
= Cache
[I
].Install();
1014 Cache
.MarkKeep(I
, false, false);
1015 if (Cache
[I
].InstBroken() == false)
1017 // Unwind operation will be keep now
1018 if (OrOp
== OrRemove
)
1022 if (InOr
== true && Installed
== true)
1023 Cache
.MarkInstall(I
, false, 0, false);
1026 clog
<< " Holding Back " << I
.FullName(false) << " rather than change " << Start
.TargetPkg().FullName(false) << endl
;
1030 if (BrokenFix
== false || DoUpgrade(I
) == false)
1032 // Consider other options
1036 clog
<< " Removing " << I
.FullName(false) << " rather than change " << Start
.TargetPkg().FullName(false) << endl
;
1037 Cache
.MarkDelete(I
);
1038 if (Counter
> 1 && Scores
[Pkg
->ID
] > Scores
[I
->ID
])
1039 Scores
[I
->ID
] = Scores
[Pkg
->ID
];
1041 else if (TryFixByInstall
== true &&
1042 Start
.TargetPkg()->CurrentVer
== 0 &&
1043 Cache
[Start
.TargetPkg()].Delete() == false &&
1044 (Flags
[Start
.TargetPkg()->ID
] & ToRemove
) != ToRemove
&&
1045 Cache
.GetCandidateVer(Start
.TargetPkg()).end() == false)
1047 /* Before removing or keeping the package with the broken dependency
1048 try instead to install the first not previously installed package
1049 solving this dependency. This helps every time a previous solver
1050 is removed by the resolver because of a conflict or alike but it is
1051 dangerous as it could trigger new breaks/conflicts… */
1053 clog
<< " Try Installing " << Start
.TargetPkg() << " before changing " << I
.FullName(false) << std::endl
;
1054 unsigned long const OldBroken
= Cache
.BrokenCount();
1055 Cache
.MarkInstall(Start
.TargetPkg(), true, 1, false);
1056 // FIXME: we should undo the complete MarkInstall process here
1057 if (Cache
[Start
.TargetPkg()].InstBroken() == true || Cache
.BrokenCount() > OldBroken
)
1058 Cache
.MarkDelete(Start
.TargetPkg(), false, 1, false);
1069 if (Start
->Type
== pkgCache::Dep::DpkgBreaks
)
1071 // first, try upgradring the package, if that
1072 // does not help, the breaks goes onto the
1075 // FIXME: use DoUpgrade(Pkg) instead?
1076 if (Cache
[End
] & pkgDepCache::DepGCVer
)
1079 clog
<< " Upgrading " << Pkg
.FullName(false) << " due to Breaks field in " << I
.FullName(false) << endl
;
1080 Cache
.MarkInstall(Pkg
, false, 0, false);
1085 // Skip adding to the kill list if it is protected
1086 if ((Flags
[Pkg
->ID
] & Protected
) != 0)
1090 clog
<< " Added " << Pkg
.FullName(false) << " to the remove list" << endl
;
1096 if (Start
->Type
!= pkgCache::Dep::Conflicts
&&
1097 Start
->Type
!= pkgCache::Dep::Obsoletes
)
1102 // Hm, nothing can possibly satisify this dep. Nuke it.
1103 if (VList
[0] == 0 &&
1104 Start
.IsNegative() == false &&
1105 (Flags
[I
->ID
] & Protected
) != Protected
)
1107 bool Installed
= Cache
[I
].Install();
1109 if (Cache
[I
].InstBroken() == false)
1111 // Unwind operation will be keep now
1112 if (OrOp
== OrRemove
)
1116 if (InOr
== true && Installed
== true)
1117 Cache
.MarkInstall(I
, false, 0, false);
1120 clog
<< " Holding Back " << I
.FullName(false) << " because I can't find " << Start
.TargetPkg().FullName(false) << endl
;
1125 clog
<< " Removing " << I
.FullName(false) << " because I can't find " << Start
.TargetPkg().FullName(false) << endl
;
1127 Cache
.MarkDelete(I
);
1142 // Apply the kill list now
1143 if (Cache
[I
].InstallVer
!= 0)
1145 for (PackageKill
*J
= KillList
; J
!= LEnd
; J
++)
1148 if ((Cache
[J
->Dep
] & pkgDepCache::DepGNow
) == 0)
1150 if (J
->Dep
.IsNegative() == true)
1153 clog
<< " Fixing " << I
.FullName(false) << " via remove of " << J
->Pkg
.FullName(false) << endl
;
1154 Cache
.MarkDelete(J
->Pkg
);
1160 clog
<< " Fixing " << I
.FullName(false) << " via keep of " << J
->Pkg
.FullName(false) << endl
;
1161 Cache
.MarkKeep(J
->Pkg
, false, false);
1166 if (Scores
[I
->ID
] > Scores
[J
->Pkg
->ID
])
1167 Scores
[J
->Pkg
->ID
] = Scores
[I
->ID
];
1175 clog
<< "Done" << endl
;
1177 if (Cache
.BrokenCount() != 0)
1179 // See if this is the result of a hold
1180 pkgCache::PkgIterator I
= Cache
.PkgBegin();
1181 for (;I
.end() != true; I
++)
1183 if (Cache
[I
].InstBroken() == false)
1185 if ((Flags
[I
->ID
] & Protected
) != Protected
)
1186 return _error
->Error(_("Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages."));
1188 return _error
->Error(_("Unable to correct problems, you have held broken packages."));
1191 // set the auto-flags (mvo: I'm not sure if we _really_ need this)
1192 pkgCache::PkgIterator I
= Cache
.PkgBegin();
1193 for (;I
.end() != true; I
++) {
1194 if (Cache
[I
].NewInstall() && !(Flags
[I
->ID
] & PreInstalled
)) {
1195 if(_config
->FindI("Debug::pkgAutoRemove",false)) {
1196 std::clog
<< "Resolve installed new pkg: " << I
.FullName(false)
1197 << " (now marking it as auto)" << std::endl
;
1199 Cache
[I
].Flags
|= pkgCache::Flag::Auto
;
1208 // ProblemResolver::BreaksInstOrPolicy - Check if the given pkg is broken/*{{{*/
1209 // ---------------------------------------------------------------------
1210 /* This checks if the given package is broken either by a hard dependency
1211 (InstBroken()) or by introducing a new policy breakage e.g. new
1212 unsatisfied recommends for a package that was in "policy-good" state
1214 Note that this is not perfect as it will ignore further breakage
1215 for already broken policy (recommends)
1217 bool pkgProblemResolver::InstOrNewPolicyBroken(pkgCache::PkgIterator I
)
1220 // a broken install is always a problem
1221 if (Cache
[I
].InstBroken() == true)
1224 // a newly broken policy (recommends/suggests) is a problem
1225 if (Cache
[I
].NowPolicyBroken() == false &&
1226 Cache
[I
].InstPolicyBroken() == true)
1232 // ProblemResolver::ResolveByKeep - Resolve problems using keep /*{{{*/
1233 // ---------------------------------------------------------------------
1234 /* This is the work horse of the soft upgrade routine. It is very gental
1235 in that it does not install or remove any packages. It is assumed that the
1236 system was non-broken previously. */
1237 bool pkgProblemResolver::ResolveByKeep()
1239 std::string
const solver
= _config
->Find("APT::Solver", "internal");
1240 if (solver
!= "internal") {
1241 OpTextProgress
Prog(*_config
);
1242 return EDSP::ResolveExternal(solver
.c_str(), Cache
, true, false, false, &Prog
);
1244 return ResolveByKeepInternal();
1247 // ProblemResolver::ResolveByKeepInternal - Resolve problems using keep /*{{{*/
1248 // ---------------------------------------------------------------------
1249 /* This is the work horse of the soft upgrade routine. It is very gental
1250 in that it does not install or remove any packages. It is assumed that the
1251 system was non-broken previously. */
1252 bool pkgProblemResolver::ResolveByKeepInternal()
1254 pkgDepCache::ActionGroup
group(Cache
);
1256 unsigned long Size
= Cache
.Head().PackageCount
;
1260 /* We have to order the packages so that the broken fixing pass
1261 operates from highest score to lowest. This prevents problems when
1262 high score packages cause the removal of lower score packages that
1263 would cause the removal of even lower score packages. */
1264 pkgCache::Package
**PList
= new pkgCache::Package
*[Size
];
1265 pkgCache::Package
**PEnd
= PList
;
1266 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
1269 qsort(PList
,PEnd
- PList
,sizeof(*PList
),&ScoreSort
);
1271 if (_config
->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
1273 clog
<< "Show Scores" << endl
;
1274 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
1275 if (Scores
[(*K
)->ID
] != 0)
1277 pkgCache::PkgIterator
Pkg(Cache
,*K
);
1278 clog
<< Scores
[(*K
)->ID
] << ' ' << Pkg
<< std::endl
;
1283 clog
<< "Entering ResolveByKeep" << endl
;
1285 // Consider each broken package
1286 pkgCache::Package
**LastStop
= 0;
1287 for (pkgCache::Package
**K
= PList
; K
!= PEnd
; K
++)
1289 pkgCache::PkgIterator
I(Cache
,*K
);
1291 if (Cache
[I
].InstallVer
== 0)
1294 if (InstOrNewPolicyBroken(I
) == false)
1297 /* Keep the package. If this works then great, otherwise we have
1298 to be significantly more agressive and manipulate its dependencies */
1299 if ((Flags
[I
->ID
] & Protected
) == 0)
1302 clog
<< "Keeping package " << I
.FullName(false) << endl
;
1303 Cache
.MarkKeep(I
, false, false);
1304 if (InstOrNewPolicyBroken(I
) == false)
1311 // Isolate the problem dependencies
1312 for (pkgCache::DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
1316 D
.GlobOr(Start
,End
);
1318 // We only worry about critical deps.
1319 if (End
.IsCritical() != true)
1323 if ((Cache
[End
] & pkgDepCache::DepGInstall
) == pkgDepCache::DepGInstall
)
1326 /* Hm, the group is broken.. I suppose the best thing to do is to
1327 is to try every combination of keep/not-keep for the set, but thats
1328 slow, and this never happens, just be conservative and assume the
1329 list of ors is in preference and keep till it starts to work. */
1333 clog
<< "Package " << I
.FullName(false) << " " << Start
<< endl
;
1335 // Look at all the possible provides on this package
1336 SPtrArray
<pkgCache::Version
*> VList
= Start
.AllTargets();
1337 for (pkgCache::Version
**V
= VList
; *V
!= 0; V
++)
1339 pkgCache::VerIterator
Ver(Cache
,*V
);
1340 pkgCache::PkgIterator Pkg
= Ver
.ParentPkg();
1342 // It is not keepable
1343 if (Cache
[Pkg
].InstallVer
== 0 ||
1344 Pkg
->CurrentVer
== 0)
1347 if ((Flags
[I
->ID
] & Protected
) == 0)
1350 clog
<< " Keeping Package " << Pkg
.FullName(false) << " due to " << Start
.DepType() << endl
;
1351 Cache
.MarkKeep(Pkg
, false, false);
1354 if (InstOrNewPolicyBroken(I
) == false)
1358 if (InstOrNewPolicyBroken(I
) == false)
1366 if (InstOrNewPolicyBroken(I
) == false)
1370 if (InstOrNewPolicyBroken(I
) == true)
1375 return _error
->Error("Internal Error, pkgProblemResolver::ResolveByKeep is looping on package %s.",I
.FullName(false).c_str());
1383 // ProblemResolver::InstallProtect - Install all protected packages /*{{{*/
1384 // ---------------------------------------------------------------------
1385 /* This is used to make sure protected packages are installed */
1386 void pkgProblemResolver::InstallProtect()
1388 pkgDepCache::ActionGroup
group(Cache
);
1390 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
1392 if ((Flags
[I
->ID
] & Protected
) == Protected
)
1394 if ((Flags
[I
->ID
] & ToRemove
) == ToRemove
)
1395 Cache
.MarkDelete(I
);
1398 // preserve the information whether the package was auto
1399 // or manually installed
1400 bool autoInst
= (Cache
[I
].Flags
& pkgCache::Flag::Auto
);
1401 Cache
.MarkInstall(I
, false, 0, !autoInst
);
1407 // PrioSortList - Sort a list of versions by priority /*{{{*/
1408 // ---------------------------------------------------------------------
1409 /* This is ment to be used in conjunction with AllTargets to get a list
1410 of versions ordered by preference. */
1411 static pkgCache
*PrioCache
;
1412 static int PrioComp(const void *A
,const void *B
)
1414 pkgCache::VerIterator
L(*PrioCache
,*(pkgCache::Version
**)A
);
1415 pkgCache::VerIterator
R(*PrioCache
,*(pkgCache::Version
**)B
);
1417 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
&&
1418 (R
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
1420 if ((L
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
&&
1421 (R
.ParentPkg()->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
1424 if (L
->Priority
!= R
->Priority
)
1425 return R
->Priority
- L
->Priority
;
1426 return strcmp(L
.ParentPkg().Name(),R
.ParentPkg().Name());
1428 void pkgPrioSortList(pkgCache
&Cache
,pkgCache::Version
**List
)
1430 unsigned long Count
= 0;
1432 for (pkgCache::Version
**I
= List
; *I
!= 0; I
++)
1434 qsort(List
,Count
,sizeof(*List
),PrioComp
);
1437 // CacheFile::ListUpdate - update the cache files /*{{{*/
1438 // ---------------------------------------------------------------------
1439 /* This is a simple wrapper to update the cache. it will fetch stuff
1440 * from the network (or any other sources defined in sources.list)
1442 bool ListUpdate(pkgAcquireStatus
&Stat
,
1443 pkgSourceList
&List
,
1446 pkgAcquire::RunResult res
;
1448 if (Fetcher
.Setup(&Stat
, _config
->FindDir("Dir::State::Lists")) == false)
1451 // Populate it with the source selection
1452 if (List
.GetIndexes(&Fetcher
) == false)
1456 RunScripts("APT::Update::Pre-Invoke");
1460 res
= Fetcher
.Run(PulseInterval
);
1462 res
= Fetcher
.Run();
1464 if (res
== pkgAcquire::Failed
)
1467 bool Failed
= false;
1468 bool TransientNetworkFailure
= false;
1469 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin();
1470 I
!= Fetcher
.ItemsEnd(); I
++)
1472 if ((*I
)->Status
== pkgAcquire::Item::StatDone
)
1477 ::URI
uri((*I
)->DescURI());
1479 uri
.Password
.clear();
1480 string descUri
= string(uri
);
1481 _error
->Warning(_("Failed to fetch %s %s\n"), descUri
.c_str(),
1482 (*I
)->ErrorText
.c_str());
1484 if ((*I
)->Status
== pkgAcquire::Item::StatTransientNetworkError
)
1486 TransientNetworkFailure
= true;
1493 // Clean out any old list files
1494 // Keep "APT::Get::List-Cleanup" name for compatibility, but
1495 // this is really a global option for the APT library now
1496 if (!TransientNetworkFailure
&& !Failed
&&
1497 (_config
->FindB("APT::Get::List-Cleanup",true) == true &&
1498 _config
->FindB("APT::List-Cleanup",true) == true))
1500 if (Fetcher
.Clean(_config
->FindDir("Dir::State::lists")) == false ||
1501 Fetcher
.Clean(_config
->FindDir("Dir::State::lists") + "partial/") == false)
1502 // something went wrong with the clean
1506 if (TransientNetworkFailure
== true)
1507 _error
->Warning(_("Some index files failed to download. They have been ignored, or old ones used instead."));
1508 else if (Failed
== true)
1509 return _error
->Error(_("Some index files failed to download. They have been ignored, or old ones used instead."));
1512 // Run the success scripts if all was fine
1513 if(!TransientNetworkFailure
&& !Failed
)
1514 RunScripts("APT::Update::Post-Invoke-Success");
1516 // Run the other scripts
1517 RunScripts("APT::Update::Post-Invoke");