#!/usr/local/bin/perl # 日本語コード require './cfg.pl'; &decode; if($form{'mode'} eq "all" ) { &HTML_all; } if($form{'mode'} eq "howto" ) { &HTML_how; } if($form{'mode'} eq "kana" ) { &HTML_kana; } if($form{'mode'} eq "genre" ) { &HTML_genre; } if($form{'mode'} eq "engnum" ) { &HTML_engnum; } if($form{'mode'} eq "names" ) { &HTML_names; } if($form{'mode'} eq "edit" ) { &HTML_edit; } if($form{'mode'} eq "write" ) { &write; } if($form{'mode'} eq "add" ) { &add; } if($form{'mode'} eq "edit2" ) { &edit; } if($form{'mode'} eq "adminedit" ) { &adminedit; } &HTML; ########################## # 基本HTML表示 ########################## sub HTML { @dat = &FileRead("$LogDir/index.dat"); @dat = grep{(split(/<>/))[2] ne "削除済み"} @dat; print "Content-type: text/html\n\n"; &header; print <
 ■ 一覧表\示 : 新着・更新 $newdisp件

EOM my @buf=@dat; $newdisp-=1; for(($form{'page'}*$newdisp) .. (($form{'page'}+1)*$newdisp)){ if(!defined $buf[$_]){last} my($num, $yomi, $name, $genre, $pass, $date) = split('<>', "$buf[$_]"); $date = sprintf("%4d年%02d月%02d日", substr($date, 0, 4), substr($date, 4, 2), substr($date, 6, 2)); print "
[$genre] $name - $date No.$num\n"; } print "
 "; print "
"; for($i=0,$j=0;$i<($#dat/$newdisp);$i++,$j++){ if($j == $form{'page'}){ print "[".($j+1)."] " }else{ print "[".($j+1)."] \n"; } } print <

EOM &footer; exit; } ########################## # 全部の記事の見出し # ページを表示 ########################## sub HTML_all { @dat = &FileRead("$LogDir/index.dat"); @dat = grep{(split(/<>/))[2] ne "削除済み"} @dat; print "Content-type: text/html\n\n"; &header; print <
 ■ 一覧表\示 : 全件表\示

