diff options
author | Daniel Nicoletti <dantti12@gmail.com> | 2012-04-16 16:24:39 -0300 |
---|---|---|
committer | Daniel Nicoletti <dantti12@gmail.com> | 2012-04-16 16:24:39 -0300 |
commit | cfb310be151e667359bd4fcf78081e53764da00e (patch) | |
tree | 397384ee7460fddc8596225fdcc1702b0399a5a2 | |
parent | 2a5d5124f987281de8ad7bede501175e4ec0b848 (diff) |
aptcc: Move ShowBroken to AptCacheFile, and added CheckDeps from apt-get
-rw-r--r-- | backends/aptcc/AptCacheFile.cpp | 200 | ||||
-rw-r--r-- | backends/aptcc/AptCacheFile.h | 15 | ||||
-rw-r--r-- | backends/aptcc/Makefile.am | 2 | ||||
-rw-r--r-- | backends/aptcc/apt-intf.cpp | 12 | ||||
-rw-r--r-- | backends/aptcc/apt-messages.cpp | 131 | ||||
-rw-r--r-- | backends/aptcc/apt-messages.h | 6 | ||||
-rw-r--r-- | backends/aptcc/pk-backend-aptcc.cpp | 11 |
7 files changed, 226 insertions, 151 deletions
diff --git a/backends/aptcc/AptCacheFile.cpp b/backends/aptcc/AptCacheFile.cpp index 94bff865..fcab43a3 100644 --- a/backends/aptcc/AptCacheFile.cpp +++ b/backends/aptcc/AptCacheFile.cpp @@ -19,13 +19,20 @@ */ #include "AptCacheFile.h" -AptCacheFile::AptCacheFile() : +#include <apt-pkg/algorithms.h> +#include <sstream> +#include <cstdio> + +AptCacheFile::AptCacheFile(PkBackend *backend) : m_packageRecords(0) { + std::cout << "AptCacheFile::AptCacheFile()" << std::endl; } AptCacheFile::~AptCacheFile() { + std::cout << "AptCacheFile::~AptCacheFile()" << std::endl; + delete m_packageRecords; pkgCacheFile::Close(); } @@ -50,6 +57,195 @@ bool AptCacheFile::BuildCaches(bool withLock) return pkgCacheFile::BuildCaches(NULL, withLock); } +bool AptCacheFile::CheckDeps(bool AllowBroken) +{ + bool FixBroken = _config->FindB("APT::Get::Fix-Broken",false); + + if (_error->PendingError() == true) { + return false; + } + + // Check that the system is OK + if (DCache->DelCount() != 0 || DCache->InstCount() != 0) { + return _error->Error("Internal error, non-zero counts"); + } + + // Apply corrections for half-installed packages + if (pkgApplyStatus(*DCache) == false) { + return false; + } + + if (_config->FindB("APT::Get::Fix-Policy-Broken",false) == true) { + FixBroken = true; + if ((DCache->PolicyBrokenCount() > 0)) { + // upgrade all policy-broken packages with ForceImportantDeps=True + for (pkgCache::PkgIterator I = Cache->PkgBegin(); !I.end(); ++I) { + if ((*DCache)[I].NowPolicyBroken() == true) { + DCache->MarkInstall(I,true,0, false, true); + } + } + } + } + + // Nothing is broken + if (DCache->BrokenCount() == 0 || AllowBroken == true) { + return true; + } + + // Attempt to fix broken things + if (FixBroken == true) { +// c1out << _("Correcting dependencies...") << flush; + if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0) { +// c1out << _(" failed.") << endl; + ShowBroken(true); + + return _error->Error("Unable to correct dependencies"); + } + if (pkgMinimizeUpgrade(*DCache) == false) { + return _error->Error("Unable to minimize the upgrade set"); + } + +// c1out << _(" Done") << endl; + } else { +// c1out << _("You might want to run 'apt-get -f install' to correct these.") << endl; + ShowBroken(true); + + return _error->Error("Unmet dependencies. Try using -f."); + } + + return true; +} + +void AptCacheFile::ShowBroken(bool Now) +{ + std::stringstream out; + + out << "The following packages have unmet dependencies:" << std::endl; + for (pkgCache::PkgIterator I = (*this)->PkgBegin(); ! I.end(); ++I) { + if (Now == true) { + if ((*this)[I].NowBroken() == false) { + continue; + } + } else { + if ((*this)[I].InstBroken() == false){ + continue; + } + } + + // Print out each package and the failed dependencies + out << " " << I.Name() << ":"; + unsigned Indent = strlen(I.Name()) + 3; + bool First = true; + pkgCache::VerIterator Ver; + + if (Now == true) { + Ver = I.CurrentVer(); + } else { + Ver = (*this)[I].InstVerIter(*this); + } + + if (Ver.end() == true) { + out << std::endl; + continue; + } + + for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;) { + // Compute a single dependency element (glob or) + pkgCache::DepIterator Start; + pkgCache::DepIterator End; + D.GlobOr(Start,End); // advances D + + if ((*this)->IsImportantDep(End) == false){ + continue; + } + + if (Now == true) { + if (((*this)[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow){ + continue; + } + } else { + if (((*this)[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall) { + continue; + } + } + + bool FirstOr = true; + while (1) { + if (First == false){ + for (unsigned J = 0; J != Indent; J++) { + out << ' '; + } + } + First = false; + + if (FirstOr == false) { + for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++) { + out << ' '; + } + } else { + out << ' ' << End.DepType() << ": "; + } + FirstOr = false; + + out << Start.TargetPkg().Name(); + + // Show a quick summary of the version requirements + if (Start.TargetVer() != 0) { + out << " (" << Start.CompType() << " " << Start.TargetVer() << ")"; + } + + /* Show a summary of the target package if possible. In the case + of virtual packages we show nothing */ + pkgCache::PkgIterator Targ = Start.TargetPkg(); + if (Targ->ProvidesList == 0) { + out << ' '; + pkgCache::VerIterator Ver = (*this)[Targ].InstVerIter(*this); + if (Now == true) { + Ver = Targ.CurrentVer(); + } + + if (Ver.end() == false) + { + char buffer[1024]; + if (Now == true) { + sprintf(buffer, "but %s is installed", Ver.VerStr()); + } else { + sprintf(buffer, "but %s is to be installed", Ver.VerStr()); + } + + out << buffer; + } else { + if ((*this)[Targ].CandidateVerIter(*this).end() == true) { + if (Targ->ProvidesList == 0) { + out << "but it is not installable"; + } else { + out << "but it is a virtual package"; + } + } else { + if (Now) { + out << "but it is not installed"; + } else { + out << "but it is not going to be installed"; + } + } + } + } + + if (Start != End) { + out << " or"; + } + out << std::endl; + + if (Start == End){ + break; + } + Start++; + } + } + } + pk_backend_error_code(m_backend, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, out.str().c_str()); +} + void AptCacheFile::buildPkgRecords() { if (m_packageRecords) { @@ -57,5 +253,5 @@ void AptCacheFile::buildPkgRecords() } // Create the text record parser - m_packageRecords = new pkgRecords(*this->GetPkgCache()); + m_packageRecords = new pkgRecords(*this); } diff --git a/backends/aptcc/AptCacheFile.h b/backends/aptcc/AptCacheFile.h index bb265be4..620b5687 100644 --- a/backends/aptcc/AptCacheFile.h +++ b/backends/aptcc/AptCacheFile.h @@ -21,11 +21,12 @@ #define APTCACHEFILE_H #include <apt-pkg/cachefile.h> +#include <pk-backend.h> class AptCacheFile : public pkgCacheFile { public: - AptCacheFile(); + AptCacheFile(PkBackend *backend); ~AptCacheFile(); /** @@ -43,6 +44,17 @@ public: */ bool BuildCaches(bool withLock = false); + /** This routine generates the caches and then opens the dependency cache + * and verifies that the system is OK. + */ + bool CheckDeps(bool AllowBroken = false); + + /** Shows a list of all broken packages together with their + * dependencies. Similar to and based on the equivalent routine in + * apt-get. + */ + void ShowBroken(bool Now); + inline pkgRecords* GetPkgRecords() { buildPkgRecords(); return m_packageRecords; } /** @@ -61,6 +73,7 @@ private: void buildPkgRecords(); pkgRecords *m_packageRecords; + PkBackend *m_backend; }; #endif // APTCACHEFILE_H diff --git a/backends/aptcc/Makefile.am b/backends/aptcc/Makefile.am index 25b36a53..b510b05f 100644 --- a/backends/aptcc/Makefile.am +++ b/backends/aptcc/Makefile.am @@ -12,8 +12,8 @@ libpk_backend_aptcc_la_SOURCES = pkg_acqfile.cpp \ apt-messages.cpp \ apt-utils.cpp \ apt-sourceslist.cpp \ - apt-intf.cpp \ AptCacheFile.cpp \ + apt-intf.cpp \ pk-backend-aptcc.cpp libpk_backend_aptcc_la_LIBADD = -lcrypt -lapt-pkg -lapt-inst $(PK_PLUGIN_LIBS) libpk_backend_aptcc_la_LDFLAGS = -module -avoid-version $(APTCC_LIBS) $(GSTREAMER_LIBS) diff --git a/backends/aptcc/apt-intf.cpp b/backends/aptcc/apt-intf.cpp index 11d13af2..aa2bc3e9 100644 --- a/backends/aptcc/apt-intf.cpp +++ b/backends/aptcc/apt-intf.cpp @@ -54,6 +54,7 @@ #define RAMFS_MAGIC 0x858458f6 AptIntf::AptIntf(PkBackend *backend, bool &cancel) : + m_cache(backend), m_backend(backend), m_cancel(cancel), m_terminalTimeout(120), @@ -93,7 +94,10 @@ bool AptIntf::init() setenv("ftp_proxy", ftp_proxy, 1); // Tries to open the cache - return !m_cache.Open(); + bool ret; + ret = m_cache.Open(); + cout << "AptIntf::init() " << ret << endl; + return !ret; } AptIntf::~AptIntf() @@ -2258,7 +2262,7 @@ bool AptIntf::runTransaction(PkgList &install, PkgList &remove, bool simulate, b bool withLock = !simulate; // Check to see if we are just simulating, //since for that no lock is needed - AptCacheFile cache; + AptCacheFile cache(m_backend); int timeout = 10; // TODO test this while (cache.Open(withLock) == false) { @@ -2332,7 +2336,7 @@ bool AptIntf::runTransaction(PkgList &install, PkgList &remove, bool simulate, b if (cache->BrokenCount() != 0) { // if the problem resolver could not fix all broken things // show what is broken - show_broken(m_backend, cache, false); + cache.ShowBroken(false); return false; } } @@ -2374,7 +2378,7 @@ bool AptIntf::installPackages(AptCacheFile &cache, bool simulating) // Sanity check if (cache->BrokenCount() != 0) { // TODO - show_broken(m_backend, cache, false); + cache.ShowBroken(false); _error->Error("Internal error, InstallPackages was called with broken packages!"); return false; } diff --git a/backends/aptcc/apt-messages.cpp b/backends/aptcc/apt-messages.cpp index c02bfcd0..15e548ec 100644 --- a/backends/aptcc/apt-messages.cpp +++ b/backends/aptcc/apt-messages.cpp @@ -81,134 +81,3 @@ bool show_warnings(PkBackend *backend, PkMessageEnum message) pk_backend_message(backend, message, warnings.str().c_str()); } } - -/** Shows broken dependencies for a single package */ -void show_broken(PkBackend *backend, pkgCacheFile &Cache, bool Now) -{ - stringstream out; - - out << "The following packages have unmet dependencies:" << endl; - for (pkgCache::PkgIterator I = Cache->PkgBegin(); ! I.end(); ++I) { - if (Now == true) { - if (Cache[I].NowBroken() == false) { - continue; - } - } else { - if (Cache[I].InstBroken() == false){ - continue; - } - } - - // Print out each package and the failed dependencies - out << " " << I.Name() << ":"; - unsigned Indent = strlen(I.Name()) + 3; - bool First = true; - pkgCache::VerIterator Ver; - - if (Now == true) { - Ver = I.CurrentVer(); - } else { - Ver = Cache[I].InstVerIter(Cache); - } - - if (Ver.end() == true) { - out << endl; - continue; - } - - for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;) { - // Compute a single dependency element (glob or) - pkgCache::DepIterator Start; - pkgCache::DepIterator End; - D.GlobOr(Start,End); // advances D - - if (Cache->IsImportantDep(End) == false){ - continue; - } - - if (Now == true) { - if ((Cache[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow){ - continue; - } - } else { - if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall) { - continue; - } - } - - bool FirstOr = true; - while (1) { - if (First == false){ - for (unsigned J = 0; J != Indent; J++) { - out << ' '; - } - } - First = false; - - if (FirstOr == false) { - for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++) { - out << ' '; - } - } else { - out << ' ' << End.DepType() << ": "; - } - FirstOr = false; - - out << Start.TargetPkg().Name(); - - // Show a quick summary of the version requirements - if (Start.TargetVer() != 0) { - out << " (" << Start.CompType() << " " << Start.TargetVer() << ")"; - } - - /* Show a summary of the target package if possible. In the case - of virtual packages we show nothing */ - pkgCache::PkgIterator Targ = Start.TargetPkg(); - if (Targ->ProvidesList == 0) { - out << ' '; - pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache); - if (Now == true) { - Ver = Targ.CurrentVer(); - } - - if (Ver.end() == false) - { - char buffer[1024]; - if (Now == true) { - sprintf(buffer, "but %s is installed", Ver.VerStr()); - } else { - sprintf(buffer, "but %s is to be installed", Ver.VerStr()); - } - - out << buffer; - } else { - if (Cache[Targ].CandidateVerIter(Cache).end() == true) { - if (Targ->ProvidesList == 0) { - out << "but it is not installable"; - } else { - out << "but it is a virtual package"; - } - } else { - if (Now) { - out << "but it is not installed"; - } else { - out << "but it is not going to be installed"; - } - } - } - } - - if (Start != End) { - out << " or"; - } - out << endl; - - if (Start == End){ - break; - } - Start++; - } - } - } - pk_backend_error_code (backend, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, out.str().c_str()); -} diff --git a/backends/aptcc/apt-messages.h b/backends/aptcc/apt-messages.h index 8c49988d..bdd04d0b 100644 --- a/backends/aptcc/apt-messages.h +++ b/backends/aptcc/apt-messages.h @@ -42,10 +42,4 @@ bool show_errors(PkBackend *backend, bool show_warnings(PkBackend *backend, PkMessageEnum message = PK_MESSAGE_ENUM_UNKNOWN); -/** Shows a list of all broken packages together with their - * dependencies. Similar to and based on the equivalent routine in - * apt-get. - */ -void show_broken(PkBackend *backend, pkgCacheFile &cache, bool Now); - #endif // AAPT_BACKEND_MESSAGES_H diff --git a/backends/aptcc/pk-backend-aptcc.cpp b/backends/aptcc/pk-backend-aptcc.cpp index 68cee840..4a4b8c38 100644 --- a/backends/aptcc/pk-backend-aptcc.cpp +++ b/backends/aptcc/pk-backend-aptcc.cpp @@ -376,16 +376,15 @@ static gboolean backend_get_or_update_system_thread (PkBackend *backend) pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY); - AptCacheFile cache; + AptCacheFile cache(backend); int timeout = 10; // TODO test this - while (cache.Open(!getUpdates) == false) { - // failed to open cache, try checkDeps then.. - // || Cache.CheckDeps(CmdL.FileSize() != 1) == false + while (cache.Open(!getUpdates) == false || cache.CheckDeps() == false) { if (getUpdates == true || (timeout <= 0)) { pk_backend_error_code(backend, PK_ERROR_ENUM_NO_CACHE, "Could not open package cache."); + delete m_apt; return false; } else { pk_backend_set_status(backend, PK_STATUS_ENUM_WAITING_FOR_LOCK); @@ -396,7 +395,7 @@ static gboolean backend_get_or_update_system_thread (PkBackend *backend) pk_backend_set_status(backend, PK_STATUS_ENUM_RUNNING); if (pkgDistUpgrade(*cache) == false) { - show_broken(backend, cache, false); + cache.ShowBroken(false); g_debug ("Internal error, DistUpgrade broke stuff"); delete m_apt; return false; @@ -687,7 +686,7 @@ static gboolean pk_backend_refresh_cache_thread(PkBackend *backend) m_apt->refreshCache(); // Rebuild the cache. - AptCacheFile cache; + AptCacheFile cache(backend); if (cache.BuildCaches(true) == false) { if (_error->PendingError() == true) { show_errors(backend, PK_ERROR_ENUM_CANNOT_FETCH_SOURCES, true); |