#!/usr/local/bin/perl
# Janne Himanka <shem@oyt.oulu.fi> 1996-09-19
# Hieman keskeneräinen perl-ohjelma, joka toteuttaa yhdyskäytävän
# WWW:n ja VTLS-kirjastojärjestelmän välillä. Puuttuvat toiminnot:
# katkaisu ja Boolen haku. Ohjelma on tehty kokonaan Perlillä.
# Vapaasti levitettävissä kunhan tieto alkuperäisestä tekijästä
# säilytetään koodin mukana. Tekijä sanoutuu irti kaikesta vastuusta
# ohjelman tekemien mahdollisten tuhojen suhteen.

use CGI::Base;
use CGI::MiniSvr;
use CGI::Request;
require "Comm.pl";
#use sigtrap;
#use diagnostics;


$ENV{PATH} .= ":/usr/sbin";
CGI::Base::Debug(2);
CGI::Request::Debug(2);

$SIG{TERM} = 'IGNORE';

$req = GetRequest('R');
$cgi = new CGI::MiniSvr;
$port = $cgi->port;
$me = "http://clovis.oulu.fi$port/cgi-bin/han/han";
$kw = 0;
$Debug = 1;
CGI::Base::LogFile("/usr/local/httpd/cgi-bin/han/han.log") unless -t STDIN;


sub init {
    &Comm'init(); #'
    ($Proc_pty_handle, $Proc_tty_handle, $Proc_pid) = 
	&open_proc("telnet kirjasto.oulu.fi");
    &stty_raw($Proc_tty_handle);    
    
    ( $match, $err, $before, $after ) = 
	&expect( $Proc_pty_handle, 30, 'KIRJASTO');

#	    print STDERR "HELLO: $err\n";
    if ($err eq 'TIMEOUT') { close_it ($Proc_pty_handle); die "TIMEOUT"; }

    sleep 2;
    print $Proc_pty_handle "hello han,user.clas01\r\n";

    ( $match, $err, $before, $after ) = 
	&expect( $Proc_pty_handle, 40, 'erminal type');

#	    print STDERR "Terminal type: $err\n";
    if ($err eq 'TIMEOUT') { close_it ($Proc_pty_handle); die "TIMEOUT"; }

    sleep 2;
    print $Proc_pty_handle "10\r\n";

    ( $match, $err, $before, $after ) = 
	&expect( $Proc_pty_handle, 40, 'Anna kokoelmatunnus');

#	    print STDERR "Kokoelmatunnus: $err\n";
    if ($err eq 'TIMEOUT') { close_it ($Proc_pty_handle); die "TIMEOUT"; }

    sleep 2;
    print $Proc_pty_handle "100\r\n";
}

sub hakulomake {

    print <<"EOT";
<html>
<head>
<title>Haku OULA-kirjastoluettelosta</title>
</head>
<body>
<h1>Haku OULA-kirjastoluettelosta</h1>
<form method="POST" action="$me">
<input type="hidden" name="sivu" value="haku">
<table>
<tr>
<th>Hakusana</th><th>Haun kohde</th>
</tr>
<tr>
<td><input type="text" name="kysely" size="30"></td>
<td>
<select name="kohde">
<option>Tekijä (Sukunimi, Etunimi)</option>
<option>Nimeke</option>
<option>Hakusana (katkaisu *)</option>
<option>Asiasana</option>
<option>UDK</option>
</select>
</td>
</tr>
</table>
<input type="submit" value="Tee haku">
</form>
</body>
</html>
EOT
    $cgi->done;


}

