#! /bin/sh
#=======================================================================#
# - COPYRIGHT NOTICE -                                                  #
#                                                                       #
# Copyright 2000-2006 OpenSpirit Corporation.                           #
#                                                                       #
# The information contained herein and which follows is proprietary     #
# information and is the property of OpenSpirit Corporation. This       #
# information is not to be divulged, released, copied, reproduced,      #
# or conveyed to unauthorized personnel, companies, or other            #
# institutions without the direct and expressed approval in writing     #
# of OpenSpirit Corporation.                                            #
#                                                                       #
#=======================================================================#
#
# This script attempts to check to see if the required OS patches
# are present on the machine for Java JRE(s) used by OpenSpirit
#

PATH=/bin:/usr/bin:$PATH; export PATH

# --------------------------------------------------------------------------------
# Internal routines come first
# --------------------------------------------------------------------------------
# Generate a temp file with the SunOS_5.6 JRE required patches info
genSunOS56() {
   if [ $# -ne 1 ]; then
      printf "$0: Error - genSunOS56() args: tmpfile\n"
      return 1
   fi

   file=$1
   cat <<- EOF > $file
	# These are the Solaris_JDK_1.4 required patch list from Sun, this information
	# can be found at http://java.sun.com/j2se/1.4/install-solaris.html and
	# http://patches.sun.com/clusters/J2SE_Solaris_2.6_Recommended.README
	# The format is the patch-revision number and information about it.
	#
	#Patch Id Description
	#-------------------------------------------------------------
	# 112542-01  SunOS 5.6: fgrep fails with "wordlist too large"
	107733-11  SunOS 5.6: linker patch
	106125-16  SunOS 5.6: Patch for patchadd and patchrm
	105181-39  SunOS 5.6: Kernel update patch
	105210-52  SunOS 5.6: libaio, libc & watchmalloc patch
	105568-26  SunOS 5.6: /usr/lib/libthread.so.1 patch
	105591-20  SunOS 5.6: Shared library patch for C++
	105633-64  OpenWindows 3.6: Xsun patch
	105669-11  CDE 1.2: libDtSvc Patch
	105284-50  Motif 1.2.7: Runtime library patch
	106841-01  OpenWindows 3.6: Keytables patch
	106842-09  SunOS 5.6: Feature patch for Euro currency support in Solaris 2.6
	106123-05  SunOS 5.6: sgml patch
	106040-18  SunOS 5.6: X Input & Output Method patch
	# 106409-01  SunOS 5.6: Fixes the Traditional Chinese TrueType fonts
	108091-03  SunOS 5.6: ssJDK1.2.1_03 fails with fatal error in ISO8859-01 Locales
	EOF
}

# --------------------------------------------------------------------------------
# Generate a temp file with the SunOS_5.7 JRE required patches info
genSunOS57() {
   if [ $# -ne 1 ]; then
      printf "$0: Error - genSunOS57() args: tmpfile\n"
      return 1
   fi

   file=$1
   cat <<- EOF > $file
	# These are the Solaris_JDK_1.4 required patch list from Sun, this information
	# can be found at http://java.sun.com/j2se/1.4/install-solaris.html and
	# http://patches.sun.com/clusters/J2SE_Solaris_7_Recommended.README
	# The format is the patch-revision number and information about it.
	#
	#Patch Id Description
	#-------------------------------------------------------------
	107544-03  SunOS 5.7: /usr/lib/fs/ufs/fsck patch
	107834-04  SunOS 5.7: dkio.h & commands.h patch
	106541-41  SunOS 5.7: Kernel Update Patch
	106980-26  SunOS 5.7: libthread patch
	106950-24  SunOS 5.7: Linker Patch
	106327-23  SunOS 5.7: 32-Bit Shared library patch for C++
	108376-45  OpenWindows 3.6.1: Xsun Patch
	106300-24  SunOS 5.7: 64-Bit Shared library patch for C++
	107702-12  CDE 1.3: dtsession patch
	108374-07  CDE 1.3: libDtWidget Patch
	107656-11  OpenWindows 3.6.1 libXt Patch
	107081-57  Motif 1.2.7 and 2.1.1: Runtime library patch for Solaris 7
	107226-19  CDE 1.3: dtwm patch
	107636-10  SunOS 5.7: X Input & Output Method patch
	# 107153-01  SunOS 5.7: There are three characters missed in zh.GBK songti.ttf
	EOF
}

# --------------------------------------------------------------------------------
# Generate a temp file with the SunOS_5.8 JRE required patches info
genSunOS58() {
   if [ $# -ne 1 ]; then
      printf "$0: Error - genSunOS58() args: tmpfile\n"
      return 1
   fi

   file=$1
   cat <<- EOF > $file
	# These are the Solaris_JDK_1.4 required patch list from Sun, this information
	# can be found at http://java.sun.com/j2se/1.4/install-solaris.html and
	# http://patches.sun.com/clusters/J2SE_Solaris_8_Recommended.README
	# The format is the patch-revision number and information about it.
	#
	#Patch Id Description
	#-------------------------------------------------------------
	112396-02  SunOS 5.8: /usr/bin/fgrep patch
	111111-04  SunOS 5.8: /usr/bin/nawk patch
	108987-17  SunOS 5.8: Patch for patchadd and patchrm
	109147-37  SunOS 5.8: linker patch
	108652-92  X11 6.4.1: Xsun patch
	108921-23  CDE 1.4: dtwm patch
	108940-68  Motif 1.2.7 and 2.1.1: Runtime library patch for Solaris 8
	111310-01  SunOS 5.8: /usr/lib/libdhcpagent.so.1 patch
	108528-29  SunOS 5.8: kernel update  and Apache patch
	112003-03  SunOS 5.8: Unable to load fontset in 64-bit Solaris 8 iso-1 or iso-15
	108989-02  SunOS 5.8: /usr/kernel/sys/acctctl and /usr/kernel/sys/exacctsys patch
	112472-01  SunOS 5.8: Font2DTest2 abort when Lucida Sans Thai Typewriter selected
	111308-05  SunOS 5.8: /usr/lib/libmtmalloc.so.1 patch
	112438-03  SunOS 5.8: /kernel/drv/random patch
	108434-18  SunOS 5.8: 32-Bit Shared library patch for C++
	110386-03  SunOS 5.8: RBAC Feature Patch
	111023-03  SunOS 5.8: /kernel/fs/mntfs and /kernel/fs/sparcv9/mntfs patch
	111317-06  SunOS 5.8: /sbin/init and /usr/sbin/init patch
	113648-04  SunOS 5.8: mount patch
	115827-01  SunOS 5.8: /sbin/sulogin and /sbin/netstrategy patch
	116602-01  SunOS 5.8: /sbin/uadmin and /sbin/hostconfig patch
	108993-48  SunOS 5.8: LDAP2 client, libc, libthread and libnsl libraries patch
	109326-17  SunOS 5.8: libresolv.so.2 and in.named patch
	108435-18  SunOS 5.8: 64-Bit Shared library patch for C++
	110615-13  SunOS 5.8: sendmail patch
	117000-05  SunOS 5.8: Kernel Patch
	113886-30  OpenGL 1.3: OpenGL Patch for Solaris (32-bit)
	108773-19  SunOS 5.8: IIIM and X Input & Output Method patch
	117350-26  SunOS 5.8: kernel patch
	113887-30  OpenGL 1.3: OpenGL Patch for Solaris (64-bit)
	111721-04  SunOS 5.8: Math Library (libm/fabsf) patch
	EOF
}

# --------------------------------------------------------------------------------
# Generate a temp file with the SunOS_5.9 JRE required patches info
genSunOS59() {
   if [ $# -ne 1 ]; then
      printf "$0: Error - genSunOS59() args: tmpfile\n"
      return 1
   fi

   file=$1
   cat <<- EOF > $file
	# These are the Solaris_JDK_1.4 required patch list from Sun, this information
	# can be found at http://java.sun.com/j2se/1.4/install-solaris.html and
	# http://patches.sun.com/clusters/J2SE_Solaris_9_Recommended.README
	# The format is the patch-revision number and information about it.
	#
	#Patch Id Description
	#-------------------------------------------------------------
	113096-03  X11 6.6.1: OWconfig patch
	111711-12  SunOS 5.9: 32-bit Shared library patch for C++
	111712-12  SunOS 5.9: 64-Bit Shared library patch for C++
	112963-22  SunOS 5.9: linker Patch
	113886-30  OpenGL 1.3: OpenGL Patch for Solaris (32-bit)
	113887-30  OpenGL 1.3: OpenGL Patch for Solaris (64-bit)
	112785-49  X11 6.6.1: Xsun patch
	111722-04  SunOS 5.9: Math Library (libm/fabsf) patch
	EOF
}

# --------------------------------------------------------------------------------
# Generate the proper SunOS patch file for 'checkSunOS'
generateSunOSPatchFile() {
   if [ $# -ne 2 ]; then
      printf "$0: Error - generateSunOSPatchFile() args: osVer tmpfile\n"
      return 1
   fi

   OSVER=$1
   tmpf=$2
   rm -f $tmpf

   case "$OSVER" in
      5.6) genSunOS56 $tmpf
         ;;
      5.7) genSunOS57 $tmpf
         ;;
      5.8) genSunOS58 $tmpf
         ;;
      5.9) genSunOS59 $tmpf
         ;;
        *) printf "Error: Do not recognize SunOS version \"%s\"\n" $OSVER
         ;;
   esac
}

