1;
#Подпрограммы работы со списком подписчиков (далее по тексту - адресная книга)


 $modes{'win'}="0"; $modes{'koi'}="1"; $modes{'iso'}="2";
 $modes{'txt'}="0"; $modes{'html'}="1";
  
#Формат файла settings.db
#1-я строка - все настройки, разделенные \x01
#2-я строка - текст письма-подтверждения подписки 
#  (в форматах txt/html, тексты разделены \x01, перевод строки заменен на \x02 
#3-я строка - текст письма, посылаемого после отказа от подписки 
#  (в форматах txt/html, тексты разделены \x01, перевод строки заменен на \x02
#4-я строка - html-код формы для подписки/отписки
#5-я строка - html-код страницы для выдачи клиенту результатов подписки

#------------------------------------------------------
#Чтение из файла конфигурации необходимых параметров
#------------------------------------------------------
sub read_settings {
open CONF, "<$setupfile"; my $line=<CONF>; close(CONF); chomp($line); 
($adminname, $adminmail, $MAIL_PROGRAM, $confirmsubs, $confirmunsubs, $abookname, $cntzap, $defcharset, $defmode) = split (/\x01/, $line);
}

#------------------------------------------------------
#Удаление адреса из адресной книги
#------------------------------------------------------
sub delete_from_book {
my $flg=delete_abook_entry($in{'newemail'});
if ($flg==0) {$errstr1="Адрес $in{'newemail'} успешно удален!";}
 else {$errstr1="Адреса $in{'newemail'} нет в адресной книге!!";}
&put_edit_form($errstr1);
}

#------------------------------------------------------
#Добавление адреса из адресной книги
#------------------------------------------------------
sub add_to_book {
 #убираем хвостовые и лидирующие пробелы в значениях поля E-Mail на всякий случай
 $in{'newemail'} =~ s/^\s+//; $in{'newemail'} =~ s/\s+$//;  
 if (valid_email($in{'newemail'})==0) {$errstr1="Неправильный E-Mail: <b>$in{'newemail'}</b>";} 
 elsif (mailstop($in{'newemail'})==1) {$errstr1="Введенный E-Mail содержит stop-символы";}
 else {
   my $line=join("\x01", $in{'newemail'}, $in{'charset'}, $in{'mode'});
   if (save_abook_entry($line)==1) {$errstr1="Адрес $in{'newemail'} уже есть в адр. книге";}
      else {$errstr1="Адрес $in{'newemail'} занесен в адр. книгу";}
     }
&put_edit_form($errstr1);
 
}

#------------------------------------------------------
#Сохранение изменений по подписчику
#------------------------------------------------------
sub save_changes {
my $errstr="";
my $tmp=get_abook_entry($in{'oldemail'});
if (($tmp) and ($in{'newemail'} ne ""))
 { chomp($tmp);
#убираем хвостовые и лидирующие пробелы в значениях поля E-Mail на всякий случай
 $in{'newemail'} =~ s/^\s+//; $in{'newemail'} =~ s/\s+$//;  
 
  if (valid_email($in{'newemail'})==0) {$errstr1="Неправильный E-Mail: <b>$in{'newemail'}</b>";} 
  elsif (mailstop($in{'newemail'})==1) {$errstr1="Введенный E-Mail содержит stop-символы";}
  else { $errstr1="Данные по $in{'newemail'} сохранены!";
  
        open (CONF, "<$abookname"); my @tmpabook=<CONF>; close(CONF);
        open (CONF, ">$abookname"); flock(CONF, LOCK_EX); my $nentry; my $newline;
		foreach $nentry (@tmpabook)
		 {chomp($nentry); 
		  if ($nentry ne $tmp) {print CONF "$nentry\n"}
		  else {  $newline=join("\x01", $in{'newemail'}, $in{'charset'}, $in{'mode'});
                  print CONF "$newline\n";
		       }                 
		 }
        close (CONF); 
	   }
						 
 }

&put_edit_form($errstr1);
 
}

