Added server console, KVM jumbo accumulator.

This commit is contained in:
Ylian Saint-Hilaire 2019-02-04 18:06:01 -08:00
parent 0ed26d55cf
commit cebb0ce63e
17 changed files with 275 additions and 130 deletions

View File

@ -1,5 +1,5 @@
/*
Copyright 2018-2019 Intel Corporation
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -187,14 +187,9 @@ function serviceHost(serviceName)
console.log(e);
process.exit();
}
if (process.platform == 'win32' || process.platform == 'darwin')
{
// Only do this on Windows/MacOS, becuase Linux is async... It'll complete later
console.log(this._ServiceOptions.name + ' installed');
process.exit();
}
i = process.argv.length;
serviceOperation = 1;
console.log(this._ServiceOptions.name + ' installed');
process.exit();
break;
case '-uninstall':
if (!this._svcManager) { this._svcManager = new serviceManager(); }
@ -301,9 +296,6 @@ function serviceHost(serviceName)
}
process.exit();
break;
default:
// Unknown arguments, skip it.
break;
}
}

View File

@ -1,5 +1,5 @@
/*
Copyright 2018-2019 Intel Corporation
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -46,9 +46,6 @@ function parseServiceStatus(token)
case 0x00000001:
j.state = 'STOPPED';
break;
default:
// Unknown service state
break;
}
var controlsAccepted = token.Deref((2 * 4), 4).toBuffer().readUInt32LE();
j.controlsAccepted = [];
@ -295,13 +292,14 @@ function serviceManager()
require('fs').chmodSync('/etc/init.d/' + options.name, m);
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._moduleName = options.name;
this._update.on('exit', function onUpdateRC_d() { console.log(this._moduleName + ' installed'); process.exit(); });
this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('update-rc.d ' + options.name + ' defaults\n');
this._update.stdin.write('exit\n');
//update-rc.d meshagent defaults # creates symlinks for rc.d
//service meshagent start
this._update.waitExit();
break;
case 'systemd':
var serviceDescription = options.description ? options.description : 'MeshCentral Agent';
@ -313,11 +311,10 @@ function serviceManager()
require('fs').writeFileSync('/lib/systemd/system/' + options.name + '.service', '[Unit]\nDescription=' + serviceDescription + '\n[Service]\nExecStart=/usr/local/mesh/' + options.name + '\nStandardOutput=null\nRestart=always\nRestartSec=3\n[Install]\nWantedBy=multi-user.target\nAlias=' + options.name + '.service\n', { flags: 'w' });
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._moduleName = options.name;
this._update.on('exit', function onUpdateRC_d() { console.log(this._moduleName + ' installed'); process.exit(); });
this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('systemctl enable ' + options.name + '.service\n');
this._update.stdin.write('exit\n');
this._update.waitExit();
break;
default: // unknown platform service type
break;
@ -416,41 +413,39 @@ function serviceManager()
{
case 'init':
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._svcname = name;
this._update.on('exit', function onUninstallExit() {
try {
require('fs').unlinkSync('/etc/init.d/' + this._svcname);
console.log(this._svcname + ' uninstalled');
}
catch (e) {
console.log(this._svcname + ' could not be uninstalled')
}
process.exit();
});
this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('service ' + name + ' stop\n');
this._update.stdin.write('update-rc.d -f ' + name + ' remove\n');
this._update.stdin.write('exit\n');
this._update.waitExit();
try
{
require('fs').unlinkSync('/etc/init.d/' + name);
console.log(name + ' uninstalled');
}
catch (e)
{
console.log(name + ' could not be uninstalled', e)
}
break;
case 'systemd':
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._svcname = name;
this._update.on('exit', function onUninstallExit() {
try {
require('fs').unlinkSync('/usr/local/mesh/' + this._svcname);
require('fs').unlinkSync('/lib/systemd/system/' + this._svcname + '.service');
console.log(this._svcname + ' uninstalled');
}
catch (e) {
console.log(this._svcname + ' could not be uninstalled')
}
process.exit();
});
this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('systemctl stop ' + name + '.service\n');
this._update.stdin.write('systemctl disable ' + name + '.service\n');
this._update.stdin.write('exit\n');
this._update.waitExit();
try
{
require('fs').unlinkSync('/usr/local/mesh/' + name);
require('fs').unlinkSync('/lib/systemd/system/' + name + '.service');
console.log(name + ' uninstalled');
}
catch (e)
{
console.log(name + ' could not be uninstalled', e)
}
break;
default: // unknown platform service type
break;

View File

@ -1,5 +1,5 @@
/*
Copyright 2018-2019 Intel Corporation
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -77,7 +77,8 @@ function SMBiosTables()
var SMData;
var structcount = 0;
while (SMData && i < SMData.length) {
while (SMData && i < SMData.length)
{
var SMtype = SMData[i];
var SMlength = SMData[i + 1];
@ -88,12 +89,20 @@ function SMBiosTables()
ret[SMtype].peek()._strings = [];
while (SMData[i] != 0) {
while (SMData[i] != 0 && i <= SMData.length)
{
var strstart = i;
// Start of String, find end of string
while (SMData[i++] != 0);
ret[SMtype].peek()._strings.push(SMData.slice(strstart, i).toString().trim());
while (SMData[i++] != 0 && i <= SMData.length);
try
{
ret[SMtype].peek()._strings.push(SMData.slice(strstart, i).toString().trim());
}
catch (ee)
{
console.log('oops');
}
}
i += (ret[SMtype].peek()._strings.length == 0) ? 2 : 1;
++structcount;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*
Copyright 2018-2019 Intel Corporation
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -46,9 +46,6 @@ function parseServiceStatus(token)
case 0x00000001:
j.state = 'STOPPED';
break;
default:
// Unknown service status.
break;
}
var controlsAccepted = token.Deref((2 * 4), 4).toBuffer().readUInt32LE();
j.controlsAccepted = [];
@ -295,13 +292,14 @@ function serviceManager()
require('fs').chmodSync('/etc/init.d/' + options.name, m);
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._moduleName = options.name;
this._update.on('exit', function onUpdateRC_d() { console.log(this._moduleName + ' installed'); process.exit(); });
this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('update-rc.d ' + options.name + ' defaults\n');
this._update.stdin.write('exit\n');
//update-rc.d meshagent defaults # creates symlinks for rc.d
//service meshagent start
this._update.waitExit();
break;
case 'systemd':
var serviceDescription = options.description ? options.description : 'MeshCentral Agent';
@ -313,13 +311,12 @@ function serviceManager()
require('fs').writeFileSync('/lib/systemd/system/' + options.name + '.service', '[Unit]\nDescription=' + serviceDescription + '\n[Service]\nExecStart=/usr/local/mesh/' + options.name + '\nStandardOutput=null\nRestart=always\nRestartSec=3\n[Install]\nWantedBy=multi-user.target\nAlias=' + options.name + '.service\n', { flags: 'w' });
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._moduleName = options.name;
this._update.on('exit', function onUpdateRC_d() { console.log(this._moduleName + ' installed'); process.exit(); });
this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('systemctl enable ' + options.name + '.service\n');
this._update.stdin.write('exit\n');
this._update.waitExit();
break;
default: // Unknown platform service type
default: // unknown platform service type
break;
}
}
@ -416,43 +413,41 @@ function serviceManager()
{
case 'init':
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._svcname = name;
this._update.on('exit', function onUninstallExit() {
try {
require('fs').unlinkSync('/etc/init.d/' + this._svcname);
console.log(this._svcname + ' uninstalled');
}
catch (e) {
console.log(this._svcname + ' could not be uninstalled')
}
process.exit();
});
this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('service ' + name + ' stop\n');
this._update.stdin.write('update-rc.d -f ' + name + ' remove\n');
this._update.stdin.write('exit\n');
this._update.waitExit();
try
{
require('fs').unlinkSync('/etc/init.d/' + name);
console.log(name + ' uninstalled');
}
catch (e)
{
console.log(name + ' could not be uninstalled', e)
}
break;
case 'systemd':
this._update = require('child_process').execFile('/bin/sh', ['sh'], { type: require('child_process').SpawnTypes.TERM });
this._update._svcname = name;
this._update.on('exit', function onUninstallExit() {
try {
require('fs').unlinkSync('/usr/local/mesh/' + this._svcname);
require('fs').unlinkSync('/lib/systemd/system/' + this._svcname + '.service');
console.log(this._svcname + ' uninstalled');
}
catch (e) {
console.log(this._svcname + ' could not be uninstalled')
}
process.exit();
});
this._update.stdout.on('data', function (chunk) { });
this._update.stdin.write('systemctl stop ' + name + '.service\n');
this._update.stdin.write('systemctl disable ' + name + '.service\n');
this._update.stdin.write('exit\n');
this._update.waitExit();
try
{
require('fs').unlinkSync('/usr/local/mesh/' + name);
require('fs').unlinkSync('/lib/systemd/system/' + name + '.service');
console.log(name + ' uninstalled');
}
catch (e)
{
console.log(name + ' could not be uninstalled', e)
}
break;
default: // Unknown platform service type
default: // unknown platform service type
break;
}
}

View File

@ -1,5 +1,5 @@
/*
Copyright 2018-2019 Intel Corporation
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -77,7 +77,8 @@ function SMBiosTables()
var SMData;
var structcount = 0;
while (SMData && i < SMData.length) {
while (SMData && i < SMData.length)
{
var SMtype = SMData[i];
var SMlength = SMData[i + 1];
@ -88,12 +89,20 @@ function SMBiosTables()
ret[SMtype].peek()._strings = [];
while (SMData[i] != 0) {
while (SMData[i] != 0 && i <= SMData.length)
{
var strstart = i;
// Start of String, find end of string
while (SMData[i++] != 0);
ret[SMtype].peek()._strings.push(SMData.slice(strstart, i).toString().trim());
while (SMData[i++] != 0 && i <= SMData.length);
try
{
ret[SMtype].peek()._strings.push(SMData.slice(strstart, i).toString().trim());
}
catch (ee)
{
console.log('oops');
}
}
i += (ret[SMtype].peek()._strings.length == 0) ? 2 : 1;
++structcount;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -187,7 +187,7 @@ function CreateMeshCentralServer(config, args) {
}
}
});
xprocess.stdout.on('data', function (data) { if (data[data.length - 1] == '\n') { data = data.substring(0, data.length - 1); } if (data.indexOf('Updating settings folder...') >= 0) { xprocess.xrestart = 1; } else if (data.indexOf('Updating server certificates...') >= 0) { xprocess.xrestart = 1; } else if (data.indexOf('Server Ctrl-C exit...') >= 0) { xprocess.xrestart = 2; } else if (data.indexOf('Starting self upgrade...') >= 0) { xprocess.xrestart = 3; } console.log(data); });
xprocess.stdout.on('data', function (data) { if (data[data.length - 1] == '\n') { data = data.substring(0, data.length - 1); } if (data.indexOf('Updating settings folder...') >= 0) { xprocess.xrestart = 1; } else if (data.indexOf('Updating server certificates...') >= 0) { xprocess.xrestart = 1; } else if (data.indexOf('Server Ctrl-C exit...') >= 0) { xprocess.xrestart = 2; } else if (data.indexOf('Starting self upgrade...') >= 0) { xprocess.xrestart = 3; } else if (data.indexOf('Server restart...') >= 0) { xprocess.xrestart = 1; } console.log(data); });
xprocess.stderr.on('data', function (data) {
if (data.startsWith('le.challenges[tls-sni-01].loopback')) { return; } // Ignore this error output from GreenLock
if (data[data.length - 1] == '\n') { data = data.substring(0, data.length - 1); }

View File

@ -404,6 +404,55 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
break;
}
case 'serverconsole':
{
// This is a server console message, only process this if full administrator
if (user.siteadmin != 0xFFFFFFFF) break;
var r = '';
var args = splitArgs(command.value);
if (args.length == 0) break;
const cmd = args[0].toLowerCase();
args = parseArgs(args);
switch (cmd) {
case 'help': {
r = 'Available commands: help, args, resetserver, showconfig, usersessions.';
break;
}
case 'args': {
r = cmd + ': ' + JSON.stringify(args);
break;
}
case 'usersessions': {
for (var i in obj.parent.wssessions) {
r += (i + ', ' + obj.parent.wssessions[i].length + ' session' + ((obj.parent.wssessions[i].length > 1) ? 'a' : '') + '.<br />');
for (var j in obj.parent.wssessions[i]) {
var addr = obj.parent.wssessions[i][j]._socket.remoteAddress;
if (addr.startsWith('::ffff:')) { addr = addr.substring(7); }
r += ' ' + addr + ' --> ' + obj.parent.wssessions[i][j].sessionId + '.<br />';
}
}
break;
}
case 'resetserver': {
console.log('Server restart...');
process.exit(0);
break;
}
case 'showconfig': {
r = JSON.stringify(obj.parent.parent.config, null, 4);
break;
}
default: { // This is an unknown command, return an error message
r = 'Unknown command \"' + cmd + '\", type \"help\" for list of avaialble commands.';
break;
}
}
if (r != '') { try { ws.send(JSON.stringify({ action: 'serverconsole', value: r, tag: command.tag })); } catch (ex) { } }
break;
}
case 'msg':
{
// Route this command to a target node
@ -893,7 +942,11 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
obj.db.Set(obj.common.escapeLinksFieldName(mesh));
// Notify mesh change
obj.parent.parent.DispatchEvent(['*', mesh._id, user._id, command.userid], obj, { etype: 'mesh', username: user.name, userid: deluser.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Removed user ' + deluser.name + ' from group ' + mesh.name, domain: domain.id });
if (deluser != null) {
obj.parent.parent.DispatchEvent(['*', mesh._id, user._id, command.userid], obj, { etype: 'mesh', username: user.name, userid: deluser.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Removed user ' + deluser.name + ' from group ' + mesh.name, domain: domain.id });
} else {
obj.parent.parent.DispatchEvent(['*', mesh._id, user._id, command.userid], obj, { etype: 'mesh', username: user.name, userid: (deluserid.split('/')[2]), meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Removed user ' + (deluserid.split('/')[2]) + ' from group ' + mesh.name, domain: domain.id });
}
}
}
break;
@ -1565,5 +1618,25 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
function EscapeHtml(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
//function EscapeHtmlBreaks(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;').replace(/\r/g, '<br />').replace(/\n/g, '').replace(/\t/g, '&nbsp;&nbsp;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
// Split a string taking into account the quoats. Used for command line parsing
function splitArgs(str) { var myArray = [], myRegexp = /[^\s"]+|"([^"]*)"/gi; do { var match = myRegexp.exec(str); if (match != null) { myArray.push(match[1] ? match[1] : match[0]); } } while (match != null); return myArray; }
function toNumberIfNumber(x) { if ((typeof x == 'string') && (+parseInt(x) === x)) { x = parseInt(x); } return x; }
// Parse arguments string array into an object
function parseArgs(argv) {
var results = { '_': [] }, current = null;
for (var i = 1, len = argv.length; i < len; i++) {
var x = argv[i];
if (x.length > 2 && x[0] == '-' && x[1] == '-') {
if (current != null) { results[current] = true; }
current = x.substring(2);
} else {
if (current != null) { results[current] = toNumberIfNumber(x); current = null; } else { results['_'].push(toNumberIfNumber(x)); }
}
}
if (current != null) { results[current] = true; }
return results;
}
return obj;
};

View File

@ -51,9 +51,11 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
obj.onDebugMessage = null;
obj.onTouchEnabledChanged = null;
obj.onDisplayinfo = null;
obj.accumulator = null;
obj.Start = function () {
obj.State = 0;
obj.accumulator = null;
}
obj.Stop = function () {
@ -178,6 +180,11 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
}
obj.ProcessDataEx = function (str) {
if (obj.accumulator != null) {
str = obj.accumulator + str;
console.log('KVM using accumulated data, total size is now ' + str.length + ' bytes.');
obj.accumulator = null;
}
if (obj.debugmode > 1) { console.log("KRecv(" + str.length + "): " + rstr2hex(str.substring(0, Math.min(str.length, 40)))); }
if (str.length < 4) return;
var cmdmsg = null, X = 0, Y = 0, command = ReadShort(str, 0), cmdsize = ReadShort(str, 2), jumboAdd = 0;
@ -186,14 +193,23 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
if (str.length < 12) return;
command = ReadShort(str, 8)
cmdsize = ReadInt(str, 4);
console.log('JUMBO cmd=' + command + ', cmdsize=' + cmdsize + ', data received=' + str.length);
if ((cmdsize + 8) > str.length) {
console.log('KVM accumulator set to ' + str.length + ' bytes, need ' + cmdsize + ' bytes.');
obj.accumulator = str;
return;
}
str = str.substring(8);
jumboAdd = 8;
//console.log('JUMBO', command, cmdsize, str.length);
}
if ((cmdsize != str.length) && (obj.debugmode > 0)) { console.log(cmdsize, str.length, cmdsize == str.length); }
if ((command >= 18) && (command != 65)) { console.error("Invalid KVM command " + command + " of size " + cmdsize); console.log("Invalid KVM data", str.length, str, rstr2hex(str)); return; }
if (cmdsize > str.length) { console.error("KVM invalid command size", cmdsize, str.length); return; }
//meshOnDebug("KVM Command: " + command + " Len:" + cmdsize);
if (cmdsize > str.length) {
console.log('KVM accumulator set to ' + str.length + ' bytes, need ' + cmdsize + ' bytes.');
obj.accumulator = str;
return;
}
//console.log("KVM Command: " + command + " Len:" + cmdsize);
if (command == 3 || command == 4 || command == 7) {
cmdmsg = str.substring(4, cmdsize);

View File

@ -99,7 +99,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au
obj.webchannel = obj.webrtc.createDataChannel("DataChannel", {}); // { ordered: false, maxRetransmits: 2 }
obj.webchannel.onmessage = function (event) { obj.xxOnMessage({ data: event.data }); };
obj.webchannel.onopen = function () { obj.webRtcActive = true; performWebRtcSwitch(); };
obj.webchannel.onclose = function (event) { /*console.log('WebRTC close');*/ if (obj.webRtcActive) { obj.Stop(); } }
obj.webchannel.onclose = function (event) { if (obj.webRtcActive) { obj.Stop(); } }
obj.webrtc.onicecandidate = function (e) {
if (e.candidate == null) {
try { obj.socket.send(JSON.stringify(obj.webrtcoffer)); } catch (ex) { } // End of candidates, send the offer

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -136,6 +136,15 @@
</tr>
</table>
</div>
<div id=ServerSubMenuSpan style=display:none>
<table id=ServerSubMenu style=width:100%;height:22px cellpadding=0 cellspacing=0 class=style1>
<tr>
<td id=ServerGeneral style=width:100px;height:24px;cursor:pointer class=style3x onclick=go(6)>General</td>
<td id=ServerConsole style=width:100px;height:24px;cursor:pointer class=style3x onclick=go(115)>Console</td>
<td class=style3 style=height:24px>&nbsp;</td>
</tr>
</table>
</div>
<div id=UserDummyMenuSpan>
<table id=UserDummyMenu style=width:100%;height:22px cellpadding=0 cellspacing=0 class=style1>
<tr><td class=style3 style="text-align:right;height:24px">&nbsp;</td></tr>
@ -604,7 +613,7 @@
<div id=p15 style=display:none>
<div id="p15title">
<div id="p15BackButton" style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div>
<h1>Console - <span id=p15deviceName></span></h1>
<h1><span id=p15deviceName></span></h1>
</div>
<table cellpadding=0 cellspacing=0 style="width:100%;padding:0px;padding:0px;margin-top:0px">
<tr>
@ -1334,6 +1343,10 @@
}
break;
}
case 'serverconsole': {
p15consoleReceive('serverconsole', message.value);
break;
}
case 'events': {
if ((message.nodeid != null) && (message.nodeid == currentNode._id)) {
currentDeviceEvents = message.events;
@ -1676,7 +1689,7 @@
function ondockeypress(e) {
if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) return desktop.m.handleKeys(e);
if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) return terminal.m.TermHandleKeys(e);
if (!xxdialogMode && xxcurrentView == 15) return agentConsoleHandleKeys(e);
if (!xxdialogMode && ((xxcurrentView == 15) || (xxcurrentView == 115))) return agentConsoleHandleKeys(e);
if (!xxdialogMode && xxcurrentView == 4) {
if (e.ctrlKey == true || e.altKey == true || e.metaKey == true) return;
var processed = 0;
@ -1725,7 +1738,7 @@
if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) { return desktop.m.handleKeyDown(e); }
if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) { return terminal.m.TermHandleKeyDown(e); }
if (!xxdialogMode && xxcurrentView == 13 && e.keyCode == 116 && p13filetree != null) { haltEvent(e); return false; } // F5 Refresh on files
if (!xxdialogMode && xxcurrentView == 15) { return agentConsoleHandleKeys(e); }
if (!xxdialogMode && ((xxcurrentView == 15) || (xxcurrentView == 115))) { return agentConsoleHandleKeys(e); }
if (!xxdialogMode && xxcurrentView == 4) {
if (e.keyCode === 8 && userSearchFocus == 0) { var x = Q('UserSearchInput').value; Q('UserSearchInput').value = (x.substring(0, x.length - 1)); processed = 1; }
if (e.keyCode === 27) { Q('UserSearchInput').value = ''; processed = 1; }
@ -3209,7 +3222,7 @@
QH('p12deviceName', nname);
QH('p13deviceName', nname);
QH('p14deviceName', nname);
QH('p15deviceName', nname);
QH('p15deviceName', 'Console - ' + nname);
QH('p16deviceName', nname);
// Node attributes
@ -5022,27 +5035,43 @@
}
var consoleNode;
var consoleServerText = '';
function setupConsole() {
// Setup the console
var samenode = (consoleNode == currentNode);
consoleNode = currentNode;
if (xxcurrentView == 115) {
// Setup server console
var samenode = (consoleNode == 'server');
consoleNode = 'server';
QH('p15deviceName', 'My Server Console');
QH('p15statetext', '');
QH('p15coreName', '');
var mesh = meshes[consoleNode.meshid];
var meshrights = mesh.links['user/' + domain + '/' + userinfo.name.toLowerCase()].rights;
if ((meshrights & 16) != 0) {
if (consoleNode.consoleText == null) { consoleNode.consoleText = ''; }
if (samenode == false) {
QH('p15agentConsoleText', consoleNode.consoleText);
QH('p15agentConsoleText', consoleServerText);
Q('p15agentConsoleText').scrollTop = Q('p15agentConsoleText').scrollHeight;
}
var online = ((consoleNode.conn & 1) != 0)?true:false;
QH('p15statetext', online?"Agent is online":"Agent is offline");
QE('p15consoleText', online);
QE('p15uploadCore', online);
} else {
QH('p15statetext', 'Access Denied');
QE('p15consoleText', false);
QE('p15uploadCore', false);
// Setup the console
var samenode = (consoleNode == currentNode);
consoleNode = currentNode;
var mesh = meshes[consoleNode.meshid];
var meshrights = mesh.links['user/' + domain + '/' + userinfo.name.toLowerCase()].rights;
if ((meshrights & 16) != 0) {
if (consoleNode.consoleText == null) { consoleNode.consoleText = ''; }
if (samenode == false) {
QH('p15agentConsoleText', consoleNode.consoleText);
Q('p15agentConsoleText').scrollTop = Q('p15agentConsoleText').scrollHeight;
}
var online = ((consoleNode.conn & 1) != 0) ? true : false;
QH('p15statetext', online ? "Agent is online" : "Agent is offline");
QE('p15consoleText', online);
QE('p15uploadCore', online);
} else {
QH('p15statetext', 'Access Denied');
QE('p15consoleText', false);
QE('p15uploadCore', false);
}
}
}
@ -5050,7 +5079,11 @@
function p15consoleClear() {
QH('p15agentConsoleText', '');
Q('id_p15consoleClear').blur();
consoleNode.consoleText = '';
if (xxcurrentView == 115) {
consoleServerText = '';
} else {
consoleNode.consoleText = '';
}
}
// Send a command to the agent
@ -5059,12 +5092,18 @@
if (e && e.keyCode != 13) return;
var v = Q('p15consoleText').value, t = '<div style=color:green>&gt; ' + EscapeHtml(Q('p15consoleText').value) + '<br/></div>';
Q('p15agentConsoleText').innerHTML += t;
consoleNode.consoleText += t;
Q('p15agentConsoleText').scrollTop = Q('p15agentConsoleText').scrollHeight;
Q('p15consoleText').value = '';
// Send the command to the mesh agent
meshserver.send({ action: 'msg', type:'console', nodeid: consoleNode._id, value: v });
if (xxcurrentView == 115) {
// Send the command to the server - TODO: In the future, we may support multiple servers.
consoleServerText += t;
meshserver.send({ action: 'serverconsole', value: v });
} else {
// Send the command to the mesh agent
consoleNode.consoleText += t;
meshserver.send({ action: 'msg', type: 'console', nodeid: consoleNode._id, value: v });
}
// Add command to history list
if (v.length > 0) {
@ -5079,10 +5118,20 @@
// Handle Mesh Agent console data
function p15consoleReceive(node, data) {
data = '<div>' + data + '</div>'
if (node.consoleText == null) { node.consoleText = data; } else { node.consoleText += data; }
if (consoleNode == node) {
Q('p15agentConsoleText').innerHTML += data;
Q('p15agentConsoleText').scrollTop = Q('p15agentConsoleText').scrollHeight;
if (node === 'serverconsole') {
// Server console data
consoleServerText += data;
if (consoleNode == 'server') {
Q('p15agentConsoleText').innerHTML += data;
Q('p15agentConsoleText').scrollTop = Q('p15agentConsoleText').scrollHeight;
}
} else {
// Agent console data
if (node.consoleText == null) { node.consoleText = data; } else { node.consoleText += data; }
if (consoleNode == node) {
Q('p15agentConsoleText').innerHTML += data;
Q('p15agentConsoleText').scrollTop = Q('p15agentConsoleText').scrollHeight;
}
}
}
@ -6627,8 +6676,8 @@
if (x == 5) { Q('LeftMenuMyFiles').classList.add('lbbuttonsel', 'lbbuttonsel2'); }
// My Server
QS('MainMenuMyServer').backgroundColor = ((x == 6) ? "#003366" : "#808080");
if (x == 6) { Q('LeftMenuMyServer').classList.add('lbbuttonsel', 'lbbuttonsel2'); }
QS('MainMenuMyServer').backgroundColor = (((x == 6) || (x == 115)) ? "#003366" : "#808080");
if (((x == 6) || (x == 115))) { Q('LeftMenuMyServer').classList.add('lbbuttonsel', 'lbbuttonsel2'); }
// column_l max-height
if (webPageFullScreen) {
@ -6644,16 +6693,23 @@
}
QV('MainSubMenuSpan', x >= 10 && x < 20);
QV('UserDummyMenuSpan', (x < 10) && webPageFullScreen);
QV('UserDummyMenuSpan', (x < 10) && (x != 6) && webPageFullScreen);
QV('MeshSubMenuSpan', x >= 20 && x < 30);
QV('UserSubMenuSpan', x >= 30 && x < 40);
var panels = { 10: 'MainDev', 11: 'MainDevDesktop', 12: 'MainDevTerminal', 13: 'MainDevFiles', 14: 'MainDevAmt', 15: 'MainDevConsole', 20: 'MeshGeneral', 30: 'UserGeneral', 31: 'UserEvents' };
QV('ServerSubMenuSpan', x == 6 || x == 115);
var panels = { 10: 'MainDev', 11: 'MainDevDesktop', 12: 'MainDevTerminal', 13: 'MainDevFiles', 14: 'MainDevAmt', 15: 'MainDevConsole', 20: 'MeshGeneral', 30: 'UserGeneral', 31: 'UserEvents', 6: 'ServerGeneral', 115: 'ServerConsole' };
for (var i in panels) {
Q(panels[i]).classList.remove('style3x');
Q(panels[i]).classList.remove('style3sel');
Q(panels[i]).classList.add((x == i) ? 'style3sel' : 'style3x');
}
// Panel 115 is weird, it's panel 15 for device console but used as a server console.
if (x == 115) { QV('p15', true); }
QV('p15uploadCore', x != 115);
QV('p15BackButton', x != 115);
if ((x == 15) || (x == 115)) { setupConsole(); }
if (x == 1) masterUpdate(4);
// Update the web page title