]>
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/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
);
150 APT_CASE(SOURCESENTRY
);
153 case FILENAME
: return _config
->FindDir("Dir::State::lists") + URItoFileName(URI
);
154 case EXISTING_FILENAME
:
155 std::string
const filename
= Option(FILENAME
);
156 std::vector
<std::string
> const types
= VectorizeString(Option(COMPRESSIONTYPES
), ' ');
157 for (std::vector
<std::string
>::const_iterator t
= types
.begin(); t
!= types
.end(); ++t
)
161 std::string
const file
= (*t
== "uncompressed") ? filename
: (filename
+ "." + *t
);
162 if (FileExists(file
))
167 std::map
<std::string
,std::string
>::const_iterator
const M
= Options
.find(Key
);
168 if (M
== Options
.end())
173 bool IndexTarget::OptionBool(OptionKeys
const EnumKey
) const /*{{{*/
175 return StringToBool(Option(EnumKey
));
178 std::string
IndexTarget::Format(std::string format
) const /*{{{*/
180 for (std::map
<std::string
, std::string
>::const_iterator O
= Options
.begin(); O
!= Options
.end(); ++O
)
182 format
= SubstVar(format
, std::string("$(") + O
->first
+ ")", O
->second
);
184 format
= SubstVar(format
, "$(METAKEY)", MetaKey
);
185 format
= SubstVar(format
, "$(SHORTDESC)", ShortDesc
);
186 format
= SubstVar(format
, "$(DESCRIPTION)", Description
);
187 format
= SubstVar(format
, "$(URI)", URI
);
188 format
= SubstVar(format
, "$(FILENAME)", Option(IndexTarget::FILENAME
));
193 pkgDebianIndexTargetFile::pkgDebianIndexTargetFile(IndexTarget
const &Target
, bool const Trusted
) :/*{{{*/
194 pkgDebianIndexFile(Trusted
), d(NULL
), Target(Target
)
198 std::string
pkgDebianIndexTargetFile::ArchiveURI(std::string
const &File
) const/*{{{*/
200 return Target
.Option(IndexTarget::REPO_URI
) + File
;
203 std::string
pkgDebianIndexTargetFile::Describe(bool const Short
) const /*{{{*/
206 return Target
.Description
;
207 return Target
.Description
+ " (" + IndexFileName() + ")";
210 std::string
pkgDebianIndexTargetFile::IndexFileName() const /*{{{*/
212 std::string
const s
= Target
.Option(IndexTarget::FILENAME
);
216 std::vector
<std::string
> const types
= VectorizeString(Target
.Option(IndexTarget::COMPRESSIONTYPES
), ' ');
217 for (std::vector
<std::string
>::const_iterator t
= types
.begin(); t
!= types
.end(); ++t
)
219 std::string p
= s
+ '.' + *t
;
226 unsigned long pkgDebianIndexTargetFile::Size() const /*{{{*/
228 unsigned long size
= 0;
230 /* we need to ignore errors here; if the lists are absent, just return 0 */
231 _error
->PushToStack();
233 FileFd
f(IndexFileName(), FileFd::ReadOnly
, FileFd::Extension
);
237 if (_error
->PendingError() == true)
239 _error
->RevertToStack();
244 bool pkgDebianIndexTargetFile::Exists() const /*{{{*/
246 return FileExists(IndexFileName());
249 std::string
pkgDebianIndexTargetFile::GetArchitecture() const /*{{{*/
251 return Target
.Option(IndexTarget::ARCHITECTURE
);
254 std::string
pkgDebianIndexTargetFile::GetComponent() const /*{{{*/
256 return Target
.Option(IndexTarget::COMPONENT
);
259 bool pkgDebianIndexTargetFile::OpenListFile(FileFd
&Pkg
, std::string
const &FileName
)/*{{{*/
261 if (Pkg
.Open(FileName
, FileFd::ReadOnly
, FileFd::Extension
) == false)
262 return _error
->Error("Problem opening %s",FileName
.c_str());
266 std::string
pkgDebianIndexTargetFile::GetProgressDescription() const
268 return Target
.Description
;
271 pkgDebianIndexRealFile::pkgDebianIndexRealFile(std::string
const &pFile
, bool const Trusted
) :/*{{{*/
272 pkgDebianIndexFile(Trusted
), d(NULL
)
274 if (pFile
== "/nonexistent/stdin")
277 File
= flAbsPath(pFile
);
280 // IndexRealFile::Size - Return the size of the index /*{{{*/
281 unsigned long pkgDebianIndexRealFile::Size() const
284 if (stat(File
.c_str(),&S
) != 0)
289 bool pkgDebianIndexRealFile::Exists() const /*{{{*/
291 return FileExists(File
);
294 std::string
pkgDebianIndexRealFile::Describe(bool const /*Short*/) const/*{{{*/
299 std::string
pkgDebianIndexRealFile::ArchiveURI(std::string
const &/*File*/) const/*{{{*/
301 return "file:" + File
;
304 std::string
pkgDebianIndexRealFile::IndexFileName() const /*{{{*/
309 std::string
pkgDebianIndexRealFile::GetProgressDescription() const
313 bool pkgDebianIndexRealFile::OpenListFile(FileFd
&Pkg
, std::string
const &FileName
)/*{{{*/
315 if (Pkg
.Open(FileName
, FileFd::ReadOnly
, FileFd::None
) == false)
316 return _error
->Error("Problem opening %s",FileName
.c_str());
321 pkgDebianIndexFile::pkgDebianIndexFile(bool const Trusted
) : pkgIndexFile(Trusted
)
324 pkgDebianIndexFile::~pkgDebianIndexFile()
327 pkgCacheListParser
* pkgDebianIndexFile::CreateListParser(FileFd
&Pkg
)
329 if (Pkg
.IsOpen() == false)
331 _error
->PushToStack();
332 pkgCacheListParser
* const Parser
= new debListParser(&Pkg
);
333 bool const newError
= _error
->PendingError();
334 _error
->MergeWithStack();
335 return newError
? NULL
: Parser
;
337 bool pkgDebianIndexFile::Merge(pkgCacheGenerator
&Gen
,OpProgress
* const Prog
)
339 std::string
const PackageFile
= IndexFileName();
341 if (OpenListFile(Pkg
, PackageFile
) == false)
343 _error
->PushToStack();
344 std::unique_ptr
<pkgCacheListParser
> Parser(CreateListParser(Pkg
));
345 bool const newError
= _error
->PendingError();
346 _error
->MergeWithStack();
347 if (newError
== false && Parser
== nullptr)
353 Prog
->SubProgress(0, GetProgressDescription());
355 if (Gen
.SelectFile(PackageFile
, *this, GetArchitecture(), GetComponent(), GetIndexFlags()) == false)
356 return _error
->Error("Problem with SelectFile %s",PackageFile
.c_str());
358 // Store the IMS information
359 pkgCache::PkgFileIterator File
= Gen
.GetCurFile();
360 pkgCacheGenerator::Dynamic
<pkgCache::PkgFileIterator
> DynFile(File
);
361 File
->Size
= Pkg
.FileSize();
362 File
->mtime
= Pkg
.ModificationTime();
364 if (Gen
.MergeList(*Parser
) == false)
365 return _error
->Error("Problem with MergeList %s",PackageFile
.c_str());
368 pkgCache::PkgFileIterator
pkgDebianIndexFile::FindInCache(pkgCache
&Cache
) const
370 std::string
const FileName
= IndexFileName();
371 pkgCache::PkgFileIterator File
= Cache
.FileBegin();
372 for (; File
.end() == false; ++File
)
374 if (File
.FileName() == NULL
|| FileName
!= File
.FileName())
378 if (stat(File
.FileName(),&St
) != 0)
380 if (_config
->FindB("Debug::pkgCacheGen", false))
381 std::clog
<< "DebianIndexFile::FindInCache - stat failed on " << File
.FileName() << std::endl
;
382 return pkgCache::PkgFileIterator(Cache
);
384 if ((map_filesize_t
)St
.st_size
!= File
->Size
|| St
.st_mtime
!= File
->mtime
)
386 if (_config
->FindB("Debug::pkgCacheGen", false))
387 std::clog
<< "DebianIndexFile::FindInCache - size (" << St
.st_size
<< " <> " << File
->Size
388 << ") or mtime (" << St
.st_mtime
<< " <> " << File
->mtime
389 << ") doesn't match for " << File
.FileName() << std::endl
;
390 return pkgCache::PkgFileIterator(Cache
);
398 APT_CONST
pkgIndexFile::~pkgIndexFile() {}
399 APT_CONST
pkgDebianIndexTargetFile::~pkgDebianIndexTargetFile() {}
400 APT_CONST
pkgDebianIndexRealFile::~pkgDebianIndexRealFile() {}