Wikifs
Plan9ではWikiもファイルサーバとして実装されている.これがwikifs.設定の仕方はInformal Wiki Setupやman wikifs(4)が参考になる.このページの通りに設定したら,Linux側からhttp://172.20.0.2/wiki/sample/plan_9_wiki/にアクセスすればよい.
wikifsは指定されたWikiデータに対するファイルシステムインタフェースを提供する.通常は,httpd経由でHTMLを出力するが,acmeをWikiエディタとして利用するためにプレーンテキストを出力するインタフェース*1も持つ.今回は前者にしぼって話をする.
まず,wikifsを実行する.以下の説明では,ディレクトリ/sys/lib/wiki.sampleにWikiデータがあると仮定して話を進める.-sオプションはサービス名で,-pオプションはパーミッションの指定.この例では,/srv/wiki.sampleをパーミッション0666でオープンして,(httpdと通信するための)ファイルディスクリプタをポストする.-aオプションはacmeと通信するために9Pコネクションを使うためのオプションなので,Webページとして使うだけなら省略してもよい.
wikifs -p 666 -s wiki.sample -a tcp!*!wiki /sys/lib/wiki.sample
続いて,httpdを起動する.httpdは起動時に/lib/namespace.httpdの定義にしたがって名前空間をセットアップする.Plan9の名前空間はプロセスごとに独立なので,httpdの名前空間を動作に必要な部分だけに絞りこむことができる.Wikiに関する記述は次のmountで,/usr/web/wiki/sampleに*2,さきほどwikifsが作った#s/wiki.sampleをユニオンマウントしている.
mount -b #s/wiki.sample /usr/web/wiki/sample
例えば,http://172.20.0.2/wiki/sample/plan_9_wiki/というURLにアクセスした場合*3,httpdは#s/wiki.sample/plan_9_wiki/にアクセスすることになる.そして,httpがこのファイルをopen,readすると,wikifsの処理が始まる.wikifsは/sys/lib/wiki.sample/d/mapファイルを参照し,plan_9_wikiがd/1にマップされているので,d/1をパーズして,HTML表現に変換し,writeする.その出力をhttpdがreadし,ネットワークに出力する.
/sys/lib/wiki/sample/d/map: 0 wiki syntax 1 plan 9 wiki 2 sandbox 3 supported pc hardware
plan_9_wikiに対する編集はplan_9_wiki/edit.html,差分はplan_9_wiki/diff.htmlなどになる.このようにURL的には1 wikiページはディレクトリとして見えるが,実装は1 ファイルとなる.Wikifsの役割は,このようなリソースに対するマッピングの変換だと言える.なお,/usr/web/wiki/sampleにはcreate.htmlしかファイルがなく,edit.htmlなど他のHTMLファイルは/sys/lib/wiki.sampleディレクトリにある.edit.htmlなどは一種のテンプレートファイルで,PAGEと書かれている部分は,plan_9_wiki/edit.htmlの場合であれば,plan_9_wikiの内容に展開される.
/sys/lib/wiki.sample/edit.html: <html> <head> <title>TITLE (Editing DATE version)</title> <META http-equiv="Content-Type" content="text/html; charset=utf-8"> </head> <!-- FFFFE9 is acme yellow; FFFFD0 is as close as you can get to it before charon decides to use grey instead of map entry 254 --> <body bgcolor="#FFFFD0" link="#0000AA" alink="#0000AA" vlink="#0000AA"> <center> <font size=+2><b>TITLE</b></font> (Editing DATE version) </center> <p> For information on editing, see the description of <a href="../0">Plan 9 wiki syntax</a>. <p> <form action="/magic/wikipost" method="post"> <table><tr><td valign=top> <input type="submit" name="x" value="Put"></td><td> <table> <tr><td align=right>(optional) Comment:</td><td><input type="text" name="comment" value="" cols=40></td></tr> <tr><td align=right>(optional) Email:</td><td><input type="text" name="author" value="" cols=40></td></tr> </table> <input type="hidden" name="title" value="TITLE"> <input type="hidden" name="version" value="VERSION"> <input type="hidden" name="service" value="sample"> <input type="hidden" name="base" value="/wiki/sample"> <p> <textarea name="text" wrap="virtual" cols="80" rows="25"> PAGE </textarea><p> </td> </table> </form> <hr> <table width=100%><tr> <td valign=center align=left> </td><td valign=center align=right> <a href="../about.html">About the server</a> | <a href="http://plan9.bell-labs.com/plan9" ><img src="http://plan9.bell-labs.com/plan9/img/power36.gif" alt="Powered by Plan 9"></a> </td> </tr></table> </html> </body>
edit.htmlで気になるのは,次のPOSTメソッドの部分だろう.
<form action="/magic/wikipost" method="post">
httpdはPOSTメソッドを処理するために,wikipostというヘルパープログラムを使う.URLが"/magic/"で始まる場合は,それに続くプログラムをexeclして処理する(rforkはしないので,execlに失敗しない限り,httpdに処理が戻ってくることはない).Plan9には動的ロードがないので,プラグイン的な仕掛けを作るためにこのようにしているのだろう.