[Exim] Expiring mails in appendfile.c

Top Page
Delete this message
Reply to this message
Author: Michael Haardt
Date:  
To: exim-users
Subject: [Exim] Expiring mails in appendfile.c
Hello,

the patch below is not tested and incomplete by intention (prototype
changes are missing), but a suggestion how easy it would be to provide the
mechanism for expiring files in mailboxes or cleaning up stale tmp files.
Any opinions?

To make use of it, we had to agree on a way to specify the file age,
e.g. as a transport option to appendfile, which could also be set from
a filter. That way you could keep the last two weeks spam mail and
purge older spam mails when newer mails come in. Hmm. Sounds tempting
for TODO folders, too. :-)

Michael
----------------------------------------------------------------------
--- src/transports/appendfile.c.orig    2004-02-13 14:23:04.000000000 +0100
+++ src/transports/appendfile.c    2004-02-13 15:12:21.000000000 +0100
@@ -669,15 +669,17 @@
                 zero if the directory cannot be opened
 */


-int
-check_dir_size(uschar *dirname, int *countptr, const pcre *regex)
+off_t
+check_dir_size(uschar *dirname, int *countptr, const pcre *regex, int maxage)
{
DIR *dir;
int sum = 0;
int count = *countptr;
struct dirent *ent;
struct stat statbuf;
+time_t now;

+time(&now);
dir = opendir(CS dirname);
if (dir == NULL) return 0;

@@ -688,7 +690,7 @@

if (Ustrcmp(name, ".") == 0 || Ustrcmp(name, "..") == 0) continue;

- count++;
+ ++count;

   if (!string_format(buffer, sizeof(buffer), "%s/%s", dirname, name))
     {
@@ -705,14 +707,22 @@
     int ovector[6];
     if (pcre_exec(regex, NULL, CS name, Ustrlen(name), 0, 0, ovector,6) >= 2)
       {
-      int size;
-      int n = ovector[3] - ovector[2];
-      Ustrncpy(buffer, name + ovector[2], n);
-      buffer[n] = 0;
-      size = Uatoi(buffer);
-      sum += size;
-      DEBUG(D_transport)
-        debug_printf("check_dir_size: size from %s is %d\n", name, size);
+      off_t size;
+      time_t birthday;
+
+      birthday = Uatoi(CS name);
+      if ((maxage != 0) && (birthday+maxage < now))
+        {
+        unlink(name);
+        --count;
+        }
+      else
+        {
+        size = Uatoi(name + ovector[2]);
+        sum += size;
+        DEBUG(D_transport)
+          debug_printf("check_dir_size: size from %s is %d\n", name, size);
+        }
       continue;
       }
     DEBUG(D_transport)
@@ -730,9 +740,17 @@
     }


   if ((statbuf.st_mode & S_IFMT) == S_IFREG)
-    sum += statbuf.st_size;
+    {
+    if ((maxage != 0) && (statbuf.st_ctime+maxage < now))
+      {
+      unlink(name);
+      --count;
+      }
+    else
+      sum += statbuf.st_size;
+    }
   else if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
-    sum += check_dir_size(buffer, &count, regex);
+    sum += check_dir_size(buffer, &count, regex, maxage);
   }


 closedir(dir);
@@ -2145,7 +2163,7 @@
       {
       DEBUG(D_transport)
         debug_printf("quota checks on directory %s\n", check_path);
-      saved_size = check_dir_size(check_path, &dircount, regex);
+      saved_size = check_dir_size(check_path, &dircount, regex, 0);
       }


     /* This code came originally from Justo Alonso. It makes use of functions