<?php
/*
* @(#) $Header: /var/cvsroot/pop3ml/class.pop3ml.php,v 1.15 2009/03/02 11:38:11 cvs Exp $
*/
/* pop3ml - php Mailing list/Newsletter manager
Copyright (C) 2008- Giuseppe Lucarelli <hide@address.com>
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
require_once('smtp.php');
require_once('mime_parser.php');
require_once('rfc822_addresses.php');
require_once("pop3.php");
require_once('sasl.php'); /* for gmail */
class MyPop3 extends pop3_class {
var $decoded;
}
class Pop3Ml
{
/* public */
var $mltable = '';
var $messagesTable = '';
var $listname = '';
var $listaddress = '';
var $listhostname = '';
var $listpost = '';
var $listport = '';
var $listtls = '';
var $listuser = '';
var $listpassword = '';
var $allow = array();
var $deny = array();
var $removeAfterPop = '';
var $moderatedlist = '';
var $modsublist = '';
var $listowner = '';
var $maxmsgsize = '';
var $headersadd = array();
var $logheader = '';
var $sublist = '';
var $mlsmtp = array();
/* private */
var $dbconn = '';
var $databaseHost = '';
var $databaseUsername = '';
var $databasePassword = '';
var $dbrow = '';
var $pop3='';
var $decoded='';
var $smtp='';
var $smtpindex='';
var $error='';
function init() {
if(!$this->dbconn=@mysql_connect($this->databaseHost, $this->databaseUsername, $this->databasePassword)) {
return false;
}
@mysql_select_db($this->databaseName,$this->dbconn);
$query = "select * from ".addslashes($this->mltable)." where listname = '".$this->listname."'";
$command = @mysql_query($query,$this->dbconn);
if(!$result = @mysql_fetch_object($command)) {
echo "no ML found: quit; ";
return false;
}
$this->dbrow = $result;
$this->listuser=$this->dbrow->listuser;
$this->listpassword=$this->dbrow->listpoppass;
$this->maxmsgsize=$this->dbrow->msgsize;
$this->removeAfterPop=$this->dbrow->removeafterpop;
$this->moderatedlist=$this->dbrow->moderatedlist;
$this->listowner=$this->dbrow->listowneremail;
$this->listaddress=$this->dbrow->listaddr;
$this->mlsmtp=explode("\n",$this->dbrow->smtpserver);
$this->dbrow->sublist=trim($this->dbrow->sublist);
$this->dbrow->allowsublist=trim($this->dbrow->allowsublist);
$this->dbrow->denysublist=trim($this->dbrow->denysublist);
$this->sublist=$this->dbrow->sublist;
$this->modsublist=$this->dbrow->modsublist;
$this->allow=(strlen($this->dbrow->allowsublist) > 2 ? explode("\n",$this->dbrow->allowsublist) : '');
$this->deny =(strlen($this->dbrow->denysublist) > 2 ? explode("\n",$this->dbrow->denysublist) : '');
$result=explode("\n",$this->setText($this->dbrow->headerchange));
foreach($result as $token) {
$item=explode('::',$token);
$this->headersadd[$item[0]] = trim($item[1]);
}
$this->smtpindex=0; // use default smtp server
//-------------------
$this->pop3 = new pop3_class;
stream_wrapper_register('pop3', 'pop3_stream'); /* Register the pop3 stream handler class */
return true;
}
//------------------------------------------------------------------------------
// if smtp server doesn't require pop auth, set to '' pop3_auth_port, user, password)
//------------------------------------------------------------------------------
function smtpinit() {
$this->smtp=new smtp_class;
$this->smtp->localhost="localhost";
$this->smtp->direct_delivery=0;
$this->smtp->timeout=10;
$this->smtp->data_timeout=0;
$this->smtp->debug=0;
$this->smtp->html_debug=0;
$this->smtp->pop3_auth_host='';
$this->smtp->realm="";
$this->smtp->workstation="";
$this->smtp->authentication_mechanism="";
$token = explode(':',trim($this->mlsmtp[$this->smtpindex]));
$this->smtp->host_name=$token[0];
$this->smtp->host_port=$token[1];
$this->smtp->ssl=$token[2];
$this->smtp->pop3authport='';
$this->smtp->user='';
$this->smtp->password='';
if($token[3]) $this->smtp->pop3authport=$token[3];
if($token[4]) $this->smtp->user=$token[4];
if($token[5]) $this->smtp->password=$token[5];
}
function &setText(&$text) {
return(str_replace(array("__LISTADDRESS__","__LISTOWNER__","__LISTHELP__"),
array($this->listaddress,$this->listowner,$this->listaddress),$text));
}
function smtpsend($mailto, $mailsubject, $mailfrom, &$mailheader, &$mailbody) {
$this->smtpinit();
if($this->smtp->direct_delivery)
{
if(!function_exists("GetMXRR"))
{
/*
* If possible specify in this array the address of at least on local
* DNS that may be queried from your network.
*/
$_NAMESERVERS=array();
include("getmxrr.php");
}
/*
* If GetMXRR function is available but it is not functional, to use
* the direct delivery mode, you may use a replacement function.
*/
/*
else
{
$_NAMESERVERS=array();
if(count($_NAMESERVERS)==0)
Unset($_NAMESERVERS);
include("rrcompat.php");
$this->smtp->getmxrr="_getmxrr";
}
*/
}
if($this->smtp->SendMessage(
$mailfrom,
array(
$mailto
),
explode("\n",$mailheader), $mailbody))
$retval = "OK.";
else
$retval = $this->smtp->error;
return $retval;
}
function sendSubscribeConfirmation($address) {
$id = md5(uniqid(rand(), true));
$mailheader = '';
$mailsubject = 'confirm subscribe to '.$this->listaddress;
$mailbody = "__SUBSCRIBE__";
$confirmtext = 'confirm.subscribe.'.$this->listname.'.'.$id.'.'.$address;
$mailbody = str_replace("__SUBSCRIBE__", $confirmtext, $this->setText($this->dbrow->submsg));
$query="insert into ".$this->subqueue." values ('".$this->listname.":$address','subscription','$id','');";
if(!@mysql_query($query,$this->dbconn)) { // there is another request, replace it
$query="update ".$this->subqueue." set request = 'subscription', keyvalue = '$id' where code = '".
$this->listname.":$address';";
@mysql_query($query,$this->dbconn);
}
foreach($this->headersadd as $hk => $hv) {
if(strcmp($hv,'')) {
$mailheader.= $hk.': '.$hv."\r\n";
}
}
$mailheader.='Subject: '.$mailsubject."\r\n";
$error = $this->smtpsend($address, $mailsubject, $this->listaddress, $mailheader, $mailbody);
if($error != 'OK.') {
echo "[$error]";
return false;
}
}
function sendWelcomeMessage($address) {
$mailsubject = 'WELCOME to '.$this->listaddress;
$mailheader = '';
$mailbody = '';
$mailbody = str_replace("__SUBSCRIBE__", $address, $this->setText($this->dbrow->welcome));
foreach($this->headersadd as $hk => $hv) {
if(strcmp($hv,'')) {
$mailheader.= $hk.': '.$hv."\r\n";
}
}
$mailheader.='Subject: '.$mailsubject."\r\n";
$error = $this->smtpsend($address, $mailsubject, $this->listaddress, $mailheader, $mailbody);
if($error != 'OK.') {
return false;
}
}
function setConfirmedAddress($address) {
$this->dbrow->sublist=$this->sublist=trim($this->sublist)."\n".$address;
$query = 'update '.$this->mltable.' set sublist = \''.
trim($this->sublist).'\' where listname = \''.$this->listname.'\'';
if($command = @mysql_query($query,$this->dbconn)) {
echo "confirmed subscription [$address]\n";
$this->sendWelcomeMessage($address);
}
}
function isNewSubscription($address) {
$bodytest = $this->decoded[0]['Body'];
if(strstr(trim($this->decoded[0]['Headers']['content-type:']),'alternative')) {
$pos=strpos($bodytest,"text/plain");
$bodytest=substr($bodytest,$pos);
$pos=strpos($bodytest,"\r\n\r\n");
$bodytest=substr($bodytest,$pos+4);
if(!$pos) {
$pos=strpos($bodytest,"\n\n");
$bodytest=substr($bodytest,$pos+2);
}
}
if(eregi("^subscribe",preg_replace("/\n|\r|=/",'',$bodytest))) {
if(strcasecmp($this->dbrow->confirmsub,'yes')) {
$this->setConfirmedAddress($address);
} else {
echo "subscribe [$address]. require confirmation: ";
$this->sendSubscribeConfirmation($address);
}
return true;
}
$query = "select * from ".addslashes($this->subqueue)." where code = '".
$this->listname.':'.$address."' and request = 'subscription'";
$command = @mysql_query($query,$this->dbconn);
if(!$result = @mysql_fetch_object($command)) {
return false;
}
if(!ereg("confirm.*subscribe.*".$this->listname.'.*'.$result->keyvalue.'.*'.$address,
preg_replace("/\n|\r|=/",'',$this->decoded[0]['Body']))) {
return false;
}
$query = "delete from ".addslashes($this->subqueue)." where code = '".
$this->listname.':'.$address."' and request = 'subscription'";
$command = @mysql_query($query,$this->dbconn);
$this->setConfirmedAddress($address);
return true;
}
function sendUnsubscribeConfirmation($address) {
$id = md5(uniqid(rand(), true));
$mailheader = '';
$mailsubject = 'confirm unsubscribe from '.$this->listaddress;
$mailbody = "__UNSUBSCRIBE__";
$confirmtext = 'confirm.unsubscribe.'.$this->listname.'.'.$id.'.'.$address;
$mailbody = str_replace("__UNSUBSCRIBE__", $confirmtext, $this->setText($this->dbrow->unsubmsg));
$query="insert into ".$this->subqueue." values ('".$this->listname.":$address','unsubscription','$id','');";
if(!@mysql_query($query,$this->dbconn)) { // there is another request, replace it
$query="update ".$this->subqueue." set request = 'unsubscription', keyvalue = '$id' where code = '".
$this->listname.":$address';";
@mysql_query($query,$this->dbconn);
}
foreach($this->headersadd as $hk => $hv) {
if(strcmp($hv,'')) {
$mailheader.= $hk.': '.$hv."\r\n";
}
}
$mailheader.='Subject: '.$mailsubject."\r\n";
$error = $this->smtpsend($address, $mailsubject, $this->listaddress, $mailheader, $mailbody);
if($error != 'OK.') {
return false;
}
}
function sendGoodbyeMessage($address) {
$mailsubject = 'GOODBYE from '.$this->listaddress;
$mailheader = '';
$mailbody = '';
$mailbody = str_replace("__UNSUBSCRIBE__", $address, $this->setText($this->dbrow->goodbye));
foreach($this->headersadd as $hk => $hv) {
if(strcmp($hv,'')) {
$mailheader.= $hk.': '.$hv."\r\n";
}
}
$mailheader.='Subject: '.$mailsubject."\r\n";
$error = $this->smtpsend($address, $mailsubject, $this->listaddress, $mailheader, $mailbody);
if($error != 'OK.') {
return false;
}
}
function unsetRegisteredAddress($address) {
$this->dbrow->sublist=$this->sublist=preg_replace('/'.$address.'(\n|)/','',trim($this->sublist));
$query = 'update '.$this->mltable.' set sublist = \''.
trim($this->sublist).'\' where listname = \''.$this->listname.'\'';
if($command = @mysql_query($query,$this->dbconn)) {
echo "confirmed unsubscription [$address]\n";
$this->sendGoodbyeMessage($address);
}
}
function isUnsubscription($address) {
$bodytest = $this->decoded[0]['Body'];
if(strstr(trim($this->decoded[0]['Headers']['content-type:']),'alternative')) {
$pos=strpos($bodytest,"text/plain");
$bodytest=substr($bodytest,$pos);
$pos=strpos($bodytest,"\r\n\r\n");
$bodytest=substr($bodytest,$pos+4);
if(!$pos) {
$pos=strpos($bodytest,"\n\n");
$bodytest=substr($bodytest,$pos+2);
}
}
if(eregi("^unsubscribe",preg_replace("/\n|\r|=/",'',$bodytest))) {
if(strcasecmp($this->dbrow->confirmunsub,'yes')) {
$this->unsetRegisteredAddress($address);
} else {
echo "unsubscribe [$address]. require confirmation\n";
$this->sendUnsubscribeConfirmation($address);
}
return true;
}
$query = "select * from ".addslashes($this->subqueue)." where code = '".
$this->listname.':'.$address."' and request = 'unsubscription'";
$command = @mysql_query($query,$this->dbconn);
if(!$result = @mysql_fetch_object($command)) {
return false;
}
echo "[$address] unsubscription request pending, ";
if(!ereg("confirm.*unsubscribe.*".$this->listname.'.*'.$result->keyvalue.'.*'.$address,
preg_replace("/\n|\r|=/",'',$this->decoded[0]['Body']))) {
return true;
}
$query = "delete from ".addslashes($this->subqueue)." where code = '".
$this->listname.':'.$address."' and request = 'unsubscription'";
$command = @mysql_query($query,$this->dbconn);
$this->unsetRegisteredAddress($address);
return true;
}
function implodeHeaders($headkey,$token) {
$retval = '';
if(!is_array($token)) {
return $retval;
}
foreach($token as $key => $val) {
if(!is_array($val)) {
$retval.= (strcmp($headkey,'') ? $headkey : $key).' '.$val."\r\n";
} else {
$retval.= $this->implodeHeaders($key,$val);
}
}
return $retval;
}
function removeMessage($message) {
$this->error = '';
$this->error=$this->pop3->DeleteMessage($message);
return true;
}
function checkSender($address) {
$retval = 'deny';
if(!strcmp($address,$this->listowner)
|| eregi("(^|\n)$address(\n|$)",$this->modsublist)
|| strcmp($this->dbrow->subscribersonly,'yes')) {
$retval = 'allow';
}
if(is_array($this->allow)) {
foreach($this->allow as $pattern) {
if(eregi($pattern, $address)) {
$retval = 'allow';
}
}
}
if(is_array($this->deny)) {
foreach($this->deny as $pattern) {
if(eregi($pattern, $address)) {
$retval = 'deny';
}
}
}
if(!preg_match('/(^|\n)'.$address.'(\n|$)/',$this->sublist)) {
if($this->isNewSubscription($address) != true && $retval != 'allow') {
echo "sorry, you are not subscribed yet and/or not allowed to post. Sender [$address] message-id [$messageid]";
}
return $retval;
}
if($this->isUnsubscription($address) == true) {
return 'deny';
}
// if newsletter don't accept others then allowed sender
if($this->dbrow->mltype != 'm' || !strstr($retval,'deny')) {
return $retval;
}
return 'allow';
}
function listMessages() {
$result=$this->pop3->ListMessages("",0);
if(GetType($result)=="array") {
for(Reset($result),$message=0;$message<count($result);Next($result),$message++) {
echo "Message ",Key($result)," - ",$result[Key($result)]," bytes.\n";
}
$result=$this->pop3->ListMessages("",1);
if(GetType($result)=="array") {
for(Reset($result),$message=0;$message<count($result);Next($result),$message++) {
echo "Message ",Key($result),", Unique ID - \"",$result[Key($result)],"\"\n";
}
}
}
}
function pop3Start() {
$temp = explode(':',$this->dbrow->hostname);
$this->pop3->hostname=$this->listhostname=$temp[0]; /* POP 3 server host name */
$this->pop3->port=$this->listport=$temp[1]; /* POP 3 server host port,
usually 110 but some servers use other ports
Gmail uses 995 */
$this->pop3->tls=$this->listtls=$temp[2]; /* Establish secure connections using TLS */
$this->pop3->realm=""; /* Authentication realm or domain */
$this->pop3->workstation=""; /* Workstation for NTLM authentication */
$this->pop3->authentication_mechanism="USER"; /* SASL authentication mechanism */
//$this->pop3->debug=1; /* Output debug information */
//$this->pop3->html_debug=1; /* Debug information is in HTML */
//$this->pop3->join_continuation_header_lines=1; /* Concatenate headers split in multiple lines */
//return $pop3;
}
/* check for new messages */
function pop3Read() {
$retval = '';
$apop=0;
$user=$this->listuser;
$password=$this->listpassword;
$this->error='';
$messages='';
$address = '';
$substate = -1;
$messageid = '';
if(($this->error=$this->pop3->Open())!="") {
return $this->error;
}
if(($this->error=$this->pop3->Login($user,$password,$apop))!="") {
echo "Connection error: $this->error\n<br>";
return $this->error;
}
if(($this->error=$this->pop3->Statistics($messages,$size))=="")
{
echo "$messages mess.".($size > 0 ? " total size [$size]" : '');
for($i=0; $i < $messages; $i++)
{
$error = '';
$this->pop3->GetConnectionName($connection_name);
$message=$i + 1;
$size = $this->pop3->ListMessages($message,0);
echo " # $message, size [$size]: ";
$message_file='pop3://'.$connection_name.'/'.$message;
$mime=new mime_parser_class;
$mime->decode_bodies = 0;
if($size > $this->maxmsgsize) {
$mime->decode_bodies = 1;
echo " Warning [exceeding].";
}
$parameters=array(
'File'=>$message_file //, 'SaveBody'=>1,
);
$success=$mime->Decode($parameters, $this->decoded);
if(!$success) {
echo 'MIME message decoding error: '.HtmlSpecialChars($mime->error)." .";
} else {
if(!strcasecmp($this->removeAfterPop,'yes')) {
$this->error.=$this->removeMessage($message)."\n";
}
$address = $this->decoded[0]['ExtractedAddresses']['from:'][0]['address'];
if(isset($this->decoded[0]['Headers']['message-id:'])) {
$messageid = $this->decoded[0]['Headers']['message-id:'];
}
if(isset($this->decoded[0]['Headers']['precedence:']) &&
$this->decoded[0]['Headers']['precedence:'] == 'bulk') {
echo "sorry, bulk message. Sender [$address] message-id [$messageid]";
}
if(!strcmp($this->checkSender($address),'allow')) {
$this->sendMessage($address,$size);
}
}
}
}
echo $this->logcr."\n";
$this->error=$this->pop3->Close();
$retval = $this->error;
return $retval;
}
function addTrailer() {
$retval = '';
if(strlen($this->dbrow->trailerfile) <= 0) {
return $retval;
}
$content_type = explode(';',$this->decoded[0]['Headers']['content-type:']);
$content_type[0] = trim($content_type[0]);
/*---------------------------------------------------------
* non enabled
if(strcasecmp(trim($content_type[0]),'text/plain')) {
if(strstr($content_type[1],'boundary=')) {
$retval = "\r\n--".
($content_type[1][9] == '"' ?
substr($content_type[1],10,-1) :
substr($content_type[1],9)).
"\r\nContent-Type: text/plain; charset=ISO-8859-1; format=flowed".
"\r\nContent-Transfer-Encoding: 7bit\r\n\r\n";
}
}
---------------------------------------------------------*/
if(strstr($content_type[0],'alternative')) {
if(strstr($content_type[1],'boundary=')) {
$retval = "\r\n--".
($content_type[1][9] == '"' ?
substr($content_type[1],10,-1) :
substr($content_type[1],9)).
"\r\nContent-Type: text/plain; charset=ISO-8859-1; format=flowed".
"\r\nContent-Transfer-Encoding: 7bit\r\n\r\n";
return $this->setText($retval);
}
}
if(!strstr($content_type[0],'mixed') && !strstr($content_type[0],'digest')) {
$retval="\r\n".$this->dbrow->trailerfile."\r\n";
return $this->setText($retval);
}
return $retval;
}
function sendFromQueue() {
$query = "select * from $this->queue where mltable = '$this->listname'";
$result = @mysql_query($query,$this->dbconn);
while($row = @mysql_fetch_object($result)) {
// change smtp server
$this->smtpindex = $row->smtp + 1;
if($this->smtpindex > (sizeof($this->mlsmtp) - 1)) {
$this->smtpindex = 0;
}
$addresses = explode(',', $row->addresses);
$messageid = $row->messageid;
$query = "select * from $this->messagesTable where id = $messageid";
$msgresult = @mysql_query($query,$this->dbconn);
if(!$msgrow = @mysql_fetch_object($msgresult)) {
break;
}
echo "sending from queue # $messageid; ";
$addresserror = '';
foreach($addresses as $address) {
$pos=strpos($msgrow->message,"\r\n\r\n");
if(!$pos) $pos=strpos($msgrow->message,"\n\n");
$error = $this->smtpsend($address, $msgrow->subject, $this->listaddress,
substr($msgrow->message,0,$pos),
substr($msgrow->message,$pos+2));
if($error != 'OK.') {
echo " error [$error] for [$address];";
$addresserror.=((strlen($addresserror) <= 0) ? '': ',').$address;
} else {
$ok++;
}
}
if(strlen($addresserror) > 1) {
$query = "update queue set mldate = '".date(Ymd).
"', addresses = '".str_replace("'","\\'",$addresserror).
"', smtp = $this->smtpindex where id = $row->id";
$command = @mysql_query($query,$this->dbconn);
} else {
$query = "update messages set state = 'sent', smtp = '".
$this->smtpindex."' where id = $messageid";
$command = @mysql_query($query,$this->dbconn);
$query = "delete from queue where id = $row->id";
$command = @mysql_query($query,$this->dbconn);
}
@mysql_free_result($msgresult);
}
@mysql_free_result($result);
$this->smtpindex = 0;
return true;
}
/* send section */
function sendMessage($sender,$msgsize) {
$error = '';
$messageid = -1;
$origmailheader = '';
$mailheader = '';
$mailbody = '';
$oksum = 0;
$sqlid = -1;
$modstate = 'sent';
if(!strcmp($this->moderatedlist,'yes')) {
$modstate = 'pending';
}
if($msgsize > $this->maxmsgsize) {
$this->headersadd['Content-Type'] = '';
$this->headersadd['Boundary'] = '';
}
$mailbody=&$this->decoded[0]['Body'];
$mailbody.=$this->addTrailer();
$mailsender = $this->listaddress; // if smtp require authentication
$mailsubject = stripslashes($this->decoded[0]['Headers']['subject:']);
if(!strcmp($modstate,'pending')) {
if(eregi("(^|\n)$sender(\n|$)",$this->modsublist)) {
$keyvalue=preg_replace('/(.*)\[(MOD#[a-zA-Z0-9]+)\](.*)/','\2',$mailsubject);
$query="select * from $this->messagesTable where state = 'pending' && subject REGEXP '$keyvalue'";
if($result = @mysql_query($query,$this->dbconn)) {
if($row = @mysql_fetch_object($result)) {
preg_match('/(^|\n|\r)subject:(.*)(\n|\r|$)/i',$row->header, $match);
if($match[2]) {
$mailsubject=trim($match[2]);
} else {
$mailsubject=preg_replace('/(.*)\[(MOD#[a-zA-Z0-9]+)\](.*)/','\3',$mailsubject);
}
$pos=strpos($row->message,"\r\n\r\n");
if(!$pos) $pos=strpos($row->message,"\n\n");
$mailbody = substr($row->message,$pos);
$query = "update $this->messagesTable set state = 'queued', subject = '$mailsubject' where id = $row->id";
@mysql_query($query,$this->dbconn);
$messageid = $row->id;
}
@mysql_free_result($result);
}
$modstate = 'sent';
} else {
$mailsubject = '[MOD#'.md5(uniqid(rand(), true)).']'.$mailsubject;
}
$this->headersadd['Subject'] = $mailsubject;
}
foreach($this->decoded[0]['Headers'] as $key => $val) {
foreach($this->headersadd as $hk => $hv) {
if(eregi("^$hk($|:)",$key)) {
if(strlen($hv) <= 0) {
$val = '';
} else {
$val = $hv;
}
unset($this->headersadd[$hk]);
$hv = '';
break;
}
}
if(is_array($val)) {
foreach($val as $token) {
$mailheader .= $key.' '.$token."\r\n";
}
} else if(strlen($val) > 0) {
$mailheader .= $key.' '.$val."\r\n";
}
}
foreach($this->headersadd as $hk => $hv) {
if(strlen($hv) > 0) {
$mailheader .= $hk . ': '.$hv."\r\n";
}
}
if($msgsize > $this->maxmsgsize) {
$mailbody = "Your message [$msgsize] was not sent because it exceed maximum size allowed [$this->maxmsgsize]\n";
$error = $this->smtpsend($sender, $mailsubject, $mailsender, $mailheader, $mailbody);
if($error != 'OK.') {
echo " error [$error] for [$sender];";
} else {
echo " resent to [$sender];";
}
return;
}
$addresserror = '';
echo "Sending ID # ";
if(!strcmp($modstate,'sent')) {
$sublist = explode("\n",$this->sublist);
} else {
echo "(moderation) ";
$sublist = explode("\n",$this->modsublist);
}
if(sizeof($sublist) > 0) {
foreach($sublist as $mailaddress) {
if(strlen($mailaddress) < 5) continue;
$mailaddress = stripslashes($mailaddress);
$error = $this->smtpsend($mailaddress, $mailsubject, $mailsender, $mailheader, $mailbody);
if($error != 'OK.') {
echo " error [$error] for [$mailaddress];";
$addresserror.=((strlen($addresserror) <= 0) ? '': ',').$mailaddress;
} else {
$ok++;
}
}
}
if(!strcmp($modstate,'sent') && strlen($addresserror) > 1) {
$modstate = 'queued';
}
// ok, insert message into archive
if($messageid > 0) {
$query = "update $this->messagesTable set state = '$modstate' where id = $messageid";
} else {
$query = "insert into ".$this->messagesTable.
" (id,mldate,state,mltable,smtp,mailfrom,subject,message,header,rowlock) values(0,now(),'".
"$modstate','$this->listname','$this->smtpindex','$sender','".
str_replace("'","\\'",$mailsubject)."','".
str_replace("'","\\'",$mailheader)."\r\n".str_replace("'","\\'",$mailbody)."','".
str_replace("'","\\'",$this->implodeHeaders('',$this->decoded[0]['Headers'])).
"','')";
}
$command = @mysql_query($query,$this->dbconn);
$sqlid = @mysql_insert_id($this->dbconn);
echo "$sqlid:";
if(strlen($addresserror) > 1) {
$query = "insert into queue (id, mldate, smtp, mltable, messageid, addresses, rowlock) values(0,now(),'".
"$this->smtpindex','$this->listname',$sqlid,'".
str_replace("'","\\'",$addresserror)."','')";
$command = @mysql_query($query,$this->dbconn);
}
echo " sent # $ok. End";
}
function lockml() {
if(strlen($this->dbrow->rowlock) > 1) {
return false;
}
$query = "update ".addslashes($this->mltable)." set rowlock = '".
$_SERVER['REMOTE_ADDR'].'-'.date('Y/m/d-H:i:s')."' where listname = '".$this->listname."'";
if(!@mysql_query($query,$this->dbconn)) {
return false;
}
return true;
}
function unlockml() {
$query = "update ".addslashes($this->mltable)." set rowlock = '' where listname = '".$this->listname."'";
if(!@mysql_query($query,$this->dbconn)) {
return false;
}
}
function run() {
echo $this->logheader;
echo date("Y/m/d H:i:s").". ".$this->listname.": ";
if($this->init() != true) {
echo $this->logfooter;
return;
}
if(!strcmp($this->dbrow->shutdown,'yes')) {
echo "ML disabled. quit";
} else if($this->lockml() != true) {
echo "already locked. quit";
} else {
$this->sendFromQueue();
$this->pop3Start();
$this->error=$this->pop3Read();
$this->unlockml();
}
echo $this->logfooter;
}
};
?>