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