#! /usr/local/bin/perl ;# ;# Changed from original by N.Yukawa 1997.9.25 ;# ;# WWWBBS version 1.0(フリーソフト) ;# ;# Script written by Kazu.Y ;# Created on: 01/Sep/97 ;# Last Modified on: 01/Sep/97 ;# I can be reached at: rescue@ask.or.jp ;# Scripts Found at: http://www.ask.or.jp/~rescue/ ;# ;# <利用規定の抜粋> ;# 1.このスクリプトは自分で使うために承諾なしに自由に改造することができます。 ;# 2.改造の有無にかかわらず、このスクリプトを再配布することはできません。 ;# 3.このシステムを有償で他人に設置してあげたりする行為は無断ではできません。 ########################################################################################### # # 基本構成(初期設定はこの構成を前提に設定されています) # # public_html(ホームページディレクトリ) # | # |-- cgi-bin(任意のディレクトリ) # | # |-- infomsg (記事ディレクトリ) [777] # |-- infotree (スレッドデータディレクトリ) [777] # | # |-- jcode.pl [755] # |-- infobbs.cgi [755] <- このCGIスクリプトを実行 # |-- infomaster.pwd [666] <- 空のファイル # # ・jcode.pl/infobbs.cgi/infomaster.pwdを同じ場所に設置する # ・[ ]内はパーミッッション値 # ・jcode.plは中身を全くいじらずにそのままアスキー転送する # ・jcode.plはjperlでは利用できないので注意すること # ・これらのファイルはアスキーモードで取り扱う(転送)すること # ・マスターキーの変更機能が効かない場合は、あなたのサーバでは # 暗号処理ができないと思われますので、設置できません # ########################################################################################### ## 初期設定 ## #終了ボタンを押すと表示するページのURL $bye = 'http://www.numse.nagoya-u.ac.jp/JSTP/gyoji.html'; #画面表示するタイトル $title = '新進部会 行事予定'; #ブラウザの上部バーに表示するタイトル $title2 = '新進部会 行事予定'; #1回に画面表示する件数 #インデックスファイルを持たないシステムなので #この件数を大きくするとその回数だけ記事ファイルにアクセスしますので #できるだけこれ以下でご利用ください. $def = 10; #設定 $body = ''; #jcode.plのパス require '/usr/local/etc/httpd/cgi-bin/jcode.pl'; ############## #■時間処理 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); if ($month < 10) { $month = "0$month"; } if ($mday < 10) { $mday = "0$mday"; } if ($sec < 10) { $sec = "0$sec"; } if ($min < 10) { $min = "0$min"; } if ($hour < 10) { $hour = "0$hour"; } $month = ($mon + 1); $wday = ('日','月','火','水','木','金','土')[$wday]; $basenum = "$year$month$mday$hour$min$sec"; $date_now = "$month\/$mday($wday)$hour\:$min"; $number = $ENV{'QUERY_STRING'}; read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); #■入力処理 $line_count = 0; @pairs = split(/&/,$buffer); 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,'euc'); $value =~ s/\n//g; $value =~ s//>/g; if (!($value =~ /\n/) && $value =~ /\r/) { $value =~ s/\r/\n/g; } if ($name eq "ikkatsu") { push(@IKKATSU,$value); } else { $FORM{$name} = $value; } } #■マスターキー確認 if (!open(IN,"./infomaster.pwd")) { &error('システム設定','マスターキーが開けません.'); } $master = ; chop($master) if $master =~ /\n$/; close(IN); if ($FORM{'action'} eq 'change_master') { &set_master; } if ($FORM{'action'} eq 'set_master') { &set_master2; } if ($master eq '') { &set_master; } #■分岐 if ($number =~ /\d+/) { &view; } if ($buffer eq '') { $start = 0; } else { $start = $FORM{'start'} + 1; } if ($FORM{'action'} eq 'post') { &post; } elsif ($FORM{'action'} eq 'write') { &write; } elsif ($FORM{'action'} eq 'remove') { &remove; } elsif ($FORM{'action'} eq 'admin' && (crypt($FORM{'master'}, substr($master,0,2)) eq $master)) { $admin = 1; &list; } elsif ($FORM{'action'} eq 'admin_remove' && (crypt($FORM{'master'}, substr($master,0,2)) eq $master)) { &ikkatsu; } &list; sub list { chdir("./infomsg/"); $ls = `ls`; @ls = split(/\s+/,$ls); @ls = reverse(@ls); $all = @ls; if ($all <= ($start + $def - 1)) { $end = $all - 1; } else { $end = $start + $def - 1; } print "Content-type: text/html\n\n"; print "$title2\n\n"; print "$body\n"; print "

