#!/usr/bin/perl print "Content-Type: text/html\n"; print "\n"; use CGI qw/:all/; use CGI::Carp(fatalsToBrowser); use Fcntl; #Web Forums #A Perl script to create an online bulletin/discussion board. #Copyright 2000 NPSIS #http://www.npsis.com #Last Modified August 20, 2000 #This is a free script. You may edit and alter it for personal #use as you see fit. You may not sell it or otherwise claim it #as your own, unless you have absolutely no morals. #See the enclosed readme file for complete instructions for #setting up the BBS. #####User Edits Here######################### $Username = 'motorowa'; my $HOME = 'http://www.motorowa.3.pl/'; my $EMAIL = 'serwis@3.pl'; my $YOURNAME = 'jaca'; my $BBS_TITLE = 'FORUM DYSKUSYJNE'; #set this to 1 to quote message when replying #set to 0 to not quote messages when replying my $quote = 1; my $BG = '#f6f6ed'; #background color my $TX = '#000000'; #text color my $LL = '#00008b'; #visited link color my $VL = '#00008b'; #link color my $BGIMG = ''; #background image url ############################################### $Loginfirstletter = substr($Username, 0, 1); #my $BBS_DIR = "/usr/home/users/$Loginfirstletter/$Username/public_html/bbs/"; my $BBS_DIR = "/home/$Username/www/bbs/"; #the path to a file containing directions, etc. that will be printed on forum list page #my $BBS_INFO = "/usr/home/users/$Loginfirstletter/$Username/public_html/bbs/info.txt"; #include trailing slash my $BBS_INFO = "/home/$Username/www/bbs/info.txt"; #include trailing slash my $BBJ_HEADER = "/home/motorowa/www/"; #my $STYLE=''; $ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin'; my $VERSION = '2.1'; my $script = url(); #opendir(DIR, $BBJ_HEADER) or die "Can't opendir $BBJ_HEADER: $!"; system "../concat_head.cgi"; system "../concat_mid_head.cgi"; print '  Forum Dyskusyjne
'; #read the whole file in undef $/; if (!param()) { my ($forum,%count,@list,@rows); #chdir($BBS_DIR) || die "Can't chdir to $BBS_DIR: $!"; opendir(DIR, $BBS_DIR) or die "Can't opendir $BBS_DIR: $!"; my @forums = grep { !/^\./ } readdir(DIR); closedir(DIR); foreach $forum (@forums) { my $path = $BBS_DIR . $forum; if (-d $path) { opendir(DIR, $path ) || die "Can't opendir $path: $!"; $count{$forum} = (@list = grep { !/^\./ } readdir(DIR)); closedir(DIR); } } my $counter = 0; my $odd_open = ""; my $odd_close = ''; my $even_open = ""; my $even_close = ''; foreach $forum ( sort keys %count) { next if $forum =~ /_archive$/; my $link = "$script?forum=$forum&task=list"; my $label = (($counter = 1- $counter) ? $odd_open : $even_open) . a({-href=>$link},get_label($forum) . " ($count{$forum} wiadomoś" . ($count{$forum} != 1 ? "ci)" : "ć)")) . ($counter ? $odd_close : $even_close); push @rows,$label; } print '


Jeśli chcesz się wypowiedzieć, podyskutować, podzielić uwagami z innym mieszkańcami naszego osiedla, lub też przeczytać co piszą inni internauci - to ta strona jest miejscem właśnie dla Ciebie. Zapraszamy na Forum Dyskutyjne - osiedlowy Hyde Park.



