#!/bin/sh
#
# @(#)IceWall SSO Performance Monitor (iwpm)
# @(#)File        : iwpmd
# @(#)Description : dfw activity reporter
# @(#)Version     : 10.00.00.100706A
#                   $Revision: 5 $
# (c) Copyright 2007-2010 Hewlett-Packard Development Company, L.P.
#
#===============================================================================
#
#                                  Parameter define
#
#===============================================================================
# Common parameter
PROGDIR=`dirname $0`
RUNDIR=$PROGDIR/../run
CONFDIR=$PROGDIR/../conf
DATADIR=$PROGDIR/../data
SCRIPTDIR=$PROGDIR/../script
CONFIGFILE=$CONFDIR/iwpmd.conf
LOCKFILE=$RUNDIR/iwpmd.lock.$$
CM_LFILE_PERF=$RUNDIR/iwpmd_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

# Get parameter from configfile
export GL_TMPDIR=`cat $CONFIGFILE | egrep "^ *TMPDIR *=" | sed 's/^.*= *//'`
export GL_FL_SRC_PERF=`cat $CONFIGFILE | egrep "^ *SRC_FILE *=" | sed 's/^.*= *//'`
export GL_FL_SRC_ERR=`cat $CONFIGFILE | egrep "^ *SRC_ERRFILE *=" | sed 's/^.*= *//'`
export GL_HOSTS=`cat $CONFIGFILE | egrep "^ *HOST *=" | cut -d '=' -f 3`
export GL_ALIASES=`cat $CONFIGFILE | egrep "^ *HOST *=" | cut -d '=' -f 2`

# data file paramater define
export GL_FL_PERF=$DATADIR/iwpmd-perf.dat
export GL_FL_ERRCNT=$DATADIR/iwpmd-err.dat

# script file defile
SC_PRI_HEAD_PERF=$SCRIPTDIR/iwpmd_printheader_perf.pl
SC_PRI_DATA_PERF=$SCRIPTDIR/iwpmd_printdata_perf.pl
SC_PRI_DATA_SCREEN=$SCRIPTDIR/iwpmd_printdata_screen.pl
SC_CALC_AVG_PERF=$SCRIPTDIR/iwpmd_calcaverage_perf.pl
SC_ANALYSE_LOG=$SCRIPTDIR/iwpmd_analyselog.pl
SC_CNT_ERRLOG=$SCRIPTDIR/iwpmd_count_errlog.pl

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

# dfw.log exist check
if [ ! -r $GL_FL_SRC_PERF ]
then
  echo "Error. can't read file. ($GL_FL_SRC_PERF)"
  exit 1
fi

# dfwerr.log exist check
if [ ! -r $GL_FL_SRC_ERR ]
then
  echo "Error. can't read file. ($GL_FL_SRC_ERR)"
  exit 1
fi
#===============================================================================
#
#                                  Sub Function
#
#===============================================================================

usage()
{
  echo "Usage: iwpmd -i <interval> [-t [<alias1> <alias2> ...] [-o <filename>]"
  echo ""
  echo "-i: Specify an interval(sec) to display."
  echo ""
  echo "-t: Writes one recored for each interval in the CSV format."
  echo "    Aliases can be specified."
  echo "    If "-t" is not specified iwpmd runs with screen display."
  echo ""
  echo "-o: Writes output to <filename>."
  echo "    It must be specified with -t option."
  echo ""
  echo "examples:"
  echo "  $0 -i 10"
  echo "  $0 -i 10 -t"
  echo "  $0 -i 10 -t sys sys2"
  echo "  $0 -i 10 -t -o /data/dfwperf.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_GetDfwErrCnt()
{
  if [ -r $GL_FL_ERRCNT ]
  then
    export GL_DFWERRCNT=`tail -1 $GL_FL_ERRCNT`
    if [ _${GL_DFWERRINITCNT} = "_-1" ]
    then
      export GL_DFWERRINITCNT=$GL_DFWERRCNT;
    fi
  else
   cleanup 1 "file not found.($GL_FL_ERRCNT)"
  fi

}

IW_GetDfwReqInfo()
{
  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/iwpmdd stop`
  echo $RMSG

  exit $1
}


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

# Set argument.
iflag=0
tflag=0
oflag=0
OUTFLAG=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
        shift
       ;;
    -t)
        tflag=1

        OUTFLAG=1
        GL_OUTPUTBK=ALL
        GL_OUTPUTIDX=0

        shift;
        for ARG in $*
        do
          if [ _`echo $ARG | awk '{print substr($0,0,1)}'` = "_-" ]
          then
            break
          fi

          okflag=0;
          index=1;
          for BK in `echo $GL_ALIASES`
          do
            if [ _$ARG = _$BK ]
            then
              GL_OUTPUTBK="$GL_OUTPUTBK $ARG"
              GL_OUTPUTIDX="$GL_OUTPUTIDX $index" 
              okflag=1;
              break;
            fi
            index=`expr $index + 1`
          done
          if [ _$okflag = "_0" ]
          then
            MSG="invalid alias. ($ARG)"
            cleanup 1 "$MSG"
          fi
          shift;
        done
        export GL_OUTPUTBK
        export GL_OUTPUTIDX

       ;;
    -o)
        oflag=1

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

## 8.0R3 Configration Manager Argument ##
#    start)
#        shift
#        if [ -r $CM_LFILE_PERF ]
#        then
#          MSG="iwpmd process is running.(`cat $CM_LFILE_PERF`)"
#          echo $MSG
#          exit 0
#        fi
#        $0 $* 2>&1 > /dev/null &
#        PID=$!
#        echo $PID > $CM_LFILE_PERF
#
#        echo "iwpmd is starting."
#        exit 0
#
#       ;;
#
#    stop)
#        if [ ! -r $CM_LFILE_PERF ]
#        then
#          MSG="process is not running."
#          echo "$MSG"
#          exit 0
#        fi
#
#        # PID  get
#        IW_PPID=`cat $CM_LFILE_PERF`
#
#        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 $CM_LFILE_PERF
#
#        echo "iwpmd is stoped."
#        exit 0
#       ;;
#
#    status)
#        if [ -r $CM_LFILE_PERF ]
#        then
#          MSG="iwpmd process is running."
#          STS=0
#        else
#          MSG="iwpmd process is not running."
#          STS=0
#        fi
#        echo "$MSG"
#        exit $STS
#        
#       ;;
#
#    delete)
#        if [ -r $2 ]
#        then
#          rm -f $2
#        fi
#        echo "remove file $2."
#        exit 0
#       ;;

    *)
      cleanup 1 "`usage`"
      ;;

  esac
done

#========================================
#     Parameter Check Section
#========================================
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 SRC_FILE parameter."
paramchk IS_NULL "$GL_FL_SRC_ERR"  "can't read SRC_ERRFILE parameter."

paramchk IS_EXIST "$GL_FL_SRC_PERF" ""
paramchk IS_EXIST "$GL_FL_SRC_ERR" ""
paramchk IS_EXIST "$SC_PRI_HEAD_PERF" ""
paramchk IS_EXIST "$SC_PRI_DATA_PERF" ""
paramchk IS_EXIST "$SC_PRI_DATA_SCREEN" ""
paramchk IS_EXIST "$SC_CALC_AVG_PERF" ""
paramchk IS_EXIST "$SC_ANALYSE_LOG" ""
paramchk IS_EXIST "$SC_CNT_ERRLOG" ""

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 iwpmdd daemon
#================================================
$PROGDIR/iwpmdd status > /dev/null
if [ $? -eq 0 ]
then
  $PROGDIR/iwpmdd start
  if [ $? -ne 0 ]
  then
    cleanup 1 "failed to start iwpmdd."
  fi
fi

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

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

#=============================
#   CSV output
#=============================
if [ _$OUTFLAG = "_1" ]
then
  OUTTMP=$GL_TMPDIR/dfw_outputrequest.$$;
  OUTTMP2=$GL_TMPDIR/dfw_outputrequest.tmp.$$
  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 >> $OUTTMP;
   LINE=`wc -l $OUTTMP | awk '{print $1}'`
   if [ $LINE -gt $GL_INTERVAL ]
   then
     sed 1d $OUTTMP > $OUTTMP2
     cat $OUTTMP2 > $OUTTMP
   fi

   # wait interval
   if [ `expr $cnt % $GL_INTERVAL` -eq 0 ]
   then
     cat $OUTTMP | \
       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`
export GL_DFWERRINITCNT=-1

while [ 1 ]
do
  if [ `expr $CTIME - $BTIME` -gt `expr $GL_INTERVAL - 1 ` ]
  then
    BTIME=$CTIME
    IW_GetDfwErrCnt
    IW_GetDfwReqInfo

    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
