]>
git.saurik.com Git - apt.git/blob - apt-pkg/indexfile.cc
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(COMPRESSIONTYPES
);
150 case FILENAME
: return _config
->FindDir("Dir::State::lists") + URItoFileName(URI
);
151 case EXISTING_FILENAME
:
152 std::string
const filename
= Option(FILENAME
);
153 std::vector
<std::string
> const types
= VectorizeString(Option(COMPRESSIONTYPES
), ' ');
154 for (std::vector
<std::string
>::const_iterator t
= types
.begin(); t
!= types
.end(); ++t
)
158 std::string
const file
= (*t
== "uncompressed") ? filename
: (filename
+ "." + *t
);
159 if (FileExists(file
))
164 std::map
<std::string
,std::string
>::const_iterator
const M
= Options
.find(Key
);
165 if (M
== Options
.end())
170 bool IndexTarget::OptionBool(OptionKeys
const EnumKey
) const /*{{{*/
172 return StringToBool(Option(EnumKey
));
175 std::string
IndexTarget::Format(std::string format
) const /*{{{*/
177 for (std::map
<std::string
, std::string
>::const_iterator O
= Options
.begin(); O
!= Options
.end(); ++O
)
179 format
= SubstVar(format
, std::string("$(") + O
->first
+ ")", O
->second
);
181 format
= SubstVar(format
, "$(METAKEY)", MetaKey
);
182 format
= SubstVar(format
, "$(SHORTDESC)", ShortDesc
);
183 format
= SubstVar(format
, "$(DESCRIPTION)", Description
);
184 format
= SubstVar(format
, "$(URI)", URI
);
185 format
= SubstVar(format
, "$(FILENAME)", Option(IndexTarget::FILENAME
));
190 pkgDebianIndexTargetFile::pkgDebianIndexTargetFile(IndexTarget
const &Target
, bool const Trusted
) :/*{{{*/
191 pkgDebianIndexFile(Trusted
), d(NULL
), Target(Target
)
195 std::string
pkgDebianIndexTargetFile::ArchiveURI(std::string
const &File
) const/*{{{*/
197 return Target
.Option(IndexTarget::REPO_URI
) + File
;
200 std::string
pkgDebianIndexTargetFile::Describe(bool const Short
) const /*{{{*/
203 return Target
.Description
;
204 return Target
.Description
+ " (" + IndexFileName() + ")";
207 std::string
pkgDebianIndexTargetFile::IndexFileName() const /*{{{*/
209 std::string
const s
= Target
.Option(IndexTarget::FILENAME
);
213 std::vector
<std::string
> const types
= VectorizeString(Target
.Option(IndexTarget::COMPRESSIONTYPES
), ' ');
214 for (std::vector
<std::string
>::const_iterator t
= types
.begin(); t
!= types
.end(); ++t
)
216 std::string p
= s
+ '.' + *t
;
223 unsigned long pkgDebianIndexTargetFile::Size() const /*{{{*/
225 unsigned long size
= 0;
227 /* we need to ignore errors here; if the lists are absent, just return 0 */
228 _error
->PushToStack();
230 FileFd
f(IndexFileName(), FileFd::ReadOnly
, FileFd::Extension
);
234 if (_error
->PendingError() == true)
236 _error
->RevertToStack();
241 bool pkgDebianIndexTargetFile::Exists() const /*{{{*/
243 return FileExists(IndexFileName());
246 std::string
pkgDebianIndexTargetFile::GetArchitecture() const /*{{{*/
248 return Target
.Option(IndexTarget::ARCHITECTURE
);
251 std::string
pkgDebianIndexTargetFile::GetComponent() const /*{{{*/
253 return Target
.Option(IndexTarget::COMPONENT
);
256 bool pkgDebianIndexTargetFile::OpenListFile(FileFd
&Pkg
, std::string
const &FileName
)/*{{{*/
258 if (Pkg
.Open(FileName
, FileFd::ReadOnly
, FileFd::Extension
) == false)
259 return _error
->Error("Problem opening %s",FileName
.c_str());
263 std::string
pkgDebianIndexTargetFile::GetProgressDescription() const
265 return Target
.Description
;
268 pkgDebianIndexRealFile::pkgDebianIndexRealFile(std::string
const &File
, bool const Trusted
) :/*{{{*/
269 pkgDebianIndexFile(Trusted
), d(NULL
), File(flAbsPath(File
))
273 // IndexRealFile::Size - Return the size of the index /*{{{*/
274 unsigned long pkgDebianIndexRealFile::Size() const
277 if (stat(File
.c_str(),&S
) != 0)
282 bool pkgDebianIndexRealFile::Exists() const /*{{{*/
284 return FileExists(File
);
287 std::string
pkgDebianIndexRealFile::Describe(bool const /*Short*/) const/*{{{*/
292 std::string
pkgDebianIndexRealFile::ArchiveURI(std::string
const &/*File*/) const/*{{{*/
294 return "file:" + File
;
297 std::string
pkgDebianIndexRealFile::IndexFileName() const /*{{{*/
302 std::string
pkgDebianIndexRealFile::GetProgressDescription() const
306 bool pkgDebianIndexRealFile::OpenListFile(FileFd
&Pkg
, std::string
const &FileName
)/*{{{*/
308 if (Pkg
.Open(FileName
, FileFd::ReadOnly
, FileFd::None
) == false)
309 return _error
->Error("Problem opening %s",FileName
.c_str());
314 pkgDebianIndexFile::pkgDebianIndexFile(bool const Trusted
) : pkgIndexFile(Trusted
)
317 pkgDebianIndexFile::~pkgDebianIndexFile()
320 pkgCacheListParser
* pkgDebianIndexFile::CreateListParser(FileFd
&Pkg
)
322 if (Pkg
.IsOpen() == false)
324 _error
->PushToStack();
325 pkgCacheListParser
* const Parser
= new debListParser(&Pkg
);
326 bool const newError
= _error
->PendingError();
327 _error
->MergeWithStack();
328 return newError
? NULL
: Parser
;
330 bool pkgDebianIndexFile::Merge(pkgCacheGenerator
&Gen
,OpProgress
* const Prog
)
332 std::string
const PackageFile
= IndexFileName();
334 if (OpenListFile(Pkg
, PackageFile
) == false)
336 _error
->PushToStack();
337 std::unique_ptr
<pkgCacheListParser
> Parser(CreateListParser(Pkg
));
338 bool const newError
= _error
->PendingError();
339 if (newError
== false && Parser
== nullptr)
345 Prog
->SubProgress(0, GetProgressDescription());
347 if (Gen
.SelectFile(PackageFile
, *this, GetArchitecture(), GetComponent(), GetIndexFlags()) == false)
348 return _error
->Error("Problem with SelectFile %s",PackageFile
.c_str());
350 // Store the IMS information
351 pkgCache::PkgFileIterator File
= Gen
.GetCurFile();
352 pkgCacheGenerator::Dynamic
<pkgCache::PkgFileIterator
> DynFile(File
);
353 File
->Size
= Pkg
.FileSize();
354 File
->mtime
= Pkg
.ModificationTime();
356 if (Gen
.MergeList(*Parser
) == false)
357 return _error
->Error("Problem with MergeList %s",PackageFile
.c_str());
360 pkgCache::PkgFileIterator
pkgDebianIndexFile::FindInCache(pkgCache
&Cache
) const
362 std::string
const FileName
= IndexFileName();
363 pkgCache::PkgFileIterator File
= Cache
.FileBegin();
364 for (; File
.end() == false; ++File
)
366 if (File
.FileName() == NULL
|| FileName
!= File
.FileName())
370 if (stat(File
.FileName(),&St
) != 0)
372 if (_config
->FindB("Debug::pkgCacheGen", false))
373 std::clog
<< "DebianIndexFile::FindInCache - stat failed on " << File
.FileName() << std::endl
;
374 return pkgCache::PkgFileIterator(Cache
);
376 if ((map_filesize_t
)St
.st_size
!= File
->Size
|| St
.st_mtime
!= File
->mtime
)
378 if (_config
->FindB("Debug::pkgCacheGen", false))
379 std::clog
<< "DebianIndexFile::FindInCache - size (" << St
.st_size
<< " <> " << File
->Size
380 << ") or mtime (" << St
.st_mtime
<< " <> " << File
->mtime
381 << ") doesn't match for " << File
.FileName() << std::endl
;
382 return pkgCache::PkgFileIterator(Cache
);
390 APT_CONST
pkgIndexFile::~pkgIndexFile() {}
391 APT_CONST
pkgDebianIndexTargetFile::~pkgDebianIndexTargetFile() {}
392 APT_CONST
pkgDebianIndexRealFile::~pkgDebianIndexRealFile() {}