だから準備中なんだってば…、書くペース遅いし、無計画に書いてるから支離滅裂だし
ソースはこれ
http://www.fenix.ne.jp/cgi-bin/cvsweb.cgi
FENIX BBS System (a.k.a HIME)
■はじめに
その昔、今みたいにインターネットが普及していなかったころ、パソコン通信とよばれる電話回線を使用して、テキストやデータをやりとりする文化がありました。
パソコン通信の世界では、パソコンで用意するソフトウェアは、基本的には、ターミナルソフトだけです。
パソコン通信で使用するターミナルソフトは、TCP/IPのような複雑なプロトコルは使用せず、入力された文字をただ送信、受信した文字をただ表示するだけなので、貧弱なハードウェアでも十分快適に動作します。
さて、時代はインターネットです。
インターネットの特徴として、ひとたびプロバイダにつなげば、世界中どこでもアクセスすることができる、ということがあります。
また、複数のサーバに同時に接続することもできます。
ところが、パソコン通信では、BBSのホストに直接電話回線を接続して通信するため、別のホストにアクセスするためには、一度切断して接続しなおさなくてはなりません。
また、電話回線をインターネットプロバイダへの接続に使用している場合には、パソコン通信を同時に利用することができません。
これでは不便です。
ならば、BBSホスト自体をインターネットから利用できるようにしてしまえばいいのではないか、と考えるのは当然の流れです。
というわけで、インターネットでアクセスできるテキストベースのBBSプログラムを探したのですが、あまり無いんですよ。
世の中BBSというと、Webベースのものを指すようです。
インターネット経由でアクセスできるからといって、WWWベース専用のものにしてしまったのではおもしろくありません。
それに、それは当時、私を含めたFENIXのユーザに多かった、インターネット接続環境をもたないユーザを見捨てることになります。
また、WWW自体がそうであるようにWebベースのBBSは匿名性が高いのに対し、パソコン通信のBBSでは、CUG(Closed User Group)などのように、ユーザ権限を細かく管理し、メッセージの読み書きを制限する特徴があります。
これらパソコン通信のBBSのもっていたアクセス環境や機能を継承しつつ、インターネット経由で利用できるBBSシステムを新規に開発することになりました。
もちろん、せっかく新規に開発するのだから、いままでに無かった、独自の概念を持たせています。
ところで、パソコン通信のようなテキストターミナル用のBBSのことをなんと呼べばいいのでしょう。いまさらですが、以下ではttyベースのBBSということにします。
■FENIX BBS Systemの特徴
- 軽快なCUIで、特殊な接続ソフトウェアを必要とせず、テキストターミナルがあれば使用できること。PC-8801だってOK
- インターネットでは嫌われるけど、パソコン通信ではあたりまえだった半角カナが使用可能
- EUC/Shift-JIS/JISを使用可能。
- sshやtelnetをインターネット経由で利用した場合と、modem経由で利用した場合とで同じインターフェース、サービスを提供する
- パソコン通信的なmailのインターフェースそのままで、インターネットメールを扱える
- チャット
- 電報
- メッセージは番号0のメッセージをルートメッセージとした、1本の木の構造になっている。後述の読み書き制限で、この木構造が重要な意味をもち、制限が加えられたメッセージの下に所属するメッセージはすべて同一の制限が与えられる。
- ユーザレベルの概念があり、ユーザレベルの高低で読み書きを制限できる。
- CUG(Closed User Group)を作成でき、同一グループに所属しないユーザからの読み書きを制限することができる
- システムにインストールされているSHELLを含む外部アプリケーションも利用できること。ただし、ユーザ/グループにより制限を加える。
■実装概要
FENIX BBS Systemは、ユーザインターフェースはCUIであり、専用shell - fensh - 上でコマンドを入力することによって操作します。
ほとんどのコマンドは、独立したプログラムとして存在し、fenshから実行(fork + execされます。
ユーザが接続、ログイン、コマンド実行までを行なったときのプロセスの流れは以下のようになります。
なぜプログラムが独立しているのか
FENIX BBS Systemでは、各コマンドが独立したプログラムとなっています。
これは見ようによってはリソースの無駄使いのように見え、また、ダサい
構造であることは否めません。しかし、この実装方法には多大なメリットがあり、
また、これ以外の実装方法は困難で面倒です。
プログラムが分かれていることのメリットは、「デバッグが容易」であること、
これに尽きます。
プログラムがわかれていれば、各機能ごとにテストを行うことができます。
そのため、ある機能に関してデバッグをするとき、複数の機能を一つの
プログラムにまとめて実装した場合と比べて、遥かに高負荷なテストを行うことが
でき、早期にバグを尽きとめられます。
また、運用中に徐々に改良を加えていくことも可能です。実際FENIXでは、
BBSプログラムの改良のためにシステムの停止したことはたぶんありません。
通常運用中にどんどんプログラム入れ替えています。
BBSのデータにアクセスするプログラムは、ルート権限で動かなければなりません。
FENIX BBS Systemでは課金対象ユーザはOSの一般ユーザ権限で実行できる
任意のプログラムを使用することができます。したがってBBSのデータに対し
ユーザがBBSプログラム以外を使用して、直接読み書きをすることを回避する
必要があるのです。
そのため、BBSのデータはルート権限のみでアクセス可能とし、一般ユーザが
システムのデータにアクセスするとき、つまりメッセージを読み書きするとき
には、suidビットの立ったプログラム通してアクセスすることにしました。
むやみにルート権限で動作するプログラムが実行されるのは望ましくありません。
その点でも、各機能ごとにプログラムを分離し、必要のあるコマンドだけが
ルート権限で動作することは妥当です。
クライアントサーバ化することはできなかったのか?と思われるかも
しれませんが、それは困難なわりにメリットがないと考えました。
単純にソケットを使用してメッセージをやり取りしたのでは、ユーザ権限を
正確にコントロールすることはできません。
なぜならば、サーバプログラムからは、接続してきたクライアントのユーザ名を
正確に知ることができないからです。リクエストを出しているユーザを知るために
そのソケットにユーザ名を流したのではは意味がありません。
FENIXでは一般ユーザが自由にプログラムを書くこともできるため、
嘘のユーザ名でリクエストを出すことができてしまうからです。
ここでユーザ名に加えてパスワードも流し、認証処理を行うことで、ユーザを
決定することも可能ですが、それではユーザにもう一度パスワードの入力を
要求することとなりスマートではありません。
■基本概念
ユーザIDとハンドル
FENIX BBS systemでは、ユーザの識別名として、user ID, handle名、alias の3種類を使用できます。
ほぼすべてのコマンドで、これらのどの識別名を使用した場合にも同様の結果が得られますが、一部に例外があります。
- User ID
- ユーザ登録するときに割り当てられる名前で、ユーザが変更することはできません。
- 主にlogin時に使用します。逆に、login時に使用できる識別名はUser IDのみです。
- システムの内部的には、unixのlogin名そのものです。
- handle名
- FENIX BBS system内部のみで有効なニックネームで、日本語も使用可能です。
- ユーザによる変更が可能です。
- alias
- 主にインターネットメールに使用するニックネームで、ユーザが自由に変更できます。
- インターネットネームで使用することを考慮して、半角英数と記号のみが使用可能です。
ユーザ権限
各ユーザには、1-9までのユーザレベルと、所属グループが与えられ、それにより
ユーザの実行可能なコマンド、読み書きできるメッセージなどが制限されます。
コマンドの実行制限はシェル(fensh)が、メッセージに対するアクセス制限は、
BBS部(HIME)のライブラリが行います。
■BBS部(HIME)
FENIX BBS systemのBBS部は、HIME - HIerachal MEssage system とよばれ、
その名の通り、メッセージが階層化されて格納されます。
この階層化構造こそが、HIMEのもっとも特徴的な部分です。
- すべてのメッセージが、root メッセージから始まる木構造の枝や葉となっている。
いわゆる、階層化ファイル化システムに似ているが、ディレクトリエントリに相当する部分も、メッセージを持つ点がことなる。
- すべてのメッセージが、一意な番号を割り付けられていて、この番号を使用してメッセージを指定できる。メッセージへのパスをいちいち指定する必要はない。
- メッセージの読み書きはread/write levelと、groupの2種類の制限が加えられ、これらを組み合わせることで柔軟なアクセス制限ができる。
レベルによるメッセージのアクセス制限
FENIX BBS Systemでは、ユーザは1-9までのレベルを持ちます。
ユーザは メッセージを書きこむとき、そのユーザのレベルまでの任意の
読み出し・書きこみレベルを書きこむメッセージに与えることができます。
メッセージのレベルは、そのメッセージへのユーザの読み書きを制限します。
- read level
- メッセージのレベル <= ユーザレベル のとき、そのメッセージを読むことができます。
- メッセージのレベル > ユーザレベル のとき、そのメッセージを読むことはできません。
- write level
- メッセージのレベル <= ユーザレベルのとき、そのメッセージへレスを書きこむことができます。
- メッセージのレベル > ユーザレベル のとき、そのメッセージにレスを書きこむことはできません。
groupによるアクセス制限とCUG(Closed User Group)
FENIX BBS Systemのユーザは一つ以上のgroupに属します。
この、groupはUNIXのgroupと同一のものです。
ユーザは、メッセージを書きこむときに、そのユーザの所属しているグループのうちの一つを、そのメッセージのグループとして指定することができます。
また、そのとき、属性として、openまたはclosedを指定することができます。
メッセージのグループは書きこみを制限し、その属性は読み出しを制限します。
- メッセージのグループが、自分の所属しているgroupのとき、
そのメッセージにレスを書きこむことができる。そのgroupに所属していない場合は書きこむことはできない。
- メッセージのgroupの属性がOpenの場合、そのgroupに所属していなくても読むことはできる。groupの属性がclosedの場合、そのgroupに所属していない限りそのメッセージを読むことはできない。
これらの性質を使用し、特定のメッセージ以下のツリーを、CUG(Closed User Group)とすることができます。
CUGとしたい先頭のメッセージに、closed属性を与えるだけで、そのメッセージのグループと同じgroupに所属しているメンバーからしか読み書きできないCUGとなります。
(注:CUGというのは、パソコン通信のBBSにあった、特定のグループにしか読み書きできないボードのことです)
アクセス制限の継承
階層化構造に従い、メッセージのアクセス制限は継承されます。
ユーザがあるメッセージのread level, groupによってアクセスが禁止された場合、そのメッセージの下にあるメッセージアクセスすることはできません。
また、読み出しを制限されているメッセージに書きこむことはできません。
これらの性質を利用することにより、特定のメッセージスレッド全体のアクセス制限を変更したいときに、先頭のメッセージの属性を変更するだけで済むことになります。
ボード
BBSシステムは一般に、大まかな話題毎にボードという単位で分類してメッセージを
格納します。HIMEにもボードと呼ばれる概念は存在しますが、他のシステムとは
若干扱いが異なります。
HIMEの場合、すべてのメッセージがルートメッセージから始まる木の枝として
格納されていくという特徴を持つため、ボードとメッセージの関係は既存のBBSとは
異なります。
HIMEでは、ボード名はそのボードの先頭メッセージのエイリアス名に
過ぎません。したがって、全てのメッセージがボードになりえます。
ある特定のメッセージにボード名をつけたとき、そのメッセージから始まる
メッセージツリーがボードとなり、階層化構造にしたがって、
そのメッセージの下に続くメッセージの集合がそのボードに書きこまれた
メッセージになります。
既存のBBSと同じ捕らえ方をすると、HIMEでは、ボードはルートメッセージから始まる
ツリー1つだけということになってしまいますが、実際にはボードの下にさらに
ボードが存在する構造である点に注意してください。message
#55,
#57
■プログラムセット
FENIX program set
ファイル名 | FENSH上の名前 | 機能
|
2ndlogin | なし | 自前のutmpへlogin/logout情報を書き込む
|
fenlogin | なし | ユーザ認証処理
|
fenchat | chat | チャット
|
fenedit | edit | テキストファイルエディタ
|
fenid | id | ユーザ情報編集
|
fenlast | last | login記録表示
|
fenmail | mail | mailインターフェース
|
fenprof | prof | profile 表示/編集
|
fentel | telegram | 電報
|
fenwho | who | ログイン状況表示
|
goodbye | goodbye | 遺言メッセージ処理
|
hime | read,news,tree,list,search
| BBS関連ユーザインターフェース
|
fensh | ( ) | 専用shell
|
fenixuserconfig
| なし | ユーザ情報テーブルを
元にOSの設定ファイルを更新
|
members | なし | cgi用ユーザリスト表示
|
pppstart | なし | 動的にIPアドレスを割り当てるpppd wrapper
|
2ndlogin
ユーザのログインシェルとして起動され、forkしてfenshを起動し、
ログイン中は常駐しつづけます。
起動時と終了時に、自前の接続記録ファイル(fenutmp)へ login/logout情報を
書き込みます。また、このとき、名前の逆引きも行います。
2ndloginが行っている処理は、本来、gettyやtelned, sshdが行うべき処理です。
やっていることはlogin/logoutを記録しているだけなので、普通はOSのutmpファイルに保存されているもので間に合うはずです。
2ndloginが必要となった背景は2つあります。
- OSに用意されているutmpの接続元ホスト情報フィールドは文字数が少なすぎる
- pseudo-ttyを利用した日本語仮想コンソールのインターフェース
実は今となってはこれら2つの要求では2ndloginの必要性を説明できません。
utmpのホスト名フィールドは256バイトに拡張されたし、日本語変換はライブラリで
行うようになったからです。
しかし、いまのところ2ndloginは残していくつもりです。
いまでも、以下の利点があるからです。
- osと独立したログイン記録は osを入れ替えたとしても残せる
- 逆引きしてホスト名を記録する
- 将来搭載されるであろうターミナル以外のログイン方式の
インターフェースとなる可能性がある
fenlogin
OSの/bin/login同等のユーザ認証処理を行います。
ただし、telnetのように盗聴されるおそれのあるプロトコルで接続してきた場合、
plain passwordを受け付けず、s/keyのチャレンジ/レスポンスを要求します。
また緊急用に、2ndloginではなく、tcshを直接起動する裏口を用意してあります。
fenchat
パソコン通信的なBBSでは必須とも言えるチャット機能です。
IRCクライアントとして実装されています。
動作のためにはIRCサーバをホストで動かす必要があります。
fenedit
テキストファイルエディタです。
行入力志向で、いわゆるスクリーンエディットはできません。
fenid
fenlast
login記録表示
fenmail
インターネットメールにも対応した、mailインターフェースです。
日本語を正しく扱えます。
MIME multipartには受信のみ対応しています。
fenprof
profile 表示/編集
fentel
電報
fenwho
ログイン状況表示
goodbye
ログアウト時に表示される1行のメッセージの表示と編集を行います。
hime -- read,news,tree,list,search
BBS関連ユーザインターフェース
fensh
専用shell
fenixuserconfig
ユーザ情報テーブルを元にOSの設定ファイルを更新
members
cgi用ユーザリスト表示
pppstart
限られたグローバルIPアドレスを有効に利用するため、PPPに割り当てる
アドレスを動的に決定します。グローバルIPの数が電話回線の数より少ない
場合に有効です。
将来への布石のつもりで実装しましたが、同時に張られるPPPのセッション数が
多くないので、あまり活躍していません。
■日本語入出力
FENIX BBS Systemではユーザのターミナルで使用する文字コードとして、
sjis,euc,jisのどれでも使用可能です。
内部処理で使用するコードはeucで統一してあり、ターミナルの文字コードとは
分離しています。そのため、入出力のときに文字コードを変換することになります。
現在の実装では、日本語コード変換はライブラリで行っています。
また、ライブラリ内の行入力関数は日本語に対応した行編集機能を持っています。
以前は、OpenBSDのttyドライバを日本語対応化改造したり、
pseudo terminalを使用して日本語変換機能付仮想ターミナルを
作ったこともありましたが、どれも今一つよい結果が得られませんでした。
いろいろな日本語コードで行編集が安定してでき、かつ、一括アップロードで
大量の文字列を流してもおかしくならないようにすることがどうしても
うまくできなかったのです。
ライブラリとして実装したことにより、FENIX BBS Systemは安定した日本語コード
変換付入出力ができるようになりました。
また、将来この機能を独立したライブラリとしてexportできる可能性を
得たことになります。
(ほら、パソ通的なBBSって近い将来絶対消えるでしょ。それでもさ...)
■ライブラリ
各コマンドで頻繁に使用する機能をライブラリとしてまとめています。
大まかに以下に分類されます。
- ユーザ情報管理
- ログイン、ログアウト管理
- ユーザID、エイリアス名、ハンドル名の関連付け
- 端末入出力
- 漢字コード変換付入出力
- 日本語対応行編集入力
- その他
- 電報
- プロセス名変更
- high level BBSアクセス
- 読み書き
- メッセージ検索
- low level BBSアクセス
- メッセージ間、親子検索
- アクセス権チェック
■歴史
- 1998/3/27 FENIX仕様決定
- FEZ,thomasが徹夜で飲みながら仕様を決定
- 1998/3/28
- 開発開始
- 1998/4/*
- 某工研内に設置したmanamiでプロトタイプ起動開始
- 1998/6/*
- OCN開通に伴い、テスト運用開始
- 1998/6/*
- ソース管理にCVS導入
- 1998/10/1
- CVSリポジトリ再構築
- 1998/10/16
- WEB対応。但し読み出しのみ
- 1998/10/25
- リアルタイム電報機能。たとえ外部コマンドを実行中でも電報が受信可能
- 1998/10/29
- guestログ記録
- 1998/11/10
- 自分のユーザレベルを得る関数の高速化。というよりバグで本来の速度がでていなかった。
- 1998/11/27
- goodbyeに編集機能を追加
- 1998/12/02
- PPPのアドレスを動的にマッピングするラッパプログラムを追加
- 1999/01/19
- pseudo-ttyを使用した漢字コード変換機能付ユーザレベル端末ドライバを実装
- 1999/03/08
- CVSリポジトリをkanaに移動
- 1999/03/08
- GNU readlineライブラリに独自の半角かな対応化パッチを当てて利用開始
- 1999/03/15
- fenmailをPOP経由でなく直接スプールにアクセスするようにした
- 1999/03/15
- fenshから任意の外部コマンドを直接実行可能にした。一般的なSHELLにより近く。
- 1999/05/12
- 独自の日本語対応入出力ライブラリを開発(jgetline, jfprintf)。
FENIX/
MEMBERS/
thomas's HOME/
MEMO/
fenix
佐藤益弘 thomas@fenix.ne.jp