#!/bin/sh

# PLEASE READ all documentation and make the appropriate edits before use.

###########################################################################
# get -- Get files from MS-DOS archive site.
#        Version 2.0
#
# call: get <site> <directory> <file...> <directory> <file...> ...
#
# Wildcard file specifications are supported, but must be quoted so that the
# calling shell doesn't try to expand them.  All parameters are basenamed and
# shifted to lower case, to make it easy to cut and paste references from
# news articles or other sources.  (This feature can be disabled for sites,
# such as microsoft, that use mixed case names).
#
# The site name parameter is a nickname you assign to each site of interest.
# For example, I treat the SimTel archive as two sites: one called "simtel"
# (DOS files) and one called "simwin" (Windows files).  Use whatever name
# you'll be able to remember.  You may assign multiple nicknames to one site.
#
# You may use the full ftp address in place of the nickname, if you wish.
# In the event of duplication, the first match will be used.
#
# In the site name table, each entry represents a combination of ftp address
# and root directory.  This allows get to work well with the larger archive
# sites, some of which maintain several independent collections.
#
# You can easily change the table of site names: see the "FAVORITE SITES"
# comment below.
#
# If the environment variable FTPLOG is set to a file name, then a record of
# your ftp transactions will be appended to that file.  Example:
#    Bourne shell and equivalents:
#                      FTPLOG=$HOME/my_file_transfers
#                      export FTPLOG
#    C shell and equivalents:
#                      setenv FTPLOG $HOME/my_file_transfers
#
# Example: get files from oak.oakland.edu, including names matching wildcard:
#
#     get simtel info 'inter33*.zip' turbopas anivga11.zip unitre12.zip
#         (site) (dir) (w/c files)   (dir)    (file)       (file)
#
# Example: show basename and lower-case features (useful for cut/paste):
#
#     get oak /SimTel/msdos/microsoft PD0646.ZIP
#       (site)(dir)                   (file)
#
# If the first parameter is not a site nickname, but it does bear a passing
# resemblance to an ftp address, this script will attempt to connect there.
# If a matching entry can be found in the site name table, it will be used,
# else files will be fetched from the root directory at the specified site.
#
# Example: get a file from someplace not in the site table:
#
#     get ftp.cray.com /applications/news Parallel_Codes.9312.txt
#
#
# Not-Bugs:
# 1) If you see a message along these lines:
#      ERROR [something]: not an SCCS file (co1)
#    it means that the SCCS "get" command is found earlier in your path than
#    this script.  Change your path to put your own scripts ahead of system
#    binaries, or rename it to something that doesn't conflict ("getftp", for
#    example.
#
# 2) If you see a message along these lines:
#      sh: --: bad option(s)
#    try changing the tippy-top line up there to
#      #!/bin/sh5
#    If that doesn't work, ask somebody local; I've never heard of your brand
#    of Unix.
#
# 3) If you see a message along these lines:
#      getopts: Command not found.
#    then your system is missing the getotps command.  Look below for the
#    comment "USE THIS IF YOUR VERSION OF UNIX DOES NOT SUPPORT GETOPTS";
#    then delete the getopts code and uncomment the getopt code.
#
# Notes:
# 1) Before using this script, change the ftp login to use your internet
#    address (see comment "CHANGE TO YOUR ADDRESS" below).  Also take a look
#    at the site name table below, to make sure it includes the sites you
#    use.  (Note in particular the illustrative -d and -t flags on the first
#    two entries -- you probably don't want them left as is.)
# 2) Site nicknames must be an exact match, not just a substring (changed
#    from earlier versions).
# 3) It is *not* necessary to get a fresh update of this script everytime an
#    archive site changes its directory structure.  No directory names are
#    hard coded.
# 4) If you want to fetch files into certain directories on your machine, or
#    even follow an archive site's directory structure, set the -d and/or -t
#    options (see site name table, below).
# 5) The way that this script works is to assume that anything with a period
#    in it is a file name, and anything without a period is a directory name.
#    Other reasonable schemes have been proposed.  However, this works very
#    well for every PC archive site I've visited.  And that's exactly what
#    this script is for.
# 6) I welcome comments.  Thanks to Kees Visser(*), Mike McDonald, Timo
#    Salmi, Rolf Bronstering, Hamish MacEwan, Shidong Tong, Ewan Ng, Pieter
#    Moerman(*), and others for comments and suggestions on earlier versions.
#    (*) = Thanks extra.
#
# Author: Jonathan C. Rice, rice@zizania.cray.com
###########################################################################


