#!/bin/sh
#	$Id: dunc,v 2.15 1998/03/01 00:47:46 john Exp john $
# set -x

umask 022
BACKTITLE="Debian GNU/Linux Dial Up Networking Configuration Utility"
MINMEN=0

readonly TempFile="/tmp/`echo $0|sed -e 's/^.*\///'`.$$"

# Create a temporary trash bin ...
mkdir ${TempFile}.dir

readonly BASEDIR=${DUNC_DIR:-$HOME/.dunc}
readonly RCFILE=${DUNC_RC:-$HOME/.dunc2rc}
# Define DUNC_UIFILE as Bruce Peren's GPL's shell interface to dialog
readonly DUNC_UIFILE=${DUNC_UIFILE:-/usr/lib/dunc/shint2dialog.sh}
abortstring='ABORT BUSY ABORT "NO CARRIER" ABORT VOICE ABORT "NO DIALTONE" ABORT "NO ANSWER"'
modeminit='"" ATZ OK'

Exit () {
# clean up and exit script
local return=$1
rm -rf ${TempFile}*
clear
exit ${return:-0}
}

# exit on interrupts
trap Exit 2 3 24
# When the system halts, clear any menus that may be displayed on the first
# console.
trap  Exit 1 15
# include the user interface functions
. $DUNC_UIFILE

# Global options from the UI FILE
#	The variable $BACKTITLE specifies the back title.
# this may not be available in a particular UI FILE
#	The variable $DIALOG_OPTIONS, initialized to nothing, provides
#	options you want on the command line of each dialog invocation.
# "dialog" in this statement refers to the dialog interface by Bruce Perens.
# Other interfaces may become available.
#	The variable $DIALOG_TEST can be set to "echo" to see the calls
#	to dialog without executing them.
# ditto above.
# The following functions should be available in any UI FILE
# The descriptive text has been mostly derived from Bruce Perens'
# GPL's shell interface to dialog, but should apply to any
# compatable UI FILE

# Display a file.
#
# fileBox filename [title]
#

# textBox takes and presents its standard input in a dialog box. This
# is useful for "here documents" and pipes.
#
# textBox [title]
#

# Display a message -- requires carriage return
# msgBox "message" "title"
#

# Display a message and return, but do not clear the screen
# infoBox "message" "title"
#

# Display a widget prompting for a yes or no.  Yes returns 0, No returns 1
# yesNoBox "test" "title"
#

# Display a text input widget
# inputBox "text" "title" "default input"
#

# Display a menu widget
# menu "text" "title" "tag1" "item1" ...
#

# Display a checklist widget (multiple value)
# checklist "text" "title" "tag1" "item1" "status1" ...
#

# Display a radiolist (single selection)
# radiolist "text" "title" "tag1" "item1" "status1" ...
#

#
# End of user interface functions
#

mkMenu ()
{
while true; do

# These local variables were used in the dinstall script I hijacked
# this user interface concept from, so I use them as well.
	local next_action=true
	local previous_action=true
	local alternate_action=true

		echo "menu \\" > $TempFile

[ $# -lt 1 ] && { # do this if mkMenu is called with no args

# This section sets up the inital menu at first invocation according
# to what's been found out about other versions.  It will usually
# just get skipped.

	if [ -d $BASEDIR -a ! -f $RCFILE ]; then
		title="Convert Or Delete Connections"
		next_action=convertConfig
		alternate_action=newConnection
			cat >> $TempFile << EOF
" A previous DUNC configuration has been found.  Please either
 select \\"Next\\" to convert to the new format or select
 \\"Alternate\\" to create a new connection (recommended)." "$title" \\
	"Next" "Convert old configuration" \\
	"Alternate" "Make a fresh new connection" \\
EOF
	elif [ ! -d $BASEDIR ]; then
# This should only get called once, unless BASEDIR gets deleted.
		next_action=newConnection
		helper=New
		alternate_action="getHelp"
		cat >> $TempFile << EOF
" There is no dial up networking configuration directory (i.e.
$BASEDIR).  Please select \\"Next\\" to create a new configuration." "$title" \\
		"Next" "Create a new connection" \\
		"Alternate" "Get Help with this menu" \\
EOF
	else
# This is what will usually appear
		helper=Main
		next_action=newConnection
		alternate_action=manageConnection
	cat >> $TempFile << EOF
" This is the \\"Dial Up Networking Client\\" utility.  Please
 select \\"Next\\" to create a new configuration or \\"Alternate\\"
 to manage an existing connection." "$title" \\
	"Next" "Create a new connection" \\
	"Alternate" "Select a connection to modify" \\
EOF
	fi
	} # end of argumentless specifics	

#
# These are specific menu fragments called by the $1 arg to mkMenu
#

case $1 in 
	change) # menu header for "manage connections" with standard
		# menu and case processing
cat >>$TempFile << EOF
" Please select \\"Next\\" to procede or \\"Previous\\" 
 to go back to the main menu." "Are You Sure?" \\
	"Next" "Select a connection to modify" \\
	"Previous" "Back to main menu" \\
	" " " " \\
EOF
	helper=Select
	next_action=selectList
	previous_action="return 1";;
#
# end of change block
#

	convert)
# The convert config function is not in the main menu and is only
# available initially if certain (above) conditions are true.  It is
# accessed under "Manage Connections" otherwise.  The same is true
# for the cleanConfig function.
			cat >> $TempFile << EOF
" A previous DUNC configuration has been found.  Please either
 select \\"Next\\" to convert to the new format or select
 \\"Alternate\\" to delete the old data and start from scratch." "$title" \\
	"Next" "Convert old configuration" \\
	"Alternate" "Delete old configuration" \\
EOF
	helper=Convert
	next_action=convertConfig
	alternate_action=cleanConfig;;
#
# end of convert block
#

	new) 	# menu header for "new connections" with standard menu
		# and case processing.  This is called from the
		# newConnection function and returns true to it
		# to continue processing on "next" action
cat >>$TempFile << EOF
"Please select \\"Next\\" to continue creating a new connection
or \\"Previous\\" to return to the main menu." "Are You Sure?" \\
	"Next" "Continue creating a new connection" \\
	"Previous" "Back to main menu" \\
	" " " " \\
