]> git.saurik.com Git - apt.git/blame - apt-pkg/deb/debindexfile.cc
Merge remote-tracking branch 'mvo/feature/no-more-acquire-guessing' into debian/exper...
[apt.git] / apt-pkg / deb / debindexfile.cc
CommitLineData
b2e465d6
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
7db98ffc 3// $Id: debindexfile.cc,v 1.5.2.3 2004/01/04 19:11:00 mdz Exp $
b2e465d6
AL
4/* ######################################################################
5
6 Debian Specific sources.list types and the three sorts of Debian
7 index files.
8
9 ##################################################################### */
10 /*}}}*/
11// Include Files /*{{{*/
ea542140
DK
12#include <config.h>
13
b2e465d6
AL
14#include <apt-pkg/debindexfile.h>
15#include <apt-pkg/debsrcrecords.h>
16#include <apt-pkg/deblistparser.h>
17#include <apt-pkg/debrecords.h>
b2e465d6
AL
18#include <apt-pkg/configuration.h>
19#include <apt-pkg/progress.h>
20#include <apt-pkg/error.h>
21#include <apt-pkg/strutl.h>
22#include <apt-pkg/acquire-item.h>
7db98ffc 23#include <apt-pkg/debmetaindex.h>
233b7808 24#include <apt-pkg/gpgv.h>
453b82a3
DK
25#include <apt-pkg/fileutl.h>
26#include <apt-pkg/indexfile.h>
27#include <apt-pkg/mmap.h>
28#include <apt-pkg/pkgcache.h>
29#include <apt-pkg/cacheiterators.h>
30#include <apt-pkg/pkgcachegen.h>
31#include <apt-pkg/pkgrecords.h>
32#include <apt-pkg/srcrecords.h>
0d29b9d4 33#include <apt-pkg/sptr.h>
e011829d 34
453b82a3
DK
35#include <stdio.h>
36#include <iostream>
37#include <string>
b2e465d6
AL
38#include <sys/stat.h>
39 /*}}}*/
40
73688d27
DK
41using std::string;
42
b2e465d6
AL
43// SourcesIndex::debSourcesIndex - Constructor /*{{{*/
44// ---------------------------------------------------------------------
45/* */
7db98ffc
MZ
46debSourcesIndex::debSourcesIndex(string URI,string Dist,string Section,bool Trusted) :
47 pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section)
b2e465d6
AL
48{
49}
50 /*}}}*/
51// SourcesIndex::SourceInfo - Short 1 liner describing a source /*{{{*/
52// ---------------------------------------------------------------------
53/* The result looks like:
5e02df82 54 http://foo/debian/ stable/main src 1.1.1 (dsc) */
b2e465d6
AL
55string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record,
56 pkgSrcRecords::File const &File) const
57{
58 string Res;
5e02df82 59 Res = ::URI::NoUserPassword(URI) + ' ';
b2e465d6
AL
60 if (Dist[Dist.size() - 1] == '/')
61 {
62 if (Dist != "/")
63 Res += Dist;
64 }
65 else
66 Res += Dist + '/' + Section;
67
68 Res += " ";
69 Res += Record.Package();
70 Res += " ";
71 Res += Record.Version();
72 if (File.Type.empty() == false)
73 Res += " (" + File.Type + ")";
74 return Res;
75}
76 /*}}}*/
77// SourcesIndex::CreateSrcParser - Get a parser for the source files /*{{{*/
78// ---------------------------------------------------------------------
79/* */
80pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const
81{
94e8c9d4 82 string SourcesURI = _config->FindDir("Dir::State::lists") +
83 URItoFileName(IndexURI("Sources"));
1aadba5a 84
b0f4b486
MV
85 std::vector<std::string> types = APT::Configuration::getCompressionTypes();
86 for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
87 {
88 string p;
89 p = SourcesURI + '.' + *t;
90 if (FileExists(p))
91 return new debSrcRecordParser(p, this);
92 }
93 if (FileExists(SourcesURI))
94 return new debSrcRecordParser(SourcesURI, this);
95 return NULL;
b2e465d6
AL
96}
97 /*}}}*/
98// SourcesIndex::Describe - Give a descriptive path to the index /*{{{*/
99// ---------------------------------------------------------------------
100/* */
af87ab54 101string debSourcesIndex::Describe(bool Short) const
b2e465d6
AL
102{
103 char S[300];
af87ab54 104 if (Short == true)
cc742108 105 snprintf(S,sizeof(S),"%s",Info("Sources").c_str());
af87ab54 106 else
cc742108 107 snprintf(S,sizeof(S),"%s (%s)",Info("Sources").c_str(),
af87ab54
AL
108 IndexFile("Sources").c_str());
109
b2e465d6
AL
110 return S;
111}
112 /*}}}*/
113// SourcesIndex::Info - One liner describing the index URI /*{{{*/
114// ---------------------------------------------------------------------
115/* */
116string debSourcesIndex::Info(const char *Type) const
117{
5e02df82 118 string Info = ::URI::NoUserPassword(URI) + ' ';
b2e465d6
AL
119 if (Dist[Dist.size() - 1] == '/')
120 {
121 if (Dist != "/")
122 Info += Dist;
123 }
124 else
125 Info += Dist + '/' + Section;
126 Info += " ";
127 Info += Type;
128 return Info;
129}
130 /*}}}*/
131// SourcesIndex::Index* - Return the URI to the index files /*{{{*/
132// ---------------------------------------------------------------------
133/* */
3809194b 134string debSourcesIndex::IndexFile(const char *Type) const
b2e465d6 135{
ec7a129e 136 string s = URItoFileName(IndexURI(Type));
b0f4b486
MV
137
138 std::vector<std::string> types = APT::Configuration::getCompressionTypes();
139 for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
140 {
141 string p = s + '.' + *t;
142 if (FileExists(p))
143 return p;
144 }
145 return s;
b2e465d6 146}
ec7a129e 147
b2e465d6
AL
148string debSourcesIndex::IndexURI(const char *Type) const
149{
150 string Res;
151 if (Dist[Dist.size() - 1] == '/')
152 {
153 if (Dist != "/")
154 Res = URI + Dist;
155 else
156 Res = URI;
157 }
158 else
159 Res = URI + "dists/" + Dist + '/' + Section +
160 "/source/";
161
162 Res += Type;
163 return Res;
164}
165 /*}}}*/
b2e465d6
AL
166// SourcesIndex::Exists - Check if the index is available /*{{{*/
167// ---------------------------------------------------------------------
168/* */
169bool debSourcesIndex::Exists() const
170{
171 return FileExists(IndexFile("Sources"));
172}
173 /*}}}*/
174// SourcesIndex::Size - Return the size of the index /*{{{*/
175// ---------------------------------------------------------------------
176/* */
177unsigned long debSourcesIndex::Size() const
178{
915f0520
MP
179 unsigned long size = 0;
180
181 /* we need to ignore errors here; if the lists are absent, just return 0 */
182 _error->PushToStack();
183
f0e83599 184 FileFd f(IndexFile("Sources"), FileFd::ReadOnly, FileFd::Extension);
915f0520
MP
185 if (!f.Failed())
186 size = f.Size();
187
188 if (_error->PendingError() == true)
189 size = 0;
190 _error->RevertToStack();
5473df3f 191
915f0520 192 return size;
b2e465d6
AL
193}
194 /*}}}*/
195
196// PackagesIndex::debPackagesIndex - Contructor /*{{{*/
197// ---------------------------------------------------------------------
198/* */
5dd4c8b8
DK
199debPackagesIndex::debPackagesIndex(string const &URI, string const &Dist, string const &Section,
200 bool const &Trusted, string const &Arch) :
201 pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section), Architecture(Arch)
b2e465d6 202{
5dd4c8b8
DK
203 if (Architecture == "native")
204 Architecture = _config->Find("APT::Architecture");
b2e465d6
AL
205}
206 /*}}}*/
207// PackagesIndex::ArchiveInfo - Short version of the archive url /*{{{*/
208// ---------------------------------------------------------------------
209/* This is a shorter version that is designed to be < 60 chars or so */
210string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const
211{
5e02df82 212 string Res = ::URI::NoUserPassword(URI) + ' ';
b2e465d6
AL
213 if (Dist[Dist.size() - 1] == '/')
214 {
215 if (Dist != "/")
216 Res += Dist;
217 }
218 else
219 Res += Dist + '/' + Section;
220
221 Res += " ";
222 Res += Ver.ParentPkg().Name();
223 Res += " ";
dd13742e
DK
224 if (Dist[Dist.size() - 1] != '/')
225 Res.append(Ver.Arch()).append(" ");
b2e465d6
AL
226 Res += Ver.VerStr();
227 return Res;
228}
229 /*}}}*/
230// PackagesIndex::Describe - Give a descriptive path to the index /*{{{*/
231// ---------------------------------------------------------------------
232/* This should help the user find the index in the sources.list and
233 in the filesystem for problem solving */
af87ab54 234string debPackagesIndex::Describe(bool Short) const
b2e465d6
AL
235{
236 char S[300];
af87ab54
AL
237 if (Short == true)
238 snprintf(S,sizeof(S),"%s",Info("Packages").c_str());
239 else
240 snprintf(S,sizeof(S),"%s (%s)",Info("Packages").c_str(),
241 IndexFile("Packages").c_str());
b2e465d6
AL
242 return S;
243}
244 /*}}}*/
245// PackagesIndex::Info - One liner describing the index URI /*{{{*/
246// ---------------------------------------------------------------------
247/* */
248string debPackagesIndex::Info(const char *Type) const
249{
5e02df82 250 string Info = ::URI::NoUserPassword(URI) + ' ';
b2e465d6
AL
251 if (Dist[Dist.size() - 1] == '/')
252 {
253 if (Dist != "/")
254 Info += Dist;
255 }
256 else
257 Info += Dist + '/' + Section;
258 Info += " ";
dd13742e
DK
259 if (Dist[Dist.size() - 1] != '/')
260 Info += Architecture + " ";
b2e465d6
AL
261 Info += Type;
262 return Info;
263}
264 /*}}}*/
265// PackagesIndex::Index* - Return the URI to the index files /*{{{*/
266// ---------------------------------------------------------------------
267/* */
3809194b 268string debPackagesIndex::IndexFile(const char *Type) const
b2e465d6 269{
ec7a129e 270 string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type));
b0f4b486
MV
271
272 std::vector<std::string> types = APT::Configuration::getCompressionTypes();
273 for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
274 {
275 string p = s + '.' + *t;
276 if (FileExists(p))
277 return p;
278 }
279 return s;
b2e465d6
AL
280}
281string debPackagesIndex::IndexURI(const char *Type) const
282{
283 string Res;
284 if (Dist[Dist.size() - 1] == '/')
285 {
286 if (Dist != "/")
287 Res = URI + Dist;
288 else
289 Res = URI;
290 }
291 else
292 Res = URI + "dists/" + Dist + '/' + Section +
5dd4c8b8 293 "/binary-" + Architecture + '/';
b2e465d6
AL
294
295 Res += Type;
296 return Res;
297}
298 /*}}}*/
b2e465d6
AL
299// PackagesIndex::Exists - Check if the index is available /*{{{*/
300// ---------------------------------------------------------------------
301/* */
302bool debPackagesIndex::Exists() const
303{
304 return FileExists(IndexFile("Packages"));
305}
306 /*}}}*/
307// PackagesIndex::Size - Return the size of the index /*{{{*/
308// ---------------------------------------------------------------------
309/* This is really only used for progress reporting. */
310unsigned long debPackagesIndex::Size() const
311{
915f0520
MP
312 unsigned long size = 0;
313
314 /* we need to ignore errors here; if the lists are absent, just return 0 */
315 _error->PushToStack();
316
f0e83599 317 FileFd f(IndexFile("Packages"), FileFd::ReadOnly, FileFd::Extension);
915f0520
MP
318 if (!f.Failed())
319 size = f.Size();
5473df3f 320
915f0520
MP
321 if (_error->PendingError() == true)
322 size = 0;
323 _error->RevertToStack();
324
325 return size;
b2e465d6
AL
326}
327 /*}}}*/
328// PackagesIndex::Merge - Load the index file into a cache /*{{{*/
329// ---------------------------------------------------------------------
330/* */
2e5f4e45 331bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
b2e465d6
AL
332{
333 string PackageFile = IndexFile("Packages");
468720c5 334 FileFd Pkg(PackageFile,FileFd::ReadOnly, FileFd::Extension);
5dd4c8b8 335 debListParser Parser(&Pkg, Architecture);
3184b4cf 336
b2e465d6
AL
337 if (_error->PendingError() == true)
338 return _error->Error("Problem opening %s",PackageFile.c_str());
2e5f4e45
DK
339 if (Prog != NULL)
340 Prog->SubProgress(0,Info("Packages"));
b2e465d6
AL
341 ::URI Tmp(URI);
342 if (Gen.SelectFile(PackageFile,Tmp.Host,*this) == false)
343 return _error->Error("Problem with SelectFile %s",PackageFile.c_str());
344
345 // Store the IMS information
346 pkgCache::PkgFileIterator File = Gen.GetCurFile();
a9fe5928 347 pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(File);
76a763e1
DK
348 File->Size = Pkg.FileSize();
349 File->mtime = Pkg.ModificationTime();
b2e465d6
AL
350
351 if (Gen.MergeList(Parser) == false)
352 return _error->Error("Problem with MergeList %s",PackageFile.c_str());
353
354 // Check the release file
fe0f7911
DK
355 string ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("InRelease");
356 bool releaseExists = false;
b2e465d6 357 if (FileExists(ReleaseFile) == true)
fe0f7911
DK
358 releaseExists = true;
359 else
360 ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("Release");
361
362 if (releaseExists == true || FileExists(ReleaseFile) == true)
b2e465d6 363 {
233b7808
DK
364 FileFd Rel;
365 // Beware: The 'Release' file might be clearsigned in case the
366 // signature for an 'InRelease' file couldn't be checked
367 if (OpenMaybeClearSignedFile(ReleaseFile, Rel) == false)
368 return false;
369
b2e465d6
AL
370 if (_error->PendingError() == true)
371 return false;
e011829d 372 Parser.LoadReleaseInfo(File,Rel,Section);
b2e465d6
AL
373 }
374
375 return true;
376}
377 /*}}}*/
378// PackagesIndex::FindInCache - Find this index /*{{{*/
379// ---------------------------------------------------------------------
380/* */
381pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const
382{
383 string FileName = IndexFile("Packages");
384 pkgCache::PkgFileIterator File = Cache.FileBegin();
f7f0d6c7 385 for (; File.end() == false; ++File)
b2e465d6 386 {
f6442c77 387 if (File.FileName() == NULL || FileName != File.FileName())
b2e465d6
AL
388 continue;
389
390 struct stat St;
391 if (stat(File.FileName(),&St) != 0)
c8e572e3
MV
392 {
393 if (_config->FindB("Debug::pkgCacheGen", false))
394 std::clog << "PackagesIndex::FindInCache - stat failed on " << File.FileName() << std::endl;
b2e465d6 395 return pkgCache::PkgFileIterator(Cache);
c8e572e3 396 }
b2e465d6 397 if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime)
c8e572e3
MV
398 {
399 if (_config->FindB("Debug::pkgCacheGen", false))
400 std::clog << "PackagesIndex::FindInCache - size (" << St.st_size << " <> " << File->Size
401 << ") or mtime (" << St.st_mtime << " <> " << File->mtime
402 << ") doesn't match for " << File.FileName() << std::endl;
b2e465d6 403 return pkgCache::PkgFileIterator(Cache);
c8e572e3 404 }
b2e465d6
AL
405 return File;
406 }
407
408 return File;
409}
410 /*}}}*/
411
a52f938b
OS
412// TranslationsIndex::debTranslationsIndex - Contructor /*{{{*/
413// ---------------------------------------------------------------------
414/* */
45df0ad2
DK
415debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section,
416 char const * const Translation) :
417 pkgIndexFile(true), URI(URI), Dist(Dist), Section(Section),
418 Language(Translation)
419{}
a52f938b
OS
420 /*}}}*/
421// TranslationIndex::Trans* - Return the URI to the translation files /*{{{*/
422// ---------------------------------------------------------------------
423/* */
3809194b 424string debTranslationsIndex::IndexFile(const char *Type) const
a52f938b 425{
ec7a129e 426 string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type));
b0f4b486
MV
427
428 std::vector<std::string> types = APT::Configuration::getCompressionTypes();
429 for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
430 {
431 string p = s + '.' + *t;
432 if (FileExists(p))
433 return p;
434 }
435 return s;
a52f938b
OS
436}
437string debTranslationsIndex::IndexURI(const char *Type) const
438{
439 string Res;
440 if (Dist[Dist.size() - 1] == '/')
441 {
442 if (Dist != "/")
422eeaaa 443 Res = URI + Dist;
a52f938b 444 else
422eeaaa 445 Res = URI;
a52f938b
OS
446 }
447 else
422eeaaa 448 Res = URI + "dists/" + Dist + '/' + Section +
a52f938b
OS
449 "/i18n/Translation-";
450
451 Res += Type;
452 return Res;
453}
454 /*}}}*/
a52f938b
OS
455// TranslationsIndex::Describe - Give a descriptive path to the index /*{{{*/
456// ---------------------------------------------------------------------
457/* This should help the user find the index in the sources.list and
458 in the filesystem for problem solving */
459string debTranslationsIndex::Describe(bool Short) const
460{
461 char S[300];
462 if (Short == true)
463 snprintf(S,sizeof(S),"%s",Info(TranslationFile().c_str()).c_str());
464 else
465 snprintf(S,sizeof(S),"%s (%s)",Info(TranslationFile().c_str()).c_str(),
45df0ad2 466 IndexFile(Language).c_str());
a52f938b
OS
467 return S;
468}
469 /*}}}*/
470// TranslationsIndex::Info - One liner describing the index URI /*{{{*/
471// ---------------------------------------------------------------------
472/* */
473string debTranslationsIndex::Info(const char *Type) const
474{
5e02df82 475 string Info = ::URI::NoUserPassword(URI) + ' ';
a52f938b
OS
476 if (Dist[Dist.size() - 1] == '/')
477 {
478 if (Dist != "/")
479 Info += Dist;
480 }
481 else
482 Info += Dist + '/' + Section;
483 Info += " ";
484 Info += Type;
485 return Info;
486}
487 /*}}}*/
45df0ad2 488bool debTranslationsIndex::HasPackages() const /*{{{*/
11680bfd 489{
45df0ad2 490 return FileExists(IndexFile(Language));
11680bfd 491}
45df0ad2 492 /*}}}*/
a52f938b
OS
493// TranslationsIndex::Exists - Check if the index is available /*{{{*/
494// ---------------------------------------------------------------------
495/* */
496bool debTranslationsIndex::Exists() const
497{
45df0ad2 498 return FileExists(IndexFile(Language));
a52f938b
OS
499}
500 /*}}}*/
501// TranslationsIndex::Size - Return the size of the index /*{{{*/
502// ---------------------------------------------------------------------
503/* This is really only used for progress reporting. */
504unsigned long debTranslationsIndex::Size() const
505{
915f0520
MP
506 unsigned long size = 0;
507
508 /* we need to ignore errors here; if the lists are absent, just return 0 */
509 _error->PushToStack();
510
f0e83599 511 FileFd f(IndexFile(Language), FileFd::ReadOnly, FileFd::Extension);
915f0520
MP
512 if (!f.Failed())
513 size = f.Size();
5473df3f 514
915f0520
MP
515 if (_error->PendingError() == true)
516 size = 0;
517 _error->RevertToStack();
5473df3f 518
915f0520 519 return size;
a52f938b
OS
520}
521 /*}}}*/
522// TranslationsIndex::Merge - Load the index file into a cache /*{{{*/
523// ---------------------------------------------------------------------
524/* */
2e5f4e45 525bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
a52f938b
OS
526{
527 // Check the translation file, if in use
45df0ad2 528 string TranslationFile = IndexFile(Language);
64c2bdc9 529 if (FileExists(TranslationFile))
a52f938b 530 {
468720c5 531 FileFd Trans(TranslationFile,FileFd::ReadOnly, FileFd::Extension);
bc1c9081 532 debTranslationsParser TransParser(&Trans);
a52f938b
OS
533 if (_error->PendingError() == true)
534 return false;
535
2e5f4e45
DK
536 if (Prog != NULL)
537 Prog->SubProgress(0, Info(TranslationFile.c_str()));
a52f938b
OS
538 if (Gen.SelectFile(TranslationFile,string(),*this) == false)
539 return _error->Error("Problem with SelectFile %s",TranslationFile.c_str());
540
541 // Store the IMS information
542 pkgCache::PkgFileIterator TransFile = Gen.GetCurFile();
76a763e1
DK
543 TransFile->Size = Trans.FileSize();
544 TransFile->mtime = Trans.ModificationTime();
a52f938b
OS
545
546 if (Gen.MergeList(TransParser) == false)
547 return _error->Error("Problem with MergeList %s",TranslationFile.c_str());
548 }
549
550 return true;
551}
552 /*}}}*/
c51c6f08
OS
553// TranslationsIndex::FindInCache - Find this index /*{{{*/
554// ---------------------------------------------------------------------
555/* */
556pkgCache::PkgFileIterator debTranslationsIndex::FindInCache(pkgCache &Cache) const
557{
45df0ad2 558 string FileName = IndexFile(Language);
4d34acf1 559
c51c6f08 560 pkgCache::PkgFileIterator File = Cache.FileBegin();
f7f0d6c7 561 for (; File.end() == false; ++File)
f416d22e
MV
562 {
563 if (FileName != File.FileName())
564 continue;
4d34acf1 565
f416d22e
MV
566 struct stat St;
567 if (stat(File.FileName(),&St) != 0)
c8e572e3
MV
568 {
569 if (_config->FindB("Debug::pkgCacheGen", false))
570 std::clog << "TranslationIndex::FindInCache - stat failed on " << File.FileName() << std::endl;
f416d22e 571 return pkgCache::PkgFileIterator(Cache);
c8e572e3 572 }
f416d22e 573 if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime)
c8e572e3
MV
574 {
575 if (_config->FindB("Debug::pkgCacheGen", false))
576 std::clog << "TranslationIndex::FindInCache - size (" << St.st_size << " <> " << File->Size
577 << ") or mtime (" << St.st_mtime << " <> " << File->mtime
578 << ") doesn't match for " << File.FileName() << std::endl;
f416d22e 579 return pkgCache::PkgFileIterator(Cache);
c8e572e3 580 }
f416d22e
MV
581 return File;
582 }
c51c6f08
OS
583 return File;
584}
585 /*}}}*/
b2e465d6
AL
586// StatusIndex::debStatusIndex - Constructor /*{{{*/
587// ---------------------------------------------------------------------
588/* */
7db98ffc 589debStatusIndex::debStatusIndex(string File) : pkgIndexFile(true), File(File)
b2e465d6
AL
590{
591}
592 /*}}}*/
593// StatusIndex::Size - Return the size of the index /*{{{*/
594// ---------------------------------------------------------------------
595/* */
596unsigned long debStatusIndex::Size() const
597{
598 struct stat S;
599 if (stat(File.c_str(),&S) != 0)
600 return 0;
601 return S.st_size;
602}
603 /*}}}*/
604// StatusIndex::Merge - Load the index file into a cache /*{{{*/
605// ---------------------------------------------------------------------
606/* */
2e5f4e45 607bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
b2e465d6 608{
468720c5 609 FileFd Pkg(File,FileFd::ReadOnly, FileFd::Extension);
b2e465d6
AL
610 if (_error->PendingError() == true)
611 return false;
612 debListParser Parser(&Pkg);
613 if (_error->PendingError() == true)
614 return false;
2e5f4e45
DK
615
616 if (Prog != NULL)
617 Prog->SubProgress(0,File);
b2e465d6
AL
618 if (Gen.SelectFile(File,string(),*this,pkgCache::Flag::NotSource) == false)
619 return _error->Error("Problem with SelectFile %s",File.c_str());
620
621 // Store the IMS information
622 pkgCache::PkgFileIterator CFile = Gen.GetCurFile();
76a763e1
DK
623 CFile->Size = Pkg.FileSize();
624 CFile->mtime = Pkg.ModificationTime();
78a5476f 625 map_stringitem_t const storage = Gen.StoreString(pkgCacheGenerator::MIXED, "now");
2b803d40 626 CFile->Archive = storage;
b2e465d6
AL
627
628 if (Gen.MergeList(Parser) == false)
629 return _error->Error("Problem with MergeList %s",File.c_str());
630 return true;
631}
632 /*}}}*/
633// StatusIndex::FindInCache - Find this index /*{{{*/
634// ---------------------------------------------------------------------
635/* */
636pkgCache::PkgFileIterator debStatusIndex::FindInCache(pkgCache &Cache) const
637{
638 pkgCache::PkgFileIterator File = Cache.FileBegin();
f7f0d6c7 639 for (; File.end() == false; ++File)
b2e465d6
AL
640 {
641 if (this->File != File.FileName())
642 continue;
643
644 struct stat St;
645 if (stat(File.FileName(),&St) != 0)
c8e572e3
MV
646 {
647 if (_config->FindB("Debug::pkgCacheGen", false))
648 std::clog << "StatusIndex::FindInCache - stat failed on " << File.FileName() << std::endl;
b2e465d6 649 return pkgCache::PkgFileIterator(Cache);
c8e572e3 650 }
b2e465d6 651 if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime)
c8e572e3
MV
652 {
653 if (_config->FindB("Debug::pkgCacheGen", false))
654 std::clog << "StatusIndex::FindInCache - size (" << St.st_size << " <> " << File->Size
655 << ") or mtime (" << St.st_mtime << " <> " << File->mtime
656 << ") doesn't match for " << File.FileName() << std::endl;
b2e465d6 657 return pkgCache::PkgFileIterator(Cache);
c8e572e3 658 }
b2e465d6
AL
659 return File;
660 }
661 return File;
662}
663 /*}}}*/
664// StatusIndex::Exists - Check if the index is available /*{{{*/
665// ---------------------------------------------------------------------
666/* */
a02db58f 667APT_CONST bool debStatusIndex::Exists() const
b2e465d6
AL
668{
669 // Abort if the file does not exist.
670 return true;
671}
672 /*}}}*/
673
0d29b9d4
MV
674// debDebPkgFile - Single .deb file /*{{{*/
675// ---------------------------------------------------------------------
676debDebPkgFileIndex::debDebPkgFileIndex(std::string DebFile)
677 : pkgIndexFile(true), DebFile(DebFile)
678{
fb11075f 679 DebFileFullPath = flAbsPath(DebFile);
0d29b9d4
MV
680}
681
682std::string debDebPkgFileIndex::ArchiveURI(std::string /*File*/) const
683{
684 return "file:" + DebFileFullPath;
685}
686
687bool debDebPkgFileIndex::Exists() const
688{
689 return FileExists(DebFile);
690}
691bool debDebPkgFileIndex::Merge(pkgCacheGenerator& Gen, OpProgress* Prog) const
692{
693 if(Prog)
694 Prog->SubProgress(0, "Reading deb file");
695
696 // get the control data out of the deb file vid dpkg -I
697 // ... can I haz libdpkg?
fdff5b03 698 Configuration::Item const *Opts = _config->Tree("DPkg::Options");
0cf39629 699 std::string dpkg = _config->Find("Dir::Bin::dpkg","dpkg");
fdff5b03
MV
700 std::vector<const char *> Args;
701 Args.push_back(dpkg.c_str());
702 if (Opts != 0)
703 {
704 Opts = Opts->Child;
705 for (; Opts != 0; Opts = Opts->Next)
706 {
707 if (Opts->Value.empty() == true)
708 continue;
709 Args.push_back(Opts->Value.c_str());
710 }
711 }
712 Args.push_back("-I");
713 Args.push_back(DebFile.c_str());
714 Args.push_back("control");
715 Args.push_back(NULL);
a9d990a2
MV
716 FileFd PipeFd;
717 pid_t Child;
fdff5b03 718 if(Popen((const char**)&Args[0], PipeFd, Child, FileFd::ReadOnly) == false)
a9d990a2 719 return _error->Error("Popen failed");
0d29b9d4
MV
720 // FIXME: static buffer
721 char buf[8*1024];
a9d990a2
MV
722 unsigned long long n = 0;
723 if(PipeFd.Read(buf, sizeof(buf)-1, &n) == false)
724 return _error->Errno("read", "Failed to read dpkg pipe");
725 ExecWait(Child, "Popen");
0d29b9d4
MV
726
727 // now write the control data to a tempfile
fdff5b03 728 SPtr<FileFd> DebControl = GetTempFile("deb-file-" + flNotDir(DebFile));
0d29b9d4
MV
729 if(DebControl == NULL)
730 return false;
731 DebControl->Write(buf, n);
732 // append size of the file
733 FileFd Fd(DebFile, FileFd::ReadOnly);
734 string Size;
735 strprintf(Size, "Size: %llu\n", Fd.Size());
736 DebControl->Write(Size.c_str(), Size.size());
737 // and rewind for the listparser
738 DebControl->Seek(0);
739
740 // and give it to the list parser
741 debDebFileParser Parser(DebControl, DebFile);
742 if(Gen.SelectFile(DebFile, "local", *this) == false)
743 return _error->Error("Problem with SelectFile %s", DebFile.c_str());
744
745 pkgCache::PkgFileIterator File = Gen.GetCurFile();
746 File->Size = DebControl->Size();
747 File->mtime = DebControl->ModificationTime();
748
749 if (Gen.MergeList(Parser) == false)
750 return _error->Error("Problem with MergeLister for %s", DebFile.c_str());
751
752 return true;
753}
754pkgCache::PkgFileIterator debDebPkgFileIndex::FindInCache(pkgCache &Cache) const
755{
0d29b9d4
MV
756 pkgCache::PkgFileIterator File = Cache.FileBegin();
757 for (; File.end() == false; ++File)
758 {
759 if (File.FileName() == NULL || DebFile != File.FileName())
760 continue;
761
762 return File;
763 }
764
765 return File;
766}
767unsigned long debDebPkgFileIndex::Size() const
768{
769 struct stat buf;
770 if(stat(DebFile.c_str(), &buf) != 0)
771 return 0;
772 return buf.st_size;
773}
774 /*}}}*/
775
a49e7948
MV
776// debDscFileIndex stuff
777debDscFileIndex::debDscFileIndex(std::string &DscFile)
778 : pkgIndexFile(true), DscFile(DscFile)
779{
780}
781
782bool debDscFileIndex::Exists() const
783{
784 return FileExists(DscFile);
785}
786
787unsigned long debDscFileIndex::Size() const
788{
789 struct stat buf;
790 if(stat(DscFile.c_str(), &buf) == 0)
791 return buf.st_size;
792 return 0;
793}
794
795// DscFileIndex::CreateSrcParser - Get a parser for the .dsc file /*{{{*/
a49e7948
MV
796pkgSrcRecords::Parser *debDscFileIndex::CreateSrcParser() const
797{
798 if (!FileExists(DscFile))
799 return NULL;
800
801 return new debDscRecordParser(DscFile,this);
802}
803 /*}}}*/
b2e465d6
AL
804// Index File types for Debian /*{{{*/
805class debIFTypeSrc : public pkgIndexFile::Type
806{
807 public:
808
809 debIFTypeSrc() {Label = "Debian Source Index";};
810};
811class debIFTypePkg : public pkgIndexFile::Type
812{
813 public:
814
815 virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const
816 {
817 return new debRecordParser(File.FileName(),*File.Cache());
818 };
819 debIFTypePkg() {Label = "Debian Package Index";};
820};
97234432
MV
821class debIFTypeTrans : public debIFTypePkg
822{
823 public:
824 debIFTypeTrans() {Label = "Debian Translation Index";};
825};
b2e465d6
AL
826class debIFTypeStatus : public pkgIndexFile::Type
827{
828 public:
829
830 virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const
831 {
832 return new debRecordParser(File.FileName(),*File.Cache());
833 };
834 debIFTypeStatus() {Label = "Debian dpkg status file";};
835};
0d29b9d4
MV
836class debIFTypeDebPkgFile : public pkgIndexFile::Type
837{
838 public:
839 virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const
840 {
841 return new debDebFileRecordParser(File.FileName(),*File.Cache());
842 };
843 debIFTypeDebPkgFile() {Label = "deb Package file";};
844};
a49e7948
MV
845class debIFTypeDscFile : public pkgIndexFile::Type
846{
847 public:
848 virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string DscFile) const
849 {
850 return new debDscRecordParser(DscFile, NULL);
851 };
852 debIFTypeDscFile() {Label = "dsc File Source Index";};
853};
77da39b9
MV
854class debIFTypeDebianSourceDir : public pkgIndexFile::Type
855{
856 public:
857 virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string SourceDir) const
858 {
859 return new debDscRecordParser(SourceDir + string("/debian/control"), NULL);
860 };
861 debIFTypeDebianSourceDir() {Label = "debian/control File Source Index";};
862};
a49e7948 863
b2e465d6
AL
864static debIFTypeSrc _apt_Src;
865static debIFTypePkg _apt_Pkg;
97234432 866static debIFTypeTrans _apt_Trans;
b2e465d6 867static debIFTypeStatus _apt_Status;
0d29b9d4 868static debIFTypeDebPkgFile _apt_DebPkgFile;
a49e7948
MV
869// file based pseudo indexes
870static debIFTypeDscFile _apt_DscFile;
77da39b9 871static debIFTypeDebianSourceDir _apt_DebianSourceDir;
b2e465d6
AL
872
873const pkgIndexFile::Type *debSourcesIndex::GetType() const
874{
875 return &_apt_Src;
876}
877const pkgIndexFile::Type *debPackagesIndex::GetType() const
878{
879 return &_apt_Pkg;
880}
a52f938b
OS
881const pkgIndexFile::Type *debTranslationsIndex::GetType() const
882{
97234432 883 return &_apt_Trans;
a52f938b 884}
b2e465d6
AL
885const pkgIndexFile::Type *debStatusIndex::GetType() const
886{
887 return &_apt_Status;
888}
0d29b9d4
MV
889const pkgIndexFile::Type *debDebPkgFileIndex::GetType() const
890{
891 return &_apt_DebPkgFile;
070536e6 892}
a49e7948
MV
893const pkgIndexFile::Type *debDscFileIndex::GetType() const
894{
895 return &_apt_DscFile;
896}
77da39b9
MV
897const pkgIndexFile::Type *debDebianSourceDirIndex::GetType() const
898{
899 return &_apt_DebianSourceDir;
0d29b9d4 900}
b2e465d6 901 /*}}}*/
862bafea
DK
902
903debStatusIndex::~debStatusIndex() {}
904debPackagesIndex::~debPackagesIndex() {}
905debTranslationsIndex::~debTranslationsIndex() {}
906debSourcesIndex::~debSourcesIndex() {}
907
908debDebPkgFileIndex::~debDebPkgFileIndex() {}