[balsa/64-save-empty-attachment] body: implement libbalsa_message_body_check_if_empty()




commit d5b1c407638506ebd3ed6480e4e707ed2e46c742
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Mon Jan 17 17:20:48 2022 -0500

    body: implement libbalsa_message_body_check_if_empty()
    
    balsa-mime-widget-callbacks: Warn about empty part
    
    Do not try to save an empty attachment.

 libbalsa/body.c                   | 51 +++++++++++++++++++++++++++++++++++++++
 libbalsa/body.h                   |  3 +++
 src/balsa-mime-widget-callbacks.c | 20 +++++++++++++++
 3 files changed, 74 insertions(+)
---
diff --git a/libbalsa/body.c b/libbalsa/body.c
index d2c732305..39374b310 100644
--- a/libbalsa/body.c
+++ b/libbalsa/body.c
@@ -779,6 +779,57 @@ libbalsa_message_body_save_stream(LibBalsaMessageBody * body,
     return len >= 0;
 }
 
+/*
+ * libbalsa_message_body_check_if_empty
+ *
+ * body:     the message body to check
+ * is_empty: location to store the result
+ * err:      a GError
+ *
+ * Returns FALSE if the body could not be checked; the error is reported
+ *     in err.
+ *
+ * This seems complicated, but see https://gitlab.gnome.org/GNOME/glib/-/blob/main/glib/gerror.c#L358
+ */
+gboolean
+libbalsa_message_body_check_if_empty(LibBalsaMessageBody * body,
+                                     gboolean *is_empty,
+                                     GError **err)
+{
+    GMimeStream *body_stream;
+    gboolean retval = FALSE;
+
+    g_return_val_if_fail(body != NULL, FALSE);
+
+    body_stream = libbalsa_message_body_get_stream(body, err);
+
+    if (body_stream != NULL) {
+        gint64 len;
+
+        len = g_mime_stream_length(body_stream);
+
+        if (len < 0) {
+            char buf[1];
+
+            len = g_mime_stream_read(body_stream, buf, 1);
+        }
+
+        if (len < 0) {
+            g_set_error(err, LIBBALSA_ERROR_QUARK, 1,
+                        _("Failed to read stream"));
+        } else {
+            if (is_empty != NULL)
+                *is_empty = (len == 0);
+
+            retval = TRUE;
+        }
+
+        g_object_unref(body_stream);
+    }
+
+    return retval;
+}
+
 gchar *
 libbalsa_message_body_get_mime_type(LibBalsaMessageBody * body)
 {
diff --git a/libbalsa/body.h b/libbalsa/body.h
index 08098aa28..04bfc24e6 100644
--- a/libbalsa/body.h
+++ b/libbalsa/body.h
@@ -107,6 +107,9 @@ gboolean libbalsa_message_body_save_stream(LibBalsaMessageBody * body,
                                            GMimeStream * dest,
                                            gboolean filter_crlf,
                                            GError **err);
+gboolean libbalsa_message_body_check_if_empty(LibBalsaMessageBody * body,
+                                              gboolean *is_empty,
+                                              GError **err);
 gboolean libbalsa_message_body_save(LibBalsaMessageBody * body,
                                     const gchar * filename, mode_t mode,
                                     gboolean filter_crlf, GError **err);
diff --git a/src/balsa-mime-widget-callbacks.c b/src/balsa-mime-widget-callbacks.c
index 895e5a844..f01989c75 100644
--- a/src/balsa-mime-widget-callbacks.c
+++ b/src/balsa-mime-widget-callbacks.c
@@ -67,6 +67,7 @@ balsa_mime_widget_ctx_menu_save(GtkWidget * parent_widget,
                                LibBalsaMessageBody * mime_body)
 {
     gchar *cont_type, *title;
+    gboolean is_empty;
     GtkWidget *save_dialog;
     gchar *file_uri;
     LibbalsaVfs *save_file;
@@ -76,6 +77,25 @@ balsa_mime_widget_ctx_menu_save(GtkWidget * parent_widget,
     g_return_if_fail(mime_body != NULL);
 
     cont_type = libbalsa_message_body_get_mime_type(mime_body);
+
+
+    if (!libbalsa_message_body_check_if_empty(mime_body, &is_empty, &err)) {
+        balsa_information(LIBBALSA_INFORMATION_ERROR,
+                          _("Could not access %s MIME Part: %s"), cont_type, err->message);
+        g_error_free(err);
+        g_free(cont_type);
+
+        return;
+    }
+
+    if (is_empty) {
+        balsa_information(LIBBALSA_INFORMATION_WARNING,
+                          _("Empty %s MIME Part was not saved"), cont_type);
+        g_free(cont_type);
+
+        return;
+    }
+
     title = g_strdup_printf(_("Save %s MIME Part"), cont_type);
 
     save_dialog =


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