#!/usr/bin/perl

#############################################################
$nam  = 'Multi::Mail';                                      #
$cod  = 'Hyper Mailer eXpert';                              #
$scr  = 'hmx.cgi';                                          #
$ver  = 'series 12.05E ';                                   #
$url  = 'http://magokorokikaku.com/moeya';                  #
$cpr  = 'Copyright (c) MagokoroPlanning';                   #
$adm  = 'postmaster@magokorokikaku.com';                    #
#############################################################








































#************************************************************
#  バージョン表示
#************************************************************

$copyright = <<"HERE";
<address id="copy">
<a href="$scr?magokoro" title="スクリプト情報">
$nam</a>
</address>
HERE


#************************************************************
#  モード判別
#************************************************************

&decode;
if ($mode eq 'regist')   { &check; }
if ($mode eq 'send')     { &sendmail; }
if ($mode eq 'magokoro') { &magokoro; }
&html;


#************************************************************
#  decode
#************************************************************
sub decode {

#設定ファイルの読込
  require './cfg.pl';

#文字コード変換モジュールの使用を宣言
# use Jcode;
  require 'Jcode.pm';

# 引数を解釈
  $mode = $ENV{'QUERY_STRING'};
  $mode =~ s/\W//g;

  $charset  =~ s/-JP|-jp//g;
  $charset  =~ s/-8/8/g;
  $charset  =~ s/UTF/utf/g;
  $charset  =~ s/EUC/euc/g;
  $charset  =~ s/JIS/jis/g;
  $charset  =~ s/Shift/shift/g;
  $charset  =~ s/x-/shift-/g;
  $charset  =~ s/sjis/shift-jis/g;
  $charset  =~ s/ISO-2022/jis/g;
  $charset  =~ s/iso-2022/jis/g;

# フォームから送られたデータをデコード
  read STDIN,$input,$ENV{'CONTENT_LENGTH'};

  @pairs = split(/&/,$input); 
  foreach $pair (@pairs) {
    ($list, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

    if ($charset eq 'utf8')
     { $value = Jcode->new($value, "utf8")->euc; }
    elsif ($charset eq 'euc')
     { $value = Jcode->new($value ,"euc")->euc; }
    elsif ($charset eq 'jis')
     { $value = Jcode->new($value ,"jis")->euc; }
    elsif ($charset eq 'shift-jis')
     { $value = Jcode->new($value ,"sjis")->euc; }
    else
     { &codeerror; }

    $FORM{$list} = $value;
  }
  $name    = $FORM{'name'};
  $name    = Jcode->new($name ,"euc")->sjis;
  $from    = $FORM{'from'};
  $subject = $FORM{'subject'};
  $comment = $FORM{'comment'};
}


#************************************************************
#  メールフォームを表示
#************************************************************
sub html {

  if (!$mustnam){$thnam2 ="$thnam $mk"; }
  else {$thnam2 ="$thnam&nbsp;&nbsp;"; }

  if (!$mustadr){$thadr2 ="$thadr $mk"; }
  else {$thadr2 ="$thadr&nbsp;&nbsp;"; }

  if (!$mustsub){$thsub2 ="$thsub $mk"; }
  else {$thsub2 ="$thsub&nbsp;&nbsp;"; }

  if (!$mustmes){$thmes2 ="$thmes $mk"; }
  else {$thmes2 ="$thmes&nbsp;&nbsp;"; }

  if (($mustnam)&&($mustadr)&&($mustsub)&&($mustmes)){
  $caption = '';
  }
  else {
  $caption = "<tr>
    <td></td>
    <td class=\"caption\">
     $captxt
    </td>
  </tr>";
  }

$form = <<"HERE";
<div id="mail">
$text
<form method="post" action="$scr?regist">
<table>
  <tr>
    <th><label for="name">$thnam2</label></th>
    <td><input id="name" type="text" name="name" class="txt" /></td>
  </tr>
  <tr>
    <th><label for="from">$thadr2</label></th>
    <td><input id="from" type="text" name="from" class="txt" /></td>
  </tr>
  <tr>
    <th><label for="subj">$thsub2</label></th>
    <td><input id="subj" type="text" name="subject" class="txt" /></td>
  </tr>
  <tr>
    <th><label for="comm">$thmes2</label></th>
    <td><textarea id="comm" name="comment" wrap="soft"></textarea></td>
  </tr>
  $caption
  <tr>
    <td></td>
    <td>
      <input type="submit" value="$submittext" class="button" />
    </td>
  </tr>
 </table>
</form>
$text2
</div>
HERE

# テンプレートファイルが存在するなら、それを利用する
 if ( -e "$tmpfile" ){
  $body  = "$title\n";
  $body .= "$form\n";
  $body .= "$copyright\n";
  &convert;
  &tmpuse;
  }

# ブラウザに出力
  print "Content-type: text/html\n\n";
  $body  = "$head\n";
  $body .= "$title\n";
  $body .= "$form\n";
  $body .= "$copyright\n";
  $body .= "$footer\n";
  &convert;
  print "$body";

exit;
}


#************************************************************
#　入力内容のチェック
#************************************************************
sub check {

# 呼び出し元のチェック
  if ( $refcheck ){
    if($ENV{HTTP_REFERER} !~ m/^$ref_url/){
      if($ENV{HTTP_REFERER} !~ m/^$cgi_url/)
        {&mailerror('不正な呼び出しです。'); }
    }
  }

#送信者名
  if (($name eq "")&&($mustnam))
  {$name = "$nanasi"; }
  elsif ($name eq "")
  {&mailerror("大変\申\し訳ありません。$thnamは必ず入力してください。"); }

#メールアドレス
  if (($from eq "")&&($mustadr))
  {$from = "$mailto"; }
  elsif ($from eq "")
  {&mailerror("大変\申\し訳ありません。$thadrは必ず入力してください。"); }

 #【メールアドレスの正規表現】
 # 　 大崎博基様の公開されているソースをそのまま利用させて頂いております。
 #    →http://www.din.or.jp/~ohzaki/index.htm
  $mail_regex =
  q{(?:[^(\040)<>@,;:".\\\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\\} .
  q{\[\]\000-\037\x80-\xff])|"[^\\\\\x80-\xff\n\015"]*(?:\\\\[^\x80-\xff][} .
  q{^\\\\\x80-\xff\n\015"]*)*")(?:\.(?:[^(\040)<>@,;:".\\\\\[\]\000-\037\x} .
  q{80-\xff]+(?![^(\040)<>@,;:".\\\\\[\]\000-\037\x80-\xff])|"[^\\\\\x80-} .
  q{\xff\n\015"]*(?:\\\\[^\x80-\xff][^\\\\\x80-\xff\n\015"]*)*"))*@(?:[^(} .
  q{\040)<>@,;:".\\\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\\\[\]\0} .
  q{00-\037\x80-\xff])|\[(?:[^\\\\\x80-\xff\n\015\[\]]|\\\\[^\x80-\xff])*} .
  q{\])(?:\.(?:[^(\040)<>@,;:".\\\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,} .
  q{;:".\\\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\\\x80-\xff\n\015\[\]]|\\\\[} .
  q{^\x80-\xff])*\]))*};
  
 # $from が正しいメールアドレス(addr_spec)か判定する
  if ($from !~ /^$mail_regex$/o)
  {&mailerror('不正なメールアドレスです。'); }


#件名
  if (($subject eq "")&&($mustsub))
  {$subject = "$mudai"; }
  elsif ($subject eq "")
  {&mailerror("大変\申\し訳ありません。$thsubは必ず入力してください。"); }

#メール本文
  if (($comment eq "")&&($mustmes)) 
  {$comment = "入力無し"; }
  elsif ($comment eq "")
  {&mailerror("大変\申\し訳ありません。$thmesは必ず入力してください。"); }
  elsif (($comment =~ /\<\/a\>/)||($comment =~ /\<\/A\>/))  
  {&mailerror("$thmes内でアンカータグを用いているものはスパムと判断し、送信できない仕様になっております。"); }

# 汚染チェック
  $from    =~ s/\r|\n//g;
  $mailto  =~ s/\r|\n//g;

  if ($kakunin){&kakunin;}
  &sendmail;
}


#************************************************************
#  送信前の確認画面
#************************************************************
sub kakunin {

  $name = Jcode->new($name)->sjis;
  $subject = Jcode->new($subject)->sjis;
  $comment = Jcode->new($comment)->sjis;

  if ($from eq "$mailto"){$adr ='入力無し';}
  else {$adr ="$from";}

  $comment =~ s/\n/\<br \/\>/g;
  $reform = <<"HERE";
  <h2>送信前確認</h2>
  <form method="post" action="$scr?send">
  <div id="mail">
  <table id="check_table">
    <tr>
      <th>$thnam</th>
      <td>$name&nbsp;様<input type="hidden" name="name" value="$name" /></td>
    </tr>
    <tr>
      <th>$thadr</th>
      <td>$adr<input type="hidden" name="from" value="$from" /></td>
    </tr>
    <tr>
      <th>$thsub</th>
      <td>$subject<input type="hidden" name="subject" value="$subject" /></td>
    </tr>
    <tr>
      <th>$thmes</th>
      <td>$comment<input type="hidden" name="comment" value="$comment" /></td>
    </tr>
  </table>
  <p>以上の内容で誤りが無ければ、『$submittext』ボタンを押して下さい。</p>
  <input type="submit" value="$submittext" class="button" /><br />
  <input type="button" value="$teisei" onClick="history.back()" class="button" />
  </div>
  </form>
HERE

# テンプレートファイルが存在するなら、それを利用する
 if ( -e "$tmpfile" ){
  $body  = "$title\n";
  $body .= "$reform\n";
  $body .= "$copyright\n";
  &convert;
  &tmpuse;
  }

# ブラウザに出力
  print "Content-type: text/html\n\n";
  $body  = "$head\n";
  $body .= "$title\n";
  $body .= "$reform\n";
  $body .= "$copyright\n";
  $body .= "$footer\n";
  &convert;
  print "$body";

exit;
}


#************************************************************
#  sendmail処理
#************************************************************
sub sendmail {

#文字コードを適切な形式に変換
  $top = Jcode->new($top ,"sjis")->euc;
  $subject1 = "$top $subject";
  $subject1 = &mail64encode($subject1);
  if ($from eq "$mailto")
  {$name1 = "$name （アドレス未記入）"; }
  else {$name1 = "$name"; }
  $name1 = &mail64encode($name1);
  $comment =~ s/\<br \/\>//g;
  $comment = Jcode->new($comment)->jis;
  $h1      = '送信日時 : ';
  $h1      = Jcode->new($h1)->jis;
  $h2      = 'ホスト名 : ';
  $h2      = Jcode->new($h2)->jis;

# ホスト名、送信時間を取得
  $ip   = $ENV{'REMOTE_ADDR'};
  $host = gethostbyaddr(pack("C4", split('\.', $ip)), 2) || $ip;
  @tim  = localtime(time());
  $year = $tim[5] + 1900;
  $mon  = $tim[4] + 1;
  $t    = sprintf('%02d:%02d:%02d', $tim[2], $tim[1], $tim[0]);
  $date = "$year/$mon/$tim[3] $t";

# ホストチェック
  if($dame[0] ne ''){
    foreach(@dame){
      if($host =~ /$_/){
        &mailerror("何らかの原因で送信できません。");
      }
    }
  }

# アドレスチェック
  if($iya[0] ne ''){
    foreach(@iya){
      if($from =~ /$_/){
        &mailerror("何らかの原因で送信できません。");
      }
    }
  }

# プライオリティ
  if($priority){$juuyou ="X-Priority: $priority\n"; }
  else{ $juuyou =""; }

# 連続投稿チェック
  &rennzoku;

# sendmailにデータを渡す
  if (!(open(MAIL,"| $sendmail -t"))) { &mailerror('何らかの原因で送信できません。'); }
	print MAIL "To: $mailto\n";
	print MAIL "From: $name1<$from>\n";
	print MAIL "Subject: $subject1\n";
	print MAIL "MIME-Version: 1.0\n";
	print MAIL "Content-Type: text/plain; charset=\"ISO-2022-JP\"\n";
	print MAIL "Content-Transfer-Encoding: 7bit\n";
	print MAIL "$juuyou\n";
	print MAIL "$comment\n";

  if ($hostget){
	print MAIL "\n\n\n";
	print MAIL "---------------------------------------\n";
	print MAIL "$h1$date\n";
	print MAIL "$h2$host\n";
  }

  close(MAIL);

# 自動返信
  if (($autore) && ($from ne "$mailto")){&autore; }

#ログデータ作成
  if ($loging){ &loging; }

# 完了表示
  &mailend;
}


#************************************************************
#  自動返信
#************************************************************
sub autore {

#文字コードを適切な形式に変換
  $subject2 = &mail64encode($subject2);
  $name2 = "$name 様";
  $name2 = &mail64encode($name2);
  $retxt =~ s/==お名前==/$name/g;
  $retxt =~ s/==送信日時==/$date/g;
  $quout = "\>$comment";
  $quout =~ s/\n/\n\>/g;
  $retxt = Jcode->new($retxt)->jis;

# sendmailにデータを渡す
  if (!(open(MAIL,"| $sendmail -t"))) { &mailerror('何らかの原因で送信できません。'); }
	print MAIL "To: $name2<$from>\n";
	print MAIL "From: $mailto\n";
	print MAIL "Subject: $subject2\n";
	print MAIL "MIME-Version: 1.0\n";
	print MAIL "Content-Type: text/plain; charset=\"ISO-2022-JP\"\n";
	print MAIL "Content-Transfer-Encoding: 7bit\n";
	print MAIL "\n";
	print MAIL "$retxt\n";

  close(MAIL);

# 完了表示
  &mailend;
}


#************************************************************
#  連続投稿チェック
#************************************************************
sub rennzoku {

# チェックファイルが存在しなければ作成する
  if (! -e "check.dat"){
    open (FILE , ">>check.dat") ;
    close (FILE) ;
  }

  $dumm = '';
  $wait = '300';
  $ENV{'TZ'} = "JST-9";
  $times = time;

# チェックファイルからデータの読み込み
  open(IN,"+<check.dat") || &mailerror("Open Error: $logfile");
  @data=<IN>;
  close (IN) ;
  foreach (@data) {
    local($dm,$ch,$ct) = split(/<>/);
    if (($ch eq $host) && ($times - $ct < $wait)) {
&mailerror("一度メール送信すると、その後５分間は投稿を受け付けない仕様です。");
    }
  }

# 新規データの成形
  while (3 <= @data) { pop(@data); }
  unshift(@data,"$dumm<>$host<>$times\n");

# ログファイルに書き込み
  open(OUT,"+<check.dat") || &mailerror("Open Error: $logfile");
  print OUT "@data";
  close (OUT) ;
}


#************************************************************
#  ログ生成
#************************************************************
sub loging {

# ログファイルはShift-JISで保存する
  $log0 = Jcode->new($name)->sjis;
  $log2 = Jcode->new($subject)->sjis;
  $log3 = Jcode->new($comment)->sjis;

# ログファイルが存在しなければ作成する
  if (! -e "$logfile"){
    open (FILE , ">>$logfile") ;
    close (FILE) ;
  }

  $date = "$year/$mon/$tim[3] $t";
  if ($from eq $mailto){ $log1='記入無し'; }
  else{ $log1="$from"; }

# ログファイルからデータの読み込み
  open(IN,"+<$logfile") || &mailerror("Open Error: $logfile");
  @data=<IN>;
  close (IN) ;

# 新規データの成形
  while (50 <= @data) { pop(@data); }
  unshift(@data,"$log0<>$log1<>$log2<>$log3<>$host<>$date\n");

# ログファイルに書き込み
  open(OUT,"+<$logfile") || &mailerror("Open Error: $logfile");
  flock(OUT, 2);
  print OUT "@data";
  flock(OUT, 8);
  close (OUT) ;
}


#************************************************************
# 完了表示
#************************************************************
sub mailend {

$i = int(rand(5));

# テンプレートファイルが存在するなら、それを利用する
 if ( -e "$tmpfile" ){
  $body  = "$title\n";
  $body .= "$thank\n";
  $body .= "<p style=\"text-align:center;\">$img[$i]</p>\n";
  $body .= "<p><a href=\"$home\">$back</a></p>\n";
  $body .= "$copyright\n";
  &convert;
  &tmpuse;
  }

# ブラウザに出力
  print "Content-type: text/html\n\n";
  $body  = "$head\n";
  $body .= "$title\n";
  $body .= "$thank\n";
  $body .= "<p style=\"text-align:center;\">$img[$i]</p>\n";
  $body .= "<p><a href=\"$home\">$back</a></p>\n";
  $body .= "$copyright\n";
  $body .= "$footer\n";
  &convert;
  print "$body";

exit;
}


#************************************************************
# エラー表示
#************************************************************
sub mailerror {

# テンプレートファイルが存在するなら、それを利用する
 if ( -e "$tmpfile" ){
  $body  = "$title\n";
  $body .= "$errtext\n";
  $body .= "<p>$_[0]</p>\n";
  $body .= "<p><a href=\"javascript:history.back()\">$back</a></p>\n";
  $body .= "$copyright\n";
  &convert;
  &tmpuse;
  }

# ブラウザに出力
  print "Content-type: text/html\n\n";
  $body  = "$head\n";
  $body .= "$title\n";
  $body .= "$errtext\n";
  $body .= "<p>$_[0]</p>\n";
  $body .= "<p><a href=\"javascript:history.back()\">$back</a></p>\n";
  $body .= "$copyright\n";
  $body .= "$footer\n";
  &convert;
  print "$body";

exit;
}


#************************************************************
#  BASE64変換
#************************************************************
 # 　 とほほ様の公開されているソースをそのまま利用させて頂いております。
 #    →http://www.tohoho-web.com/
sub mail64encode {
  local($str) = $_[0];
  $str = Jcode->new($str)->jis;
  $str =~ s/\x1b\x28\x42/\x1b\x28\x4a/g;
  $str = &base64encode($str);
  return("=?iso-2022-jp?B?$str?=");
}

sub base64encode {
  local($base) = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
               . "abcdefghijklmnopqrstuvwxyz"
               . "0123456789+/";
  local($xx, $yy, $zz, $i);
  $xx = unpack("B*", $_[0]);
  for ($i = 0; $yy = substr($xx, $i, 6); $i += 6) {
    $zz .= substr($base, ord(pack("B*", "00" . $yy)), 1);
    if (length($yy) == 2) {
      $zz .= "==";
    } elsif (length($yy) == 4) {
      $zz .= "=";
    }
  }
  return($zz);
}


#************************************************************
#  文字コード判別
#************************************************************
sub convert {

  if ($charset eq 'utf8') { $body  = Jcode->new($body)->utf8; }
  elsif ($charset eq 'euc') { $body  = Jcode->new($body)->euc; }
  elsif ($charset eq 'jis') { $body  = Jcode->new($body)->jis; }
  elsif ($charset eq 'shift-jis') { $body  = Jcode->new($body)->sjis; }
  else { &codeerror; }
}


#************************************************************
# テンプレートを利用する
#************************************************************
sub tmpuse {

  print "Content-type: text/html\n\n";
  open(IN,"$tmpfile");
  while (<IN>) {
    s/\$entries/$body/;

    print;
  }
  close(IN);

  exit;
}


#************************************************************
# 文字コード設定エラー
#************************************************************
sub codeerror {

  print "Content-type: text/html\n\n";
  print <<"EOM";
<!DOCTYPE html PUBliC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=shift-jis" /><title>文字コード設定エラー</title></head>
<body><h1>文字コード設定エラー</h1>
<h2>不正な文字コードがスカラー変数 \$charset で指定されております</h2>
<pre>
使用できる文字コードは <strong>shift-jis, jis, euc, utf-8</strong> の４種類です。
必ず半角アルファベットの小文字で指定してください。
</pre></body></html>

EOM

exit;
}


#************************************************************
#  バージョン情報
#************************************************************
sub magokoro {

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

  $body = <<"HERE";
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=$charset" />
<meta http-equiv="Content-script-Type" content="text/javascript" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="$nam; $url" />
<title>$nam</title>
<link rel="start" href="$home" title="Home" />
<link rel="stylesheet" href="$css" type="text/css" />
<script type="text/javascript">
 function netabare(id){
   if( document.getElementById(id).style.display != "block" ){
     document.getElementById(id).style.display="block";
  }else{
     document.getElementById(id).style.display="none";
   }
  }
</script>
$style
<style type="text/css">
  \@import "$url/multi/style.css";
  .netabare{display:none;margin-top:0.5em;}
</style>
</head>
<body>
<h1>$nam</h1>
<h2>スクリプト情報</h2>
<p class="info">
【名称】 $nam<br />
【開発コード】 $cod<br />
【バージョン】 $ver<br />
【著作権】 Copyright (c) 来栖川重工 / 真心企画 / 萌屋本舗<br />
【WEBサイト】 <a href="$url/moeya_top.htm">$url/</a>
</p>
<ul>
<li>当スクリプトの著作権は作者及び関連団体が保有します。</li>
<li>本製品を使用して起こったいかなる損害も作者は一切の責任を負いません。</li>
<li>バグ報告などは大歓迎です。上記 URL までお願いします。できる限り対応したいと思います。</li>
</ul>
<input type="button" value="機能\紹介" onclick="netabare('cm');return false;" />
<ul id="cm" class="netabare">
<li>Unicode(UTF-8)も出力&amp;処理可能\。Blogでの運用にも最適です。</li>
<li>たった二つのファイルで動作。初心者でも設置が楽ちんです。</li>
<li>送信前にプレビュー画面を表\示できます。</li>
<li>自動返信機能\実装。</li>
<li>送信ログの記録可能\。</li>
<li>必須入力と任意入力の切り替えはワンタッチで可能\。</li>
<li>htmlテンプレート(俗に言うスキン)も使用可能\です。デザインのカスタムもこれで自在です。</li>
<li>件名の先頭に任意の文字列を挿入可能\。フォルダ分け等に便利です。</li>
<li>送信者のリモートホストをメールの末尾に記録して送信いたします。</li>
<li>指定したリモートホストからの送信を禁止できます。</li>
<li>指定したメールアドレスからの送信を禁止できます。</li>
<li>送信するメールの重要度を任意に設定可能\。</li>
<li>重複送信を防止するように、送信後5分間は同一IPからの送信をブロックします。</li>
</ul>

<p class="module">
【<strong>使用モジュール</strong>】<br />
Jcode module Version $Jcode::VERSION<br />
Copyright (c) 小飼弾<br />
<a href="http://openlab.ring.gr.jp/Jcode/index-j.html" title="Jcode公式サイト">http://openlab.ring.gr.jp/Jcode/index-j.html</a><br />
 <a href="http://www.ring.gr.jp/pub/lang/perl/CPAN/modules/by-module/Encode/DANKOGAI/" title="CAPAN">http://www.ring.gr.jp/pub/lang/perl/CPAN/modules/by-module/Encode/DANKOGAI/ </a>
</p>
<p class="back"><a href="javascript:history.back()">$back</a></p>
</body>
</html>
HERE

  &convert;
  print "$body";

exit;
}


__END__
