]>
git.saurik.com Git - apt.git/blob - apt-pkg/pkgcache.cc
adaae9c89139361d94c2bd1deb1be819ffc71d35
   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    MultiArchEnabled 
= APT::Configuration::getArchitectures().size() > 1; 
 119 // Cache::ReMap - Reopen the cache file                                 /*{{{*/ 
 120 // --------------------------------------------------------------------- 
 121 /* If the file is already closed then this will open it open it. */ 
 122 bool pkgCache::ReMap() 
 124    // Apply the typecasts. 
 125    HeaderP 
= (Header 
*)Map
.Data(); 
 126    GrpP 
= (Group 
*)Map
.Data(); 
 127    PkgP 
= (Package 
*)Map
.Data(); 
 128    VerFileP 
= (VerFile 
*)Map
.Data(); 
 129    DescFileP 
= (DescFile 
*)Map
.Data(); 
 130    PkgFileP 
= (PackageFile 
*)Map
.Data(); 
 131    VerP 
= (Version 
*)Map
.Data(); 
 132    DescP 
= (Description 
*)Map
.Data(); 
 133    ProvideP 
= (Provides 
*)Map
.Data(); 
 134    DepP 
= (Dependency 
*)Map
.Data(); 
 135    StringItemP 
= (StringItem 
*)Map
.Data(); 
 136    StrP 
= (char *)Map
.Data(); 
 138    if (Map
.Size() == 0 || HeaderP 
== 0) 
 139       return _error
->Error(_("Empty package cache")); 
 143    if (HeaderP
->Signature 
!= DefHeader
.Signature 
|| 
 144        HeaderP
->Dirty 
== true) 
 145       return _error
->Error(_("The package cache file is corrupted")); 
 147    if (HeaderP
->MajorVersion 
!= DefHeader
.MajorVersion 
|| 
 148        HeaderP
->MinorVersion 
!= DefHeader
.MinorVersion 
|| 
 149        HeaderP
->CheckSizes(DefHeader
) == false) 
 150       return _error
->Error(_("The package cache file is an incompatible version")); 
 153    if (HeaderP
->VerSysName 
== 0 || 
 154        (VS 
= pkgVersioningSystem::GetVS(StrP 
+ HeaderP
->VerSysName
)) == 0) 
 155       return _error
->Error(_("This APT does not support the versioning system '%s'"),StrP 
+ HeaderP
->VerSysName
); 
 157    // Chcek the arhcitecture 
 158    if (HeaderP
->Architecture 
== 0 || 
 159        _config
->Find("APT::Architecture") != StrP 
+ HeaderP
->Architecture
) 
 160       return _error
->Error(_("The package cache was built for a different architecture")); 
 164 // Cache::Hash - Hash a string                                          /*{{{*/ 
 165 // --------------------------------------------------------------------- 
 166 /* This is used to generate the hash entries for the HashTable. With my 
 167    package list from bo this function gets 94% table usage on a 512 item 
 168    table (480 used items) */ 
 169 unsigned long pkgCache::sHash(const string 
&Str
) const 
 171    unsigned long Hash 
= 0; 
 172    for (string::const_iterator I 
= Str
.begin(); I 
!= Str
.end(); I
++) 
 173       Hash 
= 5*Hash 
+ tolower_ascii(*I
); 
 174    return Hash 
% _count(HeaderP
->PkgHashTable
); 
 177 unsigned long pkgCache::sHash(const char *Str
) const 
 179    unsigned long Hash 
= 0; 
 180    for (const char *I 
= Str
; *I 
!= 0; I
++) 
 181       Hash 
= 5*Hash 
+ tolower_ascii(*I
); 
 182    return Hash 
% _count(HeaderP
->PkgHashTable
); 
 186 // Cache::SingleArchFindPkg - Locate a package by name                  /*{{{*/ 
 187 // --------------------------------------------------------------------- 
 188 /* Returns 0 on error, pointer to the package otherwise 
 189    The multiArch enabled methods will fallback to this one as it is (a bit) 
 190    faster for single arch environments and realworld is mostly singlearch… */ 
 191 pkgCache::PkgIterator 
