#!/usr/bin/perl #tigvote.cgi # #TigVote, ver. 2.05 # #Alex Pankratov #E-mail - tigra_polosat@mail.ru #------------------------------------ #Copyright (C) 2001, Alex Pankratov #============================================================= use CGI::Carp qw(fatalsToBrowser); require "vars.txt"; #============================================================= $text[1]="Нет опций!"; $text[2]="Назад"; $text[3]="Ошибка! Попробуйте еще раз."; $text[4]="Благодарим Вас за голосование !"; $text[5]="Проголосовало"; $text[6]="Закрыть окно"; $text[7]="Ваш голос не принят,
так как Вы уже голосовали!"; $ip=$ENV{'REMOTE_ADDR'}; if ($ENV{'REQUEST_METHOD'} eq 'GET'){$query=$ENV{'QUERY_STRING'};} else {if ($ENV{'REQUEST_METHOD'} eq 'POST'){read(STDIN, $query, $ENV{'CONTENT_LENGTH'});} else {exit;} } $query=~tr/;'`\\"|*~<>()[]{}$\n\r//d; chomp($query); @pairs=split /&/,$query; 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; if ($name eq "tigvote"){$tigvote[$value]=1} $FORM{$name}=$value; } $action=$FORM{'action'}; $FORM{'file'}=~tr/\.\/\\//d; @files=split /,/,$FORM{'file'}; print "Content-Type: text/html\n\n"; unless (-e "$data_dir/vote/$files[0].txt"){ $pr_page.="Файл голосования не найден.
\n"; print_page(); exit; } getDate(); if (&lock("$data_dir/vote/$files[0].txt")) {print "$error_message";exit} open FILE,"<$data_dir/vote/$files[0].txt"; @fil=; close FILE; chomp(@fil); ($tag_title_open,$tag_title_close,$tag_system_open,$tag_system_close)=split/\|`\|/,$fil[0]; ($tag_question_open,$tag_question_close)=split/\|`\|/,$fil[1]; $graphLenght=$fil[2]; $graphWidth=$fil[3]; $submitText=$fil[4]; ($close_ip,$close_ip_time)=split/\|`\|/,$fil[5]; ($showResult,$sys_lang,$sort,$url_button,$shell,$shell_on_form,$shell_on_submit,$shell_on_result)=split/\|`\|/,$fil[6]; $URLtoImage=$fil[7]; $body=$first_body=$fil[8]; #считываем файл с языками if (open (FILE,"<$data_dir/languages.txt")){ @languages=; close FILE; chomp (@languages); for $i(0..$#languages){ if ($languages[$i]=~/^::/){ ($temp,$lang_name,$lang_abb)=split/::/,$languages[$i]; if ($lang_abb eq $sys_lang){ $counter=1; for $n(($i+1)..$#languages){ if ($languages[$n] eq ":end"){last} $text[$counter]=$languages[$n]; $counter++; } } } } } ######################### if ($action eq 'submit'){goto SUBMIT} if (&unlock("$data_dir/vote/$files[0].txt")) {print "$error_message";exit} if ($action eq 'result'){ result(); $pr_page.="\n

\n"; print_page(); exit; } if ($action eq 'jresult'){ $j="1";result(); $pr_page.="\n

\n"; print_page(); exit; } if ($action eq 'form'){goto FORM} if ($action eq 'form_check'){$check=1;goto FORM} if ($action eq 'form_select'){$select=1;goto FORM} $pr_page.="Вызов скрипта с ошибочным параметром

\n"; print_page(); exit; ################################################### # построение формы # ################################################### FORM: $pr_page.="
\n"; $pr_page.="\n"; $pr_page.="\n"; $pr_page.="\n"; $pr_page.="\n"; if ($select){ $pr_page.="\n"; } else { for $i(10..$#fil){ ($row,$value)=split /\|`\|/,$fil[$i]; $pr_page.="\n"; } } if ($url_button){$pr_page.="\n"; $pr_page.="
$tag_title_open$fil[9]$tag_title_close
\n"; $pr_page.="$tag_question_open\n"; $pr_page.="\n"; $pr_page.="$tag_question_close"; $pr_page.="
$tag_question_open$row$tag_question_close
\n"} else {$pr_page.="
\n"} $pr_page.="
\n"; $pr_page.="\n"; print_page(); exit; ################################################### # получение голоса # ################################################### SUBMIT: unless (@tigvote){ $pr_page.="
"; $pr_page.="$tag_system_open$text[1]$tag_system_close"; # Ни один пункт не был выбран! $pr_page.="

