diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-03-10 13:43:22 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-03-10 13:43:22 +0000 |
commit | 18ebe7bb829772d7bf1df49d23a2c9dd53a2afcd (patch) | |
tree | 51b017fdad8d712f2aa4f7a5d505032acc2e9185 | |
parent | 9fe06f87591f813fce7f9068f19246c8d933fc6a (diff) | |
download | mailfromd-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-- | ChangeLog | 22 | ||||
-rw-r--r-- | NEWS | 62 | ||||
-rw-r--r-- | doc/Makefile.am | 2 | ||||
-rw-r--r-- | doc/mailfromd.texi | 402 | ||||
-rw-r--r-- | mflib/match_dnsbl.mf | 4 | ||||
-rw-r--r-- | mflib/match_rhsbl.mf | 2 | ||||
-rw-r--r-- | src/mailfromd.h | 4 | ||||
-rw-r--r-- | src/main.c | 65 | ||||
-rw-r--r-- | src/status.mfi | 2 |
9 files changed, 534 insertions, 31 deletions
@@ -1,3 +1,21 @@ +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, @@ -70,6 +88,10 @@ 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. @@ -1,4 +1,4 @@ -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. @@ -7,6 +7,66 @@ 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 diff --git a/doc/Makefile.am b/doc/Makefile.am index 2ac69c35..10cbd2b9 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -76,7 +76,7 @@ check-mflib: 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 - \ diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi index 27ff4c46..9cf4871e 100644 --- a/doc/mailfromd.texi +++ b/doc/mailfromd.texi @@ -184,6 +184,7 @@ Mail Filtering Language * begin/end:: * Functions:: Functions. * Expressions:: Expressions. +* Shadowing:: Variable and Constant Shadowing. * Statements:: * Conditionals:: Conditional Statements. * Loops:: Loop Statements. @@ -270,6 +271,7 @@ Command Line Options. * Operation Modifiers:: * General Settings:: +* Preprocessor Options:: * Timeout Control:: * Logging and Debugging Options:: * Informational Options:: @@ -1001,7 +1003,31 @@ the corresponding section below. @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 @@ -3322,7 +3348,7 @@ 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 @@ -3396,6 +3422,54 @@ echo sprintf ('Mail from %s', $f) 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 @@ -3425,6 +3499,7 @@ amount of white-space characters (i.e. spaces, tabulations or newlines). * begin/end:: * Functions:: Functions. * Expressions:: Expressions. +* Shadowing:: Variable and Constant Shadowing. * Statements:: * Conditionals:: Conditional Statements. * Loops:: Loop Statements. @@ -4402,6 +4477,11 @@ a literal string, prepend a percent sign to its name, e.g.: 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 @@ -7105,9 +7185,10 @@ the word @samp{ANY}, which stands for @samp{127.0.0.0/8}. 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} @@ -8501,6 +8582,212 @@ Similarly, to cast an expression to numeric, add zero to it: 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 @@ -9739,6 +10026,42 @@ 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 @@ -9911,6 +10234,7 @@ words: @item __package__ @item __patch__ @item __preproc__ +@item __statedir__ @item __version__ @item accept @item add @@ -9968,6 +10292,17 @@ are keywords in @code{on} context: @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 @@ -10199,6 +10534,7 @@ value to be assigned to it. @menu * Operation Modifiers:: * General Settings:: +* Preprocessor Options:: * Timeout Control:: * Logging and Debugging Options:: * Informational Options:: @@ -10285,18 +10621,13 @@ Run in test mode. @xref{Testing Filter Scripts}. Default @var{state} is 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} @@ -10378,10 +10709,6 @@ mailfrom_address=@var{string}} instead. @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}] @@ -10410,11 +10737,6 @@ 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} @@ -10440,7 +10762,7 @@ 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} @@ -10476,6 +10798,42 @@ values}, for a detailed discussion of this option. @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 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 @@ -25,7 +25,7 @@ func match_dnsbl(string address, string zone, string iprange) 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 @@ -44,6 +44,8 @@ do else return 0 fi + else + throw e_invip "%address: invalid IP address" fi # never reached done 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 @@ -25,7 +25,7 @@ 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 diff --git a/src/mailfromd.h b/src/mailfromd.h index d3531f5c..4a124492 100644 --- a/src/mailfromd.h +++ b/src/mailfromd.h @@ -79,7 +79,9 @@ 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) @@ -71,6 +71,7 @@ int preprocess_option; /* Only preprocess the sources */ # 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 */ @@ -130,6 +131,50 @@ time_t io_timeout = 3; 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 @@ -1034,11 +1079,21 @@ static struct argp_option options[] = { 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 @@ -1096,7 +1151,6 @@ static struct argp_option options[] = { #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 }, @@ -1131,9 +1185,12 @@ parse_opt (int key, char *arg, struct argp_state *state) { switch (key) { case 'D': - set_option("ehlo", arg, 1); + add_pp_option("-D", arg); break; + case 'U': + add_pp_option("-U", arg); + case 'd': set_option("debug", arg, 1); break; @@ -2135,6 +2192,8 @@ main(int argc, char **argv) if (rc) exit (EX_CONFIG); + alloc_ext_pp(); + log_setup(log_to_stderr); argv += index; diff --git a/src/status.mfi b/src/status.mfi index 9d69096c..c465522c 100644 --- a/src/status.mfi +++ b/src/status.mfi @@ -17,7 +17,7 @@ const failure e_failure const temp_failure e_temp_failure # Backward-compatible definitions -m4_ifdef(`COMPAT_4_3',` +m4_ifdef(`OLD_EXCEPTION_CODES',` const ston_conv e_ston_conv const divzero e_divzero const regcomp e_regcomp |