summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/deb/debindexfile.cc73
-rw-r--r--apt-pkg/deb/debindexfile.h8
-rw-r--r--apt-pkg/deb/debrecords.cc108
-rw-r--r--apt-pkg/deb/debrecords.h49
-rw-r--r--apt-pkg/tagfile.cc6
5 files changed, 133 insertions, 111 deletions
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc
index cecfe41a9..49c6e8cc0 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>
/*}}}*/
@@ -671,8 +672,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,53 +688,56 @@ 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
@@ -838,7 +841,7 @@ 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";};
};
diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h
index 312e915f1..81914f203 100644
--- a/apt-pkg/deb/debindexfile.h
+++ b/apt-pkg/deb/debindexfile.h
@@ -177,6 +177,14 @@ class APT_HIDDEN 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 {
diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc
index b41aa5584..335bcfda0 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,28 @@ 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() {}
+
+// 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 +82,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 +106,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 +149,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 +160,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 +181,29 @@ 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;
+}
diff --git a/apt-pkg/deb/debrecords.h b/apt-pkg/deb/debrecords.h
index 7091c38e6..38e071940 100644
--- a/apt-pkg/deb/debrecords.h
+++ b/apt-pkg/deb/debrecords.h
@@ -25,21 +25,12 @@
#include <apt-pkg/indexfile.h>
#endif
-class APT_HIDDEN 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 +49,42 @@ class APT_HIDDEN debRecordParser : public pkgRecords::Parser
virtual std::string RecordField(const char *fieldName);
virtual void GetRec(const char *&Start,const char *&Stop);
-
+
+ debRecordParserBase() : Parser() {}
+ virtual ~debRecordParserBase();
+};
+
+class APT_HIDDEN debRecordParser : public debRecordParserBase
+{
+ 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 APT_HIDDEN debDebFileRecordParser : public debRecordParser
+class APT_HIDDEN debDebFileRecordParser : public debRecordParserBase
{
+ std::string debFileName;
+ std::string controlContent;
+
+ APT_HIDDEN bool LoadContent();
+ protected:
+ // single file files, so no jumping whatsoever
+ bool Jump(pkgCache::VerFileIterator const &) { return LoadContent(); }
+ bool Jump(pkgCache::DescFileIterator const &) { return LoadContent(); }
+
public:
- virtual std::string FileName() {
- return File.Name();
- }
- debDebFileRecordParser(std::string FileName,pkgCache &Cache)
- : debRecordParser(FileName, Cache) {};
+ virtual std::string FileName() { return debFileName; }
+
+ debDebFileRecordParser(std::string FileName)
+ : debRecordParserBase(), debFileName(FileName) {};
};
#endif
diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc
index 590206f17..9c40c8c92 100644
--- a/apt-pkg/tagfile.cc
+++ b/apt-pkg/tagfile.cc
@@ -183,8 +183,8 @@ bool pkgTagFile::Step(pkgTagSection &Tag)
break;
if (Resize() == false)
- return _error->Error(_("Unable to parse package file %s (1)"),
- d->Fd.Name().c_str());
+ return _error->Error(_("Unable to parse package file %s (%d)"),
+ d->Fd.Name().c_str(), 1);
} while (Tag.Scan(d->Start,d->End - d->Start, false) == false);
}
@@ -283,7 +283,7 @@ bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long long Offset)
return false;
if (Tag.Scan(d->Start, d->End - d->Start, false) == false)
- return _error->Error(_("Unable to parse package file %s (2)"),d->Fd.Name().c_str());
+ return _error->Error(_("Unable to parse package file %s (%d)"),d->Fd.Name().c_str(), 2);
return true;
}