!7 set flag DynModule. // central transpileRaw cm RemoteControlled > DynPrintLog { S controllingComputers; bool enabled; switchable bool logAll; transient Q q; visual centerAndSouthWithMargins(super.visualize(), vstackWithSpacing(jrightalignedline(dm_fieldCheckBox('enabled)), withLabel("Computers that can control me:", dm_fieldTextField('controllingComputers)))); start { dm_useLocalMechListCopies(); dm_privateChat(); q = dm_startQ(); ownResource(vmBus_onMessage('gotFromChat, voidfunc(fS msg) { q.add(r { processMsg(null, msg) }) })); ownResource(vmBus_onMessage('gotFromPrivateChat, voidfunc(fS sender, fS msg) { q.add(r { processMsg(sender, msg) }) })); print("Remote Control " + (enabled ? "ENABLED" : "DISABLED") + ". Controlling computers: " + or2(controllingComputers, "-")); } void processMsg(S sender, S msg) { S originalMsg = msg; LS computers = words2(controllingComputers); PairS authorPair = getAuthorOfSignedText2(msg); S author = pairB(authorPair); //print("Author: " + author + ", controlling computers: " + computers); bool allowed = computers.contains(author); msg = trim(unsign(msg)); new Matches m; if (jMatchStart(" eval fresh:", msg, m)) { if (allowed) dm_refreshTranspilerAndLoadedFunctions(); msg = $1 + " eval: " + m.rest(); } bool realEval = jMatchStart(" eval real", msg, m); if (realEval) msg = $1 + " eval " + m.rest(); if (jMatchStart(" eval fresh :", msg, m)) { if (allowed) dm_refreshTranspiler(); msg = $1 + " eval " + $2 + ": " + m.rest(); } if (jMatchStart(" eval :", msg, m)) { if (neqOneOf($1, "all", computerID())) ret with print("Not for me."); else if (!enabled) print("Will not eval (module disabled)."); else { print(trim(indentx("EVAL from " + author + ": " + shorten(m.rest(), 1000)))); O result = null; S error = null; try { if (logAll) logQuoted(javaxCachesDir("signed-instructions.txt"), originalMsg); if (!allowed) if (pairB(authorPair) == null) { print(l(originalMsg) + " " + quote(shorten(originalMsg, 1000))); print(quote(takeLast(originalMsg, 1000))); fail("Signature didn't verify (computer ID: " + pairA(authorPair) + ", public key md5: " + md5(getPublicKeyOfComputer(pairA(authorPair))) + ")"); } else fail("not accepting commands from " + author); result = realEval ? dm_javaEval(m.rest()) : dm_javaEvalOrInterpret(m.rest()); } catch print e { error = getStackTrace(e); } S mode = "direct"; S out; if (result != null) { int l = l_opt(result); print(">> " + (l != 0 ? "[l=" + l + "] " : "") + result); } if (error != null) { mode = "error"; out = error; } else if (result instanceof byte[]) { mode = "base64"; out = base64((byte[]) result); } else { out = str(result); if (empty(out) || trimmable(out) || containsNewLine(out)) { out = quote(out); mode = "quoted"; } } S line = "done " + $2 + " " + mode + ": " + out; if (sender == null) dm_osChat_postSigned(line); else dm_privateChat_sendSigned(sender, line); } ret; } if (!allowed) ret; // old-style formats follow //print("Got signed message from " + author + ": " + msg); if (jMatchStart(" eval:", msg, m)) { if (neqOneOf($1, "all", computerID())) print("Not for me."); else if (!enabled) print("Will not eval (module disabled)."); else { print(trim(indentx("EVAL: " + shorten(m.rest(), 1000)))); O result = dm_javaEvalOrInterpret(m.rest()); print(">> " + result); } } } // API bool addControllingComputer(S computerID) { if (contains(controllingComputers, computerID)) false; setField(controllingComputers := trim(controllingComputers + " " + computerID)); true; } }