# --------------------------------------------------------------------------------
# This routine will only work for SunOS machines (they have the 'showrev' command)
checkSunOS()
{
   if [ $# -ne 1 ]; then
      printf "$0: Error - checkSunOS() usage: checkSunOS <osVer>\n"
      return 1
   fi

   OSVER=$1

   tmpfile=/tmp/__patch_check_$OSVER_$$
   generateSunOSPatchFile $OSVER $tmpfile

   PATCHFILE=$tmpfile
   if [ ! -r $PATCHFILE ]; then
      echo "Error: Cannot find the required patch file: $PATCHFILE"
      return 1
   fi

   printf "Checking for recommended and required patches for %s-%s\n" $os_name $os_ver
   printf "Sun machine is: %s\n\n" "`uname -a`"

   showrev -p | \
   nawk -v patchfile=$PATCHFILE '\
   function getPatches( Filename )
   {
      if (system("test -r " Filename) != 0) {
         print "*** ERROR:" Filename " does not exist or is not readable."
         return 2
      }
      while (stat = getline <Filename == 1) {
         # skip comment lines
         if (substr($0, 1, 1) == "#") {
            continue
         }
         n = split($0, a)
         # make a good faith effort to handle screwy input
         if (n == 1) {
            m = split(a[1], b, "-")
            if (m == 2) {
               patchNum[num]  = b[1]
               patchRev[num]  = b[2]
               patchNote[num] = "Unknown"
            }
            else {
               print "*** WARNING: cannot split patch into number-revision"
            }
         }
         else if (n >= 2) {
            m = split(a[1], b, "-")
            if (m == 2) {
               patchNum[num]  = b[1]
               patchRev[num]  = b[2]
               # in order to get the patch note, it is everything in $0 except a[1]
               pn = sub(a[1]" ", "", $0)
               patchNote[num] = $0
            }
            else {
               print "*** WARNING: cannot split patch into number-revision"
            }
         }
         else {
            print "*** ERROR: cannot read required patch file."
            print "Line was: " $0
            return 2
         }
         havePatch[num] = 0
         num++
      }
      close(Filename)
      return 0
   
   }
      
   BEGIN {
   
      # Set the return code
      rc = 0
      # Suck up the patchlevel file
      num=0
      if ((rc = getPatches(patchfile)) != 0) {
         exit rc
      }
   }
   
   # Check each showrev -p line against our array of required patches
   # Format is:
   # Patch: 106141-01 .*
   /^Patch: / {
      # strip off any leading spaces
      sub("^[  ]*", "", $0)
      # if you cannot split it into at least 2 fields, something is wrong,
      # just ignore it. The format from showrev -p looks like:
      # Patch: 106029-01 ...
      n = split($0, a)
      if (n >= 2) {
         for (i = 0; i < num; i++) {
            m = split(a[2], b, "-")
            if (m == 2) {
               # split a[2] to get the patchnum-revisionnum apart
               if (patchNum[i] == b[1]) {
                  if (b[2] >= patchRev[i]) {
                     printf "Patch %s-%s is present as: %s-%s [%s]\n",
                           patchNum[i], patchRev[i], b[1], b[2], patchNote[i]
                     havePatch[i] = 1
                  }
               }
            }
            else {
               # If you cannot split the output from showrev -p, then break out
               # of this loop, you do not need to try it against all the OSP patches..
               printf "cannot split %s into patch-revision\n", a[2]
               break
            }
         }
      }
      else {
         printf "cannot split %s\n", $0
      }
   }
   
   END {
      # This appears to get run even if exit was called earlier.
      if (rc != 0) {
         exit rc
      }
   
      nf = 0
      for (i = 0; i < num; i++) {
         if (havePatch[i] != 1) {
            printf "WARNING: Patch %s-%s does NOT appear to be present on this system\n",
                  patchNum[i], patchRev[i]
            printf "  Description: %s\n", patchNote[i]
            nf++
         }
      }
      if (nf != 0) {
         exit 1
      }
   }'
   rc=$?

   if [ $rc -ne 0 ]; then
      printf "\nYou can find more information about recommended and required patches (including\n"
      printf "where to get them from) at:\n"
      printf "   http://sunsolve.sun.com/pub-cgi/show.pl?target=patches/patch-access&nav=patchpage\n\n"

      case "$OSVER" in
         5.6) printf "Also see http://patches.sun.com/clusters/J2SE_Solaris_2.6_Recommended.README\n"
            ;;
         5.7) printf "Also see http://patches.sun.com/clusters/J2SE_Solaris_7_Recommended.README\n"
            ;;
         5.8) printf "Also see http://patches.sun.com/clusters/J2SE_Solaris_8_Recommended.README\n"
            ;;
         5.9) printf "Also see http://patches.sun.com/clusters/J2SE_Solaris_9_Recommended.README\n"
            ;;
      esac
   fi

   if [ -r "$tmpfile" ]; then
      rm -f $tmpfile
   fi

   # Exit with the awk status
   return $rc
}

