]> git.saurik.com Git - apt.git/blame - apt-pkg/indexfile.cc
fix 'Dead assignment' by dropping unneeded boolean
[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);
9adb9778 148 APT_CASE(DEFAULTENABLED);
d7a51997 149 APT_CASE(COMPRESSIONTYPES);
3090ae69 150 APT_CASE(SOURCESENTRY);
001c76fe 151#undef APT_CASE
8881b11e 152 case FILENAME: return _config->FindDir("Dir::State::lists") + URItoFileName(URI);
3fd89e62
DK
153 case EXISTING_FILENAME:
154 std::string const filename = Option(FILENAME);
d7a51997 155 std::vector<std::string> const types = VectorizeString(Option(COMPRESSIONTYPES), ' ');
3fd89e62
DK
156 for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
157 {
158 if (t->empty())
159 continue;
160 std::string const file = (*t == "uncompressed") ? filename : (filename + "." + *t);
161 if (FileExists(file))
162 return file;
163 }
164 return "";
001c76fe 165 }
e3c1cfc7
DK
166 std::map<std::string,std::string>::const_iterator const M = Options.find(Key);
167 if (M == Options.end())
168 return "";
169 return M->second;
170}
171 /*}}}*/
1a3a14ac
DK
172bool IndexTarget::OptionBool(OptionKeys const EnumKey) const /*{{{*/
173{
174 return StringToBool(Option(EnumKey));
175}
176 /*}}}*/
8881b11e
DK
177std::string IndexTarget::Format(std::string format) const /*{{{*/
178{
179 for (std::map<std::string, std::string>::const_iterator O = Options.begin(); O != Options.end(); ++O)
180 {
181 format = SubstVar(format, std::string("$(") + O->first + ")", O->second);
182 }
183 format = SubstVar(format, "$(METAKEY)", MetaKey);
184 format = SubstVar(format, "$(SHORTDESC)", ShortDesc);
185 format = SubstVar(format, "$(DESCRIPTION)", Description);
186 format = SubstVar(format, "$(URI)", URI);
187 format = SubstVar(format, "$(FILENAME)", Option(IndexTarget::FILENAME));
188 return format;
189}
190 /*}}}*/
e3c1cfc7 191
c9443c01
DK
192pkgDebianIndexTargetFile::pkgDebianIndexTargetFile(IndexTarget const &Target, bool const Trusted) :/*{{{*/
193 pkgDebianIndexFile(Trusted), d(NULL), Target(Target)
e3c1cfc7
DK
194{
195}
196 /*}}}*/
c9443c01 197std::string pkgDebianIndexTargetFile::ArchiveURI(std::string const &File) const/*{{{*/
e3c1cfc7 198{
001c76fe 199 return Target.Option(IndexTarget::REPO_URI) + File;
e3c1cfc7
DK
200}
201 /*}}}*/
c9443c01 202std::string pkgDebianIndexTargetFile::Describe(bool const Short) const /*{{{*/
e3c1cfc7
DK
203{
204 if (Short)
205 return Target.Description;
206 return Target.Description + " (" + IndexFileName() + ")";
207}
208 /*}}}*/
c9443c01 209std::string pkgDebianIndexTargetFile::IndexFileName() const /*{{{*/
e3c1cfc7 210{
8881b11e 211 std::string const s = Target.Option(IndexTarget::FILENAME);
e3c1cfc7
DK
212 if (FileExists(s))
213 return s;
214
d7a51997 215 std::vector<std::string> const types = VectorizeString(Target.Option(IndexTarget::COMPRESSIONTYPES), ' ');
e3c1cfc7
DK
216 for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
217 {
218 std::string p = s + '.' + *t;
219 if (FileExists(p))
220 return p;
221 }
222 return s;
223}
224 /*}}}*/
c9443c01 225unsigned long pkgDebianIndexTargetFile::Size() const /*{{{*/
e3c1cfc7
DK
226{
227 unsigned long size = 0;
228
229 /* we need to ignore errors here; if the lists are absent, just return 0 */
230 _error->PushToStack();
231
232 FileFd f(IndexFileName(), FileFd::ReadOnly, FileFd::Extension);
233 if (!f.Failed())
234 size = f.Size();
235
236 if (_error->PendingError() == true)
237 size = 0;
238 _error->RevertToStack();
239
240 return size;
241}
242 /*}}}*/
c9443c01 243bool pkgDebianIndexTargetFile::Exists() const /*{{{*/
e3c1cfc7
DK
244{
245 return FileExists(IndexFileName());
246}
247 /*}}}*/
c9443c01
DK
248std::string pkgDebianIndexTargetFile::GetArchitecture() const /*{{{*/
249{
250 return Target.Option(IndexTarget::ARCHITECTURE);
251}
252 /*}}}*/
253std::string pkgDebianIndexTargetFile::GetComponent() const /*{{{*/
254{
255 return Target.Option(IndexTarget::COMPONENT);
256}
257 /*}}}*/
258bool pkgDebianIndexTargetFile::OpenListFile(FileFd &Pkg, std::string const &FileName)/*{{{*/
259{
260 if (Pkg.Open(FileName, FileFd::ReadOnly, FileFd::Extension) == false)
261 return _error->Error("Problem opening %s",FileName.c_str());
262 return true;
263}
264 /*}}}*/
265std::string pkgDebianIndexTargetFile::GetProgressDescription() const
266{
267 return Target.Description;
268}
269
7f58427b
DK
270pkgDebianIndexRealFile::pkgDebianIndexRealFile(std::string const &pFile, bool const Trusted) :/*{{{*/
271 pkgDebianIndexFile(Trusted), d(NULL)
c9443c01 272{
7f58427b
DK
273 if (pFile == "/nonexistent/stdin")
274 File = pFile;
275 else
276 File = flAbsPath(pFile);
c9443c01
DK
277}
278 /*}}}*/
279// IndexRealFile::Size - Return the size of the index /*{{{*/
280unsigned long pkgDebianIndexRealFile::Size() const
281{
282 struct stat S;
283 if (stat(File.c_str(),&S) != 0)
284 return 0;
285 return S.st_size;
286}
287 /*}}}*/
288bool pkgDebianIndexRealFile::Exists() const /*{{{*/
289{
290 return FileExists(File);
291}
292 /*}}}*/
293std::string pkgDebianIndexRealFile::Describe(bool const /*Short*/) const/*{{{*/
294{
295 return File;
296}
297 /*}}}*/
298std::string pkgDebianIndexRealFile::ArchiveURI(std::string const &/*File*/) const/*{{{*/
299{
300 return "file:" + File;
301}
302 /*}}}*/
303std::string pkgDebianIndexRealFile::IndexFileName() const /*{{{*/
304{
305 return File;
306}
307 /*}}}*/
308std::string pkgDebianIndexRealFile::GetProgressDescription() const
309{
310 return File;
311}
312bool pkgDebianIndexRealFile::OpenListFile(FileFd &Pkg, std::string const &FileName)/*{{{*/
313{
314 if (Pkg.Open(FileName, FileFd::ReadOnly, FileFd::None) == false)
315 return _error->Error("Problem opening %s",FileName.c_str());
316 return true;
317}
318 /*}}}*/
319
320pkgDebianIndexFile::pkgDebianIndexFile(bool const Trusted) : pkgIndexFile(Trusted)
321{
322}
323pkgDebianIndexFile::~pkgDebianIndexFile()
324{
325}
326pkgCacheListParser * pkgDebianIndexFile::CreateListParser(FileFd &Pkg)
327{
328 if (Pkg.IsOpen() == false)
329 return NULL;
330 _error->PushToStack();
7f8c0eed 331 pkgCacheListParser * const Parser = new debListParser(&Pkg);
c9443c01
DK
332 bool const newError = _error->PendingError();
333 _error->MergeWithStack();
334 return newError ? NULL : Parser;
335}
336bool pkgDebianIndexFile::Merge(pkgCacheGenerator &Gen,OpProgress * const Prog)
337{
338 std::string const PackageFile = IndexFileName();
339 FileFd Pkg;
340 if (OpenListFile(Pkg, PackageFile) == false)
341 return false;
342 _error->PushToStack();
343 std::unique_ptr<pkgCacheListParser> Parser(CreateListParser(Pkg));
344 bool const newError = _error->PendingError();
95278287 345 _error->MergeWithStack();
c9443c01
DK
346 if (newError == false && Parser == nullptr)
347 return true;
348 if (Parser == NULL)
349 return false;
350
351 if (Prog != NULL)
352 Prog->SubProgress(0, GetProgressDescription());
353
354 if (Gen.SelectFile(PackageFile, *this, GetArchitecture(), GetComponent(), GetIndexFlags()) == false)
355 return _error->Error("Problem with SelectFile %s",PackageFile.c_str());
356
357 // Store the IMS information
358 pkgCache::PkgFileIterator File = Gen.GetCurFile();
359 pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(File);
360 File->Size = Pkg.FileSize();
361 File->mtime = Pkg.ModificationTime();
362
363 if (Gen.MergeList(*Parser) == false)
364 return _error->Error("Problem with MergeList %s",PackageFile.c_str());
365 return true;
366}
367pkgCache::PkgFileIterator pkgDebianIndexFile::FindInCache(pkgCache &Cache) const
368{
369 std::string const FileName = IndexFileName();
370 pkgCache::PkgFileIterator File = Cache.FileBegin();
371 for (; File.end() == false; ++File)
372 {
373 if (File.FileName() == NULL || FileName != File.FileName())
374 continue;
375
376 struct stat St;
377 if (stat(File.FileName(),&St) != 0)
378 {
379 if (_config->FindB("Debug::pkgCacheGen", false))
380 std::clog << "DebianIndexFile::FindInCache - stat failed on " << File.FileName() << std::endl;
381 return pkgCache::PkgFileIterator(Cache);
382 }
383 if ((map_filesize_t)St.st_size != File->Size || St.st_mtime != File->mtime)
384 {
385 if (_config->FindB("Debug::pkgCacheGen", false))
386 std::clog << "DebianIndexFile::FindInCache - size (" << St.st_size << " <> " << File->Size
387 << ") or mtime (" << St.st_mtime << " <> " << File->mtime
388 << ") doesn't match for " << File.FileName() << std::endl;
389 return pkgCache::PkgFileIterator(Cache);
390 }
391 return File;
392 }
393
394 return File;
395}
c8a4ce6c
DK
396
397APT_CONST pkgIndexFile::~pkgIndexFile() {}
c9443c01
DK
398APT_CONST pkgDebianIndexTargetFile::~pkgDebianIndexTargetFile() {}
399APT_CONST pkgDebianIndexRealFile::~pkgDebianIndexRealFile() {}