EOF
	helper=New
	next_action="return 0"
	previous_action="return 99";;

#
# end of new block
#
	nameOK) # called from nameOK(), this menu header
		# only uses the menu tail
	shift
	local name="$1"
cat >> $TempFile <<EOF
"There is already a connection named \\
 	\"$name\" \\
 Please select \\"Next\\" to replace this with a new connection \\
 or \\"Previous\\" to choose another name" "$title" \\
	"Next" "Overwrite connection" \\
	"Previous" "Select a new name" \\
	" " " " \\
	"Modify" "Change connection properties" \\
EOF
	helper=Nameok
	next_action="return 0"
	previous_action="return 1";;
#
# end of nameOK block
#

	method) # menu of connection methods -- only uses
		# menu tail
cat >> $TempFile <<EOF
"Please select the authentication method for this connection. \\
HINT: PAP is the method most often used in Windows 95, so if your ISP \\
supports the NT or Win95 dial up client, please select \\"PAP\\"." "$title" \\
	"PAP"	"Peer Authentication Protocol" \\
	"Chat"	"Use \\"chat\\" for interactive" \\
	"CHAP"	"Crypto Handshake Auth Protocol" \\
	"None"	"Direct -- No Authentication" \\
	" " " "	\\
	"Previous" "Back to previous menu" \\
EOF
	previous_action="return 1"
	helper=Method;;
#
# end of method block
#

	properties)	# list of variables about a connection
			# to be modified by the user
cat >> $TempFile <<EOF
"Please select the property of connection \\"$selection\\" \\
you wish to modify or select \\"Previous\\" to go back." "$title" \\
EOF
[ $ispauth != "none" ] && {
cat >>$TempFile <<EOF
	"Number"	"Telephone number to call" \\
	"User"		"User name for Authentication" \\
EOF
	}
[ $ispauth != "none" -a $storepwd != "no" ] && {
cat >> $TempFile <<EOF
	"Password"	"The password for this connection" \\
EOF
	}
cat >> $TempFile <<EOF
	"Speed"		"Port speed for the modem" \\
	"Com"		"Com Port the modem is on" \\
	"Method"	"Authentication Method (e.g. PAP)" \\
EOF
[ $ispauth = "chat" ] && {
cat >> $TempFile <<EOF
	"KeepPWD"	"Store password in a file - ${storepwd:=no}" \\
	"ISPChat"	"Manage Chat Settings" \\
EOF
	}
cat >> $TempFile <<EOF
	"Details"	"Advanced options for EXPERTS" \\
	"Other"		"Other advanced/EXPERT options" \\
	" " " "	\\
	"Finished"	"Back to previous menu" \\
	"ExpertHelp"	"Help for the \\"Other advanced\\" menu" \\
	"AdvHelp"	"Help for the advanced menu" \\
EOF
	helper=Properties
	previous_action="break 2" ;;
#
# end of properties block
#
	chatprops)	# configure the individual chat properties
cat >> $TempFile << EOF
"You will now have the opportunity to change your chat settings. \\
Select the setting you wish to change, or select \\"Finished\\" if \\
your done changing chat settings" "Chat Settings" \\
	"ISPConnect"	"Change the Connect string" \\
	"ISPLogin"	"Change the Login Prompt string" \\
	"ISPPrompt"	"Change the Password Prompt string" \\
	"ISPOthers"	"Change or add other strings" \\
	"Finished"	"Return to previous menu" \\
	" " " " \\
EOF
	helper=Chat
	previous_action="break 2"
	;;
#
# end of chatprops block
#
	Advanced) # advanced menu options -- requres minmen
cat >> $TempFile <<EOF
"Proceed with CAUTION please.  Select an advanced function or \\
select \\"Previous\\" to go back." "Advanced Menu" \\
	"SysOps" "Edit global options with ${EDITOR:-'/bin/ae'}" \\
	"Convert" "Convert old connection to new format" \\
	"Delete" "Delete a connection" \\
	"Previous" "Back to previous menu" \\
EOF
	helper=Madvanced
	previous_action="break 2" ;;
#
# end of Advanced block
#
	OtherAdvanced)	# Other advanced functions menu -- requires minmen
cat >> $TempFile <<EOF
"Proceed with CAUTION please.  Select an advanced function or \\
select \\"Previous\\" to go back." "Advanced Menu" \\
	"AsyncMap" "Define an asyncmap value" \\
	"NetMask" "Define a netmask value" \\
	"MruMtu" "Define mru and mtu values" \\
	"IPadd" "Define the IP address to use" \\
	"Route" "Turn on/off default route" \\
	"Previous" "Back to previous menu" \\
EOF
	helper=Oadvanced
	previous_action="break 2" ;;
#
# end of OtherAdvanced block
#

	*) mainTitle;;
esac

	
#
# START OF STANDARD MENU FRAGMENT
# this is included unless MINMEN=1
#
[ $MINMEN -ne 1 ] && {
cat >>$TempFile << EOF
	" " " " \\
	"Create" "Create a new connection" \\
	"Modify" "Change connection properties" \\
	"Expert" "Advanced options" \\
	"Run" "Run a connection" \\
EOF
}
#
# END OF STANDARD MENU FRAGMENT
#

#
# START OF MENU TAIL
# this is always present
#

cat >>$TempFile << EOF
	"Help" "Get Help with this menu" \\
	"Quit" "Exit this utility"
EOF
#
# END OF MENU TAIL
#

