#!/usr/local/bin/perl
$programversion = "search.pl ver.1.16.66"; #プログラムのバージョン
#1997/11/25
#(c)MOROBOSHI Tomorou
#ユーザー定義用変数
$dir="."; #検索ディレクトリ
#perl動作定義変数
$| = 1; #出力をバッファにためずに、一行ごとに行う指定。
#プログラムの内部変数
# $filerule "reverse" or OTHERS : ファイル名を昇順か降順か決める "reverse"で降順、それ以外なら昇順
# $fileview "on" or OTHERS : 検索文字列の有無と無関係に検索したファイル名を表示するかどうか決める
# : "on"なら表示、それ以外なら非表示
# $contentsview "off" or OTHERS : 検索文字列がマッチした場合、検索対象データを表示するかどうか決める
# : "off"なら非表示、それ以外なら表示
# %in : cgi-lib.plがFORMから受け取ったデータを格納する連想配列
# $in{"search"} : FORMの name="search"タグの内容。検索文字列
# $in{"filerule"} : FORMの name="filerule"タグの内容
# $in{"contentsview"} : FORMの name="contentview"タグの内容
# @allfiles :ディレクトリの全ファイル名が入るリスト
# $filename :データをとりだすファイル名
# $content :ファイルから取り出された一行。検索対象データ
#以下、メインルーチン
require "cgi-lib.pl"; #cgi-lib.plがFORMからのデータ取り込みに必要です。
require "jcode.pl"; #jcode.plが文字コード変換に必要です。
#とりあえず、ブラウザに「Search Result」のhtmlを出力。
print "Content-type: text/html\n\n"; #htmlのヘッダ
print"
Search Result";
print"";
print"Search Result
";
#検索文字列をとってくる。
&ReadParse; #cgi-lib.plのサブルーチンを使う
#文字列はcgi-lib.plがデコードする
$search = $in{"search"}; #連想配列 %in からFORMのデータを得る。
$filerule = $in{"filerule"}; #ファイル名を昇順か降順か決める$filerule
$fileview = $in{"fileview"}; #ファイル名を表示するかどうか $fileview
$programversionview = $in{"version"}; #バージョン表示の有無 on or off
$contentsview = $in{"contentsview"}; #マッチした検索結果を表示するか $contentsview
&jcode'convert (*search,"euc"); #検索文字列 $search をEUCに変換
#バージョン表示部分
if ($programversionview eq "on"){
print "Program Version is [$programversion]
";
}
#検索文字列に'<'か'>'が含まれていたら、無効化し、警告文を出す。
if ($search =~ m/[<>]/){
$search =~ s/</gio; #半分に切れたタグ無効化
$search =~ s/>/>/gio; #半分に切れたタグ無効化
print "Cannot search a Word which includes '>' or '<'.
";
}
print "searching [$search]
"; #検索文字列 $search をブラウザに表示
print "
";
print"";
#ディレクトリのファイル名を得る
#opendir(THISDIR, $dir)|| die("cannot opendir, $dir: $!\n"); #ディレクトリを開く。
#@allfiles = readdir(THISDIR); #ファイル名を読み込む
#closedir(THISDIR); #ディレクトリを閉じる
&getallfiles($dir); # @allfiles に全ファイル名が入る。
#得られたファイル名のリストから不要なファイル名を削除する
#サブルーチン内部に移動。
#@allfiles = grep(!/^\.\.?$/,@allfiles); # delete ".",".."
#@allfiles = grep(!/~$/,@allfiles); # delete "*.*~" emacs BKUP
#@allfiles = grep(!/.pl$/,@allfiles); # delete "*.pl" perl SCRPT
#@allfiles = grep(!/#$/, @allfiles); # delete "*.*#" emacs BKUP
#@allfiles = grep(!/^_/, @allfiles); # delete "_*"
#@allfiles = grep(!/^\.ht/, @allfiles); # delete ".htaccess",".htpasswd"
#ファイル名リストをソートする
if ($filerule eq "reverse"){
@allfiles = sort by_reverse_character @allfiles; # $fileruleが"reverse"の時、文字コード降順でソート
}
else {
@allfiles = sort by_character @allfiles; #文字コード順(未指定時デフォルト)
}
#ファイル名リスト@allfilesから、ファイル名をひとつずつとりだし$filenameに
#格納し、すべてのファイル名で、一度ずつ、ループをおこなう
foreach $filename (@allfiles){
#$fileviewが"on"の場合、検索文字列の有無にかかわらず、
#検索対象になったファイル名を表示する。
if ($fileview eq "on"){ #この機能があると、ディレクトリ内部の非リンクファイル
print '
'; #の存在を外部から調べることができるセキュリティホールに
print "$filename
"; #なる可能性があります。この機能を望まない場合は、この4行
} #の先頭に#記号をつけてコメントアウトして機能を停止してください。
#と、書いたけどデフォルトでコメントアウトしておこう。
#読み込みのためファイルを開く
open(TXT,$filename)|| die("cannot open, $filename: $!\n");
#以下、ファイルから一行ずつ取り出して処理するループ
$oldline = "";
while($line = ) {
&jcode'convert (*line,"euc"); #取り出したデータをjcodeでeucに変換
$line =~ s/<[^>]*>//gio; #タグ抜き
# $line =~ s/&/&/gio; #半分に切れたタグ無効化
$line =~ s/</gio; #半分に切れたタグ無効化
$line =~ s/>/>/gio; #半分に切れたタグ無効化
$line =~ s/\r//gio; #CR抜き
$line =~ s/\n//gio; #LF抜き
$content = $oldline.$line; #$oldlineと$lineを結合させて二行ずつマッチ
$oldline = $line; #$oldlineに$lineを保存
$oldline =~ s/$search//goi; #$oldline内のすでにヒットした$searchを削除
# $contentに$searchが含まれいた場合の処理
if ($content =~ m/$search/){
print "- $filename"; #ファイル名をリンクつきでブラウザに表示
# $contentsviewがoffで無い場合の処理
# デフォルト(指示がない場合)は、$contentsview="on"として作動する判定条件になっている
if ($contentsview ne "off"){
print "
";
$content =~ s/$search/$search<\/strong>/g; #検索対象文字列の中の$searchを強調タグで囲む
print $content; #検索対象文字列をブラウザに表示
print '
';
}
} #$contentに$searchが含まれかいいた場合のif文の終わり。
} #$filenameで回っているwhileのループの終わり。
close(TXT); #ファイルを閉じる。
} #@allfilesで回っているforeachのループの終わり。
#以下、ブラウザにhtmlの終わりを表示する
print "
";
print "
";
print "End of Search";
print "";
print "";
#CGIのメインルーチンの終わり
#以下、sort関数で使用するルールのためのサブルーチン
#文字コード昇順(sort関数はデフォルトで文字コード昇順なので、本当は必要ない)
sub by_character {
$a cmp $b;
}
#文字コード逆順
sub by_reverse_character {
$b cmp $a;
}
#赤ラクダ本日本語版p71からの、再帰的ファイル名検索ルーチンdodirをまねしてみた。
#Globalな配列 @allfilesにディレクトリ名付きファイル名を蓄積する。
sub getallfiles{
local($dir,$nlink) = @_;
# print '$dir',$dir,"
";
# print '$nlink',$nlink,"
";
# print '$size',$size,"
";
local($dev,$ino,$mode,$subcount);
($dev,$ino,$mode,$nlink) = stat('.') unless $nlink;
opendir(DIR,'.') || die "cant open $dir";
local(@filenames) = readdir(DIR);
closedir(DIR);
if ($nlink == 2){
for(@filenames){
next if $_ eq '.';
next if $_ eq '..';
# print "$dir/$_\n";
}
}
else{
$subcount = $nlink -2;
for (@filenames){
next if $_ eq '.';
next if $_ eq '..';
#得られたファイル名から不要なファイル名を削除する
# if ($_ =~ m/\.\.?$/){$_ ='';}; # delete ".",".."
# if ($_ =~ m/~$/){$_ ='';}; # delete "*.*~" emacs BKUP
# if ($_ =~ m/.pl$/){$_ ='';};; # delete "*.pl" perl SCRPT
# if ($_ =~ m/#*.*#/){$_ ='';}; # delete "*.*#" emacs BKUP
# if ($_ =~ m/^_/){$_ ='';}; # delete "_*"
# if ($_ =~ m/^\.ht/){$_ ='';}; # delete ".htaccess",".htpasswd"
if ($_ ne ''){
$name = "$dir/$_";
@allfiles = (@allfiles,$name);
}
next if $subcount == 0;
($dev,$ino,$mode,$nlink) = lstat($_);
next unless -d _;
chdir $_ || die "cant cd to $name";
&getallfiles($name,$nlink);
chdir '..';
--$subcount;
}
}
}
#End of File