1 // -*- mode: cpp; mode: fold -*-
3 // $Id: debindexfile.cc,v 1.2 2001/02/20 07:03:17 jgg Exp $
4 /* ######################################################################
6 Debian Specific sources.list types and the three sorts of Debian
9 ##################################################################### */
11 // Include Files /*{{{*/
13 #pragma implementation "apt-pkg/debindexfile.h"
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>
30 // SourcesIndex::debSourcesIndex - Constructor /*{{{*/
31 // ---------------------------------------------------------------------
33 debSourcesIndex::debSourcesIndex(string URI
,string Dist
,string Section
) :
34 URI(URI
), Dist(Dist
), Section(Section
)
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
46 Res
= ::URI::SiteOnly(URI
) + ' ';
47 if (Dist
[Dist
.size() - 1] == '/')
53 Res
+= Dist
+ '/' + Section
;
56 Res
+= Record
.Package();
58 Res
+= Record
.Version();
59 if (File
.Type
.empty() == false)
60 Res
+= " (" + File
.Type
+ ")";
64 // SourcesIndex::CreateSrcParser - Get a parser for the source files /*{{{*/
65 // ---------------------------------------------------------------------
67 pkgSrcRecords::Parser
*debSourcesIndex::CreateSrcParser() const
70 if (Dist
[Dist
.size() - 1] == '/')
71 SourcesURI
= URI
+ Dist
;
73 SourcesURI
= URI
+ "dists/" + Dist
+ '/' + Section
+
76 SourcesURI
+= "Sources";
77 SourcesURI
= URItoFileName(SourcesURI
);
78 return new debSrcRecordParser(_config
->FindDir("Dir::State::lists") +
82 // SourcesIndex::Describe - Give a descriptive path to the index /*{{{*/
83 // ---------------------------------------------------------------------
85 string
debSourcesIndex::Describe() const
88 snprintf(S
,sizeof(S
),"%s (%s)",Info("Packages").c_str(),
89 IndexFile("Sources").c_str());
93 // SourcesIndex::Info - One liner describing the index URI /*{{{*/
94 // ---------------------------------------------------------------------
96 string
debSourcesIndex::Info(const char *Type
) const
98 string Info
= ::URI::SiteOnly(URI
) + ' ';
99 if (Dist
[Dist
.size() - 1] == '/')
105 Info
+= Dist
+ '/' + Section
;
111 // SourcesIndex::Index* - Return the URI to the index files /*{{{*/
112 // ---------------------------------------------------------------------
114 inline string
debSourcesIndex::IndexFile(const char *Type
) const
116 return URItoFileName(IndexURI(Type
));
118 string
debSourcesIndex::IndexURI(const char *Type
) const
121 if (Dist
[Dist
.size() - 1] == '/')
129 Res
= URI
+ "dists/" + Dist
+ '/' + Section
+
136 // SourcesIndex::GetIndexes - Fetch the index files /*{{{*/
137 // ---------------------------------------------------------------------
139 bool debSourcesIndex::GetIndexes(pkgAcquire
*Owner
) const
141 new pkgAcqIndex(Owner
,IndexURI("Sources"),Info("Sources"),"Sources");
142 new pkgAcqIndexRel(Owner
,IndexURI("Release"),Info("Release"),"Release");
146 // SourcesIndex::Exists - Check if the index is available /*{{{*/
147 // ---------------------------------------------------------------------
149 bool debSourcesIndex::Exists() const
151 return FileExists(IndexFile("Sources"));
154 // SourcesIndex::Size - Return the size of the index /*{{{*/
155 // ---------------------------------------------------------------------
157 unsigned long debSourcesIndex::Size() const
160 if (stat(IndexFile("Sources").c_str(),&S
) != 0)
166 // PackagesIndex::debPackagesIndex - Contructor /*{{{*/
167 // ---------------------------------------------------------------------
169 debPackagesIndex::debPackagesIndex(string URI
,string Dist
,string Section
) :
170 URI(URI
), Dist(Dist
), Section(Section
)
174 // PackagesIndex::ArchiveInfo - Short version of the archive url /*{{{*/
175 // ---------------------------------------------------------------------
176 /* This is a shorter version that is designed to be < 60 chars or so */
177 string
debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver
) const
179 string Res
= ::URI::SiteOnly(URI
) + ' ';
180 if (Dist
[Dist
.size() - 1] == '/')
186 Res
+= Dist
+ '/' + Section
;
189 Res
+= Ver
.ParentPkg().Name();
195 // PackagesIndex::Describe - Give a descriptive path to the index /*{{{*/
196 // ---------------------------------------------------------------------
197 /* This should help the user find the index in the sources.list and
198 in the filesystem for problem solving */
199 string
debPackagesIndex::Describe() const
202 snprintf(S
,sizeof(S
),"%s (%s)",Info("Packages").c_str(),
203 IndexFile("Packages").c_str());
207 // PackagesIndex::Info - One liner describing the index URI /*{{{*/
208 // ---------------------------------------------------------------------
210 string
debPackagesIndex::Info(const char *Type
) const
212 string Info
= ::URI::SiteOnly(URI
) + ' ';
213 if (Dist
[Dist
.size() - 1] == '/')
219 Info
+= Dist
+ '/' + Section
;
225 // PackagesIndex::Index* - Return the URI to the index files /*{{{*/
226 // ---------------------------------------------------------------------
228 inline string
debPackagesIndex::IndexFile(const char *Type
) const
230 return _config
->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type
));
232 string
debPackagesIndex::IndexURI(const char *Type
) const
235 if (Dist
[Dist
.size() - 1] == '/')
243 Res
= URI
+ "dists/" + Dist
+ '/' + Section
+
244 "/binary-" + _config
->Find("APT::Architecture") + '/';
250 // PackagesIndex::GetIndexes - Fetch the index files /*{{{*/
251 // ---------------------------------------------------------------------
253 bool debPackagesIndex::GetIndexes(pkgAcquire
*Owner
) const
255 new pkgAcqIndex(Owner
,IndexURI("Packages"),Info("Packages"),"Packages");
256 new pkgAcqIndexRel(Owner
,IndexURI("Release"),Info("Release"),"Release");
260 // PackagesIndex::Exists - Check if the index is available /*{{{*/
261 // ---------------------------------------------------------------------
263 bool debPackagesIndex::Exists() const
265 return FileExists(IndexFile("Packages"));
268 // PackagesIndex::Size - Return the size of the index /*{{{*/
269 // ---------------------------------------------------------------------
270 /* This is really only used for progress reporting. */
271 unsigned long debPackagesIndex::Size() const
274 if (stat(IndexFile("Packages").c_str(),&S
) != 0)
279 // PackagesIndex::Merge - Load the index file into a cache /*{{{*/
280 // ---------------------------------------------------------------------
282 bool debPackagesIndex::Merge(pkgCacheGenerator
&Gen
,OpProgress
&Prog
) const
284 string PackageFile
= IndexFile("Packages");
285 FileFd
Pkg(PackageFile
,FileFd::ReadOnly
);
286 debListParser
Parser(&Pkg
);
287 if (_error
->PendingError() == true)
288 return _error
->Error("Problem opening %s",PackageFile
.c_str());
290 Prog
.SubProgress(0,Info("Packages"));
292 if (Gen
.SelectFile(PackageFile
,Tmp
.Host
,*this) == false)
293 return _error
->Error("Problem with SelectFile %s",PackageFile
.c_str());
295 // Store the IMS information
296 pkgCache::PkgFileIterator File
= Gen
.GetCurFile();
298 if (fstat(Pkg
.Fd(),&St
) != 0)
299 return _error
->Errno("fstat","Failed to stat");
300 File
->Size
= St
.st_size
;
301 File
->mtime
= St
.st_mtime
;
303 if (Gen
.MergeList(Parser
) == false)
304 return _error
->Error("Problem with MergeList %s",PackageFile
.c_str());
306 // Check the release file
307 string ReleaseFile
= IndexFile("Release");
308 if (FileExists(ReleaseFile
) == true)
310 FileFd
Rel(ReleaseFile
,FileFd::ReadOnly
);
311 if (_error
->PendingError() == true)
313 Parser
.LoadReleaseInfo(File
,Rel
);
319 // PackagesIndex::FindInCache - Find this index /*{{{*/
320 // ---------------------------------------------------------------------
322 pkgCache::PkgFileIterator
debPackagesIndex::FindInCache(pkgCache
&Cache
) const
324 string FileName
= IndexFile("Packages");
325 pkgCache::PkgFileIterator File
= Cache
.FileBegin();
326 for (; File
.end() == false; File
++)
328 if (FileName
!= File
.FileName())
332 if (stat(File
.FileName(),&St
) != 0)
333 return pkgCache::PkgFileIterator(Cache
);
334 if ((unsigned)St
.st_size
!= File
->Size
|| St
.st_mtime
!= File
->mtime
)
335 return pkgCache::PkgFileIterator(Cache
);
343 // StatusIndex::debStatusIndex - Constructor /*{{{*/
344 // ---------------------------------------------------------------------
346 debStatusIndex::debStatusIndex(string File
) : File(File
)
350 // StatusIndex::Size - Return the size of the index /*{{{*/
351 // ---------------------------------------------------------------------
353 unsigned long debStatusIndex::Size() const
356 if (stat(File
.c_str(),&S
) != 0)
361 // StatusIndex::Merge - Load the index file into a cache /*{{{*/
362 // ---------------------------------------------------------------------
364 bool debStatusIndex::Merge(pkgCacheGenerator
&Gen
,OpProgress
&Prog
) const
366 FileFd
Pkg(File
,FileFd::ReadOnly
);
367 if (_error
->PendingError() == true)
369 debListParser
Parser(&Pkg
);
370 if (_error
->PendingError() == true)
373 Prog
.SubProgress(0,File
);
374 if (Gen
.SelectFile(File
,string(),*this,pkgCache::Flag::NotSource
) == false)
375 return _error
->Error("Problem with SelectFile %s",File
.c_str());
377 // Store the IMS information
378 pkgCache::PkgFileIterator CFile
= Gen
.GetCurFile();
380 if (fstat(Pkg
.Fd(),&St
) != 0)
381 return _error
->Errno("fstat","Failed to stat");
382 CFile
->Size
= St
.st_size
;
383 CFile
->mtime
= St
.st_mtime
;
384 CFile
->Archive
= Gen
.WriteUniqString("now");
386 if (Gen
.MergeList(Parser
) == false)
387 return _error
->Error("Problem with MergeList %s",File
.c_str());
391 // StatusIndex::FindInCache - Find this index /*{{{*/
392 // ---------------------------------------------------------------------
394 pkgCache::PkgFileIterator
debStatusIndex::FindInCache(pkgCache
&Cache
) const
396 pkgCache::PkgFileIterator File
= Cache
.FileBegin();
397 for (; File
.end() == false; File
++)
399 if (this->File
!= File
.FileName())
403 if (stat(File
.FileName(),&St
) != 0)
404 return pkgCache::PkgFileIterator(Cache
);
405 if ((unsigned)St
.st_size
!= File
->Size
|| St
.st_mtime
!= File
->mtime
)
406 return pkgCache::PkgFileIterator(Cache
);
412 // StatusIndex::Exists - Check if the index is available /*{{{*/
413 // ---------------------------------------------------------------------
415 bool debStatusIndex::Exists() const
417 // Abort if the file does not exist.
422 // Source List types for Debian /*{{{*/
423 class debSLTypeDeb
: public pkgSourceList::Type
427 bool CreateItem(vector
<pkgIndexFile
*> &List
,string URI
,
428 string Dist
,string Section
) const
430 List
.push_back(new debPackagesIndex(URI
,Dist
,Section
));
437 Label
= "Standard Debian binary tree";
441 class debSLTypeDebSrc
: public pkgSourceList::Type
445 bool CreateItem(vector
<pkgIndexFile
*> &List
,string URI
,
446 string Dist
,string Section
) const
448 List
.push_back(new debSourcesIndex(URI
,Dist
,Section
));
455 Label
= "Standard Debian source tree";
459 debSLTypeDeb _apt_DebType
;
460 debSLTypeDebSrc _apt_DebSrcType
;
462 // Index File types for Debian /*{{{*/
463 class debIFTypeSrc
: public pkgIndexFile::Type
467 debIFTypeSrc() {Label
= "Debian Source Index";};
469 class debIFTypePkg
: public pkgIndexFile::Type
473 virtual pkgRecords::Parser
*CreatePkgParser(pkgCache::PkgFileIterator File
) const
475 return new debRecordParser(File
.FileName(),*File
.Cache());
477 debIFTypePkg() {Label
= "Debian Package Index";};
479 class debIFTypeStatus
: public pkgIndexFile::Type
483 virtual pkgRecords::Parser
*CreatePkgParser(pkgCache::PkgFileIterator File
) const
485 return new debRecordParser(File
.FileName(),*File
.Cache());
487 debIFTypeStatus() {Label
= "Debian dpkg status file";};
489 static debIFTypeSrc _apt_Src
;
490 static debIFTypePkg _apt_Pkg
;
491 static debIFTypeStatus _apt_Status
;
493 const pkgIndexFile::Type
*debSourcesIndex::GetType() const
497 const pkgIndexFile::Type
*debPackagesIndex::GetType() const
501 const pkgIndexFile::Type
*debStatusIndex::GetType() const