maildirmakeコマンドはmaildir形式のメールディレクトリおよび maildirの (サブ)フォルダの作成を行います。 ここではCourierメールサーバの maildirmakeコマンドについて説明します。 CourierメールサーバではQmailメールサーバでのmaildir形式を いくつか拡張しています。
"maildir"はディレクトリであり、1メッセージ1ファイルの形で保持されます。 ただ単なるディレクトリではなく、 ロッキングメカニズムなしでメールアクセス可能なように特定の構成を持っており、 また特定のアクセス許可を与えられています。 maildirmake コマンドではこのmaildirを簡単に作成するためのものであり、 またmaildir内のフォルダも作成できます。
共有可能なmaildirを作成します。 共有可能なmaildirは共有フォルダが作成可能となるよう、 アクセス許可が若干異なっています。
maildirの新規作成ではなく、すでにあるmaildir内にフォルダを作成します。
共有可能なmaildir内に共有フォルダを作成します。 まず最初に-S オプションで共有可能なmaildirを作成します。 次にmaildirmake を-s オプション付でもう一度実行して共有フォルダを作成します。 modeはコンマで区切られた以下のキーワードの組み合わせです: read - 読み取り専用フォルダで、書き込みはあなたしか行えません ; write - 誰でも読み書き可能です; group - あなたの現在のグループからのみアクセス可になります。 (指定されないと誰でもアクセスできます。)
共有フォルダにアクセスするために必要なディレクトリとリンクを 作成したり削除したりします。下記を参照してください。
maildirmake コマンドではフォルダを含むことのできる、 拡張されたmaildirを作成します。
単独では、maildirmake は maildirで指定されたディレクトリを作成し、maildirとして必要な構成を作成します。 -f オプションをつけると maildir内に新しい"フォルダ"を作成します。maildirはすでに存在していて、maildirmakeコマンドはそのmaildir内に新しいフォルダを作成します。
フォルダはmaildir内のサブディレクトリで、 ディレクトリ名はピリオドで始まり、それ自身はmaildir形式です。 例えば、 "maildirmake -f Drafts mail/Maildir"コマンドは mail/Maildir/.Draftsディレクトリを作成し、その中に that has the usual tmp、 new、curの3つのサブディレクトリを作成します。 直接mail/Maildir/.Draftsを指定するのではなく、-fオプションを指定しなければなりません。 そうでないと正しくmaildirの機能拡張が使えなくなります。
フォルダは他のフォルダ内に直接作成できません。maildirmake -f Urgent mail/Maildir/.Draftsという指定は無効です。 代わりに、ピリオドを階層のセパレータに使って、maildirmake -f Drafts.Urgent mail/Maildirのように実行してください。 このコマンドで mail/Maildir/.Drafts.Urgentディレクトリが作成され、これにより 拡張maildir形式を扱えるすべてのプログラムで あたかもDraftsのサブフォルダのように動作します。
maildir形式に対するもう1つの拡張として、 複数のユーザで共有可能なフォルダ機能があります。 まず、共有可能なフォルダを集めるための、maildirを作成する必要があります:
この例では、誰でも読み書き可能な "Weekly" フォルダが作成されます。 同じmaildirフォルダにアクセス権の異なる複数の共有フォルダを作成できます。 誰でも共有maildirを作成できます。個別のフォルダのアクセス権は-s オプションで指定され、 これはOS固有のファイルアクセス権の設定により実装されています。
--addと --delオプションの使用により既存のmaildirに共有maildirへのアクセスを設定できます。 この拡張機能を持ったプログラム経由で共有フォルダにアクセスできます:
$HOME/Maildirはあなたのmaildirディレクトリです。 -addの引数は nick=pathであり、 nick はこの共有フォルダ群につけるフォルダ名、またpath は共有maildirのディレクトリです。 これで共有maildir内のすべての共有フォルダ -- たとえば "Weekly" -- がアクセス可能になります。 前記nickを変えることにより複数の共有maildirが追加可能です。
--delオプションで共有maildirへの "接続を切る" ことが可能です。
通常 -add コマンドでの共有指定は各ユーザで実行する必要があります。 一方、 /etc/courier/maildirshared ファイルを作成して標準の共有maildirを指定することができます。 各行は次のフォーマットです。
nick は共有maildirのフォルダ名、<tab> は1つのタブ文字、path は共有可能maildirへのパスです。
共有フォルダには読み取り権あるいは書き込み権が設定されています。 もしあなたに書き込み権があれば、 あなたはメッセージを共有フォルダに書き込めます。 あなたが書き込んだメッセージを削除することもできます。
誰でも共有可能なmaildirを設置することができます。つまり、 もしその共有maildirがあなたの作成したものであったなら、 あなたの作成したメッセージだけでなく、すべてのメッセージを削除可能です。
この文の残りの部分ではmaildirの実装に関する技術的なことについて説明します。 maildirの最初の定義と実装はDan Bernsteinによる Qmailメールサーバで行われました。それは単一の、平面構造のメールリポジトリです。 Courier メールサーバではフォルダや、自発的クォータなどです。 この文では拡張maildir形式について、 オリジナルのmaildir形式に対するどういう拡張かは気にせずに説明することにします。 オリジナルのmaildir形式については http://www.qmail.org/man/man5/maildir.htmlを参照してください。
maildir形式はオリジナルのmailbox形式に対していくつかの利点があります。 mailboxファイルと異なり、 新たなメールの配送やメールの読み取りのためにはロックは不要です。 複数のメール配送エージェントが同時に新たなメールをmaildirに配送できますし、 メールを読み取ることができます。 ロック機構はネットワークのファイル共有システムでしばしば問題を引き起こします。 maildir形式ではロックは不要であり、 たいていのファイル共有システム上で実装できます。
maildirはグループおよび他者アクセス権が除かれた単なるサブディレクトリです。 maildirは3つのサブディレクトリを持ちます: tmp、new、 curです。 フォルダは名前がピリオドではじまるサブディレクトリで、例えば.Drafts とか .Sent です。 それぞれのフォルダはその中にまた3つのサブディレクトリ tmp、new、curを持ち、それ自身はmaildir形式であるかのように扱われますが、 前記したようにそれ自身はさらにサブディレクトリとして フォルダを含むことはできません。
フォルダのためのサブディレクトリには長さ0のmaildirfolderというファイルを持ちます。これはメール配送エージェントが そのディレクトリがフォルダであることを識別し、 また必要なら親ディレクトリにアクセスして適切に動作するためにあります。 また、maildir形式を扱うプログラムによってはtmp、new、curのほかに、 maildirやそのフォルダディレクトリに追加のファイルを作成する場合があります。
メールのメッセージは後に示すように、 1つのメッセージが1つのファイルに個別に格納されます。 tmpサブディレクトリはこのmaildirへ配送中のメッセージが一時的に格納されます。 また、tmpディレクトリへの新規ファイルの名付け方法を同じにしているなら、tmpディレクトリにはその他の一時ファイルが格納されます。 newサブディレクトリにはこのmaildirに配送された新規メッセージのうち、 まだ他のアプリケーションで既読になっていないメッセージが格納されます。 cur サブディレクトリにはアプリケーションで読まれて 既読になったメッセージが格納されます。
maildirへの新規メールの配送は次の手順で行われます:
固有(ユニーク)なファイル名が新たに作成されます。これは "time.pid.host"、あるいは "time.pid_unique.host"のどちらかの形式になります。 "time" は現在のシステム時間を秒で表したものです。 "pid" はこのメッセージをmaildirへ配送しようとしているプロセスの プロセス番号です。"host" はメールを配送しようとしているマシンのホスト名です。 もし1つのプロセスが複数のメッセージを同時に配送しようとする場合は、 プロセス番号の後ろにアンダースコアを続けて連続する数値を生成します。 この規則は同じmaildirか違うmaildirかを問わず、 メールファイルを新規作成しようとするプロセスすべてにあてはまります。 この規則により複数のプロセスが同一ネットワーク上の複数のマシンで 同時に新たなメッセージを作成しようとするときに、 互いをぐちゃぐちゃにしないですみます。
上記のように作成されたファイル名はtmpサブディレクトリ中でstat(2)システムコールにより同じファイル名がないか確認されます。 もしstat(2)がシステムエラーENOENT以外のものを返したら、プロセスは2秒間スリープして、 新規ファイル名を再作成して再実行します。この確認により 確かに新規ファイル名が完全に固有のものであることを保証します。
tmpサブディレクトリを一時ファイルの置き場として利用するプログラムはすべて これと同様の手順を踏まなければなりません。 (なお、tmp中の古いファイルは突然削除されることがあります。 詳しくは下記の「maildirからのメールの読み取り」を参照してください。)
stat(2) システムコールがENOENTエラーを返したら、tmp サブディレクトリ中に新規ファイルを作成し、メールメッセージを保存します。 保存するメッセ—ジには昔ながらmailbox形式にあった、 メッセージ1つ1つを分離するための "From_" 行は不要です。 またmailbox形式の、 本文に"From_"を含む場合に行頭に付けられていた">"文字も不要です。
メッセージの保存とは、ファイルに正しく書き込まれたことを意味します。 write(2)システムコールの戻り値をチェックして、 メッセージ全部の書き込みが成功したかどうか確認してください。
メッセージが保存されたら、ファイルをクローズして、直ちにnew サブディレクトリへ移動 (リネーム)します。 ファイル名は tmpサブディレクトリのものと同じにします。
maildirに新規メッセージを作成するアプリケーションは、 new サブディレクトリへ移動する時にファイル名の後ろに ",S=nnn"形式で そのサイズをバイト数で追加することを強く推奨します。 これはmaildirの自発的クォータの動作を軽くします。 maildir中のそれぞれのメッセージに対してstat(2)システムコールを発行することなく、 maildir中のメッセージの総容量を計算できるからです。 (ある種のネットワーク上のファイルシステムにおいて 劇的なパフォーマンスの向上になります。)
maildirからメールを読み取るアプリケーションは次の手順を踏む必要があります:
maildirかそのフォルダを読み取るプログラムは、tmp サブディレクトリ中で36時間を経過したものをまず削除しなければなりません。
newサブディレクトリ中で新しいメッセージを見つけます。 見つかったメッセージそれぞれに対して、 new/filename ファイルを cur/filename:2,info ファイルにリネームします。 ここで info はメッセージの状態を示し、以下の文字の0ないしいくつかの組み合わせです: D - ドラフトメッセージ、 R - 返信済み、 S - 既読、 T - 削除マーク付きだけどまだ未削除 (maildirでのメッセージの削除は単にそのファイルを削除します)、 F - ユーザによるマーク付き。 これらのフラグはアルファベット順に並んでいる必要があります。 :2, のように何も付けられていない新規メッセージは、 返信でも既読でも削除マーク付きでもユーザマーク付きでもないことを示します。
maildirには最大サイズのクォータ制限を持たせることができますが、 これは完全に自発的な制限です。 強制的な制限が必要な場合は、maildirが格納されるファイルシステムにて 提供されるクォータ機構を用いてください。 maildirで提供されるquotaはなんらかの事情でファイルシステム提供のクォータが 使用できない場合に用いるように設計されています。 クォータの実装にはロック機構は用いていません。 そのため、ある瞬間に計算されたクォータ値は不正確であり、 特別な状況ではmaildirのクォータ制限値を上回ってしまう場合もあります。 そんな状況としては、アプリケーションがクォータ値の推測値を更新せずに 新規メッセージを作成した場合があります。 最終的にはちゃんと計算されますが、 その間にクォータ手順に則って新たなメッセージが作成されてしまうかもしれません。
自発的クォータには上記の手順のほか、 maildirやそのフォルダ内のメッセージの作成と削除に関して いくつかの追加手順が必要です。deliverquota(8)コマンドは自発的クォータ手順により単一メッセージをmaildirに配送する 小さなアプリケーションで、 最終手段として用いることができます。 あるいはlibmaildir.aライブラリを利用して、これらの細かな手順を実行できます。 自発的クォータ手順について詳しくはmaildirquota(7)を参照してください。