$title

\n"; if ($all != 0) { print "\n"; if ($admin) { print "\n"; } else { print "\n"; } print "\n"; foreach $file ($start .. $end) { $file = $ls[$file]; if (!open(IN,$file)) { push(@ERR,$file); next; } @lines = ; close(IN); &header; if (length($name) > 20) { $name = substr($name,0,18); $name = $name . '..'; } if (length($subject) > 40) { $subject = substr($subject,0,38); $subject = $subject . '..'; } print "\n"; if ($admin) { print "\n"; print "\n"; print "\n"; print "\n"; } print "\n"; print "\n"; if ($email =~ /(.*)\@(.*)\.(.*)/) { print "\n"; } else { print "\n"; } print "\n"; print "\n"; print "\n"; } print "
削除記事番号記録日記録者題名サイズ参照数
記事番号記録日記録者題名サイズ参照数
$file
$date$name$name$subject$size$rc

\n"; } else { print "メッセージはありません.

\n"; } if (@ERR) { print "警告!次のメッセージのファイルが開けません > @ERR

\n"; } if ($admin) { print "\n"; } print "\n"; $i = $all - 1; if ($end < $i) { print "\n"; if ($admin) { print "\n"; print "\n"; } print "\n"; print "\n"; } # print "\n"; # print "\n"; # print "\n"; # print "\n"; print "\n"; print "\n"; print "

\n"; # 表示義務 print "

WWWBBS v1.0 is Free.

\n"; # if (! $admin) { # # print "
\n\n\n\n\n

\n"; # # print "\n"; # print "\n"; # print "\n"; # $start--; # print "\n"; # print "\n"; # # print "\n"; # print "\n"; # print "
マスターキー "; # print "
\n"; # } print "\n"; exit; } sub header { if ($lines[0] =~ /^Crypt\:(.*)/) { $crypt = $1; } if ($lines[1] =~ /^Rc\:(.*)/) { $rc = $1; } if ($lines[2] =~ /^Date\:(.*)/) { $date = $1; } if ($lines[3] =~ /^Subject\:(.*)/) { $subject = $1; } if ($lines[4] =~ /^Name\:(.*)/) { $name = $1; } if ($lines[5] =~ /^Email\:(.*)/) { $email = $1; } if ($lines[6] =~ /^Size\:(.*)/) { $size = $1; } if ($lines[7] =~ /^Host\:(.*)/) { $host = $1; } if ($lines[8] =~ /^Homepage\:(.*)/) { $homepage = $1; } if ($lines[9] =~ /^Tree\:(.*)/) { $tree = $1; } &jcode'convert(*date,'euc'); &jcode'convert(*subject,'euc'); &jcode'convert(*name,'euc'); } sub view { if (!-e "./infomsg/$number") { &error('入出力エラー',"$number番のメッセージは削除されました."); } if (!open(IN,"./infomsg/$number")) { &error('入出力エラー',"$number番のメッセージファイルを開けません."); } @lines = ; close(IN); &header; $axs=@lines; print "Content-type: text/html\n\n"; print "$title2\n\n"; print "$body\n"; print "

$subject

\n"; # if ($axe le 11) { print "
";
        	foreach $num (11 .. $axs - 1) { print $lines[$num]; }
       		print "

\n"; # } if ($homepage ne '') { if (open(IN,"./infohtml/$homepage")) { @htmls = ; close(IN); $axs = @htmls; foreach $num (1 .. $axs - 1) { print $htmls[$num]; } print "

\n"; } print "


\n"; print "URL=$homepage

\n"; } print "


\n"; print "

オンライン申込みはこちらへ

\n"; print "

\n"; if ($email =~ /(.*)\@(.*)\.(.*)/) { print "●記録者 $name [$host]
\n"; } else { print "●記録者 $name [$host]
\n"; } print "●記録日 $date

