免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2095 | 回复: 3
打印 上一主题 下一主题

[Mail] 请教:sendmail+mimedefang邮件内容过虑[已经解决] [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-10-20 14:16 |只看该作者 |倒序浏览
系统平台:RHEL4.5
软件:sendmail8.13, mimedefang2.6.3

需求:在本服务器的用户向外发送邮件时,在邮件后面附加类似“免遭声明”之类的声明。只在本地用户发送时和本地用户第一次回复某一主题的时候附加,
         对于已要附加过声明的邮件,在后面的再回复中不再附加。

我现在的做法是:把要附加的内容存储在数据库中。在filter_end中,打开“./INPUTMSG",把经过base64加密的那部分(邮件正文部分)进行decode。
                         然后匹配正文中是否已存在特殊字段,如果有,则不再附加,反之,则附加。

现在遇到问题是:在解码./INPUTMSG时,只有在重启mimedefang服务后第一次能正确解码,后面再发送其它邮件时,解码出来的内容都是乱码了。
                        我在打开"./INPUTMSG"时,拷贝一份到其它目录下,然后利用filter_end中一样的解码过程进行解码,就能够得到正常内容,
                        但是在mimedefang过虑过程中解码得到的却是乱码。不知道是什么原因,下面把部分代码贴出来,大家帮我看一下:


  1. sub filter_end {
  2.     use DBI;
  3.     use MIME::Base64;
  4.     use Encode qw/from_to/;
  5.     my($entity) = @_;
  6.     my ($dsn)="DBI:mysql:database_name:localhost";
  7.     my ($user_name)="username";
  8.     my ($password)="userpassword";
  9.     foreach $recip(@Recipients){
  10.         $recip=~ /<.*@(.*)>/;
  11.         my $domain_to =$1;
  12.         my $localdomain="local_domain";    #定义特殊domain,对此domain发邮件时不附加
  13.         my $sign="ANNOUNCEMENT:";    #定义特殊标志,后面匹配到邮件内容中有此字符串时便不在附加
  14.         if($domain_to !~ $localdomain)
  15.         {
  16.             system("/bin/cp ./INPUTMSG /var/spool/MIMEtmp/INPUTMSG"); #拷贝./INPUTMSG到指定目录,然后可以手动解码看看实际内容
  17.             my $file="./INPUTMSG";
  18.             my $body;
  19.             my $start=qr/^Content-Transfer-Encoding: base64/;
  20.             my $end=qr/^--(?!----=_NextPart)/;                             #定义截取邮件内容的开始和结束标记,即只要$start和$end中间的内容
  21.             open (FILE,$file) or die "Connot open $!";
  22.             while(<FILE>){
  23.                 if((/$start/../$end/) and !/$start/ and !/$end/){
  24.                     $body.=$_;
  25.                     }
  26.                 }
  27.             md_syslog('info',"\$body\'s value is : $body");
  28.             close FILE;
  29.             $de_body=decode_base64("$body");
  30.             md_syslog('info',"\$de_body\'s value is : $de_body");
  31.             if ($de_body !~ $sign)
  32.                 {
  33.                 $dbh=DBI->connect($dsn,$user_name,$password);
  34.                 $sth=$dbh->prepare("SELECT * from  comment where active='YES'");
  35.                 $sth->execute();
  36.                 while(@ary=$sth->fetchrow_array()){
  37.                     ($active,$title,$content)=@ary;
  38.                     }
  39.                 from_to($content,"utf8","gb2312");
  40.                 append_text_boilerplate($entity,"$sign"."$content", 0);
  41.                 append_html_boilerplate($entity,"<br> <hr> <br>"."$sign"."<br><br>"."$content", 0);
  42.                 }
  43.         }
  44.     }
复制代码



另外,这样做,方法本身可能就有问题,在邮件发送量大的时候,处理延迟问题可能就会很突出,能不能在已经附加过声明的邮件中插入一个标记,这个标记可以终身跟随这一主题的邮件,以后只需要检查邮件中有没有该标记,然后就可以决定是否附加声明了?

请各位不吝赐教!谢谢!

[ 本帖最后由 sunrocs 于 2008-10-20 18:30 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-10-20 15:45 |只看该作者
咋没人帮偶看看呢

论坛徽章:
0
3 [报告]
发表于 2008-10-20 18:29 |只看该作者
问题已经搞定.

想想前的打开文件,真不是个什么聪明的方法,现在通过改变邮件的header来实现想要的结果
具体方法:上一封邮件的Message-ID,会现在在回复邮件的References:中,所以我在附加声明之后,修改邮件的Message-ID,在回复时,检查References:中是否含
                有我指定的Message-ID,如果有,则说明此主题的邮件已经附加过,则不再附加,也不会再修改Message-ID,反之则附加声明
实现代码如下


  1. sub filter_end {
  2.     use DBI;
  3.     use MIME::Base64;
  4.     use Encode qw/from_to/;
  5.     my($entity) = @_;
  6.     my ($dsn)="DBI:mysql:database_name:localhost";
  7.     my ($user_name)="database_user";
  8.     my ($password)="database_passwd";
  9.    
  10. md_syslog('info',"\$recipient\' value is : $recipient"."@Recipients");
  11.     foreach $recip(@Recipients){
  12.         $recip=~ /<.*@(.*)>/;
  13.         my $domain_to =$1;
  14.         my $localdomain="local_domain";
  15.         my $sign='aaaabbbbccccddddeeeeffff13456789';
  16.         if($domain_to !~ $localdomain)
  17.         {
  18.             my $file="./HEADERS";
  19.             open (FILE,$file) or die "Connot open $!";
  20.             while(<FILE>){
  21.                 $header.=$_;
  22.                 $id=(split(/:/,$_))[1] if(/References:/);
  23.                 }
  24.             md_syslog('info',"\$id\'s value is : $id,,,,,\$sign=$sign");
  25.             md_syslog('info',"\$header\'s value is : $header");
  26.             close FILE;
  27.             if($id !~ $sign)
  28.                 {
  29.                 action_change_header("Message-ID", "<$sign>");
  30.                 $dbh=DBI->connect($dsn,$user_name,$password);
  31.                 $sth=$dbh->prepare("SELECT * from  comment where active='YES'");
  32.                 $sth->execute();
  33.                 while(@ary=$sth->fetchrow_array()){
  34.                     ($active,$title,$content)=@ary;
  35.                     }
  36.                 from_to($content,"utf8","gb2312");
  37.                 #md_syslog('info',"\$content\' value is : $content");
  38.                 append_text_boilerplate($entity,"$content", 0);
  39.                 append_html_boilerplate($entity,"<br> <hr> <br>"."$content", 0);
  40.                 }
  41.             }
  42.      }
复制代码



PS:代码里只是随便指定了一个$sign,这样每封每一次发出去的邮件都有相同的Message-ID,容易被认为是垃圾邮件,你可以采取一些简单的方法,生成不同的Message-ID,方法这里不再细说

[ 本帖最后由 sunrocs 于 2008-10-21 08:46 编辑 ]

论坛徽章:
8
综合交流区版块每周发帖之星
日期:2015-12-02 15:03:53数据库技术版块每日发帖之星
日期:2015-10-02 06:20:00IT运维版块每日发帖之星
日期:2015-10-02 06:20:00IT运维版块每日发帖之星
日期:2015-09-14 06:20:00金牛座
日期:2014-10-10 11:23:34CU十二周年纪念徽章
日期:2013-10-24 15:41:34酉鸡
日期:2013-10-19 10:17:1315-16赛季CBA联赛之北京
日期:2017-03-06 15:12:44
4 [报告]
发表于 2008-10-21 08:09 |只看该作者
谢谢分享

解决问题的方法值得学习
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP