#!/usr/bin/perl #↑パールのアドレス(@ニフティ#!/usr/local/bin/perl)(インフォウェブ#!/usr/bin/perl)必ずあなたの使用しているサーバーのパールの場所を指定します。 #このプログラムの著作権はKXコンピューターシステムズにあります。 #無断使用、コピーはお断りします。このプログラムは無料で配布しています。 #このプログラムの使用に際して、問題があっても一切の保障はできません。 #gazobbs.cgi ver.5.0B 2003.7.26 #一部変更 一部の環境で背景画像が表示されない件をFIX 2003.5.24 #クッキー、削除キー対応、 2003.7.27 #Copyright (c) 2002 KX Computer Systems & Edward Carr, All Rights Reserved #http://www.kx777.com/ #ディレクトリとファイルのパーミッション # CGIのディレクトリ(755 or 777)-gazocgi #  -lock ロックファイルのディレクトリ(777) #  -img1 投稿された画像を入れておくディレクトリ(777) # -gazobbs.cgi(755) # -gazobbs.log(666) # -jcode.pl(755) # -cgi-lib.pl(755) # -img.cgi(755) # 背景画像とメール、ホームページアイコンのディレクトリ(755)-gazoimg # -bbscat1.gif(644) 記事脇の画像(お好きなものに変更してください) # -mail.gif(644) # -home.gif(644) # # 下のURLなどをあなたの実際のURLに変更してください。 # ファイル名も変更してください。このプログラムの文字だけでなく、 # 実際のファイルも名前を変えてください。 #************************************************************************ #パソコンからインターネットに読み込むためのCGIライブラリ require "./cgi-lib.pl"; #画像の制限サイズ(byte 20000なら20Kバイト) $image_max = 60000; #投稿を許可する(管理者専用とするか?) $kyoka=1;#1は許可、1以外は不許可 ##############★重要 $nifty_flg=1;#@ニフティなどCGI用のディレクトリに画像を置くと普通は読めないサーバの場合1にその他のサーバは0に設定してください。1の時はimg.cgiの設定もしてください。(たいてい、Apacheのデフォルトの設定では/cgi-bin/のファイルは、すべて実行ファイルとなるので注意してください。) #この設定を有効にすると、1画像につき1つの読み出し用プログラムを呼び出すことになるので、重くなります。 ##############★ $admin_name = 'KX'; # あなたの名前(ハンドルネーム) $admin_email = 'nashiyo@nainai.come'; # あなたのメールアドレス $master = 'aaaa'; # 管理用のパスワード 2つ設定できます。 $master2 = 'AAAA'; # 管理用のパスワード2 2つとも必ず変えておくこと。 #管理者の入り口は画面の一番したにあります。 $bbs_title = "\画\像\掲\示\板\べ\ー\だ!";#タイトル 漢字の前は\がお勧め。 $back_url = "http://anatano/anatano/index.htm"; #HOME(あなたのホームページに換える) $image_url = "../gazoimg/"; # 背景画像があるURL(@ニフティなどでは絶対URL) ##$image_url = "http://homepage2.nifty.com/nantara-kantara/"; # @ニフティの例 $back_img=""; #背景の画像名 $back_img2="bbscat1.gif"; #記事の脇の背景 $body_text = '#ffffff'; # タグの設定 $body_link = '#ff0000'; $body_alink = '#ff0000'; $body_vlink = '#ff0000'; $body_bgcolor = '#000000'; $body=<<"_EOF_"; _EOF_ $page = 10;# 1ページに表示する記事数 # ファイル関連の設定 $tz = "JST-9";# TimeZone $cginame = 'gazobbs.cgi'; # この CGI のファイルの名前 $ENV{'SCRIPT_NAME'} = "./gazobbs.cgi";#このCGIの場所 $jcode= './jcode.pl';# jcode.pl のある場所 $logfile = './gazobbs.log'; # 記録用ファイル名(絶対に変えておくこと) $lock1= './lock/gazobb1.lock'; # 鍵ファイル(1) $lock2= './lock/gazobb2.lock'; # 鍵ファイル(2) $lock_flag = 1; # 鍵ファイルの 1:使用 0:不使用 # -------------------- # 色 #記事部の一番外の背景色 $bgcol="#333333"; #わく線の色 $bgcol2="red"; #記事タイトルの色 $bgcol3="#ffffff"; #記事タイトルの背景色 $bgcol4="black"; #掲示板タイトルの色 $bgcol5="black"; #掲示板タイトルの背景色 $bgcol6="white"; # -------------------- # タイトル部分の HTML文 $html_title=<<"_EOF_";
★☆ $bbs_title ☆★
_EOF_ # -------------------- # ヘッダーの HTML文 $html_heading=<<"_EOF_"; $bbs_title $body _EOF_ $hiduke[0] = "Sun"; # 曜日の設定 $hiduke[1] = "Mon"; $hiduke[2] = "Tue"; $hiduke[3] = "Wed"; $hiduke[4] = "Thr"; $hiduke[5] = "Fri"; $hiduke[6] = "Sat"; ###########設定は以上です。 ########### #前処理 ########### if($kyoka eq 1){$pass3 = '8888';$pass4 = '9999';}else{$pass3 = 'kx8888';$pass4 = 'kx9999';} $ext = "cgi"; $image_url =~ s/\/$//; &check_code; &GetQuery(); &GetData(); ########### #主処理 ########### if ($FORM{'pass'} eq $master || $FORM{'pass'} eq $master2) { #if (1) { @logs = &read_file($logfile); &html_header; &html_editor; &html_footer; } elsif ($kyoka eq 1 && $FORM{'subpass'} eq $pass3) { &html_header; &html_submit; &html_footer; }elsif ($FORM{'subpass'} eq $pass4) { @logs = &read_file($logfile); &html_done; } else { @logs = &read_file($logfile); &html_header; &html_title; &html_sub; &html_body; &html_adminenter; &html_footer; } exit; ########### #ヘッダーフッター表示 ########### #HEAD部分の出力 sub html_header { print "Content-type: text/html\n\n"; print "$html_heading\n"; } sub html_footer{#著作権表示 print<<"_EOF_";

