Return Receipt
authorHoà Viêt Dinh <dinh.viet.hoa@free.fr>
Wed, 2 May 2001 14:16:51 +0000 (14:16 +0000)
committerHoà Viêt Dinh <dinh.viet.hoa@free.fr>
Wed, 2 May 2001 14:16:51 +0000 (14:16 +0000)
src/compose.c
src/compose.h
src/messageview.c
src/procheader.c
src/procmsg.c
src/procmsg.h
src/summaryview.c

index 674e16f..79bb45b 100644 (file)
@@ -330,6 +330,8 @@ static void compose_toggle_encrypt_cb       (gpointer        data,
                                         guint           action,
                                         GtkWidget      *widget);
 #endif
+static void compose_toggle_return_receipt_cb(gpointer data, guint action,
+                                            GtkWidget *widget);
 
 static void compose_attach_drag_received_cb (GtkWidget         *widget,
                                             GdkDragContext     *drag_context,
@@ -414,6 +416,8 @@ static GtkItemFactoryEntry compose_entries[] =
        {N_("/_Message/Si_gn"),         NULL, compose_toggle_sign_cb, 0, "<ToggleItem>"},
        {N_("/_Message/_Encrypt"),      NULL, compose_toggle_encrypt_cb, 0, "<ToggleItem>"},
 #endif /* USE_GPGME */
+       {N_("/_Message/---"),           NULL,           NULL,   0, "<Separator>"},
+       {N_("/_Message/_Request Return Receipt"),       NULL, compose_toggle_return_receipt_cb, 0, "<ToggleItem>"},
        {N_("/_Tool"),                  NULL, NULL,     0, "<Branch>"},
        {N_("/_Tool/Show _ruler"),      NULL, compose_toggle_ruler_cb,  0, "<ToggleItem>"},
        {N_("/_Tool/_Address book"),    "<alt>A",       compose_address_cb, 0, NULL},
@@ -2100,6 +2104,18 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
                fprintf(fp, "Mime-Version: 1.0\n");
        }
 
+       /* Request Return Receipt */
+       if (!is_in_custom_headers(compose, "Disposition-Notification-To")) {
+               if (compose->return_receipt) {
+                       if (compose->account->name
+                           && *compose->account->name) {
+                               compose_convert_header(buf, sizeof(buf), compose->account->name, strlen("Disposition-Notification-To: "));
+                               fprintf(fp, "Disposition-Notification-To: %s <%s>\n", buf, compose->account->address);
+                       } else
+                               fprintf(fp, "Disposition-Notification-To: %s\n", compose->account->address);
+               }
+       }
+
        if (compose->use_attach) {
                get_rfc822_date(buf, sizeof(buf));
                subst_char(buf, ' ', '_');
@@ -2636,6 +2652,8 @@ static Compose *compose_create(PrefsAccount *account)
 
        compose->modified = FALSE;
 
+       compose->return_receipt = FALSE;
+
        compose->to_list        = NULL;
        compose->newsgroup_list = NULL;
 
@@ -4087,3 +4105,14 @@ static void followupto_activated(GtkWidget *widget, Compose *compose)
 {
        gtk_widget_grab_focus(compose->text);
 }
+
+static void compose_toggle_return_receipt_cb(gpointer data, guint action,
+                                            GtkWidget *widget)
+{
+       Compose *compose = (Compose *)data;
+
+       if (GTK_CHECK_MENU_ITEM(widget)->active)
+               compose->return_receipt = TRUE;
+       else
+               compose->return_receipt = FALSE;
+}
index 4a3fca0..d5d356a 100644 (file)
@@ -140,6 +140,8 @@ struct _Compose
 
        gboolean modified;
 
+       gboolean return_receipt;
+
        GSList *to_list;
        GSList *newsgroup_list;
 
index 0aa9588..17af209 100644 (file)
@@ -44,6 +44,8 @@
 #include "gtkutils.h"
 #include "utils.h"
 #include "rfc2015.h"
+#include "account.h"
+#include "alertpanel.h"
 
 static void messageview_change_view_type(MessageView   *messageview,
                                         MessageType     type);
@@ -146,6 +148,82 @@ void messageview_init(MessageView *messageview)
        //messageview_set_font(messageview);
 }
 
