2007-11-21 [colin] 3.1.0cvs13
authorColin Leroy <colin@colino.net>
Wed, 21 Nov 2007 18:52:23 +0000 (18:52 +0000)
committerColin Leroy <colin@colino.net>
Wed, 21 Nov 2007 18:52:23 +0000 (18:52 +0000)
* src/messageview.c
* src/procmime.c
* src/procmsg.h
Send better return receipts (useful ones)
Handle incoming return receipts

ChangeLog
PATCHSETS
configure.ac
src/messageview.c
src/procmime.c
src/procmsg.h

index 75a3af0..5b8c86f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-11-21 [colin]     3.1.0cvs13
+
+       * src/messageview.c
+       * src/procmime.c
+       * src/procmsg.h
+               Send better return receipts (useful ones)
+               Handle incoming return receipts
+
 2007-11-20 [colin]     3.1.0cvs12
 
        * src/printing.c
index b5d90fc..a41aa75 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.213.2.166 -r 1.213.2.167 src/folder.c;  ) > 3.1.0cvs10.patchset
 ( cvs diff -u -r 1.207.2.187 -r 1.207.2.188 src/folderview.c;  cvs diff -u -r 1.115.2.176 -r 1.115.2.177 src/main.c;  cvs diff -u -r 1.274.2.220 -r 1.274.2.221 src/mainwindow.c;  ) > 3.1.0cvs11.patchset
 ( cvs diff -u -r 1.1.2.10 -r 1.1.2.11 src/printing.c;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 src/printing.h;  ) > 3.1.0cvs12.patchset
+( cvs diff -u -r 1.94.2.163 -r 1.94.2.164 src/messageview.c;  cvs diff -u -r 1.49.2.102 -r 1.49.2.103 src/procmime.c;  cvs diff -u -r 1.60.2.49 -r 1.60.2.50 src/procmsg.h;  ) > 3.1.0cvs13.patchset
index 1c2ad9a..8573b1d 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=1
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=12
+EXTRA_VERSION=13
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 9210d2d..74d0029 100644 (file)
@@ -69,6 +69,8 @@
 #include "log.h"
 #include "combobox.h"
 #include "printing.h"
+#include "quoted-printable.h"
+#include "version.h"
 
 static GList *messageview_list = NULL;
 
@@ -645,7 +647,11 @@ static gint disposition_notification_send(MsgInfo *msginfo)
         gchar *addrp;
        gchar *foo = NULL;
        gboolean queued_removed = FALSE;
-       
+       gchar *boundary = NULL;
+       gchar *date = NULL;
+       gchar *orig_to = NULL;
+       gchar *enc_sub = NULL;
+
        if (!msginfo->extradata)
                return -1;
        if (!msginfo->extradata->returnreceiptto && 
@@ -851,6 +857,66 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                }
        }
 
