]>
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 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. 
  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                                                        /*{{{*/ 
  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> 
  48 // Cache::Header::Header - Constructor                                  /*{{{*/ 
  49 // --------------------------------------------------------------------- 
  50 /* Simply initialize the header */ 
  51 pkgCache::Header::Header() 
  53    Signature 
= 0x98FE76DC; 
  55    /* Whenever the structures change the major version should be bumped, 
  56       whenever the generator changes the minor version should be bumped. */ 
  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
); 
  88    HashTableSize 
= _config
->FindI("APT::Cache-HashTableSize", 10 * 1048); 
  89    memset(Pools
,0,sizeof(Pools
)); 
  94 // Cache::Header::CheckSizes - Check if the two headers have same *sz   /*{{{*/ 
  95 // --------------------------------------------------------------------- 
  97 bool pkgCache::Header::CheckSizes(Header 
&Against
) const 
  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
) 
 114 // Cache::pkgCache - Constructor                                        /*{{{*/ 
 115 // --------------------------------------------------------------------- 
 117 pkgCache::pkgCache(MMap 
*Map
, bool DoMap
) : Map(*Map
) 
 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; 
 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
) 
 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    StringItemP 
= (StringItem 
*)Map
.Data(); 
 144    StrP 
= (char *)Map
.Data(); 
 146    if (Errorchecks 
== false) 
 149    if (Map
.Size() == 0 || HeaderP 
== 0) 
 150       return _error
->Error(_("Empty package cache")); 
 154    if (HeaderP
->Signature 
!= DefHeader
.Signature 
|| 
 155        HeaderP
->Dirty 
== true) 
 156       return _error
->Error(_("The package cache file is corrupted")); 
 158    if (HeaderP
->MajorVersion 
!= DefHeader
.MajorVersion 
|| 
 159        HeaderP
->MinorVersion 
!= DefHeader
.MinorVersion 
|| 
 160        HeaderP
->CheckSizes(DefHeader
) == false) 
 161       return _error
->Error(_("The package cache file is an incompatible version")); 
 163    if (Map
.Size() < HeaderP
->CacheFileSize
) 
 164       return _error
->Error(_("The package cache file is corrupted, it is too small")); 
 166    if (HeaderP
->VerSysName 
== 0 || HeaderP
->Architecture 
== 0 || HeaderP
->Architectures 
== 0) 
 167       return _error
->Error(_("The package cache file is corrupted")); 
 170    if ((VS 
= pkgVersioningSystem::GetVS(StrP 
+ HeaderP
->VerSysName
)) == 0) 
 171       return _error
->Error(_("This APT does not support the versioning system '%s'"),StrP 
+ HeaderP
->VerSysName
); 
 173    // Check the architecture 
 174    std::vector
<std::string
> archs 
= APT::Configuration::getArchitectures(); 
 175    std::vector
<std::string
>::const_iterator a 
= archs
.begin(); 
 176    std::string list 
= *a
; 
 177    for (++a
; a 
!= archs
.end(); ++a
) 
 178       list
.append(",").append(*a
); 
 179    if (_config
->Find("APT::Architecture") != StrP 
+ HeaderP
->Architecture 
|| 
 180          list 
!= StrP 
+ HeaderP
->Architectures
) 
 181       return _error
->Error(_("The package cache was built for different architectures: %s vs %s"), StrP 
+ HeaderP
->Architectures
, list
.c_str()); 
 186 // Cache::Hash - Hash a string                                          /*{{{*/ 
 187 // --------------------------------------------------------------------- 
 188 /* This is used to generate the hash entries for the HashTable. With my 
 189    package list from bo this function gets 94% table usage on a 512 item 
 190    table (480 used items) */ 
 191 map_id_t 
pkgCache::sHash(const string 
&Str
) const 
 193    unsigned long Hash 
= 0; 
 194    for (string::const_iterator I 
= Str
.begin(); I 
!= Str
.end(); ++I
) 
 195       Hash 
= 41 * Hash 
+ tolower_ascii(*I
); 
 196    return Hash 
% HeaderP
->HashTableSize
; 
 199 map_id_t 
pkgCache::sHash(const char *Str
) const 
 201    unsigned long Hash 
= tolower_ascii(*Str
); 
 202    for (const char *I 
= Str 
+ 1; *I 
!= 0; ++I
) 
 203       Hash 
= 41 * Hash 
+ tolower_ascii(*I
); 
 204    return Hash 
% HeaderP
->HashTableSize
; 
 207 // Cache::SingleArchFindPkg - Locate a package by name                  /*{{{*/ 
 208 // --------------------------------------------------------------------- 
 209 /* Returns 0 on error, pointer to the package otherwise 
 210    The multiArch enabled methods will fallback to this one as it is (a bit) 
 211    faster for single arch environments and realworld is mostly singlearch… */ 
 212 pkgCache::PkgIterator 
