]> git.saurik.com Git - apt.git/blame - apt-pkg/deb/debindexfile.cc
Merge bzip2-debs branch
[apt.git] / apt-pkg / deb / debindexfile.cc
CommitLineData
b2e465d6
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
cc742108 3// $Id: debindexfile.cc,v 1.6 2004/01/04 07:41:30 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 /*{{{*/
12#ifdef __GNUG__
13#pragma implementation "apt-pkg/debindexfile.h"
14#endif
15
16#include <apt-pkg/debindexfile.h>
17#include <apt-pkg/debsrcrecords.h>
18#include <apt-pkg/deblistparser.h>
19#include <apt-pkg/debrecords.h>
20#include <apt-pkg/sourcelist.h>
21#include <apt-pkg/configuration.h>
22#include <apt-pkg/progress.h>
23#include <apt-pkg/error.h>
24#include <apt-pkg/strutl.h>
25#include <apt-pkg/acquire-item.h>
26
27#include <sys/stat.h>
28 /*}}}*/
29
30// SourcesIndex::debSourcesIndex - Constructor /*{{{*/
31// ---------------------------------------------------------------------
32/* */
33debSourcesIndex::debSourcesIndex(string URI,string Dist,string Section) :
34 URI(URI), Dist(Dist), Section(Section)
35{
36}
37 /*}}}*/
38// SourcesIndex::SourceInfo - Short 1 liner describing a source /*{{{*/
39// ---------------------------------------------------------------------
40/* The result looks like:
41 http://foo/ stable/main src 1.1.1 (dsc) */
42string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record,
43 pkgSrcRecords::File const &File) const
44{
45 string Res;
46 Res = ::URI::SiteOnly(URI) + ' ';
47 if (Dist[Dist.size() - 1] == '/')
48 {
49 if (Dist != "/")
50 Res += Dist;
51 }
52 else
53 Res += Dist + '/' + Section;
54
55 Res += " ";
56 Res += Record.Package();
57 Res += " ";
58 Res += Record.Version();
59 if (File.Type.empty() == false)
60 Res += " (" + File.Type + ")";
61 return Res;
62}
63 /*}}}*/
64// SourcesIndex::CreateSrcParser - Get a parser for the source files /*{{{*/
65// ---------------------------------------------------------------------
66/* */
67pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const
68{
0e72dd52 69 string SourcesURI = URItoFileName(IndexURI("Sources"));
b2e465d6
AL
70 return new debSrcRecordParser(_config->FindDir("Dir::State::lists") +
71 SourcesURI,this);
72}
73 /*}}}*/
74// SourcesIndex::Describe - Give a descriptive path to the index /*{{{*/
75// ---------------------------------------------------------------------
76/* */
af87ab54 77string debSourcesIndex::Describe(bool Short) const
b2e465d6
AL
78{
79 char S[300];
af87ab54 80 if (Short == true)
cc742108 81 snprintf(S,sizeof(S),"%s",Info("Sources").c_str());
af87ab54 82 else
cc742108 83 snprintf(S,sizeof(S),"%s (%s)",Info("Sources").c_str(),
af87ab54
AL
84 IndexFile("Sources").c_str());
85
b2e465d6
AL
86 return S;
87}
88 /*}}}*/
89// SourcesIndex::Info - One liner describing the index URI /*{{{*/
90// ---------------------------------------------------------------------
91/* */
92string debSourcesIndex::Info(const char *Type) const
93{
94 string Info = ::URI::SiteOnly(URI) + ' ';
95 if (Dist[Dist.size() - 1] == '/')
96 {
97 if (Dist != "/")
98 Info += Dist;
99 }
100 else
101 Info += Dist + '/' + Section;
102 Info += " ";
103 Info += Type;
104 return Info;
105}
106 /*}}}*/
107// SourcesIndex::Index* - Return the URI to the index files /*{{{*/
108// ---------------------------------------------------------------------
109/* */
110inline string debSourcesIndex::IndexFile(const char *Type) const
111{
112 return URItoFileName(IndexURI(Type));
113}
114string debSourcesIndex::IndexURI(const char *Type) const
115{
116 string Res;
117 if (Dist[Dist.size() - 1] == '/')
118 {
119 if (Dist != "/")
120 Res = URI + Dist;
121 else
122 Res = URI;
123 }
124 else
125 Res = URI + "dists/" + Dist + '/' + Section +
126 "/source/";
127
128 Res += Type;
129 return Res;
130}
131 /*}}}*/
132// SourcesIndex::GetIndexes - Fetch the index files /*{{{*/
133// ---------------------------------------------------------------------
134/* */
135bool debSourcesIndex::GetIndexes(pkgAcquire *Owner) const
136{
137 new pkgAcqIndex(Owner,IndexURI("Sources"),Info("Sources"),"Sources");
138 new pkgAcqIndexRel(Owner,IndexURI("Release"),Info("Release"),"Release");
139 return true;
140}
141 /*}}}*/
142// SourcesIndex::Exists - Check if the index is available /*{{{*/
143// ---------------------------------------------------------------------
144/* */
145bool debSourcesIndex::Exists() const
146{
147 return FileExists(IndexFile("Sources"));
148}
149 /*}}}*/
150// SourcesIndex::Size - Return the size of the index /*{{{*/
151// ---------------------------------------------------------------------
152/* */
153unsigned long debSourcesIndex::Size() const
154{
155 struct stat S;
156 if (stat(IndexFile("Sources").c_str(),&S) != 0)
157 return 0;
158 return S.st_size;
159}
160 /*}}}*/
161
162// PackagesIndex::debPackagesIndex - Contructor /*{{{*/
163// ---------------------------------------------------------------------
164/* */
165debPackagesIndex::debPackagesIndex(string URI,string Dist,string Section) :
166 URI(URI), Dist(Dist), Section(Section)
167{
168}
169 /*}}}*/
170// PackagesIndex::ArchiveInfo - Short version of the archive url /*{{{*/
171// ---------------------------------------------------------------------
172/* This is a shorter version that is designed to be < 60 chars or so */
173string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const
174{
175 string Res = ::URI::SiteOnly(URI) + ' ';
176 if (Dist[Dist.size() - 1] == '/')
177 {
178 if (Dist != "/")
179 Res += Dist;
180 }
181 else
182 Res += Dist + '/' + Section;
183
184 Res += " ";
185 Res += Ver.ParentPkg().Name();
186 Res += " ";
187 Res += Ver.VerStr();
188 return Res;
189}
190 /*}}}*/
191// PackagesIndex::Describe - Give a descriptive path to the index /*{{{*/
192// ---------------------------------------------------------------------
193/* This should help the user find the index in the sources.list and
194 in the filesystem for problem solving */
af87ab54 195string debPackagesIndex::Describe(bool Short) const
b2e465d6
AL
196{
197 char S[300];
af87ab54
AL
198 if (Short == true)
199 snprintf(S,sizeof(S),"%s",Info("Packages").c_str());
200 else
201 snprintf(S,sizeof(S),"%s (%s)",Info("Packages").c_str(),
202 IndexFile("Packages").c_str());
b2e465d6
AL
203 return S;
204}
205 /*}}}*/
206// PackagesIndex::Info - One liner describing the index URI /*{{{*/
207// ---------------------------------------------------------------------
208/* */
209string debPackagesIndex::Info(const char *Type) const
210{
211 string Info = ::URI::SiteOnly(URI) + ' ';
212 if (Dist[Dist.size() - 1] == '/')
213 {
214 if (Dist != "/")
215 Info += Dist;
216 }
217 else
218 Info += Dist + '/' + Section;
219 Info += " ";
220 Info += Type;
221 return Info;
222}
223 /*}}}*/
224// PackagesIndex::Index* - Return the URI to the index files /*{{{*/
225// ---------------------------------------------------------------------
226/* */
227inline string debPackagesIndex::IndexFile(const char *Type) const
228{
229 return _config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type));
230}
231string debPackagesIndex::IndexURI(const char *Type) const
232{
233 string Res;
234 if (Dist[Dist.size() - 1] == '/')
235 {
236 if (Dist != "/")
237 Res = URI + Dist;
238 else
239 Res = URI;
240 }
241 else
242 Res = URI + "dists/" + Dist + '/' + Section +
243 "/binary-" + _config->Find("APT::Architecture") + '/';
244
245 Res += Type;
246 return Res;
247}
248 /*}}}*/
249// PackagesIndex::GetIndexes - Fetch the index files /*{{{*/
250// ---------------------------------------------------------------------
251/* */
252bool debPackagesIndex::GetIndexes(pkgAcquire *Owner) const
253{
254 new pkgAcqIndex(Owner,IndexURI("Packages"),Info("Packages"),"Packages");
255 new pkgAcqIndexRel(Owner,IndexURI("Release"),Info("Release"),"Release");
256 return true;
257}
258 /*}}}*/
259// PackagesIndex::Exists - Check if the index is available /*{{{*/
260// ---------------------------------------------------------------------
261/* */
262bool debPackagesIndex::Exists() const
263{
264 return FileExists(IndexFile("Packages"));
265}
266 /*}}}*/
267// PackagesIndex::Size - Return the size of the index /*{{{*/
268// ---------------------------------------------------------------------
269/* This is really only used for progress reporting. */
270unsigned long debPackagesIndex::Size() const
271{
272 struct stat S;
273 if (stat(IndexFile("Packages").c_str(),&S) != 0)
274 return 0;
275 return S.st_size;
276}
277 /*}}}*/
278// PackagesIndex::Merge - Load the index file into a cache /*{{{*/
279// ---------------------------------------------------------------------
280/* */
281bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const
282{
283 string PackageFile = IndexFile("Packages");
284 FileFd Pkg(PackageFile,FileFd::ReadOnly);
285 debListParser Parser(&Pkg);
286 if (_error->PendingError() == true)
287 return _error->Error("Problem opening %s",PackageFile.c_str());
288
289 Prog.SubProgress(0,Info("Packages"));
290 ::URI Tmp(URI);
291 if (Gen.SelectFile(PackageFile,Tmp.Host,*this) == false)
292 return _error->Error("Problem with SelectFile %s",PackageFile.c_str());
293
294 // Store the IMS information
295 pkgCache::PkgFileIterator File = Gen.GetCurFile();
296 struct stat St;
297 if (fstat(Pkg.Fd(),&St) != 0)
298 return _error->Errno("fstat","Failed to stat");
299 File->Size = St.st_size;
300 File->mtime = St.st_mtime;
301
302 if (Gen.MergeList(Parser) == false)
303 return _error->Error("Problem with MergeList %s",PackageFile.c_str());
304
305 // Check the release file
306 string ReleaseFile = IndexFile("Release");
307 if (FileExists(ReleaseFile) == true)
308 {
309 FileFd Rel(ReleaseFile,FileFd::ReadOnly);
310 if (_error->PendingError() == true)
311 return false;
312 Parser.LoadReleaseInfo(File,Rel);
313 }
314
315 return true;
316}
317 /*}}}*/
318// PackagesIndex::FindInCache - Find this index /*{{{*/
319// ---------------------------------------------------------------------
320/* */
321pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const
322{
323 string FileName = IndexFile("Packages");
324 pkgCache::PkgFileIterator File = Cache.FileBegin();
325 for (; File.end() == false; File++)
326 {
327 if (FileName != File.FileName())
328 continue;
329
330 struct stat St;
331 if (stat(File.FileName(),&St) != 0)
332 return pkgCache::PkgFileIterator(Cache);
333 if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime)
334 return pkgCache::PkgFileIterator(Cache);
335 return File;
336 }
337
338 return File;
339}
340 /*}}}*/
341
342// StatusIndex::debStatusIndex - Constructor /*{{{*/
343// ---------------------------------------------------------------------
344/* */
345debStatusIndex::debStatusIndex(string File) : File(File)
346{
347}
348 /*}}}*/
349// StatusIndex::Size - Return the size of the index /*{{{*/
350// ---------------------------------------------------------------------
351/* */
352unsigned long debStatusIndex::Size() const
353{
354 struct stat S;
355 if (stat(File.c_str(),&S) != 0)
356 return 0;
357 return S.st_size;
358}
359 /*}}}*/
360// StatusIndex::Merge - Load the index file into a cache /*{{{*/
361// ---------------------------------------------------------------------
362/* */
363bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const
364{
365 FileFd Pkg(File,FileFd::ReadOnly);
366 if (_error->PendingError() == true)
367 return false;
368 debListParser Parser(&Pkg);
369 if (_error->PendingError() == true)
370 return false;
371
372 Prog.SubProgress(0,File);
373 if (Gen.SelectFile(File,string(),*this,pkgCache::Flag::NotSource) == false)
374 return _error->Error("Problem with SelectFile %s",File.c_str());
375
376 // Store the IMS information
377 pkgCache::PkgFileIterator CFile = Gen.GetCurFile();
378 struct stat St;
379 if (fstat(Pkg.Fd(),&St) != 0)
380 return _error->Errno("fstat","Failed to stat");
381 CFile->Size = St.st_size;
382 CFile->mtime = St.st_mtime;
383 CFile->Archive = Gen.WriteUniqString("now");
384
385 if (Gen.MergeList(Parser) == false)
386 return _error->Error("Problem with MergeList %s",File.c_str());
387 return true;
388}
389 /*}}}*/
390// StatusIndex::FindInCache - Find this index /*{{{*/
391// ---------------------------------------------------------------------
392/* */
393pkgCache::PkgFileIterator debStatusIndex::FindInCache(pkgCache &Cache) const
394{
395 pkgCache::PkgFileIterator File = Cache.FileBegin();
396 for (; File.end() == false; File++)
397 {
398 if (this->File != File.FileName())
399 continue;
400
401 struct stat St;
402 if (stat(File.FileName(),&St) != 0)
403 return pkgCache::PkgFileIterator(Cache);
404 if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime)
405 return pkgCache::PkgFileIterator(Cache);
406 return File;
407 }
408 return File;
409}
410 /*}}}*/
411// StatusIndex::Exists - Check if the index is available /*{{{*/
412// ---------------------------------------------------------------------
413/* */
414bool debStatusIndex::Exists() const
415{
416 // Abort if the file does not exist.
417 return true;
418}
419 /*}}}*/
420
421// Source List types for Debian /*{{{*/
422class debSLTypeDeb : public pkgSourceList::Type
423{
424 public:
425
426 bool CreateItem(vector<pkgIndexFile *> &List,string URI,
a7c835af
AL
427 string Dist,string Section,
428 pkgSourceList::Vendor const *Vendor) const
b2e465d6
AL
429 {
430 List.push_back(new debPackagesIndex(URI,Dist,Section));
431 return true;
432 };
433
434 debSLTypeDeb()
435 {
436 Name = "deb";
437 Label = "Standard Debian binary tree";
438 }
439};
440
441class debSLTypeDebSrc : public pkgSourceList::Type
442{
443 public:
444
445 bool CreateItem(vector<pkgIndexFile *> &List,string URI,
a7c835af
AL
446 string Dist,string Section,
447 pkgSourceList::Vendor const *Vendor) const
448 {
b2e465d6
AL
449 List.push_back(new debSourcesIndex(URI,Dist,Section));
450 return true;
451 };
452
453 debSLTypeDebSrc()
454 {
455 Name = "deb-src";
456 Label = "Standard Debian source tree";
457 }
458};
459
460debSLTypeDeb _apt_DebType;
461debSLTypeDebSrc _apt_DebSrcType;
462 /*}}}*/
463// Index File types for Debian /*{{{*/
464class debIFTypeSrc : public pkgIndexFile::Type
465{
466 public:
467
468 debIFTypeSrc() {Label = "Debian Source Index";};
469};
470class debIFTypePkg : public pkgIndexFile::Type
471{
472 public:
473
474 virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const
475 {
476 return new debRecordParser(File.FileName(),*File.Cache());
477 };
478 debIFTypePkg() {Label = "Debian Package Index";};
479};
480class debIFTypeStatus : public pkgIndexFile::Type
481{
482 public:
483
484 virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const
485 {
486 return new debRecordParser(File.FileName(),*File.Cache());
487 };
488 debIFTypeStatus() {Label = "Debian dpkg status file";};
489};
490static debIFTypeSrc _apt_Src;
491static debIFTypePkg _apt_Pkg;
492static debIFTypeStatus _apt_Status;
493
494const pkgIndexFile::Type *debSourcesIndex::GetType() const
495{
496 return &_apt_Src;
497}
498const pkgIndexFile::Type *debPackagesIndex::GetType() const
499{
500 return &_apt_Pkg;
501}
502const pkgIndexFile::Type *debStatusIndex::GetType() const
503{
504 return &_apt_Status;
505}
506
507 /*}}}*/