diff options
Diffstat (limited to 'apt-pkg')
-rw-r--r-- | apt-pkg/statechanges.cc | 178 |
1 files changed, 120 insertions, 58 deletions
diff --git a/apt-pkg/statechanges.cc b/apt-pkg/statechanges.cc index dc446a665..ed8f9f524 100644 --- a/apt-pkg/statechanges.cc +++ b/apt-pkg/statechanges.cc @@ -3,6 +3,7 @@ #include <apt-pkg/debsystem.h> #include <apt-pkg/fileutl.h> #include <apt-pkg/statechanges.h> +#include <apt-pkg/prettyprinters.h> #include <algorithm> #include <memory> @@ -63,6 +64,7 @@ bool StateChanges::empty() const bool StateChanges::Save(bool const DiscardOutput) { + bool const Debug = _config->FindB("Debug::pkgDpkgPm", false); d->error.clear(); if (d->hold.empty() && d->unhold.empty() && d->install.empty() && d->deinstall.empty() && d->purge.empty()) return true; @@ -83,75 +85,135 @@ bool StateChanges::Save(bool const DiscardOutput) // FIXME: supported only since 1.17.7 in dpkg Args.push_back("-"); int dummyAvail = -1; - pid_t const dpkgMergeAvail = debSystem::ExecDpkg(Args, &dummyAvail, nullptr, true); - - FILE* dpkg = fdopen(dummyAvail, "w"); - for (auto const &V: makeDpkgAvailable) - fprintf(dpkg, "Package: %s\nVersion: 0~\nArchitecture: %s\nMaintainer: Dummy Example <dummy@example.org>\n" - "Description: dummy package record\n A record is needed to put a package on hold, so here it is.\n\n", V.ParentPkg().Name(), V.Arch()); - fclose(dpkg); - - ExecWait(dpkgMergeAvail, "dpkg --merge-avail", true); + if (Debug) + { + for (auto const &V: makeDpkgAvailable) + { + std::clog << "echo 'Dummy record for " << V.ParentPkg().FullName(false) << "' | "; + std::copy(Args.begin(), Args.end(), std::ostream_iterator<std::string>(std::clog, " ")); + std::clog << std::endl; + } + } + else + { + pid_t const dpkgMergeAvail = debSystem::ExecDpkg(Args, &dummyAvail, nullptr, true); + + FILE* dpkg = fdopen(dummyAvail, "w"); + for (auto const &V: makeDpkgAvailable) + fprintf(dpkg, "Package: %s\nVersion: 0~\nArchitecture: %s\nMaintainer: Dummy Example <dummy@example.org>\n" + "Description: dummy package record\n A record is needed to put a package on hold, so here it is.\n\n", V.ParentPkg().Name(), V.Arch()); + fclose(dpkg); + + ExecWait(dpkgMergeAvail, "dpkg --merge-avail", true); + } Args.erase(Args.begin() + BaseArgs, Args.end()); } } bool const dpkgMultiArch = _system->MultiArchSupported(); Args.push_back("--set-selections"); - int selections = -1; - pid_t const dpkgSelections = debSystem::ExecDpkg(Args, &selections, nullptr, DiscardOutput); - - FILE* dpkg = fdopen(selections, "w"); - std::string state; - auto const dpkgName = [&](pkgCache::VerIterator const &V) { - pkgCache::PkgIterator P = V.ParentPkg(); - if (dpkgMultiArch == false) - fprintf(dpkg, "%s %s\n", P.FullName(true).c_str(), state.c_str()); - else - fprintf(dpkg, "%s:%s %s\n", P.Name(), V.Arch(), state.c_str()); - }; - for (auto const &V: d->unhold) + if (Debug) { - if (V.ParentPkg()->CurrentVer != 0) - state = "install"; - else + std::string state; + auto const dpkgName = [&](pkgCache::VerIterator const &V) { + pkgCache::PkgIterator P = V.ParentPkg(); + if (strcmp(V.Arch(), "none") == 0) + ioprintf(std::clog, "echo '%s %s' | ", P.Name(), state.c_str()); + else if (dpkgMultiArch == false) + ioprintf(std::clog, "echo '%s %s' | ", P.FullName(true).c_str(), state.c_str()); + else + ioprintf(std::clog, "echo '%s:%s %s' | ", P.Name(), V.Arch(), state.c_str()); + std::copy(Args.begin(), Args.end(), std::ostream_iterator<std::string>(std::clog, " ")); + std::clog << std::endl; + }; + for (auto const &V: d->unhold) + { + if (V.ParentPkg()->CurrentVer != 0) + state = "install"; + else + state = "deinstall"; + dpkgName(V); + } + if (d->purge.empty() == false) + { + state = "purge"; + std::for_each(d->purge.begin(), d->purge.end(), dpkgName); + } + if (d->deinstall.empty() == false) + { state = "deinstall"; - dpkgName(V); - } - if (d->purge.empty() == false) - { - state = "purge"; - std::for_each(d->purge.begin(), d->purge.end(), dpkgName); - } - if (d->deinstall.empty() == false) - { - state = "deinstall"; - std::for_each(d->deinstall.begin(), d->deinstall.end(), dpkgName); - } - if (d->hold.empty() == false) - { - state = "hold"; - std::for_each(d->hold.begin(), d->hold.end(), dpkgName); + std::for_each(d->deinstall.begin(), d->deinstall.end(), dpkgName); + } + if (d->hold.empty() == false) + { + state = "hold"; + std::for_each(d->hold.begin(), d->hold.end(), dpkgName); + } + if (d->install.empty() == false) + { + state = "install"; + std::for_each(d->install.begin(), d->install.end(), dpkgName); + } } - if (d->install.empty() == false) + else { - state = "install"; - std::for_each(d->install.begin(), d->install.end(), dpkgName); - } - fclose(dpkg); + int selections = -1; + pid_t const dpkgSelections = debSystem::ExecDpkg(Args, &selections, nullptr, DiscardOutput); + + FILE* dpkg = fdopen(selections, "w"); + std::string state; + auto const dpkgName = [&](pkgCache::VerIterator const &V) { + pkgCache::PkgIterator P = V.ParentPkg(); + if (strcmp(V.Arch(), "none") == 0) + fprintf(dpkg, "%s %s\n", P.Name(), state.c_str()); + else if (dpkgMultiArch == false) + fprintf(dpkg, "%s %s\n", P.FullName(true).c_str(), state.c_str()); + else + fprintf(dpkg, "%s:%s %s\n", P.Name(), V.Arch(), state.c_str()); + }; + for (auto const &V: d->unhold) + { + if (V.ParentPkg()->CurrentVer != 0) + state = "install"; + else + state = "deinstall"; + dpkgName(V); + } + if (d->purge.empty() == false) + { + state = "purge"; + std::for_each(d->purge.begin(), d->purge.end(), dpkgName); + } + if (d->deinstall.empty() == false) + { + state = "deinstall"; + std::for_each(d->deinstall.begin(), d->deinstall.end(), dpkgName); + } + if (d->hold.empty() == false) + { + state = "hold"; + std::for_each(d->hold.begin(), d->hold.end(), dpkgName); + } + if (d->install.empty() == false) + { + state = "install"; + std::for_each(d->install.begin(), d->install.end(), dpkgName); + } + fclose(dpkg); - if (ExecWait(dpkgSelections, "dpkg --set-selections") == false) - { - std::move(d->purge.begin(), d->purge.end(), std::back_inserter(d->error)); - d->purge.clear(); - std::move(d->deinstall.begin(), d->deinstall.end(), std::back_inserter(d->error)); - d->deinstall.clear(); - std::move(d->hold.begin(), d->hold.end(), std::back_inserter(d->error)); - d->hold.clear(); - std::move(d->unhold.begin(), d->unhold.end(), std::back_inserter(d->error)); - d->unhold.clear(); - std::move(d->install.begin(), d->install.end(), std::back_inserter(d->error)); - d->install.clear(); + if (ExecWait(dpkgSelections, "dpkg --set-selections") == false) + { + std::move(d->purge.begin(), d->purge.end(), std::back_inserter(d->error)); + d->purge.clear(); + std::move(d->deinstall.begin(), d->deinstall.end(), std::back_inserter(d->error)); + d->deinstall.clear(); + std::move(d->hold.begin(), d->hold.end(), std::back_inserter(d->error)); + d->hold.clear(); + std::move(d->unhold.begin(), d->unhold.end(), std::back_inserter(d->error)); + d->unhold.clear(); + std::move(d->install.begin(), d->install.end(), std::back_inserter(d->error)); + d->install.clear(); + } } return d->error.empty(); } |