aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2008-03-10 13:43:22 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2008-03-10 13:43:22 +0000
commit18ebe7bb829772d7bf1df49d23a2c9dd53a2afcd (patch)
tree51b017fdad8d712f2aa4f7a5d505032acc2e9185
parent9fe06f87591f813fce7f9068f19246c8d933fc6a (diff)
downloadmailfromd-18ebe7bb829772d7bf1df49d23a2c9dd53a2afcd.tar.gz
mailfromd-18ebe7bb829772d7bf1df49d23a2c9dd53a2afcd.tar.bz2
* src/mailfromd.h (enum mf_status_code): Add a comma and a count
definition, needed for make check-exceptions in docs. * src/status.mfi (m4_ifdef): Use OLD_EXCEPTION_CODES instead of COMPAT_4_3. * src/main.c: New command line options: -D (--define), and -U (--undefine). * mflib/match_dnsbl.mf (match_dnsbl): Use LAZY_MATCH_RBL instead of COMPAT_4_3. Throw e_invip if address is invalid. * mflib/match_rhsbl.mf (match_rhsbl): Use LAZY_MATCH_RBL instead of COMPAT_4_3. * doc/mailfromd.texi: Document variable shadowing and new features. * doc/Makefile.am (check-exceptions): Update the rule. * NEWS: Update. git-svn-id: file:///svnroot/mailfromd/branches/release_4_3_patches@1630 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r--ChangeLog22
-rw-r--r--NEWS62
-rw-r--r--doc/Makefile.am2
-rw-r--r--doc/mailfromd.texi402
-rw-r--r--mflib/match_dnsbl.mf4
-rw-r--r--mflib/match_rhsbl.mf2
-rw-r--r--src/mailfromd.h4
-rw-r--r--src/main.c65
-rw-r--r--src/status.mfi2
9 files changed, 534 insertions, 31 deletions
diff --git a/ChangeLog b/ChangeLog
index 239eda1c..9972d196 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,24 @@
+2008-03-10 Sergey Poznyakoff <gray@gnu.org.ua>
+
+ * src/mailfromd.h (enum mf_status_code): Add a comma and a count
+ definition, needed for make check-exceptions in docs.
+ * src/status.mfi (m4_ifdef): Use OLD_EXCEPTION_CODES instead of
+ COMPAT_4_3.
+ * src/main.c: New command line options: -D (--define), and -U
+ (--undefine).
+ * mflib/match_dnsbl.mf (match_dnsbl): Use LAZY_MATCH_RBL instead of
+ COMPAT_4_3.
+ Throw e_invip if address is invalid.
+ * mflib/match_rhsbl.mf (match_rhsbl): Use LAZY_MATCH_RBL instead
+ of COMPAT_4_3.
+ * doc/mailfromd.texi: Document variable shadowing and new
+ features.
+ * doc/Makefile.am (check-exceptions): Update the rule.
+ * NEWS: Update.
+
2008-03-09 Sergey Poznyakoff <gray@gnu.org.ua>
Fix the test suite. The file status.mfh now contains m4 statements,
yet the test suite uses --no-preproc files, so we have to use an
already preprocessed version of that file.
@@ -66,12 +84,16 @@
Remove buggy conditions. Provide a correctly working replacement
for them if the m3 symbol `COMPAT_4_3' is defined.
* mflib/match_cidr.mf, mflib/safedb.mf4, tests/etc/catch.rc,
tests/etc/catch01.rc: Use new exception codes.
2008-03-01 Sergey Poznyakoff <gray@gnu.org.ua>
+
+ -= Release 4.3.1 =-
+
+2008-03-01 Sergey Poznyakoff <gray@gnu.org.ua>
* src/prog.c, src/prog.h (advance_pc): Fix type of the 2nd
argument.
* configure.ac: Use AC_TRY_LINK to check for libresolve.
2008-02-21 Sergey Poznyakoff <gray@gnu.org.ua>
diff --git a/NEWS b/NEWS
index 25ba9d4d..09dbea34 100644
--- a/NEWS
+++ b/NEWS
@@ -1,15 +1,75 @@
-Mailfromd NEWS -- history of user-visible changes. 2008-03-09
+Mailfromd NEWS -- history of user-visible changes. 2008-03-10
Copyright (C) 2005, 2006, 2007, 2008 Sergey Poznyakoff
See the end of file for copying conditions.
Please send mailfromd bug reports to <bug-mailfromd@gnu.org.ua>
Version 4.3.90 (SVN)
+* The --domain option is withdrawn.
+
+This option was declared as deprecated in version 4.0. Now it is
+withdrawn and its short version (-D) is reused for another purpose
+(see -D option, below).
+
+* New command line options -D and -U
+
+Both options work like their m4 counterpars: the `-D' command line
+option defines a preprocessor symbol, the `-U' option undefines it.
+
+* Constant vs. variable shadowing
+
+In previous versions of mailfromd name clashes between constants and
+variables went unnoticed, which sometimes lead to hard-to-diagnose
+errors. This bug is fixed in this version. If a constant is defined
+which has the same name as a previously defined variable (the constant
+"shadows" the variable), the compiler prints the following diagnostic
+message:
+
+<file>:<line>: Warning: Constant name `name' clashes with a variable name
+<file>:<line>: Warning: This is the location of the previous definition
+
+A similar diagnostics is issued if a variable is defined whose name
+coincides with a previously defined constant (the variable "shadows"
+the constant).
+
+In any case, the %NAME notation refers to the last defined symbol, be
+it variable or constant.
+
+If a variable shadows a constant, the scope of the shadowing depends
+on the storage class of the variable. For automatic variables and
+function parameters, it ends with the final `done' closing the
+function. For global variables, it lasts up to the end of input.
+
+* Exception names.
+
+To minimize chances of name clashes, all symbolic exception codes has
+been renamed by prefixing them with the `e_', thus, e.g. `divzero'
+became `e_divzero', etc. The `ioerr' exception code is renamed to
+`e_io'.
+
+For consistency, the following most often used codes are available without
+the `e_' previx: success, not_found, failure, temp_failure.
+
+The use of old exception codes is still possible by defining a
+preprocessor symbol OLD_EXCEPTION_CODES, for example:
+
+ mailfromd -DOLD_EXCEPTION_CODES
+
+* match_dnsbl and match_rhsbl
+
+Both functions malfunctioned in versions from 4.0 up to 4.3.1 due to a
+name clash between the exception code `range' and their third
+argument. This is fixed.
+
+Additionally, previous versions of match_dnsbl silently ignored
+invalid first argument. Now, the e_invip exception is signalled in
+this case.
+
Version 4.3.1, 2008-03-01
* Fix program evaluator bug that manifested itself on machines where
sizeof(unsigned long) > sizeof(usnigned).
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 2ac69c35..10cbd2b9 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -73,13 +73,13 @@ check-mflib:
$(top_srcdir)/mflib/*.mf -- \
$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) -E - \
$(info_TEXINFOS)
check-exceptions:
@check-docs.sh exceptions \
- '/typedef enum mf_status_code {/,/^};/s/[ \t]*mf_\(.*\),.*/\1/p' \
+ '/typedef enum mf_exception_code {/,/^};/s/[ \t]*mfe_\(.*\),.*/e_\1/p;/typedef enum mf_status_code {/,/^};/s/[ \t]*mf_\(.*\),.*/\1/p' \
's/@cindex \([^,][^,]*\), exception type/\1/p' \
$(top_srcdir)/src/mailfromd.h -- \
$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) -E - \
$(info_TEXINFOS)
check-refs:
diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi
index 27ff4c46..9cf4871e 100644
--- a/doc/mailfromd.texi
+++ b/doc/mailfromd.texi
@@ -181,12 +181,13 @@ Mail Filtering Language
* Variables::
* Back references::
* Handlers::
* begin/end::
* Functions:: Functions.
* Expressions:: Expressions.
+* Shadowing:: Variable and Constant Shadowing.
* Statements::
* Conditionals:: Conditional Statements.
* Loops:: Loop Statements.
* Exceptions:: Exceptional Conditions and their Handling.
* Polling:: Sender Verification Tests.
* Modules:: Modules are Collections of Useful Functions.
@@ -267,12 +268,13 @@ Configuring @command{mailfromd}
* Starting and Stopping:: How to Start and Shut Down the Daemon.
Command Line Options.
* Operation Modifiers::
* General Settings::
+* Preprocessor Options::
* Timeout Control::
* Logging and Debugging Options::
* Informational Options::
@command{mtasim} --- a testing tool
@@ -998,13 +1000,37 @@ the corresponding section below.
* 1x-2x:: Upgrading from 1.x to 2.x
@end menu
@node 43x-440
@section Upgrading from 4.3.x to 4.4
@cindex Upgrading from 4.3.x to 4.4
-@UNREVISED{}
+
+ The deprecated @option{--domain} command line option has been
+withdrawn. The short option @option{-D} now defines a preprocessor
+symbol (@pxref{Preprocessor Options}).
+
+ This version correctly handles name clashes between constants and
+variables, which remained unnoticed in previous releases.
+@xref{variable--constant shadowing}, for a detailed description of it.
+
+ To minimize chances of name clashes, all symbolic exception codes has
+been renamed by prefixing them with the @samp{e_}, thus, e.g. @code{divzero}
+became @code{e_divzero}, etc. The @code{ioerr} exception code is renamed to
+@code{e_io}. @xref{status.mfh}, for a full list of the new exception codes.
+
+@cindex @code{OLD_EXCEPTION_CODES}, preprocessor symbol
+ For consistency, the following most often used codes are available without
+the @samp{e_} previx: success, not_found, failure, temp_failure. This
+makes most existing user scripts suitable for use with version 4.4
+without any modification. If your script refers to any exception
+codes other than these four, you can still use it by defining a
+preprocessor symbol @code{OLD_EXCEPTION_CODES}, for example:
+
+@smallexample
+$ mailfromd -DOLD_EXCEPTION_CODES
+@end smallexample
@node 420-43x
@section Upgrading from 4.2 to 4.3.x
@cindex Upgrading from 4.2 to 4.3.x
@cindex @code{DEFAULT_SYSLOG_ASYNC}, @command{configure} variable
@@ -3319,13 +3345,13 @@ do
reject
fi
done
@end group
@end smallexample
- The intent was obviously to reject any mail if it comes from an
+ The intent was obviously to reject any mail that came from an
address without a proper @code{PTR} record (@pxref{hostname
function}). There is a serious error, however: @code{hostname} is not
a built-in function as it used to be in previous releases@footnote{Up to
the version 1.3.91.}, and therefore it needs to be defined or required
prior to using. Otherwise it is no more than a literal, and the whole
construct @samp{hostname($client_addr)} is regarded by @acronym{MFL}
@@ -3393,12 +3419,60 @@ must be used:
echo sprintf ('Mail from %s', $f)
@end smallexample
This does not limit the functionality, since there is no need to fall
back to variable interpretation in format strings.
+@anchor{variable--constant clashes}
+Yet another dangerous feature of the language is the way to refer to
+variable and constant names within literal strings. To expand a
+variable or a constant the same notation is used: %@var{name}
+(@xref{Variables}, and @pxref{Constants}). Now, lets consider the
+following code:
+
+@smallexample
+const x 2
+string x "X"
+
+prog envfrom
+do
+ echo "X is %x"
+done
+@end smallexample
+
+Does @code{%x} in @code{echo} refers to the variable or to the
+constant? The correct answer is @samp{to the constant}; when executed this
+code will print @samp{X is X}.
+
+The reason for such a name clash is entirely artificial. Indeed, the
+following code does not produce any ambiguity:
+
+@smallexample
+const x 2
+string x "X"
+
+prog envfrom
+do
+ echo "X is " x
+done
+@end smallexample
+
+Problems begin when we need tp expand a constant in a
+literal string. The only way to do so is by prefixing its name with a
+@samp{%}, just as if it were variable, and that produces the
+ambiguity.
+
+As of version @value{VERSION}, @command{mailfromd} will always print a
+diagnostic message whenever it stumbles upon a variable having the
+same name as a previously defined constant or vice versa. The
+resolution of such name clashes is described in detail in
+@xref{variable--constant shadowing}.
+
+Future versions of the program will provide a non-ambiguous way of
+referring to variables and constants from literal strings.
+
@node MFL, Using MFL Mode, Tutorial, Top
@chapter Mail Filtering Language
@cindex MFL
@cindex mail filtering language
The @dfn{mail filtering language}, or @acronym{MFL}, is a special
@@ -3422,12 +3496,13 @@ amount of white-space characters (i.e. spaces, tabulations or newlines).
* Variables::
* Back references::
* Handlers::
* begin/end::
* Functions:: Functions.
* Expressions:: Expressions.
+* Shadowing:: Variable and Constant Shadowing.
* Statements::
* Conditionals:: Conditional Statements.
* Loops:: Loop Statements.
* Exceptions:: Exceptional Conditions and their Handling.
* Polling:: Sender Verification Tests.
* Modules:: Modules are Collections of Useful Functions.
@@ -4399,12 +4474,17 @@ literal constant @samp{text} with the value @samp{X is }.
a literal string, prepend a percent sign to its name, e.g.:
@smallexample
echo "New %text %x" @result{} "New X is 2"
@end smallexample
+ This way of expanding constants creates an ambiguity if there happen
+to be a variable of the same name as the constant.
+@xref{variable--constant clashes}, for more information of this case
+and ways to handle it.
+
@menu
* Built-in constants::
@end menu
@node Built-in constants
@subsection Built-in constants
@@ -7102,15 +7182,16 @@ Arguments:
The range of @acronym{IP} addresses in @acronym{CIDR} notation or
the word @samp{ANY}, which stands for @samp{127.0.0.0/8}.
@end table
The function returns @code{true} if dns lookup for @var{address} in
the zone @var{dnsbl} yields an @acronym{IP} that falls within the range,
-specified by @var{cidr}. Otherwise, it returns @code{false}. If
-any of @var{address} or @var{cidr} is invalid, @code{match_dnsbl}
-returns @code{false}.
+specified by @var{cidr}. Otherwise, it returns @code{false}.
+
+This function raises the following exceptions: @code{e_invip} if
+@var{address} is invalid and @code{e_invcidr} if @var{cidr} is invalid.
@end deftypefn
@anchor{match_rhsbl}
@deftypefn {Library Function} boolean match_rhsbl (string @var{email}, @
string @var{zone}, string @var{range})
@@ -8498,12 +8579,218 @@ string to it, e.g.:
Similarly, to cast an expression to numeric, add zero to it:
@smallexample
0 + %var
@end smallexample
+@node Shadowing
+@section Variable and Constant Shadowing
+@cindex shadowing, defined
+@cindex name clashes
+ When any two named entities happen to have the same name we say that a
+@dfn{name clash} occurs. The handling of name clashes depends on
+types of the entities involved in it.
+
+@table @asis
+@item function -- any
+A name of a constant or variable can coincide with that of a function,
+it does not produce any warnings or errors because functions,
+variables and constants use different namespaces. For example, the
+following code is correct:
+
+@smallexample
+const a 4
+
+func a()
+do
+ echo %a
+done
+@end smallexample
+
+When executed, it prints @samp{4}.
+
+@item function -- function
+@itemx handler -- function
+@itemx function -- handler
+Redefinition of a function or using a predefined handler name
+(@pxref{Handlers}) as a function name results in a fatal error. For
+example, compiling this code:
+
+@smallexample
+func a()
+do
+ echo "1"
+done
+
+func a()
+do
+ echo "2"
+done
+@end smallexample
+
+@noindent
+causes the following error message:
+
+@smallexample
+mailfromd: sample.mf:9: syntax error, unexpected FUNCTION_PROC,
+expecting IDENTIFIER
+@end smallexample
+
+@item handler -- variable
+A variable name can coincide with a handler name. For example, the
+following code is perfectly OK:
+
+@smallexample
+string envfrom "M"
+prog envfrom
+do
+ echo %envfrom
+done
+@end smallexample
+
+@item handler -- handler
+As of version @value{VERSION}, multiple definitions of a handler are
+compiled without warnings. However, only the last definition is used.
+This may change in future releases.
+
+@item variable -- variable
+@cindex variable shadowing
+@cindex shadowing, variable
+Defining a variable havinf the same name as an already defined one results
+in a warning message being displayed. The compilation succeeds. The
+second variable @dfn{shadows} the first, that is any subsequent
+references to the variable name will refer to the second variable.
+For example:
+
+@smallexample
+string x "Text"
+number x 1
+
+prog envfrom
+do
+ echo %x
+done
+@end smallexample
+
+Compiling this code results in the following diagnostics:
+
+@smallexample
+mailfromd: sample.mf:4: Redeclaring `x' as different data type
+mailfromd: sample.mf:2: This is the location of the previous
+definition
+@end smallexample
+
+Executing it prints @samp{1}, i.e. the value of the last definition of
+@code{x}.
+
+The scope of the shadowing depends on storage classes of the two
+variables. If both of them have external storage class (i.e. are
+global ones), the shadowing remains in effect until the end of input.
+In other words, the previous definition of the variable is effectively
+forgotten.
+
+If the previous definition is a global, and the shadowing definition
+is an automatic variable or a function parameter, the scope of this
+shadowing ends with the scope of the second variable, after which the
+previous definition (global) becomes visible again. Consider the
+following code:
+
+@smallexample
+set x "initial"
+
+func foo(string x) returns string
+do
+ return %x
+done
+
+prog envfrom
+do
+ echo foo("param")
+ echo %x
+done
+@end smallexample
+
+Its compilation produces the following warning:
+
+@smallexample
+mailfromd: sample.mf:3: Warning: Parameter `x' is shadowing a global
+@end smallexample
+
+When executed, it produces the following output:
+
+@smallexample
+param
+initial
+State envfrom: continue
+@end smallexample
+
+@anchor{variable--constant shadowing}
+@item variable -- constant
+@cindex shadowing, variable--constant
+If a constant is defined which has the same name as a previously
+defined variable (the constant @dfn{shadows} the variable), the
+compiler prints the following diagnostic message:
+
+@smallexample
+@var{file}:@var{line}: Warning: Constant name `@var{name}' clashes with a variable name
+@var{file}:@var{line}: Warning: This is the location of the previous definition
+@end smallexample
+
+A similar diagnostics is issued if a variable is defined whose name
+coincides with a previously defined constant (the variable shadows
+the constant).
+
+In any case, any subsequent notation %@var{name} refers to the last
+defined symbol, be it variable or constant.
+
+Notice, that shadowing occurs only when using %@var{name} notation.
+Referring to the constant using its name without @samp{%} allows to
+avoid shadowing effects.
+
+If a variable shadows a constant, the scope of the shadowing depends
+on the storage class of the variable. For automatic variables and
+function parameters, it ends with the final @code{done} closing the
+function. For global variables, it lasts up to the end of input.
+
+For example, consider the following code:
+
+@smallexample
+const a 4
+
+func foo(string a)
+do
+ echo %a
+done
+
+prog envfrom
+do
+ foo(10)
+ echo %a
+done
+@end smallexample
+
+When run, it produces the following output:
+
+@smallexample
+$ mailfromd --test sample.mf
+mailfromd: sample.mf:3: Warning: Variable name `a' clashes with a
+constant name
+mailfromd: sample.mf:1: Warning: This is the location of the previous
+definition
+10
+4
+State envfrom: continue
+@end smallexample
+
+@item constant -- constant
+@cindex shadowing, constant--constant
+Redefining a constant produces a warning message. The latter
+definition shadows the former. Shadowing remains in effect until
+the end of input.
+@end table
+
@node Statements
@section Statements
@cindex statements
Statements are language constructs, that, unlike expressions, do not
return any value. Statements execute some actions, such as assigning
@@ -9736,12 +10023,48 @@ $ @kbd{mailfromf -E file.mf}
@end smallexample
The output is in the form of preprocessed source code, which is sent
to the standard output. This can be useful, among others, to debug
your own macro definitions.
+Macro definitions and deletions can be made on the command line, by
+using the @option{-D} and @option{-U} options. They have the
+following format:
+
+@table @option
+@xopindex{define, described}
+@cindex D, -D @r{option, described}
+@item -D @var{name}[=@var{value}]
+@itemx --define=@var{name}[=@var{value}]
+Define a symbol @var{name} to have a value @var{value}. If
+@var{value} is not supplied, the value is taken to be the empty
+string. The @var{value} can be any string, and the macro can be
+defined to take arguments, just as if it was defined from within the
+input using the @code{m4_define} statement.
+
+For example, the following invocation defines symbol @code{COMPAT} to
+have a value @code{43}:
+
+@smallexample
+$ mailfromf -DCOMPAT=43
+@end smallexample
+
+@xopindex{undefine, described}
+@cindex U, -U @r{option, described}
+@item -U @var{name}
+@item --undefine=@var{name}
+A counterpart of the @option{-D} option is the option @option{-U}
+(@option{--undefine}). It undefines a preprocessor symbol whose name
+is given as its argument. The following example undefines the symbol
+@code{COMPAT}:
+
+@smallexample
+$ mailfromf -UCOMPAT
+@end smallexample
+@end table
+
The following two options are supplied mainly for debugging purposes:
@table @option
@xopindex{no-preprocessor, usage}
@item --no-preprocessor
Disables the external preprocessor.
@@ -9908,12 +10231,13 @@ words:
@item __line__
@item __major__
@item __minor__
@item __package__
@item __patch__
@item __preproc__
+@item __statedir__
@item __version__
@item accept
@item add
@item and
@item begin
@item break
@@ -9965,12 +10289,23 @@ are keywords in @code{on} context:
@item as
@item from
@item host
@item poll
@end itemize
+The following keywords are preprocessor macros:
+
+@itemize
+@item defined
+@item _ (an underscore)
+@item N_
+@end itemize
+
+Any keyword beginning with a @samp{m4_} prefix is a reserved
+preprocessor symbol.
+
@node Using MFL Mode, Mailfromd Configuration, MFL, Top
@chapter Using the GNU Emacs MFL Mode
@cindex Emacs, @acronym{MFL} mode
@cindex GNU Emacs, @acronym{MFL} mode
@cindex @acronym{MFL} mode, GNU Emacs
@acronym{MFL} sources are usual @acronym{ASCII} files and you may
@@ -10196,12 +10531,13 @@ value to be assigned to it.
@node options
@section Command Line Options.
@menu
* Operation Modifiers::
* General Settings::
+* Preprocessor Options::
* Timeout Control::
* Logging and Debugging Options::
* Informational Options::
@end menu
@node Operation Modifiers
@@ -10282,24 +10618,19 @@ Run in test mode. @xref{Testing Filter Scripts}. Default @var{state} is
@table @option
@opsummary{all}
@item --all
When used with @option{--compact} or @option{--expire} option, applies
the action to all available databases. @xref{compact cronjob}.
-@opsummary{domain}
-@item -D @var{string}
-@itemx --domain=@var{string}
+@opsummary{ehlo}
+@itemx --ehlo=@var{string}
Set default @acronym{SMTP} domain. Overrides @samp{#pragma option ehlo}
(@pxref{pragma ehlo}). This option is
deprecated@footnote{@xref{31x-400}, for a detailed description of
why it is deprecated.}: use @option{-v ehlo_domain=@var{string}} instead.
-@opsummary{ehlo}
-@itemx --ehlo=@var{string}
-Same as @option{--domain}.
-
@opsummary{expire-interval}
@item -e @var{interval}
@itemx --expire-interval=@var{interval}
Set expiration intervals for all databases to the specified interval.
@xref{time interval specification}, for a description of
@var{interval} format. The option overrides @samp{#pragma option
@@ -10375,16 +10706,12 @@ description of why it is deprecated.}: use @option{-v
mailfrom_address=@var{string}} instead.
@opsummary{mtasim}
@item --mtasim
This option is reserved for use by @command{mtasim} (@pxref{mtasim}).
-@opsummary{no-preprocessor}
-@item --no-preprocessor
-Do not run the preprocessor. @xref{Preprocessor}.
-
@opsummary{optimize}
@item -O[@var{level}]
@itemx --optimize[=@var{level}]
Set optimization level for code generator. Two levels are
implemented: @samp{0}, meaning no optimization, and @samp{1}, meaning
full optimization.
@@ -10407,17 +10734,12 @@ are advised to use instead (@pxref{pragma pidfile}).
@opsummary{predict}
@item --predict=@var{rate-limit}
Used with @option{--list} enables printing of the estimated times of
sending along with the @samp{rate} database dump. Implies
@option{--list --format=rate}. @xref{estimated time of sending}.
-@opsummary{preprocessor}
-@item --preprocessor=@var{command}
-Use @var{command} as the external preprocessor instead of the default
-@command{m4}. @xref{Preprocessor}.
-
@opsummary{relayed-domain-file}
@item --relayed-domain-file=@var{file}
@anchor{option relay}
Read relayed domains from @var{file}. Overrides @samp{#pragma option
relay}, which you are advised to use instead (@pxref{option relay}).
@xref{Avoiding Verification Loops}, and the description of
@@ -10437,13 +10759,13 @@ the description of this directory and its purposes. This option
overrides the settings of @samp{#pragma option state-directory},
described in @ref{pragma state-directory}.
@opsummary{source}
@item -S
@itemx --source
-Set source address for TCP connections. Overrides @samp{#pragma
+Set source address for @acronym{TCP} connections. Overrides @samp{#pragma
option source}, which you are advised to use instead (@pxref{pragma source}).
@opsummary{time-format}
@item --time-format=@var{format}
Set format to be used for timestamps in listings, produced by
@option{--list}. The @var{format} is any valid @code{strftime} format
@@ -10473,12 +10795,48 @@ values}, for a detailed discussion of this option.
@opindex config-file
-- Reserved for future use
@opindex compile
@end ignore
@end table
+@node Preprocessor Options
+@subsection Preprocessor Options
+
+Following command line options control the preprocessor
+feature. @xref{Preprocessor}, for a detailed discussion of these.
+
+@table @option
+@opsummary{no-preprocessor}
+@item --no-preprocessor
+Do not run the preprocessor.
+
+@opsummary{preprocessor}
+@item --preprocessor=@var{command}
+Use @var{command} as the external preprocessor instead of the default
+@command{m4}.
+
+@opsummary{define}
+@cindex D, -D @r{option, summary}
+@item -D @var{name}[=@var{value}]
+@itemx --define=@var{name}[=@var{value}]
+Define a preprocessor symbol @var{name} to have a value @var{value}.
+
+@opsummary{undefine}
+@cindex U, -U @r{option, summary}
+@item -U @var{name}
+@itemx --undefine=@var{name}
+Undefine the preprocessor symbol @var{name}.
+
+@cindex E, -E @r{option, summary}
+@item -E
+Stop after the preprocessing stage; do not run the compiler proper.
+The output is in the form of preprocessed source code, which is sent
+to the standard output.
+@end table
+
+
@node Timeout Control
@subsection Timeout Control
@xref{time interval specification}, for information on @var{interval} format.
@table @option
diff --git a/mflib/match_dnsbl.mf b/mflib/match_dnsbl.mf
index 53603be5..46795a86 100644
--- a/mflib/match_dnsbl.mf
+++ b/mflib/match_dnsbl.mf
@@ -22,13 +22,13 @@
func match_dnsbl(string address, string zone, string iprange)
returns number
do
if %iprange = 'ANY'
set iprange '127.0.0.0/8'
- m4_ifdef(`COMPAT_4_3',`
+ m4_ifdef(`LAZY_MATCH_RBL',`
else
if not %iprange matches `'''`^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$`'''`
return 0
fi
fi
@@ -41,11 +41,13 @@ do
'^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$'
if match_cidr (resolve ("\4.\3.\2.\1", %zone), %iprange)
return 1
else
return 0
fi
+ else
+ throw e_invip "%address: invalid IP address"
fi
# never reached
done
#pragma regex pop
diff --git a/mflib/match_rhsbl.mf b/mflib/match_rhsbl.mf
index d08f103b..6e011967 100644
--- a/mflib/match_rhsbl.mf
+++ b/mflib/match_rhsbl.mf
@@ -22,13 +22,13 @@
func match_rhsbl(string email, string zone, string iprange)
returns number
do
if %iprange = 'ANY'
set iprange '127.0.0.0/8'
fi
- if not (%email matches '@.+$'m4_ifdef(`COMPAT_4_3',`
+ if not (%email matches '@.+$'m4_ifdef(`LAZY_MATCH_RBL',`
and %iprange matches `'''`^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$'`''))
return 0
fi
return match_cidr (resolve ((domainpart %email), %zone), %iprange)
done
diff --git a/src/mailfromd.h b/src/mailfromd.h
index d3531f5c..4a124492 100644
--- a/src/mailfromd.h
+++ b/src/mailfromd.h
@@ -76,13 +76,15 @@
/* Status values used throughout the program */
typedef enum mf_status_code {
mf_success,
mf_not_found,
mf_failure,
- mf_temp_failure
+ mf_temp_failure,
+
+ mf_status_count
} mf_status;
#define mf_resolved(c) ((c) == mf_success || (c) == mf_not_found)
/* Exception codes. */
typedef enum mf_exception_code {
diff --git a/src/main.c b/src/main.c
index 19eb2f4f..ae73aa47 100644
--- a/src/main.c
+++ b/src/main.c
@@ -68,12 +68,13 @@ int preprocess_option; /* Only preprocess the sources */
#ifdef DEFAULT_PREPROCESSOR
# define DEF_EXT_PP DEFAULT_PREPROCESSOR
#else
# define DEF_EXT_PP NULL
#endif
char *ext_pp = DEF_EXT_PP; /* External preprocessor to use */
+char *ext_pp_options;
int do_transcript; /* Enable session transript */
int do_trace; /* Enable tracing configuration */
int mtasim_option; /* mtasim compatibility mode */
unsigned optimization_level = 1; /* Optimization level */
int log_to_stderr; /* Use stderr for logging */
@@ -127,12 +128,56 @@ time_t connect_timeout = 10;
time_t io_timeout = 3;
/* Initial response settings */
time_t response_timeout = 30;
+/* Preprocessor helper function */
+static void
+add_pp_option(const char *opt, const char *arg)
+{
+ size_t len;
+
+ len = 1 + strlen(opt) + (arg ? strlen(arg) : 0);
+ if (ext_pp_options) {
+ len += strlen(ext_pp_options);
+ ext_pp_options = xrealloc(ext_pp_options, len + 1);
+ } else {
+ ext_pp_options = xmalloc(len + 1);
+ }
+ strcat(ext_pp_options, " ");
+ strcat(ext_pp_options, opt);
+ strcat(ext_pp_options, arg);
+}
+
+static void
+alloc_ext_pp()
+{
+ if (ext_pp_options) {
+ size_t len;
+ char *p;
+
+ if (!ext_pp) {
+ if (!DEF_EXT_PP) {
+ mu_error(_("Default preprocessor is not set; "
+ "use --preprocessor option"));
+ exit(EX_USAGE);
+ }
+ ext_pp = DEF_EXT_PP;
+ }
+
+ len = strlen(ext_pp) + strlen(ext_pp_options);
+ p = xmalloc(len + 1);
+ strcpy(p, ext_pp);
+ strcat(p, ext_pp_options);
+ ext_pp = p;
+ }
+}
+
+
+
/* Logging & debugging */
int
syslog_printer (int prio, const char *fmt, va_list ap)
{
#ifdef USE_SYSLOG_ASYNC
@@ -1031,17 +1076,27 @@ static struct argp_option options[] = {
{ "optimize", 'O', N_("LEVEL"), OPTION_ARG_OPTIONAL,
N_("Set code optimization level"), GRP+1 },
{ "variable", 'v', N_("VAR=VALUE"), 0,
N_("Assign VALUE to VAR"), GRP+1 },
{ "relayed-domain-file", OPTION_DOMAIN_FILE, N_("FILE"), 0,
N_("Read relayed domains from FILE"), GRP+1 },
+
+#undef GRP
+#define GRP 25
+ { NULL, 0, NULL, 0,
+ N_("Preprocessor options"), GRP },
{ "preprocessor", OPTION_PREPROCESSOR, N_("COMMAND"), 0,
N_("Use command as external preprocessor"), GRP+1 },
{ "no-preprocessor", OPTION_NO_PREPROCESSOR, NULL, 0,
N_("Disable the use of external preprocessor"), GRP+1 },
-#undef GRP
+ { "define", 'D', N_("NAME[=VALUE]"), 0,
+ N_("Define a preprocessor symbol NAME as having VALUE, or empty"),
+ GRP+1 },
+ { "undefine", 'U', N_("NAME"), 0,
+ N_("Undefine a preprocessor symbol NAME"),
+ GRP+1 },
#undef GRP
#define GRP 30
{ NULL, 0, NULL, 0,
N_("Timeout control"), GRP },
{ "milter-timeout", OPTION_MILTER_TIMEOUT, N_("TIME"), 0,
@@ -1093,13 +1148,12 @@ static struct argp_option options[] = {
N_("Debug messages include source information"), GRP+1 },
{ "stack-trace", OPTION_STACK_TRACE, NULL, 0,
N_("Enable stack traces on runtime errors"), GRP+1 },
#undef GRP
/*DEPRECATED OPTIONS*/
- { "domain", 'D', N_("STRING"), OPTION_HIDDEN, "", 1 },
{ "ehlo", 0, NULL, OPTION_ALIAS|OPTION_HIDDEN, NULL, 1 },
{ "postmaster-email", OPTION_POSTMASTER_EMAIL, N_("EMAIL"),
OPTION_HIDDEN, "", 1 },
{ "mailfrom", 0, NULL, OPTION_ALIAS|OPTION_HIDDEN, NULL, 1 },
#if 0
@@ -1128,15 +1182,18 @@ validate_options()
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key) {