diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-05-11 21:48:14 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-05-11 21:48:14 +0300 |
commit | f8323650568b0031f0ec4c50cde417cb10a48c56 (patch) | |
tree | b0007c30366860dc079a7bf8828d254b7486630f | |
parent | ffd2cf189d926abe00de0a79f292f1ea69d02aac (diff) | |
download | mailfromd-f8323650568b0031f0ec4c50cde417cb10a48c56.tar.gz mailfromd-f8323650568b0031f0ec4c50cde417cb10a48c56.tar.bz2 |
Implement functional notation for reply actions
* NEWS, doc/mailfromd.texi: Update.
* mfd/drivers.c (print_type_result, mark_type_result)
(optimize_type_result, code_type_result): Rewrite.
* mfd/gram.y: Rewrite action rules.
* mfd/lex.l (CODE,XCODE): Remove.
* mfd/opcodes (RESULT): Takes one immediate parameter.
(instr_result): Get arguments from stack.
-rw-r--r-- | NEWS | 19 | ||||
-rw-r--r-- | doc/mailfromd.texi | 86 | ||||
-rw-r--r-- | mfd/drivers.c | 115 | ||||
-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, 276 insertions, 99 deletions
@@ -1,4 +1,4 @@ | |||
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. |
4 | 4 | ||
@@ -24,6 +24,23 @@ is not strictly necessary. However, keep in mind that due to the | |||
24 | specifics of MeTA1, the number of symbols that may be exported for | 24 | 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 | ||
29 | A set of new functions is added that allow to access the headers | 46 | A set of new functions is added that allow to access the headers |
diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi index 3d2e43c5..090222eb 100644 --- a/doc/mailfromd.texi +++ b/doc/mailfromd.texi | |||
@@ -1355,16 +1355,21 @@ execution of the program to stop and to return a response code to | |||
1355 | the @command{Sendmail}. There are five actions, one for each response | 1355 | 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 |
1370 | @group | 1375 | @group |
@@ -1379,6 +1384,25 @@ reject 503 5.0.0 "Need HELO command" | |||
1379 | @noindent | 1384 | @noindent |
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 |
1384 | 1408 | ||
@@ -10253,7 +10277,8 @@ program. | |||
10253 | perform a certain action over the message being processed. There are | 10277 | 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 | ||
10259 | @table @code | 10284 | @table @code |
@@ -10263,14 +10288,16 @@ to the remote party. There are five such actions: | |||
10263 | Return an @code{accept} reply. The remote party will continue | 10288 | Return an @code{accept} reply. The remote party will continue |
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 |
10269 | Return a @code{reject} reply. The remote party will have to | 10295 | Return a @code{reject} reply. The remote party will have to |
10270 | cancel transmitting its message. The three arguments are optional, | 10296 | 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 |
10276 | Return a @samp{temporary failure} reply. The remote party can retry | 10303 | Return a @samp{temporary failure} reply. The remote party can retry |
@@ -10292,7 +10319,12 @@ continue processing of the message. | |||
10292 | 10319 | ||
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 |
10298 | are supplied, the second argument must be either an @dfn{extended | 10330 | are supplied, the second argument must be either an @dfn{extended |
@@ -10313,6 +10345,40 @@ reject 503 5.0.0 "Need HELO command" | |||
10313 | @end group | 10345 | @end group |
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 |
10318 | @cindex actions, header manipulation | 10384 | @cindex actions, header manipulation |
diff --git a/mfd/drivers.c b/mfd/drivers.c index d8dfb4b2..ed8a288a 100644 --- a/mfd/drivers.c +++ b/mfd/drivers.c | |||
@@ -889,62 +889,107 @@ code_type_un(NODE *node, struct locus **old_locus) | |||
889 | void | 889 | 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 | 895 | xcode = node->v.ret.xcode; | |
896 | print_level(level); | 896 | |
897 | if (node->v.ret.message) { | ||
898 | if (node->v.ret.message->type == node_type_string) | ||
899 | s = node->v.ret.message->v.literal->text; |