* apt-pkg/depcache.cc:
[ntk/apt.git] / apt-pkg / depcache.cc
CommitLineData
6c139d6e
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
e7b470ee 3// $Id: depcache.cc,v 1.25 2001/05/27 05:36:04 jgg Exp $
6c139d6e
AL
4/* ######################################################################
5
6 Dependency Cache - Caches Dependency information.
7
8 ##################################################################### */
9 /*}}}*/
10// Include Files /*{{{*/
11#ifdef __GNUG__
094a497d 12#pragma implementation "apt-pkg/depcache.h"
6c139d6e 13#endif
094a497d 14#include <apt-pkg/depcache.h>
094a497d
AL
15#include <apt-pkg/version.h>
16#include <apt-pkg/error.h>
b2e465d6
AL
17#include <apt-pkg/sptr.h>
18#include <apt-pkg/algorithms.h>
afb1e2e3
MV
19
20#include <apt-pkg/fileutl.h>
21#include <apt-pkg/configuration.h>
74a05226 22#include <apt-pkg/pkgsystem.h>
afb1e2e3 23#include <apt-pkg/tagfile.h>
120365ce
MV
24
25#include <iostream>
a83d884d 26#include <sstream>
b1a8717a 27#include <set>
d4c5f11f 28
8a3a2e99
MV
29#include <sys/stat.h>
30
b2e465d6 31#include <apti18n.h>
74a05226
MV
32
33pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) :
34 cache(cache), released(false)
35{
36 ++cache.group_level;
37}
38
39void pkgDepCache::ActionGroup::release()
40{
41 if(!released)
42 {
43 if(cache.group_level == 0)
44 std::cerr << "W: Unbalanced action groups, expect badness" << std::endl;
45 else
46 {
47 --cache.group_level;
48
49 if(cache.group_level == 0)
50 cache.MarkAndSweep();
51 }
52
53 released = false;
54 }
55}
56
57pkgDepCache::ActionGroup::~ActionGroup()
58{
59 release();
60}
6c139d6e
AL
61
62// DepCache::pkgDepCache - Constructors /*{{{*/
63// ---------------------------------------------------------------------
64/* */
b2e465d6 65pkgDepCache::pkgDepCache(pkgCache *pCache,Policy *Plcy) :
74a05226 66 group_level(0), Cache(pCache), PkgState(0), DepState(0)
6c139d6e 67{
b2e465d6
AL
68 delLocalPolicy = 0;
69 LocalPolicy = Plcy;
70 if (LocalPolicy == 0)
71 delLocalPolicy = LocalPolicy = new Policy;
6c139d6e
AL
72}
73 /*}}}*/
74// DepCache::~pkgDepCache - Destructor /*{{{*/
75// ---------------------------------------------------------------------
76/* */
77pkgDepCache::~pkgDepCache()
78{
79 delete [] PkgState;
80 delete [] DepState;
b2e465d6 81 delete delLocalPolicy;
6c139d6e
AL
82}
83 /*}}}*/
6c139d6e
AL
84// DepCache::Init - Generate the initial extra structures. /*{{{*/
85// ---------------------------------------------------------------------
86/* This allocats the extension buffers and initializes them. */
a246f2dc 87bool pkgDepCache::Init(OpProgress *Prog)
6c139d6e 88{
74a05226
MV
89 // Suppress mark updates during this operation (just in case) and
90 // run a mark operation when Init terminates.
91 ActionGroup actions(*this);
92
6c139d6e
AL
93 delete [] PkgState;
94 delete [] DepState;
95 PkgState = new StateCache[Head().PackageCount];
96 DepState = new unsigned char[Head().DependsCount];
97 memset(PkgState,0,sizeof(*PkgState)*Head().PackageCount);
98 memset(DepState,0,sizeof(*DepState)*Head().DependsCount);
b2e465d6 99
a246f2dc
AL
100 if (Prog != 0)
101 {
102 Prog->OverallProgress(0,2*Head().PackageCount,Head().PackageCount,
db0db9fe
CP
103 _("Building dependency tree"));
104 Prog->SubProgress(Head().PackageCount,_("Candidate versions"));
a246f2dc
AL
105 }
106
6c139d6e
AL
107 /* Set the current state of everything. In this state all of the
108 packages are kept exactly as is. See AllUpgrade */
a246f2dc
AL
109 int Done = 0;
110 for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++)
6c139d6e 111 {
a246f2dc
AL
112 if (Prog != 0)
113 Prog->Progress(Done);
114
6c139d6e
AL
115 // Find the proper cache slot
116 StateCache &State = PkgState[I->ID];
117 State.iFlags = 0;
afb1e2e3 118
6c139d6e
AL
119 // Figure out the install version
120 State.CandidateVer = GetCandidateVer(I);
121 State.InstallVer = I.CurrentVer();
122 State.Mode = ModeKeep;
123
124 State.Update(I,*this);
125 }
126
a246f2dc
AL
127 if (Prog != 0)
128 {
129
130 Prog->OverallProgress(Head().PackageCount,2*Head().PackageCount,
131 Head().PackageCount,
db0db9fe
CP
132 _("Building dependency tree"));
133 Prog->SubProgress(Head().PackageCount,_("Dependency generation"));
a246f2dc
AL
134 }
135
136 Update(Prog);
e004867d
MV
137
138 if(Prog != 0)
139 Prog->Done();
74a05226 140
6c139d6e
AL
141 return true;
142}
143 /*}}}*/
6c139d6e 144
a83d884d
MV
145bool pkgDepCache::readStateFile(OpProgress *Prog)
146{
147 FileFd state_file;
aac2e510 148 string state = _config->FindDir("Dir::State") + "extended_states";
a83d884d
MV
149 if(FileExists(state)) {
150 state_file.Open(state, FileFd::ReadOnly);
151 int file_size = state_file.Size();
bc80031f
MV
152 if(Prog != NULL)
153 Prog->OverallProgress(0, file_size, 1,
154 _("Reading state information"));
a83d884d
MV
155
156 pkgTagFile tagfile(&state_file);
157 pkgTagSection section;
158 int amt=0;
159 while(tagfile.Step(section)) {
160 string pkgname = section.FindS("Package");
161 pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname);
162 // Silently ignore unknown packages and packages with no actual
163 // version.
164 if(!pkg.end() && !pkg.VersionList().end()) {
fc5aece9 165 short reason = section.FindI("Auto-Installed", 0);
e23e6733 166 if(reason > 0)
f8ac1720 167 PkgState[pkg->ID].Flags |= Flag::Auto;
0a57c0f0 168 if(_config->FindB("Debug::pkgAutoRemove",false))
fc5aece9 169 std::cout << "Auto-Installed : " << pkgname << std::endl;
a83d884d 170 amt+=section.size();
bc80031f
MV
171 if(Prog != NULL)
172 Prog->OverallProgress(amt, file_size, 1,
173 _("Reading state information"));
a83d884d 174 }
bc80031f
MV
175 if(Prog != NULL)
176 Prog->OverallProgress(file_size, file_size, 1,
177 _("Reading state information"));
a83d884d
MV
178 }
179 }
180
181 return true;
182}
183
184bool pkgDepCache::writeStateFile(OpProgress *prog)
185{
e23e6733
MV
186 if(_config->FindB("Debug::pkgAutoRemove",false))
187 std::clog << "pkgDepCache::writeStateFile()" << std::endl;
188
b1a8717a
MV
189 FileFd StateFile;
190 string state = _config->FindDir("Dir::State") + "extended_states";
9a9665f9
MV
191
192 // if it does not exist, create a empty one
193 if(!FileExists(state))
194 {
195 StateFile.Open(state, FileFd::WriteEmpty);
196 StateFile.Close();
197 }
198
199 // open it
b1a8717a
MV
200 if(!StateFile.Open(state, FileFd::ReadOnly))
201 return _error->Error(_("Failed to open StateFile %s"),
a83d884d
MV
202 state.c_str());
203
b1a8717a
MV
204 FILE *OutFile;
205 string outfile = state + ".tmp";
206 if((OutFile = fopen(outfile.c_str(),"w")) == NULL)
207 return _error->Error(_("Failed to write temporary StateFile %s"),
208 outfile.c_str());
80fa0d8a 209
b1a8717a
MV
210 // first merge with the existing sections
211 pkgTagFile tagfile(&StateFile);
212 pkgTagSection section;
213 std::set<string> pkgs_seen;
214 const char *nullreorderlist[] = {0};
215 while(tagfile.Step(section)) {
216 string pkgname = section.FindS("Package");
217 // Silently ignore unknown packages and packages with no actual
218 // version.
219 pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname);
220 if(pkg.end() || pkg.VersionList().end())
221 continue;
222 bool oldAuto = section.FindI("Auto-Installed");
223 bool newAuto = (PkgState[pkg->ID].Flags & Flag::Auto);
224 if(_config->FindB("Debug::pkgAutoRemove",false))
225 std::clog << "Update exisiting AutoInstall info: "
226 << pkg.Name() << std::endl;
227 TFRewriteData rewrite[2];
228 rewrite[0].Tag = "Auto-Installed";
229 rewrite[0].Rewrite = newAuto ? "1" : "0";
230 rewrite[0].NewTag = 0;
231 rewrite[1].Tag = 0;
232 TFRewrite(OutFile, section, nullreorderlist, rewrite);
233 fprintf(OutFile,"\n");
234 pkgs_seen.insert(pkgname);
235 }
236
237 // then write the ones we have not seen yet
238 std::ostringstream ostr;
239 for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); pkg++) {
f8ac1720 240 if(PkgState[pkg->ID].Flags & Flag::Auto) {
b1a8717a
MV
241 if (pkgs_seen.find(pkg.Name()) != pkgs_seen.end()) {
242 if(_config->FindB("Debug::pkgAutoRemove",false))
243 std::clog << "Skipping already written " << pkg.Name() << std::endl;
244 continue;
245 }
e23e6733 246 if(_config->FindB("Debug::pkgAutoRemove",false))
b1a8717a
MV
247 std::clog << "Writing new AutoInstall: "
248 << pkg.Name() << std::endl;
a83d884d 249 ostr.str(string(""));
0a57c0f0 250 ostr << "Package: " << pkg.Name()
fc5aece9 251 << "\nAuto-Installed: 1\n\n";
b1a8717a
MV
252 fprintf(OutFile,ostr.str().c_str());
253 fprintf(OutFile,"\n");
a83d884d
MV
254 }
255 }
a4decc40 256 fclose(OutFile);
b1a8717a 257
8a3a2e99 258 // move the outfile over the real file and set permissions
b1a8717a 259 rename(outfile.c_str(), state.c_str());
8a3a2e99 260 chmod(state.c_str(), 0644);
b1a8717a 261
a83d884d
MV
262 return true;
263}
264
6c139d6e
AL
265// DepCache::CheckDep - Checks a single dependency /*{{{*/
266// ---------------------------------------------------------------------
267/* This first checks the dependency against the main target package and
268 then walks along the package provides list and checks if each provides
269 will be installed then checks the provides against the dep. Res will be
270 set to the package which was used to satisfy the dep. */
271bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res)
272{
273 Res = Dep.TargetPkg();
274
275 /* Check simple depends. A depends -should- never self match but
276 we allow it anyhow because dpkg does. Technically it is a packaging
277 bug. Conflicts may never self match */
b2e465d6
AL
278 if (Dep.TargetPkg() != Dep.ParentPkg() ||
279 (Dep->Type != Dep::Conflicts && Dep->Type != Dep::Obsoletes))
6c139d6e
AL
280 {
281 PkgIterator Pkg = Dep.TargetPkg();
282 // Check the base package
283 if (Type == NowVersion && Pkg->CurrentVer != 0)
b2e465d6
AL
284 if (VS().CheckDep(Pkg.CurrentVer().VerStr(),Dep->CompareOp,
285 Dep.TargetVer()) == true)
6c139d6e
AL
286 return true;
287
288 if (Type == InstallVersion && PkgState[Pkg->ID].InstallVer != 0)
b2e465d6
AL
289 if (VS().CheckDep(PkgState[Pkg->ID].InstVerIter(*this).VerStr(),
290 Dep->CompareOp,Dep.TargetVer()) == true)
6c139d6e
AL
291 return true;
292
293 if (Type == CandidateVersion && PkgState[Pkg->ID].CandidateVer != 0)
b2e465d6
AL
294 if (VS().CheckDep(PkgState[Pkg->ID].CandidateVerIter(*this).VerStr(),
295 Dep->CompareOp,Dep.TargetVer()) == true)
6c139d6e
AL
296 return true;
297 }
298
b2e465d6
AL
299 if (Dep->Type == Dep::Obsoletes)
300 return false;
301
6c139d6e
AL
302 // Check the providing packages
303 PrvIterator P = Dep.TargetPkg().ProvidesList();
304 PkgIterator Pkg = Dep.ParentPkg();
305 for (; P.end() != true; P++)
306 {
307 /* Provides may never be applied against the same package if it is
308 a conflicts. See the comment above. */
309 if (P.OwnerPkg() == Pkg && Dep->Type == Dep::Conflicts)
310 continue;
311
312 // Check if the provides is a hit
313 if (Type == NowVersion)
314 {
315 if (P.OwnerPkg().CurrentVer() != P.OwnerVer())
316 continue;
317 }
318
319 if (Type == InstallVersion)
320 {
321 StateCache &State = PkgState[P.OwnerPkg()->ID];
322 if (State.InstallVer != (Version *)P.OwnerVer())
323 continue;
324 }
325
326 if (Type == CandidateVersion)
327 {
328 StateCache &State = PkgState[P.OwnerPkg()->ID];
329 if (State.CandidateVer != (Version *)P.OwnerVer())
330 continue;
331 }
332
333 // Compare the versions.
b2e465d6 334 if (VS().CheckDep(P.ProvideVersion(),Dep->CompareOp,Dep.TargetVer()) == true)
6c139d6e
AL
335 {
336 Res = P.OwnerPkg();
337 return true;
338 }
339 }
340
341 return false;
342}
343 /*}}}*/
344// DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
345// ---------------------------------------------------------------------
346/* Call with Mult = -1 to preform the inverse opration */
b2e465d6 347void pkgDepCache::AddSizes(const PkgIterator &Pkg,signed long Mult)
6c139d6e
AL
348{
349 StateCache &P = PkgState[Pkg->ID];
350
e7b470ee
AL
351 if (Pkg->VersionList == 0)
352 return;
353
e5a1f2ff
AL
354 if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
355 P.Keep() == true)
2cca3bd9 356 return;
2cca3bd9 357
6c139d6e
AL
358 // Compute the size data
359 if (P.NewInstall() == true)
360 {
b2e465d6
AL
361 iUsrSize += (signed)(Mult*P.InstVerIter(*this)->InstalledSize);
362 iDownloadSize += (signed)(Mult*P.InstVerIter(*this)->Size);
d38b7b3d 363 return;
6c139d6e
AL
364 }
365
366 // Upgrading
d0c59649
AL
367 if (Pkg->CurrentVer != 0 &&
368 (P.InstallVer != (Version *)Pkg.CurrentVer() ||
369 (P.iFlags & ReInstall) == ReInstall) && P.InstallVer != 0)
6c139d6e 370 {
b2e465d6
AL
371 iUsrSize += (signed)(Mult*((signed)P.InstVerIter(*this)->InstalledSize -
372 (signed)Pkg.CurrentVer()->InstalledSize));
373 iDownloadSize += (signed)(Mult*P.InstVerIter(*this)->Size);
d38b7b3d
AL
374 return;
375 }
376
377 // Reinstall
2cca3bd9
AL
378 if (Pkg.State() == pkgCache::PkgIterator::NeedsUnpack &&
379 P.Delete() == false)
d38b7b3d 380 {
b2e465d6 381 iDownloadSize += (signed)(Mult*P.InstVerIter(*this)->Size);
d38b7b3d 382 return;
6c139d6e
AL
383 }
384
385 // Removing
386 if (Pkg->CurrentVer != 0 && P.InstallVer == 0)
d38b7b3d 387 {
b2e465d6 388 iUsrSize -= (signed)(Mult*Pkg.CurrentVer()->InstalledSize);
d38b7b3d
AL
389 return;
390 }
6c139d6e
AL
391}
392 /*}}}*/
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 */
401void pkgDepCache::AddStates(const PkgIterator &Pkg,int Add)
402{
403 StateCache &State = PkgState[Pkg->ID];
404
405 // The Package is broken
406 if ((State.DepState & DepInstMin) != DepInstMin)
407 iBrokenCount += Add;
408
409 // Bad state
410 if (Pkg.State() != PkgIterator::NeedsNothing)
411 iBadCount += Add;
412
413 // Not installed
414 if (Pkg->CurrentVer == 0)
415 {
d556d1a1
AL
416 if (State.Mode == ModeDelete &&
417 (State.iFlags | Purge) == Purge && Pkg.Purge() == false)
418 iDelCount += Add;
419
6c139d6e
AL
420 if (State.Mode == ModeInstall)
421 iInstCount += Add;
422 return;
423 }
424
425 // Installed, no upgrade
6321777b 426 if (State.Status == 0)
d0c59649 427 {
6c139d6e
AL
428 if (State.Mode == ModeDelete)
429 iDelCount += Add;
d0c59649
AL
430 else
431 if ((State.iFlags & ReInstall) == ReInstall)
432 iInstCount += Add;
433
6c139d6e
AL
434 return;
435 }
436
437 // Alll 3 are possible
438 if (State.Mode == ModeDelete)
439 iDelCount += Add;
440 if (State.Mode == ModeKeep)
441 iKeepCount += Add;
442 if (State.Mode == ModeInstall)
443 iInstCount += Add;
444}
445 /*}}}*/
446// DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
447// ---------------------------------------------------------------------
448/* The or group results are stored in the last item of the or group. This
449 allows easy detection of the state of a whole or'd group. */
450void pkgDepCache::BuildGroupOrs(VerIterator const &V)
451{
452 unsigned char Group = 0;
453
454 for (DepIterator D = V.DependsList(); D.end() != true; D++)
455 {
456 // Build the dependency state.
457 unsigned char &State = DepState[D->ID];
458
459 /* Invert for Conflicts. We have to do this twice to get the
460 right sense for a conflicts group */
b2e465d6 461 if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
6c139d6e
AL
462 State = ~State;
463
464 // Add to the group if we are within an or..
d2685fd6 465 State &= 0x7;
6c139d6e
AL
466 Group |= State;
467 State |= Group << 3;
468 if ((D->CompareOp & Dep::Or) != Dep::Or)
469 Group = 0;
470
471 // Invert for Conflicts
b2e465d6 472 if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
6c139d6e
AL
473 State = ~State;
474 }
475}
476 /*}}}*/
477// DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
478// ---------------------------------------------------------------------
479/* This is used to run over a dependency list and determine the dep
480 state of the list, filtering it through both a Min check and a Policy
481 check. The return result will have SetMin/SetPolicy low if a check
482 fails. It uses the DepState cache for it's computations. */
483unsigned char pkgDepCache::VersionState(DepIterator D,unsigned char Check,
484 unsigned char SetMin,
485 unsigned char SetPolicy)
486{
487 unsigned char Dep = 0xFF;
488
489 while (D.end() != true)
490 {
491 // Compute a single dependency element (glob or)
492 DepIterator Start = D;
493 unsigned char State = 0;
494 for (bool LastOR = true; D.end() == false && LastOR == true; D++)
495 {
496 State |= DepState[D->ID];
497 LastOR = (D->CompareOp & Dep::Or) == Dep::Or;
498 }
499
500 // Minimum deps that must be satisfied to have a working package
501 if (Start.IsCritical() == true)
502 if ((State & Check) != Check)
503 Dep &= ~SetMin;
504
505 // Policy deps that must be satisfied to install the package
506 if (IsImportantDep(Start) == true &&
507 (State & Check) != Check)
508 Dep &= ~SetPolicy;
509 }
510
511 return Dep;
512}
513 /*}}}*/
514// DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
515// ---------------------------------------------------------------------
516/* This is the main dependency computation bit. It computes the 3 main
517 results for a dependencys, Now, Install and Candidate. Callers must
518 invert the result if dealing with conflicts. */
519unsigned char pkgDepCache::DependencyState(DepIterator &D)
520{
521 unsigned char State = 0;
522
523 if (CheckDep(D,NowVersion) == true)
524 State |= DepNow;
525 if (CheckDep(D,InstallVersion) == true)
526 State |= DepInstall;
527 if (CheckDep(D,CandidateVersion) == true)
528 State |= DepCVer;
529
530 return State;
531}
532 /*}}}*/
533// DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
534// ---------------------------------------------------------------------
535/* This determines the combined dependency representation of a package
536 for its two states now and install. This is done by using the pre-generated
537 dependency information. */
538void pkgDepCache::UpdateVerState(PkgIterator Pkg)
539{
540 // Empty deps are always true
541 StateCache &State = PkgState[Pkg->ID];
542 State.DepState = 0xFF;
543
544 // Check the Current state
545 if (Pkg->CurrentVer != 0)
546 {
547 DepIterator D = Pkg.CurrentVer().DependsList();
548 State.DepState &= VersionState(D,DepNow,DepNowMin,DepNowPolicy);
549 }
550
551 /* Check the candidate state. We do not compare against the whole as
552 a candidate state but check the candidate version against the
553 install states */
554 if (State.CandidateVer != 0)
555 {
556 DepIterator D = State.CandidateVerIter(*this).DependsList();
557 State.DepState &= VersionState(D,DepInstall,DepCandMin,DepCandPolicy);
558 }
559
560 // Check target state which can only be current or installed
561 if (State.InstallVer != 0)
562 {
563 DepIterator D = State.InstVerIter(*this).DependsList();
564 State.DepState &= VersionState(D,DepInstall,DepInstMin,DepInstPolicy);
565 }
566}
567 /*}}}*/
568// DepCache::Update - Figure out all the state information /*{{{*/
569// ---------------------------------------------------------------------
570/* This will figure out the state of all the packages and all the
571 dependencies based on the current policy. */
a246f2dc 572void pkgDepCache::Update(OpProgress *Prog)
6c139d6e
AL
573{
574 iUsrSize = 0;
575 iDownloadSize = 0;
576 iDelCount = 0;
577 iInstCount = 0;
578 iKeepCount = 0;
579 iBrokenCount = 0;
580 iBadCount = 0;
581
582 // Perform the depends pass
a246f2dc
AL
583 int Done = 0;
584 for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++)
6c139d6e 585 {
a246f2dc
AL
586 if (Prog != 0 && Done%20 == 0)
587 Prog->Progress(Done);
6c139d6e
AL
588 for (VerIterator V = I.VersionList(); V.end() != true; V++)
589 {
590 unsigned char Group = 0;
591
592 for (DepIterator D = V.DependsList(); D.end() != true; D++)
593 {
594 // Build the dependency state.
595 unsigned char &State = DepState[D->ID];
b2e465d6 596 State = DependencyState(D);
6c139d6e
AL
597
598 // Add to the group if we are within an or..
599 Group |= State;
600 State |= Group << 3;
601 if ((D->CompareOp & Dep::Or) != Dep::Or)
602 Group = 0;
603
604 // Invert for Conflicts
b2e465d6 605 if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
6c139d6e
AL
606 State = ~State;
607 }
608 }
609
610 // Compute the pacakge dependency state and size additions
611 AddSizes(I);
612 UpdateVerState(I);
613 AddStates(I);
614 }
a246f2dc
AL
615
616 if (Prog != 0)
617 Prog->Progress(Done);
74a05226
MV
618
619 readStateFile(Prog);
6c139d6e
AL
620}
621 /*}}}*/
622// DepCache::Update - Update the deps list of a package /*{{{*/
623// ---------------------------------------------------------------------
624/* This is a helper for update that only does the dep portion of the scan.
74a05226 625 It is mainly meant to scan reverse dependencies. */
6c139d6e
AL
626void pkgDepCache::Update(DepIterator D)
627{
628 // Update the reverse deps
629 for (;D.end() != true; D++)
630 {
631 unsigned char &State = DepState[D->ID];
632 State = DependencyState(D);
633
634 // Invert for Conflicts
b2e465d6 635 if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes)
6c139d6e 636 State = ~State;
b2e465d6 637
6c139d6e
AL
638 RemoveStates(D.ParentPkg());
639 BuildGroupOrs(D.ParentVer());
640 UpdateVerState(D.ParentPkg());
641 AddStates(D.ParentPkg());
642 }
643}
644 /*}}}*/
645// DepCache::Update - Update the related deps of a package /*{{{*/
646// ---------------------------------------------------------------------
647/* This is called whenever the state of a package changes. It updates
648 all cached dependencies related to this package. */
649void pkgDepCache::Update(PkgIterator const &Pkg)
b2e465d6 650{
6c139d6e
AL
651 // Recompute the dep of the package
652 RemoveStates(Pkg);
653 UpdateVerState(Pkg);
654 AddStates(Pkg);
655
656 // Update the reverse deps
657 Update(Pkg.RevDependsList());
658
659 // Update the provides map for the current ver
660 if (Pkg->CurrentVer != 0)
661 for (PrvIterator P = Pkg.CurrentVer().ProvidesList();
662 P.end() != true; P++)
663 Update(P.ParentPkg().RevDependsList());
664
665 // Update the provides map for the candidate ver
9972233d
AL
666 if (PkgState[Pkg->ID].CandidateVer != 0)
667 for (PrvIterator P = PkgState[Pkg->ID].CandidateVerIter(*this).ProvidesList();
668 P.end() != true; P++)
669 Update(P.ParentPkg().RevDependsList());
6c139d6e
AL
670}
671
672 /*}}}*/
673
674// DepCache::MarkKeep - Put the package in the keep state /*{{{*/
675// ---------------------------------------------------------------------
676/* */
74a05226 677void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser)
6c139d6e
AL
678{
679 // Simplifies other routines.
680 if (Pkg.end() == true)
681 return;
813c8eea
AL
682
683 /* Reject an attempt to keep a non-source broken installed package, those
684 must be upgraded */
685 if (Pkg.State() == PkgIterator::NeedsUnpack &&
686 Pkg.CurrentVer().Downloadable() == false)
687 return;
6c139d6e 688
74a05226
MV
689 /** \todo Can this be moved later in the method? */
690 ActionGroup group(*this);
691
6c139d6e
AL
692 /* We changed the soft state all the time so the UI is a bit nicer
693 to use */
694 StateCache &P = PkgState[Pkg->ID];
695 if (Soft == true)
696 P.iFlags |= AutoKept;
697 else
698 P.iFlags &= ~AutoKept;
699
700 // Check that it is not already kept
701 if (P.Mode == ModeKeep)
702 return;
703
704 // We dont even try to keep virtual packages..
705 if (Pkg->VersionList == 0)
706 return;
32085498
MV
707
708#if 0 // reseting the autoflag here means we lose the
709 // auto-mark information if a user selects a package for removal
710 // but changes his mind then and sets it for keep again
711 // - this makes sense as default when all Garbage dependencies
712 // are automatically marked for removal (as aptitude does).
713 // setting a package for keep then makes it no longer autoinstalled
714 // for all other use-case this action is rather suprising
74a05226
MV
715 if(FromUser && !P.Marked)
716 P.Flags &= ~Flag::Auto;
32085498
MV
717#endif
718
6c139d6e
AL
719 RemoveSizes(Pkg);
720 RemoveStates(Pkg);
721
722 P.Mode = ModeKeep;
723 if (Pkg->CurrentVer == 0)
724 P.InstallVer = 0;
725 else
726 P.InstallVer = Pkg.CurrentVer();
727
728 AddStates(Pkg);
729
730 Update(Pkg);
731
732 AddSizes(Pkg);
733}
734 /*}}}*/
735// DepCache::MarkDelete - Put the package in the delete state /*{{{*/
736// ---------------------------------------------------------------------
737/* */
d556d1a1 738void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge)
6c139d6e
AL
739{
740 // Simplifies other routines.
741 if (Pkg.end() == true)
742 return;
743
74a05226
MV
744 ActionGroup group(*this);
745
6c139d6e
AL
746 // Check that it is not already marked for delete
747 StateCache &P = PkgState[Pkg->ID];
d556d1a1
AL
748 P.iFlags &= ~(AutoKept | Purge);
749 if (rPurge == true)
750 P.iFlags |= Purge;
751
752 if ((P.Mode == ModeDelete || P.InstallVer == 0) &&
753 (Pkg.Purge() == true || rPurge == false))
6c139d6e 754 return;
d556d1a1 755
6c139d6e
AL
756 // We dont even try to delete virtual packages..
757 if (Pkg->VersionList == 0)
758 return;
759
760 RemoveSizes(Pkg);
761 RemoveStates(Pkg);
762
d556d1a1 763 if (Pkg->CurrentVer == 0 && (Pkg.Purge() == true || rPurge == false))
3d615484
AL
764 P.Mode = ModeKeep;
765 else
766 P.Mode = ModeDelete;
6c139d6e 767 P.InstallVer = 0;
6c139d6e
AL
768
769 AddStates(Pkg);
770 Update(Pkg);
771 AddSizes(Pkg);
772}
773 /*}}}*/
774// DepCache::MarkInstall - Put the package in the install state /*{{{*/
775// ---------------------------------------------------------------------
776/* */
b2e465d6 777void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
74a05226 778 unsigned long Depth, bool FromUser)
b2e465d6
AL
779{
780 if (Depth > 100)
781 return;
782
6c139d6e
AL
783 // Simplifies other routines.
784 if (Pkg.end() == true)
785 return;
786
74a05226
MV
787 ActionGroup group(*this);
788
6c139d6e
AL
789 /* Check that it is not already marked for install and that it can be
790 installed */
791 StateCache &P = PkgState[Pkg->ID];
792 P.iFlags &= ~AutoKept;
793 if (P.InstBroken() == false && (P.Mode == ModeInstall ||
794 P.CandidateVer == (Version *)Pkg.CurrentVer()))
795 {
796 if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0)
74a05226 797 MarkKeep(Pkg, false, FromUser);
6c139d6e
AL
798 return;
799 }
b2e465d6
AL
800
801 // See if there is even any possible instalation candidate
802 if (P.CandidateVer == 0)
803 return;
6c139d6e
AL
804
805 // We dont even try to install virtual packages..
806 if (Pkg->VersionList == 0)
807 return;
808
809 /* Target the candidate version and remove the autoflag. We reset the
810 autoflag below if this was called recursively. Otherwise the user
811 should have the ability to de-auto a package by changing its state */
812 RemoveSizes(Pkg);
813 RemoveStates(Pkg);
814
815 P.Mode = ModeInstall;
816 P.InstallVer = P.CandidateVer;
74a05226
MV
817
818 if(FromUser)
819 {
820 // Set it to manual if it's a new install or cancelling the
821 // removal of a garbage package.
822 if(P.Status == 2 || (!Pkg.CurrentVer().end() && !P.Marked))
823 P.Flags &= ~Flag::Auto;
824 }
825 else
826 {
827 // Set it to auto if this is a new install.
828 if(P.Status == 2)
829 P.Flags |= Flag::Auto;
830 }
6c139d6e
AL
831 if (P.CandidateVer == (Version *)Pkg.CurrentVer())
832 P.Mode = ModeKeep;
833
834 AddStates(Pkg);
835 Update(Pkg);
836 AddSizes(Pkg);
837
838 if (AutoInst == false)
839 return;
840
841 DepIterator Dep = P.InstVerIter(*this).DependsList();
842 for (; Dep.end() != true;)
843 {
844 // Grok or groups
845 DepIterator Start = Dep;
846 bool Result = true;
b2e465d6
AL
847 unsigned Ors = 0;
848 for (bool LastOR = true; Dep.end() == false && LastOR == true; Dep++,Ors++)
6c139d6e
AL
849 {
850 LastOR = (Dep->CompareOp & Dep::Or) == Dep::Or;
851
852 if ((DepState[Dep->ID] & DepInstall) == DepInstall)
853 Result = false;
854 }
855
856 // Dep is satisfied okay.
857 if (Result == false)
858 continue;
859
860 /* Check if this dep should be consider for install. If it is a user
861 defined important dep and we are installed a new package then
862 it will be installed. Otherwise we only worry about critical deps */
863 if (IsImportantDep(Start) == false)
864 continue;
865 if (Pkg->CurrentVer != 0 && Start.IsCritical() == false)
866 continue;
b2e465d6
AL
867
868 /* If we are in an or group locate the first or that can
869 succeed. We have already cached this.. */
870 for (; Ors > 1 && (DepState[Start->ID] & DepCVer) != DepCVer; Ors--)
871 Start++;
2ed9b455 872
b2e465d6
AL
873 /* This bit is for processing the possibilty of an install/upgrade
874 fixing the problem */
875 SPtrArray<Version *> List = Start.AllTargets();
6c139d6e
AL
876 if ((DepState[Start->ID] & DepCVer) == DepCVer)
877 {
b2e465d6
AL
878 // Right, find the best version to install..
879 Version **Cur = List;
880 PkgIterator P = Start.TargetPkg();
881 PkgIterator InstPkg(*Cache,0);
6c139d6e 882
b2e465d6
AL
883 // See if there are direct matches (at the start of the list)
884 for (; *Cur != 0 && (*Cur)->ParentPkg == P.Index(); Cur++)
885 {
886 PkgIterator Pkg(*Cache,Cache->PkgP + (*Cur)->ParentPkg);
887 if (PkgState[Pkg->ID].CandidateVer != *Cur)
888 continue;
889 InstPkg = Pkg;
890 break;
891 }
892
893 // Select the highest priority providing package
2ed9b455 894 if (InstPkg.end() == true)
b2e465d6
AL
895 {
896 pkgPrioSortList(*Cache,Cur);
897 for (; *Cur != 0; Cur++)
898 {
899 PkgIterator Pkg(*Cache,Cache->PkgP + (*Cur)->ParentPkg);
900 if (PkgState[Pkg->ID].CandidateVer != *Cur)
901 continue;
902 InstPkg = Pkg;
903 break;
904 }
905 }
906
a23dcda4 907 if (InstPkg.end() == false)
b2e465d6 908 {
d4c5f11f
MV
909 if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
910 std::clog << "Installing " << InstPkg.Name()
911 << " as dep of " << Pkg.Name()
912 << std::endl;
92b9551f
MV
913 // now check if we should consider it a automatic dependency or not
914 string sec = _config->Find("APT::Never-MarkAuto-Section","");
915 if(Pkg.Section() && (string(Pkg.Section()) == sec))
916 {
917 if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
918 std::clog << "Setting NOT as auto-installed because its a direct dep of a package in section " << sec << std::endl;
919 MarkInstall(InstPkg,true,Depth + 1, true);
920 }
921 else
922 {
923 // mark automatic dependency
924 MarkInstall(InstPkg,true,Depth + 1, false);
925 // Set the autoflag, after MarkInstall because MarkInstall unsets it
926 if (P->CurrentVer == 0)
927 PkgState[InstPkg->ID].Flags |= Flag::Auto;
928 }
b2e465d6 929 }
6c139d6e
AL
930 continue;
931 }
932
b2e465d6
AL
933 /* For conflicts we just de-install the package and mark as auto,
934 Conflicts may not have or groups */
935 if (Start->Type == Dep::Conflicts || Start->Type == Dep::Obsoletes)
6c139d6e 936 {
6c139d6e
AL
937 for (Version **I = List; *I != 0; I++)
938 {
939 VerIterator Ver(*this,*I);
940 PkgIterator Pkg = Ver.ParentPkg();
941
942 MarkDelete(Pkg);
6c139d6e 943 }
6c139d6e
AL
944 continue;
945 }
946 }
947}
948 /*}}}*/
d0c59649
AL
949// DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
950// ---------------------------------------------------------------------
951/* */
952void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To)
953{
74a05226
MV
954 ActionGroup group(*this);
955
d0c59649
AL
956 RemoveSizes(Pkg);
957 RemoveStates(Pkg);
958
959 StateCache &P = PkgState[Pkg->ID];
960 if (To == true)
961 P.iFlags |= ReInstall;
962 else
963 P.iFlags &= ~ReInstall;
964
965 AddStates(Pkg);
966 AddSizes(Pkg);
967}
968 /*}}}*/
b2e465d6
AL
969// DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
970// ---------------------------------------------------------------------
971/* */
972void pkgDepCache::SetCandidateVersion(VerIterator TargetVer)
973{
74a05226
MV
974 ActionGroup group(*this);
975
b2e465d6
AL
976 pkgCache::PkgIterator Pkg = TargetVer.ParentPkg();
977 StateCache &P = PkgState[Pkg->ID];
74a05226 978
b2e465d6
AL
979 RemoveSizes(Pkg);
980 RemoveStates(Pkg);
981
982 if (P.CandidateVer == P.InstallVer)
983 P.InstallVer = (Version *)TargetVer;
984 P.CandidateVer = (Version *)TargetVer;
985 P.Update(Pkg,*this);
986
987 AddStates(Pkg);
988 Update(Pkg);
989 AddSizes(Pkg);
990}
74a05226
MV
991
992void pkgDepCache::MarkAuto(const PkgIterator &Pkg, bool Auto)
993{
994 StateCache &state = PkgState[Pkg->ID];
995
996 ActionGroup group(*this);
997
998 if(Auto)
999 state.Flags |= Flag::Auto;
1000 else
1001 state.Flags &= ~Flag::Auto;
1002}
b2e465d6 1003 /*}}}*/
6c139d6e
AL
1004// StateCache::Update - Compute the various static display things /*{{{*/
1005// ---------------------------------------------------------------------
1006/* This is called whenever the Candidate version changes. */
1007void pkgDepCache::StateCache::Update(PkgIterator Pkg,pkgCache &Cache)
1008{
1009 // Some info
1010 VerIterator Ver = CandidateVerIter(Cache);
1011
1012 // Use a null string or the version string
1013 if (Ver.end() == true)
1014 CandVersion = "";
1015 else
1016 CandVersion = Ver.VerStr();
1017
1018 // Find the current version
1019 CurVersion = "";
1020 if (Pkg->CurrentVer != 0)
1021 CurVersion = Pkg.CurrentVer().VerStr();
1022
1023 // Strip off the epochs for display
1024 CurVersion = StripEpoch(CurVersion);
1025 CandVersion = StripEpoch(CandVersion);
1026
1027 // Figure out if its up or down or equal
1028 Status = Ver.CompareVer(Pkg.CurrentVer());
1029 if (Pkg->CurrentVer == 0 || Pkg->VersionList == 0 || CandidateVer == 0)
1030 Status = 2;
1031}
1032 /*}}}*/
1033// StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
1034// ---------------------------------------------------------------------
1035/* */
1036const char *pkgDepCache::StateCache::StripEpoch(const char *Ver)
1037{
1038 if (Ver == 0)
1039 return 0;
1040
1041 // Strip any epoch
1042 for (const char *I = Ver; *I != 0; I++)
1043 if (*I == ':')
1044 return I + 1;
1045 return Ver;
1046}
1047 /*}}}*/
b2e465d6
AL
1048
1049// Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
6321777b 1050// ---------------------------------------------------------------------
b2e465d6
AL
1051/* The default just returns the highest available version that is not
1052 a source and automatic. */
1053pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg)
6321777b 1054{
b2e465d6
AL
1055 /* Not source/not automatic versions cannot be a candidate version
1056 unless they are already installed */
1057 VerIterator Last(*(pkgCache *)this,0);
6321777b 1058
b2e465d6
AL
1059 for (VerIterator I = Pkg.VersionList(); I.end() == false; I++)
1060 {
1061 if (Pkg.CurrentVer() == I)
1062 return I;
1063
1064 for (VerFileIterator J = I.FileList(); J.end() == false; J++)
1065 {
1066 if ((J.File()->Flags & Flag::NotSource) != 0)
1067 continue;
1068
1069 /* Stash the highest version of a not-automatic source, we use it
1070 if there is nothing better */
1071 if ((J.File()->Flags & Flag::NotAutomatic) != 0)
1072 {
1073 if (Last.end() == true)
1074 Last = I;
1075 continue;
1076 }
1077
1078 return I;
1079 }
1080 }
6321777b 1081
b2e465d6
AL
1082 return Last;
1083}
1084 /*}}}*/
1085// Policy::IsImportantDep - True if the dependency is important /*{{{*/
1086// ---------------------------------------------------------------------
1087/* */
1088bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep)
1089{
1090 return Dep.IsCritical();
6321777b
AL
1091}
1092 /*}}}*/
74a05226
MV
1093
1094pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc()
1095 : constructedSuccessfully(false)
1096{
1097 Configuration::Item const *Opts;
1098 Opts = _config->Tree("APT::NeverAutoRemove");
1099 if (Opts != 0 && Opts->Child != 0)
1100 {
1101 Opts = Opts->Child;
1102 for (; Opts != 0; Opts = Opts->Next)
1103 {
1104 if (Opts->Value.empty() == true)
1105 continue;
1106
1107 regex_t *p = new regex_t;
1108 if(regcomp(p,Opts->Value.c_str(),
1109 REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
1110 {
1111 regfree(p);
1112 delete p;
1113 _error->Error("Regex compilation error for APT::NeverAutoRemove");
1114 return;
1115 }
1116
1117 rootSetRegexp.push_back(p);
1118 }
1119 }
1120
1121 constructedSuccessfully = true;
1122}
1123
1124pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc()
1125{
1126 for(unsigned int i = 0; i < rootSetRegexp.size(); i++)
1127 {
1128 regfree(rootSetRegexp[i]);
1129 delete rootSetRegexp[i];
1130 }
1131}
1132
1133
1134bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator &pkg)
1135{
1136 for(unsigned int i = 0; i < rootSetRegexp.size(); i++)
1137 if (regexec(rootSetRegexp[i], pkg.Name(), 0, 0, 0) == 0)
1138 return true;
1139
1140 return false;
1141}
1142
1143pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc()
1144{
1145 DefaultRootSetFunc *f = new DefaultRootSetFunc;
1146 if(f->wasConstructedSuccessfully())
1147 return f;
1148 else
1149 {
1150 delete f;
1151 return NULL;
1152 }
1153}
1154
1155bool pkgDepCache::MarkFollowsRecommends()
1156{
1157 return _config->FindB("APT::AutoRemove::RecommendsImportant", true);
1158}
1159
1160bool pkgDepCache::MarkFollowsSuggests()
1161{
1162 return _config->FindB("APT::AutoRemove::SuggestsImportant", false);
1163}
1164
1165// the main mark algorithm
1166bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
1167{
1168 bool follow_recommends;
1169 bool follow_suggests;
1170
1171 // init the states
1172 for(PkgIterator p = PkgBegin(); !p.end(); ++p)
1173 {
1174 PkgState[p->ID].Marked = false;
1175 PkgState[p->ID].Garbage = false;
1176
1177 // debug output
1178 if(_config->FindB("Debug::pkgAutoRemove",false)
1179 && PkgState[p->ID].Flags & Flag::Auto)
1180 std::clog << "AutoDep: " << p.Name() << std::endl;
1181 }
1182
1183 // init vars
1184 follow_recommends = MarkFollowsRecommends();
1185 follow_suggests = MarkFollowsSuggests();
1186
1187
1188
1189 // do the mark part, this is the core bit of the algorithm
1190 for(PkgIterator p = PkgBegin(); !p.end(); ++p)
1191 {
1192 if(!(PkgState[p->ID].Flags & Flag::Auto) ||
1193 (p->Flags & Flag::Essential) ||
1194 userFunc.InRootSet(p))
1195
1196 {
1197 // the package is installed (and set to keep)
1198 if(PkgState[p->ID].Keep() && !p.CurrentVer().end())
1199 MarkPackage(p, p.CurrentVer(),
1200 follow_recommends, follow_suggests);
1201 // the package is to be installed
1202 else if(PkgState[p->ID].Install())
1203 MarkPackage(p, PkgState[p->ID].InstVerIter(*this),
1204 follow_recommends, follow_suggests);
1205 }
1206 }
1207
1208 return true;
1209}
1210
1211// mark a single package in Mark-and-Sweep
1212void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
1213 const pkgCache::VerIterator &ver,
1214 bool follow_recommends,
1215 bool follow_suggests)
1216{
1217 pkgDepCache::StateCache &state = PkgState[pkg->ID];
1218 VerIterator candver = state.CandidateVerIter(*this);
1219 VerIterator instver = state.InstVerIter(*this);
1220
1221#if 0
1222 // If a package was garbage-collected but is now being marked, we
1223 // should re-select it
1224 // For cases when a pkg is set to upgrade and this trigger the
1225 // removal of a no-longer used dependency. if the pkg is set to
1226 // keep again later it will result in broken deps
1227 if(state.Delete() && state.RemoveReason = Unused)
1228 {
1229 if(ver==candver)
1230 mark_install(pkg, false, false, NULL);
1231 else if(ver==pkg.CurrentVer())
1232 MarkKeep(pkg, false, false);
1233
1234 instver=state.InstVerIter(*this);
1235 }
1236#endif
1237
1238 // Ignore versions other than the InstVer, and ignore packages
1239 // that are already going to be removed or just left uninstalled.
1240 if(!(ver == instver && !instver.end()))
1241 return;
1242
1243 // if we are marked already we are done
1244 if(state.Marked)
1245 return;
1246
1247 //std::cout << "Setting Marked for: " << pkg.Name() << std::endl;
1248 state.Marked=true;
1249
1250 if(!ver.end())
1251 {
1252 for(DepIterator d = ver.DependsList(); !d.end(); ++d)
1253 {
1254 if(d->Type == Dep::Depends ||
1255 d->Type == Dep::PreDepends ||
1256 (follow_recommends &&
1257 d->Type == Dep::Recommends) ||
1258 (follow_suggests &&
1259 d->Type == Dep::Suggests))
1260 {
1261 // Try all versions of this package.
1262 for(VerIterator V = d.TargetPkg().VersionList();
1263 !V.end(); ++V)
1264 {
1265 if(_system->VS->CheckDep(V.VerStr(), d->CompareOp, d.TargetVer()))
1266 {
1267 MarkPackage(V.ParentPkg(), V,
1268 follow_recommends, follow_suggests);
1269 }
1270 }
1271 // Now try virtual packages
1272 for(PrvIterator prv=d.TargetPkg().ProvidesList();
1273 !prv.end(); ++prv)
1274 {
1275 if(_system->VS->CheckDep(prv.ProvideVersion(), d->CompareOp,
1276 d.TargetVer()))
1277 {
1278 MarkPackage(prv.OwnerPkg(), prv.OwnerVer(),
1279 follow_recommends, follow_suggests);
1280 }
1281 }
1282 }
1283 }
1284 }
1285}
1286
1287bool pkgDepCache::Sweep()
1288{
1289 // do the sweep
1290 for(PkgIterator p=PkgBegin(); !p.end(); ++p)
1291 {
1292 StateCache &state=PkgState[p->ID];
1293
c9b320e8
MV
1294 // skip required packages
1295 if (!p.CurrentVer().end() &&
1296 (p.CurrentVer()->Priority == pkgCache::State::Required))
1297 continue;
1298
74a05226 1299 // if it is not marked and it is installed, it's garbage
32085498 1300 if(!state.Marked && (!p.CurrentVer().end() || state.Install()))
74a05226
MV
1301 {
1302 state.Garbage=true;
1303 if(_config->FindB("Debug::pkgAutoRemove",false))
1304 std::cout << "Garbage: " << p.Name() << std::endl;
1305 }
1306 }
1307
1308 return true;
1309}