#! /bin/sh
# Copyright (c) 2013-2014 VMware Inc
# All rights reserved
#
# Author: mrm@vmware.com 
#
# /etc/init.d/snmpd
#

### BEGIN INIT INFO
# Provides: snmpd
# config: /etc/vmware/snmp.xml
# Required-Start: $network $local_fs
# Required-Stop:  $network
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Description: VMware CloudVM SNMP Agent
### END INIT INFO

# Return values acc. to LSB for all commands but status:
# 0 - success
# 1 - generic or unspecified error
# 2 - invalid or excess argument(s)
# 3 - unimplemented feature (e.g. "reload")
# 4 - insufficient privilege
# 5 - program is not installed
# 6 - program is not configured
# 7 - program is not running
# 

s_prog="/bin/snmpd"
test -x $s_prog || exit 5
RETVAL=0
TAG=snmpd
WATCHDOG=/usr/bin/vmware-watchdog
spool_path=/var/spool/snmp
PIDFILE="/var/run/vmware/snmpd.pid"
snmpd="/bin/snmpd"
prog=$(basename $snmpd)
SNMP_CONF_FILE=/etc/vmware/snmp.xml
SNMPDARGS=\&
STATUS=0

SUSE=$(grep SUSE /proc/version)
if [ "${SUSE}" != "" -o -f /etc/photon-release ]; then

 get_port() {
  if [ ! -f /etc/vmware/snmp.xml ]; then
    port=161
  else
     port=$(awk -vRS="</port>" '{gsub(/.*<port.*>/,"");print}' /etc/vmware/snmp.xml | head -1)
     if [ "${port}" == "" ]; then
        port=161
     else 
        if [[ $1 =~ ^[0-9]+$ ]]; then
          ok=1 
        else 
           port=161
        fi
     fi
  fi
  return ${port}
 }


 fw_open() {
   fw_status
   if [ $? != 0 ]; then
     return 0 
   fi
   get_port
   port=$?
   /usr/sbin/iptables -A INPUT -p udp --dport ${port} -j ACCEPT
   return $?
 }

 fw_close() {
   fw_status
   if [ $? = 0 ]; then
     return 0 
   fi
   get_port
   port=$?
   /usr/sbin/iptables -D INPUT -p udp --dport ${port} -j ACCEPT 
   return $?
 }

 fw_status() {
   get_port
   port=$?
   val=$(/usr/sbin/iptables -S INPUT | grep ${port} | grep udp)
   if [ "${val}" == "" ]; then
      return 0 
   else 
      return 1 
   fi 
 }

 mount_ramdisk() {
 if [ ! -d ${spool_path} ]; then
     mkdir -p ${spool_path}
     if [ $? != 0 ]; then
       logger -s -t snmpd -p daemon.err "ERROR: mkdir ${spool_path} failed err=$!"
       return 1
     fi
     mount -t tmpfs -o size=1m tmpfs ${spool_path}
     if [ $? != 0 ]; then
          logger -s -t snmpd -p daemon.err "ERROR: mount ramdisk failed err=$!"
          rm -rf ${spool_path}
          return 1
     fi
   fi    
   return 0
  }

  umount_ramdisk() {
  if [ -d ${spool_path} ]; then    
    umount ${spool_path}
    rm -rf ${spool_path}
  fi
  return 0
 }

