My/Ham/Log

『Cの福音』なんて本があるのね。C言語を学べば福のある音を出せるぜぃ って本かと思ったら違った。 楡周平 さんが書かれて、宝島社から出てるっつう事で、察してあげてください。

その本を読み進めると、Cってのは、コカインの頭文字Cって事が段々分かってくる。ハードボイルな 小説だ。この題はシリーズになっていて、面白かったので別の本も読んでみた。

『クラッシュ』と言うのがそれだ。600ページもある大著だけど、面白かったので一気に読んじゃったよ。 あらすじは、ハイテク旅客機 A-500の制御プログラムを開発してるベンチャー企業の社長とやり手な 女性プログラマの痴話のもつれから、話は始まる。社長とそのプログラマは創業当時からの仲間でほぼ夫婦。 しかし、社長と秘書の浮気がばれて、女性プログラマは復讐を決意する。

A-500(A-300じゃなくて良かったね)のプログラムを摩り替えて機能不全に落としいれ、それを解除する ためのクイズがWebに公開される。運悪く、全日航の運用する便が発症して制御不能になちゃうんだけど、 その便に世界のOSの80パーセント(スペース2000とか言う名前だったよ)を占めている開発社の社長が乗り合わせていた。びびった、眼鏡の君は 正解を出した人には多額の賞金を出すと宣言しちゃった。

そんなこんなで、Webのページは5000万PVと言うアクセスが有ったそうな。所が、そのページには、邪悪な ウィルス(エボラ)が仕込まれていた。発症すると、OSもろとも消してしまうという恐ろしいやつ。 そしてそのウィルスが猛威を奮い始める。

あんまり書くとネタバレになるので、これぐらいしとくけど、突っ込み所満載で二重に楽しめたよ。お試しの Webページにウィルスを植えつけたんだけど、そんなWebシステムが、世界中からアクセスされても、落ちなかった って、どんだけ素晴らしいシステムなんだろうね。

ウィルスはネットワークに強い言語で書かれていたとなってて、Webのページをすらすら見てウィルスの 出来栄えに感嘆したというくだりがあるけど、何語で書かれてるの? ひょっとしたら、こういうの

それにしても、世界のOSの80%も押さえるOSってどうよ。多様性が無いから、ウィルスに感染しちゃったら 一気に壊滅状態になっちゃうぞ。サイバー・テロへの警告の書でもあるんだな。怖いこっちゃ。

logger

先週は、タイム・トラベルに出て40年前に戻ってみたけど、連休も終わったのでまた現代に戻ってきた。 そんでもって積読を消化してる。何せ早くしないとCQ誌の次号が出ちゃうからな。

アパマン・ハム特集か。40年前は、公団住宅へ立てるアンテナの基準をJARLが制定なんて事やってたから、 今も昔も借家住まいの人は虐げられているのね。で、りっぱな持ち家に住めない人はせめて車に凝るって 聞いたけど、りっぱなアンテナを上げられない人は、モービルとか移動に走るのね。 小さいアンテナって事で、ラドとかが出てくるかと思ったら、今号には無し。特集号まで取っておこうと いう算段ですかね。

つらつらと特集を見て行くと、loggerの事を書いている人が居た。その人WindowsはおろかM$環境で動く ソフトを忌み嫌うため、loggerにちと苦労したそうな。おいらもWindowsは大嫌い。世の中がみんなWindows だと、Windows用ウィルスが出てきたら一貫の終わりじゃないですか。OSも多様性がなくっちゃ!

その人は、MAC用のSkookumLoggerと言うのを 使っているとか。emacsのキーバインドで使えるのが嬉しいとか。そう、Macはunixの流れを汲んでいますからね。でも、考えてみるに、OSと言う土台に 縛られるアプリなんて、時代遅れと思いませんか?

まあ、ウィルス作者じゃないけど、一番流行っているOSに寄生するものを作っておけば、拡散も一番効率 よく早く行われるってのは肯けます。でも、宿主を限定しない方がもっと、拡散しますぜ。

loggerもWindows限定とかMac限定とかが無い方が良いのではなかろうか。そう考えると、ここは一つ そういうものを作ってみたくなるね。

Webって今や、どんなOSでも動いちゃうな。そこにブラウザが有れば。。。

でも、サーバーはどうする? ソフトウェアデザイン誌のまねをしてみたら、 社長さんが営業してるページに 行き当たったよ。だけど、たかがアマチュア無線のためのログ用システムとして、サーバーを借りる なんて、とっても大げさ過ぎるな。

ロガーについて考える

だったら、WindowsだろうとMACだろうとUnixだろうと、それらが動くプラットフォーム上でサーバーを 立ててしまえばいいじゃん。どうせ、個人でしか使わんのだから。

