root/tags/ccbbs-1.3/bbs.cgi

Revision 115, 15.9 kB (checked in by akiyan, 2 years ago)

maintenance

Line 
1 #!/usr/bin/perl
2 #
3 # �~�X�f����rev 1.3
4 #
5 # ���̃t�@�C���͎��Ȃ��N���v�g�ł��B
6 # �ݒ� conf.cgi �ōs���܂��B
7 #
8 # �g����  HTML�ɋL�q�����O�̕��@
9 #     <!--#include virtual="�p�X/bbs.cgi?mode=latest" -->
10 #   �L�q��
11 #     <!--#include virtual="./cgi-bin/ccbbs/bbs.cgi?mode=latest" -->
12 #   �f���‚ɒ��ڃ����N������
13 #     <a href="http://..../cgi-bin/ccbbs/bbs.cgi?mode=logview">BBS</a>
14 #   �������݂̊Ǘ�
15 #     �f���‰�����dmin�����N����ĉ������B
16 #
17 # �~�ϑ���l�i���̃T�C�g�j
18 # http://www.akiyan.com/
19 #
20 # �Ƃقق�SI�� http://tohoho.wakusei.ne.jp/wwwssi.htm
21 #
22 # �X�V���� 2003-03-18 rev1.3 conf.cgi�̋L�q�~�X����B
23 # 2003-02-10 rev1.2 �Ǘ����O�C���y�[�W�̋L�q�~�X����B
24 # 2003-02-02 rev1.1 ��B
25 #
26 require 'conf.cgi';
27 require 'jcode.pl';
28 &get_query_string();
29
30         $conf{'maxlog'}--;
31         $admin_style = <<"EOM";
32 h1,h2 {
33  font-size:100%;
34  font-weight:bold;
35  margin:0;
36 }
37 body {
38  font-size:82%;
39  padding:1%;
40 }
41 thead {
42  font-weight:bold;
43 }
44 tbody {
45  font-weight:normal;
46 }
47 td {
48  border-width:0 0 1px 0;
49  border-style:dotted;
50  border-color:#888;
51  margin:0;
52  word-break:break-all;
53 }
54 EOM
55         $MODE   = $FORM{'mode'};
56         $ACTION = $FORM{'action'};
57         $LOG_FILENAME = './log.cgi';
58         @LOG_FORMAT = ('status', 'number' ,'name' ,'text' ,'time' , 'host', 'referer', 'email', 'url');
59         $LOG_CUTSTR = '<>';
60         if ($MODE eq '') {
61                 $conf{'charset'} = 'sjis';
62                 &put(&login());
63                 exit;
64         }
65         &loadlog();
66         if ($MODE eq 'write') {
67                 &write();
68                 print "location: $conf{'return_url'}\n\n";
69                 exit;
70         }
71         if ($MODE eq 'logview') {
72                 $conf{'charset'} = 'sjis';
73                 $conf{'viewline'} = $conf{'viewline_logview'};
74                 &put(&latest());
75                 exit;
76         }
77         if ($MODE eq 'latest') {
78                 &put(&latest());
79                 exit;
80         }
81         if ($MODE eq 'admin') {
82                 $conf{'charset'} = 'sjis';
83                 if ($FORM{'password'} eq $conf{'password'}) {
84                         &put(&admin());
85                 } else {
86                         &put(&login('<p style="color:#a00">�p�X���[�h���Ⴂ�܂��B</p>'));
87                 }
88                 exit;
89         }
90         exit;
91
92 ###
93 # ���O��b�V���̔z��i�[ / ���O�ۑ��ő匏���`�F�b�N�K��
94 sub loadlog
95 {
96         local($num, $row, $log_src, $array, $key, $value, $num_active);
97         @LOG = ();
98         @LOG_ALL = ();
99         @log_src = file($LOG_FILENAME);
100         if ($#log_src > $conf{'maxlog'}) {
101                 open(OUT, "+< $LOG_FILENAME");
102                 eval { flock(OUT, 2);    };
103                 eval { truncate(OUT, 0); };
104                 eval { seek(OUT, 0, 0);  };
105                 for($num = 1; $num <= $#log_src; $num++) {
106                         print(OUT $log_src[$num]);
107                 }
108                 close(OUT);
109                 @log_src = file($LOG_FILENAME);
110         }
111         @log_src = reverse(@log_src);
112         $num_active = 0;
113         for ($num = 0; $num <= $#log_src; $num++) {
114                 my $data;
115                 $row = $log_src[$num];
116                 $row =~ s/\r\n/\n/;
117                 $row =~ s/\n//;
118                 @array = split(/$LOG_CUTSTR/, $row);
119                 @data = &format_hash(*LOG_FORMAT, *array);
120                 ($data{'sec'}
121                 ,$data{'min'}
122                 ,$data{'hour'}
123                 ,$data{'mday'}
124                 ,$data{'mon'}
125                 ,$data{'YEAR'}
126                 ,$data{'wday'}
127                 ,$data{'yday'}
128                 ,$data{'isdst'}) = localtime($data{'time'});
129                 $data{'YEAR'} += ($data{'YEAR'} < 1900) ? 1900 : 0;
130                 $data{'year'} = substr($data{'YEAR'}, 2);
131                 $data{'mon'}  = &enforce_figure($data{'mon'} + 1, 2);
132                 $data{'mday'} = &enforce_figure($data{'mday'}, 2);
133                 $data{'hour'} = &enforce_figure($data{'hour'}, 2);
134                 $data{'min'}  = &enforce_figure($data{'min'}, 2);
135                 $data{'sec'}  = &enforce_figure($data{'sec'}, 2);
136                 if ($data{'email'ne '') {
137                         $data{'name'} = '<a href="mailto:' . $data{'email'} . '">' . $data{'name'} . '</a>';
138                 }
139                 if ($data{'url'} ne '') {
140                         $data{'url_link'} = &replace_hash(*data, $conf{'html_url'});
141                 } else {
142                         $data{'url_link'} = '';
143                 }
144                 while ( ($key, $value) = each %data) {
145                         $LOG_ALL[$num]{$key} = $value;
146                 }
147                 if ($data{'status'} == 0) {
148                         while ( ($key, $value) = each %data) {
149                                 $LOG[$num_active]{$key} = $value;
150                         }
151                         $num_active++;
152                 }
153         }
154 }
155
156 sub put
157 {
158         local($html) = @_;
159         if ($conf{'charset'} ne "" && $conf{'charset'} ne "sjis") {
160                 &jcode'convert(*html, $conf{'charset'});
161         }
162         print $html;
163 }
164
165 sub latest
166 {
167         local($num, $hash_grob, $html, $contents, $option, $start, $body);
168         $hash_grob = '';
169         $contents{'navi'}  = '';
170         $contents{'message_list'}  = '';
171         $html = &content_type('text/html');
172         my $view_count = 0;
173         $start = ( $FORM{'start'} > 0 ) ? $FORM{'start'} : 0;
174         for ($num = $start; $num <= $#LOG; $num++) {
175                 if ($conf{'autolink'}) {
176                         $LOG[$num]{'text'} = &auto_link($LOG[$num]{'text'}, $conf{'urlreplace'}, $conf{'target'});
177                 }
178                 $hash_grob = $LOG[$num];
179                 $contents{'message_list'} .= &replace_hash($hash_grob, $conf{'html_message'});
180                 $view_count++;
181                 if ($view_count == $conf{'viewline'}) {
182                         if ($num < $#LOG && $MODE eq 'logview') {
183                                 $option{'start'}  = $FORM{'start'} + $conf{'viewline_logview'};
184                                 $contents{'navi'} = $conf{'html_navi'};
185                                 $contents{'navi'} = &replace_hash(*conf,   $contents{'navi'});
186                                 $contents{'navi'} = &replace_hash(*option, $contents{'navi'});
187                         }
188                         $num = $#LOG;
189                 }
190         }
191         if ($MODE eq 'logview') {
192                 $body{'body'} = $conf{'html_body'};
193                 $body{'body'} = &replace_hash(*conf    , $body{'body'});
194                 $body{'body'} = &replace_hash(*contents, $body{'body'});
195                 $html .= $conf{'html_logview'};
196                 $html = &replace_hash(*body,     $html);
197                 $html = &replace_hash(*conf,     $html);
198         } else {
199                 $html .= $conf{'html_body'};
200                 $html = &replace_hash(*conf,     $html);
201                 $html = &replace_hash(*contents, $html);
202         }
203         return($html);
204 }
205
206 sub write
207 {
208         local(@data, $wdata, $first, $row);
209         $wdata = '';
210         $first = 1;
211         $data{'number'}  = &select_max(*LOG_ALL, 'number') + 1;
212         $data{'name'}    = &real_html($FORM{'name'});
213         if($conf{'nobreak'}) {
214                 $FORM{'text'} = &nobreak($FORM{'text'});
215         }
216         $data{'text'}    = &real_html($FORM{'text'});
217         $data{'time'}    = &gettime($conf{'timediff'});
218         $data{'status'}  = 0;
219         $data{'host'}    = ($ENV{'REMOTE_HOST'} ne '') ? $ENV{'REMOTE_HOST'} : $ENV{'REMOTE_ADDR'};
220         $data{'referer'} = $ENV{'HTTP_REFERER'};
221         $data{'email'}   = &secure_value(&real_html($FORM{'email'}));
222         $data{'url'}     = &secure_value(&real_html($FORM{'url'}));
223
224         if ($data{'name'} eq "") {
225                 &error('���O��������܂���);
226                 exit;
227         }
228         if ($data{'text'} eq "") {
229                 &error('���b�Z�[�W��������܂���);
230                 exit;
231         }
232         if (length($data{'name'} . $data{'text'}) > $conf{'maxlength'}) {
233                 &error('��\�ȍő������́A�S�ĕ����� . $conf{'maxlength'} . '�o�C�g�܂łł��B');
234                 exit;
235         }
236         if ((time() - (stat($LOG_FILENAME))[9]) <= $conf{'stoptime'}) {
237                 &error($conf{'stoptime'} . '�b�ȓ��A���������݂͋֎~�������܂��B');
238                 exit;
239         }
240         foreach $row (@LOG_FORMAT) {
241                 $wdata .= ($first != 1) ? $LOG_CUTSTR : '';
242                 $wdata .= $data{$row};
243                 $first = 0;
244         }
245         open(OUT, ">> $LOG_FILENAME");
246         eval { flock(OUT, 2); };
247         print(OUT "$wdata\n");
248         close(OUT);
249 }
250
251 sub login
252 {
253         local($message) = @_;
254         if ($conf{'password'} eq '') {
255                 $message .= '<p><strong style="color:#a00">�y�x���z</strong>�p�X���[�h���ݒ肳�����܂���onf.cgi��W���ăp�X���[�h��肵�Ă��������B�i���̂܂܃{�^������΃��O�C���͏o���܂��j</p>';
256         }
257         $html = &content_type('text/html');
258         $html .= &html_header($conf{'title'}.' �Ǘ����O�C��',$admin_style);
259         $html .= <<"EOM";
260 <h1>$conf{'title'} �Ǘ����O�C��</h1>
261 <hr>
262 <form action="$conf{'cgi'}" method="post" name="login">
263 $message
264 <p>Password:<input type="password" size="9" name="password"><input type="hidden" name="mode" value="admin"> <input type="submit" name="submit" value="���O�C��"></p>
265 </form>
266 <hr>
267 <p style="text-align:right"><a href="$conf{'cgi'}?mode=logview">logview</a> / Script made by <a href="http://www.akiyan.com/">�~�ϑ���l</a></p>
268 </body>
269 </html>
270 EOM
271         return($html);
272 }
273
274 sub admin
275 {
276         local($html, $contents, $num, $hash_grob, $wdata, $start, $nextstart);
277         if (($ACTION eq 'delete' || $ACTION eq 'revival') && $FORM{'number'} ne '') {
278                 open(OUT, "+< $LOG_FILENAME");
279                 eval { flock(OUT, 2);    };
280                 eval { truncate(OUT, 0); };
281                 eval { seek(OUT, 0, 0);  };
282                 for ($num = $#LOG_ALL ;$num >= 0; $num--) {
283                         if($LOG_ALL[$num]{'number'} eq $FORM{'number'}) {
284                                 if ($ACTION eq 'delete') {
285                                         $LOG_ALL[$num]{'status'} = 1;
286                                 } else {
287                                         $LOG_ALL[$num]{'status'} = 0;
288                                 }
289                         }
290                         $first = 1;
291                         $wdata = '';
292                         foreach $row (@LOG_FORMAT) {
293                                 $wdata .= ($first != 1) ? $LOG_CUTSTR : '';
294                                 $wdata .= $LOG_ALL[$num]{$row};
295                                 $first = 0;
296                         }
297                         print(OUT "$wdata\n");
298                 }
299                 close(OUT);
300                 &loadlog();
301         }
302         $html = &content_type('text/html');
303         $html .= &html_header($conf{'title'}.' �Ǘ�', $admin_style);
304         $contents{'message_list'} = '';
305         my $view_count = 0;
306         $start = ( $FORM{'start'} > 0 ) ? $FORM{'start'} : 0;
307         for ($num = $start; $num <= $#LOG; $num++) {
308                 $hash_grob = $LOG[$num];
309                 $contents{'message_list'} .= &replace_hash($hash_grob, "<tr><td>{number}</td><td>{name}</td><td>{text}{url_link}</td><td>{YEAR}/{mon}/{mday} {hour}:{min}</td><td>{host}�@</td></tr>");
310                 $view_count++;
311                 if ($view_count == $conf{'viewline_logview'}) {
312                         if ($num < $#LOG) {
313                                 $nextstart  = $start + $conf{'viewline_logview'};
314                                 $contents{'navi'} = <<"EOM";
315 <form action="$conf{'cgi'}" name="next" method="post">
316 <p><input type="hidden" name="mode" value="admin"><input type="hidden" name="start" value="$nextstart"><input type="hidden" name="password" value="$conf{'password'}"><input type="submit" name="submit" value="next"></p>
317 </form>
318 EOM
319                         }
320                         $num = $#LOG;
321                 }
322         }
323         $html .= <<"EOM";
324 <h1>$conf{'title'} �Ǘ�</h1>
325 <hr>
326 <table border="0" style="width:100%">
327 <thead>
328 <tr><td style="width:4ex">No.</td><td style="width:16ex">Name</td><td>Message</td><td style="width:18ex">Timestamp</td><td style="width:20ex">Host</td></tr>
329 </thead>
330 <tbody>
331 $contents{'message_list'}
332 <tbody>
333 </table>
334 $contents{'navi'}
335 <div style="margin-top:1em">
336 <form action="$conf{'cgi'}" method="post" name="ob">
337 Name:<input type="text" name="name" size="8">
338  E-Mail:<input type="text" name="email" size="12"><br>
339 Message:<br>
340 <textarea name="text" cols="40" rows="4"></textarea><br>
341 URL:<input type="text" name="url" size="20"> <input type="submit" value="write">
342 <input type="hidden" name="mode" value="write">
343 </form>
344 </div>
345 <div style="text-align:right">
346 <form action="$conf{'cgi'}" name="delete" method="post" style="display:inline;margin-left:1em">
347 <input type="hidden" name="mode" value="admin"><input type="hidden" name="action" value="delete"><input type="hidden" name="password" value="$conf{'password'}">Delete No.<input type="text" name="number" size="4"><input type="submit" name="submit" value="delete">
348 </form>
349 <form action="$conf{'cgi'}" name="revival" method="post" style="display:inline;margin-left:1em">
350 <input type="hidden" name="mode" value="admin"><input type="hidden" name="action" value="revival"><input type="hidden" name="password" value="$conf{'password'}">Revival No.<input type="text" name="number" size="4"><input type="submit" name="submit" value="Revival">
351 </form>
352 </div>
353 <hr>
354 <p style="text-align:right"><a href="$conf{'cgi'}?mode=logview">logview</a> / Script made by <a href="http://www.akiyan.com/">�~�ϑ���l</a></p>
355 </body>
356 </html>
357 EOM
358         return($html);
359 }
360
361 sub error
362 {
363         local($message) = @_;
364         local($html);
365         $html = &content_type('text/html');
366         $html .= &html_header($conf{'title'} . ' �G���[', $admin_style);
367         $html .= <<"EOM";
368 <h1>$conf{'title'} �G���[</h1>
369 <hr>
370 <p style="color:#a00">$message</p>
371 <p><a href="$conf{'return_url'}">Return</a></p>
372 <hr>
373 EOM
374         $html .= &html_futter();
375         &put($html);
376         exit;
377 }
378
379 #____�T�u���[�`���Q
380
381 ###
382 # �N�G���[������ǂݍ���
383 #
384 # @return void
385 #
386 sub get_query_string
387 {
388         local($conv) = @_;
389         local($a, $name, $value, $query_string);
390         if ($ENV{'REQUEST_METHOD'} eq "POST") {
391                 read(STDIN, $query_string, $ENV{'CONTENT_LENGTH'});
392         } else {
393                 $query_string = $ENV{'QUERY_STRING'};
394         }
395         @a = split(/\&/, $query_string);
396         foreach $a (@a) {
397                 ($name, $value) = split(/=/, $a);
398                 $value =~ tr/+/ /;
399                 $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg;
400                 if ( $conv ne "" ) {
401                         &jcode::convert(\$value,$conv);
402                 }
403                 $FORM{$name} = $value;
404         }
405 }
406
407 ###
408 # �N�b�L�[��ݍ���
409 #
410 # @return void
411 #
412 sub get_cookie {
413     local($row, $name, $value);
414     foreach $row (split(/; */, $ENV{'HTTP_COOKIE'})) {
415         ($name, $value) = split(/=/, $row);
416         $value =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/eg;
417         $COOKIE{$name} = $value;
418     }
419 }
420
421
422 ###
423 # content-type�w�b�_
424 # @param string
425 #
426 # @return string
427 #
428 sub content_type
429 {
430         if ($_content_type_printed) {
431                 return("");
432         }
433         $_content_type_printed = 1;
434         return("Content-type: $_[0]\n\n");
435 }
436
437 ###
438 # HTML�w�b�_
439 #
440 # @return string
441 #
442 sub html_header
443 {
444         local($title,$style) = @_;
445         return <<"EOM";
446 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
447 <html lang="ja">
448 <head>
449 <meta http-equiv="content-type" content="text/html; charset=shift_jis">
450 <meta http-equiv="content-style-type" content="text/css">
451 <style type="text/css">
452 $style
453 </style>
454 <title>$title</title>
455 </head>
456 <body>
457 EOM
458 }
459
460 ###
461 # HTML�t�b�^
462 #
463 # @return string
464 #
465 sub html_futter
466 {
467         return <<"EOM";
468 </body>
469 </html>
470 EOM
471 }
472
473 ###
474 # {}�Ɉ͂܂ꂽ�L�[��b�V���Œu��
475 #
476 # @param *hash �u�������[�ƒl
477 # @param string �u���Ώ�
478 #
479 # @return string �u���ς̑Ώ�
480 #
481 sub replace_hash
482 {
483         local(*hash, $body) = @_;
484         local($key, $value);
485         while ( ($key, $value) = each %hash) {
486         $body =~ s/\{$key\}/$value/g;
487         }
488         return($body);
489 }
490
491 ###
492 # �t�@�C����ݍ���z��i�[
493 # @param string �t�@�C����
494 #
495 # @return array �t�@�C����
496 #
497 sub file
498 {
499         local($filename) = @_;
500         local($row, @data);
501         if(!open(IN, "< $filename")) {
502                 print &content_type('text/html');
503                 print "file does not open '$filename'";
504                 exit;
505         }
506         eval { flock(IN, 1); };
507         @data = <IN>;
508         eval { flock(IN, 8); };
509         close(IN);
510         return(@data);
511 }
512
513 ###
514 # ����[�Ƃ��A����Ƃ��ăn�b�V�����
515 # @param *array ���O
516 # @param *array �l
517 #
518 # @return hash
519 #
520 sub format_hash
521 {
522         local(*key, *value) = @_;
523         local($num, @data);
524         for ($num = 0; $num <= $#key; $num++) {
525                 $data{$key[$num]} = $value[$num];
526         }
527         return(@data);
528 }
529
530 sub enforce_figure
531 {
532         local($string, $figure) = @_;
533         return(substr('0000000000000000' . $string, 16 + length($string) - $figure, $figure));
534 }
535
536 ###
537 # �n�b�V���̔z�����t�B�[���h�������𓾂�# @param *hash_array �n�b�V���̔z�� @param string �I����B�[���h��
538 #
539 # @return int �ő�
540 #
541 sub select_max
542 {
543         local(*data, $name) = @_;
544         local($num, $max_num) = (0, 0);
545         for ($num = 0; $num <= $#data; $num++) {
546                 $max_num = ($data[$num]{$name} > $max_num) ? $data[$num]{$name} : $max_num;
547         }
548         return $max_num;
549 }
550
551 ###
552 # ���݂̎������
553 # @param int ����
554 #
555 # @return int
556 #
557 sub gettime
558 {
559         local($timediff) = @_;
560         return(time() + $timediff);
561 }
562
563 ###
564 # ��ԎQ�Ƃɒu��
565 # @param string
566 #
567 # @return string
568 #
569 sub real_html
570 {
571         local($html) = @_;
572         $html =~ s/&/&amp\;/g;
573         $html =~ s/"/&quot\;/g;
574         $html =~ s/\</&lt\;/g;
575         $html =~ s/\>/&gt\;/g;
576         $html =~ s/\r\n/\n/g;
577         $html =~ s/\n/\<br\>/g;
578         return($html);
579 }
580
581 ###
582 # �Z�L�����e�B�΍�{�����l�ɒu��
583 # @param string
584 #
585 # @return string
586 sub secure_value
587 {
588         local($value) = @_;
589         $value =~ s/\"/&#34\;/g;
590         $value =~ s/\'/&#39\;/g;
591         $value =~ s/\@/&#64\;/g;
592         return($value);
593 }
594
595 ###
596 # �ϐ���t/html�ŏo�͂���# @param mixed
597 #
598 # @return void
599 #
600 sub var_dump
601 {
602         local($var) = @_;
603         print &content_type('text/html');
604         print $var . "\n";
605 }
606
607 ###
608 # URL�̎��������N
609 # @param string ���������N���镶���� @param string �u����������
610 # @return string a href���t����ꂽ������
611 sub auto_link {
612         local($html, $replace_word, $target) = @_;
613         if ($target ne '') {
614                 $target = " target=\"$target\"";
615         }
616         if ($replace_word ne "") {
617                 $html =~ s/([^=^\"]|^)(http\:[\w\.\~\-\/\?\&\+\=\:\@\%\;\#\%]+)/$1<a href=\"$2\" title=\"$2\"$target>$replace_word<\/a>/g;
618         } else {
619                 $html =~ s/([^=^\"]|^)(http\:[\w\.\~\-\/\?\&\+\=\:\@\%\;\#\%]+)/$1<a href=\"$2\"$target>$2<\/a>/g;
620         }
621         return($html);
622 }
623
624 ###
625 # ��X�y�[�X�ɒu��
626 # @param string
627 #
628 # @return string
629 sub nobreak
630 {
631         local($html) = @_;
632         $html =~ s/\r\n/\n/g;
633         $html =~ s/\n/ /g;
634         return($html);
635 }
Note: See TracBrowser for help on using the browser.