summaryrefslogtreecommitdiff
path: root/apt-pkg/deb
diff options
context:
space:
mode:
authorMichael Vogt <mvo@ubuntu.com>2014-10-06 17:42:39 +0200
committerMichael Vogt <mvo@ubuntu.com>2014-10-06 17:42:39 +0200
commita2d40703e4a5590a689ace4466f92e590434944d (patch)
tree5e878fcc11eb94d96c65940ef3d30e922f217950 /apt-pkg/deb
parentffd2dd93a640b47663ebdccc4fda00b426b3db71 (diff)
parent00a06b8eb82cf930511fc003bd16d7034e5a0cb5 (diff)
make http size check work
Diffstat (limited to 'apt-pkg/deb')
-rw-r--r--apt-pkg/deb/debindexfile.cc96
-rw-r--r--apt-pkg/deb/debindexfile.h25
-rw-r--r--apt-pkg/deb/deblistparser.cc104
-rw-r--r--apt-pkg/deb/deblistparser.h7
-rw-r--r--apt-pkg/deb/debmetaindex.h2
-rw-r--r--apt-pkg/deb/debsrcrecords.cc3
-rw-r--r--apt-pkg/deb/debsystem.h2
-rw-r--r--apt-pkg/deb/dpkgpm.cc269
-rw-r--r--apt-pkg/deb/dpkgpm.h16
9 files changed, 314 insertions, 210 deletions
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc
index 3bdc551b4..9897df53d 100644
--- a/apt-pkg/deb/debindexfile.cc
+++ b/apt-pkg/deb/debindexfile.cc
@@ -81,14 +81,18 @@ pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const
{
string SourcesURI = _config->FindDir("Dir::State::lists") +
URItoFileName(IndexURI("Sources"));
- string SourcesURIgzip = SourcesURI + ".gz";
- if (!FileExists(SourcesURI) && !FileExists(SourcesURIgzip))
- return NULL;
- else if (!FileExists(SourcesURI) && FileExists(SourcesURIgzip))
- SourcesURI = SourcesURIgzip;
-
- return new debSrcRecordParser(SourcesURI,this);
+ std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+ for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
+ {
+ string p;
+ p = SourcesURI + '.' + *t;
+ if (FileExists(p))
+ return new debSrcRecordParser(p, this);
+ }
+ if (FileExists(SourcesURI))
+ return new debSrcRecordParser(SourcesURI, this);
+ return NULL;
}
/*}}}*/
// SourcesIndex::Describe - Give a descriptive path to the index /*{{{*/
@@ -127,14 +131,18 @@ string debSourcesIndex::Info(const char *Type) const
// SourcesIndex::Index* - Return the URI to the index files /*{{{*/
// ---------------------------------------------------------------------
/* */
-inline string debSourcesIndex::IndexFile(const char *Type) const
+string debSourcesIndex::IndexFile(const char *Type) const
{
string s = URItoFileName(IndexURI(Type));
- string sgzip = s + ".gz";
- if (!FileExists(s) && FileExists(sgzip))
- return sgzip;
- else
- return s;
+
+ std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+ for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
+ {
+ string p = s + '.' + *t;
+ if (FileExists(p))
+ return p;
+ }
+ return s;
}
string debSourcesIndex::IndexURI(const char *Type) const
@@ -257,14 +265,18 @@ string debPackagesIndex::Info(const char *Type) const
// PackagesIndex::Index* - Return the URI to the index files /*{{{*/
// ---------------------------------------------------------------------
/* */
-inline string debPackagesIndex::IndexFile(const char *Type) const
+string debPackagesIndex::IndexFile(const char *Type) const
{
string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type));
- string sgzip = s + ".gz";
- if (!FileExists(s) && FileExists(sgzip))
- return sgzip;
- else
- return s;
+
+ std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+ for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
+ {
+ string p = s + '.' + *t;
+ if (FileExists(p))
+ return p;
+ }
+ return s;
}
string debPackagesIndex::IndexURI(const char *Type) const
{
@@ -409,14 +421,18 @@ debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section
// TranslationIndex::Trans* - Return the URI to the translation files /*{{{*/
// ---------------------------------------------------------------------
/* */
-inline string debTranslationsIndex::IndexFile(const char *Type) const
+string debTranslationsIndex::IndexFile(const char *Type) const
{
string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type));
- string sgzip = s + ".gz";
- if (!FileExists(s) && FileExists(sgzip))
- return sgzip;
- else
- return s;
+
+ std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+ for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
+ {
+ string p = s + '.' + *t;
+ if (FileExists(p))
+ return p;
+ }
+ return s;
}
string debTranslationsIndex::IndexURI(const char *Type) const
{
@@ -619,7 +635,7 @@ bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
pkgCache::PkgFileIterator CFile = Gen.GetCurFile();
CFile->Size = Pkg.FileSize();
CFile->mtime = Pkg.ModificationTime();
- map_ptrloc const storage = Gen.WriteUniqString("now");
+ map_stringitem_t const storage = Gen.StoreString(pkgCacheGenerator::MIXED, "now");
CFile->Archive = storage;
if (Gen.MergeList(Parser) == false)
@@ -692,15 +708,27 @@ bool debDebPkgFileIndex::Merge(pkgCacheGenerator& Gen, OpProgress* Prog) const
// 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");
- const char *Args[5] = {dpkg.c_str(),
- "-I",
- DebFile.c_str(),
- "control",
- NULL};
+ 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("control");
+ Args.push_back(NULL);
FileFd PipeFd;
pid_t Child;
- if(Popen(Args, PipeFd, Child, FileFd::ReadOnly) == false)
+ if(Popen((const char**)&Args[0], PipeFd, Child, FileFd::ReadOnly) == false)
return _error->Error("Popen failed");
// FIXME: static buffer
char buf[8*1024];
@@ -710,7 +738,7 @@ bool debDebPkgFileIndex::Merge(pkgCacheGenerator& Gen, OpProgress* Prog) const
ExecWait(Child, "Popen");
// now write the control data to a tempfile
- SPtr<FileFd> DebControl = GetTempFile("deb-file-" + DebFile);
+ SPtr<FileFd> DebControl = GetTempFile("deb-file-" + flNotDir(DebFile));
if(DebControl == NULL)
return false;
DebControl->Write(buf, n);
@@ -738,8 +766,6 @@ bool debDebPkgFileIndex::Merge(pkgCacheGenerator& Gen, OpProgress* Prog) const
}
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)
{
diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h
index 18322dc1b..2e3ff5451 100644
--- a/apt-pkg/deb/debindexfile.h
+++ b/apt-pkg/deb/debindexfile.h
@@ -65,10 +65,10 @@ class debPackagesIndex : public pkgIndexFile
std::string Section;
std::string Architecture;
- std::string Info(const char *Type) const;
- std::string IndexFile(const char *Type) const;
- std::string IndexURI(const char *Type) const;
-
+ APT_HIDDEN std::string Info(const char *Type) const;
+ APT_HIDDEN std::string IndexFile(const char *Type) const;
+ APT_HIDDEN std::string IndexURI(const char *Type) const;
+
public:
virtual const Type *GetType() const APT_CONST;
@@ -102,11 +102,11 @@ class debTranslationsIndex : public pkgIndexFile
std::string Section;
const char * const Language;
- std::string Info(const char *Type) const;
- std::string IndexFile(const char *Type) const;
- std::string IndexURI(const char *Type) const;
+ APT_HIDDEN std::string Info(const char *Type) const;
+ APT_HIDDEN std::string IndexFile(const char *Type) const;
+ APT_HIDDEN std::string IndexURI(const char *Type) const;
- inline std::string TranslationFile() const {return std::string("Translation-").append(Language);};
+ APT_HIDDEN std::string TranslationFile() const {return std::string("Translation-").append(Language);};
public:
@@ -136,10 +136,10 @@ class debSourcesIndex : public pkgIndexFile
std::string Dist;
std::string Section;
- std::string Info(const char *Type) const;
- std::string IndexFile(const char *Type) const;
- std::string IndexURI(const char *Type) const;
-
+ APT_HIDDEN std::string Info(const char *Type) const;
+ APT_HIDDEN std::string IndexFile(const char *Type) const;
+ APT_HIDDEN std::string IndexURI(const char *Type) const;
+
public:
virtual const Type *GetType() const APT_CONST;
@@ -214,6 +214,7 @@ class debDscFileIndex : public pkgIndexFile
class debDebianSourceDirIndex : public debDscFileIndex
{
+ public:
virtual const Type *GetType() const APT_CONST;
};
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 40d332196..63414c944 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -58,18 +58,6 @@ debListParser::debListParser(FileFd *File, string const &Arch) : Tags(File),
MultiArchEnabled = Architectures.size() > 1;
}
/*}}}*/
-// ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-unsigned long debListParser::UniqFindTagWrite(const char *Tag)
-{
- const char *Start;
- const char *Stop;
- if (Section.Find(Tag,Start,Stop) == false)
- return 0;
- return WriteUniqString(Start,Stop - Start);
-}
- /*}}}*/
// ListParser::Package - Return the package name /*{{{*/
// ---------------------------------------------------------------------
/* This is to return the name of the package this section describes */
@@ -108,7 +96,7 @@ unsigned char debListParser::ParseMultiArch(bool const showErrors) /*{{{*/
{
unsigned char MA;
string const MultiArch = Section.FindS("Multi-Arch");
- if (MultiArch.empty() == true)
+ if (MultiArch.empty() == true || MultiArch == "no")
MA = pkgCache::Version::None;
else if (MultiArch == "same") {
if (ArchitectureAll() == true)
@@ -144,8 +132,67 @@ unsigned char debListParser::ParseMultiArch(bool const showErrors) /*{{{*/
/* */
bool debListParser::NewVersion(pkgCache::VerIterator &Ver)
{
+ const char *Start;
+ const char *Stop;
+
// Parse the section
- Ver->Section = UniqFindTagWrite("Section");
+ if (Section.Find("Section",Start,Stop) == true)
+ {
+ map_stringitem_t const idx = StoreString(pkgCacheGenerator::SECTION, Start, Stop - Start);
+ Ver->Section = idx;
+ }
+ // Parse the source package name
+ pkgCache::GrpIterator const G = Ver.ParentPkg().Group();
+ Ver->SourcePkgName = G->Name;
+ Ver->SourceVerStr = Ver->VerStr;
+ if (Section.Find("Source",Start,Stop) == true)
+ {
+ const char * const Space = (const char * const) memchr(Start, ' ', Stop - Start);
+ pkgCache::VerIterator V;
+
+ if (Space != NULL)
+ {
+ Stop = Space;
+ const char * const Open = (const char * const) memchr(Space, '(', Stop - Space);
+ if (likely(Open != NULL))
+ {
+ const char * const Close = (const char * const) memchr(Open, ')', Stop - Open);
+ if (likely(Close != NULL))
+ {
+ std::string const version(Open + 1, (Close - Open) - 1);
+ if (version != Ver.VerStr())
+ {
+ map_stringitem_t const idx = StoreString(pkgCacheGenerator::VERSIONNUMBER, version);
+ Ver->SourceVerStr = idx;
+ }
+ }
+ }
+ }
+
+ std::string const pkgname(Start, Stop - Start);
+ if (pkgname != G.Name())
+ {
+ for (pkgCache::PkgIterator P = G.PackageList(); P.end() == false; P = G.NextPkg(P))
+ {
+ for (V = P.VersionList(); V.end() == false; ++V)
+ {
+ if (pkgname == V.SourcePkgName())
+ {
+ Ver->SourcePkgName = V->SourcePkgName;
+ break;
+ }
+ }
+ if (V.end() == false)
+ break;
+ }
+ if (V.end() == true)
+ {
+ map_stringitem_t const idx = StoreString(pkgCacheGenerator::PKGNAME, pkgname);
+ Ver->SourcePkgName = idx;
+ }
+ }
+ }
+
Ver->MultiArch = ParseMultiArch(true);
// Archive Size
Ver->Size = Section.FindULL("Size");
@@ -154,10 +201,8 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver)
Ver->InstalledSize *= 1024;
// Priority
- const char *Start;
- const char *Stop;
if (Section.Find("Priority",Start,Stop) == true)
- {
+ {
if (GrabWord(string(Start,Stop-Start),PrioList,Ver->Priority) == false)
Ver->Priority = pkgCache::State::Extra;
}
@@ -255,9 +300,6 @@ MD5SumValue debListParser::Description_md5()
bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg,
pkgCache::VerIterator &Ver)
{
- if (Pkg->Section == 0)
- Pkg->Section = UniqFindTagWrite("Section");
-
string const static myArch = _config->Find("APT::Architecture");
// Possible values are: "all", "native", "installed" and "none"
// The "installed" mode is handled by ParseStatus(), See #544481 and friends.
@@ -795,8 +837,8 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
Start = ParseDepends(Start,Stop,Package,Version,Op);
if (Start == 0)
return _error->Error("Problem parsing Provides line");
- if (Op != pkgCache::Dep::NoOp) {
- _error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str());
+ if (Op != pkgCache::Dep::NoOp && Op != pkgCache::Dep::Equals) {
+ _error->Warning("Ignoring Provides line with non-equal DepCompareOp for package %s", Package.c_str());
} else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) {
if (NewProvidesAllArch(Ver, Package, Version) == false)
return false;
@@ -893,7 +935,7 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
{
// apt-secure does no longer download individual (per-section) Release
// file. to provide Component pinning we use the section name now
- map_ptrloc const storage = WriteUniqString(component);
+ map_stringitem_t const storage = StoreString(pkgCacheGenerator::MIXED, component);
FileI->Component = storage;
pkgTagFile TagFile(&File, File.Size());
@@ -902,19 +944,19 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
return false;
std::string data;
- #define APT_INRELEASE(TAG, STORE) \
+ #define APT_INRELEASE(TYPE, TAG, STORE) \
data = Section.FindS(TAG); \
if (data.empty() == false) \
{ \
- map_ptrloc const storage = WriteUniqString(data); \
+ map_stringitem_t const storage = StoreString(pkgCacheGenerator::TYPE, data); \
STORE = storage; \
}
- APT_INRELEASE("Suite", FileI->Archive)
- APT_INRELEASE("Component", FileI->Component)
- APT_INRELEASE("Version", FileI->Version)
- APT_INRELEASE("Origin", FileI->Origin)
- APT_INRELEASE("Codename", FileI->Codename)
- APT_INRELEASE("Label", FileI->Label)
+ APT_INRELEASE(MIXED, "Suite", FileI->Archive)
+ APT_INRELEASE(MIXED, "Component", FileI->Component)
+ APT_INRELEASE(VERSIONNUMBER, "Version", FileI->Version)
+ APT_INRELEASE(MIXED, "Origin", FileI->Origin)
+ APT_INRELEASE(MIXED, "Codename", FileI->Codename)
+ APT_INRELEASE(MIXED, "Label", FileI->Label)
#undef APT_INRELEASE
Section.FindFlag("NotAutomatic", FileI->Flags, pkgCache::Flag::NotAutomatic);
Section.FindFlag("ButAutomaticUpgrades", FileI->Flags, pkgCache::Flag::ButAutomaticUpgrades);
diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h
index 56a83b36e..b55e57d41 100644
--- a/apt-pkg/deb/deblistparser.h
+++ b/apt-pkg/deb/deblistparser.h
@@ -44,12 +44,11 @@ class debListParser : public pkgCacheGenerator::ListParser
protected:
pkgTagFile Tags;
pkgTagSection Section;
- unsigned long iOffset;
+ map_filesize_t iOffset;
std::string Arch;
std::vector<std::string> Architectures;
bool MultiArchEnabled;
- unsigned long UniqFindTagWrite(const char *Tag);
virtual bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver);
bool ParseDepends(pkgCache::VerIterator &Ver,const char *Tag,
unsigned int Type);
@@ -77,8 +76,8 @@ class debListParser : public pkgCacheGenerator::ListParser
#endif
virtual bool UsePackage(pkgCache::PkgIterator &Pkg,
pkgCache::VerIterator &Ver);
- virtual unsigned long Offset() {return iOffset;};
- virtual unsigned long Size() {return Section.size();};
+ virtual map_filesize_t Offset() {return iOffset;};
+ virtual map_filesize_t Size() {return Section.size();};
virtual bool Step();
diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h
index 7091c198f..399543953 100644
--- a/apt-pkg/deb/debmetaindex.h
+++ b/apt-pkg/deb/debmetaindex.h
@@ -36,7 +36,7 @@ class debReleaseIndex : public metaIndex {
/** \brief dpointer placeholder (for later in case we need it) */
void *d;
std::map<std::string, std::vector<debSectionEntry const*> > ArchEntries;
- enum { ALWAYS_TRUSTED, NEVER_TRUSTED, CHECK_TRUST } Trusted;
+ enum APT_HIDDEN { ALWAYS_TRUSTED, NEVER_TRUSTED, CHECK_TRUST } Trusted;
public:
diff --git a/apt-pkg/deb/debsrcrecords.cc b/apt-pkg/deb/debsrcrecords.cc
index 76ba670c6..97f43aca2 100644
--- a/apt-pkg/deb/debsrcrecords.cc
+++ b/apt-pkg/deb/debsrcrecords.cc
@@ -239,7 +239,8 @@ bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List)
/* */
debSrcRecordParser::~debSrcRecordParser()
{
- delete[] Buffer;
+ // was allocated via strndup()
+ free(Buffer);
}
/*}}}*/
diff --git a/apt-pkg/deb/debsystem.h b/apt-pkg/deb/debsystem.h
index a945f68fb..226cd60bf 100644
--- a/apt-pkg/deb/debsystem.h
+++ b/apt-pkg/deb/debsystem.h
@@ -29,7 +29,7 @@ class debSystem : public pkgSystem
{
// private d-pointer
debSystemPrivate *d;
- bool CheckUpdates();
+ APT_HIDDEN bool CheckUpdates();
public:
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index 32ef343aa..95fae9a28 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -59,8 +59,8 @@ class pkgDPkgPMPrivate
{
public:
pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0),
- term_out(NULL), history_out(NULL),
- progress(NULL), master(-1), slave(-1)
+ term_out(NULL), history_out(NULL),
+ progress(NULL), master(-1), slave(NULL)
{
dpkgbuf[0] = '\0';
}
@@ -77,9 +77,9 @@ public:
APT::Progress::PackageManager *progress;
// pty stuff
- struct termios tt;
+ struct termios tt;
int master;
- int slave;
+ char * slave;
// signals
sigset_t sigmask;
@@ -510,7 +510,7 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
return result;
}
/*}}}*/
-// DPkgPM::DoStdin - Read stdin and pass to slave pty /*{{{*/
+// DPkgPM::DoStdin - Read stdin and pass to master pty /*{{{*/
// ---------------------------------------------------------------------
/*
*/
@@ -564,8 +564,8 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line)
'status: <pkg>: <pkg qstate>'
'status: <pkg>:<arch>: <pkg qstate>'
- 'processing: {install,configure,remove,purge,disappear,trigproc}: pkg'
- 'processing: {install,configure,remove,purge,disappear,trigproc}: trigger'
+ 'processing: {install,upgrade,configure,remove,purge,disappear,trigproc}: pkg'
+ 'processing: {install,upgrade,configure,remove,purge,disappear,trigproc}: trigger'
*/
// we need to split on ": " (note the appended space) as the ':' is
@@ -589,12 +589,15 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line)
std::string action;
// "processing" has the form "processing: action: pkg or trigger"
- // with action = ["install", "configure", "remove", "purge", "disappear",
- // "trigproc"]
+ // with action = ["install", "upgrade", "configure", "remove", "purge",
+ // "disappear", "trigproc"]
if (prefix == "processing")
{
pkgname = APT::String::Strip(list[2]);
action = APT::String::Strip(list[1]);
+ // we don't care for the difference (as dpkg doesn't really either)
+ if (action == "upgrade")
+ action = "install";
}
// "status" has the form: "status: pkg: state"
// with state in ["half-installed", "unpacked", "half-configured",
@@ -621,15 +624,15 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line)
{
if(action == "error")
{
- d->progress->Error(list[1], PackagesDone, PackagesTotal,
+ d->progress->Error(pkgname, PackagesDone, PackagesTotal,
list[3]);
pkgFailures++;
- WriteApportReport(list[1].c_str(), list[3].c_str());
+ WriteApportReport(pkgname.c_str(), list[3].c_str());
return;
}
else if(action == "conffile-prompt")
{
- d->progress->ConffilePrompt(list[1], PackagesDone, PackagesTotal,
+ d->progress->ConffilePrompt(pkgname, PackagesDone, PackagesTotal,
list[3]);
return;
}
@@ -638,27 +641,26 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line)
// at this point we know that we should have a valid pkgname, so build all
// the info from it
- // dpkg does not send always send "pkgname:arch" so we add it here
- // if needed
+ // dpkg does not always send "pkgname:arch" so we add it here if needed
if (pkgname.find(":") == std::string::npos)
{
- // find the package in the group that is in a touched by dpkg
- // if there are multiple dpkg will send us a full pkgname:arch
+ // find the package in the group that is touched by dpkg
+ // if there are multiple pkgs dpkg would send us a full pkgname:arch
pkgCache::GrpIterator Grp = Cache.FindGrp(pkgname);
- if (Grp.end() == false)
+ if (Grp.end() == false)
{
- pkgCache::PkgIterator P = Grp.PackageList();
- for (; P.end() != true; P = Grp.NextPkg(P))
- {
- if(Cache[P].Mode != pkgDepCache::ModeKeep)
- {
- pkgname = P.FullName();
- break;
- }
- }
+ pkgCache::PkgIterator P = Grp.PackageList();
+ for (; P.end() != true; P = Grp.NextPkg(P))
+ {
+ if(Cache[P].Keep() == false || Cache[P].ReInstall() == true)
+ {
+ pkgname = P.FullName();
+ break;
+ }
+ }
}
}
-
+
const char* const pkg = pkgname.c_str();
std::string short_pkgname = StringSplit(pkgname, ":")[0];
std::string arch = "";
@@ -697,28 +699,29 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line)
if (prefix == "status")
{
vector<struct DpkgState> const &states = PackageOps[pkg];
- const char *next_action = NULL;
if(PackageOpsDone[pkg] < states.size())
- next_action = states[PackageOpsDone[pkg]].state;
- // check if the package moved to the next dpkg state
- if(next_action && (action == next_action))
{
- // only read the translation if there is actually a next
- // action
- const char *translation = _(states[PackageOpsDone[pkg]].str);
- std::string msg;
-
- // we moved from one dpkg state to a new one, report that
- PackageOpsDone[pkg]++;
- PackagesDone++;
-
- strprintf(msg, translation, i18n_pkgname.c_str());
- d->progress->StatusChanged(pkgname, PackagesDone, PackagesTotal, msg);
-
+ char const * const next_action = states[PackageOpsDone[pkg]].state;
+ if (next_action && Debug == true)
+ std::clog << "(parsed from dpkg) pkg: " << short_pkgname
+ << " action: " << action << " (expected: '" << next_action << "' "
+ << PackageOpsDone[pkg] << " of " << states.size() << ")" << endl;
+
+ // check if the package moved to the next dpkg state
+ if(next_action && (action == next_action))
+ {
+ // only read the translation if there is actually a next action
+ char const * const translation = _(states[PackageOpsDone[pkg]].str);
+
+ // we moved from one dpkg state to a new one, report that
+ ++PackageOpsDone[pkg];
+ ++PackagesDone;
+
+ std::string msg;
+ strprintf(msg, translation, i18n_pkgname.c_str());
+ d->progress->StatusChanged(pkgname, PackagesDone, PackagesTotal, msg);
+ }
}
- if (Debug == true)
- std::clog << "(parsed from dpkg) pkg: " << short_pkgname
- << " action: " << action << endl;
}
}
/*}}}*/
@@ -1031,7 +1034,6 @@ void pkgDPkgPM::BuildPackagesProgressMap()
}
}
/*}}}*/
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13)
bool pkgDPkgPM::Go(int StatusFd)
{
APT::Progress::PackageManager *progress = NULL;
@@ -1040,68 +1042,134 @@ bool pkgDPkgPM::Go(int StatusFd)
else
progress = new APT::Progress::PackageManagerProgressFd(StatusFd);
- return GoNoABIBreak(progress);
+ return Go(progress);
}
-#endif
void pkgDPkgPM::StartPtyMagic()
{
if (_config->FindB("Dpkg::Use-Pty", true) == false)
{
- d->master = d->slave = -1;
+ d->master = -1;
+ if (d->slave != NULL)
+ free(d->slave);
+ d->slave = NULL;
return;
}
- // setup the pty and stuff
- struct winsize win;
-
+ _error->PushToStack();
// if tcgetattr for both stdin/stdout returns 0 (no error)
// we do the pty magic
- _error->PushToStack();
- if (tcgetattr(STDIN_FILENO, &d->tt) == 0 &&
- tcgetattr(STDOUT_FILENO, &d->tt) == 0)
+ if (tcgetattr(STDOUT_FILENO, &d->tt) == 0 &&
+ tcgetattr(STDIN_FILENO, &d->tt) == 0)
{
- if (ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win) < 0)
- {
- _error->Errno("ioctl", _("ioctl(TIOCGWINSZ) failed"));
- } else if (openpty(&d->master, &d->slave, NULL, &d->tt, &win) < 0)
- {
- _error->Errno("openpty", _("Can not write log (%s)"), _("Is /dev/pts mounted?"));
- d->master = d->slave = -1;
- } else {
- struct termios rtt;
- rtt = d->tt;
- cfmakeraw(&rtt);
- rtt.c_lflag &= ~ECHO;
- rtt.c_lflag |= ISIG;
+ d->master = posix_openpt(O_RDWR | O_NOCTTY);
+ if (d->master == -1)
+ _error->Errno("posix_openpt", _("Can not write log (%s)"), _("Is /dev/pts mounted?"));
+ else if (unlockpt(d->master) == -1)
+ {
+ _error->Errno("unlockpt", "Unlocking the slave of master fd %d failed!", d->master);
+ close(d->master);
+ d->master = -1;
+ }
+ else
+ {
+ char const * const slave_name = ptsname(d->master);
+ if (slave_name == NULL)
+ {
+ _error->Errno("unlockpt", "Getting name for slave of master fd %d failed!", d->master);
+ close(d->master);
+ d->master = -1;
+ }
+ else
+ {
+ d->slave = strdup(slave_name);
+ if (d->slave == NULL)
+ {
+ _error->Errno("strdup", "Copying name %s for slave of master fd %d failed!", slave_name, d->master);
+ close(d->master);
+ d->master = -1;
+ }
+ struct winsize win;
+ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) < 0)
+ _error->Errno("ioctl", "Getting TIOCGWINSZ from stdout failed!");
+ if (ioctl(d->master, TIOCSWINSZ, &win) < 0)
+ _error->Errno("ioctl", "Setting TIOCSWINSZ for master fd %d failed!", d->master);
+ if (tcsetattr(d->master, TCSANOW, &d->tt) == -1)
+ _error->Errno("tcsetattr", "Setting in Start via TCSANOW for master fd %d failed!", d->master);
+
+ struct termios raw_tt;
+ raw_tt = d->tt;
+ cfmakeraw(&raw_tt);
+ raw_tt.c_lflag &= ~ECHO;
+ raw_tt.c_lflag |= ISIG;
// block SIGTTOU during tcsetattr to prevent a hang if
// the process is a member of the background process group
// http://www.opengroup.org/onlinepubs/000095399/functions/tcsetattr.html
sigemptyset(&d->sigmask);
sigaddset(&d->sigmask, SIGTTOU);
sigprocmask(SIG_BLOCK,&d->sigmask, &d->original_sigmask);
- tcsetattr(0, TCSAFLUSH, &rtt);
- sigprocmask(SIG_SETMASK, &d->original_sigmask, 0);
- }
+ if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw_tt) == -1)
+ _error->Errno("tcsetattr", "Setting in Start via TCSAFLUSH for stdout failed!");
+ sigprocmask(SIG_SETMASK, &d->original_sigmask, NULL);
+ }
}
- // complain only if stdout is either a terminal (but still failed) or is an invalid
+ }
+ else
+ {
+ // complain only if stdout is either a terminal (but still failed) or is an invalid
// descriptor otherwise we would complain about redirection to e.g. /dev/null as well.
- else if (isatty(STDOUT_FILENO) == 1 || errno == EBADF)
- _error->Errno("tcgetattr", _("Can not write log (%s)"), _("Is stdout a terminal?"));
+ if (isatty(STDOUT_FILENO) == 1 || errno == EBADF)
+ _error->Errno("tcgetattr", _("Can not write log (%s)"), _("Is stdout a terminal?"));
+ }
- if (_error->PendingError() == true)
- _error->DumpErrors(std::cerr);
- _error->RevertToStack();
+ if (_error->PendingError() == true)
+ {
+ if (d->master != -1)
+ {
+ close(d->master);
+ d->master = -1;
+ }
+ _error->DumpErrors(std::cerr);
+ }
+ _error->RevertToStack();
}
+void pkgDPkgPM::SetupSlavePtyMagic()
+{
+ if(d->master == -1)
+ return;
+
+ if (close(d->master) == -1)
+ _error->FatalE("close", "Closing master %d in child failed!", d->master);
+ if (setsid() == -1)
+ _error->FatalE("setsid", "Starting a new session for child failed!");
+
+ int const slaveFd = open(d->slave, O_RDWR);
+ if (slaveFd == -1)
+ _error->FatalE("open", _("Can not write log (%s)"), _("Is /dev/pts mounted?"));
+
+ if (ioctl(slaveFd, TIOCSCTTY, 0) < 0)
+ _error->FatalE("ioctl", "Setting TIOCSCTTY for slave fd %d failed!", slaveFd);
+ else
+ {
+ for (unsigned short i = 0; i < 3; ++i)
+ if (dup2(slaveFd, i) == -1)
+ _error->FatalE("dup2", "Dupping %d to %d in child failed!", slaveFd, i);
+ if (tcsetattr(0, TCSANOW, &d->tt) < 0)
+ _error->FatalE("tcsetattr", "Setting in Setup via TCSANOW for slave fd %d failed!", slaveFd);
+ }
+}
void pkgDPkgPM::StopPtyMagic()
{
- if(d->slave > 0)
- close(d->slave);
+ if (d->slave != NULL)
+ free(d->slave);
+ d->slave = NULL;
if(d->master >= 0)
{
- tcsetattr(0, TCSAFLUSH, &d->tt);
+ if (tcsetattr(0, TCSAFLUSH, &d->tt) == -1)
+ _error->FatalE("tcsetattr", "Setting in Stop via TCSAFLUSH for stdin failed!");
close(d->master);
+ d->master = -1;
}
}
@@ -1114,11 +1182,7 @@ void pkgDPkgPM::StopPtyMagic()
* through to human readable (and i10n-able)
* names and calculates a percentage for each step.
*/
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
-#else
-bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress)
-#endif
{
pkgPackageManager::SigINTStop = false;
d->progress = progress;
@@ -1413,22 +1477,8 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress)
pid_t Child = ExecFork(KeepFDs);
if (Child == 0)
{
- // This is the child
- if(d->slave >= 0 && d->master >= 0)
- {
- setsid();
- int res = ioctl(d->slave, TIOCSCTTY, 0);
- if (res < 0) {
- std::cerr << "ioctl(TIOCSCTTY) failed for fd: "
- << d->slave << std::endl;
- } else {
- close(d->master);
- dup2(d->slave, 0);
- dup2(d->slave, 1);
- dup2(d->slave, 2);
- close(d->slave);
- }
- }
+ // This is the child
+ SetupSlavePtyMagic();
close(fd[0]); // close the read end of the pipe
dpkgChrootDirectory();
@@ -1438,7 +1488,8 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress)
if (_config->FindB("DPkg::FlushSTDIN",true) == true && isatty(STDIN_FILENO))
{
- int Flags,dummy;
+ int Flags;
+ int dummy = 0;
if ((Flags = fcntl(STDIN_FILENO,F_GETFL,dummy)) < 0)
_exit(100);
@@ -1667,9 +1718,10 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
// do not report dpkg I/O errors, this is a format string, so we compare
// the prefix and the suffix of the error with the dpkg error message
vector<string> io_errors;
- io_errors.push_back(string("failed to read on buffer copy for %s"));
- io_errors.push_back(string("failed in write on buffer copy for %s"));
- io_errors.push_back(string("short read on buffer copy for %s"));
+ io_errors.push_back(string("failed to read"));
+ io_errors.push_back(string("failed to write"));
+ io_errors.push_back(string("failed to seek"));
+ io_errors.push_back(string("unexpected end of file or stream"));
for (vector<string>::iterator I = io_errors.begin(); I != io_errors.end(); ++I)
{
@@ -1702,11 +1754,6 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
if (Ver.end() == true)
return;
pkgver = Ver.VerStr() == NULL ? "unknown" : Ver.VerStr();
- pkgRecords Recs(Cache);
- pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
- srcpkgname = Parse.SourcePkg();
- if(srcpkgname.empty())
- srcpkgname = pkgname;
// if the file exists already, we check:
// - if it was reported already (touched by apport).
@@ -1757,7 +1804,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
time_t now = time(NULL);
fprintf(report, "Date: %s" , ctime(&now));
fprintf(report, "Package: %s %s\n", pkgname.c_str(), pkgver.c_str());
- fprintf(report, "SourcePackage: %s\n", srcpkgname.c_str());
+ fprintf(report, "SourcePackage: %s\n", Ver.SourcePkgName());
fprintf(report, "ErrorMessage:\n %s\n", errormsg);
// ensure that the log is flushed
diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h
index 859c74b46..2a6e7e004 100644
--- a/apt-pkg/deb/dpkgpm.h
+++ b/apt-pkg/deb/dpkgpm.h
@@ -52,7 +52,7 @@ class pkgDPkgPM : public pkgPackageManager
needs to declare a Replaces on the disappeared package.
\param pkgname Name of the package that disappeared
*/
- void handleDisappearAction(std::string const &pkgname);
+ APT_HIDDEN void handleDisappearAction(std::string const &pkgname);
protected:
int pkgFailures;
@@ -110,6 +110,7 @@ class pkgDPkgPM : public pkgPackageManager
// helper
void BuildPackagesProgressMap();
void StartPtyMagic();
+ void SetupSlavePtyMagic();
void StopPtyMagic();
// input processing
@@ -117,27 +118,14 @@ class pkgDPkgPM : public pkgPackageManager
void DoTerminalPty(int master);
void DoDpkgStatusFd(int statusfd);
void ProcessDpkgStatusLine(char *line);
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13)
- void DoDpkgStatusFd(int statusfd, int /*unused*/) {
- DoDpkgStatusFd(statusfd);
- }
- void ProcessDpkgStatusLine(int /*unused*/, char *line) {
- ProcessDpkgStatusLine(line);
- }
-#endif
-
// The Actuall installation implementation
virtual bool Install(PkgIterator Pkg,std::string File);
virtual bool Configure(PkgIterator Pkg);
virtual bool Remove(PkgIterator Pkg,bool Purge = false);
-#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
virtual bool Go(APT::Progress::PackageManager *progress);
-#else
virtual bool Go(int StatusFd=-1);
- bool GoNoABIBreak(APT::Progress::PackageManager *progress);
-#endif
virtual void Reset();