\n"; print "\n"; # print "\n"; # print "\n"; # print "\n"; # print "\n"; # print "\n"; # print "\n"; # # print "\n"; # print "\n"; # print "\n"; # print "\n"; # print "\n"; print "
パスワード "; # print "

\n"; print "


\n"; #■参照数処理 $rc++; $lines[1] = "Rc:$rc\n"; if (!open(OUT,"> ./infomsg/$number")) { &error('入出力エラー',"$number番のメッセージファイルに参照数データを記録できません."); } print OUT @lines; close(OUT); #■スレッド処理 if (!open(IN,"./infotree/$tree")) { print '構成の最初の記事が削除されたため構成図は表示されません.

' . "\n"; exit; } @tr_file = ; close(IN); # print '

メッセージの構成図

' . "\n"; # print "
\n"; # foreach (@tr_file) { # # if (/.*\s\s$number.*/) { s/(.*) $number(.*)/\1 \<\;$number<\/b>\>\;\2/g; } # elsif (/.*\s\s(\d+).*/) { s/(.*\s\s)(\d+)(.*)/\1\<\;\2<\/a>\>\;\3/g; } # elsif (/.*\`\-\-$number.*/) { s/(.*)\`\-\-$number(.*)/\1\`\-\-$number<\/b>\2/g; } # else { s/(.*)\`\-\-(\d+)(.*)/\1\`\-\-\\2<\/a>\3/g; } # print; # } # print "

\n"; print "\n"; exit; } sub post { #■クッキー処理 $cookies = $ENV{'HTTP_COOKIE'}; @pairs = split(/;/,$cookies); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $name =~ s/ //g; $DUMMY{$name} = $value; } @pairs = split(/,/,$DUMMY{$bye}); foreach $pair (@pairs) { ($name, $value) = split(/:/, $pair); $COOKIE{$name} = $value; } if ($COOKIE{'name'} eq '匿名希望') { $COOKIE{'name'} = ''; } #■画面 if ($FORM{'resp_number'} ne '') { $write_title = "$FORM{'resp_number'}への返信"; } else { $write_title = "新規投稿"; } print "Content-type: text/html\n\n"; print "$title2\n\n"; print "$body\n"; print "

$write_title

\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; #■タイトル処理 if ($FORM{'resp_subject'} eq '') { print "題名   
\n"; } elsif ($FORM{'resp_subject'} =~ /^re\((.*)\):(.*)/) { $title = $2; if ($1 =~ /(\d+)/) { $resnum = ($1 + 1); print "題名
\n"; } else { print "題名
\n"; } } else { print "題名   
\n"; } print "記録者  
\n"; print "Eメール 
\n"; print "内容

\n"; print "URL

\n"; print "パスワード (記事の削除時に使用)

\n"; print "\n"; print "

