2003.08.11(初版),2003.10.22(バグ修正)
OpenBlockS266は,ぷらっとホームが開発・販売している小型コンピュータのことで,サーバ分野をターゲットしています.値段も安く(39,800円,本当はもっと安くしてくれと言いたいが,従来製品より安いのが確かなので...),CFカードやHDDがそのまま入るのも大変魅力的,さらにおなじみ(?)のLinuxが入っていることも嬉しい.しかし当然ながら,くせというか特徴というか,簡単に使えない仕様もあるので,ここでぼくの付き合い記録を書いてみます.
ぼくのプロジェクトは,インターネットからリモートで対象PCを起動・動かす・終了という内容です.OpenBlockS266(以下OBSと略す)は,インターネットと対象PC(複数)の間に置かれ,ゲートウェイの役割を果たします.恐らくこれは,二つのイーサネットインタフェースを持つOBSの狙いところでもあるでしょう.
まず,PCを起動させること.これはWOL(Wake On LAN)という技術を使えばよい,と言うのは簡単ですが,実際になかなかの手間が取られました.最初の問題は対応PCのことです.今どのLANカードもマザーボードもWOL対応を謳っていますが,いろいろ自分で調べて,確実に起動してくれたのはIntelのLANカードだけでした.なんでやろう.
次にOBSからWOLパケットを送信するプログラム.これも既存のソフトがあります.ぼくが使ったのは""ether-wake.c: v1.06 1/28/2002 Donald Becker, http://www.scyld.com/"です(感謝,Beckerさん).Perlスクリプトもありましたが,OBSには64KBの保存領域しかなくて,Perlを利用するには別途CFカードかHDDを追加する必要があります.さすがに大袈裟ではないかと思います.因に上記のether-wake.cをコンパイル(gcc,stripped)したら9KB弱のバイナリーとなります.
ether-wakeの確認ができたら,今度はウェブインタフェースを作ります.
OBSに入っているWWWサーバ thttpd は,どうやらHTMLファイルをContent-type: text/plainとして送信しているようで,ブラウザーはそれに従ってテキストとしてタグまでまるごと表示してしまいます.設定ファイルを調べてみたのですが,それを設定するオプションが見つかりません.ネットで検索したら,あるページで最新版を落としてコンパイルすれば直るという結果がありました.しかし,OBSに入っているバイナリーに比べずいぶんサイズが大きい(140KB対70KB?)ので,OBSに入っているやつは(PlatHomeによって)独自に改造されただろうということらしい.サイズの問題でこの方法はよくないとぼくが判断しました.というか,解決方法がありましたから.
ぼくの考えた方法は,CGIでHTMLファイルを見せることです.ヒントは,実はOBSに添附された設定CGIが正しく動くことから得られました.つまり,CGIでContent-typeをtext/htmlを出せばよいわけですから,ホームにはindex.htmlを作らないで,main.htmlを作って,index.cgiを以下のようにすればよい.アクセスは http://hostname/ となり,直接 http://hostname/index.html でアクセスできないけど,自分のニーズには問題ない(笑)のでOK.ここまで([もcatもROMに入っている!)shellスクリプトが書けるのはOBSの素晴らしいところではないかと思います.感心感心.
#!/bin/sh
# index.cgi: The openblocks266-ver thttpd only outputs text/plain text,
# so we have to write a cgi program to cat html files.
# Version: 0.1 (2003/08/08), zhao
echo "Content-type: text/html"
echo
FILE="main.html"
if [ -r $FILE ]; then
cat $FILE
fi
これでHTMLを見せることができ,後はether-wake(rootでsetuidが必要ですが,問題ないでしょう)を呼び出すCGIプログラムを書けばよい.ぼくの書いたサンプルを載せておきます.
#!/bin/sh
# wakeup.cgi: wake up the specified PC.
# Usage: http://hostname/wakeup.cgi?pcname
# Version: 0.1 (2003/08/08), zhao
# First, we define the MAC addresse for each target PC.
# Since we don't have much PCs, it will be fine.
# If you have a lot of PCs, a database may be more efficient.
MAC_PC1="00:11:22:33:44:55"
MAC_PC2="11:22:33:44:55:66"
echo "Content-type: text/html"
echo
echo "<html>"
echo "<head><title>PC wakeup program</title></head>"
echo "<body>"
echo "<h1>PC wakeup program</h1>"
if [ x$QUERY_STRING = x ]; then
echo "<p>Aha, you forgot to tell me which PC to wake up.</p>"
else
case $QUERY_STRING in
pc1)
MAC_TARGET=$MAC_PC1;;
pc2)
MAC_TARGET=$MAC_PC2;;
*)
MAC_TARGET="";;
esac
if [ x$MAC_TARGET = x ]; then
echo "<p>Bad target! Are you kidding me?</p>"
else
echo "<p>OK, I will wake up $QUERY_STRING for you. Please wait for a few minutes.</p>"
./ether-wake -i eth1 $MAC_TARGET
if [ $? -eq 0 ]; then
echo "<p>Status: wake-up packet sent OK.</p>"
else
echo "<p>Status: error in sending wake-up packet! This is unusual, please report it to the administrator.</p>"
fi
fi
fi
echo "</body>"
echo "</html>"
一つだけ注意事項があります.ターゲットPCがどのインタフェースに接続しているのを ether-wake に教える必要があります.デフォルトは eth0.