存档

文章标签 ‘sendmail’

无聊又写一个用来发邮件的 pm..

2010年7月9日 wd 没有评论

继使用 perl 发中文标题邮件,和中文附件邮件后,又把他们整合了一下写了一个 pm 干这个事。

其实发带附件的邮件应该是有现成的 pm 干这个事的,比如 MIME::Lite 之类,没特殊需求还是用那个吧,这个纯属无聊写的。

文件前面有使用方法。。

package SendMail;
 
use strict;
use warnings;
use Data::Dumper;
use Encode;
use MIME::Base64;
 
=head1 Examples
use SendMail;
 
my $sm = SendMail->new( {
    To => 'you@foo.com, other@bar.com',
    Subject => 'just a test 中文',
    });
 
-- or --
 
my $sm = SendMail->new( {
    From => 'me@abc.com',
    To => 'you@foo.com, other@bar.com',
    Subject => 'just a test 中文',
    } );
 
-- or --
 
my $sm = SendMail->new( {
    From => 'me@abc.com',
    To => 'you@foo.com, other@bar.com',
    Cc => 'cc@foobar.com',
    Subject => 'just a test 中文',
    } );
 
 
$sm->attach( {
    Type => "text/plain",
    Data => "只是一个测试..a test"
    });
 
$sm->attach( {
    Type => 'application/octet-stream',
    Filename => 'test 中文.txt',
    Data => "只是一个 test ..."
    });
 
$sm->test;
 
-- or --
 
$sm->send;
 
=cut
 
 
 
use vars qw($VERSION);
$VERSION = '0.01';
 
our $boundary = "FFFFFFFFKKKKKK";
our $from = 'no-reply@abc.com';
our $subject = "No subject";
 
our $to;
our $cc;
our @body;
 
 
sub new {
    my $package = shift;
    my $info = shift;
 
    $subject = $info->{Subject} || $subject;
    $subject = encode('MIME-B', decode('utf8', $subject));
    $from = $info->{From} || $from;
    $to = $info->{To} || die "Need to set MailTo 'To'!";
    $cc = $info->{Cc} || "";
 
    push @body, "MIME-Version: 1.0";
    push @body, "Content-Type: multipart/mixed; boundary=\"$boundary\"";
    push @body, "";
 
    return bless( {}, $package);
}
 
sub attach {
    my $self = shift;
    my $f_hash = shift;
 
    die "Need data when attach!" if ( not defined $f_hash->{Data} );
 
    my $type = "text/plain";
    $type = $f_hash->{Type} if defined $f_hash->{Type};
 
    my @t;
    push @t, "--$boundary";
    if ( $type eq "text/plain" ) {
        push @t, "Content-Type: $type; charset=utf-8";
    } else {
        my $filename = "file1.txt";
        $filename = encode('MIME-B', decode('utf8', $f_hash->{Filename})) if defined $f_hash->{Filename};
        push @t, "Content-Type: $type";
        push @t, "Content-Disposition: attachment; filename=$filename";
    }
    push @t, "Content-Transfer-Encoding: base64";
    push @t, "";
    push @t, encode_base64($f_hash->{Data});
 
    push @body, @t;
}
 
sub send {
    my $self = shift;
 
    open(my $fh, '|/usr/sbin/sendmail -t');
    $self->print_to($fh);
    close($fh);
}
 
sub print_to {
    my $self = shift;
    my $fh = shift;
 
    push @body, "--$boundary--";
 
    print $fh "From: $from\r\n";
    print $fh "To: $to\r\n";
    print $fh "Cc: $cc\r\n" if $cc;
    print $fh "Subject: $subject\r\n";
 
    for ( @body ) {
        print $fh "$_\r\n";
    }
}
 
sub test {
    my $self = shift;
 
    open ( my $fh, '>-');
    $self->print_to($fh);
    close($fh);
}
 
1;
分类: Linux 标签: ,

使用 perl 发带附件的邮件

2010年7月5日 wd 没有评论

上篇 使用 perl 发带中文标题的邮件后,又研究了下发带附件的。

基本差别不大,主要是那个 Content-type 要变一下。那个 boundary 可以自己随便写,和后面的统一就行了。

my $title = encode_base64("标题", "");
my $body = encode_base64("邮件正文");
my $attach = encode_base64("附件内容");
my $filename = encode('MIME-B', decode('utf8', "文件中文.txt"))
 
open(MAIL, '|/usr/sbin/sendmail -t');
 
print MAIL "From: test\@abs.com\r\n";
print MAIL "To: test\@abs.com\r\n";
print MAIL "Subject: =?UTF-8?B?$title?=\r\n";
print MAIL "MIME-Version: 1.0\r\n";
# print MAIL "Content-type: text/plain; charset=utf-8\r\n";
print MAIL <<EOF;
Content-Type: multipart/mixed; boundary=\"FFFFFFFFKKKKKK\"
 
--FFFFFFFFKKKKKK
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64
 
$body
--FFFFFFFFKKKKKK
Content-Type: application/octet-stream
Content-Disposition: attachment; filename=$filename.csv
Content-Transfer-Encoding: base64
 
