summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfukachan <fukachan>2002-12-18 04:22:36 +0000
committerfukachan <fukachan>2002-12-18 04:22:36 +0000
commit30e7da25a6dbee537d5a17071d24081570e15317 (patch)
tree0e1c0422c878eef9cc5d9114013dbbd41f669d6d
parent1e832a14f7feb5790042335e53bb9717df8e17ed (diff)
downloadfml8-30e7da25a6dbee537d5a17071d24081570e15317.tar.gz
fml8-30e7da25a6dbee537d5a17071d24081570e15317.tar.bz2
fml8-30e7da25a6dbee537d5a17071d24081570e15317.zip
clean up comments and messages
-rw-r--r--fml/lib/FML/Command/User/chaddr.pm20
-rw-r--r--fml/lib/FML/Command/User/confirm.pm18
-rw-r--r--fml/lib/FML/Command/User/get.pm5
-rw-r--r--fml/lib/FML/Command/User/off.pm19
-rw-r--r--fml/lib/FML/Command/User/on.pm18
-rw-r--r--fml/lib/FML/Command/User/send.pm6
-rw-r--r--fml/lib/FML/Command/User/subscribe.pm8
-rw-r--r--fml/lib/FML/Command/User/unsubscribe.pm11
-rw-r--r--fml/lib/FML/Error/Analyze.pm48
-rw-r--r--fml/lib/FML/Error/Cache.pm51
10 files changed, 133 insertions, 71 deletions
diff --git a/fml/lib/FML/Command/User/chaddr.pm b/fml/lib/FML/Command/User/chaddr.pm
index 25f6175f..cd4faca9 100644
--- a/fml/lib/FML/Command/User/chaddr.pm
+++ b/fml/lib/FML/Command/User/chaddr.pm
@@ -4,7 +4,7 @@
# All rights reserved. This program is free software; you can
# redistribute it and/or modify it under the same terms as Perl itself.
#
-# $FML: chaddr.pm,v 1.13 2002/09/11 23:18:09 fukachan Exp $
+# $FML: chaddr.pm,v 1.14 2002/09/22 14:56:47 fukachan Exp $
#
package FML::Command::User::chaddr;
@@ -16,7 +16,7 @@ use FML::Log qw(Log LogWarn LogError);
=head1 NAME
-FML::Command::User::chaddr - change subscriber address
+FML::Command::User::chaddr - change subscribed address
=head1 SYNOPSIS
@@ -24,15 +24,16 @@ See C<FML::Command> for more details.
=head1 DESCRIPTION
-Firstly apply confirmation before chaddr (change subscriber address).
-After confirmation succeeds, chaddr process proceeds.
+Firstly, apply confirmation before chaddr (change subscribed address)
+processed. After confirmation succeeds, chaddr process proceeds.
=head1 METHODS
=head2 C<process($curproc, $command_args)>
-if either old or new addresses in chaddr arguments is an ML member,
-try to confirm this request irrespective of "From:" address.
+If either old or new addresses in chaddr arguments is an ML member,
+try to confirm this request. The confirmation is returned to "From:"
+address in the mail header, "reply-to" is not used.
=cut
@@ -66,6 +67,10 @@ sub process
{
my ($self, $curproc, $command_args) = @_;
my $config = $curproc->{ config };
+
+ #
+ # XXX-TODO: correct to use *_maps not primary_*_map for chaddr?
+ #
my $member_map = $config->{ primary_member_map };
my $recipient_map = $config->{ primary_recipient_map };
my $cache_dir = $config->{ db_dir };
@@ -94,9 +99,12 @@ sub process
# if either old or new addresses in chaddr arguments is an ML member,
# try to confirm this request irrespective of "From:" address.
+ # 1. request from $old_addr : $old_addr (member now) -> $new_addr
+ # 2. request from $new_addr : $old_addr -> $new_addr (member now)
if ($cred->is_member($old_addr) || $cred->is_member($new_addr)) {
Log("chaddr request, try confirmation");
+ # XXX-TODO: should be FML::Confirm { ... address => [ @addr ] } ?
use FML::Confirm;
my $confirm = new FML::Confirm {
keyword => $keyword,
diff --git a/fml/lib/FML/Command/User/confirm.pm b/fml/lib/FML/Command/User/confirm.pm
index b7cbb4c3..9b495937 100644
--- a/fml/lib/FML/Command/User/confirm.pm
+++ b/fml/lib/FML/Command/User/confirm.pm
@@ -4,7 +4,7 @@
# All rights reserved. This program is free software; you can
# redistribute it and/or modify it under the same terms as Perl itself.
#
-# $FML: confirm.pm,v 1.16 2002/09/11 23:18:09 fukachan Exp $
+# $FML: confirm.pm,v 1.17 2002/09/22 14:56:47 fukachan Exp $
#
package FML::Command::User::confirm;
@@ -75,6 +75,8 @@ sub process
{
my ($self, $curproc, $command_args) = @_;
my $config = $curproc->{ config };
+
+ # XXX-TODO: correct we handle only primary_*_map here?
my $member_map = $config->{ primary_member_map };
my $recipient_map = $config->{ primary_recipient_map };
my $cache_dir = $config->{ db_dir };
@@ -88,6 +90,7 @@ sub process
# "confirm subscribe 813f42fa2aa84bbba500ed3d2781dea6"
# XXX $keyword not starts at the begining of this line.
# XXX for example, "confirm", "> confirm" and "xxx> confirm ..."
+ # XXX-TODO: we should move this check to FML::Command::__SOME_WHERE_ ?
if ($command =~ /$keyword\s+(\w+)\s+([\w\d]+)/) {
($class, $id) = ($1, $2);
}
@@ -106,12 +109,13 @@ sub process
my $address = $confirm->get_address($id);
$self->_switch_command($class, $address, $curproc, $command_args);
}
- else { # if req is expired
+ else { # if requset is expired
$curproc->reply_message_nl('error.expired', "request expired");
LogError("request expired");
croak("request is expired");
}
}
+ # request corresponding to thie confirmation reply is not found
else {
$curproc->reply_message_nl('error.no_such_confirmation',
"no such confirmatoin request id=$id",
@@ -139,6 +143,7 @@ sub _switch_command
use FML::Command;
my $obj = new FML::Command;
+ # XXX-TODO: command names which need confirmation are hard-coded.
if ($class eq 'subscribe' ||
$class eq 'unsubscribe' ||
$class eq 'chaddr' ||
@@ -157,15 +162,16 @@ sub _switch_command
croak("no such rule");
}
- # XXX temporary, please clean up in near future
+ # XXX-TODO: send back welcome file.
+ # XXX-TODO: temporary solution, please clean up in near future!
if ($class eq 'subscribe') {
use File::Spec;
use FML::Command::SendFile;
- push(@ISA, qw(FML::Command::SendFile));
+ push(@ISA, qw(FML::Command::SendFile));
- my $config = $curproc->config();
+ my $config = $curproc->config();
my $ml_home_dir = $config->{ ml_home_dir };
- my $file = File::Spec->catfile($ml_home_dir, "welcome");
+ my $file = File::Spec->catfile($ml_home_dir, "welcome");
$config->set( 'welcome_file', $file );
if (-f $file) {
diff --git a/fml/lib/FML/Command/User/get.pm b/fml/lib/FML/Command/User/get.pm
index af11a550..6c5e5a93 100644
--- a/fml/lib/FML/Command/User/get.pm
+++ b/fml/lib/FML/Command/User/get.pm
@@ -4,7 +4,7 @@
# All rights reserved. This program is free software; you can
# redistribute it and/or modify it under the same terms as Perl itself.
#
-# $FML: get.pm,v 1.12 2002/09/11 23:18:09 fukachan Exp $
+# $FML: get.pm,v 1.13 2002/09/22 14:56:47 fukachan Exp $
#
package FML::Command::User::get;
@@ -67,6 +67,9 @@ sub need_lock { 1;}
sub process
{
my ($self, $curproc, $command_args) = @_;
+
+ # XXX-TODO: call send_article() without checking here
+ # XXX-TODO: though checked in FML::Process::Command already.
$self->send_article($curproc, $command_args);
}
diff --git a/fml/lib/FML/Command/User/off.pm b/fml/lib/FML/Command/User/off.pm
index 164d81a3..e028aeb4 100644
--- a/fml/lib/FML/Command/User/off.pm
+++ b/fml/lib/FML/Command/User/off.pm
@@ -4,7 +4,7 @@
# All rights reserved. This program is free software; you can
# redistribute it and/or modify it under the same terms as Perl itself.
#
-# $FML: off.pm,v 1.3 2002/09/11 23:18:10 fukachan Exp $
+# $FML: off.pm,v 1.4 2002/09/22 14:56:47 fukachan Exp $
#
package FML::Command::User::off;
@@ -16,7 +16,7 @@ use FML::Log qw(Log LogWarn LogError);
=head1 NAME
-FML::Command::User::off - change off mode
+FML::Command::User::off - change delivery mode from real time to digest.
=head1 SYNOPSIS
@@ -24,8 +24,8 @@ See C<FML::Command> for more details.
=head1 DESCRIPTION
-Firstly apply confirmation before off.
-After confirmation succeeds, off process proceeds.
+change delivery mode from real time to digest
+after confirmation succeeds.
=head1 METHODS
@@ -54,7 +54,8 @@ sub new
sub need_lock { 1;}
-# Descriptions: off adapter: confirm before off
+# Descriptions: change delivery mode from real time to digest
+# after confirmation succeeds.
# Arguments: OBJ($self) OBJ($curproc) HASH_REF($command_args)
# Side Effects: update database for confirmation.
# prepare reply message.
@@ -63,6 +64,10 @@ sub process
{
my ($self, $curproc, $command_args) = @_;
my $config = $curproc->{ config };
+
+ #
+ # XXX-TODO: correct to use primary_*_map for on/off ?
+ #
my $member_map = $config->{ primary_member_map };
my $recipient_map = $config->{ primary_recipient_map };
my $cache_dir = $config->{ db_dir };
@@ -81,7 +86,7 @@ sub process
unless ($cred->is_member($address)) {
$curproc->reply_message_nl('error.not_member');
LogError("off request from not member");
- croak("not member");
+ croak("off request from not member");
return;
}
@@ -89,7 +94,7 @@ sub process
unless ($cred->is_recipient($address)) {
$curproc->reply_message_nl('error.not_recipient');
LogError("off request from not recipient");
- croak("not recipient");
+ croak("off request from not recipient");
}
# try confirmation before off
else {
diff --git a/fml/lib/FML/Command/User/on.pm b/fml/lib/FML/Command/User/on.pm
index 28bcaf23..dc26325c 100644
--- a/fml/lib/FML/Command/User/on.pm
+++ b/fml/lib/FML/Command/User/on.pm
@@ -4,7 +4,7 @@
# All rights reserved. This program is free software; you can
# redistribute it and/or modify it under the same terms as Perl itself.
#
-# $FML: on.pm,v 1.3 2002/09/11 23:18:10 fukachan Exp $
+# $FML: on.pm,v 1.4 2002/09/22 14:56:48 fukachan Exp $
#
package FML::Command::User::on;
@@ -16,7 +16,7 @@ use FML::Log qw(Log LogWarn LogError);
=head1 NAME
-FML::Command::User::on - on
+FML::Command::User::on - change delivery mode from digest to real time.
=head1 SYNOPSIS
@@ -24,7 +24,7 @@ See C<FML::Command> for more details.
=head1 DESCRIPTION
-Firstly apply confirmation before on.
+"on" command changes delivery mode from digest to real time.
After confirmation succeeds, on process proceeds.
=head1 METHODS
@@ -54,8 +54,8 @@ sub new
sub need_lock { 1;}
-# Descriptions: on adapter.
-# we confirm it before real on process.
+# Descriptions: change delivery mode from digest to real time
+# after confirmation.
# Arguments: OBJ($self) OBJ($curproc) HASH_REF($command_args)
# Side Effects: update database for confirmation.
# prepare reply message.
@@ -64,6 +64,10 @@ sub process
{
my ($self, $curproc, $command_args) = @_;
my $config = $curproc->{ config };
+
+ #
+ # XXX-TODO: correct to use primary_*_map for on/off ?
+ #
my $member_map = $config->{ primary_member_map };
my $recipient_map = $config->{ primary_recipient_map };
my $cache_dir = $config->{ db_dir };
@@ -82,7 +86,7 @@ sub process
unless ($cred->is_member($address)) {
$curproc->reply_message_nl('error.not_member');
LogError("on request from not member");
- croak("not member");
+ croak("on request from not member");
return;
}
@@ -97,7 +101,7 @@ sub process
}
# if not, try confirmation before on
else {
- Log("change on mode, try confirmation");
+ Log("on request, try confirmation");
use FML::Confirm;
my $confirm = new FML::Confirm {
keyword => $keyword,
diff --git a/fml/lib/FML/Command/User/send.pm b/fml/lib/FML/Command/User/send.pm
index d18b19ae..3c6a981f 100644
--- a/fml/lib/FML/Command/User/send.pm
+++ b/fml/lib/FML/Command/User/send.pm
@@ -4,7 +4,7 @@
# All rights reserved. This program is free software; you can
# redistribute it and/or modify it under the same terms as Perl itself.
#
-# $FML: send.pm,v 1.9 2002/09/11 23:18:10 fukachan Exp $
+# $FML: send.pm,v 1.10 2002/09/22 14:56:48 fukachan Exp $
#
package FML::Command::User::send;
@@ -16,7 +16,7 @@ use FML::Command::User::get;
@ISA = qw(FML::Command::User::get);
-# Descriptions: send articles
+# Descriptions: send back articles
# Arguments: OBJ($self) OBJ($curproc) HASH_REF($command_args)
# Side Effects: forward request to get module
# Return Value: none
@@ -29,7 +29,7 @@ sub process
=head1 NAME
-FML::Command::User::send - send artciles
+FML::Command::User::send - send back artciles
=head1 SYNOPSIS
diff --git a/fml/lib/FML/Command/User/subscribe.pm b/fml/lib/FML/Command/User/subscribe.pm
index c29aa68b..7f17ff36 100644
--- a/fml/lib/FML/Command/User/subscribe.pm
+++ b/fml/lib/FML/Command/User/subscribe.pm
@@ -4,7 +4,7 @@
# All rights reserved. This program is free software; you can
# redistribute it and/or modify it under the same terms as Perl itself.
#
-# $FML: subscribe.pm,v 1.14 2002/09/11 23:18:10 fukachan Exp $
+# $FML: subscribe.pm,v 1.15 2002/09/22 14:56:48 fukachan Exp $
#
package FML::Command::User::subscribe;
@@ -16,7 +16,7 @@ use FML::Log qw(Log LogWarn LogError);
=head1 NAME
-FML::Command::User::subscribe - subscribe
+FML::Command::User::subscribe - subscribe request handling
=head1 SYNOPSIS
@@ -24,7 +24,7 @@ See C<FML::Command> for more details.
=head1 DESCRIPTION
-Firstly apply confirmation before subscribe.
+Firstly apply confirmation before real subscribe process starts.
After confirmation succeeds, subcribe process proceeds.
=head1 METHODS
@@ -64,6 +64,8 @@ sub process
{
my ($self, $curproc, $command_args) = @_;
my $config = $curproc->{ config };
+
+ # XXX we handle primary_* . o.k.
my $member_map = $config->{ primary_member_map };
my $recipient_map = $config->{ primary_recipient_map };
my $cache_dir = $config->{ db_dir };
diff --git a/fml/lib/FML/Command/User/unsubscribe.pm b/fml/lib/FML/Command/User/unsubscribe.pm
index 3d9f23f0..e3f0e195 100644
--- a/fml/lib/FML/Command/User/unsubscribe.pm
+++ b/fml/lib/FML/Command/User/unsubscribe.pm
@@ -4,7 +4,7 @@
# All rights reserved. This program is free software; you can
# redistribute it and/or modify it under the same terms as Perl itself.
#
-# $FML: unsubscribe.pm,v 1.14 2002/09/11 23:18:11 fukachan Exp $
+# $FML: unsubscribe.pm,v 1.15 2002/09/22 14:56:48 fukachan Exp $
#
package FML::Command::User::unsubscribe;
@@ -16,7 +16,7 @@ use FML::Log qw(Log LogWarn LogError);
=head1 NAME
-FML::Command::User::unsubscribe - unsubscribe member
+FML::Command::User::unsubscribe - unsubscribe request handling
=head1 SYNOPSIS
@@ -24,7 +24,7 @@ See C<FML::Command> for more details.
=head1 DESCRIPTION
-Firstly apply confirmation before unsubscribe.
+Firstly apply confirmation before the real unsubscribe process.
After confirmation succeeds, unsubcribe process proceeds.
=head1 METHODS
@@ -63,6 +63,9 @@ sub process
{
my ($self, $curproc, $command_args) = @_;
my $config = $curproc->{ config };
+
+ # XXX-TODO: wrong to handle only primary_*_map in deluser phase.
+ # XXX-TODO: we should check all maps?
my $member_map = $config->{ primary_member_map };
my $recipient_map = $config->{ primary_recipient_map };
my $cache_dir = $config->{ db_dir };
@@ -81,7 +84,7 @@ sub process
unless ($cred->is_member($address)) {
$curproc->reply_message_nl('error.not_member');
LogError("unsubscribe request from not member");
- croak("not member");
+ croak("unsubscribe request from not member");
}
# try confirmation before unsubscribe
else {
diff --git a/fml/lib/FML/Error/Analyze.pm b/fml/lib/FML/Error/Analyze.pm
index 25cc348a..76a00b1f 100644
--- a/fml/lib/FML/Error/Analyze.pm
+++ b/fml/lib/FML/Error/Analyze.pm
@@ -4,7 +4,7 @@
# All rights reserved. This program is free software; you can
# redistribute it and/or modify it under the same terms as Perl itself.
#
-# $FML: Analyze.pm,v 1.8 2002/10/20 13:33:31 fukachan Exp $
+# $FML: Analyze.pm,v 1.9 2002/12/12 04:57:53 fukachan Exp $
#
package FML::Error::Analyze;
@@ -19,7 +19,7 @@ my $debug = 1;
=head1 NAME
-FML::Error::Analyze - analyzer routine for error cache
+FML::Error::Analyze - provide model specific analyzer routines.
=head1 SYNOPSIS
@@ -47,19 +47,25 @@ sub new
=head2 $data STRUCTURE
-C<$data> is passed to error analyer function.
+C<$data> is passed to the error analyer function.
$data = {
address => [
- error_string_1,
- error_string_2, ...
+ error_info_1,
+ error_info_2, ...
]
};
+where the error_info_* has error reasons.
+
+=head1 METHODS
+
+=head2 simple_count()
+
=cut
-# Descriptions: count up the nunber of errors
+# Descriptions: count up the number of errors.
# Arguments: OBJ($self) OBJ($curproc) HASH_REF($data)
# Side Effects: none
# Return Value: ARRAY_REF
@@ -74,6 +80,8 @@ sub simple_count
while (($addr, $bufarray) = each %$data) {
$count = 0;
+
+ # count up the number of error messsages if the status is 5XX.
if (defined $bufarray) {
for my $buf (@$bufarray) {
if ($buf =~ /status=5/i) {
@@ -83,6 +91,7 @@ sub simple_count
}
}
+ # add address to the removal list if the count is over $limit.
if ($count > $limit) {
push(@removelist, $addr);
}
@@ -90,7 +99,7 @@ sub simple_count
# debug info
if ($debug) {
- Log("analyze summary");
+ Log("error: simple_count analyzer summary");
my ($k, $v);
while (($k, $v) = each %$summary) {
Log("summary: $k = $v points");
@@ -101,6 +110,22 @@ sub simple_count
}
+=head2 error_continuity()
+
+ examine the continuity of error messages (*).
+ --------------------> time
+ * ok
+ ********* bad
+ * * *** * ambiguous
+
+but sum up count as the delta.
+
+ *
+ ***
+
+=cut
+
+
# Descriptions: error continuity based cost counting
# Arguments: OBJ($self) OBJ($curproc) HASH_REF($data)
# Side Effects: none
@@ -126,10 +151,6 @@ sub error_continuity
$summary->{ $addr } = [ 0 ];
}
- # count up the folloging distribution function.
- # *
- # ***
-
# center of distribution function
$i = int( (time - $time ) / (24*3600) );
$summary->{ $addr }->[ $i ] += 2;
@@ -152,6 +173,7 @@ sub error_continuity
while (($addr, $ra) = each %$summary) {
$sum = 0;
for my $v (@$ra) {
+ # count if the top of the mountain is over 2.
if (defined $v) {
$sum += 1 if $v >= 2;
}
@@ -171,10 +193,6 @@ sub error_continuity
See C<http://www.fml.org/software/FNF/> on fml coding style guide.
-=head1 CODING STYLE
-
-See C<http://www.fml.org/software/FNF/> on fml coding style guide.
-
=head1 AUTHOR
Ken'ichi Fukamachi
diff --git a/fml/lib/FML/Error/Cache.pm b/fml/lib/FML/Error/Cache.pm
index 7e41e873..bbbfb119 100644
--- a/fml/lib/FML/Error/Cache.pm
+++ b/fml/lib/FML/Error/Cache.pm
@@ -4,7 +4,7 @@
# All rights reserved. This program is free software; you can
# redistribute it and/or modify it under the same terms as Perl itself.
#
-# $FML: Cache.pm,v 1.5 2002/09/22 14:56:49 fukachan Exp $
+# $FML: Cache.pm,v 1.6 2002/11/20 14:31:44 fukachan Exp $
#
package FML::Error::Cache;
@@ -15,20 +15,23 @@ use FML::Log qw(Log LogWarn LogError);
=head1 NAME
-FML::Error::Cache - manipulate error/bounce infomation
+FML::Error::Cache - manipulate error/bounce information database.
=head1 SYNOPSIS
use FML::Error::Cache;
- my $error = new FML::Error::Cache $curproc;
- $error->cache_on( $bounce_info );
+ my $db = new FML::Error::Cache $curproc;
+ $db->add( $bounce_info );
where C<$bounce_info) follows:
- $bounce_info = [ { address => 'rudo@nuinui.net',
- status => '5.x.y',
- reason => '... reason ... ',
- }
+ $bounce_info = [
+ {
+ address => 'rudo@nuinui.net',
+ status => '5.x.y',
+ reason => '... reason ... ',
+ },
+ ...
];
=head1 DESCRIPTION
@@ -60,7 +63,7 @@ sub new
}
-# Descriptions: save bounce info into cache.
+# Descriptions: add bounce info into cache.
# Arguments: OBJ($self) HASH_REF($info)
# Side Effects: update cache
# Return Value: none
@@ -85,18 +88,18 @@ sub add
$db->{ $address } = "$unixtime status=$status reason=$reason";
}
else {
- LogWarn("Error::Cache: cache_on: invalid data");
+ LogWarn("FML::Error::Cache: add: invalid data");
}
$self->_close_cache();
}
else {
- croak("add_to_cache: unknown data input type");
+ croak("FML::Error::Cache: add: unknown data input type");
}
}
-# Descriptions: open the cache dir for File::CacheDir
+# Descriptions: open the cache database for File::CacheDir.
# Arguments: OBJ($self)
# Side Effects: none
# Return Value: OBJ
@@ -119,7 +122,7 @@ sub _open_cache
}
-# Descriptions: dummy
+# Descriptions: destruct tied hash.
# Arguments: OBJ($self)
# Side Effects: none
# Return Value: none
@@ -134,13 +137,17 @@ sub _close_cache
}
+# Descriptions: return key list in db.
+# Arguments: OBJ($self)
+# Side Effects: none
+# Return Value: ARRAY_REF
sub get_addr_list
{
my ($self) = @_;
$self->_open_cache();
- my $db = $self->{ _db };
+ my $db = $self->{ _db };
my @addr = keys %$db;
$self->_close_cache();
@@ -149,6 +156,10 @@ sub get_addr_list
}
+# Descriptions: return new Tie::JournaledDir object.
+# Arguments: OBJ($self)
+# Side Effects: none
+# Return Value: OBJ
sub _new
{
my ($self) = @_;
@@ -159,12 +170,18 @@ sub _new
my $mode = $config->{ error_analyzer_cache_mode } || 'temporal';
my $days = $config->{ error_analyzer_cache_size } || 14;
+ #
+ # XXX-TODO: this _new() method is required ?
+ #
use Tie::JournaledDir;
return new Tie::JournaledDir { dir => $dir };
}
-
+# Descriptions: get all values as HASH_REF.
+# Arguments: OBJ($self)
+# Side Effects: none
+# Return Value: HASH_REF
sub get_all_values_as_hash_ref
{
my ($self) = @_;
@@ -178,10 +195,6 @@ sub get_all_values_as_hash_ref
See C<http://www.fml.org/software/FNF/> on fml coding style guide.
-=head1 CODING STYLE
-
-See C<http://www.fml.org/software/FNF/> on fml coding style guide.
-
=head1 AUTHOR
Ken'ichi Fukamachi