場合 - みる会図書館


検索対象: UNIX MAGAZINE 2003年6月号
128件見つかりました。

1. UNIX MAGAZINE 2003年6月号

フ ェ イ ス の 街 角 66 増井俊之■ 状況依存の予測入力 予測型テキスト入力は、 PDA や携帯電話ではおなじみ の手法になりつつあります。ここ数年、私は UNIX 上の Emacs や Windows アプリケーションなどでも予測型入 カ手法である POBox を使用しています。 POBox のよ うな予測型入力システムでも一ヨ殳的なかな漢字変換システ ムでも、どの単語を確定したかによって学習がおこなわれ るのか普通なので、 1 回使った単語や文章は 2 回目以降は 入力しやすくなるという特徴があります。このため、使っ ていくにつれて自勺にカスタマイズがおこなわれること になります。しかし、初めて使う単語については予測や変 換がうまくいかない場合があります。そもそも、どんな状 況でも同じ手法で予測や変換がおこなわれるのは適切とは いえないかもしれません。 文章を書くときの状況に応じて予測の手法や辞書を切り 替えることができれは、入力の効率が矼ヒする可能性があ ります。ューザーの違いだけでなく、利用するアプリケー ションや入力をおこなう時間や場所、場合によっては気 分によって辞書や予測手法を切り替えられるとイ叫リでしょ このように、予測入力における辞書の切替え手法はいろ いろと考えられますが、今回は、入力しようとしているテ キストに関連する既存の文書を利用して予測辞書を切り替 える去について考えてみます。 予測型入力システムを用いて計算機についてのメールを 書いている場合、、、 k 。 n " と入力したときには、、コンピュ ータ " や、、コンパイラ " などの単語が予測されると好都合 です。しかし、コンサートへの誘いのメールに対して返事 動的単語補完による状況依存入力 188 を書いているのなら、 適切かもしれません。 、、コンサート " と予測されるほうが コンサートへの誘いのメールには、、、コンサート " とい う文字列が含まれている可能性か高いと思われます。した がって、もとのメールに含まれる単語をもとに入力予測を おこなうことにすれば、、、 k 。 n " から、、コンサート " を予測 させることができるはすです。この場合は、返事の対象に なるメールのテキストを予測辞書として使えはよいことに なります。 動的単語補完 既存のテキストを入力に活用する手法は、、重加勺単言甫完 (dabbrev: Dynamic Abbreviation)" と呼はオし Emacs ーヒで使用することができます。たとえば、 Emacs でこの 記事を書いているとき、、、 Abb" と入力してから M-/ キー を押すと、重加勺単言甫完をおこなう dabbrev-expand 関 数か呼び出さ、、 Abb" が、、 Abbreviation" に展開され ます。 dabbrev-expand は、編集中のテキストのなかから入 カ中の文字列と同しプレフィックス ( 接頭辞 ) をもっ単語 を検索し、みつかった場合は入力中の文字列をその単語 に展開します。上の例では、 Abbreviation という単語が テキストに含まれているため、 Abb が Abbreviation に 展開されますが、同しテキストに、、 Abbey " などの単語も 含まれている場合には M ー / キーを押すたびに Abbrevia- tion 、 Abbey 、 Abb のように↑甫単語が切り替わってい きます。 POBox などの予測入力システムにおいても、予測辞 書にもとづ <fl 甫だけでなく、 dabbrev による展開結果 も↑嚇甫として表示すれば、文中にある既出の単語も入力単 UNIX MAGAZINE 2003.6

2. UNIX MAGAZINE 2003年6月号

