Implemented RFC2919, the 'List-ID' field for mailing
authorArt Cancro <ajc@citadel.org>
Tue, 2 Sep 2008 17:41:36 +0000 (17:41 +0000)
committerArt Cancro <ajc@citadel.org>
Tue, 2 Sep 2008 17:41:36 +0000 (17:41 +0000)
lists.  This is now a top-level Citadel header field (L), which makes
it parseable by the Sieve engine.  Also added List-ID to the header
fields selectable in the mailbox filter rules editor.  And of course,
we are generating this field when we send out traffic from a Citadel-hosted
mailing list.  This also closes Bug #371.

citadel/internet_addressing.c
citadel/modules/network/serv_network.c
citadel/msgbase.c
citadel/techdoc/hack.txt
webcit/sieve.c

index c96d722e12ccd2bf4b0b5be632a5d1297c0e1a13..8661d70fa12cfae5f734e1affdb24dfd02d9530d 100644 (file)
@@ -600,6 +600,12 @@ int convert_field(struct CtdlMessage *msg, int beg, int end) {
                processed = 1;
        }
 
+       else if (!strcasecmp(key, "List-ID")) {
+               if (msg->cm_fields['L'] == NULL)
+                       msg->cm_fields['L'] = strdup(value);
+               processed = 1;
+       }
+
        else if (!strcasecmp(key, "To")) {
                if (msg->cm_fields['R'] == NULL)
                        msg->cm_fields['R'] = strdup(value);
index 86102e0a369ad15881f8f75ddb4c9b207523d324..b71d95a5f8d81f40454c1f0dd4ceb1556f00d9e8 100644 (file)
@@ -478,6 +478,15 @@ void network_deliver_digest(SpoolControl *sc) {
        msg->cm_fields['F'] = strdup(buf);
        msg->cm_fields['R'] = strdup(buf);
 
+       /* Set the 'List-ID' header */
+       msg->cm_fields['L'] = malloc(1024);
+       snprintf(msg->cm_fields['L'], 1024,
+               "%s <%ld.list-id.%s>",
+               CC->room.QRname,
+               CC->room.QRnumber,
+               config.c_fqdn
+       );
+
        /*
         * Go fetch the contents of the digest
         */
@@ -610,6 +619,18 @@ void network_spool_msg(long msgnum, void *userdata) {
                msg = CtdlFetchMessage(msgnum, 1);
                if (msg != NULL) {
 
+                       /* Set the 'List-ID' header */
+                       if (msg->cm_fields['L'] != NULL) {
+                               free(msg->cm_fields['L']);
+                       }
+                       msg->cm_fields['L'] = malloc(1024);
+                       snprintf(msg->cm_fields['L'], 1024,
+                               "%s <%ld.list-id.%s>",
+                               CC->room.QRname,
+                               CC->room.QRnumber,
+                               config.c_fqdn
+                       );
+
                        /* Prepend "[List name]" to the subject */
                        if (msg->cm_fields['U'] == NULL) {
                                msg->cm_fields['U'] = strdup("(no subject)");
index ebf44c4d395d6a3e4e955d69134589c4b30d1b49..2324ee694b67dbd7f2c2c97230e20e8527711209 100644 (file)
@@ -1776,6 +1776,9 @@ int CtdlOutputPreLoadedMsg(
                                else if (i == 'P') {
                                        cprintf("Return-Path: %s%s", mptr, nl);
                                }
+                               else if (i == 'L') {
+                                       cprintf("List-ID: %s%s", mptr, nl);
+                               }
                                else if (i == 'V') {
                                        if ((flags & QP_EADDR) != 0) 
                                                mptr = qp_encode_email_addrs(mptr);
index 21ad22039fa479dcd390ae71cabea56f59f4404d..52bbcb0e53d2b6873155570189940c64d093b1f5 100644 (file)
@@ -260,6 +260,7 @@ J   Journal         The presence of this field indicates that the message
                        is disqualified from being journaled, perhaps because
                        it is itself a journalized message and we wish to
                        avoid double journaling.
+L      List-ID         Mailing list identification, as per RFC 2919
 M      Message Text    Normal ASCII, newlines seperated by CR's or LF's,
                         null terminated as always.
 N      Nodename        Contains node name of system message originated on.
index 370f3c611d23550c39eee212502a86b8135850b4..0f9687d3552c50cb79c8e66f9936de3d3b608307 100644 (file)
@@ -355,6 +355,13 @@ void output_sieve_rule(char *hfield, char *compare, char *htext, char *sizecomp,
                );
        }
 
+       else if (!strcasecmp(hfield, "listid")) {
+               serv_printf("if%s header %s \"List-ID\" \"%s\"",
+                       comp1, comp2,
+                       htext
+               );
+       }
+
        else if (!strcasecmp(hfield, "envfrom")) {
                serv_printf("if%s envelope %s \"From\" \"%s\"",
                        comp1, comp2,
@@ -539,7 +546,7 @@ void parse_fields_from_rule_editor(void) {
                        serv_printf("# WEBCIT_RULE|%d|%s|", i, encoded_rule);
                        output_sieve_rule(hfield, compare, htext, sizecomp, sizeval,
                                        action, fileinto, redirect, automsg, final, my_addresses);
-                       serv_printf("");
+                       serv_puts("");
                }
 
 
@@ -983,7 +990,7 @@ void display_rules_editor_inner_div(void) {
 
                wprintf("<td width=20%%>%s ", _("If") );
 
-               char *hfield_values[14][2] = {
+               char *hfield_values[15][2] = {
                        {       "from",         _("From")               },
                        {       "tocc",         _("To or Cc")           },
                        {       "subject",      _("Subject")            },
@@ -996,13 +1003,14 @@ void display_rules_editor_inner_div(void) {
                        {       "xmailer",      _("X-Mailer")           },
                        {       "xspamflag",    _("X-Spam-Flag")        },
                        {       "xspamstatus",  _("X-Spam-Status")      },
+                       {       "listid",       _("List-ID")            },
                        {       "size",         _("Message size")       },
                        {       "all",          _("All")                }
                };
 
                wprintf("<select id=\"hfield%d\" name=\"hfield%d\" size=1 onChange=\"UpdateRules();\">",
                        i, i);
-               for (j=0; j<14; ++j) {
+               for (j=0; j<15; ++j) {
                        wprintf("<option %s value=\"%s\">%s</option>",
                                ( (!strcasecmp(hfield, hfield_values[j][0])) ? "selected" : ""),
                                hfield_values[j][0],