'; print start_html(-bgcolor=>$BG,-text=>$TX,-link=>$LL,-vlink=>$VL, -background=>$BGIMG,-title=>"$BBS_TITLE"), h1({align=>'center'},"$BBS_TITLE"); if (!@rows) { print center('Żadne forum nie zostało założone.'); } else { print center( 'Wybierz forum z listy poniżej.',p, table(@rows), ); } print hr; if ($BBS_INFO) { open(INFO, "$BBS_INFO") || die "Can't open $BBS_INFO: $!"; while () { print; } close(INFO); } print hr, font({-size=>'-1'},a({-href=>$HOME,-target=>'_blank'}, 'Forum Dyskusyjne'),br,'Wersja ',$VERSION,br,'by ', a({-href=>"mailto: $EMAIL"}, "$YOURNAME")),, end_html; show_foot(); exit(0); } my $forum = param('forum'); if ($forum =~ /(^[a-zA-Z0-9_]+$)/) { $forum = $1; } else { bad_input(); } my $forum_label = get_label($forum); my $task = param('task'); show_post_list() if $task eq 'list'; show_msg() if $task eq 'show_msg'; new_thread_form() if $task eq 'new_thread_form'; new_post() if $task eq 'new_post'; reply_form() if $task eq 'reply_form'; post_reply() if $task eq 'post_reply'; mark_read() if $task eq 'mark_read'; show_post_list() if $task eq 'list_archive'; ####################################################### sub show_foot { system "../concat_foot.cgi"; opendir(DIR, $BBJ_HEADER) or die "Can't opendir $BBJ_HEADER: $!"; } sub mark_read { my $last_visit = time; my $cookie = cookie(-name=>$forum, -value=>$last_visit, -expires=>'+30d',); print header(-cookie=>$cookie); show_post_list('marked'); } sub post_reply { my $reply_to = param('reply_to'); if ($reply_to =~ /(^\d\d\d\d(\.\d\d\d\d)*$)/) { $reply_to = $1; } else { bad_input(); } my $email = param('email'); validate_email($email) if $email; my $name = clean(param('name')); my $subject = clean(param('subject')); my $message = param('message'); check_required($name,$subject,$message); my $time_stamp = time; my $date = get_date($time_stamp); my $forum_dir = $BBS_DIR . $forum; #chdir($forum_dir) || die "Can't chdir to $forum_dir: $!"; opendir(DIR,$forum_dir) || die "Can't opendir $forum_dir: $!"; #see if there any more replies to this post my @posts = grep { /^$reply_to\.\d\d\d\d$/o } readdir(DIR); closedir(DIR); my ($new_post,$last_post,$start,$end); if (!@posts) { #none yet $new_post = $reply_to . '.' .'0001'; } else { $last_post = $posts[$#posts]; $last_post =~ /^(.+)(\d\d\d\d)$/; $start = $1; $end = $2; $end = sprintf("%04d",++$end); $new_post = $start . $end; } chdir($forum_dir) || die "Can't chdir to $forum_dir: $!"; until (sysopen(FILE,$new_post,O_WRONLY|O_EXCL|O_CREAT,0666)){ $new_post =~ /(.+)(\d\d\d\d)$/; $start = $1; $end = $2; $end = sprintf("%04d",++$end); $new_post = $start . $end; } store_and_confirm(*FILE,$subject,$name,$email,$message); show_foot(); exit(0); } sub reply_form { my $msg = param('msg'); if ($msg =~ /(^\d\d\d\d(\.\d\d\d\d)*$)/) { $msg = $1; } else { bad_input(); } my $forum_dir = $BBS_DIR . $forum; chdir($forum_dir); open (POST, "$msg") || die "$!\n"; my $content = ; close(POST); my ($subject,$author,$email,$date,$message) = split(/\n/,$content,5); $date = get_date($date); my $attribution = ''; if ($quote) { $attribution = "W odpowiedzi na \"$subject\", wysłanej przez $author w dniu $date:\n"; $message =~ s/^(.{0,1})/>$1/mg; $message = $attribution . $message . "\n"; } else { $message = ''; } $subject = 'Re: ' . $subject; print start_html(-bgcolor=>$BG,-text=>$TX,-link=>$LL,-vlink=>$VL, -background=>$BGIMG,-title=>"$forum_label"), h1({align=>'center'},"$forum_label"), h2({align=>'center'},'OdpowiedŸ'), '
', '', '', '
', a({-href=>"$script?task=list&forum=$forum"},b('Message List')), '', a({-href=>$script},b('Forum List')), '
', hr, 'Wpisz poniżej swoja odpowiedz. Możesz edytować zawartość pola temat i wiadomość.',p, b("W odpowiedzi na \"$subject\", wysłanej przez $author w dniu $date:"),p, font({-color=>'red'},'* '),b('Pola Wymagane'),p, start_form(-action=>$script), hidden(-name=>'forum',-value=>$forum,-override=>1), hidden(-name=>'task',-value=>'post_reply',-override=>1), hidden(-name=>'reply_to',-value=>$msg,-override=>1), table( Tr({-align=>'LEFT'}, th({-align=>'right'},font({-color=>'red'},'*'),'Twoje imię: '), td({-align=>'left'},textfield(-name=>'name',-size=>30)) ), Tr( th({-align=>'right'},'Email Address: '), td({-align=>'left'},textfield(-name=>'Twój email:',-size=>30)) ), Tr( th({-align=>'right'},font({-color=>'red'},'*'),'Temat: '), td({-align=>'left'},textfield(-name=>'subject',-value=>$subject,-size=>30)) ), Tr( th({-align=>'right',-valign=>'top'},font({-color=>'red'},'*'),'Wiadomość: '), td(textarea(-name=>'message',-rows=>10, -value=>$message, -cols=>60,-wrap=>'soft')), ), Tr({-align=>'center'}, td({-colspan=>2},submit(-name=>'Wyślij odpowiedŸ'),reset(-name=>'Wyczyść')) ), ), end_form,hr, font({-size=>'-1'},a({-href=>$HOME,-target=>'_blank'}, 'Web Forums'),br,'Version ',$VERSION,br,'by ', a({-href=>"mailto: $EMAIL"}, "$YOURNAME")),, end_html; show_foot(); exit(0); } sub new_thread_form { print start_html(-bgcolor=>$BG,-text=>$TX,-link=>$LL,-vlink=>$VL, -background=>$BGIMG,-title=>"$forum_label"), h1({align=>'center'},"$forum_label"), h2({align=>'center'},'Nowa Wiadomość'), '
', '', '', '
', a({-href=>"$script?task=list&forum=$forum"},b('Lista Wiadomości')), '', a({-href=>$script},b('Lista Grup Dyskusyjnych')), '
',hr, font({-color=>'red'},'*'),b('Pola Wymagane'),p, start_form(-action=>$script), hidden(-name=>'forum',-value=>$forum,-override=>1), hidden(-name=>'task',-value=>'new_post',-override=>1), table( Tr({-align=>'LEFT'}, th({-align=>'right'},font({-color=>'red'},'*'),'Twoje imię: '), td({-align=>'left'},textfield(-name=>'name',-size=>30)) ), Tr( th({-align=>'right'},'Twój email: '), td({-align=>'left'},textfield(-name=>'email',-size=>30)) ), Tr( th({-align=>'right'},font({-color=>'red'},'*'),'Temat: '), td({-align=>'left'},textfield(-name=>'subject',-size=>30)) ), Tr( th({-align=>'right',-valign=>'top'},font({-color=>'red'},'*'),'Wiadomość: '), td(textarea(-name=>'message',-rows=>10, -cols=>60,-wrap=>'soft')), ), Tr({-align=>'center'}, td({-colspan=>2},submit(-name=>'Wyślij'),reset(-name=>'Wyczyść')) ), ), end_form,hr, font({-size=>'-1'},a({-href=>$HOME,-target=>'_blank'}, 'Web Forums'),br,'Version ',$VERSION,br,'by ', a({-href=>"mailto: $EMAIL"}, "$YOURNAME")),, end_html; show_foot(); exit(0); } sub new_post { my $email = param('email'); validate_email($email) if $email; my $name = clean(param('name')); my $subject = clean(param('subject')); my $message = param('message'); check_required($name,$subject,$message); #get a list of top level posts my $forum_dir = $BBS_DIR . $forum; #chdir($forum_dir) || die "Can't cd to $forum_dir $!\n"; opendir(DIR, $forum_dir); my @posts = grep { /^\d\d\d\d$/ } readdir(DIR); closedir(DIR); my $last_post = $posts[$#posts]; my $new_post; if (!$last_post) { $new_post = '0001'; } else { $new_post = sprintf("%04d",$last_post++); } chdir($forum_dir) || die "Can't cd to $forum_dir $!\n"; until (sysopen(FILE,$new_post,O_WRONLY|O_EXCL|O_CREAT,0666)){ $new_post++; } store_and_confirm(*FILE,$subject,$name,$email,$message); show_foot(); exit(0); } #this sub shows a message sub show_msg { my $archive_flag = 0; $archive_flag = 1 if $forum =~ /_archive$/; my $return_to; if ($archive_flag) { ($return_to = $forum) =~ s/_archive$//; } my $msg = param('msg'); if ($msg =~ /(^\d\d\d\d(\.\d\d\d\d)*$)/) { $msg = $1; } else { bad_input(); } my ($post,$back,$next,$back_link,$next_link); #get a list of the posts and figure back and next buttons my @posts = get_list(); for (0..$#posts) { next unless $posts[$_] eq $msg; if ($_ != 0) {$back = $posts[$_ - 1];} $next = $posts[$_ +1]; last; } if ($back){ $back_link = "$script?forum=$forum&task=show_msg&msg=$back"; } if ($next) { $next_link = "$script?forum=$forum&task=show_msg&msg=$next"; } my $forum_dir = $BBS_DIR . $forum; chdir($forum_dir); open (POST, "$msg") || die "Can't open $msg: $!"; my $content = ; close(POST); my ($subject,$author,$email,$date,$message) = split(/\n/,$content,5); $date = get_date($date); print start_html(-bgcolor=>$BG,-text=>$TX,-link=>$LL,-vlink=>$VL, -background=>$BGIMG,-title=>$subject), h1({align=>'center'},"$forum_label"), h2({align=>'center'},"$subject"); print '
'; if (!$archive_flag) { print ''; } if ($back_link) { print ''; } if ($next_link) { print ''; } if ($archive_flag) { print ''; print ''; } else { print ''; } print ''; print '
', a({-href=>"$script?forum=$forum&task=reply_form&msg=$msg"},b('Wyślij OdpowiedŸ')), '', a({-href=>$back_link},b('Poprzednia wiadomość')), '', a({-href=>$next_link},b('Następna Wiadomość')), '', a({-href=>"$script?task=list&forum=$forum"},b('Zarchiwizowana Lista Wiadomości')), '', a({-href=>"$script?forum=$return_to&task=list"},b('Return to ', get_label($return_to))), '', a({-href=>"$script?task=list&forum=$forum"},b('Lista Wiadomości')), '', a({-href=>$script},b('Forum List')), '
',hr; print table( Tr({-align=>'left'}, th('Wysłany przez:'),td($author), ), Tr({-align=>'left'}, th('Email:'),td($email ? a({-href=>"mailto:$email"},$email) : 'Not Entered'), ), Tr({-align=>'left'}, th('Data:'),td($date), ), Tr({-align=>'left',-valign=>'top'}, th('Wiadomość:'),td(text_to_html($message)), ), ),p, hr; end_html; show_foot(); exit(0); } sub get_list { my $forum_dir = $BBS_DIR . $forum; my ($file,@posts); my $max = 0; opendir(DIR, $forum_dir) or die "Can't opendir $forum_dir: $!"; while (defined($file = readdir(DIR))) { if ($file =~ /(^\d\d\d\d(\.\d\d\d\d)*$)/) { push @posts, $file; #keep track of how deep the threads go, so we know how many fields #to sort on my $depth = (($file =~ tr/\.//) + 1); $max = $depth if $depth > $max; } } closedir(DIR); #top level threads sorted reverse, others inorder of post my @sort_order = ('-1n',2..$max); my @sorted_posts = fieldsort ('\.', [@sort_order], @posts); return @sorted_posts; } #this sub shows the posts in a forum sub show_post_list { my $forum_dir = $BBS_DIR . $forum; chdir($forum_dir) || die "Can't chdir $forum_dir: $!"; my $marked = shift; my $last_visit = cookie($forum); my @posts = get_list(); my ($archive,$archive_path,$return_to,$archive_flag); $archive = $forum . '_archive'; $archive_path = $BBS_DIR . $archive; if ($forum =~ /_archive$/) { $archive_flag = 1; } #if we came here thru an archive request we need to fix forum name ($return_to = $forum) =~ s/_archive$//; # if we are doing this after marking message read, #the header was already printed #if (!$marked) { # print header; #} print start_html(-bgcolor=>$BG,-text=>$TX,-link=>$LL,-vlink=>$VL, -background=>$BGIMG,-title=>$forum_label), h1({align=>'center'},$forum_label), #'
', #'Select a message from the list below',p; '
'; unless ($archive_flag) { print ''; } print ''; #only show archive link if there is an archive for this forum #and we aren't already in archive view if ((-e $archive_path) && (!$archive_flag) ){ print ''; } elsif ($task eq 'list_archive') { print ''; } if ( (!$archive_flag) && (@posts) ){ print ''; } print '
', a({-href=>"$script?forum=$forum&task=new_thread_form"},b('Nowa Wiadomość')), '', a({-href=>$script},b('Lista Grup Dyskusyjnych')), '', a({-href=>"$script?forum=$archive&task=list_archive"},b('View ', get_label($archive))), '', a({-href=>"$script?forum=$return_to&task=list"},b('Return to ', get_label($return_to))), '', a({-href=>"$script?forum=$forum&task=mark_read"},b('Oznacz Wszystkie Wiadomości Jako Przeczytane')), '

