X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/f74d99c6a78caafdc6e32d8cb135683b7154795c..cc9745a0d81a3e1aa5ef6f99f7ad638d26bdb950:/apt-pkg/edsp.cc diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index ae5c7a373..27b269fd2 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -911,14 +911,14 @@ bool EDSP::WriteSolutionStanza(FileFd &output, char const * const Type, pkgCache /*}}}*/ // EDSP::WriteProgess - pulse to the given file descriptor /*{{{*/ bool EDSP::WriteProgress(unsigned short const percent, const char* const message, FILE* output) { - fprintf(output, "Progress: %s\n", TimeRFC1123(time(NULL)).c_str()); + fprintf(output, "Progress: %s\n", TimeRFC1123(time(NULL), true).c_str()); fprintf(output, "Percentage: %d\n", percent); fprintf(output, "Message: %s\n\n", message); fflush(output); return true; } bool EDSP::WriteProgress(unsigned short const percent, const char* const message, FileFd &output) { - return WriteOkay(output, "Progress: ", TimeRFC1123(time(NULL)), "\n", + return WriteOkay(output, "Progress: ", TimeRFC1123(time(NULL), true), "\n", "Percentage: ", percent, "\n", "Message: ", message, "\n\n") && output.Flush(); } @@ -1074,26 +1074,48 @@ bool EDSP::ResolveExternal(const char* const solver, pkgDepCache &Cache, bool EIPP::OrderInstall(char const * const solver, pkgPackageManager * const PM, /*{{{*/ unsigned int const flags, OpProgress * const Progress) { + if (strcmp(solver, "internal") == 0) + { + auto const dumpfile = _config->FindFile("Dir::Log::Planner"); + if (dumpfile.empty()) + return false; + auto const dumpdir = flNotFile(dumpfile); + FileFd output; + if (CreateAPTDirectoryIfNeeded(dumpdir, dumpdir) == false || + output.Open(dumpfile, FileFd::WriteOnly | FileFd::Exclusive | FileFd::Create, FileFd::Extension, 0644) == false) + return _error->WarningE("EIPP::OrderInstall", _("Could not open file '%s'"), dumpfile.c_str()); + bool Okay = EIPP::WriteRequest(PM->Cache, output, flags, nullptr); + return Okay && EIPP::WriteScenario(PM->Cache, output, nullptr); + } + int solver_in, solver_out; - pid_t const solver_pid = ExecuteExternal("planer", solver, "Dir::Bin::Planers", &solver_in, &solver_out); + pid_t const solver_pid = ExecuteExternal("planner", solver, "Dir::Bin::Planners", &solver_in, &solver_out); if (solver_pid == 0) return false; FileFd output; if (output.OpenDescriptor(solver_in, FileFd::WriteOnly | FileFd::BufferedWrite, true) == false) - return _error->Errno("OrderInstall", "Opening planer %s stdin on fd %d for writing failed", solver, solver_in); + return _error->Errno("EIPP::OrderInstall", "Opening planner %s stdin on fd %d for writing failed", solver, solver_in); bool Okay = output.Failed() == false; if (Progress != NULL) - Progress->OverallProgress(0, 100, 5, _("Execute external planer")); + Progress->OverallProgress(0, 100, 5, _("Execute external planner")); Okay &= EIPP::WriteRequest(PM->Cache, output, flags, Progress); if (Progress != NULL) - Progress->OverallProgress(5, 100, 20, _("Execute external planer")); + Progress->OverallProgress(5, 100, 20, _("Execute external planner")); Okay &= EIPP::WriteScenario(PM->Cache, output, Progress); output.Close(); if (Progress != NULL) - Progress->OverallProgress(25, 100, 75, _("Execute external planer")); + Progress->OverallProgress(25, 100, 75, _("Execute external planner")); + + // we don't tell the external planners about boring things + for (auto Pkg = PM->Cache.PkgBegin(); Pkg.end() == false; ++Pkg) + { + if (Pkg->CurrentState == pkgCache::State::ConfigFiles && PM->Cache[Pkg].Purge() == true) + PM->Remove(Pkg, true); + } + if (Okay && EIPP::ReadResponse(solver_out, PM, Progress) == false) return false; @@ -1104,19 +1126,18 @@ bool EIPP::WriteRequest(pkgDepCache &Cache, FileFd &output, /*{{{*/ unsigned int const flags, OpProgress * const Progress) { - (void)(flags); if (Progress != NULL) - Progress->SubProgress(Cache.Head().PackageCount, _("Send request to planer")); + Progress->SubProgress(Cache.Head().PackageCount, _("Send request to planner")); unsigned long p = 0; - string del, purge, inst, reinst; + string del, inst, reinst; for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg, ++p) { if (Progress != NULL && p % 100 == 0) Progress->Progress(p); string* req; pkgDepCache::StateCache &P = Cache[Pkg]; - if (P.Purge() == true) - req = &purge; + if (P.Purge() == true && Pkg->CurrentState == pkgCache::State::ConfigFiles) + continue; if (P.Delete() == true) req = &del; else if (P.NewInstall() == true || P.Upgrade() == true || P.Downgrade() == true) @@ -1137,15 +1158,19 @@ bool EIPP::WriteRequest(pkgDepCache &Cache, FileFd &output, /*{{{*/ WriteOkay(Okay, output, " ", *a); WriteOkay(Okay, output, "\n"); - if (purge.empty() == false) - WriteOkay(Okay, output, "Purge:", purge, "\n"); if (del.empty() == false) WriteOkay(Okay, output, "Remove:", del, "\n"); if (inst.empty() == false) WriteOkay(Okay, output, "Install:", inst, "\n"); if (reinst.empty() == false) WriteOkay(Okay, output, "ReInstall:", reinst, "\n"); - WriteOkay(Okay, output, "Planer: ", _config->Find("APT::Planer", "internal"), "\n"); + WriteOkay(Okay, output, "Planner: ", _config->Find("APT::Planner", "internal"), "\n"); + if ((flags & Request::IMMEDIATE_CONFIGURATION_ALL) != 0) + WriteOkay(Okay, output, "Immediate-Configuration: yes\n"); + else if ((flags & Request::NO_IMMEDIATE_CONFIGURATION) != 0) + WriteOkay(Okay, output, "Immediate-Configuration: no\n"); + else if ((flags & Request::ALLOW_TEMPORARY_REMOVE_OF_ESSENTIALS) != 0) + WriteOkay(Okay, output, "Allow-Temporary-Remove-of-Essentials: yes\n"); return WriteOkay(Okay, output, "\n"); } /*}}}*/ @@ -1192,7 +1217,7 @@ template void forAllInterestingVersions(pkgDepCache &Cache, bool EIPP::WriteScenario(pkgDepCache &Cache, FileFd &output, OpProgress * const Progress) { if (Progress != NULL) - Progress->SubProgress(Cache.Head().PackageCount, _("Send scenario to planer")); + Progress->SubProgress(Cache.Head().PackageCount, _("Send scenario to planner")); unsigned long p = 0; bool Okay = output.Failed() == false; std::vector archs = APT::Configuration::getArchitectures(); @@ -1212,6 +1237,35 @@ bool EIPP::WriteScenario(pkgDepCache &Cache, FileFd &output, OpProgress * const pkgset[PV->ID] = true; } pkgset[P->ID] = true; + if (strcmp(P.Arch(), "any") == 0) + { + APT::StringView const pkgname(P.Name()); + auto const idxColon = pkgname.find(':'); + if (idxColon != APT::StringView::npos) + { + pkgCache::PkgIterator PA; + if (pkgname.substr(idxColon + 1) == "any") + { + auto const GA = Cache.FindGrp(pkgname.substr(0, idxColon).to_string()); + for (auto PA = GA.PackageList(); PA.end() == false; PA = GA.NextPkg(PA)) + { + pkgset[PA->ID] = true; + } + } + else + { + auto const PA = Cache.FindPkg(pkgname.to_string()); + if (PA.end() == false) + pkgset[PA->ID] = true; + } + } + } + else + { + auto const PA = Cache.FindPkg(P.FullName(false), "any"); + if (PA.end() == false) + pkgset[PA->ID] = true; + } } }; for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) @@ -1264,18 +1318,18 @@ bool EIPP::ReadResponse(int const input, pkgPackageManager * const PM, OpProgres } else if (section.Exists("Error") == true) { std::string msg = SubstVar(SubstVar(section.FindS("Message"), "\n .\n", "\n\n"), "\n ", "\n"); if (msg.empty() == true) { - msg = _("External planer failed without a proper error message"); + msg = _("External planner failed without a proper error message"); _error->Error("%s", msg.c_str()); } else - _error->Error("External planer failed with: %s", msg.substr(0,msg.find('\n')).c_str()); + _error->Error("External planner failed with: %s", msg.substr(0,msg.find('\n')).c_str()); if (Progress != NULL) Progress->Done(); - std::cerr << "The planer encountered an error of type: " << section.FindS("Error") << std::endl; + std::cerr << "The planner encountered an error of type: " << section.FindS("Error") << std::endl; std::cerr << "The following information might help you to understand what is wrong:" << std::endl; std::cerr << msg << std::endl << std::endl; return false; - } else if (section.Exists("Install") == true) - type = "Install"; + } else if (section.Exists("Unpack") == true) + type = "Unpack"; else if (section.Exists("Configure") == true) type = "Configure"; else if (section.Exists("Remove") == true) @@ -1300,7 +1354,7 @@ bool EIPP::ReadResponse(int const input, pkgPackageManager * const PM, OpProgres pkgCache::VerIterator Ver(PM->Cache.GetCache(), PM->Cache.GetCache().VerP + VerIdx[id]); auto const Pkg = Ver.ParentPkg(); - if (strcmp(type, "Install") == 0) + if (strcmp(type, "Unpack") == 0) PM->Install(Pkg, PM->FileNames[Pkg->ID]); else if (strcmp(type, "Configure") == 0) PM->Configure(Pkg); @@ -1342,8 +1396,17 @@ bool EIPP::ReadRequest(int const input, std::listSet("APT::Architecture", line); else if (LineStartsWithAndStrip(line, "Architectures:")) _config->Set("APT::Architectures", SubstVar(line, " ", ",")); - else if (LineStartsWithAndStrip(line, "Planer:")) + else if (LineStartsWithAndStrip(line, "Planner:")) ; // purely informational line + else if (LineStartsWithAndStrip(line, "Immediate-Configuration:")) + { + if (localStringToBool(line, true)) + flags |= Request::IMMEDIATE_CONFIGURATION_ALL; + else + flags |= Request::NO_IMMEDIATE_CONFIGURATION; + } + else if (ReadFlag(flags, line, "Allow-Temporary-Remove-of-Essentials:", Request::ALLOW_TEMPORARY_REMOVE_OF_ESSENTIALS)) + ; else _error->Warning("Unknown line in EIPP Request stanza: %s", line.c_str());