On Thu, Jul 06, 2006 at 07:16:08PM +0200, Jakob Hirsch wrote:
> Ian P. Christian wrote:
>
> > To do this, I obviously need to generate a random number - is this possible in
> > the ACLs? I've hacked it in using perl at the moment, but I'm just curious as
>
> I don't think it's a good idea to do such stuff in the MTA, during SMTP
> connections. Anyway, this might help you:
> http://www.exim.org/mail-archives/exim-users/Week-of-Mon-20060109/msg00051.html
I don't think that would be a good idea for Ian's
application, since it would mean that his cleanup query
could be multiple times in a given second if there were
several incoming connections then (and I agree with you
about not doing this sort of thing at SMTP time).
If you can find a set of suitable variables, you could do
this with a message-digest function; for instance, if you
check that
${substr_0_3:${md5:...}}
is, say, `000', then that gives you odds of 1 in 4096 that
your function will be run. But that means finding a
suitable ... which varies enough. For instance, if you're
running your cleanup process from the connect ACL, you
could hash the time of day, process-ID, remote IP and
remote port, and you should be reasonably safe I suppose.
For finer control over the ratios, you can turn the
output of the hash function into a number with something
like,
${eval:(0x${substr_0_8:${md5:...}} / ...) }
Here's a patch (as yet untested) which would add a
$random_LOW_HIGH expansion pseudovariable to Exim:
--- expand.c.orig 2006-07-06 18:55:31.000000000 +0100
+++ expand.c 2006-07-06 19:05:00.000000000 +0100
@@ -2710,6 +2710,34 @@
}
}
+ /* Random number */
+ else if (Ustrncmp(name, "random_", 7) == 0)
+ {
+ /* Followed by lower and upper limit of number required. */
+ int low, high;
+ uschar *endptr, *p;
+ static int seeded;
+ if (!seeded)
+ {
+ srand(time(NULL));
+ seeded = 1;
+ }
+ low = (int)Ustrtol((const uschar *)name + 7, &endptr, 10);
+ if (endptr == name + 7 || *endptr != '_')
+ {
+ expand_string_message = "random_ must be followed by lower and upper limits";
+ return NULL;
+ }
+ p = endptr + 1;
+ high = (int)Ustrtol((const uschar *)endptr, &endptr, 10);
+ if (endptr == p || high <= low)
+ {
+ expand_string_message = "random_ must be followed by lower and upper limits";
+ return NULL;
+ }
+ value = string_sprintf("%d", low + (high - low) * (double)rand() / (RAND_MAX - 1.));
+ }
+
/* Variable */
else
--
``[To] call this novel formulaic is an insult
to the beauty and diversity of formulae.''
(Geoff Pullum reviews a Dan Brown novel)