#!/bin/sh
#
# USAGE: install_services [OPTIONS]
# 
# OPTIONS:
#    -h|--help            Show this help text
#    -r|--remove          Removes the trip services from automatic launch
#    -y|--yes             Answer yes to all questions asked by the script
#    -d|--tripd           Install tripd
#    -n|--tripnet         Install tripnetd or tbserver as appropriate
#    -u|--user USERNAME   The name of the OS user to launch the software as
#    -g|--group GROUPNAME The name of the OS group to launch the software as
#    -l|--log LOGFILE     Emit output to specified log file too
# 
# This script installs or uninstalls the TRIP daemons and network services
# for automatic start during operating system boot-up.
# 
# If neither the -d nor -n options are given, both tripnet/tbserver and
# tripd are installed (or removed) using the OS mechanisms supported by the
# current machine. If -d or -n are given, only that service is installed or
# removed.
# 
# The software is by default set up to be launched as the user that owns the
# tripd binary. If this is not desired, specify a different user with the -u
# option. Note that this user must have execution rights to the TRIP binaries
# and full write access to all TRIP database files.
# 

AUTO_CONFIRM=0
INSTALL_MODE=1
OPNAME=install
OSNAME=`uname | tr [:upper:] [:lower:]`

USERNAME=tripsystem
GROUPNAME=tripusers
LOGFILE=

INSTALL_TRIPD=0
INSTALL_TRIPNET=0

usage()
{
   head -27 $0 | tail -26 | cut -c3-
}

while [ "$1" != "" ]; do
   case $1 in
      -h|--help)
         usage
         exit 0
         ;;
      -r|--remove)
         INSTALL_MODE=0
         OPNAME=uninstall
         ;;
      -y|--yes)
         AUTO_CONFIRM=1
         ;;
      -d|--tripd)
         INSTALL_TRIPD=1
         ;;
      -n|--tripnet|--tripnetd)
         INSTALL_TRIPNET=1
         ;;
      -u|--user)
         shift
         USERNAME=$1
         ;;
      -g|--group)
         shift
         GROUPNAME=$1
         ;;
      -l|--log)
         shift
         LOGFILE=$1
         ;;
      *)
        ;;
   esac
   shift
done

if [ $INSTALL_TRIPD -eq 0 ] && [ $INSTALL_TRIPNET -eq 0 ]; then
   INSTALL_TRIPD=1
   INSTALL_TRIPNET=1
fi

logit()
{
   while read line; do
      if [ "$LOGFILE" != "" ]; then
        echo $line >> $LOGFILE
      fi
      echo $line
   done
}

if [ "`id -u`" -ne "0" ]; then
   echo "ERROR: This script must be run as root" | logit
   echo "" | logit
   exit 2
fi

if [ -e /.dockerenv ]; then
   echo "ERROR: The install_services script cannot be used in a Docker container." | logit
   echo "" | logit
   exit 2
fi

if [ -e /usr/local/trip/sys/lib ]; then
   TDBS_HOME=$(dirname `readlink /usr/local/trip/sys/lib 2>/dev/null` 2> /dev/null)
   TDBS_EXE=$TDBS_HOME/bin
   TDBS_SBIN=$TDBS_HOME/sbin
fi

if [ "$TDBS_HOME" = "" ] || [ ! -d "$TDBS_HOME" ]; then
   echo "ERROR: TRIPsystem is not properly installed." | logit
   echo "" | logit
   exit 1
fi

if [ ! -f "$TDBS_SBIN/tripctl" ]; then
   echo "ERROR: The tripctl program not found in the TRIPsystem sbin directory" | logit
   echo "" | logit
   exit 1
fi

if [ $INSTALL_MODE -eq 1 ]; then
   grep -q ^$USERNAME: /etc/passwd
   if [ $? -ne 0 ]; then
      echo "ERROR: Invalid user name '$USERNAME'" | logit
      echo "Please specify a valid user name using the -u argument" | logit
      echo "" | logit
      exit 1
   fi

   grep -q ^$GROUPNAME: /etc/group
   if [ $? -ne 0 ]; then
      echo "ERROR: Invalid group name '$GROUPNAME'" | logit
      echo "Please specify a valid group name using the -g argument" | logit
      echo "" | logit
      exit 1
   fi
fi

# Are we using SysV init or systemd?
#
HAS_SYSVINIT=0
HAS_SYSTEMD=0


# Check what method to use to install the services
if [ "$OSNAME" = "linux" ]; then
   INITPROC=`ps --no-headers -o comm 1 2>/dev/null`
   if [ "$INITPROC" = "init" ]; then
      HAS_SYSVINIT=1
   elif [ "$INITPROC" = "systemd" ]; then
      HAS_SYSTEMD=1
   fi
else
   echo "ERROR: Unsupported operating system '$OSNAME'" | logit
   exit 1
fi

if [ $HAS_SYSVINIT -eq 1 ]; then
   # Verify that the expected directories for SysV init actually exists.
   if [ ! -d /etc/init.d ] || [ ! -d /etc/rc3.d ] || [ ! -d /etc/rc0.d ]; then
      HAS_SYSVINIT=0
   fi
