#!/bin/sh

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`

help(){
cat << EOF

Usage: 
service [ -h ] 
        [ -a ] [runlevel]
	[ -i ]
	[ -s ] service_name runlevels [ order_num ]
	[ -r ] service_name runlevels
	[ -l ] service_name runlevel
	[service_name] [start | stop | restart | status ] 

-h		display help information
-a		display active services in a runlevel
-i              install all services with default settings
-s		register a service for to runlevels
-r              remove a service from runlevels
-l              list the status of a service in a runlevel
service_name 	one of /etc/rc.d/init.d/ files with exec mode (755)
runlevel	any runlevel from 2 to 5
order_num	the order which service should be started.
                Recomended:
                   00-09 = reserved
		   10-19 = system services (syslog, apm, ...)
                   20-29 = networking, firewall
		   30-39 = network file system (nfs, smb, cups, ...)
		   40-49 = reserved as default
		   50-69 = local services (cron, at, gpm, ...)
		   70-89 = network services (ssh, http, ftp)
		   89-99 = reserved
EOF
}

# return default run_level (2 - 5) for known services
default_runlevel()
{
case $1 in
  syslog|log)
    echo 2345
    ;;
  apm|apmd)
    echo 2345
    ;;
  quota)
    echo 2345
    ;;
  network|firewall|portsentry)
    echo 2345
    ;;
  dhcpd|dhcp)
    echo 2345
    ;;
  bind|named)
    echo 2345
    ;;
  rpc)
    echo 2345
    ;;
  netfs)
    echo 2345
    ;;
  printer|cups|lp|lpd)
    echo 2345
    ;;
  samba|smb|smbd)
    echo 2345
    ;;
  sshd|ssh|openssh)
    echo 2345
    ;;
  sendmail|postfix|qmail|smpt)
    echo 35
    ;;
  http|httpd|apache)
    echo 35
    ;;
  ftp|proftp|proftpd)
    echo 35
    ;;
  lampp)
    echo 35
    ;;
  mysql)
    echo 35
    ;;
  inet|xinet)
    echo 35
    ;;
  nis|yp)
    echo 35
    ;;
  nfsd)
    echo 35
    ;;
  xfstt)
    echo 35
    ;;
  wlan)
    echo 2345
    ;;
  at|cron)
    echo 2345
    ;;
  gpm)
    echo 2345
    ;;
  *)
    echo 2345
    ;;
  esac
}

# return default order for known services
default_order()
{
case $1 in
  syslog|log)
    echo 10
    ;;
  apm|apmd)
    echo 11
    ;;
  quota)
    echo 15
    ;;
  network)
    echo 20
    ;;
  wlan)
    echo 21
    ;;
  firewall|portsentry)
    echo 22
    ;;
  dhcpd|dhcp)
    echo 23
    ;;
  bind|named)
    echo 24
    ;;
  rpc)
    echo 25
    ;;
  netfs)
    echo 30
    ;;
  printer|lp|lpd|cups)
    echo 35
    ;;
  cron)
    echo 50
    ;;
  at)
    echo 52
    ;;
  gpm)
    echo 60
    ;;
  xfstt)
    echo 61
    ;;
  inet|xinet)
    echo 70
    ;;
  sshd|ssh|openssh)
    echo 71
    ;;
  nis|yp)
    echo 72
    ;;
  nfsd|nfs)
    echo 73
    ;;
  samba|smb|smbd)
    echo 74
    ;;
  database|mysql|postgress)
    echo 75
    ;;
  http|httpd|apache)
    echo 80
    ;;
  ftp|proftp|proftpd)
    echo 81
    ;;
  sendmail|postfix|qmail|smpt)
    echo 83
    ;;
  lampp)
    echo 89
    ;;
  *)
    echo 40
    ;;
  esac
}

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 = 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"
  fi
  chmod a+x $SNAME
  if [ $3 ]; then
     ORDER=$3
  else
     ORDER=`default_order $1`
  fi
  START="yes"
  for LNAME in $RCDIR/S??$1; do
     START=""     
     rm -f $LNAME
  done
  LNAME=$RCDIR/S${ORDER}$1
  ln -sf $SNAME $LNAME
  if [ "$START" ]; then
     if [ -x $LNAME ]; then
         $LNAME start 
	 sleep 1
     fi    
  fi
}

add_service()
{
  rl=1
  if [ $2 ]; then
     RUNLEVELS=$2
  else
     RUNLEVELS=`default_runlevel $1`
  fi
  RUNLEVEL=`echo $RUNLEVELS | cut -b $rl`
  while [ $RUNLEVEL ]; do
    add_service1 $1 $RUNLEVEL $3
    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 
  for LNAME in $RCDIR/S??$1; do
     if [ $RUNLEVEL = $CURRENT_LEVEL ]; then
         if [ -x $LNAME ]; then
	    $LNAME stop 
	    sleep 1
	 fi    
     fi
     rm -f $LNAME
  done
}

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_service()
{
   for SNAME in /etc/rc.d/init.d/*; do
      if [ -f $SNAME ]; then
        if [ -x $SNAME ]; then
           add_service `basename $SNAME`
        fi
      fi
   done
}



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

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

esac

