@@ -1917,7 +1917,9 @@ sub redirect {
1917
1917
}
1918
1918
1919
1919
sub 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.
1921
1923
my $decl_charset = getconf(" preferred_charset" , $from ) || ' iso-8859-1' ;
1922
1924
my @charsets = split (/ \s +/ , $decl_charset );
1923
1925
@@ -2008,6 +2010,11 @@ sub send_one_mail {
2008
2010
$top -> head-> replace(" Bcc" , $bcc );
2009
2011
}
2010
2012
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
+ }
2011
2018
attach_parts($dbh , $mail_id , $top , getconf(" tmpdir" ));
2012
2019
2013
2020
my @opl ;
@@ -2087,10 +2094,10 @@ sub send_one_mail {
2087
2094
error_log(" Local delivery agent error: (\` $cmd \` , exit code=" .($? >>8)." ): $e " );
2088
2095
}
2089
2096
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 ) ;
2094
2101
$ret =1; # OK
2095
2102
}
2096
2103
}
@@ -2129,17 +2136,35 @@ sub get_delivery_agent {
2129
2136
}
2130
2137
2131
2138
sub 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 )" );
2133
2141
$sth1 -> execute;
2134
2142
my @res ;
2143
+ my $sth_job ;
2135
2144
while (@res = $sth1 -> fetchrow_array) {
2136
2145
my $mail_id =$res [0];
2137
2146
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=?" );
2139
2148
$sth -> execute($mail_id );
2140
2149
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 )) {
2143
2168
update_runtime_timestamp(" last_sent" ) if getconf_bool(" update_runtime_info" , $row [0]);
2144
2169
notice_log(" Sent outgoing message #$mail_id " );
2145
2170
my $nb_blocked = scalar (keys %hsend_blocked );
0 commit comments