+//#! /usr/bin/java --source 17 @/usr/local/etc/freed/pid1/jvm.args
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.TreeMap;
+
+import org.argeo.init.Service;
+
+import jdk.jshell.tool.JavaShellToolBuilder;
+import sun.misc.Signal;
+
+class FreedPid1 {
+ public static void main(String... args) {
+ final long pid = ProcessHandle.current().pid();
+ System.out.println("FREEd Init daemon starting with pid " + pid + "...");
+// System.out.println(System.getProperty("user.dir"));
+// System.out.println(System.getProperty("user.name"));
+// System.out.println(System.getProperty("user.home"));
+
+ // System.setProperty("user.dir", "/tmp");
+ for (Object key : new TreeMap<>(System.getProperties()).keySet()) {
+ System.out.println(key + "=" + System.getProperty(key.toString()));
+ }
+
+ System.out.flush();
+
+ Signal.handle(new Signal("TERM"), (signal) -> {
+ System.out.println("SIGTERM caught");
+ System.exit(0);
+ });
+ Signal.handle(new Signal("INT"), (signal) -> {
+ System.out.println("SIGINT caught");
+ System.exit(0);
+ });
+ Signal.handle(new Signal("HUP"), (signal) -> {
+ System.out.println("SIGHUP caught");
+ System.exit(0);
+ });
+
+ if (args.length > 0 && ("1".equals(args[0]) //
+ || "single".equals(args[0]) //
+ || "emergency".equals(args[0]))) {
+ // TODO check if we can remove dependency to management
+ String classpath = ManagementFactory.getRuntimeMXBean().getClassPath();
+ String feedbackMode = "concise";
+ // TODO --startup script
+ JavaShellToolBuilder builder = JavaShellToolBuilder.builder();
+ try {
+ builder.start("--execution", "direct", "--class-path", classpath, "--feedback", feedbackMode);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.err.flush();
+ System.exit(1);
+ return;
+ }
+
+ } else {
+ // init Linux services
+ initSysctl();
+ startInitDService("networking");
+ startInitDService("nslcd");
+
+ waitForNetwork();
+
+ // init Argeo CMS
+ Service.main(args);
+ }
+ }
+
+ static void initSysctl() {
+ try {
+ Path sysctlD = Paths.get("/etc/sysctl.d/");
+ for (Path conf : Files.newDirectoryStream(sysctlD, "*.conf")) {
+ try {
+ new ProcessBuilder("/usr/sbin/sysctl", "-p", conf.toString()).start();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ static void startInitDService(String serviceName) {
+ Path serviceInit = Paths.get("/etc/init.d/", serviceName);
+ if (Files.exists(serviceInit))
+ try {
+ new ProcessBuilder(serviceInit.toString(), "start").start().waitFor();
+ System.out.println("Service " + serviceName + " started");
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+ try {
+ new ProcessBuilder(serviceInit.toString(), "stop").start().waitFor();
+ } catch (IOException | InterruptedException e) {
+ e.printStackTrace();
+ }
+ }, "Stop service " + serviceName));
+ } catch (IOException | InterruptedException e) {
+ e.printStackTrace();
+ }
+ else
+ System.out.println("Service " + serviceName + " not found and therefore not started");
+ }
+
+ static void waitForNetwork() {
+ // TODO Do it properly
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+}