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/deblistparser.h>
25 #include <apt-pkg/macros.h>
27 #include <apt-pkg/debindexfile.h>
38 // Global list of Item supported
39 static pkgIndexFile::Type
*ItmList
[10];
40 pkgIndexFile::Type
**pkgIndexFile::Type::GlobalList
= ItmList
;
41 unsigned long pkgIndexFile::Type::GlobalListLen
= 0;
43 // Type::Type - Constructor /*{{{*/
44 // ---------------------------------------------------------------------
46 pkgIndexFile::Type::Type()
48 ItmList
[GlobalListLen
] = this;
53 // Type::GetType - Locate the type by name /*{{{*/
54 // ---------------------------------------------------------------------
56 pkgIndexFile::Type
*pkgIndexFile::Type::GetType(const char *Type
)
58 for (unsigned I
= 0; I
!= GlobalListLen
; I
++)
59 if (strcmp(GlobalList
[I
]->Label
,Type
) == 0)
64 pkgIndexFile::pkgIndexFile(bool const Trusted
) : /*{{{*/
65 d(NULL
), Trusted(Trusted
)
69 // IndexFile::ArchiveInfo - Stub /*{{{*/
70 std::string
pkgIndexFile::ArchiveInfo(pkgCache::VerIterator
const &Ver
) const
72 debDebPkgFileIndex
const * const debfile
= dynamic_cast<debDebPkgFileIndex
const*>(this);
73 if (debfile
!= nullptr)
74 return debfile
->ArchiveInfo_impl(Ver
);
78 // IndexFile::FindInCache - Stub /*{{{*/
79 pkgCache::PkgFileIterator
pkgIndexFile::FindInCache(pkgCache
&Cache
) const
81 return pkgCache::PkgFileIterator(Cache
);
84 // IndexFile::SourceIndex - Stub /*{{{*/
85 std::string
pkgIndexFile::SourceInfo(pkgSrcRecords::Parser
const &/*Record*/,
86 pkgSrcRecords::File
const &/*File*/) const
91 // IndexFile::TranslationsAvailable - Check if will use Translation /*{{{*/
92 bool pkgIndexFile::TranslationsAvailable() {
93 return (APT::Configuration::getLanguages().empty() != true);
96 // IndexFile::CheckLanguageCode - Check the Language Code /*{{{*/
97 bool pkgIndexFile::CheckLanguageCode(const char * const Lang
)
99 if (strlen(Lang
) == 2 || (strlen(Lang
) == 5 && Lang
[2] == '_'))
102 if (strcmp(Lang
,"C") != 0)
103 _error
->Warning("Wrong language code %s", Lang
);
108 // IndexFile::LanguageCode - Return the Language Code /*{{{*/
109 std::string
pkgIndexFile::LanguageCode() {
110 APT_IGNORE_DEPRECATED_PUSH
111 if (TranslationsAvailable() == false)
113 return APT::Configuration::getLanguages()[0];
114 APT_IGNORE_DEPRECATED_POP
118 // IndexTarget - Constructor /*{{{*/
119 IndexTarget::IndexTarget(std::string
const &MetaKey
, std::string
const &ShortDesc
,
120 std::string
const &LongDesc
, std::string
const &URI
, bool const IsOptional
,
121 bool const KeepCompressed
, std::map
<std::string
, std::string
> const &Options
) :
122 URI(URI
), Description(LongDesc
), ShortDesc(ShortDesc
), MetaKey(MetaKey
),
123 IsOptional(IsOptional
), KeepCompressed(KeepCompressed
), Options(Options
)
127 std::string
IndexTarget::Option(OptionKeys
const EnumKey
) const /*{{{*/
132 #define APT_CASE(X) case X: Key = #X; break
137 APT_CASE(ARCHITECTURE
);
140 APT_CASE(IDENTIFIER
);
142 APT_CASE(CREATED_BY
);
143 APT_CASE(FALLBACK_OF
);
145 APT_CASE(DEFAULTENABLED
);
146 APT_CASE(COMPRESSIONTYPES
);
147 APT_CASE(SOURCESENTRY
);
149 APT_CASE(KEEPCOMPRESSEDAS
);
150 APT_CASE(ALLOW_INSECURE
);
151 APT_CASE(ALLOW_WEAK
);
152 APT_CASE(ALLOW_DOWNGRADE_TO_INSECURE
);
156 auto const M
= Options
.find("FILENAME");
157 if (M
== Options
.end())
158 return _config
->FindDir("Dir::State::lists") + URItoFileName(URI
);
161 case EXISTING_FILENAME
:
162 std::string
const filename
= Option(FILENAME
);
163 std::vector
<std::string
> const types
= VectorizeString(Option(COMPRESSIONTYPES
), ' ');
164 for (std::vector
<std::string
>::const_iterator t
= types
.begin(); t
!= types
.end(); ++t
)
168 std::string
const file
= (*t
== "uncompressed") ? filename
: (filename
+ "." + *t
);
169 if (FileExists(file
))
174 std::map
<std::string
,std::string
>::const_iterator
const M
= Options
.find(Key
);
175 if (M
== Options
.end())
180 bool IndexTarget::OptionBool(OptionKeys
const EnumKey
) const /*{{{*/
182 return StringToBool(Option(EnumKey
), false);
185 std::string
IndexTarget::Format(std::string format
) const /*{{{*/
187 for (std::map
<std::string
, std::string
>::const_iterator O
= Options
.begin(); O
!= Options
.end(); ++O
)
189 format
= SubstVar(format
, std::string("$(") + O
->first
+ ")", O
->second
);
191 format
= SubstVar(format
, "$(METAKEY)", MetaKey
);
192 format
= SubstVar(format
, "$(SHORTDESC)", ShortDesc
);
193 format
= SubstVar(format
, "$(DESCRIPTION)", Description
);
194 format
= SubstVar(format
, "$(URI)", URI
);
195 format
= SubstVar(format
, "$(FILENAME)", Option(IndexTarget::FILENAME
));
200 pkgDebianIndexTargetFile::pkgDebianIndexTargetFile(IndexTarget
const &Target
, bool const Trusted
) :/*{{{*/
201 pkgDebianIndexFile(Trusted
), d(NULL
), Target(Target
)
205 std::string
pkgDebianIndexTargetFile::ArchiveURI(std::string
const &File
) const/*{{{*/
207 return Target
.Option(IndexTarget::REPO_URI
) + File
;
210 std::string
pkgDebianIndexTargetFile::Describe(bool const Short
) const /*{{{*/
213 return Target
.Description
;
214 return Target
.Description
+ " (" + IndexFileName() + ")";
217 std::string
pkgDebianIndexTargetFile::IndexFileName() const /*{{{*/
219 std::string
const s
= Target
.Option(IndexTarget::FILENAME
);
223 std::vector
<std::string
> const types
= VectorizeString(Target
.Option(IndexTarget::COMPRESSIONTYPES
), ' ');
224 for (std::vector
<std::string
>::const_iterator t
= types
.begin(); t
!= types
.end(); ++t
)
226 std::string p
= s
+ '.' + *t
;
233 unsigned long pkgDebianIndexTargetFile::Size() const /*{{{*/
235 unsigned long size
= 0;
237 /* we need to ignore errors here; if the lists are absent, just return 0 */
238 _error
->PushToStack();
240 FileFd
f(IndexFileName(), FileFd::ReadOnly
, FileFd::Extension
);
244 if (_error
->PendingError() == true)
246 _error
->RevertToStack();
251 bool pkgDebianIndexTargetFile::Exists() const /*{{{*/
253 return FileExists(IndexFileName());
256 std::string
pkgDebianIndexTargetFile::GetArchitecture() const /*{{{*/
258 return Target
.Option(IndexTarget::ARCHITECTURE
);
261 std::string
pkgDebianIndexTargetFile::GetComponent() const /*{{{*/
263 return Target
.Option(IndexTarget::COMPONENT
);
266 bool pkgDebianIndexTargetFile::OpenListFile(FileFd
&Pkg
, std::string
const &FileName
)/*{{{*/
268 if (Pkg
.Open(FileName
, FileFd::ReadOnly
, FileFd::Extension
) == false)
269 return _error
->Error("Problem opening %s",FileName
.c_str());
273 std::string
pkgDebianIndexTargetFile::GetProgressDescription() const
275 return Target
.Description
;
278 pkgDebianIndexRealFile::pkgDebianIndexRealFile(std::string
const &pFile
, bool const Trusted
) :/*{{{*/
279 pkgDebianIndexFile(Trusted
), d(NULL
)
283 else if (pFile
== "/nonexistent/stdin")
286 File
= flAbsPath(pFile
);
289 // IndexRealFile::Size - Return the size of the index /*{{{*/
290 unsigned long pkgDebianIndexRealFile::Size() const
293 if (stat(File
.c_str(),&S
) != 0)
298 bool pkgDebianIndexRealFile::Exists() const /*{{{*/
300 return FileExists(File
);
303 std::string
pkgDebianIndexRealFile::Describe(bool const /*Short*/) const/*{{{*/
308 std::string
pkgDebianIndexRealFile::ArchiveURI(std::string
const &/*File*/) const/*{{{*/
310 return "file:" + File
;
313 std::string
pkgDebianIndexRealFile::IndexFileName() const /*{{{*/
318 std::string
pkgDebianIndexRealFile::GetProgressDescription() const
322 bool pkgDebianIndexRealFile::OpenListFile(FileFd
&Pkg
, std::string
const &FileName
)/*{{{*/
324 if (Pkg
.Open(FileName
, FileFd::ReadOnly
, FileFd::Extension
) == false)
325 return _error
->Error("Problem opening %s",FileName
.c_str());
330 pkgDebianIndexFile::pkgDebianIndexFile(bool const Trusted
) : pkgIndexFile(Trusted
)
333 pkgDebianIndexFile::~pkgDebianIndexFile()
336 pkgCacheListParser
* pkgDebianIndexFile::CreateListParser(FileFd
&Pkg
)
338 if (Pkg
.IsOpen() == false)
340 _error
->PushToStack();
341 pkgCacheListParser
* const Parser
= new debListParser(&Pkg
);
342 bool const newError
= _error
->PendingError();
343 _error
->MergeWithStack();
352 bool pkgDebianIndexFile::Merge(pkgCacheGenerator
&Gen
,OpProgress
* const Prog
)
354 std::string
const PackageFile
= IndexFileName();
356 if (OpenListFile(Pkg
, PackageFile
) == false)
358 _error
->PushToStack();
359 std::unique_ptr
<pkgCacheListParser
> Parser(CreateListParser(Pkg
));
360 bool const newError
= _error
->PendingError();
361 _error
->MergeWithStack();
362 if (newError
== false && Parser
== nullptr)
368 Prog
->SubProgress(0, GetProgressDescription());
370 if (Gen
.SelectFile(PackageFile
, *this, GetArchitecture(), GetComponent(), GetIndexFlags()) == false)
371 return _error
->Error("Problem with SelectFile %s",PackageFile
.c_str());
373 // Store the IMS information
374 pkgCache::PkgFileIterator File
= Gen
.GetCurFile();
375 pkgCacheGenerator::Dynamic
<pkgCache::PkgFileIterator
> DynFile(File
);
376 File
->Size
= Pkg
.FileSize();
377 File
->mtime
= Pkg
.ModificationTime();
379 if (Gen
.MergeList(*Parser
) == false)
380 return _error
->Error("Problem with MergeList %s",PackageFile
.c_str());
383 pkgCache::PkgFileIterator
pkgDebianIndexFile::FindInCache(pkgCache
&Cache
) const
385 std::string
const FileName
= IndexFileName();
386 pkgCache::PkgFileIterator File
= Cache
.FileBegin();
387 for (; File
.end() == false; ++File
)
389 if (File
.FileName() == NULL
|| FileName
!= File
.FileName())
393 if (stat(File
.FileName(),&St
) != 0)
395 if (_config
->FindB("Debug::pkgCacheGen", false))
396 std::clog
<< "DebianIndexFile::FindInCache - stat failed on " << File
.FileName() << std::endl
;
397 return pkgCache::PkgFileIterator(Cache
);
399 if ((map_filesize_t
)St
.st_size
!= File
->Size
|| St
.st_mtime
!= File
->mtime
)
401 if (_config
->FindB("Debug::pkgCacheGen", false))
402 std::clog
<< "DebianIndexFile::FindInCache - size (" << St
.st_size
<< " <> " << File
->Size
403 << ") or mtime (" << St
.st_mtime
<< " <> " << File
->mtime
404 << ") doesn't match for " << File
.FileName() << std::endl
;
405 return pkgCache::PkgFileIterator(Cache
);
413 APT_CONST
pkgIndexFile::~pkgIndexFile() {}
414 APT_CONST
pkgDebianIndexTargetFile::~pkgDebianIndexTargetFile() {}
415 APT_CONST
pkgDebianIndexRealFile::~pkgDebianIndexRealFile() {}