#
# START OF STANDARD CASE PROCESSING
#
	local action
	action="`. $TempFile`"
	if [ $? -ne 0 -o -z "$action" ]; then continue; fi
	case $action in
	Next) $next_action
	return 
	;;
	Alternate) $alternate_action
	return 
	;;
	Previous|Finished) $previous_action
	return
	;;
	Convert) convertConfig
	return
	;;
	Delete) cleanConfig
	return
	;;
	AsyncMap) doAsyncmap
	return
	;;
	NetMask) doNetmask
	return
	;;
	MruMtu) doMruMtu
	return
	;;
	IPadd) doIpAddress
	return
	;;
	Route) doDefRoute
	return
	;;
	Create) newConnection
	return
	;;
	Modify) manageConnection
	return
	;;
	Run) dppp -s
	Exit
	;;
	Expert) mainAdvanced
	return
	;;
	Details) propsAdvanced
	return
	;;
	Other)	otherAdvanced
	return
	;;
	SysOps) systemConfig
	return
	;;
	PAP) doOps PAP
	return
	;;
	CHAP) doOps CHAP
	return
	;;
	Chat) doOps Chat
	return
	;;
	None) doOps None
	return
	;;
	Method) mkMenu method
	return
	;;
	KeepPWD) doOps Storepwd
	doOps
	return
	;;
	ISPChat) chatProps
	return
	;;
	ISPConnect) chatConfig connect
	return
	;;
	ISPLogin) chatConfig login
	return
	;;
	ISPPrompt) chatConfig prompt
	return
	;;
	ISPOthers) chatConfig others
	return
	;;
	Password) doOps Passwd
	return
	;;
	Com) doOps Port
	return
	;;
	Speed) doOps Speed
	return
	;;
	User) doOps User
	return
	;;
	Number) doOps Number
	return
	;;
	Edit) editConfig
	return
	;;
	Help) getHelp $helper
	return
	;;
	AdvHelp) getHelp Padvanced
	return
	;;
	ExpertHelp) getHelp Oadvanced
	return
	;;
	Quit) Exit
	;;
	esac
#
# END OF STANDARD CASE PROCESSING
#
done	# end of while loop
}

# Action functions for DUNC
convertConfig () {
title="Configuration Conversion"
msgBox "We will now attempt to convert your old\n\
        connection to the new format." $title 
[ -f $HOME/.duncrc ] || {
msgBox "Sorry, we are unable to convert your old\n\
connection.  You may still use it as you\n\
did before, but it will not be managed\n\
by this utility." $title
return
	}
# read in the previous values
. $HOME/.duncrc
# map them to current variables
ispauth="chat"
ispspeed=$spd_st
ispname=$user_st
ispnumber=$pn_st
ispconnect=$pconnect
isplogin=$plogin
ispothers=$pothers
# get and set password information
if grep -qs "^stty" $BASEDIR/dialup_connect ;then # password was not stored
  storepwd="no"
else	# the password was stored
  storepwd="yes"
  isppwd="`grep "^passwd" $BASEDIR/dialup_connect|cut -d= -f2`"
fi
# verify values
msgBox "We need to verify some settings.  If\n\
the settings are correct for each item,\n\
just press return.  Otherwise, correct\n\
the setting." $title
doOps Port
propsAdvanced noinit
chatConfig prompt
while true;do
  selection="`inputBox "Enter the name of the new connection" "$title" "ISP"`"
# we only need to do this once, which simplifies adding entries to the rcfile
  nameOK "$selection"
  if [ $? -eq 0 ];then
    break
  fi
done
MINMEN=1
doProps         # review properties
MINMEN=0
mkRC            # creat $RCFILE or a $RCFILE entry
putVars         # populate the case block with connection variables
mkFile          # create the connection files $selection.ctn and
                # $selection.cht (if required)
finishConnection        # finishing touches
mainTitle
getVars zero	# zero out hte global variables before returning
return
}

cleanConfig () {
title="Delete A Connection"
selectList
[ $? -eq 99 ] && return	# 99 exit code means no selections found
yesNoBox "Really delete connection \"$selection\"?" "Are You Sure?"
[ $? -eq 0 ] || return
getLines "$selection"
[ -n "$beginning" ] && {
ed -s $RCFILE <<EOF 2>/dev/null
$beginning,$ending d
w
q
EOF
	}
mv "$BASEDIR/$selection".* ${TempFile}.dir
if [ $? -eq 0 ];then
  msgBox "Connection \"$selection\" has been removed" "Deleted"
else
  msgBox "There was a problem removing the connection.\n\
Contact your system administrator for assistance." "Error"
fi
mainTitle
return
}

systemConfig () {
if [ -w /etc/ppp/options ]; then
  ${EDITOR:-'/bin/ae'} /etc/ppp/options
else
  msgBox "You do not have write permissions on\n\
/etc/ppp/options.  Obtain the proper\n\
permissions and rerun this utility." "Warning"
fi
return
}

doNetmask () {
ispnetmask="`inputBox "Enter the netmask for this connection." "NetMask" ${ispnetmask:-'255.255.255.0'}`"
return
}

doIpAddress () {
ispipaddress="`inputBox "Enter the IP Address for this connection." "IP Address" ${ispipaddress:-'10.0.0.10'}`"
return
}

doMruMtu () {
ispmru="`inputBox "Enter the MRU for this connection." "MRU" ${ispmru:-'296'}`"
ispmru="`inputBox "Enter the MTU for this connection." "MTU" ${ispmtu:-'296'}`"
return
}

doAsyncmap () {
ispasyncmap="`inputBox "Enter the asyncmap for this connection." "AsyncMap" ${ispasyncmap:-'0'}`"
return
}
doDefRoute () {
# set a default of on once entering this function, unless ispdefroute
# has already been set.
[ -n "$ispdefroute" ] || ispdefroute="on"
while true; do
	cat > $TempFile <<EOF
menu \\
"Select \\"defaultroute\\" to toggle this feature or \\"Finished\\" \\
to return to the previous menu." "Toggle Default Route" \\
"defaultroute" 	"${ispdefroute:=on}" \\
"Finished"	"Return to previous menu" 
EOF
	local value=`. $TempFile`
	case $value in
	defaultroute) # toggle storepwd flag
	if [ "${ispdefroute:-'on'}" = 'on' ];then
		ispdefroute="off"
		msgBox "Toggled defaultroute option to off" "OFF"
	else
		msgBox "Toggled $ispdefroute defaultroute option to on" "ON"
		ispdefroute="on"
	fi
		;;
	Finished) return
		;;
esac
done
}

