/** * Licensed to JumpMind Inc under one or more contributor * license agreements. See the NOTICE file distributed * with this work for additional information regarding * copyright ownership. JumpMind Inc licenses this file * to you under the GNU General Public License, version 3.0 (GPLv3) * (the "License"); you may not use this file except in compliance * with the License. * * You should have received a copy of the GNU General Public License, * version 3.0 (GPLv3) along with this library; if not, see * <http://www.gnu.org/licenses/>. * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.jumpmind.symmetric.wrapper; import java.io.BufferedReader; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.lang.reflect.Field; import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; import org.jumpmind.symmetric.wrapper.jna.CLibrary; @IgnoreJRERequirement public class UnixService extends WrapperService { private static final String[] RUN_LEVELS_START = new String[] { "2", "3", "5" }; private static final String[] RUN_LEVELS_STOP = new String[] { "0", "1", "6" }; private static final String RUN_SEQUENCE_START = "20"; private static final String RUN_SEQUENCE_STOP = "80"; private static final String RC_DIR = "/etc"; private static final String INITD_DIR = "/etc/init.d"; @Override protected boolean setWorkingDirectory(String dir) { return CLibrary.INSTANCE.chdir(dir) == 0; } @Override public void install() { String rcDir = getRunCommandDir(); String runFile = INITD_DIR + "/" + config.getName(); if (!isPrivileged()) { throw new WrapperException(Constants.RC_MUST_BE_ROOT, 0, "Must be root to install"); } System.out.println("Installing " + config.getName() + " ..."); try { FileWriter writer = new FileWriter(runFile); BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream( "/symmetricds.initd"))); String line = null; while ((line = reader.readLine()) != null) { line = line.replaceAll("\\$\\{wrapper.name}", config.getName()); line = line.replaceAll("\\$\\{wrapper.displayname}", config.getDisplayName()); line = line.replaceAll("\\$\\{wrapper.description}", config.getDescription()); line = line.replaceAll("\\$\\{wrapper.home}", config.getWorkingDirectory().getAbsolutePath()); line = line.replaceAll("\\$\\{wrapper.java.command}", config.getJavaCommand()); line = line.replaceAll("\\$\\{wrapper.jarfile}", config.getWrapperJarPath()); writer.write(line + "\n"); } reader.close(); writer.close(); } catch (IOException e) { throw new WrapperException(Constants.RC_FAIL_INSTALL, 0, "Failed while writing run file", e); } new File(runFile).setExecutable(true, false); for (String runLevel : RUN_LEVELS_START) { CLibrary.INSTANCE.symlink(runFile, rcDir + "/rc" + runLevel + ".d/S" + RUN_SEQUENCE_START + config.getName()); } for (String runLevel : RUN_LEVELS_STOP) { CLibrary.INSTANCE.symlink(runFile, rcDir + "/rc" + runLevel + ".d/K" + RUN_SEQUENCE_STOP + config.getName()); } System.out.println("Done"); } @Override public void uninstall() { String rcDir = getRunCommandDir(); String runFile = INITD_DIR + "/" + config.getName(); if (!isPrivileged()) { throw new WrapperException(Constants.RC_MUST_BE_ROOT, 0, "Must be root to uninstall"); } System.out.println("Uninstalling " + config.getName() + " ..."); for (String runLevel : RUN_LEVELS_START) { new File(rcDir + "/rc" + runLevel + ".d/S" + RUN_SEQUENCE_START + config.getName()).delete(); } for (String runLevel : RUN_LEVELS_STOP) { new File(rcDir + "/rc" + runLevel + ".d/K" + RUN_SEQUENCE_STOP + config.getName()).delete(); } new File(runFile).delete(); System.out.println("Done"); } protected String getRunCommandDir() { String rcDir = ""; if (new File(INITD_DIR + "/rc0.d").exists()) { rcDir = INITD_DIR; } else if (new File(RC_DIR + "/rc0.d").exists()) { rcDir = RC_DIR; } else { throw new WrapperException(Constants.RC_MISSING_INIT_FOLDER, 0, "Unable to locate run level folders"); } return rcDir; } @Override public boolean isPrivileged() { return CLibrary.INSTANCE.geteuid() == 0; } @Override public boolean isInstalled() { return new File(INITD_DIR + "/" + config.getName()).exists(); } @Override protected boolean isPidRunning(int pid) { return pid != 0 && CLibrary.INSTANCE.kill(pid, 0) == 0; } @Override protected int getCurrentPid() { return CLibrary.INSTANCE.getpid(); } @Override protected int getProcessPid(Process process) { int pid = 0; try { Field field = process.getClass().getDeclaredField("pid"); field.setAccessible(true); pid = field.getInt(process); } catch (Exception e) { } return pid; } @Override protected void killProcess(int pid, boolean isTerminate) { CLibrary.INSTANCE.kill(pid, isTerminate ? 9 : 1); } }