unixのmailxと共に使うユーティリティ

 戸田は最近(2002年11月)まで、unix上の「mailx」という、 原始的なラインモード(キャラクタインタフェース)の メールソフトを使っていました。 そして、2002年11月末に、POPサーバへアクセスしにいく、 最近の「ごく当たり前」のメール環境に変わったのですが、 Mitch Shimada氏の「popmail」を元に 自分の環境に合わせて大幅に改造したものを使って、 「mailx」を使ったのと同じ要領でメールが読める環境を整えています。 ちなみに、メールの送信は、「mailx」の返信機能で雛型を作って、 エディタで編集し、 sendmailのコマンドモード(非デーモンモード)で送っています。

 電子メールに「書類を添付」するということが一般的になりだした当初は、 添付書類が来たら、そのメールをサーバに残しておいて、 改めてMacintosh上のEudoraを動かしていました。 しかし、現在では添付書類が来てもラインモードで受けるだけにしています。 当然、添付書類はデコード(復元)されないわけですが、 その部分を切り取って手動でデコードしているのです。

 添付書類を送る時も、当初は、 それだけのためにEudoraを起動していたのですが、 現在では、手動でエンコードして、 予め用意してあるMIMEヘッダの雛型にエディタで取り込んでから、 テキストとしてmailxなりsendmailなりで送っています。

 原始的なメールソフトにこだわるようになった元々の理由は、 一般的なグラフィックインタフェースのメールソフトでは、 メールヘッダを自由に操作できないことです。 Microsoft製のメールソフトは論外として (例えば、“全てのヘッダを表示する”という選択肢が存在するにも関わらず、 それを選んでも実際にはごく一部しか出てこなかったりする)、 受信したメールのヘッダを完全にチェックできるEudoraでも、 発信するメールのヘッダの設定は自由にはできません。 それ以外のメールソフトは詳しく調べていませんが、 初心者対応という意味でも、あまり自由に設定できるソフトは少ないでしょうね。

 その後、メールを媒介としたウィルスが広まると、 “ウィルスに対して抵抗力の強いメール環境”という意味でも 重宝するようになりました。 なんせ、添付書類を能動的に開かない限り、 ほぼ100%感染の恐れはありませんから^_^;

 事情説明はさておき、原始的なメールソフトを駆使したければ、 添付書類などの最近のメール機能に対応する処置が必要です。 ここでは、そのために私が開発したツール群を紹介します。

 私と全く同じことを考える人なんて珍しいかもしれませんが、 ツール群の中で用いられているコード変換などのロジックは、 メールに関連する種々の場面で参考になるのではないかと思います。

メールボックスファイルを扱うツール

 unix上では伝統的に「mbox形式」と呼ばれるファイル形式で、 何通ものメールを1つのファイルに入れて扱います (Eudoraも内部的にはこのファイル形式を採用しているようです)。 mailxも、通常の使い方では、特定のmbox形式ファイルに メールがどんどん溜まって行きます。

 私は、このファイルを分類して、 各分類ごと1つのmbox形式ファイルにまとめ、 unixのファイル操作コマンドで整理しているのですが、 まずmailxが作ったファイルを分割せねばなりません。 mailx自身に、メール1通を1つのmbox形式ファイルに出力する機能があるのですが、 出力するごとに末尾に空行を付加するし、 最近増えてきた「utf-8・Big5・中国語EUC・韓国語EUC」などを 日本語EUCと誤認してメチャクチャにするしで、全く使わなくなりました。

 mailxの出力機能を使わなくなった当初は エディタや「行数を指定してファイルを切出すコマンド」で 処理していたのですが、そのうち面倒になって、 mbox形式ファイルを「1通1ファイル」に 分割するツール「mboxdiv」を作りました。 当初はメールが100通以上という状況を想定していなかった (100通以上あると、分割したメールがとんでもないファイル名になる)のですが、 ウィルスやスパムが増えて 1日に100通以上受信することも珍しく無くなってきたので、 2003年9月16日修正で、100個目のファイルには「残りメール全部」が入るように 変更しました。

 メールの仕分けについては、 基本的には内容を見て1つずつ手動指定しており、 分類のための系統的なツールは特に作っていません。 但し、ウィルスメールについては、SWENの流行以降、 量が桁違いに増えてやってられなくなってきました。 幸い、現在利用しているメールサーバはウィルスを判定して除去し、 パターンの決まった文字列に置きかえるので、 この文字列を見て該当メールを除去する、 grepを使ったシェルスクリプトを書いて使っています。

 そんな中で、2002年の春に、琵琶湖博物館の業務で 旧職員のメールボックスファイルを整理する必要に迫られました。 メールマガジンへの登録を解除しないまま居なくなってしまい、 しかも居なくなったことをメールサーバ管理者が認識するのが遅れて 数百通のメールが溜まってしまっている中から、 メールマガジンのメールを排除して残りを抽出せよというのです。 仕方が無いので、mbox形式の「区切り行」に記載されている情報の冒頭部分が 特定の内容になっているメールだけを抽出する「mboxpick」を作りました。

 伝統的なunix環境でメールを扱った場合には、 「区切り行」の冒頭に「Envelope-From」が記載されるので、 ある程度まで発信者別分類が可能です。 ただ、最近主流の「popサーバ」を介したアクセスだと 「Envelope-From」情報は失われます。 従って、mbox形式ファイルを採用している環境でも、 この方法では有効な分類ができない可能性が高くなります。 一般性のあるツールにしようと思ったら、 ヘッダ情報(From:やSubject:など)を見る必要がありますが、 先読みを要するので、処理が複雑になります。 よって、当面の必要が無いので対応していません。