mainAdvanced () {
# loop through the advanced menu display until user
# chooses previous_action and does a "break 2"
noswitch=0
[ $MINMEN = 1 ] && noswitch=1
[ $noswitch -eq 0 ] && MINMEN=1
while true;do
  mkMenu Advanced
done
[ $noswitch -eq 0 ] && MINMEN=0
return
}

otherAdvanced () {
# loop through the Oadvanced menu display until user
# chooses previous_action and does a "break 2"
noswitch=0
[ $MINMEN = 1 ] && noswitch=1
[ $noswitch -eq 0 ] && MINMEN=1
while true;do
  mkMenu OtherAdvanced
done
[ $noswitch -eq 0 ] && MINMEN=0
return
}

propsAdvanced () {
# use a checklist to set pppd options in an options file.  The
# options I use are turned on by default.

[ $# -eq 0 ] && {
initStateVars		# These can change within a connection selection
			# so we need to reinitialize them for each
			# invocation of propsAdvanced
	}

DIALOG_OPTIONS="--separate-output"	# set single entry per line
					# output format

eops="`checklist "   The options set here will supercede those 
          set in /etc/ppp/options.\n
     Select the ppp options that you desire   \n\n\
     option            description" "Expert Options" \
-all "force defaults" ${all_st:-off} \
defaultroute "default gateway" ${defrte_st:-off} \
-defaultroute "no default gateway" ${nodefrte_st:-off} \
crtscts "hardware flow control" ${rcts_st:-off} \
-crtscts "disable crtscts" ${norcts_st:-off} \
xonxoff "software flow controll" ${xonxoff_st:-off} \
passive "passive mode" ${psv_st:-off} \
-ac "disable field compression" ${fcomp_st:-off} \
-bsdcomp "disable BSD compression" ${bcomp_st:-off} \
-am "disable asyncmap" ${nomap_st:-off} \
-detach "don't fork" ${nodet_st:-off} \
modem "use modem controll" ${modem_st:-off} \
local "ignore Carrier Detect" ${lcl_st:-off} \
proxyarp "add arp entry for peer" ${parp_st:-off} \
persist "don't die on termination" ${prst_st:-off} \
-mru "disable mru negotiaion" ${nomru_st:-off} \
lock "use UUCP locking" ${lock_st:-off}`"

DIALOG_OPTIONS=""	# reset this to nothing
return
}

initStateVars () {
# PPP options state variables (on or off) derived from conf file
# via global variable $eops
# zero all of these between initializations
  all_st=off
  defrte_st=off
  nodefrte_st=off
  rcts_st=off
  norcts_st=off
  xonxoff_st=off
  psv_st=off
  fcomp_st=off
  bcomp_st=off
  nomap_st=off
  nodet_st=off
  modem_st=off
  lcl_st=off
  parp_st=off
  prst_st=off
  nomru_st=off
  lock_st=off
[ -n "$eops" ] && {
for i in $eops;do
case $i in

'-all')		# -all option state variable
		all_st=on
		;;

'defaultroute')	# defaultroute option state variable
		defrte_st=on
		;;

'-defaultroute')# -defaultroute option state variable
		nodefrte_st=on
		;;

'crtscts')	# crtscts option state variable
		rcts_st=on
		;;

'-crtscts')	# -crtscts option state variable
		norcts_st=on
		;;

'xonxoff')	# xonxoff option state variable
		xonxoff_st=on
		;;

'passive')	# passive mode option state variable
		psv_st=on
		;;

'-ac')		# -ac option state variable
		fcomp_st=on
		;;

'-bsdcomp')	# -bsdcomp option state variable
		bcomp_st=on
		;;

'-am')		# -am option state variable
		nomap_st=on
		;;

'-detach')	# -detach option state variable
		nodet_st=on
		;;

'modem')	# modem option state variable
		modem_st=on
		;;

'local')	# local option state variable
		lcl_st=on
		;;

'proxyarp')	# proxyarp option state variable
		parp_st=on
		;;

'persist')	# persist option state variable
		prst_st=on
		;;

'-mru')		# -mru option state variable
		nomru_st=on
		;;

'lock')		# lock option state variable
		lock_st=on
		;;
esac
done
	}
}

chatConfig () {

case "$1" in
connect)	# the connection string sent by the modem
	ispconnect="`inputBox "Enter the text of connect acknowledgement.\n\
Chat won't send any response to this." "Ack String" "${ispconnect:-'CONNECT'}"`"
	return
	;;
login)	# the login prompt string sent by the ISP
	isplogin="`inputBox "Enter the text of the first login prompt.\n\
Chat will send your username in response." "Login String" \
"${isplogin:-'login:--login:'}"`"
	return
	;;
prompt)	# password prompt sent by the ISP
	ispprompt="`inputBox "Enter the text of the next (passwd) prompt.\n\
Chat will send your passwd in response." "PWD String" "${ispprompt:-'passwd:'}"`"
	return
	;;
others)	# other possible chat requirements
	ispothers="`inputBox "Enter any additional input test you require.\n\
This may be a program name like ppp\nor a response to a menu prompt.\n\
If you're not sure, leave this blank.\nIf you need to make an entry,\n\
make the first entry the prompt you\nexpect.  If you don't expect anything,\n\
please make two single quotes (null)\nthe first entry (e.g. ''). All\n\
entries must be separated by white space.\n" "Other Strings" "${ispothers:-''}"`"
	return
	;;
*)	# chatConfig with no options will display a message and configure
	# all chat options
	msgBox "Now you will be asked to configure the chat options." "Chat"
	chatConfig connect
	chatConfig login
	chatConfig prompt
	chatConfig others
	return
	;;
esac
}

chatProps () {
# loop through the chatprops menu display until user
# chooses previous_action and does a "break 2"
noswitch=0
[ $MINMEN = 1 ] && noswitch=1
[ $noswitch -eq 0 ] && MINMEN=1
while true;do
  mkMenu chatprops
done
[ $noswitch -eq 0 ] && MINMEN=0
return
}

runSelection () {
# query the user to run the connection script
# run and exit on yes, return on no
yesNoBox "run connection \"$1\"?" "Run"
[ $? -eq 0 ] && {
dppp -c "$1"
Exit
	}
return
}

