#!/usr/bin/perl -w
#
# Program by Bruno Veldeman
#
# Copyright (c) 2001
# All rights reserved
# 
# linkpagegen.pl
# A program for automated link management.
#
# Links are tested for correctness before adding and
# are checked every x days by a cron job. (linkpagegen.pl -check)
# Bad links are marked inactive. If the link is down after 5
# consecutive checks, the link will not be displayed, but still
# be checked. If the links stays down for 30 more checks, the
# link will be removed from the list and will be added to the
# badlinks.txt file.
#
# This program will be released under GPL when passed the
# development stage if there is any interest.
#
# Any sugestions to bruno.veldeman@veldemanvalls.com
#

use strict;
use Socket;
#use Benchmark;
use HTTP::Request;
use LWP::UserAgent;

 my($line,$state,$who,$name,$descr,$URL,$clicks,$rating,$restime,$date,$cat,$buffer);
 my(%postinputs);
 my($datafile,$datadir);
    
 $datadir =  "/var/www/serverinfo/data/";
 $datafile = "links.txt";


if ( defined($ENV{ 'CONTENT_LENGTH'})){
    read(STDIN, $buffer, $ENV{ 'CONTENT_LENGTH'} );

    if ($ENV{ 'REQUEST_METHOD'}  eq 'POST'){
	%postinputs = readpostinput($buffer);

        if ( "$postinputs{'function'}" eq "addlink" ){
	# add link to datafile
	    addlink(%postinputs);
        }
	if ( "$postinputs{'function'}" eq "addlinkpage" ){
	# Print add link page
	    printaddpage();
        }
    }	
}
else {
    my (@par);
    @par=@ARGV;
    if ( defined($par[0])){
	if ("$par[0]" eq "-check"){
	    checkall();
	}
    }
    else {
    	showlinks();
    }
}    
exit(0);

