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