#!/bin/sh # For boot-up and system shutdown, most UNIXes explicitly run a shell # interpreter. In that case, the interpreter line above is ignored. # There are a few UNIXes (notably Darwin) that require the interpreter line. # Copyright (c) 2001-2008, The HSQL Development Group # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # Neither the name of the HSQL Development Group nor the names of its # contributors may be used to endorse or promote products derived from this # software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, # OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # $Id: hsqldb.init 6310 2021-02-28 15:25:00Z unsaved $ # UNIX init script for HSQLDB. # IMPORTANT! Users running multiple HSQLDB ***Server processes*** must use a # unique "SERVICE" name for each Server process. Most users will run just one # server instance, possibly serving lots of database instances. Multi-server # runners must change the value on the following line, and, if your system # uses chkconfig or insserv, you must change the value of "hsqldb" to the # same thing (as SERVICE) in the chkconfig and/or insserv blocks a few # lines down from here (incl. in the pidfile and config file paths). (Sorry # to say, but you need to repeat this procedure after every HSQLDB upgrade). SERVICE=hsqldb # This is the one setting which users will commonly change in this file. # It's impossible to determine this script name (in a portable way) at boot-up # time, since ${0} is entirely different for init scripts, depending on UNIX # version. # See the "HyperSQL on UNIX" chapter of the HyperSQL User Guide for how to # use this file. # This block only used by chkconfig systems (incl. SuSE Linux). # chkconfig: 345 87 13 # description: HyperSQL Database, A High Performance Java Database Server # pidfile: /run/hsqldb.pid # config: /etc/sysconfig/hsqldb # This block only used by insserv systems (incl. SuSE Linux). ### BEGIN INIT INFO # Provides: hsqldb # Required-Start: $syslog $remote_fs $network $named # Required-Stop: # Default-Start: 3 5 # Default-Stop: 0 1 2 6 # Short-Description: HyperSQL Database Server # Description: HyperSQL Database, A High Performance Java Database Server ### END INIT INFO # UNIX System-V and Linux users should copy this script to the common # init script directory (/etc/init.d/ on most systems) with name "hsqldb", # or whatever you have SERVICE set to (no ".init" suffix!). # N.b. Being a system script, this script does not use inherited variables. # If you want to adjust a setting, edit the config file. # Strategy of this init script is to avoid shell-specific functionality, # and use only lowest-common-denominator Bourne capabilities. # We don't include OS-specific functions, and we don't use shell- # implementation-specific functionality like "echo ...\c" or "echo -n...". # Since some Bourne shells don't support shell functions at all, we don't # even define any local functions. # This script has been generalized to the point that it can now "start" # any combination of classes with the normal static main methods. # You can supply invocation arguments to the # TARGET_CLASS invocation, and can start as many other classes as you # wish by using the INVOC_ADDL_ARGS setting (this includes running # multiple HSQLDB Servers of various types). # Template config file can be obtained from the HyperSQL distribution. # On the day I write this, I have it located at "sample/hsqldb.cfg" in the # distro, but that could change. You need to copy then edit it before it # will work. # Recommended locations for runtime configuration file: # Darwin, SunOS, Solaris: /etc/hsqldb.conf # (However, Sunfreeware.com builds use /usr/local/etc). # Linux: /etc/hsqldb/hsqldb.conf (works well to put sqltool.rc here too) # FreeBSD: /usr/local/etc/hsqldb.cfg # (Replace the base name "hsqldb" with whatever you have SERVICE set to at # the top of this file). # You can put it at any of these locations and it will be used. For # your sanity, only put a file at one of these locations. # -- blaine.simpson@admc.com set +u # Following function is Copyright Apache 2.0 by Axis Data Management Corp. # and code is copied verbatim from # http://pub.admc.com/scripts/bin/minsleep-nov.fnc # Sleeps until process dies or file appears. # 2nd parameter is assumed to be a PID if it is an integer. minsleep() { [ $# -eq 2 ] || { echo 'SYNTAX: minsleep MAXSECS PID|PATH (for integers MAXSECS and PID)' 1>&2 return 2 } TARGET_PID= TARGET_PATH= MAXSECS=$1; shift case "$1" in *[!0-9]*) TARGET_PATH="$1";; *) TARGET_PID="$1";; esac; shift _secs=0 while [ $_secs -lt $MAXSECS ]; do _secs=`expr $_secs + 1` if [ -n "$TARGET_PID" ]; then kill -0 $TARGET_PID > /dev/null 2>&1 || return 0 # Target proc died elif [ -s "$TARGET_PATH" ]; then return 0 # Target process died fi sleep 1 done return 1 # Timed out } # This is only used for recursive invocations. # Will not necessarily be set correctly at system bootup invocations # (where it is sometimes invoked like "sh... /path/to/hsqldb start"), # but, in those cases there will be no recursion. INVOC_PATH=`dirname "$0"` || { echo "'dirname' failed" 1>&2 exit 2 } [ -n "$INVOC_PATH" ] && INVOC_PATH="${INVOC_PATH}/" SYNTAX_MSG="SYNTAX: ${INVOC_PATH}${SERVICE} start|stop|stopcompact|restart|restartcmpacted|status" # You can override any of these default values in your config file: # Max time for background su command to start up and echo pid. # (0 works for moderately fast servers). SU_ECHO_SECS=30 # File used as semaphore. If file is removed, a running pid checker # process will exit. PIDCHECKER_FLAGFILE=/tmp/pidchecker.run # The following settings get overridden by optional setting in the config file. # Max time for JVM to die after all HSQLDB instances stopped. MAX_TERMINATE_SECS=60 # We require all Server/WebServer instances to be accessible within # $MAX_START_SECS from when the Server/WebServer is started. MAX_START_SECS=60 # Class to start TARGET_CLASS=org.hsqldb.server.Server CLIENT_JVMARGS= SERVER_JVMARGS= CFGFILE= LOGFILE= PIDFILE= BASEDIR= AUTH_FILE= SHUTDOWN_OPTION= SERVER_ADDL_CLASSPATH= INVOC_ADDL_ARGS= case "`uname`" in Darwin) # I.e. Mac OS X. I don't know about older Mac OSes. LOGFILE=/var/log/${SERVICE}.log PIDFILE=/var/run/${SERVICE}.pid ;; Linux) LOGFILE=/var/log/${SERVICE}.log PIDFILE=/run/${SERVICE}.pid ;; FreeBSD) LOGFILE=/var/log/${SERVICE}.log PIDFILE=/var/run/${SERVICE}.pid ;; SunOS) LOGFILE=/var/log/${SERVICE}.log PIDFILE=/etc/${SERVICE}.pid ;; *) LOGFILE=/var/log/${SERVICE}.log PIDFILE=/etc/${SERVICE}.pid ;; esac for candidate in /etc/hsqldb/${SERVICE}.conf \ /etc/sysconfig/${SERVICE} /etc/${SERVICE}.conf \ /etc/${SERVICE}.cfg /Library/Hsqldb/conf/${SERVICE}.cfg \ /Library/Hsqldb/${SERVICE}.cfg /usr/local/etc/${SERVICE}.cfg; do [ -f $candidate ] && { CFGFILE=$candidate break } done [ -n "$CFGFILE" ] || { echo "No global config file found in any of allowed locations" 1>&2 exit 11 } # Sanity check [ -n "$LOGFILE" ] && [ -n "$PIDFILE" ] || { echo "Internal problem in init script" 1>&2 exit 11 } [ $# -eq 1 ] || { echo "$SYNTAX_MSG" 1>&2 exit 4 } # It would be nice to permit some uses, like "status" by non-root users, # but for now our goal is a superuser init script. [ -w / ] || { # Very portable, but perhaps not perfect, test for superuser. echo "Only 'root' may use this init script" 1>&2 exit 4 } # Use bsd-style enable/disable if it's in place. BSDCFG= [ -r /etc/rc.conf ] && [ -f /etc/rc.conf ] && { . /etc/rc.conf BSDCFG=1 } [ -r /etc/rc.conf.local ] && [ -f /etc/rc.conf.local ] && { . /etc/rc.conf.local BSDCFG=1 } [ -n "$BSDCFG" ] && { case "$hsqldb_enable" in [Yy][Ee][Ss]);; [Oo][Nn]);; [Tt][Rr][Uu][Ee]);; *) exit 0;; # Don't run if not enabled for BSD startup esac } COMMAND="$1"; shift [ -r "$CFGFILE" ] || { echo "Unable to read config file '$CFGFILE'" 1>&2 exit 2 } [ -f "$CFGFILE" ] || { echo "'$CFGFILE' is not a regular file" 1>&2 exit 2 } HSQLDB_OWNER= JAVA_EXECUTABLE= SQLTOOL_JAR_PATH= SERVER_HOME= SHUTDOWN_URLIDS= URLIDS= . "$CFGFILE" # Suffix delimiter to $SERVER_ADDL_CLASSPATH, if it is set. [ -n "$SERVER_ADDL_CLASSPATH" ] && SERVER_ADDL_CLASSPATH="${SERVER_ADDL_CLASSPATH}:" # Validate that config file sets all required variables. [ -n "$JAVA_EXECUTABLE" ] && [ -n "$SQLTOOL_JAR_PATH" ] && [ -n "$SERVER_HOME" ] && [ -n "$URLIDS" ] || { echo "Config file '$CFGFILE' does not set one or more of following variables JAVA_EXECUTABLE, SQLTOOL_JAR_PATH, SERVER_HOME, URLIDS" 1>&2 exit 2 } [ -d "$SERVER_HOME" ] || { echo "SERVER_HOME variable in '$CFGFILE' is set to a non-directory." 1>&2 exit 2 } [ -f "$JAVA_EXECUTABLE" ] && [ -f "$SQLTOOL_JAR_PATH" ] || { echo "JAVA_EXECUTABLE or SQLTOOL_JAR_PATH in '$CFGFILE' is set to a non-file." 1>&2 exit 2 } [ -r "$SQLTOOL_JAR_PATH" ] || { echo "'$SQLTOOL_JAR_PATH' isn't readable" 1>&2 exit 2 } [ -x "$JAVA_EXECUTABLE" ] || { echo "No Java executable found at '$JAVA_EXECUTABLE'" 1>&2 exit 2 } # "chown" lives here on some UNIXes. PATH="$PATH:/usr/sbin" # Make a good effort (but not bullet-proof) check on permissions of the # auth file. Unfortunately, if auth-file is not specified, this depends # upon both (a) $HOME being set; and (b) SqlToolSprayer and SqlTool defaults. # On the other hand, it works great if AUTH_FILE is set explicitly by user. if [ -z "$AUTH_FILE" ] && [ -z "$HOME" ]; then : # Lousy init environment didn't set $HOME, so can't find dflt cfg file. else _AUTH_TEST_PATH="$AUTH_FILE" [ -n "${_AUTH_TEST_PATH}" ] || _AUTH_TEST_PATH="$HOME/sqltool.rc" [ -f "$_AUTH_TEST_PATH" ] || { echo "No auth file found at '$_AUTH_TEST_PATH'" 1>&2 exit 2 } [ -r "$_AUTH_TEST_PATH" ] || { echo "Auth file '$_AUTH_TEST_PATH' not readable" 1>&2 exit 2 } ls -lLd "$_AUTH_TEST_PATH" | grep '^-..------' > /dev/null 2>&1 || { echo "Fix permissions on '$_AUTH_TEST_PATH' like 'chmod 600 $_AUTH_TEST_PATH'" 1>&2 exit 2 } fi # Set HSQLDB_PID according to pid file. HSQLDB_PID= [ -r "$PIDFILE" ] && { [ -f "$PIDFILE" ] || { echo "'$PIDFILE' is not a regular file" 1>&2 exit 6 } [ -w "$PIDFILE" ] || { echo "'$PIDFILE' is not writable" 1>&2 exit 6 } HSQLDB_PID="`cat $PIDFILE`" || { echo "Failed to read pid file '$PIDFILE'" 1>&2 exit 6 } case "$HSQLDB_PID" in *[a-zA-Z/!@#$%*+=_~]*) HSQLDB_PID=;; *'^'*) HSQLDB_PID=;; esac [ -n "$HSQLDB_PID" ] || { echo "Pid file '$PIDFILE' does not contain a valid process identifier" 1>&2 exit 6 } kill -0 "$HSQLDB_PID" > /dev/null 2>&1 || { echo 'Removing stale pid file' rm -f "$PIDFILE" || { echo "Failed to remove pid file '$PIDFILE'" 1>&2 exit 6 } HSQLDB_PID= } #echo "PID is ($HSQLDB_PID)" } case "$COMMAND" in status) [ -n "$HSQLDB_PID" ] || { echo "I don't know of any running ${SERVICE} server." exit 0 } echo "There is an ${SERVICE} server loaded from $SQLTOOL_JAR_PATH running with pid $HSQLDB_PID." # I would give a nice ps command here, were ps not so damned # OS-specific. AUTH_FILE_SWITCH= # N.b., there will be a problem if there are special characters or # spaces inside of $AUTH_FILE. [ -n "$AUTH_FILE" ] && AUTH_FILE_SWITCH="-Dsqltoolsprayer.rcfile=$AUTH_FILE" # Might as well set CLASSPATH for a cleaner command. CLASSPATH="$SQLTOOL_JAR_PATH" export CLASSPATH export PATH # Required only for some funny init environments. exec "$JAVA_EXECUTABLE" $AUTH_FILE_SWITCH $CLIENT_JVMARGS \ "-Dsqltoolsprayer.monfile=$PIDFILE" \ org.hsqldb.cmdline.SqlToolSprayer 'CALL true;' $URLIDS > /dev/null ;; start) [ -n "$TLS_KEYSTORE" ] || [ -n "$TLS_PASSWORD" ] && echo "WARNING: The TLS_* settings have been obsoleted. See the comments in the new sample 'hsqldb.cfg' file." 1>&2 [ -n "$HSQLDB_PID" ] && { echo "There is already a ${SERVICE} server running with pid $HSQLDB_PID." 1>&2 exit 1 } if [ -n "$HSQLDB_OWNER" ]; then touch "$PIDFILE" || { echo "Failed to create pid file" 1>&2 exit 1 } chown "$HSQLDB_OWNER" "$PIDFILE" || { echo "Failed to chown pid file to '$HSQLDB_OWNER'" 1>&2 exit 1 } # Some OSes choke if there are newlines in this string. # N.b.!!! The shell of the -c command is the target user's default # login shell, so keep this command shell-independent! nohup su "$HSQLDB_OWNER" -c "cd '$SERVER_HOME' && echo "'$$'" > '$PIDFILE' && exec '$JAVA_EXECUTABLE' $SERVER_JVMARGS -classpath '${SERVER_ADDL_CLASSPATH}${SQLTOOL_JAR_PATH}' org.hsqldb.util.MainInvoker $TARGET_CLASS $INVOC_ADDL_ARGS" >> "$LOGFILE" 2>&1 & else cd "$SERVER_HOME" || { echo "Failed to cd to '$SERVER_HOME'" 1>&2 exit 1 } export JAVA_EXECUTABLE export SQLTOOL_JAR_PATH export PIDFILE export SERVER_JVMARGS export TARGET_CLASS export INVOC_ADDL_ARGS export SERVER_ADDL_CLASSPATH nohup sh -c ' echo $$ > "$PIDFILE" || { echo "Failed to write pid to pid file" 1>&2 exit 1 } eval exec "$JAVA_EXECUTABLE" $SERVER_JVMARGS -classpath "${SERVER_ADDL_CLASSPATH}${SQLTOOL_JAR_PATH}" org.hsqldb.util.MainInvoker $TARGET_CLASS $INVOC_ADDL_ARGS ' >> "$LOGFILE" 2>&1 & fi minsleep $SU_ECHO_SECS "$PIDFILE" # Make sure bg commands have time to echo pid. AUTH_FILE_SWITCH= # N.b., there will be a problem if there are special characters or # spaces inside of $AUTH_FILE. [ -n "$AUTH_FILE" ] && AUTH_FILE_SWITCH="-Dsqltoolsprayer.rcfile=$AUTH_FILE" # Might as well set CLASSPATH for a cleaner command. CLASSPATH="$SQLTOOL_JAR_PATH" export CLASSPATH export PATH # Required only for some funny init environments. # There are many reasons why we could fail to read the pid file, # but regardless of why, the pid file does not contain a valid pid. touch "$PIDCHECKER_FLAGFILE" || { echo "Failed to touch file '$PIDCHECKER_FLAGFILE'" 1>&2 exit 1 } export PIDCHECKER_FLAGFILE export PIDFILE ( while true; do # Could possibly use minsleep to simplify this, but I don't # want to take the time to test the function export behavior. # -a and -e tests are not portable. [ -f "$PIDCHECKER_FLAGFILE" ] || exit 0 kill -0 "`cat $PIDFILE`" > /dev/null 2>&1 || { rm -f "$PIDFILE" "$PIDCHECKER_FLAGFILE" exit 1 } sleep 1 done ) & "$JAVA_EXECUTABLE" $AUTH_FILE_SWITCH $CLIENT_JVMARGS \ "-Dsqltoolsprayer.monfile=$PIDFILE" \ "-Dsqltoolsprayer.maxtime=${MAX_START_SECS}000" \ org.hsqldb.cmdline.SqlToolSprayer 'CALL true;' $URLIDS > /dev/null && { rm -f "$PIDCHECKER_FLAGFILE" echo "$TARGET_CLASS started with pid `cat $PIDFILE`" exit 0 } rm -f "$PIDCHECKER_FLAGFILE" echo "Failed to start $TARGET_CLASS. See log file '$LOGFILE'." 1>&2 exit 1 ;; stop|stopcompact) [ "$COMMAND" = stopcompact ] && SHUTDOWN_OPTION='compact' [ -n "$HSQLDB_PID" ] || { echo "I don't know of any running ${SERVICE} server." 1>&2 exit 1 } AUTH_FILE_SWITCH= # N.b., there will be a problem if there are special characters or # spaces inside of $AUTH_FILE. [ -n "$AUTH_FILE" ] && AUTH_FILE_SWITCH="-Dsqltoolsprayer.rcfile=$AUTH_FILE" # Might as well set CLASSPATH for a cleaner command. CLASSPATH="$SQLTOOL_JAR_PATH" export CLASSPATH export PATH # Required only for some funny init environments. "$JAVA_EXECUTABLE" $AUTH_FILE_SWITCH $CLIENT_JVMARGS \ org.hsqldb.cmdline.SqlToolSprayer "shutdown ${SHUTDOWN_OPTION};" \ $URLIDS $SHUTDOWN_URLIDS || exit 1 minsleep $MAX_TERMINATE_SECS $HSQLDB_PID || { echo "WARNING: ${SERVICE} is still running!" 1>&2 exit 1 } rm -f "$PIDFILE" || { echo "Failed to remove pid file '$PIDFILE'" 1>&2 exit 1 } echo "Successful shutdown ${SHUTDOWN_OPTION} (for the $TARGET_CLASS process)!" exit 0 ;; restart|restartcompacted) STOP_COMMAND=stop [ "$COMMAND" = restartcompacted ] && STOP_COMMAND=stopcompact "${INVOC_PATH}"${SERVICE} $STOP_COMMAND || exit $? exec "${INVOC_PATH}"/${SERVICE} start ;; *) echo "$SYNTAX_MSG" 1>&2 exit 5 ;; esac