関連の事件では、EFFと First Amendment Projectは、カリフォルニア最高裁にDeCSSソースコードの公開を許す下級審の判決を支持するよう要求した have asked 。DVD CCA(複写管理協会)は、裁判所にその判決を覆えさせて、コードの公開を阻もうとしている。
EFFは、関連事件に関する大量の情報 amount of information を持っている。
面白いことに、NewsForgeが、Reuters, Yahoo.com, CNN.com及び数多の公開者がDMCA違反で有罪であるとの話storyを 報じていることだ。これらに共通しているのは、ソニーのCD用保護コードがマジックインキで消す手順processを記事にしていることだ。裁判が始まるのを待っている訳ではないが、これはこの法律の欠陥を分かり易く示している。
●Coxの講話
DMCAなどの米国法律を厳しく批判しているAlan Coxが、DMCAよりもっと厳しいEuropean Union Copyright Directiveに対しヨーロッパ人の注意を向けようとしている。Coxは、オンラインで聴けるavailable online EUCDの講義で話している。Alanの見解は、法律とLinuxを話題にした最近のインタビューSlashdot interviewでも説明している。
別のAlex Cox 、 Slashdot isの報告 report では、Alex Cox ( Repo Man と Sid And Nancyの作者/監督)は、ガーディアンに、映画産業の本当の海賊は、独立の振りをするハリウッド撮影所とMPAAだと書いた has written。
●ペルー向けのオープンソース
Edgar David Villanueva Nunez博士は、無料ソフトウエアだけを使うようペルー政府を制限すべきだとの提言proposalsに関するマイクロソフトからの入力input he received from Microsoft に対し慎重で理性的なcareful and rational回答を書いた。この提言の背景は費用ではなく、市民による公共情報への自由なアクセス、公共データの性能、及び国家と国民の安全であると言う。最後のものについては「外部から制御することが出来たり、望まない第三者に情報を漏らしたりする要素のないシステムに頼るのは絶対に必要なことだ」と言う。国家と独立専門家が、これに当てはまるかを検証することが出来るのは、オープンソース・ソフトウエアだけである。
この話に関するリンクは(元のスペイン語版を含め)pimientolinux.com/peru2ms/で入手することが出来る。Villanueva博士とのインタービューby Linux Todayも含む。
●「アナログホール」の穴埋め
EFF は、コンテント保護の話題に関しMPAAからの雑音を解析した advisoryを発行した。MPAAは、技術に関するルールブックを全面的に改定する計画であると思われる。報告書は、広範な科学、医学及び娯楽考案品に見出される途方もなく一般的でありふれた電子部品であるアナログ−デジタルコンバータ(ADC)にも同様の規制を呼びかけている。MPAAは、著作権対象の転換を要求されたとき装置を止める"cop-chip"を用いて、すべてのADCを制御することを提案する。この問題に関するEFF報告書 report on this subject に詳しいことが載っている。
開発者のURL:Linuxのロシア語ディストリビューション、ALT Linuxは、ALT Linux Master 2.0のリリースを発表した。リリースはCD6枚に及び広範なアプリケーションを含む。マニュアルには、インストレーション、システム管理、一般用法及びOpenOfficeが含まれる。価格は1300.00rub(約40ドル)
Hewlett-Packard は、そのBlade Servers のオプションとしてpre-installed Debian を提供する。Blade は、単一コンピュータケース内で、他のBladeと共存することが出来るカード・コンピュータである。出荷に際して、一つのBladeのDebianがインストールされている。他のbladeにはOSがないが、HPのSystemImagerソフトウエアを使ってbladeにDebianイメージをコピイすることが出来る。
Linux Magazineに、このディストリビューションの輪郭を示したThe Importance of Being Debian の記事がある。
Registerは、デスクトップLinuxを持つ as has DesktopLinux SuSE 8.0を概観した reviewed。意見は様々である。
SuSE Linux, は、64ビットIBM eサーバー用SuSE Linuxエンタープライズサーバー7の出荷を発表した announced the shipment of the SuSE Linux Enterprise Server 7 for 64-bit IBM eServer zSeries。この新64ビット環境を使う最初のアプリケーションの一つは、IBM eサーバー zシリーズ用 mySAP.com e-ビジネス プラットホームで、2002年5月末にはzシリーズ用SuSE Linux エンタープライスサーバーに利用することが出来るようになる。
Registerは、Mandrake 8.2を眺めた taken a look at Mandrake 8.2。余りよくない。
IBM はまた、Linux用新大量管理技術の立ち上げを発表した。SourceForgeを故郷とする Enterprise Volume Management Systemは、記憶管理能力の合理化と強化のため設計されている。新技術は、Linuxオープン社会と IBM Linux Technology Centre.の開発者の間の広範な協力の成果である。
はじめに
Dillo は、新しい有望なオープンソース・ウエブブラウザである。他のソフトウエアとは異なっていて殆ど比較も出来ない。数年前に発見して、それが成長し使える状態になるのを見守って来た。未だアルファソフトウエアだが、私見では今の状態で十分使うことが出来ると考える。
小型で速い点が古いChimeraブラウザに似ている。他のグラフィックブラウザのように見栄が良くはないが、長所を持っている。
Dilloの特徴
Dilloは現在、下記をサポートする:
これは他のブラウザを同様に使用することが出来る。リンクをクリックして起動する。中央ボタンで新ウインドウにリンクを呼び出す。ペイジをセーブしたりリンクをダウンロードするには、右ボタンで、ペイジソースを見ることが出来る簡単なメニューが与えられる。
Dilloの長所
Dilloは、
mailto: URLs.のサポートがない
Javascript、Java 又はFlashが本当に必要なら、Dilloは不適だ。勿論、Dilloを使って普通にサーフし、Javascript、Java 又はFlash を見る必要があるときは別のブラウザを開くことが出来る。
インストレーション
先ず Dillo homepage に行って、現行バージョンのtarballを取り込む。
次いで、以下のステップを入力する。入力はシェルプロンプトからおこなう。
・tar xvzf dilloarchive.tar.gz
・cd dillodir
・./configure --enable-cookies
./configure とタイプする
・make
su -c "make install" をおこなう。
スタートさせるには dillo とタイプする。Dilloを一緒に来る文書を必ず読むこと。
Dillo をコンパイルするには、X development, libpng 及びGTKをはじめ幾つかのライブラリをインストールしていなければならない。
Dillo はDebianその他のディストリビューションにある。
まとめ
dilloは素晴らしい。一度見てみるべきだ。Dilloは、特にローカル文書のブラウズの適している。だが現行バージョンでウェブに入るのは難しい。
Dilloは小型迅速なので、w3mを陳腐化する。速度が理由でw3mを使っている人はDilloに乗り換えるべきだ。Dilloは高速でグラフィックを表現する。画像ロードをオフにして、画像のALTだけを得ることも出来る。
Dilloは私の選んだブラウザだ。Javascript 又はFlashが必要なときだけMozilla互換ブラウザをスタートする。最も憂鬱なのは、CSSサポートがないことで、Dillo表示領域からカット&ペーストが出来ないことだ。
誰も使用を強制しないから、一寸覗いてみると良い。何が出来るか分かるし、オープンソース・ソフトウエアの良い例だ。
詳細は、Dillo ホームペイジで。
リンク
e-メールアドレスを持つ人は、各種フォーマットの添付ファイルを受けることがある。残念ながら、無料ソフトウエアでは読めないフォーマットがある。これは特にe-メール仲間がe-メールリーダーとの関連で著作権プログラムを使うとの、危ないと定評のある手順に未だしたがっている場合に当てはまる。
多くの無料ソフトウエアは、クローズドソース・ソフトウエアに依存する添付ファイルの付いたe-メールすべてを無視し、送り主にオープン標準の重要性を説く方針を取ることを推奨している。仲間が送る添付ファイルを見る楽しみをなくしたくないこともある。そんな状況になったとき、この記事で概説した技術が役立つであろう。
添付ファイルの内容全部が、油断なく護られた秘密アルゴリズムを使って暗号化されていると、Linuxユーザーに出来ることは少ない。しかし極めて多くの場合に、疑わしいファイルは、単に薄い著作権封筒に、衆知の暗号化標準を用いるデータオブジェクトの杜撰な集積を入れているに過ぎない。例えば、ネットを駈けめぐるMSワード文書は、ファイルに内蔵されたJPG及びPNG画像を含む。封筒を取り除く方法が見付かれば、これらファイルを読むのは簡単なことだ。以下の各節では、小さいPython スクリプトを、殆どのLinuxディストリビューションで入手出来る画像表現取扱いツールと一緒に使って、これをおこなう方法を説明する。
テキストの抽出
内蔵画像の問題に立ち向かう前に、 strings をユティリティを使って容易にテキストを読むことが出来る:
strings proprietary.file | less
strings proprietary.file | grep JFIF strings -n 3 proprietary.file | grep PNG strings proprietary.file | grep GIF8
from string import find
#著作権データを読み取る
fh = open( "proprietary.file" )
dat = fh.read()
fh.close()
# JFIFをサーチ
x = -1
while 1:
x = find(dat,"JFIF",x+1)
if x<0: break
# ファイルを6バイト速くスタートさせる
print x - 6
#!/usr/bin/python
from string import find
from sys import argv
headers = [("GIF8",0), ("PNG",1), ("JFIF",6)]
filepath = "proprietary.file"
if len(argv)>1: filepath = argv[1]
fh = open(filepath )
dat = fh.read()
fh.close()
for kw,off in headers:
x = 0
while 1:
x = find(dat,kw,x+1)
if x<0: break
print kw,"file begins at byte",x - off
tail -c +1001 proprietary.file | display -
#!/usr/bin/python
from string import find
from sys import argv
from os import system
headers = [("GIF8",0), ("PNG",1), ("JFIF",6)]
filepath = "proprietary.file"
if len(argv)>1: filepath = argv[1]
fh = open(filepath )
dat = fh.read()
fh.close()
for kw,off in headers:
x = 0
while 1:
x = find(dat,kw,x+1)
if x<0: break
system("tail -c +%d %s | display -" % (x - off + 1, filepath))
各画像ファイルの抽出
ImageMagick は、画像セグメントの終わりまで読み取った後に送られた余分のデータはすべて廃棄する。個別ファイルとして記憶のため画像データを完全に分離したいときもまた、各画像の終わりを見出す必要がある。このための一方法は、修正バイナリチョップアルゴリズムを使うことだ。 Listing 3(リスト3)
#!/usr/bin/python
from string import find
from sys import argv
from commands import getstatusoutput
headers = [("GIF8",0,"giftopnm","gif"), ("PNG",1,"pngtopnm","png"),
("JFIF",6,"djpeg","jpg")]
filepath = "proprietary.file"
if len(argv)>1: filepath = argv[1]
fh = open(filepath )
dat = fh.read()
fh.close()
inum = 0
for kw,off,conv,ext in headers:
x = -1
while 1:
x = find(dat,kw,x+1)
if x<0: break
beg = x - off
#画像らしいものが見付かった -- バイナリチョップにより終わりを見出す
s1 = len(dat) - x
s0 = 1
sz = s1
while s0<s1:
(stat,output) = getstatusoutput("tail -c +%d %s | head -c %d | %s >/dev/null" % (beg + 1, filepath, sz, conv))
if stat:
#失敗 -- 多分小さ過ぎる
if sz == s1:
#失敗 -- 多分無効データ
print "failed... no image here"
break
elif sz == s0:
#長さを見出した-- 画像を描き出す
imgname = "image%03d.%s" % (inum, ext)
print "writing",imgname
fh = open( imgname, "w")
fh.write(dat[beg :beg+s1])
fh.close()
inum = inum + 1
break
s0 = sz
else:
#多分大き過ぎる-- 小さいものを試す
s1 = sz
sz = int((s0+s1)/2)
画像デコードユティリティ giftopnm、djpeg、及び pngtopnm を使ってファイルの終わりを探すことが出来る。displayと同様これらのツールは、画像ファイル終わりでエラー無しで終結した後の余剰入力データを廃棄する。しかし、不完全画像データであるときは、エラーを報告して不成功のまま終了する。Pythonスクリプト長さの変動する画像データをデコードツールに送って、その完了状態を、必要ファイルの正しい長さに戻すのに用いる。
まとめ
この記事では、プラットホーム無関係オープン標準を用いてコード化されたデータオブジェクトを、著作権ファイルの中から抽出するスクリプトの書き方を示した。これらのスクリプトを他の画像ファイルや音響、音楽ファイルなどのため拡張するのは簡単な課題の筈だ。単純な暗号化の層や錯乱を通じて説明した技術の裏を掻く沢山のファイルフォーマットがあることに注意されたい。
特定のe-メール添付ファイル読取のため、適当な著作権アプリケーションにアクセスしたときであっても、上に概説したスクリプトは、あるかも知れないマクロウイルスや、そのアプリケーション専門のセキュリティを避けるため有用である。
最後に、警告の言葉。國によっては立法府が曖昧な言い回しの法律を持っており、これらのスクリプトを著作権侵犯の非合法考案品であると見なす方法で介入して来る恐れがある。これは、居住国により、該当することもしないこともある。オープンソーしとクローズドソースのシステムを混合する場合の常として、利用度は異なる。
if_statement : IF LPAREN statement RPAREN multiple-statements ELSE
multiple-statements ENDIF
ここで、(1) IF、LPAREN、RPAREN、ELSE 及びENDIF は、if , ( , ) , else 及び endifそれぞれを認識するためのトークンである。(2) 'statement' と 'multiple-statements' もまたそのための規則が書かれる別の構造である。
2.3 構文解析
簡単に言うと、構文解析は、入力プログラムが構文解析ツール(パーサー)の与える規則に一致するか否かを検証する方法である。各種の構文解析方法がある。しかし、その詳細に入る必要はない。(上の例のような)ルールの組を与えられると、パーサーは入力が定められたルールに対応構成されているかを見る、ことを知るだけで十分である。
3. 実行
コンパイラ実行の用意が出来た。トークン認識、構文解析、セマンチック・アクションを取ること、中間コード作成、その最適化、及び最終的な必要アセンブリコードの作成など各種の段階がある。これから取るステップも同様である。
3.1 言語の定義
前に言ったように、最初のステップはコンパイラが受け入れる言語を規定することである。どんな構造物とオペレータを作成したいかを明確にしなければならない。'while', 'if', 'assignment statements' などの構造物は共通である。+, -, *, / などのオペランドも同様である。言語用の規則を書き下ろさなければならない。一つの言語が受け入れる割り当てステートメントに関する規則の組を下に示す。
assign_statement : VAR EQUALS statement
statement : statement ADDOP term
| statement SUBOP term
| term
term : term MULOP factor
| term DIVOP factor
| factor
factor : VAR
| NUM
| LPAREN statement RPAREN
この論文を通じて、大文字の単語(NUM, VAR, EQUALS, ADDOP, SUBOP, MULOP, DIVOP, LPAREN, RPAREN)はトークンで、小文字の単語(assign_statement, statement, term, factor)は規則であるとの慣例を採用する。
3.2 トークンの定義と認識
次に、使用するトークンを定義する。今回の例では、九個のトークン−NUM, VAR, EQUALS, ADDOP, SUBOP, MULOP, DIVOP, LPAREN, RPARENを用いる。以下の風呂グラムが言語をトークン化するための簡単なプログラムを実行する[text version]
import lex
# トークン名のリスト、これは義務的である
tokens = (
'NUM',
'VAR',
'EQUALS',
'ADDOP',
'SUBOP'
'MULOP',
'DIVOP',
'LPAREN',
'RPAREN'
)
# トークンに関する正規のステートメント規則
t_VAR = r'[a-zA-Z_][\w_]*'
t_EQUALS = r'='
t_ADDOP = r'\+'
t_SUBOP = r'-'
t_MULOP = r'\*'
t_DIVOP = r'/'
t_LPAREN = r'\('
t_RPAREN = r'\)'
# アクションコードの付いた正規のステートメント規則
def t_NUM(t) :
r'\d+'
try:
t.value = int(t.value)
except ValueError:
print "Line %d: Number %s is too large!" % (t.lineno, t.value)
t.value = 0
return t
# 行番号を追跡ことが出来るように規則を定める
def t_newline(t):
r'\n+'
t.lineno += len(t.value)
# 無視された文字(空白とタブ)を含む文字列
t_ignore = ' \t'
# エラー取扱い規則
def t_error(t):
print "Illegal character '%s'" % t.value[0]
t.skip(1)
# lexerを構築
lex.lex()
# 入力の取得
data = raw_input()
lex.input(data)
# トークン化
while 1 :
tok = lex.token()
if not tok :
break
print tok
予約語を含めたいときは、次のような
ファンクションの中で変数名(識別子)を整合させ特殊な
名称ルックアップをおこなうのが容易である:
reserved = {
'if' : 'IF',
'then' : 'THEN',
'else' : 'ELSE',
'while' : 'WHILE',
...
}
def t_VAR(t):
r'[a-zA-Z_][\w_]*'
t.type = reserved.get(t.value,'ID') # Check for reserved words
return t
3.3 構文解析
構文解析は、yacc.pyを使うと容易である。パーサーはトークンを得るためlexerを呼び出す。そこで、前に書いたlexモジュールを入力しなければならない。そこで、各規則に対応して、ファンクションを定義し、規則自体をドキュメントとして書く。構文解析は下に示すようにおこなうことが出来る。[text version]
# Yacc 例
import yacc
# 前に定義したlesxerからトークンマップを得る
# これは必要だ
from ourexlex import tokens
__var_names = {}
def p_assign_statement(t) :
'assign_statement : VAR EQUALS statement'
__var_names[t[1]] = t[3]
def p_statement_plus(t) :
'statement : statement ADDOP term'
t[0] = t[1] + t[3]
def p_statement_minus(t) :
'statement : statement SUBOP term'
t[0] = t[1] - t[3]
def p_statement_term(t) :
'statement : term'
t[0] = t[1]
def p_term_times(t) :
'term : term MULOP factor'
t[0] = t[1] * t[3]
def p_term_div(t) :
'term : term DIVOP factor'
t[0] = t[1] / t[3]
def p_term_factor(t) :
'term : factor'
t[0] = t[1]
def p_factor_num(t) :
'factor : NUM'
t[0] = t[1]
def p_factor_var(t) :
'factor : VAR'
if __var_names.has_key(t[1]) :
t[0] = __var_names[t[1]]
else :
print "Undefined Variable", t[1], "in line no.", t.lineno(1)
def p_factor_expr(t):
'factor : LPAREN statement RPAREN'
t[0] = t[2]
# シンタクス・エラーに関するエラー規則
def p_error(t):
print "Syntax error in input!"
# パーサーの構築
yacc.yacc()
while 1:
try:
s = raw_input('enter > ')
except EOFError:
break
if not s: continue
yacc.parse(s)
ここで、各ファンクションは単一の引数tを受け取る。これはタプルである。t[i]の値がここに示すように、文法シンボルにマップされる:
def p_statement_plus(t):
'statement : statement ADDOP term'
# ^ ^ ^ ^
# t[0] t[1] t[2] t[3]
t[0] = t[1] + t[3]
3.4 セマンチック・アクション
セマンチック・アクションは、パーサーが入力を特定のルールに限定したとき取るステップである。上記の例では、このアクションはインタプリータのアクションに相当する。簡単なコンパイラに関しては、セマンチック・アクションは、規則に対応してアセンブリコードを作成ことである。
出力として8086アセンブリ命令を作るとする。ここで、オベランドを見るときはいつでも、アキュムレータの内容を一時レジスタに記憶し、オペランド自体をアキュムレータに記憶する。こうして最後に見たオペランド(又は計算の最終結果)が常にアキュムレータの中にある。
def p_factor_num(t) :
'factor : NUM'
__output_fp.write("\tmov bx,ax\n"%f) # bx <-- [ax]
__output_fp.write("\tmov ax,0x%x\n"%t[1]) # ax <-- t[1]
where, '__output_fp' is a file pointer to an output file
演算のオペランド(バイナリでも単項式でも)がここで利用出来るので、加算のためのセマンチック・アクションを次のように書く:
def p_statement_plus(t) :
'statement : statement ADDOP term'
__output_fp.write("\tadd ax,bx\n")
# ax <-- [ax] + [bx]
同様に、新しい変数に出会ったときはいつでも、その変数のためレジスタを割り当てることが出来る(ローカル変数を記憶するにはスタック位置を選択するのが良い)ので、ディクショナリを用いて割り当てたレジスタを記憶する。変数名がキイでレジスタ名が値である。変数名を参照する毎に、変数名をキイとして用いてディクショナリをサーチし、対応するレジスタ名を得る。
3.5 最適化
Cコンパイラに関しては、ここで書いたように早くはアセンブリ命令が作られない。実際に作られるのは中間コードである。次いで中間コードを最適化して、最後にアセンブリコードを作成する。
最適化自体が曖昧な話題なので、簡単な最適化技術、つまりピーホール(覗き孔)最適化、を述べるだけにする。ピーホール最適化をおこなう最も容易な方法は、特定のアセンブリプログラムを人手でコードしてコンパイラが作ったコードと比較することである。
例えば、アセンブリ命令セットに乗算用の命令がないときは、繰り返し加算で乗算のコードを作ることが出来る。ここでおこなうことの出来る単純最適化は次のとおりである。一つの演算数が1とすると、明らかにループになる繰り返し加算の代わりに、別のオペランドを結果として記憶することが出来る。乗数がループ計数を決めるので、二つの演算数のうち小さい方を乗数として選ぶことが出来る。
ピーホール最適化の別の例は、jumpの利用である。次の例を見られたい:
jmp .L1
.
.
.
.
.
.L1 jmp .L2
.
.
.
.
.
.L2 add ax,bx
ここで、最初のjump ステートメントは、以下に示すように、jumpの数を減らすのに使うことが出来る
jmp .L2
.
.
.
.
.
.L1 jmp .L2
.
.
.
.
.
.L2 add ax,bx
最適化コードを作るには各種のアルゴリズムがある。上述の方法は、複雑な時間・スペース最適化技術の、ほんの入口である。
4. 次ぎになすべきこと
これまで説明したのは成育したコンパイラではない。これを完成するには、もっと沢山の共通構築をおこなわなければならない。構造に関する規則を書くこと、新トークン毎に正規のステートメントを定義すること、文法に関する構文解析ファンクションを書くこと、及び最後にこれらのファンクションにセマンチック・アクションを取ることである。
著者紹介: Dinil Divakaran
緒言
私の勤める会社は社用e-メールプラットホームにファックス送受信用システム、マイクロソフトマイクロソフト・エクスチェンジを組み込んでいる。ある日ソフトウエア更新後このシステムが壊れた。次の条件で同等機能の何かが必要になった:
この記事では、幾つかオープンソース・アプリケーションをLinuxプラットホームに組み込んでこれらの条件を満たす方法を述べる。
謝辞
この記事を書くのを助けて頂いた多くの人々と組織に感謝の意を表する。第一に、スペインのTorrelavegaにあるSolvay Química S. L.工場のIT部の方々、第二に、この記事を書くに当たり、我が社上層部の許可と支援。最後に、本文で述べたオープンソースプロジェクトに対するすべての協力者、(重要な情報を頂いた)HylaFAX メーリングリストの参加者、及びsmbfaxクライアントツールを開発された Craig Kellyである。
システム概要
コンピュータは、TOSERFAXとしてファックスソフトウエアの組み込んだPCである。
適用したソリューションにはHylaFAXソフトウエアが含まれる。このアプリケーションは搭載モデモを制御して受信ファックスを配布し送信ファックスを送信する。
受信ファックスはPDFフォーマットに変換してSTMP e-メール経由で宛先に配られる。PDFを選んだのは、サイトのプラットホームの標準ソフトウエアの一部がAcrobat Reader であったため。宛先確認の規則は、後に述べる。
ファックスを送りたい人は、TOSERFAX,のプリンタ待ち行列に文書をプリントする。そのSambaが他のすべてのコンピュータで読めるようにする。プリントジョブが巻き取ったe-メールをユーザーに送る。このe-メールには Apacheウエブサーバーで飛行中に作られたウエブ書式のURLが含まれる。ウエブ書式により、ユーザーはファックス詳細、特に宛先電話番号、を満たすことが出来る。ユーザーが書式を満たして「送信」ボタンをクリックすると、ファックスは送信待ち行列に入る。
ハードウエアとソフトウエア
TOSERFAXのハードウエアは次の通り:
ソフトウエアについては:
TOPHONE=$($AWK '/SESSION BEGIN/ {print $NF; exit}' log/c${COMMID})
faxrcvd とFaxDispatch の新バージョンは、ここ here とここ hereにある。
faxrcvdの標準バージョンは、ファックスをe-メール中のpostscript添付ファイルとして宛先に送る。私の工場では、標準PCにpostscriptビューワがないので、これは最良の選択ではない。だが、PDFビューワを備えており、postscriptファイルをPDFに変換することが出来る。
しかし、添付ファイル付きのe-メール送付に関して、一寸した問題があった。TOSERFAX は、SMTPリレーとして、IISバージン4で走るWindowsNTサーバーを使う。発見出来ない何かの理由で、このサーバーは、faxrcvdで作った添付ファイル付きe-メールを配布することが出来なかった。
解決策は、パケージmetamail 2.7.19に含まれるツール"metasend"を使うことである。以前にSTMPリレーに受け入れられる方法でPDFフォーマットに変形しておいたスクリプト metasend.sh と tiff2pdf.sh がファックス送信に役立った。これらのスクリプトがツールtiff2psとgsを呼び出すことは説明する価値があるだろう。
ファックス送信
複数のプラットホーム用にHylaFAXで使えるように書いたファックスクライアントが幾つかある。しかし、Torrelavega のIT管理者は、クライアント側のソフトウエア搭載を避ける方向にある。現場にあるPCの唯一の操作は、最大でも、ネットワークプリンタのコンフィギュレーションなので、出来れば、エンドユーザ自身に自動的におこなわせたい。
プリンタ待ち行列を使ったため、文書のプリントが出来るアプリケーション(つまり、実用上すべてのアプリケーション)がファックスすることが出来る。この点で、この記事のファックス対策は、Microsoft Exchangeに搭載された他の著作権システムより優れている。それらは、Microsoft Officeなど特定のアプリケーションで作ったものしかファックス送信しない。
Craig Kellyの開発したパケージsmbfaxは、上述の要件を満足する。基礎の考え方は、極めて賢明だ:クライアントは送りたいファックスを、SambaでTOSERFAXにコンフィギュアし、postscriptプリンタの特性を持つプリンタ待ち行列にプリントする。プリントすると事実上Perlスクリプトが実行され、これがプリントした文書をファイルに置いて、中にURLのあるe-メールをクライアントに送る。このURLはウェブサーバー飛行中にTOSERFAX (Apache)で作られたウエブフォームへのリンクである。クライアントはURLをクリックし、ブラウザを起動し、そのウエブフォームを使って、ファックスを送る電話番号(単数又は複数)を記入し、カバーペイジを付けるかなどの詳細を選ぶ。最後に、「送信」ボタンをクリックすると、ファックスが発信待ち行列に入る。処理中にエラーがあると、クライアントに同じくe-メールで通知する。このシステムは明らかに、ファックスする人の身分(WindowsPCへのログインに際し受領した認証証明書を得ることが出来る筈だ)と同時にe-メールアドレスを知っていることを必要とする。
smbfaxのインストールは簡明直截だ。パケージ文書に色々なステップが説明されているので、ここで繰り返すのは無駄なだけだ。
一方、Sambaのコンフィギュアには、面白い仕掛けがある。関連ファイルはここ hereにある。以下の行を強調しなければならない:
[global]
workgroup = DOM
netbios name = TOSERFAX
security = DOMAIN
winbind uid = 10000-20000
winbind gid = 10000-20000
template homedir = /home/win/%D/%U
winbind separator = +
printer admin = @DOM+PRINTADMIN
...
[print$]
path = /etc/samba/printers/
browseable = yes
read only = yes
write list = @DOM+PRINTADMIN,root
# ファックス待ち行列はこの部分でコンフィギュアされる
[fax]
comment = Fax queue
path = /tmp
printable = Yes
writable = no
create mode = 0700
guest ok = no
postscript = Yes
printing = lprng
print command = /usr/local/smbfax/smbfax -r queue %u %s
lpq command = /usr/local/smbfax/smbfax show
lprm command = /usr/local/smbfax/smbfax dequeue %j
Samba サーバーとして、TOSERFAX は Windows 2000 ドメイン(Active ディレクトリ)に含まれる。Samba バージョン2.2.3は、"winbindd"のサポートを特徴としており、これがそのドメインのセッション開始に際して得た証明書に基づいてクライアント認証を作成する。その結果、WindowsユーザーをLinuxボックス内に作る必要はない。Sambaサーバーに初めて接続する各クライアントは<ドメイン名>+<ユーザー名>の組合せで識別され、1000 - 2000の範囲に "uid" を獲得する。[fax]セクションの中では、
print command = /usr/local/smbfax/smbfax -r queue %u %s
の行が、前に確認したユーザー名をパラメータ%uの中で渡して、プログラムsmbfaxを呼び出す。
[global] セクションの中では、
printer admin = @DOM+PRINTADMIN
の行が、NT ドメインDOM の中のPRINTADMINの全メンバーにプリンタ待ち行列の中で管理上の権利を与える。これらのユーザーは、プリンタをコンフィギュアし、(異なるWindowバージョンのため)ドライバをインストールし、NT 又はWindows 2000 ボックスにあり、遠隔手順呼出(RPC)を使うリモート管理ツールを用いてドメインユーザーにプリント権利を与えることが出来る。これら全部は、プリンタサーバーがWindowsボックスでなくLinuxであることにユーザーが気付かない方法でおこなわれる。
DOM+PRINTADMINグループのメンバーは、勿論パス /etc/samba/printersへの書込アクセスを与えられている。これはLinuxファイルシステム内で必要な許可を認めて行う:
$ chown -R DOM+PROWNER:DOM+PRINTADMIN /etc/samba/printers
$ chmod 0775 /etc/samba/printers
ドライバ・インストレーションは特に興味ある特性だ。現場で使われるWindowsの全バージョン95,NT,2000のためpostscriptプリンタのドライバをTOSERFAXにインストールすることが出来る。この作業を行うと、初めてプリンタ待ち行列に接続したクライアントは全部必要なドライバをインストールすることが出来る。クライアント側でコンフィギュレーション作業が不要とのネットワーク管理目標の一つを達成したことになる。
加えて、NTアクセス制御リスト(ACL)を用いて、任意の数のPRINTADMINグループのプリンタ待ち行列へのアクセスを制限することが出来る。
未だ答えていない唯一の疑問は、e-メールを使ってファックスを送りたいユーザーに連絡する方法だ。winbinddのお陰でユーザーは認証されているが、どちらがe-メールアカウントだろうか?アクチブなディレクトリからこの情報を読む方法がないので、多分OpenLDAPを使って、対策はファックスを使う可能性のあるユーザーのリストを、そのe-メールアドレスとともに、"aliases"ファイルに人手で
DOM+User1: email-1@domain.com
DOM+User2: email-2@other-domain.com
などと加える。"newaliases" を実行するとシステムの準備が整う。
システムの保守
各成分をコンフィギュアすると、最後になすべきことは、基本的運営問題を自動化することだ。これは /etc/crontabに次の行を加えると簡単に満足される:
0 21 * * * root test -x /usr/sbin/faxqclean && /usr/sbin/faxqclean
25 23 * * * root test -e /usr/sbin/faxcron && sh /usr/sbin/faxcron | mail faxmaster
しかし、SuSE 7.2 に含まれるHylaFAX パケージはfaxcron を/etc/cron.daily に残すことに注意のこと。だから、提案の計画に適用するにはそれを動かさなければならない。
結語
Linuxシステム上で HylaFAX, Samba, smbfax その他のオープンソースパケージを組合せることにより、Windows環境の中に効率の良い集中ファックスサービスを組み込んで、IT管理者の期待、特にクライアント側に追加ソフトウエアインストレーションがないこと、を実現することが出来た。
Part I (パートI)は、4月号に書いた。
ブートセクターの作り方を習った後、保護モードに切り換える前にしなければならないのは、BIOS割込の使い方だ。BIOS割込は、OSクリエータの仕事をし易くするためBIOSが提供する低レベルのルーチンだ。記事のこのパートでは、BAIOS割込を取り扱う。
1. 理論
1.1 何故 BIOS か?
BIOSは、ブートセクターをRAMにコピイして、そこでコードを実行する。この他にも、BIOSの行うことは沢山ある。OSをブートアップしたとき、ビデオドライバやフロッピイドライバなどのドライバを持っていない。これらのドライバをブートセクターに含むのは不可能に近い。そこで、別の方法を考えないといけない。BIOSがその助けになる。BIOSには使うことの出来る各種のルーチンがある。搭載機器の点検、プリンタ制御、メモリサイズ発見など各種目的の既製ルーチンなどである。これらのルーチンをBIOS割込と言う。
1.2 BIOS 割込を呼出す方法
通常のプログラム言語では、ルーチンをコールしてルーチンを呼び出す。例えばC言語では、 display と言う名のルーチンがあると、noofchar - 表示する文字数、attr - 表示文字の属性のパラメータを持つことだけで、ルーチン名を書くだけのルーチンを呼び出す。ここでは割込を使う。つまりアセンブリ命令 int を用いる。
例えば画面に何かをプリントするには、Cファンクションを次のように呼び出す:
display(noofchar, attr);
これと同じことを、BIOSを使うときは、次のように書く:
int 0x10
1.3 そこで、パラメータを渡す方法
BIOS割込を呼び出す前に、レジスタに規定のフォーマットで一定の値をロードする必要がある。BIOS割込13番を使うとする。これはデータをフロッピイからメモリに転送するものである。割込13番を呼び出す前に、データをコピイするセグメント・アドレスを規定しなければならない。また、転送するセクターのドライブ番号、トラック番号、セクター番号、セクター数などを、パラメータとして渡す必要がある。規定のレジスタに必要な値をロードしてこれを行う。考え方は、構築しようとするブートセクターの説明を読んだ後に明らかになるであろう。
一つ重要なのは、同じ割込を色々な目的で使うことが出来ることである。特定の割込を使う目的には、選んだファンクション番号に左右される。ファンクションの選択は、ahレジスタに存在する値に左右される。例えば、割込13番は、文字列の表示と同時にカーソル位置の取得に用いることが出来る。レジスタ ah に値3を移動すると、カーソル位置を取得するファンクション3号が選ばれる。文字列を表示するには、レジスタ ah に、文字列画面表示に相当する13hを移動する。
2. 何をしようとしているか?
今回のソースコードは、アセンブリ言語プログラム二つとCプログラム一つから成る。第一のアセンブリファイルはブートセクター・コードである。ブートセクターでは、フロッピイの第二セクターをメモリセグメント 0x500 (アドレス位置は 0x5000)にコピイするコードを書いた。これはBIOS割込13番を用いて行う。ブートセクターのコードは、次いで、制御をセグメント 0x500 のオフセット0に移す。第二アセンブリファイルのコードは、BIOS割込10番を使う画面上へのメッセージ表示である。Cプログラムは、アセンブリファイル1から作った実行可能コードをブートセクターに、アセンブリファイル1からから作った実行可能コードをフロッピイの第二セクターに転送するためのものである。
3. ブートセクター
割込13番を用いて、ブートセクターは、フロッピイの第二セクターメモリ位置0x5000 (セグメントアドレス 0x500)にロードする。下記に示すのは、この目的のソースコードである。このコードをファイル bsect.s にセーブする。
LOC1=0x500entry startstart:mov ax,#LOC1mov es,axmov bx,#0mov dl,#0mov dh,#0mov ch,#0mov cl,#2mov al,#1mov ah,#2int 0x13jmpi 0,#LOC1
1行目はマクロと同様である。次の二つのステートメントは、もうお馴染みだろう。次ぎに値 0x500 を es レジスタにロードする。これは、フロッピイの第二セクター(第一セクターはブートセクター)にあるコードを移動するアドレス位置だ。ここで、セグメント内のオフセットをゼロと規定する。
次ぎに、ドライブ番号を dl レジスタに、ヘッド番号を dh レジスタに、トラック番号を ch レジスタに、セクター番号を cl レジスタに、セクター数をレジスタ al に、ロードする。そこで、ドライブ番号0のトラック番号0のセクター2をセグメント 0x500 にロードする。これらすべては、1.44Mbフロッピイに相当する。
値2をレジスタ ah に移すことは、ファンクション番号の選択に相当する。これは、割込13番が与えるファンクションから選ぶものである。ここでは、データをフロッピイから転送するファンクション、ファンクション番号2を選ぶ。
ここで割込13番を選ぶと、結局、セグメント 0x500 の0番オフセットにジャンプする。
4. 第二セクター
第二セクターのコードを下記に示す:
entry startstart:mov ah,#0x03xor bh,bhint 0x10mov cx,#26mov bx,#0x0007mov bp,#mymsgmov ax,#0x1301int 0x10loop1: jmp loop1mymsg:.byte 13,10.ascii "Handling BIOS interrupts"
0x500 にロードして実行する。ここのコードは割込10番を使用して、カーソル現在位置を取得し、次いでメッセージをプリントする。
bh レジスタの中の値をクリアする。文字列の中の文字数をレジスタ ch に移動する。bx には、ペイジ数と表示中に設定する属性を移す。ここでは黒色背景に白色文字を表示する積もりである。次いでプリントするメッセージのアドレスをレジスタ bp に移す。メッセージは、キャリッジリターン(CR)とラインフィード(LF)を合わせた enter に相当する13と10の値を持つ2バイトから成る。次いで24文字の文字列がある。ここで、文字列プリント及びカーソル移動に相当するファンクションを選択する。ここで割込を呼び出す。最後に通常のループが来る。
write.c にセーブする。
#include <sys/types.h> /* unistd.h がこれを必要とする */#include <unistd.h> /* read/write を含む */#include <fcntl.h>int main(){char boot_buf[512];int floppy_desc, file_desc;file_desc = open("./bsect", O_RDONLY);read(file_desc, boot_buf, 510);close(file_desc);boot_buf[510] = 0x55;boot_buf[511] = 0xaa;floppy_desc = open("/dev/fd0", O_RDWR);lseek(floppy_desc, 0, SEEK_SET);write(floppy_desc, boot_buf, 512);file_desc = open("./sect2", O_RDONLY);read(file_desc, boot_buf, 510);close(file_desc);lseek(floppy_desc, 512, SEEK_SET);write(floppy_desc, boot_buf, 512);close(floppy_desc);}
bsect.s から作成した実行可能コード、ファイル bsect をブートセクターにコピイする。次いで、フロッピイの第二セクター sect2.s に相当する実行可能コード sect2 をコピイする。また、フロッピイをブート可能にするためおこなう変更も実施する。
make
as86 bsect.s -o bsect.old86 -d bsect.o -o bsect
sect2.s に同じことを繰り返すと sect2 が得られる。write.c をコンパイルして
cc write.c -o write./write
とタイプしてブートフロッピイをドライブに置いた後、これを実行する。
7. 次回予告
フロッピイを使ってブートすると、文字列が表示される。これでBIOS割込を使った。このシリーズの次のバートでは、プロセッサを保護モードに切り換える方法を述べる。
ファイルを学校から家に持ち帰るとき、友人から古い40MB HDDを借りた。全く古い奴で、重さが1/4キロもある大型だった。当たり前だが、ケーブルを掴んでコネクタに突っ込んだ。電源が入る筈だった。
「慎重に」電線を突っ込んだとき、HDDのボードへのコネクタが壊れた。良くあることだ。必要なハンダ付けをして、配線し直し、電源を入れて「セットアップにはDELを押す」とのメッセージを待った。最初に出たのは、メッセージでなく、煙だった。コネクタからではなく、HDDボード上のレジスタからだ。無惨に過熱して溶け落ちた。初めは煙に気付かずレジスタが金属ケースを叩く音を聞いただけだったからだ。幸い、他に焼けたものはなかった。
以後ハンダ鏝に触ったことはない。
この話の教訓:
アンドレー・ブリンシアヌ
ルーマニア
今日ではIDE装置は(UltraDMA 技術により)既に高い転送速度を有するが、固定ディスクの性能を改良する別の方法もあるので、hdparmを用いるその方法を紹介する。
1. はじめに
hdparmは、強力なHD (HD PARaMeters)チューニング制御を与えるユティリティである。この記事ではそれを述べる。HDがその最大能力で働く設定になっていなくて、そのためイライラすることがある。hdparmの特性全部を使うと、最大性能を発揮するようになる。
2. ハードディスクを眺める
先ず、ハードドライブ及びその現在の設定に関する情報を集める。これらの情報が、これからおこなうハードディスクのコンフィギュアの基礎になる。コンフィギュレーションに少しでもミスがあると、ディスクを部分的に(データ)又は全面的に(ハードウエア)壊すことがあるので、これからのステップを極めて慎重に進めること。
ここではディスクを /dev/hda と推定する。次のコマンドを入れる:
darkstar:~$ hdparm -i /dev/hda
次のような情報が得られる筈だ:
/dev/hda:
Model=QUANTUM FIREBALLlct20 20, FwRev=APL.0900, SerialNo=552114732078
Config={ HardSect NotMFM HdSw>15uSec Fixed DTR>10Mbs }
RawCHS=16383/16/63, TrkSize=32256, SectSize=21298, ECCbytes=4
BuffType=DualPortCache, BuffSize=418kB, MaxMultSect=8, MultSect=off
CurCHS=16383/16/63, CurSects=-66060037, LBA=yes, LBAsects=39876480
IORDY=on/off, tPIO={min:120,w/IORDY:120}, tDMA={min:120,rec:120}
PIO modes: pio0 pio1 pio2 pio3 pio4
DMA modes: mdma0 mdma1 mdma2 udma0 udma1 udma2 udma3 udma4 *udma5
AdvancedPM=no
Drive Supports : ATA/ATAPI-5 T13 1321D revision 1 : ATA-1 ATA-2 ATA-3
ATA-4 ATA-5
何だか分からないだろう。だがこれが役に立つ重要で有用な情報だ。見てみよう。
別の情報を獲得するため発する命令は
darkstar:~$ hdparm /dev/hda
で、これは次の結果を与える:
/dev/hda:
multcount = 0 (on)
I/O support = 0 (16-bit)
unmaskirq = 0 (off)
using_dma = 0 (off)
keepsettings = 0 (off)
nowerr = 0 (off)
readonly = 0 (off)
readahead = 8 (on)
geometry = 2482/255/63, sectors = 39876480, start = 0
簡単に説明すると、
これらに分からないものがあっても、投げ出してはいけない。記事を読み進むに連れて分かって来る。これらパラメータの幾つかは、ハードドライブのハードウエアに論理的でなく物理的に関係している、だからハードウエアを変えない限り変えることは出来ない。(もし変えると、ハードディスクが壊れデータが破壊される)
3.デバイスの設定
これからHDを設定する。注意:設定中の間違いはハードディスクとそのデータを破壊する。ここで 'hdparm -i
3.1 I /0サポート
君が(E)ISA IDEインターフェースカードを持っているのでなければ、残り (PCI/VLB)はすべて32ビットモードをサポートする。君のボックスが486以上でなければ、多分 PCI IDE コントローラがある筈だ。なければ、点検のこと。
モード '3' だけは、一定のチップセットに必要である。最良性能にはモード '1' を使う人が多い。モード '2' に付いての情報はない(16-ビット同期と思われる。
3.2 MutSEct 又は Multcount
これは簡単だ。君のHDの MaxMultSect 情報を調べて何が出来るか考える。HDがサポートしているのでMultSectを8に設定する
# hdparm -m 8 /dev/hda
/dev/hda を君のデバイスに変え、'8' を君のハードディスクがデバイスが 'hdparm -i
3.3 DMAの起動
最も簡単、単に
# hdparm -d 1
とタイプしてDMAモードをONにする。君のカードがDMAモードをサポートしていなければならない。
3.3 PIO 及び DMAモード
同一フラッグ '-X' を用いてこの両方を設定することが出来る。これは、極めて慎重に使わないとハードドライブを追い出し(本当だよ!)第一HDが自分で月に行ってしまう。君のハードディスクがサポートしているモードだけを設定する。
うん、通常 DMA モード(multiword DMA 又はmdma)ではこんな風に働く、 -X32 + (DMA 識別番号)を使う。mdma2 については:
# hdparm -X34 /dev/hda // 32 + 2 (from mdma2)
となる。
PIO 及び UltraDMA モードについても、手順は殆ど同じだ。違いは基準数で、PIOモードについては8、UltraDMA モードに付いては64になる。この記事を書く間に使ったディスクはATA100をサポートするので、次を使ってudma5モードにした:
# hdparm -X69 /dev/hda
最高DMAモードは、一定のチップセットでだけ得られるのに留意すること。
ATA66 及びATA100モードは、80芯IDFケーブルを必要とする。これらのケーブルなしでディスクをATA100にしても働かない。
3.5 前方読取(readahead)
オプション前方読取(readahead)はmultcountと同じではない。multcountは、ハードウエアが一時に一つ以上のセクターを読み取る意味で、前方読取オプションはコンピュータが先立って読み取るセクターの数である。前方読取特性は、大型ファイル読取の際には偉大だが、短いファイルでは性能を下げる。前方読取の値をmultcountと同じままにして、前方を沢山読み取るため一時に一度以上のアクセスが不要なようにするのが賢明である。
大型ファイルにアクセスするときは、前方読取を大きい値に設定することが出来る。規定値は8セクター/読取アクセス(4kbなど)である。
構文は:
# hdparm -a N /dev/hda
N は前方読取のセクター数である。
4. 最後の注釈
hdparmを使って設定することの出来る特性は他にも沢山ある。それらの殆どは、hdparmのマニュアルに含まれている。説明したのは最も普通のものだけだ。
マシンをリブートすると、コンフィギュレーションがリセットされる(設定保留はソフトリブートだけが対象なので働かない)。コマンドを rc.local に入れること(大型コンフィギュレーションについては、rc.hdparm又はこれに類似のものを持つのが賢明だ)。
この記事への質問は:piterpk@terra.com.brへ。
この英訳に関する問題は、 wzanatta@uol.com.brへ。.
少しばかりハードウエアにいたずらしたいときは何時でもMicrosoft OSをブートアップしなければならない時代があった。今はそんなことはない。 Microchip PICであれ、Intel 8051であれ、Motorola 68HC05や Atmel AVRであれ、主要マイクロコントローラ上で開発をするとき利用出来る無料ツールがある。この記事では、Linux上で PIC 16F84 を用いてスタートする方法を述べる。
2. PICI6A84の簡単な説明
Peripheral Interface Controller(周辺装置相互接続コントローラ)16F84は、初心者にも利用出来る中規模マイクロコントローラに最適である。PICマイクロコントローラは、安価で多用途である。これらは多数の機能性を単一チップ−プログラムメモリ1024バイト(長さ14ビット)、RAM68バイト、EEPROMメモリ(不十分と思うだろうが、これで十分なのだ)−の上でサポートする。16F84は、18ピンパケージで供給され、13個のデジタルIOポートピンを有する。チップ内には、タイマーと割込コントローラがある。この他に、回路内直列プログラムをサポートする。追加の文書は公式 MicroChip site.にある。
3. ハードウエア要件
PICに機械語コードを書くためには、バーナー・ハードウエアが必要だ。簡単及び複雑両方の各種のプログラム回路がネット上で得られる。これとは別に、最も普及しているのは、DavidのPIC programmerだ。この回路は簡単で設定が容易だ。回路を正しく働かせるには、最低15vの直流電源が要る。
4. ソフトウエア要件
4.1 プログラマ
上述の回路で働くPIC用GNUバーナー・ソフトウエア、pp (Pic Programmer)が利用出来る。これもDavid Tait が書いた。PIC archive サイトからダウンロード出来る。ppは、上述以外の各種回路もサポートする。PICのプログラムメモリは、1000書込サイクルしかサポートしない。ppは、既に書き込まれるコードと異なるコードを有する位置にしか上書きしない点で、極めて効率がよく速度が速い。コードが同一であると、コードをメモリに書き込まない。
PICプログラマの使用
ppのバイナリを作った後、なさなければならないのは次のステップである:
PPSETUP=3とタイプする。これはppにClassic Pic バーナー回路を使うことを告げるためである。
ここでpp とタイプする。諸事万端順調なら、ハードウエアが働いて、ppがHardware detected OKのメッセージを表示する。焼き付け中にppに与えることの出来るオプションを表示する。そうでないときは、デバッグモードに入る。これはハードウエアのデバッグに有用だ。
順調なら、ここで実際に機械語コードをPICに焼き付ける。
GNU PICアセンブラ(gpasm)の使用
GNU PICアセンブラは、入力アセンブリ命令に関する機械語コードを作成する。アセンブルした後、 intel HEX formatで機械語コードを作成する。この出力コードはppにたいする直接入力として与えることが出来る。
gpasmは gputils からダウンロード出来る。これはPICファミリ用のソフトウエア多数を含む。
5. Hello world !!!!
LEDのグループ(例えば8個)を点滅する最初のプログラムを書こう。LEDはPORTBの8ピンに接続する。そこでこれらを出力ピンとして設定する必要がある。PORTBを出力ポートとして設定すると、間に遅延時間をおいてPORTBの8ビット(8個のLEDに対応)に1と0を送ることが出来る。
アセンブリコードを書くには好みのテキストエディタ(Emacsなど)を使う。アセンブリコードの1行目で使用するマイクロコントローラを定義しなければならない(GPASMを使うとき)。次いで、コードを書き始める。LED点滅のためのコードを示す:[text version]
list p=16f84 ;specify the micro controller used.
f equ 1
porta equ 0x5 ;specify the address of the ports
portb equ 0x6 ;
Delay_i equ 0xc ;The first byte of RAM available.
Long_Delay_i equ 0xd
tmp equ 0xe
goto Main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; 以下のサブルーチンはPIC用4Mhzクロックに関し1msの遅延を生じる.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Delay
movlw 0xff
movwf Delay_i
L1 nop
decfsz Delay_i, f
goto L1
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; このサブルーチンは(約)1秒の遅延を生じる
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Long_Delay
movwf tmp
movlw 0xff
movwf Long_Delay_i
L2 call Delay
decfsz Long_Delay_i, f
goto L2
movf tmp,w
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;以下のコードは、すべてのポートを出力ポートして設定する。
;ポーとを入力ポートとして設定したいときは、
;TRIS レジスタの相当するビットを1に変える。
;例えばポートportb0-3 を入力とし他のピン全部を出力として
;使いたいときは、次の命令を用いる
;
; movlw 0x0
; tris porta
; movlw 0x0F
; tris portb
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Main
movlw 0x0
tris porta
tris portb
movlw 0xff
movwf portb
L3
call Long_Delay ;make a 1 sec delay between blinking.
comf portb,f ;complement portb
goto L3
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.s 拡張子を付けてファイルをセーブする。コマンド gpasm filename.s をタイプするとコードをアセンブルすることが出来る。エラーが報告されなければ、ファイルfilename.hex に機械語コードが得られる。そこでコードを焼き付けるには次のコマンドをタイプする。
$ export PPSETUP=3 $ pp -xp filename.hex
オプション-x は、回路に水晶発振器を使うことを定め、-p はPICのパワーアップタイマーを使うことを定める。その他普通に使われるオプションは:s
-e --- プログラム・メモリとeeprom メモリ消去のため
-w --- 監視タイマー起動のため
-v --- コードの検証のため
何をお探しですか?PICを使っていたずらしませんか?
request クラスはクライアントがサーバーに送る要求をあらわす。このクラスは、"name"プロパティと、"params"のコレクションを有する。requestは、method call と考えてよい。"name" プロパティはメソッドの名称を意味し、"params"のコレクションには、メソッドに対する引数が含まれる
reply クラスはサーバーがクライアントに送る返答をあらわす。"value" プロパティと、"errors"のコレクションを有する。reply クラスは、method call に対するreturn value と考えて良い。"value" プロパティはメソッドから返される実際の値である。"errors" コレクションには、メソッドが生じるあらゆるエラーが含まれる。
server クラスはframeworkの働き者である。このクラスから新しいサーバーを作ることを誘導する。面白いメソッド二つ - "handle_request" と "run" - を含む。"run" メソッドは、サーバーに行動を取らせ、接続を受領し始める。"handle_request" メソッドは、誘導クラスの中で無効にされ、クライアントがサービスを要求する度に呼び出される。
最後のクラスclient により、クライアント・プログラムはrequestオブジェクトをサーバーに送ることが出来る。ホストとポートにクラスのコンストラクタを渡し、次ぎに"send_request" メソッドを使って、requestオブジェクトをサーバーに送る。
2.3 簡単なサーバーとクライアント
ここでframeworkの中の主C++に入る。作動例を眺める。次の二つのファイルが最小のサーバーとクライアントを実現する。
simple_quoter_server.cpp では、"simple_quoter_server"と言う名のC++クラスを定義し, それをxmlrpc::serverから誘導する。"handle_request" メソッドを無効にする。これはクライアントがrequestする度に呼び出される。ticker が "RHAT"であると、その値をrelpyオブジェクトの "value" プロパティの中で返す。エラーが起こると、エラーをerrorsコレクションに加える。
simple_quoter_client.cpp では、 xmlrpc::client クラスのインスタンスを作ってrequestオブジェクトを設定し、"send_request" メソッドを経由してrequestをサーバーに送る。
3. framework内部
3.1 XML
frameworkは、クライアントとサーバーの間のメッセージ受渡にXMLを使う、コードを何も書かないうちにしたことは、requestとreplyに関しXMLがどのようになるかを定義することだ。以下を思い付いた:
// // <request> // <name></name> // <params> // <param> // <name></name><value></value> // </param> // </params> // </request> // // // <reply> // <return_value></return_value> // <errors> // <error></error> // </errors> // </reply> //
次ぎにExpat XML Parser の使い方を学習しなければならない。www.xml.com の上で使い方を説明した偉大な記事how to use expatを見付けたので、あらゆるものを包み込んだ次のクラスを書いた:
このnode クラスは、XML文書の中のノードをあらわす。これを "load_xml" メソッド経由でXML文字列に渡すと、それが文字列を解析してXML文書のメモリ内表現を作成する。これは聞くことの出来る子ノードを有するので、XML文書の中に深く入り込むことが出来る。XML文字列が必要であれば、その "get_xml" メソッドに聞くことが出来る。
次ぎに、上に紹介したXML定義をあらわす二つのクラスを作った:
両方のクラスに "get_xml" メソッドと "load_xml" メソッドがあるのに気付かれるだろう。"get_xml" メソッドは、クラスの内部表現を含むXML文字列を返し、"load_xml" は、その同じm文字列をクラスの中にロードし直す。結果は、これら二つのクラスがXML文字列に対し存続し、これらの文字列を後でロードすることが出来ることとなる。
残りのframeworkがXMLを全く心配しないで済むようにこれを行った。クライアントクラスとサーバークラスは、"load_xml" メソッドと "get_xml" メソッドを使って、互いに送る必要のあるXMLデータを作る。これら二つのメソッドの実行をがXMLを使わないよう変更しても、クライアントスラスとサーバークラスが正しく働くよう変更することが出来る。
3.2 ネットワークのコード
frameworkは、次の三つのC++を使って、ネットワーク上でデータを受け渡しする:
これら三つのクラスを説明した記事はLinux Gazetteの1月号にある。クラスの名称は変わっているが、動作は同じである。
3.3 スレッドのコード
これから直ぐに説明するサーバークラスは、クライアントからの要求を受けるとき、多重スレッドを使う。frameworkの中の以下のコードがスレッドのサポートを与える:
threadクラスは、実行の単一スレッドをあらわす。thread_groupクラスは、 Boost.Threads Libraryから私が借用した考え方をあらわす。基本的に、一つのスレッドを作るだけなら、threadクラスを使う。一つを超えるスレッドを作るなら、thread_groupクラスを使う。
機会があったら、是非Boost site を調べること。Boostは、C++ファンのグループでクロスプラットホームライブラリを作っている。これについて特別なのは、Boostメンバーの何人かが、C++ Standards Committeeのメンバーでもあることだ。これはここで見付かるライブラリがトップクラスのものであることを意味する。
3.4 serverクラス
serverクラスは、次のファイルが定義し実行する:
*.cpp ファイルの頭にある "accept_thread" クラスに注目されたい。前に"server" クラスはframeworkの働き者と言ったのを覚えておられるだろう。真実を全く正確には言っていない。serverクラスが行うことのすべては、"accept_thread" オブジェクト の束を作って、その完了を黙って待つことである。
"accept_thread" クラスの上書きされた"()"オペレータがすべての作業を実行するので、これを眺める。その実行は下記をおこなう:
基本的は、ソケットをうけいれ、要求を処理して、回答を送った後ソケットを閉じる。
3.5 clientクラス
clientクラスによりサーバーに要求を送ることが出来る。次のファイルが定義し実行する:
"send_request" メソッドは次のステップを実行する。
この記事に関するすべてのファイルは、次の文庫にある。
次のコマンドを用いてframeworkを引き出し構築することが出来る:
prompt$ gunzip app_server_c++.tar.gz prompt$ tar -xf app_server_c++.tar prompt$ cd app_server_c++ prompt$ make