Browse Source

WIP local deb install

tags/debian/1.1.exp1
Michael Vogt 7 years ago
parent
commit
0d29b9d436
12 changed files with 266 additions and 11 deletions
  1. +2
    -1
      apt-pkg/acquire-item.cc
  2. +25
    -1
      apt-pkg/contrib/fileutl.cc
  3. +2
    -0
      apt-pkg/contrib/fileutl.h
  4. +104
    -1
      apt-pkg/deb/debindexfile.cc
  5. +31
    -0
      apt-pkg/deb/debindexfile.h
  6. +20
    -0
      apt-pkg/deb/deblistparser.cc
  7. +12
    -3
      apt-pkg/deb/deblistparser.h
  8. +9
    -0
      apt-pkg/deb/debmetaindex.cc
  9. +24
    -0
      apt-pkg/deb/debmetaindex.h
  10. +14
    -4
      apt-pkg/deb/debrecords.h
  11. +5
    -0
      apt-pkg/sourcelist.h
  12. +18
    -1
      apt-private/private-install.cc

+ 2
- 1
apt-pkg/acquire-item.cc View File

@@ -2084,7 +2084,8 @@ void pkgAcqArchive::Done(string Message,unsigned long long Size,string CalcHash,
}
// Check the hash
if(ExpectedHash.toStr() != CalcHash)
// FIXME: could this empty() check impose *any* sort of security issue?
if(ExpectedHash.empty() == false && ExpectedHash.toStr() != CalcHash)
{
RenameOnError(HashSumMismatch);
return;


+ 25
- 1
apt-pkg/contrib/fileutl.cc View File

@@ -1920,7 +1920,6 @@ bool FileFd::Close()
{
if ((Flags & Compressed) != Compressed && iFd > 0 && close(iFd) != 0)
Res &= _error->Errno("close",_("Problem closing the file %s"), FileName.c_str());

if (d != NULL)
{
Res &= d->CloseDown(FileName);
@@ -2047,6 +2046,31 @@ std::string GetTempDir()
return string(tmpdir);
}

FileFd* GetTempFile(std::string const &Prefix, bool ImmediateUnlink)
{
char fn[512];
FileFd *Fd = new FileFd();

std::string tempdir = GetTempDir();
snprintf(fn, sizeof(fn), "%s/%s.XXXXXX",
tempdir.c_str(), Prefix.c_str());
int fd = mkstemp(fn);
if(ImmediateUnlink)
unlink(fn);
if (fd < 0)
{
_error->Errno("GetTempFile",_("Unable to mkstemp %s"), fn);
return NULL;
}
if (!Fd->OpenDescriptor(fd, FileFd::WriteOnly, FileFd::None, true))
{
_error->Errno("GetTempFile",_("Unable to write to %s"),fn);
return NULL;
}

return Fd;
}

bool Rename(std::string From, std::string To)
{
if (rename(From.c_str(),To.c_str()) != 0)


+ 2
- 0
apt-pkg/contrib/fileutl.h View File

@@ -168,6 +168,8 @@ time_t GetModificationTime(std::string const &Path);
bool Rename(std::string From, std::string To);

std::string GetTempDir();
FileFd* GetTempFile(std::string const &Prefix = "",
bool ImmediateUnlink = true);

/** \brief Ensure the existence of the given Path
*


+ 104
- 1
apt-pkg/deb/debindexfile.cc View File

@@ -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,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<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 +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;
}
/*}}}*/

+ 31
- 0
apt-pkg/deb/debindexfile.h View File

@@ -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

+ 20
- 0
apt-pkg/deb/deblistparser.cc View File

@@ -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;
}




+ 12
- 3
apt-pkg/deb/deblistparser.h View File

@@ -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

+ 9
- 0
apt-pkg/deb/debmetaindex.cc View File

@@ -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:


+ 24
- 0
apt-pkg/deb/debmetaindex.h View File

@@ -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

+ 14
- 4
apt-pkg/deb/debrecords.h View File

@@ -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

+ 5
- 0
apt-pkg/sourcelist.h View File

@@ -116,6 +116,11 @@ class pkgSourceList
// query last-modified time
time_t GetLastModifiedTime();

// Add custom metaIndex (e.g. local files)
void Add(metaIndex *mi) {
SrcList.push_back(mi);
}

pkgSourceList();
pkgSourceList(std::string File);
~pkgSourceList();


+ 18
- 1
apt-private/private-install.cc View File

@@ -19,6 +19,10 @@
#include <apt-pkg/macros.h>
#include <apt-pkg/packagemanager.h>
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/sourcelist.h>

// FIXME: include of deb specific header
#include <apt-pkg/debmetaindex.h>

#include <errno.h>
#include <stdlib.h>
@@ -669,10 +673,23 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
bool DoInstall(CommandLine &CmdL)
{
CacheFile Cache;
// first check for local pkgs and add them to the cache
for (const char **I = CmdL.FileList; *I != 0; I++)
{
if(FileExists(*I))
{
// FIMXE: direct usage of .deb specific stuff
metaIndex *mi = new debDebFileMetaIndex(*I);
pkgSourceList *sources = Cache.GetSourceList();
sources->Add(mi);
}
}

// then open the cache
if (Cache.OpenForInstall() == false ||
Cache.CheckDeps(CmdL.FileSize() != 1) == false)
return false;

std::map<unsigned short, APT::VersionSet> verset;

if(!DoCacheManipulationFromCommandLine(CmdL, Cache, verset))


Loading…
Cancel
Save