qmail の Maildir 形式でメールを受け取り、それをシェルや Perl スクリプトで処理する時に、エンコード周りで問題になることが多々ある。
今回は、Maildir 形式で受け取ったメールを Perl スクリプトで処理する場合について、気付いた点を書いていこうと思います。
Maildirの中身
Maildir 形式のファイルを除いてみると、メールヘッダと本文が書かれています。
1 2 3 4 5 6 7 8 9 | [ヘッダの一部] Return-Path: <○○○@example.org> Delivered-To: △△△@example.org From: □□□@example.org To: ◇◇◇@example.org Subject: =?iso-2022-jp?B?GyRCJDMkcyRLJEEkTyQzJHMkSyRBJE8kMyRzJEskQSRPGyhC?= Content-Type: text/plain; charset="iso-2022-jp" Content-Transfer-Encoding: 7bit B:GBgB |
Linux サーバ環境の場合、サーバの文字設定にもよりますが、Windows の Shift-JIS のターミナルからだと日本語は文字化けしています。
件名と本文を確認する
とりあえず sjis に変換して見てやると、Subject と Body は以下のようになります。
1 2 3 4 5 | $ echo '=?iso-2022-jp?B?GyRCJDMkcyRLJEEkTyQzJHMkSyRBJE8kMyRzJEskQSRPGyhC?=' | nkf --sjis こんにちはこんにちはこんにちは $ echo 'B:GBgB' | nkf --sjis 最大 |
これを Perl 内部でどのようにして処理してやるかですが、文字エンコードの変換といえば Jcode のライブラリが有名です。
本文は抜き出して変数($Bodyとする)に入れたら、下記の関数で sjis に変換できます。
1 | &jcode::convert(\$Body,'sjis'); |
サブジェクトの変換
サブジェクトについては同じ方法ではうまくいかないので調べていたのですが、とりあえずは Perl からシェルを呼んで nkf しちゃいました。
(どうにか Perl 内で完結させたいのですが・・・)
また、日本語を含むサブジェクトの場合、Maildir 形式でファイル化した時点で、複数行に折りかえることがあります。
その場合は、Subject: で始まる行だけ抜き出してしまうと、残りのサブジェクトが切れてしまうので要注意です。
例えば、下記の文字列の場合、C の後で改行されます。
(例1)こんにちはABCこんにちは
(例2)こんにちはABCこんにちはABCこんにちは
2 バイト文字と ASCII 文字が混ざると、ASCII 文字の後で改行されるみたいですね。