EOM { my @buf; #ソート @buf = map {$_->[0]} sort {$a->[4] cmp $b->[4] or $a->[2] cmp $b->[2]} map {[$_, split /<>/]} @dat; $alldisp-=1; for(($form{'page'}*$alldisp) .. (($form{'page'}+1)*$alldisp)){ if(!defined $buf[$_]){last} my($num, $yomi, $name, $genre, $pass, $date) = split('<>', "$buf[$_]"); $date = sprintf("%4d年%02d月%02d日", substr($date, 0, 4), substr($date, 4, 2), substr($date, 6, 2)); print "
[$genre] $name - $date No.$num\n"; } } print "
 "; print "
"; for($i=0,$j=0;$i<($#dat/$alldisp);$i++,$j++){ if($j == $form{'page'}){ print "[".($j+1)."] " }else{ print "[".($j+1)."] \n"; } } print <

EOM &footer; exit; } ########################## # 選択された名前の # ページを表示 ########################## sub HTML_names { my($num, $yomi, $name, $genre, $date); @dat = &FileRead("$LogDir/index.dat"); @dat = grep{(split(/<>/))[2] ne "削除済み"} @dat; foreach(@dat){ ($num, $yomi, $name, $genre, $pass, $date) = split(/<>/); if($num == $form{'no'}){ last; } } { my($year, $month, $day, $weeknum, $hour, $min) = unpack 'a4a2a2a1a2a2', $date; my $t_f_tmp = $time_format2; $t_f_tmp =~ s/\$year/$year/gi; $t_f_tmp =~ s/\$month/$month/gi; $t_f_tmp =~ s/\$day/$day/gi; $t_f_tmp =~ s/\$week/$week[$weeknum]/gi; $t_f_tmp =~ s/\$hour/$hour/gi; $t_f_tmp =~ s/\$min/$min/gi; $date = $t_f_tmp; } print "Content-type: text/html\n\n"; &header; print <
 ■ [$genre] $name ($yomi) $date - No.$num

    EOM @dat2 = &FileRead("$LogDir/$form{'no'}.txt"); foreach(@dat2){ my($comment, $name, $fontcolor, $date) = split(/<>/); { my($year, $month, $day, $weeknum, $hour, $min) = unpack 'a4a2a2a1a2a2', $date; my $t_f_tmp = $time_format2; $t_f_tmp =~ s/\$year/$year/gi; $t_f_tmp =~ s/\$month/$month/gi; $t_f_tmp =~ s/\$day/$day/gi; $t_f_tmp =~ s/\$week/$week[$weeknum]/gi; $t_f_tmp =~ s/\$hour/$hour/gi; $t_f_tmp =~ s/\$min/$min/gi; $date = $t_f_tmp; } if($wordlinkkey){ foreach(@dat){ my($i_num, $i_yomi, $i_name, $i_genre) = (split(/<>/))[0,1,2,4]; $i_name =~ s/(\W)/'%'.unpack("H2", $1)/ego; $i_yomi =~ s/(\W)/'%'.unpack("H2", $1)/ego; $i_genre =~ s/(\W)/'%'.unpack("H2", $1)/ego; $comment =~ s/(\W)/'%'.unpack("H2", $1)/ego; $comment =~ s/($i_name|$i_yomi)/$PREMATCH\ \;$&<\/a>\ \;$POSTMATCH/g; $comment =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg; } } print "
  • $comment - $nameさん [$date]\n"; } print "
"; print <
EOM &HTML_addform; print <

EOM &footer; exit; } ########################## # 選んだアルファベットの # ページを表示 ########################## sub HTML_engnum { @dat = &FileRead("$LogDir/index.dat"); @dat = grep{(split(/<>/))[2] ne "削除済み"} @dat; print "Content-type: text/html\n\n"; &header; @wordstartlist =('A','D','G','J','M','P','S','V','Y'); @wordendlist =('C','F','I','L','O','R','U','X','1'); my($wordstart,$wordend) = ($wordstartlist[$form{'word'}], $wordendlist[$form{'word'}]); for($wordstart .. $wordend){$wordse .= $_;} $wordse.='1' if($wordend eq '1'); print <
 ■ 一覧表\示 : $wordse

EOM #名前でソート @dat = map {$_->[0]} sort {$a->[3] cmp $b->[3]} map {[$_, split /<>/]} @dat; for(0 .. $#dat){ my($num, $yomi, $name, $genre, $pass, $date) = split('<>', "$dat[$_]"); my($year, $month, $day, $weeknum, $hour, $min) = unpack 'a4a2a2a1a2a2', $date; $time_format1 =~ s/\$year/$year/gi; $time_format1 =~ s/\$month/$month/gi; $time_format1 =~ s/\$day/$day/gi; $time_format1 =~ s/\$week/$week[$weeknum]/gi; $time_format1 =~ s/\$hour/$hour/gi; $time_format1 =~ s/\$min/$min/gi; $date = $time_format1; my $head = $name; $head = substr($head,0,1); $head = uc($head); if($head ge $wordstart and $head le $wordend){ print "
$name - $date No.$num\n"; $found=true; }elsif(($head =~ /[0-9]/ or $head =~ /[YZyz]/) and $wordend eq '1'){ print "
$name - $date No.$num\n"; $found=true; } } if(!$found){ print "
このデータは一件も登録されていません"; } print <

EOM &footer; exit; } ########################## # かなで選んだ50音の行から # 表示 ########################## sub HTML_kana { @dat = &FileRead("$LogDir/index.dat"); @dat = grep{(split(/<>/))[2] ne "削除済み"} @dat; print "Content-type: text/html\n\n"; &header; @wordstartlist =('ぁ','か','さ','た','な','は','ま','や','ら','わ','ぁ'); @wordendlist =('お','ご','ぞ','ど','の','ぽ','も','よ','ろ','ん','ん'); my($wordstart,$wordend) = ($wordstartlist[$form{'word'}], $wordendlist[$form{'word'}]); print <
 ■ 一覧表\示 : $wordstart行