#------------------------------------------------------
#Вывод страницы с адресами согласно установкам по кол-ву записей (в настройках)
# c учетом фильтра
#Входные параметры - сколько записей пропустить, фильтр
#------------------------------------------------------
sub view_abook {
 my ($skip,$filter)=@_;
 my $cnt=0; my $allcnt=0; &read_settings if (!$abookname);
 my $header="<table width=580 border=0  CELLPADDING=0 CELLSPACING=0 bgcolor=#000000><tr><td><table width=580 border=0  CELLPADDING=2 CELLSPACING=1>";
 my $footer="</table></td></tr></table>";

open (ABOOK, $abookname);
 while ( <ABOOK> ) { $allcnt++;
                    if (!$filter) {$cnt++;}
                    elsif ($_=~ /$filter/i) {$cnt++;}
                   }


print qq(  
 <script language=javascript>
  document.mainform.step.value="$addnew";
 </script> 
<table width="600" border="0" cellspacing="0" cellpadding="0" bgcolor=black ><tr><td>
<table width="600" border="0" cellspacing="1" cellpadding="1">
<tr><th  bgcolor=#FEF0CD align=left><font size="-1" face="Verdana, Arial"><b>Адресная книга (список подписчиков)</b></font></th></tr>
<tr><td bgcolor=#F9F1D7><font size="-1" face="Verdana, Arial">
Кол-во записей в базе: <font color=red>$allcnt</font>
\&nbsp;\&nbsp;\&nbsp;С учетом фильтра: <font color=red>$cnt</font><br>

Фильтр: <input type=textbox name=filter size=45 value="$filter"} $inputstyle><INPUT TYPE="button" VALUE="обновить" onclick="presubmit($refresh)" style="{font: 8pt 'Verdana'; color:blue; border: outset 1px; height: 24px; width: 90;}">

<INPUT TYPE="hidden" NAME="skip" VALUE="$skip"><INPUT TYPE="hidden" NAME="oldemail"><br>
);

if ($cnt>$cntzap) 
{
  my $sk;
  for ($i=0; $i<$cnt/$cntzap; $i++) {
  $sk=$i*$cntzap; $i1=$i+1;
  print "<a href='javascript:doskip($sk)'>$i1</a>\&nbsp;"
 } 

}
print "<a title='Добавить' href='javascript:donew()'>Новая запись</a><br><br>";

# Вывести N записей
if ($cnt>0) {
print $header;
seek (ABOOK,0,0); $allcnt=min($cnt, $cntzap); $cnt=0; $sk=0; 
 while ( <ABOOK> ) { if ((!$filter) or ($_=~ /$filter/i)) 
                      { $sk++;
					    if ($sk>$skip)
						{
					    chomp; 
					    my ($a1, $a2, $a3) = split (/\x01/, $_, 3);
						$a2=$defcharset if (!$a2);
						$a3=$defmode if (!$a3);
print qq(
<tr><td bgcolor=#F9F1D7 class=sml>$a1</td><td bgcolor=#F9F1D7 class=sml>$a2</td>
<td bgcolor=#F9F1D7 class=sml>$a3</td><td bgcolor=#F9F1D7 class=sml><a href="#toform" onclick="javascript:doedit('$a1','$modes{"$a2"}','$modes{"$a3"}')">Edit</a></td>
<td bgcolor=#F9F1D7 class=sml><a href="javascript:dodel('$a1')" title='Удалить запись'>X</a></td></tr> 
);
						 $cnt++;
						last if ($cnt>=$allcnt);
						}
					   }
                   }
				   
print $footer;
 } #if cnt>0

print qq(
</td></tr>
</table></td></tr></table>
);
				   
}
#------------------------------------------------------
#Получить запись из адресной книжки
#Входной параметр - email
#Возвращает запись или пустую строку, если такого мыла нет в адр. книжке
#------------------------------------------------------
sub get_abook_entry {
 my $ent=shift; &read_settings if (!$abookname);
#Проверяем, есть ли такой мыл в книжке
 my $emlentry=""; my $eline=""; my $exist=0;
 open ( CONF, "$abookname" ) or $exist=0;
 while ( <CONF> ) { $eline=$_;
				   $emlentry=substr($eline, 0, index($eline,"\x01"));
				   $emlentry=$eline if (!$emlentry); 
                   if ($ent eq $emlentry) {$exist=1; last; }
                  }
close (CONF); $eline="" if ($exist==0); 
return $eline; 
}

#------------------------------------------------------
#Внесение новой записи в адресную книжку
#Входной параметр - запись
#Возвращает 0, если запись успешно внесена, 1 - если такой email уже есть в адр. книге
#------------------------------------------------------
sub save_abook_entry {
 my $entry=shift; &read_settings if (!$abookname);
#Проверяем, есть ли такой мыл в книжке
my $tstmail=substr($entry, 0, index($entry,"\x01")); 
my $exist=0; my $curentry="";
 open ( CONF, "$abookname" ) or $exist=0;
 while ( <CONF> ) {$curentry=$_;
				   $emlentry=substr($curentry, 0, index($curentry,"\x01"));
				   $emlentry=$curentry if (!$emlentry); 
                   if ($tstmail eq $emlentry) {$exist=1; last; }
                  }
close ( CONF );
if ($exist==0) {
                open ( CONF, ">>$abookname" );
                flock(CONF, LOCK_EX); print CONF "$entry\n"; close (CONF);
				}
return $exist; 
}

