Fix bug 1224.
[exim.git] / src / src / rda.c
index 06eff227e689d6c253e90cfe6da411f4b5bbc917..877434098067d32d8037e3bb761793a860bebc1e 100644 (file)
@@ -1,10 +1,8 @@
-/* $Cambridge: exim/src/src/rda.c,v 1.8 2005/06/27 14:29:43 ph10 Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2005 */
+/* Copyright (c) University of Cambridge 1995 - 2009 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* This module contains code for extracting addresses from a forwarding list
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* This module contains code for extracting addresses from a forwarding list
@@ -327,6 +325,7 @@ Arguments:
   options                   the options bits
   include_directory         restrain to this directory
   sieve_vacation_directory  passed to sieve_interpret
   options                   the options bits
   include_directory         restrain to this directory
   sieve_vacation_directory  passed to sieve_interpret
+  sieve_enotify_mailto_owner passed to sieve_interpret
   sieve_useraddress         passed to sieve_interpret
   sieve_subaddress          passed to sieve_interpret
   generated                 where to hang generated addresses
   sieve_useraddress         passed to sieve_interpret
   sieve_subaddress          passed to sieve_interpret
   generated                 where to hang generated addresses
@@ -344,15 +343,16 @@ Returns:                    a suitable return for rda_interpret()
 
 static int
 rda_extract(redirect_block *rdata, int options, uschar *include_directory,
 
 static int
 rda_extract(redirect_block *rdata, int options, uschar *include_directory,
-  uschar *sieve_vacation_directory, uschar *sieve_useraddress,
-  uschar *sieve_subaddress, address_item **generated, uschar **error,
-  error_block **eblockp, int *filtertype)
+  uschar *sieve_vacation_directory, uschar *sieve_enotify_mailto_owner,
+  uschar *sieve_useraddress, uschar *sieve_subaddress,
+  address_item **generated, uschar **error, error_block **eblockp,
+  int *filtertype)
 {
 uschar *data;
 
 if (rdata->isfile)
   {
 {
 uschar *data;
 
 if (rdata->isfile)
   {
-  int yield;
+  int yield = 0;
   data = rda_get_file_contents(rdata, options, error, &yield);
   if (data == NULL) return yield;
   }
   data = rda_get_file_contents(rdata, options, error, &yield);
   if (data == NULL) return yield;
   }
@@ -405,7 +405,8 @@ if (*filtertype != FILTER_FORWARD)
       return FF_ERROR;
       }
     frc = sieve_interpret(data, options, sieve_vacation_directory,
       return FF_ERROR;
       }
     frc = sieve_interpret(data, options, sieve_vacation_directory,
-      sieve_useraddress, sieve_subaddress, generated, error);
+      sieve_enotify_mailto_owner, sieve_useraddress, sieve_subaddress,
+      generated, error);
     }
 
   expand_forbid = old_expand_forbid;
     }
 
   expand_forbid = old_expand_forbid;
@@ -511,7 +512,8 @@ Arguments:
   options                   options to pass to the extraction functions,
                               plus ENOTDIR and EACCES handling bits
   include_directory         restrain :include: to this directory
   options                   options to pass to the extraction functions,
                               plus ENOTDIR and EACCES handling bits
   include_directory         restrain :include: to this directory
-  sieve_vacation_directory  directory passed to sieve_interpret()
+  sieve_vacation_directory  directory passed to sieve_interpret
+  sieve_enotify_mailto_owner passed to sieve_interpret
   sieve_useraddress         passed to sieve_interpret
   sieve_subaddress          passed to sieve_interpret
   ugid                      uid/gid to run under - if NULL, no change
   sieve_useraddress         passed to sieve_interpret
   sieve_subaddress          passed to sieve_interpret
   ugid                      uid/gid to run under - if NULL, no change
@@ -540,9 +542,10 @@ Returns:        values from extraction function, or FF_NONEXIST:
 
 int
 rda_interpret(redirect_block *rdata, int options, uschar *include_directory,
 
 int
 rda_interpret(redirect_block *rdata, int options, uschar *include_directory,
-  uschar *sieve_vacation_directory, uschar *sieve_useraddress,
-  uschar *sieve_subaddress, ugid_block *ugid, address_item **generated,
-  uschar **error, error_block **eblockp, int *filtertype, uschar *rname)
+  uschar *sieve_vacation_directory, uschar *sieve_enotify_mailto_owner,
+  uschar *sieve_useraddress, uschar *sieve_subaddress, ugid_block *ugid,
+  address_item **generated, uschar **error, error_block **eblockp,
+  int *filtertype, uschar *rname)
 {
 int fd, rc, pfd[2];
 int yield, status;
 {
 int fd, rc, pfd[2];
 int yield, status;
@@ -586,8 +589,8 @@ if (!ugid->uid_set ||                         /* Either there's no uid, or */
      Ustrstr(data, ":include:") == NULL))     /* and there's no :include: */
   {
   return rda_extract(rdata, options, include_directory,
      Ustrstr(data, ":include:") == NULL))     /* and there's no :include: */
   {
   return rda_extract(rdata, options, include_directory,
-    sieve_vacation_directory, sieve_useraddress, sieve_subaddress,
-    generated, error, eblockp, filtertype);
+    sieve_vacation_directory, sieve_enotify_mailto_owner, sieve_useraddress,
+    sieve_subaddress, generated, error, eblockp, filtertype);
   }
 
 /* We need to run the processing code in a sub-process. However, if we can
   }
 
 /* We need to run the processing code in a sub-process. However, if we can
@@ -607,9 +610,13 @@ if (pipe(pfd) != 0)
 
 /* Ensure that SIGCHLD is set to SIG_DFL before forking, so that the child
 process can be waited for. We sometimes get here with it set otherwise. Save
 
 /* Ensure that SIGCHLD is set to SIG_DFL before forking, so that the child
 process can be waited for. We sometimes get here with it set otherwise. Save
-the old state for resetting on the wait. */
+the old state for resetting on the wait. Ensure that all cached resources are
+freed so that the subprocess starts with a clean slate and doesn't interfere
+with the parent process. */
 
 oldsignal = signal(SIGCHLD, SIG_DFL);
 
 oldsignal = signal(SIGCHLD, SIG_DFL);