EOM #よみがなでソート @dat = map {$_->[0]} sort {$a->[2] cmp $b->[2]} map {[$_, split /<>/]} @dat; for(0 .. $#dat){ my($num, $yomi, $name, $genre, $pass, $date) = split('<>', "$dat[$_]"); my($year, $month, $day, $weeknum, $hour, $min) = unpack 'a4a2a2a1a2a2', $date; $time_format1 =~ s/\$year/$year/gi; $time_format1 =~ s/\$month/$month/gi; $time_format1 =~ s/\$day/$day/gi; $time_format1 =~ s/\$week/$week[$weeknum]/gi; $time_format1 =~ s/\$hour/$hour/gi; $time_format1 =~ s/\$min/$min/gi; $date = $time_format1; if(substr($yomi,0,2) ge $wordstart and substr($yomi,0,2) le $wordend){ print "
$name - $date No.$num\n"; $found=true; } } if(!$found){ print "
このデータは一件も登録されていません"; } print <

EOM &footer; exit; } ########################## # 選んだジャンルの # 項目を表示 ########################## sub HTML_genre { @dat = &FileRead("$LogDir/index.dat"); @dat = grep{(split(/<>/))[2] ne "削除済み"} @dat; print "Content-type: text/html\n\n"; &header; print <
 ■ 一覧表\示 : $form{'word'}

EOM #よみがなでソート @dat = map {$_->[0]} sort {$a->[2] cmp $b->[2]} map {[$_, split /<>/]} @dat; for(0 .. $#dat){ my($num, $yomi, $name, $genre, $pass, $date) = split('<>', "$dat[$_]"); my($year, $month, $day, $weeknum, $hour, $min) = unpack 'a4a2a2a1a2a2', $date; $time_format1 =~ s/\$year/$year/gi; $time_format1 =~ s/\$month/$month/gi; $time_format1 =~ s/\$day/$day/gi; $time_format1 =~ s/\$week/$week[$weeknum]/gi; $time_format1 =~ s/\$hour/$hour/gi; $time_format1 =~ s/\$min/$min/gi; $date = $time_format1; if($genre eq $form{'word'}){ print "
[$genre] $name - $date No.$num\n"; $found=true; } } if(!$found){ print "
このデータは一件も登録されていません"; } print <

