Commit cb7c2943 authored by serge.aumont's avatar serge.aumont
Browse files

[*feature] Tracking feature : a great contrib from French army DGA Information...

[*feature] Tracking feature : a great contrib from French army DGA Information Superiority (Guillaume Colotte and laurent Cailleux)
The tracking feature is a way to request DSN or DSN + MDN when sending a message to each subscribers. In that case, Sympa (bounced.pl) collect both DSN and MDN and store them in a new table "notification_table". Them, for each message, the list owner can display which subscribers has displayed, received or not received the message. This can be used for some important list where list owner need to collect the proof of reception or display of each message. This page is accessible via archive (button "tracking").
This feature is controled by 2 list parameters see "tracking" paragraph in "edit list config"/bounce .

 See : http://www.sympa.org/manual/bounces#message_tracking and http://www.sympa.org/manual_6.1/parameters-bounces#tracking 



git-svn-id: https://subversion.renater.fr/sympa/trunk@6645 05aa8bb8-cd2b-0410-b1d7-8918dfa770ce
parent 700a6803
......@@ -50,6 +50,7 @@ use mail;
use Bulk;
use List;
use tools;
use tracking;
use Sympa::Constants;
my $daemon_name = &Log::set_daemon($0);
......@@ -219,14 +220,16 @@ while (!$end) {
## Go through the bulk_mailer table and process messages
if ($bulk = Bulk::next()) {
if ($bulk->{'messagekey'} ne $messagekey) {
# current packet is no related to the same message as the previous packet
# current packet is not related to the same message as the previous packet
# so it is needed to fetch the new message from message_table
$messagekey = $bulk->{'messagekey'};
$message_from_spool = &Bulk::message_from_spool($bulk->{'messagekey'});
$messageasstring_init = $message_from_spool->{'messageasstring'};
unless ( $messageasstring_init ) {
&do_log('err',"internal error : current packet (messagekey= %s) contain a ref to a null message",$bulk->{'messagekey'});
&do_log('err',"internal error : current packet (messagekey= %s) contains a ref to a null message",$bulk->{'messagekey'});
unless (&Bulk::remove($bulk->{'messagekey'},$bulk->{'packetid'})) {
&do_log('err',"failed to remove processed packet '%s', messagekey '%s'", $bulk->{'messagekey'},$bulk->{'packetid'});
}
......@@ -256,30 +259,41 @@ while (!$end) {
# -6 dkim sign
#
if (($bulk->{'verp'})||($bulk->{'merge'})){ # message needs personalization
#my $list = new List($bulk->{'listname'}, $bulk->{'robot'});
my $listname= $bulk->{'listname'}; my $robot = $bulk->{'robot'};
if (($bulk->{'verp'})||($bulk->{'merge'})||($bulk->{'tracking'}eq 'dsn')||($bulk->{'tracking'}eq 'mdn')){ # message needs personalization
my $key ;
### Parse an MIME::Entity message
my $parser = new MIME::Parser;
$parser->output_to_core(1);
my $entity = $parser->parse_data($messageasstring_init);
foreach $rcpt (@rcpts) {
my $return_path = $bulk->{'returnpath'};
if ($bulk->{'verp'}) {
my $return_path = $rcpt;
$return_path =~ s/\@/\=\=a\=\=/;
$return_path = "$Conf::Conf{'bounce_email_prefix'}+$return_path\=\=$bulk->{'listname'}\@$bulk->{'robot'}";
my $notification_id;
my $return_path;
my $escaped_rcpt = $rcpt;
$escaped_rcpt =~ s/\@/\=\=a\=\=/;
if(($bulk->{'tracking'} eq 'dsn')||($bulk->{'tracking'} eq 'mdn')){ # tracking by MDN required tracking by DSN to
my $msgid = $entity->head->get('Message-Id'); chomp $msgid;
$notification_id = &tracking::find_notification_id_by_message($rcpt, $msgid, $listname,$robot);
$return_path = $Conf::Conf{'bounce_email_prefix'}.'+'.$escaped_rcpt.'=='.$listname.'=='.$notification_id.'@'.$robot;
$entity->head->replace('Disposition-Notification-To',$return_path) if ($bulk->{'tracking'} eq 'mdn') ;
$messageasstring_init = $entity->as_string;
}else{ # VERP
$return_path = $Conf::Conf{'bounce_email_prefix'}.'+'.$escaped_rcpt.'=='.$listname.'@'.$robot;
}
if ($bulk->{'merge'}) {
### Parse an MIME::Entity message
my $parser = new MIME::Parser;
$parser->output_to_core(1);
my $entity = $parser->parse_data($messageasstring_init); ## Retrouver la méthode qui correspond
if ($bulk->{'merge'}) {
unless(&Bulk::merge_msg ($entity, $rcpt, $bulk, $data)){
&do_log('err', 'Erreur d appel &Bulk::merge_msg');
}
$messageasstring = $entity->as_string;
}else{
$messageasstring = $messageasstring_init;
}
if (&Conf::get_robot_conf($bulk->{'robot'}, 'dkim_feature') eq 'on'){
$messageasstring = &tools::remove_invalid_dkim_signature($messageasstring );
}
......@@ -289,14 +303,15 @@ while (!$end) {
'dkim_selector'=> $message_from_spool->{'dkim_selector'},
'dkim_privatekey' => $message_from_spool->{'dkim_privatekey'},
'dkim_header_list' =>$message_from_spool->{'dkim_header_list'} } );
}
*SMTP = &mail::smtpto($return_path, \$rcpt, $bulk->{'robot'});
}
*SMTP = &mail::smtpto($return_path, \$rcpt, $bulk->{'robot'},$notification_id);
# Message with customized data
print SMTP $messageasstring;
close SMTP;
}
}else{ # message dont needs personalization, they can be sent by packet
if (&Conf::get_robot_conf($bulk->{'robot'}, 'dkim_feature') eq 'on'){
if (&Conf::get_robot_conf($bulk->{'robot'}, 'dkim_feature') eq 'on'){
$messageasstring_init = &tools::remove_invalid_dkim_signature($messageasstring_init );
}
# Initial message
......@@ -307,6 +322,7 @@ while (!$end) {
'dkim_privatekey' => $message_from_spool->{'dkim_privatekey'},
'dkim_header_list' =>$message_from_spool->{'dkim_header_list'} } );
}
*SMTP = &mail::smtpto($bulk->{'returnpath'}, \@rcpts, $bulk->{'robot'});
print SMTP $messageasstring_init;
close SMTP;
......@@ -335,7 +351,7 @@ while (!$end) {
}
do_log('notice', 'bulk.pl exited normally due to signal');
&do_log('notice', 'bulk.pl exited normally due to signal');
&tools::remove_pid($Conf::Conf{'pidfile_bulk'}, $$, $options);
exit(0);
......
......@@ -19,7 +19,7 @@ CALENDAR
($tag$% FOREACH year = calendar %$tag$)
<div>
<ul class="calendar">
<li class="calendarYear">($tag$% year.key %$tag$)</li>
<li class="calendarLinksInactive">($tag$% year.key %$tag$)</li>
($tag$% FOREACH month = ['01' '02' '03' '04' '05' '06' '07' '08' '09' '10' '11' '12'] %$tag$)
($tag$% IF year.value.item(month) %$tag$)
($tag$% IF year.key == '$yyyy$' && month == '$mois$'%$tag$) <li class="calendarLinksCurrentPage"><a href="($tag$% path_cgi %$tag$)/arc/($tag$% list %$tag$)/($tag$% year.key %$tag$)-($tag$% month %$tag$)/" title="($tag$%|loc(year.value.item(month))%$tag$)%1 message(s)($tag$%END%$tag$)">($tag$% month %$tag$)</a></li>
......@@ -175,13 +175,13 @@ IDXPGEND
<div id="ActionHeader">
$SEARCH_FORM$
$CALENDAR$
<div class="text_center"><strong>$PRINTABLE_MONTH$&nbsp;&nbsp;&nbsp;$NUMOFMSG$ ($tag$%|loc%$tag$)mails($tag$%END%$tag$)</strong></div><br />
<div class="text_center"><strong>$PRINTABLE_MONTH$&nbsp;&nbsp;&nbsp;$NUMOFMSG$ ($tag$%|loc%$tag$)mails($tag$%END%$tag$)</strong></div><br />
<!-- ($tag$%|loc%$tag$)Pages navigation: ($tag$%END%$tag$)<br /> -->
<span class="search_form">
<a class="ArcMenuLinksSortActive" href="mail$PAGENUM$.html">($tag$%|loc%$tag$)Chronological($tag$%END%$tag$)</a>
<a class="ArcMenuLinksSortInactive" href="thrd$PAGENUM$.html">($tag$%|loc%$tag$)Thread($tag$%END%$tag$)</a>
</span>
</span>
$PREVPGLINK$ ($tag$%|loc($PAGENUM$,$NUMOFPAGES$)%$tag$)page # %1/%2($tag$%END%$tag$) $NEXTPGLINK$
</div>
<!-- end header -->
......@@ -454,6 +454,9 @@ $POWERED_BY$
<input type="hidden" name="in_reply_to" value="$MSGID$" />
<input type="hidden" name="subject" value="Re: $SUBJECTNA$" />
<input type="hidden" name="list" value="($tag$% list %$tag$)" />
<input type="hidden" name="fromname" value="$FROMNAME$" />
<input type="hidden" name="fromaddr" value="$FROMADDRNAME:J$@$FROMADDRDOMAIN$" />
($tag$% IF list_conf.reply_to_header.apply == 'forced' %$tag$)
($tag$% IF list_conf.reply_to_header.value == 'all' %$tag$)
<input type="hidden" name="to" value="$FROMADDRNAME:J$ $FROMADDRDOMAIN$,($tag$% list %$tag$) ($tag$% list_conf.host %$tag$)" />
......@@ -485,6 +488,15 @@ $POWERED_BY$
($tag$% IF is_owner %$tag$)
<br /><input class="MainMenuLinks" type="submit" name="action_view_source" value="($tag$%|loc%$tag$)view source($tag$%END%$tag$)" />
($tag$% END %$tag$)
($tag$% IF listconf.tracking.delivery_status_notification == 'on' || listconf.tracking.message_delivery_notification == 'on_demand' || listconf.tracking.message_delivery_notification == 'on' %$tag$)
($tag$% IF is_owner %$tag$)
<input class="MainMenuLinks" type="submit" name="action_tracking" value="mail tracking" />
($tag$% ELSE %$tag$)
<input class="MainMenuLinks" type="submit" name="action_tracking_percent" value="mail tracking (percentage)" />
($tag$% END %$tag$)
($tag$% END %$tag$)
</form>
</span>
......
......@@ -173,3 +173,17 @@ CREATE TABLE stat_table (
read_stat number NOT NULL,
PRIMARY KEY (id_stat)
);
CREATE TABLE IF NOT EXISTS `notification_table` (
`pk_notification` int(11) NOT NULL AUTO_INCREMENT COMMENT 'primary key of tracking datas. one for each message and each subscriber',
`message_id_notification` varchar(1000) DEFAULT NULL COMMENT 'message-id for which tracking is actived',
`recipient_notification` varchar(1000) NOT NULL COMMENT 'subscriber email',
`reception_option_notification` varchar(10) DEFAULT NULL COMMENT 'qsubscriber reception option. Not all reception option are compatible with tracking',
`status_notification` varchar(1000) DEFAULT NULL COMMENT 'latest notification status received',
`arrival_date_notification` varchar(1000) DEFAULT NULL COMMENT 'latest notification date ( a string extracted from the notification itself)',
`type_notification` enum('DSN','MDN') DEFAULT NULL COMMENT 'DSN or MDN depending of the latest notification received',
`message_notification` longtext COMMENT 'DSN or MDM when received',
`list_notification` varchar(1000) NOT NULL,
`robot_notification` varchar(80) NOT NULL,
PRIMARY KEY (`pk_notification`)
) ;
function showMDN(el) {
var pre = el.parentNode.getElementsByTagName('pre');
if(!pre) return;
var mdn = pre[0].innerHTML;
return showMessage(mdn.replace(/ /g, '&nbsp;').replace(/\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;').replace(/\n/g, '<br />'), true);
}
function showMessage(message, ishtml) { // if ishtml not set then \n to <br /> transformation is applied to message
if(!ishtml) message = message.replace(/\n/g, '<br />');
var body = document.getElementsByTagName('body')[0];
if(!body) return;
var block = document.createElement('div');
block.id = 'ErrorBlock';
body.insertBefore(block, body.childNodes[0]);
var msg = document.createElement('div');
msg.id = 'ErrorMsg';
body.insertBefore(msg, body.childNodes[0]);
var ctn = document.createElement('div');
ctn.className = 'messageContent';
msg.appendChild(ctn);
if(message) ctn.innerHTML = message;
var form = document.createElement('form');
msg.appendChild(form);
var fs = document.createElement('fieldset');
form.appendChild(fs);
var cls = document.createElement('input');
cls.type = 'button';
cls.className = 'MainMenuLinks';
cls.value = 'OK';
cls._body = body;
cls._block = block;
cls._msg = msg;
cls.onclick = function() {
this._body.removeChild(this._block);
this._body.removeChild(this._msg);
};
fs.appendChild(cls);
return ctn;
}
// To confirm archives deletion
function dbl_confirm(my_form, my_message,my_message2) {
if (confirm(my_message)) {
......
......@@ -140,7 +140,7 @@ sub next {
}
# select the packet that has been locked previously
$statement = sprintf "SELECT messagekey_bulkmailer AS messagekey, messageid_bulkmailer AS messageid, packetid_bulkmailer AS packetid, receipients_bulkmailer AS receipients, returnpath_bulkmailer AS returnpath, listname_bulkmailer AS listname, robot_bulkmailer AS robot, priority_message_bulkmailer AS priority_message, priority_packet_bulkmailer AS priority_packet, verp_bulkmailer AS verp, merge_bulkmailer as merge, reception_date_bulkmailer AS reception_date, delivery_date_bulkmailer AS delivery_date FROM bulkmailer_table WHERE lock_bulkmailer=%s %s",$dbh->quote($lock), $order;
$statement = sprintf "SELECT messagekey_bulkmailer AS messagekey, messageid_bulkmailer AS messageid, packetid_bulkmailer AS packetid, receipients_bulkmailer AS receipients, returnpath_bulkmailer AS returnpath, listname_bulkmailer AS listname, robot_bulkmailer AS robot, priority_message_bulkmailer AS priority_message, priority_packet_bulkmailer AS priority_packet, verp_bulkmailer AS verp, tracking_bulkmailer AS tracking, merge_bulkmailer as merge, reception_date_bulkmailer AS reception_date, delivery_date_bulkmailer AS delivery_date FROM bulkmailer_table WHERE lock_bulkmailer=%s %s",$dbh->quote($lock), $order;
unless ($sth = $dbh->prepare($statement)) {
do_log('err','Unable to prepare SQL statement : %s', $dbh->errstr);
......@@ -153,7 +153,9 @@ sub next {
}
my $result = $sth->fetchrow_hashref('NAME_lc');
$sth->finish();
return $result;
}
......@@ -406,18 +408,19 @@ sub store {
my $priority_packet = $data{'priority_packet'};
my $delivery_date = $data{'delivery_date'};
my $verp = $data{'verp'};
my $tracking = $data{'tracking'};
$tracking = '' unless (($tracking eq 'dsn')||($tracking eq 'mdn'));
$verp=0 unless($verp);
my $merge = $data{'merge'};
$merge=0 unless($merge);
my $dkim = $data{'dkim'};
my $tag_as_last = $data{'tag_as_last'};
&do_log('debug', 'Bulk::store(<msg>,<rcpts>,from = %s,robot = %s,listname= %s,priority_message = %s, delivery_date= %s,verp = %s, merge = %s, dkim: d= %s i=%s, last: %s)',$from,$robot,$listname,$priority_message,$delivery_date,$verp,$merge,$dkim->{'d'},$dkim->{'i'},$tag_as_last);
&do_log('debug', 'Bulk::store(<msg>,<rcpts>,from = %s,robot = %s,listname= %s,priority_message = %s, delivery_date= %s,verp = %s, tracking = %s, merge = %s, dkim: d= %s i=%s, last: %s)',$from,$robot,$listname,$priority_message,$delivery_date,$verp,$tracking, $merge,$dkim->{'d'},$dkim->{'i'},$tag_as_last);
$dbh = &List::db_get_handler();
$priority_message = &Conf::get_robot_conf($robot,'sympa_priority') unless ($priority_message);
$priority_packet = &Conf::get_robot_conf($robot,'sympa_packet_priority') unless ($priority_packet);
unless ($dbh and $dbh->ping) {
......@@ -546,7 +549,8 @@ sub store {
do_log('err','Duplicate message not stored in bulmailer_table');
}else {
my $statement = sprintf "INSERT INTO bulkmailer_table (messagekey_bulkmailer,messageid_bulkmailer,packetid_bulkmailer,receipients_bulkmailer,returnpath_bulkmailer,robot_bulkmailer,listname_bulkmailer, verp_bulkmailer, merge_bulkmailer, priority_message_bulkmailer, priority_packet_bulkmailer, reception_date_bulkmailer, delivery_date_bulkmailer) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)", $dbh->quote($messagekey),$dbh->quote($msg_id),$dbh->quote($packetid),$dbh->quote($rcptasstring),$dbh->quote($from),$dbh->quote($robot),$dbh->quote($listname),$verp,$merge,$priority_message, $priority_for_packet, $current_date,$delivery_date;
my $statement = sprintf "INSERT INTO bulkmailer_table (messagekey_bulkmailer,messageid_bulkmailer,packetid_bulkmailer,receipients_bulkmailer,returnpath_bulkmailer,robot_bulkmailer,listname_bulkmailer, verp_bulkmailer, tracking_bulkmailer, merge_bulkmailer, priority_message_bulkmailer, priority_packet_bulkmailer, reception_date_bulkmailer, delivery_date_bulkmailer) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)", $dbh->quote($messagekey),$dbh->quote($msg_id),$dbh->quote($packetid),$dbh->quote($rcptasstring),$dbh->quote($from),$dbh->quote($robot),$dbh->quote($listname),$verp,$dbh->quote($tracking),$merge,$priority_message, $priority_for_packet, $current_date,$delivery_date;
unless ($sth = $dbh->do($statement)) {
do_log('err','Unable to add packet in bulkmailer_table "%s"; error : %s', $statement, $dbh->errstr);
return undef;
......@@ -637,7 +641,7 @@ sub store_test {
my $listname = 'notalist';
my $priority_message = 9;
my $delivery_date = time;
my $verp = 1;
my $verp = 'on';
my $merge = 1;
&do_log('debug', 'Bulk::store_test(<msg>,<rcpts>,from = %s,robot = %s,listname= %s,priority_message = %s,delivery_date= %s,verp = %s, merge = %s)',$from,$robot,$listname,$priority_message,$delivery_date,$verp,$merge);
......
......@@ -570,6 +570,8 @@ sub load_robots {
$robot_conf->{$robot}{'static_content_url'} ||= $Conf{'static_content_url'};
$robot_conf->{$robot}{'static_content_path'} ||= $Conf{'static_content_path'};
$robot_conf->{$robot}{'tracking_delivery_status_notification'} ||= $Conf{'tracking_delivery_status_notification'};
$robot_conf->{$robot}{'tracking_message_delivery_notification'} ||= $Conf{'tracking_message_delivery_notification'};
## CSS
$robot_conf->{$robot}{'css_url'} ||= $robot_conf->{$robot}{'static_content_url'}.'/css/'.$robot;
......
This diff is collapsed.
......@@ -5,7 +5,7 @@ nobase_modules_DATA = admin.pm Archive.pm Bulk.pm Commands.pm confdef.pm \
LDAPSource.pm Scenario.pm PlainDigest.pm report.pm \
tools.pm tt2.pm time_utils.pm Sympa/Constants.pm \
Sympa/Template/Compat.pm Robot.pm WebAgent.pm \
HTML/myFormatText.pm
HTML/myFormatText.pm tracking.pm
EXTRA_DIST = Sympa/Constants.pm.in $(nobase_modules_DATA)
CLEANFILES = Sympa/Constants.pm
......
......@@ -798,6 +798,7 @@ sub probe_db {
'robot_bulkmailer' => 'varchar(80)',
'listname_bulkmailer' => 'varchar(50)',
'verp_bulkmailer' => 'int(1)',
'tracking_bulkmailer' => "enum('mdn','dsn')",
'merge_bulkmailer' => 'int(1)',
'priority_message_bulkmailer' => 'smallint(10)',
'priority_packet_bulkmailer' => 'smallint(10)',
......@@ -917,6 +918,7 @@ sub probe_db {
'robot_bulkmailer' => 'text',
'listname_bulkmailer' => 'text',
'verp_bulkmailer' => 'integer',
'tracking_bulkmailer' => 'integer',
'merge_bulkmailer' => 'integer',
'priority_message_bulkmailer' => 'integer',
'priority_packet_bulkmailer' => 'integer',
......
......@@ -1460,8 +1460,13 @@ our @params = (
vhost => '1',
file => 'sympa.conf',
},
{
name => 'tracking_delivery_status_notification',
default => 'off',
},
{
name => 'tracking_message_delivery_notification',
default => 'off',
},
);
......@@ -21,14 +21,15 @@
package mail;
use strict;
use Exporter;
require Exporter;
use Carp;
use POSIX qw(sysconf);
@ISA = qw(Exporter);
@EXPORT = qw(mail_file mail_message mail_forward set_send_spool);
#use strict;
use POSIX;
use MIME::Charset;
use MIME::Tools;
use Conf;
use Log;
use Language;
......@@ -37,9 +38,9 @@ use Bulk;
use tools;
use Sympa::Constants;
our @ISA = qw(Exporter);
our @EXPORT = qw(mail_file mail_message mail_forward set_send_spool);
use strict;
#use strict;
## RCS identification.
#my $id = '@(#)$Id$';
......@@ -52,7 +53,7 @@ if ($@) {
$max_arg = 4096;
printf STDERR gettext("Your system does not conform to the POSIX P1003.1 standard, or\nyour Perl system does not define the _SC_ARG_MAX constant in its POSIX\nlibrary. You must modify the smtp.pm module in order to set a value\nfor variable %s.\n"), $max_arg;
} else {
$max_arg = sysconf($max_arg);
$max_arg = POSIX::sysconf($max_arg);
}
my %pid = ();
......@@ -282,22 +283,18 @@ sub mail_file {
$data->{'return_path'} ||= &Conf::get_robot_conf($robot, 'request');
## SENDING
unless (defined &sending('msg' => $message,
'rcpt' => $rcpt,
'from' => $data->{'return_path'},
'robot' => $robot,
'listname' => $listname,
'priority' => &Conf::get_robot_conf($robot,'sympa_priority'),
'sign_mode' => $sign_mode,
'use_bulk' => $data->{'use_bulk'},
'dkim' => $data->{'dkim'},
)
)
{
return undef;
}
return 1;
return undef unless (defined &sending('msg' => $message,
'rcpt' => $rcpt,
'from' => $data->{'return_path'},
'robot' => $robot,
'listname' => $listname,
'priority' => &Conf::get_robot_conf($robot,'sympa_priority'),
'sign_mode' => $sign_mode,
'use_bulk' => $data->{'use_bulk'},
'dkim' => $data->{'dkim'},
)
);
return 1;
}
####################################################
......@@ -319,6 +316,7 @@ sub mail_message {
my $message = $params{'message'};
my $list = $params{'list'};
my $verp = $params{'verp'};
my @rcpt = @{$params{'rcpt'}};
my $dkim = $params{'dkim_parameters'};
my $tag_as_last = $params{'tag_as_last'};
......@@ -330,16 +328,15 @@ sub mail_message {
my $from = $list->{'name'}.&Conf::get_robot_conf($robot, 'return_path_suffix').'@'.$host;
do_log('debug', 'mail::mail_message(from: %s, , file:%s, %s, verp->%s, %d rcpt, last: %s)', $from, $message->{'filename'}, $message->{'smime_crypted'}, $verp, $#rcpt+1, $tag_as_last);
return 0 if ($#rcpt == -1);
my($i, $j, $nrcpt, $size);
my $numsmtp = 0;
## If message contain a footer or header added by Sympa use the object message else
## Extract body from original file to preserve signature
my ($msg_body, $msg_header);
$msg_header = $message->{'msg'}->head;
if ($message->{'altered'}) {
$msg_body = $message->{'msg'}->body_as_string;
......@@ -405,6 +402,7 @@ sub mail_message {
push(@sendto, $i);
$j = $i;
}
if ($#sendto >= 0) {
$numsmtp++ ;# if (&sendto($msg_header, $msg_body, $from, \@sendto, $robot));
my @tab = @sendto ; push @sendtobypacket, \@tab ;# do not replace this line by push @sendtobypacket, \@sendto !!!
......@@ -530,7 +528,6 @@ sub reaper {
# $robot(+) : robot
# $encrypt : 'smime_crypted' | undef
# $verp : 1| undef
# $merge : 1| undef
# $use_bulk : if defined, send message using bulk
#
# OUT : 1 - call to sending
......@@ -547,12 +544,11 @@ sub sendto {
my $priority = $params{'priority'};
my $encrypt = $params{'encrypt'};
my $verp = $params{'verp'};
my $merge = $params{'merge'};
my $dkim = $params{'dkim'};
my $use_bulk = $params{'use_bulk'};
my $tag_as_last = $params{'tag_as_last'};
do_log('debug', 'mail::sendto(from : %s,listname: %s, encrypt : %s, verp : %s, priority = %s, last: %s', $from, $listname, $encrypt, $verp, $priority, $tag_as_last);
do_log('debug', 'mail::sendto(from : %s,listname: %s, encrypt : %s, verp : %s, priority = %s, last: %s, use_bulk: %s', $from, $listname, $encrypt, $verp, $priority, $tag_as_last, $use_bulk);
my $delivery_date = $params{'delivery_date'};
$delivery_date = time() unless $delivery_date; # if not specified, delivery tile is right now (used for sympa messages etc)
......@@ -604,7 +600,6 @@ sub sendto {
'priority' => $priority,
'delivery_date' => $delivery_date,
'verp' => $verp,
'merge' => $merge,
'use_bulk' => $use_bulk,
'dkim' => $dkim,
'tag_as_last' => $tag_as_last);
......@@ -662,7 +657,7 @@ sub sending {
my $sympa_file;
my $fh;
my $signed_msg; # if signing
if ($sign_mode eq 'smime') {
my $parser = new MIME::Parser;
$parser->output_to_core(1);
......@@ -694,16 +689,22 @@ sub sending {
if (ref($msg) eq "MIME::Entity") {
$messageasstring = $msg->as_string;
my $head = $msg->head;
$msg_id = $head->get('Message-ID');
$msg_id = $head->get('Message-ID'); chomp $msg_id;
}else {
$messageasstring = $msg;
if ($messageasstring =~ /Message-ID:\s*(\<.*\>)\s*\n/) {
$msg_id = $1;
$msg_id = $1; chomp $msg_id;
}
}#
my $verpfeature = (($verp eq 'on')||($verp eq 'mdn')||($verp eq 'dsn'));
my $trackingfeature ;
if (($verp eq 'mdn')||($verp eq 'dsn')) {
$trackingfeature = $verp;
}else{
$trackingfeature ='';
}
my $verpfeature = ($verp eq 'on');
my $mergefeature = ($merge eq 'on');
if ($use_bulk){ # in that case use bulk tables to prepare message distribution
my $bulk_code = &Bulk::store('msg' => $messageasstring,
......@@ -716,17 +717,17 @@ sub sending {
'priority_packet' => $priority_packet,
'delivery_date' => $delivery_date,
'verp' => $verpfeature,
'tracking' => $trackingfeature,
'merge' => $mergefeature,
'dkim' => $dkim,
'tag_as_last' => $tag_as_last,
);
unless (defined $bulk_code) {
&do_log('err', 'Failed to store message for list %s', $listname);
&List::send_notify_to_listmaster('bulk_error', $robot, {'listname' => $listname});
return undef;
}
}elsif(defined $send_spool) { # in context wwsympa.fcgi do not send message to reciepients but copy it to standard spool
do_log('debug',"NOT USING BULK");
......@@ -780,12 +781,15 @@ sub sending {
# IN : $from :(+) for SMTP "MAIL From:" field
# $rcpt :(+) ref(SCALAR)|ref(ARRAY)- for SMTP "RCPT To:" field
# $robot :(+) robot
# $msgkey : a id of this message submission in notification table
# OUT : mail::$fh - file handle on opened file for ouput, for SMTP "DATA" field
# | undef
#
##################################################################################
sub smtpto {
my($from, $rcpt, $robot, $sign_mode) = @_;
my($from, $rcpt, $robot, $msgkey, $sign_mode) = @_;
&do_log('debug2', 'smtpto( from :%s, rcpt:%s, robot:%s, msgkey:%s, sign_mode: %s )', $from, $rcpt, $robot, $msgkey, $sign_mode);
unless ($from) {
&do_log('err', 'Missing Return-Path in mail::smtpto()');
......@@ -831,19 +835,24 @@ sub smtpto {
my $sendmail = &Conf::get_robot_conf($robot, 'sendmail');
my $sendmail_args = &Conf::get_robot_conf($robot, 'sendmail_args');
if ($pid == 0) {
if ($msgkey) {
$sendmail_args .= ' -N success,delay,failure -V '.$msgkey;
}
close(OUT);
open(STDIN, "<&IN");
if (! ref($rcpt)) {
exec $sendmail, split(/\s+/,$sendmail_args), '-f', $from, $rcpt;
exec $sendmail, split(/\s+/,$sendmail_args),'-f', $from, $rcpt;
}elsif (ref($rcpt) eq 'SCALAR') {
exec $sendmail, split(/\s+/,$sendmail_args), '-f', $from, $$rcpt;
}elsif (ref($rcpt) eq 'ARRAY'){
exec $sendmail, split(/\s+/,$sendmail_args), '-f', $from, @$rcpt;
}
exit 1; ## Should never get there.
exit 1; ## Should never get there.
}
if ($main::options{'mail'}) {
$str = "safefork: $sendmail $sendmail_args -f $from ";
......
# Tracking.pm - this module does the mail tracking processing
# RCS Identication ; mar, 15 septembre 2009
# Sympa - SYsteme de Multi-Postage Automatique
# Copyright (c) 1997, 1998, 1999, 2000, 2001 Comite Reseau des Universites
# Copyright (c) 1997,1998, 1999 Institut Pasteur & Christophe Wolfhugel
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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.
package tracking;
use strict;
use DBI;
use CGI;
use Email::Simple;