summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/contrib/fileutl.cc46
-rw-r--r--apt-pkg/contrib/fileutl.h3
-rw-r--r--apt-pkg/contrib/gpgv.cc12
-rw-r--r--apt-pkg/contrib/hashes.cc25
-rw-r--r--apt-pkg/contrib/hashes.h9
-rw-r--r--apt-pkg/contrib/strutl.cc8
-rw-r--r--apt-pkg/contrib/strutl.h1
-rw-r--r--apt-pkg/deb/debmetaindex.cc17
-rw-r--r--apt-pkg/deb/debmetaindex.h7
-rw-r--r--apt-pkg/deb/dpkgpm.cc76
-rw-r--r--apt-pkg/deb/dpkgpm.h1
-rw-r--r--apt-pkg/depcache.cc2
-rw-r--r--apt-pkg/indexfile.h4
-rw-r--r--apt-pkg/indexrecords.cc5
-rw-r--r--apt-pkg/indexrecords.h1
-rw-r--r--apt-pkg/init.cc10
-rw-r--r--apt-pkg/install-progress.cc73
-rw-r--r--apt-pkg/install-progress.h18
-rw-r--r--apt-pkg/metaindex.h24
-rw-r--r--apt-pkg/policy.cc4
-rw-r--r--apt-pkg/tagfile.cc11
21 files changed, 283 insertions, 74 deletions
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index d2be276c7..efbf7aaf4 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -760,16 +760,13 @@ bool WaitFd(int Fd,bool write,unsigned long timeout)
return true;
}
/*}}}*/
-// ExecFork - Magical fork that sanitizes the context before execing /*{{{*/
+// MergeKeepFdsFromConfiguration - Merge APT::Keep-Fds configuration /*{{{*/
// ---------------------------------------------------------------------
-/* This is used if you want to cleanse the environment for the forked
- child, it fixes up the important signals and nukes all of the fds,
- otherwise acts like normal fork. */
-pid_t ExecFork()
+/* This is used to merge the APT::Keep-Fds with the provided KeepFDs
+ * set.
+ */
+void MergeKeepFdsFromConfiguration(std::set<int> &KeepFDs)
{
- set<int> KeepFDs;
-
- // FIXME: remove looking at APT::Keep-Fds eventually, its a hack
Configuration::Item const *Opts = _config->Tree("APT::Keep-Fds");
if (Opts != 0 && Opts->Child != 0)
{
@@ -782,6 +779,19 @@ pid_t ExecFork()
KeepFDs.insert(fd);
}
}
+}
+ /*}}}*/
+// ExecFork - Magical fork that sanitizes the context before execing /*{{{*/
+// ---------------------------------------------------------------------
+/* This is used if you want to cleanse the environment for the forked
+ child, it fixes up the important signals and nukes all of the fds,
+ otherwise acts like normal fork. */
+pid_t ExecFork()
+{
+ set<int> KeepFDs;
+ // we need to merge the Keep-Fds as external tools like
+ // debconf-apt-progress use it
+ MergeKeepFdsFromConfiguration(KeepFDs);
return ExecFork(KeepFDs);
}
@@ -1535,6 +1545,9 @@ bool FileFd::Skip(unsigned long long Over)
/* */
bool FileFd::Truncate(unsigned long long To)
{
+ // truncating /dev/null is always successful - as we get an error otherwise
+ if (To == 0 && FileName == "/dev/null")
+ return true;
#if defined HAVE_ZLIB || defined HAVE_BZ2
if (d != NULL && (d->gz != NULL || d->bz2 != NULL))
return FileFdError("Truncating compressed files is not implemented (%s)", FileName.c_str());
@@ -1814,3 +1827,20 @@ std::vector<std::string> Glob(std::string const &pattern, int flags)
return result;
}
/*}}}*/
+
+std::string GetTempDir()
+{
+ const char *tmpdir = getenv("TMPDIR");
+
+#ifdef P_tmpdir
+ if (!tmpdir)
+ tmpdir = P_tmpdir;
+#endif
+
+ // check that tmpdir is set and exists
+ struct stat st;
+ if (!tmpdir || strlen(tmpdir) == 0 || stat(tmpdir, &st) != 0)
+ tmpdir = "/tmp";
+
+ return string(tmpdir);
+}
diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h
index 63a999c30..e752e9621 100644
--- a/apt-pkg/contrib/fileutl.h
+++ b/apt-pkg/contrib/fileutl.h
@@ -165,6 +165,8 @@ bool DirectoryExists(std::string const &Path) __attrib_const;
bool CreateDirectory(std::string const &Parent, std::string const &Path);
time_t GetModificationTime(std::string const &Path);
+std::string GetTempDir();
+
/** \brief Ensure the existence of the given Path
*
* \param Parent directory of the Path directory - a trailing
@@ -184,6 +186,7 @@ void SetNonBlock(int Fd,bool Block);
bool WaitFd(int Fd,bool write = false,unsigned long timeout = 0);
pid_t ExecFork();
pid_t ExecFork(std::set<int> keep_fds);
+void MergeKeepFdsFromConfiguration(std::set<int> &keep_fds);
bool ExecWait(pid_t Pid,const char *Name,bool Reap = false);
// File string manipulators
diff --git a/apt-pkg/contrib/gpgv.cc b/apt-pkg/contrib/gpgv.cc
index f47e7ea48..f57a72d86 100644
--- a/apt-pkg/contrib/gpgv.cc
+++ b/apt-pkg/contrib/gpgv.cc
@@ -10,6 +10,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <unistd.h>
#include<apt-pkg/configuration.h>
#include<apt-pkg/error.h>
@@ -21,16 +22,9 @@
/*}}}*/
static char * GenerateTemporaryFileTemplate(const char *basename) /*{{{*/
{
- const char *tmpdir = getenv("TMPDIR");
-#ifdef P_tmpdir
- if (!tmpdir)
- tmpdir = P_tmpdir;
-#endif
- if (!tmpdir)
- tmpdir = "/tmp";
-
std::string out;
- strprintf(out, "%s/%s.XXXXXX", tmpdir, basename);
+ std::string tmpdir = GetTempDir();
+ strprintf(out, "%s/%s.XXXXXX", tmpdir.c_str(), basename);
return strdup(out.c_str());
}
/*}}}*/
diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc
index e1a431823..b4c768db9 100644
--- a/apt-pkg/contrib/hashes.cc
+++ b/apt-pkg/contrib/hashes.cc
@@ -55,6 +55,26 @@ HashString::HashString(std::string StringedHash) /*{{{*/
/*}}}*/
bool HashString::VerifyFile(std::string filename) const /*{{{*/
{
+ std::string fileHash = GetHashForFile(filename);
+
+ if(_config->FindB("Debug::Hashes",false) == true)
+ std::clog << "HashString::VerifyFile: got: " << fileHash << " expected: " << toStr() << std::endl;
+
+ return (fileHash == Hash);
+}
+ /*}}}*/
+bool HashString::FromFile(std::string filename) /*{{{*/
+{
+ // pick the strongest hash
+ if (Type == "")
+ Type = _SupportedHashes[0];
+
+ Hash = GetHashForFile(filename);
+ return true;
+}
+ /*}}}*/
+std::string HashString::GetHashForFile(std::string filename) const /*{{{*/
+{
std::string fileHash;
FileFd Fd(filename, FileFd::ReadOnly);
@@ -84,10 +104,7 @@ bool HashString::VerifyFile(std::string filename) const /*{{{*/
}
Fd.Close();
- if(_config->FindB("Debug::Hashes",false) == true)
- std::clog << "HashString::VerifyFile: got: " << fileHash << " expected: " << toStr() << std::endl;
-
- return (fileHash == Hash);
+ return fileHash;
}
/*}}}*/
const char** HashString::SupportedHashes()
diff --git a/apt-pkg/contrib/hashes.h b/apt-pkg/contrib/hashes.h
index 0c0b6c6a7..0a8bcd259 100644
--- a/apt-pkg/contrib/hashes.h
+++ b/apt-pkg/contrib/hashes.h
@@ -36,7 +36,10 @@ class HashString
protected:
std::string Type;
std::string Hash;
- static const char * _SupportedHashes[10];
+ static const char* _SupportedHashes[10];
+
+ // internal helper
+ std::string GetHashForFile(std::string filename) const;
public:
HashString(std::string Type, std::string Hash);
@@ -49,6 +52,10 @@ class HashString
// verify the given filename against the currently loaded hash
bool VerifyFile(std::string filename) const;
+ // generate a hash string from the given filename
+ bool FromFile(std::string filename);
+
+
// helper
std::string toStr() const; // convert to str as "type:hash"
bool empty() const;
diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc
index 9f794927d..962112854 100644
--- a/apt-pkg/contrib/strutl.cc
+++ b/apt-pkg/contrib/strutl.cc
@@ -49,6 +49,14 @@ std::string Strip(const std::string &s)
size_t end = s.find_last_not_of(" \t\n");
return s.substr(start, end-start+1);
}
+
+bool Endswith(const std::string &s, const std::string &end)
+{
+ if (end.size() > s.size())
+ return false;
+ return (s.substr(s.size() - end.size(), s.size()) == end);
+}
+
}
}
/*}}}*/
diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h
index c8fc317c0..8d746f10e 100644
--- a/apt-pkg/contrib/strutl.h
+++ b/apt-pkg/contrib/strutl.h
@@ -36,6 +36,7 @@ using std::ostream;
namespace APT {
namespace String {
std::string Strip(const std::string &s);
+ bool Endswith(const std::string &s, const std::string &ending);
};
};
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc
index b597b6f3c..504877558 100644
--- a/apt-pkg/deb/debmetaindex.cc
+++ b/apt-pkg/deb/debmetaindex.cc
@@ -1,4 +1,3 @@
-// ijones, walters
#include <config.h>
#include <apt-pkg/debmetaindex.h>
@@ -72,6 +71,22 @@ string debReleaseIndex::MetaIndexURI(const char *Type) const
return Res;
}
+#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+std::string debReleaseIndex::LocalFileName() const
+{
+ // see if we have a InRelease file
+ std::string PathInRelease = MetaIndexFile("InRelease");
+ if (FileExists(PathInRelease))
+ return PathInRelease;
+
+ // and if not return the normal one
+ if (FileExists(PathInRelease))
+ return MetaIndexFile("Release");
+
+ return "";
+}
+#endif
+
string debReleaseIndex::IndexURISuffix(const char *Type, string const &Section, string const &Arch) const
{
string Res ="";
diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h
index b9ecab97c..cef8d68f7 100644
--- a/apt-pkg/deb/debmetaindex.h
+++ b/apt-pkg/deb/debmetaindex.h
@@ -3,6 +3,7 @@
#define PKGLIB_DEBMETAINDEX_H
#include <apt-pkg/metaindex.h>
+#include <apt-pkg/init.h>
#include <map>
#include <string>
@@ -39,9 +40,15 @@ class debReleaseIndex : public metaIndex {
virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const;
std::vector <struct IndexTarget *>* ComputeIndexTargets() const;
std::string Info(const char *Type, std::string const &Section, std::string const &Arch="") const;
+
std::string MetaIndexInfo(const char *Type) const;
std::string MetaIndexFile(const char *Types) const;
std::string MetaIndexURI(const char *Type) const;
+
+#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+ virtual std::string LocalFileName() const;
+#endif
+
std::string IndexURI(const char *Type, std::string const &Section, std::string const &Arch="native") const;
std::string IndexURISuffix(const char *Type, std::string const &Section, std::string const &Arch="native") const;
std::string SourceIndexURI(const char *Type, const std::string &Section) const;
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index 26d79dbb1..14ce133cf 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -44,6 +44,7 @@
#include <unistd.h>
#include <sys/ioctl.h>
#include <pty.h>
+#include <stdio.h>
#include <apti18n.h>
/*}}}*/
@@ -201,7 +202,7 @@ pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg)
// ---------------------------------------------------------------------
/* */
pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache)
- : pkgPackageManager(Cache), PackagesDone(0), PackagesTotal(0)
+ : pkgPackageManager(Cache), pkgFailures(0), PackagesDone(0), PackagesTotal(0)
{
d = new pkgDPkgPMPrivate();
}
@@ -417,6 +418,7 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
// Create the pipes
std::set<int> KeepFDs;
+ MergeKeepFdsFromConfiguration(KeepFDs);
int Pipes[2];
if (pipe(Pipes) != 0)
return _error->Errno("pipe","Failed to create IPC pipe to subprocess");
@@ -595,7 +597,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line)
errors look like this:
'status: /var/cache/apt/archives/krecipes_0.8.1-0ubuntu1_i386.deb : error : trying to overwrite `/usr/share/doc/kde/HTML/en/krecipes/krectip.png', which is also in package krecipes-data
and conffile-prompt like this
- 'status: conffile-prompt: conffile : 'current-conffile' 'new-conffile' useredited distedited
+ 'status:/etc/compiz.conf/compiz.conf : conffile-prompt: 'current-conffile' 'new-conffile' useredited distedited
*/
if (prefix == "status")
{
@@ -607,7 +609,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line)
WriteApportReport(list[1].c_str(), list[3].c_str());
return;
}
- else if(action == "conffile")
+ else if(action == "conffile-prompt")
{
d->progress->ConffilePrompt(list[1], PackagesDone, PackagesTotal,
list[3]);
@@ -1035,7 +1037,10 @@ void pkgDPkgPM::StartPtyMagic()
if (tcgetattr(STDOUT_FILENO, &d->tt) == 0)
{
ioctl(1, TIOCGWINSZ, (char *)&win);
- if (openpty(&d->master, &d->slave, NULL, &d->tt, &win) < 0)
+ if (_config->FindB("Dpkg::Use-Pty", true) == false)
+ {
+ d->master = d->slave = -1;
+ } 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;
@@ -1181,7 +1186,7 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress)
StartPtyMagic();
// Tell the progress that its starting and fork dpkg
- d->progress->Start();
+ d->progress->Start(d->master);
// this loop is runs once per dpkg operation
vector<Item>::const_iterator I = List.begin();
@@ -1380,6 +1385,7 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress)
d->progress->StartDpkg();
std::set<int> KeepFDs;
KeepFDs.insert(fd[1]);
+ MergeKeepFdsFromConfiguration(KeepFDs);
pid_t Child = ExecFork(KeepFDs);
if (Child == 0)
{
@@ -1528,6 +1534,7 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress)
if(stopOnError)
{
CloseLog();
+ StopPtyMagic();
d->progress->Stop();
return false;
}
@@ -1619,18 +1626,49 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
}
// do not report out-of-memory failures
- if(strstr(errormsg, strerror(ENOMEM)) != NULL) {
+ if(strstr(errormsg, strerror(ENOMEM)) != NULL ||
+ strstr(errormsg, "failed to allocate memory") != NULL) {
std::clog << _("No apport report written because the error message indicates a out of memory error") << std::endl;
return;
}
- // do not report dpkg I/O errors
- // XXX - this message is localized, but this only matches the English version. This is better than nothing.
- if(strstr(errormsg, "short read in buffer_copy (")) {
- std::clog << _("No apport report written because the error message indicates a dpkg I/O error") << std::endl;
+ // do not report bugs regarding inaccessible local files
+ if(strstr(errormsg, strerror(ENOENT)) != NULL ||
+ strstr(errormsg, "cannot access archive") != NULL) {
+ std::clog << _("No apport report written because the error message indicates an issue on the local system") << std::endl;
+ return;
+ }
+
+ // do not report errors encountered when decompressing packages
+ if(strstr(errormsg, "--fsys-tarfile returned error exit status 2") != NULL) {
+ std::clog << _("No apport report written because the error message indicates an issue on the local system") << std::endl;
return;
}
+ // 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"));
+
+ for (vector<string>::iterator I = io_errors.begin(); I != io_errors.end(); I++)
+ {
+ vector<string> list = VectorizeString(dgettext("dpkg", (*I).c_str()), '%');
+ if (list.size() > 1) {
+ // we need to split %s, VectorizeString only allows char so we need
+ // to kill the "s" manually
+ if (list[1].size() > 1) {
+ list[1].erase(0, 1);
+ if(strstr(errormsg, list[0].c_str()) &&
+ strstr(errormsg, list[1].c_str())) {
+ std::clog << _("No apport report written because the error message indicates a dpkg I/O error") << std::endl;
+ return;
+ }
+ }
+ }
+ }
+
// get the pkgname and reportfile
pkgname = flNotDir(pkgpath);
pos = pkgname.find('_');
@@ -1720,6 +1758,24 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
char buf[1024];
while( fgets(buf, sizeof(buf), log) != NULL)
fprintf(report, " %s", buf);
+ fprintf(report, " \n");
+ fclose(log);
+ }
+ }
+
+ // attach history log it if we have it
+ string histfile_name = _config->FindFile("Dir::Log::History");
+ if (!histfile_name.empty())
+ {
+ FILE *log = NULL;
+ char buf[1024];
+
+ fprintf(report, "DpkgHistoryLog:\n");
+ log = fopen(histfile_name.c_str(),"r");
+ if(log != NULL)
+ {
+ while( fgets(buf, sizeof(buf), log) != NULL)
+ fprintf(report, " %s", buf);
fclose(log);
}
}
diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h
index 06318d94f..02e12a6d9 100644
--- a/apt-pkg/deb/dpkgpm.h
+++ b/apt-pkg/deb/dpkgpm.h
@@ -89,7 +89,6 @@ class pkgDPkgPM : public pkgPackageManager
const std::string &short_pkgname);
// Terminal progress
- void SetupTerminalScrollArea(int nr_scrolled_rows);
void SendTerminalProgress(float percentage);
// apport integration
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index a06789cdf..f9c891c86 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -1522,7 +1522,7 @@ bool pkgDepCache::SetCandidateRelease(pkgCache::VerIterator TargetVer,
if (itsFine == false)
{
// change the candidate
- Changed.push_back(make_pair(oldCand, TargetVer));
+ Changed.push_back(make_pair(V, TargetVer));
if (SetCandidateRelease(V, TargetRel, Changed) == false)
{
if (stillOr == false)
diff --git a/apt-pkg/indexfile.h b/apt-pkg/indexfile.h
index 1d34dc773..2d433b60a 100644
--- a/apt-pkg/indexfile.h
+++ b/apt-pkg/indexfile.h
@@ -78,10 +78,10 @@ class pkgIndexFile
virtual bool Exists() const = 0;
virtual bool HasPackages() const = 0;
virtual unsigned long Size() const = 0;
- virtual bool Merge(pkgCacheGenerator &/*Gen*/,OpProgress* /*Prog*/) const { return false; };
+ virtual bool Merge(pkgCacheGenerator &Gen, OpProgress* Prog) const { return false; };
__deprecated virtual bool Merge(pkgCacheGenerator &Gen, OpProgress &Prog) const
{ return Merge(Gen, &Prog); };
- virtual bool MergeFileProvides(pkgCacheGenerator &/*Gen*/,OpProgress* /*Prog*/) const {return true;};
+ virtual bool MergeFileProvides(pkgCacheGenerator &Gen,OpProgress* Prog) const {return true;};
__deprecated virtual bool MergeFileProvides(pkgCacheGenerator &Gen, OpProgress &Prog) const
{return MergeFileProvides(Gen, &Prog);};
virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const;
diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc
index 8a72ca151..f8097c3c6 100644
--- a/apt-pkg/indexrecords.cc
+++ b/apt-pkg/indexrecords.cc
@@ -27,6 +27,11 @@ string indexRecords::GetDist() const
return this->Dist;
}
+string indexRecords::GetSuite() const
+{
+ return this->Suite;
+}
+
bool indexRecords::CheckDist(const string MaybeDist) const
{
return (this->Dist == MaybeDist
diff --git a/apt-pkg/indexrecords.h b/apt-pkg/indexrecords.h
index a98b939bc..d003ec0fa 100644
--- a/apt-pkg/indexrecords.h
+++ b/apt-pkg/indexrecords.h
@@ -46,6 +46,7 @@ class indexRecords
virtual bool Load(std::string Filename);
std::string GetDist() const;
+ std::string GetSuite() const;
time_t GetValidUntil() const;
virtual bool CheckDist(const std::string MaybeDist) const;
std::string GetExpectedDist() const;
diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc
index 76278921f..81b601a7f 100644
--- a/apt-pkg/init.cc
+++ b/apt-pkg/init.cc
@@ -44,16 +44,8 @@ bool pkgInitConfig(Configuration &Cnf)
Cnf.CndSet("APT::Install-Suggests", false);
Cnf.CndSet("Dir","/");
- // State
+ // State
Cnf.CndSet("Dir::State","var/lib/apt/");
-
- /* Just in case something goes horribly wrong, we can fall back to the
- old /var/state paths.. */
- struct stat St;
- if (stat("/var/lib/apt/.",&St) != 0 &&
- stat("/var/state/apt/.",&St) == 0)
- Cnf.CndSet("Dir::State","var/state/apt/");
-
Cnf.CndSet("Dir::State::lists","lists/");
Cnf.CndSet("Dir::State::cdroms","cdroms.list");
Cnf.CndSet("Dir::State::mirrors","mirrors/");
diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc
index 09b1bef9e..fe065da4f 100644
--- a/apt-pkg/install-progress.cc
+++ b/apt-pkg/install-progress.cc
@@ -9,6 +9,8 @@
#include <sys/ioctl.h>
#include <sstream>
#include <fcntl.h>
+#include <algorithm>
+#include <stdio.h>
namespace APT {
namespace Progress {
@@ -222,8 +224,46 @@ bool PackageManagerProgressDeb822Fd::StatusChanged(std::string PackageName,
}
+PackageManagerFancy::PackageManagerFancy()
+ : child_pty(-1)
+{
+ // setup terminal size
+ old_SIGWINCH = signal(SIGWINCH, PackageManagerFancy::staticSIGWINCH);
+ instances.push_back(this);
+}
+std::vector<PackageManagerFancy*> PackageManagerFancy::instances;
+
+PackageManagerFancy::~PackageManagerFancy()
+{
+ instances.erase(find(instances.begin(), instances.end(), this));
+ signal(SIGWINCH, old_SIGWINCH);
+}
+
+void PackageManagerFancy::staticSIGWINCH(int signum)
+{
+ std::vector<PackageManagerFancy *>::const_iterator I;
+ for(I = instances.begin(); I != instances.end(); I++)
+ (*I)->HandleSIGWINCH(signum);
+}
+
+int PackageManagerFancy::GetNumberTerminalRows()
+{
+ struct winsize win;
+ // FIXME: get from "child_pty" instead?
+ if(ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win) != 0)
+ return -1;
+
+ if(_config->FindB("Debug::InstallProgress::Fancy", false) == true)
+ std::cerr << "GetNumberTerminalRows: " << win.ws_row << std::endl;
+
+ return win.ws_row;
+}
+
void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows)
{
+ if(_config->FindB("Debug::InstallProgress::Fancy", false) == true)
+ std::cerr << "SetupTerminalScrollArea: " << nr_rows << std::endl;
+
// scroll down a bit to avoid visual glitch when the screen
// area shrinks by one row
std::cout << "\n";
@@ -232,39 +272,41 @@ void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows)
std::cout << "\033[s";
// set scroll region (this will place the cursor in the top left)
- std::cout << "\033[1;" << nr_rows - 1 << "r";
+ std::cout << "\033[0;" << nr_rows - 1 << "r";
// restore cursor but ensure its inside the scrolling area
std::cout << "\033[u";
static const char *move_cursor_up = "\033[1A";
std::cout << move_cursor_up;
- // setup env for (hopefully!) ncurses
- string s;
- strprintf(s, "%i", nr_rows);
- setenv("LINES", s.c_str(), 1);
-
+ // ensure its flushed
std::flush(std::cout);
+
+ // setup tty size to ensure xterm/linux console are working properly too
+ // see bug #731738
+ struct winsize win;
+ ioctl(child_pty, TIOCGWINSZ, (char *)&win);
+ win.ws_row = nr_rows - 1;
+ ioctl(child_pty, TIOCSWINSZ, (char *)&win);
}
-PackageManagerFancy::PackageManagerFancy()
- : nr_terminal_rows(-1)
+void PackageManagerFancy::HandleSIGWINCH(int)
{
- struct winsize win;
- if(ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win) == 0)
- {
- nr_terminal_rows = win.ws_row;
- }
+ int nr_terminal_rows = GetNumberTerminalRows();
+ SetupTerminalScrollArea(nr_terminal_rows);
}
-void PackageManagerFancy::Start()
+void PackageManagerFancy::Start(int a_child_pty)
{
+ child_pty = a_child_pty;
+ int nr_terminal_rows = GetNumberTerminalRows();
if (nr_terminal_rows > 0)
SetupTerminalScrollArea(nr_terminal_rows);
}
void PackageManagerFancy::Stop()
{
+ int nr_terminal_rows = GetNumberTerminalRows();
if (nr_terminal_rows > 0)
{
SetupTerminalScrollArea(nr_terminal_rows + 1);
@@ -273,6 +315,7 @@ void PackageManagerFancy::Stop()
static const char* clear_screen_below_cursor = "\033[J";
std::cout << clear_screen_below_cursor;
}
+ child_pty = -1;
}
bool PackageManagerFancy::StatusChanged(std::string PackageName,
@@ -284,7 +327,7 @@ bool PackageManagerFancy::StatusChanged(std::string PackageName,
HumanReadableAction))
return false;
- int row = nr_terminal_rows;
+ int row = GetNumberTerminalRows();
static string save_cursor = "\033[s";
static string restore_cursor = "\033[u";
diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h
index d721c6373..8a5b68a8f 100644
--- a/apt-pkg/install-progress.h
+++ b/apt-pkg/install-progress.h
@@ -3,7 +3,8 @@
#include <string>
#include <unistd.h>
-
+#include <signal.h>
+#include <vector>
namespace APT {
namespace Progress {
@@ -28,7 +29,7 @@ namespace Progress {
virtual ~PackageManager() {};
/* Global Start/Stop */
- virtual void Start() {};
+ virtual void Start(int child_pty=-1) {};
virtual void Stop() {};
/* When dpkg is invoked (may happen multiple times for each
@@ -116,13 +117,22 @@ namespace Progress {
class PackageManagerFancy : public PackageManager
{
+ private:
+ static void staticSIGWINCH(int);
+ static std::vector<PackageManagerFancy*> instances;
+
protected:
- int nr_terminal_rows;
void SetupTerminalScrollArea(int nr_rows);
+ void HandleSIGWINCH(int);
+
+ int GetNumberTerminalRows();
+ sighandler_t old_SIGWINCH;
+ int child_pty;
public:
PackageManagerFancy();
- virtual void Start();
+ ~PackageManagerFancy();
+ virtual void Start(int child_pty=-1);
virtual void Stop();
virtual bool StatusChanged(std::string PackageName,
unsigned int StepsDone,
diff --git a/apt-pkg/metaindex.h b/apt-pkg/metaindex.h
index 5783735ff..18a90a29d 100644
--- a/apt-pkg/metaindex.h
+++ b/apt-pkg/metaindex.h
@@ -5,6 +5,7 @@
#include <string>
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/indexfile.h>
+#include <apt-pkg/init.h>
#ifndef APT_8_CLEANER_HEADERS
#include <apt-pkg/srcrecords.h>
@@ -28,27 +29,36 @@ class metaIndex
public:
-
// Various accessors
virtual std::string GetURI() const {return URI;}
virtual std::string GetDist() const {return Dist;}
virtual const char* GetType() const {return Type;}
+ // interface to to query it
+#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
+ // returns the path of the local file (or "" if its not available)
+ virtual std::string LocalFileName() const {return "";};
+#endif
+
// Interface for acquire
- virtual std::string ArchiveURI(std::string const& /*File*/) const = 0;
+ virtual std::string ArchiveURI(std::string const& File) const = 0;
virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const = 0;
-
virtual std::vector<pkgIndexFile *> *GetIndexFiles() = 0;
virtual bool IsTrusted() const = 0;
- metaIndex(std::string const &URI, std::string const &Dist, char const * const Type) :
- Indexes(NULL), Type(Type), URI(URI), Dist(Dist) {
+ metaIndex(std::string const &URI, std::string const &Dist,
+ char const * const Type)
+ : Indexes(NULL), Type(Type), URI(URI), Dist(Dist)
+ {
+ /* nothing */
}
- virtual ~metaIndex() {
+ virtual ~metaIndex()
+ {
if (Indexes == 0)
return;
- for (std::vector<pkgIndexFile *>::iterator I = (*Indexes).begin(); I != (*Indexes).end(); ++I)
+ for (std::vector<pkgIndexFile *>::iterator I = (*Indexes).begin();
+ I != (*Indexes).end(); ++I)
delete *I;
delete Indexes;
}
diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc
index 0a06cc6e3..d0f97441d 100644
--- a/apt-pkg/policy.cc
+++ b/apt-pkg/policy.cc
@@ -405,6 +405,10 @@ bool ReadPinFile(pkgPolicy &Plcy,string File)
PreferenceSection Tags;
while (TF.Step(Tags) == true)
{
+ // can happen when there are only comments in a record
+ if (Tags.Count() == 0)
+ continue;
+
string Name = Tags.FindS("Package");
if (Name.empty() == true)
return _error->Error(_("Invalid record in the preferences file %s, no Package header"), File.c_str());
diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc
index e0802e3d5..bef3c76ba 100644
--- a/apt-pkg/tagfile.cc
+++ b/apt-pkg/tagfile.cc
@@ -259,7 +259,12 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
TagCount = 0;
while (TagCount+1 < sizeof(Indexes)/sizeof(Indexes[0]) && Stop < End)
{
- TrimRecord(true,End);
+ TrimRecord(true,End);
+
+ // this can happen when TrimRecord trims away the entire Record
+ // (e.g. because it just contains comments)
+ if(Stop == End)
+ return true;
// Start a new index and add it to the hash
if (isspace(Stop[0]) == 0)
@@ -273,7 +278,9 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
if (Stop == 0)
return false;
- for (; Stop+1 < End && Stop[1] == '\r'; Stop++);
+ for (; Stop+1 < End && Stop[1] == '\r'; Stop++)
+ /* nothing */
+ ;
// Double newline marks the end of the record
if (Stop+1 < End && Stop[1] == '\n')