#!/usr/bin/perl
use CGI qw(:all);
use strict;
use Fcntl qw(:flock);

my ($adm_func,$exit,@data,$ip,$stop_flag,$pass,$n,$command,@main,$name,$mes,$color,$i,@print,$sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst,$date,$sem,@base,@info,$err);

$sem="chat.sem";
$name=param('name');
$mes=param('mes');
$color=param('color');
$pass=param('pass');

$name=substr($name, 0, 20);
$mes=substr($mes, 0, 300);
$color=substr($color, 0, 7);

$command=$ENV{'QUERY_STRING'};

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$mon+=1;
if ($hour<10) {
 $hour="0$hour";
}
if ($min<10) {
 $min="0$min";
}
if ($sec<10) {
 $sec="0$sec";
}
$date="$hour:$min:$sec";

&clear;

if ($command eq "") {
 &global;
} elsif ($command eq "main") {
 &main;
} elsif ($command eq "write") {
 &check;
} elsif ($command eq "who") {
 &who;
} elsif ($command eq "login") {
 &login;
} elsif ($command eq "exit") {
 $exit=1;
 &check;
}

sub global {
print header;
print <<EOF;
<html>
<head>
<title>Светлячок | Наш чат</title>
<meta http-equiv=Content-Type content="text/html; charset=windows-1251">
<style>
 body {margin: 0 0 0 0;
 }
input.2 {border-right: #000000 1pt solid;
border-bottom: #000000 1pt solid;
border-left: #ffffff 1pt solid;
border-top: #ffffff 1pt solid;
margin: 5 5 5 5;
background-color:#e0e0e0;
}
a {font-family: verdana;
color: #002255;
text-decoration: none;
font-size: 11px;
}
a:visited {color: #002255;
TEXT-DECORATION: none;
font-size: 11px;
}
a:active {color: #000000;
font-size: 11px;
}
a:hover {color: #0060f0;
font-size: 11px;
}
.header {font-family: verdana;
font-size: 11px;
color: #000000;
}
p.log {
margin: 12 0 0 0;
}
</style>
</head>
<frameset rows="*,120">
 <frameset cols="*,150">
 <frame src="chat.pl?main" marginwidth="0" marginheight="0">
 <frame src="chat.pl?who" marginwidth="0" marginheight="0">
 </frameset>
 <frameset>
 <frame src="chat.pl?login" marginwidth="0" marginheight="0">
 </frameset>
</framest>
<noframes>
<body bgcolor="#8080b0" text="#ffe0e0">
Извините, но ваш браузер не поддерживает фреймы!
</body>
</noframes>
</html>
EOF

}

sub main {
 open(TXT, "main.dat");
  @main=<TXT>;
 close(TXT);

@main=reverse(@main);

 print header;
print <<EOF;
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=windows-1251">
<meta http-equiv="refresh" content="15">
<style>
<!--
body {background-color: #f0f0f0;
margin: 10 10 10 10;
}
input.2 {border-right: #000000 1pt solid;
border-bottom: #000000 1pt solid;
border-left: #ffffff 1pt solid;
border-top: #ffffff 1pt solid;
margin: 5 5 5 5;
background-color:#e0e0e0;
}
a {font-family: verdana;
color: #002255;
text-decoration: none;
font-size: 11px;
}
a:visited {color: #002255;
TEXT-DECORATION: none;
font-size: 11px;
}
a:active {color: #000000;
font-size: 11px;
}
a:hover {color: #0060f0;
font-size: 11px;
}
.header {font-family: verdana;
font-size: 11px;
color: #000000;
}
p.log {
margin: 12 0 0 0;
}
-->
</style>
<script language="javascript">
<!--
 function end() {
  location.href='#end';
 }
-->
</script>
</head>
<body onload="end()">
<font class="header">
@main
<a name="end"> </a>
</font>
</body>
</html>
EOF

}

