From 0d29b9d4368284782862c7b507c47002b79ddb27 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 26 Apr 2014 00:00:51 +0200 Subject: WIP local deb install --- apt-pkg/deb/debindexfile.cc | 105 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) (limited to 'apt-pkg/deb/debindexfile.cc') diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index eee758b7a..f9864c67b 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -667,6 +668,95 @@ APT_CONST bool debStatusIndex::Exists() const } /*}}}*/ +// debDebPkgFile - Single .deb file /*{{{*/ +// --------------------------------------------------------------------- +debDebPkgFileIndex::debDebPkgFileIndex(std::string DebFile) + : pkgIndexFile(true), DebFile(DebFile) +{ + // FIXME: we need to os.normpath(DebFile) here, this is a lame workaround + DebFileFullPath = SafeGetCWD() + DebFile; +} + +std::string debDebPkgFileIndex::ArchiveURI(std::string /*File*/) const +{ + return "file:" + DebFileFullPath; +} + +bool debDebPkgFileIndex::Exists() const +{ + return FileExists(DebFile); +} +bool debDebPkgFileIndex::Merge(pkgCacheGenerator& Gen, OpProgress* Prog) const +{ + if(Prog) + Prog->SubProgress(0, "Reading deb file"); + + // get the control data out of the deb file vid dpkg -I + // ... can I haz libdpkg? + string cmd; + // FIXME: shell injection + strprintf(cmd, "dpkg -I %s control", DebFile.c_str()); + FILE *p = popen(cmd.c_str(), "r"); + if (p == NULL) + return _error->Error("popen failed"); + // FIXME: static buffer + char buf[8*1024]; + size_t n = fread(buf, 1, sizeof(buf)-1, p); + if (n == 0) + return _error->Errno("popen", "Failed to read dpkg pipe"); + pclose(p); + + // now write the control data to a tempfile + SPtr DebControl = GetTempFile("deb-file-" + 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 + DebControl->Seek(0); + + // and give it to the list parser + debDebFileParser Parser(DebControl, DebFile); + if(Gen.SelectFile(DebFile, "local", *this) == 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()); + + return true; +} +pkgCache::PkgFileIterator debDebPkgFileIndex::FindInCache(pkgCache &Cache) const +{ + // FIXME: we could simply always return pkgCache::PkgFileIterator(Cache); + // to indicate its never in the cache which will force a Merge() + pkgCache::PkgFileIterator File = Cache.FileBegin(); + for (; File.end() == false; ++File) + { + if (File.FileName() == NULL || DebFile != File.FileName()) + continue; + + return File; + } + + return File; +} +unsigned long debDebPkgFileIndex::Size() const +{ + struct stat buf; + if(stat(DebFile.c_str(), &buf) != 0) + return 0; + return buf.st_size; +} + /*}}}*/ + // Index File types for Debian /*{{{*/ class debIFTypeSrc : public pkgIndexFile::Type { @@ -699,10 +789,20 @@ class debIFTypeStatus : public pkgIndexFile::Type }; debIFTypeStatus() {Label = "Debian dpkg status file";}; }; +class debIFTypeDebPkgFile : public pkgIndexFile::Type +{ + public: + virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const + { + return new debDebFileRecordParser(File.FileName(),*File.Cache()); + }; + debIFTypeDebPkgFile() {Label = "deb Package file";}; +}; static debIFTypeSrc _apt_Src; static debIFTypePkg _apt_Pkg; static debIFTypeTrans _apt_Trans; static debIFTypeStatus _apt_Status; +static debIFTypeDebPkgFile _apt_DebPkgFile; const pkgIndexFile::Type *debSourcesIndex::GetType() const { @@ -720,5 +820,8 @@ const pkgIndexFile::Type *debStatusIndex::GetType() const { return &_apt_Status; } - +const pkgIndexFile::Type *debDebPkgFileIndex::GetType() const +{ + return &_apt_DebPkgFile; +} /*}}}*/ -- cgit v1.2.3