#!/usr/bin/perl #****************************************************************************** #variable.cgi - Variable Board Ver.1.06 # #Version :1.06 #Modified :2001/10/23 #Copyright :The Room #E-Mail :dream@lib.net #URL :http://dream.lib.net/room/ # #これはフリー素材です。 #転載・商用目的の利用の際には、メールをお願いします。 # #****************************************************************************** #1行目のperlのディレクトリ指定は、サーバによって異なります。 #詳しくは、管理者にお聞きください。 #****************************************************************************** # # パスの設定は、指定が無い限り相対パスで。 # 「〜は 1 を設定」と書いてあるものは、0を設定することで、 # その機能が無効になります。 # #****************************************************************************** #jcode.pl のパス $jcode = './jcode.pl'; #ログファイルのパス $logfile = './log.dat'; #スキンデータファイルのパス $skindatafile = './skinset.cgi'; #メインスキンのパス $mainskin[0] = './bbs_main.html'; #レススキンのパス $resskin[0] = './res.html'; #メッセージスキンのパス $messkin[0] = './message.html'; #カウンタ用ライブラリのパス(カウンタ使用時のみ) $countlib = './counter.cgi'; #カウンタ用ファイルのパス(カウンタ使用時のみ) $countfile = './count.dat'; #gifcat.pl のパス(グラフィックカウンタ使用時のみ) $gifcat = './gifcat.pl'; #IP保存用ファイルのパス(カウンタでIPチェックを行う場合のみ) $ipfile = './ipdata.dat'; #****************************************************************************** #管理用パスワード $adminpass = 'rockrocket'; #管理人しか親記事書き込み不可にするなら 1 を。 $parentlimit = 0; #管理人しかレス記事書き込み不可にするなら 1 を。 $reslimit = 0; #ホームページのURL(リンクが貼られます) $homeurl[0] = 'http://www.morguesidecinema.com/'; #****************************************************************************** #i-mode/J-Sky/ドットi対応にするなら 1 を設定。 # メソッドの自動変換、改行コードの削除が行われます。 $automethod = 1; #絵文字を削除する場合は 1 を設定。 $piclet[1] = 1;#i-mode $piclet[2] = 1;#J-Sky #$piclet[3] = 1;#ドットi(未実装) #各端末のホームページURL(リンクが貼られます) $homeurl[1] = 'http://xxx.yyy.zzz/i/';#i-mode $homeurl[2] = 'http://xxx.yyy.zzz/j/';#J-Skyweb $homeurl[3] = 'http://xxx.yyy.zzz/d/';#ドットi #端末毎に別のスキンを使用する場合は設定。 #例:$mainskin[1]='./main-i.html'; $mainskin[1]='';$resskin[1]='';$messkin[1]='';#i-mode $mainskin[2]='';$resskin[2]='';$messkin[2]='';#J-Skyweb $mainskin[3]='';$resskin[3]='';$messkin[3]='';#ドットi #****************************************************************************** #デフォルトの名前(未設定だと入力必須) $defaultname = 'No Name'; #デフォルトのタイトル(未設定だと入力必須) $defaulttitle = 'No Title'; #最大ログ数 $maxlog = 50; #1ページに表示するログ数 $pagein = 10; #親記事の最大書き込み字数( 0 だと無制限) $maxparent = 800; #レス記事の最大書き込み字数( 0 だと無制限) $maxres = 400; #使用を許可するタグ(全て使用不可能にする場合は、@permittag = (); ) @permittag = ('i','b','font'); #レスがついた記事を一番上に移動させるなら 1 を設定。 $resmove = 0; #時間表示の設定 # $year 年/$month 月/$day 日/$hour 時/$min 分/$sec 秒/$week 曜日 sub timeset{return "$month/$day($week) $hour:$min";} #時刻表示のゼロ補完の有無 # 10以下を表示するときは 04 のように頭に 0 を追加します。 # この機能を使う場合は 1 を、使わない場合は 0 を。 $spzero[4] = 0;#月の補完 $spzero[3] = 0;#日の補完 $spzero[2] = 0;#時の補完 $spzero[1] = 1;#分の補完 $spzero[0] = 0;#秒の補完 #曜日の設定(日〜土の順番) @weekday = ("Sun","Mon","Tue","Wed","Thr","Fri","Sat"); #グリニッジ標準時からのずれ(秒単位で指定) $areatime = 32400; #****************************************************************************** #IPをソースに表示するなら 1 を設定。 $ipindicate = 1; #二重投稿を禁止する場合は 1 を設定。 $dblcheck = 1; #URLが書かれたら自動的にリンクを貼る場合は 1 を設定。 $autolink = 1; #他ページからの投稿を禁止するなら 1 を設定。 # i/j/D対応の時は、自動的に 0 になります。 $refcheck = 0; #スクリプトを置くURL(http://〜の絶対パス) $scripturl = 'http://127.0.0.1/dev/variable/variable.cgi'; #アクセス拒否をするホストを設定 #例:@acsdeny = ("xxx.yyy.ne.jp","aaa.bbb.co.jp"); @acsdeny = (); #****************************************************************************** #カウンタを使用しないなら 0 を、テキストカウンタなら 1 を、 #画像を使用したカウンタなら 2 を設定。 # i/j/D対応の場合、画像カウンタは使用不可。 $counter = 0; #テキストカウンタなら、カウンタ表示色を設定。 $countcolor = '#000000'; #画像カウンタなら、画像の入っているディレクトリを指定 $imgdir = './countimg'; #表示桁数 $figure = 6; #IPで重複カウントのチェックを行うなら 1 を設定。 # 同時にアクセスログも取得されます。 $ipcheck = 1; #上で 1 を設定した場合、アクセスログの最大数を設定。 # アクセスログを取得したくない場合は 0 を。 $maxaccess = 200; #アクセスログを管理人しか見られないようにする場合は 1 を設定。 # パスワード認証が必要になります。 $logcheck = 1; #****************************************************************************** require $jcode; require $skindatafile; #データ受け取り $cl = $ENV{"CONTENT_LENGTH"}; if( $cl > 0 ){ read(STDIN, $qs, $cl ); }else{ $qs = $ENV{"QUERY_STRING"}; } @contents = split(/&/,$qs); foreach $i (0 .. $#contents) { local($key,$text)= split(/=/,$contents[$i]); $text =~ s/\+/ /g; $text =~ s/%(..)/pack("c",hex($1))/ge; $text =~ s/\r\n/\n/g; $text =~ s/&/&/g; $text =~ s/\$/$/g; if ($key eq 'msg'){ $text =~ s/\a|\t//g; $text =~ s//\a/g; }else{ $text =~ s//>/g; } $text =~ s/\G((?:[\x80-\x9F\xE0-\xF7\xFA-\xFC][\x40-\xFF]|[\x00-\x7F])*?)(?:[\xF8\xF9][\x40-\x7E\x80-\xAF])/$1/go if $piclet[1]; $text =~ s/\x1b\$.+\x0f//g if $piclet[2]; &jcode::convert(\$text,"sjis"); $act = $text if $key eq 'act'; $check = $text if $key eq 'check'; $page = $text if $key eq 'page'; $num = $text if $key eq 'num'; $msg = $text if $key eq 'msg'; $name = $text if $key eq 'name'; $url = $text if $key eq 'url'; $mail = $text if $key eq 'mail'; $title = $text if $key eq 'title'; $msg = $text if $key eq 'msg'; $pass = $text if $key eq 'pass'; $delpass = $text if $key eq 'delpass'; foreach $i(@additemname){ $additemvalue{$i}=$text if $key eq $i; } $getdata{$key}=1; } $page||=0; if ($act eq "imgcount"){ require $countlib; &count; exit; } #環境変数取得 $ip = $ENV{'REMOTE_ADDR'}; $host = gethostbyaddr(pack("C4", split(/\./, $ip)), 2); $host = $ENV{'REMOTE_HOST'} if $host eq ""; $host = $ip if $host eq ""; $user_agent = $ENV{'HTTP_USER_AGENT'}; #アクセス制御 foreach(@acsdeny){&error("あなたのホストからのアクセスは禁止されています。") if $host =~ /$_/i;} #端末チェック $method = "post"; $target = "./variable.cgi"; if($automethod){ $terminal = 0; if ($user_agent =~ /DoCoMo/){ $terminal = 1; } elsif ($user_agent =~ /^J-PHONE\/(\d+)\.(\d+)/){ $method = "get" if $1 == 2; $terminal = 2; $target=$scripturl; } elsif ($user_agent =~ /^ASTEL/){ $terminal = 3; } if($terminal){ $automethod = 2; $refcheck=0; $target=$scripturl; $homeurl[0] = $homeurl[$terminal]; $mainskin[0] = $mainskin[$terminal] if $mainskin[$terminal] ne ""; $resskin[0] = $resskin[$terminal] if $resskin[$terminal] ne ""; $messkin[0] = $messkin[$terminal] if $messkin[$terminal] ne ""; } } #クッキー設定 for $a1 (split(/; */, $ENV{'HTTP_COOKIE'})) { ($key, $text) = split(/=/, $a1); $text =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/eg; $COOKIE{$key}=$text; } if (($act eq "res") || ($act eq "write")){ #書き込み $name = $defaultname if $name eq ""; $title = $defaulttitle if $title eq ""; $act = "" if $msg eq ""; print "Set-Cookie:name=$name; expires=Thu, 1-Jan-2030 00:00:00 GMT;\n"; print "Set-Cookie:mail=$mail; expires=Thu, 1-Jan-2030 00:00:00 GMT;\n"; print "Set-Cookie:url=$url; expires=Thu, 1-Jan-2030 00:00:00 GMT;\n"; print "Set-Cookie:pass=$pass; expires=Thu, 1-Jan-2030 00:00:00 GMT;\n"; foreach(@additemname){ if($getdata{$_}){ print "Set-Cookie:$_=$additemvalue{$_}; expires=Thu, 1-Jan-2030 00:00:00 GMT;\n"; }else{ $additemvalue{$_}=$COOKIE{$_}; } } }else{ #読み込み $name = $COOKIE{'name'} || $defaultname; $url = $COOKIE{'url'}; $mail = $COOKIE{'mail'}; $pass = $COOKIE{'pass'}; foreach(@additemname){ $additemvalue{$_}=$COOKIE{$_}; } } for(0 .. $#additemname){ $additemvalue{$additemname[$_]} = $additemdefd[$_] if $additemvalue{$additemname[$_]} eq ""; $additemvalue{$additemname[$_]} = "" if $additemname[$_] !~ /^add\_/i; } if ($act eq "write"){&write;} elsif ($act eq "resform"){&resform;} elsif ($act eq "res"){&res;} elsif ($act eq "del"){&del;} elsif ($act eq "accesslog"){ if ((!$logcheck) || (($logcheck) && ($delpass eq $adminpass))){ require $countlib; &accesslog; }else{ &accesscheck; } } &read; #******************************************************************************* sub accesscheck{ #アクセスログ認証 my $msg = < パスワードを入力してください。

