#!/usr/local/bin/perl ############################################## # # トピックス出力CGI Ver 1.0 # Homepageworks Inc. K.Asasora # http://www.hpw.co.jp/ # asa@hpw.co.jp # # このプログラムは #(有)ホームページワークスより #(有)ふく利 # にライセンスされています。 # 許可なく二次使用することを禁じます。 # # 2005/09/30 # ############################################## # SSL非対応版に改修。 2004/04 # 変数設定  # → action=listで全記事一覧画面呼出 require './jcode.pl'; #jcode呼び出し $url = '../../index.html'; #戻り先URL $script = './up.cgi'; #このCGI名 $logfile = './upmast.txt'; #ログファイル名 $lockfile = './upmast.lock'; #ロックファイル名 $cntfile = './upmast.cnt'; #記事毎の参照数カウントファイル名 ※使用しない場合は'' $cgidirc = ''; #index.shtmlからこのCGIへのパスを記述(例:'cgi-bin/topics/') $title = '中華そば ふく利|新着情報';#タイトルを指定 $cr = 'FUKURI Inc.';#Copyrightを指定 $textcolor = '#333333'; #メッセージ表示部分のテキスト「name,email,color,msg」の文字色 $resflg = 0 ; #レス記事の表示順(0:古い→新しい 1:新しい→古い) $tbgcolor = '#FFFFFF'; #ログ表示部の背景色を指定 #詳細ページの横幅をピクセルで指定。※「%」での指定は出来ません $tablesize2 = '800' ; $datamax = 100 ; #最大データ保存件数(親記事件数) $pagemax = 20 ; #タイトル一覧画面に表示する件数(…親記事の件数) $topimax = 3 ; #トップページに表示する件数 $tag = 'no'; #タグ許可(yes,no) $timemode = 1 ; #記事投稿時間および新着情報を表示するか(する:0 しない:1) $newtime = 168 ; #何時間以内に投稿(又はレス)記事を「新着情報」とするか $newgif = './img/new.gif' ; #新着情報に表示させる「new」の画像 $gif_spacer = './img/spacer.gif'; #1×1の透過画像 #色の指定 @COLORS = ('#333333','#FF0000','#CC6666','#FF6600','#669900','#3399CC','#3366FF','#3333CC','#660099'); @COLORSNM = ('Black','Red','Pink','Orange','Green','Sky','Blue','DeepBlue','Purple'); #=================================================================================== # デフォルト出力ページ設定 ======================================================= #=================================================================================== # 記事表示ページ上段のHTMLを記述 から $html_topdefault=<<"_EOF_"; _EOF_ # ↑ この _EOF_ は消去不可 #----------------------------------------------------------------------------------- # 記事表示ページ上段のHTMLを記述 まで $html_bottomdefault=<<"_EOF_"; _EOF_ # ↑ この _EOF_ は消去不可 #----------------------------------------------------------------------------------- #=================================================================================== # 記事表示ページ設定 #=================================================================================== # 記事表示ページ上段のHTMLを記述 から $html_tophtml=<<"_EOF_"; $title _EOF_ # ↑ この _EOF_ は消去不可 #----------------------------------------------------------------------------------- # 記事表示ページ下段のHTMLを記述 まで $html_bottomhtml=<<"_EOF_"; _EOF_ # ↑ この _EOF_ は消去不可 #===================================================================================== # アップロードディレクトリのパス → パスの最後は / $UpFolder = "./upimg/"; # アップロードディレクトリのURLパス → パスの最後は / $UpUrl = "./upimg/"; $sizeflg = 0 ; #画像の下にファイルサイズを表示しますか?(0:no 1:yes) $damedame = 0 ; #Locationヘッダが使えないサーバーは1。通常は0でいいはず。※トクトク、3nopage,WinNTサーバー等が1 #<<< ここから下はいじらない方がいいです。 @FMT = ("gif","jpg","jpeg","png"); @errtag = ('table','meta','form','!--','embed','html','body','tr','td','th','a'); #危険タグ ############################################################################### #### Main Process START ##################################################### ############################################################################### $ENV{'TZ'} = "JST-9"; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); #システム日時・時刻取得 $year = substr(sprintf("%02d",$year + 1900),2,2); $month = sprintf("%02d",$mon + 1); $mday = sprintf("%02d",$mday); $hour = sprintf("%02d",$hour); $min = sprintf("%02d",$min); if ( $timemode eq "1" ) { $today = "$year/$month/$mday"; } else { $today = "$year/$month/$mday-$hour:$min"; } $iday = time + ( 60 * 60 * ($newtime * -1) ) ; #$newtime時間前 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($iday); $year = substr(sprintf("%02d",$year + 1900),2,2); $month = sprintf("%02d",$mon + 1); $mday = sprintf("%02d",$mday); $hour = sprintf("%02d",$hour); $min = sprintf("%02d",$min); if ( $timemode eq "1" ) { $newday = "$year/$month/$mday"; } else { $newday = "$year/$month/$mday-$hour:$min"; } if ($ENV{'HTTP_USER_AGENT'} !~ /MSIE/i) { $css_style = "" ; } &decode ; #<<<デコード if ( $FORM{'action'} eq "view" ) { #<<<ログ表示新 &view ; #<< $maxdatasz ) { &error("画像ファイルのサイズが" . int($maxdatasz / 1024) . "kbを超えている為アップロード出来ません。"); } @pairs2 = split(/-*\S*\s*Content-Disposition: form-data; name="\w*"/,$read_data); $img_data = pop(@pairs2); $mac=0; if ($img_data =~ /(.*)filename="(.*)"/i) { $upfname=$2; push(@pairs2,$upfname); } if ($img_data =~ /(.*)Content-type:(.*)\/(.*)/i) { $type=$3; } if ($img_data =~ /application\/x-macary/i) { $mac=1; } @pairs3 = split(/; name="/,$read_data); foreach ( @pairs3 ) { $pos = index( $_, "\""); $_ = substr($_,0,$pos) ; $i++; } } else { if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/,$buffer); } foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; if ($tag eq 'yes') { #危険なタグは禁止!!! foreach ( @errtag ) { if ($value =~ /<$_(.|\n)*>/i) { &error("使用出来ないタグが入力されています"); } } } else { $value =~ s//>/g; } $value =~ s/\,/,/g; &jcode'convert(*value,'sjis'); $value =~ s/\r\n/
/g; $value =~ s/\r|\n/
/g; $FORM{$name} = $value; } $i=0; foreach $pair2 (@pairs2) { $pair2 =~ s/^\r\n\r\n//g; if ( $pairs3[$i] ne 'comment' ) { $pair2 =~ s/\r\n//g; } $pair2 =~ tr/+/ /; $pair2 =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; foreach ( @errtag ) { if ($pair2 =~ /<$_(.|\n)*>/i) { &error("使用出来ないタグが入力されています"); } } &jcode'convert(*pair2,'sjis'); $pair2 =~ s/\,/,/g; $pair2 =~ s/\r\n/
/g; $pair2 =~ s/\r|\n/
/g; $FORM{$pairs3[$i]} = $pair2; $i++; } $FORM{'hp'} =~ s/^http\:\/\///; } ###<-------------------------------------------------------------- ###<--- ログファイル読み込み ###<-------------------------------------------------------------- sub dataread { #<<<ログ読み込み if ( !(open(IN,"$logfile"))) { &error("ログファイル($logfile)のオープンに失敗しました"); } @FINDTBL = split(/ /,$FORM{'word'}); #検索文字列 foreach ( ) { ($regdate,$no1,$no2,$name,$email,$hp,$ttl,$comment,$resno,$col,$pass,$imgfile,$hst,$dt) = split(/,/,$_); $found = 0 ; if ( $FORM{'word'} ) { $cnt = @FINDTBL ; if ( $cnt > 0 ) { foreach $buf ( @FINDTBL ) { #検索文字列 if ( index($name,$buf) >= 0 ) { $found = 1 ; last ;} if ( index($email,$buf) >= 0 ) { $found = 1 ; last ;} if ( index($hp,$buf) >= 0 ) { $found = 1 ; last ;} if ( index($ttl,$buf) >= 0 ) { $found = 1 ; last ;} if ( index($comment,$buf) >= 0 ) { $found = 1 ; last ;} } } else { $found = 1 ; } } else { $found = 1 ; } if ( $found == 1 ) { if ( $resno eq '' ) { push(@MAINLOG,"$_") ; } else { push(@RESLOG,"$_") ; } $maxno = $no1 if ( $maxno < $no1 ); if ( $resno ne '' ) { if ( $RESNAME[$resno] eq '' ) { $RESNAME[$resno] = $name ; } $rescnttbl[$resno]++ ; #返信数をカウント } } } close(IN); if ( $FORM{'action'} eq '' && $FORM{'new'} == 1 ) { @MAINLOG = sort @MAINLOG ; @MAINLOG = reverse @MAINLOG ; $dm = @MAINLOG; for ( $i = 0 ; ( $i < $newdata ) && ( $i < $dm ); $i++ ) { push(@NEW,$MAINLOG[$i]); } @MAINLOG = @NEW ; } @RESLOG = reverse @RESLOG if ( $resflg == 0 ) ; #表示対象ページの先頭データ件数を算出 $dm = @MAINLOG; if ( $dm % $pagemax == 0) { $p = $dm / $pagemax ; } else { $p = $dm / $pagemax + 1; } $p = sprintf("%3d",$p); if ( $FORM{'disppage'} ) { $d = $FORM{'disppage'} * $pagemax - $pagemax ; } else { $d = 0 ; $FORM{'disppage'} = 1 ; } #<<<カウンターファイル読み込み(直前のリモホと同一の場合はカウントしない) if ( $cntfile ) { &GetHost ; if ( !(open(IN,"$cntfile"))) { &error("カウンターファイル($cntfile)のオープンに失敗しました"); } $found = 0 ; foreach ( ) { ($cntno,$cnt,$hst) = split(/,/,$_); $hst =~ s/\n//g; if ( $FORM{'no2'} == $cntno ) { if ( $FORM{'up'} == 1 && $hst ne $host ) { $cnt++ ; $hst = $host ; } $found = 1 ; } $LOOK{$cntno} = $cnt ; push(@new,"$cntno,$cnt,$hst\n") ; } if ( $found == 0 ) { $LOOK{$FORM{'no2'}} = 1 ; push(@new,"$FORM{'no2'},1,$host\n") ; } close(IN); if ( $FORM{'up'} == 1) { if ( !(open(OUT,">$cntfile"))) { &error("カウンターファイル($cntfile)のオープンに失敗しました"); } print OUT @new; close(OUT); } } } ###<-------------------------------------------------------------- ###<--- ログ一覧表示 ###<-------------------------------------------------------------- sub listdisp { &dataread ; #<<<ログ読み込み if ( $FORM{'action'} eq "list" ) { #一覧表示モードの場合 if ( $FORM{'new'} ) { print "- 新着記事$newdata件を表\示しています -\n" ; print "    記事一覧に戻る

