Browse Source
based on a very early draft for EDSP by Stefano APT can now write a scenario as well as load most stuff from it.debian/1.8.y

18 changed files with 609 additions and 18 deletions
@ -0,0 +1,74 @@ |
|||
// -*- mode: cpp; mode: fold -*-
|
|||
// Description /*{{{*/
|
|||
/* ######################################################################
|
|||
The universe file is designed to work as an intermediate file between |
|||
APT and the resolver. Its on propose very similar to a dpkg status file |
|||
##################################################################### */ |
|||
/*}}}*/ |
|||
// Include Files /*{{{*/
|
|||
#include <apt-pkg/edspindexfile.h> |
|||
#include <apt-pkg/edsplistparser.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 <sys/stat.h> |
|||
/*}}}*/ |
|||
|
|||
// edspIndex::edspIndex - Constructor /*{{{*/
|
|||
// ---------------------------------------------------------------------
|
|||
/* */ |
|||
edspIndex::edspIndex(string File) : debStatusIndex(File) |
|||
{ |
|||
} |
|||
/*}}}*/ |
|||
// StatusIndex::Merge - Load the index file into a cache /*{{{*/
|
|||
bool edspIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const |
|||
{ |
|||
FileFd Pkg(File,FileFd::ReadOnlyGzip); |
|||
if (_error->PendingError() == true) |
|||
return false; |
|||
edspListParser Parser(&Pkg); |
|||
if (_error->PendingError() == true) |
|||
return false; |
|||
|
|||
if (Prog != NULL) |
|||
Prog->SubProgress(0,File); |
|||
if (Gen.SelectFile(File,string(),*this) == 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("universe"); |
|||
|
|||
if (Gen.MergeList(Parser) == false) |
|||
return _error->Error("Problem with MergeList %s",File.c_str()); |
|||
return true; |
|||
} |
|||
/*}}}*/ |
|||
// Index File types for APT /*{{{*/
|
|||
class edspIFType: public pkgIndexFile::Type |
|||
{ |
|||
public: |
|||
virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const |
|||
{ |
|||
// we don't have a record parser for this type as the file is not presistent
|
|||
return NULL; |
|||
}; |
|||
edspIFType() {Label = "APT universe file";}; |
|||
}; |
|||
static edspIFType _apt_Universe; |
|||
|
|||
const pkgIndexFile::Type *edspIndex::GetType() const |
|||
{ |
|||
return &_apt_Universe; |
|||
} |
|||
/*}}}*/ |
@ -0,0 +1,25 @@ |
|||
// -*- mode: cpp; mode: fold -*-
|
|||
// Description /*{{{*/
|
|||
/* ######################################################################
|
|||
The universe file is designed to work as an intermediate file between |
|||
APT and the resolver. Its on propose very similar to a dpkg status file |
|||
##################################################################### */ |
|||
/*}}}*/ |
|||
#ifndef PKGLIB_EDSPINDEXFILE_H |
|||
#define PKGLIB_EDSPINDEXFILE_H |
|||
|
|||
#include <apt-pkg/indexfile.h> |
|||
#include <apt-pkg/debindexfile.h> |
|||
|
|||
class edspIndex : public debStatusIndex |
|||
{ |
|||
public: |
|||
|
|||
virtual const Type *GetType() const; |
|||
|
|||
virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; |
|||
|
|||
edspIndex(string File); |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,109 @@ |
|||
// -*- mode: cpp; mode: fold -*-
|
|||
// Description /*{{{*/
|
|||
/* ######################################################################
|
|||
|
|||
Package Cache Generator - Generator for the cache structure. |
|||
|
|||
This builds the cache structure from the abstract package list parser. |
|||
|
|||
##################################################################### */ |
|||
/*}}}*/ |
|||
// Include Files /*{{{*/
|
|||
#include <apt-pkg/edsplistparser.h> |
|||
#include <apt-pkg/error.h> |
|||
#include <apt-pkg/configuration.h> |
|||
#include <apt-pkg/strutl.h> |
|||
#include <apt-pkg/md5.h> |
|||
#include <apt-pkg/macros.h> |
|||
/*}}}*/ |
|||
|
|||
// ListParser::edspListParser - Constructor /*{{{*/
|
|||
edspListParser::edspListParser(FileFd *File, string const &Arch) : debListParser(File, Arch) |
|||
{} |
|||
/*}}}*/ |
|||
// ListParser::NewVersion - Fill in the version structure /*{{{*/
|
|||
bool edspListParser::NewVersion(pkgCache::VerIterator &Ver) |
|||
{ |
|||
Ver->ID = Section.FindI("APT-ID", Ver->ID); |
|||
return debListParser::NewVersion(Ver); |
|||
} |
|||
/*}}}*/ |
|||
// ListParser::Description - Return the description string /*{{{*/
|
|||
// ---------------------------------------------------------------------
|
|||
/* Sorry, no description for the resolvers… */ |
|||
string edspListParser::Description() |
|||
{ |
|||
return ""; |
|||
} |
|||
string edspListParser::DescriptionLanguage() |
|||
{ |
|||
return ""; |
|||
} |
|||
MD5SumValue edspListParser::Description_md5() |
|||
{ |
|||
return MD5SumValue(""); |
|||
} |
|||
/*}}}*/ |
|||
// ListParser::VersionHash - Compute a unique hash for this version /*{{{*/
|
|||
// ---------------------------------------------------------------------
|
|||
/* */ |
|||
unsigned short edspListParser::VersionHash() |
|||
{ |
|||
if (Section.Exists("APT-Hash") == true) |
|||
return Section.FindI("APT-Hash"); |
|||
else if (Section.Exists("APT-ID") == true) |
|||
return Section.FindI("APT-ID"); |
|||
return 0; |
|||
} |
|||
/*}}}*/ |
|||
// ListParser::ParseStatus - Parse the status field /*{{{*/
|
|||
// ---------------------------------------------------------------------
|
|||
/* The Status: line here is not a normal dpkg one but just one which tells
|
|||
use if the package is installed or not, where missing means not. */ |
|||
bool edspListParser::ParseStatus(pkgCache::PkgIterator &Pkg, |
|||
pkgCache::VerIterator &Ver) |
|||
{ |
|||
const char *Start; |
|||
const char *Stop; |
|||
if (Section.Find("Status",Start,Stop) == false) |
|||
return true; |
|||
|
|||
// UsePackage() is responsible for setting the flag in the default case
|
|||
bool const static essential = _config->Find("pkgCacheGen::Essential", "") == "installed"; |
|||
if (essential == true && |
|||
Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false) |
|||
return false; |
|||
|
|||
// Isolate the first word
|
|||
const char *I = Start; |
|||
for(; I < Stop && *I != ' '; I++); |
|||
|
|||
// Process the flag field
|
|||
WordList StatusList[] = {{"installed",pkgCache::State::Installed}, |
|||
{}}; |
|||
if (GrabWord(string(Start,I-Start),StatusList,Pkg->CurrentState) == false) |
|||
return _error->Error("Malformed Status line"); |
|||
|
|||
/* A Status line marks the package as indicating the current
|
|||
version as well. Only if it is actually installed.. Otherwise |
|||
the interesting dpkg handling of the status file creates bogus |
|||
entries. */ |
|||
if (!(Pkg->CurrentState == pkgCache::State::NotInstalled || |
|||
Pkg->CurrentState == pkgCache::State::ConfigFiles)) |
|||
{ |
|||
if (Ver.end() == true) |
|||
_error->Warning("Encountered status field in a non-version description"); |
|||
else |
|||
Pkg->CurrentVer = Ver.Index(); |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
/*}}}*/ |
|||
// ListParser::LoadReleaseInfo - Load the release information /*{{{*/
|
|||
bool edspListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, |
|||
FileFd &File, string component) |
|||
{ |
|||
return true; |
|||
} |
|||
/*}}}*/ |
@ -0,0 +1,38 @@ |
|||
// -*- mode: cpp; mode: fold -*-
|
|||
// Description /*{{{*/
|
|||
/* ######################################################################
|
|||
|
|||
EDSP Package List Parser - This implements the abstract parser |
|||
interface for the APT specific intermediate format which is passed |
|||
to external resolvers |
|||
|
|||
##################################################################### */ |
|||
/*}}}*/ |
|||
#ifndef PKGLIB_EDSPLISTPARSER_H |
|||
#define PKGLIB_EDSPLISTPARSER_H |
|||
|
|||
#include <apt-pkg/deblistparser.h> |
|||
#include <apt-pkg/pkgcachegen.h> |
|||
#include <apt-pkg/indexfile.h> |
|||
#include <apt-pkg/tagfile.h> |
|||
|
|||
class edspListParser : public debListParser |
|||
{ |
|||
public: |
|||
virtual bool NewVersion(pkgCache::VerIterator &Ver); |
|||
virtual string Description(); |
|||
virtual string DescriptionLanguage(); |
|||
virtual MD5SumValue Description_md5(); |
|||
virtual unsigned short VersionHash(); |
|||
|
|||
bool LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,FileFd &File, |
|||
string section); |
|||
|
|||
edspListParser(FileFd *File, string const &Arch = ""); |
|||
|
|||
protected: |
|||
virtual bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver); |
|||
|
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,117 @@ |
|||
// -*- mode: cpp; mode: fold -*-
|
|||
// Description /*{{{*/
|
|||
/* ######################################################################
|
|||
|
|||
This system provides the abstraction to use the universe file as the |
|||
only source of package information to be able to feed the created file |
|||
back to APT for its own consumption (eat your own dogfood). |
|||
|
|||
##################################################################### */ |
|||
/*}}}*/ |
|||
// Include Files /*{{{*/
|
|||
#include <apt-pkg/edspsystem.h> |
|||
#include <apt-pkg/debversion.h> |
|||
#include <apt-pkg/edspindexfile.h> |
|||
#include <apt-pkg/configuration.h> |
|||
#include <apt-pkg/error.h> |
|||
#include <apt-pkg/fileutl.h> |
|||
#include <apti18n.h> |
|||
#include <sys/types.h> |
|||
#include <unistd.h> |
|||
#include <dirent.h> |
|||
#include <errno.h> |
|||
/*}}}*/ |
|||
|
|||
edspSystem edspSys; |
|||
|
|||
// System::debSystem - Constructor /*{{{*/
|
|||
edspSystem::edspSystem() |
|||
{ |
|||
StatusFile = 0; |
|||
|
|||
Label = "Debian APT solver interface"; |
|||
VS = &debVS; |
|||
} |
|||
/*}}}*/ |
|||
// System::~debSystem - Destructor /*{{{*/
|
|||
edspSystem::~edspSystem() |
|||
{ |
|||
delete StatusFile; |
|||
} |
|||
/*}}}*/ |
|||
// System::Lock - Get the lock /*{{{*/
|
|||
bool edspSystem::Lock() |
|||
{ |
|||
return true; |
|||
} |
|||
/*}}}*/ |
|||
// System::UnLock - Drop a lock /*{{{*/
|
|||
bool edspSystem::UnLock(bool NoErrors) |
|||
{ |
|||
return true; |
|||
} |
|||
/*}}}*/ |
|||
// System::CreatePM - Create the underlying package manager /*{{{*/
|
|||
// ---------------------------------------------------------------------
|
|||
/* we can't use edsp input as input for real installations - just a
|
|||
simulation can work, but everything else will fail bigtime */ |
|||
pkgPackageManager *edspSystem::CreatePM(pkgDepCache *Cache) const |
|||
{ |
|||
return NULL; |
|||
} |
|||
/*}}}*/ |
|||
// System::Initialize - Setup the configuration space.. /*{{{*/
|
|||
bool edspSystem::Initialize(Configuration &Cnf) |
|||
{ |
|||
Cnf.Set("Dir::State::extended_states", "/dev/null"); |
|||
Cnf.Set("Dir::State::status","/dev/null"); |
|||
Cnf.Set("Dir::State::lists","/dev/null"); |
|||
|
|||
Cnf.Set("Debug::NoLocking", "true"); |
|||
Cnf.Set("APT::Get::Simulate", "true"); |
|||
|
|||
if (StatusFile) { |
|||
delete StatusFile; |
|||
StatusFile = 0; |
|||
} |
|||
return true; |
|||
} |
|||
/*}}}*/ |
|||
// System::ArchiveSupported - Is a file format supported /*{{{*/
|
|||
bool edspSystem::ArchiveSupported(const char *Type) |
|||
{ |
|||
return false; |
|||
} |
|||
/*}}}*/ |
|||
// System::Score - Determine if we should use the edsp system /*{{{*/
|
|||
signed edspSystem::Score(Configuration const &Cnf) |
|||
{ |
|||
if (FileExists(Cnf.FindFile("Dir::State::universe","")) == true) |
|||
return 1000; |
|||
return -1000; |
|||
} |
|||
/*}}}*/ |
|||
// System::AddStatusFiles - Register the status files /*{{{*/
|
|||
bool edspSystem::AddStatusFiles(vector<pkgIndexFile *> &List) |
|||
{ |
|||
if (StatusFile == 0) |
|||
StatusFile = new edspIndex(_config->FindFile("Dir::State::universe")); |
|||
List.push_back(StatusFile); |
|||
return true; |
|||
} |
|||
/*}}}*/ |
|||
// System::FindIndex - Get an index file for status files /*{{{*/
|
|||
bool edspSystem::FindIndex(pkgCache::PkgFileIterator File, |
|||
pkgIndexFile *&Found) const |
|||
{ |
|||
if (StatusFile == 0) |
|||
return false; |
|||
if (StatusFile->FindInCache(*File.Cache()) == File) |
|||
{ |
|||
Found = StatusFile; |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
/*}}}*/ |
@ -0,0 +1,38 @@ |
|||
// -*- mode: cpp; mode: fold -*-
|
|||
// Description /*{{{*/
|
|||
// $Id: debsystem.h,v 1.4 2003/01/11 07:16:33 jgg Exp $
|
|||
/* ######################################################################
|
|||
|
|||
System - Debian version of the System Class |
|||
|
|||
##################################################################### */ |
|||
/*}}}*/ |
|||
#ifndef PKGLIB_EDSPSYSTEM_H |
|||
#define PKGLIB_EDSPSYSTEM_H |
|||
|
|||
#include <apt-pkg/pkgsystem.h> |
|||
|
|||
class edspIndex; |
|||
class edspSystem : public pkgSystem |
|||
{ |
|||
edspIndex *StatusFile; |
|||
|
|||
public: |
|||
|
|||
virtual bool Lock(); |
|||
virtual bool UnLock(bool NoErrors = false); |
|||
virtual pkgPackageManager *CreatePM(pkgDepCache *Cache) const; |
|||
virtual bool Initialize(Configuration &Cnf); |
|||
virtual bool ArchiveSupported(const char *Type); |
|||
virtual signed Score(Configuration const &Cnf); |
|||
virtual bool AddStatusFiles(std::vector<pkgIndexFile *> &List); |
|||
virtual bool FindIndex(pkgCache::PkgFileIterator File, |
|||
pkgIndexFile *&Found) const; |
|||
|
|||
edspSystem(); |
|||
~edspSystem(); |
|||
}; |
|||
|
|||
extern edspSystem edspSys; |
|||
|
|||
#endif |
@ -0,0 +1,130 @@ |
|||
// -*- mode: cpp; mode: fold -*-
|
|||
// Description /*{{{*/
|
|||
/* ######################################################################
|
|||
Set of methods to help writing and reading everything needed for EDSP |
|||
##################################################################### */ |
|||
/*}}}*/ |
|||
// Include Files /*{{{*/
|
|||
#include <apt-pkg/edspwriter.h> |
|||
#include <apt-pkg/error.h> |
|||
#include <apt-pkg/configuration.h> |
|||
#include <apt-pkg/version.h> |
|||
#include <apt-pkg/policy.h> |
|||
|
|||
#include <apti18n.h> |
|||
#include <limits> |
|||
|
|||
#include <stdio.h> |
|||
/*}}}*/ |
|||
|
|||
// edspWriter::WriteUniverse - to the given file descriptor /*{{{*/
|
|||
bool edspWriter::WriteUniverse(pkgDepCache &Cache, FILE* output) |
|||
{ |
|||
// we could use pkgCache::DepType and ::Priority, but these would be lokalized strings…
|
|||
const char * const PrioMap[] = {0, "important", "required", "standard", |
|||
"optional", "extra"}; |
|||
const char * const DepMap[] = {"", "Depends", "PreDepends", "Suggests", |
|||
"Recommends" , "Conflicts", "Replaces", |
|||
"Obsoletes", "Breaks", "Enhances"}; |
|||
|
|||
for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) |
|||
{ |
|||
for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver) |
|||
{ |
|||
fprintf(output, "Package: %s\n", Pkg.Name()); |
|||
fprintf(output, "Architecture: %s\n", Ver.Arch()); |
|||
fprintf(output, "Version: %s\n", Ver.VerStr()); |
|||
if (Pkg.CurrentVer() == Ver) |
|||
fprintf(output, "Installed: yes\n"); |
|||
if (Pkg->SelectedState == pkgCache::State::Hold) |
|||
fprintf(output, "Hold: yes\n"); |
|||
fprintf(output, "APT-ID: %u\n", Ver->ID); |
|||
fprintf(output, "Priority: %s\n", PrioMap[Ver->Priority]); |
|||
if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) |
|||
fprintf(output, "Essential: yes\n"); |
|||
fprintf(output, "Section: %s\n", Ver.Section()); |
|||
if (Ver->MultiArch == pkgCache::Version::Allowed || Ver->MultiArch == pkgCache::Version::AllAllowed) |
|||
fprintf(output, "Multi-Arch: allowed\n"); |
|||
else if (Ver->MultiArch == pkgCache::Version::Foreign || Ver->MultiArch == pkgCache::Version::AllForeign) |
|||
fprintf(output, "Multi-Arch: foreign\n"); |
|||
else if (Ver->MultiArch == pkgCache::Version::Same) |
|||
fprintf(output, "Multi-Arch: same\n"); |
|||
signed short Pin = std::numeric_limits<signed short>::min(); |
|||
for (pkgCache::VerFileIterator File = Ver.FileList(); File.end() == false; ++File) { |
|||
signed short const p = Cache.GetPolicy().GetPriority(File.File()); |
|||
if (Pin < p) |
|||
Pin = p; |
|||
} |
|||
fprintf(output, "APT-Pin: %d\n", Pin); |
|||
if (Cache.GetCandidateVer(Pkg) == Ver) |
|||
fprintf(output, "APT-Candidate: yes\n"); |
|||
if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) |
|||
fprintf(output, "APT-Automatic: yes\n"); |
|||
std::string dependencies[pkgCache::Dep::Enhances + 1]; |
|||
bool orGroup = false; |
|||
for (pkgCache::DepIterator Dep = Ver.DependsList(); Dep.end() == false; ++Dep) |
|||
{ |
|||
// Ignore implicit dependencies for multiarch here
|
|||
if (strcmp(Pkg.Arch(), Dep.TargetPkg().Arch()) != 0) |
|||
continue; |
|||
if (orGroup == false) |
|||
dependencies[Dep->Type].append(", "); |
|||
dependencies[Dep->Type].append(Dep.TargetPkg().Name()); |
|||
if (Dep->Version != 0) |
|||
dependencies[Dep->Type].append(" (").append(pkgCache::CompTypeDeb(Dep->CompareOp)).append(" ").append(Dep.TargetVer()).append(")"); |
|||
if ((Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or) |
|||
{ |
|||
dependencies[Dep->Type].append(" | "); |
|||
orGroup = true; |
|||
} |
|||
else |
|||
orGroup = false; |
|||
} |
|||
for (int i = 1; i < pkgCache::Dep::Enhances + 1; ++i) |
|||
if (dependencies[i].empty() == false) |
|||
fprintf(output, "%s: %s\n", DepMap[i], dependencies[i].c_str()+2); |
|||
string provides; |
|||
for (pkgCache::PrvIterator Prv = Ver.ProvidesList(); Prv.end() == false; ++Prv) |
|||
{ |
|||
// Ignore implicit provides for multiarch here
|
|||
if (strcmp(Pkg.Arch(), Prv.ParentPkg().Arch()) != 0 || strcmp(Pkg.Name(),Prv.Name()) == 0) |
|||
continue; |
|||
provides.append(", ").append(Prv.Name()); |
|||
} |
|||
if (provides.empty() == false) |
|||
fprintf(output, "Provides: %s\n", provides.c_str()+2); |
|||
|
|||
|
|||
fprintf(output, "\n"); |
|||
} |
|||
} |
|||
return true; |
|||
} |
|||
/*}}}*/ |
|||
// edspWriter::WriteRequest - to the given file descriptor /*{{{*/
|
|||
bool edspWriter::WriteRequest(pkgDepCache &Cache, FILE* output) |
|||
{ |
|||
string del, inst, upgrade; |
|||
for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) |
|||
{ |
|||
string* req; |
|||
if (Cache[Pkg].Delete() == true) |
|||
req = &del; |
|||
else if (Cache[Pkg].NewInstall() == true) |
|||
req = &inst; |
|||
else if (Cache[Pkg].Upgrade() == true) |
|||
req = &upgrade; |
|||
else |
|||
continue; |
|||
req->append(", ").append(Pkg.FullName()); |
|||
} |
|||
if (del.empty() == false) |
|||
fprintf(output, "Remove: %s\n", del.c_str()+2); |
|||
if (inst.empty() == false) |
|||
fprintf(output, "Install: %s\n", inst.c_str()+2); |
|||
if (upgrade.empty() == false) |
|||
fprintf(output, "Upgrade: %s\n", upgrade.c_str()+2); |
|||
|
|||
return true; |
|||
} |
|||
/*}}}*/ |
@ -0,0 +1,19 @@ |
|||
// -*- mode: cpp; mode: fold -*-
|
|||
// Description /*{{{*/
|
|||
/* ######################################################################
|
|||
Set of methods to help writing and reading everything needed for EDSP |
|||
##################################################################### */ |
|||
/*}}}*/ |
|||
#ifndef PKGLIB_EDSPWRITER_H |
|||
#define PKGLIB_EDSPWRITER_H |
|||
|
|||
#include <apt-pkg/depcache.h> |
|||
|
|||
class edspWriter /*{{{*/ |
|||
{ |
|||
public: |
|||
bool static WriteUniverse(pkgDepCache &Cache, FILE* output); |
|||
bool static WriteRequest(pkgDepCache &Cache, FILE* output); |
|||
}; |
|||
/*}}}*/ |
|||
#endif |
Loading…
Reference in new issue