掲示板管理者の環境設定の作成 掲示板により変更可能な項目を設定できるようする。 設定画面は、こんな感じ タイトル バックグランド 文字の色 LINKの色 VLINKの色 ALINKの色 罫線の色 罫線の太さ 保管件数 1ページの表示記事数 ホームの設定 管理者メールアドレス タイトル下のフリーエリア 一番下のフリーエリア 画像投稿許可フラグ タグ投稿許可フラグ とりあえず、現時点でのソース(スクリプト)大公開 #!/usr/bin/perl # 上のperlのパスはサーバーによって違うことがあるので、 # プロバイダーのCGI設置案内を参照して下さい。 # 通常は /usr/local/bin/perl または /usr/bin/perl です #=========================================================== # plbbs.cgi Ver 0.0.0 $ver = 'plbbs.cgi V0.00'; # # Copyright (C) 2003 M.Kondo # http://kondo-net.gr.jp/ # # 免責事項 # ・スクリプト利用による損害は、保証できません。 #=========================================================== # サーバーのsendmailのパス # サーバー(プロバイダ)によって違う場合もあるので、確認して下さい $sendmail = '/usr/sbin/sendmail'; #=========================================================== $script = './plbbs.cgi'; # スクリプトファイル名 require 'jcode.pl'; # コード変換ライブラリ取込 require './cgi-lib.pl'; # ライブラリ取込 #=========================================================== $admin_id = '0123'; # 総管理者ID $admin_password = '0123'; # 総管理者パスワード $datapath = './data/'; # データ保管フォルダー #----------------------------------------------------------- # アップロードディレクトリ # → パスの最後は / で終わること # → フルパスだと / から記述する $ImgDir = './img/'; $ImgDir = '/home/httpd/html/test/joyful/img/'; #----------------------------------------------------------- # アップロードディレクトリのURLパス # → パスの最後は / で終わること $ImgUrl = "http://www.xxx.xxx/~xxx/img/"; $ImgUrl = "http://www.kondo-net.gr.jp/test/joyful/img/"; #----------------------------------------------------------- # 添付ファイルのアップロードに失敗したとき # 0 : 添付ファイルは無視し、記事は受理する # 1 : エラー表示して処理を中断する $clip_error = 1; #----------------------------------------------------------- # 投稿受理最大サイズ (bytes) # → 例 : 102400 = 100KB $cgi_lib'maxdata = 102400; #----------------------------------------------------------- # 画像ファイルの最大表示の大きさ(単位:ピクセル) # → これを超える画像は縮小表示します $MaxW = 300; # 横幅 $MaxH = 150; # 縦幅 #=========================================================== ## ロック処理を行うかどうかの選択 (しない=0 する(symlink関数)=1 する(open関数)=2 ) ### 通常は 1 を指定してください ### エラーとなる場合 2 open関数を使用します ### どうしてもエラーとなる場合は 0 しないでやってみる $lockkey = '1'; #=========================================================== $room = 'plbbs'; # デフォルトのルームID @wdays = ( "日", "月", "火", "水", "木", "金", "土", "日" ); $imgwait = 'http://kondo-net.gr.jp/img/soon.gif'; #=========================================================== &decode; # デコード処理 &lock; # ロック処理 &init; &plmain; # メイン処理 &unlock; # ロック解除 exit; #----------------------------------------------------------- # メイン処理 #----------------------------------------------------------- sub plmain() { if($mode eq 'administrator'){ &administrator; } elsif($mode eq 'admin'){ &admin; } elsif($mode eq 'regist'){ ®ist; } elsif($mode eq 'userkill'){ &userkill; } else{ &view; } } #----------------------------------------------------------- # 総管理人 #----------------------------------------------------------- sub administrator() { if($admin_password eq $in{'password'} and $admin_id eq $in{'userid'}){ &header; ## ヘッダー部出力 &footer; ## フッター部出力 }else{ &header; ## ヘッダー部出力 &footer; ## フッター部出力 } } #----------------------------------------------------------- # 管理人 #----------------------------------------------------------- sub admin() { require "$datapath$room.cfg"; if($admin_pass eq $in{'password'} and $room eq $in{'userid'}){ if($in{'action'} eq 'data'){ &editview; }elsif($in{'action'} eq 'env'){ &edit_env; }else{ &adminheader; ## ヘッダー部出力 &adminfooter; ## フッター部出力 } }else{ &adminheader; ## ヘッダー部出力 print <ID・パスワードを入力して下さい ID: PW: 記事・画像許可設定 環境設定 EOM &adminfooter; ## フッター部出力 } # print "-- $datapath$room.cfg -- $admin_pass -- $in{'password'} -- $in{'userid'} --"; } #----------------------------------------------------------- # 管理者環境修正処理 #----------------------------------------------------------- sub edit_env() { my $saveflag=0; # &envdataload; ## データ読み込み if($saveflag == 1){ # &envdatasave; ## データ保管 } &edit_env_view; } #----------------------------------------------------------- sub edit_env_view() { &adminheader; ## ヘッダー部出力 print < タイトル バックグランドカラー バックグランド 文字の色 LINKの色 VLINKの色 ALINKの色 罫線の色 罫線の太さ 保管件数 1ページの表\示記事数 ホームの設定 管理者メールアドレス タイトル下のフリーエリア 一番下のフリーエリア 画像投稿許可フラグ タグ投稿許可フラグ EOM &adminfooter; ## フッター部出力 } #----------------------------------------------------------- # 管理者修正表示処理 #----------------------------------------------------------- sub editview() { my $saveflag=0; &dataload; ## データ読み込み foreach $room_data (@room_datas){ my @logs = split(/<>/,$room_data); foreach $del (@DEL) { if($del eq $logs[0]){ $saveflag=1; $room_data =~ s/.*\n//; my @img = split(/\,/,$logs[6]); if (-e "$ImgDir$room/$img[0]") { unlink("$ImgDir$room/$img[0]"); } } } foreach $edt (@EDT) { if($edt eq $logs[0]){ $saveflag=1; my @img = split(/\,/,$logs[6]); my $ll = "<>$img[0],1,$img[2],$img[3]<>"; $room_data =~ s/<>$logs[6]<>/$ll/; } } } if($saveflag == 1){ &datasave; ## データ保管 } &roomdatas_editview; } #----------------------------------------------------------- #----------------------------------------------------------- sub roomdatas_editview() { my $start,$end,$data_count; if($in{start} == 0){ $start = 0; }else{ $start = 0 + $in{start}; } $nextno = 0 + $start + $cfg{'logpagemax'}; $endno = $nextno; $data_count = 0 + @room_datas; if($endno > $data_count){ $endno = $data_count; } &header; ## ヘッダー部出力 print < EOM for(my $i=$start;$i<$endno;$i++){ roomdata_editview( $room_datas[$i] ); } print < EOM if($endno != $data_count){ print < EOM } print < EOM &footer; ## フッター部出力 } #----------------------------------------------------------- # データ表示処理 # # 0 1 2 3 4 5 6 7 8 9 10 11 12 # no<>name<>email,f1,f2<>title<>msg<>url<>img,f3,w,h<>delkey<>date<>ip<>host<>referer<>AGENT<><><> #----------------------------------------------------------- sub roomdata_editview() { if($_[0] eq ''){ return; } my @logs = split(/<>/,$_[0]); my $sec,$min,$hour,$mday,$mon,$year,$wday; ($sec,$min,$hour,$mday,$mon,$year,$wday)=localtime($logs[8]); # my $strtime = sprintf("%04d%02d%02d%02d%02d%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec); $year+=1900; $mon+=1; my $strdate = "$year年$mon月$mday日(@wdays[$wday])" . sprintf("%02d:%02d:%02d",$hour,$min,$sec); my @dataemail = split(/\,/,$logs[2]); my $strname=$logs[1]; if($dataemail[1]){ $strname="$logs[1] $dataemail[0]"; } my $strurl=''; if($logs[5] ne ''){ $strurl="$logs[5]"; } my @dataimg = split(/\,/,$logs[6]); my $strimg=' '; my $strimgcheck=' '; if($dataimg[0] ne ''){ $strimg = < EOM if($dataimg[1]){ }else{ $strimgcheck = <画像許可 EOM } } print < [$logs[0]]削除 $logs[3] 投稿者:$strname 投稿日:$strdate $strurl $strimg $logs[4] $strimgcheck IP$logs[9] HOST$logs[10] referer$logs[11] AGENT$logs[12] EOM } #----------------------------------------------------------- # ユーザー記事削除処理 #----------------------------------------------------------- sub userkill() { &dataload; ## データ読み込み foreach $room_data (@room_datas){ my @logs = split(/<>/,$room_data); my $delno = $in{'delno'}; my $delkey = $in{'delkey'}; if($delno eq $logs[0]){ if($delkey eq $logs[7]){ $saveflag=1; $room_data =~ s/.*\n//; my @img = split(/\,/,$logs[6]); if (-e "$ImgDir$room/$img[0]") { unlink("$ImgDir$room/$img[0]"); } } last; } } if($saveflag == 1){ &datasave; ## データ保管 } &roomdatas_view; } #----------------------------------------------------------- # 通常表示処理 #----------------------------------------------------------- sub view() { &dataload; ## データ読み込み &roomdatas_view; } #----------------------------------------------------------- #----------------------------------------------------------- sub roomdatas_view() { my $start,$end,$data_count; if($in{start} == 0){ $start = 0; }else{ $start = 0 + $in{start}; } $nextno = 0 + $start + $cfg{'logpagemax'}; $endno = $nextno; $data_count = 0 + @room_datas; if($endno > $data_count){ $endno = $data_count; } &header; ## ヘッダー部出力 &enter_form; ## 投稿部出力 for(my $i=$start;$i<$endno;$i++){ if($room_datas[$i] ne ''){ roomdata_view( $room_datas[$i] ); } } if($endno != $data_count){ $nexthtml=< EOM } print < $nexthtml投稿NO/削除キー/ EOM &footer; ## フッター部出力 } #----------------------------------------------------------- # データ表示処理 # # 0 1 2 3 4 5 6 7 8 9 10 11 12 # no<>name<>email,f1,f2<>title<>msg<>url<>img,f3,w,h<>delkey<>date<>ip<>host<>referer<>AGENT<><><> #----------------------------------------------------------- sub roomdata_view() { my @logs = split(/<>/,$_[0]); my $sec,$min,$hour,$mday,$mon,$year,$wday; ($sec,$min,$hour,$mday,$mon,$year,$wday)=localtime($logs[8]); # my $strtime = sprintf("%04d%02d%02d%02d%02d%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec); $year+=1900; $mon+=1; my $strdate = "$year年$mon月$mday日(@wdays[$wday])" . sprintf("%02d:%02d:%02d",$hour,$min,$sec); my @dataemail = split(/\,/,$logs[2]); my $strname=$logs[1]; if($dataemail[1]){ $strname="$logs[1]"; } my $strurl=''; if($logs[5] ne ''){ $strurl="H"; } my @dataimg = split(/\,/,$logs[6]); my $strimg=''; if($dataimg[0] ne ''){ if($dataimg[1]){ $strimg = < EOM }else{ $strimg = ""; } } print < [$logs[0]] $logs[3] 投稿者:$strname 投稿日:$strdate $strurl $strimg$logs[4] EOM } #----------------------------------------------------------- # 投稿処理 #----------------------------------------------------------- sub regist(){ &dataload; ## データ読込 my $rc= &dataregist; ## データ書込 if($rc){ &roomdatas_view; }else{ &unlock; print "Location: $script?room=$room\n\n"; exit; } } #----------------------------------------------------------- # 投稿フォーム #----------------------------------------------------------- sub enter_form() { print < お名前 メールアドレス 公開 レス通知 タイトル メッセージ </TEXTAREA> 画像 URL 削除キー EOM } #----------------------------------------------------------- # 初期値設定 #----------------------------------------------------------- sub init{ %cfg=( "background" => "", "bgcolor" => "#FFFFFF", "text" => "#000000", "link" => "#0000FF", "vlink" => "#FF00FF", "alink" => "#FF0000", "title" => "掲示板", # タイトル "table_border" => "1", # 罫線太さ "table_bordercolor" => "", # 罫線カラー "logmax" => 50, # 記事保管件数 "logpagemax" => 5, # 1ページの記事表示件数 "homeaddr" => "/", # ホーム "adminemail" => "", # 管理者のメールアドレス "freearea1" => "freearea1", "freearea2" => "freearea2", "imageregistflag" => 0, # 0:画像不可 1:画像投稿許可 "tagsregistflag" => 0, # 0:TAGS不可 1:TAGS投稿許可 ); } #----------------------------------------------------------- # 通常ヘッダー処理 #----------------------------------------------------------- sub header { if($head_flag != 1){ $head_flag=1; print "Content-type: text/html\n\n"; print <<"EOM"; EOM if($admincm ne ''){ print <<"EOM"; $admincm EOM } ## タイトル表示 my $title=$cfg{'title'}; print <<"EOM"; $title EOM my $freearea1=$cfg{'freearea1'}; if($freearea1 ne ''){ print <<"EOM"; $freearea1 EOM } print ""; } } #----------------------------------------------------------- # 通常フッター処理 #----------------------------------------------------------- sub footer { my $freearea2=$cfg{'freearea2'}; if($freearea2 ne ''){ print <<"EOM"; $freearea2 EOM } print <<"EOM"; ID/PW/ - CGI(Perl PHP) - --- KONDO-NET.GR.JP --- EOM } #----------------------------------------------------------- # 管理用ヘッダー処理 #----------------------------------------------------------- sub adminheader { if($head_flag != 1){ $head_flag=1; print "Content-type: text/html\n\n"; print <<"EOM"; PLBBS.CGI管理画面 EOM } } #----------------------------------------------------------- # 管理用フッター処理 #----------------------------------------------------------- sub adminfooter { print <<"EOM"; 掲示板表\示 - CGI(Perl PHP) - --- KONDO-NET.GR.JP --- EOM } #----------------------------------------------------------- # データ読込 #----------------------------------------------------------- sub dataload() { if(!open(DAT,"$datapath$room.dat")){&error("OPEN ERROR $room.dat");} @room_datas = ; close(DAT); } #----------------------------------------------------------- # データ保管 # 0 1 2 3 4 5 6 7 8 9 10 11 12 # no<>name<>email,f1,f2<>title<>msg<>url<>img,f3,w,h<>delkey<>date<>ip<>host<>referer<>AGENT<><><> #----------------------------------------------------------- sub dataregist() { my $strname = $in{'FROM'}; my $stremail = $in{'EMAIL'}; my $stremail_1 = $in{'C1'}; my $stremail_2 = $in{'C2'}; my $strtitle = $in{'TITLE'}; my $strmsg = $in{'MESSAGE'}; my $strurl = $in{'URL'}; # my $strimg = $in{''}; my $strdelkey = $in{'DELKEY'}; my $strtime = time; my $strip = $ENV{'REMOTE_ADDR'}; my $strhost = $ENV{'REMOTE_HOST'}; my $strref = $ENV{'HTTP_REFERER'}; my $stragent = $ENV{'HTTP_USER_AGENT'}; if ($strhost eq '') { $strhost = $strip; } if ($strhost eq $strip) { $strhost = gethostbyaddr(pack('C4',split(/\./,$strhost)),2) || $strip; } if($strname eq '' or $stremail eq '' or $strtitle eq '' or $strmsg eq '' or $strdelkey eq ''){ return 1; } my ($no)=split(/<>/,$room_datas[0]); $no++; # ファイル添付処理 if ($in{'upfile'}) { &UpFile($no); $strimg="$ImgUrl$room/$no$tail"; } my $line="$no<>$strname<>$stremail,$stremail_1,$stremail_2<>$strtitle<>$strmsg<>$strurl<>$strimg,,$W,$H<>$strdelkey<>$strtime<>$strip<>$strhost<>$strref<>$stragent<><><>\n"; $num = unshift(@room_datas, $line); if($num>$cfg{'logmax'}){ pop @room_datas; } &datasave; return 0; } #----------------------------------------------------------- # データ保管 #----------------------------------------------------------- sub datasave() { if(!open(DAT,">$datapath$room.dat")){&error("OPEN ERROR $room.dat");} print DAT @room_datas; close(DAT); } #----------------------------------------------------------- # デコード処理 #----------------------------------------------------------- sub decode(){ &ReadParse; while (($parameter,$value) = each %in) { if ($parameter ne 'upfile') { # シフトJISコードに変換 &jcode'convert(*value, "sjis"); #--正規表現--# $value =~ s/,/./g; $value =~ s/\r\n//g; $value =~ s/\r//g; $value =~ s/\n//g; $value =~ s/</g; $value =~ s/>/>/g; #--削除データがあれば配列に追加--# if ($parameter eq 'delno') { push(@DEL, $value); } #--削除データがあれば配列に追加--# if ($parameter eq 'edtno') { push(@EDT, $value); } } $in{$parameter} = $value; } if($in{'room'} ne ''){ $room = $in{'room'}; } $mode=$in{'mode'}; } #----------------------------------------------------------- # ロック処理 #----------------------------------------------------------- sub lock(){ if($lockflag){ return; } $lockfile = "$datapath$room.loc"; # 1分以上古いロックは削除する if (-e $lockfile) { local($mtime) = (stat($lockfile))[9]; if ($mtime < time - 60) { $lockflag=1; &unlock; } } if ($lockkey eq '1') { #--symlink関数でのロック--# local($retry) = 5; while (!symlink(".",$lockfile)) { if (--$retry <= 0) { &error("アクセスが集中しています"); } sleep(1); } $lockflag = 1; }elsif ($lockkey eq '2') { #--open関数でのロック--# foreach (1 .. 5) { if (-e $lockfile) { sleep(1); } else { open(LOCK,">$lockfile"); close(LOCK); $lockflag = 1; last; } } if ($lockflag == 0) { &error("アクセスが集中しています"); } } } #----------------------------------------------------------- # ロック解除処理 #----------------------------------------------------------- sub unlock(){ if($lockflag){ if (-e $lockfile) { unlink $lockfile; } } $lockflag=0; } #----------------------------------------------------------- # エラー処理 # #----------------------------------------------------------- sub error { if ($lockflag) { &unlock; } &header if (!$head_flag); print "ERROR !\n"; print "$_[0]\n"; print "\n"; &footer; exit; } #--------------------# # 画像アップロード # #--------------------# sub UpFile { my $no = $_[0]; local($macbin,$fname,$flag,$upfile); # 画像処理 $macbin=0; foreach (@in) { if (/(.*)Content-type:(.*)/i) { $tail=$2; } if (/(.*)filename=(.*)/i) { $fname=$2; } if (/application\/x-macbinary/i) { $macbin=1; } } $tail =~ s/\r//g; $tail =~ s/\n//g; $fname =~ tr/\"\x0D\x0A//d; # ファイル形式を認識 $flag=0; if ($tail =~ /image\/gif/i && $gif) { $tail=".gif"; $flag=1; } if ($tail =~ /image\/jpeg/i && $jpeg) { $tail=".jpg"; $flag=1; } if ($tail =~ /image\/x-png/i && $png) { $tail=".png"; $flag=1; } if ($tail =~ /text\/plain/i && $text) { $tail=".txt"; $flag=1; } if ($tail =~ /lha/i && $lha) { $tail=".lzh"; $flag=1; } if ($tail =~ /zip/i && $zip) { $tail=".zip"; $flag=1; } if ($tail =~ /pdf/i && $pdf) { $tail=".pdf"; $flag=1; } if ($tail =~ /audio\/.*mid/i && $midi) { $tail=".mid"; $flag=1; } if ($tail =~ /msword/i && $word) { $tail=".doc"; $flag=1; } if ($tail =~ /ms-excel/i && $excel) { $tail=".xls"; $flag=1; } if ($tail =~ /ms-powerpoint/i && $ppt) { $tail=".ppt"; $flag=1; } if ($tail =~ /audio\/.*realaudio/i && $ram) { $tail=".ram"; $flag=1; } if ($tail =~ /application\/.*realmedia/i && $rm) { $tail=".rm"; $flag=1; } if ($tail =~ /video\/.*mpeg/i && $mpeg) { $tail=".mpg"; $flag=1; } if ($tail =~ /audio\/.*mpeg/i && $mp3) { $tail=".mp3"; $flag=1; } if (!$flag) { # アップロードを許可するファイル形式 # 0:no 1:yes $gif = 1; # GIFファイル $jpeg = 1; # JPEGファイル $png = 1; # PNGファイル if ($fname =~ /\.gif$/i && $gif) { $tail=".gif"; $flag=1; } if ($fname =~ /\.jpe?g$/i && $jpeg) { $tail=".jpg"; $flag=1; } if ($fname =~ /\.png$/i && $png) { $tail=".png"; $flag=1; } if ($fname =~ /\.lzh$/i && $lha) { $tail=".lzh"; $flag=1; } if ($fname =~ /\.txt$/i && $text) { $tail=".txt"; $flag=1; } if ($fname =~ /\.zip$/i && $zip) { $tail=".zip"; $flag=1; } if ($fname =~ /\.pdf$/i && $pdf) { $tail=".pdf"; $flag=1; } if ($fname =~ /\.mid$/i && $midi) { $tail=".mid"; $flag=1; } if ($fname =~ /\.doc$/i && $word) { $tail=".doc"; $flag=1; } if ($fname =~ /\.xls$/i && $excel) { $tail=".xls"; $flag=1; } if ($fname =~ /\.ppt$/i && $ppt) { $tail=".ppt"; $flag=1; } if ($fname =~ /\.ram$/i && $ram) { $tail=".ram"; $flag=1; } if ($fname =~ /\.rm$/i && $rm) { $tail=".rm"; $flag=1; } if ($fname =~ /\.mpe?g$/i && $mpeg) { $tail=".mpg"; $flag=1; } if ($fname =~ /\.mp3$/i && $mp3) { $tail=".mp3"; $flag=1; } } # アップロード失敗処理 if (!$flag && !$clip_error) { return; } elsif (!$flag && $clip_error) { &error("アップロードできないファイル形式です"); } $upfile = $in{'upfile'}; # マックバイナリ対策 if ($macbin) { $length = substr($upfile,83,4); $length = unpack("%N",$length); $upfile = substr($upfile,128,$length); } # 添付データを書き込み $ImgFile = "$ImgDir$room/$no$tail"; open(OUT,"> $ImgFile") || &error("アップロード失敗"); binmode(OUT); binmode(STDOUT); print OUT $upfile; close(OUT); chmod (0666,$ImgFile); # 画像サイズ取得 if ($tail eq ".jpg") { ($W, $H) = &JpegSize($ImgFile); } elsif ($tail eq ".gif") { ($W, $H) = &GifSize($ImgFile); } elsif ($tail eq ".png") { ($W, $H) = &PngSize($ImgFile); } # 画像表示縮小 if ($W > $MaxW || $H > $MaxH) { $W2 = $MaxW / $W; $H2 = $MaxH / $H; if ($W2 < $H2) { $key = $W2; } else { $key = $H2; } $W = int ($W * $key) || 1; $H = int ($H * $key) || 1; } } #------------------# # JPEGサイズ認識 # #------------------# sub JpegSize { local($jpeg) = @_; local($t, $m, $c, $l, $W, $H); open(JPEG,"$jpeg") || return (0,0); binmode JPEG; read(JPEG, $t, 2); while (1) { read(JPEG, $t, 4); ($m, $c, $l) = unpack("a a n", $t); if ($m ne "\xFF") { $W = $H = 0; last; } elsif ((ord($c) >= 0xC0) && (ord($c) <= 0xC3)) { read(JPEG, $t, 5); ($H, $W) = unpack("xnn", $t); last; } else { read(JPEG, $t, ($l - 2)); } } close(JPEG); return ($W, $H); } #-----------------# # GIFサイズ認識 # #-----------------# sub GifSize { local($gif) = @_; local($data); open(GIF,"$gif") || return (0,0); binmode(GIF); sysread(GIF,$data,10); close(GIF); if ($data =~ /^GIF/) { $data = substr($data,-4); } $W = unpack("v",substr($data,0,2)); $H = unpack("v",substr($data,2,2)); return ($W, $H); } #-----------------# # PNGサイズ認識 # #-----------------# sub PngSize { local($png) = @_; local($data); open(PNG, "$png") || return (0,0); binmode(PNG); read(PNG, $data, 24); close(PNG); $W = unpack("N", substr($data, 16, 20)); $H = unpack("N", substr($data, 20, 24)); return ($W, $H); } __END__ LINUX TOP 前ページ 次ページ --- KONDO-NET.GR.JP --- 今日のアクセス人目
掲示板管理者の環境設定の作成
掲示板により変更可能な項目を設定できるようする。 設定画面は、こんな感じ タイトル バックグランド 文字の色 LINKの色 VLINKの色 ALINKの色 罫線の色 罫線の太さ 保管件数 1ページの表示記事数 ホームの設定 管理者メールアドレス タイトル下のフリーエリア 一番下のフリーエリア 画像投稿許可フラグ タグ投稿許可フラグ とりあえず、現時点でのソース(スクリプト)大公開 #!/usr/bin/perl # 上のperlのパスはサーバーによって違うことがあるので、 # プロバイダーのCGI設置案内を参照して下さい。 # 通常は /usr/local/bin/perl または /usr/bin/perl です #=========================================================== # plbbs.cgi Ver 0.0.0 $ver = 'plbbs.cgi V0.00'; # # Copyright (C) 2003 M.Kondo # http://kondo-net.gr.jp/ # # 免責事項 # ・スクリプト利用による損害は、保証できません。 #=========================================================== # サーバーのsendmailのパス # サーバー(プロバイダ)によって違う場合もあるので、確認して下さい $sendmail = '/usr/sbin/sendmail'; #=========================================================== $script = './plbbs.cgi'; # スクリプトファイル名 require 'jcode.pl'; # コード変換ライブラリ取込 require './cgi-lib.pl'; # ライブラリ取込 #=========================================================== $admin_id = '0123'; # 総管理者ID $admin_password = '0123'; # 総管理者パスワード $datapath = './data/'; # データ保管フォルダー #----------------------------------------------------------- # アップロードディレクトリ # → パスの最後は / で終わること # → フルパスだと / から記述する $ImgDir = './img/'; $ImgDir = '/home/httpd/html/test/joyful/img/'; #----------------------------------------------------------- # アップロードディレクトリのURLパス # → パスの最後は / で終わること $ImgUrl = "http://www.xxx.xxx/~xxx/img/"; $ImgUrl = "http://www.kondo-net.gr.jp/test/joyful/img/"; #----------------------------------------------------------- # 添付ファイルのアップロードに失敗したとき # 0 : 添付ファイルは無視し、記事は受理する # 1 : エラー表示して処理を中断する $clip_error = 1; #----------------------------------------------------------- # 投稿受理最大サイズ (bytes) # → 例 : 102400 = 100KB $cgi_lib'maxdata = 102400; #----------------------------------------------------------- # 画像ファイルの最大表示の大きさ(単位:ピクセル) # → これを超える画像は縮小表示します $MaxW = 300; # 横幅 $MaxH = 150; # 縦幅 #=========================================================== ## ロック処理を行うかどうかの選択 (しない=0 する(symlink関数)=1 する(open関数)=2 ) ### 通常は 1 を指定してください ### エラーとなる場合 2 open関数を使用します ### どうしてもエラーとなる場合は 0 しないでやってみる $lockkey = '1'; #=========================================================== $room = 'plbbs'; # デフォルトのルームID @wdays = ( "日", "月", "火", "水", "木", "金", "土", "日" ); $imgwait = 'http://kondo-net.gr.jp/img/soon.gif'; #=========================================================== &decode; # デコード処理 &lock; # ロック処理 &init; &plmain; # メイン処理 &unlock; # ロック解除 exit; #----------------------------------------------------------- # メイン処理 #----------------------------------------------------------- sub plmain() { if($mode eq 'administrator'){ &administrator; } elsif($mode eq 'admin'){ &admin; } elsif($mode eq 'regist'){ ®ist; } elsif($mode eq 'userkill'){ &userkill; } else{ &view; } } #----------------------------------------------------------- # 総管理人 #----------------------------------------------------------- sub administrator() { if($admin_password eq $in{'password'} and $admin_id eq $in{'userid'}){ &header; ## ヘッダー部出力 &footer; ## フッター部出力 }else{ &header; ## ヘッダー部出力 &footer; ## フッター部出力 } } #----------------------------------------------------------- # 管理人 #----------------------------------------------------------- sub admin() { require "$datapath$room.cfg"; if($admin_pass eq $in{'password'} and $room eq $in{'userid'}){ if($in{'action'} eq 'data'){ &editview; }elsif($in{'action'} eq 'env'){ &edit_env; }else{ &adminheader; ## ヘッダー部出力 &adminfooter; ## フッター部出力 } }else{ &adminheader; ## ヘッダー部出力 print <ID・パスワードを入力して下さい ID: PW: 記事・画像許可設定 環境設定 EOM &adminfooter; ## フッター部出力 } # print "-- $datapath$room.cfg -- $admin_pass -- $in{'password'} -- $in{'userid'} --"; } #----------------------------------------------------------- # 管理者環境修正処理 #----------------------------------------------------------- sub edit_env() { my $saveflag=0; # &envdataload; ## データ読み込み if($saveflag == 1){ # &envdatasave; ## データ保管 } &edit_env_view; } #----------------------------------------------------------- sub edit_env_view() { &adminheader; ## ヘッダー部出力 print < タイトル バックグランドカラー バックグランド 文字の色 LINKの色 VLINKの色 ALINKの色 罫線の色 罫線の太さ 保管件数 1ページの表\示記事数 ホームの設定 管理者メールアドレス タイトル下のフリーエリア 一番下のフリーエリア 画像投稿許可フラグ タグ投稿許可フラグ EOM &adminfooter; ## フッター部出力 } #----------------------------------------------------------- # 管理者修正表示処理 #----------------------------------------------------------- sub editview() { my $saveflag=0; &dataload; ## データ読み込み foreach $room_data (@room_datas){ my @logs = split(/<>/,$room_data); foreach $del (@DEL) { if($del eq $logs[0]){ $saveflag=1; $room_data =~ s/.*\n//; my @img = split(/\,/,$logs[6]); if (-e "$ImgDir$room/$img[0]") { unlink("$ImgDir$room/$img[0]"); } } } foreach $edt (@EDT) { if($edt eq $logs[0]){ $saveflag=1; my @img = split(/\,/,$logs[6]); my $ll = "<>$img[0],1,$img[2],$img[3]<>"; $room_data =~ s/<>$logs[6]<>/$ll/; } } } if($saveflag == 1){ &datasave; ## データ保管 } &roomdatas_editview; } #----------------------------------------------------------- #----------------------------------------------------------- sub roomdatas_editview() { my $start,$end,$data_count; if($in{start} == 0){ $start = 0; }else{ $start = 0 + $in{start}; } $nextno = 0 + $start + $cfg{'logpagemax'}; $endno = $nextno; $data_count = 0 + @room_datas; if($endno > $data_count){ $endno = $data_count; } &header; ## ヘッダー部出力 print < EOM for(my $i=$start;$i<$endno;$i++){ roomdata_editview( $room_datas[$i] ); } print < EOM if($endno != $data_count){ print < EOM } print < EOM &footer; ## フッター部出力 } #----------------------------------------------------------- # データ表示処理 # # 0 1 2 3 4 5 6 7 8 9 10 11 12 # no<>name<>email,f1,f2<>title<>msg<>url<>img,f3,w,h<>delkey<>date<>ip<>host<>referer<>AGENT<><><> #----------------------------------------------------------- sub roomdata_editview() { if($_[0] eq ''){ return; } my @logs = split(/<>/,$_[0]); my $sec,$min,$hour,$mday,$mon,$year,$wday; ($sec,$min,$hour,$mday,$mon,$year,$wday)=localtime($logs[8]); # my $strtime = sprintf("%04d%02d%02d%02d%02d%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec); $year+=1900; $mon+=1; my $strdate = "$year年$mon月$mday日(@wdays[$wday])" . sprintf("%02d:%02d:%02d",$hour,$min,$sec); my @dataemail = split(/\,/,$logs[2]); my $strname=$logs[1]; if($dataemail[1]){ $strname="$logs[1] $dataemail[0]"; } my $strurl=''; if($logs[5] ne ''){ $strurl="$logs[5]"; } my @dataimg = split(/\,/,$logs[6]); my $strimg=' '; my $strimgcheck=' '; if($dataimg[0] ne ''){ $strimg = < EOM if($dataimg[1]){ }else{ $strimgcheck = <画像許可 EOM } } print < [$logs[0]]削除 $logs[3] 投稿者:$strname 投稿日:$strdate $strurl $strimg $logs[4] $strimgcheck IP$logs[9] HOST$logs[10] referer$logs[11] AGENT$logs[12] EOM } #----------------------------------------------------------- # ユーザー記事削除処理 #----------------------------------------------------------- sub userkill() { &dataload; ## データ読み込み foreach $room_data (@room_datas){ my @logs = split(/<>/,$room_data); my $delno = $in{'delno'}; my $delkey = $in{'delkey'}; if($delno eq $logs[0]){ if($delkey eq $logs[7]){ $saveflag=1; $room_data =~ s/.*\n//; my @img = split(/\,/,$logs[6]); if (-e "$ImgDir$room/$img[0]") { unlink("$ImgDir$room/$img[0]"); } } last; } } if($saveflag == 1){ &datasave; ## データ保管 } &roomdatas_view; } #----------------------------------------------------------- # 通常表示処理 #----------------------------------------------------------- sub view() { &dataload; ## データ読み込み &roomdatas_view; } #----------------------------------------------------------- #----------------------------------------------------------- sub roomdatas_view() { my $start,$end,$data_count; if($in{start} == 0){ $start = 0; }else{ $start = 0 + $in{start}; } $nextno = 0 + $start + $cfg{'logpagemax'}; $endno = $nextno; $data_count = 0 + @room_datas; if($endno > $data_count){ $endno = $data_count; } &header; ## ヘッダー部出力 &enter_form; ## 投稿部出力 for(my $i=$start;$i<$endno;$i++){ if($room_datas[$i] ne ''){ roomdata_view( $room_datas[$i] ); } } if($endno != $data_count){ $nexthtml=< EOM } print < $nexthtml投稿NO/削除キー/ EOM &footer; ## フッター部出力 } #----------------------------------------------------------- # データ表示処理 # # 0 1 2 3 4 5 6 7 8 9 10 11 12 # no<>name<>email,f1,f2<>title<>msg<>url<>img,f3,w,h<>delkey<>date<>ip<>host<>referer<>AGENT<><><> #----------------------------------------------------------- sub roomdata_view() { my @logs = split(/<>/,$_[0]); my $sec,$min,$hour,$mday,$mon,$year,$wday; ($sec,$min,$hour,$mday,$mon,$year,$wday)=localtime($logs[8]); # my $strtime = sprintf("%04d%02d%02d%02d%02d%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec); $year+=1900; $mon+=1; my $strdate = "$year年$mon月$mday日(@wdays[$wday])" . sprintf("%02d:%02d:%02d",$hour,$min,$sec); my @dataemail = split(/\,/,$logs[2]); my $strname=$logs[1]; if($dataemail[1]){ $strname="$logs[1]"; } my $strurl=''; if($logs[5] ne ''){ $strurl="H"; } my @dataimg = split(/\,/,$logs[6]); my $strimg=''; if($dataimg[0] ne ''){ if($dataimg[1]){ $strimg = < EOM }else{ $strimg = ""; } } print < [$logs[0]] $logs[3] 投稿者:$strname 投稿日:$strdate $strurl $strimg$logs[4] EOM } #----------------------------------------------------------- # 投稿処理 #----------------------------------------------------------- sub regist(){ &dataload; ## データ読込 my $rc= &dataregist; ## データ書込 if($rc){ &roomdatas_view; }else{ &unlock; print "Location: $script?room=$room\n\n"; exit; } } #----------------------------------------------------------- # 投稿フォーム #----------------------------------------------------------- sub enter_form() { print < お名前 メールアドレス 公開 レス通知 タイトル メッセージ </TEXTAREA> 画像 URL 削除キー EOM } #----------------------------------------------------------- # 初期値設定 #----------------------------------------------------------- sub init{ %cfg=( "background" => "", "bgcolor" => "#FFFFFF", "text" => "#000000", "link" => "#0000FF", "vlink" => "#FF00FF", "alink" => "#FF0000", "title" => "掲示板", # タイトル "table_border" => "1", # 罫線太さ "table_bordercolor" => "", # 罫線カラー "logmax" => 50, # 記事保管件数 "logpagemax" => 5, # 1ページの記事表示件数 "homeaddr" => "/", # ホーム "adminemail" => "", # 管理者のメールアドレス "freearea1" => "freearea1", "freearea2" => "freearea2", "imageregistflag" => 0, # 0:画像不可 1:画像投稿許可 "tagsregistflag" => 0, # 0:TAGS不可 1:TAGS投稿許可 ); } #----------------------------------------------------------- # 通常ヘッダー処理 #----------------------------------------------------------- sub header { if($head_flag != 1){ $head_flag=1; print "Content-type: text/html\n\n"; print <<"EOM"; EOM if($admincm ne ''){ print <<"EOM"; $admincm EOM } ## タイトル表示 my $title=$cfg{'title'}; print <<"EOM"; $title EOM my $freearea1=$cfg{'freearea1'}; if($freearea1 ne ''){ print <<"EOM"; $freearea1 EOM } print ""; } } #----------------------------------------------------------- # 通常フッター処理 #----------------------------------------------------------- sub footer { my $freearea2=$cfg{'freearea2'}; if($freearea2 ne ''){ print <<"EOM"; $freearea2 EOM } print <<"EOM"; ID/PW/ - CGI(Perl PHP) - --- KONDO-NET.GR.JP --- EOM } #----------------------------------------------------------- # 管理用ヘッダー処理 #----------------------------------------------------------- sub adminheader { if($head_flag != 1){ $head_flag=1; print "Content-type: text/html\n\n"; print <<"EOM"; PLBBS.CGI管理画面 EOM } } #----------------------------------------------------------- # 管理用フッター処理 #----------------------------------------------------------- sub adminfooter { print <<"EOM"; 掲示板表\示 - CGI(Perl PHP) - --- KONDO-NET.GR.JP --- EOM } #----------------------------------------------------------- # データ読込 #----------------------------------------------------------- sub dataload() { if(!open(DAT,"$datapath$room.dat")){&error("OPEN ERROR $room.dat");} @room_datas = ; close(DAT); } #----------------------------------------------------------- # データ保管 # 0 1 2 3 4 5 6 7 8 9 10 11 12 # no<>name<>email,f1,f2<>title<>msg<>url<>img,f3,w,h<>delkey<>date<>ip<>host<>referer<>AGENT<><><> #----------------------------------------------------------- sub dataregist() { my $strname = $in{'FROM'}; my $stremail = $in{'EMAIL'}; my $stremail_1 = $in{'C1'}; my $stremail_2 = $in{'C2'}; my $strtitle = $in{'TITLE'}; my $strmsg = $in{'MESSAGE'}; my $strurl = $in{'URL'}; # my $strimg = $in{''}; my $strdelkey = $in{'DELKEY'}; my $strtime = time; my $strip = $ENV{'REMOTE_ADDR'}; my $strhost = $ENV{'REMOTE_HOST'}; my $strref = $ENV{'HTTP_REFERER'}; my $stragent = $ENV{'HTTP_USER_AGENT'}; if ($strhost eq '') { $strhost = $strip; } if ($strhost eq $strip) { $strhost = gethostbyaddr(pack('C4',split(/\./,$strhost)),2) || $strip; } if($strname eq '' or $stremail eq '' or $strtitle eq '' or $strmsg eq '' or $strdelkey eq ''){ return 1; } my ($no)=split(/<>/,$room_datas[0]); $no++; # ファイル添付処理 if ($in{'upfile'}) { &UpFile($no); $strimg="$ImgUrl$room/$no$tail"; } my $line="$no<>$strname<>$stremail,$stremail_1,$stremail_2<>$strtitle<>$strmsg<>$strurl<>$strimg,,$W,$H<>$strdelkey<>$strtime<>$strip<>$strhost<>$strref<>$stragent<><><>\n"; $num = unshift(@room_datas, $line); if($num>$cfg{'logmax'}){ pop @room_datas; } &datasave; return 0; } #----------------------------------------------------------- # データ保管 #----------------------------------------------------------- sub datasave() { if(!open(DAT,">$datapath$room.dat")){&error("OPEN ERROR $room.dat");} print DAT @room_datas; close(DAT); } #----------------------------------------------------------- # デコード処理 #----------------------------------------------------------- sub decode(){ &ReadParse; while (($parameter,$value) = each %in) { if ($parameter ne 'upfile') { # シフトJISコードに変換 &jcode'convert(*value, "sjis"); #--正規表現--# $value =~ s/,/./g; $value =~ s/\r\n//g; $value =~ s/\r//g; $value =~ s/\n//g; $value =~ s/</g; $value =~ s/>/>/g; #--削除データがあれば配列に追加--# if ($parameter eq 'delno') { push(@DEL, $value); } #--削除データがあれば配列に追加--# if ($parameter eq 'edtno') { push(@EDT, $value); } } $in{$parameter} = $value; } if($in{'room'} ne ''){ $room = $in{'room'}; } $mode=$in{'mode'}; } #----------------------------------------------------------- # ロック処理 #----------------------------------------------------------- sub lock(){ if($lockflag){ return; } $lockfile = "$datapath$room.loc"; # 1分以上古いロックは削除する if (-e $lockfile) { local($mtime) = (stat($lockfile))[9]; if ($mtime < time - 60) { $lockflag=1; &unlock; } } if ($lockkey eq '1') { #--symlink関数でのロック--# local($retry) = 5; while (!symlink(".",$lockfile)) { if (--$retry <= 0) { &error("アクセスが集中しています"); } sleep(1); } $lockflag = 1; }elsif ($lockkey eq '2') { #--open関数でのロック--# foreach (1 .. 5) { if (-e $lockfile) { sleep(1); } else { open(LOCK,">$lockfile"); close(LOCK); $lockflag = 1; last; } } if ($lockflag == 0) { &error("アクセスが集中しています"); } } } #----------------------------------------------------------- # ロック解除処理 #----------------------------------------------------------- sub unlock(){ if($lockflag){ if (-e $lockfile) { unlink $lockfile; } } $lockflag=0; } #----------------------------------------------------------- # エラー処理 # #----------------------------------------------------------- sub error { if ($lockflag) { &unlock; } &header if (!$head_flag); print "ERROR !\n"; print "$_[0]\n"; print "\n"; &footer; exit; } #--------------------# # 画像アップロード # #--------------------# sub UpFile { my $no = $_[0]; local($macbin,$fname,$flag,$upfile); # 画像処理 $macbin=0; foreach (@in) { if (/(.*)Content-type:(.*)/i) { $tail=$2; } if (/(.*)filename=(.*)/i) { $fname=$2; } if (/application\/x-macbinary/i) { $macbin=1; } } $tail =~ s/\r//g; $tail =~ s/\n//g; $fname =~ tr/\"\x0D\x0A//d; # ファイル形式を認識 $flag=0; if ($tail =~ /image\/gif/i && $gif) { $tail=".gif"; $flag=1; } if ($tail =~ /image\/jpeg/i && $jpeg) { $tail=".jpg"; $flag=1; } if ($tail =~ /image\/x-png/i && $png) { $tail=".png"; $flag=1; } if ($tail =~ /text\/plain/i && $text) { $tail=".txt"; $flag=1; } if ($tail =~ /lha/i && $lha) { $tail=".lzh"; $flag=1; } if ($tail =~ /zip/i && $zip) { $tail=".zip"; $flag=1; } if ($tail =~ /pdf/i && $pdf) { $tail=".pdf"; $flag=1; } if ($tail =~ /audio\/.*mid/i && $midi) { $tail=".mid"; $flag=1; } if ($tail =~ /msword/i && $word) { $tail=".doc"; $flag=1; } if ($tail =~ /ms-excel/i && $excel) { $tail=".xls"; $flag=1; } if ($tail =~ /ms-powerpoint/i && $ppt) { $tail=".ppt"; $flag=1; } if ($tail =~ /audio\/.*realaudio/i && $ram) { $tail=".ram"; $flag=1; } if ($tail =~ /application\/.*realmedia/i && $rm) { $tail=".rm"; $flag=1; } if ($tail =~ /video\/.*mpeg/i && $mpeg) { $tail=".mpg"; $flag=1; } if ($tail =~ /audio\/.*mpeg/i && $mp3) { $tail=".mp3"; $flag=1; } if (!$flag) { # アップロードを許可するファイル形式 # 0:no 1:yes $gif = 1; # GIFファイル $jpeg = 1; # JPEGファイル $png = 1; # PNGファイル if ($fname =~ /\.gif$/i && $gif) { $tail=".gif"; $flag=1; } if ($fname =~ /\.jpe?g$/i && $jpeg) { $tail=".jpg"; $flag=1; } if ($fname =~ /\.png$/i && $png) { $tail=".png"; $flag=1; } if ($fname =~ /\.lzh$/i && $lha) { $tail=".lzh"; $flag=1; } if ($fname =~ /\.txt$/i && $text) { $tail=".txt"; $flag=1; } if ($fname =~ /\.zip$/i && $zip) { $tail=".zip"; $flag=1; } if ($fname =~ /\.pdf$/i && $pdf) { $tail=".pdf"; $flag=1; } if ($fname =~ /\.mid$/i && $midi) { $tail=".mid"; $flag=1; } if ($fname =~ /\.doc$/i && $word) { $tail=".doc"; $flag=1; } if ($fname =~ /\.xls$/i && $excel) { $tail=".xls"; $flag=1; } if ($fname =~ /\.ppt$/i && $ppt) { $tail=".ppt"; $flag=1; } if ($fname =~ /\.ram$/i && $ram) { $tail=".ram"; $flag=1; } if ($fname =~ /\.rm$/i && $rm) { $tail=".rm"; $flag=1; } if ($fname =~ /\.mpe?g$/i && $mpeg) { $tail=".mpg"; $flag=1; } if ($fname =~ /\.mp3$/i && $mp3) { $tail=".mp3"; $flag=1; } } # アップロード失敗処理 if (!$flag && !$clip_error) { return; } elsif (!$flag && $clip_error) { &error("アップロードできないファイル形式です"); } $upfile = $in{'upfile'}; # マックバイナリ対策 if ($macbin) { $length = substr($upfile,83,4); $length = unpack("%N",$length); $upfile = substr($upfile,128,$length); } # 添付データを書き込み $ImgFile = "$ImgDir$room/$no$tail"; open(OUT,"> $ImgFile") || &error("アップロード失敗"); binmode(OUT); binmode(STDOUT); print OUT $upfile; close(OUT); chmod (0666,$ImgFile); # 画像サイズ取得 if ($tail eq ".jpg") { ($W, $H) = &JpegSize($ImgFile); } elsif ($tail eq ".gif") { ($W, $H) = &GifSize($ImgFile); } elsif ($tail eq ".png") { ($W, $H) = &PngSize($ImgFile); } # 画像表示縮小 if ($W > $MaxW || $H > $MaxH) { $W2 = $MaxW / $W; $H2 = $MaxH / $H; if ($W2 < $H2) { $key = $W2; } else { $key = $H2; } $W = int ($W * $key) || 1; $H = int ($H * $key) || 1; } } #------------------# # JPEGサイズ認識 # #------------------# sub JpegSize { local($jpeg) = @_; local($t, $m, $c, $l, $W, $H); open(JPEG,"$jpeg") || return (0,0); binmode JPEG; read(JPEG, $t, 2); while (1) { read(JPEG, $t, 4); ($m, $c, $l) = unpack("a a n", $t); if ($m ne "\xFF") { $W = $H = 0; last; } elsif ((ord($c) >= 0xC0) && (ord($c) <= 0xC3)) { read(JPEG, $t, 5); ($H, $W) = unpack("xnn", $t); last; } else { read(JPEG, $t, ($l - 2)); } } close(JPEG); return ($W, $H); } #-----------------# # GIFサイズ認識 # #-----------------# sub GifSize { local($gif) = @_; local($data); open(GIF,"$gif") || return (0,0); binmode(GIF); sysread(GIF,$data,10); close(GIF); if ($data =~ /^GIF/) { $data = substr($data,-4); } $W = unpack("v",substr($data,0,2)); $H = unpack("v",substr($data,2,2)); return ($W, $H); } #-----------------# # PNGサイズ認識 # #-----------------# sub PngSize { local($png) = @_; local($data); open(PNG, "$png") || return (0,0); binmode(PNG); read(PNG, $data, 24); close(PNG); $W = unpack("N", substr($data, 16, 20)); $H = unpack("N", substr($data, 20, 24)); return ($W, $H); } __END__ LINUX TOP 前ページ 次ページ --- KONDO-NET.GR.JP --- 今日のアクセス人目
掲示板により変更可能な項目を設定できるようする。
設定画面は、こんな感じ
とりあえず、現時点でのソース(スクリプト)大公開
#!/usr/bin/perl # 上のperlのパスはサーバーによって違うことがあるので、 # プロバイダーのCGI設置案内を参照して下さい。 # 通常は /usr/local/bin/perl または /usr/bin/perl です #=========================================================== # plbbs.cgi Ver 0.0.0 $ver = 'plbbs.cgi V0.00'; # # Copyright (C) 2003 M.Kondo # http://kondo-net.gr.jp/ # # 免責事項 # ・スクリプト利用による損害は、保証できません。 #=========================================================== # サーバーのsendmailのパス # サーバー(プロバイダ)によって違う場合もあるので、確認して下さい $sendmail = '/usr/sbin/sendmail'; #=========================================================== $script = './plbbs.cgi'; # スクリプトファイル名 require 'jcode.pl'; # コード変換ライブラリ取込 require './cgi-lib.pl'; # ライブラリ取込 #=========================================================== $admin_id = '0123'; # 総管理者ID $admin_password = '0123'; # 総管理者パスワード $datapath = './data/'; # データ保管フォルダー #----------------------------------------------------------- # アップロードディレクトリ # → パスの最後は / で終わること # → フルパスだと / から記述する $ImgDir = './img/'; $ImgDir = '/home/httpd/html/test/joyful/img/'; #----------------------------------------------------------- # アップロードディレクトリのURLパス # → パスの最後は / で終わること $ImgUrl = "http://www.xxx.xxx/~xxx/img/"; $ImgUrl = "http://www.kondo-net.gr.jp/test/joyful/img/"; #----------------------------------------------------------- # 添付ファイルのアップロードに失敗したとき # 0 : 添付ファイルは無視し、記事は受理する # 1 : エラー表示して処理を中断する $clip_error = 1; #----------------------------------------------------------- # 投稿受理最大サイズ (bytes) # → 例 : 102400 = 100KB $cgi_lib'maxdata = 102400; #----------------------------------------------------------- # 画像ファイルの最大表示の大きさ(単位:ピクセル) # → これを超える画像は縮小表示します $MaxW = 300; # 横幅 $MaxH = 150; # 縦幅 #=========================================================== ## ロック処理を行うかどうかの選択 (しない=0 する(symlink関数)=1 する(open関数)=2 ) ### 通常は 1 を指定してください ### エラーとなる場合 2 open関数を使用します ### どうしてもエラーとなる場合は 0 しないでやってみる $lockkey = '1'; #=========================================================== $room = 'plbbs'; # デフォルトのルームID @wdays = ( "日", "月", "火", "水", "木", "金", "土", "日" ); $imgwait = 'http://kondo-net.gr.jp/img/soon.gif'; #=========================================================== &decode; # デコード処理 &lock; # ロック処理 &init; &plmain; # メイン処理 &unlock; # ロック解除 exit; #----------------------------------------------------------- # メイン処理 #----------------------------------------------------------- sub plmain() { if($mode eq 'administrator'){ &administrator; } elsif($mode eq 'admin'){ &admin; } elsif($mode eq 'regist'){ ®ist; } elsif($mode eq 'userkill'){ &userkill; } else{ &view; } } #----------------------------------------------------------- # 総管理人 #----------------------------------------------------------- sub administrator() { if($admin_password eq $in{'password'} and $admin_id eq $in{'userid'}){ &header; ## ヘッダー部出力 &footer; ## フッター部出力 }else{ &header; ## ヘッダー部出力 &footer; ## フッター部出力 } } #----------------------------------------------------------- # 管理人 #----------------------------------------------------------- sub admin() { require "$datapath$room.cfg"; if($admin_pass eq $in{'password'} and $room eq $in{'userid'}){ if($in{'action'} eq 'data'){ &editview; }elsif($in{'action'} eq 'env'){ &edit_env; }else{ &adminheader; ## ヘッダー部出力 &adminfooter; ## フッター部出力 } }else{ &adminheader; ## ヘッダー部出力 print <ID・パスワードを入力して下さい ID: PW: 記事・画像許可設定 環境設定 EOM &adminfooter; ## フッター部出力 } # print "-- $datapath$room.cfg -- $admin_pass -- $in{'password'} -- $in{'userid'} --"; } #----------------------------------------------------------- # 管理者環境修正処理 #----------------------------------------------------------- sub edit_env() { my $saveflag=0; # &envdataload; ## データ読み込み if($saveflag == 1){ # &envdatasave; ## データ保管 } &edit_env_view; } #----------------------------------------------------------- sub edit_env_view() { &adminheader; ## ヘッダー部出力 print < タイトル バックグランドカラー バックグランド 文字の色 LINKの色 VLINKの色 ALINKの色 罫線の色 罫線の太さ 保管件数 1ページの表\示記事数 ホームの設定 管理者メールアドレス タイトル下のフリーエリア 一番下のフリーエリア 画像投稿許可フラグ タグ投稿許可フラグ EOM &adminfooter; ## フッター部出力 } #----------------------------------------------------------- # 管理者修正表示処理 #----------------------------------------------------------- sub editview() { my $saveflag=0; &dataload; ## データ読み込み foreach $room_data (@room_datas){ my @logs = split(/<>/,$room_data); foreach $del (@DEL) { if($del eq $logs[0]){ $saveflag=1; $room_data =~ s/.*\n//; my @img = split(/\,/,$logs[6]); if (-e "$ImgDir$room/$img[0]") { unlink("$ImgDir$room/$img[0]"); } } } foreach $edt (@EDT) { if($edt eq $logs[0]){ $saveflag=1; my @img = split(/\,/,$logs[6]); my $ll = "<>$img[0],1,$img[2],$img[3]<>"; $room_data =~ s/<>$logs[6]<>/$ll/; } } } if($saveflag == 1){ &datasave; ## データ保管 } &roomdatas_editview; } #----------------------------------------------------------- #----------------------------------------------------------- sub roomdatas_editview() { my $start,$end,$data_count; if($in{start} == 0){ $start = 0; }else{ $start = 0 + $in{start}; } $nextno = 0 + $start + $cfg{'logpagemax'}; $endno = $nextno; $data_count = 0 + @room_datas; if($endno > $data_count){ $endno = $data_count; } &header; ## ヘッダー部出力 print < EOM for(my $i=$start;$i<$endno;$i++){ roomdata_editview( $room_datas[$i] ); } print < EOM if($endno != $data_count){ print < EOM } print < EOM &footer; ## フッター部出力 } #----------------------------------------------------------- # データ表示処理 # # 0 1 2 3 4 5 6 7 8 9 10 11 12 # no<>name<>email,f1,f2<>title<>msg<>url<>img,f3,w,h<>delkey<>date<>ip<>host<>referer<>AGENT<><><> #----------------------------------------------------------- sub roomdata_editview() { if($_[0] eq ''){ return; } my @logs = split(/<>/,$_[0]); my $sec,$min,$hour,$mday,$mon,$year,$wday; ($sec,$min,$hour,$mday,$mon,$year,$wday)=localtime($logs[8]); # my $strtime = sprintf("%04d%02d%02d%02d%02d%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec); $year+=1900; $mon+=1; my $strdate = "$year年$mon月$mday日(@wdays[$wday])" . sprintf("%02d:%02d:%02d",$hour,$min,$sec); my @dataemail = split(/\,/,$logs[2]); my $strname=$logs[1]; if($dataemail[1]){ $strname="$logs[1] $dataemail[0]"; } my $strurl=''; if($logs[5] ne ''){ $strurl="$logs[5]"; } my @dataimg = split(/\,/,$logs[6]); my $strimg=' '; my $strimgcheck=' '; if($dataimg[0] ne ''){ $strimg = < EOM if($dataimg[1]){ }else{ $strimgcheck = <画像許可 EOM } } print < [$logs[0]]削除 $logs[3] 投稿者:$strname 投稿日:$strdate $strurl $strimg $logs[4] $strimgcheck IP$logs[9] HOST$logs[10] referer$logs[11] AGENT$logs[12] EOM } #----------------------------------------------------------- # ユーザー記事削除処理 #----------------------------------------------------------- sub userkill() { &dataload; ## データ読み込み foreach $room_data (@room_datas){ my @logs = split(/<>/,$room_data); my $delno = $in{'delno'}; my $delkey = $in{'delkey'}; if($delno eq $logs[0]){ if($delkey eq $logs[7]){ $saveflag=1; $room_data =~ s/.*\n//; my @img = split(/\,/,$logs[6]); if (-e "$ImgDir$room/$img[0]") { unlink("$ImgDir$room/$img[0]"); } } last; } } if($saveflag == 1){ &datasave; ## データ保管 } &roomdatas_view; } #----------------------------------------------------------- # 通常表示処理 #----------------------------------------------------------- sub view() { &dataload; ## データ読み込み &roomdatas_view; } #----------------------------------------------------------- #----------------------------------------------------------- sub roomdatas_view() { my $start,$end,$data_count; if($in{start} == 0){ $start = 0; }else{ $start = 0 + $in{start}; } $nextno = 0 + $start + $cfg{'logpagemax'}; $endno = $nextno; $data_count = 0 + @room_datas; if($endno > $data_count){ $endno = $data_count; } &header; ## ヘッダー部出力 &enter_form; ## 投稿部出力 for(my $i=$start;$i<$endno;$i++){ if($room_datas[$i] ne ''){ roomdata_view( $room_datas[$i] ); } } if($endno != $data_count){ $nexthtml=< EOM } print < $nexthtml投稿NO/削除キー/ EOM &footer; ## フッター部出力 } #----------------------------------------------------------- # データ表示処理 # # 0 1 2 3 4 5 6 7 8 9 10 11 12 # no<>name<>email,f1,f2<>title<>msg<>url<>img,f3,w,h<>delkey<>date<>ip<>host<>referer<>AGENT<><><> #----------------------------------------------------------- sub roomdata_view() { my @logs = split(/<>/,$_[0]); my $sec,$min,$hour,$mday,$mon,$year,$wday; ($sec,$min,$hour,$mday,$mon,$year,$wday)=localtime($logs[8]); # my $strtime = sprintf("%04d%02d%02d%02d%02d%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec); $year+=1900; $mon+=1; my $strdate = "$year年$mon月$mday日(@wdays[$wday])" . sprintf("%02d:%02d:%02d",$hour,$min,$sec); my @dataemail = split(/\,/,$logs[2]); my $strname=$logs[1]; if($dataemail[1]){ $strname="$logs[1]"; } my $strurl=''; if($logs[5] ne ''){ $strurl="H"; } my @dataimg = split(/\,/,$logs[6]); my $strimg=''; if($dataimg[0] ne ''){ if($dataimg[1]){ $strimg = < EOM }else{ $strimg = ""; } } print < [$logs[0]] $logs[3] 投稿者:$strname 投稿日:$strdate $strurl $strimg$logs[4] EOM } #----------------------------------------------------------- # 投稿処理 #----------------------------------------------------------- sub regist(){ &dataload; ## データ読込 my $rc= &dataregist; ## データ書込 if($rc){ &roomdatas_view; }else{ &unlock; print "Location: $script?room=$room\n\n"; exit; } } #----------------------------------------------------------- # 投稿フォーム #----------------------------------------------------------- sub enter_form() { print < お名前 メールアドレス 公開 レス通知 タイトル メッセージ </TEXTAREA> 画像 URL 削除キー EOM } #----------------------------------------------------------- # 初期値設定 #----------------------------------------------------------- sub init{ %cfg=( "background" => "", "bgcolor" => "#FFFFFF", "text" => "#000000", "link" => "#0000FF", "vlink" => "#FF00FF", "alink" => "#FF0000", "title" => "掲示板", # タイトル "table_border" => "1", # 罫線太さ "table_bordercolor" => "", # 罫線カラー "logmax" => 50, # 記事保管件数 "logpagemax" => 5, # 1ページの記事表示件数 "homeaddr" => "/", # ホーム "adminemail" => "", # 管理者のメールアドレス "freearea1" => "freearea1", "freearea2" => "freearea2", "imageregistflag" => 0, # 0:画像不可 1:画像投稿許可 "tagsregistflag" => 0, # 0:TAGS不可 1:TAGS投稿許可 ); } #----------------------------------------------------------- # 通常ヘッダー処理 #----------------------------------------------------------- sub header { if($head_flag != 1){ $head_flag=1; print "Content-type: text/html\n\n"; print <<"EOM"; EOM if($admincm ne ''){ print <<"EOM"; $admincm EOM } ## タイトル表示 my $title=$cfg{'title'}; print <<"EOM"; $title EOM my $freearea1=$cfg{'freearea1'}; if($freearea1 ne ''){ print <<"EOM"; $freearea1 EOM } print ""; } } #----------------------------------------------------------- # 通常フッター処理 #----------------------------------------------------------- sub footer { my $freearea2=$cfg{'freearea2'}; if($freearea2 ne ''){ print <<"EOM"; $freearea2 EOM } print <<"EOM"; ID/PW/ - CGI(Perl PHP) - --- KONDO-NET.GR.JP --- EOM } #----------------------------------------------------------- # 管理用ヘッダー処理 #----------------------------------------------------------- sub adminheader { if($head_flag != 1){ $head_flag=1; print "Content-type: text/html\n\n"; print <<"EOM"; PLBBS.CGI管理画面 EOM } } #----------------------------------------------------------- # 管理用フッター処理 #----------------------------------------------------------- sub adminfooter { print <<"EOM"; 掲示板表\示 - CGI(Perl PHP) - --- KONDO-NET.GR.JP --- EOM } #----------------------------------------------------------- # データ読込 #----------------------------------------------------------- sub dataload() { if(!open(DAT,"$datapath$room.dat")){&error("OPEN ERROR $room.dat");} @room_datas = ; close(DAT); } #----------------------------------------------------------- # データ保管 # 0 1 2 3 4 5 6 7 8 9 10 11 12 # no<>name<>email,f1,f2<>title<>msg<>url<>img,f3,w,h<>delkey<>date<>ip<>host<>referer<>AGENT<><><> #----------------------------------------------------------- sub dataregist() { my $strname = $in{'FROM'}; my $stremail = $in{'EMAIL'}; my $stremail_1 = $in{'C1'}; my $stremail_2 = $in{'C2'}; my $strtitle = $in{'TITLE'}; my $strmsg = $in{'MESSAGE'}; my $strurl = $in{'URL'}; # my $strimg = $in{''}; my $strdelkey = $in{'DELKEY'}; my $strtime = time; my $strip = $ENV{'REMOTE_ADDR'}; my $strhost = $ENV{'REMOTE_HOST'}; my $strref = $ENV{'HTTP_REFERER'}; my $stragent = $ENV{'HTTP_USER_AGENT'}; if ($strhost eq '') { $strhost = $strip; } if ($strhost eq $strip) { $strhost = gethostbyaddr(pack('C4',split(/\./,$strhost)),2) || $strip; } if($strname eq '' or $stremail eq '' or $strtitle eq '' or $strmsg eq '' or $strdelkey eq ''){ return 1; } my ($no)=split(/<>/,$room_datas[0]); $no++; # ファイル添付処理 if ($in{'upfile'}) { &UpFile($no); $strimg="$ImgUrl$room/$no$tail"; } my $line="$no<>$strname<>$stremail,$stremail_1,$stremail_2<>$strtitle<>$strmsg<>$strurl<>$strimg,,$W,$H<>$strdelkey<>$strtime<>$strip<>$strhost<>$strref<>$stragent<><><>\n"; $num = unshift(@room_datas, $line); if($num>$cfg{'logmax'}){ pop @room_datas; } &datasave; return 0; } #----------------------------------------------------------- # データ保管 #----------------------------------------------------------- sub datasave() { if(!open(DAT,">$datapath$room.dat")){&error("OPEN ERROR $room.dat");} print DAT @room_datas; close(DAT); } #----------------------------------------------------------- # デコード処理 #----------------------------------------------------------- sub decode(){ &ReadParse; while (($parameter,$value) = each %in) { if ($parameter ne 'upfile') { # シフトJISコードに変換 &jcode'convert(*value, "sjis"); #--正規表現--# $value =~ s/,/./g; $value =~ s/\r\n//g; $value =~ s/\r//g; $value =~ s/\n//g; $value =~ s/</g; $value =~ s/>/>/g; #--削除データがあれば配列に追加--# if ($parameter eq 'delno') { push(@DEL, $value); } #--削除データがあれば配列に追加--# if ($parameter eq 'edtno') { push(@EDT, $value); } } $in{$parameter} = $value; } if($in{'room'} ne ''){ $room = $in{'room'}; } $mode=$in{'mode'}; } #----------------------------------------------------------- # ロック処理 #----------------------------------------------------------- sub lock(){ if($lockflag){ return; } $lockfile = "$datapath$room.loc"; # 1分以上古いロックは削除する if (-e $lockfile) { local($mtime) = (stat($lockfile))[9]; if ($mtime < time - 60) { $lockflag=1; &unlock; } } if ($lockkey eq '1') { #--symlink関数でのロック--# local($retry) = 5; while (!symlink(".",$lockfile)) { if (--$retry <= 0) { &error("アクセスが集中しています"); } sleep(1); } $lockflag = 1; }elsif ($lockkey eq '2') { #--open関数でのロック--# foreach (1 .. 5) { if (-e $lockfile) { sleep(1); } else { open(LOCK,">$lockfile"); close(LOCK); $lockflag = 1; last; } } if ($lockflag == 0) { &error("アクセスが集中しています"); } } } #----------------------------------------------------------- # ロック解除処理 #----------------------------------------------------------- sub unlock(){ if($lockflag){ if (-e $lockfile) { unlink $lockfile; } } $lockflag=0; } #----------------------------------------------------------- # エラー処理 # #----------------------------------------------------------- sub error { if ($lockflag) { &unlock; } &header if (!$head_flag); print "ERROR !\n"; print "$_[0]\n"; print "\n"; &footer; exit; } #--------------------# # 画像アップロード # #--------------------# sub UpFile { my $no = $_[0]; local($macbin,$fname,$flag,$upfile); # 画像処理 $macbin=0; foreach (@in) { if (/(.*)Content-type:(.*)/i) { $tail=$2; } if (/(.*)filename=(.*)/i) { $fname=$2; } if (/application\/x-macbinary/i) { $macbin=1; } } $tail =~ s/\r//g; $tail =~ s/\n//g; $fname =~ tr/\"\x0D\x0A//d; # ファイル形式を認識 $flag=0; if ($tail =~ /image\/gif/i && $gif) { $tail=".gif"; $flag=1; } if ($tail =~ /image\/jpeg/i && $jpeg) { $tail=".jpg"; $flag=1; } if ($tail =~ /image\/x-png/i && $png) { $tail=".png"; $flag=1; } if ($tail =~ /text\/plain/i && $text) { $tail=".txt"; $flag=1; } if ($tail =~ /lha/i && $lha) { $tail=".lzh"; $flag=1; } if ($tail =~ /zip/i && $zip) { $tail=".zip"; $flag=1; } if ($tail =~ /pdf/i && $pdf) { $tail=".pdf"; $flag=1; } if ($tail =~ /audio\/.*mid/i && $midi) { $tail=".mid"; $flag=1; } if ($tail =~ /msword/i && $word) { $tail=".doc"; $flag=1; } if ($tail =~ /ms-excel/i && $excel) { $tail=".xls"; $flag=1; } if ($tail =~ /ms-powerpoint/i && $ppt) { $tail=".ppt"; $flag=1; } if ($tail =~ /audio\/.*realaudio/i && $ram) { $tail=".ram"; $flag=1; } if ($tail =~ /application\/.*realmedia/i && $rm) { $tail=".rm"; $flag=1; } if ($tail =~ /video\/.*mpeg/i && $mpeg) { $tail=".mpg"; $flag=1; } if ($tail =~ /audio\/.*mpeg/i && $mp3) { $tail=".mp3"; $flag=1; } if (!$flag) { # アップロードを許可するファイル形式 # 0:no 1:yes $gif = 1; # GIFファイル $jpeg = 1; # JPEGファイル $png = 1; # PNGファイル if ($fname =~ /\.gif$/i && $gif) { $tail=".gif"; $flag=1; } if ($fname =~ /\.jpe?g$/i && $jpeg) { $tail=".jpg"; $flag=1; } if ($fname =~ /\.png$/i && $png) { $tail=".png"; $flag=1; } if ($fname =~ /\.lzh$/i && $lha) { $tail=".lzh"; $flag=1; } if ($fname =~ /\.txt$/i && $text) { $tail=".txt"; $flag=1; } if ($fname =~ /\.zip$/i && $zip) { $tail=".zip"; $flag=1; } if ($fname =~ /\.pdf$/i && $pdf) { $tail=".pdf"; $flag=1; } if ($fname =~ /\.mid$/i && $midi) { $tail=".mid"; $flag=1; } if ($fname =~ /\.doc$/i && $word) { $tail=".doc"; $flag=1; } if ($fname =~ /\.xls$/i && $excel) { $tail=".xls"; $flag=1; } if ($fname =~ /\.ppt$/i && $ppt) { $tail=".ppt"; $flag=1; } if ($fname =~ /\.ram$/i && $ram) { $tail=".ram"; $flag=1; } if ($fname =~ /\.rm$/i && $rm) { $tail=".rm"; $flag=1; } if ($fname =~ /\.mpe?g$/i && $mpeg) { $tail=".mpg"; $flag=1; } if ($fname =~ /\.mp3$/i && $mp3) { $tail=".mp3"; $flag=1; } } # アップロード失敗処理 if (!$flag && !$clip_error) { return; } elsif (!$flag && $clip_error) { &error("アップロードできないファイル形式です"); } $upfile = $in{'upfile'}; # マックバイナリ対策 if ($macbin) { $length = substr($upfile,83,4); $length = unpack("%N",$length); $upfile = substr($upfile,128,$length); } # 添付データを書き込み $ImgFile = "$ImgDir$room/$no$tail"; open(OUT,"> $ImgFile") || &error("アップロード失敗"); binmode(OUT); binmode(STDOUT); print OUT $upfile; close(OUT); chmod (0666,$ImgFile); # 画像サイズ取得 if ($tail eq ".jpg") { ($W, $H) = &JpegSize($ImgFile); } elsif ($tail eq ".gif") { ($W, $H) = &GifSize($ImgFile); } elsif ($tail eq ".png") { ($W, $H) = &PngSize($ImgFile); } # 画像表示縮小 if ($W > $MaxW || $H > $MaxH) { $W2 = $MaxW / $W; $H2 = $MaxH / $H; if ($W2 < $H2) { $key = $W2; } else { $key = $H2; } $W = int ($W * $key) || 1; $H = int ($H * $key) || 1; } } #------------------# # JPEGサイズ認識 # #------------------# sub JpegSize { local($jpeg) = @_; local($t, $m, $c, $l, $W, $H); open(JPEG,"$jpeg") || return (0,0); binmode JPEG; read(JPEG, $t, 2); while (1) { read(JPEG, $t, 4); ($m, $c, $l) = unpack("a a n", $t); if ($m ne "\xFF") { $W = $H = 0; last; } elsif ((ord($c) >= 0xC0) && (ord($c) <= 0xC3)) { read(JPEG, $t, 5); ($H, $W) = unpack("xnn", $t); last; } else { read(JPEG, $t, ($l - 2)); } } close(JPEG); return ($W, $H); } #-----------------# # GIFサイズ認識 # #-----------------# sub GifSize { local($gif) = @_; local($data); open(GIF,"$gif") || return (0,0); binmode(GIF); sysread(GIF,$data,10); close(GIF); if ($data =~ /^GIF/) { $data = substr($data,-4); } $W = unpack("v",substr($data,0,2)); $H = unpack("v",substr($data,2,2)); return ($W, $H); } #-----------------# # PNGサイズ認識 # #-----------------# sub PngSize { local($png) = @_; local($data); open(PNG, "$png") || return (0,0); binmode(PNG); read(PNG, $data, 24); close(PNG); $W = unpack("N", substr($data, 16, 20)); $H = unpack("N", substr($data, 20, 24)); return ($W, $H); } __END__ LINUX TOP 前ページ 次ページ --- KONDO-NET.GR.JP --- 今日のアクセス人目
- CGI(Perl PHP) -
--- KONDO-NET.GR.JP ---
LINUX TOP 前ページ 次ページ