@@ -1917,7 +1917,9 @@ sub redirect {
19171917}
19181918
19191919sub send_one_mail {
1920- my ($from , $subject , $mail_id ) = @_ ;
1920+ my ($from , $subject , $mail_id , $job_id ) = @_ ;
1921+ # job_id is set for scheduled messages
1922+ # the job entry is deleted as soon as the message is sent.
19211923 my $decl_charset = getconf(" preferred_charset" , $from ) || ' iso-8859-1' ;
19221924 my @charsets = split (/ \s +/ , $decl_charset );
19231925
@@ -2008,6 +2010,11 @@ sub send_one_mail {
20082010 $top -> head-> replace(" Bcc" , $bcc );
20092011 }
20102012
2013+ if (defined $job_id ) {
2014+ # for scheduled deliveries, replace the Date header with the
2015+ # current date and time
2016+ Manitou::MailFormat::add_date_header($top );
2017+ }
20112018 attach_parts($dbh , $mail_id , $top , getconf(" tmpdir" ));
20122019
20132020 my @opl ;
@@ -2087,10 +2094,10 @@ sub send_one_mail {
20872094 error_log(" Local delivery agent error: (\` $cmd \` , exit code=" .($? >>8)." ): $e " );
20882095 }
20892096 else {
2090- # Set the SENT and ARCHIVED status bits
2091- my $sths = $ dbh-> prepare (" UPDATE mail SET status=status|(256+32),sender_date=now() WHERE mail_id=?" );
2092- $sths -> execute( $mail_id );
2093- $sths -> finish ;
2097+ # Set the SENT and ARCHIVED status bits. Clear SCHEDULED.
2098+ $ dbh-> do (" UPDATE mail SET status=( status|(256+32))&(~1024) ,sender_date=now() WHERE mail_id=?" ,
2099+ {}, $mail_id );
2100+ $dbh -> do( " DELETE FROM jobs_queue WHERE job_id=? " ,{}, $job_id ) if ( defined $job_id ) ;
20942101 $ret =1; # OK
20952102 }
20962103 }
@@ -2129,17 +2136,35 @@ sub get_delivery_agent {
21292136}
21302137
21312138sub send_mails {
2132- my $sth1 = $dbh -> prepare(" SELECT mail_id FROM mail_status WHERE status=129" );
2139+ my $sched_bit =1024; # bitmask for "send later"
2140+ my $sth1 = $dbh -> prepare(" SELECT mail_id FROM mail_status WHERE (status=129 OR status=129+$sched_bit )" );
21332141 $sth1 -> execute;
21342142 my @res ;
2143+ my $sth_job ;
21352144 while (@res = $sth1 -> fetchrow_array) {
21362145 my $mail_id =$res [0];
21372146 next if (exists $hsend_blocked {$mail_id });
2138- my $sth = $dbh -> prepare(" SELECT sender,subject FROM mail WHERE mail_id=? AND status=129 " );
2147+ my $sth = $dbh -> prepare(" SELECT sender,subject,status FROM mail WHERE mail_id=?" );
21392148 $sth -> execute($mail_id );
21402149 my @row ;
2141- while (@row = $sth -> fetchrow_array) {
2142- if (send_one_mail($row [0], $row [1], $mail_id )) {
2150+ while (my ($sender ,$subject ,$status ) = $sth -> fetchrow_array) {
2151+ my $job_id ;
2152+ my $sched_time ; # timestamp as seconds since epoch
2153+ if ($status == 129+$sched_bit ) {
2154+ if (!defined $sth_job ) { # prepare the query only if needed
2155+ $sth_job = $dbh -> prepare(" SELECT job_id,job_args FROM jobs_queue WHERE mail_id=? AND job_type=?" );
2156+ }
2157+ $sth_job -> execute($mail_id , " send_mail" );
2158+ ($job_id , $sched_time ) = $sth_job -> fetchrow_array;
2159+ # check if the scheduled time is reached
2160+ next if ( ! ($sched_time =~ / ^[0-9]+$ / && $sched_time <= time ()) );
2161+ }
2162+ elsif ($status != 129) {
2163+ # If the status has changed since the initial fetch (when other messages
2164+ # were sent in the loop), ignore the message.
2165+ next ;
2166+ }
2167+ if (send_one_mail($sender , $subject , $mail_id , $job_id )) {
21432168 update_runtime_timestamp(" last_sent" ) if getconf_bool(" update_runtime_info" , $row [0]);
21442169 notice_log(" Sent outgoing message #$mail_id " );
21452170 my $nb_blocked = scalar (keys %hsend_blocked );
0 commit comments