2004-10-12 [paul] 0.9.12cvs124.1
authorPaul Mangan <paul@claws-mail.org>
Tue, 12 Oct 2004 09:45:18 +0000 (09:45 +0000)
committerPaul Mangan <paul@claws-mail.org>
Tue, 12 Oct 2004 09:45:18 +0000 (09:45 +0000)
* ChangeLog.claws
* configure.ac
* m4/spamassassin.m4
* src/Makefile.am
* src/account.c
* src/compose.c
* src/compose.h
* src/crash.c
* src/main.c
* src/mimeview.c
* src/passphrase.c
* src/passphrase.h
* src/prefs_account.c
* src/prefs_account.h
* src/prefs_common.c
* src/privacy.c
* src/privacy.h
* src/procmime.c
* src/procmime.h
* src/procmsg.c
* src/rfc2015.c
* src/rfc2015.h
* src/select-keys.c
* src/select-keys.h
* src/textview.c
* src/common/utils.c
* src/common/utils.h
* src/gtk/about.c
* src/plugins/pgpmime/Makefile.am
* src/plugins/pgpmime/passphrase.c
* src/plugins/pgpmime/passphrase.h
* src/plugins/pgpmime/pgpmime.c
* src/plugins/pgpmime/plugin.c
* src/plugins/pgpmime/select-keys.c
* src/plugins/pgpmime/select-keys.h
* src/plugins/pgpmime/sgpgme.c
* src/plugins/pgpmime/sgpgme.h
sync with HEAD

37 files changed:
ChangeLog-gtk2.claws
ChangeLog.claws
PATCHSETS
configure.ac
m4/spamassassin.m4
src/Makefile.am
src/account.c
src/common/utils.c
src/common/utils.h
src/compose.c
src/compose.h
src/crash.c
src/gtk/about.c
src/main.c
src/mimeview.c
src/passphrase.c [deleted file]
src/passphrase.h [deleted file]
src/plugins/pgpmime/Makefile.am
src/plugins/pgpmime/passphrase.c
src/plugins/pgpmime/pgpmime.c
src/plugins/pgpmime/plugin.c
src/plugins/pgpmime/select-keys.c
src/plugins/pgpmime/sgpgme.c
src/plugins/pgpmime/sgpgme.h
src/prefs_account.c
src/prefs_account.h
src/prefs_common.c
src/privacy.c
src/privacy.h
src/procmime.c
src/procmime.h
src/procmsg.c
src/rfc2015.c [deleted file]
src/rfc2015.h [deleted file]
src/select-keys.c [deleted file]
src/select-keys.h [deleted file]
src/textview.c

index 130e6f86d6fb6b822b69a5e8d14c2003d34207a1..3e4d8a84c7fde307911fcb7486f0e953bce72707 100644 (file)
@@ -1,3 +1,44 @@
+2004-10-12 [paul]      0.9.12cvs124.1
+
+       * ChangeLog.claws
+       * configure.ac
+       * m4/spamassassin.m4
+       * src/Makefile.am
+       * src/account.c
+       * src/compose.c
+       * src/compose.h
+       * src/crash.c
+       * src/main.c
+       * src/mimeview.c
+       * src/passphrase.c
+       * src/passphrase.h
+       * src/prefs_account.c
+       * src/prefs_account.h
+       * src/prefs_common.c
+       * src/privacy.c
+       * src/privacy.h
+       * src/procmime.c
+       * src/procmime.h
+       * src/procmsg.c
+       * src/rfc2015.c
+       * src/rfc2015.h
+       * src/select-keys.c
+       * src/select-keys.h
+       * src/textview.c
+       * src/common/utils.c
+       * src/common/utils.h
+       * src/gtk/about.c
+       * src/plugins/pgpmime/Makefile.am
+       * src/plugins/pgpmime/passphrase.c
+       * src/plugins/pgpmime/passphrase.h
+       * src/plugins/pgpmime/pgpmime.c
+       * src/plugins/pgpmime/plugin.c
+       * src/plugins/pgpmime/select-keys.c
+       * src/plugins/pgpmime/select-keys.h
+       * src/plugins/pgpmime/sgpgme.c
+       * src/plugins/pgpmime/sgpgme.h
+               sync with HEAD
+
 2004-10-04 [colin]     0.9.12cvs122.1
 
        * src/mainwindow.c
index 63d3b6b04b59a4d2eebaa23322013666a3e98171..a1f94997914e4f54f4cf38d9f2417d98b34d009c 100644 (file)
@@ -1,3 +1,83 @@
+2004-10-08 [christoph] 0.9.12cvs124
+
+       * m4/spamassassin.m4
+               fix libspamc OpenSSL
+
+       * src/compose.c
+               rearrange the compose menu
+
+2004-10-08 [christoph] 0.9.12cvs123
+
+       * src/Makefile.am
+       * src/account.c
+       * src/compose.[ch]
+       * src/crash.c
+       * src/main.c
+       * src/mimeview.c
+       * src/passphrase.[ch]                           ** REMOVE **
+       * src/prefs_account.[ch]
+       * src/prefs_common.[ch]
+       * src/privacy.[ch]
+       * src/procmime.[ch]
+       * src/procmsg.c
+       * src/rfc2015.[ch]                              ** REMOVE **
+       * src/select-keys.[ch]                          ** REMOVE **
+       * src/common/utils.[ch]
+       * src/gtk/about.c
+       * src/plugins/pgpmime/Makefile.am
+       * src/plugins/pgpmime/passphrase.[ch]           ** NEW **
+       * src/plugins/pgpmime/pgpmime.c
+       * src/plugins/pgpmime/plugin.c
+       * src/plugins/pgpmime/prefs_gpg.[ch]
+       * src/plugins/pgpmime/select-keys.[ch]          ** NEW **
+       * src/plugins/pgpmime/sgpgme.[ch]
+               o Add new MIME-Writer
+               o extend PrivacySystem with sign and encrypt functions
+               o extend PGP/MIME plugin with sign and encrypt functions
+               o integrate extended Privacy API in Compose and Sending process
+
+2004-10-04 [colin]     0.9.12cvs122
+
+       * src/mainwindow.c
+       * src/messageview.c
+       * src/messageview.h
+       * src/textview.c
+               Make forced encoding limited to messageview and
+               apply only to parts displayed using textview
+
+2004-10-04 [colin]     0.9.12cvs121
+
+       * src/summaryview.c
+               Fix bug #605 (collapsed threads re-expand when moving or
+               deleting mails)
+
+2004-10-03 [colin]     0.9.12cvs120
+
+       * src/summaryview.c
+               Fix bug #602
+
+2004-10-02 [colin]     0.9.12cvs119
+
+       * src/mainwindow.c
+       * src/messageview.c
+       * src/prefs_common.h
+       * src/procmime.c
+       * src/procmime.h
+       * src/textview.c
+               Clean up forced charset feature
+               Add forced decode
+
+2004-10-01 [colin]     0.9.12cvs118
+
+       * src/mimeview.c
+               Better fix for Save all: skip multipart mails' first 
+               text part
+
+2004-10-01 [colin]     0.9.12cvs117
+
+       * src/mimeview.c
+               Only save attachments in Save All
+
 2004-10-01 [paul]      0.9.12cvs116
 
        * ChangeLog
index 6dacc5270afc0acdfcbe77456e0824bca82950db..319e19101b244e174f4a314ca5ac7baa59043536 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.654.2.225 -r 1.654.2.226 configure.ac; ) > 0.9.12cvs120.1.patchset
 ( cvs diff -u -r 1.395.2.34 -r 1.395.2.35 src/summaryview.c; ) > 0.9.12cvs121.1.patchset
 ( cvs diff -u -r 1.274.2.21 -r 1.274.2.22 src/mainwindow.c; cvs diff -u -r 1.94.2.31 -r 1.94.2.32 src/messageview.c; cvs diff -u -r 1.19.2.3 -r 1.19.2.4 src/messageview.h; cvs diff -u -r 1.96.2.19 -r 1.96.2.20 src/textview.c; ) > 0.9.12cvs122.1.patchset
+( cvs diff -u -r 1.2504.2.23 -r 1.2504.2.24 ChangeLog.claws; cvs diff -u -r 1.654.2.228 -r 1.654.2.229 configure.ac; cvs diff -u -r 1.1.4.1 -r 1.1.4.2 m4/spamassassin.m4; cvs diff -u -r 1.155.2.12 -r 1.155.2.13 src/Makefile.am; cvs diff -u -r 1.61.2.12 -r 1.61.2.13 src/account.c; cvs diff -u -r 1.382.2.48 -r 1.382.2.49 src/compose.c; cvs diff -u -r 1.50.2.5 -r 1.50.2.6 src/compose.h; cvs diff -u -r 1.23.2.5 -r 1.23.2.6 src/crash.c; cvs diff -u -r 1.115.2.19 -r 1.115.2.20 src/main.c; cvs diff -u -r 1.83.2.21 -r 1.83.2.22 src/mimeview.c; cvs diff -u -r -1.12.2.4 -r -1.12.2.5 src/passphrase.c; cvs diff -u -r -1.5 -r -1.6 src/passphrase.h; cvs diff -u -r 1.105.2.8 -r 1.105.2.9 src/prefs_account.c; cvs diff -u -r 1.49.2.4 -r 1.49.2.5 src/prefs_account.h; cvs diff -u -r 1.204.2.21 -r 1.204.2.22 src/prefs_common.c; cvs diff -u -r 1.10.2.1 -r 1.10.2.2 src/privacy.c; cvs diff -u -r 1.10.2.1 -r 1.10.2.2 src/privacy.h; cvs diff -u -r 1.49.2.9 -r 1.49.2.10 src/procmime.c; cvs diff -u -r 1.17.2.4 -r 1.17.2.5 src/procmime.h; cvs diff -u -r 1.150.2.9 -r 1.150.2.10 src/procmsg.c; cvs diff -u -r -1.30.2.2 -r -1.30.2.3 src/rfc2015.c; cvs diff -u -r -1.7.2.2 -r -1.7.2.3 src/rfc2015.h; cvs diff -u -r -1.7.2.2 -r -1.7.2.3 src/select-keys.c; cvs diff -u -r -1.1.1.1 -r -1.1.1.2 src/select-keys.h; cvs diff -u -r 1.96.2.20 -r 1.96.2.21 src/textview.c; cvs diff -u -r 1.36.2.7 -r 1.36.2.8 src/common/utils.c; cvs diff -u -r 1.20.2.6 -r 1.20.2.7 src/common/utils.h; cvs diff -u -r 1.4.2.3 -r 1.4.2.4 src/gtk/about.c; cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/plugins/pgpmime/Makefile.am; cvs diff -u -r 0 -r 1 src/plugins/pgpmime/passphrase.c; cvs diff -u -r 0 -r 1 src/plugins/pgpmime/passphrase.h; cvs diff -u -r 1.1.2.4 -r 1.1.2.5 src/plugins/pgpmime/pgpmime.c; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 src/plugins/pgpmime/plugin.c; cvs diff -u -r 0 -r 1 src/plugins/pgpmime/select-keys.c; cvs diff -u -r 0 -r 1 src/plugins/pgpmime/select-keys.h; cvs diff -u -r 1.1.2.2 -r 1.1.2.3 src/plugins/pgpmime/sgpgme.c; cvs diff -u -r 1.1.2.2 -r 1.1.2.3 src/plugins/pgpmime/sgpgme.h; ) > 0.9.12cvs124.1.patchset
index 2286ac2012902e52c376f1041e10b7f45409cf80..fc58517212d84a684e76ef0ad19e5a09d59f7a94 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=9
 MICRO_VERSION=12
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=122
+EXTRA_VERSION=124
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=.1
 
index fd5bcc16c4de608d469872e13c20f6efbc0cc477..002bd860da092d83642160c81f51e610c3e2c8b8 100644 (file)
@@ -82,8 +82,8 @@ if test $haveexmax = yes ; then
   AC_DEFINE(HAVE_EX__MAX, 1, HAVE_EX__MAX)
 fi
 
-if test "$USE_OPENSSL" -ne 0; then
+if test x$ac_cv_enable_openssl = xyes; then
     AC_DEFINE(SPAMC_SSL, 1, Compile libspamc with OpenSSL support)
 fi
 
-])
\ No newline at end of file
+])
index c2246f88a09c70e4149c1570ac6c53afee4d549a..114b9a387a677df6e35018e1ee57d0c6b1a925a1 100644 (file)
@@ -78,7 +78,6 @@ sylpheed_SOURCES = \
        news.c \
        news_gtk.c \
        noticeview.c \
-       passphrase.c \
        pine.c \
        pop.c \
        prefs_account.c \
@@ -109,8 +108,6 @@ sylpheed_SOURCES = \
        quote_fmt_parse.y \
        recv.c \
        remotefolder.c \
-       rfc2015.c \
-       select-keys.c \
        send_message.c \
        setup.c \
        simple-gettext.c \
@@ -208,7 +205,6 @@ sylpheedinclude_HEADERS = \
        news.h \
        news_gtk.h \
        noticeview.h \
-       passphrase.h \
        pine.h \
        pop.h \
        prefs_account.h \
@@ -239,8 +235,6 @@ sylpheedinclude_HEADERS = \
        quote_fmt_parse.h \
        recv.h \
        remotefolder.h \
-       rfc2015.h \
-       select-keys.h \
        send_message.h \
        setup.h \
        sourcewindow.h \
index 97769b894cec38512b709cc8bfe1251c5632a5fa..60092ae2c2acbd2cc3d9a366e594fc56889b42bc 100644 (file)
@@ -307,8 +307,8 @@ void account_edit_open(void)
 
        if (compose_get_compose_list()) {
                alertpanel_error(_("Some composing windows are open.\n"
-                                   "Please close all the composing "
-                                   "windows before editing the accounts."));
+                                  "Please close all the composing "
+                                  "windows before editing the accounts."));
                inc_unlock();
                return;
        }
@@ -847,14 +847,9 @@ static void account_clone(void)
         ACP_FASSIGN(set_autoreplyto);
         ACP_FDUP(auto_replyto);
 
-#if USE_GPGME
         /* privacy */
         ACP_FASSIGN(default_encrypt);
         ACP_FASSIGN(default_sign);
-        ACP_FASSIGN(default_gnupg_mode);
-        ACP_FASSIGN(sign_key);
-        ACP_FDUP(sign_key_id);
-#endif /* USE_GPGME */
        
         /* advanced */
         ACP_FASSIGN(set_smtpport);
index 8ca8fa06e62b6ae3f26fae4a70c96ba44225031c..b8151a21cc523217a67a52ed8a34b255874451d8 100644 (file)
@@ -576,7 +576,7 @@ gint subject_compare_for_sort(const gchar *s1, const gchar *s2)
 
 void trim_subject_for_compare(gchar *str)
 {
-       guchar *srcp;
+       gchar *srcp;
 
        eliminate_parenthesis(str, '[', ']');
        eliminate_parenthesis(str, '(', ')');
@@ -589,7 +589,7 @@ void trim_subject_for_compare(gchar *str)
 
 void trim_subject_for_sort(gchar *str)
 {
-       guchar *srcp;
+       gchar *srcp;
 
        g_strstrip(str);
 
@@ -2485,29 +2485,17 @@ gint move_file(const gchar *src, const gchar *dest, gboolean overwrite)
        return 0;
 }
 
-gint copy_file_part(FILE *fp, off_t offset, size_t length, const gchar *dest)
+gint copy_file_part_to_fp(FILE *fp, off_t offset, size_t length, FILE *dest_fp)
 {
-       FILE *dest_fp;
        gint n_read;
        gint bytes_left, to_read;
        gchar buf[BUFSIZ];
-       gboolean err = FALSE;
 
        if (fseek(fp, offset, SEEK_SET) < 0) {
                perror("fseek");
                return -1;
        }
 
-       if ((dest_fp = fopen(dest, "wb")) == NULL) {
-               FILE_OP_ERROR(dest, "fopen");
-               return -1;
-       }
-
-       if (change_file_mode_rw(dest_fp, dest) < 0) {
-               FILE_OP_ERROR(dest, "chmod");
-               g_warning("can't change file mode\n");
-       }
-
        bytes_left = length;
        to_read = MIN(bytes_left, sizeof(buf));
 
@@ -2515,9 +2503,6 @@ gint copy_file_part(FILE *fp, off_t offset, size_t length, const gchar *dest)
                if (n_read < to_read && ferror(fp))
                        break;
                if (fwrite(buf, n_read, 1, dest_fp) < 1) {
-                       g_warning("writing to %s failed.\n", dest);
-                       fclose(dest_fp);
-                       unlink(dest);
                        return -1;
                }
                bytes_left -= n_read;
@@ -2528,19 +2513,40 @@ gint copy_file_part(FILE *fp, off_t offset, size_t length, const gchar *dest)
 
        if (ferror(fp)) {
                perror("fread");
-               err = TRUE;
+               return -1;
        }
-       if (fclose(dest_fp) == EOF) {
+
+       return 0;
+}
+
+gint copy_file_part(FILE *fp, off_t offset, size_t length, const gchar *dest)
+{
+       FILE *dest_fp;
+       gboolean err = FALSE;
+
+       if ((dest_fp = fopen(dest, "wb")) == NULL) {
+               FILE_OP_ERROR(dest, "fopen");
+               return -1;
+       }
+
+       if (change_file_mode_rw(dest_fp, dest) < 0) {
+               FILE_OP_ERROR(dest, "chmod");
+               g_warning("can't change file mode\n");
+       }
+
+       if (copy_file_part_to_fp(fp, offset, length, dest_fp) < 0)
+               err = TRUE;
+
+       if (!err && fclose(dest_fp) == EOF) {
                FILE_OP_ERROR(dest, "fclose");
                err = TRUE;
        }
 
        if (err) {
+               g_warning("writing to %s failed.\n", dest);
                unlink(dest);
                return -1;
        }
-
-       return 0;
 }
 
 /* convert line endings into CRLF. If the last line doesn't end with
index 8df78bdef4ff916e678335e10156a231dff653af..0adb6e5f0838adafd6d6f48ae6d3108f19a21a78 100644 (file)
@@ -380,6 +380,10 @@ gint copy_file                     (const gchar    *src,
 gint move_file                 (const gchar    *src,
                                 const gchar    *dest,
                                 gboolean        overwrite);
+gint copy_file_part_to_fp      (FILE           *fp,
+                                off_t           offset,
+                                size_t          length,
+                                FILE           *dest_fp);
 gint copy_file_part            (FILE           *fp,
                                 off_t           offset,
                                 size_t          length,
index f3c620fdc8d6d474c136428e50baf88db5a2128e..c55dddec7eb262f260f7d05e602dd6c6b1663b35 100644 (file)
 #include "foldersel.h"
 #include "toolbar.h"
 
-#if USE_GPGME
-#  include "rfc2015.h"
-#endif
-
 typedef enum
 {
        COL_MIMETYPE = 0,
@@ -233,8 +229,7 @@ static gboolean compose_check_for_valid_recipient
 static gboolean compose_check_entries          (Compose        *compose,
                                                 gboolean       check_subject);
 static gint compose_write_to_file              (Compose        *compose,
-                                                const gchar    *file,
-                                                gboolean        is_draft);
+                                                FILE           *fp);
 static gint compose_write_body_to_file         (Compose        *compose,
                                                 const gchar    *file);
 static gint compose_remove_reedit_target       (Compose        *compose);
@@ -246,12 +241,9 @@ static gint compose_queue_sub                      (Compose        *compose,
                                                 gint           *msgnum,
                                                 FolderItem     **item,
                                                 gboolean       check_subject);
-static void compose_write_attach               (Compose        *compose,
-                                                FILE           *fp);
-static gchar *compose_get_header               (Compose        *compose,
-                                                const gchar    *charset,
-                                                EncodingType    encoding,
-                                                gboolean        is_draft);
+static void compose_add_attachments            (Compose        *compose,
+                                                MimeInfo       *parent);
+static gchar *compose_get_header               (Compose        *compose);
 
 static void compose_convert_header             (gchar          *dest,
                                                 gint            len,
@@ -408,22 +400,20 @@ static void compose_toggle_attach_cb      (gpointer        data,
 static void compose_toggle_ruler_cb    (gpointer        data,
                                         guint           action,
                                         GtkWidget      *widget);
-#if USE_GPGME
 static void compose_toggle_sign_cb     (gpointer        data,
                                         guint           action,
                                         GtkWidget      *widget);
 static void compose_toggle_encrypt_cb  (gpointer        data,
                                         guint           action,
                                         GtkWidget      *widget);
-static void compose_set_gnupg_mode_cb  (gpointer        data,
-                                        guint           action,
-                                        GtkWidget      *widget);
-static void compose_update_gnupg_mode_menu_item(Compose * compose);
-static void activate_gnupg_mode        (Compose *compose, 
-                                        PrefsAccount *account);
+static void compose_set_privacy_system_cb(gpointer        data,
+                                        guint           action,
+                                        GtkWidget      *widget);
+static void compose_update_privacy_system_menu_item(Compose * compose);
+static void activate_privacy_system     (Compose *compose, 
+                                         PrefsAccount *account);
 static void compose_use_signing(Compose *compose, gboolean use_signing);
 static void compose_use_encryption(Compose *compose, gboolean use_encryption);
-#endif
 static void compose_toggle_return_receipt_cb(gpointer data, guint action,
                                             GtkWidget *widget);
 static void compose_toggle_remove_refs_cb(gpointer data, guint action,
@@ -510,15 +500,20 @@ static GtkItemFactoryEntry compose_popup_entries[] =
 
 static GtkItemFactoryEntry compose_entries[] =
 {
-       {N_("/_File"),                          NULL, NULL, 0, "<Branch>"},
-       {N_("/_File/_Save"),
+       {N_("/_Message"),                               NULL, NULL, 0, "<Branch>"},
+       {N_("/_Message/_Send"),         "<control>Return",
+                                       compose_send_cb, 0, NULL},
+       {N_("/_Message/Send _later"),   "<shift><control>S",
+                                       compose_send_later_cb,  0, NULL},
+       {N_("/_Message/---"),                   NULL, NULL, 0, "<Separator>"},
+       {N_("/_Message/_Attach file"),          "<control>M", compose_attach_cb,      0, NULL},
+       {N_("/_Message/_Insert file"),          "<control>I", compose_insert_file_cb, 0, NULL},
+       {N_("/_Message/Insert si_gnature"),     "<control>G", compose_insert_sig_cb,  0, NULL},
+       {N_("/_Message/---"),                   NULL, NULL, 0, "<Separator>"},
+       {N_("/_Message/_Save"),
                                                "<control>S", compose_draft_cb, 1, NULL},
-       {N_("/_File/---"),                      NULL, NULL, 0, "<Separator>"},
-       {N_("/_File/_Attach file"),             "<control>M", compose_attach_cb,      0, NULL},
-       {N_("/_File/_Insert file"),             "<control>I", compose_insert_file_cb, 0, NULL},
-       {N_("/_File/Insert si_gnature"),        "<control>G", compose_insert_sig_cb,  0, NULL},
-       {N_("/_File/---"),                      NULL, NULL, 0, "<Separator>"},
-       {N_("/_File/_Close"),                   "<control>W", compose_close_cb, 0, NULL},
+       {N_("/_Message/---"),                   NULL, NULL, 0, "<Separator>"},
+       {N_("/_Message/_Close"),                        "<control>W", compose_close_cb, 0, NULL},
 
        {N_("/_Edit"),                  NULL, NULL, 0, "<Branch>"},
        {N_("/_Edit/_Undo"),            "<control>Z", compose_undo_cb, 0, NULL},
@@ -629,53 +624,22 @@ static GtkItemFactoryEntry compose_entries[] =
        {N_("/_Spelling/_Spelling Configuration"),
                                        NULL, NULL, 0, "<Branch>"},
 #endif
-#if 0 /* NEW COMPOSE GUI */
-       {N_("/_View"),                  NULL, NULL, 0, "<Branch>"},
-       {N_("/_View/_To"),              NULL, compose_toggle_to_cb     , 0, "<ToggleItem>"},
-       {N_("/_View/_Cc"),              NULL, compose_toggle_cc_cb     , 0, "<ToggleItem>"},
-       {N_("/_View/_Bcc"),             NULL, compose_toggle_bcc_cb    , 0, "<ToggleItem>"},
-       {N_("/_View/_Reply to"),        NULL, compose_toggle_replyto_cb, 0, "<ToggleItem>"},
-       {N_("/_View/---"),              NULL, NULL, 0, "<Separator>"},
-       {N_("/_View/_Followup to"),     NULL, compose_toggle_followupto_cb, 0, "<ToggleItem>"},
-       {N_("/_View/---"),              NULL, NULL, 0, "<Separator>"},
-       {N_("/_View/R_uler"),           NULL, compose_toggle_ruler_cb, 0, "<ToggleItem>"},
-       {N_("/_View/---"),              NULL, NULL, 0, "<Separator>"},
-       {N_("/_View/_Attachment"),      NULL, compose_toggle_attach_cb, 0, "<ToggleItem>"},
-#endif
-       {N_("/_Message"),               NULL, NULL, 0, "<Branch>"},
-       {N_("/_Message/_Send"),         "<control>Return",
-                                       compose_send_cb, 0, NULL},
-       {N_("/_Message/Send _later"),   "<shift><control>S",
-                                       compose_send_later_cb,  0, NULL},
-#if 0 /* NEW COMPOSE GUI */
-       {N_("/_Message/---"),           NULL, NULL, 0, "<Separator>"},
-       {N_("/_Message/_To"),           NULL, compose_toggle_to_cb     , 0, "<ToggleItem>"},
-       {N_("/_Message/_Cc"),           NULL, compose_toggle_cc_cb     , 0, "<ToggleItem>"},
-       {N_("/_Message/_Bcc"),          NULL, compose_toggle_bcc_cb    , 0, "<ToggleItem>"},
-       {N_("/_Message/_Reply to"),     NULL, compose_toggle_replyto_cb, 0, "<ToggleItem>"},
-       {N_("/_Message/---"),           NULL, NULL, 0, "<Separator>"},
-       {N_("/_Message/_Followup to"),  NULL, compose_toggle_followupto_cb, 0, "<ToggleItem>"},
-       {N_("/_Message/---"),           NULL, NULL, 0, "<Separator>"},
-       {N_("/_Message/_Attach"),       NULL, compose_toggle_attach_cb, 0, "<ToggleItem>"},
-#endif
-#if USE_GPGME
-       {N_("/_Message/---"),           NULL, NULL, 0, "<Separator>"},
-       {N_("/_Message/Si_gn"),         NULL, compose_toggle_sign_cb   , 0, "<ToggleItem>"},
-       {N_("/_Message/_Encrypt"),      NULL, compose_toggle_encrypt_cb, 0, "<ToggleItem>"},
-       {N_("/_Message/Mode"),          NULL, NULL,   0, "<Branch>"},
-       {N_("/_Message/Mode/MIME"),     NULL, compose_set_gnupg_mode_cb,   GNUPG_MODE_DETACH, "<RadioItem>"},   
-       {N_("/_Message/Mode/Inline"),   NULL, compose_set_gnupg_mode_cb,   GNUPG_MODE_INLINE, "/Message/Mode/MIME"},    
-#endif /* USE_GPGME */
-       {N_("/_Message/---"),           NULL,           NULL,   0, "<Separator>"},
-       {N_("/_Message/_Priority"),     NULL,           NULL,   0, "<Branch>"},
-       {N_("/_Message/Priority/_Highest"), NULL, compose_set_priority_cb, PRIORITY_HIGHEST, "<RadioItem>"},
-       {N_("/_Message/Priority/Hi_gh"),    NULL, compose_set_priority_cb, PRIORITY_HIGH, "/Message/Priority/Highest"},
-       {N_("/_Message/Priority/_Normal"),  NULL, compose_set_priority_cb, PRIORITY_NORMAL, "/Message/Priority/Highest"},
-       {N_("/_Message/Priority/Lo_w"),    NULL, compose_set_priority_cb, PRIORITY_LOW, "/Message/Priority/Highest"},
-       {N_("/_Message/Priority/_Lowest"),  NULL, compose_set_priority_cb, PRIORITY_LOWEST, "/Message/Priority/Highest"},
-       {N_("/_Message/---"),           NULL,           NULL,   0, "<Separator>"},
-       {N_("/_Message/_Request Return Receipt"),       NULL, compose_toggle_return_receipt_cb, 0, "<ToggleItem>"},
-       {N_("/_Message/Remo_ve references"),    NULL, compose_toggle_remove_refs_cb, 0, "<ToggleItem>"},
+       {N_("/_Options"),               NULL, NULL, 0, "<Branch>"},
+       {N_("/_Options/---"),           NULL, NULL, 0, "<Separator>"},
+       {N_("/_Options/Privacy System"),                NULL, NULL,   0, "<Branch>"},
+       {N_("/_Options/Privacy System/None"),   NULL, compose_set_privacy_system_cb,   0, "<RadioItem>"},
+       {N_("/_Options/Si_gn"),         NULL, compose_toggle_sign_cb   , 0, "<ToggleItem>"},
+       {N_("/_Options/_Encrypt"),      NULL, compose_toggle_encrypt_cb, 0, "<ToggleItem>"},
+       {N_("/_Options/---"),           NULL,           NULL,   0, "<Separator>"},
+       {N_("/_Options/_Priority"),     NULL,           NULL,   0, "<Branch>"},
+       {N_("/_Options/Priority/_Highest"), NULL, compose_set_priority_cb, PRIORITY_HIGHEST, "<RadioItem>"},
+       {N_("/_Options/Priority/Hi_gh"),    NULL, compose_set_priority_cb, PRIORITY_HIGH, "/Options/Priority/Highest"},
+       {N_("/_Options/Priority/_Normal"),  NULL, compose_set_priority_cb, PRIORITY_NORMAL, "/Options/Priority/Highest"},
+       {N_("/_Options/Priority/Lo_w"),    NULL, compose_set_priority_cb, PRIORITY_LOW, "/Options/Priority/Highest"},
+       {N_("/_Options/Priority/_Lowest"),  NULL, compose_set_priority_cb, PRIORITY_LOWEST, "/Options/Priority/Highest"},
+       {N_("/_Options/---"),           NULL,           NULL,   0, "<Separator>"},
+       {N_("/_Options/_Request Return Receipt"),       NULL, compose_toggle_return_receipt_cb, 0, "<ToggleItem>"},
+       {N_("/_Options/Remo_ve references"),    NULL, compose_toggle_remove_refs_cb, 0, "<ToggleItem>"},
        {N_("/_Tools"),                 NULL, NULL, 0, "<Branch>"},
        {N_("/_Tools/Show _ruler"),     NULL, compose_toggle_ruler_cb, 0, "<ToggleItem>"},
        {N_("/_Tools/_Address book"),   "<shift><control>A", compose_address_cb , 0, NULL},
@@ -1225,11 +1189,9 @@ void compose_reedit(MsgInfo *msginfo)
        GtkTextIter iter;
        FILE *fp;
        gchar buf[BUFFSIZE];
-#ifdef USE_GPGME
        gboolean use_signing = FALSE;
        gboolean use_encryption = FALSE;
-       gboolean gnupg_mode = FALSE;
-#endif
+       gchar *privacy_system = NULL;
 
        g_return_if_fail(msginfo != NULL);
        g_return_if_fail(msginfo->folder != NULL);
@@ -1258,7 +1220,6 @@ void compose_reedit(MsgInfo *msginfo)
                                                                sizeof(queueheader_buf), "S:")) {
                        account = account_find_from_address(queueheader_buf);
                }
