2006-06-15 [colin] 2.3.0cvs16
authorColin Leroy <colin@colino.net>
Thu, 15 Jun 2006 17:03:17 +0000 (17:03 +0000)
committerColin Leroy <colin@colino.net>
Thu, 15 Jun 2006 17:03:17 +0000 (17:03 +0000)
* src/folderview.c
Add "Send queue" in the folder's contextual
menu
* src/compose.c
* src/messageview.c
* src/privacy.c
* src/privacy.h
* src/procmime.c
* src/procmsg.c
* src/plugins/pgpcore/passphrase.c
* src/plugins/pgpcore/sgpgme.c
* src/plugins/pgpinline/pgpinline.c
* src/plugins/pgpmime/pgpmime.c
Better error reporting
* src/mbox.c
Probably fix bug #971 (2.2.3 cannot read mail
from local mbox)

15 files changed:
ChangeLog
PATCHSETS
configure.ac
src/compose.c
src/folderview.c
src/mbox.c
src/messageview.c
src/plugins/pgpcore/passphrase.c
src/plugins/pgpcore/sgpgme.c
src/plugins/pgpinline/pgpinline.c
src/plugins/pgpmime/pgpmime.c
src/privacy.c
src/privacy.h
src/procmime.c
src/procmsg.c

index 1ce54b5..246473f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2006-06-15 [colin]     2.3.0cvs16
+
+       * src/folderview.c
+               Add "Send queue" in the folder's contextual
+               menu
+       * src/compose.c
+       * src/messageview.c
+       * src/privacy.c
+       * src/privacy.h
+       * src/procmime.c
+       * src/procmsg.c
+       * src/plugins/pgpcore/passphrase.c
+       * src/plugins/pgpcore/sgpgme.c
+       * src/plugins/pgpinline/pgpinline.c
+       * src/plugins/pgpmime/pgpmime.c
+               Better error reporting
+       * src/mbox.c
+               Probably fix bug #971 (2.2.3 cannot read mail 
+               from local mbox)
+
+
 2006-06-15 [mones]     2.3.0cvs15
 
        * tools/make.themes.project
index 6f1e9b7..0eecd8d 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.213.2.99 -r 1.213.2.100 src/folder.c;  ) > 2.3.0cvs13.patchset
 ( cvs diff -u -r 1.213.2.100 -r 1.213.2.101 src/folder.c;  ) > 2.3.0cvs14.patchset
 ( diff -u /dev/null tools/make.themes.project;  ) > 2.3.0cvs15.patchset
+( cvs diff -u -r 1.382.2.277 -r 1.382.2.278 src/compose.c;  cvs diff -u -r 1.207.2.103 -r 1.207.2.104 src/folderview.c;  cvs diff -u -r 1.28.2.17 -r 1.28.2.18 src/mbox.c;  cvs diff -u -r 1.94.2.87 -r 1.94.2.88 src/messageview.c;  cvs diff -u -r 1.10.2.8 -r 1.10.2.9 src/privacy.c;  cvs diff -u -r 1.10.2.7 -r 1.10.2.8 src/privacy.h;  cvs diff -u -r 1.49.2.77 -r 1.49.2.78 src/procmime.c;  cvs diff -u -r 1.150.2.68 -r 1.150.2.69 src/procmsg.c;  cvs diff -u -r 1.1.2.13 -r 1.1.2.14 src/plugins/pgpcore/passphrase.c;  cvs diff -u -r 1.1.2.18 -r 1.1.2.19 src/plugins/pgpcore/sgpgme.c;  cvs diff -u -r 1.1.2.12 -r 1.1.2.13 src/plugins/pgpinline/pgpinline.c;  cvs diff -u -r 1.1.2.34 -r 1.1.2.35 src/plugins/pgpmime/pgpmime.c;  ) > 2.3.0cvs16.patchset
index 133d66b..5e5ad2d 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=3
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=15
+EXTRA_VERSION=16
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 60945b7..f567ea2 100644 (file)
@@ -4055,7 +4055,7 @@ gint compose_send(Compose *compose)
                                           "Charset conversion failed."));
                } else if (val == -3) {
                        alertpanel_error(_("Could not queue message for sending:\n\n"
-                                          "Signature failed."));
+                                          "Signature failed: %s"), privacy_get_error());
                } else if (val == -2 && errno != 0) {
                        alertpanel_error(_("Could not queue message for sending:\n\n%s."), strerror(errno));
                } else {
@@ -7520,7 +7520,7 @@ static void compose_send_later_cb(gpointer data, guint action,
                alertpanel_error(_("Could not queue message:\n\n%s."), strerror(errno));
        } else if (val == -3) {
                alertpanel_error(_("Could not queue message for sending:\n\n"
-                                  "Signature failed."));
+                                  "Signature failed: %s"), privacy_get_error());
        } else if (val == -4) {
                alertpanel_error(_("Could not queue message for sending:\n\n"
                                   "Charset conversion failed."));
index 06f1e8c..5f5fbed 100644 (file)
@@ -227,6 +227,10 @@ static void folderview_empty_trash_cb      (FolderView     *folderview,
                                         guint           action,
                                         GtkWidget      *widget);
 
+static void folderview_send_queue_cb   (FolderView     *folderview,
+                                        guint           action,
+                                        GtkWidget      *widget);
+
 static void folderview_search_cb       (FolderView     *folderview,
                                         guint           action,
                                         GtkWidget      *widget);
@@ -285,10 +289,15 @@ static GtkItemFactoryEntry folderview_common_popup_entries[] =
 };
 
 static GtkItemFactoryEntry folder_view_trash_popup_entries[] = {
-       {N_("/------"),                 NULL, NULL, 0, "<Separator>"},
+       {N_("/------trashsep"),                 NULL, NULL, 0, "<Separator>"},
        {N_("/Empty _trash..."),        NULL, folderview_empty_trash_cb, 0, NULL},
 };
 
