o
  binaries/mips-ultrix4.4.tar.gz      Mips ULTRIX systems
  binaries/rs6000-aix3.2.tar.gz       IBM RS6000
  binaries/sparc-solaris2.4.tar.gz    SUN sparc Solaris2.4
  binaries/sparc-sunos4.1.3.tar.gz    SUN sparc SunOS4.1.3
  binaries/alpha-osf2.0.tar.gz        DEC OSF/1 V2.0 Alpha
  binaries/alpha-osf3.2.tar.gz        DEC OSF/1 V3.2 Alpha-AXP
  binaries/hppa1.1-hpux9.01.tar.gz    HP-UX 9.01 9000/710

  filename                            content
  --------------------------------------------------------------------------
  base/tetex-base.tar.gz              a very basic TeX system
  base/latex-base.tar.gz              a small LaTeX system, needs tetex-base

  filename                            content
  --------------------------------------------------------------------------
  goodies/latex-extra.tar.gz          a lot of extra packages for LaTeX
  goodies/bibtex.tar.gz               a tool to make a bibliography for (La)TeX
  goodies/amstex.tar.gz               more mathematics for TeX
  goodies/pictex.tar.gz               portable pictures with (La)TeX
  goodies/xtexsh.tar.gz               a small development environment

  filename                            documentation
  --------------------------------------------------------------------------
  doc/general-doc.tar.gz              TeX-FAQ, ftp locations, TDS, ...
  doc/kpathsea-doc.tar.gz             search library used by TeX and friends
  doc/ams-doc.tar.gz                  d. about AMS fonts, AMSLaTeX and AMSTeX
  doc/babel-doc.tar.gz                d. about the babel system
  doc/bibtex-doc.tar.gz               d. about the bibtex program
  doc/eplain-doc.tar.gz               extended plain format
  doc/fontname-doc.tar.gz             File names for TeX fonts (Karl Berry)
  doc/dcfonts-doc.tar.gz              d. about DC fonts
  doc/oldgerman-doc.tar.gz            d. about old german fonts
  doc/german-doc.tar.gz               some documentation in german language
  doc/latex-doc.tar.gz                much documentation about LaTeX
  doc/makeindex-doc.tar.gz            a general purpose index formater
  doc/texdraw-doc.tar.gz              d. about the texdraw macros

  filename                            fonts
  --------------------------------------------------------------------------
  fonts/urw-fonts.tar.gz              PostScript fonts from URW
  fonts/adobe-fonts.tar.gz            PostScript fonts from Adobe
  fonts/bitstrea-fonts.tar.gz         charter fonts (from Bitstream)
  fonts/ams-fonts.tar.gz              AMS fonts
  fonts/dc-fonts.tar.gz               DC fonts
  fonts/gothic-fonts.tar.gz           old german fonts
  fonts/pandora-fonts.tar.gz          pandora fonts
  fonts/wasy-fonts.tar.gz             WASY symbol font
  fonts/concrete-fonts.tar.gz         concrete fonts
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             #!/bin/sh

################################################################
# Basic IO:
################################################################

################################################################
# read: called with the name of a variable and (optionally) a
#       different message text. Keeps the old value of the
#       variable, if the empty string in entered.
################################################################
gets()
{
    gets_var=$1; gets_text=${2-$gets_var}
    eval old=\$$gets_var
    eval $echon \""New value for $gets_text [$old]: "\"
    read $gets_var
    eval test -z \"\$$gets_var\" && eval $gets_var=\'$old\'
}

################################################################
# getopt: get a menu choice.
#   $1: string with valid characters
#   $2: message for prompting
################################################################
getopt()
{
    chars=$1; msg=$2
    while true; do
        #$echon "$msg ([$chars]): "
        $echon "$msg: " >&2
        read ans
        ans=`echo $ans | tr '[a-z]' '[A-Z]'`
        case "$ans" in
          [$chars])
            echo "$ans"
            return
        esac
    done
}

################################################################
# toolge: given the name of a variable, toogle switches between
#         the values ' ' and X.
################################################################
toggle()
{
    if eval test \"\$$1\" = X; then
        eval $1=\' \'
    else
        eval $1=X
    fi
}

################################################################
# This tricky function displays the value of a variable that can
# contain newline characters. Variables will be expanded, too.
# Arguments:
#       1: the name of the variable
################################################################
textvar_show()
{
    OLDIFS=$IFS; IFS='';
    eval echo \"`eval echo \\$${1}`\"
    IFS=$OLDIFS
}

