#!/usr/bin/perl

#Управление подпиской (клиентская часть)
# Created by PVDLab
# URL:    http://pvdlab.net
# E-Mail: serg@pvdlab.net
# -------------------------------------------------------------------
# Обрабатывается только метод POST, в противном случае
# будет выдаваться сообщение об ошибке.
# -------------------------------------------------------------------
# Входные параметры: (обязательные помечены *)
# email (*)  - E-Mail клиента для подписки/отписки
# action     - действие ("su"-подписка, "un"-отписка). Если не указан - "su" по умолчанию
# charset    - кодировка (допустимы "win", "koi", "iso". Если не указан - берется из настроек)
# mode       - режим (допустимы "txt" или "html". Если не указан - берется из настроек
# -------------------------------------------------------------------

use Fcntl ':flock'; # import LOCK_* constants

$setupfile="settings.db";
#Переменная $kill_banner нужна только для того, чтобы "убить popup-баннер" на Virtualave
#Можете убрать, если в ней нет необходимости :)
$kill_banner="

";

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


open CONF, "<$setupfile"; my @lines=<CONF>; close(CONF);
# читаем HTML-код из настроек
# 5-я строка - html-код страницы для выдачи клиенту результатов подписки
 chomp($lines[4]);
 @msg=split(/\x01/, $lines[4]); $msg[10]=~ s/\x02/\n/g;

#Если метод не POST - выдаем клиенту сообщение об ошибке и выходим
if ($ENV{'REQUEST_METHOD'} ne 'POST')
 {
   $msg[10]=~ s/<<result>>/<font color=red>Ошибка\!<\/font>/ig;
   $msg[10]=~ s/<<errstr>>/<font color=red>Метод GET не поддерживается\!<\/font>/ig;
   $msg[10]=~ s/<<confirm>>/\&nbsp\;/ig;
   print $msg[10];
   print $kill_banner;
   exit;
 }

     read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'} );
       @pairs = split(/&/, $buffer);
       foreach $pair (@pairs)
       { ($name, $value) = split(/=/, $pair);
         $value =~tr/+/ /;
         $value =~ tr/ / /;
         $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
#убираем хвостовые и лидирующие пробелы в значениях полей
         $value =~ s/^\s+//; $value =~ s/\s+$//;
         $in{$name} = $value;
        }
#1-я строка - все настройки, разделенные \x01
($adminname, $adminmail, $MAIL_PROGRAM, $confirmsubs, $confirmunsubs, $abookname, $cntzap, $defcharset, $defmode) = split (/\x01/, $line[0]);
chomp($defmode); $defmode=~ s/\r//;
#4-я строка - html-код формы для подписки/отписки

require "lib_abook.pl";

  $email=$in{"email"};
  if ((!$in{'action'}) or ($in{'action'} eq "")) {$action='su'} else {$action=$in{'action'}};
  if ((!$in{'charset'}) or ($in{'charset'} eq "")) {$charset=$defcharset} else {$charset=$in{'charset'}};
  if ((!$in{'mode'}) or ($in{'mode'} eq "")) {$mode=$defmode} else {$mode=$in{'mode'}};


if ($action eq 'su')
{
    if ((valid_email($email)==0) or (mailstop($email)==1))
      {my $flg=1; $result=$msg[1]; $errstr=$msg[4]; $confirm="";}
       else
       { my $tmpline=join("\x01", $email, $charset, $mode);
         my $flg=save_abook_entry($tmpline);
         $result=$msg[$flg];
         if ($flg>0) {$errstr=$msg[5]; $confirm="";}
           else {$errstr="";
                 if ($confirmsubs eq "on") {$confirm=$msg[8]; &sendconfirm;} else {$confirm=""}
                }
        }

}
else {
      if ((valid_email($email)==0) or (mailstop($email)==1)) {my $flg=1; $result=$msg[3]; $errstr=$msg[6]; $confirm="";}
       else
       { #нужно для того, чтобы знать кодировку и режим при посылке подтверждения об подписке
         $cliententry=get_abook_entry($email); chomp($cliententry);
         $cliententry=~ s/\r//g;
         my $flg=delete_abook_entry($email);
         $result=$msg[2+$flg];
         if ($flg>0) {$errstr=$msg[7]; $confirm="";}
           else {$errstr="";
                 if ($confirmunsubs eq "on") {$confirm=$msg[9]; &sendconfirm;} else {$confirm=""}
                }
        }
      }

