I just found some silly bugs in exim_fixdb which prevent it from being used
to edit ratelimit databases. Firstly:
# exim_dumpdb /var/spool/exim ratelimit
14-Sep-2005 19:41:04.732567 rate: 31.208 key: 1h/per_rcpt/strict/web40000
14-Sep-2005 18:00:36.233889 rate: 5.466 key: 1h/per_rcpt/strict/web10000
# exim_fixdb /var/spool/exim ratelimit
Modifying Exim hints database /var/spool/exim/db/ratelimit
> 1h/per_rcpt/strict/web40000
No previous record name is set
>
This is due to logic in exim_fixdb which treats a line starting with a digit
followed by any non-digit as being a field number plus value instead of a
key.
Once that's sorted, fixdb doesn't display the field contents properly:
# exim_dumpdb /var/spool/exim ratelimit
14-Sep-2005 19:41:04.732567 rate: 31.208 key: 1h/per_rcpt/strict/web40000
14-Sep-2005 18:00:36.233889 rate: 5.466 key: 1h/per_rcpt/strict/web10000
# exim_fixdb /var/spool/exim ratelimit
Modifying Exim hints database /var/spool/exim/db/ratelimit
> 1h/per_rcpt/strict/web40000
14-Sep-2005 19:41:04
0 time stamp: 01-Jan-1970 01:00:00
1 fract. time: .000000
2 sender rate: 0.000
>
The attached patch fixes this too (and demonstrates the evilness of using
pointer casts in C :-) exim_fixdb now works for me.
Aside: note that the timestamp is always reset in dbfn_write. So although
the code allows you to choose a new timestamp value by setting field 0 to a
new value, it doesn't actually achieve anything.
Regards,
Brian.
--- exim-4.52/src/exim_dbutil.c.orig Wed Sep 14 19:53:47 2005
+++ exim-4.52/src/exim_dbutil.c Wed Sep 14 21:09:40 2005
@@ -767,7 +767,7 @@
/* If the buffer contains just one digit, or just consists of "d", use the
previous name for an update. */
- if ((isdigit((uschar)buffer[0]) && !isdigit((uschar)buffer[1])) ||
+ if ((isdigit((uschar)buffer[0]) && (buffer[1] == ' ' || buffer[1] == 0)) ||
Ustrcmp(buffer, "d") == 0)
{
if (name[0] == 0)
@@ -894,7 +894,8 @@
break;
case type_ratelimit:
- ratelimit = (dbdata_ratelimit *)value;
+ ratelimit = (dbdata_ratelimit *)record;
+ length = sizeof(dbdata_ratelimit);
switch(fieldno)
{
case 0:
@@ -904,6 +905,7 @@
case 1:
ratelimit->time_usec = Uatoi(value);
+ break;
case 2:
ratelimit->rate = Ustrtod(value, NULL);
@@ -1014,7 +1016,7 @@
break;
case type_ratelimit:
- ratelimit = (dbdata_ratelimit *)value;
+ ratelimit = (dbdata_ratelimit *)record;
printf("0 time stamp: %s\n", print_time(ratelimit->time_stamp));
printf("1 fract. time: .%06d\n", ratelimit->time_usec);
printf("2 sender rate: % .3f\n", ratelimit->rate);