簡易BBS(CGI用)
1行タイプの簡易BBSプログラムです。
この HTML 上では漢字がシフトJIS になっていますが、本来は EUC 向けとなっています。
@Nifty向けにパス名などが設定されています。また、同様の理由で組み込み以外のライブラリを必要としません。
フォームのデコードも自前で行なっています。
#!/usr/local/bin/perl
# IE/その他判別
$IE = ( $ENV{'HTTP_USER_AGENT'} =~ /MSIE/i );
$cgi_path = "";
$cgi_file = "http://hpcgi2.nifty.com/caty/testbbs.cgi";
$datafile = "dfile";
$max_url = 80;
$max_name = 24;
$max_text = 128;
if ($IE) {
$ftext_size = 128;
} else {
$ftext_size = 100;
}
$record_size = 256;
$record_top = 1;
$record_max = 255;
read(STDIN, $bf, $ENV{'CONTENT_LENGTH'} );
%FORM = &form_decode($bf);
&pr_header;
pr_form(0);
$err = 0;
$data_ptr = 1;
$data_num = 0;
$top_rec = "";
### file open & initialize ###
if (!open(DATAFILE, "+< $datafile")) {
# オープンできない場合新規作成とみなす
unlink "$datafile";
if (!open(DATAFILE, "> $datafile")) {
# どうにもならない
$err = 1;
} else {
close(DATAFILE);
if (!open(DATAFILE, "+< $datafile")) {
$err = 1;
} else {
# 新規作成処理
binmode(DATAFILE); # 一応入れておく
flock(DATAFILE,2);
&set_dataptr;
}
}
} else {
binmode(DATAFILE); # 一応入れておく
flock(DATAFILE,1);
seek(DATAFILE, 0, 0);
if (read(DATAFILE, $top_rec, $record_size) == $record_size) {
($data_ptr, $data_num) = split(/:/, $top_rec, 2);
## print $data_ptr, " ", $data_num, "<BR>";
} else {
$err = 1;
}
}
if ($err == 0) {
# file open 成功時のみ
if ($ENV{'REQUEST_METHOD'} =~/POST/i && length($FORM{'text'})>0) {
# text 未入力でPOST動作の場合は投稿を無効とする
&post_msg;
} else {
&disp_msg;
}
} else {
print "サーバー側の異常でファイルが開けませんでした。<BR>";
}
close(DATAFILE);
&pr_footer;
#--------------- main end ---------------
########## html Header/Footer 出力 ##########
sub pr_header {
print <<Multi_text;
Content-type: text/html
<html><HEAD><META http-equiv="Content-Type" content="text/html; charset=euc-jp">
<TITLE>BBS output</TITLE>
</HEAD>
<BODY bgcolor="#101040" text="#ffffff" link="#ff7f00" vlink="#ff0000" alink="#ff0000">
<HR WIDTH="80%" SIZE=4>
<H2 ALIGN="center">Test bbs (1行タイプ)</H2>
<HR WIDTH="80%" SIZE=4>
<H5 ALIGN="center">注1)ブラウザー設定で JavaScript が有効となっていない場合、誤動作の可能性があります。</H5>
<H5 ALIGN="center">注2)漢字は EUC コード使用なので環境によっては文字化けするかもしれません。</H5>
<BASEFONT SIZE="3">
Multi_text
}
sub pr_footer {
print <<Multi_text;
</BODY>
</HTML>
Multi_text
}
########## 入力用 form 出力 ##########
sub pr_form {
print <<Multi_text;
<SCRIPT LANGUAGE="JavaScript">
<!--
function formcheck()
{
len = document.form1.name.value.length;
if ( len < 1 ) {
alert("名前が入力されていません");
return false;
}
len = document.form1.text.value.length;
if ( len < 1 ) {
alert("メッセージが入力されていません");
return false;
}
return true;
}
function reload()
{
document.formdmy.name.value = document.form1.name.value ;
document.formdmy.utl.value = document.form1.url.value ;
document.formdmy.text.value = document.form1.text.value ;
return true;
}
// -->
</SCRIPT>
<HR>
<TABLE BORDER="0">
<FORM NAME="form1" onSubmit="return formcheck()" onReset="return reset_reload()" ACTION="$cgi_file" METHOD="POST">
<TR><TD WIDTH=64>名前</TD><TD><INPUT TYPE="text" NAME="name" VALUE="$FORM{'name'}" SIZE=$max_name MAXLENGTH=$max_name></TD></TR>
<TR><TD WIDTH=64>URL</TD><TD><INPUT TYPE="text" NAME="url" VALUE="$FORM{'url'}" SIZE=$max_url MAXLENGTH=$max_url>(省略可)</TD></TR>
<TR><TD WIDTH=64>本文</TD><TD><INPUT TYPE="text" NAME="text" SIZE=$ftext_size MAXLENGTH=$max_text></TD></TR>
</TABLE>
<P>
<TABLE BORDER="0">
<TR><TD><INPUT TYPE="submit" VALUE="書き込み"></TD>
</FORM>
<FORM NAME="formdmy" onSubmit="return reload()" ACTION="$cgi_file" METHOD="POST">
<INPUT TYPE="hidden" NAME="name" VALUE="$FORM{'name'}" >
<INPUT TYPE="hidden" NAME="url" VALUE="$FORM{'url'}" >
<INPUT TYPE="hidden" NAME="text" VALUE="" >
<TD><INPUT TYPE="submit" VALUE="再表示"></TD>
</FORM>
</TABLE>
<HR>
あなたのブラウザー情報<BR>
REMOTE_HOST=$ENV{'REMOTE_HOST'}<BR>
REMOTE_ADDR=$ENV{'REMOTE_ADDR'}<BR>
HTTP_USER_AGENT=$ENV{'HTTP_USER_AGENT'}<BR>
<HR>
Multi_text
}
########## トップレコード変更 ##########
sub set_dataptr {
$top_rec = sprintf("%07d:%07d:", $data_ptr, $data_num) . (" " x $record_size);
seek(DATAFILE, 0, 0);
print DATAFILE substr($top_rec, 0, $record_size);
}
########## メッセージ投稿 ##########
sub post_msg {
my($name) = $FORM{'name'};
my($text) = $FORM{'text'};
my($url) = $FORM{'url'};
my($l_name) = length($name);
my($l_text) = length($text);
my($l_url) = length($url);
if ( $l_name < 1 || $l_name > $max_name ) {
print "名前が正しく入力されていません。";
return;
}
if ( $l_text < 1 || $l_text > $max_text ) {
print "本文が正しく入力されていません。";
return;
}
if ( $l_url > $max_url ) {
print "urlが長過ぎます。";
return;
}
if ( $l_url > 0 ) {
if ( $url =~ /@/ && !($url =~ m#/#) ) {
$tmprecord = sprintf(' <A href="mailto:%s" >%s</A> : %s', $url, $name, $text);
} else {
if ( $url =~ /^http:/ ) {
$tmprecord = sprintf(' <A href="%s" >%s</A> : %s', $url, $name, $text);
} else {
$tmprecord = sprintf(' <A href="http://%s" >%s</A> : %s', $url, $name, $text);
}
}
} else {
$tmprecord = sprintf(" %s : %s", $name, $text);
}
# post
my($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time());
$tmprecord = sprintf("%02d/%02d/%02d %02d:%02d ", $year %= 100, $mon+1, $mday, $hour, $min)
. $tmprecord . "\n" . (" " x $record_size);
seek(DATAFILE, $record_size * $data_ptr, 0);
print DATAFILE substr($tmprecord, 0, $record_size);
# Pointer update
$data_ptr++;
if ($data_ptr > $record_max) {
$data_ptr = $record_top;
}
$data_num++;
if ($data_num > $record_max) {
$data_num = $record_max;
}
&set_dataptr;
&disp_msg;
}
########## メッセージ表示 ##########
sub disp_msg {
my($name) = $FORM{'name'};
my($text) = $FORM{'text'};
my($mail) = $FORM{'mail'};
my($tmp) = "";
my($trash) = "";
my($i) = 0;
if ($i < $data_num) {
my($ptr) = $data_ptr - 1;
if ($ptr < $record_top) {
$ptr = $record_max;
}
for (my($i) = 0 ; $i < $data_num ; $i++) {
seek(DATAFILE, $record_size * $ptr, 0);
if (read(DATAFILE, $tmp, $record_size) > 1) {
my(@data) = split(/\n/, $tmp, 2);
print $data[0], "<BR>\n";
$ptr--;
if ($ptr < $record_top) {
$ptr = $record_max;
}
} else {
print "ファイル読み込み中に異常が発生しました。<BR>\n";
last;
}
}
} else {
print "書き込みはありません。<BR>\n";
}
print '<PRE>';
print `ls -l ../bin`;
print `echo "-----------------"`;
print `ls -x`;
print `/bin/df`;
print '</PRE><HR>';
}
########## CGI FORM decode ##########
sub form_decode {
my (%thash);
my (@pairs) = split(/&/, $_[0]);
#print '@pairs =', @pairs , '<BR>';
foreach (@pairs) {
tr/+/ /;
s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
my ($key, $val) = split(/=/, $_, 2);
#print $key, ' ', $val , '<BR>';
chomp( $val );
$thash {$key} = htmltag_disable($val);
}
return (%thash);
}
########## HTML tag / \n を無効化(SJISではいまいち) ##########
sub htmltag_disable {
$_ = $_[0];
s/&/&/g;
s/</</g;
s/>/>/g;
s/"/"/g;
s/\n//g;
return ($_);
}
総合ホームページ
Perl納戸部屋