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)  

private-cacheset.cc
Go to the documentation of this file.
1 #include <config.h>
2 
4 #include <apt-pkg/cachefile.h>
5 #include <apt-pkg/cachefilter.h>
6 #include <apt-pkg/configuration.h>
7 #include <apt-pkg/depcache.h>
8 #include <apt-pkg/pkgcache.h>
9 #include <apt-pkg/policy.h>
10 #include <apt-pkg/progress.h>
11 #include <apt-pkg/strutl.h>
12 
14 
15 #include <stddef.h>
16 
17 #include <apti18n.h>
18 
21  OpProgress * const progress)
22 {
23  Matcher null_matcher = Matcher();
25  null_matcher, progress);
26 }
29  Matcher &matcher,
30  OpProgress * const progress)
31 {
32  pkgCache * const Cache = CacheFile.GetPkgCache();
33  if (unlikely(Cache == nullptr))
34  return false;
35  if (progress != nullptr)
36  progress->SubProgress(Cache->Head().PackageCount, _("Sorting"));
37 
38  pkgDepCache * const DepCache = CacheFile.GetDepCache();
39  if (unlikely(DepCache == nullptr))
40  return false;
41  APT::CacheSetHelper helper(false);
42 
43  int Done=0;
44 
45  bool const insertCurrentVer = _config->FindB("APT::Cmd::Installed", false);
46  bool const insertUpgradable = _config->FindB("APT::Cmd::Upgradable", false);
47  bool const insertManualInstalled = _config->FindB("APT::Cmd::Manual-Installed", false);
48 
49  for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
50  {
51  if (progress != NULL)
52  {
53  if (Done % 500 == 0)
54  progress->Progress(Done);
55  ++Done;
56  }
57 
58  // exclude virtual pkgs
59  if (P->VersionList == 0)
60  continue;
61 
62  if ((matcher)(P) == false)
63  continue;
64 
65  pkgDepCache::StateCache &state = (*DepCache)[P];
66  if (insertCurrentVer == true)
67  {
68  if (P->CurrentVer != 0)
70  }
71  else if (insertUpgradable == true)
72  {
73  if(P.CurrentVer() && state.Upgradable())
75  }
76  else if (insertManualInstalled == true)
77  {
78  if (P.CurrentVer() &&
79  ((*DepCache)[P].Flags & pkgCache::Flag::Auto) == false)
81  }
82  else
83  {
84  if (vci->FromPackage(vci, CacheFile, P, APT::CacheSetHelper::CANDIDATE, helper) == false)
85  {
86  // no candidate, this may happen for packages in
87  // dpkg "deinstall ok config-file" state - we pick the first ver
88  // (which should be the only one)
89  vci->insert(P.VersionList());
90  }
91  }
92  }
93  if (progress != NULL)
94  progress->Done();
95  return true;
96 }
97  /*}}}*/
98 
99 // CacheSetHelper saving virtual packages /*{{{*/
101  enum CacheSetHelper::VerSelector const select,
102  pkgCacheFile &Cache,
103  pkgCache::PkgIterator const &Pkg)
104 {
105  if (select == NEWEST || select == CANDIDATE || select == ALL)
106  virtualPkgs.insert(Pkg);
107  return CacheSetHelper::canNotGetVersion(select, Cache, Pkg);
108 }
110  enum CacheSetHelper::VerSelector const select,
112  pkgCacheFile &Cache,
113  pkgCache::PkgIterator const &Pkg)
114 {
115  if (select == NEWEST || select == CANDIDATE || select == ALL)
116  virtualPkgs.insert(Pkg);
117  return CacheSetHelper::canNotFindVersion(select, vci, Cache, Pkg);
118 }
119 static pkgCache::PkgIterator canNotFindPkgName_impl(pkgCacheFile &Cache, std::string const &str)
120 {
121  std::string pkg = str;
122  size_t const archfound = pkg.find_last_of(':');
123  std::string arch;
124  if (archfound != std::string::npos) {
125  arch = pkg.substr(archfound+1);
126  pkg.erase(archfound);
127  if (arch == "all" || arch == "native")
128  arch = _config->Find("APT::Architecture");
129  }
130 
131  // If we don't find 'foo:amd64' look for 'foo:amd64:any'.
132  // Note: we prepare for an error here as if foo:amd64 does not exist,
133  // but foo:amd64:any it means that this package is only referenced in a
134  // (architecture specific) dependency. We do not add to virtualPkgs directly
135  // as we can't decide from here which error message has to be printed.
136  // FIXME: This doesn't match 'barbarian' architectures
137  pkgCache::PkgIterator Pkg(Cache, 0);
138  std::vector<std::string> const archs = APT::Configuration::getArchitectures();
139  if (archfound == std::string::npos)
140  {
141  for (auto const &a : archs)
142  {
143  Pkg = Cache.GetPkgCache()->FindPkg(pkg + ':' + a, "any");
144  if (Pkg.end() == false && Pkg->ProvidesList != 0)
145  break;
146  }
147  if (Pkg.end() == true)
148  for (auto const &a : archs)
149  {
150  Pkg = Cache.GetPkgCache()->FindPkg(pkg + ':' + a, "any");
151  if (Pkg.end() == false)
152  break;
153  }
154  }
155  else
156  {
157  Pkg = Cache.GetPkgCache()->FindPkg(pkg + ':' + arch, "any");
158  if (Pkg.end() == true)
159  {
161  for (auto const &a : archs)
162  {
163  if (pams(a.c_str()) == false)
164  continue;
165  Pkg = Cache.GetPkgCache()->FindPkg(pkg + ':' + a, "any");
166  if (Pkg.end() == false)
167  break;
168  }
169  }
170  }
171  return Pkg;
172 }
174 {
175  pkgCache::PkgIterator const Pkg = canNotFindPkgName_impl(Cache, str);
176  if (Pkg.end())
177  return APT::CacheSetHelper::canNotFindPkgName(Cache, str);
178  return Pkg;
179 }
181  CacheSetHelper{ShowErrors, ErrorType}
182 {}
183  /*}}}*/
184 
185 // CacheSetHelperAPTGet - responsible for message telling from the CacheSets/*{{{*/
187  APT::CacheSetHelper{true}, out(pout)
188 {
189  explicitlyNamed = true;
190 }
192  std::string const &pattern)
193 {
194  switch (select)
195  {
196  case REGEX:
197  showRegExSelection(pkg, pattern);
198  break;
199  case TASK:
200  showTaskSelection(pkg, pattern);
201  break;
202  case FNMATCH:
203  showFnmatchSelection(pkg, pattern);
204  break;
205  default:
206  APT::CacheSetHelper::showPackageSelection(pkg, select, pattern);
207  break;
208  }
209 }
210 void CacheSetHelperAPTGet::showTaskSelection(pkgCache::PkgIterator const &Pkg, std::string const &pattern)
211 {
212  ioprintf(out, _("Note, selecting '%s' for task '%s'\n"),
213  Pkg.FullName(true).c_str(), pattern.c_str());
214  explicitlyNamed = false;
215 }
216 void CacheSetHelperAPTGet::showFnmatchSelection(pkgCache::PkgIterator const &Pkg, std::string const &pattern)
217 {
218  ioprintf(out, _("Note, selecting '%s' for glob '%s'\n"),
219  Pkg.FullName(true).c_str(), pattern.c_str());
220  explicitlyNamed = false;
221 }
222 void CacheSetHelperAPTGet::showRegExSelection(pkgCache::PkgIterator const &Pkg, std::string const &pattern)
223 {
224  ioprintf(out, _("Note, selecting '%s' for regex '%s'\n"),
225  Pkg.FullName(true).c_str(), pattern.c_str());
226  explicitlyNamed = false;
227 }
229  pkgCache::VerIterator const &Ver, enum VerSelector const select, std::string const &pattern)
230 {
231  switch (select)
232  {
233  case RELEASE:
234  case VERSIONNUMBER:
235  if (pattern == Ver.VerStr())
236  return;
237  selectedByRelease.push_back(make_pair(Ver, pattern));
238  break;
239  default:
240  return APT::CacheSetHelper::showVersionSelection(Pkg, Ver, select, pattern);
241  }
242 }
243 
245 {
246  if (virtualPkgs.empty() == true)
247  return true;
249  Pkg != virtualPkgs.end(); ++Pkg) {
250  if (Pkg->ProvidesList != 0) {
251  ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
252  Pkg.FullName(true).c_str());
253 
254  pkgCache::PrvIterator I = Pkg.ProvidesList();
255  unsigned short provider = 0;
256  for (; I.end() == false; ++I) {
257  pkgCache::PkgIterator const OPkg = I.OwnerPkg();
258 
259  if (Cache[OPkg].CandidateVerIter(Cache) == I.OwnerVer())
260  {
261  c1out << " " << OPkg.FullName(true) << " " << I.OwnerVer().VerStr();
262  if (Cache[OPkg].Install() == true && Cache[OPkg].NewInstall() == false)
263  c1out << _(" [Installed]");
264  c1out << std::endl;
265  ++provider;
266  }
267  }
268  // if we found no candidate which provide this package, show non-candidates
269  if (provider == 0)
270  for (I = Pkg.ProvidesList(); I.end() == false; ++I)
271  c1out << " " << I.OwnerPkg().FullName(true) << " " << I.OwnerVer().VerStr()
272  << _(" [Not candidate version]") << std::endl;
273  else
274  out << _("You should explicitly select one to install.") << std::endl;
275  } else {
276  ioprintf(c1out,
277  _("Package %s is not available, but is referred to by another package.\n"
278  "This may mean that the package is missing, has been obsoleted, or\n"
279  "is only available from another source\n"),Pkg.FullName(true).c_str());
280 
281  std::vector<bool> Seen(Cache.GetPkgCache()->Head().PackageCount, false);
282  APT::PackageList pkglist;
283  for (pkgCache::DepIterator Dep = Pkg.RevDependsList();
284  Dep.end() == false; ++Dep) {
285  if (Dep->Type != pkgCache::Dep::Replaces)
286  continue;
287  pkgCache::PkgIterator const DP = Dep.ParentPkg();
288  if (Seen[DP->ID] == true)
289  continue;
290  Seen[DP->ID] = true;
291  pkglist.insert(DP);
292  }
293  ShowList(c1out, _("However the following packages replace it:"), pkglist,
295  }
296  c1out << std::endl;
297  }
298  return false;
299 }
301 {
302  switch (select)
303  {
304  case NEWEST:
305  return canNotFindNewestVer(Cache, Pkg);
306  case CANDIDATE:
307  return canNotFindCandidateVer(Cache, Pkg);
308  default:
309  return APT::CacheSetHelper::canNotGetVersion(select, Cache, Pkg);
310  }
311 }
313 {
314  switch (select)
315  {
316  case NEWEST:
317  canNotFindNewestVer(Cache, Pkg);
318  break;
319  case CANDIDATE:
320  canNotFindCandidateVer(Cache, Pkg);
321  break;
322  default:
323  return APT::CacheSetHelper::canNotFindVersion(select, vci, Cache, Pkg);
324  }
325 }
326 
328 {
329  APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, CacheSetHelper::CANDIDATE);
330  if (verset.empty() == false)
331  return *(verset.begin());
332  else if (ShowError == true) {
333  _error->Error(_("Package '%s' has no installation candidate"),Pkg.FullName(true).c_str());
334  virtualPkgs.insert(Pkg);
335  }
336  return pkgCache::VerIterator(Cache, 0);
337 }
339 {
340  if (Pkg->ProvidesList != 0)
341  {
342  APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, CacheSetHelper::NEWEST);
343  if (verset.empty() == false)
344  return *(verset.begin());
345  if (ShowError == true)
346  ioprintf(out, _("Virtual packages like '%s' can't be removed\n"), Pkg.FullName(true).c_str());
347  }
348  else
349  {
350  pkgCache::GrpIterator Grp = Pkg.Group();
351  pkgCache::PkgIterator P = Grp.PackageList();
352  for (; P.end() != true; P = Grp.NextPkg(P))
353  {
354  if (P == Pkg)
355  continue;
356  if (P->CurrentVer != 0) {
357  // TRANSLATORS: Note, this is not an interactive question
358  ioprintf(c1out,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
359  Pkg.FullName(true).c_str(), P.FullName(true).c_str());
360  break;
361  }
362  }
363  if (P.end() == true)
364  ioprintf(c1out,_("Package '%s' is not installed, so not removed\n"),Pkg.FullName(true).c_str());
365  }
366  return pkgCache::VerIterator(Cache, 0);
367 }
369  CacheSetHelper::VerSelector const select)
370 {
371  /* This is a pure virtual package and there is a single available
372  candidate providing it. */
373  if (unlikely(Cache[Pkg].CandidateVer != 0) || Pkg->ProvidesList == 0)
374  return APT::VersionSet();
375 
377  bool found_one = false;
378  for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; ++P) {
379  pkgCache::VerIterator const PVer = P.OwnerVer();
380  pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
381 
382  /* Ignore versions that are not a candidate. */
383  if (Cache[PPkg].CandidateVer != PVer)
384  continue;
385 
386  if (found_one == false) {
387  Prov = PPkg;
388  found_one = true;
389  } else if (PPkg != Prov) {
390  // same group, so it's a foreign package
391  if (PPkg->Group == Prov->Group) {
392  // do we already have the requested arch?
393  if (strcmp(Pkg.Arch(), Prov.Arch()) == 0 ||
394  strcmp(Prov.Arch(), "all") == 0 ||
395  unlikely(strcmp(PPkg.Arch(), Prov.Arch()) == 0)) // packages have only on candidate, but just to be sure
396  continue;
397  // see which architecture we prefer more and switch to it
398  std::vector<std::string> archs = APT::Configuration::getArchitectures();
399  if (std::find(archs.begin(), archs.end(), PPkg.Arch()) < std::find(archs.begin(), archs.end(), Prov.Arch()))
400  Prov = PPkg;
401  continue;
402  }
403  found_one = false; // we found at least two
404  break;
405  }
406  }
407 
408  if (found_one == true) {
409  ioprintf(out, _("Note, selecting '%s' instead of '%s'\n"),
410  Prov.FullName(true).c_str(), Pkg.FullName(true).c_str());
411  return APT::VersionSet::FromPackage(Cache, Prov, select, *this);
412  }
413  return APT::VersionSet();
414 }
416 {
418  if (Pkg.end())
419  {
420  Pkg = APT::CacheSetHelper::canNotFindPkgName(Cache, str);
421  if (Pkg.end() && ShowError)
422  {
423  notFound.insert(str);
424  }
425  }
426  return Pkg;
427 }
428  /*}}}*/
static bool std::string const metaIndex const *const pkgAcqMetaClearSig *const pkgAcquire::Item *const I
VerSelector
specifies which version(s) we want to refer to
Definition: cacheset.h:95
virtual void showVersionSelection(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const &Ver, enum VerSelector const select, std::string const &pattern)
be notified about the version being selected via pattern
Definition: cacheset.cc:851
virtual void showPackageSelection(pkgCache::PkgIterator const &pkg, PkgSelector const select, std::string const &pattern)
be notified about the package being selected via pattern
Definition: cacheset.cc:816
virtual void canNotFindVersion(enum VerSelector const select, VersionContainerInterface *const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg)
be notified if a version can't be found for a package
Definition: cacheset.cc:721
virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str)
Definition: cacheset.cc:713
virtual pkgCache::VerIterator canNotGetVersion(enum VerSelector const select, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg)
Definition: cacheset.cc:758
bool empty() const APT_OVERRIDE
Definition: cacheset.h:361
const_iterator begin() const
Definition: cacheset.h:371
bool insert(pkgCache::PkgIterator const &P) APT_OVERRIDE
Definition: cacheset.h:357
const_iterator end() const
Definition: cacheset.h:372
static bool FromPackage(VersionContainerInterface *const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &P, CacheSetHelper::VerSelector const fallback, CacheSetHelper &helper)
Definition: cacheset.cc:516
virtual bool insert(pkgCache::VerIterator const &V)=0
bool empty() const APT_OVERRIDE
Definition: cacheset.h:815
static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P, CacheSetHelper::VerSelector const fallback, CacheSetHelper &helper)
returns all versions specified for the package
Definition: cacheset.h:907
const_iterator begin() const
Definition: cacheset.h:825
bool explicitlyNamed
were things like Task or RegEx used to select packages?
void showFnmatchSelection(pkgCache::PkgIterator const &Pkg, std::string const &pattern)
std::set< std::string > notFound
void showTaskSelection(pkgCache::PkgIterator const &Pkg, std::string const &pattern)
void showRegExSelection(pkgCache::PkgIterator const &Pkg, std::string const &pattern)
void showVersionSelection(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const &Ver, enum VerSelector const select, std::string const &pattern) APT_OVERRIDE
be notified about the version being selected via pattern
void canNotFindVersion(enum VerSelector const select, APT::VersionContainerInterface *const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) APT_OVERRIDE
be notified if a version can't be found for a package
APT::VersionSet tryVirtualPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg, CacheSetHelper::VerSelector const select)
virtual void showPackageSelection(pkgCache::PkgIterator const &Pkg, enum PkgSelector const select, std::string const &pattern) APT_OVERRIDE
be notified about the package being selected via pattern
pkgCache::VerIterator canNotGetVersion(enum VerSelector const select, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) APT_OVERRIDE
pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg)
virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str) APT_OVERRIDE
pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg)
CacheSetHelperAPTGet(std::ostream &out)
std::ostream & out
stream message should be printed to
bool showVirtualPackageErrors(pkgCacheFile &Cache)
APT::PackageSet virtualPkgs
std::list< std::pair< pkgCache::VerIterator, std::string > > selectedByRelease
virtual void canNotFindVersion(enum CacheSetHelper::VerSelector const select, APT::VersionContainerInterface *vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) APT_OVERRIDE
virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str) APT_OVERRIDE
CacheSetHelperVirtuals(bool const ShowErrors=true, GlobalError::MsgType const &ErrorType=GlobalError::NOTICE)
APT::PackageSet virtualPkgs
virtual pkgCache::VerIterator canNotGetVersion(enum CacheSetHelper::VerSelector const select, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) APT_OVERRIDE
std::string Find(const char *Name, const char *Default=0) const
bool FindB(const char *Name, bool const &Default=false) const
MsgType
a message can have one of following severity
Definition: error.h:55
virtual void Done()
Definition: progress.h:60
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
pkgDepCache * GetDepCache()
Definition: cachefile.h:74
pkgCache * GetPkgCache()
Definition: cachefile.h:73
Configuration * _config
APT_PUBLIC std::vector< std::string > const getArchitectures(bool const &Cached=true)
Returns a vector of Architectures we support.
VersionContainer< std::set< pkgCache::VerIterator > > VersionSet
Definition: cacheset.h:1058
pkgCache - Structure definitions for the cache file
bool GetLocalitySortedVersionSet(pkgCacheFile &CacheFile, APT::VersionContainerInterface *const vci, OpProgress *const progress)
static pkgCache::PkgIterator canNotFindPkgName_impl(pkgCacheFile &Cache, std::string const &str)
bool AlwaysTrue(pkgCache::PkgIterator const &)
std::string PrettyFullName(pkgCache::PkgIterator const &Pkg)
std::string EmptyString(pkgCache::PkgIterator const &)
APT_PUBLIC std::ostream c1out
bool ShowList(std::ostream &out, std::string const &Title, Container const &cont, PredicateC Predicate, DisplayP PkgDisplay, DisplayV VerboseDisplay)
bool Upgradable() const
Definition: depcache.h:253
void ioprintf(ostream &out, const char *format,...)
Definition: strutl.cc:1433