#!/usr/bin/perl
# $
# $ (Guestbook version 4.7)
# $
# $ Thank you for using my guestbook script, this has been popular with the web community
# $ and I have noticed many people using it on the internet, especially 2 sites that I
# $ know of that have been offering use of it for free. This means a lot to me because
# $ they have chosen it over the many other guestbook scripts out there.
# $
# $ This code is distributed in the hope that is will be useful but WITHOUT ANY
# $ WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY DISCLAMED. This includes
# $ but isn't limited to warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# $ PURPOSE. The RESELLING of this code is STRICTLY PROHIBITED.
# $
# $ $Revision: 4.7
# $ $Author: Paul Williams
# $ $Email: paul@rainbow.nwnet.co.uk
# $ $URL: http://www.cgiuk.com/
# $ $Created: 05/07/1996 17:16
# $ $Last Modified: 07/01/2000 21:37
# $
# $ Copyright 1996, 1997, 1998, 1999, 2000 Cougasoft. All rights reserved.
# $
# $ Deutsche Bearbeitung von Carsten Schubert (Webmasterwelt: http://www.wmwelt.de)
# $ Email: wmwelt@gmx.net
# $ Das Copyright des Autors bleibt natürlich trotz der deutschsprachigen Lokalisation bestehen
# $ Copyright 1999, 2000 Webmasterwelt
#
# $--------------------------------------------------------------------------------------------
#
# M A I N P R O G R A M
#
# $--------------------------------------------------------------------------------------------
#
$VERSION = sprintf("%d.%02d", q$Revision: 4.72 $ =~ /(\d+)\.(\d+)/);
unless ( (my $pref = &preferences("data/igb-pref.pref", 34) ) == 1
|| (my $pref2 = &preferences("igb-pref.pref", 34) ) == 1)
{
print "Content-type: text/plain\n\n";
print "Error initiating preference file(s);\n\n";
print "$pref\n$pref2\n\nScript currently residing in:" . (`pwd`);
exit;
}
my (%INPUT, %PREF, %ERR, $FLAGPOST, $FLAGFORMPRINT, $cgiopt, $cgicount, $cgierr, $comments);
&ReadInput();
#
# $--------------------------------------------------------------------------------------------
#
# A C T I O N = S I G N G U E S T B O O K
#
# $--------------------------------------------------------------------------------------------
#
sub signguestbook
{
my $i = 0;
$comments = $INPUT{'COMMENTS'};
$INPUT{'COMMENTS'} =~ s/\cM//g;
$INPUT{'COMMENTS'} =~ s/( |\t)+/ /g;
$INPUT{'COMMENTS'} =~ s/\n+/
/g;
# $ Open the file which containts the words we want to disallow, you must
# $ edit this file by hand, at the moment I'm not allowing it to be edited by
# $ the administration but it might be a feature in a newer version.
if ($PREF{'DISALLOW'}) {
&openf("DISALLOW", $PREF{'DISALLOWFILE'});
while () {
chop;
return $ERR{general} = "Ihr Eintrag enthält ein verbotenes Wort [$_] bitte ändern." if ($INPUT{'COMMENTS'} =~ /$_/i);
}
close(DISALLOW);
}
my (@longwords) = split(/\s+/, $INPUT{'COMMENTS'});
$INPUT{'COMMENTS'} = "";
foreach (@longwords) {
$INPUT{'COMMENTS'} .= "$_ " unless ($PREF{'CHECKBIGWORD'} && length > 30);
$i++;
}
return $ERR{general} = "Bitte benutzen Sie mindestens $PREF{'MAXWORDS'} Wörter, bisher benutzt $i" if ($PREF{'MAXWORDS'} && $i >= $PREF{'MAXWORDS'});
&write();
&sendmail();
&top_html("Erfolg !", 2);
&FormPrint("CELLSPACING=0 CELLPADDING=4 BGCOLOR=\"$PREF{TBCOLOR}\" WIDTH=70% BORDER=0", 25, undef, 'YES',
HEADER, "Submitted Variables", "\n",
STRING, "Name", &Ternary($INPUT{NAME}), "\n",
STRING, "Email", &Ternary($INPUT{EMAIL}), "\n",
STRING, "Stadt", &Ternary($INPUT{CITY}), "\n",
STRING, "Land", &Ternary($INPUT{COUNTRY}), "\n",
STRING, ($INPUT{LINK}?"Homepage":undef), "$INPUT{LINK}", "\n",
STRING, "Komentar", &Ternary($INPUT{COMMENTS}), "\n"
);
print "
Bitte hier klicken , wenn Sie Ihren Eintrag sehen möchten." if !$INPUT{'NOPOST'};
print "
Danke für Ihren Eintrag, h i e r gehts zurück zu meiner Seite! " if $INPUT{'NOPOST'};
&bottom(1);
}
if ($INPUT{'&q'} eq "sign")
{
my $SVCOMMENT = $INPUT{COMMENTS};
# Check to see if there are any errors, if there are not then this person
# can be added to the database. If you look below there should be exactly
# five fields submitted with no errors.
if ($FLAGPOST and $cgierr == 0 and $cgicount >= 6
and $ENV{HTTP_REFERER} =~ m,$ENV{SCRIPT_NAME},i)
{
&signguestbook();
}
$ERR{general} = "Bitte schauen sie unten für mehr Details über den Fehler." if ($FLAGPOST and !$ERR{general});
&top_html("Sign in...", 2);
FormPrint("CELLSPACING=0 CELLPADDING=4", 25, "q=sign", 'yes',
HEADER, "SIGN GUESTBOOK", "\n",
TEXT, "Name", "_rs[h]_NAME", &Ternary($INPUT{NAME}), 40, 100, "\n",
TEXT, "Email Adresse", "_re_EMAIL", &Ternary($INPUT{EMAIL}), 40, 255, "\n",
TEXT, "Stadt", "_s[h]_CITY", &Ternary($INPUT{CITY}), 40, 100, "\n",
TEXT, "Land", "_s[h]_COUNTRY", &Ternary($INPUT{COUNTRY}), 40, 100, "\n",
TEXT, "Homepage", "_u_LINK", &Ternary($INPUT{LINK}), 40, 100, "\n",
TEXTAREA, "Komentar", "_r".($PREF{HTML}=='0'?undef:'s[h]')."l[10][2500]_COMMENTS", &Ternary($SVCOMMENT), 50, 7, "\n",
CHECKBOX, "Als Mitteilung senden", "NOPOST", "1", $INPUT{NOPOST}, "Wenn markiert, Eintrag erscheint nicht im Gästebuch, sondern wird per Mail gesendet.", "\n"
);
&bottom(1);
}
#
# $--------------------------------------------------------------------------------------------
#
# A C T I O N = R A N D O M L I N K
#
# $--------------------------------------------------------------------------------------------
#
elsif ($INPUT{'&q'} eq 'random')
{
&openf("DATA", "$PREF{'DATA'}");
my @data = ; close DATA;
srand(time ^ $$);
for (my $n = 0; $n < 3; $n++)
{
my $l = $data[rand($#data)];
my ($email, $name, $city, $state, $comment, $link, $date, $country) = split('\|\|', $l);
if ($link =~ m`^http://`) {
print "Location: $link\n\n";
exit 0;
}
}
print "Location: http://www.rostock-elektronik.de/\n\n";
}
#
# $--------------------------------------------------------------------------------------------
#
# A C T I O N = E L S E
#
# $--------------------------------------------------------------------------------------------
#
else
{
my ($i, @lines);
$INPUT{'&trail'} = $PREF{PERPAGE} unless $INPUT{'&trail'};
&openf("DISPLAY", "$PREF{'DATA'}");
if ($PREF{'DISPLAY'} == 2) { @lines = reverse(); }
else { @lines = ; }
close(DISPLAY);
&top_html("Willkommen !", 1);
print "\n";
foreach (@lines)
{
next if ($i++ < $INPUT{'&trail'} - $PREF{'PERPAGE'});
my ($email, $name, $city, $state, $comment, $link, $date, $country) = split('\|\|');
print "\n| ";
print " | \n
\n\n";
print "\n";
print "$name - $date \n";
print "$city " if $city;
print "[$country]" if $country;
print " " unless !$state && !$city;
print "$comment \n\n";
print "$link\n" if $link;
print "";
print " | \n
\n\n";
last if ($i == $INPUT{'&trail'});
}
print "\n| ";
print " | \n
\n\n";
print "
\n";
&multipages($#lines + 1,$i,$INPUT{'&trail'},$PREF{PERPAGE},undef) if ($i == $INPUT{'&trail'} or $INPUT{'&trail'} != $PREF{PERPAGE});
print "
" if (! ($i == $INPUT{'&trail'} or $INPUT{'&trail'} != $PREF{PERPAGE}) );
# $ Please don't change this and claim you wrote the script, I have seen it
# $ done on quite a few websites, its a little dis-heartening, thank you :)
print "Script written by Paul Williams " .
"CougaSoft & " ."WmWelt
";
&bottom(1);
}
#
# $--------------------------------------------------------------------------------------------
#
# S U B R O U T I N E S
#
# $--------------------------------------------------------------------------------------------
#
sub top_html
{
print "Content-type: text/html\n\n" .
# $ Please don't change this, people seem to like to alter the written by which is
# $ a little dis-heartening, especially as its hidden inside the html output. The
# $ version number is also embedded in the script which helps me if ever you have
# $ trouble with it.
"\n" .
"\n" .
"\n" .
" $PREF{'GBNAME'} Guestbook - $_[0]\n" .
"\n" .
"\n\n";
print "
\n\n" if $PREF{GIF};
print "[Eintragen] - [H o m e] - " .
"[Zufallslink]
" if $_[1] == 1;
print "[Einträge lesen] - [H o m e] - " .
"[Zufallslink]
" if $_[1] == 2;
}
#
# $--------------------------------------------------------------------------------------------
#
# S U B - W R I T E G U E S T B O O K
#
# $--------------------------------------------------------------------------------------------
#
sub write
{
# $ Open the data file and read through it until we reach the end, the way we
# $ work out if the post has already been added is if the comments match. This
# $ is the only way to really do it because we can't match other variables as
# $ people may post again with some more compliments ;)
&openf("DATABASE", "+>>$PREF{'DATA'}");
# $ Get data but before we wipe it, make sure its not been added.
seek DATABASE, 0, 0; my @results = ;
foreach (@results)
{
my ($email, $name, $city, $state, $comment, $link, $date, $country) = split('\|\|');
close(DATABASE), ¬ify("500 Internal Server Error", "Ihr Eintrag ist bereits aufgenommen.
Bitte " .
"hier klicken um ihn zu lesen.", 0) if ($comment eq $INPUT{'COMMENTS'});
}
# If we have got this far then this is a new comment, as this is the case we
# can now wipe the file clean and append the results (in chronological order).
if (!$INPUT{'NOPOST'})
{
seek DATABASE, 0, 0; truncate DATABASE, 0;
my $date = &date(); my $init = 0;
print DATABASE "$INPUT{'EMAIL'}||$INPUT{NAME}||$INPUT{'CITY'}||" .
"||$INPUT{'COMMENTS'}||$INPUT{'LINK'}||$date||$INPUT{'COUNTRY'}||\n";
while ( --$PREF{'MAXIMUM'} ) {
print DATABASE "$results[$init]";
$init++;
}
}
close DATABASE;
}
#
# $--------------------------------------------------------------------------------------------
#
# S U B - T E R N A R Y
#
# $--------------------------------------------------------------------------------------------
#
sub Ternary
{
my $ternval = shift;
$ternval =~ s,",",g;
return $ternval ? $ternval : undef;
}
#
# $--------------------------------------------------------------------------------------------
#
# S U B - R E A D - I N P U T
#
# $--------------------------------------------------------------------------------------------
#
sub ReadInput
{
my $choice = shift;
if ($ENV{'QUERY_STRING'})
{
my (@pairs, $pair, $name, $value);
@pairs = split($choice?'\&':'\+', $ENV{'QUERY_STRING'});
foreach $pair (@pairs)
{
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$INPUT{"&$name"} = $value;
}
}
my (@pairs, $input, $pair, $name, $value, $opt);
if ($ENV{'CONTENT_LENGTH'})
{
read(STDIN, $input, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $input);
foreach $pair (@pairs)
{
($name, $value) = split(/=/, $pair);
$name =~ tr/+/ /;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/^\s*//; # Don't allow people to just use a space by
$value =~ s/\s*$//; # chopping all preceding and trailing spaces.
# Check the $name key above for a little more information.
if ($name =~ s/^_(.*?)_([A-Z\- ]+)$/$2/)
{
$opt = $1;
# $ Must do the substitution option now because it contains some
# $ flags which the others may need to work with (eg 'u').
if ($opt =~ /s\[([shutle]+)\]/)
{
$_ = $1;
if ($value)
{
$value =~ s/<([^>]|\n)*>//g if /h/;
$value =~ s/\s+/ /g if /s/;
$value =~ s/'/\\'/g if /e/; # Escape
$value =~ s/\b(\w){1}(\w+)\b/(uc $1) . (lc $2)/ge if /t/;
$value = uc $value if /u/;
$value = lc $value if /l/;
}
# Remove all the sub flags from the option.
$opt =~ s/s\[$_\]//;
}
# $ B = banned/disallowed characters. $opt comes in the form
# $ of a regular expression so make sure its right ;)
if ($opt =~ /b\[(.*?)\]/)
{
my $regexp = $1;
$ERR{"$name"} = "Character" . (length $regexp == 1?"":"s") . " [$regexp] " .
(length $regexp == 1?"is":"are") . " not allowed inside this field.", $cgierr++ if $value && $value =~ m#[$regexp]#;
# Remove regular expression from the option.
$opt =~ s/b\[$regexp\]//;
}
if ($opt =~ /r/ && !$value)
{ $ERR{"$name"} = "Fehlende Angabe", $cgierr++; }
elsif ($opt =~ /d/ && $value && ($value !~ /^[0-9]+$/))
{ $ERR{"$name"} = "Das Feld $name kann nur Zahlen enthalten.", $cgierr++; }
elsif ($opt =~ /h/ && $value && ($value !~ /^\#[0-9a-zA-Z]+$/ || length($value) != 7))
{ $ERR{"$name"} = "Es gibt ein Syntax Problem mit $name, bitte im Hex-Format [#FFDCED] schreiben", $cgierr++; }
elsif ($opt =~ /e/ && $value && &mailcheck($value) == -1)
{ $ERR{"$name"} = "Incorrect email syntax, please write like 'yourname\@yourhost.com'", $cgierr++; }
elsif ($opt =~ /u/ && $value && $value !~ m,^http://([^/:]+)(?::(\d+))?(/\S*)?$,)
{ $ERR{"$name"} = "$name does not have the correct URL syntax.", $cgierr++; }
elsif ($opt =~ /i/ && $value && $value !~ /(\.gif|\.jpeg|\.jpg)$/i)
{ $ERR{"$name"} = "$name has incorrect IMAGE syntax, please use a .GIF or .JPG graphic", $cgierr++; }
elsif ($opt =~ /t/ && !-e $value)
{ $ERR{"$name"} = "$name ($value) does not exist on the server", $cgierr++; }
elsif ($opt =~ /w/ && $value && $value =~ /\s/)
{ $ERR{"$name"} = "Variable $name can not contain any spaces.", $cgierr++; }
elsif ($opt =~ /l\[([\d]+)\]\[([\d]+)\]/ && $value)
{
$cgierr++, $ERR{"$name"} = "Minimum length for $name is $1, you've only used " . length($value) . " characters" if $1 && length($value) < $1;
$cgierr++, $ERR{"$name"} = "Maximum length for $name is $2, you've used " . length($value) . " characters" if $2 && length($value) > $2;
}
# $ Push all the values of $name to an array of the same name,
# $ not very pretty but at least it does the trick.
push @$name, $value if $opt =~ /p/;
$cgiopt++;
}
$INPUT{$name} = $value, $cgicount++;
}
$FLAGPOST = 1;
}
# Couple of global variables that I call here to save time.
$INPUT{'time'} = time;
1;
# $ Read Input ()
}
#
# $--------------------------------------------------------------------------------------------
#
# S U B - F O R M P R I N T
#
# $--------------------------------------------------------------------------------------------
#
sub FormPrint
{
my ($tablepref, $tdwidth, $action, $finishform, @type) = @_;
my ($inputname, $value, $tmp, $errbr);
$PREF{'ERR'} = "RED" unless $PREF{'ERR'};
# $ FormPrint can not handle every event I would like it too (I may add it
# $ in the future but I am trying to keep the code small) so I have the
# $ option to pause the printing
unless ($FLAGFORMPRINT)
{
$action = "?" . $action if $action;
print qq!\n\n