#!/usr/local/bin/perl

############################################################################
# Title:		Communique Chat
# Version:		2.01a
# Created By:	Chris Smith (csmith@creativematrix.com)
#			Creaive Matrix, Inc. (http://www.creativematrix.com)
#
# Copyright (C) 1998  Creative Matrix, Inc.
#
# This program 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, version 2
# of the License.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
############################################################################

## Define Variables
############################################################################

## Array Preferences
@room_names			= ("Entry","Kitchen");
@room_values		= ("entry","kitchen");

## HTML Tag Preferences
$html_tag_font_begin	= "<FONT FACE=\"arial\" SIZE=-1>";
$html_tag_font_end	= "</FONT>";

## Message Preferences
$msg_bad_referrer		= "Недопустимый запрос к скрипту.";
$msg_error_file_open	= "Произошла ошибка при открытии файла комнаты чата.";
$msg_error_file_create	= "Произошла ошибка при создании файла комнаты чата.";
$msg_not_post		= "Недопустимый запрос к скрипту.";

## Path Preferences
$path_to_chat_files	= "/home/f/freyn.agava.ru/cgi/bluechat/chat";
$path_to_templet_files	= "/home/f/freyn.agava.ru/WWW/chat/chat/templets";

## System Preferences
$sys_allow_html		= "0";		# 0 = да; 1 = нет;
$sys_allow_images		= "0";		# 0 = да; 1 = нет;
$sys_allow_java		= "0";		# 0 = да; 1 = нет;
$sys_allow_javascript	= "0";		# 0 = да; 1 = нет;
$sys_create_rooms		= "0";		# 0 = да; 1 = нет;
$sys_display_ip		= "0";		# 0 = да; 1 = нет;
$sys_log_rooms		= "1";		# 0 = да; 1 = нет;
$sys_num_of_posts		= "30";		# Любое число

## URLs
$url_of_referrer		= "freyn.agava.ru/";
$url_to_images		= "http://www.freyn.agava.ru/chat/images";
$url_to_script		= "http://www.freyn.agava.ru/cgi-bin/bluechat/chat/chat.pl";

## Begin Program
############################################################################

if (($ENV{'REQUEST_METHOD'} eq "POST") && ($ENV{'HTTP_REFERER'} =~ /$url_of_referrer/))	{
	&parsePostInput();
} else {
	&printChatLogon();
}

@messages = ();

&cleanUser();
&readRoomFile();
&createDateStamp();
&cleanUserInput() unless $formdata{'user_body'} eq "";
&writeRoomFile() unless $formdata{'user_body'} eq "";
&createRooms();
&printChatPage();
&writeRoomLog() unless $formdata{'user_body'} eq "";
&exitProgram();

## Subroutines
############################################################################

