Maildir/MH用のfromコマンド。
Maildir/MH用のfromコマンドを作成する。 おまけ機能で、印刷に便利な拡張も施す。
図 0. スクリプトmaildirfrom.pl
#!/usr/bin/perl
use strict;
use Getopt::Long;
my($debug)=0; # Debug flag
my($maildir_dir)="/Maildir/new";# Default checking Maildir directory
my($maildir); # Full path of Maildir directory
my($sender_str); # sender string
my($count)=-1; # for mail number counting
my($use_date); # for -use_date command line option
my($list); # Print mail number
my(@print); # The mail number lists to printing out to STDOUT
# Check commandline option.
GetOptions(
# Original from compatible options
"c" => sub {$count=0}, # Count only option
"s=s" => \$sender_str, #
"f=s" => \$maildir, #
# Below original options
"maildir_suffix=s" => \$maildir_dir, # Maildir check directory
"list" => sub {$count=0;$list=1}, # Print mail number
"print=i" => \@print, # Print out specified mail
"debug" => \$debug, # debug flag
"use_date" => \$use_date, # Use date field as output date
) or usage();
$count=0 if($#print>=0);
# Set Maildir directory.
if(!$maildir){
if($#ARGV>=0) {
$maildir=((getpwnam($ARGV[0]))[7])."/".$maildir_dir;
} elsif (defined $ENV{MAIL}) {
$maildir=$ENV{MAIL};
} else {
$maildir=((getpwuid($<))[7])."/".$maildir_dir;
}
}
print "Maildir is $maildir.\n" if($debug);
# Let's go!!
opendir(MAILDIR,$maildir) or die "Can't open directory $maildir";
my(@dirent)=readdir(MAILDIR);
closedir(MAILDIR);
for(my($i)=0;$i<=$#dirent;$i++){
my($fname)=$maildir."/".$dirent[$i];
check_file($fname) if(-f $fname);
}
printf "There %s %d message%s in your incoming mailbox.\n"
, ($count==1?"is":"are"), $count, ($count==1?"":"s") if($count>=0 && $#print<0);
# Check a file
sub check_file {
my($file)=shift;
my($header); # Mail header strings
my($sender);
print "Filename: $file\n" if($debug);
open(MAIL,$file) or die("Cannot open $file");
my($date)=(stat(MAIL))[10];
$date=localtime($date);
while(<MAIL>){
$header.=$_;
my(@line) = split(/:/);
last if(/^$/); # Escape loop at the end of mail header
if($line[0] =~ /return-path/i) {
$sender=$line[1];
chomp($sender);
$sender =~ s/\s*<(.*)>\s*/$1/;
}
if($use_date && $line[0] =~ /date/i) {
$date = $line[1];
chomp($date);
$date=~ s/\s*(.*)\s*/$1/;
}
}
if(!defined $sender_str || $sender =~ /$sender_str/i){
$count++ if($count>=0);
if($count<0){
print "From $sender ".$date."\n";
} elsif($#print>=0) {
for(my($i)=0;$i<=$#print;$i++){
if($i+1 == $count){
print $header;
while(<MAIL>){print $_;}
}
}
} elsif($list) {
print "$count:\t$sender ".$date."\n";
}
}
close MAIL;
}
sub usage {
print STDERR "usage: $0 [-c] [-f maildir] [-s sender] [-maildir_suffix maildir_sufix] [-use_date] [-list] [-print mail_num] [-debug] [user]\n";
exit(1);
}使い方を表示する。
$ maildirfrom.pl -h
usage: maildirfrom.pl [-c] [-f maildir] [-s sender] [-maildir_suffix maildir_sufix] [-use_date] [-list] [-print mail_num] [-debug] [user]
~/Mail/trash内のメール件数を表示する。
$ maildirfrom.pl -c -f ~/Mail/trash/
There are 732 messages in your incoming mailbox.
senderの条件指定をした上で、番号つきのリスト表示をする。
$ maildirfrom.pl -list -s mutoh -f ~/Mail/trash/| head -2
1: mutoh@master.openedu.org Sun Mar 23 01:05:47 2003
2: mutoh@master.openedu.org Mon Mar 24 03:23:20 2003
上記の条件で、1つ目のメールを表示する。
$ maildirfrom.pl -print 1 -s mutoh -f ~/Mail/trash/| head -3
Return-Path: <mutoh@master.openedu.org>
Delivered-To: tmutoh@mx10.freecom.ne.jp
Received: (qmail 7653 invoked from network); 23 Mar 2003 01:01:31 +0900
安全性などの理由から、最近ではmbox形式よりも MaildirやMH形式が良く利用されるようになっています。 Maildir/MH形式では、1メールが1ファイルとなってフォルダにあたる ディレクトリに格納されています。 mbox形式の場合、標準でfromコマンドが用意されており、 ローカルに配送されたメールのsenderや到着日時がわかるようになっていますが、 Maildir/MH形式では標準コマンドとしてはこのようなものは 用意されていないようです。 そこで、Perlを利用して作成してみました。 印刷などにも使えるように、 オリジナルのfromに若干の拡張を施しています。
from [1]が持っているコマンドラインオプションは同じ意味にしています。 fromでは、 -fでmbox形式のメールを取得しますが、 Maildir/MHではディレクトリの中にメールが入っているため、 ここはディレクトリの指定にしています。 しかし、これはオプションを変更した方が良いかもしれません。 追加したオプションは1文字ではなく、長い形式にしてあります。
実際に調べるディレクトリの順番もfromコマンドに 合わせています。 これは以下の順になります。
-fオプションで指定されたディレクトリ。
コマンドラインオプションで指定されたユーザのMaildirディレクトリ [2] 。
HOME環境変数。
実行したユーザのMaildirディレクトリ。
スクリプトの構造自体は、 「MH/Maildir形式のメールの重複を取り除く。」と同じですので省略します。 今回は、Return-Pathフィールドと、 --use_dateオプションで指定された場合はDateフィールドを チェックするようにしていますので、 メールヘッダの終了である空行までループを回しています。
印刷のために、-listと-printオプションを 追加しています。 -listを指定することで、 先頭にメールを指定するための番号が表示されます。 その後この番号を"-print 番号"と指定することで、 そのメールが表示されます。 -printオプションは複数指定可能になっています。 これらは、senderを指定する-sオプションと併用も 可能なので、うまく候補を絞ってください。
| [1] | ソースがインストールされている場合、 /usr/src/usr.bin/from/from.cに ソースがあります。 |
| [2] | 追加した-maildir_suffixオプションで 場所の変更は可能ですが、 デフォルトでは~user/Maildir/newです。 |