From 670cb97e79c2b1fe5b89cb15b38491137c50e5d2 Mon Sep 17 00:00:00 2001 From: Xaekai Date: Wed, 20 Jul 2016 03:01:34 -0700 Subject: [PATCH] Complete rewrite of the service socket client Add one more command to the service commandline --- index.js | 12 ++++++ servcmd.sh.js | 114 ++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 99 insertions(+), 27 deletions(-) diff --git a/index.js b/index.js index f82a3176..ed8ecac9 100644 --- a/index.js +++ b/index.js @@ -97,6 +97,18 @@ function handleLine(line) { } }) } + } else if (line.indexOf("/unloadchan") === 0) { + var args = line.split(/\s+/); args.shift(); + if(args.length){ + var name = args.shift(); + var chan = sv.getChannel(name); + var users = Array.prototype.slice.call(chan.users); + chan.emit("empty"); + users.forEach(function (u) { + u.kick("Channel shutting down"); + }); + Logger.eventlog.log("[acp] " + "SYSTEM" + " forced unload of " + name); + } } } diff --git a/servcmd.sh.js b/servcmd.sh.js index c90d4228..1786171e 100755 --- a/servcmd.sh.js +++ b/servcmd.sh.js @@ -3,6 +3,23 @@ ** CyTube Service Socket Commandline */ +const readline = require('readline'); +const spawn = require('child_process').spawn; +const util = require('util'); +const net = require('net'); +const fs = require('fs'); + +const COMPLETIONS = [ + "/delete_old_tables", + "/gc", + "/globalban", + "/reload", + "/reload-partitions", + "/switch", + "/unglobalban", + "/unloadchan" +]; + var Config = require("./lib/config"); Config.load("config.yaml"); @@ -12,13 +29,56 @@ if(!Config.get("service-socket.enabled")){ } const SOCKETFILE = Config.get("service-socket.socket"); -var net = require('net'); -var client = net.createConnection(SOCKETFILE) - .on('connect', () => { - console.log("Connected."); - }) - .on('data', (msg) => { +// Wipe the TTY +process.stdout.write('\x1Bc'); + +var commandline, eventlog, syslog; +var client = net.createConnection(SOCKETFILE).on('connect', () => { + commandline = readline.createInterface({ + input: process.stdin, + output: process.stdout, + completer: tabcomplete + }); + commandline.setPrompt("> ", 2); + commandline.on("line", function(line) { + if(line === 'exit'){ return cleanup(); } + if(line === 'quit'){ return cleanup(); } + if(line.match(/^\/globalban/) && line.split(/\s+/).length === 2){ + console.log('You must provide a reason') + return commandline.prompt(); + } + client.write(line); + commandline.prompt(); + }); + commandline.on('close', function() { + return cleanup(); + }); + commandline.on("SIGINT", function() { + commandline.clearLine(); + commandline.question("Terminate connection? ", function(answer) { + return answer.match(/^y(es)?$/i) ? cleanup() : commandline.output.write("> "); + }); + }); + commandline.prompt(); + + console.log = function() { cmdouthndlr("log", arguments); } + console.warn = function() { cmdouthndlr("warn", arguments); } + console.error = function() { cmdouthndlr("error", arguments); } + // console.info is reserved in this script for the exit message + // this prevents an extraneous final prompt from readline on terminate + + eventlog = spawn('tail', ['-f', 'events.log']); + eventlog.stdout.on('data', function (data) { + console.log(data.toString().replace(/^(.+)$/mg, 'events: $1')); + }); + + syslog = spawn('tail', ['-f', 'sys.log']); + syslog.stdout.on('data', function (data) { + console.log(data.toString().replace(/^(.+)$/mg, 'sys: $1')); + }); + + }).on('data', (msg) => { msg = msg.toString(); if(msg === '__disconnect'){ @@ -27,30 +87,30 @@ var client = net.createConnection(SOCKETFILE) } // Generic message handler - console.info('Server:', data) - }) - .on('error', (data) => { - console.error('Unable to connect to Service Socket.'); - process.exit(1); - }) - ; + console.log('server: ', data) -var inputbuffer = ""; -process.stdin.on("data", (data) => { - inputbuffer += data; - if (inputbuffer.indexOf("\n") !== -1) { - var line = inputbuffer.substring(0, inputbuffer.indexOf("\n")); - inputbuffer = inputbuffer.substring(inputbuffer.indexOf("\n") + 1); - // Let the client escape - if(line === 'exit'){ return cleanup(); } - if(line === 'quit'){ return cleanup(); } - client.write(line); - } -}); + }).on('error', (data) => { + console.error('Unable to connect to Service Socket.', data); + process.exit(1); + }); + +function cmdouthndlr(type, args) { + var t = Math.ceil((commandline.line.length + 3) / process.stdout.columns); + var text = util.format.apply(console, args); + commandline.output.write("\n\x1B[" + t + "A\x1B[0J"); + commandline.output.write(text + "\n"); + commandline.output.write(Array(t).join("\n\x1B[E")); + commandline._refreshLine(); +} function cleanup(){ - console.log('\n',"Terminating.",'\n'); + console.info('\n',"Terminating.",'\n'); + eventlog.stdin.end(); + syslog.stdin.end(); client.end(); process.exit(0); } -process.on('SIGINT', cleanup); + +function tabcomplete(line) { + return [COMPLETIONS.filter((cv)=>{ return cv.indexOf(line) == 0; }), line]; +}