pkgCache::SingleArchFindPkg(const string 
&Name
) 
 193    // Look at the hash bucket 
 194    Package 
*Pkg 
= PkgP 
+ HeaderP
->PkgHashTable
[Hash(Name
)]; 
 195    for (; Pkg 
!= PkgP
; Pkg 
= PkgP 
+ Pkg
->NextPackage
) 
 197       if (Pkg
->Name 
!= 0 && StrP
[Pkg
->Name
] == Name
[0] && 
 198           stringcasecmp(Name
,StrP 
+ Pkg
->Name
) == 0) 
 199          return PkgIterator(*this,Pkg
); 
 201    return PkgIterator(*this,0); 
 204 // Cache::FindPkg - Locate a package by name                            /*{{{*/ 
 205 // --------------------------------------------------------------------- 
 206 /* Returns 0 on error, pointer to the package otherwise */ 
 207 pkgCache::PkgIterator 
pkgCache::FindPkg(const string 
&Name
) { 
 208         if (MultiArchCache() == false) 
 209                 return SingleArchFindPkg(Name
); 
 210         size_t const found 
= Name
.find(':'); 
 211         if (found 
== string::npos
) 
 212                 return FindPkg(Name
, "native"); 
 213         string 
const Arch 
= Name
.substr(found
+1); 
 215                 return FindPkg(Name
, "any"); 
 216         return FindPkg(Name
.substr(0, found
), Arch
); 
 219 // Cache::FindPkg - Locate a package by name                            /*{{{*/ 
 220 // --------------------------------------------------------------------- 
 221 /* Returns 0 on error, pointer to the package otherwise */ 
 222 pkgCache::PkgIterator 
pkgCache::FindPkg(const string 
&Name
, string 
const &Arch
) { 
 223         if (MultiArchCache() == false) { 
 224                 if (Arch 
== "native" || Arch 
== "all" || Arch 
== "any" || 
 225                     Arch 
== _config
->Find("APT::Architecture")) 
 226                         return SingleArchFindPkg(Name
); 
 228                         return PkgIterator(*this,0); 
 230         /* We make a detour via the GrpIterator here as 
 231            on a multi-arch environment a group is easier to 
 232            find than a package (less entries in the buckets) */ 
 233         pkgCache::GrpIterator Grp 
= FindGrp(Name
); 
 234         if (Grp
.end() == true) 
 235                 return PkgIterator(*this,0); 
 237         return Grp
.FindPkg(Arch
); 
 240 // Cache::FindGrp - Locate a group by name                              /*{{{*/ 
 241 // --------------------------------------------------------------------- 
 242 /* Returns End-Pointer on error, pointer to the group otherwise */ 
 243 pkgCache::GrpIterator 
pkgCache::FindGrp(const string 
&Name
) { 
 244         if (unlikely(Name
.empty() == true)) 
 245                 return GrpIterator(*this,0); 
 247         // Look at the hash bucket for the group 
 248         Group 
*Grp 
= GrpP 
+ HeaderP
->GrpHashTable
[sHash(Name
)]; 
 249         for (; Grp 
!= GrpP
; Grp 
= GrpP 
+ Grp
->Next
) { 
 250                 if (Grp
->Name 
!= 0 && StrP
[Grp
->Name
] == Name
[0] && 
 251                     stringcasecmp(Name
, StrP 
+ Grp
->Name
) == 0) 
 252                         return GrpIterator(*this, Grp
); 
 255         return GrpIterator(*this,0); 
 258 // Cache::CompTypeDeb - Return a string describing the compare type     /*{{{*/ 
 259 // --------------------------------------------------------------------- 
 260 /* This returns a string representation of the dependency compare  
 261    type in the weird debian style.. */ 
 262 const char *pkgCache::CompTypeDeb(unsigned char Comp
) 
 264    const char *Ops
[] = {"","<=",">=","<<",">>","=","!="}; 
 265    if ((unsigned)(Comp 
& 0xF) < 7) 
 266       return Ops
[Comp 
& 0xF]; 
 270 // Cache::CompType - Return a string describing the compare type        /*{{{*/ 
 271 // --------------------------------------------------------------------- 
 272 /* This returns a string representation of the dependency compare  
 274 const char *pkgCache::CompType(unsigned char Comp
) 
 276    const char *Ops
[] = {"","<=",">=","<",">","=","!="}; 
 277    if ((unsigned)(Comp 
& 0xF) < 7) 
 278       return Ops
[Comp 
& 0xF]; 
 282 // Cache::DepType - Return a string describing the dep type             /*{{{*/ 
 283 // --------------------------------------------------------------------- 
 285 const char *pkgCache::DepType(unsigned char Type
) 
 287    const char *Types
[] = {"",_("Depends"),_("PreDepends"),_("Suggests"), 
 288                           _("Recommends"),_("Conflicts"),_("Replaces"), 
 289                           _("Obsoletes"),_("Breaks"), _("Enhances")}; 
 290    if (Type 
< sizeof(Types
)/sizeof(*Types
)) 
 295 // Cache::Priority - Convert a priority value to a string               /*{{{*/ 
 296 // --------------------------------------------------------------------- 
 298 const char *pkgCache::Priority(unsigned char Prio
) 
 300    const char *Mapping
[] = {0,_("important"),_("required"),_("standard"), 
 301                             _("optional"),_("extra")}; 
 302    if (Prio 
< _count(Mapping
)) 
 303       return Mapping
[Prio
]; 
 307 // GrpIterator::FindPkg - Locate a package by arch                      /*{{{*/ 
 308 // --------------------------------------------------------------------- 
 309 /* Returns an End-Pointer on error, pointer to the package otherwise */ 
 310 pkgCache::PkgIterator 
pkgCache::GrpIterator::FindPkg(string Arch
) { 
 311         if (unlikely(IsGood() == false || S
->FirstPackage 
== 0)) 
 312                 return PkgIterator(*Owner
, 0); 
 314         static string 
const myArch 
= _config
->Find("APT::Architecture"); 
 315         /* Most of the time the package for our native architecture is 
 316            the one we add at first to the cache, but this would be the 
 317            last one we check, so we do it now. */ 
 318         if (Arch 
== "native" || Arch 
== myArch
) { 
 320                 pkgCache::Package 
*Pkg 
= Owner
->PkgP 
+ S
->LastPackage
; 
 321                 if (stringcasecmp(Arch
, Owner
->StrP 
+ Pkg
->Arch
) == 0) 
 322                         return PkgIterator(*Owner
, Pkg
); 
 325         /* If we accept any package we simply return the "first" 
 326            package in this group (the last one added). */ 
 328                 return PkgIterator(*Owner
, Owner
->PkgP 
+ S
->FirstPackage
); 
 330         /* Iterate over the list to find the matching arch 
 331            unfortunately this list includes "package noise" 
 332            (= different packages with same calculated hash), 
 333            so we need to check the name also */ 
 334         for (pkgCache::Package 
*Pkg 
= PackageList(); Pkg 
!= Owner
->PkgP
; 
 335              Pkg 
= Owner
->PkgP 
+ Pkg
->NextPackage
) { 
 336                 if (S
->Name 
== Pkg
->Name 
&& 
 337                     stringcasecmp(Arch
, Owner
->StrP 
+ Pkg
->Arch
) == 0) 
 338                         return PkgIterator(*Owner
, Pkg
); 
 339                 if ((Owner
->PkgP 
+ S
->LastPackage
) == Pkg
) 
 343         return PkgIterator(*Owner
, 0); 
 346 // GrpIterator::FindPreferredPkg - Locate the "best" package            /*{{{*/ 
 347 // --------------------------------------------------------------------- 
 348 /* Returns an End-Pointer on error, pointer to the package otherwise */ 
 349 pkgCache::PkgIterator 
pkgCache::GrpIterator::FindPreferredPkg() { 
 350         pkgCache::PkgIterator Pkg 
= FindPkg("native"); 
 351         if (Pkg
.end() == false) 
 354         std::vector
<std::string
> const archs 
= APT::Configuration::getArchitectures(); 
 355         for (std::vector
<std::string
>::const_iterator a 
= archs
.begin(); 
 356              a 
!= archs
.end(); ++a
) { 
 358                 if (Pkg
.end() == false) 
 362         return PkgIterator(*Owner
, 0); 
 365 // GrpIterator::NextPkg - Locate the next package in the group          /*{{{*/ 
 366 // --------------------------------------------------------------------- 
 367 /* Returns an End-Pointer on error, pointer to the package otherwise. 
 368    We can't simply ++ to the next as the next package of the last will 
 369    be from a different group (with the same hash value) */ 
 370 pkgCache::PkgIterator 
pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator 
const &LastPkg
) { 
 371         if (unlikely(IsGood() == false || S
->FirstPackage 
== 0 || 
 372             LastPkg
.end() == true)) 
 373                 return PkgIterator(*Owner
, 0); 
 375         if (S
->LastPackage 
== LastPkg
.Index()) 
 376                 return PkgIterator(*Owner
, 0); 
 378         return PkgIterator(*Owner
, Owner
->PkgP 
+ LastPkg
->NextPackage
); 
 381 // GrpIterator::operator ++ - Postfix incr                              /*{{{*/ 
 382 // --------------------------------------------------------------------- 
 383 /* This will advance to the next logical group in the hash table. */ 
 384 void pkgCache::GrpIterator::operator ++(int)  
 386    // Follow the current links 
 387    if (S 
!= Owner
->GrpP
) 
 388       S 
= Owner
->GrpP 
+ S
->Next
; 
 390    // Follow the hash table 
 391    while (S 
== Owner
->GrpP 
&& (HashIndex
+1) < (signed)_count(Owner
->HeaderP
->GrpHashTable
)) 
 394       S 
= Owner
->GrpP 
+ Owner
->HeaderP
->GrpHashTable
[HashIndex
]; 
 398 // PkgIterator::operator ++ - Postfix incr                              /*{{{*/ 
 399 // --------------------------------------------------------------------- 
 400 /* This will advance to the next logical package in the hash table. */ 
 401 void pkgCache::PkgIterator::operator ++(int)  
 403    // Follow the current links 
 404    if (S 
!= Owner
->PkgP
) 
 405       S 
= Owner
->PkgP 
+ S
->NextPackage
; 
 407    // Follow the hash table 
 408    while (S 
== Owner
->PkgP 
&& (HashIndex
+1) < (signed)_count(Owner
->HeaderP
->PkgHashTable
)) 
 411       S 
= Owner
->PkgP 
+ Owner
->HeaderP
->PkgHashTable
[HashIndex
]; 
 415 // PkgIterator::State - Check the State of the package                  /*{{{*/ 
 416 // --------------------------------------------------------------------- 
 417 /* By this we mean if it is either cleanly installed or cleanly removed. */ 
 418 pkgCache::PkgIterator::OkState 
pkgCache::PkgIterator::State() const 
 420    if (S
->InstState 
== pkgCache::State::ReInstReq 
|| 
 421        S
->InstState 
== pkgCache::State::HoldReInstReq
) 
 424    if (S
->CurrentState 
== pkgCache::State::UnPacked 
|| 
 425        S
->CurrentState 
== pkgCache::State::HalfConfigured
) 
 426       // we leave triggers alone complettely. dpkg deals with 
 427       // them in a hard-to-predict manner and if they get  
 428       // resolved by dpkg before apt run dpkg --configure on  
 429       // the TriggersPending package dpkg returns a error 
 430       //Pkg->CurrentState == pkgCache::State::TriggersAwaited 
 431       //Pkg->CurrentState == pkgCache::State::TriggersPending) 
 432       return NeedsConfigure
; 
 434    if (S
->CurrentState 
== pkgCache::State::HalfInstalled 
|| 
 435        S
->InstState 
!= pkgCache::State::Ok
) 
 441 // PkgIterator::CandVersion - Returns the candidate version string      /*{{{*/ 
 442 // --------------------------------------------------------------------- 
 443 /* Return string representing of the candidate version. */ 
 445 pkgCache::PkgIterator::CandVersion() const  
 447   //TargetVer is empty, so don't use it. 
 448   VerIterator version 
= pkgPolicy(Owner
).GetCandidateVer(*this); 
 449   if (version
.IsGood()) 
 450     return version
.VerStr(); 
 454 // PkgIterator::CurVersion - Returns the current version string         /*{{{*/ 
 455 // --------------------------------------------------------------------- 
 456 /* Return string representing of the current version. */ 
 458 pkgCache::PkgIterator::CurVersion() const  
 460   VerIterator version 
= CurrentVer(); 
 461   if (version
.IsGood()) 
 462     return CurrentVer().VerStr(); 
 466 // ostream operator to handle string representation of a package        /*{{{*/ 
 467 // --------------------------------------------------------------------- 
 468 /* Output name < cur.rent.version -> candid.ate.version | new.est.version > (section) 
 469    Note that the characters <|>() are all literal above. Versions will be ommited 
 470    if they provide no new information (e.g. there is no newer version than candidate) 
 471    If no version and/or section can be found "none" is used. */ 
 473 operator<<(ostream
& out
, pkgCache::PkgIterator Pkg
)  
 475    if (Pkg
.end() == true) 
 476       return out 
<< "invalid package"; 
 478    string current 
= string(Pkg
.CurVersion() == 0 ? "none" : Pkg
.CurVersion()); 
 479    string candidate 
= string(Pkg
.CandVersion() == 0 ? "none" : Pkg
.CandVersion()); 
 480    string newest 
= string(Pkg
.VersionList().end() ? "none" : Pkg
.VersionList().VerStr()); 
 482    out 
<< Pkg
.Name() << " [ " << Pkg
.Arch() << " ] < " << current
; 
 483    if (current 
!= candidate
) 
 484       out 
<< " -> " << candidate
; 
 485    if ( newest 
!= "none" && candidate 
!= newest
) 
 486       out 
<< " | " << newest
; 
 487    out 
<< " > ( " << string(Pkg
.Section()==0?"none":Pkg
.Section()) << " )"; 
 491 // PkgIterator::FullName - Returns Name and (maybe) Architecture        /*{{{*/ 
 492 // --------------------------------------------------------------------- 
 493 /* Returns a name:arch string */ 
 494 std::string 
pkgCache::PkgIterator::FullName(bool const &Pretty
) const 
 496    string fullname 
= Name(); 
 497    if (Pretty 
== false || 
 498        (strcmp(Arch(), "all") != 0 && _config
->Find("APT::Architecture") != Arch())) 
 499       return fullname
.append(":").append(Arch()); 
 503 // DepIterator::IsCritical - Returns true if the dep is important       /*{{{*/ 
 504 // --------------------------------------------------------------------- 
 505 /* Currently critical deps are defined as depends, predepends and 
 506    conflicts (including dpkg's Breaks fields). */ 
 507 bool pkgCache::DepIterator::IsCritical() 
 509    if (S
->Type 
== pkgCache::Dep::Conflicts 
|| 
 510        S
->Type 
== pkgCache::Dep::DpkgBreaks 
|| 
 511        S
->Type 
== pkgCache::Dep::Obsoletes 
|| 
 512        S
->Type 
== pkgCache::Dep::Depends 
|| 
 513        S
->Type 
== pkgCache::Dep::PreDepends
) 
 518 // DepIterator::SmartTargetPkg - Resolve dep target pointers w/provides /*{{{*/ 
 519 // --------------------------------------------------------------------- 
 520 /* This intellegently looks at dep target packages and tries to figure 
 521    out which package should be used. This is needed to nicely handle 
 522    provide mapping. If the target package has no other providing packages 
 523    then it returned. Otherwise the providing list is looked at to  
 524    see if there is one one unique providing package if so it is returned. 
 525    Otherwise true is returned and the target package is set. The return 
 526    result indicates whether the node should be expandable  
 528    In Conjunction with the DepCache the value of Result may not be  
 529    super-good since the policy may have made it uninstallable. Using 
 530    AllTargets is better in this case. */ 
 531 bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator 
&Result
) 
 533    Result 
= TargetPkg(); 
 535    // No provides at all 
 536    if (Result
->ProvidesList 
== 0) 
 539    // There is the Base package and the providing ones which is at least 2 
 540    if (Result
->VersionList 
!= 0) 
 543    /* We have to skip over indirect provisions of the package that 
 544       owns the dependency. For instance, if libc5-dev depends on the 
 545       virtual package libc-dev which is provided by libc5-dev and libc6-dev 
 546       we must ignore libc5-dev when considering the provides list. */  
 547    PrvIterator PStart 
= Result
.ProvidesList(); 
 548    for (; PStart
.end() != true && PStart
.OwnerPkg() == ParentPkg(); PStart
++); 
 550    // Nothing but indirect self provides 
 551    if (PStart
.end() == true) 
 554    // Check for single packages in the provides list 
 555    PrvIterator P 
= PStart
; 
 556    for (; P
.end() != true; P
++) 
 558       // Skip over self provides 
 559       if (P
.OwnerPkg() == ParentPkg()) 
 561       if (PStart
.OwnerPkg() != P
.OwnerPkg()) 
 565    Result 
= PStart
.OwnerPkg(); 
 567    // Check for non dups 
 574 // DepIterator::AllTargets - Returns the set of all possible targets    /*{{{*/ 
 575 // --------------------------------------------------------------------- 
 576 /* This is a more useful version of TargetPkg() that follows versioned 
 577    provides. It includes every possible package-version that could satisfy 
 578    the dependency. The last item in the list has a 0. The resulting pointer 
 579    must be delete [] 'd */ 
 580 pkgCache::Version 
**pkgCache::DepIterator::AllTargets() 
 583    unsigned long Size 
=0; 
 587       PkgIterator DPkg 
= TargetPkg(); 
 589       // Walk along the actual package providing versions 
 590       for (VerIterator I 
= DPkg
.VersionList(); I
.end() == false; I
++) 
 592          if (Owner
->VS
->CheckDep(I
.VerStr(),S
->CompareOp
,TargetVer()) == false) 
 595          if ((S
->Type 
== pkgCache::Dep::Conflicts 
|| 
 596               S
->Type 
== pkgCache::Dep::DpkgBreaks 
|| 
 597               S
->Type 
== pkgCache::Dep::Obsoletes
) && 
 598              ParentPkg() == I
.ParentPkg()) 
 606       // Follow all provides 
 607       for (PrvIterator I 
= DPkg
.ProvidesList(); I
.end() == false; I
++) 
 609          if (Owner
->VS
->CheckDep(I
.ProvideVersion(),S
->CompareOp
,TargetVer()) == false) 
 612          if ((S
->Type 
== pkgCache::Dep::Conflicts 
|| 
 613               S
->Type 
== pkgCache::Dep::DpkgBreaks 
|| 
 614               S
->Type 
== pkgCache::Dep::Obsoletes
) && 
 615              ParentPkg() == I
.OwnerPkg()) 
 620             *End
++ = I
.OwnerVer(); 
 623       // Do it again and write it into the array 
 626          Res 
= new Version 
*[Size
+1]; 
 639 // DepIterator::GlobOr - Compute an OR group                            /*{{{*/ 
 640 // --------------------------------------------------------------------- 
 641 /* This Takes an iterator, iterates past the current dependency grouping 
 642    and returns Start and End so that so End is the final element 
 643    in the group, if End == Start then D is End++ and End is the 
 644    dependency D was pointing to. Use in loops to iterate sensibly. */ 
 645 void pkgCache::DepIterator::GlobOr(DepIterator 
&Start
,DepIterator 
&End
) 
 647    // Compute a single dependency element (glob or) 
 650    for (bool LastOR 
= true; end() == false && LastOR 
== true;) 
 652       LastOR 
= (S
->CompareOp 
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
; 
 659 // VerIterator::CompareVer - Fast version compare for same pkgs         /*{{{*/ 
 660 // --------------------------------------------------------------------- 
 661 /* This just looks over the version list to see if B is listed before A. In 
 662    most cases this will return in under 4 checks, ver lists are short. */ 
 663 int pkgCache::VerIterator::CompareVer(const VerIterator 
&B
) const 
 665    // Check if they are equal 
 673    /* Start at A and look for B. If B is found then A > B otherwise 
 674       B was before A so A < B */ 
 675    VerIterator I 
= *this; 
 676    for (;I
.end() == false; I
++) 
 682 // VerIterator::Downloadable - Checks if the version is downloadable    /*{{{*/ 
 683 // --------------------------------------------------------------------- 
 685 bool pkgCache::VerIterator::Downloadable() const 
 687    VerFileIterator Files 
= FileList(); 
 688    for (; Files
.end() == false; Files
++) 
 689       if ((Files
.File()->Flags 
& pkgCache::Flag::NotSource
) != pkgCache::Flag::NotSource
) 
 694 // VerIterator::Automatic - Check if this version is 'automatic'        /*{{{*/ 
 695 // --------------------------------------------------------------------- 
 696 /* This checks to see if any of the versions files are not NotAutomatic.  
 697    True if this version is selectable for automatic installation. */ 
 698 bool pkgCache::VerIterator::Automatic() const 
 700    VerFileIterator Files 
= FileList(); 
 701    for (; Files
.end() == false; Files
++) 
 702       if ((Files
.File()->Flags 
& pkgCache::Flag::NotAutomatic
) != pkgCache::Flag::NotAutomatic
) 
 707 // VerIterator::Pseudo - Check if this version is a pseudo one          /*{{{*/ 
 708 // --------------------------------------------------------------------- 
 709 /* Sometimes you have the need to express dependencies with versions 
 710    which doesn't really exist or exist multiply times for "different" 
 711    packages. We need these versions for dependency resolution but they 
 712    are a problem everytime we need to download/install something. */ 
 713 bool pkgCache::VerIterator::Pseudo() const 
 715    if (S
->MultiArch 
== pkgCache::Version::All 
&& 
 716            strcmp(Arch(true),"all") != 0) 
 718            GrpIterator 
const Grp 
= ParentPkg().Group(); 
 719            return (Grp
->LastPackage 
!= Grp
->FirstPackage
); 
 724 // VerIterator::NewestFile - Return the newest file version relation    /*{{{*/ 
 725 // --------------------------------------------------------------------- 
 726 /* This looks at the version numbers associated with all of the sources 
 727    this version is in and returns the highest.*/ 
 728 pkgCache::VerFileIterator 
pkgCache::VerIterator::NewestFile() const 
 730    VerFileIterator Files 
= FileList(); 
 731    VerFileIterator Highest 
= Files
; 
 732    for (; Files
.end() == false; Files
++) 
 734       if (Owner
->VS
->CmpReleaseVer(Files
.File().Version(),Highest
.File().Version()) > 0) 
 741 // VerIterator::RelStr - Release description string                     /*{{{*/ 
 742 // --------------------------------------------------------------------- 
 743 /* This describes the version from a release-centric manner. The output is a  
 744    list of Label:Version/Archive */ 
 745 string 
pkgCache::VerIterator::RelStr() 
 749    for (pkgCache::VerFileIterator I 
= this->FileList(); I
.end() == false; I
++) 
 751       // Do not print 'not source' entries' 
 752       pkgCache::PkgFileIterator File 
= I
.File(); 
 753       if ((File
->Flags 
& pkgCache::Flag::NotSource
) == pkgCache::Flag::NotSource
) 
 756       // See if we have already printed this out.. 
 758       for (pkgCache::VerFileIterator J 
= this->FileList(); I 
!= J
; J
++) 
 760          pkgCache::PkgFileIterator File2 
= J
.File(); 
 761          if (File2
->Label 
== 0 || File
->Label 
== 0) 
 764          if (strcmp(File
.Label(),File2
.Label()) != 0) 
 767          if (File2
->Version 
== File
->Version
) 
 772          if (File2
->Version 
== 0 || File
->Version 
== 0) 
 774          if (strcmp(File
.Version(),File2
.Version()) == 0) 
 786       if (File
->Label 
!= 0) 
 787          Res 
= Res 
+ File
.Label() + ':'; 
 789       if (File
->Archive 
!= 0) 
 791          if (File
->Version 
== 0) 
 792             Res 
+= File
.Archive(); 
 794             Res 
= Res 
+ File
.Version() + '/' +  File
.Archive(); 
 798          // No release file, print the host name that this came from 
 799          if (File
->Site 
== 0 || File
.Site()[0] == 0) 
 805    if (S
->ParentPkg 
!= 0) 
 806       Res
.append(" [").append(Arch()).append("]"); 
 810 // PkgFileIterator::IsOk - Checks if the cache is in sync with the file /*{{{*/ 
 811 // --------------------------------------------------------------------- 
 812 /* This stats the file and compares its stats with the ones that were 
 813    stored during generation. Date checks should probably also be  
 815 bool pkgCache::PkgFileIterator::IsOk() 
 818    if (stat(FileName(),&Buf
) != 0) 
 821    if (Buf
.st_size 
!= (signed)S
->Size 
|| Buf
.st_mtime 
!= S
->mtime
) 
 827 // PkgFileIterator::RelStr - Return the release string                  /*{{{*/ 
 828 // --------------------------------------------------------------------- 
 830 string 
pkgCache::PkgFileIterator::RelStr() 
 834       Res 
= Res 
+ (Res
.empty() == true?"v=":",v=") + Version(); 
 836       Res 
= Res 
+ (Res
.empty() == true?"o=":",o=")  + Origin(); 
 838       Res 
= Res 
+ (Res
.empty() == true?"a=":",a=")  + Archive(); 
 840       Res 
= Res 
+ (Res
.empty() == true?"n=":",n=")  + Codename(); 
 842       Res 
= Res 
+ (Res
.empty() == true?"l=":",l=")  + Label(); 
 843    if (Component() != 0) 
 844       Res 
= Res 
+ (Res
.empty() == true?"c=":",c=")  + Component(); 
 845    if (Architecture() != 0) 
 846       Res 
= Res 
+ (Res
.empty() == true?"b=":",b=")  + Architecture(); 
 850 // VerIterator::TranslatedDescription - Return the a DescIter for locale/*{{{*/ 
 851 // --------------------------------------------------------------------- 
 852 /* return a DescIter for the current locale or the default if none is  
 855 pkgCache::DescIterator 
pkgCache::VerIterator::TranslatedDescription() const 
 857    std::vector
<string
> const lang 
= APT::Configuration::getLanguages(); 
 858    for (std::vector
<string
>::const_iterator l 
= lang
.begin(); 
 859         l 
!= lang
.end(); l
++) 
 861       pkgCache::DescIterator DescDefault 
= DescriptionList(); 
 862       pkgCache::DescIterator Desc 
= DescDefault
; 
 864       for (; Desc
.end() == false; Desc
++) 
 865          if (*l 
== Desc
.LanguageCode()) 
 867       if (Desc
.end() == true)  
 872    return DescriptionList();