#!/bin/sh
#
# $Id$
#
# Copyright (c) 2010 Werner Jaeger <werner_jaeger@web.de>
#
# This is free software; you may redistribute it and/or modify
# it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2,
# or (at your option) any later version.
#
# This 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 with
# the Debian operating system, in /usr/share/common-licenses/GPL;  if
# not, write to the Free Software Foundation, Inc., 51 Franklin Street, 
# Fifth Floor, Boston, MA 02110-1301, USA
#
### BEGIN INIT INFO
# Provides:          l2tp-ipsec-vpn-daemon
# Required-Start:    $local_fs $remote_fs $network $syslog
# Required-Stop:     $local_fs $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Daemon used to start/stop L2TP over IPsec VPN connections by non privileged users
# Description:       Daemon used to start/stop L2TP over IPsec VPN connections by non privileged users
### END INIT INFO

# Fedora:
#  When this file is installed as /etc/rc.d/init.d/l2tp-ipsec-vpn-daemon
#  and added to the chkconfig system with `chkconfig --add l2tp-ipsec-vpn-daemon`
#  then the default values of these variables can be overridden
#  in the /etc/sysconfig/l2tp-ipsec-vpn-daemon file
# Ubuntu:
#  Values read from /etc/default/l2tp-ipsec-vpn-daemon

PACKAGE_NAME="L2TP Control Daemon"
UNAME_S=$(uname -s)

# Ubuntu: Do NOT "set -e"
#         PATH should only include /usr/* if it runs after the mountnfs.sh
PATH=/usr/sbin:/usr/bin:/sbin:/bin
DESC="start/stop L2TP Control Daemon"
NAME=L2tpIPsecVpnControlDaemon
SNAME=l2tp-ipsec-vpn-daemon
DAEMON=/usr/lib/l2tp-ipsec-vpn-daemon/$NAME
PIDFILE=/var/run/$NAME.pid
LOCKFILE=${LOCKFILE-/var/lock/subsys/$NAME}

if [ -e /etc/SuSE-release ]; then
  DISTRIB_ID="suse"
elif [ -e /etc/fedora-release ]; then
  DISTRIB_ID="fedora"
elif [ -e /etc/redhat-release ]; then
  DISTRIB_ID="redhat" # also exists on Fedora
elif [ -e /etc/lsb-release ]; then
  ## TODO: here is a trap for other distributions
  ##       should use /usr/bin/lsb_release -i -s
  DISTRIB_ID="ubuntu"
elif [ -e /etc/debian_version ]; then
  DISTRIB_ID="debian" # also exists on Ubuntu
elif [ -e /etc/slackware-version ]; then
  DISTRIB_ID="slackware"
elif [ "$UNAME_S" = "Darwin" ]; then
  DISTRIB_ID="Darwin"
elif [ "$UNAME_S" = "FreeBSD" ]; then
  DISTRIB_ID="FreeBSD"
else
  echo "This script needs to be ported to this OS"
  exit 1
fi

if [ -d /etc/rc.d/init.d ]; then
  # Fedora & Redhat
  SCRIPTNAME=/etc/rc.d/init.d/$SNAME
  test -f /etc/rc.d/init.d/functions && . /etc/rc.d/init.d/functions
  test -r /etc/sysconfig/$SNAME && . /etc/sysconfig/$SNAME
elif [ -d /etc/init.d ]; then
  # Ubuntu & Debian
  SCRIPTNAME=/etc/init.d/$SNAME
  test -r /etc/default/$SNAME && . /etc/default/$SNAME
  test -f /etc/default/rcS && . /etc/default/rcS
  # Ubuntu: Define LSB log_* functions.
  #         Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
  test -f /lib/lsb/init-functions && . /lib/lsb/init-functions
elif [ "$DISTRIB_ID" = "Darwin" ]; then
  # Darwin
  SCRIPTNAME=$0
elif [ "$DISTRIB_ID" = "FreeBSD" ]; then
  SCRIPTNAME=$0 # FreeBSD 
else
  echo "This script needs to be ported to this OS"
  exit 1
fi

# Exit if the package can not be found
if [ ! -x "$DAEMON" ]; then
  echo "Error: Can not find $DAEMON"
  exit 0
fi

# Edit /etc/default/l2tp-ipsec-vpn-daemon and set RUN_CONTROL_DAEMON=no to 
# prevent it from being started at boot time.
if [ "$RUN_CONTROL_DAEMON" = no ]; then
  exit 0
fi

#
# Fedora:
#  launches $* in the background
forkdaemon()
{
  daemon $*
  RETVAL=$?
  if [ $RETVAL -eq 0 ]; then
    touch $LOCKFILE
    success
    return 0
  fi

  failure
  return 1
}


