#!/bin/sh
# @(#)getfbm.sh                Version 1.21                   3/17/2003
#---------------------------------------------------------------------+
#  Copyright (c)2003 Duc M. Do. All Rights Reserved.                  |
#                                                                     |
#                http://www.thecassandraproject.org/                  |
#                                                                     |
#  This is free software; you can redistribute it and/or modify it    |
#  under the terms of the GNU General Public License as published by  |
#  the Free Software Foundation; either version 2 of the License, or  |
#  (at your option) any later version.                                |
#                                                                     |
#  This software is distributed in the hope that it will be useful,   |
#  but WITHOUT ANY WARRANTY; without even the implied warranty of     |
#  merchantability or fitness for a particular purpose. See the GNU   |
#  General Public License (http://www.fsf.org/copyleft/gpl.htm)for    |
#  more details.                                                      |
#                                                                     |
#  To obtain the GNU General Public License, write to:                |
#                                                                     |
#      Free Software Foundation, Inc.                                 |
#      59 Temple Place - Suite 330                                    |
#      Boston, MA  02111-1307                                         |
#      USA                                                            |
#---------------------------------------------------------------------+

# This file is   getfbm.sh
#
# This script file extract data for FBMs from the checkpoint files. The
# data are readily available in the checkpoint file for each CP, but in
# a format that is not very user-friendly. Additionally, the data format
# is different for the legacy FBMs versus the newer 200-series FBMs, and
# that for the FCM/FBI is different still.
#
# Revision History:
#
#  2/18/03  DMD  0.90  original concept (thanks, Andreas!) and script file
#  2/21/03  DMD  1.00  working model
#  2/28/03  DMD  1.01  add option to print headers or not
#  3/04/03  DMD  1.10  make FBM type determination generic (not dependent
#                      on our naming convention) by using iccprt to print
#                      out the ECB compound to look at HWTYPE; branch the
#                      cassandra version
#  3/05/03  DMD  1.11  add extended FBM notation, but, alas, we cannot get
#                      any more info about the extended modules than this
#                      (Thanks to Jim Kahlden for catching this)
#  3/11/03  DMD  1.20  compile the list of FBMs from the iccprt output
#                      (thanks to Terry Lloyd for this idea)
#  3/17/03  DMD  1.21  fine-tune the legacy FBM regex's using sample
#                      checkpoint files from a couple of beta-testers
#
# Future Enhancements:
#
# - allow getting FBM data from a CP on a remote host (by rmount'ing the
#   remote AW, perhaps?)
# - more info on the extended FBMs?
#
# Bugs List:
#
# - ECB12 and ECB18 intelligent transmitters fail to give up information?
# - FBP (fieldbus processor) and FBC (cluster I/O) info conflict?

#------------------+
# Function section |
#------------------+
#
# function 'usage' echoes the syntax
usage()
{
echo "\nUsage:  getfbm.sh [-n] <CPlbug>\n
        -n:       no headers on output, handy for export to Excel
        <CPlbug>: letterbug ID of a control station\n"
}

#
# function 'headers' prints the report headers if needed
headers()
{
echo "+------------------------------------------------------+"
echo "|              FBM information for $CP              |"
echo "+------------------------------------------------------+"
echo "   FBM     Part   Man H/W  S/W   Serial  PROM   FBM  Ext"
echo "  LbugID  Number Date Rev  Rev   Number   Lvl  Type  FBM"
}

#
# function 'readfcm' uses 'nawk' to extract data for an FCM/FBI
# spaces in the printf statements are important
readfcm()
{
nawk '{if ($1 == fcm) {
          getline
          if (NF == 2 && length($1) == 7 && length($2) == 6) {
             if (flag == "NOHEADER") printf "%6s ", cp
             printf "%6s", fcm                     # letterbug id
             printf "   %7s", $1                   # part number
             printf " %4s", substr($2,3)           # manufacturing date
             printf "  %2s", substr($2,1,2)        # hardware revision
             getline
             printf " %5-s\n", $1                  # software revision
             ++found                               # once we find both FCMs...
             if (found >= 2) exit                  # disregard the rest
          }
       }
     }
     END {if (found == 0) print fcm}' fcm=$1 flag=$NFLAG cp=$CP $CP.out
}

#
# function 'readlegacyfbm' uses 'nawk' to extract data for a legacy FBM
# spaces in the printf statements are important
readlegacyfbm()
{
EXT=0
EXT=`nawk '{if ($1 == "DEV_ID" && $3 == fbm) {     # match fbm ...
               getline; getline; getline           # ... skip a few
               print $3}                           # save the EXTYPE
           }' fbm=$1 $CP.ecb`
nawk '{if ($1 ~ fbm) {                             # match fbm id ...
          getline                                  # ... go to next line
          if ($1 ~ fbm) {                          # match it again ...
             getline                               # ... go to next line
             while (($1 !~ /\./ || length($1) < 28) && i < 10) {
                getline                            # skip up to 10 lines that
                ++i                                # has no period or has
             }                                     # less than 28 chars
             if ($1 ~ /[0-9][A-Za-z][A-Za-z0-9_\-]*\.[0-9]*/) {
                printf "  %6s", fbm                # letterbug id
                printf " %7s", substr($1,2,7)      # part number
                printf " %4s", substr($1,13,4)     # manufacturing date
                printf "  %2s", substr($1,9,2)     # hardware revision
                printf " %5-s", substr($1,25)      # software revision
                printf " %8s", substr($1,17,8)     # serial number
                getline
                if ($1 ~ /[0-9]*\.[0-9]*/) eeprom=$1
                else                       eeprom=""
                printf " %5-s", eeprom             # EEPROM level
                printf " %4s", type                # fbm type
                if (extfbm == 0) printf "\n"       # finish the line
                else printf " %4s\n", extfbm       # extended fbm type
                ++found                            # once we find the FBM...
                exit                               # disregard the rest
             }
          }
       }
      }
      END {if (found == 0) print "  " fbm}' fbm=$1 type=$2 extfbm=$EXT $CP.out
}