-#ifdef USE_GPGME               
                if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
                                             sizeof(queueheader_buf), "X-Sylpheed-Sign:")) {
                        param = atoi(&queueheader_buf[strlen("X-Sylpheed-Sign:")]);
@@ -1270,12 +1231,10 @@ void compose_reedit(MsgInfo *msginfo)
                        param = atoi(&queueheader_buf[strlen("X-Sylpheed-Encrypt:")]);
                        use_encryption = param;
                }
-               if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
-                                            sizeof(queueheader_buf), "X-Sylpheed-Gnupg-Mode:")) {
-                       param = atoi(&queueheader_buf[strlen("X-Sylpheed-Gnupg-Mode:")]);
-                       gnupg_mode = param;
-               }
-#endif         
+                if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
+                                            sizeof(queueheader_buf), "X-Sylpheed-Privacy-System:")) {
+                        privacy_system = g_strdup(&queueheader_buf[strlen("X-Sylpheed-Privacy-System:")]);
+                }
                if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, 
                                             sizeof(queueheader_buf), "X-Priority: ")) {
                        param = atoi(&queueheader_buf[strlen("X-Priority: ")]); /* mind the space */
@@ -1295,11 +1254,9 @@ void compose_reedit(MsgInfo *msginfo)
        g_return_if_fail(account != NULL);
 
        compose = compose_create(account, COMPOSE_REEDIT);
-#ifdef USE_GPGME
-       compose->gnupg_mode = gnupg_mode;
+       compose->privacy_system = privacy_system;
        compose_use_signing(compose, use_signing);
        compose_use_encryption(compose, use_encryption);
-#endif
        compose->targetinfo = procmsg_msginfo_copy(msginfo);
 
         if (msginfo->folder->stype == F_QUEUE
@@ -1407,19 +1364,15 @@ Compose *compose_redirect(PrefsAccount *account, MsgInfo *msginfo)
        menu_set_sensitive(ifactory, "/Property...", FALSE);
 
        ifactory = gtk_item_factory_from_widget(compose->menubar);
-       menu_set_sensitive(ifactory, "/File/Save", FALSE);
-       menu_set_sensitive(ifactory, "/File/Insert file", FALSE);
-       menu_set_sensitive(ifactory, "/File/Attach file", FALSE);
-       menu_set_sensitive(ifactory, "/File/Insert signature", FALSE);
+       menu_set_sensitive(ifactory, "/Message/Save", FALSE);
+       menu_set_sensitive(ifactory, "/Message/Insert file", FALSE);
+       menu_set_sensitive(ifactory, "/Message/Attach file", FALSE);
+       menu_set_sensitive(ifactory, "/Message/Insert signature", FALSE);
        menu_set_sensitive(ifactory, "/Edit", FALSE);
-#if USE_GPGME
-       menu_set_sensitive(ifactory, "/Message/Sign", FALSE);
-       menu_set_sensitive(ifactory, "/Message/Encrypt", FALSE);
-       menu_set_sensitive(ifactory, "/Message/Mode/MIME", FALSE);
-       menu_set_sensitive(ifactory, "/Message/Mode/Inline", FALSE);
-#endif
-       menu_set_sensitive(ifactory, "/Message/Priority", FALSE);
-       menu_set_sensitive(ifactory, "/Message/Request Return Receipt", FALSE);
+       menu_set_sensitive(ifactory, "/Options/Sign", FALSE);
+       menu_set_sensitive(ifactory, "/Options/Encrypt", FALSE);
+       menu_set_sensitive(ifactory, "/Options/Priority", FALSE);
+       menu_set_sensitive(ifactory, "/Options/Request Return Receipt", FALSE);
        menu_set_sensitive(ifactory, "/Tools/Show ruler", FALSE);
        menu_set_sensitive(ifactory, "/Tools/Actions", FALSE);
        
@@ -2029,11 +1982,8 @@ static void compose_reedit_set_entry(Compose *compose, MsgInfo *msginfo)
        SET_ADDRESS(COMPOSE_FOLLOWUPTO, compose->followup_to);
 
        compose_update_priority_menu_item(compose);
-#if USE_GPGME  
-       compose_update_gnupg_mode_menu_item(compose);
-#endif
+       compose_update_privacy_system_menu_item(compose);
        compose_show_first_last_header(compose, TRUE);
-
 }
 
 #undef SET_ENTRY
@@ -2294,7 +2244,6 @@ static void compose_attach_append(Compose *compose, const gchar *file,
        gtk_clist_set_row_data(GTK_CLIST(compose->attach_clist), row, ainfo);
 }
 
-#ifdef USE_GPGME
 static void compose_use_signing(Compose *compose, gboolean use_signing)
 {
        GtkItemFactory *ifactory;
@@ -2303,11 +2252,9 @@ static void compose_use_signing(Compose *compose, gboolean use_signing)
        compose->use_signing = use_signing;
        ifactory = gtk_item_factory_from_widget(compose->menubar);
        menuitem = gtk_item_factory_get_item
-               (ifactory, "/Message/Sign");
-
+               (ifactory, "/Options/Sign");
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), 
                                       use_signing);
-       compose_update_gnupg_mode_menu_item(compose);
 }
 
 static void compose_use_encryption(Compose *compose, gboolean use_encryption)
@@ -2318,13 +2265,11 @@ static void compose_use_encryption(Compose *compose, gboolean use_encryption)
        compose->use_encryption = use_encryption;
        ifactory = gtk_item_factory_from_widget(compose->menubar);
        menuitem = gtk_item_factory_get_item
-               (ifactory, "/Message/Encrypt");
+               (ifactory, "/Options/Encrypt");
 
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), 
                                       use_encryption);
-       compose_update_gnupg_mode_menu_item(compose);
 }
-#endif /* USE_GPGME */
 
 #define NEXT_PART_NOT_CHILD(info)  \
 {  \
@@ -2391,27 +2336,13 @@ static void compose_attach_parts(Compose *compose, MsgInfo *msginfo)
                        continue;
                }
 