\n" ; } elsif ( $timemode eq "0" ) { print "- $newtime時間以内に投稿されたものには  が\表\示されます -

\n"; } } $z = 1 ; if ( $FORM{'action'} eq "list" ) { #一覧表示モードの場合$pagemax数の記事を表示 for ( $i = $d ; ( $z <= $pagemax ) && ( $i < $dm ); $i++ ) { ($regdate,$no1,$no2,$name,$email,$hp,$ttl,$comment,$resno,$col,$pass,$imgfile,$hst,$dt) = split(/,/,$MAINLOG[$i]); print "\n"; print " \n"; print " \n"; print " \n"; print " \n"; print "
$ttl"; if ( $regdate ge $newday && $timemode eq "0" ) { print ""; } else { print " "; } print " $regdate
\n"; $z++ ; } } else { #トップページトピックスの場合$topimax数の記事を表示 for ( $i = $d ; ( $z <= $topimax ) && ( $i < $dm ); $i++ ) { ($regdate,$no1,$no2,$name,$email,$hp,$ttl,$comment,$resno,$col,$pass,$imgfile,$hst,$dt) = split(/,/,$MAINLOG[$i]); print "\n"; print " \n"; print " \n"; print " \n"; print " \n"; print "
$regdate  $ttl"; if ( $regdate ge $newday && $timemode eq "0" ) { print ""; } else { print " "; } print "
\n"; $z++ ; } } if ( $FORM{'action'} eq "list" ) { #一覧表示モードの場合下記を表示 &scrl ; } else { print "\n"; print " \n"; print " \n"; print " \n"; print " \n"; print "
※ 新着 $topimax 件を表\示しています。→ $title一覧はこちら
\n"; } } ###<-------------------------------------------------------------- ###<--- ログ表示 ###<-------------------------------------------------------------- sub view { $filelock ; &dataread if ( $FORM{'action'} ne '' && $FORM{'action'} ne 'info') ;#<<<ログ読み込み &fileunlock ; print "Content-type: text/html; charset=Shift_JIS\n\n"; print<<"_EOF_"; #記事表示ページのヘッダHTMLを記述 $html_tophtml _EOF_ if ( $maru == 0 ) { $sp = 3 ; } else { $sp = 0 ; } foreach ( @MAINLOG ) { ($regdate,$no1,$no2,$name,$email,$hp,$ttl,$comment,$resno,$col,$pass,$imgfile,$hst,$dt) = split(/,/,$_); $dt =~ s/\n//g ; if ( $FORM{'no2'} == $no2 ) { #詳細ページ表示エリア print "\n"; print "\n"; print " \n"; print " "; print " \n"; print "\n"; print "\n"; print " \n"; print " \n"; print " \n"; print "
\n"; if ( !($ttl) ) { $ttl = "(無題)" ; } print "