#------------------------------------------------------
#Удаление записи из адресной книжки
#Входной параметр - email
#Возвращает 0, если запись успешно удалена, 1 - если такого email нет в адр. книге
#------------------------------------------------------
sub delete_abook_entry {
 my $entry=shift; my $tmp=get_abook_entry($entry);
   if ($tmp ne "")
   {   chomp($tmp);
       open (CONF, "<$abookname"); my @tmpabook=<CONF>; close(CONF);
       open (CONF, ">$abookname"); flock(CONF, LOCK_EX); my $nentry; 
		foreach $nentry (@tmpabook)
		 {chomp($nentry); 
		  print CONF "$nentry\n" if ($nentry ne $tmp);
		 }
       close (CONF); return 0;
	} else {return 1;}     
}

sub put_edit_form {
 my $infomessage=shift;
 &read_settings if (!$abookname);
print qq(
<script language=javascript>
function dodel (e) {
document.mainform.newemail.value=e;
document.mainform.step.value="$deleterecord";
document.mainform.submit();
}
function doedit (e, c, m) {
showform('edit');
document.mainform.newemail.value=e;
document.mainform.oldemail.value=e;
document.mainform.charset.selectedIndex=c;
document.mainform.mode.selectedIndex=m;
document.mainform.modifybtn.value="Сохранить >>";
document.mainform.step.value="$editrecord";
}
function donew () {
showform('new');
document.mainform.newemail.value="";
document.mainform.charset.selectedIndex=$modes{"$defcharset"};
document.mainform.mode.selectedIndex=$modes{"$defmode"};
document.mainform.modifybtn.value="Добавить >>";
document.mainform.step.value="$addnew";
document.mainform.newemail.focus();
}
function doskip (sk) {
document.mainform.skip.value=sk;
document.mainform.step.value="$nextpage";
document.mainform.submit();
}
function validate ()
{
stroka=document.mainform.newemail.value; ind=stroka.indexOf('\@');
if (ind>0 && ind<stroka.length-1) {document.mainform.submit();}
else {alert('Введен неверный E-Mail');}
}
function wrDIV(tx) {
if (navigator.appName == "Netscape") 
{document.layers['nsdiv'].document.writeln(tx); document.layers['nsdiv'].document.close();}
else { mydiv.innerHTML=tx;}
}
function showform(mode) {
if (mode=='new') {
stroka="<font size='-1' face='Verdana, Arial' color=blue><b>Добавление новой записи</b></font>";
}
else {
stroka="<font size='-1' face='Verdana, Arial' color=red><b>Редактирование записи</b></font>";
}
wrDIV(stroka);
}
</script>
<table width=600 border=0 cellspacing=0 cellpadding=0 bgcolor=black ><tr><td><table width=600 border=0 cellspacing="1" cellpadding=1>
<tr><th bgcolor=#FEF0CD align=left>
);
if ($ENV{'HTTP_USER_AGENT'} =~ /MSIE/i) {
print "<div id=mydiv><font size='-1' face='Verdana, Arial'><b>Добавление новой записи</b></font></div>";
} else {print "\&nbsp;";}

print qq(
</th></tr>
<tr><td bgcolor=#F9F1D7 align=left><font size='-1' face='Verdana, Arial'>E-Mail:
<input type=text name=newemail value='' style="{font: 8pt 'Verdana'; border: outset 1px; width: 300;}">
<select name=charset style="{font: 8pt 'Verdana'; border: outset 1px; width: 58;}">
<option value=win>Win<option value=koi selected>Koi8<option value=iso>Iso</select><select name=mode style="{font: 8pt 'Verdana'; border: outset 1px; width: 57;}">
<option value=txt selected>txt<option value=html>html</select>
<input type=button value='Добавить>>' onclick='validate()' name=modifybtn style="{font: 8pt 'Verdana'; color:blue; border: outset 1px; width: 90;}">
</font></td></tr></table></td></tr></table><br>
);
&put_message($infomessage) unless (!$infomessage);
}


#Проверка email на валидность
sub valid_email {
my $ve=shift;
if  ($ve !~ /([\w,\-,\.]+\@[\w,\-,\.]+\.\w{2,3})/) {return 0;} else {return 1;}
}

# Проверка почтового адреса на стоп символы
sub mailstop {
    my $stopmail=shift;
    if ($stopmail=~ tr/\/\\\+=~;<>*|`&$!#()[]{}:'" //) {
        return 1;                                   # есть стоп символы (1) !!!
    } else {return 0;}
}

sub min {
my ($a,$b)=@_;
if ($a<$b) {return $a;} else {return $b;}
}

1;