#!/bin/sh
#
# brief - easily obtain a weather briefing from Contel DUATS
#
# @(#) brief 1.26, 23 March 1992
#
# Copyright (C) 1991, 1992 Geoffrey G. Peck, All Rights Reserved.
#
# This script was written by Geoff Peck, geoff@apple.com, with input from a
# cast of a thousand netters.  No warranty or support of any kind is implied.
#
# This script may be freely re-distributed at no charge provided that
# this notice is left intact.  Modified copies must preserve this notice.
# It is requested that any useful changes you make be sent to the author.
#
# Please make sure that you have successfully connected to Contel via
# the internet (telnet duats.contel.com or telnet 131.131.7.106 for those
# who are not certificated pilots; duat.contel.com or 131.131.7.105 for
# those who are) _before_ you use this script!
#
# typical use:
#    brief -from lax -to pdx -route direct -duration 1000 | lpr
#
# One may also create "default options" files, which are shell scripts
# which set appropriate variables, so one might utter the command
#    brief -o outputfile laxpdx
#
# You may create a file ".briefrc" in your home directory which contains
# Bourne-style lines to set defaults for various variables.  At a minimum,
# it is suggested that you set:
#   myacct=10099999	# contel duats account number
#   mypw='abracadabra'	# contel duats password
# If you would rather not store your password, simply omit that line and
# you will be prompted for the password each time you use this script.
#
# Users who are not pilots, or who have not obtained a duats account
# number, may specify "myacct=anonymous" or use the command-line option
# "-anon" to obtain a briefing.  Note that anonymous users may not file
# flight plans, and such anonymous briefings are _not_ considered "legal"
# pre-flight briefings.  If you use the anonymous option, you will not be
# asked to supply a password.
#
# Other things you'll probably want in your .briefrc include:
#    from=RHV		# departure airport
#    to=TRK		# destination airport
#    altitude=095	# altitude for flight - 3 digits
#    duration=0130	# duration of flight - 4 digits
#   			# note: if you make the duration greater than 12 hours,
#   			# you will frequently get additional winds aloft
#   			# forecasts, which is good for planning purposes
#    plantype=VFR	# VFR or IFR
#    actype='PA28/R'	# aircraft type/suffix ... blank = stored default
#    tas=130		# true airspeed, knots
#    fuel=0500		# fuel on board - 4 digits
#    homebase=RHV	# aircraft home base
#    numaboard=2	# number aboard
#    color='WHT/BLU'	# aircraft color
#    decode=Y           # Y to decode weather briefing
#
# Finally, if you have a brain-dead DNS (dynamic name server), you should
# add the following lines (uncommented) to your .briefrc:
#    pilotduatshost=131.131.7.105
#    nonpilotduatshost=131.131.7.106
#
# The ".briefrc" file is present so that you need not make _any_ changes
# to this script for most simple customizations, and you can integrate
# updates into your work environment more easily.
#
# Note also that you may have additional "custom" files with arbitrary
# names which are invoked at runtime, e.g. "brief rhv-sba" would open
# a file named "rhv-sba" which could override options.  The order of
# option overriding, from lowest-priority to highest-priority, is:
# (1) this file, (2) your .briefrc, (3) command-line options in left-to
# right order, including any "custom" files in the order specified.
# So, you could say "brief -file 2901T rhv-sba" ...

# -----------------------------------------------------------------
# defaults -- most can be overridden with command-line options or .briefrc

# weather briefing default parameters

aircraft=		# aircraft ID (Nxxxxx) ... blank = use stored default
from=			# departure airport
to=			# destination airport
fromnow=60		# minutes from now to depart
altitude=		# altitude for flight - 3 digits
route="DIRECT"		# route of flight
duration=		# duration of flight - 4 digits
fdcnotams=Y		# Y to suppress FDC notams
outputfile=		# blank - standard output
decode=			# Y to decode weather briefing

# flight plan filing default parameters

fileplan=		# Y to file a flight plan -- do not default this!
plantype=		# VFR or IFR
actype=			# aircraft type/suffix ... blank = stored default
tas=			# true airspeed, knots
fuel=			# fuel on board - 4 digits
remarks=		# default remarks
pilotname=		# pilot name ... blank = use stored default
pilotaddr=		# pilot address ... blank = use stored default
pilotphone=		# pilot phone ... blank = use stored default
homebase=		# aircraft home base
numaboard=		# number aboard
color=			# aircraft color
destname=		# destination contact name
destphone=		# destination contact phone

