# ↑サーバに合わせて変更してください。 # 通常 (#!/usr/local/bin/perl) もしくは (#!/usr/bin/perl) # ################################################################## # Lindenbaum(Tree BBS) $ver = '1.2'; # Copyright (C) 2002-2004 Missing Link. # All rights reserved. # 作成者 Sho # E-mail: sho@area-s.com # Home Page: http://www.area-s.com/ # このスクリプトはフリーウェアです。 # 本スクリプトを利用する方は以下のURLに記載された # 利用既定に同意したものとみなします。 # http://www.area-s.com/main/rule.html # 著作権はMISSING LINKが保有します。 # 質問等はサポート掲示板まで。 # http://www.area-s.com/main/support.html # ################################################################## # ############################ 初期処理 ############################ require 'set.cgi'; unshift(@mrk_img,undef); unshift(@mrk_inf,undef); if (!$use_mrk) { undef @mrk_inf; undef @mrk_img; } foreach(1 .. $#mrk_img) { $mrk_img[$_] = qq||; $tag .= qq|$mrk_img[$_]:$mrk_inf[$_] |; } $mrk_inf = qq|□ マーク:$tag| if $use_mrk; $TM = 3;$NM = 5;$PS = 6;$HT = 12;$RS = 15; $NW = time - $new_tim * 3600; # ############################ 処理終了 ############################ # ######################## 設定チェック開始 ######################## if ($set_chk) { &error("ディレクトリのパーミッションをチェックしてください") unless -r '../' || -w '../' || -x '../'; &error("管理パスワードを変更して下さい[set.cgiの48行目]") if $mgr_pas eq '0000'; &error("本人識別機能を有効にする場合は暗号キーを設定して下さい[set.cgiの59行目]") if $osf_key eq '0000' && $use_osf; &error("本人識別機能を有効にする場合はパスワードを暗号化して下さい[set.cgiの43行目]") if !$use_crp && $use_osf; if ($mke_pst) { &error("過去ログ用のディレクトリ$pst_dirが存在しません") unless -e "$pst_dir/"; &error("過去ログ用のディレクトリのパーミッションをチェックしてください") unless -r $pst_dir || -w $pst_dir || -x $pst_dir; } } # ######################## 設定チェック終了 ######################## # ######################## メインプログラム ######################## # &error("ただいまメンテナンス中です"); &ip_check; &for_old_version if $use_old; &decode; if ($F{'md'} eq '') { &base_view } else { &{$F{'md'}} } exit; # ######################### プログラム終了 ######################### # ######################## 以下サブルーチン ######################## # Sub Base View # sub base_view { &header('java'); if ($use_ctr) { ($data) = &open_dat($cnt_dat); $CT = (split(/,/,$data))[0]; print qq||; print qq|Count: $CT| if $CT; } &title; &menu('info','mark'); &tree_view; &delete_form; &footer; } # Sub Tree View # sub tree_view { &lock; @BL = &open_dat($log_cgi); &unlock; &page($F{'pg'},$#BL,$pge_log); foreach ($start .. $end) { &split_data($BL[$_],'m'); &print_sub; print &print_leaf; if ($rs) { @RL = split(/<->/,$rs); foreach (@RL) { &split_data($_,'r'); &print_sub; print &print_leaf; } } &hr if $use_lne; } &hr if !$use_lne; &page_link($#BL); } # Sub New View # sub new_view { &lock; @BL = &open_dat($log_cgi); &unlock; foreach (@BL) { push(@RL,split(/<->/,(split(/<>/))[$RS])) } @RL = map { join('<>',split(/×/)) } @RL; push(@BL,@RL); undef @RL; @BL = map { $_->[0] } sort { $b->[1] <=> $a->[1] } grep { $_->[1] > $NW } map { [$_,(split(/<>/))[$TM]] } @BL; &header('java'); &title; &menu('','mark'); &label("$new_tim時間以内の投稿を新着順に表\示します。"); &hr; foreach (@BL) { &split_data($_,'m'); &print_sub; &read_view('button'); } &footer; } # Sub All View # sub all_view { &lock; ($BL) = map { $_->[0] } grep { $_->[1] eq $F{'mn'} } map { [$_,(split(/<>/))[0]] } &open_dat($log_cgi); &unlock; &header('java'); &title; &menu('','mark'); &split_data($BL,'m'); &print_sub; &read_view('button'); $tag = &print_leaf; @RL = split(/<->/,$rs); foreach (@RL) { &split_data($_,'r'); &print_sub; &read_view('button'); $tag .= &print_leaf; } print $tag; &hr; &footer; } # Sub Main Regist # sub main_regist { &get_cookie; &header('java'); &title; &menu('','mark'); ®ist_form; &footer; } # Sub Res Regist # sub res_regist { $F{'mn'} || &error('エラー:引数が指定されていません'); &lock; ($BL) = map { $_->[0] } grep { $_->[1] eq $F{'mn'} } map { [$_,(split(/<>/))[0]] } &open_dat($log_cgi); &unlock; &get_cookie; &header('java'); &title; &menu('info','mark'); &split_data($BL,'m'); &print_sub; &res_view; $tag = &print_leaf; @RL = split(/<->/,$rs); foreach (@RL) { &split_data($_,'r'); &print_sub; &res_view; $tag .= &print_leaf; } print $tag; &hr; ®ist_form; &footer; } # Sub Print Sub # sub print_sub { $id = &print_id if $use_osf; $lf = $use_lif && $lf ? $lif_img : undef; $nm &&= qq|$nm| if $mgr_lne && &get_crypt($mgr_pas,$ps,1); } # Sub Print Leaf # sub print_leaf { my $leaf; if (!$cs) { $nw = $tm > $NW ? $aln_img : $all_img; $nw = qq|$nw|; } else { $nw = $tm > $NW ? $rsn_img : $res_img; $pd = $cs * $res_poz; } $tl = substr($tl,0,$ttl_cut - 2) . "\ ・・" if length($tl) > $ttl_cut && $cm; $tl = qq|$tl|; $tl = qq|(T/O) $tl| if !$cm; $leaf = qq|$nw $tl $nm $id $dt | . qq|[$no] $mrk_img[$mk] $lf|; $leaf = qq|
$leaf
\n| if !$cs; $leaf = qq|
$leaf
\n| if $cs; $leaf = qq|$leaf\n| if $no == $F{'rn'}; return $leaf; } # Sub Read View # sub read_view { my $Cm = $cm; $ml &&= "$ml"; $ul &&= "http://$ul"; if ($F{'md'} ne 'search') { $Cm =~ s/(https?|ftp|gopher|telnet|whois|news)\:([\w|\:\!\#\$\%\=\&\-\^\`\\\|\@\~\[\{\]\}\;\+\*\,\.\?\/]*)/$1\:$2<\/a>/ig; $Cm =~ s/([\>]|^)(>[^<]*)/$1$2<\/span>/g if $ref_clr; } if ($cd) { $Cm =~ s/
/\n/g; $Cm &&= "
$Cm
"; } $Cm &&= "
$Cm
"; push(@TL,[['記事番号','b',0,0,'nowrap'],[':'],[$no,0,'100%']]) if $_[0] ne 'preview'; push(@TL,[['投稿時間','b',0,0,'nowrap'],[':'],[$dt]]) if $_[0] ne 'preview'; push(@TL,[['投稿者名','b',0,0,'nowrap'],[':'],["$nm $id $mrk_img[$mk] $lf"]]); push(@TL,[['メール','b',0,0,'nowrap'],[':'],[$ml]]); push(@TL,[['サイト','b',0,0,'nowrap'],[':'],[$ul]]); push(@TL,[['タイトル','b',0,0,'nowrap'],[':'],[$tl]]); push(@TL,[[$Cm]]) if $Cm; push(@TL,[[&sbmt(value=>'決定').&bttn(value=>'戻る',option=>1),'','','right']]) if $_[0] eq 'preview'; &table(row=>$#TL+1,col=>3,aln=>$align,d=>[@TL]); undef @TL; print qq|
[返信]
\n| if $_[0] eq 'button'; &hr; } # Sub Res View # sub res_view { return if $no ne $F{'rn'}; $re_tl = $tl; $re_cm = $cm ? $cm : $tl; &read_view; } # Sub Preview # sub preview { &double_check; &header('java'); &title; &menu('','mark'); &form('start'); $F{'to'} && undef $F{'cm'}; &split_data(&join_data('m'),'m'); $align = 'center'; &label('以下の内容で投稿します。'); &hr; &read_view('preview'); $F{'cm'} =~ s/
/\r/g; $F{'cm'} =~ s/\t//g; foreach('nm','ps','ml','ul','tl','cm','mk','ck','cd','dn','lf','to','mn','rn') { if ($_ eq 'cm') { next if $F{'to'} } print &hide(name=>$_,value=>$F{$_}) if $F{$_}; } print &hide(name=>'md',value=>'set_regist'); &form('end'); &footer; exit; } # Sub Set Regist # sub set_regist { ®ist_check; $F{'pv'} && &preview; $F{'cd'} ||= 0; $F{'lf'} ||= 0; &lock; @BL = $F{'mn'} ? map { [split(/<>/)] } &open_dat($log_cgi) : &open_dat($log_cgi); $no = &double_check; if (!$F{'mn'}) { unshift(@BL,&join_data('m')) } else { foreach (0 .. $#BL) { next if $F{'mn'} ne $BL[$_][0]; @RL = split(/<->/,$BL[$_][$RS]); foreach (0 .. $#RL) { if ($F{'rn'} eq $F{'mn'}) { $x = @RL; last } ($x1,$x2) = (split(/×/,$RL[$_]))[0,2]; # 直属の記事にヒット if ($F{'rn'} eq $x1) { $x = $_ + 1; $cs = $x2; next; } # 最後尾をサーチ if ($x) { if ($cs >= $x2) { last } else { $x++ } } } $cs++; splice(@RL,$x,0,&join_data('r')); $BL[$_][$RS] = join('<->',@RL); $x = $_; last; } unshift(@BL,splice(@BL,$x,1)) if $use_rsu && !$F{'dn'}; @BL = map { join('<>',@$_) } @BL; } &set_past if $max_log < @BL; &write_dat($log_cgi,@BL) &write_dat($num_dat,join('<>',$no,$F{'nm'},$F{'cm'})); &unlock; &send_mail if $use_eml; $F{'rn'} = $no; # 自分の投稿した記事が赤くなる。 &base_view; } # Sub Set Past # sub set_past { $PL = pop(@BL); return if !$mke_pst; @PL = split(/<>/,$PL); @RL = map { $_->[$PS] = undef; join('<>',@$_,"\n") } map { [split(/×/)] } split(/<->/,$PL[$RS]); @PL[$PS,$RS] = undef; $PL = join('<>',@PL); unshift(@RL,$PL); &get_past; $pn = $PF[0] ? $PF[0] : '000'; $pf = "$pn\.cgi"; unless (-e "$pst_dir/$pf") { &write_dat("$pst_dir/$pf",@RL); chmod(0666,"$pst_dir/$pf"); return; } @PL = &open_dat("$pst_dir/$pf"); if (@PL >= $pst_max) { $pn++; $pf = sprintf("%03d",$pn) . '.cgi'; &write_dat("$pst_dir/$pf",@RL); chmod(0666,"$pst_dir/$pf"); } else { push(@PL,@RL); &write_dat("$pst_dir/$pf",@PL); } } # Sub Past View # sub past_view { my $ck = 1; &get_past; &header('java'); &title; &menu; if (@PF) { foreach (@PF) { push(@TL,[[&rdio(name=>pt,value=>$_,check=>$ck)."過去ログ No. $_
\n"]]); $ck = 0; } push(@TL,[[&sbmt(value=>'決定'),0,0,'right']]); &form('start'); &table(spc=>3,aln=>center,row=>$#PF+2,col=>1,d=>[@TL]); print &hide(name=>'md',value=>'past_view'); &form('end'); undef @TL; } else { &label('過去ログはありません。') } if ($F{'pt'}) { if ($F{'pt'} =~ /\D/) { &error('不正な入力です') } @PL = &open_dat("$pst_dir/$F{'pt'}\.cgi"); print qq|
過去ログ No. $F{'pt'}
\n|; &hr; foreach (@PL) { &split_data($_,'m'); &print_sub; &read_view; } } &footer; } # Sub Get Past # sub get_past { opendir(DIR,"$pst_dir/") || &error("過去ログディレクトリ読みこみエラー"); @PF = sort { $b cmp $a } grep { s/\.cgi$// } readdir(DIR); closedir(DIR); } # Sub Regist Check # sub regist_check { if ($ban_pxy) { while (($ek,$ev) = each(%ENV)) { &error("ProxyServer経由での書き込みは禁止です") if "$ek $ev" =~ /proxy|squid/i; } } if ($ban_url) { $ref_url = $ENV{'HTTP_REFERER'}; $ref_url =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; if ($ref_url !~ /$ban_url/i) { &error("不正なアクセスです") } } $pst_oly && !$buffer && &error("不正なアクセスです"); if ($F{'nm'} eq "") { &error('お名前を入力してください') } if ($F{'cm'} eq "" && !$F{'to'}) { &error('コメントを入力してください') } if ($F{'ml'} && $F{'ml'} !~ /(.*)\@(.*)\.(.*)/) { &error('不正なメールアドレスです') } if ($F{'ppw'} ne $wri_ans) { &error('質問の答えが違います') } if ($F{'ps'} eq "" && $use_osf) { &error('パスワードが未入力です') } undef $F{'cm'} if $F{'to'}; $F{'tl'} ||= $non_ttl; while ($F{'cm'} =~ /
$/) { $F{'cm'} =~ s/
$// } if ($nam_lgt && length $F{'nm'} > $nam_lgt * 2) { &error("名前は$nam_lgt文字までです") } if ($ttl_lgt && length $F{'tl'} > $ttl_lgt * 2) { &error("タイトルは$ttl_lgt文字までです") } if ($cmt_lgt && length $F{'cm'} > $cmt_lgt * 2) { &error("一回の投稿は$cmt_lgt文字までです") } if ($F{'cm'} =~ /(
){$brk_lgt,}/) { &error('空行が多すぎます') } if ($F{'cm'} =~ /[0-9a-zA-Z]{$wrd_lgt,}/) { &error('超過する英単語があります') } foreach (@xxx_lst) { next if !$_; if (index($F{'cm'},$_) >= 0) { &error('投稿記事に禁止ワードが含まれています') } if (index($F{'tl'},$_) >= 0) { &error('タイトルに禁止ワードが含まれています') } } # URLの先頭部処理 $F{'ul'} =~ s/^http\:\/\///; &set_cookie if $F{'ck'}; } # Sub Double Check # sub double_check { @CL = &open_dat($num_dat); # 二重投稿禁止処理(名前とコメント内容をチェック) my ($x1,$x2,$x3) = split(/<>/,$CL[0]); if ($F{'nm'} eq $x2 && $F{'cm'} eq $x3) { &error("既に投稿しました") } return ++$x1; } # Sub IP Check # sub ip_check { &get_host; $ht = &cut_ip($ht); @IP = &open_dat($rjc_dat); foreach (@IP) { chomp $_; if ($ht eq $_) { &error("同一IPがアクセス制限中です") } } } # Sub Cut IP # sub cut_ip { $_[0] =~ s/(\d+)\.(\d+)\.(\d+)\.(\d+)/$1\.$2\.$3\./; return $_[0]; } # Sub Regist Form # sub regist_form { my ($T,@TL); if ($re_tl) { if ($re_tl =~ /^Re(\d+)\:(.*)/) { $T = $1 + 1; $re_tl = "Re$T:$2" } elsif ($re_tl =~ /^Re\:(.*)/) { $re_tl = "Re2:$1" } else { $re_tl = 'Re:'.$re_tl } } if (!$use_ref) { undef $re_cm } if ($re_cm) { $re_cm = "> $re_cm"; $re_cm =~ s/
/\r> /g; } $tagA[0][0] = &cbox(name=>ck,value=>ok,check=>$c_ck) . 'クッキー保存'; $tagA[1][0] = &cbox(name=>dn,value=>ok) . 'スレッドを上げない' if $use_rsu && $use_rsd && $F{'mn'}; $tagA[2][0] = &cbox(name=>pv,value=>ok) . 'プレビュー' if !$use_apv; $tagA[3][0] = &cbox(name=>lf,value=>leaf) . "初心者マーク $lif_img" if $use_lif; $tagA[4][0] = &cbox(name=>cd,value=>code) . 'コード表示'; $tagA[5][0] = &cbox(name=>to,value=>to) . 'タイトルのみ' if $use_toy; $tagB = '削除用パスワード:' . &pass(name=>'ps',value=>"$c_ps") . &hide(name=>'md',value=>'set_regist'); $tagB .= &hide(name=>'mn',value=>"$F{'mn'}") if $F{'mn'}; $tagB .= &hide(name=>'rn',value=>"$F{'rn'}") if $F{'rn'}; $tagB .= &hide(name=>'pv',value=>ok) if $use_apv; $tagC = ' ' x 2 . 'なし' . &rdio(name=>mk,check=>1) if $use_mrk; foreach(1 .. $#mrk_img) { $tagC .= qq|  $mrk_img[$_]| . &rdio(name=>mk,value=>$_); } push(@TL,[['名前','b'],[':'],[&text(name=>nm,size=>$mtx_wth,value=>"$c_nm")]]); push(@TL,[['メール','b'],[':'],[&text(name=>ml,size=>$ltx_wth,value=>"$c_ml")]]); push(@TL,[['サイト','b'],[':'],[&text(name=>ul,size=>$ltx_wth,value=>"http://$c_ul")]]); push(@TL,[['タイトル','b'],[':'],[&text(name=>tl,size=>$ltx_wth,value=>$re_tl)]]); push(@TL,[['コメント','b'],[':'],[&area(name=>cm,col=>$tar_wth,value=>$re_cm,row=>$tar_hgt)]]); push(@TL,[[$wri_qst,'b'],[':'],[&text(name=>ppw,size=>$ltx_wth,value=>$c_ppw)]]); push(@TL,[['マーク','b'],[':'],[$tagC]]) if $use_mrk; push(@TL,[[],[],$tagA[0],$tagA[1]]); push(@TL,[[],[],$tagA[2],$tagA[3]]) if $tagA[2] || $tagA[3]; push(@TL,[[],[],$tagA[4],$tagA[5]]); push(@TL,[[$tagB,'','','right']]); push(@TL,[[&sbmt(value=>'決定'),'','','right']]); &form('start'); &table(aln=>center,row=>$#TL+1,col=>4,d=>[@TL]); &form('end'); } # Sub Delete Form # sub delete_form { &form('start'); print qq|
|; print qq|削除フォーム
|; print qq|記事番号:| . &text(name=>dl,size=>$stx_wth); print qq|
|; print qq|パスワード:| . &pass(name=>ps,size=>$stx_wth); print qq|
|; print &hide(name=>'md',value=>'set_delete'); print &sbmt(value=>'決定'); print qq|
|; &form('end'); } # Sub Set Delete # sub set_delete { my $X; !$F{'dl'} && &error('削除番号が未入力です'); !$F{'ps'} && &error('パスワードが未入力です'); $pst_oly && !$buffer && &error("不正なアクセスです"); for ($i=0;$i<=1;$i++) { $DL[$i] = '(削除)' } &lock; @BL = map { [split(/<>/)] } &open_dat($log_cgi); foreach $X (0 .. $#BL) { if ($BL[$X][0] eq $F{'dl'}) { &error('パスワードが不正です') if !&get_crypt($F{'ps'},$BL[$X][$PS]); if (!$BL[$X][$RS]) { splice(@BL,$X,1); } else { @{$BL[$X]}[5..13] = undef; @{$BL[$X]}[9,10] = @DL; } $deleted = 1; last; } @RL = map { [split(/×/)] } split(/<->/,$BL[$X][$RS]); foreach (@RL) { if ($_->[0] ne $F{'dl'}) { next } &error('パスワードが不正です') if !&get_crypt($F{'ps'},$_->[$PS]); @{$_}[5..13] = undef; @{$_}[9,10] = @DL; @RL = map { join('×',@$_) } @RL; $BL[$X][$RS] = join('<->',@RL); $deleted = 1; last; } last if $deleted; } undef @RL; &error("削除番号$F{'dl'}に該当する記事はありません") if !$deleted; @BL = map { join('<>',@$_) } @BL; &write_dat($log_cgi,@BL); &unlock; $F{'rn'} = $F{'dl'}; # 自分の削除した記事が赤くなる。 &base_view; } # Sub Search View # sub search_view { &header('java'); &title; &menu; &search_form; &footer; } # Sub Search Form # sub search_form { &form('start'); &table(spc=>3,row=>6,col=>3,aln=>center, d=>[[['検索するキーワードを入力して下さい。
複数ある場合はスペースで区切ってください。']], [[&rdio(name=>tp,value=>0,check=>$F{'tp'}-1).'and'.&rdio(name=>tp,value=>1,check=>$F{'tp'}).'or']], [[&text(name=>kw,size=>$ltx_wth,value=>$F{'kw'}),0,0,'right']], [[&cbox(name=>al,value=>ok,check=>$F{'al'}).'大文字小文字を区別する',0,0,'right']], [[&cbox(name=>pt,value=>ok,check=>$F{'pt'}).'過去ログを含む',0,0,'right']], [[&sbmt(value=>'検索'),0,0,'right']]]); print &hide(name=>'md',value=>'search'); &form('end'); } # Sub Search # sub search { my ($ht,$ct,$bg,@sw); !$F{'kw'} && &error('検索するキーワードが入力されていません'); $kw = $F{'kw'}; if ($kw =~ /(=|\?)/) { &error("キーワードに「$1」は使用出来ません") } $kw =~ s/ / /g; $kw =~ s/\t/ /g; foreach (split(/\s+/,$kw)) { if (length $_ <= 2) { &error("短い検索キーワードは使用出来ません --> 「$_」") } push(@sw,$_); &jcode::convert(*_,'euc'); push(@kw,$_); } $kw = join(' ',@sw); foreach (&open_dat($log_cgi)) { @RL = split(/<->/,(split(/<>/))[$RS]); @RL = map { join('<>',split(/×/)) } @RL; push(@BL,($_,@RL)); } if ($F{'pt'}) { &get_past; foreach (@PF) { push(@BL,&open_dat("$pst_dir/$_\.cgi")) } } undef @PF; foreach (@BL) { undef $bg; &split_data($_,'m'); $vl = join('<>',$nm,$tl,$cm); &jcode::convert(*vl,'euc'); foreach (@kw) { if ($F{'al'}) { if ($vl =~ s/($_)/<<$1>>/g) { $bg = 1 } elsif (!$F{'tp'}) { $bg = 0; last } } else { if ($vl =~ s/($_)/<<$1>>/ig) { $bg = 1 } elsif (!$F{'tp'}) { $bg = 0; last } } } $bg && $ht++; next if !$bg || $ht < $F{'pg'} || $ht > $F{'pg'} + $pge_log; $vl =~ s/</g; $vl =~ s/>>/<\/b>/g; &jcode::convert(*vl,'sjis'); ($nm,$tl,$cm) = split(/<>/,$vl); $cm =~ s/\n/
/g; push(@SL,&join_data('s')); } undef @BL; &header('java'); &title; &menu; &search_form; $ht = $ht ? $ht : 0; &page($F{'pg'},$ht,$pge_log); $ct = join('',$start+1,'-',$#SL+1,' [',$#SL-$start+1,'件]を表示'); &hr; &label("検索結果$ht件"); &label($ct) if $ht; &page_link($ht,"search&tp=$F{'tp'}&pt=$F{'pt'}&al=$F{'al'}&kw=$kw"); &hr; foreach (0 .. $#SL) { &split_data($SL[$_],'m'); &print_sub; &read_view; } &page_link($ht,"search&tp=$F{'tp'}&pt=$F{'pt'}&kw=$kw"); &footer; } # Sub Manual # sub manual { &header; &label('◆ 使い方 ◆'); &hr; print &open_dat($man_dat); &footer('nocopyright'); } # Sub Manager Password # sub manager_pass { &get_cookie; &header; &form('start'); print qq|

◆ 管理者パスワード ◆
|; print &pass(name=>ps); print &sbmt(value=>'決定'); print qq|

|; print &hide(name=>md,value=>manager_menu); &form('end'); &footer('nocopyright'); } # Sub Manager Menu # sub manager_menu { if ($F{'ps'} ne $mgr_pas) { &error('パスワードが不正です') } &header('java'); &menu; &form('start'); &label('◆ 管理者メニュー ◆'); &table(row=>4,col=>1,aln=>center,wid=>200, d=>[[[&rdio(name=>md,value=>edit_manual,check=>1) . '使い方の編集
']], [[&rdio(name=>md,value=>ip_select) . 'IP制限']], [["[ログのダウンロード]",0,0,'right']], [[&sbmt(value=>'決定'),0,0,'right']]]); print &hide(name=>ps,value=>$F{'ps'}); &form('end'); &footer('nocopyright'); } # Sub Edit Manual # sub edit_manual { if ($F{'ps'} ne $mgr_pas) { &error('パスワードが不正です') } &header; &form('start'); @ML = &open_dat($man_dat); $ML[0] =~ s/
/\r/g; &label('◆ 使い方の編集 ◆'); &table(row=>2,col=>1,aln=>center, d=>[[[&area(name=>man,col=>60,row=>25,value=>$ML[0])]], [[&sbmt(value=>'決定'),0,0,'right']]]); print &hide(name=>md,value=>set_manual); print &hide(name=>ps,value=>$F{'ps'}); &form('end'); &footer('nocopyright'); } # Sub Set Manual # sub set_manual { if ($F{'ps'} ne $mgr_pas) { &error('パスワードが不正です') } ($F{'man'}) = &convert(0,$F{'man'}); &write_dat($man_dat,$F{'man'}); &manager_menu; } # Sub IP Select # sub ip_select { if ($F{'ps'} ne $mgr_pas) { &error('パスワードが不正です') } @BL = map { [(split(/<>/))[$NM,$HT,$RS]] } &open_dat($log_cgi); foreach (@BL) { map { &cut_ip($_->[1]); $IP{"$_->[0]$_->[1]"} = $_ } map { [(split(/×/))[$NM,$HT]] } split(/<->/,$_->[2]) if $_->[2]; &cut_ip($_->[1]); $IP{"$_->[0]$_->[1]"} = [$_->[0],$_->[1]]; } @IP = sort { $a->[1] <=> $b->[1] || $a->[0] cmp $b->[0] } values %IP if $F{'st'}; @IP = sort { $a->[0] cmp $b->[0] || $a->[1] <=> $b->[1] } values %IP if !$F{'st'}; undef %IP; @stat = stat $log_cgi; &header('java'); &title; &menu; if (!$stat[7]) { &error("投稿数は0件です") } print qq|[IP順にソ\ート]\n| if !$F{'st'}; print qq|[名前順にソ\ート]\n| if $F{'st'}; &form('start'); print qq|

