diff src/sm-archive.cpp @ 13:75e1a9bcbc2e

gpl3, add removal option for original recipients
author carl
date Sat, 25 Aug 2007 11:14:49 -0700
parents f9e8bbf33a2a
children 8ebecad6530f
line wrap: on
line diff
--- a/src/sm-archive.cpp	Mon Mar 19 22:38:37 2007 -0700
+++ b/src/sm-archive.cpp	Sat Aug 25 11:14:49 2007 -0700
@@ -1,11 +1,11 @@
 /*
 
-Copyright (c) 2004, 2005 Carl Byington - 510 Software Group, released
-under the GPL version 2 or any later version at your choice available at
-http://www.fsf.org/licenses/gpl.txt
+Copyright (c) 2007 Carl Byington - 510 Software Group, released under
+the GPL version 3 or any later version at your choice available at
+http://www.gnu.org/licenses/gpl-3.0.txt
 
 Based on a sample milter Copyright (c) 2000-2003 Sendmail, Inc. and its
-suppliers.	Inspired by the DCC by Rhyolite Software
+suppliers.
 
 -p port  The port through which the MTA will connect to this milter.
 -t sec	 The timeout value.
@@ -89,6 +89,11 @@
 
 void mlfiPriv::reset(bool final) {
 	targets.clear();
+	for (string_set::iterator i=removal.begin(); i!=removal.end(); i++) {
+		char *remove = (*i);
+		free(remove);
+	}
+	removal.clear();
 	if (mailaddr) free(mailaddr);
 	if (queueid)  free(queueid);
 	if (!final) {
@@ -174,6 +179,15 @@
 	}
 }
 
+void add_remove(mlfiPriv &priv, char *remove);
+void add_remove(mlfiPriv &priv, char *remove)
+{
+	if (remove) {
+		string_set::iterator i = priv.removal.find(remove);
+		if (i == priv.removal.end()) priv.removal.insert(remove);
+	}
+}
+
 sfsistat mlfi_envrcpt(SMFICTX *ctx, char **rcpt)
 {
 	mlfiPriv &priv = *MLFIPRIV;
@@ -186,8 +200,10 @@
 		my_syslog(&priv, msg);
 	}
 	char *target = dc.find_to(rcptaddr);
+	add_target(priv, target);
+	bool remove  = dc.find_remove(rcptaddr);
+	if (remove) add_remove(priv, strdup(rcptaddr));
 	free(rcptaddr);
-	add_target(priv, target);
 	return SMFIS_CONTINUE;
 }
 
@@ -206,6 +222,15 @@
 			my_syslog(&priv, msg);
 		}
 	}
+	for (string_set::iterator i=priv.removal.begin(); i!=priv.removal.end(); i++) {
+		char *remove = (*i);
+		smfi_delrcpt(ctx, remove);
+		if (debug_syslog > 1) {
+			char msg[maxlen];
+			snprintf(msg, sizeof(msg), "removing recipient <%s>", remove);
+			my_syslog(&priv, msg);
+		}
+	}
 	// reset for a new message on the same connection
 	mlfi_abort(ctx);
 	return SMFIS_CONTINUE;
@@ -231,7 +256,8 @@
 {
 	"SM-ARCHIVE",       // filter name
 	SMFI_VERSION,		// version code -- do not change
-	SMFIF_ADDRCPT,		// flags
+	SMFIF_ADDRCPT | \
+	SMFIF_DELRCPT,		// flags
 	mlfi_connect,		// connection info filter
 	NULL,				// SMTP HELO command filter
 	mlfi_envfrom,		// envelope sender filter
@@ -275,8 +301,6 @@
 //
 extern "C" {void* config_loader(void *arg);}
 void* config_loader(void *arg) {
-	typedef set<CONFIG *> configp_set;
-	configp_set old_configs;
 	while (loader_run) {
 		sleep(180);  // look for modifications every 3 minutes
 		if (!loader_run) break;
@@ -296,9 +320,10 @@
 				// replace the global config pointer
 				pthread_mutex_lock(&config_mutex);
 					CONFIG *old = config;
+					bool last = old && (!old->reference_count);
 					config = newc;
 				pthread_mutex_unlock(&config_mutex);
-				if (old) old_configs.insert(old);
+				if (last) delete old;	// there were no references to this config
 			}
 			else {
 				// failed to load new config
@@ -308,20 +333,6 @@
 				dc.load_time = time(NULL);
 			}
 		}
-		// now look for old configs with zero ref counts
-		for (configp_set::iterator i=old_configs.begin(); i!=old_configs.end(); ) {
-			CONFIG *old = *i;
-			if (!old->reference_count) {
-				if (debug_syslog) {
-					char buf[maxlen];
-					snprintf(buf, sizeof(buf), "freeing memory for old configuration generation %d", old->generation);
-					my_syslog(buf);
-				}
-				delete old; // destructor does all the work
-				old_configs.erase(i++);
-			}
-			else i++;
-		}
 	}
 	return NULL;
 }
@@ -428,6 +439,7 @@
 		if (conf) {
 			conf->dump();
 			delete conf;
+			clear_strings();	// for valgrind checking
 			return 0;
 		}
 		else {