#!/bin/bash

# **************************** LICENSE START ***********************************
#
# Copyright 2012 ECMWF and INPE. This software is distributed under the terms
# of the Apache License version 2.0. In applying this license, ECMWF does not
# waive the privileges and immunities granted to it by virtue of its status as
# an Intergovernmental Organization or submit itself to any jurisdiction.
#
# ***************************** LICENSE END ************************************

#                                                (vk Sep-95, rev 020904)
#
# This is a common version of SGI specific script 'mvrun' that
# has been written only for ECMWF and it has not been
# designed to be portable...
#
# Script executes a metview module and reports crashes by mail.
# (within time this script has grown toooo looooooonnnngggggggg!)

set +e
Module=`basename $1`
start_date=`date`
running_bin="`ls -l $1 | cut -c43-`"
send_mail=NO

#-- these ok for sgimips & rs6000:
MV_DBG=dbx
MV_MAIL=/usr/bin/mail

if [ X$ARCH = Xlinux ]
then
  MV_DBG=gdb
  MV_MAIL=mail
fi

#-- execute module, with possible parameters
if [ $METVIEW_LOG = no_log -o "$METVIEW_LOG" = "-" ]
then
  "$@"
  SUCCESS_STATUS=$?
else
  if [ "$OS" = "hpcf" ]
  then
    MVLOGROOT="$TEMP"
  else
    MVLOGROOT="$SCRATCH"
  fi
  
  MYLOG="$MVLOGROOT/$METVIEW_LOG.$Module.log"
  echo "[mvrun_c info] process $$ starting `date` with cmd:" >| $MYLOG
  echo "[mvrun info] $@"                    >> $MYLOG
  echo "[mvrun info] MAG_HOME = $MAG_HOME"  >> $MYLOG
  echo "[mvrun info] mode is $METVIEW_MODE" >> $MYLOG
  echo " " >> $MYLOG

  /usr/bin/time "$@"      2>&1 | tee -a $MYLOG > /dev/null
  SUCCESS_STATUS=$?

  echo " " >> $MYLOG
  echo "[mvrun info] process $$ ended `date`" >> $MYLOG
  echo "[mvrun info] process exit status was $SUCCESS_STATUS" >> $MYLOG

  #-- if development macro log then no mail => exit
  if [ X$METV_DEV = Xyes ]
  then
    exit $SUCCESS_STATUS
  fi
fi

st_sig=`expr $SUCCESS_STATUS / 128`
st_signal=`expr $SUCCESS_STATUS % 128`
#-- (x:y) were used when divided by 16, now [x:y] when div 128
st_text="$SUCCESS_STATUS [$st_sig:$st_signal]"

current_bin="`ls -l $1 | cut -c43-`"
if [ "$running_bin" != "$current_bin" ]
then
  st_text="UPDATED!"
fi

MVUSERID=$USER
[ "$MVUSERID" = "" ] && MVUSERID=$LOGNAME
[ "$MVUSERID" = "" ] && MVUSERID="???"

if [ $st_sig -ne 0 ]
then
  send_mail=YES
  case $st_signal in
    1)
      send_mail=NO
      ;;
    2)
      send_mail=NO
      ;;
    4)
      st_reason="Illegal Instruction"
      ;;
    5)
      st_reason="Trace/Breakpoint Trap"
      ;;
    6)
      st_reason="Abort"
      ;;
    7)
      st_reason="Emulation Trap"
      ;;
    8)
      st_reason="Arithmetic Exception"
      ;;
    10)
      st_reason="Bus Error"
      ;;
    11)
      st_reason="Segmentation Fault"
      ;;
    12)
      st_reason="Bad System Call"
      ;;
    *)
      send_mail=NO
      st_reason="(reason not decoded)"

      MV_CRASH_LOG="/home/graphics/cgx/public/Metview_crashlog_nomail"
      if [ ! -f $MV_CRASH_LOG ]
      then
        touch $MV_CRASH_LOG
        chmod 666 $MV_CRASH_LOG
        #-- give file to cgx (not to decrease users available disk quota) --
        chown cgx $MV_CRASH_LOG
      fi
      #echo "`date -u '+%d.%m.%Y %R'`; $Module; `echo $METVIEW_MODE | cut -c1`; $st_text; $MVUSERID; `hostname`; `cat $METVIEW_DIR_SHARE/app-defaults/MvTitleBarVersionText`" >> $MV_CRASH_LOG
      echo "`date -u '+%d.%m.%Y %R'`; $MVUSERID; `echo $METVIEW_MODE | cut -c1`; $st_text; $Module; `hostname`; $METVIEW_VERSION_TITLE" >> $MV_CRASH_LOG
      ;;
  esac
fi

#-- is this a Graphics Section user id --#
graph_uid=NO
if [ X`echo $MVUSERID | cut -c 1-2` = Xcg ]
then
  graph_uid=YES
fi

