]>
git.saurik.com Git - apt.git/blob - apt-pkg/depcache.cc
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 /*{{{*/
11 #include <apt-pkg/depcache.h>
12 #include <apt-pkg/version.h>
13 #include <apt-pkg/error.h>
14 #include <apt-pkg/sptr.h>
15 #include <apt-pkg/algorithms.h>
17 #include <apt-pkg/fileutl.h>
18 #include <apt-pkg/configuration.h>
19 #include <apt-pkg/pkgsystem.h>
20 #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") + "extended_states";
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
, bool InstalledOnly
)
183 if(_config
->FindB("Debug::pkgAutoRemove",false))
184 std::clog
<< "pkgDepCache::writeStateFile()" << std::endl
;
187 string state
= _config
->FindDir("Dir::State") + "extended_states";
189 // if it does not exist, create a empty one
190 if(!FileExists(state
))
192 StateFile
.Open(state
, FileFd::WriteEmpty
);
197 if(!StateFile
.Open(state
, FileFd::ReadOnly
))
198 return _error
->Error(_("Failed to open StateFile %s"),
202 string outfile
= state
+ ".tmp";
203 if((OutFile
= fopen(outfile
.c_str(),"w")) == NULL
)
204 return _error
->Error(_("Failed to write temporary StateFile %s"),
207 // first merge with the existing sections
208 pkgTagFile
tagfile(&StateFile
);
209 pkgTagSection section
;
210 std::set
<string
> pkgs_seen
;
211 const char *nullreorderlist
[] = {0};
212 while(tagfile
.Step(section
)) {
213 string pkgname
= section
.FindS("Package");
214 // Silently ignore unknown packages and packages with no actual
216 pkgCache::PkgIterator pkg
=Cache
->FindPkg(pkgname
);
217 if(pkg
.end() || pkg
.VersionList().end())
219 bool newAuto
= (PkgState
[pkg
->ID
].Flags
& Flag::Auto
);
220 if(_config
->FindB("Debug::pkgAutoRemove",false))
221 std::clog
<< "Update exisiting AutoInstall info: "
222 << pkg
.Name() << std::endl
;
223 TFRewriteData rewrite
[2];
224 rewrite
[0].Tag
= "Auto-Installed";
225 rewrite
[0].Rewrite
= newAuto
? "1" : "0";
226 rewrite
[0].NewTag
= 0;
228 TFRewrite(OutFile
, section
, nullreorderlist
, rewrite
);
229 fprintf(OutFile
,"\n");
230 pkgs_seen
.insert(pkgname
);
233 // then write the ones we have not seen yet
234 std::ostringstream ostr
;
235 for(pkgCache::PkgIterator pkg
=Cache
->PkgBegin(); !pkg
.end(); pkg
++) {
236 if(PkgState
[pkg
->ID
].Flags
& Flag::Auto
) {
237 if (pkgs_seen
.find(pkg
.Name()) != pkgs_seen
.end()) {
238 if(_config
->FindB("Debug::pkgAutoRemove",false))
239 std::clog
<< "Skipping already written " << pkg
.Name() << std::endl
;
242 // skip not installed ones if requested
243 if(InstalledOnly
&& pkg
->CurrentVer
== 0)
245 if(_config
->FindB("Debug::pkgAutoRemove",false))
246 std::clog
<< "Writing new AutoInstall: "
247 << pkg
.Name() << std::endl
;
248 ostr
.str(string(""));
249 ostr
<< "Package: " << pkg
.Name()
250 << "\nAuto-Installed: 1\n\n";
251 fprintf(OutFile
,ostr
.str().c_str());
252 fprintf(OutFile
,"\n");
257 // move the outfile over the real file and set permissions
258 rename(outfile
.c_str(), state
.c_str());
259 chmod(state
.c_str(), 0644);
264 // DepCache::CheckDep - Checks a single dependency /*{{{*/
265 // ---------------------------------------------------------------------
266 /* This first checks the dependency against the main target package and
267 then walks along the package provides list and checks if each provides
268 will be installed then checks the provides against the dep. Res will be
269 set to the package which was used to satisfy the dep. */
270 bool pkgDepCache::CheckDep(DepIterator Dep
,int Type
,PkgIterator
&Res
)
272 Res
= Dep
.TargetPkg();
274 /* Check simple depends. A depends -should- never self match but
275 we allow it anyhow because dpkg does. Technically it is a packaging
276 bug. Conflicts may never self match */
277 if (Dep
.TargetPkg() != Dep
.ParentPkg() ||
278 (Dep
->Type
!= Dep::Conflicts
&& Dep
->Type
!= Dep::DpkgBreaks
&& Dep
->Type
!= Dep::Obsoletes
))
280 PkgIterator Pkg
= Dep
.TargetPkg();
281 // Check the base package
282 if (Type
== NowVersion
&& Pkg
->CurrentVer
!= 0)
283 if (VS().CheckDep(Pkg
.CurrentVer().VerStr(),Dep
->CompareOp
,
284 Dep
.TargetVer()) == true)
287 if (Type
== InstallVersion
&& PkgState
[Pkg
->ID
].InstallVer
!= 0)
288 if (VS().CheckDep(PkgState
[Pkg
->ID
].InstVerIter(*this).VerStr(),
289 Dep
->CompareOp
,Dep
.TargetVer()) == true)
292 if (Type
== CandidateVersion
&& PkgState
[Pkg
->ID
].CandidateVer
!= 0)
293 if (VS().CheckDep(PkgState
[Pkg
->ID
].CandidateVerIter(*this).VerStr(),
294 Dep
->CompareOp
,Dep
.TargetVer()) == true)
298 if (Dep
->Type
== Dep::Obsoletes
)
301 // Check the providing packages
302 PrvIterator P
= Dep
.TargetPkg().ProvidesList();
303 PkgIterator Pkg
= Dep
.ParentPkg();
304 for (; P
.end() != true; P
++)
306 /* Provides may never be applied against the same package if it is
307 a conflicts. See the comment above. */
308 if (P
.OwnerPkg() == Pkg
&&
309 (Dep
->Type
== Dep::Conflicts
|| Dep
->Type
== Dep::DpkgBreaks
))
312 // Check if the provides is a hit
313 if (Type
== NowVersion
)
315 if (P
.OwnerPkg().CurrentVer() != P
.OwnerVer())
319 if (Type
== InstallVersion
)
321 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
322 if (State
.InstallVer
!= (Version
*)P
.OwnerVer())
326 if (Type
== CandidateVersion
)
328 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
329 if (State
.CandidateVer
!= (Version
*)P
.OwnerVer())
333 // Compare the versions.
334 if (VS().CheckDep(P
.ProvideVersion(),Dep
->CompareOp
,Dep
.TargetVer()) == true)
344 // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
345 // ---------------------------------------------------------------------
346 /* Call with Mult = -1 to preform the inverse opration */
347 void pkgDepCache::AddSizes(const PkgIterator
&Pkg
,signed long Mult
)
349 StateCache
&P
= PkgState
[Pkg
->ID
];
351 if (Pkg
->VersionList
== 0)
354 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
358 // Compute the size data
359 if (P
.NewInstall() == true)
361 iUsrSize
+= (signed)(Mult
*P
.InstVerIter(*this)->InstalledSize
);
362 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
367 if (Pkg
->CurrentVer
!= 0 &&
368 (P
.InstallVer
!= (Version
*)Pkg
.CurrentVer() ||
369 (P
.iFlags
& ReInstall
) == ReInstall
) && P
.InstallVer
!= 0)
371 iUsrSize
+= (signed)(Mult
*((signed)P
.InstVerIter(*this)->InstalledSize
-
372 (signed)Pkg
.CurrentVer()->InstalledSize
));
373 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
378 if (Pkg
.State() == pkgCache::PkgIterator::NeedsUnpack
&&
381 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
386 if (Pkg
->CurrentVer
!= 0 && P
.InstallVer
== 0)
388 iUsrSize
-= (signed)(Mult
*Pkg
.CurrentVer()->InstalledSize
);
393 // DepCache::AddStates - Add the package to the state counter /*{{{*/
394 // ---------------------------------------------------------------------
395 /* This routine is tricky to use, you must make sure that it is never
396 called twice for the same package. This means the Remove/Add section
397 should be as short as possible and not encompass any code that will
398 calld Remove/Add itself. Remember, dependencies can be circular so
399 while processing a dep for Pkg it is possible that Add/Remove
400 will be called on Pkg */
401 void pkgDepCache::AddStates(const PkgIterator
&Pkg
,int Add
)
403 StateCache
&State
= PkgState
[Pkg
->ID
];
405 // The Package is broken (either minimal dep or policy dep)
406 if ((State
.DepState
& DepInstMin
) != DepInstMin
)
408 if ((State
.DepState
& DepInstPolicy
) != DepInstPolicy
)
409 iPolicyBrokenCount
+= Add
;
412 if (Pkg
.State() != PkgIterator::NeedsNothing
)
416 if (Pkg
->CurrentVer
== 0)
418 if (State
.Mode
== ModeDelete
&&
419 (State
.iFlags
| Purge
) == Purge
&& Pkg
.Purge() == false)
422 if (State
.Mode
== ModeInstall
)
427 // Installed, no upgrade
428 if (State
.Status
== 0)
430 if (State
.Mode
== ModeDelete
)
433 if ((State
.iFlags
& ReInstall
) == ReInstall
)
439 // Alll 3 are possible
440 if (State
.Mode
== ModeDelete
)
442 if (State
.Mode
== ModeKeep
)
444 if (State
.Mode
== ModeInstall
)
448 // DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
449 // ---------------------------------------------------------------------
450 /* The or group results are stored in the last item of the or group. This
451 allows easy detection of the state of a whole or'd group. */
452 void pkgDepCache::BuildGroupOrs(VerIterator
const &V
)
454 unsigned char Group
= 0;
456 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
458 // Build the dependency state.
459 unsigned char &State
= DepState
[D
->ID
];
461 /* Invert for Conflicts. We have to do this twice to get the
462 right sense for a conflicts group */
463 if (D
->Type
== Dep::Conflicts
||
464 D
->Type
== Dep::DpkgBreaks
||
465 D
->Type
== Dep::Obsoletes
)
468 // Add to the group if we are within an or..
472 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
475 // Invert for Conflicts
476 if (D
->Type
== Dep::Conflicts
||
477 D
->Type
== Dep::DpkgBreaks
||
478 D
->Type
== Dep::Obsoletes
)
483 // DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
484 // ---------------------------------------------------------------------
485 /* This is used to run over a dependency list and determine the dep
486 state of the list, filtering it through both a Min check and a Policy
487 check. The return result will have SetMin/SetPolicy low if a check
488 fails. It uses the DepState cache for it's computations. */
489 unsigned char pkgDepCache::VersionState(DepIterator D
,unsigned char Check
,
490 unsigned char SetMin
,
491 unsigned char SetPolicy
)
493 unsigned char Dep
= 0xFF;
495 while (D
.end() != true)
497 // Compute a single dependency element (glob or)
498 DepIterator Start
= D
;
499 unsigned char State
= 0;
500 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
502 State
|= DepState
[D
->ID
];
503 LastOR
= (D
->CompareOp
& Dep::Or
) == Dep::Or
;
506 // Minimum deps that must be satisfied to have a working package
507 if (Start
.IsCritical() == true)
508 if ((State
& Check
) != Check
)
511 // Policy deps that must be satisfied to install the package
512 if (IsImportantDep(Start
) == true &&
513 (State
& Check
) != Check
)
520 // DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
521 // ---------------------------------------------------------------------
522 /* This is the main dependency computation bit. It computes the 3 main
523 results for a dependencys, Now, Install and Candidate. Callers must
524 invert the result if dealing with conflicts. */
525 unsigned char pkgDepCache::DependencyState(DepIterator
&D
)
527 unsigned char State
= 0;
529 if (CheckDep(D
,NowVersion
) == true)
531 if (CheckDep(D
,InstallVersion
) == true)
533 if (CheckDep(D
,CandidateVersion
) == true)
539 // DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
540 // ---------------------------------------------------------------------
541 /* This determines the combined dependency representation of a package
542 for its two states now and install. This is done by using the pre-generated
543 dependency information. */
544 void pkgDepCache::UpdateVerState(PkgIterator Pkg
)
546 // Empty deps are always true
547 StateCache
&State
= PkgState
[Pkg
->ID
];
548 State
.DepState
= 0xFF;
550 // Check the Current state
551 if (Pkg
->CurrentVer
!= 0)
553 DepIterator D
= Pkg
.CurrentVer().DependsList();
554 State
.DepState
&= VersionState(D
,DepNow
,DepNowMin
,DepNowPolicy
);
557 /* Check the candidate state. We do not compare against the whole as
558 a candidate state but check the candidate version against the
560 if (State
.CandidateVer
!= 0)
562 DepIterator D
= State
.CandidateVerIter(*this).DependsList();
563 State
.DepState
&= VersionState(D
,DepInstall
,DepCandMin
,DepCandPolicy
);
566 // Check target state which can only be current or installed
567 if (State
.InstallVer
!= 0)
569 DepIterator D
= State
.InstVerIter(*this).DependsList();
570 State
.DepState
&= VersionState(D
,DepInstall
,DepInstMin
,DepInstPolicy
);
574 // DepCache::Update - Figure out all the state information /*{{{*/
575 // ---------------------------------------------------------------------
576 /* This will figure out the state of all the packages and all the
577 dependencies based on the current policy. */
578 void pkgDepCache::Update(OpProgress
*Prog
)
588 // Perform the depends pass
590 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
592 if (Prog
!= 0 && Done%20
== 0)
593 Prog
->Progress(Done
);
594 for (VerIterator V
= I
.VersionList(); V
.end() != true; V
++)
596 unsigned char Group
= 0;
598 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
600 // Build the dependency state.
601 unsigned char &State
= DepState
[D
->ID
];
602 State
= DependencyState(D
);
604 // Add to the group if we are within an or..
607 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
610 // Invert for Conflicts
611 if (D
->Type
== Dep::Conflicts
||
612 D
->Type
== Dep::DpkgBreaks
||
613 D
->Type
== Dep::Obsoletes
)
618 // Compute the pacakge dependency state and size additions
625 Prog
->Progress(Done
);
630 // DepCache::Update - Update the deps list of a package /*{{{*/
631 // ---------------------------------------------------------------------
632 /* This is a helper for update that only does the dep portion of the scan.
633 It is mainly meant to scan reverse dependencies. */
634 void pkgDepCache::Update(DepIterator D
)
636 // Update the reverse deps
637 for (;D
.end() != true; D
++)
639 unsigned char &State
= DepState
[D
->ID
];
640 State
= DependencyState(D
);
642 // Invert for Conflicts
643 if (D
->Type
== Dep::Conflicts
||
644 D
->Type
== Dep::DpkgBreaks
||
645 D
->Type
== Dep::Obsoletes
)
648 RemoveStates(D
.ParentPkg());
649 BuildGroupOrs(D
.ParentVer());
650 UpdateVerState(D
.ParentPkg());
651 AddStates(D
.ParentPkg());
655 // DepCache::Update - Update the related deps of a package /*{{{*/
656 // ---------------------------------------------------------------------
657 /* This is called whenever the state of a package changes. It updates
658 all cached dependencies related to this package. */
659 void pkgDepCache::Update(PkgIterator
const &Pkg
)
661 // Recompute the dep of the package
666 // Update the reverse deps
667 Update(Pkg
.RevDependsList());
669 // Update the provides map for the current ver
670 if (Pkg
->CurrentVer
!= 0)
671 for (PrvIterator P
= Pkg
.CurrentVer().ProvidesList();
672 P
.end() != true; P
++)
673 Update(P
.ParentPkg().RevDependsList());
675 // Update the provides map for the candidate ver
676 if (PkgState
[Pkg
->ID
].CandidateVer
!= 0)
677 for (PrvIterator P
= PkgState
[Pkg
->ID
].CandidateVerIter(*this).ProvidesList();
678 P
.end() != true; P
++)
679 Update(P
.ParentPkg().RevDependsList());
684 // DepCache::MarkKeep - Put the package in the keep state /*{{{*/
685 // ---------------------------------------------------------------------
687 void pkgDepCache::MarkKeep(PkgIterator
const &Pkg
, bool Soft
, bool FromUser
)
689 // Simplifies other routines.
690 if (Pkg
.end() == true)
693 /* Reject an attempt to keep a non-source broken installed package, those
695 if (Pkg
.State() == PkgIterator::NeedsUnpack
&&
696 Pkg
.CurrentVer().Downloadable() == false)
699 /** \todo Can this be moved later in the method? */
700 ActionGroup
group(*this);
702 /* We changed the soft state all the time so the UI is a bit nicer
704 StateCache
&P
= PkgState
[Pkg
->ID
];
706 P
.iFlags
|= AutoKept
;
708 P
.iFlags
&= ~AutoKept
;
710 // Check that it is not already kept
711 if (P
.Mode
== ModeKeep
)
714 // We dont even try to keep virtual packages..
715 if (Pkg
->VersionList
== 0)
717 #if 0 // reseting the autoflag here means we lose the
718 // auto-mark information if a user selects a package for removal
719 // but changes his mind then and sets it for keep again
720 // - this makes sense as default when all Garbage dependencies
721 // are automatically marked for removal (as aptitude does).
722 // setting a package for keep then makes it no longer autoinstalled
723 // for all other use-case this action is rather suprising
724 if(FromUser
&& !P
.Marked
)
725 P
.Flags
&= ~Flag::Auto
;
732 if (Pkg
->CurrentVer
== 0)
735 P
.InstallVer
= Pkg
.CurrentVer();
744 // DepCache::MarkDelete - Put the package in the delete state /*{{{*/
745 // ---------------------------------------------------------------------
747 void pkgDepCache::MarkDelete(PkgIterator
const &Pkg
, bool rPurge
)
749 // Simplifies other routines.
750 if (Pkg
.end() == true)
753 ActionGroup
group(*this);
755 // Check that it is not already marked for delete
756 StateCache
&P
= PkgState
[Pkg
->ID
];
757 P
.iFlags
&= ~(AutoKept
| Purge
);
761 if ((P
.Mode
== ModeDelete
|| P
.InstallVer
== 0) &&
762 (Pkg
.Purge() == true || rPurge
== false))
765 // We dont even try to delete virtual packages..
766 if (Pkg
->VersionList
== 0)
772 if (Pkg
->CurrentVer
== 0 && (Pkg
.Purge() == true || rPurge
== false))
783 // DepCache::MarkInstall - Put the package in the install state /*{{{*/
784 // ---------------------------------------------------------------------
786 void pkgDepCache::MarkInstall(PkgIterator
const &Pkg
,bool AutoInst
,
787 unsigned long Depth
, bool FromUser
,
788 bool ForceImportantDeps
)
793 // Simplifies other routines.
794 if (Pkg
.end() == true)
797 ActionGroup
group(*this);
799 /* Check that it is not already marked for install and that it can be
801 StateCache
&P
= PkgState
[Pkg
->ID
];
802 P
.iFlags
&= ~AutoKept
;
803 if ((P
.InstPolicyBroken() == false && P
.InstBroken() == false) &&
804 (P
.Mode
== ModeInstall
||
805 P
.CandidateVer
== (Version
*)Pkg
.CurrentVer()))
807 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer() && P
.InstallVer
== 0)
808 MarkKeep(Pkg
, false, FromUser
);
812 // See if there is even any possible instalation candidate
813 if (P
.CandidateVer
== 0)
815 // We dont even try to install virtual packages..
816 if (Pkg
->VersionList
== 0)
818 /* Target the candidate version and remove the autoflag. We reset the
819 autoflag below if this was called recursively. Otherwise the user
820 should have the ability to de-auto a package by changing its state */
824 P
.Mode
= ModeInstall
;
825 P
.InstallVer
= P
.CandidateVer
;
829 // Set it to manual if it's a new install or cancelling the
830 // removal of a garbage package.
831 if(P
.Status
== 2 || (!Pkg
.CurrentVer().end() && !P
.Marked
))
832 P
.Flags
&= ~Flag::Auto
;
836 // Set it to auto if this is a new install.
838 P
.Flags
|= Flag::Auto
;
840 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer())
847 if (AutoInst
== false)
850 DepIterator Dep
= P
.InstVerIter(*this).DependsList();
851 for (; Dep
.end() != true;)
854 DepIterator Start
= Dep
;
857 for (bool LastOR
= true; Dep
.end() == false && LastOR
== true; Dep
++,Ors
++)
859 LastOR
= (Dep
->CompareOp
& Dep::Or
) == Dep::Or
;
861 if ((DepState
[Dep
->ID
] & DepInstall
) == DepInstall
)
865 // Dep is satisfied okay.
869 /* Check if this dep should be consider for install. If it is a user
870 defined important dep and we are installed a new package then
871 it will be installed. Otherwise we only check for important
872 deps that have changed from the installed version
874 if (IsImportantDep(Start
) == false)
877 /* check if any ImportantDep() (but not Critial) where added
878 * since we installed the package
880 bool isNewImportantDep
= false;
881 if(!ForceImportantDeps
&& !Start
.IsCritical())
884 VerIterator instVer
= Pkg
.CurrentVer();
887 for (DepIterator D
= instVer
.DependsList(); D
.end() != true; D
++)
889 //FIXME: deal better with or-groups(?)
890 DepIterator LocalStart
= D
;
892 if(IsImportantDep(D
) && Start
.TargetPkg() == D
.TargetPkg())
895 // this is a new dep if it was not found to be already
896 // a important dep of the installed pacakge
897 isNewImportantDep
= !found
;
900 if(isNewImportantDep
)
901 if(_config
->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
902 std::clog
<< "new important dependency: "
903 << Start
.TargetPkg().Name() << std::endl
;
905 // skip important deps if the package is already installed
906 if (Pkg
->CurrentVer
!= 0 && Start
.IsCritical() == false
907 && !isNewImportantDep
&& !ForceImportantDeps
)
910 /* If we are in an or group locate the first or that can
911 succeed. We have already cached this.. */
912 for (; Ors
> 1 && (DepState
[Start
->ID
] & DepCVer
) != DepCVer
; Ors
--)
915 /* This bit is for processing the possibilty of an install/upgrade
916 fixing the problem */
917 SPtrArray
<Version
*> List
= Start
.AllTargets();
918 if (Start
->Type
!= Dep::DpkgBreaks
&&
919 (DepState
[Start
->ID
] & DepCVer
) == DepCVer
)
921 // Right, find the best version to install..
922 Version
**Cur
= List
;
923 PkgIterator P
= Start
.TargetPkg();
924 PkgIterator
InstPkg(*Cache
,0);
926 // See if there are direct matches (at the start of the list)
927 for (; *Cur
!= 0 && (*Cur
)->ParentPkg
== P
.Index(); Cur
++)
929 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
930 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
936 // Select the highest priority providing package
937 if (InstPkg
.end() == true)
939 pkgPrioSortList(*Cache
,Cur
);
940 for (; *Cur
!= 0; Cur
++)
942 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
943 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
950 if (InstPkg
.end() == false)
952 if(_config
->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
953 std::clog
<< "Installing " << InstPkg
.Name()
954 << " as dep of " << Pkg
.Name()
956 // now check if we should consider it a automatic dependency or not
957 string sec
= _config
->Find("APT::Never-MarkAuto-Section","");
958 if(Pkg
.Section() && (string(Pkg
.Section()) == sec
))
960 if(_config
->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
961 std::clog
<< "Setting NOT as auto-installed because its a direct dep of a package in section " << sec
<< std::endl
;
962 MarkInstall(InstPkg
,true,Depth
+ 1, true);
966 // mark automatic dependency
967 MarkInstall(InstPkg
,true,Depth
+ 1, false, ForceImportantDeps
);
968 // Set the autoflag, after MarkInstall because MarkInstall unsets it
969 if (P
->CurrentVer
== 0)
970 PkgState
[InstPkg
->ID
].Flags
|= Flag::Auto
;
976 /* For conflicts we just de-install the package and mark as auto,
977 Conflicts may not have or groups. For dpkg's Breaks we try to
978 upgrade the package. */
979 if (Start
->Type
== Dep::Conflicts
|| Start
->Type
== Dep::Obsoletes
||
980 Start
->Type
== Dep::DpkgBreaks
)
982 for (Version
**I
= List
; *I
!= 0; I
++)
984 VerIterator
Ver(*this,*I
);
985 PkgIterator Pkg
= Ver
.ParentPkg();
987 if (Start
->Type
!= Dep::DpkgBreaks
)
990 if (PkgState
[Pkg
->ID
].CandidateVer
!= *I
)
991 MarkInstall(Pkg
,true,Depth
+ 1, false, ForceImportantDeps
);
998 // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
999 // ---------------------------------------------------------------------
1001 void pkgDepCache::SetReInstall(PkgIterator
const &Pkg
,bool To
)
1003 ActionGroup
group(*this);
1008 StateCache
&P
= PkgState
[Pkg
->ID
];
1010 P
.iFlags
|= ReInstall
;
1012 P
.iFlags
&= ~ReInstall
;
1018 // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
1019 // ---------------------------------------------------------------------
1021 void pkgDepCache::SetCandidateVersion(VerIterator TargetVer
)
1023 ActionGroup
group(*this);
1025 pkgCache::PkgIterator Pkg
= TargetVer
.ParentPkg();
1026 StateCache
&P
= PkgState
[Pkg
->ID
];
1031 if (P
.CandidateVer
== P
.InstallVer
)
1032 P
.InstallVer
= (Version
*)TargetVer
;
1033 P
.CandidateVer
= (Version
*)TargetVer
;
1034 P
.Update(Pkg
,*this);
1041 void pkgDepCache::MarkAuto(const PkgIterator
&Pkg
, bool Auto
)
1043 StateCache
&state
= PkgState
[Pkg
->ID
];
1045 ActionGroup
group(*this);
1048 state
.Flags
|= Flag::Auto
;
1050 state
.Flags
&= ~Flag::Auto
;
1053 // StateCache::Update - Compute the various static display things /*{{{*/
1054 // ---------------------------------------------------------------------
1055 /* This is called whenever the Candidate version changes. */
1056 void pkgDepCache::StateCache::Update(PkgIterator Pkg
,pkgCache
&Cache
)
1059 VerIterator Ver
= CandidateVerIter(Cache
);
1061 // Use a null string or the version string
1062 if (Ver
.end() == true)
1065 CandVersion
= Ver
.VerStr();
1067 // Find the current version
1069 if (Pkg
->CurrentVer
!= 0)
1070 CurVersion
= Pkg
.CurrentVer().VerStr();
1072 // Strip off the epochs for display
1073 CurVersion
= StripEpoch(CurVersion
);
1074 CandVersion
= StripEpoch(CandVersion
);
1076 // Figure out if its up or down or equal
1077 Status
= Ver
.CompareVer(Pkg
.CurrentVer());
1078 if (Pkg
->CurrentVer
== 0 || Pkg
->VersionList
== 0 || CandidateVer
== 0)
1082 // StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
1083 // ---------------------------------------------------------------------
1085 const char *pkgDepCache::StateCache::StripEpoch(const char *Ver
)
1091 for (const char *I
= Ver
; *I
!= 0; I
++)
1098 // Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
1099 // ---------------------------------------------------------------------
1100 /* The default just returns the highest available version that is not
1101 a source and automatic. */
1102 pkgCache::VerIterator
pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg
)
1104 /* Not source/not automatic versions cannot be a candidate version
1105 unless they are already installed */
1106 VerIterator
Last(*(pkgCache
*)this,0);
1108 for (VerIterator I
= Pkg
.VersionList(); I
.end() == false; I
++)
1110 if (Pkg
.CurrentVer() == I
)
1113 for (VerFileIterator J
= I
.FileList(); J
.end() == false; J
++)
1115 if ((J
.File()->Flags
& Flag::NotSource
) != 0)
1118 /* Stash the highest version of a not-automatic source, we use it
1119 if there is nothing better */
1120 if ((J
.File()->Flags
& Flag::NotAutomatic
) != 0)
1122 if (Last
.end() == true)
1134 // Policy::IsImportantDep - True if the dependency is important /*{{{*/
1135 // ---------------------------------------------------------------------
1137 bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep
)
1139 if(Dep
.IsCritical())
1141 else if(Dep
->Type
== pkgCache::Dep::Recommends
)
1143 if ( _config
->FindB("APT::Install-Recommends", false))
1145 // we suport a special mode to only install-recommends for certain
1147 // FIXME: this is a meant as a temporarly solution until the
1148 // recommends are cleaned up
1149 string s
= _config
->Find("APT::Install-Recommends-Section","");
1152 const char *sec
= Dep
.ParentVer().Section();
1153 if (sec
&& strcmp(sec
, s
.c_str()) == 0)
1157 else if(Dep
->Type
== pkgCache::Dep::Suggests
)
1158 return _config
->FindB("APT::Install-Suggests", false);
1164 pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc()
1165 : constructedSuccessfully(false)
1167 Configuration::Item
const *Opts
;
1168 Opts
= _config
->Tree("APT::NeverAutoRemove");
1169 if (Opts
!= 0 && Opts
->Child
!= 0)
1172 for (; Opts
!= 0; Opts
= Opts
->Next
)
1174 if (Opts
->Value
.empty() == true)
1177 regex_t
*p
= new regex_t
;
1178 if(regcomp(p
,Opts
->Value
.c_str(),
1179 REG_EXTENDED
| REG_ICASE
| REG_NOSUB
) != 0)
1183 _error
->Error("Regex compilation error for APT::NeverAutoRemove");
1187 rootSetRegexp
.push_back(p
);
1191 constructedSuccessfully
= true;
1194 pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc()
1196 for(unsigned int i
= 0; i
< rootSetRegexp
.size(); i
++)
1198 regfree(rootSetRegexp
[i
]);
1199 delete rootSetRegexp
[i
];
1204 bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator
&pkg
)
1206 for(unsigned int i
= 0; i
< rootSetRegexp
.size(); i
++)
1207 if (regexec(rootSetRegexp
[i
], pkg
.Name(), 0, 0, 0) == 0)
1213 pkgDepCache::InRootSetFunc
*pkgDepCache::GetRootSetFunc()
1215 DefaultRootSetFunc
*f
= new DefaultRootSetFunc
;
1216 if(f
->wasConstructedSuccessfully())
1225 bool pkgDepCache::MarkFollowsRecommends()
1227 return _config
->FindB("APT::AutoRemove::RecommendsImportant", true);
1230 bool pkgDepCache::MarkFollowsSuggests()
1232 return _config
->FindB("APT::AutoRemove::SuggestsImportant", false);
1235 // the main mark algorithm
1236 bool pkgDepCache::MarkRequired(InRootSetFunc
&userFunc
)
1238 bool follow_recommends
;
1239 bool follow_suggests
;
1242 for(PkgIterator p
= PkgBegin(); !p
.end(); ++p
)
1244 PkgState
[p
->ID
].Marked
= false;
1245 PkgState
[p
->ID
].Garbage
= false;
1248 if(_config
->FindB("Debug::pkgAutoRemove",false)
1249 && PkgState
[p
->ID
].Flags
& Flag::Auto
)
1250 std::clog
<< "AutoDep: " << p
.Name() << std::endl
;
1254 follow_recommends
= MarkFollowsRecommends();
1255 follow_suggests
= MarkFollowsSuggests();
1259 // do the mark part, this is the core bit of the algorithm
1260 for(PkgIterator p
= PkgBegin(); !p
.end(); ++p
)
1262 if(!(PkgState
[p
->ID
].Flags
& Flag::Auto
) ||
1263 (p
->Flags
& Flag::Essential
) ||
1264 userFunc
.InRootSet(p
))
1267 // the package is installed (and set to keep)
1268 if(PkgState
[p
->ID
].Keep() && !p
.CurrentVer().end())
1269 MarkPackage(p
, p
.CurrentVer(),
1270 follow_recommends
, follow_suggests
);
1271 // the package is to be installed
1272 else if(PkgState
[p
->ID
].Install())
1273 MarkPackage(p
, PkgState
[p
->ID
].InstVerIter(*this),
1274 follow_recommends
, follow_suggests
);
1281 // mark a single package in Mark-and-Sweep
1282 void pkgDepCache::MarkPackage(const pkgCache::PkgIterator
&pkg
,
1283 const pkgCache::VerIterator
&ver
,
1284 bool follow_recommends
,
1285 bool follow_suggests
)
1287 pkgDepCache::StateCache
&state
= PkgState
[pkg
->ID
];
1288 VerIterator currver
= pkg
.CurrentVer();
1289 VerIterator candver
= state
.CandidateVerIter(*this);
1290 VerIterator instver
= state
.InstVerIter(*this);
1293 // If a package was garbage-collected but is now being marked, we
1294 // should re-select it
1295 // For cases when a pkg is set to upgrade and this trigger the
1296 // removal of a no-longer used dependency. if the pkg is set to
1297 // keep again later it will result in broken deps
1298 if(state
.Delete() && state
.RemoveReason
= Unused
)
1301 mark_install(pkg
, false, false, NULL
);
1302 else if(ver
==pkg
.CurrentVer())
1303 MarkKeep(pkg
, false, false);
1305 instver
=state
.InstVerIter(*this);
1309 // For packages that are not going to be removed, ignore versions
1310 // other than the InstVer. For packages that are going to be
1311 // removed, ignore versions other than the current version.
1312 if(!(ver
== instver
&& !instver
.end()) &&
1313 !(ver
== currver
&& instver
.end() && !ver
.end()))
1316 // if we are marked already we are done
1320 //std::cout << "Setting Marked for: " << pkg.Name() << std::endl;
1325 for(DepIterator d
= ver
.DependsList(); !d
.end(); ++d
)
1327 if(d
->Type
== Dep::Depends
||
1328 d
->Type
== Dep::PreDepends
||
1329 (follow_recommends
&&
1330 d
->Type
== Dep::Recommends
) ||
1332 d
->Type
== Dep::Suggests
))
1334 // Try all versions of this package.
1335 for(VerIterator V
= d
.TargetPkg().VersionList();
1338 if(_system
->VS
->CheckDep(V
.VerStr(), d
->CompareOp
, d
.TargetVer()))
1340 MarkPackage(V
.ParentPkg(), V
,
1341 follow_recommends
, follow_suggests
);
1344 // Now try virtual packages
1345 for(PrvIterator prv
=d
.TargetPkg().ProvidesList();
1348 if(_system
->VS
->CheckDep(prv
.ProvideVersion(), d
->CompareOp
,
1351 MarkPackage(prv
.OwnerPkg(), prv
.OwnerVer(),
1352 follow_recommends
, follow_suggests
);
1360 bool pkgDepCache::Sweep()
1363 for(PkgIterator p
=PkgBegin(); !p
.end(); ++p
)
1365 StateCache
&state
=PkgState
[p
->ID
];
1367 // skip required packages
1368 if (!p
.CurrentVer().end() &&
1369 (p
.CurrentVer()->Priority
== pkgCache::State::Required
))
1372 // if it is not marked and it is installed, it's garbage
1373 if(!state
.Marked
&& (!p
.CurrentVer().end() || state
.Install()))
1376 if(_config
->FindB("Debug::pkgAutoRemove",false))
1377 std::cout
<< "Garbage: " << p
.Name() << std::endl
;