#!/bin/sh
#
# @(#)IceWall SSO Performance Monitor (iwpm)
# @(#)File        : iwpmc
# @(#)Description : certd activity reporter
# @(#)Version     : 10.00.00.100706A
#                   $Revision: 5 $
# (c) Copyright 2007-2010 Hewlett-Packard Development Company, L.P.
#
#
#===============================================================================
#
#                                  Parameter declare
#
#===============================================================================
# Common parameter
PROGDIR=`dirname $0`
RUNDIR=$PROGDIR/../run
CONFDIR=$PROGDIR/../conf
DATADIR=$PROGDIR/../data
SCRIPTDIR=$PROGDIR/../script
CONFIGFILE=$CONFDIR/iwpmc.conf
LOCKFILE=$RUNDIR/iwpmc.lock.$$
CM_LFILE_INFO=$RUNDIR/iwpmc_cmagt_info.lock
CM_LFILE_PERF=$RUNDIR/iwpmc_cmagt_perf.lock

# check directory permission
if [ ! -w $RUNDIR -o ! -x $RUNDIR ]
then
 echo "directory permission error. (run)"
 exit 1
fi

if [ ! -w $DATADIR -o ! -x $DATADIR ]
then
 echo "directory permission error. (data)"
 exit 1
fi  

if [ ! -r $CONFDIR -o ! -x $CONFDIR ]
then
 echo "directory permission error. (conf)"
 exit 1
fi

if [ ! -r $SCRIPTDIR ]
then
 echo "directory permission error. (script)"
 exit 1
fi

# configfile permission check
if [ ! -r $CONFIGFILE ]
then
  echo "Error. can't read file. ($CONFIGFILE)"
  exit 1
fi

# define parameter from config file
export GL_TMPDIR=`cat $CONFIGFILE | egrep "^ *TMPDIR *=" | sed 's/^.*= *//'`
export GL_FL_SRC_PERF=`cat $CONFIGFILE | egrep "^ *PERF_FILE *=" | sed 's/^.*= *//'`
export GL_FL_SRC_INFO=`cat $CONFIGFILE | egrep "^ *CERTINFO_FILE *=" | sed 's/^.*= *//'`
export GL_CERTDIR=`cat $CONFIGFILE | egrep "^ *CERTDIR *=" | sed 's/^.*= *//'`

# data file paramater define
export GL_FL_INFO=$DATADIR/iwpmc-info.dat
export GL_FL_PERF=$DATADIR/iwpmc-perf.dat

# temporary file parameter define
export GL_FL_CPU=$GL_TMPDIR/iwpmc-cpuinfo.$$
export FL_CERTPID=$GL_CERTDIR/bin/certd.pid

# script file defile
SC_INFOCERT=$GL_CERTDIR/bin/info-cert
SC_PRI_HEAD_INFO=$SCRIPTDIR/iwpmc_printheader_info.pl
SC_PRI_HEAD_PERF=$SCRIPTDIR/iwpmc_printheader_perf.pl
SC_PRI_DATA_INFO=$SCRIPTDIR/iwpmc_printdata_info.pl
SC_PRI_DATA_PERF=$SCRIPTDIR/iwpmc_printdata_perf.pl
SC_PRI_DATA_SCREEN=$SCRIPTDIR/iwpmc_printdata_screen.pl
SC_CALC_AVG_INFO=$SCRIPTDIR/iwpmc_calcaverage_info.pl
SC_CALC_AVG_PERF=$SCRIPTDIR/iwpmc_calcaverage_perf.pl
SC_ANALYSE_LOG=$SCRIPTDIR/iwpmc_analyselog.pl

# other parameter
export GL_INTERVAL="-1"
export GL_CTIME=""
export GL_MNAME=""
export GL_NNAME=""
export GL_AVINTVAL="60"
CERTD_PID=""
iflag=0
pflag=0
tflag=0
oflag=0
OUTPUTTYPE=""
OUTPUTFILENAME=""
BTIME=0
CTIME=0

#===============================================================================
#
#                                  Sub Function
#
#===============================================================================

