#!/bin/sh
#
#  bundle_fltr [-pkg ] infile outfile 
#
#     Allow user to select products. Available products are
#     based upon <infile> 
#     <outfile> will consist of package lines based on selected
#     products from <infile>.
#
#     -pkg: allow user to select packages that correspond to the
#	    products selected before.
#
#    Algorithm:
#       let user pick from "installable products" to determine
#	installable packages i.e. packages do not have ok file.
#
#############################################################################
#############################################################################
#
#	Copyright (C) Cadence Design Systems, Inc. All rights
#	reserved.  Unpublished -- rights reserved under the
#	copyright laws of the United States of America.
#
#			RESTRICTED RIGHTS LEGEND
#	Use, duplication, or disclosure by the Government is subject
#	to restrictions as set forth in subparagraph (c)(l)(ii) of 
#	the Rights in Technical Data and Computer Software clause 
#	at DFARS 52.227-7013.
#
#			Cadence Design Systems, Inc.
#			555 River Oaks Parkway
#			San Jose, CA 95134	USA
#
#############################################################################
BOURNE=/bin/sh
XTERMPATH=/usr/openwin/bin
XTERMBIN=xterm
XTERMOPTS="-T 'SoftLoad 6.0 Console' -fn 9x15  -sl 200 -g 80x40+0+0 -bg \#e0e0e0 -fg \#800000 -sb -e ${BOURNE} softload_GUI"
sysPATH=/bin:/usr/bin:/usr/ucb:$XTERMPATH

jsr=''

OSvendor=sun4
OSarchs=$OSvendor
Archtype() {
    echo $OSvendor
}


Clear() {
    clear		2>/dev/null	#beware of bad termcap entry
}

Page() {
    MORE=""  more
}

EchoN() {
    echo -n "$*"
}

Beep() {
    $jsr EchoN ""	2>/dev/null
}


Affirmative() {
    while : ; do
	read Affirm
	case $Affirm in
	    [yY]*) return 0 ;;
	    [nN]*) return 1 ;;
	    *)     $jsr EchoN "Please press y (yes) or n (no) : " ;;
	esac
    done
}

Proceed() {
    test "X$1" = 'X-q' || $jsr EchoN "Press [Return] to proceed, q to quit : "
    while : ; do
	read proc < /dev/tty
	case $proc in
	    "")    return 0 ;;
	    [qQ]*) return 1 ;;
	    *) 	   $jsr EchoN "Press [Return] to proceed, q to quit : " ;;
	esac
    done
}

Exit() {

    status=$1; shift
    files="$*"
    for file in $files; do
        test -f $file && rm $file
    done
    exit $status

}
#This did not work for the -v flag. Fixed it so that it works fine
#now



Fgrepf() {		# fgrep -v filename
    vset=false
    Util="fgrep"
    opts=
    while test $# -gt 0 ; do
       case $1 in
          -egrep)
               Util="egrep"
               shift;;
          -v)
               opts="$opts `expr X$1 : '.\(.*\)'`"
               shift
               vset=true;;
          -*)
               opts="$opts `expr X$1 : '.\(.*\)'`"
               shift;;
           *)  break;;
       esac
    done

    patFl=$1
    srcFl=$2

    if [ "X$Util" = "Xegrep" ]; then
      split -5 $patFl /tmp/split$$_
    else
      split -75 $patFl /tmp/split$$_
    fi

    for pat in /tmp/split$$_* ; do
      if $vset; then
       count=0
       $Util $opts -f $pat $srcFl > /tmp/srcTFL$$
       srcTFL="/tmp/srcTFL$$"
       for pat1 in /tmp/split$$_* ; do
        count=`expr $count + 1`
        $Util $opts -f $pat1 $srcTFL > /tmp/srcFL${count}$$
        srcTFL="/tmp/srcFL${count}$$"
        echo $count > /tmp/count$$
       done
       if [ -s /tmp/count$$ ]; then
        read count < /tmp/count$$
       fi  
       cat /tmp/srcFL${count}$$ | sort -n | uniq >> /tmp/resFL$$
       while [ "$count" -gt 0 ]; do
         rm -f /tmp/srcFL${count}$$
         count=`expr $count - 1`
       done
       rm -f /tmp/srcTFL$$
      else
        $Util $opts -f $pat $srcFl
      fi
    done | sort -n | uniq
    if $vset; then
      cat /tmp/resFL$$ | sort -u | sort -n | uniq
    fi
    rm -f /tmp/resFL$$ /tmp/count$$ /tmp/split$$_* 
    
}