pkgCache::SingleArchFindPkg(const string 
&Name
) 
 214    // Look at the hash bucket 
 215    Package 
*Pkg 
= PkgP 
+ HeaderP
->PkgHashTable()[Hash(Name
)]; 
 216    for (; Pkg 
!= PkgP
; Pkg 
= PkgP 
+ Pkg
->Next
) 
 218       if (unlikely(Pkg
->Name 
== 0)) 
 221       int const cmp 
= strcasecmp(Name
.c_str(), StrP 
+ Pkg
->Name
); 
 223          return PkgIterator(*this, Pkg
); 
 227    return PkgIterator(*this,0); 
 230 // Cache::FindPkg - Locate a package by name                            /*{{{*/ 
 231 // --------------------------------------------------------------------- 
 232 /* Returns 0 on error, pointer to the package otherwise */ 
 233 pkgCache::PkgIterator 
pkgCache::FindPkg(const string 
&Name
) { 
 234         size_t const found 
= Name
.find(':'); 
 235         if (found 
== string::npos
) 
 237                 if (MultiArchCache() == false) 
 238                         return SingleArchFindPkg(Name
); 
 240                         return FindPkg(Name
, "native"); 
 242         string 
const Arch 
= Name
.substr(found
+1); 
 243         /* Beware: This is specialcased to handle pkg:any in dependencies as 
 244            these are linked to virtual pkg:any named packages with all archs. 
 245            If you want any arch from a given pkg, use FindPkg(pkg,arch) */ 
 247                 return FindPkg(Name
, "any"); 
 248         return FindPkg(Name
.substr(0, found
), Arch
); 
 251 // Cache::FindPkg - Locate a package by name                            /*{{{*/ 
 252 // --------------------------------------------------------------------- 
 253 /* Returns 0 on error, pointer to the package otherwise */ 
 254 pkgCache::PkgIterator 
pkgCache::FindPkg(const string 
&Name
, string 
const &Arch
) { 
 255         if (MultiArchCache() == false && Arch 
!= "none") { 
 256                 if (Arch 
== "native" || Arch 
== "all" || Arch 
== "any" || 
 257                     Arch 
== NativeArch()) 
 258                         return SingleArchFindPkg(Name
); 
 260                         return PkgIterator(*this,0); 
 262         /* We make a detour via the GrpIterator here as 
 263            on a multi-arch environment a group is easier to 
 264            find than a package (less entries in the buckets) */ 
 265         pkgCache::GrpIterator Grp 
= FindGrp(Name
); 
 266         if (Grp
.end() == true) 
 267                 return PkgIterator(*this,0); 
 269         return Grp
.FindPkg(Arch
); 
 272 // Cache::FindGrp - Locate a group by name                              /*{{{*/ 
 273 // --------------------------------------------------------------------- 
 274 /* Returns End-Pointer on error, pointer to the group otherwise */ 
 275 pkgCache::GrpIterator 
pkgCache::FindGrp(const string 
&Name
) { 
 276         if (unlikely(Name
.empty() == true)) 
 277                 return GrpIterator(*this,0); 
 279         // Look at the hash bucket for the group 
 280         Group 
*Grp 
= GrpP 
+ HeaderP
->GrpHashTable()[sHash(Name
)]; 
 281         for (; Grp 
!= GrpP
; Grp 
= GrpP 
+ Grp
->Next
) { 
 282                 if (unlikely(Grp
->Name 
== 0)) 
 285                 int const cmp 
= strcasecmp(Name
.c_str(), StrP 
+ Grp
->Name
); 
 287                         return GrpIterator(*this, Grp
); 
 292         return GrpIterator(*this,0); 
 295 // Cache::CompTypeDeb - Return a string describing the compare type     /*{{{*/ 
 296 // --------------------------------------------------------------------- 
 297 /* This returns a string representation of the dependency compare  
 298    type in the weird debian style.. */ 
 299 const char *pkgCache::CompTypeDeb(unsigned char Comp
) 
 301    const char * const Ops
[] = {"","<=",">=","<<",">>","=","!="}; 
 302    if (unlikely((unsigned)(Comp 
& 0xF) >= sizeof(Ops
)/sizeof(Ops
[0]))) 
 304    return Ops
[Comp 
& 0xF]; 
 307 // Cache::CompType - Return a string describing the compare type        /*{{{*/ 
 308 // --------------------------------------------------------------------- 
 309 /* This returns a string representation of the dependency compare 
 311 const char *pkgCache::CompType(unsigned char Comp
) 
 313    const char * const Ops
[] = {"","<=",">=","<",">","=","!="}; 
 314    if (unlikely((unsigned)(Comp 
& 0xF) >= sizeof(Ops
)/sizeof(Ops
[0]))) 
 316    return Ops
[Comp 
& 0xF]; 
 319 // Cache::DepType - Return a string describing the dep type             /*{{{*/ 
 320 // --------------------------------------------------------------------- 
 322 const char *pkgCache::DepType(unsigned char Type
) 
 324    const char *Types
[] = {"",_("Depends"),_("PreDepends"),_("Suggests"), 
 325                           _("Recommends"),_("Conflicts"),_("Replaces"), 
 326                           _("Obsoletes"),_("Breaks"), _("Enhances")}; 
 327    if (Type 
< sizeof(Types
)/sizeof(*Types
)) 
 332 // Cache::Priority - Convert a priority value to a string               /*{{{*/ 
 333 // --------------------------------------------------------------------- 
 335 const char *pkgCache::Priority(unsigned char Prio
) 
 337    const char *Mapping
[] = {0,_("important"),_("required"),_("standard"), 
 338                             _("optional"),_("extra")}; 
 339    if (Prio 
< _count(Mapping
)) 
 340       return Mapping
[Prio
]; 
 344 // GrpIterator::FindPkg - Locate a package by arch                      /*{{{*/ 
 345 // --------------------------------------------------------------------- 
 346 /* Returns an End-Pointer on error, pointer to the package otherwise */ 
 347 pkgCache::PkgIterator 
pkgCache::GrpIterator::FindPkg(string Arch
) const { 
 348         if (unlikely(IsGood() == false || S
->FirstPackage 
== 0)) 
 349                 return PkgIterator(*Owner
, 0); 
 351         /* If we accept any package we simply return the "first" 
 352            package in this group (the last one added). */ 
 354                 return PkgIterator(*Owner
, Owner
->PkgP 
+ S
->FirstPackage
); 
 356         char const* const myArch 
= Owner
->NativeArch(); 
 357         /* Most of the time the package for our native architecture is 
 358            the one we add at first to the cache, but this would be the 
 359            last one we check, so we do it now. */ 
 360         if (Arch 
== "native" || Arch 
== myArch 
|| Arch 
== "all") { 
 361                 pkgCache::Package 
*Pkg 
= Owner
->PkgP 
+ S
->LastPackage
; 
 362                 if (strcasecmp(myArch
, Owner
->StrP 
+ Pkg
->Arch
) == 0) 
 363                         return PkgIterator(*Owner
, Pkg
); 
 367         /* Iterate over the list to find the matching arch 
 368            unfortunately this list includes "package noise" 
 369            (= different packages with same calculated hash), 
 370            so we need to check the name also */ 
 371         for (pkgCache::Package 
*Pkg 
= PackageList(); Pkg 
!= Owner
->PkgP
; 
 372              Pkg 
= Owner
->PkgP 
+ Pkg
->Next
) { 
 373                 if (S
->Name 
== Pkg
->Name 
&& 
 374                     stringcasecmp(Arch
, Owner
->StrP 
+ Pkg
->Arch
) == 0) 
 375                         return PkgIterator(*Owner
, Pkg
); 
 376                 if ((Owner
->PkgP 
+ S
->LastPackage
) == Pkg
) 
 380         return PkgIterator(*Owner
, 0); 
 383 // GrpIterator::FindPreferredPkg - Locate the "best" package            /*{{{*/ 
 384 // --------------------------------------------------------------------- 
 385 /* Returns an End-Pointer on error, pointer to the package otherwise */ 
 386 pkgCache::PkgIterator 
pkgCache::GrpIterator::FindPreferredPkg(bool const &PreferNonVirtual
) const { 
 387         pkgCache::PkgIterator Pkg 
= FindPkg("native"); 
 388         if (Pkg
.end() == false && (PreferNonVirtual 
== false || Pkg
->VersionList 
!= 0)) 
 391         std::vector
<std::string
> const archs 
= APT::Configuration::getArchitectures(); 
 392         for (std::vector
<std::string
>::const_iterator a 
= archs
.begin(); 
 393              a 
!= archs
.end(); ++a
) { 
 395                 if (Pkg
.end() == false && (PreferNonVirtual 
== false || Pkg
->VersionList 
!= 0)) 
 398         // packages without an architecture 
 399         Pkg 
= FindPkg("none"); 
 400         if (Pkg
.end() == false && (PreferNonVirtual 
== false || Pkg
->VersionList 
!= 0)) 
 403         if (PreferNonVirtual 
== true) 
 404                 return FindPreferredPkg(false); 
 405         return PkgIterator(*Owner
, 0); 
 408 // GrpIterator::NextPkg - Locate the next package in the group          /*{{{*/ 
 409 // --------------------------------------------------------------------- 
 410 /* Returns an End-Pointer on error, pointer to the package otherwise. 
 411    We can't simply ++ to the next as the next package of the last will 
 412    be from a different group (with the same hash value) */ 
 413 pkgCache::PkgIterator 
pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator 
const &LastPkg
) const { 
 414         if (unlikely(IsGood() == false || S
->FirstPackage 
== 0 || 
 415             LastPkg
.end() == true)) 
 416                 return PkgIterator(*Owner
, 0); 
 418         if (S
->LastPackage 
== LastPkg
.Index()) 
 419                 return PkgIterator(*Owner
, 0); 
 421         return PkgIterator(*Owner
, Owner
->PkgP 
+ LastPkg
->Next
); 
 424 // GrpIterator::operator ++ - Postfix incr                              /*{{{*/ 
 425 // --------------------------------------------------------------------- 
 426 /* This will advance to the next logical group in the hash table. */ 
 427 void pkgCache::GrpIterator::operator ++(int) 
 429    // Follow the current links 
 430    if (S 
!= Owner
->GrpP
) 
 431       S 
= Owner
->GrpP 
+ S
->Next
; 
 433    // Follow the hash table 
 434    while (S 
== Owner
->GrpP 
&& (HashIndex
+1) < (signed)Owner
->HeaderP
->HashTableSize
) 
 437       S 
= Owner
->GrpP 
+ Owner
->HeaderP
->GrpHashTable()[HashIndex
]; 
 441 // PkgIterator::operator ++ - Postfix incr                              /*{{{*/ 
 442 // --------------------------------------------------------------------- 
 443 /* This will advance to the next logical package in the hash table. */ 
 444 void pkgCache::PkgIterator::operator ++(int) 
 446    // Follow the current links 
 447    if (S 
!= Owner
->PkgP
) 
 448       S 
= Owner
->PkgP 
+ S
->Next
; 
 450    // Follow the hash table 
 451    while (S 
== Owner
->PkgP 
&& (HashIndex
+1) < (signed)Owner
->HeaderP
->HashTableSize
) 
 454       S 
= Owner
->PkgP 
+ Owner
->HeaderP
->PkgHashTable()[HashIndex
]; 
 458 // PkgIterator::State - Check the State of the package                  /*{{{*/ 
 459 // --------------------------------------------------------------------- 
 460 /* By this we mean if it is either cleanly installed or cleanly removed. */ 
 461 pkgCache::PkgIterator::OkState 
pkgCache::PkgIterator::State() const 
 463    if (S
->InstState 
== pkgCache::State::ReInstReq 
|| 
 464        S
->InstState 
== pkgCache::State::HoldReInstReq
) 
 467    if (S
->CurrentState 
== pkgCache::State::UnPacked 
|| 
 468        S
->CurrentState 
== pkgCache::State::HalfConfigured
) 
 469       // we leave triggers alone complettely. dpkg deals with 
 470       // them in a hard-to-predict manner and if they get  
 471       // resolved by dpkg before apt run dpkg --configure on  
 472       // the TriggersPending package dpkg returns a error 
 473       //Pkg->CurrentState == pkgCache::State::TriggersAwaited 
 474       //Pkg->CurrentState == pkgCache::State::TriggersPending) 
 475       return NeedsConfigure
; 
 477    if (S
->CurrentState 
== pkgCache::State::HalfInstalled 
|| 
 478        S
->InstState 
!= pkgCache::State::Ok
) 
 484 // PkgIterator::CandVersion - Returns the candidate version string      /*{{{*/ 
 485 // --------------------------------------------------------------------- 
 486 /* Return string representing of the candidate version. */ 
 488 pkgCache::PkgIterator::CandVersion() const 
 490   //TargetVer is empty, so don't use it. 
 491   VerIterator version 
= pkgPolicy(Owner
).GetCandidateVer(*this); 
 492   if (version
.IsGood()) 
 493     return version
.VerStr(); 
 497 // PkgIterator::CurVersion - Returns the current version string         /*{{{*/ 
 498 // --------------------------------------------------------------------- 
 499 /* Return string representing of the current version. */ 
 501 pkgCache::PkgIterator::CurVersion() const 
 503   VerIterator version 
= CurrentVer(); 
 504   if (version
.IsGood()) 
 505     return CurrentVer().VerStr(); 
 509 // ostream operator to handle string representation of a package        /*{{{*/ 
 510 // --------------------------------------------------------------------- 
 511 /* Output name < cur.rent.version -> candid.ate.version | new.est.version > (section) 
 512    Note that the characters <|>() are all literal above. Versions will be omitted 
 513    if they provide no new information (e.g. there is no newer version than candidate) 
 514    If no version and/or section can be found "none" is used. */ 
 516 operator<<(std::ostream
& out
, pkgCache::PkgIterator Pkg
)  
 518    if (Pkg
.end() == true) 
 519       return out 
<< "invalid package"; 
 521    string current 
= string(Pkg
.CurVersion() == 0 ? "none" : Pkg
.CurVersion()); 
 522    string candidate 
= string(Pkg
.CandVersion() == 0 ? "none" : Pkg
.CandVersion()); 
 523    string newest 
= string(Pkg
.VersionList().end() ? "none" : Pkg
.VersionList().VerStr()); 
 525    out 
<< Pkg
.Name() << " [ " << Pkg
.Arch() << " ] < " << current
; 
 526    if (current 
!= candidate
) 
 527       out 
<< " -> " << candidate
; 
 528    if ( newest 
!= "none" && candidate 
!= newest
) 
 529       out 
<< " | " << newest
; 
 530    if (Pkg
->VersionList 
== 0) 
 531       out 
<< " > ( none )"; 
 533       out 
<< " > ( " << string(Pkg
.VersionList().Section()==0?"unknown":Pkg
.VersionList().Section()) << " )"; 
 537 // PkgIterator::FullName - Returns Name and (maybe) Architecture        /*{{{*/ 
 538 // --------------------------------------------------------------------- 
 539 /* Returns a name:arch string */ 
 540 std::string 
pkgCache::PkgIterator::FullName(bool const &Pretty
) const 
 542    string fullname 
= Name(); 
 543    if (Pretty 
== false || 
 544        (strcmp(Arch(), "all") != 0 && 
 545         strcmp(Owner
->NativeArch(), Arch()) != 0)) 
 546       return fullname
.append(":").append(Arch()); 
 550 // DepIterator::IsCritical - Returns true if the dep is important       /*{{{*/ 
 551 // --------------------------------------------------------------------- 
 552 /* Currently critical deps are defined as depends, predepends and 
 553    conflicts (including dpkg's Breaks fields). */ 
 554 bool pkgCache::DepIterator::IsCritical() const 
 556    if (IsNegative() == true || 
 557        S
->Type 
== pkgCache::Dep::Depends 
|| 
 558        S
->Type 
== pkgCache::Dep::PreDepends
) 
 563 // DepIterator::IsNegative - Returns true if the dep is a negative one  /*{{{*/ 
 564 // --------------------------------------------------------------------- 
 565 /* Some dependencies are positive like Depends and Recommends, others 
 566    are negative like Conflicts which can and should be handled differently */ 
 567 bool pkgCache::DepIterator::IsNegative() const 
 569    return S
->Type 
== Dep::DpkgBreaks 
|| 
 570           S
->Type 
== Dep::Conflicts 
|| 
 571           S
->Type 
== Dep::Obsoletes
; 
 574 // DepIterator::SmartTargetPkg - Resolve dep target pointers w/provides /*{{{*/ 
 575 // --------------------------------------------------------------------- 
 576 /* This intellegently looks at dep target packages and tries to figure 
 577    out which package should be used. This is needed to nicely handle 
 578    provide mapping. If the target package has no other providing packages 
 579    then it returned. Otherwise the providing list is looked at to  
 580    see if there is one one unique providing package if so it is returned. 
 581    Otherwise true is returned and the target package is set. The return 
 582    result indicates whether the node should be expandable  
 584    In Conjunction with the DepCache the value of Result may not be  
 585    super-good since the policy may have made it uninstallable. Using 
 586    AllTargets is better in this case. */ 
 587 bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator 
&Result
) const 
 589    Result 
= TargetPkg(); 
 591    // No provides at all 
 592    if (Result
->ProvidesList 
== 0) 
 595    // There is the Base package and the providing ones which is at least 2 
 596    if (Result
->VersionList 
!= 0) 
 599    /* We have to skip over indirect provisions of the package that 
 600       owns the dependency. For instance, if libc5-dev depends on the 
 601       virtual package libc-dev which is provided by libc5-dev and libc6-dev 
 602       we must ignore libc5-dev when considering the provides list. */  
 603    PrvIterator PStart 
= Result
.ProvidesList(); 
 604    for (; PStart
.end() != true && PStart
.OwnerPkg() == ParentPkg(); ++PStart
); 
 606    // Nothing but indirect self provides 
 607    if (PStart
.end() == true) 
 610    // Check for single packages in the provides list 
 611    PrvIterator P 
= PStart
; 
 612    for (; P
.end() != true; ++P
) 
 614       // Skip over self provides 
 615       if (P
.OwnerPkg() == ParentPkg()) 
 617       if (PStart
.OwnerPkg() != P
.OwnerPkg()) 
 621    Result 
= PStart
.OwnerPkg(); 
 623    // Check for non dups 
 630 // DepIterator::AllTargets - Returns the set of all possible targets    /*{{{*/ 
 631 // --------------------------------------------------------------------- 
 632 /* This is a more useful version of TargetPkg() that follows versioned 
 633    provides. It includes every possible package-version that could satisfy 
 634    the dependency. The last item in the list has a 0. The resulting pointer 
 635    must be delete [] 'd */ 
 636 pkgCache::Version 
**pkgCache::DepIterator::AllTargets() const 
 639    unsigned long Size 
=0; 
 643       PkgIterator DPkg 
= TargetPkg(); 
 645       // Walk along the actual package providing versions 
 646       for (VerIterator I 
= DPkg
.VersionList(); I
.end() == false; ++I
) 
 648          if (IsIgnorable(I
.ParentPkg()) == true) 
 650          if (IsSatisfied(I
) == false) 
 658       // Follow all provides 
 659       for (PrvIterator I 
= DPkg
.ProvidesList(); I
.end() == false; ++I
) 
 661          if (IsIgnorable(I
) == true) 
 663          if (IsSatisfied(I
) == false) 
 668             *End
++ = I
.OwnerVer(); 
 671       // Do it again and write it into the array 
 674          Res 
= new Version 
*[Size
+1]; 
 687 // DepIterator::GlobOr - Compute an OR group                            /*{{{*/ 
 688 // --------------------------------------------------------------------- 
 689 /* This Takes an iterator, iterates past the current dependency grouping 
 690    and returns Start and End so that so End is the final element 
 691    in the group, if End == Start then D is End++ and End is the 
 692    dependency D was pointing to. Use in loops to iterate sensibly. */ 
 693 void pkgCache::DepIterator::GlobOr(DepIterator 
&Start
,DepIterator 
&End
) 
 695    // Compute a single dependency element (glob or) 
 698    for (bool LastOR 
= true; end() == false && LastOR 
== true;) 
 700       LastOR 
= (S
->CompareOp 
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
; 
 707 // DepIterator::IsIgnorable - should this packag/providr be ignored?    /*{{{*/ 
 708 // --------------------------------------------------------------------- 
 709 /* Deps like self-conflicts should be ignored as well as implicit conflicts 
 710    on virtual packages. */ 
 711 bool pkgCache::DepIterator::IsIgnorable(PkgIterator 
const &/*Pkg*/) const 
 713    if (IsNegative() == false) 
 716    pkgCache::PkgIterator PP 
= ParentPkg(); 
 717    pkgCache::PkgIterator PT 
= TargetPkg(); 
 718    if (PP
->Group 
!= PT
->Group
) 
 723    pkgCache::VerIterator PV 
= ParentVer(); 
 724    // ignore group-conflict on a M-A:same package - but not our implicit dependencies 
 725    // so that we can have M-A:same packages conflicting with their own real name 
 726    if ((PV
->MultiArch 
& pkgCache::Version::Same
) == pkgCache::Version::Same
) 
 728       // Replaces: ${self}:other ( << ${binary:Version}) 
 729       if (S
->Type 
== pkgCache::Dep::Replaces 
&& S
->CompareOp 
== pkgCache::Dep::Less 
&& strcmp(PV
.VerStr(), TargetVer()) == 0) 
 731       // Breaks: ${self}:other (!= ${binary:Version}) 
 732       if (S
->Type 
== pkgCache::Dep::DpkgBreaks 
&& S
->CompareOp 
== pkgCache::Dep::NotEquals 
&& strcmp(PV
.VerStr(), TargetVer()) == 0) 
 739 bool pkgCache::DepIterator::IsIgnorable(PrvIterator 
const &Prv
) const 
 741    if (IsNegative() == false) 
 744    PkgIterator 
const Pkg 
= ParentPkg(); 
 745    /* Provides may never be applied against the same package (or group) 
 746       if it is a conflicts. See the comment above. */ 
 747    if (Prv
.OwnerPkg()->Group 
== Pkg
->Group
) 
 749    // Implicit group-conflicts should not be applied on providers of other groups 
 750    if (Pkg
->Group 
== TargetPkg()->Group 
&& Prv
.OwnerPkg()->Group 
!= Pkg
->Group
) 
 756 // DepIterator::IsMultiArchImplicit - added by the cache generation     /*{{{*/ 
 757 // --------------------------------------------------------------------- 
 758 /* MultiArch can be translated to SingleArch for an resolver and we did so, 
 759    by adding dependencies to help the resolver understand the problem, but 
 760    sometimes it is needed to identify these to ignore them… */ 
 761 bool pkgCache::DepIterator::IsMultiArchImplicit() const 
 763    if (ParentPkg()->Arch 
!= TargetPkg()->Arch 
&& 
 764        (S
->Type 
== pkgCache::Dep::Replaces 
|| 
 765         S
->Type 
== pkgCache::Dep::DpkgBreaks 
|| 
 766         S
->Type 
== pkgCache::Dep::Conflicts
)) 
 771 // DepIterator::IsSatisfied - check if a version satisfied the dependency /*{{{*/ 
 772 bool pkgCache::DepIterator::IsSatisfied(VerIterator 
const &Ver
) const 
 774    return Owner
->VS
->CheckDep(Ver
.VerStr(),S
->CompareOp
,TargetVer()); 
 776 bool pkgCache::DepIterator::IsSatisfied(PrvIterator 
const &Prv
) const 
 778    return Owner
->VS
->CheckDep(Prv
.ProvideVersion(),S
->CompareOp
,TargetVer()); 
 781 // ostream operator to handle string representation of a dependecy      /*{{{*/ 
 782 // --------------------------------------------------------------------- 
 784 std::ostream
& operator<<(std::ostream
& out
, pkgCache::DepIterator D
) 
 787       return out 
<< "invalid dependency"; 
 789    pkgCache::PkgIterator P 
= D
.ParentPkg(); 
 790    pkgCache::PkgIterator T 
= D
.TargetPkg(); 
 792    out 
<< (P
.end() ? "invalid pkg" : P
.FullName(false)) << " " << D
.DepType() 
 795       out 
<< "invalid pkg"; 
 800       out 
<< " (" << D
.CompType() << " " << D
.TargetVer() << ")"; 
 805 // VerIterator::CompareVer - Fast version compare for same pkgs         /*{{{*/ 
 806 // --------------------------------------------------------------------- 
 807 /* This just looks over the version list to see if B is listed before A. In 
 808    most cases this will return in under 4 checks, ver lists are short. */ 
 809 int pkgCache::VerIterator::CompareVer(const VerIterator 
&B
) const 
 811    // Check if they are equal 
 819    /* Start at A and look for B. If B is found then A > B otherwise 
 820       B was before A so A < B */ 
 821    VerIterator I 
= *this; 
 822    for (;I
.end() == false; ++I
) 
 828 // VerIterator::Downloadable - Checks if the version is downloadable    /*{{{*/ 
 829 // --------------------------------------------------------------------- 
 831 APT_PURE 
bool pkgCache::VerIterator::Downloadable() const 
 833    VerFileIterator Files 
= FileList(); 
 834    for (; Files
.end() == false; ++Files
) 
 835       if ((Files
.File()->Flags 
& pkgCache::Flag::NotSource
) != pkgCache::Flag::NotSource
) 
 840 // VerIterator::Automatic - Check if this version is 'automatic'        /*{{{*/ 
 841 // --------------------------------------------------------------------- 
 842 /* This checks to see if any of the versions files are not NotAutomatic.  
 843    True if this version is selectable for automatic installation. */ 
 844 APT_PURE 
bool pkgCache::VerIterator::Automatic() const 
 846    VerFileIterator Files 
= FileList(); 
 847    for (; Files
.end() == false; ++Files
) 
 848       // Do not check ButAutomaticUpgrades here as it is kind of automatic… 
 849       if ((Files
.File()->Flags 
& pkgCache::Flag::NotAutomatic
) != pkgCache::Flag::NotAutomatic
) 
 854 // VerIterator::NewestFile - Return the newest file version relation    /*{{{*/ 
 855 // --------------------------------------------------------------------- 
 856 /* This looks at the version numbers associated with all of the sources 
 857    this version is in and returns the highest.*/ 
 858 pkgCache::VerFileIterator 
pkgCache::VerIterator::NewestFile() const 
 860    VerFileIterator Files 
= FileList(); 
 861    VerFileIterator Highest 
= Files
; 
 862    for (; Files
.end() == false; ++Files
) 
 864       if (Owner
->VS
->CmpReleaseVer(Files
.File().Version(),Highest
.File().Version()) > 0) 
 871 // VerIterator::RelStr - Release description string                     /*{{{*/ 
 872 // --------------------------------------------------------------------- 
 873 /* This describes the version from a release-centric manner. The output is a  
 874    list of Label:Version/Archive */ 
 875 string 
pkgCache::VerIterator::RelStr() const 
 879    for (pkgCache::VerFileIterator I 
= this->FileList(); I
.end() == false; ++I
) 
 881       // Do not print 'not source' entries' 
 882       pkgCache::PkgFileIterator File 
= I
.File(); 
 883       if ((File
->Flags 
& pkgCache::Flag::NotSource
) == pkgCache::Flag::NotSource
) 
 886       // See if we have already printed this out.. 
 888       for (pkgCache::VerFileIterator J 
= this->FileList(); I 
!= J
; ++J
) 
 890          pkgCache::PkgFileIterator File2 
= J
.File(); 
 891          if (File2
->Label 
== 0 || File
->Label 
== 0) 
 894          if (strcmp(File
.Label(),File2
.Label()) != 0) 
 897          if (File2
->Version 
== File
->Version
) 
 902          if (File2
->Version 
== 0 || File
->Version 
== 0) 
 904          if (strcmp(File
.Version(),File2
.Version()) == 0) 
 916       if (File
->Label 
!= 0) 
 917          Res 
= Res 
+ File
.Label() + ':'; 
 919       if (File
->Archive 
!= 0) 
 921          if (File
->Version 
== 0) 
 922             Res 
+= File
.Archive(); 
 924             Res 
= Res 
+ File
.Version() + '/' +  File
.Archive(); 
 928          // No release file, print the host name that this came from 
 929          if (File
->Site 
== 0 || File
.Site()[0] == 0) 
 935    if (S
->ParentPkg 
!= 0) 
 936       Res
.append(" [").append(Arch()).append("]"); 
 940 // VerIterator::MultiArchType - string representing MultiArch flag      /*{{{*/ 
 941 const char * pkgCache::VerIterator::MultiArchType() const 
 943    if ((S
->MultiArch 
& pkgCache::Version::Same
) == pkgCache::Version::Same
) 
 945    else if ((S
->MultiArch 
& pkgCache::Version::Foreign
) == pkgCache::Version::Foreign
) 
 947    else if ((S
->MultiArch 
& pkgCache::Version::Allowed
) == pkgCache::Version::Allowed
) 
 952 // PkgFileIterator::IsOk - Checks if the cache is in sync with the file /*{{{*/ 
 953 // --------------------------------------------------------------------- 
 954 /* This stats the file and compares its stats with the ones that were 
 955    stored during generation. Date checks should probably also be  
 957 bool pkgCache::PkgFileIterator::IsOk() 
 960    if (stat(FileName(),&Buf
) != 0) 
 963    if (Buf
.st_size 
!= (signed)S
->Size 
|| Buf
.st_mtime 
!= S
->mtime
) 
 969 // PkgFileIterator::RelStr - Return the release string                  /*{{{*/ 
 970 // --------------------------------------------------------------------- 
 972 string 
pkgCache::PkgFileIterator::RelStr() 
 976       Res 
= Res 
+ (Res
.empty() == true?"v=":",v=") + Version(); 
 978       Res 
= Res 
+ (Res
.empty() == true?"o=":",o=")  + Origin(); 
 980       Res 
= Res 
+ (Res
.empty() == true?"a=":",a=")  + Archive(); 
 982       Res 
= Res 
+ (Res
.empty() == true?"n=":",n=")  + Codename(); 
 984       Res 
= Res 
+ (Res
.empty() == true?"l=":",l=")  + Label(); 
 985    if (Component() != 0) 
 986       Res 
= Res 
+ (Res
.empty() == true?"c=":",c=")  + Component(); 
 987    if (Architecture() != 0) 
 988       Res 
= Res 
+ (Res
.empty() == true?"b=":",b=")  + Architecture(); 
 992 // VerIterator::TranslatedDescription - Return the a DescIter for locale/*{{{*/ 
 993 // --------------------------------------------------------------------- 
 994 /* return a DescIter for the current locale or the default if none is 
 997 pkgCache::DescIterator 
pkgCache::VerIterator::TranslatedDescription() const 
 999    std::vector
<string
> const lang 
= APT::Configuration::getLanguages(); 
1000    for (std::vector
<string
>::const_iterator l 
= lang
.begin(); 
1001         l 
!= lang
.end(); ++l
) 
1003       pkgCache::DescIterator Desc 
= DescriptionList(); 
1004       for (; Desc
.end() == false; ++Desc
) 
1005          if (*l 
== Desc
.LanguageCode()) 
1007       if (Desc
.end() == true) 
1011             Desc 
= DescriptionList(); 
1012             for (; Desc
.end() == false; ++Desc
) 
1013                if (strcmp(Desc
.LanguageCode(), "") == 0) 
1015             if (Desc
.end() == true) 
1023    for (pkgCache::DescIterator Desc 
= DescriptionList(); 
1024         Desc
.end() == false; ++Desc
) 
1025       if (strcmp(Desc
.LanguageCode(), "") == 0) 
1027    return DescriptionList(); 
1031 // PrvIterator::IsMultiArchImplicit - added by the cache generation     /*{{{*/ 
1032 // --------------------------------------------------------------------- 
1033 /* MultiArch can be translated to SingleArch for an resolver and we did so, 
1034    by adding provides to help the resolver understand the problem, but 
1035    sometimes it is needed to identify these to ignore them… */ 
1036 bool pkgCache::PrvIterator::IsMultiArchImplicit() const 
1038    pkgCache::PkgIterator 
const Owner 
= OwnerPkg(); 
1039    pkgCache::PkgIterator 
const Parent 
= ParentPkg(); 
1040    if (strcmp(Owner
.Arch(), Parent
.Arch()) != 0 || Owner
->Name 
== Parent
->Name
) 
1045 APT_DEPRECATED APT_PURE 
const char * pkgCache::PkgIterator::Section() const {/*{{{*/ 
1046    if (S
->VersionList 
== 0) 
1048    return VersionList().Section();