Mailfromd NEWS -- history of user-visible changes. 2007-04-25
Copyright (C) 2005, 2006, 2007 Sergey Poznyakoff
See the end of file for copying conditions.
Please send mailfromd bug reports to <bug-mailfromd@gnu.org.ua>
Version 3.1.92, SVN
* mtasim
The `mtasim' utility is an MTA simulator for testing and debugging
mailfromd filter scripts. It supports stdio (-bs) and daemon (-bd)
modes, has GNU readline support and `expect' facility, which makes it
useful in automated test cases.
See the documentation, chapter `mtasim'.
Version 3.1.91, 2007-04-23
* Non-blocking syslog
This version is shipped with non-blocking syslog implementation by
Simon Kelley. You may wish to enable it if you noticed that the
number of mailfromd processes grows uncontrollably and the processes
are hung for prolonged amounts of time. Usually this indicates that
the daemon blocks in syslog() calls. Read the description of
`--enable-syslog-async' option in chapter `Building' for the detailed
discussion of this (try `info -f doc/mailfromd.info --index-search
syslog-async').
* SPF support
The function check_host() tests the SPF record for the given
identity/host name. The syntax is:
number check_host(string ip, string domain, string sender, string helo)
See the documentation, node `SPF functions' for the detailed
description of this function and the related functions and variables.
* next and pass
Use `pass' instead of `next'.
The `next' keyword has changed its semantics: it is now used to
resume the next iteration of the enclosing loop statement (see
below).
For compatibility with the previous versions, its use outside of a
loop statement is still allowed, but a warning is issued. You are
encouraged to replace all occurrences of `next' in your configuration
scripts with `pass'.
* Loop
The loop statement is implemented. Its syntax is:
loop [name]
[for <stmt>,] [while <stmt>,] [<stmt>]
do
...
done [while <stmt>]
See the documentation, section `Loop Statements'.
* break and next
The `break' statement exits from the enclosing loop.
The `next' statement resumes the next iteration of the enclosing loop
statement.
Both statements take an optional argument specifying the identifier
(name) of the loop to break from (or continue), this allows to build
complex iterations consisting of nested loops. For example, in this
code (line numbers added for clarity):
1 loop outer for set i 1, while %i < %N
2 do
3 ...
4 loop for set j 1, while %j < %i
5 do
6 if foo(%j)
7 break outer
8 fi
9 done
10 done
11 accept
if the call to `foo' in line 6 returns true, the control is immediately passed
to `accept' in line 11.
* Resizable stack
The runtime stack of the MFL grows automatically as the need arises.
Thus, `#pragma stacksize' sets the initial size of the stack, and
the `Out of stack space' error, which was common in the previous
versions, now can occur only if there is no more virtual memory left.
Whenever the stack gets expanded, mailfromd issues a warning message
to the logs, notifying of the new stack size, e.g.:
warning: stack segment expanded, new size=8192
You can use these messages to adjust your stack size configuration
settings.
* Runtime stack traces
New command line option --stack-trace enables dumping stack traces
on runtime errors. This might help localize the source of the error.
The trace looks like:
mailfromd: RUNTIME ERROR near ../mflib/match_cidr.mf:30: invalid CIDR (boo%)
mailfromd: Stack trace:
mailfromd: 0077: test.mf:7: match_cidr
mailfromd: 0096: test.mf:13: bar
mailfromd: 0110: test.mf:18: foo
mailfromd: Stack trace finishes
mailfromd: Execution of the configuration program was not finished
Each trace line describes one stack frame, the lines appear in the
order of most recently called to least recently called. Each frame
consists of:
1. Value of program counter at the time of its execution
2. Source code location, if available
3. Name of the function called
The same output can be obtained by calling function stack_trace()
in your filter program.
See the documentation, section `Runtime Errors', for the detailed
description and examples.
* connect handler
Connect handler is implemented.
* envfrom and envrcpt
Both handlers take an additional second argument, containing the rest
of the SMTP command line.
* New functions
- string db_name(string fmt)
Return full file name of the database file corresponding to format
`fmt'
- number db_expire_interval(string fmt)
Return the expiration period for db format `fmt'
- string getmx(string domain [, number resolve])
Returns a whitespace-separated list of MX names (if `resolve' is not
given or is 0) or MX IP addresses (if `resolve'==1) for `domain'. If
`domain' has no MX records, empty string is returned. If the DNS
query fails, `getmx' raises an appropriate exception.
This interface differs from that of version 3.1.4 in that the calls to
getmx(domain) and getmx(domain,1) can return different number of
entries (see the docs for an example).
* #pragma regex stack
The `#pragma regex' statement can keep a stack of regex flags. The
stack is maintained using `push' and `pop' commands. The statement
#pragma regex push [options]
saves current regex flags on stack and then optionally modifies them
as requested by options.
The statement
#pragma regex pop [options]
does the opposite: restores the current regex flags from the top of
stack and applies [options] to it.
This statement is useful in include files to avoid disturbing user
regex settings. E.g.:
#pragma regex push +extended +icase
.
.
.
#pragma regex pop
* Optional arguments in user-defined functions
User-defined functions can take optional arguments. In a declaration,
optional arguments are separated from the mandatory ones by a
semicolon. For example:
func foo(number a, number b; string c)
This function is declared with two mandatory arguments (a and b), and
an optional one (c). Subsequently it can be invoked either as
foo(x, y, z)
or
foo(x, y)
When invoking such functions, any missing arguments are replaced with
default values:
- 0 for numeric arguments
- "" for string arguments
Thus, continuing our previous example, the invocation `foo(x, y)' is
equivalent to `foo(x, y, "")'.
* New statement #include_once
This statement works exactly like `#include' except that it keeps
track of the included files. If the requested file has already been
included, `#include_once' returns silently, while `#include' issues
an err
|