X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/893d3e85b98124fc28002be5584b685324646037..8d0d92558c00d1825e413ce67be51a46a5c18aea:/apt-pkg/deb/debindexfile.cc diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index ed7633803..84dabc06b 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -9,46 +9,41 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ +#include <config.h> + #include <apt-pkg/debindexfile.h> #include <apt-pkg/debsrcrecords.h> #include <apt-pkg/deblistparser.h> #include <apt-pkg/debrecords.h> -#include <apt-pkg/sourcelist.h> #include <apt-pkg/configuration.h> -#include <apt-pkg/progress.h> #include <apt-pkg/error.h> -#include <apt-pkg/strutl.h> -#include <apt-pkg/acquire-item.h> -#include <apt-pkg/debmetaindex.h> +#include <apt-pkg/fileutl.h> +#include <apt-pkg/indexfile.h> +#include <apt-pkg/pkgcache.h> +#include <apt-pkg/cacheiterators.h> +#include <apt-pkg/pkgrecords.h> +#include <apt-pkg/srcrecords.h> + +#include <stdio.h> +#include <iostream> +#include <string> +#include <sstream> #include <sys/stat.h> /*}}}*/ -// SourcesIndex::debSourcesIndex - Constructor /*{{{*/ -// --------------------------------------------------------------------- -/* */ -debSourcesIndex::debSourcesIndex(string URI,string Dist,string Section,bool Trusted) : - pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section) +// Sources Index /*{{{*/ +debSourcesIndex::debSourcesIndex(IndexTarget const &Target,bool const Trusted) : + pkgDebianIndexTargetFile(Target, Trusted), d(NULL) { } - /*}}}*/ -// SourcesIndex::SourceInfo - Short 1 liner describing a source /*{{{*/ -// --------------------------------------------------------------------- -/* The result looks like: - http://foo/ stable/main src 1.1.1 (dsc) */ -string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record, +std::string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record, pkgSrcRecords::File const &File) const { - string Res; - Res = ::URI::SiteOnly(URI) + ' '; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Res += Dist; - } - else - Res += Dist + '/' + Section; - + // The result looks like: http://foo/debian/ stable/main src 1.1.1 (dsc) + std::string Res = Target.Description; + Res.erase(Target.Description.rfind(' ')); + Res += " "; Res += Record.Package(); Res += " "; @@ -57,544 +52,350 @@ string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record, Res += " (" + File.Type + ")"; return Res; } - /*}}}*/ -// SourcesIndex::CreateSrcParser - Get a parser for the source files /*{{{*/ -// --------------------------------------------------------------------- -/* */ pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const { - string SourcesURI = URItoFileName(IndexURI("Sources")); - return new debSrcRecordParser(_config->FindDir("Dir::State::lists") + - SourcesURI,this); + std::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 +bool debSourcesIndex::OpenListFile(FileFd &, std::string const &) { - string Info = ::URI::SiteOnly(URI) + ' '; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Info += Dist; - } - else - Info += Dist + '/' + Section; - Info += " "; - Info += Type; - return Info; + return true; } - /*}}}*/ -// SourcesIndex::Index* - Return the URI to the index files /*{{{*/ -// --------------------------------------------------------------------- -/* */ -inline string debSourcesIndex::IndexFile(const char *Type) const +pkgCacheListParser * debSourcesIndex::CreateListParser(FileFd &) { - return URItoFileName(IndexURI(Type)); + return NULL; } -string debSourcesIndex::IndexURI(const char *Type) const +uint8_t debSourcesIndex::GetIndexFlags() 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; + return 0; } /*}}}*/ -// SourcesIndex::Exists - Check if the index is available /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool debSourcesIndex::Exists() const +// Packages Index /*{{{*/ +debPackagesIndex::debPackagesIndex(IndexTarget const &Target, bool const Trusted) : + pkgDebianIndexTargetFile(Target, Trusted), d(NULL) { - return FileExists(IndexFile("Sources")); } - /*}}}*/ -// SourcesIndex::Size - Return the size of the index /*{{{*/ -// --------------------------------------------------------------------- -/* */ -unsigned long debSourcesIndex::Size() const +std::string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator const &Ver) const { - struct stat S; - if (stat(IndexFile("Sources").c_str(),&S) != 0) - return 0; - return S.st_size; -} - /*}}}*/ + std::string Res = Target.Description; + Res.erase(Target.Description.rfind(' ')); -// PackagesIndex::debPackagesIndex - Contructor /*{{{*/ -// --------------------------------------------------------------------- -/* */ -debPackagesIndex::debPackagesIndex(string URI,string Dist,string Section,bool Trusted) : - pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section) -{ -} - /*}}}*/ -// PackagesIndex::ArchiveInfo - Short version of the archive url /*{{{*/ -// --------------------------------------------------------------------- -/* This is a shorter version that is designed to be < 60 chars or so */ -string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const -{ - string Res = ::URI::SiteOnly(URI) + ' '; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Res += Dist; - } - else - Res += Dist + '/' + Section; - Res += " "; Res += Ver.ParentPkg().Name(); Res += " "; + std::string const Dist = Target.Option(IndexTarget::RELEASE); + 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; +uint8_t debPackagesIndex::GetIndexFlags() const +{ + return 0; } /*}}}*/ -// PackagesIndex::Info - One liner describing the index URI /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debPackagesIndex::Info(const char *Type) const +// Translation-* Index /*{{{*/ +debTranslationsIndex::debTranslationsIndex(IndexTarget const &Target) : + pkgDebianIndexTargetFile(Target, true), d(NULL) +{} +bool debTranslationsIndex::HasPackages() const { - string Info = ::URI::SiteOnly(URI) + ' '; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Info += Dist; - } - else - Info += Dist + '/' + Section; - Info += " "; - Info += Type; - return Info; + return Exists(); } - /*}}}*/ -// PackagesIndex::Index* - Return the URI to the index files /*{{{*/ -// --------------------------------------------------------------------- -/* */ -inline string debPackagesIndex::IndexFile(const char *Type) const +bool debTranslationsIndex::OpenListFile(FileFd &Pkg, std::string const &FileName) { - return _config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type)); + if (FileExists(FileName)) + return pkgDebianIndexTargetFile::OpenListFile(Pkg, FileName); + return true; } -string debPackagesIndex::IndexURI(const char *Type) const +uint8_t debTranslationsIndex::GetIndexFlags() const { - string Res; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Res = URI + Dist; - else - Res = URI; - } - else - Res = URI + "dists/" + Dist + '/' + Section + - "/binary-" + _config->Find("APT::Architecture") + '/'; - - Res += Type; - return Res; + return pkgCache::Flag::NotSource | pkgCache::Flag::NoPackages; } - /*}}}*/ -// PackagesIndex::Exists - Check if the index is available /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool debPackagesIndex::Exists() const +std::string debTranslationsIndex::GetArchitecture() const { - return FileExists(IndexFile("Packages")); + return std::string(); +} +pkgCacheListParser * debTranslationsIndex::CreateListParser(FileFd &Pkg) +{ + if (Pkg.IsOpen() == false) + return NULL; + _error->PushToStack(); + pkgCacheListParser * const Parser = new debTranslationsParser(&Pkg); + bool const newError = _error->PendingError(); + _error->MergeWithStack(); + return newError ? NULL : Parser; } /*}}}*/ -// PackagesIndex::Size - Return the size of the index /*{{{*/ -// --------------------------------------------------------------------- -/* This is really only used for progress reporting. */ -unsigned long debPackagesIndex::Size() const +// dpkg/status Index /*{{{*/ +debStatusIndex::debStatusIndex(std::string const &File) : pkgDebianIndexRealFile(File, true), d(NULL) +{ +} +std::string debStatusIndex::GetArchitecture() const +{ + return std::string(); +} +std::string debStatusIndex::GetComponent() const +{ + return "now"; +} +uint8_t debStatusIndex::GetIndexFlags() const +{ + return pkgCache::Flag::NotSource; +} + +pkgCacheListParser * debStatusIndex::CreateListParser(FileFd &Pkg) { - struct stat S; - if (stat(IndexFile("Packages").c_str(),&S) != 0) - return 0; - return S.st_size; + if (Pkg.IsOpen() == false) + return NULL; + _error->PushToStack(); + pkgCacheListParser * const Parser = new debStatusListParser(&Pkg); + bool const newError = _error->PendingError(); + _error->MergeWithStack(); + return newError ? NULL : Parser; } /*}}}*/ -// PackagesIndex::Merge - Load the index file into a cache /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const -{ - string PackageFile = IndexFile("Packages"); - FileFd Pkg(PackageFile,FileFd::ReadOnly); - debListParser Parser(&Pkg); - if (_error->PendingError() == true) - return _error->Error("Problem opening %s",PackageFile.c_str()); - - Prog.SubProgress(0,Info("Packages")); - ::URI Tmp(URI); - if (Gen.SelectFile(PackageFile,Tmp.Host,*this) == false) - return _error->Error("Problem with SelectFile %s",PackageFile.c_str()); +// DebPkgFile Index - a single .deb file as an index /*{{{*/ +debDebPkgFileIndex::debDebPkgFileIndex(std::string const &DebFile) + : pkgDebianIndexRealFile(DebFile, true), d(NULL), DebFile(DebFile) +{ +} +bool debDebPkgFileIndex::GetContent(std::ostream &content, std::string const &debfile) +{ + struct stat Buf; + if (stat(debfile.c_str(), &Buf) != 0) + return false; - // Store the IMS information - pkgCache::PkgFileIterator File = Gen.GetCurFile(); - struct stat St; - if (fstat(Pkg.Fd(),&St) != 0) - return _error->Errno("fstat","Failed to stat"); - File->Size = St.st_size; - File->mtime = St.st_mtime; - - if (Gen.MergeList(Parser) == false) - return _error->Error("Problem with MergeList %s",PackageFile.c_str()); + // 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()); + Args.push_back("-I"); + 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"); + + content << "Filename: " << debfile << "\n"; + content << "Size: " << Buf.st_size << "\n"; + bool first_line_seen = false; + 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'; + char const * b = buffer; + if (first_line_seen == false) + { + for (; *b != '\0' && (*b == '\n' || *b == '\r'); ++b) + /* skip over leading newlines */; + if (*b == '\0') + continue; + first_line_seen = true; + } + content << b; + } while(true); + ExecWait(Child, "Popen"); - // Check the release file - string ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("Release"); - if (FileExists(ReleaseFile) == true) - { - FileFd Rel(ReleaseFile,FileFd::ReadOnly); - if (_error->PendingError() == true) - return false; - Parser.LoadReleaseInfo(File,Rel,Section); - } - return true; } - /*}}}*/ -// PackagesIndex::FindInCache - Find this index /*{{{*/ -// --------------------------------------------------------------------- -/* */ -pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const +bool debDebPkgFileIndex::OpenListFile(FileFd &Pkg, std::string const &FileName) +{ + // write the control data to a tempfile + if (GetTempFile("deb-file-" + flNotDir(FileName), true, &Pkg) == NULL) + return false; + std::ostringstream content; + if (GetContent(content, FileName) == false) + return false; + std::string const contentstr = content.str(); + if (contentstr.empty()) + return true; + if (Pkg.Write(contentstr.c_str(), contentstr.length()) == false || Pkg.Seek(0) == false) + return false; + return true; +} +pkgCacheListParser * debDebPkgFileIndex::CreateListParser(FileFd &Pkg) +{ + if (Pkg.IsOpen() == false) + return NULL; + _error->PushToStack(); + pkgCacheListParser * const Parser = new debDebFileParser(&Pkg, DebFile); + bool const newError = _error->PendingError(); + _error->MergeWithStack(); + return newError ? NULL : Parser; +} +uint8_t debDebPkgFileIndex::GetIndexFlags() const { - string FileName = IndexFile("Packages"); + return pkgCache::Flag::LocalSource; +} +std::string debDebPkgFileIndex::GetArchitecture() const +{ + return std::string(); +} +std::string debDebPkgFileIndex::GetComponent() const +{ + return "local-deb"; +} +pkgCache::PkgFileIterator debDebPkgFileIndex::FindInCache(pkgCache &Cache) const +{ + std::string const FileName = IndexFileName(); pkgCache::PkgFileIterator File = Cache.FileBegin(); - for (; File.end() == false; File++) + for (; File.end() == false; ++File) { if (File.FileName() == NULL || FileName != File.FileName()) continue; - - struct stat St; - if (stat(File.FileName(),&St) != 0) - return pkgCache::PkgFileIterator(Cache); - if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime) - return pkgCache::PkgFileIterator(Cache); + // we can't do size checks here as file size != content size return File; } - + return File; } - /*}}}*/ - -// TranslationsIndex::debTranslationsIndex - Contructor /*{{{*/ -// --------------------------------------------------------------------- -/* */ -debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section) : - pkgIndexFile(true), URI(URI), Dist(Dist), Section(Section) +std::string debDebPkgFileIndex::ArchiveInfo_impl(pkgCache::VerIterator const &Ver) const { + std::string Res = IndexFileName() + " "; + Res.append(Ver.ParentPkg().Name()).append(" "); + Res.append(Ver.Arch()).append(" "); + Res.append(Ver.VerStr()); + return Res; } /*}}}*/ -// TranslationIndex::Trans* - Return the URI to the translation files /*{{{*/ -// --------------------------------------------------------------------- -/* */ -inline string debTranslationsIndex::IndexFile(const char *Type) const +// DscFile Index - a single .dsc file as an index /*{{{*/ +debDscFileIndex::debDscFileIndex(std::string const &DscFile) + : pkgDebianIndexRealFile(DscFile, true), d(NULL) { - return _config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type)); } -string debTranslationsIndex::IndexURI(const char *Type) const +pkgSrcRecords::Parser *debDscFileIndex::CreateSrcParser() 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::GetIndexes - Fetch the index files /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool debTranslationsIndex::GetIndexes(pkgAcquire *Owner) const -{ - if (TranslationsAvailable()) { - string TranslationFile = "Translation-" + LanguageCode(); - new pkgAcqIndexTrans(Owner, IndexURI(LanguageCode().c_str()), - Info(TranslationFile.c_str()), - TranslationFile); - } - - return true; + if (Exists() == false) + return NULL; + return new debDscRecordParser(File, this); } - /*}}}*/ -// 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(LanguageCode().c_str()).c_str()); - return S; -} - /*}}}*/ -// TranslationsIndex::Info - One liner describing the index URI /*{{{*/ -// --------------------------------------------------------------------- -/* */ -string debTranslationsIndex::Info(const char *Type) const +std::string debDscFileIndex::GetComponent() const { - string Info = ::URI::SiteOnly(URI) + ' '; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Info += Dist; - } - else - Info += Dist + '/' + Section; - Info += " "; - Info += Type; - return Info; + return "local-dsc"; } - /*}}}*/ -bool debTranslationsIndex::HasPackages() const +std::string debDscFileIndex::GetArchitecture() const { - if(!TranslationsAvailable()) - return false; - - return FileExists(IndexFile(LanguageCode().c_str())); + return "source"; } - -// TranslationsIndex::Exists - Check if the index is available /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool debTranslationsIndex::Exists() const +uint8_t debDscFileIndex::GetIndexFlags() const { - return FileExists(IndexFile(LanguageCode().c_str())); + return pkgCache::Flag::LocalSource; } /*}}}*/ -// TranslationsIndex::Size - Return the size of the index /*{{{*/ -// --------------------------------------------------------------------- -/* This is really only used for progress reporting. */ -unsigned long debTranslationsIndex::Size() const +// ControlFile Index - a directory with a debian/control file /*{{{*/ +std::string debDebianSourceDirIndex::GetComponent() const { - struct stat S; - if (stat(IndexFile(LanguageCode().c_str()).c_str(),&S) != 0) - return 0; - return S.st_size; + return "local-control"; } /*}}}*/ -// TranslationsIndex::Merge - Load the index file into a cache /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const -{ - // Check the translation file, if in use - string TranslationFile = IndexFile(LanguageCode().c_str()); - if (TranslationsAvailable() && FileExists(TranslationFile)) - { - FileFd Trans(TranslationFile,FileFd::ReadOnly); - debListParser TransParser(&Trans); - if (_error->PendingError() == true) - return false; - - Prog.SubProgress(0, Info(TranslationFile.c_str())); - if (Gen.SelectFile(TranslationFile,string(),*this) == false) - return _error->Error("Problem with SelectFile %s",TranslationFile.c_str()); - - // Store the IMS information - pkgCache::PkgFileIterator TransFile = Gen.GetCurFile(); - struct stat TransSt; - if (fstat(Trans.Fd(),&TransSt) != 0) - return _error->Errno("fstat","Failed to stat"); - TransFile->Size = TransSt.st_size; - TransFile->mtime = TransSt.st_mtime; - - if (Gen.MergeList(TransParser) == false) - return _error->Error("Problem with MergeList %s",TranslationFile.c_str()); - } - - return true; -} - /*}}}*/ -// TranslationsIndex::FindInCache - Find this index /*{{{*/ -// --------------------------------------------------------------------- -/* */ -pkgCache::PkgFileIterator debTranslationsIndex::FindInCache(pkgCache &Cache) const +// String Package Index - a string of Packages file content /*{{{*/ +std::string debStringPackageIndex::GetArchitecture() const { - string FileName = IndexFile(LanguageCode().c_str()); - - pkgCache::PkgFileIterator File = Cache.FileBegin(); - for (; File.end() == false; File++) - { - if (FileName != File.FileName()) - continue; - - struct stat St; - if (stat(File.FileName(),&St) != 0) - return pkgCache::PkgFileIterator(Cache); - if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime) - return pkgCache::PkgFileIterator(Cache); - return File; - } - return File; + return std::string(); } - /*}}}*/ -// StatusIndex::debStatusIndex - Constructor /*{{{*/ -// --------------------------------------------------------------------- -/* */ -debStatusIndex::debStatusIndex(string File) : pkgIndexFile(true), File(File) +std::string debStringPackageIndex::GetComponent() const { + return "apt-tmp-index"; } - /*}}}*/ -// StatusIndex::Size - Return the size of the index /*{{{*/ -// --------------------------------------------------------------------- -/* */ -unsigned long debStatusIndex::Size() const +uint8_t debStringPackageIndex::GetIndexFlags() const { - struct stat S; - if (stat(File.c_str(),&S) != 0) - return 0; - return S.st_size; + return pkgCache::Flag::NotSource; } - /*}}}*/ -// StatusIndex::Merge - Load the index file into a cache /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const +const pkgIndexFile::Type *debStringPackageIndex::GetType() const { - FileFd Pkg(File,FileFd::ReadOnly); - if (_error->PendingError() == true) - return false; - debListParser Parser(&Pkg); - if (_error->PendingError() == true) - return false; - - Prog.SubProgress(0,File); - if (Gen.SelectFile(File,string(),*this,pkgCache::Flag::NotSource) == false) - return _error->Error("Problem with SelectFile %s",File.c_str()); - - // Store the IMS information - pkgCache::PkgFileIterator CFile = Gen.GetCurFile(); - struct stat St; - if (fstat(Pkg.Fd(),&St) != 0) - return _error->Errno("fstat","Failed to stat"); - CFile->Size = St.st_size; - CFile->mtime = St.st_mtime; - CFile->Archive = Gen.WriteUniqString("now"); - - if (Gen.MergeList(Parser) == false) - return _error->Error("Problem with MergeList %s",File.c_str()); - return true; + return pkgIndexFile::Type::GetType("Debian Package Index"); } - /*}}}*/ -// StatusIndex::FindInCache - Find this index /*{{{*/ -// --------------------------------------------------------------------- -/* */ -pkgCache::PkgFileIterator debStatusIndex::FindInCache(pkgCache &Cache) const +debStringPackageIndex::debStringPackageIndex(std::string const &content) : + pkgDebianIndexRealFile("", false), d(NULL) { - pkgCache::PkgFileIterator File = Cache.FileBegin(); - for (; File.end() == false; File++) - { - if (this->File != File.FileName()) - continue; - - struct stat St; - if (stat(File.FileName(),&St) != 0) - return pkgCache::PkgFileIterator(Cache); - if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime) - return pkgCache::PkgFileIterator(Cache); - return File; - } - return File; + char fn[1024]; + std::string const tempdir = GetTempDir(); + snprintf(fn, sizeof(fn), "%s/%s.XXXXXX", tempdir.c_str(), "apt-tmp-index"); + int const fd = mkstemp(fn); + File = fn; + FileFd::Write(fd, content.data(), content.length()); + close(fd); } - /*}}}*/ -// StatusIndex::Exists - Check if the index is available /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool debStatusIndex::Exists() const +debStringPackageIndex::~debStringPackageIndex() { - // Abort if the file does not exist. - return true; + RemoveFile("~debStringPackageIndex", File); } /*}}}*/ // 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: - - virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const + virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE { return new debRecordParser(File.FileName(),*File.Cache()); }; 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: - - virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const + virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE { return new debRecordParser(File.FileName(),*File.Cache()); }; debIFTypeStatus() {Label = "Debian dpkg status file";}; }; -static debIFTypeSrc _apt_Src; -static debIFTypePkg _apt_Pkg; -static debIFTypeTrans _apt_Trans; -static debIFTypeStatus _apt_Status; +class APT_HIDDEN debIFTypeDebPkgFile : public pkgIndexFile::Type +{ + public: + virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE + { + return new debDebFileRecordParser(File.FileName()); + }; + debIFTypeDebPkgFile() {Label = "Debian deb file";}; +}; +class APT_HIDDEN debIFTypeDscFile : public pkgIndexFile::Type +{ + public: + virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string const &DscFile) const APT_OVERRIDE + { + return new debDscRecordParser(DscFile, NULL); + }; + debIFTypeDscFile() {Label = "Debian dsc file";}; +}; +class APT_HIDDEN debIFTypeDebianSourceDir : public pkgIndexFile::Type +{ + public: + virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string const &SourceDir) const APT_OVERRIDE + { + return new debDscRecordParser(SourceDir + std::string("/debian/control"), NULL); + }; + debIFTypeDebianSourceDir() {Label = "Debian control file";}; +}; + +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 +APT_HIDDEN debIFTypeDscFile _apt_DscFile; +APT_HIDDEN debIFTypeDebianSourceDir _apt_DebianSourceDir; const pkgIndexFile::Type *debSourcesIndex::GetType() const { @@ -612,5 +413,24 @@ const pkgIndexFile::Type *debStatusIndex::GetType() const { return &_apt_Status; } - +const pkgIndexFile::Type *debDebPkgFileIndex::GetType() const +{ + return &_apt_DebPkgFile; +} +const pkgIndexFile::Type *debDscFileIndex::GetType() const +{ + return &_apt_DscFile; +} +const pkgIndexFile::Type *debDebianSourceDirIndex::GetType() const +{ + return &_apt_DebianSourceDir; +} /*}}}*/ + +debStatusIndex::~debStatusIndex() {} +debPackagesIndex::~debPackagesIndex() {} +debTranslationsIndex::~debTranslationsIndex() {} +debSourcesIndex::~debSourcesIndex() {} + +debDebPkgFileIndex::~debDebPkgFileIndex() {} +debDscFileIndex::~debDscFileIndex() {}