diff options
author | Julian Andres Klode <julian.klode@canonical.com> | 2021-04-23 11:37:28 +0200 |
---|---|---|
committer | Julian Andres Klode <julian.klode@canonical.com> | 2021-04-23 12:26:46 +0200 |
commit | 80dd1447595c536d31912c486ac5e96f983ccc7a (patch) | |
tree | 1253ecca8e3d9c609ce0a09417f2a1b900358f2a /apt-private/private-json-hooks.cc | |
parent | dc11a4422d99cb49817c827b9f827617b5880600 (diff) |
json: Hook protocol 0.2 (added upgrade,downgrade,reinstall modes)
Hook protocol 0.2 makes the new fields we added mandatory, and
replaces `install` mode with `upgrade`, `downgrade`, `reinstall`
where appropriate.
Hook negotiation is hacky, but it's the best we can do for now.
Users are advised to upgrade to 0.2
Diffstat (limited to 'apt-private/private-json-hooks.cc')
-rw-r--r-- | apt-private/private-json-hooks.cc | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/apt-private/private-json-hooks.cc b/apt-private/private-json-hooks.cc index a40597e0a..957140525 100644 --- a/apt-private/private-json-hooks.cc +++ b/apt-private/private-json-hooks.cc @@ -17,6 +17,7 @@ #include <ostream> #include <sstream> #include <stack> +#include <unordered_map> #include <signal.h> #include <sys/socket.h> @@ -265,7 +266,7 @@ static void DpkgChrootDirectory() /** * @brief Send a notification to the hook's stream */ -static void NotifyHook(std::ostream &os, std::string const &method, const char **FileList, CacheFile &Cache, std::set<std::string> const &UnknownPackages) +static void NotifyHook(std::ostream &os, std::string const &method, const char **FileList, CacheFile &Cache, std::set<std::string> const &UnknownPackages, int hookVersion) { SortedPackageUniverse Universe(Cache); JsonWriter jsonWriter{os}; @@ -311,7 +312,14 @@ static void NotifyHook(std::ostream &os, std::string const &method, const char * switch (Cache[Pkg].Mode) { case pkgDepCache::ModeInstall: - jsonWriter.name("mode").value("install"); + if (Pkg->CurrentVer != 0 && Cache[Pkg].Upgrade() && hookVersion >= 0x020) + jsonWriter.name("mode").value("upgrade"); + else if (Pkg->CurrentVer != 0 && Cache[Pkg].Downgrade() && hookVersion >= 0x020) + jsonWriter.name("mode").value("downgrade"); + else if (Pkg->CurrentVer != 0 && Cache[Pkg].ReInstall() && hookVersion >= 0x020) + jsonWriter.name("mode").value("reinstall"); + else + jsonWriter.name("mode").value("install"); break; case pkgDepCache::ModeDelete: jsonWriter.name("mode").value(Cache[Pkg].Purge() ? "purge" : "deinstall"); @@ -344,7 +352,7 @@ static void NotifyHook(std::ostream &os, std::string const &method, const char * static std::string BuildHelloMessage() { std::stringstream Hello; - JsonWriter(Hello).beginObject().name("jsonrpc").value("2.0").name("method").value("org.debian.apt.hooks.hello").name("id").value(0).name("params").beginObject().name("versions").beginArray().value("0.1").endArray().endObject().endObject(); + JsonWriter(Hello).beginObject().name("jsonrpc").value("2.0").name("method").value("org.debian.apt.hooks.hello").name("id").value(0).name("params").beginObject().name("versions").beginArray().value("0.1").value("0.2").endArray().endObject().endObject(); return Hello.str(); } @@ -361,11 +369,10 @@ static std::string BuildByeMessage() /// @brief Run the Json hook processes in the given option. bool RunJsonHook(std::string const &option, std::string const &method, const char **FileList, CacheFile &Cache, std::set<std::string> const &UnknownPackages) { - std::stringstream ss; - NotifyHook(ss, method, FileList, Cache, UnknownPackages); - std::string TheData = ss.str(); + std::unordered_map<int, std::string> notifications; std::string HelloData = BuildHelloMessage(); std::string ByeData = BuildByeMessage(); + int hookVersion; bool result = true; @@ -465,6 +472,20 @@ bool RunJsonHook(std::string const &option, std::string const &method, const cha goto out; } + if (strstr(line, "\"0.1\"")) + { + hookVersion = 0x010; + } + else if (strstr(line, "\"0.2\"")) + { + hookVersion = 0x020; + } + else + { + _error->Error("Unknown hook version in handshake from hook %s: %s", Opts->Value.c_str(), line); + goto out; + } + size = getline(&line, &linesize, F); if (size < 0) { @@ -476,9 +497,18 @@ bool RunJsonHook(std::string const &option, std::string const &method, const cha _error->Error("Expected empty line after handshake from %s, received %s", Opts->Value.c_str(), line); goto out; } - - fwrite(TheData.data(), TheData.size(), 1, F); - fwrite("\n\n", 2, 1, F); + { + std::string &data = notifications[hookVersion]; + if (data.empty()) + { + std::stringstream ss; + NotifyHook(ss, method, FileList, Cache, UnknownPackages, hookVersion); + ; + data = ss.str(); + } + fwrite(data.data(), data.size(), 1, F); + fwrite("\n\n", 2, 1, F); + } fwrite(ByeData.data(), ByeData.size(), 1, F); fwrite("\n\n", 2, 1, F); @@ -490,6 +520,7 @@ bool RunJsonHook(std::string const &option, std::string const &method, const cha result = _error->Error("Failure running hook %s", Opts->Value.c_str()); break; } + } signal(SIGINT, old_sigint); signal(SIGPIPE, old_sigpipe); |