# duats host -- use 131.131.7.105/106 if you have a brain-dead DNS

pilotduatshost=duat.contel.com		# for certificated pilots
nonpilotduatshost=duats.contel.com	# for non-certificated-pilot users

# if you are on a "secure" internal network and can telnet to a machine with
# "outside-world" access, set the following variables.  If you do not wish
# to set gatewaypw, you will be prompted for it on each use of the script.

gatewaymachine=		# machine on the open internet
gatewayuser=		# login name on gateway machine
gatewaypw=		# password for gateway machine

# -----------------------------------------------------------------

if [ -r /usr/5bin/echo ]
then
    PATH=/usr/5bin:$PATH
    export PATH
fi

if [ -r $HOME/.briefrc ]
then
    . $HOME/.briefrc
fi

tmpfile=/tmp/WX$$
outfil=/tmp/WXOUT$$
statfile=/tmp/WXS$$

trap "rm -f $tmpfile $outfil $statfile" 1 2 3 15

# get time now, UTC 

if [ -r /bin/uname ]
then			# system V systems...
    timenow=`TZ=UTC0 date +%H%M`
    thishost=`uname -n`
else			# 4BSD systems ...
    timenow=`date -u | sed 's/^...........\(..\).\(..\).*$/\1\2/'`
    thishost=`hostname`
fi
timezone=`date | sed 's/^....................\(...\).*$/\1/'`

# if logged into the gateway machine, avoid the additional telnet hop...

if [ "$thishost" = "$gatewaymachine" ]
then
    gatewaymachine=
fi

# override defaults using command-line options

