連載 / Pe 日活用のヒント Web サイトの内容を管理しているサーバー 図 4 sync-n-putjs. pl びメ吏用例 END JavaScript insersion by sync_n_nputj s ・ pl く /noscript> く img border="O" width="l" hight="l" src="http://usage-tracking ・ jp/t . gif?js=no"> く noscript> く script 1anguage="JavaScript" src="/usage—tracking. js"> く /script> BEGIN JavaScript insersion by sync-n-nputjs ・ pl 図 3 sync-n-putjs. pl が HTML ファイルに埋め込む内容 内容制作のための 領域。アクセス統計 の仕組みは含まれて いない sync—n—putjs ・可 く img border="0" width="l" hight= く noscript> sync—n-putJs . pl [-verbose] 図 5 sync-n-putjs. pl の く /noscript> src="http://usage-tracking ・ jp/t ・ gif?js=no"> 本サーバーへ 本番の環境で使われる ファイルの領域。アクセ ス統計のための加工を おこなっている SRCDIR DSTDIR というわけで、 sync-n-putjs. pl が HTML ファイルの 末尾に埋め込む内容は図 3 のようになる。 いくつかの企業が、上記の仕組みで Web サイトのアク セス統言 t サービスを提供している。企業のサービスを利用 せず、自分でアクセス統計をとる場合でも一考に価する手 法だと思う。 sync-n-putjs. pl を使う理由 こうしたアクセス統言 t の手法があるとして、なぜ sync- n-putjs. pl のようなプログラムが必要なのだろうか。それ は、アクセス統言 t の仕組みとは無関係にページを制作でき るからである。 はじめは Web サーバーのアクセスログを処理してアク セス統言 t をとっていたが、その後アクセス統言 t サービス A を使い始め、さらにサービス B に乗り換えた、というのは ありそうな話である。しかし、 Web ページを制作する側と しては、アクセス統言 t の仕組みとは無関係に仕事をしたい。 そのためには、 sync-n-putjs. pl のようなプログラムを 使い、制作した HTML ファイルから実際に Web サーバー に置くファイルを生成すればよい ( 図 4 ) 。このようにすれ 80 ば、アクセス統引・方法を変更する際に埋め込む謎を修正 する手間が減る。 sync-n-putjs. pl の乍 sync-n-putjs. pl の具体的な使い途が分かったところ で、その動作を詳しく説明しよう。 コマンド行の書式は図 5 のとおりである。 S C. 〃 / がミラー元ディレクトリ、 DSTDIR がミ ラー先ディレクトリである。 -verbose オプションを付 けると、より詳しいメッセージが出力されるようになる。 -norecurse オプションを付けると、 SRCDIR の直下の ファイルのみをミラーする。 動作の基本はミラー元をミラー先に階層的にコピーする ことで、扱うのは普通のファイル、ディレクトリ、シンポ リック・リンクである。それ以外のデバイスファイルなど は無視し、ハードリンクは考慮しない。ミラー元で 1 つの ファイルがハードリンクによる 2 つのパスをもっている場 ミラー先では別のファイルになる。 前述のように、 HTML ファイル ( 具体的には名前の末 尾が . html または . htm のファイル ) については、コピー したうえでファイルの最後にアクセス統言 t のための言当を 挿入する。挿入する位置は </body 〉タグの前である。 UN 工 X MAGAZ 工 NE 2004.5
連載 / PerI 活用のヒント ファイルをコピーするかどうかは、ファイルの最終更 のマシンからのミラーまたは別のマシンへのミラーである。 新日時 ( タイムスタンプ ) のみで判断している。最終更新 しかし、同じマシンの特定のディレクトリから別のディレ 日時が異なっていればコピーし、同じならコピーしない。 クトリにミラーすることもできる , 、。。を一、オプシ付きは実行すれば、ピーした HTML ファイルの場合はかならずミラー元と大きさが違 うので、コピーするかどうかは最終更新日時をもとに判断 ファイルのノヾスが標準出力に出力される。出力はそれだけ するしかない。このため、ファイルをコピーしたときは、最 ではないが、コピーされたファイルのパス名だけを判別す 終更新日時がミラー元と同じになるようにしている。 るのはそれほと難しくなさそうだ。 sync-n-putjs. pl を実 ミラー元で削除されたファイルやディレクトリ、シンボ 装するとしたら、 rsync でコピーされたファイルについて、 リック・リンクはミラー先でも削除される。名前の末尾が それが HTML ファイルの場合はアクセス統言 t のための変 以下のいずれか ( 大文字 / 小文字は無関係 ) のファイル、デ 更を加えるという方法が考えられる。 ィレクトリ、シンポリック・リンクはコピーされない。 HTML ファイルはすべてミラー元とは異なるので、普 通に rsync を使うと毎回すべての HTML ファイルがコ ・ org ・ orlg ピーしなおされ、アクセス統言のための変更が加えられる また、名前が rcs ( こちらも大文字 / 小文字は無関係 ) の ことになる。これでは効率カい。しかし、一 u オプション ファイル、ディレクトリ、シンポリック・リンクもコピーさ を与えて rsync を実行すると、ミラー先のファイルのほう れない。これらは一時ファイルや RCSI のファイル、ディ カ噺しい場合は更新されない。したがって、 rsync を使っ レクトリであり、コピーする必要はないはずだからである。 て sync-n-putjs. pl を実装することは可能である。 File: : ファイルとディレクトリのモードや所有者、グループな SyncNMod を使用する場合とくらべても劣る点はほとん どの属性は、ミラー元とミラー先が極力同じになるように どない。強いて挙げるなら、 sync-n-putjs ・ pl が rsync に する。 root はディレクトリとファイルの属性を自由に設疋 依存するので、このコマンドがないと動作しなくなる。ま できるが、一ヨ殳ユーザーには制限があるので、、極力 " なので ー v オプションを付けた rsync の出力フォーマットは ある。なお、属性のみカ畯わって最終更新日時に変化がな 厳密に定義されているわけではないので、将来形式カ畯わ くてもミラー先に反映される。 り、 sync-n-putjs ・ pl に変更の必要が生じる可能性がある。 sync-n-putjs. pl と File: :SyncNM0d は UNIX を念 頭に書いたものだが、 Cygwin の Perl や Windows の rdist ActivePerI でも問題なく動作するようだ。ショートカッ rdist の r も remote の r だが、配布先マシンを 10Ca1 ー トも Cygwin の Perl や ActivePerl でミラーされる。た host にすることで、同一マシン内でのミラーに使うことか だし、パスの区切り文字を、、 / " にしているので、これカ源 できる。 因でコピーできないことがあるだろう。 rdist は DistfiIe をもとに動作する。 DistfiIe にはど のディレクトリをどのマシンのどのディレクトリにミラー File: :SyncNMod を使う理由 するかといった情報を静的に記述する。 Web サイトの運 用ではサイト内のさまざまな部分を更新することがあるの sync-n-putjs. pl の実装には、既存のコマンドやモジュ で、 sync-n-putjs. pl は任意のサプディレクトリに対して ールを利用することも考えられる。以下、使えそうなコマ 動作してほしい。これに関しては、 DistfiIe 自体を動的に ンドやモジュールについて述べる。 生成することで対処できる。生成される DistfiIe は図 6 rsync のようになる。これは、 /dl/stage/htdoc/about から ディレクトリをミラーするためのコマンドに rsync があ /dl/prod/htdoc/about ヘミラーする場合の例である。 special の行では、コピー後に実行されるコマンド em- る。 rsync の r は remote の r なので、本来の使い方は別 bed-usage-tracker が指定されている。コマンド行引数 1 Revision Control Systemo UNIX 用のファイル・ノヾージョン艝理 である $REMFILE は、コピー先のパス名に置き換えられ ソフトウェアの 1 つ。 81 UNIX MAGAZINE 2004.5
0 Pe 日活用のヒント 今聿英世 FiIe::SyncNMod ティレクトリの内容をミラーする 今回は、ディレクトリの内容を別のディレクトリにミラ ーするためのモジュール File::SyncNMod と、それを使っ たサンプル・プログラム sync_n-putjs. pl を紹介する。 ミラーする " という言葉を、、更新されているもの こでは、 だけを階層的にコピーする " という未で使っている。 sync-n-putjs. pl は、基本的にはディレクトリの内容を 別のディレクトリにミラーするプログラムだが、 HTML ファイルをコピーする際はその末尾に一定の JavaScript を挿入する。 File: :SyncNMod の SyncNMod は、、 Syn- chronize aNd Modify" という意未で、 sync-n-putjs. pl のように一部のファイルに変更を加えたうえでミラーする プログラムを作れるようになっている。 ディレクトリをミラーする際は、細かな点まで気を配 ってファイルを扱わなければならない。 File::SyncNMod について理解を深めれば、ファイルやディレクトリ、シン ボリック・リンクの細かな処理を Perl でどのようにおこ なうかが分かるだろう。 この連載でとりあげるプログラムは私が一 -- ・から書いたも のであり、連載のこれまでのぶんも含めて以下の URL で 公開している。 ・ http://www.geocities.c0.jp/SiliconValley-Oakland / 4080 / プログラムの配布ファイルのなかには、日本語マニュア ル (POD ファイル ) が含まれている。対象とする perl の バージョンは、 UNIX の Perl 5.6 / 5.8 、 Windows の Ac- tivePerl 5.8 と Cygwin の Perl 5.8 である。 こでは、 各種の Linux 、 BSD 、 SoIaris などの商用 UNIX をす べてまとめて UNIX と呼んでいる。記事中に示す操作は UNIX のコマンド行でのものだが、 Windows 上の Cyg- 78 win でもほば同じ操作がおこなえる。ただし、 Windows の ActivePerl は Cygwin のアプリケーションではない ので、若干の注意カ必要である。 sync-n-putjs. pl の用途 sync-n-putjs. pl の具体的な使い途は、 Web ページのア クセス統言 t をとる仕掛けを HTML ファイルに埋め込むこ とである。まず、その仕掛けについて説明しよう。 JavaScript によるアクセス統計 基本的なアイデアは、 Web ページにアクセス統引・のため の画像を埋め込む、つまりアクセス糸 t 用の IMG タグを 付けるというものである。こうすることにより、ページが 読み込まれるたびに画像に対するアクセスが発生し、ペー ジ本体を提供する Web サーバーとは別の Web サーバー でページ閲覧を観測できる ( 図 1 ) 。これは画像によるべー ジカウンタと似ている。ページカウンタは自分がアクセス された回数を保持していて、それに応じた数字を画像とし て出力する。 同様のことは、上記の方法以外にも、ハ IG タグを作り だす JavaScript を埋め込むことでも実現できる。これは JavaScript を HTML ファイルに直接書き込むのではな く、 JavaScript のファイルを <script src= . ”〉で参 照するようにしてもよい。 たとえば、内容を保持している web サーバーのドキュ メント・ルート (document root) に、図 2 に小す usage- tracking. js があるとしよう。この JavaScript は以下の タグを作成する ( 誌面の都合上、で折り返しています。 以下同様 ) 。 UN 工 X MAGAZINE 2004.5
連載 / Pe 日活用のヒント 図 6 ま加勺に生成される Distfile install —oyounger , remove , nochkowner ,nochkgroup /dl/prod/htdoc/about ; except-pat ( ~ \ $ \.org/$ \ ・ orig\$ ) ; a11 : ( /dl/stage/htdoc/about ) ー > ( localhost ) special "embed—usage—tracker $REMFILE" る。これではすべてのファイルで special コマンドが実行 されてしまうが、 HTML ファイル以外には何もしないよ うに embed-usage-tracker を作成しておけばよい。 また、 install には younger オプションカ寸いているの で、ミラー元よりミラー先のファイルのほうか新しい場合 はコピーしない。こうしておかないと、すべての HTML ファイルが毎回コピーされてしまう。 というわけで、 rdist を使って sync-n-putjs. pl を実装 することも可能である。 File::SyncNMod モジュールを 使う場合とくらべて劣っているのは以下の点である。 ・ sync-n-putjs. pl が動的に Distfile を生成したうえで rdist を起動し、 rdist が embed-usage-tracker を起 動するというややネ礬隹な動作になる。 ファイルがコピーされるたびに embed_usage-tracker か起動するので効率カい。 その一方で、 rdist を使ったほうがプログラム全体の行数 は少なくてすむだろう。 CPAN で公開されているモジュール CPAN2 で公開されている、名前が F ⅱ e : : で始まるモジ ュールのなかに使えそうなものがないカ寐してみた。まず 目についたのは File::DirSync である。これは同一マシン 内でディレクトリをミラーするためのモジュールで、キャ ッシュを活用して高速化しているらしい。しかし、マニュ アルを読んだかぎりでは、 sync-n-putjs. pl のようなプロ グラムの素材となることは考慮されていないようだ。 次に目に留まったのが File::Rsync 、 File::RsyncP で ある。これらは rsync デーモンのクライアントのよう で、 rsync と深く関係していることから簡単に sync-n- putjs. pl の素材とはなりそうにない。 File::Sync というモジュールもあるが、これは UNIX の sync システムコールへのインターフェイスで、ディレ クトリをコピーするためのモジュールではない。 2 http://www.cpan.org/ 82 以上のように、既存のコマンドやモジュールでは、 sync- n-putjs. pl をなるべくボータブルで効率的に実装するのは 難しい。こうした事情があるので、私は FiIe::SyncNMod を作成した・ ・・といいたいところだが、これは嘘である。 私は当初、 -u オプションを知らなかったために rsync は使 えないと判断した。そこで FiIe::SyncNMod を書こうと 考え、それほど大変ではなさそうだったので書いてしまっ た。そしてひととおり動くようになった時点で、本当に書 く必要があったのか調べてみた、というのが実清である。 FiIe: :SyncNMod のイ吏い方 File::SyncNMod はオプジェクト指向のモジュールだ が、外部から呼び出されることを想定しているのは sync と いうクラスメソッドのみで、使い方は以下のとおりである。 Fi1e : :SyncNM0d->sync($srcdir, $dstdir, %option) ; %option には、、 verbose = 〉 1 " と、、 depth = 〉深さ " が指定可能である。前者を指定した場合はメッセージが多 く出力される。後者を指定した場合は指定した深さのぶん だけミラーをおこなう。指定がない場合は深さの制限なし にミラーをおこなう。さて、深さの定義だが、 $srcdir で 指定したディレクトリだけをコピーし、その中身をコピー しない場合を深さ 1 とする。 $srcdir の直下のファイル、 ディレクトリだけをミラーする場合は深さ 2 となる。 FiIe::SyncNMod クラスの使い方として、コンストラ クタでインスタンスを作成してからメソッドを適用するこ とも考えられるが、そうする必然性が思い当たらないので このようにしている。 File::SyncNMod クラス自体を使うことも不可能では ないが、サプクラスを作成し、それを介して使うのが本来 のかたちである。サプクラスでは以下のインスタンス・メ ソッドが定義されることを想定している。 $obj->tobeskipped($srcpath) $obj → copy($src , $dst) tobeskipped メソッドは、 $srcpath がコピーすべきパ スではない場合は真を、コピーすべきパスの場合は偽を返 UNIX MAGAZINE 2004.5
連載 / Pe 日活用のヒント リスト 1 sync-n-putjs ・ pl ・ open 、 unlink その他のおもなメソッド 必要に応じて属性をコピーする。 ファイルのコピーをおこなったかどうかにかかわらす、 178 行目 $self- 〉 cp-attrib($srcst, $dst) ; 一時ファイルはかならずスキップするようにしている。 したときに一時ファイルがコピーされるのを防ぐため、 でミラーしたものをさらに File : : SyncNMod でミラー さらに、あまりないことだと思うが、 File::SyncNMod 合より、明確なエラーカ起こることが多いだろう。 名前は本来のものでも内容力坏完全なファイルがある場 の内容のままのほうが問題が少ないからである。また、 の途中のファイルがあるよりは、ファイルがないか以前 ピーの途中のファイルカ駛われることを防げる。コピー このようにすることで、 dosync の処理が中断してもコ である。 /dl/prod/htdoc/about/. t . index. html に対する一時ファイルの名前は、 /dl/prod/htdoc/about/index. html 前に変更している。たとえば、 の一時ファイルに属性をコピーしたうえでミラー先の名 のではなく、いったん別の名前 ($tmp) でコピーし、そ ファイルをコピーする際は、ミラー先に直接コピーする 168 行目 $self- 〉 copy($src, $tmp) or do { 致しない場合はファイルのコピーをおこなう。 ミラー先カ在しないか、存在しても最終更新日時が - ー。ー。、 いすれも組込み関数を呼び出したうえで、処理が成功し なかった場合の処理をおこなうようになっている。 ・ rm—rf このメソッドは、名前が示すように UNIX の rm コマ ンドを一 rf オプション付きで起動したときのように動作 する。つまり、指定したパス以下を階層的に削除する。 ・ cp-attrib ファイルの属性をコピーする。コピーする属性はモード と所有者、グループである。いずれの属性もすでにコピ ー元と同じであればコピーしない。 stat カした mode に 07777 と論理積 ( & ) を適用した値を使って処理して いる理由は、その部分、つまり下位 12 ビットが chmod の処理対象だからである。それより上位のビットはファ イル、ディレクトリ、シンボリック・リンクといったファ イルの種別を表す部分である。 UNIX のファイル属性の詳細は、、 man -S 2 stat" が参 考になる。また、属性のコピーに使われる組込みコマン ド chmod 、 utime は同じ名前の UNIX のシステムコー ルに対応しており、言田は、、 man -S 2 chmod" 、、 man —S 2 utime" に解説されている。 ☆ 今回は、ファイル、ディレクトリ、シンボリック・リン クやそれらの属性を Perl で扱う方法を解説した。 File:: SyncNMod 自体を利用したり、すこし複雑なファイル処 理プログラムを書くときの参考にしていただければ幸いで ある。 ( いまづ・ひでよモルガン・スタンレー証券 ) 1 3 4 6 8 9 10 11 12 13 14 15 # ! /usr/bin/perl —w sub tobeskipped { use base qw(Fi1e: :SyncNM0d) ; package SyncNPutJS ; use StriCt ; # $ld: sync—n—putjs. pl,v 1 . 2 2004 / 03 / 10 08 : 56 : 40 himazu Exp $ # See . /LICENSE for terms of distribution. # (c) 2003 Morgan Stan1ey Dean Witter and Co. UN 工 X MAGAZINE 2004.5 85
連載 / Pe 日活用のヒント UNIX MAGAZINE 2004.5 て処理を終える。 入部分を追加し、その後に (/body 〉とく /html 〉を加え のく /body 〉とく /html 〉は削除している。そのうえで挿 ミラー元をミラー先にコピーするときに終了タグ また、 行から <!--END ... 〉までを無視する。 め、くい BEGIN ... 〉がミラー元にある場合は、その が、あっても問題カ起きないようになっている。そのた ァイルにはアクセス統言のための挿入部分はないはずだ さきほどの説明よりすこし複雑である。ミラー元のフ メソッドを定義している。 HTML ファイルの処理は、 HTML ファイルに対して特別な処理をおこなう copy 36 行目 sub copy { ped メソッドを定義している。 rcs 、 *.org 、 *. orig 、 * ~ をスキップするように tobeskip- 15 行目 sub tobeskipped { スであることを亘暠している。 SyncNPutJS クラスが File::SyncNMod のサプクラ 13 行目 use base qw(File::SyncNMod); こからが SyncNPutJS クラスの定義である。 11 行目 package SyncNPutJS; SyncNPutJS クラス ンのなかから SyncNPutJS- 〉 sync() を呼び出している。 SyncNPutJS クラスの定義で、末尾の main サプルーチ 末尾のリスト 1 に、 sync-n-putjs. pl を示す。大部分が sync-n-putjs. pl の詳細 コピーする。 ドは FiIe: ℃ opy::copy() を呼び出す。つまり、そのまま び出されない。 File::SyncNMod クラスの copy メソッ 出され、ディレクトリやシンポリック・リンクのときは呼 はない。 copy メソッドは通常のファイルのときだけ呼び 属性は別途処理されるので、 copy メソッドカ対処する必要 ス $dst にコピーする。モードや所有者などのファイルの copy メソッドは、パス $src で指定されたファイルをパ クトリ、シンボリック・リンクがコピーされる。 義していないサプクラスでは、すべてのファイル、ディレ ッドはつねに偽を返す。したがって、 tobeskipped を定 すようにする。 File::SyncNMod の tobeskipped メソ 84 行目 $self- 〉 SUPER::copy($src, $dst); HTML ファイル以外は親クラスの copy メソッドを呼 び出している。 それ以外の部分 90 行目 package main; こで SyncNPutJS クラスの定義カ冬るので、これ以 降はクラスに属さない部分である。このようにすること で、 1 つのファイルにクラスの定義とそうではない実行 部分の両方をもたせることができる。 FiIe::SyncNMod の詳細 末尾のリスト 2 に、 File::SyncNMod を示す。いうま でもないことだが、 /usr/Iib/perl/site-perl/File などの File::* のモジュールが入るべき場所に保存して使う。 31 行目 sub sync { 外部から呼び出されることを想定している唯一のクラス メソッドである。見てのとおり、インスタンスを作成し、 そのインスタンスに dosync メソッドを適用している。 sub dosync 94 行目 sub dosync { 、、 $obj- 〉 dosync($src, $dst, $depth) ; " の形式で呼び 出されるメソッドで、再帰呼出しによりディレクトリ をミラーする。このモジュールの要となるメソッドで ある。 97 行目 if ( $self- 〉 tobeskipped($src) Ⅱ まず、スキップすべきものかを判断する。スキップすべ きなら、何もせすに終了する。名前が、、 . t. " で始まるフ ァイルもスキップする。このようにしている理由は後述 する。 101 行目 my $srcst = lstat($src) or 糸旧ムみ関数の stat と lstat は、それぞれ UNIX の stat 、 lstat システムコールに相当するもので、ファイルやディ レクトリのモード、所有者、最終更新日時などの属性を 読み込むために使用する。 こでは、シンポリック・リンクを認識できるように lstat を呼び出している。シンポリック・リンクに対し 83
16 17 18 19 20 21 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 86 連載 / Pe 日活用のヒント my $self shift ; use constant JSBODY = > くく 'END' ・ END BEGIN JavaScript insersion by sync-n-nputj s . pl use constant JSHEADER = > くく ) END ' ; shift ; 10Ca1 ( $ ー ) く img border="0" width="l" hight="l" src="http://usage-tracking ・ JP/t . gif?Js=no"> く noscript> く script 1anguage="JavaScript" src="/usage—tracking ・ js"> く /script> く /noscript> END use く ! ー END s ub constant JSTRA 工 LER = > くく ' END ' ・ END JavaScript copy { my ($self, $src, my $skip = 0 ; if ( $src my $srcfh my $dstfh my $header xnsersion by sync—n—nputjs ・ pl $dst) J SHEADER ; $self->open()> $dst") or return 0 ; $self->open(" く $src") or return 0 ; $header ; my $header—re chomp $header—re ; $header—re my $trailer = JSTRAILER; $trailer; my $trailer—re chomp $trailer—re ; $trailer—re my $htmltagname my $bodytagname while ( く $srcfh> ) { if ( / く (html)\w/i ) { $htmltagname = $ 1 ; elsif ( / く (body)\W/i ) { $bodytagname if ( ml$header-re は。 ) { $skip = 1 ; next ; elsif ( ml$trailer-re は 0 ) { $skip = 0 ; next ; next if ( $skip ) ; 引く /body> Ⅱ i; 引く / 瓧 ml > Ⅱ i ; $dstfh->print($-) ; UNIX MAGAZINE 2004.5
連載 / Pe 日活用のヒント ミラー元のディレクトリの各要素について dosync を呼 134 行目 foreach my $i ( @srcdir ) { た—norecurse オプションの動作が実現されている。 を呼び出した時点で $depth は 2 であり、さきほど述べ 一方、—norecurse オプションがあると、 sync が dosync 制限なしにミラーがおこなわれる。 である。そのためこの行カ鵬になることはなく、深さの は、 sync が dosync を呼び出した時点で $depth は 0 ための部分である。—norecurse オプションがない場合 sync-n-putjs. pl の—norecurse オプションを実装する 133 行目 if ( ——$depth ) { ラー元にもあるかを確認する。ミラー元にないものは削 そこで、ミラー先のディレクトリの内容を読み込み、 ー先のディレクトリか在していたということである。 この時点で $dstst カ痕だということは、はじめからミラ 122 行目 if ( $dstst ) { ミラー元のディレクトリの内容を読み込む。 118 行目 my $srcdh = my-opendir($src) or die ' 必要に応じてディレクトリの属性をコピーする。 117 行目 $self- 〉 cp-attrib($srcst, $dst); クトリを作成する。 は削除する。そのうえで必要に応じてミラー先にディレ ミラー先のパスか有在していてもディレクトリでなけれ 105 行目 my $dstst = lstat($dst) Ⅱ ある。 この行からが、ミラー元がディレクトリの場合の処理で 104 行目 if ( S-ISDIR($srcmode) ) { ティレクトリの処理 なる。 ンク、通常のファイルのいずれであるかによって処理が異 このあとは、 $src がディレクトリ、シンポリック・リ オプジェクトを返す。 File::stat で定義されている lstat であり、 File::stat こで呼び出しているのは組込み関数の lstat ではなく、 ファイルの冒頭で、、 use File::stat;" としているので、 に stat を適用したものカされてしまう。 て stat を呼び出すと、リンク自体ではなく、 リンク先 84 び出す。 シンポリック・リンクの処理 139 行目 elsif ( $AO ne ' ' MS 、ⅲ 32 ” & & S-ISLNK($srcmode) ) { ミラー元がシンボリック・リンクの場合 この行からが、 の処理である。 Windows の場合、 UNIX のファイルシ ステムのシンボリック・リンクと同等の機能をもってい ないので、この部分は飛ばされる。 S-ISLNK() 自体は Windows においても、、 use Fcntl ';mode';" ( 15 行目 ) により定義されるが、 S-ISLNK() を呼び出すと以下のように表示されてプログラムが停止 する。 Your vendor has not defined Fcnt1 macro S_IFLNK, used at C : /Per1/1ib/Fcnt1. pm line 214. S-ISLNK() 自体は定義されているので、 defined(&S- ISLNK) は真であり、この結果をもとにシンポリック・ リンクの処理をおこなうかを判断することはできない。 そこで、 $AO で OS の種別を判断し、 Windows であ ればこの部分を実行しないようにしている。 143 行目 if ( $dstlink ) { ミラー先がシンボリック・リンクの場合、その内谷かミ ラー元と同じなら return し、内容が違う場合は削除し て処理を続行する。 148 行目 $self- 〉 rm-rf($dst) if (lstat($dst) ) ; ミラー先がシンポリック・リンクではなく、ファイルか ディレクトリなら削除する。 151 行目 symlink($srclink, $dst) or この時点でミラー先のシンポリック・リンクを作成する 準備は整っているので、糸ル囚み関数 symlink により作 成する。 通常のファイルの処理 154 行目 elsif ( S-ISREG($srcmode) ) { この行からは、ミラー元が通常のファイルの場合の処理 である。 157 行目 if ( $dstst ) { ミラー先カ在する場合、通常のファイルでなけれは削 163 行目 if ( !$dstst Ⅱ $srcmtime ! = $dstst- 〉 mtime UNIX MAGAZINE 2004.5