Add maildirfolder_create_regex to appendfile.
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Thu, 27 Apr 2006 08:53:24 +0000 (08:53 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Thu, 27 Apr 2006 08:53:24 +0000 (08:53 +0000)
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
doc/doc-txt/OptionLists.txt
src/src/transports/appendfile.c
src/src/transports/appendfile.h
src/src/transports/tf_maildir.c
src/src/transports/tf_maildir.h
test/confs/5009
test/scripts/5000-maildir/5009

index 24233428557dd81cd507b6f7aa53dd34417e8753..822c9349160cbe5bff2702a13af6949af7226c68 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.348 2006/04/25 14:02:29 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.349 2006/04/27 08:53:24 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -50,6 +50,8 @@ PH/09 If maildir_quota_directory_regex was set to exclude (say) the .Trash
       excluded directory. This bug has been fixed by ignoring all quota
       processing for deliveries into excluded directories.
 
+PH/10 Added the maildirfolder_create_regex option to appendfile.
+
 
 Exim version 4.61
 -----------------
index dc03699f374ab3212bbee11bc5e35c4d5e76abf9..264501b01f6f5ec667ce6caeb8fb47eacfa55cd9 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.101 2006/04/20 14:11:29 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.102 2006/04/27 08:53:24 ph10 Exp $
 
 New Features in Exim
 --------------------
@@ -29,6 +29,11 @@ Version 4.62
    incoming address, and the relevant transport has batch_max set greater than
    one, a batch delivery now occurs.
 
+3. The appendfile transport has a new option called maildirfolder_create_regex.
+   Its value is a regular expression. For a maildir delivery, this is matched
+   against the maildir directory; if it matches, Exim ensures that a
+   maildirfolder file is created alongside the new, cur, and tmp directories.
+
 
 Version 4.61
 ------------
index d4c27305a91fa66c7d7e6b0cc41d381d84ff1a57..80be8a7b816a598cf946d5c66b345bc5b282582d 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.19 2006/02/28 12:42:47 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.20 2006/04/27 08:53:24 ph10 Exp $
 
 LISTS OF EXIM OPTIONS
 ---------------------
@@ -11,7 +11,7 @@ This file contains complete lists of four kinds of Exim option:
   4. Those that can appear in the build time configuration for the Exim monitor
      (Local/eximon.conf).
 
-This file was last updated for Exim release 4.61.
+This file was last updated for Exim release 4.62.
 
 
 1. RUN TIME OPTIONS
@@ -314,6 +314,7 @@ maildir_format                       boolean         false         appendfile
 maildir_retries                      integer         10            appendfile        1.70
 maildir_tag                          string*         unset         appendfile        1.92
 maildir_use_size_file                boolean         false         appendfile        4.30
+maildirfolder_create_regex           string          unset         appendfile        4.62
 mailstore_format                     boolean         false         appendfile        2.00
 mailstore_prefix                     string*         unset         appendfile        2.00
 mailstore_suffix                     string*         unset         appendfile        2.00
index d7f2705448b17501046bbd45f135c5b12e5e4082..76acded26db3d801f285e6efd5922d4fa4016a89 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.17 2006/04/25 14:02:30 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.18 2006/04/27 08:53:24 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -107,6 +107,8 @@ optionlist appendfile_transport_options[] = {
       (void *)offsetof(appendfile_transport_options_block, maildir_tag) },
   { "maildir_use_size_file", opt_bool,
       (void *)offsetof(appendfile_transport_options_block, maildir_use_size_file ) } ,
+  { "maildirfolder_create_regex", opt_stringptr,
+      (void *)offsetof(appendfile_transport_options_block, maildirfolder_create_regex ) },
 #endif  /* SUPPORT_MAILDIR */
 #ifdef SUPPORT_MAILSTORE
   { "mailstore_format",  opt_bool,
@@ -184,6 +186,7 @@ appendfile_transport_options_block appendfile_transport_option_defaults = {
   NULL,           /* mailbox_filecount_string */
   US"^(?:cur|new|\\..*)$",  /* maildir_dir_regex */
   NULL,           /* maildir_tag */
+  NULL,           /* maildirfolder_create_regex */
   NULL,           /* mailstore_prefix */
   NULL,           /* mailstore_suffix */
   NULL,           /* check_string (default changed for non-bsmtp file)*/
@@ -2152,10 +2155,11 @@ else
     }
 
   #ifdef SUPPORT_MAILDIR
-  /* For a maildir delivery, ensure that all the relevant directories exist */
+  /* For a maildir delivery, ensure that all the relevant directories exist,
+  and a maildirfolder file if necessary. */
 
   if (mbformat == mbf_maildir && !maildir_ensure_directories(path, addr,
-    ob->create_directory, ob->dirmode))
+    ob->create_directory, ob->dirmode, ob->maildirfolder_create_regex))
       return FALSE;
   #endif  /* SUPPORT_MAILDIR */
 
@@ -2236,6 +2240,8 @@ else
             {
             *slash = 0;
             check_path = new_check_path;
+            DEBUG(D_transport) debug_printf("maildirfolder file exists: "
+              "quota check directory changed to %s\n", check_path);
             }
           }
         }