ヘッダ中の日本語などを扱うツール

 電子メールのヘッダは、7bitコードで記述せねばならないことになっています。 つまり、シフトJISなり日本語EUCなりで記述された日本語は使えません。 また、制御文字も通らないことがあります。 つまり、ISO-2022-JP(いわゆるJIS)の日本語も保証できません。 そのため、MIMEという規格の一部として、ヘッダ中の発信者情報やSubjectに 日本語などの文字列をエンコードして埋め込む仕様が定められました。

 ヘッダ中のMIME文字列のデコードは、有名な「nkf」でもできます。 ところが、nkfは汎用に作られていることが災いして、 JIS X0201カナ(いわゆる半角カナ)が入ったファイルを変に変換したり、 最近増えてきた「utf-8・Big5・中国語EUC・韓国語EUC」などを 日本語EUCと誤認してメチャクチャにしたり、不都合が多いのです (utf-8には2002年ごろ対応しています)。 また、日本語圏以外からのメールでは、「Base64」ではなく 「quoted printable」でエンコードする流儀も少なくないのですが、 このように多様になってきている状況にも対応しにくいのです。

 そこで、ヘッダ中のMIME文字列を、とにかく何も考えずに 単純にデコードしてしまうツール「mimehead」を作りました。 現在では、冒頭でコメントした「popmail」にメールヘッダのMIME文字列処理機能を サポートさせたため出番が減っていますが、MIME-Bodyのヘッダには対応しておらず、 ここにMIME文字列がある場合は、相変わらず出番となります。

 全く何も考えていないので、通常の日本語圏からのメールでは、 デコード結果はISO-2022-JP文字列になります。 私の環境では、さらにシフトJISへの変換が必要なのですが、 それはunixコマンドラインの「パイプ」機能を用いて、引続いて行っています。

 本当のところを言うと、ヘッダ中のMIME文字列には 「どのコードで記述された文字列をエンコードしたか」という情報が 含まれていて、それに応じた変換をするのが正しい処置なのですが、 それは必要に応じて変換前の文字列を人間の目で見て対応することにしています。 そもそも、日本語圏以外からのメールでは、 この情報が嘘であることも少なくないんですよね。

 ちなみに、私が新規発信するメールは基本的に英語でSubjectを書きますし、 発信人情報や宛先人情報に日本語文字列は入れないことにしています。 Subjectが日本語のメールへの返事では元のSubjectをそのまま使いますが、 原則としてISO-2022-JP文字列をMIMEエンコードせずに入れています。 これは、ヘッダのMIMEエンコードには、 空白が保存されないという仕様上の欠陥があり、 また、日本語が読める相手へのメールでは、 Subject中のISO-2022-JP文字列が保存されることが多いからです。 しかし、たまに化けてしまう場合があるので、そのような場合に備えて、 シフトJIS文字列を「ヘッダ仕様でMIMEエンコードしたISO-2022-JP文字列」に 変換するツール「enb64sub」も作ってあります。 ヘッダのMIMEエンコードには行長制限があるのですが、 それを気にしないという手抜きをしています。 結果を見て不都合なら、元のテキストに適宜改行を入れて エンコードし直すという使い方を前提にしています。

