X-Git-Url: https://git.hcoop.net/ntk/apt.git/blobdiff_plain/408a4726131e9db26ff868623a5d216a26c45a50..1701312682aad167b4ff3425a8e9b680c04b49a5:/apt-pkg/deb/debindexfile.cc diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index 9f435bba..eee758b7 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -9,25 +9,36 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#ifdef __GNUG__ -#pragma implementation "apt-pkg/debindexfile.h" -#endif +#include #include #include #include #include -#include #include #include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include /*}}}*/ +using std::string; + // SourcesIndex::debSourcesIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -39,12 +50,12 @@ debSourcesIndex::debSourcesIndex(string URI,string Dist,string Section,bool Trus // SourcesIndex::SourceInfo - Short 1 liner describing a source /*{{{*/ // --------------------------------------------------------------------- /* The result looks like: - http://foo/ stable/main src 1.1.1 (dsc) */ + http://foo/debian/ stable/main src 1.1.1 (dsc) */ string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record, pkgSrcRecords::File const &File) const { string Res; - Res = ::URI::SiteOnly(URI) + ' '; + Res = ::URI::NoUserPassword(URI) + ' '; if (Dist[Dist.size() - 1] == '/') { if (Dist != "/") @@ -67,9 +78,16 @@ string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record, /* */ pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const { - string SourcesURI = URItoFileName(IndexURI("Sources")); - return new debSrcRecordParser(_config->FindDir("Dir::State::lists") + - SourcesURI,this); + string SourcesURI = _config->FindDir("Dir::State::lists") + + URItoFileName(IndexURI("Sources")); + string SourcesURIgzip = SourcesURI + ".gz"; + + if (!FileExists(SourcesURI) && !FileExists(SourcesURIgzip)) + return NULL; + else if (!FileExists(SourcesURI) && FileExists(SourcesURIgzip)) + SourcesURI = SourcesURIgzip; + + return new debSrcRecordParser(SourcesURI,this); } /*}}}*/ // SourcesIndex::Describe - Give a descriptive path to the index /*{{{*/ @@ -92,7 +110,7 @@ string debSourcesIndex::Describe(bool Short) const /* */ string debSourcesIndex::Info(const char *Type) const { - string Info = ::URI::SiteOnly(URI) + ' '; + string Info = ::URI::NoUserPassword(URI) + ' '; if (Dist[Dist.size() - 1] == '/') { if (Dist != "/") @@ -110,8 +128,14 @@ string debSourcesIndex::Info(const char *Type) const /* */ inline string debSourcesIndex::IndexFile(const char *Type) const { - return URItoFileName(IndexURI(Type)); + string s = URItoFileName(IndexURI(Type)); + string sgzip = s + ".gz"; + if (!FileExists(s) && FileExists(sgzip)) + return sgzip; + else + return s; } + string debSourcesIndex::IndexURI(const char *Type) const { string Res; @@ -143,19 +167,32 @@ bool debSourcesIndex::Exists() const /* */ unsigned long debSourcesIndex::Size() const { - struct stat S; - if (stat(IndexFile("Sources").c_str(),&S) != 0) - return 0; - return S.st_size; + unsigned long size = 0; + + /* we need to ignore errors here; if the lists are absent, just return 0 */ + _error->PushToStack(); + + FileFd f(IndexFile("Sources"), FileFd::ReadOnly, FileFd::Extension); + if (!f.Failed()) + size = f.Size(); + + if (_error->PendingError() == true) + size = 0; + _error->RevertToStack(); + + return size; } /*}}}*/ // PackagesIndex::debPackagesIndex - Contructor /*{{{*/ // --------------------------------------------------------------------- /* */ -debPackagesIndex::debPackagesIndex(string URI,string Dist,string Section,bool Trusted) : - pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section) +debPackagesIndex::debPackagesIndex(string const &URI, string const &Dist, string const &Section, + bool const &Trusted, string const &Arch) : + pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section), Architecture(Arch) { + if (Architecture == "native") + Architecture = _config->Find("APT::Architecture"); } /*}}}*/ // PackagesIndex::ArchiveInfo - Short version of the archive url /*{{{*/ @@ -163,7 +200,7 @@ debPackagesIndex::debPackagesIndex(string URI,string Dist,string Section,bool Tr /* This is a shorter version that is designed to be < 60 chars or so */ string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const { - string Res = ::URI::SiteOnly(URI) + ' '; + string Res = ::URI::NoUserPassword(URI) + ' '; if (Dist[Dist.size() - 1] == '/') { if (Dist != "/") @@ -175,6 +212,8 @@ string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const Res += " "; Res += Ver.ParentPkg().Name(); Res += " "; + if (Dist[Dist.size() - 1] != '/') + Res.append(Ver.Arch()).append(" "); Res += Ver.VerStr(); return Res; } @@ -199,7 +238,7 @@ string debPackagesIndex::Describe(bool Short) const /* */ string debPackagesIndex::Info(const char *Type) const { - string Info = ::URI::SiteOnly(URI) + ' '; + string Info = ::URI::NoUserPassword(URI) + ' '; if (Dist[Dist.size() - 1] == '/') { if (Dist != "/") @@ -208,6 +247,8 @@ string debPackagesIndex::Info(const char *Type) const else Info += Dist + '/' + Section; Info += " "; + if (Dist[Dist.size() - 1] != '/') + Info += Architecture + " "; Info += Type; return Info; } @@ -217,7 +258,12 @@ string debPackagesIndex::Info(const char *Type) const /* */ inline string debPackagesIndex::IndexFile(const char *Type) const { - return _config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type)); + string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type)); + string sgzip = s + ".gz"; + if (!FileExists(s) && FileExists(sgzip)) + return sgzip; + else + return s; } string debPackagesIndex::IndexURI(const char *Type) const { @@ -231,7 +277,7 @@ string debPackagesIndex::IndexURI(const char *Type) const } else Res = URI + "dists/" + Dist + '/' + Section + - "/binary-" + _config->Find("APT::Architecture") + '/'; + "/binary-" + Architecture + '/'; Res += Type; return Res; @@ -250,44 +296,64 @@ bool debPackagesIndex::Exists() const /* This is really only used for progress reporting. */ unsigned long debPackagesIndex::Size() const { - struct stat S; - if (stat(IndexFile("Packages").c_str(),&S) != 0) - return 0; - return S.st_size; + unsigned long size = 0; + + /* we need to ignore errors here; if the lists are absent, just return 0 */ + _error->PushToStack(); + + FileFd f(IndexFile("Packages"), FileFd::ReadOnly, FileFd::Extension); + if (!f.Failed()) + size = f.Size(); + + if (_error->PendingError() == true) + size = 0; + _error->RevertToStack(); + + return size; } /*}}}*/ // PackagesIndex::Merge - Load the index file into a cache /*{{{*/ // --------------------------------------------------------------------- /* */ -bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const +bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const { string PackageFile = IndexFile("Packages"); - FileFd Pkg(PackageFile,FileFd::ReadOnly); - debListParser Parser(&Pkg); + FileFd Pkg(PackageFile,FileFd::ReadOnly, FileFd::Extension); + debListParser Parser(&Pkg, Architecture); + if (_error->PendingError() == true) return _error->Error("Problem opening %s",PackageFile.c_str()); - - Prog.SubProgress(0,Info("Packages")); + if (Prog != NULL) + Prog->SubProgress(0,Info("Packages")); ::URI Tmp(URI); if (Gen.SelectFile(PackageFile,Tmp.Host,*this) == false) return _error->Error("Problem with SelectFile %s",PackageFile.c_str()); // Store the IMS information pkgCache::PkgFileIterator File = Gen.GetCurFile(); - struct stat St; - if (fstat(Pkg.Fd(),&St) != 0) - return _error->Errno("fstat","Failed to stat"); - File->Size = St.st_size; - File->mtime = St.st_mtime; + pkgCacheGenerator::Dynamic DynFile(File); + File->Size = Pkg.FileSize(); + File->mtime = Pkg.ModificationTime(); if (Gen.MergeList(Parser) == false) return _error->Error("Problem with MergeList %s",PackageFile.c_str()); // Check the release file - string ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("Release"); + string ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("InRelease"); + bool releaseExists = false; if (FileExists(ReleaseFile) == true) + releaseExists = true; + else + ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("Release"); + + if (releaseExists == true || FileExists(ReleaseFile) == true) { - FileFd Rel(ReleaseFile,FileFd::ReadOnly); + FileFd Rel; + // Beware: The 'Release' file might be clearsigned in case the + // signature for an 'InRelease' file couldn't be checked + if (OpenMaybeClearSignedFile(ReleaseFile, Rel) == false) + return false; + if (_error->PendingError() == true) return false; Parser.LoadReleaseInfo(File,Rel,Section); @@ -303,16 +369,26 @@ pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const { string FileName = IndexFile("Packages"); pkgCache::PkgFileIterator File = Cache.FileBegin(); - for (; File.end() == false; File++) + for (; File.end() == false; ++File) { if (File.FileName() == NULL || FileName != File.FileName()) continue; struct stat St; if (stat(File.FileName(),&St) != 0) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "PackagesIndex::FindInCache - stat failed on " << File.FileName() << std::endl; return pkgCache::PkgFileIterator(Cache); + } if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "PackagesIndex::FindInCache - size (" << St.st_size << " <> " << File->Size + << ") or mtime (" << St.st_mtime << " <> " << File->mtime + << ") doesn't match for " << File.FileName() << std::endl; return pkgCache::PkgFileIterator(Cache); + } return File; } @@ -323,17 +399,23 @@ pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const // TranslationsIndex::debTranslationsIndex - Contructor /*{{{*/ // --------------------------------------------------------------------- /* */ -debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section) : - pkgIndexFile(true), URI(URI), Dist(Dist), Section(Section) -{ -} +debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section, + char const * const Translation) : + pkgIndexFile(true), URI(URI), Dist(Dist), Section(Section), + Language(Translation) +{} /*}}}*/ // TranslationIndex::Trans* - Return the URI to the translation files /*{{{*/ // --------------------------------------------------------------------- /* */ inline string debTranslationsIndex::IndexFile(const char *Type) const { - return _config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type)); + string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type)); + string sgzip = s + ".gz"; + if (!FileExists(s) && FileExists(sgzip)) + return sgzip; + else + return s; } string debTranslationsIndex::IndexURI(const char *Type) const { @@ -358,12 +440,10 @@ string debTranslationsIndex::IndexURI(const char *Type) const /* */ bool debTranslationsIndex::GetIndexes(pkgAcquire *Owner) const { - if (TranslationsAvailable()) { - string TranslationFile = "Translation-" + LanguageCode(); - new pkgAcqIndexTrans(Owner, IndexURI(LanguageCode().c_str()), - Info(TranslationFile.c_str()), - TranslationFile); - } + string const TranslationFile = string("Translation-").append(Language); + new pkgAcqIndexTrans(Owner, IndexURI(Language), + Info(TranslationFile.c_str()), + TranslationFile); return true; } @@ -379,7 +459,7 @@ string debTranslationsIndex::Describe(bool Short) const snprintf(S,sizeof(S),"%s",Info(TranslationFile().c_str()).c_str()); else snprintf(S,sizeof(S),"%s (%s)",Info(TranslationFile().c_str()).c_str(), - IndexFile(LanguageCode().c_str()).c_str()); + IndexFile(Language).c_str()); return S; } /*}}}*/ @@ -388,7 +468,7 @@ string debTranslationsIndex::Describe(bool Short) const /* */ string debTranslationsIndex::Info(const char *Type) const { - string Info = ::URI::SiteOnly(URI) + ' '; + string Info = ::URI::NoUserPassword(URI) + ' '; if (Dist[Dist.size() - 1] == '/') { if (Dist != "/") @@ -401,20 +481,17 @@ string debTranslationsIndex::Info(const char *Type) const return Info; } /*}}}*/ -bool debTranslationsIndex::HasPackages() const +bool debTranslationsIndex::HasPackages() const /*{{{*/ { - if(!TranslationsAvailable()) - return false; - - return FileExists(IndexFile(LanguageCode().c_str())); + return FileExists(IndexFile(Language)); } - + /*}}}*/ // TranslationsIndex::Exists - Check if the index is available /*{{{*/ // --------------------------------------------------------------------- /* */ bool debTranslationsIndex::Exists() const { - return FileExists(IndexFile(LanguageCode().c_str())); + return FileExists(IndexFile(Language)); } /*}}}*/ // TranslationsIndex::Size - Return the size of the index /*{{{*/ @@ -422,37 +499,45 @@ bool debTranslationsIndex::Exists() const /* This is really only used for progress reporting. */ unsigned long debTranslationsIndex::Size() const { - struct stat S; - if (stat(IndexFile(LanguageCode().c_str()).c_str(),&S) != 0) - return 0; - return S.st_size; + unsigned long size = 0; + + /* we need to ignore errors here; if the lists are absent, just return 0 */ + _error->PushToStack(); + + FileFd f(IndexFile(Language), FileFd::ReadOnly, FileFd::Extension); + if (!f.Failed()) + size = f.Size(); + + if (_error->PendingError() == true) + size = 0; + _error->RevertToStack(); + + return size; } /*}}}*/ // TranslationsIndex::Merge - Load the index file into a cache /*{{{*/ // --------------------------------------------------------------------- /* */ -bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const +bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const { // Check the translation file, if in use - string TranslationFile = IndexFile(LanguageCode().c_str()); - if (TranslationsAvailable() && FileExists(TranslationFile)) + string TranslationFile = IndexFile(Language); + if (FileExists(TranslationFile)) { - FileFd Trans(TranslationFile,FileFd::ReadOnly); + FileFd Trans(TranslationFile,FileFd::ReadOnly, FileFd::Extension); debListParser TransParser(&Trans); if (_error->PendingError() == true) return false; - Prog.SubProgress(0, Info(TranslationFile.c_str())); + if (Prog != NULL) + Prog->SubProgress(0, Info(TranslationFile.c_str())); if (Gen.SelectFile(TranslationFile,string(),*this) == false) return _error->Error("Problem with SelectFile %s",TranslationFile.c_str()); // Store the IMS information pkgCache::PkgFileIterator TransFile = Gen.GetCurFile(); - struct stat TransSt; - if (fstat(Trans.Fd(),&TransSt) != 0) - return _error->Errno("fstat","Failed to stat"); - TransFile->Size = TransSt.st_size; - TransFile->mtime = TransSt.st_mtime; + TransFile->Size = Trans.FileSize(); + TransFile->mtime = Trans.ModificationTime(); if (Gen.MergeList(TransParser) == false) return _error->Error("Problem with MergeList %s",TranslationFile.c_str()); @@ -466,19 +551,29 @@ bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const /* */ pkgCache::PkgFileIterator debTranslationsIndex::FindInCache(pkgCache &Cache) const { - string FileName = IndexFile(LanguageCode().c_str()); + string FileName = IndexFile(Language); pkgCache::PkgFileIterator File = Cache.FileBegin(); - for (; File.end() == false; File++) + for (; File.end() == false; ++File) { if (FileName != File.FileName()) continue; struct stat St; if (stat(File.FileName(),&St) != 0) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "TranslationIndex::FindInCache - stat failed on " << File.FileName() << std::endl; return pkgCache::PkgFileIterator(Cache); + } if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "TranslationIndex::FindInCache - size (" << St.st_size << " <> " << File->Size + << ") or mtime (" << St.st_mtime << " <> " << File->mtime + << ") doesn't match for " << File.FileName() << std::endl; return pkgCache::PkgFileIterator(Cache); + } return File; } return File; @@ -505,27 +600,26 @@ unsigned long debStatusIndex::Size() const // StatusIndex::Merge - Load the index file into a cache /*{{{*/ // --------------------------------------------------------------------- /* */ -bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const +bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const { - FileFd Pkg(File,FileFd::ReadOnly); + FileFd Pkg(File,FileFd::ReadOnly, FileFd::Extension); if (_error->PendingError() == true) return false; debListParser Parser(&Pkg); if (_error->PendingError() == true) return false; - - Prog.SubProgress(0,File); + + if (Prog != NULL) + Prog->SubProgress(0,File); if (Gen.SelectFile(File,string(),*this,pkgCache::Flag::NotSource) == false) return _error->Error("Problem with SelectFile %s",File.c_str()); // Store the IMS information pkgCache::PkgFileIterator CFile = Gen.GetCurFile(); - struct stat St; - if (fstat(Pkg.Fd(),&St) != 0) - return _error->Errno("fstat","Failed to stat"); - CFile->Size = St.st_size; - CFile->mtime = St.st_mtime; - CFile->Archive = Gen.WriteUniqString("now"); + CFile->Size = Pkg.FileSize(); + CFile->mtime = Pkg.ModificationTime(); + map_ptrloc const storage = Gen.WriteUniqString("now"); + CFile->Archive = storage; if (Gen.MergeList(Parser) == false) return _error->Error("Problem with MergeList %s",File.c_str()); @@ -538,16 +632,26 @@ bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const pkgCache::PkgFileIterator debStatusIndex::FindInCache(pkgCache &Cache) const { pkgCache::PkgFileIterator File = Cache.FileBegin(); - for (; File.end() == false; File++) + for (; File.end() == false; ++File) { if (this->File != File.FileName()) continue; struct stat St; if (stat(File.FileName(),&St) != 0) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "StatusIndex::FindInCache - stat failed on " << File.FileName() << std::endl; return pkgCache::PkgFileIterator(Cache); + } if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "StatusIndex::FindInCache - size (" << St.st_size << " <> " << File->Size + << ") or mtime (" << St.st_mtime << " <> " << File->mtime + << ") doesn't match for " << File.FileName() << std::endl; return pkgCache::PkgFileIterator(Cache); + } return File; } return File; @@ -556,7 +660,7 @@ pkgCache::PkgFileIterator debStatusIndex::FindInCache(pkgCache &Cache) const // StatusIndex::Exists - Check if the index is available /*{{{*/ // --------------------------------------------------------------------- /* */ -bool debStatusIndex::Exists() const +APT_CONST bool debStatusIndex::Exists() const { // Abort if the file does not exist. return true;