#!/usr/local/bin/perl #=============================================================================# # # # msearch - mat's search program # # version 1.52 # # # # 超簡易インデックス版検索エンジンプログラム # # Copyright (C) 2000-2005, Katsushi Matsuda. All Right Reserved. # # # #=============================================================================# #=============================================================================# # インデックス作成CGI # #=============================================================================# require './jcode.pl'; # 漢字コード変換パッケージ require './indexing.pl'; # インデックス作成モジュール #################### ### 変更可能変数 ### #################### ### デバッグ時にのみ設定して下さい. ### 0 - デバッグ情報出力なし ### 1 - 出力する $debug = 0; ### インデックスを作成する時のパスワードを設定して下さい. $g_password = "msearchpass"; $g_index = "default"; # デフォルトインデックス名 $body_background = ""; # 背景の画像 $body_bgcolor = "white"; # 背景の色 $body_text = "black"; # 文字の色 $body_link = "blue"; # 未到達リンクの色 $body_alink = "red"; # 活動中リンクの色 $body_vlink = "blue"; # 到達済リンクの色 $title_generate = "msearch / genindex / インデックス作成フォーム"; $title_control = "msearch / genindex / インデックス管理メニュー"; $title_result = "msearch / genindex / 実行"; $g_cgi = "genindex.cgi"; # このCGIプログラム $g_cookie = "1"; # クッキーを使うか $g_cookie_span = "60"; # クッキーの有効期限(日数) ################## ### メイン処理 ### ################## ### 引数の取得とパージング $arg = getargument(); $qarg = parseargument($arg); ### クッキーの取得とパージング $chash = parsecookie() if($g_cookie == 1); ### バッファリングの停止 $io = select(STDOUT); $| = 1; select($io); ### モード選択 if($qarg->{'mode'} eq "control") { ### インデックス補助ツールモード if($qarg->{'action'} ne "") { ## 補助ツールコマンド実行(クッキーは出力しない) # HTMLのContent-typeを出力する printcontenttype(); # ヘッダーの出力 printheader($title_result); # パスワードのチェック if(checkpassword() != 1) { print "パスワードが違います\n"; exit; } ## 各アクションによって処理を分岐 if($qarg->{'action'} eq "get") { ## 情報取得 doget(); } elsif($qarg->{'action'} eq "delete") { ## インデックス削除 dodelete(); } elsif($qarg->{'action'} eq "make") { ## 空インデックス作成 domake(); } elsif($qarg->{'action'} eq "combine") { ## インデックス結合 docombine(); } else { ## 不明なアクション } # フッターの出力 printfooter(); } else { ## 補助ツール画面(クッキーは出力しない) # HTMLのContent-typeを出力する printcontenttype(); # ヘッダーの出力 printheader($title_control); # 補助ツールの出力 printmenu(); # フッターの出力 printfooter(); } } else { ## インデックス作成モード if($qarg->{'includedir'} ne "" && $qarg->{'includeurl'} ne "" && $qarg->{'conf'} ne "") { ## インデックス作成(クッキーは出力する) # デバッグモードのチェック if($qarg->{'debug'} ne "") { $debug = $qarg->{'debug'}; } # $qarg->{'rescuealt'}はindexing.plで直接参照する # クッキーを出力する printallcookie() if($g_cookie == 1); # HTMLのContent-typeを出力する printcontenttype(); # ヘッダーの出力 printheader($title_result); # パスワードのチェック if(checkpassword() != 1) { print "パスワードが違います\n"; exit; } # インデックス作成呼び出し makeindex(); # フッターの出力 printfooter(); } else { ## インデックス作成画面(クッキーは出力しない) # HTMLのContent-typeを出力する printcontenttype(); # ヘッダーの出力 printheader($title_generate); # 作成フォームの出力 printform(); # フッターの出力 printfooter(); } } ### 終了 exit; ################################ ### genindex.cgiに個有の関数 ### ################################ ### ### 引数の取得 ### sub getargument { my $arg; # 取得するクエリー(戻り値) if($ENV{'REQUEST_METHOD'} eq 'GET') { $arg = $ENV{'QUERY_STRING'}; } elsif ($ENV{'REQUEST_METHOD'} eq 'POST') { read(STDIN,$arg,$ENV{'CONTENT_LENGTH'}); } return $arg; } ### ### 引数のパーズ ### sub parseargument { my $arg = $_[0]; # エンコードされた引数(引数) my %qarg; # パーズ結果のハッシュ(戻り値) my @avpairs; # 属性-値ペアの配列 my $avpair; # 属性-値ペア my $attribute; # 属性 my $value; # 値 @avpairs = split(/&/,$arg); for $avpair (@avpairs) { # 空白のデコード $avpair =~ tr/+/ /; # 属性と値に分解 ($attribute,$value) = split(/=/,$avpair); # 属性のデコード $attribute =~ s/%([\da-fA-F]{2})/pack("C",hex($1))/ge; # 値のデコード $value =~ s/%([\da-fA-F]{2})/pack("C",hex($1))/ge; $value =~ s/ //g; # 同じ属性が複数ある場合は','で繋ぐ if(defined $qarg{$attribute}) { $qarg{$attribute} .= ",$value"; } else { $qarg{$attribute} = $value; } } return \%qarg; } ### ### クッキーのパーズ ### sub parsecookie { my %cookies; # パーズ結果のハッシュ(戻り値) my @avpairs; # 属性-値ペアの配列 my $avpair; # 属性-値ペア my $attribute; # 属性 my $value; # 値 @avpairs = split(/; /,$ENV{'HTTP_COOKIE'}); for $avpair (@avpairs) { # 属性と値に分解 ($attribute,$value) = split(/=/,$avpair); # 空白のデコード $value =~ tr/+/ /; # 値のデコード $value =~ s/%([\da-fA-F]{2})/pack("C",hex($1))/ge; $cookies{$attribute} = $value; } return \%cookies; } ### ### パスワードのチェック ### sub checkpassword { my $t_pass = ""; if($qarg->{'conf'} ne "") { $t_pass = $qarg->{'conf'}; &jcode::convert(\$t_pass,"euc","",""); if($g_password eq $t_pass) { # パスワードが合っている return(1); } else { # パスワードが違っている return(0); } } else { # パスワードが違っている return(0); } } ### ### 全てのクッキーを出力する ### sub printallcookie { if($qarg->{'index'} ne "") { printcookie('index',$qarg->{'index'},$g_cookie_span); } if($qarg->{'includedir'} ne "") { printcookie('includedir',$qarg->{'includedir'},$g_cookie_span); } if($qarg->{'includeurl'} ne "") { printcookie('includeurl',$qarg->{'includeurl'},$g_cookie_span); } if($qarg->{'suffix'} ne "") { printcookie('suffix',$qarg->{'suffix'},$g_cookie_span); } if($qarg->{'excludedir'} ne "") { printcookie('excludedir',$qarg->{'excludedir'},$g_cookie_span); } if($qarg->{'excludefile'} ne "") { printcookie('excludefile',$qarg->{'excludefile'},$g_cookie_span); } if($qarg->{'excludekey'} ne "") { printcookie('excludekey',$qarg->{'excludekey'},$g_cookie_span); } if($qarg->{'sort'} ne "") { printcookie('sort',$qarg->{'sort'},$g_cookie_span); } if($qarg->{'rescuealt'} ne "") { printcookie('rescuealt',$qarg->{'rescuealt'},$g_cookie_span); } } ### ### クッキーの出力 ### sub printcookie { my $attribute = $_[0]; # 属性名(入力) my $value = $_[1]; # 値(入力) my $timespan = $_[2]; # expireまでの時間(単位=日)(入力) my @week = ("Sun","Mon","Tue","Wed","Thu","Fri","Sat"); my @month = ("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"); my ($sec,$min,$hour,$day,$mon,$year,$wday); # 値のエンコーディング $value =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/ge; # expire日の作成 ($sec,$min,$hour,$day,$mon,$year) = gmtime(); $year += 1900; plusday(\$year,\$mon,\$day,$timespan); # 何日後の計算 $wday = $week[&dayweek($year,$mon,$day)]; # 曜日の計算 $mon = $month[$mon]; $hour = "0" . $hour if($hour < 10); $min = "0" . $min if($min < 10); $sec = "0" . $sec if($sec < 10); # 出力 print "Set-Cookie: $attribute=$value; "; print "expires=$wday, $day-$mon-$year $hour:$min:$sec GMT;\n"; } ### ### 曜日を返す関数 ### sub dayweek { my $year = $_[0]; # 年(入力) my $month = $_[1]; # 月(入力) [0....11] my $day = $_[2]; # 日(入力) my $dayweek; # 曜日(戻り値) [0...6] $month++; if($month < 3) { $year--; $month += 12; } $dayweek = ($year + $year/4 - $year/100 + $year/400 + (13 * $month + 8)/5 + $day) % 7; return($dayweek); } ### ### うるう年がどうかを返す関数(1:閏年,0:平年) ### sub isuruu { my $year = $_[0]; # 年(入力) if(($year%4) == 0) { if(($year%400) == 0) { return(1); } elsif(($year%100) == 0) { return(0); } else { return(1); } } else { return(0); } } ### ### ある日から何日後を計算する ### sub plusday { my $year = $_[0]; # 年への参照(入力) my $month = $_[1]; # 月への参照(入力) [0....11] my $day = $_[2]; # 日への参照(入力) my $span = $_[3]; # 足す日(入力) my @mday = (31,28,31,30,31,30,31,31,30,31,30,31); while($span > 0) { my $thismonth = $mday[$$month]; # 現在の月の最終日 $mday[1] += 1 if($$month == 1 && isuruu($$year) == 1); # うるう年の2月 if($thismonth - $$day < $span) { # 次の月へ $span -= $thismonth - $$day + 1; $$day = 1; $$month++; if($$month > 11) { # 次の年へ $$month = 0; $$year++; } } else { # この月で全部足せた $$day += $span; $span = 0; } } } ### ### 情報取得 ### sub doget { my @files = (); my $file = ""; print "補助ツールモードへは,ブラウザの「戻る」で戻って下さい.
\n";
print "SERVER_NAME = $ENV{SERVER_NAME}
\n";
print "HTTP_HOST = $ENV{HTTP_HOST}
\n";
print "SERVER_SOFTWARE = $ENV{SERVER_SOFTWARE}
\n";
print "DOCUMENT_ROOT = $ENV{DOCUMENT_ROOT}
\n";
print "SCRIPT_FILENAME = $ENV{SCRIPT_FILENAME}
\n";
print "SCRIPT_NAME = $ENV{SCRIPT_NAME}
\n";
if(exists $ENV{MOD_PERL}) {
print "MOD_PERL VERSION = $ENV{MOD_PERL}
\n";
} else {
print "PERL VERSION = $]
\n";
}
print "PROCESS ID = $$
\n";
print "REAL USER ID = $<(" . user($<) . ")
\n";
print "EFFECTIVE USER ID = $>(" . user($>) . ")
\n";
print "REAL GROUP ID = $( " . group($() . "
\n";
print "EFFECTIVE GROUP ID = $) " . group($)) . "
\n";
print "HTTP_USER_AGENT = $ENV{HTTP_USER_AGENT}
\n";
print "CURRENT DIR = " . mypwd() . "
\n";
print "
\n"; print "
\n";
print "
|
\n"; print "
\n";
print "
|
\n"; $index = $g_index if($index eq ""); $file = $index . ".idx"; if(unlink($file)) { print "インデックス:$indexを削除しました."; } else { print "インデックス:$indexを削除するのに失敗しました."; } } ### ### 空インデックス作成 ### sub domake { my $index = $qarg->{'index'}; my $file = ""; print "補助ツールモードへは,ブラウザの「戻る」で戻って下さい.
\n"; $index = $g_index if($index eq ""); $file = $index . ".idx"; # try 1 if(open(FILE,">$file")) { print "空インデックス:$indexを作成しました.(try 1)"; close(FILE); return; } # try 2 if(sysopen(FILE,"$file",O_RDWR|O_CREAT)) { print "空インデックス:$indexを作成しました.(try 2)"; close(FILE); return; } # try 3 `touch $file`; if(-f $file && -z $file) { print "空インデックス:$indexを作成しました.(try 3)"; return; } print "空インデックスの作成に失敗しました."; } ### ### インデックス結合 ### sub docombine { my @files = (); my @indice = (); my ($file, $all); print "補助ツールモードへは,ブラウザの「戻る」で戻って下さい.
\n";
unlink("./$g_index.idx");
opendir(P,".");
@files = readdir(P);
closedir(P);
foreach $file (@files) {
if($file =~ /\.idx$/i) {
push(@indice,$file);
}
}
if($#indice == -1) {
print "インデックス結合に失敗しました(結合対象のインデックスが存在しません).";
return;
}
# try 1
$all = join(" ",@indice);
`cat $all>./$g_index.idx`;
if(-f "./$g_index.idx" && -s "./$g_index.idx") {
print "インデックス結合に成功しました.(try 1)";
return;
}
# try 2
if(!open(FILE,">./$g_index.idx")) {
print "インデックス結合に失敗しました($g_indexインデックス作成失敗).";
return;
}
foreach $file (@indice) {
if(!open(IN,"<$file")) {
print "インデックス結合に失敗しました($fileインデックスオープンエラー).";
return;
}
while(
msearch用インデックス作成フォーム
msearch用インデックス補助ツール
※1
作成するインデックスの名称.指定しない場合はデフォルト値(default)
が名称となる.インデックスを切り替えて検索する場合には,それぞれの検索
対象毎にインデックスの名称を付ける.インデックスのファイル名は
インデックス名に『.idx』という拡張子(suffix)が自動的に付けられるので,
ここでは拡張子を指定してはならない.
※2
インデックス化するHTMLファイルがあるディレクトリ.必ず1ディレクト
リのみ指定しなければならない.絶対パスではなく,このプログラム
(genindex.cgi)のあるディレクトリからの相対パスもしくは,絶対パスで指定
する.このプログラムは,この指定されたディレクトリ以下のすべてのHTML
ファイルをインデックス化する.
※3
上の対象ディレクトリがURLでは表されるかを指定する.例えば,対象
ディレクトリが,"../public_html"であり,そのURLが
"http://www.foo.co.jp/~user/"の様に指定する.
※4
インデックス化するHTMLファイルの拡張子を指定する.何も指定しない
場合は,".html"と".htm".指定する場合は,このデフォルト値を上書きするの
で,注意が必要.".html,.shtml"の様に半角のカンマを使い,複数指定できる
(実際にはダブルクォーテーションはいらない).
※5
上の対象ディレクトリの中でインデックス化しないディレクトリを指定
する.例えば,"../public_html/cgi-bin"以下をインデックス化しない場合は,
"cgi-bin"の様に対象ディレクトリからの相対パスで指定する.半角カンマを
使い,複数指定できる.
また,非対象ディレクトリにしたいディレクトリ
名を正規表現を使って指定することができる.ただし,この場合,対象ディレ
クトリからの相対パスではなく,ディレクトリ名のみを正規表現で指定する.
例えば,対象ディレクトリ以下にある全ての"_vti_cnf"というディレクトリを
インデックス化したくない場合は"(_vti_cnf)"とする."("と")"は,この中は
正規表現だと指定するために必要です."(_vti_cnf)"の代わりに"(^_.*)"の
ように記述しても構いません.
※6
上の対象ディレクトリの中で,且つ非対象ディレクトリ以外でインデッ
クス化しないファイルを指定する.例えば,"../public_html/secret.html"
ファイルをインデックス化したくない場合は,"secret.html"の様に対象ディレ
クトリからの相対パスで指定する.半角カンマを使い,複数指定できる.
また,非対象ディレクトリと同様に非対象ファイルとしたいファイル名を正規
表現を使って指定することができる.正規表現は"("と")"で囲って指定する.
※7
検索対象に入れたくないキーワードを指定します.ここで指定したキー
ワードで検索した場合,検索結果は0件となります.半角カンマを使い,複数
指定できます.例えば,「インターネット」と「検索」というキーワードを
検索対象にしたくない場合は,"インターネット,検索"と指定します.ここで
指定したキーワードは検索結果の一部表示にも出てきませんので注意して下さい.
ただし,タイトルに含まれるキーワードは削除しません.
※8
検索結果のランキング(ソート)方法を指定します.ランキングはイン
デックスを作る時に決定しなければなりません.
※9
ここをチェックすると,alt属性中の文字列も検索対象に含めます.
※10
このCGIを動かすことが出来る人を限定するためのパスワードです.生
のパスワードデータを送りますので,グラブされる可能性があります.
※11
ここをチェックすると,デバッグ情報が出力されます.正常に
インデックスが作成されない場合の状況を把握するために有益な情報が表示
されます.
msearch用インデックス作成フォーム
msearch用インデックス補助ツール
/g;
print "$str\n";
}