################# CHANGE TO YOUR ADDRESS ! ! ! ! ! ########################

mysite=catatonic.state.edu          ### <<--- change this to your site name

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

set -f
usage="Usage: `basename $0` <site> <dir> <files...> <dir> <files...> ..."
if [ $# -lt 3 ]
then
  echo $usage
  exit 1
fi
  
remote=`(
#############################################################################
#     **** MODIFY THE FOLLOWING TABLE TO INCLUDE YOUR FAVORITE SITES ****
#
# Format:
#   -n <nickname>    This is the name YOU give to the site and base
#                    directory.  Choose whatever unique identifier will help
#                    you keep things straight.  For sites that maintain two or
#                    more independent collections, it might be best to assign
#                    several nicknames to the site, one for each root
#                    directory. 
#   -s <site name>   This is the site's internet address.
#   -r <path name>   This is the directory that forms the root of the search
#                    space.  For most sites, one "master" parent directory
#                    contains all of the MS-DOS files.  The path name must
#                    include an asterisk to show where subdirectory names go.
#   -b               If this flag is present, all arguments will be run
#                    through 'basename'.
#   -l               If this flag is present, all arguments will be converted
#                    to lower case.  The -b and -l flags can make it easier
#                    to cut-and-paste a get command from various posted
#                    references to files.
#   -d <local dir>   This is the local directory (the place in YOUR file
#                    system, not the archive site's file system) into which
#                    you want files to be fetched.
#   -t               If this flag is specified, then the local directory (-d)
#                    is the base of a directory tree; files are fetched into
#                    subdirectories with names matching those on the archive
#                    site.
#
# Required: -n, -s, -r
# Optional: -b, -l, -d, -t.
#
# Pitfalls: using -t but not -b will yield path names you probably don't
#  want.  Using -t but not -d will work fine but only if you happen to be
#  occupying the directory with the proper subtree.
#  Use both -b and -d <local dir> when you enable -t and all should be rosy.
#
# Examples: look at these sample entries:
#
# -n simtel -n oak -s oak.oakland.edu -r /SimTel/msdos/* -d $HOME/pc/oak -tbl
# -n simwin -s oak.oakland.edu -r /SimTel/win3/* -d $HOME/pc/oak/windows -bl
#
#  First, note that there are two nicknames (-n) on the first line.  This
#  allows me to refer to the site as simtel or as oak, whichever name pops
#  into my head.
#
#  Second, look at the -d and -t options on the first entry.  The -d option
#  says, "when fetching files from simtel/oak, don't fetch them into the
#  current working directory, but instead into $HOME/pc/oak."  That allows me
#  to separate files by origin until I can deal with them.  The addition of
#  the -t flag (it's part of "-tbl" at the end of the line) says, "...don't
#  really fetch the files into $HOME/pc/oak, but into $HOME/pc/oak/asmutil or
#  $HOME/pc/oak/deskaccs or $HOME/pc/oak/zmodem" and so on, according to the
#  directory structure at SimTel.  The net result of this is that I can
#  maintain a mirror-like file system, containing only those files I've
#  ftp'ed, of course, on my own machine.
#
#  N.B.: the local subtree MUST EXIST BEFORE USING -t -- this script does not
#  *create* local directories.
#
#  Third, note that the second entry (simwin) only includes the -d flag, not
#  the -t flag.  In other words, I want any windows program fetched into
#  $HOME/pc/oak/windows -- but I don't care which SimTel windows subdirectory
#  it came from.
#
#  Files from any site without the -d switch will be fetched into the current
#  working directory.  [If you'd like some other default behavior, change
#  "local="."" where indicated below.]
#
# Comments are ok within the site table, provided that they don't contain
# a string of the form "-n something" or "-s something".
#
##############################################################################

grep -i "\-[ns]\ \{1,\}$1\ " <<EOF | head -1

# The mighty SimTel Repository: great job, Keith...
#   NOTE the use of the -d and -t options -- REMOVE THESE if you don't want
#   to work that way.
-n simtel -n oak -s oak.oakland.edu -r /SimTel/msdos/* -bl
-n simwin    -s oak.oakland.edu -r /SimTel/win3/* -bl
-n pcblue    -s oak.oakland.edu -r /pub/pc-blue/*

# The canonical Windows site; and its mirrors, which are actually accesible...
-n cica      -s ftp.cica.indiana.edu -r /pub/pc/win3/* -bl
-n cica-cd   -s ftp.cdrom.com -r /pub/cica/* -bl
-n cica-dec  -s gatekeeper.dec.com -r /pub/micro/msdos/win3/* -bl
-n cica-orst -s archive.orst.edu -r /pub/mirrors/ftp.cica.indiana.edu/win3/* -bl
-n cica-il   -s ftp.technion.ac.il -r /pub/unsupported/mswin/cica/* -bl

# Garbo, the good Professor's home grounds; wonderful Pascal collection...
-n garbo     -s garbo.uwasa.fi -r /pc/* -bl
-n garbounix -s garbo.uwasa.fi -r /unix/* -bl
-n garbowin  -s garbo.uwasa.fi -r /windows/* -bl

# Borland compilers: examples and tips...
-n bp        -s ftp.borland.com -r /pub/libs/pas/bi/* -bl
-n bc        -s ftp.borland.com -r /pub/libs/c/bi/* -bl

# Microsoft...
-n msdos     -s ftp.microsoft.com -r /peropsys/msdos/*
-n mswin     -s ftp.microsoft.com -r /peropsys/windows/*

# And miscellany...
-n defunct   -s wsmr-simtel20.army.mil -r pd1:<msdos.*> -bl
-n ulowell -n uml -s ftp.uml.edu -r /msdos/games/* -b
-n uwp       -s ftp.uwp.edu -r /pub/msdos/games/* -bl
-n pcgpe -n oulu -s x2ftp.oulu.fi -r /pub/msdos/programming/* -bl
-n victoria  -s ftp.comp.vuw.ac.nz -r /msdos/*
-n demos     -s hornet.eng.ufl.edu -r /pub/msdos/demos/* -bl
-n wuarchive -s wuarchive.wustl.edu -r /systems/ibmpc/msdos/* -bl
-n uunet     -s ftp.uu.net -r /systems/ibmpc/msdos/simtel/* -bl
-n heidelberg -s sun0.urz.uni-heidelberg.de -r /mirrors/msdos/* -bl

EOF
)`

if [ -z "$remote" ]
then
  echo "No place named $1 in site table,"
  case $1 in
    *.*)
      echo "will try to FTP to its root directory."
      remote="-n unlisted -s $1 -r /*";;
    *)
      echo "and it doesn't look like an FTP address."
      echo $usage
      exit 1;;
  esac