finishConnection () {
# this is to tidy up things with the user and is in no way
# associated with any Finnish Connections ;)

msgBox "Finished configuring connection" "Finished"

# make this the default ?
if [ $storepwd != no ]
# can't be default unless the password is stored
then
    yesNoBox "Make this the default connection (CAUTION: This\nwill replace \
your \$HOME/.ppprc file)?" "Default?"
    [ $? -eq 0 ] && {
    [ -f $HOME/.ppprc ] && mv $HOME/.ppprc $HOME/.ppprc.old
    ln -f "$BASEDIR/${selection}.ctn" $HOME/.ppprc
    msgBox "You can run this connection by running \nthe pppd command \
without any arguments!" "Default Set"
    }
fi

runSelection "$selection"
}

newConnection () {
# this sets up new connections by calling other functions to:
# - initialize a clean state by zeroing state variables
# - query the user for information about a connection
# - check to see if $RCFILE exists, if not, create it, if so, back it up
# - save the state variables in $RCFILE
# - build a .ctn/.cht file pair (unless PAP or CHAP auth is used,
#   in which case no .cht file is needed)
# - zero the state variables after completing the above
#
# Note: global variable $selection gets set here

MINMEN=0
getVars zero

title="Create A New Connection"

mkMenu new
[ $? -eq 0 ] && {
while true;do
  selection="`inputBox "Enter the name of the new connection" "$title" "ISP"`"
# we only need to do this once, which simplifies adding entries to the rcfile
  nameOK "$selection" 
  if [ $? -eq 0 ];then 
    break
  fi
done
MINMEN=1
mkMenu method 	# calls doOps with appropriate method arg
		# this starts the process of collecting all other
		# connection related information
[ $ispauth != "none" ] && doOps		# calls all doOps args required
doProps		# review properties
MINMEN=0
mkRC		# creat $RCFILE or a $RCFILE entry
putVars		# populate the case block with connection variables
mkFile		# create the connection files $selection.ctn and 
		# $selection.cht (if required)
finishConnection	# finishing touches
	}
mainTitle
getVars zero	# zero out the golbal variables
return
}

mkRC () {
# if $RCFILE does not exist, create it
# otherwise, back it up as $RCFILE.$ext and add an entry for $selection
# $selection is presumed to be unique since nameOK returned true

ext=${ext:-0}
if [ -f $RCFILE ]; then
	cp $RCFILE $RCFILE.$ext
	ext=`expr $ext + 1`
local bottom="`echo /esac/ n|ed -s $RCFILE 2>/dev/null|cut -f1`"
ed -s $RCFILE <<EOF >/dev/null 2>&1
`expr $bottom - 1`
a
"$selection")
	;;
.
w
q
EOF
else # $RCFILE does not exist
	cat >$RCFILE <<EOF 2>/dev/null
case \$1 in
"$selection")
	;;
esac
EOF
fi
return
}

nameOK () {
if [ -f "$BASEDIR/$1.ctn" ];then
MINMEN=1
  mkMenu nameOK "$1"
  local ret=$?
MINMEN=0
  return $ret
else
  return 0
fi
}

manageConnection () {
# This will go through the other functions required to read in and
# provide access to change an existing connection.  It uses
# recursion to achieve a consistent look and feel for the process.
# In this context, a connection consists of a ppp options file and
# a chat file (pair).

getVars zero	# initialize globals to null

title="Change A Connection"
mkMenu change 	# calls selectList on "next" action
[ $? -eq 99 ] && return	# 99 exit code from selectList means no selections
# use setting of $selection to get the right case block
# out of $RCFILE for global variables
getVars init "$selection" 

[ $? -eq 1 ] && return	# return to calling function if return code is 1
MINMEN=1
doProps
putVars		# update case block for $selection with current 
		# connection variable values
mkFile		# (re)create the connection files $selection.ctn and 
		# $selection.cht (if required)
MINMEN=0
finishConnection
mainTitle
getVars zero	# initialize globals to null
return
}

doProps () {
msgBox "You will now have the chance to \nreview or change \
connection properties" "Properties"
while true;do
  title="Select A Property To Manage"
  mkMenu properties	# calls doOps for each property to modify
done
}
selectList () {
# This looks in $BASEDIR for .ctn files and builds a selection
# menu based on its findings.  It also builds a corresponding 
# custom case block in ${TempFile}1.
# global variable here is $selection

cat >$TempFile <<EOF
menu \\
"Please select from the list below or select \\"Previous\\"
to return to the previous menu." "Select A Connection" \\
EOF

cat >${TempFile}1 <<EOF
case \$value in
EOF

j=1

# The list returned may not be read correctly if there are funky characters
# in the filename (i.e. spaces), so this bit of code should work around
# that.
# the global variable $selection is set here
local list="`ls $BASEDIR/*.ctn 2>/dev/null`"
[ -n "$list" ] || {
msgBox "No Connections Found!" "Error"
return 99
	}
for i in $list
do
  if [ `echo $i|grep \.ctn` ]; then
  name="$name $i"
# $selection is used to store the value of the active connection name and
# $connection is only used once to get the name from a selection list.
  connection=`basename "$name" .ctn`
  echo -n "\"$j\" \"$connection\"" >>$TempFile
  echo ' \'>>$TempFile
  cat >>${TempFile}1 <<EOF
  $j) selection="$connection" ;;
EOF

  j=`expr $j + 1`
  name=""
  else
  name="$name $i"
  fi
done

cat >>$TempFile <<EOF
" " " " \\
"Previous" "Return to previous menu" 
EOF

cat >>${TempFile}1 <<EOF
Previous) return ;;
esac
EOF

local value=`. $TempFile`
# sets the global $selection variable
. ${TempFile}1 

return
}

