summaryrefslogtreecommitdiff
path: root/fml/lib/FML
diff options
context:
space:
mode:
authorfukachan <fukachan>2008-09-09 08:48:59 +0000
committerfukachan <fukachan>2008-09-09 08:48:59 +0000
commit453db284ee46f8c24e2d28a6ad493d1175535b1f (patch)
treef684b32276616fd21f4c51b9bf60bc84bf6e4697 /fml/lib/FML
parent0ecdfd221c3b6ae46065f2d0becc6effd2c524bf (diff)
downloadfml8-453db284ee46f8c24e2d28a6ad493d1175535b1f.tar.gz
fml8-453db284ee46f8c24e2d28a6ad493d1175535b1f.tar.bz2
fml8-453db284ee46f8c24e2d28a6ad493d1175535b1f.zip
anonymous cgi initial version
Diffstat (limited to 'fml/lib/FML')
-rw-r--r--fml/lib/FML/CGI/Anonymous/DB.pm270
-rw-r--r--fml/lib/FML/CGI/Anonymous/Submit.pm53
-rw-r--r--fml/lib/FML/CGI/Skin/Anonymous.pm558
3 files changed, 881 insertions, 0 deletions
diff --git a/fml/lib/FML/CGI/Anonymous/DB.pm b/fml/lib/FML/CGI/Anonymous/DB.pm
new file mode 100644
index 00000000..598066f1
--- /dev/null
+++ b/fml/lib/FML/CGI/Anonymous/DB.pm
@@ -0,0 +1,270 @@
+#-*- perl -*-
+#
+# Copyright (C) 2008 Ken'ichi Fukamachi
+# All rights reserved. This program is free software; you can
+# redistribute it and/or modify it under the same terms as Perl itself.
+#
+# $FML: @template.pm,v 1.12 2008/08/24 08:28:36 fukachan Exp $
+#
+
+package FML::CGI::Anonymous::DB;
+use strict;
+use vars qw(@ISA @EXPORT @EXPORT_OK $AUTOLOAD);
+use Carp;
+
+=head1 NAME
+
+FML::CGI::Anonymous::DB - anonymous user database.
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+=head1 METHODS
+
+=head2 new()
+
+constructor.
+
+=cut
+
+
+# Descriptions: constructor.
+# Arguments: OBJ($self) OBJ($curproc)
+# Side Effects: none
+# Return Value: OBJ
+sub new
+{
+ my ($self, $curproc) = @_;
+ my ($type) = ref($self) || $self;
+ my $me = { _curproc => $curproc };
+ return bless $me, $type;
+}
+
+
+# Descriptions: assign a magic string and an identifier.
+# see FML::CGI::Skin::Anonymous::run_cgi_main()
+# for more details.
+# Arguments: OBJ($self)
+# Side Effects: update PCB and database.
+# Return Value: none
+sub assign_id
+{
+ my ($self) = @_;
+ my ($curproc) = $self->{ _curproc };
+ my ($config) = $curproc->config();
+ my ($pcb) = $curproc->pcb();
+
+ # generate a session identifier and a challenge magic string.
+ use FML::String::Random;
+ my $string = new FML::String::Random;
+ my $magic_string = $string->magic_string();
+ my $session_id = $string->identifier($magic_string);
+ $self->set_session_id($session_id);
+ $self->set_magic_string($magic_string);
+
+ # save them and the request into the temporal database => {
+ # session_id-$session_id => $session_id,
+ # magic_string-$session_id => $magic_string.
+ # };
+ my $expire = $config->as_second("anonymous_cgi_expire_limit") || 300;
+ my $confirm = $self->_db_open();
+ $confirm->set($session_id, "session_id", $session_id);
+ $confirm->set($session_id, "magic_string", $magic_string);
+ $confirm->set($session_id, "expire_time", time + $expire);
+}
+
+
+=head1 UTILITIES
+
+=head2 set_session_id($session_id)
+
+save the current session_id in PCB.
+
+=head2 get_session_id()
+
+get the current session_id.
+
+=head2 set_magic_string($magic_string)
+
+save the current magic string in PCB.
+
+=head2 get_magic_string()
+
+get the current magic string.
+
+=cut
+
+
+# Descriptions: save session_id in PCB.
+# Arguments: OBJ($self) STR($session_id)
+# Side Effects: update pcb.
+# Return Value: none
+sub set_session_id
+{
+ my ($self, $session_id) = @_;
+ my ($curproc) = $self->{ _curproc };
+ my ($pcb) = $curproc->pcb();
+
+ $pcb->set("cgi", "anonymous_session_id", $session_id);
+}
+
+
+# Descriptions: get the current session_id in PCB.
+# Arguments: OBJ($self)
+# Side Effects: none
+# Return Value: STR
+sub get_session_id
+{
+ my ($self) = @_;
+ my ($curproc) = $self->{ _curproc };
+ my ($pcb) = $curproc->pcb();
+
+ if (defined $pcb) {
+ return $pcb->get("cgi", "anonymous_session_id");
+ }
+ else {
+ $curproc->logerror("get_session_id: no pcb");
+ return undef;
+ }
+}
+
+
+# Descriptions: save magic string in PCB.
+# Arguments: OBJ($self) STR($magic_string)
+# Side Effects: update pcb.
+# Return Value: none
+sub set_magic_string
+{
+ my ($self, $magic_string) = @_;
+ my ($curproc) = $self->{ _curproc };
+ my ($pcb) = $curproc->pcb();
+
+ $pcb->set("cgi", "magic_string", $magic_string);
+}
+
+
+# Descriptions: get the current magic string in PCB.
+# Arguments: OBJ($self)
+# Side Effects: none
+# Return Value: STR
+sub get_magic_string
+{
+ my ($self) = @_;
+ my ($curproc) = $self->{ _curproc };
+ my ($pcb) = $curproc->pcb();
+
+ if (defined $pcb) {
+ return $pcb->get("cgi", "magic_string");
+ }
+ else {
+ $curproc->logerror("get_magic_string: no pcb");
+ return undef;
+ }
+}
+
+
+# Descriptions: check if the request for this session_id is too old ?
+# Arguments: OBJ($self) STR($session_id)
+# Side Effects: none
+# Return Value: NUM(1 or 0)
+sub is_expired
+{
+ my ($self, $session_id) = @_;
+ my $confirm = $self->_db_open();
+ my $expire_time = $confirm->get($session_id, "expire_time") || 0;
+
+ return( time > $expire_time ? 1 : 0 );
+}
+
+
+# Descriptions: check if the $magic_string is correct for $session_id.
+# Arguments: OBJ($self) STR($session_id) STR($magic_string)
+# Side Effects: none
+# Return Value: NUM(1 or 0)
+sub is_correct_magic_string
+{
+ my ($self, $session_id, $magic_string) = @_;
+ my $confirm = $self->_db_open();
+ my $db_session_id = $confirm->get($session_id, "session_id");
+ my $db_magic_string = $confirm->get($session_id, "magic_string");
+
+ # case insensitive
+ $magic_string =~ tr/A-Z/a-z/;
+ $db_magic_string =~ tr/A-Z/a-z/;
+ if ($magic_string eq $db_magic_string) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+=head1 DATABASE OPERATIONS
+
+private.
+
+DO NOT USE THESE METHODS.
+
+=cut
+
+
+# Descriptions: open the database.
+# Arguments: OBJ($self)
+# Side Effects: none
+# Return Value: OBJ
+sub _db_open
+{
+ my ($self) = @_;
+ my ($curproc) = $self->{ _curproc };
+ my ($config) = $curproc->config();
+ my ($pcb) = $curproc->pcb();
+
+ use FML::Confirm;
+ my $cache_dir = $config->{ db_dir };
+ my $confirm = new FML::Confirm $curproc, {
+ keyword => "confirm",
+ cache_dir => $cache_dir,
+ class => "cgi",
+ address => "dummy",
+ buffer => "dummy",
+ };
+ return $confirm;
+}
+
+
+# Descriptions: close the database (dummy).
+# Arguments: OBJ($self)
+# Side Effects: none
+# Return Value: none
+sub _db_close
+{
+ my ($self) = @_;
+}
+
+
+=head1 CODING STYLE
+
+See C<http://www.fml.org/software/FNF/> on fml coding style guide.
+
+=head1 AUTHOR
+
+Ken'ichi Fukamachi
+
+=head1 COPYRIGHT
+
+Copyright (C) 2008 Ken'ichi Fukamachi
+
+All rights reserved. This program is free software; you can
+redistribute it and/or modify it under the same terms as Perl itself.
+
+=head1 HISTORY
+
+FML::CGI::Anonymous::DB appeared in fml8 mailing list driver package.
+See C<http://www.fml.org/> for more details.
+
+=cut
+
+
+1;
diff --git a/fml/lib/FML/CGI/Anonymous/Submit.pm b/fml/lib/FML/CGI/Anonymous/Submit.pm
new file mode 100644
index 00000000..05679da2
--- /dev/null
+++ b/fml/lib/FML/CGI/Anonymous/Submit.pm
@@ -0,0 +1,53 @@
+#-*- perl -*-
+#
+# Copyright (C) 2008 Ken'ichi Fukamachi
+# All rights reserved. This program is free software; you can
+# redistribute it and/or modify it under the same terms as Perl itself.
+#
+# $FML: @template.pm,v 1.12 2008/08/24 08:28:36 fukachan Exp $
+#
+
+package FML::CGI::Anonymous::Submit;
+use strict;
+use Carp;
+use vars qw(@ISA @EXPORT @EXPORT_OK $AUTOLOAD);
+use CGI qw/:standard/; # load standard CGI routines
+
+use FML::CGI::Skin::Anonymous;
+@ISA = qw(FML::CGI::Skin::Anonymous);
+
+
+=head1 NAME
+
+FML::CGI::Anonymous::Submit - submit a request from an anonymous user.
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+=head1 METHODS
+
+=head1 CODING STYLE
+
+See C<http://www.fml.org/software/FNF/> on fml coding style guide.
+
+=head1 AUTHOR
+
+Ken'ichi Fukamachi
+
+=head1 COPYRIGHT
+
+Copyright (C) 2008 Ken'ichi Fukamachi
+
+All rights reserved. This program is free software; you can
+redistribute it and/or modify it under the same terms as Perl itself.
+
+=head1 HISTORY
+
+FML::CGI::Anonymous::Submit appeared in fml8 mailing list driver package.
+See C<http://www.fml.org/> for more details.
+
+=cut
+
+
+1;
diff --git a/fml/lib/FML/CGI/Skin/Anonymous.pm b/fml/lib/FML/CGI/Skin/Anonymous.pm
new file mode 100644
index 00000000..b823d210
--- /dev/null
+++ b/fml/lib/FML/CGI/Skin/Anonymous.pm
@@ -0,0 +1,558 @@
+#-*- perl -*-
+#
+# Copyright (C) 2008 Ken'ichi Fukamachi
+# All rights reserved. This program is free software; you can
+# redistribute it and/or modify it under the same terms as Perl itself.
+#
+# $FML$
+#
+
+package FML::CGI::Skin::Anonymous;
+use strict;
+use Carp;
+use vars qw(@ISA @EXPORT @EXPORT_OK $AUTOLOAD $global_error_reason);
+use CGI qw/:standard/; # load standard CGI routines
+
+use FML::Process::CGI;
+@ISA = qw(FML::Process::CGI);
+
+my $debug = 0;
+
+
+=head1 NAME
+
+FML::CGI::Skin::Anonymous - provides CGI control function for anonymous users.
+
+=head1 SYNOPSIS
+
+ $obj = new FML::CGI::Skin::Anonymous;
+ $obj->prepare();
+ $obj->verify_request();
+ $obj->run();
+ $obj->finish();
+
+run() executes html_start(), run_cgi() and html_end() described below.
+
+See L<FML::Process::Flow> for flow details.
+
+=head1 DESCRIPTION
+
+=head2 CLASS HIERARCHY
+
+C<FML::CGI::Skin::Anonymous> is a subclass of C<FML::Process::CGI>.
+
+ FML::Process::Kernel
+ |
+ A
+ FML::Process::CGI::Kernel
+ |
+ A
+ FML::Process::CGI
+ |
+ A
+ -----------------------
+ | |
+ A A
+ FML::CGI::Skin::Anonymous
+
+=head1 METHODS
+
+Almost cgi common methods are forwarded to
+C<FML::Process::CGI> base class.
+
+This module has routines needed for the admin CGI.
+
+=cut
+
+
+# Descriptions: print out HTML header + body former part.
+# Arguments: OBJ($curproc)
+# Side Effects: none
+# Return Value: none
+sub html_start
+{
+ my ($curproc) = @_;
+ my $config = $curproc->config();
+ my $myname = $curproc->cgi_var_myname();
+ my $ml_name = $curproc->cgi_var_ml_name();
+ my $ml_domain = $curproc->cgi_var_ml_domain();
+ my $name_ui = $curproc->message_nl('cgi.anonymous.top');
+ my $title = "${ml_name}\@${ml_domain} $name_ui";
+ my $color = $config->{ cgi_main_menu_color } || '#FFFFFF';
+ my $charset = $curproc->langinfo_get_charset("cgi");
+
+ # o.k start html
+ print start_html(-title => $title,
+ -lang => $charset,
+ -BGCOLOR => $color);
+ print "\n";
+}
+
+
+# Descriptions: print out body latter part.
+# Arguments: OBJ($curproc)
+# Side Effects: none
+# Return Value: none
+sub html_end
+{
+ my ($curproc) = @_;
+
+ # o.k. end of html
+ print end_html;
+ print "\n";
+}
+
+
+# Descriptions: main routine for CGI.
+# kick off suitable FML::Command finally
+# via cgi_execulte_command().
+# Arguments: OBJ($curproc)
+# Side Effects: none
+# Return Value: none
+sub run_cgi_main
+{
+ my ($curproc) = @_;
+ my $config = $curproc->config();
+ my $address = $curproc->cgi_try_get_address();
+ my $ml_name = $curproc->cgi_var_ml_name();
+ my $pcb = $curproc->pcb();
+ my $mode = 'anonymous'; # cgi needs to run for an anonymous user.
+
+ # specified command, we need to identify
+ # the command specifined in the cgi_navigation and cgi_mein.
+ my $navi_command = $curproc->safe_param_navi_command() || '';
+ my $command = $curproc->safe_param_command() || '';
+
+ # updat config: $ml_name is found now (get $ml_name from CGI).
+ $config->set('ml_name', $ml_name);
+
+ if ($debug) {
+ print "<PRE>\n";
+ print "ml_name = $ml_name\n";
+ print "command = $command\n";
+ print "navi_command = $navi_command\n";
+ print "</PRE>\n";
+ }
+
+ # [I] 1st challenge phase ($curproc->prepare() has done it already).
+ # 1. save request and information before verification.
+ # 1.1 assign a hidden id for this request.
+ # 1.2 generate a challenge magic string (ALPHABET+, up to 8 chars).
+ # 1.3 save them and the request into the temporal database.
+ # bind the challenge password with the id
+ # for the later reverse operation.
+ #
+ # 2. show menu by $curproc->run_cgi_menu() at the center of table.
+ #
+ # [II] 2nd challenge phase: something is requested by an anonymou user.
+ # 3. check if this request is from a human or a spam robot ?
+ # 3.1 use the challenge password (assigned at 1.2 above).
+ my $is_ok = $curproc->_anonymous_is_human_operating();
+ if ($is_ok) {
+ # if confirmed that a human seems operating, process the request.
+ $curproc->_anonymous_run_cgi_main();
+ }
+ else {
+ if (defined $global_error_reason && $global_error_reason) {
+ my $buf = $curproc->message_nl("cgi.fail",
+ "Error! request fails.");
+ print "<p>", $buf, "<br>\n";
+ }
+
+ $curproc->logdebug("first time");
+ }
+}
+
+
+# Descriptions: check if the request is operated by a human.
+# Arguments: OBJ($curproc)
+# Side Effects: none
+# Return Value: NUM(1 or 0)
+sub _anonymous_is_human_operating
+{
+ my ($curproc) = @_;
+
+ if ($curproc->_anonymous_cgi_is_first_time()) {
+ return 0;
+ }
+ else {
+ my $session_id = $curproc->safe_param_session_id();
+ my $magic_string = $curproc->safe_param_magic_string();
+ if ($session_id && $magic_string) {
+ $curproc->log("session_id = $session_id");
+ $curproc->logdebug("magic_string = $magic_string");
+ }
+ else {
+ $curproc->logwarn("invalid request");
+ return 0;
+ }
+
+ # check the magic string is valid or not. return 1 if ok.
+ use FML::CGI::Anonymous::DB;
+ my $db = new FML::CGI::Anonymous::DB $curproc;
+
+ # 1. expired ?
+ if ($db->is_expired($session_id)) {
+ $curproc->logerror("expired request");
+ $global_error_reason = "expired";
+ return 0;
+ }
+
+ # 2. not expired, ok, check if the magic string is correct.
+ if ($db->is_correct_magic_string($session_id, $magic_string)) {
+ $curproc->log("correct magic string");
+ return 1;
+ }
+ else {
+ $global_error_reason = "incorrect_magic_string";
+ $curproc->logwarn("incorrect magic string");
+ return 0;
+ }
+ }
+}
+
+
+# Descriptions: main routine for CGI.
+# kick off suitable FML::Command finally
+# via cgi_execulte_command().
+# Arguments: OBJ($curproc)
+# Side Effects: none
+# Return Value: none
+sub _anonymous_run_cgi_main
+{
+ my ($curproc) = @_;
+ my $config = $curproc->config();
+ my $pcb = $curproc->pcb();
+ my $mode = 'user';
+
+ my $ml_name = $curproc->cgi_var_ml_name();
+ my $address = $curproc->cgi_try_get_address();
+ my $navi_command = $curproc->safe_param_navi_command() || '';
+ my $command = $curproc->safe_param_command() || '';
+
+ # updat config: $ml_name is found now (get $ml_name from CGI).
+ $config->set('ml_name', $ml_name);
+
+ if ($debug) {
+ print "<PRE>\n";
+ print "ml_name = $ml_name\n";
+ print "command = $command\n";
+ print "navi_command = $navi_command\n";
+ print "address = $address\n";
+ print "</PRE>\n";
+ }
+
+ if ($command && $address) {
+ print "<br>* case 2 <br>\n" if $debug;
+
+ my $command_context =
+ $curproc->command_context_init($command);
+ $command_context->set_mode("User");
+ $command_context->set_ml_name($ml_name);
+ $command_context->set_data($address);
+ $command_context->set_options( [ $address ] );
+
+ # XXX we need a fake that we handle a mail request.
+ my $cred = $curproc->credential();
+ $cred->set_sender($address);
+ $curproc->set_allow_reply_message();
+
+ $pcb->set('cgi', 'command_context', $command_context);
+ $curproc->cgi_execute_command($command_context, "ml_anonymous_cgi");
+ }
+ else {
+ $curproc->log("cgi_main: invalid condition, not processed.");
+ $pcb->set('cgi', 'command_context', undef);
+ }
+}
+
+
+# Descriptions: show menu (table based menu).
+# Arguments: OBJ($curproc) HASH_REF($args)
+# Side Effects: none
+# Return Value: none
+sub run_cgi_navigator
+{
+ my ($curproc, $args) = @_;
+ my $target = $curproc->cgi_var_frame_target();
+ my $action = $curproc->cgi_var_action();
+
+ # natural language-ed name
+ my $name_ml_name = $curproc->message_nl('term.ml_name', 'ml_name');
+ my $name_command = $curproc->message_nl('term.command', 'command');
+ my $name_submit = $curproc->message_nl('term.submit', 'submit');
+ my $name_reset = $curproc->message_nl('term.reset', 'reset');
+
+ # 1. ML
+ # my $title = $curproc->cgi_var_navigator_title();
+ # print $title, "\n";
+
+ # 2. command
+ my $usage = "anonymous usage";
+ my $name_usage = $curproc->message_nl('cgi.anonymous.usage', $usage);
+ print $name_usage;
+ print "\n<BR>\n";
+
+ # 3. submit
+ # print submit(-name => $name_submit);
+ # print reset(-name => $name_reset);
+}
+
+
+=head2 run_cgi_menu()
+
+execute cgi_menu() given as FML::Command::* class.
+The menu function should be within FML::Command::User::* class.
+
+ for my $command ($commands_for_ml_anonymous_cgi) {
+ if $command in $anonymous_cgi_allowed_commands {
+ FML::Command::User::$command->cgi_menu();
+ }
+ }
+
+=cut
+
+
+# Descriptions: show the main menu at the screen center.
+# Arguments: OBJ($curproc)
+# Side Effects: load module
+# Return Value: none
+sub run_cgi_menu
+{
+ my ($curproc) = @_;
+ my $msg_args = $curproc->_gen_msg_args();
+
+ # top level help message
+ print $curproc->message_nl("cgi.anonymous.top", "", $msg_args);
+
+ if ($curproc->_anonymous_cgi_is_first_time()) {
+ $curproc->_anonymous_cgi_print_menu();
+ $curproc->_anonymous_cgi_print_magic_string();
+ }
+ else {
+ ;
+ }
+}
+
+
+# Descriptions: check if this request is done at the first time.
+# Arguments: OBJ($curproc)
+# Side Effects: none
+# Return Value: NUM(1 or 0)
+sub _anonymous_cgi_is_first_time
+{
+ my ($curproc) = @_;
+
+ my $session_id = $curproc->safe_param_session_id();
+ return( $session_id ? 0 : 1 );
+}
+
+
+# Descriptions: show menu for an anonymous user.
+# Arguments: OBJ($curproc)
+# Side Effects: none
+# Return Value: none
+sub _anonymous_cgi_print_menu
+{
+ my ($curproc) = @_;
+ my $ml_name = $curproc->cgi_var_ml_name();
+
+ for my $command (qw(subscribe unsubscribe)) {
+ my $pkg = sprintf("FML::Command::User::%s", $command);
+ my $command_context = {
+ command_mode => "user",
+ comname => $command,
+ command => $command,
+ ml_name => $ml_name,
+ options => [ ],
+ argv => undef,
+ args => undef,
+ };
+
+ my $eval = qq{
+ use $pkg;
+ my \$command = new $pkg;
+ \$command->cgi_menu(\$curproc, \$command_context);
+ };
+ eval $eval;
+ if ($@) {
+ print "$command not suport anonymous mode\n<br>\n";
+ print "{$@}\n";
+ }
+ }
+}
+
+
+# Descriptions: print the magic string.
+# Arguments: OBJ($curproc)
+# Side Effects: none
+# Return Value: none
+sub _anonymous_cgi_print_magic_string
+{
+ my ($curproc) = @_;
+ my $config = $curproc->config();
+ my $_mgs = "magic string";
+ my $name_magic = $curproc->message_nl('term.magic_string', $_mgs);
+ my $is_mode = "png";
+
+ use FML::CGI::Anonymous::DB;
+ my $db = new FML::CGI::Anonymous::DB $curproc;
+ my $string = $db->get_magic_string();
+ my $session_id = $db->get_session_id();
+
+ use FML::String::Banner;
+ my $banner = new FML::String::Banner;
+ $banner->set_string($string);
+ if ($is_mode eq "ascii") {
+ my $ascii = $banner->as_ascii();
+ printf("\n<pre>[%s]\n\n%s\n</pre>\n", $name_magic, $ascii);
+ }
+ elsif ($is_mode eq "png") {
+ my $html_tmp_dir = $config->get('html_tmp_dir');
+ unless (-d $html_tmp_dir) {
+ mkdir $html_tmp_dir, 0755;
+ }
+
+ use File::Spec;
+ my $png_filename = sprintf("%s.png", $session_id);
+ my $image_file = File::Spec->catfile($html_tmp_dir, $png_filename);
+
+ use FileHandle;
+ my $wh = new FileHandle "> $image_file";
+ if (defined $wh) {
+ $wh->binmode();
+ my $png = $banner->as_png();
+ $wh->print($png);
+ $wh->close();
+ }
+
+ my $url_base = $config->{ html_tmp_base_url };
+ my $url = sprintf("%s/%s", $url_base, $png_filename);
+ printf("\n<p>%s\n\n<image src=\"%s\">\n", $name_magic, $url);
+ }
+}
+
+
+# Descriptions: dummy.
+# Arguments: OBJ($curproc)
+# Side Effects: none
+# Return Value: none
+sub run_cgi_title
+{
+ my ($curproc) = @_;
+}
+
+
+=head2 run_cgi_help()
+
+show help.
+
+=cut
+
+
+# Descriptions: show help.
+# Arguments: OBJ($curproc)
+# Side Effects: none
+# Return Value: none
+sub run_cgi_help
+{
+ my ($curproc) = @_;
+ my $ml_name = $curproc->cgi_var_ml_name();
+ my $ml_domain = $curproc->cgi_var_ml_domain();
+ my $mode = $curproc->cgi_var_cgi_mode();
+ my $msg_args = $curproc->_gen_msg_args();
+
+ print "<B>\n<CENTER>\n";
+ print "$ml_name\@$ml_domain ML\n";
+ print "</CENTER><BR>\n</B>\n";
+}
+
+
+=head2 run_cgi_command_help()
+
+show command dependent help.
+
+=cut
+
+
+# Descriptions: show command dependent help.
+# Arguments: OBJ($curproc)
+# Side Effects: none
+# Return Value: none
+sub run_cgi_command_help
+{
+ my ($curproc) = @_;
+ my $buf = '';
+ my $navi_command = $curproc->safe_param_navi_command();
+ my $command = $curproc->safe_param_command();
+ my $msg_args = $curproc->_gen_msg_args();
+
+ # natural language-ed name
+ my $name_usage = $curproc->message_nl('term.usage', 'usage');
+
+ if ($navi_command) {
+ print "[$name_usage]<br> <b> $navi_command </b> <br>\n";
+ $buf = $curproc->message_nl("cgi.config.$navi_command", '', $msg_args);
+ }
+ elsif ($command) {
+ print "[$name_usage]<br> <b> $command </b> <br>\n";
+ $buf = $curproc->message_nl("cgi.config.$command", '', $msg_args);
+ }
+
+ print $buf;
+}
+
+
+# Descriptions: prepare arguemnts for message handling.
+# Arguments: OBJ($curproc)
+# Side Effects: none
+# Return Value: HASH_REF
+sub _gen_msg_args
+{
+ my ($curproc) = @_;
+
+ # natural language-ed name
+ my $name_submit = $curproc->message_nl('term.submit', 'submit');
+ my $name_show = $curproc->message_nl('term.show', 'show');
+ my $name_map = $curproc->message_nl('term.map', 'map');
+ my $msg_args = {
+ _arg_button_submit => $name_submit,
+ _arg_button_show => $name_show,
+ _arg_scroll_map => $name_map,
+ };
+
+ return $msg_args;
+}
+
+
+=head1 SEE ALSO
+
+L<CGI>,
+L<FML::Process::CGI>
+and
+L<FML::Process::Flow>.
+
+=head1 CODING STYLE
+
+See C<http://www.fml.org/software/FNF/> on fml coding style guide.
+
+=head1 AUTHOR
+
+Ken'ichi Fukamachi
+
+=head1 COPYRIGHT
+
+Copyright (C) 2008 Ken'ichi Fukamachi
+
+All rights reserved. This program is free software; you can
+redistribute it and/or modify it under the same terms as Perl itself.
+
+=head1 HISTORY
+
+FML::CGI::Skin::Anonymous appeared in fml8 mailing list driver package.
+See C<http://www.fml.org/> for more details.
+
+=cut
+
+
+1;