diff options
-rw-r--r-- | NEWS | 19 | ||||
-rw-r--r-- | doc/mailfromd.texi | 86 | ||||
-rw-r--r-- | mfd/drivers.c | 113 | ||||
-rw-r--r-- | mfd/gram.y | 131 | ||||
-rw-r--r-- | mfd/lex.l | 4 | ||||
-rw-r--r-- | mfd/mailfromd.h | 8 | ||||
-rw-r--r-- | mfd/opcodes | 2 | ||||
-rw-r--r-- | mfd/prog.c | 10 |
8 files changed, 275 insertions, 98 deletions
@@ -1,3 +1,3 @@ | |||
1 | Mailfromd NEWS -- history of user-visible changes. 2009-05-10 | 1 | Mailfromd NEWS -- history of user-visible changes. 2009-05-11 |
2 | Copyright (C) 2005, 2006, 2007, 2008, 2009 Sergey Poznyakoff | 2 | Copyright (C) 2005, 2006, 2007, 2008, 2009 Sergey Poznyakoff |
3 | See the end of file for copying conditions. | 3 | See the end of file for copying conditions. |
@@ -25,4 +25,21 @@ specifics of MeTA1, the number of symbols that may be exported for | |||
25 | each stage is limited (Mailfromd manual, section 11.1.2). | 25 | each stage is limited (Mailfromd manual, section 11.1.2). |
26 | 26 | ||
27 | * Reject and tempfail actions: Functional notation | ||
28 | |||
29 | The reply actions `reject' and `tempfail' allow functional notation, | ||
30 | i.e. their arguments can be supplied as to a function: | ||
31 | |||
32 | reject(550, 5.7.7, "IP address does not resolve") | ||
33 | |||
34 | An important feature of this notation is that all three arguments are | ||
35 | MFL expressions, which means that you can now compute the reply codes | ||
36 | at run time: | ||
37 | |||
38 | reject(550 + %n, "5.7." %x, "Transaction rejected") | ||
39 | |||
40 | An argument can be omitted, in which case the default value is used, e.g.: | ||
41 | |||
42 | reject(550 + %n, , "Transaction rejected") | ||
43 | |||
27 | * New functions | 44 | * New functions |
28 | 45 | ||
diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi index 3d2e43c5..090222eb 100644 --- a/doc/mailfromd.texi +++ b/doc/mailfromd.texi | |||
@@ -1356,14 +1356,19 @@ the @command{Sendmail}. There are five actions, one for each response | |||
1356 | code: @code{continue}, @code{accept}, @code{reject}, @code{discard}, | 1356 | code: @code{continue}, @code{accept}, @code{reject}, @code{discard}, |
1357 | and @code{tempfail}. Among these, @code{reject} and @code{discard} | 1357 | and @code{tempfail}. Among these, @code{reject} and @code{discard} |
1358 | can optionally take one to three arguments. The first | 1358 | can optionally take one to three arguments. There are two ways of |
1359 | argument is a three-digit @acronym{RFC} 2821 reply code. It must begin with | 1359 | supplying the arguments. |
1360 | @samp{5} for @code{reject} and with @samp{4} for @code{tempfail}. If | 1360 | |
1361 | two arguments are supplied, the second argument must be either an | 1361 | In the first form, called @dfn{literal} or @dfn{traditional} notation, |
1362 | @dfn{extended reply code} (@acronym{RFC} 1893/2034) or a textual string to be | 1362 | the arguments are supplied as additional words after the action name, |
1363 | separated by whitespace. The first argument is a three-digit | ||
1364 | @acronym{RFC} 2821 reply code. It must begin with @samp{5} for | ||
1365 | @code{reject} and with @samp{4} for @code{tempfail}. If two arguments | ||
1366 | are supplied, the second argument must be either an @dfn{extended | ||
1367 | reply code} (@acronym{RFC} 1893/2034) or a textual string to be | ||
1363 | returned along with the @acronym{SMTP} reply. Finally, if all three | 1368 | returned along with the @acronym{SMTP} reply. Finally, if all three |
1364 | arguments are supplied, then the second one must be an extended reply | 1369 | arguments are supplied, then the second one must be an extended reply |
1365 | code and the third one must supply the textual string. The following | 1370 | code and the third one must supply the textual string. The following |
1366 | examples illustrate all possible ways of using the @code{reject} | 1371 | examples illustrate all possible ways of using the @code{reject} |
1367 | statement: | 1372 | statement in literal notation: |
1368 | 1373 | ||
1369 | @smallexample | 1374 | @smallexample |
@@ -1380,4 +1385,23 @@ reject 503 5.0.0 "Need HELO command" | |||
1380 | Please note the quotes around the textual string. | 1385 | Please note the quotes around the textual string. |
1381 | 1386 | ||
1387 | Another form for these action is called @dfn{functional} notation, | ||
1388 | because it resembles the function syntax. When used in this form, the | ||
1389 | action word is followed by a parenthesized group of exactly three | ||
1390 | arguments, separated by commas. The meaning and ordering of the | ||
1391 | argument is the same as in literal form. Any of three arguments may | ||
1392 | be absent, in which case it will be replaced by the default value. To | ||
1393 | illustrate this, here are the statements from the previous example, | ||
1394 | written in functional notation: | ||
1395 | |||
1396 | @smallexample | ||
1397 | @group | ||
1398 | reject(,,) | ||
1399 | reject(503,,) | ||
1400 | reject(503, 5.0.0) | ||
1401 | reject(503,, "Need HELO command") | ||
1402 | reject(503, 5.0.0, "Need HELO command") | ||
1403 | @end group | ||
1404 | @end smallexample | ||
1405 | |||
1382 | @node Conditional Execution | 1406 | @node Conditional Execution |
1383 | @section Conditional Execution | 1407 | @section Conditional Execution |
@@ -10254,5 +10278,6 @@ perform a certain action over the message being processed. There are | |||
10254 | two kinds of actions: return actions and header manipulation actions. | 10278 | two kinds of actions: return actions and header manipulation actions. |
10255 | 10279 | ||
10256 | Return actions tell @command{Sendmail} to return given response code | 10280 | @subsubheading Reply Actions |
10281 | Reply actions tell @command{Sendmail} to return given response code | ||
10257 | to the remote party. There are five such actions: | 10282 | to the remote party. There are five such actions: |
10258 | 10283 | ||
@@ -10264,5 +10289,6 @@ to the remote party. There are five such actions: | |||
10264 | transmitting its message. | 10289 | transmitting its message. |
10265 | 10290 | ||
10266 | @item reject [@var{code}] [@var{excode}] [@var{message}] | 10291 | @item reject @var{code} @var{excode} @var{message-expr} |
10292 | @itemx reject (@var{code-expr}, @var{excode-expr}, @var{message-expr}) | ||
10267 | @cindex reject action, defined | 10293 | @cindex reject action, defined |
10268 | @kwindex reject | 10294 | @kwindex reject |
@@ -10271,5 +10297,6 @@ cancel transmitting its message. The three arguments are optional, | |||
10271 | their usage is described below. | 10297 | their usage is described below. |
10272 | 10298 | ||
10273 | @item tempfail [@var{code}] [@var{excode}] [@var{message}] | 10299 | @item tempfail @var{code} @var{excode} @var{message} |
10300 | @itemx tempfail (@var{code-expr}, @var{excode-expr}, @var{message-expr}) | ||
10274 | @cindex tempfail action, defined | 10301 | @cindex tempfail action, defined |
10275 | @kwindex tempfail | 10302 | @kwindex tempfail |
@@ -10293,5 +10320,10 @@ continue processing of the message. | |||
10293 | @anchor{reject} | 10320 | @anchor{reject} |
10294 | Two actions, @code{reject} and @code{tempfail} can take up to three | 10321 | Two actions, @code{reject} and @code{tempfail} can take up to three |
10295 | optional parameters. The first argument is a three-digit | 10322 | optional parameters. There are two forms of supplying these |
10323 | parameters. | ||
10324 | |||
10325 | In the first form, called @dfn{literal} or @dfn{traditional} notation, | ||
10326 | the arguments are supplied as additional words after the action name, | ||
10327 | and are separated by whitespace. The first argument is a three-digit | ||
10296 | @acronym{RFC} 2821 reply code. It must begin with @samp{5} for | 10328 | @acronym{RFC} 2821 reply code. It must begin with @samp{5} for |
10297 | @code{reject} and with @samp{4} for @code{tempfail}. If two arguments | 10329 | @code{reject} and with @samp{4} for @code{tempfail}. If two arguments |
@@ -10314,4 +10346,38 @@ reject 503 5.0.0 "Need HELO command" | |||
10314 | @end smallexample | 10346 | @end smallexample |
10315 | 10347 | ||
10348 | The notion @dfn{textual string}, used above means either a literal | ||
10349 | string or an @acronym{MFL} expression that evaluates to string. | ||
10350 | However, both code and extended code must always be literal. | ||
10351 | |||
10352 | The second form of supplying arguments is called @dfn{functional} | ||
10353 | notation, because it resembles the function syntax. When used in this | ||
10354 | form, the action word is followed by a parenthesized group of exactly | ||
10355 | three arguments, separated by commas. Each argument is a | ||
10356 | @acronym{MFL} expression. The meaning and ordering of the arguments is | ||
10357 | the same as in literal form. Any or all of these three arguments may | ||
10358 | be absent, in which case it will be replaced by the default value. To | ||
10359 | illustrate this, here are the statements from the previous example, | ||
10360 | written in functional notation: | ||
10361 | |||
10362 | @smallexample | ||
10363 | @group | ||
10364 | reject(,,) | ||
10365 | reject(503,,) | ||
10366 | reject(503, 5.0.0) | ||
10367 | reject(503, "Need HELO command",) | ||
10368 | reject(503, 5.0.0, "Need HELO command") | ||
10369 | @end group | ||
10370 | @end smallexample | ||
10371 | |||
10372 | Notice that there is an important difference between the two | ||
10373 | notations. The functional notation allows to compute both reply codes | ||
10374 | at run time, e.g.: | ||
10375 | |||
10376 | @smallexample | ||
10377 | reject(500 + %dig2*10 + %dig3, "5." %edig2 "." %edig2) | ||
10378 | @end smallexample | ||
10379 | |||
10380 | @subsubheading Header Actions | ||
10381 | |||
10316 | @anchor{header manipulation} | 10382 | @anchor{header manipulation} |
10317 | @cindex header manipulation actions | 10383 | @cindex header manipulation actions |
diff --git a/mfd/drivers.c b/mfd/drivers.c index d8dfb4b2..ed8a288a 100644 --- a/mfd/drivers.c +++ b/mfd/drivers.c | |||
@@ -890,27 +890,26 @@ void | |||
890 | print_type_result(NODE *node, int level) | 890 | print_type_result(NODE *node, int level) |
891 | { | 891 | { |
892 | if (node->v.ret.code) { | 892 | NODE *code, *xcode; |
893 | const char *s = NULL; | 893 | |
894 | int expr = 0; | 894 | code = node->v.ret.code; |
895 | xcode = node->v.ret.xcode; | ||
895 | 896 | ||
896 | print_level(level); | 897 | print_level(level); |
897 | if (node->v.ret.message) { | 898 | printf("SET REPLY "); |
898 | if (node->v.ret.message->type == node_type_string) | ||
899 | s = node->v.ret.message->v.literal->text; | ||
900 | else { | ||
901 | expr = 1; | ||
902 | s = "(expression)"; | ||
903 | } | ||
904 | } | ||
905 | dbg_setreply(NULL, | ||
906 | (char*) LITERAL_TEXT(node->v.ret.code), | ||
907 | (char*) LITERAL_TEXT(node->v.ret.xcode), | ||
908 | (char*) s); | ||
909 | if (expr) | ||
910 | print_node(node->v.ret.message, level+1); | ||
911 | } | ||
912 | print_level(level); | ||
913 | print_stat(node->v.ret.stat); | 899 | print_stat(node->v.ret.stat); |
914 | printf("\n"); | 900 | printf("\n"); |
901 | print_level(level); | ||
902 | printf("CODE:\n"); | ||
903 | if (code) | ||
904 | print_node(code, level+1); | ||
905 | print_level(level); | ||
906 | printf("XCODE:\n"); | ||
907 | if (xcode) | ||
908 | print_node(xcode, level+1); | ||
909 | print_level(level); | ||
910 | printf("MESSAGE:\n"); | ||
911 | if (node->v.ret.message) | ||
912 | print_node(node->v.ret.message, level+1); | ||
913 | printf("\n"); | ||
915 | } | 914 | } |