fi
shift

basename="echo"
lower=""
subtree=""
local="."  ########## <<-- if you want a default local directory, set it here

##### USE THIS IF YOUR VERSION OF UNIX SUPPORTS "GETOPTS" #####

while getopts bd:ln:r:s:t p $remote
do
  case $p in
    b) basename="basename";;
    d) local=$OPTARG;;
    l) lower="| tr A-Z a-z";;
    n) nickname=$OPTARG;;
    r) root=$OPTARG;;
    s) site=$OPTARG;;
    t) subtree='echo lcd $local/$f';;
    \?) echo "Bad site table entry:"; echo "$remote"; exit 1;;
  esac
done

##### USE THIS IF YOUR VERSION OF UNIX DOES NOT SUPPORT "GETOPTS" #####
# inputargs=$*
# set -- `getopt bd:ln:r:s:t $remote`
# while [ $1 != -- ]
# do
#   case $1 in
#     -b) basename="basename"
#         shift;;
#     -d) local=$2
#         shift 2;;
#     -l) lower="| tr A-Z a-z"
#         shift;;
#     -n) nickname=$2
#         shift 2;;
#     -r) root=$2
#         shift 2;;
#     -s) site=$2
#         shift 2;;
#     -t) subtree='echo lcd $local/$f'
#         shift;;
#   esac
# done
# set -- `getopt x $inputargs`
# shift
########################################################################

echo "*** Connecting to $site ($nickname) ***"

(
echo "user anonymous $USER@$mysite"
echo binary
echo lcd $local
while [ $# -gt 0 ]
do
  f=`eval $basename $1 $lower`
  case $f in
    *\**|*\?*)
      echo mget $f
      echo `date '+19%y-%m-%d %T GET ftp:'`//$site$d/$f >>${FTPLOG:=/dev/null};;
    *.*)
      echo get $f
      echo `date '+19%y-%m-%d %T GET ftp:'`//$site$d/$f >>${FTPLOG:=/dev/null};;
    *)
      d=`echo $root|sed -e "s!\*!$f!"`
      echo cd $d
      eval $subtree
      ;;
  esac
  shift
done
echo quit
) | ftp -vin $site
