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>
29 pkgDepCache::ActionGroup::ActionGroup(pkgDepCache
&cache
) :
30 cache(cache
), released(false)
35 void pkgDepCache::ActionGroup::release()
39 if(cache
.group_level
== 0)
40 std::cerr
<< "W: Unbalanced action groups, expect badness" << std::endl
;
45 if(cache
.group_level
== 0)
53 pkgDepCache::ActionGroup::~ActionGroup()
58 // DepCache::pkgDepCache - Constructors /*{{{*/
59 // ---------------------------------------------------------------------
61 pkgDepCache::pkgDepCache(pkgCache
*pCache
,Policy
*Plcy
) :
62 group_level(0), Cache(pCache
), PkgState(0), DepState(0)
67 delLocalPolicy
= LocalPolicy
= new Policy
;
70 // DepCache::~pkgDepCache - Destructor /*{{{*/
71 // ---------------------------------------------------------------------
73 pkgDepCache::~pkgDepCache()
77 delete delLocalPolicy
;
80 // DepCache::Init - Generate the initial extra structures. /*{{{*/
81 // ---------------------------------------------------------------------
82 /* This allocats the extension buffers and initializes them. */
83 bool pkgDepCache::Init(OpProgress
*Prog
)
85 // Suppress mark updates during this operation (just in case) and
86 // run a mark operation when Init terminates.
87 ActionGroup
actions(*this);
91 PkgState
= new StateCache
[Head().PackageCount
];
92 DepState
= new unsigned char[Head().DependsCount
];
93 memset(PkgState
,0,sizeof(*PkgState
)*Head().PackageCount
);
94 memset(DepState
,0,sizeof(*DepState
)*Head().DependsCount
);
98 Prog
->OverallProgress(0,2*Head().PackageCount
,Head().PackageCount
,
99 _("Building dependency tree"));
100 Prog
->SubProgress(Head().PackageCount
,_("Candidate versions"));
103 /* Set the current state of everything. In this state all of the
104 packages are kept exactly as is. See AllUpgrade */
106 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
109 Prog
->Progress(Done
);
111 // Find the proper cache slot
112 StateCache
&State
= PkgState
[I
->ID
];
115 // Figure out the install version
116 State
.CandidateVer
= GetCandidateVer(I
);
117 State
.InstallVer
= I
.CurrentVer();
118 State
.Mode
= ModeKeep
;
120 State
.Update(I
,*this);
126 Prog
->OverallProgress(Head().PackageCount
,2*Head().PackageCount
,
128 _("Building dependency tree"));
129 Prog
->SubProgress(Head().PackageCount
,_("Dependency generation"));
141 bool pkgDepCache::readStateFile(OpProgress
*Prog
)
144 string state
= _config
->FindDir("Dir::State") + "pkgstates";
145 if(FileExists(state
)) {
146 state_file
.Open(state
, FileFd::ReadOnly
);
147 int file_size
= state_file
.Size();
149 Prog
->OverallProgress(0, file_size
, 1,
150 _("Reading state information"));
152 pkgTagFile
tagfile(&state_file
);
153 pkgTagSection section
;
155 while(tagfile
.Step(section
)) {
156 string pkgname
= section
.FindS("Package");
157 pkgCache::PkgIterator pkg
=Cache
->FindPkg(pkgname
);
158 // Silently ignore unknown packages and packages with no actual
160 if(!pkg
.end() && !pkg
.VersionList().end()) {
161 short reason
= section
.FindI("Auto-Installed", 0);
163 PkgState
[pkg
->ID
].Flags
|= Flag::Auto
;
164 if(_config
->FindB("Debug::pkgAutoRemove",false))
165 std::cout
<< "Auto-Installed : " << pkgname
<< std::endl
;
168 Prog
->OverallProgress(amt
, file_size
, 1,
169 _("Reading state information"));
172 Prog
->OverallProgress(file_size
, file_size
, 1,
173 _("Reading state information"));
180 bool pkgDepCache::writeStateFile(OpProgress
*prog
)
183 string state
= _config
->FindDir("Dir::State") + "pkgstates";
185 if(_config
->FindB("Debug::pkgAutoRemove",false))
186 std::clog
<< "pkgDepCache::writeStateFile()" << std::endl
;
188 if(!StateFile
.Open(state
, FileFd::WriteEmpty
))
189 return _error
->Error(_("Failed to write StateFile %s"),
192 std::ostringstream ostr
;
193 for(pkgCache::PkgIterator pkg
=Cache
->PkgBegin(); !pkg
.end();pkg
++) {
195 if(PkgState
[pkg
->ID
].Flags
& Flag::Auto
) {
196 if(_config
->FindB("Debug::pkgAutoRemove",false))
197 std::clog
<< "AutoInstall: " << pkg
.Name() << std::endl
;
198 ostr
.str(string(""));
199 ostr
<< "Package: " << pkg
.Name()
200 << "\nAuto-Installed: 1\n\n";
201 StateFile
.Write(ostr
.str().c_str(), ostr
.str().size());
207 // DepCache::CheckDep - Checks a single dependency /*{{{*/
208 // ---------------------------------------------------------------------
209 /* This first checks the dependency against the main target package and
210 then walks along the package provides list and checks if each provides
211 will be installed then checks the provides against the dep. Res will be
212 set to the package which was used to satisfy the dep. */
213 bool pkgDepCache::CheckDep(DepIterator Dep
,int Type
,PkgIterator
&Res
)
215 Res
= Dep
.TargetPkg();
217 /* Check simple depends. A depends -should- never self match but
218 we allow it anyhow because dpkg does. Technically it is a packaging
219 bug. Conflicts may never self match */
220 if (Dep
.TargetPkg() != Dep
.ParentPkg() ||
221 (Dep
->Type
!= Dep::Conflicts
&& Dep
->Type
!= Dep::Obsoletes
))
223 PkgIterator Pkg
= Dep
.TargetPkg();
224 // Check the base package
225 if (Type
== NowVersion
&& Pkg
->CurrentVer
!= 0)
226 if (VS().CheckDep(Pkg
.CurrentVer().VerStr(),Dep
->CompareOp
,
227 Dep
.TargetVer()) == true)
230 if (Type
== InstallVersion
&& PkgState
[Pkg
->ID
].InstallVer
!= 0)
231 if (VS().CheckDep(PkgState
[Pkg
->ID
].InstVerIter(*this).VerStr(),
232 Dep
->CompareOp
,Dep
.TargetVer()) == true)
235 if (Type
== CandidateVersion
&& PkgState
[Pkg
->ID
].CandidateVer
!= 0)
236 if (VS().CheckDep(PkgState
[Pkg
->ID
].CandidateVerIter(*this).VerStr(),
237 Dep
->CompareOp
,Dep
.TargetVer()) == true)
241 if (Dep
->Type
== Dep::Obsoletes
)
244 // Check the providing packages
245 PrvIterator P
= Dep
.TargetPkg().ProvidesList();
246 PkgIterator Pkg
= Dep
.ParentPkg();
247 for (; P
.end() != true; P
++)
249 /* Provides may never be applied against the same package if it is
250 a conflicts. See the comment above. */
251 if (P
.OwnerPkg() == Pkg
&& Dep
->Type
== Dep::Conflicts
)
254 // Check if the provides is a hit
255 if (Type
== NowVersion
)
257 if (P
.OwnerPkg().CurrentVer() != P
.OwnerVer())
261 if (Type
== InstallVersion
)
263 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
264 if (State
.InstallVer
!= (Version
*)P
.OwnerVer())
268 if (Type
== CandidateVersion
)
270 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
271 if (State
.CandidateVer
!= (Version
*)P
.OwnerVer())
275 // Compare the versions.
276 if (VS().CheckDep(P
.ProvideVersion(),Dep
->CompareOp
,Dep
.TargetVer()) == true)
286 // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
287 // ---------------------------------------------------------------------
288 /* Call with Mult = -1 to preform the inverse opration */
289 void pkgDepCache::AddSizes(const PkgIterator
&Pkg
,signed long Mult
)
291 StateCache
&P
= PkgState
[Pkg
->ID
];
293 if (Pkg
->VersionList
== 0)
296 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
300 // Compute the size data
301 if (P
.NewInstall() == true)
303 iUsrSize
+= (signed)(Mult
*P
.InstVerIter(*this)->InstalledSize
);
304 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
309 if (Pkg
->CurrentVer
!= 0 &&
310 (P
.InstallVer
!= (Version
*)Pkg
.CurrentVer() ||
311 (P
.iFlags
& ReInstall
) == ReInstall
) && P
.InstallVer
!= 0)
313 iUsrSize
+= (signed)(Mult
*((signed)P
.InstVerIter(*this)->InstalledSize
-
314 (signed)Pkg
.CurrentVer()->InstalledSize
));
315 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
320 if (Pkg
.State() == pkgCache::PkgIterator::NeedsUnpack
&&
323 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
328 if (Pkg
->CurrentVer
!= 0 && P
.InstallVer
== 0)
330 iUsrSize
-= (signed)(Mult
*Pkg
.CurrentVer()->InstalledSize
);
335 // DepCache::AddStates - Add the package to the state counter /*{{{*/
336 // ---------------------------------------------------------------------
337 /* This routine is tricky to use, you must make sure that it is never
338 called twice for the same package. This means the Remove/Add section
339 should be as short as possible and not encompass any code that will
340 calld Remove/Add itself. Remember, dependencies can be circular so
341 while processing a dep for Pkg it is possible that Add/Remove
342 will be called on Pkg */
343 void pkgDepCache::AddStates(const PkgIterator
&Pkg
,int Add
)
345 StateCache
&State
= PkgState
[Pkg
->ID
];
347 // The Package is broken
348 if ((State
.DepState
& DepInstMin
) != DepInstMin
)
352 if (Pkg
.State() != PkgIterator::NeedsNothing
)
356 if (Pkg
->CurrentVer
== 0)
358 if (State
.Mode
== ModeDelete
&&
359 (State
.iFlags
| Purge
) == Purge
&& Pkg
.Purge() == false)
362 if (State
.Mode
== ModeInstall
)
367 // Installed, no upgrade
368 if (State
.Status
== 0)
370 if (State
.Mode
== ModeDelete
)
373 if ((State
.iFlags
& ReInstall
) == ReInstall
)
379 // Alll 3 are possible
380 if (State
.Mode
== ModeDelete
)
382 if (State
.Mode
== ModeKeep
)
384 if (State
.Mode
== ModeInstall
)
388 // DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
389 // ---------------------------------------------------------------------
390 /* The or group results are stored in the last item of the or group. This
391 allows easy detection of the state of a whole or'd group. */
392 void pkgDepCache::BuildGroupOrs(VerIterator
const &V
)
394 unsigned char Group
= 0;
396 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
398 // Build the dependency state.
399 unsigned char &State
= DepState
[D
->ID
];
401 /* Invert for Conflicts. We have to do this twice to get the
402 right sense for a conflicts group */
403 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
406 // Add to the group if we are within an or..
410 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
413 // Invert for Conflicts
414 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
419 // DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
420 // ---------------------------------------------------------------------
421 /* This is used to run over a dependency list and determine the dep
422 state of the list, filtering it through both a Min check and a Policy
423 check. The return result will have SetMin/SetPolicy low if a check
424 fails. It uses the DepState cache for it's computations. */
425 unsigned char pkgDepCache::VersionState(DepIterator D
,unsigned char Check
,
426 unsigned char SetMin
,
427 unsigned char SetPolicy
)
429 unsigned char Dep
= 0xFF;
431 while (D
.end() != true)
433 // Compute a single dependency element (glob or)
434 DepIterator Start
= D
;
435 unsigned char State
= 0;
436 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
438 State
|= DepState
[D
->ID
];
439 LastOR
= (D
->CompareOp
& Dep::Or
) == Dep::Or
;
442 // Minimum deps that must be satisfied to have a working package
443 if (Start
.IsCritical() == true)
444 if ((State
& Check
) != Check
)
447 // Policy deps that must be satisfied to install the package
448 if (IsImportantDep(Start
) == true &&
449 (State
& Check
) != Check
)
456 // DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
457 // ---------------------------------------------------------------------
458 /* This is the main dependency computation bit. It computes the 3 main
459 results for a dependencys, Now, Install and Candidate. Callers must
460 invert the result if dealing with conflicts. */
461 unsigned char pkgDepCache::DependencyState(DepIterator
&D
)
463 unsigned char State
= 0;
465 if (CheckDep(D
,NowVersion
) == true)
467 if (CheckDep(D
,InstallVersion
) == true)
469 if (CheckDep(D
,CandidateVersion
) == true)
475 // DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
476 // ---------------------------------------------------------------------
477 /* This determines the combined dependency representation of a package
478 for its two states now and install. This is done by using the pre-generated
479 dependency information. */
480 void pkgDepCache::UpdateVerState(PkgIterator Pkg
)
482 // Empty deps are always true
483 StateCache
&State
= PkgState
[Pkg
->ID
];
484 State
.DepState
= 0xFF;
486 // Check the Current state
487 if (Pkg
->CurrentVer
!= 0)
489 DepIterator D
= Pkg
.CurrentVer().DependsList();
490 State
.DepState
&= VersionState(D
,DepNow
,DepNowMin
,DepNowPolicy
);
493 /* Check the candidate state. We do not compare against the whole as
494 a candidate state but check the candidate version against the
496 if (State
.CandidateVer
!= 0)
498 DepIterator D
= State
.CandidateVerIter(*this).DependsList();
499 State
.DepState
&= VersionState(D
,DepInstall
,DepCandMin
,DepCandPolicy
);
502 // Check target state which can only be current or installed
503 if (State
.InstallVer
!= 0)
505 DepIterator D
= State
.InstVerIter(*this).DependsList();
506 State
.DepState
&= VersionState(D
,DepInstall
,DepInstMin
,DepInstPolicy
);
510 // DepCache::Update - Figure out all the state information /*{{{*/
511 // ---------------------------------------------------------------------
512 /* This will figure out the state of all the packages and all the
513 dependencies based on the current policy. */
514 void pkgDepCache::Update(OpProgress
*Prog
)
524 // Perform the depends pass
526 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
528 if (Prog
!= 0 && Done
%20 == 0)
529 Prog
->Progress(Done
);
530 for (VerIterator V
= I
.VersionList(); V
.end() != true; V
++)
532 unsigned char Group
= 0;
534 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
536 // Build the dependency state.
537 unsigned char &State
= DepState
[D
->ID
];
538 State
= DependencyState(D
);
540 // Add to the group if we are within an or..
543 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
546 // Invert for Conflicts
547 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
552 // Compute the pacakge dependency state and size additions
559 Prog
->Progress(Done
);
564 // DepCache::Update - Update the deps list of a package /*{{{*/
565 // ---------------------------------------------------------------------
566 /* This is a helper for update that only does the dep portion of the scan.
567 It is mainly meant to scan reverse dependencies. */
568 void pkgDepCache::Update(DepIterator D
)
570 // Update the reverse deps
571 for (;D
.end() != true; D
++)
573 unsigned char &State
= DepState
[D
->ID
];
574 State
= DependencyState(D
);
576 // Invert for Conflicts
577 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
580 RemoveStates(D
.ParentPkg());
581 BuildGroupOrs(D
.ParentVer());
582 UpdateVerState(D
.ParentPkg());
583 AddStates(D
.ParentPkg());
587 // DepCache::Update - Update the related deps of a package /*{{{*/
588 // ---------------------------------------------------------------------
589 /* This is called whenever the state of a package changes. It updates
590 all cached dependencies related to this package. */
591 void pkgDepCache::Update(PkgIterator
const &Pkg
)
593 // Recompute the dep of the package
598 // Update the reverse deps
599 Update(Pkg
.RevDependsList());
601 // Update the provides map for the current ver
602 if (Pkg
->CurrentVer
!= 0)
603 for (PrvIterator P
= Pkg
.CurrentVer().ProvidesList();
604 P
.end() != true; P
++)
605 Update(P
.ParentPkg().RevDependsList());
607 // Update the provides map for the candidate ver
608 if (PkgState
[Pkg
->ID
].CandidateVer
!= 0)
609 for (PrvIterator P
= PkgState
[Pkg
->ID
].CandidateVerIter(*this).ProvidesList();
610 P
.end() != true; P
++)
611 Update(P
.ParentPkg().RevDependsList());
616 // DepCache::MarkKeep - Put the package in the keep state /*{{{*/
617 // ---------------------------------------------------------------------
619 void pkgDepCache::MarkKeep(PkgIterator
const &Pkg
, bool Soft
, bool FromUser
)
621 // Simplifies other routines.
622 if (Pkg
.end() == true)
625 /* Reject an attempt to keep a non-source broken installed package, those
627 if (Pkg
.State() == PkgIterator::NeedsUnpack
&&
628 Pkg
.CurrentVer().Downloadable() == false)
631 /** \todo Can this be moved later in the method? */
632 ActionGroup
group(*this);
634 /* We changed the soft state all the time so the UI is a bit nicer
636 StateCache
&P
= PkgState
[Pkg
->ID
];
638 P
.iFlags
|= AutoKept
;
640 P
.iFlags
&= ~AutoKept
;
642 // Check that it is not already kept
643 if (P
.Mode
== ModeKeep
)
646 // We dont even try to keep virtual packages..
647 if (Pkg
->VersionList
== 0)
650 if(FromUser
&& !P
.Marked
)
651 P
.Flags
&= ~Flag::Auto
;
656 if (Pkg
->CurrentVer
== 0)
659 P
.InstallVer
= Pkg
.CurrentVer();
668 // DepCache::MarkDelete - Put the package in the delete state /*{{{*/
669 // ---------------------------------------------------------------------
671 void pkgDepCache::MarkDelete(PkgIterator
const &Pkg
, bool rPurge
)
673 // Simplifies other routines.
674 if (Pkg
.end() == true)
677 ActionGroup
group(*this);
679 // Check that it is not already marked for delete
680 StateCache
&P
= PkgState
[Pkg
->ID
];
681 P
.iFlags
&= ~(AutoKept
| Purge
);
685 if ((P
.Mode
== ModeDelete
|| P
.InstallVer
== 0) &&
686 (Pkg
.Purge() == true || rPurge
== false))
689 // We dont even try to delete virtual packages..
690 if (Pkg
->VersionList
== 0)
696 if (Pkg
->CurrentVer
== 0 && (Pkg
.Purge() == true || rPurge
== false))
707 // DepCache::MarkInstall - Put the package in the install state /*{{{*/
708 // ---------------------------------------------------------------------
710 void pkgDepCache::MarkInstall(PkgIterator
const &Pkg
,bool AutoInst
,
711 unsigned long Depth
, bool FromUser
)
716 // Simplifies other routines.
717 if (Pkg
.end() == true)
720 ActionGroup
group(*this);
722 /* Check that it is not already marked for install and that it can be
724 StateCache
&P
= PkgState
[Pkg
->ID
];
725 P
.iFlags
&= ~AutoKept
;
726 if (P
.InstBroken() == false && (P
.Mode
== ModeInstall
||
727 P
.CandidateVer
== (Version
*)Pkg
.CurrentVer()))
729 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer() && P
.InstallVer
== 0)
730 MarkKeep(Pkg
, false, FromUser
);
734 // See if there is even any possible instalation candidate
735 if (P
.CandidateVer
== 0)
738 // We dont even try to install virtual packages..
739 if (Pkg
->VersionList
== 0)
742 /* Target the candidate version and remove the autoflag. We reset the
743 autoflag below if this was called recursively. Otherwise the user
744 should have the ability to de-auto a package by changing its state */
748 P
.Mode
= ModeInstall
;
749 P
.InstallVer
= P
.CandidateVer
;
753 // Set it to manual if it's a new install or cancelling the
754 // removal of a garbage package.
755 if(P
.Status
== 2 || (!Pkg
.CurrentVer().end() && !P
.Marked
))
756 P
.Flags
&= ~Flag::Auto
;
760 // Set it to auto if this is a new install.
762 P
.Flags
|= Flag::Auto
;
764 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer())
771 if (AutoInst
== false)
774 DepIterator Dep
= P
.InstVerIter(*this).DependsList();
775 for (; Dep
.end() != true;)
778 DepIterator Start
= Dep
;
781 for (bool LastOR
= true; Dep
.end() == false && LastOR
== true; Dep
++,Ors
++)
783 LastOR
= (Dep
->CompareOp
& Dep::Or
) == Dep::Or
;
785 if ((DepState
[Dep
->ID
] & DepInstall
) == DepInstall
)
789 // Dep is satisfied okay.
793 /* Check if this dep should be consider for install. If it is a user
794 defined important dep and we are installed a new package then
795 it will be installed. Otherwise we only worry about critical deps */
796 if (IsImportantDep(Start
) == false)
798 if (Pkg
->CurrentVer
!= 0 && Start
.IsCritical() == false)
801 /* If we are in an or group locate the first or that can
802 succeed. We have already cached this.. */
803 for (; Ors
> 1 && (DepState
[Start
->ID
] & DepCVer
) != DepCVer
; Ors
--)
806 /* This bit is for processing the possibilty of an install/upgrade
807 fixing the problem */
808 SPtrArray
<Version
*> List
= Start
.AllTargets();
809 if ((DepState
[Start
->ID
] & DepCVer
) == DepCVer
)
811 // Right, find the best version to install..
812 Version
**Cur
= List
;
813 PkgIterator P
= Start
.TargetPkg();
814 PkgIterator
InstPkg(*Cache
,0);
816 // See if there are direct matches (at the start of the list)
817 for (; *Cur
!= 0 && (*Cur
)->ParentPkg
== P
.Index(); Cur
++)
819 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
820 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
826 // Select the highest priority providing package
827 if (InstPkg
.end() == true)
829 pkgPrioSortList(*Cache
,Cur
);
830 for (; *Cur
!= 0; Cur
++)
832 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
833 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
840 if (InstPkg
.end() == false)
841 MarkInstall(InstPkg
, true, Depth
+ 1, false);
846 /* For conflicts we just de-install the package and mark as auto,
847 Conflicts may not have or groups */
848 if (Start
->Type
== Dep::Conflicts
|| Start
->Type
== Dep::Obsoletes
)
850 for (Version
**I
= List
; *I
!= 0; I
++)
852 VerIterator
Ver(*this,*I
);
853 PkgIterator Pkg
= Ver
.ParentPkg();
862 // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
863 // ---------------------------------------------------------------------
865 void pkgDepCache::SetReInstall(PkgIterator
const &Pkg
,bool To
)
867 ActionGroup
group(*this);
872 StateCache
&P
= PkgState
[Pkg
->ID
];
874 P
.iFlags
|= ReInstall
;
876 P
.iFlags
&= ~ReInstall
;
882 // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
883 // ---------------------------------------------------------------------
885 void pkgDepCache::SetCandidateVersion(VerIterator TargetVer
)
887 ActionGroup
group(*this);
889 pkgCache::PkgIterator Pkg
= TargetVer
.ParentPkg();
890 StateCache
&P
= PkgState
[Pkg
->ID
];
895 if (P
.CandidateVer
== P
.InstallVer
)
896 P
.InstallVer
= (Version
*)TargetVer
;
897 P
.CandidateVer
= (Version
*)TargetVer
;
905 void pkgDepCache::MarkAuto(const PkgIterator
&Pkg
, bool Auto
)
907 StateCache
&state
= PkgState
[Pkg
->ID
];
909 ActionGroup
group(*this);
912 state
.Flags
|= Flag::Auto
;
914 state
.Flags
&= ~Flag::Auto
;
917 // StateCache::Update - Compute the various static display things /*{{{*/
918 // ---------------------------------------------------------------------
919 /* This is called whenever the Candidate version changes. */
920 void pkgDepCache::StateCache::Update(PkgIterator Pkg
,pkgCache
&Cache
)
923 VerIterator Ver
= CandidateVerIter(Cache
);
925 // Use a null string or the version string
926 if (Ver
.end() == true)
929 CandVersion
= Ver
.VerStr();
931 // Find the current version
933 if (Pkg
->CurrentVer
!= 0)
934 CurVersion
= Pkg
.CurrentVer().VerStr();
936 // Strip off the epochs for display
937 CurVersion
= StripEpoch(CurVersion
);
938 CandVersion
= StripEpoch(CandVersion
);
940 // Figure out if its up or down or equal
941 Status
= Ver
.CompareVer(Pkg
.CurrentVer());
942 if (Pkg
->CurrentVer
== 0 || Pkg
->VersionList
== 0 || CandidateVer
== 0)
946 // StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
947 // ---------------------------------------------------------------------
949 const char *pkgDepCache::StateCache::StripEpoch(const char *Ver
)
955 for (const char *I
= Ver
; *I
!= 0; I
++)
962 // Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
963 // ---------------------------------------------------------------------
964 /* The default just returns the highest available version that is not
965 a source and automatic. */
966 pkgCache::VerIterator
pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg
)
968 /* Not source/not automatic versions cannot be a candidate version
969 unless they are already installed */
970 VerIterator
Last(*(pkgCache
*)this,0);
972 for (VerIterator I
= Pkg
.VersionList(); I
.end() == false; I
++)
974 if (Pkg
.CurrentVer() == I
)
977 for (VerFileIterator J
= I
.FileList(); J
.end() == false; J
++)
979 if ((J
.File()->Flags
& Flag::NotSource
) != 0)
982 /* Stash the highest version of a not-automatic source, we use it
983 if there is nothing better */
984 if ((J
.File()->Flags
& Flag::NotAutomatic
) != 0)
986 if (Last
.end() == true)
998 // Policy::IsImportantDep - True if the dependency is important /*{{{*/
999 // ---------------------------------------------------------------------
1001 bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep
)
1003 return Dep
.IsCritical();
1007 pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc()
1008 : constructedSuccessfully(false)
1010 Configuration::Item
const *Opts
;
1011 Opts
= _config
->Tree("APT::NeverAutoRemove");
1012 if (Opts
!= 0 && Opts
->Child
!= 0)
1015 for (; Opts
!= 0; Opts
= Opts
->Next
)
1017 if (Opts
->Value
.empty() == true)
1020 regex_t
*p
= new regex_t
;
1021 if(regcomp(p
,Opts
->Value
.c_str(),
1022 REG_EXTENDED
| REG_ICASE
| REG_NOSUB
) != 0)
1026 _error
->Error("Regex compilation error for APT::NeverAutoRemove");
1030 rootSetRegexp
.push_back(p
);
1034 constructedSuccessfully
= true;
1037 pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc()
1039 for(unsigned int i
= 0; i
< rootSetRegexp
.size(); i
++)
1041 regfree(rootSetRegexp
[i
]);
1042 delete rootSetRegexp
[i
];
1047 bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator
&pkg
)
1049 for(unsigned int i
= 0; i
< rootSetRegexp
.size(); i
++)
1050 if (regexec(rootSetRegexp
[i
], pkg
.Name(), 0, 0, 0) == 0)
1056 pkgDepCache::InRootSetFunc
*pkgDepCache::GetRootSetFunc()
1058 DefaultRootSetFunc
*f
= new DefaultRootSetFunc
;
1059 if(f
->wasConstructedSuccessfully())
1068 bool pkgDepCache::MarkFollowsRecommends()
1070 return _config
->FindB("APT::AutoRemove::RecommendsImportant", true);
1073 bool pkgDepCache::MarkFollowsSuggests()
1075 return _config
->FindB("APT::AutoRemove::SuggestsImportant", false);
1078 // the main mark algorithm
1079 bool pkgDepCache::MarkRequired(InRootSetFunc
&userFunc
)
1081 bool follow_recommends
;
1082 bool follow_suggests
;
1085 for(PkgIterator p
= PkgBegin(); !p
.end(); ++p
)
1087 PkgState
[p
->ID
].Marked
= false;
1088 PkgState
[p
->ID
].Garbage
= false;
1091 if(_config
->FindB("Debug::pkgAutoRemove",false)
1092 && PkgState
[p
->ID
].Flags
& Flag::Auto
)
1093 std::clog
<< "AutoDep: " << p
.Name() << std::endl
;
1097 follow_recommends
= MarkFollowsRecommends();
1098 follow_suggests
= MarkFollowsSuggests();
1102 // do the mark part, this is the core bit of the algorithm
1103 for(PkgIterator p
= PkgBegin(); !p
.end(); ++p
)
1105 if(!(PkgState
[p
->ID
].Flags
& Flag::Auto
) ||
1106 (p
->Flags
& Flag::Essential
) ||
1107 userFunc
.InRootSet(p
))
1110 // the package is installed (and set to keep)
1111 if(PkgState
[p
->ID
].Keep() && !p
.CurrentVer().end())
1112 MarkPackage(p
, p
.CurrentVer(),
1113 follow_recommends
, follow_suggests
);
1114 // the package is to be installed
1115 else if(PkgState
[p
->ID
].Install())
1116 MarkPackage(p
, PkgState
[p
->ID
].InstVerIter(*this),
1117 follow_recommends
, follow_suggests
);
1124 // mark a single package in Mark-and-Sweep
1125 void pkgDepCache::MarkPackage(const pkgCache::PkgIterator
&pkg
,
1126 const pkgCache::VerIterator
&ver
,
1127 bool follow_recommends
,
1128 bool follow_suggests
)
1130 pkgDepCache::StateCache
&state
= PkgState
[pkg
->ID
];
1131 VerIterator candver
= state
.CandidateVerIter(*this);
1132 VerIterator instver
= state
.InstVerIter(*this);
1135 // If a package was garbage-collected but is now being marked, we
1136 // should re-select it
1137 // For cases when a pkg is set to upgrade and this trigger the
1138 // removal of a no-longer used dependency. if the pkg is set to
1139 // keep again later it will result in broken deps
1140 if(state
.Delete() && state
.RemoveReason
= Unused
)
1143 mark_install(pkg
, false, false, NULL
);
1144 else if(ver
==pkg
.CurrentVer())
1145 MarkKeep(pkg
, false, false);
1147 instver
=state
.InstVerIter(*this);
1151 // Ignore versions other than the InstVer, and ignore packages
1152 // that are already going to be removed or just left uninstalled.
1153 if(!(ver
== instver
&& !instver
.end()))
1156 // if we are marked already we are done
1160 //std::cout << "Setting Marked for: " << pkg.Name() << std::endl;
1165 for(DepIterator d
= ver
.DependsList(); !d
.end(); ++d
)
1167 if(d
->Type
== Dep::Depends
||
1168 d
->Type
== Dep::PreDepends
||
1169 (follow_recommends
&&
1170 d
->Type
== Dep::Recommends
) ||
1172 d
->Type
== Dep::Suggests
))
1174 // Try all versions of this package.
1175 for(VerIterator V
= d
.TargetPkg().VersionList();
1178 if(_system
->VS
->CheckDep(V
.VerStr(), d
->CompareOp
, d
.TargetVer()))
1180 MarkPackage(V
.ParentPkg(), V
,
1181 follow_recommends
, follow_suggests
);
1184 // Now try virtual packages
1185 for(PrvIterator prv
=d
.TargetPkg().ProvidesList();
1188 if(_system
->VS
->CheckDep(prv
.ProvideVersion(), d
->CompareOp
,
1191 MarkPackage(prv
.OwnerPkg(), prv
.OwnerVer(),
1192 follow_recommends
, follow_suggests
);
1200 bool pkgDepCache::Sweep()
1203 for(PkgIterator p
=PkgBegin(); !p
.end(); ++p
)
1205 StateCache
&state
=PkgState
[p
->ID
];
1207 // if it is not marked and it is installed, it's garbage
1208 if(!state
.Marked
&& (!p
.CurrentVer().end() || state
.Install()) &&
1212 if(_config
->FindB("Debug::pkgAutoRemove",false))
1213 std::cout
<< "Garbage: " << p
.Name() << std::endl
;