Next: Sending Rate, Previous: rset, Up: Tutorial [Contents][Index]
Any MTA provides a way to limit the number of recipients
per message. For example, in Sendmail
you may use the
MaxRecipientsPerMessage
option8. However, such methods are not flexible, so
you are often better off using mailfromd
for this purpose.
Mailfromd
keeps the number of recipients collected so far
in variable rcpt_count
, which can be controlled in
envrcpt
handler as shown in the example below:
prog envrcpt do if rcpt_count > 10 reject 550 5.7.1 "Too many recipients" fi done
This filter will accept no more than 10 recipients per message. You may achieve finer granularity by using additional conditions. For example, the following code will allow any number of recipients if the mail is coming from a domain relayed by the server, while limiting it to 10 for incoming mail from other domains:
prog envrcpt do if not relayed(hostname($client_addr)) and rcpt_count > 10 reject 550 5.7.1 "Too many recipients" fi done
There are three important features to notice in the above code.
First of all, it introduces two boolean operators:
and
, which evaluates to true
only if both
left-side and right-side expressions are true
, and not
,
which reverses the value of its argument.
Secondly, the scope of an operation is determined by its
precedence, or binding strength. Not
binds more
tightly than and
, so its scope is limited by the next
expression between it and and
. Using parentheses to underline the
operator scoping, the above if
condition can be rewritten as
follows:
if (not (relayed(hostname($client_addr)))) and (%rcpt_count > 10)
Finally, it is important to notice that all boolean expressions
are computed using shortcut evaluation. To understand what it
is, let’s consider the following expression: x and
y
. Its value is true
only if both x and y
are true
. Now suppose that we evaluate the expression from
left to right and we find that x is false. This means that
no matter what the value of y is, the resulting expression will be
false
, therefore there is no need to compute y at all.
So, the boolean shortcut evaluation works as follows:
x and y
If x ⇒
, do not evaluate y and
return false
false
.
x or y
If x ⇒
, do not evaluate y and
return true
true
.
Thus, in the expression not relayed(hostname($client_addr)) and
rcpt_count > 10
, the value of the rcpt_count
variable will be
compared with ‘10’ only if the relayed
function yielded
false
.
To further enhance our sample filter, you may wish to make the
reject
output more informative, to let the sender know what
the recipient limit is. To do so, you can use the concatenation
operator ‘.’ (a dot):
set max_rcpt 10 prog envrcpt do if not relayed(hostname($client_addr)) and rcpt_count > 10 reject 550 5.7.1 "Too many recipients, max=" . max_rcpt fi done
When evaluating the third argument to reject
,
mailfromd
will first convert max_rcpt
to string and
then concatenate both strings together, producing string ‘Too many
recipients, max=10’.
Next: Sending Rate, Previous: rset, Up: Tutorial [Contents][Index]