while [ `expr $# '>' 0` -eq 1 ]
do
    case $1 in
    -account|-acct)
	myacct=$2
	mypw=
	if [ `expr "$myacct" : '^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$'` -eq 0 ]
	then
	    echo 1>&2 $1 $2": $1 option requires an 8-digit numeric argument"
	    exit 1
	fi
	shift
	;;
    -anon|-anonymous)
	myacct=anonymous
	mypw=
	;;
    -aircraft|-id|-tail)
	aircraft=$2
	if [ `expr "$aircraft" : '^[nN][A-Za-z0-9]'` -eq 0 ]
	then
	    echo 1>&2 $1 $2": invalid N-number -- must start with 'N'"
	    exit 1
	fi
	shift
	;;
    -from)
	from=$2
	shift
	;;
    -dest|-destination|-to)
	to=$2
	shift
	;;
    -local)
	from=$2
	to=$2
	route=DIRECT
	local=1
	shift
	;;
    -fromnow)
	fromnow=$2
	if [ `expr "$fromnow" : '^[0-9]*$'` -eq 0 ]
	then
	    echo 1>&2 $1 $2": $1 option requires a numeric argument"
	    exit 1
	fi
	shift
	;;
    -altitude|-fl)
	altitude=$2
	if [ `expr "$altitude" : '^[0-9][0-9][0-9]$'` -eq 0 ]
	then
	    echo 1>&2 $1 $2": $1 option requires a 3-digit argument"
	    exit 1
	fi
	shift
	;;
    -duration)
	duration=$2
	if [ `expr "$duration" : '^[0-2][0-9][0-9][0-9]$'` -eq 0 ]
	then
	    echo 1>&2 $1 $2": $1 option requires a 4-digit argument"
	    exit 1
	fi
	shift
	;;
    -time|-depart)
	fromnow=0
	timenow=$2
	if [ `expr "$timenow" : '^[0-2][0-9][0-9][0-9]$'` -eq 0 ]
	then
	    echo 1>&2 $1 $2": $1 option requires a 4-digit argument"
	    exit 1
	fi
	shift
	;;
    -route|-via)
	route=$2
	shift
	;;
    -alternate|-alt)
	alternate=$2
	shift
	;;
    -fdc|-fdcnotams)
	fdcnotams=
	;;
    -nofdc|-nofdcnotams)
	fdcnotams=Y
	;;
    -decode)
	decode=Y
	;;
    -nodecode)
	decode=
	;;
    -timezone)
	timezone=$2
	if [ `expr "$timezone" : '^[ecmpECMP][sdSD][tT]$'` -eq 0 ]
	then
	    echo 1>&2 $1 $2": invalid timezone -- try PST, PDT, EST, etc."
	    exit 1
	fi
	shift
	;;
    -file|-flightplan)
	fileplan=Y
	;;
    -vfr)
	plantype=VFR
	;;
    -ifr)
	plantype=IFR
	;;
    -type)
	actype=$2
	shift
	;;
    -tas|-speed)
	tas=$2
	shift
	;;
    -fuel)
	fuel=$2
	if [ `expr "$fuel" : '^[0-1][0-9][0-9][0-9]$'` -eq 0 ]
	then
	    echo 1>&2 $1 $2": $1 option requires a 4-digit argument"
	    exit 1
	fi
	shift
	;;
    -remarks)
	remarks=$2
	shift
	;;
    -name|-pilot)
	pilotname=$2
	shift
	;;
    -address)
	pilotaddr=$2
	shift
	;;
    -phone)
	pilotphone=$2
	if [ `expr "$pilotphone" : '^[0-9][0-1][0-9] [0-9][0-9][0-9] [0-9][0-9][0-9][0-9]$'` -eq 0 ]
	then
	    echo 1>&2 $1 $2": $1 option requires a telephone number argument"
	    echo 1>&2 "formatted as NNN NNN NNNN"
	    exit 1
	fi
	shift
	;;
    -base)
	homebase=$2
	shift
	;;
    -pax|-passengers|-aboard)
	numaboard=$2
	if [ `expr "$numaboard" : '^[0-9]*$'` -eq 0 ]
	then
	    echo 1>&2 $1 $2": $1 option requires a numeric argument"
	    exit 1
	fi
	shift
	;;
    -color)
	color=$2
	shift
	;;
    -destname)
	destname=$2
	shift
	;;
    -destphone)
	destphone=$2
	if [ `expr "$destphone" : '^[0-9][0-1][0-9] [0-9][0-9][0-9] [0-9][0-9][0-9][0-9]$'` -eq 0 ]
	then
	    echo 1>&2 $1 $2": $1 option requires a telephone number argument"
	    echo 1>&2 "formatted as NNN NNN NNNN"
	    exit 1
	fi
	shift
	;;
    -o)
	outputfile=$2
	shift
	;;
    -help)
	echo 1>&2 'Main options:
    -from airport-id
    -to airport-id
    -local airport-id          ... local briefing (sets -to, -from, -via)
    -via "fix1 fix2 ... fixN"  ... route of flight
    -altitude altitude         ... 3 digits, as in 030
    -duration time-enroute     ... 4 digits, as in 0130
    -fromnow minutes           ... departure time, minutes from now
    -time time-off             ... (or, if you prefer) departure time, zulu
    -fdc | -nofdc              ... display/suppress FDC NOTAMS
    -decode | -nodecode        ... display/suppress decoded briefing
    -timezone zone             ... select timezone (default = from your host)
    -aircraft aircraft-id
    -o outputfile
    -watch                     ... watch session in progress (use with -o)
    -show                      ... show options before connecting to DUATS
    -debug                     ... show intermediate script but don'"'"'t login
    -anon                      ... log on to Contel anonymously
    -acct 10000000             ... specify Contel account number
    
If you wish to file a flight plan, the following options are available:

    -file                      ... file a flight plan
    -vfr                       ... make it VFR
    -ifr                       ... make it IFR
    -type type/s               ... aircraft type + suffix, e.g. PA28/R
    -tas speed                 ... true airspeed in knots
    -fuel time                 ... fuel on boards, 4 digits, as 0500
    -alternate airport-id      ... alternate airport if required
    -remarks "whatever"
    -pilot "pilot name"
    -address "pilot address"
    -phone "212 555 1212"      ... pilot phone formatted as shown
    -base airport-id           ... aircraft home base
    -pax number                ... number of passengers on board
    -color "wht/blk"           ... aircraft colors
    -destname "destination contact"
    -destphone "212 555 1212"  ... destination phone formatted as shown'
	exit
	;;
    -show)
	show=Y
	;;
    -debug)
	debug=Y
	;;
    -watch)
	watch=Y
	;;
    -nowatch)
	watch=
	;;
    -*)
	echo 1>&2 $1': unknown option -- try -help'
	exit 1
	;;
    *)
	# non-flag argument is taken to be an options file
	if [ -r $1 ]
	then
	    . $1
	else
	    echo 1>&2 $1': unexpected argument -- try -help'
	    exit 1
	fi
	;;
    esac
    shift
