Well, there were other errors in the patch, so here is the
new-and-improved version.  I did some testing, and it seems to work.
With this patch, a filter can return "050 Ok", and the message will be
accepted with no more filters being run.  The code gets converted to
"250 Ok" before being passed back to the sender.

--- courier/cdfilters.C.orig	2006-03-19 17:16:09.000000000 -0500
+++ courier/cdfilters.C	2006-03-22 20:50:56.000000000 -0500
@@ -18,4 +18,5 @@
 #include	"localstatedir.h"
 
+
 using namespace std;
 
@@ -26,4 +27,60 @@
 	void *);
 
+#define FILTER_LIST_INCREMENT	8
+#define MEMORY_ERROR	"432 Out of memory when processing mail filters.\n"
+
+static char **filterlist   = NULL;
+static int  filterlistsize = 0;
+static int  nfilters	   = 0;
+
+static void free_filters()
+{
+	if (filterlist != NULL)
+	{
+		for (int n = 0; n < nfilters; n++)
+		{
+			free(filterlist[n]);
+		}
+	}
+	nfilters = 0;
+}
+
+static int add_filter(const char *filter)
+{
+char	*dupfilter = strdup(filter);
+
+	if (dupfilter == NULL)
+	{
+		cout << MEMORY_ERROR << flush;
+		return (1);
+	}
+
+	if (nfilters >= filterlistsize)
+	{
+		if (filterlist == NULL)
+		{
+			filterlist = (char **) malloc(sizeof (char *) *
+						      FILTER_LIST_INCREMENT);
+		}
+		else
+		{
+			filterlist = (char **) realloc(filterlist,
+						       sizeof (char *) *
+						       (filterlistsize +
+							FILTER_LIST_INCREMENT));
+		}
+		if (filterlist == NULL)
+		{
+			free(dupfilter);
+			cout << MEMORY_ERROR << flush;
+			return (1);
+		}
+		filterlistsize += FILTER_LIST_INCREMENT;
+	}
+
+	filterlist[nfilters++] = dupfilter;
+	return (0);
+}
+
 int run_filter(const char *filename,
 	unsigned nmsgids,
@@ -37,7 +94,9 @@
 struct dirent *de;
 CString	sockname;
+int	rc;
 
 	if (!iswhitelisted)
 	{
+		free_filters();
 		dirp=opendir(FILTERSOCKETDIR);
 		while (dirp && (de=readdir(dirp)) != 0)
@@ -47,16 +106,30 @@
 			sockname = FILTERSOCKETDIR "/";
 			sockname += de->d_name;
-			if (dofilter( sockname,
-					filename, nmsgids,
-					msgidfunc,
-					funcarg))
+			if (add_filter(sockname) != 0)
 			{
-				closedir(dirp);
 				return (1);
 			}
 		}
 		if (dirp)	closedir(dirp);
+
+		qsort((void *) filterlist,
+		      (size_t) nfilters,
+		      sizeof (char *),
+		      (int (*)(const void*, const void*)) strcmp);
+
+		for (int n = 0; n < nfilters; n++)
+		{
+			rc = dofilter( filterlist[n],
+				       filename, nmsgids,
+				       msgidfunc,
+				       funcarg);
+			if (rc)
+			{
+				return (rc < 0 ? 0 : rc);
+			}
+		}
 	}
 
+	free_filters();
 	dirp=opendir(ALLFILTERSOCKETDIR);
 	while (dirp && (de=readdir(dirp)) != 0)
@@ -66,14 +139,28 @@
 		sockname = ALLFILTERSOCKETDIR "/";
 		sockname += de->d_name;
-		if (dofilter( sockname,
-				filename, nmsgids,
-				msgidfunc,
-				funcarg))
+		if (add_filter(sockname) != 0)
 		{
-			closedir(dirp);
 			return (1);
 		}
 	}
 	if (dirp)	closedir(dirp);
+
+	qsort((void *) filterlist,
+	      (size_t) nfilters,
+	      sizeof (char *),
+	      (int (*)(const void*, const void*)) strcmp);
+
+	for (int n = 0; n < nfilters; n++)
+	{
+		rc = dofilter( filterlist[n],
+			       filename, nmsgids,
+			       msgidfunc,
+			       funcarg);
+		if (rc)
+		{
+			return (rc < 0 ? 0 : rc);
+		}
+	}
+
 	return (0);
 }
@@ -158,5 +245,4 @@
 		if (sockname.GetLength() == 0)
 			sockname=" ";
-
 		sockstream << sockname << '\n';
 	}
@@ -188,5 +274,5 @@
 	if (isdigit(d))
 	{
-		if (d != '4' && d != '5')
+		if (d != '0' && d != '4' && d != '5')
 		{
 			while (isdigit(sockname[0]) &&
@@ -204,4 +290,10 @@
 	}
 
+	rc = 1;
+	if (d == '0')
+	{
+		sockname[0] = '2';
+		rc = -1;
+	}
 	cout << sockname << "\n";
 
@@ -216,4 +308,4 @@
 	sockstream.close();
 	close(s);
-	return (1);
+	return (rc);
 }

-- 
 Lloyd Zusman
 [EMAIL PROTECTED]
 God bless you.

Reply via email to