#!/usr/bin/perl

$0 =~ /^(.*)[\/\\].*/ && chdir ($1);
$| = 1;

use CGI;
use CGI::Carp qw(fatalsToBrowser);
use vars qw($mailprog,$picpath);
use strict;

my $mailprog   = "/usr/sbin/sendmail -t";
my $picpath    = "/images";
my $captchadir = "../captcha";
my $caplog     = "../cgi-bin/caplog";
my $wwwadr     = "http://www.dolzianer.de/cgi-bin/publicbook.pl";
my $title      = "Gästebuch";
my $eintraege  = 10;
my $zeichen    = 500;
my $woerter    = 50;
my $lock       = 0;
my $zeitstd    = 0;
my $query      = new CGI;
my %PARA       = &parse_para();
my $bookdat    = "publicbook.dat";
my $bookpath   = "../gaestebuch/";
my $bookpl     = "publicbook.pl";
my $htmmain    = "gaestebuch_main_public.html";
my $htminst    = "gaestebuch_eintrag.html";

if ($PARA{'func'} eq "captcha") {
  &get_captcha();
  exit;
} elsif ($PARA{'func'} eq "form") {
  &sign_form();
} elsif ($PARA{'func'} eq "new") {
  &new();
} else {
  &show();
}

sub show {
  my ($GUESTAMOUNT,$GUESTDATA)=&read_data();

  $PARA{'action'}   =~ s/\D//g;
  $PARA{'action'} ||=  0;
  $PARA{'action'}   =  0 if ($PARA{'action'}>$GUESTAMOUNT);

  my $anzeige_von = $PARA{'action'};
  my $anzan       = $eintraege;
  my $nocache     = time;
  my ($out);

  open (HTML, "< $bookpath/$htminst") || die "Kann die Datei -$bookpath/$htminst- nicht öffnen : $! ";
  my @html=<HTML>;
  close(HTML);
  my $html=join('',@html);

  for my $x ($anzeige_von .. $anzeige_von+$anzan-1) {
    last if ($x>=$GUESTAMOUNT);

    my $html_tmp = $html;
    my $hp       = "keine Homepage";
    my $em       = "keine E-Mail";

    if ($GUESTDATA->[$x][4] =~ /http:\/\/.*\./) {
      $hp="<a class=\"gb_link\" href=\"$GUESTDATA->[$x][4]\" target=\"new\">$GUESTDATA->[$x][4]</a>";
    }

    if ($GUESTDATA->[$x][2] =~ /.*\@.*\..*/) {
      $em="<a class=\"gb_link\" href=\"mailto:$GUESTDATA->[$x][2]\">$GUESTDATA->[$x][2]</a>";
    }

    if ($GUESTDATA->[$x][6]) {
      $GUESTDATA->[$x][6]="<br>$GUESTDATA->[$x][6]<br>";
    }

    $html_tmp =~ s/<!--comment-->/$GUESTDATA->[$x][6]/ig;
    $html_tmp =~ s/<!--name-->/$GUESTDATA->[$x][1]/ig;
    $html_tmp =~ s/<!--text-->/$GUESTDATA->[$x][3]/ig;
    $html_tmp =~ s/<!--mail-->/$em/ig;
    $html_tmp =~ s/<!--www-->/$hp/ig;
    $html_tmp =~ s/<!--time-->/$GUESTDATA->[$x][5]/ig;
    $html_tmp =~ s/<!--pics-->/$picpath/ig;
    $out .= $html_tmp;
  }

  my $anzeige_zurueck = $anzeige_von-$anzan;
  my $anzeige_weiter  = $anzeige_von+$anzan;
  my $anzeige_von     = $anzeige_von+1;
  my $anzeige_bis     = $anzeige_von+$anzan;

  $out .= qq(<table border=0 width=100% cellspacing=0 cellpadding=0 width=100%><tr><td>);

  if($anzeige_zurueck >= 0) {
    $out .= qq(<a href="$wwwadr?func=show&action=$anzeige_zurueck&nocache=$nocache"  onmouseover="window.status='Vorherige $anzan ...';return true;" onmouseout="window.status='';return true;"><img src="$picpath/previous.gif" border=0 alt="Vorherige $anzan ..."></a>);
  } else {
    $out .= qq(&#160;);
  }

  if ($anzeige_weiter>$GUESTAMOUNT) { $anzeige_bis=$GUESTAMOUNT; }

  $out .= qq~
  </td><td align=center width=100% class=\"gb_status\"><b>$anzeige_von-$anzeige_bis \| $GUESTAMOUNT Einträge</b></td>
  <td align=right>~;

  if($anzeige_weiter<$GUESTAMOUNT) {
    $out .= qq(<a href="$wwwadr?func=show&action=$anzeige_weiter&nocache=$nocache" onmouseover="window.status='Nächste $anzan ...';return true;" onmouseout="window.status='';return true;"><img src="$picpath/next.gif" border=0 alt="Nächste $anzan ..."></a>) ;
  } else {
    $out .= qq(&#160;) ;
  }

  $out .= qq(</td></tr></table>) ;

  print $query->header('text/html');
  print &parse_tmpl($out,$GUESTAMOUNT) ;
}

sub new {
  my %FM=&parse_form() ;

  if (!$FM{'name'} || !$FM{'com'} || (length($FM{'com'})>$zeichen && $zeichen>0 ) ) {
    &er_form(\%FM);
  }

  my $errcode = &check_captcha($FM{'capback'});

  if ($errcode) {
    &er_captcha($FM{'capback'});
  }

  $FM{'com'} =~ s/<script>.*</script>/gi;

  foreach my $key (keys %FM) {
    $FM{$key} =~ s/\&/\&amp\;/g;
    $FM{$key} =~ s/"/\&quot\;/g;
    $FM{$key} =~ s/\cM\n/<BR>/g;
    $FM{$key} =~ s/\n\cM/<BR>/g;
    $FM{$key} =~ s/\cM/<BR>/g;
    $FM{$key} =~ s/\n/<BR>/g;
    $FM{$key} =~ s/\|/\//g;

    my @text=split(/\s+/,$FM{$key});
    my $textok ;

    foreach my $word (@text){
      if ( length($word) > $woerter ) {
        my @chars=split(//,$word);
        my $wordout="";

        for(my $i=0; $i<= $#chars/$woerter; $i++) {
          $wordout=$wordout." ".substr($word,$i*$woerter,$woerter);
        }
        $textok .= "$wordout " if ($wordout);
      } else {
        $textok .= "$word " if ($word);
      }
    }

    $FM{$key} = $textok;
    $FM{$key} =~ s/\s+/ /g;
    $FM{$key} =~ s/\s+/ /g;
    $FM{$key} =~ s/^\s+//g;
    $FM{$key} =~ s/\s+$//g;
  }

  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time+(3600*$zeitstd));
  my $datum = sprintf "%02d.%02d.%04d - %02d:%02d" , $mday , $mon+=1 ,$year+=1900 , $hour , $min;

  open (DATNEW , ">> $bookpath/$bookdat") || die "Kann die Datei -$bookpath/$bookdat- nicht öffnen: $! ";
  flock(DATNEW,2) if ($lock==1);
  print DATNEW time."\|$FM{'name'}\|$FM{'email'}\|$FM{'com'}\|$FM{'url'}\|$datum\|\|$ENV{'REMOTE_ADDR'}\|\n";
  close (DATNEW);

  print $query->redirect("$wwwadr?func=show&action=0&nocache=".time);
}

sub er_captcha {
  my $errcap = shift ;
  my $errmark   = "&nbsp;<font color=ff0000><b>X<\/b><\/font>&nbsp;";
  my $x_hinweis = "Die Buchstabenkombination $errcap ist falsch!";

  &sign_form($x_hinweis,,,);
  exit;
}

sub er_form {
  my $FM        = shift ;
  my $errmark   = "&nbsp;<font color=ff0000><b>X<\/b><\/font>&nbsp;";
  my $x_hinweis = "Ihr müßt mindestens den Namem und einen Kommentar eintragen.";
  my $x_name=$errmark if (!$FM->{'name'});
  my $x_text=$errmark if (!$FM->{'com'});
  my ($x_mail,$x_url);

  if ( $zeichen>0 && length($FM->{'com'})>$zeichen ) {
    $x_hinweis=qq(<font color=ff0000>Maximal zulässige Länge von $zeichen Zeichen überschritten!</font><br>&nbsp;<br>);
  }

  &sign_form($x_hinweis,$x_name,$x_mail,$x_url,$x_text);
  exit;
}

sub sign_form {
  my ($x_hinweis,$x_name,$x_mail,$x_url,$x_text) = @_;
  my ($GUESTAMOUNT) = &read_data();
  my %FM            = &parse_form();
  my ($out);

  $FM{'url'}="http://" unless ($FM{'url'}) ;
  $FM{'com'} =~ s/\n//g ;

  $out = qq~
  <form name="mail" method=POST action="$wwwadr?func=new">
  <table border=0 cellspacing=3>~;

  if ($x_hinweis) {
    $out .= qq~
    <tr>
      <td><br><font color="#ff0000">&nbsp;Fehler:</font><br>&nbsp;<br></td>
      <td>&nbsp;</td>
      <td>$x_hinweis</td>
    </tr>~;
  }

  $out .= qq~

  <tr>
    <td><font face="Verdana,Geneva" size="2" color="#BE9000">&nbsp;Name:</b></font></td>
    <td><font face="Verdana,Geneva" size="2" color="#BE9000">$x_name</font></td>
    <td><input type=text name="name" size=44 maxlength=140 value="$FM{'name'}"></td>
  </tr>
  <tr>
    <td><font face="Verdana,Geneva" size="2" color="#BE9000">&nbsp;Email:</b></font></td>
    <td><font face="Verdana,Geneva" size="2" color="#BE9000"><b>$x_mail</b></font></td>
    <td><input type=text name="email" size=44 maxlength=140 value="$FM{'email'}"></td>
  </tr>
  <tr>
    <td valign=top><font face="Verdana,Geneva" size="2" color="#BE9000">&nbsp;Kommentar:</b></font><br><img src="$picpath/trenner.gif" border=0 width=120 height=1></td>
    <td valign=top><font face="Verdana,Geneva" size="2" color="#BE9000"><b>$x_text</b></font></td>
    <td><textarea name="com" rows=10 cols=33 wrap=virtual>$FM{'com'}</textarea><br></td>
  </tr>
  <tr>
    <td><img src="$picpath/trenner.gif" border=0 width=120 height=1></td>
    <td>&nbsp;</td>
  </tr>
  </table>
  <table border=0 cellspacing=3>
  <tr>
    <td><img src="$picpath/trenner.gif" border=0 width=120 height=1></td>
    <td>&nbsp;</td>
    <td><img src="$bookpl?func=captcha" border=0 width=100 height=25 align=left>&nbsp;Code eingeben:</td>
    <td><input type=text name="capback" size=10 maxlength=10 value="$FM{'capback'}"></td>
  </tr>
  </table>
  <table border=0 cellspacing=3>
  <tr>
    <td><img src="$picpath/trenner.gif" border=0 width=120 height=1></td>
    <td>&nbsp;</td>
    <td><br><br><input type=submit value="Ins Gästebuch eintragen ..."></td>
  </tr>
  </table>
  </form>~;

  print $query->header('text/html');
  print &parse_tmpl($out,$GUESTAMOUNT);
}

sub read_data {
  my @guest;
  my $guests=0;

  open (DAT , "< $bookpath/$bookdat") || die "Kann die Datei -$bookpath/$bookdat- nicht öffnen: $! ";
  while ( my @data=split(/\|/,<DAT>) ) {
    push ( @guest , [@data] );
  }
  close(DAT);

  @guest  = reverse @guest;
  $guests = $#guest+1;

  return($guests,\@guest);
}

sub parse_tmpl {
  my ($in,$dd)=@_;
  my ($ix2,$ix3);
  my $nocache=time;

  open (HTML , "< $bookpath/$htmmain") || die "Kann die Datei -$bookpath/$htmmain- nicht öffnen : $! ";
  my @tmpl=<HTML>;
  close(HTML);
  my $tmpl = join('',@tmpl);
  my $ddout=qq~
  <select name="links" size=1 OnChange="jump(this.options[this.selectedIndex].value)">
  <option value="$wwwadr?func=show&action=0&nocache=$nocache">Eintrag ...</option>~;

  for (my $ix=1 ; $ix <= $dd ; $ix+=$eintraege) {
    $ix2+=$eintraege;
    $ix3=$ix-1;
    $ix2=$dd if ($ix2 > $dd);
    $ddout .= qq(<option value="$wwwadr?func=show&action=$ix3&nocache=$nocache">$ix - $ix2</option>\n);
  }

  $tmpl =~ s/\[PART:main\]/$in/;
  $tmpl =~ s/\[PART:ddlist\]/$ddout<\/select>/;
  $tmpl =~ s/\[PART:title\]/$title/g;
  $tmpl =~ s/\[PART:imagedir\]/$picpath/g;

  return($tmpl);
}

sub parse_para {
  my %PARA ;

  foreach ( split(/\&/ , $ENV{'QUERY_STRING'}) ) {
    my ($feldname,$wert) = split(/=/);
    $feldname =~ s/\W//g;

    $PARA{$feldname} =  $wert;
    $PARA{$feldname} =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    $PARA{$feldname} =~ tr/\+/ /;
    $PARA{$feldname} =~ s/\W/ /g;
  }
  return(%PARA);
}

sub parse_form {
  my %FM;

  foreach my $fname ( $query->param  ) {
    $FM{$fname} =  $query->param($fname);
    $FM{$fname} =~ s/<([^>]|\n)*>/ /g;
    $FM{$fname} =~ s/\|/\//g;
    $FM{$fname} =~ s/\cM\n//g;
    $FM{$fname} =~ s/\n\cM//g;
    $FM{$fname} =~ s/\cM//g;
    $FM{$fname} =~ s/\s+/ /g;
    $FM{$fname} =~ s/^\s+//g;
    $FM{$fname} =~ s/\s+$//g;
  }
  return(%FM) ;
}

sub get_captcha   {
  my $captchaCode = "";

  opendir( DIR, "$captchadir");
  my @allfiles = readdir( DIR);
  closedir( DIR);
  shift( @allfiles);

  my $img = int rand( scalar @allfiles);
  unless( -e "$captchadir/$allfiles[$img]") {
    $img = 0;
  }

  $captchaCode = $allfiles[$img];
  $captchaCode =~ s/\..*//gi;

  &set_session_var("captchaCode", $captchaCode);

  print "Content-type: image/gif\n";
  print "\n";
  open( IMAGE, "$captchadir/$allfiles[$img]");
  while( <IMAGE>)   {
    print $_;
  }
  close(IMAGE);
}

sub set_session_var {
  my ($captchaTxt, $captchaCode) = @_;

  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time+(3600*$zeitstd));
#  my $datum = sprintf "%02d.%02d.%04d - %02d:%02d" , $mday , $mon+=1 ,$year+=1900 , $hour , $min;
  my $datum = sprintf "%02d.%02d.%04d" , $mday , $mon+=1 ,$year+=1900;

  open (DATNEW , ">> $caplog/caplog.dat") || die "Kann die Datei -$caplog/caplog.dat- nicht öffnen: $! ";
  flock(DATNEW,2) if ($lock==1);
  print DATNEW time."\|$captchaCode\|$datum\|$ENV{'REMOTE_ADDR'}\|\n";
  close (DATNEW);
}

sub check_captcha {
  my $vglStr = shift;
  my $errCode = 'ERROR';

  open(LOGFILE, "< $caplog/caplog.dat") || die "Datei konnte nicht geöffnet werden: $!\n";
  my @logfile = <LOGFILE>;
  close(LOGFILE);

  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time+(3600*$zeitstd));
  my $datum = sprintf "%02d.%02d.%04d" , $mday , $mon+=1 ,$year+=1900;

  for(my $i=0;$i<scalar @logfile;$i++) {
    my @logdat = split(/\|/, $logfile[$i]);

    if($logdat[1] eq $vglStr && $logdat[2] eq $datum && $logdat[3] eq $ENV{'REMOTE_ADDR'}) {
      $errCode = '';
      last;
    }
  }
  return $errCode;
}