#!/bin/sh
# disk_tbl infile outfile
#
#	This program determines disk space requirements and disk space
#	availability based upon <infile> and mounted directories.
#
#	<outfile> consists of lines of the format:
#	    mountpoint available_Kbytes required_Kbytes
#
#############################################################################
#
#	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/bin/X11
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=''

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

Page() {
    TERM=vt100 MORE=""  more		#make sure we don't clear screen
}

EchoN() {
    echo  "$*\c"
}

Beep() {
    tput bel		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
}


FlInfo() {
    /bin/ls -ldL $*  |
	sed -e 's@^\(..........\)\([^ 	]\)@\1 \2@'	\
	    -e 's@^L@l@' -e 's@^D@d@' -e 's@^F@-@'
}
	
FlOwner() {
    $jsr FlInfo $* | awk '{print $3}'
}

FlGroup() {
    $jsr FlInfo $* | awk '{print $4}'
}

FlSize() {
    $jsr FlInfo $* | awk '{print $5}'
}

LinkName() {
    $jsr FlInfo $* | awk '{print $11}'
}

IsSymLink() {
    $jsr FlInfo $1  2>/dev/null | grep '^l' 1>/dev/null
    return $?
}


DirentExists() {		#non-referencing symLinks included
    test -d $1 -o -f $1 || $jsr IsSymLink $1
    return $?
}
	
FlsNewer() {
    than=`echo $1 | sed 's@[/.]@\\\\&@g'`	#stick in backslashes to escape
    {
	echo ""					#in case none newer
	/bin/ls -Ldtr $* 
    } | sed -e '1,/^'$than'$/d' -e '/^'$than'$/d'
}

FlsOlder() {
    than=`echo $1 | sed 's@[/.]@\\\\&@g'`	#stick in backslashes to escape
    {
	echo ""					#in case none older
	/bin/ls -Ldt $* 
    } | sed -e '1,/^'$than'$/d' -e '/^'$than'$/d'
}



FsFragSize() {
    echo 4096
}

TreeSizeK() {
    du -sk $1 | awk '{print $1}'
}


FlSizeK() {
    $jsr FlSize $1 | awk '{print int($1 / 1024 + 0.99) }'
}


Df() {					#reports info in Kbytes, hierarchically
    echo "\
Filesystem                          avail Kb  Mounted on"
    df="df -I"
    $df $* | sed -e 's@//@/@g' -e 's@\([^ 	]\)/$@\1@' | awk '\
	NR == 1  { next }
	NF == 1  { filesys = $1; next }		#broken into two lines
	{   if ( $0 ~ /^[^ 	].*/ ) filesys = $1
	    mntPt = $(NF)
	    avail = $(NF-2)
	    if ( avail < 0 ) avail = 0
	    printf( "%-35s %8d  %s\n", filesys, avail, mntPt )
	}' | sort -b +2
}