usage()
{
  echo "Usage: iwpmc -i <interval> [-p <time>] [-t {c | p}] [-o <filename>]"
  echo ""
  echo "-i: Specify an interval(sec) to display."
  echo ""
  echo "-p: Specify a period(sec) to calculate average and max values of CERTINFO."
  echo "    Default is 60 sec."
  echo ""
  echo "-t: Writes one recored for each interval in the CSV format."
  echo "      c: CERTINFO log information."
  echo "      p: PERF log information."
  echo ""
  echo "-o: Writes output to <filename>."
  echo "    It must be specified with -t option."
  echo ""
  echo "examples:"
  echo "  iwpmc -i 10"
  echo "  iwpmc -i 10 -p 120"
  echo "  iwpmc -i 10 -p 120 -t c"
  echo "  iwpmc -i 10 -p 120 -t p -o /data/certdperf.csv"
}

paramchk()
{
  ## arg1: check type
  ##   IS_NULL : null check
  ##   IS_EXIST : existence check
  ##   IS_EXEC : executable check
  ##
  ## arg2 : parameter value
  ##
  ## arg3 : messege
  ##
  ## return :
  ##   success : 0
  ##   error   : exit 1
  ##

  if [ _$1 = _IS_NULL ]
  then
    if [ _$2 = _ ]
    then
      echo "Error. $3 (null)"
      exit 1
    fi
  fi

  if [ _$1 = _IS_EXIST ]
  then
    if [ ! -r $2 ]
    then
      echo "Error. $2 does not exist. $3"
     exit 1
    fi
  fi

  if [ _$1 = _IS_EXEC ]
  then
    if [ ! -x $2 ]
    then
      echo "Error. can't exec $2. $3"
     exit 1
    fi
  fi
  
  return 0
}

IW_GetMachineName()
{
  ## no arg
  ## return : machine name
  uname -s
}

IW_GetNodeName()
{
  ## no arg
  ## return : node name
  uname -n | awk '{print substr($0,1,30); }'
}

IW_GetCTime()
{
  ## no args
  ## Return the current time(seconds) from 1970/1/1 0:00:00.
  ##   ex 1166170623
  perl -e 'print time'
}

IW_GetMemUsage()
{
  ## arg1 : PID
  ## return : mem usage(certd rss,vss, total physical memory)
  ##   ex 421736,1111628,2055476

  if [ _${GL_MNAME} = "_Linux" ]
  then
    CERTDMEM=`ps -p $CERTD_PID -o rss,vsz| tail -1 | \
              awk '{ printf("%dkB,%dkB",$1,$2 ) }'`
    TOTALMEM=`cat /proc/meminfo |\
              awk '/^MemTotal.*/ {printf("%dkB",$2 )}'`
  else
    export UNIX95=1
    CERTDMEM=`ps -p $CERTD_PID -o vsz | tail -1 | \
              awk '{ printf("--kB,%dkB",$1 ) }'`

    TOTALMEM=`/usr/sbin/dmesg | grep -i phys | grep "Physical:" | awk '{print $2}'`
    if [ _$TOTALMEM = "_" ]
    then
      TOTALMEM="----kB"
    else
      TOTALMEM=$TOTALMEM"kB"
    fi
  fi

  export GL_PRI_MEM=`echo $CERTDMEM,$TOTALMEM`

}


IW_GetCertInfo()
{
  if [ -r $GL_FL_INFO ]
  then
    export GL_PRI_DATA_INFO=`tail -$GL_AVINTVAL $GL_FL_INFO | perl $SC_CALC_AVG_INFO | sed 's/^..........,//g'`
  else
   cleanup 1 "file not found.($GL_FL_INFO)"
  fi
}

IW_GetPerfInfo()
{
  ## return : login,access, passwordchange, logout
  ##  cnt(avg) time(avg) time select(avg) time update(avg) time insert(avg)
  if [ -r $GL_FL_PERF ]
  then
    export GL_PRI_DATA_PERF=`tail -$GL_INTERVAL $GL_FL_PERF | perl $SC_CALC_AVG_PERF | sed 's/^..........,//g'`
  else
   cleanup 1 "file not found.($GL_FL_PERF)"
  fi

}