sub cleanUser		{
	## Disallow JavaScript
	$formdata{'user_email'} =~ s/javascript\://ig;
	$formdata{'user_homepage'} =~ s/javascript\://ig;
	$formdata{'user_homepage'} =~ s/http\:\/\///ig;

	## Clean invalid chararcters from the room name
	$formdata{'user_room'} =~ s/\|//g;
	$formdata{'user_room'} =~ s/\\//g;
	$formdata{'user_room'} =~ s/\=//g;
	$formdata{'user_room'} =~ s/\+//g;
	$formdata{'user_room'} =~ s/\)//g;
	$formdata{'user_room'} =~ s/\(//g;
	$formdata{'user_room'} =~ s/\*//g;
	$formdata{'user_room'} =~ s/\&//g;
	$formdata{'user_room'} =~ s/\^//g;
	$formdata{'user_room'} =~ s/\%//g;
	$formdata{'user_room'} =~ s/\$//g;
	$formdata{'user_room'} =~ s/\#//g;
	$formdata{'user_room'} =~ s/\@//g;
	$formdata{'user_room'} =~ s/\!//g;
	$formdata{'user_room'} =~ s/\`//g;
	$formdata{'user_room'} =~ s/\~//g;
	$formdata{'user_room'} =~ s/\;//g;
	$formdata{'user_room'} =~ s/\://g;
	$formdata{'user_room'} =~ s/\'//g;
	$formdata{'user_room'} =~ s/\"//g;
	$formdata{'user_room'} =~ s/\[//g;
	$formdata{'user_room'} =~ s/\{//g;
	$formdata{'user_room'} =~ s/\]//g;
	$formdata{'user_room'} =~ s/\}//g;
	$formdata{'user_room'} =~ s/\,//g;
	$formdata{'user_room'} =~ s/\.//g;
	$formdata{'user_room'} =~ s/\///g;
	$formdata{'user_room'} =~ s/\<//g;
	$formdata{'user_room'} =~ s/\>//g;
	$formdata{'user_room'} =~ s/\?//g;
	$formdata{'user_room'} =~ s/\s/\_/g;

	if ($formdata{'user_room'} eq "")	{
		$formdata{'user_room'} = $room_values[0];
	}

	## Remove HTML from non-message fields
	$formdata{'user_handle'} =~ s/<([^>]+)>//ig;
	$formdata{'user_handle'} =~ s/<(IMG\s*SRC.*)>//ig;
	$formdata{'user_email'} =~ s/<([^>]+)>//ig;
	$formdata{'user_homepage'} =~ s/<([^>]+)>//ig;
}

sub cleanUserInput	{
	## Disallow JavaScript
	$formdata{'user_body'} =~ s/<SCRIPT\w*\>//ig unless $sys_allow_javascript eq "0";
	$formdata{'user_body'} =~ s/<\/SCRIPT\>//ig unless $sys_allow_javascript eq "0";

	## Disallow Java Applets
	$formdata{'user_body'} =~ s/<APPLET\w*\>//ig unless $sys_allow_java eq "0";
	$formdata{'user_body'} =~ s/<\/APPLET\>//ig unless $sys_allow_java eq "0";

	if ((length ($formdata{'user_body'}) > 50) && (($formdata{'user_body'}) !~ /\s/)){
		$formdata{'user_body'} = "";
	}

	$formdata{'user_body'} =~ s/<([^>]+)>//ig unless $sys_allow_html eq "0";
	$formdata{'user_body'} =~ s/<(IMG\s*SRC.*)>//ig unless $sys_allow_images eq "0";
	$formdata{'user_body'} =~ s/\n/<BR\>/g;
	$formdata{'user_body'} =~ s/<BR\><BR\>/<P\>/ig;
}

sub createDateStamp	{
	my($year,$month,$day,$hour,$minute,$second);

	$year = (localtime)[5] + 1900;
	$month = (localtime)[4] + 1;
	$day = (localtime)[3];
	$hour = (localtime)[2];
	$minute = (localtime)[1];
	$second = (localtime)[0];

	$month = "0$month" unless length($month) == 2;
	$day = "0$day" unless length($day) == 2;
	$hour = "0$hour" unless length($hour) == 2;
	$minute = "0$minute" unless length($minute) == 2;
	$second = "0$second" unless length($second) == 2;

	$datestamp = "$month/$day/$year $hour:$minute:$second";
}

sub createRooms		{
	my($room,$value,$counter);

	$room_list = "\t<TR>\n\t\t<TD COLSPAN=2>\n\t\t\t$html_tag_font_begin<B>Комната:</B>$html_tag_font_end\n";

	if ($sys_create_rooms eq "0")	{
		$room_list .= "\t\t\t<INPUT TYPE=TEXT NAME=\"user_room\" VALUE=\"$formdata{'user_room'}\" SIZE=10 MAXLENGTH=10>\n\t\t\t<INPUT TYPE=SUBMIT VALUE=\"  Сказать\">\n\t\t\t<INPUT TYPE=SUBMIT VALUE=\"  Обновить\">\n\t\t</TD>\n\t</TR>\n\t<TR>\n\t\t<TD COLSPAN=2>\n\t\t\t$html_tag_font_begin<B>Доступные комнаты:</B> ";

		foreach $room (@room_values)	{
			$room_list .= "\[ $room \]";
		}

		$room_list .= "$html_tag_font_end\n\t\t</TD>\n\t</TR>\n";
	} else {
		$counter = 0;
		$room_list = "\t<TR>\n\t\t<TD COLSPAN=2>\n\t\t\t$html_tag_font_begin<B>Комната:</B>$html_tag_font_end\n\t\t\t<SELECT NAME=\"user_room\">";

		foreach $room (@room_names)	{
			$value = $room_values[$counter];

			if ($value eq $formdata{'user_room'})	{
				$room_list .= "<OPTION VALUE=\"$value\" SELECTED>$room";
			} else {
				$room_list .= "<OPTION VALUE=\"$value\">$room";
			}

			$counter++;
		}

		$room_list .= "</SELECT>\n\t\t\t<INPUT TYPE=SUBMIT VALUE=\"  Сказать  \">\n\t\t\t<INPUT TYPE=SUBMIT VALUE=\"  Обновить  \">\n\t\t</TD>\n\t</TR>";
	}
}

sub exitProgram		{
	exit(0);
}

sub parsePostInput	{
	$buffer = "";
	read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
	@pairs=split(/&/,$buffer);
	foreach $pair (@pairs)  {

		@a = split(/=/,$pair);
		$name=$a[0];
		$value=$a[1];
		$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
		$value =~ s/~!/ ~!/g;
		$value =~ s/\+/ /g;
		$value =~ s/\r//g;
		push (@data,$name);
		push (@data, $value);
	}
	%formdata=@data;
}

sub printChatLogon	{
	my($line,@chat_logon);

	@chat_logon = &readFile("$path_to_chat_files/index.html");

	print "Content-type:  text/html\n\n";
	print @chat_logon;

	&exitProgram();
}

sub printChatPage		{
	my($line,@chat_page);

	@chat_page = &readFile("$path_to_templet_files/chatpage.templet");

	print "Content-type:  text/html\n\n";

	foreach $line (@chat_page)	{
		$line =~ s/\*\*USER_ROOM_SINGLE\*\*/$formdata{'user_room'}/;
		$line =~ s/\*\*USER_HANDLE\*\*/$formdata{'user_handle'}/;
		$line =~ s/\*\*USER_COLOR\*\*/$formdata{'user_color'}/;
		$line =~ s/\*\*USER_EMAIL\*\*/$formdata{'user_email'}/;
		$line =~ s/\*\*USER_HOMEPAGE\*\*/$formdata{'user_homepage'}/;
		$line =~ s/\*\*MESSAGES\*\*/@messages/;
		$line =~ s/\*\*USER_DATESTAMP\*\*/$datestamp/;
		$line =~ s/\*\*USER_ROOM\*\*/$room_list/;
		$line =~ s/\*\*USER_IMAGE\*\*/$formdata{'user_image'}/;

		print $line;
	}
}

sub printErrorPage	{
	my($message) = @_;
	my($line,@error_page);
	chomp($message);

	open(ERRORPAGETEMP, "$path_to_templet_files/error.templet") || &exitProgram();
	@error_page = <ERRORPAGETEMP>;
	close(ERRORPAGETEMP);

	print "Content-type:  text/html\n\n";

	foreach $line (@error_page)	{
		if ($line =~ m/\*\*ERROR_MESSAGE\*\*/)	{
			$line =~ s/\*\*ERROR_MESSAGE\*\*/$message/;
		}

		print @error_page;
	}
}

sub readFile		{
	my($file_to_read) = @_;
	my(@file_in);

	open(FILE_IN, "$file_to_read") || &printErrorPage($msg_error_file_open);
	@file_in = <FILE_IN>;
	close(FILE_IN);

	return @file_in;
}

sub readRoomFile		{
	if (-e "$path_to_chat_files/$formdata{'user_room'}.room")	{
		open(ROOMIN, "$path_to_chat_files/$formdata{'user_room'}.room") || &printErrorPage($msg_error_file_open);
		@messages = <ROOMIN>;
		close(ROOMIN);
	}
}

sub writeRoomFile		{
	if ($sys_display_ip eq "0")	{
		$ip = " от $ENV{'REMOTE_HOST'}";
	}

	if ($formdata{'user_image'})	{
		$user_icon = "<IMG SRC=\"$url_to_images/$formdata{'user_image'}\" HEIGHT=55 WIDTH=42 BORDER=0>";
	} else {
		$user_icon = "";
	}

	if ($formdata{'user_email'})	{
		$email_icon = "<A HREF=\"mailto:$formdata{'user_email'}\"><IMG SRC=\"$url_to_images/email.gif\" HEIGHT=26 WIDTH=52 BORDER=0></A><BR>";
	} else {
		$email_icon = "";
	}

	if ($formdata{'user_homepage'})	{
		$homepage_icon = "<A HREF=\"http://$formdata{'user_homepage'}\" TARGET=_new><IMG SRC=\"$url_to_images/hp.gif\" HEIGHT=26 WIDTH=52 BORDER=0></A>";
	} else {
		$homepage_icon = "";
	}

	$temparray = "<TABLE BORDER=0 WIDTH=100\% CELLPADDING=2><TR><TD BGCOLOR=\"\#$formdata{'user_color'}\" COLSPAN=3>$html_tag_font_begin<FONT COLOR=\"\#FFFFFF\"><B>\&nbsp\;\&nbsp\;$formdata{'user_handle'}</B>$ip \($datestamp\)\, говорит\:</FONT>$html_tag_font_end</TD></TR><TR><TD WIDTH=10\% VALIGN=TOP ALIGN=CENTER>$url_to_image</TD><TD WIDTH=80\% VALIGN=TOP><BLOCKQUOTE><TT>$formdata{'user_body'}</TT></BLOCKQUOTE></TD><TD WIDTH=10\% VALIGN=TOP ALIGN=CENTER>$email_icon$homepage_icon</TD></TR></TABLE>\n";
	$templog = "<TABLE BORDER=0 WIDTH=100\% CELLPADDING=2><TR><TD BGCOLOR=\"\#$formdata{'user_color'}\" COLSPAN=3>$html_tag_font_begin<FONT COLOR=\"\#FFFFFF\"><B>\&nbsp\;\&nbsp\;$formdata{'user_handle'}</B> от $ENV{'REMOTE_HOST'} \($datestamp\)\, говорит\:</FONT>$html_tag_font_end</TD></TR><TR><TD WIDTH=10\% VALIGN=TOP ALIGN=CENTER>$url_to_image</TD><TD WIDTH=80\% VALIGN=TOP><BLOCKQUOTE><TT>$formdata{'user_body'}</TT></BLOCKQUOTE></TD><TD WIDTH=10\% VALIGN=TOP ALIGN=CENTER>$email_icon$homepage_icon</TD></TR></TABLE>\n";
	unshift(@messages, $temparray);
	splice(@messages, $sys_num_of_posts, 30);

	if (-e "$path_to_chat_files/$formdata{'user_room'}.room")	{
		open(ROOMOUT, ">$path_to_chat_files/$formdata{'user_room'}.room") || &printErrorPage($msg_error_file_open);
		flock(ROOMOUT, 2);
		print ROOMOUT @messages;
		flock(ROOMOUT, 8);
		close(ROOMOUT);
	} else {
		if ($sys_create_rooms eq "0")	{
			open(ROOMOUT1, ">$path_to_chat_files/$formdata{'user_room'}.room") || &printErrorPage($msg_error_file_create);
			flock(ROOMOUT1, 2);
			print ROOMOUT1 @messages;
			flock(ROOMOUT1, 8);
			close(ROOMOUT1);
		}
	}
}

sub writeRoomLog		{
	if ($sys_log_rooms eq "0")	{
		if (-e "$path_to_chat_files/$formdata{'user_room'}.log")	{
			open(ROOMLOG, ">>$path_to_chat_files/$formdata{'user_room'}.log") || &exitProgram();
			flock(ROOMLOG, 2);
			print ROOMLOG $templog;
			flock(ROOMLOG, 8);
			close(ROOMLOG);
		} else {
			open(ROOMLOG1, ">$path_to_chat_files/$formdata{'user_room'}.log") || &exitProgram();
			flock(ROOMLOG1, 2);
			print ROOMLOG1 $templog;
			flock(ROOMLOG1, 8);
			close(ROOMLOG1);
		}
	}
}