#!/usr/local/bin/perl
# Copyright 2002 Benjamin Trott.
# This code is released under the Artistic License.
use strict;
use lib qw(. ./ext);
use IP_Base;
my $Charset = 'euc-jp';
my $DataDir = "./tbdir";
my $RSSDir = "./rssdir";
my $tbpath = "./tb.cgi";
my $Pkey = "0628";
my $TrackbackUrl = './';
my $vDir = '.';
unshift @INC, './lib';
use vars qw( $VERSION );
$VERSION = '1.02.20040903';
use CGI qw( :standard );
eval('charset $Charset');
my $pms = param('__mode');
my $oth;
my $mode;
($mode, $oth)=split(/\?/, $pms) if( $pms );
unless ($mode) {
my $r1 = rindex($ENV{SCRIPT_NAME}, "/");
unless( substr($ENV{SCRIPT_NAME}, $r1+1) eq "tb.cgi" ){1;}else{
my $tb_id = munge_tb_id(get_tb_id());
respond_exit("No TrackBack ID (tb_id)") unless $tb_id;
my $url=delTag(param('url'));
respond_exit("No URL (url)") unless $url;
my $title=delTag(param('title'));
$title ||=$url;
my $excerpt=delTag(param('excerpt'));
my $blog_name=delTag(param('blog_name'));
my $cset=delTag(param('charset'));
my ($header, $footer, $custom, $ping_msg, $custom_admin, $lst, $blogname_max, $title_max, $excerpt_max, $mto)=get_custom();
my ($sendmail_path, $mail_address)=split(/\x02/, $mto);
require Jcode;
my $code = {
'utf-8'=>'utf8','iso-2022-jp'=>'jis','shift_jis'=>'sjis','euc-jp'=>'euc'
}->{lc($cset)} || Jcode::getcode($excerpt . $title . $blog_name);
my $dummy;
($title, $dummy)=split(/\n/, Jcode->new($title, $code)->jfold($title_max)->euc());
($excerpt, $dummy)=split(/\n/, Jcode->new($excerpt, $code)->jfold($excerpt_max)->euc());
($blog_name, $dummy)=split(/\n/, Jcode->new($blog_name, $code)->jfold($blogname_max)->euc());
my $rej=is_reject($ENV{'REMOTE_HOST'}, $ENV{'REMOTE_ADDR'}, $url);
# IPスパムフィルターでチェックします
if ( $rej ) {
## IP Spam Filter Start_!
my $uhk = IP_Base::_allow_url_domain($url,'./ipcheck');
if (IP_Base::_check_ip_base($ENV{'REMOTE_ADDR'},'./ipcheck',$uhk,'TB',$url)==0){ $rej = 0;}
## IP Spam Filter End_!
}
# 連続ひらがなが内容に含まれているかどうか確認
if ( $rej ) {
my $bbdy = $excerpt;
if ($bbdy !~ m/(\xA4[\xA1-\xF3]){2}/) { $rej = 0;}
}
if( $rej )
{
send_email($tb_id, $sendmail_path, $mail_address, $url, $rej);
add_data($tb_id, $title, $excerpt, $blog_name, $url, time,
$ENV{'REMOTE_HOST'}, $ENV{'REMOTE_ADDR'});
make_nicky_log($tb_id);
respond_exit();
}
respond_exit("Reject");
}
} elsif( $mode eq 'num' ){
my $tb_id=param('tb_id');
my $str=header()."document.write('(";
if( $tb_id ){
my @data=get_data($tb_id);
my $i=0;
for my $record(@data){
my($tb_idr, $dummy)=split(/\x01/, $record);
$i++ if( $tb_id eq $tb_idr );
}
$str .= "$i";
}else{
$str .= "no tb_id";
}
print $str, ")')\n";
} elsif ($mode eq 'red' ){
my $tb_id="20040421A";
open WD, ">./junkfile2";
print WD redirect("./nicky.cgi");
print WD "bac\n";
close WD;
# print redirect("tb.cgi" . "?__mode=list&tb_id=$tb_id");
print redirect("./nicky.cgi" . "?__mode=list&tb_id=$tb_id");
} elsif ($mode eq 'list') {
put_list();
} elsif ($mode eq 'testreject' ){
my $ip=param('ip');
my $hn=param('hn');
my $url=param('url');
print header();
print "
\n";
if( isTBadmin() ){
my $ret=is_reject($hn, $ip, $url);
if( $ret ){
print "Pass\n";
}else{
print "Reject\n";
}
}
print "\n";
} elsif ($mode eq 'delete') {
die "You are not authorized" unless isTBadmin();
my $tb_id = munge_tb_id(get_tb_id());
die("No TrackBack ID (tb_id)") unless $tb_id;
my $index = param('index') || 0;
delete_tb($tb_id, $index);
make_nicky_log($tb_id);
print redirect(url() . "?__mode=list&tb_id=$tb_id");
} elsif ($mode eq 'rss') {
my $tb_id = munge_tb_id(get_tb_id());
respond_exit("No TrackBack ID (tb_id)") unless $tb_id;
my @data=get_data($tb_id);
my @rssdat;
for my $record( @data ){
my($tb_idr, $title, $excerpt, $blog_name, $url, $time, $host, $addr)=
split(/\x01/, $record);
if( $tb_id eq $tb_idr ){
@rssdat=(@rssdat, $record);
}elsif( $tb_id =~ /alldata/ ){
@rssdat=(@rssdat, $record);
}
}
respond_exit(undef, generate_rss($tb_id, @rssdat));
} elsif ($mode eq 'send_ping') {
require Jcode;
require LWP::UserAgent;
my $ua = LWP::UserAgent->new;
$ua->agent("TrackBack/$VERSION");
my @qs = map $_ . '=' . encode_url(Jcode->new(param($_) || '', 'euc')->utf8()),qw( title excerpt blog_name );
push @qs, "url=".encode_url(param('url') || '');
push @qs, "charset=utf-8";
my $ping = param('ping_url') or ping_form_exit("No ping URL");
my $req;
if ($ping =~ /\?/) {
$req = HTTP::Request->new(GET => $ping . '&' . join('&', @qs));
} else {
$req = HTTP::Request->new(POST => $ping);
$req->content_type('application/x-www-form-urlencoded');
$req->content(join('&', @qs));
}
my $res = $ua->request($req);
ping_form_exit("HTTP error: " . $res->status_line) unless $res->is_success;
my($e, $msg) = $res->content =~ m!(\d+).*(.+?)!s;
$e ? ping_form_exit("Error: $msg") : ping_form_exit("Ping successfuly sent");
} elsif ($mode eq 'send_form') {
ping_form_exit($oth);
} elsif ($mode eq 'PassWord' ) {
&password_form();
} elsif ($mode eq 'setup_password'){
print password_done();
} elsif ($mode eq 'dummy_password' ){
print dummy_password();
} elsif ($mode eq 'custom'){
edit_tb();
} elsif ($mode eq 'write_custom'){
write_custom();
}
sub get_tb_id {
my $tb_id = param('tb_id');
unless ($tb_id) {
if (my $pi = path_info()) {
($tb_id = $pi) =~ s!^/!!;
}
}
$tb_id;
}
sub munge_tb_id {
my($id) = @_;
return '' unless $id;
$id =~ tr/a-zA-Z0-9/_/cs;
$id;
}
sub delete_tb{
my($tb_id, $index)=@_;
my @data=get_data($tb_id);
my $tb_idr;
my @ary;
my $tb_file = get_file_name($tb_id);
open FH, ">" . $tb_file;
binmode FH;
for my $item(@data){
($tb_idr, @ary)=split(/\x01/, $item);
if( $tb_id eq $tb_idr ){
print FH $item."\x02" unless( $index == $ary[4] );
}else{
print FH $item."\x02";
}
}
close FH;
}
sub is_reject{
my(@listdat)=@_;
my $ret=1;
my $dat=from_file("./reject_list.cgi");
my $line;
my @ysl;
my $ys;
$dat=~s/\r//g;
$dat=~s/\r| //g;
for $line(split(/\n/, $dat)){
@ysl=split(/\./, $line);
for $ys(@listdat){
if( substr($line, length($line)-1) eq '*' ){
if( $ys =~ /^$line/ ){
$ret=0;
last;
}
}else{
if( $ys =~ /^$line$/ ){
$ret=0;
last;
}
}
}
last if( !$ret );
}
$ret;
}
sub get_file_name{
my($tb_id)=@_;
my $y=substr($tb_id, 0, 4);
my $m=substr($tb_id, 4, 2);
"$DataDir/$y$m.cgi";
}
sub del_daytb {
my($year, $month, $day, $daysub)=@_;
my $tb_id = "$year$month$day$daysub";
my $itemid = "$year$month$day";
my $tb_file= get_file_name($tb_id);
my @data = get_data($tb_id);
my @ary;
my $tb_idr;
my $ds;
my $dsubord;
$dsubord=ord($daysub);
open FH, ">" . $tb_file;
binmode FH;
for my $item(@data){
($tb_idr, @ary)=split(/\x01/, $item);
if( $tb_idr !~ /$itemid[A-Za-z]/ ){
print FH $item."\x02";
}else{
$ds=ord(substr($tb_idr, 8));
if( $ds == $dsubord ){
}elsif( $ds < $dsubord ){
print FH $item."\x02";
}else{
print FH $itemid;
print FH sprintf("%c\x01", $ds-1);
print FH "$ds\x01";
for $ds(@ary){
print FH "$ds\x01";
}
print FH "\x02";
}
}
}
close FH;
}
sub make_nicky_log {
my($tb_id)=@_;
my $year=substr($tb_id, 0, 4);
my $month=substr($tb_id, 4, 2);
my $day=substr($tb_id, 6, 2);
my $daysub=substr($tb_id, 8, 1);
local *WD;
eval('require("./nicky.cgi")');
unless( $@ ){
ReadSetup();
initial2nd();
MakeHTMLone($year, $month, $day, $daysub, 0);
MakeLastHTMLsub();
}
}
sub get_data {
my($tb_id)=@_;
my $tb_file = get_file_name($tb_id);
my $all_dat;
if( open FH, $tb_file ){
binmode FH;
while (){
$all_dat.=$_;
} close FH;
}
split(/\x02/, $all_dat);
}
sub add_data {
my($tb_idr, $title, $excerpt, $blog_name, $url, $time, $host, $addr)=@_;
my $tb_id=$_[0];
my $tb_file = get_file_name($tb_id);
open FH, ">>$tb_file";
binmode FH;
print FH "$tb_idr\x01$title\x01$excerpt\x01$blog_name\x01$url\x01$time\x01$host\x01$addr\x02";
close FH;
}
sub generate_rss {
my($tb_id, @data) = @_;
my $rss = qq(TB: $tb_id\n);
# my $max = $limit ? $limit - 1 : $#$data;
# for my $i (@{$data}[0..$max]) {
# $rss .= sprintf "- %s%s%s
\n", xml('title', $i->{title}),
# xml('link', $i->{url}), xml('description', $i->{excerpt}) if $i;
# }
my $max = 50;
for my $record (@data[0..$max]) {
my($tb_idr, $title, $excerpt, $blog_name, $url, $time, $host, $addr)=
split(/\x01/, $record);
$rss .= sprintf "- %s%s%s
\n", xml('title', $title),
xml('link', $url), xml('description', $excerpt) if $record;
}
$rss . qq();
}
sub put_list {
my $tb_id = munge_tb_id(get_tb_id());
my ($header, $footer, $custom, $ping_msg, $custom_admin, $lst)=get_custom();
die("No TrackBack ID (tb_id)") unless $tb_id;
my $url_me = url();
my @week_str=('(Sun)','(Mon)','(Tue)','(Wed)','(Thu)','(Fri)','(Sat)');
my $url_nicky=$url_me;
$url_nicky=~s/tb.cgi/nicky.cgi/;
$url_nicky="$url_nicky?DT=$tb_id#$tb_id";
my($title, $msgall)=get_nicky_file($tb_id);
my($msg, $dummy)=split(/
|
/, $msgall);
$msg=delTag($msg);
$title=delTag($title);
$dummy=from_file("./tb_admin.cgi");
my($dummy1, $page_title)=split(/\n/, $dummy);
$ping_msg=~s/\$url_ping/$url_me\/$tb_id/g;
$ping_msg=~s/\$tb_id/$tb_id/g;
$ping_msg=~s/\$url_nicky/$url_nicky/g;
$ping_msg=~s/\$title/$title/g;
$ping_msg=~s/\$msg/$msg/g;
$header=~s/\$url_ping/$url_me\/$tb_id/g;
print header(-charset => $Charset), $header, $ping_msg;
my @data = get_data($tb_id);
my $i = 0;
my $logged_in = isTBadmin();
my $cstr;
my $templ;
@data=reverse(@data) if( $lst eq "new" );
for my $record (@data) {
my($tb_idr, $title, $excerpt, $blog_name, $url, $ltime, $host, $addr)=split(/\x01/, $record);
if( $tb_idr eq $tb_id ){
my($csec,$cmin,$chour,$cday,$cmon,$cyear,$cwday,$cyday,$cisdst)=
localtime $ltime;
my $ts=sprintf("%04d/%02d/%02d%s %02d:%02d", $cyear+1900, $cmon+1, $cday, @week_str[($cwday%7)], $chour, $cmin);
$templ=$custom;
$templ=~s/\$url/$url/g;
$templ=~s/\$tb_title/$title/g;
$blog_name ||= "[No blog name]";
$templ=~s/\$blog_name/$blog_name/g;
$excerpt ||= "[No excerpt]";
$templ=~s/\$excerpt/$excerpt/g;
$templ=~s/\$time/$ts/g;
$cstr=$logged_in ? qq([DELETE]) : '';
$templ=~s/\$delete/$cstr/g;
print $templ;
$i++;
}
}
if( isTBadmin() ){
$page_title=~s/\n|\r|\t//g;
while( $page_title=~s/ $// ){}
$custom_admin=~s/\$msg/$msg/g;
$custom_admin=~s/\$title/$title/g;
$custom_admin=~s/\$page_title/$page_title/g;
$custom_admin=~s/\$url_nicky/$url_nicky/g;
print $custom_admin;
}
$footer=~s/\$url_ping/$url_me\/$tb_id/g;
print $footer;
}
sub send_email {
my($tb_id, $sendmail_path, $mail_address, $url, $rej)=@_;
my($subject)="=?ISO-2022-JP?B?GyRCJUglaSVDJS8lUCVDJS9ETENOGyhC?=";
if( $sendmail_path && $mail_address ){
open(FH, "|$sendmail_path -t -Fnicky");
binmode FH;
print FH "To: $mail_address\n";
print FH "Subject: $subject\n";
print FH "Content-Type: text/plain; charset=ISO-2022-JP\n";
print FH "Content-Transfer-Encoding: 7bit\n";
print FH "\n";
print FH "from : $ENV{REMOTE_HOST}($ENV{REMOTE_ADDR})\n";
print FH " $url\n";
print FH "agent : $ENV{HTTP_USER_AGENT}\n\n";
print FH "http://$ENV{HTTP_HOST}$ENV{SCRIPT_NAME}\?tb_id=$tb_id&__mode=list\n\n";
if( !$rej ){
print FH "REJECT\n\n";
}
close FH;
}
}
sub respond_exit {
print "Content-Type: text/xml; charset=EUC-JP\n\n";
print qq(\n\n);
if ($_[0]) {
printf qq(1\n%s\n), xml('message', $_[0]);
} else {
print qq(0\n) . ($_[1] ? $_[1] : '');
}
print "\n";
exit;
}
sub ping_form_exit {
my($oth) = @_;
my($subp, $subv)=split(/=/, $oth);
my $ping_url_str;
my $ping_url_for_blog;
my($header,$footer,$custom,$ping_msg,$custom_admin, $lst)=get_custom();
print header(), $header;
unless( $oth ){
print $footer;
exit;
}elsif( $subp eq "ping_url" ){
$ping_url_str="";
$ping_url_for_blog="この記事へのTrackBack先URL";
}elsif( $oth =~ /successfuly/ ){
print "";
if( isTBadmin() ){
print "送信しました\n";
}else{
print "ありがとうございました。\n";
}
print "";
print " |