分享小弟針對emos 1.3備份mail perl 程式!
分享小弟針對 emos1.3 系統備份mail perl 程式!小弟接觸perl 才二星期,寫得很粗糙,可能不適合各位大大,但因為小弟受到各位大大照顧,才能建置emos mail server ,所以想為論壇儘點棉薄之力,謝謝各位大大!!!
#!/usr/bin/perl
use File::Copy;
use File::stat;
use Date::Format;
use Mail::Internet;
use Encode qw/encode decode/;
use Encode;
use Encode::Guess qw/big5-eten utf8/;
#使用 postfix rcpt_bcc_list、send_bcc_list設定,將要備份mail 轉寄至 lin 目錄
sys_copy('/home/domains/mail.xxxx.com.tw/lin/Maildir/cur/','/backup/mail/');
sys_copy('/home/domains/mail.xxxx.com.tw/lin/Maildir/new/','/backup/mail/');
#要篩選使用者
@user=("jliu","young7","elaine","pacila","woodyg","doreen","gisele","jessice","liky","chris","enerce","sunny","jenny");
if (! -e "/mailbackup/anyone/") { mkdir("/mailbackup/anyone/", 0755);}
my $mail_size = sprintf("%.2f",dir_size('/mailbackup/')/1024);
#燒錄容量大小(MB)
my $burn_szie = 4200;
#檢測要燒錄檔案是否超過容量
if ($mail_size >= $burn_szie) {
$iname = makeISO();
burniso($iname);
print "燒錄mail成功!!\n";
#正式刪除mail檔案,只保留ISO檔
!system "rm -rf /mailbackup/*" or die "can't delete:$!--/mailbackup/*\n";
die mail("jacky\@mail.xxxx.com.tw","已燒錄mail備份成功 !!","" );
}
print "mail目錄現有容量共有:$mail_size MB\n";
my $total_size;
#針對 目錄 /backup/mail/ 下所備份mail 作處理
for $file (</backup/mail/*>) {
$i = 'Y';
$x = 'N'; # =Y時,此信件有要備份使用者
$y = 0 ;
#獲得檔案建立日期
my $date_string = time2str("%Y-%m-%d %H-%M",stat($file)->mtime);
#獲得檔案容量大小,sprintf 四拾五入
my $filesize = sprintf("%.2f", (-s $file)/(1024*1024));
print "filesize=$filesize MB\n";
my $subj;
open FH, $file;
@all=<FH>;
close(FH);
while ($y <= $#user){ # $#user 帶出 @userb陣列總共有幾個元素
for $num(@all){
#針對 @user 使用者作篩選
if (($num =~ /^To: .*$user[$y]\@mail.xxxx.com.tw/)||
($num =~ /^Return-Path: <$user[$y]\@mail.xxxx.com.tw>/)||
($num =~ /^Cc:.*$user[$y]\@mail.xxxx.com.tw/)||
($num =~ /for.*$user[$y]\@mail.xxxx.com.tw/)){
print "name=$user[$y]\n";
#print $_ while (<FH>);
#print "$file\n";
$x = 'Y';
} elsif (($num =~ /^Subject:/i) && ($i eq 'Y')){
chomp($num); #去除變數值的最後換行符號(\n)
#將主旨(subject)含有中文字轉換為可視中文
if (($num =~ /\?utf-8\?/i)||($num =~ /\?big5\?/i)){
if ($num=~/\?B\?/){
use MIME::Base64;
$num =~/\?B\?.*\?/;
$num1 = substr($&,3,length($&)-4);
#print "num=$num\n";
$subj = decode_base64($num1);
} elsif ($num=~/\?Q\?/) {
use MIME::QuotedPrint;
$num =~/\?Q\?.*\?/;
$num1 = substr($&,3,length($&)-4);
$subj = decode_qp($num1);
}
#針對utf8 -> big5
if ($num =~ /\?utf-8\?/i){
$subj= encode("big5",decode("utf8",$subj));
#print "num=$num\n";
#print "長度=length($num)\n";
}
} else {
#print "原文英文信:$num\n";
$num1 = substr($num,9);
my $enc = guess_encoding($num1) ;
if ((length($num1) > 0) && (($enc -> name) eq "big5-eten")) {
#print "中文信:$num1\t",$enc->name,"\n";
$subj=$num1;
} else {
$subj = substr($num1,0,42);#針對超過64字元長字串進行裁減
#printf "裁減英文信:$subj ,長度:%s\n",length($num1);
}
}
#print"----$file---\n";
$i = 'N';
} else { next;}
}
if ($x eq 'Y'){
$dir = "/mailbackup/$user[$y]/";
#print "dir=$dir\n";
if (! -e $dir) { mkdir($dir, 0755);} #辨別是否有此使用者目錄,如沒有此使用者就新增此目錄
print "$date_string $subj.eml\n";
copy("$file", "$dir$date_string $subj.eml");
unlink $file if -e $file;
if (! -e $file) { print "$file 已備份匯出!\n"; }
last; # 此信件已尋找到符合帳號,所以跳出 while迴圈:
}
$y++;
}
#針對無法辨識信件歸類至 anyone目錄
if (-e $file) {
$dir = "/mailbackup/anyone/";
copy("$file", "$dir$date_string $subj.eml");
print "name=anyone\n";
print "$date_string $subj.eml\n";
unlink $file if -e $file;
print "$file 已備份匯出!\n";
}
$total_size = $total_size + $filesize;
print "匯出mail容量累計:$total_size MB\n";
$mail_tol = $mail_size+$total_size;
print "總容量:$mail_tol MB\n";
if ($mail_tol >= $burn_szie){
print "mail匯出已超過 $burn_szie MB容量,請放入DVD 片!!\n";
$iname = makeISO();
burniso($iname);
#正式刪除mail檔案,只保留ISO檔
!system "rm -rf /mailbackup/*" or die "can't delete:$!--/mailbackup/*\n";
mail("jacky\@mail.xxxx.com.tw","已燒錄mail備份成功 !!","" );
}
last if ($mail_tol >= $burn_szie);
print "換檔案\n";
}
# 複製完刪除
sub copy_dir{
my $source = $_[0];
my $target = $_[1];
use File::Copy;
opendir(DIR,$source);
while(my $filename = readdir(DIR)){
if(-f "$source/$filename"){
copy("$source/$filename","$target/$filename") or die "can't copy: $!--$source/$filename\n";
unlink "$source/$filename" if -e "$source/$filename";
}
}
close(DIR);
}
#呼叫系統 shell cp
sub sys_copy{
my $source = $_[0];
my $target = $_[1];
#use File::Copy;
opendir(DIR,$source);
while(my $filename = readdir(DIR)){
if(-f "$source/$filename"){
!system "cp -rfp $source/$filename $target/$filename" or die "can't copy: $!--$source/$filename\n";
unlink "$source/$filename" if -e "$source/$filename";
}
}
close(DIR);
}
#回傳指定目錄大小(KB)
sub dir_size{
$dir = `du -sk $_[0]` ;
$dir =~ s/$_[0]//; #去除多餘文字
$dir =~ s/\s+//; #去除空白地方
return $dir;
}
sub round {
my $val = shift;
my $col = shift;
my $r = 10 ** $col;
my $a = ($val > 0) ? 0.5 : -0.5;
return int($val * $r + $a) / $r;
}
#製作影像檔
sub makeISO {
($sec,$min,$hour,$day,$mon,$year)=localtime(time);
$year+=1900 ;
$mon++ ;
$isoname = "mailbackup$year-$mon-$day.iso";
#$iso = Filesys::MakeISO->new;
#$iso->image('mailbackup.iso');
#$iso->dir('/mailbackup');
#$iso->make_iso;
#if(!$iso) {mail("jacky\@mail.xxxx.com.tw","無法制作ISO檔!!","$!" );}
!system "mkisofs -o /backup/mail-iso/$isoname -r -J -graft-point /mailbackup/=/mailbackup/"
or die mail("jacky\@mail.xxxx.com.tw",'無法製作ISO檔!!',"$!" );
return $isoname;
}
sub burniso {
$isoname = $_[0];
!system "cdrecord -v dev=2,0,0 fs=8m speed=4 -data -sao driveropts=burnfree /backup/mail-iso/$isoname" or die unlink "/backup/mail-iso/$isoname" if -e "/backup/mail-iso/$isoname" and mail("jacky\@mail.xxxx.com.tw","無法燒錄ISO檔:$isoname!!","$!" );
}
#sub del_file {
# ;
#}
sub mail {
#收件者
$to = $_[0];
# sendmail 程式路徑位址
my $mailprg = "/usr/sbin/sendmail -t";
# 寄件者 l
my $from = "root\@mail.xxxx.com.tw";
#主旨
my $subj = $_[1];
#內容
my $messg = $_[2];
open (MAIL,"|$mailprg") || die "$!\n";
print MAIL "Return-Path: $from\n";
print MAIL "From: $from\n";
print MAIL "To: $to\n";
print MAIL "Subject:$subj\n";
print MAIL "\n";
print MAIL "$messg\n";
print MAIL "--- mail message for xxxx (c) 2009 written by mailbackup\n";
close(MAIL);
print "OK!\n\n";
}
[[i] 本帖最后由 hmfjacky 于 2009-7-29 15:28 编辑 [/i]] 狂顶!!!兄弟的脚本很详细哦!!很感谢,希望以后有更多好的作品问世!! 1楼的台湾老大太强悍了,学2周就能写那么复杂的程式,太崇拜了:funk: :funk: 顶礼膜拜中...:lol :lol 支持顶顶,写得太复杂了。 偶像呀, :handshake 感谢分享! 我不懂,但上面几份老大都说好,肯定非常不错,:handshake 小弟最近想將 mail backup ISO 檔案名稱,加上mail 備份時間的期間,好讓以後要尋找mail 不用那麼辛苦,小弟已做到可以搜尋最大、最小日期,所以先將程式 post 出來,如果和主程式測試成功,另外找時間將主程式一齊post 出來,謝謝。
#! /usr/bin/perl
use File::Find;
# 路徑設定,命令列輸入路徑
my $dir=shift;
#print "dir=$dir\n";
my @array; #儲存 sub do_search 所搜尋到檔案日期
find(\&do_search, $dir);
#print "array=@array\n";
diff(@array);
#搜尋檔案名稱日期格式
sub do_search {
$name = $File::Find::name;
if (-f $name){
if ($name =~ /(\d+)\-(\d+)\-(\d+)/){ #搜尋檔案名稱含有日期(2009-11-02)
$content = $&; #搜尋完畢,將搜尋到字串帶入變數
#print "$content,$name\n" if ($content =~ s/\-//g);
#去掉日期多餘符號(-),並塞給陣列(@array)
push @array,$content if ($content =~ s/\-//g);
}
}
}
#將搜尋到日期帶入,求最大、最小日期
sub diff {
my @param = @_;
my ($max, $min) = ($param[0], $param[0]);
for (@param) {
$max = $_ if $_ > $max; # 求最大值
$min = $_ if $_ < $min; # 求最小值
}
print "max=$max\n";
print "min=$min\n";
}
[[i] 本帖最后由 hmfjacky 于 2009-11-12 16:36 编辑 [/i]] 实在太猛了,希望enjoylinux老大可以集成到emos里啊! 好东西,看来就可以用上了 好东西啊。支持支持。正在学习中 [i=s] 本帖最后由 hmfjacky 于 2011-2-11 13:55 编辑 [/i]
各位大大,好久不見,去年工作太忙了,一直沒有時間上來,真的很抱歉。小弟應該只針對下面二隻子程式作稍微修改,先將備份日期期間當作目錄名稱,並針對/mailbackup目錄,各別user製作各別壓縮檔(因以前小弟在製作影像檔並燒錄成光碟片時,發現mail 檔名是繁體中文時會打不開,所以先壓縮再來燒錄就不會出現奇怪問題),再燒錄成光碟片。
因小弟比較沒時間上來論壇,如果有問題要互相切磋可以 mail 小弟信箱:[email]jacky@yfang.idv.tw[/email],謝謝。
#製作影像檔
sub makeISO {
($sec,$min,$hour,$day,$mon,$year)=localtime(time);
$year+=1900 ;
$mon++ ;
#搜尋 /mailbackup 內檔案日期最大及最小值,把備份日期當作目錄名稱
find(\&do_search,"/mailbackup");
#print "array=@array\n";
$name = diff(@array);
if (! -e "/backup/mail-iso/$name") { mkdir("/backup/mail-iso/$name", 0755);}
#針對各user製作各別壓縮檔
my @catalog = </mailbackup/*>;
#print "file=@files\n";
for $catalog(@catalog){
$catalog =~ /\/mailbackup\//i; #$'代表字串中比對成功之後的部分
!system "zip -r /backup/mail-iso/$name/$'.zip /mailbackup/$'" or die mail("jacky\@mail.xxx.com.tw","無法製作壓縮檔$'!!","$!" );
}
#製作影像檔
!system "mkisofs -o /backup/mail-iso/$name.iso -r -l -J -graft-point /$name/=/backup/mail-iso/$name" or die
mail("jacky\@mail.xxx.com.tw",'無法製作ISO檔!!',"$!" );
#刪除 tar 檔
#unlink "/backup/mail-iso/$name.tar.gz" if -e "/backup/mail-iso/$name.tar.gz";
return "$name.iso";
#print "iso檔名:$name.iso\n";
}
#將搜尋到日期帶入,求最大、最小日期
sub diff {
my @param = @_;
my ($max, $min) = ($param[0], $param[0]);
for (@param) {
$max = $_ if $_ > $max; # 求最大值
$min = $_ if $_ < $min; # 求最小值
}
print "max=$max\n";
print "min=$min\n";
#回傳檔名
$year = substr $max,0,4;
$mon = substr $max,4,2;
$day = substr $max,6,2;
$max = "$year-$mon-$day";
$year = substr $min,0,4;
$mon = substr $min,4,2;
$day = substr $min,6,2;
$min = "$year-$mon-$day";
return "mailbackup$min~$max";
} 非常感谢台湾的兄弟贡献那么好的东西!!!再次感谢,感谢一万次。哈哈~~ [i=s] 本帖最后由 hmfjacky 于 2011-2-14 17:03 编辑 [/i]
小弟今天發現mail 備份燒錄出來時,只要mail 檔名含有分號[:]就無法在windows系統下打開,小弟在linux是可以打開,所以先前沒有注意到,真的是太對不起各位大大。所以今天重看程式,想要加入剔掉分號,但有點不能理解先前的寫法,所以二、三天改完程式再post 到網站上,謝謝! [i=s] 本帖最后由 hmfjacky 于 2011-2-16 09:41 编辑 [/i]
針mail 檔名在windows 系統不能有特殊符號[\/:*?"<>|],小弟增加一段程式來更換為(_)字元:
#100/02/15 因windows系統檔名不能含有特別符號(\/:*?"<>|),所以更換為(_)字元
#但有二個字元(/"),沒辦法替換,還要繼續研究
$_ = $subj;
if ((tr/\\\/:\*\?\"\<\>\|/_/)>0){
$subj = $_;
#print"is change character subj--- $subj\n";
} 小弟上傳一個程式,可修改先前已作完備份,含有特殊符號的mail檔名。
#!/usr/bin/perl
for $file (</backup/mail-iso/mailbackup2010-11-26~2011-01-07/mailbackup/*>) {
if (!-f $file){
print " $file as floder\n";
#搜尋目錄下檔案:
opendir(DIR, $file);
@array = readdir(DIR);
foreach $filename(@array){
print "file--$filename\n";
$_ = $filename;
if ((tr/\\\/:\*\?\"\<\>\|/_/)>0){
#更改檔名
rename("$file/$filename","$file/$_");
print"is change character subj--- $_\n";
}
}
}
} 顶一下兄弟的帖子,难得的技术原创精华牛贴!! 2周。太强悍了 楼主挺厉害的
页:
[1]