proftpdは比較的軽量で、スタンドアローンでも(x)inetd配下でも動くftpdである。しかも、apache httpdに似たモジュールによる機能追加をサポートしており、コンフィグレーションファイルの書き方も似ている。ftpについて理解していてApache httpdの管理経験があれば、特にドキュメントを読まなくても一通りのことはできる。もちろんmod_tlsでSSLには対応済み。ただし、Explicit のみ。
ApacheのようなDSOに対応していないのが弱点で、つまりモジュールを足すには再コンパイルするしか無かった。でも、なんか1.3.0を見るとmod_dsoというモジュールが追加になっているので解消された模様。
というわけで、そんなproftpdのモジュールを開発してみようと思う。本稿はその開発メモである。
staticモジュール
とりあえず、staticモジュールを作るのを目標としよう。
Make段階でmodules/glue.shというスクリプトが走って、これがmodules/mod_*.cから、モジュール定義構造体(typedef module_struc module)へのポインタを抜き出す。だから、staticリンクされるモジュールでは、 modules/mod_モジュール名.c というファイルに module型のグローバル変数 "モジュール名_module"を定義すればよい。そうすれば勝手に、staticロードモジュールリストにリストアップされる。
in mod_example.c
#include "conf.h"
module example_module = {
/* module構造体の双方向リンクリストのためのポインタ。実行時に使われるのか? */
/* .next = */ NULL, /* .prev = */ NULL,
/* 準拠しているProftpd Module APIのバージョン。モジュール自体のバージョンではない */
/* .api_version = */ 0x20,
/* モジュール名 */
/* .name = */ "example",
/* このモジュールが提供するディレクティブの定義テーブルへのポインタ */
/* .conftable = */ NULL,
/* このモジュールが提供するコマンドハンドラの定義テーブルへのポインタ */
/* FTPコマンドの実行に割り込むにはこれを使うってことか。 */
/* .cmdtable = */ NULL,
/* おなじく、認証処理への割り込みのためのハンドラ定義テーブル */
/* .authtable = */ NULL,
/* モジュール初期化関数へのポインタ */
/* .init = */ example_init,
/* FTPセッション初期化関数へのポインタ */
/* .sess_init = */ example_sess_init,
/* モジュールのバージョン文字列 */
/* .module_version = */"mod_example/example",
/* よく分からない。NULLで良いっぽい */
/* .handle = */ NULL,
/*" Internal Use"と書いてある。実行時の優先順位か? */
/* .priority = */ 0
};
提供しない部分はNULLで良いらしい。example_module変数は定義テーブルって言う性質上constにしたいような気もするけれど、あからさまに実行時にリンクリスト作るぞーって感じだからそれは無理だろう。constにしたらアーキテクチャにもよるけど、たぶんSEGVる。
- aprとおなじようなネスト可能なpoolオブジェクトによるメモリー管理が提供されている
- loggingも独自のAPIがある。
- APIやコールバックは成功時にTRUE, 失敗時にFALSEを返すのが基本らしい。
- TRUE, FALSEはproftpd.hで独自に定義してある。
コメント