cleanup()
{
  ## program exit function.
  # massage print
  if [ "_$2" != _ ]
  then
    echo "$2"
  fi

  # remove temporary file
  rm -f $RUNDIR/*.$$ $GL_TMPDIR/*.$$


  # stop daemon
  RMSG=`$PROGDIR/iwpmcd stop`
  echo $RMSG

  exit $1
}


#===============================================================================
#
#                                    Main Function
#
#===============================================================================
trap 'cleanup 0 "exit program."' HUP INT QUIT KILL TERM

#================================================
#              Argument Handling
#================================================
iflag=0;
pflag=0;
ARGC=$#
while [ $# -ne 0 ]
do
  case $1 in
    -i)
        iflag=1

        GL_INTERVAL=`echo $2 | awk '/^[0-9]*$/ {print}'` ; shift
        ##  numeric check
        if [ _$GL_INTERVAL = "_" ]
        then
          cleanup 1 "`usage`"
        fi

        ##  value check ( argument > 0)
        if [ $GL_INTERVAL -le 0 ]
        then
          cleanup 1 "`usage`"
        fi
       ;;
    -p)
        pflag=1

        export GL_AVINTVAL=`echo $2 | awk '/^[0-9]*$/ {print}'` ; shift
        ##  numeric check
        if [ _$GL_AVINTVAL = "_" ]
        then
          cleanup 1 "`usage`"
        fi

        ##  value check ( argument > 0)
        if [ $GL_AVINTVAL -le 0 ]
        then
          cleanup 1 "`usage`"
        fi
       ;;
    -t)
        tflag=1

        OUTPUTTYPE=$2; shift
        ##  value check. (The argument must be 'c' or 'p'.)
        if [ _$OUTPUTTYPE != "_c" -a _$OUTPUTTYPE != "_p" ]
        then
          cleanup 1 "`usage`"
        fi
       ;;
    -o)
        oflag=1

        OUTPUTFILENAME=$2; shift
        ##  null check
        if [ _$OUTPUTFILENAME = "_" ]
        then
          cleanup 1 "`usage`"
        fi
       ;;

## 8.0R3 Configration Manager Argument ##
#    start)
#        if [ _$2 = "_info" ]
#        then
#          if [ -r $CM_LFILE_INFO ]
#          then
#            MSG="iwpmc(info) process is running."
#            echo "$MSG"
#            exit 0
#          fi
#          LFILE=$CM_LFILE_INFO
#        else
#          if [ -r $CM_LFILE_PERF ]
#          then
#            MSG="iwpmc(perf) process is running."
#            echo  "$MSG"
#            exit 0
#          fi
#          LFILE=$CM_LFILE_PERF
#        fi
#        shift; shift;
#        $0 $* 2>&1 > /dev/null &
#        PID=$!
#        echo $PID > $LFILE
#
#        echo "iwpmc is starting."
#        exit 0
#       ;;
#
#    stop)
#        if [ _$2 = "_info" ]
#        then
#          if [ ! -r $CM_LFILE_INFO ]
#          then
#            MSG="process is not running."
#            echo "$MSG"
#            exit 0
#          fi
#          LFILE=$CM_LFILE_INFO
#        else
#          if [ ! -r $CM_LFILE_PERF ]
#          then
#            MSG="process is not running."
#            echo "$MSG"
#            exit 0
#          fi
#          LFILE=$CM_LFILE_PERF
#        fi
#
#        # PID  get
#        IW_PPID=`cat $LFILE`
#
#        PIDLIST=`ps -ef | awk -v PPID=$IW_PPID '{ if ( $3 == PPID ) print $2; }'`
#
#        # kill parent process
#        ps -ef | awk -v PID=$IW_PPID '{ if ( $2 == PID ) print $2; }' | grep $IW_PPID > /dev/null
#        if [ $? -eq 0 ]
#        then
#           kill $IW_PPID
#        fi
#
#        # kill child process
#        for CPID in $PIDLIST
#        do
#          # kill parent process
#          ps -ef | awk -v PID=$CPID '{ if ( $2 == PID ) print $2; }' | grep $CPID > /dev/null
#          if [ $? -eq 0 ]
#          then
#            PIDLIST2=`ps -ef | grep -v perl | awk -v PPID=$CPID '{ if ( $3 == PPID ) print $2; }'`
#            kill $CPID
#
#            # kill child process
#            for CPID2 in $PIDLIST2
#            do
#              ps -ef |  awk -v PID=$CPID2 '{ if ( $2 == PID ) print $2; }' | grep $CPID2 > /dev/null
#              if [ $? -eq 0 ]
#              then
#                kill $CPID2
#              fi
#            done
#          fi
#        done
#
#        rm -f $LFILE
#        echo "iwpmc is stoped."
#        exit 0
#       ;;
#
#    status)
#        if [ _$2 = "_info" ]
#        then
#          if [ -r $CM_LFILE_INFO ]
#          then
#            MSG="iwpmc(info) process is running."
#            STS=0
#          else
#            MSG="iwpmc(info) process is not running."
#            STS=0
#          fi
#        else
#          if [ -r $CM_LFILE_PERF ]
#          then
#            MSG="iwpmc(perf) process is running."
#            STS=0
#          else
#            MSG="iwpmc(perf) process is not running."
#            STS=0
#          fi
#        fi
#
#        echo "$MSG"
#        exit $STS
#        
#       ;;
#
#    delete)
#        if [ -r $2 ]
#        then
#          rm -f $2
#        fi
#        echo "remove file $2."
#        exit 0
#
#       ;;
    *)
      echo "Error. Invalid parameter."
      cleanup 1 "`usage`"
      ;;
  esac
  shift
done


#================================================
#              Parameter Check
#================================================
if [ $ARGC -lt 1 ]
then
  usage
  exit 1
fi

# 'i' Parameter check
if [ $iflag -ne 1 ]
then
  usage
  exit 1
fi

# 'o' parameter check
if [ $oflag -eq 1 ]
then
  if [ $tflag -ne 1 ]
  then
    usage
    exit 1
  fi
fi

# environment parameter check
paramchk IS_NULL "$GL_TMPDIR"      "can't read TMPDIR parameter."
paramchk IS_NULL "$GL_FL_SRC_PERF" "can't read PERF_FILE parameter."
paramchk IS_NULL "$GL_FL_SRC_INFO" "can't read CERTINFO_FILE parameter."
paramchk IS_NULL "$GL_CERTDIR"     "can't read CERTDIR parameter."

paramchk IS_EXEC  "$SC_INFOCERT"    ""

paramchk IS_EXIST "$GL_FL_SRC_PERF" ""
paramchk IS_EXIST "$GL_FL_SRC_INFO" ""
paramchk IS_EXIST "$FL_CERTPID"     "(or certd is not running.)"
CERTD_PID=`cat $FL_CERTPID`
paramchk IS_EXIST "$SC_PRI_HEAD_INFO" ""
paramchk IS_EXIST "$SC_PRI_HEAD_PERF" ""
paramchk IS_EXIST "$SC_PRI_DATA_INFO" ""
paramchk IS_EXIST "$SC_PRI_DATA_PERF" ""
paramchk IS_EXIST "$SC_PRI_DATA_SCREEN" ""
paramchk IS_EXIST "$SC_CALC_AVG_INFO" ""
paramchk IS_EXIST "$SC_CALC_AVG_PERF" ""
paramchk IS_EXIST "$SC_ANALYSE_LOG" ""

if [ ! -w $GL_TMPDIR -o ! -x $GL_TMPDIR ]
then
 echo "directory permission error. (tmp)"
 exit 1
fi

## output file permission check
if [ -n "$OUTPUTFILENAME" ]
then
  if [ -e $OUTPUTFILENAME -a ! -w $OUTPUTFILENAME ]
  then
    echo "output file permission error. ($OUTPUTFILENAME)"
    exit 1
  fi
  OUTPUTFILEPATH="`/usr/bin/dirname $OUTPUTFILENAME`/"
  if [ ! -w $OUTPUTFILEPATH -o ! -x $OUTPUTFILEPATH ]
  then
    echo "output file permission error. ($OUTPUTFILENAME)"
    exit 1
  fi
fi
#================================================
#             Start iwpmcd daemon
#================================================
$PROGDIR/iwpmcd status > /dev/null
if [ $? -eq 0 ]
then
  $PROGDIR/iwpmcd start
  if [ $? -ne 0 ]
  then
    cleanup 1 "failed to start iwpmcd."
  fi
fi
sleep 1

#================================================
#             LockFile Create
#================================================
echo $$ > $LOCKFILE

#================================================
#             Print Performance Data
#================================================

#=============================
#   CSV(infocert) output
#=============================
if [ _$OUTPUTTYPE = "_c" ]
then
  if [ _$OUTPUTFILENAME = "_" ]
  then
   OUTPUTFILENAME=/dev/null
  fi

  # print header
  perl $SC_PRI_HEAD_INFO | tee -a $OUTPUTFILENAME

  # print data
  cnt=0;
  paramchk IS_EXIST "$GL_FL_INFO"

  tail -f $GL_FL_INFO 2> /dev/null | \
  while [ 1 ]
  do
   read CACHE;

   # create temp file for caluculate average
   echo $CACHE >> $GL_TMPDIR/iwpmc_outputcache.$$;
   LINE=`wc -l $GL_TMPDIR/iwpmc_outputcache.$$ | awk '{print $1}'`
   if [ $LINE -gt $GL_AVINTVAL ]
   then
     sed 1d $GL_TMPDIR/iwpmc_outputcache.$$ > $GL_TMPDIR/iwpmc_outputcache.tmp.$$
     cat $GL_TMPDIR/iwpmc_outputcache.tmp.$$ > $GL_TMPDIR/iwpmc_outputcache.$$
     rm -f $GL_TMPDIR/iwpmc_outputcache.tmp.$$;
   fi

   # wait interval
   if [ `expr $cnt % $GL_INTERVAL` -eq 0 ]
   then
     cat $GL_TMPDIR/iwpmc_outputcache.$$ | \
       perl $SC_CALC_AVG_INFO | \
       perl $SC_PRI_DATA_INFO | \
       sed 's/ //g' | tee -a $OUTPUTFILENAME
     cnt=0;
   fi
  cnt=`expr $cnt + 1`
  done

#=============================
# CSV(request performance) output
#=============================
elif [ _$OUTPUTTYPE = "_p" ]
then
  if [ _$OUTPUTFILENAME = "_" ]
  then
   OUTPUTFILENAME=/dev/null
  fi

  # print header
  perl $SC_PRI_HEAD_PERF | tee -a $OUTPUTFILENAME

  # print data
  cnt=0;
  paramchk IS_EXIST "$GL_FL_PERF"

  tail -f $GL_FL_PERF 2> /dev/null | \
  while [ 1 ]
  do
   read REQ;

   # create temp file for caluculate average
   echo $REQ >> $GL_TMPDIR/iwpmc_outputrequest.$$;
   LINE=`wc -l $GL_TMPDIR/iwpmc_outputrequest.$$ | awk '{print $1}'`
   if [ $LINE -gt $GL_INTERVAL ]
   then
     sed 1d $GL_TMPDIR/iwpmc_outputrequest.$$ > $GL_TMPDIR/iwpmc_outputrequest.tmp.$$
     cat $GL_TMPDIR/iwpmc_outputrequest.tmp.$$ > $GL_TMPDIR/iwpmc_outputrequest.$$
   fi

   # wait interval
   if [ `expr $cnt % $GL_INTERVAL` -eq 0 ]
   then
     cat $GL_TMPDIR/iwpmc_outputrequest.$$ | \
       perl $SC_CALC_AVG_PERF | \
       perl $SC_PRI_DATA_PERF | \
       sed 's/ //g' | tee -a $OUTPUTFILENAME
     cnt=0;
   fi
  cnt=`expr $cnt + 1`
  done

#=============================
#      Screen output 
#=============================
else
export GL_MNAME=`IW_GetMachineName`
export GL_NNAME=`IW_GetNodeName`

while [ 1 ]
do
  if [ `expr $CTIME - $BTIME` -gt `expr $GL_INTERVAL - 1 ` ]
  then
    BTIME=$CTIME
    IW_GetMemUsage
    IW_GetCertInfo
    IW_GetPerfInfo

    clear
    perl $SC_PRI_DATA_SCREEN

  fi
  # sleep 0.5s
  perl -e 'select(undef, undef, undef, 0.5);'

  CTIME=`IW_GetCTime`
done
fi

exit 0