test -z "$Rm"	&& Rm=/bin/rm;		export Rm
if [ -z "$Proot" ]; then  #{
    echo "$0 environment not initialized
$0 can only be used when called from within SoftLoad" 				1>&2
    exit 1 
fi #}
export Proot

if [ -z "$InstPlat" ]; then  #{
   echo "$0 Installation platform not specified"   1>&2
   exit 1
fi #}

export InstPlat
 

useGUI=${useGUI?'useGUI environment not initialized'}

if [ "X$1" = "X-pkg" ]; then #{
   pkgflag=$1; shift
fi #}
infile=$1; shift
outfile=$1; shift

NL="
"

tmp=$Proot/install/tmp
sortbundles=${tmp}/sortbundles.$InstPlat
bundles=${tmp}/bundles.$InstPlat
pkginfo=$tmp/pkginfo.$InstPlat
pf_input=$tmp/pf_input
selprodfile=$tmp/selprodfile

if [ -z "$bin_dir" ]; then  #{
  bin_dir=$Proot/install/bin.$OSvendor
fi  #}

process_file=$bin_dir/process_file

if [ -s $infile ]; then #{
  tmpfl1=$tmp/tmpfl1_$$
  tmpfl2=$tmp/tmpfl2_$$
  tmpfl3=$tmp/tmpfl3_$$
  tmpfl4=$tmp/tmpfl4_$$
  tmphold=$tmp/hold_$$
  tmphold1=$tmp/hold1_$$
  holdfile=$tmp/Products.hold.$InstPlat
  holdmess=$tmp/holdmess_$$
  okfile=$tmp/okfile$$ 

  # get installable products status and size
  while : ; do  #{
    echo "${NL}Retrieving product status..."

    # This section takes care of hold products

    if [ -s $holdfile ]; then  #{
      cat $holdfile |\
      while read eachline ; do  #{
        productIdent=`echo $eachline | awk '{ print $2 }'`
        prod_desc=`echo $eachline | awk '{ print $1 }'`
        if [ $OSvendor = "sun" ]; then  #{
          PlatF=sun4
        else
          PlatF=$OSvendor
        fi  #}
        release=`echo $eachline | awk '{ print $3 }'`

        grep "$prod_desc" $sortbundles  1>/dev/null 2>&1

        if [ $? -ne 0 ]; then   #{
          if [ -f $Proot/install/pdts/${productIdent}_${PlatF}_${release}.ok \
              -o -f $Proot/install/pdts/${productIdent}_${PlatF}_${release}.nok ]; then  #{
            echo $eachline
          fi  #}
        else
          echo $eachline
        fi  #}
      done > $tmphold  #}
      if [  -s $tmphold ]; then  #{
        echo "${NL}These products are on hold. Even if you have licenses for these products you will not be able to install them. See the Release Alert for more information." >> $holdmess

        echo "${NL}For more information call the Cadence Customer Response Center (CRC) 1-800-Cadenc2" >> $holdmess
        echo "${NL}" >> $holdmess
        awk '{ print $1 }' $tmphold | tee $tmphold1 | tr "~" " ">> $holdmess
        Fgrepf -v $tmphold1 $bundles > $tmp/Xholdbundles$$
        mv $tmp/Xholdbundles$$ $bundles
        if [ "X$sselection" != "X4" -a "X$sselection" != "X5" ]; then #{
          if [ -s $tmphold ]; then #{
            if $useGUI; then #{
              $BOURNE $bin_dir/toplevel.sh  17 "$tmphold"\
                 || Exit $? $tmphold $holdmess
            else
              cat $holdmess
              EchoN "${NL}Press [RETURN] to continue:"
              read junk
            fi  #}
          fi  #}
        fi  #}
      fi  #}
      $Rm -f $tmphold $tmphold1 $holdmess
    fi #}
    # End hold section

    # Begin kludge for Document Installation

    if [ "X$sselection" = "X5" ]; then  #{
      docbund=$tmp/docbund$$
      docpkg=$tmp/docpkg$$

      # Get the list of entries form allbundles and allpkginfo 
      # if the package name
      # has the keyword Doc. before the version

      awk '$2 ~ /^.*Doc.[0-9.]*-[dapbs][0-9]*.*$/ { print $0 }' $infile >$docbund
      awk '$2 ~ /^.*Doc.[0-9.]*-[dapbs][0-9]*.*$/ { print $0 }' $pkginfo >$docpkg

      # The following awk section makes sure that when we display 
      # the products which have Doc packages for installation, 
      # display only the total size
      # of Doc packages for each product; Not the total size 
      # of the product.

      awk '
        # Parse thro the docbund file and store each field into
        # an array indexed by <productID>. Since there could(will)
        # be multiple packages for each product, store the package
        # field indexed by <productID><delimiter><pkgname> 
        # Set the size of the product to 0.

        FILENAME == "'$docbund'" {
          bundDesc[$3]=$1
          bundPkg[$3" "$2]=$2
          bundProd[$3]=$3
          bundSize[$3]=0
          bundTheRest[$3]=$5" "$6
          next
        }

        # Parse thro the pkginfo and store the pkg size indexed by
        # package name

        FILENAME == "'$docpkg'" {
          pkgsize[$2]=$3
          next
        }

        END {

          # For each entry in bundPkg array , split
          # the index itself into <productID> and <pkgname>
          # Add the package size for <pkgname> from pkgsize array
          # to bundSize. This way if there are ( will be ) multiple
          # packages associated with a product, the product size gets
          # incremented. 

          for ( each in bundPkg ) {
            a=split(each, entry, " ")
            bundSize[entry[1]] = bundSize[entry[1]] + pkgsize[entry[2]]
          }

          # Now print all the entries out

          for ( each in bundPkg ) {
            split(each, entry, " ")
            print bundDesc[entry[1]], bundPkg[each], bundProd[entry[1]], bundSize[entry[1]], bundTheRest[entry[1]]
          }

        }
      ' $docbund $docpkg > $tmp/affDocprod$$  #End of awk

      ( cd $Proot/install/pkgs && \
        ls *.ok 2>/dev/null | sed 's@\.ok$@@' > $tmp/pkgsok$$ ) 
      if [ -s $tmp/pkgsok$$ ]; then #{
        Fgrepf -v $tmp/pkgsok$$ $tmp/affDocprod$$
      else
        cat $tmp/affDocprod$$
      fi | sort -n > $pf_input  #}
      
      $process_file 3 p $Proot i ${pf_input} S | sort -u > $tmpfl2 	 
      awk '{
        if ( $NF == "failed" ) {
             $NF="available"
              }
              print $0
      }' $tmpfl2 | sort -n > ${tmpfl2}_tmp
      mv ${tmpfl2}_tmp $tmpfl2

      $Rm $docbund $docpkg $tmp/pkgsok$$ ${pf_input} 

    else
      $process_file 3 p $Proot i $bundles S | sort -u | sort -n > $tmpfl2 
    fi #}

    test -s $tmpfl2 || {
      echo "${NL}All products are already installed."
       > $outfile
      Exit 0 $tmpfl2 
    }	

    #have user select products to later select packages from
    > $tmpfl1
    if [ "X$default_install" = "Xyes" ]; then #{If default install is 
      cat $tmpfl2 > $tmpfl1
    else
      if $useGUI; then #{
        if [ "X$sselection" = "X4" ]; then #{
          Label="Cadence Catalog"
        else
          Label="$WorkOrder"
        fi #}
        diskAvail=$tmp/disk$$
        $BOURNE disk_tbl /dev/null $diskAvail > /dev/null
        diskSpace=
        diskSpace=`awk '{print $2}' $diskAvail`
        rm -rf $diskAvail 
  
        if [ "X$sselection" = "X5" ]; then  #{
          cp ${bundles} ${bundles}.save 
          mv $tmp/affDocprod$$ ${bundles}
          $BOURNE $bin_dir/toplevel.sh 18 $tmpfl2 $tmpfl1 "$diskSpace" \
               || Exit $? $tmpfl2 $tmpfl1 
          mv ${bundles}.save ${bundles}
        else
          $BOURNE $bin_dir/toplevel.sh 2 $tmpfl2 $tmpfl1 "$diskSpace" "$Label" \
               || Exit $? $tmpfl2 $tmpfl1 
        fi #}sselection =5 fi
        case $? in #{
          255) exit 255;;
          250) exit 250;;
        esac #}
      else	
        if [ "X$sselection" = "X5" ]; then  #{
          cp ${bundles} ${bundles}.save 
        
          mv $tmp/affDocprod$$ ${bundles}
          $BOURNE choice_fltr -F \
            -M "${NL}Documents for the following products can be installed. If you do not select all ${NL}of them, you can select documents for products by their numbers. ${NL}If you install only documentation, products status will be \"Failed\" because ${NL}the entire product is not installed. If a product is not listed, it's ${NL}documentation is already installed. " \
            -T "product" $tmpfl2 $tmpfl1 || Exit $? $tmpfl2 $tmpfl1
          mv ${bundles}.save ${bundles}
        else
          $BOURNE choice_fltr -F \
            -M "${NL}The following products can be installed. If you do not select all ${NL}of them, you can select products by their numbers." \
            -T "product" $tmpfl2 $tmpfl1 || Exit $? $tmpfl2 $tmpfl1
        fi #}sselection =5 fi
      fi #}end of if useGUI if stmt
    fi  #}Default or custom install
      
    #The following lines will let the customer know of the
    #change in the statuses of the products.

    $Rm $tmpfl2	
    if [ -s $tmpfl1 ]; then  #{
      # generate and run awk program with lines of the following form
      # to collect pkgnames for selected products

      sed  's@^[^ ]* [^ ]* \([^ ]*\).*$@$3 == "\1" { print }@' $tmpfl1 > $tmp/awkb$$
      $Rm $tmpfl1

      > $okfile; >$tmpfl3

      awk -f $tmp/awkb$$ $infile  > $tmpfl3
      cat $tmpfl3 > $selprodfile

      echo ""

      echo "${NL}Generating detailed installation data..."
      $Rm $tmp/awkb$$
      # find all packages information associated with products
      if [ "X$sselection" = "X5" ]; then  #{
        awk '$2 ~ /^.*Doc.[0-9.]*-[dapbs][0-9]*.*$/ { print $0 }' $tmpfl3
      else
        cat $tmpfl3
      fi | sed  's@^[^ ]* \([^ ]*\).*$@$2 == "\1" { print }@' > $tmp/awkb1$$  #}

      awk -f $tmp/awkb1$$ $pkginfo | sort -u +1 -2 > /tmp/pdt$$

      #check the no of lines in the awk file and the number of lines
      #in the pdts file if not the same flag an error message


      if [ `cat $tmp/awkb1$$ | sort -u | wc -l` -gt `wc -l < /tmp/pdt$$` ]; then #{
        msg="SL-1: Installation information mismatch (bundles)
