summaryrefslogtreecommitdiff
path: root/MistyCore/service.js
diff options
context:
space:
mode:
Diffstat (limited to 'MistyCore/service.js')
-rw-r--r--MistyCore/service.js216
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