]> git.saurik.com Git - apt.git/blob - apt-pkg/deb/debindexfile.cc
RPM version compare test program
[apt.git] / apt-pkg / deb / debindexfile.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: debindexfile.cc,v 1.5 2001/04/29 05:13:51 jgg Exp $
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 /* */
33 debSourcesIndex::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) */
42 string 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 /* */
67 pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const
68 {
69 string SourcesURI = URItoFileName(IndexURI("Sources"));
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 /* */
77 string debSourcesIndex::Describe(bool Short) const
78 {
79 char S[300];
80 if (Short == true)
81 snprintf(S,sizeof(S),"%s",Info("Packages").c_str());
82 else
83 snprintf(S,sizeof(S),"%s (%s)",Info("Packages").c_str(),
84 IndexFile("Sources").c_str());
85
86 return S;
87 }
88 /*}}}*/
89 // SourcesIndex::Info - One liner describing the index URI /*{{{*/
90 // ---------------------------------------------------------------------
91 /* */
92 string 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 /* */
110 inline string debSourcesIndex::IndexFile(const char *Type) const
111 {
112 return URItoFileName(IndexURI(Type));
113 }
114 string 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 /* */
135 bool 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 /* */
145 bool debSourcesIndex::Exists() const
146 {
147 return FileExists(IndexFile("Sources"));
148 }
149 /*}}}*/
150 // SourcesIndex::Size - Return the size of the index /*{{{*/
151 // ---------------------------------------------------------------------
152 /* */
153 unsigned 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 /* */
165 debPackagesIndex::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 */
173 string 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 */
195 string debPackagesIndex::Describe(bool Short) const
196 {
197 char S[300];
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());
203 return S;
204 }
205 /*}}}*/
206 // PackagesIndex::Info - One liner describing the index URI /*{{{*/
207 // ---------------------------------------------------------------------
208 /* */
209 string 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 /* */
227 inline string debPackagesIndex::IndexFile(const char *Type) const
228 {
229 return _config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type));
230 }
231 string 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 /* */
252 bool 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 /* */
262 bool 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. */
270 unsigned 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 /* */
281 bool 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 /* */
321 pkgCache::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 /* */
345 debStatusIndex::debStatusIndex(string File) : File(File)
346 {
347 }
348 /*}}}*/
349 // StatusIndex::Size - Return the size of the index /*{{{*/
350 // ---------------------------------------------------------------------
351 /* */
352 unsigned 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 /* */
363 bool 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 /* */
393 pkgCache::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 /* */
414 bool debStatusIndex::Exists() const
415 {
416 // Abort if the file does not exist.
417 return true;
418 }
419 /*}}}*/
420
421 // Source List types for Debian /*{{{*/
422 class debSLTypeDeb : public pkgSourceList::Type
423 {
424 public:
425
426 bool CreateItem(vector<pkgIndexFile *> &List,string URI,
427 string Dist,string Section,
428 pkgSourceList::Vendor const *Vendor) const
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
441 class debSLTypeDebSrc : public pkgSourceList::Type
442 {
443 public:
444
445 bool CreateItem(vector<pkgIndexFile *> &List,string URI,
446 string Dist,string Section,
447 pkgSourceList::Vendor const *Vendor) const
448 {
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
460 debSLTypeDeb _apt_DebType;
461 debSLTypeDebSrc _apt_DebSrcType;
462 /*}}}*/
463 // Index File types for Debian /*{{{*/
464 class debIFTypeSrc : public pkgIndexFile::Type
465 {
466 public:
467
468 debIFTypeSrc() {Label = "Debian Source Index";};
469 };
470 class 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 };
480 class 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 };
490 static debIFTypeSrc _apt_Src;
491 static debIFTypePkg _apt_Pkg;
492 static debIFTypeStatus _apt_Status;
493
494 const pkgIndexFile::Type *debSourcesIndex::GetType() const
495 {
496 return &_apt_Src;
497 }
498 const pkgIndexFile::Type *debPackagesIndex::GetType() const
499 {
500 return &_apt_Pkg;
501 }
502 const pkgIndexFile::Type *debStatusIndex::GetType() const
503 {
504 return &_apt_Status;
505 }
506
507 /*}}}*/