|
#!/bin/bash |
|
# PhrozenByte mta-server |
|
# Version 3.1 |
|
# |
|
# SHORT DESCRIPTION: |
|
# Manages Multi Theft Auto (MTA) server daemons |
|
# |
|
# COPYRIGHT AND LICENSING: |
|
# Copyright (C) 2006-2016 Daniel Rudolf <http://www.daniel-rudolf.de/> |
|
# |
|
# This program is free software: you can redistribute it and/or modify |
|
# it under the terms of the GNU General Public License as published by |
|
# the Free Software Foundation, version 3 of the License only. |
|
# |
|
# This program is distributed in the hope that it will be useful, |
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
# GNU General Public License for more details. |
|
# |
|
# You should have received a copy of the GNU General Public License |
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
LC_ALL=C |
|
APP_NAME="$(basename "$0")" |
|
|
|
function showUsage() { |
|
echo "Usage:" |
|
echo " $APP_NAME {start|attach|cleanup|stop|restart|status} MTA_EXEC_PATH" |
|
} |
|
|
|
# you must run this as root |
|
if [ "$(id -u)" -ne "0" ]; then |
|
echo "$APP_NAME: You must run this as \`root'" >&2 |
|
exit 1 |
|
fi |
|
|
|
# check parameters |
|
EXEC_PATH="/opt/mta" |
|
if [ $# -ne 2 ]; then |
|
showUsage |
|
exit 1 |
|
else |
|
if [ "${2:0:1}" != "/" ] && [ -d "/opt/mta/$2" ]; then |
|
EXEC_PATH="/opt/mta/$2" |
|
else |
|
if [ ! -e "$2" ]; then |
|
echo "$APP_NAME: Invalid MTA_EXEC_PATH: No such file or directory" >&2 |
|
exit 1 |
|
elif [ ! -d "$2" ]; then |
|
echo "$APP_NAME: Invalid MTA_EXEC_PATH: Not a directory" >&2 |
|
exit 1 |
|
fi |
|
|
|
EXEC_PATH="$2" |
|
fi |
|
fi |
|
|
|
# validate exec path |
|
ENVFILE="$EXEC_PATH/mta-server.env" |
|
CMD_START="$EXEC_PATH/start-mta-server" |
|
CMD_CLEANUP="$EXEC_PATH/cleanup-mta-server" |
|
if [ ! -f "$ENVFILE" ]; then |
|
echo "$APP_NAME: Invalid MTA_EXEC_PATH: \`mta-server.env' not found" >&2 |
|
exit 1 |
|
elif [ ! -r "$ENVFILE" ]; then |
|
echo "$APP_NAME: Invalid MTA_EXEC_PATH: \`mta-server.env' not readable" >&2 |
|
exit 1 |
|
elif [ ! -x "$CMD_START" ]; then |
|
echo "$APP_NAME: Invalid MTA_EXEC_PATH: No executable environment" >&2 |
|
exit 1 |
|
elif [ ! -x "$CMD_CLEANUP" ]; then |
|
echo "$APP_NAME: Invalid MTA_EXEC_PATH: No executable environment (cleanup)" >&2 |
|
exit 1 |
|
fi |
|
|
|
# get server id |
|
SERVER_ID="$(source "$ENVFILE" ; echo -n "$SERVER_ID")" |
|
if [ -z "$SERVER_ID" ]; then |
|
echo "$APP_NAME: Invalid MTA_EXEC_PATH: Invalid \`mta-server.env'" >&2 |
|
exit 1 |
|
fi |
|
|
|
# get PIDs of already running servers |
|
SCREEN_PIDS="$(screen -list | awk "/^\t([0-9]+)\.mta-server-$SERVER_ID\t/ {print \$1}" | cut -d "." -f 1)" |
|
|
|
case "$1" in |
|
# start server |
|
start) |
|
# check if server is already running |
|
if [ -n "$SCREEN_PIDS" ]; then |
|
if [ "$(echo "$SCREEN_PIDS" | wc -l)" -eq "1" ]; then |
|
echo "$APP_NAME: There is propably already a server running" >&2 |
|
else |
|
echo "$APP_NAME: There are propably already $(echo "$SCREEN_PIDS" | wc -l) servers running" >&2 |
|
fi |
|
exit 1 |
|
fi |
|
|
|
# start server |
|
echo -n "Starting server" |
|
screen -dmS "mta-server-$SERVER_ID" "$CMD_START" |
|
|
|
# wait for startup (don't wait for longer than 40 * 0.25 = 10 seconds) |
|
SCREEN_PID_COUNT="$(echo -n "$SCREEN_PIDS" | wc -l)" |
|
SERVER_RUNNING="no" |
|
|
|
i=0 |
|
while [ "$i" -le 40 ]; do |
|
CURRENT_SCREEN_PID_COUNT="$(screen -list | awk "/^\t([0-9]+)\.mta-server-$SERVER_ID\t/ {print \$1}" | wc -l)" |
|
if [ "$CURRENT_SCREEN_PID_COUNT" -ne "$SCREEN_PID_COUNT" ]; then |
|
if [ "$SERVER_RUNNING" == "no" ]; then |
|
# screen session appeared |
|
SCREEN_PID_COUNT="$CURRENT_SCREEN_PID_COUNT" |
|
SERVER_RUNNING="yes" |
|
else |
|
# screen session disappeared |
|
SERVER_RUNNING="error" |
|
break |
|
fi |
|
fi |
|
|
|
echo -n "." |
|
sleep 0.25 |
|
let "i++" |
|
done |
|
echo |
|
|
|
if [ "$SERVER_RUNNING" != "yes" ]; then |
|
# startup failed |
|
if [ "$SERVER_RUNNING" == "error" ]; then |
|
echo "$APP_NAME: Server crashed immediately after startup" >&2 |
|
else |
|
echo "$APP_NAME: Giving up; the server is probably not running" >&2 |
|
fi |
|
|
|
echo "Maybe a previously started server crashed, try running \`$EXEC_PATH/cleanup-mta-server'" >&2 |
|
echo "You should also check the logfiles at \`/var/log/mta-server.log'" >&2 |
|
exit 1 |
|
fi |
|
;; |
|
|
|
attach) |
|
if [ -z "$SCREEN_PIDS" ]; then |
|
echo "$APP_NAME: There is probably no server running" >&2 |
|
exit 1 |
|
fi |
|
|
|
if [ "$(echo "$SCREEN_PIDS" | wc -l)" -gt "1" ]; then |
|
echo "There are currently $(echo "$SCREEN_PIDS" | wc -l) servers running" |
|
echo "Attaching server with PID $(echo "$SCREEN_PIDS" | tail -n 1)..." |
|
sleep 3 |
|
fi |
|
|
|
screen -r "$(echo "$SCREEN_PIDS" | tail -n 1).mta-server-$SERVER_ID" |
|
;; |
|
|
|
cleanup) |
|
if [ -z "$SCREEN_PIDS" ]; then |
|
echo "Cleaning up environment..." |
|
"$CMD_CLEANUP" |
|
exit $? |
|
else |
|
echo "You can't cleanup while a server is running" |
|
if [ "$(echo "$SCREEN_PIDS" | wc -l)" -gt "1" ]; then |
|
echo "There are probably ($(echo "$SCREEN_PIDS" | wc -l) servers running" |
|
fi |
|
|
|
exit 1 |
|
fi |
|
;; |
|
|
|
stop) |
|
# is a server running? |
|
if [ -n "$SCREEN_PIDS" ]; then |
|
echo -n "Stopping server" |
|
|
|
# stop all running servers |
|
EXIT=0 |
|
for SCREEN_PID in $SCREEN_PIDS; do |
|
echo -n " (PID: $SCREEN_PID)" |
|
|
|
# send shutdown command |
|
screen -S "$SCREEN_PID.mta-server-$SERVER_ID" -p 0 \ |
|
-X stuff "$(printf '%80s' | tr ' ' '\b')$(printf '%80s\r')shutdown$(printf '\r')" |
|
|
|
# wait for shutdown (don't wait for longer than 120 * 0.25 = 30 seconds) |
|
i=0 |
|
while [ "$i" -le 120 ]; do |
|
if [ "$(screen -list | awk "/^\t$SCREEN_PID\.mta-server-$SERVER_ID\t/ {print \$1}" | wc -l)" -gt "0" ]; then |
|
echo -n "." |
|
sleep 0.25 |
|
let "i++" |
|
else |
|
break |
|
fi |
|
done |
|
echo |
|
|
|
# when server is still running, ... |
|
if [ "$(screen -list | awk "/^\t$SCREEN_PID\.mta-server-$SERVER_ID\t/ {print \$1}" | wc -l)" -ne "0" ]; then |
|
EXIT=1 |
|
|
|
# quit the screen session |
|
echo "$APP_NAME: Unable to shutdown server - quit screen session..." >&2 |
|
screen -S "$SCREEN_PID.mta-server-$SERVER_ID" -X quit |
|
sleep 1 |
|
|
|
# when the server is still running, kill screen |
|
if [ "$(screen -list | awk "/^\t$SCREEN_PID\.mta-server-$SERVER_ID\t/ {print \$1}" | wc -l)" -ne "0" ]; then |
|
echo "$APP_NAME: Unable to quit screen session - killing screen session..." >&2 |
|
kill -KILL "$SCREEN_PID" |
|
fi |
|
fi |
|
done |
|
|
|
exit $EXIT |
|
else |
|
echo "$APP_NAME: There is probably no server running" >&2 |
|
exit 1 |
|
fi |
|
;; |
|
|
|
restart) |
|
$0 stop "$EXEC_PATH" |
|
if [ $? != 0 ]; then |
|
exit $? |
|
fi |
|
|
|
$0 start "$EXEC_PATH" |
|
if [ $? != 0 ]; then |
|
exit $? |
|
fi |
|
;; |
|
|
|
status) |
|
if [ -n "$SCREEN_PIDS" ]; then |
|
if [ "$(echo "$SCREEN_PIDS" | wc -l)" -eq "1" ]; then |
|
echo "There is propably a server running" |
|
else |
|
echo "There are propably $(echo "$SCREEN_PIDS" | wc -l) servers running" |
|
fi |
|
else |
|
echo "There is propably no server running" |
|
fi |
|
;; |
|
|
|
*) |
|
echo "$APP_NAME: Unknown parameter \`$1'" >&2 |
|
showUsage |
|
exit 1 |
|
;; |
|
esac |
|
|
|
exit 0 |