summaryrefslogtreecommitdiff
path: root/apt-pkg/deb
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/deb')
-rw-r--r--apt-pkg/deb/debindexfile.cc5
-rw-r--r--apt-pkg/deb/debindexfile.h4
-rw-r--r--apt-pkg/deb/deblistparser.cc124
-rw-r--r--apt-pkg/deb/deblistparser.h11
-rw-r--r--apt-pkg/deb/debmetaindex.cc5
-rw-r--r--apt-pkg/deb/debsrcrecords.cc8
-rw-r--r--apt-pkg/deb/dpkgpm.cc41
7 files changed, 109 insertions, 89 deletions
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc
index 9961b5ae4..1e8c04033 100644
--- a/apt-pkg/deb/debindexfile.cc
+++ b/apt-pkg/deb/debindexfile.cc
@@ -66,7 +66,10 @@ pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const
string SourcesURI = _config->FindDir("Dir::State::lists") +
URItoFileName(IndexURI("Sources"));
string SourcesURIgzip = SourcesURI + ".gz";
- if (!FileExists(SourcesURI) && FileExists(SourcesURIgzip))
+
+ if (!FileExists(SourcesURI) && !FileExists(SourcesURIgzip))
+ return NULL;
+ else if (!FileExists(SourcesURI) && FileExists(SourcesURIgzip))
SourcesURI = SourcesURIgzip;
return new debSrcRecordParser(SourcesURI,this);
diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h
index b5085992d..6697c5f26 100644
--- a/apt-pkg/deb/debindexfile.h
+++ b/apt-pkg/deb/debindexfile.h
@@ -22,8 +22,9 @@
class debStatusIndex : public pkgIndexFile
{
+ protected:
string File;
-
+
public:
virtual const Type *GetType() const;
@@ -36,6 +37,7 @@ class debStatusIndex : public pkgIndexFile
virtual bool HasPackages() const {return true;};
virtual unsigned long Size() const;
virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const;
+ bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog, unsigned long const Flag) const;
virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const;
debStatusIndex(string File);
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 9201e6a54..a94b79f05 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -67,23 +67,12 @@ string debListParser::Package() {
/*}}}*/
// ListParser::Architecture - Return the package arch /*{{{*/
// ---------------------------------------------------------------------
-/* This will return the Architecture of the package this section describes
- Note that architecture "all" packages will get the architecture of the
- Packages file parsed here. */
+/* This will return the Architecture of the package this section describes */
string debListParser::Architecture() {
- string const Result = Section.FindS("Architecture");
- if (Result.empty() == true || Result == "all")
- {
- if (Arch.empty() == true)
- /* FIXME: this is a problem for installed arch all
- packages as we don't know from which arch this
- package was installed - and therefore which
- dependency this package resolves. */
- return _config->Find("APT::Architecture");
- else
- return Arch;
- }
- return Result;
+ std::string const Arch = Section.FindS("Architecture");
+ if (Arch.empty() == true)
+ return _config->Find("APT::Architecture");
+ return Arch;
}
/*}}}*/
// ListParser::ArchitectureAll /*{{{*/
@@ -112,29 +101,35 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver)
Ver->Section = UniqFindTagWrite("Section");
// Parse multi-arch
- if (Section.FindS("Architecture") == "all")
- /* Arch all packages can't have a Multi-Arch field,
- but we need a special treatment for them nonetheless */
- Ver->MultiArch = pkgCache::Version::All;
- else
- {
- string const MultiArch = Section.FindS("Multi-Arch");
- if (MultiArch.empty() == true)
- Ver->MultiArch = pkgCache::Version::None;
- else if (MultiArch == "same")
- Ver->MultiArch = pkgCache::Version::Same;
- else if (MultiArch == "foreign")
- Ver->MultiArch = pkgCache::Version::Foreign;
- else if (MultiArch == "allowed")
- Ver->MultiArch = pkgCache::Version::Allowed;
- else
+ string const MultiArch = Section.FindS("Multi-Arch");
+ if (MultiArch.empty() == true)
+ Ver->MultiArch = pkgCache::Version::None;
+ else if (MultiArch == "same") {
+ // Parse multi-arch
+ if (ArchitectureAll() == true)
{
- _error->Warning("Unknown Multi-Arch type »%s« for package »%s«",
- MultiArch.c_str(), Section.FindS("Package").c_str());
+ /* Arch all packages can't be Multi-Arch: same */
+ _error->Warning("Architecture: all package '%s' can't be Multi-Arch: same",
+ Section.FindS("Package").c_str());
Ver->MultiArch = pkgCache::Version::None;
}
+ else
+ Ver->MultiArch = pkgCache::Version::Same;
+ }
+ else if (MultiArch == "foreign")
+ Ver->MultiArch = pkgCache::Version::Foreign;
+ else if (MultiArch == "allowed")
+ Ver->MultiArch = pkgCache::Version::Allowed;
+ else
+ {
+ _error->Warning("Unknown Multi-Arch type '%s' for package '%s'",
+ MultiArch.c_str(), Section.FindS("Package").c_str());
+ Ver->MultiArch = pkgCache::Version::None;
}
+ if (ArchitectureAll() == true)
+ Ver->MultiArch |= pkgCache::Version::All;
+
// Archive Size
Ver->Size = Section.FindULL("Size");
// Unpacked Size (in K)
@@ -150,24 +145,6 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver)
Ver->Priority = pkgCache::State::Extra;
}
- if (Ver->MultiArch == pkgCache::Version::All)
- {
- /* We maintain a "pseudo" arch=all package for architecture all versions
- on which these versions can depend on. This pseudo package is many used
- for downloading/installing: The other pseudo-packages will degenerate
- to a NOP in the download/install step - this package will ensure that
- it is downloaded only one time and installed only one time -- even if
- the architecture bound versions coming in and out on regular basis. */
- if (strcmp(Ver.Arch(true),"all") == 0)
- return true;
- else if (MultiArchEnabled == true)
- {
- // our pseudo packages have no size to not confuse the fetcher
- Ver->Size = 0;
- Ver->InstalledSize = 0;
- }
- }
-
if (ParseDepends(Ver,"Depends",pkgCache::Dep::Depends) == false)
return false;
if (ParseDepends(Ver,"Pre-Depends",pkgCache::Dep::PreDepends) == false)
@@ -302,18 +279,18 @@ unsigned short debListParser::VersionHash()
/* Strip out any spaces from the text, this undoes dpkgs reformatting
of certain fields. dpkg also has the rather interesting notion of
reformatting depends operators < -> <= */
- char *I = S;
+ char *J = S;
for (; Start != End; Start++)
{
if (isspace(*Start) == 0)
- *I++ = tolower_ascii(*Start);
+ *J++ = tolower_ascii(*Start);
if (*Start == '<' && Start[1] != '<' && Start[1] != '=')
- *I++ = '=';
+ *J++ = '=';
if (*Start == '>' && Start[1] != '>' && Start[1] != '=')
- *I++ = '=';
+ *J++ = '=';
}
- Result = AddCRC16(Result,S,I - S);
+ Result = AddCRC16(Result,S,J - S);
}
return Result;
@@ -505,7 +482,7 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
// Parse off the package name
const char *I = Start;
for (;I != Stop && isspace(*I) == 0 && *I != '(' && *I != ')' &&
- *I != ',' && *I != '|'; I++);
+ *I != ',' && *I != '|' && *I != '[' && *I != ']'; I++);
// Malformed, no '('
if (I != Stop && *I == ')')
@@ -644,13 +621,13 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
return true;
string Package;
- string const pkgArch = Ver.Arch(true);
+ string const pkgArch = Ver.Arch();
string Version;
unsigned int Op;
while (1)
{
- Start = ParseDepends(Start,Stop,Package,Version,Op);
+ Start = ParseDepends(Start,Stop,Package,Version,Op,false,!MultiArchEnabled);
if (Start == 0)
return _error->Error("Problem parsing dependency %s",Tag);
@@ -683,7 +660,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
{
string Package;
string Version;
- string const Arch = Ver.Arch(true);
+ string const Arch = Ver.Arch();
unsigned int Op;
while (1)
@@ -703,27 +680,28 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
}
}
- if (Ver->MultiArch == pkgCache::Version::Allowed)
+ if (MultiArchEnabled == false)
+ return true;
+ else if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
{
string const Package = string(Ver.ParentPkg().Name()).append(":").append("any");
- NewProvides(Ver, Package, "any", Ver.VerStr());
+ return NewProvidesAllArch(Ver, Package, Ver.VerStr());
}
+ else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign)
+ return NewProvidesAllArch(Ver, Ver.ParentPkg().Name(), Ver.VerStr());
- if (Ver->MultiArch != pkgCache::Version::Foreign)
- return true;
-
- if (MultiArchEnabled == false)
- return true;
-
- string const Package = Ver.ParentPkg().Name();
- string const Version = Ver.VerStr();
+ return true;
+}
+ /*}}}*/
+// ListParser::NewProvides - add provides for all architectures /*{{{*/
+bool debListParser::NewProvidesAllArch(pkgCache::VerIterator &Ver, string const &Package,
+ string const &Version) {
for (std::vector<string>::const_iterator a = Architectures.begin();
a != Architectures.end(); ++a)
{
if (NewProvides(Ver, Package, *a, Version) == false)
return false;
}
-
return true;
}
/*}}}*/
@@ -768,7 +746,7 @@ bool debListParser::Step()
if (Architecture == Arch)
return true;
- if (Architecture == "all")
+ if (Architecture == "all" && Arch == _config->Find("APT::Architecture"))
return true;
}
diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h
index 4bc1bd93c..8b8aff788 100644
--- a/apt-pkg/deb/deblistparser.h
+++ b/apt-pkg/deb/deblistparser.h
@@ -25,9 +25,9 @@ class debListParser : public pkgCacheGenerator::ListParser
const char *Str;
unsigned char Val;
};
-
- private:
-
+
+ protected:
+
pkgTagFile Tags;
pkgTagSection Section;
unsigned long iOffset;
@@ -36,10 +36,11 @@ class debListParser : public pkgCacheGenerator::ListParser
bool MultiArchEnabled;
unsigned long UniqFindTagWrite(const char *Tag);
- bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver);
+ virtual bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver);
bool ParseDepends(pkgCache::VerIterator &Ver,const char *Tag,
unsigned int Type);
bool ParseProvides(pkgCache::VerIterator &Ver);
+ bool NewProvidesAllArch(pkgCache::VerIterator &Ver, string const &Package, string const &Version);
static bool GrabWord(string Word,WordList *List,unsigned char &Out);
public:
@@ -69,7 +70,7 @@ class debListParser : public pkgCacheGenerator::ListParser
static const char *ParseDepends(const char *Start,const char *Stop,
string &Package,string &Ver,unsigned int &Op,
bool const &ParseArchFlags = false,
- bool const &StripMultiArch = false);
+ bool const &StripMultiArch = true);
static const char *ConvertRelation(const char *I,unsigned int &Op);
debListParser(FileFd *File, string const &Arch = "");
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc
index a6edab6b9..a91cc34e9 100644
--- a/apt-pkg/deb/debmetaindex.cc
+++ b/apt-pkg/deb/debmetaindex.cc
@@ -195,11 +195,14 @@ vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
}
}
+ std::vector<std::string> const lang = APT::Configuration::getLanguages(true);
+ if (lang.empty() == true)
+ return IndexTargets;
+
// get the Translations:
// - if its a dists-style repository get the i18n/Index first
// - if its flat try to acquire files by guessing
if (Dist[Dist.size() - 1] == '/') {
- std::vector<std::string> const lang = APT::Configuration::getLanguages(true);
for (std::set<std::string>::const_iterator s = sections.begin();
s != sections.end(); ++s) {
for (std::vector<std::string>::const_iterator l = lang.begin();
diff --git a/apt-pkg/deb/debsrcrecords.cc b/apt-pkg/deb/debsrcrecords.cc
index 21336e1af..749305005 100644
--- a/apt-pkg/deb/debsrcrecords.cc
+++ b/apt-pkg/deb/debsrcrecords.cc
@@ -14,6 +14,7 @@
#include <apt-pkg/error.h>
#include <apt-pkg/strutl.h>
#include <apt-pkg/configuration.h>
+#include <apt-pkg/aptconfiguration.h>
using std::max;
/*}}}*/
@@ -111,7 +112,9 @@ bool debSrcRecordParser::Files(vector<pkgSrcRecords::File> &List)
string Base = Sect.FindS("Directory");
if (Base.empty() == false && Base[Base.length()-1] != '/')
Base += '/';
-
+
+ std::vector<std::string> const compExts = APT::Configuration::getCompressorExtensions();
+
// Iterate over the entire list grabbing each triplet
const char *C = Files.c_str();
while (*C != 0)
@@ -144,7 +147,8 @@ bool debSrcRecordParser::Files(vector<pkgSrcRecords::File> &List)
}
F.Type = string(F.Path,Tmp+1,Pos-Tmp);
- if (F.Type == "gz" || F.Type == "bz2" || F.Type == "lzma" || F.Type == "tar")
+ if (std::find(compExts.begin(), compExts.end(), std::string(".").append(F.Type)) != compExts.end() ||
+ F.Type == "tar")
{
Pos = Tmp-1;
continue;
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index 7d0d34a46..b37980b7e 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -308,6 +308,15 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
SetCloseExec(STDIN_FILENO,false);
SetCloseExec(STDERR_FILENO,false);
+ if (_config->FindDir("DPkg::Chroot-Directory","/") != "/")
+ {
+ std::cerr << "Chrooting into "
+ << _config->FindDir("DPkg::Chroot-Directory")
+ << std::endl;
+ if (chroot(_config->FindDir("DPkg::Chroot-Directory","/").c_str()) != 0)
+ _exit(100);
+ }
+
const char *Args[4];
Args[0] = "/bin/sh";
Args[1] = "-c";
@@ -382,8 +391,9 @@ void pkgDPkgPM::DoTerminalPty(int master)
{
// this happens when the child is about to exit, we
// give it time to actually exit, otherwise we run
- // into a race
- usleep(500000);
+ // into a race so we sleep for half a second.
+ struct timespec sleepfor = { 0, 500000000 };
+ nanosleep(&sleepfor, NULL);
return;
}
if(len <= 0)
@@ -881,7 +891,10 @@ bool pkgDPkgPM::Go(int OutStatusFd)
// Generate the argument list
const char *Args[MaxArgs + 50];
-
+ // keep track of allocated strings for multiarch package names
+ char *Packages[MaxArgs + 50];
+ unsigned int pkgcount = 0;
+
// Now check if we are within the MaxArgs limit
//
// this code below is problematic, because it may happen that
@@ -989,16 +1002,27 @@ bool pkgDPkgPM::Go(int OutStatusFd)
}
else
{
+ string const nativeArch = _config->Find("APT::Architecture");
+ unsigned long const oldSize = I->Op == Item::Configure ? Size : 0;
for (;I != J && Size < MaxArgBytes; I++)
{
if((*I).Pkg.end() == true)
continue;
if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end())
continue;
- Args[n++] = I->Pkg.Name();
+ if (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all"))
+ Args[n++] = I->Pkg.Name();
+ else
+ {
+ Packages[pkgcount] = strdup(I->Pkg.FullName(false).c_str());
+ Args[n++] = Packages[pkgcount++];
+ }
Size += strlen(Args[n-1]);
- }
- }
+ }
+ // skip configure action if all sheduled packages disappeared
+ if (oldSize == Size)
+ continue;
+ }
Args[n] = 0;
J = I;
@@ -1145,6 +1169,11 @@ bool pkgDPkgPM::Go(int OutStatusFd)
sigemptyset(&sigmask);
sigprocmask(SIG_BLOCK,&sigmask,&original_sigmask);
+ /* clean up the temporary allocation for multiarch package names in
+ the parent, so we don't leak memory when we return. */
+ for (unsigned int i = 0; i < pkgcount; i++)
+ free(Packages[i]);
+
// the result of the waitpid call
int res;
int select_ret;