添付書類などを扱うツール

 メール本体にtextではない部分(いわゆる「添付書類」)を含む メールが増えてきましたが、個別に処理するツールを揃えておけば、 どのような場合にでも対応できます。 送信する場合は、MIMEヘッダなどで挟み込んで組み立てるわけですが、 MIMEヘッダの雛型を用意しておいて、エディタで手動で行っています。 画像などのデータは原則としてWWWページに貼りつけてURLを通知しており、 添付書類を送る頻度は少ないので、これで充分です。

 受信メールの処理には、添付書類を分離する作業が必要ですが、 ずっと手動でやっていました。 手動作業がイヤになってしまうほどの頻度では無かったからです。 ところが、とある事情で添付書類が十何個もあるメールが来てしまい、 これを処理するために、 メールをMIME-Bodyに分割する「mimediv」を作りました。 とはいっても、手抜きの作りになっていて、 MIME-Bodyを区切る境界行を識別する文字列は、 人間がメールヘッダを読んで判断し、指定します。 元々手動作業を平然とやってたのですから、 それくらいは何の苦にもなりません。

 さて、MIME-Bodyに含まれるバイナリファイルはエンコードされるので、 受信時にはデコード、送信時にはエンコードが必要です。 何故かtextをエンコードしてあるメールも増えてきました。 悪名高き「multipart/alternative」を推進している Microsoft系のメールソフトが付けてくるhtmlソースは、 「quoted printable」でエンコードされています。

 MIME以前から存在するuuencodeとかISHとかBinHexとかは 既製のツールがいくらでもありますが、これらに較べると、 MIMEに組込まれる形で普及した「Base64」と「quoted printable」 を単独で処理する既製のツールというのは少ないようです。 それに、この2つは変換規則が単純で、簡単にプログラムできますから、 使い勝手が思い通りのものを自作する方が手っ取り速いのです。

 というわけで、単純なエンコード/デコードのツールとしては、 「Base64」をエンコードする「enbase64」、 デコードする「base64」、そして 「quoted printable」をデコードする「mimeQ」の3つを作ってあります。 「quoted printable」をエンコードせねばならない状況に 遭遇したことは無いので、それは作っていません。 さらに、上述の「mimediv」で分離したMIME-Bodyには MIMEヘッダが付いているので、それを削って本体の「Base64」のみを デコードする「mimeB」も作ってあります。

付記:2003年10月29日修正まで、「base64」と「mimeB」の出力の 最後に余分な1バイトが付加される場合があるというバグがありました。 「Base64」のエンコード文字列は4文字が3バイトに対応し、 最後に2バイト残った場合は3文字、1バイト残った場合は2文字になります。 従って、エンコード文字列を4文字ずつ取っていって最後に1文字残った場合、 その1文字は意味をなしません。 当初は、最後に1文字残ることは無いという前提で書いていたので、 その次に来るべき文字が入る予定のメモリに残っている「最後から4文字目」と 組合わせて適当な1バイトを出力する結果になっていました。 正しくは、この残った1文字を「積極的に無視」せねばならないようです。

 ちなみに、「Base64」と「quoted printable」の使い分けですが、 方式の原理の違いとしては、「Base64」はデータの質に関わらず 全てのデータを一定の法則でエンコードするのに対して、 「quoted printable」は「通常の文字」でないデータだけを変換する という違いがあります。 従って、文字主体ではあるが、 環境によって正常に転送されないような文字が含まれている という場合に「quoted printable」を用い、 文字以外のデータが主体の、いわゆる「バイナリファイル」には 「Base64」を使うというのが本来の用法ということになりますが、 必ずしも守られていないようです。 特に、spamメールによく施されている 「spamよけフィルタを回避するためのエンコード」では、 「quoted printable」で、エンコードする必要の無い「通常の文字」を 意図的にエンコードする例が見受けられます。

 「quoted printable」のエンコードは単純に16進数を使うのですが、 この16進数に使う「A」〜「F」の“数字”は 大文字でも小文字でも良いことになっているようです。 しかし、実際には殆どの場合に大文字が使われるので、 小文字への対応をしばらくサボっていましたが、 2004年6月13日バージョンで対応しました。

特殊なコード変換を行うツール