Call the Cadence Customer Response Center (CRC) 1-800-Cadenc2
(1-800-223-3622)to get the right files"
        echo "$msg" 1>&2
        Exit 250 $tmp/awkb1 ;
      fi #}

      $Rm $tmp/awkb1$$

      #This is for making configure the default option when 
      #after installation of a configurable product the 
      #main menu pops up again

      test -s /tmp/pdt$$ && { \
        cat < /tmp/pdt$$ > $tmp/defcp 
      }


      #get installable packages
      cat /tmp/pdt$$ > $tmpfl4
      $process_file 2 p $Proot i $tmpfl4 k pkgs ok > /tmp/pdt$$
      $Rm $tmpfl4

      # all the corresponding packages have been installed

      if [ -s /tmp/pdt$$ ]; then  #{
       :  #Update everything in load_pkgs 
      else

        $jsr EchoN "${NL}Updating product history...${NL}"

        while read pdtdesc pkgname pdtname pdtsize platform FMrelease ; do  #{
          pdtRoot="$Proot/install/pdts/${pdtname}_${platform}_${FMrelease}"
          pkgRoot="$Proot/install/pkgs/${pkgname}"
          test -s ${pkgRoot}.ok && {
          # If the pkgname.ok file exists (it's already been loaded
          # successfully) and this product isn't listed as depending
          # on that package, establish that relationship
          test `egrep -c "^$pdtname $platform " ${pkgRoot}.ok` -eq 0 && \
             echo $pdtname $platform $FMrelease >> ${pkgRoot}.ok
          }
          # If the product.nok file doesn't exist, create it and add the
          # initialization info
          test -s ${pdtRoot}.nok || {
            echo "$pdtdesc pkgname $pdtname $pdtsize $platform $FMrelease" > ${pdtRoot}.nok
            # New product.nok generated - output a dot to let them know
            # we're still here and running
            $jsr EchoN "."
          }
          echo $pdtRoot >> $okfile
          # Update processing files to reflect the products/packages to
          # load
          # If this package doesn't yet appear in the product.nok file,
          # add it in
          test `egrep -c "^$pkgname$" ${pdtRoot}.nok` -eq 0 && \
          echo $pkgname >> ${pdtRoot}.nok
        done   < $tmpfl3 #}End of awk
        for nokfile in `/bin/cat $okfile | sort -u` ; do  #{
          mv ${nokfile}.nok ${nokfile}.ok
        done  #}
        > $outfile ; Exit 0 $okfile
      fi #}	




      if [ ! -z "${pkgflag}" ]; then #{
        #
        # See if we need to append pkgname to pkgdesc to 
        # uniquely identify selections
        #
        if [ `wc -l < /tmp/pdt$$` -gt `awk '{print $1}' /tmp/pdt$$ | sort -u | wc -l` ]; then #{
          dofullname="yes"
        else
          dofullname="no"
        fi  #}

        if [ $dofullname = "yes" ]; then
          #append parenthesized pkgname to pkgdesc
          sed 's@\([^ ]*\) \([^ ]*\)@\1~~~~~~~~~~~~~~(\2) \2@' /tmp/pdt$$ > $tmpfl2
          numCols=1
        else
          /bin/cat /tmp/pdt$$ > $tmpfl2
          numCols=2
        fi

        #
        # get user selections
        #

        $BOURNE choice_fltr -M \
