[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[debian-devel:13504] Re: How to read a lot of mails(Re: doc-debian-ja)



佐野@浜松です。

In <20001228021020S.nabetani@xxxxxxxxxxxxxxxxxxxxxxxxxxx>,
  on "Thu, 28 Dec 2000 02:10:54 +0900',
   with "[debian-devel:13496] How to read a lot of mails(Re: doc-debian-ja)",
 NABETANI Hidenobu <nabetani@xxxxxxxxxxxxxxxxxxxxxxxxxxx> さん wrote:

> kgh12351@xxxxxxxxxxx (Taketoshi Sano) writes:

> > 私は procmail で振り分けた後、主に t-gnus で nnmh 使って読んでることが
> > 多いです。たまに mew から読む時もありますが。
> 
> 私は procmail で振り分けた後、mail2news(newsgate パッケージ) で
> local news server に放り込んでいます。
> 
> 研究室等の複数人が読む可能性がある場合には便利です。

私も一部の ML については local の news group に流してます。

私の使っているのは JF の「Mail2News ミニハウツー、v1.0, 4 November 1996」に
書かれている mail2news.pl をベースに手を加えたものです。

例えば $HOME/.procmailrc に

:0 Hc
* ^List-name: nlug$
   LINUX/nlug-ml/.

   :0 A
   | /usr/local/lib/mail2news/fakefeed.sh linux-ml.nlug

と書いておいて LINUX/nlug-ml/ 以下に mh 形式で保存すると同時に
ローカルニュースグループ linux-ml.nlug に流すとか。

$ cat /usr/local/lib/mail2news/fakefeed.sh
#! /bin/sh
cat | /usr/local/lib/mail2news/fakeid.pl | \
  /usr/local/lib/mail2news/removegroup.pl | \
  /usr/local/lib/mail2news/mail2news.pl $1

$ cat /usr/local/lib/mail2news/removegroup.pl
#! /usr/bin/perl
# point at the correct location of perl

# header munging loop
while (<STDIN>) {
   last if /^$/;

   print 
   unless /^Newsgroups:/i;

}

print "\n";
print while <STDIN>;   # gobble rest of message

exit $?;

$ cat /usr/local/lib/mail2news/mail2news.pl
#! /usr/bin/perl
# point at the correct location of perl

($program = $0) =~ s%.*/%%;
# ( $version  ) = $] =~ /(\d+\.\d+).*\nPatch level/;
# die "$program: requires at least version 3 of perl\n"
#        if $version < 3;

# $inews = "/usr/bin/inews";
# $iopts = "-h -o \"mail2news gateway\"";
# $inews = "/bin/cat";
# $iopts = "";
$inews = "/usr/bin/inews";
$iopts = "-h -S ";
$postinghost = "localhost";

if ($#ARGV < 0) {
    $newsgroup = "local.m2n_test";
# we'll expect the newsgroup line in the body
} elsif ($#ARGV == 0) {
    $newsgroup = $ARGV[0];
} else {
    die "usage: $program [newsgroup]\n";
}

# in case inews dumps core or something crazy
$SIG{'PIPE'} = "plumber";
sub plumber { die "$program: \"$inews\" died prematurely!\n"; }

open (INEWS, "| $inews $iopts") ||
    die "$program: can't run $inews\n";

# header munging loop
$continuation = 0;

while (<STDIN>) {
   last if /^$/;

   # transform real from: line back to icky style
   # s/^From:\s+(.*) <(.*)>/From: $2 ($1)/;

   s/Message-Id/Message-ID/;

   if (/^\w+.*:/) {
     $continuation = 0; }

   if (/^(Date|Path|Newsgroups|Organization|Message-ID):/i) {
     print INEWS;
     $continuation = 0; }

   if (/^(Subject|From|References|Content-Type):/i) {
     $continuation = 1; }

   if (/^(MIME-.*|Content-Transfer-Encoding|X-.*):/i) {
     print INEWS;
     $continuation = 0; }

   if (/^(Reply-To|In-Reply-To):/i) {
     print INEWS;
     $continuation = 0; }

   if ($continuation == 1) {
     print INEWS; }

   $saw_subject |= ( $+ eq 'Subject' );

   $saw_msgid |= ( $+ eq 'Message-ID' );

   $saw_newsgroup |= ( $+ eq 'Newsgroups' );

   $saw_organization |= ( $+ eq 'Organization' );

   $saw_path |= ( $+ eq 'Path' );

}

   # transform from_ line to path header; also works locally
   s/^From\s+(\S+)@(\S+).*/Path: $2!$1/
     || s/^From\s+(\S+)[^@]*$/Path: $1\n/  unless $saw_path;

warn "$program: didn't expect Path in headers\n"
    if $saw_path;

warn "$program: didn't expect newsgroup in both headers and ARGV\n"
    if $newsgroup && $saw_newsgroup;

die "$program: didn't get newsgroup from either headers or ARGV\n"
    unless $newsgroup || $saw_newsgroup;

$approved = $newsgroup;
$approved =~ s/\./'-'/eg;

($sec,$min,$hour,$mday,$mon,$year)=localtime(time);
$madeupid =
  "\<$year$mon$mday.$hour$min$sec.$$\@m2n.pika.standalone.local.net\>";

printf INEWS "Newsgroups: %s\n", $newsgroup if $newsgroup && !$saw_newsgroup;
printf INEWS "Approved: %s\@localhost\n", $approved;
print INEWS "Subject: Untitled\n" unless $saw_subject;
printf INEWS "Message-ID: %s\n", $madeupid unless $saw_msgid;
# printf INEWS "NNTP-Posting-Host: %s\n", $postinghost;
print INEWS "Organization: (mail2news gateway)\n" unless $saw_organization;
# printf INEWS "Sender: %s\@localhost\n", $approved;
print INEWS "\n";

print INEWS while <STDIN>;   # gobble rest of message

close INEWS;
exit $?;


こんな感じ。ML のメールをローカルニュースグループだけに流すようにすると
 Expire とかは local news server にやらせることができるので便利なんですが
アナウンスとかで複数の ML にクロスポストされたメールは各 ML で別々に届いて
しまうので、後から来たメールは同じ Message-ID を持つために受け取って
もらえないんですよね。

クロスポストの多い ML だとそのへんが問題になるので、一時期けっこう
ローカルニュースグループに集めてましたが、最近は procmail による MH 形式での
保存と t-gnus の nnmh 経由での閲覧を組み合わせてます。

なお expire は自作のスクリプトでやってます。

$ cat ~/bin/purgeOLD
#! /bin/sh
#
# if you wish to check the action, enable next line
# TESTMODE=1
#
name=`basename $0`;
target="";
days=30;
if [ -z "$1" ] ; then
 echo " usage $name PATH DAYs ";
 exit -1;
else
 :
fi
#
# make assure that I am not at $HOME
/bin/mkdir $HOME/bin/.heaven 2>/dev/null
cd $HOME/bin/.heaven || exit 1
#
target=$1;
#
if [ ! -z "$target" ] ; then
  if [ ! -d "$target" ] ; then
    echo "Error on cd to $target!!";
    exit 1;
  fi
  cd "$target"
fi
#
if [ ! -z "$2" ] ; then
 days=$2;
fi
#
if [ ! -z "$3" ] ; then
  echo "test-mode"
  TESTMODE=1
fi
#
FILES=` /usr/bin/find . -daystart -follow -type f \
  -mtime +"$days" `
if [ -z "$FILES" ] ; then
  exit 0;
else
  :
fi
#
if [ ! -z "$target" ] ; then
 echo " -------------------------------- "
 echo "  Path: $target "
 echo "  Expire: $days"
fi
echo " Following files will be deleted : ";
echo "$FILES" | column -x
if [ -z "$TESTMODE" ] ; then
  echo "$FILES"|xargs rm 
#
# /usr/bin/find . \
#  -daystart -follow -type f \
#  -mtime +"$days" |xargs rm -f
#
  echo ""
fi

これを次のスクリプトから呼び出してます。

$ cat ~/bin/purgeMails
#! /bin/sh
LOG=$HOME/log/purgemail.log
PURGE=$HOME/bin/purgeOLD
FIND=/usr/bin/find
SED=/bin/sed
MHFOLDER=/usr/bin/mh/folder
MHSORTM=/usr/bin/mh/sortm
# echo is a shell built-in
XARGS=/usr/bin/xargs
RM=/bin/rm

function do_purge()
{
	TARGET=$1
	DAYS=$2
	if [ -z "$TARGET" ] ; then return -1; fi
	if [ -z "$DAYS" ] ; then return -1; fi
	if [ ! -d "$TARGET" ] ; then
		  echo "Error : requested directory is not valid";
		  echo "Check : $TARGET";
		  return -1;
	fi
	cd $1 || return -1
	FILES=` /usr/bin/find . -daystart -follow -type f -mtime +"$DAYS" `
	if [ -z "$FILES" ] ; then
		  return 0;
	else
		  $FIND $TARGET -follow -name '.mew-cache'|$XARGS $RM -f
		  $FIND $TARGET -follow -name '.mh_sequences'|$XARGS $RM -f
		  $PURGE $TARGET $DAYS >>"$LOG"

#		  for i in `$FIND "$TARGET" -type d -follow -mindepth 1`;
#		    do
#			NAM=`echo "$i"|$SED -e "s,^$HOME/Mail/,+,"`
#			$MHFOLDER -pack "$NAM" >>"$LOG"
#			$MHSORTM "$NAM" >>"$LOG"
#		    done
	fi

}

if [ -f $LOG -a -s $LOG ] ; then
    /usr/bin/savelog -p -t $LOG;
fi

/usr/bin/touch $LOG >&/dev/null
/bin/echo "begin: `/bin/date`" >>"$LOG"
:
do_purge $HOME/Mail/purge/years5/  2000
do_purge $HOME/Mail/purge/years3/  1200
do_purge $HOME/Mail/purge/yearly/   400
do_purge $HOME/Mail/purge/months6/  200
do_purge $HOME/Mail/purge/months3/  100
do_purge $HOME/Mail/purge/months2/   70
do_purge $HOME/Mail/purge/monthly/   33
do_purge $HOME/Mail/purge/weeks2/  16
do_purge $HOME/Mail/purge/weekly/   9
do_purge $HOME/Mail/purge/3days/   5
do_purge $HOME/Mail/purge/daily/   3

/bin/echo "end: `/bin/date`" >>"$LOG"

/usr/bin/mail -s "purgemail.log" sano <$LOG


この purgeMails は crontab に

# weekly purge of mail
30 12 * * 5 $HOME/bin/purgeMails

として登録してあり、週に一度、金曜日の昼に自動で実行されます。

メールを振り分けるディレクトリは $HOME/Mail 以下にあるんですが、
 $HOME/Mail/purge/<expire_duration>/ 以下にそれぞれのディレクトリへの
シンボリックリンクを置いて、<expire_duration> に相当する日数で
 expire されます。

一度失敗して $HOME で rm -rf を始めてしまったことがありますが、
その後改良したのでたぶん今は大丈夫なはず。

-- 
     # (わたしのおうちは浜松市、「夜のお菓子」で有名さ。)
    <kgh12351@xxxxxxxxxxx> : Taketoshi Sano (佐野 武俊)