sub login {
print header;
print <<EOF;
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=windows-1251">
<link href="main2.css" type="text/css" rel="stylesheet">
<style>
<!--
body {background-color: #f0f0f0;
margin: 20 20 20 20;
}
input.2 {border-right: #000000 1pt solid;
border-bottom: #000000 1pt solid;
border-left: #ffffff 1pt solid;
border-top: #ffffff 1pt solid;
margin: 5 5 5 5;
background-color:#e0e0e0;
}
a {font-family: verdana;
color: #002255;
text-decoration: none;
font-size: 11px;
}
a:visited {color: #002255;
TEXT-DECORATION: none;
font-size: 11px;
}
a:active {color: #000000;
font-size: 11px;
}
a:hover {color: #0060f0;
font-size: 11px;
}
.header {font-family: verdana;
font-size: 11px;
color: #000000;
}
p.log {
margin: 12 0 0 0;
}
-->
</style>
</head>
<body>
<center>
<table cellspacing="0" cellpadiing="0">
<form action="chat.pl?write" method="post">
<tr>
<td>
<font class="header">Имя:&nbsp;</font>
<input type="text" name="name" style="border: 1px solid #666666; font: 11px verdana; background-color: #fffff0" size="15">
</td>
<td>
<font class="header">&nbsp;&nbsp;Пароль:&nbsp;</font>
<input type="password" name="pass" style="border: 1px solid #666666; font: 11px verdana; background-color: #fffff0" size="15">
</td>
<td>
<font class="header">&nbsp;&nbsp;Цвет сообщений:&nbsp;&nbsp;</font>
</td>
<td bgcolor="#000000">
<input name="color" type="radio" value="000000" checked>
</td>
<td bgcolor="#666666">
<input name="color" type="radio" value="666666">
</td>
<td bgcolor="#f00000">
<input name="color" type="radio" value="f00000">
</td>
<td bgcolor="#a00000">
<input name="color" type="radio" value="a00000">
</td>
<td bgcolor="#00f000">
<input name="color" type="radio" value="00f000">
</td>
<td bgcolor="#009000">
<input name="color" type="radio" value="009000">
</td>
<td bgcolor="#0000f0">
<input name="color" type="radio" value="0000f0">
</td>
<td bgcolor="#000090">
<input name="color" type="radio" value="000090">
</td>
<td bgcolor="#f0d000">
<input name="color" type="radio" value="f0d000">
</td>
<td bgcolor="#f0a000">
<input name="color" type="radio" value="f0a000">
</td>
<td bgcolor="#f07000">
<input name="color" type="radio" value="f07000">
</td>
<td bgcolor="#00a060">
<input name="color" type="radio" value="00a060">
</td>
<td bgcolor="#00e0c0">
<input name="color" type="radio" value="00e0c0">
</td>
<td bgcolor="#00a0f0">
<input name="color" type="radio" value="00a0f0">
</td>
<td bgcolor="#0060e0">
<input name="color" type="radio" value="0060e0">
</td>
<td bgcolor="#9000f0">
<input name="color" type="radio" value="9000f0"">
</td>
<td bgcolor="#f000f0">
<input name="color" type="radio" value="f000f0">
</td>
<td bgcolor="#f00090">
<input name="color" type="radio" value="f00090">
</td>
</tr>
<tr>
<td colspan="1" valign="middle">
<a href="reg.pl?new" target="_blank">Регистрация</a>&nbsp;&nbsp;&nbsp;
</td>
<td colspan="13" valign="middle">
<p>
<hr size="1" width="100%" color="#3060f0">
</p>
</td>
<td colspan="7" align="right">
<input type="submit" value="Войти &gt;" style="width:70; border: #003366 1pt solid;background-color: #e4dbd0; font-family: verdana; font-size: 10; color: #003366;">
</td>
</tr>
</form>
</table>
$err
</center>
</body>
</html>
EOF
}