\n"; print "\n"; exit; } sub write { #■入力チェック if ($FORM{'resp_number'} ne '') { if (!-e "./infomsg/$FORM{'resp_number'}") { &error('返信エラー',"返信元となる$FORM{'resp_number'}番の記事は削除されていますので投稿できません."); }} if ($FORM{'resp_base'} ne '') { if (!-e "./infomsg/$FORM{'resp_base'}") { $no_tree = 1; }} else { $FORM{'resp_base'} = $basenum; } if ($FORM{'name'} eq '') { $FORM{'name'} = '匿名希望'; } if ($FORM{'subject'} eq '') { &error('入力不備','題名が書かれていません.'); } # if ($FORM{'value'} eq '') { &error('入力不備','内容が書かれていません.'); } if ($FORM{'pwd'} =~ /\W/ || $FORM{'pwd'} eq '') { &error('入力不備','パスワードを半角英数字で入力してください.'); } if ($FORM{'email'} ne '' && $FORM{'pobox'} ne '') { &error('入力不備','Eメールを入力される場合は私書箱指定はできません.'); } if ((!$email =~ /(.*)\@(.*)\.(.*)/) && $email ne '') { &error('入力不備','Eメールは半角文字で正しく記入してください.'); } $host = $ENV{'REMOTE_HOST'}; $addr = $ENV{'REMOTE_ADDR'}; if ($host eq $addr) { $host = gethostbyaddr(pack('C4',split(/\./,$host)),2) || $addr; } &encode($FORM{'pwd'}); #■記録 if (!open(DB,"> ./infomsg/$basenum")) { &error('記録エラー','記事の記録ができません.'); } print DB "Crypt:$crypt_password\n"; print DB "Rc:0\n"; print DB "Date:$date_now\n"; print DB "Subject:$FORM{'subject'}\n"; print DB "Name:$FORM{'name'}\n"; print DB "Email:$FORM{'email'}\n"; $size = length($FORM{'value'}); print DB "Size:$size\n"; print DB "Host:$host\n"; print DB "Homepage:$FORM{'homepage'}\n"; print DB "Tree:$FORM{'resp_base'}\n\n"; print DB $FORM{'value'}; close(DB); if (! $no_tree) { &tree; } #■クッキー処理 $ENV{'TZ'} = "GMT"; ($secg,$ming,$hourg,$mdayg,$mong,$yearg,$wdayg,$ydayg,$isdstg) = localtime(time + 30*24*60*60); if ($yearg < 10) { $yearg = "0$yearg"; } if ($secg < 10) { $secg = "0$secg"; } if ($ming < 10) { $ming = "0$ming"; } if ($hourg < 10) { $hourg = "0$hourg"; } if ($mdayg < 10) { $mdayg = "0$mdayg"; } $y0="Sunday"; $y1="Monday"; $y2="Tuesday"; $y3="Wednesday"; $y4="Thursday"; $y5="Friday"; $y6="Saturday"; $youbi = ($y0,$y1,$y2,$y3,$y4,$y5,$y6) [$wdayg]; $m0="Jan"; $m1="Feb"; $m2="Mar"; $m3="Apr"; $m4="May"; $m5="Jun"; $m6="Jul"; $m7="Aug"; $m8="Sep"; $m9="Oct"; $m10="Nov"; $m11="Dec"; $month = ($m0,$m1,$m2,$m3,$m4,$m5,$m6,$m7,$m8,$m9,$m10,$m11) [$mong]; $date_gmt = "$youbi, $mdayg\-$month\-$yearg $hourg:$ming:$secg GMT"; $cook="name\:$FORM{'name'}\,email\:$FORM{'email'}\,pwd\:$FORM{'pwd'}"; print "Set-Cookie: $bye=$cook; expires=$date_gmt\n"; $start = 0; &list; } sub encode { #■暗号化 $now = time; ($p1, $p2) = unpack("C2", $now); $wk = $now / (60*60*24*7) + $p1 + $p2 - 8; @saltset = ('a'..'z','A'..'Z','0'..'9','.','/'); $nsalt = $saltset[$wk % 64] . $saltset[$now % 64]; $crypt_password = crypt($_[0], $nsalt); } sub tree { #■スレッド処理 if ($basenum eq $FORM{'resp_base'}) { if (!open(OUT,"> ./infotree/$basenum")) { &error('記録エラー','スレッドファイルに記録できません.'); } print OUT "