sub tee_haku {

    my $komento;
    my (@rivit, @rivi);
    my ($match, $err, $before, $after);

    for ($R::kohde) {
	/^Tekij/ && do {
	    $komento = "a/";
	    last;
	};
	/^Nimeke/ && do {
	    $komento = "t/";
	    last;
	};
	/^Hakusana/ && do {
	    &sanahaku;
	    return;
	};
	/^Asiasana/ && do {
	    $komento = "s/";
	    last;
	};
	/^UDK/ && do {
	    $komento = "z/";
	    last;
	};
    }
    $komento .= $R::kysely;
    print <<"EOT";
<html>
<head>
<title>OULA-haun tulos</title>
</head>
<body>
<h1>OULA-haun tulos</h1>
<table>
<tr>
<th>Viite</th><th>Teoksia kpl</th><th>Hakuavain</th>
</tr>
EOT

    print $Proc_pty_handle "$komento\r\n";
    ($match, $err, $before, $after) = 
	&expect($Proc_pty_handle, 20, '\s+1[.>*][\0-\377]+\nRivin');

    @rivit = split(/\n/, $match);
    for (@rivit) {
	next unless (/\s*(\d+)[.>\s]+(\d*)\s+(.+)/);
	@rivi = ($1, $2, $3);
	if ($rivi[1] > 1) {
	    $rivi[0] =~ s#(\d+)#<a href=$me?sivu=lista2&edellinen=haku&valitse=$1>$1</a>#;
	}
	else {
	    $rivi[0] =~ s#(\d+)#<a href=$me?sivu=nide&edellinen=haku&valitse=$1>$1</a>#;
	}
	print <<"EOT";
<tr>
<td>$rivi[0]</td>
<td>$rivi[1]</td>
<td>$rivi[2]</td>
</tr>
EOT
}



    print <<"EOT";
</table>
<hr>
<a href="$me?sivu=eka">Hakusivulle</a>
<a href="$me?sivu=ps&kohde=haku&kysely=ps">Taaksepäin listauksessa</a>
<a href="$me?sivu=ns&kohde=haku&kysely=ns">Eteenpäin listauksessa</a>
</body>
</html>
EOT

    $cgi->done;

}


sub valitse_listasta2 {

    my (@rivi, @rivit);
    my ($match, $err, $before, $after) = ("", "", "", "");
    my $ekasivu = 0;

    print <<"EOT";
<html>
<head>
<title>OULA-haun viitteet</title>
</head>
<body>
<h1>OULA-haun viitteet</h1>
<table>
<tr>
<th>Viite</th><th>Sijaintitiedot</th>
</tr>
EOT

    print $Proc_pty_handle "$R::valitse\r\n";

    ($match, $err, $before, $after) = 
	&expect($Proc_pty_handle, 20, '\s+\d+\.[\0-\377]+Muu komento');
    @rivit = split(/\n/, $match);
    for (@rivit) {
	next unless (/^\s+(\d+)\.\s+(.+)/);
	@rivi = ($1, $2);
	if ($rivi[0] == 1) { $ekasivu = 1; }
	$rivi[0] =~ s#(\d+)#<a href=$me?sivu=nide&edellinen=lista2&valitse=$1>$1</a>#;
	print <<"EOT";
<tr>
<td>$rivi[0]</td>
<td>$rivi[1]</td>
</tr>
EOT
}

    print <<"EOT";
</table>
<hr>
<a href="$me?sivu=eka">Hakusivulle</a>
EOT
    if ($ekasivu) {
	if ($R::edellinen eq "haku") {
	    print "<a href=\"$me?sivu=ps&kohde=haku&kysely=ps\">Edelliselle sivulle</a><br>\n";
	}
	elsif ($R::edellinen eq "sanahaku") {
	    print "<a href=\"$me?sivu=ps&kohde=sanahaku&kysely=ps\">Edelliselle sivulle</a><br>\n";
	}
    }
    else {
	print "<a href=\"$me?sivu=ps&kohde=lista2\">Taaksepäin listassa</a><br>\n";
    }
    if ($match =~ /NS\.+Seuraava n/) {
	print "<a href=\"$me?sivu=ns&kohde=lista2\">Eteenpäin listassa</a><br>\n";
    }
    if ($kw) {
	print "<a href=\"$me?sivu=sanahaku&kysely=kw&edellinen=lista2\">Haetut sanat -sivulle</a><br>\n";
    }

	print <<"EOT";
</body>
</html>
EOT

    $cgi->done;

}

