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/strutl.h>
19 #include <apt-pkg/configuration.h>
20 #include <apt-pkg/pkgsystem.h>
21 #include <apt-pkg/tagfile.h>
31 // helper for Install-Recommends-Sections and Never-MarkAuto-Sections /*{{{*/
33 ConfigValueInSubTree(const char* SubTree
, const char *needle
)
35 Configuration::Item
const *Opts
;
36 Opts
= _config
->Tree(SubTree
);
37 if (Opts
!= 0 && Opts
->Child
!= 0)
40 for (; Opts
!= 0; Opts
= Opts
->Next
)
42 if (Opts
->Value
.empty() == true)
44 if (strcmp(needle
, Opts
->Value
.c_str()) == 0)
51 pkgDepCache::ActionGroup::ActionGroup(pkgDepCache
&cache
) : /*{{{*/
52 cache(cache
), released(false)
57 void pkgDepCache::ActionGroup::release()
61 if(cache
.group_level
== 0)
62 std::cerr
<< "W: Unbalanced action groups, expect badness" << std::endl
;
67 if(cache
.group_level
== 0)
75 pkgDepCache::ActionGroup::~ActionGroup()
80 // DepCache::pkgDepCache - Constructors /*{{{*/
81 // ---------------------------------------------------------------------
83 pkgDepCache::pkgDepCache(pkgCache
*pCache
,Policy
*Plcy
) :
84 group_level(0), Cache(pCache
), PkgState(0), DepState(0)
86 DebugMarker
= _config
->FindB("Debug::pkgDepCache::Marker", false);
87 DebugAutoInstall
= _config
->FindB("Debug::pkgDepCache::AutoInstall", false);
91 delLocalPolicy
= LocalPolicy
= new Policy
;
94 // DepCache::~pkgDepCache - Destructor /*{{{*/
95 // ---------------------------------------------------------------------
97 pkgDepCache::~pkgDepCache()
101 delete delLocalPolicy
;
104 // DepCache::Init - Generate the initial extra structures. /*{{{*/
105 // ---------------------------------------------------------------------
106 /* This allocats the extension buffers and initializes them. */
107 bool pkgDepCache::Init(OpProgress
*Prog
)
109 // Suppress mark updates during this operation (just in case) and
110 // run a mark operation when Init terminates.
111 ActionGroup
actions(*this);
115 PkgState
= new StateCache
[Head().PackageCount
];
116 DepState
= new unsigned char[Head().DependsCount
];
117 memset(PkgState
,0,sizeof(*PkgState
)*Head().PackageCount
);
118 memset(DepState
,0,sizeof(*DepState
)*Head().DependsCount
);
122 Prog
->OverallProgress(0,2*Head().PackageCount
,Head().PackageCount
,
123 _("Building dependency tree"));
124 Prog
->SubProgress(Head().PackageCount
,_("Candidate versions"));
127 /* Set the current state of everything. In this state all of the
128 packages are kept exactly as is. See AllUpgrade */
130 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
132 if (Prog
!= 0 && Done%20
== 0)
133 Prog
->Progress(Done
);
135 // Find the proper cache slot
136 StateCache
&State
= PkgState
[I
->ID
];
139 // Figure out the install version
140 State
.CandidateVer
= GetCandidateVer(I
);
141 State
.InstallVer
= I
.CurrentVer();
142 State
.Mode
= ModeKeep
;
144 State
.Update(I
,*this);
150 Prog
->OverallProgress(Head().PackageCount
,2*Head().PackageCount
,
152 _("Building dependency tree"));
153 Prog
->SubProgress(Head().PackageCount
,_("Dependency generation"));
164 bool pkgDepCache::readStateFile(OpProgress
*Prog
) /*{{{*/
167 string state
= _config
->FindDir("Dir::State") + "extended_states";
168 if(FileExists(state
)) {
169 state_file
.Open(state
, FileFd::ReadOnly
);
170 int file_size
= state_file
.Size();
172 Prog
->OverallProgress(0, file_size
, 1,
173 _("Reading state information"));
175 pkgTagFile
tagfile(&state_file
);
176 pkgTagSection section
;
178 bool debug_autoremove
=_config
->FindB("Debug::pkgAutoRemove",false);
179 while(tagfile
.Step(section
)) {
180 string pkgname
= section
.FindS("Package");
181 pkgCache::PkgIterator pkg
=Cache
->FindPkg(pkgname
);
182 // Silently ignore unknown packages and packages with no actual
184 if(!pkg
.end() && !pkg
.VersionList().end()) {
185 short reason
= section
.FindI("Auto-Installed", 0);
187 PkgState
[pkg
->ID
].Flags
|= Flag::Auto
;
189 std::cout
<< "Auto-Installed : " << pkgname
<< std::endl
;
192 Prog
->OverallProgress(amt
, file_size
, 1,
193 _("Reading state information"));
197 Prog
->OverallProgress(file_size
, file_size
, 1,
198 _("Reading state information"));
204 bool pkgDepCache::writeStateFile(OpProgress
*prog
, bool InstalledOnly
) /*{{{*/
206 bool debug_autoremove
= _config
->FindB("Debug::pkgAutoRemove",false);
209 std::clog
<< "pkgDepCache::writeStateFile()" << std::endl
;
212 string state
= _config
->FindDir("Dir::State") + "extended_states";
214 // if it does not exist, create a empty one
215 if(!FileExists(state
))
217 StateFile
.Open(state
, FileFd::WriteEmpty
);
222 if(!StateFile
.Open(state
, FileFd::ReadOnly
))
223 return _error
->Error(_("Failed to open StateFile %s"),
227 string outfile
= state
+ ".tmp";
228 if((OutFile
= fopen(outfile
.c_str(),"w")) == NULL
)
229 return _error
->Error(_("Failed to write temporary StateFile %s"),
232 // first merge with the existing sections
233 pkgTagFile
tagfile(&StateFile
);
234 pkgTagSection section
;
235 std::set
<string
> pkgs_seen
;
236 const char *nullreorderlist
[] = {0};
237 while(tagfile
.Step(section
)) {
238 string
const pkgname
= section
.FindS("Package");
239 // Silently ignore unknown packages and packages with no actual
241 pkgCache::PkgIterator pkg
=Cache
->FindPkg(pkgname
);
242 if(pkg
.end() || pkg
.VersionList().end())
244 StateCache
const &P
= PkgState
[pkg
->ID
];
245 bool newAuto
= (P
.Flags
& Flag::Auto
);
246 // skip not installed or now-removed ones if requested
247 if (InstalledOnly
&& (
248 (pkg
->CurrentVer
== 0 && P
.Mode
!= ModeInstall
) ||
249 (pkg
->CurrentVer
!= 0 && P
.Mode
== ModeDelete
)))
251 // The section is obsolete if it contains no other tag
252 unsigned int const count
= section
.Count();
254 (count
== 2 && section
.Exists("Auto-Installed")))
259 if(_config
->FindB("Debug::pkgAutoRemove",false))
260 std::clog
<< "Update existing AutoInstall info: "
261 << pkgname
<< std::endl
;
262 TFRewriteData rewrite
[2];
263 rewrite
[0].Tag
= "Auto-Installed";
264 rewrite
[0].Rewrite
= newAuto
? "1" : "0";
265 rewrite
[0].NewTag
= 0;
267 TFRewrite(OutFile
, section
, nullreorderlist
, rewrite
);
268 fprintf(OutFile
,"\n");
269 pkgs_seen
.insert(pkgname
);
272 // then write the ones we have not seen yet
273 std::ostringstream ostr
;
274 for(pkgCache::PkgIterator pkg
=Cache
->PkgBegin(); !pkg
.end(); pkg
++) {
275 StateCache
const &P
= PkgState
[pkg
->ID
];
276 if(P
.Flags
& Flag::Auto
) {
277 if (pkgs_seen
.find(pkg
.Name()) != pkgs_seen
.end()) {
279 std::clog
<< "Skipping already written " << pkg
.Name() << std::endl
;
282 // skip not installed ones if requested
283 if (InstalledOnly
&& (
284 (pkg
->CurrentVer
== 0 && P
.Mode
!= ModeInstall
) ||
285 (pkg
->CurrentVer
!= 0 && P
.Mode
== ModeDelete
)))
288 std::clog
<< "Writing new AutoInstall: "
289 << pkg
.Name() << std::endl
;
290 ostr
.str(string(""));
291 ostr
<< "Package: " << pkg
.Name()
292 << "\nAuto-Installed: 1\n\n";
293 fprintf(OutFile
,"%s",ostr
.str().c_str());
294 fprintf(OutFile
,"\n");
299 // move the outfile over the real file and set permissions
300 rename(outfile
.c_str(), state
.c_str());
301 chmod(state
.c_str(), 0644);
306 // DepCache::CheckDep - Checks a single dependency /*{{{*/
307 // ---------------------------------------------------------------------
308 /* This first checks the dependency against the main target package and
309 then walks along the package provides list and checks if each provides
310 will be installed then checks the provides against the dep. Res will be
311 set to the package which was used to satisfy the dep. */
312 bool pkgDepCache::CheckDep(DepIterator Dep
,int Type
,PkgIterator
&Res
)
314 Res
= Dep
.TargetPkg();
316 /* Check simple depends. A depends -should- never self match but
317 we allow it anyhow because dpkg does. Technically it is a packaging
318 bug. Conflicts may never self match */
319 if (Dep
.TargetPkg() != Dep
.ParentPkg() ||
320 (Dep
->Type
!= Dep::Conflicts
&& Dep
->Type
!= Dep::DpkgBreaks
&& Dep
->Type
!= Dep::Obsoletes
))
322 PkgIterator Pkg
= Dep
.TargetPkg();
323 // Check the base package
324 if (Type
== NowVersion
&& Pkg
->CurrentVer
!= 0)
325 if (VS().CheckDep(Pkg
.CurrentVer().VerStr(),Dep
->CompareOp
,
326 Dep
.TargetVer()) == true)
329 if (Type
== InstallVersion
&& PkgState
[Pkg
->ID
].InstallVer
!= 0)
330 if (VS().CheckDep(PkgState
[Pkg
->ID
].InstVerIter(*this).VerStr(),
331 Dep
->CompareOp
,Dep
.TargetVer()) == true)
334 if (Type
== CandidateVersion
&& PkgState
[Pkg
->ID
].CandidateVer
!= 0)
335 if (VS().CheckDep(PkgState
[Pkg
->ID
].CandidateVerIter(*this).VerStr(),
336 Dep
->CompareOp
,Dep
.TargetVer()) == true)
340 if (Dep
->Type
== Dep::Obsoletes
)
343 // Check the providing packages
344 PrvIterator P
= Dep
.TargetPkg().ProvidesList();
345 PkgIterator Pkg
= Dep
.ParentPkg();
346 for (; P
.end() != true; P
++)
348 /* Provides may never be applied against the same package if it is
349 a conflicts. See the comment above. */
350 if (P
.OwnerPkg() == Pkg
&&
351 (Dep
->Type
== Dep::Conflicts
|| Dep
->Type
== Dep::DpkgBreaks
))
354 // Check if the provides is a hit
355 if (Type
== NowVersion
)
357 if (P
.OwnerPkg().CurrentVer() != P
.OwnerVer())
361 if (Type
== InstallVersion
)
363 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
364 if (State
.InstallVer
!= (Version
*)P
.OwnerVer())
368 if (Type
== CandidateVersion
)
370 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
371 if (State
.CandidateVer
!= (Version
*)P
.OwnerVer())
375 // Compare the versions.
376 if (VS().CheckDep(P
.ProvideVersion(),Dep
->CompareOp
,Dep
.TargetVer()) == true)
386 // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
387 // ---------------------------------------------------------------------
388 /* Call with Mult = -1 to preform the inverse opration */
389 void pkgDepCache::AddSizes(const PkgIterator
&Pkg
,signed long Mult
)
391 StateCache
&P
= PkgState
[Pkg
->ID
];
393 if (Pkg
->VersionList
== 0)
396 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
400 // Compute the size data
401 if (P
.NewInstall() == true)
403 iUsrSize
+= (signed)(Mult
*P
.InstVerIter(*this)->InstalledSize
);
404 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
409 if (Pkg
->CurrentVer
!= 0 &&
410 (P
.InstallVer
!= (Version
*)Pkg
.CurrentVer() ||
411 (P
.iFlags
& ReInstall
) == ReInstall
) && P
.InstallVer
!= 0)
413 iUsrSize
+= (signed)(Mult
*((signed)P
.InstVerIter(*this)->InstalledSize
-
414 (signed)Pkg
.CurrentVer()->InstalledSize
));
415 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
420 if (Pkg
.State() == pkgCache::PkgIterator::NeedsUnpack
&&
423 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
428 if (Pkg
->CurrentVer
!= 0 && P
.InstallVer
== 0)
430 iUsrSize
-= (signed)(Mult
*Pkg
.CurrentVer()->InstalledSize
);
435 // DepCache::AddStates - Add the package to the state counter /*{{{*/
436 // ---------------------------------------------------------------------
437 /* This routine is tricky to use, you must make sure that it is never
438 called twice for the same package. This means the Remove/Add section
439 should be as short as possible and not encompass any code that will
440 calld Remove/Add itself. Remember, dependencies can be circular so
441 while processing a dep for Pkg it is possible that Add/Remove
442 will be called on Pkg */
443 void pkgDepCache::AddStates(const PkgIterator
&Pkg
,int Add
)
445 StateCache
&State
= PkgState
[Pkg
->ID
];
447 // The Package is broken (either minimal dep or policy dep)
448 if ((State
.DepState
& DepInstMin
) != DepInstMin
)
450 if ((State
.DepState
& DepInstPolicy
) != DepInstPolicy
)
451 iPolicyBrokenCount
+= Add
;
454 if (Pkg
.State() != PkgIterator::NeedsNothing
)
458 if (Pkg
->CurrentVer
== 0)
460 if (State
.Mode
== ModeDelete
&&
461 (State
.iFlags
| Purge
) == Purge
&& Pkg
.Purge() == false)
464 if (State
.Mode
== ModeInstall
)
469 // Installed, no upgrade
470 if (State
.Status
== 0)
472 if (State
.Mode
== ModeDelete
)
475 if ((State
.iFlags
& ReInstall
) == ReInstall
)
481 // Alll 3 are possible
482 if (State
.Mode
== ModeDelete
)
484 if (State
.Mode
== ModeKeep
)
486 if (State
.Mode
== ModeInstall
)
490 // DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
491 // ---------------------------------------------------------------------
492 /* The or group results are stored in the last item of the or group. This
493 allows easy detection of the state of a whole or'd group. */
494 void pkgDepCache::BuildGroupOrs(VerIterator
const &V
)
496 unsigned char Group
= 0;
498 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
500 // Build the dependency state.
501 unsigned char &State
= DepState
[D
->ID
];
503 /* Invert for Conflicts. We have to do this twice to get the
504 right sense for a conflicts group */
505 if (D
->Type
== Dep::Conflicts
||
506 D
->Type
== Dep::DpkgBreaks
||
507 D
->Type
== Dep::Obsoletes
)
510 // Add to the group if we are within an or..
514 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
517 // Invert for Conflicts
518 if (D
->Type
== Dep::Conflicts
||
519 D
->Type
== Dep::DpkgBreaks
||
520 D
->Type
== Dep::Obsoletes
)
525 // DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
526 // ---------------------------------------------------------------------
527 /* This is used to run over a dependency list and determine the dep
528 state of the list, filtering it through both a Min check and a Policy
529 check. The return result will have SetMin/SetPolicy low if a check
530 fails. It uses the DepState cache for it's computations. */
531 unsigned char pkgDepCache::VersionState(DepIterator D
,unsigned char Check
,
532 unsigned char SetMin
,
533 unsigned char SetPolicy
)
535 unsigned char Dep
= 0xFF;
537 while (D
.end() != true)
539 // Compute a single dependency element (glob or)
540 DepIterator Start
= D
;
541 unsigned char State
= 0;
542 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
544 State
|= DepState
[D
->ID
];
545 LastOR
= (D
->CompareOp
& Dep::Or
) == Dep::Or
;
548 // Minimum deps that must be satisfied to have a working package
549 if (Start
.IsCritical() == true)
550 if ((State
& Check
) != Check
)
553 // Policy deps that must be satisfied to install the package
554 if (IsImportantDep(Start
) == true &&
555 (State
& Check
) != Check
)
562 // DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
563 // ---------------------------------------------------------------------
564 /* This is the main dependency computation bit. It computes the 3 main
565 results for a dependencys, Now, Install and Candidate. Callers must
566 invert the result if dealing with conflicts. */
567 unsigned char pkgDepCache::DependencyState(DepIterator
&D
)
569 unsigned char State
= 0;
571 if (CheckDep(D
,NowVersion
) == true)
573 if (CheckDep(D
,InstallVersion
) == true)
575 if (CheckDep(D
,CandidateVersion
) == true)
581 // DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
582 // ---------------------------------------------------------------------
583 /* This determines the combined dependency representation of a package
584 for its two states now and install. This is done by using the pre-generated
585 dependency information. */
586 void pkgDepCache::UpdateVerState(PkgIterator Pkg
)
588 // Empty deps are always true
589 StateCache
&State
= PkgState
[Pkg
->ID
];
590 State
.DepState
= 0xFF;
592 // Check the Current state
593 if (Pkg
->CurrentVer
!= 0)
595 DepIterator D
= Pkg
.CurrentVer().DependsList();
596 State
.DepState
&= VersionState(D
,DepNow
,DepNowMin
,DepNowPolicy
);
599 /* Check the candidate state. We do not compare against the whole as
600 a candidate state but check the candidate version against the
602 if (State
.CandidateVer
!= 0)
604 DepIterator D
= State
.CandidateVerIter(*this).DependsList();
605 State
.DepState
&= VersionState(D
,DepInstall
,DepCandMin
,DepCandPolicy
);
608 // Check target state which can only be current or installed
609 if (State
.InstallVer
!= 0)
611 DepIterator D
= State
.InstVerIter(*this).DependsList();
612 State
.DepState
&= VersionState(D
,DepInstall
,DepInstMin
,DepInstPolicy
);
616 // DepCache::Update - Figure out all the state information /*{{{*/
617 // ---------------------------------------------------------------------
618 /* This will figure out the state of all the packages and all the
619 dependencies based on the current policy. */
620 void pkgDepCache::Update(OpProgress
*Prog
)
630 // Perform the depends pass
632 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
634 if (Prog
!= 0 && Done%20
== 0)
635 Prog
->Progress(Done
);
636 for (VerIterator V
= I
.VersionList(); V
.end() != true; V
++)
638 unsigned char Group
= 0;
640 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
642 // Build the dependency state.
643 unsigned char &State
= DepState
[D
->ID
];
644 State
= DependencyState(D
);
646 // Add to the group if we are within an or..
649 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
652 // Invert for Conflicts
653 if (D
->Type
== Dep::Conflicts
||
654 D
->Type
== Dep::DpkgBreaks
||
655 D
->Type
== Dep::Obsoletes
)
660 // Compute the pacakge dependency state and size additions
667 Prog
->Progress(Done
);
672 // DepCache::Update - Update the deps list of a package /*{{{*/
673 // ---------------------------------------------------------------------
674 /* This is a helper for update that only does the dep portion of the scan.
675 It is mainly meant to scan reverse dependencies. */
676 void pkgDepCache::Update(DepIterator D
)
678 // Update the reverse deps
679 for (;D
.end() != true; D
++)
681 unsigned char &State
= DepState
[D
->ID
];
682 State
= DependencyState(D
);
684 // Invert for Conflicts
685 if (D
->Type
== Dep::Conflicts
||
686 D
->Type
== Dep::DpkgBreaks
||
687 D
->Type
== Dep::Obsoletes
)
690 RemoveStates(D
.ParentPkg());
691 BuildGroupOrs(D
.ParentVer());
692 UpdateVerState(D
.ParentPkg());
693 AddStates(D
.ParentPkg());
697 // DepCache::Update - Update the related deps of a package /*{{{*/
698 // ---------------------------------------------------------------------
699 /* This is called whenever the state of a package changes. It updates
700 all cached dependencies related to this package. */
701 void pkgDepCache::Update(PkgIterator
const &Pkg
)
703 // Recompute the dep of the package
708 // Update the reverse deps
709 Update(Pkg
.RevDependsList());
711 // Update the provides map for the current ver
712 if (Pkg
->CurrentVer
!= 0)
713 for (PrvIterator P
= Pkg
.CurrentVer().ProvidesList();
714 P
.end() != true; P
++)
715 Update(P
.ParentPkg().RevDependsList());
717 // Update the provides map for the candidate ver
718 if (PkgState
[Pkg
->ID
].CandidateVer
!= 0)
719 for (PrvIterator P
= PkgState
[Pkg
->ID
].CandidateVerIter(*this).ProvidesList();
720 P
.end() != true; P
++)
721 Update(P
.ParentPkg().RevDependsList());
724 // DepCache::MarkKeep - Put the package in the keep state /*{{{*/
725 // ---------------------------------------------------------------------
727 void pkgDepCache::MarkKeep(PkgIterator
const &Pkg
, bool Soft
, bool FromUser
,
730 // Simplifies other routines.
731 if (Pkg
.end() == true)
734 /* Reject an attempt to keep a non-source broken installed package, those
736 if (Pkg
.State() == PkgIterator::NeedsUnpack
&&
737 Pkg
.CurrentVer().Downloadable() == false)
740 /** \todo Can this be moved later in the method? */
741 ActionGroup
group(*this);
743 /* We changed the soft state all the time so the UI is a bit nicer
745 StateCache
&P
= PkgState
[Pkg
->ID
];
747 P
.iFlags
|= AutoKept
;
749 P
.iFlags
&= ~AutoKept
;
751 // Check that it is not already kept
752 if (P
.Mode
== ModeKeep
)
755 // We dont even try to keep virtual packages..
756 if (Pkg
->VersionList
== 0)
758 #if 0 // reseting the autoflag here means we lose the
759 // auto-mark information if a user selects a package for removal
760 // but changes his mind then and sets it for keep again
761 // - this makes sense as default when all Garbage dependencies
762 // are automatically marked for removal (as aptitude does).
763 // setting a package for keep then makes it no longer autoinstalled
764 // for all other use-case this action is rather suprising
765 if(FromUser
&& !P
.Marked
)
766 P
.Flags
&= ~Flag::Auto
;
769 if (DebugMarker
== true)
770 std::clog
<< OutputInDepth(Depth
) << "MarkKeep " << Pkg
<< " FU=" << FromUser
<< std::endl
;
776 if (Pkg
->CurrentVer
== 0)
779 P
.InstallVer
= Pkg
.CurrentVer();
788 // DepCache::MarkDelete - Put the package in the delete state /*{{{*/
789 // ---------------------------------------------------------------------
791 void pkgDepCache::MarkDelete(PkgIterator
const &Pkg
, bool rPurge
,
792 unsigned long Depth
, bool FromUser
)
794 // Simplifies other routines.
795 if (Pkg
.end() == true)
798 ActionGroup
group(*this);
800 // Check that it is not already marked for delete
801 StateCache
&P
= PkgState
[Pkg
->ID
];
802 P
.iFlags
&= ~(AutoKept
| Purge
);
806 if ((P
.Mode
== ModeDelete
|| P
.InstallVer
== 0) &&
807 (Pkg
.Purge() == true || rPurge
== false))
810 // We dont even try to delete virtual packages..
811 if (Pkg
->VersionList
== 0)
814 // check if we are allowed to install the package
815 if (IsDeleteOk(Pkg
,rPurge
,Depth
,FromUser
) == false)
818 if (DebugMarker
== true)
819 std::clog
<< OutputInDepth(Depth
) << "MarkDelete " << Pkg
<< " FU=" << FromUser
<< std::endl
;
824 if (Pkg
->CurrentVer
== 0 && (Pkg
.Purge() == true || rPurge
== false))
835 // DepCache::IsDeleteOk - check if it is ok to remove this package /*{{{*/
836 // ---------------------------------------------------------------------
837 /* The default implementation just honors dpkg hold
838 But an application using this library can override this method
839 to control the MarkDelete behaviour */
840 bool pkgDepCache::IsDeleteOk(PkgIterator
const &Pkg
,bool rPurge
,
841 unsigned long Depth
, bool FromUser
)
843 if (FromUser
== false && Pkg
->SelectedState
== pkgCache::State::Hold
&& _config
->FindB("APT::Ignore-Hold",false) == false)
845 if (DebugMarker
== true)
846 std::clog
<< OutputInDepth(Depth
) << "Hold prevents MarkDelete of " << Pkg
<< " FU=" << FromUser
<< std::endl
;
852 // DepCache::MarkInstall - Put the package in the install state /*{{{*/
853 // ---------------------------------------------------------------------
855 void pkgDepCache::MarkInstall(PkgIterator
const &Pkg
,bool AutoInst
,
856 unsigned long Depth
, bool FromUser
,
857 bool ForceImportantDeps
)
862 // Simplifies other routines.
863 if (Pkg
.end() == true)
866 ActionGroup
group(*this);
868 /* Check that it is not already marked for install and that it can be
870 StateCache
&P
= PkgState
[Pkg
->ID
];
871 P
.iFlags
&= ~AutoKept
;
872 if ((P
.InstPolicyBroken() == false && P
.InstBroken() == false) &&
873 (P
.Mode
== ModeInstall
||
874 P
.CandidateVer
== (Version
*)Pkg
.CurrentVer()))
876 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer() && P
.InstallVer
== 0)
877 MarkKeep(Pkg
, false, FromUser
, Depth
+1);
881 // See if there is even any possible instalation candidate
882 if (P
.CandidateVer
== 0)
884 // We dont even try to install virtual packages..
885 if (Pkg
->VersionList
== 0)
888 // check if we are allowed to install the package
889 if (IsInstallOk(Pkg
,AutoInst
,Depth
,FromUser
) == false)
892 /* Target the candidate version and remove the autoflag. We reset the
893 autoflag below if this was called recursively. Otherwise the user
894 should have the ability to de-auto a package by changing its state */
898 P
.Mode
= ModeInstall
;
899 P
.InstallVer
= P
.CandidateVer
;
903 // Set it to manual if it's a new install or cancelling the
904 // removal of a garbage package.
905 if(P
.Status
== 2 || (!Pkg
.CurrentVer().end() && !P
.Marked
))
906 P
.Flags
&= ~Flag::Auto
;
910 // Set it to auto if this is a new install.
912 P
.Flags
|= Flag::Auto
;
914 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer())
921 if (AutoInst
== false)
924 if (DebugMarker
== true)
925 std::clog
<< OutputInDepth(Depth
) << "MarkInstall " << Pkg
<< " FU=" << FromUser
<< std::endl
;
927 DepIterator Dep
= P
.InstVerIter(*this).DependsList();
928 for (; Dep
.end() != true;)
931 DepIterator Start
= Dep
;
934 for (bool LastOR
= true; Dep
.end() == false && LastOR
== true; Dep
++,Ors
++)
936 LastOR
= (Dep
->CompareOp
& Dep::Or
) == Dep::Or
;
938 if ((DepState
[Dep
->ID
] & DepInstall
) == DepInstall
)
942 // Dep is satisfied okay.
946 /* Check if this dep should be consider for install. If it is a user
947 defined important dep and we are installed a new package then
948 it will be installed. Otherwise we only check for important
949 deps that have changed from the installed version
951 if (IsImportantDep(Start
) == false)
954 /* Check if any ImportantDep() (but not Critical) were added
955 * since we installed the package. Also check for deps that
956 * were satisfied in the past: for instance, if a version
957 * restriction in a Recommends was tightened, upgrading the
958 * package should follow that Recommends rather than causing the
959 * dependency to be removed. (bug #470115)
961 bool isNewImportantDep
= false;
962 bool isPreviouslySatisfiedImportantDep
= false;
963 if(!ForceImportantDeps
&& !Start
.IsCritical())
966 VerIterator instVer
= Pkg
.CurrentVer();
969 for (DepIterator D
= instVer
.DependsList(); D
.end() != true; D
++)
971 //FIXME: deal better with or-groups(?)
972 DepIterator LocalStart
= D
;
974 if(IsImportantDep(D
) && !D
.IsCritical() &&
975 Start
.TargetPkg() == D
.TargetPkg())
977 if(!isPreviouslySatisfiedImportantDep
)
980 while((D2
->CompareOp
& Dep::Or
) != 0)
983 isPreviouslySatisfiedImportantDep
=
984 (((*this)[D2
] & DepGNow
) != 0);
990 // this is a new dep if it was not found to be already
991 // a important dep of the installed pacakge
992 isNewImportantDep
= !found
;
995 if(isNewImportantDep
)
996 if(DebugAutoInstall
== true)
997 std::clog
<< OutputInDepth(Depth
) << "new important dependency: "
998 << Start
.TargetPkg().Name() << std::endl
;
999 if(isPreviouslySatisfiedImportantDep
)
1000 if(DebugAutoInstall
== true)
1001 std::clog
<< OutputInDepth(Depth
) << "previously satisfied important dependency on "
1002 << Start
.TargetPkg().Name() << std::endl
;
1004 // skip important deps if the package is already installed
1005 if (Pkg
->CurrentVer
!= 0 && Start
.IsCritical() == false
1006 && !isNewImportantDep
&& !isPreviouslySatisfiedImportantDep
1007 && !ForceImportantDeps
)
1010 /* If we are in an or group locate the first or that can
1011 succeed. We have already cached this.. */
1012 for (; Ors
> 1 && (DepState
[Start
->ID
] & DepCVer
) != DepCVer
; Ors
--)
1015 /* This bit is for processing the possibilty of an install/upgrade
1016 fixing the problem */
1017 SPtrArray
<Version
*> List
= Start
.AllTargets();
1018 if (Start
->Type
!= Dep::DpkgBreaks
&&
1019 (DepState
[Start
->ID
] & DepCVer
) == DepCVer
)
1021 // Right, find the best version to install..
1022 Version
**Cur
= List
;
1023 PkgIterator P
= Start
.TargetPkg();
1024 PkgIterator
InstPkg(*Cache
,0);
1026 // See if there are direct matches (at the start of the list)
1027 for (; *Cur
!= 0 && (*Cur
)->ParentPkg
== P
.Index(); Cur
++)
1029 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
1030 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
1036 // Select the highest priority providing package
1037 if (InstPkg
.end() == true)
1039 pkgPrioSortList(*Cache
,Cur
);
1040 for (; *Cur
!= 0; Cur
++)
1042 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
1043 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
1050 if (InstPkg
.end() == false)
1052 if(DebugAutoInstall
== true)
1053 std::clog
<< OutputInDepth(Depth
) << "Installing " << InstPkg
.Name()
1054 << " as " << Start
.DepType() << " of " << Pkg
.Name()
1056 // now check if we should consider it a automatic dependency or not
1057 if(Pkg
.Section() && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", Pkg
.Section()))
1059 if(DebugAutoInstall
== true)
1060 std::clog
<< OutputInDepth(Depth
) << "Setting NOT as auto-installed (direct "
1061 << Start
.DepType() << " of pkg in APT::Never-MarkAuto-Sections)" << std::endl
;
1062 MarkInstall(InstPkg
,true,Depth
+ 1, true);
1066 // mark automatic dependency
1067 MarkInstall(InstPkg
,true,Depth
+ 1, false, ForceImportantDeps
);
1068 // Set the autoflag, after MarkInstall because MarkInstall unsets it
1069 if (P
->CurrentVer
== 0)
1070 PkgState
[InstPkg
->ID
].Flags
|= Flag::Auto
;
1076 /* For conflicts we just de-install the package and mark as auto,
1077 Conflicts may not have or groups. For dpkg's Breaks we try to
1078 upgrade the package. */
1079 if (Start
->Type
== Dep::Conflicts
|| Start
->Type
== Dep::Obsoletes
||
1080 Start
->Type
== Dep::DpkgBreaks
)
1082 for (Version
**I
= List
; *I
!= 0; I
++)
1084 VerIterator
Ver(*this,*I
);
1085 PkgIterator Pkg
= Ver
.ParentPkg();
1087 if (Start
->Type
!= Dep::DpkgBreaks
)
1088 MarkDelete(Pkg
,false,Depth
+ 1, false);
1089 else if (PkgState
[Pkg
->ID
].CandidateVer
!= *I
)
1090 MarkInstall(Pkg
,true,Depth
+ 1, false, ForceImportantDeps
);
1097 // DepCache::IsInstallOk - check if it is ok to install this package /*{{{*/
1098 // ---------------------------------------------------------------------
1099 /* The default implementation just honors dpkg hold
1100 But an application using this library can override this method
1101 to control the MarkInstall behaviour */
1102 bool pkgDepCache::IsInstallOk(PkgIterator
const &Pkg
,bool AutoInst
,
1103 unsigned long Depth
, bool FromUser
)
1105 if (FromUser
== false && Pkg
->SelectedState
== pkgCache::State::Hold
&& _config
->FindB("APT::Ignore-Hold",false) == false)
1107 if (DebugMarker
== true)
1108 std::clog
<< OutputInDepth(Depth
) << "Hold prevents MarkInstall of " << Pkg
<< " FU=" << FromUser
<< std::endl
;
1114 // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
1115 // ---------------------------------------------------------------------
1117 void pkgDepCache::SetReInstall(PkgIterator
const &Pkg
,bool To
)
1119 ActionGroup
group(*this);
1124 StateCache
&P
= PkgState
[Pkg
->ID
];
1126 P
.iFlags
|= ReInstall
;
1128 P
.iFlags
&= ~ReInstall
;
1134 // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
1135 // ---------------------------------------------------------------------
1137 void pkgDepCache::SetCandidateVersion(VerIterator TargetVer
)
1139 ActionGroup
group(*this);
1141 pkgCache::PkgIterator Pkg
= TargetVer
.ParentPkg();
1142 StateCache
&P
= PkgState
[Pkg
->ID
];
1147 if (P
.CandidateVer
== P
.InstallVer
)
1148 P
.InstallVer
= (Version
*)TargetVer
;
1149 P
.CandidateVer
= (Version
*)TargetVer
;
1150 P
.Update(Pkg
,*this);
1157 void pkgDepCache::MarkAuto(const PkgIterator
&Pkg
, bool Auto
)
1159 StateCache
&state
= PkgState
[Pkg
->ID
];
1161 ActionGroup
group(*this);
1164 state
.Flags
|= Flag::Auto
;
1166 state
.Flags
&= ~Flag::Auto
;
1169 // StateCache::Update - Compute the various static display things /*{{{*/
1170 // ---------------------------------------------------------------------
1171 /* This is called whenever the Candidate version changes. */
1172 void pkgDepCache::StateCache::Update(PkgIterator Pkg
,pkgCache
&Cache
)
1175 VerIterator Ver
= CandidateVerIter(Cache
);
1177 // Use a null string or the version string
1178 if (Ver
.end() == true)
1181 CandVersion
= Ver
.VerStr();
1183 // Find the current version
1185 if (Pkg
->CurrentVer
!= 0)
1186 CurVersion
= Pkg
.CurrentVer().VerStr();
1188 // Strip off the epochs for display
1189 CurVersion
= StripEpoch(CurVersion
);
1190 CandVersion
= StripEpoch(CandVersion
);
1192 // Figure out if its up or down or equal
1193 Status
= Ver
.CompareVer(Pkg
.CurrentVer());
1194 if (Pkg
->CurrentVer
== 0 || Pkg
->VersionList
== 0 || CandidateVer
== 0)
1198 // StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
1199 // ---------------------------------------------------------------------
1201 const char *pkgDepCache::StateCache::StripEpoch(const char *Ver
)
1207 for (const char *I
= Ver
; *I
!= 0; I
++)
1213 // Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
1214 // ---------------------------------------------------------------------
1215 /* The default just returns the highest available version that is not
1216 a source and automatic. */
1217 pkgCache::VerIterator
pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg
)
1219 /* Not source/not automatic versions cannot be a candidate version
1220 unless they are already installed */
1221 VerIterator
Last(*(pkgCache
*)this,0);
1223 for (VerIterator I
= Pkg
.VersionList(); I
.end() == false; I
++)
1225 if (Pkg
.CurrentVer() == I
)
1228 for (VerFileIterator J
= I
.FileList(); J
.end() == false; J
++)
1230 if ((J
.File()->Flags
& Flag::NotSource
) != 0)
1233 /* Stash the highest version of a not-automatic source, we use it
1234 if there is nothing better */
1235 if ((J
.File()->Flags
& Flag::NotAutomatic
) != 0)
1237 if (Last
.end() == true)
1249 // Policy::IsImportantDep - True if the dependency is important /*{{{*/
1250 // ---------------------------------------------------------------------
1252 bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep
)
1254 if(Dep
.IsCritical())
1256 else if(Dep
->Type
== pkgCache::Dep::Recommends
)
1258 if ( _config
->FindB("APT::Install-Recommends", false))
1260 // we suport a special mode to only install-recommends for certain
1262 // FIXME: this is a meant as a temporarly solution until the
1263 // recommends are cleaned up
1264 const char *sec
= Dep
.ParentVer().Section();
1265 if (sec
&& ConfigValueInSubTree("APT::Install-Recommends-Sections", sec
))
1268 else if(Dep
->Type
== pkgCache::Dep::Suggests
)
1269 return _config
->FindB("APT::Install-Suggests", false);
1274 pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc() /*{{{*/
1275 : constructedSuccessfully(false)
1277 Configuration::Item
const *Opts
;
1278 Opts
= _config
->Tree("APT::NeverAutoRemove");
1279 if (Opts
!= 0 && Opts
->Child
!= 0)
1282 for (; Opts
!= 0; Opts
= Opts
->Next
)
1284 if (Opts
->Value
.empty() == true)
1287 regex_t
*p
= new regex_t
;
1288 if(regcomp(p
,Opts
->Value
.c_str(),
1289 REG_EXTENDED
| REG_ICASE
| REG_NOSUB
) != 0)
1293 _error
->Error("Regex compilation error for APT::NeverAutoRemove");
1297 rootSetRegexp
.push_back(p
);
1301 constructedSuccessfully
= true;
1304 pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc() /*{{{*/
1306 for(unsigned int i
= 0; i
< rootSetRegexp
.size(); i
++)
1308 regfree(rootSetRegexp
[i
]);
1309 delete rootSetRegexp
[i
];
1313 bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator
&pkg
) /*{{{*/
1315 for(unsigned int i
= 0; i
< rootSetRegexp
.size(); i
++)
1316 if (regexec(rootSetRegexp
[i
], pkg
.Name(), 0, 0, 0) == 0)
1322 pkgDepCache::InRootSetFunc
*pkgDepCache::GetRootSetFunc() /*{{{*/
1324 DefaultRootSetFunc
*f
= new DefaultRootSetFunc
;
1325 if(f
->wasConstructedSuccessfully())
1334 bool pkgDepCache::MarkFollowsRecommends()
1336 return _config
->FindB("APT::AutoRemove::RecommendsImportant", true);
1339 bool pkgDepCache::MarkFollowsSuggests()
1341 return _config
->FindB("APT::AutoRemove::SuggestsImportant", false);
1344 // pkgDepCache::MarkRequired - the main mark algorithm /*{{{*/
1345 bool pkgDepCache::MarkRequired(InRootSetFunc
&userFunc
)
1347 bool follow_recommends
;
1348 bool follow_suggests
;
1349 bool debug_autoremove
= _config
->FindB("Debug::pkgAutoRemove",false);
1352 for(PkgIterator p
= PkgBegin(); !p
.end(); ++p
)
1354 PkgState
[p
->ID
].Marked
= false;
1355 PkgState
[p
->ID
].Garbage
= false;
1358 if(debug_autoremove
&& PkgState
[p
->ID
].Flags
& Flag::Auto
)
1359 std::clog
<< "AutoDep: " << p
.Name() << std::endl
;
1363 follow_recommends
= MarkFollowsRecommends();
1364 follow_suggests
= MarkFollowsSuggests();
1368 // do the mark part, this is the core bit of the algorithm
1369 for(PkgIterator p
= PkgBegin(); !p
.end(); ++p
)
1371 if(!(PkgState
[p
->ID
].Flags
& Flag::Auto
) ||
1372 (p
->Flags
& Flag::Essential
) ||
1373 userFunc
.InRootSet(p
))
1376 // the package is installed (and set to keep)
1377 if(PkgState
[p
->ID
].Keep() && !p
.CurrentVer().end())
1378 MarkPackage(p
, p
.CurrentVer(),
1379 follow_recommends
, follow_suggests
);
1380 // the package is to be installed
1381 else if(PkgState
[p
->ID
].Install())
1382 MarkPackage(p
, PkgState
[p
->ID
].InstVerIter(*this),
1383 follow_recommends
, follow_suggests
);
1390 // MarkPackage - mark a single package in Mark-and-Sweep /*{{{*/
1391 void pkgDepCache::MarkPackage(const pkgCache::PkgIterator
&pkg
,
1392 const pkgCache::VerIterator
&ver
,
1393 bool follow_recommends
,
1394 bool follow_suggests
)
1396 pkgDepCache::StateCache
&state
= PkgState
[pkg
->ID
];
1397 VerIterator currver
= pkg
.CurrentVer();
1398 VerIterator candver
= state
.CandidateVerIter(*this);
1399 VerIterator instver
= state
.InstVerIter(*this);
1402 // If a package was garbage-collected but is now being marked, we
1403 // should re-select it
1404 // For cases when a pkg is set to upgrade and this trigger the
1405 // removal of a no-longer used dependency. if the pkg is set to
1406 // keep again later it will result in broken deps
1407 if(state
.Delete() && state
.RemoveReason
= Unused
)
1410 mark_install(pkg
, false, false, NULL
);
1411 else if(ver
==pkg
.CurrentVer())
1412 MarkKeep(pkg
, false, false);
1414 instver
=state
.InstVerIter(*this);
1418 // For packages that are not going to be removed, ignore versions
1419 // other than the InstVer. For packages that are going to be
1420 // removed, ignore versions other than the current version.
1421 if(!(ver
== instver
&& !instver
.end()) &&
1422 !(ver
== currver
&& instver
.end() && !ver
.end()))
1425 // if we are marked already we are done
1429 bool debug_autoremove
= _config
->FindB("Debug::pkgAutoRemove", false);
1431 if(debug_autoremove
)
1433 std::clog
<< "Marking: " << pkg
.Name();
1435 std::clog
<< " " << ver
.VerStr();
1437 std::clog
<< ", Curr=" << currver
.VerStr();
1439 std::clog
<< ", Inst=" << instver
.VerStr();
1440 std::clog
<< std::endl
;
1447 for(DepIterator d
= ver
.DependsList(); !d
.end(); ++d
)
1449 if(d
->Type
== Dep::Depends
||
1450 d
->Type
== Dep::PreDepends
||
1451 (follow_recommends
&&
1452 d
->Type
== Dep::Recommends
) ||
1454 d
->Type
== Dep::Suggests
))
1456 // Try all versions of this package.
1457 for(VerIterator V
= d
.TargetPkg().VersionList();
1460 if(_system
->VS
->CheckDep(V
.VerStr(), d
->CompareOp
, d
.TargetVer()))
1462 if(debug_autoremove
)
1464 std::clog
<< "Following dep: " << d
.ParentPkg().Name()
1465 << " " << d
.ParentVer().VerStr() << " "
1466 << d
.DepType() << " "
1467 << d
.TargetPkg().Name();
1468 if((d
->CompareOp
& ~pkgCache::Dep::Or
) != pkgCache::Dep::NoOp
)
1470 std::clog
<< " (" << d
.CompType() << " "
1471 << d
.TargetVer() << ")";
1473 std::clog
<< std::endl
;
1475 MarkPackage(V
.ParentPkg(), V
,
1476 follow_recommends
, follow_suggests
);
1479 // Now try virtual packages
1480 for(PrvIterator prv
=d
.TargetPkg().ProvidesList();
1483 if(_system
->VS
->CheckDep(prv
.ProvideVersion(), d
->CompareOp
,
1486 if(debug_autoremove
)
1488 std::clog
<< "Following dep: " << d
.ParentPkg().Name()
1489 << " " << d
.ParentVer().VerStr() << " "
1490 << d
.DepType() << " "
1491 << d
.TargetPkg().Name();
1492 if((d
->CompareOp
& ~pkgCache::Dep::Or
) != pkgCache::Dep::NoOp
)
1494 std::clog
<< " (" << d
.CompType() << " "
1495 << d
.TargetVer() << ")";
1497 std::clog
<< ", provided by "
1498 << prv
.OwnerPkg().Name() << " "
1499 << prv
.OwnerVer().VerStr()
1503 MarkPackage(prv
.OwnerPkg(), prv
.OwnerVer(),
1504 follow_recommends
, follow_suggests
);
1512 bool pkgDepCache::Sweep() /*{{{*/
1514 bool debug_autoremove
= _config
->FindB("Debug::pkgAutoRemove",false);
1517 for(PkgIterator p
=PkgBegin(); !p
.end(); ++p
)
1519 StateCache
&state
=PkgState
[p
->ID
];
1521 // skip required packages
1522 if (!p
.CurrentVer().end() &&
1523 (p
.CurrentVer()->Priority
== pkgCache::State::Required
))
1526 // if it is not marked and it is installed, it's garbage
1527 if(!state
.Marked
&& (!p
.CurrentVer().end() || state
.Install()))
1530 if(debug_autoremove
)
1531 std::cout
<< "Garbage: " << p
.Name() << std::endl
;