apt  2.2.4
About: Apt (Advanced Package Tool) is a management system for software packages (Debian/Ubuntu). Release series 2.2.
  Fossies Dox: apt-2.2.4.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

depcache.cc
Go to the documentation of this file.
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 /* ######################################################################
4 
5  Dependency Cache - Caches Dependency information.
6 
7  ##################################################################### */
8  /*}}}*/
9 // Include Files /*{{{*/
10 #include <config.h>
11 
12 #include <apt-pkg/algorithms.h>
14 #include <apt-pkg/cachefile.h>
15 #include <apt-pkg/cacheset.h>
16 #include <apt-pkg/configuration.h>
17 #include <apt-pkg/depcache.h>
18 #include <apt-pkg/error.h>
19 #include <apt-pkg/fileutl.h>
20 #include <apt-pkg/macros.h>
21 #include <apt-pkg/pkgcache.h>
22 #include <apt-pkg/prettyprinters.h>
23 #include <apt-pkg/progress.h>
24 #include <apt-pkg/strutl.h>
25 #include <apt-pkg/tagfile.h>
26 #include <apt-pkg/version.h>
27 #include <apt-pkg/versionmatch.h>
28 
29 #include <algorithm>
30 #include <iostream>
31 #include <iterator>
32 #include <list>
33 #include <set>
34 #include <string>
35 #include <utility>
36 #include <vector>
37 #include <stdio.h>
38 #include <string.h>
39 
40 #include <sys/stat.h>
41 
42 #include <apti18n.h>
43  /*}}}*/
44 
45 using std::string;
46 
47 // helper for kernel autoremoval /*{{{*/
48 
49 /** \brief Returns \b true for packages matching a regular
50  * expression in APT::NeverAutoRemove.
51  */
53 {
54  std::unique_ptr<APT::CacheFilter::Matcher> Kernels;
55 
56  public:
57  DefaultRootSetFunc2(pkgCache *cache) : Kernels(APT::KernelAutoRemoveHelper::GetProtectedKernelsFilter(cache)){};
58  virtual ~DefaultRootSetFunc2(){};
59 
60  bool InRootSet(const pkgCache::PkgIterator &pkg) APT_OVERRIDE { return pkg.end() == false && ((*Kernels)(pkg) || DefaultRootSetFunc::InRootSet(pkg)); };
61 };
62 
63  /*}}}*/
64 // helper for Install-Recommends-Sections and Never-MarkAuto-Sections /*{{{*/
65 static bool
66 ConfigValueInSubTree(const char* SubTree, const char *needle)
67 {
68  Configuration::Item const *Opts;
69  Opts = _config->Tree(SubTree);
70  if (Opts != 0 && Opts->Child != 0)
71  {
72  Opts = Opts->Child;
73  for (; Opts != 0; Opts = Opts->Next)
74  {
75  if (Opts->Value.empty() == true)
76  continue;
77  if (strcmp(needle, Opts->Value.c_str()) == 0)
78  return true;
79  }
80  }
81  return false;
82 }
83  /*}}}*/
85  d(NULL), cache(cache), released(false)
86 {
88 }
89 
91 {
92  if(!released)
93  {
94  if(cache.group_level == 0)
95  std::cerr << "W: Unbalanced action groups, expect badness" << std::endl;
96  else
97  {
98  --cache.group_level;
99 
100  if(cache.group_level == 0)
101  cache.MarkAndSweep();
102  }
103 
104  released = true;
105  }
106 }
107 
109 {
110  release();
111 }
112  /*}}}*/
113 // DepCache::pkgDepCache - Constructors /*{{{*/
114 // ---------------------------------------------------------------------
115 /* */
116 
118 {
119  std::unique_ptr<InRootSetFunc> inRootSetFunc;
120 };
121 pkgDepCache::pkgDepCache(pkgCache *const pCache, Policy *const Plcy) : group_level(0), Cache(pCache), PkgState(0), DepState(0),
124 {
125  DebugMarker = _config->FindB("Debug::pkgDepCache::Marker", false);
126  DebugAutoInstall = _config->FindB("Debug::pkgDepCache::AutoInstall", false);
127  delLocalPolicy = 0;
128  LocalPolicy = Plcy;
129  if (LocalPolicy == 0)
131 }
132  /*}}}*/
133 // DepCache::~pkgDepCache - Destructor /*{{{*/
134 // ---------------------------------------------------------------------
135 /* */
137 {
138  delete [] PkgState;
139  delete [] DepState;
140  delete delLocalPolicy;
141  delete d;
142 }
143  /*}}}*/
144 bool pkgDepCache::CheckConsistency(char const *const msgtag) /*{{{*/
145 {
146  auto const OrigPkgState = PkgState;
147  auto const OrigDepState = DepState;
148 
150  DepState = new unsigned char[Head().DependsCount];
151  memset(PkgState,0,sizeof(*PkgState)*Head().PackageCount);
152  memset(DepState,0,sizeof(*DepState)*Head().DependsCount);
153 
154  auto const origUsrSize = iUsrSize;
155  auto const origDownloadSize = iDownloadSize;
156  auto const origInstCount = iInstCount;
157  auto const origDelCount = iDelCount;
158  auto const origKeepCount = iKeepCount;
159  auto const origBrokenCount = iBrokenCount;
160  auto const origPolicyBrokenCount = iPolicyBrokenCount;
161  auto const origBadCount = iBadCount;
162 
163  for (PkgIterator I = PkgBegin(); not I.end(); ++I)
164  {
165  auto &State = PkgState[I->ID];
166  auto const &OrigState = OrigPkgState[I->ID];
167  State.iFlags = OrigState.iFlags;
168 
169  State.CandidateVer = OrigState.CandidateVer;
170  State.InstallVer = OrigState.InstallVer;
171  State.Mode = OrigState.Mode;
172  State.Update(I,*this);
173  State.Status = OrigState.Status;
174  }
175  PerformDependencyPass(nullptr);
176 
177  _error->PushToStack();
178 #define APT_CONSISTENCY_CHECK(VAR,STR) \
179  if (orig##VAR != i##VAR) \
180  _error->Warning("Internal Inconsistency in pkgDepCache: " #VAR " " STR " vs " STR " (%s)", i##VAR, orig##VAR, msgtag)
182  APT_CONSISTENCY_CHECK(DownloadSize, "%lld");
189 #undef APT_CONSISTENCY_CHECK
190 
191  for (PkgIterator P = PkgBegin(); not P.end(); ++P)
192  {
193  auto const &State = PkgState[P->ID];
194  auto const &OrigState = OrigPkgState[P->ID];
195  if (State.Status != OrigState.Status)
196  _error->Warning("Internal Inconsistency in pkgDepCache: Status of %s is %d vs %d (%s)", P.FullName().c_str(), State.Status, OrigState.Status, msgtag);
197  if (State.NowBroken() != OrigState.NowBroken())
198  _error->Warning("Internal Inconsistency in pkgDepCache: Now broken for %s is %d vs %d (%s)", P.FullName().c_str(), static_cast<int>(State.DepState), static_cast<int>(OrigState.DepState), msgtag);
199  if (State.NowPolicyBroken() != OrigState.NowPolicyBroken())
200  _error->Warning("Internal Inconsistency in pkgDepCache: Now policy broken for %s is %d vs %d (%s)", P.FullName().c_str(), static_cast<int>(State.DepState), static_cast<int>(OrigState.DepState), msgtag);
201  if (State.InstBroken() != OrigState.InstBroken())
202  _error->Warning("Internal Inconsistency in pkgDepCache: Install broken for %s is %d vs %d (%s)", P.FullName().c_str(), static_cast<int>(State.DepState), static_cast<int>(OrigState.DepState), msgtag);
203  if (State.InstPolicyBroken() != OrigState.InstPolicyBroken())
204  _error->Warning("Internal Inconsistency in pkgDepCache: Install broken for %s is %d vs %d (%s)", P.FullName().c_str(), static_cast<int>(State.DepState), static_cast<int>(OrigState.DepState), msgtag);
205  }
206 
207  auto inconsistent = _error->PendingError();
208  _error->MergeWithStack();
209 
210  delete[] PkgState;
211  delete[] DepState;
212  PkgState = OrigPkgState;
213  DepState = OrigDepState;
214  iUsrSize = origUsrSize;
215  iDownloadSize = origDownloadSize;
216  iInstCount = origInstCount;
217  iDelCount = origDelCount;
218  iKeepCount = origKeepCount;
219  iBrokenCount = origBrokenCount;
220  iPolicyBrokenCount = origPolicyBrokenCount;
221  iBadCount = origBadCount;
222 
223  return not inconsistent;
224 }
225  /*}}}*/
226 // DepCache::Init - Generate the initial extra structures. /*{{{*/
227 // ---------------------------------------------------------------------
228 /* This allocats the extension buffers and initializes them. */
229 bool pkgDepCache::Init(OpProgress * const Prog)
230 {
231  // Suppress mark updates during this operation (just in case) and
232  // run a mark operation when Init terminates.
233  ActionGroup actions(*this);
234 
235  delete [] PkgState;
236  delete [] DepState;
238  DepState = new unsigned char[Head().DependsCount];
239  memset(PkgState,0,sizeof(*PkgState)*Head().PackageCount);
240  memset(DepState,0,sizeof(*DepState)*Head().DependsCount);
241 
242  if (Prog != 0)
243  {
244  Prog->OverallProgress(0,2*Head().PackageCount,Head().PackageCount,
245  _("Building dependency tree"));
246  Prog->SubProgress(Head().PackageCount,_("Candidate versions"));
247  }
248 
249  /* Set the current state of everything. In this state all of the
250  packages are kept exactly as is. See AllUpgrade */
251  int Done = 0;
252  for (PkgIterator I = PkgBegin(); I.end() != true; ++I, ++Done)
253  {
254  if (Prog != 0 && Done%20 == 0)
255  Prog->Progress(Done);
256 
257  // Find the proper cache slot
258  StateCache &State = PkgState[I->ID];
259  State.iFlags = 0;
260 
261  // Figure out the install version
263  State.InstallVer = I.CurrentVer();
264  State.Mode = ModeKeep;
265 
266  State.Update(I,*this);
267  }
268 
269  if (Prog != 0)
270  {
271  Prog->OverallProgress(Head().PackageCount,2*Head().PackageCount,
272  Head().PackageCount,
273  _("Building dependency tree"));
274  Prog->SubProgress(Head().PackageCount,_("Dependency generation"));
275  }
276 
277  Update(Prog);
278 
279  if(Prog != 0)
280  Prog->Done();
281 
282  return true;
283 }
284  /*}}}*/
285 bool pkgDepCache::readStateFile(OpProgress * const Prog) /*{{{*/
286 {
287  FileFd state_file;
288  string const state = _config->FindFile("Dir::State::extended_states");
289  if(RealFileExists(state)) {
290  state_file.Open(state, FileFd::ReadOnly, FileFd::Extension);
291  off_t const file_size = state_file.Size();
292  if(Prog != NULL)
293  {
294  Prog->Done();
295  Prog->OverallProgress(0, file_size, 1,
296  _("Reading state information"));
297  }
298 
299  pkgTagFile tagfile(&state_file);
300  pkgTagSection section;
301  off_t amt = 0;
302  bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
303  while(tagfile.Step(section)) {
304  string const pkgname = section.FindS("Package");
305  string pkgarch = section.FindS("Architecture");
306  if (pkgarch.empty() == true)
307  pkgarch = "any";
308  pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch);
309  // Silently ignore unknown packages and packages with no actual version.
310  if(pkg.end() == true || pkg->VersionList == 0)
311  continue;
312 
313  short const reason = section.FindI("Auto-Installed", 0);
314  if(reason > 0)
315  {
316  PkgState[pkg->ID].Flags |= Flag::Auto;
317  if (unlikely(debug_autoremove))
318  std::clog << "Auto-Installed : " << pkg.FullName() << std::endl;
319  if (pkgarch == "any")
320  {
321  pkgCache::GrpIterator G = pkg.Group();
322  for (pkg = G.NextPkg(pkg); pkg.end() != true; pkg = G.NextPkg(pkg))
323  if (pkg->VersionList != 0)
324  PkgState[pkg->ID].Flags |= Flag::Auto;
325  }
326  }
327  amt += section.size();
328  if(Prog != NULL)
329  Prog->OverallProgress(amt, file_size, 1,
330  _("Reading state information"));
331  }
332  if(Prog != NULL)
333  Prog->OverallProgress(file_size, file_size, 1,
334  _("Reading state information"));
335  }
336 
337  return true;
338 }
339  /*}}}*/
340 bool pkgDepCache::writeStateFile(OpProgress * const /*prog*/, bool const InstalledOnly) /*{{{*/
341 {
342  bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
343 
344  if(debug_autoremove)
345  std::clog << "pkgDepCache::writeStateFile()" << std::endl;
346 
347  FileFd StateFile;
348  string const state = _config->FindFile("Dir::State::extended_states");
349  if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::State"), flNotFile(state)) == false)
350  return false;
351 
352  // if it does not exist, create a empty one
353  if(!RealFileExists(state))
354  {
355  StateFile.Open(state, FileFd::WriteAtomic, FileFd::Extension);
356  StateFile.Close();
357  }
358 
359  // open it
360  if (!StateFile.Open(state, FileFd::ReadOnly, FileFd::Extension))
361  return _error->Error(_("Failed to open StateFile %s"),
362  state.c_str());
363 
365  if (OutFile.IsOpen() == false || OutFile.Failed() == true)
366  return _error->Error(_("Failed to write temporary StateFile %s"), state.c_str());
367 
368  // first merge with the existing sections
369  pkgTagFile tagfile(&StateFile);
370  pkgTagSection section;
371  std::set<string> pkgs_seen;
372  while(tagfile.Step(section)) {
373  string const pkgname = section.FindS("Package");
374  string pkgarch = section.FindS("Architecture");
375  if (pkgarch.empty() == true)
376  pkgarch = "native";
377  // Silently ignore unknown packages and packages with no actual
378  // version.
379  pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch);
380  if(pkg.end() || pkg.VersionList().end())
381  continue;
382  StateCache const &P = PkgState[pkg->ID];
383  bool newAuto = (P.Flags & Flag::Auto);
384  // reset to default (=manual) not installed or now-removed ones if requested
385  if (InstalledOnly && (
386  (pkg->CurrentVer == 0 && P.Mode != ModeInstall) ||
387  (pkg->CurrentVer != 0 && P.Mode == ModeDelete)))
388  newAuto = false;
389  if (newAuto == false)
390  {
391  // The section is obsolete if it contains no other tag
392  auto const count = section.Count();
393  if (count < 2 ||
394  (count == 2 && section.Exists("Auto-Installed")) ||
395  (count == 3 && section.Exists("Auto-Installed") && section.Exists("Architecture")))
396  {
397  if(debug_autoremove)
398  std::clog << "Drop obsolete section with " << count << " fields for " << APT::PrettyPkg(this, pkg) << std::endl;
399  continue;
400  }
401  }
402 
403  if(debug_autoremove)
404  std::clog << "Update existing AutoInstall to " << newAuto << " for " << APT::PrettyPkg(this, pkg) << std::endl;
405 
406  std::vector<pkgTagSection::Tag> rewrite;
407  rewrite.push_back(pkgTagSection::Tag::Rewrite("Architecture", pkg.Arch()));
408  rewrite.push_back(pkgTagSection::Tag::Rewrite("Auto-Installed", newAuto ? "1" : "0"));
409  section.Write(OutFile, NULL, rewrite);
410  if (OutFile.Write("\n", 1) == false)
411  return false;
412  pkgs_seen.insert(pkg.FullName());
413  }
414 
415  // then write the ones we have not seen yet
416  for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); ++pkg) {
417  StateCache const &P = PkgState[pkg->ID];
418  if(P.Flags & Flag::Auto) {
419  if (pkgs_seen.find(pkg.FullName()) != pkgs_seen.end()) {
420  if(debug_autoremove)
421  std::clog << "Skipping already written " << APT::PrettyPkg(this, pkg) << std::endl;
422  continue;
423  }
424  // skip not installed ones if requested
425  if (InstalledOnly && (
426  (pkg->CurrentVer == 0 && P.Mode != ModeInstall) ||
427  (pkg->CurrentVer != 0 && P.Mode == ModeDelete)))
428  continue;
429  if(debug_autoremove)
430  std::clog << "Writing new AutoInstall: " << APT::PrettyPkg(this, pkg) << std::endl;
431  std::string stanza = "Package: ";
432  stanza.append(pkg.Name())
433  .append("\nArchitecture: ").append(pkg.Arch())
434  .append("\nAuto-Installed: 1\n\n");
435  if (OutFile.Write(stanza.c_str(), stanza.length()) == false)
436  return false;
437  }
438  }
439  if (StateFile.Failed())
440  {
441  OutFile.OpFail();
442  return false;
443  }
444  if (OutFile.Close() == false)
445  return false;
446  chmod(state.c_str(), 0644);
447  return true;
448 }
449  /*}}}*/
450 // DepCache::CheckDep - Checks a single dependency /*{{{*/
451 // ---------------------------------------------------------------------
452 /* This first checks the dependency against the main target package and
453  then walks along the package provides list and checks if each provides
454  will be installed then checks the provides against the dep. Res will be
455  set to the package which was used to satisfy the dep. */
456 bool pkgDepCache::CheckDep(DepIterator const &Dep,int const Type,PkgIterator &Res)
457 {
458  Res = Dep.TargetPkg();
459 
460  /* Check simple depends. A depends -should- never self match but
461  we allow it anyhow because dpkg does. Technically it is a packaging
462  bug. Conflicts may never self match */
463  if (Dep.IsIgnorable(Res) == false)
464  {
465  // Check the base package
466  if (Type == NowVersion)
467  {
468  if (Res->CurrentVer != 0 && Dep.IsSatisfied(Res.CurrentVer()) == true)
469  return true;
470  }
471  else if (Type == InstallVersion)
472  {
473  if (PkgState[Res->ID].InstallVer != 0 &&
474  Dep.IsSatisfied(PkgState[Res->ID].InstVerIter(*this)) == true)
475  return true;
476  }
477  else if (Type == CandidateVersion)
478  if (PkgState[Res->ID].CandidateVer != 0 &&
479  Dep.IsSatisfied(PkgState[Res->ID].CandidateVerIter(*this)) == true)
480  return true;
481  }
482 
483  if (Dep->Type == Dep::Obsoletes)
484  return false;
485 
486  // Check the providing packages
487  PrvIterator P = Dep.TargetPkg().ProvidesList();
488  for (; P.end() != true; ++P)
489  {
490  if (Dep.IsIgnorable(P) == true)
491  continue;
492 
493  // Check if the provides is a hit
494  if (Type == NowVersion)
495  {
496  if (P.OwnerPkg().CurrentVer() != P.OwnerVer())
497  continue;
498  }
499  else if (Type == InstallVersion)
500  {
501  StateCache &State = PkgState[P.OwnerPkg()->ID];
502  if (State.InstallVer != (Version *)P.OwnerVer())
503  continue;
504  }
505  else if (Type == CandidateVersion)
506  {
507  StateCache &State = PkgState[P.OwnerPkg()->ID];
508  if (State.CandidateVer != (Version *)P.OwnerVer())
509  continue;
510  }
511 
512  // Compare the versions.
513  if (Dep.IsSatisfied(P) == true)
514  {
515  Res = P.OwnerPkg();
516  return true;
517  }
518  }
519 
520  return false;
521 }
522  /*}}}*/
523 // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
524 // ---------------------------------------------------------------------
525 /* Call with Inverse = true to perform the inverse operation */
526 void pkgDepCache::AddSizes(const PkgIterator &Pkg, bool const Inverse)
527 {
528  StateCache &P = PkgState[Pkg->ID];
529 
530  if (Pkg->VersionList == 0)
531  return;
532 
533  if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
534  P.Keep() == true)
535  return;
536 
537  // Compute the size data
538  if (P.NewInstall() == true)
539  {
540  if (Inverse == false) {
541  iUsrSize += P.InstVerIter(*this)->InstalledSize;
542  iDownloadSize += P.InstVerIter(*this)->Size;
543  } else {
544  iUsrSize -= P.InstVerIter(*this)->InstalledSize;
545  iDownloadSize -= P.InstVerIter(*this)->Size;
546  }
547  return;
548  }
549 
550  // Upgrading
551  if (Pkg->CurrentVer != 0 &&
552  (P.InstallVer != (Version *)Pkg.CurrentVer() ||
553  (P.iFlags & ReInstall) == ReInstall) && P.InstallVer != 0)
554  {
555  if (Inverse == false) {
556  iUsrSize -= Pkg.CurrentVer()->InstalledSize;
557  iUsrSize += P.InstVerIter(*this)->InstalledSize;
558  iDownloadSize += P.InstVerIter(*this)->Size;
559  } else {
560  iUsrSize -= P.InstVerIter(*this)->InstalledSize;
561  iUsrSize += Pkg.CurrentVer()->InstalledSize;
562  iDownloadSize -= P.InstVerIter(*this)->Size;
563  }
564  return;
565  }
566 
567  // Reinstall
568  if (Pkg.State() == pkgCache::PkgIterator::NeedsUnpack &&
569  P.Delete() == false)
570  {
571  if (Inverse == false)
572  iDownloadSize += P.InstVerIter(*this)->Size;
573  else
574  iDownloadSize -= P.InstVerIter(*this)->Size;
575  return;
576  }
577 
578  // Removing
579  if (Pkg->CurrentVer != 0 && P.InstallVer == 0)
580  {
581  if (Inverse == false)
582  iUsrSize -= Pkg.CurrentVer()->InstalledSize;
583  else
584  iUsrSize += Pkg.CurrentVer()->InstalledSize;
585  return;
586  }
587 }
588  /*}}}*/
589 // DepCache::AddStates - Add the package to the state counter /*{{{*/
590 // ---------------------------------------------------------------------
591 /* This routine is tricky to use, you must make sure that it is never
592  called twice for the same package. This means the Remove/Add section
593  should be as short as possible and not encompass any code that will
594  call Remove/Add itself. Remember, dependencies can be circular so
595  while processing a dep for Pkg it is possible that Add/Remove
596  will be called on Pkg */
597 void pkgDepCache::AddStates(const PkgIterator &Pkg, bool const Invert)
598 {
599  signed char const Add = (Invert == false) ? 1 : -1;
600  StateCache &State = PkgState[Pkg->ID];
601 
602  // The Package is broken (either minimal dep or policy dep)
603  if ((State.DepState & DepInstMin) != DepInstMin)
604  iBrokenCount += Add;
605  if ((State.DepState & DepInstPolicy) != DepInstPolicy)
606  iPolicyBrokenCount += Add;
607 
608  // Bad state
609  if (Pkg.State() != PkgIterator::NeedsNothing)
610  iBadCount += Add;
611 
612  // Not installed
613  if (Pkg->CurrentVer == 0)
614  {
615  if (State.Mode == ModeDelete &&
616  (State.iFlags & Purge) == Purge && Pkg.Purge() == false)
617  iDelCount += Add;
618 
619  if (State.Mode == ModeInstall)
620  iInstCount += Add;
621  return;
622  }
623 
624  // Installed, no upgrade
625  if (State.Status == 0)
626  {
627  if (State.Mode == ModeDelete)
628  iDelCount += Add;
629  else
630  if ((State.iFlags & ReInstall) == ReInstall)
631  iInstCount += Add;
632  return;
633  }
634 
635  // Alll 3 are possible
636  if (State.Mode == ModeDelete)
637  iDelCount += Add;
638  else if (State.Mode == ModeKeep)
639  iKeepCount += Add;
640  else if (State.Mode == ModeInstall)
641  iInstCount += Add;
642 }
643  /*}}}*/
644 // DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
645 // ---------------------------------------------------------------------
646 /* The or group results are stored in the last item of the or group. This
647  allows easy detection of the state of a whole or'd group. */
649 {
650  unsigned char Group = 0;
651  for (DepIterator D = V.DependsList(); D.end() != true; ++D)
652  {
653  // Build the dependency state.
654  unsigned char &State = DepState[D->ID];
655 
656  /* Invert for Conflicts. We have to do this twice to get the
657  right sense for a conflicts group */
658  if (D.IsNegative() == true)
659  State = ~~State;
660 
661  // Add to the group if we are within an or..
662  State &= 0x7;
663  Group |= State;
664  State |= Group << 3;
665  if ((D->CompareOp & Dep::Or) != Dep::Or)
666  Group = 0;
667 
668  // Invert for Conflicts
669  if (D.IsNegative() == true)
670  State = ~~State;
671  }
672 }
673  /*}}}*/
674 // DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
675 // ---------------------------------------------------------------------
676 /* This is used to run over a dependency list and determine the dep
677  state of the list, filtering it through both a Min check and a Policy
678  check. The return result will have SetMin/SetPolicy low if a check
679  fails. It uses the DepState cache for it's computations. */
680 unsigned char pkgDepCache::VersionState(DepIterator D, unsigned char const Check,
681  unsigned char const SetMin,
682  unsigned char const SetPolicy) const
683 {
684  unsigned char Dep = 0xFF;
685  while (D.end() != true)
686  {
687  // the last or-dependency has the state of all previous or'ed
688  DepIterator Start, End;
689  D.GlobOr(Start, End);
690  // ignore if we are called with Dep{Install,…} or DepG{Install,…}
691  // the later would be more correct, but the first is what we get
692  unsigned char const State = DepState[End->ID] | (DepState[End->ID] >> 3);
693 
694  // Minimum deps that must be satisfied to have a working package
695  if (Start.IsCritical() == true)
696  {
697  if ((State & Check) != Check)
698  return Dep &= ~(SetMin | SetPolicy);
699  }
700  // Policy deps that must be satisfied to install the package
701  else if (IsImportantDep(Start) == true &&
702  (State & Check) != Check)
703  Dep &= ~~SetPolicy;
704  }
705  return Dep;
706 }
707  /*}}}*/
708 // DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
709 // ---------------------------------------------------------------------
710 /* This is the main dependency computation bit. It computes the 3 main
711  results for a dependency: Now, Install and Candidate. Callers must
712  invert the result if dealing with conflicts. */
714 {
715  unsigned char State = 0;
716 
717  if (CheckDep(D,NowVersion) == true)
718  State |= DepNow;
719  if (CheckDep(D,InstallVersion) == true)
720  State |= DepInstall;
721  if (CheckDep(D,CandidateVersion) == true)
722  State |= DepCVer;
723 
724  return State;
725 }
726  /*}}}*/
727 // DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
728 // ---------------------------------------------------------------------
729 /* This determines the combined dependency representation of a package
730  for its two states now and install. This is done by using the pre-generated
731  dependency information. */
733 {
734  // Empty deps are always true
735  StateCache &State = PkgState[Pkg->ID];
736  State.DepState = 0xFF;
737 
738  // Check the Current state
739  if (Pkg->CurrentVer != 0)
740  {
741  DepIterator D = Pkg.CurrentVer().DependsList();
743  }
744 
745  /* Check the candidate state. We do not compare against the whole as
746  a candidate state but check the candidate version against the
747  install states */
748  if (State.CandidateVer != 0)
749  {
750  DepIterator D = State.CandidateVerIter(*this).DependsList();
752  }
753 
754  // Check target state which can only be current or installed
755  if (State.InstallVer != 0)
756  {
757  DepIterator D = State.InstVerIter(*this).DependsList();
759  }
760 }
761  /*}}}*/
762 // DepCache::Update - Figure out all the state information /*{{{*/
763 // ---------------------------------------------------------------------
764 /* This will figure out the state of all the packages and all the
765  dependencies based on the current policy. */
767 {
768  iUsrSize = 0;
769  iDownloadSize = 0;
770  iInstCount = 0;
771  iDelCount = 0;
772  iKeepCount = 0;
773  iBrokenCount = 0;
774  iPolicyBrokenCount = 0;
775  iBadCount = 0;
776 
777  int Done = 0;
778  for (PkgIterator I = PkgBegin(); I.end() != true; ++I, ++Done)
779  {
780  if (Prog != 0 && Done%20 == 0)
781  Prog->Progress(Done);
782  for (VerIterator V = I.VersionList(); V.end() != true; ++V)
783  {
784  unsigned char Group = 0;
785 
786  for (DepIterator D = V.DependsList(); D.end() != true; ++D)
787  {
788  // Build the dependency state.
789  unsigned char &State = DepState[D->ID];
790  State = DependencyState(D);
791 
792  // Add to the group if we are within an or..
793  Group |= State;
794  State |= Group << 3;
795  if ((D->CompareOp & Dep::Or) != Dep::Or)
796  Group = 0;
797 
798  // Invert for Conflicts
799  if (D.IsNegative() == true)
800  State = ~~State;
801  }
802  }
803 
804  // Compute the package dependency state and size additions
805  AddSizes(I);
806  UpdateVerState(I);
807  AddStates(I);
808  }
809  if (Prog != 0)
810  Prog->Progress(Done);
811 }
812 void pkgDepCache::Update(OpProgress * const Prog)
813 {
814  PerformDependencyPass(Prog);
815  readStateFile(Prog);
816 }
817  /*}}}*/
818 // DepCache::Update - Update the deps list of a package /*{{{*/
819 // ---------------------------------------------------------------------
820 /* This is a helper for update that only does the dep portion of the scan.
821  It is mainly meant to scan reverse dependencies. */
823 {
824  // Update the reverse deps
825  for (;D.end() != true; ++D)
826  {
827  unsigned char &State = DepState[D->ID];
828  State = DependencyState(D);
829 
830  // Invert for Conflicts
831  if (D.IsNegative() == true)
832  State = ~~State;
833 
834  RemoveStates(D.ParentPkg());
835  BuildGroupOrs(D.ParentVer());
836  UpdateVerState(D.ParentPkg());
837  AddStates(D.ParentPkg());
838  }
839 }
840  /*}}}*/
841 // DepCache::Update - Update the related deps of a package /*{{{*/
842 // ---------------------------------------------------------------------
843 /* This is called whenever the state of a package changes. It updates
844  all cached dependencies related to this package. */
846 {
847  // Recompute the dep of the package
848  RemoveStates(Pkg);
849  UpdateVerState(Pkg);
850  AddStates(Pkg);
851 
852  // Update the reverse deps
853  Update(Pkg.RevDependsList());
854 
855  // Update the provides map for the current ver
856  auto const CurVer = Pkg.CurrentVer();
857  if (not CurVer.end())
858  for (PrvIterator P = CurVer.ProvidesList(); not P.end(); ++P)
859  Update(P.ParentPkg().RevDependsList());
860 
861  // Update the provides map for the candidate ver
862  auto const CandVer = PkgState[Pkg->ID].CandidateVerIter(*this);
863  if (not CandVer.end() && CandVer != CurVer)
864  for (PrvIterator P = CandVer.ProvidesList(); not P.end(); ++P)
865  Update(P.ParentPkg().RevDependsList());
866 }
867  /*}}}*/
868 // DepCache::IsModeChangeOk - check if it is ok to change the mode /*{{{*/
869 // ---------------------------------------------------------------------
870 /* this is used by all Mark methods on the very first line to check sanity
871  and prevents mode changes for packages on hold for example.
872  If you want to check Mode specific stuff you can use the virtual public
873  Is<Mode>Ok methods instead */
874 static char const* PrintMode(char const mode)
875 {
876  switch (mode)
877  {
878  case pkgDepCache::ModeInstall: return "Install";
879  case pkgDepCache::ModeKeep: return "Keep";
880  case pkgDepCache::ModeDelete: return "Delete";
881  case pkgDepCache::ModeGarbage: return "Garbage";
882  default: return "UNKNOWN";
883  }
884 }
885 static bool IsModeChangeOk(pkgDepCache &Cache, pkgDepCache::ModeList const mode, pkgCache::PkgIterator const &Pkg,
886  unsigned long const Depth, bool const FromUser, bool const DebugMarker)
887 {
888  // we are not trying to hard…
889  if (unlikely(Depth > 100))
890  return false;
891 
892  // general sanity
893  if (unlikely(Pkg.end() == true || Pkg->VersionList == 0))
894  return false;
895 
896  // the user is always right
897  if (FromUser == true)
898  return true;
899 
900  auto &P = Cache[Pkg];
901  // not changing the mode is obviously also fine as we might want to call
902  // e.g. MarkInstall multiple times with different arguments for the same package
903  if (P.Mode == mode)
904  return true;
905 
906  // if previous state was set by user only user can reset it
908  {
909  if (unlikely(DebugMarker == true))
910  std::clog << OutputInDepth(Depth) << "Ignore Mark" << PrintMode(mode)
911  << " of " << APT::PrettyPkg(&Cache, Pkg) << " as its mode (" << PrintMode(P.Mode)
912  << ") is protected" << std::endl;
913  return false;
914  }
915  // enforce dpkg holds
916  else if (mode != pkgDepCache::ModeKeep && Pkg->SelectedState == pkgCache::State::Hold &&
917  _config->FindB("APT::Ignore-Hold",false) == false)
918  {
919  if (unlikely(DebugMarker == true))
920  std::clog << OutputInDepth(Depth) << "Hold prevents Mark" << PrintMode(mode)
921  << " of " << APT::PrettyPkg(&Cache, Pkg) << std::endl;
922  return false;
923  }
924 
925  return true;
926 }
927  /*}}}*/
928 // DepCache::MarkKeep - Put the package in the keep state /*{{{*/
929 // ---------------------------------------------------------------------
930 /* */
931 bool pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
932  unsigned long Depth)
933 {
934  if (not IsModeChangeOk(*this, ModeKeep, Pkg, Depth, FromUser, DebugMarker))
935  return false;
936 
937  /* Reject an attempt to keep a non-source broken installed package, those
938  must be upgraded */
939  if (Pkg.State() == PkgIterator::NeedsUnpack &&
940  Pkg.CurrentVer().Downloadable() == false)
941  return false;
942 
943  /* We changed the soft state all the time so the UI is a bit nicer
944  to use */
945  StateCache &P = PkgState[Pkg->ID];
946 
947  // Check that it is not already kept
948  if (P.Mode == ModeKeep)
949  return true;
950 
951  if (Soft == true)
952  P.iFlags |= AutoKept;
953  else
954  P.iFlags &= ~~AutoKept;
955 
956  ActionGroup group(*this);
957 
958 #if 0 // resetting the autoflag here means we lose the
959  // auto-mark information if a user selects a package for removal
960  // but changes his mind then and sets it for keep again
961  // - this makes sense as default when all Garbage dependencies
962  // are automatically marked for removal (as aptitude does).
963  // setting a package for keep then makes it no longer autoinstalled
964  // for all other use-case this action is rather surprising
965  if(FromUser && !P.Marked)
966  P.Flags &= ~~Flag::Auto;
967 #endif
968 
969  if (DebugMarker == true)
970  std::clog << OutputInDepth(Depth) << "MarkKeep " << APT::PrettyPkg(this, Pkg) << " FU=" << FromUser << std::endl;
971 
972  RemoveSizes(Pkg);
973  RemoveStates(Pkg);
974 
975  P.Mode = ModeKeep;
976  if (Pkg->CurrentVer == 0)
977  P.InstallVer = 0;
978  else
979  P.InstallVer = Pkg.CurrentVer();
980 
981  AddStates(Pkg);
982  Update(Pkg);
983  AddSizes(Pkg);
984 
985  return true;
986 }
987  /*}}}*/
988 // DepCache::MarkDelete - Put the package in the delete state /*{{{*/
989 // ---------------------------------------------------------------------
990 /* */
991 bool pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
992  unsigned long Depth, bool FromUser)
993 {
994  if (not IsModeChangeOk(*this, ModeDelete, Pkg, Depth, FromUser, DebugMarker))
995  return false;
996 
997  StateCache &P = PkgState[Pkg->ID];
998 
999  // Check that it is not already marked for delete
1000  if ((P.Mode == ModeDelete || P.InstallVer == 0) &&
1001  (Pkg.Purge() == true || rPurge == false))
1002  return true;
1003 
1004  // check if we are allowed to remove the package
1005  if (IsDeleteOk(Pkg,rPurge,Depth,FromUser) == false)
1006  return false;
1007 
1008  P.iFlags &= ~(AutoKept | Purge);
1009  if (rPurge == true)
1010  P.iFlags |= Purge;
1011 
1012  ActionGroup group(*this);
1013 
1014  if (FromUser == false)
1015  {
1016  VerIterator const PV = P.InstVerIter(*this);
1017  if (PV.end() == false)
1018  {
1019  // removed metapackages mark their dependencies as manual to prevent in "desktop depends browser, texteditor"
1020  // the removal of browser to suggest the removal of desktop and texteditor.
1021  // We ignore the auto-bit here as we can't deal with metapackage cascardes otherwise.
1022  // We do not check for or-groups here as we don't know which package takes care of
1023  // providing the feature the user likes e.g.: browser1 | browser2 | browser3
1024  // Temporary removals are effected by this as well, which is bad, but unlikely in practice
1025  bool const PinNeverMarkAutoSection = (PV->Section != 0 && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", PV.Section()));
1026  if (PinNeverMarkAutoSection)
1027  {
1028  for (DepIterator D = PV.DependsList(); D.end() != true; ++D)
1029  {
1030  if (D.IsMultiArchImplicit() == true || D.IsNegative() == true || IsImportantDep(D) == false)
1031  continue;
1032 
1033  pkgCacheFile CacheFile(this);
1035  for (auto const &V : verlist)
1036  {
1037  PkgIterator const DP = V.ParentPkg();
1038  if(DebugAutoInstall == true)
1039  std::clog << OutputInDepth(Depth) << "Setting " << DP.FullName(false) << " NOT as auto-installed (direct "
1040  << D.DepType() << " of " << Pkg.FullName(false) << " which is in APT::Never-MarkAuto-Sections)" << std::endl;
1041 
1042  MarkAuto(DP, false);
1043  }
1044  }
1045  }
1046  }
1047  }
1048 
1049  if (DebugMarker == true)
1050  std::clog << OutputInDepth(Depth) << (rPurge ? "MarkPurge " : "MarkDelete ") << APT::PrettyPkg(this, Pkg) << " FU=" << FromUser << std::endl;
1051 
1052  RemoveSizes(Pkg);
1053  RemoveStates(Pkg);
1054 
1055  if (Pkg->CurrentVer == 0 && (Pkg.Purge() == true || rPurge == false))
1056  P.Mode = ModeKeep;
1057  else
1058  P.Mode = ModeDelete;
1059  P.InstallVer = 0;
1060 
1061  AddStates(Pkg);
1062  Update(Pkg);
1063  AddSizes(Pkg);
1064 
1065  return true;
1066 }
1067  /*}}}*/
1068 // DepCache::IsDeleteOk - check if it is ok to remove this package /*{{{*/
1069 // ---------------------------------------------------------------------
1070 /* The default implementation tries to prevent deletion of install requests.
1071  dpkg holds are enforced by the private IsModeChangeOk */
1072 bool pkgDepCache::IsDeleteOk(PkgIterator const &Pkg,bool rPurge,
1073  unsigned long Depth, bool FromUser)
1074 {
1075  return IsDeleteOkProtectInstallRequests(Pkg, rPurge, Depth, FromUser);
1076 }
1078  bool const /*rPurge*/, unsigned long const Depth, bool const FromUser)
1079 {
1080  if (FromUser == false && Pkg->CurrentVer == 0)
1081  {
1082  StateCache &P = PkgState[Pkg->ID];
1083  if (P.InstallVer != 0 && P.Status == 2 && (P.Flags & Flag::Auto) != Flag::Auto)
1084  {
1085  if (DebugMarker == true)
1086  std::clog << OutputInDepth(Depth) << "Manual install request prevents MarkDelete of " << APT::PrettyPkg(this, Pkg) << std::endl;
1087  return false;
1088  }
1089  }
1090  return true;
1091 }
1092  /*}}}*/
1093 struct CompareProviders /*{{{*/
1094 {
1097  explicit CompareProviders(pkgDepCache const &pCache, pkgCache::DepIterator const &Dep) : Cache{pCache}, Pkg{Dep.TargetPkg()} {}
1099  {
1100  pkgCache::PkgIterator const A = AV.ParentPkg();
1101  pkgCache::PkgIterator const B = BV.ParentPkg();
1102  // Deal with protected first as if they don't work we usually have a problem
1103  if (Cache[A].Protect() != Cache[B].Protect())
1104  return Cache[A].Protect();
1105  // Prefer MA:same packages if other architectures for it are installed
1106  if ((AV->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same ||
1107  (BV->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
1108  {
1109  bool instA = false;
1110  if ((AV->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
1111  {
1112  pkgCache::GrpIterator Grp = A.Group();
1113  for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
1114  if (P->CurrentVer != 0)
1115  {
1116  instA = true;
1117  break;
1118  }
1119  }
1120  bool instB = false;
1121  if ((BV->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
1122  {
1123  pkgCache::GrpIterator Grp = B.Group();
1124  for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
1125  {
1126  if (P->CurrentVer != 0)
1127  {
1128  instB = true;
1129  break;
1130  }
1131  }
1132  }
1133  if (instA != instB)
1134  return instA;
1135  }
1136  if ((A->CurrentVer == 0 || B->CurrentVer == 0) && A->CurrentVer != B->CurrentVer)
1137  return A->CurrentVer != 0;
1138  // Prefer packages in the same group as the target; e.g. foo:i386, foo:amd64
1139  if (A->Group != B->Group)
1140  {
1141  if (A->Group == Pkg->Group && B->Group != Pkg->Group)
1142  return true;
1143  else if (B->Group == Pkg->Group && A->Group != Pkg->Group)
1144  return false;
1145  }
1146  // we like essentials
1147  if ((A->Flags & pkgCache::Flag::Essential) != (B->Flags & pkgCache::Flag::Essential))
1148  {
1150  return true;
1151  else if ((B->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
1152  return false;
1153  }
1154  if ((A->Flags & pkgCache::Flag::Important) != (B->Flags & pkgCache::Flag::Important))
1155  {
1157  return true;
1158  else if ((B->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
1159  return false;
1160  }
1161  // prefer native architecture
1162  if (strcmp(A.Arch(), B.Arch()) != 0)
1163  {
1164  if (strcmp(A.Arch(), A.Cache()->NativeArch()) == 0)
1165  return true;
1166  else if (strcmp(B.Arch(), B.Cache()->NativeArch()) == 0)
1167  return false;
1168  std::vector<std::string> archs = APT::Configuration::getArchitectures();
1169  for (std::vector<std::string>::const_iterator a = archs.begin(); a != archs.end(); ++a)
1170  if (*a == A.Arch())
1171  return true;
1172  else if (*a == B.Arch())
1173  return false;
1174  }
1175  // higher priority seems like a good idea
1176  if (AV->Priority != BV->Priority)
1177  return AV->Priority < BV->Priority;
1178  // unable to decide…
1179  return A->ID > B->ID;
1180  }
1181 };
1182  /*}}}*/
1183 bool pkgDepCache::MarkInstall_StateChange(pkgCache::PkgIterator const &Pkg, bool AutoInst, bool FromUser) /*{{{*/
1184 {
1185  bool AlwaysMarkAsAuto = _config->FindB("APT::Get::Mark-Auto", false) == true;
1186  auto &P = (*this)[Pkg];
1187  if (P.Protect() && P.InstallVer == P.CandidateVer)
1188  return true;
1189 
1190  P.iFlags &= ~pkgDepCache::AutoKept;
1191 
1192  /* Target the candidate version and remove the autoflag. We reset the
1193  autoflag below if this was called recursively. Otherwise the user
1194  should have the ability to de-auto a package by changing its state */
1195  RemoveSizes(Pkg);
1196  RemoveStates(Pkg);
1197 
1198  P.Mode = pkgDepCache::ModeInstall;
1199  P.InstallVer = P.CandidateVer;
1200 
1201  if(FromUser && !AlwaysMarkAsAuto)
1202  {
1203  // Set it to manual if it's a new install or already installed,
1204  // but only if its not marked by the autoremover (aptitude depend on this behavior)
1205  // or if we do automatic installation (aptitude never does it)
1206  if(P.Status == 2 || (Pkg->CurrentVer != 0 && (AutoInst == true || P.Marked == false)))
1207  P.Flags &= ~~pkgCache::Flag::Auto;
1208  }
1209  else
1210  {
1211  // Set it to auto if this is a new install.
1212  if(P.Status == 2)
1213  P.Flags |= pkgCache::Flag::Auto;
1214  }
1215  if (P.CandidateVer == (pkgCache::Version *)Pkg.CurrentVer())
1216  P.Mode = pkgDepCache::ModeKeep;
1217 
1218  AddStates(Pkg);
1219  Update(Pkg);
1220  AddSizes(Pkg);
1221  return true;
1222 }
1223  /*}}}*/
1224 static bool MarkInstall_DiscardCandidate(pkgDepCache &Cache, pkgCache::PkgIterator const &Pkg) /*{{{*/
1225 {
1226  auto &State = Cache[Pkg];
1227  State.CandidateVer = State.InstallVer;
1228  auto const oldStatus = State.Status;
1229  State.Update(Pkg, Cache);
1230  State.Status = oldStatus;
1231  return true;
1232 }
1233  /*}}}*/
1235 {
1236  StateCache &State = PkgState[Pkg->ID];
1237  if (State.Mode == ModeKeep && State.InstallVer == State.CandidateVer && State.CandidateVer == Pkg.CurrentVer())
1238  return true;
1239  RemoveSizes(Pkg);
1240  RemoveStates(Pkg);
1241  if (Pkg->CurrentVer != 0)
1242  State.InstallVer = Pkg.CurrentVer();
1243  else
1244  State.InstallVer = nullptr;
1245  State.Mode = ModeKeep;
1246  AddStates(Pkg);
1247  Update(Pkg);
1248  AddSizes(Pkg);
1249  return MarkInstall_DiscardCandidate(*this, Pkg);
1250 }
1251  /*}}}*/
1252 static bool MarkInstall_CollectDependencies(pkgDepCache const &Cache, pkgCache::VerIterator const &PV, std::vector<pkgCache::DepIterator> &toInstall, std::vector<pkgCache::DepIterator> &toRemove) /*{{{*/
1253 {
1254  auto const propagateProctected = Cache[PV.ParentPkg()].Protect();
1255  for (auto Dep = PV.DependsList(); not Dep.end();)
1256  {
1257  auto const Start = Dep;
1258  // check if an installed package satisfies the dependency (and get the extend of the or-group)
1259  bool foundSolution = false;
1260  for (bool LastOR = true; not Dep.end() && LastOR; ++Dep)
1261  {
1262  LastOR = (Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
1263  if ((Cache[Dep] & pkgDepCache::DepInstall) == pkgDepCache::DepInstall)
1264  foundSolution = true;
1265  }
1266  if (foundSolution && not propagateProctected)
1267  continue;
1268 
1269  /* Check if this dep should be consider for install.
1270  (Pre-)Depends, Conflicts and Breaks for sure.
1271  Recommends & Suggests depending on configuration */
1272  if (not Cache.IsImportantDep(Start))
1273  continue;
1274 
1275  if (Start.IsNegative())
1276  {
1277  if (Start->Type != pkgCache::Dep::Obsoletes)
1278  toRemove.push_back(Start);
1279  }
1280  else
1281  toInstall.push_back(Start);
1282  }
1283  return true;
1284 }
1285  /*}}}*/
1287 {
1288  pkgCacheFile CacheFile{&Cache};
1289  APT::VersionVector toUpgrade, toNewInstall;
1290  do
1291  {
1293  if (not sorted)
1294  {
1295  std::move(verlist.begin(), verlist.end(), std::back_inserter(toUpgrade));
1296  continue;
1297  }
1298  std::sort(verlist.begin(), verlist.end(), CompareProviders{Cache, Start});
1299  for (auto &&Ver : verlist)
1300  {
1301  auto P = Ver.ParentPkg();
1302  if (P->CurrentVer != 0)
1303  toUpgrade.emplace_back(std::move(Ver));
1304  else
1305  toNewInstall.emplace_back(std::move(Ver));
1306  }
1307  } while (Start++ != End);
1308  if (toUpgrade.empty())
1309  toUpgrade = std::move(toNewInstall);
1310  else
1311  std::move(toNewInstall.begin(), toNewInstall.end(), std::back_inserter(toUpgrade));
1312 
1313  if (not sorted)
1314  std::sort(toUpgrade.begin(), toUpgrade.end(), [](pkgCache::VerIterator const &A, pkgCache::VerIterator const &B) { return A->ID < B->ID; });
1315  toUpgrade.erase(std::unique(toUpgrade.begin(), toUpgrade.end()), toUpgrade.end());
1316 
1317  if (not End.IsNegative())
1318  toUpgrade.erase(std::remove_if(toUpgrade.begin(), toUpgrade.end(), [&Cache](pkgCache::VerIterator const &V) {
1319  auto const P = V.ParentPkg();
1320  auto const &State = Cache[P];
1321  return State.Protect() && (State.Delete() || (State.Keep() && P->CurrentVer == 0));
1322  }),
1323  toUpgrade.end());
1324 
1325  return toUpgrade;
1326 }
1327  /*}}}*/
1328 static bool MarkInstall_MarkDeleteForNotUpgradeable(pkgDepCache &Cache, bool const DebugAutoInstall, pkgCache::VerIterator const &PV, unsigned long const Depth, pkgCache::PkgIterator const &Pkg, bool const propagateProctected, APT::PackageVector &delayedRemove)/*{{{*/
1329 {
1330  auto &State = Cache[Pkg];
1331  if (not propagateProctected)
1332  {
1333  if (State.Delete())
1334  return true;
1335  if(DebugAutoInstall)
1336  std::clog << OutputInDepth(Depth) << " Delayed Removing: " << Pkg.FullName() << " as upgrade is not an option for " << PV.ParentPkg().FullName() << " (" << PV.VerStr() << ")\n";
1337  if (not IsModeChangeOk(Cache, pkgDepCache::ModeDelete, Pkg, Depth, false, DebugAutoInstall) ||
1338  not Cache.IsDeleteOk(Pkg, false, Depth, false))
1339  return false;
1340  delayedRemove.push_back(Pkg);
1341  return true;
1342  }
1343 
1344  if (not State.Delete())
1345  {
1346  if(DebugAutoInstall)
1347  std::clog << OutputInDepth(Depth) << " Removing: " << Pkg.FullName() << " as upgrade is not an option for " << PV.ParentPkg().FullName() << " (" << PV.VerStr() << ")\n";
1348  if (not Cache.MarkDelete(Pkg, false, Depth + 1, false))
1349  return false;
1350  }
1351  MarkInstall_DiscardCandidate(Cache, Pkg);
1352  Cache.MarkProtected(Pkg);
1353  return true;
1354 }
1355  /*}}}*/
1356 static bool MarkInstall_RemoveConflictsIfNotUpgradeable(pkgDepCache &Cache, bool const DebugAutoInstall, pkgCache::VerIterator const &PV, unsigned long Depth, std::vector<pkgCache::DepIterator> &toRemove, APT::PackageVector &toUpgrade, APT::PackageVector &delayedRemove, bool const propagateProctected, bool const FromUser) /*{{{*/
1357 {
1358  /* Negative dependencies have no or-group
1359  If the candidate is effected try to keep current and discard candidate
1360  If the current is effected try upgrading to candidate or remove it */
1361  bool failedToRemoveSomething = false;
1362  APT::PackageVector badCandidate;
1363  for (auto const &D : toRemove)
1364  {
1365  for (auto const &Ver : getAllPossibleSolutions(Cache, D, D, APT::CacheSetHelper::CANDIDATE, true))
1366  {
1367  auto const Pkg = Ver.ParentPkg();
1368  auto &State = Cache[Pkg];
1369  if (State.CandidateVer != Ver)
1370  continue;
1371  if (Pkg.CurrentVer() != Ver)
1372  {
1373  if (State.Install() && not Cache.MarkKeep(Pkg, false, false, Depth))
1374  {
1375  failedToRemoveSomething = true;
1376  if (not propagateProctected && not FromUser)
1377  break;
1378  }
1379  else if (propagateProctected)
1380  {
1381  MarkInstall_DiscardCandidate(Cache, Pkg);
1382  if (Pkg->CurrentVer == 0)
1383  Cache.MarkProtected(Pkg);
1384  }
1385  else
1386  badCandidate.push_back(Pkg);
1387  }
1388  else if (not MarkInstall_MarkDeleteForNotUpgradeable(Cache, DebugAutoInstall, PV, Depth, Pkg, propagateProctected, delayedRemove))
1389  {
1390  failedToRemoveSomething = true;
1391  if (not propagateProctected && not FromUser)
1392  break;
1393  }
1394  }
1395  if (failedToRemoveSomething && not propagateProctected && not FromUser)
1396  break;
1397  for (auto const &Ver : getAllPossibleSolutions(Cache, D, D, APT::CacheSetHelper::INSTALLED, true))
1398  {
1399  auto const Pkg = Ver.ParentPkg();
1400  auto &State = Cache[Pkg];
1401  if (State.CandidateVer != Ver && State.CandidateVer != nullptr &&
1402  std::find(badCandidate.cbegin(), badCandidate.cend(), Pkg) == badCandidate.end())
1403  toUpgrade.push_back(Pkg);
1404  else if (State.CandidateVer == Pkg.CurrentVer())
1405  ; // already done in the first loop above
1406  else if (not MarkInstall_MarkDeleteForNotUpgradeable(Cache, DebugAutoInstall, PV, Depth, Pkg, propagateProctected, delayedRemove))
1407  {
1408  failedToRemoveSomething = true;
1409  if (not propagateProctected && not FromUser)
1410  break;
1411  }
1412  }
1413  if (failedToRemoveSomething && not propagateProctected && not FromUser)
1414  break;
1415  }
1416  toRemove.clear();
1417  return not failedToRemoveSomething;
1418 }
1419  /*}}}*/
1420 static bool MarkInstall_UpgradeOrRemoveConflicts(pkgDepCache &Cache, bool const DebugAutoInstall, unsigned long Depth, bool const ForceImportantDeps, APT::PackageVector &toUpgrade, bool const propagateProctected, bool const FromUser) /*{{{*/
1421 {
1422  bool failedToRemoveSomething = false;
1423  for (auto const &InstPkg : toUpgrade)
1424  if (not Cache[InstPkg].Install() && not Cache.MarkInstall(InstPkg, true, Depth + 1, false, ForceImportantDeps))
1425  {
1426  if (DebugAutoInstall)
1427  std::clog << OutputInDepth(Depth) << " Removing: " << InstPkg.FullName() << " as upgrade is not possible\n";
1428  if (not Cache.MarkDelete(InstPkg, false, Depth + 1, false))
1429  {
1430  failedToRemoveSomething = true;
1431  if (not propagateProctected && not FromUser)
1432  break;
1433  }
1434  else if (propagateProctected)
1435  Cache.MarkProtected(InstPkg);
1436  }
1437  toUpgrade.clear();
1438  return not failedToRemoveSomething;
1439 }
1440  /*}}}*/
1441 static bool MarkInstall_InstallDependencies(pkgDepCache &Cache, bool const DebugAutoInstall, bool const DebugMarker, pkgCache::PkgIterator const &Pkg, unsigned long Depth, bool const ForceImportantDeps, std::vector<pkgCache::DepIterator> &toInstall, APT::PackageVector *const toMoveAuto, bool const propagateProctected, bool const FromUser) /*{{{*/
1442 {
1443  auto const IsSatisfiedByInstalled = [&](auto &D) { return (Cache[pkgCache::DepIterator{Cache, &D}] & pkgDepCache::DepInstall) == pkgDepCache::DepInstall; };
1444  bool failedToInstallSomething = false;
1445  for (auto &&Dep : toInstall)
1446  {
1447  auto const Copy = Dep;
1448  pkgCache::DepIterator Start, End;
1449  Dep.GlobOr(Start, End);
1450  bool foundSolution = std::any_of(Start, Dep, IsSatisfiedByInstalled);
1451  if (foundSolution && not propagateProctected)
1452  continue;
1453  bool const IsCriticalDep = Start.IsCritical();
1454  if (foundSolution)
1455  {
1456  // try propagating protected to this satisfied dependency
1457  if (not IsCriticalDep)
1458  continue;
1459  auto const possibleSolutions = getAllPossibleSolutions(Cache, Start, End, APT::CacheSetHelper::CANDANDINST, false);
1460  if (possibleSolutions.size() != 1)
1461  continue;
1462  auto const InstPkg = possibleSolutions.begin().ParentPkg();
1463  if (Cache[InstPkg].Protect())
1464  continue;
1465  Cache.MarkProtected(InstPkg);
1466  if (not Cache.MarkInstall(InstPkg, true, Depth + 1, false, ForceImportantDeps))
1467  failedToInstallSomething = true;
1468  continue;
1469  }
1470 
1471  /* Check if any ImportantDep() (but not Critical) were added
1472  * since we installed the package. Also check for deps that
1473  * were satisfied in the past: for instance, if a version
1474  * restriction in a Recommends was tightened, upgrading the
1475  * package should follow that Recommends rather than causing the
1476  * dependency to be removed. (bug #470115)
1477  */
1478  if (Pkg->CurrentVer != 0 && not ForceImportantDeps && not IsCriticalDep)
1479  {
1480  bool isNewImportantDep = true;
1481  bool isPreviouslySatisfiedImportantDep = false;
1482  for (pkgCache::DepIterator D = Pkg.CurrentVer().DependsList(); D.end() != true; ++D)
1483  {
1484  //FIXME: Should we handle or-group better here?
1485  // We do not check if the package we look for is part of the same or-group
1486  // we might find while searching, but could that really be a problem?
1487  if (D.IsCritical() || not Cache.IsImportantDep(D) ||
1488  Start.TargetPkg() != D.TargetPkg())
1489  continue;
1490 
1491  isNewImportantDep = false;
1492 
1493  while ((D->CompareOp & pkgCache::Dep::Or) != 0)
1494  ++D;
1495 
1496  isPreviouslySatisfiedImportantDep = ((Cache[D] & pkgDepCache::DepGNow) != 0);
1497  if (isPreviouslySatisfiedImportantDep)
1498  break;
1499  }
1500 
1501  if (isNewImportantDep)
1502  {
1503  if (DebugAutoInstall)
1504  std::clog << OutputInDepth(Depth) << "new important dependency: "
1505  << Start.TargetPkg().FullName() << '\n';
1506  }
1507  else if (isPreviouslySatisfiedImportantDep)
1508  {
1509  if (DebugAutoInstall)
1510  std::clog << OutputInDepth(Depth) << "previously satisfied important dependency on "
1511  << Start.TargetPkg().FullName() << '\n';
1512  }
1513  else
1514  {
1515  if (DebugAutoInstall)
1516  std::clog << OutputInDepth(Depth) << "ignore old unsatisfied important dependency on "
1517  << Start.TargetPkg().FullName() << '\n';
1518  continue;
1519  }
1520  }
1521 
1522  auto const possibleSolutions = getAllPossibleSolutions(Cache, Start, End, APT::CacheSetHelper::CANDIDATE, true);
1523  for (auto const &InstVer : possibleSolutions)
1524  {
1525  auto const InstPkg = InstVer.ParentPkg();
1526  if (Cache[InstPkg].CandidateVer != InstVer)
1527  continue;
1528  if (DebugAutoInstall)
1529  std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.FullName()
1530  << " as " << End.DepType() << " of " << Pkg.FullName() << '\n';
1531  if (propagateProctected && IsCriticalDep && possibleSolutions.size() == 1)
1532  {
1533  if (not Cache.MarkInstall(InstPkg, false, Depth + 1, false, ForceImportantDeps))
1534  continue;
1535  Cache.MarkProtected(InstPkg);
1536  }
1537  if (not Cache.MarkInstall(InstPkg, true, Depth + 1, false, ForceImportantDeps))
1538  continue;
1539 
1540  if (toMoveAuto != nullptr && InstPkg->CurrentVer == 0)
1541  toMoveAuto->push_back(InstPkg);
1542 
1543  foundSolution = true;
1544  break;
1545  }
1546  if (DebugMarker && not foundSolution)
1547  std::clog << OutputInDepth(Depth+1) << APT::PrettyDep(&Cache, Copy) << " can't be satisfied! (dep)\n";
1548  if (not foundSolution && IsCriticalDep)
1549  {
1550  failedToInstallSomething = true;
1551  if (not propagateProctected && not FromUser)
1552  break;
1553  }
1554  }
1555  toInstall.clear();
1556  return not failedToInstallSomething;
1557 }
1558  /*}}}*/
1559 // DepCache::MarkInstall - Put the package in the install state /*{{{*/
1560 bool pkgDepCache::MarkInstall(PkgIterator const &Pkg, bool AutoInst,
1561  unsigned long Depth, bool FromUser,
1562  bool ForceImportantDeps)
1563 {
1564  StateCache &P = PkgState[Pkg->ID];
1565  if (P.Protect() && P.Keep() && P.CandidateVer != nullptr && P.CandidateVer == Pkg.CurrentVer())
1566  ; // we are here to mark our dependencies as protected, no state is changed
1567  else if (not IsModeChangeOk(*this, ModeInstall, Pkg, Depth, FromUser, DebugMarker))
1568  return false;
1569 
1570 
1571  // See if there is even any possible installation candidate
1572  if (P.CandidateVer == 0)
1573  return false;
1574 
1575  // Check that it is not already marked for install and that it can be installed
1576  if (not P.Protect() && not P.InstPolicyBroken() && not P.InstBroken())
1577  {
1578  if (P.CandidateVer == Pkg.CurrentVer())
1579  {
1580  if (P.InstallVer == 0)
1581  return MarkKeep(Pkg, false, FromUser, Depth + 1);
1582  return true;
1583  }
1584  else if (P.Mode == ModeInstall)
1585  return true;
1586  }
1587 
1588  // check if we are allowed to install the package
1589  if (not IsInstallOk(Pkg, AutoInst, Depth, FromUser))
1590  return false;
1591 
1592  ActionGroup group(*this);
1593  if (FromUser && not MarkInstall_StateChange(Pkg, AutoInst, FromUser))
1594  return false;
1595 
1596  bool const AutoSolve = AutoInst && _config->Find("APT::Solver", "internal") == "internal";
1597  bool const failEarly = not P.Protect() && not FromUser;
1598  bool hasFailed = false;
1599 
1600  std::vector<pkgCache::DepIterator> toInstall, toRemove;
1601  APT::PackageVector toUpgrade, delayedRemove;
1602  if (AutoSolve)
1603  {
1604  VerIterator const PV = P.CandidateVerIter(*this);
1605  if (unlikely(PV.end()))
1606  return false;
1607  if (not MarkInstall_CollectDependencies(*this, PV, toInstall, toRemove))
1608  return false;
1609 
1610  if (not MarkInstall_RemoveConflictsIfNotUpgradeable(*this, DebugAutoInstall, PV, Depth, toRemove, toUpgrade, delayedRemove, P.Protect(), FromUser))
1611  {
1612  if (failEarly)
1613  return false;
1614  hasFailed = true;
1615  }
1616  }
1617 
1618  if (not FromUser && not MarkInstall_StateChange(Pkg, AutoInst, FromUser))
1619  return false;
1620 
1621  if (not AutoSolve)
1622  return not hasFailed;
1623 
1624  if (DebugMarker)
1625  std::clog << OutputInDepth(Depth) << "MarkInstall " << APT::PrettyPkg(this, Pkg) << " FU=" << FromUser << '\n';
1626 
1627  class ScopedProtected
1628  {
1630  bool const already;
1631 
1632  public:
1633  ScopedProtected(pkgDepCache::StateCache &p) : P{p}, already{P.Protect()}
1634  {
1635  if (not already)
1636  P.iFlags |= Protected;
1637  }
1638  ~~ScopedProtected()
1639  {
1640  if (not already)
1641  P.iFlags &= (~~Protected);
1642  }
1643  operator bool() noexcept { return already; }
1644  } propagateProctected{PkgState[Pkg->ID]};
1645 
1646  if (not MarkInstall_UpgradeOrRemoveConflicts(*this, DebugAutoInstall, Depth, ForceImportantDeps, toUpgrade, propagateProctected, FromUser))
1647  {
1648  if (failEarly)
1649  {
1651  return false;
1652  }
1653  hasFailed = true;
1654  }
1655 
1656  bool const MoveAutoBitToDependencies = [&]() {
1657  VerIterator const PV = P.InstVerIter(*this);
1658  if (unlikely(PV.end()))
1659  return false;
1660  if (PV->Section == 0 || (P.Flags & Flag::Auto) == Flag::Auto)
1661  return false;
1662  VerIterator const CurVer = Pkg.CurrentVer();
1663  if (not CurVer.end() && CurVer->Section != 0 && strcmp(CurVer.Section(), PV.Section()) != 0)
1664  {
1665  bool const CurVerInMoveSection = ConfigValueInSubTree("APT::Move-Autobit-Sections", CurVer.Section());
1666  bool const InstVerInMoveSection = ConfigValueInSubTree("APT::Move-Autobit-Sections", PV.Section());
1667  return (not CurVerInMoveSection && InstVerInMoveSection);
1668  }
1669  return false;
1670  }();
1671 
1672  APT::PackageVector toMoveAuto;
1673  if (not MarkInstall_InstallDependencies(*this, DebugAutoInstall, DebugMarker, Pkg, Depth, ForceImportantDeps, toInstall,
1674  MoveAutoBitToDependencies ? &toMoveAuto : nullptr, propagateProctected, FromUser))
1675  {
1676  if (failEarly)
1677  {
1679  return false;
1680  }
1681  hasFailed = true;
1682  }
1683 
1684  for (auto const &R : delayedRemove)
1685  {
1686  if (not MarkDelete(R, false, Depth, false))
1687  {
1688  if (failEarly)
1689  {
1691  return false;
1692  }
1693  hasFailed = true;
1694  }
1695  }
1696 
1697  if (MoveAutoBitToDependencies)
1698  {
1699  if (DebugAutoInstall)
1700  std::clog << OutputInDepth(Depth) << "Setting " << Pkg.FullName(false) << " as auto-installed, moving manual to its dependencies" << std::endl;
1701  MarkAuto(Pkg, true);
1702  for (auto const &InstPkg : toMoveAuto)
1703  {
1704  if (DebugAutoInstall)
1705  std::clog << OutputInDepth(Depth) << "Setting " << InstPkg.FullName(false) << " NOT as auto-installed (dependency"
1706  << " of " << Pkg.FullName(false) << " which is manual and in APT::Move-Autobit-Sections)\n";
1707  MarkAuto(InstPkg, false);
1708  }
1709  }
1710  return not hasFailed;
1711 }
1712  /*}}}*/
1713 // DepCache::IsInstallOk - check if it is ok to install this package /*{{{*/
1714 // ---------------------------------------------------------------------
1715 /* The default implementation checks if the installation of an M-A:same
1716  package would lead us into a version-screw and if so forbids it.
1717  dpkg holds are enforced by the private IsModeChangeOk */
1718 bool pkgDepCache::IsInstallOk(PkgIterator const &Pkg,bool AutoInst,
1719  unsigned long Depth, bool FromUser)
1720 {
1721  return IsInstallOkMultiArchSameVersionSynced(Pkg,AutoInst, Depth, FromUser) &&
1722  IsInstallOkDependenciesSatisfiableByCandidates(Pkg,AutoInst, Depth, FromUser);
1723 }
1725  bool const /*AutoInst*/, unsigned long const Depth, bool const FromUser)
1726 {
1727  if (FromUser == true) // as always: user is always right
1728  return true;
1729 
1730  // if we have checked before and it was okay, it will still be okay
1731  if (PkgState[Pkg->ID].Mode == ModeInstall &&
1732  PkgState[Pkg->ID].InstallVer == PkgState[Pkg->ID].CandidateVer)
1733  return true;
1734 
1735  // ignore packages with none-M-A:same candidates
1736  VerIterator const CandVer = PkgState[Pkg->ID].CandidateVerIter(*this);
1737  if (unlikely(CandVer.end() == true) || CandVer == Pkg.CurrentVer() ||
1738  (CandVer->MultiArch & pkgCache::Version::Same) != pkgCache::Version::Same)
1739  return true;
1740 
1741  GrpIterator const Grp = Pkg.Group();
1742  for (PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
1743  {
1744  // not installed or self-check: fine by definition
1745  if (P->CurrentVer == 0 || P == Pkg)
1746  continue;
1747 
1748  // not having a candidate or being in sync
1749  // (simple string-compare as stuff like '1' == '0:1-0' can't happen here)
1750  VerIterator CV = PkgState[P->ID].CandidateVerIter(*this);
1751  if (CV.end() == true || strcmp(CandVer.VerStr(), CV.VerStr()) == 0)
1752  continue;
1753 
1754  // packages losing M-A:same can be out-of-sync
1755  if ((CV->MultiArch & pkgCache::Version::Same) != pkgCache::Version::Same)
1756  continue;
1757 
1758  // not downloadable means the package is obsolete, so allow out-of-sync
1759  if (CV.Downloadable() == false)
1760  continue;
1761 
1762  PkgState[Pkg->ID].iFlags |= AutoKept;
1763  if (unlikely(DebugMarker == true))
1764  std::clog << OutputInDepth(Depth) << "Ignore MarkInstall of " << APT::PrettyPkg(this, Pkg)
1765  << " as it is not in sync with its M-A:same sibling " << APT::PrettyPkg(this, P)
1766  << " (" << CandVer.VerStr() << " != " << CV.VerStr() << ")" << std::endl;
1767  return false;
1768  }
1769 
1770  return true;
1771 }
1773  bool const AutoInst, unsigned long const Depth, bool const /*FromUser*/)
1774 {
1775  if (AutoInst == false)
1776  return true;
1777 
1778  VerIterator const CandVer = PkgState[Pkg->ID].CandidateVerIter(*this);
1779  if (unlikely(CandVer.end() == true) || CandVer == Pkg.CurrentVer())
1780  return true;
1781 
1782  for (DepIterator Dep = CandVer.DependsList(); Dep.end() != true;)
1783  {
1784  DepIterator Start = Dep;
1785  bool foundSolution = false;
1786  unsigned Ors = 0;
1787  // Is it possible to statisfy this dependency?
1788  for (bool LastOR = true; not Dep.end() && LastOR; ++Dep, ++Ors)
1789  {
1790  LastOR = (Dep->CompareOp & Dep::Or) == Dep::Or;
1791 
1792  if ((DepState[Dep->ID] & (DepInstall | DepCVer)) != 0)
1793  foundSolution = true;
1794  }
1795 
1796  if (foundSolution || not Start.IsCritical() || Start.IsNegative())
1797  continue;
1798 
1799  if (DebugAutoInstall == true)
1800  std::clog << OutputInDepth(Depth) << APT::PrettyDep(this, Start) << " can't be satisfied!" << std::endl;
1801 
1802  // the dependency is critical, but can't be installed, so discard the candidate
1803  // as the problemresolver will trip over it otherwise trying to install it (#735967)
1804  StateCache &State = PkgState[Pkg->ID];
1805  if (not State.Protect())
1806  {
1807  if (Pkg->CurrentVer != 0)
1808  SetCandidateVersion(Pkg.CurrentVer());
1809  else
1810  State.CandidateVer = nullptr;
1811  if (not State.Delete())
1812  {
1813  State.Mode = ModeKeep;
1814  State.Update(Pkg, *this);
1815  }
1816  }
1817  return false;
1818  }
1819 
1820  return true;
1821 }
1822  /*}}}*/
1823 // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
1824 // ---------------------------------------------------------------------
1825 /* */
1826 void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To)
1827 {
1828  if (unlikely(Pkg.end() == true))
1829  return;
1830 
1831  APT::PackageList pkglist;
1832  if (Pkg->CurrentVer != 0 &&
1833  (Pkg.CurrentVer()-> MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
1834  {
1835  pkgCache::GrpIterator Grp = Pkg.Group();
1836  for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
1837  {
1838  if (P->CurrentVer != 0)
1839  pkglist.insert(P);
1840  }
1841  }
1842  else
1843  pkglist.insert(Pkg);
1844 
1845  ActionGroup group(*this);
1846 
1847  for (APT::PackageList::const_iterator Pkg = pkglist.begin(); Pkg != pkglist.end(); ++Pkg)
1848  {
1849  RemoveSizes(Pkg);
1850  RemoveStates(Pkg);
1851 
1852  StateCache &P = PkgState[Pkg->ID];
1853  if (To == true)
1854  P.iFlags |= ReInstall;
1855  else
1856  P.iFlags &= ~~ReInstall;
1857 
1858  AddStates(Pkg);
1859  AddSizes(Pkg);
1860  }
1861 }
1862  /*}}}*/
1864 {
1865  return PkgState[Pkg->ID].CandidateVerIter(*this);
1866 }
1867  /*}}}*/
1868 // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
1869 // ---------------------------------------------------------------------
1870 /* */
1872 {
1873  pkgCache::PkgIterator Pkg = TargetVer.ParentPkg();
1874  StateCache &P = PkgState[Pkg->ID];
1875 
1876  if (P.CandidateVer == TargetVer)
1877  return;
1878 
1879  ActionGroup group(*this);
1880 
1881  RemoveSizes(Pkg);
1882  RemoveStates(Pkg);
1883 
1884  if (P.CandidateVer == P.InstallVer && P.Install() == true)
1885  P.InstallVer = (Version *)TargetVer;
1886  P.CandidateVer = (Version *)TargetVer;
1887  P.Update(Pkg,*this);
1888 
1889  AddStates(Pkg);
1890  Update(Pkg);
1891  AddSizes(Pkg);
1892 
1893 }
1894  /*}}}*/
1895 // DepCache::SetCandidateRelease - Change the candidate version /*{{{*/
1896 // ---------------------------------------------------------------------
1897 /* changes the candidate of a package and walks over all its dependencies
1898  to check if it needs to change the candidate of the dependency, too,
1899  to reach a installable versionstate */
1901  std::string const &TargetRel)
1902 {
1903  std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > Changed;
1904  return SetCandidateRelease(TargetVer, TargetRel, Changed);
1905 }
1907  std::string const &TargetRel,
1908  std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > &Changed)
1909 {
1910  ActionGroup group(*this);
1911  SetCandidateVersion(TargetVer);
1912 
1913  if (TargetRel == "installed" || TargetRel == "candidate") // both doesn't make sense in this context
1914  return true;
1915 
1916  pkgVersionMatch Match(TargetRel, pkgVersionMatch::Release);
1917  // save the position of the last element we will not undo - if we have to
1918  std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::iterator newChanged = --(Changed.end());
1919 
1920  for (pkgCache::DepIterator D = TargetVer.DependsList(); D.end() == false; ++D)
1921  {
1922  if (D->Type != pkgCache::Dep::PreDepends && D->Type != pkgCache::Dep::Depends &&
1923  ((D->Type != pkgCache::Dep::Recommends && D->Type != pkgCache::Dep::Suggests) ||
1924  IsImportantDep(D) == false))
1925  continue;
1926 
1927  // walk over an or-group and check if we need to do anything
1928  // for simpilicity no or-group is handled as a or-group including one dependency
1929  pkgCache::DepIterator Start = D;
1930  bool itsFine = false;
1931  for (bool stillOr = true; stillOr == true; ++Start)
1932  {
1933  stillOr = (Start->CompareOp & Dep::Or) == Dep::Or;
1934  pkgCache::PkgIterator const P = Start.TargetPkg();
1935  // virtual packages can't be a solution
1936  if (P.end() == true || (P->ProvidesList == 0 && P->VersionList == 0))
1937  continue;
1938  // if its already installed, check if this one is good enough
1939  pkgCache::VerIterator const Now = P.CurrentVer();
1940  if (Now.end() == false && Start.IsSatisfied(Now))
1941  {
1942  itsFine = true;
1943  break;
1944  }
1945  pkgCache::VerIterator const Cand = PkgState[P->ID].CandidateVerIter(*this);
1946  // no versioned dependency - but is it installable?
1947  if (Start.TargetVer() == 0 || Start.TargetVer()[0] == '\0')
1948  {
1949  // Check if one of the providers is installable
1950  if (P->ProvidesList != 0)
1951  {
1952  pkgCache::PrvIterator Prv = P.ProvidesList();
1953  for (; Prv.end() == false; ++Prv)
1954  {
1955  pkgCache::VerIterator const C = PkgState[Prv.OwnerPkg()->ID].CandidateVerIter(*this);
1956  if (C.end() == true || C != Prv.OwnerVer() ||
1958  continue;
1959  break;
1960  }
1961  if (Prv.end() == true)
1962  continue;
1963  }
1964  // no providers, so check if we have an installable candidate version
1965  else if (Cand.end() == true ||
1966  (VersionState(Cand.DependsList(), DepInstall, DepCandMin, DepCandPolicy) & DepCandMin) != DepCandMin)
1967  continue;
1968  itsFine = true;
1969  break;
1970  }
1971  if (Cand.end() == true)
1972  continue;
1973  // check if the current candidate is enough for the versioned dependency - and installable?
1974  if (Start.IsSatisfied(Cand) == true &&
1975  (VersionState(Cand.DependsList(), DepInstall, DepCandMin, DepCandPolicy) & DepCandMin) == DepCandMin)
1976  {
1977  itsFine = true;
1978  break;
1979  }
1980  }
1981 
1982  if (itsFine == true) {
1983  // something in the or-group was fine, skip all other members
1984  for (; (D->CompareOp & Dep::Or) == Dep::Or; ++D);
1985  continue;
1986  }
1987 
1988  // walk again over the or-group and check each if a candidate switch would help
1989  itsFine = false;
1990  for (bool stillOr = true; stillOr == true; ++D)
1991  {
1992  stillOr = (D->CompareOp & Dep::Or) == Dep::Or;
1993  // changing candidate will not help if the dependency is not versioned
1994  if (D.TargetVer() == 0 || D.TargetVer()[0] == '\0')
1995  {
1996  if (stillOr == true)
1997  continue;
1998  break;
1999  }
2000 
2002  if (TargetRel == "newest")
2003  V = D.TargetPkg().VersionList();
2004  else
2005  V = Match.Find(D.TargetPkg());
2006 
2007  // check if the version from this release could satisfy the dependency
2008  if (V.end() == true || D.IsSatisfied(V) == false)
2009  {
2010  if (stillOr == true)
2011  continue;
2012  break;
2013  }
2014 
2015  pkgCache::VerIterator oldCand = PkgState[D.TargetPkg()->ID].CandidateVerIter(*this);
2016  if (V == oldCand)
2017  {
2018  // Do we already touched this Version? If so, their versioned dependencies are okay, no need to check again
2019  for (std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::const_iterator c = Changed.begin();
2020  c != Changed.end(); ++c)
2021  {
2022  if (c->first->ParentPkg != V->ParentPkg)
2023  continue;
2024  itsFine = true;
2025  break;
2026  }
2027  }
2028 
2029  if (itsFine == false)
2030  {
2031  // change the candidate
2032  Changed.push_back(make_pair(V, TargetVer));
2033  if (SetCandidateRelease(V, TargetRel, Changed) == false)
2034  {
2035  if (stillOr == false)
2036  break;
2037  // undo the candidate changing
2038  SetCandidateVersion(oldCand);
2039  Changed.pop_back();
2040  continue;
2041  }
2042  itsFine = true;
2043  }
2044 
2045  // something in the or-group was fine, skip all other members
2046  for (; (D->CompareOp & Dep::Or) == Dep::Or; ++D);
2047  break;
2048  }
2049 
2050  if (itsFine == false && (D->Type == pkgCache::Dep::PreDepends || D->Type == pkgCache::Dep::Depends))
2051  {
2052  // undo all changes which aren't lead to a solution
2053  for (std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::const_iterator c = ++newChanged;
2054  c != Changed.end(); ++c)
2055  SetCandidateVersion(c->first);
2056  Changed.erase(newChanged, Changed.end());
2057  return false;
2058  }
2059  }
2060  return true;
2061 }
2062  /*}}}*/
2063 // DepCache::MarkAuto - set the Auto flag for a package /*{{{*/
2064 // ---------------------------------------------------------------------
2065 /* */
2066 void pkgDepCache::MarkAuto(const PkgIterator &Pkg, bool Auto)
2067 {
2068  StateCache &state = PkgState[Pkg->ID];
2069 
2070  ActionGroup group(*this);
2071 
2072  if(Auto)
2073  state.Flags |= Flag::Auto;
2074  else
2075  state.Flags &= ~~Flag::Auto;
2076 }
2077  /*}}}*/
2078 // StateCache::Update - Compute the various static display things /*{{{*/
2079 // ---------------------------------------------------------------------
2080 /* This is called whenever the Candidate version changes. */
2082 {
2083  // Some info
2085 
2086  // Use a null string or the version string
2087  if (Ver.end() == true)
2088  CandVersion = "";
2089  else
2090  CandVersion = Ver.VerStr();
2091 
2092  // Find the current version
2093  if (Pkg->CurrentVer != 0)
2094  CurVersion = Pkg.CurrentVer().VerStr();
2095  else
2096  CurVersion = "";
2097 
2098  // Figure out if its up or down or equal
2099  if (Pkg->CurrentVer == 0 || Pkg->VersionList == 0 || CandidateVer == 0)
2100  Status = 2;
2101  else
2102  Status = Ver.CompareVer(Pkg.CurrentVer());
2103 }
2104  /*}}}*/
2105 // Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
2106 // ---------------------------------------------------------------------
2107 /* The default just returns the highest available version that is not
2108  a source and automatic. */
2110 {
2111  /* Not source/not automatic versions cannot be a candidate version
2112  unless they are already installed */
2113  VerIterator Last;
2114 
2115  for (VerIterator I = Pkg.VersionList(); I.end() == false; ++I)
2116  {
2117  if (Pkg.CurrentVer() == I)
2118  return I;
2119 
2120  for (VerFileIterator J = I.FileList(); J.end() == false; ++J)
2121  {
2122  if (J.File().Flagged(Flag::NotSource))
2123  continue;
2124 
2125  /* Stash the highest version of a not-automatic source, we use it
2126  if there is nothing better */
2127  if (J.File().Flagged(Flag::NotAutomatic) ||
2128  J.File().Flagged(Flag::ButAutomaticUpgrades))
2129  {
2130  if (Last.end() == true)
2131  Last = I;
2132  continue;
2133  }
2134 
2135  return I;
2136  }
2137  }
2138 
2139  return Last;
2140 }
2141  /*}}}*/
2142 // Policy::IsImportantDep - True if the dependency is important /*{{{*/
2143 // ---------------------------------------------------------------------
2144 /* */
2146 {
2147  if(Dep.IsCritical())
2148  return true;
2149  else if(Dep->Type == pkgCache::Dep::Recommends)
2150  {
2151  if (InstallRecommends)
2152  return true;
2153  // we support a special mode to only install-recommends for certain
2154  // sections
2155  // FIXME: this is a meant as a temporary solution until the
2156  // recommends are cleaned up
2157  const char *sec = Dep.ParentVer().Section();
2158  if (sec && ConfigValueInSubTree("APT::Install-Recommends-Sections", sec))
2159  return true;
2160  }
2161  else if(Dep->Type == pkgCache::Dep::Suggests)
2162  return InstallSuggests;
2163 
2164  return false;
2165 }
2166  /*}}}*/
2167 // Policy::GetPriority - Get the priority of the package pin /*{{{*/
2169 { return 0; }
2170 APT_PURE signed short pkgDepCache::Policy::GetPriority(pkgCache::VerIterator const &/*Ver*/, bool /*ConsiderFiles*/)
2171 { return 0; }
2173 { return 0; }
2174  /*}}}*/
2176 {
2178  if (f->wasConstructedSuccessfully())
2179  return f;
2180  else
2181  {
2182  delete f;
2183  return NULL;
2184  }
2185 }
2186 
2188 {
2189  if (d->inRootSetFunc == nullptr)
2190  d->inRootSetFunc.reset(GetRootSetFunc());
2191  return d->inRootSetFunc.get();
2192 }
2193  /*}}}*/
2195 {
2196  return _config->FindB("APT::AutoRemove::RecommendsImportant", true);
2197 }
2198 
2200 {
2201  return _config->FindB("APT::AutoRemove::SuggestsImportant", true);
2202 }
2203 
2204 // pkgDepCache::MarkRequired - the main mark algorithm /*{{{*/
2206 {
2207  if (Pkg->CurrentVer == 0)
2208  {
2209  if (PkgState[Pkg->ID].Keep())
2210  return true;
2211  }
2212  else
2213  {
2214  if (PkgState[Pkg->ID].Delete())
2215  return true;
2216  }
2217  return false;
2218 }
2220 {
2221  if (_config->Find("APT::Solver", "internal") != "internal")
2222  return true;
2223 
2224  bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
2225 
2226  // init the states
2227  auto const PackagesCount = Head().PackageCount;
2228  for(auto i = decltype(PackagesCount){0}; i < PackagesCount; ++i)
2229  {
2230  PkgState[i].Marked = false;
2231  PkgState[i].Garbage = false;
2232  }
2233  if (debug_autoremove)
2234  for(PkgIterator p = PkgBegin(); !p.end(); ++p)
2235  if(PkgState[p->ID].Flags & Flag::Auto)
2236  std::clog << "AutoDep: " << p.FullName() << std::endl;
2237 
2238  bool const follow_recommends = MarkFollowsRecommends();
2239  bool const follow_suggests = MarkFollowsSuggests();
2240 
2241  // do the mark part, this is the core bit of the algorithm
2242  for (PkgIterator P = PkgBegin(); !P.end(); ++P)
2243  {
2244  if (PkgState[P->ID].Marked || IsPkgInBoringState(P, PkgState))
2245  continue;
2246 
2247  const char *reason = nullptr;
2248 
2249  if ((PkgState[P->ID].Flags & Flag::Auto) == 0)
2250  reason = "Manual-Installed";
2251  else if (P->Flags & Flag::Essential)
2252  reason = "Essential";
2253  else if (P->Flags & Flag::Important)
2254  reason = "Important";
2255  else if (P->CurrentVer != 0 && P.CurrentVer()->Priority == pkgCache::State::Required)
2256  reason = "Required";
2257  else if (userFunc.InRootSet(P))
2258  reason = "Blacklisted [APT::NeverAutoRemove]";
2259  else if (not IsModeChangeOk(*this, ModeGarbage, P, 0, false, DebugMarker))
2260  reason = "Hold";
2261  else
2262  continue;
2263 
2264  if (PkgState[P->ID].Install())
2265  MarkPackage(P, PkgState[P->ID].InstVerIter(*this),
2266  follow_recommends, follow_suggests, reason);
2267  else
2268  MarkPackage(P, P.CurrentVer(),
2269  follow_recommends, follow_suggests, reason);
2270  }
2271 
2272  return true;
2273 }
2274  /*}}}*/
2275 // MarkPackage - mark a single package in Mark-and-Sweep /*{{{*/
2277  const pkgCache::VerIterator &Ver,
2278  bool const &follow_recommends,
2279  bool const &follow_suggests,
2280  const char *reason)
2281 {
2282  {
2283  pkgDepCache::StateCache &state = PkgState[Pkg->ID];
2284  // if we are marked already we are done
2285  if(state.Marked || unlikely(Ver.end()))
2286  return;
2287  state.Marked=true;
2288  }
2289 
2290  if (IsPkgInBoringState(Pkg, PkgState))
2291  return;
2292 
2293  bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove", false);
2294  if(debug_autoremove)
2295  std::clog << "Marking: " << Pkg.FullName() << " " << Ver.VerStr()
2296  << " (" << reason << ")" << std::endl;
2297 
2298  for (auto D = Ver.DependsList(); D.end() == false; ++D)
2299  {
2300  auto const T = D.TargetPkg();
2301  if (PkgState[T->ID].Marked)
2302  continue;
2303 
2304  if (D->Type != Dep::Depends &&
2305  D->Type != Dep::PreDepends &&
2306  (follow_recommends == false || D->Type != Dep::Recommends) &&
2307  (follow_suggests == false || D->Type != Dep::Suggests))
2308  continue;
2309 
2310  // handle the virtual part first
2311  APT::VersionVector providers;
2312  for(auto Prv = T.ProvidesList(); Prv.end() == false; ++Prv)
2313  {
2314  auto PP = Prv.OwnerPkg();
2315  if (IsPkgInBoringState(PP, PkgState))
2316  continue;
2317 
2318  // we want to ignore provides from uninteresting versions
2319  auto const PV = (PkgState[PP->ID].Install()) ?
2320  PkgState[PP->ID].InstVerIter(*this) : PP.CurrentVer();
2321  if (unlikely(PV.end()) || PV != Prv.OwnerVer() || D.IsSatisfied(Prv) == false)
2322  continue;
2323 
2324  providers.emplace_back(PV);
2325  }
2326  if (providers.empty() == false)
2327  {
2328  // sort providers by source version so that only the latest versioned
2329  // binary package of a source package is marked instead of all
2330  std::sort(providers.begin(), providers.end(),
2331  [](pkgCache::VerIterator const &A, pkgCache::VerIterator const &B) {
2332  auto const nameret = strcmp(A.SourcePkgName(), B.SourcePkgName());
2333  if (nameret != 0)
2334  return nameret < 0;
2335  auto const verret = A.Cache()->VS->CmpVersion(A.SourceVerStr(), B.SourceVerStr());
2336  if (verret != 0)
2337  return verret > 0;
2338  return strcmp(A.ParentPkg().Name(), B.ParentPkg().Name()) < 0;
2339  });
2340  auto const prvsize = providers.size();
2341  providers.erase(std::unique(providers.begin(), providers.end(),
2342  [](pkgCache::VerIterator const &A, pkgCache::VerIterator const &B) {
2343  return strcmp(A.SourcePkgName(), B.SourcePkgName()) == 0 &&
2344  strcmp(A.SourceVerStr(), B.SourceVerStr()) != 0;
2345  }), providers.end());
2346  for (auto && PV: providers)
2347  {
2348  auto const PP = PV.ParentPkg();
2349  if (debug_autoremove)
2350  std::clog << "Following dep: " << APT::PrettyDep(this, D)
2351  << ", provided by " << PP.FullName() << " " << PV.VerStr()
2352  << " (" << providers.size() << "/" << prvsize << ")"<< std::endl;
2353  MarkPackage(PP, PV, follow_recommends, follow_suggests, "Provider");
2354  }
2355  }
2356 
2357  // now deal with the real part of the package
2358  if (IsPkgInBoringState(T, PkgState))
2359  continue;
2360 
2361  auto const TV = (PkgState[T->ID].Install()) ?
2362  PkgState[T->ID].InstVerIter(*this) : T.CurrentVer();
2363  if (unlikely(TV.end()) || D.IsSatisfied(TV) == false)
2364  continue;
2365 
2366  if (debug_autoremove)
2367  std::clog << "Following dep: " << APT::PrettyDep(this, D) << std::endl;
2368  MarkPackage(T, TV, follow_recommends, follow_suggests, "Dependency");
2369  }
2370 }
2371  /*}}}*/
2372 bool pkgDepCache::Sweep() /*{{{*/
2373 {
2374  bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
2375 
2376  // do the sweep
2377  for(PkgIterator p=PkgBegin(); !p.end(); ++p)
2378  {
2379  StateCache &state=PkgState[p->ID];
2380 
2381  // skip required packages
2382  if (!p.CurrentVer().end() &&
2383  (p.CurrentVer()->Priority == pkgCache::State::Required))
2384  continue;
2385 
2386  // if it is not marked and it is installed, it's garbage
2387  if(!state.Marked && (!p.CurrentVer().end() || state.Install()))
2388  {
2389  state.Garbage=true;
2390  if(debug_autoremove)
2391  std::clog << "Garbage: " << p.FullName() << std::endl;
2392  }
2393  }
2394 
2395  return true;
2396 }
2397  /*}}}*/
2398 // DepCache::MarkAndSweep /*{{{*/
2400 {
2401  return MarkRequired(rootFunc) && Sweep();
2402 }
2404 {
2406  if (f != NULL)
2407  return MarkAndSweep(*f);
2408  else
2409  return false;
2410 }
2411  /*}}}*/
static bool std::string const metaIndex const *const pkgAcqMetaClearSig *const pkgAcquire::Item *const I
return false
VerSelector
specifies which version(s) we want to refer to
Definition: cacheset.h:95
const_iterator begin() const
Definition: cacheset.h:371
void clear() APT_OVERRIDE
Definition: cacheset.h:362
bool insert(pkgCache::PkgIterator const &P) APT_OVERRIDE
Definition: cacheset.h:357
const_iterator end() const
Definition: cacheset.h:372
void push_back(const value_type &P)
Definition: cacheset.h:395
bool empty() const APT_OVERRIDE
Definition: cacheset.h:815
size_t size() const APT_OVERRIDE
Definition: cacheset.h:817
const_iterator begin() const
Definition: cacheset.h:825
static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D, CacheSetHelper::VerSelector const selector, CacheSetHelper &helper)
Definition: cacheset.h:947
const_iterator end() const
Definition: cacheset.h:826
iterator erase(iterator pos)
Definition: cacheset.h:822
bool wasConstructedSuccessfully() const
returns if the matcher setup was successful
const Item * Tree(const char *Name) const
std::string Find(const char *Name, const char *Default=0) const
bool FindB(const char *Name, bool const &Default=false) const
std::string FindDir(const char *Name, const char *Default=0) const
std::string FindFile(const char *Name, const char *Default=0) const
Returns true for packages matching a regular expression in APT::NeverAutoRemove.
Definition: depcache.cc:53
DefaultRootSetFunc2(pkgCache *cache)
Definition: depcache.cc:57
std::unique_ptr< APT::CacheFilter::Matcher > Kernels
Definition: depcache.cc:54
virtual ~DefaultRootSetFunc2()
Definition: depcache.cc:58
bool InRootSet(const pkgCache::PkgIterator &pkg) APT_OVERRIDE
Definition: depcache.cc:60
Definition: fileutl.h:39
bool IsOpen()
Definition: fileutl.h:150
@ Extension
Definition: fileutl.h:80
@ Atomic
Definition: fileutl.h:65
@ ReadWrite
Definition: fileutl.h:61
@ WriteAtomic
Definition: fileutl.h:74
@ ReadOnly
Definition: fileutl.h:59
bool Write(const void *From, unsigned long long Size)
Definition: fileutl.cc:2819
void OpFail()
Definition: fileutl.h:153
bool Failed()
Definition: fileutl.h:151
bool Open(std::string FileName, unsigned int const Mode, CompressMode Compress, unsigned long const AccessMode=0666)
Definition: fileutl.cc:2415
unsigned long long Size()
Definition: fileutl.cc:2967
bool Close()
Definition: fileutl.cc:2977
virtual void Done()
Definition: progress.h:60
void OverallProgress(unsigned long long Current, unsigned long long Total, unsigned long long Size, const std::string &Op)
Definition: progress.cc:55
void Progress(unsigned long long Current)
Definition: progress.cc:43
void SubProgress(unsigned long long SubTotal, const std::string &Op="", float const Percent=-1)
Definition: progress.cc:73
pkgCache::Dep Dep
Definition: pkgcache.h:841
pkgCache::VerFileIterator VerFileIterator
Definition: pkgcache.h:836
pkgCache::PrvIterator PrvIterator
Definition: pkgcache.h:833
pkgCache::PkgIterator PkgIterator
Definition: pkgcache.h:829
pkgCache::VerIterator VerIterator
Definition: pkgcache.h:830
pkgCache::DepIterator DepIterator
Definition: pkgcache.h:832
pkgCache::GrpIterator GrpIterator
Definition: pkgcache.h:828
Represents an active action group.
Definition: depcache.h:166
void release()
Clean up the action group before it is destroyed.
Definition: depcache.cc:90
pkgDepCache & cache
Definition: depcache.h:168
APT_HIDDEN ActionGroup(const ActionGroup &other)
virtual ~ActionGroup()
Destroy the action group.
Definition: depcache.cc:108
Returns true for packages matching a regular expression in APT::NeverAutoRemove.
Definition: depcache.h:203
An arbitrary predicate on packages.
Definition: depcache.h:67
virtual bool InRootSet(const pkgCache::PkgIterator &)
Definition: depcache.h:69
virtual signed short GetPriority(PkgIterator const &Pkg)
Definition: depcache.cc:2168
virtual bool IsImportantDep(DepIterator const &Dep) const
Definition: depcache.cc:2145
virtual VerIterator GetCandidateVer(PkgIterator const &Pkg)
Definition: depcache.cc:2109
unsigned long iDelCount
Definition: depcache.h:314
unsigned long iPolicyBrokenCount
Definition: depcache.h:317
APT_HIDDEN void MarkPackage(const pkgCache::PkgIterator &pkg, const pkgCache::VerIterator &ver, bool const &follow_recommends, bool const &follow_suggests, const char *reason)
Mark a single package and all its unmarked important dependencies during mark-and-sweep.
Definition: depcache.cc:2276
void RemoveStates(const PkgIterator &Pkg)
Definition: depcache.h:348
bool DebugMarker
Definition: depcache.h:320
virtual InRootSetFunc * GetRootSetFunc()
Definition: depcache.cc:2175
unsigned long iInstCount
Definition: depcache.h:313
pkgCache * Cache
Definition: depcache.h:305
unsigned long iKeepCount
Definition: depcache.h:315
bool MarkRequired(InRootSetFunc &rootFunc)
Update the Marked field of all packages.
Definition: depcache.cc:2219
unsigned char * DepState
Definition: depcache.h:307
unsigned long KeepCount()
Definition: depcache.h:495
void RemoveSizes(const PkgIterator &Pkg)
Definition: depcache.h:346
bool MarkKeep(PkgIterator const &Pkg, bool Soft=false, bool FromUser=true, unsigned long Depth=0)
Definition: depcache.cc:931
unsigned long iBadCount
Definition: depcache.h:318
unsigned long long iDownloadSize
Definition: depcache.h:312
void BuildGroupOrs(VerIterator const &V)
Definition: depcache.cc:648
APT_HIDDEN bool MarkInstall_StateChange(PkgIterator const &Pkg, bool AutoInst, bool FromUser)
Definition: depcache.cc:1183
void SetReInstall(PkgIterator const &Pkg, bool To)
Definition: depcache.cc:1826
pkgDepCache(pkgCache *const Cache, Policy *const Plcy=0)
Definition: depcache.cc:121
signed long long UsrSize()
Definition: depcache.h:492
virtual bool IsInstallOk(const PkgIterator &Pkg, bool AutoInst=true, unsigned long Depth=0, bool FromUser=true)
Definition: depcache.cc:1718
pkgCache::VerIterator GetCandidateVersion(pkgCache::PkgIterator const &Pkg)
Definition: depcache.cc:1863
void AddSizes(const PkgIterator &Pkg, bool const Invert=false)
Definition: depcache.cc:526
void MarkProtected(PkgIterator const &Pkg)
Definition: depcache.h:416
@ CandidateVersion
Definition: depcache.h:139
@ InstallVersion
Definition: depcache.h:139
void Update(DepIterator Dep)
Definition: depcache.cc:822
unsigned long BadCount()
Definition: depcache.h:499
unsigned long iBrokenCount
Definition: depcache.h:316
void MarkAuto(const PkgIterator &Pkg, bool Auto)
Definition: depcache.cc:2066
void SetCandidateVersion(VerIterator TargetVer)
Definition: depcache.cc:1871
virtual ~pkgDepCache()
Definition: depcache.cc:136
unsigned long InstCount()
Definition: depcache.h:496
APT_HIDDEN void PerformDependencyPass(OpProgress *const Prog)
Definition: depcache.cc:766
bool CheckConsistency(char const *const msgtag="")
Definition: depcache.cc:144
bool IsInstallOkDependenciesSatisfiableByCandidates(PkgIterator const &Pkg, bool const AutoInst, unsigned long const Depth, bool const FromUser)
Definition: depcache.cc:1772
virtual bool IsDeleteOk(const PkgIterator &Pkg, bool MarkPurge=false, unsigned long Depth=0, bool FromUser=true)
Definition: depcache.cc:1072
virtual bool MarkFollowsSuggests()
Definition: depcache.cc:2199
bool Sweep()
Set the StateCache::Garbage flag on all packages that should be removed.
Definition: depcache.cc:2372
InRootSetFunc * GetCachedRootSetFunc() APT_HIDDEN
Definition: depcache.cc:2187
void UpdateVerState(PkgIterator const &Pkg)
Definition: depcache.cc:732
bool MarkInstall(PkgIterator const &Pkg, bool AutoInst=true, unsigned long Depth=0, bool FromUser=true, bool ForceImportantDeps=false)
Definition: depcache.cc:1560
unsigned long DelCount()
Definition: depcache.h:494
bool SetCandidateRelease(pkgCache::VerIterator TargetVer, std::string const &TargetRel)
Definition: depcache.cc:1900
@ DepNowPolicy
Definition: depcache.h:132
@ DepInstPolicy
Definition: depcache.h:133
@ DepCandPolicy
Definition: depcache.h:134
bool readStateFile(OpProgress *const prog)
Definition: depcache.cc:285
PkgIterator PkgBegin()
Definition: depcache.h:356
signed long long iUsrSize
Definition: depcache.h:310
Policy * LocalPolicy
Definition: depcache.h:324
int group_level
Definition: depcache.h:298
pkgCache & GetCache()
Definition: depcache.h:361
bool CheckDep(DepIterator const &Dep, int const Type, PkgIterator &Res)
Definition: depcache.cc:456
bool MarkAndSweep()
Definition: depcache.cc:2403
unsigned char VersionState(DepIterator D, unsigned char const Check, unsigned char const SetMin, unsigned char const SetPolicy) const
Definition: depcache.cc:680
unsigned long BrokenCount()
Definition: depcache.h:497
bool Init(OpProgress *const Prog)
Definition: depcache.cc:229
bool MarkDelete(PkgIterator const &Pkg, bool MarkPurge=false, unsigned long Depth=0, bool FromUser=true)
Definition: depcache.cc:991
bool DebugAutoInstall
Definition: depcache.h:321
bool IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg, bool const AutoInst, unsigned long const Depth, bool const FromUser)
Definition: depcache.cc:1724
bool IsDeleteOkProtectInstallRequests(PkgIterator const &Pkg, bool const rPurge, unsigned long const Depth, bool const FromUser)
Definition: depcache.cc:1077
Policy * delLocalPolicy
Definition: depcache.h:323
APT_HIDDEN bool MarkInstall_DiscardInstall(PkgIterator const &Pkg)
Definition: depcache.cc:1234
unsigned long PolicyBrokenCount()
Definition: depcache.h:498
bool IsImportantDep(DepIterator Dep) const
Definition: depcache.h:364
void AddStates(const PkgIterator &Pkg, bool const Invert=false)
Definition: depcache.cc:597
StateCache * PkgState
Definition: depcache.h:306
virtual bool MarkFollowsRecommends()
Definition: depcache.cc:2194
bool writeStateFile(OpProgress *const prog, bool const InstalledOnly=true)
Definition: depcache.cc:340
unsigned char DependencyState(DepIterator const &D)
Definition: depcache.cc:713
Header & Head()
Definition: depcache.h:354
Private *const d
Definition: depcache.h:522
bool Step(pkgTagSection &Section)
Definition: tagfile.cc:204
std::string FindS(APT::StringView sv) const
Definition: tagfile.h:70
APT_HIDDEN bool Exists(Key key) const
bool Write(FileFd &File, char const *const *const Order=NULL, std::vector< Tag > const &Rewrite=std::vector< Tag >()) const
Definition: tagfile.cc:999
unsigned int Count() const
amount of Tags in the current section
Definition: tagfile.cc:942
APT_HIDDEN signed int FindI(Key key, signed long Default=0) const
Definition: tagfile.cc:776
unsigned long size() const
Definition: tagfile.h:122
pkgCache::VerIterator Find(pkgCache::PkgIterator Pkg)
Configuration * _config
static bool IsModeChangeOk(pkgDepCache &Cache, pkgDepCache::ModeList const mode, pkgCache::PkgIterator const &Pkg, unsigned long const Depth, bool const FromUser, bool const DebugMarker)
Definition: depcache.cc:885
static bool ConfigValueInSubTree(const char *SubTree, const char *needle)
Definition: depcache.cc:66
static bool MarkInstall_RemoveConflictsIfNotUpgradeable(pkgDepCache &Cache, bool const DebugAutoInstall, pkgCache::VerIterator const &PV, unsigned long Depth, std::vector< pkgCache::DepIterator > &toRemove, APT::PackageVector &toUpgrade, APT::PackageVector &delayedRemove, bool const propagateProctected, bool const FromUser)
Definition: depcache.cc:1356
static bool MarkInstall_CollectDependencies(pkgDepCache const &Cache, pkgCache::VerIterator const &PV, std::vector< pkgCache::DepIterator > &toInstall, std::vector< pkgCache::DepIterator > &toRemove)
Definition: depcache.cc:1252
static bool IsPkgInBoringState(pkgCache::PkgIterator const &Pkg, pkgDepCache::StateCache const *const PkgState)
Definition: depcache.cc:2205
static bool MarkInstall_MarkDeleteForNotUpgradeable(pkgDepCache &Cache, bool const DebugAutoInstall, pkgCache::VerIterator const &PV, unsigned long const Depth, pkgCache::PkgIterator const &Pkg, bool const propagateProctected, APT::PackageVector &delayedRemove)
Definition: depcache.cc:1328
static char const * PrintMode(char const mode)
Definition: depcache.cc:874
#define APT_CONSISTENCY_CHECK(VAR, STR)
static APT::VersionVector getAllPossibleSolutions(pkgDepCache &Cache, pkgCache::DepIterator Start, pkgCache::DepIterator const &End, APT::CacheSetHelper::VerSelector const selector, bool const sorted)
Definition: depcache.cc:1286
static bool MarkInstall_UpgradeOrRemoveConflicts(pkgDepCache &Cache, bool const DebugAutoInstall, unsigned long Depth, bool const ForceImportantDeps, APT::PackageVector &toUpgrade, bool const propagateProctected, bool const FromUser)
Definition: depcache.cc:1420
static bool MarkInstall_InstallDependencies(pkgDepCache &Cache, bool const DebugAutoInstall, bool const DebugMarker, pkgCache::PkgIterator const &Pkg, unsigned long Depth, bool const ForceImportantDeps, std::vector< pkgCache::DepIterator > &toInstall, APT::PackageVector *const toMoveAuto, bool const propagateProctected, bool const FromUser)
Definition: depcache.cc:1441
static bool MarkInstall_DiscardCandidate(pkgDepCache &Cache, pkgCache::PkgIterator const &Pkg)
Definition: depcache.cc:1224
string flNotFile(string File)
Definition: fileutl.cc:676
bool CreateAPTDirectoryIfNeeded(string const &Parent, string const &Path)
Ensure the existence of the given Path.
Definition: fileutl.cc:400
bool RealFileExists(string File)
Definition: fileutl.cc:337
#define APT_OVERRIDE
Definition: macros.h:111
#define APT_PURE
Definition: macros.h:56
APT_PUBLIC std::vector< std::string > const getArchitectures(bool const &Cached=true)
Returns a vector of Architectures we support.
std::unique_ptr< APT::CacheFilter::Matcher > GetProtectedKernelsFilter(pkgCache *cache, bool returnRemove)
Definition: algorithms.cc:1625
pkgCache - Structure definitions for the cache file
bool Policy(CommandLine &CmdL)
CompareProviders(pkgDepCache const &pCache, pkgCache::DepIterator const &Dep)
Definition: depcache.cc:1097
bool operator()(pkgCache::VerIterator const &AV, pkgCache::VerIterator const &BV)
Definition: depcache.cc:1098
pkgCache::PkgIterator const Pkg
Definition: depcache.cc:1096
pkgDepCache const & Cache
Definition: depcache.cc:1095
@ ButAutomaticUpgrades
Definition: pkgcache.h:203
map_id_t PackageCount
Definition: pkgcache.h:335
map_id_t DependsCount
Definition: pkgcache.h:338
information for a single version of a package
Definition: pkgcache.h:625
std::unique_ptr< InRootSetFunc > inRootSetFunc
Definition: depcache.cc:119
bool Install() const
Definition: depcache.h:260
unsigned char Mode
Definition: depcache.h:240
bool InstPolicyBroken() const
Definition: depcache.h:259
bool NewInstall() const
Definition: depcache.h:247
bool Garbage
true if this package is unused and should be removed.
Definition: depcache.h:236
VerIterator InstVerIter(pkgCache &Cache)
Definition: depcache.h:262
bool Delete() const
Definition: depcache.h:248
VerIterator CandidateVerIter(pkgCache &Cache)
Definition: depcache.h:264
bool Protect() const
Definition: depcache.h:251
bool Marked
true if this package can be reached from the root set.
Definition: depcache.h:228
unsigned short Flags
Definition: depcache.h:224
const char * CandVersion
Definition: depcache.h:214
void Update(PkgIterator Pkg, pkgCache &Cache)
Definition: depcache.cc:2081
signed char Status
Definition: depcache.h:239
unsigned short iFlags
Definition: depcache.h:225
bool InstBroken() const
Definition: depcache.h:258
const char * CurVersion
Definition: depcache.h:215
Version * CandidateVer
Definition: depcache.h:218
bool Keep() const
Definition: depcache.h:250
unsigned char DepState
Definition: depcache.h:241
static Tag Rewrite(std::string const &Name, std::string const &Data)
Definition: tagfile.cc:958
std::string OutputInDepth(const unsigned long Depth, const char *Separator)
Definition: strutl.cc:540