[ 管理者:$admin_name ]

画像\貼\付掲示板 v5.0B
Copyright © 1999-2005 KX Computer Systems & Edward Carr, All Rights Reserved
_EOF_ } sub html_title { print "
\n"; print " ホームへ\n"; print "
"; print "$html_title\n"; print "\n"; print "
\n"; } ########### #表示処理 ########### ########### #記事の表示処理2 ########### ########### #ページ計算処理 ########### sub html_body { local($start,$end) = &page_log; for ($i = $start;$i<$end;$i++) { ($date,$title,$img_flg,$img_fl_nam,$subname,$formdata3,$formdata4,$message,$host,$delkey) = &get_data($logs[$i]); if ($FORM{'pass'} eq $master || $FORM{'pass'} eq $master2) { print "
\n"; #削除ボタン print "[削除] 
\n"; } # $date = &get_weekly_date($date); &html_format($date,$title,$img_flg,$img_fl_nam,$subname,$formdata3,$formdata4,$message,$host,$delkey); } } ########### #ページ計算処理 ########### sub page_log { # ページを設定 local($start,$end); $start = $FORM{'start'}; $end = $start + $page; if ($start < 0) { $start = 0; } if ($start > @logs) { $start = @logs; } if ($end < 0) { $end = 0;} if ($end > @logs) { $end = @logs; } print "

\n"; $temp = $start-$page; if ($start>0) { print "前ページ▲ "; } else { print "△"; } $temp = $start+$page; if ($end<=$#logs) { print "次ページ▼ "; } else { print "▽"; } return ($start,$end); } ########### #記事の表示処理 ########### sub html_format {#記事の表示 ($date,$title,$img_flg,$img_fl_nam,$subname,$formdata3,$formdata4,$message,$host,$delkey) = @_; #自動リンク $message =~ s/(http:\/\/[\w\$\#\~\.\/\-\?\=\&\:\%]+)/$1<\/a>/g; $message =~ s/(ftp:\/\/[\w\$\#\~\.\/\-\?\=\&\:\%]+)/$1<\/a>/g; #名前、記事 print<<"_EOF_";

  _EOF_ #画像 if($img_flg eq 1 && $nifty_flg eq 0){ print<<"_EOF_"; _EOF_ }#画像1end if($img_flg eq 1 && $nifty_flg eq 1){ print<<"_EOF_"; _EOF_ }#画像2end #日 print<<"_EOF_"; _EOF_ #削除ボタン if($delkey ne ""){ print<<"_EOF_"; _EOF_ } print<<"_EOF_";
$title
投稿者:$subname
$message

 
\"./img.cgi?file\=$img_fl_nam\"
$date _EOF_ #メール if($formdata3 ne ""){ print<<"_EOF_"; mail.gif _EOF_ } #ホーム if($formdata4 ne "http://" && $formdata4 ne ""){ print<<"_EOF_"; home.gif _EOF_ } print<<"_EOF_";
 削除キー 
 
_EOF_ } ########### #ログを変数に代入する処理 ########### sub get_data { local($date,$title,$img_flg,$img_fl_nam,$subname,$formdata3,$formdata4,$message,$host,$delkey) = split(/<>/,$_[0]); $message =~ s/\n//; return ($date,$title,$img_flg,$img_fl_nam,$subname,$formdata3,$formdata4,$message,$host,$delkey); } ########### #曜日計算処理 ########### sub get_weekly_date { local($date) = $_[0]; local($year,$mon,$day,$week) = (substr($date,0,4),substr($date,4,2),substr($date,6,2),0); if ($mon < 3) { $year--; $mon += 12; } $week = (int($year) + int($year/4) - int($year/100) + int($year/400) + int(($mon*13+8)/5) + $day) % 7; local($year,$mon) = (substr($date,0,4),substr($date,4,2)); $date = $year."/".$mon."/".$day."($hiduke[$week])"; return $date; } ########### #投稿用の入り口ボタンを表示する処理 ########### sub html_sub { if($kyoka eq 1){ print<<"_EOF_";