sub who {

my(@files, @data0, $buffer, $k, $j);

@files=glob("users/*.dat");

&get_lock;
open(DAT, "pep_base.cfg");
 @data0=<DAT>;
close(DAT);
for ($i=0; $i<@files; $i++) {

 $buffer=$files[$i];
 $buffer=~s/^.*\///i;
 $buffer=~s/\..*$//i;
 for ($j=0; $j<@data0; $j++) {
  @info=split(/:-:-:/, $data0[$j]);
  if ($buffer eq $info[0] and $info[6]!=2 and (-M $files[$i])>0.007) {
   $data0[$j]=~s/1$/0/i;
  }
 }
}
open(DAT, ">pep_base.cfg");
for ($i=0; $i<@data0; $i++) {
 print DAT $data0[$i];
}
close(DAT);
&release_lock();


(@files, @data, @info, $buffer, $k)=0;

open(BS, "pep_base.cfg");
 @data=<BS>;
close(BS);

for ($i=0; $i<@data; $i++) {
 @info=split(/:-:-:/, $data[$i]);
 if ($info[6]==1) {
  $data[$i]="$info[0] [<a href=\"inf.pl?login=$info[0]\" target=\"_blank\">i</a>]";
 } else {
  $data[$i]="";
 }
}

print header;
print <<EOF;
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=windows-1251">
<link href="main2.css" type="text/css" rel="stylesheet">
<meta http-equiv="refresh" content="60">
<style>
<!--
body {background-color: #f0f0f0;
margin: 10 10 10 10;
}
input.2 {border-right: #000000 1pt solid;
border-bottom: #000000 1pt solid;
border-left: #ffffff 1pt solid;
border-top: #ffffff 1pt solid;
margin: 5 5 5 5;
background-color:#e0e0e0;
}
a {font-family: verdana;
color: #002255;
text-decoration: none;
font-size: 11px;
}
a:visited {color: #002255;
TEXT-DECORATION: none;
font-size: 11px;
}
a:active {color: #000000;
font-size: 11px;
}
a:hover {color: #0060f0;
font-size: 11px;
}
.header {font-family: verdana;
font-size: 11px;
color: #000000;
}
p.log {
margin: 12 0 0 0;
}
-->
</style>
<script language="javascript">
<!-- hide
 function refresh(url) {
  location.href=url;
 }
-->
</script>
</head>
<body>
<form method="post" action="chat.pl?who">
<center>
&nbsp;&nbsp;&nbsp;&nbsp;<input type="button" style="width:70; border: #003366 1pt solid;background-color: #e4dbd0; font-family: verdana; font-size: 10; color: #003366;" value="Обновить" onclick="refresh('chat.pl?who')">
</center>
<br>
<font class="header">
 @data
</font>
</form>
</body>
</html>
EOF
}

