blob: 9454af6307e91e1a1e3eb84718124321fb24cec3 [file] [log] [blame] [raw]
#!/bin/sh
# Copyright 2015-2020 Rivoreo
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# PROVIDE: minecraft
# REQUIRE: LOGIN FILESYSTEMS
# KEYWORD: shutdown
. /etc/rc.subr
name="minecraft"
desc="The Minecraft server"
rcvar="${name}_enable"
start_cmd="minecraft_start"
stop_cmd="minecraft_stop"
status_cmd="minecraft_status"
load_rc_config ${name}
[ -z "${minecraft_enable}" ] && minecraft_enable="NO"
if [ -n "${minecraft_user}" ]; then
minecraft_user_name="${minecraft_user}"
elif [ -z "${minecraft_user_name}" ]; then
minecraft_user_name="minecraft"
fi
[ -z "${minecraft_home}" ] && minecraft_home="`pw user show -7 -n ${minecraft_user_name} | cut -d : -f 6`"
if [ -z "${minecraft_servers}" ]; then
echo "No server defined, exiting" 1>&2
exit 255
fi
case "${minecraft_use_tmux}" in
[Oo][Nn]|[Yy][Ee][Ss]|Y|[Tt][Rr][Uu][Ee]|1)
minecraft_use_tmux=1
[ -z "${minecraft_session_name}" ] && minecraft_session_name=minecraft
;;
[Oo][Ff][Ff]|[Nn][Oo]|N|[Ff][Aa][Ll][Ss][Ee]|0|"")
minecraft_use_tmux=0
[ -z "${minecraft_alternative_log_file}" ] && minecraft_alternative_log_file=/dev/null
;;
*)
echo "Unrecognized value of minecraft_use_tmux" 1>&2
exit 1
esac
# Workaround to enable the 'status' action
procname="java"
pidfile=
for i in ${minecraft_servers}; do
pidfile="${pidfile}${minecraft_home}/$i/server.pid
"
done
export PATH=/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin
PID=
is_running() {
if [ $# != 1 ]; then
printf "Internal error: is_running: # (%s) != 1\\n" $# 1>&2
exit 2
fi
pid_file="${minecraft_home}/$1/server.pid"
[ -f "$pid_file" ] && PID="`cat \"$pid_file\"`" && [ -n "$PID" ] && [ "$PID" != 0 ] && [ "`ps -o comm= -p $PID`" = java ] && return 0
rm -f "$pid_file"
return 1
}
minecraft_start() {
local command_line
r=0
for i in ${minecraft_servers}; do
if is_running "$i"; then
printf "Server %s is already running\\n" "$i"
continue
fi
#echo Starting Minecraft server...
cd "${minecraft_home}/$i" || continue
if [ -n "${minecraft_start_command}" ]; then
command_line="${minecraft_start_command}"
elif [ -n run.sh ]; then
command_line="exec sh run.sh"
[ -f start.sh ] && printf "Warning: deprecated startup script '%s/start.sh' exists\\n" "$MINECRAFT_HOME/$i" 1>&2
elif [ -f start.sh ]; then
printf "Warning: using deprecated startup script '%s/start.sh'\\n" "$MINECRAFT_HOME/$i" 1>&2
command_line="exec sh start.sh"
else
printf "Startup script '%s/run.sh' not found\\n" "$MINECRAFT_HOME/$i" 1>&2
continue
fi
if [ "$minecraft_use_tmux" = 1 ]; then
su "${minecraft_user_name}" -c "exec tmux -L \"${minecraft_session_name}-$i\" new-session -d \"${minecraft_start_command}\""
else
su "${minecraft_user_name}" -c "${minecraft_start_command}" < /dev/null >> "${minecraft_alternative_log_file}" 2>&1 & sh_pid=$!
fi
sleep 1
if is_running "$i"; then
if [ "${minecraft_use_tmux}" = 1 ] || [ $PID = $sh_pid ]; then
printf "Minecraft server %s started\\n" "$i"
else
printf "Minecraft server %s appeared to be started, but PID mismatch (%s!=%s)\\n" "$i" $PID $sh_pid
fi
else
printf "Failed to start Minecraft server %s\\n" "$i"
r=$((r+1))
fi
done
return $r
}
minecraft_stop() {
for i in ${minecraft_servers}; do
if ! is_running "$i"; then
printf "Server %s is not running\\n" "$i" 1>&2
continue
fi
#echo Stopping Minecraft server...
if [ "${minecraft_use_tmux}" = 1 ]; then
su -m "${minecraft_user_name}" -c "tmux -L \"${minecraft_session_name}-$i\" send-keys -t 0 C-u stop ENTER"
j=8
while [ $j -gt 0 ]; do
j=$((j-1))
sleep 0.5
printf .
if ! is_running "$i"; then
printf " %s stopped\\n" "$i" 1>&2
continue 2
fi
done
echo
fi
echo "Sending SIGINT..." 1>&2
kill -s INT "$PID"
j=4
if while [ $j -gt 0 ]; do
j=$((j-1))
sleep 0.5
if ! is_running "$i"; then
j=0
false
fi
done; then
echo "Sending SIGTERM..." 1>&2
kill "$PID"
j=8
if while [ $j -gt 0 ]; do
j=$((j-1))
sleep 0.5
if ! is_running "$i"; then
j=0
false
fi
done; then
echo "Sending SIGKILL..." 1>&2
kill -s KILL $PID
fi
fi
printf "%s stopped\\n" "$i" 1>&2
done
}
minecraft_status() {
r=0
for i in ${minecraft_servers}; do
if is_running "$i"; then
printf "%s is running (pid %s)\\n" "$i" "$PID"
else
printf "%s is not running\\n" "$i"
r=$((r+1))
fi
done
return $r
}
run_rc_command "$1"