Cyrus IMAPdと腐れExchange Serverのメールをバックアップアカウントへ合成コピーした時に、腐れExchange Serverのメールがダブるので、それを消すツールを作った。
こういうちょいとしたツール作りは楽しい:-)
まあ、普通のまともなメールサーバーなら、Message IDが同じだとメールの同一性は保証されていて、Cyrus IMAPdへスプールしてもインテリジェントにduplicate markを付けて、冗長な同じメールは実データとして格納しないはずだ。
しかし、腐れExchange ServerとOutlookは意味の無いReceivedヘッダをわざわざ追加し、winmail.datとかいう何の役にも立たないゴミを付加してくれるので、さすがのCyrus IMAPdも別のメールとしか見てくれないようだ。
「簡単」と素人を騙して売りつけ、実は制御不能の腐れExchange Serverなんぞ相手にしていなければ、作る必要の無いツールな訳だが、まあ、問題解決のプロセスを考えるのが面白いからよかろう。
で、最初、PHPで組んだ時に、UIDがキーの連想配列にMessage IDを格納して、array_unique()という簡単な処理で、ダブってないMessage IDのリストが作れ、array_diffで、削除すべきメールのリストがすぐ作れた。
だが、盲点は、消されるのはダブっているメールの一方であって、必ずしも腐れExchange Serverのゴミメールじゃないという事だ。
そこで、imap_fetch_overview()で取得したサイズも配列に格納し、array_multisort()で、UID、Message ID、Sizeのそれぞれの配列をソートする。
すると、リストで、ダブっているMessage IDのトップは必ずサイズの小さいものとなり、array_unique()で生き残るのは一番最初に見つかったものなので、サイズの大きいメールが駆逐されるというアルゴリズムにした。
これで完璧だ:-D
しかし、マイクロソフトのもたらす後戻り工数って、全世界規模だとどれくらいの損害額なんだろうなあ。