]>
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 /*{{{*/
24 #pragma implementation "apt-pkg/pkgcache.h"
25 #pragma implementation "apt-pkg/cacheiterators.h"
28 #include <apt-pkg/pkgcache.h>
29 #include <apt-pkg/indexfile.h>
30 #include <apt-pkg/version.h>
31 #include <apt-pkg/error.h>
32 #include <apt-pkg/strutl.h>
33 #include <apt-pkg/configuration.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 PackageSz
= sizeof(pkgCache::Package
);
63 PackageFileSz
= sizeof(pkgCache::PackageFile
);
64 VersionSz
= sizeof(pkgCache::Version
);
65 DescriptionSz
= sizeof(pkgCache::Description
);
66 DependencySz
= sizeof(pkgCache::Dependency
);
67 ProvidesSz
= sizeof(pkgCache::Provides
);
68 VerFileSz
= sizeof(pkgCache::VerFile
);
69 DescFileSz
= sizeof(pkgCache::DescFile
);
86 memset(HashTable
,0,sizeof(HashTable
));
87 memset(Pools
,0,sizeof(Pools
));
90 // Cache::Header::CheckSizes - Check if the two headers have same *sz /*{{{*/
91 // ---------------------------------------------------------------------
93 bool pkgCache::Header::CheckSizes(Header
&Against
) const
95 if (HeaderSz
== Against
.HeaderSz
&&
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
)
118 // Cache::ReMap - Reopen the cache file /*{{{*/
119 // ---------------------------------------------------------------------
120 /* If the file is already closed then this will open it open it. */
121 bool pkgCache::ReMap()
123 // Apply the typecasts.
124 HeaderP
= (Header
*)Map
.Data();
125 PkgP
= (Package
*)Map
.Data();
126 VerFileP
= (VerFile
*)Map
.Data();
127 DescFileP
= (DescFile
*)Map
.Data();
128 PkgFileP
= (PackageFile
*)Map
.Data();
129 VerP
= (Version
*)Map
.Data();
130 DescP
= (Description
*)Map
.Data();
131 ProvideP
= (Provides
*)Map
.Data();
132 DepP
= (Dependency
*)Map
.Data();
133 StringItemP
= (StringItem
*)Map
.Data();
134 StrP
= (char *)Map
.Data();
136 if (Map
.Size() == 0 || HeaderP
== 0)
137 return _error
->Error(_("Empty package cache"));
141 if (HeaderP
->Signature
!= DefHeader
.Signature
||
142 HeaderP
->Dirty
== true)
143 return _error
->Error(_("The package cache file is corrupted"));
145 if (HeaderP
->MajorVersion
!= DefHeader
.MajorVersion
||
146 HeaderP
->MinorVersion
!= DefHeader
.MinorVersion
||
147 HeaderP
->CheckSizes(DefHeader
) == false)
148 return _error
->Error(_("The package cache file is an incompatible version"));
151 if (HeaderP
->VerSysName
== 0 ||
152 (VS
= pkgVersioningSystem::GetVS(StrP
+ HeaderP
->VerSysName
)) == 0)
153 return _error
->Error(_("This APT does not support the versioning system '%s'"),StrP
+ HeaderP
->VerSysName
);
155 // Chcek the arhcitecture
156 if (HeaderP
->Architecture
== 0 ||
157 _config
->Find("APT::Architecture") != StrP
+ HeaderP
->Architecture
)
158 return _error
->Error(_("The package cache was built for a different architecture"));
162 // Cache::Hash - Hash a string /*{{{*/
163 // ---------------------------------------------------------------------
164 /* This is used to generate the hash entries for the HashTable. With my
165 package list from bo this function gets 94% table usage on a 512 item
166 table (480 used items) */
167 unsigned long pkgCache::sHash(const string
&Str
) const
169 unsigned long Hash
= 0;
170 for (string::const_iterator I
= Str
.begin(); I
!= Str
.end(); I
++)
171 Hash
= 5*Hash
+ tolower(*I
);
172 return Hash
% _count(HeaderP
->HashTable
);
175 unsigned long pkgCache::sHash(const char *Str
) const
177 unsigned long Hash
= 0;
178 for (const char *I
= Str
; *I
!= 0; I
++)
179 Hash
= 5*Hash
+ tolower(*I
);
180 return Hash
% _count(HeaderP
->HashTable
);
184 // Cache::FindPkg - Locate a package by name /*{{{*/
185 // ---------------------------------------------------------------------
186 /* Returns 0 on error, pointer to the package otherwise */
187 pkgCache::PkgIterator
pkgCache::FindPkg(const string
&Name
)
189 // Look at the hash bucket
190 Package
*Pkg
= PkgP
+ HeaderP
->HashTable
[Hash(Name
)];
191 for (; Pkg
!= PkgP
; Pkg
= PkgP
+ Pkg
->NextPackage
)
193 if (Pkg
->Name
!= 0 && StrP
[Pkg
->Name
] == Name
[0] &&
194 stringcasecmp(Name
,StrP
+ Pkg
->Name
) == 0)
195 return PkgIterator(*this,Pkg
);
197 return PkgIterator(*this,0);
200 // Cache::CompTypeDeb - Return a string describing the compare type /*{{{*/
201 // ---------------------------------------------------------------------
202 /* This returns a string representation of the dependency compare
203 type in the weird debian style.. */
204 const char *pkgCache::CompTypeDeb(unsigned char Comp
)
206 const char *Ops
[] = {"","<=",">=","<<",">>","=","!="};
207 if ((unsigned)(Comp
& 0xF) < 7)
208 return Ops
[Comp
& 0xF];
212 // Cache::CompType - Return a string describing the compare type /*{{{*/
213 // ---------------------------------------------------------------------
214 /* This returns a string representation of the dependency compare
216 const char *pkgCache::CompType(unsigned char Comp
)
218 const char *Ops
[] = {"","<=",">=","<",">","=","!="};
219 if ((unsigned)(Comp
& 0xF) < 7)
220 return Ops
[Comp
& 0xF];
224 // Cache::DepType - Return a string describing the dep type /*{{{*/
225 // ---------------------------------------------------------------------
227 const char *pkgCache::DepType(unsigned char Type
)
229 const char *Types
[] = {"",_("Depends"),_("PreDepends"),_("Suggests"),
230 _("Recommends"),_("Conflicts"),_("Replaces"),
231 _("Obsoletes"),_("Breaks")};
232 if (Type
< sizeof(Types
)/sizeof(*Types
))
237 // Cache::Priority - Convert a priority value to a string /*{{{*/
238 // ---------------------------------------------------------------------
240 const char *pkgCache::Priority(unsigned char Prio
)
242 const char *Mapping
[] = {0,_("important"),_("required"),_("standard"),
243 _("optional"),_("extra")};
244 if (Prio
< _count(Mapping
))
245 return Mapping
[Prio
];
249 // Bases for iterator classes /*{{{*/
250 void pkgCache::VerIterator::_dummy() {}
251 void pkgCache::DepIterator::_dummy() {}
252 void pkgCache::PrvIterator::_dummy() {}
253 void pkgCache::DescIterator::_dummy() {}
255 // PkgIterator::operator ++ - Postfix incr /*{{{*/
256 // ---------------------------------------------------------------------
257 /* This will advance to the next logical package in the hash table. */
258 void pkgCache::PkgIterator::operator ++(int)
260 // Follow the current links
261 if (Pkg
!= Owner
->PkgP
)
262 Pkg
= Owner
->PkgP
+ Pkg
->NextPackage
;
264 // Follow the hash table
265 while (Pkg
== Owner
->PkgP
&& (HashIndex
+1) < (signed)_count(Owner
->HeaderP
->HashTable
))
268 Pkg
= Owner
->PkgP
+ Owner
->HeaderP
->HashTable
[HashIndex
];
272 // PkgIterator::State - Check the State of the package /*{{{*/
273 // ---------------------------------------------------------------------
274 /* By this we mean if it is either cleanly installed or cleanly removed. */
275 pkgCache::PkgIterator::OkState
pkgCache::PkgIterator::State() const
277 if (Pkg
->InstState
== pkgCache::State::ReInstReq
||
278 Pkg
->InstState
== pkgCache::State::HoldReInstReq
)
281 if (Pkg
->CurrentState
== pkgCache::State::UnPacked
||
282 Pkg
->CurrentState
== pkgCache::State::HalfConfigured
)
283 return NeedsConfigure
;
285 if (Pkg
->CurrentState
== pkgCache::State::HalfInstalled
||
286 Pkg
->InstState
!= pkgCache::State::Ok
)
292 // DepIterator::IsCritical - Returns true if the dep is important /*{{{*/
293 // ---------------------------------------------------------------------
294 /* Currently critical deps are defined as depends, predepends and
295 conflicts (including dpkg's Breaks fields). */
296 bool pkgCache::DepIterator::IsCritical()
298 if (Dep
->Type
== pkgCache::Dep::Conflicts
||
299 Dep
->Type
== pkgCache::Dep::DpkgBreaks
||
300 Dep
->Type
== pkgCache::Dep::Obsoletes
||
301 Dep
->Type
== pkgCache::Dep::Depends
||
302 Dep
->Type
== pkgCache::Dep::PreDepends
)
307 // DepIterator::SmartTargetPkg - Resolve dep target pointers w/provides /*{{{*/
308 // ---------------------------------------------------------------------
309 /* This intellegently looks at dep target packages and tries to figure
310 out which package should be used. This is needed to nicely handle
311 provide mapping. If the target package has no other providing packages
312 then it returned. Otherwise the providing list is looked at to
313 see if there is one one unique providing package if so it is returned.
314 Otherwise true is returned and the target package is set. The return
315 result indicates whether the node should be expandable
317 In Conjunction with the DepCache the value of Result may not be
318 super-good since the policy may have made it uninstallable. Using
319 AllTargets is better in this case. */
320 bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator
&Result
)
322 Result
= TargetPkg();
324 // No provides at all
325 if (Result
->ProvidesList
== 0)
328 // There is the Base package and the providing ones which is at least 2
329 if (Result
->VersionList
!= 0)
332 /* We have to skip over indirect provisions of the package that
333 owns the dependency. For instance, if libc5-dev depends on the
334 virtual package libc-dev which is provided by libc5-dev and libc6-dev
335 we must ignore libc5-dev when considering the provides list. */
336 PrvIterator PStart
= Result
.ProvidesList();
337 for (; PStart
.end() != true && PStart
.OwnerPkg() == ParentPkg(); PStart
++);
339 // Nothing but indirect self provides
340 if (PStart
.end() == true)
343 // Check for single packages in the provides list
344 PrvIterator P
= PStart
;
345 for (; P
.end() != true; P
++)
347 // Skip over self provides
348 if (P
.OwnerPkg() == ParentPkg())
350 if (PStart
.OwnerPkg() != P
.OwnerPkg())
354 Result
= PStart
.OwnerPkg();
356 // Check for non dups
363 // DepIterator::AllTargets - Returns the set of all possible targets /*{{{*/
364 // ---------------------------------------------------------------------
365 /* This is a more useful version of TargetPkg() that follows versioned
366 provides. It includes every possible package-version that could satisfy
367 the dependency. The last item in the list has a 0. The resulting pointer
368 must be delete [] 'd */
369 pkgCache::Version
**pkgCache::DepIterator::AllTargets()
372 unsigned long Size
=0;
376 PkgIterator DPkg
= TargetPkg();
378 // Walk along the actual package providing versions
379 for (VerIterator I
= DPkg
.VersionList(); I
.end() == false; I
++)
381 if (Owner
->VS
->CheckDep(I
.VerStr(),Dep
->CompareOp
,TargetVer()) == false)
384 if ((Dep
->Type
== pkgCache::Dep::Conflicts
||
385 Dep
->Type
== pkgCache::Dep::DpkgBreaks
||
386 Dep
->Type
== pkgCache::Dep::Obsoletes
) &&
387 ParentPkg() == I
.ParentPkg())
395 // Follow all provides
396 for (PrvIterator I
= DPkg
.ProvidesList(); I
.end() == false; I
++)
398 if (Owner
->VS
->CheckDep(I
.ProvideVersion(),Dep
->CompareOp
,TargetVer()) == false)
401 if ((Dep
->Type
== pkgCache::Dep::Conflicts
||
402 Dep
->Type
== pkgCache::Dep::DpkgBreaks
||
403 Dep
->Type
== pkgCache::Dep::Obsoletes
) &&
404 ParentPkg() == I
.OwnerPkg())
409 *End
++ = I
.OwnerVer();
412 // Do it again and write it into the array
415 Res
= new Version
*[Size
+1];
428 // DepIterator::GlobOr - Compute an OR group /*{{{*/
429 // ---------------------------------------------------------------------
430 /* This Takes an iterator, iterates past the current dependency grouping
431 and returns Start and End so that so End is the final element
432 in the group, if End == Start then D is End++ and End is the
433 dependency D was pointing to. Use in loops to iterate sensibly. */
434 void pkgCache::DepIterator::GlobOr(DepIterator
&Start
,DepIterator
&End
)
436 // Compute a single dependency element (glob or)
439 for (bool LastOR
= true; end() == false && LastOR
== true;)
441 LastOR
= (Dep
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
448 // VerIterator::CompareVer - Fast version compare for same pkgs /*{{{*/
449 // ---------------------------------------------------------------------
450 /* This just looks over the version list to see if B is listed before A. In
451 most cases this will return in under 4 checks, ver lists are short. */
452 int pkgCache::VerIterator::CompareVer(const VerIterator
&B
) const
454 // Check if they are equal
462 /* Start at A and look for B. If B is found then A > B otherwise
463 B was before A so A < B */
464 VerIterator I
= *this;
465 for (;I
.end() == false; I
++)
471 // VerIterator::Downloadable - Checks if the version is downloadable /*{{{*/
472 // ---------------------------------------------------------------------
474 bool pkgCache::VerIterator::Downloadable() const
476 VerFileIterator Files
= FileList();
477 for (; Files
.end() == false; Files
++)
478 if ((Files
.File()->Flags
& pkgCache::Flag::NotSource
) != pkgCache::Flag::NotSource
)
483 // VerIterator::Automatic - Check if this version is 'automatic' /*{{{*/
484 // ---------------------------------------------------------------------
485 /* This checks to see if any of the versions files are not NotAutomatic.
486 True if this version is selectable for automatic installation. */
487 bool pkgCache::VerIterator::Automatic() const
489 VerFileIterator Files
= FileList();
490 for (; Files
.end() == false; Files
++)
491 if ((Files
.File()->Flags
& pkgCache::Flag::NotAutomatic
) != pkgCache::Flag::NotAutomatic
)
496 // VerIterator::NewestFile - Return the newest file version relation /*{{{*/
497 // ---------------------------------------------------------------------
498 /* This looks at the version numbers associated with all of the sources
499 this version is in and returns the highest.*/
500 pkgCache::VerFileIterator
pkgCache::VerIterator::NewestFile() const
502 VerFileIterator Files
= FileList();
503 VerFileIterator Highest
= Files
;
504 for (; Files
.end() == false; Files
++)
506 if (Owner
->VS
->CmpReleaseVer(Files
.File().Version(),Highest
.File().Version()) > 0)
513 // VerIterator::RelStr - Release description string /*{{{*/
514 // ---------------------------------------------------------------------
515 /* This describes the version from a release-centric manner. The output is a
516 list of Label:Version/Archive */
517 string
pkgCache::VerIterator::RelStr()
521 for (pkgCache::VerFileIterator I
= this->FileList(); I
.end() == false; I
++)
523 // Do not print 'not source' entries'
524 pkgCache::PkgFileIterator File
= I
.File();
525 if ((File
->Flags
& pkgCache::Flag::NotSource
) == pkgCache::Flag::NotSource
)
528 // See if we have already printed this out..
530 for (pkgCache::VerFileIterator J
= this->FileList(); I
!= J
; J
++)
532 pkgCache::PkgFileIterator File2
= J
.File();
533 if (File2
->Label
== 0 || File
->Label
== 0)
536 if (strcmp(File
.Label(),File2
.Label()) != 0)
539 if (File2
->Version
== File
->Version
)
544 if (File2
->Version
== 0 || File
->Version
== 0)
546 if (strcmp(File
.Version(),File2
.Version()) == 0)
558 if (File
->Label
!= 0)
559 Res
= Res
+ File
.Label() + ':';
561 if (File
->Archive
!= 0)
563 if (File
->Version
== 0)
564 Res
+= File
.Archive();
566 Res
= Res
+ File
.Version() + '/' + File
.Archive();
570 // No release file, print the host name that this came from
571 if (File
->Site
== 0 || File
.Site()[0] == 0)
580 // PkgFileIterator::IsOk - Checks if the cache is in sync with the file /*{{{*/
581 // ---------------------------------------------------------------------
582 /* This stats the file and compares its stats with the ones that were
583 stored during generation. Date checks should probably also be
585 bool pkgCache::PkgFileIterator::IsOk()
588 if (stat(FileName(),&Buf
) != 0)
591 if (Buf
.st_size
!= (signed)File
->Size
|| Buf
.st_mtime
!= File
->mtime
)
597 // PkgFileIterator::RelStr - Return the release string /*{{{*/
598 // ---------------------------------------------------------------------
600 string
pkgCache::PkgFileIterator::RelStr()
604 Res
= Res
+ (Res
.empty() == true?"v=":",v=") + Version();
606 Res
= Res
+ (Res
.empty() == true?"o=":",o=") + Origin();
608 Res
= Res
+ (Res
.empty() == true?"a=":",a=") + Archive();
610 Res
= Res
+ (Res
.empty() == true?"l=":",l=") + Label();
611 if (Component() != 0)
612 Res
= Res
+ (Res
.empty() == true?"c=":",c=") + Component();
616 // VerIterator::TranslatedDescription - Return the a DescIter for locale/*{{{*/
617 // ---------------------------------------------------------------------
618 /* return a DescIter for the current locale or the default if none is
621 pkgCache::DescIterator
pkgCache::VerIterator::TranslatedDescription() const
623 pkgCache::DescIterator DescDefault
= DescriptionList();
624 pkgCache::DescIterator Desc
= DescDefault
;
625 for (; Desc
.end() == false; Desc
++)
626 if (pkgIndexFile::LanguageCode() == Desc
.LanguageCode())
628 if (Desc
.end() == true) Desc
= DescDefault
;