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