+static void notification_convert_header(gchar *dest, gint len, gchar *src,
+                                       gint header_len)
+{
+       g_return_if_fail(src != NULL);
+       g_return_if_fail(dest != NULL);
+
+       if (len < 1) return;
+
+       remove_return(src);
+
+       if (is_ascii_str(src)) {
+               strncpy2(dest, src, len);
+               dest[len - 1] = '\0';
+               return;
+       } else
+               conv_encode_header(dest, len, src, header_len);
+}
+
+static gint dispotition_notification_send(MsgInfo * msginfo)
+{
+       gchar buf[BUFFSIZE];
+       gchar tmp[MAXPATHLEN + 1];
+       FILE *fp;
+       GSList * to_list;
+       gint ok;
+
+       /* write to temporary file */
+       g_snprintf(tmp, sizeof(tmp), "%s%ctmpmsg%d",
+                  get_rc_dir(), G_DIR_SEPARATOR, (gint)msginfo);
+
+       if ((fp = fopen(tmp, "w")) == NULL) {
+               FILE_OP_ERROR(tmp, "fopen");
+               return -1;
+       }
+
+       /* chmod for security */
+       if (change_file_mode_rw(fp, tmp) < 0) {
+               FILE_OP_ERROR(tmp, "chmod");
+               g_warning(_("can't change file mode\n"));
+       }
+
+       /* Date */
+       get_rfc822_date(buf, sizeof(buf));
+       fprintf(fp, "Date: %s\n", buf);
+
+       /* From */
+       if (cur_account->name && *cur_account->name) {
+               notification_convert_header
+                       (buf, sizeof(buf), cur_account->name,
+                        strlen("From: "));
+               fprintf(fp, "From: %s <%s>\n", buf, cur_account->address);
+       } else
+               fprintf(fp, "From: %s\n", cur_account->address);
+
+       /* To */
+       fprintf(fp, "To: %s\n", msginfo->dispositionnotificationto);
+
+       /* Subject */
+       notification_convert_header(buf, sizeof(buf), msginfo->subject,
+                                   strlen("Subject: "));
+       fprintf(fp, "Subject: Disposition notification: %s\n", buf);
+
+       if (fclose(fp) == EOF) {
+               FILE_OP_ERROR(tmp, "fclose");
+               unlink(tmp);
+               return -1;
+       }
+
+       to_list = address_list_append(NULL, msginfo->dispositionnotificationto);
+       ok = send_message(tmp, cur_account, to_list);
+
+       if (unlink(tmp) < 0) FILE_OP_ERROR(tmp, "unlink");
+
+       return ok;
+}
+
 void messageview_show(MessageView *messageview, MsgInfo *msginfo)
 {
        FILE *fp;
@@ -192,6 +270,19 @@ void messageview_show(MessageView *messageview, MsgInfo *msginfo)
        g_return_if_fail(file != NULL);
 
        tmpmsginfo = procheader_parse(file, msginfo->flags, TRUE);
+
+       if (tmpmsginfo->dispositionnotificationto
+           && (MSG_IS_UNREAD(msginfo->flags))) {
+               gint ok;
+               
+               if (alertpanel(_("Return Receipt"), _("Send return receipt ?"),
+                              _("Yes"), _("No"), NULL) == G_ALERTDEFAULT) {
+                       ok = dispotition_notification_send(tmpmsginfo);
+                       if (ok < 0)
+                               alertpanel_error(_("Error occurred while sending notification."));
+               }
+       }
+
        headerview_show(messageview->headerview, tmpmsginfo);
        procmsg_msginfo_free(tmpmsginfo);
 
index 922e794..9a280cd 100644 (file)
@@ -280,6 +280,7 @@ enum
        H_CONTENT_TYPE  = 8,
        H_SEEN          = 9,
        H_X_FACE        = 10,
+       H_DISPOSITION_NOTIFICATION_TO = 11
 };
 
 MsgInfo *procheader_parse(const gchar *file, MsgFlags flags, gboolean full)
