#!/usr/local/bin/perl5 # # ssi.cgi # 1997/08/10 Ver.0.00 # 1997/08/12 Ver.0.01 # 1997/08/17 Ver.0.02 # 1997/08/19 Ver.0.03 # 1997/08/20 Ver.0.04 # 1997/08/21 Ver.0.05 # 1997/09/15 Ver.0.06 # host コマンドが動作しなくなっため、 # ディレクトリを指定するように変更 # 1997/12/20 Ver.0.07 # config timefmt の指定を追加 # 1997/12/23 Ver.0.08 bugfix # 1997/12/29 Ver.0.09 # 1998/01/14 Ver.0.10 # host コマンドから gethostbyaddr へ # 環境変数 HTTP_X_FORWARDED_FOR の変換を追加 # 1998/02/18 Ver.0.11 # 1998/03/25 Ver.0.12 # HREF="./a.htm" を HREF="ssi.cgi?a.htm" へ変換する機能を付加 # /usr/mesh/bin/perl5 を /usr/local/bin/perl5 へ変更 # 大文字での記述に対応 # 1998/03/28 Ver.0.13 # 1998/07/05 Ver.0.14 # ロジックを簡素化しました。 # 1998/07/07 Ver.0.15 # 行末の処理の bugfix # 1999/11/15 Ver.0.16 # BIGLOBE サーバーの設定変更に対応 # 環境変数 REMOTE_ADDR を REMOTE_HOST へ設定 # 2001/09/14 Ver.0.17 # # (C) 1997,1998,1999,2001 がま # e-mail addr : <gama@mvg.biglobe.ne.jp> # # usage: # ex. <A HREF="ssi.cgi?foo.htm">foo</A> $ownname ="ssi.cgi"; $dflthtml = 'welcome.htm'; # 省略時の html ファイル名 $date = '/bin/date'; # date コマンドのありか $timefmt = ''; # timefmt の初期値 { $HTMLF=$ENV{'QUERY_STRING'}; unless($HTMLF) { $HTMLF= $dflthtml; # 省略時の指定 } else { $HTMLF=~ s/\.\.+//g; # .. を削除 $HTMLF=~ s/\/\/+//g; # // を削除 $HTMLF=~ s/^\///; # 先頭の / を削除 } # ///////////////////////////////////////////////////////////////////////// print "Content-type: text/html\n\n"; # <!--#command tag1="value1" tag2="value2" --> # <!--#exec cmd="./command&arg" --> という記述の処理 # <!--#echo var="REMOTE_HOST" --> という記述の処理 # <!--#config timefmt="%y/%m/%d %H:%M:%S" --> # <!--# と --> が同じ行内にある場合しか考慮していない open(FHTML,"<$HTMLF"); while (<FHTML>) { while (/(.*?)<!--#(\w*?)\s(.*?)-->(.*\n)/) { # 1 line に複数記述には対応 print $1; # <!--# より前を出力 $ssicmd= "\L$2\E"; # 小文字化 $ssiarg= $3; # 指定の中身だけ $_=$4; # --> より後ろ if ( $ssicmd eq "exec" ) { &exec_proc($ssiarg); } elsif ( $ssicmd eq "echo" ) { &echo_proc; } elsif ( $ssicmd eq "config" ) { &config_proc; } else { &error_proc; } } #### <A HREF="./a.htm "> ==> <A HREF="ssi.cgi?a.htm "> ### s/(<.+?href=")\.\/(.+?".*?>)/$1$ownname\?$2/i; print $_; } close(FHTML); } # ///////////////////////////////////////////////////////////////////////// sub exec_proc { my($cmd) = shift;; print ""; $|=1; if ($cmd=~ /cmd=\"(.*)\"/i ) { # cmd="" $cmd = $1; $cmd =~ s/\?/ /g; # ? をスペースへ system ("$cmd"); # 実行 } else { &error_proc; } $|=0; } # ///////////////////////////////////////////////////////////////////////// sub config_proc { if ($ssiarg=~/timefmt=\"(.*)\"/i ) { # timefmt="" $timefmt="+\'$1\'"; } else { &error_proc; } } #///////////////////////////////////////////////////////////////////////// sub echo_proc { my($var); if ($ssiarg=~ /var=\"(.*)\"/i ) { # cmd="" $var = $1; # if ($var eq "DATE_LOCAL") { open(PROC,"$date $timefmt |"); while ($r = <PROC>) { # 結果を読み出す chomp($r); print $r; } close(PROC); } elsif ($var eq "DATE_GMT") { open(PROC,"$date -u $timefmt |"); while ($r = <PROC>) { # 結果を読み出す chomp($r); print $r; } close(PROC); } elsif ($var eq "REMOTE_HOST" || $var eq "HTTP_X_FORWARDED_FOR") { if ($var eq "REMOTE_HOST" ) { $ENV{$var} = $ENV{'REMOTE_ADDR'}; } unless ( $r = gethostbyaddr(pack('C4',split(/\./,$ENV{$var})),2)) { $r = $ENV{$var}; } print $r; } else { print $ENV{$var}; } } else { &error-proc; } } #///////////////////////////////////////////////////////////////////////// sub error_proc { print " Message from ssi.cgi, error at --#$ssicmd $ssiarg--."; }