getVars () {
# deal with global vars on a per connection basis. 
# getVars zero - sets vars to null ""
# zero should be run after each connection is finished being
# modified (and has been written out) and before each new connection.  
# getVars init <connection> - initializes variables from the
# <connection> case block in $RCFILE (here <connection is really
# set in $selection)
# init needs to be run for each new connection to manage
case $1 in
zero) 	# sets everything to null.  This should be run for all new
	# connections and after all "manage" sessions (per connection)
	ispname=""
	ispspeed=""
	ispport=""
	ispnumber=""
	isppwd=""
	ispauth=""
	ispconnect=""
	isplogin=""
	ispprompt=""
	ispothers=""
	ispasyncmap=""
	ispipaddress=""
	ispnetmask=""
	ispmru=""
	ispmtu=""
	ispdefroute=""
	storepwd="null"
	selection=""
	eops=""
	;;
init)	# gets connection specific vars from $RCFILE
	shift
	. $RCFILE "$1"
	;;
esac
}

putVars () {
# This writes the global variables out to $RCFILE in the
# appropriate case block using getLines() to find the first
# and last lines of the block in $RCFILE

# set up the expert opts variable
local exp_opts=""
for i in $eops
do
  exp_opts="${exp_opts}${i} "
done
getLines "$selection"

>${TempFile}1 # zero this file
[ `expr $beginning + 1` -ne $ending ] && {
cat >${TempFile}1 <<EOF
`expr $beginning + 1`,`expr $ending - 1`d
EOF
	}
cat >>${TempFile}1 <<EOF
/$selection/
a
ispname="$ispname"
ispspeed="$ispspeed"
ispport="$ispport"
ispnumber="$ispnumber"
storepwd="${storepwd:-null}"
ispauth="$ispauth"
ispconnect="$ispconnect"
isplogin="$isplogin"
ispprompt="$ispprompt"
ispothers="$ispothers"
ispasyncmap="$ispasyncmap"
ispipaddress="$ispipaddress"
ispnetmask="$ispnetmask"
ispmru="$ispmru"
ispmtu="$ispmtu"
ispdefroute="$ispdefroute"
EOF
case $ispauth in
	pap|chap) # store the passwd for pap or chap authentication
	cat >>${TempFile}1 <<EOF
isppwd="$isppwd"
EOF
	;;
	chap) # store the passwd for chap authentication
	;;
	chat) # only store the passwd if storepwd=yes
	if [ $storepwd = "yes" ];then
	cat >>${TempFile}1 <<EOF
isppwd="$isppwd"
EOF
	fi
esac
cat >>${TempFile}1 <<EOF
eops="$exp_opts"
.
w
q
EOF
ed -s $RCFILE <${TempFile}1 2>/dev/null

}

mkFile () {
# This function assumes that putVars has been executed and $RCFILE
# is up to date and that getVars init has been run
local pfile="$BASEDIR/$selection.ctn"
local cfile="$BASEDIR/$selection.cht"

[ -d $BASEDIR ] || mkdir -p $BASEDIR

cat >"$pfile" <<EOF
# This file was generated by dunc version 2
# The options here may be edited manually.
# when used with dppp, they are complimentary and
# supercedant to the options in /etc/ppp/options
# and $HOME/.ppprc (unless this is your default
# connection, in which case .ppprc is a link to here.
#
#METHOD = $ispauth
#
# device 
$ispport
# speed
$ispspeed
# these are defaults ...
# turn on debugging
debug
# use a standard class C netmask unless ispnetmask is defined
netmask ${ispnetmask:-'255.255.255.0'}
EOF
[ "${ispdefroute:-'on'}" = "on" ] && {
cat >>"$pfile" <<EOF
# use the defaultroute option
defaultroute
EOF
	}
[ $ispauth != "none" ] && {
cat >>"$pfile" <<EOF
# use modem control lines (can be overridden by expert options)
modem
# set flow control option
crtscts
# set the asyncmap to 0 unless ispasyncmap is defined
asyncmap ${ispasyncmap:-'0'}
# end of defaults
EOF
	}
[ -n "$ispmru" ] && {
cat >>"$pfile" <<EOF
# mru/mtu values
mru $ispmru
mtu $ispmtu
EOF
	}
[ -n "$ispipaddress" ] && {
cat >>"$pfile" <<EOF
# set the local IP address
$ispipaddress
EOF
	}
[ -n "$eops" ] && {
cat >>"$pfile" <<EOF
# start of expert options
EOF
for i in $eops;do
	cat >"$pfile" <<EOF
# expert option $i
$i
EOF
done
cat >>"$pfile" <<EOF
# end of expert options
EOF
	}
[ $ispauth = "pap" -o $ispauth = "chap" ] && {
cat >>"$pfile" <<EOF
# noauth is required for  pppd-2.3 and above, but must be removed for
# pppd 2.2 and below.
noauth
user $ispname
EOF
if [ $ispnumber != "DIRECT" ]; then
  cat >>"$pfile" <<EOF
connect "/usr/sbin/chat -v -f $cfile"
EOF
  cat >"$cfile" <<EOF
$abortstring $modeminit atdt$ispnumber CONNECT \\d\\c
EOF
else 	# $ispnumber is DIRECT
  cat >> "$pfile" <<EOF
connect '/usr/sbin/chat -v "" \r CONNECT'
EOF
fi
secretsFile
	}
[ $ispauth = "none" ] && {
cat >>"$pfile"<<EOF
# wait for a connection
passive
EOF
	}
[ $ispauth = "chat" ] && {
if [ $storepwd = "no" ];then
  if  [ $ispnumber != "DIRECT" ];then
    cat >"$cfile" <<EOF
$abortstring $modeminit atdt$ispnumber $ispconnect "" $isplogin \\d\\q$ispname $ispprompt \\qQUERY_PWD $ispothers
EOF
  else 	# $ispnumber is DIRECT
    cat >"$cfile" <<EOF
"" \r $ispconnect "" $isplogin \\d\\q$ispname $ispprompt \\qQUERY_PWD $ispothers
EOF
  fi
else	# $storepwd = yes
  if  [ $ispnumber != "DIRECT" ];then
    cat >>"$pfile" <<EOF
connect "/usr/sbin/chat -v -f $cfile"
EOF
    cat >"$cfile" <<EOF
$abortstring $modeminit atdt$ispnumber $ispconnect "" $isplogin \\d\\q$ispname $ispprompt \\d\\q$isppwd $ispothers
EOF
  else 	# $ispnumber is DIRECT
    cat >"$cfile" <<EOF
"" \r $ispconnect "" $isplogin \\d\\q$ispname $ispprompt \\q$isppwd $ispothers
EOF
  fi
fi
	}

}

