cyrus-imapd 2.1.15, sieve, lmtpd, and return-path header

Chris Stromsoe cbs at cts.ucla.edu
Mon Sep 22 22:02:11 EDT 2003


On Mon, 22 Sep 2003, Pat Lashley wrote:

> --On Monday, September 22, 2003 18:08:23 -0700 Chris Stromsoe
> <cbs at cts.ucla.edu> wrote:
>
> > From what I can tell, ...
> >
> > While there may not be much call to match against the last-hop
> > received header (unless maybe you want to take different actions
> > depending on the origin of mail from different remote last-hop LMTP
> > mta's), there is interest (at least here) for being able to filter on
> > return-path.
>
> Can't you get what you want using the "envelope" extension?

Probably.  "But..." the rules are being generated by smartsieve.  Relying
on smartsieve to know that return-path is special (compared to any other
random header) and that it should use envelope seems a little goofy.  I
can also see some utility in having the return-path and other generated
headers in the header cache.

Anyway, the attached (compiled but untested) patch splits fill_cache()
into a second piece (insert_cache_element()), and uses the new function to
insert the return-path into the header cache.



-Chris
-------------- next part --------------
--- /usr/local/src/bol/cyrus-imapd-2.1.15/imap/lmtpengine.c	2003-07-22 12:17:15.000000000 -0700
+++ lmtpengine.c	2003-09-22 18:56:21.891697000 -0700
@@ -892,6 +892,50 @@
     return 0;
 }
 
+
+static int insert_cache_element (message_data_t *m, char *name, char *body) {
+
+        int cl, clinit;
+
+        /* put it in the hash table */
+        clinit = cl = hashheader(name);
+        while (m->cache[cl] != NULL && strcmp(name, m->cache[cl]->name)) {
+            cl++;               /* resolve collisions linearly */
+            cl %= HEADERCACHESIZE;
+            if (cl == clinit) break; /* gone all the way around, so bail */
+        }
+
+        /* found where to put it, so insert it into a list */
+        if (m->cache[cl]) {
+            /* add this body on */
+            m->cache[cl]->contents[m->cache[cl]->ncontents++] = body;
+
+            /* whoops, won't have room for the null at the end! */
+            if (!(m->cache[cl]->ncontents % 8)) {
+                /* increase the size */
+                m->cache[cl] = (header_t *)
+                    xrealloc(m->cache[cl],sizeof(header_t) +
+                             ((8 + m->cache[cl]->ncontents) * sizeof(char *)));
+            }
+
+            /* have no need of this */
+            free(name);
+        } else {
+            /* create a new entry in the hash table */
+            m->cache[cl] = (header_t *) xmalloc(sizeof(header_t) +
+                                                8 * sizeof(char*));
+            m->cache[cl]->name = name;
+            m->cache[cl]->contents[0] = body;
+            m->cache[cl]->ncontents = 1;
+        }
+
+        /* we always want a NULL at the end */
+        m->cache[cl]->contents[m->cache[cl]->ncontents] = NULL;
+
+        return 0;
+}
+
+
 static int fill_cache(struct protstream *fin, FILE *fout, message_data_t *m)
 {
     int r = 0;
@@ -899,7 +943,6 @@
     /* let's fill that header cache */
     for (;;) {
 	char *name, *body;
-	int cl, clinit;
 
 	if ((r = parseheader(fin, fout, &name, &body)) < 0) {
 	    break;
@@ -909,40 +952,7 @@
 	    break;
 	}
 
-	/* put it in the hash table */
-	clinit = cl = hashheader(name);
-	while (m->cache[cl] != NULL && strcmp(name, m->cache[cl]->name)) {
-	    cl++;		/* resolve collisions linearly */
-	    cl %= HEADERCACHESIZE;
-	    if (cl == clinit) break; /* gone all the way around, so bail */
-	}
-
-	/* found where to put it, so insert it into a list */
-	if (m->cache[cl]) {
-	    /* add this body on */
-	    m->cache[cl]->contents[m->cache[cl]->ncontents++] = body;
-
-	    /* whoops, won't have room for the null at the end! */
-	    if (!(m->cache[cl]->ncontents % 8)) {
-		/* increase the size */
-		m->cache[cl] = (header_t *)
-		    xrealloc(m->cache[cl],sizeof(header_t) +
-			     ((8 + m->cache[cl]->ncontents) * sizeof(char *)));
-	    }
-
-	    /* have no need of this */
-	    free(name);
-	} else {
-	    /* create a new entry in the hash table */
-	    m->cache[cl] = (header_t *) xmalloc(sizeof(header_t) + 
-						8 * sizeof(char*));
-	    m->cache[cl]->name = name;
-	    m->cache[cl]->contents[0] = body;
-	    m->cache[cl]->ncontents = 1;
-	}
-
-	/* we always want a NULL at the end */
-	m->cache[cl]->contents[m->cache[cl]->ncontents] = NULL;
+	insert_cache_element(m, name, body);
     }
 
     if (r) {
@@ -994,6 +1004,8 @@
     if (m->return_path && func->addretpath) { /* add the return path */
 	char *rpath = m->return_path;
 	const char *hostname = 0;
+	char *name, *body;
+	int bodylen = 0;
 
 	clean_retpath(rpath);
 	/* Append our hostname if there's no domain in address */
@@ -1002,8 +1014,15 @@
 	    hostname = config_servername;
 	}
 
-	fprintf(f, "Return-Path: <%s%s%s>\r\n",
+	bodylen = strlen(rpath) + (hostname ? 1 + strlen(hostname) : 0) + 2;
+	body = xmalloc(bodylen + 1);
+	sprintf(body, "<%s%s%s>",
 		rpath, hostname ? "@" : "", hostname ? hostname : "");
+	body[bodylen] = 0;
+	name = xstrdup("Received-Path");
+
+	fprintf(f, "%s: %s\r\n", name, body);
+	insert_cache_element(m, xstrdup("Return-Path"), body);
     }
 
     /* add a received header */


More information about the Info-cyrus mailing list