]> git.saurik.com Git - apt.git/blame - apt-pkg/pkgcache.cc
eliminate dead file-provides code in cache generation
[apt.git] / apt-pkg / pkgcache.cc
CommitLineData
578bfd0a
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
bac2e715 3// $Id: pkgcache.cc,v 1.37 2003/02/10 01:40:58 doogie Exp $
578bfd0a
AL
4/* ######################################################################
5
6 Package Cache - Accessor code for the cache
7
094a497d 8 Please see doc/apt-pkg/cache.sgml for a more detailed description of
578bfd0a
AL
9 this format. Also be sure to keep that file up-to-date!!
10
1e3f4083 11 This is the general utility functions for cache management. They provide
578bfd0a
AL
12 a complete set of accessor functions for the cache. The cacheiterators
13 header contains the STL-like iterators that can be used to easially
14 navigate the cache as well as seemlessly dereference the mmap'd
15 indexes. Use these always.
16
17 The main class provides for ways to get package indexes and some
18 general lookup functions to start the iterators.
19
20 ##################################################################### */
21 /*}}}*/
22// Include Files /*{{{*/
ea542140
DK
23#include<config.h>
24
094a497d 25#include <apt-pkg/pkgcache.h>
af29ffb4 26#include <apt-pkg/policy.h>
094a497d
AL
27#include <apt-pkg/version.h>
28#include <apt-pkg/error.h>
231fea14 29#include <apt-pkg/strutl.h>
b2e465d6 30#include <apt-pkg/configuration.h>
45df0ad2 31#include <apt-pkg/aptconfiguration.h>
453b82a3 32#include <apt-pkg/mmap.h>
5c0d3668 33#include <apt-pkg/macros.h>
578bfd0a 34
453b82a3
DK
35#include <stddef.h>
36#include <string.h>
37#include <ostream>
38#include <vector>
578bfd0a
AL
39#include <string>
40#include <sys/stat.h>
ea542140
DK
41
42#include <apti18n.h>
578bfd0a
AL
43 /*}}}*/
44
851a45a8
AL
45using std::string;
46
012b102a 47
578bfd0a
AL
48// Cache::Header::Header - Constructor /*{{{*/
49// ---------------------------------------------------------------------
50/* Simply initialize the header */
51pkgCache::Header::Header()
52{
dfe66c72
DK
53#define APT_HEADER_SET(X,Y) X = Y; static_assert(std::numeric_limits<decltype(X)>::max() > Y, "Size violation detected in pkgCache::Header")
54 APT_HEADER_SET(Signature, 0x98FE76DC);
55
578bfd0a
AL
56 /* Whenever the structures change the major version should be bumped,
57 whenever the generator changes the minor version should be bumped. */
dfe66c72
DK
58 APT_HEADER_SET(MajorVersion, 10);
59 APT_HEADER_SET(MinorVersion, 0);
60 APT_HEADER_SET(Dirty, false);
61
62 APT_HEADER_SET(HeaderSz, sizeof(pkgCache::Header));
63 APT_HEADER_SET(GroupSz, sizeof(pkgCache::Group));
64 APT_HEADER_SET(PackageSz, sizeof(pkgCache::Package));
65 APT_HEADER_SET(ReleaseFileSz, sizeof(pkgCache::ReleaseFile));
66 APT_HEADER_SET(PackageFileSz, sizeof(pkgCache::PackageFile));
67 APT_HEADER_SET(VersionSz, sizeof(pkgCache::Version));
68 APT_HEADER_SET(DescriptionSz, sizeof(pkgCache::Description));
69 APT_HEADER_SET(DependencySz, sizeof(pkgCache::Dependency));
70 APT_HEADER_SET(DependencyDataSz, sizeof(pkgCache::DependencyData));
71 APT_HEADER_SET(ProvidesSz, sizeof(pkgCache::Provides));
72 APT_HEADER_SET(VerFileSz, sizeof(pkgCache::VerFile));
73 APT_HEADER_SET(DescFileSz, sizeof(pkgCache::DescFile));
74#undef APT_HEADER_SET
75
52c41485 76 GroupCount = 0;
578bfd0a
AL
77 PackageCount = 0;
78 VersionCount = 0;
a52f938b 79 DescriptionCount = 0;
578bfd0a 80 DependsCount = 0;
71c9e95b 81 DependsDataCount = 0;
b07aeb1a 82 ReleaseFileCount = 0;
578bfd0a 83 PackageFileCount = 0;
a7e66b17 84 VerFileCount = 0;
a52f938b 85 DescFileCount = 0;
a7e66b17 86 ProvidesCount = 0;
ad00ae81 87 MaxVerFileSize = 0;
a52f938b 88 MaxDescFileSize = 0;
dfe66c72 89
578bfd0a 90 FileList = 0;
b07aeb1a 91 RlsFileList = 0;
b2e465d6
AL
92 VerSysName = 0;
93 Architecture = 0;
32ab4bd0
DK
94 SetArchitectures(0);
95 SetHashTableSize(_config->FindI("APT::Cache-HashTableSize", 10 * 1048));
578bfd0a 96 memset(Pools,0,sizeof(Pools));
0688ccd8
JAK
97
98 CacheFileSize = 0;
578bfd0a
AL
99}
100 /*}}}*/
101// Cache::Header::CheckSizes - Check if the two headers have same *sz /*{{{*/
102// ---------------------------------------------------------------------
103/* */
104bool pkgCache::Header::CheckSizes(Header &Against) const
105{
106 if (HeaderSz == Against.HeaderSz &&
52c41485 107 GroupSz == Against.GroupSz &&
578bfd0a 108 PackageSz == Against.PackageSz &&
b07aeb1a 109 ReleaseFileSz == Against.ReleaseFileSz &&
578bfd0a
AL
110 PackageFileSz == Against.PackageFileSz &&
111 VersionSz == Against.VersionSz &&
a52f938b 112 DescriptionSz == Against.DescriptionSz &&
dcb79bae 113 DependencySz == Against.DependencySz &&
71c9e95b 114 DependencyDataSz == Against.DependencyDataSz &&
dcb79bae 115 VerFileSz == Against.VerFileSz &&
a52f938b 116 DescFileSz == Against.DescFileSz &&
578bfd0a
AL
117 ProvidesSz == Against.ProvidesSz)
118 return true;
119 return false;
120}
121 /*}}}*/
122
123// Cache::pkgCache - Constructor /*{{{*/
124// ---------------------------------------------------------------------
125/* */
32ab4bd0 126APT_IGNORE_DEPRECATED_PUSH
6c55f07a 127pkgCache::pkgCache(MMap *Map, bool DoMap) : Map(*Map), d(NULL)
578bfd0a 128{
4cbf323f
MV
129 // call getArchitectures() with cached=false to ensure that the
130 // architectures cache is re-evaulated. this is needed in cases
131 // when the APT::Architecture field changes between two cache creations
132 MultiArchEnabled = APT::Configuration::getArchitectures(false).size() > 1;
b2e465d6
AL
133 if (DoMap == true)
134 ReMap();
578bfd0a 135}
32ab4bd0 136APT_IGNORE_DEPRECATED_POP
578bfd0a
AL
137 /*}}}*/
138// Cache::ReMap - Reopen the cache file /*{{{*/
139// ---------------------------------------------------------------------
140/* If the file is already closed then this will open it open it. */
a9fe5928 141bool pkgCache::ReMap(bool const &Errorchecks)
578bfd0a
AL
142{
143 // Apply the typecasts.
144 HeaderP = (Header *)Map.Data();
5bf15716 145 GrpP = (Group *)Map.Data();
578bfd0a 146 PkgP = (Package *)Map.Data();
dcb79bae 147 VerFileP = (VerFile *)Map.Data();
a52f938b 148 DescFileP = (DescFile *)Map.Data();
b07aeb1a 149 RlsFileP = (ReleaseFile *)Map.Data();
578bfd0a
AL
150 PkgFileP = (PackageFile *)Map.Data();
151 VerP = (Version *)Map.Data();
a52f938b 152 DescP = (Description *)Map.Data();
578bfd0a
AL
153 ProvideP = (Provides *)Map.Data();
154 DepP = (Dependency *)Map.Data();
71c9e95b 155 DepDataP = (DependencyData *)Map.Data();
578bfd0a
AL
156 StrP = (char *)Map.Data();
157
a9fe5928
DK
158 if (Errorchecks == false)
159 return true;
160
b2e465d6
AL
161 if (Map.Size() == 0 || HeaderP == 0)
162 return _error->Error(_("Empty package cache"));
578bfd0a
AL
163
164 // Check the header
165 Header DefHeader;
166 if (HeaderP->Signature != DefHeader.Signature ||
167 HeaderP->Dirty == true)
b2e465d6 168 return _error->Error(_("The package cache file is corrupted"));
578bfd0a
AL
169
170 if (HeaderP->MajorVersion != DefHeader.MajorVersion ||
171 HeaderP->MinorVersion != DefHeader.MinorVersion ||
172 HeaderP->CheckSizes(DefHeader) == false)
b2e465d6
AL
173 return _error->Error(_("The package cache file is an incompatible version"));
174
7d79339f
JAK
175 if (Map.Size() < HeaderP->CacheFileSize)
176 return _error->Error(_("The package cache file is corrupted, it is too small"));
177
32ab4bd0 178 if (HeaderP->VerSysName == 0 || HeaderP->Architecture == 0 || HeaderP->GetArchitectures() == 0)
7a223b93
DK
179 return _error->Error(_("The package cache file is corrupted"));
180
b2e465d6 181 // Locate our VS..
7a223b93 182 if ((VS = pkgVersioningSystem::GetVS(StrP + HeaderP->VerSysName)) == 0)
db0db9fe 183 return _error->Error(_("This APT does not support the versioning system '%s'"),StrP + HeaderP->VerSysName);
b2e465d6 184
7a223b93
DK
185 // Check the architecture
186 std::vector<std::string> archs = APT::Configuration::getArchitectures();
187 std::vector<std::string>::const_iterator a = archs.begin();
188 std::string list = *a;
189 for (++a; a != archs.end(); ++a)
190 list.append(",").append(*a);
191 if (_config->Find("APT::Architecture") != StrP + HeaderP->Architecture ||
32ab4bd0
DK
192 list != StrP + HeaderP->GetArchitectures())
193 return _error->Error(_("The package cache was built for different architectures: %s vs %s"), StrP + HeaderP->GetArchitectures(), list.c_str());
7a223b93 194
578bfd0a
AL
195 return true;
196}
197 /*}}}*/
198// Cache::Hash - Hash a string /*{{{*/
199// ---------------------------------------------------------------------
200/* This is used to generate the hash entries for the HashTable. With my
201 package list from bo this function gets 94% table usage on a 512 item
202 table (480 used items) */
4ad8619b 203map_id_t pkgCache::sHash(const string &Str) const
578bfd0a
AL
204{
205 unsigned long Hash = 0;
f7f0d6c7 206 for (string::const_iterator I = Str.begin(); I != Str.end(); ++I)
aa0fe657 207 Hash = 41 * Hash + tolower_ascii(*I);
32ab4bd0 208 return Hash % HeaderP->GetHashTableSize();
578bfd0a
AL
209}
210
4ad8619b 211map_id_t pkgCache::sHash(const char *Str) const
578bfd0a 212{
aa0fe657
DK
213 unsigned long Hash = tolower_ascii(*Str);
214 for (const char *I = Str + 1; *I != 0; ++I)
215 Hash = 41 * Hash + tolower_ascii(*I);
32ab4bd0 216 return Hash % HeaderP->GetHashTableSize();
578bfd0a 217}
8d4c859d
DK
218 /*}}}*/
219// Cache::SingleArchFindPkg - Locate a package by name /*{{{*/
220// ---------------------------------------------------------------------
221/* Returns 0 on error, pointer to the package otherwise
222 The multiArch enabled methods will fallback to this one as it is (a bit)
223 faster for single arch environments and realworld is mostly singlearch… */
224pkgCache::PkgIterator pkgCache::SingleArchFindPkg(const string &Name)
225{
226 // Look at the hash bucket
32ab4bd0
DK
227 Package *Pkg = PkgP + HeaderP->PkgHashTableP()[Hash(Name)];
228 for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage)
8d4c859d 229 {
b59325e8 230 int const cmp = strcmp(Name.c_str(), StrP + (GrpP + Pkg->Group)->Name);
aa0fe657
DK
231 if (cmp == 0)
232 return PkgIterator(*this, Pkg);
233 else if (cmp < 0)
234 break;
8d4c859d
DK
235 }
236 return PkgIterator(*this,0);
237}
578bfd0a
AL
238 /*}}}*/
239// Cache::FindPkg - Locate a package by name /*{{{*/
240// ---------------------------------------------------------------------
241/* Returns 0 on error, pointer to the package otherwise */
25396fb0
DK
242pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) {
243 size_t const found = Name.find(':');
244 if (found == string::npos)
6c9937da 245 return FindPkg(Name, "native");
4d174dc8 246 string const Arch = Name.substr(found+1);
eddc9dd0
DK
247 /* Beware: This is specialcased to handle pkg:any in dependencies as
248 these are linked to virtual pkg:any named packages with all archs.
249 If you want any arch from a given pkg, use FindPkg(pkg,arch) */
4d174dc8
DK
250 if (Arch == "any")
251 return FindPkg(Name, "any");
252 return FindPkg(Name.substr(0, found), Arch);
25396fb0
DK
253}
254 /*}}}*/
255// Cache::FindPkg - Locate a package by name /*{{{*/
256// ---------------------------------------------------------------------
257/* Returns 0 on error, pointer to the package otherwise */
8d4c859d 258pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string const &Arch) {
5bf15716
DK
259 /* We make a detour via the GrpIterator here as
260 on a multi-arch environment a group is easier to
261 find than a package (less entries in the buckets) */
262 pkgCache::GrpIterator Grp = FindGrp(Name);
263 if (Grp.end() == true)
264 return PkgIterator(*this,0);
265
266 return Grp.FindPkg(Arch);
267}
268 /*}}}*/
269// Cache::FindGrp - Locate a group by name /*{{{*/
270// ---------------------------------------------------------------------
271/* Returns End-Pointer on error, pointer to the group otherwise */
272pkgCache::GrpIterator pkgCache::FindGrp(const string &Name) {
273 if (unlikely(Name.empty() == true))
274 return GrpIterator(*this,0);
275
276 // Look at the hash bucket for the group
32ab4bd0 277 Group *Grp = GrpP + HeaderP->GrpHashTableP()[sHash(Name)];
5bf15716 278 for (; Grp != GrpP; Grp = GrpP + Grp->Next) {
b59325e8 279 int const cmp = strcmp(Name.c_str(), StrP + Grp->Name);
aa0fe657 280 if (cmp == 0)
5bf15716 281 return GrpIterator(*this, Grp);
aa0fe657
DK
282 else if (cmp < 0)
283 break;
5bf15716
DK
284 }
285
286 return GrpIterator(*this,0);
578bfd0a
AL
287}
288 /*}}}*/
b2e465d6
AL
289// Cache::CompTypeDeb - Return a string describing the compare type /*{{{*/
290// ---------------------------------------------------------------------
291/* This returns a string representation of the dependency compare
292 type in the weird debian style.. */
293const char *pkgCache::CompTypeDeb(unsigned char Comp)
294{
69c2ecbd
DK
295 const char * const Ops[] = {"","<=",">=","<<",">>","=","!="};
296 if (unlikely((unsigned)(Comp & 0xF) >= sizeof(Ops)/sizeof(Ops[0])))
297 return "";
298 return Ops[Comp & 0xF];
b2e465d6
AL
299}
300 /*}}}*/
301// Cache::CompType - Return a string describing the compare type /*{{{*/
302// ---------------------------------------------------------------------
69c2ecbd 303/* This returns a string representation of the dependency compare
b2e465d6
AL
304 type */
305const char *pkgCache::CompType(unsigned char Comp)
306{
69c2ecbd
DK
307 const char * const Ops[] = {"","<=",">=","<",">","=","!="};
308 if (unlikely((unsigned)(Comp & 0xF) >= sizeof(Ops)/sizeof(Ops[0])))
309 return "";
310 return Ops[Comp & 0xF];
b2e465d6
AL
311}
312 /*}}}*/
313// Cache::DepType - Return a string describing the dep type /*{{{*/
314// ---------------------------------------------------------------------
315/* */
316const char *pkgCache::DepType(unsigned char Type)
317{
318 const char *Types[] = {"",_("Depends"),_("PreDepends"),_("Suggests"),
319 _("Recommends"),_("Conflicts"),_("Replaces"),
f8ae7e8b 320 _("Obsoletes"),_("Breaks"), _("Enhances")};
308c7d30 321 if (Type < sizeof(Types)/sizeof(*Types))
b2e465d6
AL
322 return Types[Type];
323 return "";
324}
325 /*}}}*/
0149949b
AL
326// Cache::Priority - Convert a priority value to a string /*{{{*/
327// ---------------------------------------------------------------------
328/* */
329const char *pkgCache::Priority(unsigned char Prio)
330{
b2e465d6
AL
331 const char *Mapping[] = {0,_("important"),_("required"),_("standard"),
332 _("optional"),_("extra")};
0149949b
AL
333 if (Prio < _count(Mapping))
334 return Mapping[Prio];
335 return 0;
336}
337 /*}}}*/
5bf15716
DK
338// GrpIterator::FindPkg - Locate a package by arch /*{{{*/
339// ---------------------------------------------------------------------
340/* Returns an End-Pointer on error, pointer to the package otherwise */
e841200b 341pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) const {
5bf15716
DK
342 if (unlikely(IsGood() == false || S->FirstPackage == 0))
343 return PkgIterator(*Owner, 0);
344
60dcec6d
DK
345 /* If we accept any package we simply return the "first"
346 package in this group (the last one added). */
347 if (Arch == "any")
348 return PkgIterator(*Owner, Owner->PkgP + S->FirstPackage);
349
959470da 350 char const* const myArch = Owner->NativeArch();
5bf15716
DK
351 /* Most of the time the package for our native architecture is
352 the one we add at first to the cache, but this would be the
353 last one we check, so we do it now. */
566046f4 354 if (Arch == "native" || Arch == myArch || Arch == "all") {
5bf15716 355 pkgCache::Package *Pkg = Owner->PkgP + S->LastPackage;
b59325e8 356 if (strcmp(myArch, Owner->StrP + Pkg->Arch) == 0)
5bf15716 357 return PkgIterator(*Owner, Pkg);
959470da 358 Arch = myArch;
5bf15716
DK
359 }
360
5d1e330d 361 // Iterate over the list to find the matching arch
5bf15716 362 for (pkgCache::Package *Pkg = PackageList(); Pkg != Owner->PkgP;
32ab4bd0 363 Pkg = Owner->PkgP + Pkg->NextPackage) {
5d1e330d 364 if (stringcmp(Arch, Owner->StrP + Pkg->Arch) == 0)
5bf15716
DK
365 return PkgIterator(*Owner, Pkg);
366 if ((Owner->PkgP + S->LastPackage) == Pkg)
367 break;
368 }
369
bd2fb30a
DK
370 return PkgIterator(*Owner, 0);
371}
372 /*}}}*/
373// GrpIterator::FindPreferredPkg - Locate the "best" package /*{{{*/
374// ---------------------------------------------------------------------
375/* Returns an End-Pointer on error, pointer to the package otherwise */
3db58cf4 376pkgCache::PkgIterator pkgCache::GrpIterator::FindPreferredPkg(bool const &PreferNonVirtual) const {
bd2fb30a 377 pkgCache::PkgIterator Pkg = FindPkg("native");
3db58cf4 378 if (Pkg.end() == false && (PreferNonVirtual == false || Pkg->VersionList != 0))
bd2fb30a
DK
379 return Pkg;
380
381 std::vector<std::string> const archs = APT::Configuration::getArchitectures();
382 for (std::vector<std::string>::const_iterator a = archs.begin();
383 a != archs.end(); ++a) {
384 Pkg = FindPkg(*a);
3db58cf4 385 if (Pkg.end() == false && (PreferNonVirtual == false || Pkg->VersionList != 0))
bd2fb30a
DK
386 return Pkg;
387 }
c919ad6e
DK
388 // packages without an architecture
389 Pkg = FindPkg("none");
390 if (Pkg.end() == false && (PreferNonVirtual == false || Pkg->VersionList != 0))
391 return Pkg;
bd2fb30a 392
3db58cf4
DK
393 if (PreferNonVirtual == true)
394 return FindPreferredPkg(false);
5bf15716
DK
395 return PkgIterator(*Owner, 0);
396}
397 /*}}}*/
398// GrpIterator::NextPkg - Locate the next package in the group /*{{{*/
399// ---------------------------------------------------------------------
400/* Returns an End-Pointer on error, pointer to the package otherwise.
c408e01e
DK
401 We can't simply ++ to the next as the next package of the last will
402 be from a different group (with the same hash value) */
e841200b 403pkgCache::PkgIterator pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator const &LastPkg) const {
5bf15716
DK
404 if (unlikely(IsGood() == false || S->FirstPackage == 0 ||
405 LastPkg.end() == true))
406 return PkgIterator(*Owner, 0);
407
c408e01e
DK
408 if (S->LastPackage == LastPkg.Index())
409 return PkgIterator(*Owner, 0);
5bf15716 410
32ab4bd0 411 return PkgIterator(*Owner, Owner->PkgP + LastPkg->NextPackage);
5bf15716
DK
412}
413 /*}}}*/
71c9e95b 414// GrpIterator::operator++ - Prefix incr /*{{{*/
25396fb0
DK
415// ---------------------------------------------------------------------
416/* This will advance to the next logical group in the hash table. */
3707fd4f 417pkgCache::GrpIterator& pkgCache::GrpIterator::operator++()
25396fb0
DK
418{
419 // Follow the current links
420 if (S != Owner->GrpP)
421 S = Owner->GrpP + S->Next;
422
423 // Follow the hash table
32ab4bd0 424 while (S == Owner->GrpP && (HashIndex+1) < (signed)Owner->HeaderP->GetHashTableSize())
25396fb0 425 {
71c9e95b 426 ++HashIndex;
32ab4bd0 427 S = Owner->GrpP + Owner->HeaderP->GrpHashTableP()[HashIndex];
25396fb0 428 }
3707fd4f 429 return *this;
d3e8fbb3 430}
f55a958f 431 /*}}}*/
71c9e95b 432// PkgIterator::operator++ - Prefix incr /*{{{*/
578bfd0a
AL
433// ---------------------------------------------------------------------
434/* This will advance to the next logical package in the hash table. */
71c9e95b 435pkgCache::PkgIterator& pkgCache::PkgIterator::operator++()
578bfd0a
AL
436{
437 // Follow the current links
773e2c1f 438 if (S != Owner->PkgP)
32ab4bd0 439 S = Owner->PkgP + S->NextPackage;
b2e465d6 440
578bfd0a 441 // Follow the hash table
32ab4bd0 442 while (S == Owner->PkgP && (HashIndex+1) < (signed)Owner->HeaderP->GetHashTableSize())
578bfd0a 443 {
71c9e95b 444 ++HashIndex;
32ab4bd0 445 S = Owner->PkgP + Owner->HeaderP->PkgHashTableP()[HashIndex];
578bfd0a 446 }
3707fd4f 447 return *this;
d3e8fbb3 448}
578bfd0a 449 /*}}}*/
71c9e95b
DK
450pkgCache::DepIterator& pkgCache::DepIterator::operator++() /*{{{*/
451{
452 if (S == Owner->DepP)
453 return *this;
454 S = Owner->DepP + (Type == DepVer ? S->NextDepends : S->NextRevDepends);
455 if (S == Owner->DepP)
456 S2 = Owner->DepDataP;
457 else
458 S2 = Owner->DepDataP + S->DependencyData;
459 return *this;
460}
461 /*}}}*/
578bfd0a
AL
462// PkgIterator::State - Check the State of the package /*{{{*/
463// ---------------------------------------------------------------------
464/* By this we mean if it is either cleanly installed or cleanly removed. */
465pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const
d38b7b3d 466{
773e2c1f
DK
467 if (S->InstState == pkgCache::State::ReInstReq ||
468 S->InstState == pkgCache::State::HoldReInstReq)
c7c1b0f6
AL
469 return NeedsUnpack;
470
773e2c1f
DK
471 if (S->CurrentState == pkgCache::State::UnPacked ||
472 S->CurrentState == pkgCache::State::HalfConfigured)
c6aa14e4
MV
473 // we leave triggers alone complettely. dpkg deals with
474 // them in a hard-to-predict manner and if they get
475 // resolved by dpkg before apt run dpkg --configure on
476 // the TriggersPending package dpkg returns a error
09fab244 477 //Pkg->CurrentState == pkgCache::State::TriggersAwaited
c6aa14e4 478 //Pkg->CurrentState == pkgCache::State::TriggersPending)
578bfd0a
AL
479 return NeedsConfigure;
480
773e2c1f
DK
481 if (S->CurrentState == pkgCache::State::HalfInstalled ||
482 S->InstState != pkgCache::State::Ok)
578bfd0a
AL
483 return NeedsUnpack;
484
485 return NeedsNothing;
486}
487 /*}}}*/
af29ffb4
MV
488// PkgIterator::CandVersion - Returns the candidate version string /*{{{*/
489// ---------------------------------------------------------------------
490/* Return string representing of the candidate version. */
491const char *
d3e8fbb3 492pkgCache::PkgIterator::CandVersion() const
af29ffb4
MV
493{
494 //TargetVer is empty, so don't use it.
749eb4cf 495 VerIterator version = pkgPolicy(Owner).GetCandidateVer(*this);
af29ffb4
MV
496 if (version.IsGood())
497 return version.VerStr();
498 return 0;
d3e8fbb3 499}
af29ffb4
MV
500 /*}}}*/
501// PkgIterator::CurVersion - Returns the current version string /*{{{*/
502// ---------------------------------------------------------------------
503/* Return string representing of the current version. */
504const char *
d3e8fbb3 505pkgCache::PkgIterator::CurVersion() const
af29ffb4
MV
506{
507 VerIterator version = CurrentVer();
508 if (version.IsGood())
509 return CurrentVer().VerStr();
510 return 0;
d3e8fbb3 511}
af29ffb4
MV
512 /*}}}*/
513// ostream operator to handle string representation of a package /*{{{*/
514// ---------------------------------------------------------------------
515/* Output name < cur.rent.version -> candid.ate.version | new.est.version > (section)
1e3f4083 516 Note that the characters <|>() are all literal above. Versions will be omitted
af29ffb4
MV
517 if they provide no new information (e.g. there is no newer version than candidate)
518 If no version and/or section can be found "none" is used. */
519std::ostream&
8f3ba4e8 520operator<<(std::ostream& out, pkgCache::PkgIterator Pkg)
af29ffb4
MV
521{
522 if (Pkg.end() == true)
523 return out << "invalid package";
524
525 string current = string(Pkg.CurVersion() == 0 ? "none" : Pkg.CurVersion());
526 string candidate = string(Pkg.CandVersion() == 0 ? "none" : Pkg.CandVersion());
527 string newest = string(Pkg.VersionList().end() ? "none" : Pkg.VersionList().VerStr());
528
5dd4c8b8 529 out << Pkg.Name() << " [ " << Pkg.Arch() << " ] < " << current;
af29ffb4
MV
530 if (current != candidate)
531 out << " -> " << candidate;
532 if ( newest != "none" && candidate != newest)
533 out << " | " << newest;
7a669774
DK
534 if (Pkg->VersionList == 0)
535 out << " > ( none )";
536 else
537 out << " > ( " << string(Pkg.VersionList().Section()==0?"unknown":Pkg.VersionList().Section()) << " )";
af29ffb4
MV
538 return out;
539}
540 /*}}}*/
75ce2062
DK
541// PkgIterator::FullName - Returns Name and (maybe) Architecture /*{{{*/
542// ---------------------------------------------------------------------
543/* Returns a name:arch string */
544std::string pkgCache::PkgIterator::FullName(bool const &Pretty) const
545{
546 string fullname = Name();
547 if (Pretty == false ||
959470da
DK
548 (strcmp(Arch(), "all") != 0 &&
549 strcmp(Owner->NativeArch(), Arch()) != 0))
75ce2062
DK
550 return fullname.append(":").append(Arch());
551 return fullname;
552}
553 /*}}}*/
578bfd0a
AL
554// DepIterator::IsCritical - Returns true if the dep is important /*{{{*/
555// ---------------------------------------------------------------------
556/* Currently critical deps are defined as depends, predepends and
308c7d30 557 conflicts (including dpkg's Breaks fields). */
e841200b 558bool pkgCache::DepIterator::IsCritical() const
578bfd0a 559{
359e46db 560 if (IsNegative() == true ||
71c9e95b
DK
561 S2->Type == pkgCache::Dep::Depends ||
562 S2->Type == pkgCache::Dep::PreDepends)
578bfd0a
AL
563 return true;
564 return false;
565}
566 /*}}}*/
df77d8a5
DK
567// DepIterator::IsNegative - Returns true if the dep is a negative one /*{{{*/
568// ---------------------------------------------------------------------
569/* Some dependencies are positive like Depends and Recommends, others
570 are negative like Conflicts which can and should be handled differently */
571bool pkgCache::DepIterator::IsNegative() const
572{
71c9e95b
DK
573 return S2->Type == Dep::DpkgBreaks ||
574 S2->Type == Dep::Conflicts ||
575 S2->Type == Dep::Obsoletes;
df77d8a5
DK
576}
577 /*}}}*/
578bfd0a
AL
578// DepIterator::SmartTargetPkg - Resolve dep target pointers w/provides /*{{{*/
579// ---------------------------------------------------------------------
580/* This intellegently looks at dep target packages and tries to figure
581 out which package should be used. This is needed to nicely handle
582 provide mapping. If the target package has no other providing packages
583 then it returned. Otherwise the providing list is looked at to
584 see if there is one one unique providing package if so it is returned.
585 Otherwise true is returned and the target package is set. The return
b2e465d6
AL
586 result indicates whether the node should be expandable
587
588 In Conjunction with the DepCache the value of Result may not be
589 super-good since the policy may have made it uninstallable. Using
590 AllTargets is better in this case. */
e841200b 591bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator &Result) const
578bfd0a
AL
592{
593 Result = TargetPkg();
594
595 // No provides at all
596 if (Result->ProvidesList == 0)
597 return false;
598
599 // There is the Base package and the providing ones which is at least 2
600 if (Result->VersionList != 0)
601 return true;
602
603 /* We have to skip over indirect provisions of the package that
604 owns the dependency. For instance, if libc5-dev depends on the
605 virtual package libc-dev which is provided by libc5-dev and libc6-dev
606 we must ignore libc5-dev when considering the provides list. */
607 PrvIterator PStart = Result.ProvidesList();
f7f0d6c7 608 for (; PStart.end() != true && PStart.OwnerPkg() == ParentPkg(); ++PStart);
578bfd0a
AL
609
610 // Nothing but indirect self provides
611 if (PStart.end() == true)
612 return false;
613
614 // Check for single packages in the provides list
615 PrvIterator P = PStart;
f7f0d6c7 616 for (; P.end() != true; ++P)
578bfd0a
AL
617 {
618 // Skip over self provides
619 if (P.OwnerPkg() == ParentPkg())
620 continue;
621 if (PStart.OwnerPkg() != P.OwnerPkg())
622 break;
623 }
b2e465d6
AL
624
625 Result = PStart.OwnerPkg();
578bfd0a
AL
626
627 // Check for non dups
628 if (P.end() != true)
629 return true;
b2e465d6 630
578bfd0a
AL
631 return false;
632}
633 /*}}}*/
634// DepIterator::AllTargets - Returns the set of all possible targets /*{{{*/
635// ---------------------------------------------------------------------
b2e465d6 636/* This is a more useful version of TargetPkg() that follows versioned
578bfd0a 637 provides. It includes every possible package-version that could satisfy
fbfb2a7c
AL
638 the dependency. The last item in the list has a 0. The resulting pointer
639 must be delete [] 'd */
e841200b 640pkgCache::Version **pkgCache::DepIterator::AllTargets() const
578bfd0a
AL
641{
642 Version **Res = 0;
643 unsigned long Size =0;
644 while (1)
645 {
646 Version **End = Res;
647 PkgIterator DPkg = TargetPkg();
648
649 // Walk along the actual package providing versions
f7f0d6c7 650 for (VerIterator I = DPkg.VersionList(); I.end() == false; ++I)
578bfd0a 651 {
85434114 652 if (IsIgnorable(I.ParentPkg()) == true)
578bfd0a 653 continue;
887c6940 654 if (IsSatisfied(I) == false)
578bfd0a 655 continue;
85434114 656
578bfd0a
AL
657 Size++;
658 if (Res != 0)
659 *End++ = I;
660 }
661
662 // Follow all provides
f7f0d6c7 663 for (PrvIterator I = DPkg.ProvidesList(); I.end() == false; ++I)
578bfd0a 664 {
85434114 665 if (IsIgnorable(I) == true)
578bfd0a 666 continue;
887c6940 667 if (IsSatisfied(I) == false)
85434114 668 continue;
5f909b67 669
578bfd0a
AL
670 Size++;
671 if (Res != 0)
672 *End++ = I.OwnerVer();
673 }
674
675 // Do it again and write it into the array
676 if (Res == 0)
677 {
678 Res = new Version *[Size+1];
679 Size = 0;
680 }
681 else
682 {
683 *End = 0;
684 break;
685 }
686 }
687
688 return Res;
689}
690 /*}}}*/
43d017d6
AL
691// DepIterator::GlobOr - Compute an OR group /*{{{*/
692// ---------------------------------------------------------------------
693/* This Takes an iterator, iterates past the current dependency grouping
694 and returns Start and End so that so End is the final element
695 in the group, if End == Start then D is End++ and End is the
696 dependency D was pointing to. Use in loops to iterate sensibly. */
697void pkgCache::DepIterator::GlobOr(DepIterator &Start,DepIterator &End)
698{
699 // Compute a single dependency element (glob or)
700 Start = *this;
701 End = *this;
018f1533 702 for (bool LastOR = true; end() == false && LastOR == true;)
43d017d6 703 {
71c9e95b 704 LastOR = (S2->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
3707fd4f 705 ++(*this);
43d017d6
AL
706 if (LastOR == true)
707 End = (*this);
708 }
709}
710 /*}}}*/
85434114
DK
711// DepIterator::IsIgnorable - should this packag/providr be ignored? /*{{{*/
712// ---------------------------------------------------------------------
713/* Deps like self-conflicts should be ignored as well as implicit conflicts
714 on virtual packages. */
fd23676e 715bool pkgCache::DepIterator::IsIgnorable(PkgIterator const &PT) const
85434114 716{
021626db
DK
717 if (IsNegative() == false)
718 return false;
719
fd23676e 720 pkgCache::PkgIterator const PP = ParentPkg();
021626db
DK
721 if (PP->Group != PT->Group)
722 return false;
723 // self-conflict
724 if (PP == PT)
725 return true;
fd23676e 726 pkgCache::VerIterator const PV = ParentVer();
021626db
DK
727 // ignore group-conflict on a M-A:same package - but not our implicit dependencies
728 // so that we can have M-A:same packages conflicting with their own real name
729 if ((PV->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
8c7af4d4 730 return IsMultiArchImplicit() == false;
85434114
DK
731
732 return false;
733}
734bool pkgCache::DepIterator::IsIgnorable(PrvIterator const &Prv) const
735{
736 if (IsNegative() == false)
737 return false;
738
739 PkgIterator const Pkg = ParentPkg();
740 /* Provides may never be applied against the same package (or group)
741 if it is a conflicts. See the comment above. */
742 if (Prv.OwnerPkg()->Group == Pkg->Group)
743 return true;
744 // Implicit group-conflicts should not be applied on providers of other groups
8c7af4d4 745 if (IsMultiArchImplicit() && Prv.OwnerPkg()->Group != Pkg->Group)
85434114
DK
746 return true;
747
748 return false;
749}
750 /*}}}*/
887c6940
DK
751// DepIterator::IsSatisfied - check if a version satisfied the dependency /*{{{*/
752bool pkgCache::DepIterator::IsSatisfied(VerIterator const &Ver) const
753{
71c9e95b 754 return Owner->VS->CheckDep(Ver.VerStr(),S2->CompareOp,TargetVer());
887c6940
DK
755}
756bool pkgCache::DepIterator::IsSatisfied(PrvIterator const &Prv) const
757{
71c9e95b 758 return Owner->VS->CheckDep(Prv.ProvideVersion(),S2->CompareOp,TargetVer());
887c6940
DK
759}
760 /*}}}*/
8c7af4d4
DK
761// DepIterator::IsImplicit - added by the cache generation /*{{{*/
762bool pkgCache::DepIterator::IsImplicit() const
763{
764 if (IsMultiArchImplicit() == true)
765 return true;
766 if (IsNegative() || S2->Type == pkgCache::Dep::Replaces)
767 {
768 if ((S2->CompareOp & pkgCache::Dep::ArchSpecific) != pkgCache::Dep::ArchSpecific &&
769 strcmp(ParentPkg().Arch(), TargetPkg().Arch()) != 0)
770 return true;
771 }
772 return false;
773}
774 /*}}}*/
47f6d1b7
DK
775// ostream operator to handle string representation of a dependecy /*{{{*/
776// ---------------------------------------------------------------------
777/* */
8f3ba4e8 778std::ostream& operator<<(std::ostream& out, pkgCache::DepIterator D)
47f6d1b7
DK
779{
780 if (D.end() == true)
781 return out << "invalid dependency";
782
783 pkgCache::PkgIterator P = D.ParentPkg();
784 pkgCache::PkgIterator T = D.TargetPkg();
785
786 out << (P.end() ? "invalid pkg" : P.FullName(false)) << " " << D.DepType()
787 << " on ";
788 if (T.end() == true)
789 out << "invalid pkg";
790 else
791 out << T;
792
793 if (D->Version != 0)
794 out << " (" << D.CompType() << " " << D.TargetVer() << ")";
795
796 return out;
797}
798 /*}}}*/
578bfd0a
AL
799// VerIterator::CompareVer - Fast version compare for same pkgs /*{{{*/
800// ---------------------------------------------------------------------
801/* This just looks over the version list to see if B is listed before A. In
802 most cases this will return in under 4 checks, ver lists are short. */
803int pkgCache::VerIterator::CompareVer(const VerIterator &B) const
804{
805 // Check if they are equal
806 if (*this == B)
807 return 0;
808 if (end() == true)
809 return -1;
810 if (B.end() == true)
811 return 1;
812
813 /* Start at A and look for B. If B is found then A > B otherwise
814 B was before A so A < B */
815 VerIterator I = *this;
f7f0d6c7 816 for (;I.end() == false; ++I)
578bfd0a
AL
817 if (I == B)
818 return 1;
819 return -1;
820}
821 /*}}}*/
b518cca6
AL
822// VerIterator::Downloadable - Checks if the version is downloadable /*{{{*/
823// ---------------------------------------------------------------------
824/* */
0e6fe58e 825APT_PURE bool pkgCache::VerIterator::Downloadable() const
b518cca6
AL
826{
827 VerFileIterator Files = FileList();
f7f0d6c7 828 for (; Files.end() == false; ++Files)
b07aeb1a 829 if (Files.File().Flagged(pkgCache::Flag::NotSource) == false)
b518cca6
AL
830 return true;
831 return false;
832}
833 /*}}}*/
3c124dde
AL
834// VerIterator::Automatic - Check if this version is 'automatic' /*{{{*/
835// ---------------------------------------------------------------------
836/* This checks to see if any of the versions files are not NotAutomatic.
837 True if this version is selectable for automatic installation. */
0e6fe58e 838APT_PURE bool pkgCache::VerIterator::Automatic() const
3c124dde
AL
839{
840 VerFileIterator Files = FileList();
f7f0d6c7 841 for (; Files.end() == false; ++Files)
5ed56f93 842 // Do not check ButAutomaticUpgrades here as it is kind of automatic…
b07aeb1a 843 if (Files.File().Flagged(pkgCache::Flag::NotAutomatic) == false)
3c124dde
AL
844 return true;
845 return false;
846}
847 /*}}}*/
848// VerIterator::NewestFile - Return the newest file version relation /*{{{*/
849// ---------------------------------------------------------------------
850/* This looks at the version numbers associated with all of the sources
851 this version is in and returns the highest.*/
852pkgCache::VerFileIterator pkgCache::VerIterator::NewestFile() const
853{
854 VerFileIterator Files = FileList();
855 VerFileIterator Highest = Files;
f7f0d6c7 856 for (; Files.end() == false; ++Files)
3c124dde 857 {
b2e465d6 858 if (Owner->VS->CmpReleaseVer(Files.File().Version(),Highest.File().Version()) > 0)
3c124dde
AL
859 Highest = Files;
860 }
861
862 return Highest;
863}
864 /*}}}*/
b2e465d6
AL
865// VerIterator::RelStr - Release description string /*{{{*/
866// ---------------------------------------------------------------------
867/* This describes the version from a release-centric manner. The output is a
868 list of Label:Version/Archive */
d4489d49 869string pkgCache::VerIterator::RelStr() const
b2e465d6
AL
870{
871 bool First = true;
872 string Res;
f7f0d6c7 873 for (pkgCache::VerFileIterator I = this->FileList(); I.end() == false; ++I)
b2e465d6
AL
874 {
875 // Do not print 'not source' entries'
b07aeb1a
DK
876 pkgCache::PkgFileIterator const File = I.File();
877 if (File.Flagged(pkgCache::Flag::NotSource))
b2e465d6
AL
878 continue;
879
880 // See if we have already printed this out..
881 bool Seen = false;
f7f0d6c7 882 for (pkgCache::VerFileIterator J = this->FileList(); I != J; ++J)
b2e465d6 883 {
b07aeb1a
DK
884 pkgCache::PkgFileIterator const File2 = J.File();
885 if (File2.Label() == 0 || File.Label() == 0)
b2e465d6
AL
886 continue;
887
888 if (strcmp(File.Label(),File2.Label()) != 0)
889 continue;
890
b07aeb1a 891 if (File2.Version() == File.Version())
b2e465d6
AL
892 {
893 Seen = true;
894 break;
895 }
b07aeb1a 896 if (File2.Version() == 0 || File.Version() == 0)
b2e465d6
AL
897 break;
898 if (strcmp(File.Version(),File2.Version()) == 0)
899 Seen = true;
900 }
901
902 if (Seen == true)
903 continue;
904
905 if (First == false)
906 Res += ", ";
907 else
908 First = false;
909
b07aeb1a 910 if (File.Label() != 0)
b2e465d6
AL
911 Res = Res + File.Label() + ':';
912
b07aeb1a 913 if (File.Archive() != 0)
b2e465d6 914 {
b07aeb1a 915 if (File.Version() == 0)
b2e465d6
AL
916 Res += File.Archive();
917 else
918 Res = Res + File.Version() + '/' + File.Archive();
919 }
920 else
921 {
922 // No release file, print the host name that this came from
b07aeb1a 923 if (File.Site() == 0 || File.Site()[0] == 0)
b2e465d6
AL
924 Res += "localhost";
925 else
926 Res += File.Site();
927 }
5dd4c8b8 928 }
857e9c13 929 if (S->ParentPkg != 0)
5dd4c8b8 930 Res.append(" [").append(Arch()).append("]");
b2e465d6
AL
931 return Res;
932}
933 /*}}}*/
7a948ec7
DK
934// VerIterator::MultiArchType - string representing MultiArch flag /*{{{*/
935const char * pkgCache::VerIterator::MultiArchType() const
936{
937 if ((S->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
938 return "same";
939 else if ((S->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign)
940 return "foreign";
941 else if ((S->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
942 return "allowed";
943 return "none";
944}
945 /*}}}*/
b07aeb1a 946// RlsFileIterator::IsOk - Checks if the cache is in sync with the file /*{{{*/
578bfd0a
AL
947// ---------------------------------------------------------------------
948/* This stats the file and compares its stats with the ones that were
b07aeb1a 949 stored during generation. Date checks should probably also be
578bfd0a 950 included here. */
b07aeb1a 951bool pkgCache::RlsFileIterator::IsOk()
578bfd0a
AL
952{
953 struct stat Buf;
954 if (stat(FileName(),&Buf) != 0)
955 return false;
956
773e2c1f 957 if (Buf.st_size != (signed)S->Size || Buf.st_mtime != S->mtime)
578bfd0a
AL
958 return false;
959
960 return true;
961}
962 /*}}}*/
b07aeb1a
DK
963// RlsFileIterator::RelStr - Return the release string /*{{{*/
964string pkgCache::RlsFileIterator::RelStr()
af87ab54
AL
965{
966 string Res;
967 if (Version() != 0)
968 Res = Res + (Res.empty() == true?"v=":",v=") + Version();
969 if (Origin() != 0)
970 Res = Res + (Res.empty() == true?"o=":",o=") + Origin();
971 if (Archive() != 0)
972 Res = Res + (Res.empty() == true?"a=":",a=") + Archive();
efc487fb
DK
973 if (Codename() != 0)
974 Res = Res + (Res.empty() == true?"n=":",n=") + Codename();
af87ab54
AL
975 if (Label() != 0)
976 Res = Res + (Res.empty() == true?"l=":",l=") + Label();
b07aeb1a
DK
977 return Res;
978}
979 /*}}}*/
980// PkgFileIterator::IsOk - Checks if the cache is in sync with the file /*{{{*/
981// ---------------------------------------------------------------------
982/* This stats the file and compares its stats with the ones that were
983 stored during generation. Date checks should probably also be
984 included here. */
985bool pkgCache::PkgFileIterator::IsOk()
986{
987 struct stat Buf;
988 if (stat(FileName(),&Buf) != 0)
989 return false;
990
991 if (Buf.st_size != (signed)S->Size || Buf.st_mtime != S->mtime)
992 return false;
993
994 return true;
995}
996 /*}}}*/
997string pkgCache::PkgFileIterator::RelStr() /*{{{*/
998{
999 std::string Res;
1000 if (ReleaseFile() == 0)
1001 {
1002 if (Component() != 0)
1003 Res = Res + (Res.empty() == true?"a=":",a=") + Component();
1004 }
1005 else
1006 {
1007 Res = ReleaseFile().RelStr();
1008 if (Component() != 0)
1009 Res = Res + (Res.empty() == true?"c=":",c=") + Component();
1010 }
5dd4c8b8
DK
1011 if (Architecture() != 0)
1012 Res = Res + (Res.empty() == true?"b=":",b=") + Architecture();
af87ab54
AL
1013 return Res;
1014}
1015 /*}}}*/
012b102a
MV
1016// VerIterator::TranslatedDescription - Return the a DescIter for locale/*{{{*/
1017// ---------------------------------------------------------------------
d3e8fbb3 1018/* return a DescIter for the current locale or the default if none is
012b102a
MV
1019 * found
1020 */
1021pkgCache::DescIterator pkgCache::VerIterator::TranslatedDescription() const
1022{
45df0ad2
DK
1023 std::vector<string> const lang = APT::Configuration::getLanguages();
1024 for (std::vector<string>::const_iterator l = lang.begin();
f7f0d6c7 1025 l != lang.end(); ++l)
45df0ad2 1026 {
4b625b95
DK
1027 pkgCache::DescIterator Desc = DescriptionList();
1028 for (; Desc.end() == false; ++Desc)
0e7c3313 1029 if (*l == Desc.LanguageCode())
45df0ad2 1030 break;
4b625b95 1031 if (Desc.end() == true)
0e7c3313
DK
1032 {
1033 if (*l == "en")
1034 {
1035 Desc = DescriptionList();
1036 for (; Desc.end() == false; ++Desc)
1037 if (strcmp(Desc.LanguageCode(), "") == 0)
1038 break;
1039 if (Desc.end() == true)
1040 continue;
1041 }
1042 else
1043 continue;
1044 }
45df0ad2
DK
1045 return Desc;
1046 }
4b625b95
DK
1047 for (pkgCache::DescIterator Desc = DescriptionList();
1048 Desc.end() == false; ++Desc)
1049 if (strcmp(Desc.LanguageCode(), "") == 0)
1050 return Desc;
45df0ad2 1051 return DescriptionList();
d3e8fbb3 1052}
012b102a
MV
1053
1054 /*}}}*/
c8a4ce6c
DK
1055
1056pkgCache::~pkgCache() {}