EOD &error($msg); } #******************************************************************************* sub del{ #記事削除 &error("記事番号を入力してください。") if $num eq ""; &error("パスワードを入力してください。") if $delpass eq ""; my ($flag,@temp1,@log,$msg); open(IO,"+<$logfile"); eval{flock(IO,2)}; while(){ @temp1 = split(/<>/,$_); $flag = 0 if $temp1[1] == 0; if ($temp1[0] == $num){ if ((crypt($delpass,$temp1[6]) eq $temp1[6]) || ($delpass eq $adminpass)){ if ($temp1[1]){ $msg = "$num番の記事を削除しました。"; }else{ $flag = 1; $msg = "$num番とそのレス記事を削除しました。"; } }else{ close(IO); &error("パスワードが間違っています。"); } }else{ push(@log,$_) if !$flag; } } if (!$msg){ close(IO); &error("記事番号が間違っています。"); } truncate(IO,0); seek(IO,0,0); print IO @log; close(IO); &error($msg); } #******************************************************************************* sub res{ #レス入力 if (($pass ne $adminpass) && ($reslimit)){ &error("管理人以外は書き込み出来ません。"); } &writecheck; $msg =~ s/
//ig if ($skintype == 2); $msg = substr($msg,0,$maxres) if $maxres != 0; my ($a1,$a2,$a3,$ct,@temp1,@temp2,$add,$parents); foreach(@additemname){$add.="$_=$additemvalue{$_}|";} $a1="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./"; $a2=substr($a1,int(rand(64)),1).substr($a1,int(rand(64)),1); my $cryptpass=crypt($pass,$a2); $ct = $a1 = $a3 = $a4 = $parent = 0; $a2 = ""; open(IO,"+<$logfile"); eval{flock(IO,2)}; while(){ @temp1 = split(/<>/,$_); if ($a1 < $temp1[2]){ $a1 = $temp1[2]; $a2 = $temp1[9]; } $a3 = $temp1[0] if $temp1[0] > $a3; if ($temp1[1] == 0){ $parents++; $ct = 0; if ($temp1[0] == $num){ $ct = 1; $a4 = $#log+1 if !$resmove; push(@temp2,$_); }else{ push(@log,$_); } } elsif($ct){ push(@temp2,$_); }else{ push(@log,$_); } } if ((($a2 eq $msg) && ($dblcheck)) || ($temp2[0] eq "")){ close(IO); &error("記事の指定が不正です。") if !$temp2[0]; &error("二重投稿は禁止されています。"); } $a3++; push(@temp2,"$a3<>1<>".time()."<>$name<>$mail<>$url<>$cryptpass<>$add<><>$msg<>$ip/$host<>\n"); splice(@log,$a4,0,@temp2); truncate(IO,0); seek(IO,0,0); print IO @log; close(IO); $nextflag = 1 if $parents > $pagein; &page_analize($mainskin[0]); &page_setting; } #******************************************************************************* sub resform{ #レス入力フォーム open(IN,$logfile); eval{flock(IN,1)}; while(){ last if ($flag) && ($_ =~ /^\d+<>0<>/); $flag = 1 if $_ =~ /^$num<>/; push(@log,$_) if $flag; } close(IN); &error("記事の指定が不正です。") if !$flag; &page_analize($resskin[0]); &page_setting; } #******************************************************************************* sub write{ #書き込み if (($pass ne $adminpass) && ($parentlimit)){ &error("管理人以外は書き込み出来ません。"); } &error("タイトルを入力してください。") if !$title; &writecheck; $msg = substr($msg,0,$maxparent) if $maxparent != 0; my ($a1,$a2,$a3,$ct,@temp1,@temp2,$add); foreach(@additemname){$add.="$_=$additemvalue{$_}|";} $a1="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./"; $a2=substr($a1,int(rand(64)),1).substr($a1,int(rand(64)),1); my $cryptpass=crypt($pass,$a2); $ct = $a1 = $a3 = 0; $a2 = ""; open(IO,"+<$logfile"); eval{flock(IO,2)}; while(){ @temp1 = split(/<>/,$_); if ($a1 < $temp1[2]){ $a1 = $temp1[2]; $a2 = $temp1[9]; } $a3 = $temp1[0] if $temp1[0] > $a3; if ($temp1[1] == 0){ $ct++; push(@log,@temp2); @temp2=(); } push(@temp2,$_); } if (($a2 eq $msg) && ($dblcheck)){ close(IO); &error("二重投稿は禁止されています。"); } push(@log,@temp2) if $ct < $maxlog; $a3++; unshift(@log,"$a3<>0<>".time()."<>$name<>$mail<>$url<>$cryptpass<>$add<>$title<>$msg<>$ip/$host<>\n"); truncate(IO,0); seek(IO,0,0); print IO @log; close(IO); $ct++; $nextflag = 1 if $ct > $pagein; &page_analize($mainskin[0]); &page_setting; } #******************************************************************************* sub read{ #読み込み &page_analize($mainskin[0]); my $ct = -1; open(IN,$logfile) || die &error("ログファイルが開けません。"); eval{flock(IN,1)}; while(){ if ($_ =~ /^\d+<>0<>/){ $ct++; if ($ct >= $pagein*$page){ if ($ct >= $pagein*($page+1)){ $nextflag = 1; last; } push(@log,$_); } } elsif ($ct >= $pagein*$page){ push(@log,$_); } } close(IN); &page_setting; } #****************************************************************************** sub page_setting{ #スキンに従って表示設定 my $ct = -1; my ($a1,$a2,@temp1,$subbuffer1,$subbuffer2,$mainbuffer,$i); foreach(@log){ @temp1 = split(/<>/,$_); if ($temp1[1] == 0){ #親記事 $ct++ if $temp1[1] == 0; last if $ct >= $pagein; #変数リセット $subbuffer1 =~ s/\n/$subbuffer2/i; $mainbuffer .= $subbuffer1; $subbuffer1 = $buffer[1]; $subbuffer2 = ""; #親記事セット &art_setting($subbuffer1,@temp1); if ($skintype == 1){ $a1 = "$target?act=resform&num=$temp1[0]"; $subbuffer1 =~ s/\n([^\n]*)\$reslink([^\n]*)\n/\n$1$a1$2\n/ig; } elsif ($skintype == 2){ $subbuffer1 =~ s///i; } }else{ #レス記事セット $a2=$buffer[2]; &art_setting($a2,@temp1); $subbuffer2.=$a2; } } $subbuffer1 =~ s/\n/$subbuffer2/i; $mainbuffer .= $subbuffer1; if ($qs eq ""){$check=1;}else{$check=0;} if ($counter == 1){ require $countlib; $a1 = &count; $buffer[0] =~ s/\$counter/$a1<\/font>/ig; } elsif ($counter == 2){ $buffer[0] =~ s/\$counter//ig; } if ($page != 0){ $a1=$page-1; $buffer[0] =~ s/\n([^\n]*)\$prevpage([^\n]*)\n/\n$1.\/variable.cgi?page=$a1$2\n/ig; }else{ $buffer[0] =~ s/\n([^\n]*)\$prevpage([^\n]*)\n/\n/ig; } if ($nextflag){ $a1=$page+1; $buffer[0] =~ s/\n([^\n]*)\$nextpage([^\n]*)\n/\n$1.\/variable.cgi?page=$a1$2\n/ig; }else{ $buffer[0] =~ s/\n([^\n]*)\$nextpage([^\n]*)\n/\n/ig; } $buffer[0] =~ s//$mainbuffer/ig; $buffer[0] =~ s///i if $act eq "resform"; $buffer[0] =~ s//
/ig; #追加項目達。 for(0 .. $#additemname){ if ($additemtype[$_] == 0){ #radio $buffer[0] =~ s/((.*<\/select>)\n/$1 selected>$2\n/i; }else{ #text $buffer[0] =~ s/(){ $_ =~ s/\r\n/\n/g; if (($_ =~ /\n/i) || ($_ =~ /\n/i)){ $point = 1; } elsif ($_ =~ /\n/i){ $point = 2; } elsif ($_ =~ /\n/i){ $point = 0; } $buffer[$point].=$_; } close(IN); } #******************************************************************************* sub error{ #メッセージ・エラー表示 $buffer[0]=""; open(IN,$messkin[0]); while(){$buffer[0].=$_;} close(IN); $buffer[0] =~ s/\$message/$_[0]/ig; &output; } #******************************************************************************* sub timesub{ #時刻設定 my @temp1 = gmtime($_[0]+$areatime); $temp1[5]+=1900;$temp1[4]++; for(0 .. 4){$temp1[$_] = "0".$temp1[$_] if ($temp1[$_] < 10) && ($spzero[$_]);} ($sec,$min,$hour,$day,$month,$year)=@temp1; $week=$weekday[$temp1[6]]; return ×et; } #******************************************************************************* sub writecheck{ #書き込み前準備 if (($ENV{'HTTP_REFERER'} !~ /^$scripturl/i) && ($refcheck)){ &error("別ページからの投稿は禁止されています。"); } &error("メッセージを入力してください。") if !$msg; &error("お名前を入力してください。") if !$name; while(1){if (!(chomp($msg))){last;}} #許可タグ以外を無効にする foreach (@permittag){ $msg =~ s/\t(\/?$_)\a/<$1>/ig; $msg =~ s/\t$_ ([^\a]*)\a/<$_ $1>/ig; } $msg =~ s/\t/</g; $msg =~ s/\a/>/g; #自動タグ閉じ foreach (@permittag){ if (($msg =~ /<$_/i) && ($msg !~ /<\/$_/i)){$msg .="<\/$_>";} } #URLには自動的にリンクを行う if (($autolink) && ($msg !~ /$1<\/A>/g; } $msg =~ s/\n/
/g; } #*******************************************************************************