sub showlinks{
    # Tel browser this is HTML
    print("Content-type: text/html\n\n");
    
    # Document Headers
    print('<!DOCTYPE HTML PULIC "-//W3C//DTD HTML 4.0-Transitional//EN">');
    print("\n");
    print('<HTML>');
    print("\n");
    print('<HEAD>');
    print("\n");
    print('<META name="generator" content="linkpagegen.pl by bruno.veldeman@veldemanvalls.com">');
    print("\n");
    print('<TITLE>Links</TITLE>');
    print("\n");
    print('</HEAD>');
    # Document Body
    print("\n");
    print('<BODY bgcolor="#000000" text="#eeeeee" link="#eeeeee" alink="#eeeeee" vlink="#eeeeee">');
    print("\n");
    print('<H2><center>Links</center></H2>');
    print("\n");
    print('<center><table border="1" cellpadding="0" cellspacing="0" width="*,100,100,100">');
    print("\n");
    print('<tr>');
    print("\n");
    print('<td>');
    print("\n");
    print('<b><font size="4">Nombre y descripci&oacute;n</font></b>');
    print("\n");
    print('</td>');
    print("\n");
    print('<td>');
    print("\n");
    print('<b><font size="4">URL</font></b>');
    print("\n");
    print('</td>');
    print("\n");
    print('<td>');
    print("\n");
    print('<b><font size="4">Valoraci&oacute;n</font></b>');
    print("\n");
    print('</td>');
    print("\n");
    print('<td>');
    print("\n");
    print('<b><font size="4">Fecha</font></b>');
    print("\n");
    print('</td>');
    print("\n");
    print('<td>');
    print("\n");
    print('<b><font size="4">Tiempos de<br>respuesta</font></b>');
    print("\n");
    print('</td>');
    print("\n");
    print('</tr>');
    print("\n");

    # Fill the table with data

    open(LINKS,"<$datadir$datafile");
    while ( not eof(LINKS)){
        $line = <LINKS>;
	#Split the line in vars
        ($state,$who,$name,$descr,$URL,$clicks,$rating,$restime,$date,$cat) = split(/\t/,$line);
	if ( "$state" eq "A") { 
	    print('<tr>');
	    print("\n");
	    print('<td>');
	    print("\n");
	    print('<b><a href="');
	    print("$URL");
	    print('">');
	    print("$name</a></b>, $descr");
	    print("\n");
	    print('</td>');
	    print("\n");
	    print('<td>');
	    print("\n");
	    print('<a href="');
	    print("$URL");
	    print('">');
	    print("$URL</a>");
	    print("\n");
	    print('</td>');
	    print("\n");
	    print('<td>');
	    print("\n");
	    ratprn ($rating);
	    print("\n");
	    print('</td>');
	    print("\n");
	    print('<td>');
	    print("\n");
	    print("$date");
	    print("\n");
	    print('</td>');
	    print("\n");
	    print('<td>');
	    print("\n");
	    print("$restime");
	    print("\n");
	    print('</td>');
	    print("\n");
	    print('</tr>');
	    print("\n");
        }
        if ( "$state" eq "I" ){
	    print('<tr>');
	    print("\n");
	    print('<td>');
	    print("\n");
	    print('<b><a href="');
	    print("$URL");
	    print('">');
	    print("$name</a></b>, $descr");
	    print("\n");
	    print('</td>');
	    print("\n");
	    print('<td>');
	    print("\n");
	    print("Inactivo");
	    print("\n");
	    print('</td>');
	    print("\n");
	    print('<td>');
	    print("\n");
	    ratprn ($rating);
	    print("\n");
	    print('</td>');
	    print("\n");
	    print('<td>');
	    print("\n");
	    print("$date");
	    print("\n");
	    print('</td>');
	    print("\n");
	    print('<td>');
	    print("\n");
	    print("#");
	    print("\n");
	    print('</td>');
	    print("\n");
	    print('</tr>');
	    print("\n");
	}
        if ( "$state" eq "C" ){
	    print('<tr>');
	    print("\n");
	    print('<td colspan="5" text=#000000 bgcolor=#0000ff><font size="+2"><center>');
	    print("\n");
	    print("$name");
	    print("\n");
	    print('</center></font></td>');
	    print("\n");
	}
    }
    close(LINKS);

    print('</table></center>');
    # Document Ending
    print("\n");
    print('<P>');
    print("\n");
    print('<center>by Bruno Veldeman</center>');
    print("\n");
    print('</P>');
    print("\n");
    print('<P><center>');
    print("\n");
    print('<form name="FormName" action="/cgi-bin/linkpagegen.pl" method="POST">');
    print("\n");
    print('<input type="hidden" name="function" value="addlinkpage">');
    print("\n");
    print('<input type="submit" value="A&ntilde;adir link">');
    print("\n");
    print('</form>');
    print("\n");
    print('</center></P>');
    print("\n");
    print('</BODY>');
    print("\n");
    print('</HTML>');
    print("\n");
    return(0);
} #End showlinks
	

sub ratprn{
    my ($counter);
    my ($num) = @_;
    for ( $counter = 0 ; $counter < $num ; $counter++){
    print ("*");
    }
    return;
} #End ratprn

sub readpostinput{

    my (%searchField, $pair, @pairs, $value);

    my($buffer) = @_;
    
    @pairs = split(/&/,$buffer);

    foreach $pair (@pairs){
	($name, $value) = split(/=/, $pair);
	$value =~ tr/+/ /;
	$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
	$name =~ tr/+/ /;
	$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
	$searchField{ $name}  = $value;
    }

    return(%searchField);
} #End readpostinput


sub addlink{    

    my (%fields) = @_;
    my ($name) = $fields{'who'};
    
    if ( checklink($fields{'URL'}) ){
	addtofile(%fields);
        printthankyou(%fields);
    }
    else{
	printnogood(%fields);
    }
# Code to add the link to the database
    
return(0);
} #End addlink
 