'; my $item; my $depth = 0; #this is how deep our list tags are if (!@posts) { print center('Brak wiadomości w tym forum.'); } else { if ($archive_flag) { print center(b('To reply to archive messages, start a new post in the forum.')),p; } print b('Wiadomości na tym ' ,$archive_flag ? 'archive' : 'forum',':'),br; foreach $item (@posts) { my $count = (($item =~ tr/\.//) + 1); #get the reply depth count open (POST, "$item") || die "Can't open $item: $!"; my $content = ; close(POST); my ($subject,$author,$email,$post_time) = split(/\n/,$content); my $date = get_date($post_time); if ($depth < $count){ #need to go one deeper print '
    '; $depth++; } if ($depth > $count) { #need to back up one level my $diff = $depth - $count; for (1..$diff) { print '
'; $depth--; } } my $link = "$script?forum=$forum&task=show_msg&msg=$item"; if ($email) { print '
  • ',a({-href=>$link},$subject), ' wysłał(a) ', a({-href=>"mailto:$email"}, $author), " ($date)"; if (($last_visit) && ($post_time > $last_visit)) { print ' NEW' unless $marked; } } else { print '
  • ',a({-href=>$link},$subject), ' wysłał(a) ', $author, " ($date)"; if (($last_visit) && ($post_time > $last_visit)) { print ' NEW' unless $marked; } } print "\n"; } for (1..$depth) { #clear them all out print ''; } } print hr, font({-size=>'-1'},a({-href=>$HOME,-target=>'_blank'}, 'Web Forums'),br,'Version ',$VERSION,br,'by ', a({-href=>"mailto: $EMAIL"}, "$YOURNAME")),, end_html; show_foot(); exit(0); } #end show_post_list sub get_label { my $label = $_[0]; $label =~ s/_/\x20/g; #switch underlines for spaces $label =~ s/\b(\w)/\U$1/g; #capitalize first letter of each word return $label; } sub validate_email { my $email = shift; #so far this check is pretty good if ($email !~ /^[\w\-\.\!\%\+]+\@[a-zA-z0-9\-]+(\.[a-zA-Z0-9\-]+)*\.[a-zA-Z0-9\-]+$/){ print start_html(-bgcolor=>$BG,-text=>$TX,-link=>$LL,-vlink=>$VL, -background=>$BGIMG,-title=>"Form Error"), h2('Invalid Email Address'), 'Wprowadzony adres wydaje się nie mieć prawidłowego formatu.',p, 'Proszę poprawić formularz przed wysłaniem.',p, a({href=>'javascript:history.go(-1);'},'Spróbuj raz jeszcze.'), end_html; show_foot(); exit(0); } } sub get_date { my $time = shift; my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = localtime($time); my $month_name = ('Sty','Lut','Mar','Kwie','Maj','Cze','Lip','Sie', 'Wrz','Paz','Lis','Gru')[$mon]; $year += 1900; my $date = "$month_name $mday, $year"; return $date; } sub text_to_html { #since most messages will be read as html, convert these entities my $str = shift; $str=~s/&/&/g; $str=~s/\"/"/g; $str =~ s//>/g; $str =~ s/\n\n/

    /g; $str =~ s/\n/
    /g; return $str; } sub clean { #prevent any image tags, etc. used in subject and name fields my $str = shift; $str =~ s///g; return $str; } sub check_required(){ my ($name,$subject,$message) = @_; my @empty; if (!$name) { push @empty, 'Imię
    '; } if (!$subject) { push @empty, 'Temat
    '; } if (!$message) { push @empty, 'Wiadomość
    '; } if (@empty) { print start_html(-bgcolor=>$BG,-text=>$TX,-link=>$LL,-vlink=>$VL, -background=>$BGIMG,-title=>"Form Error"), h2('Puste Pola Formularza'), 'The following required fields were not filled in.',p, @empty,p, a({href=>'javascript:history.go(-1);'},'Spróbuj raz jeszcze.'), end_html; show_foot(); exit(0); } } sub store_and_confirm { my ($fh,$subject,$name,$email,$message) = @_; my $time_stamp = time; my $date = get_date($time_stamp); print $fh $subject . "\n"; print $fh $name . "\n"; print $fh $email . "\n"; print $fh $time_stamp . "\n"; print $fh $message . "\n"; close($fh); print start_html(-bgcolor=>$BG,-text=>$TX,-link=>$LL,-vlink=>$VL, -background=>$BGIMG,-title=>"$forum_label"), h1({align=>'center'},"$forum_label"), h2({align=>'center'},'Wiadomość została wysłana'), '

    ', '', '', '
    ', a({-href=>"$script?task=list&forum=$forum"},b('Lista Wiadomości')), '', a({-href=>"$script"},b('Lista Grup Dyskusyjnych')), '
    ', hr, 'Poniższa wiadomość została wysłana:',p, table( Tr({-align=>'left'}, th('Wysłana przez:'),td($name), ), Tr({-align=>'left'}, th('Email:'),td($email ? $email : 'Not Entered'), ), Tr({-align=>'left'}, th('Data:'),td($date), ), Tr({-align=>'left'}, th('Temat:'),td($subject), ), Tr({-align=>'left',-valign=>'top'}, th('Wiadomość:'),td(text_to_html($message)), ), ),p,hr, font({-size=>'-1'},a({-href=>$HOME,-target=>'_blank'}, 'Web Forums'),br,'Version ',$VERSION,br,'by ', a({-href=>"mailto: $EMAIL"}, "$YOURNAME")),, end_html; } sub bad_input { print start_html(-bgcolor=>$BG,-text=>$TX,-link=>$LL,-vlink=>$VL, -background=>$BGIMG,-title=>"Błšd"), h2('Złe Wieœci!'), 'Wydaje się że Twój input zawiera niedozwolone znaki.', end_html; show_foot(); exit(0); } #generic sort function by Joseph Hall, joseph@5sigma.com sub fieldsort { my ($sep, $cols); if (ref $_[0]) { $sep = '\\s+' } else { $sep = shift; } unless (ref($cols = shift) eq 'ARRAY') { die "fieldsort columns must be in anon array"; } my (@sortcode, @col); my $col = 1; for (@$cols) { my ($a, $b) = /^-/ ? qw(b a) : qw(a b); my $op = /n$/ ? '<=>' : 'cmp'; push @col, (/(\d+)/)[0] - 1; push @sortcode, "\$${a}->[$col] $op \$${b}->[$col]"; $col++; } my $sortfunc = eval "sub { " . join (" or ", @sortcode) . " } "; my $splitfunc = eval 'sub { (split /$sep/o, $_)[@col] } '; return map $_->[0], sort { $sortfunc->() } map [$_, $splitfunc->($_)], @_; }