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です。 |