diff options
Diffstat (limited to 'apt-pkg/deb')
-rw-r--r-- | apt-pkg/deb/debindexfile.cc | 525 | ||||
-rw-r--r-- | apt-pkg/deb/debindexfile.h | 103 | ||||
-rw-r--r-- | apt-pkg/deb/deblistparser.cc | 49 | ||||
-rw-r--r-- | apt-pkg/deb/deblistparser.h | 26 | ||||
-rw-r--r-- | apt-pkg/deb/debmetaindex.cc | 602 | ||||
-rw-r--r-- | apt-pkg/deb/debmetaindex.h | 31 | ||||
-rw-r--r-- | apt-pkg/deb/debrecords.cc | 115 | ||||
-rw-r--r-- | apt-pkg/deb/debrecords.h | 50 | ||||
-rw-r--r-- | apt-pkg/deb/debsrcrecords.cc | 58 | ||||
-rw-r--r-- | apt-pkg/deb/debsrcrecords.h | 9 | ||||
-rw-r--r-- | apt-pkg/deb/debsystem.cc | 2 | ||||
-rw-r--r-- | apt-pkg/deb/debversion.h | 1 | ||||
-rw-r--r-- | apt-pkg/deb/dpkgpm.cc | 170 |
13 files changed, 736 insertions, 1005 deletions
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index 335f9d36e..0fffa52b0 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -34,6 +34,7 @@ #include <stdio.h> #include <iostream> +#include <sstream> #include <string> #include <sys/stat.h> /*}}}*/ @@ -43,8 +44,8 @@ using std::string; // SourcesIndex::debSourcesIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -debSourcesIndex::debSourcesIndex(string URI,string Dist,string Section,bool Trusted) : - pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section) +debSourcesIndex::debSourcesIndex(IndexTarget const &Target,bool const Trusted) : + pkgIndexTargetFile(Target, Trusted) { } /*}}}*/ @@ -55,16 +56,9 @@ debSourcesIndex::debSourcesIndex(string URI,string Dist,string Section,bool Trus string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record, pkgSrcRecords::File const &File) const { - string Res; - Res = ::URI::NoUserPassword(URI) + ' '; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Res += Dist; - } - else - Res += Dist + '/' + Section; - + string Res = Target.Description; + Res.erase(Target.Description.rfind(' ')); + Res += " "; Res += Record.Package(); Res += " "; @@ -79,129 +73,19 @@ string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record, /* */ pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const { - string SourcesURI = _config->FindDir("Dir::State::lists") + - URItoFileName(IndexURI("Sources")); - - std::vector<std::string> types = APT::Configuration::getCompressionTypes(); - for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t) - { - string p; - p = SourcesURI + '.' + *t; - if (FileExists(p)) - return new debSrcRecordParser(p, this); - } + string const SourcesURI = IndexFileName(); if (FileExists(SourcesURI)) return new debSrcRecordParser(SourcesURI, this); return NULL; } /*}}}*/ -// SourcesIndex::Describe - Give a descriptive path to the index /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debSourcesIndex::Describe(bool Short) const -{ - char S[300]; - if (Short == true) - snprintf(S,sizeof(S),"%s",Info("Sources").c_str()); - else - snprintf(S,sizeof(S),"%s (%s)",Info("Sources").c_str(), - IndexFile("Sources").c_str()); - - return S; -} - /*}}}*/ -// SourcesIndex::Info - One liner describing the index URI /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debSourcesIndex::Info(const char *Type) const -{ - string Info = ::URI::NoUserPassword(URI) + ' '; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Info += Dist; - } - else - Info += Dist + '/' + Section; - Info += " "; - Info += Type; - return Info; -} - /*}}}*/ -// SourcesIndex::Index* - Return the URI to the index files /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debSourcesIndex::IndexFile(const char *Type) const -{ - string s = URItoFileName(IndexURI(Type)); - - std::vector<std::string> types = APT::Configuration::getCompressionTypes(); - for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t) - { - string p = s + '.' + *t; - if (FileExists(p)) - return p; - } - return s; -} - -string debSourcesIndex::IndexURI(const char *Type) const -{ - string Res; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Res = URI + Dist; - else - Res = URI; - } - else - Res = URI + "dists/" + Dist + '/' + Section + - "/source/"; - - Res += Type; - return Res; -} - /*}}}*/ -// SourcesIndex::Exists - Check if the index is available /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool debSourcesIndex::Exists() const -{ - return FileExists(IndexFile("Sources")); -} - /*}}}*/ -// SourcesIndex::Size - Return the size of the index /*{{{*/ -// --------------------------------------------------------------------- -/* */ -unsigned long debSourcesIndex::Size() const -{ - 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 const &URI, string const &Dist, string const &Section, - bool const &Trusted, string const &Arch) : - pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section), Architecture(Arch) +debPackagesIndex::debPackagesIndex(IndexTarget const &Target, bool const Trusted) : + pkgIndexTargetFile(Target, Trusted) { - if (Architecture == "native") - Architecture = _config->Find("APT::Architecture"); } /*}}}*/ // PackagesIndex::ArchiveInfo - Short version of the archive url /*{{{*/ @@ -209,137 +93,42 @@ debPackagesIndex::debPackagesIndex(string const &URI, string const &Dist, string /* This is a shorter version that is designed to be < 60 chars or so */ string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const { - string Res = ::URI::NoUserPassword(URI) + ' '; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Res += Dist; - } - else - Res += Dist + '/' + Section; - + std::string const Dist = Target.Option(IndexTarget::RELEASE); + string Res = Target.Option(IndexTarget::SITE) + " " + Dist; + std::string const Component = Target.Option(IndexTarget::COMPONENT); + if (Component.empty() == false) + Res += "/" + Component; + Res += " "; Res += Ver.ParentPkg().Name(); Res += " "; - if (Dist[Dist.size() - 1] != '/') + if (Dist.empty() == false && Dist[Dist.size() - 1] != '/') Res.append(Ver.Arch()).append(" "); Res += Ver.VerStr(); return Res; } /*}}}*/ -// PackagesIndex::Describe - Give a descriptive path to the index /*{{{*/ -// --------------------------------------------------------------------- -/* This should help the user find the index in the sources.list and - in the filesystem for problem solving */ -string debPackagesIndex::Describe(bool Short) const -{ - char S[300]; - if (Short == true) - snprintf(S,sizeof(S),"%s",Info("Packages").c_str()); - else - snprintf(S,sizeof(S),"%s (%s)",Info("Packages").c_str(), - IndexFile("Packages").c_str()); - return S; -} - /*}}}*/ -// PackagesIndex::Info - One liner describing the index URI /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debPackagesIndex::Info(const char *Type) const -{ - string Info = ::URI::NoUserPassword(URI) + ' '; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Info += Dist; - } - else - Info += Dist + '/' + Section; - Info += " "; - if (Dist[Dist.size() - 1] != '/') - Info += Architecture + " "; - Info += Type; - return Info; -} - /*}}}*/ -// PackagesIndex::Index* - Return the URI to the index files /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debPackagesIndex::IndexFile(const char *Type) const -{ - string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type)); - - std::vector<std::string> types = APT::Configuration::getCompressionTypes(); - for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t) - { - string p = s + '.' + *t; - if (FileExists(p)) - return p; - } - return s; -} -string debPackagesIndex::IndexURI(const char *Type) const -{ - string Res; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Res = URI + Dist; - else - Res = URI; - } - else - Res = URI + "dists/" + Dist + '/' + Section + - "/binary-" + Architecture + '/'; - - Res += Type; - return Res; -} - /*}}}*/ -// PackagesIndex::Exists - Check if the index is available /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool debPackagesIndex::Exists() const -{ - return FileExists(IndexFile("Packages")); -} - /*}}}*/ -// PackagesIndex::Size - Return the size of the index /*{{{*/ -// --------------------------------------------------------------------- -/* This is really only used for progress reporting. */ -unsigned long debPackagesIndex::Size() const -{ - 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 { - string PackageFile = IndexFile("Packages"); + string const PackageFile = IndexFileName(); FileFd Pkg(PackageFile,FileFd::ReadOnly, FileFd::Extension); - debListParser Parser(&Pkg, Architecture); + debListParser Parser(&Pkg, Target.Option(IndexTarget::ARCHITECTURE)); if (_error->PendingError() == true) return _error->Error("Problem opening %s",PackageFile.c_str()); if (Prog != NULL) - Prog->SubProgress(0,Info("Packages")); + Prog->SubProgress(0, Target.Description); + + + std::string const URI = Target.Option(IndexTarget::REPO_URI); + std::string Dist = Target.Option(IndexTarget::RELEASE); + if (Dist.empty()) + Dist = "/"; ::URI Tmp(URI); - if (Gen.SelectFile(PackageFile,Tmp.Host,*this) == false) + if (Gen.SelectFile(PackageFile, *this, Target.Option(IndexTarget::ARCHITECTURE), Target.Option(IndexTarget::COMPONENT)) == false) return _error->Error("Problem with SelectFile %s",PackageFile.c_str()); // Store the IMS information @@ -347,31 +136,10 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> 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("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; - // 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); - } - return true; } /*}}}*/ @@ -380,7 +148,7 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const /* */ pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const { - string FileName = IndexFile("Packages"); + string const FileName = IndexFileName(); pkgCache::PkgFileIterator File = Cache.FileBegin(); for (; File.end() == false; ++File) { @@ -410,113 +178,13 @@ pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const /*}}}*/ // TranslationsIndex::debTranslationsIndex - Contructor /*{{{*/ -// --------------------------------------------------------------------- -/* */ -debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section, - char const * const Translation) : - pkgIndexFile(true), URI(URI), Dist(Dist), Section(Section), - Language(Translation) +debTranslationsIndex::debTranslationsIndex(IndexTarget const &Target) : + pkgIndexTargetFile(Target, true) {} /*}}}*/ -// TranslationIndex::Trans* - Return the URI to the translation files /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debTranslationsIndex::IndexFile(const char *Type) const -{ - string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type)); - - std::vector<std::string> types = APT::Configuration::getCompressionTypes(); - for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t) - { - string p = s + '.' + *t; - if (FileExists(p)) - return p; - } - return s; -} -string debTranslationsIndex::IndexURI(const char *Type) const -{ - string Res; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Res = URI + Dist; - else - Res = URI; - } - else - Res = URI + "dists/" + Dist + '/' + Section + - "/i18n/Translation-"; - - Res += Type; - return Res; -} - /*}}}*/ -// TranslationsIndex::Describe - Give a descriptive path to the index /*{{{*/ -// --------------------------------------------------------------------- -/* This should help the user find the index in the sources.list and - in the filesystem for problem solving */ -string debTranslationsIndex::Describe(bool Short) const -{ - char S[300]; - if (Short == true) - 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(Language).c_str()); - return S; -} - /*}}}*/ -// TranslationsIndex::Info - One liner describing the index URI /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debTranslationsIndex::Info(const char *Type) const -{ - string Info = ::URI::NoUserPassword(URI) + ' '; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Info += Dist; - } - else - Info += Dist + '/' + Section; - Info += " "; - Info += Type; - return Info; -} - /*}}}*/ bool debTranslationsIndex::HasPackages() const /*{{{*/ { - return FileExists(IndexFile(Language)); -} - /*}}}*/ -// TranslationsIndex::Exists - Check if the index is available /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool debTranslationsIndex::Exists() const -{ - return FileExists(IndexFile(Language)); -} - /*}}}*/ -// TranslationsIndex::Size - Return the size of the index /*{{{*/ -// --------------------------------------------------------------------- -/* This is really only used for progress reporting. */ -unsigned long debTranslationsIndex::Size() const -{ - 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; + return Exists(); } /*}}}*/ // TranslationsIndex::Merge - Load the index file into a cache /*{{{*/ @@ -525,24 +193,24 @@ unsigned long debTranslationsIndex::Size() const bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const { // Check the translation file, if in use - string TranslationFile = IndexFile(Language); + string const TranslationFile = IndexFileName(); if (FileExists(TranslationFile)) { FileFd Trans(TranslationFile,FileFd::ReadOnly, FileFd::Extension); debTranslationsParser TransParser(&Trans); if (_error->PendingError() == true) return false; - + if (Prog != NULL) - Prog->SubProgress(0, Info(TranslationFile.c_str())); - if (Gen.SelectFile(TranslationFile,string(),*this) == false) + Prog->SubProgress(0, Target.Description); + if (Gen.SelectFile(TranslationFile, *this, "", Target.Option(IndexTarget::COMPONENT), pkgCache::Flag::NotSource | pkgCache::Flag::NoPackages) == false) return _error->Error("Problem with SelectFile %s",TranslationFile.c_str()); // Store the IMS information pkgCache::PkgFileIterator TransFile = Gen.GetCurFile(); TransFile->Size = Trans.FileSize(); TransFile->mtime = Trans.ModificationTime(); - + if (Gen.MergeList(TransParser) == false) return _error->Error("Problem with MergeList %s",TranslationFile.c_str()); } @@ -555,8 +223,8 @@ bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const /* */ pkgCache::PkgFileIterator debTranslationsIndex::FindInCache(pkgCache &Cache) const { - string FileName = IndexFile(Language); - + string FileName = IndexFileName(); + pkgCache::PkgFileIterator File = Cache.FileBegin(); for (; File.end() == false; ++File) { @@ -579,10 +247,11 @@ pkgCache::PkgFileIterator debTranslationsIndex::FindInCache(pkgCache &Cache) con return pkgCache::PkgFileIterator(Cache); } return File; - } + } return File; } /*}}}*/ + // StatusIndex::debStatusIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -615,18 +284,17 @@ bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const if (Prog != NULL) Prog->SubProgress(0,File); - if (Gen.SelectFile(File,string(),*this,pkgCache::Flag::NotSource) == false) + if (Gen.SelectFile(File, *this, "", "now", pkgCache::Flag::NotSource) == false) return _error->Error("Problem with SelectFile %s",File.c_str()); // Store the IMS information pkgCache::PkgFileIterator CFile = Gen.GetCurFile(); + pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(CFile); CFile->Size = Pkg.FileSize(); CFile->mtime = Pkg.ModificationTime(); - map_stringitem_t const storage = Gen.StoreString(pkgCacheGenerator::MIXED, "now"); - CFile->Archive = storage; - + if (Gen.MergeList(Parser) == false) - return _error->Error("Problem with MergeList %s",File.c_str()); + return _error->Error("Problem with MergeList %s",File.c_str()); return true; } /*}}}*/ @@ -671,8 +339,7 @@ APT_CONST bool debStatusIndex::Exists() const } /*}}}*/ -// debDebPkgFile - Single .deb file /*{{{*/ -// --------------------------------------------------------------------- +// debDebPkgFile - Single .deb file /*{{{*/ debDebPkgFileIndex::debDebPkgFileIndex(std::string DebFile) : pkgIndexFile(true), DebFile(DebFile) { @@ -688,64 +355,67 @@ bool debDebPkgFileIndex::Exists() const { return FileExists(DebFile); } -bool debDebPkgFileIndex::Merge(pkgCacheGenerator& Gen, OpProgress* Prog) const +bool debDebPkgFileIndex::GetContent(std::ostream &content, std::string const &debfile) { - if(Prog) - Prog->SubProgress(0, "Reading deb file"); - - // get the control data out of the deb file vid dpkg -I - // ... can I haz libdpkg? - Configuration::Item const *Opts = _config->Tree("DPkg::Options"); - std::string dpkg = _config->Find("Dir::Bin::dpkg","dpkg"); + // get the control data out of the deb file via dpkg-deb -I + std::string dpkg = _config->Find("Dir::Bin::dpkg","dpkg-deb"); std::vector<const char *> Args; Args.push_back(dpkg.c_str()); - if (Opts != 0) - { - Opts = Opts->Child; - for (; Opts != 0; Opts = Opts->Next) - { - if (Opts->Value.empty() == true) - continue; - Args.push_back(Opts->Value.c_str()); - } - } Args.push_back("-I"); - Args.push_back(DebFile.c_str()); + Args.push_back(debfile.c_str()); Args.push_back("control"); Args.push_back(NULL); FileFd PipeFd; pid_t Child; if(Popen((const char**)&Args[0], PipeFd, Child, FileFd::ReadOnly) == false) return _error->Error("Popen failed"); - // FIXME: static buffer - char buf[8*1024]; - unsigned long long n = 0; - if(PipeFd.Read(buf, sizeof(buf)-1, &n) == false) - return _error->Errno("read", "Failed to read dpkg pipe"); + + char buffer[1024]; + do { + unsigned long long actual = 0; + if (PipeFd.Read(buffer, sizeof(buffer)-1, &actual) == false) + return _error->Errno("read", "Failed to read dpkg pipe"); + if (actual == 0) + break; + buffer[actual] = '\0'; + content << buffer; + } while(true); ExecWait(Child, "Popen"); - // now write the control data to a tempfile + content << "Filename: " << debfile << "\n"; + struct stat Buf; + if (stat(debfile.c_str(), &Buf) != 0) + return false; + content << "Size: " << Buf.st_size << "\n"; + + return true; +} +bool debDebPkgFileIndex::Merge(pkgCacheGenerator& Gen, OpProgress* Prog) const +{ + if(Prog) + Prog->SubProgress(0, "Reading deb file"); + + // write the control data to a tempfile SPtr<FileFd> DebControl = GetTempFile("deb-file-" + flNotDir(DebFile)); if(DebControl == NULL) return false; - DebControl->Write(buf, n); - // append size of the file - FileFd Fd(DebFile, FileFd::ReadOnly); - string Size; - strprintf(Size, "Size: %llu\n", Fd.Size()); - DebControl->Write(Size.c_str(), Size.size()); - // and rewind for the listparser + std::ostringstream content; + if (GetContent(content, DebFile) == false) + return false; + std::string const contentstr = content.str(); + DebControl->Write(contentstr.c_str(), contentstr.length()); + // rewind for the listparser DebControl->Seek(0); // and give it to the list parser debDebFileParser Parser(DebControl, DebFile); - if(Gen.SelectFile(DebFile, "local", *this) == false) + if(Gen.SelectFile(DebFile, *this, "", "now", pkgCache::Flag::LocalSource) == false) return _error->Error("Problem with SelectFile %s", DebFile.c_str()); pkgCache::PkgFileIterator File = Gen.GetCurFile(); File->Size = DebControl->Size(); File->mtime = DebControl->ModificationTime(); - + if (Gen.MergeList(Parser) == false) return _error->Error("Problem with MergeLister for %s", DebFile.c_str()); @@ -802,13 +472,13 @@ pkgSrcRecords::Parser *debDscFileIndex::CreateSrcParser() const } /*}}}*/ // Index File types for Debian /*{{{*/ -class debIFTypeSrc : public pkgIndexFile::Type +class APT_HIDDEN debIFTypeSrc : public pkgIndexFile::Type { public: debIFTypeSrc() {Label = "Debian Source Index";}; }; -class debIFTypePkg : public pkgIndexFile::Type +class APT_HIDDEN debIFTypePkg : public pkgIndexFile::Type { public: @@ -818,12 +488,12 @@ class debIFTypePkg : public pkgIndexFile::Type }; debIFTypePkg() {Label = "Debian Package Index";}; }; -class debIFTypeTrans : public debIFTypePkg +class APT_HIDDEN debIFTypeTrans : public debIFTypePkg { public: debIFTypeTrans() {Label = "Debian Translation Index";}; }; -class debIFTypeStatus : public pkgIndexFile::Type +class APT_HIDDEN debIFTypeStatus : public pkgIndexFile::Type { public: @@ -833,16 +503,16 @@ class debIFTypeStatus : public pkgIndexFile::Type }; debIFTypeStatus() {Label = "Debian dpkg status file";}; }; -class debIFTypeDebPkgFile : public pkgIndexFile::Type +class APT_HIDDEN debIFTypeDebPkgFile : public pkgIndexFile::Type { public: virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const { - return new debDebFileRecordParser(File.FileName(),*File.Cache()); + return new debDebFileRecordParser(File.FileName()); }; debIFTypeDebPkgFile() {Label = "deb Package file";}; }; -class debIFTypeDscFile : public pkgIndexFile::Type +class APT_HIDDEN debIFTypeDscFile : public pkgIndexFile::Type { public: virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string DscFile) const @@ -851,7 +521,7 @@ class debIFTypeDscFile : public pkgIndexFile::Type }; debIFTypeDscFile() {Label = "dsc File Source Index";}; }; -class debIFTypeDebianSourceDir : public pkgIndexFile::Type +class APT_HIDDEN debIFTypeDebianSourceDir : public pkgIndexFile::Type { public: virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string SourceDir) const @@ -861,14 +531,14 @@ class debIFTypeDebianSourceDir : public pkgIndexFile::Type debIFTypeDebianSourceDir() {Label = "debian/control File Source Index";}; }; -static debIFTypeSrc _apt_Src; -static debIFTypePkg _apt_Pkg; -static debIFTypeTrans _apt_Trans; -static debIFTypeStatus _apt_Status; -static debIFTypeDebPkgFile _apt_DebPkgFile; +APT_HIDDEN debIFTypeSrc _apt_Src; +APT_HIDDEN debIFTypePkg _apt_Pkg; +APT_HIDDEN debIFTypeTrans _apt_Trans; +APT_HIDDEN debIFTypeStatus _apt_Status; +APT_HIDDEN debIFTypeDebPkgFile _apt_DebPkgFile; // file based pseudo indexes -static debIFTypeDscFile _apt_DscFile; -static debIFTypeDebianSourceDir _apt_DebianSourceDir; +APT_HIDDEN debIFTypeDscFile _apt_DscFile; +APT_HIDDEN debIFTypeDebianSourceDir _apt_DebianSourceDir; const pkgIndexFile::Type *debSourcesIndex::GetType() const { @@ -906,3 +576,4 @@ debTranslationsIndex::~debTranslationsIndex() {} debSourcesIndex::~debSourcesIndex() {} debDebPkgFileIndex::~debDebPkgFileIndex() {} +debDscFileIndex::~debDscFileIndex() {} diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h index d727d9547..6285a9e5c 100644 --- a/apt-pkg/deb/debindexfile.h +++ b/apt-pkg/deb/debindexfile.h @@ -1,6 +1,5 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: debindexfile.h,v 1.3.2.1 2003/12/24 23:09:17 mdz Exp $ /* ###################################################################### Debian Index Files @@ -28,117 +27,68 @@ class pkgAcquire; class pkgCacheGenerator; -class debStatusIndex : public pkgIndexFile +class APT_HIDDEN debStatusIndex : public pkgIndexFile { - /** \brief dpointer placeholder (for later in case we need it) */ void *d; - protected: std::string File; public: virtual const Type *GetType() const APT_CONST; - + // Interface for acquire virtual std::string Describe(bool /*Short*/) const {return File;}; - + // Interface for the Cache Generator virtual bool Exists() const; virtual bool HasPackages() const {return true;}; virtual unsigned long Size() const; virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; - bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog, unsigned long const Flag) const; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; debStatusIndex(std::string File); virtual ~debStatusIndex(); }; - -class debPackagesIndex : public pkgIndexFile + +class APT_HIDDEN debPackagesIndex : public pkgIndexTargetFile { - /** \brief dpointer placeholder (for later in case we need it) */ void *d; - - std::string URI; - std::string Dist; - std::string Section; - std::string Architecture; - - APT_HIDDEN std::string Info(const char *Type) const; - APT_HIDDEN std::string IndexFile(const char *Type) const; - APT_HIDDEN std::string IndexURI(const char *Type) const; - public: - + virtual const Type *GetType() const APT_CONST; // Stuff for accessing files on remote items virtual std::string ArchiveInfo(pkgCache::VerIterator Ver) const; - virtual std::string ArchiveURI(std::string File) const {return URI + File;}; - - // Interface for acquire - virtual std::string Describe(bool Short) const; - + // Interface for the Cache Generator - virtual bool Exists() const; virtual bool HasPackages() const {return true;}; - virtual unsigned long Size() const; virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; - debPackagesIndex(std::string const &URI, std::string const &Dist, std::string const &Section, - bool const &Trusted, std::string const &Arch = "native"); + debPackagesIndex(IndexTarget const &Target, bool const Trusted); virtual ~debPackagesIndex(); }; -class debTranslationsIndex : public pkgIndexFile +class APT_HIDDEN debTranslationsIndex : public pkgIndexTargetFile { - /** \brief dpointer placeholder (for later in case we need it) */ void *d; - - std::string URI; - std::string Dist; - std::string Section; - const char * const Language; - - APT_HIDDEN std::string Info(const char *Type) const; - APT_HIDDEN std::string IndexFile(const char *Type) const; - APT_HIDDEN std::string IndexURI(const char *Type) const; - - APT_HIDDEN std::string TranslationFile() const {return std::string("Translation-").append(Language);}; - public: - + virtual const Type *GetType() const APT_CONST; - // Interface for acquire - virtual std::string Describe(bool Short) const; - // Interface for the Cache Generator - virtual bool Exists() const; virtual bool HasPackages() const; - virtual unsigned long Size() const; virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; - debTranslationsIndex(std::string URI,std::string Dist,std::string Section, char const * const Language); + debTranslationsIndex(IndexTarget const &Target); virtual ~debTranslationsIndex(); }; -class debSourcesIndex : public pkgIndexFile +class APT_HIDDEN debSourcesIndex : public pkgIndexTargetFile { - /** \brief dpointer placeholder (for later in case we need it) */ void *d; - - std::string URI; - std::string Dist; - std::string Section; - - APT_HIDDEN std::string Info(const char *Type) const; - APT_HIDDEN std::string IndexFile(const char *Type) const; - APT_HIDDEN std::string IndexURI(const char *Type) const; - public: virtual const Type *GetType() const APT_CONST; @@ -146,24 +96,18 @@ class debSourcesIndex : public pkgIndexFile // Stuff for accessing files on remote items virtual std::string SourceInfo(pkgSrcRecords::Parser const &Record, pkgSrcRecords::File const &File) const; - virtual std::string ArchiveURI(std::string File) const {return URI + File;}; - - // Interface for acquire - virtual std::string Describe(bool Short) const; // Interface for the record parsers virtual pkgSrcRecords::Parser *CreateSrcParser() const; - + // Interface for the Cache Generator - virtual bool Exists() const; virtual bool HasPackages() const {return false;}; - virtual unsigned long Size() const; - - debSourcesIndex(std::string URI,std::string Dist,std::string Section,bool Trusted); + + debSourcesIndex(IndexTarget const &Target, bool const Trusted); virtual ~debSourcesIndex(); }; -class debDebPkgFileIndex : public pkgIndexFile +class APT_HIDDEN debDebPkgFileIndex : public pkgIndexFile { private: void *d; @@ -177,6 +121,14 @@ class debDebPkgFileIndex : public pkgIndexFile return DebFile; } + /** get the control (file) content of the deb file + * + * @param[out] content of the control file + * @param debfile is the filename of the .deb-file + * @return \b true if successful, otherwise \b false. + */ + static bool GetContent(std::ostream &content, std::string const &debfile); + // Interface for the Cache Generator virtual bool Exists() const; virtual bool HasPackages() const { @@ -193,9 +145,10 @@ class debDebPkgFileIndex : public pkgIndexFile virtual ~debDebPkgFileIndex(); }; -class debDscFileIndex : public pkgIndexFile +class APT_HIDDEN debDscFileIndex : public pkgIndexFile { private: + void *d; std::string DscFile; public: virtual const Type *GetType() const APT_CONST; @@ -208,10 +161,10 @@ class debDscFileIndex : public pkgIndexFile }; debDscFileIndex(std::string &DscFile); - virtual ~debDscFileIndex() {}; + virtual ~debDscFileIndex(); }; -class debDebianSourceDirIndex : public debDscFileIndex +class APT_HIDDEN debDebianSourceDirIndex : public debDscFileIndex { public: virtual const Type *GetType() const APT_CONST; diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 616d8296d..c5e77b0ff 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -141,6 +141,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) map_stringitem_t const idx = StoreString(pkgCacheGenerator::SECTION, Start, Stop - Start); Ver->Section = idx; } +#if APT_PKG_ABI >= 413 // Parse the source package name pkgCache::GrpIterator const G = Ver.ParentPkg().Group(); Ver->SourcePkgName = G->Name; @@ -192,6 +193,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) } } } +#endif Ver->MultiArch = ParseMultiArch(true); // Archive Size @@ -804,7 +806,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver, if (NewDepends(Ver,Package,"none",Version,Op,Type) == false) return false; } - else if (MultiArchEnabled == true && found != string::npos && + else if (found != string::npos && strcmp(Package.c_str() + found, ":any") != 0) { string Arch = Package.substr(found+1, string::npos); @@ -851,10 +853,16 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver) while (1) { Start = ParseDepends(Start,Stop,Package,Version,Op); + const size_t archfound = Package.rfind(':'); if (Start == 0) return _error->Error("Problem parsing Provides line"); if (Op != pkgCache::Dep::NoOp && Op != pkgCache::Dep::Equals) { _error->Warning("Ignoring Provides line with non-equal DepCompareOp for package %s", Package.c_str()); + } else if (archfound != string::npos) { + string OtherArch = Package.substr(archfound+1, string::npos); + Package = Package.substr(0, archfound); + if (NewProvides(Ver, Package, OtherArch, Version) == false) + return false; } else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) { if (NewProvidesAllArch(Ver, Package, Version) == false) return false; @@ -943,43 +951,6 @@ bool debListParser::Step() return false; } /*}}}*/ -// ListParser::LoadReleaseInfo - Load the release information /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, - FileFd &File, string component) -{ - // apt-secure does no longer download individual (per-section) Release - // file. to provide Component pinning we use the section name now - map_stringitem_t const storage = StoreString(pkgCacheGenerator::MIXED, component); - FileI->Component = storage; - - pkgTagFile TagFile(&File, File.Size()); - pkgTagSection Section; - if (_error->PendingError() == true || TagFile.Step(Section) == false) - return false; - - std::string data; - #define APT_INRELEASE(TYPE, TAG, STORE) \ - data = Section.FindS(TAG); \ - if (data.empty() == false) \ - { \ - map_stringitem_t const storage = StoreString(pkgCacheGenerator::TYPE, data); \ - STORE = storage; \ - } - APT_INRELEASE(MIXED, "Suite", FileI->Archive) - APT_INRELEASE(MIXED, "Component", FileI->Component) - APT_INRELEASE(VERSIONNUMBER, "Version", FileI->Version) - APT_INRELEASE(MIXED, "Origin", FileI->Origin) - APT_INRELEASE(MIXED, "Codename", FileI->Codename) - APT_INRELEASE(MIXED, "Label", FileI->Label) - #undef APT_INRELEASE - Section.FindFlag("NotAutomatic", FileI->Flags, pkgCache::Flag::NotAutomatic); - Section.FindFlag("ButAutomaticUpgrades", FileI->Flags, pkgCache::Flag::ButAutomaticUpgrades); - - return !_error->PendingError(); -} - /*}}}*/ // ListParser::GetPrio - Convert the priority from a string /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -992,7 +963,7 @@ unsigned char debListParser::GetPrio(string Str) return Out; } /*}}}*/ -#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) +#if APT_PKG_ABI >= 413 bool debListParser::SameVersion(unsigned short const Hash, /*{{{*/ pkgCache::VerIterator const &Ver) { diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index f20f7f33e..420d5ff08 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -26,7 +26,7 @@ class FileFd; -class debListParser : public pkgCacheGenerator::ListParser +class APT_HIDDEN debListParser : public pkgCacheGenerator::ListParser { public: @@ -59,7 +59,7 @@ class debListParser : public pkgCacheGenerator::ListParser public: - static unsigned char GetPrio(std::string Str); + APT_PUBLIC static unsigned char GetPrio(std::string Str); // These all operate against the current section virtual std::string Package(); @@ -71,7 +71,7 @@ class debListParser : public pkgCacheGenerator::ListParser virtual std::vector<std::string> AvailableDescriptionLanguages(); virtual MD5SumValue Description_md5(); virtual unsigned short VersionHash(); -#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) +#if APT_PKG_ABI >= 413 virtual bool SameVersion(unsigned short const Hash, pkgCache::VerIterator const &Ver); #endif virtual bool UsePackage(pkgCache::PkgIterator &Pkg, @@ -80,30 +80,30 @@ class debListParser : public pkgCacheGenerator::ListParser virtual map_filesize_t Size() {return Section.size();}; virtual bool Step(); - - bool LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,FileFd &File, - std::string section); - static const char *ParseDepends(const char *Start,const char *Stop, + bool LoadReleaseInfo(pkgCache::RlsFileIterator &FileI,FileFd &File, + std::string const §ion); + + APT_PUBLIC static const char *ParseDepends(const char *Start,const char *Stop, std::string &Package,std::string &Ver,unsigned int &Op); - static const char *ParseDepends(const char *Start,const char *Stop, + APT_PUBLIC static const char *ParseDepends(const char *Start,const char *Stop, std::string &Package,std::string &Ver,unsigned int &Op, bool const &ParseArchFlags); - static const char *ParseDepends(const char *Start,const char *Stop, + APT_PUBLIC static const char *ParseDepends(const char *Start,const char *Stop, std::string &Package,std::string &Ver,unsigned int &Op, bool const &ParseArchFlags, bool const &StripMultiArch); - static const char *ParseDepends(const char *Start,const char *Stop, + APT_PUBLIC static const char *ParseDepends(const char *Start,const char *Stop, std::string &Package,std::string &Ver,unsigned int &Op, bool const &ParseArchFlags, bool const &StripMultiArch, bool const &ParseRestrictionsList); - static const char *ConvertRelation(const char *I,unsigned int &Op); + APT_PUBLIC static const char *ConvertRelation(const char *I,unsigned int &Op); debListParser(FileFd *File, std::string const &Arch = ""); virtual ~debListParser(); }; -class debDebFileParser : public debListParser +class APT_HIDDEN debDebFileParser : public debListParser { private: std::string DebFile; @@ -114,7 +114,7 @@ class debDebFileParser : public debListParser pkgCache::VerIterator &Ver); }; -class debTranslationsParser : public debListParser +class APT_HIDDEN debTranslationsParser : public debListParser { public: // a translation can never be a real package diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index c103da8f7..34fc98838 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -1,5 +1,6 @@ #include <config.h> +#include <apt-pkg/error.h> #include <apt-pkg/debmetaindex.h> #include <apt-pkg/debindexfile.h> #include <apt-pkg/strutl.h> @@ -10,10 +11,12 @@ #include <apt-pkg/indexrecords.h> #include <apt-pkg/sourcelist.h> #include <apt-pkg/hashes.h> -#include <apt-pkg/macros.h> #include <apt-pkg/metaindex.h> +#include <apt-pkg/pkgcachegen.h> +#include <apt-pkg/tagfile.h> +#include <apt-pkg/gpgv.h> +#include <apt-pkg/macros.h> -#include <string.h> #include <map> #include <string> #include <utility> @@ -21,30 +24,16 @@ #include <set> #include <algorithm> -using namespace std; +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string.h> -string debReleaseIndex::Info(const char *Type, string const &Section, string const &Arch) const -{ - string Info = ::URI::SiteOnly(URI) + ' '; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Info += Dist; - } - else - { - Info += Dist + '/' + Section; - if (Arch.empty() != true) - Info += " " + Arch; - } - Info += " "; - Info += Type; - return Info; -} +using namespace std; string debReleaseIndex::MetaIndexInfo(const char *Type) const { - string Info = ::URI::SiteOnly(URI) + ' '; + string Info = ::URI::ArchiveOnly(URI) + ' '; if (Dist[Dist.size() - 1] == '/') { if (Dist != "/") @@ -56,6 +45,10 @@ string debReleaseIndex::MetaIndexInfo(const char *Type) const Info += Type; return Info; } +std::string debReleaseIndex::Describe() const +{ + return MetaIndexInfo("Release"); +} string debReleaseIndex::MetaIndexFile(const char *Type) const { @@ -78,7 +71,6 @@ string debReleaseIndex::MetaIndexURI(const char *Type) const return Res; } -#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) std::string debReleaseIndex::LocalFileName() const { // see if we have a InRelease file @@ -92,167 +84,183 @@ std::string debReleaseIndex::LocalFileName() const return ""; } -#endif -string debReleaseIndex::IndexURISuffix(const char *Type, string const &Section, string const &Arch) const -{ - string Res =""; - if (Dist[Dist.size() - 1] != '/') - { - if (Arch == "native") - Res += Section + "/binary-" + _config->Find("APT::Architecture") + '/'; - else - Res += Section + "/binary-" + Arch + '/'; - } - return Res + Type; +debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist) : + metaIndex(URI, Dist, "deb"), Trusted(CHECK_TRUST) +{} + +debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist, bool const Trusted) : + metaIndex(URI, Dist, "deb") { + SetTrusted(Trusted); +} + +debReleaseIndex::~debReleaseIndex() { + for (map<string, vector<debSectionEntry const*> >::const_iterator A = ArchEntries.begin(); + A != ArchEntries.end(); ++A) + for (vector<const debSectionEntry *>::const_iterator S = A->second.begin(); + S != A->second.end(); ++S) + delete *S; } - -string debReleaseIndex::IndexURI(const char *Type, string const &Section, string const &Arch) const +template<typename CallC> +void foreachTarget(std::string const URI, std::string const Dist, + std::map<std::string, std::vector<debReleaseIndex::debSectionEntry const *> > const &ArchEntries, + CallC &Call) { - if (Dist[Dist.size() - 1] == '/') + bool const flatArchive = (Dist[Dist.length() - 1] == '/'); + std::string baseURI = URI; + if (flatArchive) { - string Res; if (Dist != "/") - Res = URI + Dist; - else - Res = URI; - return Res + Type; + baseURI += Dist; } else - return URI + "dists/" + Dist + '/' + IndexURISuffix(Type, Section, Arch); - } + baseURI += "dists/" + Dist + "/"; + std::string const Release = (Dist == "/") ? "" : Dist; + std::string const Site = ::URI::ArchiveOnly(URI); + std::vector<std::string> lang = APT::Configuration::getLanguages(true); + if (lang.empty()) + lang.push_back("none"); + map<string, vector<debReleaseIndex::debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source"); + if (src != ArchEntries.end()) + { + std::vector<std::string> const targets = _config->FindVector("APT::Acquire::Targets::deb-src", "", true); + for (std::vector<std::string>::const_iterator T = targets.begin(); T != targets.end(); ++T) + { +#define APT_T_CONFIG(X) _config->Find(std::string("APT::Acquire::Targets::deb-src::") + *T + "::" + (X)) + std::string const MetaKey = APT_T_CONFIG(flatArchive ? "flatMetaKey" : "MetaKey"); + std::string const ShortDesc = APT_T_CONFIG("ShortDescription"); + std::string const LongDesc = APT_T_CONFIG(flatArchive ? "flatDescription" : "Description"); + bool const IsOptional = _config->FindB(std::string("APT::Acquire::Targets::deb-src::") + *T + "::Optional", true); +#undef APT_T_CONFIG + if (MetaKey.empty()) + continue; -string debReleaseIndex::SourceIndexURISuffix(const char *Type, const string &Section) const -{ - string Res =""; - if (Dist[Dist.size() - 1] != '/') - Res += Section + "/source/"; - return Res + Type; -} + vector<debReleaseIndex::debSectionEntry const*> const SectionEntries = src->second; + for (vector<debReleaseIndex::debSectionEntry const*>::const_iterator I = SectionEntries.begin(); + I != SectionEntries.end(); ++I) + { + for (vector<std::string>::const_iterator l = lang.begin(); l != lang.end(); ++l) + { + if (*l == "none" && MetaKey.find("$(LANGUAGE)") != std::string::npos) + continue; + + std::map<std::string, std::string> Options; + Options.insert(std::make_pair("SITE", Site)); + Options.insert(std::make_pair("RELEASE", Release)); + if (MetaKey.find("$(COMPONENT)") != std::string::npos) + Options.insert(std::make_pair("COMPONENT", (*I)->Section)); + if (MetaKey.find("$(LANGUAGE)") != std::string::npos) + Options.insert(std::make_pair("LANGUAGE", *l)); + Options.insert(std::make_pair("ARCHITECTURE", "source")); + Options.insert(std::make_pair("BASE_URI", baseURI)); + Options.insert(std::make_pair("REPO_URI", URI)); + Options.insert(std::make_pair("TARGET_OF", "deb-src")); + Options.insert(std::make_pair("CREATED_BY", *T)); + Call(MetaKey, ShortDesc, LongDesc, IsOptional, Options); + + if (MetaKey.find("$(LANGUAGE)") == std::string::npos) + break; + } -string debReleaseIndex::SourceIndexURI(const char *Type, const string &Section) const -{ - string Res; - if (Dist[Dist.size() - 1] == '/') + if (MetaKey.find("$(COMPONENT)") == std::string::npos) + break; + } + } + } + + std::vector<std::string> const targets = _config->FindVector("APT::Acquire::Targets::deb", "", true); + for (std::vector<std::string>::const_iterator T = targets.begin(); T != targets.end(); ++T) { - if (Dist != "/") - Res = URI + Dist; - else - Res = URI; - return Res + Type; +#define APT_T_CONFIG(X) _config->Find(std::string("APT::Acquire::Targets::deb::") + *T + "::" + (X)) + std::string const MetaKey = APT_T_CONFIG(flatArchive ? "flatMetaKey" : "MetaKey"); + std::string const ShortDesc = APT_T_CONFIG("ShortDescription"); + std::string const LongDesc = APT_T_CONFIG(flatArchive ? "flatDescription" : "Description"); + bool const IsOptional = _config->FindB(std::string("APT::Acquire::Targets::deb::") + *T + "::Optional", true); +#undef APT_T_CONFIG + if (MetaKey.empty()) + continue; + + for (map<string, vector<debReleaseIndex::debSectionEntry const*> >::const_iterator a = ArchEntries.begin(); + a != ArchEntries.end(); ++a) + { + if (a->first == "source") + continue; + + for (vector <const debReleaseIndex::debSectionEntry *>::const_iterator I = a->second.begin(); + I != a->second.end(); ++I) { + + for (vector<std::string>::const_iterator l = lang.begin(); l != lang.end(); ++l) + { + if (*l == "none" && MetaKey.find("$(LANGUAGE)") != std::string::npos) + continue; + + std::map<std::string, std::string> Options; + Options.insert(std::make_pair("SITE", Site)); + Options.insert(std::make_pair("RELEASE", Release)); + if (MetaKey.find("$(COMPONENT)") != std::string::npos) + Options.insert(std::make_pair("COMPONENT", (*I)->Section)); + if (MetaKey.find("$(LANGUAGE)") != std::string::npos) + Options.insert(std::make_pair("LANGUAGE", *l)); + if (MetaKey.find("$(ARCHITECTURE)") != std::string::npos) + Options.insert(std::make_pair("ARCHITECTURE", a->first)); + Options.insert(std::make_pair("BASE_URI", baseURI)); + Options.insert(std::make_pair("REPO_URI", URI)); + Options.insert(std::make_pair("TARGET_OF", "deb")); + Options.insert(std::make_pair("CREATED_BY", *T)); + Call(MetaKey, ShortDesc, LongDesc, IsOptional, Options); + + if (MetaKey.find("$(LANGUAGE)") == std::string::npos) + break; + } + + if (MetaKey.find("$(COMPONENT)") == std::string::npos) + break; + } + + if (MetaKey.find("$(ARCHITECTURE)") == std::string::npos) + break; + } } - else - return URI + "dists/" + Dist + "/" + SourceIndexURISuffix(Type, Section); } -string debReleaseIndex::TranslationIndexURISuffix(const char *Type, const string &Section) const -{ - string Res =""; - if (Dist[Dist.size() - 1] != '/') - Res += Section + "/i18n/Translation-"; - return Res + Type; -} -string debReleaseIndex::TranslationIndexURI(const char *Type, const string &Section) const +struct ComputeIndexTargetsClass { - string Res; - if (Dist[Dist.size() - 1] == '/') + vector <IndexTarget> IndexTargets; + + void operator()(std::string MetaKey, std::string ShortDesc, std::string LongDesc, + bool const IsOptional, std::map<std::string, std::string> Options) { - if (Dist != "/") - Res = URI + Dist; - else - Res = URI; - return Res + Type; + for (std::map<std::string, std::string>::const_iterator O = Options.begin(); O != Options.end(); ++O) + { + MetaKey = SubstVar(MetaKey, std::string("$(") + O->first + ")", O->second); + ShortDesc = SubstVar(ShortDesc, std::string("$(") + O->first + ")", O->second); + LongDesc = SubstVar(LongDesc, std::string("$(") + O->first + ")", O->second); + } + IndexTarget Target( + MetaKey, + ShortDesc, + LongDesc, + Options.find("BASE_URI")->second + MetaKey, + IsOptional, + Options + ); + IndexTargets.push_back(Target); } - else - return URI + "dists/" + Dist + "/" + TranslationIndexURISuffix(Type, Section); -} - -debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist) : - metaIndex(URI, Dist, "deb"), Trusted(CHECK_TRUST) -{} +}; -debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist, bool const Trusted) : - metaIndex(URI, Dist, "deb") { - SetTrusted(Trusted); +std::vector<IndexTarget> debReleaseIndex::GetIndexTargets() const +{ + ComputeIndexTargetsClass comp; + foreachTarget(URI, Dist, ArchEntries, comp); + return comp.IndexTargets; } -debReleaseIndex::~debReleaseIndex() { - for (map<string, vector<debSectionEntry const*> >::const_iterator A = ArchEntries.begin(); - A != ArchEntries.end(); ++A) - for (vector<const debSectionEntry *>::const_iterator S = A->second.begin(); - S != A->second.end(); ++S) - delete *S; -} -vector <IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const { - vector <IndexTarget *>* IndexTargets = new vector <IndexTarget *>; - - map<string, vector<debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source"); - if (src != ArchEntries.end()) { - vector<debSectionEntry const*> const SectionEntries = src->second; - for (vector<debSectionEntry const*>::const_iterator I = SectionEntries.begin(); - I != SectionEntries.end(); ++I) { - IndexTarget * Target = new IndexTarget(); - Target->ShortDesc = "Sources"; - Target->MetaKey = SourceIndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section); - Target->URI = SourceIndexURI(Target->ShortDesc.c_str(), (*I)->Section); - Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section); - IndexTargets->push_back (Target); - } - } - - // Only source release - if (IndexTargets->empty() == false && ArchEntries.size() == 1) - return IndexTargets; - - std::set<std::string> sections; - for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin(); - a != ArchEntries.end(); ++a) { - if (a->first == "source") - continue; - for (vector <const debSectionEntry *>::const_iterator I = a->second.begin(); - I != a->second.end(); ++I) { - IndexTarget * Target = new IndexTarget(); - Target->ShortDesc = "Packages"; - Target->MetaKey = IndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section, a->first); - Target->URI = IndexURI(Target->ShortDesc.c_str(), (*I)->Section, a->first); - Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section, a->first); - IndexTargets->push_back (Target); - sections.insert((*I)->Section); - } - } - - std::vector<std::string> lang = APT::Configuration::getLanguages(true); - std::vector<std::string>::iterator lend = std::remove(lang.begin(), lang.end(), "none"); - if (lend != lang.end()) - lang.erase(lend); - - if (lang.empty() == true) - return IndexTargets; - - // get the Translation-* files, later we will skip download of non-existent if we have an index - for (std::set<std::string>::const_iterator s = sections.begin(); - s != sections.end(); ++s) { - for (std::vector<std::string>::const_iterator l = lang.begin(); - l != lang.end(); ++l) { - IndexTarget * Target = new OptionalIndexTarget(); - Target->ShortDesc = "Translation-" + *l; - Target->MetaKey = TranslationIndexURISuffix(l->c_str(), *s); - Target->URI = TranslationIndexURI(l->c_str(), *s); - Target->Description = Info (Target->ShortDesc.c_str(), *s); - IndexTargets->push_back(Target); - } - } - - return IndexTargets; -} /*}}}*/ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const { - bool const tryInRelease = _config->FindB("Acquire::TryInRelease", true); - indexRecords * const iR = new indexRecords(Dist); if (Trusted == ALWAYS_TRUSTED) iR->SetTrusted(true); @@ -260,37 +268,17 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const iR->SetTrusted(false); // special case for --print-uris - if (GetAll) { - vector <IndexTarget *> *targets = ComputeIndexTargets(); - for (vector <IndexTarget*>::const_iterator Target = targets->begin(); Target != targets->end(); ++Target) { - new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description, - (*Target)->ShortDesc, HashStringList()); - } - delete targets; - - // this is normally created in pkgAcqMetaSig, but if we run - // in --print-uris mode, we add it here - if (tryInRelease == false) - new pkgAcqMetaIndex(Owner, NULL, - MetaIndexURI("Release"), - MetaIndexInfo("Release"), "Release", - MetaIndexURI("Release.gpg"), MetaIndexInfo("Release.gpg"), "Release.gpg", - ComputeIndexTargets(), - iR); + std::vector<IndexTarget> const targets = GetIndexTargets(); +#define APT_TARGET(X) IndexTarget("", X, MetaIndexInfo(X), MetaIndexURI(X), false, std::map<std::string,std::string>()) + pkgAcqMetaBase * const TransactionManager = new pkgAcqMetaClearSig(Owner, + APT_TARGET("InRelease"), APT_TARGET("Release"), APT_TARGET("Release.gpg"), + targets, iR); +#undef APT_TARGET + if (GetAll) + { + for (std::vector<IndexTarget>::const_iterator Target = targets.begin(); Target != targets.end(); ++Target) + new pkgAcqIndex(Owner, TransactionManager, *Target); } - if (tryInRelease == true) - new pkgAcqMetaClearSig(Owner, - MetaIndexURI("InRelease"), MetaIndexInfo("InRelease"), "InRelease", - MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release", - MetaIndexURI("Release.gpg"), MetaIndexInfo("Release.gpg"), "Release.gpg", - ComputeIndexTargets(), - iR); - else - new pkgAcqMetaIndex(Owner, NULL, - MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release", - MetaIndexURI("Release.gpg"), MetaIndexInfo("Release.gpg"), "Release.gpg", - ComputeIndexTargets(), - iR); return true; } @@ -327,45 +315,25 @@ bool debReleaseIndex::IsTrusted() const return FileExists(VerifiedSigFile); } -vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() { - if (Indexes != NULL) - return Indexes; - - Indexes = new vector <pkgIndexFile*>; - map<string, vector<debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source"); - if (src != ArchEntries.end()) { - vector<debSectionEntry const*> const SectionEntries = src->second; - for (vector<debSectionEntry const*>::const_iterator I = SectionEntries.begin(); - I != SectionEntries.end(); ++I) - Indexes->push_back(new debSourcesIndex (URI, Dist, (*I)->Section, IsTrusted())); - } - - // Only source release - if (Indexes->empty() == false && ArchEntries.size() == 1) - return Indexes; - - std::vector<std::string> const lang = APT::Configuration::getLanguages(true); - map<string, set<string> > sections; - for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin(); - a != ArchEntries.end(); ++a) { - if (a->first == "source") - continue; - for (vector<debSectionEntry const*>::const_iterator I = a->second.begin(); - I != a->second.end(); ++I) { - Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted(), a->first)); - sections[(*I)->Section].insert(lang.begin(), lang.end()); - } - } - - for (map<string, set<string> >::const_iterator s = sections.begin(); - s != sections.end(); ++s) - for (set<string>::const_iterator l = s->second.begin(); - l != s->second.end(); ++l) { - if (*l == "none") continue; - Indexes->push_back(new debTranslationsIndex(URI,Dist,s->first,(*l).c_str())); - } - - return Indexes; +std::vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() +{ + if (Indexes != NULL) + return Indexes; + + Indexes = new std::vector<pkgIndexFile*>(); + std::vector<IndexTarget> const Targets = GetIndexTargets(); + bool const istrusted = IsTrusted(); + for (std::vector<IndexTarget>::const_iterator T = Targets.begin(); T != Targets.end(); ++T) + { + std::string const TargetName = T->Option(IndexTarget::CREATED_BY); + if (TargetName == "Packages") + Indexes->push_back(new debPackagesIndex(*T, istrusted)); + else if (TargetName == "Sources") + Indexes->push_back(new debSourcesIndex(*T, istrusted)); + else if (TargetName == "Translations") + Indexes->push_back(new debTranslationsIndex(*T)); + } + return Indexes; } void debReleaseIndex::PushSectionEntry(vector<string> const &Archs, const debSectionEntry *Entry) { @@ -379,22 +347,121 @@ void debReleaseIndex::PushSectionEntry(string const &Arch, const debSectionEntry ArchEntries[Arch].push_back(Entry); } -void debReleaseIndex::PushSectionEntry(const debSectionEntry *Entry) { - if (Entry->IsSrc == true) - PushSectionEntry("source", Entry); - else { - for (map<string, vector<const debSectionEntry *> >::iterator a = ArchEntries.begin(); - a != ArchEntries.end(); ++a) { - a->second.push_back(Entry); - } - } -} - debReleaseIndex::debSectionEntry::debSectionEntry (string const &Section, bool const &IsSrc): Section(Section), IsSrc(IsSrc) {} -class debSLTypeDebian : public pkgSourceList::Type +static bool ReleaseFileName(debReleaseIndex const * const That, std::string &ReleaseFile) +{ + ReleaseFile = That->MetaIndexFile("InRelease"); + bool releaseExists = false; + if (FileExists(ReleaseFile) == true) + releaseExists = true; + else + { + ReleaseFile = That->MetaIndexFile("Release"); + if (FileExists(ReleaseFile)) + releaseExists = true; + } + return releaseExists; +} + +bool debReleaseIndex::Merge(pkgCacheGenerator &Gen,OpProgress * /*Prog*/) const/*{{{*/ +{ + std::string ReleaseFile; + bool const releaseExists = ReleaseFileName(this, ReleaseFile); + + ::URI Tmp(URI); + if (Gen.SelectReleaseFile(ReleaseFile, Tmp.Host) == false) + return _error->Error("Problem with SelectReleaseFile %s", ReleaseFile.c_str()); + + if (releaseExists == false) + return true; + + 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; + + // Store the IMS information + pkgCache::RlsFileIterator File = Gen.GetCurRlsFile(); + pkgCacheGenerator::Dynamic<pkgCache::RlsFileIterator> DynFile(File); + // Rel can't be used as this is potentially a temporary file + struct stat Buf; + if (stat(ReleaseFile.c_str(), &Buf) != 0) + return _error->Errno("fstat", "Unable to stat file %s", ReleaseFile.c_str()); + File->Size = Buf.st_size; + File->mtime = Buf.st_mtime; + + pkgTagFile TagFile(&Rel, Rel.Size()); + pkgTagSection Section; + if (_error->PendingError() == true || TagFile.Step(Section) == false) + return false; + + std::string data; + #define APT_INRELEASE(TYPE, TAG, STORE) \ + data = Section.FindS(TAG); \ + if (data.empty() == false) \ + { \ + map_stringitem_t const storage = Gen.StoreString(pkgCacheGenerator::TYPE, data); \ + STORE = storage; \ + } + APT_INRELEASE(MIXED, "Suite", File->Archive) + APT_INRELEASE(VERSIONNUMBER, "Version", File->Version) + APT_INRELEASE(MIXED, "Origin", File->Origin) + APT_INRELEASE(MIXED, "Codename", File->Codename) + APT_INRELEASE(MIXED, "Label", File->Label) + #undef APT_INRELEASE + Section.FindFlag("NotAutomatic", File->Flags, pkgCache::Flag::NotAutomatic); + Section.FindFlag("ButAutomaticUpgrades", File->Flags, pkgCache::Flag::ButAutomaticUpgrades); + + return !_error->PendingError(); +} + /*}}}*/ +// ReleaseIndex::FindInCache - Find this index /*{{{*/ +pkgCache::RlsFileIterator debReleaseIndex::FindInCache(pkgCache &Cache, bool const ModifyCheck) const +{ + std::string ReleaseFile; + bool const releaseExists = ReleaseFileName(this, ReleaseFile); + + pkgCache::RlsFileIterator File = Cache.RlsFileBegin(); + for (; File.end() == false; ++File) + { + if (File->FileName == 0 || ReleaseFile != File.FileName()) + continue; + + // empty means the file does not exist by "design" + if (ModifyCheck == false || (releaseExists == false && File->Size == 0)) + return File; + + struct stat St; + if (stat(File.FileName(),&St) != 0) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "ReleaseIndex::FindInCache - stat failed on " << File.FileName() << std::endl; + return pkgCache::RlsFileIterator(Cache); + } + if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime) + { + if (_config->FindB("Debug::pkgCacheGen", false)) + std::clog << "ReleaseIndex::FindInCache - size (" << St.st_size << " <> " << File->Size + << ") or mtime (" << St.st_mtime << " <> " << File->mtime + << ") doesn't match for " << File.FileName() << std::endl; + return pkgCache::RlsFileIterator(Cache); + } + return File; + } + + return File; +} + /*}}}*/ + +debDebFileMetaIndex::~debDebFileMetaIndex() {} + +class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type { protected: @@ -404,9 +471,12 @@ class debSLTypeDebian : public pkgSourceList::Type { // parse arch=, arch+= and arch-= settings map<string, string>::const_iterator arch = Options.find("arch"); - vector<string> Archs = - (arch != Options.end()) ? VectorizeString(arch->second, ',') : - APT::Configuration::getArchitectures(); + vector<string> Archs; + if (arch != Options.end()) + Archs = VectorizeString(arch->second, ','); + else + Archs = APT::Configuration::getArchitectures(); + if ((arch = Options.find("arch+")) != Options.end()) { std::vector<std::string> const plusArch = VectorizeString(arch->second, ','); @@ -427,6 +497,7 @@ class debSLTypeDebian : public pkgSourceList::Type map<string, string>::const_iterator const trusted = Options.find("trusted"); + debReleaseIndex *Deb = NULL; for (vector<metaIndex *>::const_iterator I = List.begin(); I != List.end(); ++I) { @@ -434,34 +505,23 @@ class debSLTypeDebian : public pkgSourceList::Type if (strcmp((*I)->GetType(), "deb") != 0) continue; - debReleaseIndex *Deb = (debReleaseIndex *) (*I); - if (trusted != Options.end()) - Deb->SetTrusted(StringToBool(trusted->second, false)); - /* This check insures that there will be only one Release file queued for all the Packages files and Sources files it corresponds to. */ - if (Deb->GetURI() == URI && Deb->GetDist() == Dist) + if ((*I)->GetURI() == URI && (*I)->GetDist() == Dist) { - if (IsSrc == true) - Deb->PushSectionEntry("source", new debReleaseIndex::debSectionEntry(Section, IsSrc)); - else - { - if (Dist[Dist.size() - 1] == '/') - Deb->PushSectionEntry("any", new debReleaseIndex::debSectionEntry(Section, IsSrc)); - else - Deb->PushSectionEntry(Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc)); - } - return true; + Deb = dynamic_cast<debReleaseIndex*>(*I); + if (Deb != NULL) + break; } } // No currently created Release file indexes this entry, so we create a new one. - debReleaseIndex *Deb; - if (trusted != Options.end()) - Deb = new debReleaseIndex(URI, Dist, StringToBool(trusted->second, false)); - else + if (Deb == NULL) + { Deb = new debReleaseIndex(URI, Dist); + List.push_back(Deb); + } if (IsSrc == true) Deb->PushSectionEntry ("source", new debReleaseIndex::debSectionEntry(Section, IsSrc)); @@ -472,7 +532,10 @@ class debSLTypeDebian : public pkgSourceList::Type else Deb->PushSectionEntry (Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc)); } - List.push_back(Deb); + + if (trusted != Options.end()) + Deb->SetTrusted(StringToBool(trusted->second, false)); + return true; } }; @@ -486,7 +549,7 @@ debDebFileMetaIndex::debDebFileMetaIndex(std::string const &DebFile) } -class debSLTypeDeb : public debSLTypeDebian +class APT_HIDDEN debSLTypeDeb : public debSLTypeDebian { public: @@ -504,7 +567,7 @@ class debSLTypeDeb : public debSLTypeDebian } }; -class debSLTypeDebSrc : public debSLTypeDebian +class APT_HIDDEN debSLTypeDebSrc : public debSLTypeDebian { public: @@ -522,7 +585,7 @@ class debSLTypeDebSrc : public debSLTypeDebian } }; -class debSLTypeDebFile : public pkgSourceList::Type +class APT_HIDDEN debSLTypeDebFile : public pkgSourceList::Type { public: @@ -541,6 +604,7 @@ class debSLTypeDebFile : public pkgSourceList::Type Label = "Debian Deb File"; } }; -debSLTypeDeb _apt_DebType; -debSLTypeDebSrc _apt_DebSrcType; -debSLTypeDebFile _apt_DebFileType; + +APT_HIDDEN debSLTypeDeb _apt_DebType; +APT_HIDDEN debSLTypeDebSrc _apt_DebSrcType; +APT_HIDDEN debSLTypeDebFile _apt_DebFileType; diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h index 399543953..f2706e08a 100644 --- a/apt-pkg/deb/debmetaindex.h +++ b/apt-pkg/deb/debmetaindex.h @@ -20,8 +20,10 @@ class pkgAcquire; class pkgIndexFile; class debDebPkgFileIndex; class IndexTarget; +class pkgCacheGenerator; +class OpProgress; -class debReleaseIndex : public metaIndex { +class APT_HIDDEN debReleaseIndex : public metaIndex { public: class debSectionEntry @@ -46,23 +48,21 @@ class debReleaseIndex : public metaIndex { virtual std::string ArchiveURI(std::string const &File) const {return URI + File;}; virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const; - std::vector <IndexTarget *>* ComputeIndexTargets() const; - std::string Info(const char *Type, std::string const &Section, std::string const &Arch="") const; + virtual std::vector<IndexTarget> GetIndexTargets() const; + + virtual std::string Describe() const; + virtual pkgCache::RlsFileIterator FindInCache(pkgCache &Cache, bool const ModifyCheck) const; + virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; std::string MetaIndexInfo(const char *Type) const; std::string MetaIndexFile(const char *Types) const; std::string MetaIndexURI(const char *Type) const; -#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) - virtual std::string LocalFileName() const; +#if APT_PKG_ABI >= 413 + virtual #endif + std::string LocalFileName() const; - std::string IndexURI(const char *Type, std::string const &Section, std::string const &Arch="native") const; - std::string IndexURISuffix(const char *Type, std::string const &Section, std::string const &Arch="native") const; - std::string SourceIndexURI(const char *Type, const std::string &Section) const; - std::string SourceIndexURISuffix(const char *Type, const std::string &Section) const; - std::string TranslationIndexURI(const char *Type, const std::string &Section) const; - std::string TranslationIndexURISuffix(const char *Type, const std::string &Section) const; virtual std::vector <pkgIndexFile *> *GetIndexFiles(); void SetTrusted(bool const Trusted); @@ -70,12 +70,12 @@ class debReleaseIndex : public metaIndex { void PushSectionEntry(std::vector<std::string> const &Archs, const debSectionEntry *Entry); void PushSectionEntry(std::string const &Arch, const debSectionEntry *Entry); - void PushSectionEntry(const debSectionEntry *Entry); }; -class debDebFileMetaIndex : public metaIndex +class APT_HIDDEN debDebFileMetaIndex : public metaIndex { private: + void *d; std::string DebFile; debDebPkgFileIndex *DebIndex; public: @@ -85,6 +85,9 @@ class debDebFileMetaIndex : public metaIndex virtual bool GetIndexes(pkgAcquire* /*Owner*/, const bool& /*GetAll=false*/) const { return true; } + virtual std::vector<IndexTarget> GetIndexTargets() const { + return std::vector<IndexTarget>(); + } virtual std::vector<pkgIndexFile *> *GetIndexFiles() { return Indexes; } @@ -92,7 +95,7 @@ class debDebFileMetaIndex : public metaIndex return true; } debDebFileMetaIndex(std::string const &DebFile); - virtual ~debDebFileMetaIndex() {}; + virtual ~debDebFileMetaIndex(); }; diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc index b41aa5584..f527042e4 100644 --- a/apt-pkg/deb/debrecords.cc +++ b/apt-pkg/deb/debrecords.cc @@ -11,35 +11,35 @@ #include <config.h> #include <apt-pkg/debrecords.h> +#include <apt-pkg/debindexfile.h> #include <apt-pkg/strutl.h> #include <apt-pkg/aptconfiguration.h> #include <apt-pkg/fileutl.h> #include <apt-pkg/cacheiterators.h> #include <apt-pkg/pkgcache.h> #include <apt-pkg/tagfile.h> +#include <apt-pkg/error.h> #include <string.h> #include <algorithm> +#include <sstream> #include <string> #include <vector> #include <langinfo.h> + +#include <apti18n.h> /*}}}*/ using std::string; // RecordParser::debRecordParser - Constructor /*{{{*/ -// --------------------------------------------------------------------- -/* */ -debRecordParser::debRecordParser(string FileName,pkgCache &Cache) : - File(FileName,FileFd::ReadOnly, FileFd::Extension), - Tags(&File, std::max(Cache.Head().MaxVerFileSize, - Cache.Head().MaxDescFileSize) + 200) +debRecordParser::debRecordParser(string FileName,pkgCache &Cache) : + debRecordParserBase(), File(FileName, FileFd::ReadOnly, FileFd::Extension), + Tags(&File, std::max(Cache.Head().MaxVerFileSize, Cache.Head().MaxDescFileSize) + 200) { } /*}}}*/ // RecordParser::Jump - Jump to a specific record /*{{{*/ -// --------------------------------------------------------------------- -/* */ bool debRecordParser::Jump(pkgCache::VerFileIterator const &Ver) { return Tags.Jump(Section,Ver->Offset); @@ -49,32 +49,29 @@ bool debRecordParser::Jump(pkgCache::DescFileIterator const &Desc) return Tags.Jump(Section,Desc->Offset); } /*}}}*/ -// RecordParser::FileName - Return the archive filename on the site /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::FileName() +debRecordParser::~debRecordParser() {} + +debRecordParserBase::debRecordParserBase() : Parser() {} +// RecordParserBase::FileName - Return the archive filename on the site /*{{{*/ +string debRecordParserBase::FileName() { return Section.FindS("Filename"); } /*}}}*/ -// RecordParser::Name - Return the package name /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::Name() +// RecordParserBase::Name - Return the package name /*{{{*/ +string debRecordParserBase::Name() { return Section.FindS("Package"); } /*}}}*/ -// RecordParser::Homepage - Return the package homepage /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::Homepage() +// RecordParserBase::Homepage - Return the package homepage /*{{{*/ +string debRecordParserBase::Homepage() { return Section.FindS("Homepage"); } /*}}}*/ -// RecordParser::Hashes - return the available archive hashes /*{{{*/ -HashStringList debRecordParser::Hashes() const +// RecordParserBase::Hashes - return the available archive hashes /*{{{*/ +HashStringList debRecordParserBase::Hashes() const { HashStringList hashes; for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type) @@ -86,27 +83,20 @@ HashStringList debRecordParser::Hashes() const return hashes; } /*}}}*/ -// RecordParser::Maintainer - Return the maintainer email /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::Maintainer() +// RecordParserBase::Maintainer - Return the maintainer email /*{{{*/ +string debRecordParserBase::Maintainer() { return Section.FindS("Maintainer"); } /*}}}*/ -// RecordParser::RecordField - Return the value of an arbitrary field /*{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::RecordField(const char *fieldName) +// RecordParserBase::RecordField - Return the value of an arbitrary field /*{{*/ +string debRecordParserBase::RecordField(const char *fieldName) { return Section.FindS(fieldName); } - - /*}}}*/ -// RecordParser::ShortDesc - Return a 1 line description /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::ShortDesc(std::string const &lang) + /*}}}*/ +// RecordParserBase::ShortDesc - Return a 1 line description /*{{{*/ +string debRecordParserBase::ShortDesc(std::string const &lang) { string const Res = LongDesc(lang); if (Res.empty() == true) @@ -117,10 +107,8 @@ string debRecordParser::ShortDesc(std::string const &lang) return string(Res,0,Pos); } /*}}}*/ -// RecordParser::LongDesc - Return a longer description /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::LongDesc(std::string const &lang) +// RecordParserBase::LongDesc - Return a longer description /*{{{*/ +string debRecordParserBase::LongDesc(std::string const &lang) { string orig; if (lang.empty() == true) @@ -162,12 +150,9 @@ string debRecordParser::LongDesc(std::string const &lang) } /*}}}*/ -static const char *SourceVerSeparators = " ()"; - -// RecordParser::SourcePkg - Return the source package name if any /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::SourcePkg() +static const char * const SourceVerSeparators = " ()"; +// RecordParserBase::SourcePkg - Return the source package name if any /*{{{*/ +string debRecordParserBase::SourcePkg() { string Res = Section.FindS("Source"); string::size_type Pos = Res.find_first_of(SourceVerSeparators); @@ -176,10 +161,8 @@ string debRecordParser::SourcePkg() return string(Res,0,Pos); } /*}}}*/ -// RecordParser::SourceVer - Return the source version number if present /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debRecordParser::SourceVer() +// RecordParserBase::SourceVer - Return the source version number if present /*{{{*/ +string debRecordParserBase::SourceVer() { string Pkg = Section.FindS("Source"); string::size_type Pos = Pkg.find_first_of(SourceVerSeparators); @@ -199,13 +182,35 @@ string debRecordParser::SourceVer() return string(Pkg, VerStart, VerEnd - VerStart); } /*}}}*/ -// RecordParser::GetRec - Return the whole record /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void debRecordParser::GetRec(const char *&Start,const char *&Stop) +// RecordParserBase::GetRec - Return the whole record /*{{{*/ +void debRecordParserBase::GetRec(const char *&Start,const char *&Stop) { Section.GetSection(Start,Stop); } /*}}}*/ +debRecordParserBase::~debRecordParserBase() {} -debRecordParser::~debRecordParser() {} +bool debDebFileRecordParser::LoadContent() +{ + // load content only once + if (controlContent.empty() == false) + return true; + + std::ostringstream content; + if (debDebPkgFileIndex::GetContent(content, debFileName) == false) + return false; + // add two newlines to make sure the scanner finds the section, + // which is usually done by pkgTagFile automatically if needed. + content << "\n\n"; + + controlContent = content.str(); + if (Section.Scan(controlContent.c_str(), controlContent.length()) == false) + return _error->Error(_("Unable to parse package file %s (%d)"), debFileName.c_str(), 3); + return true; +} +bool debDebFileRecordParser::Jump(pkgCache::VerFileIterator const &) { return LoadContent(); } +bool debDebFileRecordParser::Jump(pkgCache::DescFileIterator const &) { return LoadContent(); } +std::string debDebFileRecordParser::FileName() { return debFileName; } + +debDebFileRecordParser::debDebFileRecordParser(std::string FileName) : debRecordParserBase(), debFileName(FileName) {} +debDebFileRecordParser::~debDebFileRecordParser() {} diff --git a/apt-pkg/deb/debrecords.h b/apt-pkg/deb/debrecords.h index 6b5f94334..8efcec8cd 100644 --- a/apt-pkg/deb/debrecords.h +++ b/apt-pkg/deb/debrecords.h @@ -25,21 +25,13 @@ #include <apt-pkg/indexfile.h> #endif -class debRecordParser : public pkgRecords::Parser +class APT_HIDDEN debRecordParserBase : public pkgRecords::Parser { - /** \brief dpointer placeholder (for later in case we need it) */ void *d; - protected: - FileFd File; - pkgTagFile Tags; pkgTagSection Section; - - virtual bool Jump(pkgCache::VerFileIterator const &Ver); - virtual bool Jump(pkgCache::DescFileIterator const &Desc); - - public: + public: // These refer to the archive file for the Version virtual std::string FileName(); virtual std::string SourcePkg(); @@ -58,20 +50,44 @@ class debRecordParser : public pkgRecords::Parser virtual std::string RecordField(const char *fieldName); virtual void GetRec(const char *&Start,const char *&Stop); - + + debRecordParserBase(); + virtual ~debRecordParserBase(); +}; + +class APT_HIDDEN debRecordParser : public debRecordParserBase +{ + void *d; + protected: + FileFd File; + pkgTagFile Tags; + + virtual bool Jump(pkgCache::VerFileIterator const &Ver); + virtual bool Jump(pkgCache::DescFileIterator const &Desc); + + public: debRecordParser(std::string FileName,pkgCache &Cache); virtual ~debRecordParser(); }; // custom record parser that reads deb files directly -class debDebFileRecordParser : public debRecordParser +class APT_HIDDEN debDebFileRecordParser : public debRecordParserBase { + void *d; + std::string debFileName; + std::string controlContent; + + APT_HIDDEN bool LoadContent(); + protected: + // single file files, so no jumping whatsoever + bool Jump(pkgCache::VerFileIterator const &); + bool Jump(pkgCache::DescFileIterator const &); + public: - virtual std::string FileName() { - return File.Name(); - } - debDebFileRecordParser(std::string FileName,pkgCache &Cache) - : debRecordParser(FileName, Cache) {}; + virtual std::string FileName(); + + debDebFileRecordParser(std::string FileName); + virtual ~debDebFileRecordParser(); }; #endif diff --git a/apt-pkg/deb/debsrcrecords.cc b/apt-pkg/deb/debsrcrecords.cc index 97f43aca2..21a4ff8ea 100644 --- a/apt-pkg/deb/debsrcrecords.cc +++ b/apt-pkg/deb/debsrcrecords.cc @@ -32,6 +32,10 @@ using std::max; using std::string; +debSrcRecordParser::debSrcRecordParser(std::string const &File,pkgIndexFile const *Index) + : Parser(Index), Fd(File,FileFd::ReadOnly, FileFd::Extension), Tags(&Fd,102400), + iOffset(0), Buffer(NULL) {} + // SrcRecordParser::Binaries - Return the binaries field /*{{{*/ // --------------------------------------------------------------------- /* This member parses the binaries field into a pair of class arrays and @@ -121,9 +125,32 @@ bool debSrcRecordParser::BuildDepends(std::vector<pkgSrcRecords::Parser::BuildDe // --------------------------------------------------------------------- /* This parses the list of files and returns it, each file is required to have a complete source package */ -bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List) +bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &F) +{ + std::vector<pkgSrcRecords::File2> F2; + if (Files2(F2) == false) + return false; + for (std::vector<pkgSrcRecords::File2>::const_iterator f2 = F2.begin(); f2 != F2.end(); ++f2) + { + pkgSrcRecords::File2 f; +#if __GNUC__ >= 4 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + f.MD5Hash = f2->MD5Hash; + f.Size = f2->Size; +#if __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif + f.Path = f2->Path; + f.Type = f2->Type; + F.push_back(f); + } + return true; +} +bool debSrcRecordParser::Files2(std::vector<pkgSrcRecords::File2> &List) { - List.erase(List.begin(),List.end()); + List.clear(); // Stash the / terminated directory prefix string Base = Sect.FindS("Directory"); @@ -162,7 +189,7 @@ bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List) path = Base + path; // look if we have a record for this file already - std::vector<pkgSrcRecords::File>::iterator file = List.begin(); + std::vector<pkgSrcRecords::File2>::iterator file = List.begin(); for (; file != List.end(); ++file) if (file->Path == path) break; @@ -170,16 +197,8 @@ bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List) // we have it already, store the new hash and be done if (file != List.end()) { -#if __GNUC__ >= 4 - // set for compatibility only, so warn users not us - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif if (checksumField == "Files") - file->MD5Hash = hash; -#if __GNUC__ >= 4 - #pragma GCC diagnostic pop -#endif + APT_IGNORE_DEPRECATED(file->MD5Hash = hash;) // an error here indicates that we have two different hashes for the same file if (file->Hashes.push_back(hashString) == false) return _error->Error("Error parsing checksum in %s of source package %s", checksumField.c_str(), Package().c_str()); @@ -187,21 +206,16 @@ bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List) } // we haven't seen this file yet - pkgSrcRecords::File F; + pkgSrcRecords::File2 F; F.Path = path; - F.Size = strtoull(size.c_str(), NULL, 10); + F.FileSize = strtoull(size.c_str(), NULL, 10); F.Hashes.push_back(hashString); -#if __GNUC__ >= 4 - // set for compatibility only, so warn users not us - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif + APT_IGNORE_DEPRECATED_PUSH + F.Size = F.FileSize; if (checksumField == "Files") F.MD5Hash = hash; -#if __GNUC__ >= 4 - #pragma GCC diagnostic pop -#endif + APT_IGNORE_DEPRECATED_POP // Try to guess what sort of file it is we are getting. string::size_type Pos = F.Path.length()-1; diff --git a/apt-pkg/deb/debsrcrecords.h b/apt-pkg/deb/debsrcrecords.h index a0a151875..7aeb2db88 100644 --- a/apt-pkg/deb/debsrcrecords.h +++ b/apt-pkg/deb/debsrcrecords.h @@ -21,7 +21,7 @@ class pkgIndexFile; -class debSrcRecordParser : public pkgSrcRecords::Parser +class APT_HIDDEN debSrcRecordParser : public pkgSrcRecords::Parser { /** \brief dpointer placeholder (for later in case we need it) */ void *d; @@ -54,14 +54,13 @@ class debSrcRecordParser : public pkgSrcRecords::Parser return std::string(Start,Stop); }; virtual bool Files(std::vector<pkgSrcRecords::File> &F); + bool Files2(std::vector<pkgSrcRecords::File2> &F); - debSrcRecordParser(std::string const &File,pkgIndexFile const *Index) - : Parser(Index), Fd(File,FileFd::ReadOnly, FileFd::Extension), Tags(&Fd,102400), - iOffset(0), Buffer(NULL) {} + debSrcRecordParser(std::string const &File,pkgIndexFile const *Index); virtual ~debSrcRecordParser(); }; -class debDscRecordParser : public debSrcRecordParser +class APT_HIDDEN debDscRecordParser : public debSrcRecordParser { public: debDscRecordParser(std::string const &DscFile, pkgIndexFile const *Index); diff --git a/apt-pkg/deb/debsystem.cc b/apt-pkg/deb/debsystem.cc index 142f3a6e6..9a5da9da1 100644 --- a/apt-pkg/deb/debsystem.cc +++ b/apt-pkg/deb/debsystem.cc @@ -38,7 +38,7 @@ using std::string; debSystem debSys; -class debSystemPrivate { +class APT_HIDDEN debSystemPrivate { public: debSystemPrivate() : LockFD(-1), LockCount(0), StatusFile(0) { diff --git a/apt-pkg/deb/debversion.h b/apt-pkg/deb/debversion.h index 434ff4a2e..7befe6372 100644 --- a/apt-pkg/deb/debversion.h +++ b/apt-pkg/deb/debversion.h @@ -1,6 +1,5 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: debversion.h,v 1.3 2001/05/03 05:25:04 jgg Exp $ /* ###################################################################### Debian Version - Versioning system for Debian diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 0cded32e1..6ee939edd 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -72,7 +72,9 @@ class pkgDPkgPMPrivate public: pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0), term_out(NULL), history_out(NULL), - progress(NULL), master(-1), slave(NULL) + progress(NULL), tt_is_valid(false), master(-1), + slave(NULL), protect_slave_from_dying(-1), + direct_stdin(false) { dpkgbuf[0] = '\0'; } @@ -90,13 +92,16 @@ public: // pty stuff struct termios tt; + bool tt_is_valid; int master; char * slave; + int protect_slave_from_dying; // signals sigset_t sigmask; sigset_t original_sigmask; + bool direct_stdin; }; namespace @@ -198,18 +203,12 @@ pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg) { pkgCache::VerIterator Ver; for (Ver = Pkg.VersionList(); Ver.end() == false; ++Ver) - { - pkgCache::VerFileIterator Vf = Ver.FileList(); - pkgCache::PkgFileIterator F = Vf.File(); - for (F = Vf.File(); F.end() == false; ++F) - { - if (F && F.Archive()) - { - if (strcmp(F.Archive(), "now")) - return Ver; - } - } - } + for (pkgCache::VerFileIterator Vf = Ver.FileList(); Vf.end() == false; ++Vf) + for (pkgCache::PkgFileIterator F = Vf.File(); F.end() == false; ++F) + { + if (F.Archive() != 0 && strcmp(F.Archive(), "now") == 0) + return Ver; + } return Ver; } /*}}}*/ @@ -1044,6 +1043,12 @@ void pkgDPkgPM::BuildPackagesProgressMap() PackagesTotal++; } } + /* one extra: We don't want the progress bar to reach 100%, especially not + if we call dpkg --configure --pending and process a bunch of triggers + while showing 100%. Also, spindown takes a while, so never reaching 100% + is way more correct than reaching 100% while still doing stuff even if + doing it this way is slightly bending the rules */ + ++PackagesTotal; } /*}}}*/ bool pkgDPkgPM::Go(int StatusFd) @@ -1068,48 +1073,44 @@ void pkgDPkgPM::StartPtyMagic() return; } + if (isatty(STDIN_FILENO) == 0) + d->direct_stdin = true; + _error->PushToStack(); - // if tcgetattr for both stdin/stdout returns 0 (no error) - // we do the pty magic - if (tcgetattr(STDOUT_FILENO, &d->tt) == 0 && - tcgetattr(STDIN_FILENO, &d->tt) == 0) + + d->master = posix_openpt(O_RDWR | O_NOCTTY); + if (d->master == -1) + _error->Errno("posix_openpt", _("Can not write log (%s)"), _("Is /dev/pts mounted?")); + else if (unlockpt(d->master) == -1) + _error->Errno("unlockpt", "Unlocking the slave of master fd %d failed!", d->master); + else { - d->master = posix_openpt(O_RDWR | O_NOCTTY); - if (d->master == -1) - _error->Errno("posix_openpt", _("Can not write log (%s)"), _("Is /dev/pts mounted?")); - else if (unlockpt(d->master) == -1) - { - _error->Errno("unlockpt", "Unlocking the slave of master fd %d failed!", d->master); - close(d->master); - d->master = -1; - } + char const * const slave_name = ptsname(d->master); + if (slave_name == NULL) + _error->Errno("ptsname", "Getting name for slave of master fd %d failed!", d->master); else { - char const * const slave_name = ptsname(d->master); - if (slave_name == NULL) - { - _error->Errno("unlockpt", "Getting name for slave of master fd %d failed!", d->master); - close(d->master); - d->master = -1; - } - else + d->slave = strdup(slave_name); + if (d->slave == NULL) + _error->Errno("strdup", "Copying name %s for slave of master fd %d failed!", slave_name, d->master); + else if (grantpt(d->master) == -1) + _error->Errno("grantpt", "Granting access to slave %s based on master fd %d failed!", slave_name, d->master); + else if (tcgetattr(STDIN_FILENO, &d->tt) == 0) { - d->slave = strdup(slave_name); - if (d->slave == NULL) + d->tt_is_valid = true; + struct termios raw_tt; + // copy window size of stdout if its a 'good' terminal + if (tcgetattr(STDOUT_FILENO, &raw_tt) == 0) { - _error->Errno("strdup", "Copying name %s for slave of master fd %d failed!", slave_name, d->master); - close(d->master); - d->master = -1; + struct winsize win; + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) < 0) + _error->Errno("ioctl", "Getting TIOCGWINSZ from stdout failed!"); + if (ioctl(d->master, TIOCSWINSZ, &win) < 0) + _error->Errno("ioctl", "Setting TIOCSWINSZ for master fd %d failed!", d->master); } - struct winsize win; - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) < 0) - _error->Errno("ioctl", "Getting TIOCGWINSZ from stdout failed!"); - if (ioctl(d->master, TIOCSWINSZ, &win) < 0) - _error->Errno("ioctl", "Setting TIOCSWINSZ for master fd %d failed!", d->master); if (tcsetattr(d->master, TCSANOW, &d->tt) == -1) _error->Errno("tcsetattr", "Setting in Start via TCSANOW for master fd %d failed!", d->master); - struct termios raw_tt; raw_tt = d->tt; cfmakeraw(&raw_tt); raw_tt.c_lflag &= ~ECHO; @@ -1121,18 +1122,22 @@ void pkgDPkgPM::StartPtyMagic() sigaddset(&d->sigmask, SIGTTOU); sigprocmask(SIG_BLOCK,&d->sigmask, &d->original_sigmask); if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw_tt) == -1) - _error->Errno("tcsetattr", "Setting in Start via TCSAFLUSH for stdout failed!"); + _error->Errno("tcsetattr", "Setting in Start via TCSAFLUSH for stdin failed!"); sigprocmask(SIG_SETMASK, &d->original_sigmask, NULL); + + } + if (d->slave != NULL) + { + /* on linux, closing (and later reopening) all references to the slave + makes the slave a death end, so we open it here to have one open all + the time. We could use this fd in SetupSlavePtyMagic() for linux, but + on kfreebsd we get an incorrect ("step like") output then while it has + no problem with closing all references… so to avoid platform specific + code here we combine both and be happy once more */ + d->protect_slave_from_dying = open(d->slave, O_RDWR | O_CLOEXEC | O_NOCTTY); } } } - else - { - // complain only if stdout is either a terminal (but still failed) or is an invalid - // descriptor otherwise we would complain about redirection to e.g. /dev/null as well. - if (isatty(STDOUT_FILENO) == 1 || errno == EBADF) - _error->Errno("tcgetattr", _("Can not write log (%s)"), _("Is stdout a terminal?")); - } if (_error->PendingError() == true) { @@ -1141,44 +1146,60 @@ void pkgDPkgPM::StartPtyMagic() close(d->master); d->master = -1; } + if (d->slave != NULL) + { + free(d->slave); + d->slave = NULL; + } _error->DumpErrors(std::cerr); } _error->RevertToStack(); } void pkgDPkgPM::SetupSlavePtyMagic() { - if(d->master == -1) + if(d->master == -1 || d->slave == NULL) return; if (close(d->master) == -1) _error->FatalE("close", "Closing master %d in child failed!", d->master); + d->master = -1; if (setsid() == -1) _error->FatalE("setsid", "Starting a new session for child failed!"); - int const slaveFd = open(d->slave, O_RDWR); + int const slaveFd = open(d->slave, O_RDWR | O_NOCTTY); if (slaveFd == -1) _error->FatalE("open", _("Can not write log (%s)"), _("Is /dev/pts mounted?")); - - if (ioctl(slaveFd, TIOCSCTTY, 0) < 0) + else if (ioctl(slaveFd, TIOCSCTTY, 0) < 0) _error->FatalE("ioctl", "Setting TIOCSCTTY for slave fd %d failed!", slaveFd); else { - for (unsigned short i = 0; i < 3; ++i) + unsigned short i = 0; + if (d->direct_stdin == true) + ++i; + for (; i < 3; ++i) if (dup2(slaveFd, i) == -1) _error->FatalE("dup2", "Dupping %d to %d in child failed!", slaveFd, i); - if (tcsetattr(0, TCSANOW, &d->tt) < 0) + if (d->tt_is_valid == true && tcsetattr(STDIN_FILENO, TCSANOW, &d->tt) < 0) _error->FatalE("tcsetattr", "Setting in Setup via TCSANOW for slave fd %d failed!", slaveFd); } + + if (slaveFd != -1) + close(slaveFd); } void pkgDPkgPM::StopPtyMagic() { if (d->slave != NULL) free(d->slave); d->slave = NULL; + if (d->protect_slave_from_dying != -1) + { + close(d->protect_slave_from_dying); + d->protect_slave_from_dying = -1; + } if(d->master >= 0) { - if (tcsetattr(0, TCSAFLUSH, &d->tt) == -1) + if (d->tt_is_valid == true && tcsetattr(STDIN_FILENO, TCSAFLUSH, &d->tt) == -1) _error->FatalE("tcsetattr", "Setting in Stop via TCSAFLUSH for stdin failed!"); close(d->master); d->master = -1; @@ -1261,9 +1282,8 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) // support subpressing of triggers processing for special // cases like d-i that runs the triggers handling manually - bool const SmartConf = (_config->Find("PackageManager::Configure", "all") != "all"); bool const TriggersPending = _config->FindB("DPkg::TriggersPending", false); - if (_config->FindB("DPkg::ConfigurePending", SmartConf) == true) + if (_config->FindB("DPkg::ConfigurePending", true) == true) List.push_back(Item(Item::ConfigurePending, PkgIterator())); // for the progress @@ -1572,8 +1592,8 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) // wait for input or output here FD_ZERO(&rfds); - if (d->master >= 0 && !d->stdin_is_dev_null) - FD_SET(0, &rfds); + if (d->master >= 0 && d->direct_stdin == false && d->stdin_is_dev_null == false) + FD_SET(STDIN_FILENO, &rfds); FD_SET(_dpkgin, &rfds); if(d->master >= 0) FD_SET(d->master, &rfds); @@ -1684,7 +1704,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) if (apportPkg.end() == true || apportPkg->CurrentVer == 0) return; - string pkgname, reportfile, srcpkgname, pkgver, arch; + string pkgname, reportfile, pkgver, arch; string::size_type pos; FILE *report; @@ -1823,7 +1843,16 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) time_t now = time(NULL); fprintf(report, "Date: %s" , ctime(&now)); fprintf(report, "Package: %s %s\n", pkgname.c_str(), pkgver.c_str()); +#if APT_PKG_ABI >= 413 fprintf(report, "SourcePackage: %s\n", Ver.SourcePkgName()); +#else + pkgRecords Recs(Cache); + pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); + std::string srcpkgname = Parse.SourcePkg(); + if(srcpkgname.empty()) + srcpkgname = pkgname; + fprintf(report, "SourcePackage: %s\n", srcpkgname.c_str()); +#endif fprintf(report, "ErrorMessage:\n %s\n", errormsg); // ensure that the log is flushed @@ -1863,8 +1892,15 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) } } - // log the ordering - const char *ops_str[] = {"Install", "Configure","Remove","Purge"}; + // log the ordering, see dpkgpm.h and the "Ops" enum there + const char *ops_str[] = { + "Install", + "Configure", + "Remove", + "Purge", + "ConfigurePending", + "TriggersPending", + }; fprintf(report, "AptOrdering:\n"); for (vector<Item>::iterator I = List.begin(); I != List.end(); ++I) if ((*I).Pkg != NULL) |