#!/bin/sh
# Utility for managing vlinit or sysvinit services
# Originally by ????
# Modified by Eko M. Budi for Vector Linux
# GNU-GPL (c) Eko M. Budi, 2004
#         (c) Vector Linux, 2004

INIT="/etc/rc.d/init.d"
COL=70
SET_COL="echo -en \\033[${COL}G"

# determine current level
CURRENT_LEVEL=`runlevel | cut -d " " -f 2`
INITDIR=/etc/rc.d/init.d
BASIC="dnsmasq sshd"

. /etc/rc.d/functions-service

help() {
cat << EOF

Usage: 
service [service_name] [start | stop | restart | status ] 
        [ -p ] print service description
        [ -a ] [runlevel]
	[ -l ] service_name runlevel
	[ -s ] service_name [runlevels] [ start_order [ kill_order ]]
	[ -k ] service_name runlevels
	[ -i | 
	[ -b ]
	[ -h ] 
-p              print service description
-a		display active services in a runlevel
-l              list the status of a service in a runlevel
-s		add  a service for runlevels
-r              remove a service from runlevels
-i              install all services with default settings
-b              install basic services
-h		display help information
service_name 	one of /etc/rc.d/init.d/ files with exec mode (755)
runlevel	any runlevel from 2 to 5 (can be "2345")
start_order	Recomended:
                   00-09 = ...
		   10-19 = hardware (pcmcia,hotplug,...)
                   20-39 = networking (network,firewall,portmap,...)
		   30-39 = network client (netfs, cups, ...)
		   40-59 = local services (log, cron, ...)
		   60-79 = intranet servers (nfs, smb, ...)
		   80-89 = internet servers (inet, http, ...)
		   90-99 = additional services (at, gpm, ...)
kill_order      the order which service will be killed
                default = 100-start_order
EOF
}

print_service()
{
   for SNAME in /etc/rc.d/init.d/* ; do
      if [ -f $SNAME ]; then
        NAME=`basename $SNAME`
        echo "$NAME : " `service_desc $NAME`
      fi
   done
}

list_service()
{
   if [ -f /etc/rc.d/init.d/$1 ]; then
      if [ -h /etc/rc.d/rc$2.d/S??$1 ]; then
         echo "on"
      else
         echo "off"
      fi
   fi
}

display1()
{
    if [ -x /etc/rc.d/init.d/$1 ]; then
      printf "%-16s  " "$1*"
    else
      printf "%-16s  " $1
    fi
    for LEVEL in 2 3 4 5; do
       if [ -h /etc/rc.d/rc$LEVEL.d/S??$1 ]; then
          echo -n "on   "   
       else
          echo -n "-    "
       fi
    done
    echo  
}

display()
{
   if [ $1 ]; then
      if [ -f /etc/rc.d/init.d/$1 ]; then
          echo "Service  level    2    3    4    5"
          display1 $1
      else
         echo "$1 is not exist"
      fi
   else
      echo "Services level    2    3    4    5"
      for SNAME in /etc/rc.d/init.d/* ; do
	 if [ -f $SNAME ]; then
	      display1 `basename $SNAME`
	 fi      
      done
   fi
}

# Add service's symlink to a run level
# $1 = service
# $2 = run_level
# $3 = start order
# $4 = stop order
add_service1()
{
  RCDIR=/etc/rc.d/rc$2.d
  if [ ! -d $RCDIR ]; then
     echo "Invalid run_level"
     help;
     exit 1
  fi
  SNAME=/etc/rc.d/init.d/$1
  if [ ! -r $SNAME ]; then
     echo "No service named $1"
     exit 1
  fi
  if [ -x $SNAME ]; then
     if [ ! -x "$RCDIR/S*$1" ]; then
        [ $2 = "$CURRENTLEVEL" ] && $SNAME start         
     fi
  else
     chmod a+x $SNAME
     [ $2 = "$CURRENTLEVEL" ] && $SNAME start
  fi
  #echo Deleting /etc/rc.d/rc${3}.d/???${2} 
  rm -f $RCDIR/S*$1
  rm -f $RCDIR/K*$1

  #echo Registering /etc/rc.d/rc${3}.d/S${SORDER}${2} 
  (cd $RCDIR; ln -sf ../init.d/$1 S${3}${1}; ln -s ../init.d/$1 K${4}${1} )
}

# Add service's symlink to some run levels
# $1 = service
# $2 = run_levels
# $3 = start order
# $4 = stop order
add_service()
{
  rl=1
  if [ "$2" ]; then
     RUNLEVELS=$2
  else
     RUNLEVELS=`service_order $1 | cut -d " " -f 1`
  fi
  if [ "$3" ]; then
     STARTORDER=$3
  else
     STARTORDER=`service_order $1 | cut -d " " -f 2`
  fi
  if [ "$4" ]; then
     KILLORDER=$4
  else
     let KILLORDER=99-$STARTORDER
  fi
  RUNLEVEL=`echo $RUNLEVELS | cut -b $rl`
  while [ $RUNLEVEL ]; do
    add_service1 $1 $RUNLEVEL $STARTORDER $KILLORDER
    let rl=$rl+1
    RUNLEVEL=`echo $RUNLEVELS | cut -b $rl`
  done
  echo Service $1 has been activated for run level $RUNLEVELS
}

# Remove service's symlink from a run level
# $1 = service
# $2 = runlevel
del_service1()
{
  RCDIR=/etc/rc.d/rc$2.d
  if [ ! -d $RCDIR ]; then
     echo "Invalid run_level"
     help;
     exit 1       
  fi
  if [ -x "$RCDIR/S*$1" ]; then
     [ $2 = "$CURRENTLEVEL" ] && /etc/rc.d/$1 stop
  fi
  rm -f $RCDIR/S*$1
  rm -f $RCDIR/K*$1
}

del_service()
{
  rl=1
  if [ $2 ]; then
     RUNLEVELS=$2
  else
     RUNLEVELS="2345"
  fi  
  RUNLEVEL=`echo $RUNLEVELS | cut -b $rl`
  while [ "$RUNLEVEL" ]; do
    del_service1 $1 $RUNLEVEL
    let rl=$rl+1
    RUNLEVEL=`echo $RUNLEVELS | cut -b $rl`
  done
  echo Service $1 has been deactivated from run level $RUNLEVELS
}

## Install all service according to default
## Only the executables one
install_service()
{
   for LEVEL in 2 3 4 5; do
      rm -rf /etc/rc.d/rc${LEVEL}.d/*
   done

   for SNAME in $INITDIR/*; do
      if [ -f $SNAME ] && [ -x $SNAME ]; then
           add_service `basename $SNAME`
      fi
   done
}

# Install basic services
basic_service()
{
   # Remove all links !
   for LEVEL in 2 3 4 5; do
     rm /etc/rc.d/rc${LEVEL}.d/*
   done

   for SERVICE in $BASIC; do
     service -s $SERVICE
   done
}

run_service()
{
   SCRIPT=/etc/rc.d/init.d/$1
   if [ -x $SCRIPT ]; then
       $SCRIPT $2
   else
       echo service $1 is not active.  
   fi
}

case "$1" in
-a)
	display $2
	;;
-i)     
        install_service
	;;
-b)
        basic_service
	;;
-s)
	add_service $2 $3 $4 $5
	;;
-r)
	del_service $2 $3
	;;
-l)     list_service $2 $3
        ;;
-p)     print_service
        ;;
"" | -h)
	help
	;;
*)
	run_service $*
	;;
esac