#
# Ubuntu: Function that starts the daemon/service
#
do_start()
{
  # Return
  #   0 if daemon has been started
  #   1 if daemon was already running
  #   2 if daemon could not be started
  start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null || return 1
  start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS || return 2

  # Add code here, if necessary, that waits for the process to be ready
  # to handle requests from services started subsequently which depend
  # on this one.  As a last resort, sleep for some time.
  sleep 1
  test -f "$PIDFILE" || return 2
}

#
# Ubuntu: Function that stops the daemon/service
#
do_stop()
{
  # Return
  #   0 if daemon has been stopped
  #   1 if daemon was already stopped
  #   2 if daemon could not be stopped
  #   other if a failure occurred
  start-stop-daemon --stop --quiet --retry=QUIT/30/KILL/5 --pidfile $PIDFILE --exec $DAEMON

  RETVAL="$?"
  test "$RETVAL" != 0 && return "$RETVAL"
  # Wait for children to finish too if this is a daemon that forks
  # and if the daemon is only ever run from this initscript.
  # If the above conditions are not satisfied then add some other code
  # that waits for the process to drop all resources that could be
  # needed by services started subsequently.  A last resort is to
  # sleep for some time.
  start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
  test "$?" != 0 && return "$RETVAL"
  # Many daemons don't delete their pidfiles when they exit.
  rm -f $PIDFILE
  return "$RETVAL"
}

#
# Ubuntu: Function that sends a SIGHUP to the daemon/service
#
do_reload()
{
  #
  # If the daemon can reload its configuration without
  # restarting (for example, when it is sent a SIGHUP),
  # then implement that here.
  #
  start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --exec $DAEMON
  return 0
}

