#!/bin/sh
#
# tun_zebedee plugin
# Author: Shun-ichi TAHARA <jado@flowernet.gr.jp>
# Time-stamp: <05/03/25 21:54:14 jado@sheira>
#
# Copyright (c) 2004 Shun-ichi TAHARA
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#

# *** Please change below as suitable ***
ZEBEDEECONF=/usr/local/etc/zebedee/client.zbd

# Additional settings going into /etc/network.conf:
#
# ZEBSERVER  : Opposite zebedee server      [server[:port]]
# ZEBPROXY   : SSL proxy server in the way  [direct|server:port]
# ZEBTUNNELS : List of zebedee tunnel specs [none|lport:host:rport...]

TUNZEBDEV=$PLUGINSTATE/tun_zebedee.devices
TUNZEBDEFPORT=11965

tunzeb_config ()
{
    cat $1 | /usr/bin/awk '
	BEGIN{
	    delete proxy;
	    delete tunnel;
	    lastserver = "";
	}
	/^server +[^ ]+/{
	    lastserver = tolower($2);
	}
	/^proxy +[^ ]+/{
	    if ($2 == "direct" || proxy[lastserver] == "") {
		proxy[lastserver] = $2;
	    }
	}
	/^tunnel +[^ ]+/{
	    if (tolower($2) == "none") {
		tunnel[lastserver] = "none";
	    } else if (tunnel[lastserver] != "none") {
		tunnel[lastserver] = tunnel[lastserver] " " $2;
	    }
	}
	END{
	    for (server in tunnel) {
		if (tunnel[server] == "none") {
		    continue;
		}
		printf("%s ", server);
		if (proxy[server] != "" && proxy[server] != "direct") {
		    printf("-x \"httpproxy %s\" ", proxy[server]);
		}
		split(server, sv, ":");
		if (sv[2] != "") {
		    printf("-T %u ", sv[2]);
		}
		printf("%s%s\n", sv[1], tunnel[server]);
	    }
	}
    '
}

tunzeb_sv_start ()
{
    local PIDFILE=$PLUGINSTATE/zebedee-$1.pid

    if [ -s "$ZEBEDEECONF" ]; then
	eval "@ZEBEDEE@ -f $ZEBEDEECONF -o SYSLOG -d $2 &"
    else
	eval "@ZEBEDEE@ -o SYSLOG -d $2 &"
    fi
    echo $! > $PIDFILE
}

tunzeb_sv_stop ()
{
    local PIDFILE=$PLUGINSTATE/zebedee-$1.pid

    if [ -s "$PIDFILE" ]; then
	kill `cat $PIDFILE` 2> /dev/null
	rm -f $PIDFILE
    fi
}

tunzeb_update ()
{
    local OLD= NEW=

    if [ ! -x @ZEBEDEE@ ]; then
	echo "Please install Zebedee to work with ZEBSERVER and ZEBTUNNELS."
	return
    fi

    OLD=`tunzeb_config $TUNZEBDEV`
    NEW=`tunzeb_config $TUNZEBDEV.N`
    mv $TUNZEBDEV.N $TUNZEBDEV

    echo "$OLD" | while read old_svr old_prm; do
	if [ -z "$old_svr" ]; then
	    continue
	fi
	echo "$NEW" | while read new_svr new_prm; do
	    if [ "$old_svr" = "$new_svr" ]; then
		if [ ! "$old_prm" = "$new_prm" ]; then
		    tunzeb_sv_stop "$old_svr"
		    tunzeb_sv_start "$new_svr" "$new_prm"
		fi
		break # break -> continue
	    fi
	    ((0))
	done && continue # break -> continue

	# old_svr is not found in NEW
	tunzeb_sv_stop "$old_svr"
    done

    echo "$NEW" | while read new_svr new_prm; do
	if [ -z "$new_svr" ]; then
	    continue
	fi
	echo "$OLD" | while read old_svr old_prm; do
	    if [ "$old_svr" = "$new_svr" ]; then
		break # break -> continue
	    fi
	    ((0))
	done && continue # break -> continue

	# new_svr is not found in OLD
	tunzeb_sv_start "$new_svr" "$new_prm"
    done
}

# Variables definition

tun_zebedee_VARS="ZEBSERVER ZEBPROXY ZEBTUNNELS"

# Script on starting

tun_zebedee_start ()
{
    touch $TUNZEBDEV
    /usr/bin/sed -e "/# $1 begin/,/# $1 end/d" $TUNZEBDEV > $TUNZEBDEV.N
    if [ -n "$ZEBSERVER" ]; then
	echo "# $1 begin" >> $TUNZEBDEV.N
	case "$ZEBSERVER" in
	*:*)
	    echo "server $ZEBSERVER" >> $TUNZEBDEV.N
	    ;;
	*)
	    echo "server $ZEBSERVER:$TUNZEBDEFPORT" >> $TUNZEBDEV.N
	esac
	if [ -n "$ZEBPROXY" ]; then
	    if [ ! "$ZEBPROXY" = "direct" -a -x @HOST@ ]; then
		# Workaround for zebedee-2.5's bug (?)
		local phost="${ZEBPROXY%:*}"
		local pport="${ZEBPROXY##*:}"
		local result=`@HOST@ -W 3 "$phost" | /usr/bin/grep 'has address'`
		if [ -n "$result" ]; then
		    phost="${result#*has address }"
		fi
		ZEBPROXY="$phost:$pport"
	    fi
	    echo "proxy $ZEBPROXY" >> $TUNZEBDEV.N
	fi
	for s in $ZEBTUNNELS; do
	    echo "tunnel $s" >> $TUNZEBDEV.N
	done
	echo "# $1 end" >> $TUNZEBDEV.N
    fi

    tunzeb_update
}

# Script on stopping

tun_zebedee_stop ()
{
    /usr/bin/sed -e "/# $1 begin/,/# $1 end/d" $TUNZEBDEV > $TUNZEBDEV.N

    tunzeb_update
}
