Maildirの削除

某所で、メールサーバをmboxからMaildir形式に変更し、IMAPに乗り換えた。
メールを読まない(削除しない)不届き者が居るので、古くなったメールを削除してくれないかという依頼があった。
最初は単純に考えて、メールボックス内のファイルをmtimeで削除することを考えた。


# find ~/Maildir -type f -mtime +60 -exec rm {} \;

一見、これで上手くいくかに思えたのだが、imapのパフォーマンスが落ちる。原因を探ったところ、imapのインデックスファイルが削除されてしまう事が判明した。
上記のfindに加えてインデックスファイルを除外すると、上手くいくことが判ったが、どうもコマンド行が長くなりすぎる。
# find ~/Maildir -type f -mtime +60 \
! -name 'courier*' ! -name '.imap*' ! -name 'dovecot*' -exec rm {} \;

更に、ユーザ(約1200アカウント)個別にExpire日数を設定したいという依頼があったり、削除する前にしばらくバックアップしておきたかったり...。

思い切って、Perlで書くことに。。

実際にはユーザ名からExpire日数を取り出すために利用するハッシュ変数%const_expireはファイルにでも書いておいて、起動時に取り出すとすっきりする。


%const_expire = (
"itou" => 100,
"yamada" => 20,
"tanaka" => 50,
)
$passfile = "/etc/passwd";
$uid_min = 500;
$uid_max = 59999;
@db_username = ();
@db_uid = ();
@db_homepage = ();
@db_expire = ();
eval {open( FILE, "< $passfile" ); };
if ($@) {die "Failed in reading password file ($passfile).";};
while( <FILE> ){
chomp( $_ );
@list = split(/:/, $_);
$name = lc($list[0]);
if($list[2]>=$uid_min and $list[2]<=$uid_max) {
push(@db_username, $name);
push(@db_uid , $list[2]);
push(@db_homepath, $list[5]);
push(@db_expire , $const_expire{$name});
}
}

これで、削除対象ユーザの一覧が出来た。
あとはユーザ別にFindを行えば、削除対象ファイルの一覧が作れる。

で、対象メールを隔離して、圧縮。
ファイルの一覧を管理者にメールすればOK。

とはいえ、最初はfindだけでやろうとしてたのに案外手間が掛かったな。