特集・プログラミング入門 表 1 的なアルゴリズムの手間 れれ一 1 ) / 2 れれ一 1 ) / 2 れれ一 1 ) / 4 れ ( れ一 1 ) / 2 れ ( れ一 1 ) / 2 れれ一 1 ) / 4 れ ( れ一 1 ) / 2 れ一 1 れ一 1 れれ一 1 ) / 4 れ ( れ一 1 ) / 4 れれ一 1 ) / 8 アルゴリスム 純ソート ハフル整列法 〕尺整列法 挿入整列法 最 ) 比較 可れ一 1 ) / 2 可れ一 1 ) / 2 れ ( れ一 1 ) / 2 れ ( れ一 1 ) / 2 最悪の奐 平均の比較 arr [j + 1 ] tmp ; も基均なものです。いずれのアルゴリズムでも、任意の こまでに紹介したのは、整列のアルゴリズムのなかで 基礎的なアルゴリズムの特性 交換の手間は可れ一 1 ) / 8 となります。 半分です。すなわち、上交の手間はれ ( れ一 1 ) / 4 となり、 爿な勺については、上交も交換もさきはどの値のちょうど 換の手間は最悪の場合で可れ一 1 ) / 4 となります。 ので、これを半分と数えることにしましよう。すると、交 こでは値を移測けるだけな 値を交換していたのに対し、 いために計算がちょっと面倒です。 swap 関数では 2 つの 交換の手間については、今度は swap 関数を用いていな ます。 みてきたアルゴリズムと同様な手間がかかることが分かり こまでに もすべてを実行することになります。すると、 動する必要がありますから、外側のループも内側のルーフ しよう。このようなときには、データをつねに麪頁まて彩 データカ芍迎頂に並んでいたケースを考えてもらえはよいで 悪の場合はれ ( れ一 1 ) / 2 回となります。これは、すべての 挿入整列法の手間をみてみましよう。上交の回数は、最 列した状態を作りだしています。 いているはずなので、一尉寺しておいたデータを挿入し、整 する位置がみつかったときは、すでにそこにスペースか空 な値をもつものをどんどん後ろへすらしていきます。挿入 変数にイ尉寺しておき、内側のループでそのデータより大き このプログラムでは、まず注目しているデータを tmp UNIX MAGAZINE 2003.6 2 れ一 1 れ ( れ一 1 ) 2 つの要素を上交する処理をおこなうために、 平均の交換 ます。挿入整列法は、整列した状態に近い入力に関しては かっているのであれば、それについて考慮する必要があり また、特徴のある入力が与えられることがあらかしめ分 可能匪があります。 は・よいため、巨大なデータであっても効率よく処理できる りませんが、値のコピーはたんなる数値のみを対象にすれ データを参照するときによけいに配列を参照しなけれはな 字だけを並べ替える方法も考えられます。この手法では、 並べ替えるのではなく、新たに配列を準備し、データの添 あるかもしれません。そのようなときには、データ自体を 巨大なデータであっても、挿入整列法を使いたい場面も タの場合には、明らかロ尺整列法か効率的といえるでし があり、こちらの手間は無視できません。このようなデー ては、巨大なレコードを含むデータ全体を入れ替える必要 手間はそれはどかかりません。一方、データの交換につい 上交処理では、小さなキーどうしを上交するだけなので、 データを考えてみましよう。このようなデータにおける たとえは、レコードが巨大で、キーのサイズは小さい り大きな間題になる場合です。 くるのは、上交と交換の手間を上交して、後者のはうがよ こだけは〇 ( れ ) になっています。これか効いて らず、 部分です。ほかの項目は〇 ( れ 2 ) となっているにもかかわ でしようか。表のなかで目立つのは、〕尺整列法の交換の それでは、この 2 つのうちのどちらを尺すればよいの 入整列法のどちらかを選ぶことになります。 はどうみても分が悪いです実際には、尺整列法か挿 この表からも分かるように、単純ソートやヾプル整列法 それぞれの手間を表にまとめてみましよう俵 1 ) 。 がよいのでしようか。こまでにみてきたものについて、 それでは、これらのうちどのアルゴリズムを利用するの であることに変わりはありません。 合の手間は半分に改善されていますが、それでも 0 ( れ 2 ) という手間がかかっています。挿入整列法では、平均の場 139

3. UNIX MAGAZINE 2003年6月号

