[balsa] Support for successful DSN's (Albrecht Dre ß)



commit 03f320777c2b63b31f3dce6192db344ed43132dd
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Tue Feb 24 17:20:43 2015 -0500

    Support for successful DSN's (Albrecht Dreß)
    
        * libbalsa/identity.[hc]: define default DSN setting, load and
        store it
        * libbalsa/identity.c, src/balsa-index.c,
        src/filter-edit-callbacks.c: fix clang nagging about a misplaced
        'static const' qualifier
        * libbalsa/message.h: add request dsn flag
        * libbalsa/send.c: instruct libesmtp to request the DSN
        * libbalsa/send.c: pass const parameter as const
        * src/balsa-icons.c: add braces around macro
        * src/sendmsg-window.[hc]: add GUI stuff for requesting the DSN

 ChangeLog                   |   15 +++++++++++++++
 libbalsa/identity.c         |   13 +++++++++++--
 libbalsa/identity.h         |    1 +
 libbalsa/imap/pop3.h        |    4 ++++
 libbalsa/message.h          |    3 +++
 libbalsa/send.c             |   35 +++++++++++++++++++++++------------
 src/balsa-icons.c           |    3 ++-
 src/balsa-index.c           |    2 +-
 src/filter-edit-callbacks.c |    2 +-
 src/sendmsg-window.c        |   39 +++++++++++++++++++++++++++++++--------
 src/sendmsg-window.h        |    3 ++-
 11 files changed, 94 insertions(+), 26 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 452dc74..2a1a753 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2015-02-24  Albrecht Dreß
+
+       Support for successful DSN's
+
+       * libbalsa/identity.[hc]: define default DSN setting, load and
+       store it
+       * libbalsa/identity.c, src/balsa-index.c,
+       src/filter-edit-callbacks.c: fix clang nagging about a misplaced
+       'static const' qualifier
+       * libbalsa/message.h: add request dsn flag
+       * libbalsa/send.c: instruct libesmtp to request the DSN
+       * libbalsa/send.c: pass const parameter as const
+       * src/balsa-icons.c: add braces around macro
+       * src/sendmsg-window.[hc]: add GUI stuff for requesting the DSN
+
 2015-02-23  Albrecht Dreß
 
        Build with clang
diff --git a/libbalsa/identity.c b/libbalsa/identity.c
index 8bd04d4..11b8aca 100644
--- a/libbalsa/identity.c
+++ b/libbalsa/identity.c
@@ -115,6 +115,7 @@ libbalsa_identity_init(LibBalsaIdentity* ident)
     ident->crypt_protocol = LIBBALSA_PROTECT_OPENPGP;
     ident->force_key_id = NULL;
     ident->request_mdn = FALSE;
+    ident->request_dsn = FALSE;
     /*
     ident->face = NULL;
     ident->x_face = NULL;
@@ -936,13 +937,13 @@ append_ident_notebook_page(GtkNotebook *notebook, guint rows,
  * Put the required GtkEntries, Labels, and Checkbuttons in the dialog
  * for creating/editing identities.
  */