+static GtkItemFactoryEntry folder_view_queue_popup_entries[] = {
+       {N_("/------queuesep"),                 NULL, NULL, 0, "<Separator>"},
+       {N_("/Send _queue..."), NULL, folderview_send_queue_cb, 0, NULL},
+};
+
 
 GtkTargetEntry folderview_drag_types[] =
 {
@@ -1503,8 +1512,6 @@ static void folderview_update_node(FolderView *folderview, GtkCTreeNode *node)
                        style = bold_tgtfold_style;
                }
        } else if (use_color) {
-               GdkColor gdk_color;
-
                style = normal_color_style;
                gtk_ctree_node_set_foreground(ctree, node,
                                              &folderview->color_new);
@@ -1723,7 +1730,7 @@ static gboolean folderview_button_pressed(GtkWidget *ctree, GdkEventButton *even
        FolderViewPopup *fpopup;
        GtkItemFactory *fpopup_factory;
        GtkWidget *popup;
-       FolderItem *special_trash = NULL;
+       FolderItem *special_trash = NULL, *special_queue = NULL;
        PrefsAccount *ac;
 
        if (!event) return FALSE;
@@ -1789,9 +1796,11 @@ static gboolean folderview_button_pressed(GtkWidget *ctree, GdkEventButton *even
        if (fpopup->set_sensitivity != NULL)
                fpopup->set_sensitivity(fpopup_factory, item);
 
-       if (NULL != (ac = account_find_from_item(item)))
+       if (NULL != (ac = account_find_from_item(item))) {
                special_trash = account_get_special_folder(ac, F_TRASH);
-
+               special_queue = account_get_special_folder(ac, F_QUEUE);
+       }
+       
        if ((item == folder->trash || item == special_trash
             || folder_has_parent_of_type(item, F_TRASH)) &&
            gtk_item_factory_get_item(fpopup_factory, "/Empty trash...") == NULL) {
@@ -1803,6 +1812,17 @@ static gboolean folderview_button_pressed(GtkWidget *ctree, GdkEventButton *even
                gtk_item_factory_delete_entry(fpopup_factory, &folder_view_trash_popup_entries[1]);
        }
        
+       if ((item == folder->queue || item == special_queue
+            || folder_has_parent_of_type(item, F_QUEUE)) &&
+           gtk_item_factory_get_item(fpopup_factory, "/Send queue...") == NULL) {
+               gtk_item_factory_create_item(fpopup_factory, &folder_view_queue_popup_entries[0], folderview, 1);
+               gtk_item_factory_create_item(fpopup_factory, &folder_view_queue_popup_entries[1], folderview, 1);
+       } else if (item != folder->queue && (special_queue == NULL || item != special_queue)
+               && !folder_has_parent_of_type(item, F_QUEUE)) {
+               gtk_item_factory_delete_entry(fpopup_factory, &folder_view_queue_popup_entries[0]);
+               gtk_item_factory_delete_entry(fpopup_factory, &folder_view_queue_popup_entries[1]);
+       }
+       
 #define SET_SENS(name, sens) \
        menu_set_sensitive(fpopup_factory, name, sens)
 
@@ -1817,6 +1837,12 @@ static gboolean folderview_button_pressed(GtkWidget *ctree, GdkEventButton *even
                SET_SENS("/Empty trash...", msglist != NULL);
                procmsg_msg_list_free(msglist);
        }
+       if (item == folder->queue || item == special_queue
+           || folder_has_parent_of_type(item, F_QUEUE)) {
+               GSList *msglist = folder_item_get_msg_list(item);
+               SET_SENS("/Send queue...", msglist != NULL);
+               procmsg_msg_list_free(msglist);
+       }
 #undef SET_SENS
 
        popup = gtk_item_factory_get_widget(fpopup_factory, fpopup->path);
@@ -2159,6 +2185,64 @@ static void folderview_empty_trash_cb(FolderView *folderview, guint action,
        folder_item_remove_all_msg(item);
 }
 
+static void folderview_send_queue_cb(FolderView *folderview, guint action,
+                                     GtkWidget *widget)
+{
+       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
+       FolderItem *item;
+       FolderItem *special_queue = NULL;
+       PrefsAccount *ac;
+       gchar *errstr = NULL;
+
+       if (!folderview->selected) return;
+       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
+       g_return_if_fail(item != NULL);
+       g_return_if_fail(item->folder != NULL);
+
+       if (NULL != (ac = account_find_from_item(item)))
+               special_queue = account_get_special_folder(ac, F_QUEUE);
+
+       if (item != item->folder->queue && item != special_queue
+       &&  !folder_has_parent_of_type(item, F_QUEUE)) return;
+       
+       if (procmsg_queue_is_empty(item))
+               return;
+
+       if (prefs_common.work_offline)
+               if (alertpanel(_("Offline warning"), 
+                              _("You're working offline. Override?"),
+                              GTK_STOCK_NO, GTK_STOCK_YES,
+                              NULL) != G_ALERTALTERNATE)
+               return;
+
+       /* ask for confirmation before sending queued messages only
+          in online mode and if there is at least one message queued
+          in any of the folder queue
+       */
+       if (prefs_common.confirm_send_queued_messages) {
+               if (!prefs_common.work_offline) {
+                       if (alertpanel(_("Send queued messages"), 
+                                  _("Send all queued messages?"),
+                                  GTK_STOCK_CANCEL, _("_Send"),
+                                  NULL) != G_ALERTALTERNATE)
+                               return;
+               }
+       }
+
+       if (procmsg_send_queue(item, prefs_common.savemsg, &errstr) < 0) {
+               if (!errstr)
+                       alertpanel_error_log(_("Some errors occurred while "
+                                          "sending queued messages."));
+               else {
+                       gchar *tmp = g_strdup_printf(_("Some errors occurred "
+                                       "while sending queued messages:\n%s"), errstr);
+                       g_free(errstr);
+                       alertpanel_error_log(tmp);
+                       g_free(tmp);
+               }
+       }
+}
+
 static void folderview_search_cb(FolderView *folderview, guint action,
                                 GtkWidget *widget)
 {
index be06f0d..26cea30 100644 (file)
@@ -278,6 +278,7 @@ gint lock_mbox(const gchar *base, LockType type)
                g_free(lockfile);
        } else if (type == LOCK_FLOCK) {
                gint lockfd;
+               gboolean fcntled = FALSE;
 #if HAVE_FCNTL_H
                struct flock fl;
                fl.l_type = F_WRLCK;
@@ -299,15 +300,17 @@ gint lock_mbox(const gchar *base, LockType type)
                if (fcntl(lockfd, F_SETLK, &fl) == -1) {
                        g_warning("can't fnctl %s (%s)", base, strerror(errno));
                        return -1;
+               } else {
+                       fcntled = TRUE;
                }
 #endif
 
 #if HAVE_FLOCK
-               if (flock(lockfd, LOCK_EX|LOCK_NB) < 0) {
+               if (flock(lockfd, LOCK_EX|LOCK_NB) < 0 && !fcntled) {
                        perror("flock");
 #else
 #if HAVE_LOCKF
-               if (lockf(lockfd, F_TLOCK, 0) < 0) {
+               if (lockf(lockfd, F_TLOCK, 0) < 0 && !fcntled) {
                        perror("lockf");
 #else
                {
@@ -345,6 +348,7 @@ gint unlock_mbox(const gchar *base, gint fd, LockType type)
 
                return 0;
        } else if (type == LOCK_FLOCK) {
+               gboolean fcntled = FALSE;
 #if HAVE_FCNTL_H
                struct flock fl;
                fl.l_type = F_UNLCK;
@@ -355,14 +359,16 @@ gint unlock_mbox(const gchar *base, gint fd, LockType type)
                if (fcntl(fd, F_SETLK, &fl) == -1) {
                        g_warning("can't fnctl %s", base);
                        return -1;
+               } else {
+                       fcntled = TRUE;
                }
 #endif
 #if HAVE_FLOCK
-               if (flock(fd, LOCK_UN) < 0) {
+               if (flock(fd, LOCK_UN) < 0 && !fcntled) {
                        perror("flock");
 #else
 #if HAVE_LOCKF
-               if (lockf(fd, F_ULOCK, 0) < 0) {
+               if (lockf(fd, F_ULOCK, 0) < 0 && !fcntled) {
                        perror("lockf");
 #else
                {
index 6e48381..d7382ac 100644 (file)
@@ -788,8 +788,11 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
 
        while ((encinfo = find_encrypted_part(mimeinfo)) != NULL) {
                debug_print("decrypting message part\n");
-               if (privacy_mimeinfo_decrypt(encinfo) < 0)
+               if (privacy_mimeinfo_decrypt(encinfo) < 0) {
+                       alertpanel_error(_("Couldn't decrypt: %s"),
+                               privacy_get_error());
                        break;
+               }
        }
        
        messageview->updating = TRUE;
index 2e7a45b..770dea6 100644 (file)
@@ -294,7 +294,7 @@ static int free_passphrase(gpointer _unused)
 #endif
         g_free(last_pass);
         last_pass = NULL;
-        debug_print("%% passphrase removed");
+        debug_print("%% passphrase removed\n");
     }
     
     return FALSE;
@@ -310,11 +310,11 @@ gpgmegtk_passphrase_cb(void *opaque, const char *uid_hint,
         pass = last_pass;
     else {
     gpgmegtk_set_passphrase_grab (prefs_gpg_get_config()->passphrase_grab);
-    debug_print ("%% requesting passphrase for '%s': ", uid_hint);
+    debug_print ("%% requesting passphrase for '%s'\n ", uid_hint);
     pass = passphrase_mbox (uid_hint, passphrase_hint, prev_bad);
     gpgmegtk_free_passphrase();
     if (!pass) {
-        debug_print ("%% cancel passphrase entry");
+        debug_print ("%% cancel passphrase entry\n");
         write(fd, "\n", 1);
         return GPG_ERR_CANCELED;
     }
@@ -323,7 +323,7 @@ gpgmegtk_passphrase_cb(void *opaque, const char *uid_hint,
             last_pass = g_strdup(pass);
 #ifndef G_PLATFORM_WIN32
             if (mlock(last_pass, strlen(last_pass)) == -1)
-                debug_print("%% locking passphrase failed");
+                debug_print("%% locking passphrase failed\n");
 #endif
             if (prefs_gpg_get_config()->store_passphrase_timeout > 0) {
                     gtk_timeout_add(prefs_gpg_get_config()
@@ -331,7 +331,7 @@ gpgmegtk_passphrase_cb(void *opaque, const char *uid_hint,
                                 free_passphrase, NULL);
             }
         }
-        debug_print ("%% sending passphrase");
+        debug_print ("%% sending passphrase\n");
     }
     }
 
index 88682de..060febf 100644 (file)
@@ -57,6 +57,7 @@ gpgme_verify_result_t sgpgme_verify_signature(gpgme_ctx_t ctx, gpgme_data_t sig,
 
        if ((err = gpgme_op_verify(ctx, sig, plain, dummy)) != GPG_ERR_NO_ERROR) {
                debug_print("op_verify err %s\n", gpgme_strerror(err));
+               privacy_set_error(gpgme_strerror(err));
                return GINT_TO_POINTER(-GPG_ERR_SYSTEM_ERROR);
                
        }
@@ -163,7 +164,7 @@ gchar *sgpgme_sigstat_info_short(gpgme_ctx_t ctx, gpgme_verify_result_t status)
        static gboolean warned = FALSE;
 
        if (GPOINTER_TO_INT(status) == -GPG_ERR_SYSTEM_ERROR) {
-               return g_strdup(_("The signature can't be checked - GPG error."));
+               return g_strdup_printf(_("The signature can't be checked - %s"), privacy_get_error());
        }
 
        if (status == NULL) {
@@ -344,6 +345,7 @@ gpgme_data_t sgpgme_data_from_mimeinfo(MimeInfo *mimeinfo)
        if (err) {
                debug_print ("gpgme_data_new_from_file failed: %s\n",
                             gpgme_strerror (err));
+               privacy_set_error(_("Couldn't get data from message, %s"), gpgme_strerror(err));
                return NULL;
        }
        return data;
@@ -357,8 +359,9 @@ gpgme_data_t sgpgme_decrypt_verify(gpgme_data_t cipher, gpgme_verify_result_t *s
 
        memset (&info, 0, sizeof info);
        
-       if (gpgme_data_new(&plain) != GPG_ERR_NO_ERROR) {
+       if ((err = gpgme_data_new(&plain)) != GPG_ERR_NO_ERROR) {
                gpgme_release(ctx);
+               privacy_set_error(_("Couldn't initialize data, %s"), gpgme_strerror(err));
                return NULL;
        }
        
@@ -377,6 +380,7 @@ gpgme_data_t sgpgme_decrypt_verify(gpgme_data_t cipher, gpgme_verify_result_t *s
                err = gpgme_op_decrypt_verify(ctx, cipher, plain);
                if (err != GPG_ERR_NO_ERROR) {
                        debug_print("can't decrypt (%s)\n", gpgme_strerror(err));
+                       privacy_set_error("%s", gpgme_strerror(err));
                        gpgmegtk_free_passphrase();
                        gpgme_data_release(plain);
                        return NULL;
@@ -444,6 +448,18 @@ gboolean sgpgme_setup_signers(gpgme_ctx_t ctx, PrefsAccount *account)
 
        config = prefs_gpg_account_get_config(account);
 
+       switch(config->sign_key) {
+       case SIGN_KEY_DEFAULT:
+               debug_print("using default gnupg key\n");
+               break;
+       case SIGN_KEY_BY_FROM:
+               debug_print("using key for %s\n", account->address);
+               break;
+       case SIGN_KEY_CUSTOM:
+               debug_print("using key for %s\n", config->sign_key_id);
+               break;
+       }
+
        if (config->sign_key != SIGN_KEY_DEFAULT) {
                gchar *keyid;
                gpgme_key_t key;
index bf8a345..354230b 100644 (file)
@@ -26,6 +26,8 @@
 
 #include "defs.h"
 #include <glib.h>
+#include <glib/gi18n.h>
+#include <errno.h>
 #include <gpgme.h>
 
 #include "utils.h"
@@ -231,6 +233,7 @@ static gint pgpinline_check_signature(MimeInfo *mimeinfo)
        
        if (!textdata) {
                g_free(textdata);
+               privacy_set_error(_("Couldn't get text data."));
                return 0;
        }
 
@@ -247,9 +250,10 @@ static gint pgpinline_check_signature(MimeInfo *mimeinfo)
        }
        g_free(textdata);
 
-       if (!tmp)
+       if (!tmp) {
+               privacy_set_error(_("Couldn't convert text data to any sane charset."));
                return 0;
-
+       }
        textdata = g_strdup(tmp);
        g_free(tmp);
        
@@ -370,12 +374,14 @@ static MimeInfo *pgpinline_decrypt(MimeInfo *mimeinfo)
        if (procmime_mimeinfo_parent(mimeinfo) == NULL ||
            mimeinfo->type != MIMETYPE_TEXT) {
                gpgme_release(ctx);
+               privacy_set_error(_("Couldn't parse mime part."));
                return NULL;
        }
 
        textdata = get_part_as_string(mimeinfo);
        if (!textdata) {
                gpgme_release(ctx);
+               privacy_set_error(_("Couldn't get text data."));
                return NULL;
        }
 
@@ -398,6 +404,7 @@ static MimeInfo *pgpinline_decrypt(MimeInfo *mimeinfo)
 
        if ((dstfp = g_fopen(fname, "wb")) == NULL) {
                FILE_OP_ERROR(fname, "fopen");
+               privacy_set_error(_("Couldn't open decrypted file %s"), fname);
                g_free(fname);
                gpgme_data_release(plain);
                gpgme_release(ctx);
@@ -427,6 +434,7 @@ static MimeInfo *pgpinline_decrypt(MimeInfo *mimeinfo)
        
        if (parseinfo == NULL) {
                gpgme_release(ctx);
+               privacy_set_error(_("Couldn't scan decrypted file."));
                return NULL;
        }
        decinfo = g_node_first_child(parseinfo->node) != NULL ?
@@ -434,6 +442,7 @@ static MimeInfo *pgpinline_decrypt(MimeInfo *mimeinfo)
                
        if (decinfo == NULL) {
                gpgme_release(ctx);
+               privacy_set_error(_("Couldn't scan decrypted file parts."));
                return NULL;
        }
 
@@ -470,7 +479,9 @@ static gboolean pgpinline_sign(MimeInfo *mimeinfo, PrefsAccount *account)
        gpgme_ctx_t ctx;
        gpgme_data_t gpgtext, gpgsig;
        guint len;
+       gpgme_error_t err;
        struct passphrase_cb_info_s info;
+       gpgme_sign_result_t result = NULL;
 
        memset (&info, 0, sizeof info);
 
@@ -485,6 +496,7 @@ static gboolean pgpinline_sign(MimeInfo *mimeinfo, PrefsAccount *account)
        fp = my_tmpfile();
        if (fp == NULL) {
                perror("my_tmpfile");
+               privacy_set_error(_("Couldn't create temporary file."));
                return FALSE;
        }
        procmime_write_mimeinfo(msgcontent, fp);
@@ -503,6 +515,7 @@ static gboolean pgpinline_sign(MimeInfo *mimeinfo, PrefsAccount *account)
 
        if (!sgpgme_setup_signers(ctx, account)) {
                gpgme_release(ctx);
+               privacy_set_error(_("Couldn't find private key."));
                return FALSE;
        }
 
@@ -511,18 +524,46 @@ static gboolean pgpinline_sign(MimeInfo *mimeinfo, PrefsAccount *account)
                gpgme_set_passphrase_cb (ctx, gpgmegtk_passphrase_cb, &info);
        }
 
-       if (gpgme_op_sign(ctx, gpgtext, gpgsig, GPGME_SIG_MODE_CLEAR
+       if ((err = gpgme_op_sign(ctx, gpgtext, gpgsig, GPGME_SIG_MODE_CLEAR)
            != GPG_ERR_NO_ERROR) {
                gpgme_release(ctx);
+               privacy_set_error(_("Data signing failed, %s"), gpgme_strerror(err));
+               return FALSE;
+       }
+       result = gpgme_op_sign_result(ctx);
+       if (result && result->signatures) {
+               gpgme_new_signature_t sig = result->signatures;
+               while (sig) {
+                       debug_print("valid signature: %s\n", sig->fpr);
+                       sig = sig->next;
+               }
+       } else if (result && result->invalid_signers) {
+               gpgme_invalid_key_t invalid = result->invalid_signers;
+               while (invalid) {
+                       g_warning("invalid signer: %s (%s)", invalid->fpr, 
+                               gpgme_strerror(invalid->reason));
+                       privacy_set_error(_("Data signing failed due to invalid signer: %s"), 
+                               gpgme_strerror(invalid->reason));
+                       invalid = invalid->next;
+               }
+               gpgme_release(ctx);
+               return FALSE;
+       } else {
+               /* can't get result (maybe no signing key?) */
+               debug_print("gpgme_op_sign_result error\n");
+               privacy_set_error(_("Data signing failed, no results."));
+               gpgme_release(ctx);
                return FALSE;
        }
 
+
        sigcontent = gpgme_data_release_and_get_mem(gpgsig, &len);
        
        gpgme_release(ctx);
        
        if (sigcontent == NULL || len <= 0) {
                g_warning("gpgme_data_release_and_get_mem failed");
+               privacy_set_error(_("Data signing failed, no contents."));
                gpgme_data_release(gpgtext);
                g_free(textstr);
                g_free(sigcontent);
@@ -569,7 +610,9 @@ static gboolean pgpinline_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data)
        gpgme_ctx_t ctx;
        gpgme_key_t *kset = NULL;
        gchar **fprs = g_strsplit(encrypt_data, " ", -1);
+       gpgme_error_t err;
        gint i = 0;
+
        while (fprs[i] && strlen(fprs[i])) {
                i++;
        }
@@ -580,11 +623,11 @@ static gboolean pgpinline_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data)
        i = 0;
        while (fprs[i] && strlen(fprs[i])) {
                gpgme_key_t key;
-               gpgme_error_t err;
                err = gpgme_get_key(ctx, fprs[i], &key, 0);
                if (err) {
                        debug_print("can't add key '%s'[%d] (%s)\n", fprs[i],i, gpgme_strerror(err));
-                       break;
+                       privacy_set_error(_("Couldn't add GPG key %s, %s"), fprs[i], gpgme_strerror(err));
+                       return FALSE;
                }
                debug_print("found %s at %d\n", fprs[i], i);
                kset[i] = key;
@@ -604,6 +647,7 @@ static gboolean pgpinline_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data)
 
        fp = my_tmpfile();
        if (fp == NULL) {
+               privacy_set_error(_("Couldn't create temporary file, %s"), strerror(errno));
                perror("my_tmpfile");
                return FALSE;
        }
@@ -621,13 +665,14 @@ static gboolean pgpinline_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data)
        gpgme_new(&ctx);
        gpgme_set_armor(ctx, 1);
 
-       gpgme_op_encrypt(ctx, kset, GPGME_ENCRYPT_ALWAYS_TRUST, gpgtext, gpgenc);
+       err = gpgme_op_encrypt(ctx, kset, GPGME_ENCRYPT_ALWAYS_TRUST, gpgtext, gpgenc);
 
        gpgme_release(ctx);
        enccontent = gpgme_data_release_and_get_mem(gpgenc, &len);
 
        if (enccontent == NULL || len <= 0) {
                g_warning("gpgme_data_release_and_get_mem failed");
+               privacy_set_error(_("Encryption failed, %s"), gpgme_strerror(err));
                gpgme_data_release(gpgtext);
                g_free(textstr);
                return FALSE;
index bce3ef5..706f792 100644 (file)
 
 #include "defs.h"
 #include <glib.h>
+#include <glib/gi18n.h>
 #include <gpgme.h>
 #include <ctype.h>
+#include <errno.h>
 
 #include "utils.h"
 #include "privacy.h"
@@ -185,9 +187,10 @@ static gint pgpmime_check_signature(MimeInfo *mimeinfo)
        g_return_val_if_fail(fp != NULL, SIGNATURE_INVALID);
        
        boundary = g_hash_table_lookup(parent->typeparameters, "boundary");
-       if (!boundary)
+       if (!boundary) {
+               privacy_set_error(_("Signature boundary not found."));
                return 0;
-
+       }
        textstr = get_canonical_content(fp, boundary);
 
        err = gpgme_data_new_from_mem(&textdata, textstr, strlen(textstr), 0);
@@ -300,10 +303,12 @@ static MimeInfo *pgpmime_decrypt(MimeInfo *mimeinfo)
        gpgme_ctx_t ctx;
        gchar *chars;
        size_t len;
+       gpgme_error_t err;
 
-       if (gpgme_new(&ctx) != GPG_ERR_NO_ERROR)
+       if ((err = gpgme_new(&ctx)) != GPG_ERR_NO_ERROR) {
+       privacy_set_error(_("Couldn't initialize GPG context, %s"), gpgme_strerror(err));
                return NULL;
-
+       }
        
        g_return_val_if_fail(pgpmime_is_encrypted(mimeinfo), NULL);
        
@@ -324,6 +329,7 @@ static MimeInfo *pgpmime_decrypt(MimeInfo *mimeinfo)
 
        if ((dstfp = g_fopen(fname, "wb")) == NULL) {
                FILE_OP_ERROR(fname, "fopen");
+               privacy_set_error(_("Couldn't open decrypted file %s"), fname);
                g_free(fname);
                gpgme_data_release(plain);
                gpgme_release(ctx);
@@ -342,11 +348,13 @@ static MimeInfo *pgpmime_decrypt(MimeInfo *mimeinfo)
        g_free(fname);
        if (parseinfo == NULL) {
                gpgme_release(ctx);
+               privacy_set_error(_("Couldn't parse decrypted file."));
                return NULL;
        }
        decinfo = g_node_first_child(parseinfo->node) != NULL ?
                g_node_first_child(parseinfo->node)->data : NULL;
        if (decinfo == NULL) {
+               privacy_set_error(_("Couldn't parse decrypted file parts."));
                gpgme_release(ctx);
                return NULL;
        }
@@ -392,7 +400,7 @@ gboolean pgpmime_sign(MimeInfo *mimeinfo, PrefsAccount *account)
        
        fp = my_tmpfile();
        if (fp == NULL) {
-               perror("my_tmpfile");
+               privacy_set_error(_("Couldn't create temporary file: %s"), strerror(errno));
                return FALSE;
        }
        procmime_write_mimeinfo(mimeinfo, fp);
@@ -431,6 +439,7 @@ gboolean pgpmime_sign(MimeInfo *mimeinfo, PrefsAccount *account)
        fp = my_tmpfile();
        if (fp == NULL) {
                perror("my_tmpfile");
+               privacy_set_error(_("Couldn't create temporary file: %s"), strerror(errno));
                return FALSE;
        }
        procmime_write_mimeinfo(sigmultipart, fp);
@@ -450,6 +459,7 @@ gboolean pgpmime_sign(MimeInfo *mimeinfo, PrefsAccount *account)
 
        if (!sgpgme_setup_signers(ctx, account)) {
                gpgme_release(ctx);
+               privacy_set_error(_("Couldn't find private key."));
                return FALSE;
        }
 
@@ -462,23 +472,42 @@ gboolean pgpmime_sign(MimeInfo *mimeinfo, PrefsAccount *account)
 
        err = gpgme_op_sign(ctx, gpgtext, gpgsig, GPGME_SIG_MODE_DETACH);
        if (err != GPG_ERR_NO_ERROR) {
+               privacy_set_error(_("Data signing failed, %s"), gpgme_strerror(err));
                debug_print("gpgme_op_sign error : %x\n", err);
                gpgme_release(ctx);
                return FALSE;
        }
        result = gpgme_op_sign_result(ctx);
        if (result && result->signatures) {
-           if (gpgme_get_protocol(ctx) == GPGME_PROTOCOL_OpenPGP) {
-               micalg = g_strdup_printf("PGP-%s", gpgme_hash_algo_name(
-                           result->signatures->hash_algo));
-           } else {
-               micalg = g_strdup(gpgme_hash_algo_name(
-                           result->signatures->hash_algo));
-           }
+               gpgme_new_signature_t sig = result->signatures;
+               if (gpgme_get_protocol(ctx) == GPGME_PROTOCOL_OpenPGP) {
+                       micalg = g_strdup_printf("PGP-%s", gpgme_hash_algo_name(
+                               result->signatures->hash_algo));
+               } else {
+                       micalg = g_strdup(gpgme_hash_algo_name(
+                               result->signatures->hash_algo));
+               }
+               while (sig) {
+                       debug_print("valid signature: %s\n", sig->fpr);
+                       sig = sig->next;
+               }
+       } else if (result && result->invalid_signers) {
+               gpgme_invalid_key_t invalid = result->invalid_signers;
+               while (invalid) {
+                       g_warning("invalid signer: %s (%s)", invalid->fpr, 
+                               gpgme_strerror(invalid->reason));
+                       privacy_set_error(_("Data signing failed due to invalid signer: %s"), 
+                               gpgme_strerror(invalid->reason));
+                       invalid = invalid->next;
+               }
+               gpgme_release(ctx);
+               return FALSE;
        } else {
-           /* can't get result (maybe no signing key?) */
-           debug_print("gpgme_op_sign_result error\n");
-           return FALSE;
+               /* can't get result (maybe no signing key?) */
+               debug_print("gpgme_op_sign_result error\n");
+               privacy_set_error(_("Data signing failed, no results."));
+               gpgme_release(ctx);
+               return FALSE;
        }
 
        gpgme_release(ctx);
@@ -488,6 +517,7 @@ gboolean pgpmime_sign(MimeInfo *mimeinfo, PrefsAccount *account)
 
        if (sigcontent == NULL || len <= 0) {
                g_warning("gpgme_data_release_and_get_mem failed");
+               privacy_set_error(_("Data signing failed, no contents."));
                return FALSE;
        }
 
@@ -530,6 +560,8 @@ gboolean pgpmime_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data)
        gpgme_key_t *kset = NULL;
        gchar **fprs = g_strsplit(encrypt_data, " ", -1);
        gint i = 0;
+       gpgme_error_t err;
+       
        while (fprs[i] && strlen(fprs[i])) {
                i++;
        }
@@ -540,11 +572,11 @@ gboolean pgpmime_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data)
        i = 0;
        while (fprs[i] && strlen(fprs[i])) {
                gpgme_key_t key;
-               gpgme_error_t err;
                err = gpgme_get_key(ctx, fprs[i], &key, 0);
                if (err) {
                        debug_print("can't add key '%s'[%d] (%s)\n", fprs[i],i, gpgme_strerror(err));
-                       break;
+                       privacy_set_error(_("Couldn't add GPG key %s, %s"), fprs[i], gpgme_strerror(err));
+                       return FALSE;
                }
                debug_print("found %s at %d\n", fprs[i], i);
                kset[i] = key;
@@ -571,7 +603,7 @@ gboolean pgpmime_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data)
        /* write message content to temporary file */
        fp = my_tmpfile();
        if (fp == NULL) {
-               perror("my_tmpfile");
+               privacy_set_error(_("Couldn't create temporary file, %s"), strerror(errno));
                return FALSE;
        }
        procmime_write_mimeinfo(encmultipart, fp);
@@ -588,7 +620,7 @@ gboolean pgpmime_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data)
        gpgme_set_armor(ctx, 1);
        gpgme_data_rewind(gpgtext);
        
-       gpgme_op_encrypt(ctx, kset, GPGME_ENCRYPT_ALWAYS_TRUST, gpgtext, gpgenc);
+       err = gpgme_op_encrypt(ctx, kset, GPGME_ENCRYPT_ALWAYS_TRUST, gpgtext, gpgenc);
 
        gpgme_release(ctx);
        enccontent = gpgme_data_release_and_get_mem(gpgenc, &len);
@@ -597,6 +629,7 @@ gboolean pgpmime_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data)
 
        if (enccontent == NULL || len <= 0) {
                g_warning("gpgme_data_release_and_get_mem failed");
+               privacy_set_error(_("Encryption failed, %s"), gpgme_strerror(err));
                return FALSE;
        }
 
index 684defc..4d8ed93 100644 (file)
 #include "procmime.h"
 
 static GSList *systems = NULL;
+static gchar *privacy_last_error = NULL;
+
+void privacy_set_error(const gchar *format, ...)
+{
+       va_list args;
+       gchar buf[BUFSIZ];
+
+       va_start(args, format);
+       g_vsnprintf(buf, BUFSIZ, format, args);
+       va_end(args);
+       g_free(privacy_last_error);
+       privacy_last_error = g_strdup(buf);
+}
+
+static gchar tmp_privacy_error[BUFSIZ];
+
+const gchar *privacy_get_error (void)
+{
+       if (privacy_last_error) {
+               strncpy2(tmp_privacy_error, privacy_last_error, BUFSIZ-1);
+               g_free(privacy_last_error);
+               privacy_last_error = NULL;
+               return tmp_privacy_error;
+       } else {
+               return _("Unknown error");
+       }
+}
 
 PrivacySystem *privacy_data_get_system(PrivacyData *data)
 {
@@ -365,7 +392,10 @@ gboolean privacy_encrypt(const gchar *id, MimeInfo *mimeinfo, const gchar *encda
 
        g_return_val_if_fail(id != NULL, FALSE);
        g_return_val_if_fail(mimeinfo != NULL, FALSE);
-       g_return_val_if_fail(encdata != NULL, FALSE);
+       if (encdata == NULL) {
+               privacy_set_error(_("No recipient keys defined."));
+               return FALSE;
+       }
 
        system = privacy_get_system(id);
        if (system == NULL)
index a4fea96..440401d 100644 (file)
@@ -65,6 +65,9 @@ gboolean privacy_encrypt                      (const gchar  *system,
                                                 MimeInfo     *mimeinfo,
                                                 const gchar  *encdata);
 
+void privacy_set_error                         (const gchar *format, ...);
+const gchar *privacy_get_error                 (void);
+
 struct _PrivacySystem {
        /** Identifier for the PrivacySystem that can use in config files */
        gchar            *id;
index f6fddff..3295949 100644 (file)
@@ -48,6 +48,7 @@
 #include "utils.h"
 #include "prefs_common.h"
 #include "prefs_gtk.h"
+#include "alertpanel.h"
 
 static GHashTable *procmime_get_mime_type_table        (void);
 
@@ -818,8 +819,11 @@ FILE *procmime_get_first_encrypted_text_content(MsgInfo *msginfo)
        partinfo = mimeinfo;
        if ((encinfo = find_encrypted_part(partinfo)) != NULL) {
                debug_print("decrypting message part\n");
-               if (privacy_mimeinfo_decrypt(encinfo) < 0)
+               if (privacy_mimeinfo_decrypt(encinfo) < 0) {
+                       alertpanel_error(_("Couldn't decrypt: %s"),
+                               privacy_get_error());
                        return NULL;
+               }
        }
        partinfo = mimeinfo;
        while (partinfo && partinfo->type != MIMETYPE_TEXT) {
index 2116e9a..f6c9cc6 100644 (file)
@@ -1525,7 +1525,8 @@ send_mail:
                        g_free(encrypt_data);
                        if (errstr) {
                                if (*errstr) g_free(*errstr);
-                               *errstr = g_strdup_printf(_("Couldn't encrypt the email."));
+                               *errstr = g_strdup_printf(_("Couldn't encrypt the email: %s"),
+                                               privacy_get_error());
                        }
                        return -1;
                }