特集・プログラミング入門 こまでできたら、最初に取り出したデータを中間に置 いて両方を連結すれは、全体としての整列か完成します。 これで、アルゴリズムの動作 ( お早できたと思います。 それでは、プログラムとして実現してみましよう。ク イックソートでは、再帰的に関数を呼び出して分割したデ ータを整列します。そこで、これまでの関数と同様なイン ターフェイスを提供するために、トップレベルの関数を作 ります。 VOid sort(void) クイックソートを実現する関数に引数として渡している のは、データかオ褓内されている配列のアドレスと、データ がいくつあるかを示す値です。最初の呼出しでは、もとも とのデータかオ褓内されている配列 arr と、そこにオ内され ているデータ数である N を指定しています。 関数での処理に入る前に、分割したデータの手苻方法を 考えなければなりません。関数では、分割した 2 つのデー タの集まりをイ尉寺する必要があります。しかし、これらの サイズをどれくらいとればよいのかは分かりません。デー タが 10 個ある場合、真ん中のデータとして 1 っ使います が、残りの 9 個のデータをどううリするかは真ん中のデー タによって変わります。最悪の場合には、すべてのデータ カ畤方に偏ってしまう可能性があります。このデータを保 持するのに配列を使うとす川ま、すべてのデータ寺で きるサイズの配列を準備しなけれはなりません。すると、 酉改」のサイズとしては N ー 1 が必要になります。 本当にそうなのか、ちょっと立ち止まって考えてみま しよう。たしかに、最初に呼び出されるときには N ー 1 の サイズが必要です。しかし、さらにその先て呼び出される ときにはより小さなサイズの配列で十分足りるはすです。 この関数は再帰的に呼び出されますから、配列は自動変数 としてスタック上にとる必要があります。したがって、で きるかぎり小さな配列を宣言するようにしないと、スタッ クの容量不足でプログラムかま行できなくなってしまいま す。そこで、今回はスタック上に自動変数として石杲する 釧■ 0000 ・ sort—sub(arr, N) ; UNIX MAGAZINE 2003.6 のではなく、 malloc 関数を用いてヒープ領域から確保す る方式にします。この方針にもとづいて作成したプログラ ムは、図 1 のようになります。 ます、分割したデータをイ尉寺するための領域を確保しま す。次に、う曰頁のデータを mid にイ内し、このデータを もとに残りのデータを分割します。う頁のデータよりも小 さいデータは larr に、う頁のデータよりも大きいデータ は harr : ゴ褓内します。小さいデータがあるのなら、その データを整列するために関数を再帰的に呼び出します。呼 出しか終った点では、 larr と harr はそれぞれ整列して いるはすです。これを最後に、中間に mid をはさみなが ら連結して全体を整列します。 こで、クイックソートの性能をみてみましよう。ま すは、もっとも効率のよくなる場合からです。以下では、 れ個のデータを処理するときの手間を C れとします。この ときデータをう第リするには、すべてのデータを比較する必 要があります。もっとも効率がよくなるのは、ちょうど半 分に分割できる場合です。すなわち、 Cn = C ,. / 2 十れ となるときが、もっとも効率がよいということになりま す。また、分割を続けていってデータの数が 1 か 0 に なると、整列は完了しているとみなせるため、 となります。 CI = C() = 0 この漸イしにを解くと、 Cn れ 10g2 れ になりますから、理論 -1 : の限界に近い手間になります。と ころが、現実にはこれほど想どおりに分割できることは ありえないので、平均の手間を考えるとこれよりもすこ し手間がかかります。しかし、その場合もアルゴリズム の計算量としては 0 ( れ I 。 g れ ) のままです。厳密にいえ は・ 2 れ log 卩 2 ・ 1.39 れ 1 。 g2 れとなり、最適の場合の約 39 % 増しの手間になります。 間題は最悪の場合です。せつかくの 0 ( 司。 g れ ) のアル ゴリズムなのですが、最悪の場合にはこの言 fr 算量では計算 できません。れ ( れ一 1 ) / 2 の手間がかかってしまうのです。 最悪の入力を考えるのも簡単です。すでに整列している入 143

4. UNIX MAGAZINE 2003年6月号

連載 / IPv6 の実装ーの 図 9 ポリシー直に従って適切な SPD 工ントリを返す里 761 762 766 767 769 770 771 772 773 775 776 777 778 779 781 785 786 787 788 789 736 switch (currsp—>policy) { case case IPSEC_POLICY_BYPASS : *error = EINVAL; re turn NULL ; IPSEC_POLICY_ENTRUST : ip6—def—p01icy—>refcnt + + ; *error = 0 ; ipsec—fillpcbcache (pcbsp , return ip6—def—p01icy ; IPSEC_POLICY_IPSEC : currsp—>refcnt 十十・ ipsec-fillpcbcache (pcbsp , return currsp ; m , ip6—def—p01icy, dir) ; currsp , dir) ; default : currsp , dir) ; / * NOTREACHED * / て e turn NULL ; *error = EINVAL ; return currsp , 732 ~ 736 行目は、ソケットを作成したプロセスか明示 checkpcbcache() で検索された SPD 工ントリカ亟され 的にポリシーを指定している場合です。この場合は ipsec- ます。 738 741 742 743 744 745 } default : *error = EINVAL ; return NULL ; / * NOTREACHED * / 未定義のポリシーか指定してある場合はエラーとなり、 NULL カ亟されます。 749 ~ 787 行目は罸在プロセスではない場合の SPD 工 ント弱尺処理です。 749 ~ 758 行目 ( 図 8 ) で、 ipsec-setspidx-mbuf() と key-allocsp() を使ってバケットに適合する SPD 工ン トリを検索します。この点で SPD 工ントリがみつかれ ば、そのエントリを返します。 図 9 の 761 ~ 787 行目で、ポリシーの値に従って適切 90 な SPD 工ントリを返します。罸雀プロセスとの違いは、 IPSEC-POLICY-BYPASS カ甘旨定されているときに工 UNIX MAGAZINE 2003.6 ( しま・けいいち IIJ) 次回も IP セキュリティの出力処理の角見を続けます。 ☆ ラーとなる点です。