#
# function 'read200fbm' uses 'nawk' to extract data for a 200-series FBM
# spaces in the printf statements are important
read200fbm()
{
nawk '{if ($1 ~ fbm) {                             # match fbm ...
          getline                                  # ... go to next line
          if ($1 ~ fbm) {                          # match it again ...
             getline                               # ... go to next line
             while ($1 !~ /[A-Z][0-9][0-9][0-9][0-9][A-Z][A-Z]/ && i < 5) {
                getline                            # skip up to 5 lines
                ++i                                # that dont match the
             }                                     # alphanumeric pattern
             if (NF == 1) {
                model=$1                           # save the part number
                getline                            # go to next line
                if (NF == 2 && $2 ~ /[0-9]+\.[0-9]+/) {
                   printf "  %6s", fbm             # letterbug id
                   printf " %7s", model            # part number
                   printf " %4s", substr($1,5,4)   # manufacturing date
                   printf "  %2s", substr($1,1,2)  # hardware revision
                   printf " %5-s", $2              # software revision
                   printf " %8s", substr($1,9,8)   # serial number
                   type=substr($1,17)              # save the fbm type
                   getline                         # go to next line
                   printf " %5-s", $2              # EEPROM level
                   printf " %4s\n", type           # fbm type
                   ++found                         # once we find the FBM...
                   exit                            # disregard the rest
                }
             }
             else if (NF == 3 && $3 ~ /[0-9]+\.[0-9]+/) {
                printf "  %6s", fbm                # letterbug id
                printf " %7s", $1                  # part number
                printf " %4s", substr($2,5,4)      # manufacturing date
                printf "  %2s", substr($2,1,2)     # hardware revision
                printf " %5-s", $3                 # software revision
                printf " %8s", substr($2,9,8)      # serial number
                type=substr($2,17)                 # save the fbm type
                getline                            # go to next line
                printf " %5-s", $2                 # EEPROM level
                printf " %4s\n", type              # fbm type
                ++found                            # once we find the FBM...
                exit                               # disregard the rest
             }
          }
       }
      }
      END {if (found == 0) print "  " fbm}' fbm=$1 $CP.out
}

#-------------+
# Main script |
#-------------+
if [ $# -lt 1 ]; then usage; exit 1; fi

# use 'getopts' to parse the command line for options
NFLAG=""
while getopts n opt
do
    case $opt in
        n)  NFLAG=NOHEADER;;   # no headers, good for export to Excel
    esac
done
shift `expr $OPTIND - 1`

CP=`echo $1 | tr '[a-z]' '[A-Z]'`
# check to see if this CP is real
if [ "`grep $CP /etc/cplns`" = "" ]
then echo "\n`basename $0`: $CP is non-existent\n"; exit 1
fi

# set up the temp directory and a couple of needed variables
TMP=/tmp
IIF=/usr/fox/sp/IIF.pkg
HOST=`grep $CP /usr/fox/sp/sldb | awk '{print $2}'`   # CP boot host
MYNAME=`uname -n`                                     # current node name

# proceed only if we are on the CP's boot host
if [ "$MYNAME" = "$HOST" ]
then
    strings /usr/fox/sp/files/DB$CP.UC > $TMP/$CP.out
    cd /opt/fox/ciocfg/api; ./iccprt -p -n \*_ECB:\* -o $TMP/$CP.ecb $CP
    nawk '/DEV_ID/ {print $3}' $TMP/$CP.ecb > $TMP/$CP.fbm
else
    echo "\n`basename $0`: $MYNAME is not the boot host for $CP\n"
    exit 1
fi

# print the headers unless it was specified not to with -n
if [ "$NFLAG" != "NOHEADER" ]; then headers; fi
cd $TMP

# loop through for each FBM found for this CP
for fbm in `cat $CP.fbm`
do
    HWTYPE=`nawk '{if ($1 == "DEV_ID" && $3 == fbm) { # match fbm ...
                      getline                         # ... go to next line
                      print $3}                       # save the hw type
                  }' fbm=$fbm $CP.ecb`
    if [ $HWTYPE -lt 200 ]     # this is a legacy FBM
    then
        if [ "$NFLAG" = "NOHEADER" ]; then echo "$CP \c"; fi
        readlegacyfbm $fbm $HWTYPE
    elif [ $HWTYPE -eq 200 ]   # this is an FCM/FBI
    then
        readfcm $fbm
    else                       # this is a 200-series FBM
        if [ "$NFLAG" = "NOHEADER" ]; then echo "$CP \c"; fi
        read200fbm $fbm
    fi
done

# clean up
rm $CP.out $CP.ecb $CP.fbm 2> /dev/null

