#!/bin/sh
## ==========================================================================
#   Licensed under BSD 2clause license See LICENSE file for more information
#   Author: Michał Łyszczek <michal.lyszczek@bofc.pl>
## ==========================================================================

### BEGIN INIT INFO
# Provides:
# Required-Start: $remote_fs $local_fs $network
# Required-Stop: $remote_fs $local_fs
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 6
# Short-Description: start and stop termsend daemon
# Description: share files or program output from command line using the most
#   basic UNIX tools
### END INIT INFO

###
# some systems like solaris has alias on stop, remove those aliases so our
# init script can work as expected
#

unalias stop  > /dev/null 2>&1
unalias start > /dev/null 2>&1

## ==========================================================================
#                                                 ____ _  __
#        _____ ____   __  __ _____ _____ ___     / __/(_)/ /___   _____
#       / ___// __ \ / / / // ___// ___// _ \   / /_ / // // _ \ / ___/
#      (__  )/ /_/ // /_/ // /   / /__ /  __/  / __// // //  __/(__  )
#     /____/ \____/ \__,_//_/    \___/ \___/  /_/  /_//_/ \___//____/
#
## ==========================================================================


. /etc/termsend.conf


## ==========================================================================
#                    _                __
#      ____   _____ (_)_   __ ____ _ / /_ ___     _   __ ____ _ _____ _____
#     / __ \ / ___// /| | / // __ `// __// _ \   | | / // __ `// ___// ___/
#    / /_/ // /   / / | |/ // /_/ // /_ /  __/   | |/ // /_/ // /   (__  )
#   / .___//_/   /_/  |___/ \__,_/ \__/ \___/    |___/ \__,_//_/   /____/
#  /_/
## ==========================================================================


LOG_LEVEL=${LOG_LEVEL:="6"}
COLORFUL_OUTPUT=${COLORFUL_OUTPUT:="0"}
LISTEN_PORT=${LISTEN_PORT:="1337"}
TIMED_LISTEN_PORT=${TIMED_LISTEN_PORT:="1338"}
SSL_LISTEN_PORT=${SSL_LISTEN_PORT:="0"}
TIMED_SSL_LISTEN_PORT=${TIMED_SSL_LISTEN_PORT:="0"}
CERT_FILE=${CERT_FILE:="/etc/termsend/termsend.cert"}
KEY_FILE=${KEY_FILE:="/etc/termsend/termsend.key"}
PEM_PASS_FILE=${PEM_PASS_FILE:=""}
MAX_SIZE=${MAX_SIZE:="1048576"}
MAX_TIMEOUT=${MAX_TIMEOUT:="60"}
TIMED_MAX_TIMEOUT=${TIMED_MAX_TIMEOUT:="3"}
MAX_CONNECTIONS=${MAX_CONNECTIONS:="10"}
DOMAIN=${DOMAIN:="http://termsend.bofc.pl"}
USER=${USER:="termsend"}
GROUP=${GROUP:="termsend"}
PID_FILE=${PID_FILE:="/var/run/termsend.pid"}
QUERY_LOG=${QUERY_LOG:="/var/log/termsend-query.log"}
PROGRAM_LOG=${PROGRAM_LOG:="/var/log/termsend.log"}
LIST_FILE=${LIST_FILE:="/etc/termsend-iplist"}
LIST_TYPE=${LIST_TYPE:="0"}
OUTPUT_DIR=${OUTPUT_DIR:="/var/lib/termsend"}
BIND_IP=${BIND_IP:="0.0.0.0"}
UMASK=${UMASK:="022"}

command=/usr/bin/termsend
colors=
ssl_listen_port=
timed_ssl_listen_port=
ssl_opts=
umask ${UMASK}


## ==========================================================================
#                         __     __ _          ____
#          ____   __  __ / /_   / /(_)_____   / __/__  __ ____   _____
#         / __ \ / / / // __ \ / // // ___/  / /_ / / / // __ \ / ___/
#        / /_/ // /_/ // /_/ // // // /__   / __// /_/ // / / /(__  )
#       / .___/ \__,_//_.___//_//_/ \___/  /_/   \__,_//_/ /_//____/
#      /_/
## ==========================================================================


## ==========================================================================
#   pre start function, that performs some sanity check of the system before
#   server can be started
## ==========================================================================