_EOF_ } } ########### #管理者用の入り口を表示する処理 ########### sub html_adminenter { print<<"_EOF_";
_EOF_ } ########### #管理者が削除する画面を表示する処理 ########### sub html_editor { &editor_edit; if ($nengappi == 0) { ($year,$mon,$day) = &get_date; } else { ($year,$mon,$day) = (substr($nengappi,0,4),substr($nengappi,4,2),substr($nengappi,6,2)) } if ($year.$mon.$day eq (split(/<>/,$_))[0]) { ($date,$title,$img_flg,$img_fl_nam,$subname,$formdata3,$formdata4,$message,$host,$delkey) = &get_data($_); $message =~ s/
/\n/g; } $kiji = @logs; $size = (stat($logfile))[7]; print<<"_EOF_";

[通常画面]

_EOF_ &html_body; print<<"_EOF_"

_EOF_ } ########### #投稿用が終わったら元の画面を表示する処理 ########### sub html_done { &editor_edit; print "Location: $ENV{'SCRIPT_NAME'}\n\n"; } ########### #投稿用の入力画面を表示する処理 ########### sub html_submit {#訪問者書き込みの画面 ##くっきーを頂きます。 $cooks = $ENV{'HTTP_COOKIE'}; $cooks = '' unless($cooks =~s/.*carrbbsdata=(.*)carrend.*/$1/); ($cookname,$cookemail,$cookurl,$cookcolor,$cookdate,$count,$cooknekogao,$ckey,$dum) = split(/<>/, $cooks); $histry = "$count回目:LAST LOGIN:$lastdate" if($lastdate); if(!$count){ #くっきー情報の無い場合のデフォルト値 $color = 'red';$count = 1;$nekogao = './neko0.gif'; } #getcookie END ($year,$mon,$day) = &get_date; $image_s=$image_max/1000; print<<"_EOF_";
[通常画面]
(投稿画面)
タイトル:
お名前:
削除用キー:
記事:
画像:(必須項目ではありません。\パ\ソ\コ\ン中のJPGかGIFファイルを指定してください。)
ファイル名やフォルダ名に\日\本文字や空白があると\表\示されないことがあります。


(${image_s} Kバイト以内)
MAIL:
HOME:
   _EOF_ # &html_body; print<<"_EOF_"