sub nide {

    my (@rivi, @rivit);
    my ($label, $value);
    my $template = "A4A2A21A15A14A6";


    print <<"EOT";
<html>
<head>
<title>OULA-haun nidevalikko</title>
</head>
<body>
<h1>OULA-haun nidevalikko</h1>
<p>
EOT

    print $Proc_pty_handle "$R::valitse\r\n";
    ($match, $err, $before, $after) = 
	&expect($Proc_pty_handle, 20, '[A-ZÅÄÖ]+:[\0-\377]+\nRivin');
    @rivit = split(/\n/, $match);
    for (@rivit) {
	next unless (/([A-ZÅÄÖ]+:)\s+(.+)/);
	$label = $1; $value = $2;
	print "<strong>$label</strong><samp> </samp>$value<br>\n";
    }

    print <<"EOT";
<hr>
<table border="1" cellspacing="1" cellpadding="1">
<tr>
<th>VIITE</th><th>KOKOELMA</th><th>TILA</th><th>ID-NUMERO</th><th>KPL OSA/NRO</th>
</tr>
EOT

    for (@rivit) {
	next unless (/^\s+\d/);
	@rivi = unpack($template, $_);
	$rivi[0] =~ s/\s//g;
	$rivi[0] =~ s!(\d+)!<a href="$me?sivu=hylly&edellinen=nide&valitse=$1">$1</a>!;
	print "<tr>\n";
	print <<"EOT";
<td>$rivi[0]</td>
<td>$rivi[2]</td>
<td>$rivi[3]</td>
<td>$rivi[4]</td>
<td>$rivi[5]</td>
</tr>
EOT
    }

    print <<"EOT";
</table>
<hr>
EOT
    if (($R::edellinen eq "lista2") ||($R::edellinen eq "hylly") ) {
	print "<a href=\"$me?sivu=ps&edellinen=nide&kohde=lista2\">Edelliselle sivulle</a><br>\n";
    }
    elsif ($R::edellinen eq "sanahaku") {
	print "<a href=\"$me?sivu=ps&edellinen=nide&kohde=sanahaku\">Edelliselle sivulle</a><br>\n";
}
    if ($kw) {
	print "<a href=\"$me?sivu=sanahaku&kysely=kw&edellinen=nide\">Haetut sanat -sivulle</a><br>\n";
    }

    print <<"EOT";
<a href="$me?sivu=eka">Hakusivulle</a>
</body>
</html>
EOT

    $cgi->done;

}

sub hylly {

    my (@rivi, @rivit);
    my ($label, $value);

    print <<"EOT";
<html>
<head>
<title>OULA - teoksen hyllysijainti</title>
</head>
<body>
<h1>OULA - teoksen hyllysijainti</h1>
<p>
EOT

    print $Proc_pty_handle "$R::valitse\r\n";
    ($match, $err, $before, $after) = 
	&expect($Proc_pty_handle, 20, '[A-ZÅÄÖ]+:[\0-\377]+\nPS');
    @rivit = split(/\n/, $match);
    for (@rivit) {
	next unless (/([A-ZÅÄÖ]+:)\s+(.+)/);
	$label = $1; $value = $2;
	print "<strong>$label</strong><samp> </samp>$value<br>\n";
    }

for (@rivit) {
    next unless (/^(---->)(.+)/);
    @rivi = ($1, $2);
    print "<p>$rivi[0] $rivi[1]</p>\n";
}

    print <<"EOT";
<hr>
<a href="$me?sivu=ps&kohde=nide&edellinen=hylly">Edelliselle sivulle</a><br>
<a href="$me?sivu=eka">Hakusivulle</a><br>
EOT
    if ($kw) {
	print "<a href=\"$me?sivu=sanahaku&kysely=kw&edellinen=hylly\">Haetut sanat -sivulle</a><br>\n";
    }

    print <<"EOT";
</body>
</html>
EOT

    $cgi->done;
}

