From 02f0eb5231edfb665704bd0cfd9bfbe5ec59fae1 Mon Sep 17 00:00:00 2001 From: fukachan Date: Wed, 27 Jul 2005 12:21:35 +0000 Subject: sync and translated. --- fml/doc/en/tutorial/internals/CURPROC.sgml | 16 +- fml/doc/en/tutorial/internals/PCB.sgml | 64 +++++++ fml/doc/en/tutorial/internals/bootloader.sgml | 221 +++++++++++++++++++++++ fml/doc/en/tutorial/internals/cgi.examples.sgml | 125 +++++++++++++ fml/doc/en/tutorial/internals/config.cf.sgml | 16 +- fml/doc/en/tutorial/internals/credential.sgml | 4 +- fml/doc/en/tutorial/internals/dbms.sgml | 28 ++- fml/doc/en/tutorial/internals/directory.sgml | 49 ++++++ fml/doc/en/tutorial/internals/language.sgml | 224 ++++++++++++++++++++++++ fml/doc/en/tutorial/internals/lock.sgml | 83 +++++++++ fml/doc/en/tutorial/internals/main.cf.sgml | 119 +++++++++++++ fml/doc/en/tutorial/internals/merge.sgml | 122 +++++++++++++ fml/doc/en/tutorial/internals/restriction.sgml | 202 +++++++++++++++++++++ fml/doc/en/tutorial/internals/struct.sgml | 29 ++- fml/doc/en/tutorial/internals/userctl.sgml | 57 ++++++ 15 files changed, 1331 insertions(+), 28 deletions(-) create mode 100644 fml/doc/en/tutorial/internals/PCB.sgml create mode 100644 fml/doc/en/tutorial/internals/bootloader.sgml create mode 100644 fml/doc/en/tutorial/internals/cgi.examples.sgml create mode 100644 fml/doc/en/tutorial/internals/directory.sgml create mode 100644 fml/doc/en/tutorial/internals/language.sgml create mode 100644 fml/doc/en/tutorial/internals/lock.sgml create mode 100644 fml/doc/en/tutorial/internals/main.cf.sgml create mode 100644 fml/doc/en/tutorial/internals/merge.sgml create mode 100644 fml/doc/en/tutorial/internals/restriction.sgml create mode 100644 fml/doc/en/tutorial/internals/userctl.sgml diff --git a/fml/doc/en/tutorial/internals/CURPROC.sgml b/fml/doc/en/tutorial/internals/CURPROC.sgml index e6fc8f2b..8296e4c6 100644 --- a/fml/doc/en/tutorial/internals/CURPROC.sgml +++ b/fml/doc/en/tutorial/internals/CURPROC.sgml @@ -2,19 +2,24 @@ __parent_args => HASH { ARGV => ARRAY + ___shared_memory___ => HASH argv => ARRAY cf_list => ARRAY + curproc => FML::Process::Distribute fml_version main_cf => HASH module_info => HASH myname need_ml_name options => HASH + program_fullname program_name } __print_style => SCALAR +__start_time => SCALAR + article => HASH { body => Mail::Message header => FML::Header @@ -31,29 +36,38 @@ incoming_message => HASH { message => Mail::Message } +log_message_queue => FML::Log::Print::Simple + main_cf => HASH { - _hints + _hints => HASH config_dir debug default_command_line_option_config default_config_cf default_config_dir + default_cui_menu default_domain + default_gui_menu default_ml_home_prefix default_module_config default_paths_cf domain_default_config + domain_default_config_cf exec_prefix executable_prefix fml_group fml_owner fml_version + group_writable_config_dir lib_dir libexec_dir local_lib_dir + ml_home_prefix_maps prefix prefix_dir + primary_ml_home_prefix_map share_dir + site_default_config_cf virtual_maps } diff --git a/fml/doc/en/tutorial/internals/PCB.sgml b/fml/doc/en/tutorial/internals/PCB.sgml new file mode 100644 index 00000000..975bc3fa --- /dev/null +++ b/fml/doc/en/tutorial/internals/PCB.sgml @@ -0,0 +1,64 @@ + + +module function category + <-- (get value) + --> (set value) +-------------------------------------------------------------------------------- +Error run --> error +Error finish <-- error +Fake set_emul_domain --> faker +Fake get_emul_domain <-- faker +Fake set_emul_ml_list --> faker +Fake get_emul_ml_list <-- faker +Fake set_emul_user_list --> faker +Fake get_emul_user_list <-- faker +Kernel sysflow_reopen_stderr_channel --> stderr +Kernel sysflow_reopen_stderr_channel --> stderr +Kernel sysflow_finalize_stderr_channel <-- stderr +Kernel sysflow_finalize_stderr_channel <-- stderr +Kernel sysflow_finalize_stderr_channel --> stderr +State current_process_set_ml_name <-- current_process +State current_process_get_ml_name <-- current_process +State restriction_state_set_deny_reason --> check_restrictions +State restriction_state_get_deny_reason <-- check_restrictions +State article_set_id --> article_message +State article_get_id <-- article_message +State command_context_set_ml_name --> process_command +State command_context_get_ml_name <-- process_command +State command_context_set_stop_process --> process_command +State command_context_get_stop_process <-- process_command +State command_context_set_normal_stop --> process_command +State command_context_get_normal_stop <-- process_command +State command_context_set_need_confirm --> process_command +State command_context_get_need_confirm <-- process_command +State command_context_set_admin_auth --> process_command +State command_context_get_admin_auth <-- process_command +State command_context_set_admin_password --> process_command +State command_context_get_admin_password <-- process_command +State command_context_set_try_admin_auth_request --> process_command +State command_context_reset_try_admin_auth_request --> process_command +State command_context_get_try_admin_auth_request <-- process_command +State filter_state_set_error --> filter_state +State filter_state_get_error <-- filter_state +State filter_state_spam_checker_set_error --> filter_state +State filter_state_spam_checker_get_error <-- filter_state +State filter_state_virus_checker_set_error --> filter_state +State filter_state_virus_checker_get_error <-- filter_state +State filter_state_set_tempfail_request --> filter_state +State filter_state_get_tempfail_request <-- filter_state +State smtp_server_state_set_error --> smtp_transaction +State smtp_server_state_get_error <-- smtp_transaction +State error_message_set_count <-- reply_message_count +State error_message_set_count --> reply_message_count +State error_message_get_count <-- reply_message_count +Utils incoming_message_set_cache_file_path --> incoming_message +Utils incoming_message_get_cache_file_path <-- incoming_message +Utils incoming_message_set_current_queue --> incoming_smtp_transaction +Utils incoming_message_get_current_queue <-- incoming_smtp_transaction +Utils set_language_hint --> language_hint +Utils get_language_hint <-- language_hint +Utils set_charset --> charset +Utils get_charset <-- charset +Utils get_charset <-- charset + + diff --git a/fml/doc/en/tutorial/internals/bootloader.sgml b/fml/doc/en/tutorial/internals/bootloader.sgml new file mode 100644 index 00000000..e7c9d6b8 --- /dev/null +++ b/fml/doc/en/tutorial/internals/bootloader.sgml @@ -0,0 +1,221 @@ + + + + + + &fml8; boot loader to resolv version dependence dynamically + + + +&fml8; provides a boot loader to resolv version dependence dynamically. +For example, the loader boot straps &fml8; as follows: + +fml (libexec/distribute) boots like this ... + + functions class + ---------------------------------------- + + main::Bootstrap() libexec/loader + | + V + main::Bootstrap2() FML::Process::Switch + | + V + ProcessSwitch() FML::Process::Switch + | + | + | switch to ($obj = FML::Process:Distribute) + | + V + ProcessStart($obj,$args) FML::Process::Flow + + + + + + + Case: distribution + + + +&fml8; loader boot straps like this in the case of distribution. + + + +/usr/local/libexec/fml/distributre (== /usr/local/libexec/fml/loader +in fact) reads /usr/local/etc/fml/main.cf and resolvers the version it +should use from $fml_version variable. Let $fml_version +current-20010501. The loader uses library perl modules under +/usr/local/lib/fml/current-20010501/. + + + +The loader resets @INC (perl include path). +It loads FML::Process::Switch and checks $0 (program name in process table). +The loader resolves from the name that the role is distribution. +It loads FML::Process::Distribute and switches to the class. + + + +The relation between program name and class (perl module) is defined +at /usr/local/etc/fml/defaults/$fml_version/modules file. + + + +FML::Process::Flow::ProcessStart() function drives these sequential +steps. ProcessStart() takes FML::Process::Distribute object as an +argument and drives the object. + + + + + + + + FML::Process:: class structure + + + + +FML::Process::Distribute >-| +FML::Process::Command >-|-- FML::Process::Kernel +FML::Process::Mead >-| | + |-use-a FML::Parse + |-use-a FML::Config + |-use-a FML::Log + |-use-a ... SOMETHING ... + + + + + + + + + Modules in process execution + + + + + + + libexec/loader (wrapper): + executes Bootstrap() runction. + libexec/distribute et.al. is a symlink(2) to this loader. + See under /usr/local/libexec/fml/ path. + + + + + + + + reads /usr/local/etc/fml/main.cf and resolves $fml_version. + reset @INC by main.cf value. + Since default_config.cf is version dependent, + the loader should evaluate the file before it reads + ML specific configuration files. + + + + + + Evaluate @ARGV and resolves which ML specific configuration + files we need to load. + + + + + + load FML::Process::Switch class which is also version dependent. + + + + + + The loader executes Bootstrap2() and ProcessSwitch() + to switch the context to each one such as + distribution, command mail et.al. + In this time, the loader knows the role + from $0 process name. + + + + + + Exapmle of Polymorphyism: + dynamic binding of module and creation of process + object in starting the process. + + FML::Process::Flow describes the flow of process + like this: + +$process = new FML::Process::SOMETHING; +$process->prepare($args); +$process->verify_request($args); +$process->run($args); +$process->finish($args); + + Each process should probide proper methods under + FML::Process:: class. + + + + + + + + + + + + + Discussion: where function should resolve $ml_name and $ml_domain. + + + +Currently &fml8; resolves them in prepare() under FML::Process:: classes. + + + +Here is a part of background idea. + +main::Bootstrap() + + resoles $fml_version based on main.cf information. + + pass hints to some processes e.g. CGI. + CGI only + it should ignore invalid input. + $ml_name $and ml_domain is hard-coded in cgi scripts. + + +main::Bootstrap2() +ProcessSwitch() + + resolves the module, configuration files, library path and @INC. + + pass hints to some processes e.g. CGI. + CGI only + +ProcessStart($obj, $args) + + main process starts + + new + + prepare + resoles $ml_name and $ml_domain. + parse input from CGI using hints. + determine ml specific configuration files. + parse incoming message. + parse command line arguments. + + + + + + + diff --git a/fml/doc/en/tutorial/internals/cgi.examples.sgml b/fml/doc/en/tutorial/internals/cgi.examples.sgml new file mode 100644 index 00000000..bf10702d --- /dev/null +++ b/fml/doc/en/tutorial/internals/cgi.examples.sgml @@ -0,0 +1,125 @@ + + + + + + CGI implementation: inheritance among CGI classes + + + +@ISA of config.cgi follow: + +FML::CGI::Menu FML::Process::CGI::Kernel FML::Process::CGI::Param + +In the case of thread.cgi, @ISA is + +FML::CGI::Thread FML::Process::CGI::Kernel FML::Process::CGI::Param + + + + +.cgi specific codes locate at FML::CGI:: class layer. + + + +FML::Process::CGI::Kernel provides the main part of CGI process +and CGI specific function run_cgi_XXX(). +If needed, FML::CGI:: class overloads this layer. +Currently, +the following methods in FML::Process::CGI::Kernel are not used. + +run_cgi_log +run_cgi_dummy +run_cgi_date + + + + + + + + + CGI Implementation: config.cgi + + + +@ISA of config.cgi is as follows: + +FML::CGI::Menu FML::Process::CGI::Kernel FML::Process::CGI::Param + +Let see processing of config.cgi below. + + + +config.cgi process object $curproc is a +FML::Process::CGI::Kernel class. + + new() + prepare() + verify_request() + run() + finish() + +is sequentially called from FML::Process::CGI::Kernel class. + + + +run() is important. run() executes the following methods sequentially. + + $curproc->html_start(); (FML::CGI::Menu) + $curproc->_drive_cgi_by_table(); (FML::Process::CGI::Kernel) + $curproc->html_end(); (FML::CGI::Menu) + +_drive_cgi_by_table() prepares the screen. +This function calls the main part of CGI. + + + +$curproc->_drive_cgi_by_table() +calles the following run_XXX() methods. + +run_cgi_main (FML::CGI::Menu) + +calls cgi_execute_command (FML::Process::CGI::Kernel) to +execute FML::Command::Admin::$COMMAND via FML::Command class. +This is the main part of command execution via CGI but +the screen creation is a role of another part. + + + +For example, consider subscribe an address via CGI. +run_cgi_main() executes the real process of subscription. +Instead run_cgi_menu() creates input menu. +Former calls FML::Command::Admin::subscribe::process() method, +latter calls FML::Command::Admin::subscribe::cgi_menu() method. + + + +There are several other run_cgi_XXX() methods. They are optional for +screen creation. + + + +The following run_cgi_XXX() uses the default method. + +run_cgi_title FML::Process::CGI::Kernel (show title) +run_cgi_options FML::Process::CGI::Kernel (show language selection) + +.cgi specific methods are as follows: + +run_cgi_navigator FML::CGI::Menu +run_cgi_help FML::CGI::Menu +run_cgi_command_help FML::CGI::Menu +run_cgi_menu FML::CGI::Menu + + + + +run_cgi_menu() executes +FML::Command::Admin::COMMAND::cgi_menu() +via cgi_execute_cgi_menu() method. + + + diff --git a/fml/doc/en/tutorial/internals/config.cf.sgml b/fml/doc/en/tutorial/internals/config.cf.sgml index 154c0db6..db55cee8 100644 --- a/fml/doc/en/tutorial/internals/config.cf.sgml +++ b/fml/doc/en/tutorial/internals/config.cf.sgml @@ -1,9 +1,9 @@ - + Configuration file: config.cf @@ -21,13 +21,13 @@ You can customize each ML differently. -In the case of &fml4;, there are $DIR and config.ph in ML home -directory. This "config.ph" file is a perl script. +In the case of &fml4;, there is a config.ph in ML home directory, +$DIR (e.g. /var/spool/ml). This "config.ph" file is a perl script. There is a config.cf file in &fmldevel;, too. -But the format is diffrent. The format is like this: +But the format is different. The format is like this: variable = value @@ -35,6 +35,10 @@ variable = value It is similar to postfix or .ini files. + +It is similar to a perl module. You can write perl codes after =cut line. + + @@ -128,7 +132,7 @@ since the last $a overwrites the previous one. <!-- ======================================= --> -<sect1> +<sect1 id="config.cf.format.extension"> <title> Extension to postfix style diff --git a/fml/doc/en/tutorial/internals/credential.sgml b/fml/doc/en/tutorial/internals/credential.sgml index 825b345c..e771ea31 100644 --- a/fml/doc/en/tutorial/internals/credential.sgml +++ b/fml/doc/en/tutorial/internals/credential.sgml @@ -1,5 +1,5 @@ @@ -14,7 +14,7 @@ User authentication is provided by methods of FML::Credential class. - + Discussion: FML::Credential implementation diff --git a/fml/doc/en/tutorial/internals/dbms.sgml b/fml/doc/en/tutorial/internals/dbms.sgml index c608bf9e..ae23be7e 100644 --- a/fml/doc/en/tutorial/internals/dbms.sgml +++ b/fml/doc/en/tutorial/internals/dbms.sgml @@ -1,5 +1,5 @@ @@ -9,6 +9,16 @@ + +This chapter describes how to handle persistent data. +You should use DBMS (DataBase Management System) for that data. +See + + + +on the internal use database. + + Overview @@ -32,20 +42,4 @@ preprocessing module calling IO::Adapter should handle it. </sect1> -<sect1 id="dbms.todo"> - <title> - TODO - - - -Consider if methods are least set or not. - -IO::Adapter - -is enough minimum ? - - - - - diff --git a/fml/doc/en/tutorial/internals/directory.sgml b/fml/doc/en/tutorial/internals/directory.sgml new file mode 100644 index 00000000..bee4dfd7 --- /dev/null +++ b/fml/doc/en/tutorial/internals/directory.sgml @@ -0,0 +1,49 @@ + + + + + + Directory + + + + + + Q: how recursively sub directory can be created ? + + + +The structore holding the html-ized article is as follows: + +200201/msg\d+.html + + + + +one sub-directory by default. + + + +Consider directory listing. +"ls" returns 1000 files soon, but 10000 files a little slowly. + + + +To accelerate listing, we should use sub-directory structure. +For example, each sub-directory holds 1000 files. +HTML 化されたファイルをおくサブディレクトリを 1000 ごとに用意すると、 +The structure such as "spool/sub/file" holds 10^6 ( million ) files +and +listing of it is fast. + + + +It must be enough to assume that 1 million articles for one ML. + + + + + + diff --git a/fml/doc/en/tutorial/internals/language.sgml b/fml/doc/en/tutorial/internals/language.sgml new file mode 100644 index 00000000..dc4aa124 --- /dev/null +++ b/fml/doc/en/tutorial/internals/language.sgml @@ -0,0 +1,224 @@ + + + + + + Language preference in processing + + + + + + Problems of language preference + + + +The simplest model is that we suppose we should return the japanese +message when the ML is configures as for Japanese. +This model needs the language of a ML is fixed. +This ML always returns the error message in Japanese. + + + +However, it is not proper to ignore Accept-Language: header field +since some Japanese people cannot read Japanese on the screen. +There may be invalid Accept-Language: field. +There are several problems. + + + +For example, if "Accept-Language: ja" is given, we can recognize the +language is "ja". However, how about the case Japanese send a mail +with the body content "help" (English) ? In that case we cannot +determine we should return the reply in us-ascii or iso-2022-jp. +For example, how about the following example ? + +Example: + +From: rudo@example.co.jp +Subject: help +mime-version: 1.0 +content-type: text/plain; charset=us-ascii + +help + + + + +We should return the English reply message based on charset +information since this message contains English only, so charset is +us-ascii. But this case we should return Japanese message since the +sender is a Japanese. So we should return the help message in both +English and Japanese if the ML is configures as Japanese +preferrable. If English is preferrable, the reply is English only. + + + +If Accept-Lanaguage: is specified, we prefer it. Even if the ML is +English preferrable (config: language_preference_order = en) and the +message with "Accept-Lanaguage: ja" is given, the ML returns the +Japanese help message. +&fml8; behaves like it. + + + + + + + + Japanese preferred ML + + + +language_preference_order variable controls the behaviour. +By default, an ML for Japanese is configures as + +language_preference_order = ja en + +&fml8; uses this hint. + + + + + + Accept-Language: ja, en + + + +&fml8; returns the message only in Japanese. + + + + + + + + Accept-Language: en + + + +&fml8; returns the message only in English. + + + + + + + + no Accept-Language:, Content-Type: charset=iso-2022-jp + + + +&fml8; returns the message only in Japanese. + + + + + + + + no Accept-Language:, Content-Type: charset=us-ascii + + + +We cannot determine the language. +We should return the message in both English and Japanese. + + + + + + + + no Accept-Language:, no Content-Type: + + + +We cannot determine the language. +We should return the message in both English and Japanese. + + + + + + + + + + English preferred ML + + + +By default, a ML for English people is configured as + +language_preference_order = en + +&fml8; uses this hints. + + + + + + Accept-Language: ja, en + + + +&fml8; returns the message only in Japanese. + + + + + + + + Accept-Language: en + + + +&fml8; returns the message only in English. + + + + + + + + no Accept-Language:, Content-Type: charset=iso-2022-jp + + + +&fml8; returns the message only in Japanese. + + + + + + + + no Accept-Language:, Content-Type: charset=us-ascii + + + +&fml8; returns the message only in English. + + + + + + + + no Accept-Language:, no Content-Type: + + + +&fml8; returns the message only in English. + + + + + + + + diff --git a/fml/doc/en/tutorial/internals/lock.sgml b/fml/doc/en/tutorial/internals/lock.sgml new file mode 100644 index 00000000..54b05194 --- /dev/null +++ b/fml/doc/en/tutorial/internals/lock.sgml @@ -0,0 +1,83 @@ + + + + + + Lock + + + +Synchronization among processes uses lock. +&fml8; provides flock(2) or lockf(2) based lock mechanism. + + + + + + Overview: lock + + + +After 2003/03, &fml8; provides more granular not giant lock. + + + +Each resource defines each lock channel name. + + + +For example, +Mail::Delivery related class accesses the member list. +It needs several locks. + + + +Mail::Delivery::SMTP needs lock of member list. +FML::Send and FML::Process::Delivery locks member list access +in callling Mail::Delivery::SMTP. + + + +Instead +Mail::Delivery::Queue just sees the mail queue. +The function can access the queue concurrently, also. +So this module does not need lock. + + + +Generally speaking, modules using maps require lock. +For example, +FML/Command/UserControl.pm and +FML/Command/Auth.pm +needs write lock, but +FML/Credential.pm +needs only read lock. + + + +It is useful if &fml8; provides reader writer lock. But it is not implemented. +Currently we attension we use short critical region. + + + + + + + + TODO + + + +mutex lock in calling *_maps. + + + +READER WRITER LOCK in calling IO::Adapter. + + + + + + diff --git a/fml/doc/en/tutorial/internals/main.cf.sgml b/fml/doc/en/tutorial/internals/main.cf.sgml new file mode 100644 index 00000000..43eaf7ef --- /dev/null +++ b/fml/doc/en/tutorial/internals/main.cf.sgml @@ -0,0 +1,119 @@ + + + + + + Example: /usr/local/etc/fml/main.cf + + + +/usr/local/etc/fml/main.cf is not specific. +This is meta file to define fundamental variables +e.g. fml version, directory path et.al. +&fml8; loader reads them. + + + +The format of main.cf is same as other .cf files: + + +file extension corresponds to the format. + + + +variable = value + +style. + + +# +# $FML: main.cf.sgml,v 1.10 2004/10/06 09:07:39 fukachan Exp $ +# + +# fml version +# This is important +# Example: fml 8.0 +# fml-current YYYYMMDD +# fml-devel YYYYMMDD +fml_version = current-20020701 + +fml_owner = fml + +fml_group = fml + + +### +### DIRECTORIES +### + +# Example: /usr/local +prefix = /usr/local +exec_prefix = ${prefix} + +# $config_dir holds the global main configuration and +# several version-dependent default configurations +# Example: /usr/local/etc/fml +config_dir = /usr/local/etc/fml + +# Example: /usr/local/etc/fml/defaults/$fml_version +default_config_dir = $config_dir/defaults/$fml_version + +# defined for convenience, for example, we need this variable +# at include, include-ctl, which needs expansion of ../libexec/fml/fml.pl +# Example: /usr/local/libexec/fml +executable_prefix = ${exec_prefix}/libexec/fml + +# Example: /usr/local/libexec/fml/$fml_version +libexec_dir = ${exec_prefix}/libexec/fml/$fml_version + +# Example: /usr/local/lib/fml/$fml_version +lib_dir = ${exec_prefix}/lib/fml/$fml_version + +# Example: /usr/local/share/fml/$fml_version +share_dir = ${prefix}/share/fml/$fml_version + +# site local library location +# which is prepared but not used by fml itself +local_lib_dir = ${exec_prefix}/lib/fml/site_local + + +# ml's home directories +# $ml_home_dir (e.g. /var/spool/ml/elena ) is taken from loader's @ARGV. +# This is compatible with fml 4.0. +# Example: /var/spool/ml +default_ml_home_prefix = /var/spool/ml + + + +### +### CONFIGURATION FILES AND DEFAULT PARAMETERS +### + + +# default domain +default_domain = fml.org + + +# version dependent default_config.cf location +# whic holds +# Example: /usr/local/etc/fml/defaults/8.0/default_config.cf +default_config_cf = $default_config_dir/default_config.cf + + +# domain specific configurations +# Example: /usr/local/etc/fml/domains/fml.org/default_config.cf +domain_default_config = $config_dir/domains/$default_domain/config.cf + + +# virtual format: domain directory +# for example, +# fml.org /var/spool/ml/fml.org +# nuinui.net /var/spool/ml/nuinui.net +virtual_maps = $config_dir/virtual + + + + + diff --git a/fml/doc/en/tutorial/internals/merge.sgml b/fml/doc/en/tutorial/internals/merge.sgml new file mode 100644 index 00000000..100172f5 --- /dev/null +++ b/fml/doc/en/tutorial/internals/merge.sgml @@ -0,0 +1,122 @@ + + + + + + Convert another ML system to &fml8; + + + + + + Implementation: &fml4; to &fml8; + + + + + Case 1: /var/spool/ml/elena/ from &fml4; to &fml8; + + + +This conversion does the following steps in fact. + + + +1) install &fml8; firstly. In this case, add +/var/spool/ml/etc/mail/aliases into $alias_maps of postfix main.cf. +/var/spool/ml/etc/mail/aliases may be empty. + + + +2) run "makefml --force newml elena" to create several files &fml8; +needs. + + + +3) convert address lists in /var/spool/ml/elena to &fml8; style. + + + +3-1) +IO::Adapter ignores a line beginning with '^#' as a comment. +We should handle carefully it since +"actives" file contains ^# lines as "off" address. + + + +3-2) +s=skip (off) options is ignored. +It handles as "on". + + + +3-3) +m=... (digest) options is ignored. + +Also, "# address" is "off" in the case of &fml4; but ignored in the +case of &fml8;. We should warn it ? + + + +4) remove the corresponding entry of alias file +(/var/spool/ml/etc/fml/aliases) of &fml4; and rebuild .db. + + + + + + + + Case 2: convert the whole /var/spool/ml/ from &fml4; to &fml8; + + + +Apply case 1 for all ML's. + + + +If we can stop all ML's, it is easy to remove +/var/spool/ml/etc/fml/aliases of &fml4; firstly and apply case 1 steps. +stop MTA in migration. + + + + + + + + Discussion: use half and half of &fml4; and &fml8; softwares. + + + +(X-Sequence: fml-devel 389) + + + +How in half and half case. + + + +For example, site_init.ph or config.ph of &fml4; follows + +[fml4] + +push(@ACTIVE_LIST,"$DIR/recipients") if( -f "$DIR/recipients" ) ; + +instead in the case of &fml8; +site_default_config.cf or config.cf follows: + +[fml8] + +html_archive_dir = $ml_home_dir/htdocs + + + + + + + + + diff --git a/fml/doc/en/tutorial/internals/restriction.sgml b/fml/doc/en/tutorial/internals/restriction.sgml new file mode 100644 index 00000000..60731434 --- /dev/null +++ b/fml/doc/en/tutorial/internals/restriction.sgml @@ -0,0 +1,202 @@ + + + + + + Restrict input data + + + +&fml8; checks the input by regular expression FML::Restriction class +provides. + + + + + + Overview: checks of input data + + + + + Restriction for article posting + + + +Restrictions for article are ambiguous or too restrictive. In fact +FML::Restriction class does not provide restriction rules for article +posting. + + + +Instead FML::Filter filter system checks each line of content. + + + + + + + + Restrictions for command mail + + + +FML::Process::Command class parses each line of the command mail and +checks the input by regular expressions FML::Restriction::Command +provides. If the check is passed, &fml8; calls +FML::Command::{User,Admin}::COMMAND at the next step. + + + + + + + + CGI + + + +CGI programs can receive the input from HTTP via only safe_param_XXX() +method. + + + +It is expected that +safe_param_*() +and +try_cgi_*() +returns the safe value. + + + +These safe_param_XXX() functions checks the input by regular +expressions FML::Restriction::CGI provides (FML::Restriction::CGI +inherits FML::Restriction::Base). + + + + + + + + makefml / fml + + + +CUI runs on the shell. +It means he/she who runs CUI has priviledge to log in the mailing list +server. +So it does not check the input. + + + +Each module checks the input independetly in that case +though no checks by FML::Restriction at the entrance. +For example, "adduser" module checks whether the input address +is valid or not even in the case of CUI. +These restrictions are dependent command specific modules. + + + + + + + + + + FML::Restriction class + + + +ACLs for the input data and commands are found at FML::Restriction +class. + + + +For example, CGI modules use FML::Restriction::CGI class to check +if the input data matches the proper regular expression. + + + +Though FML::Restriction inherits FML::Restriction::Base class, +fundamentally each module should use FML::Restriction as object +composition. For example, use in the following way: + +use FML::Restriction::CGI; +$safe = new FML::Restriction::CGI; +my $allowed_regexp = $safe->param_regexp(); + +if ($value =~ /^$allowed_regexp{$key}$) { ... ok, do something ... ;} + + + + + + + + + How CGI restricts the input + + + +CGI checks the input data by using FML::Restriction::CGI class. + + + +The input should be restricted by FML::Restriction class. +We should not use param() method provided by perl's CGI class. +Instead use safe_param_xxx() method always to get value. + + + +The following use may be allowed + +for my $dirty_buf (param()) { + ... check ... +} + +but we should not use raw param() call. + +param($dirtty_buf) + +Instead, use safe_param_key(). + +for my $key (param()) { + ... check ... + + if (key eq $key) { + value = safe_param_key() + } +} + + + + + + + + + Discussion: FML::Restriction is too restrictive ? + + + +FML::Restriction class allows a subset of RFC defined expression. + + + +RRC definition is too large. +It is too difficult to implement it ;-) +We restrict the expression a little. + + + +FML::Restriction::Command may be more granular but more granular +version is not implemented. + + + + + + diff --git a/fml/doc/en/tutorial/internals/struct.sgml b/fml/doc/en/tutorial/internals/struct.sgml index ab4e7002..2d42b866 100644 --- a/fml/doc/en/tutorial/internals/struct.sgml +++ b/fml/doc/en/tutorial/internals/struct.sgml @@ -1,5 +1,5 @@ @@ -9,7 +9,32 @@ -&struct.curproc; + + + curproc object + + + +Example of FML::Process::Distribute object. + + + &struct.curproc; + + + + + + + PCB category list + + + +PCB category list, which contains module and function relation. + + +&list.pcb; + + diff --git a/fml/doc/en/tutorial/internals/userctl.sgml b/fml/doc/en/tutorial/internals/userctl.sgml new file mode 100644 index 00000000..29bb95d5 --- /dev/null +++ b/fml/doc/en/tutorial/internals/userctl.sgml @@ -0,0 +1,57 @@ + + + + + + subscribe / unsubscribe + + + + + + which map subscribe/unsubscribe is operated to ? + + + +Subscribe/unsubscribe is operated to $primary_*map. + + + +For example, +subscription of remote administrators is operated into +both $primary_admin_member_map and $primary_admin_recipient_map. +unsubscription of remote administrators is operated into +both $primary_admin_member_map and $primary_admin_recipient_map. + + + +Why use primary_*_map ? +If we use admin_member_maps and admin_recipient_maps, it causes a problem. + + + +Subscription should be operated into one map. So we should operate it +into primary_*_map. + + + +Unsubscription must be same since xxx_maps is composed of different +privileged maps. + + + +For example, $member_maps is as follows. +It contais a list of member and a list of remote administrators. + +member_maps = $primary_member_map + $admin_member_maps + +So unsubscription operated for $member_maps may cause +unsubscription of remote administrators. It is wrong logic. + + + + + -- cgit v1.2.1