$cache = "/somedir/cache.dat"; #cache file StorePath $lockfile = "/somedir/locks.dat"; #lock file store path #remoteの場合は、from,to #localの場合は、procmailrcの場所を指定する @post_tos =( 'remote someaddr@somedomain someaddr_to@somedomain_to', 'local procmailrcs.file', ); %commands =( 'sendmail' => '/usr/sbin/sendmail', 'procmail' => '/usr/bin/procmail', ); $locktimeout = 10; $lockflag = 0; require './somedir/mimer.pl'; #mimer.pl必須 &lock_rootin($lockfile,$locktimeout); &make_cache; foreach (@post_tos) { ($deli,$from,$to) = split(/\t/,$_); if ($deli eq "remote") { &go_send_remote($from,$to); } elsif ($deli eq "local") { &go_send_local($from); } } sub make_cache { open(OUT,">$cache") or &errors; while() { print OUT $_; } close(OUT); } sub go_send_local { my($from,$rcptto) = @_; my($cmd) = $commands{'procmail'}; #| /usr/bin/procmail -m ./.procmailrc open(OUT,"| $cmd -m $from") or &errors; open(IN,"$cache"); while() { print OUT $_; } close(IN); close(OUT); } sub go_send_remote { my($from,$rcptto) = @_; my($skip_header,$get_fromheader,$header_ended,$headers,$check_header,$head_data,$orgfrom,$fromheaders,$origin_post); $header_ended = 0; $origin_post = 0; my($cmd) = $commands{'sendmail'}; open(OUT,"| $cmd $rcptto") or &errors; open(IN,"$cache"); print OUT "To: <$rcptto>" . "\n"; print OUT "From: <$from>" . "\n"; $skip_header = 0; $get_fromheader = 0; while() { if ($header_ended == 0) { #--- MDA nara cr delete ga yuukou. ---- if ($_ eq "\n") { $header_ended = 1; if ($headers ne "") { print OUT $headers; } $headers =""; } else { if ($_ =~ m/^(.*?):\s(.*?)\n$/) { $skip_header = 0; $check_header = $1; $head_data = $2; if ($headers ne "") { print OUT $headers; } $headers =""; if ($get_fromheader == 1) { $get_fromheader = 0; $orgfrom = &decode_mime($fromheaders); } if ($check_header =~ /^Return-Path/i) { $skip_header = 1; next; } if ($check_header =~ /^Delivered-To/i) { $skip_header = 1; next; } if ($check_header =~ /^X-Original-To/i) { $skip_header = 1; next; } if ($check_header =~ /^Delivered-To/i) { $skip_header = 1; next; } if ($check_header =~ /^Cc/i) { $skip_header = 1; next; } if ($check_header =~ /^To/i) { $skip_header = 1; next; } if ($check_header =~ /^From/i) { $get_fromheader = 1; $skip_header = 1; $fromheaders .= $head_data . "\n"; next; } $headers .= $_; next; } elsif($skip_header == 1) { if ($get_fromheader == 1) { $fromheaders .= $_; } next; } else { $headers .= $_; } } } elsif($origin_post == 0) { print OUT "\n"; print OUT "This is Mail Transfer Program.\n"; print OUT "Original from: " . $orgfrom . "\n"; $origin_post = 1; print OUT $_; } else { print OUT $_; } } close(IN); close(OUT); } unlink($cache); &end_lock; sub decode_mime { my($orgfrom) = $_[0]; my($mimes) = "=?ISO-2022-JP"; if ($orgfrom =~ m/$mimes/) { $decode_from = &mimedecode($orgfrom); return($decode_from); } return($orgfrom); } sub errors { if ($lockflag != 0) { &end_lock; } exit 1; } sub lock_rootin { my($tmppath,$locktimeout) = @_; $lockflag++; if (-e $tmppath ) { open(LOCK, "$tmppath") or &errors; } else { open(LOCK,">$tmppath") or &errors; } eval { $lockstart = 1; local $SIG{ALRM} = sub { die "time out" }; # 時間が来たら抜け出す alarm($locktimeout); # 制限時間 flock(LOCK, 2); alarm(0); }; if ($@ =~ /time out/) { $lockstart = 0; &end_lock; &errors; } } sub end_lock { local($i); for ($i = 1; $i <= $lockflag ; $i++) { if ($i == 1 ) { flock(LOCK,8); close(LOCK); } if ($i == 2 ) { flock(LOCK2,8); close(LOCK2); } if ($i == 3 ) { flock(LOCK3,8); close(LOCK3); } if ($i == 4 ) { flock(LOCK4,8); close(LOCK4); } } $lockflag = 0; }