制限するIPにチェックを入れてください。
選択できるのは一回に1つずつです。

\n|; print &rdio(name=>r,check=>1) . qq|未選択
\n|; foreach (@IP) { next if !$_->[1]; print &rdio(name=>r,value=>$_->[1]); print qq|$_->[0] $_->[1]
\n| if !$F{'st'}; print qq|$_->[1] $_->[0]
\n| if $F{'st'}; } print qq|

復活させるIPにチェックを入れてください。
選択できるのは一回に1つずつです。

\n|; print &rdio(name=>d,check=>1) . qq|未選択
\n|; @IP = &open_dat($rjc_dat); foreach (@IP) { chomp $_; print &rdio(name=>d,value=>$_) . qq|$_
\n|; } &hr; print &sbmt(value=>'決定'); print &hide(name=>md,value=>ip_restrict); print &hide(name=>ps,value=>$F{'ps'}); &form('end'); } # Sub IP Restrict # sub ip_restrict { if ($F{'ps'} ne $mgr_pas) { &error('パスワードが不正です') } @IP = &open_dat($rjc_dat); foreach (0 .. $#IP) { $ip = $IP[$_]; chomp $ip; if ($ip eq $F{'r'}) { $rpoint = 1 } if ($ip eq $F{'d'}) { $dpoint = $_ } } if ($dpoint ne '') { splice(@IP,$dpoint,1) } if (!$rpoint && $F{'r'}) { push(@IP,"$F{'r'}\n") } &write_dat($rjc_dat,@IP); &ip_select; } # Sub Send Mail # sub send_mail { return if $use_eml == 1 && $eml_adr eq $F{'ml'}; local ($tl,$cm,$ml,$ul); $tl = "[$no] $F{'tl'}"; ($cm) = &convert(0,$F{'cm'}); $ml = $F{'ml'} ? $F{'ml'} : 'NoMail@xxx.xxx'; $ul = $F{'ul'}; $ul &&= "http://$F{'ul'}"; $cm = <<"END"; *--* *--* *--* *--* *--* *--* *--* *--* *--* *--* Date:$dt Host:$ht User:$F{'nm'} E-Mail:$ml Title:$tl URL:$ul Comment: $cm *--* *--* *--* *--* *--* *--* *--* *--* *--* *--* Sent from Tree-style BBS Lindenbaum END &jcode::convert(*cm,'jis','sjis'); &jcode::convert(*tl,'jis','sjis'); if (!open(MAIL,"| $sml_pth -t")) { &error("メール送信に失敗しました") } print MAIL "X-Mailer: Lindenbaum $ver\n"; print MAIL "To: $eml_adr\n"; print MAIL "From: $ml\n"; print MAIL "Subject: $tl\n"; print MAIL "MIME-Version: 1.0\n"; print MAIL "Content-type: text/plain; charset=ISO-2022-JP\n"; print MAIL "Content-Transfer-Encoding: 7bit\n"; print MAIL "\n\n"; print MAIL "$cm\n"; close(MAIL); } # Sub Menu # sub menu { my (@TL); print qq|
\n|; &hr; print qq|[HOME] \n|; print qq|[使い方] \n|; print qq|[リロード] \n|; print qq|[新規投稿] \n|; print qq|[新着記事] \n|; print qq|[ワード検索] \n|; print qq|[過去ログ] \n| if $mke_pst; print qq|[管理用]\n|; &hr; push(@TL,[[$min_inf,0,0,0,nowrap]]) if $_[0]; push(@TL,[[$mrk_inf,0,0,0,nowrap]]) if $use_mrk && $_[1]; &table(row=>$#TL+1,col=>1,d=>[@TL]) if @_; &hr if @_; print qq|
\n|; } # Sub Header # sub header { print qq|Content-type: text/html\n\n|; print qq|\n\n|; print qq|\n|; print qq|$ttl_lbl\n|; if ($css_fle) { print qq|\n| } else { &style } &java_script if $_[0]; print qq|\n|; print qq|$bdy_tag\n|; print $bnr_top; $headflag = 1; } # Sub Footer # sub footer { if ($_[0]) { print qq|
\n|; print $bnr_btm; print qq|\n\n|; } else { # 著作権表示。絶対に消さないで下さい! # ここにリンクを貼る場合、Missing Linkと同じ行にせず、 # 必ず改行を行って別行にしてください。 # 改造者のリンクを貼る場合、改造者の前に必ず「Edit:」をつけること。 print qq|
\n
Lindenbaum Ver $ver
\n|; print qq|■ MISSING LINK ■|; print qq|
\n|; print $bnr_btm; print qq|\n\n|; } } # Sub StyleSheet # sub style { print qq|\n|; } # Java Script # sub java_script { print qq|\n|; } # Sub Title # sub title { print qq|
\n|; print qq|
\n| if $ttl_img; print qq|
\n|; print qq|$ttl_wrd\n| if $ttl_wrd; print qq|
\n|; } # Sub Form # sub form { print qq|
\n| if $_[0] eq 'start'; print qq|
\n| if $_[0] eq 'end'; } # Sub Table # sub table { my %D = @_; my ($d,$T,$A,$X,$Y,$cols,$width,$space,$pad); $D{'wid'} &&= " width=$D{'wid'}"; $D{'aln'} &&= " align=$D{'aln'}"; $D{'spn'} &&= " cellspacing=$D{'spc'}"; $D{'pad'} &&= " cellpadding=$D{'pad'}"; $D{'bdr'} ||= 0; print qq|\n|; foreach $X (0 .. $D{'row'} - 1) { print qq||; foreach $Y (0 .. $D{'col'} - 1) { next if !$D{'d'}[$X][$Y][0] && $Y > 0; $cols = 1; foreach ($Y + 1 .. $D{'col'} - 1) { if ($D{'d'}[$X][$_][0]) { last } else { $cols++ } } undef $T; $d = $D{'d'}[$X][$Y]; $A = $d->[3] =~ /o/ ? 'valign' : 'align'; $T = qq| colspan=$cols| if $cols > 1; $T .= qq| nowrap| if $d->[4]; $T .= qq| $A=$d->[3]| if $d->[3]; $T .= qq| width=$d->[2]| if $d->[2]; $d->[0] = "<$d->[1]>$d->[0][1]>" if $d->[1]; print qq|$d->[0]|; } print qq|\n|; } print qq|
\n|; } # Sub Text # sub text { my %D = @_; my $mytag; $mytag = qq|\n|; return $mytag; } # Sub Area # sub area { my %D = @_; my $mytag; $mytag = qq|\n|; return $mytag; } # Sub Pass # sub pass { my %D = @_; my $mytag; $mytag = qq|\n|; return $mytag; } # Sub Radio # sub rdio { my %D = @_; my $mytag; $mytag = qq|\n| if $D{'check'}; $mytag = qq|\n| if !$D{'check'}; return $mytag; } # Sub Checkbox # sub cbox { my %D = @_; my $mytag; $mytag = qq|\n| if $D{'check'}; $mytag = qq|\n| if !$D{'check'}; return $mytag; } # Sub Hidden # sub hide { my %D = @_; my $mytag; $mytag = qq|\n|; return $mytag; } # Sub Submit # sub sbmt { my %D = @_; my $mytag; $mytag = qq|\n|; return $mytag; } # Sub Button # sub bttn { my %D = @_; my $mytag; if ($D{'option'} == 1) { $D{'option'} = ' onClick="history.back()"' } $mytag = qq|\n|; return $mytag; } # Sub HR # sub hr { if (!$ver_chk) { print qq|
\n| } else { print qq|
\n| } } # Sub Label # sub label { print qq|
$_[0]
\n|; } # Sub Page # sub page { ($first,$total,$eachpage) = @_; $start = $first eq '' ? 0 : $first; $end = $start + ($eachpage - 1); $end = $total if $end >= $total; $next = $end + 1; $back = $start - $eachpage; } # Sub Page Link # sub page_link { !$_[0] && return; print qq|
|; print qq|[BACK] | if $back >= 0; print qq|[NEXT] | if $end != $total; for ($i=0;$i<=$_[0];$i+=$pge_log) { $pge_num = $i / $pge_log + 1; $tag = $i == $F{'pg'} ? "[$pge_num]" : "[$pge_num]"; print qq|$tag|; } print qq|
\n|; } # Sub Split Data # sub split_data { ($no,$mn,$cs,$tm,$dt,$nm,$ps,$ml,$ul,$tl,$cm,$mk,$ht,$cd,$lf,$rs) = split(/<>/,$_[0]) if $_[1] eq 'm'; ($no,$mn,$cs,$tm,$dt,$nm,$ps,$ml,$ul,$tl,$cm,$mk,$ht,$cd,$lf) = split(/×/,$_[0]) if $_[1] eq 'r'; } # Sub Join Data # sub join_data { my $data; &get_time; &get_host; $ps = &set_crypt($F{'ps'}) if $F{'ps'}; $data = join('<>',$no,$no,$cs,$tm,$dt,$F{'nm'},$ps,$F{'ml'},$F{'ul'}, $F{'tl'},$F{'cm'},$F{'mk'},$ht,$F{'cd'},$F{'lf'},$rs,"\n") if $_[0] eq 'm'; $data = join('×',$no,$F{'mn'},$cs,$tm,$dt,$F{'nm'},$ps,$F{'ml'}, $F{'ul'},$F{'tl'},$F{'cm'},$F{'mk'},$ht,$F{'cd'},$F{'lf'}) if $_[0] eq 'r'; $data = join('<>',$no,$mn,$cs,$tm,$dt,$nm,$ps,$ml, $ul,$tl,$cm,$mk,$ht,$cd,$lf,"\n") if $_[0] eq 's'; return $data; } # Sub For Old Version # sub for_old_version { $ver_chk = $ENV{'HTTP_USER_AGENT'}; $ver_chk = $ver_chk =~ /(MSIE|6\.|7\.)/ ? 0 : 1; } # Sub Print ID # sub print_id { if ($ps) { $ips = substr($ps,6); return qq| [ID:$ips]| if $ips; } else { return undef } } # Sub Get Cryptogram # sub get_crypt { my $word = $_[0]; my $crypt = $_[1]; my $salt; return 1 if !$word && !$crypt; return 1 if $word eq $mgr_pas && !$_[2]; if (!$use_crp) { if ($word eq $crypt) { return 1 } else { return 0 } } $salt = substr($crypt,0,2); if ($crypt eq crypt($word,$salt)) { return 1 } else { return 0 } } # Sub Set Cryptogram # sub set_crypt { my $word = $_[0]; my ($salt,$xx); return $word if !$word; return $word if !$use_crp; srand(time|$$) if !$use_osf; srand($def_key) if $use_osf; $xx = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" . "abcdefghijklmnopqrstuvwxyz" . "0123456789./"; $salt = substr($xx,int(rand(64)),1); $salt .= substr($xx,int(rand(64)),1); return $crypt = crypt($word,$salt); } # Sub Get Time # sub get_time { $ENV{'TZ'} = "JST-9"; $tm = time; my @wk; my ($sc,$mn,$hr,$dy,$mt,$yr,$wd) = localtime($tm); $yr -= 100; @wk = ('日','月','火','水','木','金','土') if $dte_stl eq 'j'; @wk = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat') if $dte_stl eq 'e'; $dt = sprintf("%02d/%02d/%02d [%s] %02d:%02d",$yr,$mt+1,$dy,$wk[$wd],$hr,$mn); } # Sub Get Host # sub get_host { my $ad; $ht = $ENV{'REMOTE_HOST'}; $ad = $ENV{'REMOTE_ADDR'}; if ($ht eq "") { $ht = $ad } # if ($ht eq $ad) { $ht = gethostbyaddr(pack("C4",split(/\./,$ad)),2) } } # Sub Get Cookie # sub get_cookie { @pairs = split(/;/,$ENV{'HTTP_COOKIE'}); foreach (@pairs) { local($name,$value) = split(/=/); $name =~ s/ //g; $DUMMY{$name} = $value; } @pairs = split(/,/,$DUMMY{'LIN'}); foreach (@pairs) { local($name, $value) = split(/:/); $COOKIE{$name} = $value; } $c_nm = $COOKIE{'nm'}; $c_ml = $COOKIE{'ml'}; $c_ul = $COOKIE{'ul'}; $c_ps = $COOKIE{'ps'}; $c_ck = $COOKIE{'ck'}; } # Sub Set Cookie # sub set_cookie { my ($sc,$mn,$hr,$dy,$mt,$yr,$wd) = gmtime(time + 90*24*60*60); my ($dt,$ck); $yr += 1900; if ($sc < 10) { $sc = "0$sc" } if ($mn < 10) { $mn = "0$mn" } if ($hr < 10) { $hr = "0$hr" } if ($dy < 10) { $dy = "0$dy" } $mt = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')[$mt]; $wd = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday')[$wd]; $dt = "$wd, $dy\-$mt\-$yr $hr:$mn:$sc GMT"; $ck = "nm\:$F{'nm'}\,ml\:$F{'ml'}\,ul\:$F{'ul'}\,ps\:$F{'ps'}\,ck\:$F{'ck'}"; print "Set-Cookie: LIN=$ck; expires=$dt\n"; } # Sub Lock # sub lock { return if !$loc_key; local($flag) = 10; if ($loc_key == 1) { rmdir($loc_fle) if (time - (stat($loc_fle))[9] > 60); while (!mkdir($loc_fle,0755)) { --$flag or &error('現在、サーバが混み合っています',1); sleep(1); } } elsif ($loc_key == 2) { unlink($loc_fle) if (time - (stat($loc_fle))[9] > 60); while (!symlink(".",$loc_fle)) { --$flag or &error('現在、サーバが混み合っています',1); sleep(1); } } } # Sub Unlock # sub unlock { if ($loc_key == 1) { rmdir($loc_fle) } elsif ($loc_key == 2) { unlink($loc_fle) } } # Sub Open Dat # sub open_dat { open(IN,"$_[0]") || &error("$_[0]読み込みエラー:$_[0]が存在しないかパーミッションが不正です"); local(@lines) = ; close(IN); return @lines; } # Sub Write Dat # sub write_dat { open(OUT,">$_[0]") || &error("$_[0]書き込みエラー:$_[0]が存在しないかパーミッションが不正です"); shift(@_); print OUT @_; close(OUT); } # Sub Error # sub error { $_[1] || &unlock; $headflag || &header; &hr; &label($_[0]); &hr; &footer; exit; } # Sub Decode # sub decode { if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); @pairs = split(/&/,$buffer); } else { @pairs = split(/&/,$ENV{'QUERY_STRING'}) } foreach $pair (@pairs) { ($name,$value) = split(/=/,$pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; &jcode::convert(*value,'sjis'); &jcode::h2z_sjis(*value) if $cvt_kna; ($value) = &convert(1,$value); $F{$name} = $value; } } # Sub Convert # sub convert { my $type = shift(@_); my @words = @_; foreach (@words) { if ($type) { s/&/&/g; s//>/g; s/"/"/g; s/×/×/g; s/\r\n/
/g; s/\r/
/g; s/\n/
/g; } else { s/
/\n/g if $F{'md'} ne 'set_manual'; s/<//g; s/"/"/g; s/×/×/g; s/&/&/g; } } return @words; }