]>
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>
28 pkgDepCache::ActionGroup::ActionGroup(pkgDepCache
&cache
) :
29 cache(cache
), released(false)
34 void pkgDepCache::ActionGroup::release()
38 if(cache
.group_level
== 0)
39 std::cerr
<< "W: Unbalanced action groups, expect badness" << std::endl
;
44 if(cache
.group_level
== 0)
52 pkgDepCache::ActionGroup::~ActionGroup()
57 // DepCache::pkgDepCache - Constructors /*{{{*/
58 // ---------------------------------------------------------------------
60 pkgDepCache::pkgDepCache(pkgCache
*pCache
,Policy
*Plcy
) :
61 group_level(0), Cache(pCache
), PkgState(0), DepState(0)
66 delLocalPolicy
= LocalPolicy
= new Policy
;
69 // DepCache::~pkgDepCache - Destructor /*{{{*/
70 // ---------------------------------------------------------------------
72 pkgDepCache::~pkgDepCache()
76 delete delLocalPolicy
;
79 // DepCache::Init - Generate the initial extra structures. /*{{{*/
80 // ---------------------------------------------------------------------
81 /* This allocats the extension buffers and initializes them. */
82 bool pkgDepCache::Init(OpProgress
*Prog
)
84 // Suppress mark updates during this operation (just in case) and
85 // run a mark operation when Init terminates.
86 ActionGroup
actions(*this);
90 PkgState
= new StateCache
[Head().PackageCount
];
91 DepState
= new unsigned char[Head().DependsCount
];
92 memset(PkgState
,0,sizeof(*PkgState
)*Head().PackageCount
);
93 memset(DepState
,0,sizeof(*DepState
)*Head().DependsCount
);
97 Prog
->OverallProgress(0,2*Head().PackageCount
,Head().PackageCount
,
98 _("Building dependency tree"));
99 Prog
->SubProgress(Head().PackageCount
,_("Candidate versions"));
102 /* Set the current state of everything. In this state all of the
103 packages are kept exactly as is. See AllUpgrade */
105 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
108 Prog
->Progress(Done
);
110 // Find the proper cache slot
111 StateCache
&State
= PkgState
[I
->ID
];
114 // Figure out the install version
115 State
.CandidateVer
= GetCandidateVer(I
);
116 State
.InstallVer
= I
.CurrentVer();
117 State
.Mode
= ModeKeep
;
119 State
.Update(I
,*this);
125 Prog
->OverallProgress(Head().PackageCount
,2*Head().PackageCount
,
127 _("Building dependency tree"));
128 Prog
->SubProgress(Head().PackageCount
,_("Dependency generation"));
140 bool pkgDepCache::readStateFile(OpProgress
*Prog
)
143 string state
= _config
->FindDir("Dir::State") + "extended_states";
144 if(FileExists(state
)) {
145 state_file
.Open(state
, FileFd::ReadOnly
);
146 int file_size
= state_file
.Size();
148 Prog
->OverallProgress(0, file_size
, 1,
149 _("Reading state information"));
151 pkgTagFile
tagfile(&state_file
);
152 pkgTagSection section
;
154 while(tagfile
.Step(section
)) {
155 string pkgname
= section
.FindS("Package");
156 pkgCache::PkgIterator pkg
=Cache
->FindPkg(pkgname
);
157 // Silently ignore unknown packages and packages with no actual
159 if(!pkg
.end() && !pkg
.VersionList().end()) {
160 short reason
= section
.FindI("Auto-Installed", 0);
162 PkgState
[pkg
->ID
].Flags
|= Flag::Auto
;
163 if(_config
->FindB("Debug::pkgAutoRemove",false))
164 std::cout
<< "Auto-Installed : " << pkgname
<< std::endl
;
167 Prog
->OverallProgress(amt
, file_size
, 1,
168 _("Reading state information"));
171 Prog
->OverallProgress(file_size
, file_size
, 1,
172 _("Reading state information"));
179 bool pkgDepCache::writeStateFile(OpProgress
*prog
)
181 if(_config
->FindB("Debug::pkgAutoRemove",false))
182 std::clog
<< "pkgDepCache::writeStateFile()" << std::endl
;
185 string state
= _config
->FindDir("Dir::State") + "extended_states";
187 // if it does not exist, create a empty one
188 if(!FileExists(state
))
190 StateFile
.Open(state
, FileFd::WriteEmpty
);
195 if(!StateFile
.Open(state
, FileFd::ReadOnly
))
196 return _error
->Error(_("Failed to open StateFile %s"),
200 string outfile
= state
+ ".tmp";
201 if((OutFile
= fopen(outfile
.c_str(),"w")) == NULL
)
202 return _error
->Error(_("Failed to write temporary StateFile %s"),
205 // first merge with the existing sections
206 pkgTagFile
tagfile(&StateFile
);
207 pkgTagSection section
;
208 std::set
<string
> pkgs_seen
;
209 const char *nullreorderlist
[] = {0};
210 while(tagfile
.Step(section
)) {
211 string pkgname
= section
.FindS("Package");
212 // Silently ignore unknown packages and packages with no actual
214 pkgCache::PkgIterator pkg
=Cache
->FindPkg(pkgname
);
215 if(pkg
.end() || pkg
.VersionList().end())
217 bool oldAuto
= section
.FindI("Auto-Installed");
218 bool newAuto
= (PkgState
[pkg
->ID
].Flags
& Flag::Auto
);
219 if(_config
->FindB("Debug::pkgAutoRemove",false))
220 std::clog
<< "Update exisiting AutoInstall info: "
221 << pkg
.Name() << std::endl
;
222 TFRewriteData rewrite
[2];
223 rewrite
[0].Tag
= "Auto-Installed";
224 rewrite
[0].Rewrite
= newAuto
? "1" : "0";
225 rewrite
[0].NewTag
= 0;
227 TFRewrite(OutFile
, section
, nullreorderlist
, rewrite
);
228 fprintf(OutFile
,"\n");
229 pkgs_seen
.insert(pkgname
);
232 // then write the ones we have not seen yet
233 std::ostringstream ostr
;
234 for(pkgCache::PkgIterator pkg
=Cache
->PkgBegin(); !pkg
.end(); pkg
++) {
235 if(PkgState
[pkg
->ID
].Flags
& Flag::Auto
) {
236 if (pkgs_seen
.find(pkg
.Name()) != pkgs_seen
.end()) {
237 if(_config
->FindB("Debug::pkgAutoRemove",false))
238 std::clog
<< "Skipping already written " << pkg
.Name() << std::endl
;
241 if(_config
->FindB("Debug::pkgAutoRemove",false))
242 std::clog
<< "Writing new AutoInstall: "
243 << pkg
.Name() << std::endl
;
244 ostr
.str(string(""));
245 ostr
<< "Package: " << pkg
.Name()
246 << "\nAuto-Installed: 1\n\n";
247 fprintf(OutFile
,ostr
.str().c_str());
248 fprintf(OutFile
,"\n");
253 // move the outfile over the real file
254 rename(outfile
.c_str(), state
.c_str());
259 // DepCache::CheckDep - Checks a single dependency /*{{{*/
260 // ---------------------------------------------------------------------
261 /* This first checks the dependency against the main target package and
262 then walks along the package provides list and checks if each provides
263 will be installed then checks the provides against the dep. Res will be
264 set to the package which was used to satisfy the dep. */
265 bool pkgDepCache::CheckDep(DepIterator Dep
,int Type
,PkgIterator
&Res
)
267 Res
= Dep
.TargetPkg();
269 /* Check simple depends. A depends -should- never self match but
270 we allow it anyhow because dpkg does. Technically it is a packaging
271 bug. Conflicts may never self match */
272 if (Dep
.TargetPkg() != Dep
.ParentPkg() ||
273 (Dep
->Type
!= Dep::Conflicts
&& Dep
->Type
!= Dep::DpkgBreaks
&& Dep
->Type
!= Dep::Obsoletes
))
275 PkgIterator Pkg
= Dep
.TargetPkg();
276 // Check the base package
277 if (Type
== NowVersion
&& Pkg
->CurrentVer
!= 0)
278 if (VS().CheckDep(Pkg
.CurrentVer().VerStr(),Dep
->CompareOp
,
279 Dep
.TargetVer()) == true)
282 if (Type
== InstallVersion
&& PkgState
[Pkg
->ID
].InstallVer
!= 0)
283 if (VS().CheckDep(PkgState
[Pkg
->ID
].InstVerIter(*this).VerStr(),
284 Dep
->CompareOp
,Dep
.TargetVer()) == true)
287 if (Type
== CandidateVersion
&& PkgState
[Pkg
->ID
].CandidateVer
!= 0)
288 if (VS().CheckDep(PkgState
[Pkg
->ID
].CandidateVerIter(*this).VerStr(),
289 Dep
->CompareOp
,Dep
.TargetVer()) == true)
293 if (Dep
->Type
== Dep::Obsoletes
)
296 // Check the providing packages
297 PrvIterator P
= Dep
.TargetPkg().ProvidesList();
298 PkgIterator Pkg
= Dep
.ParentPkg();
299 for (; P
.end() != true; P
++)
301 /* Provides may never be applied against the same package if it is
302 a conflicts. See the comment above. */
303 if (P
.OwnerPkg() == Pkg
&&
304 (Dep
->Type
== Dep::Conflicts
|| Dep
->Type
== Dep::DpkgBreaks
))
307 // Check if the provides is a hit
308 if (Type
== NowVersion
)
310 if (P
.OwnerPkg().CurrentVer() != P
.OwnerVer())
314 if (Type
== InstallVersion
)
316 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
317 if (State
.InstallVer
!= (Version
*)P
.OwnerVer())
321 if (Type
== CandidateVersion
)
323 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
324 if (State
.CandidateVer
!= (Version
*)P
.OwnerVer())
328 // Compare the versions.
329 if (VS().CheckDep(P
.ProvideVersion(),Dep
->CompareOp
,Dep
.TargetVer()) == true)
339 // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
340 // ---------------------------------------------------------------------
341 /* Call with Mult = -1 to preform the inverse opration */
342 void pkgDepCache::AddSizes(const PkgIterator
&Pkg
,signed long Mult
)
344 StateCache
&P
= PkgState
[Pkg
->ID
];
346 if (Pkg
->VersionList
== 0)
349 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
353 // Compute the size data
354 if (P
.NewInstall() == true)
356 iUsrSize
+= (signed)(Mult
*P
.InstVerIter(*this)->InstalledSize
);
357 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
362 if (Pkg
->CurrentVer
!= 0 &&
363 (P
.InstallVer
!= (Version
*)Pkg
.CurrentVer() ||
364 (P
.iFlags
& ReInstall
) == ReInstall
) && P
.InstallVer
!= 0)
366 iUsrSize
+= (signed)(Mult
*((signed)P
.InstVerIter(*this)->InstalledSize
-
367 (signed)Pkg
.CurrentVer()->InstalledSize
));
368 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
373 if (Pkg
.State() == pkgCache::PkgIterator::NeedsUnpack
&&
376 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
381 if (Pkg
->CurrentVer
!= 0 && P
.InstallVer
== 0)
383 iUsrSize
-= (signed)(Mult
*Pkg
.CurrentVer()->InstalledSize
);
388 // DepCache::AddStates - Add the package to the state counter /*{{{*/
389 // ---------------------------------------------------------------------
390 /* This routine is tricky to use, you must make sure that it is never
391 called twice for the same package. This means the Remove/Add section
392 should be as short as possible and not encompass any code that will
393 calld Remove/Add itself. Remember, dependencies can be circular so
394 while processing a dep for Pkg it is possible that Add/Remove
395 will be called on Pkg */
396 void pkgDepCache::AddStates(const PkgIterator
&Pkg
,int Add
)
398 StateCache
&State
= PkgState
[Pkg
->ID
];
400 // The Package is broken (either minimal dep or policy dep)
401 if ((State
.DepState
& DepInstMin
) != DepInstMin
)
403 if ((State
.DepState
& DepInstPolicy
) != DepInstPolicy
)
404 iPolicyBrokenCount
+= Add
;
407 if (Pkg
.State() != PkgIterator::NeedsNothing
)
411 if (Pkg
->CurrentVer
== 0)
413 if (State
.Mode
== ModeDelete
&&
414 (State
.iFlags
| Purge
) == Purge
&& Pkg
.Purge() == false)
417 if (State
.Mode
== ModeInstall
)
422 // Installed, no upgrade
423 if (State
.Status
== 0)
425 if (State
.Mode
== ModeDelete
)
428 if ((State
.iFlags
& ReInstall
) == ReInstall
)
434 // Alll 3 are possible
435 if (State
.Mode
== ModeDelete
)
437 if (State
.Mode
== ModeKeep
)
439 if (State
.Mode
== ModeInstall
)
443 // DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
444 // ---------------------------------------------------------------------
445 /* The or group results are stored in the last item of the or group. This
446 allows easy detection of the state of a whole or'd group. */
447 void pkgDepCache::BuildGroupOrs(VerIterator
const &V
)
449 unsigned char Group
= 0;
451 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
453 // Build the dependency state.
454 unsigned char &State
= DepState
[D
->ID
];
456 /* Invert for Conflicts. We have to do this twice to get the
457 right sense for a conflicts group */
458 if (D
->Type
== Dep::Conflicts
||
459 D
->Type
== Dep::DpkgBreaks
||
460 D
->Type
== Dep::Obsoletes
)
463 // Add to the group if we are within an or..
467 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
470 // Invert for Conflicts
471 if (D
->Type
== Dep::Conflicts
||
472 D
->Type
== Dep::DpkgBreaks
||
473 D
->Type
== Dep::Obsoletes
)
478 // DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
479 // ---------------------------------------------------------------------
480 /* This is used to run over a dependency list and determine the dep
481 state of the list, filtering it through both a Min check and a Policy
482 check. The return result will have SetMin/SetPolicy low if a check
483 fails. It uses the DepState cache for it's computations. */
484 unsigned char pkgDepCache::VersionState(DepIterator D
,unsigned char Check
,
485 unsigned char SetMin
,
486 unsigned char SetPolicy
)
488 unsigned char Dep
= 0xFF;
490 while (D
.end() != true)
492 // Compute a single dependency element (glob or)
493 DepIterator Start
= D
;
494 unsigned char State
= 0;
495 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
497 State
|= DepState
[D
->ID
];
498 LastOR
= (D
->CompareOp
& Dep::Or
) == Dep::Or
;
501 // Minimum deps that must be satisfied to have a working package
502 if (Start
.IsCritical() == true)
503 if ((State
& Check
) != Check
)
506 // Policy deps that must be satisfied to install the package
507 if (IsImportantDep(Start
) == true &&
508 (State
& Check
) != Check
)
515 // DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
516 // ---------------------------------------------------------------------
517 /* This is the main dependency computation bit. It computes the 3 main
518 results for a dependencys, Now, Install and Candidate. Callers must
519 invert the result if dealing with conflicts. */
520 unsigned char pkgDepCache::DependencyState(DepIterator
&D
)
522 unsigned char State
= 0;
524 if (CheckDep(D
,NowVersion
) == true)
526 if (CheckDep(D
,InstallVersion
) == true)
528 if (CheckDep(D
,CandidateVersion
) == true)
534 // DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
535 // ---------------------------------------------------------------------
536 /* This determines the combined dependency representation of a package
537 for its two states now and install. This is done by using the pre-generated
538 dependency information. */
539 void pkgDepCache::UpdateVerState(PkgIterator Pkg
)
541 // Empty deps are always true
542 StateCache
&State
= PkgState
[Pkg
->ID
];
543 State
.DepState
= 0xFF;
545 // Check the Current state
546 if (Pkg
->CurrentVer
!= 0)
548 DepIterator D
= Pkg
.CurrentVer().DependsList();
549 State
.DepState
&= VersionState(D
,DepNow
,DepNowMin
,DepNowPolicy
);
552 /* Check the candidate state. We do not compare against the whole as
553 a candidate state but check the candidate version against the
555 if (State
.CandidateVer
!= 0)
557 DepIterator D
= State
.CandidateVerIter(*this).DependsList();
558 State
.DepState
&= VersionState(D
,DepInstall
,DepCandMin
,DepCandPolicy
);
561 // Check target state which can only be current or installed
562 if (State
.InstallVer
!= 0)
564 DepIterator D
= State
.InstVerIter(*this).DependsList();
565 State
.DepState
&= VersionState(D
,DepInstall
,DepInstMin
,DepInstPolicy
);
569 // DepCache::Update - Figure out all the state information /*{{{*/
570 // ---------------------------------------------------------------------
571 /* This will figure out the state of all the packages and all the
572 dependencies based on the current policy. */
573 void pkgDepCache::Update(OpProgress
*Prog
)
583 // Perform the depends pass
585 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
587 if (Prog
!= 0 && Done%20
== 0)
588 Prog
->Progress(Done
);
589 for (VerIterator V
= I
.VersionList(); V
.end() != true; V
++)
591 unsigned char Group
= 0;
593 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
595 // Build the dependency state.
596 unsigned char &State
= DepState
[D
->ID
];
597 State
= DependencyState(D
);
599 // Add to the group if we are within an or..
602 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
605 // Invert for Conflicts
606 if (D
->Type
== Dep::Conflicts
||
607 D
->Type
== Dep::DpkgBreaks
||
608 D
->Type
== Dep::Obsoletes
)
613 // Compute the pacakge dependency state and size additions
620 Prog
->Progress(Done
);
625 // DepCache::Update - Update the deps list of a package /*{{{*/
626 // ---------------------------------------------------------------------
627 /* This is a helper for update that only does the dep portion of the scan.
628 It is mainly meant to scan reverse dependencies. */
629 void pkgDepCache::Update(DepIterator D
)
631 // Update the reverse deps
632 for (;D
.end() != true; D
++)
634 unsigned char &State
= DepState
[D
->ID
];
635 State
= DependencyState(D
);
637 // Invert for Conflicts
638 if (D
->Type
== Dep::Conflicts
||
639 D
->Type
== Dep::DpkgBreaks
||
640 D
->Type
== Dep::Obsoletes
)
643 RemoveStates(D
.ParentPkg());
644 BuildGroupOrs(D
.ParentVer());
645 UpdateVerState(D
.ParentPkg());
646 AddStates(D
.ParentPkg());
650 // DepCache::Update - Update the related deps of a package /*{{{*/
651 // ---------------------------------------------------------------------
652 /* This is called whenever the state of a package changes. It updates
653 all cached dependencies related to this package. */
654 void pkgDepCache::Update(PkgIterator
const &Pkg
)
656 // Recompute the dep of the package
661 // Update the reverse deps
662 Update(Pkg
.RevDependsList());
664 // Update the provides map for the current ver
665 if (Pkg
->CurrentVer
!= 0)
666 for (PrvIterator P
= Pkg
.CurrentVer().ProvidesList();
667 P
.end() != true; P
++)
668 Update(P
.ParentPkg().RevDependsList());
670 // Update the provides map for the candidate ver
671 if (PkgState
[Pkg
->ID
].CandidateVer
!= 0)
672 for (PrvIterator P
= PkgState
[Pkg
->ID
].CandidateVerIter(*this).ProvidesList();
673 P
.end() != true; P
++)
674 Update(P
.ParentPkg().RevDependsList());
679 // DepCache::MarkKeep - Put the package in the keep state /*{{{*/
680 // ---------------------------------------------------------------------
682 void pkgDepCache::MarkKeep(PkgIterator
const &Pkg
, bool Soft
, bool FromUser
)
684 // Simplifies other routines.
685 if (Pkg
.end() == true)
688 /* Reject an attempt to keep a non-source broken installed package, those
690 if (Pkg
.State() == PkgIterator::NeedsUnpack
&&
691 Pkg
.CurrentVer().Downloadable() == false)
694 /** \todo Can this be moved later in the method? */
695 ActionGroup
group(*this);
697 /* We changed the soft state all the time so the UI is a bit nicer
699 StateCache
&P
= PkgState
[Pkg
->ID
];
701 P
.iFlags
|= AutoKept
;
703 P
.iFlags
&= ~AutoKept
;
705 // Check that it is not already kept
706 if (P
.Mode
== ModeKeep
)
709 // We dont even try to keep virtual packages..
710 if (Pkg
->VersionList
== 0)
712 #if 0 // reseting the autoflag here means we lose the
713 // auto-mark information if a user selects a package for removal
714 // but changes his mind then and sets it for keep again
715 // - this makes sense as default when all Garbage dependencies
716 // are automatically marked for removal (as aptitude does).
717 // setting a package for keep then makes it no longer autoinstalled
718 // for all other use-case this action is rather suprising
719 if(FromUser
&& !P
.Marked
)
720 P
.Flags
&= ~Flag::Auto
;
727 if (Pkg
->CurrentVer
== 0)
730 P
.InstallVer
= Pkg
.CurrentVer();
739 // DepCache::MarkDelete - Put the package in the delete state /*{{{*/
740 // ---------------------------------------------------------------------
742 void pkgDepCache::MarkDelete(PkgIterator
const &Pkg
, bool rPurge
)
744 // Simplifies other routines.
745 if (Pkg
.end() == true)
748 ActionGroup
group(*this);
750 // Check that it is not already marked for delete
751 StateCache
&P
= PkgState
[Pkg
->ID
];
752 P
.iFlags
&= ~(AutoKept
| Purge
);
756 if ((P
.Mode
== ModeDelete
|| P
.InstallVer
== 0) &&
757 (Pkg
.Purge() == true || rPurge
== false))
760 // We dont even try to delete virtual packages..
761 if (Pkg
->VersionList
== 0)
767 if (Pkg
->CurrentVer
== 0 && (Pkg
.Purge() == true || rPurge
== false))
778 // DepCache::MarkInstall - Put the package in the install state /*{{{*/
779 // ---------------------------------------------------------------------
781 void pkgDepCache::MarkInstall(PkgIterator
const &Pkg
,bool AutoInst
,
782 unsigned long Depth
, bool FromUser
,
783 bool ForceImportantDeps
)
788 // Simplifies other routines.
789 if (Pkg
.end() == true)
792 ActionGroup
group(*this);
794 /* Check that it is not already marked for install and that it can be
796 StateCache
&P
= PkgState
[Pkg
->ID
];
797 P
.iFlags
&= ~AutoKept
;
798 if ((P
.InstPolicyBroken() == false && P
.InstBroken() == false) &&
799 (P
.Mode
== ModeInstall
||
800 P
.CandidateVer
== (Version
*)Pkg
.CurrentVer()))
802 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer() && P
.InstallVer
== 0)
803 MarkKeep(Pkg
, false, FromUser
);
807 // See if there is even any possible instalation candidate
808 if (P
.CandidateVer
== 0)
810 // We dont even try to install virtual packages..
811 if (Pkg
->VersionList
== 0)
813 /* Target the candidate version and remove the autoflag. We reset the
814 autoflag below if this was called recursively. Otherwise the user
815 should have the ability to de-auto a package by changing its state */
819 P
.Mode
= ModeInstall
;
820 P
.InstallVer
= P
.CandidateVer
;
824 // Set it to manual if it's a new install or cancelling the
825 // removal of a garbage package.
826 if(P
.Status
== 2 || (!Pkg
.CurrentVer().end() && !P
.Marked
))
827 P
.Flags
&= ~Flag::Auto
;
831 // Set it to auto if this is a new install.
833 P
.Flags
|= Flag::Auto
;
835 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer())
842 if (AutoInst
== false)
845 DepIterator Dep
= P
.InstVerIter(*this).DependsList();
846 for (; Dep
.end() != true;)
849 DepIterator Start
= Dep
;
852 for (bool LastOR
= true; Dep
.end() == false && LastOR
== true; Dep
++,Ors
++)
854 LastOR
= (Dep
->CompareOp
& Dep::Or
) == Dep::Or
;
856 if ((DepState
[Dep
->ID
] & DepInstall
) == DepInstall
)
860 // Dep is satisfied okay.
864 /* Check if this dep should be consider for install. If it is a user
865 defined important dep and we are installed a new package then
866 it will be installed. Otherwise we only check for important
867 deps that have changed from the installed version
869 if (IsImportantDep(Start
) == false)
872 /* check if any ImportantDep() (but not Critial) where added
873 * since we installed the package
875 bool isNewImportantDep
= false;
876 if(!ForceImportantDeps
&& !Start
.IsCritical())
879 VerIterator instVer
= Pkg
.CurrentVer();
882 for (DepIterator D
= instVer
.DependsList(); D
.end() != true; D
++)
884 //FIXME: deal better with or-groups(?)
885 DepIterator LocalStart
= D
;
887 if(IsImportantDep(D
) && Start
.TargetPkg() == D
.TargetPkg())
890 // this is a new dep if it was not found to be already
891 // a important dep of the installed pacakge
892 isNewImportantDep
= !found
;
895 if(isNewImportantDep
)
896 if(_config
->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
897 std::clog
<< "new important dependency: "
898 << Start
.TargetPkg().Name() << std::endl
;
900 // skip important deps if the package is already installed
901 if (Pkg
->CurrentVer
!= 0 && Start
.IsCritical() == false
902 && !isNewImportantDep
&& !ForceImportantDeps
)
905 /* If we are in an or group locate the first or that can
906 succeed. We have already cached this.. */
907 for (; Ors
> 1 && (DepState
[Start
->ID
] & DepCVer
) != DepCVer
; Ors
--)
910 /* This bit is for processing the possibilty of an install/upgrade
911 fixing the problem */
912 SPtrArray
<Version
*> List
= Start
.AllTargets();
913 if (Start
->Type
!= Dep::DpkgBreaks
&&
914 (DepState
[Start
->ID
] & DepCVer
) == DepCVer
)
916 // Right, find the best version to install..
917 Version
**Cur
= List
;
918 PkgIterator P
= Start
.TargetPkg();
919 PkgIterator
InstPkg(*Cache
,0);
921 // See if there are direct matches (at the start of the list)
922 for (; *Cur
!= 0 && (*Cur
)->ParentPkg
== P
.Index(); Cur
++)
924 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
925 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
931 // Select the highest priority providing package
932 if (InstPkg
.end() == true)
934 pkgPrioSortList(*Cache
,Cur
);
935 for (; *Cur
!= 0; Cur
++)
937 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
938 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
945 if (InstPkg
.end() == false)
947 if(_config
->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
948 std::clog
<< "Installing " << InstPkg
.Name()
949 << " as dep of " << Pkg
.Name()
951 // now check if we should consider it a automatic dependency or not
952 string sec
= _config
->Find("APT::Never-MarkAuto-Section","");
953 if(Pkg
.Section() && (string(Pkg
.Section()) == sec
))
955 if(_config
->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
956 std::clog
<< "Setting NOT as auto-installed because its a direct dep of a package in section " << sec
<< std::endl
;
957 MarkInstall(InstPkg
,true,Depth
+ 1, true);
961 // mark automatic dependency
962 MarkInstall(InstPkg
,true,Depth
+ 1, false, ForceImportantDeps
);
963 // Set the autoflag, after MarkInstall because MarkInstall unsets it
964 if (P
->CurrentVer
== 0)
965 PkgState
[InstPkg
->ID
].Flags
|= Flag::Auto
;
971 /* For conflicts we just de-install the package and mark as auto,
972 Conflicts may not have or groups. For dpkg's Breaks we try to
973 upgrade the package. */
974 if (Start
->Type
== Dep::Conflicts
|| Start
->Type
== Dep::Obsoletes
||
975 Start
->Type
== Dep::DpkgBreaks
)
977 for (Version
**I
= List
; *I
!= 0; I
++)
979 VerIterator
Ver(*this,*I
);
980 PkgIterator Pkg
= Ver
.ParentPkg();
982 if (Start
->Type
!= Dep::DpkgBreaks
)
985 if (PkgState
[Pkg
->ID
].CandidateVer
!= *I
)
986 MarkInstall(Pkg
,true,Depth
+ 1, false, ForceImportantDeps
);
993 // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
994 // ---------------------------------------------------------------------
996 void pkgDepCache::SetReInstall(PkgIterator
const &Pkg
,bool To
)
998 ActionGroup
group(*this);
1003 StateCache
&P
= PkgState
[Pkg
->ID
];
1005 P
.iFlags
|= ReInstall
;
1007 P
.iFlags
&= ~ReInstall
;
1013 // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
1014 // ---------------------------------------------------------------------
1016 void pkgDepCache::SetCandidateVersion(VerIterator TargetVer
)
1018 ActionGroup
group(*this);
1020 pkgCache::PkgIterator Pkg
= TargetVer
.ParentPkg();
1021 StateCache
&P
= PkgState
[Pkg
->ID
];
1026 if (P
.CandidateVer
== P
.InstallVer
)
1027 P
.InstallVer
= (Version
*)TargetVer
;
1028 P
.CandidateVer
= (Version
*)TargetVer
;
1029 P
.Update(Pkg
,*this);
1036 void pkgDepCache::MarkAuto(const PkgIterator
&Pkg
, bool Auto
)
1038 StateCache
&state
= PkgState
[Pkg
->ID
];
1040 ActionGroup
group(*this);
1043 state
.Flags
|= Flag::Auto
;
1045 state
.Flags
&= ~Flag::Auto
;
1048 // StateCache::Update - Compute the various static display things /*{{{*/
1049 // ---------------------------------------------------------------------
1050 /* This is called whenever the Candidate version changes. */
1051 void pkgDepCache::StateCache::Update(PkgIterator Pkg
,pkgCache
&Cache
)
1054 VerIterator Ver
= CandidateVerIter(Cache
);
1056 // Use a null string or the version string
1057 if (Ver
.end() == true)
1060 CandVersion
= Ver
.VerStr();
1062 // Find the current version
1064 if (Pkg
->CurrentVer
!= 0)
1065 CurVersion
= Pkg
.CurrentVer().VerStr();
1067 // Strip off the epochs for display
1068 CurVersion
= StripEpoch(CurVersion
);
1069 CandVersion
= StripEpoch(CandVersion
);
1071 // Figure out if its up or down or equal
1072 Status
= Ver
.CompareVer(Pkg
.CurrentVer());
1073 if (Pkg
->CurrentVer
== 0 || Pkg
->VersionList
== 0 || CandidateVer
== 0)
1077 // StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
1078 // ---------------------------------------------------------------------
1080 const char *pkgDepCache::StateCache::StripEpoch(const char *Ver
)
1086 for (const char *I
= Ver
; *I
!= 0; I
++)
1093 // Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
1094 // ---------------------------------------------------------------------
1095 /* The default just returns the highest available version that is not
1096 a source and automatic. */
1097 pkgCache::VerIterator
pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg
)
1099 /* Not source/not automatic versions cannot be a candidate version
1100 unless they are already installed */
1101 VerIterator
Last(*(pkgCache
*)this,0);
1103 for (VerIterator I
= Pkg
.VersionList(); I
.end() == false; I
++)
1105 if (Pkg
.CurrentVer() == I
)
1108 for (VerFileIterator J
= I
.FileList(); J
.end() == false; J
++)
1110 if ((J
.File()->Flags
& Flag::NotSource
) != 0)
1113 /* Stash the highest version of a not-automatic source, we use it
1114 if there is nothing better */
1115 if ((J
.File()->Flags
& Flag::NotAutomatic
) != 0)
1117 if (Last
.end() == true)
1129 // Policy::IsImportantDep - True if the dependency is important /*{{{*/
1130 // ---------------------------------------------------------------------
1132 bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep
)
1134 if(Dep
.IsCritical())
1136 else if(Dep
->Type
== pkgCache::Dep::Recommends
)
1138 if ( _config
->FindB("APT::Install-Recommends", false))
1140 // we suport a special mode to only install-recommends for certain
1142 // FIXME: this is a meant as a temporarly solution until the
1143 // recommends are cleaned up
1144 string s
= _config
->Find("APT::Install-Recommends-Section","");
1147 const char *sec
= Dep
.TargetPkg().Section();
1148 if (sec
&& strcmp(sec
, s
.c_str()) == 0)
1152 else if(Dep
->Type
== pkgCache::Dep::Suggests
)
1153 return _config
->FindB("APT::Install-Suggests", false);
1159 pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc()
1160 : constructedSuccessfully(false)
1162 Configuration::Item
const *Opts
;
1163 Opts
= _config
->Tree("APT::NeverAutoRemove");
1164 if (Opts
!= 0 && Opts
->Child
!= 0)
1167 for (; Opts
!= 0; Opts
= Opts
->Next
)
1169 if (Opts
->Value
.empty() == true)
1172 regex_t
*p
= new regex_t
;
1173 if(regcomp(p
,Opts
->Value
.c_str(),
1174 REG_EXTENDED
| REG_ICASE
| REG_NOSUB
) != 0)
1178 _error
->Error("Regex compilation error for APT::NeverAutoRemove");
1182 rootSetRegexp
.push_back(p
);
1186 constructedSuccessfully
= true;
1189 pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc()
1191 for(unsigned int i
= 0; i
< rootSetRegexp
.size(); i
++)
1193 regfree(rootSetRegexp
[i
]);
1194 delete rootSetRegexp
[i
];
1199 bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator
&pkg
)
1201 for(unsigned int i
= 0; i
< rootSetRegexp
.size(); i
++)
1202 if (regexec(rootSetRegexp
[i
], pkg
.Name(), 0, 0, 0) == 0)
1208 pkgDepCache::InRootSetFunc
*pkgDepCache::GetRootSetFunc()
1210 DefaultRootSetFunc
*f
= new DefaultRootSetFunc
;
1211 if(f
->wasConstructedSuccessfully())
1220 bool pkgDepCache::MarkFollowsRecommends()
1222 return _config
->FindB("APT::AutoRemove::RecommendsImportant", true);
1225 bool pkgDepCache::MarkFollowsSuggests()
1227 return _config
->FindB("APT::AutoRemove::SuggestsImportant", false);
1230 // the main mark algorithm
1231 bool pkgDepCache::MarkRequired(InRootSetFunc
&userFunc
)
1233 bool follow_recommends
;
1234 bool follow_suggests
;
1237 for(PkgIterator p
= PkgBegin(); !p
.end(); ++p
)
1239 PkgState
[p
->ID
].Marked
= false;
1240 PkgState
[p
->ID
].Garbage
= false;
1243 if(_config
->FindB("Debug::pkgAutoRemove",false)
1244 && PkgState
[p
->ID
].Flags
& Flag::Auto
)
1245 std::clog
<< "AutoDep: " << p
.Name() << std::endl
;
1249 follow_recommends
= MarkFollowsRecommends();
1250 follow_suggests
= MarkFollowsSuggests();
1254 // do the mark part, this is the core bit of the algorithm
1255 for(PkgIterator p
= PkgBegin(); !p
.end(); ++p
)
1257 if(!(PkgState
[p
->ID
].Flags
& Flag::Auto
) ||
1258 (p
->Flags
& Flag::Essential
) ||
1259 userFunc
.InRootSet(p
))
1262 // the package is installed (and set to keep)
1263 if(PkgState
[p
->ID
].Keep() && !p
.CurrentVer().end())
1264 MarkPackage(p
, p
.CurrentVer(),
1265 follow_recommends
, follow_suggests
);
1266 // the package is to be installed
1267 else if(PkgState
[p
->ID
].Install())
1268 MarkPackage(p
, PkgState
[p
->ID
].InstVerIter(*this),
1269 follow_recommends
, follow_suggests
);
1276 // mark a single package in Mark-and-Sweep
1277 void pkgDepCache::MarkPackage(const pkgCache::PkgIterator
&pkg
,
1278 const pkgCache::VerIterator
&ver
,
1279 bool follow_recommends
,
1280 bool follow_suggests
)
1282 pkgDepCache::StateCache
&state
= PkgState
[pkg
->ID
];
1283 VerIterator candver
= state
.CandidateVerIter(*this);
1284 VerIterator instver
= state
.InstVerIter(*this);
1287 // If a package was garbage-collected but is now being marked, we
1288 // should re-select it
1289 // For cases when a pkg is set to upgrade and this trigger the
1290 // removal of a no-longer used dependency. if the pkg is set to
1291 // keep again later it will result in broken deps
1292 if(state
.Delete() && state
.RemoveReason
= Unused
)
1295 mark_install(pkg
, false, false, NULL
);
1296 else if(ver
==pkg
.CurrentVer())
1297 MarkKeep(pkg
, false, false);
1299 instver
=state
.InstVerIter(*this);
1303 // Ignore versions other than the InstVer, and ignore packages
1304 // that are already going to be removed or just left uninstalled.
1305 if(!(ver
== instver
&& !instver
.end()))
1308 // if we are marked already we are done
1312 //std::cout << "Setting Marked for: " << pkg.Name() << std::endl;
1317 for(DepIterator d
= ver
.DependsList(); !d
.end(); ++d
)
1319 if(d
->Type
== Dep::Depends
||
1320 d
->Type
== Dep::PreDepends
||
1321 (follow_recommends
&&
1322 d
->Type
== Dep::Recommends
) ||
1324 d
->Type
== Dep::Suggests
))
1326 // Try all versions of this package.
1327 for(VerIterator V
= d
.TargetPkg().VersionList();
1330 if(_system
->VS
->CheckDep(V
.VerStr(), d
->CompareOp
, d
.TargetVer()))
1332 MarkPackage(V
.ParentPkg(), V
,
1333 follow_recommends
, follow_suggests
);
1336 // Now try virtual packages
1337 for(PrvIterator prv
=d
.TargetPkg().ProvidesList();
1340 if(_system
->VS
->CheckDep(prv
.ProvideVersion(), d
->CompareOp
,
1343 MarkPackage(prv
.OwnerPkg(), prv
.OwnerVer(),
1344 follow_recommends
, follow_suggests
);
1352 bool pkgDepCache::Sweep()
1355 for(PkgIterator p
=PkgBegin(); !p
.end(); ++p
)
1357 StateCache
&state
=PkgState
[p
->ID
];
1359 // skip required packages
1360 if (!p
.CurrentVer().end() &&
1361 (p
.CurrentVer()->Priority
== pkgCache::State::Required
))
1364 // if it is not marked and it is installed, it's garbage
1365 if(!state
.Marked
&& (!p
.CurrentVer().end() || state
.Install()))
1368 if(_config
->FindB("Debug::pkgAutoRemove",false))
1369 std::cout
<< "Garbage: " << p
.Name() << std::endl
;