Keep track of thread references, in the server and in the text client. This required...
authorArt Cancro <ajc@citadel.org>
Thu, 3 Apr 2008 20:37:33 +0000 (20:37 +0000)
committerArt Cancro <ajc@citadel.org>
Thu, 3 Apr 2008 20:37:33 +0000 (20:37 +0000)
citadel/citadel_ipc.c
citadel/citadel_ipc.h
citadel/messages.c
citadel/modules/calendar/serv_calendar.c
citadel/msgbase.c
citadel/msgbase.h

index 7bb8caad0635a33365389f112e6b08e2315fe431..d1769cc1c17411af0eb5b628e36b7a700ba90158 100644 (file)
@@ -535,6 +535,8 @@ int CtdlIPCGetSingleMessage(CtdlIPC *ipc, long msgnum, int headers, int as_mime,
                                        safestrncpy(mret[0]->node, &aaa[5], SIZ);
                                else if (!strncasecmp(aaa, "rcpt=", 5))
                                        safestrncpy(mret[0]->recipient, &aaa[5], SIZ);
+                               else if (!strncasecmp(aaa, "wefw=", 5))
+                                       safestrncpy(mret[0]->references, &aaa[5], SIZ);
                                else if (!strncasecmp(aaa, "time=", 5))
                                        mret[0]->time = atol(&aaa[5]);
 
@@ -894,17 +896,24 @@ int CtdlIPCSetRoomAide(CtdlIPC *ipc, const char *username, char *cret)
 
 
 /* ENT0 */
-int CtdlIPCPostMessage(CtdlIPC *ipc, int flag, int *subject_required,  const struct ctdlipcmessage *mr, char *cret)
+int CtdlIPCPostMessage(CtdlIPC *ipc, int flag, int *subject_required,  struct ctdlipcmessage *mr, char *cret)
 {
        register int ret;
        char cmd[SIZ];
+       char *ptr;
 
        if (!cret) return -2;
        if (!mr) return -2;
 
+       if (mr->references) {
+               for (ptr=mr->references; *ptr != 0; ++ptr) {
+                       if (*ptr == '|') *ptr = '!';
+               }
+       }
+
        snprintf(cmd, sizeof cmd,
-                       "ENT0 %d|%s|%d|%d|%s|%s", flag, mr->recipient,
-                       mr->anonymous, mr->type, mr->subject, mr->author);
+                       "ENT0 %d|%s|%d|%d|%s|%s||||||%s|", flag, mr->recipient,
+                       mr->anonymous, mr->type, mr->subject, mr->author, mr->references);
        ret = CtdlIPCGenericCommand(ipc, cmd, mr->text, strlen(mr->text), NULL,
                        NULL, cret);
        if ((flag == 0) && (subject_required != NULL)) {
index ca41a3b0459e8e1ca918bc1f11d950d28fa5a9f1..01b0636223b784d142d4d600fb1326612814251f 100644 (file)
@@ -146,6 +146,7 @@ struct ctdlipcmessage {
        char anonymous;                 /* An anonymous message */
        char mime_chosen[SIZ];          /* Chosen MIME part to output */
        char content_type[SIZ];         /* How would you like that? */
+       char references[SIZ];           /* Thread references */
 };
 
 
@@ -228,7 +229,7 @@ int CtdlIPCSetRoomAttributes(CtdlIPC *ipc, int forget, struct ctdlroom *qret,
 int CtdlIPCGetRoomAide(CtdlIPC *ipc, char *cret);
 int CtdlIPCSetRoomAide(CtdlIPC *ipc, const char *username, char *cret);
 int CtdlIPCPostMessage(CtdlIPC *ipc, int flag, int *subject_required, 
-                                          const struct ctdlipcmessage *mr,
+                                          struct ctdlipcmessage *mr,
                                           char *cret);
 int CtdlIPCRoomInfo(CtdlIPC *ipc, char **iret, char *cret);
 int CtdlIPCDeleteMessage(CtdlIPC *ipc, long msgnum, char *cret);
index adc1d13b6db0bebaa1e6e889c5d542dca7c2a556..bc5a6e5cfd4bd0c9ef44baced9fa9e74a8b21c62 100644 (file)
@@ -52,6 +52,7 @@
 
 char reply_to[SIZ];
 char reply_subject[SIZ];
+char reply_references[SIZ];
 
 struct cittext {
        struct cittext *next;
@@ -404,6 +405,7 @@ int read_message(CtdlIPC *ipc,
 
        strcpy(reply_to, NO_REPLY_TO);
        strcpy(reply_subject, "");
+       strcpy(reply_references, "");
 
        r = CtdlIPCGetSingleMessage(ipc, num, (pagin == READ_HEADER ? 1 : 0), 4, &message, buf);
        if (r / 100 != 1) {
@@ -588,9 +590,20 @@ int read_message(CtdlIPC *ipc,
                lines_printed = checkpagin(lines_printed, pagin, screenheight);
        }
 
+
+       /* Always do msgid before references ... the latter is a concatenation! */
+       if (message->msgid != NULL) {
+               safestrncpy(reply_references, message->msgid, sizeof reply_references);
+       }
+
+       if (message->references != NULL) if (!IsEmptyStr(message->references)) {
+               int l = strlen(reply_references);
+               strcpy(&reply_references[l++], "|");
+               safestrncpy(&reply_references[l], message->references, (sizeof(reply_references) - l));
+       }
+
        if (message->subject != NULL) {
-               safestrncpy(reply_subject, message->subject,
-                                               sizeof reply_subject);
+               safestrncpy(reply_subject, message->subject, sizeof reply_subject);
                if (!IsEmptyStr(message->subject)) {
                        if (dest) {
                                fprintf(dest, "Subject: %s\n",
@@ -1090,6 +1103,7 @@ int entmsg(CtdlIPC *ipc,
        strcpy(message.recipient, "");
        strcpy(message.author, "");
        strcpy(message.subject, "");
+       strcpy(message.references, "");
        message.text = "";              /* point to "", changes later */
        message.anonymous = 0;
        message.type = mode;
@@ -1136,6 +1150,7 @@ int entmsg(CtdlIPC *ipc,
        strcpy(message.recipient, buf);
 
        if (is_reply) {
+
                if (!IsEmptyStr(reply_subject)) {
                        if (!strncasecmp(reply_subject,
                           "Re: ", 3)) {
@@ -1148,6 +1163,8 @@ int entmsg(CtdlIPC *ipc,
                                        reply_subject);
                        }
                }
+
+               safestrncpy(message.references, reply_references, sizeof message.references);
        }
 
        if (room_flags & QR_ANONOPT) {
index 21d2e3d0451d21c96f7329514946323b4b1ffb67..cc134e0d1a721623ca9e06b623a4ef78e66fa576 100644 (file)
@@ -344,7 +344,8 @@ void ical_send_a_reply(icalcomponent *request, char *action) {
                        "",
                        summary_string,         /* Use summary for subject */
                        NULL,
-                       reply_message_text);
+                       reply_message_text,
+                       NULL);
        
                if (msg != NULL) {
                        valid = validate_recipients(organizer_string, NULL, 0);
@@ -719,7 +720,8 @@ int ical_update_my_calendar_with_reply(icalcomponent *cal) {
                        "",
                        "",             /* no subject */
                        NULL,
-                       message_text);
+                       message_text,
+                       NULL);
        
                if (msg != NULL) {
                        CIT_ICAL->avoid_sending_invitations = 1;
@@ -1792,7 +1794,8 @@ void ical_send_out_invitations(icalcomponent *cal) {
                        "",
                        summary_string,         /* Use summary for subject */
                        NULL,
-                       request_message_text);
+                       request_message_text,
+                       NULL);
        
                if (msg != NULL) {
                        valid = validate_recipients(attendees_string, NULL, 0);
index 291d54fdda6245be56812a34f4fd6018940f003c..a6cc699b9ef6297d3d057011ba1eabba448d08ad 100644 (file)
@@ -2995,7 +2995,8 @@ struct CtdlMessage *CtdlMakeMessage(
        char *my_email,                 /* which of my email addresses to use (empty is ok) */
        char *subject,                  /* Subject (optional) */
        char *supplied_euid,            /* ...or NULL if this is irrelevant */
-       char *preformatted_text         /* ...or NULL to read text from client */
+       char *preformatted_text,        /* ...or NULL to read text from client */
+       char *references                /* Thread references */
 ) {
        char dest_node[256];
        char buf[1024];
@@ -3086,6 +3087,12 @@ struct CtdlMessage *CtdlMakeMessage(
                msg->cm_fields['E'] = strdup(supplied_euid);
        }
 
+       if (references != NULL) {
+               if (!IsEmptyStr(references)) {
+                       msg->cm_fields['W'] = strdup(references);
+               }
+       }
+
        if (preformatted_text != NULL) {
                msg->cm_fields['M'] = preformatted_text;
        }
@@ -3503,6 +3510,8 @@ void cmd_ent0(char *entargs)
        int i, j;
        char buf[256];
        int newuseremail_ok = 0;
+       char references[SIZ];
+       char *ptr;
 
        unbuffer_output();
 
@@ -3525,6 +3534,10 @@ void cmd_ent0(char *entargs)
                        break;
        }
        extract_token(newuseremail, entargs, 10, '|', sizeof newuseremail);
+       extract_token(references, entargs, 11, '|', sizeof references);
+       for (ptr=references; *ptr != 0; ++ptr) {
+               if (*ptr == '!') *ptr = '|';
+       }
 
        /* first check to make sure the request is valid. */
 
@@ -3718,7 +3731,7 @@ void cmd_ent0(char *entargs)
                CC->room.QRname, anonymous, format_type,
                newusername, newuseremail, subject,
                ((!IsEmptyStr(supplied_euid)) ? supplied_euid : NULL),
-               NULL);
+               NULL, references);
 
        /* Put together one big recipients struct containing to/cc/bcc all in
         * one.  This is for the envelope.
index 731f1bcd0f7cbe1ddba261137f15363b07ddb85a..1c02bd68630d93220a2ffb4728d629c97fba136b 100644 (file)
@@ -188,7 +188,8 @@ struct CtdlMessage *CtdlMakeMessage(
        char *my_email,                 /* which of my email addresses to use (empty is ok) */
         char *subject,                  /* Subject (optional) */
        char *supplied_euid,            /* ...or NULL if this is irrelevant */
-        char *preformatted_text         /* ...or NULL to read text from client */
+        char *preformatted_text,        /* ...or NULL to read text from client */
+       char *references                /* Thread references */
 );
 int CtdlCheckInternetMailPermission(struct ctdluser *who);
 int CtdlIsMe(char *addr, int addr_buf_len);