]>
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(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(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"),
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
296 bool pkgCache::DepIterator::IsCritical()
298 if (Dep
->Type
== pkgCache::Dep::Conflicts
||
299 Dep
->Type
== pkgCache::Dep::Obsoletes
||
300 Dep
->Type
== pkgCache::Dep::Depends
||
301 Dep
->Type
== pkgCache::Dep::PreDepends
)
306 // DepIterator::SmartTargetPkg - Resolve dep target pointers w/provides /*{{{*/
307 // ---------------------------------------------------------------------
308 /* This intellegently looks at dep target packages and tries to figure
309 out which package should be used. This is needed to nicely handle
310 provide mapping. If the target package has no other providing packages
311 then it returned. Otherwise the providing list is looked at to
312 see if there is one one unique providing package if so it is returned.
313 Otherwise true is returned and the target package is set. The return
314 result indicates whether the node should be expandable
316 In Conjunction with the DepCache the value of Result may not be
317 super-good since the policy may have made it uninstallable. Using
318 AllTargets is better in this case. */
319 bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator
&Result
)
321 Result
= TargetPkg();
323 // No provides at all
324 if (Result
->ProvidesList
== 0)
327 // There is the Base package and the providing ones which is at least 2
328 if (Result
->VersionList
!= 0)
331 /* We have to skip over indirect provisions of the package that
332 owns the dependency. For instance, if libc5-dev depends on the
333 virtual package libc-dev which is provided by libc5-dev and libc6-dev
334 we must ignore libc5-dev when considering the provides list. */
335 PrvIterator PStart
= Result
.ProvidesList();
336 for (; PStart
.end() != true && PStart
.OwnerPkg() == ParentPkg(); PStart
++);
338 // Nothing but indirect self provides
339 if (PStart
.end() == true)
342 // Check for single packages in the provides list
343 PrvIterator P
= PStart
;
344 for (; P
.end() != true; P
++)
346 // Skip over self provides
347 if (P
.OwnerPkg() == ParentPkg())
349 if (PStart
.OwnerPkg() != P
.OwnerPkg())
353 Result
= PStart
.OwnerPkg();
355 // Check for non dups
362 // DepIterator::AllTargets - Returns the set of all possible targets /*{{{*/
363 // ---------------------------------------------------------------------
364 /* This is a more useful version of TargetPkg() that follows versioned
365 provides. It includes every possible package-version that could satisfy
366 the dependency. The last item in the list has a 0. The resulting pointer
367 must be delete [] 'd */
368 pkgCache::Version
**pkgCache::DepIterator::AllTargets()
371 unsigned long Size
=0;
375 PkgIterator DPkg
= TargetPkg();
377 // Walk along the actual package providing versions
378 for (VerIterator I
= DPkg
.VersionList(); I
.end() == false; I
++)
380 if (Owner
->VS
->CheckDep(I
.VerStr(),Dep
->CompareOp
,TargetVer()) == false)
383 if ((Dep
->Type
== pkgCache::Dep::Conflicts
||
384 Dep
->Type
== pkgCache::Dep::Obsoletes
) &&
385 ParentPkg() == I
.ParentPkg())
393 // Follow all provides
394 for (PrvIterator I
= DPkg
.ProvidesList(); I
.end() == false; I
++)
396 if (Owner
->VS
->CheckDep(I
.ProvideVersion(),Dep
->CompareOp
,TargetVer()) == false)
399 if ((Dep
->Type
== pkgCache::Dep::Conflicts
||
400 Dep
->Type
== pkgCache::Dep::Obsoletes
) &&
401 ParentPkg() == I
.OwnerPkg())
406 *End
++ = I
.OwnerVer();
409 // Do it again and write it into the array
412 Res
= new Version
*[Size
+1];
425 // DepIterator::GlobOr - Compute an OR group /*{{{*/
426 // ---------------------------------------------------------------------
427 /* This Takes an iterator, iterates past the current dependency grouping
428 and returns Start and End so that so End is the final element
429 in the group, if End == Start then D is End++ and End is the
430 dependency D was pointing to. Use in loops to iterate sensibly. */
431 void pkgCache::DepIterator::GlobOr(DepIterator
&Start
,DepIterator
&End
)
433 // Compute a single dependency element (glob or)
436 for (bool LastOR
= true; end() == false && LastOR
== true;)
438 LastOR
= (Dep
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
445 // VerIterator::CompareVer - Fast version compare for same pkgs /*{{{*/
446 // ---------------------------------------------------------------------
447 /* This just looks over the version list to see if B is listed before A. In
448 most cases this will return in under 4 checks, ver lists are short. */
449 int pkgCache::VerIterator::CompareVer(const VerIterator
&B
) const
451 // Check if they are equal
459 /* Start at A and look for B. If B is found then A > B otherwise
460 B was before A so A < B */
461 VerIterator I
= *this;
462 for (;I
.end() == false; I
++)
468 // VerIterator::Downloadable - Checks if the version is downloadable /*{{{*/
469 // ---------------------------------------------------------------------
471 bool pkgCache::VerIterator::Downloadable() const
473 VerFileIterator Files
= FileList();
474 for (; Files
.end() == false; Files
++)
475 if ((Files
.File()->Flags
& pkgCache::Flag::NotSource
) != pkgCache::Flag::NotSource
)
480 // VerIterator::Automatic - Check if this version is 'automatic' /*{{{*/
481 // ---------------------------------------------------------------------
482 /* This checks to see if any of the versions files are not NotAutomatic.
483 True if this version is selectable for automatic installation. */
484 bool pkgCache::VerIterator::Automatic() const
486 VerFileIterator Files
= FileList();
487 for (; Files
.end() == false; Files
++)
488 if ((Files
.File()->Flags
& pkgCache::Flag::NotAutomatic
) != pkgCache::Flag::NotAutomatic
)
493 // VerIterator::NewestFile - Return the newest file version relation /*{{{*/
494 // ---------------------------------------------------------------------
495 /* This looks at the version numbers associated with all of the sources
496 this version is in and returns the highest.*/
497 pkgCache::VerFileIterator
pkgCache::VerIterator::NewestFile() const
499 VerFileIterator Files
= FileList();
500 VerFileIterator Highest
= Files
;
501 for (; Files
.end() == false; Files
++)
503 if (Owner
->VS
->CmpReleaseVer(Files
.File().Version(),Highest
.File().Version()) > 0)
510 // VerIterator::RelStr - Release description string /*{{{*/
511 // ---------------------------------------------------------------------
512 /* This describes the version from a release-centric manner. The output is a
513 list of Label:Version/Archive */
514 string
pkgCache::VerIterator::RelStr()
518 for (pkgCache::VerFileIterator I
= this->FileList(); I
.end() == false; I
++)
520 // Do not print 'not source' entries'
521 pkgCache::PkgFileIterator File
= I
.File();
522 if ((File
->Flags
& pkgCache::Flag::NotSource
) == pkgCache::Flag::NotSource
)
525 // See if we have already printed this out..
527 for (pkgCache::VerFileIterator J
= this->FileList(); I
!= J
; J
++)
529 pkgCache::PkgFileIterator File2
= J
.File();
530 if (File2
->Label
== 0 || File
->Label
== 0)
533 if (strcmp(File
.Label(),File2
.Label()) != 0)
536 if (File2
->Version
== File
->Version
)
541 if (File2
->Version
== 0 || File
->Version
== 0)
543 if (strcmp(File
.Version(),File2
.Version()) == 0)
555 if (File
->Label
!= 0)
556 Res
= Res
+ File
.Label() + ':';
558 if (File
->Archive
!= 0)
560 if (File
->Version
== 0)
561 Res
+= File
.Archive();
563 Res
= Res
+ File
.Version() + '/' + File
.Archive();
567 // No release file, print the host name that this came from
568 if (File
->Site
== 0 || File
.Site()[0] == 0)
577 // PkgFileIterator::IsOk - Checks if the cache is in sync with the file /*{{{*/
578 // ---------------------------------------------------------------------
579 /* This stats the file and compares its stats with the ones that were
580 stored during generation. Date checks should probably also be
582 bool pkgCache::PkgFileIterator::IsOk()
585 if (stat(FileName(),&Buf
) != 0)
588 if (Buf
.st_size
!= (signed)File
->Size
|| Buf
.st_mtime
!= File
->mtime
)
594 // PkgFileIterator::RelStr - Return the release string /*{{{*/
595 // ---------------------------------------------------------------------
597 string
pkgCache::PkgFileIterator::RelStr()
601 Res
= Res
+ (Res
.empty() == true?"v=":",v=") + Version();
603 Res
= Res
+ (Res
.empty() == true?"o=":",o=") + Origin();
605 Res
= Res
+ (Res
.empty() == true?"a=":",a=") + Archive();
607 Res
= Res
+ (Res
.empty() == true?"l=":",l=") + Label();
608 if (Component() != 0)
609 Res
= Res
+ (Res
.empty() == true?"c=":",c=") + Component();
613 // VerIterator::TranslatedDescription - Return the a DescIter for locale/*{{{*/
614 // ---------------------------------------------------------------------
615 /* return a DescIter for the current locale or the default if none is
618 pkgCache::DescIterator
pkgCache::VerIterator::TranslatedDescription() const
620 pkgCache::DescIterator DescDefault
= DescriptionList();
621 pkgCache::DescIterator Desc
= DescDefault
;
622 for (; Desc
.end() == false; Desc
++)
623 if (pkgIndexFile::LanguageCode() == Desc
.LanguageCode())
625 if (Desc
.end() == true) Desc
= DescDefault
;