]> git.saurik.com Git - apt.git/blob - apt-pkg/pkgcache.cc
Merge branch 'debian/sid' into debian/experimental
[apt.git] / apt-pkg / pkgcache.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: pkgcache.cc,v 1.37 2003/02/10 01:40:58 doogie Exp $
4 /* ######################################################################
5
6 Package Cache - Accessor code for the cache
7
8 Please see doc/apt-pkg/cache.sgml for a more detailed description of
9 this format. Also be sure to keep that file up-to-date!!
10
11 This is the general utility functions for cache management. They provide
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 /*{{{*/
23 #include<config.h>
24
25 #include <apt-pkg/pkgcache.h>
26 #include <apt-pkg/policy.h>
27 #include <apt-pkg/version.h>
28 #include <apt-pkg/error.h>
29 #include <apt-pkg/strutl.h>
30 #include <apt-pkg/configuration.h>
31 #include <apt-pkg/aptconfiguration.h>
32 #include <apt-pkg/mmap.h>
33 #include <apt-pkg/macros.h>
34
35 #include <stddef.h>
36 #include <string.h>
37 #include <ostream>
38 #include <vector>
39 #include <string>
40 #include <sys/stat.h>
41
42 #include <apti18n.h>
43 /*}}}*/
44
45 using std::string;
46
47
48 // Cache::Header::Header - Constructor /*{{{*/
49 // ---------------------------------------------------------------------
50 /* Simply initialize the header */
51 pkgCache::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. */
57 MajorVersion = 10;
58 MinorVersion = 0;
59 Dirty = false;
60
61 HeaderSz = sizeof(pkgCache::Header);
62 GroupSz = sizeof(pkgCache::Group);
63 PackageSz = sizeof(pkgCache::Package);
64 PackageFileSz = sizeof(pkgCache::PackageFile);
65 VersionSz = sizeof(pkgCache::Version);
66 DescriptionSz = sizeof(pkgCache::Description);
67 DependencySz = sizeof(pkgCache::Dependency);
68 ProvidesSz = sizeof(pkgCache::Provides);
69 VerFileSz = sizeof(pkgCache::VerFile);
70 DescFileSz = sizeof(pkgCache::DescFile);
71
72 GroupCount = 0;
73 PackageCount = 0;
74 VersionCount = 0;
75 DescriptionCount = 0;
76 DependsCount = 0;
77 PackageFileCount = 0;
78 VerFileCount = 0;
79 DescFileCount = 0;
80 ProvidesCount = 0;
81 MaxVerFileSize = 0;
82 MaxDescFileSize = 0;
83
84 FileList = 0;
85 VerSysName = 0;
86 Architecture = 0;
87 Architectures = 0;
88 HashTableSize = _config->FindI("APT::Cache-HashTableSize", 10 * 1048);
89 memset(Pools,0,sizeof(Pools));
90
91 CacheFileSize = 0;
92 }
93 /*}}}*/
94 // Cache::Header::CheckSizes - Check if the two headers have same *sz /*{{{*/
95 // ---------------------------------------------------------------------
96 /* */
97 bool pkgCache::Header::CheckSizes(Header &Against) const
98 {
99 if (HeaderSz == Against.HeaderSz &&
100 GroupSz == Against.GroupSz &&
101 PackageSz == Against.PackageSz &&
102 PackageFileSz == Against.PackageFileSz &&
103 VersionSz == Against.VersionSz &&
104 DescriptionSz == Against.DescriptionSz &&
105 DependencySz == Against.DependencySz &&
106 VerFileSz == Against.VerFileSz &&
107 DescFileSz == Against.DescFileSz &&
108 ProvidesSz == Against.ProvidesSz)
109 return true;
110 return false;
111 }
112 /*}}}*/
113
114 // Cache::pkgCache - Constructor /*{{{*/
115 // ---------------------------------------------------------------------
116 /* */
117 pkgCache::pkgCache(MMap *Map, bool DoMap) : Map(*Map)
118 {
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;
123 if (DoMap == true)
124 ReMap();
125 }
126 /*}}}*/
127 // Cache::ReMap - Reopen the cache file /*{{{*/
128 // ---------------------------------------------------------------------
129 /* If the file is already closed then this will open it open it. */
130 bool pkgCache::ReMap(bool const &Errorchecks)
131 {
132 // Apply the typecasts.
133 HeaderP = (Header *)Map.Data();
134 GrpP = (Group *)Map.Data();
135 PkgP = (Package *)Map.Data();
136 VerFileP = (VerFile *)Map.Data();
137 DescFileP = (DescFile *)Map.Data();
138 PkgFileP = (PackageFile *)Map.Data();
139 VerP = (Version *)Map.Data();
140 DescP = (Description *)Map.Data();
141 ProvideP = (Provides *)Map.Data();
142 DepP = (Dependency *)Map.Data();
143 StrP = (char *)Map.Data();
144
145 if (Errorchecks == false)
146 return true;
147
148 if (Map.Size() == 0 || HeaderP == 0)
149 return _error->Error(_("Empty package cache"));
150
151 // Check the header
152 Header DefHeader;
153 if (HeaderP->Signature != DefHeader.Signature ||
154 HeaderP->Dirty == true)
155 return _error->Error(_("The package cache file is corrupted"));
156
157 if (HeaderP->MajorVersion != DefHeader.MajorVersion ||
158 HeaderP->MinorVersion != DefHeader.MinorVersion ||
159 HeaderP->CheckSizes(DefHeader) == false)
160 return _error->Error(_("The package cache file is an incompatible version"));
161
162 if (Map.Size() < HeaderP->CacheFileSize)
163 return _error->Error(_("The package cache file is corrupted, it is too small"));
164
165 if (HeaderP->VerSysName == 0 || HeaderP->Architecture == 0 || HeaderP->Architectures == 0)
166 return _error->Error(_("The package cache file is corrupted"));
167
168 // Locate our VS..
169 if ((VS = pkgVersioningSystem::GetVS(StrP + HeaderP->VerSysName)) == 0)
170 return _error->Error(_("This APT does not support the versioning system '%s'"),StrP + HeaderP->VerSysName);
171
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
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) */
190 map_id_t pkgCache::sHash(const string &Str) const
191 {
192 unsigned long Hash = 0;
193 for (string::const_iterator I = Str.begin(); I != Str.end(); ++I)
194 Hash = 41 * Hash + tolower_ascii(*I);
195 return Hash % HeaderP->HashTableSize;
196 }
197
198 map_id_t pkgCache::sHash(const char *Str) const
199 {
200 unsigned long Hash = tolower_ascii(*Str);
201 for (const char *I = Str + 1; *I != 0; ++I)
202 Hash = 41 * Hash + tolower_ascii(*I);
203 return Hash % HeaderP->HashTableSize;
204 }
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… */
211 pkgCache::PkgIterator pkgCache::SingleArchFindPkg(const string &Name)
212 {
213 // Look at the hash bucket
214 Package *Pkg = PkgP + HeaderP->PkgHashTable()[Hash(Name)];
215 for (; Pkg != PkgP; Pkg = PkgP + Pkg->Next)
216 {
217 int const cmp = strcmp(Name.c_str(), StrP + (GrpP + Pkg->Group)->Name);
218 if (cmp == 0)
219 return PkgIterator(*this, Pkg);
220 else if (cmp < 0)
221 break;
222 }
223 return PkgIterator(*this,0);
224 }
225 /*}}}*/
226 // Cache::FindPkg - Locate a package by name /*{{{*/
227 // ---------------------------------------------------------------------
228 /* Returns 0 on error, pointer to the package otherwise */
229 pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) {
230 size_t const found = Name.find(':');
231 if (found == string::npos)
232 {
233 if (MultiArchCache() == false)
234 return SingleArchFindPkg(Name);
235 else
236 return FindPkg(Name, "native");
237 }
238 string const Arch = Name.substr(found+1);
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) */
242 if (Arch == "any")
243 return FindPkg(Name, "any");
244 return FindPkg(Name.substr(0, found), Arch);
245 }
246 /*}}}*/
247 // Cache::FindPkg - Locate a package by name /*{{{*/
248 // ---------------------------------------------------------------------
249 /* Returns 0 on error, pointer to the package otherwise */
250 pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string const &Arch) {
251 if (MultiArchCache() == false && Arch != "none") {
252 if (Arch == "native" || Arch == "all" || Arch == "any" ||
253 Arch == NativeArch())
254 return SingleArchFindPkg(Name);
255 else
256 return PkgIterator(*this,0);
257 }
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 */
271 pkgCache::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
276 Group *Grp = GrpP + HeaderP->GrpHashTable()[sHash(Name)];
277 for (; Grp != GrpP; Grp = GrpP + Grp->Next) {
278 int const cmp = strcmp(Name.c_str(), StrP + Grp->Name);
279 if (cmp == 0)
280 return GrpIterator(*this, Grp);
281 else if (cmp < 0)
282 break;
283 }
284
285 return GrpIterator(*this,0);
286 }
287 /*}}}*/
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.. */
292 const char *pkgCache::CompTypeDeb(unsigned char Comp)
293 {
294 const char * const Ops[] = {"","<=",">=","<<",">>","=","!="};
295 if (unlikely((unsigned)(Comp & 0xF) >= sizeof(Ops)/sizeof(Ops[0])))
296 return "";
297 return Ops[Comp & 0xF];
298 }
299 /*}}}*/
300 // Cache::CompType - Return a string describing the compare type /*{{{*/
301 // ---------------------------------------------------------------------
302 /* This returns a string representation of the dependency compare
303 type */
304 const char *pkgCache::CompType(unsigned char Comp)
305 {
306 const char * const Ops[] = {"","<=",">=","<",">","=","!="};
307 if (unlikely((unsigned)(Comp & 0xF) >= sizeof(Ops)/sizeof(Ops[0])))
308 return "";
309 return Ops[Comp & 0xF];
310 }
311 /*}}}*/
312 // Cache::DepType - Return a string describing the dep type /*{{{*/
313 // ---------------------------------------------------------------------
314 /* */
315 const char *pkgCache::DepType(unsigned char Type)
316 {
317 const char *Types[] = {"",_("Depends"),_("PreDepends"),_("Suggests"),
318 _("Recommends"),_("Conflicts"),_("Replaces"),
319 _("Obsoletes"),_("Breaks"), _("Enhances")};
320 if (Type < sizeof(Types)/sizeof(*Types))
321 return Types[Type];
322 return "";
323 }
324 /*}}}*/
325 // Cache::Priority - Convert a priority value to a string /*{{{*/
326 // ---------------------------------------------------------------------
327 /* */
328 const char *pkgCache::Priority(unsigned char Prio)
329 {
330 const char *Mapping[] = {0,_("important"),_("required"),_("standard"),
331 _("optional"),_("extra")};
332 if (Prio < _count(Mapping))
333 return Mapping[Prio];
334 return 0;
335 }
336 /*}}}*/
337 // GrpIterator::FindPkg - Locate a package by arch /*{{{*/
338 // ---------------------------------------------------------------------
339 /* Returns an End-Pointer on error, pointer to the package otherwise */
340 pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) const {
341 if (unlikely(IsGood() == false || S->FirstPackage == 0))
342 return PkgIterator(*Owner, 0);
343
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
349 char const* const myArch = Owner->NativeArch();
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. */
353 if (Arch == "native" || Arch == myArch || Arch == "all") {
354 pkgCache::Package *Pkg = Owner->PkgP + S->LastPackage;
355 if (strcmp(myArch, Owner->StrP + Pkg->Arch) == 0)
356 return PkgIterator(*Owner, Pkg);
357 Arch = myArch;
358 }
359
360 // Iterate over the list to find the matching arch
361 for (pkgCache::Package *Pkg = PackageList(); Pkg != Owner->PkgP;
362 Pkg = Owner->PkgP + Pkg->Next) {
363 if (stringcmp(Arch, Owner->StrP + Pkg->Arch) == 0)
364 return PkgIterator(*Owner, Pkg);
365 if ((Owner->PkgP + S->LastPackage) == Pkg)
366 break;
367 }
368
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 */
375 pkgCache::PkgIterator pkgCache::GrpIterator::FindPreferredPkg(bool const &PreferNonVirtual) const {
376 pkgCache::PkgIterator Pkg = FindPkg("native");
377 if (Pkg.end() == false && (PreferNonVirtual == false || Pkg->VersionList != 0))
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);
384 if (Pkg.end() == false && (PreferNonVirtual == false || Pkg->VersionList != 0))
385 return Pkg;
386 }
387 // packages without an architecture
388 Pkg = FindPkg("none");
389 if (Pkg.end() == false && (PreferNonVirtual == false || Pkg->VersionList != 0))
390 return Pkg;
391
392 if (PreferNonVirtual == true)
393 return FindPreferredPkg(false);
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.
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) */
402 pkgCache::PkgIterator pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator const &LastPkg) const {
403 if (unlikely(IsGood() == false || S->FirstPackage == 0 ||
404 LastPkg.end() == true))
405 return PkgIterator(*Owner, 0);
406
407 if (S->LastPackage == LastPkg.Index())
408 return PkgIterator(*Owner, 0);
409
410 return PkgIterator(*Owner, Owner->PkgP + LastPkg->Next);
411 }
412 /*}}}*/
413 // GrpIterator::operator ++ - Postfix incr /*{{{*/
414 // ---------------------------------------------------------------------
415 /* This will advance to the next logical group in the hash table. */
416 void pkgCache::GrpIterator::operator ++(int)
417 {
418 // Follow the current links
419 if (S != Owner->GrpP)
420 S = Owner->GrpP + S->Next;
421
422 // Follow the hash table
423 while (S == Owner->GrpP && (HashIndex+1) < (signed)Owner->HeaderP->HashTableSize)
424 {
425 HashIndex++;
426 S = Owner->GrpP + Owner->HeaderP->GrpHashTable()[HashIndex];
427 }
428 }
429 /*}}}*/
430 // PkgIterator::operator ++ - Postfix incr /*{{{*/
431 // ---------------------------------------------------------------------
432 /* This will advance to the next logical package in the hash table. */
433 void pkgCache::PkgIterator::operator ++(int)
434 {
435 // Follow the current links
436 if (S != Owner->PkgP)
437 S = Owner->PkgP + S->Next;
438
439 // Follow the hash table
440 while (S == Owner->PkgP && (HashIndex+1) < (signed)Owner->HeaderP->HashTableSize)
441 {
442 HashIndex++;
443 S = Owner->PkgP + Owner->HeaderP->PkgHashTable()[HashIndex];
444 }
445 }
446 /*}}}*/
447 // PkgIterator::State - Check the State of the package /*{{{*/
448 // ---------------------------------------------------------------------
449 /* By this we mean if it is either cleanly installed or cleanly removed. */
450 pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const
451 {
452 if (S->InstState == pkgCache::State::ReInstReq ||
453 S->InstState == pkgCache::State::HoldReInstReq)
454 return NeedsUnpack;
455
456 if (S->CurrentState == pkgCache::State::UnPacked ||
457 S->CurrentState == pkgCache::State::HalfConfigured)
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
462 //Pkg->CurrentState == pkgCache::State::TriggersAwaited
463 //Pkg->CurrentState == pkgCache::State::TriggersPending)
464 return NeedsConfigure;
465
466 if (S->CurrentState == pkgCache::State::HalfInstalled ||
467 S->InstState != pkgCache::State::Ok)
468 return NeedsUnpack;
469
470 return NeedsNothing;
471 }
472 /*}}}*/
473 // PkgIterator::CandVersion - Returns the candidate version string /*{{{*/
474 // ---------------------------------------------------------------------
475 /* Return string representing of the candidate version. */
476 const char *
477 pkgCache::PkgIterator::CandVersion() const
478 {
479 //TargetVer is empty, so don't use it.
480 VerIterator version = pkgPolicy(Owner).GetCandidateVer(*this);
481 if (version.IsGood())
482 return version.VerStr();
483 return 0;
484 }
485 /*}}}*/
486 // PkgIterator::CurVersion - Returns the current version string /*{{{*/
487 // ---------------------------------------------------------------------
488 /* Return string representing of the current version. */
489 const char *
490 pkgCache::PkgIterator::CurVersion() const
491 {
492 VerIterator version = CurrentVer();
493 if (version.IsGood())
494 return CurrentVer().VerStr();
495 return 0;
496 }
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)
501 Note that the characters <|>() are all literal above. Versions will be omitted
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. */
504 std::ostream&
505 operator<<(std::ostream& out, pkgCache::PkgIterator Pkg)
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
514 out << Pkg.Name() << " [ " << Pkg.Arch() << " ] < " << current;
515 if (current != candidate)
516 out << " -> " << candidate;
517 if ( newest != "none" && candidate != newest)
518 out << " | " << newest;
519 if (Pkg->VersionList == 0)
520 out << " > ( none )";
521 else
522 out << " > ( " << string(Pkg.VersionList().Section()==0?"unknown":Pkg.VersionList().Section()) << " )";
523 return out;
524 }
525 /*}}}*/
526 // PkgIterator::FullName - Returns Name and (maybe) Architecture /*{{{*/
527 // ---------------------------------------------------------------------
528 /* Returns a name:arch string */
529 std::string pkgCache::PkgIterator::FullName(bool const &Pretty) const
530 {
531 string fullname = Name();
532 if (Pretty == false ||
533 (strcmp(Arch(), "all") != 0 &&
534 strcmp(Owner->NativeArch(), Arch()) != 0))
535 return fullname.append(":").append(Arch());
536 return fullname;
537 }
538 /*}}}*/
539 // DepIterator::IsCritical - Returns true if the dep is important /*{{{*/
540 // ---------------------------------------------------------------------
541 /* Currently critical deps are defined as depends, predepends and
542 conflicts (including dpkg's Breaks fields). */
543 bool pkgCache::DepIterator::IsCritical() const
544 {
545 if (IsNegative() == true ||
546 S->Type == pkgCache::Dep::Depends ||
547 S->Type == pkgCache::Dep::PreDepends)
548 return true;
549 return false;
550 }
551 /*}}}*/
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 */
556 bool pkgCache::DepIterator::IsNegative() const
557 {
558 return S->Type == Dep::DpkgBreaks ||
559 S->Type == Dep::Conflicts ||
560 S->Type == Dep::Obsoletes;
561 }
562 /*}}}*/
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
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. */
576 bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator &Result) const
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();
593 for (; PStart.end() != true && PStart.OwnerPkg() == ParentPkg(); ++PStart);
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;
601 for (; P.end() != true; ++P)
602 {
603 // Skip over self provides
604 if (P.OwnerPkg() == ParentPkg())
605 continue;
606 if (PStart.OwnerPkg() != P.OwnerPkg())
607 break;
608 }
609
610 Result = PStart.OwnerPkg();
611
612 // Check for non dups
613 if (P.end() != true)
614 return true;
615
616 return false;
617 }
618 /*}}}*/
619 // DepIterator::AllTargets - Returns the set of all possible targets /*{{{*/
620 // ---------------------------------------------------------------------
621 /* This is a more useful version of TargetPkg() that follows versioned
622 provides. It includes every possible package-version that could satisfy
623 the dependency. The last item in the list has a 0. The resulting pointer
624 must be delete [] 'd */
625 pkgCache::Version **pkgCache::DepIterator::AllTargets() const
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
635 for (VerIterator I = DPkg.VersionList(); I.end() == false; ++I)
636 {
637 if (IsIgnorable(I.ParentPkg()) == true)
638 continue;
639 if (IsSatisfied(I) == false)
640 continue;
641
642 Size++;
643 if (Res != 0)
644 *End++ = I;
645 }
646
647 // Follow all provides
648 for (PrvIterator I = DPkg.ProvidesList(); I.end() == false; ++I)
649 {
650 if (IsIgnorable(I) == true)
651 continue;
652 if (IsSatisfied(I) == false)
653 continue;
654
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 /*}}}*/
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. */
682 void pkgCache::DepIterator::GlobOr(DepIterator &Start,DepIterator &End)
683 {
684 // Compute a single dependency element (glob or)
685 Start = *this;
686 End = *this;
687 for (bool LastOR = true; end() == false && LastOR == true;)
688 {
689 LastOR = (S->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
690 (*this)++;
691 if (LastOR == true)
692 End = (*this);
693 }
694 }
695 /*}}}*/
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. */
700 bool pkgCache::DepIterator::IsIgnorable(PkgIterator const &/*Pkg*/) const
701 {
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 }
725
726 return false;
727 }
728 bool 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 /*}}}*/
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… */
750 bool pkgCache::DepIterator::IsMultiArchImplicit() const
751 {
752 if (ParentPkg()->Arch != TargetPkg()->Arch &&
753 (S->Type == pkgCache::Dep::Replaces ||
754 S->Type == pkgCache::Dep::DpkgBreaks ||
755 S->Type == pkgCache::Dep::Conflicts))
756 return true;
757 return false;
758 }
759 /*}}}*/
760 // DepIterator::IsSatisfied - check if a version satisfied the dependency /*{{{*/
761 bool pkgCache::DepIterator::IsSatisfied(VerIterator const &Ver) const
762 {
763 return Owner->VS->CheckDep(Ver.VerStr(),S->CompareOp,TargetVer());
764 }
765 bool pkgCache::DepIterator::IsSatisfied(PrvIterator const &Prv) const
766 {
767 return Owner->VS->CheckDep(Prv.ProvideVersion(),S->CompareOp,TargetVer());
768 }
769 /*}}}*/
770 // ostream operator to handle string representation of a dependecy /*{{{*/
771 // ---------------------------------------------------------------------
772 /* */
773 std::ostream& operator<<(std::ostream& out, pkgCache::DepIterator D)
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 /*}}}*/
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. */
798 int 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;
811 for (;I.end() == false; ++I)
812 if (I == B)
813 return 1;
814 return -1;
815 }
816 /*}}}*/
817 // VerIterator::Downloadable - Checks if the version is downloadable /*{{{*/
818 // ---------------------------------------------------------------------
819 /* */
820 APT_PURE bool pkgCache::VerIterator::Downloadable() const
821 {
822 VerFileIterator Files = FileList();
823 for (; Files.end() == false; ++Files)
824 if ((Files.File()->Flags & pkgCache::Flag::NotSource) != pkgCache::Flag::NotSource)
825 return true;
826 return false;
827 }
828 /*}}}*/
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. */
833 APT_PURE bool pkgCache::VerIterator::Automatic() const
834 {
835 VerFileIterator Files = FileList();
836 for (; Files.end() == false; ++Files)
837 // Do not check ButAutomaticUpgrades here as it is kind of automatic…
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.*/
847 pkgCache::VerFileIterator pkgCache::VerIterator::NewestFile() const
848 {
849 VerFileIterator Files = FileList();
850 VerFileIterator Highest = Files;
851 for (; Files.end() == false; ++Files)
852 {
853 if (Owner->VS->CmpReleaseVer(Files.File().Version(),Highest.File().Version()) > 0)
854 Highest = Files;
855 }
856
857 return Highest;
858 }
859 /*}}}*/
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 */
864 string pkgCache::VerIterator::RelStr() const
865 {
866 bool First = true;
867 string Res;
868 for (pkgCache::VerFileIterator I = this->FileList(); I.end() == false; ++I)
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;
877 for (pkgCache::VerFileIterator J = this->FileList(); I != J; ++J)
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 }
891 if (File2->Version == 0 || File->Version == 0)
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 }
923 }
924 if (S->ParentPkg != 0)
925 Res.append(" [").append(Arch()).append("]");
926 return Res;
927 }
928 /*}}}*/
929 // VerIterator::MultiArchType - string representing MultiArch flag /*{{{*/
930 const 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 /*}}}*/
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. */
946 bool pkgCache::PkgFileIterator::IsOk()
947 {
948 struct stat Buf;
949 if (stat(FileName(),&Buf) != 0)
950 return false;
951
952 if (Buf.st_size != (signed)S->Size || Buf.st_mtime != S->mtime)
953 return false;
954
955 return true;
956 }
957 /*}}}*/
958 // PkgFileIterator::RelStr - Return the release string /*{{{*/
959 // ---------------------------------------------------------------------
960 /* */
961 string 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();
970 if (Codename() != 0)
971 Res = Res + (Res.empty() == true?"n=":",n=") + Codename();
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();
976 if (Architecture() != 0)
977 Res = Res + (Res.empty() == true?"b=":",b=") + Architecture();
978 return Res;
979 }
980 /*}}}*/
981 // VerIterator::TranslatedDescription - Return the a DescIter for locale/*{{{*/
982 // ---------------------------------------------------------------------
983 /* return a DescIter for the current locale or the default if none is
984 * found
985 */
986 pkgCache::DescIterator pkgCache::VerIterator::TranslatedDescription() const
987 {
988 std::vector<string> const lang = APT::Configuration::getLanguages();
989 for (std::vector<string>::const_iterator l = lang.begin();
990 l != lang.end(); ++l)
991 {
992 pkgCache::DescIterator Desc = DescriptionList();
993 for (; Desc.end() == false; ++Desc)
994 if (*l == Desc.LanguageCode())
995 break;
996 if (Desc.end() == true)
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 }
1010 return Desc;
1011 }
1012 for (pkgCache::DescIterator Desc = DescriptionList();
1013 Desc.end() == false; ++Desc)
1014 if (strcmp(Desc.LanguageCode(), "") == 0)
1015 return Desc;
1016 return DescriptionList();
1017 }
1018
1019 /*}}}*/
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… */
1025 bool pkgCache::PrvIterator::IsMultiArchImplicit() const
1026 {
1027 pkgCache::PkgIterator const Owner = OwnerPkg();
1028 pkgCache::PkgIterator const Parent = ParentPkg();
1029 if (strcmp(Owner.Arch(), Parent.Arch()) != 0 || Owner.Group()->Name == Parent.Group()->Name)
1030 return true;
1031 return false;
1032 }
1033 /*}}}*/
1034 APT_DEPRECATED APT_PURE const char * pkgCache::PkgIterator::Section() const {/*{{{*/
1035 if (S->VersionList == 0)
1036 return 0;
1037 return VersionList().Section();
1038 }
1039 /*}}}*/