sub addtofile{

    my (%fields) = @_;
    my ($line,$tempfile,$result,$t,$curcat,$now,$copy,$iscat);
    my ($state,$who,$name,$descr,$URL,$clicks,$rating,$restime,$date,$cat);

    $tempfile = "tempfile.tmp";

    # Set the date and time
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
    
    if ($sec < 10) {
    	$sec = "0$sec";
    }
    if ($min < 10) {
    	$min = "0$min";
    }
    if ($hour < 10) {
    	$hour = "0$hour";
    }
    if ($mon < 10) {
    	$mon = "0$mon";
    }
    if ($mday < 10) {
    	$mday = "0$mday";
    }
    if ($year > 99) {
    	$year += 1900;
    }
    
    $now = "$hour\:$min\:$sec $mon/$mday/$year";

    $iscat = 0;
    $copy = 0;

    open(LINKS,"$datadir$datafile"); # Open the data file
    open(TEMP,">$datadir$tempfile"); # Open a temp file
    while ( not eof(LINKS)){
	$line = <LINKS>;
	chomp($line);
	if ( not (substr($line,1) eq "#") ){
	    #Split the line in vars
	    ($state,$who,$name,$descr,$URL,$clicks,$rating,$restime,$date,$cat) = split(/\t/,$line);
	    if ( "$state" eq "C"){
	    # Is cat header
		if ($who eq $fields{'cat'}){
		# Is cat of link being added
		    $iscat = 1;
    		}
		else{
		    if ($iscat == 1){
		        print TEMP "A\t$fields{'who'}\t$fields{'name'}\t$fields{'descr'}\t$fields{'URL'}\t0\t$fields{'rating'}\t0\t$now\t$fields{'cat'}\n";
			$copy = 1;
			$iscat = 0;
		    }
		}
		print TEMP "$line\n";
	    }
	    else{
		if ( $iscat == 1){
		    if ( ("$fields{'name'}" le "$name") and ($copy == 0)){
		        print TEMP "A\t$fields{'who'}\t$fields{'name'}\t$fields{'descr'}\t$fields{'URL'}\t0\t$fields{'rating'}\t0\t$now\t$fields{'cat'}\n";
			$copy = 1;
			$iscat = 0;
		    }
		}
		print TEMP "$line\n";
	    }
	}
	else{
	    print TEMP "$line\n";
	}
    }
    if ( $copy eq 0){
        print TEMP "A\t$fields{'who'}\t$fields{'name'}\t$fields{'descr'}\t$fields{'URL'}\t0\t$fields{'rating'}\t0\t$now\t$fields{'cat'}\n";
    }
    close(TEMP);
    close(LINKS);
    system("mv -f $datadir$tempfile $datadir$datafile");
    return(0);
}
sub printaddpage{
    
    my ($counter);
    
    # Tel browser this is HTML
    print("Content-type: text/html\n\n");
    
    # Document Headers
    print('<!DOCTYPE HTML PULIC "-//W3C//DTD HTML 4.0-Transitional//EN">');
    print("\n");
    print('<HTML>');
    print("\n");
    print('<head>');
    print("\n");
    print('<meta name="generator" content="linkpagegen.pl by bruno.veldeman@veldemanvalls.com">');
    print("\n");
    print('<title>A&ntilde;adir Link</title>');
    print("\n");
    print('</head>');
    print("\n");
    print('<body bgcolor="#000018" text="white" link="white" alink="white" vlink="white">');
    print("\n");
    print('<div align="center">');
    print("\n");
    print('<h2><b>A&ntilde;adir Link</b></h2>');
    print("\n");
    print('</div>');
    print("\n");
    print('<form action="/cgi-bin/linkpagegen.pl" method="POST">');
    print("\n");
    print('<input type="hidden" name="function" value="addlink">');
    print("\n");
    print('<table border="1" cellpadding="0" cellspacing="2" width="558">');
    print("\n");
    print('<tr height="40">');
    print("\n");
    print('<td height="40">Su nombre :</td>');
    print("\n");
    print('<td height="40"><input type="text" name="who" size="24"> (Opcional)</td>');
    print("\n");
    print('</tr>');
    print("\n");
    print('<tr height="40">');
    print("\n");
    print('<td height="40">Nombre de la p&aacute;gina : </td>');
    print("\n");
    print('<td height="40"><input type="text" name="name" size="62"></td>');
    print("\n");
    print('</tr>');
    print("\n");
    print("\n");
    print('<tr height="40">');
    print("\n");
    print('<td height="40">Descripci&oacute;n corta :</td>');
    print("\n");
    print('<td height="40"><input type="text" name="descr" size="62"></td>');
    print("\n");
    print('</tr>');
    print("\n");
    print('<tr height="40">');
    print("\n");
    print('<td height="40">Direcci&oacute;n :</td>');
    print("\n");
    print('<td height="40"><input type="text" name="URL" size="62" value="http://"></td>');
    print("\n");
    print('</tr>');
    print("\n");
    print('<tr height="40">');
    print("\n");
    print('<td height="40">Valoraci&oacute;n : </td>');
    print("\n");
    print('<td height="40"><select name="rating" size="1">');
    print("\n");
    print('<option>Seleccione una valoraci&oacute;n</option>');
    print("\n");
    print('<option value="1">*</option>');
    print("\n");
    print('<option value="2">**</option>');
    print("\n");
    print('<option value="3">***</option>');
    print("\n");
    print('<option value="4">****</option>');
    print("\n");
    print('<option value="5">*****</option>');
    print("\n");
    print('</select></td>');
    print("\n");
    print('</tr>');
    print("\n");
    print('<tr height="40">');
    print("\n");
    print('<td height="40">Categor&iacute;a : </td>');
    print("\n");
    print('<td height="40"><select name="cat" size="1">');
    print("\n");
    print('<option>Seleccione una categor&iacute;a</option>');
    print("\n");
    # List the categories in popup
    $counter = 1;
    open(LINKS,"$datadir$datafile"); # Open the data file
    while ( not eof(LINKS)){
	$line = <LINKS>;
	chomp($line);
	if ( not (substr($line,1) eq "#") ){
	    #Split the line in vars
	    ($state,$who,$name,$descr,$URL,$clicks,$rating,$restime,$date,$cat) = split(/\t/,$line);
	    if ( "$state" eq "C"){
	    # Is cat header
	        print('<option value="');
		print ("$counter");
		print ('">');
		print ("$name");
		print ('</option>');
		print("\n");
		$counter++;
	    }
	}
    }
    close(LINKS);
    print('</select></td>');
    print("\n");
    print('</tr>');
    print("\n");
    print('</table>');
    print("\n");
    print('<p><input type="submit" value="A&ntilde;adir"></p>');
    print("\n");
    print('</form>');
    print("\n");
    print('<p></p>');
    print("\n");
    print('<p></p>');
    print("\n");
    print('<p></p>');
    print("\n");
    print('</body>');
    print("\n");
    print('</html>');
    print("\n");
    return(0);
} #End printaddpage

