#!/usr/bin/perl ############################################### # bbs10.cgi # V2.0 (2004.8.9) # Copyright(C) CGI-design ############################################### require 'cgi-lib.pl'; $script = 'bbs10.cgi'; $base = './bbsdata'; #データ格納ディレクトリ $bbsfile = "$base/bbs.txt"; #記事 $nofile = "$base/no.txt"; #記事番号 $opfile = "$base/option.txt"; #オプション $lockfile = "$base/lock"; #ロック $cgi_lib'maxdata = 300000; #入力最大容量(byte) open (IN,"$opfile") || &error("OPEN ERROR"); $opdata = ; close IN; if (!$opdata) { $pass = &crypt('cgi'); chmod(0666,$opfile); open (OUT,">$opfile") || &error("OPEN ERROR"); print OUT "$pass<>掲示板<><><><>$base<>$base<>#ffffff<>#000000<>#800000<>#c00000<>#0000ff<>#eeeeee<>#fef5da<>#ffffff<>#aaaaaa<>24<>5<>50<>1<>200<>200"; close OUT; chmod(0666,$bbsfile); chmod(0666,$nofile); } ### メイン処理 ### &ReadParse; while (($n,$val) = each %in) { if ($n eq 'img') {next;} $val =~ s/&/&/g; $val =~ s//>/g; $val =~ s/"/"/g; $in{$n} = $val; } $mode = $in{'mode'}; $wrt = $in{'wrt'}; $num = $in{'num'}; open (IN, "$opfile") || &error("OPEN ERROR"); ($pass,$title,$com_adm,$home,$bg_img,$savedir,$loaddir,$bg_color,$text_color,$title_color,$sub_color,$name_color,$subbg_color,$new_color,$com_color,$frame_color,$newhour,$page,$logmax,$img_dsp,$max_w,$max_h) = split(/<>/,); close IN; if (!$page) {$page = 5;} $nowtime = time; $newtime = $nowtime - $newhour * 3600; if ($mode eq 'resin') {&resin;} elsif ($mode eq 'edtin') {&edtin;} elsif ($mode eq 'admin') {&admin;} else {&main;} print "\n"; exit; ### sub header { print "Content-type: text/html\n\n"; print "\n"; print "$title\n"; $head = 1; } ### sub main { if ($wrt eq 'new') {&newwrt;} elsif ($wrt eq 'edt') {&edtwrt;} elsif ($wrt eq 'del') {&delwrt;} &header; print "
\n"; print "
"; if ($home) {print "[HOME]";} print "$title
\n"; if (!$num) { if ($com_adm) {print "
$com_adm
\n";} &getcook; &in_form; } $back = $num - $page; $next = $num + $page; $sum = 0; $m = -1; $start = 1; open (IN,"$bbsfile") || &error("OPEN ERROR"); while () { ($no,$rno,$time,$date,$img_type,$img_w,$img_h,$img_big,$name,$mail,$hp,$sub,$com) = split(/<>/); $sum++; if (!$rno) {$m++;} if ($m < $num || $next <= $m) {next;} if (!$rno && !$start) {print "\n";} &bbs_dsp; $start = 0; } close IN; print "\n"; print "
\n"; if (0 <= $back) { print "\n"; } if ($next <= $m) { print "\n"; } if ($page <= $m) { print "\n"; } print "
\n"; print "\n"; print "
\n"; print "\n"; print "
\n"; $i = 1; for ($k=0; $k<=$m; $k+=$page) { if ($k == $num) {print "\n";} else {print "\n";} $i++; } print "
P$iP$i
全 $sum件  [管理]
\n"; # 次の行は著作権表示ですので削除しないで下さい。# print "CGI-design\n"; } ### sub bbs_dsp { if (!$rno || $mode eq 'edtin') { print "
\n"; if ($rno) {print "
";} } else {print "
\n";} if ($newtime < $time) {$bc_head = $new_color;} else {$bc_head = $subbg_color;} print "\n"; print "\n"; if (!$mode) { if (!$rno) { print "\n"; } print ""; } print "
 $sub  $name   $date\n"; if ($hp) {print " HP\n";} if ($mail) {print " Mail";} print "
