![]() |
![]() |
2007/10/29
"Everything is a file" は Plan 9 のコンセプトの一つである。システムコールを増やさずに、OS にとっての必要な情報をファイルインターフェースでプログラマに提供するやりかたは本当に良いと思う。
以下に紹介するのは Python で書いた dnsquery 関数である。UNIX であれば DNS の呼び出しに独立した大きなモジュールが必要となるだろう[1]。
Plan 9 では次の(コメントを除けば) 8 行程度の関数で十分である。
def dnsquery(name,s):
"""
usage:
print dnsquery("/net/dns","ar.aichi-u.ac.jp ip")
print dnsquery("/net/dns","202.250.160.40 ptr")
"""
f = open(name,"w+")
f.seek(0)
t = split(s)
if t[1] == "ptr":
u = split(t[0],".")
s = join((u[3],u[2],u[1],u[0]),".")+".in-addr.arpa ptr"
f.write(s)
f.seek(0)
return f.readline() # "" if not answered
このコードの半分は IP から FQDN を求める場合に費やされている。
Plan 9 のコマンド
ndb/dnsquery
において、IP から FQDN を求めたい場合には(例えば)
202.250.160.40 ptr
とする。Python の関数 dnsquery() でもこの形式を保ちたいと考えるのは当然である。
しかし。この要求は /net/dns に対しては何故か
40.160.250.202.in-addr.arpa ptr
として渡さなくてはならないのだ。(ちょっと不便だね...)
このような事になっていなければ、たったの 4 行で済んだのに!
ところで Python は利口だね。どうやら f.close() が自動実行されるらしい。"/net/dns" はオプションにした方が良かったかな...
2007/10/31
先に紹介した dnsquery() はバグがある事に気付いた。1つの IP に複数の FQDN がある場合に対応していないのだ。その解決のために、f.readline() を f.readlines() に置き換えれば良いように思われるかも知れないが、そうするとレコードの区切りが明示的に与えられない。問題の解決には Plan 9 の read() を使う必要がある。
ついでに "/net/ndb" をオプションにし、さらに戻り値を簡潔にした。読み取りのバッファサイズは 256 にして置いたが、これで十分かどうかは知らない注1。
#!/bin/env python
import sys,os
import re
from string import *
def dnsquery(q,name="/net/dns"):
"""
usage:
print dnsquery("ar.aichi-u.ac.jp ip")
print dnsquery("ar.aichi-u.ac.jp ip","/net/dns")
print dnsquery("202.250.160.40 ptr")
"""
f = os.open(name,os.ORDWR)
os.seek(f,0,0)
t = split(q)
if t[1] == "ptr":
u = split(t[0],".")
q = join((u[3],u[2],u[1],u[0]),".")+".in-addr.arpa ptr"
r = []
try:
os.write(f,q)
os.seek(f,0,0)
v = os.read(f,256) # "" if not answered
while v:
r = r + [v.split()[2]]
v = os.read(f,256)
except:
pass
os.close(f)
return r
print dnsquery("202.250.160.40 ptr")
print dnsquery("ar.aichi-u.ac.jp ip","/net/dns")
print dnsquery("129.79.115.30 ptr","/net/dns")
print dnsquery("207.210.94.66 ptr")
print dnsquery("67.122.237.50 ptr")
print dnsquery("63.236.211.155 ptr")
print dnsquery("130.203.4.6 ptr")
print dnsquery("13.203.4.6 ptr")
sys.exit()
"""-------------------------------------------
term% query.py
['ar.aichi-u.ac.jp']
['202.250.160.40']
['129-79-115-30.dhcp-bl.indiana.edu']
['cpanel100.atl.wiresix.com', 'vparent100.atl.wiresix.com']
['adsl-67-122-237-50.dsl.scrm01.pacbell.net', 'adsl-67-122-237-50.dsl.pltn13.pacbell.net']
['serv155.datamatrox.com', '63-236-211-155.dia.static.qwest.net']
['psuvax1.cse.psu.edu']
[]
-------------------------------------------"""
[1] Python DNS Library
http://sourceforge.net/projects/pydns/
[2] Fully qualified domain name
http://en.wikipedia.org/wiki/FQDN