+       boundary = generate_mime_boundary("DN");
+       get_rfc822_date(buf, sizeof(buf));
+       date = g_strdup(buf);
+       if (msginfo->to) {
+               orig_to = g_strdup(msginfo->to);
+               extract_address(orig_to);
+       }
+       if (msginfo->subject) {
+               enc_sub = g_malloc0(strlen(msginfo->subject)*2);
+               qp_encode_line(enc_sub, (const guchar *)msginfo->subject);
+               g_strstrip(enc_sub);
+       }
+       if (fprintf(fp, "MIME-Version: 1.0\n"
+                       "Content-Type: multipart/report; report-type=disposition-notification;\n"
+                       "  boundary=\"%s\"\n"
+                       "\n"
+                       "--%s\n"
+                       "Content-Type: text/plain; charset=UTF-8\n"
+                       "Content-Transfer-Encoding: quoted-printable\n"
+                       "\n"
+                       "The message sent on: %s\n"
+                       "To: %s\n"
+                       "With subject: \"%s\"\n"
+                       "has been displayed at %s.\n"
+                       "\n"
+                       "There is no guarantee that the message has been read or understood.\n"
+                       "\n"
+                       "--%s\n"
+                       "Content-Type: message/disposition-notification\n"
+                       "\n"
+                       "Reporting-UA: %s\n"
+                       "Original-Recipient: rfc822;%s\n"
+                       "Final-Recipient: rfc822;%s\n"
+                       "Original-Message-ID: <%s>\n"
+                       "Disposition: manual-action/MDN-sent-manually; displayed\n"
+                       "\n"
+                       "--%s--\n", 
+                       boundary, 
+                       boundary,
+                       msginfo->date, 
+                       orig_to?orig_to:"No To:",
+                       enc_sub?enc_sub:"No subject",
+                       date,
+                       boundary,
+                       PROG_VERSION,
+                       orig_to?orig_to:"No To:",
+                       account->address,
+                       msginfo->msgid?msginfo->msgid:"NO MESSAGE ID",
+                       boundary) < 0) {
+               fclose(fp);
+               g_unlink(tmp);
+               g_free(boundary);
+               return -1;
+       }
+
+       g_free(enc_sub);
+       g_free(orig_to);
+       g_free(date);
+       g_free(boundary);
+
        if (fclose(fp) == EOF) {
                FILE_OP_ERROR(tmp, "fclose");
                g_unlink(tmp);
@@ -1404,7 +1470,12 @@ static void return_receipt_show(NoticeView *noticeview, MsgInfo *msginfo)
 
        if (from_me) {
                noticeview_set_icon(noticeview, STOCK_PIXMAP_NOTICE_WARN);
-               noticeview_set_text(noticeview, _("You asked for a return receipt in this message."));
+               if (MSG_IS_RETRCPT_GOT(msginfo->flags)) {
+                       noticeview_set_text(noticeview, _("You got a return receipt in this message : "
+                                                         "it has been displayed by the recipient."));
+               } else {
+                       noticeview_set_text(noticeview, _("You asked for a return receipt in this message."));
+               }
                noticeview_set_button_text(noticeview, NULL);
                noticeview_set_button_press_callback(noticeview, NULL, NULL);
        } else {
index 6ac2659..4420c20 100644 (file)
@@ -1354,6 +1354,64 @@ static void procmime_parse_message_rfc822(MimeInfo *mimeinfo, gboolean short_sca
        }
 }
 
+static void procmime_parse_disposition_notification(MimeInfo *mimeinfo, gboolean short_scan)
+{
+       HeaderEntry hentry[] = {{"Original-Message-ID:",  NULL, TRUE},
+                               {"Disposition:",          NULL, TRUE},
+                               {NULL,                    NULL, FALSE}};
+       guint i;
+       FILE *fp;
+       gchar *orig_msg_id = NULL;
+       gchar *disp = NULL;
+
+       procmime_decode_content(mimeinfo);
+
+       fp = g_fopen(mimeinfo->data.filename, "rb");
+       if (fp == NULL) {
+               FILE_OP_ERROR(mimeinfo->data.filename, "fopen");
+               return;
+       }
+       fseek(fp, mimeinfo->offset, SEEK_SET);
+       procheader_get_header_fields(fp, hentry);
+
+       if (!hentry[0].body || !hentry[1].body) {
+               goto bail;
+       }
+
+       orig_msg_id = g_strdup(hentry[0].body);
+       disp = g_strdup(hentry[1].body);
+
+       extract_parenthesis(orig_msg_id, '<', '>');
+       remove_space(orig_msg_id);
+       
+       if (strstr(disp, "displayed")) {
+               /* find sent message, if possible */
+               MsgInfo *info = NULL;
+               GList *flist;
+               debug_print("%s has been displayed.\n", orig_msg_id);
+               for (flist = folder_get_list(); flist != NULL; flist = g_list_next(flist)) {
+                       FolderItem *outbox = ((Folder *)(flist->data))->outbox;
+                       if (!outbox) {
+                               debug_print("skipping folder with no outbox...\n");
+                               continue;
+                       }
+                       info = folder_item_get_msginfo_by_msgid(outbox, orig_msg_id);
+                       debug_print("%s %s in %s\n", info?"found":"didn't find", orig_msg_id, outbox->path);
+                       if (info) {
+                               procmsg_msginfo_set_flags(info, MSG_RETRCPT_GOT, 0);
+                               procmsg_msginfo_free(info);
+                       }
+               }
+       }
+       g_free(orig_msg_id);
+       g_free(disp);
+bail:
+       for (i = 0; i < (sizeof hentry / sizeof hentry[0]); i++) {
+               g_free(hentry[i].body);
+               hentry[i].body = NULL;
+       }
+}
+
 static void procmime_parse_multipart(MimeInfo *mimeinfo, gboolean short_scan)
 {
        HeaderEntry hentry[] = {{"Content-Type:",  NULL, TRUE},
@@ -1813,6 +1871,9 @@ static int procmime_parse_mimepart(MimeInfo *parent,
                        if (g_ascii_strcasecmp(mimeinfo->subtype, "rfc822") == 0) {
                                procmime_parse_message_rfc822(mimeinfo, short_scan);
                        }
+                       if (g_ascii_strcasecmp(mimeinfo->subtype, "disposition-notification") == 0) {
+                               procmime_parse_disposition_notification(mimeinfo, short_scan);
+                       }
                        break;
                        
                case MIMETYPE_MULTIPART:
index ca26618..0a1175c 100644 (file)
@@ -88,7 +88,8 @@ typedef GSList MsgNumberList;
 #define MSG_POSTFILTERED       (1U << 14)
 #define MSG_WATCH_THREAD       (1U << 15)   /* watch threads */
 #define MSG_FULLY_CACHED       (1U << 16)   /* IMAP: fully cached */
-                                               
+#define MSG_RETRCPT_GOT                (1U << 17)   /* got return receipt */
+       
 /* RESERVED */
 #define        MSG_RESERVED_CLAWS      (1U << 30)   /* for claws-mail */
 #define        MSG_RESERVED            (1U << 31)
@@ -160,6 +161,7 @@ typedef guint32 MsgTmpFlags;
 #define MSG_IS_IGNORE_THREAD(msg)      (((msg).perm_flags & MSG_IGNORE_THREAD) != 0)
 #define MSG_IS_RETRCPT_PENDING(msg)    (((msg).perm_flags & MSG_RETRCPT_PENDING) != 0)
 #define MSG_IS_RETRCPT_SENT(msg)       (((msg).perm_flags & MSG_RETRCPT_SENT) != 0)
+#define MSG_IS_RETRCPT_GOT(msg)                (((msg).perm_flags & MSG_RETRCPT_GOT) != 0)
 #define MSG_IS_SPAM(msg)               (((msg).perm_flags & MSG_SPAM) != 0)
 #define MSG_IS_WATCH_THREAD(msg)       (((msg).perm_flags & MSG_WATCH_THREAD) != 0)
 #define MSG_IS_FULLY_CACHED(msg)       (((msg).perm_flags & MSG_FULLY_CACHED) != 0)