]>
git.saurik.com Git - apt.git/blob - apt-pkg/depcache.cc
6eb6c1d85283029f2bfeb0037d070dc7c74748fe
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: depcache.cc,v 1.25 2001/05/27 05:36:04 jgg Exp $
4 /* ######################################################################
6 Dependency Cache - Caches Dependency information.
8 ##################################################################### */
10 // Include Files /*{{{*/
12 #pragma implementation "apt-pkg/depcache.h"
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>
20 #include <apt-pkg/fileutl.h>
21 #include <apt-pkg/configuration.h>
22 #include <apt-pkg/pkgsystem.h>
23 #include <apt-pkg/tagfile.h>
30 pkgDepCache::ActionGroup::ActionGroup(pkgDepCache
&cache
) :
31 cache(cache
), released(false)
36 void pkgDepCache::ActionGroup::release()
40 if(cache
.group_level
== 0)
41 std::cerr
<< "W: Unbalanced action groups, expect badness" << std::endl
;
46 if(cache
.group_level
== 0)
54 pkgDepCache::ActionGroup::~ActionGroup()
59 // DepCache::pkgDepCache - Constructors /*{{{*/
60 // ---------------------------------------------------------------------
62 pkgDepCache::pkgDepCache(pkgCache
*pCache
,Policy
*Plcy
) :
63 group_level(0), Cache(pCache
), PkgState(0), DepState(0)
68 delLocalPolicy
= LocalPolicy
= new Policy
;
71 // DepCache::~pkgDepCache - Destructor /*{{{*/
72 // ---------------------------------------------------------------------
74 pkgDepCache::~pkgDepCache()
78 delete delLocalPolicy
;
81 // DepCache::Init - Generate the initial extra structures. /*{{{*/
82 // ---------------------------------------------------------------------
83 /* This allocats the extension buffers and initializes them. */
84 bool pkgDepCache::Init(OpProgress
*Prog
)
86 // Suppress mark updates during this operation (just in case) and
87 // run a mark operation when Init terminates.
88 ActionGroup
actions(*this);
92 PkgState
= new StateCache
[Head().PackageCount
];
93 DepState
= new unsigned char[Head().DependsCount
];
94 memset(PkgState
,0,sizeof(*PkgState
)*Head().PackageCount
);
95 memset(DepState
,0,sizeof(*DepState
)*Head().DependsCount
);
99 Prog
->OverallProgress(0,2*Head().PackageCount
,Head().PackageCount
,
100 _("Building dependency tree"));
101 Prog
->SubProgress(Head().PackageCount
,_("Candidate versions"));
104 /* Set the current state of everything. In this state all of the
105 packages are kept exactly as is. See AllUpgrade */
107 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
110 Prog
->Progress(Done
);
112 // Find the proper cache slot
113 StateCache
&State
= PkgState
[I
->ID
];
116 // Figure out the install version
117 State
.CandidateVer
= GetCandidateVer(I
);
118 State
.InstallVer
= I
.CurrentVer();
119 State
.Mode
= ModeKeep
;
121 State
.Update(I
,*this);
127 Prog
->OverallProgress(Head().PackageCount
,2*Head().PackageCount
,
129 _("Building dependency tree"));
130 Prog
->SubProgress(Head().PackageCount
,_("Dependency generation"));
142 bool pkgDepCache::readStateFile(OpProgress
*Prog
)
145 string state
= _config
->FindDir("Dir::State") + "pkgstates";
146 if(FileExists(state
)) {
147 state_file
.Open(state
, FileFd::ReadOnly
);
148 int file_size
= state_file
.Size();
150 Prog
->OverallProgress(0, file_size
, 1,
151 _("Reading state information"));
153 pkgTagFile
tagfile(&state_file
);
154 pkgTagSection section
;
156 while(tagfile
.Step(section
)) {
157 string pkgname
= section
.FindS("Package");
158 pkgCache::PkgIterator pkg
=Cache
->FindPkg(pkgname
);
159 // Silently ignore unknown packages and packages with no actual
161 if(!pkg
.end() && !pkg
.VersionList().end()) {
162 short reason
= section
.FindI("Auto-Installed", 0);
164 PkgState
[pkg
->ID
].Flags
|= Flag::Auto
;
165 if(_config
->FindB("Debug::pkgAutoRemove",false))
166 std::cout
<< "Auto-Installed : " << pkgname
<< std::endl
;
169 Prog
->OverallProgress(amt
, file_size
, 1,
170 _("Reading state information"));
173 Prog
->OverallProgress(file_size
, file_size
, 1,
174 _("Reading state information"));
181 bool pkgDepCache::writeStateFile(OpProgress
*prog
)
184 string state
= _config
->FindDir("Dir::State") + "pkgstates";
186 if(_config
->FindB("Debug::pkgAutoRemove",false))
187 std::clog
<< "pkgDepCache::writeStateFile()" << std::endl
;
189 if(!StateFile
.Open(state
, FileFd::WriteEmpty
))
190 return _error
->Error(_("Failed to write StateFile %s"),
193 std::ostringstream ostr
;
194 for(pkgCache::PkgIterator pkg
=Cache
->PkgBegin(); !pkg
.end();pkg
++) {
196 if(PkgState
[pkg
->ID
].Flags
& Flag::Auto
) {
197 if(_config
->FindB("Debug::pkgAutoRemove",false))
198 std::clog
<< "AutoInstall: " << pkg
.Name() << std::endl
;
199 ostr
.str(string(""));
200 ostr
<< "Package: " << pkg
.Name()
201 << "\nAuto-Installed: 1\n\n";
202 StateFile
.Write(ostr
.str().c_str(), ostr
.str().size());
208 // DepCache::CheckDep - Checks a single dependency /*{{{*/
209 // ---------------------------------------------------------------------
210 /* This first checks the dependency against the main target package and
211 then walks along the package provides list and checks if each provides
212 will be installed then checks the provides against the dep. Res will be
213 set to the package which was used to satisfy the dep. */
214 bool pkgDepCache::CheckDep(DepIterator Dep
,int Type
,PkgIterator
&Res
)
216 Res
= Dep
.TargetPkg();
218 /* Check simple depends. A depends -should- never self match but
219 we allow it anyhow because dpkg does. Technically it is a packaging
220 bug. Conflicts may never self match */
221 if (Dep
.TargetPkg() != Dep
.ParentPkg() ||
222 (Dep
->Type
!= Dep::Conflicts
&& Dep
->Type
!= Dep::Obsoletes
))
224 PkgIterator Pkg
= Dep
.TargetPkg();
225 // Check the base package
226 if (Type
== NowVersion
&& Pkg
->CurrentVer
!= 0)
227 if (VS().CheckDep(Pkg
.CurrentVer().VerStr(),Dep
->CompareOp
,
228 Dep
.TargetVer()) == true)
231 if (Type
== InstallVersion
&& PkgState
[Pkg
->ID
].InstallVer
!= 0)
232 if (VS().CheckDep(PkgState
[Pkg
->ID
].InstVerIter(*this).VerStr(),
233 Dep
->CompareOp
,Dep
.TargetVer()) == true)
236 if (Type
== CandidateVersion
&& PkgState
[Pkg
->ID
].CandidateVer
!= 0)
237 if (VS().CheckDep(PkgState
[Pkg
->ID
].CandidateVerIter(*this).VerStr(),
238 Dep
->CompareOp
,Dep
.TargetVer()) == true)
242 if (Dep
->Type
== Dep::Obsoletes
)
245 // Check the providing packages
246 PrvIterator P
= Dep
.TargetPkg().ProvidesList();
247 PkgIterator Pkg
= Dep
.ParentPkg();
248 for (; P
.end() != true; P
++)
250 /* Provides may never be applied against the same package if it is
251 a conflicts. See the comment above. */
252 if (P
.OwnerPkg() == Pkg
&& Dep
->Type
== Dep::Conflicts
)
255 // Check if the provides is a hit
256 if (Type
== NowVersion
)
258 if (P
.OwnerPkg().CurrentVer() != P
.OwnerVer())
262 if (Type
== InstallVersion
)
264 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
265 if (State
.InstallVer
!= (Version
*)P
.OwnerVer())
269 if (Type
== CandidateVersion
)
271 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
272 if (State
.CandidateVer
!= (Version
*)P
.OwnerVer())
276 // Compare the versions.
277 if (VS().CheckDep(P
.ProvideVersion(),Dep
->CompareOp
,Dep
.TargetVer()) == true)
287 // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
288 // ---------------------------------------------------------------------
289 /* Call with Mult = -1 to preform the inverse opration */
290 void pkgDepCache::AddSizes(const PkgIterator
&Pkg
,signed long Mult
)
292 StateCache
&P
= PkgState
[Pkg
->ID
];
294 if (Pkg
->VersionList
== 0)
297 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
301 // Compute the size data
302 if (P
.NewInstall() == true)
304 iUsrSize
+= (signed)(Mult
*P
.InstVerIter(*this)->InstalledSize
);
305 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
310 if (Pkg
->CurrentVer
!= 0 &&
311 (P
.InstallVer
!= (Version
*)Pkg
.CurrentVer() ||
312 (P
.iFlags
& ReInstall
) == ReInstall
) && P
.InstallVer
!= 0)
314 iUsrSize
+= (signed)(Mult
*((signed)P
.InstVerIter(*this)->InstalledSize
-
315 (signed)Pkg
.CurrentVer()->InstalledSize
));
316 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
321 if (Pkg
.State() == pkgCache::PkgIterator::NeedsUnpack
&&
324 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
329 if (Pkg
->CurrentVer
!= 0 && P
.InstallVer
== 0)
331 iUsrSize
-= (signed)(Mult
*Pkg
.CurrentVer()->InstalledSize
);
336 // DepCache::AddStates - Add the package to the state counter /*{{{*/
337 // ---------------------------------------------------------------------
338 /* This routine is tricky to use, you must make sure that it is never
339 called twice for the same package. This means the Remove/Add section
340 should be as short as possible and not encompass any code that will
341 calld Remove/Add itself. Remember, dependencies can be circular so
342 while processing a dep for Pkg it is possible that Add/Remove
343 will be called on Pkg */
344 void pkgDepCache::AddStates(const PkgIterator
&Pkg
,int Add
)
346 StateCache
&State
= PkgState
[Pkg
->ID
];
348 // The Package is broken
349 if ((State
.DepState
& DepInstMin
) != DepInstMin
)
353 if (Pkg
.State() != PkgIterator::NeedsNothing
)
357 if (Pkg
->CurrentVer
== 0)
359 if (State
.Mode
== ModeDelete
&&
360 (State
.iFlags
| Purge
) == Purge
&& Pkg
.Purge() == false)
363 if (State
.Mode
== ModeInstall
)
368 // Installed, no upgrade
369 if (State
.Status
== 0)
371 if (State
.Mode
== ModeDelete
)
374 if ((State
.iFlags
& ReInstall
) == ReInstall
)
380 // Alll 3 are possible
381 if (State
.Mode
== ModeDelete
)
383 if (State
.Mode
== ModeKeep
)
385 if (State
.Mode
== ModeInstall
)
389 // DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
390 // ---------------------------------------------------------------------
391 /* The or group results are stored in the last item of the or group. This
392 allows easy detection of the state of a whole or'd group. */
393 void pkgDepCache::BuildGroupOrs(VerIterator
const &V
)
395 unsigned char Group
= 0;
397 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
399 // Build the dependency state.
400 unsigned char &State
= DepState
[D
->ID
];
402 /* Invert for Conflicts. We have to do this twice to get the
403 right sense for a conflicts group */
404 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
407 // Add to the group if we are within an or..
411 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
414 // Invert for Conflicts
415 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
420 // DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
421 // ---------------------------------------------------------------------
422 /* This is used to run over a dependency list and determine the dep
423 state of the list, filtering it through both a Min check and a Policy
424 check. The return result will have SetMin/SetPolicy low if a check
425 fails. It uses the DepState cache for it's computations. */
426 unsigned char pkgDepCache::VersionState(DepIterator D
,unsigned char Check
,
427 unsigned char SetMin
,
428 unsigned char SetPolicy
)
430 unsigned char Dep
= 0xFF;
432 while (D
.end() != true)
434 // Compute a single dependency element (glob or)
435 DepIterator Start
= D
;
436 unsigned char State
= 0;
437 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
439 State
|= DepState
[D
->ID
];
440 LastOR
= (D
->CompareOp
& Dep::Or
) == Dep::Or
;
443 // Minimum deps that must be satisfied to have a working package
444 if (Start
.IsCritical() == true)
445 if ((State
& Check
) != Check
)
448 // Policy deps that must be satisfied to install the package
449 if (IsImportantDep(Start
) == true &&
450 (State
& Check
) != Check
)
457 // DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
458 // ---------------------------------------------------------------------
459 /* This is the main dependency computation bit. It computes the 3 main
460 results for a dependencys, Now, Install and Candidate. Callers must
461 invert the result if dealing with conflicts. */
462 unsigned char pkgDepCache::DependencyState(DepIterator
&D
)
464 unsigned char State
= 0;
466 if (CheckDep(D
,NowVersion
) == true)
468 if (CheckDep(D
,InstallVersion
) == true)
470 if (CheckDep(D
,CandidateVersion
) == true)
476 // DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
477 // ---------------------------------------------------------------------
478 /* This determines the combined dependency representation of a package
479 for its two states now and install. This is done by using the pre-generated
480 dependency information. */
481 void pkgDepCache::UpdateVerState(PkgIterator Pkg
)
483 // Empty deps are always true
484 StateCache
&State
= PkgState
[Pkg
->ID
];
485 State
.DepState
= 0xFF;
487 // Check the Current state
488 if (Pkg
->CurrentVer
!= 0)
490 DepIterator D
= Pkg
.CurrentVer().DependsList();
491 State
.DepState
&= VersionState(D
,DepNow
,DepNowMin
,DepNowPolicy
);
494 /* Check the candidate state. We do not compare against the whole as
495 a candidate state but check the candidate version against the
497 if (State
.CandidateVer
!= 0)
499 DepIterator D
= State
.CandidateVerIter(*this).DependsList();
500 State
.DepState
&= VersionState(D
,DepInstall
,DepCandMin
,DepCandPolicy
);
503 // Check target state which can only be current or installed
504 if (State
.InstallVer
!= 0)
506 DepIterator D
= State
.InstVerIter(*this).DependsList();
507 State
.DepState
&= VersionState(D
,DepInstall
,DepInstMin
,DepInstPolicy
);
511 // DepCache::Update - Figure out all the state information /*{{{*/
512 // ---------------------------------------------------------------------
513 /* This will figure out the state of all the packages and all the
514 dependencies based on the current policy. */
515 void pkgDepCache::Update(OpProgress
*Prog
)
525 // Perform the depends pass
527 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
529 if (Prog
!= 0 && Done%20
== 0)
530 Prog
->Progress(Done
);
531 for (VerIterator V
= I
.VersionList(); V
.end() != true; V
++)
533 unsigned char Group
= 0;
535 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
537 // Build the dependency state.
538 unsigned char &State
= DepState
[D
->ID
];
539 State
= DependencyState(D
);
541 // Add to the group if we are within an or..
544 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
547 // Invert for Conflicts
548 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
553 // Compute the pacakge dependency state and size additions
560 Prog
->Progress(Done
);
565 // DepCache::Update - Update the deps list of a package /*{{{*/
566 // ---------------------------------------------------------------------
567 /* This is a helper for update that only does the dep portion of the scan.
568 It is mainly meant to scan reverse dependencies. */
569 void pkgDepCache::Update(DepIterator D
)
571 // Update the reverse deps
572 for (;D
.end() != true; D
++)
574 unsigned char &State
= DepState
[D
->ID
];
575 State
= DependencyState(D
);
577 // Invert for Conflicts
578 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
581 RemoveStates(D
.ParentPkg());
582 BuildGroupOrs(D
.ParentVer());
583 UpdateVerState(D
.ParentPkg());
584 AddStates(D
.ParentPkg());
588 // DepCache::Update - Update the related deps of a package /*{{{*/
589 // ---------------------------------------------------------------------
590 /* This is called whenever the state of a package changes. It updates
591 all cached dependencies related to this package. */
592 void pkgDepCache::Update(PkgIterator
const &Pkg
)
594 // Recompute the dep of the package
599 // Update the reverse deps
600 Update(Pkg
.RevDependsList());
602 // Update the provides map for the current ver
603 if (Pkg
->CurrentVer
!= 0)
604 for (PrvIterator P
= Pkg
.CurrentVer().ProvidesList();
605 P
.end() != true; P
++)
606 Update(P
.ParentPkg().RevDependsList());
608 // Update the provides map for the candidate ver
609 if (PkgState
[Pkg
->ID
].CandidateVer
!= 0)
610 for (PrvIterator P
= PkgState
[Pkg
->ID
].CandidateVerIter(*this).ProvidesList();
611 P
.end() != true; P
++)
612 Update(P
.ParentPkg().RevDependsList());
617 // DepCache::MarkKeep - Put the package in the keep state /*{{{*/
618 // ---------------------------------------------------------------------
620 void pkgDepCache::MarkKeep(PkgIterator
const &Pkg
, bool Soft
, bool FromUser
)
622 // Simplifies other routines.
623 if (Pkg
.end() == true)
626 /* Reject an attempt to keep a non-source broken installed package, those
628 if (Pkg
.State() == PkgIterator::NeedsUnpack
&&
629 Pkg
.CurrentVer().Downloadable() == false)
632 /** \todo Can this be moved later in the method? */
633 ActionGroup
group(*this);
635 /* We changed the soft state all the time so the UI is a bit nicer
637 StateCache
&P
= PkgState
[Pkg
->ID
];
639 P
.iFlags
|= AutoKept
;
641 P
.iFlags
&= ~AutoKept
;
643 // Check that it is not already kept
644 if (P
.Mode
== ModeKeep
)
647 // We dont even try to keep virtual packages..
648 if (Pkg
->VersionList
== 0)
651 if(FromUser
&& !P
.Marked
)
652 P
.Flags
&= ~Flag::Auto
;
657 if (Pkg
->CurrentVer
== 0)
660 P
.InstallVer
= Pkg
.CurrentVer();
669 // DepCache::MarkDelete - Put the package in the delete state /*{{{*/
670 // ---------------------------------------------------------------------
672 void pkgDepCache::MarkDelete(PkgIterator
const &Pkg
, bool rPurge
)
674 // Simplifies other routines.
675 if (Pkg
.end() == true)
678 ActionGroup
group(*this);
680 // Check that it is not already marked for delete
681 StateCache
&P
= PkgState
[Pkg
->ID
];
682 P
.iFlags
&= ~(AutoKept
| Purge
);
686 if ((P
.Mode
== ModeDelete
|| P
.InstallVer
== 0) &&
687 (Pkg
.Purge() == true || rPurge
== false))
690 // We dont even try to delete virtual packages..
691 if (Pkg
->VersionList
== 0)
697 if (Pkg
->CurrentVer
== 0 && (Pkg
.Purge() == true || rPurge
== false))
708 // DepCache::MarkInstall - Put the package in the install state /*{{{*/
709 // ---------------------------------------------------------------------
711 void pkgDepCache::MarkInstall(PkgIterator
const &Pkg
,bool AutoInst
,
712 unsigned long Depth
, bool FromUser
)
717 // Simplifies other routines.
718 if (Pkg
.end() == true)
721 ActionGroup
group(*this);
723 /* Check that it is not already marked for install and that it can be
725 StateCache
&P
= PkgState
[Pkg
->ID
];
726 P
.iFlags
&= ~AutoKept
;
727 if (P
.InstBroken() == false && (P
.Mode
== ModeInstall
||
728 P
.CandidateVer
== (Version
*)Pkg
.CurrentVer()))
730 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer() && P
.InstallVer
== 0)
731 MarkKeep(Pkg
, false, FromUser
);
735 // See if there is even any possible instalation candidate
736 if (P
.CandidateVer
== 0)
739 // We dont even try to install virtual packages..
740 if (Pkg
->VersionList
== 0)
743 /* Target the candidate version and remove the autoflag. We reset the
744 autoflag below if this was called recursively. Otherwise the user
745 should have the ability to de-auto a package by changing its state */
749 P
.Mode
= ModeInstall
;
750 P
.InstallVer
= P
.CandidateVer
;
754 // Set it to manual if it's a new install or cancelling the
755 // removal of a garbage package.
756 if(P
.Status
== 2 || (!Pkg
.CurrentVer().end() && !P
.Marked
))
757 P
.Flags
&= ~Flag::Auto
;
761 // Set it to auto if this is a new install.
763 P
.Flags
|= Flag::Auto
;
765 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer())
772 if (AutoInst
== false)
775 DepIterator Dep
= P
.InstVerIter(*this).DependsList();
776 for (; Dep
.end() != true;)
779 DepIterator Start
= Dep
;
782 for (bool LastOR
= true; Dep
.end() == false && LastOR
== true; Dep
++,Ors
++)
784 LastOR
= (Dep
->CompareOp
& Dep::Or
) == Dep::Or
;
786 if ((DepState
[Dep
->ID
] & DepInstall
) == DepInstall
)
790 // Dep is satisfied okay.
794 /* Check if this dep should be consider for install. If it is a user
795 defined important dep and we are installed a new package then
796 it will be installed. Otherwise we only worry about critical deps */
797 if (IsImportantDep(Start
) == false)
799 if (Pkg
->CurrentVer
!= 0 && Start
.IsCritical() == false)
802 /* If we are in an or group locate the first or that can
803 succeed. We have already cached this.. */
804 for (; Ors
> 1 && (DepState
[Start
->ID
] & DepCVer
) != DepCVer
; Ors
--)
807 /* This bit is for processing the possibilty of an install/upgrade
808 fixing the problem */
809 SPtrArray
<Version
*> List
= Start
.AllTargets();
810 if ((DepState
[Start
->ID
] & DepCVer
) == DepCVer
)
812 // Right, find the best version to install..
813 Version
**Cur
= List
;
814 PkgIterator P
= Start
.TargetPkg();
815 PkgIterator
InstPkg(*Cache
,0);
817 // See if there are direct matches (at the start of the list)
818 for (; *Cur
!= 0 && (*Cur
)->ParentPkg
== P
.Index(); Cur
++)
820 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
821 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
827 // Select the highest priority providing package
828 if (InstPkg
.end() == true)
830 pkgPrioSortList(*Cache
,Cur
);
831 for (; *Cur
!= 0; Cur
++)
833 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
834 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
841 if (InstPkg
.end() == false)
843 if(_config
->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
844 std::clog
<< "Installing " << InstPkg
.Name()
845 << " as dep of " << Pkg
.Name()
847 MarkInstall(InstPkg
, true, Depth
+ 1, false);
852 /* For conflicts we just de-install the package and mark as auto,
853 Conflicts may not have or groups */
854 if (Start
->Type
== Dep::Conflicts
|| Start
->Type
== Dep::Obsoletes
)
856 for (Version
**I
= List
; *I
!= 0; I
++)
858 VerIterator
Ver(*this,*I
);
859 PkgIterator Pkg
= Ver
.ParentPkg();
868 // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
869 // ---------------------------------------------------------------------
871 void pkgDepCache::SetReInstall(PkgIterator
const &Pkg
,bool To
)
873 ActionGroup
group(*this);
878 StateCache
&P
= PkgState
[Pkg
->ID
];
880 P
.iFlags
|= ReInstall
;
882 P
.iFlags
&= ~ReInstall
;
888 // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
889 // ---------------------------------------------------------------------
891 void pkgDepCache::SetCandidateVersion(VerIterator TargetVer
)
893 ActionGroup
group(*this);
895 pkgCache::PkgIterator Pkg
= TargetVer
.ParentPkg();
896 StateCache
&P
= PkgState
[Pkg
->ID
];
901 if (P
.CandidateVer
== P
.InstallVer
)
902 P
.InstallVer
= (Version
*)TargetVer
;
903 P
.CandidateVer
= (Version
*)TargetVer
;
911 void pkgDepCache::MarkAuto(const PkgIterator
&Pkg
, bool Auto
)
913 StateCache
&state
= PkgState
[Pkg
->ID
];
915 ActionGroup
group(*this);
918 state
.Flags
|= Flag::Auto
;
920 state
.Flags
&= ~Flag::Auto
;
923 // StateCache::Update - Compute the various static display things /*{{{*/
924 // ---------------------------------------------------------------------
925 /* This is called whenever the Candidate version changes. */
926 void pkgDepCache::StateCache::Update(PkgIterator Pkg
,pkgCache
&Cache
)
929 VerIterator Ver
= CandidateVerIter(Cache
);
931 // Use a null string or the version string
932 if (Ver
.end() == true)
935 CandVersion
= Ver
.VerStr();
937 // Find the current version
939 if (Pkg
->CurrentVer
!= 0)
940 CurVersion
= Pkg
.CurrentVer().VerStr();
942 // Strip off the epochs for display
943 CurVersion
= StripEpoch(CurVersion
);
944 CandVersion
= StripEpoch(CandVersion
);
946 // Figure out if its up or down or equal
947 Status
= Ver
.CompareVer(Pkg
.CurrentVer());
948 if (Pkg
->CurrentVer
== 0 || Pkg
->VersionList
== 0 || CandidateVer
== 0)
952 // StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
953 // ---------------------------------------------------------------------
955 const char *pkgDepCache::StateCache::StripEpoch(const char *Ver
)
961 for (const char *I
= Ver
; *I
!= 0; I
++)
968 // Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
969 // ---------------------------------------------------------------------
970 /* The default just returns the highest available version that is not
971 a source and automatic. */
972 pkgCache::VerIterator
pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg
)
974 /* Not source/not automatic versions cannot be a candidate version
975 unless they are already installed */
976 VerIterator
Last(*(pkgCache
*)this,0);
978 for (VerIterator I
= Pkg
.VersionList(); I
.end() == false; I
++)
980 if (Pkg
.CurrentVer() == I
)
983 for (VerFileIterator J
= I
.FileList(); J
.end() == false; J
++)
985 if ((J
.File()->Flags
& Flag::NotSource
) != 0)
988 /* Stash the highest version of a not-automatic source, we use it
989 if there is nothing better */
990 if ((J
.File()->Flags
& Flag::NotAutomatic
) != 0)
992 if (Last
.end() == true)
1004 // Policy::IsImportantDep - True if the dependency is important /*{{{*/
1005 // ---------------------------------------------------------------------
1007 bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep
)
1009 return Dep
.IsCritical();
1013 pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc()
1014 : constructedSuccessfully(false)
1016 Configuration::Item
const *Opts
;
1017 Opts
= _config
->Tree("APT::NeverAutoRemove");
1018 if (Opts
!= 0 && Opts
->Child
!= 0)
1021 for (; Opts
!= 0; Opts
= Opts
->Next
)
1023 if (Opts
->Value
.empty() == true)
1026 regex_t
*p
= new regex_t
;
1027 if(regcomp(p
,Opts
->Value
.c_str(),
1028 REG_EXTENDED
| REG_ICASE
| REG_NOSUB
) != 0)
1032 _error
->Error("Regex compilation error for APT::NeverAutoRemove");
1036 rootSetRegexp
.push_back(p
);
1040 constructedSuccessfully
= true;
1043 pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc()
1045 for(unsigned int i
= 0; i
< rootSetRegexp
.size(); i
++)
1047 regfree(rootSetRegexp
[i
]);
1048 delete rootSetRegexp
[i
];
1053 bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator
&pkg
)
1055 for(unsigned int i
= 0; i
< rootSetRegexp
.size(); i
++)
1056 if (regexec(rootSetRegexp
[i
], pkg
.Name(), 0, 0, 0) == 0)
1062 pkgDepCache::InRootSetFunc
*pkgDepCache::GetRootSetFunc()
1064 DefaultRootSetFunc
*f
= new DefaultRootSetFunc
;
1065 if(f
->wasConstructedSuccessfully())
1074 bool pkgDepCache::MarkFollowsRecommends()
1076 return _config
->FindB("APT::AutoRemove::RecommendsImportant", true);
1079 bool pkgDepCache::MarkFollowsSuggests()
1081 return _config
->FindB("APT::AutoRemove::SuggestsImportant", false);
1084 // the main mark algorithm
1085 bool pkgDepCache::MarkRequired(InRootSetFunc
&userFunc
)
1087 bool follow_recommends
;
1088 bool follow_suggests
;
1091 for(PkgIterator p
= PkgBegin(); !p
.end(); ++p
)
1093 PkgState
[p
->ID
].Marked
= false;
1094 PkgState
[p
->ID
].Garbage
= false;
1097 if(_config
->FindB("Debug::pkgAutoRemove",false)
1098 && PkgState
[p
->ID
].Flags
& Flag::Auto
)
1099 std::clog
<< "AutoDep: " << p
.Name() << std::endl
;
1103 follow_recommends
= MarkFollowsRecommends();
1104 follow_suggests
= MarkFollowsSuggests();
1108 // do the mark part, this is the core bit of the algorithm
1109 for(PkgIterator p
= PkgBegin(); !p
.end(); ++p
)
1111 if(!(PkgState
[p
->ID
].Flags
& Flag::Auto
) ||
1112 (p
->Flags
& Flag::Essential
) ||
1113 userFunc
.InRootSet(p
))
1116 // the package is installed (and set to keep)
1117 if(PkgState
[p
->ID
].Keep() && !p
.CurrentVer().end())
1118 MarkPackage(p
, p
.CurrentVer(),
1119 follow_recommends
, follow_suggests
);
1120 // the package is to be installed
1121 else if(PkgState
[p
->ID
].Install())
1122 MarkPackage(p
, PkgState
[p
->ID
].InstVerIter(*this),
1123 follow_recommends
, follow_suggests
);
1130 // mark a single package in Mark-and-Sweep
1131 void pkgDepCache::MarkPackage(const pkgCache::PkgIterator
&pkg
,
1132 const pkgCache::VerIterator
&ver
,
1133 bool follow_recommends
,
1134 bool follow_suggests
)
1136 pkgDepCache::StateCache
&state
= PkgState
[pkg
->ID
];
1137 VerIterator candver
= state
.CandidateVerIter(*this);
1138 VerIterator instver
= state
.InstVerIter(*this);
1141 // If a package was garbage-collected but is now being marked, we
1142 // should re-select it
1143 // For cases when a pkg is set to upgrade and this trigger the
1144 // removal of a no-longer used dependency. if the pkg is set to
1145 // keep again later it will result in broken deps
1146 if(state
.Delete() && state
.RemoveReason
= Unused
)
1149 mark_install(pkg
, false, false, NULL
);
1150 else if(ver
==pkg
.CurrentVer())
1151 MarkKeep(pkg
, false, false);
1153 instver
=state
.InstVerIter(*this);
1157 // Ignore versions other than the InstVer, and ignore packages
1158 // that are already going to be removed or just left uninstalled.
1159 if(!(ver
== instver
&& !instver
.end()))
1162 // if we are marked already we are done
1166 //std::cout << "Setting Marked for: " << pkg.Name() << std::endl;
1171 for(DepIterator d
= ver
.DependsList(); !d
.end(); ++d
)
1173 if(d
->Type
== Dep::Depends
||
1174 d
->Type
== Dep::PreDepends
||
1175 (follow_recommends
&&
1176 d
->Type
== Dep::Recommends
) ||
1178 d
->Type
== Dep::Suggests
))
1180 // Try all versions of this package.
1181 for(VerIterator V
= d
.TargetPkg().VersionList();
1184 if(_system
->VS
->CheckDep(V
.VerStr(), d
->CompareOp
, d
.TargetVer()))
1186 MarkPackage(V
.ParentPkg(), V
,
1187 follow_recommends
, follow_suggests
);
1190 // Now try virtual packages
1191 for(PrvIterator prv
=d
.TargetPkg().ProvidesList();
1194 if(_system
->VS
->CheckDep(prv
.ProvideVersion(), d
->CompareOp
,
1197 MarkPackage(prv
.OwnerPkg(), prv
.OwnerVer(),
1198 follow_recommends
, follow_suggests
);
1206 bool pkgDepCache::Sweep()
1209 for(PkgIterator p
=PkgBegin(); !p
.end(); ++p
)
1211 StateCache
&state
=PkgState
[p
->ID
];
1213 // if it is not marked and it is installed, it's garbage
1214 if(!state
.Marked
&& (!p
.CurrentVer().end() || state
.Install()) &&
1218 if(_config
->FindB("Debug::pkgAutoRemove",false))
1219 std::cout
<< "Garbage: " << p
.Name() << std::endl
;