Handle RFC822 'References:' field and Citadel W (Wefewences) field
authorArt Cancro <ajc@citadel.org>
Wed, 26 Mar 2008 21:15:32 +0000 (21:15 +0000)
committerArt Cancro <ajc@citadel.org>
Wed, 26 Mar 2008 21:15:32 +0000 (21:15 +0000)
citadel/internet_addressing.c
citadel/msgbase.c
citadel/server.h
citadel/techdoc/hack.txt

index ebc419f6abfbc60444615a81e9b28435cfcaf94c..6f28a69a336ff79376637ab89caa7fefebc08e3d 100644 (file)
@@ -397,12 +397,64 @@ int convert_field(struct CtdlMessage *msg, int beg, int end) {
                processed = 1;
        }
 
+       else if (!strcasecmp(key, "References")) {
+               if (msg->cm_fields['W'] != NULL) {
+                       free(msg->cm_fields['W']);
+               }
+               msg->cm_fields['W'] = strdup(value);
+               processed = 1;
+       }
+
+       else if (!strcasecmp(key, "In-reply-to")) {
+               if (msg->cm_fields['W'] == NULL) {              /* References: supersedes In-reply-to: */
+                       msg->cm_fields['W'] = strdup(value);
+               }
+               processed = 1;
+       }
+
+
+
        /* Clean up and move on. */
        free(key);      /* Don't free 'value', it's actually the same buffer */
        return(processed);
 }
 
 
+/*
+ * Convert RFC822 references format (References) to Citadel references format (Weferences)
+ */
+void convert_references_to_wefewences(char *str) {
+       int bracket_nesting = 0;
+       char *ptr = str;
+       char *moveptr = NULL;
+       char ch;
+
+       while(*ptr) {
+               ch = *ptr;
+               if (ch == '>') {
+                       --bracket_nesting;
+                       if (bracket_nesting < 0) bracket_nesting = 0;
+               }
+               if ((ch == '>') && (bracket_nesting == 0) && (*(ptr+1)) && (ptr>str) ) {
+                       *ptr = '|';
+                       ++ptr;
+               }
+               else if (bracket_nesting > 0) {
+                       ++ptr;
+               }
+               else {
+                       moveptr = ptr;
+                       while (*moveptr) {
+                               *moveptr = *(moveptr+1);
+                               ++moveptr;
+                       }
+               }
+               if (ch == '<') ++bracket_nesting;
+       }
+
+}
+
+
 /*
  * Convert an RFC822 message (headers + body) to a CtdlMessage structure.
  * NOTE: the supplied buffer becomes part of the CtdlMessage structure, and
@@ -484,6 +536,13 @@ struct CtdlMessage *convert_internet_message(char *rfc822) {
                msg->cm_fields['T'] = strdup(buf);
        }
 
+       /* If a W (references, or rather, Wefewences) field is present, we
+        * have to convert it from RFC822 format to Citadel format.
+        */
+       if (msg->cm_fields['W'] != NULL) {
+               convert_references_to_wefewences(msg->cm_fields['W']);
+       }
+
        return msg;
 }
 
index 74bec403afb8848b716bcc4dfc9d01f210737f10..81ee81aa8e8c8e78b94324af31abdf17cb047ea7 100644 (file)
@@ -100,7 +100,7 @@ char *msgkeys[] = {
        "time",
        "subj",
        NULL,
-       NULL,
+       "wefw",
        NULL,
        "cccc",
        NULL
@@ -1689,6 +1689,20 @@ int CtdlOutputPreLoadedMsg(
                                                atol(mptr), DATESTRING_RFC822);
                                        cprintf("Date: %s%s", datestamp, nl);
                                }
+                               else if (i == 'W') {
+                                       cprintf("References: ");
+                                       k = num_tokens(mptr, '|');
+                                       for (i=0; i<k; ++i) {
+                                               extract_token(buf, mptr, i, '|', sizeof buf);
+                                               cprintf("<%s>", buf);
+                                               if (i == (k-1)) {
+                                                       cprintf("%s", nl);
+                                               }
+                                               else {
+                                                       cprintf(" ");
+                                               }
+                                       }
+                               }
                        }
                }
                if (subject_found == 0) {
index cfdea64cd64e1043e0a74e5fa9069b20b1ffed7e..302f7f00c677b312efc47720fc63d0ac811ebd3d 100644 (file)
@@ -397,6 +397,6 @@ struct UseTable {
 /*               **********                    Important fields                */
 /*                         ***************     Semi-important fields           */
 /*                                        *    Message text (MUST be last)     */
-#define FORDER "IPTAFONHRDBCEJGKLQSVWXZYUM"
+#define FORDER "IPTAFONHRDBCEWJGKLQSVXZYUM"
 
 #endif /* SERVER_H */
index 89c5cecea07fbb0f57eb34090a55f001b0a4a084..21ad22039fa479dcd390ae71cabea56f59f4404d 100644 (file)
@@ -285,8 +285,9 @@ T   date/Time       A 32-bit integer containing the date and time of
 U       sUbject         Optional.  Developers may choose whether they wish to
                         generate or display subject fields.
 V      enVelope-to     The recipient specified in incoming SMTP messages.
-W      Weferences      Sort of like thread-id + references + in-reply-to
-                       (not yet implemented.  coming soon.)
+W      Wefewences      Previous message ID's for conversation threading.  When
+                       converting from RFC822 we use References: if present, or
+                       In-Reply-To: otherwise.
 Y      carbon copY     Optional, and only in Mail messages.
 0      Error           This field is typically never found in a message on
                        disk or in transit.  Message scanning modules are