sub write {

if ($info[5]==2 or $info[5]==3) {
 $adm_func="<script language=\"javascript\">
	<!--
	function adm ()
	{
	open(\"adm.pl?name=$name\&pass=$pass\", window);
	}
	-->
	</script>
	<input value=\"Функции\" type=\"button\" style=\"width:70\; border: \#003366 1pt solid\;background-color: \#e4dbd0\; font-family: verdana\; font-size: 10\; color: \#003366\;\" onclick=\"adm()\">";
} else {
 $adm_func="";
}
print header;
print <<EOF;
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=windows-1251">
<link href="main2.css" type="text/css" rel="stylesheet">
<style>
<!--
body {background-color: #f0f0f0;
margin: 20 20 20 20;
}
input.2 {border-right: #000000 1pt solid;
border-bottom: #000000 1pt solid;
border-left: #ffffff 1pt solid;
border-top: #ffffff 1pt solid;
margin: 5 5 5 5;
background-color:#e0e0e0;
}
a {font-family: verdana;
color: #002255;
text-decoration: none;
font-size: 11px;
}
a:visited {color: #002255;
TEXT-DECORATION: none;
font-size: 11px;
}
a:active {color: #000000;
font-size: 11px;
}
a:hover {color: #0060f0;
font-size: 11px;
}
.header {font-family: verdana;
font-size: 11px;
color: #000000;
}
p.log {
margin: 12 0 0 0;
}
-->
</style>
</head>
<body>
<center>
<form method="post" action="chat.pl?write">
<table cellspacing="0" cellpadding="0">
<tr>
<td>
<input type="hidden" value="$color" name="color">
<input type="hidden" value="$name" name="name">
<input type="hidden" value="$pass" name="pass">
<font class="header">Сообщение: </font><input type="text" name="mes" style="border: #003366 1pt solid;font-family: verdana;font-size: 10px;background-color: #fffff0;" size="55">
</td>
<td>
&nbsp;&nbsp;&nbsp;
<input type="submit" value="Написать"  style="width:70; border: #003366 1pt solid;background-color: #e4dbd0; font-family: verdana; font-size: 10; color: #003366;">
<input type="reset" value="Очистить" style="width:70; border: #003366 1pt solid;background-color: #e4dbd0; font-family: verdana; font-size: 10; color: #003366;">
 $adm_func
</td>
</tr>
</table>
</form>
<form method="post" action="chat.pl?exit">
<input type="hidden" value="$name" name="name">
<input type="hidden" value="$pass" name="pass">
<input type="submit" value="Выйти" style="width:70; border: #003366 1pt solid;background-color: #e4dbd0; font-family: verdana; font-size: 10; color: #003366;">
</form>
</center>
</body>
</html>
EOF
}

sub check {
 &get_lock;
 open(BS, "pep_base.cfg");
  @base=<BS>;
 close(BS);

 $stop_flag=-1;
 for ($i=0; $i<@base; $i++) {
  if ($base[$i]=~m/^$name:-:-:/i) {
   $stop_flag=$i;
  }
 }
 if ($stop_flag==-1) {
  $err="<font style=\"font-family: verdana;font-size: 12px;color: #b00000\">Пользователь $name не существует или был удален из базы!</font>";
  &release_lock;
  &login;
 } else {
  &check1;
 }
}

sub check1 {
 @info=split(/:-:-:/, $base[$stop_flag]);
 if ($info[1] eq $pass) {
  &check2;
 } else {
  $err="<font style=\"font-family: verdana;font-size: 12px;color: #b00000\">Пароль неверен, проверьте правильность написания!</font>";
  &release_lock;
  &login;
 }
}

sub check2 {
 $ip=remote_addr;
 open(CHAR, ">users/$name.dat");
  print CHAR "$date\n";
 close(CHAR);

 if ($exit!=1) {
  $base[$stop_flag]="$name:-:-:$pass:-:-:$info[2]:-:-:$info[3]:-:-:$ip:-:-:$info[5]:-:-:1\n";

  open(BS, ">pep_base.cfg");
   print BS @base;
  close(BS);
  &release_lock;
  &wfile;
 } else {
  $base[$stop_flag]="$name:-:-:$pass:-:-:$info[2]:-:-:$info[3]:-:-:$ip:-:-:$info[5]:-:-:0\n";

  open(BS, ">pep_base.cfg");
   print BS @base;
  close(BS);
  &release_lock;
  &login;
 }
}

sub wfile {
 open(MAIN, "main.dat");
  @print=<MAIN>;
 close(MAIN);
 
 if ($mes ne "") {
  $mes="<b>($date) $name:<\/b><font color=\"#$color\"> $mes<\/font><br>\n";

  &get_lock();
  open(MAIN, ">main.dat");
   print MAIN $mes;
   for ($i=0; $i<49; $i++) {
    print MAIN $print[$i];
   }
  close(MAIN);
  &release_lock();
 }
 &write;
}

sub clear {
 for ($i=0; $i<7; $i++) {
  $color=~s/[^A-Fa-f0-9]//i;
 }

 for ($i=0; $i<20; $i++) {
  $name=~s/[^A-Za-z0-9\_\-\+\=]//;
 }

 for ($i=0; $i<300; $i++) {
  $_=$mes;
  s/<//i;
  s/>//i;
  s/"//i;
  s/^\s//i;
  s/\s$//i;
  $mes=$_;
 }
}

sub get_lock {
open(SEM, ">$sem") || "Невозможно открыть семафор: $!";
 flock(SEM, LOCK_EX) || "Невозможно заблокировать семафор: $!";
}

sub release_lock {
 close(SEM);
}
