#!/usr/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 52is220 src/bos/usr/sbin/invscout/VPD_Survey/invscout_lsvpd.sh 1.8 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2007,2010 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)34        1.8  src/bos/usr/sbin/invscout/VPD_Survey/invscout_lsvpd.sh, cmdinvscout, 52is220, 1041A_52is220 9/29/10 16:03:03
#############################################
#                                           #
# The goal of this script is to create vpd  #
# data for enclosures that do not have it   #
# so devices in those enclosures can  be    #
# placed when creating the XML VPD file.    #
#                                           #
#############################################

#Global Variables                           
ADP_ENC_ARRAY=""
ENC_ARRAY=""
FOUND_FC="FALSE"
FIELD_1=""
FIELD_2=""

#############################################
#                                           #
#              print_enclr                  #
# Inputs: Enclosure location code           #
# Outputs: Creates and prints vpd output    #
# for unknown devices to stdout             #
#                                           #
#############################################

print_enclr()
{
   # FC field required object delimeter
   echo "*FC ********"
   # DS description of the device
   echo "*DS Unknown Enclosure"
   # YL Physical location code of enclosure
   echo "*YL $1"
   # TM Required for invscout.  TM requires -
   echo "*TM 0000-000"
   # SE Required 7 characters
   echo "*SE 0000000"
   return 0
}

#############################################
#                                           #
#              test_enclsr                  #
# Inputs: Enclosure location code           #
# Outputs: None                             #
# Fucntion: Tests to see if enclosure is in #
# existing VPD output                       #
#                                           #
#############################################

test_enclsr() {

   # Initialize exist flag to false
   flag=FALSE
   
   # For all existing enclosures compare to
   # new input.  If it exists, then do nothing
   
   for i in ${ENC_ARRAY}
   do
      if [ $1 = ${i} ]
      then
         flag=TRUE # Exists so exit loop and
                   # ignore the rest
         break
      fi
 
   done

   # Compare flag to see if the device exists
   # in the lsvpd output 
   # FALSE = NO TRUE = YES
   if [ ${flag} = "FALSE" ]
   then
      # call print function to create and append
      # the enclosure vpd to the lsvpd output
      print_enclr "$1"
   fi
   
   #return success
   return 0 
}

############################################
#                                          #
#             check_for_FC                 #
#                                          #
# Inputs: $1                               #
#         $1 lsvpd second field            #
#                                          #
############################################
check_for_FC ()
{
   FOUND_FC="FALSE"
   FIELD="$1"
   case "${FIELD}" in

      *"*FC ========"*)
         FIELD_1="${FIELD%%"*FC ========"*}"
         FIELD_2="========"
         FOUND_FC="TRUE";
      ;;

      *"*FC ********"*)
         FIELD_1="${FIELD%%"*FC ********"*}"
         FIELD_2="********"
         FOUND_FC="TRUE";
         ;;

      *"*FC ????????"*)
         FIELD_1="${FIELD%%"*FC ????????"*}"
         FIELD_2="????????"
         FOUND_FC="TRUE";
         ;;
      *)
         FOUND_FC="FALSE";
      ;;

   esac
}

############################################
#                                          #
#             add_enclosure                #
#                                          #
# Inputs: $1 and $2                        #
#         $1 determines how we were called #
#         $2 is the location code we were  #
#         called with                      #
# Ouputs: Creates global arrays            #
#         containing locations from        #
#         adapters and enclosures          #
#                                          #
############################################
         
add_enclosure(){
   # Existence flag initialized to FALSE
   flag=FALSE
   # If we were called with an Adapter's enclosure
   # then add to ADP_ENC_ARRAY if it is not present
   # in the array. 
   # ELSE add to ENC_ARRAY if it is not present 
   # in the enclosure array.  
   if [ "$1" -eq 0 ]
   then
      # check all current adapter enclosures
      # to see if the location code is present 
      for i in ${ADP_ENC_ARRAY}
      do
         if [ ${i} = "$2" ]
         then
            # Set the flag true and break from
            # the loop to stop processing other
            # array elements.  
            flag=TRUE;
            break
         fi
      done

      # Check to see if we were found in the array 
      # TRUE = Yes, False = No
      # If we were not found add ourselves to
      # the list 
      if [ ${flag} = "FALSE" ]
      then
         ADP_ENC_ARRAY="${ADP_ENC_ARRAY} $2"
      fi
   
   else
      # We were called with an Enclosures location
      # code so elements go in ENC_ARRAY
      # check all current enclosures locations
      # to see if we are present in the array
      
      for i in ${ENC_ARRAY}
      do
         if [ ${i} = "$2" ]
         then
            # Set the flag true and break from
            # the loop to stop processing other
            # array elements.  
            flag=TRUE;
            break
         fi
      done

      # Check to see if we were found in the array 
      # TRUE = Yes, False = No
      # If we were not found add ourselves to
      # the list 
      if [ ${flag} = "FALSE" ]
      then
         ENC_ARRAY="${ENC_ARRAY} $2"
      fi
   fi
   # return success
   return 0
}

