]>
git.saurik.com Git - apt.git/blob - apt-pkg/indexfile.cc
fad3391973dc9c49474b11453e2059d409b125dd
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: indexfile.cc,v 1.2.2.1 2003/12/24 23:09:17 mdz Exp $
4 /* ######################################################################
6 Index File - Abstraction for an index of archive/souce file.
8 ##################################################################### */
10 // Include Files /*{{{*/
13 #include <apt-pkg/configuration.h>
14 #include <apt-pkg/indexfile.h>
15 #include <apt-pkg/error.h>
16 #include <apt-pkg/fileutl.h>
17 #include <apt-pkg/aptconfiguration.h>
18 #include <apt-pkg/pkgcache.h>
19 #include <apt-pkg/pkgcachegen.h>
20 #include <apt-pkg/cacheiterators.h>
21 #include <apt-pkg/srcrecords.h>
22 #include <apt-pkg/strutl.h>
23 #include <apt-pkg/progress.h>
24 #include <apt-pkg/macros.h>
26 #include <apt-pkg/deblistparser.h>
37 // Global list of Item supported
38 static pkgIndexFile::Type
*ItmList
[10];
39 pkgIndexFile::Type
**pkgIndexFile::Type::GlobalList
= ItmList
;
40 unsigned long pkgIndexFile::Type::GlobalListLen
= 0;
42 // Type::Type - Constructor /*{{{*/
43 // ---------------------------------------------------------------------
45 pkgIndexFile::Type::Type()
47 ItmList
[GlobalListLen
] = this;
52 // Type::GetType - Locate the type by name /*{{{*/
53 // ---------------------------------------------------------------------
55 pkgIndexFile::Type
*pkgIndexFile::Type::GetType(const char *Type
)
57 for (unsigned I
= 0; I
!= GlobalListLen
; I
++)
58 if (strcmp(GlobalList
[I
]->Label
,Type
) == 0)
63 pkgIndexFile::pkgIndexFile(bool const Trusted
) : /*{{{*/
64 d(NULL
), Trusted(Trusted
)
68 // IndexFile::ArchiveInfo - Stub /*{{{*/
69 std::string
pkgIndexFile::ArchiveInfo(pkgCache::VerIterator
const &/*Ver*/) const
74 // IndexFile::FindInCache - Stub /*{{{*/
75 pkgCache::PkgFileIterator
pkgIndexFile::FindInCache(pkgCache
&Cache
) const
77 return pkgCache::PkgFileIterator(Cache
);
80 // IndexFile::SourceIndex - Stub /*{{{*/
81 std::string
pkgIndexFile::SourceInfo(pkgSrcRecords::Parser
const &/*Record*/,
82 pkgSrcRecords::File
const &/*File*/) const
87 // IndexFile::TranslationsAvailable - Check if will use Translation /*{{{*/
88 // ---------------------------------------------------------------------
90 bool pkgIndexFile::TranslationsAvailable() {
91 return (APT::Configuration::getLanguages().empty() != true);
94 // IndexFile::CheckLanguageCode - Check the Language Code /*{{{*/
95 // ---------------------------------------------------------------------
96 /* No intern need for this method anymore as the check for correctness
97 is already done in getLanguages(). Note also that this check is
98 rather bad (doesn't take three character like ast into account).
99 TODO: Remove method with next API break */
100 APT_DEPRECATED
bool pkgIndexFile::CheckLanguageCode(const char * const Lang
)
102 if (strlen(Lang
) == 2 || (strlen(Lang
) == 5 && Lang
[2] == '_'))
105 if (strcmp(Lang
,"C") != 0)
106 _error
->Warning("Wrong language code %s", Lang
);
111 // IndexFile::LanguageCode - Return the Language Code /*{{{*/
112 // ---------------------------------------------------------------------
113 /* As we have now possibly more than one LanguageCode this method is
114 supersided by a) private classmembers or b) getLanguages().
115 TODO: Remove method with next API break */
116 APT_DEPRECATED
std::string
pkgIndexFile::LanguageCode() {
117 if (TranslationsAvailable() == false)
119 return APT::Configuration::getLanguages()[0];
123 // IndexTarget - Constructor /*{{{*/
124 IndexTarget::IndexTarget(std::string
const &MetaKey
, std::string
const &ShortDesc
,
125 std::string
const &LongDesc
, std::string
const &URI
, bool const IsOptional
,
126 bool const KeepCompressed
, std::map
<std::string
, std::string
> const &Options
) :
127 URI(URI
), Description(LongDesc
), ShortDesc(ShortDesc
), MetaKey(MetaKey
),
128 IsOptional(IsOptional
), KeepCompressed(KeepCompressed
), Options(Options
)
132 std::string
IndexTarget::Option(OptionKeys
const EnumKey
) const /*{{{*/
137 #define APT_CASE(X) case X: Key = #X; break
142 APT_CASE(ARCHITECTURE
);
146 APT_CASE(CREATED_BY
);
148 APT_CASE(DEFAULTENABLED
);
149 APT_CASE(COMPRESSIONTYPES
);
150 APT_CASE(SOURCESENTRY
);
152 case FILENAME
: return _config
->FindDir("Dir::State::lists") + URItoFileName(URI
);
153 case EXISTING_FILENAME
:
154 std::string
const filename
= Option(FILENAME
);
155 std::vector
<std::string
> const types
= VectorizeString(Option(COMPRESSIONTYPES
), ' ');
156 for (std::vector
<std::string
>::const_iterator t
= types
.begin(); t
!= types
.end(); ++t
)
160 std::string
const file
= (*t
== "uncompressed") ? filename
: (filename
+ "." + *t
);
161 if (FileExists(file
))
166 std::map
<std::string
,std::string
>::const_iterator
const M
= Options
.find(Key
);
167 if (M
== Options
.end())
172 bool IndexTarget::OptionBool(OptionKeys
const EnumKey
) const /*{{{*/
174 return StringToBool(Option(EnumKey
));
177 std::string
IndexTarget::Format(std::string format
) const /*{{{*/
179 for (std::map
<std::string
, std::string
>::const_iterator O
= Options
.begin(); O
!= Options
.end(); ++O
)
181 format
= SubstVar(format
, std::string("$(") + O
->first
+ ")", O
->second
);
183 format
= SubstVar(format
, "$(METAKEY)", MetaKey
);
184 format
= SubstVar(format
, "$(SHORTDESC)", ShortDesc
);
185 format
= SubstVar(format
, "$(DESCRIPTION)", Description
);
186 format
= SubstVar(format
, "$(URI)", URI
);
187 format
= SubstVar(format
, "$(FILENAME)", Option(IndexTarget::FILENAME
));
192 pkgDebianIndexTargetFile::pkgDebianIndexTargetFile(IndexTarget
const &Target
, bool const Trusted
) :/*{{{*/
193 pkgDebianIndexFile(Trusted
), d(NULL
), Target(Target
)
197 std::string
pkgDebianIndexTargetFile::ArchiveURI(std::string
const &File
) const/*{{{*/
199 return Target
.Option(IndexTarget::REPO_URI
) + File
;
202 std::string
pkgDebianIndexTargetFile::Describe(bool const Short
) const /*{{{*/
205 return Target
.Description
;
206 return Target
.Description
+ " (" + IndexFileName() + ")";
209 std::string
pkgDebianIndexTargetFile::IndexFileName() const /*{{{*/
211 std::string
const s
= Target
.Option(IndexTarget::FILENAME
);
215 std::vector
<std::string
> const types
= VectorizeString(Target
.Option(IndexTarget::COMPRESSIONTYPES
), ' ');
216 for (std::vector
<std::string
>::const_iterator t
= types
.begin(); t
!= types
.end(); ++t
)
218 std::string p
= s
+ '.' + *t
;
225 unsigned long pkgDebianIndexTargetFile::Size() const /*{{{*/
227 unsigned long size
= 0;
229 /* we need to ignore errors here; if the lists are absent, just return 0 */
230 _error
->PushToStack();
232 FileFd
f(IndexFileName(), FileFd::ReadOnly
, FileFd::Extension
);
236 if (_error
->PendingError() == true)
238 _error
->RevertToStack();
243 bool pkgDebianIndexTargetFile::Exists() const /*{{{*/
245 return FileExists(IndexFileName());
248 std::string
pkgDebianIndexTargetFile::GetArchitecture() const /*{{{*/
250 return Target
.Option(IndexTarget::ARCHITECTURE
);
253 std::string
pkgDebianIndexTargetFile::GetComponent() const /*{{{*/
255 return Target
.Option(IndexTarget::COMPONENT
);
258 bool pkgDebianIndexTargetFile::OpenListFile(FileFd
&Pkg
, std::string
const &FileName
)/*{{{*/
260 if (Pkg
.Open(FileName
, FileFd::ReadOnly
, FileFd::Extension
) == false)
261 return _error
->Error("Problem opening %s",FileName
.c_str());
265 std::string
pkgDebianIndexTargetFile::GetProgressDescription() const
267 return Target
.Description
;
270 pkgDebianIndexRealFile::pkgDebianIndexRealFile(std::string
const &pFile
, bool const Trusted
) :/*{{{*/
271 pkgDebianIndexFile(Trusted
), d(NULL
)
273 if (pFile
== "/nonexistent/stdin")
276 File
= flAbsPath(pFile
);
279 // IndexRealFile::Size - Return the size of the index /*{{{*/
280 unsigned long pkgDebianIndexRealFile::Size() const
283 if (stat(File
.c_str(),&S
) != 0)
288 bool pkgDebianIndexRealFile::Exists() const /*{{{*/
290 return FileExists(File
);
293 std::string
pkgDebianIndexRealFile::Describe(bool const /*Short*/) const/*{{{*/
298 std::string
pkgDebianIndexRealFile::ArchiveURI(std::string
const &/*File*/) const/*{{{*/
300 return "file:" + File
;
303 std::string
pkgDebianIndexRealFile::IndexFileName() const /*{{{*/
308 std::string
pkgDebianIndexRealFile::GetProgressDescription() const
312 bool pkgDebianIndexRealFile::OpenListFile(FileFd
&Pkg
, std::string
const &FileName
)/*{{{*/
314 if (Pkg
.Open(FileName
, FileFd::ReadOnly
, FileFd::None
) == false)
315 return _error
->Error("Problem opening %s",FileName
.c_str());
320 pkgDebianIndexFile::pkgDebianIndexFile(bool const Trusted
) : pkgIndexFile(Trusted
)
323 pkgDebianIndexFile::~pkgDebianIndexFile()
326 pkgCacheListParser
* pkgDebianIndexFile::CreateListParser(FileFd
&Pkg
)
328 if (Pkg
.IsOpen() == false)
330 _error
->PushToStack();
331 pkgCacheListParser
* const Parser
= new debListParser(&Pkg
);
332 bool const newError
= _error
->PendingError();
333 _error
->MergeWithStack();
334 return newError
? NULL
: Parser
;
336 bool pkgDebianIndexFile::Merge(pkgCacheGenerator
&Gen
,OpProgress
* const Prog
)
338 std::string
const PackageFile
= IndexFileName();
340 if (OpenListFile(Pkg
, PackageFile
) == false)
342 _error
->PushToStack();
343 std::unique_ptr
<pkgCacheListParser
> Parser(CreateListParser(Pkg
));
344 bool const newError
= _error
->PendingError();
345 _error
->MergeWithStack();
346 if (newError
== false && Parser
== nullptr)
352 Prog
->SubProgress(0, GetProgressDescription());
354 if (Gen
.SelectFile(PackageFile
, *this, GetArchitecture(), GetComponent(), GetIndexFlags()) == false)
355 return _error
->Error("Problem with SelectFile %s",PackageFile
.c_str());
357 // Store the IMS information
358 pkgCache::PkgFileIterator File
= Gen
.GetCurFile();
359 pkgCacheGenerator::Dynamic
<pkgCache::PkgFileIterator
> DynFile(File
);
360 File
->Size
= Pkg
.FileSize();
361 File
->mtime
= Pkg
.ModificationTime();
363 if (Gen
.MergeList(*Parser
) == false)
364 return _error
->Error("Problem with MergeList %s",PackageFile
.c_str());
367 pkgCache::PkgFileIterator
pkgDebianIndexFile::FindInCache(pkgCache
&Cache
) const
369 std::string
const FileName
= IndexFileName();
370 pkgCache::PkgFileIterator File
= Cache
.FileBegin();
371 for (; File
.end() == false; ++File
)
373 if (File
.FileName() == NULL
|| FileName
!= File
.FileName())
377 if (stat(File
.FileName(),&St
) != 0)
379 if (_config
->FindB("Debug::pkgCacheGen", false))
380 std::clog
<< "DebianIndexFile::FindInCache - stat failed on " << File
.FileName() << std::endl
;
381 return pkgCache::PkgFileIterator(Cache
);
383 if ((map_filesize_t
)St
.st_size
!= File
->Size
|| St
.st_mtime
!= File
->mtime
)
385 if (_config
->FindB("Debug::pkgCacheGen", false))
386 std::clog
<< "DebianIndexFile::FindInCache - size (" << St
.st_size
<< " <> " << File
->Size
387 << ") or mtime (" << St
.st_mtime
<< " <> " << File
->mtime
388 << ") doesn't match for " << File
.FileName() << std::endl
;
389 return pkgCache::PkgFileIterator(Cache
);
397 APT_CONST
pkgIndexFile::~pkgIndexFile() {}
398 APT_CONST
pkgDebianIndexTargetFile::~pkgDebianIndexTargetFile() {}
399 APT_CONST
pkgDebianIndexRealFile::~pkgDebianIndexRealFile() {}