sub printthankyou{

    my (%fields) = @_;
    my ($name) = $fields{'who'};

    # Tel browser this is HTML
    print("Content-type: text/html\n\n");

    # Document Headers
    print('<!DOCTYPE HTML PULIC "-//W3C//DTD HTML 4.0-Transitional//EN">');
    print("\n");
    print('<HTML>');
    print("\n");
    print('<HEAD>');
    print("\n");
    print('<TITLE>Gracias</TITLE>');
    print("\n");
    print('</HEAD>');
    print("\n");
    print('<BODY>');
    print("\n");
    print('<TABLE CELLSPACING=2 CELLPADDING=2 border=0 width=600>');
    print("\n");
    print('<TR><th><BR>');
    print("\n");
    print('<center>');
    print("\n");
    print("<FONT SIZE=+3><B>Gracias $name </b></font>");
    print("\n");
    print('</center><BR><BR>');
    print("\n");
    print('<CENTER><B><FONT SIZE=+1>');
    print("\n");
    print('<P>El link ya ha sido agregado a la lista.');
    print("\n");
    print('</P>');
    print("\n");
    print('<BR>');
    print("\n");
    print('<P><A href="/cgi-bin/linkpagegen.pl">Volver a la p&aacute;gina de links</A>');
    print("\n");
    print('</P>');
    print("\n");
    print('</FONT></B><CENTER>');
    print("\n");
    print('</th>');
    print("\n");
    print('</table>');
    print("\n");
    print('</BODY>');
    print("\n");
    print('</HTML>');
    print("\n");
    return(0);
} #End printthankyou

