#!/usr/local/bin/perl

#971124b_search.pl
#search.pl ver.1.9.1
#1997/11/24
#(c)MOROBOSHI Tomorou

#変数
# $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が文字コード変換に必要です。

$dir=".";              #自分と同じディレクトリを検索する。（実は使うのを忘れてた）
$| = 1;                #出力をバッファにためずに、一行ごとに行う指定。

#とりあえず、ブラウザに「Search Result」のhtmlを出力。

print "Content-type: text/html\n\n";                    #htmlのヘッダ
print"<html><head><title>Search Result</title></head>";
print"<h1>Search Result</h1>";
print"<ul>";

#検索文字列をとってくる。

&ReadParse;                           #cgi-lib.plのサブルーチンを使う
                                      #文字列はcgi-lib.plがデコードする
$search = $in{"search"};              #連想配列 %in からFORMのデータを得る。
$filerule = $in{"filerule"};          #ファイル名を昇順か降順か決める$filerule
$fileview = $in{"fileview"};          #ファイル名を表示するかどうか  $fileview
$contentsview = $in{"contentsview"};  #マッチした検索結果を表示するか $contentsview
&jcode'convert (*search,"euc");       #検索文字列 $search をEUCに変換

print "searching [$search]<br>";      #検索文字列 $search をブラウザに表示

#ディレクトリのファイル名を得る

opendir(THISDIR, ".");                #ディレクトリを開く。あれ？ $dir使ってないや
                                               #得られたファイル名のリストから不要なファイル名を削除する
@allfiles = grep(!/^\.\.?$/,readdir(THISDIR)); # 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 ".*" UNIX hidden
closedir(THISDIR);                    #ディレクトリを閉じる

#ファイル名リストをソートする
@allfiles = sort by_character @allfiles;             #文字コード順（未指定時デフォルト）
if($filerule eq "reverse"){
    @allfiles = sort by_reverse_character @allfiles; # $fileruleが"reverse"の時、文字コード降順でソート
}

#ファイル
#ファイル名リスト@allfilesから、ファイル名をひとつずつとりだし$filenameに
#格納し、すべてのファイル名で、一度ずつ、ループをおこなう

foreach $filename (@allfiles){

    #$fileviewが"on"の場合、検索文字列の有無にかかわらず、
    #検索対象になったファイル名を表示する。

#    if ($fileview eq "on"){           #この機能があると、ディレクトリ内部の非リンクファイル
#        print '<hr>';                 #の存在を外部から調べることができるセキュリティホールに
#        print "<h2>$filename</h2>";   #なる可能性があります。この機能を望まない場合は、この４行
#    }                                 #の先頭に#記号をつけてコメントアウトして機能を停止してください。
                                       #と、書いたけどデフォルトでコメントアウトしておこう。
    #読み込みのためファイルを開く

    open(TXT,$filename);  

    #以下、ファイルから一行ずつ取り出して処理するループ

    while($content = <TXT>)  {

        &jcode'convert (*content,"euc"); #取り出したデータをjcodeでeucに変換

        $content =~ s/<[^>]*>//gio;      #タグ抜き
        $content =~ s/\r//gio;           #CR抜き
        $content =~ s/\n//gio;           #LF抜き

        # $contentに$searchが含まれいた場合の処理
        if ($content =~ m/$search/){
            print "<li><a href=\"$filename\">$filename</a>"; #ファイル名をリンクつきでブラウザに表示
            # $contentsviewがoffで無い場合の処理
            # デフォルト（指示がない場合）は、$contentsview="on"として作動する判定条件になっている
            if ($contentsview ne "off"){
                print "<br>";
                $content =~ s/$search/<strong>$search<\/strong>/g; #検索対象文字列の中の$searchを強調タグで囲む
                print $content;                                    #検索対象文字列をブラウザに表示
                print '<hr width="30%">'; 
            } 
        }            #$contentに$searchが含まれかいいた場合のif文の終わり。
    }                #$filenameで回っているwhileのループの終わり。
    close(TXT);      #ファイルを閉じる。
}                    #@allfilesで回っているforeachのループの終わり。

#以下、ブラウザにhtmlの終わりを表示する

print "</ul>";
print "</body>";
print "</html>";

#CGIのメインルーチンの終わり

#以下、sort関数で使用するルールのためのサブルーチン

#文字コード昇順（sort関数はデフォルトで文字コード昇順なので、本当は必要ない）
sub by_character {
    $a cmp $b;
}  

#文字コード逆順
sub by_reverse_character {
    $b cmp $a;
}

