2000-10-30(月) [長年日記]
■ アジアカップ
アジアカップ決勝。すげー危なかったけど、勝ててよかった。柳沢が出てきたときはどうしようかと思ったけど(←お約束のコメント)。MVPは川口だな。だてにオールバックじゃないね。昨日は札幌もとうとう優勝を決めたので、かみさん秘蔵のシャンパンを開けようか……って話になったんだけど、飲んだら最後、翌日の出社はないよな、ってことで延期。来週、川崎がナビスコで優勝したら開けよう(関連なし)。なんにせよ、ちゃんと出社した自分をほめてあげたいです。
■ biff
いままで、fetchmail
のログ出力先を/dev/console
にして、xconsole
で眺めていたいんちきbiffだが、もうちょっとマシにしたくなったので作ることにした。こういうチマチマしたもんばっかり作ってるな、最近。いわゆる普通のbiffは、メールサーバーにアクセスして新着メールを監視するものだけど、ウチの環境はメールが届くと同時にprocmail
が振り分けちゃうので、サーバーに溜った時点ではもう遅い。ISPからfetchしてきたと同時になんらかのアクションを起こさないといけない。タイミングとして一番いいのは.qmail
で、メールからSubjectを抜き出すフィルタを作って、その出力を……どこに出そう?
フィルタはメール1通ごとに起動されるから、その出力はどこか別のプロセスで一括して表示しないといけない。プロセス間通信を使えばよろしい。今回は同じマシン上なので、UNIXソケットを使うことにしよう。使い方、イマイチよく知らないけど(笑)。表示側アプリ(サーバー)は、Ruby/Gtkでいい。汎用にするために、来たモノはなんでも表示する汎用コンソール(myconsole
)。
#!/usr/bin/ruby -KE require 'socket' require 'thread' require 'gtk' include FileTest SOCKET = "/tmp/myconsole-#{ENV['USER']}" File.delete( SOCKET ) if exist?( SOCKET ) and socket?( SOCKET ) $gs = UNIXServer.open( SOCKET ) Thread.start do loop do ns = $gs.accept Thread.start do sock = ns while l = sock.gets $log.insert( nil, nil, nil, "\n" + l.chomp ) end end end $gs.close end window = Gtk::Window.new( Gtk::WINDOW_TOPLEVEL ) window.set_title( 'my console' ) window.signal_connect( 'delete_event' ) do false; end window.signal_connect( 'destroy' ) do exit; end logvadj = Gtk::Adjustment.new( 0, 0, 0, 0, 0, 0 ) $log = Gtk::Text.new( nil, logvadj ) logvscroll = Gtk::VScrollbar.new( logvadj ) log_box = Gtk::HBox.new( false, 0 ) log_box.pack_start( $log, true, true, 0 ) log_box.pack_start( logvscroll, false, false, 0 ) window.add( log_box ) $log.show logvscroll.show log_box.show window.show window.set_usize( 8, 8 ) Gtk::main
■ クライアント側のフィルタは単純にこんな感じ(biff
)。
#!/usr/bin/ruby -KE require 'socket' require 'nkf' head = ARGF.gets( "\n\n" ) subject = nil head.each do |line| if /^Subject:\s*(.*)$/ =~ line then subject = $1 elsif subject if /^\s+(.*)$/ =~ line subject += $1 else break end end end if subject then subject = NKF::nkf( '-e', subject ) else subject = 'no subject' end begin SOCKET = "/tmp/myconsole-#{ENV['USER']}" sock = UNIXSocket.open( SOCKET ) sock.puts subject sock.close rescue Errno::ECONNREFUSED end
■ 出力には差出人を加えてもいい。表示させる必要のないメールを判断してスキップするようなプラグインを加えられるようにしてもいいな。
あとは、.qmail
に「|biff
」って行を追加するだけ。セッションの始めにmyconsole
を起動して、(sawmillの設定でタイトルバーとかを消して)画面の隅においておけばよろしい。動作状況はこんな感じ。ああ、こんなに簡単ならとっととやればよかったじゃん。
しかしなんだ。いまうちではfetchmail
がメールを1通fetchすると、qmail-ほげほげ
が走り(←何が走るのかよく知らない)、procmail
が走って振り分けをし、さらにメーリングリストの場合はdispatch
がバックアップを取り、ものによってはcut-egroups
がeGroupsの広告を削ってからqmail-ingect
を呼び出し、さらに今日からbiff
も走るという状態だ。メール1通につきプロセス6個も消費してるし。お大尽な話だなぁ、こりゃ。こういう工夫を自力でどんどん追加できちゃうのって、UNIXならではの楽しみでやんすな。