# HG changeset patch
# User John "Elwin" Edwards <elwin@sdf.org>
# Date 1338844901 25200
# Node ID 83f9a799a3745182c8b257d0ec4d8c2d8843f242
# Parent  9b58f8d3ea700c08d00b4b2278c0b669954dc6e4
rlgwebd.js: read commands from the console

The RLG-Web server can now be controlled with commands sent to stdin.
Currently, the only one implemented is "quit".  Some improvements to
the shutdown process were also made.

diff -r 9b58f8d3ea70 -r 83f9a799a374 rlgterm.js
--- a/rlgterm.js	Mon Jun 04 10:19:36 2012 -0700
+++ b/rlgterm.js	Mon Jun 04 14:21:41 2012 -0700
@@ -132,7 +132,7 @@
   if (!msgDict.t)
     return null;
   else if (msgDict.t == "E") {
-    if (msgDict.c == 1) {
+    if (msgDict.c == 1 || msgDict.c == 6) {
       logout();
     }
     debug(1, "Server error: " + msgDict.s);
diff -r 9b58f8d3ea70 -r 83f9a799a374 rlgwebd.js
--- a/rlgwebd.js	Mon Jun 04 10:19:36 2012 -0700
+++ b/rlgwebd.js	Mon Jun 04 14:21:41 2012 -0700
@@ -15,6 +15,7 @@
 var serveStaticRoot = "/var/www/"; // inside the chroot
 var passwdfile = "/dgldir/dgl-login";
 var sessions = {};
+var allowlogin = true;
 
 var games = {
   "rogue3": {
@@ -198,8 +199,9 @@
       ss.remove();
   };
   this.remove = function () {
-    delete sessions[ss.sessid];
-    tslog("Session %s removed.", this.sessid);
+    var id = ss.sessid;
+    delete sessions[id];
+    tslog("Session %s removed.", id);
   };
 }
 
@@ -305,6 +307,10 @@
 }
 
 function login(req, res, formdata) {
+  if (!allowlogin) {
+    sendError(res, 6, null);
+    return;
+  }
   if (!("game" in formdata)) {
     sendError(res, 2, "No game specified.");
     return;
@@ -521,8 +527,14 @@
     if (result == null) {
       if (term.alive)
         reply.t = "n";
-      else
-        reply.t = "q";
+      else {
+        if (allowlogin)
+          reply.t = "q";
+        else {
+          sendError(res, 6, null);
+          return;
+        }
+      }
     }
     else {
       reply.t = "d";
@@ -539,7 +551,8 @@
 }
 
 var errorcodes = [ "Generic Error", "Not logged in", "Invalid data", 
-        "Login failed", "Already playing", "Game launch failed" ];
+        "Login failed", "Already playing", "Game launch failed",
+        "Server shutting down" ];
 
 function sendError(res, ecode, msg) {
   res.writeHead(200, { "Content-Type": "text/plain" });
@@ -554,7 +567,7 @@
   res.end();
 }
 
-function handler(req, res) {
+function webHandler(req, res) {
   /* default headers for the response */
   var resheaders = {'Content-Type': 'text/html'};
   /* The request body will be added to this as it arrives. */
@@ -635,6 +648,26 @@
 
 }
 
+function shutdown () {
+  httpServer.close();
+  httpServer.removeAllListeners('request');
+  process.stdin.removeAllListeners('data');
+  tslog("Shutting down...");
+  process.exit();
+}
+
+function conHandler(chunk) {
+  var msg = chunk.toString().split('\n')[0];
+  if (msg == "quit") {
+    allowlogin = false;
+    tslog("Disconnecting...");
+    for (var sessid in sessions) {
+      sessions[sessid].close();
+    }
+    setTimeout(shutdown, 10000);
+  }
+}
+
 process.on("exit", function () {
   for (var sessid in sessions) {
     if (sessions[sessid].alive)
@@ -675,5 +708,8 @@
   process.exit(1);
 }
 
-http.createServer(handler).listen(8080, "127.0.0.1");
+process.stdin.on('data', conHandler);
+process.stdin.resume();
+var httpServer = http.createServer(webHandler);
+httpServer.listen(8080, "127.0.0.1");
 tslog('rlgwebd running at http://127.0.0.1:8080/');