]> git.saurik.com Git - apt.git/blob - apt-pkg/depcache.cc
5da411e4d0c8a1cef3a1d5afd4971335162c73e9
[apt.git] / apt-pkg / depcache.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: depcache.cc,v 1.25 2001/05/27 05:36:04 jgg Exp $
4 /* ######################################################################
5
6 Dependency Cache - Caches Dependency information.
7
8 ##################################################################### */
9 /*}}}*/
10 // Include Files /*{{{*/
11 #ifdef __GNUG__
12 #pragma implementation "apt-pkg/depcache.h"
13 #endif
14 #include <apt-pkg/depcache.h>
15 #include <apt-pkg/version.h>
16 #include <apt-pkg/error.h>
17 #include <apt-pkg/sptr.h>
18 #include <apt-pkg/algorithms.h>
19
20 #include <apt-pkg/fileutl.h>
21 #include <apt-pkg/configuration.h>
22 #include <apt-pkg/tagfile.h>
23
24 #include <apti18n.h>
25 /*}}}*/
26
27 // DepCache::pkgDepCache - Constructors /*{{{*/
28 // ---------------------------------------------------------------------
29 /* */
30 pkgDepCache::pkgDepCache(pkgCache *pCache,Policy *Plcy) :
31 Cache(pCache), PkgState(0), DepState(0)
32 {
33 delLocalPolicy = 0;
34 LocalPolicy = Plcy;
35 if (LocalPolicy == 0)
36 delLocalPolicy = LocalPolicy = new Policy;
37 }
38 /*}}}*/
39 // DepCache::~pkgDepCache - Destructor /*{{{*/
40 // ---------------------------------------------------------------------
41 /* */
42 pkgDepCache::~pkgDepCache()
43 {
44 delete [] PkgState;
45 delete [] DepState;
46 delete delLocalPolicy;
47 }
48 /*}}}*/
49 // DepCache::Init - Generate the initial extra structures. /*{{{*/
50 // ---------------------------------------------------------------------
51 /* This allocats the extension buffers and initializes them. */
52 bool pkgDepCache::Init(OpProgress *Prog)
53 {
54 delete [] PkgState;
55 delete [] DepState;
56 PkgState = new StateCache[Head().PackageCount];
57 DepState = new unsigned char[Head().DependsCount];
58 memset(PkgState,0,sizeof(*PkgState)*Head().PackageCount);
59 memset(DepState,0,sizeof(*DepState)*Head().DependsCount);
60
61 if (Prog != 0)
62 {
63 Prog->OverallProgress(0,2*Head().PackageCount,Head().PackageCount,
64 _("Building dependency tree"));
65 Prog->SubProgress(Head().PackageCount,_("Candidate versions"));
66 }
67
68 /* Set the current state of everything. In this state all of the
69 packages are kept exactly as is. See AllUpgrade */
70 int Done = 0;
71 for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++)
72 {
73 if (Prog != 0)
74 Prog->Progress(Done);
75
76 // Find the proper cache slot
77 StateCache &State = PkgState[I->ID];
78 State.iFlags = 0;
79 State.DirtyState = pkgCache::State::RemoveUnknown;
80 //State.AutomaticRemove = I->AutomaticRemove;
81 State.AutomaticRemove = pkgCache::State::RemoveUnknown;
82
83 // Figure out the install version
84 State.CandidateVer = GetCandidateVer(I);
85 State.InstallVer = I.CurrentVer();
86 State.Mode = ModeKeep;
87
88 State.Update(I,*this);
89 }
90
91 if (Prog != 0)
92 {
93
94 Prog->OverallProgress(Head().PackageCount,2*Head().PackageCount,
95 Head().PackageCount,
96 _("Building dependency tree"));
97 Prog->SubProgress(Head().PackageCount,_("Dependency generation"));
98 }
99
100 Update(Prog);
101
102 return true;
103 }
104 /*}}}*/
105
106 // DepCache::CheckDep - Checks a single dependency /*{{{*/
107 // ---------------------------------------------------------------------
108 /* This first checks the dependency against the main target package and
109 then walks along the package provides list and checks if each provides
110 will be installed then checks the provides against the dep. Res will be
111 set to the package which was used to satisfy the dep. */
112 bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res)
113 {
114 Res = Dep.TargetPkg();
115
116 /* Check simple depends. A depends -should- never self match but
117 we allow it anyhow because dpkg does. Technically it is a packaging
118 bug. Conflicts may never self match */
119 if (Dep.TargetPkg() != Dep.ParentPkg() ||
120 (Dep->Type != Dep::Conflicts && Dep->Type != Dep::Obsoletes))
121 {
122 PkgIterator Pkg = Dep.TargetPkg();
123 // Check the base package
124 if (Type == NowVersion && Pkg->CurrentVer != 0)
125 if (VS().CheckDep(Pkg.CurrentVer().VerStr(),Dep->CompareOp,
126 Dep.TargetVer()) == true)
127 return true;
128
129 if (Type == InstallVersion && PkgState[Pkg->ID].InstallVer != 0)
130 if (VS().CheckDep(PkgState[Pkg->ID].InstVerIter(*this).VerStr(),
131 Dep->CompareOp,Dep.TargetVer()) == true)
132 return true;
133
134 if (Type == CandidateVersion && PkgState[Pkg->ID].CandidateVer != 0)
135 if (VS().CheckDep(PkgState[Pkg->ID].CandidateVerIter(*this).VerStr(),
136 Dep->CompareOp,Dep.TargetVer()) == true)
137 return true;
138 }
139
140 if (Dep->Type == Dep::Obsoletes)
141 return false;
142
143 // Check the providing packages
144 PrvIterator P = Dep.TargetPkg().ProvidesList();
145 PkgIterator Pkg = Dep.ParentPkg();
146 for (; P.end() != true; P++)
147 {
148 /* Provides may never be applied against the same package if it is
149 a conflicts. See the comment above. */
150 if (P.OwnerPkg() == Pkg && Dep->Type == Dep::Conflicts)
151 continue;
152
153 // Check if the provides is a hit
154 if (Type == NowVersion)
155 {
156 if (P.OwnerPkg().CurrentVer() != P.OwnerVer())
157 continue;
158 }
159
160 if (Type == InstallVersion)
161 {
162 StateCache &State = PkgState[P.OwnerPkg()->ID];
163 if (State.InstallVer != (Version *)P.OwnerVer())
164 continue;
165 }
166
167 if (Type == CandidateVersion)
168 {
169 StateCache &State = PkgState[P.OwnerPkg()->ID];
170 if (State.CandidateVer != (Version *)P.OwnerVer())
171 continue;
172 }
173
174 // Compare the versions.
175 if (VS().CheckDep(P.ProvideVersion(),Dep->CompareOp,Dep.TargetVer()) == true)
176 {
177 Res = P.OwnerPkg();
178 return true;
179 }
180 }
181
182 return false;
183 }
184 /*}}}*/
185 // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
186 // ---------------------------------------------------------------------
187 /* Call with Mult = -1 to preform the inverse opration */
188 void pkgDepCache::AddSizes(const PkgIterator &Pkg,signed long Mult)
189 {
190 StateCache &P = PkgState[Pkg->ID];
191
192 if (Pkg->VersionList == 0)
193 return;
194
195 if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
196 P.Keep() == true)
197 return;
198
199 // Compute the size data
200 if (P.NewInstall() == true)
201 {
202 iUsrSize += (signed)(Mult*P.InstVerIter(*this)->InstalledSize);
203 iDownloadSize += (signed)(Mult*P.InstVerIter(*this)->Size);
204 return;
205 }
206
207 // Upgrading
208 if (Pkg->CurrentVer != 0 &&
209 (P.InstallVer != (Version *)Pkg.CurrentVer() ||
210 (P.iFlags & ReInstall) == ReInstall) && P.InstallVer != 0)
211 {
212 iUsrSize += (signed)(Mult*((signed)P.InstVerIter(*this)->InstalledSize -
213 (signed)Pkg.CurrentVer()->InstalledSize));
214 iDownloadSize += (signed)(Mult*P.InstVerIter(*this)->Size);
215 return;
216 }
217
218 // Reinstall
219 if (Pkg.State() == pkgCache::PkgIterator::NeedsUnpack &&
220 P.Delete() == false)
221 {
222 iDownloadSize += (signed)(Mult*P.InstVerIter(*this)->Size);
223 return;
224 }
225
226 // Removing
227 if (Pkg->CurrentVer != 0 && P.InstallVer == 0)
228 {
229 iUsrSize -= (signed)(Mult*Pkg.CurrentVer()->InstalledSize);
230 return;
231 }
232 }
233 /*}}}*/
234 // DepCache::AddStates - Add the package to the state counter /*{{{*/
235 // ---------------------------------------------------------------------
236 /* This routine is tricky to use, you must make sure that it is never
237 called twice for the same package. This means the Remove/Add section
238 should be as short as possible and not encompass any code that will
239 calld Remove/Add itself. Remember, dependencies can be circular so
240 while processing a dep for Pkg it is possible that Add/Remove
241 will be called on Pkg */
242 void pkgDepCache::AddStates(const PkgIterator &Pkg,int Add)
243 {
244 StateCache &State = PkgState[Pkg->ID];
245
246 // The Package is broken
247 if ((State.DepState & DepInstMin) != DepInstMin)
248 iBrokenCount += Add;
249
250 // Bad state
251 if (Pkg.State() != PkgIterator::NeedsNothing)
252 iBadCount += Add;
253
254 // Not installed
255 if (Pkg->CurrentVer == 0)
256 {
257 if (State.Mode == ModeDelete &&
258 (State.iFlags | Purge) == Purge && Pkg.Purge() == false)
259 iDelCount += Add;
260
261 if (State.Mode == ModeInstall)
262 iInstCount += Add;
263 return;
264 }
265
266 // Installed, no upgrade
267 if (State.Status == 0)
268 {
269 if (State.Mode == ModeDelete)
270 iDelCount += Add;
271 else
272 if ((State.iFlags & ReInstall) == ReInstall)
273 iInstCount += Add;
274
275 return;
276 }
277
278 // Alll 3 are possible
279 if (State.Mode == ModeDelete)
280 iDelCount += Add;
281 if (State.Mode == ModeKeep)
282 iKeepCount += Add;
283 if (State.Mode == ModeInstall)
284 iInstCount += Add;
285 }
286 /*}}}*/
287 // DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
288 // ---------------------------------------------------------------------
289 /* The or group results are stored in the last item of the or group. This
290 allows easy detection of the state of a whole or'd group. */
291 void pkgDepCache::BuildGroupOrs(VerIterator const &V)
292 {
293 unsigned char Group = 0;
294
295 for (DepIterator D = V.DependsList(); D.end() != true; D++)
296 {
297 // Build the dependency state.
298 unsigned char &State = DepState[D->ID];
299
300 /* Invert for Conflicts. We have to do this twice to get the
301 right sense for a conflicts group */
302 if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
303 State = ~State;
304
305 // Add to the group if we are within an or..
306 State &= 0x7;
307 Group |= State;
308 State |= Group << 3;
309 if ((D->CompareOp & Dep::Or) != Dep::Or)
310 Group = 0;
311
312 // Invert for Conflicts
313 if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
314 State = ~State;
315 }
316 }
317 /*}}}*/
318 // DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
319 // ---------------------------------------------------------------------
320 /* This is used to run over a dependency list and determine the dep
321 state of the list, filtering it through both a Min check and a Policy
322 check. The return result will have SetMin/SetPolicy low if a check
323 fails. It uses the DepState cache for it's computations. */
324 unsigned char pkgDepCache::VersionState(DepIterator D,unsigned char Check,
325 unsigned char SetMin,
326 unsigned char SetPolicy)
327 {
328 unsigned char Dep = 0xFF;
329
330 while (D.end() != true)
331 {
332 // Compute a single dependency element (glob or)
333 DepIterator Start = D;
334 unsigned char State = 0;
335 for (bool LastOR = true; D.end() == false && LastOR == true; D++)
336 {
337 State |= DepState[D->ID];
338 LastOR = (D->CompareOp & Dep::Or) == Dep::Or;
339 }
340
341 // Minimum deps that must be satisfied to have a working package
342 if (Start.IsCritical() == true)
343 if ((State & Check) != Check)
344 Dep &= ~SetMin;
345
346 // Policy deps that must be satisfied to install the package
347 if (IsImportantDep(Start) == true &&
348 (State & Check) != Check)
349 Dep &= ~SetPolicy;
350 }
351
352 return Dep;
353 }
354 /*}}}*/
355 // DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
356 // ---------------------------------------------------------------------
357 /* This is the main dependency computation bit. It computes the 3 main
358 results for a dependencys, Now, Install and Candidate. Callers must
359 invert the result if dealing with conflicts. */
360 unsigned char pkgDepCache::DependencyState(DepIterator &D)
361 {
362 unsigned char State = 0;
363
364 if (CheckDep(D,NowVersion) == true)
365 State |= DepNow;
366 if (CheckDep(D,InstallVersion) == true)
367 State |= DepInstall;
368 if (CheckDep(D,CandidateVersion) == true)
369 State |= DepCVer;
370
371 return State;
372 }
373 /*}}}*/
374 // DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
375 // ---------------------------------------------------------------------
376 /* This determines the combined dependency representation of a package
377 for its two states now and install. This is done by using the pre-generated
378 dependency information. */
379 void pkgDepCache::UpdateVerState(PkgIterator Pkg)
380 {
381 // Empty deps are always true
382 StateCache &State = PkgState[Pkg->ID];
383 State.DepState = 0xFF;
384
385 // Check the Current state
386 if (Pkg->CurrentVer != 0)
387 {
388 DepIterator D = Pkg.CurrentVer().DependsList();
389 State.DepState &= VersionState(D,DepNow,DepNowMin,DepNowPolicy);
390 }
391
392 /* Check the candidate state. We do not compare against the whole as
393 a candidate state but check the candidate version against the
394 install states */
395 if (State.CandidateVer != 0)
396 {
397 DepIterator D = State.CandidateVerIter(*this).DependsList();
398 State.DepState &= VersionState(D,DepInstall,DepCandMin,DepCandPolicy);
399 }
400
401 // Check target state which can only be current or installed
402 if (State.InstallVer != 0)
403 {
404 DepIterator D = State.InstVerIter(*this).DependsList();
405 State.DepState &= VersionState(D,DepInstall,DepInstMin,DepInstPolicy);
406 }
407 }
408 /*}}}*/
409 // DepCache::Update - Figure out all the state information /*{{{*/
410 // ---------------------------------------------------------------------
411 /* This will figure out the state of all the packages and all the
412 dependencies based on the current policy. */
413 void pkgDepCache::Update(OpProgress *Prog)
414 {
415 iUsrSize = 0;
416 iDownloadSize = 0;
417 iDelCount = 0;
418 iInstCount = 0;
419 iKeepCount = 0;
420 iBrokenCount = 0;
421 iBadCount = 0;
422
423 // Perform the depends pass
424 int Done = 0;
425 for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++)
426 {
427 if (Prog != 0 && Done%20 == 0)
428 Prog->Progress(Done);
429 for (VerIterator V = I.VersionList(); V.end() != true; V++)
430 {
431 unsigned char Group = 0;
432
433 for (DepIterator D = V.DependsList(); D.end() != true; D++)
434 {
435 // Build the dependency state.
436 unsigned char &State = DepState[D->ID];
437 State = DependencyState(D);
438
439 // Add to the group if we are within an or..
440 Group |= State;
441 State |= Group << 3;
442 if ((D->CompareOp & Dep::Or) != Dep::Or)
443 Group = 0;
444
445 // Invert for Conflicts
446 if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
447 State = ~State;
448 }
449 }
450
451 // Compute the pacakge dependency state and size additions
452 AddSizes(I);
453 UpdateVerState(I);
454 AddStates(I);
455 }
456
457 // read the state file ------------------------------
458 FileFd state_file;
459 string state = _config->FindDir("Dir::State") + "pkgstates";
460 if(FileExists(state)) {
461 state_file.Open(state, FileFd::ReadOnly);
462 int file_size = state_file.Size();
463 Prog->OverallProgress(0, file_size, 1, _("Reading extended state information"));
464
465 pkgTagFile tagfile(&state_file);
466 pkgTagSection section;
467 int amt=0;
468 while(tagfile.Step(section)) {
469 string pkgname = section.FindS("Package");
470 pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname);
471 // Silently ignore unknown packages and packages with no actual
472 // version.
473 if(!pkg.end() && !pkg.VersionList().end()) {
474 short reason = section.FindI("Remove-Reason", pkgCache::State::RemoveManual);
475 PkgState[pkg->ID].AutomaticRemove = reason;
476 //std::cout << "Set: " << pkgname << " to " << reason << std::endl;
477 amt+=section.size();
478 Prog->OverallProgress(amt, file_size, 1, _("Reading extended state information"));
479 }
480 Prog->OverallProgress(file_size, file_size, 1, _("Reading extended state information"));
481 }
482 }
483 //--------------------------------------
484
485
486 if (Prog != 0)
487 Prog->Progress(Done);
488 }
489 /*}}}*/
490 // DepCache::Update - Update the deps list of a package /*{{{*/
491 // ---------------------------------------------------------------------
492 /* This is a helper for update that only does the dep portion of the scan.
493 It is mainly ment to scan reverse dependencies. */
494 void pkgDepCache::Update(DepIterator D)
495 {
496 // Update the reverse deps
497 for (;D.end() != true; D++)
498 {
499 unsigned char &State = DepState[D->ID];
500 State = DependencyState(D);
501
502 // Invert for Conflicts
503 if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
504 State = ~State;
505
506 RemoveStates(D.ParentPkg());
507 BuildGroupOrs(D.ParentVer());
508 UpdateVerState(D.ParentPkg());
509 AddStates(D.ParentPkg());
510 }
511 }
512 /*}}}*/
513 // DepCache::Update - Update the related deps of a package /*{{{*/
514 // ---------------------------------------------------------------------
515 /* This is called whenever the state of a package changes. It updates
516 all cached dependencies related to this package. */
517 void pkgDepCache::Update(PkgIterator const &Pkg)
518 {
519 // Recompute the dep of the package
520 RemoveStates(Pkg);
521 UpdateVerState(Pkg);
522 AddStates(Pkg);
523
524 // Update the reverse deps
525 Update(Pkg.RevDependsList());
526
527 // Update the provides map for the current ver
528 if (Pkg->CurrentVer != 0)
529 for (PrvIterator P = Pkg.CurrentVer().ProvidesList();
530 P.end() != true; P++)
531 Update(P.ParentPkg().RevDependsList());
532
533 // Update the provides map for the candidate ver
534 if (PkgState[Pkg->ID].CandidateVer != 0)
535 for (PrvIterator P = PkgState[Pkg->ID].CandidateVerIter(*this).ProvidesList();
536 P.end() != true; P++)
537 Update(P.ParentPkg().RevDependsList());
538 }
539
540 /*}}}*/
541
542 // DepCache::MarkKeep - Put the package in the keep state /*{{{*/
543 // ---------------------------------------------------------------------
544 /* */
545 void pkgDepCache::MarkKeep(PkgIterator const &Pkg,bool Soft)
546 {
547 // Simplifies other routines.
548 if (Pkg.end() == true)
549 return;
550
551 /* Reject an attempt to keep a non-source broken installed package, those
552 must be upgraded */
553 if (Pkg.State() == PkgIterator::NeedsUnpack &&
554 Pkg.CurrentVer().Downloadable() == false)
555 return;
556
557 /* We changed the soft state all the time so the UI is a bit nicer
558 to use */
559 StateCache &P = PkgState[Pkg->ID];
560 if (Soft == true)
561 P.iFlags |= AutoKept;
562 else
563 P.iFlags &= ~AutoKept;
564
565 // Check that it is not already kept
566 if (P.Mode == ModeKeep)
567 return;
568
569 // We dont even try to keep virtual packages..
570 if (Pkg->VersionList == 0)
571 return;
572
573 P.Flags &= ~Flag::Auto;
574 RemoveSizes(Pkg);
575 RemoveStates(Pkg);
576
577 P.Mode = ModeKeep;
578 if (Pkg->CurrentVer == 0)
579 P.InstallVer = 0;
580 else
581 P.InstallVer = Pkg.CurrentVer();
582
583 AddStates(Pkg);
584
585 Update(Pkg);
586
587 AddSizes(Pkg);
588 }
589 /*}}}*/
590 // DepCache::MarkDelete - Put the package in the delete state /*{{{*/
591 // ---------------------------------------------------------------------
592 /* */
593 void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge)
594 {
595 // Simplifies other routines.
596 if (Pkg.end() == true)
597 return;
598
599 // Check that it is not already marked for delete
600 StateCache &P = PkgState[Pkg->ID];
601 P.iFlags &= ~(AutoKept | Purge);
602 if (rPurge == true)
603 P.iFlags |= Purge;
604
605 if ((P.Mode == ModeDelete || P.InstallVer == 0) &&
606 (Pkg.Purge() == true || rPurge == false))
607 return;
608
609 // We dont even try to delete virtual packages..
610 if (Pkg->VersionList == 0)
611 return;
612
613 RemoveSizes(Pkg);
614 RemoveStates(Pkg);
615
616 if (Pkg->CurrentVer == 0 && (Pkg.Purge() == true || rPurge == false))
617 P.Mode = ModeKeep;
618 else
619 P.Mode = ModeDelete;
620 P.InstallVer = 0;
621 // This was not inverted before, but I think it should be
622 P.Flags &= ~Flag::Auto;
623
624 AddStates(Pkg);
625 Update(Pkg);
626 AddSizes(Pkg);
627 }
628 /*}}}*/
629 // DepCache::MarkInstall - Put the package in the install state /*{{{*/
630 // ---------------------------------------------------------------------
631 /* */
632 void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
633 unsigned long Depth)
634 {
635 if (Depth > 100)
636 return;
637
638 // Simplifies other routines.
639 if (Pkg.end() == true)
640 return;
641
642 /* Check that it is not already marked for install and that it can be
643 installed */
644 StateCache &P = PkgState[Pkg->ID];
645 P.iFlags &= ~AutoKept;
646 if (P.InstBroken() == false && (P.Mode == ModeInstall ||
647 P.CandidateVer == (Version *)Pkg.CurrentVer()))
648 {
649 if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0)
650 MarkKeep(Pkg);
651 return;
652 }
653
654 // See if there is even any possible instalation candidate
655 if (P.CandidateVer == 0)
656 return;
657
658 // We dont even try to install virtual packages..
659 if (Pkg->VersionList == 0)
660 return;
661
662 /* Target the candidate version and remove the autoflag. We reset the
663 autoflag below if this was called recursively. Otherwise the user
664 should have the ability to de-auto a package by changing its state */
665 RemoveSizes(Pkg);
666 RemoveStates(Pkg);
667
668 P.Mode = ModeInstall;
669 P.InstallVer = P.CandidateVer;
670 P.Flags &= ~Flag::Auto;
671 if (P.CandidateVer == (Version *)Pkg.CurrentVer())
672 P.Mode = ModeKeep;
673
674 AddStates(Pkg);
675 Update(Pkg);
676 AddSizes(Pkg);
677
678 if (AutoInst == false)
679 return;
680
681 DepIterator Dep = P.InstVerIter(*this).DependsList();
682 for (; Dep.end() != true;)
683 {
684 // Grok or groups
685 DepIterator Start = Dep;
686 bool Result = true;
687 unsigned Ors = 0;
688 for (bool LastOR = true; Dep.end() == false && LastOR == true; Dep++,Ors++)
689 {
690 LastOR = (Dep->CompareOp & Dep::Or) == Dep::Or;
691
692 if ((DepState[Dep->ID] & DepInstall) == DepInstall)
693 Result = false;
694 }
695
696 // Dep is satisfied okay.
697 if (Result == false)
698 continue;
699
700 /* Check if this dep should be consider for install. If it is a user
701 defined important dep and we are installed a new package then
702 it will be installed. Otherwise we only worry about critical deps */
703 if (IsImportantDep(Start) == false)
704 continue;
705 if (Pkg->CurrentVer != 0 && Start.IsCritical() == false)
706 continue;
707
708 /* If we are in an or group locate the first or that can
709 succeed. We have already cached this.. */
710 for (; Ors > 1 && (DepState[Start->ID] & DepCVer) != DepCVer; Ors--)
711 Start++;
712
713 /* This bit is for processing the possibilty of an install/upgrade
714 fixing the problem */
715 SPtrArray<Version *> List = Start.AllTargets();
716 if ((DepState[Start->ID] & DepCVer) == DepCVer)
717 {
718 // Right, find the best version to install..
719 Version **Cur = List;
720 PkgIterator P = Start.TargetPkg();
721 PkgIterator InstPkg(*Cache,0);
722
723 // See if there are direct matches (at the start of the list)
724 for (; *Cur != 0 && (*Cur)->ParentPkg == P.Index(); Cur++)
725 {
726 PkgIterator Pkg(*Cache,Cache->PkgP + (*Cur)->ParentPkg);
727 if (PkgState[Pkg->ID].CandidateVer != *Cur)
728 continue;
729 InstPkg = Pkg;
730 break;
731 }
732
733 // Select the highest priority providing package
734 if (InstPkg.end() == true)
735 {
736 pkgPrioSortList(*Cache,Cur);
737 for (; *Cur != 0; Cur++)
738 {
739 PkgIterator Pkg(*Cache,Cache->PkgP + (*Cur)->ParentPkg);
740 if (PkgState[Pkg->ID].CandidateVer != *Cur)
741 continue;
742 InstPkg = Pkg;
743 break;
744 }
745 }
746
747 if (InstPkg.end() == false)
748 {
749 MarkInstall(InstPkg,true,Depth + 1);
750
751 // Set the autoflag, after MarkInstall because MarkInstall unsets it
752 if (P->CurrentVer == 0)
753 PkgState[InstPkg->ID].Flags |= Flag::Auto;
754 }
755
756 continue;
757 }
758
759 /* For conflicts we just de-install the package and mark as auto,
760 Conflicts may not have or groups */
761 if (Start->Type == Dep::Conflicts || Start->Type == Dep::Obsoletes)
762 {
763 for (Version **I = List; *I != 0; I++)
764 {
765 VerIterator Ver(*this,*I);
766 PkgIterator Pkg = Ver.ParentPkg();
767
768 MarkDelete(Pkg);
769 PkgState[Pkg->ID].Flags |= Flag::Auto;
770 }
771 continue;
772 }
773 }
774 }
775 /*}}}*/
776 // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
777 // ---------------------------------------------------------------------
778 /* */
779 void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To)
780 {
781 RemoveSizes(Pkg);
782 RemoveStates(Pkg);
783
784 StateCache &P = PkgState[Pkg->ID];
785 if (To == true)
786 P.iFlags |= ReInstall;
787 else
788 P.iFlags &= ~ReInstall;
789
790 AddStates(Pkg);
791 AddSizes(Pkg);
792 }
793 /*}}}*/
794 // DepCache::SetDirty - Switch the package between dirty states /*{{{*/
795 // ---------------------------------------------------------------------
796 /* */
797 void pkgDepCache::SetDirty(PkgIterator const &Pkg, pkgCache::State::PkgRemoveState To)
798 {
799 StateCache &P = PkgState[Pkg->ID];
800 P.DirtyState = To;
801 }
802 /*}}}*/
803 // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
804 // ---------------------------------------------------------------------
805 /* */
806 void pkgDepCache::SetCandidateVersion(VerIterator TargetVer)
807 {
808 pkgCache::PkgIterator Pkg = TargetVer.ParentPkg();
809 StateCache &P = PkgState[Pkg->ID];
810
811 RemoveSizes(Pkg);
812 RemoveStates(Pkg);
813
814 if (P.CandidateVer == P.InstallVer)
815 P.InstallVer = (Version *)TargetVer;
816 P.CandidateVer = (Version *)TargetVer;
817 P.Update(Pkg,*this);
818
819 AddStates(Pkg);
820 Update(Pkg);
821 AddSizes(Pkg);
822 }
823 /*}}}*/
824 // StateCache::Update - Compute the various static display things /*{{{*/
825 // ---------------------------------------------------------------------
826 /* This is called whenever the Candidate version changes. */
827 void pkgDepCache::StateCache::Update(PkgIterator Pkg,pkgCache &Cache)
828 {
829 // Some info
830 VerIterator Ver = CandidateVerIter(Cache);
831
832 // Use a null string or the version string
833 if (Ver.end() == true)
834 CandVersion = "";
835 else
836 CandVersion = Ver.VerStr();
837
838 // Find the current version
839 CurVersion = "";
840 if (Pkg->CurrentVer != 0)
841 CurVersion = Pkg.CurrentVer().VerStr();
842
843 // Strip off the epochs for display
844 CurVersion = StripEpoch(CurVersion);
845 CandVersion = StripEpoch(CandVersion);
846
847 // Figure out if its up or down or equal
848 Status = Ver.CompareVer(Pkg.CurrentVer());
849 if (Pkg->CurrentVer == 0 || Pkg->VersionList == 0 || CandidateVer == 0)
850 Status = 2;
851 }
852 /*}}}*/
853 // StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
854 // ---------------------------------------------------------------------
855 /* */
856 const char *pkgDepCache::StateCache::StripEpoch(const char *Ver)
857 {
858 if (Ver == 0)
859 return 0;
860
861 // Strip any epoch
862 for (const char *I = Ver; *I != 0; I++)
863 if (*I == ':')
864 return I + 1;
865 return Ver;
866 }
867 /*}}}*/
868
869 // Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
870 // ---------------------------------------------------------------------
871 /* The default just returns the highest available version that is not
872 a source and automatic. */
873 pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg)
874 {
875 /* Not source/not automatic versions cannot be a candidate version
876 unless they are already installed */
877 VerIterator Last(*(pkgCache *)this,0);
878
879 for (VerIterator I = Pkg.VersionList(); I.end() == false; I++)
880 {
881 if (Pkg.CurrentVer() == I)
882 return I;
883
884 for (VerFileIterator J = I.FileList(); J.end() == false; J++)
885 {
886 if ((J.File()->Flags & Flag::NotSource) != 0)
887 continue;
888
889 /* Stash the highest version of a not-automatic source, we use it
890 if there is nothing better */
891 if ((J.File()->Flags & Flag::NotAutomatic) != 0)
892 {
893 if (Last.end() == true)
894 Last = I;
895 continue;
896 }
897
898 return I;
899 }
900 }
901
902 return Last;
903 }
904 /*}}}*/
905 // Policy::IsImportantDep - True if the dependency is important /*{{{*/
906 // ---------------------------------------------------------------------
907 /* */
908 bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep)
909 {
910 return Dep.IsCritical();
911 }
912 /*}}}*/