done

# obtain passwords which have not been defaulted...

while [ `expr "$myacct" : '^10[0-9][0-9][0-9][0-9][0-9][0-9]$'` -eq 0 -a \
	"$myacct" != anonymous ]
do
    if [ -n "$myacct" ]
    then
	echo 1>&2 $myacct': invalid account number -- must be 8 digits (10xxxxxx)'
    fi
    echo 1>&2 Enter Contel DUATS account number or '"anonymous":  \c'
    read myacct
done
while [ -z "$mypw" -a "$myacct" != anonymous ]
do
    echo 1>&2 Enter DUATS password for account $myacct':  \c'
    trap "stty echo;exit" 2
    stty -echo
    read mypw
    stty echo
    echo
    trap 2
done
while [ -n "$gatewaymachine" -a -n "$gatewayuser" -a -z "$gatewaypw" ]
do
    echo 1>&2 Enter password for $gatewayuser on $gatewaymachine':  \c'
    trap "stty echo;exit" 2
    stty -echo
    read gatewaypw
    stty echo
    echo
    trap 2
done
if [ "$myacct" = anonymous ]
then
    duatshost="$nonpilotduatshost"
else
    duatshost="$pilotduatshost"
fi

# check that a minimum set of variables has been set

if [ -z "$from" -o -z "$to" -o -z "$altitude" -o -z "$route" -o -z "$duration" ]
then
    echo 1>&2 One or more mandatory fields are missing...
    echo 1>&2 '    'Airport of origin '(-from)' = $from
    echo 1>&2 '    'Destination airport '(-to)' = $to
    echo 1>&2 '    'Enroute altitude '(-altitude)' = $altitude
    echo 1>&2 '    'Route of flight '(-route)' = $route
    echo 1>&2 '    'Flight duration '(-duration)' = $duration
    exit 1
fi

# if filing a flight plan, test that the appropriate variables have been set

if [ "$myacct" = anonymous -a "$fileplan" ]
then
    echo 1>&2 Anonymous users may not file flight plans.
    exit 1
fi
if [ "$fileplan" ]
then
    if [ -z "$plantype" -o -z "$tas" -o -z "$fuel" -o -z "$homebase" -o \
	    -z "$numaboard" -o -z "$color" ]
    then
	echo 1>&2 Cannot file a flight plan because one or more mandatory fields are missing...
	echo 1>&2 '    'Flight plan type '(-vfr or -ifr)' = $plantype
	echo 1>&2 '    'True airspeed '(-tas)' = $tas
	echo 1>&2 '    'Fuel on board '(-fuel)' = $fuel
	echo 1>&2 '    'Aircraft home base '(-base)' = $homebase
	echo 1>&2 '    'Number aboard '(-pax)' = $numaboard
	echo 1>&2 '    'Aircraft color '(-color)' = $color
	exit 1
    fi
fi

# check color field for validity

if [ "$color" ]
then
    okcolors='^(A|B|BE|BK|BR|G|GD|GY|M|O|P|R|S|T|TQ|V|W|Y|AMBER|BLUE|BEIGE|BLACK|BROWN|GREEN|GOLD|GRAY|MAROON|ORANGE|PURPLE|RED|SILVER|TAN|TURQUOISE|VIOLET|WHITE|YELLOW)$'
    badcolors=`echo $color | tr '/' '\12' | tr '[a-z]' '[A-Z]' | egrep -v "$okcolors"`
    if [ "$badcolors" ]
    then
	echo 1>&2 "Invalid color(s): `echo $badcolors`"
echo 1>&2 '  Use either the CODE or the WORD from the following list:
      A  Amber      GD Gold      S  Silver
      B  Blue       GY Gray      T  Tan
      BE Beige      M  Maroon    TQ Turquoise
      BK Black      O  Orange    V  Violet
      BR Brown      P  Purple    W  White
      G  Green      R  Red       Y  Yellow'
	exit 1
    fi