-struct {
+static const struct {
     const gchar *mnemonic;
     const gchar *path_key;
     const gchar *box_key;
     const gchar *basename;
     const gchar *info;
-} static const path_info[] = {
+} path_info[] = {
         /* Translators: please do not translate Face. */
     {N_("_Face Path"),
      "identity-facepath",
@@ -1004,6 +1005,9 @@ setup_ident_frame(GtkDialog * dialog, gboolean createp, gpointer tree)
                                  _("send messages in both plain text and _HTML format"),
                                  "identity-sendmpalternative", TRUE);
     ident_dialog_add_checkbutton(table, row++, dialog, 
+                                 _("request positive (successful) _Delivery Status Notification by default"),
+                                 "identity-requestdsn", TRUE);
+    ident_dialog_add_checkbutton(table, row++, dialog,
                                  _("request _Message Disposition Notification by default"),
                                  "identity-requestmdn", TRUE);
     ident_dialog_add_file_chooser_button(table, row++, dialog,
@@ -1483,6 +1487,7 @@ ident_dialog_update(GObject * dlg)
     g_free(id->x_face);
     id->x_face          = ident_dialog_get_path(dlg, "identity-xfacepath");
     id->request_mdn     = ident_dialog_get_bool(dlg, "identity-requestmdn");
+    id->request_dsn     = ident_dialog_get_bool(dlg, "identity-requestdsn");
 
     id->gpg_sign        = ident_dialog_get_bool(dlg, "identity-gpgsign");
     id->gpg_encrypt     = ident_dialog_get_bool(dlg, "identity-gpgencrypt");
@@ -1870,6 +1875,8 @@ display_frame_update(GObject * dialog, LibBalsaIdentity* ident)
                            ident->x_face, TRUE);
     display_frame_set_boolean(dialog, "identity-requestmdn", 
                               ident->request_mdn);    
+    display_frame_set_boolean(dialog, "identity-requestdsn",
+                              ident->request_dsn);
 
     display_frame_set_boolean(dialog, "identity-gpgsign", 
                               ident->gpg_sign);    
@@ -1975,6 +1982,7 @@ libbalsa_identity_new_config(const gchar* name)
     ident->face = libbalsa_conf_get_string("FacePath");
     ident->x_face = libbalsa_conf_get_string("XFacePath");
     ident->request_mdn = libbalsa_conf_get_bool("RequestMDN");
+    ident->request_dsn = libbalsa_conf_get_bool("RequestDSN");
 
     ident->gpg_sign = libbalsa_conf_get_bool("GpgSign");
     ident->gpg_encrypt = libbalsa_conf_get_bool("GpgEncrypt");
@@ -2021,6 +2029,7 @@ libbalsa_identity_save(LibBalsaIdentity* ident, const gchar* group)
     if (ident->x_face)
         libbalsa_conf_set_string("XFacePath", ident->x_face);
     libbalsa_conf_set_bool("RequestMDN", ident->request_mdn);
+    libbalsa_conf_set_bool("RequestDSN", ident->request_dsn);
 
     libbalsa_conf_set_bool("GpgSign", ident->gpg_sign);
     libbalsa_conf_set_bool("GpgEncrypt", ident->gpg_encrypt);
diff --git a/libbalsa/identity.h b/libbalsa/identity.h
index 606f2ce..a91afe9 100644
--- a/libbalsa/identity.h
+++ b/libbalsa/identity.h
@@ -77,6 +77,7 @@ extern "C"
         gchar *face;
         gchar *x_face;
        gboolean request_mdn;
+       gboolean request_dsn;
 
        gboolean gpg_sign;
        gboolean gpg_encrypt;
diff --git a/libbalsa/imap/pop3.h b/libbalsa/imap/pop3.h
index 6c7efeb..7051641 100644
--- a/libbalsa/imap/pop3.h
+++ b/libbalsa/imap/pop3.h
@@ -33,9 +33,13 @@
  * Error domains for GError: only one for now, more to come.
  */
 
+#if 0
 enum {
     IMAP_ERROR
 };
+#else
+#define IMAP_ERROR (g_quark_from_static_string("libbalsa-imap-quark"))
+#endif
  
 /*
  * Error codes for GError: only one for now, more to come.
diff --git a/libbalsa/message.h b/libbalsa/message.h
index 86f26b2..ef5c941 100644
--- a/libbalsa/message.h
+++ b/libbalsa/message.h
@@ -214,6 +214,9 @@ struct _LibBalsaMessage {
     gchar * force_key_id;
 #endif
 
+    /* request a DSN (sending) */
+    gboolean request_dsn;
+
     /* a forced multipart subtype or NULL for mixed; used only for
      * sending */
     gchar *subtype;
diff --git a/libbalsa/send.c b/libbalsa/send.c
index fb303d2..fa241ba 100644
--- a/libbalsa/send.c
+++ b/libbalsa/send.c
@@ -597,7 +597,8 @@ libbalsa_message_cb (void **buf, int *len, void *arg)
 
 static void
 add_recipients(smtp_message_t message,
-               InternetAddressList * recipient_list)
+               InternetAddressList * recipient_list,
+               gboolean request_dsn)
 {
     const InternetAddress *ia;
     int i;
@@ -608,14 +609,19 @@ add_recipients(smtp_message_t message,
     for (i = 0; i < internet_address_list_length (recipient_list); i++) {
         ia = internet_address_list_get_address (recipient_list, i);
 
-       if (INTERNET_ADDRESS_IS_MAILBOX (ia))
-           smtp_add_recipient (message, INTERNET_ADDRESS_MAILBOX (ia)->addr);
-       else
-           add_recipients(message, INTERNET_ADDRESS_GROUP (ia)->members);
+       if (INTERNET_ADDRESS_IS_MAILBOX (ia)) {
+           smtp_recipient_t recipient;
+
+           recipient = smtp_add_recipient (message, INTERNET_ADDRESS_MAILBOX (ia)->addr);
+           if (request_dsn) {
+               smtp_dsn_set_notify(recipient, Notify_SUCCESS | Notify_FAILURE | Notify_DELAY);
 
-            /* XXX  - this is where to add DSN requests.  It would be
-               cool if LibBalsaAddress could contain DSN options
-               for a particular recipient. */
+               /* XXX  - It would be cool if LibBalsaAddress could contain DSN options
+                  for a particular recipient.  For the time being, just use a switch */
+           }
+       } else {
+           add_recipients(message, INTERNET_ADDRESS_GROUP (ia)->members, request_dsn);
+       }
     }
 }
 
@@ -776,6 +782,11 @@ lbs_process_queue(LibBalsaMailbox * outbox, LibBalsaFccboxFinder finder,
            /* Add this after the Bcc: copy. */
            message = smtp_add_message (session);
 
+           if (msg->request_dsn) {
+               smtp_dsn_set_ret(message, Ret_HDRS);
+               smtp_dsn_set_envid(message, msg->message_id);
+           }
+
             /* The main copy must not contain a Bcc: header, unless the
              * message has no To: recipients and no Cc: recipients, and
              * exactly one Bcc: recipient: */
@@ -856,11 +867,11 @@ lbs_process_queue(LibBalsaMailbox * outbox, LibBalsaFccboxFinder finder,
               the Bcc recipient list, when it has more than one address.
               The bcc copy gets the single Bcc recipient.  */
 
-            add_recipients(message, msg->headers->to_list);
-            add_recipients(message, msg->headers->cc_list);
+            add_recipients(message, msg->headers->to_list, msg->request_dsn);
+            add_recipients(message, msg->headers->cc_list, msg->request_dsn);
 
             add_recipients(bcc_message ? bcc_message : message, 
-                           msg->headers->bcc_list);
+                           msg->headers->bcc_list, msg->request_dsn);
 
            /* Prohibit status headers. */
            smtp_set_header_option(message, "Status", Hdr_PROHIBIT, 1);
@@ -1601,7 +1612,7 @@ balsa_send_message_real(SendMessageInfo* info)
 
 
 static void
-message_add_references(LibBalsaMessage * message, GMimeMessage * msg)
+message_add_references(const LibBalsaMessage * message, GMimeMessage * msg)
 {
     /* If the message has references set, add them to the envelope */
     if (message->references != NULL) {
diff --git a/src/balsa-icons.c b/src/balsa-icons.c
index 6c02d74..9f08b5e 100644
--- a/src/balsa-icons.c
+++ b/src/balsa-icons.c
@@ -139,8 +139,9 @@ load_balsa_pixmap(GtkIconTheme *icon_theme, GtkIconFactory *factory,
                gtk_icon_set_add_source(icon_set, icon_source);
                 gtk_icon_source_free(icon_source);
            }
-       } else
+       } else {
            BICONS_ERR("bad size %d", bpixmap->sizes[n]);
+       }
     }
 
     gtk_icon_factory_add(factory, bpixmap->name, icon_set);
diff --git a/src/balsa-index.c b/src/balsa-index.c
index 95d29bb..e1ab0db 100644
--- a/src/balsa-index.c
+++ b/src/balsa-index.c
@@ -1874,7 +1874,7 @@ mru_menu_cb(const gchar * url, BalsaIndex * index)
 static GtkWidget *
 bndx_popup_menu_create(BalsaIndex * index)
 {
-    const static struct {       /* this is a invariable part of */
+    static const struct {       /* this is a invariable part of */
         const char *icon, *label;       /* the context message menu.    */
         GCallback func;
     } entries[] = {
diff --git a/src/filter-edit-callbacks.c b/src/filter-edit-callbacks.c
index c0651ce..ddb8ba8 100644
--- a/src/filter-edit-callbacks.c
+++ b/src/filter-edit-callbacks.c
@@ -1718,7 +1718,7 @@ change_filter_name(gchar * old_name,gchar * new_name)
 void
 fe_new_pressed(GtkWidget * widget, gpointer data)
 {
-    const static char FLT_NAME_TEMPLATE[] = N_("New filter");
+    static const char FLT_NAME_TEMPLATE[] = N_("New filter");
     gint filter_number;
     LibBalsaFilter* fil;
     guint len = strlen(_(FLT_NAME_TEMPLATE))+4;
diff --git a/src/sendmsg-window.c b/src/sendmsg-window.c
index 835e0bb..e667d4d 100644
--- a/src/sendmsg-window.c
+++ b/src/sendmsg-window.c
@@ -130,6 +130,8 @@ static void toggle_fcc_cb          (GtkToggleAction * toggle_action,
                                     BalsaSendmsg * bsmsg);
 static void toggle_reqdispnotify_cb(GtkToggleAction * toggle_action,
                                     BalsaSendmsg * bsmsg);
+static void toggle_reqdsn_cb       (GtkToggleAction * toggle_action,
+                                    BalsaSendmsg * bsmsg);
 static void sw_show_toolbar_cb     (GtkToggleAction * action,
                                     BalsaSendmsg * bsmsg);
 static void toggle_format_cb       (GtkToggleAction * toggle_action,
@@ -428,10 +430,14 @@ static const GtkToggleActionEntry toggle_entries[] = {
 #endif                          /* ENABLE_TOUCH_UI */
     {"Fcc", NULL, N_("F_cc"), NULL, NULL,
      G_CALLBACK(toggle_fcc_cb), TRUE},
-    {"RequestMDN", BALSA_PIXMAP_REQUEST_MDN,
-     N_("_Request Disposition Notification"), NULL, 
-     N_("Request Message Disposition Notification"),
-     G_CALLBACK(toggle_reqdispnotify_cb), FALSE},
+     {"RequestMDN", BALSA_PIXMAP_REQUEST_MDN,
+      N_("_Request Disposition Notification"), NULL,
+      N_("Request Message Disposition Notification"),
+      G_CALLBACK(toggle_reqdispnotify_cb), FALSE},
+     {"RequestDSN", BALSA_PIXMAP_REQUEST_MDN,
+       N_("_Request Delivery Status Notification"), NULL,
+       N_("Request positive (successful) Delivery Status Notification"),
+       G_CALLBACK(toggle_reqdsn_cb), FALSE},
     {"Flowed", NULL, N_("_Format = Flowed"), NULL,
      NULL, G_CALLBACK(toggle_format_cb), FALSE},
     /* Send as message/alternative with text/plain and text/html parts */
@@ -524,6 +530,7 @@ static const char *ui_description =
 "    <menu action='LanguageMenu'>"
 "    </menu>"
 "    <menu action='OptionsMenu'>"
+"      <menuitem action='RequestDSN'/>"
 "      <menuitem action='RequestMDN'/>"
 "      <menuitem action='Flowed'/>"
 "      <menuitem action='SendMPAlt'/>"
@@ -591,6 +598,7 @@ static const char *ui_description =
 "      </menu>"
 "      <separator/>"
 "      <menuitem action='SelectIdentity'/>"
+"      <menuitem action='RequestDSN'/>"
 "      <menuitem action='RequestMDN'/>"
 "      <menu action='ToolsMoreMenu'>"
 "        <menuitem action='Flowed'/>"
@@ -1658,6 +1666,7 @@ update_bsmsg_identity(BalsaSendmsg* bsmsg, LibBalsaIdentity* ident)
     libbalsa_address_view_set_domain(bsmsg->recipient_view, ident->domain);
 
     sw_set_active(bsmsg, "RequestMDN", ident->request_mdn);
+    sw_set_active(bsmsg, "RequestDSN", ident->request_dsn);
 }
 
 
@@ -4680,7 +4689,8 @@ sendmsg_window_new()
 #endif                          /* HAVE_GTKSOURCEVIEW */
 
     /* set options */
-    bsmsg->req_dispnotify = FALSE;
+    bsmsg->req_mdn = FALSE;
+    bsmsg->req_dsn = FALSE;
 
     sw_set_active(bsmsg, "Flowed", bsmsg->flow);
     sw_set_active(bsmsg, "SendMPAlt", bsmsg->ident->send_mp_alternative);
@@ -5088,6 +5098,9 @@ sendmsg_window_continue(LibBalsaMailbox * mailbox, guint msgno)
          libbalsa_message_get_user_header(message, "X-Balsa-MDN")))
         sw_set_active(bsmsg, "RequestMDN", atoi(postpone_hdr) != 0);
     if ((postpone_hdr =
+         libbalsa_message_get_user_header(message, "X-Balsa-DSN")))
+        sw_set_active(bsmsg, "RequestDSN", atoi(postpone_hdr) != 0);
+    if ((postpone_hdr =
          libbalsa_message_get_user_header(message, "X-Balsa-Lang"))) {
         GtkWidget *langs =
             gtk_menu_item_get_submenu(GTK_MENU_ITEM
@@ -5610,8 +5623,9 @@ bsmsg2message(BalsaSendmsg * bsmsg)
         libbalsa_address_view_get_list(bsmsg->replyto_view, "Reply To:");
 #endif
 
-    if (bsmsg->req_dispnotify)
+    if (bsmsg->req_mdn)
        libbalsa_message_set_dispnotify(message, ident->ia);
+    message->request_dsn = bsmsg->req_dsn;
 
     sw_set_header_from_path(message, "Face", ident->face,
             /* Translators: please do not translate Face. */
@@ -6136,7 +6150,9 @@ message_postpone(BalsaSendmsg * bsmsg)
         g_ptr_array_add(headers, g_strdup(bsmsg->fcc_url));
     }
     g_ptr_array_add(headers, g_strdup("X-Balsa-MDN"));
-    g_ptr_array_add(headers, g_strdup_printf("%d", bsmsg->req_dispnotify));
+    g_ptr_array_add(headers, g_strdup_printf("%d", bsmsg->req_mdn));
+    g_ptr_array_add(headers, g_strdup("X-Balsa-DSN"));
+    g_ptr_array_add(headers, g_strdup_printf("%d", bsmsg->req_dsn));
 #ifdef HAVE_GPGME
     g_ptr_array_add(headers, g_strdup("X-Balsa-Crypto"));
     g_ptr_array_add(headers, g_strdup_printf("%d", bsmsg->gpg_mode));
@@ -6639,7 +6655,14 @@ static void
 toggle_reqdispnotify_cb(GtkToggleAction * action,
                         BalsaSendmsg * bsmsg)
 {
-    bsmsg->req_dispnotify = gtk_toggle_action_get_active(action);
+    bsmsg->req_mdn = gtk_toggle_action_get_active(action);
+}
+
+static void
+toggle_reqdsn_cb(GtkToggleAction * action,
+                 BalsaSendmsg * bsmsg)
+{
+    bsmsg->req_dsn = gtk_toggle_action_get_active(action);
 }
 
 static void
diff --git a/src/sendmsg-window.h b/src/sendmsg-window.h
index c555b76..2513333 100644
--- a/src/sendmsg-window.h
+++ b/src/sendmsg-window.h
@@ -97,7 +97,8 @@ extern "C" {
         gulong identities_changed_id;
        gboolean flow;          /* send format=flowed */ 
        gboolean send_mp_alt;   /* send multipart/alternative (plain and html) */ 
-       gboolean req_dispnotify; /* send a MDN */ 
+       gboolean req_mdn;        /* send a MDN */
+       gboolean req_dsn;        /* send a delivery status notification */
        gboolean quit_on_close; /* quit balsa after the compose window */
                                /* is closed.                          */
         /* style for changing the color of address labels when the


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]