"; $pr_page.="$tag_system_open$text[2]$tag_system_close"; # Вернуться $pr_page.="\n

\n"; if (&unlock("$data_dir/vote/$files[0].txt")) {print "$error_message";exit} print_page(); exit; } for $i(0..$#tigvote){ if ($tigvote[$i]){ ($row,$number)=split/\|`\|/,$fil[$i+10]; # проверка глюка с появлением пустых пунктов unless ($row){ $pr_page.="
\n"; $pr_page.="$tag_system_open$text[3]$tag_system_close"; # ошибка приема данных. повторите попытку. $pr_page.="

"; $pr_page.="$tag_system_open$text[2]$tag_system_close"; # Вернуться $pr_page.="\n

\n"; if (&unlock("$data_dir/vote/$files[0].txt")) {print "$error_message";exit} print_page(); exit; } ############ $number++; $fil[$i+10]="$row|`|$number"; } } # проверка IP if($close_ip eq 'yes'){IPcheck()} for $i(0..$#fil){$fil[$i].="\n"} # исправление глюка с появлением пустых пунктов chomp($fil[9]); ($fil[9])=split/\|`\|/,$fil[9]; $fil[9].="\n"; for $i(10..$#fil){ ($row,$number)=split/\|`\|/,$fil[$i]; unless ($row){$fil[$i]=""} } ############# open FILE,">$data_dir/vote/$files[0].txt"; print FILE @fil; close FILE; if (&unlock("$data_dir/vote/$files[0].txt")) {print "$error_message";exit} $point=""; for $i(0..$#tigvote){ if ($tigvote[$i]){ ($row,$number)=split/\|`\|/,$fil[$i+10]; $point.="$row
"; } } $forLog="1=$point"; writeLog(); #ответ после голосования $pr_page.="$tag_system_open$text[4]$tag_system_close"; # Спасибо, Ваш голос был принят. $pr_page.="

\n"; if($showResult eq 'yes'){result();} else { $pr_page.=""; $pr_page.="$tag_system_open$text[2]$tag_system_close"; # Вернуться $pr_page.=""; } print_page(); exit; ################################################# # подпрограммы # ################################################# ################################################# # подпрограмма вывода графика # ################################################# sub result() { $pr_page.="\n"; for $f(0..$#files){ if (&lock("$data_dir/vote/$files[$f].txt")) {print "$error_message";exit} open FILE,"<$data_dir/vote/$files[$f].txt"; @fil=; close FILE; if (&unlock("$data_dir/vote/$files[$f].txt")) {print "$error_message";exit} chomp(@fil); ($tag_title_open,$tag_title_close,$tag_system_open,$tag_system_close)=split/\|`\|/,$fil[0]; ($tag_question_open,$tag_question_close)=split/\|`\|/,$fil[1]; $graphLenght=$fil[2]; $graphWidth=$fil[3]; $submitText=$fil[4]; ($close_ip,$close_ip_time)=split/\|`\|/,$fil[5]; ($showResult,$sys_lang,$sort,$url_button)=split/\|`\|/,$fil[6]; $URLtoImage=$fil[7]; $body=$fil[8]; #обработка данных из файла $sum=0;@num=""; for $i(10..$#fil){ ($mess[$i-10],$num[$i-10])=split /\|`\|/,$fil[$i]; $sum+=$num[$i-10]; } #вычисление графика #нахождение большего значения, вычисление коэффициента @temp=sort{$b<=>$a}@num; $max=$temp[0]; unless ($max){$max=1;} $koeff=$graphLenght/$max; #сортировка по значению if ($sort eq "vote"){ for $i(0..$#num){ for $n(0..$#num-$i-1){ if ($num[$n]<$num[$n+1]){@num[$n,$n+1]=@num[$n+1,$n];@mess[$n,$n+1]=@mess[$n+1,$n]} } } } if ($sort eq "vote-reverse"){ for $i(0..$#num){ for $n(0..$#num-$i-1){ if ($num[$n]>$num[$n+1]){@num[$n,$n+1]=@num[$n+1,$n];@mess[$n,$n+1]=@mess[$n+1,$n]} } } } #сортировка по алфавиту if ($sort eq "point"){ for $i(0..$#mess){ for $n(0..$#mess-$i-1){ if ($mess[$n] gt $mess[$n+1]){@mess[$n,$n+1]=@mess[$n+1,$n];@num[$n,$n+1]=@num[$n+1,$n]} } } } if ($sort eq "point-reverse"){ for $i(0..$#mess){ for $n(0..$#mess-$i-1){ if ($mess[$n] lt $mess[$n+1]){@mess[$n,$n+1]=@mess[$n+1,$n];@num[$n,$n+1]=@num[$n+1,$n]} } } } #построение графика $pr_page.="\n\n"; } $pr_page.="\n"; $pr_page.="
\n\n"; $pr_page.="\n"; $pr_page.="\n"; $num_img=0; for $i(10..$#fil){ $width=int($num[$i-10]*$koeff); $percent=0; if($sum!=0){$percent=$num[$i-10]/$sum*100;$percent=int($percent*100+0.5)/100;} if($width==0){$pr_page.="\n";} else {$pr_page.="\n";} if ($num_img<9){$num_img++} else {$num_img=0} } $pr_page.="\n"; $pr_page.="
$tag_title_open$fil[9]$tag_title_close
$tag_question_open$mess[$i-10]$tag_question_close$tag_question_open $num[$i-10]$tag_question_close$tag_question_open($percent%)$tag_question_close
$tag_question_open$mess[$i-10]$tag_question_close$tag_question_open $num[$i-10]$tag_question_close$tag_question_open($percent%)$tag_question_close
$tag_question_open"; $pr_page.="$text[5]"; # Всего $pr_page.=":$tag_question_close$tag_question_open $sum$tag_question_close 
\n"; $pr_page.="\n"; $pr_page.="
\n"; $pr_page.="
TigVote 2.05 © 2001
\n\n"; if ($j==1){$pr_page.=""; $pr_page.="$tag_system_open$text[6]$tag_system_close"; # Закрыть окно $pr_page.=""} else {$pr_page.=""; $pr_page.="$tag_system_open$text[2]$tag_system_close"; # Вернуться $pr_page.=""} } ################################################# # подпрограмма проверки IP # ################################################# sub IPcheck() { $close_ip_time*=60; if (&lock("$data_dir/vote/$files[0]-ip.txt")) {print "$error_message";exit} open FILE,"<$data_dir/vote/$files[0]-ip.txt"; @filip=; close FILE; # не пущать, если адрес есть в базе for $i(0..$#filip){ ($file_ip,$ip_time)=split/:/,$filip[$i]; chomp($ip_time); if($file_ip eq $ip){ if ((!$close_ip_time) || (time-$ip_time)<$close_ip_time){ if (&unlock("$data_dir/vote/$files[0].txt")) {print "$error_message";exit} if (&unlock("$data_dir/vote/$files[0]-ip.txt")) {print "$error_message";exit} $pr_page.="$tag_system_open$text[7]$tag_system_close"; # Ваш голос не был принят, т.к.
Вы уже голосовали! $pr_page.="

"; if($showResult eq 'yes'){result();} $point=""; for $i(0..$#tigvote){ if ($tigvote[$i]){ ($row,$number)=split/\|`\|/,$fil[$i+10]; $point.="$row
"; } } $forLog="3=$point"; writeLog(); print_page(); exit; } else {$filip[$i]="";} } } push (@filip,"$ip:".time."\n"); open FILE,">$data_dir/vote/$files[0]-ip.txt"; print FILE @filip; close FILE; if (&unlock("$data_dir/vote/$files[0]-ip.txt")) {print "$error_message";exit} } ################################################# # подпрограмма записи лог-файла # ################################################# sub writeLog() { if (&lock("$data_dir/vote/$files[0]-log.txt")) {print "$error_message";exit} open LOG,">>$data_dir/vote/$files[0]-log.txt"; print LOG "$date=$ENV{'REMOTE_ADDR'}=$ENV{'REMOTE_HOST'}=$forLog\n"; close LOG; if (&unlock("$data_dir/vote/$files[0]-log.txt")) {print "$error_message";exit} } ################################################# # подпрограмма определения даты # ################################################# sub getDate() { @days = ('Воскресенье','Понедельник','Вторник','Среда','Четверг','Пятница','Суббота'); @months = ('01','02','03','04','05','06','07','08','09','10','11','12'); ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); $year=$year-100; if($year < 10) { $year = "0$year"; } if($hour < 10) { $hour = "0$hour"; } if ($min < 10) { $min = "0$min"; } if ($sec < 10) { $sec = "0$sec"; } $date = "$mday=$months[$mon]=$year=$days[$wday]=$hour=$min=$sec"; } ################################################# # не могу открыть файл с языками # ################################################# sub no_lang(){ $no_lang=1; } ################################################# # вывод конечной страницы # ################################################# sub print_page(){ if ($shell){ open FILE,"<$data_dir/shells/$shell.txt"; @shell=; close FILE; for $i(0..$#shell){ $shell[$i]=~s//$pr_page/; } } if ($shell && $shell_on_form && (($action eq "form") || ($action eq "form_check") || ($action eq "form_select"))){ print @shell; return; } if ($shell && $shell_on_submit && ($action eq "submit")){ print @shell; return; } if ($shell && $shell_on_result && (($action eq "result") || ($action eq "jresult"))){ print @shell; return; } # html-оболочка отключена print "\n\nГолосование на сайте группы компаний ЛОЭС.\n\n$first_body\n\n"; print $pr_page; print < END_of_multiple_text } ################################################################## # # lock() Version 2.1 # Written by Craig Patchett craig@patchett.com # Created 16/09/1996 Last Modified 12/05/2000 # # Функция создает эксклюзивную блокировку для файла. Блокировка # работает только если другие программы, пытающиеся получить # доступ к файлу, также используют эти подпрограммы. # # Функция возвращает: # 0 - Если блокировка установлена # 1 - При ошибке создания $LOCK_DIR/$filename.tmp # 2 - Если $filename используется # 3 - Если lock-файл не возможно открыть или создать # # Глобальные переменные: # $error_message - информация о возникшей ошибке # $NAME_LEN - максимальная длина файла # $LOCK_DIR - каталог для создания файла блокировки # $MAX_WAIT - максимальное время ожидания блокировки # # Во время работы создаются: # $LOCK_DIR/$filename.tmp # $LOCK_DIR/$filename.lok (существует только пока файл # заблокирован) # ################################################################## sub lock { local($filename)=@_; local($wait, $lock_pid); local($temp_file)="$LOCK_DIR$$.tmp"; local($lock_file)=$filename; $lock_file=~tr/\/\\:.//d; # Удаляем разделители каталогов if ($NAME_LEN && ($NAME_LEN < length($lock_file))) { $lock_file=substr($lock_file, -$NAME_LEN); } $lock_file="$LOCK_DIR$lock_file.lok"; $error_message=''; # Создание файла с PID if (!open(TEMP, ">$temp_file")) { $error_message="Content-type: text/html\n\n1. Невозможно создать $temp_file ($!)."; return(1); } print TEMP $$; close(TEMP); # Проверка lock-файла if (-e $lock_file) { #Ожидание, пока файл разблокируют (если lock-файл существует) for ($wait=$MAX_WAIT; $wait; --$wait) { sleep(1); last unless -e $lock_file; } } if ((-e $lock_file) && (-M $lock_file < 0)) { unlink($temp_file); $error_message="Content-type: text/html\n\n2. Файл \"$filename\" в данный момент используется. Попытайтесь еще раз позднее."; return(2); } else { if (!rename($temp_file, $lock_file)) { unlink($temp_file); $error_message="Content-type: text/html\n\n3. Невозможно блокировать файл \"$filename\" ($!)."; return(3); } # Проверка блокировки if (!open(LOCK, "<$lock_file")) { $error_message="Content-type: text/html\n\n4. Невозможно проверить блокировку файла \"$filename\" ($!)."; return(3); } $lock_pid=; close(LOCK); if ($lock_pid ne $$) { $error_message="Content-type: text/html\n\n5. Файл \"$filename\" в данный момент используется. Попытайтесь еще раз позднее."; return(2); } else { return(0) } } } ################################################################## # # unlock() Version 2.1 # Written by Craig Patchett craig@patchett.com # Created 16/09/1996 Last Modified 12/05/2000 # # Разблокирует файл, заблокированный функцией lock() # # Возвращает: # 0 - Если файл разблокирован # 1 - Если нет доступа к lock-файлу # 2 - Если файл заблокирован другим процессом # 3 - Если невозможно разблокировать файл # # Глобальные переменные: # $error_message - информация о возникшей ошибке # $NAME_LEN - максимальная длина файла # $LOCK_DIR - каталог для создания файла блокировки # # Во время работы удаляется $LOCK_DIR/$filename.lok # ################################################################## sub unlock { local($filename)=@_; local($lock_file)=$filename; $lock_file=~tr/\/\\:.//d; # Удаляем разделители каталогов if ($NAME_LEN; close(LOCK); if ($lock_pid ne $$) { $error_message="Content-type: text/html\n\nФайл \"$filename\" заблокирован другим процессом."; return(2); } #Удаление lock-файла if (!unlink($lock_file)) { $error_message="Content-type: text/html\n\nНевозможно разблокировать файл \"$filename\" ($!)."; return(3); } return(0); }