# --------------------------------------------------------------------------------
# This routine is for IRIX64 machines
checkIRIX64()
{
   if [ $# -ne 1 ]; then
      printf "$0: Error - checkIRIX64() usage: checkIRIX64 <osVer>\n"
      return 1
   fi

   OSVER=$1

   # how do you find out the installed patches on an IRIX box?
   printf "\n"
   printf "Warning: Check the SGI JRE README for info on required patches for IRIX %s\n" $OSVER
   printf "Info: We recommend that you get the latest IRIX maintenance release installed.\n\n"
}

# --------------------------------------------------------------------------------
# This routine is for Linux boxes
checkLinux()
{
   if [ $# -ne 1 ]; then
      printf "$0: Error - checkLinux() usage: checkLinux <osVer>\n"
      return 1
   fi

   OSVER=$1

   # As far as we know there is nothing to check here..
   printf "\n"
   printf "Warning: Check the Linux JRE README file for info on required patches.\n"
   printf "\n"
}

# --------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
# Main script starts here

# Figure out what kind of machine we are on
os_name=`uname -s`         # e.g., 'SunOS' or 'IRIX64'
os_ver=`uname -r`          # e.g., '5.6' or '6.5'

# Make the appropriate check for this architecture
case "${os_name}" in
   SunOS) checkSunOS ${os_ver}
      ;;
   IRIX64) checkIRIX64 ${os_ver}
      ;;
   Linux) checkLinux ${os_ver}
      ;;
   *) printf "Error: machine architecture \"%s\" is not recognized.\n" "${os_name}_${os_ver}"
      printf "Cannot check for required patches.\n"
      exit 1
esac

exit $?

