changeset 28:2ad2b6491aa9

rlgwebd.js: become a real daemon. The RLG-Web server now forks off, writes to a logfile, and reads from a control socket. Unfortunately it can't handle the problem of another rlgwebd process already running. Maybe a lockfile would help.
author John "Elwin" Edwards <elwin@sdf.org>
date Mon, 04 Jun 2012 20:45:27 -0700
parents 83f9a799a374
children cf9d294bc52f
files rlgwebd.js
diffstat 1 files changed, 40 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/rlgwebd.js	Mon Jun 04 14:21:41 2012 -0700
+++ b/rlgwebd.js	Mon Jun 04 20:45:27 2012 -0700
@@ -3,12 +3,16 @@
 // If you can't quite trust node to find it on its own
 var localModules = '/usr/local/lib/node_modules/';
 var http = require('http');
+var net = require('net');
 var url = require('url');
 var path = require('path');
 var fs = require('fs');
 var child_process = require('child_process');
 var daemon = require(path.join(localModules, "daemon"));
 
+// These first two files are NOT in the chroot.
+var ctlsocket = "/var/local/rlgwebd/ctl";
+var logfile = "/var/local/rlgwebd/log";
 var chrootDir = "/var/dgl/";
 var dropToUID = 501;
 var dropToGID = 501;
@@ -651,7 +655,7 @@
 function shutdown () {
   httpServer.close();
   httpServer.removeAllListeners('request');
-  process.stdin.removeAllListeners('data');
+  ctlServer.close();
   tslog("Shutting down...");
   process.exit();
 }
@@ -684,32 +688,39 @@
   tslog("Not running as root, cannot chroot.");
   process.exit(1);
 }
-try {
-  process.chdir(chrootDir); 
-}
-catch (err) {
-  tslog("Cannot enter %s: %s", chrootDir, err);
-  process.exit(1);
-}
-try {
-  daemon.chroot(chrootDir);
-}
-catch (err) {
-  tslog("chroot to %s failed: %s", chrootDir, err);
-  process.exit(1);
-}
-try {
-  // drop gid first, that requires UID=0
-  process.setgid(dropToGID);
-  process.setuid(dropToUID);
-}
-catch (err) {
-  tslog("Could not drop permissions: %s", err);
-  process.exit(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/'); 
+/* Open the control socket before chrooting where it can't be found */
+var ctlServer = net.createServer(function (sock) {
+  sock.on('data', conHandler);
+});
+ctlServer.listen(ctlsocket, function () {
+  /* fork off and die */
+  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);
+  }
+  catch (err) {
+    tslog("chroot to %s failed: %s", chrootDir, err);
+    process.exit(1);
+  }
+  try {
+    // drop gid first, that requires UID=0
+    process.setgid(dropToGID);
+    process.setuid(dropToUID);
+  }
+  catch (err) {
+    tslog("Could not drop permissions: %s", err);
+    process.exit(1);
+  }
+  var httpServer = http.createServer(webHandler);
+  httpServer.listen(8080, "127.0.0.1");
+  tslog('rlgwebd running at http://127.0.0.1:8080/'); 
+});
+