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
 -------------------------------------------
 
 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.
 
       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
 -----------------
 
 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
 --------------------
 
 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.
 
    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
 ------------
 
 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
 ---------------------
 
 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).
 
   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
 
 
 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
 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
 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    *
 
 /*************************************************
 *     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 ) } ,
       (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,
 #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,           /* 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)*/
   NULL,           /* mailstore_prefix */
   NULL,           /* mailstore_suffix */
   NULL,           /* check_string (default changed for non-bsmtp file)*/
@@ -2152,10 +2155,11 @@ else
     }
 
   #ifdef SUPPORT_MAILDIR
     }
 
   #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,
 
   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 */
 
       return FALSE;
   #endif  /* SUPPORT_MAILDIR */
 
@@ -2236,6 +2240,8 @@ else
             {
             *slash = 0;
             check_path = new_check_path;
             {
             *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    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -25,6 +25,7 @@ typedef struct {
   uschar *mailbox_filecount_string;
   uschar *maildir_dir_regex;
   uschar *maildir_tag;
   uschar *mailbox_filecount_string;
   uschar *maildir_dir_regex;
   uschar *maildir_tag;
+  uschar *maildirfolder_create_regex;
   uschar *mailstore_prefix;
   uschar *mailstore_suffix;
   uschar *check_string;
   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    *
 
 /*************************************************
 *     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
 *************************************************/
 
 /* 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
 
 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,
 
 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;
 {
 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
 
 /* 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. */
 
 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    *
 
 /*************************************************
 *     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 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 *);
 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).*)$
   maildir_format
   maildir_use_size_file
   maildir_quota_directory_regex = ^(?:cur|new|\.(?!Trash).*)$
+  maildirfolder_create_regex = /\.[^/]+$
   quota = 1M
 
 
   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
 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
 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
 ****
 exim -DSUB=.Trash -odi userx@test.ex
 Test message
 ****