#!/usr/bin/perl -w
# This file needs normal 755 permissions
=head1 pppcontrol -- a web interface for gpppwarp

You can use pppcontrol if you have a webserver running on
the computer where your modem is connected. To activate
the modem connection you first select this page (you can
have it as the default page in Netscape) and then you 
start the ppp connection from here.

=head1 Installation

1) Just move this cgi program into the cgi-bin
   directory of your webserver (often /home/httpd/cgi-bin/)

2) Change the variable $url below to have the right IP address.

All other configuration is done in /etc/ppp just as for gpppwarp.

This software is part of a package called gpppwrap
and available from http://www.linuxfocus.org/~guido/

Copyright: GPL
Written by: guido@bearix.oche.de

=cut

# -------------------------------------------------------
use strict;
my $version="1.1";
#global data:
my %FORM;
my %html;
my ($options,$onoff);
my $cmdres="";
# valid entries form /etc/ppp/gpppwrap.conf:
my @ppponargs;
#The url of this program:
my $url = "http://10.0.0.1/cgi-bin/pppcontrol";
#
#
# set selected variables
$ENV{'IFS'}=" ";
$ENV{'PATH'}="/bin:/usr/bin";
$ENV{'HOME'}="/tmp";
#
print "Pragma: no-cache\n";
print "Content-type: text/html\n\n";
#
&cgi_receive;
# now after cgi_receive delete the environment:
%ENV=();
$ENV{'IFS'}=" ";
$ENV{'TERM'}="dumb";
$ENV{'PATH'}="/bin:/usr/bin";
$ENV{'HOME'}="/tmp";
#
&readHTMLpage();
if ($FORM{'nextstate'}){
    &run_ppp_scripts();
}else{
    &read_etc_ppp_gpppwrap_conf();
    &make_options_list();
    $onoff=&onoff();
    &printHTMLpage('main');
}
#--------------------------------------------------------
sub printHTMLpage($){
    my $reqpage = shift;
    my $tmp;
    die "ERROR: no such template $reqpage\n" unless ($html{$reqpage});
    for (@{$html{$reqpage}}){
        # the /o is important!!
        s/\$url/$url/o;
        s/\$onoff/$onoff/o;
        s/\$options/$options/o;
        s/\$cmdres/$cmdres/o;
        s/\$version/$version/o;
        print;
    }
}
#--------------------------------------------------------
sub readHTMLpage(){
    #read and print any text between __ xxx __ and the next __ 
    my $pagename="nix";
    while(<DATA>){
        if (/^__ (\w+) __/){
            $pagename=$1;
            next;
        }
        next if (/^__ /);
        push(@{$html{$pagename}},$_);
    }
}
#--------------------------------------------------------
# write to @ppponargs
sub read_etc_ppp_gpppwrap_conf(){
    open(RDB,"/etc/ppp/gpppwrap.conf")||die "ERROR: pppcontrol, can not read /etc/ppp/gpppwrap.conf\n";
    while(<RDB>){
        chomp;
        next unless(/^ppponarg:/);
        s/#.*$//; #remove tailing comments
        s/ppponarg:\s*//;
        push(@ppponargs,$_);
    }
    close RDB;
    die "ERROR: pppcontrol, no ppponarg found in /etc/ppp/gpppwrap.conf\n" unless (scalar @ppponargs > 1);
}
#--------------------------------------------------------
# make options list: read the contet of @ppponargs
# and write to $options a string like this one:
#  <option VALUE="02412345" selected>02412345 - my isp
#  <option VALUE="02345987">02345987 - backup isp
sub make_options_list(){
    my ($numandtxt,$num);
    $options="";
    my $last=get_last_dialed();
    for (@ppponargs){
        $numandtxt=$_;
        s/\s*\-.*//;
        s/\s+//g;
        $num=$_;
        if ($last && ($last eq $num)){
            $options.="<option VALUE=\"$num\" selected>$numandtxt\n";
        }else{
            $options.="<option VALUE=\"$num\">$numandtxt\n";
        }
    }
}
#--------------------------------------------------------
# returns html code and check if a ppp interface is
# up by reading the output of /sbin/ifconfig
sub onoff(){
    open(PIPE,"/sbin/ifconfig |")||die "ERROR: pppcontrol, can not open pipe to /sbin/ifconfig\n"; 
    while(<PIPE>){
        if (m/^ppp/){
            close PIPE;
            return "<font size=\"+1\" color=\"#00FF00\">on</font>";
        }
    }
    close PIPE;
    return "<font size=\"+1\" color=\"#FF0000\">off</font>";
}
#--------------------------------------------------------
# write ppponarg number to /tmp/gpppwarp.last if possible
sub writelast_dialed($){
    # and read its content
    my $ph=shift;
    if ( open(OUT,">/tmp/gpppwarp.last")){
        print OUT "$ph\n";
        close OUT;
    }
    return 0;
}
#--------------------------------------------------------
# returns 0 or a string
sub get_last_dialed(){
    # check if there is a /tmp/gpppwarp.last file
    # and read its content
    my $tmp=0;
    if ( -r "/tmp/gpppwarp.last"){
        open(FF,"/tmp/gpppwarp.last")||die "ERROR: can not read /tmp/gpppwarp.last\n";
        while(<FF>){
            chomp;
            if (/\w/){
                $tmp=$_;
                last;
            }
        }
        close FF;
        return $tmp;
    }else{
        return 0;
    }
}
#--------------------------------------------------------
# run the /etc/ppp/scripts/ppp-on or /etc/ppp/scripts/ppp-off
# script.
sub run_ppp_scripts(){
	if ($FORM{'nextstate'} eq "on"){
        my $phnum;
        $phnum=$FORM{'phnum'};
        if ($phnum){
            &writelast_dialed($phnum);
            $cmdres="number: $phnum";
            $phnum=quotemeta $phnum;
            $cmdres.=`/etc/ppp/scripts/ppp-on $phnum 2>&1`;     
        }else{
            $cmdres="Strage error: arg for ppp-on was empty\n";
        }
        &printHTMLpage('resulton');
    }else{
        $cmdres=`/etc/ppp/scripts/ppp-off 2>&1`;     
        &printHTMLpage('resultoff');
    }
}
#--------------------------------------------------------
#--------------------------------------------------------
sub cgi_receive{
    my $buffer = "";
    my $pair;
    my $name;
    my $value;
    if ($ENV{'GATEWAY_INTERFACE'} && $ENV{'GATEWAY_INTERFACE'} =~ /CGI/){
        if ($ENV{'REQUEST_METHOD'} eq 'GET') {
            if($ENV{'QUERY_STRING'}){
                $buffer = $ENV{'QUERY_STRING'};
            }
        }elsif ($ENV{'REQUEST_METHOD'} eq 'POST') {
            read(STDIN, $buffer,$ENV{'CONTENT_LENGTH'});
        }else{
            die "Unknown REQUEST_METHOD: $ENV{'REQUEST_METHOD'}";
        }
    }else {
        $buffer = $ARGV[0] if ($ARGV[0]);
    }
    # now decode it:
    #
    # Split the name-value pairs
    foreach $pair (split(/\&/, $buffer)){
        ($name, $value) = split(/=/, $pair);
        $value = " " unless ($value);
        # Un-Webify plus signs and %-encoding
        $value =~ tr/+/ /;
        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
        $FORM{$name} = $value;
    }
}