古い日本語非対応Macintoshからのメール

 最近は出番がありませんが、 かつて、非日本語圏で日本語を使っている人からのメールで、 「quoted printable」をデコードしても全然意味を為さない というケースがよくありました。

 これは、相手方Macintoshのメールソフトが 日本語非対応だった場合に起り得る現象です。 日本のパソコンで一般的なシフトJISは、 文字コード80H以上の部分で日本語文字列を表現します。 ところが、欧米のパソコンでは、 この部分にアクセントつきのアルファベットや、 諸々の記号類が割り当てられているのが普通でした。 そして、その流儀もIBM-PCとMacintoshで全然違うという状況でした。

 その後、ISO-8859-1(Latin-1)という標準が制定され、 unicodeの冒頭部分もこれを踏襲しています。 そこで、Macintoshのメールソフトなどでは、 文字コード80H以上の記号類をISO-8859-1の文字に変換して 扱うということが行われるようになりました。 Macintoshの記号類とISO-8859-1の文字は一致せず、 一方にしか存在しない記号が沢山あるのですが、 強引にコジつけて「1対1対応」を作った変換表が、 何故か事実上標準化していました。

 日本語非対応のメールソフトは、 当然「シフトJIS」などという存在を知りません。 従って、シフトJISで書かれた日本語文字列を「記号類」と解釈して、 それをISO-8859-1に変換してしまい、さらに 「quoted printable」でエンコードしてしまうわけです。 これを元のシフトJISに戻すツールが「macmime」です。

 なお、このツールは、NetNewsでの議論を元に開発したものです。 議論の内容については、適当な過去記事アーカイブで、 fj.questions.misc,fj.kanji,fj.net.mimeに私が投稿した <4dvaji$2na@nws-5000.lbm.go.jp> (22 Jan 1996 06:24:50 GMT)から始まるスレッドや fj.kanjiに投稿があった <6cdl2c$f6k$1@mail1.gadget.ne.jp> (Wed, 18 Feb 1998 03:40:58 GMT)から始まるスレッドを参照してください。

HTML中にコードで埋め込まれたunicode文字

 html形式で来るメールの中に「&#12354;」などという形の 文字列がズラズラ並んでいることがあります。これは、htmlの規格で、 文字を表わすコードを10進数で書いて表現する形式なのです。 この場合、コードは必ずunicodeで表現することになっています。

 htmlの規格ですから、比較的新しいWWWブラウザがあれば簡単に読めるハズです。 しかし、単純にブラウザで読んでしまうと、htmlファイルの中に書いてある 画像ファイルなどへ勝手にアクセスしに行ってしまいます。 画像なら単に遅くなる程度で済むのですが(とはいえ、それ自体迷惑な話ですが)、 Javascriptやプラグインなどだったりすると、危険なことになるかもしれません。

 ですから、WWWブラウザの機能を有さない環境で読める必要があるのですが、 そんな環境は私の知る限りありません。 従って、実在する他の環境で読めるような形式に unicode文字列を変換してやる必要があるわけです。

 ところが、この数字を単純に2バイトキャラクタにしてもダメです。 この方式を「UCS-2」と呼ぶ(コード変換ツールなどでは 単に「unicode」と呼んでいる場合がある)のですが、 通常のASCII文字列をそのまま共存させることができず、 UCS-2の流儀に合わせて変換してやる必要があるのです。 この場合、ASCII文字も2バイトキャラクタで表現されるため、 ファイルサイズが肥大します。 元々ならASCIIの部分は素直に読めたのですが、 それも読みにくくなります。これでは、あまり嬉しくありません。

 unicodeのファイル表現形式には、変換規則を若干複雑にすることによって、 ASCII文字がそのまま共存できるようにした「UTF-8」という方式もあります。 そこで、「&#12354;」などという形の表現を UTF-8に変換するツール「htmlcode」を作りました。

 なお、htmlには文字コードを10進数ではなく16進数で表現する形式もあります。 実際にメールで使われる例が少ないため、しばらく対応をサボっていましたが、 2004年5月17日バージョンで対応しました。

「UNIXのmailxと共に使うユーティリティ」の ダウンロード

 プログラムは全て、unixのキャラクタインタフェースの環境(cshとか)で 使う前提で書いてあります。NEWS-OS Rel.6で日常的に使っています。

 原則として、MS-DOS上でも動作するように書いてあります (Quick C Ver.2で一通り確認済、 但しコマンドオプション処理が対応できないものあり)が、 バイナリ入出力をリダイレクトで行うと正常動作しないので注意してください (標準入出力のモードを切り替える必要があり、厄介なので対応していません)。

 本ページの掲載にあたって、いくつか代表的なものを Windows上のVisual C++ Ver.6でコンパイルしてみたところ、 MS-DOSウィンドウで動作するWin32アプリケーションとして 使えそうだということが判りました。 但し、MS-DOSとunixとで動作を変えてある部分は 基本的にMS-DOSの流儀に従わねばならないのですが、 元のソースのままだとunixの流儀で作ってしまうので、 その部分だけ修正が必要です。

 そのうち気が向いたら、Windowsの通常のグラフィックインタフェースの アプリケーションに書換えるかもしれませんが、当面予定はありません。


2002年1月19日初稿/2004年6月13日ソフトウェア最終改訂/2004年11月30日説明文最終改訂/2014年1月23日ホスト移転

戸田孝の雑学資料室へ戻る
Copyright © 2002 by TODA, Takashi