diff options
Diffstat (limited to 'MistyCore/service.js')
-rw-r--r-- | MistyCore/service.js | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/MistyCore/service.js b/MistyCore/service.js new file mode 100644 index 0000000..91ada43 --- /dev/null +++ b/MistyCore/service.js @@ -0,0 +1,216 @@ +const fs = require("fs"); +const YAML = require('yaml'); +const child_process = require('child_process'); + +global.servicesProcesses = {}; +global.servicesTimers = {}; +const chalk = require("chalk"); + +let me = { + list: () => { + let services = {}; + + for (let name of fs.readdirSync(systemRoot + "/LaunchDaemons")) { + services[name.substring(0, name.length - 4)] = YAML.parse(fs.readFileSync(systemRoot + "/LaunchDaemons/" + name).toString()); + } + + log("MistyCore-LaunchDaemons", "Gathered list of launch daemons"); + return services; + }, + + reachTarget: (target) => { + process.stdout.clearLine(null); + process.stdout.cursorTo(0); + process.stdout.write(" Loading launch daemons for target " + target + "..."); + + log("MistyCore-LaunchDaemons", "Reached target: " + target); + let matchingServices = []; + + for (let name of fs.readdirSync(systemRoot + "/LaunchDaemons")) { + let service = YAML.parse(fs.readFileSync(systemRoot + "/LaunchDaemons/" + name).toString()); + if (service.metadata.target === target || parseInt(service.metadata.target) === target) { + service.name = name; + matchingServices.push(service); + } + } + + log("MistyCore-LaunchDaemons", "Starting " + matchingServices.length + " launch daemons"); + process.stdout.write(chalk.green(" Success") + "\n"); + for (let service of matchingServices) { + me.start(service.name); + } + }, + + stop: (name, force) => { + let displayName = name.substring(0, name.length - 4); + log("MistyCore-LaunchDaemons", "Stopping " + displayName); + log("MistyCore-LaunchDaemons", "Reading configuration from " + systemRoot + "/LaunchDaemons/" + name); + + let service = YAML.parse(fs.readFileSync(systemRoot + "/LaunchDaemons/" + name).toString()); + let pid = parseInt(fs.readFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName).toString()); + + if (pid === -1) { + log("MistyCore-LaunchDaemons", "Cannot stop " + displayName + ": launch daemon is not running"); + } else { + if (service.commands.stop) { + log("MistyCore-LaunchDaemons", "Launch daemon is using start/stop commands, not stopping as a daemon"); + + try { + child_process.execSync(service.commands.stop, { shell: "/System/Binaries/sh" }); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName, "-1"); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemonsTimes/" + displayName, new Date().getTime().toString()); + } catch (e) { + log("MistyCore-LaunchDaemons", "Launch daemon has failed to stop"); + log("MistyCore-LaunchDaemons", e.stack); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName, "-2"); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemonsTimes/" + displayName, new Date().getTime().toString()); + } + } else { + if (force) { + log("MistyCore-LaunchDaemons", "Launch daemon is using start/stop commands, killing process"); + process.kill(pid, "SIGKILL"); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName, "-1"); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemonsTimes/" + displayName, new Date().getTime().toString()); + } else { + log("MistyCore-LaunchDaemons", "Launch daemon is using start/stop commands, terminating process"); + process.kill(pid); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName, "-1"); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemonsTimes/" + displayName, new Date().getTime().toString()); + } + } + } + }, + + restart: (name, force) => { + let displayName = name.substring(0, name.length - 4); + log("MistyCore-LaunchDaemons", "Restarting " + displayName); + log("MistyCore-LaunchDaemons", "Reading configuration from " + systemRoot + "/LaunchDaemons/" + name); + let service = YAML.parse(fs.readFileSync(systemRoot + "/LaunchDaemons/" + name).toString()); + + if (service.commands.restart) { + log("MistyCore-LaunchDaemons", "Launch daemon is using restart commands, not restarting as a daemon"); + try { + child_process.execSync(service.commands.restart, { shell: "/System/Binaries/sh" }); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName, "0"); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemonsTimes/" + displayName, new Date().getTime().toString()); + } catch (e) { + log("MistyCore-LaunchDaemons", "Launch daemon has failed to restart"); + log("MistyCore-LaunchDaemons", e.stack); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName, "-2"); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemonsTimes/" + displayName, new Date().getTime().toString()); + } + } else { + log("MistyCore-LaunchDaemons", "Launch daemon is not using restart commands, restarting as a daemon"); + me.stop(name, force); + me.start(name, true); + } + }, + + start: (name, hidden) => { + let displayName = name.substring(0, name.length - 4); + fs.writeFileSync(systemRoot + "/Logs/LaunchDaemons/" + displayName + ".log", ""); + log("MistyCore-LaunchDaemons", "Starting " + displayName); + log("MistyCore-LaunchDaemons", "Reading configuration from " + systemRoot + "/LaunchDaemons/" + name); + let service = YAML.parse(fs.readFileSync(systemRoot + "/LaunchDaemons/" + name).toString()); + + if (!hidden) { + process.stdout.clearLine(null); + process.stdout.cursorTo(0); + process.stdout.write(" Starting launch daemon: " + displayName + "..."); + } + + if (service.commands.stop) { + log("MistyCore-LaunchDaemons", "Launch daemon is using start/stop commands, not starting as a daemon"); + try { + let proc = child_process.exec(service.commands.start, { shell: "/System/Binaries/sh" }); + global.servicesProcesses[proc.pid] = proc; + global.servicesTimers[proc.pid] = setTimeout(() => { + proc.kill("SIGKILL"); + log("MistyCore-LaunchDaemons", "Launch daemon has failed to start"); + log("MistyCore-LaunchDaemons", "Startup timed out"); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName, "-2"); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemonsTimes/" + displayName, new Date().getTime().toString()); + }, 10000); + proc.on('exit', (code) => { + if (code === 0) { + log("MistyCore-LaunchDaemons", "Launch daemon has completed startup"); + delete global.servicesProcesses[proc.pid]; + clearTimeout(global.servicesTimers[proc.pid]); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName, "0"); + } else { + log("MistyCore-LaunchDaemons", "Launch daemon has failed to start"); + log("MistyCore-LaunchDaemons", "Process exited with code " + code); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName, "-2"); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemonsTimes/" + displayName, new Date().getTime().toString()); + } + }) + proc.stdout.on('data', (data) => { + fs.appendFileSync(systemRoot + "/Logs/LaunchDaemons/" + displayName + ".log", data); + log(displayName, data.toString()); + }); + proc.stderr.on('data', (data) => { + fs.appendFileSync(systemRoot + "/Logs/LaunchDaemons/" + displayName + ".log", data); + log(displayName, data.toString()); + }); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName, "-3"); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemonsTimes/" + displayName, new Date().getTime().toString()); + + if (!hidden) { + process.stdout.write(chalk.green(" Success") + "\n"); + } + } catch (e) { + log("MistyCore-LaunchDaemons", "Launch daemon has failed to start"); + log("MistyCore-LaunchDaemons", e.stack); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName, "-2"); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemonsTimes/" + displayName, new Date().getTime().toString()); + + if (!hidden) { + process.stdout.write(chalk.yellow(" Failure") + "\n"); + console.log(""); + console.log(chalk.red.inverse("MistyOS is unable to start up.")); + console.log(""); + console.log(chalk.red("A failing launch daemon is preventing MistyOS from starting up correctly.")); + console.log(" " + chalk.red("Launch daemon: " + displayName)); + console.log(" " + chalk.red("Error message: " + e.message)); + console.log(""); + console.log(chalk.red("Try starting your device in safe mode by holding Shift during start up.")); + global.halt(); + } + } + } else { + log("MistyCore-LaunchDaemons", "Launch daemon is not using start/stop commands, starting as a daemon"); + try { + let proc = child_process.exec(service.commands.start, {shell: "/System/Binaries/sh"}); + global.servicesProcesses[proc.pid] = proc; + proc.on('exit', (code) => { + if (code === 0 || code === null) { + log("MistyCore-LaunchDaemons", "Launch daemon has stopped"); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName, "-1"); + } else { + log("MistyCore-LaunchDaemons", "Launch daemon has failed with code " + code); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName, "-2"); + } + + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemonsTimes/" + displayName, new Date().getTime().toString()); + }) + proc.stdout.on('data', (data) => { + fs.appendFileSync(systemRoot + "/Logs/LaunchDaemons/" + displayName + ".log", data); + log(displayName, data.toString()); + }); + proc.stderr.on('data', (data) => { + fs.appendFileSync(systemRoot + "/Logs/LaunchDaemons/" + displayName + ".log", data); + log(displayName, data.toString()); + }); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName, proc.pid.toString()); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemonsTimes/" + displayName, new Date().getTime().toString()); + } catch (e) { + log("MistyCore-LaunchDaemons", "Launch daemon has failed to start"); + log("MistyCore-LaunchDaemons", e.stack); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemons/" + displayName, "-2"); + fs.writeFileSync(systemRoot + "/../Volumes/VM/LaunchDaemonsTimes/" + displayName, new Date().getTime().toString()); + } + } + } +} + +module.exports = me;
\ No newline at end of file |