# systemd expects this process to be snmpd
# keep this routine is idempotent.
 app_start_systemctl() {
     # are we configured?
     ENABLED=$(grep '<enable>false</enable>' /etc/vmware/snmp.xml)
     if [ $? -eq "0" ]; then
         logger -s -t snmpd -p daemon.info "agent has not been enabled."
         exit 6
     fi
     logger -s -t snmpd -p daemon.info "Starting snmpd by administrative command."
     mount_ramdisk
     fw_open
     ulimit -c unlimited
     exec ${s_prog} > /dev/null 2>&1 
 }

 app_start_sysv() {
     # are we configured? if not silent ok
     ENABLED=$(grep '<enable>false</enable>' /etc/vmware/snmp.xml)
     if [ $? -eq "0" ]; then
         logger -s -t snmpd -p daemon.info "agent has not been enabled."
         exit 0
     fi
     . /etc/rc.status
     logger -s -t snmpd -p daemon.info "Starting snmpd by administrative command."
     mount_ramdisk
     fw_open
     ulimit -c unlimited
     ${WATCHDOG} -s ${TAG} -u 30 -q 5 ${s_prog} > /dev/null 2>&1 &
     sleep 1
     pidof -s snmpd > /dev/null 2>&1
     rc_status -v
 }

 app_start() {
   if [ "$(pidof -s snmpd)" != "" ]; then
       exit 0
   fi
   if [ -x /bin/systemctl ];then
        app_start_systemctl
   else 
        app_start_sysv
   fi
 }

 app_stop_sysv() {
    ${WATCHDOG} -k ${TAG} > /dev/null > /dev/null 2>&1 
    sleep 1
    # second the snmpd daemon
    kill $(pgrep -f snmpd | grep -v ^$$\$) > /dev/null 2>&1
 }

 app_stop() {
   logger -s -t snmpd -p daemon.info "Shutting down snmpd by administrative command."
   if [ "$(pidof -s snmpd)" == "" ]; then
      exit 0
   fi
   if [ ! -x /bin/systemctl ]; then
        app_stop_sysv
   fi
   fw_close
   umount_ramdisk
 }

 case "$1" in
    start)
      app_start
    ;;

    stop)
      app_stop
    ;;

    try-restart)
       # no op
    ;;

    restart)
       ## Stop the service and regardless of whether it was
       ## running or not, start it again.
       app_stop
       app_start
       exit 0 
    ;;

    force-reload)
       ## Like force-reload, useless for cron daemon
       # could send 'C' to control port, but no need.
    ;;

    reload)
       ## Like force-reload, useless for cron daemon
       # could send 'C' to control port, but no need.
    ;;

    status)
        pidof snmpd > /dev/null 2>&1
        result=$?
        if [ $result -eq 0 ]; then
            echo "$s_prog is running"
        else
            echo "$s_prog is not running"
            result=7
        fi
        exit $result
    ;;

    *)
       echo "Usage: $0 {start|stop|status|restart}"
       exit 1
    ;;
    esac

    exit $STATUS

fi

# 
CENTOS=$(grep CentOS /etc/issue)
#

if [ "${CENTOS}" != "" ]; then
 . /etc/init.d/functions

start() {
    [ -x $snmpd ] || exit 5
    [ -f $SNMP_CONF_FILE ] || exit 6

    echo -n $"Starting $prog: " 
        if [ -e /var/lock/subsys/snmpd ]; then
        if [ -e /var/run/snmpd.pid ] && [ -e /proc/`cat /var/run/snmpd.pid` ]; then
        echo -n $"cannot start snmpd: snmpd is already running.";
        failure $"cannot start snmpd: snmpd already running.";
        echo
        return 1
        fi
    fi
    daemon $snmpd $SNMPDARGS
    RETVAL=$?
    echo
    [ $RETVAL -eq 0 ] && touch /var/lock/subsys/snmpd;
    return $RETVAL
}

stop() {
    echo -n $"Stopping $prog: "
        if [ ! -e /var/lock/subsys/snmpd ]; then
        echo -n $"cannot stop snmpd: snmpd is not running."
        failure $"cannot stop snmpd: snmpd is not running."
        echo
        return 1;
    fi
    killproc snmpd
    RETVAL=$?
    echo
        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/snmpd;
    return $RETVAL
}   


restart() {
    stop
    start
}   

reload() {
    echo -n $"Reloading cron daemon configuration: "
    killproc snmpd -HUP
    RETVAL=$?
    echo
    return $RETVAL
}   

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    restart
    ;;
  reload)
    reload
    ;;
  status)
    "echo "TESTING" 
    ;;
  condrestart)
    [ -f /var/lock/subsys/snmpd ] && restart || :
    ;;
  *)
    echo $"Usage: $0 {start|stop|status|reload|restart|condrestart}"
    exit 1
esac

fi

echo "ERROR: unsupported linux distribution $(cat /etc/issue)"
exit 1

