The following issue has been UPDATED.
======================================================================
http://www.dbmail.org/mantis/view.php?id=358
======================================================================
Reported By: blake
Assigned To: aaron
======================================================================
Project: DBMail
Issue ID: 358
Category: general delivery
Reproducibility: always
Severity: minor
Priority: normal
Status: resolved
target: 2.1.7
Resolution: fixed
Fixed in Version: 2.1.7
======================================================================
Date Submitted: 06-Jun-06 08:12 CEST
Last Modified: 20-Jul-06 16:13 CEST
======================================================================
Summary: Sieve filters only match the first occurrence of a
header.
Description:
if I have a rule like this:
if allof (
header :contains "Received" "mail.example.com"
, header :contains "Delivered-To" "[EMAIL PROTECTED]"
) {
fileinto "Example/Test";
stop;
}
It appears, based on looking at the log output, and the way the filters
function, that only the first occurances of "Received" and "Delivered-To"
are checked.
======================================================================
----------------------------------------------------------------------
blake - 06-Jun-06 08:14
----------------------------------------------------------------------
Aaron Stone wrote:
I asked Jeffrey Stedfast the GMime maintainer if he could add a simple
function for fetching all instances of a header, and he liked the idea,
but has not included it in GMime yet :-\
The workaround is to loop through all headers belonging to a message and
pull out instances of the header we're looking for. I did not write a
function to do this because I was expecting to see it in GMime 2.2...
I will write the workaround function since we're not likely to see the
real deal in the upstream library anytime soon.
----------------------------------------------------------------------
blake - 06-Jun-06 08:16
----------------------------------------------------------------------
Let me know if this patch works for you!
Aaron
diff -X exclude -rauN dbmail/dbmail-message.c dbmail-2.1/dbmail-message.c
--- dbmail/dbmail-message.c 2006-06-02 07:41:43.010083552 -0700
+++ dbmail-2.1/dbmail-message.c 2006-06-05 16:08:39.248458120 -0700
@@ -432,11 +432,60 @@
{
g_mime_message_set_header(GMIME_MESSAGE(self->content), header, value);
}
+
const gchar * dbmail_message_get_header(const struct DbmailMessage *self,
const char *header)
{
return g_mime_object_get_header(GMIME_OBJECT(self->content), header);
}
+static void _get_header_repeated(const char *name, const char *value,
gpointer user_data)
+{
+ struct {
+ char *header;
+ char **headers;
+ int pos;
+ int len;
+ } *_my_headers = user_data;
+
+ if (strcmp(name, _my_headers->header)) {
+ if (_my_headers->pos + 1 == _my_headers->len) {
+ _my_headers->len += 8;
+ _my_headers->headers = g_renew(char *,
_my_headers->headers,
_my_headers->len);
+
+ /* There used to be a renew0, but not anymore. */
+ int i;
+ for (i = _my_headers->pos; i < _my_headers->len; i++) {
+ _my_headers->headers[i] = NULL;
+ }
+ }
+ _my_headers->headers[_my_headers->pos] = (char *)value;
+ _my_headers->pos++;
+ }
+}
+
+/* Memory for the individual header values is NOT allocated;
+ * Memory for the header array IS allocated and must be freed.
+ * Do NOT use g_strfreev with this return value! */
+gchar ** dbmail_message_get_header_repeated(const struct DbmailMessage
*self, const char *header)
+{
+ struct {
+ char *header;
+ char **headers;
+ int pos;
+ int len;
+ } _my_headers;
+
+ /* Start with 8 slots. */
+ _my_headers.pos = 0;
+ _my_headers.len = 8;
+ _my_headers.header = (char *)header;
+ _my_headers.headers = g_new0(char *, _my_headers.len);
+
+ g_mime_header_foreach(GMIME_OBJECT(self->content)->headers,
_get_header_repeated, &_my_headers);
+
+ return _my_headers.headers;
+}
+
GList * dbmail_message_get_header_addresses(struct DbmailMessage
*message, const char *field_name)
{
InternetAddressList *ialisthead, *ialist;
diff -X exclude -rauN dbmail/dbmail-message.h dbmail-2.1/dbmail-message.h
--- dbmail/dbmail-message.h 2006-04-13 08:47:35.312204272 -0700
+++ dbmail-2.1/dbmail-message.h 2006-06-05 16:03:34.142841224 -0700
@@ -127,6 +127,14 @@
void dbmail_message_set_header(struct DbmailMessage *self, const char
*header, const char *value);
const gchar * dbmail_message_get_header(const struct DbmailMessage *self,
const char *header);
+/* Get all instances of a header.
+ *
+ * Memory for the individual header values is NOT allocated;
+ * Memory for the header array IS allocated and must be freed.
+ * Do NOT use g_strfreev with this return value!
+ */
+gchar ** dbmail_message_get_header_repeated(const struct DbmailMessage
*self, const char *header);
+
void dbmail_message_cache_tofield(const struct DbmailMessage *self);
void dbmail_message_cache_ccfield(const struct DbmailMessage *self);
void dbmail_message_cache_fromfield(const struct DbmailMessage *self);
diff -X exclude -rauN dbmail/modules/sortsieve.c
dbmail-2.1/modules/sortsieve.c
--- dbmail/modules/sortsieve.c 2006-05-06 23:52:27.291685424 -0700
+++ dbmail-2.1/modules/sortsieve.c 2006-06-05 16:04:14.547698752 -0700
@@ -286,12 +286,9 @@
header = (char *)sieve2_getvalue_string(s, "header");
- bodylist = (char **)dm_malloc(sizeof(char *) * 2);
- bodylist[0] = (char *)dbmail_message_get_header(m->message, header);
- bodylist[1] = NULL;
+ bodylist = (char **)dbmail_message_get_header_repeated(m->message,
header);
- /* We have to free the header ourselves. */
- dm_list_nodeadd(&m->freelist, &bodylist[0], sizeof(char *));
+ /* We have to free the header array, but not its contents. */
dm_list_nodeadd(&m->freelist, &bodylist, sizeof(char **));
trace(TRACE_INFO, "%s, %s: Getting header [%s] returning value [%s]",
diff -X exclude -rauN dbmail/pool.c dbmail-2.1/pool.c
--- dbmail/pool.c 2006-05-06 15:19:29.020693824 -0700
+++ dbmail-2.1/pool.c 2006-06-05 16:10:17.723487640 -0700
@@ -27,6 +27,7 @@
static State_t state_new(void);
static int set_lock(int type);
+static pid_t reap_child(void);
/*
*
*
----------------------------------------------------------------------
blake - 06-Jun-06 08:18
----------------------------------------------------------------------
The behavior appears to be the same with the patch. (I've sent Aaron some
logs privately to continue to debug the problem.)
----------------------------------------------------------------------
aaron - 06-Jun-06 08:34
----------------------------------------------------------------------
The patch I originally wrote had "if (strcmp(...,...))" which should have
been "if (strcasecmp(...,...) == 0)". Now in SVN.
----------------------------------------------------------------------
paul - 06-Jun-06 11:55
----------------------------------------------------------------------
Aaron,
why are you retrieving headers case-insensitive? This breaks gmime
standard behaviour, and is not required afaict.
I've redone this code by using standard glib facilities. Hope you don't
mind :-/
----------------------------------------------------------------------
aaron - 08-Jun-06 14:52
----------------------------------------------------------------------
Ok, this is working well now. Turned out that case-insensitive was
required.
Issue History
Date Modified Username Field Change
======================================================================
06-Jun-06 08:12 blake New Issue
06-Jun-06 08:14 blake Note Added: 0001224
06-Jun-06 08:16 blake Note Added: 0001225
06-Jun-06 08:18 blake Note Added: 0001226
06-Jun-06 08:34 aaron target => 2.1.7
06-Jun-06 08:34 aaron Status new => resolved
06-Jun-06 08:34 aaron Fixed in Version => SVN Trunk
06-Jun-06 08:34 aaron Resolution open => fixed
06-Jun-06 08:34 aaron Assigned To => aaron
06-Jun-06 08:34 aaron Note Added: 0001227
06-Jun-06 11:55 paul Note Added: 0001228
06-Jun-06 11:55 paul Resolution fixed => reopened
06-Jun-06 11:57 paul Status resolved => assigned
08-Jun-06 14:52 aaron Status assigned => resolved
08-Jun-06 14:52 aaron Resolution reopened => fixed
08-Jun-06 14:52 aaron Note Added: 0001229
20-Jul-06 16:13 paul Fixed in Version SVN Trunk => 2.1.7
======================================================================