EOM &footer; exit; } ########################## # 注意事項項目表示部 ########################## sub HTML_att { print "\n" ; print " \n" ; print " \n" ; print " \n" ; print "
\n" ; foreach (@attention) { print "
  • $_
  • \n"; } print "
  • 現在 ".($#dat+1)." 件登録されています。
  • \n"; print "
    \n" ; } ########################## # カラーリスト表示部 ########################## sub HTML_color { print ""; } ########################## # 追記フォームを表示する ########################## sub HTML_addform { my(@genrelist)=@_; print <
    追加情報
    Name
    color EOM &HTML_color; print <
    EOM } ########################## # 登録フォームを表示する ########################## sub HTML_registform { my(@genrelist)=@_; print <

    新規用語登録
     登録者名
     項目名
     よみがな
     情報/コメント
    ジャンル
    文字色 EOM &HTML_color; print <
    EOM } ########################## # 削除ページを表示する ########################## sub HTML_edit { if($form{'no'} eq "" or $form{'pass'} eq ""){return;} # $form{'no'} $form{'pass'} @dat = &FileRead("$LogDir/index.dat"); @dat = grep{(split(/<>/))[2] ne "削除済み"} @dat; my $parent="", $admin=0; foreach(@dat){ my($no, $yomi, $name, $genre, $pass, $date) = split(/<>/); if($no == $form{'no'}){ if($admin_pass eq $form{'pass'}){ $admin = 1; $parent = $_; last; }elsif($pass eq $form{'pass'}){ $parent = $_; last; } } } &error("パスワードが違います。") if(!$parent); print "Content-type: text/html\n\n"; &header; if($admin){# 管理者パスワードだったら my @txt = &FileRead("$LogDir/$form{'no'}.txt"); print "

    項目修正処理(管理者用)

    \n" ; print "
    \n" ; my($no, $yomi, $pname, $genre, $pass, $date) = split(/<>/,$parent); print ""; print ""; print ""; print ""; print "
    "; print "ジャンル"; print ""; print ""; print "
    "; print "項目名"; print ""; print ""; print "
    "; print "よみがな"; print ""; print ""; print "
    "; print "\n" ; print "\n" ; print "\n" ; print "\n" ; print "
    \n"; print "
    "; print "コメント修正削除処理"; print "
    \n" ; print "
    \n"; print "
    [$genre] $pname No.$no
    \n"; foreach(0 .. $#txt){ my($comment, $name, $color, $time) = split("<>",$txt[$_]); print "
    $name > $comment\n"; } print "
    "; print "\n
    \n" ; print < (書き換える場合、修正するコメントにチェックをつけ下記を入力し修正をクリックしてください)
    Name
    color EOM &HTML_color; print <
    EOM print "\n" ; print "\n" ; print "\n" ; print "\n" ; }else{# 投稿者パスワードだったら print "

    削除修正処理

    \n" ; print "
    \n" ; my($no, $yomi, $pname, $genre, $pass, $date) = split(/<>/,$parent); print ""; print ""; print ""; print ""; print "
    "; print "ジャンル"; print ""; print ""; print "
    "; print "項目名"; print ""; print ""; print "
    "; print "よみがな"; print ""; print ""; print "
    "; print "\n" ; print "\n" ; print "\n" ; print "\n" ; print "\n" ; print "
    \n" ; } print "
    "; &footer; exit; } ########################## # 削除フォーム表示形式部 ########################## sub HTML_delform { print <

    - 登録項目を修正削除することができます -
    記事No 暗証キー

    EOM } ########################## # 留意事項の # ページを表示 ########################## sub HTML_how { $strtag = $tagkey?"以下のものが使用可です。
    font,marquee,button,input,b,i,s,strike,tt,u,sup,sub,em,strong,blink,img,hr":"使用不可です。"; print "Content-type: text/html\n\n"; print <<"end_of_show_header"; $title_str $body

    辞典の使い方


    $link
    end_of_show_header print <
     ■ 新規用語登録について ■ 

    • 項目名よみがな情報/コメント必須項目です。

    • 登録者名が未記入の場合"$noname1"と表\示されます。

    • ジャンルについては新規ジャンルの追加が優先されます。

    • パスワードは設定しておくと、投稿者が記事の修正削除が行なえます。

    • タグについては情報/コメント欄に対し、$strtag

    • 投稿された用語に関しては誰にでも閲覧・追記することができます。
     ■ 新追加情報について ■ 

    • Nameが未記入の場合"$noname2"と表\示されます。

    • コメントが未記入の場合、何も書き込まれません

    • タグについては新規用語登録の情報/コメント欄を参照ください。

    • こちらから追記された内容は管理者のみ編集削除ができます。


    EOM exit; } ########################## # 項目表示形式部 ########################## sub HTML_list { print <
     ■ 項目表\示形式
    [ 新着・更新 / 全件 ]
    ジャンル [ EOM @genrelist = &Make_list(3,@dat); @genrelist = sort(@genrelist); foreach(0 .. $#genrelist){ my($url)=$genrelist[$_]; $url =~ s/<//g; $url =~ s/(\W)/'%'.unpack("H2", $1)/ego; print "$genrelist[$_]"; print " / " if(defined($genrelist[($_+1)])); } print <
    英数 [ ABC / DEF / GHI / JKL / MNO / PQR / STU / VWX / YZ1 ]
    かな [ あ行 / か行 / さ行 / た行 / な行 / は行 / ま行 / や行 / ら行 / わ行・ん ]
    EOM } ########################## # ファイルを読み込んで # 指定された縦列を配列にし返す # 引数(列番号,配列) ########################## sub Make_list{ my ($num,@dat) = (@_); my @genrelist; foreach (@dat){ { my $genre = (split(/<>/))[$num]; unshift(@genrelist,$genre); } } { my %count; @genrelist = grep(!$count{$_}++, @genrelist); } return @genrelist; } ########################## # index.datに書き込む ########################## sub write { my @Index = &FileRead("$LogDir/index.dat"); ($form{'tname'}=$noname1) if($form{'tname'} eq ""); &error("項目名を入力してください") if($form{'name'} eq ""); &error("読みは全角ひらがなで入力してください") if($form{'yomi'} lt "ぁ" || $form{'yomi'} gt "ァ"); &error("読みは全角ひらがなのみで入力してください") if($form{'yomi'} =~ /[a-z0-9]/ig); &error("情報/コメントを入力してください") if($form{'comment'} eq ""); my($genre) = ($form{'newgenre'})?($form{'newgenre'}):($form{'genre'}); &error("ジャンルが選択、入力されていません") if($genre eq "(新規ジャンル)"); &error("多重投稿です。") if($form{'name'} eq (split("<>", $Index[0]))[2]); $time = &TimeGet; $newnum = $#Index; $newnum += 2; unshift(@Index,"$newnum<>$form{'yomi'}<>$form{'name'}<>$genre<>$form{'pass'}<>$time\n"); &FileWrite("$LogDir/index.dat", @Index); push(@dat,("$form{'comment'}<>$form{'tname'}<>$form{'color'}<>$time\n")); &FileWrite("$LogDir/$newnum.txt", @dat); } ########################## # txtに追記する ########################## sub add{ (return) if($form{'comment'} eq ""); ($form{'name'}=$noname2) if($form{'name'} eq ""); # 番号のtxtにコメントを書き込む my @dat = &FileRead("$LogDir/$form{'no'}.txt"); &error("多重投稿です。") if($form{'comment'} eq (split("<>", $dat[-1]))[0]); $time = &TimeGet; push(@dat,("$form{'comment'}<>$form{'name'}<>$form{'color'}<>$time\n")); &FileWrite("$LogDir/$form{'no'}.txt", @dat); # index.datの順番を変える my @Index = &FileRead("$LogDir/index.dat"); my @buf; foreach(@Index){ my $num = (split(/<>/))[0]; if($num eq $form{'no'}){ $tmp = $_; next; } push(@buf,$_); } unshift(@buf,$tmp); &FileWrite("$LogDir/index.dat", @buf); } ########################## # 記事内容を修正削除 ########################## sub edit { my @Index = &FileRead("$LogDir/index.dat"); my @buf; if($form{"command"} eq " 削除 "){ # 元記事からの削除 foreach(@Index){ my ($num, $yomi, $name, $genre, $pass, $date) = split(/<>/); if($num eq $form{'no'}){ push(@buf,"$num<><>削除済み<><>$pass<>$date"); next; } push(@buf,$_); } &FileWrite("$LogDir/index.dat", @buf); }elsif($form{"command"} eq " 修正 "){ &error("項目名を入力してください") if($form{'name'} eq ""); &error("読みは全角ひらがなで入力してください") if($form{'yomi'} lt "ぁ" || $form{'yomi'} gt "ァ"); &error("読みは全角ひらがなのみで入力してください") if($form{'yomi'} =~ /[a-z0-9]/ig); &error("ジャンルが空白文字の\可\能\性があります") if($form{'genre'} eq ""); $time = &TimeGet; foreach(@Index){ my ($num, $yomi, $name, $genre, $pass, $date) = split(/<>/); if($num == $form{'no'}){ push(@buf,"$num<>$form{'yomi'}<>$form{'name'}<>$form{'genre'}<>$pass<>$time\n"); next; } push(@buf,$_); } &FileWrite("$LogDir/index.dat", @buf); } } ########################## # 記事内容を修正削除(管理者) ########################## sub adminedit { if($form{"command"} eq " 削除 "){ # 元記事からの削除 if($form{"all"} eq "on"){ my @Index = &FileRead("$LogDir/index.dat"); my @buf; foreach(@Index){ my ($num, $yomi, $name, $genre, $pass, $date) = split(/<>/); if($num eq $form{'no'}){ push(@buf,"$num<><>削除済み<><>$pass<>$date"); next; } push(@buf,$_); } &FileWrite("$LogDir/index.dat", @buf); } # 番号のtxtのコメント行を削除 my @dat = &FileRead("$LogDir/$form{'no'}.txt"); @buf = grep{$form{$count++} ne "on"} @dat; &FileWrite("$LogDir/$form{'no'}.txt", @buf); }elsif($form{"command"} eq " 修正 "){ my @buf=(); # 修正 $time = &TimeGet; # 番号のtxtのコメント行を修正 my @dat = &FileRead("$LogDir/$form{'no'}.txt"); foreach(0 .. $#dat){ if($form{$_} eq "on"){ push(@buf,("$form{'comment'}<>$form{'name'}<>$form{'color'}<>$time\n")); next; } push(@buf, $dat[$_]); } &FileWrite("$LogDir/$form{'no'}.txt", @buf); } } ########################## # 時間を得る # 戻り値 dateに入っている時間 ########################## sub TimeGet { #タイム・ゾーン(地方時間帯)をJapan(JST-9)として日本標準時にセットする $ENV{'TZ'}="JST-9"; #時間を取得し変数に入れる my($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time); #指定された書式(第一引数)でdateに入れる my $date=sprintf("%04d%02d%02d%d%2d%02d%02d",$year+1900,$mon+1,$mday,$wday,$hour,$min); return $date; } ########################## # ファイルをロックする # 引数(ファイル名) ########################## sub lock { my($retry)=0; foreach (1 .. 5) { if (-e "$lockfile") { sleep(1); } else { if (open(FILE, ">$lockfile")) { close(FILE); $rerty = 1; return 1; } } } return 0; } ########################## # ファイルのロックを解除する # 引数(ファイル名) ########################## sub unlock { if(-e $lockfile) { unlink($lockfile); } } ########################## # デコード処理ルーチン ########################## sub decode { #POSTかGETか調べて、bufに格納する if($ENV{'REQUEST_METHOD'} eq "POST"){ read(STDIN, $buf, $ENV{'CONTENT_LENGTH'}); } else { $buf = $ENV{'QUERY_STRING'}; } if ($buf eq '') { return; } #bufの文字列を&で区切り、名前と値のpair(ペア)に分ける @pairs = split(/&/, $buf); foreach(@pairs){ #現在のpairs($_)からnameとvalueに振り分ける ($name, $value) = split(/=/, $_); #tr(translitarate)を使って間にある + を半角スペースに変換する $value =~ tr/\+/ /; #16進数を取り出し($1に入る)、hex関数で10進数にする。 #pack関数で型指定("C")をして、文字に変換する #それからs/で(%??)を(e(評価する)を使って)pack関数を評価した値に置き換える $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg; &jcode::convert ( $value, 'sjis' ); #文字を実体名に置き換える $value =~ s/&/&/g; #ampersand (?) $value =~ s/"/"/g; #quotation mark (") $value =~ s//>/g; $value =~ s/<>/<>/g; $value =~ s/(\t|\r\n|\r|\n)/
    /g;#\t(タブ)\r(キャリッジリターン)\n(ニューライン)を消す #nameをキーに、valueを値にしてハッシュに代入する $form{$name} = $value; } #サイズチェック if(length($form{"comment"}) > $data_size){ print "Content-type: text/html\n\n"; &error("投稿量が多すぎです。") } &tag($form{"comment"}) if($tagkey); } ########################## # ヘッダー部表示ルーチン ########################## sub header { print <<"end_of_show_header"; $title_str $body end_of_show_header print "
    "; if($title_img){ print "\n" ; }else{ print "$title_str"; } print "
    "; print "$link"; print "
    \n"; &HTML_att; print "
    "; print "
    "; print "
    "; } ########################## # 著作権部表示ルーチン ########################## sub copyright { print <<"end_of_show_copyright";
    - 辞典CGI 3.09. -
    end_of_show_copyright } ########################## # フッター部表示ルーチン ########################## sub footer { &HTML_list; &HTML_registform(@genrelist); &HTML_delform; ©right; print <<"end_of_show_footer"; end_of_show_footer } ########################## # ファイルに書き込む # 引数(ファイル名、書き込む配列) ########################## sub FileWrite { &lock if($lockkey); #ローカライズし #引数をfilenameとLINESに格納する my($filename, @LINES) = @_; #open関数でファイルを開く(このあとOUTはのように使える) #失敗したらエラーページで終了 if( !(open(OUT,">$filename")) ){ &error("$filenameに書き込めません。"); } #OUTに@LINESを出力する print OUT @LINES; #ファイルを閉じる close (OUT); &unlock if($lockkey); } ########################## # ファイルを読み込む # 引数(ファイル名) ########################## sub FileRead { &lock if($lockkey); #ローカライズする my($filename,@LOG); #引数のファイル名(@_)を$filenameに格納する ($filename) = @_; #open関数でファイルを開く(このあとINはのように使える) #失敗したらエラーページで終了 if( !(open(IN,"$filename")) ){ &error("$filenameが開けません。"); } #@LOGに読み込んだ内容を格納し @LOG = ; #ファイルを閉じ close(IN); #配列を返す &unlock if($lockkey); return @LOG; } ########################## # エラー処理ルーチン ########################## sub error { print "Content-type: text/html\n\n"; &header; print "$body"; my($error,@error_fields) = @_; print "




    $_[0]


    "; &footer; exit; } ########################## # タグを有効にして閉じ忘れを補完する # 引数(文字列) ########################## sub tag{ my @allowtag = qw(font marquee button input b i s strike tt u sup sub em strong blink img hr); my ($found,$invalue,$tag,$intag,$outtag,%count); my $arg = $_[0]; my @value = split(/</,$arg); my $first = shift(@value); foreach(@value){ $found=$tag=$intag=$outtag=''; $invalue = $_; foreach (@allowtag){ if($invalue =~ /^($_)\b(.*?)>(.*)/i){ ($tag,$intag,$outtag) = ($1,$2,$3); $intag =~ s/\'|\"//g; $intag =~ s/"/"/g; #quotation mark (") if($_ eq 'img'){ # img固有の処理 last if($intag =~ /^\/|dynsrc|file:|mailto:|\?/i); last if($intag !~ /^\s/); $intag =~ s/\b(width|height)\s*=\s*(\d|\%)*\s*//gi; } elsif($_ eq 'hr'){ # hr固有の処理 $intag =~ s/\b(width|height)\s*=\s*(\d|\%)*\s*//gi; } elsif($_ eq 'font' || $_ eq 'marquee' || $_ eq 'button' || $_ eq 'input'){ last if($intag =~ /\b(javascript\s*:|style\s*=|point\-size\s*=)/i); } elsif($_ eq 'b' || $_ eq 'i' || $_ eq 's' || $_ eq 'strike' || $_ eq 'tt' || $_ eq 'u' || $_ eq 's' || $_ eq 'sup' || $_ eq 'sub' || $_ eq 'em' || $_ eq 'strong' || $_ eq 'blink'){ last if($intag); } $count{$_}++; } elsif($invalue =~ /^(\/$_)>(.*)/i && $_ ne 'hr' && $_ ne 'img'){ # 閉じタグの場合 $count{"_$_"}++; ($tag,$outtag) = ($1,$2); } else{ next; } $found++; last; } if($found){ $_ = "<$tag$intag>$outtag"; } else{ $_ = "<$_"; } } unshift(@value,$first); $arg = join('',(@value)); #タグ閉じ補完(marqueeを最初に閉じるようにsort) my @tagkey = grep(!/_|img|hr/,keys(%count)); my $i = 0; foreach(@tagkey){ if($i != 0 && $tagkey[$i] eq 'marquee'){ #先頭がmarqueeじゃなかったら入れ替える ($tagkey[0],$tagkey[$i]) = ($tagkey[$i],$tagkey[0]); last; } $i++; } foreach(@tagkey){ $arg .= "" x $count{$_}; } $_[0] = $arg; }