fi


if [ $HAS_SYSTEMD -eq 0 ] && [ $HAS_SYSVINIT -eq 0 ]; then
   echo "Neither systemd NOR SysV init is available on this system." | logit
   echo "Unable to $OPNAME the TRIP services." | logit
   exit 1
fi


if [ "$OSNAME" = "linux" ]; then
   if [ $HAS_SYSTEMD -eq 1 ]; then
      if [ $INSTALL_MODE -eq 1 ]; then
         echo "Configuring TRIP services to be managed by systemd" | logit
      fi
   elif [ $HAS_SYSVINIT -eq 1 ]; then
      which start-stop-daemon > /dev/null 2>&1
      if [ $? -eq 0 ]; then
         if [ $INSTALL_MODE -eq 1 ]; then
            echo "Configuring TRIP services to be launched by SysV init" | logit
         fi
      else
         if [ $INSTALL_MODE -eq 1 ]; then
            echo "WARNING: Could not find the prerequisite start-stop-daemon utility program" | logit
            echo "WARNING: Cannot install $OPNAME for SysV init launch" | logit
         fi
         HAS_SYSVINIT=0
      fi
   fi
fi

INSTALL_ERRORS=0

#############################################################################
# Configure TRIP for a systemd system
#############################################################################

if [ $HAS_SYSTEMD -eq 1 ] && [ $INSTALL_MODE -eq 1 ]; then

   if [ $INSTALL_TRIPD -eq 1 ]; then
      systemctl list-unit-files --type=service|grep -q tripd
      if [ $? -eq 0 ]; then
         echo "The tripd service is already installed. No action taken." | logit
         INSTALL_TRIPD=0
      fi
   fi
   if [ $INSTALL_TRIPD -eq 1 ]; then
      systemctl stop tripd > /dev/null 2>&1
      cat $TDBS_HOME/share/systemd/tripd.service | \
      sed "s/^User=.*$/User=$USERNAME/g" | \
      sed "s/^Group=.*$/Group=$GROUPNAME/g" | \
      sed "s,^ExecStart=.*$,ExecStart=$TDBS_SBIN/tripctl start tripd,g" | \
      sed "s,^ExecStop=.*$,ExecStop=$TDBS_SBIN/tripctl stop tripd,g" > \
      /etc/systemd/system/tripd.service

      systemctl enable tripd --now
      if [ $? -ne 0 ]; then
         echo "ERROR: Failed to start the tripd service" | logit
         INSTALL_ERRORS=`expr $INSTALL_ERRORS + 1`
      else
         echo "" | logit
         echo "Service tripd successfully installed and started." | logit
         echo "Use the systemctl command to start, stop, enable and disable tripd." | logit
      fi
   fi

   if [ $INSTALL_TRIPNET -eq 1 ]; then
      systemctl list-unit-files --type=service|grep -q tripnetd
      if [ $? -eq 0 ]; then
         echo "The tripnetd service is already installed. No action taken." | logit
         INSTALL_TRIPNET=0
      fi
   fi
   if [ $INSTALL_TRIPNET -eq 1 ]; then
      systemctl stop tripnetd > /dev/null 2>&1
      cat $TDBS_HOME/share/systemd/tripnetd.service | \
         sed "s/^User=tripsystem/User=$USERNAME/g" | \
         sed "s/^Group=tripusers/Group=$GROUPNAME/g" | \
         sed "s,^ExecStart=.*$,ExecStart=$TDBS_SBIN/tripctl start tripnetd,g" | \
         sed "s,^ExecStop=.*$,ExecStop=$TDBS_SBIN/tripctl stop tripnetd,g" > \
         /etc/systemd/system/tripnetd.service

      systemctl enable tripnetd --now
      if [ $? -ne 0 ]; then
         echo "ERROR: Failed to start the tripnetd service" | logit
         INSTALL_ERRORS=`expr $INSTALL_ERRORS + 1`
      else
         echo "" | logit
         echo "Service tripnetd successfully installed and started." | logit
         echo "Use the systemctl command to start, stop, enable and disable tripnetd." | logit
      fi
   fi

