]>
git.saurik.com Git - apt.git/blob - apt-pkg/indexfile.cc
1ed7984101f03bf8a2a418ce21cd07c140462620
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: indexfile.cc,v 1.2.2.1 2003/12/24 23:09:17 mdz Exp $
4 /* ######################################################################
6 Index File - Abstraction for an index of archive/souce file.
8 ##################################################################### */
10 // Include Files /*{{{*/
13 #include <apt-pkg/configuration.h>
14 #include <apt-pkg/indexfile.h>
15 #include <apt-pkg/error.h>
16 #include <apt-pkg/fileutl.h>
17 #include <apt-pkg/aptconfiguration.h>
18 #include <apt-pkg/pkgcache.h>
19 #include <apt-pkg/pkgcachegen.h>
20 #include <apt-pkg/cacheiterators.h>
21 #include <apt-pkg/srcrecords.h>
22 #include <apt-pkg/strutl.h>
23 #include <apt-pkg/progress.h>
24 #include <apt-pkg/macros.h>
26 #include <apt-pkg/deblistparser.h>
37 // Global list of Item supported
38 static pkgIndexFile::Type
*ItmList
[10];
39 pkgIndexFile::Type
**pkgIndexFile::Type::GlobalList
= ItmList
;
40 unsigned long pkgIndexFile::Type::GlobalListLen
= 0;
42 // Type::Type - Constructor /*{{{*/
43 // ---------------------------------------------------------------------
45 pkgIndexFile::Type::Type()
47 ItmList
[GlobalListLen
] = this;
52 // Type::GetType - Locate the type by name /*{{{*/
53 // ---------------------------------------------------------------------
55 pkgIndexFile::Type
*pkgIndexFile::Type::GetType(const char *Type
)
57 for (unsigned I
= 0; I
!= GlobalListLen
; I
++)
58 if (strcmp(GlobalList
[I
]->Label
,Type
) == 0)
63 pkgIndexFile::pkgIndexFile(bool const Trusted
) : /*{{{*/
64 d(NULL
), Trusted(Trusted
)
68 // IndexFile::ArchiveInfo - Stub /*{{{*/
69 std::string
pkgIndexFile::ArchiveInfo(pkgCache::VerIterator
const &/*Ver*/) const
74 // IndexFile::FindInCache - Stub /*{{{*/
75 pkgCache::PkgFileIterator
pkgIndexFile::FindInCache(pkgCache
&Cache
) const
77 return pkgCache::PkgFileIterator(Cache
);
80 // IndexFile::SourceIndex - Stub /*{{{*/
81 std::string
pkgIndexFile::SourceInfo(pkgSrcRecords::Parser
const &/*Record*/,
82 pkgSrcRecords::File
const &/*File*/) const
87 // IndexFile::TranslationsAvailable - Check if will use Translation /*{{{*/
88 // ---------------------------------------------------------------------
90 bool pkgIndexFile::TranslationsAvailable() {
91 return (APT::Configuration::getLanguages().empty() != true);
94 // IndexFile::CheckLanguageCode - Check the Language Code /*{{{*/
95 // ---------------------------------------------------------------------
96 /* No intern need for this method anymore as the check for correctness
97 is already done in getLanguages(). Note also that this check is
98 rather bad (doesn't take three character like ast into account).
99 TODO: Remove method with next API break */
100 APT_DEPRECATED
bool pkgIndexFile::CheckLanguageCode(const char * const Lang
)
102 if (strlen(Lang
) == 2 || (strlen(Lang
) == 5 && Lang
[2] == '_'))
105 if (strcmp(Lang
,"C") != 0)
106 _error
->Warning("Wrong language code %s", Lang
);
111 // IndexFile::LanguageCode - Return the Language Code /*{{{*/
112 // ---------------------------------------------------------------------
113 /* As we have now possibly more than one LanguageCode this method is
114 supersided by a) private classmembers or b) getLanguages().
115 TODO: Remove method with next API break */
116 APT_DEPRECATED
std::string
pkgIndexFile::LanguageCode() {
117 if (TranslationsAvailable() == false)
119 return APT::Configuration::getLanguages()[0];
123 // IndexTarget - Constructor /*{{{*/
124 IndexTarget::IndexTarget(std::string
const &MetaKey
, std::string
const &ShortDesc
,
125 std::string
const &LongDesc
, std::string
const &URI
, bool const IsOptional
,
126 bool const KeepCompressed
, std::map
<std::string
, std::string
> const &Options
) :
127 URI(URI
), Description(LongDesc
), ShortDesc(ShortDesc
), MetaKey(MetaKey
),
128 IsOptional(IsOptional
), KeepCompressed(KeepCompressed
), Options(Options
)
132 std::string
IndexTarget::Option(OptionKeys
const EnumKey
) const /*{{{*/
137 #define APT_CASE(X) case X: Key = #X; break
142 APT_CASE(ARCHITECTURE
);
146 APT_CASE(CREATED_BY
);
148 APT_CASE(DEFAULTENABLED
);
149 APT_CASE(COMPRESSIONTYPES
);
151 case FILENAME
: return _config
->FindDir("Dir::State::lists") + URItoFileName(URI
);
152 case EXISTING_FILENAME
:
153 std::string
const filename
= Option(FILENAME
);
154 std::vector
<std::string
> const types
= VectorizeString(Option(COMPRESSIONTYPES
), ' ');
155 for (std::vector
<std::string
>::const_iterator t
= types
.begin(); t
!= types
.end(); ++t
)
159 std::string
const file
= (*t
== "uncompressed") ? filename
: (filename
+ "." + *t
);
160 if (FileExists(file
))
165 std::map
<std::string
,std::string
>::const_iterator
const M
= Options
.find(Key
);
166 if (M
== Options
.end())
171 bool IndexTarget::OptionBool(OptionKeys
const EnumKey
) const /*{{{*/
173 return StringToBool(Option(EnumKey
));
176 std::string
IndexTarget::Format(std::string format
) const /*{{{*/
178 for (std::map
<std::string
, std::string
>::const_iterator O
= Options
.begin(); O
!= Options
.end(); ++O
)
180 format
= SubstVar(format
, std::string("$(") + O
->first
+ ")", O
->second
);
182 format
= SubstVar(format
, "$(METAKEY)", MetaKey
);
183 format
= SubstVar(format
, "$(SHORTDESC)", ShortDesc
);
184 format
= SubstVar(format
, "$(DESCRIPTION)", Description
);
185 format
= SubstVar(format
, "$(URI)", URI
);
186 format
= SubstVar(format
, "$(FILENAME)", Option(IndexTarget::FILENAME
));
191 pkgDebianIndexTargetFile::pkgDebianIndexTargetFile(IndexTarget
const &Target
, bool const Trusted
) :/*{{{*/
192 pkgDebianIndexFile(Trusted
), d(NULL
), Target(Target
)
196 std::string
pkgDebianIndexTargetFile::ArchiveURI(std::string
const &File
) const/*{{{*/
198 return Target
.Option(IndexTarget::REPO_URI
) + File
;
201 std::string
pkgDebianIndexTargetFile::Describe(bool const Short
) const /*{{{*/
204 return Target
.Description
;
205 return Target
.Description
+ " (" + IndexFileName() + ")";
208 std::string
pkgDebianIndexTargetFile::IndexFileName() const /*{{{*/
210 std::string
const s
= Target
.Option(IndexTarget::FILENAME
);
214 std::vector
<std::string
> const types
= VectorizeString(Target
.Option(IndexTarget::COMPRESSIONTYPES
), ' ');
215 for (std::vector
<std::string
>::const_iterator t
= types
.begin(); t
!= types
.end(); ++t
)
217 std::string p
= s
+ '.' + *t
;
224 unsigned long pkgDebianIndexTargetFile::Size() const /*{{{*/
226 unsigned long size
= 0;
228 /* we need to ignore errors here; if the lists are absent, just return 0 */
229 _error
->PushToStack();
231 FileFd
f(IndexFileName(), FileFd::ReadOnly
, FileFd::Extension
);
235 if (_error
->PendingError() == true)
237 _error
->RevertToStack();
242 bool pkgDebianIndexTargetFile::Exists() const /*{{{*/
244 return FileExists(IndexFileName());
247 std::string
pkgDebianIndexTargetFile::GetArchitecture() const /*{{{*/
249 return Target
.Option(IndexTarget::ARCHITECTURE
);
252 std::string
pkgDebianIndexTargetFile::GetComponent() const /*{{{*/
254 return Target
.Option(IndexTarget::COMPONENT
);
257 bool pkgDebianIndexTargetFile::OpenListFile(FileFd
&Pkg
, std::string
const &FileName
)/*{{{*/
259 if (Pkg
.Open(FileName
, FileFd::ReadOnly
, FileFd::Extension
) == false)
260 return _error
->Error("Problem opening %s",FileName
.c_str());
264 std::string
pkgDebianIndexTargetFile::GetProgressDescription() const
266 return Target
.Description
;
269 pkgDebianIndexRealFile::pkgDebianIndexRealFile(std::string
const &File
, bool const Trusted
) :/*{{{*/
270 pkgDebianIndexFile(Trusted
), d(NULL
), File(flAbsPath(File
))
274 // IndexRealFile::Size - Return the size of the index /*{{{*/
275 unsigned long pkgDebianIndexRealFile::Size() const
278 if (stat(File
.c_str(),&S
) != 0)
283 bool pkgDebianIndexRealFile::Exists() const /*{{{*/
285 return FileExists(File
);
288 std::string
pkgDebianIndexRealFile::Describe(bool const /*Short*/) const/*{{{*/
293 std::string
pkgDebianIndexRealFile::ArchiveURI(std::string
const &/*File*/) const/*{{{*/
295 return "file:" + File
;
298 std::string
pkgDebianIndexRealFile::IndexFileName() const /*{{{*/
303 std::string
pkgDebianIndexRealFile::GetProgressDescription() const
307 bool pkgDebianIndexRealFile::OpenListFile(FileFd
&Pkg
, std::string
const &FileName
)/*{{{*/
309 if (Pkg
.Open(FileName
, FileFd::ReadOnly
, FileFd::None
) == false)
310 return _error
->Error("Problem opening %s",FileName
.c_str());
315 pkgDebianIndexFile::pkgDebianIndexFile(bool const Trusted
) : pkgIndexFile(Trusted
)
318 pkgDebianIndexFile::~pkgDebianIndexFile()
321 pkgCacheListParser
* pkgDebianIndexFile::CreateListParser(FileFd
&Pkg
)
323 if (Pkg
.IsOpen() == false)
325 _error
->PushToStack();
326 pkgCacheListParser
* const Parser
= new debListParser(&Pkg
);
327 bool const newError
= _error
->PendingError();
328 _error
->MergeWithStack();
329 return newError
? NULL
: Parser
;
331 bool pkgDebianIndexFile::Merge(pkgCacheGenerator
&Gen
,OpProgress
* const Prog
)
333 std::string
const PackageFile
= IndexFileName();
335 if (OpenListFile(Pkg
, PackageFile
) == false)
337 _error
->PushToStack();
338 std::unique_ptr
<pkgCacheListParser
> Parser(CreateListParser(Pkg
));
339 bool const newError
= _error
->PendingError();
340 if (newError
== false && Parser
== nullptr)
346 Prog
->SubProgress(0, GetProgressDescription());
348 if (Gen
.SelectFile(PackageFile
, *this, GetArchitecture(), GetComponent(), GetIndexFlags()) == false)
349 return _error
->Error("Problem with SelectFile %s",PackageFile
.c_str());
351 // Store the IMS information
352 pkgCache::PkgFileIterator File
= Gen
.GetCurFile();
353 pkgCacheGenerator::Dynamic
<pkgCache::PkgFileIterator
> DynFile(File
);
354 File
->Size
= Pkg
.FileSize();
355 File
->mtime
= Pkg
.ModificationTime();
357 if (Gen
.MergeList(*Parser
) == false)
358 return _error
->Error("Problem with MergeList %s",PackageFile
.c_str());
361 pkgCache::PkgFileIterator
pkgDebianIndexFile::FindInCache(pkgCache
&Cache
) const
363 std::string
const FileName
= IndexFileName();
364 pkgCache::PkgFileIterator File
= Cache
.FileBegin();
365 for (; File
.end() == false; ++File
)
367 if (File
.FileName() == NULL
|| FileName
!= File
.FileName())
371 if (stat(File
.FileName(),&St
) != 0)
373 if (_config
->FindB("Debug::pkgCacheGen", false))
374 std::clog
<< "DebianIndexFile::FindInCache - stat failed on " << File
.FileName() << std::endl
;
375 return pkgCache::PkgFileIterator(Cache
);
377 if ((map_filesize_t
)St
.st_size
!= File
->Size
|| St
.st_mtime
!= File
->mtime
)
379 if (_config
->FindB("Debug::pkgCacheGen", false))
380 std::clog
<< "DebianIndexFile::FindInCache - size (" << St
.st_size
<< " <> " << File
->Size
381 << ") or mtime (" << St
.st_mtime
<< " <> " << File
->mtime
382 << ") doesn't match for " << File
.FileName() << std::endl
;
383 return pkgCache::PkgFileIterator(Cache
);
391 APT_CONST
pkgIndexFile::~pkgIndexFile() {}
392 APT_CONST
pkgDebianIndexTargetFile::~pkgDebianIndexTargetFile() {}
393 APT_CONST
pkgDebianIndexRealFile::~pkgDebianIndexRealFile() {}