@@ -295,6 +296,7 @@ MsgInfo *procheader_parse(const gchar *file, MsgFlags flags, gboolean full)
                                           {"Content-Type:",    NULL, FALSE},
                                           {"Seen:",            NULL, FALSE},
                                           {"X-Face:",          NULL, FALSE},
+                                          {"Disposition-Notification-To:",NULL, FALSE},
                                           {NULL,               NULL, FALSE}};
 
        static HeaderEntry hentry_short[] = {{"Date:",          NULL, FALSE},
@@ -415,6 +417,10 @@ MsgInfo *procheader_parse(const gchar *file, MsgFlags flags, gboolean full)
                        if (msginfo->xface) break;
                        msginfo->xface = g_strdup(hp);
                        break;
+               case H_DISPOSITION_NOTIFICATION_TO:
+                       if (msginfo->dispositionnotificationto) break;
+                       msginfo->dispositionnotificationto = g_strdup(hp);
+                       break;
                default:
                }
        }
index 27faf07..969a0e8 100644 (file)
@@ -749,6 +749,7 @@ MsgInfo *procmsg_msginfo_copy(MsgInfo *msginfo)
        MEMBCOPY(to_folder);
 
        MEMBDUP(xface);
+       MEMBDUP(dispositionnotificationto);
 
        return newmsginfo;
 }
@@ -757,6 +758,7 @@ void procmsg_msginfo_free(MsgInfo *msginfo)
 {
        if (msginfo == NULL) return;
 
+       g_free(msginfo->dispositionnotificationto);
        g_free(msginfo->xface);
 
        g_free(msginfo->fromname);
index 07c8de5..f3c230d 100644 (file)
@@ -121,6 +121,8 @@ struct _MsgInfo
 
        gchar *xface;
 
+       gchar *dispositionnotificationto;
+
        /* used only for encrypted messages */
        gchar *plaintext_file;
        guint decryption_failed : 1;
index ee93e68..b2524bb 100644 (file)
@@ -1424,17 +1424,6 @@ static void summary_display_msg(SummaryView *summaryview, GtkCTreeNode *row,
        }
        g_free(filename);
 
-       if (MSG_IS_NEW(msginfo->flags))
-               summaryview->newmsgs--;
-       if (MSG_IS_UNREAD(msginfo->flags))
-               summaryview->unread--;
-       if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)) {
-               MSG_UNSET_FLAGS(msginfo->flags, MSG_NEW | MSG_UNREAD);
-               summary_set_row_marks(summaryview, row);
-               gtk_clist_thaw(GTK_CLIST(ctree));
-               summary_status_show(summaryview);
-       }
-
        if (new_window) {
                MessageView *msgview;
 
@@ -1457,6 +1446,17 @@ static void summary_display_msg(SummaryView *summaryview, GtkCTreeNode *row,
                gtkut_ctree_node_move_if_on_the_edge(ctree, row);
        }
 
+       if (MSG_IS_NEW(msginfo->flags))
+               summaryview->newmsgs--;
+       if (MSG_IS_UNREAD(msginfo->flags))
+               summaryview->unread--;
+       if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)) {
+               MSG_UNSET_FLAGS(msginfo->flags, MSG_NEW | MSG_UNREAD);
+               summary_set_row_marks(summaryview, row);
+               gtk_clist_thaw(GTK_CLIST(ctree));
+               summary_status_show(summaryview);
+       }
+
        if (GTK_WIDGET_VISIBLE(summaryview->headerwin->window))
                header_window_show(summaryview->headerwin, msginfo);