diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-11-04 16:43:33 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-11-04 16:43:33 +0200 |
commit | 4274008d26a3cc0cee44e410655cf31f17eb75f6 (patch) | |
tree | f34acd69d2fd326fa99e65233d6bac4bac1b5149 | |
parent | 9ce3f39943eee5fb703a86ece6c80f8f72ca74b6 (diff) | |
download | mailfromd-4274008d26a3cc0cee44e410655cf31f17eb75f6.tar.gz mailfromd-4274008d26a3cc0cee44e410655cf31f17eb75f6.tar.bz2 |
Improve docs.
* NEWS, doc/deprecate.texi,
doc/mailfromd.texi: Document new features.
* doc/sexp.texi: New file.
* doc/upgrade.texi: Update.
* mfd/bi_msg.m4 (message_read_line)
(message_read_body_line): Raise eof exception when there
are no more lines left.
-rw-r--r-- | NEWS | 9 | ||||
-rw-r--r-- | doc/Makefile.am | 1 | ||||
-rw-r--r-- | doc/deprecate.texi | 67 | ||||
-rw-r--r-- | doc/mailfromd.texi | 492 | ||||
-rw-r--r-- | doc/sexp.texi | 65 | ||||
-rw-r--r-- | doc/upgrade.texi | 14 | ||||
-rw-r--r-- | mfd/bi_msg.m4 | 4 |
7 files changed, 551 insertions, 101 deletions
@@ -1,4 +1,4 @@ -Mailfromd NEWS -- history of user-visible changes. 2009-10-20 +Mailfromd NEWS -- history of user-visible changes. 2009-11-04 Copyright (C) 2005, 2006, 2007, 2008, 2009 Sergey Poznyakoff See the end of file for copying conditions. @@ -40,7 +40,7 @@ the source. Starting with this release the script file is renamed to `mailfromd.rc' is recognized and parsed. This ensures backward compatibility. -** Pies removed +** Pies withdrawn The `pies' utility has been removed from the package. It is moved into a stand-alone package called `Pies'. See @@ -85,6 +85,11 @@ Use `.' operator instead. See `Explicit concatenation', below. The `#require' keyword is deprecated. Use `require' instead. See `Module system', for details. +** message_read_line, message_read_body_line and EOF + +These functions raise EOF exception if there are no more lines to read. +In previous version, e_io was signalled in this case. + * Upgrade procedure To remove the deprecated features from your scripts and upgrade them diff --git a/doc/Makefile.am b/doc/Makefile.am index d8956df5..c5e409e6 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -25,6 +25,7 @@ mailfromd_TEXINFOS=\ pragma-database.texi\ pragma-option.texi\ rendition.texi\ + sexp.texi\ smap.texi\ strftime.texi\ upgrade.texi\ diff --git a/doc/deprecate.texi b/doc/deprecate.texi index 29e35a77..87f6af4f 100644 --- a/doc/deprecate.texi +++ b/doc/deprecate.texi @@ -23,13 +23,69 @@ @node implicit concatenation @appendixsec Implicit Concatenation and Operational Syntax -@UNREVISED + Implicit concatenation and operational syntax are two deprecated +features still supported by @command{mailfromd} version +@value{VERSION}. These features will disappear in the next release, +so you are advised to update your scripts if they still use them. +@xref{5x0-600, upgrade your scripts}, for a description of the upgrade +procedure. + + @dfn{Implicit concatenation} is performed wherever the compiler +encounters two adjacent variables or adjacent variable and literal. +Notice, that it does not affect implicit concatenation of adjacent +literals, which is supported as before. That is, the following is +correct: + +@smallexample + echo "GNU's" " not " " UNIX" +@end smallexample + +@noindent +whereas the following is deprecated: + +@smallexample + echo %y %z +@end smallexample + + When compiler encounters such a construct, it acts as if there were +a @samp{.} (dot) operator between the variables +(@pxref{Concatenation}), and issues the following warning: + +@smallexample +@var{file}:@var{line}: implicit concatenation is deprecated +@var{file}:@var{line}: use `.' operator +@end smallexample -@quotation -@i{It seemed like a good idea at the time.}@* -Brian Kernighan -@end quotation + @dfn{Operationa syntax} consists in calling a function of one +argument without parentheses around the actual parameter, e.g.: + +@smallexample + set x primitive_hostname $client_addr +@end smallexample + +@noindent +instead of: + +@smallexample + set x primitive_hostname($client_addr) +@end smallexample + + If such usage is encountered, the compiler issues the following +warning: + +@smallexample +@var{file}:@var{line}: use of function name as a prefix operator is +deprecated +@end smallexample + + Both features brought more trouble than advantage, and therefore +I decided to remove them. Please, update your scripts, if you are +still using them. For the sake of completeness, here is what +the documentation for previous versions of @command{mailfromd} +said on the subject: + +@quotation There are some features of @acronym{MFL} which, when used improperly, may lead to subtle, hard identifiable errors. These are: concatenation operation (@pxref{Concatenation}) and passing arguments to @@ -55,6 +111,7 @@ doubt, parenthesize: echo toupper("some" "thing") @result{} "SOMETHING" echo toupper("some") "thing" @result{} "SOMEthing" @end smallexample +@end quotation @node old-style function declarations @appendixsec Old-Style Function Declarations diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi index b1bf4772..efa1b985 100644 --- a/doc/mailfromd.texi +++ b/doc/mailfromd.texi @@ -121,8 +121,9 @@ Appendices * Gacopyz:: * Time and Date Formats:: -* Upgrading:: +* s-expression:: * Deprecated Features:: +* Upgrading:: * Copying This Manual:: The GNU Free Documentation License. * Concept Index:: Index of Concepts. @@ -158,6 +159,7 @@ Tutorial * SMTP Timeouts:: * Avoiding Verification Loops:: * HELO Domain:: +* rset:: * Controlling Number of Recipients:: * Sending Rate:: * Greylisting:: @@ -269,7 +271,7 @@ Expressions * Constant expressions:: String and Numeric Constants. * Function calls:: A Function Call is an Expression. -* Concatenation:: Adjacent Expressions Concatenate. +* Concatenation:: String Concatenation. * Arithmetic operations:: @samp{+}, @samp{-}, etc. * Relational expressions:: @samp{=}, @samp{<}, etc. * Special comparisons:: @code{matches}, @code{mx matches}, etc. @@ -287,10 +289,17 @@ Statements @c Conditionals @c Exception handlers +Modules + +* module structure:: Declaring Modules +* scope of visibility:: +* import:: Require and Import + Configuring @command{mailfromd} * conf-types:: Special Configuration Data Types * conf-base:: Base Mailfromd Configuration +* conf-milter:: Milter Connection Configuration * conf-debug:: Logging and Debugging configuration * conf-timeout:: Timeout Configuration * conf-callout:: Call-out Configuration @@ -348,9 +357,13 @@ Deprecated Features * pragma-option:: * pragma-database:: +* implicit concatenation:: +* old-style function declarations:: +* operational notation:: Upgrading +* 5x0-600:: Upgrading from 5.x to 6.0 * 500-510:: Upgrading from 5.0 to 5.1 * 440-500:: Upgrading from 4.4 to 5.0 * 43x-440:: Upgrading from 4.3.x to 4.4 @@ -1139,6 +1152,7 @@ detailed discussion of the mail filtering language and * SMTP Timeouts:: * Avoiding Verification Loops:: * HELO Domain:: +* rset:: * Controlling Number of Recipients:: * Sending Rate:: * Greylisting:: @@ -1292,7 +1306,7 @@ be rejected. When returned by any other handler, it causes the whole message will be rejected. The @code{reject} and @code{tempfail} actions executed by -@code{helo} handler do not take effect immediately. Instead their +@code{helo} handler do not take effect immediately. Instead, their action is deferred until the next @acronym{SMTP} command from the client, which is usually @code{MAIL FROM}. @@ -1504,7 +1518,7 @@ as a statement. @cindex built-in and library functions, introduced @cindex library and built-in functions, introduced @cindex module, defined -@cindex #require, introduced +@kwindex require @command{Mailfromd} comes with a rich set of predefined functions for various purposes. There are two basic function classes: @dfn{built-in} functions, that are implemented by the @acronym{MFL} @@ -1515,18 +1529,18 @@ calling them. In contrast, the library functions are defined in @dfn{modules}, special @acronym{MFL} source files that contain functions designed for a particular task. In order to access a library function, you must first @dfn{require} a module it is defined in. -This is done using @code{#require} statement. For example, the +This is done using @code{require} statement. For example, the function @code{hostname} looks up in the @acronym{DNS} the name corresponding to the @acronym{IP} address specified as its argument. This function is defined in module @file{dns.mf}, so before calling it you must require this module: @smallexample -#require dns +require dns @end smallexample @noindent -The @code{#require} statement takes a single argument: the name of the +The @code{require} statement takes a single argument: the name of the requested module (without the @samp{.mf} suffix). It looks up the module on disk and loads it if it is available. @@ -1926,6 +1940,42 @@ done @end group @end smallexample +@node rset +@section SMTP RSET and Milter Abort Handling +@cindex RSET +@cindex milter abort + In previous section we have used a global variable to hold certain +information and share it between hanlders. In the majority of cases, +such information is session specific, and becomes invalid if the +remote party issues the SMTP @code{RSET} command. Therefore, +@command{mailfromd} clears all global variables when it receives a +Milter @samp{abort} request, which is normally generated by this +command. + +@kwindex precious +@cindex precious variables +@cindex variable, precious + However, you may need some variables that will retain their values +even across SMTP session resets. In @command{mailfromd} terminology +such variables are called @dfn{precious}. Precious variables are +declared by prefixing their declaration with the keyword +@code{precious}. Consider, for example, this snippet of code: + +@smallexample +precious number rcpt_counter + +prog envrcpt +do + set rcpt_counter %rcpt_counter + 1 +done +@end smallexample + + Here, the variable @samp{rcpt_counter} is declared as precious and +its value is incremented each time the @samp{envrcpt} handler is +called. This way, @samp{rcpt_counter} will keep the total number of +SMTP @code{RCPT} commands issued during the session, no matter how +many times it was restarted using the @code{RSET} command. + @node Controlling Number of Recipients @section Controlling Number of Recipients @@ -2075,7 +2125,7 @@ returns @code{False} and does not update the database. following statement somewhere at the beginning of your script: @smallexample -#require rateok +require rateok @end smallexample For example, the following code limits the mail sending rate for each @@ -2085,7 +2135,7 @@ temporary failure response: @smallexample @group -#require rateok +require rateok prog envfrom do @@ -2755,6 +2805,22 @@ expecting OR or AND or ')' @end group @end smallexample +@xopindex{location-column, described} + The error location is indicated by the name of the file and the +number of the line when the error occurred. By using the +@option{--location-column} option you instruct @command{mailfromd} to +also print the @dfn{column number}. E.g. with this option the above +error message may look like: + +@smallexample +@group +mailfromd: /etc/mailfromd.mf:39:12 syntax error, unexpected ACT_REJECT, +expecting OR or AND or ')' +@end group +@end smallexample + + Here, @samp{39} is the line and @samp{12} is the column number. + @cindex cross-reference For complex scripts you may wish to obtain a listing of variables used in the script. This can be achieved using @option{--xref} @@ -3587,14 +3653,16 @@ debugging, or in your @code{catch} statements. @node Notes @section Notes and Cautions -@UNREVISED - Another place to execute special caution are format strings used -with @code{sprintf} (@pxref{String formatting}) and @code{strftime} + This section discussess some potential culprits in the +@acronym{MFL}. + + It is important to execute special caution when writing format +strings for @code{sprintf} (@pxref{String formatting}) and @code{strftime} (@pxref{strftime}) functions. They use @samp{%} as a character introducing conversion specifiers, while the same character is used to expand a @acronym{MFL} variable within a string. To prevent this -misinterpretation, enclose format specification in @emph{single +misinterpretation, always enclose format specification in @emph{single quotes} (@pxref{singe-vs-double}). To illustrate this, let's consider the following example: @@ -4360,13 +4428,15 @@ result in raising a @code{e_macroundef} exception at the run time Constants are defined using @code{const} statement: @smallexample -const @var{name} @var{expr} +[@var{qualifier}] const @var{name} @var{expr} @end smallexample @noindent where @var{name} is an identifier, and @var{expr} is any valid @acronym{MFL} expression evaluating immediately to a constant literal -or numeric value. +or numeric value. Optional @var{qualifier} defines the scope of +visibility for that constant (@pxref{scope of visibility}): either +@code{public} or @code{static}. @cindex constants, using in program text After defining, any appearance of @var{name} in the program text is @@ -4522,27 +4592,40 @@ These memory regions are identified by @dfn{variable names}. A variable name must begin with a letter or underscore and must consist of letters, digits and underscores. - Each variable is associated with its @dfn{lexical scope}, i.e. the -part of source code where it can be used. Depending on the scope we -discern two main classes of variables: global and automatic ones. +@cindex scope of visibility, variables +@cindex variable lexical scope +@anchor{variable scope} + Each variable is associated with its @dfn{scope of visibility}, +which defines the part of source code where it can be used +(@pxref{scope of visibility}). Depending on the scope we discern +three main classes of variables: public, static and automatic (or local). + + @dfn{Public variables} have indefinite lexical scope, so they may +be referred to anywhere in the program. @dfn{Static} are variables +visible only within their module (@pxref{Modules}). @dfn{Automatic} +or @dfn{local variables} are visible only within the given function or +handler. - @dfn{Global variables} have indefinite lexical scope, so they may -be referred to anywhere in the program. @dfn{Automatic} or @dfn{local -variables} are visible only within the given function or handler. + Public and static variables are sometimes collectively called +@dfn{global}. - The two variable classes occupy separate @dfn{namespaces}, so that an -automatic variable can have the same name as an existing global one. -In this case this variable is said to @dfn{shadow} its global + These variable classes occupy separate @dfn{namespaces}, so that an +automatic variable can have the same name as an existing public or +static one. In this case this variable is said to @dfn{shadow} its global counterpart. All references to such a name will refer to the automatic variable until the end of its scope is reached, where the global one becomes visible again. + Likewise, a static variable may have the same name as a static +variable defined in another module. However, it may not have the +same name as a public variable. + @cindex variables, declaring @cindex variable declarations A variable is @dfn{declared} using the following syntax: @smallexample -@var{type} @var{name} +[@var{qualifiers}] @var{type} @var{name} @end smallexample @noindent @@ -4556,7 +4639,36 @@ variables and @samp{number} for numeric ones. string var @end smallexample - Declaration can be followed by any valid @acronym{MFL} +@cindex qualifiers, variable declaration +@kwindex public +@kwindex static +Optional @var{qualifiers} are allowed only in global declarations, i.e. +in the variable declarations that appear outside of functions. They +specify the scope of the variable. The @code{public} qualifier +declares the variable as public and the @code{static} qualifier +declares it as static. The default scope is @samp{public}, +unless specified otherwise in the module declaration (@pxref{module +structure}). + +@kwindex precious +@cindex variables, precious +Additionally, @var{qualifiers} may contain the word @code{precious}, +which instructs the compiler to mark this variable as @dfn{precious}. +(@pxref{rset,, precious variables}). If both scope qualifier and +@code{precious} are used, they may appear in any order, e.g.: + +@smallexample +static precious string rcpt_list +@end smallexample + +@noindent +or + +@smallexample +precious static string rcpt_list +@end smallexample + + The declaration can be followed by any valid @acronym{MFL} expression, which supplies the @dfn{initial value} for the variable, for example: @@ -5651,7 +5763,7 @@ module (@pxref{Modules}). Examples: @smallexample -#require strip_domain_part +require strip_domain_part strip_domain_part("puszcza.gnu.org.ua", 2) @result{} "org.ua" strip_domain_part("puszcza.gnu.org.ua", 0) @result{} "gnu.org.ua" @end smallexample @@ -5666,7 +5778,7 @@ function is defined in @file{is_ip.mf} module (@pxref{Modules}). For example: @smallexample -#require is_ip +require is_ip is_ip("1.2.3.4") @result{} 1 is_ip("1.2.3.x") @result{} 0 @@ -6386,8 +6498,7 @@ message_lines(@var{x}) = message_body_lines(@var{x}) @deftypefn {Built-in Function} string message_read_body_line (number @var{nmsg}) Read and return next line from the body of message @var{nmsg}. If -there are no more lines to read, raise the @code{not_found} exception. -@FIXME{Probably a special exception type is needed for that.} +there are no more lines to read, raise the @code{eof} exception. Use @code{message_body_rewind} (see above) to rewind the body stream and read its contents again. @@ -6395,7 +6506,7 @@ and read its contents again. @deftypefn {Built-in Function} string message_read_line (number @var{nmsg}) Read and return next line from message @var{nmsg}. If -there are no more lines to read, raise the @code{not_found} exception. +there are no more lines to read, raise the @code{eof} exception. Use @code{message_rewind} to rewind the message stream and read its contents again. @@ -6654,7 +6765,7 @@ without throwing exceptions. available after requesting @file{dns.mf} module (@pxref{Modules}): @smallexample -#require dns +require dns @end smallexample @deftypefn {Built-in Function} string dns_getaddr (string @var{domain}) @@ -6695,7 +6806,7 @@ getmx("org.pl") @result{} "" @emph{Notes}: @enumerate 1 @item The @code{getmx} function returns at most 32 @acronym{MX} names or @acronym{IP} addresses. -@FIXME{This limit should probably be configurable.} +@FIXME{This limit should be configurable.} @item The number of items returned by @code{getmx(@var{domain})} can differ from that obtained from @code{getmx(@var{domain}, 1)}, e.g.: @@ -7124,7 +7235,7 @@ interfaces, which return cleanly if the @samp{e_dbfailure} exception occurs. To use these interfaces, request the @file{safedb.mf} module: @smallexample -#require safedb +require safedb @end smallexample The exception-safe interfaces are: @@ -7456,7 +7567,7 @@ If it does not return a meaningful value, @code{localdomain} calls the machine, and returns its domain part. To use this function, require @file{localdomain.mf} module -(@pxref{Modules}), e.g.: @code{#require localdomain}. +(@pxref{Modules}), e.g.: @code{require localdomain}. @end deftypefn @deftypefn {Built-in Function} number time () @@ -7934,7 +8045,7 @@ we advise to use the @code{rateok} function, described below. @flindex rateok.mf To use this function, require @file{rateok.mf} module -(@pxref{Modules}), e.g.: @code{#require rateok}. +(@pxref{Modules}), e.g.: @code{require rateok}. The @code{rateok} function returns @samp{True} if the mail sending rate for @var{key}, computed for the interval of @var{sample-interval} @@ -8015,7 +8126,7 @@ To use this function, require @file{valid_domain.mf} module (@pxref{Modules}): @smallexample -#require valid_domain +require valid_domain @end smallexample @end deftypefn @@ -8461,7 +8572,7 @@ verification in @code{envfrom} handler: @smallexample #include_once <status.mfh> -#require spf +require spf prog envfrom do @@ -8846,7 +8957,7 @@ the message domain. By default @var{dirname} is To summarize all the above, the usual @acronym{NLS} setup will look like: @smallexample -#require nls +require nls begin do @@ -9087,7 +9198,7 @@ invoked. @cindex @code{func} statement, function definition @smallexample @group -func @var{name} (@var{param-decl}) returns @var{data-type} +[@var{qualifier}] func @var{name} (@var{param-decl}) returns @var{data-type} do @var{function-body} done @@ -9108,6 +9219,23 @@ Variable declarations}), i.e.: declares the parameter @var{name} having the type @var{type}. The @var{type} is @code{string} or @code{number}. +@cindex qualifier, function declaration +@kwindex public +@kwindex static +@cindex scope of visibility, functions +@anchor{function scope of visibility} + Optional @var{qualifier} declares the scope of visibility for that +function (@pxref{scope of visibility}). It is similar to that of +variables, except that functions cannot be local (i.e. you cannot +declare function within another function). + + The @code{public} qualifier declares a function that may be referred +to from any module, whereas the @code{static} qualifier declares a +function that may be called only from the current module +(@pxref{Modules}). The default scope is @samp{public}, +unless specified otherwise in the module declaration (@pxref{module +structure}). + For example, the following declares a function @samp{sum}, that takes two numeric arguments and returns a numeric value: @@ -9115,6 +9243,12 @@ two numeric arguments and returns a numeric value: func sum(number x, number y) returns number @end smallexample + Similarly, the following is a declaration of a static function: + +@smallexample +static func sum(number x, number y) returns number +@end smallexample + Parameters are referenced in the @var{function-body} by their name, using the syntax for variable references: @code{%@var{name}}. The value of a parameter can be altered using @code{set} statement, the @@ -9365,8 +9499,8 @@ shows definitions of some of the library functions shipped with @command{mailfromd}. These functions are contained in modules installed along with the @command{mailfromd} binary. To use any of them in your code, require the appropriate module as described in -@FIXME-ref{require}, e.g. to use the @code{revip} -function, do @code{require 'revip'}. +@ref{import}, e.g. to use the @code{revip} function, do +@code{require 'revip'}. Functions and their definitions: @@ -9432,7 +9566,7 @@ definition follows: @smallexample @group -#require dns +require dns func valid_domain(string domain) returns number do @@ -9448,8 +9582,8 @@ The function @code{match_dnsbl} (@pxref{match_dnsbl}) is defined as follows: @smallexample -#require dns -#require match_cidr +require dns +require match_cidr #pragma regex push +extended func match_dnsbl(string address, string zone, string range) @@ -9495,7 +9629,7 @@ assigned to a variable or passed to a function. @menu * Constant expressions:: String and Numeric Constants. * Function calls:: A Function Call is an Expression. -* Concatenation:: Adjacent Expressions Concatenate. +* Concatenation:: String Concatenation. * Arithmetic operations:: @samp{+}, @samp{-}, etc. * Relational expressions:: @samp{=}, @samp{<}, etc. * Special comparisons:: @code{matches}, @code{mx matches}, etc. @@ -9817,7 +9951,7 @@ String concatenation @cindex type casts, implicit @cindex implicit type casts When two operands on each side of a binary expression have -different type, @command{mailfromd} evaluator has to coerce them to a +different type, @command{mailfromd} evaluator coerces them to a common type. This is known as @dfn{implicit type casting}. The rules for implicit type casting are: @@ -9843,6 +9977,7 @@ left-hand side argument. @cindex type casts, explicit @cindex explicit type casts +@anchor{explicit type casts} The construct for explicit type cast is: @smallexample @@ -10975,8 +11110,8 @@ nested statements. @FIXME{Elaborate on that.} argument must be an immediate value, you cannot use an expression in its place. Secondly, its range is limited to exception codes, described in @ref{status.mfh}. In other words, you cannot (yet) -invent your own exception types. @FIXME{This should be fixed in -future releases.} +invent your own exception types. @FIXME{This is fixed in the +@samp{mtax-cleanup} branch.} @node Polling @section Sender Verification Tests @@ -11225,31 +11360,202 @@ done @section Modules @cindex module, defined - A module is an @acronym{MFL} source file containing a collection of -conceptually united functions and data. Currently, there are no -special syntax rules that make an arbitrary source file a module, it -suffices to make sure the module name ends in standard suffix -@samp{.mf} and place it in one of the directories comprising the include -source path (@pxref{include search path}). However, such syntax rules -will appear in future versions. It is planned that modules will be -compiled and stored on disk in form of object files or combined into -libraries. + A @dfn{module} is a logically isolated part of code that implements a +separate concern or feature and contains a collection of conceptually +united functions and/or data. Each module occupies a separate +compilation unit (i.e. file). The functionality provided by +a module is incorporated into another module or the main program by +@dfn{requiring} this module or by @dfn{importing} the desired +components from it. - In order to make definitions from module @file{@var{modname}.mf} -available to your filter program, use the following statement: +@menu +* module structure:: Declaring Modules +* scope of visibility:: +* import:: Require and Import +@end menu + +@node module structure +@subsection Declaring Modules +@cindex module declaration +@kwindex module + A module file must begin with a @dfn{module declaration}: @smallexample -#require @var{modname} +module @var{modname} [@var{interface-type}]. @end smallexample -@FIXME{require} -@ignore -The @code{#require} statement looks up the module -@file{@var{modname}.mf} in the include path and attempts to compile -it (@pxref{require}). It is not an error to require the same module -several times. However, requiring a non-existing module results in -compilation error. -@end ignore + Note the final dot. + +The @var{modname} parameter declares the name of the module. It is +recommended that it be the same as the file name without the +@samp{.mf} extension. The module name must be a valid @acronym{MFL} +literal. It also must not coincide with any defined @acronym{MFL} +symbol, therefore we recommend to always quote it (see example below). + +The optional parameter @var{interface-type} defines the @dfn{default +scope of visibility} for the symbols declared in this module. If it is +@samp{public}, then all symbols declared in this module are made +public (importable) by default, unless explicitly declared otherwise +(@pxref{scope of visibility}). If it is @samp{static}, then all +symbols, not explicitly marked as public, become static. If the +@var{interface-type} is not given, @samp{public} is assumed. + +The actual @acronym{MFL} code follows the @samp{module} line. + +The module definition is terminated by the @dfn{logical end} of its +compilation unit, i.e. either by the end of file, or by the +keyword @code{bye}, whichever occurs first. + +@kwindex bye +Special keyword @code{bye} may be used to prematurely end the current +compilation unit before the physical end of the containing file. +Any material between @code{bye} and the end of file is ignored by the +compiler. + +Let's illustrate these concepts by writing a module @samp{revip}: + +@smallexample +@group +module 'revip' public. + +func revip(string ip) + returns string +do + return inet_ntoa(ntohl(inet_aton(%ip))) +done + +bye + +This text is ignored. You may put any additional +documentation here. +@end group +@end smallexample + +@node scope of visibility +@subsection Scope of Visibility +@cindex scope of visibility + @dfn{Scope of Visibility} of a symbol defines from where this symbol +may be referred to. Symbols in @acronym{MFL} may have either of the +following two scopes: + +@table @dfn +@item Public + Public symbols are visible from the current module, as well as from +any external modules, including the main script file, provided that +they are properly imported (@pxref{import}). + +@item Static + Static symbols are visible only from the current module. There is +no way to refer to them from outside. +@end table + + The default scope of visibility for all symbols declared within +a module is defined in the module declaration (@pxref{module +structure}). It may be overridden for any individual symbol by +prefixing its declaration with an appropriate @dfn{qualifier}: either +@code{public} or @code{static}. + +@node import +@subsection Require and Import +@cindex importing from modules +@cindex requiring modules + Functions or variables declared in another module must be @dfn{imported} +prior to their actual use. @acronym{MFL} provides two ways of doing +so: by @dfn{requiring} the entire module or by importing selected +symbols from it. + +@deffn {Module Import} require modname + The @code{require} statement instructs the compiler to locate the +module @var{modname} and to load all public interfaces from it. +@end deffn + + The compiler looks for the file @file{@var{modname}.mf} in the +current search path (@pxref{include search path}). If no such file +is found, a compilation error is reported. + + For example, the following statement: + +@smallexample +require revip +@end smallexample + +@noindent +imports all interfaces from the module @file{revip.mf}. + +@kwindex from +@kwindex import +@cindex @code{from @dots{} import} + Another, more sophisticated way to import from a module is to use +the @samp{from ... import} construct: + +@smallexample +from @var{module} import @var{symbols}. +@end smallexample + +Note the final dot. The @samp{from} and @samp{module} statements are +the only two constructs in @acronym{MFL} that require the delimiter. + +The @var{module} has the same semantics as in the @code{require} +construct. The @var{symbols} is a comma-separated list of symbol +names to import from @var{module}. A symbol name may be given in +several forms: + +@enumerate 1 +@item Literal + +Literals specify exact symbol names to import. For example, +the following statement imports from module @file{A.mf} symbols +@samp{foo} and @samp{bar}: + +@smallexample +from A import foo,bar. +@end smallexample + +@item Regular expression + +Regular expressions must be surrounded by slashes. A regular +expression instructs the compiler to import all symbols whose +names match that expression. For example, the following statement +imports from @file{A.mf} all symbols whose names begin with @samp{foo} +and contain at least one digit after it: + +@smallexample +from A import '/^foo.*[0-9]/'. +@end smallexample + +The type of regular expressions used in the @samp{from} statement is +controlled by @code{#pragma regex} (@pxref{regex}). + +@item Regular expression with transformation + +Regular expression may be followed by a @dfn{s-expression}, i.e. a +@command{sed}-like expression of the form: + +@smallexample +s/@var{regexp}/@var{replace}/[@var{flags}] +@end smallexample + +@noindent +where @var{regexp} is a @dfn{regular expression}, @var{replace} is a +replacement for each part of the input that matches @var{regexp}. +S-expressions and their parts are discussed in detail in +@ref{s-expression}. + +The effect of such construct is to import all symbols that match the +regular expression and apply the s-expression to their names. + +For example: + +@smallexample +from A import '/^foo.*[0-9]/s/.*/my_&/'. +@end smallexample + +This statement imports all symbols whose names begin with @samp{foo} +and contain at least one digit after it, and renames them, by prefixing +their names with the string @samp{my_}. Thus, if @file{A.mf} declared a +function @samp{foo_1}, it becomes visible under the name of @samp{my_foo_1}. + +@end enumerate @node Preprocessor @section @acronym{MFL} Preprocessor @@ -11420,12 +11726,15 @@ with this option, because @command{mailfromd} cannot verify whether @node Filter Script Example @section Example of a Filter Script File - This section will show a working example of the filter script file. -For the ease of illustration, it is divided in several sections. -Each section is prefaced with a comment explaining its function. + In this section we will discuss a working example of the filter +script file. For the ease of illustration, it is divided in several +sections. Each section is prefaced with a comment explaining its +function. -@FIXME{Example of config: + This filter assumes that the @file{mailfromd.conf} file contains the +following: +@smallexample relayed-domain-file (/etc/mail/sendmail.cw, /etc/mail/relay-domains); io-timeout 33; @@ -11433,9 +11742,14 @@ database cache @{ negative-expire-interval 1 day; positive-expire-interval 2 weeks; @}; -} +@end smallexample + + Of course, the exact parameter settings may vary, what is important +is that they be declared. @xref{Mailfromd Configuration}, for a +description of @command{mailfromd} configuration file syntax. - The first part defines the configuration settings for this host: + Now, let's return to the script. Its first part defines the +configuration settings for this host: @smallexample #pragma regex +extended +icase @@ -11915,10 +12229,10 @@ Mailutils Manual}. @node conf-types @section Special Configuration Data Types -@UNREVISED - In addition to the usual mailutils data types (@pxref{S |