普通に考えるとLAMPだな。Linux上でapacheのWebサーバーを動かして、バックエンドはMySQL。フロントは PerlとかPythonとかRubyで動かすと言うやつだ。でもまだ大げさだな。LLだけで出来ないか? ああ、LLの代わりにJavaでもいいけど。Javaを裸で使うのはアホみたいなんで、clojureの皮をかぶせてって 手があるな。ちょいと面倒くさそうだけど。

今更Perlも無いでしょう。そうするとRubyか。Rubyならwebrickと言うサーバーがあるな。Railsでレールに 乗るか。MySQLの代わりに今はsqlite3ぐらいが付いてくるのかな? でも、私はRails脱落組なので、 きっぱりとこの路線は諦めます。

そうすると、残るはPythonかなあ? ああ、Gaucheって手もあるな。でも、世界制覇を望むなら、括弧だらけ は括弧いいけど、脱落かな? そうすると、残るはPythonか。これなら、天下のぐぐる様も使ってるから、いいかも。

PythonでWebサーバーとかあるんか? Zopeとか色々あるけど、余計な物無しで行きたいね。 調べてみたら、実験用のCGIが動くサーバーが有るみたい。それに、Python2.5からは、標準でsqlite3の モジュールが付いてるみたい。これなら、loggerを動かすには、Python2.5以上を入れておいて下さいって 事で、済んじゃうぞ。余計な物を入れると言う面倒が無いのが嬉しい。

参考資料

とまあ、いろいろと検討した結果、Pythonに戻ってきちまったよ。ここらでPythonの参考資料を調べて おくかな。資料と言えば、まずは書籍だろう。 関連図書 をまとめてくれている2ch人が居た。みんパイ本は持ってたんだけど、引越しの時に処分しちゃったからなあ。 今読むならDive Into Python 3 日本語版がいいかな。本を 一冊公開しちゃうって、太っ腹度は RHGの青木さんみたいだなあ。後、日本語の扱いで悩まないためには、 こちらが、為になるな。

周平さんが『クラッシュ』を書いた頃は、JavaScriptも使いづらい代物で危ないものだったろうけど、 最近はぐぐる様あたりもばりばり使ってますなあ。 jQueryなんて皮を被せて。いずれ使うようになるかも知れないので Web制作の現場で使えるjQuery UIデザイン入門メモして おきます。

JavaScriptを最初からやろうとすると、JS用のREPLが必要になる。もじら組からそんなのが出てたような。 でも、JDKが入っているなら

C:\homes>jrunscript
js> 1 + 2
3.0
js> ^Z
C:\homes>

こんな具合に、Sunの遺産が使えます。JavaScriptはブラウザー用言語だと思ったら間違いっぽいので JavaScriptでわかる!組込みプログラミングの神髄 こんな風に勉強にも役立ちますだ。そんじゃ、寄り道はこれぐらいにして。 全体的にJavaScriptを見るなら こことか そこ が、便利です。そうそう、JavaScript用の debuggerも、有ったほうがいいな。

でも、今更JavaScriptって気がしないでもないな。そんなあなたには、 CoffeeScriptの方がお似合いかも。きっと、これらに 対抗して、抹茶スクリプトとか、ハーブスクリプトを誰方が作っているに違いない。

Python製のWebサーバー

取りあえず、FreeBSD上のPythonでサーバーを動かしてみる。ぐぐる先生に動かし方を聞いたら

[sakae@cdr ~]$  python -m CGIHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

モジュールを動かすだけの超簡単操作だけだった。けど、0.0.0.0 ってのがちと気になるな。それに、みんなが 8000番ってのも好かん!

[sakae@cdr ~]$ netstat -a -f inet
Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address       (state)
tcp4       0      0 *.8000                 *.*                    LISTEN

ああ、やっぱりね。NICならどれでもいいよって心の広い設定になってる。これ、せめてlocalhost限定 ぐらいにしておきたいね。さて、どうやるんだ? その前に、サーバーを止めないとな。ええい、強制終了のCtrl+C だい。

^CTraceback (most recent call last):
  File "/usr/local/lib/python2.6/runpy.py", line 122, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/local/lib/python2.6/runpy.py", line 34, in _run_code
    exec code in run_globals
  File "/usr/local/lib/python2.6/CGIHTTPServer.py", line 368, in <module>
    test()
  File "/usr/local/lib/python2.6/CGIHTTPServer.py", line 364, in test
    SimpleHTTPServer.test(HandlerClass, ServerClass)
  File "/usr/local/lib/python2.6/SimpleHTTPServer.py", line 214, in test
    BaseHTTPServer.test(HandlerClass, ServerClass)
  File "/usr/local/lib/python2.6/BaseHTTPServer.py", line 588, in test
    httpd.serve_forever()
  File "/usr/local/lib/python2.6/SocketServer.py", line 224, in serve_forever
    r, w, e = select.select([self], [], [], poll_interval)