sub sanahaku {

    my (@rivi, @rivit);
    my $komento;
    my ($match, $err, $before, $after);

    if ($R::kysely eq "ps") { $komento = "ps\r\n"; }
    elsif ($R::kysely eq "kw") { $komento = "/kw\r\n"; }
    elsif ($R::kysely =~ /^\d+$/) { $komento = $R::kysely }
    else {
	$komento = "w/$R::kysely\r\n";
	$kw = 1;
    }

    print <<"EOT";
<html>
<head>
<title>OULA-haun tulos</title>
</head>
<body>
<h1>OULA-haun tulos</h1>
<h2>komento = $komento %% kysely = $R::kysely</h2>
<table>
<tr>
<th>Viite</th><th>Hakusana</th><th>Teoksia kpl</th>
</tr>
EOT


    if ($R::kysely =~ /\*$/) {
# Käyttäjä on katkaissut oikealta
	print $Proc_pty_handle $komento;

	while (1) {
	    print "<!-- Etappi 1 $match -->\n";
	    ($match, $err, $before, $after) = 
		&expect($Proc_pty_handle, 15, 'Jatkatko hakua', 'Jatka painamalla', 'ASIASANAT[\0-\377]+Muu komento', '^\s*\d+\.[\0-\377]+Muu komento');

	    if (($match eq 'Jatkatko hakua') || ($match eq 'Jatka painamalla')) {
		print $Proc_pty_handle "\r\n";
	    }
	    else { last; }
	}
	print "<!-- Etappi 2 $match -->\n";
	if ($match =~ /ASIASANAT/) {
	    &sanahakuselaus($match);
	    return;
	}
	else {
#	    ($match, $err, $before, $after) = 
#		&expect($Proc_pty_handle, 5, '^\s+\d+\.[\0-\377]+Muu komento');

	    @rivit = split(/\n/, $match);
	    for (@rivit) {
		next unless (/^\s+(\d+)\.[\s*]+(.+) VIIT/);
		@rivi = ($1, $2, $3);
		print "<!-- $rivi[0] $rivi[1] $rivi[2] -->\n";
		next if ($rivi[2] == 4992); # Liian suuri tulosjoukko
		$rivi[1] =~ s#(\w+)#<a href=$me?sivu=lista2&edellinen=sanahaku&valitse=$rivi[0]>$1</a>#;
		print <<"EOT";
<tr>
<td>$rivi[0]</td>
<td>$rivi[1]</td>
<td>$rivi[2]</td>
</tr>
EOT
}
	}
    }
	else {
# Käyttäjä ei ole katkaissut
	print $Proc_pty_handle $komento;

    ($match, $err, $before, $after) = 
	&expect($Proc_pty_handle, 20, '\s+\d+\.[\0-\377]+Muu komento');
    @rivit = split(/\n/, $match);
    for (@rivit) {
	next unless (/^\s+(\d+)\.[\s*]+(.+) VIIT/);
	@rivi = ($1, $2, $3);
	next if ($rivi[2] == 4992); # Liian suuri tulosjoukko
	$rivi[1] =~ s#(\w+)#<a href=$me?sivu=lista2&edellinen=sanahaku&valitse=$rivi[0]>$1</a>#;
	print <<"EOT";
<tr>
<td>$rivi[0]</td>
<td>$rivi[1]</td>
<td>$rivi[2]</td>
</tr>
EOT
}

    }
    print <<"EOT";
</table>
<hr>
<a href="$me?sivu=eka">Hakusivulle</a>
</body>
</html>
EOT

    $cgi->done;

}