\n"; print "\n"; print "\n"; print "
[修正]
\n"; if (!$rno) {print "
\n";} print "\n"; if ($img_type) { print "\n"; } $com =~ s/([^=^\"]|^)(http\:[\w\.\~\-\/\?\&\+\=\:\@\%\;\#\%]+)/$1$2<\/a>/g; print "
"; $imgfile = "$loaddir/$no.$img_type"; $imgsrc = ""; if ($img_big) {print "$imgsrc";} else {print $imgsrc;} print "$com
\n"; } ### sub in_form { print "
\n"; print "\n"; if (!$mode) { print "\n"; &getcook; $sub=$com=''; $submit = '投稿する'; } elsif ($mode eq 'resin') { print "\n"; print "\n"; &getcook; $sub=$com=''; $submit = '返信する'; } else { print "\n"; print "\n"; print "\n"; print "\n"; $com =~ s/
/\r/g; $pwd = ''; $submit = '修正する'; } print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; if ($img_dsp) {print "\n";} print "\n"; print "
名前
メール
HP
題名

内容
画像
修正キー (英数8文字以内)
\n"; if ($mode eq 'edtin') { print "\n"; } print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "

\n"; } ### sub newwrt { &in_chk; ($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime; $year += 1900; $mon++; $week = ('日','月','火','水','木','金','土')[$wday]; $nowdate = sprintf("$year年$mon月$mday日($week) $hour:%02d",$min); if ($in{'pwd'} ne '') {$pwd = &crypt($in{'pwd'});} else {$pwd = '';} $addr = $ENV{'REMOTE_ADDR'}; &lock; open (IN,"$nofile") || &error("OPEN ERROR"); $no = ; close IN; $no++; open (OUT,">$nofile") || &error("OPEN ERROR"); print OUT $no; close OUT; &img("$savedir/$no",'img'); $newdata = "$no<>$in{'rno'}<>$nowtime<>$nowdate<>$type<>$width<>$height<>$big<>$in{'name'}<>$in{'mail'}<>$in{'hp'}<>$in{'sub'}<>$in{'com'}<>$pwd<>$addr<>\n"; if (!$in{'rno'}) { $i=$stop=0; open (IN,"$bbsfile") || &error("OPEN ERROR"); while () { ($no,$rno,$time,$date,$img_type) = split(/<>/); $i++; if ($logmax && $logmax <= $i && !$rno) {$stop = 1;} if (!$stop) {push(@new,$_);} elsif ($img_type) {unlink "$savedir/$no.$img_type";} } close IN; unshift(@new,$newdata); } else { $mat = 0; open (IN,"$bbsfile") || &error("OPEN ERROR"); while () { ($no,$rno) = split(/<>/); if ($no eq $in{'rno'}) {$mat = 1; push(@new,$_);} elsif ($rno eq $in{'rno'}) {push(@new,$_);} else {push(@tmp,$_);} } close IN; if ($mat) {push(@new,$newdata);} push(@new,@tmp); } open (OUT,">$bbsfile") || &error("OPEN ERROR"); print OUT @new; close OUT; &unlock; &setcook; } ### sub in_chk { if (!$in{'name'}) {&error("名前を入力して下さい");} if (!$in{'com'}) {&error("内容を入力して下さい");} $in{'com'} =~ s/\r\n|\r|\n/
/g; $in{'hp'} =~ s/^http\:\/\///; } ### sub resin { &header; print "
\n"; print "
[Return]
\n"; print "***** 返 信 *****
\n"; $mat = 0; open (IN,"$bbsfile") || &error("OPEN ERROR"); while () { ($no,$rno,$time,$date,$img_type,$img_w,$img_h,$img_big,$name,$mail,$hp,$sub,$com) = split(/<>/); if ($no eq $in{'no'} || $rno eq $in{'no'}) {$mat = 1; &bbs_dsp;} elsif ($mat) {last;} } close IN; print "


