]> git.saurik.com Git - apt.git/blame - apt-pkg/indexfile.cc
use c++11 algorithms to avoid strange compiler warnings
[apt.git] / apt-pkg / indexfile.cc
CommitLineData
b2e465d6
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
7db98ffc 3// $Id: indexfile.cc,v 1.2.2.1 2003/12/24 23:09:17 mdz Exp $
b2e465d6
AL
4/* ######################################################################
5
6 Index File - Abstraction for an index of archive/souce file.
7
8 ##################################################################### */
9 /*}}}*/
10// Include Files /*{{{*/
ea542140
DK
11#include<config.h>
12
e3c1cfc7 13#include <apt-pkg/configuration.h>
b2e465d6
AL
14#include <apt-pkg/indexfile.h>
15#include <apt-pkg/error.h>
e3c1cfc7 16#include <apt-pkg/fileutl.h>
45df0ad2 17#include <apt-pkg/aptconfiguration.h>
453b82a3 18#include <apt-pkg/pkgcache.h>
c9443c01 19#include <apt-pkg/pkgcachegen.h>
453b82a3
DK
20#include <apt-pkg/cacheiterators.h>
21#include <apt-pkg/srcrecords.h>
d7a51997 22#include <apt-pkg/strutl.h>
c9443c01 23#include <apt-pkg/progress.h>
453b82a3 24#include <apt-pkg/macros.h>
a52f938b 25
c9443c01
DK
26#include <apt-pkg/deblistparser.h>
27
c9443c01 28#include <sys/stat.h>
c9443c01 29
453b82a3
DK
30#include <string>
31#include <vector>
a52f938b 32#include <clocale>
4f333a8b 33#include <cstring>
c9443c01 34#include <memory>
b2e465d6
AL
35 /*}}}*/
36
37// Global list of Item supported
38static pkgIndexFile::Type *ItmList[10];
39pkgIndexFile::Type **pkgIndexFile::Type::GlobalList = ItmList;
40unsigned long pkgIndexFile::Type::GlobalListLen = 0;
41
42// Type::Type - Constructor /*{{{*/
43// ---------------------------------------------------------------------
44/* */
45pkgIndexFile::Type::Type()
46{
47 ItmList[GlobalListLen] = this;
dd688285
DK
48 GlobalListLen++;
49 Label = NULL;
b2e465d6
AL
50}
51 /*}}}*/
52// Type::GetType - Locate the type by name /*{{{*/
53// ---------------------------------------------------------------------
54/* */
55pkgIndexFile::Type *pkgIndexFile::Type::GetType(const char *Type)
56{
57 for (unsigned I = 0; I != GlobalListLen; I++)
58 if (strcmp(GlobalList[I]->Label,Type) == 0)
59 return GlobalList[I];
60 return 0;
e3c1cfc7
DK
61}
62 /*}}}*/
c9443c01 63pkgIndexFile::pkgIndexFile(bool const Trusted) : /*{{{*/
6c55f07a 64 d(NULL), Trusted(Trusted)
e3c1cfc7 65{
b2e465d6
AL
66}
67 /*}}}*/
b2e465d6 68// IndexFile::ArchiveInfo - Stub /*{{{*/
c9443c01 69std::string pkgIndexFile::ArchiveInfo(pkgCache::VerIterator const &/*Ver*/) const
b2e465d6 70{
8f3ba4e8 71 return std::string();
b2e465d6
AL
72}
73 /*}}}*/
74// IndexFile::FindInCache - Stub /*{{{*/
b2e465d6
AL
75pkgCache::PkgFileIterator pkgIndexFile::FindInCache(pkgCache &Cache) const
76{
77 return pkgCache::PkgFileIterator(Cache);
78}
79 /*}}}*/
80// IndexFile::SourceIndex - Stub /*{{{*/
65512241
DK
81std::string pkgIndexFile::SourceInfo(pkgSrcRecords::Parser const &/*Record*/,
82 pkgSrcRecords::File const &/*File*/) const
b2e465d6 83{
8f3ba4e8 84 return std::string();
b2e465d6
AL
85}
86 /*}}}*/
45df0ad2 87// IndexFile::TranslationsAvailable - Check if will use Translation /*{{{*/
a52f938b
OS
88// ---------------------------------------------------------------------
89/* */
45df0ad2
DK
90bool pkgIndexFile::TranslationsAvailable() {
91 return (APT::Configuration::getLanguages().empty() != true);
a52f938b
OS
92}
93 /*}}}*/
45df0ad2 94// IndexFile::CheckLanguageCode - Check the Language Code /*{{{*/
a52f938b 95// ---------------------------------------------------------------------
45df0ad2
DK
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 */
c9443c01 100APT_DEPRECATED bool pkgIndexFile::CheckLanguageCode(const char * const Lang)
a52f938b
OS
101{
102 if (strlen(Lang) == 2 || (strlen(Lang) == 5 && Lang[2] == '_'))
103 return true;
104
105 if (strcmp(Lang,"C") != 0)
106 _error->Warning("Wrong language code %s", Lang);
107
108 return false;
109}
110 /*}}}*/
45df0ad2 111// IndexFile::LanguageCode - Return the Language Code /*{{{*/
a52f938b 112// ---------------------------------------------------------------------
45df0ad2
DK
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 */
453b82a3 116APT_DEPRECATED std::string pkgIndexFile::LanguageCode() {
45df0ad2
DK
117 if (TranslationsAvailable() == false)
118 return "";
119 return APT::Configuration::getLanguages()[0];
a52f938b
OS
120}
121 /*}}}*/
e3c1cfc7
DK
122
123// IndexTarget - Constructor /*{{{*/
124IndexTarget::IndexTarget(std::string const &MetaKey, std::string const &ShortDesc,
125 std::string const &LongDesc, std::string const &URI, bool const IsOptional,
653ef26c
DK
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)
e3c1cfc7
DK
129{
130}
131 /*}}}*/
001c76fe 132std::string IndexTarget::Option(OptionKeys const EnumKey) const /*{{{*/
e3c1cfc7 133{
001c76fe
DK
134 std::string Key;
135 switch (EnumKey)
136 {
137#define APT_CASE(X) case X: Key = #X; break
138 APT_CASE(SITE);
139 APT_CASE(RELEASE);
140 APT_CASE(COMPONENT);
141 APT_CASE(LANGUAGE);
142 APT_CASE(ARCHITECTURE);
143 APT_CASE(BASE_URI);
144 APT_CASE(REPO_URI);
8881b11e 145 APT_CASE(TARGET_OF);
001c76fe 146 APT_CASE(CREATED_BY);
1a3a14ac 147 APT_CASE(PDIFFS);
d7a51997 148 APT_CASE(COMPRESSIONTYPES);
001c76fe 149#undef APT_CASE
8881b11e 150 case FILENAME: return _config->FindDir("Dir::State::lists") + URItoFileName(URI);
3fd89e62
DK
151 case EXISTING_FILENAME:
152 std::string const filename = Option(FILENAME);
d7a51997 153 std::vector<std::string> const types = VectorizeString(Option(COMPRESSIONTYPES), ' ');
3fd89e62
DK
154 for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
155 {
156 if (t->empty())
157 continue;
158 std::string const file = (*t == "uncompressed") ? filename : (filename + "." + *t);
159 if (FileExists(file))
160 return file;
161 }
162 return "";
001c76fe 163 }
e3c1cfc7
DK
164 std::map<std::string,std::string>::const_iterator const M = Options.find(Key);
165 if (M == Options.end())
166 return "";
167 return M->second;
168}
169 /*}}}*/
1a3a14ac
DK
170bool IndexTarget::OptionBool(OptionKeys const EnumKey) const /*{{{*/
171{
172 return StringToBool(Option(EnumKey));
173}
174 /*}}}*/
8881b11e
DK
175std::string IndexTarget::Format(std::string format) const /*{{{*/
176{
177 for (std::map<std::string, std::string>::const_iterator O = Options.begin(); O != Options.end(); ++O)
178 {
179 format = SubstVar(format, std::string("$(") + O->first + ")", O->second);
180 }
181 format = SubstVar(format, "$(METAKEY)", MetaKey);
182 format = SubstVar(format, "$(SHORTDESC)", ShortDesc);
183 format = SubstVar(format, "$(DESCRIPTION)", Description);
184 format = SubstVar(format, "$(URI)", URI);
185 format = SubstVar(format, "$(FILENAME)", Option(IndexTarget::FILENAME));
186 return format;
187}
188 /*}}}*/
e3c1cfc7 189
c9443c01
DK
190pkgDebianIndexTargetFile::pkgDebianIndexTargetFile(IndexTarget const &Target, bool const Trusted) :/*{{{*/
191 pkgDebianIndexFile(Trusted), d(NULL), Target(Target)
e3c1cfc7
DK
192{
193}
194 /*}}}*/
c9443c01 195std::string pkgDebianIndexTargetFile::ArchiveURI(std::string const &File) const/*{{{*/
e3c1cfc7 196{
001c76fe 197 return Target.Option(IndexTarget::REPO_URI) + File;
e3c1cfc7
DK
198}
199 /*}}}*/
c9443c01 200std::string pkgDebianIndexTargetFile::Describe(bool const Short) const /*{{{*/
e3c1cfc7
DK
201{
202 if (Short)
203 return Target.Description;
204 return Target.Description + " (" + IndexFileName() + ")";
205}
206 /*}}}*/
c9443c01 207std::string pkgDebianIndexTargetFile::IndexFileName() const /*{{{*/
e3c1cfc7 208{
8881b11e 209 std::string const s = Target.Option(IndexTarget::FILENAME);
e3c1cfc7
DK
210 if (FileExists(s))
211 return s;
212
d7a51997 213 std::vector<std::string> const types = VectorizeString(Target.Option(IndexTarget::COMPRESSIONTYPES), ' ');
e3c1cfc7
DK
214 for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
215 {
216 std::string p = s + '.' + *t;
217 if (FileExists(p))
218 return p;
219 }
220 return s;
221}
222 /*}}}*/
c9443c01 223unsigned long pkgDebianIndexTargetFile::Size() const /*{{{*/
e3c1cfc7
DK
224{
225 unsigned long size = 0;
226
227 /* we need to ignore errors here; if the lists are absent, just return 0 */
228 _error->PushToStack();
229
230 FileFd f(IndexFileName(), FileFd::ReadOnly, FileFd::Extension);
231 if (!f.Failed())
232 size = f.Size();
233
234 if (_error->PendingError() == true)
235 size = 0;
236 _error->RevertToStack();
237
238 return size;
239}
240 /*}}}*/
c9443c01 241bool pkgDebianIndexTargetFile::Exists() const /*{{{*/
e3c1cfc7
DK
242{
243 return FileExists(IndexFileName());
244}
245 /*}}}*/
c9443c01
DK
246std::string pkgDebianIndexTargetFile::GetArchitecture() const /*{{{*/
247{
248 return Target.Option(IndexTarget::ARCHITECTURE);
249}
250 /*}}}*/
251std::string pkgDebianIndexTargetFile::GetComponent() const /*{{{*/
252{
253 return Target.Option(IndexTarget::COMPONENT);
254}
255 /*}}}*/
256bool pkgDebianIndexTargetFile::OpenListFile(FileFd &Pkg, std::string const &FileName)/*{{{*/
257{
258 if (Pkg.Open(FileName, FileFd::ReadOnly, FileFd::Extension) == false)
259 return _error->Error("Problem opening %s",FileName.c_str());
260 return true;
261}
262 /*}}}*/
263std::string pkgDebianIndexTargetFile::GetProgressDescription() const
264{
265 return Target.Description;
266}
267
268pkgDebianIndexRealFile::pkgDebianIndexRealFile(std::string const &File, bool const Trusted) :/*{{{*/
269 pkgDebianIndexFile(Trusted), d(NULL), File(flAbsPath(File))
270{
271}
272 /*}}}*/
273// IndexRealFile::Size - Return the size of the index /*{{{*/
274unsigned long pkgDebianIndexRealFile::Size() const
275{
276 struct stat S;
277 if (stat(File.c_str(),&S) != 0)
278 return 0;
279 return S.st_size;
280}
281 /*}}}*/
282bool pkgDebianIndexRealFile::Exists() const /*{{{*/
283{
284 return FileExists(File);
285}
286 /*}}}*/
287std::string pkgDebianIndexRealFile::Describe(bool const /*Short*/) const/*{{{*/
288{
289 return File;
290}
291 /*}}}*/
292std::string pkgDebianIndexRealFile::ArchiveURI(std::string const &/*File*/) const/*{{{*/
293{
294 return "file:" + File;
295}
296 /*}}}*/
297std::string pkgDebianIndexRealFile::IndexFileName() const /*{{{*/
298{
299 return File;
300}
301 /*}}}*/
302std::string pkgDebianIndexRealFile::GetProgressDescription() const
303{
304 return File;
305}
306bool pkgDebianIndexRealFile::OpenListFile(FileFd &Pkg, std::string const &FileName)/*{{{*/
307{
308 if (Pkg.Open(FileName, FileFd::ReadOnly, FileFd::None) == false)
309 return _error->Error("Problem opening %s",FileName.c_str());
310 return true;
311}
312 /*}}}*/
313
314pkgDebianIndexFile::pkgDebianIndexFile(bool const Trusted) : pkgIndexFile(Trusted)
315{
316}
317pkgDebianIndexFile::~pkgDebianIndexFile()
318{
319}
320pkgCacheListParser * pkgDebianIndexFile::CreateListParser(FileFd &Pkg)
321{
322 if (Pkg.IsOpen() == false)
323 return NULL;
324 _error->PushToStack();
7f8c0eed 325 pkgCacheListParser * const Parser = new debListParser(&Pkg);
c9443c01
DK
326 bool const newError = _error->PendingError();
327 _error->MergeWithStack();
328 return newError ? NULL : Parser;
329}
330bool pkgDebianIndexFile::Merge(pkgCacheGenerator &Gen,OpProgress * const Prog)
331{
332 std::string const PackageFile = IndexFileName();
333 FileFd Pkg;
334 if (OpenListFile(Pkg, PackageFile) == false)
335 return false;
336 _error->PushToStack();
337 std::unique_ptr<pkgCacheListParser> Parser(CreateListParser(Pkg));
338 bool const newError = _error->PendingError();
339 if (newError == false && Parser == nullptr)
340 return true;
341 if (Parser == NULL)
342 return false;
343
344 if (Prog != NULL)
345 Prog->SubProgress(0, GetProgressDescription());
346
347 if (Gen.SelectFile(PackageFile, *this, GetArchitecture(), GetComponent(), GetIndexFlags()) == false)
348 return _error->Error("Problem with SelectFile %s",PackageFile.c_str());
349
350 // Store the IMS information
351 pkgCache::PkgFileIterator File = Gen.GetCurFile();
352 pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(File);
353 File->Size = Pkg.FileSize();
354 File->mtime = Pkg.ModificationTime();
355
356 if (Gen.MergeList(*Parser) == false)
357 return _error->Error("Problem with MergeList %s",PackageFile.c_str());
358 return true;
359}
360pkgCache::PkgFileIterator pkgDebianIndexFile::FindInCache(pkgCache &Cache) const
361{
362 std::string const FileName = IndexFileName();
363 pkgCache::PkgFileIterator File = Cache.FileBegin();
364 for (; File.end() == false; ++File)
365 {
366 if (File.FileName() == NULL || FileName != File.FileName())
367 continue;
368
369 struct stat St;
370 if (stat(File.FileName(),&St) != 0)
371 {
372 if (_config->FindB("Debug::pkgCacheGen", false))
373 std::clog << "DebianIndexFile::FindInCache - stat failed on " << File.FileName() << std::endl;
374 return pkgCache::PkgFileIterator(Cache);
375 }
376 if ((map_filesize_t)St.st_size != File->Size || St.st_mtime != File->mtime)
377 {
378 if (_config->FindB("Debug::pkgCacheGen", false))
379 std::clog << "DebianIndexFile::FindInCache - size (" << St.st_size << " <> " << File->Size
380 << ") or mtime (" << St.st_mtime << " <> " << File->mtime
381 << ") doesn't match for " << File.FileName() << std::endl;
382 return pkgCache::PkgFileIterator(Cache);
383 }
384 return File;
385 }
386
387 return File;
388}
c8a4ce6c
DK
389
390APT_CONST pkgIndexFile::~pkgIndexFile() {}
c9443c01
DK
391APT_CONST pkgDebianIndexTargetFile::~pkgDebianIndexTargetFile() {}
392APT_CONST pkgDebianIndexRealFile::~pkgDebianIndexRealFile() {}