Author Topic: Yet Another Startup Script  (Read 151 times)

Offline quixadhal

  • BFF
  • ***
  • Posts: 642
    • View Profile
    • WileyMUD
Yet Another Startup Script
« on: July 01, 2018, 02:49:17 PM »
So, I generally hate those dumb "looping" startup scripts that keep restarting your MUD in a while loop.  A while ago I wrote a very small one that just did "start" "stop" and "status".

For some reason, while watching the world cup game the other day, I decided to pretty it up and add a couple more little features.....  FOOL!

It's a bit big now, but it was fun messing around with bash scripting again.

Code: [Select]
#!/bin/bash

# These should be the only lines you need to configure.
M_DIR="/home/quixadhal/dw/bin"
M_CFG="$M_DIR/dw.cfg"

# The rest of this should be fine.
SCRIPT="$0"
CMD="$1"

D_PORT=`grep <"$M_CFG" external_port_1 | awk '{print $NF}'`
A_PORT=`grep <"$M_CFG" 'address server port' | awk '{print $NF}'`
G_DRIVER="$M_DIR/driver $M_CFG"
G_ADDR="$M_DIR/addr_server $A_PORT"

function get_status() {
    HEADER=`ps -auxwwww | head -1`
    DRIVER=`ps -auxwwww | grep "$G_DRIVER" | grep -v "grep $G_DRIVER" | head -1`
    ADDR=`ps -auxwwww | grep "$G_ADDR" | grep -v "grep $G_ADDR" | head -1`
    D_PID=`echo $DRIVER | awk '{print $2}'`
    A_PID=`echo $ADDR | awk '{print $2}'`
    CRON_HEADER='# m h  dom mon dow   command'
    CRON_START_ENTRY=`crontab -l | grep "$SCRIPT start" | head -1`
    CRON_STOP_ENTRY=`crontab -l | grep "$SCRIPT stop" | head -1`

    if [ -n "$D_PID" ]; then
        D_RUNNING="The driver is running on port $D_PORT"
    else
        D_RUNNING="The driver is not running"
    fi
    if [ -n "$A_PID" ]; then
        A_RUNNING="The address server is running on port $A_PORT"
    else
        A_RUNNING="The address server is not running"
    fi
}

function start_up() {
    get_status
    if [ -z "$ADDR" ]; then
        echo "Launching address server..."
        $M_DIR/addr_server $A_PORT >/dev/null 2>&1 &
        sleep 1
    fi
    if [ -z "$DRIVER" ]; then
        echo "Launching driver..."
        $M_DIR/driver $M_CFG >/dev/null 2>&1 &
        sleep 1
    fi
}

function shut_down() {
    get_status
    if [ ! -z "$D_PID" ]; then
        echo "Halting driver... $D_PID"
        kill "$D_PID"
        sleep 1
    fi
    if [ ! -z "$A_PID" ]; then
        echo "Halting address server... $A_PID"
        kill "$A_PID"
        sleep 1
    fi
}

function display_usage() {
    echo "Usage: $SCRIPT [start|stop|status|schedule|unschedule]"
}

function display_help() {
    echo ""
    echo "This is a quick and dirty tool to let you start and stop"
    echo "an LPMUD running under the FluffOS game driver."
    echo ""
    display_usage
    echo ""
    echo "    help          - This detailed man page."
    echo "    start         - Starts the address server and game driver."
    echo "    stop          - Tries to halt the address server and game driver."
    echo "    status        - Displays process information about both."
    echo "    schedule      - Creates a cron entry to start or stop the mud."
    echo ""
    echo "                    Format:   [start|stop] <hour> <minute>"
    echo "                              The hour and minute argument sare both"
    echo "                              required, and should either be numbers"
    echo "                              with hour [0-23] and minute [0-59], or"
    echo "                              a valid crontab range may be specified."
    echo "                              Whitespace is NOT allowed."
    echo "                    Example:  bash% (set -f; mud schedule start * */15)"
    echo "                              The () are needed to not screw up file"
    echo "                              globbing in your main shell"
    echo ""
    echo "    unschedule    - Removes all cron entries."
    echo ""
}

function display_status() {
    get_status
    echo ""
    if [ -n "$D_PID" -o -n "$A_PID" ]; then
        echo "$HEADER"
        echo "$DRIVER"
        echo "$ADDR"
        echo ""
    fi
    echo "$D_RUNNING"
    echo "$A_RUNNING"
    if [ -n "$CRON_START_ENTRY" -a -n "$CRON_STOP_ENTRY" ]; then
        echo "Schedule:"
        echo "$CRON_HEADER"
        echo "$CRON_START_ENTRY"
        echo "$CRON_STOP_ENTRY"
    elif [ -n "$CRON_START_ENTRY" ]; then
        echo "Schedule:"
        echo "$CRON_HEADER"
        echo "$CRON_START_ENTRY"
        echo "No crontab halt schedule exists"
    elif [ -n "$CRON_STOP_ENTRY" ]; then
        echo "No crontab startup schedule exists"
        echo "Schedule:"
        echo "$CRON_HEADER"
        echo "$CRON_STOP_ENTRY"
    else
        echo "No crontab startup schedule exists"
        echo "No crontab halt schedule exists"
    fi
    echo ""
}