index 90330d738924d61df431fb0658d827eccd6da565..63a7c4f02e0e145d8a3838ad9c0ce27aa1fcf09a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/transports/appendfile.h,v 1.4 2006/02/07 11:19:03 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/appendfile.h,v 1.5 2006/04/27 08:53:24 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -25,6 +25,7 @@ typedef struct {
   uschar *mailbox_filecount_string;
   uschar *maildir_dir_regex;
   uschar *maildir_tag;
+  uschar *maildirfolder_create_regex;
   uschar *mailstore_prefix;
   uschar *mailstore_suffix;
   uschar *check_string;
index 50a4c186495aeb470f81bfb818bb3947f33bc434..2eaea4be01489a6ff5b1f020a9f3372224ceece7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/transports/tf_maildir.c,v 1.8 2006/02/07 11:19:03 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/tf_maildir.c,v 1.9 2006/04/27 08:53:24 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -29,19 +29,22 @@ calculations are not hard wired in, but are supplied as a regex. */
 *************************************************/
 
 /* This function is called at the start of a maildir delivery, to ensure that
-all the relevant directories exist.
+all the relevant directories exist. It also creates a maildirfolder file if the
+base directory matches a given pattern.
 
 Argument:
   path              the base directory name
   addr              the address item (for setting an error message)
   create_directory  true if we are allowed to create missing directories
   dirmode           the mode for created directories
+  maildirfolder_create_regex
+                    the pattern to match for maildirfolder creation
 
 Returns:            TRUE on success; FALSE on failure
 */
 
 BOOL maildir_ensure_directories(uschar *path, address_item *addr,
-  BOOL create_directory, int dirmode)
+  BOOL create_directory, int dirmode, uschar *maildirfolder_create_regex)
 {
 int i;
 struct stat statbuf;
@@ -52,7 +55,7 @@ DEBUG(D_transport)
 
 /* First ensure that the path we have is a directory; if it does not exist,
 create it. Then make sure the tmp, new & cur subdirs of the maildir are
-there. If not, fail which aborts the delivery (even though the cur subdir is
+there. If not, fail. This aborts the delivery (even though the cur subdir is
 not actually needed for delivery). Handle all 4 directory tests/creates in a
 loop so that code can be shared. */
 
@@ -135,7 +138,55 @@ for (i = 0; i < 4; i++)
     }
   }
 
-return TRUE;   /* All directories exist */
+/* If the basic path matches maildirfolder_create_regex, we are dealing with
+a subfolder, and should ensure that a maildirfolder file exists. */
+
+if (maildirfolder_create_regex != NULL)
+  {
+  const uschar *error;
+  int offset;
+  const pcre *regex;
+
+  DEBUG(D_transport) debug_printf("checking for maildirfolder requirement\n");
+
+  regex = pcre_compile(CS maildirfolder_create_regex, PCRE_COPT,
+    (const char **)&error, &offset, NULL);
+
+  if (regex == NULL)
+    {
+    addr->message = string_sprintf("appendfile: regular expression "
+      "error: %s at offset %d while compiling %s", error, offset,
+      maildirfolder_create_regex);
+    return FALSE;
+    }
+
+  if (pcre_exec(regex, NULL, CS path, Ustrlen(path), 0, 0, NULL, 0) >= 0)
+    {
+    uschar *fname = string_sprintf("%s/maildirfolder", path);
+    if (Ustat(fname, &statbuf) == 0)
+      {
+      DEBUG(D_transport) debug_printf("maildirfolder already exists\n");
+      }
+    else
+      {
+      int fd = Uopen(fname, O_WRONLY|O_APPEND|O_CREAT, 0);
+      if (fd < 0)
+        {
+        addr->message = string_sprintf("appendfile: failed to create "
+          "maildirfolder file in %s directory: %s", path, strerror(errno));
+        return FALSE;
+        }
+      (void)close(fd);
+      DEBUG(D_transport) debug_printf("created maildirfolder file\n");
+      }
+    }
+  else
+    {
+    DEBUG(D_transport) debug_printf("maildirfolder file not required\n");
+    }
+  }
+
+return TRUE;   /* Everything exists that should exist */
 }
 
 
index 727abf45962760e9db711aec6f05e56bc8e33cd4..e892618b8b979431bab0f7198eadebac67eb26ad 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/transports/tf_maildir.h,v 1.4 2006/02/07 11:19:03 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/tf_maildir.h,v 1.5 2006/04/27 08:53:24 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -12,7 +12,8 @@ maildirsize files for quota handling in maildir directories. */
 
 extern off_t  maildir_compute_size(uschar *, int *, time_t *, const pcre *,
                 const pcre *, BOOL);
-extern BOOL   maildir_ensure_directories(uschar *, address_item *, BOOL, int);
+extern BOOL   maildir_ensure_directories(uschar *, address_item *, BOOL, int,
+                uschar *);
 extern int    maildir_ensure_sizefile(uschar *,
                 appendfile_transport_options_block *, const pcre *,
                 const pcre *, off_t *, int *);
index a2f673d9ec970a5ffdefaadfc0262ea13cae2223..aa87fecd10cac1f1be973b1365a849715a73340c 100644 (file)
@@ -36,6 +36,7 @@ t1:
   maildir_format
   maildir_use_size_file
   maildir_quota_directory_regex = ^(?:cur|new|\.(?!Trash).*)$
+  maildirfolder_create_regex = /\.[^/]+$
   quota = 1M
 
 
index 1a2e5fc3af42358c260db66780ee2f9be2e7073d..20d4157895e3ace4f4ddd12949813aeac9acacce 100644 (file)
@@ -4,14 +4,14 @@ exim -odi userx@test.ex
 Test message
 ****
 cat DIR/test-mail/maildirsize >>test-stdout
-mkdir test-mail/.Sub
-touch test-mail/.Sub/maildirfolder
+#mkdir test-mail/.Sub
+#touch test-mail/.Sub/maildirfolder
 exim -DSUB=.Sub -odi userx@test.ex
 Test message
 ****
 cat DIR/test-mail/maildirsize >>test-stdout
-mkdir test-mail/.Trash
-touch test-mail/.Trash/maildirfolder
+#mkdir test-mail/.Trash
+#touch test-mail/.Trash/maildirfolder
 exim -DSUB=.Trash -odi userx@test.ex
 Test message
 ****