\n"; &in_form; } ### sub edtin { &header; print "
\n"; print "
[Return]
\n"; open (IN,"$bbsfile") || &error("OPEN ERROR"); while () { ($no,$rno,$time,$date,$img_type,$img_w,$img_h,$img_big,$name,$mail,$hp,$sub,$com,$pwd,$regaddr) = split(/<>/); if ($no eq $in{'no'}) {last;} } close IN; if ($regaddr ne $ENV{'REMOTE_ADDR'}) { if ($in{'pwd'} eq '') { print "



修正キーを入力して下さい

\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
\n"; print "
\n"; exit; } $mat = &decrypt($in{'pwd'},$pass); if (!$mat) { if ($pwd eq '') {&error("該当の記事に修正キーが設定されていません");} $mat = &decrypt($in{'pwd'},$pwd); if (!$mat) {&error("修正キーが違います");} } } print "***** 修正・削除 *****
\n"; $wcom = $com; &bbs_dsp; print "


\n"; $com = $wcom; &in_form; } ### sub in_pwchk { open (IN,"$bbsfile") || &error("OPEN ERROR"); while () { ($no,$rno,$time,$date,$img_type,$img_w,$img_h,$img_big,$name,$mail,$hp,$sub,$com,$pwd,$regaddr) = split(/<>/); if ($no eq $in{'no'}) {last;} } close IN; if ($regaddr eq $ENV{'REMOTE_ADDR'}) {return;} if ($in{'edtpw'} eq '') {&error;} $mat = &decrypt($in{'edtpw'},$pass); if ($mat) {return;} if ($pwd eq '') {&error;} $mat = &decrypt($in{'edtpw'},$pwd); if (!$mat) {&error;} } ### sub edtwrt { &in_pwchk; &in_chk; &img("$savedir/$in{'no'}",'img'); &lock; open (IN, "$bbsfile") || &error("OPEN ERROR"); while () { ($no,$rno,$time,$date,$img_type,$img_w,$img_h,$img_big,$name,$mail,$hp,$sub,$com,$pwd,$regaddr) = split(/<>/); if ($no eq $in{'no'}) { if ($type) {$img_type = $type; $img_w = $width; $img_h = $height; $img_big = $big;} if ($in{'pwd'} ne '') {$pwd = &crypt($in{'pwd'});} push(@new,"$no<>$rno<>$time<>$date<>$img_type<>$img_w<>$img_h<>$img_big<>$in{'name'}<>$in{'mail'}<>$in{'hp'}<>$in{'sub'}<>$in{'com'}<>$pwd<>$regaddr<>\n"); } else {push(@new,$_);} } close IN; open (OUT,">$bbsfile") || &error("OPEN ERROR"); print OUT @new; close OUT; &unlock; } ### sub delwrt { &in_pwchk; &lock; open (IN,"$bbsfile") || &error("OPEN ERROR"); while () { ($no,$rno,$time,$date,$img_type) = split(/<>/); if ($no eq $in{'no'} || $rno eq $in{'no'}) {if ($img_type) {unlink "$savedir/$no.$img_type";}} else {push(@new,$_);} } close IN; open (OUT,">$bbsfile") || &error("OPEN ERROR"); print OUT @new; close OUT; &unlock; } ### sub admin { &header; print "
\n"; print "
[Return]
\n"; $inpass = $in{'pass'}; if ($inpass eq '') { print "



パスワードを入力して下さい

