トップ 最新

ただのにっき

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ならではの楽しみでやんすな。