sub sanahakuselaus {

    my $sivu = shift || "";
    my ($match, $err, $before, $after);
    my (@rivi, @rivit);

    if ($sivu eq "") {
	print $Proc_pty_handle "$R::kysely\r\n";
	($match, $err, $before, $after) =
	    &expect($Proc_pty_handle, 20, 'ASIASANAT[\0-\377]+Muu komento');
	$sivu = $match;
    }

    print <<"EOT";
<html>
<head>
<title>OULA - sanaluettelo</title>
</head>
<body>
<h1>OULA - sanaluettelo</h1>
<table>
<tr>
<th>Viite</th><th>Sana</th><th>KPL</th>
</tr>
EOT

    @rivit = split(/\n/, $sivu);
    for (@rivit) {
	next unless (/^\s*(\d+)\.\s+(.+)\s+\d+\s+\d+\s+\d+\s+(\d+)/);
	@rivi = ($1, $2, $3);
	$rivi[1] =~ s#(\d+)#<a href=$me?sivu=sanahaku&kysely=$rivi[0]>$1</a>#;
	print <<"EOT";
<tr>
<td>$rivi[0]</td>
<td>$rivi[1]</td>
<td>$rivi[2]</td>
</tr>
EOT
}

    print <<"EOT";
</table>
<hr>
<a href="$me?sivu=ps&kohde=sanahakuselaus&kysely=ps">Edelliselle sivulle</a>
<a href="$me?sivu=ns&kohde=sanahakuselaus&kysely=ns">Seuraavalle sivulle</a>
<a href="$me?sivu=eka">Hakusivulle</a>
</body>
</html>
EOT

    $cgi->done;


}


### PARENT
print <<"EOT";
<html>
<head>
<title>OULA-kirjastoluettelo</title>
</head>
<body>
<h1>Yhdyskäytävä OULA-kirjastoluetteloon</h1>
<p>
Tervetuloa käyttämään Oulun yliopiston kirjaston OULA-kirjastoluetteloa
tämän WWW-yhdyskäytävän kautta! Tämä on testiversio, joten toiminta on enemmän tai vähemmän epäluotettavaa.
</p>
<p>
<a href="$me?sivu=eka">Ota yhteys OULAan...tämä kestää hetkisen.</a>
</p>
<p>
<strong>HUOM</strong> Älä käytä selaimen (esim. netscapen) Back-nappia
kun palaat edelliselle sivulle, käytä sen sijaan sivun alalaidassa olevia 
linkkejä. Yhteys katkeaa itsestään, jos et tee mitään noin minuuttiin.
</p>
<p>
Tämä ohjelma voi lakata toimimasta milloin hyvänsä, sillä teen siihen koko ajan suurehkoja muutoksia. --Janne
</p>
<hr>
<address><a href="mailto:webmaster\@clovis.oulu.fi">webmaster\@clovis.oulu.fi</a></address>
</body>
</html>
EOT

$cgi->done();
$cgi->spawn and exit 0;


### CHILD
CGI::Request::Interface($cgi);
&init;


while($req = GetRequest('R') or $cgi->exit){

#    SendHeaders();
    for ($req->param('sivu')) {

	/eka/ && do {
	    &hakulomake;
	    last;
	};
	/^haku/ && do {
	    &tee_haku;
	    last;
	};
	/^sanahaku$/ && do {
	    &sanahaku;
	    last;
	};
	/^sanahakuselaus/ && do {
	    &sanahakuselaus;
	    last;
	};
	/^lista2/ && do {
	    &valitse_listasta2;
	    last;
	};
	/nide/ && do {
	    &nide;
	    last;
	};
	/hylly/ && do {
	    &hylly;
	    last;
	};
	/^ps/ && do {
	    $R::valitse = "ps";
	    if ($R::kohde eq "lista2") { &valitse_listasta2; }
	    elsif ($R::kohde eq "nide") { &nide; }
	    elsif ($R::kohde eq "haku") { &tee_haku; }
	    elsif ($R::kohde eq "sanahaku") { &sanahaku; }
	    elsif ($R::kohde eq "sanahakuselaus") { &sanahakuselaus; }
	    last;
	};
	/^ns/ && do {
	    $R::valitse = "ns";
	    if ($R::kohde eq "lista2") {&valitse_listasta2;}
	    elsif ($R::kohde eq "haku") { &tee_haku; }
	    elsif ($R::kohde eq "sanahaku") { &sanahaku; }
	    elsif ($R::kohde eq "sanahakuselaus") { &sanahakuselaus; }
	    last;
	};
    }
}

$cgi->exit;


