#!/usr/bin/perl
#-------------------------------------------------------------------------------
# unico diary system v2.0.1
# (旧 PINKGUN DIARY から改称)
# 19980413 first. 20010725 modified
# script by az* http://www.azworks.org/~az/
#-------------------------------------------------------------------------------
# 一行目の Perl のパスと必須設定を書き換えて、
# 適切なパーミッションを設定すればとりあえず動きます。
# 詳しい設置方法はマニュアル(配布アーカイブに同梱)をご覧ください。
#-------------------------------------------------------------------------------
# 必須設定。
#-------------------------------------------------------------------------------
$logfile = './u_diary.dat'; # ログ保存ファイル
$template = './template.html'; # 表示用テンプレートファイル
$script = './u_diary.cgi'; # このスクリプトのファイル名
$css = './unico.css'; # 管理画面等用CSSファイル
$jcode = './jcode.pl'; # jcode.plの場所
$password = '840818'; # 管理者モードパスワード *必ず変更する!!
#-------------------------------------------------------------------------------
# 各種カスタマイズ項目
#-------------------------------------------------------------------------------
$d_max = 10; # デフォルト表示件数
$max = 50; # 最大記録件数
$link = 'on'; # オートリンク機能のon/off
$target = ' target="_blank"'; # オートリンク時のターゲット属性
$link_max = 40; # オートリンク時の見かけのURLの長さ制限
$w_reg = 'off'; # 二重書きこみ防止機能のon/off
#-------------------------------------------------------------------------------
# 日付時刻
#-------------------------------------------------------------------------------
# 日付表示フォーマット(運用中でも変更が反映されます)
$date ='%y.%m.%d';
# 詳細はマニュアル参照。
# 以前の設定はこうなります
# en xxxx/xx/xx xx:xx:xx => $date ='%Y/%m/%d %H:%I:%S';
# en2 xxxx/xx/xx => $date ='%Y/%m/%d';
# jp xxxx年xx月xx日 xx時xx分xx秒 => $date ='%Y年%m月%d日 %H時%I分%S秒';
# jp2 xxxx年xx月xx日 => $date ='%Y年%m月%d日';
# pp xx月 xxにち (ポスぺ風)=> $date ='%m月 %dにち';
@month = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); # 月のテキスト形式指定
@week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); # 曜日のテキスト形式指定
@m = ('am','pm'); # 午前/午後
#-------------------------------------------------------------------------------
# セキュリティ関連
#-------------------------------------------------------------------------------
@tag = ('b','font','img','a'); # 有効タグ。「'」でくくり「,」で区切る。<,>は不要。
$style = 'off'; # タグのstyle,class,id属性を有効にするとき on。
$jscript = 'off'; # タグのJAVAスクリプト属性(onClickとか)を有効にするとき on。
$max_length = 8192; # 最大入力バイト数。0だと無制限。
#-------------------------------------------------------------------------------
# そのほか
#-------------------------------------------------------------------------------
$method = 'post'; # FORMのMETHOD属性を指定(通常はPOST)
$form_html = './form.txt'; # 拡張フォーム設定ファイル
$tz = 9; # 海外サーバなど時刻がずれる時のみ変更してください
# 設定ここまで------------------------------------------------------------------
# ファイルチェック
open(LOG,$logfile) || &error("$logfileが open できません。");
@lines = 管理者専用モード。記事の新規書きこみ・修正・削除が実行できます。 \n";
$body .= <
二重書きこみは禁止されています。') ;
}
}
$value = join("<>",%form);
unshift (@data, "$value\n");
@data = splice(@data,0,$max);
$log_lines = $#data; # 行数読みなおし
truncate(LOG, 0); # ファイルの古い内容をクリア
seek(LOG, 0, 0); # 書き込み位置を先頭に戻す
print LOG @data; # 値を書き込む
close(LOG); # ファイルを閉じる
if($imode){&imode;
}else{&log;}
}
# ログ表示
sub log{
$page{max} = $max;
$page{script} = $script;
$page{method} = $method;
if(($form{start} =~ \D) or ($form{start} < 1)){
$page{start} = 1 ;
}else{ $page{start} = $form{start}; }
if(($form{d_max} =~ \D) or (!$form{d_max})){
$page{d_max} = $d_max ;
$form{d_max} = $page{d_max};
}else{ $page{d_max} = $form{d_max}; }
# NEXTのURL
if ($page{'start'} > 1){
$page{'next'} = "$script";
if($page{'start'}-$d_max > 0){
$page{'next'} .= "?start=" . ($page{'start'}-$d_max);
}
}
# PREVのURL
if($page{'start'} + $d_max <= $log_lines +1){
$page{'prev'} = "$script?start=";
$page{'prev'} .= $page{'start'}+$d_max;
}
print "Content-type: text/html\n";
print "Pragma: no-cache\n\n";
# テンプレート読みこみ
$. = 0; # 行数初期化
open(IN,$template);
$locate = \@header;
while(
';
$. = 0; # 行数初期化
open(LOG,$logfile);
while(
/\n/g;
$log{note} =~ s/</g;
$log{note} =~ s/>/>/g;
$body .= "\n";
$body .= "
\n";
$body .= "日時 $log{date} \n";
delete $log{note};
delete $log{date};
delete $log{Write_Time};
delete $log{ip};
foreach (keys %log){
$body .= "内容 \n";
$body .= " \n";
}
$body .= "$_ \n";
$body .= "
END
last unless(-- $form{d_max});
}
close(LOG);
$body .= <
HTML
&print_html($title,$body);
}
# 携帯からの書き込みフォーム
sub imode_form{
if($jsky){$method = 'get';}
print "Content-type: text/html\n";
print "Pragma: no-cache\n\n";
print <
$form{date}
$form{note} ....
END
exit;
}
# HTML出力
sub print_html{
($title, $body) = @_;
print "Content-type: text/html\n";
print "Pragma: no-cache\n\n";
print <$title
$body
END
exit;
}
# 書き込み内容の変換
sub change{
my ( $msg, $new, @tmp, $tmp, @options, $options, @text, $text,);
$msg = $_[0];
#改行処理
$msg =~ s/\r\n/\n/g;
$msg =~ s/\r/\n/g;
$/ = ''; chomp $msg; $/ = "\n"; # 行末の空行を除去
$msg =~ s/\n/
/g;
# タグ処理
($new,@tmp) = split(/</,$msg);
$new = &autolink($new);
foreach $tmp (@tmp){
# >がなければタグじゃないとみなしてテキスト処理
if($tmp !~ />/){$tmp = &autolink('<' . $tmp); next;}
($options,@text) = split(/>/,$tmp);
$text = &autolink(join('>',@text)); # >より右はテキスト処理
($tag,@options) = split(/\s|
/i,$options); # タグとオプションを分割
# 許可タグ
if(grep(/^$tag$/i,@tag)){
# JavaScript, stylesheet 関連オプションを削除
foreach(@options){
if($style ne 'on'){
if($_ =~ /^(style|class)/i){$_ = '';}
if($jscript ne 'on'){ if($_ =~ /^id/i){$_ = '';}}
}
if($jscript ne 'on'){ if($_ =~ /^on/i){$_ = '';}}
}
$tmp = '<' . join(' ',$tag,@options) . '>' . $text;
# 閉じタグ
}elsif($tag =~ m!^/!){
$tag =~ s!^/!!;
if(grep(/^$tag$/i,@tag)){ # 許可
$tmp = '' . $tag . '>' . $text;
}else{ $tmp = '</' . &autolink($tag) . '>' . $text;} # 禁止閉じタグ
# 禁止タグ
}else{ $tmp = '<' . &autolink(join(' ',$tag,@options)) . '>' . $text;}
}
$new .= join('',@tmp);
# タグ処理ここまで
return $new;
}
# テキスト部の処理(オートリンク)
sub autolink{
if($link ne 'on'){return $_[0];}
# URLのマッチングは「Perlメモ」http://www.din.or.jp/~ohzaki/perl.htm を参考にさせていただきました。
# …というかそのまんまです。ありがとうございました!!
$_[0] =~ s/(s?https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/&url($1)/gie;
$_[0] =~ s/([\w\.\-]+)\@([\w\.\-]+)/$1\@$2<\/A>/ig;
return $_[0];
}
sub url{
$short = substr($_[0],0,$link_max);
return qq|$short...<\/A>|;
}
# 日付表示
sub date{
$log_date = $_[0];
($sec, $min, $hour, $mday, $mon, $year, $w) = gmtime($log_date + $tz*60*60);
$log_date = $date;
$log_date =~ s/%Y/$year + 1900/ge;
$log_date =~ s/%y/substr($year + 1900,-2)/eg;
$log_date =~ s/%M/$month[$mon]/g;
$log_date =~ s/%m/sprintf("%02d",$mon + 1)/eg;
$log_date =~ s/%n/$mon + 1/g;
$log_date =~ s/%d/sprintf("%02d",$mday)/eg;
$log_date =~ s/%j/$mday/g;
$log_date =~ s/%D/$week[$w]/g;
if($hour >= 12){ $hhour = $hour-12; $m = 1;}else{$hhour = $hour;}
$log_date =~ s/%h/sprintf("%02d",$hhour)/eg;
$log_date =~ s/%H/sprintf("%02d",$hour)/eg;
$log_date =~ s/%g/$hhour/g;
$log_date =~ s/%G/$hour/g;
$log_date =~ s/%a/$m[$m]/g;
$log_date =~ s/%I/sprintf("%02d",$min)/eg;
$log_date =~ s/%i/$min/g;
$log_date =~ s/%S/sprintf("%02d",$sec)/eg;
$log_date =~ s/%s/$sec/g;
return $log_date;
}
sub readform{
if ($ENV{'REQUEST_METHOD'} eq "POST") {
if(($ENV{'CONTENT_LENGTH'} > $max_length)and($max_length)){ &error("入力文字数が多すぎます。");}
read(STDIN, $formdata, $ENV{'CONTENT_LENGTH'});
} else {
if(($ENV{'QUERY_STRING'} > $max_length)and($max_length)){ &error("入力文字数が多すぎます。");}
$formdata = $ENV{'QUERY_STRING'};
}
@pears = split(/&|;/,$formdata);
foreach (@pears) {
($name,$value) = split(/=/,$_);
$value =~ tr/+/ /;
$value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg;
$name =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg;
$value =~ s/</g;
$value =~ s/>/>/g;
$form{$name} = $value;
}
if($ENV{HTTP_USER_AGENT} =~ /^DoCoMo/){
$imode = 1;
}elsif($ENV{HTTP_USER_AGENT} =~ /^J-PHONE/){
$imode = 1; $jsky=1;
}
}
sub code_conv{
require $jcode;
while (($key, $value) = each(%form)) {
#絵文字除去コードは「CGIぽん」サマ(http://specters.net/cgipon/)を参考にさせていただきました。
if($imode){
if($jsky){$value =~ s/\x1B\$(?:..)+\x0F//g; # j-sky絵文字除去
}else{
my $sjis = '[\x80-\x9F\xE0-\xF7\xFA-\xFC][\x40-\xFF]|[\x00-\x7F]';
my $emoji_i = '[\xF8\xF9][\x40-\x7E\x80-\xAF]';
$value =~ s/\G((?:$sjis)*?)(?:$emoji_i)/$1/go;
# i-mode絵文字除去
}
&jcode'h2z_sjis(*value);
}else{ &jcode'convert(*value,'sjis');}
$form{$key} = $value;
}
}
sub no_pass{
$title = 'unico [management]';
$body = <