$attach
--FFFFFFFFKKKKKK--
EOF
    close(MAIL);
分类: Linux 标签: ,

使用 perl 发送中文邮件标题乱码

2010年6月30日 wd 没有评论

代码如下面,解决乱码的方法是使用 base64 编码。

use MIME::Base64::Perl;
 
open(MAIL, '|/usr/sbin/sendmail -t');
 
my $recver = 'wangdong@abc.com';
my $alertTitle = "中文 asdfsdf sdfsdf sdf sdf s df sd fsd f sd fsd f sdf sdf sdf";
my $alertText = "body ";
 
my $encoded = encode_base64($alertTitle, "");
 
print MAIL "From: alert\@abc.com\r\n";
print MAIL "To: $recver\r\n";
print MAIL "Subject: =?UTF-8?B?" . $encoded . "?=\r\n";
print MAIL "MIME-Version: 1.0\r\n";
print MAIL "Content-type: text/plain; charset=utf-8\r\n";
print MAIL "\n";
print MAIL "$alertText";
 
close(MAIL);

这里面 encode_base64 可以把文本做 base64 编码,要注意的是这个方法的第二个参数,是用来把编码结果进行格式化的,会每 76 个字符插入一个这个参数,默认是换行。

如果不是 utf8 的文本,那把里面的 utf8 改一下就好了。

分类: Linux 标签: ,

命令行发送有附件的邮件

2008年12月1日 wd 没有评论

命令行下面发送邮件比较简单,恐怕都会使用。

$ echo "hello .. " | mail -s subject xxx@abc.com
$ cat /path/to/file | mail -s subject xxx@abc.com
$ mail -s subject xxx@abc.com << EOF
hi
the end..
EOF

上面这些方法都可以发送邮件。还有一种方法。

$ cat a.txt
Subject: test
From: xxx@abc.com
To: xxx@abc.com
 
hi
sdfsdfsdf
the end.
$ cat a.txt | sendmail -t

这样可以把邮件头信息写到文件里面的,你也可以用 php,perl 来打印类似的信息给 sendmail -t ,让他来发。

那么如果有附件应该怎么办?可以使用 uuencode。

$ uuencode a.txt a.txt | mail -s test xxx@abc.com
$ (cat a.txt; uuencode b.txt b.txt; cat c.txt) |sendmail -t

应该说的很明白了吧?

分类: Mail 标签:

sendmail 中自动抄送某个用户的邮件给别人

2007年6月26日 wd 没有评论

sendmail有个 /etc/aliases 配置文件,在里面可以给某个帐号设置alias,这样给这个alias发的邮件,都会给设置好的用户转发过去。要知道sendmail的帐号是和系统帐号联系在一起的,添加mail帐号得给系统添加帐号(qmail可以实现虚拟用户,或许sendmail也可以,而我不知道罢了)。而这个alias帐号却不是必须有得有系统帐号的,只要设置了alias,就可以给alias用户发邮件,就好像系统真有这么一个帐号一样。

关于 /etc/aliases 文件,这里有个文章有说明。下面复制几个例子。

# RFC 822 规定每个域名都需要有一个 "postmaster" 
postmaster      : root
 
# 将 postmaster 的邮件都转发给 root 帐号,当然你下面还可以将root帐号的邮件在转发给别人。
 
# 转发也可以转发到文件
# 比如这个,都说了nobody了还给发邮件,邮件都丢掉
nobody          : /dev/null
 
# 也可以通过管道作为另一个程序的输入
# 比如给procmail,它能实现的功能可就多了,比如可以根据邮件大小转发到不同的用户,或者调用spamassian、clamav来查垃圾邮件和病毒等
# 一个自动的bug跟踪程序
program-bugs: |/usr/local/bin/program-bug-tracker
 
# 也可以转发到多个帐号,用逗号分隔就可以
project-list: johndoe@host1.uiuc.edu,jsmith@host2.uiuc.edu,someone@host.purdue.edu

可以看到功能还是很强悍的,尤其是可以 pipe 到程序,procmail、maildrop都是很不错的过滤程序,能实现很多其他的功能。

标题的要求是“抄送”某个帐号的邮件给别的用户,有点类似监控的意思。怎么实现呢?可能第一个想到的就是类似下面这种方法:

somebody:other1,other2,somebody

这样是不是就能实现抄送呢?这样会造成死循环,呵呵。

看样子似乎只能通过pipe到程序实现了,看procmail、maildrop的文档还不够头疼的。其实还有个简单的方法,就是 .forward 文件。

.forward 文件位于用户的 home 下面,权限是 600 。他的功能和 /etc/aliases 文件类似,不过是 aliases 文件只能由root用户来修改,而 .forward 文件用户自己就可以修改。除了上面aliases能做到的事情外,他还多了一个功能,就是标题要求的功能。

按照标题的要求,只需要在 somebody 用户的 .forward 文件中放入下面的内容就可以了。

\\somebody
other1
other2

要注意 somebody 前面的那个\,就是用来防止转发死循环的。加了\之后,给somebody转发的时候会忽略该用户的 .forward 文件。

分类: Linux, Mail 标签: ,