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