elif [ $HAS_SYSTEMD -eq 1 ] && [ $INSTALL_MODE -eq 0 ]; then

   SYSD_RELOAD_REQUIRED=0

   if [ $INSTALL_TRIPD -eq 1 ]; then
      systemctl list-unit-files --type=service|grep -q tripd
      if [ $? -eq 0 ]; then
         echo "Removing systemd service for TRIP Daemon" | logit
         systemctl stop tripd > /dev/null 2>&1
         systemctl disable tripd > /dev/null 2>&1
         SYSD_RELOAD_REQUIRED=1
      else
         echo "The tripd service is not installed. No action taken." | logit
      fi
      if [ -e /etc/systemd/system/tripd.service ]; then
         rm -f /etc/systemd/system/tripd.service
         if [ $? -eq 0 ] && [ $SYSD_RELOAD_REQUIRED -eq 1 ]; then
            echo "Service tripd successfully removed." | logit
         fi
      fi
      echo "" | logit
   fi

   if [ $INSTALL_TRIPNET -eq 1 ]; then
      systemctl list-unit-files --type=service|grep -q tripnetd
      if [ $? -eq 0 ]; then
         echo "Removing systemd service for TRIPnet Daemon" | logit
         systemctl stop tripnetd > /dev/null 2>&1
         systemctl disable tripnetd > /dev/null 2>&1
         SYSD_RELOAD_REQUIRED=1
      else
         echo "The tripnetd service is not installed. No action taken." | logit
      fi
      if [ -e /etc/systemd/system/tripnetd.service ]; then
         rm -f /etc/systemd/system/tripnetd.service
         if [ $? -eq 0 ] && [ $SYSD_RELOAD_REQUIRED -eq 1 ]; then
            echo "Service tripnetd successfully removed." | logit
         fi
      fi
   fi

   if [ $SYSD_RELOAD_REQUIRED -eq 1 ]; then
      systemctl daemon-reload
      systemctl reset-failed
   fi


#############################################################################
# Configure TRIP for a SysV init system
#############################################################################

elif [ $HAS_SYSVINIT -eq 1 ] && [ $INSTALL_MODE -eq 1 ]; then

   echo "Installing SysV init scripts for TRIP" | logit

   if [ "$OSNAME" = "sunos" ]; then
      INITOWNER=root:sys
   else
      INITOWNER=root:root
   fi

   if [ $INSTALL_TRIPD -eq 1 ]; then
      # TODO: There is a delay between shutdown request and full stop
      service stop tripd > /dev/null 2>&1

      cat $TDBS_HOME/share/init/tripd | \
      sed 's/^DAEMON_USER=.*$/\${DAEMON_USER:-$(USERNAME)}/g' |
      sed 's/^DAEMON_GROUP=.*$/\${DAEMON_USER:-$(GROUPNAME)}/g' > \
      /etc/init.d/tripd
      chmod 744 /etc/init.d/tripd
      chown $INITOWNER /etc/init.d/tripd
      ln -s /etc/init.d/tripd /etc/rc3.d/S80tripd
      ln -s /etc/init.d/tripd /etc/rc0.d/K01tripd
   fi

   if [ $INSTALL_TRIPNET -eq 1 ]; then
      # TODO: There is a delay between shutdown request and full stop
      service stop tripnetd > /dev/null 2>&1

      cat $TDBS_HOME/share/init/tripnetd | \
      sed 's/^DAEMON_USER=.*$/\${DAEMON_USER:-$(USERNAME)}/g' |
      sed 's/^DAEMON_GROUP=.*$/\${DAEMON_USER:-$(GROUPNAME)}/g' > \
      /etc/init.d/tripd
      chmod 744 /etc/init.d/tripnetd
      chown $INITOWNER /etc/init.d/tripnetd
      ln -s /etc/init.d/tripnetd /etc/rc3.d/S81tripnetd
      ln -s /etc/init.d/tripnetd /etc/rc0.d/K01tripnetd
   fi

   if [ $INSTALL_TRIPD -eq 1 ]; then
      service start tripd
      if [ $? -ne 0 ]; then
         INSTALL_ERRORS=`expr $INSTALL_ERRORS + 1`
         echo "Error starting tripd service" | logit
      fi
   fi

   if [ $INSTALL_TRIPNET -eq 1 ]; then
      service start tripnetd
      if [ $? -ne 0 ]; then
         INSTALL_ERRORS=`expr $INSTALL_ERRORS + 1`
         echo "Error starting tripnetd service" | logit
      fi
   fi

elif [ $HAS_SYSVINIT -eq 1 ] && [ $INSTALL_MODE -eq 0 ]; then

   if [ $INSTALL_TRIPD -eq 1 ]; then
      service tripd status > /dev/null 2>&1
      if [ $? -eq 0 ]; then
         echo "Removing SysV init scripts for TRIP Daemon" | logit
         service stop tripd > /dev/null 2>&1
      fi

      if [ -e /etc/init/tripd ]; then rm -f /etc/init.d/tripd; fi
      if [ -e /etc/rc3.d/tripd ]; then rm -f /etc/rc3.d/tripd; fi
      if [ -e /etc/rc0.d/tripd ]; then rm -f /etc/rc0.d/tripd; fi

   fi

   if [ $INSTALL_TRIPNET -eq 1 ]; then
      service tripnetd status > /dev/null 2>&1
      if [ $? -eq 0 ]; then
         echo "Removing SysV init scripts for TRIPnet (tripnetd)" | logit
         service stop tripnetd > /dev/null 2>&1
      fi

      if [ -e /etc/init.d/tripnetd ]; then rm -f /etc/init.d/tripnetd; fi
      if [ -e /etc/rc3.d/tripnetd ]; then rm -f /etc/rc3.d/tripnetd; fi
      if [ -e /etc/rc0.d/tripnetd ]; then rm -f /etc/rc0.d/tripnetd; fi
   fi

fi

echo "" | logit

exit $INSTALL_ERRORS