readln()
{
    $echon 'Press return to continue... '
    read foo
}

help()
{
    var=$1
    cls
    textvar_show $var 2>&1 | $PAGER
    echo
    readln
}

################################################################
# Use the yesno functions to ask the user a simple yes/no
# question.
# Arguments:
#   $1: test to display for the question (" (Y/N)? " will
#       automatically be appended).
################################################################
yesno()
{
    while true; do
    $echon "$1 (Y/N)? "
    read ans
    case $ans in
        y|Y)    return 0;;
        n|N)    return 1;;
        esac
    done
}

################################################################
# A set of functions the might do an echo without linefeed in
# the end. Function find_echo sets the variable "echon" to a
# suitable function.
################################################################
echo_a() { echo      -n "$@";   }
echo_b() { echo         "$@\c"; }
echo_c() { echo      -e "$@\c"; }
echo_d() { /bin/echo -n "$@";   }
echo_e() { /bin/echo    "$@\c"; }
echo_f() { /bin/echo -e "$@\c"; }

################################################################
# Test which of the above functions does the trick. We set
# the variable "echon" to the first function that works
# correctly.
################################################################
find_echo()
{
    for i in a b c d e f; do
        test "`echo_$i c``echo_$i a`"  = ca && echon=echo_$i && return
    done
    echon=echo
}


################################################################
# series and packages management:
################################################################

###############################################################################
# The series structure:
#  s_${series}_la:   "list of all packages"
#  s_${series}_lf:   "list of packages we found on the disk"
#  s_${series}_ls:   "list of selected packages"
#  s_${series}_mis:  "list of packages that are missing"
#  s_${series}_nf:   "number of packages we find"
#  s_${series}_ns:   "number of selected packages"
#  s_${series}_nmis: "number of packages that are missing"
#  s_${series}_du:   "disk space usage of all packages found"
#  s_${series}_dus:  "disk space usage of selected packages"
#  s_${series}_h:    "help text"
###############################################################################

###############################################################################
# The package structure:
#  p_${package}_n:  "the name of the package"
#  p_${package}_s:  "is the package selected?"
#  p_${package}_l:  "level: required, recommended or optional"
#  p_${package}_da: "did we find the package?"
#  p_${package}_fn: "the filename of a package the we found"
#  p_${package}_h:  "help text"
###############################################################################

allseries_locate()
{
    for al_series in $S_all_la;
    do
        series_locate $al_series;
    done
}

allseries_locate_check()
{
    notall=false
    hasbin=false
    test "$this_platform" != "" &&
        eval test \"\$p_${this_platform}_da\" = true &&
        hasbin=true
    for alc_series in $S_all_la; do
        test $alc_series = bin && $hasbin && continue
        eval alc_all_packages=\"\$s_${alc_series}_la\"
        for alc_p in $alc_all_packages; do
          if eval test \"\$p_${alc_p}_da\" = false; then
            notall=true
            eval echo \""Warning: package not found: \${p_${alc_p}_d-$alc_p} (series: $alc_series)."\"
          fi
        done
    done
    if test "$notall" = true; then
        echo
        echo "Notice: ignore the warnings, if the packages are missing intentionally."
        echo
        $echon "Press return to continue or Control-C to abort... "
        read foo
    fi
}

series_locate()
{
    sl_series=$1
    eval sl_all_packages=\"\$s_${sl_series}_la\"
    eval dft_dir=\"\$s_${sl_series}_d\"
    lf=; mis=; nmis=0; nf=0
    for sl_p in $sl_all_packages; do
        eval bn=\${p_${sl_p}_d-$sl_p}
        fn=
        test -f $here/$dft_dir/$bn.tar.gz && fn=$here/$dft_dir/$bn.tar.gz
        test -f $here/$bn.tar.gz && fn=$here/$bn.tar.gz
        if test -z "$fn"; then
          eval p_${sl_p}_da=false
          eval p_${sl_p}_fn=

          mis="$mis $sl_p"
          nmis=`expr $nmis + 1`
        else
          eval p_${sl_p}_da=true
          eval p_${sl_p}_fn=$fn

          lf="$lf $sl_p"
          nf=`expr $nf + 1`
        fi
    done
    eval s_${sl_series}_lf=\"$lf\"
    eval s_${sl_series}_mis=\"$mis\"
    eval s_${sl_series}_nmis=$nmis
    eval s_${sl_series}_nf=$nf
    setlength s_${sl_series}_nf 2
}

