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