#!/bin/csh -f
#
# Configuration script for top.
#
# Use with version 3.0 and higher.
#
set PRIME = "/usr/games/primes"
set vars = (module LoadMax topn NominalTopn delay owner group mode random TableSize bindir mandir manext Cmdshell Cmdcc Cmdawk Cmdinstall cdefs)
set fastrack = 0
set yesno = (no yes)

onintr byebye

# make sure that getans is there and ready
if (! -e getans) then
   echo 'This package is not complete.  The shell file "getans" is missing.'
   exit 10
endif
chmod +x getans

if ($#argv > 0) then
# fast track configuration
   set fastrack = 1
else
cat <<'EOF'
Configuration for top, version 3

One moment....
'EOF'
endif

# collect file names and module names
ls -1 m_*.c >$$.f
ls -1 m_*.man >$$.m
sed -e 's/^m_//' -e 's/.c$//' $$.f >$$.n

# build Make.desc
set descs = `sed -e 's/\.c$/.desc/' $$.f`
sed -e "s/%descs%/$descs/" Make.desc.X >Make.desc

# build desc files and SYNOPSIS as needed
make -f Make.desc >/dev/null

if (-e .defaults) then
   echo ""
   echo "Reading configuration from last time..."
   source .defaults
   set nodefaults = 0
   if ($fastrack == 1) then
      set module = $1
   endif
else
   if ($fastrack == 1) then
      echo "No previous configuration was found."
      set fastrack = 0
      set module = $1
   else
      set module = bsd43
   endif
   set LoadMax     = 5.0
   set topn        = 15
   set NominalTopn = 18
   set delay       = 5
   set TableSize   = 0
   set bindir      = /usr/local/bin
   set mandir      = /usr/man/manl
   set manext      = l
   set nodefaults  = 1
   set Cmdshell    = /bin/sh
   set Cmdawk      = awk
   set Cmdinstall  = install
   set Cmdcc       = cc
   set cdefs       = -O
endif
echo ""

if ($fastrack == 1) then
   grep -s $module $$.n
   if ($status != 0) then
      echo "$module is not recognized.  To see a list of available modules"
      echo 'run "Configure" with no arguments.'
      rm -f $$.[fmn]
      exit 1
   endif
   cat <<EOF
Using these settings:
        Bourne Shell   $Cmdshell
          C compiler   $Cmdcc
    Compiler options   $cdefs
         Awk command   $Cmdawk
     Install command   $Cmdinstall

              Module   $module
             LoadMax   $LoadMax
        Default TOPN   $topn
        Nominal TOPN   $NominalTopn
       Default Delay   $delay
Random passwd access   $yesno[$random]
          Table Size   $TableSize
               Owner   $owner
         Group Owner   $group
                Mode   $mode
       bin directory   $bindir
       man directory   $mandir
       man extension   $manext

EOF
   goto fast
endif

cat <<'EOF'
You will be asked a series of questions.  Each question will have a
default answer enclosed in brackets, such as "[5.0]".  In most cases,
the default answer will work well.  To use that value, merely press
return.

'EOF'

# display synopses

getmod:
cat <<'EOF'

The following machine-dependent modules are available:
'EOF'
awk -F: ' { printf "%-8s %s\n", $1, $2 }' SYNOPSIS
echo ''
./getans "What module is appropriate for this machine? " string $module .$$
set module = `cat .$$`

# is it a valid one?
grep -s $module $$.n
if ($status != 0) then
    echo "That is not a recognized module name."
    goto getmod
endif

# display a full description
sed -e '1,/DESCRIPTION:/d' -e '/^$/,$d' m_${module}.desc

# verify it
echo ""
./getans "Is this what you want to use?" yesno 1 .$$
if (`cat .$$` == 0) then
   goto getmod
endif
endif

cat <<'EOF'

First we need to find out a little bit about the executables needed to
compile top.

'EOF'
./getans "What is the full path name for the Bourne shell" file "$Cmdshell" .$$
set Cmdshell = `cat .$$`

cat <<'EOF'

Please supply the name of the appropriate command.  It need not be a
full path name, but the named command does need to exist somewhere on
the current path.

'EOF'
./getans "AWK Interpreter" path "$Cmdawk" .$$
set Cmdawk = `cat .$$`
./getans "Installer" path "$Cmdinstall" .$$
set Cmdinstall = `cat .$$`
./getans "C Compiler" path "$Cmdcc" .$$
set Cmdcc = `cat .$$`

cat <<EOF

What other options should be used with the $Cmdcc command?
EOF
./getans "Compiler options" string "$cdefs" .$$
set cdefs = `cat .$$`

cat <<'EOF'

Now you need to answer some questions concerning the configuration of
top itself.

The space command forces an immediate update.  Sometimes, on loaded
systems, this update will take a significant period of time (because all
the output is buffered).  So, if the short-term load average is above
"LoadMax", then top will put the cursor home immediately after the space
is pressed before the next update is attempted.  This serves as a visual
acknowledgement of the command.  "LoadMax" should always be specified as a
floating point number.

'EOF'
./getans "LoadMax" number "$LoadMax" .$$
set LoadMax = `cat .$$`

cat <<'EOF'

"Default TOPN" is the default number of processes to show.  This is the
number that will be used when the user does not specify the number of
processes to show.  If you want "all" (or infinity) as the default, use
the value "-1".

'EOF'

./getans "Default TOPN" neginteger "$topn" .$$
set topn = `cat .$$`

cat <<'EOF'

"Nominal_TOPN" is used as the default TOPN when Default_TOPN is Infinity
and the output is a dumb terminal.  If we didn't do this, then
installations who use a default TOPN of Infinity will get every process in
the system when running top on a dumb terminal (or redirected to a file).
Note that Nominal_TOPN is a default: it can still be overridden on the
command line, even with the value "infinity".

'EOF'

./getans "Nominal TOPN" integer "$NominalTopn" .$$
set NominalTopn = `cat .$$`

cat <<'EOF'

Default Delay is the default number of seconds to wait between screen
updates.

'EOF'

./getans "Default Delay" integer "$delay" .$$
set delay = `cat .$$`

echo ""

ypwhich >&/dev/null
set rand = 0
if ($status == 0 || -e /etc/passwd.dir) then
   set rand = 1
endif

if ($rand == 1) then
   echo "It looks like you have a passwd file that can be accessed at random."
   set pr = 'Do you want top to take advantage of this'
else
   echo "It looks like you have conventional passwd file access.  Top can take"
   echo "advantage of a random access passwd mechanism if such exists.  Do"
   echo "you want top to assume that accesses to the file /etc/passwd are done"
   set pr = 'with random access rather than sequential'
endif

if ($nodefaults == 1) then
   set random = $rand
endif

./getans "${pr}?" yesno $random .$$
set random = `cat .$$`

echo ""

ypcat passwd.byname >&/tmp/$$.a
if ($status == 0) then
   set cnt = `wc -l </tmp/$$.a`
   set mapfile = "NIS map"
else
   set cnt = `wc -l </etc/passwd`
   set mapfile = "file"
endif
rm /tmp/$$.a
set double = `expr $cnt \* 2`
echo "I found $cnt entries in your passwd $mapfile.  Top hashes the username to"
echo "uid mappings as it goes along and it needs a good guess on the size of"
echo "that hash table.  This number should be the next highest prime number"
echo "after $double."
echo ""
if (-e $PRIME) then
   set pr = `$PRIME $double | head -1`
   echo "I have calculated that to be $pr."
else
   set pr = $double
   echo "I cannot calculate that prime number, so you will need to provide it for me."
endif

if ($TableSize == 0) then
   set TableSize = $pr
endif

./getans "Enter the hash table size" integer "$TableSize" .$$
set TableSize = `cat .$$`

echo ""

# !!! I need to fix this:  /dev/kmem might not exist on some machines !!!

set t_owner = root
set t_group = wheel
if (-e /dev/kmem) then
   ls -lg /dev/kmem >/tmp/$$.b
   grep '^....r..r..' /tmp/$$.b >&/dev/null
   if ($status == 1) then
      grep '^....r..-..' /tmp/$$.b >&/dev/null
      if ($status == 0) then
         set t_group = `awk ' { print $4 }' /tmp/$$.b`
         set t_mode = 2755
         echo "It looks like only group $t_group can read the memory devices."
      else
         set t_mode = 4755
         echo "It looks like only root can read the memory devices."
      endif
   else
      set t_mode = 755
      echo "It looks like anybody can read the memory devices."
   endif
else
   echo "It looks like there are no memory device special files."
   set t_mode = 755
endif
if ($nodefaults) then
   set owner = $t_owner
   set group = $t_group
   set mode =  $t_mode
endif
echo "Tell me how to set the following when top is installed:"
./getans "Owner" user "$owner" .$$
set owner = `cat .$$`
./getans "Group owner" group "$group" .$$
set group = `cat .$$`
./getans "Mode" integer "$mode" .$$
set mode = `cat .$$`
rm -f /tmp/$$.b

echo ""
./getans "Install the executable in this directory" file "$bindir" .$$
set bindir = `cat .$$`

echo ""
./getans "Install the manual page in this directory" file "$mandir" .$$
set mandir = `cat .$$`

echo ""
./getans "Install the manual page with this extension" string "$manext" .$$
set manext = `cat .$$`

echo ""
echo "We are done with the questions."

echo "Saving configuration..."
# save settings to use as defaults the next time
rm -f .defaults
foreach v ($vars)
   set tmp = `eval echo \$$v`
   echo set $v = "'$tmp'" >>.defaults
end

fast:

# set variables which contain module lists
set modules = `cat $$.f`
set manmodules = `cat $$.m`

# clean up
rm -f $$.f $$.m $$.n

# set the link for machine.c
rm -f machine.c machine.o
ln -s m_${module}.c machine.c
set libs = `grep LIBS: m_${module}.desc | sed -e 's/^.[^:]*: *//'`

if ( { grep -s SIGINT /usr/include/signal.h } ) then
    set signal="/usr/include/signal.h"
else
    set signal="/usr/include/sys/signal.h"
endif


echo "Building Makefile..."
sed -e "s|%topn%|$topn|" \
    -e "s|%delay%|$delay|" \
    -e "s|%owner%|$owner|" \
    -e "s|%group%|$group|" \
    -e "s|%mode%|$mode|" \
    -e "s|%bindir%|$bindir|" \
    -e "s|%mandir%|$mandir|" \
    -e "s|%manext%|$manext|" \
    -e "s|%tablesize%|$TableSize|" \
    -e "s|%libs%|$libs|" \
    -e "s|%cdefs%|$cdefs|" \
    -e "s|%modules%|$modules|" \
    -e "s|%manmodules%|$manmodules|" \
    -e "s|%signal%|$signal|" \
    -e "s|%cc%|$Cmdcc|" \
    -e "s|%awk%|$Cmdawk|" \
    -e "s|%install%|$Cmdinstall|" \
    -e "s|%shell%|$Cmdshell|" \
	Makefile.X >Makefile

echo "Building top.local.h..."
sed -e "s|%LoadMax%|$LoadMax|" \
    -e "s|%TableSize%|$TableSize|" \
    -e "s|%NominalTopn%|$NominalTopn|" \
    -e "s|%topn%|$topn|" \
    -e "s|%delay%|$delay|" \
    -e "s|%random%|$random|" \
	top.local.H >top.local.h

echo "Building top.1..."
sed -e "s|%topn%|$topn|" \
    -e "s|%delay%|$delay|" \
	top.X >top.1
if (-e m_${module}.man ) then
    cat m_${module}.man >>top.1
endif

# clean up
rm -f .$$

echo 'Doing a "make clean".'
make clean

echo 'To create the executable, type "make".'
exit 0

byebye:
rm -f .$$ $$.[fmn] /tmp/$$.[ab]
exit 1