+search_tidyup();
+
 if ((pid = fork()) == 0)
   {
   header_line *waslast = header_last;   /* Save last header */
 if ((pid = fork()) == 0)
   {
   header_line *waslast = header_last;   /* Save last header */
@@ -632,8 +639,8 @@ if ((pid = fork()) == 0)
   /* Now do the business */
 
   yield = rda_extract(rdata, options, include_directory,
   /* Now do the business */
 
   yield = rda_extract(rdata, options, include_directory,
-    sieve_vacation_directory, sieve_useraddress, sieve_subaddress, generated,
-    error, eblockp, filtertype);
+    sieve_vacation_directory, sieve_enotify_mailto_owner, sieve_useraddress,
+    sieve_subaddress, generated, error, eblockp, filtertype);
 
   /* Pass back whether it was a filter, and the return code and any overall
   error text via the pipe. */
 
   /* Pass back whether it was a filter, and the return code and any overall
   error text via the pipe. */
@@ -740,9 +747,11 @@ if ((pid = fork()) == 0)
     rda_write_string(fd, NULL);   /* Marks end of addresses */
     }
 
     rda_write_string(fd, NULL);   /* Marks end of addresses */
     }
 
-  /* OK, this process is now done. Must use _exit() and not exit() !! */
+  /* OK, this process is now done. Free any cached resources. Must use _exit()
+  and not exit() !! */
 
   (void)close(fd);
 
   (void)close(fd);
+  search_tidyup();
   _exit(0);
   }
 
   _exit(0);
   }
 
@@ -764,9 +773,6 @@ if (read(fd, filtertype, sizeof(int)) != sizeof(int) ||
     read(fd, &yield, sizeof(int)) != sizeof(int) ||
     !rda_read_string(fd, error)) goto DISASTER;
 
     read(fd, &yield, sizeof(int)) != sizeof(int) ||
     !rda_read_string(fd, error)) goto DISASTER;
 
-DEBUG(D_route)
-  debug_printf("rda_interpret: subprocess yield=%d error=%s\n", yield, *error);
-
 /* Read the contents of any syntax error blocks if we have a pointer */
 
 if (eblockp != NULL)
 /* Read the contents of any syntax error blocks if we have a pointer */
 
 if (eblockp != NULL)
@@ -923,6 +929,9 @@ while ((rc = wait(&status)) != pid)
     }
   }
 
     }
   }
 
+DEBUG(D_route)
+  debug_printf("rda_interpret: subprocess yield=%d error=%s\n", yield, *error);
+
 if (had_disaster)
   {
   *error = string_sprintf("internal problem in %s: failure to transfer "
 if (had_disaster)
   {
   *error = string_sprintf("internal problem in %s: failure to transfer "