#!/usr/bin/perl
# dcboard.cgi
#
# DCForum Version 6.25
# Sept 26, 2003
#
#    This file is part of DCForum
#
#    DCForum is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    DCForum is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with DCForum; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
#
#
#
# 	$Id: dcboard.cgi,v 1.2 2003/09/11 12:34:26 david Exp $	
#


# DCF 6.2 now automatically determines $cgidir
# NO NEED TO EDIT IF YOU ARE INSTALLING IN DEFAULT MODE
my $this = $0;
$this =~ s/\\/\//g;
$this =~ s~(.*)\/[^\/]+~$1~;
$this = "." unless ($this =~ /\//);
$cgidir = $this;

# In the event that above code doesn't work on your server
# define $cgidir here
# $cgidir = 'full directory path to /cgi-bin/dcforum';
require "$cgidir/dcforum_Ilene00.setup";
require "$cgilib/dcforumlib.pl";
require "$cgilib/date.pl";

# unbuffer output
$| = 1;

# Read-in form data...
ReadParse();

$r_in = \%in;
$r_in->{'forum'} =~ s/\W//g;


# mod.2001.01.25.01
# Jump to forum bug fix
# If az is jump, then redirect to that forum listing
if ($r_in->{'az'} eq 'jump') {
	# create forum_links
	print "Location: $r_in->{'forum'}\n\n";
	exit;
}

# mod.2001.04.01.01
# Moved all form input check to dcforumlib.pl
$r_in = check_form_input($r_in);

# if archive keyword, then the database should be arc_database
if ($r_in->{'archive'}) {
  $database = "arc_" . $database;
}

# initialize some internal variables...
# Need to change this for speed improvement
$r_setup = initialize();
require "$cgilib/global.pl";

# Get current time and date
get_date($r_in);

# Ok, if the user is not logged in, set date and time
# cookie to keep track of new message since last visit
last_visit_stamp($r_in,$r_setup);

# OK, before we do anything, let's check the user's session ID
# If it exists then read in user data
# Note: the session ID is also returned to $r_in->{'userdata'}->{'session'}
$r_in->{'userdata'} = get_session();

# If the input forum type is Private, then
# set appropriate file extension and dir
# mod.2001.06.15.01 - Restricted forum hack
if ( private($r_setup->{'forum_type'}->{ $r_in->{'forum'} }) ) {
   $maindir = $privatedir;
}

# If template files exists in $maindir, then use it instead
if ($r_in->{'forum'} and -e "$maindir/$r_in->{'forum'}/$template") {
   $templatefile = "$maindir/$r_in->{'forum'}/$template";
}

# mod.2001.08.01 - multi-icon hack
# Next readin the team members
# $r_in->{'team'} is a reference to hash
$r_in->{'team'} = get_team_members("$password_file_dir/$team_file_name");

my $forum_style = get_cookie($thread_style_cookie);

#print "$forum_style - $thread_style_cookie";
#exit;
# Determine viewmode
if ($r_in->{'archive'} eq '' and $r_in->{'viewmode'} eq '') {
   if ($flag_status{$r_setup->{'make_fully_threaded_list_default'}}) {
      $r_in->{'viewmode'} = 'threaded' unless ($forum_style);
   }
   else {
      $r_in->{'viewmode'} = 'threaded' if ($forum_style);
   }
}

# Ok, the action starts here
if ($r_in->{'az'} eq '') {   # lobby is the default page
   $r_in->{'az'} = 'lobby';
	$html_forum_links = qq~<br><table border="0" width="$r_setup->{'table_width'}" 
   cellspacing="0" cellpadding="0"><tr><td><img src="$imgurl/locked_folder.gif"><font 
   size="$r_setup->{'font_size_4'}" 
   face="$r_setup->{'font_face_4'}" color="$r_setup->{'font_color_4'}"><a 
   href="$boardurl?az=help&selected=14">Moderated forum</a><br><img 
   src="$imgurl/new_folder.gif">Forum contains topics with unread 
   messages</font></td></tr></table>~;

}
elsif	($r_in->{'az'} eq 'list') {

	$html_forum_links = forum_links($r_in,$r_setup);
   # mod.2001.07.13.01
   # Allow fully threaded listing if archive is not chosen
   $r_in->{'az'} = 'fully_threaded_list' if ($r_in->{'viewmode'} eq 'threaded');
   # If az is list without forum name, then default to lobby
   $r_in->{'az'} = 'lobby' unless ($r_in->{'forum'});

}

# Check and make sure HTTP_REFERER is ok
# for certain requests
# May need to revisit this at a later time...
# mod.2002.02.20.01 - added check_referer flag
if ($flag_status{$r_setup->{'check_referer'}} and unsafe_request($r_in)) {
   print "Location: $boardurl\n\n";
   exit;
}

# Bug fix...
# redirect anything that belongs to admin utility
# if admin_, then redirect
if ($r_in->{'az'} =~ /^admin_/) {
   print "Location: $boardurl\n\n";
   exit;
}

# OK, depending on az, do it
# But, first check and see if the forum is shutdown
if (-e "$password_file_dir/forumlock.lock") {
   print_header();
   print_header_end();
   $html_output = sub_heading("Forum is currently offline for maintenance - Please try again later",$r_setup);  
	$html_forum_links = '';
}
# DCF 6.2 Hack
elsif (-e "$userlib/$r_in->{'az'}.pl") {
   require "$userlib/$r_in->{'az'}.pl";
   my $command = '$html_output = ' 
                    . $r_in->{'az'} . '($r_in,$r_setup)';
   eval($command);
}
elsif (-e "$cgilib/$r_in->{'az'}.pl") {
   require "$cgilib/$r_in->{'az'}.pl";
   my $command = '$html_output = ' 
                    . $r_in->{'az'} . '($r_in,$r_setup)';
   eval($command);
}
else {
   print_header();
   print_header_end();
   $html_output = sub_heading("ERROR: $r_in->{'az'}.pl file can't be found!!!",$r_setup);
   $html_output .= "<b>Check and make sure $r_in->{'az'}.pl is in your Lib directory</b>";
}

if ($html_output) {

   # Comment this line if yuou don't want header
   my $heading = $r_setup->{'forum_title'};
   $html_output = sub_heading($heading,$r_setup) . $html_output;
   $html_output .= $html_forum_links;
   $html_output .= qq~
   <p>&nbsp;</p>
   <p>&nbsp;</p>
   <p>&nbsp;</p>
   <p>&nbsp;</p>
   <p>&nbsp;</p>
   <p align="center">
   <font size="1" face="$r_setup->{'font_face_5'}" color="$r_setup->{'font_color_5'}">
   $copyright</font>
   </p>
   ~;
   print_header();
   print_header_end();

   my $http_header = qq~
   <SCRIPT SRC="$mainurl/dcf.js"></script>~;

   my %namespace = (
      TITLE => $heading,
      HTMLOUTPUT => $html_output,
      HTTPHEADER => $http_header
   );

   # display output
   display_output($templatefile,\%namespace);

}

exit;



#############################################################
# function last_visit_stamp
# Keeps track of the date and time of last visit
#############################################################
sub last_visit_stamp {
   my ($r_in,$r_setup) = @_;
   
   $r_in->{$current_session_cookie} = get_cookie($current_session_cookie);
   unless ($r_in->{$current_session_cookie}) {

   	my ($mmonth,$dd,$yy) = split(/\//,$r_in->{'date'});
   	my ($hh,$minute,$second) = split(/\:/,$r_in->{'localtime'});
      my $time_stamp = compute_time($yy, $mmonth, $dd, $hh, $minute, $second);
   	$time_stamp = url_encode($time_stamp);
      $r_in->{$time_stamp_cookie} = get_cookie($last_visit_cookie);
   	unless ($r_in->{$time_stamp_cookie}) {
         $r_in->{$time_stamp_cookie} = $time_stamp;
   	}
   	else {
   		send_cookie($time_stamp_cookie,$r_in->{$time_stamp_cookie},$r_setup->{'expires'},$domain);
   	}
   	send_cookie($last_visit_cookie,$time_stamp,$r_setup->{'expires'},$domain);
   	send_cookie($current_session_cookie,$time_stamp,'','');
   }
   else {
      $r_in->{$time_stamp_cookie} = get_cookie($time_stamp_cookie);
   }

}

#======================================================================#
# get_session                                                          #
# If session cookie exists, then it returns a hash reference           #
# to the user data.                                                    #
#======================================================================#
sub get_session {
   my $r_temp = {};
   my $session = get_cookie($cookie_name);
   if ($session) {
      if (-e "$sessiondir/$session.session") {
         $r_temp = get_userdata("$sessiondir/$session.session");
         # MOD.2001.08.08.01
         # Also return session ID
         $r_temp->{'session'} = $session;
      }
      else {
         send_cookie($cookie_name,'','Thur, 31-Dec-98 12:00:00 GMT','');
         $session = '';
      }
   }
   return $r_temp;
}

###########################################################################
# function unsafe_request
# Return 1 if the request doesn't seem to check out
# All requests not in %safe_request hash must pass HTTP_REFERER test
###########################################################################

sub unsafe_request {

   my $r_in = shift;

   # Define requests that are allowed to have
   # incorrect HTTP_REFERER
   # NOTE - for those functions that use javascript popup
   # menu, HTTP_REFERER is checked in each module
   my %safe_actions = (
      'show_thread' => 1,
      'list' => 1,
      'fully_threaded_list' => 1,
      'lobby' => 1,
      'upload_file' => 1,
      'html_reference' => 1,
      'read_count' => 1,
      'choose_avatar' => 1,
      'user_rating' => 1,
      'topic_rating' => 1,
      'search' => 1,
      'icq' => 1,
      'emoticon_table' => 1
   );
   # Restrict some actions to only occur
   # from within the forums
   unless ($safe_actions{$r_in->{'az'}}) {
      unless (check_referer()) {
        return 1;
      }
      else {
        return 0;
      }
   }

   # mod.2001.07.14.01
   # Moved to function unsafe_request
   # Any action with 'admin' prefix is unsafe
   if ($r_in->{'az'} =~ /^admin/) {
      return 1;
   }

   # Next check and make sure certain requests are done thru POST Only
   
   my %post_requests = (
      'a_mesg' => 1,
      'e_mesg' => 1,
      'poll' => 1,
      'pview' => 1,
      'send_icq' => 1
   );

   if ($post_requests{$r_in->{'az'}}) {
      return 1 if (lc($ENV{'REQUEST_METHOD'}) ne 'post');   
   }

   return 0;

}


##############################################################
# Function check_referer
# Return 1 if HTTP_REFERER checks out
##############################################################
sub check_referer {

      # referer checking
      # Check it iff HTTP_REFERER is not empty
      if ($ENV{'HTTP_REFERER'} and 
         ($ENV{'HTTP_REFERER'} =~ /$cgiurl/i 
            or $ENV{'HTTP_REFERER'} =~ /$mainurl/i)) {
        return 1;
      }
      else {
         return 0;
      }
  
}