\n"; print "
\n"; print "\n"; print "\n"; print "
\n"; print "
\n"; exit; } $mat = &decrypt($inpass,$pass); if (!$mat) {&error("パスワードが違います");} if ($wrt) { if ($in{'newpass'} ne '') {$pass = &crypt($in{'newpass'});} $title = $in{'title'}; $com_adm = $in{'com'}; $com_adm =~ s/\r\n|\r|\n/
/g; $home = $in{'home'}; $bg_img = $in{'bg_img'}; $savedir = $in{'savedir'}; $loaddir = $in{'loaddir'}; $bg_color = $in{'color0'}; $text_color = $in{'color1'}; $title_color = $in{'color2'}; $sub_color = $in{'color3'}; $name_color = $in{'color4'}; $subbg_color = $in{'color5'}; $new_color = $in{'color6'}; $com_color = $in{'color7'}; $frame_color = $in{'color8'}; $newhour = $in{'newhour'}; $page = $in{'page'}; $logmax = $in{'logmax'}; $img_dsp = $in{'img_dsp'}; $max_w = $in{'max_w'}; $max_h = $in{'max_h'}; open (OUT, ">$opfile") || &error("OPEN ERROR"); print OUT "$pass<>$title<>$com_adm<>$home<>$bg_img<>$savedir<>$loaddir<>$bg_color<>$text_color<>$title_color<>$sub_color<>$name_color<>$subbg_color<>$new_color<>$com_color<>$frame_color<>$newhour<>$page<>$logmax<>$img_dsp<>$max_w<>$max_h"; close OUT; } print "下記に入力後、「設定する」を押して下さい。
\n"; print "
\n"; print "\n"; print "\n"; print "