#-- do the hard work if really crashed and not Graphics id
if [ $send_mail = YES ]
then
  UserMsg=/tmp/crash_$$.$Module.UserMsg
  MailMsg=/tmp/crash_$$.$Module.MailMsg
  Person=`finger $LOGNAME | grep "name: $LOGNAME" | cut -f3 -d: | head -1`

  #-- log into logfile --
  MV_CRASH_LOG="/home/graphics/cgx/public/Metview_crashlog_`cat $METVIEW_DIR_SHARE/app-defaults/MvVersion`"
  if [ ! -f $MV_CRASH_LOG ]
  then
    touch $MV_CRASH_LOG
    chmod 666 $MV_CRASH_LOG
    #-- give file to cgx (not to decrease users available disk quota) --
    chown cgx $MV_CRASH_LOG
  fi
  #-- new crash file format 25.3.1998, add METVIEW_MODE first letter 6.8.1998 --
  #-- 2000-08-18: make column widths more even i.e. constant width values first --
  echo "`date -u '+%d.%m.%Y %R'`; $MVUSERID; `echo $METVIEW_MODE | cut -c1`; $st_text; $Module; `hostname`; `cat $METVIEW_DIR_SHARE/app-defaults/MvTitleBarVersionText`" >> $MV_CRASH_LOG

  #-- inform user about crash and core --
  echo " " >> $UserMsg
  echo "This is an automatic message to Metview user $Person:"    > $UserMsg
  echo "a module '$Module' just crashed in your Metview session !">>$UserMsg

  if [ "$running_bin" != "$current_bin" ]
  then
    echo " " >> $UserMsg
    echo " " >> $UserMsg
    echo "________THIS CRASH WAS CAUSED BY A METVIEW UPDATE !!!!!" >> $UserMsg
  fi
  echo "________" >> $UserMsg
  echo " " >> $UserMsg

  if [ -s core ]
  then
    echo "You have the following core file in your directory:" >> $UserMsg
    ls -l core >> $UserMsg
    file core >> $UserMsg
    echo "________" >> $UserMsg
    echo " " >> $UserMsg
    #-- ecquota is an ECMWF modification for HP servers --
    ecquota -v >> $UserMsg
  else
    echo "No core file was produced or the core file is empty !" >> $UserMsg
  fi
  echo " " >> $UserMsg

  if [ "$running_bin" = "$current_bin" ]
  then
   echo "    +------------------------------------------------------+">>$UserMsg
   echo "    |      A Metview module has crashed unexpectedly!      |">>$UserMsg
   echo "    |     Sorry for the trouble it may have caused you.    |">>$UserMsg
   echo "    |                                                      |">>$UserMsg
   echo "    | If this happens repeatedly then please contact us.   |">>$UserMsg
   echo "    | We would be very happy to have a look at the problem |">>$UserMsg
   echo "    | in order to fix it as soon as possible.              |">>$UserMsg
   echo "    |                                                      |">>$UserMsg
   echo "    |          Software Applications Team, ECMWF           |">>$UserMsg
   echo "    +------------------------------------------------------+">>$UserMsg
   echo " " >> $UserMsg
  fi

  [ -s core ] && echo "Check your disk quota" >> $UserMsg
  echo "  M e t v i e w" >> $UserMsg

  if [ $graph_uid = YES ]
  then
    echo " " >> $UserMsg
    echo " ($MVUSERID is Graphics User Id => no email will be sent!)" >> $UserMsg
  fi

  if [ $METVIEW_MODE = batch ]
  then
    $MV_MAIL $MVUSERID < $UserMsg
  else
    xterm -title "Metview Crash Info" -bg gray -fg red4 -b 12 -e view $UserMsg &
    #-- try to make sure window appears even when network is slow...
    sleep 15
  fi

  #-- inform Metview group by mail --
  SUBJ="Mv_$METVIEW_RELEASE-$Module-crash"
  cat $METVIEW_DIR_SHARE/app-defaults/MvTitleBarVersionText >> $MailMsg
  echo " " >> $MailMsg
  echo "$Module: $st_reason! (status=$SUCCESS_STATUS: code=$st_sig, signal=$st_signal)" >> $MailMsg
  echo "User is $MVUSERID:$Person on `hostname` (informed)" >> $MailMsg

  #-- phone number is an ECMWF command!!!
  pn "\[$MVUSERID" >> $MailMsg

  echo " " >> $MailMsg
  echo "Started: $start_date" >> $MailMsg
  echo "Crashed: `date`" >> $MailMsg
  echo " " >> $MailMsg
  echo "Crashed binary: $running_bin" >> $MailMsg
  echo "Current binary: $current_bin" >> $MailMsg
  if [ "$running_bin" != "$current_bin" ]
  then
    echo " " >> $MailMsg
    echo "!!!!!! CRASH DUE TO EXECUTABLE UPDATE !!!!!" >> $MailMsg
  fi
  echo " " >> $MailMsg

  if [ -s core ]
  then
    CoreOk=`file core | grep $Module`
    file core >> $MailMsg
    echo "file etc.: `ls -l core | cut -c17-`" >> $MailMsg
    echo "directory: `pwd`" >> $MailMsg
    chmod 777 core

    if [ "$CoreOk" != "" ]
    then
      #-- examine call stack, redirect & tee to catch crash reason
      echo " " >> $MailMsg
      echo "where;quit" | $MV_DBG $1 core 2>&1 | tee -a $MailMsg
    else
      echo " " >> $MailMsg
      echo "Wrong core file !" >> $MailMsg
    fi
  else
    echo "No core file or core file empty !" >> $MailMsg
  fi

  if [ $graph_uid = NO ]
  then
    #-- do not use full address 'name-at-ecmwf-dot-int'
    METVIEW_SUPPORT_MAIL=${METVIEW_SUPPORT_MAIL:=metviewbugs}
    $MV_MAIL -s $SUBJ $METVIEW_SUPPORT_MAIL < $MailMsg
    # $MV_MAIL -s $SUBJ cgh < $MailMsg
  fi

  rm -f $MailMsg
  rm -f $UserMsg
fi
exit $SUCCESS_STATUS