fi

# compute time off in zulu

timeoff=`echo $timenow $fromnow |
	 awk '{ a = (int($1 / 100) * 60) + ($1 % 100) + $2 ;
	        printf "%02d%02d", (int(a / 60) % 24), a % 60 }'`

# compute time zone menu selection number

case "$timezone" in
    EST|EDT)
	timezoneid=E
	;;
    CST|CDT)
	timezoneid=C
	;;
    MST|MDT)
	timezoneid=M
	;;
    PST|PDT)
	timezoneid=P
	;;
    *)
	echo 1>&2 "Invalid timezone $timezone"
	exit 1
esac

# construct a script that logs into duat.contel.com and types the right
# stuff at it -- the delays below are very approximate and might need
# to be adjusted ... sigh ...

# build up quick-path command in "cmd"

cmd='#PLOS'
cmd="$cmd%$timezoneid"
if [ "$myacct" != anonymous ]	# don't specify an aircraft ID for anon users
then
    cmd="$cmd%$aircraft"
fi
cmd="$cmd%$from"
cmd="$cmd%$to"
cmd="$cmd%$timeoff"
cmd="$cmd%$altitude"
cmd="$cmd%$route"
cmd="$cmd%$duration"
cmd="$cmd%$fdcnotams"
cmd="$cmd%"

if [ ! "$decode" ]
then
    # suppress decoded weather
    cmd="$cmd"Q
fi
cmd="$cmd%"

if [ ! "$fileplan" ]
then
    cmd="${cmd}BYE%Y"	# sign off at end of weather briefing
fi

# if filing a flight plan, assemble quick-path command in "file"

if [ "$fileplan" ]
then
  file='#FPDS'
  file="$file%$plantype"	# flight plan type
  file="$file%$aircraft"	# aircraft tail number
  file="$file%$actype"		# aircraft type / equipment
  file="$file%$tas"		# true airspeed
  file="$file%$from"		# departure point
  file="$file%$to"		# destination
  file="$file%$timeoff"		# departure time
  file="$file%$altitude"	# altitude
  file="$file%$route"		# route
  file="$file%$duration"	# duration
  file="$file%$remarks"		# remarks
  file="$file%$fuel"		# fuel on board
  file="$file%$alternate"	# alternate
  file="$file%$pilotname"	# pilot name
  file="$file%$pilotaddr"	# pilot address
  file="$file%$pilotphone"	# pilot phone
  file="$file%$homebase"	# aircraft home base
  file="$file%$numaboard"	# number aboard
  file="$file%$color"		# color of aircraft
  file="$file%$destname"	# destination contact name
  file="$file%$destphone"	# destination contact phone
  file="$file%"
fi