secretsFile () {
# this checks to see if we can write to either pap-secrets or chap-secrets
# if not, it writes to a $HOME/$ispauth_secrets file and alerts the user
if [ -w "/etc/ppp/${ispauth}-secrets" ];then
  if grep -qs "$ispname" "/etc/ppp/${ispauth}-secrets" ; then
    ed -s "/etc/ppp/${ispauth}-secrets" <<EOF 2>/dev/null
/$ispname/ d
-
a
# this entry was created by $USER for connection $selection
$ispname * $isppwd
.
w
q
EOF
  else
    echo "# this entry was created by $USER for connection $selection">>"/etc/ppp/${ispauth}-secrets"
    echo "$ispname * $isppwd">>"/etc/ppp/${ispauth}-secrets"
  fi
else
    echo "# this entry was created by $USER for connection $selection">>"$HOME/${ispauth}-secrets"
  echo "$ispname * $isppwd" >> "$HOME/${ispauth}-secrets"
  /bin/chmod 600 "$HOME/${ispauth}-secrets"
  msgBox "   Could not write to /etc/ppp/${ispauth}-secrets!\n\
Writing to $HOME/${ispauth}-secrets instead.  Use\n\
this file to amend the /etc/ppp/${ispauth}-secrets file\n\
      after aquiring write permissions to it." "Warning!"
fi
}

getLines () {
# this sets beginning and ending to the first and last line number of
# the case block for a connection in $RCFILE

cat >${TempFile}1 <<EOF
/"$1"/ n
q
EOF
beginning=`ed -s $RCFILE <${TempFile}1 2>/dev/null|cut -f1`

cat >${TempFile}1 <<EOF
$beginning
/;;/ n
q
EOF
ending=`ed -s $RCFILE <${TempFile}1 2>/dev/null|grep ";;"|cut -f1`

}

doOps () {
# this function uses the following global variables:
# ispname - ISP user name for each connection (reset in manage function)
# ispspeed - connection port speed (reset in Manage)
# ispport - modem port (reset in Manage)
# ispnumber - telephone number to call
# isppwd - password to store
# ispauth - pap, chap, or chat
# storepwd - boolean, only pertains to Chat connections.  If set to true
#	     the passwd will be stored in a file.  pppup will prompt
#	     for it otherwise.

title="Manage $1 Configuration"
case $1 in
User) # input the user name for the ppp account
	ispname="`inputBox "Enter your username (usually given to you \\
by your ISP)" "$title" "${ispname:-$USER}"`"
	return
	;;
Port) # identify the port the modem is on
	ispport="`inputBox "Enter the port your modem is on \\
(usually /dev/ttyS1)
/dev/ttyS0 is COM1 in DOS
/dev/ttyS1 is COM2 in DOS
/dev/ttyS2 is COM3 in DOS
/dev/ttyS3 is COM4 in DOS" "$title" "${ispport:-"/dev/ttyS1"}"`"
	return
	;;
Speed) # get the port speed
ispspeed="`inputBox "Enter your modem port speed (e.g. 9600, 19200, 38400, 115200)" \
"Set Speed" "${ispspeed:-38400}"`"
	return
	;;
Number) # get the number to call or DIRECT for a direct connection
	ispnumber="`inputBox "Enter the number to dial for this connection \
or DIRECT if you are directly connected (i.e. no modem)" "Number to dial" \
"${ispnumber:-DIRECT}"`"
	return
	;;
Passwd)
	isppwd="`inputBox "Enter the password for this connection" \
"Enter Password" \
"${isppwd:-welcome}"`"
	return
	;;
Storepwd)
while true; do
	cat > $TempFile <<EOF
menu \\
"Select \\"StorePWD\\" to toggle storing the password in a file \\
or \\"Finished\\" to return to the previous menu.  This is currently \\
only supported for Chat connections." "Toggle Store Passwd" \\
"StorePWD" 	"${storepwd:=no}" \\
"Finished"	"Return to previous menu" 
EOF
	local value=`. $TempFile`
	case $value in
	StorePWD) # toggle storepwd flag
	if [ "${storepwd}X" = "yesX" ];then
		storepwd="no"
		msgBox "Toggled password storage off" "OFF"
	else
		storepwd="yes"
		msgBox "Toggled password storage on" "ON"
		doOps Passwd
	fi
		;;
	Finished) break 2
		;;
esac
done
	;;
PAP|Win95) # PAP specific section
	ispauth="pap"
	doOps Passwd
	;;
CHAP) # CHAP specific section
	ispauth="chap"
	doOps Passwd
	;;
Chat) # Builds a chat file
	ispauth="chat"
	storepwd="no"
	chatConfig
	doOps Storepwd
	;;
None)	# direct, non-login connection -- the simplest kind of ppp connection
	ispauth="none"
	doDirect
	;;
*) 	# do everything but auth,passwd, and storepwd
	msgBox "Now you will configure some\n\
basic connection properties" "Configuration"
	doOps User
	doOps Port
	doOps Speed
	doOps Number
return
	;;
esac
return
}

getHelp () {
title="Help For This Menu"
local next_action=$1
local select=`menu "Select \"Next\" to continue getting help \
or \"Previous\" to go back.  You can also use \
the arrow keys to select another help topic." "$title" \
"Next"	"Get help on the current topic" \
"Previous"  "Return to the previous menu" \
" " " " \
"Select" "Selecting a connection to modify" \
"New" "Creating a new connection" \
"Main" "Overview of the main menu" \
"Method" "Choosing a connection method" \
"Properties" "Changing properties" \
"Chat" "Configuring chat properties" \
"Madvanced" "The expert menu" \
"Oadvanced" "Other advanced properties" \
"Padvanced" "Advanced proterties details"`

[ $select = "Next" ] && select=$next_action

case $select in
Select)
	cat >${TempFile}.help <<EOF