############################################################
#                                                          #
#                                                          #
#                       build_array                        #
#                                                          #
# Inputs - $1 = VPD Attribute                              #
#          $2 = VPD Attribute Value                        #
#                                                          #
# Function adds all enclosures to an array of enclosure    #
# location codes                                           #
#                                                          #
############################################################
build_array()
{
   # If VPD attribute is a location code then check 
   # to see if it is an enclosure or other device         
   if [ "$1" = "*YL" ]
   then
      case "$2" in
      *-*)
          # We are "other device"
          # Remove everything but the location code
          # for the enclosure this belongs to
          enclosure=${2%%-*}
          # Add enclosure to array if it doesn't already
          # exist
          add_enclosure 0 "${enclosure}";
      ;;
      *)
          # We are an "enclosure"
          # Enclosure location is already in the form we need
          # so we add it to the array if it doesn't already
          # exist
          enclosure="$2"
          add_enclosure 1 "${enclosure}";
      ;;
      esac
   fi
   # Return success
   return 0
}

##############################################
#                    Main                    #
# Inputs:  None                              #
# Output:  /usr/sbin/lsvpd  -m stdout with   #
#          appended VPD data created for     #
#          enclsures without VPD from the    #
#          lsvpd command.                    #
# Errors:  stderr from lsvpd                 #
##############################################
# Because we are a wrapper for the lsvpd
# command we first want to run lsvpd -m 
# (-m returns ?? ** == instead of just ?? )
# Then we want to read line by line and parse
# the output from lsvpd.  We first print each 
# line to stdout because we want the raw
# data from lsvpd.  If we are not successfull
# then we do not wrap anything and just
# return the error code and stderr and let
# invscout process it.  

TMP_FILE=/var/adm/invscout/invtemp.log
OLD_LANG=$LANG
LANG=C
/usr/sbin/lsvpd -m > $TMP_FILE
rc=$?
LANG=$OLD_LANG

if [ ${rc} -ne 0 ]
then
# Errors so return error
# return code from lsvpd 
# but output whatever it gave
# us so we have stdout and
# stderror
  while read line
        do
        print "${line}"
        done > $TMP_FILE
   exit ${rc} 
fi

# IFS - Internal Field Seperator
# aka - delimeter
# IFS is by default \t \n and " "
# We need to keep the white space so
# we change the IFS to use it as a char
# instead of white space
# but we first want to save the original
# values of it

OLD_IFS="${IFS}"
IFS=\\n

while read line
                 do {
                    # We need to set the IFS back to 
                    # original values because we want to again
                    # use white space as a seperator field
                    IFS="${OLD_IFS}"

                    # Echo the output to stdout
                    # for inventory scout to
                    # process
                    # Parse lsvpd output and 
                    # create arrays for all
                    # enclosure locations present
                    # in lsvpd's output
                    # Break the line into it's two inputs
                    # and assign them to vars.  Then call
                    # build array enclosing them in quotes
                    # to build the array properly.  
                    # We must do this to avoid sending in a 
                    # single variable and also avoid having
                    # the wildcard char (*) replaced with
                    # filenames
 
                    var1="${line%%" "*}"
                    var2="${line#*"${var1} "}"
		    FOUND_FC="FALSE";
                    if [ "${var1}" != "${var2}" ]
                    then
		       check_for_FC "${var2}"
		       if [ "${FOUND_FC}" == "TRUE" ]
                       then
                          build_array "${var1}" "${FIELD_1}"
                          build_array "*FC" "${FIELD_2}"
                       else
                          build_array "${var1}" "${var2}";
		       fi
                    fi
                    if [ "${FOUND_FC}" == "TRUE" ]
                    then
                       print "${var1}" "${FIELD_1}"
		       print "*FC" "${FIELD_2}"
                    else
                       print "${line}"
                    fi
                 
                 # IFS has to go back to only using new lines
                 # for the next loop iteration
                 IFS=\\n
                 }
                 done < $TMP_FILE

   # Now that we are done we need to reset IFS so the rest of
   # the program can use the IFS as the default
   IFS="${OLD_IFS}"
   # Compare enclosure location codes in the 
   # arrays and print out newly created enclosures
   # so they will be appended to the output
   # of lsvpd for invscout to process
   for i in ${ADP_ENC_ARRAY}
   do
      test_enclsr "${i}"
   done   
   # Return success
   return 0