echo "#!/bin/sh
(sleep 600 &
 (sleep 5 ; echo $myacct" > $tmpfile
if [ "$myacct" = anonymous ]
then
    echo "  sleep 2 ; echo internet		 # first name
  sleep 2 ; echo q  		# middle initial
  sleep 2 ; echo    		# no pilot certificate number
  sleep 2 ; echo 80 		# characters per line
  sleep 2 ; echo 0  		# lines per page
  sleep 3 ; echo $aircraft	# aircraft ID if any" >> $tmpfile
fi
echo "  sleep 5 ; echo $mypw
  # CR to continue after boilerplate message
  sleep 5 ; echo
  # use fastpath mechanism -- obtain low altitude briefing
  sleep 2 ; echo '$cmd' | tr '%' '\\\\\\\\'" >> $tmpfile

if [ "$decode" ]
then
    echo "  # long delay to allow decoded weather to print" >> $tmpfile
    echo "  sleep 60" >> $tmpfile
else
    echo "  # delay to allow weather to print" >> $tmpfile
    echo "  sleep 20" >> $tmpfile
fi

if [ "$file" ]
then
  echo "  # input flight plan data
  sleep 2 ; echo '$file' | tr '%' '\\\\\\\\'
  # file flight plan
  sleep 20 ; echo 'F'
  # sign off
  sleep 2; echo '#BYE%Y' | tr '%' '\\\\\\\\'" >> $tmpfile
fi

echo " )
) | telnet $duatshost" >> $tmpfile

# save options summary in file

(
    echo "Weather briefing requested on" `date`":"
    if [ "$myacct" = anonymous ]
    then
	echo "  Anonymous request -- not valid as an official FAA briefing"
    elif [ "$aircraft" ]
    then
  	echo "  Aircraft:          $aircraft"
    else
	echo "  Aircraft:          [default]"
    fi
    echo     "  Departing:         $from"
    echo     "  At:                $timeoff"
    echo     "  Destination:       $to"
    echo     "  Time enroute:      $duration"
    if [ "$route" ]
    then
  	echo "  Route:             $route"
    else
	echo "  Route:             [direct]"
    fi
    if [ "$fdcnotams" ]
    then
	echo "  Suppressing FDC NOTAMs"
    fi
    if [ "$decode" ]
    then
	echo "  Requesting decoded weather"
    fi

    if [ "$fileplan" ]
    then
	echo "  Filing $plantype flight plan"

	if [ "$actype" ]
	then
	    echo "    Aircraft Type:   $actype"
	else
	    echo "    Aircraft Type:   [default]"
	fi
	echo "    Color:           $color"
	echo "    TAS:             $tas"
	echo "    Fuel on Board:   $fuel"
	echo "    Alternate:       $alternate"
	echo "    Home Base:       $homebase"
	echo "    Souls on Board:  $numaboard"
	if [ "$pilotname" ]
	then
	    echo "    Pilot:           $pilotname"
	fi
	if [ "$pilotaddr" ]
	then
	    echo "    Address:             $pilotaddr"
	fi
	if [ "$pilotphone" ]
	then
	    echo "    Phone:               $pilotphone"
	fi
	if [ "$destname" ]
	then
	    echo "    Destination Contact: $destname"
	fi
	if [ "$destphone" ]
	then
	    echo "    Destination Phone:   $destphone"
	fi
	if [ "$remarks" ]
	then
	    echo "    Remarks:             $remarks"
	fi
    fi
) > $statfile

# display options if requested

if [ "$show" ]
then
    cat 1>&2 $statfile
fi


# obtain the briefing, either directly or via a gateway machine

if [ "$debug" ]
then
    if [ "$outputfile" ]
    then
	cp $tmpfile $outputfile
    else
	cat $tmpfile
    fi
elif [ -z "$gatewaymachine" ]
then
    if [ -z "$watch" ]
    then
	sh $tmpfile 2>&1 > $outfil 
    else
	sh $tmpfile 2>&1 | tee $outfil 
    fi
else
    # log onto machine that is on the open Internet to get the briefing
    if [ -z "$watch" ]
    then
	(sleep 660 &
	 (sleep  3 ; echo $gatewayuser
	  sleep  3 ; echo $gatewaypw
	  sleep 10 ; echo '/bin/sh << EOF'
	  sleep  1 ; cat $tmpfile
	  echo EOF
	  echo exit
	 )
	) | telnet $gatewaymachine 2>&1 > $outfil
    else
	(sleep 660 &
	 (sleep  3 ; echo $gatewayuser
	  sleep  3 ; echo $gatewaypw
	  sleep 10 ; echo '/bin/sh << EOF'
	  sleep  1 ; cat $tmpfile
	  echo EOF
	  echo exit
	 )
	) | telnet $gatewaymachine 2>&1 | tee $outfil
    fi
fi

# trim extraneous junk from the beginning and the end of the briefing

if [ ! "$debug" ]
then
    if [ "$outputfile" ]
    then
	cp $statfile $outputfile
	echo "" >> $outputfile
	sed < $outfil \
	    -e '1,/^Select function/d' \
	    -e '/DUAT Main Menu/,/^Dest contact/d' \
	    -e '/File a Flight Plan/,/enter S to start new session/d' \
	    -e '/Phone no. (nnn nnn nnnn):/d' |
	tr -d '\015' >> $outputfile
    else
	cat $statfile
	echo ""
	sed < $outfil \
	    -e '1,/^Select function/d' \
	    -e '/DUAT Main Menu/,/^Dest contact/d' \
	    -e '/File a Flight Plan/,/enter S to start new session/d' \
	    -e '/Phone no. (nnn nnn nnnn):/d' |
	tr -d '\015'
    fi
fi

rm -f $tmpfile $outfil $statfile


