]>
git.saurik.com Git - apt.git/blob - apt-pkg/pkgcache.cc
   1 // -*- mode: cpp; mode: fold -*- 
   3 // $Id: pkgcache.cc,v 1.37 2003/02/10 01:40:58 doogie Exp $ 
   4 /* ###################################################################### 
   6    Package Cache - Accessor code for the cache 
   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!! 
  11    This is the general utility functions for cache managment. 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. 
  17    The main class provides for ways to get package indexes and some 
  18    general lookup functions to start the iterators. 
  20    ##################################################################### */ 
  22 // Include Files                                                        /*{{{*/ 
  23 #include <apt-pkg/pkgcache.h> 
  24 #include <apt-pkg/policy.h> 
  25 #include <apt-pkg/version.h> 
  26 #include <apt-pkg/error.h> 
  27 #include <apt-pkg/strutl.h> 
  28 #include <apt-pkg/configuration.h> 
  29 #include <apt-pkg/aptconfiguration.h> 
  30 #include <apt-pkg/macros.h> 
  44 // Cache::Header::Header - Constructor                                  /*{{{*/ 
  45 // --------------------------------------------------------------------- 
  46 /* Simply initialize the header */ 
  47 pkgCache::Header::Header() 
  49    Signature 
= 0x98FE76DC; 
  51    /* Whenever the structures change the major version should be bumped, 
  52       whenever the generator changes the minor version should be bumped. */ 
  57    HeaderSz 
= sizeof(pkgCache::Header
); 
  58    GroupSz 
= sizeof(pkgCache::Group
); 
  59    PackageSz 
= sizeof(pkgCache::Package
); 
  60    PackageFileSz 
= sizeof(pkgCache::PackageFile
); 
  61    VersionSz 
= sizeof(pkgCache::Version
); 
  62    DescriptionSz 
= sizeof(pkgCache::Description
); 
  63    DependencySz 
= sizeof(pkgCache::Dependency
); 
  64    ProvidesSz 
= sizeof(pkgCache::Provides
); 
  65    VerFileSz 
= sizeof(pkgCache::VerFile
); 
  66    DescFileSz 
= sizeof(pkgCache::DescFile
); 
  84    memset(PkgHashTable
,0,sizeof(PkgHashTable
)); 
  85    memset(GrpHashTable
,0,sizeof(GrpHashTable
)); 
  86    memset(Pools
,0,sizeof(Pools
)); 
  89 // Cache::Header::CheckSizes - Check if the two headers have same *sz   /*{{{*/ 
  90 // --------------------------------------------------------------------- 
  92 bool pkgCache::Header::CheckSizes(Header 
&Against
) const 
  94    if (HeaderSz 
== Against
.HeaderSz 
&& 
  95        GroupSz 
== Against
.GroupSz 
&& 
  96        PackageSz 
== Against
.PackageSz 
&& 
  97        PackageFileSz 
== Against
.PackageFileSz 
&& 
  98        VersionSz 
== Against
.VersionSz 
&& 
  99        DescriptionSz 
== Against
.DescriptionSz 
&& 
 100        DependencySz 
== Against
.DependencySz 
&& 
 101        VerFileSz 
== Against
.VerFileSz 
&& 
 102        DescFileSz 
== Against
.DescFileSz 
&& 
 103        ProvidesSz 
== Against
.ProvidesSz
) 
 109 // Cache::pkgCache - Constructor                                        /*{{{*/ 
 110 // --------------------------------------------------------------------- 
 112 pkgCache::pkgCache(MMap 
*Map
, bool DoMap
) : Map(*Map
) 
 114    // call getArchitectures() with cached=false to ensure that the  
 115    // architectures cache is re-evaulated. this is needed in cases 
 116    // when the APT::Architecture field changes between two cache creations 
 117    MultiArchEnabled 
= APT::Configuration::getArchitectures(false).size() > 1; 
 122 // Cache::ReMap - Reopen the cache file                                 /*{{{*/ 
 123 // --------------------------------------------------------------------- 
 124 /* If the file is already closed then this will open it open it. */ 
 125 bool pkgCache::ReMap(bool const &Errorchecks
) 
 127    // Apply the typecasts. 
 128    HeaderP 
= (Header 
*)Map
.Data(); 
 129    GrpP 
= (Group 
*)Map
.Data(); 
 130    PkgP 
= (Package 
*)Map
.Data(); 
 131    VerFileP 
= (VerFile 
*)Map
.Data(); 
 132    DescFileP 
= (DescFile 
*)Map
.Data(); 
 133    PkgFileP 
