]>
git.saurik.com Git - apt.git/blob - apt-pkg/indexfile.cc
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 // ---------------------------------------------------------------------
94 bool pkgIndexFile::TranslationsAvailable() {
95 return (APT::Configuration::getLanguages().empty() != true);
98 // IndexFile::CheckLanguageCode - Check the Language Code /*{{{*/
99 // ---------------------------------------------------------------------
100 /* No intern need for this method anymore as the check for correctness
101 is already done in getLanguages(). Note also that this check is
102 rather bad (doesn't take three character like ast into account).
103 TODO: Remove method with next API break */
104 APT_DEPRECATED
bool pkgIndexFile::CheckLanguageCode(const char * const Lang
)
106 if (strlen(Lang
) == 2 || (strlen(Lang
) == 5 && Lang
[2] == '_'))
109 if (strcmp(Lang
,"C") != 0)
110 _error
->Warning("Wrong language code %s", Lang
);
115 // IndexFile::LanguageCode - Return the Language Code /*{{{*/
116 // ---------------------------------------------------------------------
117 /* As we have now possibly more than one LanguageCode this method is
118 supersided by a) private classmembers or b) getLanguages().
119 TODO: Remove method with next API break */
120 APT_DEPRECATED
std::string
pkgIndexFile::LanguageCode() {
121 if (TranslationsAvailable() == false)
123 return APT::Configuration::getLanguages()[0];
127 // IndexTarget - Constructor /*{{{*/
128 IndexTarget::IndexTarget(std::string
const &MetaKey
, std::string
const &ShortDesc
,
129 std::string
const &LongDesc
, std::string
const &URI
, bool const IsOptional
,
130 bool const KeepCompressed
, std::map
<std::string
, std::string
> const &Options
) :
131 URI(URI
), Description(LongDesc
), ShortDesc(ShortDesc
), MetaKey(MetaKey
),
132 IsOptional(IsOptional
), KeepCompressed(KeepCompressed
), Options(Options
)
136 std::string
IndexTarget::Option(OptionKeys
const EnumKey
) const /*{{{*/
141 #define APT_CASE(X) case X: Key = #X; break
146 APT_CASE(ARCHITECTURE
);
150 APT_CASE(CREATED_BY
);
152 APT_CASE(DEFAULTENABLED
);
153 APT_CASE(COMPRESSIONTYPES
);
154 APT_CASE(SOURCESENTRY
);
157 case FILENAME
: return _config
->FindDir("Dir::State::lists") + URItoFileName(URI
);
158 case EXISTING_FILENAME
:
159 std::string
const filename
= Option(FILENAME
);
160 std::vector
<std::string
> const types
= VectorizeString(Option(COMPRESSIONTYPES
), ' ');
161 for (std::vector
<std::string
>::const_iterator t
= types
.begin(); t
!= types
.end(); ++t
)
165 std::string
const file
= (*t
== "uncompressed") ? filename
: (filename
+ "." + *t
);
166 if (FileExists(file
))
171 std::map
<std::string
,std::string
>::const_iterator
const M
= Options
.find(Key
);
172 if (M
== Options
.end())
177 bool IndexTarget::OptionBool(OptionKeys
const EnumKey
) const /*{{{*/
179 return StringToBool(Option(EnumKey
));
182 std::string
IndexTarget::Format(std::string format
) const /*{{{*/
184 for (std::map
<std::string
, std::string
>::const_iterator O
= Options
.begin(); O
!= Options
.end(); ++O
)
186 format
= SubstVar(format
, std::string("$(") + O
->first
+ ")", O
->second
);
188 format
= SubstVar(format
, "$(METAKEY)", MetaKey
);
189 format
= SubstVar(format
, "$(SHORTDESC)", ShortDesc
);
190 format
= SubstVar(format
, "$(DESCRIPTION)", Description
);
191 format
= SubstVar(format
, "$(URI)", URI
);
192 format
= SubstVar(format
, "$(FILENAME)", Option(IndexTarget::FILENAME
));
197 pkgDebianIndexTargetFile::pkgDebianIndexTargetFile(IndexTarget
const &Target
, bool const Trusted
) :/*{{{*/
198 pkgDebianIndexFile(Trusted
), d(NULL
), Target(Target
)
202 std::string
pkgDebianIndexTargetFile::ArchiveURI(std::string
const &File
) const/*{{{*/
204 return Target
.Option(IndexTarget::REPO_URI
) + File
;
207 std::string
pkgDebianIndexTargetFile::Describe(bool const Short
) const /*{{{*/
210 return Target
.Description
;
211 return Target
.Description
+ " (" + IndexFileName() + ")";
214 std::string
pkgDebianIndexTargetFile::IndexFileName() const /*{{{*/
216 std::string
const s
= Target
.Option(IndexTarget::FILENAME
);
220 std::vector
<std::string
> const types
= VectorizeString(Target
.Option(IndexTarget::COMPRESSIONTYPES
), ' ');
221 for (std::vector
<std::string
>::const_iterator t
= types
.begin(); t
!= types
.end(); ++t
)
223 std::string p
= s
+ '.' + *t
;
230 unsigned long pkgDebianIndexTargetFile::Size() const /*{{{*/
232 unsigned long size
= 0;
234 /* we need to ignore errors here; if the lists are absent, just return 0 */
235 _error
->PushToStack();
237 FileFd
f(IndexFileName(), FileFd::ReadOnly
, FileFd::Extension
);
241 if (_error
->PendingError() == true)
243 _error
->RevertToStack();
248 bool pkgDebianIndexTargetFile::Exists() const /*{{{*/
250 return FileExists(IndexFileName());
253 std::string
pkgDebianIndexTargetFile::GetArchitecture() const /*{{{*/
255 return Target
.Option(IndexTarget::ARCHITECTURE
);
258 std::string
pkgDebianIndexTargetFile::GetComponent() const /*{{{*/
260 return Target
.Option(IndexTarget::COMPONENT
);
263 bool pkgDebianIndexTargetFile::OpenListFile(FileFd
&Pkg
, std::string
const &FileName
)/*{{{*/
265 if (Pkg
.Open(FileName
, FileFd::ReadOnly
, FileFd::Extension
) == false)
266 return _error
->Error("Problem opening %s",FileName
.c_str());
270 std::string
pkgDebianIndexTargetFile::GetProgressDescription() const
272 return Target
.Description
;
275 pkgDebianIndexRealFile::pkgDebianIndexRealFile(std::string
const &pFile
, bool const Trusted
) :/*{{{*/
276 pkgDebianIndexFile(Trusted
), d(NULL
)
278 if (pFile
== "/nonexistent/stdin")
281 File
= flAbsPath(pFile
);
284 // IndexRealFile::Size - Return the size of the index /*{{{*/
285 unsigned long pkgDebianIndexRealFile::Size() const
288 if (stat(File
.c_str(),&S
) != 0)
293 bool pkgDebianIndexRealFile::Exists() const /*{{{*/
295 return FileExists(File
);
298 std::string
pkgDebianIndexRealFile::Describe(bool const /*Short*/) const/*{{{*/
303 std::string
pkgDebianIndexRealFile::ArchiveURI(std::string
const &/*File*/) const/*{{{*/
305 return "file:" + File
;
308 std::string
pkgDebianIndexRealFile::IndexFileName() const /*{{{*/
313 std::string
pkgDebianIndexRealFile::GetProgressDescription() const
317 bool pkgDebianIndexRealFile::OpenListFile(FileFd
&Pkg
, std::string
const &FileName
)/*{{{*/
319 if (Pkg
.Open(FileName
, FileFd::ReadOnly
, FileFd::None
) == false)
320 return _error
->Error("Problem opening %s",FileName
.c_str());
325 pkgDebianIndexFile::pkgDebianIndexFile(bool const Trusted
) : pkgIndexFile(Trusted
)
328 pkgDebianIndexFile::~pkgDebianIndexFile()
331 pkgCacheListParser
* pkgDebianIndexFile::CreateListParser(FileFd
&Pkg
)
333 if (Pkg
.IsOpen() == false)
335 _error
->PushToStack();
336 pkgCacheListParser
* const Parser
= new debListParser(&Pkg
);
337 bool const newError
= _error
->PendingError();
338 _error
->MergeWithStack();
339 return newError
? NULL
: Parser
;
341 bool pkgDebianIndexFile::Merge(pkgCacheGenerator
&Gen
,OpProgress
* const Prog
)
343 std::string
const PackageFile
= IndexFileName();
345 if (OpenListFile(Pkg
, PackageFile
) == false)
347 _error
->PushToStack();
348 std::unique_ptr
<pkgCacheListParser
> Parser(CreateListParser(Pkg
));
349 bool const newError
= _error
->PendingError();
350 _error
->MergeWithStack();
351 if (newError
== false && Parser
== nullptr)
357 Prog
->SubProgress(0, GetProgressDescription());
359 if (Gen
.SelectFile(PackageFile
, *this, GetArchitecture(), GetComponent(), GetIndexFlags()) == false)
360 return _error
->Error("Problem with SelectFile %s",PackageFile
.c_str());
362 // Store the IMS information
363 pkgCache::PkgFileIterator File
= Gen
.GetCurFile();
364 pkgCacheGenerator::Dynamic
<pkgCache::PkgFileIterator
> DynFile(File
);
365 File
->Size
= Pkg
.FileSize();
366 File
->mtime
= Pkg
.ModificationTime();
368 if (Gen
.MergeList(*Parser
) == false)
369 return _error
->Error("Problem with MergeList %s",PackageFile
.c_str());
372 pkgCache::PkgFileIterator
pkgDebianIndexFile::FindInCache(pkgCache
&Cache
) const
374 std::string
const FileName
= IndexFileName();
375 pkgCache::PkgFileIterator File
= Cache
.FileBegin();
376 for (; File
.end() == false; ++File
)
378 if (File
.FileName() == NULL
|| FileName
!= File
.FileName())
382 if (stat(File
.FileName(),&St
) != 0)
384 if (_config
->FindB("Debug::pkgCacheGen", false))
385 std::clog
<< "DebianIndexFile::FindInCache - stat failed on " << File
.FileName() << std::endl
;
386 return pkgCache::PkgFileIterator(Cache
);
388 if ((map_filesize_t
)St
.st_size
!= File
->Size
|| St
.st_mtime
!= File
->mtime
)
390 if (_config
->FindB("Debug::pkgCacheGen", false))
391 std::clog
<< "DebianIndexFile::FindInCache - size (" << St
.st_size
<< " <> " << File
->Size
392 << ") or mtime (" << St
.st_mtime
<< " <> " << File
->mtime
393 << ") doesn't match for " << File
.FileName() << std::endl
;
394 return pkgCache::PkgFileIterator(Cache
);
402 APT_CONST
pkgIndexFile::~pkgIndexFile() {}
403 APT_CONST
pkgDebianIndexTargetFile::~pkgDebianIndexTargetFile() {}
404 APT_CONST
pkgDebianIndexRealFile::~pkgDebianIndexRealFile() {}