function is_numeric() {
    if [ -n "$1" ]; then
        [[ $1 =~ ^[0-9]+$ ]] && { return 0; } || { return 1; }
    fi
    return 1;
}

function is_crontab_format_numeric() {
    if [ -n "$1" ]; then
        if is_numeric "$1"; then
            # plain old numbers are fine
            return 0;
        elif [[ $1 =~ ^[0-9]+(,[0-9]+)*$ ]]; then
            # cron accepts numbers with commas as lists
            return 0;
        elif [[ $1 =~ ^\*(/[0-9]+)?$ ]]; then
            # cron accepts */N for divisible numbers
            # and just * for every
            return 0;
        fi
    fi
    return 1;
}

function is_crontab_hour() {
    if [ -n "$1" ]; then
        if is_numeric "$1"; then
            if [ $1 -ge 0 -a $1 -le 23 ]; then
                return 0;
            else
                return 1;
            fi
        elif is_crontab_format_numeric "$1"; then
            # We can't easily check this, but the format is OK
            return 0;
        fi
    fi
    return 1;
}

function is_crontab_minute() {
    if [ -n "$1" ]; then
        if is_numeric "$1"; then
            if [ $1 -ge 0 -a $1 -le 59 ]; then
                return 0;
            else
                return 1;
            fi
        elif is_crontab_format_numeric "$1"; then
            # We can't easily check this, but the format is OK
            return 0;
        fi
    fi
    return 1;
}

function unschedule() {
    crontab -l | grep -v "$SCRIPT start" | grep -v "$SCRIPT stop" | crontab -
}

function schedule_raw() {
    SUBCMD="$1"
    HOUR="$2"
    MIN="$3"

    get_status
    if [ "$SUBCMD" == "start" ]; then
        SAVE_START=""
        SAVE_STOP="$CRON_STOP_ENTRY"
    else
        SAVE_START="$CRON_START_ENTRY"
        SAVE_STOP=""
    fi
    unschedule
    NEW_ENTRY="$MIN $HOUR * * * $SCRIPT $SUBCMD >/dev/null 2>&1"
    if [ -n "$SAVE_START" ] ; then
        crontab -l | sed "\$ a $SAVE_START" | sed "\$ a $NEW_ENTRY" | crontab -
    elif [ -n "$SAVE_STOP" ]; then
        crontab -l | sed "\$ a $SAVE_STOP" | sed "\$ a $NEW_ENTRY" | crontab -
    else
        crontab -l | sed "\$ a $NEW_ENTRY" | crontab -
    fi
}

function schedule() {
    if [ $# -eq 3 ]; then
        # <start|stop> <hour> <minute>
        SUBCMD="$1"
        HOUR="$2"
        MIN="$3"
        if [ "$SUBCMD" == "start" -o "$SUBCMD" == "stop" ]; then
            if [ -n "$HOUR" -a -n "$MIN" ] && is_crontab_hour "$HOUR" && is_crontab_minute "$MIN"; then
                schedule_raw "$SUBCMD" "$HOUR" "$MIN"
            else
                echo "Time must be a valid hour and minute, or follow crontab format"
                display_help
                exit 1
            fi
        else
            echo "Command must be \"start\" or \"stop\""
            display_help
            exit 1
        fi
    else
        echo "Invalid arguments for schedule (expected 3, got $#)"
        echo "Arguments: $*"
        display_help
        exit 1
    fi
}

if [ -z "$CMD" ]; then
    # No arguments, assume you want status info
    display_status
    exit 0
elif [ "$CMD" == "start" -o "$CMD" == "--start" ]; then
    start_up
elif [ "$CMD" == "stop" -o "$CMD" == "--stop" ]; then
    shut_down
elif [ "$CMD" == "schedule" -o "$CMD" == "--schedule" ]; then
    shift
    set -f
    schedule $*
elif [ "$CMD" == "unschedule" -o "$CMD" == "--unschedule" ]; then
    unschedule
elif [ "$CMD" == "help" -o "$CMD" == "-h" -o "$CMD" == "--help" ]; then
    display_help
    exit 1
elif [ "$CMD" != "status" -a "$CMD" != "--status" ]; then
    # This is the catch-all for "I have no idea what arguments are valid!"
    display_usage
    exit 1
fi

# We usually want to see the results of whatever we did
display_status
exit 0