$ttl

\n"; print "

\n"; print "\n"; $no = sprintf("%d",$no); print "-- $dt..No.\[$no2\]

"; $comment =~ s/([^=^\"]|^)(http|ftp)([\w|\!\#\&\=\-\%\@\~\;\+\:\.\?\/]+)/$1$2$3<\/a>/g; print "

$comment

\n"; if( $imgfile ) { print "
"; } if ( $sizeflg == 1 ) { ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $uptime, $mtime, $ctime, $blksize, $blocks) = stat($imgfile); local ($file) = $imgfile =~ /([^\/]+)$/; #u010515 $size = int ((-s "$UpFolder$file") / 1024); #u010515 print "

画像ファイルサイズ [ $size" ."kb ]

\n"; } print "
\n"; print "\n"; print " \n"; print " \n"; print " \n"; print "\n"; #ここまで #ここからレス出力ルーチン if ( @RESLOG > 0 ) { $sw = 0 ; foreach ( @RESLOG ) { ($regdate,$n1,$n2,$name,$email,$hp,$ttl,$comment,$resno,$col,$pass,$imgfile,$hst,$dt) = split(/,/,$_); if ( $no1 == $n1 ) { if ( $sw == 0 ) { $wk = $tablesize2 - 100 ; print "

\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; $sw = 1 ; } print ""; print "\n"; print "\n"; print "\n"; print "\n"; } } if ( $sw == 1 ) { print "\n"; print "\n"; print "\n"; print "
" if ( $maru == 0 ) ; print "" if ( $maru == 1 ) ; print "" if ( $maru == 0 ) ; print "" if ( $maru == 1 ) ; print "
\n"; print "$ttl

>>>"; #u010309 $l = length($name); if ( $l >= 14 ) { print "\n"; } else { print "\n"; } if ( $email ne '' ) { print "$name\n"; } else { print "$name\n"; } print "\n"; if ( $hp ne '' ) { print "-[URL]"; } print "  -- $regdate..No.\[$n2\]
 
\n"; print "   \n"; $comment =~ s/([^=^\"]|^)(http|ftp)([\w|\!\#\&\=\-\%\@\~\;\+\:\.\?\/]+)/$1こちら<\/a>/g; print "$comment
 
\n"; print "
" if ( $maru == 0 ) ; print "" if ( $maru == 1 ) ; print "" if ( $maru == 0 ) ; print "" if ( $maru == 1 ) ; print "
\n"; } } print "\n"; } } #レス出力ルーチンここまで print<<"_EOF_"; #記事表示ページの下部HTMLを記述 $html_bottomhtml _EOF_ } ###<-------------------------------------------------------------- ###<--- スクロール ###<-------------------------------------------------------------- sub scrl { $dm = @MAINLOG; if ( $dm % $pagemax == 0) { $p = $dm / $pagemax ;} else { $p = $dm / $pagemax + 1;} $p = sprintf("%3d",$p); print "
\n"; if ( $p > 1 ) { print "\n"; if ( $FORM{'disppage'} + 1 <= $p && $FORM{'disppage'} != 1 ) { $dmy = "colspan=2"; } else { $dmy = ""; } print "\n"; if ( $FORM{'disppage'} !=1 ) { print "\n"; $pag = $FORM{'disppage'} - 1 ; print "\n"; print "\n"; print "\n"; } if ( $FORM{'disppage'} + 1 <= $p ) { print "\n"; $pag = $FORM{'disppage'} + 1 ; print "\n"; print "\n"; print "\n"; } print "
"; for ( $i = 1 ; $i <= $p ; $i++ ) { if ( (!($FORM{'disppage'}) && $i != 1 ) || ( $FORM{'disppage'} && ( $i ne $FORM{'disppage'}) ) ) { print "$i\n"; } else { print "$i\n"; } if ( $i != $p ) { print " "; } } print "
>\" $css_style>
\n"; } } ###<-------------------------------------------------------------- ###<--- ファイルロック設定 ###<-------------------------------------------------------------- sub filelock { if (-e $lockfile) { ($ftm) = (stat($lockfile))[9]; if ($ftm < time - 150) { unlink($lockfile); } } foreach (1 .. 5) { if (-e $lockfile) { sleep(1); } else { open(LOCK,">$lockfile"); close(LOCK); return; } } &error("只今他の方が書き込み中です。ブラウザの「戻る」で戻って再度登録を行って下さい。"); } ###<-------------------------------------------------------------- ###<--- ファイルロック解除 ###<-------------------------------------------------------------- sub fileunlock { if (-e $lockfile) { unlink($lockfile); } } ###<-------------------------------------------------------------- ###<--- ホスト名を取得 ###<-------------------------------------------------------------- sub GetHost { $host = $ENV{'REMOTE_HOST'}; $addr = $ENV{'REMOTE_ADDR'}; if ($host eq "" || $host eq "$addr") { ($p1,$p2,$p3,$p4) = split(/\./,$addr); $temp = pack("C4",$p1,$p2,$p3,$p4); $host = gethostbyaddr("$temp", 2); if ($host eq "") { $host = $addr; } } foreach $buf(@DANGER_LIST){ if ( $buf ) { # パターンマッチを変換 $buf=~ s/\./\\./g; $buf=~ s/\?/\./g; $buf=~ s/\*/\.\*/g; if($ENV{'REMOTE_HOST'} =~ /$buf/gi){ &error("\申\し\訳ありません。
あなたのプロバイダーからは投稿できませんでした. "); } } } } ###<-------------------------------------------------------------- ###<--- HTMLヘッダー書き出し ###<-------------------------------------------------------------- sub header { print "Content-type: text/html; charset=Shift_JIS\n\n"; print<<"_EOF_"; $title 一覧画面 新着情報

_EOF_ } # ↑ この _EOF_ は消去不可 ###<-------------------------------------------------------------- ###<--- HTMLフッダー書き出し ###<-------------------------------------------------------------- sub footer { print "\n"; } #=================================================================================== # 過去ログ一覧出力ページ設定 ===================================================== #=================================================================================== # 過去ログ一覧ページ上段のHTMLを記述 から sub listtop{ print "Content-type: text/html; charset=Shift_JIS\n\n"; print<<"_EOF_"; $title

$title

検索:  

_EOF_ } # ↑ この _EOF_ は消去不可 #----------------------------------------------------------------------------------- # 過去ログ一覧ページ下段のHTMLを記述 まで sub listbottom{ print<<"_EOF_";

 

_EOF_ } # ↑ この _EOF_ は消去不可 #-----------------------------------------------------------------------------------