_EOF_ } ########### #投稿された内容をチェックし書き出す処理 ########### sub editor_edit { if ($FORM{'message'} ne '') { if ($FORM{'year'}< 1583 || $FORM{'year'}> 9999) { return; } if ($FORM{'mon'}< 1 || $FORM{'mon'}> 12) { return; } if ($FORM{'day'}< 1 || $FORM{'day'}> (0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)[$FORM{'mon'}]) { return; } if ($FORM{'mon'} == 2 && $FORM{'day'} == 29) { if (($FORM{'year'} % 4 != 0 && $FORM{'year'} % 100 == 0) || ($FORM{'year'} % 400 != 0)) { return; } } $FORM{'mon'} = substr("0$FORM{'mon'}",length($FORM{'mon'})-1,2); $FORM{'day'} = substr("0$FORM{'day'}",length($FORM{'day'})-1,2); $times = time;#18時間時差があるなら、$times = time+18*60*60とする。 ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime($times); $min = "0$min" if ($min < 10); $month++; $youbi = ('日','月','火','水','木','金','土') [$wday]; $date = $FORM{'year'}.$FORM{'mon'}.$FORM{'day'}; $date2 = $FORM{'year'}.$FORM{'mon'}.$FORM{'day'}."($youbi)$hour:$min"; $FORM{'message'} =~ s/\r\n/
/g; $FORM{'message'} =~ s/\r|\n/
/g; #画像出力 #サイズエラー検出 if (length($in{'IMAGE'}) > $image_max) { &Error("サイズオーバー","画像は$image_maxバイト以内にしてください."); } foreach (@in) { ($fname) = $_ =~ /\bfilename="([^"]*)"/i; ($fname) = $_ =~ /\bfilename=([^\s:;]+)/i unless defined $fname; if ($fname eq '') { next; } ($name) = $_ =~ /\bname="([^"]+)"/i; ($name) = $_ =~ /\bname=([^\s:;]+)/i unless defined $name; ($ctype) = $_ =~ /\s*Content-type:\s*"([^"]+)"/i; ($ctype) = $_ =~ /\s*Content-Type:\s*([^\s:;]+)/i unless defined $ctype; unless ($ctype =~ /^image/i) { &error('エラー',"この画像ファイルは使用できません。"); } if ($ctype eq '') { &error('エラー',"$fnameはContent-Typeが認識できないために受付できません."); } if ($name =~ /IMAGE/) { $fname = reverse("$fname"); ($fname) = split(/\\|\/|\:/,$fname); $fname = reverse("$fname"); ($fname,$ext) = split(/\./,$fname); $ext1 = $ext; $ext2 = ''; $randtime=time; if (!open(IMAGE,"> ./img1/$date$randtime$ext2\.$ext")) { &Error('書出エラー',"画像データ ./img1/$date$randtime$ext2\.$ext が記録できませんでした."); } binmode(IMAGE); print IMAGE $in{$name}; close(IMAGE); $f_n="./img1/$date$randtime$ext2\.$ext"; chmod(0666,"./img1/$date$randtime$ext2\.$ext"); } } if($f_n ne ''){ $img_flg = "1"; }else{$img_flg = "0"} $host = $ENV{'REMOTE_HOST'}; push(@new,"$date2<>$FORM{'title'}<>$img_flg<>$date$randtime$ext2\.$ext<>$FORM{'subname'}<>$FORM{'formdata3'}<>$FORM{'formdata4'}<>$FORM{'message'}<>$host<>$FORM{'123key'}<>\n"); #くっきーをブラウザにプレゼントします。 local($dmy,$mdc,$monc,$yrc,$wdayc,$mc,$yc); ($dmy,$dmy,$dmy,$mdc,$monc,$yrc,$wdayc,$dmy,$dmy) = localtime($times + 7776000); $yc = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday') [$wdayc]; $mc = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec') [$monc]; $yrc = $yrc+1900; $mdc = "0$mdc" if ($mdc < 10); $count++; $data = "$FORM{'subname'}<>$FORM{'formdata3'}<>$FORM{'formdata4'}<>$FORM{'color'}<>$date2<>$count<>$FORM{'nekogao'}<>$FORM{'123key'}<>carrend"; print "Set-Cookie: carrbbsdata=$data; expires=$yc, $mdc-$mc-$yrc 00:00:00 GMT\n"; #このクッキーはだいたい3ヶ月間有効です。 }#if #削除処理 ($del1,$del2)=split(/:#/,$FORM{'del'}); foreach $data (@logs) { local($datex,$title,$img_flg,$img_fl_nam,$subname,$formdata3,$formdata4,$message,$host,$delkey) = split(/<>/,$data); if ($del1 eq $title && $del2 eq $datex && ($FORM{'pass'} eq $master || $FORM{'pass'} eq $master2 || $FORM{'pass'} eq $delkey)) {#1 if($img_flg eq 1){unlink("./img1/$img_fl_nam");} next; }#1 push (@new,$data); } @logs = &write_file($logfile,@new); undef @new; }#END ########### #ファイル読み込み処理 ########### sub read_file {# local($logfile) = $_[0]; if (!open(IN,$logfile)) { &error(1,"記録ファイルの読み込み不可"); } local(@files) = ; close(IN); return @files; } ########### #ファイル書き出し処理 ########### sub write_file { #出力 local($logfile,@lines) = @_; &dubble_lock_file; if ($lock_error) { &error(1,"ロックファイルを検出しました。時間をおいてご利用下さい。"); } if (!open(OUT,">$logfile")) { &dubble_unlock_file; &error(1,"記録ファイルの書き込み不可"); } print OUT @lines; close(OUT); &dubble_unlock_file; return @lines; } ########### #ファイルロック処理 ########### sub dubble_lock_file { if($lock_flag){ if (!(&lock_file($lock1))) { &dubble_unlock_file; } elsif (!(&lock_file($lock2))) { &dubble_unlock_file; } }} sub dubble_unlock_file { if($lock_flag){ &unlock_file($lock2);&unlock_file($lock1); }} sub lock_file { if($lock_flag){ local($lockfile) = $_[0]; if (!$lock_flag) { return 1; } local($retry) = 5; while (-f $lockfile) { if ($retry-- <= 0) { local($mtime) = (stat($lockfile))[9]; if ($mtime < time()-60*15) { return 0; } $lock_error = 1; return 1; } sleep 1; } open (LOCK,">$lockfile"); close(LOCK); return 1; }} sub unlock_file { if($lock_flag){ local($lockfile) = $_[0]; unlink($lockfile); }} ########### #日付の処理2 ########### sub get_date { $ENV{'TZ'} = $tz; local($sec,$min,$hour,$day,$mon,$year) = localtime(time); if ($hour < 12) { local($sec,$min,$hour,$day,$mon,$year) = localtime(time-12*60*60); } $mon++; if ($mon < 10) { $mon = "0$mon"; } if ($day < 10) { $day = "0$day"; } if ($year < 99) { $year += 100; } $year += 1900; return ($year,$mon,$day); } ########### #フォームからの読み込み処理 ########### sub GetQuery { $cmd = $ENV{'QUERY_STRING'}; @pairs = split(/&/,$cmd); foreach $pair (@pairs) { ($key,$val) = split(/=/,$pair); $val =~ tr/+/ /; $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; $cmd{$key} = $val; }#foreach } sub GetData { &ReadParse; while (($key,$val) = each %in) { #イメージスキップ if ($key eq 'IMAGEs' || $key eq 'IMAGE') { next; } #コード変換 &jcode'h2z_sjis(*val); &jcode'convert(*val,'sjis'); #改行変換 $val =~ s/\t//g; $val =~ s/\r\n/\r/g; $val =~ s/\n/\r/g; #タグ禁止 $val =~ s/&/&/g; $val =~ s/"/"/g; $val =~ s//>/g; #変数代入 $in{$key} = $val; $FORM{$key} = $val; if ($key eq 'edit') { $nengappi = $val; } } } sub Error { #エラー処理 unlink($lockfile); local (@msg) = @_; local ($i); &html_header; print <<"EOF"; $body

$msg[0]

EOF if ($msg[1] ne '') { print "
    \n"; foreach $i (1 .. $#msg) { print "
  • $msg[$i]\n"; } print "
\n"; } print <<"EOF"; EOF exit; } ########### #デバッグ用の処理 ########### sub check_code { if (!(-r $jcode)) { &error(1,"jcode.pl がみつかりません。"); } require $jcode; } sub error { ($err,$err_msg) = @_; if ($err) { print "Content-type: text/html\n\n"; } print<<"_EOF_";
$err_msg

[ back ]
_EOF_ exit; }