-               if ((compose->mode == COMPOSE_REEDIT || 
-                    compose->mode == COMPOSE_FORWARD_INLINE ||
-                    compose->mode == COMPOSE_FORWARD )  &&
-                   (child->type == MIMETYPE_APPLICATION) && 
-                   !strcmp(child->subtype, "pgp-signature")) {
-#ifdef USE_GPGME
-                       if (compose->mode == COMPOSE_REEDIT) {
-                               compose->gnupg_mode  = GNUPG_MODE_DETACH;
-                               compose_use_signing(compose, TRUE);
-                       }
-#endif
-                       child = procmime_mimeinfo_next(child);
-                       continue;
-               }
                outfile = procmime_get_tmp_file_name(child);
                if (procmime_get_part(outfile, child) < 0)
                        g_warning("Can't get the part of multipart message.");
                else {
                        gchar *content_type;
 
-                       content_type = g_strdup_printf("%s/%s", procmime_get_type_str(child->type), child->subtype);
+                       content_type = procmime_get_content_type_str(child->type, child->subtype);
                        partname = procmime_mimeinfo_get_parameter(child, "name");
                        if (partname == NULL)
                                partname = "";
@@ -3223,18 +3154,16 @@ static void compose_select_account(Compose *compose, PrefsAccount *account,
 
 #endif
 
-#if USE_GPGME
        if (account->default_sign)
-               menu_set_active(ifactory, "/Message/Sign", TRUE);
+               menu_set_active(ifactory, "/Options/Sign", TRUE);
        else
-               menu_set_active(ifactory, "/Message/Sign", FALSE);
+               menu_set_active(ifactory, "/Options/Sign", FALSE);
        if (account->default_encrypt)
-               menu_set_active(ifactory, "/Message/Encrypt", TRUE);
+               menu_set_active(ifactory, "/Options/Encrypt", TRUE);
        else
-               menu_set_active(ifactory, "/Message/Encrypt", FALSE);
+               menu_set_active(ifactory, "/Options/Encrypt", FALSE);
                                       
-       activate_gnupg_mode(compose, account);          
-#endif /* USE_GPGME */
+       activate_privacy_system(compose, account);
 
        if (!init && compose->mode != COMPOSE_REDIRECT)
                compose_insert_sig(compose, TRUE);
@@ -3374,104 +3303,6 @@ bail:
        return -1;
 }
 
-#if 0 /* compose restructure */
-gint compose_send(Compose *compose)
-{
-       gchar tmp[MAXPATHLEN + 1];
-       gint ok = 0;
-       static gboolean lock = FALSE;
-
-       if (lock) return 1;
-
-       g_return_val_if_fail(compose->account != NULL, -1);
-
-       lock = TRUE;
-
-       if (compose_check_entries(compose, TRUE) == FALSE) {
-               lock = FALSE;
-               return 1;
-       }
-
-       /* write to temporary file */
-       g_snprintf(tmp, sizeof(tmp), "%s%ctmpmsg.%p",
-                  get_tmp_dir(), G_DIR_SEPARATOR, compose);
-
-       if (prefs_common.linewrap_at_send)
-               compose_wrap_line_all(compose);
-
-       if (compose_write_to_file(compose, tmp, FALSE) < 0) {
-               lock = FALSE;
-               return -1;
-       }
-
-       if (!compose->to_list && !compose->newsgroup_list) {
-               g_warning("can't get recipient list.");
-               unlink(tmp);
-               lock = FALSE;
-               return -1;
-       }
-
-       if (compose->to_list) {
-               PrefsAccount *ac;
-
-#if 0 /* NEW COMPOSE GUI */
-               if (compose->account->protocol != A_NNTP)
-                       ac = compose->account;
-               else {
-                       ac = account_find_from_address(compose->account->address);
-                       if (!ac) {
-                               if (cur_account && cur_account->protocol != A_NNTP)
-                                       ac = cur_account;
-                               else
-                                       ac = account_get_default();
-                       }
-                       if (!ac || ac->protocol == A_NNTP) {
-                               alertpanel_error(_("Account for sending mail is not specified.\n"
-                                                  "Please select a mail account before sending."));
-                               unlink(tmp);
-                               lock = FALSE;
-                               return -1;
-                       }
-               }
-#endif
-               ac = compose->account;
-
-               ok = send_message(tmp, ac, compose->to_list);
-       }
-
-       if (ok == 0 && compose->newsgroup_list) {
-               ok = news_post(FOLDER(compose->account->folder), tmp);
-               if (ok < 0) {
-                       alertpanel_error(_("Error occurred while posting the message to %s ."),
-                                        compose->account->nntp_server);
-                       unlink(tmp);
-                       lock = FALSE;
-                       return -1;
-               }
-       }
-
-       if (ok == 0) {
-               if (compose->mode == COMPOSE_REEDIT) {
-                       compose_remove_reedit_target(compose);
-               }
-               /* save message to outbox */
-               if (prefs_common.savemsg) {
-                       FolderItem *outbox;
-
-                       outbox = account_get_special_folder
-                               (compose->account, F_OUTBOX);
-                       if (procmsg_save_to_outbox(outbox, tmp, FALSE) < 0)
-                               alertpanel_error
-                                       (_("Can't save the message to Sent."));
-               }
-       }
-
-       unlink(tmp);
-       lock = FALSE;
-       return ok;
-}
-#endif
-
 static gboolean compose_use_attach(Compose *compose) 
 {
        return gtk_clist_get_row_data(GTK_CLIST(compose->attach_clist), 0) != NULL;
@@ -3591,31 +3422,17 @@ static gint compose_redirect_write_headers(Compose *compose, FILE *fp)
        return 0;
 }
 
-static gint compose_redirect_write_to_file(Compose *compose, const gchar *file)
+static gint compose_redirect_write_to_file(Compose *compose, FILE *fdest)
 {
        FILE *fp;
-       FILE *fdest;
        size_t len;
        gchar buf[BUFFSIZE];
-       gchar *header;
 
        if ((fp = fopen(compose->redirect_filename, "rb")) == NULL) {
-               FILE_OP_ERROR(file, "fopen");
-               return -1;
-       }
-
-       if ((fdest = fopen(file, "wb")) == NULL) {
-               FILE_OP_ERROR(file, "fopen");
-               fclose(fp);
+               FILE_OP_ERROR(compose->redirect_filename, "fopen");
                return -1;
        }
 
-       /* chmod for security */
-       if (change_file_mode_rw(fdest, file) < 0) {
-               FILE_OP_ERROR(file, "chmod");
-               g_warning("can't change file mode\n");
-       }
-
        while (procheader_get_one_field_asis(buf, sizeof(buf), fp) != -1) {
                /* should filter returnpath, delivered-to */
                if (g_strncasecmp(buf, "Return-Path:",
@@ -3661,119 +3478,37 @@ static gint compose_redirect_write_to_file(Compose *compose, const gchar *file)
        compose_redirect_write_headers(compose, fdest);
 
        while ((len = fread(buf, sizeof(gchar), sizeof(buf), fp)) > 0) {
-               if (fwrite(buf, sizeof(gchar), len, fdest) != len) {
-                       FILE_OP_ERROR(file, "fwrite");
+               if (fwrite(buf, sizeof(gchar), len, fdest) != len)
                        goto error;
-               }
        }
 
        fclose(fp);
-       if (fclose(fdest) == EOF) {
-               FILE_OP_ERROR(file, "fclose");
-               unlink(file);
-               return -1;
-       }
 
        return 0;
- error:
+error:
        fclose(fp);
-       fclose(fdest);
-       unlink(file);
 
        return -1;
 }
 
-
-#if USE_GPGME
-/* interfaces to rfc2015 to keep out the prefs stuff there.
- * returns 0 on success and -1 on error. */
-static gint compose_create_signers_list(Compose *compose, GSList **pkey_list)
-{
-       const gchar *key_id = NULL;
-       GSList *key_list;
-
-       switch (compose->account->sign_key) {
-       case SIGN_KEY_DEFAULT:
-               *pkey_list = NULL;
-               return 0;
-       case SIGN_KEY_BY_FROM:
-               key_id = compose->account->address;
-               break;
-       case SIGN_KEY_CUSTOM:
-               key_id = compose->account->sign_key_id;
-               break;
-       default:
-               break;
-       }
-
-       key_list = rfc2015_create_signers_list(key_id);
-
-       if (!key_list) {
-               alertpanel_error(_("Could not find any key associated with "
-                                  "currently selected key id `%s'."), key_id);
-               return -1;
-       }
-
-       *pkey_list = key_list;
-       return 0;
-}
-
-/* clearsign message body text */
-static gint compose_clearsign_text(Compose *compose, gchar **text)
-{
-       GSList *key_list;
-       gchar *tmp_file;
-
-       tmp_file = get_tmp_file();
-       if (str_write_to_file(*text, tmp_file) < 0) {
-               g_free(tmp_file);
-               return -1;
-       }
-
-       if (compose_create_signers_list(compose, &key_list) < 0 ||
-           rfc2015_clearsign(tmp_file, key_list) < 0) {
-               unlink(tmp_file);
-               g_free(tmp_file);
-               return -1;
-       }
-
-       g_free(*text);
-       *text = file_read_to_str(tmp_file);
-       unlink(tmp_file);
-       g_free(tmp_file);
-       if (*text == NULL)
-               return -1;
-
-       return 0;
-}
-#endif /* USE_GPGME */
-
-static gint compose_write_to_file(Compose *compose, const gchar *file,
-                                 gboolean is_draft)
+static gint compose_write_to_file(Compose *compose, FILE *fp)
 {
        GtkTextBuffer *buffer;
        GtkTextIter start, end;
-       FILE *fp;
-       size_t len;
        gchar *chars;
        gchar *buf;
-       gchar *canon_buf;
        const gchar *out_codeset;
        EncodingType encoding;
-       gboolean already_encoded = FALSE;
-       gchar *header;
+       MimeInfo *mimemsg, *mimetext;
 
-       if ((fp = fopen(file, "wb")) == NULL) {
-               FILE_OP_ERROR(file, "fopen");
-               return -1;
-       }
-
-       /* chmod for security */
-       if (change_file_mode_rw(fp, file) < 0) {
-               FILE_OP_ERROR(file, "chmod");
-               g_warning("can't change file mode\n");
-       }
+       /* create message MimeInfo */
+       mimemsg = procmime_mimeinfo_new();
+        mimemsg->type = MIMETYPE_MESSAGE;
+        mimemsg->subtype = g_strdup("rfc822");
+       mimemsg->content = MIMECONTENT_MEM;
+       mimemsg->data = compose_get_header(compose);
 
+       /* Create text part MimeInfo */
        /* get all composed text */
        buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(compose->text));
        gtk_text_buffer_get_start_iter(buffer, &start);
@@ -3800,39 +3535,29 @@ static gint compose_write_to_file(Compose *compose, const gchar *file,
                else
                        encoding = procmime_get_encoding_for_charset(out_codeset);
 
-#if USE_GPGME
-               if (!is_draft &&
-                   compose->use_signing && !compose->gnupg_mode &&
-                   encoding == ENC_8BIT)
-                       encoding = ENC_BASE64;
-               
-               if (compose->use_encryption && compose->gnupg_mode)
-                       encoding = ENC_8BIT; /* this will be encrypted to a 7bit string */
-#endif
-
-               src_codeset = CS_UTF_8;
+               src_codeset = conv_get_current_charset_str();
+               /* if current encoding is US-ASCII, set it the same as
+                  outgoing one to prevent code conversion failure */
+               if (!strcasecmp(src_codeset, CS_US_ASCII))
+                       src_codeset = out_codeset;
 
                debug_print("src encoding = %s, out encoding = %s, transfer encoding = %s\n",
                            src_codeset, out_codeset, procmime_get_encoding_str(encoding));
 
                buf = conv_codeset_strdup(chars, src_codeset, out_codeset);
                if (!buf) {
-                       AlertValue aval = G_ALERTDEFAULT;
+                       AlertValue aval;
                        gchar *msg;
 
-                       if (!is_draft) {
-                               msg = g_strdup_printf(_("Can't convert the character encoding of the message from\n"
+                       msg = g_strdup_printf(_("Can't convert the character encoding of the message from\n"
                                                "%s to %s.\n"
                                                "Send it anyway?"), src_codeset, out_codeset);
-                               aval = alertpanel_with_type
-                                       (_("Error"), msg, _("Yes"), _("+No"), NULL, NULL, ALERT_ERROR);
-                               g_free(msg);
-                       }
-                       
+                       aval = alertpanel_with_type
+                               (_("Error"), msg, _("Yes"), _("+No"), NULL, NULL, ALERT_ERROR);
+                       g_free(msg);
+
                        if (aval != G_ALERTDEFAULT) {
                                g_free(chars);
-                               fclose(fp);
-                               unlink(file);
                                return -1;
                        } else {
                                buf = chars;
@@ -3843,146 +3568,41 @@ static gint compose_write_to_file(Compose *compose, const gchar *file,
        }
        g_free(chars);
 
-       canon_buf = canonicalize_str(buf);
-       g_free(buf);
-       buf = canon_buf;
-
-#if USE_GPGME
-       if (!is_draft && compose->use_signing && compose->gnupg_mode) {
-               gchar *tmpbuf;
-
-               if (compose_clearsign_text(compose, &buf) < 0) {
-                       g_warning("clearsign failed\n");
-                       fclose(fp);
-                       unlink(file);
-                       g_free(buf);
-                       return -1;
-               }
-               tmpbuf = conv_codeset_strdup(buf, CS_UTF_8, out_codeset);
-               if (tmpbuf) {
-                       g_free(buf);
-                       buf = tmpbuf;
-               }
-       }
-#endif
-
-       /* write headers */
-       header = compose_get_header(compose, out_codeset, encoding, is_draft);
-       if (header == NULL || fwrite(header, sizeof(gchar), strlen(header), fp) < strlen(header)) {
-               g_warning("can't write headers\n");
-               fclose(fp);
-               /* unlink(file); */
-               g_free(header);
-               g_free(buf);
-               return -1;
-       }
-       g_free(header);
+       mimetext = procmime_mimeinfo_new();
+       mimetext->content = MIMECONTENT_MEM;
+       mimetext->data = buf;
+       mimetext->type = MIMETYPE_TEXT;
+       mimetext->subtype = g_strdup("plain");
+       g_hash_table_insert(mimetext->typeparameters, g_strdup("charset"),
+                           g_strdup(out_codeset));
+       /* procmime_encode_content(mimetext, encoding); */
 
+       /* append attachment parts */
        if (compose_use_attach(compose)) {
-#if USE_GPGME
-            /* This prolog message is ignored by mime software and
-             * because it would make our signing/encryption task
-             * tougher, we don't emit it in that case */
-            if (!compose->use_signing && !compose->use_encryption)
-#endif
-               fputs("This is a multi-part message in MIME format.\n", fp);
-
-               fprintf(fp, "\n--%s\n", compose->boundary);
-               fprintf(fp, "Content-Type: text/plain; charset=%s\n",
-                       out_codeset);
-#if USE_GPGME
-               if (compose->use_signing && !compose->gnupg_mode)
-                       fprintf(fp, "Content-Disposition: inline\n");
-#endif
-               fprintf(fp, "Content-Transfer-Encoding: %s\n",
-                       procmime_get_encoding_str(encoding));
-               fputc('\n', fp);
-       }
+               MimeInfo *mimempart;
 
-       /* write body */
-       len = strlen(buf);
-       if (encoding == ENC_BASE64) {
-               gchar outbuf[B64_BUFFSIZE];
-               gint i, l;
-
-               for (i = 0; i < len; i += B64_LINE_SIZE) {
-                       l = MIN(B64_LINE_SIZE, len - i);
-                       base64_encode(outbuf, buf + i, l);
-                       fputs(outbuf, fp);
-                       fputc('\n', fp);
-               }
-       } else if (encoding == ENC_QUOTED_PRINTABLE) {
-               gchar *outbuf;
-               size_t outlen;
-               if (!already_encoded) {
-                       outbuf = g_malloc(len * 4);
-                       qp_encode_line(outbuf, buf);
-                       outlen = strlen(outbuf);
-               } else {
-                       outbuf = g_strdup(buf);
-                       outlen = len;
-               }
-               if (fwrite(outbuf, sizeof(gchar), outlen, fp) != outlen) {
-                       FILE_OP_ERROR(file, "fwrite");
-                       fclose(fp);
-                       unlink(file);
-                       g_free(outbuf);
-                       g_free(buf);
-                       return -1;
-               }
-               g_free(outbuf);
-       } else if (fwrite(buf, sizeof(gchar), len, fp) != len) {
-               FILE_OP_ERROR(file, "fwrite");
-               fclose(fp);
-               unlink(file);
-               g_free(buf);
-               return -1;
-       }
-       g_free(buf);
+               mimempart = procmime_mimeinfo_new();
+               mimempart->content = MIMECONTENT_EMPTY;
+               mimempart->type = MIMETYPE_MULTIPART;
+               mimempart->subtype = g_strdup("mixed");
+               g_hash_table_insert(mimempart->typeparameters, g_strdup("boundary"),
+                                   generate_mime_boundary(NULL));
 
-       if (compose_use_attach(compose))
-               compose_write_attach(compose, fp);
+               mimetext->disposition = DISPOSITIONTYPE_INLINE;
 
-       if (fclose(fp) == EOF) {
-               FILE_OP_ERROR(file, "fclose");
-               unlink(file);
-               return -1;
-       }
+               g_node_append(mimempart->node, mimetext->node);
+               g_node_append(mimemsg->node, mimempart->node);
 
-#if USE_GPGME
-       if (is_draft) {
-               uncanonicalize_file_replace(file);
-               return 0;
-       }
-
-       if ((compose->use_signing && !compose->gnupg_mode) ||
-           compose->use_encryption) {
-               if (canonicalize_file_replace(file) < 0) {
-                       unlink(file);
-                       return -1;
-               }
-       }
-
-       if (compose->use_signing && !compose->gnupg_mode) {
-               GSList *key_list;
+               compose_add_attachments(compose, mimempart);
+       } else
+               g_node_append(mimemsg->node, mimetext->node);
 
-               if (compose_create_signers_list(compose, &key_list) < 0 ||
-                   rfc2015_sign(file, key_list) < 0) {
-                       unlink(file);
-                       return -1;
-               }
-       }
-       if (compose->use_encryption) {
-               if (rfc2015_encrypt(file, compose->to_list,
-                                   compose->gnupg_mode,
-                                   out_codeset) < 0) {
-                       unlink(file);
+       /* sign message */
+       if (compose->use_signing && privacy_system_can_sign(compose->privacy_system))
+               if (!privacy_sign(compose->privacy_system, mimemsg))
                        return -1;
-               }
-       }
-#endif /* USE_GPGME */
 
-       uncanonicalize_file_replace(file);
+       procmime_write_mimeinfo(mimemsg, fp);
 
        return 0;
 }
@@ -4080,10 +3700,9 @@ static gint compose_queue(Compose *compose, gint *msgnum, FolderItem **item)
 static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item, gboolean check_subject)
 {
        FolderItem *queue;
-       gchar *tmp, *tmp2;
-       FILE *fp, *src_fp;
+       gchar *tmp;
+       FILE *fp;
        GSList *cur;
-       gchar buf[BUFFSIZE];
        gint num;
         static gboolean lock = FALSE;
        PrefsAccount *mailac = NULL, *newsac = NULL;
@@ -4128,27 +3747,8 @@ static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item,
 
         if (prefs_common.linewrap_at_send)
                compose_wrap_line_all(compose);
-                       
-       /* write to temporary file */
-       tmp2 = g_strdup_printf("%s%ctmp%d", g_get_tmp_dir(),
-                                     G_DIR_SEPARATOR, (gint)compose);
 
-       if (compose->redirect_filename != NULL) {
-               if (compose_redirect_write_to_file(compose, tmp2) < 0) {
-                       unlink(tmp2);
-                       lock = FALSE;
-                       return -1;
-               }
-       }
-       else {
-               if (compose_write_to_file(compose, tmp2, FALSE) < 0) {
-                       unlink(tmp2);
-                       lock = FALSE;
-                       return -1;
-               }
-       }
-
-       /* add queue header */
+       /* write queue header */
        tmp = g_strdup_printf("%s%cqueue.%p", get_tmp_dir(),
                              G_DIR_SEPARATOR, compose);
        if ((fp = fopen(tmp, "wb")) == NULL) {
@@ -4156,15 +3756,7 @@ static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item,
                g_free(tmp);
                return -1;
        }
-       if ((src_fp = fopen(tmp2, "rb")) == NULL) {
-               FILE_OP_ERROR(tmp2, "fopen");
-               fclose(fp);
-               unlink(tmp);
-               g_free(tmp);
-               unlink(tmp2);
-               g_free(tmp2);
-               return -1;
-       }
+
        if (change_file_mode_rw(fp, tmp) < 0) {
                FILE_OP_ERROR(tmp, "chmod");
                g_warning("can't change file mode\n");
@@ -4211,17 +3803,23 @@ static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item,
                fprintf(fp, "\n");
        }
        /* Sylpheed account IDs */
-       if (mailac) {
+       if (mailac)
                fprintf(fp, "MAID:%d\n", mailac->account_id);
-       }
-       if (newsac) {
+       if (newsac)
                fprintf(fp, "NAID:%d\n", newsac->account_id);
+
+       if (compose->privacy_system != NULL) {
+               fprintf(fp, "X-Sylpheed-Privacy-System:%s\n", compose->privacy_system);
+               fprintf(fp, "X-Sylpheed-Sign:%d\n", compose->use_signing);
+               fprintf(fp, "X-Sylpheed-Encrypt:%d\n", compose->use_encryption);
+               if (compose->use_encryption) {
+                       gchar *encdata;
+
+                       encdata = privacy_get_encrypt_data(compose->privacy_system, compose->to_list);
+                       fprintf(fp, "X-Sylpheed-Encrypt-Data:%s\n", encdata);
+                       g_free(encdata);
+               }
        }
-#ifdef USE_GPGME
-       fprintf(fp, "X-Sylpheed-Sign:%d\n", compose->use_signing);
-       fprintf(fp, "X-Sylpheed-Encrypt:%d\n", compose->use_encryption);
-       fprintf(fp, "X-Sylpheed-Gnupg-Mode:%d\n", compose->gnupg_mode);
-#endif
 
        /* Save copy folder */
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn))) {
@@ -4249,25 +3847,28 @@ static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item,
        }
        fprintf(fp, "\n");
 
-       while (fgets(buf, sizeof(buf), src_fp) != NULL) {
-               if (fputs(buf, fp) == EOF) {
-                       FILE_OP_ERROR(tmp, "fputs");
+       if (compose->redirect_filename != NULL) {
+               if (compose_redirect_write_to_file(compose, fp) < 0) {
+                       lock = FALSE;
+                       fclose(fp);
+                       unlink(tmp);
+                       g_free(tmp);
+                       return -1;
+               }
+       } else {
+               if (compose_write_to_file(compose, fp) < 0) {
+                       lock = FALSE;
                        fclose(fp);
-                       fclose(src_fp);
                        unlink(tmp);
                        g_free(tmp);
-                       unlink(tmp2);
-                       g_free(tmp2);
                        return -1;
                }
        }
-       fclose(src_fp);
+
        if (fclose(fp) == EOF) {
                FILE_OP_ERROR(tmp, "fclose");
                unlink(tmp);
                g_free(tmp);
-               unlink(tmp2);
-               g_free(tmp2);
                return -1;
        }
 
@@ -4287,8 +3888,6 @@ static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item,
        }
        unlink(tmp);
        g_free(tmp);
-       unlink(tmp2);
-       g_free(tmp2);
 
        if (compose->mode == COMPOSE_REEDIT) {
                compose_remove_reedit_target(compose);
@@ -4302,75 +3901,47 @@ static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item,
        return 0;
 }
 
-static void compose_write_attach(Compose *compose, FILE *fp)
+static void compose_add_attachments(Compose *compose, MimeInfo *parent)
 {
        AttachInfo *ainfo;
        GtkCList *clist = GTK_CLIST(compose->attach_clist);
        gint row;
-       FILE *attach_fp;
-       gchar filename[BUFFSIZE];
-       gint len;
+       MimeInfo *mimepart;
+       struct stat statbuf;
+       gchar *type, *subtype;
 
        for (row = 0; (ainfo = gtk_clist_get_row_data(clist, row)) != NULL;
             row++) {
-               if ((attach_fp = fopen(ainfo->file, "rb")) == NULL) {
-                       g_warning("Can't open file %s\n", ainfo->file);
-                       continue;
-               }
-
-               fprintf(fp, "\n--%s\n", compose->boundary);
-
-               if (!strcmp2(ainfo->content_type, "message/rfc822")) {
-                       fprintf(fp, "Content-Type: %s\n", ainfo->content_type);
-                       fprintf(fp, "Content-Disposition: inline\n");
+               mimepart = procmime_mimeinfo_new();
+               mimepart->content = MIMECONTENT_FILE;
+               mimepart->filename = g_strdup(ainfo->file);
+               mimepart->offset = 0;
+
+               stat(ainfo->file, &statbuf);
+               mimepart->length = statbuf.st_size;
+
+               type = g_strdup(ainfo->content_type);
+               subtype = strchr(type, '/') + 1;
+               *(subtype - 1) = '\0';
+               mimepart->type = procmime_get_media_type(type);
+               mimepart->subtype = g_strdup(subtype);
+               g_free(type);
+
+               if (mimepart->type == MIMETYPE_MESSAGE && 
+                   !g_strcasecmp(mimepart->subtype, "rfc822")) {
+                       mimepart->disposition = DISPOSITIONTYPE_INLINE;
                } else {
-                       compose_convert_header(filename, sizeof(filename),
-                                              ainfo->name, 12, FALSE);
-                       fprintf(fp, "Content-Type: %s;\n"
-                                   " name=\"%s\"\n",
-                               ainfo->content_type, filename);
-                       fprintf(fp, "Content-Disposition: attachment;\n"
-                                   " filename=\"%s\"\n", filename);
+                       g_hash_table_insert(mimepart->typeparameters,
+                                           g_strdup("name"), g_strdup(ainfo->name));
+                       g_hash_table_insert(mimepart->dispositionparameters,
+                                           g_strdup("filename"), g_strdup(ainfo->name));
+                       mimepart->disposition = DISPOSITIONTYPE_ATTACHMENT;
                }
 
-               fprintf(fp, "Content-Transfer-Encoding: %s\n\n",
-                       procmime_get_encoding_str(ainfo->encoding));
-
-               if (ainfo->encoding == ENC_BASE64) {
-                       gchar inbuf[B64_LINE_SIZE], outbuf[B64_BUFFSIZE];
+               procmime_encode_content(mimepart, ainfo->encoding);
 
-                       while ((len = fread(inbuf, sizeof(gchar),
-                                           B64_LINE_SIZE, attach_fp))
-                              == B64_LINE_SIZE) {
-                               base64_encode(outbuf, inbuf, B64_LINE_SIZE);
-                               fputs(outbuf, fp);
-                               fputc('\n', fp);
-                       }
-                       if (len > 0 && feof(attach_fp)) {
-                               base64_encode(outbuf, inbuf, len);
-                               fputs(outbuf, fp);
-                               fputc('\n', fp);
-                       }
-               } else if (ainfo->encoding == ENC_QUOTED_PRINTABLE) {
-                       gchar inbuf[BUFFSIZE], outbuf[BUFFSIZE * 4];
-
-                       while (fgets(inbuf, sizeof(inbuf), attach_fp) != NULL) {
-                               qp_encode_line(outbuf, inbuf);
-                               fputs(outbuf, fp);
-                       }
-               } else {
-                       gchar buf[BUFFSIZE];
-
-                       while (fgets(buf, sizeof(buf), attach_fp) != NULL) {
-                               strcrchomp(buf);
-                               fputs(buf, fp);
-                       }
-               }
-
-               fclose(attach_fp);
+               g_node_append(parent->node, mimepart->node);
        }
-
-       fprintf(fp, "\n--%s--\n", compose->boundary);
 }
 
 #define QUOTE_IF_REQUIRED(out, str)                                    \
@@ -4440,6 +4011,7 @@ static void compose_add_headerfield_from_headerlist(Compose *compose,
                                g_string_append(fieldstr, str);
                                add_field = TRUE;
                        }
+                       g_free(str);
                }
        }
        if (add_field) {
@@ -4459,8 +4031,7 @@ static void compose_add_headerfield_from_headerlist(Compose *compose,
        return;
 }
 
-static gchar *compose_get_header(Compose *compose, const gchar *charset,
-                                EncodingType encoding, gboolean is_draft)
+static gchar *compose_get_header(Compose *compose)
 {
        gchar buf[BUFFSIZE];
        const gchar *entry_str;
@@ -4472,31 +4043,11 @@ static gchar *compose_get_header(Compose *compose, const gchar *charset,
 
        /* struct utsname utsbuf; */
 
-       g_return_val_if_fail(charset != NULL, NULL);
        g_return_val_if_fail(compose->account != NULL, NULL);
        g_return_val_if_fail(compose->account->address != NULL, NULL);
 
        header = g_string_sized_new(64);
 
-       /* Save draft infos */
-       if (is_draft) {
-               g_string_sprintfa(header, "X-Sylpheed-Account-Id:%d\n", compose->account->account_id);
-               g_string_sprintfa(header, "S:%s\n", compose->account->address);
-               if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn))) {
-                       gchar *savefolderid;
-
-                       savefolderid = gtk_editable_get_chars(GTK_EDITABLE(compose->savemsg_entry), 0, -1);
-                       g_string_sprintfa(header, "SCF:%s\n", savefolderid);
-                       g_free(savefolderid);
-               }
-#ifdef USE_GPGME
-               g_string_sprintfa(header, "X-Sylpheed-Sign:%d\n", compose->use_signing);
-               g_string_sprintfa(header, "X-Sylpheed-Encrypt:%d\n", compose->use_encryption);
-               g_string_sprintfa(header, "X-Sylpheed-Gnupg-Mode:%d\n", compose->gnupg_mode);
-#endif
-               g_string_sprintfa(header, "\n");
-       }
-
        /* Date */
        if (compose->account->add_date) {
                get_rfc822_date(buf, sizeof(buf));
@@ -4542,6 +4093,7 @@ static gchar *compose_get_header(Compose *compose, const gchar *charset,
                                               strlen("Subject: "), FALSE);
                        g_string_sprintfa(header, "Subject: %s\n", buf);
                }
+               g_free(tmpstr);
        }
 
        /* Message-ID */
@@ -4613,23 +4165,6 @@ static gchar *compose_get_header(Compose *compose, const gchar *charset,
                }
        }
 
-       /* MIME */
-       g_string_sprintfa(header, "Mime-Version: 1.0\n");
-       if (compose_use_attach(compose)) {
-               compose->boundary = generate_mime_boundary(NULL);
-               g_string_sprintfa(header,
-                       "Content-Type: multipart/mixed;\n"
-                       " boundary=\"%s\"\n", compose->boundary);
-       } else {
-               g_string_sprintfa(header, "Content-Type: text/plain; charset=%s\n", charset);
-#if USE_GPGME
-               if (compose->use_signing && !compose->gnupg_mode)
-                       g_string_sprintfa(header, "Content-Disposition: inline\n");
-#endif
-               g_string_sprintfa(header, "Content-Transfer-Encoding: %s\n",
-                       procmime_get_encoding_str(encoding));
-       }
-
        /* PRIORITY */
        switch (compose->priority) {
                case PRIORITY_HIGHEST: g_string_sprintfa(header, "Importance: high\n"
@@ -4710,9 +4245,6 @@ static gchar *compose_get_header(Compose *compose, const gchar *charset,
                g_free(headername_wcolon);              
        }
 
-       /* separator between header and body */
-       g_string_sprintfa(header, "\n");
-
        str = header->str;
        g_string_free(header, FALSE);
 
@@ -5266,9 +4798,6 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
        gtk_container_add(GTK_CONTAINER(subject_frame), subject);
        
        edit_vbox = gtk_vbox_new(FALSE, 0);
-#if 0 /* NEW COMPOSE GUI */
-       gtk_box_pack_start(GTK_BOX(vbox2), edit_vbox, TRUE, TRUE, 0);
-#endif
 
        gtk_box_pack_start(GTK_BOX(edit_vbox), subject_hbox, FALSE, FALSE, 0);
 
@@ -5360,34 +4889,9 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
        ifactory = gtk_item_factory_from_widget(menubar);
        menu_set_sensitive(ifactory, "/Edit/Undo", FALSE);
        menu_set_sensitive(ifactory, "/Edit/Redo", FALSE);
-       menu_set_sensitive(ifactory, "/Message/Remove references", FALSE);
+       menu_set_sensitive(ifactory, "/Options/Remove references", FALSE);
 
        tmpl_menu = gtk_item_factory_get_item(ifactory, "/Tools/Template");
-#if 0 /* NEW COMPOSE GUI */
-       gtk_widget_hide(bcc_hbox);
-       gtk_widget_hide(bcc_entry);
-       gtk_widget_hide(reply_hbox);
-       gtk_widget_hide(reply_entry);
-       gtk_widget_hide(followup_hbox);
-       gtk_widget_hide(followup_entry);
-       gtk_widget_hide(ruler_hbox);
-       gtk_table_set_row_spacing(GTK_TABLE(table), 4, 0);
-       gtk_table_set_row_spacing(GTK_TABLE(table), 5, 0);
-       gtk_table_set_row_spacing(GTK_TABLE(table), 6, 0);
-
-       if (account->protocol == A_NNTP) {
-               gtk_widget_hide(to_hbox);
-               gtk_widget_hide(to_entry);
-               gtk_widget_hide(cc_hbox);
-               gtk_widget_hide(cc_entry);
-               gtk_table_set_row_spacing(GTK_TABLE(table), 1, 0);
-               gtk_table_set_row_spacing(GTK_TABLE(table), 3, 0);
-       } else {
-               gtk_widget_hide(newsgroups_hbox);
-               gtk_widget_hide(newsgroups_entry);
-               gtk_table_set_row_spacing(GTK_TABLE(table), 2, 0);
-       }
-#endif
 
        undostruct = undo_init(text);
        undo_set_change_state_func(undostruct, &compose_undo_state_changed,
@@ -5437,10 +4941,9 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
 
        compose->autowrap       = prefs_common.autowrap;
 
-#if USE_GPGME
        compose->use_signing    = FALSE;
        compose->use_encryption = FALSE;
-#endif /* USE_GPGME */
+       compose->privacy_system = NULL;
 
        compose->modified = FALSE;
 
@@ -5502,7 +5005,6 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
        compose_select_account(compose, account, TRUE);
 
        menu_set_active(ifactory, "/Edit/Auto wrapping", prefs_common.autowrap);
-       menu_set_active(ifactory, "/View/Ruler", prefs_common.show_ruler);
        if (account->set_autocc && account->auto_cc && mode != COMPOSE_REEDIT)
                compose_entry_append(compose, account->auto_cc, COMPOSE_CC);
 
@@ -5540,9 +5042,10 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
        /* Actions menu */
        compose_update_actions_menu(compose);
 
-#if USE_GPGME
-       activate_gnupg_mode(compose, account);
-#endif 
+       /* Privacy Systems menu */
+       compose_update_privacy_systems_menu(compose);
+
+       activate_privacy_system(compose, account);
        toolbar_set_style(compose->toolbar->toolbar, compose->handlebox, prefs_common.toolbar_style);
        gtk_widget_show(window);
        
@@ -5610,62 +5113,93 @@ static void compose_update_priority_menu_item(Compose * compose)
        switch (compose->priority) {
                case PRIORITY_HIGHEST:
                        menuitem = gtk_item_factory_get_item
-                               (ifactory, "/Message/Priority/Highest");
+                               (ifactory, "/Options/Priority/Highest");
                        break;
                case PRIORITY_HIGH:
                        menuitem = gtk_item_factory_get_item
-                               (ifactory, "/Message/Priority/High");
+                               (ifactory, "/Options/Priority/High");
                        break;
                case PRIORITY_NORMAL:
                        menuitem = gtk_item_factory_get_item
-                               (ifactory, "/Message/Priority/Normal");
+                               (ifactory, "/Options/Priority/Normal");
                        break;
                case PRIORITY_LOW:
                        menuitem = gtk_item_factory_get_item
-                               (ifactory, "/Message/Priority/Low");
+                               (ifactory, "/Options/Priority/Low");
                        break;
                case PRIORITY_LOWEST:
                        menuitem = gtk_item_factory_get_item
-                               (ifactory, "/Message/Priority/Lowest");
+                               (ifactory, "/Options/Priority/Lowest");
                        break;
        }
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
 }      
 
-#if USE_GPGME 
-static void compose_set_gnupg_mode_cb(gpointer data,
-                                   guint action,
-                                   GtkWidget *widget)
+static void compose_set_privacy_system_cb(gpointer data,
+                                         guint action,
+                                         GtkWidget *widget)
 {
        Compose *compose = (Compose *) data;
-       compose->gnupg_mode = action;
+       gchar *systemid;
+       GtkItemFactory *ifactory;
+       gboolean can_sign = FALSE, can_encrypt = FALSE;
+
+       systemid = gtk_object_get_data(GTK_OBJECT(widget), "privacy_system");
+       g_free(compose->privacy_system);
+       compose->privacy_system = NULL;
+       if (systemid != NULL) {
+               compose->privacy_system = g_strdup(systemid);
+
+               can_sign = privacy_system_can_sign(systemid);
+               can_encrypt = privacy_system_can_encrypt(systemid);
+       }
+
+       ifactory = gtk_item_factory_from_widget(compose->menubar);
+       menu_set_sensitive(ifactory, "/Options/Sign", can_sign);
+       menu_set_sensitive(ifactory, "/Options/Encrypt", can_encrypt);
 }
 
-static void compose_update_gnupg_mode_menu_item(Compose * compose)
+static void compose_update_privacy_system_menu_item(Compose * compose)
 {
+       static gchar *branch_path = "/Options/Privacy System";
        GtkItemFactory *ifactory;
        GtkWidget *menuitem = NULL;
+       GList *amenu;
+       gboolean can_sign = FALSE, can_encrypt = FALSE;
 
        ifactory = gtk_item_factory_from_widget(compose->menubar);
-       
-       switch (compose->gnupg_mode) {
-               case GNUPG_MODE_DETACH:
-                       menuitem = gtk_item_factory_get_item
-                               (ifactory, "/Message/Mode/MIME");
-                       break;
-               case GNUPG_MODE_INLINE:
-                       menuitem = gtk_item_factory_get_item
-                               (ifactory, "/Message/Mode/Inline");
-                       break;
+
+       if (compose->privacy_system != NULL) {
+               gchar *systemid;
+
+               menuitem = gtk_item_factory_get_widget(ifactory, branch_path);
+               g_return_if_fail(menuitem != NULL);
+
+               amenu = GTK_MENU_SHELL(menuitem)->children;
+               menuitem = NULL;
+               while (amenu != NULL) {
+                       GList *alist = amenu->next;
+
+                       systemid = gtk_object_get_data(GTK_OBJECT(amenu->data), "privacy_system");
+                       if (systemid != NULL)
+                               if (strcmp(systemid, compose->privacy_system) == 0) {
+                                       menuitem = GTK_WIDGET(amenu->data);
+
+                                       can_sign = privacy_system_can_sign(systemid);
+                                       can_encrypt = privacy_system_can_encrypt(systemid);
+
+                                       break;
+                               }
+
+                       amenu = alist;
+               }
+               if (menuitem != NULL)
+                       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
        }
-       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
-       
-       if (compose->use_encryption == TRUE || compose->use_signing == TRUE)
-               menu_set_sensitive(ifactory, "/Message/Mode", TRUE);
-       else 
-               menu_set_sensitive(ifactory, "/Message/Mode", FALSE);
+
+       menu_set_sensitive(ifactory, "/Options/Sign", can_sign);
+       menu_set_sensitive(ifactory, "/Options/Encrypt", can_encrypt);
 }      
-#endif
  
 static void compose_set_template_menu(Compose *compose)
 {
@@ -5701,6 +5235,55 @@ void compose_update_actions_menu(Compose *compose)
        action_update_compose_menu(ifactory, "/Tools/Actions", compose);
 }
 
+void compose_update_privacy_systems_menu(Compose *compose)
+{
+       static gchar *branch_path = "/Options/Privacy System";
+       GtkItemFactory *ifactory;
+       GtkWidget *menuitem;
+       gchar *menu_path;
+       GSList *systems, *cur;
+       GList *amenu;
+       GtkItemFactoryEntry ifentry = {NULL, NULL, NULL, 0, "<Branch>"};
+       GtkWidget *widget;
+
+       ifactory = gtk_item_factory_from_widget(compose->menubar);
+
+       /* remove old entries */
+       ifentry.path = branch_path;
+       menuitem = gtk_item_factory_get_widget(ifactory, branch_path);
+       g_return_if_fail(menuitem != NULL);
+
+       amenu = GTK_MENU_SHELL(menuitem)->children->next;
+       while (amenu != NULL) {
+               GList *alist = amenu->next;
+               gtk_widget_destroy(GTK_WIDGET(amenu->data));
+               amenu = alist;
+       }
+
+       ifentry.accelerator     = NULL;
+       ifentry.callback_action = 0;
+       ifentry.callback        = compose_set_privacy_system_cb;
+       ifentry.item_type       = "/Options/Privacy System/None";
+
+       systems = privacy_get_system_ids();
+       for (cur = systems; cur != NULL; cur = g_slist_next(cur)) {
+               gchar *systemid = cur->data;
+
+               menu_path = g_strdup_printf("%s/%s", branch_path,
+                                           privacy_system_get_name(systemid));
+               ifentry.path = menu_path;
+               gtk_item_factory_create_item(ifactory, &ifentry, compose, 1);
+               widget = gtk_item_factory_get_widget(ifactory, menu_path);
+
+               g_object_set_data_full(G_OBJECT(widget), "privacy_system",
+                                      g_strdup(systemid), g_free);
+
+               g_free(systemid);
+               g_free(menu_path);
+       }
+       g_slist_free(systems);
+}
+
 void compose_reflect_prefs_all(void)
 {
        GList *cur;
@@ -6389,8 +5972,8 @@ static void compose_set_ext_editor_sensitive(Compose *compose,
 
        menu_set_sensitive(ifactory, "/Message/Send", sensitive);
        menu_set_sensitive(ifactory, "/Message/Send later", sensitive);
-       menu_set_sensitive(ifactory, "/File/Insert file", sensitive);
-       menu_set_sensitive(ifactory, "/File/Insert signature", sensitive);
+       menu_set_sensitive(ifactory, "/Message/Insert file", sensitive);
+       menu_set_sensitive(ifactory, "/Message/Insert signature", sensitive);
        menu_set_sensitive(ifactory, "/Edit/Wrap current paragraph", sensitive);
        menu_set_sensitive(ifactory, "/Edit/Wrap all long lines", sensitive);
        menu_set_sensitive(ifactory, "/Edit/Edit with external editor",
@@ -6593,12 +6176,12 @@ static void compose_allow_user_actions (Compose *compose, gboolean allow)
 {
        GtkItemFactory *ifactory = gtk_item_factory_from_widget(compose->menubar);
        toolbar_comp_set_sensitive(compose, allow);
-       menu_set_sensitive(ifactory, "/File", allow);
+       menu_set_sensitive(ifactory, "/Message", allow);
        menu_set_sensitive(ifactory, "/Edit", allow);
 #if USE_ASPELL
        menu_set_sensitive(ifactory, "/Spelling", allow);
 #endif 
-       menu_set_sensitive(ifactory, "/Message", allow);
+       menu_set_sensitive(ifactory, "/Options", allow);
        menu_set_sensitive(ifactory, "/Tools", allow);
        menu_set_sensitive(ifactory, "/Help", allow);
 }
@@ -6645,6 +6228,7 @@ static void compose_draft_cb(gpointer data, guint action, GtkWidget *widget)
        MsgFlags flag = {0, 0};
        static gboolean lock = FALSE;
        MsgInfo *newmsginfo;
+       FILE *fp;
        
        if (lock) return;
 
@@ -6655,12 +6239,40 @@ static void compose_draft_cb(gpointer data, guint action, GtkWidget *widget)
 
        tmp = g_strdup_printf("%s%cdraft.%p", get_tmp_dir(),
                              G_DIR_SEPARATOR, compose);
+       if ((fp = fopen(tmp, "wb")) == NULL) {
+               FILE_OP_ERROR(tmp, "fopen");
+               return;
+       }
 
-       if (compose_write_to_file(compose, tmp, TRUE) < 0) {
+       /* chmod for security */
+       if (change_file_mode_rw(fp, tmp) < 0) {
+               FILE_OP_ERROR(tmp, "chmod");
+               g_warning("can't change file mode\n");
+       }
+
+       /* Save draft infos */
+       fprintf(fp, "X-Sylpheed-Account-Id:%d\n", compose->account->account_id);
+       fprintf(fp, "S:%s\n", compose->account->address);
+       if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn))) {
+               gchar *savefolderid;
+
+               savefolderid = gtk_editable_get_chars(GTK_EDITABLE(compose->savemsg_entry), 0, -1);
+               fprintf(fp, "SCF:%s\n", savefolderid);
+               g_free(savefolderid);
+       }
+       fprintf(fp, "X-Sylpheed-Sign:%d\n", compose->use_signing);
+       fprintf(fp, "X-Sylpheed-Encrypt:%d\n", compose->use_encryption);
+       fprintf(fp, "X-Sylpheed-Gnupg-Mode:%s\n", compose->privacy_system);
+       fprintf(fp, "\n");
+
+       if (compose_write_to_file(compose, fp) < 0) {
+               fclose(fp);
+               unlink(tmp);
                g_free(tmp);
                lock = FALSE;
                return;
        }
+       fclose(fp);
 
        folder_item_scan(draft);
        if ((msgnum = folder_item_add_msg(draft, tmp, &flag, TRUE)) < 0) {
@@ -6681,7 +6293,9 @@ static void compose_draft_cb(gpointer data, guint action, GtkWidget *widget)
                procmsg_msginfo_unset_flags(newmsginfo, ~0, ~0);
                procmsg_msginfo_set_flags(newmsginfo, 0, MSG_DRAFT);
                if (compose_use_attach(compose))
-                       procmsg_msginfo_set_flags(newmsginfo, 0, MSG_HAS_ATTACHMENT);
+                       procmsg_msginfo_set_flags(newmsginfo, 0,
+                                                 MSG_HAS_ATTACHMENT);
+
                procmsg_msginfo_free(newmsginfo);
        }
        
@@ -7318,149 +6932,6 @@ static void compose_toggle_autowrap_cb(gpointer data, guint action,
                compose_wrap_line_all_full(compose, TRUE);
 }
 
-#if 0 /* NEW COMPOSE GUI */
-static void compose_toggle_to_cb(gpointer data, guint action,
-                                GtkWidget *widget)
-{
-       Compose *compose = (Compose *)data;
-
-       if (GTK_CHECK_MENU_ITEM(widget)->active) {
-               gtk_widget_show(compose->to_hbox);
-               gtk_widget_show(compose->to_entry);
-               gtk_table_set_row_spacing(GTK_TABLE(compose->table), 1, 4);
-               compose->use_to = TRUE;
-       } else {
-               gtk_widget_hide(compose->to_hbox);
-               gtk_widget_hide(compose->to_entry);
-               gtk_table_set_row_spacing(GTK_TABLE(compose->table), 1, 0);
-               gtk_widget_queue_resize(compose->table_vbox);
-               compose->use_to = FALSE;
-       }
-
-       if (addressbook_get_target_compose() == compose)
-               addressbook_set_target_compose(compose);
-}
-
-static void compose_toggle_cc_cb(gpointer data, guint action,
-                                GtkWidget *widget)
-{
-       Compose *compose = (Compose *)data;
-
-       if (GTK_CHECK_MENU_ITEM(widget)->active) {
-               gtk_widget_show(compose->cc_hbox);
-               gtk_widget_show(compose->cc_entry);
-               gtk_table_set_row_spacing(GTK_TABLE(compose->table), 3, 4);
-               compose->use_cc = TRUE;
-       } else {
-               gtk_widget_hide(compose->cc_hbox);
-               gtk_widget_hide(compose->cc_entry);
-               gtk_table_set_row_spacing(GTK_TABLE(compose->table), 3, 0);
-               gtk_widget_queue_resize(compose->table_vbox);
-               compose->use_cc = FALSE;
-       }
-
-       if (addressbook_get_target_compose() == compose)
-               addressbook_set_target_compose(compose);
-}
-
-static void compose_toggle_bcc_cb(gpointer data, guint action,
-                                 GtkWidget *widget)
-{
-       Compose *compose = (Compose *)data;
-
-       if (GTK_CHECK_MENU_ITEM(widget)->active) {
-               gtk_widget_show(compose->bcc_hbox);
-               gtk_widget_show(compose->bcc_entry);
-               gtk_table_set_row_spacing(GTK_TABLE(compose->table), 4, 4);
-               compose->use_bcc = TRUE;
-       } else {
-               gtk_widget_hide(compose->bcc_hbox);
-               gtk_widget_hide(compose->bcc_entry);
-               gtk_table_set_row_spacing(GTK_TABLE(compose->table), 4, 0);
-               gtk_widget_queue_resize(compose->table_vbox);
-               compose->use_bcc = FALSE;
-       }
-
-       if (addressbook_get_target_compose() == compose)
-               addressbook_set_target_compose(compose);
-}
-
-static void compose_toggle_replyto_cb(gpointer data, guint action,
-                                     GtkWidget *widget)
-{
-       Compose *compose = (Compose *)data;
-
-       if (GTK_CHECK_MENU_ITEM(widget)->active) {
-               gtk_widget_show(compose->reply_hbox);
-               gtk_widget_show(compose->reply_entry);
-               gtk_table_set_row_spacing(GTK_TABLE(compose->table), 5, 4);
-               compose->use_replyto = TRUE;
-       } else {
-               gtk_widget_hide(compose->reply_hbox);
-               gtk_widget_hide(compose->reply_entry);
-               gtk_table_set_row_spacing(GTK_TABLE(compose->table), 5, 0);
-               gtk_widget_queue_resize(compose->table_vbox);
-               compose->use_replyto = FALSE;
-       }
-}
-
-static void compose_toggle_followupto_cb(gpointer data, guint action,
-                                        GtkWidget *widget)
-{
-       Compose *compose = (Compose *)data;
-
-       if (GTK_CHECK_MENU_ITEM(widget)->active) {
-               gtk_widget_show(compose->followup_hbox);
-               gtk_widget_show(compose->followup_entry);
-               gtk_table_set_row_spacing(GTK_TABLE(compose->table), 6, 4);
-               compose->use_followupto = TRUE;
-       } else {
-               gtk_widget_hide(compose->followup_hbox);
-               gtk_widget_hide(compose->followup_entry);
-               gtk_table_set_row_spacing(GTK_TABLE(compose->table), 6, 0);
-               gtk_widget_queue_resize(compose->table_vbox);
-               compose->use_followupto = FALSE;
-       }
-}
-
-static void compose_toggle_attach_cb(gpointer data, guint action,
-                                    GtkWidget *widget)
-{
-       Compose *compose = (Compose *)data;
-
-       if (GTK_CHECK_MENU_ITEM(widget)->active) {
-               gtk_widget_ref(compose->edit_vbox);
-
-               gtkut_container_remove(GTK_CONTAINER(compose->vbox2),
-                                      compose->edit_vbox);
-               gtk_paned_add2(GTK_PANED(compose->paned), compose->edit_vbox);
-               gtk_box_pack_start(GTK_BOX(compose->vbox2), compose->paned,
-                                  TRUE, TRUE, 0);
-               gtk_widget_show(compose->paned);
-
-               gtk_widget_unref(compose->edit_vbox);
-               gtk_widget_unref(compose->paned);
-
-               compose->use_attach = TRUE;
-       } else {
-               gtk_widget_ref(compose->paned);
-               gtk_widget_ref(compose->edit_vbox);
-
-               gtkut_container_remove(GTK_CONTAINER(compose->vbox2),
-                                      compose->paned);
-               gtkut_container_remove(GTK_CONTAINER(compose->paned),
-                                      compose->edit_vbox);
-               gtk_box_pack_start(GTK_BOX(compose->vbox2),
-                                  compose->edit_vbox, TRUE, TRUE, 0);
-
-               gtk_widget_unref(compose->edit_vbox);
-
-               compose->use_attach = FALSE;
-       }
-}
-#endif
-
-#if USE_GPGME
 static void compose_toggle_sign_cb(gpointer data, guint action,
                                   GtkWidget *widget)
 {
@@ -7470,8 +6941,6 @@ static void compose_toggle_sign_cb(gpointer data, guint action,
                compose->use_signing = TRUE;
        else
                compose->use_signing = FALSE;
-
-       compose_update_gnupg_mode_menu_item(compose);
 }
 
 static void compose_toggle_encrypt_cb(gpointer data, guint action,
@@ -7483,20 +6952,18 @@ static void compose_toggle_encrypt_cb(gpointer data, guint action,
                compose->use_encryption = TRUE;
        else
                compose->use_encryption = FALSE;
-               
-       compose_update_gnupg_mode_menu_item(compose);
 }
 
-static void activate_gnupg_mode (Compose *compose, PrefsAccount *account) 
+static void activate_privacy_system(Compose *compose, PrefsAccount *account) 
 {
+       /* TODO
        if (account->default_gnupg_mode)
                compose->gnupg_mode = GNUPG_MODE_INLINE;
        else
                compose->gnupg_mode = GNUPG_MODE_DETACH;
-               
-       compose_update_gnupg_mode_menu_item(compose);
+       */              
+       compose_update_privacy_system_menu_item(compose);
 }
-#endif /* USE_GPGME */
 
 static void compose_toggle_ruler_cb(gpointer data, guint action,
                                    GtkWidget *widget)
index a7fb02c997f8ba69568a6fbc5ecc757fb2290a96..146735f64dc1f1289c3fb8a65d757bb93c055dff 100644 (file)
@@ -174,8 +174,7 @@ struct _Compose
        /* privacy settings */
        gboolean use_signing;
        gboolean use_encryption;
-       
-       gint gnupg_mode;
+       gchar *privacy_system;
 
        gboolean modified;
 
@@ -274,7 +273,7 @@ void compose_entry_mark_default_to  (Compose          *compose,
 gint compose_send                      (Compose          *compose);
 
 void compose_update_actions_menu       (Compose        *compose);
-
+void compose_update_privacy_systems_menu(Compose       *compose);
 void compose_reflect_prefs_all                 (void);
 void compose_reflect_prefs_pixmap_theme        (void);
 
index 630d915338f9d6d67c8f4b2798271c2fd29b76a1..40047445602bccf2e8fcf35eebd2dccd0a2f03dc 100644 (file)
@@ -411,9 +411,6 @@ static const gchar *get_compiled_in_features(void)
 #if HAVE_LIBJCONV
                   " libjconv"
 #endif
-#if USE_GPGME
-                  " GPGME"
-#endif
 #if USE_OPENSSL
                   " OpenSSL"
 #endif
index 61ffda212a010084742d4b6bd8ed89b2db72e00d..43c7185bc476e1e980a2223cf0e4cc6bb171ffbe 100644 (file)
@@ -143,9 +143,6 @@ static void about_create(void)
 #if HAVE_LIBCOMPFACE
                   " compface"
 #endif
-#if USE_GPGME
-                  " GnuPG"
-#endif
 #if USE_OPENSSL
                   " OpenSSL"
 #endif
@@ -205,11 +202,6 @@ static void about_create(void)
        buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
        gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0);
 
-#if USE_GPGME
-       gtk_text_buffer_insert(buffer, &iter,
-               _("GPGME is copyright 2001 by Werner Koch <dd9jn@gnu.org>\n\n"), -1);
-#endif /* USE_GPGME */
-
        gtk_text_buffer_insert(buffer, &iter,
                _("This program is free software; you can redistribute it and/or modify "
                  "it under the terms of the GNU General Public License as published by "
index 60e35ce4b9a7978abce58dffbc222cab137f63c7..5ba2971517710647dd1fbcf738d63d09d2b95d9d 100644 (file)
 # include <gdk/gdkx.h>
 #endif
 
-#if USE_GPGME
-#  include <gpgme.h>
-#  include "passphrase.h"
-#endif
-
 #include "sylpheed.h"
 #include "intl.h"
 #include "main.h"
index 07e4b89a7d91bd609e2243422058015829c3a94e..b48fbe23ecab3a1115db21633ce0405c4e676fe9 100644 (file)
@@ -429,7 +429,7 @@ static GtkCTreeNode *mimeview_append_part(MimeView *mimeview,
        gchar *str[N_MIMEVIEW_COLS];
 
        if (partinfo->type != MIMETYPE_UNKNOWN && partinfo->subtype) {
-               g_snprintf(content_type, 64, "%s/%s", procmime_get_type_str(partinfo->type), partinfo->subtype);
+               g_snprintf(content_type, 64, "%s/%s", procmime_get_media_type_str(partinfo->type), partinfo->subtype);
        } else {
                g_snprintf(content_type, 64, "UNKNOWN");
        }
diff --git a/src/passphrase.c b/src/passphrase.c
deleted file mode 100644 (file)
index b3dadcb..0000000
+++ /dev/null
@@ -1,345 +0,0 @@
-/* passphrase.c - GTK+ based passphrase callback
- *      Copyright (C) 2001 Werner Koch (dd9jn)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#if USE_GPGME
-
-#include <string.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <glib.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtkmain.h>
-#include <gtk/gtkwidget.h>
-#include <gtk/gtkwindow.h>
-#include <gtk/gtkvbox.h>
-#include <gtk/gtktable.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkentry.h>
-#include <gtk/gtkhbbox.h>
-#include <gtk/gtkbutton.h>
-#include <gtk/gtkfilesel.h>
-#include <gtk/gtksignal.h>
-#ifdef GDK_WINDOWING_X11
-#include <gdk/gdkx.h>  /* GDK_DISPLAY() */
-#endif /* GDK_WINDOWING_X11 */
-
-#include "intl.h"
-#include "passphrase.h"
-#include "prefs_common.h"
-#include "manage_window.h"
-#include "utils.h"
-
-static int grab_all = 0;
-
-static gboolean pass_ack;
-static gchar *last_pass = NULL;
-
-static void passphrase_ok_cb(GtkWidget *widget, gpointer data);
-static void passphrase_cancel_cb(GtkWidget *widget, gpointer data);
-static gint passphrase_deleted(GtkWidget *widget, GdkEventAny *event,
-                              gpointer data);
-static gboolean passphrase_key_pressed(GtkWidget *widget, GdkEventKey *event,
-                                      gpointer data);
-static gchar* passphrase_mbox (const gchar *desc);
-
-
-static GtkWidget *create_description (const gchar *desc);
-
-void
-gpgmegtk_set_passphrase_grab (gint yes)
-{
-    grab_all = yes;
-}
-
-static gchar*
-passphrase_mbox (const gchar *desc)
-{
-    gchar *the_passphrase = NULL;
-    GtkWidget *vbox;
-    GtkWidget *table;
-    GtkWidget *pass_label;
-    GtkWidget *confirm_box;
-    GtkWidget *window;
-    GtkWidget *pass_entry;
-    GtkWidget *ok_button;
-    GtkWidget *cancel_button;
-    gint       grab_result;
-
-    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-    gtk_window_set_title(GTK_WINDOW(window), _("Passphrase"));
-    gtk_widget_set_size_request(window, 450, -1);
-    gtk_container_set_border_width(GTK_CONTAINER(window), 4);
-    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
-    gtk_window_set_modal(GTK_WINDOW(window), TRUE);
-    gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
-    g_signal_connect(G_OBJECT(window), "delete_event",
-                    G_CALLBACK(passphrase_deleted), NULL);
-    g_signal_connect(G_OBJECT(window), "key_press_event",
-                    G_CALLBACK(passphrase_key_pressed), NULL);
-    MANAGE_WINDOW_SIGNALS_CONNECT(window);
-    manage_window_set_transient(GTK_WINDOW(window));
-
-    vbox = gtk_vbox_new(FALSE, 8);
-    gtk_container_add(GTK_CONTAINER(window), vbox);
-
-    if (desc) {
-        GtkWidget *label;
-        label = create_description (desc);
-        gtk_box_pack_start (GTK_BOX(vbox), label, TRUE, TRUE, 0);
-    }
-
-    table = gtk_table_new(2, 2, FALSE);
-    gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
-    gtk_container_set_border_width(GTK_CONTAINER(table), 8);
-    gtk_table_set_row_spacings(GTK_TABLE(table), 12);
-    gtk_table_set_col_spacings(GTK_TABLE(table), 8);
-
-
-    pass_label = gtk_label_new("");
-    gtk_table_attach (GTK_TABLE(table), pass_label, 0, 1, 0, 1,
-                      GTK_FILL, GTK_EXPAND|GTK_FILL, 0, 0);
-    gtk_misc_set_alignment (GTK_MISC (pass_label), 1, 0.5);
-
-    pass_entry = gtk_entry_new();
-    gtk_table_attach (GTK_TABLE(table), pass_entry, 1, 2, 0, 1,
-                      GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
-    gtk_entry_set_visibility (GTK_ENTRY(pass_entry), FALSE);
-    gtk_widget_grab_focus (pass_entry);
-
-
-    confirm_box = gtk_hbutton_box_new ();
-    gtk_button_box_set_layout (GTK_BUTTON_BOX(confirm_box), GTK_BUTTONBOX_END);
-    gtk_box_set_spacing (GTK_BOX(confirm_box), 5);
-
-    ok_button = gtk_button_new_with_label (_("OK"));
-    GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
-    gtk_box_pack_start (GTK_BOX(confirm_box), ok_button, TRUE, TRUE, 0);
-
-    cancel_button = gtk_button_new_with_label (_("Cancel"));
-    GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT);
-    gtk_box_pack_start(GTK_BOX(confirm_box), cancel_button, TRUE, TRUE, 0);
-
-    gtk_box_pack_end(GTK_BOX(vbox), confirm_box, FALSE, FALSE, 0);
-    gtk_widget_grab_default (ok_button);
-
-    g_signal_connect(G_OBJECT(ok_button), "clicked",
-                    G_CALLBACK(passphrase_ok_cb), NULL);
-    g_signal_connect(G_OBJECT(pass_entry), "activate",
-                    G_CALLBACK(passphrase_ok_cb), NULL);
-    g_signal_connect(G_OBJECT(cancel_button), "clicked",
-                    G_CALLBACK(passphrase_cancel_cb), NULL);
-
-    if (grab_all)
-        g_object_set (G_OBJECT(window), "type", GTK_WINDOW_POPUP, NULL);
-    gtk_window_set_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER);
-    if (grab_all)   
-        gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
-    
-    gtk_widget_show_all(window);
-
-    /* don't use XIM on entering passphrase */
-    gtkut_editable_disable_im(GTK_EDITABLE(pass_entry));
-
-    if (grab_all) {
-#ifdef GDK_WINDOWING_X11
-        XGrabServer(GDK_DISPLAY());
-#endif /* GDK_WINDOWING_X11 */
-        if ( grab_result = gdk_pointer_grab ( window->window, TRUE, 0,
-                                NULL, NULL, GDK_CURRENT_TIME)) {
-#ifdef GDK_WINDOWING_X11
-            XUngrabServer ( GDK_DISPLAY() );
-#endif /* GDK_WINDOWING_X11 */
-            g_warning ("OOPS: Could not grab mouse (grab status %d)\n",
-                       grab_result);
-            gtk_widget_destroy (window);
-            return NULL;
-        }
-        if ( grab_result = gdk_keyboard_grab( window->window, FALSE, 
-                                               GDK_CURRENT_TIME )) {
-            gdk_pointer_ungrab (GDK_CURRENT_TIME);
-#ifdef GDK_WINDOWING_X11
-            XUngrabServer ( GDK_DISPLAY() );
-#endif /* GDK_WINDOWING_X11 */
-            g_warning ("OOPS: Could not grab keyboard (grab status %d)\n",
-                       grab_result);
-            gtk_widget_destroy (window);
-            return NULL;
-        }
-    }
-
-    gtk_main();
-
-    if (grab_all) {
-#ifdef GDK_WINDOWING_X11
-        XUngrabServer (GDK_DISPLAY());
-#endif /* GDK_WINDOWING_X11 */
-        gdk_pointer_ungrab (GDK_CURRENT_TIME);
-        gdk_keyboard_ungrab (GDK_CURRENT_TIME);
-        gdk_flush();
-    }
-
-    manage_window_focus_out(window, NULL, NULL);
-
-    if (pass_ack) {
-        const gchar *entry_text = gtk_entry_get_text(GTK_ENTRY(pass_entry));
-        if (entry_text) /* Hmmm: Do we really need this? */
-            the_passphrase = g_strdup (entry_text);
-    }
-    gtk_widget_destroy (window);
-
-    return the_passphrase;
-}
-
-
-static void 
-passphrase_ok_cb(GtkWidget *widget, gpointer data)
-{
-    pass_ack = TRUE;
-    gtk_main_quit();
-}
-
-static void 
-passphrase_cancel_cb(GtkWidget *widget, gpointer data)
-{
-    pass_ack = FALSE;
-    gtk_main_quit();
-}
-
-
-static gint
-passphrase_deleted(GtkWidget *widget, GdkEventAny *event, gpointer data)
-{
-    passphrase_cancel_cb(NULL, NULL);
-    return TRUE;
-}
-
-
-static gboolean
-passphrase_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
-{
-    if (event && event->keyval == GDK_Escape)
-        passphrase_cancel_cb(NULL, NULL);
-    return FALSE;
-}
-
-static gint 
-linelen (const gchar *s)
-{
-    gint i;
-
-    for (i = 0; *s && *s != '\n'; s++, i++)
-        ;
-
-    return i;
-}
-
-static GtkWidget *
-create_description (const gchar *desc)
-{
-    const gchar *cmd = NULL, *uid = NULL, *info = NULL;
-    gchar *buf;
-    GtkWidget *label;
-
-    cmd = desc;
-    uid = strchr (cmd, '\n');
-    if (uid) {
-        info = strchr (++uid, '\n');
-        if (info )
-            info++;
-    }
-
-    if (!uid)
-        uid = _("[no user id]");
-    if (!info)
-        info = "";
-
-    buf = g_strdup_printf (_("%sPlease enter the passphrase for:\n\n"
-                           "  %.*s  \n"
-                           "(%.*s)\n"),
-                           !strncmp (cmd, "TRY_AGAIN", 9 ) ?
-                           _("Bad passphrase! Try again...\n\n") : "",
-                           linelen (uid), uid, linelen (info), info);
-
-    label = gtk_label_new (buf);
-    g_free (buf);
-
-    return label;
-}
-
-static int free_passphrase(gpointer _unused)
-{
-    if (last_pass != NULL) {
-        munlock(last_pass, strlen(last_pass));
-        g_free(last_pass);
-        last_pass = NULL;
-        debug_print("%% passphrase removed");
-    }
-    
-    return FALSE;
-}
-
-const char*
-gpgmegtk_passphrase_cb (void *opaque, const char *desc, void **r_hd)
-{
-    struct passphrase_cb_info_s *info = opaque;
-    GpgmeCtx ctx = info ? info->c : NULL;
-    const char *pass;
-
-    if (!desc) {
-        /* FIXME: cleanup by looking at *r_hd */
-        return NULL;
-    }
-    if (prefs_common.store_passphrase && last_pass != NULL &&
-        strncmp(desc, "TRY_AGAIN", 9) != 0)
-        return g_strdup(last_pass);
-
-    gpgmegtk_set_passphrase_grab (prefs_common.passphrase_grab);
-    debug_print ("%% requesting passphrase for `%s': ", desc);
-    pass = passphrase_mbox (desc);
-    gpgmegtk_free_passphrase();
-    if (!pass) {
-        debug_print ("%% cancel passphrase entry");
-        gpgme_cancel (ctx);
-    }
-    else {
-        if (prefs_common.store_passphrase) {
-            last_pass = g_strdup(pass);
-            if (mlock(last_pass, strlen(last_pass)) == -1)
-                debug_print("%% locking passphrase failed");
-
-            if (prefs_common.store_passphrase_timeout > 0) {
-                gtk_timeout_add(prefs_common.store_passphrase_timeout*60*1000,
-                                free_passphrase, NULL);
-            }
-        }
-        debug_print ("%% sending passphrase");
-    }
-
-    return pass;
-}
-
-void gpgmegtk_free_passphrase(void)
-{
-    (void)free_passphrase(NULL); /* could be inline */
-}
-
-#endif /* USE_GPGME */
diff --git a/src/passphrase.h b/src/passphrase.h
deleted file mode 100644 (file)
index 5556a50..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* passphrase.h - GTK+ based passphrase callback
- *      Copyright (C) 2001 Werner Koch (dd9jn)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef GPGMEGTK_PASSPHRASE_H
-#define GPGMEGTK_PASSPHRASE_H
-
-#include <glib.h>
-#include <gpgme.h>
-
-struct passphrase_cb_info_s {
-    GpgmeCtx c;
-    int did_it;
-};
-
-void gpgmegtk_set_passphrase_grab (gint yesno);
-const char* gpgmegtk_passphrase_cb(void *opaque, const char *desc, void **r_hd);
-void gpgmegtk_free_passphrase (void);
-
-#endif /* GPGMEGTK_PASSPHRASE_H */
index e0922667ce8b809ce3c08586028476b803bd67cc..f22781711cc307121d675fa7cc3ccacfd24fd01c 100644 (file)
@@ -3,9 +3,20 @@ plugindir = $(pkglibdir)/plugins
 plugin_LTLIBRARIES = pgpmime.la
 
 pgpmime_la_SOURCES = \
+       passphrase.c \
        plugin.c \
-       pgpmime.c pgpmime.h \
-       sgpgme.c sgpgme.h
+       pgpmime.c \
+       prefs_gpg.c \
+       select-keys.c \
+       sgpgme.c
+
+pluginincludedir = $(pkgincludedir)/plugins/pgpmime
+plugininclude_HEADERS = \
+       passphrase.h \
+       pgpmime.h \
+       prefs_gpg.h \
+       select-keys.h \
+       sgpgme.h
 
 pgpmime_la_LDFLAGS = \
        -avoid-version -module
index adf762620361e56b2cbbd689f4e3f958ad30f918..24fdfa52c48facecea1365f30f0392a33f14fbc4 100644 (file)
@@ -27,7 +27,6 @@
 #include <sys/mman.h>
 #include <glib.h>
 #include <gdk/gdkkeysyms.h>
-#include <gdk/gdkx.h>  /* GDK_DISPLAY() */
 #include <gtk/gtkmain.h>
 #include <gtk/gtkwidget.h>
 #include <gtk/gtkwindow.h>
@@ -39,6 +38,9 @@
 #include <gtk/gtkbutton.h>
 #include <gtk/gtkfilesel.h>
 #include <gtk/gtksignal.h>
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>  /* GDK_DISPLAY() */
+#endif /* GDK_WINDOWING_X11 */
 
 #include "intl.h"
 #include "passphrase.h"
@@ -58,8 +60,8 @@ static void passphrase_ok_cb(GtkWidget *widget, gpointer data);
 static void passphrase_cancel_cb(GtkWidget *widget, gpointer data);
 static gint passphrase_deleted(GtkWidget *widget, GdkEventAny *event,
                               gpointer data);
-static void passphrase_key_pressed(GtkWidget *widget, GdkEventKey *event,
-                                  gpointer data);
+static gboolean passphrase_key_pressed(GtkWidget *widget, GdkEventKey *event,
+                                      gpointer data);
 static gchar* passphrase_mbox (const gchar *desc);
 
 
@@ -83,18 +85,19 @@ passphrase_mbox (const gchar *desc)
     GtkWidget *pass_entry;
     GtkWidget *ok_button;
     GtkWidget *cancel_button;
+    gint       grab_result;
 
-    window = gtk_window_new(GTK_WINDOW_DIALOG);
+    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
     gtk_window_set_title(GTK_WINDOW(window), _("Passphrase"));
-    gtk_widget_set_usize(window, 450, -1);
+    gtk_widget_set_size_request(window, 450, -1);
     gtk_container_set_border_width(GTK_CONTAINER(window), 4);
     gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
     gtk_window_set_modal(GTK_WINDOW(window), TRUE);
-    gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE);
-    gtk_signal_connect(GTK_OBJECT(window), "delete_event",
-                       GTK_SIGNAL_FUNC(passphrase_deleted), NULL);
-    gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
-                       GTK_SIGNAL_FUNC(passphrase_key_pressed), NULL);
+    gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
+    g_signal_connect(G_OBJECT(window), "delete_event",
+                    G_CALLBACK(passphrase_deleted), NULL);
+    g_signal_connect(G_OBJECT(window), "key_press_event",
+                    G_CALLBACK(passphrase_key_pressed), NULL);
     MANAGE_WINDOW_SIGNALS_CONNECT(window);
     manage_window_set_transient(GTK_WINDOW(window));
 
@@ -128,7 +131,7 @@ passphrase_mbox (const gchar *desc)
 
     confirm_box = gtk_hbutton_box_new ();
     gtk_button_box_set_layout (GTK_BUTTON_BOX(confirm_box), GTK_BUTTONBOX_END);
-    gtk_button_box_set_spacing (GTK_BUTTON_BOX(confirm_box), 5);
+    gtk_box_set_spacing (GTK_BOX(confirm_box), 5);
 
     ok_button = gtk_button_new_with_label (_("OK"));
     GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
@@ -141,18 +144,18 @@ passphrase_mbox (const gchar *desc)
     gtk_box_pack_end(GTK_BOX(vbox), confirm_box, FALSE, FALSE, 0);
     gtk_widget_grab_default (ok_button);
 
-    gtk_signal_connect(GTK_OBJECT(ok_button), "clicked",
-                       GTK_SIGNAL_FUNC(passphrase_ok_cb), NULL);
-    gtk_signal_connect(GTK_OBJECT(pass_entry), "activate",
-                       GTK_SIGNAL_FUNC(passphrase_ok_cb), NULL);
-    gtk_signal_connect(GTK_OBJECT(cancel_button), "clicked",
-                       GTK_SIGNAL_FUNC(passphrase_cancel_cb), NULL);
+    g_signal_connect(G_OBJECT(ok_button), "clicked",
+                    G_CALLBACK(passphrase_ok_cb), NULL);
+    g_signal_connect(G_OBJECT(pass_entry), "activate",
+                    G_CALLBACK(passphrase_ok_cb), NULL);
+    g_signal_connect(G_OBJECT(cancel_button), "clicked",
+                    G_CALLBACK(passphrase_cancel_cb), NULL);
 
     if (grab_all)
-        gtk_object_set (GTK_OBJECT(window), "type", GTK_WINDOW_POPUP, NULL);
+        g_object_set (G_OBJECT(window), "type", GTK_WINDOW_POPUP, NULL);
     gtk_window_set_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER);
     if (grab_all)   
-        gtk_window_set_policy (GTK_WINDOW(window), FALSE, FALSE, TRUE);
+        gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
     
     gtk_widget_show_all(window);
 
@@ -160,18 +163,27 @@ passphrase_mbox (const gchar *desc)
     gtkut_editable_disable_im(GTK_EDITABLE(pass_entry));
 
     if (grab_all) {
+#ifdef GDK_WINDOWING_X11
         XGrabServer(GDK_DISPLAY());
-        if ( gdk_pointer_grab ( window->window, TRUE, 0,
+#endif /* GDK_WINDOWING_X11 */
+        if ( grab_result = gdk_pointer_grab ( window->window, TRUE, 0,
                                 NULL, NULL, GDK_CURRENT_TIME)) {
+#ifdef GDK_WINDOWING_X11
             XUngrabServer ( GDK_DISPLAY() );
-            g_warning ("OOPS: Could not grab mouse\n");
+#endif /* GDK_WINDOWING_X11 */
+            g_warning ("OOPS: Could not grab mouse (grab status %d)\n",
+                       grab_result);
             gtk_widget_destroy (window);
             return NULL;
         }
-        if ( gdk_keyboard_grab( window->window, FALSE, GDK_CURRENT_TIME )) {
+        if ( grab_result = gdk_keyboard_grab( window->window, FALSE, 
+                                               GDK_CURRENT_TIME )) {
             gdk_pointer_ungrab (GDK_CURRENT_TIME);
+#ifdef GDK_WINDOWING_X11
             XUngrabServer ( GDK_DISPLAY() );
-            g_warning ("OOPS: Could not grab keyboard\n");
+#endif /* GDK_WINDOWING_X11 */
+            g_warning ("OOPS: Could not grab keyboard (grab status %d)\n",
+                       grab_result);
             gtk_widget_destroy (window);
             return NULL;
         }
@@ -180,7 +192,9 @@ passphrase_mbox (const gchar *desc)
     gtk_main();
 
     if (grab_all) {
+#ifdef GDK_WINDOWING_X11
         XUngrabServer (GDK_DISPLAY());
+#endif /* GDK_WINDOWING_X11 */
         gdk_pointer_ungrab (GDK_CURRENT_TIME);
         gdk_keyboard_ungrab (GDK_CURRENT_TIME);
         gdk_flush();
@@ -189,9 +203,9 @@ passphrase_mbox (const gchar *desc)
     manage_window_focus_out(window, NULL, NULL);
 
     if (pass_ack) {
-        the_passphrase = gtk_entry_get_text(GTK_ENTRY(pass_entry));
-        if (the_passphrase) /* Hmmm: Do we really need this? */
-            the_passphrase = g_strdup (the_passphrase);
+        const gchar *entry_text = gtk_entry_get_text(GTK_ENTRY(pass_entry));
+        if (entry_text) /* Hmmm: Do we really need this? */
+            the_passphrase = g_strdup (entry_text);
     }
     gtk_widget_destroy (window);
 
@@ -222,11 +236,12 @@ passphrase_deleted(GtkWidget *widget, GdkEventAny *event, gpointer data)
 }
 
 
-static void 
+static gboolean
 passphrase_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
 {
     if (event && event->keyval == GDK_Escape)
         passphrase_cancel_cb(NULL, NULL);
+    return FALSE;
 }
 
 static gint 
index b7092f351ac7648ebe1793dc8c887b5a16799d27..947c5f94f2e5986170a680d47cc39c02bcb08066 100644 (file)
@@ -26,6 +26,7 @@
 #include "defs.h"
 #include <glib.h>
 #include <gpgme.h>
+#include <ctype.h>
 
 #include "utils.h"
 #include "privacy.h"
 #include "pgpmime.h"
 #include "sgpgme.h"
 #include "prefs_common.h"
+#include "prefs_gpg.h"
+#include "passphrase.h"
+
+extern struct GPGConfig prefs_gpg;
 
 typedef struct _PrivacyDataPGP PrivacyDataPGP;
 
@@ -119,15 +124,44 @@ static gboolean pgpmime_is_signed(MimeInfo *mimeinfo)
        return TRUE;
 }
 
+static gchar *get_canonical_content(FILE *fp, const gchar *boundary)
+{
+       gchar *ret;
+       GString *textbuffer;
+       guint boundary_len;
+       gchar buf[BUFFSIZE];
+
+       boundary_len = strlen(boundary);
+       while (fgets(buf, sizeof(buf), fp) != NULL)
+               if (IS_BOUNDARY(buf, boundary, boundary_len))
+                       break;
+
+       textbuffer = g_string_new("");
+       while (fgets(buf, sizeof(buf), fp) != NULL) {
+               gchar *buf2;
+
+               if (IS_BOUNDARY(buf, boundary, boundary_len))
+                       break;
+               
+               buf2 = canonicalize_str(buf);
+               g_string_append(textbuffer, buf2);
+               g_free(buf2);
+       }
+       g_string_truncate(textbuffer, textbuffer->len - 2);
+               
+       ret = textbuffer->str;
+       g_string_free(textbuffer, FALSE);
+
+       return ret;
+}
+
 static gint pgpmime_check_signature(MimeInfo *mimeinfo)
 {
        PrivacyDataPGP *data;
        MimeInfo *parent, *signature;
        FILE *fp;
-       gchar buf[BUFFSIZE];
        gchar *boundary;
-       GString *textstr;
-       gint boundary_len;
+       gchar *textstr;
        GpgmeData sigdata, textdata;
        
        g_return_val_if_fail(mimeinfo != NULL, -1);
@@ -140,29 +174,13 @@ static gint pgpmime_check_signature(MimeInfo *mimeinfo)
        fp = fopen(parent->filename, "rb");
        g_return_val_if_fail(fp != NULL, SIGNATURE_INVALID);
        
-       boundary = g_hash_table_lookup(parent->parameters, "boundary");
+       boundary = g_hash_table_lookup(parent->typeparameters, "boundary");
        if (!boundary)
                return 0;
 
-       boundary_len = strlen(boundary);
-       while (fgets(buf, sizeof(buf), fp) != NULL)
-               if (IS_BOUNDARY(buf, boundary, boundary_len))
-                       break;
+       textstr = get_canonical_content(fp, boundary);
 
-       textstr = g_string_new("");
-       while (fgets(buf, sizeof(buf), fp) != NULL) {
-               gchar *buf2;
-
-               if (IS_BOUNDARY(buf, boundary, boundary_len))
-                       break;
-               
-               buf2 = canonicalize_str(buf);
-               g_string_append(textstr, buf2);
-               g_free(buf2);
-       }
-       g_string_truncate(textstr, textstr->len - 2);
-               
-       gpgme_data_new_from_mem(&textdata, textstr->str, textstr->len, 0);
+       gpgme_data_new_from_mem(&textdata, textstr, strlen(textstr), 0);
        signature = (MimeInfo *) mimeinfo->node->next->data;
        sigdata = sgpgme_data_from_mimeinfo(signature);
 
@@ -171,7 +189,7 @@ static gint pgpmime_check_signature(MimeInfo *mimeinfo)
        
        gpgme_data_release(sigdata);
        gpgme_data_release(textdata);
-       g_string_free(textstr, TRUE);
+       g_free(textstr);
        fclose(fp);
        
        return 0;
@@ -184,7 +202,7 @@ static SignatureStatus pgpmime_get_sig_status(MimeInfo *mimeinfo)
        g_return_val_if_fail(data != NULL, SIGNATURE_INVALID);
 
        if (data->sigstatus == GPGME_SIG_STAT_NONE && 
-           prefs_common.auto_check_signatures)
+           prefs_gpg.auto_check_signatures)
                pgpmime_check_signature(mimeinfo);
        
        return sgpgme_sigstat_gpgme_to_privacy(data->ctx, data->sigstatus);
@@ -197,7 +215,7 @@ static gchar *pgpmime_get_sig_info_short(MimeInfo *mimeinfo)
        g_return_val_if_fail(data != NULL, g_strdup("Error"));
 
        if (data->sigstatus == GPGME_SIG_STAT_NONE && 
-           prefs_common.auto_check_signatures)
+           prefs_gpg.auto_check_signatures)
                pgpmime_check_signature(mimeinfo);
        
        return sgpgme_sigstat_info_short(data->ctx, data->sigstatus);
@@ -210,7 +228,7 @@ static gchar *pgpmime_get_sig_info_full(MimeInfo *mimeinfo)
        g_return_val_if_fail(data != NULL, g_strdup("Error"));
 
        if (data->sigstatus == GPGME_SIG_STAT_NONE && 
-           prefs_common.auto_check_signatures)
+           prefs_gpg.auto_check_signatures)
                pgpmime_check_signature(mimeinfo);
        
        return sgpgme_sigstat_info_full(data->ctx, data->sigstatus);
@@ -305,7 +323,7 @@ static MimeInfo *pgpmime_decrypt(MimeInfo *mimeinfo)
        g_node_unlink(decinfo->node);
        procmime_mimeinfo_free_all(parseinfo);
 
-       decinfo->tmpfile = TRUE;
+       decinfo->tmp = TRUE;
 
        if (sigstat != GPGME_SIG_STAT_NONE) {
                if (decinfo->privacy != NULL) {
@@ -320,12 +338,244 @@ static MimeInfo *pgpmime_decrypt(MimeInfo *mimeinfo)
                if (data->ctx)
                        gpgme_release(data->ctx);
                data->ctx = ctx;
-       } else 
+       } else
                gpgme_release(ctx);
 
        return decinfo;
 }
 
+/*
+ * Find TAG in XML and return a pointer into xml set just behind the
+ * closing angle.  Return NULL if not found. 
+ */
+static const char *
+find_xml_tag (const char *xml, const char *tag)
+{
+    int taglen = strlen (tag);
+    const char *s = xml;
+    while ( (s = strchr (s, '<')) ) {
+        s++;
+        if (!strncmp (s, tag, taglen)) {
+            const char *s2 = s + taglen;
+            if (*s2 == '>' || isspace (*(const unsigned char*)s2) ) {
+                /* found */
+                while (*s2 && *s2 != '>') /* skip attributes */
+                    s2++;
+                /* fixme: do need to handle angles inside attribute vallues? */
+                return *s2? (s2+1):NULL;
+            }
+        }
+        while (*s && *s != '>') /* skip to end of tag */
+            s++;
+    }
+    return NULL;
+}
+
+
+/*
+ * Extract the micalg from an GnupgOperationInfo XML container.
+ */
+static char *
+extract_micalg (char *xml)
+{
+    const char *s;
+
+    s = find_xml_tag (xml, "GnupgOperationInfo");
+    if (s) {
+        const char *s_end = find_xml_tag (s, "/GnupgOperationInfo");
+        s = find_xml_tag (s, "signature");
+        if (s && s_end && s < s_end) {
+            const char *s_end2 = find_xml_tag (s, "/signature");
+            if (s_end2 && s_end2 < s_end) {
+                s = find_xml_tag (s, "micalg");
+                if (s && s < s_end2) {
+                    s_end = strchr (s, '<');
+                    if (s_end) {
+                        char *p = g_malloc (s_end - s + 1);
+                        memcpy (p, s, s_end - s);
+                        p[s_end-s] = 0;
+                        return p;
+                    }
+                }
+            }
+        }
+    }
+    return NULL;
+}
+
+gboolean pgpmime_sign(MimeInfo *mimeinfo)
+{
+       MimeInfo *msgcontent, *sigmultipart, *newinfo;
+       gchar *textstr, *opinfo, *micalg;
+       FILE *fp;
+       gchar *boundary, *sigcontent;
+       GpgmeCtx ctx;
+       GpgmeData gpgtext, gpgsig;
+       guint len;
+       struct passphrase_cb_info_s info;
+  
+       memset (&info, 0, sizeof info);
+
+       /* remove content node from message */
+       msgcontent = (MimeInfo *) mimeinfo->node->children->data;
+       g_node_unlink(msgcontent->node);
+
+       /* create temporary multipart for content */
+       sigmultipart = procmime_mimeinfo_new();
+       sigmultipart->type = MIMETYPE_MULTIPART;
+       sigmultipart->subtype = g_strdup("signed");
+       boundary = generate_mime_boundary("Signature");
+       g_hash_table_insert(sigmultipart->typeparameters, g_strdup("boundary"),
+                            g_strdup(boundary));
+       g_hash_table_insert(sigmultipart->typeparameters, g_strdup("protocol"),
+                            g_strdup("application/pgp-signature"));
+       g_node_append(sigmultipart->node, msgcontent->node);
+       g_node_append(mimeinfo->node, sigmultipart->node);
+
+       /* write message content to temporary file */
+       fp = my_tmpfile();
+       procmime_write_mimeinfo(sigmultipart, fp);
+       rewind(fp);
+
+       /* read temporary file into memory */
+       textstr = get_canonical_content(fp, boundary);
+
+       fclose(fp);
+
+       gpgme_data_new_from_mem(&gpgtext, textstr, strlen(textstr), 0);
+       gpgme_data_new(&gpgsig);
+       gpgme_new(&ctx);
+       gpgme_set_textmode(ctx, 1);
+       gpgme_set_armor(ctx, 1);
+       gpgme_signers_clear(ctx);
+
+       if (!getenv("GPG_AGENT_INFO")) {
+               info.c = ctx;
+               gpgme_set_passphrase_cb (ctx, gpgmegtk_passphrase_cb, &info);
+           }
+
+       if (gpgme_op_sign(ctx, gpgtext, gpgsig, GPGME_SIG_MODE_DETACH) != GPGME_No_Error)
+               return FALSE;
+       opinfo = gpgme_get_op_info(ctx, 0);
+       micalg = extract_micalg(opinfo);
+       g_free(opinfo);
+
+       gpgme_release(ctx);
+       sigcontent = gpgme_data_release_and_get_mem(gpgsig, &len);
+       gpgme_data_release(gpgtext);
+       g_free(textstr);
+
+       /* add signature */
+       g_hash_table_insert(sigmultipart->typeparameters, g_strdup("micalg"),
+                            micalg);
+
+       newinfo = procmime_mimeinfo_new();
+       newinfo->type = MIMETYPE_APPLICATION;
+       newinfo->subtype = g_strdup("pgp-signature");
+       newinfo->content = MIMECONTENT_MEM;
+       newinfo->data = g_memdup(sigcontent, len + 1);
+       newinfo->data[len] = '\0';
+       g_node_append(sigmultipart->node, newinfo->node);
+
+       g_free(sigcontent);
+
+       return TRUE;
+}
+
+gchar *pgpmime_get_encrypt_data(GSList *recp_names)
+{
+       return sgpgme_get_encrypt_data(recp_names);
+}
+
+gboolean pgpmime_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data)
+{
+       MimeInfo *msgcontent, *encmultipart, *newinfo;
+       FILE *fp;
+       gchar *boundary, *enccontent;
+       guint len;
+       gchar *textstr;
+       GpgmeData gpgtext, gpgenc;
+       gchar **recipients, **nextrecp;
+       GpgmeRecipients recp;
+       GpgmeCtx ctx;
+
+       /* build GpgmeRecipients from encrypt_data */
+       recipients = g_strsplit(encrypt_data, " ", 0);
+       gpgme_recipients_new(&recp);
+       for (nextrecp = recipients; *nextrecp != NULL; nextrecp++) {
+               printf("%s\n", *nextrecp);
+               gpgme_recipients_add_name_with_validity(recp, *nextrecp,
+                                                       GPGME_VALIDITY_FULL);
+       }
+       g_strfreev(recipients);
+
+       debug_print("Encrypting message content\n");
+
+       /* remove content node from message */
+       msgcontent = (MimeInfo *) mimeinfo->node->children->data;
+       g_node_unlink(msgcontent->node);
+
+       /* create temporary multipart for content */
+       encmultipart = procmime_mimeinfo_new();
+       encmultipart->type = MIMETYPE_MULTIPART;
+       encmultipart->subtype = g_strdup("encrypted");
+       boundary = generate_mime_boundary("Encrypt");
+       g_hash_table_insert(encmultipart->typeparameters, g_strdup("boundary"),
+                            g_strdup(boundary));
+       g_hash_table_insert(encmultipart->typeparameters, g_strdup("protocol"),
+                            g_strdup("application/pgp-encrypted"));
+       g_node_append(encmultipart->node, msgcontent->node);
+
+       /* write message content to temporary file */
+       fp = my_tmpfile();
+       procmime_write_mimeinfo(encmultipart, fp);
+       rewind(fp);
+
+       /* read temporary file into memory */
+       textstr = get_canonical_content(fp, boundary);
+
+       fclose(fp);
+
+       /* encrypt data */
+       gpgme_data_new_from_mem(&gpgtext, textstr, strlen(textstr), 0);
+       gpgme_data_new(&gpgenc);
+       gpgme_new(&ctx);
+       gpgme_set_armor(ctx, 1);
+
+       gpgme_op_encrypt(ctx, recp, gpgtext, gpgenc);
+
+       gpgme_release(ctx);
+       enccontent = gpgme_data_release_and_get_mem(gpgenc, &len);
+       gpgme_recipients_release(recp);
+       gpgme_data_release(gpgtext);
+       g_free(textstr);
+
+       /* create encrypted multipart */
+       g_node_unlink(msgcontent->node);
+       procmime_mimeinfo_free_all(msgcontent);
+       g_node_append(mimeinfo->node, encmultipart->node);
+
+       newinfo = procmime_mimeinfo_new();
+       newinfo->type = MIMETYPE_APPLICATION;
+       newinfo->subtype = g_strdup("pgp-encrypted");
+       newinfo->content = MIMECONTENT_MEM;
+       newinfo->data = g_strdup("Version: 1\n");
+       g_node_append(encmultipart->node, newinfo->node);
+
+       newinfo = procmime_mimeinfo_new();
+       newinfo->type = MIMETYPE_APPLICATION;
+       newinfo->subtype = g_strdup("octet-stream");
+       newinfo->content = MIMECONTENT_MEM;
+       newinfo->data = g_memdup(enccontent, len + 1);
+       newinfo->data[len] = '\0';
+       g_node_append(encmultipart->node, newinfo->node);
+
+       g_free(enccontent);
+
+       return TRUE;
+}
+
 static PrivacySystem pgpmime_system = {
        "pgpmime",                      /* id */
        "PGP Mime",                     /* name */
@@ -340,6 +590,13 @@ static PrivacySystem pgpmime_system = {
 
        pgpmime_is_encrypted,           /* is_encrypted(MimeInfo *) */
        pgpmime_decrypt,                /* decrypt(MimeInfo *) */
+
+       TRUE,
+       pgpmime_sign,
+
+       TRUE,
+       pgpmime_get_encrypt_data,
+       pgpmime_encrypt,
 };
 
 void pgpmime_init()
index 130ae59a8cb210f319c72f328b86109ce2b0df9f..7e10f985cb805c22b87b5844bb56563d53e22007 100644 (file)
@@ -28,6 +28,7 @@
 #include "version.h"
 #include "sgpgme.h"
 #include "pgpmime.h"
+#include "prefs_gpg.h"
 
 gint plugin_init(gchar **error)
 {
@@ -43,12 +44,14 @@ gint plugin_init(gchar **error)
 
        sgpgme_init();
        pgpmime_init();
+       prefs_gpg_init();
 
        return 0;       
 }
 
 void plugin_done(void)
 {
+       prefs_gpg_init();
        pgpmime_done();
        sgpgme_done();
 }
index 00da2e04556de5c8d782d387d136c77137a0471b..0d09c845e10de89d26c7d96b0f75b2b0560a1a6c 100644 (file)
@@ -82,8 +82,8 @@ static void open_dialog (struct select_keys_s *sk);
 static void close_dialog (struct select_keys_s *sk);
 static gint delete_event_cb (GtkWidget *widget,
                              GdkEventAny *event, gpointer data);
-static void key_pressed_cb (GtkWidget *widget,
-                            GdkEventKey *event, gpointer data);
+static gboolean key_pressed_cb (GtkWidget *widget,
+                                GdkEventKey *event, gpointer data);
 static void showall_btn_cb (GtkWidget *widget, gpointer data);
 static void select_btn_cb (GtkWidget *widget, gpointer data);
 static void cancel_btn_cb (GtkWidget *widget, gpointer data);
@@ -267,15 +267,15 @@ create_dialog (struct select_keys_s *sk)
     const char *titles[N_COL_TITLES];
 
     g_assert (!sk->window);
-    window = gtk_window_new (GTK_WINDOW_DIALOG);
-    gtk_widget_set_usize (window, 520, 280);
+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    gtk_widget_set_size_request (window, 520, 280);
     gtk_container_set_border_width (GTK_CONTAINER (window), 8);
     gtk_window_set_title (GTK_WINDOW (window), _("Select Keys"));
     gtk_window_set_modal (GTK_WINDOW (window), TRUE);
-    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
-                        GTK_SIGNAL_FUNC (delete_event_cb), sk);
-    gtk_signal_connect (GTK_OBJECT (window), "key_press_event",
-                        GTK_SIGNAL_FUNC (key_pressed_cb), sk);
+    g_signal_connect (G_OBJECT (window), "delete_event",
+                     G_CALLBACK (delete_event_cb), sk);
+    g_signal_connect (G_OBJECT (window), "key_press_event",
+                     G_CALLBACK (key_pressed_cb), sk);
     MANAGE_WINDOW_SIGNALS_CONNECT (window);
 
     vbox = gtk_vbox_new (FALSE, 8);
@@ -310,12 +310,12 @@ create_dialog (struct select_keys_s *sk)
     gtk_clist_set_column_width (GTK_CLIST(clist), COL_EMAIL,    130);
     gtk_clist_set_column_width (GTK_CLIST(clist), COL_VALIDITY,  20);
     gtk_clist_set_selection_mode (GTK_CLIST(clist), GTK_SELECTION_BROWSE);
-    gtk_signal_connect (GTK_OBJECT(GTK_CLIST(clist)->column[COL_NAME].button),
-                       "clicked",
-                        GTK_SIGNAL_FUNC(sort_keys_name), sk);
-    gtk_signal_connect (GTK_OBJECT(GTK_CLIST(clist)->column[COL_EMAIL].button),
-                       "clicked",
-                        GTK_SIGNAL_FUNC(sort_keys_email), sk);
+    g_signal_connect (G_OBJECT(GTK_CLIST(clist)->column[COL_NAME].button),
+                     "clicked",
+                     G_CALLBACK(sort_keys_name), sk);
+    g_signal_connect (G_OBJECT(GTK_CLIST(clist)->column[COL_EMAIL].button),
+                     "clicked",
+                     G_CALLBACK(sort_keys_email), sk);
 
     hbox = gtk_hbox_new (FALSE, 8);
     gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
@@ -324,8 +324,8 @@ create_dialog (struct select_keys_s *sk)
     gtk_widget_show (showall_btn);
     gtk_box_pack_start (GTK_BOX (hbox), showall_btn, FALSE, FALSE, 0);
 
-    gtk_signal_connect (GTK_OBJECT (showall_btn), "clicked",
-                        GTK_SIGNAL_FUNC (showall_btn_cb), sk);
+    g_signal_connect(G_OBJECT (showall_btn), "clicked",
+                     G_CALLBACK(showall_btn_cb), sk);
 
     gtkut_button_set_create (&bbox, 
                              &select_btn, _("Select"),
@@ -334,12 +334,12 @@ create_dialog (struct select_keys_s *sk)
     gtk_box_pack_end (GTK_BOX (hbox), bbox, FALSE, FALSE, 0);
     gtk_widget_grab_default (select_btn);
 
-    gtk_signal_connect (GTK_OBJECT (select_btn), "clicked",
-                        GTK_SIGNAL_FUNC (select_btn_cb), sk);
-    gtk_signal_connect (GTK_OBJECT(cancel_btn), "clicked",
-                        GTK_SIGNAL_FUNC (cancel_btn_cb), sk);
-    gtk_signal_connect (GTK_OBJECT (other_btn), "clicked",
-                        GTK_SIGNAL_FUNC (other_btn_cb), sk);
+    g_signal_connect (G_OBJECT (select_btn), "clicked",
+                     G_CALLBACK (select_btn_cb), sk);
+    g_signal_connect (G_OBJECT(cancel_btn), "clicked",
+                     G_CALLBACK (cancel_btn_cb), sk);
+    g_signal_connect (G_OBJECT (other_btn), "clicked",
+                     G_CALLBACK (other_btn_cb), sk);
 
     vbox2 = gtk_vbox_new (FALSE, 4);
     gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
@@ -386,16 +386,17 @@ delete_event_cb (GtkWidget *widget, GdkEventAny *event, gpointer data)
 }
 
 
-static void 
+static gboolean 
 key_pressed_cb (GtkWidget *widget, GdkEventKey *event, gpointer data)
 {
     struct select_keys_s *sk = data;
 
-    g_return_if_fail (sk);
+    g_return_val_if_fail (sk, FALSE);
     if (event && event->keyval == GDK_Escape) {
         sk->okay = 0;
         gtk_main_quit ();
     }
+       return FALSE;
 }
 
 
index 8e0eca648b227da496304ccce10132942e96a6e1..80827d75b54999eb7901732b37dc5da208613570 100644 (file)
 #include "alertpanel.h"
 #include "passphrase.h"
 #include "intl.h"
+#include "prefs_gpg.h"
+#include "select-keys.h"
+
+extern struct GPGConfig prefs_gpg;
 
 static void idle_function_for_gpgme(void)
 {
@@ -244,7 +248,6 @@ GpgmeData sgpgme_decrypt_verify(GpgmeData cipher, GpgmeSigStat *status, GpgmeCtx
        struct passphrase_cb_info_s info;
        GpgmeData plain;
        GpgmeError err;
-       GpgmeSigStat sigstat;
 
        memset (&info, 0, sizeof info);
        
@@ -269,6 +272,39 @@ GpgmeData sgpgme_decrypt_verify(GpgmeData cipher, GpgmeSigStat *status, GpgmeCtx
        return plain;
 }
 
+gchar *sgpgme_get_encrypt_data(GSList *recp_names)
+{
+
+       GpgmeRecipients recp;
+       GString *encdata;
+       void *iter;
+       const gchar *recipient;
+       gchar *data;
+
+       recp = gpgmegtk_recipient_selection(recp_names);
+       if (recp == NULL)
+               return NULL;
+
+       if (gpgme_recipients_enum_open(recp, &iter) != GPGME_No_Error) {
+               gpgme_recipients_release(recp);
+               return NULL;
+       }
+
+       encdata = g_string_sized_new(64);
+       while ((recipient = gpgme_recipients_enum_read(recp, &iter)) != NULL) {
+               if (encdata->len > 0)
+                       g_string_append_c(encdata, ' ');
+               g_string_append(encdata, recipient);
+       }
+
+       gpgme_recipients_release(recp);
+
+       data = encdata->str;
+       g_string_free(encdata, FALSE);
+
+       return data;
+}
+
 void sgpgme_init()
 {
        if (gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP) != 
@@ -277,7 +313,7 @@ void sgpgme_init()
                debug_print("gpgme_engine_version:\n%s\n",
                            gpgme_get_engine_info());
 
-               if (prefs_common.gpg_warning) {
+               if (prefs_gpg.gpg_warning) {
                        AlertValue val;
 
                        val = alertpanel_message_with_disable
@@ -286,7 +322,7 @@ void sgpgme_init()
                                   "to be upgraded.\n"
                                   "OpenPGP support disabled."), ALERT_WARNING);
                        if (val & G_ALERTDISABLE)
-                               prefs_common.gpg_warning = FALSE;
+                               prefs_gpg.gpg_warning = FALSE;
                }
        }
 
@@ -296,6 +332,7 @@ void sgpgme_init()
 void sgpgme_done()
 {
         gpgmegtk_free_passphrase();
+       gpgme_register_idle(NULL);
 }
 
 #endif /* USE_GPGME */
index c380ef4ac50d2cbba7dea7f28b3a659f5c651ee5..70f86a24193d5ff35dae9284e7e9fd10341f4d00 100644 (file)
@@ -40,5 +40,6 @@ gchar *sgpgme_sigstat_info_full               (GpgmeCtx ctx,
 GpgmeData sgpgme_data_from_mimeinfo    (MimeInfo *mimeinfo);
 GpgmeData sgpgme_decrypt_verify                (GpgmeData cipher, GpgmeSigStat *status,
                                         GpgmeCtx ctx);
+gchar *sgpgme_get_encrypt_data         (GSList *recp_names);
 
 #endif /* SGPGME_H */
index 90cc7159e0939cd672ca21232a5fb83caf512683..146ddcd3f36c79bc8dd7226841dba293d45b2f5b 100644 (file)
@@ -135,18 +135,10 @@ static struct Compose {
        GtkWidget *autoreplyto_entry;
 } compose;
 
-#if USE_GPGME
 static struct Privacy {
        GtkWidget *default_encrypt_chkbtn;
        GtkWidget *default_sign_chkbtn;
-       GtkWidget *gnupg_mime_radiobtn;
-       GtkWidget *gnupg_inline_radiobtn;
-       GtkWidget *defaultkey_radiobtn;
-       GtkWidget *emailkey_radiobtn;
-       GtkWidget *customkey_radiobtn;
-       GtkWidget *customkey_entry;
 } privacy;
-#endif /* USE_GPGME */
 
 #if USE_OPENSSL
 static struct SSLPrefs {
@@ -219,10 +211,6 @@ static void prefs_account_smtp_auth_type_set_optmenu       (PrefParam *pparam);
 static void prefs_account_enum_set_data_from_radiobtn  (PrefParam *pparam);
 static void prefs_account_enum_set_radiobtn            (PrefParam *pparam);
 
-#if USE_GPGME
-static void prefs_account_gnupg_inline_warning         (GtkWidget *widget);
-#endif /* USE_GPGME */
-
 static void prefs_account_crosspost_set_data_from_colormenu(PrefParam *pparam);
 static void prefs_account_crosspost_set_colormenu(PrefParam *pparam);
 
@@ -402,7 +390,6 @@ static PrefParam param[] = {
         &compose.autoreplyto_entry,
         prefs_set_data_from_entry, prefs_set_entry},
 
-#if USE_GPGME
        /* Privacy */
        {"default_encrypt", "FALSE", &tmp_ac_prefs.default_encrypt, P_BOOL,
         &privacy.default_encrypt_chkbtn,
@@ -410,18 +397,6 @@ static PrefParam param[] = {
        {"default_sign", "FALSE", &tmp_ac_prefs.default_sign, P_BOOL,
         &privacy.default_sign_chkbtn,
         prefs_set_data_from_toggle, prefs_set_toggle},
-       {"default_gnupg_mode", NULL, &tmp_ac_prefs.default_gnupg_mode, P_ENUM,
-        &privacy.gnupg_mime_radiobtn,
-        prefs_account_enum_set_data_from_radiobtn,
-        prefs_account_enum_set_radiobtn},
-       {"sign_key", NULL, &tmp_ac_prefs.sign_key, P_ENUM,
-        &privacy.defaultkey_radiobtn,
-        prefs_account_enum_set_data_from_radiobtn,
-        prefs_account_enum_set_radiobtn},
-       {"sign_key_id", NULL, &tmp_ac_prefs.sign_key_id, P_STRING,
-        &privacy.customkey_entry,
-        prefs_set_data_from_entry, prefs_set_entry},
-#endif /* USE_GPGME */
 
 #if USE_OPENSSL
        /* SSL */
@@ -539,9 +514,7 @@ static void prefs_account_basic_create              (void);
 static void prefs_account_receive_create       (void);
 static void prefs_account_send_create          (void);
 static void prefs_account_compose_create       (void);
-#if USE_GPGME
 static void prefs_account_privacy_create       (void);
-#endif /* USE_GPGME */
 #if USE_OPENSSL
 static void prefs_account_ssl_create           (void);
 #endif /* USE_OPENSSL */
@@ -766,10 +739,8 @@ static void prefs_account_create(void)
        SET_NOTEBOOK_LABEL(dialog.notebook, _("Send"), page++);
        prefs_account_compose_create();
        SET_NOTEBOOK_LABEL(dialog.notebook, _("Compose"), page++);
-#if USE_GPGME
        prefs_account_privacy_create();
        SET_NOTEBOOK_LABEL(dialog.notebook, _("Privacy"), page++);
-#endif /* USE_GPGME */
 #if USE_OPENSSL
        prefs_account_ssl_create();
        SET_NOTEBOOK_LABEL(dialog.notebook, _("SSL"), page++);
@@ -1659,7 +1630,6 @@ static void prefs_account_compose_create(void)
        compose.autoreplyto_entry  = autoreplyto_entry;
 }
 
-#if USE_GPGME
 static void prefs_account_privacy_create(void)
 {
        GtkWidget *vbox1;
@@ -1692,102 +1662,9 @@ static void prefs_account_privacy_create(void)
        PACK_CHECK_BUTTON (vbox2, default_sign_chkbtn,
                           _("Sign message by default"));
                            
-       PACK_FRAME (vbox1, frame_mode, _("Default mode"));
-       
-       vbox_mode = gtk_vbox_new (FALSE, 0);
-       gtk_widget_show (vbox_mode);
-       gtk_container_add (GTK_CONTAINER (frame_mode), vbox_mode);
-       gtk_container_set_border_width (GTK_CONTAINER (vbox_mode), 8);
-
-       gnupg_mime_radiobtn = gtk_radio_button_new_with_label
-               (NULL, _("Use PGP/MIME"));
-       gtk_widget_show (gnupg_mime_radiobtn);
-       gtk_box_pack_start (GTK_BOX (vbox_mode), gnupg_mime_radiobtn,
-                           FALSE, FALSE, 0);
-       g_object_set_data (G_OBJECT (gnupg_mime_radiobtn), 
-                          MENU_VAL_ID,
-                          GINT_TO_POINTER (GNUPG_MODE_DETACH));
-
-       gnupg_inline_radiobtn = gtk_radio_button_new_with_label_from_widget
-               (GTK_RADIO_BUTTON (gnupg_mime_radiobtn),
-                _("Use Inline"));
-       gtk_widget_show (gnupg_inline_radiobtn);
-       gtk_box_pack_start (GTK_BOX (vbox_mode), gnupg_inline_radiobtn,
-                           FALSE, FALSE, 0);
-       g_object_set_data(G_OBJECT (gnupg_inline_radiobtn), 
-                         MENU_VAL_ID,
-                         GINT_TO_POINTER (GNUPG_MODE_INLINE));
-       g_signal_connect (G_OBJECT (gnupg_inline_radiobtn), "clicked",
-                         G_CALLBACK(prefs_account_gnupg_inline_warning), 
-                         NULL);
-
-
-       PACK_FRAME (vbox1, frame1, _("Sign key"));
-
-       vbox2 = gtk_vbox_new (FALSE, 0);
-       gtk_widget_show (vbox2);
-       gtk_container_add (GTK_CONTAINER (frame1), vbox2);
-       gtk_container_set_border_width (GTK_CONTAINER (vbox2), 8);
-
-       defaultkey_radiobtn = gtk_radio_button_new_with_label
-               (NULL, _("Use default GnuPG key"));
-       gtk_widget_show (defaultkey_radiobtn);
-       gtk_box_pack_start (GTK_BOX (vbox2), defaultkey_radiobtn,
-                           FALSE, FALSE, 0);
-       g_object_set_data (G_OBJECT (defaultkey_radiobtn),
-                          MENU_VAL_ID,
-                          GINT_TO_POINTER (SIGN_KEY_DEFAULT));
-
-       emailkey_radiobtn = gtk_radio_button_new_with_label_from_widget
-               (GTK_RADIO_BUTTON (defaultkey_radiobtn),
-                _("Select key by your email address"));
-       gtk_widget_show (emailkey_radiobtn);
-       gtk_box_pack_start (GTK_BOX (vbox2), emailkey_radiobtn,
-                           FALSE, FALSE, 0);
-       g_object_set_data (G_OBJECT (emailkey_radiobtn),
-                          MENU_VAL_ID,
-                          GINT_TO_POINTER (SIGN_KEY_BY_FROM));
-
-       customkey_radiobtn = gtk_radio_button_new_with_label_from_widget
-               (GTK_RADIO_BUTTON (defaultkey_radiobtn),
-                _("Specify key manually"));
-       gtk_widget_show (customkey_radiobtn);
-       gtk_box_pack_start (GTK_BOX (vbox2), customkey_radiobtn,
-                           FALSE, FALSE, 0);
-       g_object_set_data (G_OBJECT (customkey_radiobtn),
-                          MENU_VAL_ID,
-                          GINT_TO_POINTER (SIGN_KEY_CUSTOM));
-
-       hbox1 = gtk_hbox_new (FALSE, 8);
-       gtk_widget_show (hbox1);
-       gtk_box_pack_start (GTK_BOX (vbox2), hbox1, FALSE, FALSE, 0);
-
-       label = gtk_label_new ("");
-       gtk_widget_show (label);
-       gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, FALSE, 0);
-       gtk_widget_set_size_request (label, 16, -1);
-
-       label = gtk_label_new (_("User or key ID:"));
-       gtk_widget_show (label);
-       gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, FALSE, 0);
-
-       customkey_entry = gtk_entry_new ();
-       gtk_widget_show (customkey_entry);
-       gtk_box_pack_start (GTK_BOX (hbox1), customkey_entry,
-                           TRUE, TRUE, 0);
-
-       SET_TOGGLE_SENSITIVITY (customkey_radiobtn, customkey_entry);
-
        privacy.default_encrypt_chkbtn = default_encrypt_chkbtn;
        privacy.default_sign_chkbtn    = default_sign_chkbtn;
-       privacy.gnupg_mime_radiobtn    = gnupg_mime_radiobtn;
-       privacy.gnupg_inline_radiobtn  = gnupg_inline_radiobtn;
-       privacy.defaultkey_radiobtn    = defaultkey_radiobtn;
-       privacy.emailkey_radiobtn      = emailkey_radiobtn;
-       privacy.customkey_radiobtn     = customkey_radiobtn;
-       privacy.customkey_entry        = customkey_entry;
 }
-#endif /* USE_GPGME */
 
 #if USE_OPENSSL
 
@@ -2367,18 +2244,6 @@ static void prefs_account_enum_set_radiobtn(PrefParam *pparam)
        }
 }
 
-#if USE_GPGME
-static void prefs_account_gnupg_inline_warning(GtkWidget *widget)
-{
-       if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) &&
-           gtk_notebook_get_current_page(GTK_NOTEBOOK(dialog.notebook)) > 0)
-               alertpanel_warning
-                       (_("Its not recommended to use the old style Inline\n"
-                          "mode for GnuPG messages. It doesn't comply with\n"
-                          "RFC 3156 - MIME Security with OpenPGP."));
-}
-#endif /* USE_GPGME */
-
 static void prefs_account_protocol_set_data_from_optmenu(PrefParam *pparam)
 {
        GtkWidget *menu;
index 10987599b003dd561d9c59741fd6436d854d0104..3a6cd3294309f72ab0887184bf1ad8c5eda818e6 100644 (file)
@@ -42,19 +42,6 @@ typedef enum {
        SIG_DIRECT
 } SigType;
 
-#if USE_GPGME
-typedef enum {
-       SIGN_KEY_DEFAULT,
-       SIGN_KEY_BY_FROM,
-       SIGN_KEY_CUSTOM
-} SignKeyType;
-
-typedef enum {
-       GNUPG_MODE_DETACH,
-       GNUPG_MODE_INLINE
-} DefaultGnuPGMode;
-#endif /* USE_GPGME */
-
 #include <glib.h>
 
 #include "smtp.h"
@@ -139,14 +126,9 @@ struct _PrefsAccount
        gboolean  set_autoreplyto;
        gchar    *auto_replyto;
 
-#if USE_GPGME
        /* Privacy */
        gboolean default_encrypt;
        gboolean default_sign;
-       gboolean default_gnupg_mode;
-       SignKeyType sign_key;
-       gchar *sign_key_id;
-#endif /* USE_GPGME */
 
        /* Advanced */
        gboolean  set_smtpport;
index bd369b9cfd3d8ee6887683a7ba499756c8273710..910bff44c7d6b6913701c011d3a182ce6b895388 100644 (file)
@@ -152,17 +152,6 @@ static struct Message {
        GtkWidget *chkbtn_attach_desc;
 } message;
 
-#if USE_GPGME
-static struct Privacy {
-       GtkWidget *checkbtn_auto_check_signatures;
-       GtkWidget *checkbtn_store_passphrase;
-       GtkWidget *spinbtn_store_passphrase;
-       GtkObject *spinbtn_store_passphrase_adj;
-       GtkWidget *checkbtn_passphrase_grab;
-       GtkWidget *checkbtn_gpg_warning;
-} privacy;
-#endif
-
 static struct Interface {
        /* GtkWidget *checkbtn_emacs; */
        GtkWidget *checkbtn_always_show_msg;
@@ -635,29 +624,6 @@ static PrefParam param[] = {
        {"mime_open_command", "gedit '%s'",
         &prefs_common.mime_open_cmd, P_STRING, NULL, NULL, NULL},
 
-#if USE_GPGME
-       /* Privacy */
-       {"auto_check_signatures", "TRUE",
-        &prefs_common.auto_check_signatures, P_BOOL,
-        &privacy.checkbtn_auto_check_signatures,
-        prefs_set_data_from_toggle, prefs_set_toggle},
-       {"store_passphrase", "FALSE", &prefs_common.store_passphrase, P_BOOL,
-        &privacy.checkbtn_store_passphrase,
-        prefs_set_data_from_toggle, prefs_set_toggle},
-       {"store_passphrase_timeout", "0",
-        &prefs_common.store_passphrase_timeout, P_INT,
-        &privacy.spinbtn_store_passphrase,
-        prefs_set_data_from_spinbtn, prefs_set_spinbtn},
-#ifndef __MINGW32__
-       {"passphrase_grab", "FALSE", &prefs_common.passphrase_grab, P_BOOL,
-        &privacy.checkbtn_passphrase_grab,
-        prefs_set_data_from_toggle, prefs_set_toggle},
-#endif /* __MINGW32__ */
-       {"gpg_warning", "TRUE", &prefs_common.gpg_warning, P_BOOL,
-        &privacy.checkbtn_gpg_warning,
-        prefs_set_data_from_toggle, prefs_set_toggle},
-#endif /* USE_GPGME */
-
        /* Interface */
        {"separate_folder", "FALSE", &prefs_common.sep_folder, P_BOOL,
         NULL, NULL, NULL},
@@ -769,9 +735,6 @@ static void prefs_compose_create    (void);
 static void prefs_quote_create         (void);
 static void prefs_display_create       (void);
 static void prefs_message_create       (void);
-#if USE_GPGME
-static void prefs_privacy_create       (void);
-#endif
 static void prefs_interface_create     (void);
 static void prefs_other_create         (void);
 
@@ -957,10 +920,6 @@ static void prefs_common_create(void)
        SET_NOTEBOOK_LABEL(dialog.notebook, _("Display"),   page++);
        prefs_message_create();
        SET_NOTEBOOK_LABEL(dialog.notebook, _("Message"),   page++);
-#if USE_GPGME
-       prefs_privacy_create();
-       SET_NOTEBOOK_LABEL(dialog.notebook, _("Privacy"),   page++);
-#endif
        prefs_interface_create();
        SET_NOTEBOOK_LABEL(dialog.notebook, _("Interface"), page++);
        prefs_other_create();
@@ -1901,108 +1860,6 @@ static void prefs_message_create(void)
        message.chkbtn_attach_desc  = chkbtn_attach_desc;
 }
 
-#if USE_GPGME
-static void prefs_privacy_create(void)
-{
-       GtkWidget *vbox1;
-       GtkWidget *vbox2;
-       GtkWidget *vbox3;
-       GtkWidget *hbox1;
-       GtkWidget *hbox_spc;
-       GtkWidget *label;
-       GtkWidget *checkbtn_auto_check_signatures;
-       GtkWidget *checkbtn_store_passphrase;
-       GtkObject *spinbtn_store_passphrase_adj;
-       GtkWidget *spinbtn_store_passphrase;
-       GtkTooltips *store_tooltip;
-       GtkWidget *checkbtn_passphrase_grab;
-       GtkWidget *checkbtn_gpg_warning;
-
-       vbox1 = gtk_vbox_new (FALSE, VSPACING);
-       gtk_widget_show (vbox1);
-       gtk_container_add (GTK_CONTAINER (dialog.notebook), vbox1);
-       gtk_container_set_border_width (GTK_CONTAINER (vbox1), VBOX_BORDER);
-
-       vbox2 = gtk_vbox_new (FALSE, 0);
-       gtk_widget_show (vbox2);
-       gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, FALSE, 0);
-
-       PACK_CHECK_BUTTON (vbox2, checkbtn_auto_check_signatures,
-                          _("Automatically check signatures"));
-
-       PACK_CHECK_BUTTON (vbox2, checkbtn_store_passphrase,
-                          _("Store passphrase in memory temporarily"));
-
-       vbox3 = gtk_vbox_new (FALSE, 0);
-       gtk_widget_show (vbox3);
-       gtk_box_pack_start (GTK_BOX (vbox2), vbox3, FALSE, FALSE, 0);
-
-       hbox1 = gtk_hbox_new (FALSE, 8);
-       gtk_widget_show (hbox1);
-       gtk_box_pack_start (GTK_BOX (vbox3), hbox1, FALSE, FALSE, 0);
-
-       hbox_spc = gtk_hbox_new (FALSE, 0);
-       gtk_widget_show (hbox_spc);
-       gtk_box_pack_start (GTK_BOX (hbox1), hbox_spc, FALSE, FALSE, 0);
-       gtk_widget_set_size_request (hbox_spc, 12, -1);
-
-       label = gtk_label_new (_("Expire after"));
-       gtk_widget_show (label);
-       gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, FALSE, 0);
-
-       store_tooltip = gtk_tooltips_new();
-
-       spinbtn_store_passphrase_adj = gtk_adjustment_new (0, 0, 1440, 1, 5, 5);
-       spinbtn_store_passphrase = gtk_spin_button_new
-               (GTK_ADJUSTMENT (spinbtn_store_passphrase_adj), 1, 0);
-       gtk_widget_show (spinbtn_store_passphrase);
-       gtk_tooltips_set_tip(GTK_TOOLTIPS(store_tooltip), spinbtn_store_passphrase,
-                            _("Setting to '0' will store the passphrase"
-                              " for the whole session"),
-                            NULL);
-       gtk_box_pack_start (GTK_BOX (hbox1), spinbtn_store_passphrase, FALSE, FALSE, 0);
-       gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbtn_store_passphrase),
-                                    TRUE);
-       gtk_widget_set_size_request (spinbtn_store_passphrase, 64, -1);
-
-       label = gtk_label_new (_("minute(s) "));
-       gtk_widget_show (label);
-       gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, FALSE, 0);
-
-       hbox1 = gtk_hbox_new (FALSE, 8);
-       gtk_widget_show (hbox1);
-       gtk_box_pack_start (GTK_BOX (vbox3), hbox1, FALSE, FALSE, 0);
-
-       hbox_spc = gtk_hbox_new (FALSE, 0);
-       gtk_widget_show (hbox_spc);
-       gtk_box_pack_start (GTK_BOX (hbox1), hbox_spc, FALSE, FALSE, 0);
-       gtk_widget_set_size_request (hbox_spc, 12, -1);
-
-       SET_TOGGLE_SENSITIVITY (checkbtn_store_passphrase, vbox3);
-
-#ifndef __MINGW32__
-       PACK_CHECK_BUTTON (vbox2, checkbtn_passphrase_grab,
-                          _("Grab input while entering a passphrase"));
-#endif
-
-       PACK_CHECK_BUTTON
-               (vbox2, checkbtn_gpg_warning,
-                _("Display warning on startup if GnuPG doesn't work"));
-
-       hbox1 = gtk_hbox_new (FALSE, 8);
-       gtk_widget_show (hbox1);
-       gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, FALSE, 0);
-
-       privacy.checkbtn_auto_check_signatures
-                                            = checkbtn_auto_check_signatures;
-       privacy.checkbtn_store_passphrase    = checkbtn_store_passphrase;
-       privacy.spinbtn_store_passphrase     = spinbtn_store_passphrase;
-       privacy.spinbtn_store_passphrase_adj = spinbtn_store_passphrase_adj;
-       privacy.checkbtn_passphrase_grab     = checkbtn_passphrase_grab;
-       privacy.checkbtn_gpg_warning         = checkbtn_gpg_warning;
-}
-#endif /* USE_GPGME */
-
 static void prefs_interface_create(void)
 {
        GtkWidget *vbox1;
index 76a3cd1628dea01153e3f965d85f3afdbd2274a2..7220023eb70620a169c2eb2b6ee627a53ed25094 100644 (file)
@@ -225,3 +225,127 @@ gint privacy_mimeinfo_decrypt(MimeInfo *mimeinfo)
 
        return -1;
 }
+
+GSList *privacy_get_system_ids()
+{
+       GSList *cur;
+       GSList *ret = NULL;
+
+       for(cur = systems; cur != NULL; cur = g_slist_next(cur)) {
+               PrivacySystem *system = (PrivacySystem *) cur->data;
+
+               ret = g_slist_append(ret, g_strdup(system->id));
+       }
+
+       return ret;
+}
+
+static PrivacySystem *privacy_get_system(const gchar *id)
+{
+       GSList *cur;
+
+       g_return_val_if_fail(id != NULL, NULL);
+
+       for(cur = systems; cur != NULL; cur = g_slist_next(cur)) {
+               PrivacySystem *system = (PrivacySystem *) cur->data;
+
+               if(strcmp(id, system->id) == 0)
+                       return system;
+       }
+
+       return NULL;
+}
+
+const gchar *privacy_system_get_name(const gchar *id)
+{
+       PrivacySystem *system;
+
+       g_return_val_if_fail(id != NULL, NULL);
+
+       system = privacy_get_system(id);
+       if (system == NULL)
+               return NULL;
+
+       return system->name;
+}
+
+gboolean privacy_system_can_sign(const gchar *id)
+{
+       PrivacySystem *system;
+
+       g_return_val_if_fail(id != NULL, FALSE);
+
+       system = privacy_get_system(id);
+       if (system == NULL)
+               return FALSE;
+
+       return system->can_sign;
+}
+
+gboolean privacy_system_can_encrypt(const gchar *id)
+{
+       PrivacySystem *system;
+
+       g_return_val_if_fail(id != NULL, FALSE);
+
+       system = privacy_get_system(id);
+       if (system == NULL)
+               return FALSE;
+
+       return system->can_encrypt;
+}
+
+gboolean privacy_sign(const gchar *id, MimeInfo *target)
+{
+       PrivacySystem *system;
+
+       g_return_val_if_fail(id != NULL, FALSE);
+       g_return_val_if_fail(target != NULL, FALSE);
+
+       system = privacy_get_system(id);
+       if (system == NULL)
+               return FALSE;
+       if (!system->can_sign)
+               return FALSE;
+       if (system->sign == NULL)
+               return FALSE;
+
+       return system->sign(target);
+}
+
+gchar *privacy_get_encrypt_data(const gchar *id, GSList *recp_names)
+{
+       PrivacySystem *system;
+
+       g_return_val_if_fail(id != NULL, NULL);
+       g_return_val_if_fail(recp_names != NULL, NULL);
+
+       system = privacy_get_system(id);
+       if (system == NULL)
+               return FALSE;
+       if (!system->can_encrypt)
+               return FALSE;
+       if (system->get_encrypt_data == NULL)
+               return FALSE;
+
+       return system->get_encrypt_data(recp_names);
+}
+
+gboolean privacy_encrypt(const gchar *id, MimeInfo *mimeinfo, const gchar *encdata)
+{
+       PrivacySystem *system;
+
+       g_return_val_if_fail(id != NULL, FALSE);
+       g_return_val_if_fail(mimeinfo != NULL, FALSE);
+       g_return_val_if_fail(encdata != NULL, FALSE);
+
+       system = privacy_get_system(id);
+       if (system == NULL)
+               return FALSE;
+       if (!system->can_encrypt)
+               return FALSE;
+       if (system->encrypt == NULL)
+               return FALSE;
+
+       return system->encrypt(mimeinfo, encdata);
+}
index e77c66555e22b758d885b7eb52998af1bc242f99..c3222036f86beeb85387fe090c2dee534de05e57 100644 (file)
@@ -49,22 +49,43 @@ gchar *privacy_mimeinfo_sig_info_full               (MimeInfo *);
 gboolean privacy_mimeinfo_is_encrypted         (MimeInfo *);
 gint privacy_mimeinfo_decrypt                  (MimeInfo *);
 
+GSList *privacy_get_system_ids                 ();
+const gchar *privacy_system_get_name           (const gchar *);
+gboolean privacy_system_can_sign               (const gchar *);
+gboolean privacy_system_can_encrypt            (const gchar *);
+
+gboolean privacy_sign                          (const gchar *system,
+                                                MimeInfo    *mimeinfo);
+gchar *privacy_get_encrypt_data                        (const gchar *system,
+                                                GSList      *recp_names);
+gboolean privacy_encrypt                       (const gchar *system,
+                                                MimeInfo    *mimeinfo,
+                                                const gchar *encdata);
+
 struct _PrivacySystem {
        /** Identifier for the PrivacySystem that can use in config files */
        gchar            *id;
        /** Human readable name for the PrivacySystem for the user interface */
        gchar            *name;
 
-       void             (*free_privacydata)    (PrivacyData *);
+       void             (*free_privacydata)    (PrivacyData *data);
+
+       gboolean         (*is_signed)           (MimeInfo *mimeinfo);
+       gint             (*check_signature)     (MimeInfo *mimeinfo);
+       SignatureStatus  (*get_sig_status)      (MimeInfo *mimeinfo);
+       gchar           *(*get_sig_info_short)  (MimeInfo *mimeinfo);
+       gchar           *(*get_sig_info_full)   (MimeInfo *mimeinfo);
+
+       gboolean         (*is_encrypted)        (MimeInfo *mimeinfo);
+       MimeInfo        *(*decrypt)             (MimeInfo *mimeinfo);
 
-       gboolean         (*is_signed)           (MimeInfo *);
-       gint             (*check_signature)     (MimeInfo *);
-       SignatureStatus  (*get_sig_status)      (MimeInfo *);
-       gchar           *(*get_sig_info_short)  (MimeInfo *);
-       gchar           *(*get_sig_info_full)   (MimeInfo *);
+       gboolean           can_sign;
+       gboolean         (*sign)                (MimeInfo *mimeinfo);
 
-       gboolean         (*is_encrypted)        (MimeInfo *);
-       MimeInfo        *(*decrypt)             (MimeInfo *);
+       gboolean           can_encrypt;
+       gchar           *(*get_encrypt_data)    (GSList *recp_names);
+       gboolean         (*encrypt)             (MimeInfo *mimeinfo,
+                                                const gchar *encrypt_data);
 };
 
 struct _PrivacyData {
index b89338b28a16de29b73b3766cdf6d76600b35b46..157094d6e98e044098141e08d4f666d7e55c37f8 100644 (file)
@@ -55,12 +55,18 @@ MimeInfo *procmime_mimeinfo_new(void)
        MimeInfo *mimeinfo;
 
        mimeinfo = g_new0(MimeInfo, 1);
-       mimeinfo->type          = MIMETYPE_UNKNOWN;
-       mimeinfo->encoding_type = ENC_UNKNOWN;
-       mimeinfo->disposition   = DISPOSITIONTYPE_UNKNOWN;
+       mimeinfo->content        = MIMECONTENT_EMPTY;
+       mimeinfo->filename       = NULL;
+
+       mimeinfo->type           = MIMETYPE_UNKNOWN;
+       mimeinfo->encoding_type  = ENC_UNKNOWN;
+       mimeinfo->typeparameters = g_hash_table_new(g_str_hash, g_str_equal);
+
+       mimeinfo->disposition    = DISPOSITIONTYPE_UNKNOWN;
+       mimeinfo->dispositionparameters 
+                                = g_hash_table_new(g_str_hash, g_str_equal);
 
-       mimeinfo->parameters = g_hash_table_new(g_str_hash, g_str_equal);
-       mimeinfo->node       = g_node_new(mimeinfo);
+       mimeinfo->node           = g_node_new(mimeinfo);
        
        return mimeinfo;
 }
@@ -94,16 +100,30 @@ static gboolean free_func(GNode *node, gpointer data)
 {
        MimeInfo *mimeinfo = (MimeInfo *) node->data;
 
-       if (mimeinfo->tmpfile)
-               unlink(mimeinfo->filename);
-       g_free(mimeinfo->filename);
+       switch (mimeinfo->content) {
+       case MIMECONTENT_FILE:
+               if (mimeinfo->tmp)
+                       unlink(mimeinfo->filename);
+               g_free(mimeinfo->filename);
+               break;
+
+       case MIMECONTENT_MEM:
+               if (mimeinfo->tmp)
+                       g_free(mimeinfo->data);
+       default:
+               break;
+       }
 
        g_free(mimeinfo->subtype);
        g_free(mimeinfo->description);
        g_free(mimeinfo->id);
 
-       g_hash_table_foreach_remove(mimeinfo->parameters, procmime_mimeinfo_parameters_destroy, NULL);
-       g_hash_table_destroy(mimeinfo->parameters);
+       g_hash_table_foreach_remove(mimeinfo->typeparameters,
+               procmime_mimeinfo_parameters_destroy, NULL);
+       g_hash_table_destroy(mimeinfo->typeparameters);
+       g_hash_table_foreach_remove(mimeinfo->dispositionparameters,
+               procmime_mimeinfo_parameters_destroy, NULL);
+       g_hash_table_destroy(mimeinfo->dispositionparameters);
 
        if (mimeinfo->privacy)
                privacy_free_privacydata(mimeinfo->privacy);
@@ -234,10 +254,16 @@ enum
 
 const gchar *procmime_mimeinfo_get_parameter(MimeInfo *mimeinfo, const gchar *name)
 {
+       const gchar *value;
+
        g_return_val_if_fail(mimeinfo != NULL, NULL);
        g_return_val_if_fail(name != NULL, NULL);
+
+       value = g_hash_table_lookup(mimeinfo->dispositionparameters, name);
+       if (value == NULL)
+               value = g_hash_table_lookup(mimeinfo->typeparameters, name);
        
-       return g_hash_table_lookup(mimeinfo->parameters, name);
+       return value;
 }
 
 gboolean procmime_decode_content(MimeInfo *mimeinfo)
@@ -254,9 +280,8 @@ gboolean procmime_decode_content(MimeInfo *mimeinfo)
                   
        g_return_val_if_fail(mimeinfo != NULL, FALSE);
 
-       if (encoding == ENC_BINARY || 
-           encoding == ENC_7BIT ||
-           encoding == ENC_8BIT)
+       if (encoding == ENC_UNKNOWN ||
+           encoding == ENC_BINARY)
                return TRUE;
 
        infp = fopen(mimeinfo->filename, "rb");
@@ -324,11 +349,12 @@ gboolean procmime_decode_content(MimeInfo *mimeinfo)
        fclose(infp);
 
        stat(tmpfilename, &statbuf);
-       if (mimeinfo->tmpfile)
+       if (mimeinfo->tmp && (mimeinfo->filename != NULL))
                unlink(mimeinfo->filename);
-       g_free(mimeinfo->filename);
+       if (mimeinfo->filename != NULL)
+               g_free(mimeinfo->filename);
        mimeinfo->filename = tmpfilename;
-       mimeinfo->tmpfile = TRUE;
+       mimeinfo->tmp = TRUE;
        mimeinfo->offset = 0;
        mimeinfo->length = statbuf.st_size;
        mimeinfo->encoding_type = ENC_BINARY;
@@ -336,6 +362,81 @@ gboolean procmime_decode_content(MimeInfo *mimeinfo)
        return TRUE;
 }
 
+#define B64_LINE_SIZE          57
+#define B64_BUFFSIZE           77
+
+gboolean procmime_encode_content(MimeInfo *mimeinfo, EncodingType encoding)
+{
+       FILE *infp, *outfp;
+       gint len;
+       gchar *tmpfilename;
+       struct stat statbuf;
+
+       if (mimeinfo->encoding_type != ENC_UNKNOWN ||
+           mimeinfo->encoding_type != ENC_BINARY ||
+           mimeinfo->encoding_type != ENC_7BIT ||
+           mimeinfo->encoding_type != ENC_8BIT)
+               if(!procmime_decode_content(mimeinfo))
+                       return FALSE;
+
+       outfp = get_tmpfile_in_dir(get_mime_tmp_dir(), &tmpfilename);
+       if (!outfp) {
+               perror("tmpfile");
+               return FALSE;
+       }
+
+       if ((infp = fopen(mimeinfo->filename, "rb")) == NULL) {
+               g_warning("Can't open file %s\n", mimeinfo->filename);
+               return FALSE;
+       }
+
+       if (encoding == ENC_BASE64) {
+               gchar inbuf[B64_LINE_SIZE], outbuf[B64_BUFFSIZE];
+
+               while ((len = fread(inbuf, sizeof(gchar),
+                                   B64_LINE_SIZE, infp))
+                      == B64_LINE_SIZE) {
+                       base64_encode(outbuf, inbuf, B64_LINE_SIZE);
+                       fputs(outbuf, outfp);
+                       fputc('\n', outfp);
+               }
+               if (len > 0 && feof(infp)) {
+                       base64_encode(outbuf, inbuf, len);
+                       fputs(outbuf, outfp);
+                       fputc('\n', outfp);
+               }
+       } else if (encoding == ENC_QUOTED_PRINTABLE) {
+               gchar inbuf[BUFFSIZE], outbuf[BUFFSIZE * 4];
+
+               while (fgets(inbuf, sizeof(inbuf), infp) != NULL) {
+                       qp_encode_line(outbuf, inbuf);
+                       fputs(outbuf, outfp);
+               }
+       } else {
+               gchar buf[BUFFSIZE];
+
+               while (fgets(buf, sizeof(buf), infp) != NULL) {
+                       strcrchomp(buf);
+                       fputs(buf, outfp);
+               }
+       }
+
+       fclose(outfp);
+       fclose(infp);
+
+       stat(tmpfilename, &statbuf);
+       if (mimeinfo->tmp && (mimeinfo->filename != NULL))
+               unlink(mimeinfo->filename);
+       g_free(mimeinfo->filename);
+       mimeinfo->filename = tmpfilename;
+       mimeinfo->tmp = TRUE;
+       mimeinfo->offset = 0;
+       mimeinfo->length = statbuf.st_size;
+       mimeinfo->encoding_type = encoding;
+
+       return TRUE;
+}
+
 gint procmime_get_part(const gchar *outfile, MimeInfo *mimeinfo)
 {
        FILE *infp, *outfp;
@@ -957,7 +1058,7 @@ static struct TypeTable mime_type_table[] = {
        {NULL, 0},
 };
 
-const gchar *procmime_get_type_str(MimeMediaType type)
+const gchar *procmime_get_media_type_str(MimeMediaType type)
 {
        struct TypeTable *type_table;
        
@@ -968,6 +1069,17 @@ const gchar *procmime_get_type_str(MimeMediaType type)
        return NULL;
 }
 
+MimeMediaType procmime_get_media_type(const gchar *str)
+{
+       struct TypeTable *typetablearray;
+
+       for (typetablearray = mime_type_table; typetablearray->str != NULL; typetablearray++)
+               if (g_strncasecmp(str, typetablearray->str, strlen(typetablearray->str)) == 0)
+                       return typetablearray->type;
+
+       return MIMETYPE_UNKNOWN;
+}
+
 /*!
  *\brief       Safe wrapper for content type string.
  *
@@ -978,7 +1090,7 @@ gchar *procmime_get_content_type_str(MimeMediaType type,
 {
        const gchar *type_str = NULL;
 
-       if (subtype == NULL || !(type_str = procmime_get_type_str(type)))
+       if (subtype == NULL || !(type_str = procmime_get_media_type_str(type)))
                return g_strdup("unknown");
        return g_strdup_printf("%s/%s", type_str, subtype);
 }
@@ -1042,7 +1154,7 @@ void procmime_parse_message_rfc822(MimeInfo *mimeinfo)
                MimeInfo *subinfo;
 
                subinfo = procmime_mimeinfo_new();
-               subinfo->encoding_type = ENC_BINARY;
+               subinfo->encoding_type = ENC_UNKNOWN;
                subinfo->type = MIMETYPE_TEXT;
                subinfo->subtype = g_strdup("plain");
                subinfo->filename = g_strdup(mimeinfo->filename);
@@ -1075,7 +1187,7 @@ void procmime_parse_multipart(MimeInfo *mimeinfo)
        gchar buf[BUFFSIZE];
        FILE *fp;
 
-       boundary = g_hash_table_lookup(mimeinfo->parameters, "boundary");
+       boundary = g_hash_table_lookup(mimeinfo->typeparameters, "boundary");
        if (!boundary)
                return;
        boundary_len = strlen(boundary);
@@ -1099,7 +1211,7 @@ void procmime_parse_multipart(MimeInfo *mimeinfo)
                                                        hentry[2].body, hentry[3].body, 
                                                        hentry[4].body, 
                                                        mimeinfo->filename, lastoffset,
-                                                       (ftell(fp) - strlen(buf)) - lastoffset);
+                                                       (ftell(fp) - strlen(buf)) - lastoffset - 1);
                        }
                        
                        if (buf[2 + boundary_len]     == '-' &&
@@ -1127,7 +1239,7 @@ void procmime_parse_multipart(MimeInfo *mimeinfo)
        fclose(fp);
 }
 
-static void add_to_mimeinfo_parameters(gchar **parts, MimeInfo *mimeinfo)
+static void add_to_mimeinfo_parameters(gchar **parts, GHashTable *table)
 {
        gchar **strarray;
 
@@ -1145,9 +1257,8 @@ static void add_to_mimeinfo_parameters(gchar **parts, MimeInfo *mimeinfo)
                                extract_quote(parameters_parts[1], '"');
                        else if ((firstspace = strchr(parameters_parts[1], ' ')) != NULL)
                                *firstspace = '\0';
-                       if (g_hash_table_lookup(mimeinfo->parameters,
-                                              parameters_parts[0]) == NULL)
-                               g_hash_table_insert(mimeinfo->parameters,
+                       if (g_hash_table_lookup(table, parameters_parts[0]) == NULL)
+                               g_hash_table_insert(table,
                                                    g_strdup(parameters_parts[0]),
                                                    g_strdup(parameters_parts[1]));
                }
@@ -1160,7 +1271,6 @@ static void procmime_parse_content_type(const gchar *content_type, MimeInfo *mim
        gchar **content_type_parts;
        gchar **strarray;
        gchar *str;
-       struct TypeTable *typetablearray;
        
        g_return_if_fail(content_type != NULL);
        g_return_if_fail(mimeinfo != NULL);
@@ -1179,24 +1289,25 @@ static void procmime_parse_content_type(const gchar *content_type, MimeInfo *mim
        if ((str == NULL) || (str[0] == '\0') || (strchr(str, '/') == NULL)) {
                mimeinfo->type = MIMETYPE_TEXT;
                mimeinfo->subtype = g_strdup("plain");
-               if (g_hash_table_lookup(mimeinfo->parameters,
+               if (g_hash_table_lookup(mimeinfo->typeparameters,
                                       "charset") == NULL)
-                       g_hash_table_insert(mimeinfo->parameters,
+                       g_hash_table_insert(mimeinfo->typeparameters,
                                            g_strdup("charset"),
                                            g_strdup("us-ascii"));
        } else {
-               mimeinfo->type = MIMETYPE_UNKNOWN;
-               for (typetablearray = mime_type_table; typetablearray->str != NULL; typetablearray++) {
-                       if (g_strncasecmp(str, typetablearray->str, strlen(typetablearray->str)) == 0 &&
-                           str[strlen(typetablearray->str)] == '/') {
-                               mimeinfo->type = typetablearray->type;
-                               mimeinfo->subtype = g_strdup(str + strlen(typetablearray->str) + 1);
-                               break;
-                       }
-               }
+               gchar *type, *subtype;
+
+               type = g_strdup(str);
+               subtype = strchr(type, '/') + 1;
+               *(subtype - 1) = '\0';
+
+               mimeinfo->type = procmime_get_media_type(type);
+               mimeinfo->subtype = g_strdup(subtype);
+
+               g_free(type);
 
                /* Get mimeinfo->parmeters */
-               add_to_mimeinfo_parameters(&content_type_parts[1], mimeinfo);
+               add_to_mimeinfo_parameters(&content_type_parts[1], mimeinfo->typeparameters);
        }
 
        g_strfreev(content_type_parts);
@@ -1230,7 +1341,7 @@ static void procmime_parse_content_disposition(const gchar *content_disposition,
        else
                mimeinfo->disposition = DISPOSITIONTYPE_ATTACHMENT;
        
-       add_to_mimeinfo_parameters(&content_disp_parts[1], mimeinfo);
+       add_to_mimeinfo_parameters(&content_disp_parts[1], mimeinfo->dispositionparameters);
        g_strfreev(content_disp_parts);
 }
 
@@ -1263,6 +1374,7 @@ void procmime_parse_mimepart(MimeInfo *parent,
 
        /* Create MimeInfo */
        mimeinfo = procmime_mimeinfo_new();
+       mimeinfo->content = MIMECONTENT_FILE;
        if (parent != NULL)
                g_node_append(parent->node, mimeinfo->node);
        mimeinfo->filename = g_strdup(filename);
@@ -1274,15 +1386,15 @@ void procmime_parse_mimepart(MimeInfo *parent,
        } else {
                mimeinfo->type = MIMETYPE_TEXT;
                mimeinfo->subtype = g_strdup("plain");
-               if (g_hash_table_lookup(mimeinfo->parameters,
+               if (g_hash_table_lookup(mimeinfo->typeparameters,
                                       "charset") == NULL)
-                       g_hash_table_insert(mimeinfo->parameters, g_strdup("charset"), g_strdup("us-ascii"));
+                       g_hash_table_insert(mimeinfo->typeparameters, g_strdup("charset"), g_strdup("us-ascii"));
        }
 
        if (content_encoding != NULL) {
                procmime_parse_content_encoding(content_encoding, mimeinfo);
        } else {
-               mimeinfo->encoding_type = ENC_7BIT;
+               mimeinfo->encoding_type = ENC_UNKNOWN;
        }
 
        if (content_description != NULL)
@@ -1346,7 +1458,7 @@ static void output_mime_structure(MimeInfo *mimeinfo, int indent)
        g_node_traverse(mimeinfo->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, output_func, NULL);
 }
 
-static MimeInfo *procmime_scan_file_with_offset(const gchar *filename, int offset)
+MimeInfo *procmime_scan_file_with_offset(const gchar *filename, int offset)
 {
        MimeInfo *mimeinfo;
        struct stat buf;
@@ -1354,7 +1466,8 @@ static MimeInfo *procmime_scan_file_with_offset(const gchar *filename, int offse
        stat(filename, &buf);
 
        mimeinfo = procmime_mimeinfo_new();
-       mimeinfo->encoding_type = ENC_BINARY;
+       mimeinfo->content = MIMECONTENT_FILE;
+       mimeinfo->encoding_type = ENC_UNKNOWN;
        mimeinfo->type = MIMETYPE_MESSAGE;
        mimeinfo->subtype = g_strdup("rfc822");
        mimeinfo->filename = g_strdup(filename);
@@ -1368,7 +1481,7 @@ static MimeInfo *procmime_scan_file_with_offset(const gchar *filename, int offse
        return mimeinfo;
 }
 
-MimeInfo *procmime_scan_file(gchar *filename)
+MimeInfo *procmime_scan_file(const gchar *filename)
 {
        MimeInfo *mimeinfo;
 
@@ -1379,7 +1492,7 @@ MimeInfo *procmime_scan_file(gchar *filename)
        return mimeinfo;
 }
 
-MimeInfo *procmime_scan_queue_file(gchar *filename)
+MimeInfo *procmime_scan_queue_file(const gchar *filename)
 {
        FILE *fp;
        MimeInfo *mimeinfo;
@@ -1401,3 +1514,220 @@ MimeInfo *procmime_scan_queue_file(gchar *filename)
 
        return mimeinfo;
 }
+
+static void write_parameters(gpointer key, gpointer value, gpointer user_data)
+{
+       gchar *param = key;
+       gchar *val = value;
+       FILE *fp = user_data;
+
+       /* FIXME: better encoding of parameters */
+       fprintf(fp, "; %s=", param);
+       if (strchr(val, ' ') != NULL)
+               fprintf(fp, "\"%s\"", val);
+       else
+               fprintf(fp, "%s", val);
+}
+
+void procmime_write_mime_header(MimeInfo *mimeinfo, FILE *fp)
+{
+       struct TypeTable *type_table;
+
+       debug_print("procmime_write_mime_header\n");
+
+       for (type_table = mime_type_table; type_table->str != NULL; type_table++)
+               if (mimeinfo->type == type_table->type) {
+                       fprintf(fp, "Content-Type: %s/%s", type_table->str, mimeinfo->subtype);
+                       break;
+               }
+       g_hash_table_foreach(mimeinfo->typeparameters, write_parameters, fp);
+       fprintf(fp, "\n");
+
+       if (mimeinfo->encoding_type != ENC_UNKNOWN)
+               fprintf(fp, "Content-Transfer-Encoding: %s\n", procmime_get_encoding_str(mimeinfo->encoding_type));
+
+       if (mimeinfo->description != NULL)
+               fprintf(fp, "Content-Description: %s\n", mimeinfo->description);
+
+       if (mimeinfo->id != NULL)
+               fprintf(fp, "Content-ID: %s\n", mimeinfo->id);
+
+       if (mimeinfo->disposition != DISPOSITIONTYPE_UNKNOWN) {
+               fprintf(fp, "Content-Disposition: ");
+               if (mimeinfo->disposition == DISPOSITIONTYPE_INLINE)
+                       fprintf(fp, "inline");
+               else if (mimeinfo->disposition == DISPOSITIONTYPE_ATTACHMENT)
+                       fprintf(fp, "attachment");
+               else
+                       fprintf(fp, "unknown");
+
+               /* FIXME: linebreaks after too many parameters */
+               g_hash_table_foreach(mimeinfo->dispositionparameters, write_parameters, fp);
+               fprintf(fp, "\n");
+       }
+
+       fprintf(fp, "\n");
+}
+
+gint procmime_write_message_rfc822(MimeInfo *mimeinfo, FILE *fp)
+{
+       FILE *infp;
+       GNode *childnode;
+       MimeInfo *child;
+       gchar buf[BUFFSIZE];
+       gboolean skip = FALSE;;
+
+       debug_print("procmime_write_message_rfc822\n");
+
+       /* write header */
+       switch (mimeinfo->content) {
+       case MIMECONTENT_FILE:
+               if ((infp = fopen(mimeinfo->filename, "rb")) == NULL) {
+                       FILE_OP_ERROR(mimeinfo->filename, "fopen");
+                       return -1;
+               }
+               fseek(infp, mimeinfo->offset, SEEK_SET);
+               while (fgets(buf, sizeof(buf), infp) == buf) {
+                       if (buf[0] == '\n' && buf[1] == '\0')
+                               break;
+                       if (skip && (buf[0] == ' ' || buf[0] == '\t'))
+                               continue;
+                       if (g_strncasecmp(buf, "Mime-Version:", 13) == 0 ||
+                           g_strncasecmp(buf, "Content-Type:", 13) == 0 ||
+                           g_strncasecmp(buf, "Content-Transfer-Encoding:", 26) == 0 ||
+                           g_strncasecmp(buf, "Content-Description:", 20) == 0 ||
+                           g_strncasecmp(buf, "Content-ID:", 11) == 0 ||
+                           g_strncasecmp(buf, "Content-Disposition:", 20) == 0) {
+                               skip = TRUE;
+                               continue;
+                       }
+                       fwrite(buf, sizeof(gchar), strlen(buf), fp);
+                       skip = FALSE;
+               }
+               fclose(infp);
+               break;
+
+       case MIMECONTENT_MEM:
+               fwrite(mimeinfo->data, strlen(mimeinfo->data), sizeof(gchar), fp);
+               break;
+
+       default:
+               break;
+       }
+
+       childnode = mimeinfo->node->children;
+       if (childnode == NULL)
+               return -1;
+
+       child = (MimeInfo *) childnode->data;
+       fprintf(fp, "Mime-Version: 1.0\n");
+       procmime_write_mime_header(child, fp);
+       return procmime_write_mimeinfo(child, fp);
+}
+
+gint procmime_write_multipart(MimeInfo *mimeinfo, FILE *fp)
+{
+       FILE *infp;
+       GNode *childnode;
+       gchar *boundary, *str, *str2;
+       gchar buf[BUFFSIZE];
+       gboolean firstboundary;
+
+       debug_print("procmime_write_multipart\n");
+
+       boundary = g_hash_table_lookup(mimeinfo->typeparameters, "boundary");
+
+       switch (mimeinfo->content) {
+       case MIMECONTENT_FILE:
+               if ((infp = fopen(mimeinfo->filename, "rb")) == NULL) {
+                       FILE_OP_ERROR(mimeinfo->filename, "fopen");
+                       return -1;
+               }
+               fseek(infp, mimeinfo->offset, SEEK_SET);
+               while (fgets(buf, sizeof(buf), infp) == buf) {
+                       if (IS_BOUNDARY(buf, boundary, strlen(boundary)))
+                               break;
+                       fwrite(buf, sizeof(gchar), strlen(buf), fp);
+               }
+               fclose(infp);
+               break;
+
+       case MIMECONTENT_MEM:
+               str = g_strdup(mimeinfo->data);
+               if (((str2 = strstr(str, boundary)) != NULL) && ((str2 - str) >= 2) &&
+                   (*(str2 - 1) == '-') && (*(str2 - 2) == '-'))
+                       *(str2 - 2) = '\0';
+               fwrite(str, strlen(str), sizeof(gchar), fp);
+               g_free(str);
+               break;
+
+       default:
+               break;
+       }
+
+       childnode = mimeinfo->node->children;
+       firstboundary = TRUE;
+       while (childnode != NULL) {
+               MimeInfo *child = childnode->data;
+
+               if (firstboundary)
+                       firstboundary = FALSE;
+               else
+                       fprintf(fp, "\n");
+               fprintf(fp, "--%s\n", boundary);
+
+               procmime_write_mime_header(child, fp);
+               if (procmime_write_mimeinfo(child, fp) < 0)
+                       return -1;
+
+               childnode = g_node_next_sibling(childnode);
+       }       
+       fprintf(fp, "\n--%s--\n", boundary);
+
+       return 0;
+}
+
+gint procmime_write_mimeinfo(MimeInfo *mimeinfo, FILE *fp)
+{
+       FILE *infp;
+
+       debug_print("procmime_write_mimeinfo\n");
+
+       if (G_NODE_IS_LEAF(mimeinfo->node)) {
+               switch (mimeinfo->content) {
+               case MIMECONTENT_FILE:
+                       if ((infp = fopen(mimeinfo->filename, "rb")) == NULL) {
+                               FILE_OP_ERROR(mimeinfo->filename, "fopen");
+                               return -1;
+                       }
+                       copy_file_part_to_fp(infp, mimeinfo->offset, mimeinfo->length, fp);
+                       fclose(infp);
+                       return 0;
+
+               case MIMECONTENT_MEM:
+                       fwrite(mimeinfo->data, strlen(mimeinfo->data), sizeof(gchar), fp);
+                       return 0;
+
+               default:
+                       return 0;
+               }
+       } else {
+               /* Call writer for mime type */
+               switch (mimeinfo->type) {
+               case MIMETYPE_MESSAGE:
+                       if (g_strcasecmp(mimeinfo->subtype, "rfc822") == 0)
+                               return procmime_write_message_rfc822(mimeinfo, fp);
+                       break;
+                       
+               case MIMETYPE_MULTIPART:
+                       return procmime_write_multipart(mimeinfo, fp);
+                       
+               default:
+                       break;
+               }
+
+               return -1;
+       }
+
+       return 0;
+}
index c628d212e256cec722e3468dcc08960fbf25baea..354391bfbfce2d966e05084f4b4e8309610b4684 100644 (file)
@@ -54,9 +54,16 @@ typedef enum
 {
        DISPOSITIONTYPE_INLINE,
        DISPOSITIONTYPE_ATTACHMENT,
-       DISPOSITIONTYPE_UNKNOWN
+       DISPOSITIONTYPE_UNKNOWN,
 } DispositionType;
 
+typedef enum
+{
+       MIMECONTENT_EMPTY,
+       MIMECONTENT_FILE,               /* the file contains all content including sub parts */
+       MIMECONTENT_MEM,
+} MimeContent;
+
 #include <glib.h>
 #include <stdio.h>
 
@@ -94,8 +101,13 @@ struct _MimeType
 struct _MimeInfo
 {
        /* Internal data */
-       gchar *filename;
-       gboolean tmpfile;
+       MimeContent content;
+       union
+       {
+               gchar *filename;
+               gchar *data;
+       };
+       gboolean tmp;
 
        GNode *node;
 
@@ -104,7 +116,7 @@ struct _MimeInfo
        MimeMediaType    type;
        gchar           *subtype;
 
-       GHashTable      *parameters;
+       GHashTable      *typeparameters;
 
        /* Content-Transfer-Encoding */
        EncodingType     encoding_type;
@@ -120,6 +132,7 @@ struct _MimeInfo
 
        /* Content-Disposition */
        DispositionType  disposition;
+       GHashTable      *dispositionparameters;
 
        /* Privacy */
        PrivacyData     *privacy;
@@ -167,6 +180,7 @@ void procmime_scan_subject              (MimeInfo       *mimeinfo,
 MimeInfo *procmime_scan_mime_header    (FILE           *fp);
 
 gboolean procmime_decode_content       (MimeInfo       *mimeinfo);
+gboolean procmime_encode_content       (MimeInfo       *mimeinfo, EncodingType encoding);
 gint procmime_get_part                 (const gchar    *outfile,
                                         MimeInfo       *mimeinfo);
 FILE *procmime_get_text_content                (MimeInfo       *mimeinfo);
@@ -189,16 +203,20 @@ GList *procmime_get_mime_type_list        (void);
 EncodingType procmime_get_encoding_for_charset (const gchar    *charset);
 EncodingType procmime_get_encoding_for_file    (const gchar    *file);
 const gchar *procmime_get_encoding_str         (EncodingType    encoding);
-MimeInfo *procmime_scan_file                   (gchar          *filename);
-MimeInfo *procmime_scan_queue_file             (gchar          *filename);
-const gchar *procmime_get_type_str             (MimeMediaType   type);
-gchar *procmime_get_content_type_str           (MimeMediaType   type,
-                                                const char     *subtype);
+MimeInfo *procmime_scan_file                   (const gchar    *filename);
+MimeInfo *procmime_scan_queue_file             (const gchar    *filename);
+const gchar *procmime_get_media_type_str       (MimeMediaType   type);
+MimeMediaType procmime_get_media_type          (const gchar    *str);
+gchar *procmime_get_content_type_str           (MimeMediaType   type,
+                                                const gchar    *subtype);
 void procmime_force_charset                    (const gchar    *str);
 void procmime_force_encoding                   (EncodingType    encoding);
+
 void renderer_read_config(void);
 void renderer_write_config(void);
 
+gint procmime_write_mimeinfo(MimeInfo *mimeinfo, FILE *fp);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index a9d9d78c61d982fef61377303d11a650a267bb2f..c89b2cf4136a64fe7ba9e8639e9e6d62e68509ff 100644 (file)
@@ -1023,7 +1023,10 @@ enum
        Q_NEWS_ACCOUNT_ID  = 5,
        Q_SAVE_COPY_FOLDER = 6,
        Q_REPLY_MESSAGE_ID = 7,
-       Q_FWD_MESSAGE_ID   = 8
+       Q_FWD_MESSAGE_ID   = 8,
+       Q_PRIVACY_SYSTEM   = 9,
+       Q_ENCRYPT          = 10,
+       Q_ENCRYPT_DATA     = 11,
 };
 
 gint procmsg_send_message_queue(const gchar *file)
@@ -1037,6 +1040,9 @@ gint procmsg_send_message_queue(const gchar *file)
                                       {"SCF:",  NULL, FALSE},
                                       {"RMID:", NULL, FALSE},
                                       {"FMID:", NULL, FALSE},
+                                      {"X-Sylpheed-Privacy-System:", NULL, FALSE},
+                                      {"X-Sylpheed-Encrypt:", NULL, FALSE},
+                                      {"X-Sylpheed-Encrypt-Data:", NULL, FALSE},
                                       {NULL,    NULL, FALSE}};
        FILE *fp;
        gint filepos;
@@ -1048,6 +1054,9 @@ gint procmsg_send_message_queue(const gchar *file)
        gchar *savecopyfolder = NULL;
        gchar *replymessageid = NULL;
        gchar *fwdmessageid = NULL;
+       gchar *privacy_system = NULL;
+       gboolean encrypt = FALSE;
+       gchar *encrypt_data = NULL;
        gchar buf[BUFFSIZE];
        gint hnum;
        PrefsAccount *mailac = NULL, *newsac = NULL;
@@ -1092,10 +1101,40 @@ gint procmsg_send_message_queue(const gchar *file)
                case Q_FWD_MESSAGE_ID:
                        if (!fwdmessageid) fwdmessageid = g_strdup(p);
                        break;
+               case Q_PRIVACY_SYSTEM:
+                       if (privacy_system == NULL) privacy_system = g_strdup(p);
+                       break;
+               case Q_ENCRYPT:
+                       if (p[0] == '1') encrypt = TRUE;
+                       break;
+               case Q_ENCRYPT_DATA:
+                       if (encrypt_data == NULL) encrypt_data = g_strdup(p);
+                       break;
                }
        }
        filepos = ftell(fp);
 
+       if (encrypt) {
+               /* FIXME: memory leaks, in case of errors */
+               MimeInfo *mimeinfo;
+
+               fclose(fp);
+
+               mimeinfo = procmime_scan_queue_file(file);
+               if (!privacy_encrypt(privacy_system, mimeinfo, encrypt_data))
+                       return -1;
+
+               fp = my_tmpfile();
+               if (procmime_write_mimeinfo(mimeinfo, fp) < 0) {
+                       fclose(fp);
+                       return -1;
+               }
+               procmime_mimeinfo_free_all(mimeinfo);
+                       
+               rewind(fp);
+               filepos = 0;
+       }
+
        if (to_list) {
                debug_print("Sending message by mail\n");
                if (!from) {
@@ -1132,7 +1171,7 @@ gint procmsg_send_message_queue(const gchar *file)
        }
 
        fseek(fp, filepos, SEEK_SET);
-       if (newsgroup_list && (newsval == 0)) {
+       if (newsgroup_list && (mailval == 0)) {
                Folder *folder;
                gchar *tmp = NULL;
                FILE *tmpfp;
diff --git a/src/rfc2015.c b/src/rfc2015.c
deleted file mode 100644 (file)
index 13b212c..0000000
+++ /dev/null
@@ -1,865 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001 Werner Koch (dd9jn)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#if USE_GPGME
-
-#include "defs.h"
-
-#include <glib.h>
-#include <stdio.h>
-#include <string.h>
-#include <locale.h>
-#include <ctype.h>
-
-#include <gpgme.h>
-
-#include "intl.h"
-#include "procmime.h"
-#include "procheader.h"
-#include "base64.h"
-#include "uuencode.h"
-#include "unmime.h"
-#include "codeconv.h"
-#include "utils.h"
-#include "prefs_common.h"
-#include "passphrase.h"
-#include "select-keys.h"
-#include "rfc2015.h"
-#include "alertpanel.h"
-
-#define DIM(v)     (sizeof(v)/sizeof((v)[0]))
-
-static char *content_names[] = {
-    "Content-Type",
-    "Content-Disposition",
-    "Content-Transfer-Encoding",
-    NULL
-};
-
-static char *mime_version_name[] = {
-    "Mime-Version",
-    NULL
-};
-
-#if 0
-static void dump_mimeinfo (const char *text, MimeInfo *x)
-{
-    debug_print ("MimeInfo[%s] %p  level=%d\n",
-               text, x, x? x->level:0 );
-    if (!x)
-        return;
-
-    debug_print ("      enc=`%s' enc_type=%d mime_type=%d\n",
-               x->encoding, x->encoding_type, x->mime_type );
-    debug_print ("      cont_type=`%s' cs=`%s' name=`%s' bnd=`%s'\n",
-               x->content_type, x->charset, x->name, x->boundary );
-    debug_print ("      cont_disp=`%s' fname=`%s' fpos=%ld size=%u, lvl=%d\n",
-               x->content_disposition, x->filename, x->fpos, x->size,
-               x->level );
-    dump_mimeinfo (".main", x->main );
-    dump_mimeinfo (".sub", x->sub );
-    dump_mimeinfo (".next", x->next );
-    debug_print ("MimeInfo[.parent] %p\n", x ); 
-    dump_mimeinfo (".children", x->children );
-    dump_mimeinfo (".plaintext", x->plaintext );
-}
-
-static void dump_part ( MimeInfo *mimeinfo, FILE *fp )
-{
-    unsigned int size = mimeinfo->size;
-    int c;
-
-    if (fseek (fp, mimeinfo->fpos, SEEK_SET)) {
-        debug_print ("dump_part: fseek error\n");
-        return;
-    }
-
-    debug_print ("--- begin dump_part ----\n");
-    while (size-- && (c = getc (fp)) != EOF) 
-        putc (c, stderr);
-    if (ferror (fp))
-        debug_print ("dump_part: read error\n");
-    debug_print ("--- end dump_part ----\n");
-}
-#endif
-
-void
-rfc2015_secure_remove (const char *fname)
-{
-    if (!fname)
-        return;
-    /* fixme: overwrite the file first */
-    remove (fname);
-}
-
-
-
-
-static int
-name_cmp(const char *a, const char *b)
-{
-    for( ; *a && *b; a++, b++) {
-        if(*a != *b
-           && toupper(*(unsigned char *)a) != toupper(*(unsigned char *)b))
-            return 1;
-    }
-
-    return *a != *b;
-}
-
-static int
-headerp(char *p, char **names)
-{
-    int i, c;
-    char *p2;
-
-    p2 = strchr(p, ':');
-    if(!p2 || p == p2) {
-        return 0;
-    }
-    if(p2[-1] == ' ' || p2[-1] == '\t') {
-        return 0;
-    }
-
-    if(!names[0])
-        return 1;  
-
-    c = *p2;
-    *p2 = 0;
-    for(i = 0 ; names[i] != NULL; i++) {
-        if(!name_cmp (names[i], p))
-            break;
-    }
-    *p2 = c;
-
-    return names[i] != NULL;
-}
-
-/*
- * plain contains an entire mime object.
- * Encrypt it and return an GpgmeData object with the encrypted version of
- * the file or NULL in case of error.
- */
-static GpgmeData
-pgp_encrypt ( GpgmeData plain, GpgmeRecipients rset )
-{
-    GpgmeCtx ctx = NULL;
-    GpgmeError err;
-    GpgmeData cipher = NULL;
-
-    err = gpgme_new (&ctx);
-    if (!err)
-       err = gpgme_data_new (&cipher);
-    if (!err) {
-        gpgme_set_armor (ctx, 1);
-       err = gpgme_op_encrypt (ctx, rset, plain, cipher);
-    }
-
-    if (err) {
-        debug_print ("encryption failed: %s\n", gpgme_strerror (err));
-        gpgme_data_release (cipher);
-        cipher = NULL;
-    }
-    else {
-        debug_print ("** encryption succeeded\n");
-    }
-
-    gpgme_release (ctx);
-    return cipher;
-}
-
-/*
- * Create and return a list of keys matching a key id
- */
-
-GSList *rfc2015_create_signers_list (const char *keyid)
-{
-       GSList *key_list = NULL;
-       GpgmeCtx list_ctx = NULL;
-       GSList *p;
-       GpgmeError err;
-       GpgmeKey key;
-
-       err = gpgme_new (&list_ctx);
-       if (err)
-               goto leave;
-       err = gpgme_op_keylist_start (list_ctx, keyid, 1);
-       if (err)
-               goto leave;
-       while ( !(err = gpgme_op_keylist_next (list_ctx, &key)) ) {
-               key_list = g_slist_append (key_list, key);
-       }
-       if (err != GPGME_EOF)
-               goto leave;
-       err = 0;
-       if (key_list == NULL) {
-               debug_print ("no keys found for keyid \"%s\"\n", keyid);
-       }
-
-leave:
-       if (err) {
-               debug_print ("rfc2015_create_signers_list failed: %s\n", gpgme_strerror (err));
-               for (p = key_list; p != NULL; p = p->next)
-                       gpgme_key_unref ((GpgmeKey) p->data);
-               g_slist_free (key_list);
-       }
-       if (list_ctx)
-               gpgme_release (list_ctx);
-       return err ? NULL : key_list;
-}
-
-/*
- * Encrypt the file by extracting all recipients and finding the
- * encryption keys for all of them.  The file content is then replaced
- * by the encrypted one.  */
-int
-rfc2015_encrypt (const char *file, GSList *recp_list, gboolean ascii_armored,
-                const gchar *out_codeset)
-{
-    FILE *fp = NULL;
-    char buf[BUFFSIZE];
-    int i, clineidx, saved_last;
-    char *clines[3] = {NULL};
-    GpgmeError err;
-    GpgmeData header = NULL;
-    GpgmeData plain = NULL;
-    GpgmeData cipher = NULL;
-    GpgmeRecipients rset = NULL;
-    size_t nread;
-    int mime_version_seen = 0;
-    char *boundary;
-
-    boundary = generate_mime_boundary ("Encrypt");
-
-    /* Create the list of recipients */
-    rset = gpgmegtk_recipient_selection (recp_list);
-    if (!rset) {
-        debug_print ("error creating recipient list\n" );
-        goto failure;
-    }
-
-    /* Open the source file */
-    if ((fp = fopen(file, "rb")) == NULL) {
-        FILE_OP_ERROR(file, "fopen");
-        goto failure;
-    }
-
-    err = gpgme_data_new (&header);
-    if (!err)
-       err = gpgme_data_new (&plain);
-    if (err) {
-        debug_print ("gpgme_data_new failed: %s\n", gpgme_strerror (err));
-        goto failure;
-    }
-
-    /* get the content header lines from the source */
-    clineidx = 0;
-    saved_last = 0;
-    while (!err && fgets(buf, sizeof(buf), fp)) {
-        /* fixme: check for overlong lines */
-        if (headerp (buf, content_names)) {
-            if (clineidx >= DIM (clines)) {
-                debug_print ("rfc2015_encrypt: too many content lines\n");
-                goto failure;
-            }
-            clines[clineidx++] = g_strdup (buf);
-            saved_last = 1;
-            continue;
-        }
-
-        if (saved_last) {
-            if (*buf == ' ' || *buf == '\t') {
-                char *last = clines[clineidx - 1];
-                clines[clineidx - 1] = g_strconcat (last, buf, NULL);
-                g_free (last);
-                continue;
-            }
-            saved_last = 0;
-        }
-
-        if (headerp (buf, mime_version_name)) 
-            mime_version_seen = 1;
-
-        if (buf[0] == '\r' || buf[0] == '\n')
-            break;
-       
-       err = gpgme_data_write (header, buf, strlen (buf));
-    }
-    if (ferror (fp)) {
-        FILE_OP_ERROR (file, "fgets");
-        goto failure;
-    }
-
-    /* write them to the temp data and add the rest of the message */
-    for (i = 0; !err && i < clineidx; i++) {
-        debug_print ("%% %s:%d: cline=`%s'", __FILE__ ,__LINE__, clines[i]);
-       if (!ascii_armored)
-               err = gpgme_data_write (plain, clines[i], strlen (clines[i]));
-    }
-    if (!err && !ascii_armored)
-        err = gpgme_data_write (plain, "\r\n", 2);
-
-    while (!err && fgets(buf, sizeof(buf), fp)) {
-        err = gpgme_data_write (plain, buf, strlen (buf));
-    }
-    if (ferror (fp)) {
-        FILE_OP_ERROR (file, "fgets");
-        goto failure;
-    }
-    if (err) {
-        debug_print ("gpgme_data_write failed: %s\n", gpgme_strerror (err));
-        goto failure;
-    }
-
-    cipher = pgp_encrypt (plain, rset);
-    gpgme_data_release (plain); plain = NULL;
-    gpgme_recipients_release (rset); rset = NULL;
-    if (!cipher)
-        goto failure;
-
-    /* we have the encrypted message available in cipher and now we
-     * are going to rewrite the source file. To be sure that file has
-     * been truncated we use an approach which should work everywhere:
-     * close the file and then reopen it for writing. It is important
-     * that this works, otherwise it may happen that parts of the
-     * plaintext are still in the file (The encrypted stuff is, due to
-     * compression, usually shorter than the plaintext). 
-     * 
-     * Yes, there is a race condition here, but everyone, who is so
-     * stupid to store the temp file with the plaintext in a public
-     * directory has to live with this anyway. */
-    if (fclose (fp)) {
-        FILE_OP_ERROR(file, "fclose");
-        goto failure;
-    }
-    if ((fp = fopen(file, "wb")) == NULL) {
-        FILE_OP_ERROR(file, "fopen");
-        goto failure;
-    }
-
-    /* Write the header, append new content lines, part 1 and part 2 header */
-    err = gpgme_data_rewind (header);
-    if (err) {
-        debug_print ("gpgme_data_rewind failed: %s\n", gpgme_strerror (err));
-        goto failure;
-    }
-    while (!(err = gpgme_data_read (header, buf, BUFFSIZE, &nread))) {
-        fwrite (buf, nread, 1, fp);
-    }
-    if (err != GPGME_EOF) {
-        debug_print ("gpgme_data_read failed: %s\n", gpgme_strerror (err));
-        goto failure;
-    }
-    if (ferror (fp)) {
-        FILE_OP_ERROR (file, "fwrite");
-        goto failure;
-    }
-    gpgme_data_release (header); header = NULL;
-    
-    if (!mime_version_seen) 
-        fputs ("MIME-Version: 1\r\n", fp);
-
-    if (ascii_armored) {
-        fprintf(fp, 
-            "Content-Type: text/plain; charset=%s\r\n"
-            "Content-Disposition: inline\r\n"  
-            "Content-Transfer-Encoding: 8bit\r\n"  
-            "\r\n", out_codeset ? out_codeset : CS_US_ASCII);
-    } else {
-        fprintf (fp,
-               "Content-Type: multipart/encrypted;"
-               " protocol=\"application/pgp-encrypted\";\r\n"
-               " boundary=\"%s\"\r\n"
-               "\r\n"
-               "--%s\r\n"
-               "Content-Type: application/pgp-encrypted\r\n"
-               "\r\n"
-               "Version: 1\r\n"
-               "\r\n"
-               "--%s\r\n"
-               "Content-Type: application/octet-stream\r\n"
-               "\r\n",
-               boundary, boundary, boundary);
-    }
-
-    /* append the encrypted stuff */
-    err = gpgme_data_rewind (cipher);
-    if (err) {
-        debug_print ("** gpgme_data_rewind on cipher failed: %s\n",
-                   gpgme_strerror (err));
-        goto failure;
-    }
-
-    while (!(err = gpgme_data_read (cipher, buf, BUFFSIZE, &nread))) {
-        fwrite (buf, nread, 1, fp);
-    }
-    if (err != GPGME_EOF) {
-        debug_print ("** gpgme_data_read failed: %s\n", gpgme_strerror (err));
-        goto failure;
-    }
-
-    /* and the final boundary */
-    if (!ascii_armored) {
-        fprintf (fp,
-                "\r\n"
-                "--%s--\r\n",
-                boundary);
-    }
-    fflush (fp);
-    if (ferror (fp)) {
-        FILE_OP_ERROR (file, "fwrite");
-        goto failure;
-    }
-    fclose (fp);
-    gpgme_data_release (cipher);
-    return 0;
-
-failure:
-    if (fp) 
-        fclose (fp);
-    gpgme_data_release (header);
-    gpgme_data_release (plain);
-    gpgme_data_release (cipher);
-    gpgme_recipients_release (rset);
-    g_free (boundary);
-    return -1; /* error */
-}
-
-/* 
- * plain contains an entire mime object.  Sign it and return an
- * GpgmeData object with the signature of it or NULL in case of error.
- * r_siginfo returns an XML object with information about the signature.
- */
-static GpgmeData
-pgp_sign (GpgmeData plain, GSList *key_list, gboolean clearsign,
-         char **r_siginfo)
-{
-    GSList *p;
-    GpgmeCtx ctx = NULL;
-    GpgmeError err;
-    GpgmeData sig = NULL;
-    struct passphrase_cb_info_s info;
-
-    *r_siginfo = NULL;
-    memset (&info, 0, sizeof info);
-
-    err = gpgme_new (&ctx);
-    if (err)
-        goto leave;
-    err = gpgme_data_new (&sig);
-    if (err)
-        goto leave;
-
-    if (!getenv("GPG_AGENT_INFO")) {
-        info.c = ctx;
-        gpgme_set_passphrase_cb (ctx, gpgmegtk_passphrase_cb, &info);
-    }
-    gpgme_set_textmode (ctx, 1);
-    gpgme_set_armor (ctx, 1);
-    gpgme_signers_clear (ctx);
-    for (p = key_list; p != NULL; p = p->next) {
-       err = gpgme_signers_add (ctx, (GpgmeKey) p->data);
-       if (err)
-           goto leave;
-    }
-    for (p = key_list; p != NULL; p = p->next)
-       gpgme_key_unref ((GpgmeKey) p->data);
-    g_slist_free (key_list);
-
-    if (err)
-       goto leave;
-    err = gpgme_op_sign
-       (ctx, plain, sig,
-        clearsign ? GPGME_SIG_MODE_CLEAR : GPGME_SIG_MODE_DETACH);
-    if (!err)
-        *r_siginfo = gpgme_get_op_info (ctx, 0);
-
-leave:
-    if (err) {
-        gpgmegtk_free_passphrase();
-        debug_print ("signing failed: %s\n", gpgme_strerror (err));
-        gpgme_data_release (sig);
-        sig = NULL;
-    }
-    else {
-        debug_print ("signing succeeded\n");
-    }
-
-    gpgme_release (ctx);
-    return sig;
-}
-
-/*
- * Find TAG in XML and return a pointer into xml set just behind the
- * closing angle.  Return NULL if not found. 
- */
-static const char *
-find_xml_tag (const char *xml, const char *tag)
-{
-    int taglen = strlen (tag);
-    const char *s = xml;
-    while ( (s = strchr (s, '<')) ) {
-        s++;
-        if (!strncmp (s, tag, taglen)) {
-            const char *s2 = s + taglen;
-            if (*s2 == '>' || isspace (*(const unsigned char*)s2) ) {
-                /* found */
-                while (*s2 && *s2 != '>') /* skip attributes */
-                    s2++;
-                /* fixme: do need to handle angles inside attribute vallues? */
-                return *s2? (s2+1):NULL;
-            }
-        }
-        while (*s && *s != '>') /* skip to end of tag */
-            s++;
-    }
-    return NULL;
-}
-
-
-/*
- * Extract the micalg from an GnupgOperationInfo XML container.
- */
-static char *
-extract_micalg (char *xml)
-{
-    const char *s;
-
-    s = find_xml_tag (xml, "GnupgOperationInfo");
-    if (s) {
-        const char *s_end = find_xml_tag (s, "/GnupgOperationInfo");
-        s = find_xml_tag (s, "signature");
-        if (s && s_end && s < s_end) {
-            const char *s_end2 = find_xml_tag (s, "/signature");
-            if (s_end2 && s_end2 < s_end) {
-                s = find_xml_tag (s, "micalg");
-                if (s && s < s_end2) {
-                    s_end = strchr (s, '<');
-                    if (s_end) {
-                        char *p = g_malloc (s_end - s + 1);
-                        memcpy (p, s, s_end - s);
-                        p[s_end-s] = 0;
-                        return p;
-                    }
-                }
-            }
-        }
-    }
-    return NULL;
-}
-
-
-/*
- * Sign the file and replace its content with the signed one.
- */
-int
-rfc2015_sign (const char *file, GSList *key_list)
-{
-    FILE *fp = NULL;
-    char buf[BUFFSIZE];
-    int i, clineidx, saved_last;
-    char *clines[3] = {NULL};
-    GpgmeError err;
-    GpgmeData header = NULL;
-    GpgmeData plain = NULL;
-    GpgmeData sigdata = NULL;
-    size_t nread;
-    int mime_version_seen = 0;
-    char *boundary;
-    char *micalg = NULL;
-    char *siginfo;
-
-    boundary = generate_mime_boundary ("Signature");
-
-    /* Open the source file */
-    if ((fp = fopen(file, "rb")) == NULL) {
-        FILE_OP_ERROR(file, "fopen");
-        goto failure;
-    }
-
-    err = gpgme_data_new (&header);
-    if (!err)
-        err = gpgme_data_new (&plain);
-    if (err) {
-        debug_print ("gpgme_data_new failed: %s\n", gpgme_strerror (err));
-        goto failure;
-    }
-
-    /* get the content header lines from the source */
-    clineidx = 0;
-    saved_last = 0;
-    while (!err && fgets(buf, sizeof(buf), fp)) {
-        /* fixme: check for overlong lines */
-        if (headerp (buf, content_names)) {
-            if (clineidx >= DIM (clines)) {
-                debug_print ("rfc2015_sign: too many content lines\n");
-                goto failure;
-            }
-            clines[clineidx++] = g_strdup (buf);
-            saved_last = 1;
-            continue;
-        }
-        if (saved_last) {
-            if (*buf == ' ' || *buf == '\t') {
-                char *last = clines[clineidx - 1];
-                clines[clineidx - 1] = g_strconcat (last, buf, NULL);
-                g_free (last);
-                continue;
-            }
-            saved_last = 0;
-        }
-
-        if (headerp (buf, mime_version_name)) 
-            mime_version_seen = 1;
-
-        if (buf[0] == '\r' || buf[0] == '\n')
-            break;
-        err = gpgme_data_write (header, buf, strlen (buf));
-    }
-    if (ferror (fp)) {
-        FILE_OP_ERROR (file, "fgets");
-        goto failure;
-    }
-
-    /* write them to the temp data and add the rest of the message */
-    for (i = 0; !err && i < clineidx; i++) {
-        err = gpgme_data_write (plain, clines[i], strlen (clines[i]));
-    }
-    if (!err)
-        err = gpgme_data_write (plain, "\r\n", 2 );
-    while (!err && fgets(buf, sizeof(buf), fp)) {
-        err = gpgme_data_write (plain, buf, strlen (buf));
-    }
-    if (ferror (fp)) {
-        FILE_OP_ERROR (file, "fgets");
-        goto failure;
-    }
-    if (err) {
-        debug_print ("gpgme_data_write failed: %s\n", gpgme_strerror (err));
-        goto failure;
-    }
-
-    sigdata = pgp_sign (plain, key_list, FALSE, &siginfo); 
-    if (siginfo) {
-       micalg = extract_micalg (siginfo);
-       free (siginfo);
-    }
-    if (!sigdata) 
-        goto failure;
-
-    /* we have the signed message available in sigdata and now we are
-     * going to rewrite the original file. To be sure that file has
-     * been truncated we use an approach which should work everywhere:
-     * close the file and then reopen it for writing. */
-    if (fclose (fp)) {
-        FILE_OP_ERROR(file, "fclose");
-        goto failure;
-    }
-    if ((fp = fopen(file, "wb")) == NULL) {
-        FILE_OP_ERROR(file, "fopen");
-        goto failure;
-    }
-
-    /* Write the rfc822 header and add new content lines */
-    err = gpgme_data_rewind (header);
-    if (err)
-        debug_print ("gpgme_data_rewind failed: %s\n", gpgme_strerror (err));
-    while (!(err = gpgme_data_read (header, buf, BUFFSIZE, &nread))) {
-        fwrite (buf, nread, 1, fp);
-    }
-    if (err != GPGME_EOF) {
-        debug_print ("gpgme_data_read failed: %s\n", gpgme_strerror (err));
-        goto failure;
-    }
-    if (ferror (fp)) {
-        FILE_OP_ERROR (file, "fwrite");
-        goto failure;
-    }
-    gpgme_data_release (header);
-    header = NULL;
-
-    if (!mime_version_seen) 
-        fputs ("MIME-Version: 1.0\r\n", fp);
-    fprintf (fp, "Content-Type: multipart/signed; "
-             "protocol=\"application/pgp-signature\";\r\n");
-    if (micalg)
-        fprintf (fp, " micalg=\"%s\";\r\n", micalg);
-    fprintf (fp, " boundary=\"%s\"\r\n", boundary);
-
-    /* Part 1: signed material */
-    fprintf (fp, "\r\n"
-                 "--%s\r\n",
-                 boundary);
-    err = gpgme_data_rewind (plain);
-    if (err) {
-        debug_print ("gpgme_data_rewind on plain failed: %s\n",
-                   gpgme_strerror (err));
-        goto failure;
-    }
-    while (!(err = gpgme_data_read (plain, buf, BUFFSIZE, &nread))) {
-        fwrite (buf, nread, 1, fp);   
-    }
-    if (err != GPGME_EOF) {
-        debug_print ("gpgme_data_read failed: %s\n", gpgme_strerror (err));
-        goto failure;
-    }
-
-    /* Part 2: signature */
-    fprintf (fp, "\r\n"
-                 "--%s\r\n",
-                 boundary);
-    fputs ("Content-Type: application/pgp-signature\r\n"
-          "\r\n", fp);
-
-    err = gpgme_data_rewind (sigdata);
-    if (err) {
-        debug_print ("gpgme_data_rewind on sigdata failed: %s\n",
-                   gpgme_strerror (err));
-        goto failure;
-    }
-
-    while (!(err = gpgme_data_read (sigdata, buf, BUFFSIZE, &nread))) {
-        fwrite (buf, nread, 1, fp);
-    }
-    if (err != GPGME_EOF) {
-        debug_print ("gpgme_data_read failed: %s\n", gpgme_strerror (err));
-        goto failure;
-    }
-
-    /* Final boundary */
-    fprintf (fp, "\r\n"
-                 "--%s--\r\n",
-                 boundary);
-    fflush (fp);
-    if (ferror (fp)) {
-        FILE_OP_ERROR (file, "fwrite");
-        goto failure;
-    }
-    fclose (fp);
-    gpgme_data_release (header);
-    gpgme_data_release (plain);
-    gpgme_data_release (sigdata);
-    g_free (boundary);
-    g_free (micalg);
-    return 0;
-
-failure:
-    if (fp) 
-        fclose (fp);
-    gpgme_data_release (header);
-    gpgme_data_release (plain);
-    gpgme_data_release (sigdata);
-    g_free (boundary);
-    g_free (micalg);
-    return -1; /* error */
-}
-
-
-/*
- * Sign the file with clear text and replace its content with the signed one.
- */
-gint
-rfc2015_clearsign (const gchar *file, GSList *key_list)
-{
-    FILE *fp;
-    gchar buf[BUFFSIZE];
-    GpgmeError err;
-    GpgmeData text = NULL;
-    GpgmeData sigdata = NULL;
-    size_t nread;
-    gchar *siginfo;
-
-    if ((fp = fopen(file, "rb")) == NULL) {
-       FILE_OP_ERROR(file, "fopen");
-       goto failure;
-    }
-
-    err = gpgme_data_new(&text);
-    if (err) {
-       debug_print("gpgme_data_new failed: %s\n", gpgme_strerror(err));
-       goto failure;
-    }
-
-    while (!err && fgets(buf, sizeof(buf), fp)) {
-       err = gpgme_data_write(text, buf, strlen(buf));
-    }
-    if (ferror(fp)) {
-       FILE_OP_ERROR(file, "fgets");
-       goto failure;
-    }
-    if (err) {
-       debug_print("gpgme_data_write failed: %s\n", gpgme_strerror(err));
-       goto failure;
-    }
-
-    sigdata = pgp_sign(text, key_list, TRUE, &siginfo);
-    if (siginfo) {
-       g_free(siginfo);
-    }
-    if (!sigdata)
-       goto failure;
-
-    if (fclose(fp) == EOF) {
-       FILE_OP_ERROR(file, "fclose");
-       fp = NULL;
-       goto failure;
-    }
-    if ((fp = fopen(file, "wb")) == NULL) {
-       FILE_OP_ERROR(file, "fopen");
-       goto failure;
-    }
-
-    err = gpgme_data_rewind(sigdata);
-    if (err) {
-       debug_print("gpgme_data_rewind on sigdata failed: %s\n",
-                   gpgme_strerror(err));
-       goto failure;
-    }
-
-    while (!(err = gpgme_data_read(sigdata, buf, sizeof(buf), &nread))) {
-       fwrite(buf, nread, 1, fp);
-    }
-    if (err != GPGME_EOF) {
-       debug_print("gpgme_data_read failed: %s\n", gpgme_strerror(err));
-       goto failure;
-    }
-
-    if (fclose(fp) == EOF) {
-       FILE_OP_ERROR(file, "fclose");
-       fp = NULL;
-       goto failure;
-    }
-    gpgme_data_release(text);
-    gpgme_data_release(sigdata);
-    return 0;
-
-failure:
-    if (fp)
-       fclose(fp);
-    gpgme_data_release(text);
-    gpgme_data_release(sigdata);
-    return -1;
-}
-
-#endif /* USE_GPGME */
diff --git a/src/rfc2015.h b/src/rfc2015.h
deleted file mode 100644 (file)
index 3c14a4b..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001 Werner Koch (dd9jn)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __RFC2015_H__
-#define __RFC2015_H__
-
-#include <glib.h>
-#include <stdio.h>
-
-#include "procmime.h"
-
-void rfc2015_init                      (void);
-void rfc2015_done                      (void);
-
-void rfc2015_disable_all               (void);
-void rfc2015_secure_remove             (const gchar    *fname);
-MimeInfo *rfc2015_find_signature       (MimeInfo       *mimeinfo);
-gboolean rfc2015_has_signature         (MimeInfo       *mimeinfo);
-void rfc2015_check_signature           (MimeInfo       *mimeinfo,
-                                        FILE           *fp);
-gint rfc2015_is_encrypted              (MimeInfo       *mimeinfo);
-gboolean rfc2015_msg_is_encrypted      (const gchar    *file);
-void rfc2015_decrypt_message           (MsgInfo        *msginfo,
-                                        MimeInfo       *mimeinfo,
-                                        FILE           *fp);
-GSList *rfc2015_create_signers_list    (const gchar    *keyid);
-gint rfc2015_encrypt                   (const gchar    *file,
-                                        GSList         *recp_list,
-                                        gboolean        ascii_armored,
-                                        const gchar    *out_codeset);
-gint rfc2015_sign                      (const gchar    *file,
-                                        GSList         *key_list);
-gint rfc2015_clearsign                 (const gchar    *file,
-                                        GSList         *key_list);
-#endif /* __RFC2015_H__ */
diff --git a/src/select-keys.c b/src/select-keys.c
deleted file mode 100644 (file)
index 0d09c84..0000000
+++ /dev/null
@@ -1,546 +0,0 @@
-/* select-keys.c - GTK+ based key selection
- *      Copyright (C) 2001 Werner Koch (dd9jn)
- *
- * This program is free software; you can redistribute it and/or modify        
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#ifdef USE_GPGME
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <glib.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtkmain.h>
-#include <gtk/gtkwidget.h>
-#include <gtk/gtkwindow.h>
-#include <gtk/gtkscrolledwindow.h>
-#include <gtk/gtkvbox.h>
-#include <gtk/gtkhbox.h>
-#include <gtk/gtkclist.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkentry.h>
-#include <gtk/gtkhbbox.h>
-#include <gtk/gtkbutton.h>
-#include <gtk/gtksignal.h>
-
-#include "intl.h"
-#include "select-keys.h"
-#include "utils.h"
-#include "gtkutils.h"
-#include "inputdialog.h"
-#include "manage_window.h"
-
-#define DIM(v) (sizeof(v)/sizeof((v)[0]))
-#define DIMof(type,member)   DIM(((type *)0)->member)
-
-
-enum col_titles { 
-    COL_ALGO,
-    COL_KEYID,
-    COL_NAME,
-    COL_EMAIL,
-    COL_VALIDITY,
-
-    N_COL_TITLES
-};
-
-struct select_keys_s {
-    int okay;
-    GtkWidget *window;
-    GtkLabel *toplabel;
-    GtkCList *clist;
-    const char *pattern;
-    GpgmeRecipients rset;
-    GpgmeCtx select_ctx;
-
-    GtkSortType sort_type;
-    enum col_titles sort_column;
-    
-};
-
-
-static void set_row (GtkCList *clist, GpgmeKey key);
-static void fill_clist (struct select_keys_s *sk, const char *pattern);
-static void create_dialog (struct select_keys_s *sk);
-static void open_dialog (struct select_keys_s *sk);
-static void close_dialog (struct select_keys_s *sk);
-static gint delete_event_cb (GtkWidget *widget,
-                             GdkEventAny *event, gpointer data);
-static gboolean key_pressed_cb (GtkWidget *widget,
-                                GdkEventKey *event, gpointer data);
-static void showall_btn_cb (GtkWidget *widget, gpointer data);
-static void select_btn_cb (GtkWidget *widget, gpointer data);
-static void cancel_btn_cb (GtkWidget *widget, gpointer data);
-static void other_btn_cb (GtkWidget *widget, gpointer data);
-static void sort_keys (struct select_keys_s *sk, enum col_titles column);
-static void sort_keys_name (GtkWidget *widget, gpointer data);
-static void sort_keys_email (GtkWidget *widget, gpointer data);
-
-
-static void
-update_progress (struct select_keys_s *sk, int running, const char *pattern)
-{
-    static int windmill[] = { '-', '\\', '|', '/' };
-    char *buf;
-
-    if (!running)
-        buf = g_strdup_printf (_("Please select key for `%s'"), 
-                               pattern);
-    else 
-        buf = g_strdup_printf (_("Collecting info for `%s' ... %c"), 
-                               pattern,
-                               windmill[running%DIM(windmill)]);
-    gtk_label_set_text (sk->toplabel, buf);
-    g_free (buf);
-}
-
-
-/**
- * select_keys_get_recipients:
- * @recp_names: A list of email addresses
- * 
- * Select a list of recipients from a given list of email addresses.
- * This may pop up a window to present the user a choice, it will also
- * check that the recipients key are all valid.
- * 
- * Return value: NULL on error or a list of list of recipients.
- **/
-GpgmeRecipients
-gpgmegtk_recipient_selection (GSList *recp_names)
-{
-    struct select_keys_s sk;
-    GpgmeError err;
-
-    memset (&sk, 0, sizeof sk);
-
-    err = gpgme_recipients_new (&sk.rset);
-    if (err) {
-        g_warning ("failed to allocate recipients set: %s",
-                   gpgme_strerror (err));
-        return NULL;
-    }
-
-    open_dialog (&sk);
-
-    do {
-        sk.pattern = recp_names? recp_names->data:NULL;
-        gtk_clist_clear (sk.clist);
-        fill_clist (&sk, sk.pattern);
-        update_progress (&sk, 0, sk.pattern);
-        gtk_main ();
-        if (recp_names)
-            recp_names = recp_names->next;
-    } while (sk.okay && recp_names);
-
-    close_dialog (&sk);
-
-    if (!sk.okay) {
-        gpgme_recipients_release (sk.rset);
-        sk.rset = NULL;
-    }
-    return sk.rset;
-} 
-
-static void
-destroy_key (gpointer data)
-{
-    GpgmeKey key = data;
-    gpgme_key_release (key);
-}
-
-static void
-set_row (GtkCList *clist, GpgmeKey key)
-{
-    const char *s;
-    const char *text[N_COL_TITLES];
-    char *algo_buf;
-    int row;
-
-    /* first check whether the key is capable of encryption which is not
-     * the case for revoked, expired or sign-only keys */
-    if ( !gpgme_key_get_ulong_attr (key, GPGME_ATTR_CAN_ENCRYPT, NULL, 0 ) )
-        return;
-    
-    algo_buf = g_strdup_printf ("%lu/%s", 
-         gpgme_key_get_ulong_attr (key, GPGME_ATTR_LEN, NULL, 0 ),
-         gpgme_key_get_string_attr (key, GPGME_ATTR_ALGO, NULL, 0 ) );
-    text[COL_ALGO] = algo_buf;
-
-    s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID, NULL, 0);
-    if (strlen (s) == 16)
-        s += 8; /* show only the short keyID */
-    text[COL_KEYID] = s;
-
-    s = gpgme_key_get_string_attr (key, GPGME_ATTR_NAME, NULL, 0);
-    text[COL_NAME] = s;
-
-    s = gpgme_key_get_string_attr (key, GPGME_ATTR_EMAIL, NULL, 0);
-    text[COL_EMAIL] = s;
-
-    s = gpgme_key_get_string_attr (key, GPGME_ATTR_VALIDITY, NULL, 0);
-    text[COL_VALIDITY] = s;
-
-    row = gtk_clist_append (clist, (gchar**)text);
-    g_free (algo_buf);
-
-    gtk_clist_set_row_data_full (clist, row, key, destroy_key);
-}
-
-
-static void 
-fill_clist (struct select_keys_s *sk, const char *pattern)
-{
-    GtkCList *clist;
-    GpgmeCtx ctx;
-    GpgmeError err;
-    GpgmeKey key;
-    int running=0;
-
-    g_return_if_fail (sk);
-    clist = sk->clist;
-    g_return_if_fail (clist);
-
-    debug_print ("select_keys:fill_clist:  pattern `%s'\n", pattern);
-
-    /*gtk_clist_freeze (select_keys.clist);*/
-    err = gpgme_new (&ctx);
-    g_assert (!err);
-
-    sk->select_ctx = ctx;
-
-    update_progress (sk, ++running, pattern);
-    while (gtk_events_pending ())
-        gtk_main_iteration ();
-
-    err = gpgme_op_keylist_start (ctx, pattern, 0);
-    if (err) {
-        debug_print ("** gpgme_op_keylist_start(%s) failed: %s",
-                     pattern, gpgme_strerror (err));
-        sk->select_ctx = NULL;
-        return;
-    }
-    update_progress (sk, ++running, pattern);
-    while ( !(err = gpgme_op_keylist_next ( ctx, &key )) ) {
-        debug_print ("%% %s:%d:  insert\n", __FILE__ ,__LINE__ );
-        set_row (clist, key ); key = NULL;
-        update_progress (sk, ++running, pattern);
-        while (gtk_events_pending ())
-            gtk_main_iteration ();
-    }
-    debug_print ("%% %s:%d:  ready\n", __FILE__ ,__LINE__ );
-    if (err != GPGME_EOF)
-        debug_print ("** gpgme_op_keylist_next failed: %s",
-                     gpgme_strerror (err));
-    sk->select_ctx = NULL;
-    gpgme_release (ctx);
-    /*gtk_clist_thaw (select_keys.clist);*/
-}
-
-
-static void 
-create_dialog (struct select_keys_s *sk)
-{
-    GtkWidget *window;
-    GtkWidget *vbox, *vbox2, *hbox;
-    GtkWidget *bbox;
-    GtkWidget *scrolledwin;
-    GtkWidget *clist;
-    GtkWidget *label;
-    GtkWidget *select_btn, *cancel_btn, *other_btn;
-    GtkWidget *showall_btn;
-    const char *titles[N_COL_TITLES];
-
-    g_assert (!sk->window);
-    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-    gtk_widget_set_size_request (window, 520, 280);
-    gtk_container_set_border_width (GTK_CONTAINER (window), 8);
-    gtk_window_set_title (GTK_WINDOW (window), _("Select Keys"));
-    gtk_window_set_modal (GTK_WINDOW (window), TRUE);
-    g_signal_connect (G_OBJECT (window), "delete_event",
-                     G_CALLBACK (delete_event_cb), sk);
-    g_signal_connect (G_OBJECT (window), "key_press_event",
-                     G_CALLBACK (key_pressed_cb), sk);
-    MANAGE_WINDOW_SIGNALS_CONNECT (window);
-
-    vbox = gtk_vbox_new (FALSE, 8);
-    gtk_container_add (GTK_CONTAINER (window), vbox);
-
-    hbox  = gtk_hbox_new(FALSE, 4);
-    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-    label = gtk_label_new ( "" );
-    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-
-    hbox = gtk_hbox_new (FALSE, 8);
-    gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
-    gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
-
-    scrolledwin = gtk_scrolled_window_new (NULL, NULL);
-    gtk_box_pack_start (GTK_BOX (hbox), scrolledwin, TRUE, TRUE, 0);
-    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwin),
-                                    GTK_POLICY_AUTOMATIC,
-                                    GTK_POLICY_AUTOMATIC);
-
-    titles[COL_ALGO]     = _("Size");
-    titles[COL_KEYID]    = _("Key ID");
-    titles[COL_NAME]     = _("Name");
-    titles[COL_EMAIL]    = _("Address");
-    titles[COL_VALIDITY] = _("Val");
-
-    clist = gtk_clist_new_with_titles (N_COL_TITLES, (char**)titles);
-    gtk_container_add (GTK_CONTAINER (scrolledwin), clist);
-    gtk_clist_set_column_width (GTK_CLIST(clist), COL_ALGO,      72);
-    gtk_clist_set_column_width (GTK_CLIST(clist), COL_KEYID,     76);
-    gtk_clist_set_column_width (GTK_CLIST(clist), COL_NAME,     130);
-    gtk_clist_set_column_width (GTK_CLIST(clist), COL_EMAIL,    130);
-    gtk_clist_set_column_width (GTK_CLIST(clist), COL_VALIDITY,  20);
-    gtk_clist_set_selection_mode (GTK_CLIST(clist), GTK_SELECTION_BROWSE);
-    g_signal_connect (G_OBJECT(GTK_CLIST(clist)->column[COL_NAME].button),
-                     "clicked",
-                     G_CALLBACK(sort_keys_name), sk);
-    g_signal_connect (G_OBJECT(GTK_CLIST(clist)->column[COL_EMAIL].button),
-                     "clicked",
-                     G_CALLBACK(sort_keys_email), sk);
-
-    hbox = gtk_hbox_new (FALSE, 8);
-    gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
-    showall_btn = gtk_button_new_with_label (_(" List all keys "));
-    gtk_widget_show (showall_btn);
-    gtk_box_pack_start (GTK_BOX (hbox), showall_btn, FALSE, FALSE, 0);
-
-    g_signal_connect(G_OBJECT (showall_btn), "clicked",
-                     G_CALLBACK(showall_btn_cb), sk);
-
-    gtkut_button_set_create (&bbox, 
-                             &select_btn, _("Select"),
-                             &cancel_btn, _("Cancel"),
-                             &other_btn,  _("Other"));
-    gtk_box_pack_end (GTK_BOX (hbox), bbox, FALSE, FALSE, 0);
-    gtk_widget_grab_default (select_btn);
-
-    g_signal_connect (G_OBJECT (select_btn), "clicked",
-                     G_CALLBACK (select_btn_cb), sk);
-    g_signal_connect (G_OBJECT(cancel_btn), "clicked",
-                     G_CALLBACK (cancel_btn_cb), sk);
-    g_signal_connect (G_OBJECT (other_btn), "clicked",
-                     G_CALLBACK (other_btn_cb), sk);
-
-    vbox2 = gtk_vbox_new (FALSE, 4);
-    gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
-
-    gtk_widget_show_all (window);
-
-    sk->window = window;
-    sk->toplabel = GTK_LABEL (label);
-    sk->clist  = GTK_CLIST (clist);
-}
-
-
-static void
-open_dialog (struct select_keys_s *sk)
-{
-    if (!sk->window)
-        create_dialog (sk);
-    manage_window_set_transient (GTK_WINDOW (sk->window));
-    sk->okay = 0;
-    sk->sort_column = N_COL_TITLES; /* use an invalid value */
-    sk->sort_type = GTK_SORT_ASCENDING;
-    gtk_widget_show (sk->window);
-}
-
-
-static void
-close_dialog (struct select_keys_s *sk)
-{
-    g_return_if_fail (sk);
-    gtk_widget_destroy (sk->window);
-    sk->window = NULL;
-}
-
-
-static gint
-delete_event_cb (GtkWidget *widget, GdkEventAny *event, gpointer data)
-{
-    struct select_keys_s *sk = data;
-
-    sk->okay = 0;
-    gtk_main_quit ();
-
-    return TRUE;
-}
-
-
-static gboolean 
-key_pressed_cb (GtkWidget *widget, GdkEventKey *event, gpointer data)
-{
-    struct select_keys_s *sk = data;
-
-    g_return_val_if_fail (sk, FALSE);
-    if (event && event->keyval == GDK_Escape) {
-        sk->okay = 0;
-        gtk_main_quit ();
-    }
-       return FALSE;
-}
-
-
-static void 
-select_btn_cb (GtkWidget *widget, gpointer data)
-{
-    struct select_keys_s *sk = data;
-    int row;
-    GpgmeKey key;
-
-    g_return_if_fail (sk);
-    if (!sk->clist->selection) {
-        debug_print ("** nothing selected");
-        return;
-    }
-    row = GPOINTER_TO_INT(sk->clist->selection->data);
-    key = gtk_clist_get_row_data(sk->clist, row);
-    if (key) {
-        const char *s = gpgme_key_get_string_attr (key,
-                                                   GPGME_ATTR_FPR,
-                                                   NULL, 0 );
-        if ( gpgme_key_get_ulong_attr (key, GPGME_ATTR_VALIDITY, NULL, 0 )
-             < GPGME_VALIDITY_FULL ) {
-            debug_print ("** FIXME: we are faking the trust calculation");
-        }
-        if (!gpgme_recipients_add_name_with_validity (sk->rset, s,
-                                                      GPGME_VALIDITY_FULL) ) {
-            sk->okay = 1;
-            gtk_main_quit ();
-        }
-    }
-}
-
-
-static void 
-cancel_btn_cb (GtkWidget *widget, gpointer data)
-{
-    struct select_keys_s *sk = data;
-
-    g_return_if_fail (sk);
-    sk->okay = 0;
-    if (sk->select_ctx)
-        gpgme_cancel (sk->select_ctx);
-    gtk_main_quit ();
-}
-
-
-static void
-other_btn_cb (GtkWidget *widget, gpointer data)
-{
-    struct select_keys_s *sk = data;
-    char *uid;
-
-    g_return_if_fail (sk);
-    uid = input_dialog ( _("Add key"),
-                         _("Enter another user or key ID:"),
-                         NULL );
-    if (!uid)
-        return;
-    fill_clist (sk, uid);
-    update_progress (sk, 0, sk->pattern);
-    g_free (uid);
-}
-
-static void
-showall_btn_cb (GtkWidget *widget, gpointer data)
-{
-    struct select_keys_s *sk = data;
-    char *uid;
-
-    g_return_if_fail (sk);
-    uid = "";
-       
-    fill_clist (sk, uid);
-    update_progress (sk, 0, sk->pattern);
-}
-
-static gint 
-cmp_attr (gconstpointer pa, gconstpointer pb, GpgmeAttr attr)
-{
-    GpgmeKey a = ((GtkCListRow *)pa)->data;
-    GpgmeKey b = ((GtkCListRow *)pb)->data;
-    const char *sa, *sb;
-    
-    sa = a? gpgme_key_get_string_attr (a, attr, NULL, 0 ) : NULL;
-    sb = b? gpgme_key_get_string_attr (b, attr, NULL, 0 ) : NULL;
-    if (!sa)
-        return !!sb;
-    if (!sb)
-        return -1;
-    return strcasecmp(sa, sb);
-}
-
-static gint 
-cmp_name (GtkCList *clist, gconstpointer pa, gconstpointer pb)
-{
-    return cmp_attr (pa, pb, GPGME_ATTR_NAME);
-}
-
-static gint 
-cmp_email (GtkCList *clist, gconstpointer pa, gconstpointer pb)
-{
-    return cmp_attr (pa, pb, GPGME_ATTR_EMAIL);
-}
-
-static void
-sort_keys ( struct select_keys_s *sk, enum col_titles column)
-{
-    GtkCList *clist = sk->clist;
-
-    switch (column) {
-      case COL_NAME:
-        gtk_clist_set_compare_func (clist, cmp_name);
-        break;
-      case COL_EMAIL:
-        gtk_clist_set_compare_func (clist, cmp_email);
-        break;
-      default:
-        return;
-    }
-
-    /* column clicked again: toggle as-/decending */
-    if ( sk->sort_column == column) {
-        sk->sort_type = sk->sort_type == GTK_SORT_ASCENDING ?
-                        GTK_SORT_DESCENDING : GTK_SORT_ASCENDING;
-    }
-    else
-        sk->sort_type = GTK_SORT_ASCENDING;
-
-    sk->sort_column = column;
-    gtk_clist_set_sort_type (clist, sk->sort_type);
-    gtk_clist_sort (clist);
-}
-
-static void
-sort_keys_name (GtkWidget *widget, gpointer data)
-{
-    sort_keys ((struct select_keys_s*)data, COL_NAME);
-}
-
-static void
-sort_keys_email (GtkWidget *widget, gpointer data)
-{
-    sort_keys ((struct select_keys_s*)data, COL_EMAIL);
-}
-
-#endif /*USE_GPGME*/
diff --git a/src/select-keys.h b/src/select-keys.h
deleted file mode 100644 (file)
index 009afc1..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* select-keys.h - GTK+ based key selection
- *      Copyright (C) 2001 Werner Koch (dd9jn)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef GPGMEGTK_SELECT_KEYS_H
-#define GPGMEGTK_SELECT_KEYS_H
-
-#include <glib.h>
-#include <gpgme.h>
-
-
-GpgmeRecipients gpgmegtk_recipient_selection (GSList *recp_names);
-
-
-#endif /* GPGMEGTK_SELECT_KEYS_H */
index 13bff83a3822290754bf61614ef284c7be83efa5..47ad7b0821c493e5e388dabf70e6da924f68ee22 100644 (file)
@@ -358,6 +358,7 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
        gchar buf[BUFFSIZE];
        GPtrArray *headers = NULL;
        const gchar *name;
+       gchar *content_type;
        gint charcount;
 
        g_return_if_fail(mimeinfo != NULL);
@@ -385,17 +386,18 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
        }
 
        name = procmime_mimeinfo_get_parameter(mimeinfo, "filename");
+       content_type = procmime_get_content_type_str(mimeinfo->type,
+                                                    mimeinfo->subtype);
        if (name == NULL)
                name = procmime_mimeinfo_get_parameter(mimeinfo, "name");
        if (name != NULL)
-               g_snprintf(buf, sizeof(buf), "\n[%s  %s/%s (%d bytes)]\n",
-                          name,
-                          procmime_get_type_str(mimeinfo->type),
-                          mimeinfo->subtype, mimeinfo->length);
+               g_snprintf(buf, sizeof(buf), "\n[%s  %s (%d bytes)]\n",
+                          name, content_type, mimeinfo->length);
        else
-               g_snprintf(buf, sizeof(buf), "\n[%s/%s (%d bytes)]\n",
-                          procmime_get_type_str(mimeinfo->type),
-                          mimeinfo->subtype, mimeinfo->length);
+               g_snprintf(buf, sizeof(buf), "\n[%s (%d bytes)]\n",
+                          content_type, mimeinfo->length);
+
+       g_free(content_type);                      
 
        if (mimeinfo->type != MIMETYPE_TEXT) {
                gtk_text_buffer_insert(buffer, &iter, buf, -1);