ふむふむ。モジュールを起動すると、内部では、runpy.pyが動くんだな。そやつの管理下で、お目当ての CGIHTTPServerが動き、そやつがSimpleHTTPServerを呼び出し、その中でBaseHTTPServerが呼ばれ、最後は SocketServerが縁の下の力持ちってなってんのね。

そんじゃ、CGIHTTPServer.test()あたりから辿っていけば、IPとかportを指定してる部分が分かるかな? そんな要領に見て行って、必要な部分をパクッって(もとえ、専門用語ではオーバーライドって言うのかな? ) 書いたのが、以下のやつ(server.py)。

#!/usr/local/bin/python

import BaseHTTPServer
import CGIHTTPServer

CGIHTTPServer.CGIHTTPRequestHandler.cgi_directories = ['/ham']
CGIHTTPServer.is_python = lambda self,path:  True

def test():
    HandlerClass = CGIHTTPServer.CGIHTTPRequestHandler
    ServerClass =  BaseHTTPServer.HTTPServer

    server_address = ('localhost', 54321)

    HandlerClass.protocol_version = "HTTP/1.0"
    httpd = ServerClass(server_address, HandlerClass)

    sa = httpd.socket.getsockname()
    print "Serving HTTP on", sa[0], "port", sa[1], "..."
    httpd.serve_forever()

test()

こやつを走らせて、目的通りになったか確認してみると

[sakae@cdr ~]$ netstat -a -p tcp
Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address       (state)
tcp4       0      0 localhost.54321        *.*                    LISTEN

どうやら、localhost限定でしか接続を受け付けないサーバーが出来上がりました。ああ、それから cgi_directoriesの初期値は、

    cgi_directories = ['/cgi-bin', '/htbin']

上記のように定義されてますが、ちょいと気分が悪いので変更してあります。従って、パクッて書いた スクリプトを置いてあるdirの直下にhamと言うdirを作り、その中に、cgiへの応答スクリプトを 置いておけば、OKです。

また、標準では、cgiスクリプト名を下記によりチェックし、.pyか.pyw以外はエラーにしてます。。

    def is_python(self, path):
        """Test whether argument path is a Python script."""
        head, tail = os.path.splitext(path)
        return tail.lower() in (".py", ".pyw")

これじゃ、URLを入力した時ちょいとかっこ悪いので、このコードを潰しておきました。但し、Windowsでは、もう少し別な 場所にもパッチを当てないと動かないみたいです。

WindowsはDOSの時代から面々と引き継がれてきた、 ファイル名のサフィックスによる縛りが有るからなあ。サフィックスを誤魔化して、ウィルスである事を 隠すという古典的な手法が今でも通用するし。もうこういうDNAは退化して欲しいぞ。

[sakae@cdr ~]$ bin/tree.rb my
|-+ my
  |-- JA8IOC.db
  |-+ ham
  | |-- conf.py
  | |-- log
  |-- readme.txt
  |-- server.py

そして、ブラウザー上からは

 http://localhost:54321/ham/log

のように、呼び出します。なお、cgiスクリプトであるlogと、その設定ファイルconf.pyは後で説明します。

python上のsqlite3

その前にデータベースが動くか確認。

[sakae@cdr ~]$ ipython
Python 2.6.6 (r266:84292, Apr 14 2011, 08:05:27)
Type "copyright", "credits" or "license" for more information.

IPython 0.10.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object'. ?object also works, ?? prints more.

In [1]: import sqlite3
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)

/usr/home/sakae/<ipython console> in <module>()

/usr/local/lib/python2.6/sqlite3/__init__.py in <module>()
     20 # 2. Altered source versions must be plainly marked as such, and must not be

     21 #    misrepresented as being the original software.

     22 # 3. This notice may not be removed or altered from any source distribution.

     23
---> 24 from dbapi2 import *

/usr/local/lib/python2.6/sqlite3/dbapi2.py in <module>()
     25 import time
     26
---> 27 from _sqlite3 import *
     28
     29 paramstyle = "qmark"

ImportError: No module named _sqlite3

ははは、見事にsqlite3のモジュールが入っていなかった。FreeBSDのpythonシステムでは、別パッケージに なってるのね。database/py-sqlite3 から、入れましたよ。勿論、WindowsとかLinuxは、最初から入って ましたけどね。

調子に乗って、古いFreeBSDにもpy-sqlite3を突っ込んでみたら、今度は違うエラーが出てきた。 Load_extentionが見つからんですって。これは、sqlite3のバージョンが古くて、拡張機能がサポートされて いない為でした。いろいろな環境でやってみると、勉強になるなあ。

ちょいと疲れてしまったので、続くにしときます。