ここ数ヶ月メイラをMewからIcedoveにしてIMAPを使用しているのだが,INBOXが突然読めなくなってしまった.
Icedoveは以下のメッセージを出力する.
The current command did not succeed. The mail server responded: SELECT failed: Unable to parse internal header at 181712145: T).
他のフォルダは問題なく読めているので,INBOXが壊れてしまったのだろう.
さしあたって壊れたINBOXはinbox.brokenに名前を変え,新しいINBOXにメイルが届くことを確認してinbox.brokenからメイルを救出することを考えた.
簡単なフォーマットでメイルを救出したあとで,IMAP経由で扱える形に変換といった手段である.
以下の手順で救出することを考えた.
以下のコマンドで変換する.
% mbxtomh-lazy inbox.broken temporary
MH形式からmbox形式へ変換する.
% sudo apt-get install nmh % mv temporary ~/Mail % /usr/bin/mh/packf +temporary -file temporary.mbox
mbox形式からmbx形式へ変換する.
% sudo apt-get install uw-mailutils % mv temporary.mbox ~/ % mailutil copy temporary.mbox temporary.mbx
手順を考えるにあたってicatがあればicatでmbx→mbox変換がすぐにできただろうが今のUW IMAPにはない.
とりあえずメイルを救出することはできた... ところがしかし,この方法では未読/既読やタグ(laterとか)といったメタ情報は失われてしまう.
やっぱフォーマット理解して直さないとだめかもしんない.
もう少し調べて以下がわかった.
通常はメタ情報のメイルサイズから次のメタ情報の位置を計算する.ひょっとしたら,メタ情報にあるメイルサイズと,実際のメイルサイズがくい違っているのではないかと考え,正規表現マッチでメタ情報を捉えて調べてみるとその通りだった.
そこで,正規表現マッチでメタ情報を捉えて実際のメイルサイズを計算し,くい違っていたらメタ情報を書換えて記録するスクリプトを書いた.作成したスクリプトをrepair-mbx-sizeとして置いておく.
以下のようにして救出した.
実行してメタ情報修正後のmbxファイルを作成する.
% repair-mbx-size inbox.broken temporary miss-matched size mail[417]: header (2096) != mail size (8530) miss-matched size mail[1472]: header (3430) != mail size (25876) miss-matched size mail[1734]: header (3499) != mail size (11175) miss-matched size mail[1749]: header (4006) != mail size (11121) miss-matched size mail[2264]: header (1902) != mail size (21567) miss-matched size mail[3158]: header (3147) != mail size (5085) miss-matched size mail[6782]: header (3705) != mail size (4660) miss-matched size mail[6975]: header (3977) != mail size (4725) miss-matched size mail[8120]: header (3566) != mail size (5531) wrote 31115 mails.
diffでメタ情報のみの変更でメイルに変更がないことを確認する. 数はそんなにないので目視確認.
% diff --text -u inbox.broken temporary | lv -Ij
今度は未読/既読,タグ情報もうまく復活できた.サイズが狂っていた9通のメイルも特に問題なくIMAP経由で取得できた.
完璧ではないんだろうけど,多くは取り戻すことができたと考える.