#--------------------------------------------------------
__END__
__ main __
<HTML>
<HEAD>
<TITLE>ppp control</TITLE>
</HEAD>

<BODY>
<CENTER><H1>
ppp control</H1></CENTER>
<p>
From this page you can activate the PPP connection to your
internet service provider. Just select an entry from the list below
and press ppp-on to dail out or ppp-off to terminate the connection.

<br>
The current state of the connection is: $onoff
</p>

<center>
<table>
<tr>
<td>
  <FORM METHOD="get" ACTION="$url"> 
      <TABLE BORDER="1" CELLPADDING="5" cellspacing="0" bgcolor="#9999BB" WIDTH="100%">
      <TR>
      <TD ALIGN="center">
  	      <select name="phnum">
        $options
          </select>
      </TD>
      </TR>
      <TR>
      <TR>
      <TD  VALIGN="top" ALIGN="center">
          <input type=hidden name="nextstate" value="on">
          <INPUT TYPE="submit" VALUE="ppp-on">
      </TD>
      </TR>
      </TABLE>
  </FORM>
</td>
</tr>
<tr>
<td>  
      <TABLE BORDER="1" CELLPADDING="5" cellspacing="0" bgcolor="#9999BB" WIDTH="100%">
      <TR>
      <TD  VALIGN="top" ALIGN="center">
        <FORM METHOD="get" ACTION="$url"> 
        <input type=hidden name="nextstate" value="off">
        <INPUT TYPE="submit" VALUE="ppp-off">
        </FORM>
      </TD>
      </TR>
      </TABLE>
</td>
</TR>
</TABLE>
</CENTER>

<HR width="100%" size=2 NOSHADE >
<small>pppcontrol version $version</small>
</BODY>
</HTML>

__ resulton __
<HTML>
<HEAD>
<TITLE>ppp on</TITLE>
</HEAD>
<BODY>
<p>Thanks, I will now dial out ....</p>
<pre>$cmdres</pre>
<br>
<HR width="100%" size=2 NOSHADE >
<p align=center><a href="$url">Back to the main ppp control page</a>
</p>
</BODY>
</HTML>

__ resultoff __
<HTML>
<HEAD>
<TITLE>ppp off</TITLE>
</HEAD>
<BODY>
<p>Thanks, I will now terminate ppp ....</p>
<pre>$cmdres</pre>
<br>
<HR width="100%" size=2 NOSHADE >
<p align=center><a href="$url">Back to the main ppp control page</a>
</p>
</BODY>
</HTML>


__ ende __

 vim: set sw=4 ts=4 et si: 