\n"; print OUT "
$basenum\n"; print OUT "
"; print OUT "\n"; print OUT "
\n"; close(OUT); return; } else { if (!-e "./infotree/$FORM{'resp_base'}") { return; }} if (!open(IN,"./infotree/$FORM{'resp_base'}")) { return; } @tr_file = ; close(IN); if (!open(OUT,"> ./infotree/$FORM{'resp_base'}")) { return; } foreach $line (@tr_file) { if ($line =~ /
/) { print OUT "
\n"; print OUT "
`--$basenum\n"; print OUT "
\n"; print OUT "
\n"; print OUT "
\n"; } else { print OUT $line; } } close(OUT); } sub remove { #■削除処理 if (!-e "./infomsg/$FORM{'remove_number'}") { &error('削除','このメッセージは既に削除されています.'); unlink("./infotree/$FORM{'remove_number'}") || return; } if (!open(IN,"./infomsg/$FORM{'remove_number'}")) { &error('削除失敗',"$FORM{'remove_number'}番のメッセージは異常により削除できません. 管理者が直接削除してください."); } @lines = ; close(IN); &header; $ok = 1; if (crypt($FORM{'pwd'}, substr($crypt,0,2)) eq $crypt) { $ok = 0; } elsif (crypt($FORM{'pwd'}, substr($master,0,2)) eq $master) { $ok = 0; } if ($ok) { &error('削除失敗',"パスワードが認証されませんので削除できません."); } unlink("./infomsg/$FORM{'remove_number'}") || push(@REMOVE,"MSG/$FORM{'remove_number'}"); if (-e "./infotree/$FORM{'remove_number'}") { unlink("./infotree/$FORM{'remove_number'}") || push(@REMOVE,"TREE/$FORM{'remove_number'}"); } #■スレッド処理 if (!open(IN,"./infotree/$tree")) { return; } @tr_file = ; close(IN); if (!open(OUT,"> ./infotree/$tree")) { return; } foreach $line (@tr_file) { $line =~ s/$FORM{'remove_number'}/DELETED/g; print OUT $line; } close(OUT); if (@REMOVE) { &error('削除失敗',"次のファイルの削除に失敗しました. 管理者が直接削除してください. > @REMOVE"); } $start = 0; &list; } sub ikkatsu { #■一括削除処理 foreach $temp (@IKKATSU) { if (!-e "./infomsg/$temp") { unlink("./infotree/$temp"); next; } if (!open(IN,"./infomsg/$temp")) { unlink("./infomsg/$temp") || push(@REMOVE,"MSG/$temp"); unlink("./infotree/$temp"); next; } @lines = ; close(IN); &header; unlink("./infomsg/$temp") || push(@REMOVE,"MSG/$temp"); if (-e "./infotree/$temp") { unlink("./infotree/$temp") || push(@REMOVE,"TREE/$temp"); } #■スレッド処理 if (!open(IN,"./infotree/$tree")) { next; } @tr_file = ; close(IN); if (!open(OUT,"> ./infotree/$tree")) { next; } foreach $line (@tr_file) { $line =~ s/$temp/DELETED/g; print OUT $line; } close(OUT); } if (@REMOVE) { &error('削除失敗',"次のファイルの削除に失敗しました. 管理者が直接削除してください. > @REMOVE"); } $start = 0; &list; } sub set_master { print "Content-type: text/html\n\n"; print "$title2\n"; print "$body\n"; print "

マスターキーの設定

\n"; print "
\n"; print "\n"; print "

\n"; print "旧パスワード
\n"; print "新パスワード
\n"; print "新パスワード (確認のためもう一度)

\n"; print "\n"; print "

\n"; print "

\n"; exit; } sub set_master2 { if ($FORM{'old'} eq '' && $FORM{'new1'} eq '' && $FORM{'new2'} eq '') { &error('マスターキー設定','入力してください.'); } elsif ($master eq '' && $FORM{'old'} ne '') { &error('マスターキー設定','新規設定ですので、旧パスワード欄は空欄にしてください.'); } elsif ($master eq '' && ($FORM{'new1'} eq '' || $FORM{'new2'} eq '')) { &error('マスターキー設定','新パスワードは確認も含めて2回入力してください.'); } elsif ($master ne '' && $FORM{'old'} eq '') { &error('マスターキー設定','旧パスワードを入力してください.'); } elsif ($FORM{'new1'} ne $FORM{'new2'}) { &error('マスターキー設定','確認のために入力したパスワードが一致しません.'); } elsif ($FORM{'new1'} =~ /\s/ || $FORM{'new1'} =~ /\W/) { &error('マスターキー設定','半角英数字で入力してください.'); } elsif (length("$FORM{'new1'}") > 8 || length("$FORM{'new1'}") < 4) { &error('マスターキー設定','4文字から8文字で入力してください.'); } elsif ($master ne '') { if (crypt($FORM{'old'}, substr($master,0,2)) ne $master) { &error('マスターキー設定','旧パスワードが認証されませんでした.'); }} &encode($FORM{'new1'}); $master = $crypt_password; if (!open(OUT,">./infomaster.pwd")) { &error('マスターキー設定','マスターキーファイルに記録できません.'); } print OUT $crypt_password; close(OUT); } sub error { print "Content-type: text/html\n\n"; print "$title2\n"; print "$body\n"; print "

$_[0]

\n"; print $_[1] . "

\n"; print "[一覧へ] またはブラウザの[戻る]ボタンを押して前の画面に移動してください.

\n"; print "\n"; exit; }