"${NL}The following packages can be installed. If you do not select all ${NL}of them, you can select packages by their numbers." \
           -T package $tmpfl2 /tmp/pdt$$ || Exit $? $tmpfl2 /tmp/pdt$$
        $Rm $tmpfl2
        if [ -s /tmp/pdt$$ -a $dofullname = "yes" ]; then  #{
          #remove parenthesized pkgname from desc
          ./overwrite /tmp/pdt$$ \
          sed 's@~~~~~~~~~~~~~~([^)]*) @ @' /tmp/pdt$$
        fi  #}
      fi #}
      ## do not select any packages
      test -s /tmp/pdt$$ || {
        > $outfile
        break 
      }
      if [ ! -z "$dodisk_chk" -a "$dodisk_chk" != "no" ]; then #{
       $BOURNE disk_chk -T "product" /tmp/pdt$$
       mystatus=$?
       case $mystatus in #{
         0) ;; #proceed with installation
         250) 
           echo "${NL}Reverting to previous product history state..."
           ## remove products.nok which generate before	
           for nokfile in `/bin/cat $okfile` ; do #{
             test -s $nokfile.nok && $Rm $nokfile.nok
           done	 #}
           exit 250 ;; #back to main menu
         222) 
           echo "${NL}Reverting to previous product history state..."
           ## remove products.nok which generate before	
	   for nokfile in `/bin/cat $okfile` ; do #{
             test -s $nokfile.nok && $Rm $nokfile.nok
           done	 #}
           exit 222    
         ;;   #reselect
         *) Exit $mystatus /tmp/pdt$$ $okfile ;; 
       esac #}
     else
       echo "${NL}Disk checks ignored ${NL}"
     fi #}
     # generate and run awk program with lines of the following form
     # to collect installable pkgnames for selected products and
     # platform release information
     sed  's@^[^ ]* \([^ ]*\).*$@$2 == "\1" { print $2, $3, $5, $6 }@' /tmp/pdt$$ > $tmp/awkb$$
     awk -f $tmp/awkb$$  $tmpfl3  | sort > $outfile  #pkgnames
     $Rm    $tmp/awkb$$ /tmp/pdt$$ $tmpfl3
   else
     > $outfile
   fi  #}
   break	
 done  #}
 test -f $okfile && $Rm $okfile	
else
  cp $infile $outfile
fi  #}
exit 0
