- improve autoresponder-cron, refs #308
- let phpMailer-Class throw its exception so we can catch them
This commit is contained in:
@@ -21,45 +21,33 @@
|
|||||||
* @todo skip mail parsing after x bytes for large mails
|
* @todo skip mail parsing after x bytes for large mails
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$mail = new PHPMailer();
|
$mail = new PHPMailer(true);
|
||||||
|
|
||||||
//dont do anything when module is disabled
|
//dont do anything when module is disabled
|
||||||
|
|
||||||
if((int)$settings['autoresponder']['autoresponder_active'] == 0)
|
if((int)$settings['autoresponder']['autoresponder_active'] == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//only send autoresponder to mails which were delivered since last run
|
//only send autoresponder to mails which were delivered since last run
|
||||||
|
|
||||||
if((int)$settings['autoresponder']['last_autoresponder_run'] == 0)
|
if((int)$settings['autoresponder']['last_autoresponder_run'] == 0)
|
||||||
{
|
{
|
||||||
//mails from last 5 minutes, otherwise all mails will be parsed -> mailbomb prevention
|
//mails from last 5 minutes, otherwise all mails will be parsed -> mailbomb prevention
|
||||||
|
|
||||||
$cycle = 300;
|
$cycle = 300;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// calculate seconds since last check
|
||||||
$cycle = time() - (int)$settings['autoresponder']['last_autoresponder_run'];
|
$cycle = time() - (int)$settings['autoresponder']['last_autoresponder_run'];
|
||||||
|
|
||||||
//prevent mailbombs when cycle is bigger than two days
|
//prevent mailbombs when cycle is bigger than two days
|
||||||
|
|
||||||
if($cycle > (2 * 60 * 60 * 24))$cycle = (60 * 60 * 24);
|
if($cycle > (2 * 60 * 60 * 24))$cycle = (60 * 60 * 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set last_autoresponder_run
|
||||||
$db->query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = '" . (int)time() . "' WHERE `settinggroup` = 'autoresponder' AND `varname` = 'last_autoresponder_run'");
|
$db->query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = '" . (int)time() . "' WHERE `settinggroup` = 'autoresponder' AND `varname` = 'last_autoresponder_run'");
|
||||||
|
|
||||||
/*
|
// get all customer set ip autoresponders
|
||||||
//can be used for later usage if autoresponders should be only active in a defined period
|
|
||||||
|
|
||||||
//This query has to disable every autoresponder entry which ended in the past
|
|
||||||
$db->query("UPDATE `autoresponder` SET `enabled` = 0 WHERE `to` < CURDATE()");
|
|
||||||
|
|
||||||
//This query has to activate every autoresponder entry which starts today
|
|
||||||
$db->query("UPDATE `autoresponder` SET `enabled` = 1 WHERE `from` = CURDATE()");
|
|
||||||
*/
|
|
||||||
//getting all mailboxes where autoresponders are active and configured
|
|
||||||
|
|
||||||
$result = $db->query("SELECT * FROM `" . TABLE_MAIL_AUTORESPONDER . "` INNER JOIN `" . TABLE_MAIL_USERS . "` ON `" . TABLE_MAIL_AUTORESPONDER . "`.`email` = `" . TABLE_MAIL_USERS . "`.`email` WHERE `enabled` = 1");
|
$result = $db->query("SELECT * FROM `" . TABLE_MAIL_AUTORESPONDER . "` INNER JOIN `" . TABLE_MAIL_USERS . "` ON `" . TABLE_MAIL_AUTORESPONDER . "`.`email` = `" . TABLE_MAIL_USERS . "`.`email` WHERE `enabled` = 1");
|
||||||
|
|
||||||
if($db->num_rows($result) > 0)
|
if($db->num_rows($result) > 0)
|
||||||
@@ -78,31 +66,40 @@ if($db->num_rows($result) > 0)
|
|||||||
// already ended
|
// already ended
|
||||||
if($ts_end != -1 && $ts_end < $ts_now) continue;
|
if($ts_end != -1 && $ts_end < $ts_now) continue;
|
||||||
|
|
||||||
|
// setup mail-path (e.g. /var/customers/mail/[loginname]/[user@domain.tld]/new
|
||||||
$path = $row['homedir'] . $row['maildir'] . "new/";
|
$path = $row['homedir'] . $row['maildir'] . "new/";
|
||||||
|
|
||||||
|
// if the directory does not exist, inform syslog
|
||||||
if(!is_dir($path))
|
if(!is_dir($path))
|
||||||
{
|
{
|
||||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "Error accessing maildir: " . $path);
|
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "Error accessing maildir: " . $path);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$files = scandir($path);
|
// get all files
|
||||||
foreach($files as $entry)
|
$its = new RecursiveIteratorIterator(
|
||||||
|
new RecursiveDirectoryIterator($path)
|
||||||
|
);
|
||||||
|
|
||||||
|
$responded_counter = 0;
|
||||||
|
foreach ($its as $fullFilename => $it )
|
||||||
{
|
{
|
||||||
if($entry == '.'
|
if($it->getFilename() == '.' || $it->getFilename() == '..')
|
||||||
|| $entry == '..')continue;
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* is the time passed between now and
|
* is the time passed between now and
|
||||||
* the time we received the mail lower/equal
|
* the time we received the mail lower/equal
|
||||||
* than our cycle-seconds?
|
* than our cycle-seconds?
|
||||||
*/
|
*/
|
||||||
if(time() - filemtime($path . $entry) <= $cycle)
|
$filemtime = $it->getMTime();
|
||||||
|
if(time() - $filemtime <= $cycle)
|
||||||
{
|
{
|
||||||
$content = file($path . $entry);
|
$content = file($fullFilename);
|
||||||
|
|
||||||
//error reading mail contents
|
|
||||||
|
|
||||||
|
// error reading mail contents or just empty
|
||||||
if(count($content) == 0)
|
if(count($content) == 0)
|
||||||
{
|
{
|
||||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "Unable to read mail from maildir: " . $entry);
|
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "Unable to read mail from maildir: " . $entry);
|
||||||
@@ -117,53 +114,48 @@ if($db->num_rows($result) > 0)
|
|||||||
foreach($content as $line)
|
foreach($content as $line)
|
||||||
{
|
{
|
||||||
// header ends on first empty line, skip rest of mail
|
// header ends on first empty line, skip rest of mail
|
||||||
|
|
||||||
if(strlen(rtrim($line)) == 0)
|
if(strlen(rtrim($line)) == 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//fetching from field
|
//fetching from field
|
||||||
|
|
||||||
if(!strlen($from)
|
if(!strlen($from)
|
||||||
&& preg_match("/^From:(.+)<(.*)>$/", $line, $match))
|
&& preg_match("/^From:(.+)<(.*)>$/", $line, $match)
|
||||||
{
|
) {
|
||||||
$from = $match[2];
|
$from = $match[2];
|
||||||
}
|
}
|
||||||
elseif(!strlen($from)
|
elseif(!strlen($from)
|
||||||
&& preg_match("/^From:\s+(.*@.*)$/", $line, $match))
|
&& preg_match("/^From:\s+(.*@.*)$/", $line, $match)
|
||||||
{
|
) {
|
||||||
$from = $match[1];
|
$from = $match[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
//fetching to field
|
//fetching to field
|
||||||
|
|
||||||
if(!strlen($to)
|
if(!strlen($to)
|
||||||
&& preg_match("/^To:(.+)<(.*)>$/", $line, $match))
|
&& preg_match("/^To:(.+)<(.*)>$/", $line, $match)
|
||||||
{
|
) {
|
||||||
$to = $match[2];
|
$to = $match[2];
|
||||||
}
|
}
|
||||||
elseif(!strlen($to)
|
elseif(!strlen($to)
|
||||||
&& preg_match("/To:\s+(.*@.*)$/", $line, $match))
|
&& preg_match("/To:\s+(.*@.*)$/", $line, $match)
|
||||||
{
|
) {
|
||||||
$to = $match[1];
|
$to = $match[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
//fetching sender field
|
//fetching sender field
|
||||||
|
|
||||||
if(!strlen($to)
|
if(!strlen($to)
|
||||||
&& preg_match("/^Sender:(.+)<(.*)>$/", $line, $match))
|
&& preg_match("/^Sender:(.+)<(.*)>$/", $line, $match)
|
||||||
{
|
) {
|
||||||
$sender = $match[2];
|
$sender = $match[2];
|
||||||
}
|
}
|
||||||
elseif(!strlen($to)
|
elseif(!strlen($to)
|
||||||
&& preg_match("/Sender:\s+(.*@.*)$/", $line, $match))
|
&& preg_match("/Sender:\s+(.*@.*)$/", $line, $match)
|
||||||
{
|
) {
|
||||||
$sender = $match[1];
|
$sender = $match[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
//check for amavis/spamassassin spam headers
|
//check for amavis/spamassassin spam headers
|
||||||
|
|
||||||
if(preg_match("/^X-Spam-Status: (Yes|No)(.*)$/", $line, $match))
|
if(preg_match("/^X-Spam-Status: (Yes|No)(.*)$/", $line, $match))
|
||||||
{
|
{
|
||||||
if($match[1] == 'Yes')$spam = true;
|
if($match[1] == 'Yes')$spam = true;
|
||||||
@@ -178,13 +170,13 @@ if($db->num_rows($result) > 0)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//skip mail when marked as spam
|
//skip mail when marked as spam
|
||||||
|
if($spam == true)
|
||||||
if($spam == true)continue;
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
//error while parsing mail
|
//error while parsing mail
|
||||||
|
if($to == '' || $from == '')
|
||||||
if($to == ''
|
|
||||||
|| $from == '')
|
|
||||||
{
|
{
|
||||||
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "No valid headers found in mail to parse: " . $entry);
|
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "No valid headers found in mail to parse: " . $entry);
|
||||||
continue;
|
continue;
|
||||||
@@ -193,15 +185,15 @@ if($db->num_rows($result) > 0)
|
|||||||
//important! prevent mailbombs when mail comes from a maildaemon/mailrobot
|
//important! prevent mailbombs when mail comes from a maildaemon/mailrobot
|
||||||
//robot/daemon mails must go to Sender: field in envelope header
|
//robot/daemon mails must go to Sender: field in envelope header
|
||||||
//refers to "Das Postfix-Buch" / RFC 2822
|
//refers to "Das Postfix-Buch" / RFC 2822
|
||||||
|
if($sender != '')
|
||||||
if($sender != '')$from = $sender;
|
{
|
||||||
|
$from = $sender;
|
||||||
|
}
|
||||||
|
|
||||||
//make message valid to email format
|
//make message valid to email format
|
||||||
|
|
||||||
$message = str_replace("\r\n", "\n", $row['message']);
|
$message = str_replace("\r\n", "\n", $row['message']);
|
||||||
|
|
||||||
//check if mail is already an answer
|
//check if mail is already an answer
|
||||||
|
|
||||||
$fullcontent = implode("", $content);
|
$fullcontent = implode("", $content);
|
||||||
|
|
||||||
if(strstr($fullcontent, $message))
|
if(strstr($fullcontent, $message))
|
||||||
@@ -232,9 +224,9 @@ if($db->num_rows($result) > 0)
|
|||||||
}
|
}
|
||||||
|
|
||||||
$mail->ClearAddresses();
|
$mail->ClearAddresses();
|
||||||
|
$responded_counter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Responded to '" . $responded_counter . "' mails from '".$path."'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ $yesterday = time() - (60 * 60 * 24);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
require (dirname(__FILE__) . '/../lib/class.phpmailer.php');
|
require (dirname(__FILE__) . '/../lib/class.phpmailer.php');
|
||||||
$mail = new PHPMailer();
|
$mail = new PHPMailer(true);
|
||||||
$mail->SetFrom($settings['panel']['adminmail'], 'Froxlor Administrator');
|
$mail->SetFrom($settings['panel']['adminmail'], 'Froxlor Administrator');
|
||||||
|
|
||||||
// Warn the customers at 90% traffic-usage
|
// Warn the customers at 90% traffic-usage
|
||||||
|
|||||||
Reference in New Issue
Block a user