#!/bin/sh -e

. /usr/share/debconf/confmodule

INTERFACES=$(grep : /proc/net/dev | cut -d':' -f1 | sort | sed -e 's/ *//' | grep -E '^(eth|nas|tap|nic-)')

log() {
	logger -t DEBUG:ppp-udeb $*
}

fail() {
	logger -t FAIL:ppp-udeb $*
}

not_already_up() {
	ifconfig | egrep "^$1[[:space:]]" | wc -l
}

ppp_concentrator_on() {
	db_subst ppp/detect_progress IFACE "${1}" || true
	if not_already_up $1; then
		log "$1 was not configured. ppp-udeb will bring it up"
		PPPUP=yes
		ifconfig $1 up
	else
		log "$1 was already up"
		PPPUP=no
	fi
	MAXWAIT=20; IW=5; TOTWAIT=$(($MAXWAIT + $MAXWAIT + $IW))
	R=0
	rm -f /tmp/probe-finished
	db_progress START 0 $TOTWAIT ppp/detect_progress
	for P in " " "-U" ; do
		( R=$(/usr/sbin/pppoe-discovery -A -I $P $1 2>/tmp/ppp-errors | grep AC | wc -l); echo $R > /tmp/probe-finished ) &
		WAIT=0
		TO=$(grep Timeout /tmp/ppp-error 2>/dev/null | wc -l || true)

		while [ ! -f /tmp/probe-finished ]; do
			log "Timout detected $TO"
			sleep 1
			db_progress STEP 1
			WAIT=$(($WAIT + 1))
			if [ $WAIT -ge $MAXWAIT ]; then
				touch /tmp/probe-finished
			fi
			TO=$(grep Timeout /tmp/ppp-error 2>/dev/null | wc -l || true)
			if [ $TO -eq 1 ]; then
				touch /tmp/probe-finished
				break
			fi
			log "pppoe probe output size: $(cat /tmp/probe-finished 2> /dev/null)"
		done
		if [ -z "$P" ]; then
			sleep $IW
			db_progress STEP $IW
		fi
	done

	PROCESS=$(ps -A | grep pppoe-discovery | sed s:^[[:space:]]::g | cut -f1 -d' ') || true
	if [ $TO -ne 1 -a ! -z $PROCESS ]; then
		kill $PROCESS
	fi
	R=`cat /tmp/probe-finished 2>/dev/null` || true
	rm -f /tmp/probe-finished
	db_progress STOP

	if [ 1$R -ne 10 ]; then
		return 0
	else
		return 1
	fi
}

if [ -z "$INTERFACES" ]; then
  db_input critical ppp/detect_failed || true
  db_go || true
  exit 1
fi

# test each of the interfaces for a concentrator,
# then stop when one is found.

for IFACE in $INTERFACES; do
	if ppp_concentrator_on $IFACE; then
		log "setting pppoe connection on $IFACE"
		db_set ppp/interface $IFACE
		break
	else
		if [ "$PPPUP" = yes ]; then
			log "no concentrator found on $IFACE; will bring the interface back down"
			ifconfig $IFACE down
		else
			log "ppp-udeb no concentrator found on $IFACE"
		fi
		IFACE=''
	fi
done

if [ -z "$IFACE" ]; then
	db_input critical ppp/no_concentrators || true
	db_go || true
	exit 1
fi

db_input high ppp/username || true
db_go || true
db_get ppp/username
USERNAME="$RET"

db_input high ppp/password || true
db_go || true
db_get ppp/password
PASSWORD="$RET"

# XXX just to be sure that the answers will not be cached if the script
# is run a second time
db_unregister ppp/password
db_unregister ppp/username


cat <<EOF > /etc/ppp/peers/pppoe
# kernel space PPPoE driver example configuration
#
# See the manual page pppd(8) for information on all the options.

# MUST CHANGE: Uncomment the following line, replacing the user@provider.net
# by the DSL user name given to your by your DSL provider.
# There should be a matching entry with the password in /etc/ppp/pap-secrets
# and/or /etc/ppp/chap-secrets.
#user "myusername@myprovider.net"
user "$USERNAME"

# Load the pppoe plugin. Change the ethernet interface name if needed.
plugin rp-pppoe.so
$IFACE

# Assumes that your IP address is allocated dynamically by the ISP.
noipdefault
# Try to get the name server addresses from the ISP.
usepeerdns
# Use this connection as the default route.
# Comment out if you already have the correct default route installed.
defaultroute

# Make sure that sensitive data does not get into the logs
hide-password

# Peer should be alive
lcp-echo-interval 20
lcp-echo-failure 3

# Makes pppd "dial again" when the connection is lost.
persist

# Do not ask the remote to authenticate.
noauth

# RFC 2516, paragraph 7 mandates that the following options MUST NOT be
# requested and MUST be rejected if requested by the peer:
# Address-and-Control-Field-Compression (ACFC)
noaccomp
# Asynchronous-Control-Character-Map (ACCM)
default-asyncmap

# Do not try to negotiate other kinds of compression.
nopcomp
noccp
novj
EOF

: > /etc/ppp/pap-secrets
chmod 600 /etc/ppp/pap-secrets
cat <<EOF > /etc/ppp/pap-secrets
#GENERATED-BY-DEBIAN-INSTALLER#
$USERNAME	*	$PASSWORD
EOF
cp /etc/ppp/pap-secrets /etc/ppp/chap-secrets

log-output -t depmod
log-output -t ppp-udeb modprobe pppoe

# FIXME: bring down the pppoe connection if that already exists,
# but only our pppoe connection to ensure idempotency, otherwise one
# might end up with more than one pppoe connection on the same IFACE

if [ "$PPPOE" ]; then
	ifconfig $PPPOE down || true
fi
log-output -t ppp-udeb pppd call pppoe || true
# FIXME: detect the ppp connection that was brought up
# db_set ppp/pppoe_pair "$IFACE:$PPPOE"
# this can not be done because db_stop was called earlier. or?

# FIXME - how can this be improved?
[ -e /etc/resolv.conf ] || ln -s /etc/ppp/resolv.conf /etc/resolv.conf

log-output apt-install ppp || true

#DEBHELPER#

exit 0
