[exim] [PATCH] exim_fixdb

Top Page
Delete this message
Reply to this message
Author: Brian Candler
Date:  
To: exim-users
Subject: [exim] [PATCH] exim_fixdb
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);