# main
case "$1" in
  start)
    test -d ${L2TP_IPSEC_VPN_CONTROLD_RUN_DIR:-/var/run/$NAME} || mkdir -p ${L2TP_IPSEC_VPN_CONTROLD_RUN_DIR:-/var/run/$NAME}
    if [ "$DISTRIB_ID" = "ubuntu" -o "$DISTRIB_ID" = "debian" ] ; then
      test "x$VERBOSE" != "xno" && log_daemon_msg "Starting $DESC" "$SNAME"
      retval=0
      do_start
      test "$?" -ne 0 -a "$?" -ne 1 && retval=1
      test "x$VERBOSE" != "xno" && log_daemon_msg "$retval"
      exit "$retval"
    elif [ "$DISTRIB_ID" = "fedora" -o "$DISTRIB_ID" = "redhat" ]; then
      action "Starting ${PACKAGE_NAME}:" forkdaemon $DAEMON $DAEMON_OPTS
    elif [ "$DISTRIB_ID" = "suse" ]; then
      echo -n "Starting ${PACKAGE_NAME}"
      startproc -p $PIDFILE $DAEMON $DAEMON_OPTS
      rc_status -v
    elif [ "$DISTRIB_ID" = "Darwin" ]; then
      echo "Starting ${PACKAGE_NAME}"
      launchctl list $NAME > /dev/null 2>&1 && exit 0
      launchctl submit -l $NAME -p $DAEMON -o /dev/null -e /dev/null -- $DAEMON_OPTS
    elif [ "$DISTRIB_ID" = "FreeBSD" ]; then
      echo "Starting ${PACKAGE_NAME}"
      name="$NAME"
      command="/usr/sbin/daemon"
      command_args="$DAEMON $DAEMON_OPTS"
      pidfile="$PIDFILE"
      run_rc_command "$1"
    else
      echo "This script needs to be ported to this OS"
      exit 1
    fi
  ;;
  stop)
    if [ "$DISTRIB_ID" = "ubuntu" -o "$DISTRIB_ID" = "debian" ] ; then
      test "x$VERBOSE" != "xno" && log_daemon_msg "Stopping $DESC" "$SNAME"
      retval=0
      do_stop
      test "$?" -ne 0 -a "$?" -ne 1 && retval=1
      test "x$VERBOSE" != "xno" && log_daemon_msg "$retval"
      exit "$retval"
    elif [ "$DISTRIB_ID" = "fedora" -o "$DISTRIB_ID" = "redhat" ]; then
      action "Stopping ${NAME}:" killproc -p $PIDFILE $DAEMON
      rm -f $LOCKFILE
    elif [ "$DISTRIB_ID" = "suse" ]; then
      echo -n "Stopping ${NAME}"
      killproc -p $PIDFILE $DAEMON
      rc_status -v
    elif [ "$DISTRIB_ID" = "Darwin" ]; then
      echo "Stopping ${PACKAGE_NAME}"
      launchctl list $NAME > /dev/null 2>&1 || exit 0
      echo "Stopping ${NAME}"
      launchctl remove ${NAME}
      rm -f ${PIDFILE}
    elif [ "$DISTRIB_ID" = "FreeBSD" ]; then
      echo "Stopping ${PACKAGE_NAME}"
      if [ -e "$PIDFILE" ]; then 
	     kill $(cat $PIDFILE)
	     rm -f ${PIDFILE}
      fi
    else
      echo "This script needs to be ported to this OS"
      exit 1
    fi
  ;;
  #reload|force-reload)
  #
  # If do_reload() is not implemented then leave this commented out
  # and leave 'force-reload' as an alias for 'restart'.
  #
  #test "x$VERBOSE" != "xno" && log_daemon_msg "Reloading $DESC" "$NAME"
  #do_reload
  #log_end_msg $?
  #;;
  restart|force-reload)
    test -d ${L2TP_IPSEC_VPN_CONTROLD_RUN_DIR:-/var/run/$NAME} || mkdir -p ${L2TP_IPSEC_VPN_CONTROLD_RUN_DIR:-/var/run/$NAME}
    if [ "$DISTRIB_ID" = "ubuntu" -o "$DISTRIB_ID" = "debian" ] ; then
      #
      # If the "reload" option is implemented then remove the
      # 'force-reload' alias
      #
      test "x$VERBOSE" != "xno" && log_daemon_msg "Restarting $DESC" "$SNAME"
      do_stop
      case "$?" in
          0|1)
            do_start
            case "$?" in
              0) log_end_msg 0 ;;
              1) log_end_msg 1 ;; # Old process is still running
              *) log_end_msg 1 ;; # Failed to start
            esac
          ;;
          *)
            # Failed to stop
            log_end_msg 1
          ;;
      esac
    else
      # This is the typical process for restart
      sh $0 'stop'
      sh $0 'start'
    fi
  ;;
  status)
    if [ "$DISTRIB_ID" = "ubuntu" -o "$DISTRIB_ID" = "debian" ] ; then
      status_of_proc -p $PIDFILE $DAEMON $NAME
    elif [ "$DISTRIB_ID" = "fedora" -o "$DISTRIB_ID" = "redhat" ]; then
      status -p $PIDFILE $NAME
    elif [  "$DISTRIB_ID" = "suse" ]; then
      echo -n "Checking for service ${NAME}: "
      checkproc -p $PIDFILE $NAME
      rc_status -v
    elif [ "$DISTRIB_ID" = "Darwin" ]; then
      /bin/echo -n "${PACKAGE_NAME} is "
      launchctl list $NAME > /dev/null 2>&1
      status=$?
      [ $status -eq 0 ] || /bin/echo -n "not "
      echo "running."
    elif [ "$DISTRIB_ID" = "FreeBSD" ]; then
	   if pgrep $NAME > /dev/null ; then 
		  echo "$NAME running as pid `cat $PIDFILE`" ; else 
		  echo "$TM_NAME not running" 
	   fi
      exit $status
    else
      echo "This script needs to be ported to this OS"
      exit 1
    fi
  ;;
  condrestart)
    test -d ${L2TP_IPSEC_VPN_CONTROLD_RUN_DIR:-/var/run/$NAME} || mkdir -p ${L2TP_IPSEC_VPN_CONTROLD_RUN_DIR:-/var/run/$NAME}
    if [ "$DISTRIB_ID" = "fedora" -o "$DISTRIB_ID" = "redhat" ]; then
      if ! $0 'status'
      then
        sh $0 'stop'
        sh $0 'start'
      fi
    else
      echo "This script needs to be ported to this OS"
      exit 1
    fi
  ;;
  *)
    if [ "$DISTRIB_ID" = "ubuntu" -o "$DISTRIB_ID" = "debian" ] ; then
      echo "Usage: $SCRIPTNAME {start|stop|restart|status|force-reload}" >&2
    elif [ "$DISTRIB_ID" = "fedora" -o "$DISTRIB_ID" = "redhat" ]; then
      echo "Usage: $0 {start|stop|status|restart|condrestart}"
    elif [ "$DISTRIB_ID" = "suse" ]; then
      echo "Usage: $0 {start|stop|restart|status}"
    elif [ "$DISTRIB_ID" = "Darwin" ]; then
      echo "Usage: $0 {start|stop|restart|status}"
    elif [ "$DISTRIB_ID" = "FreeBSD" ]; then
      echo "Usage: $0 Usage: (start|stop|restart|status)"
      echo "NB: FreeBSD's ports system installs a rc script in"
      echo "/usr/local/etc/rc.d/ with native rc.subr(8) features."
    else
      echo "This script needs to be ported to this OS"
      exit 1
    fi
    exit 3
  ;;
esac