= (PackageFile 
*)Map
.Data(); 
 134    VerP 
= (Version 
*)Map
.Data(); 
 135    DescP 
= (Description 
*)Map
.Data(); 
 136    ProvideP 
= (Provides 
*)Map
.Data(); 
 137    DepP 
= (Dependency 
*)Map
.Data(); 
 138    StringItemP 
= (StringItem 
*)Map
.Data(); 
 139    StrP 
= (char *)Map
.Data(); 
 141    if (Errorchecks 
== false) 
 144    if (Map
.Size() == 0 || HeaderP 
== 0) 
 145       return _error
->Error(_("Empty package cache")); 
 149    if (HeaderP
->Signature 
!= DefHeader
.Signature 
|| 
 150        HeaderP
->Dirty 
== true) 
 151       return _error
->Error(_("The package cache file is corrupted")); 
 153    if (HeaderP
->MajorVersion 
!= DefHeader
.MajorVersion 
|| 
 154        HeaderP
->MinorVersion 
!= DefHeader
.MinorVersion 
|| 
 155        HeaderP
->CheckSizes(DefHeader
) == false) 
 156       return _error
->Error(_("The package cache file is an incompatible version")); 
 159    if (HeaderP
->VerSysName 
== 0 || 
 160        (VS 
= pkgVersioningSystem::GetVS(StrP 
+ HeaderP
->VerSysName
)) == 0) 
 161       return _error
->Error(_("This APT does not support the versioning system '%s'"),StrP 
+ HeaderP
->VerSysName
); 
 163    // Chcek the arhcitecture 
 164    if (HeaderP
->Architecture 
== 0 || 
 165        _config
->Find("APT::Architecture") != StrP 
+ HeaderP
->Architecture
) 
 166       return _error
->Error(_("The package cache was built for a different architecture")); 
 170 // Cache::Hash - Hash a string                                          /*{{{*/ 
 171 // --------------------------------------------------------------------- 
 172 /* This is used to generate the hash entries for the HashTable. With my 
 173    package list from bo this function gets 94% table usage on a 512 item 
 174    table (480 used items) */ 
 175 unsigned long pkgCache::sHash(const string 
&Str
) const 
 177    unsigned long Hash 
= 0; 
 178    for (string::const_iterator I 
= Str
.begin(); I 
!= Str
.end(); I
++) 
 179       Hash 
= 5*Hash 
+ tolower_ascii(*I
); 
 180    return Hash 
% _count(HeaderP
->PkgHashTable
); 
 183 unsigned long pkgCache::sHash(const char *Str
) const 
 185    unsigned long Hash 
= 0; 
 186    for (const char *I 
= Str
; *I 
!= 0; I
++) 
 187       Hash 
= 5*Hash 
+ tolower_ascii(*I
); 
 188    return Hash 
% _count(HeaderP
->PkgHashTable
); 
 192 // Cache::SingleArchFindPkg - Locate a package by name                  /*{{{*/ 
 193 // --------------------------------------------------------------------- 
 194 /* Returns 0 on error, pointer to the package otherwise 
 195    The multiArch enabled methods will fallback to this one as it is (a bit) 
 196    faster for single arch environments and realworld is mostly singlearch… */ 
 197 pkgCache::PkgIterator 
pkgCache::SingleArchFindPkg(const string 
&Name
) 
 199    // Look at the hash bucket 
 200    Package 
*Pkg 
= PkgP 
+ HeaderP
->PkgHashTable
[Hash(Name
)]; 
 201    for (; Pkg 
!= PkgP
; Pkg 
= PkgP 
+ Pkg
->NextPackage
) 
 203       if (Pkg
->Name 
!= 0 && StrP
[Pkg
->Name
] == Name
[0] && 
 204           stringcasecmp(Name
,StrP 
+ Pkg
->Name
) == 0) 
 205          return PkgIterator(*this,Pkg
); 
 207    return PkgIterator(*this,0); 
 210 // Cache::FindPkg - Locate a package by name                            /*{{{*/ 
 211 // --------------------------------------------------------------------- 
 212 /* Returns 0 on error, pointer to the package otherwise */ 
 213 pkgCache::PkgIterator 