start_pre()
{
    echo -n "Checking configuration for termsend server... "

    # if any of the ssl ports are enabled, then pass key and cert
    # file to termsend
    if [ ${SSL_LISTEN_PORT} -ne 0 ] ; then
        ssl_listen_port="--ssl-listen-port=${SSL_LISTEN_PORT}"
        ssl_opts="--key-file=${KEY_FILE} --cert-file=${CERT_FILE}"
    fi

    if [ ${TIMED_SSL_LISTEN_PORT} -ne 0 ] ; then
        timed_ssl_listen_port="--timed-ssl-listen-port=${TIMED_SSL_LISTEN_PORT}"
        ssl_opts="--key-file=${KEY_FILE} --cert-file=${CERT_FILE}"
    fi

    if [ "x${PEM_PASS_FILE}" != "x" ] ; then
        ssl_opts+=" --pem-pass-file=${PEM_PASS_FILE}"
    fi

    if [ "${COLORFUL_OUTPUT}" -eq "1" ] ; then
        colors="-c"
    fi

    # chcek if output directory exists
    if [ ! -d "${OUTPUT_DIR}" ] ; then
        echo "error"
        echo "Output directory \"${OUTPUT_DIR}\" doesn\'t exist"
        echo "You need to create it first before you can start server"
        echo "failed to start termsend server"
        exit 1
    fi

    if [ $(id -u) -eq 0 ]; then
        # these checks are valid only when run from root

        # check if ${USER} and ${GROUP} exist in the system
        if ! /usr/bin/id -u ${USER} > /dev/null 2>&1 ; then
            echo "error"
            echo "User ${USER} doesn't exist in current system"
            echo "failed to start termsend server"
            exit 1
        fi

        if ! /usr/bin/id -g ${GROUP} > /dev/null 2>&1 ; then
            echo "error"
            echo "Group ${GROUP} doesn't exist in current system"
            echo "failed to start termsend server"
            exit 1
        fi

        # is directory writeable by selected user?
        if /bin/su ${USER} -c "if [ -w "${OUTPUT_DIR}" ]; then exit 1; fi"; then
            echo "error"
            echo "Output directory \"${OUTPUT_DIR}\" is not writeable"
            echo "for user ${USER}"
            echo "failed to start termsend server"
            exit 1
        fi

        # create log files if they don't exist and set proper permissions
        if [ ! -f "${QUERY_LOG}" ] ; then
            /bin/touch "${QUERY_LOG}"
            /bin/chown ${USER} "${QUERY_LOG}"
            /bin/chgrp adm "${QUERY_LOG}"
            /bin/chmod 640 "${QUERY_LOG}"
        fi

        if [ ! -f "${PROGRAM_LOG}" ] ; then
            /bin/touch "${PROGRAM_LOG}"
            /bin/chown ${USER} "${PROGRAM_LOG}"
            /bin/chgrp adm "${PROGRAM_LOG}"
            /bin/chmod 640 "${PROGRAM_LOG}"
        fi
    else
        # is directory writeable by current user?
        if [ ! -w "${OUTPUT_DIR}" ]; then
            echo "error"
            echo "Output directory \"${OUTPUT_DIR}\" is not writeable"
            echo "for user $(whoami)"
            echo "failed to start termsend server"
            exit 1
        fi
    fi

    echo "ok"
}


## ==========================================================================
#   starts server as daemon
## ==========================================================================


start() {
    echo -n "Starting termsend server... "
    if [ "${COLORFUL_OUTPUT}" -eq "1" ] ; then
        colors="-c"
    fi

    ${command} -l${LOG_LEVEL} ${colors} -i${LISTEN_PORT} -s${MAX_SIZE} \
        -t${MAX_TIMEOUT} -m${MAX_CONNECTIONS} -d"${DOMAIN}" -q"${QUERY_LOG}" \
        -p"${PROGRAM_LOG}" -o"${OUTPUT_DIR}" -T"${LIST_TYPE}" -L"${LIST_FILE}" \
        -b${BIND_IP} -D -P"${PID_FILE}" -u${USER} -g${GROUP} \
        -M${TIMED_MAX_TIMEOUT} \
        ${ssl_listen_port} ${timed_ssl_listen_port} ${ssl_opts}

    if [ "$?" -ne "0" ] ; then
        echo "error"
        echo "Failed to start program, please check ${PROGRAM_LOG}" \
            "to see more information about what went wrong"
        exit 1
    fi

    echo "ok"
}


## ==========================================================================
#   stops the server but lets it finish any job it currently performs.  If
#   stop gets called twice, server will abandon any job and will exit asap
## ==========================================================================


stop() {
    echo -n "Stopping termsend server... "
    if /bin/kill -15 $(cat "${PID_FILE}") > /dev/null 2>&1; then
        echo "ok"
        return 0
    fi

    echo "already stopped"
}


## ==========================================================================
#                                __                __
#                         _____ / /_ ____ _ _____ / /_
#                        / ___// __// __ `// ___// __/
#                       (__  )/ /_ / /_/ // /   / /_
#                      /____/ \__/ \__,_//_/    \__/
#
## ==========================================================================


case "$1" in
    start)
        start_pre
        start
        ;;

    stop)
        stop
        ;;

    restart|force-reload)
        stop
        start_pre
        start
        ;;

    status)
        if [ ! -f "${PID_FILE}" ] ; then
            # file doesn't exist, server wasn't started yet, or it was closed
            # and server removed pid file
            echo "server is not running"
            exit 3
        fi

        if [ $(wc -c < "${PID_FILE}") -eq 0 ] ; then
            # file exists but its size is 0, meaning server started and ended
            # but couldn't remove pid, so it truncated it to 0 bytes size
            echo "server is not running"
            exit 3
        fi

        if /bin/ps -p $(cat "${PID_FILE}") > /dev/null 2>&1 ; then
            # process exists and is alive
            echo "server is running"
            exit 0
        fi

        # information about pid exists in pid file, but process is not running
        # that means server exited in non-clean way and didn't clean pid file
        echo "server crashed"
        exit 1
        ;;
    *)
        echo -e "usage: $0 {start|stop|status|restart}"
        echo -e ""
        echo -e "exit codes"
        echo -e "\tstart"
        echo -e "\t\t0\tstarted with success"
        echo -e "\t\t1\terror starting server"
        echo -e ""
        echo -e "\tstop"
        echo -e "\t\t0\tserver stopped with success"
        echo -e "\t\t1\tcouldn't stop server (already stopped or crashed)"
        echo -e ""
        echo -e "\tstatus"
        echo -e "\t\t0\tserver is running"
        echo -e "\t\t1\tserver crashed"
        echo -e "\t\t3\tserver is not running"
        echo -e ""
        echo -e "\trestart"
        echo -e "\t\t0\tserver restarted"
        echo -e "\t\t1\terror restarting server"
esac