\n"; print "
\n"; print "\n"; $com_adm =~ s/
/\r/g; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; @name = ('基本背景色','基本文字色','タイトル色','題名色','名前色','見出し帯色','新記事の見出し帯色','記事背景色','記事枠色'); @data = ($bg_color,$text_color,$title_color,$sub_color,$name_color,$subbg_color,$new_color,$com_color,$frame_color); for (0 .. $#name) { print "\n"; } print "\n"; print "\n"; if ($img_dsp) {$chk = ' checked';} else {$chk = '';} print "\n"; print "\n"; print "
タイトル
コメント
ホームURL
壁紙
画像格納ディレクトリ
画像読出ディレクトリ
カラーコード
$name[$_]\n"; print "\n"; print "
新記事の表\示時間時間
記事表\示件/ページ(親記事数)   最大件(親/返信記事の合計)
画像表\示入力する   横maxpx、 縦maxpx
パスワード変更 (英数8文字以内)
\n"; } ### sub img { $type=$width=$height=$big=$mac=''; $imgdata = $in{"$_[1]"}; if (!$imgdata) {return;} foreach (@in) { if ($_ =~ /$_[1]/ and $_ =~ /Content-Type:(.+)/i) { if ($1 =~ /image\/.*jpeg/i) {$type = 'jpg';} elsif ($1 =~ /image\/gif/i) {$type = 'gif';} elsif ($1 =~ /image\/.*png/i) {$type = 'png';} } if ($_ =~ /application\/x-macbinary/i) {$mac = 1;} } if (!$type) {&error("このファイルはアップロードできません。");} if ($mac) { $leng = substr($imgdata,83,4); $leng = unpack("%N",$leng); $imgdata = substr($imgdata,128,$leng); } $img_file = "$_[0].$type"; open (IMG,">$img_file") || &error("$img_file画像ファイルを作成できません"); binmode IMG; print IMG $imgdata; close IMG; chmod (0666,$img_file); ($t,$width,$height) = &getImageSize("$img_file"); if (!$width || !$height) {&error("ファイルを認識できません。");} $big = 0; if ($max_w && $max_w < $width) {$rate_w = $max_w / $width; $big = 1;} else {$rate_w = 1;} if ($max_h && $max_h < $height) {$rate_h = $max_h / $height; $big = 1;} else {$rate_h = 1;} if ($big) { if ($rate_w < $rate_h) {$rate = $rate_w;} else {$rate = $rate_h;} $width = int($width * $rate); $height = int($height * $rate); } } #========================================= # Get Image Pixel Size.(出典:stdio-902) #========================================= sub getImageSize { local($file_name) = @_; local($head); return if (!open IMG, $file_name); binmode IMG; read IMG, $head, 8; if ($head eq "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a") { local($width, $height); if (read(IMG, $head, 4) != 4 || read(IMG, $head, 4) != 4 || $head ne 'IHDR') { close IMG; return "PNG", 0; } read IMG, $head, 8; close IMG; $width = unpack "N", substr($head, 0, 4); $height = unpack "N", substr($head, 4, 4); return "PNG", $width, $height; } $head = substr $head, 0, 3; if ($head eq "\x47\x49\x46") { local($head, $width, $height); seek IMG, 6, 0; read IMG, $head, 4; close IMG; ($width, $height) = unpack "vv", $head; return "GIF", $width, $height; } $head = substr $head, 0, 2; if ($head eq "\xff\xd8") { local($head, $width, $height, $w1, $w2, $h1, $h2, $l1, $l2, $length); seek IMG, 2, 0; while (read IMG, $head, 1) { last if ($head eq ""); if ($head eq "\xff") { $head = getc IMG; if ($head =~ /^[\xc0-\xc3\xc5-\xcf]$/) { seek IMG, 3, 1; last if (read(IMG, $head, 4) != 4); close IMG; ($h1, $h2, $w1, $w2) = unpack "C4", $head; $height = $h1 * 256 + $h2; $width = $w1 * 256 + $w2; return "JPG", $width, $height; } elsif ($head eq "\xd9" || $head eq "\xda") { last; } else { last if (read(IMG, $head, 2) != 2); ($l1, $l2) = unpack "CC", $head; $length = $l1 * 256 + $l2; seek IMG, $length - 2, 1; } } } close IMG; return "JPG", 0; } return 0; } ### sub setcook { my($sec,$min,$hour,$mday,$mon,$year,$wday) = gmtime(time+60*24*60*60); $ww = (Sun,Mon,Tue,Wed,Thu,Fri,Sat)[$wday]; $month = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec)[$mon]; $gmt = sprintf("%s, %02d-%s-%04d %02d:%02d:%02d GMT",$ww,$mday,$month,$year+1900,$hour,$min,$sec); $cook = "$in{'name'}<>$in{'mail'}<>$in{'hp'}<>$in{'pwd'}<>"; print "Set-Cookie: bbs10=$cook; expires=$gmt;\n"; } ### sub getcook { if ($wrt eq 'new') { $name = $in{'name'}; $mail = $in{'mail'}; $hp = $in{'hp'}; $pwd = $in{'pwd'}; return; } my($n,$val); foreach (split(/;\s*/,$ENV{'HTTP_COOKIE'})) { ($n,$val) = split(/=/); if ($n eq 'bbs10') {last;} $val = ''; } ($name,$mail,$hp,$pwd) = split(/<>/,$val); } ### sub lock { $retry = 3; if (-e $lockfile) { $locktime = (stat($lockfile))[9]; if ($locktime < time - 60) {&unlock;} } while (!mkdir($lockfile, 0755)) { if (--$retry < 0) {&error("busy!");} sleep(1); } } ### sub unlock {rmdir($lockfile);} ### sub crypt { @salt = ('a' .. 'z','A' .. 'Z','0' .. '9'); srand; $salt = "$salt[int(rand($#salt))]$salt[int(rand($#salt))]"; return crypt($_[0],$salt); } ### sub decrypt { $salt = $_[1] =~ /^\$1\$(.*)\$/ && $1 || substr($_[1],0,2); if (crypt($_[0],$salt) eq $_[1] || crypt($_[0],'$1$' . $salt) eq $_[1]) {return 1;} return 0; } ### sub error { if (!$head) {&header; print "
\n";} print "



ERROR !!

$_[0]\n"; print "
\n"; exit; }