' +
'';
}).join('');
}
+ /** Entfernt einen Agenten aus der Liste (z.B. den alten Namen nach dem
+ * Umbenennen). Läuft er noch, meldet er sich von selbst wieder. */
+ function forgetHost(hostId, name) {
+ if (!confirm('"' + name + '" aus der Liste entfernen?\n\n' +
+ 'Das stoppt den Agenten NICHT — läuft er noch, erscheint er ' +
+ 'beim nächsten Lebenszeichen wieder.')) return;
+ send({ action: 'host_forget', hostId });
+ }
+
// ── APK-Rollout auf Android/Fire TV (per Satellit + ADB) ─────────
let apkTarget = null; // {satId, ip, name}
let apkRequestId = null;
diff --git a/diagnostic/server.js b/diagnostic/server.js
index f842af8..6caa258 100644
--- a/diagnostic/server.js
+++ b/diagnostic/server.js
@@ -2812,6 +2812,14 @@ wss.on("connection", (ws) => {
} else if (msg.action === "host_list") {
// Browser will die aktuelle Host-Agenten-Liste.
ws.send(JSON.stringify({ type: "host_update", hosts: hostList() }));
+ } else if (msg.action === "host_forget") {
+ // Alten/umbenannten Agenten aus der Liste werfen. Meldet er sich wieder
+ // (host_hello), taucht er automatisch neu auf — das ist also gefahrlos.
+ const id = String(msg.hostId || "");
+ if (id && hosts.delete(id)) {
+ log("info", "host", `Agent '${id}' aus der Liste entfernt`);
+ broadcastHosts();
+ }
} else if (msg.action === "rooms_query") {
// Browser will die RVS-Raum-Diagnose — via persistente rvsWs anfragen,
// die Antwort (rooms_info) kommt auf derselben Verbindung zurueck.
diff --git a/satellite/satellite.py b/satellite/satellite.py
index 66e1c6b..0d68a52 100644
--- a/satellite/satellite.py
+++ b/satellite/satellite.py
@@ -1301,18 +1301,23 @@ def _do_adb_provision(params: dict) -> dict:
return {"ok": False, "error": f"'{package}' ist nicht installiert — "
"erst adb.install ausfuehren."}
+ # WICHTIG: 'adb shell' haengt die Argumente zu EINER Kommandozeile zusammen,
+ # die auf dem Geraet nochmal von der Shell zerlegt wird. Werte mit Leerzeichen
+ # ("Wohnzimmer Fire TV") wuerden dabei abgeschnitten -> jeden Wert quoten.
+ import shlex
+ q = shlex.quote
args = ["-s", target, "shell", "am", "start",
"-n", f"{package}/.MainActivity",
"-a", f"{package}.PROVISION",
- "-e", "host", rvs_host,
- "-e", "token", rvs_token,
+ "-e", "host", q(rvs_host),
+ "-e", "token", q(rvs_token),
"--ei", "port", str(int(params.get("rvs_port") or 443)),
"--ez", "tls", "true" if _as_bool(params.get("rvs_tls"), True) else "false",
"--ez", "control", "true" if _as_bool(params.get("control"), True) else "false"]
if params.get("name"):
- args += ["-e", "name", str(params["name"])]
+ args += ["-e", "name", q(str(params["name"]))]
if params.get("reply_mode"):
- args += ["-e", "reply_mode", str(params["reply_mode"])]
+ args += ["-e", "reply_mode", q(str(params["reply_mode"]))]
rc, out, err = _adb_run(args, timeout=60)
if rc != 0 or "Error" in f"{out} {err}":