更改配置为卫星电子邮件系统的服务器的 IP 后,我忘记mynetworks
在邮件服务器上进行更新以允许代表新 IP 地址发送电子邮件。
这就是为什么上周有大量电子邮件被发送到 /var/spool/mail/ 并带有软退回通知的原因未送达的邮件退回给发件人直到我们注意到了这个问题并修复了邮件服务器配置。
现在我们想将退回的电子邮件重新发送给原始收件人。这意味着解析 /var/spool/mail/* 处的文件并提取原始电子邮件,然后再次使用原始邮件头发送它们。该怎么做?
答案1
我编写了一个 PHP 脚本来解析 /var/spool/mail/ 文件,以便重新发送带有原始邮件头的退回邮件。请注意根据您的需要更改第一行的配置。
<?php
DEFINE('SIMPLIFIEDBOUNDARYCHECK', '/hostxx.mydomain.tld--');
DEFINE('TEST', true);
DEFINE('TESTRECEIVER', '[email protected]');
$excludeReceiver = array('[email protected]');
function startsWith($haystack, $needle) {
return $needle === "" || strpos($haystack, $needle) === 0;
}
function endsWith($haystack, $needle) {
return $needle === "" || substr($haystack, -strlen($needle)) === $needle;
}
if(!isset($argv[1])) {
die("resend mails: filename argument missing, e.g. /var/spool/mail/www-data");
}
$filename = $argv[1];
$handle = fopen($filename, "r");
if(!$handle)
die("$filename could not be opened");
$state = 0;
$mail = NULL;
while(($line = fgets($handle)) !== false) {
switch($state) {
case 0:
if(startsWith($line, 'Content-Description: Undelivered Message')) {
$state = 1;
$mail = new Mail();
}
break;
case 1: // pre-header
$trimmedLine = trim($line);
if(empty($trimmedLine)) {
$state = 2;
break;
}
break;
case 2: // header
$trimmedLine = trim($line);
if(empty($trimmedLine)) {
$state = 3;
break;
}
$mail->readHeader($line);
// echo $line;
break;
case 3:
// body
if(endsWith(trim($line), SIMPLIFIEDBOUNDARYCHECK)) {
$state = 0;
$mail->send();
break;
}
$mail->appendBody($line);
}
}
fclose($handle);
class Mail {
private $to;
private $subject;
private $body = '';
private $extraHeader = '';
public function readHeader($line) {
if(startsWith($line, 'To: ')) {
$this->to = substr(trim($line), 4);
}else if(startsWith($line, 'Date: ') || startsWith($line, 'From: ') || startsWith($line, 'Content-Type: ') || startsWith($line, ' boundary="') || startsWith($line, 'MIME-Version:')) {
$this->extraHeader .= $line;
}else if(startsWith($line, 'Subject: ')) {
$this->subject = substr(trim($line), 9);
}
}
public function appendBody($line) {
$this->body .= $line;
}
public function send() {
global $excludeReceiver;
if(in_array($this->to, $excludeReceiver)) {
echo "Suppressed To: $this->to, Subject: " . $this->subject . "\n";
return;
}
$receiver = TEST ? TESTRECEIVER : $this->to;
echo "To: $receiver, Subject: " . $this->subject . "\n";
mail($receiver, $this->subject, $this->body, $this->extraHeader);
}
}