5. UNIX MAGAZINE 2003年6月号

連載 / 旧 v6 の実装ーの 図 5 終点ノードが伺ーリンク上にない場合 ~ 里 3337 if (state—>ro—>ro—rt—>rt—flags & RTF—GATEWAY) { 3338 3339 (struct sockaddr * ) state—>ro—>ro—rt—>rt_gateway ; state—>dst (struct sockaddr—in6 * ) state¯>dst ; dst6 3340 } には新しいへッダの終点アドレスに対する経路を設定しな けれはなりません。トンネル外側の終点アドレスに対する 経路情報は SAD 工ントリから取得できます。 3 , 307 行目 で経路↑青報を更新します。 3310 if (state—>ro—>ro—rt & & 3311 3318 3319 3320 3315 3316 ( ! (state—>ro—>ro_rt—>rt_flags & RTF-UP) Ⅱ ! IN6_ARE_ADDR_EQUAL (&dst6—>sin6_addr , &ip6—>ip6—dst) RTFREE(state—>ro—>ro—rt) ; state—>ro—>ro_rt = NULL; 糸各か有在しない場合、バケットを送信することができ ないので破棄します。 3 , 337 ~ 3 , 340 行目 ( 図 5 ) は、トンネルの終点ノード か伺ーリンク上にない場合の処理です。このとき、経路情 報に RTF-GATEWAY フラグが付き、ゲートウェイ・ ノードのアドレスカ陏効になっています。 3 , 338 ~ 3 , 339 行目で、 state—>dst と dst6 をバケットか次に渡される ゲートウェイ・ノードのアドレスに設定します。 3341 } else 3342 SPIX(S) ; 3321 } 3 , 310 ~ 3 , 321 行目は経路 1 青報の正当性のチェックです。 3 , 307 行目で SAD 工ントリから取り出した経路か有効で ない ( 3 , 311 行目 ) か、糸響各情報の終点アドレスがバケッ トの終点アドレスとは異なる、すなわち適切な経路清報で はない場合 ( 3 , 315 ~ 3 , 316 行目 ) には、 3 , 319 ~ 3 , 320 行 3322 if (state—>ro—>ro_rt 目で無効な糸各情報を解放します。 SAD 工ントリがトンネルモード用でなけれは、とくに 処理は必要ありません ( 3 , 342 行目 ) 。 3344 state—>m = 1psec6—sp1ithdr(state—>m) ; 3345 if ( ! state—>m) { 3347 3348 3349 } error = ENOMEM ・ goto bad ; 3323 3325 3327 3328 } *dst6 = sa_dst ; dst6—>sin6—scope—id rtalloc(state—>ro) ; 0 ; / * xxx * / ip6 = mtod(state—>m, struct ip6—hdr * ) ; 3350 3 , 344 ~ 3 , 349 行目で、ふたたひンヾケットを IP ヘッダ 部とデータ部に分割します。トンネルモードでは、内側の IP ヘッダ以降が IP セキュリティの処理対象になります。 殞則の IP ヘッダからは、内側の IP ヘッダ以降がデータ 部にみえるので、処理を簡単にするためにヘッダとデータ を別の mbuf にうリします。 3 , 363 ~ 3 , 395 行目 ( 図 6 ) で、内側の IP ヘッダ以降 を、指定された IP セキュリティ・プロトコルで処理しま す。呼び出す関数はトランスポート・モードの場合と同じ SAD 工ントリにそもそも経路がキャッシュされていな かったり、 3 , 310 ~ 3 , 321 行目で経路か無効であると判断 された場合、 state->ro->ro-rt が 0 になります。トン ネルバケットの殞則の終点アドレスである sa-dst に対す る経路報を 3 , 327 行目で検索し、 state->ro に設定し ます。 0 3396 3397 3398 if (error) { state—>m goto bad ; NULL ; 3329 3332 3333 3334 86 if (state—>ro—>ro—rt got0 bad ; error = EHOSTUNREACH ; 3399 } esp6-output() の実行 ) に失敗した場合は、バケットを ロ・い 証ヘッダや暗号化へッダの作成 (ah6-output() や 破棄します。 3400 p1en state—>m—>m—pkthdr. len UNIX MAGAZINE 2003.6

6. UNIX MAGAZINE 2003年6月号

特集・プログラミング入門 分割には地頁の 4 を使うので、地直を孑一変数は次の要 素である 2 を指すことになります。 ↑ ます、う頁を指す変数 ( ↑ ) を移動しますが、 2 は 4 よ り小さく、次の 3 も 4 より小さいので、変数はその次の 要素である 7 を指します。 介 ↑ 次は末尾を指す変数 ( 介 ) を移動します。こちらは 5 が 4 よりも大きいのでデクリメントされますが、そこで処理 はいったん停止します。 0 ■■・ 000 0 ■ 0 ■ 000 0 ■■■ 000 両方の変数か動けなくなったため、 いるデータを交換します。 こで両者カ甘旨して この状態がさきはどの例と違うのは、 2 つの変数の位置 関係です。さきはどは地頁を孑一変数のはうか方にありま したが、今度は位置関係が逆転しています。こうなった ら、う第リは終了です。最後に、うリの基準とした値と、末 尾を指す変数カ甘旨している値 ( 小さいはうのグループの最 後の価とを交換し、分割処理を終了します。 次は、最悪の場午又の対処を考えましよう。効率がもっ とも悪くなるのは、分割のための値が最小値や最大値だっ たりする場合です。逆に、うリのために使う値が、対象と 介 ↑ 交換したあと、再度先頭を指す変数や末尾を指す変数 を移動します。すると、今度は次のような状態で停止し ます。 0 ■■ 00 ■ 0 0 ■■ 00 ・ 0 0 ■ 000 ・ 0 UNIX MAGAZINE 2003.6 するデータをちょうど半分に分けるような値となってい れば効率はよくなります。分割のためのデータとして、で きるかぎり、、真ん中 " に近い値を使えば、分割もうまくい くはすです。 こまでは、たんにう巨頁の値を分割のための データとしていましたが、この考えに沿ってう曰頁、中央、 末尾の 3 つの値を調べ、これらのなかで真ん中の値を使う 方法があります。この去で分割がうまくおこなえないの は、選んだ 3 つの値のうちの 2 つか最大値に近かったり、 あるいは最小値に近かったりする場合です。ですから、 のように修正すれば、最悪の場合がはとんど現れないよう にすることができます。 また、この方法を用いることで ( はんのすこしですが ) 高速化できるケースがあります。分割すべき箇所をみつけ るときには、 : 頁と末尾を指す変数の位置関係か逆転する まて処理を続けますが、その過程で、注目している酉改」の 範囲よりも外側を検査しないように値の範囲もつねにチェ ックする必要があります。しかし、 3 つの値のうち、小さ かった値を寬こ、大きかった値を末尾に配置すれば、そ れぞれの変数がこの範川より外側に出ることをチェックす る必要はなくなります。いわは、番兵の彳難リに使えるよう になるわけです。 結果をさきにいうと、この 3 要素の中間値を利用する方 法を使った場合、、け匀の手間が 2 れ 1 。れかられ 1 。 g 。れ になり、計算時間も 5 % はど改良されるといわれていま す。がんばった割には得られるものが少ないと感じるか もしれませんが、できるかぎり多くの入力に対して効率 よく測胙するようになるのですから、そこは考え方の間題 です。ただし、この改良は、、最悪の場午の対処 " にはな りますが、最悪の場合の手間を改善するものではありませ ん。いくらこの修正をおこなっても、最悪の場合の手間は 0 ( れ 2 ) である点は変わりがありません。 さらなる改良としては、挿ノはリ法との併用力挙げられ ます。クイックソートは、再平出しの最終段階ではデー タの数が 1 個や 0 個になるまで処理を続けます。データ の個数が少ないときは、さきほど紹介した挿入整列法のほ うか効率がよくなることもあります。そのため、分割した 際にデータの個数がある程度以下になったら、再隻クイツ クソートて整列するのではなく、挿入整列法を利用する方 法し尺肢に入れておきましよう。 再帰呼出しの末端の位置でつねに挿入整列法を呼び出 145

7. UNIX MAGAZINE 2003年6月号

連載 /Red Hat Linux のツールたち ー① 図 16 A4 判甬紙に印刷 [hayao@valhalla hayao] $ bj f ilter lp て -Pbj f850raw [hayao@valhalla hayao] $ ■ —model BJF850 —media plain -papersize a4 /tmp/redhat . bmp ー \ なお、 PS ファイルを印刷するスクリプト bjf850ps の なかでは、 bjfilter に —gui オプションを付けて実行す るようになっています。したがって、このオプションを 削除し、代わりに自分がよく使うオプション設定を加えれ は、印刷設定パネルを表示せすに PS ファイルを印刷でき るようになります。 ネットワーク・プリンタの場合 こまでは、 PC の USB ポートやパラレルポートに直 孑妾続されたプリンタを前提としていましたが、プリンタ にプリントサーバーを接続してネットワーク・プリンタと して使っている場合にも、 BJFiIter を用いて印刷するこ とかできます。 たとえは、 BJ-F850 にプリントサーバーを接続し、 bj というホスト名でアクセスできるように設定しているとし ましよう。この場合、 /etc/printcap. local に登録する 2 つのプリンタの言当は以下のようになります。 bj f850 て aw ICANON BJ—F850 (raw) : \ : rm=bj : rp=raw : \ : sd=/var/sp001/1pd/bjf850raw:\ : mx#O : sh : rw : \ : if=/usr/IocaI/bin/bjf850raw: bjf850psl CANON BJ-F850 / PS Fi1ter : \ : rm=bj : rp=raw : \ : sd=/var/sp001/1pd/bjf850ps : \ : mx#0 : sh : rw : \ : if=/usr/10ca1/bin/bjf850ps : PC に直接接続されている場合とは異なり、 lp パラメー タの代わりに、、 rm" と、、 rp" を使います。 rm パラメータ にはプリンタ ( プリントサーバー ) のホスト名 ( または IP アドレス ) を、 rp パラメータにはプリンタにアクセスする 際のポート名を指定します。ポート名は使用するプリント ーごとに違いますが、マニュアルなどにとくに明記 されていなけれは、適当な文字列でかまわないはすです。 あとは、スプール・ディレクトリが正しく作成されてい れは・印刷できる、 ・・はすですが、実際には印刷に失敗し てしまいます。 108 こオは、ネットワーク・プリンタでは、 USB ポートや パラレルポートに接続した場合と違ってプリンタの状態が 取得できないのが原因です。このため、ステータスモニタ カワ。リンタの監視に失敗し、そこから印刷処理か進まなく なってしまうようです。 これを角夬するには、 2 つのフィルタ・スクリプトをそ れぞれ次のように変更します。 ・ bjf850ps —lgmon オプショ bjfilter を実行している行を探し、 ンを削除してランゲージモニタとステータスモニタを起 動しないようにします。 ・ bjf850raw lgmon を実行している行を探し、 ー gui オフションを 削除してステータスモニタを起動しないようにします。 これらの変更により、ネットワーク・プリンタとして利 用している場合も印刷できるようになります。ただし、ス テータスモニタか使えないため、プリンタのエラー ( 用紙 切れなど ) を検出することはできません。 今回は BJFiIter のバージョン 1.30 を使っていますが、 より新しい機種用のバージョンでは、なんらかの角共策が とられているかもしれません。 今回は、キヤノンのインクジェット・プリンタを例に、メ ーカーが公開しているドライバを利用して Windows と 同様な感覚で印刷するガ去を紹介しました。 次回は、 EPSON ( エプソンコーワ ) が公開している Photo lmage Print System for Linux" のインストー ルと使い方について紹介する予定です。 ( よこがき・はやお ) [ 文献 ] [ 1 ] 横垣馮麪隹「 VMware Workstation 3.2 ( 3 ) ー - プリンタの 言殳定」、 UNIX MAGAZINE 2003 年 5 月号 ☆ UNIX MAGAZINE 2003.6

8. UNIX MAGAZINE 2003年6月号

821 822 823 824 連載 / IPv6 の実装ーの bzero(&spidx, sizeof (spidx) ) ; struct secpolicyindex spidx; ipsec6-getpolicybysock() 関数 もう 1 つの SPD 工ントリ検索関数である ipsec6_get- policybysock() は、ソケット経由でバケットか生成され spidx は secpolicyindex 構造イ本の変数です。 SPD ェ ントリは 833 行目の key-allocsp() 関数て検索されます。 その際の検索キーとして spidx を利用します。 ipsec—setspidx—mbuf (&spidx, 827 *error た場合に利用されます。 652 struct secpolicy * 653 ipsec6—getp01icybysock(), dir, SO, 654 655 656 657 658 { struct mbuf *m ; u_int dir; struct socket *so; 828 AF_INET6, m, (flag & IP-FORWARDING) ? 0 ipsec-setspidx-mbuf() は、 mbuf にオ内されている バケットの情報から spidx に必要な情報をコピーする関 一日立層プロトコル番号 始点 / 終点アドレス 数です。コピーされる情報は、 ・ポート番号 です。 830 831 833 834 } if sp (*error ! = 0 ) return NULL ; key—allocsp(&spidx, dir) ; ipsec-setspidx-mbuf() で正常に spidx のイ直か疋で きたら、 spidx をキーにして key-allocsp() を呼び出しま す。 key-allocsp() は、 spidx に設定された情報と dir で 指定されたバケットの流れる方向から、適切な SPD ェン トリのポインタを返す関数です。 837 if ()p ! = NULL) { ipsec6-getpolicybysock() は 4 つの引数をもちます。 m と so は SPD 工ントリの検索キーとなるバケットとソ ケットです。 dir はバケットの流れる方向で、 ipsec6-get- policybyaddr() の場合と同様、 INBOUND か OUT- BOUND のいすれかの値をとります。 error は ipsec6- getpolicybysock() で発生したエラーを通知するために 利用されます。 673 pcbsp = sot0in6pcb(so)->in6p-sp; ソケットを使って通信する場合、各ソケットに対応す る SPD 工ントリは PCB 内部に作られます。 pcbsp に、 currsp ; ー 0 ; dir) ; checkpcbcache (m , pcbsp, PCB に設定されている SPD 工ントリへのポインタを設 定します ( 673 行目 ) 。 682 683 684 685 686 = IPSec if (currsp) { 841 842 return SP , 843 } key-allocsp() で適合する SPD 工ントリがみつかった ら、その SPD 工ントリのポインタを返します。 846 847 848 849 } ip6-def—p01icy->refcnt + + ; return ip6-def—p01icy; 適切な SPD 工ントリか存在しない場合は、システム・ デフォルトとして設定されているポリシーを含む SPD ェ ントリ (ip6-def-policy) を返します。 88 ipsec-checkpcbcache() は、 PCB に設定されている SPD 工ントリカ陏効かどうかを確認します。たとえば、 UDP を使ってコネクションレスで通信する場合、バケ ット送信のたびに終点アドレスか変化する可能生がありま す。このとき、 PCB に一尉寺している SPD ェントリを出 力するバケットに対応する SPD ェントリに更新しなけ ればなりません。 ipsec-checkpcbcache() を呼び出すと、 必要に応して適切な SPD 工ントリを再検索します。な お、 TCP のようなコネクション指向プロトコルを利用す るときには、終点アドレスが変化することはありません。 この場合、一一度検索した SPD 工ントリか断売して利用さ 再検索処理は実行されません。 UNIX MAGAZINE 2003.6

9. UNIX MAGAZINE 2003年6月号

連載 / IPv6 の実装ー⑩ 図 1 SPD 工ントリのオ 554 555 556 557 if ()o = = NULL) sp = ipsec6-getp01icybysock(m, sp = ipsec6-getp01icybyaddr(m, IPSEC_DIR_OUTBOUND , IPSEC_DIR_OUTBOUND , 0 , &error) ; SO, ; と、同時にカーネル内でソケットに対応する PCB (Pro- tocol Control Block) が作られます。各 PCB には SPD 工ントリをオ褓内するための領域か確保されており、ソケッ トを使って通信するときは、 4 月号て解説した SPD 工ン トリのリストに加え、 PCB にオ内されている SPD 工ン トリも参照されます。 ューサー空間のフログラムが通信する際、通常はソケッ トを利用します。近ド爾架索 (Neighbor Discovery) の入 出力のように、カーネル内でバケットか生成される場合 や、ルータとして動作しているノードでバケットか沖幻医さ れる場合はソケットは作られません。 554 ~ 557 行目 ( 図 1 ) では、出力しようとしているパ ケットに対応する SPD 工ントリを検索します。バケット に対応するソケットがなければ、 555 行目で ipsec6-get- policybyaddr() を呼び出し、バケットに言当求されている アドレス情報などから対応する SPD 工ントリを検索し ます。ソケットが存在する場合は ipsec6-getpolicyby- sock() を呼び出し、 PCB に格納されている SPD ェン トリも検索対象とします。これらの関数についてはあとで が IPSEC-POLICY-DISCARD であれは、 トは破棄しなけれはなりません。 575 case IPSEC_POLICY_BYPASS : 576 case IPSEC_POLICY_NONE : このノヾケッ 578 579 needipsec break ・ IPSEC-POLICY-BYPASS か IPSEC-POLICY- NONE カ甘旨定されている場合、このバケットは IP セキュ リティの処理をおこなわすに出力することができます。変 数 needipsec を 0 に設疋すると、以後の ip6-output() の処理で、バケットに対する IP セキュリティ関連の処理 カ躾行されなくなります。 case IPSEC_POLICY_IPSEC : 581 582 584 585 586 587 588 if (sp->req = = NULL) { error = key—spdacquire goto freehdrs ; needipsec break; 解説します。 if (sp 559 561 562 } = NULL ) { goto freehdrs ; SPD ェントリが存在しなければバケットを破棄しま す。認証や暗号化の処理をおこなう必要がない場合でも、 IP セキュリティ処理カ坏要であることが明示されている SPD ェントリカ亟されます。 567 ~ 593 行目で、必要に応して SAD (Security As- sociation Database : セキュリティ・アソシェーション・ データベース ) 工ントリを礑呆します。 567 switch (sp->policy) { 568 case IPSEC POLICY_DISCARD : 5 73 goto freehdrs ; SPD ェントリに指定されているセキュリティ・ポリシー 78 IPSEC-POLICY-IPSEC カ甘旨定されている場合は、 IP セキュリティの処理が必要です。 IP セキュリティ処 理に必要な情報は SAD 工ントリに↑褓内されています。ま す、 582 行目で対応する SAD 工ントリが SPD 工ントリ にすでに割り当てられているかを確認し、割り当てられて いなけれは 584 行目の key-spdacquire() で SAD 工ン トリを割り当てます。そして、以後の ip6-output() の処 理で IP セキュリティ処理が実行されるように、 587 行目 で変数 needipsec を 1 に設定します。 590 case IPSEC_POLICY_ENTRUST: 591 default : 593 } IPSEC-POLICY-ENTRUST は、 IP セキュリティ の処理方法について特定の挙動を示す値ではありません。 これは、 PCB 内部に作成された SPD ェントリに設定さ れる匆月値てす。 UNIX MAGAZINE 2003.6

10. UNIX MAGAZINE 2003年6月号

JavaServer Pages 荒井美千子 カスタムタグの検査 実行時属性直の検査 先月は、 TagExtraInfo を使ってカスタムタグの属性 を検査するガ去を角見しました。そのなかで抜けていた部 分があったのて補足しておきます。 前号でも説明したように、 TagExtraInfo による属陸値 の検査は、 JSP ファイルをサープレットのコードへ変換 するときに実行されます ( 図 1 ー 1 ) 。 ところで、カスタムタグの属性が、、実行時属性 " の場 合、すなわち JSP の式タグなどで値を指定したときには ( 図 1 ー 3 ) 、 JSP ファイルを変換する時点では属性値カ鴃 まっていません。そのため、 TagExtraInfo を利用した 検査はできません。 前号て紹介した ctl:range タグの改訒版を使って、 Tag- ExtraInfo て夫彳寺属性刎直を検査しようとしたときに何 か起こるか、そしてどのような回避策があるかをみていき を満たす必要があります。 TagExtraInfo は、この牛を 期値ミ最終仙 : それぞれの属性の値は、 く ctl :range start=" 初期値” e Ⅱ d = " 最終イ直 " 、、 end" の 2 つの属生をもつカスタムタグです。 前回登場した ctl:range は、以下のように カスタムタグ ctl:range の準備 ましよう。 st art 牛を満たす場合には処理を続け、プラウザ上に、 満たすかどうかを JSP ファイルの変換時に検査します。 UNIX MAGAZINE 2003.6 [ 初期値 , 最終値 ] か表示されます。牛を満たさない場合には、属性値の誤 りを示す工ラーメッセージか表示されます。 ます、 start 属性と end 属性を夫行時属性として、 く ctl :range start=" く %= 初期値 % > ” - end=" く %= 最終値 % > ” / > のように、 JSP の式タグで属性の値を指定したときに何が 起きるかを実験してみます ( 誌面の都合上、で折り返し ています。以ー - ド同様 ) 。 最初に、夫行時属性の実験に必要なファイルを 4 つ用 意します。 ・ Range ・ java : ctl:range タグのタグハンドラ ( 図 2 ) ・ RangeTEI. java : 属性を検査するためのクラス ( 図 3 ) ・ control. tld : TLD ( タグライプラリ言当主子 ) ファイル ( 図 4 ) ・ web. xml : control. tld を参照するためのファイル ( 図 5 ) Range. java 、 RangeTEI. java 、 web. xml は前回登場 したものと同し内容ですが、 control. tld ファイルは若下 異なります。 ctl:range タグの start 属性と end 属が 実行属性として扱われるように、それぞれの属性の言 (Range. java をコンパイルしたもの ) WEB-INF/classes/control/Range. class ンのディレクトリの以下の場所に置きます。 4 つのファイルはいつものように、 JSP アプリケー く rtexprvalue>true く /rtexprvalue> に次の設定を追加しています。 91 ンヨ