sub printnogood{

    my (%fields) = @_;
    my ($name) = $fields{'who'};

    # Tel browser this is HTML
    print("Content-type: text/html\n\n");

    # Document Headers
    print('<!DOCTYPE HTML PULIC "-//W3C//DTD HTML 4.0-Transitional//EN">');
    print("\n");
    print('<HTML>');
    print("\n");
    print('<HEAD>');
    print("\n");
    print('<TITLE>Error</TITLE>');
    print("\n");
    print('</HEAD>');
    print("\n");
    print('<BODY>');
    print("\n");
    print('<TABLE CELLSPACING=2 CELLPADDING=2 border=0 width=600>');
    print("\n");
    print('<TR><th><BR>');
    print("\n");
    print('<center>');
    print("\n");
    print("<FONT SIZE=+3><B>Lo siento $name </b></font>");
    print("\n");
    print('</center><BR><BR>');
    print("\n");
    print('<CENTER><B><FONT SIZE=+1>');
    print("\n");
    print('<P>El link no es v&aacute;lido.');
    print("\n");
    print('</P>');
    print("\n");
    print('<BR>');
    print("\n");
    print('<P><A href="/cgi-bin/linkpagegen.pl">Volver atras</A>');
    print("\n");
    print('</P>');
    print("\n");
    print('</FONT></B><CENTER>');
    print("\n");
    print('</th>');
    print("\n");
    print('</table>');
    print("\n");
    print('</BODY>');
    print("\n");
    print('</HTML>');
    print("\n");
    return(0);
} #End printthankyou

sub checklink{

    my ($url) = @_;

    my $ua       = new LWP::UserAgent;
    my $request  = new HTTP::Request GET => $url;
    my $response = $ua->request($request);

	print $url;
	print("\n");

    if ( $response->is_success ){
	print $response->code;
	print("\n");
	return(1);
    }
    else {
	print $response->code ;
	print("\n");
	return(0);
    }
} 

sub checkall{

    my (%fields) = @_;
    my ($line,$tempfile,$result,$t,$curcat,$now,$copy);
    my ($state,$who,$name,$descr,$URL,$clicks,$rating,$restime,$date,$cat);
    

    $tempfile = "tempfile.tmp";
    
    open(LINKS,"$datadir$datafile"); # Open the data file
    open(TEMP,">$datadir$tempfile"); # Open a temp file
    while ( not eof(LINKS)){
	$copy = 0;
	$line = <LINKS>;
	chomp($line);
	#Split the line in vars
	($state,$who,$name,$descr,$URL,$clicks,$rating,$restime,$date,$cat) = split(/\t/,$line);
	if ( "$state" eq "A"){
	# Is active link, just check and time
	    $result = checklink($URL);
	    $restime = 0;
	    if ( $result == 0 ){
		$state = "I";
		$restime = 1;
	    }
	    print TEMP "$state\t$who\t$name\t$descr\t$URL\t$clicks\t$rating\t$restime\t$date\t$cat\n";
	}
	else{
	    if ( "$state" eq "I"){
	    # Is inactive link, check and increment counter if not ok
		$result = checklink($URL);
	        if ( $result == 0 ){
		    $restime++;
    		    if ( $restime <= 5 ){
			$state = "I";
		    }
		    else{
			$state = "B";
		    }
		}
		else{
		    $state = "A";
		    #$restime = timestr($t); 
		}
		print TEMP "$state\t$who\t$name\t$descr\t$URL\t$clicks\t$rating\t$restime\t$date\t$cat\n";
	    }
	    else{
		if ( "$state" eq "B"){
		# Is bad link, check and increment counter if not ok
		    if ( $restime <= 10 ){
			$result = checklink($URL);
		        if ( $result == 1 ){
			    #$restime = timestr($t);
			    $state = "A";
			}
			else{
			$restime++;
			}
		    }
		    print TEMP "$state\t$who\t$name\t$descr\t$URL\t$clicks\t$rating\t$restime\t$date\t$cat\n";
		}
		else{
		    if ( "$state" eq "C"){
		    # Is category header, just copy
		    	print TEMP "$state\t$who\t$name\n";
		    }
		    else{
		    # Just copy the line, must be a comment
			print TEMP "$line\n";
		    }
		}
	    }
	}
    }
    close(TEMP);
    close(LINKS);
    system("mv -f $datadir$tempfile $datadir$datafile");
    return(0);
}