DfTree() {
    (
	if [ $# -eq 1 ]; then
	    cd $1 || return 1
	fi

        if [ `expr "$1" : "/afs*"` -gt 0 ]; then
                echo "\
Filesystem                          avail Kb  Mounted on"
           /usr/afsws/bin/fs lq . > /tmp/fslq$$
           /usr/afsws/bin/fs df . > /tmp/fsdf$$
           spaceOnPartion=`awk 'NR == 2,NR == 2 { print $4 }' /tmp/fsdf$$`
           quotaOnVolume=`awk 'NR == 2,NR == 2 { print $2 }' /tmp/fslq$$`
           usedOnVolume=`awk 'NR == 2,NR == 2 { print $3 }' /tmp/fslq$$`
           if [ $quotaOnVolume = "no" ]; then
              avail=$spaceOnPartion
           else
              availQuota=`expr $quotaOnVolume - $usedOnVolume`
              if [ $spaceOnPartion -gt $availQuota ]; then
                 avail=$availQuota
              else
                 avail=$spaceOnPartion
              fi
           fi
           rm /tmp/fslq$$ /tmp/fsdf$$
           echo "AFS       $avail     /afs"
        else
           $jsr Df | awk '\
           BEGIN   { here = "'`/bin/pwd`'" }       #requires real absolute path
           NR == 1 { print; next }
           {
             if ( here == "/" ) {
               	print                           #filesys is descendant of $here
             } else if ( $3 == "/" || \
                $3 "/" == substr( here , 1, length($3)+1 ) ) {
               	pending = $0                    #filesys is ancestor of $here
             } else if ( $3 == here ) {
               	pending = ""
               	print                           #filesys is $here
             } else if ( substr( $3, 1, length(here)+1 ) == here "/" ) {
              	if ( pending != "" ) print pending
               	pending = ""
               	print                           #filesys is descendant of $here
             }
           }
       	   END {
               if ( pending != "" ) print pending
           }'
         fi

    )
}


DkAvail() {
    ( cd $1 && $jsr Df . ) | awk 'NR == 2 {print $2}'
}


test -z "$Rm" && Rm="/bin/rm -f"
export Rm

infile=$1; shift
dfTbl=$1; shift

rsrc=/tmp/rsrc$$
echo "Determining available disk space"
$jsr DfTree $Proot | sed '1d' > $rsrc		#fileSystem availKb mountPoint

numMounts=`wc -l < $rsrc`
fragSz=`$jsr FsFragSize`
if [ $numMounts -gt 1 ]; then			#multi-filesystem installation

    sort -r -b +2 -o $rsrc $rsrc		#put root at end
    awkprog=/tmp/awk$$

    (
#
#   Generate an awk progam of the following form:
#
#	BEGIN {
#	    numMounts = ###
#	    for ( i = 1; i <= N; i++ )
#		required[i] = 0
#	    name[1] = "XXXXXX"; avail[1] = #####
#	    ...
#	    name[N] = "XXXXXX"; avail[N] = #####
#	}
#	{ frags = int($2/fragSz +0.99) }
#	/^\.\/filesys1\// { required[1] += frags; next }
#	...
#	{ required[N] += frags; }
#	END {
#	    format = "%-35s %8d  %8d\n"
#	    for ( i = 1; i <= N; i++ )
#		printf( format, name[i], avail[i], required[i] )
#	}
#

	#
	#generate BEGIN step
	#
	echo "\
BEGIN {
    numMounts = $numMounts
    fragSz = $fragSz
    for ( i = 1; i <= numMounts; i++ )
	required[i] = 0"

	awk  '{ print "    name[" NR "] = \"" $3 "\"; avail[" NR "] = " $2 }
              END { 
		  print "}" 
    		  print "{   frags = int($2/fragSz +0.99)"
		  print "    if ( frags == 0 ) frags = 1 "
		  print "}" 
	      }' < $rsrc

	#
	#generate Main processing loop
	#
	if [ $Proot = "/" ]; then		# kludge for pattern matching
	    rootPat=""
	else
	    Proot=`( cd $Proot && /bin/pwd )`	# extra care to get real path
	    rootPat=$Proot
	fi
	awk '{print $3}' $rsrc |\
	    sed -e "s@^$Proot"'$@./@' -e "s@^$rootPat/@./@"	\
	        -e 's@//@/@g' -e 's@/@\\/@g' -e 's@\.@\\.@g'	|\
	    awk '\
NR < '"$numMounts"' \
    { print "/^" $0 "\\// { required[" NR "] += frags; next }"; next }
    { print              "{ required[" NR "] += frags }" }'

	#
	#generate END Step
	#
	echo \
'END {
    for ( i = 1; i <= numMounts; i++ )
	print name[i], avail[i], int(required[i]*fragSz/1024 +0.99)	#kbytes
}'

    ) > $awkprog
    $Rm $rsrc

    #
    # now determine how much space is required in each filesystem
    #
    echo "Determining required disk space"
    $Rm  $Proot/install/tmp/mdsk_chk
    cat $infile | while read pkgdesc pkgname remainder; do
       if [ -s $Proot/install/tmp/$pkgname.inv ]; then
           awk '{print $NF, $2}' $Proot/install/tmp/$pkgname.inv # name, size
        elif [ -s $Proot/install/pkgs/$pkgname.inv ]; then
           awk '{print $NF, $2}' $Proot/install/pkgs/$pkgname.inv # name, size
        else
           echo "postponed" > $Proot/install/tmp/mdsk_chk
           break;
        fi
    done  > /tmp/awkin$$

    awk -f $awkprog /tmp/awkin$$ > $dfTbl
    $Rm $awkprog
  
    if [ -s $Proot/install/tmp/mdsk_chk ]; then
      echo "Disk checks postponed..."
      echo " "
      $Rm  $awkprog
      exit 132
    fi


else		# numMounts == 1 --> we already know required space

    echo "Determining required disk space"
    dkreq=`awk '
        { dkreq += $3 }
	END { print dkreq }' $infile `
    
    awk '{ print $3, $2, "'$dkreq'" }' $rsrc > $dfTbl
    $Rm $rsrc

fi
exit 0

