From fd6bc4d2a901aabe0bb6067fbcc14a4fe3faa8b9 Mon Sep 17 00:00:00 2001 From: Mike Pennisi Date: Tue, 16 Aug 2016 15:52:25 -0400 Subject: [PATCH] Remove daemon support The "daemon" feature contains a security vulnerability [1]. This feature relies on a beta release (e.g. version 0.5.1) of a Node.js module on npm--one that was superseded by a stable (e.g. version 1.0) release published three years ago [2]. Due to a build-time dependency on the long-since deprecated `node-waf` tool, the module at that version can only be built for Node.js versions 0.8 and below. Given this, actual usage of this feature is likely very limited. Remove it completely so the integrity of this module's core functionality can be verified. [1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=809252 [2] The source expects the module to define a property named `deamonize`, which was removed for the 1.0 release: https://github.com/indexzero/daemon.node/tree/v1.0.0 --- README.md | 50 ------------------ cli.js | 112 ++--------------------------------------- examples/static.coffee | 27 ---------- examples/static.js | 25 --------- package.json | 2 +- 5 files changed, 4 insertions(+), 212 deletions(-) delete mode 100755 examples/static.coffee delete mode 100755 examples/static.js diff --git a/README.md b/README.md index 79437e0..501779e 100644 --- a/README.md +++ b/README.md @@ -39,50 +39,6 @@ cli.withStdinLines(function(lines, newline) { }); ``` -### static.js - -Let's create a static file server with daemon support to see the opts parser + plugins in use - note: this requires `npm install creationix daemon` - -```javascript -var cli = require('cli').enable('daemon', 'status'); //Enable 2 plugins - -cli.parse({ - log: ['l', 'Enable logging'], - port: ['p', 'Listen on this port', 'number', 8080], - serve: [false, 'Serve static files from PATH', 'path', './public'] -}); - -cli.main(function(args, options) { - var server, middleware = []; - - if (options.log) { - this.debug('Enabling logging'); - middleware.push(require('creationix/log')()); - } - - this.debug('Serving files from ' + options.serve); - middleware.push(require('creationix/static')('/', options.serve, 'index.html')); - - server = this.createServer(middleware).listen(options.port); - - this.ok('Listening on port ' + options.port); -}); -``` - -To output usage information - -```bash -$ ./static.js --help -``` - -To create a daemon that serves files from */tmp*, run - -```bash -$ ./static.js -ld --serve=/tmp -``` - -For more examples, see [./examples](https://github.com/chriso/cli/tree/master/examples) - ## Command Line Arguments Parser cli takes an object as a map for the arguments you wish to parse. @@ -209,12 +165,6 @@ cli.ok(msg); Enables glob matching of arguments -**daemon** - *requires* `npm install daemon` - -Adds `-d,--daemon ARG` for daemonizing the process and controlling the resulting daemon - -`ARG` can be either start (default), stop, restart, pid (outputs the daemon's pid if it's running), or log (output the daemon's stdout+stderr) - **timeout** Adds `-t,--timeout N` to exit the process after N seconds with an error diff --git a/cli.js b/cli.js index 044aa03..aefaef5 100644 --- a/cli.js +++ b/cli.js @@ -28,7 +28,7 @@ var cli = exports, argv, curr_opt, curr_val, full_opt, is_long, short_tags = [], opt_list, parsed = {}, usage, argv_parsed, command_list, commands, - daemon, daemon_arg, show_debug; + show_debug; cli.app = null; cli.version = null; @@ -85,7 +85,6 @@ if (process.env.NODE_DISABLE_COLORS || process.env.TERM === 'dumb') { var enable = { help: true, //Adds -h, --help version: false, //Adds -v,--version => gets version by parsing a nearby package.json - daemon: false, //Adds -d,--daemon [ARG] => (see cli.daemon() below) status: false, //Adds -k,--no-color & --debug => display plain status messages /display debug messages timeout: false, //Adds -t,--timeout N => timeout the process after N seconds catchall: false, //Adds -c,--catch => catch and output uncaughtExceptions @@ -94,16 +93,6 @@ var enable = { cli.enable = function (/*plugins*/) { Array.prototype.slice.call(arguments).forEach(function (plugin) { switch (plugin) { - case 'daemon': - try { - daemon = require('daemon'); - if (typeof daemon.daemonize !== 'function') { - throw 'Invalid module'; - } - } catch (e) { - cli.fatal('daemon.node not installed. Please run `npm install daemon`'); - } - break; case 'catchall': process.on('uncaughtException', function (err) { cli.error('Uncaught exception: ' + (err.msg || err)); @@ -347,9 +336,6 @@ cli.parse = function (opts, command_def) { console.error(cli.app + ' v' + cli.version); cli.exit(); break; - } else if (enable.daemon && (o === 'd' || o === 'daemon')) { - daemon_arg = cli.getArrayValue(['start','stop','restart','pid','log'], is_long ? null : 'start'); - continue; } else if (enable.catchall && (o === 'c' || o === 'catch')) { continue; } else if (enable.status && (o === 'k' || o === 'no-color')) { @@ -667,9 +653,6 @@ cli.getUsage = function (code) { if (enable.catchall && seen_opts.indexOf('c') === -1 && seen_opts.indexOf('catch') === -1) { console.error(pad(' -c, --catch', switch_pad) + 'Catch unanticipated errors'); } - if (enable.daemon && seen_opts.indexOf('d') === -1 && seen_opts.indexOf('daemon') === -1) { - console.error(pad(' -d, --daemon [ARG]', switch_pad) + 'Daemonize the process. Control the daemon using [start, stop, restart, log, pid]'); - } if (enable.version && seen_opts.indexOf('v') === -1 && seen_opts.indexOf('version') === -1) { console.error(pad(' -v, --version', switch_pad) + 'Display the current version'); } @@ -965,102 +948,13 @@ cli.toType = function(obj) { } /** - * A method for creating and controlling a daemon. - * - * `arg` can be: - * start = daemonizes the process - * stop = stops the daemon if it is running - * restart = alias for stop -> start - * pid = outputs the daemon's PID if it is running - * log = outputs the daemon's log file (stdout + stderr) - * - * @param {String} arg (Optional - default is 'start') - * @param {Function} callback - * @api public - */ -cli.daemon = function (arg, callback) { - if (typeof daemon === 'undefined') { - cli.fatal('Daemon is not initialized'); - } - - if (typeof arg === 'function') { - callback = arg; - arg = 'start'; - } - - var lock_file = '/tmp/' + cli.app + '.pid', - log_file = '/tmp/' + cli.app + '.log'; - - var start = function () { - daemon.daemonize(log_file, lock_file, function (err) { - if (err) return cli.error('Error starting daemon: ' + err); - callback(); - }); - }; - - var stop = function () { - try { - cli.native.fs.readFileSync(lock_file); - } catch (e) { - return cli.error('Daemon is not running'); - } - daemon.kill(lock_file, function (err, pid) { - if (err && err.errno === 3) { - return cli.error('Daemon is not running'); - } else if (err) { - return cli.error('Error stopping daemon: ' + err.errno); - } - cli.ok('Successfully stopped daemon with pid: ' + pid); - }); - }; - - switch(arg) { - case 'stop': - stop(); - break; - case 'restart': - daemon.stop(lock_file, function () { - start(); - }); - break; - case 'log': - try { - cli.native.fs.createReadStream(log_file, {encoding: 'utf8'}).pipe(process.stdout); - } catch (e) { - return cli.error('No daemon log file'); - } - break; - case 'pid': - try { - var pid = cli.native.fs.readFileSync(lock_file, 'utf8'); - cli.native.fs.statSync('/proc/' + pid); - cli.info(pid); - } catch (e) { - return cli.error('Daemon is not running'); - } - break; - default: - start(); - break; - } -} - -/** - * The main entry method. Calling cli.main() is only necessary in - * scripts that have daemon support enabled. `callback` receives (args, options) + * The main entry method. `callback` receives (args, options) * * @param {Function} callback * @api public */ cli.main = function (callback) { - var after = function () { - callback.apply(cli, [cli.args, cli.options]); - }; - if (enable.daemon && daemon_arg) { - cli.daemon(daemon_arg, after); - } else { - after(); - } + callback.call(cli, cli.args, cli.options); } /** diff --git a/examples/static.coffee b/examples/static.coffee deleted file mode 100755 index cbf3b16..0000000 --- a/examples/static.coffee +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env coffee - -cli = require 'cli' - -cli.enable('daemon','status') - .setUsage('static.coffee [OPTIONS]') - -cli.parse { - log: ['l', 'Enable logging'] - port: ['p', 'Listen on this port', 'number', 8080] - serve: [false, 'Serve static files from PATH', 'path', './public'] -} - -middleware = [] - -cli.main (args, options) -> - - if options.log - @debug 'Enabling logging' - middleware.push require('creationix/log')() - - @debug 'Serving files from ' + options.serve - middleware.push require('creationix/static')('/', options.serve, 'index.html') - - server = @createServer(middleware).listen options.port - - @ok 'Listening on port ' + options.port \ No newline at end of file diff --git a/examples/static.js b/examples/static.js deleted file mode 100755 index eb6fd24..0000000 --- a/examples/static.js +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env node - -var cli = require('cli').enable('status', 'daemon'); - -cli.parse({ - log: ['l', 'Enable logging'], - port: ['p', 'Listen on this port', 'number', 8080], - serve: [false, 'Serve static files from PATH', 'path', './public'] -}); - -cli.main(function (args, options) { - var server, middleware = []; - - if (options.log) { - this.debug('Enabling logging'); - middleware.push(require('creationix/log')()); - } - - this.debug('Serving files from ' + options.serve); - middleware.push(require('creationix/static')('/', options.serve, 'index.html')); - - server = this.createServer(middleware).listen(options.port); - - this.ok('Listening on port ' + options.port); -}); \ No newline at end of file diff --git a/package.json b/package.json index 96ebb5d..8cbfe4b 100755 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "description" : "A tool for rapidly building command line apps", "version" : "0.11.3", "homepage" : "http://github.com/node-js-libs/cli", - "keywords" : ["cli","command line","opts","parseopt","opt","args","console","argsparse","optparse","daemon","autocomplete","command","autocompletion"], + "keywords" : ["cli","command line","opts","parseopt","opt","args","console","argsparse","optparse","autocomplete","command","autocompletion"], "author" : "Chris O'Hara ", "main" : "cli.js", "bugs": {