match - みる会図書館


検索対象: UNIX MAGAZINE 2004年12月号
11件見つかりました。

1. UNIX MAGAZINE 2004年12月号

図 1 ホスト名が@で始まっている場合のタ歩里 if (tok [ 0 ] #ifdef NETGROUP static char *mydomain = 0 ; if (mydomain yp-get-default—domain(&mydomain) ; return (innetgr(tok + 1 , eval—hostname(host) , tcpd—warn("netgroup support is disabled") ; #else = の され、なければ NULL が返されるので、これを使って判 ます。 @がある場合はその後ろの部分が host 変数に代入 区切られているので、 split-at 関数を使ってこれを分離し #endif return (NO) ; (char * ) 0 , mydomain) ) ; / * 取 ot tcpd-jump() * / host_match 関数 次に紹介するのは、ホスト名が一致しているかどうか 断しています。 split—at(tok + 1 , ' @ ) ) ) if ( (host return (string—match (tOk , - eval-daemon(request) ) ) ; 100 ます。 が、基本的には server-match 関数と同じものとなってい host-match のどちらを用いるかといった点が異なります 求のなかから取り出す値や、比較の際に string-match と ーザー名とホスト名を書くことになります。そのため、要 を書きますが、クライアントの場合には、ホスト名のみかユ 場合には、デーモン名のみかデーモン名とホスト名の両方 クライアントの指定方法が異なるところです。サーバーの er-match 関数との違いは、設疋ファイル内でのサーバーと かを調べる client-match 関数も定義されています。 serv- サーバーではなく、クライアントが要求と一致している request—>server) ) ; & & host—match(host , - eval—daemon(request) ) return (string—match(tok, - } else { 合にのみ真を返します。 match 関数を使って両者を調べ、両方とも一致している場 ため、 string-match 関数とホスト名の一致を調べる host- 両方が一致するかどうかを調べなければなりません。その ホスト名も含まれる場合には、ホスト名とデーモン名の 結果を返します。 関数を呼び出して文字列がデーモン名と一致するかを調べ、 求のなかからデーモン名の部分を取り出し、 string-match デーモン名だけの場合には、 eval-daemon マクロで要 を調べる host-match 関数です。この関数は、調べるホ スト名を表す文字列と、要求のなかでホストを示すための host-info 構造体へのポインタを引数にとります。 static int host—match(tok, host) char *tOk ; struct host_info *host ; 関数の本体は、設定ファイルに書かれた文字列の種類に よって場合分けをしながら、ホスト名が一 - 一致しているかを 順番に調べる構造になっています。最初はホスト名が@で 始まっている場合です。この場合には、指定されたホスト が NIS のネットグループに含まれているかどうかを調べま す ( 図 1 ) 。 ネットグループの機能を使うかどうかはマクロで制御で きるようになっていますが、この機能を使う場合には、 yp- get-default-domain 関数により NIS のドメイン名を取 得し、さらに innetgr ライプラリ関数を利用して、指定さ れたホストがネットグループに含まれているかどうかを調 べます。ネットグループの機能を使わない設定になってい る場合には、 NO を返して関数を終了します。 ホスト名の部分が、、 / " で始まる場合、実際の指定は別の ファイルに言当されていることを示します。 } else if (tokCO] return (hostfile—match(tok, host) ) ; この場合には、 hostfile-match 関数を呼び出してファ イルの中身との一致を調べます。 hostfile-match 関数は、 ファイルをオープンし、その各行ごとに host-match 関数 を呼び出すことで、ファイルの中身をすべて調べます。 ホスト名として KNOWN が指定されていれば、ホスト UN 工 X MAGAZINE 2004. 12

2. UNIX MAGAZINE 2004年12月号

for 文の本体を実行します。設疋ファイルでは、サーバー などの仕様を複数並べてできるので、 こでは 1 つの 仕様をそれぞれチェックすることになります。 for 文の本体では、ます先頭のトークンが EXCEPT で はないことを確認しています。 EXCEPT であれは構文と して誤りなので、この場合にはマッチしなかったことを示 す NO という値を返します。 if (STR_EQ(tok, "EXCEPT") ) return (NO) ; 先頭が EXCEPT でなければ、みつけたトークンを第 3 引数で指定された関数に渡し、要求と一致しているかを調 べます。 if (match—fn(tok, request) ) { この関数が真となるのはトークンと要求が一致している ときなので、この場合には EXCEPT トークンがみつかる か、すべての文字列を処理するまでトークンを読み飛ばし ます。 while ((tok = strtok((char * ) 0 , sep)) & & STR_NE (tok , "EXCEPT" ) ) / * VOID * / ここに到達したときに t 。 k が 0 になるのは、すべての文 字列の処理が終った場合なので、関数として真を返します。 一方、 EXCEPT がみつかったために while ループを 抜けるときには、 list-match 関数を再帰的に呼び出して、 EXCEPT 以下の部分が - ー - ・致するかどうかを調べます。 致する場合には全体を偽とし、一致しない場合には全体を 真としなければならないので、一致していない ( 関数が 0 を返した ) ときに自分自身は真を返せるような式となって います。 return (tOk 0 Ⅱ list-match((char * ) 0 , 疇 - request , match—fn) また、最初の for 文ですべてを処理してしまった場合な どは、一致しなかったと判断しなければなりません。その ため、関数の値としては NO を返しています。 再帰呼出しの際には、第 1 引数に文字列を指定していな い点に注意してください。なんとなくおかしな気がします が、これはなかなかよくできています。第 1 引数に NULL が指定された状態で呼び出されると、最初の for 文の実行時 にも直前の strtok 関数呼出しの場所の次の場所からトー UN 工 X MAGAZINE 2004. 12 プログラミング・テクニック : 99 server_match 関数 調べます。後者の場合はデーモン名とホスト名が、、@" で か、デーモン名とホスト名の両方が指定されているのかを この関数では、まずデーモン名だけが指定されているの struct request—info *request ; *tok; char static int server—match(tok, request) を表す request-info 構造体へのポインタを指定します。 マッチを検査する文字列が第 1 引数で、第 2 引数には要求 引数は、 list-match 関数から呼び出される形式と同様、 とマッチするかを検査するためのものです。 の関数は、文字列をサーバーに関する言とみなし、要求 すときに引数として渡される server-match 関数です。 次は、 table-match 関数から list-match 関数を呼び出 利用していても問題は発生しません。 イプラリ側 ) で保持できるため、別の場所で同様な関数を 合も、途中の状態をプログラム側 ( この場合は libwrap ラ をもつ strsep 関数も利用できます。いすれを利用した場 出しのインターフェイスは若干異なりますが、同様の機能 第 3 引数として受度しするようになっています。また、呼 関数です。この関数は再入可能とするために、文脈情報を これを解決するのが、 strtok 関数とよく似た strtok-r べきです。 tok 関数のように状態をもつ関数は呼び出さないようにす 作するはずがありません。ライプラリ関数のなかでは、 str- うに変更されてしまうかもしれません。これでは正しく動 strtok 関数の呼出しによって、ほかの文写冽に注目するよ した文字列からトークンを切り出すつもりでいても、別の すると、何カ起こるでしよう。プログラムでは自分の指定 ラムのソースコードでも strtok 関数を呼び出していたと ません。たとえば、このライプラリ関数を利用するプログ 関数のなかで strtok のような関数を使うのはお勧めでき こで提供しているのはライプラリ関数です。ライプラリ ラリとして流用しているために生じる問題点があります。 この関数には、 TCP Wrappers 用のコードをライプ 図どおりの動作をすることになります。 クンを切り出した次の場所のトークンを切り出すので、意 クンを切り出すことになります。つまり、 EXCEPT トー

3. UNIX MAGAZINE 2004年12月号

0 プロクラミンク・テクニック 多治見寿和 TCP Wrappers ( 6 ) 前回は、 libwrap ライプラリ関数のソースコードをみま した。といっても、 libwr 叩専用に作られたソースコード は 1 つしかなく、実際には tcp-wrappers ディレクトリに 置かれたものを流用しています。そのなかから、処理のメ イン部分である hosts-access 関数と、 table-match 関数 を紹介しました。 これらの関数をみれば、ライプラリ関数としての動作の 概要は分かります。しかし、サービスの要求が設定ファイ ルに指定された条件と一致しているかを判定する方法はよ く分かりません。今回は、このあたりをみていきましよう。 ますは list-match 関数です。この関数は、設疋ファイ ル中のリストの記述に含まれる EXCEPT の処理をおこ なうためのものです。 EXCEPT 演算子については 7 月 号でも紹介しましたが、たとえば、、リスト IEXCEPT リ スト 2 " とした場合、リスト 1 に一致し、かっリスト 2 に 一致しないものとマッチします。また、 EXCEPT は右結 合の演算子で、、、リスト 1 EXCEPT リスト 2 EXCEPT リスト 3 " は、、リスト 1 EXCEPT ( リスト 2 EXCEPT リスト 3 ) " と解釈されます。 list-match 関数は hosts-access. c ファイル ( 前回紹介 した table-match 関数の直後 ) で定義されています。 の関数は 3 つの引数をとります。第 1 引数には、設定ファ イル中の一致を検査したい文字列を指定します。第 2 引数 にはサービス要求の詳細を示す request-info 構造体への ポインタを、第 3 引数には一致を検査するための関数を指 定します。 list match 関数 98 static int list—match(list , request , match—fn) char *list; struct request—info *request ; (*match-fn) ( ) ; int 関数自身が static と亘言されているのは、この関数は前 回紹介した hosts-access 関数経由で呼び出され、ほかか ら直接呼び出されることはないためです。 この関数の内容をみる前に、重要な彳齬リを果たす strtok 関数の動作をおさらいしておきましよう。 strtok 関数は、 文字列をトークン化するための関数です。第 1 引数に渡さ れた文字列の頁から、第 2 引数に指定された文字列に含 まれる文字を探します。文字がみつかれば、その直前まで を文字列として返します。 このライプラリ関数は状態をもつ珍しい関数です。最初 に第 1 引数として文字列を渡すと、 2 回目からは第 1 引数 を NULL として呼び出すことで、同じ文字列のまだトー クン化していない部分から新たにトークンを切り出します。 つまり、最初の呼出しでは第 1 引数に文字列を指定し、 2 回目以降は NULL を指定して呼び出すことで、文字列の すべてのトークンを切り出せるわけです。文字列にトーク ンカっていないときには関数が NULL を返すので、す べてを処理したかどうかを判断することができます。 それでは list-match 関数のソースコードをみていきま しよう。関数の本体は for 文となっており、 strtok 関数を 使ってすべてのトークンを処理する典型的なコードといえ ます ( 誌面の都合上、で折り返しています。以下同様 ) 。 for (tok = strtok(list, sep) ; tok ! = 0 ; , ・ tok = strtok((char * ) 0 , sep)) { 引数として渡された list 変数ロ内されている文字列か らトークンを切り出しながら、すべてのトークンについて UNIX MAGAZ 工 NE 2004. 12

4. UNIX MAGAZINE 2004年12月号

図 2 指定された文字列がホストのアドレスもしくはホスト名と一致するかを調べる } else { / * anything else * / return (string—match (tOk , eval—hostaddr (host) ) Ⅱ (NOT_INADDR(tok) & & string_match(tok, eval_hostname(host) ) ) ) ; 図 3 IPv4 身彡 IPv6 アドレスの IPv4 アドレスへの変換 #ifdef INET6 / * convert IPv4 mapped IPv6 address to IPv4 address * / if (STRN_EQ(string, & & dot—quad—addr(string + 7 ) ! = INADDR_NONE) { string 十 = 7 ; #endif なくホスト名と一致するかを調べます ( 図 2 ) 。 図では、指定された文字列がアドレス形式でないことを 確認するために NOT-INADDR マクロを使っています。 このマクロは tcpd. h ファイルで次のように定義されてい ます。 #define NOT-INADDR(s) (s [strspn(s , , " 01234567890. / " ) ] ! = 0 ) strspn 関数は、第 1 引数に指定された文字列の頁から、 第 2 引数に指定された文字列に含まれる文字のみで構成さ れる部分文字列を取り出し、その長さを返す関数です。っ まり、第 1 引数の何文字目までが第 2 引数に含まれている かを返します。この値を文字列の添字として使うと、第 2 引数に含まれていない先頭の文字を参照することになりま す。これがヌル文字であれば、文字列全体が第 2 引数に含 まれることになるので、数字とドットとスラッシュのみで 構成された文字列だということが分かります。つまり、ア ドレスを表す文字列であると判断しているわけです。 最後は、文字列比較をおこなう string-match 関数です。 たんに文字列を比較するだけなら簡単ですが、実際には特 殊なキーワードの処理もおこなうためにやや複雑なものと なっています。 引数は 2 つで、どちらも文字列です。ただし、第 1 引数 は設定ファイルに杢された文字列で、第 2 引数が要求か ら生成した文字列となります。 static int string—match(tok, string) Char *tok; char *string; string match 関数 102 関数の本体では、まず IPv4 射影 IPv6 アドレスを通常 の IPv4 アドレスに変換しています ( 図 3 ) 。 先頭が、、 : : 仕仕 : " のアドレスは IPv4 射影 IPv6 アドレス です。この場合、後続の部分が IPv4 アドレス形式である ことを確認して、頁部分を取り去ります。 次は、指定された形式にもとづいて処理を変える部分で す。まずは、ドットで始まる文字列が指定された場合です。 この場合はドメイン名の一部が指定されたとみなし、要求 のホスト名の末尾部分と一致するかを検査します。 if (tokCO] strlen(string) strlen(tok) ; return (n > 0 & & STR-EQ(tok, string + Ⅱ ) ) ; そのため、まず要求から得た文字列の長さが指定された 文字列よりも長いことを確認し、文字列の後ろの部分と比 較します。 指定された文字列が ALL ならすべてのものに一致する ことになるため、かならず YES を返します。 } else if (STR-EQ(tok, "ALL")) { return (YES) ; 指定された文字列が KNOWN の場合、 UNKNOWN でなければ一致します。このためのコードもいたって簡単 です。 } else if (STR—EQ(tok, "KNOWN")) { return (STR-NE(string, unknown) ) ; 指定された文字列の末尾がドットの場合、前方から調べ ー 1 ] return (STRN_EQ(tok, string, Ⅱ ) ) ; / * prefix * / } else if (tok[(n = strlen(tok)) てそこまでが一 -- ・致していれば OK です。 UNIX MAGAZ 工 NE 2004. 12

5. UNIX MAGAZINE 2004年12月号

名とアドレスの両方が判明した場合に一致したとみなされ ます。 } else if (STR-EQ(tok, "KNOWN")) { eval—hostname (host) ; char return (STR—NE(eva1_hostaddr (host) , 疇 - unknown) & & HOSTNAME—KNOWN (name) ) ; そのため、まず eval-hostname 関数でホスト名を取り 出し、あとで HOSTNAME-KNOWN マクロを使って これが UNKNOWN や PARANOID でないことを確認 します。アドレスについては、 eval-hostaddr 関数を使っ てアドレスを取り出し、それが UNKNOWN ではないこ とを確認します。どちらの条件も満たしたときに、関数は 真を返すことになります。 設疋ファイルに言古生されたホスト名が LOCAL の場合、 ローカル・ネットワークに接続されたホストかどうかを検 査します。 } else if (STR-EQ(tok, "LOCAL")) { eval—hostname (host) ; char *name まない名前カ陬得できたものが、ローカル・ネットワークに 実際には、ホスト名を取得したときに HOSTNAME_KNOWN (name) ) ; return (strchr (name , " ( ドット ) を含 トワーク・アドレスとマスクの組であると解釈します。 指定のなかに、、 / " ( スラッシュ ) が含まれる場合は、ネッ KNOWN などになっていないことを確認しています。 接続されたホストであると判定します。この場合も、 UN- ためにたいへん複雑なものとなっていますが、 IPv4 アド masked-match 関数は、 IPv6 アドレスにも対応する どうかを調べます。 マスクの組に要求のなかのホストのアドレスが含まれるか このとき、 masked-match 関数を使って、 eval—hostaddr (host) ) ) ; return (masked—match(tok , mask , , } else if ((mask = split-at(tok, ) / , ) ) アドレスと UNIX MAGAZINE 2004. 12 列がホストのアドレスと一致する、またはアドレス形式で こまでに説明した以外のケースでは、指定された文字 たネットワークと等しいことを確認するだけです。 スとマスクのビットごとの論理積をとったものが指定され ク、マスクを unsigned long 形式の値になおし、アドレ レスだけであれば処理は簡単です。アドレスやネットワー SC 翡 好評発売中 ! プログラミング テクニック プログラミング テクニック リ N Ⅸコマンドのソースコードにみる inetd 、多見を和 ( 物し 践プログラミング手法 9 。 : 牆ぃ 第れて・たソフトア にな工第といった ー 0 ー ne ーあります . そこには . プ 0 ツム第をに・第な強物がど っさりと・り・物ていま第 YXC vipw ASCII ・多治見寿和著 ・ B5 判、 240 ページ ・ ISBN 4-7561-4389- X ・ 1 , 890 円 ( 税込み ) 生きたプログラムから学ぶ 実践的手法の数々 フリーの UNIX やアプリケーションのソース コードを見ながら、プログラミングにおけ る " 名匠の技 " を学ばうというのが本書の 目的です。長い年月をかけ、多くの人の手 ですこしすっ改良されてきたソフトウェア は洗練の度合いを増し、名匠の手になる工 芸品といった趣があります。そこには、プ ログラム開発に必要な技術がどっさりと盛 り込まれています。 目次から ( 本書より ) ソースコードから学ぶ◆テータ構造◆ 2 重リンクリ スト◆木構造◆ AVL 木◆ハッシュ◆端末の操作◆端 末の制御◆ cat コマンド◆コマンド◆ファイ丿レの ロック◆パスワード・ファイル◆ワンタイム・パスワ ード◆公開鍵暗号◆ Secu 「 e She Ⅱ◆構文の解析◆ yacc ◆ lex ◆ ping ◆ telnet ◆ ftp ◆ inetd ◆ xst 「◆ 電話 (03) 6888 ー 5500 ( 営業局 ) 東京都千代田区九段北ト 1 3-5 日本地所第一ビル 〒 1 02 ー 8584 株式会社アスキー (UNIX MAGAZINE 1 997 年 1 1 月号 ~ 2000 年 3 月号より ) cmp と cksum ◆ man ◆フィ丿レタコマンド 101

6. UNIX MAGAZINE 2004年12月号

集 Open Cygwin WindowHere root = Registry. LocaIMachine ; rk = root . OpenSubKey (SHELL-EX-APPROVED-REG-KEY , true) ; rk. SetVa1ue(guid. ToString() , "F01derBackgroundRunCmd shell extension") ; rk. C10se() ; / / Set D 工 RGB-CONTEXT_MENU_EX_REG_KEY to my guid root = Registry. C1assesR00t ; rk = て 00t . CreateSubKey (DIRBG—CONTEXT-MENU—EX_REG_KEY) ; rk. SetVa1ue('"' , guid. ToString() ) ; rk . C10se() ; catch ( Exception e ) { MessageBox. Show(e . ToString()) ; [System. Runtime . InteropServices . ComUnregisterFunctionAttribute ( ) ] static void UnregisterServer(String strl) try { RegistryKey て 00t ; RegistryKey rk; て 00t = Registry. LocaIMachine ; rk = root . OpenSubKey(SHELL—EX-APPROVED_REG_KEY , true) ; rk. DeIeteVaIue (guid) ; rk. C10se() ; root = Registry. C1assesR00t ; root . De1eteSubKey (DIRBG-CONTEXT—MENU_EX_REG_KEY) ; catch ( Exception e ) { MessageBox. Show(e . TOString() ) ; 1 「 - 1 工エー - 97 UNIX MAGAZ 工 NE 2004. 12

7. UNIX MAGAZINE 2004年12月号

if ( str ! = Ⅱ u11 ) { if ( str. Length > = cchMax ) { str = str. Substring(), cchMax str 十 " \ 0 " ・ str charArray = str. ToCharArray ( ) ; Marsha1. Copy (charArray , 0 , commandString , private VOid ExecuteCommand (string command) StartupInfo si = new StartupInfo ( ) ; charArray. Length) ; ProcessInformation pi = new ProcessInformation() ; si . cb = 68 ; //sizeof(si); try { if ( ! CreateProcess ( Ⅱ u11 , command. Rep1ace("%L" , f01derPath) , false, 0 , 0 , f01derPath. Substring(), 2 ) , MessageBox. Show("UnabIe t0 execute " 十 command 十 ” : E て ro て in F01derBackgroundRunCmd" ) ; catch ( Exception e ) { MessageBox. Show(e . ToString() ) ; void IContextMenu. InvokeCommand(IntPtr pici) try { 0 , 0 , si, pi) Type typINVOKECOMMANDINFO = Type. GetType ( "She11Ext . INVOKECOMMAND 工 NFO" ) ; INVOKECOMMANDINFO ici (INVOKECOMMANDINFO)Marsha1. PtrToStructure (pici , typINVOKECOMMANDINFO) ; if ( ici . verb く = m—items. Length ) ExecuteCommand(m—items [ici. verb ー 1 ] . Command) ; catch(Exception e) { MessageBox. Show(). TOString()) ; [System. Runtime. InteropServices. ComRegisterFunctionAttribute()] static void RegisterServer(String strl) try { RegistryKey root ; RegistryKey rk ; root = Registry. CurrentUser; 96 UNIX MAGAZINE 2004. 12

8. UNIX MAGAZINE 2004年12月号

Hummingbi 「 d 期 ndo Ⅳ s と UN ー つなぐなら 書を ( を ) 讐き努簽うラ 日洋をス、ノ ). ( ユム : 型 : ム・ ト ~ ツ朝・・をれイ当ト三を リを ◆ S れ ノ朝れ′ 1 ′わをソ尹 ~ ネッ第ワー々 アカデミック版 値下げしました ! 世界シェアⅣ 0 PCX サー/ゞ \ 19 , 740 ( 税込 ) 他の追處を許さない世界シェアⅣ 0.1 の実績高速描画、高い安定性に加え、日本語スカサホートも万全新たに c e S わ e 〃接続、 p Ⅳ刑 T 環境への対応強化コ Pv6 サホート、ライセンス資産管理 & レホーティンク機能を搭載しました 価格 . \ 81 900 ( 税込 ) Windows 98/Me/NT4.0/2000/XP/Windows server 2003 対応※ IIDC Reserch March, 2000 〈 NFS V4 文寸応〉 Windows 98/Me/NT4. O/2000/XP/Windows server 2003 対応 NFS Maestro Client V9. OJ 価格・ Y56 , 700 ( 税込 ) 体験版のお申込はこちらから 1 第 networkS http://www-macnica.net/hummingbird/ マクニカネットワークス株式会社〒 222-8562 横浜市港北区新横浜 1 -5-5 本社 045-476-1960 大阪営業所 06-6300-0825 ERéed V9.0

9. UNIX MAGAZINE 2004年12月号

集 Open Cygmn WindowHere m . Text = menuStr ; 1 , m . Command m. He1pText m—items [i] cmdStr ; menuStr. Rep1ace("&" m ; catch( Exception e ) { MessageBox. Show(e . TOString() ) ; else { m_items return 0 ; int new MenuItem [ 0 ] ; IContextMenu. QueryContextMenu (uint hMenu , uint iMenu , int idCmdFirst , if ( m—items . Length int id = 1 ; if ( (uF1ags & 0xf) MENUITEMINFO mii mii . CbSize mii . fMask int idCmdLast , uint uF1ags) 0 ) return 1 ; 0 Ⅱ (uF1ags & (uint) CMF. CMF_EXPLORE) ! = new MENUITEMINFO ( ) ; = 48 ; (uint)MIIM . ID ー (uint)MIIM . TYPE ー (uint)MIIM . STATE; = の { foreach ( MenuItem item in m—items ) { mii . 工 D mii . fType idCmdFirst + id ; (uint)MF. STRING ; mii . dwTypeData item. Text ; (uint) MF . ENABLED ; mii . fState InsertMenu 工 tem (hMenu , iMenu + (uint) id , id 十十・ return id ; VOid ref mii) ; IContextMenu. GetCommandString (int idCmd, uint uF1ags , int pwReserved , String str; Char ロ charArray ; switch ( uF1ags ) { case (uint)GCS . VERBW: str = m—items CidCmd break ; case (uint) GCS . HELPTEXTW : m—items CidCmd str UNIX MAGAZ 工 NE 2004. 12 break; str = nu11 ; default : break; IntPtr commandString , int cchMax) 1 ] . Command ; 1 ] . He1pText ; 95

10. UNIX MAGAZINE 2004年12月号

この場合には文字列の長さを調べ、その長さだけ要求か ら得た文字列と比較します。 これら以外の場合には文字列としての正確な一致を調べ ますが、 IPv6 アドレスの可能性もあるため、まずはそち らを確認します。 IPv6 アドレスであれは全体が、、「と ] で括られているはすなので、まずはそのような形式になっ ているかどうかを調べます。 strlen(tok) ; len ' [ ' & & tok[len ー 1 ] if (*tok この条件が成立する場合、設疋ファイルで指定されてい る文字列は IPv6 アドレスのはずです。アドレスとしての 構造が正しいかを確認するために、 getaddrinfo ライプラ tok[len ー 1 ] ch ; freeaddrinfo(res) ; memcpy(&pat , res->ai—addr, sizeof (pat) ) ; &res)) if ( (ret = getaddrinfo(tok + 1 , NULL, &hints , hints. ai—flags = AI-PASSIVE ー AI—NUMERICHOST; hints . ai—socktype SOCK_STREAM ; hints . ai-family = AF—INET6; memset (&hints , 0 , sizeof (hints) ) ; tok C1en ー 1 ] ch = tok[len ー 1 ] ; リ関数を使ってアドレスをバイナリ形式に変換します。 UNIX MAGAZ 工 NE 2004. 12 ていることを確認しています。 れていたら、それが要求のほうのアドレスにも同様に付い 設疋ファイルから得たアドレスにスコーフ。識別子がイ寸けら これらも等しいことを確認する必要があります。そこで、 スコーフ。識別子を用いる場合には、アドレスだけでなく addr にオ内されます。 れていたアドレスが pat に、要求から得られたアドレスが アドレス変換が成功した場合には、設疋ファイルに書か freeaddrinfo(res) ; memcpy(&addr, res¯>ai—addr, sizeof (addr) ) ; return NO ; &hints, &res) ! = 0 ) if (ret ! = 0 Ⅱ getaddrinfo(string, NULL, - 致しないことを示します。 らかの getaddrinfo が失敗した場合には NO を返し、 イナリ形式の IPv6 アドレスに変換します。ここで、どち さらに、要求から得られた文字列についても、同様にバ プログラミング・テクニック : #ifdef NI_WITHSCOPEID return NO ; pat . sin6-scope-id) addr. sin6—scope—id ! = - if (pat . sin6-scope-id ! = 0 & & #endif &addr . sin6—addr , return ( ! memcmp (&pat . sin6—addr , , し、値カ賻しいかどうかを返します。 あとは、バイナリ形式となっているアドレスを直接比較 ことを示します。 スコーオ嬲リ子が異なる場合は NO を返し、一致しない in6-addr)) ) ; sizeof (struct 。 # , #endif return (ret) ; return (STR-EQ (tok, string) ) ; どうしの比較をおこない、一致するかどうかを判断します。 IPv6 アドレス形式でなかった場合には、単純に文字列 ☆ いずれ TCP Wrappers でも strsep 関数を使うように変 ルには strsep 関数を利用すべきと明記されていますから、 ある実装です。ただ、 strtok 関数のオンライン・マニュア イプラリとして利用することを考えると、ちょっと問題の 把握していれば、問題にはならないからです。しかし、ラ ードのほかの部分で strtok 関数を使っているかどうかを はありません。というのも、 TCP Wrappers の作者がコ Wrappers のソースコードとして考えるのならとくに支障 では strtok 関数をそのまま使っています。これは、 TCP 「 list-match 関数」の節で述べたように、ソースコード る関数群を紹介しました。 れた条件にマッチしているかどうかを検査する際に利用す 今回は、サービスに関する要求カ羸疋ファイルに指定さ 更されるのでしよう。 103 ( たじみ・ひさかず )