#!/usr/bin/perl

##
## netwatch: Watch network status
##
## Author: Shun-ichi TAHARA <jado@flowernet.gr.jp>
## Time-stamp: <03/05/30 02:14:30 jado@sheira>
##

$SIG{CHLD} = sub { wait };
$home = $ENV{HOME} or (getpwuid($<))[7] or die "Can't get home directory\n";
%config = ();
%status = ();
@cases = ();

## Main

&config;

while (1) {
    foreach (@cases) {
	my ($file) = glob "/var/lib/net/$_";
	if (-f $file) {
	    &connected($_) unless $status{$_};
	} else {
	    &disconnected($_) if $status{$_};
	}
    }
    while (sleep(5) < 1) {}
}

## NOTREACHED

sub config {
    local (*INFILE);
    my ($prev, $case) = ('', 'eth0-default');

    unless (open(INFILE, "$home/.netwatch")) {
	%config = ();
	return;
    }
    while (<INFILE>) {
	next if /^\s*\#/;
	chomp;
	# continuous line
	if ($prev ne '') {
	    s/^\s*//;
	    $_ = $prev . $_;
	    $prev = '';
	}
	if (/\\$/) {
	    chop;
	    $prev = $_;
	    next;
	}
	s/^\s*//;
	s/\s*$//;
	next if /^$/;
	if (/^case\s+(\S+)\s+(.*)$/) {
	    $case = $1;
	    push @{$config{$case}}, $2;
	} elsif (/^case\s+(\S+)/) {
	    $case = $1;
	} else {
	    push @{$config{$case}}, $_;
	}
    }
    close(INFILE);
    @cases = keys %config;
}

sub connected {
    my ($case) = @_;

    foreach (@{$config{$case}}) {
	my ($pid);

	if ($pid = fork) {
	    push @{$status{$case}}, $pid;
	} elsif (defined $pid) {
	    exec $_;
	    exit(0);
	}
    }
}

sub disconnected {
    my ($case) = @_;

    kill 'TERM', @{$status{$case}};
    delete $status{$case};
}