#Выдает клиенту результаты
   $msg[10]=~ s/<<result>>/$result/ig;
   $msg[10]=~ s/<<errstr>>/$errstr/ig;
   $msg[10]=~ s/<<confirm>>/$confirm/ig;
   $msg[10]=~ s/\[email\]/$email/ig;
print $msg[10];
print $kill_banner;
exit;

# Отправка подтверждения о подписке/отказе
sub sendconfirm {
#в конфигурации
#2-я строка - текст письма-подтверждения подписки
#  (в форматах txt/html, тексты разделены \x01, перевод строки заменен на \x02
#3-я строка - текст письма, посылаемого после отказа от подписки
#  (в форматах txt/html, тексты разделены \x01, перевод строки заменен на \x02

chomp($lines[1]);
if ($action eq "su") {$lines[1]=~ s/\x02/\n/g; ($txt, $html) = split (/\x01/, $lines[1]); $subj="Подтверждение подписки"; }
   else
   { $lines[2]=~ s/\x02/\n/g; ($txt, $html) = split (/\x01/, $lines[2]); $subj="Подтверждение отказа от подписки";
     #Если отписка - кодировка и режим берется из адресной книжки, а не из параметров
     ($a1, $charset, $mode) = split (/\x01/, $cliententry, 3);
     $charset=$defcharset if (!$charset);
     $mode=$defmode if (!$mode);

   }
#Кодировка и режим
if ($charset eq "win")
 {$echarset='windows-1251'; if ($mode eq "html") {$emode='text/html'; $buf=$html} else {$emode='text/plain'; $buf=$txt}}
elsif ($charset eq "koi")
 {$echarset='koi8-r'; $subj=wintokoi($subj); $adminname=wintokoi($adminname); if ($mode eq "html") {$emode='text/html'; $buf=wintokoi($html)} else {$emode='text/plain'; $buf=wintokoi($txt)}}
else
 {$echarset='iso-8859-5'; $subj=wintoiso($subj); $adminname=wintoiso($adminname); if ($mode eq "html") {$emode='text/html'; $buf=wintoiso($html)} else {$emode='text/plain'; $buf=wintoiso($txt)}}

$buf=~ s/\[email\]/$email/ig;
$buf=~ s/\[charset\]/$echarset/ig;
$buf=~ s/\[mode\]/$mode/ig;
open (MZ,$MAIL_PROGRAM) or return;
print MZ "To: $email\n";
print MZ "From: \"$adminname\" \<$adminmail\>\n";
print MZ "Subject: $subj\n";
print MZ "MIME-Version: 1.0\n";
print MZ "Content-Type: $emode\; charset=\"$echarset\"\n";
print MZ "Content-Transfer-Encoding: 8bit\n\n";
print MZ "$buf\n";
close (MZ);
}

# возращает перекодированную переменную, вызов wintokoi(<переменная>)
sub wintokoi {
    @_[0]=~ tr/\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF/\xE1\xE2\xF7\xE7\xE4\xE5\xF6\xFA\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF2\xF3\xF4\xF5\xE6\xE8\xE3\xFE\xFB\xFD\xFF\xF9\xF8\xFC\xE0\xF1\xC1\xC2\xD7\xC7\xC4\xC5\xD6\xDA\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD2\xD3\xD4\xD5\xC6\xC8\xC3\xDE\xDB\xDD\xDF\xD9\xD8\xDC\xC0\xD1/;
return @_[0];
}

# возращает перекодированную переменную, вызов wintoiso(<переменная>)
sub wintoiso {
    @_[0]=~ tr/\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF/\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF/;
return @_[0];
}