summaryrefslogtreecommitdiff
path: root/apt-pkg/deb
diff options
context:
space:
mode:
authorMichael Vogt <mvo@debian.org>2014-05-07 18:10:52 +0200
committerMichael Vogt <mvo@debian.org>2014-05-07 18:10:52 +0200
commit00026265672f2663e0aa0ab1a3fa7333f718a643 (patch)
tree841fc7de4952b7ac0f535555ff8ddbce752b955e /apt-pkg/deb
parent38d2959ffb8c6f5f291b2910014a67b1b352ab4c (diff)
parentaaf677da5b62d3d0fdeb26f9b4c63fed544b63cd (diff)
downloadapt-00026265672f2663e0aa0ab1a3fa7333f718a643.tar.gz
Merge remote-tracking branch 'mvo/feature/apt-install-deb' into debian/experimental
Diffstat (limited to 'apt-pkg/deb')
-rw-r--r--apt-pkg/deb/debindexfile.cc107
-rw-r--r--apt-pkg/deb/debindexfile.h31
-rw-r--r--apt-pkg/deb/deblistparser.cc20
-rw-r--r--apt-pkg/deb/deblistparser.h15
-rw-r--r--apt-pkg/deb/debmetaindex.cc29
-rw-r--r--apt-pkg/deb/debmetaindex.h24
-rw-r--r--apt-pkg/deb/debrecords.h18
7 files changed, 236 insertions, 8 deletions
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc
index eee758b7a..86ef92bfb 100644
--- a/apt-pkg/deb/debindexfile.cc
+++ b/apt-pkg/deb/debindexfile.cc
@@ -30,6 +30,7 @@
#include <apt-pkg/pkgcachegen.h>
#include <apt-pkg/pkgrecords.h>
#include <apt-pkg/srcrecords.h>
+#include <apt-pkg/sptr.h>
#include <stdio.h>
#include <iostream>
@@ -667,6 +668,97 @@ APT_CONST bool debStatusIndex::Exists() const
}
/*}}}*/
+// debDebPkgFile - Single .deb file /*{{{*/
+// ---------------------------------------------------------------------
+debDebPkgFileIndex::debDebPkgFileIndex(std::string DebFile)
+ : pkgIndexFile(true), DebFile(DebFile)
+{
+ DebFileFullPath = flAbsPath(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?
+ const char *Args[5] = {"/usr/bin/dpkg",
+ "-I",
+ DebFile.c_str(),
+ "control",
+ NULL};
+ FileFd PipeFd;
+ pid_t Child;
+ if(Popen(Args, 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");
+ ExecWait(Child, "Popen");
+
+ // now write the control data to a tempfile
+ SPtr<FileFd> 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 +791,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 +822,8 @@ const pkgIndexFile::Type *debStatusIndex::GetType() const
{
return &_apt_Status;
}
-
+const pkgIndexFile::Type *debDebPkgFileIndex::GetType() const
+{
+ return &_apt_DebPkgFile;
+}
/*}}}*/
diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h
index 017c69a0a..69754e79d 100644
--- a/apt-pkg/deb/debindexfile.h
+++ b/apt-pkg/deb/debindexfile.h
@@ -164,4 +164,35 @@ class debSourcesIndex : public pkgIndexFile
virtual ~debSourcesIndex() {};
};
+class debDebPkgFileIndex : public pkgIndexFile
+{
+ private:
+ void *d;
+ std::string DebFile;
+ std::string DebFileFullPath;
+
+ public:
+ virtual const Type *GetType() const APT_CONST;
+
+ virtual std::string Describe(bool /*Short*/) const {
+ return DebFile;
+ }
+
+ // 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;
+
+ // Interface for acquire
+ virtual std::string ArchiveURI(std::string /*File*/) const;
+
+ debDebPkgFileIndex(std::string DebFile);
+ virtual ~debDebPkgFileIndex() {};
+
+};
+
#endif
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index a1bcfb710..d5e3ccb65 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -959,3 +959,23 @@ bool debListParser::SameVersion(unsigned short const Hash, /*{{{*/
}
/*}}}*/
#endif
+
+
+debDebFileParser::debDebFileParser(FileFd *File, std::string const &DebFile)
+ : debListParser(File, ""), DebFile(DebFile)
+{
+}
+
+bool debDebFileParser::UsePackage(pkgCache::PkgIterator &Pkg,
+ pkgCache::VerIterator &Ver)
+{
+ bool res = debListParser::UsePackage(Pkg, Ver);
+ // we use the full file path as a provides so that the file is found
+ // by its name
+ if(NewProvidesAllArch(Ver, DebFile, Ver.VerStr()) == false)
+ return false;
+ return res;
+}
+
+
+
diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h
index baace79fe..92ec048b1 100644
--- a/apt-pkg/deb/deblistparser.h
+++ b/apt-pkg/deb/deblistparser.h
@@ -56,7 +56,8 @@ class debListParser : public pkgCacheGenerator::ListParser
bool ParseProvides(pkgCache::VerIterator &Ver);
bool NewProvidesAllArch(pkgCache::VerIterator &Ver, std::string const &Package, std::string const &Version);
static bool GrabWord(std::string Word,WordList *List,unsigned char &Out);
-
+ APT_HIDDEN unsigned char ParseMultiArch(bool const showErrors);
+
public:
static unsigned char GetPrio(std::string Str);
@@ -101,9 +102,17 @@ class debListParser : public pkgCacheGenerator::ListParser
debListParser(FileFd *File, std::string const &Arch = "");
virtual ~debListParser() {};
+};
- private:
- APT_HIDDEN unsigned char ParseMultiArch(bool const showErrors);
+class debDebFileParser : public debListParser
+{
+ private:
+ std::string DebFile;
+
+ public:
+ debDebFileParser(FileFd *File, std::string const &DebFile);
+ virtual bool UsePackage(pkgCache::PkgIterator &Pkg,
+ pkgCache::VerIterator &Ver);
};
#endif
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc
index 6fd12add8..56eecdca1 100644
--- a/apt-pkg/deb/debmetaindex.cc
+++ b/apt-pkg/deb/debmetaindex.cc
@@ -471,6 +471,15 @@ class debSLTypeDebian : public pkgSourceList::Type
}
};
+debDebFileMetaIndex::debDebFileMetaIndex(std::string const &DebFile)
+ : metaIndex(DebFile, "local-uri", "deb-dist"), DebFile(DebFile)
+{
+ DebIndex = new debDebPkgFileIndex(DebFile);
+ Indexes = new vector<pkgIndexFile *>();
+ Indexes->push_back(DebIndex);
+}
+
+
class debSLTypeDeb : public debSLTypeDebian
{
public:
@@ -507,5 +516,25 @@ class debSLTypeDebSrc : public debSLTypeDebian
}
};
+class debSLTypeDebFile : public pkgSourceList::Type
+{
+ public:
+
+ bool CreateItem(vector<metaIndex *> &List, string const &URI,
+ string const &Dist, string const &Section,
+ std::map<string, string> const &Options) const
+ {
+ metaIndex *mi = new debDebFileMetaIndex(URI);
+ List.push_back(mi);
+ return true;
+ }
+
+ debSLTypeDebFile()
+ {
+ Name = "deb-file";
+ Label = "Debian Deb File";
+ }
+};
debSLTypeDeb _apt_DebType;
debSLTypeDebSrc _apt_DebSrcType;
+debSLTypeDebFile _apt_DebFileType;
diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h
index 2286fa8b2..0e70bba87 100644
--- a/apt-pkg/deb/debmetaindex.h
+++ b/apt-pkg/deb/debmetaindex.h
@@ -18,6 +18,7 @@
class pkgAcquire;
class pkgIndexFile;
+class debDebPkgFileIndex;
class debReleaseIndex : public metaIndex {
public:
@@ -71,4 +72,27 @@ class debReleaseIndex : public metaIndex {
void PushSectionEntry(const debSectionEntry *Entry);
};
+class debDebFileMetaIndex : public metaIndex
+{
+ private:
+ std::string DebFile;
+ debDebPkgFileIndex *DebIndex;
+ public:
+ virtual std::string ArchiveURI(std::string const& /*File*/) const {
+ return DebFile;
+ }
+ virtual bool GetIndexes(pkgAcquire* /*Owner*/, const bool& /*GetAll=false*/) const {
+ return true;
+ }
+ virtual std::vector<pkgIndexFile *> *GetIndexFiles() {
+ return Indexes;
+ }
+ virtual bool IsTrusted() const {
+ return true;
+ }
+ debDebFileMetaIndex(std::string const &DebFile);
+ virtual ~debDebFileMetaIndex() {};
+
+};
+
#endif
diff --git a/apt-pkg/deb/debrecords.h b/apt-pkg/deb/debrecords.h
index bdac6c90b..d572bc5c2 100644
--- a/apt-pkg/deb/debrecords.h
+++ b/apt-pkg/deb/debrecords.h
@@ -29,17 +29,16 @@ class debRecordParser : public pkgRecords::Parser
{
/** \brief dpointer placeholder (for later in case we need it) */
void *d;
-
+
+ protected:
FileFd File;
pkgTagFile Tags;
pkgTagSection Section;
- protected:
-
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();
@@ -66,4 +65,15 @@ class debRecordParser : public pkgRecords::Parser
virtual ~debRecordParser() {};
};
+// custom record parser that reads deb files directly
+class debDebFileRecordParser : public debRecordParser
+{
+ public:
+ virtual std::string FileName() {
+ return File.Name();
+ }
+ debDebFileRecordParser(std::string FileName,pkgCache &Cache)
+ : debRecordParser(FileName, Cache) {};
+};
+
#endif