| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //var fs = require('fs');
 | 
					
						
							|  |  |  | var os = require('os'); | 
					
						
							|  |  |  | var mkdirp = require('mkdirp'); | 
					
						
							|  |  |  | var exec = require('child_process').exec; | 
					
						
							|  |  |  | var path = require('path'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  | var Launcher = module.exports; | 
					
						
							| 
									
										
										
										
											2018-07-28 02:14:23 -06:00
										 |  |  | Launcher._killAll = function (fn) { | 
					
						
							|  |  |  |   var psList = require('ps-list'); | 
					
						
							|  |  |  |   psList().then(function (procs) { | 
					
						
							|  |  |  |     procs.forEach(function (proc) { | 
					
						
							| 
									
										
										
										
											2018-09-24 18:11:11 -06:00
										 |  |  |       if ('node' === proc.name && /\btelebit(d| daemon)\b/i.test(proc.cmd)) { | 
					
						
							| 
									
										
										
										
											2018-07-28 02:14:23 -06:00
										 |  |  |         console.log(proc); | 
					
						
							|  |  |  |         process.kill(proc.pid); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     // Two things:
 | 
					
						
							|  |  |  |     // 1) wait to see if the process dies
 | 
					
						
							|  |  |  |     // 2) wait to give time for the socket to connect
 | 
					
						
							|  |  |  |     setTimeout(function () { | 
					
						
							|  |  |  |       if (fn) { fn(null); return; } | 
					
						
							|  |  |  |     }, 1.75 * 1000); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2018-07-28 02:07:11 -06:00
										 |  |  | Launcher._getError = function getError(err, stderr) { | 
					
						
							|  |  |  |   if (err) { return err; } | 
					
						
							|  |  |  |   if (stderr) { | 
					
						
							|  |  |  |     err = new Error(stderr); | 
					
						
							|  |  |  |     err.code = 'ELAUNCHER'; | 
					
						
							|  |  |  |     return err; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | Launcher._detect = function (things, fn) { | 
					
						
							|  |  |  |   if (things.launcher) { | 
					
						
							|  |  |  |     if ('string' === typeof things.launcher) { | 
					
						
							|  |  |  |       fn(null, things.launcher); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ('function' === typeof things.launcher) { | 
					
						
							|  |  |  |       things.launcher(things); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-24 18:11:11 -06:00
										 |  |  |   require('./which.js').launcher(things._execOpts, fn); | 
					
						
							| 
									
										
										
										
											2018-07-28 02:07:11 -06:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  | Launcher.install = function (things, fn) { | 
					
						
							|  |  |  |   if (!fn) { fn = function (err) { if (err) { console.error(err); } }; } | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |   things = things || {}; | 
					
						
							|  |  |  |   // in some future version we can take this file out
 | 
					
						
							|  |  |  |   // and accept process.env from things
 | 
					
						
							| 
									
										
										
										
											2018-06-27 04:24:56 -06:00
										 |  |  |   var installLauncher = require('./template-launcher'); | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Right now this is just for npm install -g and npx
 | 
					
						
							|  |  |  |   if (things.env) { | 
					
						
							|  |  |  |     things.env.PATH = things.env.PATH || process.env.PATH; | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     things.env = process.env; | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |   things.argv = things.argv || process.argv; | 
					
						
							|  |  |  |   things._execOpts = { windowsHide: true, env: things.env }; | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |   var telebitRoot = path.join(__dirname, '../..'); | 
					
						
							|  |  |  |   var vars = { | 
					
						
							|  |  |  |     telebitPath: telebitRoot | 
					
						
							|  |  |  |   , telebitUser: os.userInfo().username | 
					
						
							|  |  |  |   , telebitGroup: (/^darwin/i.test(os.platform()) ? 'staff' : os.userInfo().username) | 
					
						
							|  |  |  |   , telebitRwDirs: [ | 
					
						
							| 
									
										
										
										
											2018-06-28 01:53:03 -06:00
										 |  |  |       telebitRoot | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |     , path.join(os.homedir(), '.config/telebit') | 
					
						
							|  |  |  |     , path.join(os.homedir(), '.local/share/telebit') | 
					
						
							| 
									
										
										
										
											2018-06-27 04:24:56 -06:00
										 |  |  |     ] | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |   , telebitNode: (things.argv[0]||'').replace(/\.exe/i, '') // path.join(telebitRoot, 'bin/node')
 | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |   , telebitBin: path.join(telebitRoot, 'bin/telebit') | 
					
						
							|  |  |  |   , telebitdBin: path.join(telebitRoot, 'bin/telebitd') | 
					
						
							| 
									
										
										
										
											2018-06-27 04:24:56 -06:00
										 |  |  |   , telebitJs: path.join(telebitRoot, 'bin/telebit.js') | 
					
						
							|  |  |  |   , telebitdJs: path.join(telebitRoot, 'bin/telebitd.js') | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |   , telebitConfig: path.join(os.homedir(), '.config/telebit/telebit.yml') | 
					
						
							|  |  |  |   , telebitdConfig: path.join(os.homedir(), '.config/telebit/telebitd.yml') | 
					
						
							| 
									
										
										
										
											2018-06-27 22:58:43 -06:00
										 |  |  |   , TELEBIT_LOG_DIR: path.join(os.homedir(), '.local/share/telebit/var/log') | 
					
						
							| 
									
										
										
										
											2018-06-28 12:37:57 -06:00
										 |  |  |   , TELEBIT_SOCK_DIR: path.join(os.homedir(), '.local/share/telebit/var/run') | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |   }; | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |   vars.telebitBinTpl = path.join(telebitRoot, 'usr/share/dist/bin/telebit.tpl'); | 
					
						
							| 
									
										
										
										
											2018-06-27 04:24:56 -06:00
										 |  |  |   vars.telebitNpm = path.resolve(vars.telebitNode, '../npm'); | 
					
						
							| 
									
										
										
										
											2018-10-09 16:30:10 -06:00
										 |  |  |   vars.nodePath = path.resolve(vars.telebitNode, '../../lib/node_modules'); | 
					
						
							|  |  |  |   vars.npmConfigPrefix = path.resolve(vars.telebitNode, '..', '..'); | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |   vars.userspace = (!things.telebitUser || (things.telebitUser === os.userInfo().username)) ? true : false; | 
					
						
							| 
									
										
										
										
											2018-06-27 04:24:56 -06:00
										 |  |  |   if (-1 === vars.telebitRwDirs.indexOf(vars.npmConfigPrefix)) { | 
					
						
							|  |  |  |     vars.telebitRwDirs.push(vars.npmConfigPrefix); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   vars.telebitRwDirs = vars.telebitRwDirs.join(' '); | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |   var launchers = { | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |     'node': function () { | 
					
						
							|  |  |  |       var fs = require('fs'); | 
					
						
							|  |  |  |       var spawn = require('child_process').spawn; | 
					
						
							|  |  |  |       var logpath = path.join(os.homedir(), '.local/share/telebit/var/log'); | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         mkdirp.sync(logpath); | 
					
						
							|  |  |  |       } catch(e) { | 
					
						
							|  |  |  |         if (fn) { fn(e); return; } | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       var stdout = fs.openSync(path.join(logpath, 'info.log'), 'a'); | 
					
						
							|  |  |  |       var stderr = fs.openSync(path.join(logpath, 'error.log'), 'a'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-28 01:53:03 -06:00
										 |  |  |       var killed = 0; | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |       var err; | 
					
						
							| 
									
										
										
										
											2018-07-03 04:12:53 -06:00
										 |  |  |       var args = [ | 
					
						
							|  |  |  |         path.join(telebitRoot, 'bin/telebitd.js') | 
					
						
							|  |  |  |       , 'daemon' | 
					
						
							|  |  |  |       , '--config' | 
					
						
							|  |  |  |       , vars.telebitdConfig | 
					
						
							|  |  |  |       ]; | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |       var subprocess = spawn( | 
					
						
							|  |  |  |         vars.telebitNode | 
					
						
							| 
									
										
										
										
											2018-07-03 04:12:53 -06:00
										 |  |  |       , args | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |       , { detached: true | 
					
						
							|  |  |  |         , stdio: [ 'ignore', stdout, stderr ] | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       ); | 
					
						
							| 
									
										
										
										
											2018-07-03 04:12:53 -06:00
										 |  |  |       //console.log('[debug]', vars.telebitNode, args.join(' '));
 | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |       subprocess.unref(); | 
					
						
							|  |  |  |       subprocess.on('error', function (_err) { | 
					
						
							|  |  |  |         err = _err; | 
					
						
							| 
									
										
										
										
											2018-06-28 01:53:03 -06:00
										 |  |  |         killed += 1; | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |       }); | 
					
						
							|  |  |  |       subprocess.on('exit', function (code, signal) { | 
					
						
							|  |  |  |         if (!err) { err = new Error('' + code + ' ' + signal + ' failure to launch'); } | 
					
						
							| 
									
										
										
										
											2018-06-28 01:53:03 -06:00
										 |  |  |         killed += 1; | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-28 03:12:13 -06:00
										 |  |  |       // Two things:
 | 
					
						
							|  |  |  |       // 1) wait to see if the process dies
 | 
					
						
							| 
									
										
										
										
											2018-07-03 04:12:53 -06:00
										 |  |  |       // 2) wait to give time for the socket to connect
 | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |       setTimeout(function () { | 
					
						
							| 
									
										
										
										
											2018-06-28 03:12:13 -06:00
										 |  |  |         if (fn) { fn(err); return; } | 
					
						
							| 
									
										
										
										
											2018-07-03 04:12:53 -06:00
										 |  |  |       }, 1.75 * 1000); | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , 'launchctl': function () { | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |       var launcher = path.join(os.homedir(), 'Library/LaunchAgents/cloud.telebit.remote.plist'); | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         mkdirp.sync(path.join(os.homedir(), 'Library/LaunchAgents')); | 
					
						
							| 
									
										
										
										
											2018-06-27 04:24:56 -06:00
										 |  |  |         installLauncher.sync({ | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |             file: { | 
					
						
							|  |  |  |               tpl: vars.telebitBinTpl | 
					
						
							|  |  |  |             , launcher: path.join(vars.telebitPath, 'bin/telebit') | 
					
						
							| 
									
										
										
										
											2018-06-28 13:01:19 -06:00
										 |  |  |             , executable: true | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |           } | 
					
						
							|  |  |  |         , vars: vars | 
					
						
							| 
									
										
										
										
											2018-06-27 04:24:56 -06:00
										 |  |  |         }); | 
					
						
							|  |  |  |         installLauncher({ | 
					
						
							|  |  |  |           file: { | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |               tpl: path.join(vars.telebitPath, 'usr/share/dist/etc/skel/Library/LaunchAgents/cloud.telebit.remote.plist.tpl') | 
					
						
							|  |  |  |             , launcher: launcher | 
					
						
							| 
									
										
										
										
											2018-06-27 04:24:56 -06:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |           , vars: vars | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         var launcherstr = (vars.userspace ? "" : "sudo ") + "launchctl "; | 
					
						
							| 
									
										
										
										
											2018-06-27 22:58:43 -06:00
										 |  |  |         var execstr = launcherstr + "unload -w " + launcher; | 
					
						
							|  |  |  |         exec(execstr, things._execOpts, function (/*err, stdout, stderr*/) { | 
					
						
							|  |  |  |           // we probably only need to skip the stderr (saying that it can't stop something that isn't started)
 | 
					
						
							| 
									
										
										
										
											2018-07-28 02:07:11 -06:00
										 |  |  |           //err = Launcher._getError(err, stderr);
 | 
					
						
							| 
									
										
										
										
											2018-06-27 22:58:43 -06:00
										 |  |  |           //if (err) { fn(err); return; }
 | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |           //console.log((stdout||'').trim());
 | 
					
						
							|  |  |  |           //console.log('unload worked?');
 | 
					
						
							| 
									
										
										
										
											2018-06-27 22:58:43 -06:00
										 |  |  |           execstr = launcherstr + "load -w " + launcher; | 
					
						
							|  |  |  |           exec(execstr, things._execOpts, function (err, stdout, stderr) { | 
					
						
							| 
									
										
										
										
											2018-07-28 02:07:11 -06:00
										 |  |  |             err = Launcher._getError(err, stderr); | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |             if (err) { fn(err); return; } | 
					
						
							|  |  |  |             //console.log((stdout||'').trim());
 | 
					
						
							|  |  |  |             //console.log('load worked?');
 | 
					
						
							| 
									
										
										
										
											2018-06-28 03:12:13 -06:00
										 |  |  |             setTimeout(function () { | 
					
						
							|  |  |  |               fn(null); | 
					
						
							|  |  |  |             }, 1.25 * 1000); | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } catch(e) { | 
					
						
							| 
									
										
										
										
											2018-06-27 04:24:56 -06:00
										 |  |  |         console.error("'" + launcher + "' error:"); | 
					
						
							|  |  |  |         console.error(e); | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |         if (fn) { fn(e); return; } | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |    , 'systemctl': function () { | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |       var launcher = path.join(os.homedir(), '.config/systemd/user/telebit.service'); | 
					
						
							| 
									
										
										
										
											2018-06-28 01:53:03 -06:00
										 |  |  |       var launchername = 'telebit.service'; | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |       try { | 
					
						
							|  |  |  |         mkdirp.sync(path.join(os.homedir(), '.config/systemd/user')); | 
					
						
							|  |  |  |         installLauncher({ | 
					
						
							|  |  |  |           file: { | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |             tpl: path.join(vars.telebitPath, 'usr/share/dist/etc/skel/.config/systemd/user/telebit.service.tpl') | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |           , launcher: launcher | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         , vars: vars | 
					
						
							|  |  |  |         }, function () { | 
					
						
							| 
									
										
										
										
											2018-06-28 01:53:03 -06:00
										 |  |  |           // IMPORTANT
 | 
					
						
							|  |  |  |           // It's a dangerous to go alone, take this:
 | 
					
						
							|  |  |  |           // SYSTEMD_LOG_LEVEL=debug journalctl -xef --user-unit=telebit
 | 
					
						
							|  |  |  |           // (makes debugging systemd issues not "easy" per se, but possible)
 | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |           var launcherstr = (vars.userspace ? "" : "sudo ") + "systemctl " + (vars.userspace ? "--user " : ""); | 
					
						
							| 
									
										
										
										
											2018-06-28 02:01:43 -06:00
										 |  |  |           var execstr = launcherstr + "daemon-reload"; | 
					
						
							|  |  |  |           exec(execstr, things._execOpts, function (err, stdout, stderr) { | 
					
						
							| 
									
										
										
										
											2018-07-28 02:07:11 -06:00
										 |  |  |             err = Launcher._getError(err, stderr); | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |             if (err) { fn(err); return; } | 
					
						
							|  |  |  |             //console.log((stdout||'').trim());
 | 
					
						
							| 
									
										
										
										
											2018-06-28 02:01:43 -06:00
										 |  |  |             var execstr = launcherstr + "enable " + launchername; | 
					
						
							|  |  |  |             exec(execstr, things._execOpts, function (err, stdout, stderr) { | 
					
						
							| 
									
										
										
										
											2018-07-28 13:51:30 -06:00
										 |  |  |               err = Launcher._getError(err, stderr && !/Created symlink/i.test(stderr) && stderr || ''); | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |               if (err) { fn(err); return; } | 
					
						
							|  |  |  |               //console.log((stdout||'').trim());
 | 
					
						
							| 
									
										
										
										
											2018-06-28 02:01:43 -06:00
										 |  |  |               var execstr = launcherstr + "restart " + launchername; | 
					
						
							|  |  |  |               exec(execstr, things._execOpts, function (err, stdout, stderr) { | 
					
						
							| 
									
										
										
										
											2018-07-28 02:07:11 -06:00
										 |  |  |                 err = Launcher._getError(err, stderr); | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |                 if (err) { fn(err); return; } | 
					
						
							|  |  |  |                 //console.log((stdout||'').trim());
 | 
					
						
							| 
									
										
										
										
											2018-06-28 02:01:43 -06:00
										 |  |  |                 setTimeout(function () { | 
					
						
							|  |  |  |                   var execstr = launcherstr + "status " + launchername; | 
					
						
							|  |  |  |                   exec(execstr, things._execOpts, function (err, stdout, stderr) { | 
					
						
							| 
									
										
										
										
											2018-07-28 02:07:11 -06:00
										 |  |  |                     err = Launcher._getError(err, stderr); | 
					
						
							| 
									
										
										
										
											2018-06-28 02:01:43 -06:00
										 |  |  |                     if (err) { fn(err); return; } | 
					
						
							|  |  |  |                     if (!/active.*running/i.test(stdout)) { | 
					
						
							|  |  |  |                       err = new Error("systemd failed to start '" + launchername + "'"); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     if (err) { fn(err); return; } | 
					
						
							|  |  |  |                     //console.log((stdout||'').trim());
 | 
					
						
							|  |  |  |                     fn(null); | 
					
						
							|  |  |  |                   }); | 
					
						
							|  |  |  |                 }, 1.25 * 1000); | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |               }); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } catch(e) { | 
					
						
							| 
									
										
										
										
											2018-06-27 04:24:56 -06:00
										 |  |  |         console.error("'" + launcher + "' error:"); | 
					
						
							|  |  |  |         console.error(e); | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |         if (fn) { fn(e); return; } | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , 'reg.exe': function () { | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |       if (!vars.userspace) { | 
					
						
							|  |  |  |         console.warn("sysetm-level, privileged services are not yet supported on windows"); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |       vars.telebitNode += '.exe'; | 
					
						
							|  |  |  |       var cmd = 'reg.exe add "HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"' | 
					
						
							|  |  |  |         + ' /V "Telebit" /t REG_SZ /D ' | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |         + '"' + things.argv[0] + ' /c '  // something like C:\\Program Files (x64)\nodejs\node.exe
 | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |         + [ path.join(__dirname, 'bin/telebitd.js') | 
					
						
							|  |  |  |           , 'daemon' | 
					
						
							|  |  |  |           , '--config' | 
					
						
							|  |  |  |           , path.join(os.homedir(), '.config/telebit/telebitd.yml') | 
					
						
							|  |  |  |           ].join(' ') | 
					
						
							|  |  |  |         + '" /F' | 
					
						
							|  |  |  |         ; | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |       exec(cmd, things._execOpts, function (err, stdout, stderr) { | 
					
						
							| 
									
										
										
										
											2018-07-28 02:07:11 -06:00
										 |  |  |         err = Launcher._getError(err, stderr); | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |         if (err) { fn(err); return; } | 
					
						
							| 
									
										
										
										
											2018-06-28 03:12:13 -06:00
										 |  |  |         // need to start it for the first time ourselves
 | 
					
						
							| 
									
										
										
										
											2018-06-28 12:37:57 -06:00
										 |  |  |         run(null, 'node'); | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function run(err, launcher) { | 
					
						
							|  |  |  |     if (err) { | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |       console.error("No luck with '" + launcher + "', trying a child process instead..."); | 
					
						
							| 
									
										
										
										
											2018-06-27 04:24:56 -06:00
										 |  |  |       console.error(err); | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |       launcher = 'node'; | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-27 04:24:56 -06:00
										 |  |  |     if (launchers[launcher]) { | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |       // console.log('Launching with launcher ' + launcher);
 | 
					
						
							| 
									
										
										
										
											2018-06-28 12:37:57 -06:00
										 |  |  |       mkdirp.sync(path.join(vars.telebitPath, 'bin')); | 
					
						
							|  |  |  |       mkdirp.sync(vars.TELEBIT_LOG_DIR); | 
					
						
							|  |  |  |       mkdirp.sync(vars.TELEBIT_SOCK_DIR); | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |       launchers[launcher](); | 
					
						
							|  |  |  |       return; | 
					
						
							| 
									
										
										
										
											2018-06-27 04:24:56 -06:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       console.error("No launcher handler for '" + launcher+ "'"); | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-28 02:07:11 -06:00
										 |  |  |   things._vars = vars; | 
					
						
							|  |  |  |   things._userspace = vars.userspace; | 
					
						
							|  |  |  |   Launcher._detect(things, run); | 
					
						
							| 
									
										
										
										
											2018-06-27 03:21:44 -06:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2018-07-28 02:10:29 -06:00
										 |  |  | Launcher.uninstall = function (things, fn) { | 
					
						
							|  |  |  |   if (!fn) { fn = function (err) { if (err) { console.error(err); } }; } | 
					
						
							|  |  |  |   things = things || {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Right now this is just for npm install -g and npx
 | 
					
						
							|  |  |  |   if (things.env) { | 
					
						
							|  |  |  |     things.env.PATH = things.env.PATH || process.env.PATH; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     things.env = process.env; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   things.argv = things.argv || process.argv; | 
					
						
							|  |  |  |   things._execOpts = { windowsHide: true, env: things.env }; | 
					
						
							|  |  |  |   var vars = { | 
					
						
							|  |  |  |     telebitUser: os.userInfo().username | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   vars.userspace = (!things.telebitUser || (things.telebitUser === os.userInfo().username)) ? true : false; | 
					
						
							|  |  |  |   var launchers = { | 
					
						
							|  |  |  |     'node': function () { | 
					
						
							| 
									
										
										
										
											2018-07-28 02:14:23 -06:00
										 |  |  |       Launcher._killAll(fn); | 
					
						
							| 
									
										
										
										
											2018-07-28 02:10:29 -06:00
										 |  |  |     } | 
					
						
							|  |  |  |   , 'launchctl': function () { | 
					
						
							|  |  |  |       var launcher = path.join(os.homedir(), 'Library/LaunchAgents/cloud.telebit.remote.plist'); | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         var launcherstr = (vars.userspace ? "" : "sudo ") + "launchctl "; | 
					
						
							|  |  |  |         var execstr = launcherstr + "unload -w " + launcher; | 
					
						
							|  |  |  |         exec(execstr, things._execOpts, function (err, stdout, stderr) { | 
					
						
							|  |  |  |           // we probably only need to skip the stderr (saying that it can't stop something that isn't started)
 | 
					
						
							|  |  |  |           //err = Launcher._getError(err, stderr);
 | 
					
						
							|  |  |  |           //if (err) { fn(err); return; }
 | 
					
						
							|  |  |  |           //console.log((stdout||'').trim());
 | 
					
						
							|  |  |  |           //console.log('unload worked?');
 | 
					
						
							|  |  |  |           err = Launcher._getError(err, stderr); | 
					
						
							|  |  |  |           if (err) { fn(err); return; } | 
					
						
							|  |  |  |           //console.log((stdout||'').trim());
 | 
					
						
							|  |  |  |           //console.log('load worked?');
 | 
					
						
							|  |  |  |           setTimeout(function () { | 
					
						
							|  |  |  |             fn(null); | 
					
						
							|  |  |  |           }, 1.25 * 1000); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } catch(e) { | 
					
						
							|  |  |  |         console.error("'" + launcher + "' error (uninstall):"); | 
					
						
							|  |  |  |         console.error(e); | 
					
						
							|  |  |  |         if (fn) { fn(e); return; } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |    , 'systemctl': function () { | 
					
						
							|  |  |  |       var launcher = path.join(os.homedir(), '.config/systemd/user/telebit.service'); | 
					
						
							|  |  |  |       var launchername = 'telebit.service'; | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         mkdirp.sync(path.join(os.homedir(), '.config/systemd/user')); | 
					
						
							|  |  |  |         // IMPORTANT
 | 
					
						
							|  |  |  |         // It's a dangerous to go alone, take this:
 | 
					
						
							|  |  |  |         // SYSTEMD_LOG_LEVEL=debug journalctl -xef --user-unit=telebit
 | 
					
						
							|  |  |  |         // (makes debugging systemd issues not "easy" per se, but possible)
 | 
					
						
							|  |  |  |         var launcherstr = (vars.userspace ? "" : "sudo ") + "systemctl " + (vars.userspace ? "--user " : ""); | 
					
						
							|  |  |  |         var execstr = launcherstr + "disable " + launchername; | 
					
						
							|  |  |  |         exec(execstr, things._execOpts, function (err, stdout, stderr) { | 
					
						
							| 
									
										
										
										
											2018-07-28 13:51:30 -06:00
										 |  |  |           err = Launcher._getError(err, stderr && !/Removed symlink/i.test(stderr) && stderr || ''); | 
					
						
							| 
									
										
										
										
											2018-07-28 02:10:29 -06:00
										 |  |  |           if (err) { fn(err); return; } | 
					
						
							|  |  |  |           //console.log((stdout||'').trim());
 | 
					
						
							|  |  |  |           var execstr = launcherstr + "stop " + launchername; | 
					
						
							|  |  |  |           exec(execstr, things._execOpts, function (err, stdout, stderr) { | 
					
						
							|  |  |  |             err = Launcher._getError(err, stderr); | 
					
						
							|  |  |  |             if (err) { fn(err); return; } | 
					
						
							|  |  |  |             //console.log((stdout||'').trim());
 | 
					
						
							|  |  |  |             setTimeout(function () { | 
					
						
							|  |  |  |               var execstr = launcherstr + "status " + launchername; | 
					
						
							|  |  |  |               exec(execstr, things._execOpts, function (err, stdout, stderr) { | 
					
						
							|  |  |  |                 err = Launcher._getError(err, stderr); | 
					
						
							|  |  |  |                 if (err) { fn(err); return; } | 
					
						
							|  |  |  |                 if (!/inactive.*dead/i.test(stdout)) { | 
					
						
							|  |  |  |                   err = new Error("systemd failed to stop '" + launchername + "'"); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (err) { fn(err); return; } | 
					
						
							|  |  |  |                 //console.log((stdout||'').trim());
 | 
					
						
							|  |  |  |                 fn(null); | 
					
						
							|  |  |  |               }); | 
					
						
							|  |  |  |             }, 1.25 * 1000); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } catch(e) { | 
					
						
							|  |  |  |         console.error("'" + launcher + "' error:"); | 
					
						
							|  |  |  |         console.error(e); | 
					
						
							|  |  |  |         if (fn) { fn(e); return; } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , 'reg.exe': function () { | 
					
						
							|  |  |  |       if (!vars.userspace) { | 
					
						
							|  |  |  |         console.warn("sysetm-level, privileged services are not yet supported on windows"); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       var cmd = 'reg.exe add "HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"' | 
					
						
							|  |  |  |         + ' /V "Telebit" /F' | 
					
						
							|  |  |  |         ; | 
					
						
							|  |  |  |       exec(cmd, things._execOpts, function (err, stdout, stderr) { | 
					
						
							|  |  |  |         err = Launcher._getError(err, stderr); | 
					
						
							|  |  |  |         if (err) { fn(err); return; } | 
					
						
							|  |  |  |         // need to start it for the first time ourselves
 | 
					
						
							|  |  |  |         kill(null, 'node'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function kill(err, launcher) { | 
					
						
							|  |  |  |     if (err) { | 
					
						
							|  |  |  |       console.error("No luck with '" + launcher + "', trying a process.kill() instead..."); | 
					
						
							|  |  |  |       console.error(err); | 
					
						
							|  |  |  |       launcher = 'node'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (launchers[launcher]) { | 
					
						
							|  |  |  |       launchers[launcher](); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       console.error("No launcher handler (uninstall) for '" + launcher + "'"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   things._vars = vars; | 
					
						
							|  |  |  |   things._userspace = vars.userspace; | 
					
						
							|  |  |  |   Launcher._detect(things, kill); | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2018-06-27 04:24:56 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | if (module === require.main) { | 
					
						
							| 
									
										
										
										
											2018-07-28 02:07:11 -06:00
										 |  |  |   Launcher.install({ | 
					
						
							| 
									
										
										
										
											2018-06-27 21:35:14 -06:00
										 |  |  |     argv: process.argv | 
					
						
							|  |  |  |   , env: process.env | 
					
						
							|  |  |  |   }, function (err) { | 
					
						
							|  |  |  |     if (err) { console.error(err); return; } | 
					
						
							|  |  |  |     console.log("Telebit launched, or so it seems."); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-06-27 04:24:56 -06:00
										 |  |  | } |