pkgCache::FindPkg(const string 
&Name
) { 
 214         size_t const found 
= Name
.find(':'); 
 215         if (found 
== string::npos
) 
 217                 if (MultiArchCache() == false) 
 218                         return SingleArchFindPkg(Name
); 
 220                         return FindPkg(Name
, "native"); 
 222         string 
const Arch 
= Name
.substr(found
+1); 
 223         /* Beware: This is specialcased to handle pkg:any in dependencies as 
 224            these are linked to virtual pkg:any named packages with all archs. 
 225            If you want any arch from a given pkg, use FindPkg(pkg,arch) */ 
 227                 return FindPkg(Name
, "any"); 
 228         return FindPkg(Name
.substr(0, found
), Arch
); 
 231 // Cache::FindPkg - Locate a package by name                            /*{{{*/ 
 232 // --------------------------------------------------------------------- 
 233 /* Returns 0 on error, pointer to the package otherwise */ 
 234 pkgCache::PkgIterator 
pkgCache::FindPkg(const string 
&Name
, string 
const &Arch
) { 
 235         if (MultiArchCache() == false) { 
 236                 if (Arch 
== "native" || Arch 
== "all" || Arch 
== "any" || 
 237                     Arch 
== NativeArch()) 
 238                         return SingleArchFindPkg(Name
); 
 240                         return PkgIterator(*this,0); 
 242         /* We make a detour via the GrpIterator here as 
 243            on a multi-arch environment a group is easier to 
 244            find than a package (less entries in the buckets) */ 
 245         pkgCache::GrpIterator Grp 
= FindGrp(Name
); 
 246         if (Grp
.end() == true) 
 247                 return PkgIterator(*this,0); 
 249         return Grp
.FindPkg(Arch
); 
 252 // Cache::FindGrp - Locate a group by name                              /*{{{*/ 
 253 // --------------------------------------------------------------------- 
 254 /* Returns End-Pointer on error, pointer to the group otherwise */ 
 255 pkgCache::GrpIterator 
pkgCache::FindGrp(const string 
&Name
) { 
 256         if (unlikely(Name
.empty() == true)) 
 257                 return GrpIterator(*this,0); 
 259         // Look at the hash bucket for the group 
 260         Group 
*Grp 
= GrpP 
+ HeaderP
->GrpHashTable
[sHash(Name
)]; 
 261         for (; Grp 
!= GrpP
; Grp 
= GrpP 
+ Grp
->Next
) { 
 262                 if (Grp
->Name 
!= 0 && StrP
[Grp
->Name
] == Name
[0] && 
 263                     stringcasecmp(Name
, StrP 
+ Grp
->Name
) == 0) 
 264                         return GrpIterator(*this, Grp
); 
 267         return GrpIterator(*this,0); 
 270 // Cache::CompTypeDeb - Return a string describing the compare type     /*{{{*/ 
 271 // --------------------------------------------------------------------- 
 272 /* This returns a string representation of the dependency compare  
 273    type in the weird debian style.. */ 
 274 const char *pkgCache::CompTypeDeb(unsigned char Comp
) 
 276    const char *Ops
[] = {"","<=",">=","<<",">>","=","!="}; 
 277    if ((unsigned)(Comp 
& 0xF) < 7) 
 278       return Ops
[Comp 
& 0xF]; 
 282 // Cache::CompType - Return a string describing the compare type        /*{{{*/ 
 283 // --------------------------------------------------------------------- 
 284 /* This returns a string representation of the dependency compare  
 286 const char *pkgCache::CompType(unsigned char Comp
) 
 288    const char *Ops
[] = {"","<=",">=","<",">","=","!="}; 
 289    if ((unsigned)(Comp 
& 0xF) < 7) 
 290       return Ops
[Comp 
& 0xF]; 
 294 // Cache::DepType - Return a string describing the dep type             /*{{{*/ 
 295 // --------------------------------------------------------------------- 
 297 const char *pkgCache::DepType(unsigned char Type
) 
 299    const char *Types
[] = {"",_("Depends"),_("PreDepends"),_("Suggests"), 
 300                           _("Recommends"),_("Conflicts"),_("Replaces"), 
 301                           _("Obsoletes"),_("Breaks"), _("Enhances")}; 
 302    if (Type 
< sizeof(Types
)/sizeof(*Types
)) 
 307 // Cache::Priority - Convert a priority value to a string               /*{{{*/ 
 308 // --------------------------------------------------------------------- 
 310 const char *pkgCache::Priority(unsigned char Prio
) 
 312    const char *Mapping
[] = {0,_("important"),_("required"),_("standard"), 
 313                             _("optional"),_("extra")}; 
 314    if (Prio 
< _count(Mapping
)) 
 315       return Mapping
[Prio
]; 
 319 // GrpIterator::FindPkg - Locate a package by arch                      /*{{{*/ 
 320 // --------------------------------------------------------------------- 
 321 /* Returns an End-Pointer on error, pointer to the package otherwise */ 
 322 pkgCache::PkgIterator 
pkgCache::GrpIterator::FindPkg(string Arch
) const { 
 323         if (unlikely(IsGood() == false || S
->FirstPackage 
== 0)) 
 324                 return PkgIterator(*Owner
, 0); 
 326         /* If we accept any package we simply return the "first" 
 327            package in this group (the last one added). */ 
 329                 return PkgIterator(*Owner
, Owner
->PkgP 
+ S
->FirstPackage
); 
 331         char const* const myArch 
= Owner
->NativeArch(); 
 332         /* Most of the time the package for our native architecture is 
 333            the one we add at first to the cache, but this would be the 
 334            last one we check, so we do it now. */ 
 335         if (Arch 
== "native" || Arch 
== myArch 
|| Arch 
== "all") { 
 336                 pkgCache::Package 
*Pkg 
= Owner
->PkgP 
+ S
->LastPackage
; 
 337                 if (strcasecmp(myArch
, Owner
->StrP 
+ Pkg
->Arch
) == 0) 
 338                         return PkgIterator(*Owner
, Pkg
); 
 342         /* Iterate over the list to find the matching arch 
 343            unfortunately this list includes "package noise" 
 344            (= different packages with same calculated hash), 
 345            so we need to check the name also */ 
 346         for (pkgCache::Package 
*Pkg 
= PackageList(); Pkg 
!= Owner
->PkgP
; 
 347              Pkg 
= Owner
->PkgP 
+ Pkg
->NextPackage
) { 
 348                 if (S
->Name 
== Pkg
->Name 
&& 
 349                     stringcasecmp(Arch
, Owner
->StrP 
+ Pkg
->Arch
) == 0) 
 350                         return PkgIterator(*Owner
, Pkg
); 
 351                 if ((Owner
->PkgP 
+ S
->LastPackage
) == Pkg
) 
 355         return PkgIterator(*Owner
, 0); 
 358 // GrpIterator::FindPreferredPkg - Locate the "best" package            /*{{{*/ 
 359 // --------------------------------------------------------------------- 
 360 /* Returns an End-Pointer on error, pointer to the package otherwise */ 
 361 pkgCache::PkgIterator 
pkgCache::GrpIterator::FindPreferredPkg(bool const &PreferNonVirtual
) const { 
 362         pkgCache::PkgIterator Pkg 
= FindPkg("native"); 
 363         if (Pkg
.end() == false && (PreferNonVirtual 
== false || Pkg
->VersionList 
!= 0)) 
 366         std::vector
<std::string
> const archs 
= APT::Configuration::getArchitectures(); 
 367         for (std::vector
<std::string
>::const_iterator a 
= archs
.begin(); 
 368              a 
!= archs
.end(); ++a
) { 
 370                 if (Pkg
.end() == false && (PreferNonVirtual 
== false || Pkg
->VersionList 
!= 0)) 
 374         if (PreferNonVirtual 
== true) 
 375                 return FindPreferredPkg(false); 
 376         return PkgIterator(*Owner
, 0); 
 379 // GrpIterator::NextPkg - Locate the next package in the group          /*{{{*/ 
 380 // --------------------------------------------------------------------- 
 381 /* Returns an End-Pointer on error, pointer to the package otherwise. 
 382    We can't simply ++ to the next as the next package of the last will 
 383    be from a different group (with the same hash value) */ 
 384 pkgCache::PkgIterator 
pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator 
const &LastPkg
) const { 
 385         if (unlikely(IsGood() == false || S
->FirstPackage 
== 0 || 
 386             LastPkg
.end() == true)) 
 387                 return PkgIterator(*Owner
, 0); 
 389         if (S
->LastPackage 
== LastPkg
.Index()) 
 390                 return PkgIterator(*Owner
, 0); 
 392         return PkgIterator(*Owner
, Owner
->PkgP 
+ LastPkg
->NextPackage
); 
 395 // GrpIterator::operator ++ - Postfix incr                              /*{{{*/ 
 396 // --------------------------------------------------------------------- 
 397 /* This will advance to the next logical group in the hash table. */ 
 398 void pkgCache::GrpIterator::operator ++(int)  
 400    // Follow the current links 
 401    if (S 
!= Owner
->GrpP
) 
 402       S 
= Owner
->GrpP 
+ S
->Next
; 
 404    // Follow the hash table 
 405    while (S 
== Owner
->GrpP 
&& (HashIndex
+1) < (signed)_count(Owner
->HeaderP
->GrpHashTable
)) 
 408       S 
= Owner
->GrpP 
+ Owner
->HeaderP
->GrpHashTable
[HashIndex
]; 
 412 // PkgIterator::operator ++ - Postfix incr                              /*{{{*/ 
 413 // --------------------------------------------------------------------- 
 414 /* This will advance to the next logical package in the hash table. */ 
 415 void pkgCache::PkgIterator::operator ++(int)  
 417    // Follow the current links 
 418    if (S 
!= Owner
->PkgP
) 
 419       S 
= Owner
->PkgP 
+ S
->NextPackage
; 
 421    // Follow the hash table 
 422    while (S 
== Owner
->PkgP 
&& (HashIndex
+1) < (signed)_count(Owner
->HeaderP
->PkgHashTable
)) 
 425       S 
= Owner
->PkgP 
+ Owner
->HeaderP
->PkgHashTable
[HashIndex
]; 
 429 // PkgIterator::State - Check the State of the package                  /*{{{*/ 
 430 // --------------------------------------------------------------------- 
 431 /* By this we mean if it is either cleanly installed or cleanly removed. */ 
 432 pkgCache::PkgIterator::OkState 
pkgCache::PkgIterator::State() const 
 434    if (S
->InstState 
== pkgCache::State::ReInstReq 
|| 
 435        S
->InstState 
== pkgCache::State::HoldReInstReq
) 
 438    if (S
->CurrentState 
== pkgCache::State::UnPacked 
|| 
 439        S
->CurrentState 
== pkgCache::State::HalfConfigured
) 
 440       // we leave triggers alone complettely. dpkg deals with 
 441       // them in a hard-to-predict manner and if they get  
 442       // resolved by dpkg before apt run dpkg --configure on  
 443       // the TriggersPending package dpkg returns a error 
 444       //Pkg->CurrentState == pkgCache::State::TriggersAwaited 
 445       //Pkg->CurrentState == pkgCache::State::TriggersPending) 
 446       return NeedsConfigure
; 
 448    if (S
->CurrentState 
== pkgCache::State::HalfInstalled 
|| 
 449        S
->InstState 
!= pkgCache::State::Ok
) 
 455 // PkgIterator::CandVersion - Returns the candidate version string      /*{{{*/ 
 456 // --------------------------------------------------------------------- 
 457 /* Return string representing of the candidate version. */ 
 459 pkgCache::PkgIterator::CandVersion() const  
 461   //TargetVer is empty, so don't use it. 
 462   VerIterator version 
= pkgPolicy(Owner
).GetCandidateVer(*this); 
 463   if (version
.IsGood()) 
 464     return version
.VerStr(); 
 468 // PkgIterator::CurVersion - Returns the current version string         /*{{{*/ 
 469 // --------------------------------------------------------------------- 
 470 /* Return string representing of the current version. */ 
 472 pkgCache::PkgIterator::CurVersion() const  
 474   VerIterator version 
= CurrentVer(); 
 475   if (version
.IsGood()) 
 476     return CurrentVer().VerStr(); 
 480 // ostream operator to handle string representation of a package        /*{{{*/ 
 481 // --------------------------------------------------------------------- 
 482 /* Output name < cur.rent.version -> candid.ate.version | new.est.version > (section) 
 483    Note that the characters <|>() are all literal above. Versions will be ommited 
 484    if they provide no new information (e.g. there is no newer version than candidate) 
 485    If no version and/or section can be found "none" is used. */ 
 487 operator<<(ostream
& out
, pkgCache::PkgIterator Pkg
)  
 489    if (Pkg
.end() == true) 
 490       return out 
<< "invalid package"; 
 492    string current 
= string(Pkg
.CurVersion() == 0 ? "none" : Pkg
.CurVersion()); 
 493    string candidate 
= string(Pkg
.CandVersion() == 0 ? "none" : Pkg
.CandVersion()); 
 494    string newest 
= string(Pkg
.VersionList().end() ? "none" : Pkg
.VersionList().VerStr()); 
 496    out 
<< Pkg
.Name() << " [ " << Pkg
.Arch() << " ] < " << current
; 
 497    if (current 
!= candidate
) 
 498       out 
<< " -> " << candidate
; 
 499    if ( newest 
!= "none" && candidate 
!= newest
) 
 500       out 
<< " | " << newest
; 
 501    out 
<< " > ( " << string(Pkg
.Section()==0?"none":Pkg
.Section()) << " )"; 
 505 // PkgIterator::FullName - Returns Name and (maybe) Architecture        /*{{{*/ 
 506 // --------------------------------------------------------------------- 
 507 /* Returns a name:arch string */ 
 508 std::string 
pkgCache::PkgIterator::FullName(bool const &Pretty
) const 
 510    string fullname 
= Name(); 
 511    if (Pretty 
== false || 
 512        (strcmp(Arch(), "all") != 0 && 
 513         strcmp(Owner
->NativeArch(), Arch()) != 0)) 
 514       return fullname
.append(":").append(Arch()); 
 518 // DepIterator::IsCritical - Returns true if the dep is important       /*{{{*/ 
 519 // --------------------------------------------------------------------- 
 520 /* Currently critical deps are defined as depends, predepends and 
 521    conflicts (including dpkg's Breaks fields). */ 
 522 bool pkgCache::DepIterator::IsCritical() const 
 524    if (IsNegative() == true || 
 525        S
->Type 
== pkgCache::Dep::Depends 
|| 
 526        S
->Type 
== pkgCache::Dep::PreDepends
) 
 531 // DepIterator::IsNegative - Returns true if the dep is a negative one  /*{{{*/ 
 532 // --------------------------------------------------------------------- 
 533 /* Some dependencies are positive like Depends and Recommends, others 
 534    are negative like Conflicts which can and should be handled differently */ 
 535 bool pkgCache::DepIterator::IsNegative() const 
 537    return S
->Type 
== Dep::DpkgBreaks 
|| 
 538           S
->Type 
== Dep::Conflicts 
|| 
 539           S
->Type 
== Dep::Obsoletes
; 
 542 // DepIterator::SmartTargetPkg - Resolve dep target pointers w/provides /*{{{*/ 
 543 // --------------------------------------------------------------------- 
 544 /* This intellegently looks at dep target packages and tries to figure 
 545    out which package should be used. This is needed to nicely handle 
 546    provide mapping. If the target package has no other providing packages 
 547    then it returned. Otherwise the providing list is looked at to  
 548    see if there is one one unique providing package if so it is returned. 
 549    Otherwise true is returned and the target package is set. The return 
 550    result indicates whether the node should be expandable  
 552    In Conjunction with the DepCache the value of Result may not be  
 553    super-good since the policy may have made it uninstallable. Using 
 554    AllTargets is better in this case. */ 
 555 bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator 
&Result
) const 
 557    Result 
= TargetPkg(); 
 559    // No provides at all 
 560    if (Result
->ProvidesList 
== 0) 
 563    // There is the Base package and the providing ones which is at least 2 
 564    if (Result
->VersionList 
!= 0) 
 567    /* We have to skip over indirect provisions of the package that 
 568       owns the dependency. For instance, if libc5-dev depends on the 
 569       virtual package libc-dev which is provided by libc5-dev and libc6-dev 
 570       we must ignore libc5-dev when considering the provides list. */  
 571    PrvIterator PStart 
= Result
.ProvidesList(); 
 572    for (; PStart
.end() != true && PStart
.OwnerPkg() == ParentPkg(); PStart
++); 
 574    // Nothing but indirect self provides 
 575    if (PStart
.end() == true) 
 578    // Check for single packages in the provides list 
 579    PrvIterator P 
= PStart
; 
 580    for (; P
.end() != true; P
++) 
 582       // Skip over self provides 
 583       if (P
.OwnerPkg() == ParentPkg()) 
 585       if (PStart
.OwnerPkg() != P
.OwnerPkg()) 
 589    Result 
= PStart
.OwnerPkg(); 
 591    // Check for non dups 
 598 // DepIterator::AllTargets - Returns the set of all possible targets    /*{{{*/ 
 599 // --------------------------------------------------------------------- 
 600 /* This is a more useful version of TargetPkg() that follows versioned 
 601    provides. It includes every possible package-version that could satisfy 
 602    the dependency. The last item in the list has a 0. The resulting pointer 
 603    must be delete [] 'd */ 
 604 pkgCache::Version 
**pkgCache::DepIterator::AllTargets() const 
 607    unsigned long Size 
=0; 
 611       PkgIterator DPkg 
= TargetPkg(); 
 613       // Walk along the actual package providing versions 
 614       for (VerIterator I 
= DPkg
.VersionList(); I
.end() == false; I
++) 
 616          if (Owner
->VS
->CheckDep(I
.VerStr(),S
->CompareOp
,TargetVer()) == false) 
 619          if (IsNegative() == true && 
 620              ParentPkg() == I
.ParentPkg()) 
 628       // Follow all provides 
 629       for (PrvIterator I 
= DPkg
.ProvidesList(); I
.end() == false; I
++) 
 631          if (Owner
->VS
->CheckDep(I
.ProvideVersion(),S
->CompareOp
,TargetVer()) == false) 
 634          if (IsNegative() == true && 
 635              ParentPkg() == I
.OwnerPkg()) 
 640             *End
++ = I
.OwnerVer(); 
 643       // Do it again and write it into the array 
 646          Res 
= new Version 
*[Size
+1]; 
 659 // DepIterator::GlobOr - Compute an OR group                            /*{{{*/ 
 660 // --------------------------------------------------------------------- 
 661 /* This Takes an iterator, iterates past the current dependency grouping 
 662    and returns Start and End so that so End is the final element 
 663    in the group, if End == Start then D is End++ and End is the 
 664    dependency D was pointing to. Use in loops to iterate sensibly. */ 
 665 void pkgCache::DepIterator::GlobOr(DepIterator 
&Start
,DepIterator 
&End
) 
 667    // Compute a single dependency element (glob or) 
 670    for (bool LastOR 
= true; end() == false && LastOR 
== true;) 
 672       LastOR 
= (S
->CompareOp 
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
; 
 679 // ostream operator to handle string representation of a dependecy      /*{{{*/ 
 680 // --------------------------------------------------------------------- 
 682 std::ostream
& operator<<(ostream
& out
, pkgCache::DepIterator D
) 
 685       return out 
<< "invalid dependency"; 
 687    pkgCache::PkgIterator P 
= D
.ParentPkg(); 
 688    pkgCache::PkgIterator T 
= D
.TargetPkg(); 
 690    out 
<< (P
.end() ? "invalid pkg" : P
.FullName(false)) << " " << D
.DepType() 
 693       out 
<< "invalid pkg"; 
 698       out 
<< " (" << D
.CompType() << " " << D
.TargetVer() << ")"; 
 703 // VerIterator::CompareVer - Fast version compare for same pkgs         /*{{{*/ 
 704 // --------------------------------------------------------------------- 
 705 /* This just looks over the version list to see if B is listed before A. In 
 706    most cases this will return in under 4 checks, ver lists are short. */ 
 707 int pkgCache::VerIterator::CompareVer(const VerIterator 
&B
) const 
 709    // Check if they are equal 
 717    /* Start at A and look for B. If B is found then A > B otherwise 
 718       B was before A so A < B */ 
 719    VerIterator I 
= *this; 
 720    for (;I
.end() == false; I
++) 
 726 // VerIterator::Downloadable - Checks if the version is downloadable    /*{{{*/ 
 727 // --------------------------------------------------------------------- 
 729 bool pkgCache::VerIterator::Downloadable() const 
 731    VerFileIterator Files 
= FileList(); 
 732    for (; Files
.end() == false; Files
++) 
 733       if ((Files
.File()->Flags 
& pkgCache::Flag::NotSource
) != pkgCache::Flag::NotSource
) 
 738 // VerIterator::Automatic - Check if this version is 'automatic'        /*{{{*/ 
 739 // --------------------------------------------------------------------- 
 740 /* This checks to see if any of the versions files are not NotAutomatic.  
 741    True if this version is selectable for automatic installation. */ 
 742 bool pkgCache::VerIterator::Automatic() const 
 744    VerFileIterator Files 
= FileList(); 
 745    for (; Files
.end() == false; Files
++) 
 746       // Do not check ButAutomaticUpgrades here as it is kind of automatic… 
 747       if ((Files
.File()->Flags 
& pkgCache::Flag::NotAutomatic
) != pkgCache::Flag::NotAutomatic
) 
 752 // VerIterator::Pseudo - deprecated no-op method                        /*{{{*/ 
 753 bool pkgCache::VerIterator::Pseudo() const { return false; } 
 755 // VerIterator::NewestFile - Return the newest file version relation    /*{{{*/ 
 756 // --------------------------------------------------------------------- 
 757 /* This looks at the version numbers associated with all of the sources 
 758    this version is in and returns the highest.*/ 
 759 pkgCache::VerFileIterator 
pkgCache::VerIterator::NewestFile() const 
 761    VerFileIterator Files 
= FileList(); 
 762    VerFileIterator Highest 
= Files
; 
 763    for (; Files
.end() == false; Files
++) 
 765       if (Owner
->VS
->CmpReleaseVer(Files
.File().Version(),Highest
.File().Version()) > 0) 
 772 // VerIterator::RelStr - Release description string                     /*{{{*/ 
 773 // --------------------------------------------------------------------- 
 774 /* This describes the version from a release-centric manner. The output is a  
 775    list of Label:Version/Archive */ 
 776 string 
pkgCache::VerIterator::RelStr() const 
 780    for (pkgCache::VerFileIterator I 
= this->FileList(); I
.end() == false; I
++) 
 782       // Do not print 'not source' entries' 
 783       pkgCache::PkgFileIterator File 
= I
.File(); 
 784       if ((File
->Flags 
& pkgCache::Flag::NotSource
) == pkgCache::Flag::NotSource
) 
 787       // See if we have already printed this out.. 
 789       for (pkgCache::VerFileIterator J 
= this->FileList(); I 
!= J
; J
++) 
 791          pkgCache::PkgFileIterator File2 
= J
.File(); 
 792          if (File2
->Label 
== 0 || File
->Label 
== 0) 
 795          if (strcmp(File
.Label(),File2
.Label()) != 0) 
 798          if (File2
->Version 
== File
->Version
) 
 803          if (File2
->Version 
== 0 || File
->Version 
== 0) 
 805          if (strcmp(File
.Version(),File2
.Version()) == 0) 
 817       if (File
->Label 
!= 0) 
 818          Res 
= Res 
+ File
.Label() + ':'; 
 820       if (File
->Archive 
!= 0) 
 822          if (File
->Version 
== 0) 
 823             Res 
+= File
.Archive(); 
 825             Res 
= Res 
+ File
.Version() + '/' +  File
.Archive(); 
 829          // No release file, print the host name that this came from 
 830          if (File
->Site 
== 0 || File
.Site()[0] == 0) 
 836    if (S
->ParentPkg 
!= 0) 
 837       Res
.append(" [").append(Arch()).append("]"); 
 841 // PkgFileIterator::IsOk - Checks if the cache is in sync with the file /*{{{*/ 
 842 // --------------------------------------------------------------------- 
 843 /* This stats the file and compares its stats with the ones that were 
 844    stored during generation. Date checks should probably also be  
 846 bool pkgCache::PkgFileIterator::IsOk() 
 849    if (stat(FileName(),&Buf
) != 0) 
 852    if (Buf
.st_size 
!= (signed)S
->Size 
|| Buf
.st_mtime 
!= S
->mtime
) 
 858 // PkgFileIterator::RelStr - Return the release string                  /*{{{*/ 
 859 // --------------------------------------------------------------------- 
 861 string 
pkgCache::PkgFileIterator::RelStr() 
 865       Res 
= Res 
+ (Res
.empty() == true?"v=":",v=") + Version(); 
 867       Res 
= Res 
+ (Res
.empty() == true?"o=":",o=")  + Origin(); 
 869       Res 
= Res 
+ (Res
.empty() == true?"a=":",a=")  + Archive(); 
 871       Res 
= Res 
+ (Res
.empty() == true?"n=":",n=")  + Codename(); 
 873       Res 
= Res 
+ (Res
.empty() == true?"l=":",l=")  + Label(); 
 874    if (Component() != 0) 
 875       Res 
= Res 
+ (Res
.empty() == true?"c=":",c=")  + Component(); 
 876    if (Architecture() != 0) 
 877       Res 
= Res 
+ (Res
.empty() == true?"b=":",b=")  + Architecture(); 
 881 // VerIterator::TranslatedDescription - Return the a DescIter for locale/*{{{*/ 
 882 // --------------------------------------------------------------------- 
 883 /* return a DescIter for the current locale or the default if none is  
 886 pkgCache::DescIterator 
pkgCache::VerIterator::TranslatedDescription() const 
 888    std::vector
<string
> const lang 
= APT::Configuration::getLanguages(); 
 889    for (std::vector
<string
>::const_iterator l 
= lang
.begin(); 
 890         l 
!= lang
.end(); l
++) 
 892       pkgCache::DescIterator Desc 
= DescriptionList(); 
 893       for (; Desc
.end() == false; ++Desc
) 
 894          if (*l 
== Desc
.LanguageCode() || 
 895              (*l 
== "en" && strcmp(Desc
.LanguageCode(),"") == 0)) 
 897       if (Desc
.end() == true) 
 901    for (pkgCache::DescIterator Desc 
= DescriptionList(); 
 902         Desc
.end() == false; ++Desc
) 
 903       if (strcmp(Desc
.LanguageCode(), "") == 0) 
 905    return DescriptionList();