From fabaea68499d105d2a264307731f71f706b5d5ec Mon Sep 17 00:00:00 2001 From: "John \"Elwin\" Edwards" Date: Sat, 20 Jul 2013 12:23:53 -0700 Subject: [PATCH] Replace the daemon module with posix. The daemon module doesn't include chroot() anymore, so a replacement is needed. Detaching a daemon keeps getting harder to do in Node, so some setup has been moved into a shell script. --- rlgwebd | 22 ++++++++++++++++++++++ rlgwebd.js | 32 ++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 14 deletions(-) create mode 100755 rlgwebd diff --git a/rlgwebd b/rlgwebd new file mode 100755 index 0000000..9ab806e --- /dev/null +++ b/rlgwebd @@ -0,0 +1,22 @@ +#!/bin/sh + +LOGFILE=/var/local/rlgwebd/log +CTLSOCKET=/var/local/rlgwebd/ctl +RLGWEBDJS=./rlgwebd.js + +if [ $UID != 0 ] +then + echo "$0 needs to run as root." >&2 + exit 1 +fi + +if [ $# -gt 0 ] && [ $1 = stop ] +then + socat "EXEC:echo quit" "$CTLSOCKET" +else + # Start + setsid node "$RLGWEBDJS" >$LOGFILE & +fi + +exit + diff --git a/rlgwebd.js b/rlgwebd.js index c5aa04d..42a8151 100755 --- a/rlgwebd.js +++ b/rlgwebd.js @@ -9,14 +9,13 @@ var path = require('path'); var fs = require('fs'); var events = require('events'); var child_process = require('child_process'); -var daemon = require(path.join(localModules, "daemon")); +var posix = require(path.join(localModules, "posix")); var pty = require(path.join(localModules, "pty.js")); var WebSocketServer = require(path.join(localModules, "websocket")).server; /* Configuration variables */ -// These first two files are NOT in the chroot. +// The first file is NOT in the chroot. var ctlsocket = "/var/local/rlgwebd/ctl"; -var logfile = "/var/local/rlgwebd/log"; var httpPort = 8080; var chrootDir = "/var/dgl/"; var dropToUID = 501; @@ -911,7 +910,18 @@ function stopgame(res, formdata) { return; } var pid = parseInt(fdata.split('\n')[0], 10); - process.kill(pid, 'SIGHUP'); + try { + process.kill(pid, 'SIGHUP'); + } + catch (err) { + /* If the PID is invalid, the lockfile is stale. */ + if (err.code == "ESRCH") { + var nodere = RegExp("^" + pname + ":node:"); + if (fname.match(nodere)) { + fs.unlink(fullfile); + } + } + } /* The response doesn't mean that the game is gone. The only way * to make sure a dgamelaunch-supervised game is over would be to * poll fname until it disappears. */ @@ -1396,17 +1406,11 @@ var ctlServer = net.createServer(function (sock) { sock.on('data', conHandler); }); ctlServer.listen(ctlsocket, function () { - /* fork off and die */ + /* rlgwebd.js now assumes that it has been started by the rlgwebd shell + * script, or some other method that detaches it and sets up stdio. */ + /* chroot and drop permissions. posix.chroot() does chdir() itself. */ try { - daemon.start(logfile); - } - catch (err) { - tslog("Daemonization failed: %s", err); - process.exit(1); - } - /* chroot and drop permissions. daemon.chroot() does chdir() itself. */ - try { - daemon.chroot(chrootDir); + posix.chroot(chrootDir); } catch (err) { tslog("chroot to %s failed: %s", chrootDir, err);