Skip to content
Snippets Groups Projects
Commit e99aa524 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Support for spying via MQTT between nodes

For read-only spying, the mqtt_spy.js module can be used via jsexec (from an
OS shell command prompt), similar to mosquitto_sub.

For read-write spying, just use the ;SPY sysop command as before and if MQTT
is configured/enabled, it'll use MQTT rather than sockets or shared memory
queues to spy on the target node.

For the first time, you can spy between nodes that are on different servers of
the same BBS using the ;SPY sysop command.

Passes through ctrl characters (except Ctrl-C), unlike the built-in spy
function. This could be revisited later or made optional, but it sems to make
sense to allow Ctrl-Z (e.g. to save a message in fseditor.js) to be passed
through to the target node.
parent 4c10ab2b
No related branches found
No related tags found
1 merge request!463MRC mods by Codefenix (2024-10-20)
// Spy on a terminal server node using MQTT
require("key_defs.js", "CTRL_C");
require("nodedefs.js", "NodeStatus");
"use strict";
function get_ansi_seq()
{
var seq = '';
var key;
while(key = ascii(console.getbyte(100))) {
seq += key;
if(key < '@' || key > '~')
continue;
switch(key) {
case 'A': // Up
case 'B': // Down
case 'C': // Right
case 'D': // Left
case 'F': // Preceding line
case 'H': // Home
case 'K': // End
case 'V': // PageUp
case 'U': // PageDn
case '@': // Insert
case '~': // Various VT-220
// Pass-through these sequences to spied-upon node (eat all others)
return KEY_ESC + '[' + seq;
}
return null;
}
return null;
}
if(argc < 1) {
alert("Node number not specified");
exit(0);
}
var node_num = parseInt(argv[0], 10);
if(node_num < 1 || node_num > system.nodes || isNaN(node_num)
|| (js.global.bbs != undefined && node_num == bbs.node_num)) {
alert("Invalid Node Number: " + node_num);
exit(0);
}
var in_topic = format("sbbs/%s/node/%u/input", system.qwk_id, node_num);
var out_topic = format("sbbs/%s/node/%u/output", system.qwk_id, node_num);
var status_topic = format("sbbs/%s/node/%u/status", system.qwk_id, node_num);
var mqtt = new MQTT();
if(!mqtt.connect()) {
alert("Connect error: " + mqtt.error_str);
exit(1);
}
if(!mqtt.subscribe(status_topic)) {
alert(format("Subscribe to '%s' error: %s", status_topic, mqtt.error_str));
exit(1);
}
var node_status = parseInt(mqtt.read(1000));
if(!mqtt.subscribe(out_topic)) {
alert(format("Subscribe to '%s' error: %s", out_topic, mqtt.error_str));
exit(1);
}
print("*** Synchronet MQTT Spy on Node " + node_num + ": Ctrl-C to Abort ***\r\n");
while(!js.terminated) {
var msg = mqtt.read(/* timeout: */10, /* verbose: */true);
if(msg) {
if(msg.topic == out_topic)
write(msg.data);
else if(msg.topic == status_topic) {
var new_status = parseInt(msg.data, 10);
if(new_status != node_status) {
node_status = new_status;
print("\r\nNew node status: " + NodeStatus[node_status]);
}
}
}
if(js.global.console) {
if(console.aborted || !bbs.online)
break;
console.line_counter = 0;
while(bbs.online) {
var key = ascii(console.getbyte(10));
if(!key)
break;
if(key == KEY_ESC) {
key = ascii(console.getbyte(500));
if(!key)
key = KEY_ESC;
else if(key != '[')
key = KEY_ESC + key;
else
key = get_ansi_seq();
}
mqtt.publish(in_topic, key);
}
}
}
print();
print("Done spying");
......@@ -441,6 +441,9 @@ function str_cmds(str)
str=str.substr(3);
writeln("");
try { // May throw on parseInt()
if(system.mqtt_enabled)
js.exec('mqtt_spy.js', this, parseInt(get_nodenum(str)));
else
bbs.spy(parseInt(get_nodenum(str)));
write("\1n\r\nSpy session complete.\r\n");
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment