#!/bin/sh
# nfcollector
# Copyright (c) 2003-2006 by Cisco Systems, Inc.
# All rights reserved.

. `dirname $0`/nfcenv.sh

if [ -z "$1" ]; then
  echo "Usage: $0 [[{start | stop} <id>] | status | list | show-tech [-nologs] | shutdown | clean ]"
  exit 1
fi

CLASSPATH=$NFC_DIR/lib/pw.jar
CLASSPATH=$CLASSPATH:$NFC_DIR/lib/nfc.jar
CLASSPATH=$CLASSPATH:$NFC_DIR/lib/log4j-1.2.8.jar

CONSTANTS="-Dlog4j.configuration=file:$NFC_DIR/config/nfcpw-log4j.properties -DNFC_DIR=$NFC_DIR"

# functions

# create a process list from PID file.  Prevent extra spaces in process list because they cause
# problems on Linux
create_proc_list()
{
    PSLIST=`cat $NFC_DIR/logs/*.pid 2>/dev/null`
}

# find_log_file
find_log_file() {
    # resolve environment variables in logfile paths
    eval $1=`grep log4j\.appender\.$2\.File $3 | awk -F= '{print $2}'`
}

# output_log_file
output_log_file() {
    if [ -f $1 ]; then
        echo "********** `basename $1` **********"
        $TAIL -100 $1
        echo ""
    fi
}

# do_show_tech
SHOW_TECH_LOG=$NFC_DIR/logs/show-tech.log
do_show_tech()
{
    UNAME=`which uname | awk '/uname/ {print $1}'`
    
    OS=`$UNAME -s`
    
    TEE=`which tee | awk '/tee/ {print $1}'`
    CAT=`which cat| awk '/cat/ {print $1}'`
    TAIL=`which tail | awk '/tail/ {print $1}'`
    HEAD=`which head | awk '/head/ {print $1}'`
    ULIMIT=`which ulimit | awk '/ulimit/ {print $1}'`
    NETSTAT=`which netstat | awk '/netstat/ {print $1}'`
    PS=`which ps | awk '/ps/ {print $1}'`
    KILL=`which kill | awk '/kill/ {print $1}'`
    DF=`which df | awk '/df/ {print $1}'`
    
    LS=/bin/ls
    GREP=/bin/grep
    WC=/usr/bin/wc
    TAR=/bin/tar
    UUENCODE=/usr/bin/uuencode
    if [ $OS = HP-UX ]; then
        GZIP=/usr/contrib/bin/gzip
    else
        GZIP=/bin/gzip
    fi

    create_proc_list

    PKG_NAME=CSCOnfc
    if [ "$OS" = "HP-UX" ]; then
        PACKAGE_INFO="/usr/sbin/swlist -v"
    elif [ "$OS" = "SunOS" ]; then
        PACKAGE_INFO="/usr/bin/pkginfo -l"
    elif [ "$OS" = "Linux" ]; then
        PACKAGE_INFO="/bin/rpm -q -i "
        ULIMIT="ulimit"  # bash built-in
    else
        echo "This operating system is not supported"
        exit 1;
    fi

    if [ ! -w $NFC_DIR/logs ]; then
        SHOW_TECH_LOG="/tmp/show-tech.log"
        echo "No write permission to create $SHOW_TECH_LOG in $NFC_DIR/logs"
        echo "Please see $SHOW_TECH_LOG for show-tech infomation"
        echo "Press <CR> to continue"
        read dummy
    fi
  
    {
        echo ""
        echo "********** Beginning of show-tech **********"
        echo "Date : `date` "
        echo "\nNetFlow FlowCollector Environment variables"
        echo "\nNFC_DIR=$NFC_DIR"
        echo "NFC_XMLCONFIG=$NFC_XMLCONFIG"
        echo ""

        find_log_file "NFCPW_LOG" "pwLog" $NFC_DIR/config/nfcpw-log4j.properties
        find_log_file "NFC_LOG" "nfcLog" $NFC_DIR/config/nfc-log4j.properties
        find_log_file "NFCXML_LOG" "xmlLog" $NFC_DIR/config/nfcxml-log4j.properties
        find_log_file "NFCBGP_LOG" "bgpLog" $NFC_DIR/config/nfcbgp-log4j.properties
        find_log_file "NFCRE_LOG" "reLog" $NFC_DIR/config/nfcre-log4j.properties
        find_log_file "NFCWEB_LOG" "webLog" $NFC_DIR/config/nfcweb-log4j.properties
        NFC_INSTALL_LOG=$NFC_DIR/logs/nfc_install.log

        echo "********** $UNAME -a **********"
        $UNAME -a
        echo ""

        echo "********** $ULIMIT -a **********"
        $ULIMIT -a
        echo ""

        if [ "$OS" = "SunOS" ]; then
            SYSINFO="/usr/platform/`uname -m`/sbin/prtdiag"
            echo "********** $SYSINFO **********"
            $SYSINFO        
        elif [ "$OS" = "HP-UX" ]; then
            SYSINFO="/opt/ignite/bin/print_manifest"
            echo "********** $SYSINFO **********"
            $SYSINFO        
        elif [ "$OS" = "Linux" ]; then
            SYSINFO="$CAT /etc/redhat-release"
            echo "********** $SYSINFO **********"        
            $SYSINFO
            echo ""        
            SYSINFO="$CAT /proc/cpuinfo"
            echo "********** $SYSINFO **********"        
            $SYSINFO        
            SYSINFO="/usr/bin/free -k"
            echo "********** $SYSINFO **********"        
            $SYSINFO        
        fi

        echo ""

        if [ "$OS" = "SunOS" ]; then
            echo "********** udp_max_buf **********"
            /usr/sbin/ndd /dev/udp udp_max_buf
            echo ""
            echo "********** netstat info **********"
            $NETSTAT -s | grep udp
        elif [ "$OS" = "HP-UX" ]; then
            echo "********** netstat info **********"
            $NETSTAT -p udp
        elif [ "$OS" = "Linux" ]; then
        echo "********** net.core.rmem_max info **********"
            /sbin/sysctl net.core.rmem_max
            echo ""
        echo "********** netstat info **********"
        $NETSTAT -s -u
        fi
        echo ""

        echo "********** $DF -k **********"
            $DF -k
        echo ""

        echo "********** pkginfo/swlist **********"
        $PACKAGE_INFO $PKG_NAME
        echo ""

        echo "********** process listing **********"
        
        if [ `echo "$PSLIST" | wc -w` -gt 0 ]; then
            $PS -f -p "`echo $PSLIST`"
        fi
        echo ""

        output_log_file $NFCPW_LOG
        output_log_file $NFC_LOG
        output_log_file $NFCXML_LOG
        output_log_file $NFCBGP_LOG
        output_log_file $NFCRE_LOG
        output_log_file $NFCWEB_LOG
        output_log_file $NFC_INSTALL_LOG
        output_log_file $NFC_DIR/logs/nfcudprdr.log

        echo ""
        echo "********** NFC configuration **********"
        echo ""
        echo "nfc-config-predefined.xml"
        $CAT $NFC_DIR/config/nfc-config-predefined.xml
        echo ""
        echo "nfc-config.xml"
        if [ ! -z "$NFC_XMLCONFIG" ]; then
            $CAT $NFC_XMLCONFIG
        else
            $CAT $NFC_DIR/config/nfc-config.xml
        fi
        echo ""

        echo "********** End of show-tech **********"
        echo ""
        
        #
        # Append the contents of logfiles in $NFC_DIR/logs to the show-tech log.
        # This can be disabled by specifying 'nfcollector show-tech -nologs'.
        #
        if [ $# -le 1 -o "$2" != "-nologs" ]; then 
            SHOW_TECH_LOG_BASENAME=`basename $SHOW_TECH_LOG`
            LOG_FILE_LIST="`cd $NFC_DIR; $LS logs/*.log logs/*.log.[0-9]* 2>/dev/null | $GREP -v $SHOW_TECH_LOG_BASENAME`"
            
            if [ `echo "$LOG_FILE_LIST" | $WC -l` = 0 ]; then
                echo "********** No log files were found in $NFC_DIR/logs **********"
                echo ""
            
            else
                ENCODED_GZIPPED_TARFILE=nfclogfiles.tar.gz
                
                echo "uuencoded data for logfiles in NFC_DIR/logs that were tarred and"
                echo "gzipped follows.  To extract logfiles from the data, copy and paste"
                echo "the data including the begin and end lines into another file and run"
                echo "uudecode on that file, piping standard output to GNU zcat and tar -x."
                echo "Note that there are different options on Solaris and Linux for"
                echo "sending uudecode output to stdout:"
                echo ""
                echo "(Solaris) uudecode -p logdata | gzcat | tar xvf -"
                echo "(Linux)   uudecode -o /dev/stdout logdata | zcat | tar xvf -"
                echo ""
                
                ( cd $NFC_DIR; $TAR cf - `echo $LOG_FILE_LIST` | $GZIP | $UUENCODE $ENCODED_GZIPPED_TARFILE )
            fi
        fi
        
    } | $TEE $TEE_FLAG $SHOW_TECH_LOG 2>&1
}

clean_processes()
{
    create_proc_list

    if [ `echo "$PSLIST" | wc -w` -gt 0 ]; then
        kill -9 $PSLIST
    fi

    rm -f $NFC_DIR/logs/*.pid
}

print_crypto_banner()
{
echo ""
echo "This product contains cryptographic features and is subject to"
echo "United States and local country laws governing import, export,"
echo "transfer and use. Delivery of Cisco cryptographic products does"
echo "not imply third-party authority to import, export, distribute"
echo "or use encryption. Importers, exporters, distributors and users"
echo "are responsible for compliance with U.S. and local country laws."
echo ""
echo "By using this product you agree to comply with applicable laws"
echo "and regulations. If you are unable to comply with U.S. and local"
echo "laws, return this product immediately."
echo ""
echo "A summary of U.S. laws governing Cisco cryptographic products may be"
echo "found at: http://www.cisco.com/wwl/export/crypto/tool/stqrg.html"
echo ""
echo "If you require further assistance please contact us by sending email"
echo "to export@cisco.com."
echo ""
}

if [ "$1" = "start" ]; then
  print_crypto_banner

# Make sure the user running the script is the owner of NFC as specified
# at install time.
  nfcRunsAs=`ls -aldL $NFC_DIR | awk '{ print $3 }'`

  if [ $nfcRunsAs != `whoami` ]; then
    echo "$0: must be run as user $nfcRunsAs"
    exit 1
  fi
fi

if [ "$1" = "start" -a "$2" = "nfcd" ]; then
  $JAVA_HOME/bin/java -DNFC_PROG=pw -cp $CLASSPATH $CONSTANTS com.cisco.nfc.pw.ProcessWatcher $NFC_DIR/config/nfcpw.xml &
  echo $! > $NFC_DIR/logs/nfcpw.pid
  RC=$?
elif [ \( "$1" = stop -a \( "$2" = nfcd -o "$2" = all \) \) -o "$1" = shutdown ]; then
  $JAVA_HOME/bin/java -DNFC_PROG=pwclient -cp $CLASSPATH com.cisco.nfc.pw.PWClient shutdown
  RC=$?
  pwpid=`cat $NFC_DIR/logs/nfcpw.pid 2>/dev/null`
  if [ ! -z "$pwpid" ]; then
    # 'PWClient shutdown' blocks for managed processes to exit starting in 5.0.3;
    # here we're giving the process watcher itself some additional time to exit.
    max_pw_wait_time_secs=20
    pw_wait_time_secs=0
    while [ "`ps -ef | awk '{ print $2 }' | grep $pwpid`" ]; do
        if [ $pw_wait_time_secs -ge $max_pw_wait_time_secs ]; then
            echo "The process watcher failed to stop after $pw_wait_time_secs seconds, exiting."
            exit 1
        fi
        pw_wait_time_secs=`expr $pw_wait_time_secs + 1`
        echo "Waiting for the process watcher to stop..."
        sleep 1
    done
    echo "The process watcher has stopped."
  fi
  rm -f $NFC_DIR/logs/nfcpw.pid
elif [ "$1" = "show-tech" ]; then
  do_show_tech $*
  RC=0
elif [ "$1" = "status" ]; then
  echo ""
  echo "NetFlow Collection Engine Status (`date`)"
  echo "NFC_DIR=$NFC_DIR"
  echo "NFC_XMLCONFIG=$NFC_XMLCONFIG"
  echo ""
  $JAVA_HOME/bin/java -DNFC_PROG=pwclient -cp $CLASSPATH com.cisco.nfc.pw.PWClient status
  RC=$?
elif [ "$1" = "list" ]; then
  $JAVA_HOME/bin/java -DNFC_PROG=pwclient -cp $CLASSPATH com.cisco.nfc.pw.PWClient list
  RC=$?
elif [ "$1" = "clean" ]; then
  clean_processes
  RC=0
elif [ "$1" = "version" ]; then
  echo '6.0.0 [standard image, build 31]'
  RC=0
else
  $JAVA_HOME/bin/java -DNFC_PROG=pwclient -cp $CLASSPATH com.cisco.nfc.pw.PWClient $* > /dev/null 2>&1
  RC=$?
fi

# Check if PWClient failed because ProcessWatcher is not running.
# If so and command is "start", start ProcessWatcher and retry command, unless command was "start all"
# 6/7/2006: set exit status with the retry result
# If PWClient fails with a value of 2 then there was a problem with the command line
# If PWClient fails with 3, one or more processes failed to stop on a shutdown request.
if [ $RC -eq 1 ]; then
  if [ "$1" = "start" ]; then
    $JAVA_HOME/bin/java -DNFC_PROG=pw -cp $CLASSPATH $CONSTANTS com.cisco.nfc.pw.ProcessWatcher $NFC_DIR/config/nfcpw.xml &
    echo $! > $NFC_DIR/logs/nfcpw.pid
    sleep 3
    if [ "$2" = "all" ]; then
      RC=0
    else
      $JAVA_HOME/bin/java -DNFC_PROG=pwclient -cp $CLASSPATH com.cisco.nfc.pw.PWClient $* > /dev/null 2>&1
      RC=$?
    fi
  else
    echo "NFC Process Watcher is not running"
#    exit 1
  fi
elif [ $RC -eq 2 ]; then
  echo "Usage: $0 [[{start | stop} <id>] | status | list | show-tech [-nologs] | shutdown]"
#  exit 1
  RC=1
fi  

# Mimic output of NFC 3.x/4.x status
if [ "$1" = "status" ]; then
    echo ""
    echo "Control Files:"
#   TODO: We should actually get this list of PID files from $NFC_DIR/config/nfcpw.xml
    ls -l $NFC_DIR/logs/*.pid 2> /dev/null
    echo ""
    echo "Process List:"
    create_proc_list 2> /dev/null
    if [ `echo "$PSLIST" | wc -w` -gt 0 ]; then
        ps -f -p "`echo $PSLIST`"
    fi
    echo ""
    echo "Disk Space for ${NFC_DIR}:"
    df -k $NFC_DIR
fi

# Show status if the status of any of the processes has changed
if [ "$1" = "start" -o "$1" = "stop" ]; then
  $JAVA_HOME/bin/java -DNFC_PROG=pwclient -cp $CLASSPATH com.cisco.nfc.pw.PWClient status 2> /dev/null
fi

exit $RC