series_select_all()
{
    ssa_series=$1
    eval all_packages=\"\$s_${ssa_series}_lf\"
    for ssa_p in $all_packages; do
        package_select $ssa_p
    done
    series_stat $ssa_series
}

series_deselect_all()
{
    sda_series=$1
    eval all_packages=\"\$s_${sda_series}_lf\"
    for sda_p in $all_packages; do
        package_deselect $sda_p
    done
    series_stat $sda_series
}

series_stat()
{
    series=$1
    dus=0
    ns=0
    ls=''
    eval ss_all_packages=\"\$s_${series}_lf\"
    for ss_p in $ss_all_packages; do
        eval \$p_${ss_p}_s || continue
        eval newdu=\"\$p_${ss_p}_du\"
        if test -z "$newdu"; then
          echo "unknown disk space usage for package: $ss_p"
          newdu=0
        fi
        ls="$ls $ss_p"
        ns=`expr $ns + 1`
        dus=`expr $dus + $newdu`
    done
    eval s_${series}_dus=\$dus
    setlength s_${series}_dus 5
    eval s_${series}_ns=\$ns
    setlength s_${series}_ns 2
    eval s_${series}_ls=\$ls
}

nobin_stat()
{
    dus=0; nf=0; ns=0;
    for ns_series in $S_nobin_la; do
      eval dus=\`expr \$dus + \$s_${ns_series}_dus\`
      eval nf=\` expr \$nf  + \$s_${ns_series}_nf\`
      eval ns=\` expr \$ns  + \$s_${ns_series}_ns\`
    done
    S_nobin_dus=$dus;  setlength S_nobin_dus 5
    S_nobin_nf=$nf;    setlength S_nobin_nf 2
    S_nobin_ns=$ns;    setlength S_nobin_ns 2
    total_stat
}

total_stat()
{
    s_total_dus=`expr $s_bin_dus + $S_nobin_dus`; setlength s_total_dus 5
    s_total_nf=`expr $s_bin_nf + $S_nobin_nf`;    setlength s_total_nf 2
    s_total_ns=`expr $s_bin_ns + $S_nobin_ns`;    setlength s_total_du 2
}

package_select()   { eval p_${1}_s=true;  }
package_deselect() { eval p_${1}_s=false; }

series_list()
{
    sl_series=$1
    cls
    echo "Series \`\`$sl_series'' statistics:"; echo
    echo "                  package name   size selected"
    echo "  --------------------------------------------"
    eval sl_all_p=\"\$s_${sl_series}_lf\"
    for sl_p in $sl_all_p; do
      eval sl_n=\"\$p_${sl_p}_n\"
      eval sl_du=\"\$p_${sl_p}_du\"
      eval sl_s=\"\$p_${sl_p}_s\"
      if $sl_s; then sl_s='[X]'; else sl_s='[ ]'; fi
      setlength sl_n 30
      setlength sl_du 5
      echo "$sl_n ${sl_du}k    $sl_s"
    done
    eval sl_s_dus=\"\$s_${sl_series}_dus\"
    setlength sl_s_dus 5
    echo "  --------------------------------------------"
    echo "                selected size: ${sl_s_dus}k"
    echo
    echo
    readln
}

series_init()
{
    $echon "Locating packages... "; allseries_locate; echo "Done."
    $echon "Initializing series... "
    for si_series in $S_nobin_la; do
        series_select_all $si_series
    done
    echo "Done."
    series_deselect_all bin
    test -z "$this_platform" || {
        this_platform_set "$this_platform"
        package_select "$this_platform"
        series_stat bin
    }
    allseries_locate_check
}

this_platform_set()
{
    this_platform="$1"
    for tps_p in $s_bin_lf; do
        eval p_${tps_p}_l=optional
    done
    series_deselect_all bin
    if test -z "$this_platform"; then
        this_platform_n=
        this_platform_d=
    else
      package_select ${this_platform}
      series_stat bin
      eval this_platform_n=\$p_${this_platform}_n
      eval this_platform_d=\$p_${this_platform}_d
      eval p_${this_platform}_l=required
    fi
    nobin_stat
}

############################