Choose "Next" to proceed with selecting a
connection to modify.  A selection box will
be displayed with the available connections.

Selecting a connection is easy.  Just use the
arrow keys to highlight the connection and
press return.

After you have selected a connection to modify,
you will have the chance to change any of the
connection properties from the properties menu.
EOF
	;;
Main)
	cat >${TempFile}.help <<EOF
You can press return at this menu to take the "Next"
action or "Alternate" to take the alternate action.
Or you can select one of the other menu options.

If you select "Next", you will proceed with defining
a new connection.  You will be asked to verify that
this is what you want to do.  If you choose
"Alternate", you will proceed with managing an
existing connection.  Likewise, you will be prompted
to verify this choice.

The other options available are to enter the
"Expert" menu (where you could choose to delete
connections or convert old ones or make global options
modifications to /etc/ppp/options) or the "Run" menu
(where you will be asked to select a connection to run).  

Or of course you can quit or get help from just about
anywhere.
EOF
	;;
New)
	cat >${TempFile}.help <<EOF
Select "Next" to proceed with setting up a new
connection.  You will be taken through a number
of screens asking for information about the
connection.  You will be asked to name the
connection.  This can be any legal filename.

You will then be asked to select an 
authentication method.  This will determine
the rest of the set up sequence.  Check with
your ISP for supported or suggested methods
of authentication.  The ones supported here
are PAP, CHAP, CHAT, and NONE.

After finishing the initial set up you will 
have the chance to review or change any of
the settings before either committing the
changes or quiting the program.
EOF
	;;
Convert)
	cat >${TempFile}.help <<EOF
The conversion option attempts to convert
a connection created with a version of
"dunc" prior to 2.0 into the new format.

This is not always successful and in some
cases just plain won't work.  Your mileage
may vary.  In any event, the original files
and dialup script remain in tact.
EOF
	;;
Nameok)
	cat >${TempFile}.help <<EOF
There is already a connection with the name
you entered.  You can choose "Next" to
overwrite this connection or "Previous" to
select a new name.  If you choose to over-
write the existing connection, all previous
information about that connection will be
lost.
EOF
	;;
Method)
	cat >${TempFile}.help <<EOF
Please select one of the supported authentication
methods.  A brief description of each is listed 
here:

PAP - Peer Authentication Protocol
This is the method used by Win95 clients and
servers that support them.  Choose this if
you want to connect to a server or ISP that
supports this protocol.  There are security
issues with this protocol on a multiuser
that stores the authenticating tokens centrally,
so be forwarned.  Even if the tokens are stored
encrypted (not supported with this utility), a
token can be easily hijacked by simple social
engineering.  This is, however, probably the
easiest type of connection to set up.

CHAP - Cryptographic Handshake Authentication
       Protocol
This method is similarly easy to setup to PAP
and is supported in a similar way on the server
side.  It may not be as available though.  It
has the same convenience features and same risks.
Check with your ISP to make sure this protocol
is supported before selecting this method.

CHAT - This is the method previously supported
by dunc version older than 2.0.  It is the only
method that allows you to supply a password each
time you run your connection.  This is the most
secure as it transparently supports one time
password tokens (i.e. SecureID).  It is also
the most difficult to set up.  There is a chat
tutorial available in the on line help that will
hopefully be useful to a novice.  The other
documentation with pppd (e.g. the howto's) is
also very useful.  The dunc package tries to
make this as simple as possible, but can only
do so much.

NONE - Choose this if you are directly wired to
a machine that does not require any authentication
at all (i.e. a linux box running pppd in passive
mode and no getty).  It has been rumored that
you can connect your linux box up to an Apple
Newton using this method.  Support for Fig Newton
and other Newtons is planned for the next dunc
release.
EOF
	;;
Properties)
	cat >${TempFile}.help <<EOF
Please select any property you wish to view
or change the value.  If you change a value
that has more or less options associated
with it, this menu may change accordingly.
This may at first be confusing, but is meant
to only display options pertinent to the
connection being managed.  For example, if
you change authentication methods from PAP
to Chat, you will have some additional menu
selections available.  One of these is the
option to store the password or not.  This
options is only supported for Chat connections
so it is not available if the current method
is PAP, CHAP, or NONE.

This menu is intened to adapt to the current
connection context to give you full control
over the connection settings.  See the advanced
menu about the options details available under
"Details".
EOF
	;;
Chat)
	cat >${TempFile}.help <<EOF
`zcat /usr/doc/dunc/chat.tut.gz`
EOF
	;;
Madvanced)
	cat >${TempFile}.help <<EOF
With the advanced menu options here, you can:

Edit the system default options in /etc/ppp/options
using either the editor defined in the $EDITOR
environment variable, or "/bin/ae" failing this.
As many people dislike ae, defining this variable
is probably a good idea.  If you do not have write
permission to the options file, you will be issued
a warning message.  Changes made to this file are
global in that they affect all users that do not
specifically override the use of this file, or of
its options.  Please see the pppd man page for
details.

Convert an old connection definition.  This is
only available as a courtesy and is not known to
be 100% useful.  Try it if you wish, but I don't
expect it to work reliably for everyone.  This
will not remove the old script or files though, so
they may still be used as they were if you wish.

Delete a connection.  You may delete any managed
connection using this option.  Please be careful.
Once you delete a connection, its files and other
data re gone forever.  You may want to make a
backup of your data before using this option.

Other advanced functions may be available in the
future.
EOF
	;;
Oadvanced)
	cat >${TempFile}.help <<EOF
These additional expert options were added to provide
the ability to select your own netmask, IP address,
MRU/MTU, asyncmap, or boolean switch the defaultroute
flag.

The defaults provided are usually suitable for most
common situations, however.
EOF
	;;
Padvanced)
	cat >${TempFile}.help <<EOF
`zcat /usr/doc/dunc/ppp_opts.tut.gz`
EOF
	;;
Previous)
	return
	;;
esac
fileBox ${TempFile}.help $title
mainTitle
return
}

mainTitle () {
title="Debian GNU/Linux Dial Up Network Configuration"
	}
clear
while true; do
mainTitle
mkMenu
done
