+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
+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
( 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
MICRO_VERSION=12
INTERFACE_AGE=0
BINARY_AGE=0
-EXTRA_VERSION=122
+EXTRA_VERSION=124
EXTRA_RELEASE=
EXTRA_GTK2_VERSION=.1
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
+])
news.c \
news_gtk.c \
noticeview.c \
- passphrase.c \
pine.c \
pop.c \
prefs_account.c \
quote_fmt_parse.y \
recv.c \
remotefolder.c \
- rfc2015.c \
- select-keys.c \
send_message.c \
setup.c \
simple-gettext.c \
news.h \
news_gtk.h \
noticeview.h \
- passphrase.h \
pine.h \
pop.h \
prefs_account.h \
quote_fmt_parse.h \
recv.h \
remotefolder.h \
- rfc2015.h \
- select-keys.h \
send_message.h \
setup.h \
sourcewindow.h \
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;
}
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);
void trim_subject_for_compare(gchar *str)
{
- guchar *srcp;
+ gchar *srcp;
eliminate_parenthesis(str, '[', ']');
eliminate_parenthesis(str, '(', ')');
void trim_subject_for_sort(gchar *str)
{
- guchar *srcp;
+ gchar *srcp;
g_strstrip(str);
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));
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;
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
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,
#include "foldersel.h"
#include "toolbar.h"
-#if USE_GPGME
-# include "rfc2015.h"
-#endif
-
typedef enum
{
COL_MIMETYPE = 0,
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);
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,
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,
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},
{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},
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);
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:")]);
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 */
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
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);
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
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;
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)
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) \
{ \
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 = "";
#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);
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;
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:",
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);
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;
}
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;
}
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;
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) {
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");
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))) {
}
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;
}
}
unlink(tmp);
g_free(tmp);
- unlink(tmp2);
- g_free(tmp2);
if (compose->mode == COMPOSE_REEDIT) {
compose_remove_reedit_target(compose);
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) \
g_string_append(fieldstr, str);
add_field = TRUE;
}
+ g_free(str);
}
}
if (add_field) {
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;
/* 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));
strlen("Subject: "), FALSE);
g_string_sprintfa(header, "Subject: %s\n", buf);
}
+ g_free(tmpstr);
}
/* Message-ID */
}
}
- /* 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"
g_free(headername_wcolon);
}
- /* separator between header and body */
- g_string_sprintfa(header, "\n");
-
str = header->str;
g_string_free(header, FALSE);
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);
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,
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;
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);
/* 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);
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)
{
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;
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",
{
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);
}
MsgFlags flag = {0, 0};
static gboolean lock = FALSE;
MsgInfo *newmsginfo;
+ FILE *fp;
if (lock) return;
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) {
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);
}
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)
{
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,
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)
/* privacy settings */
gboolean use_signing;
gboolean use_encryption;
-
- gint gnupg_mode;
+ gchar *privacy_system;
gboolean modified;
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);
#if HAVE_LIBJCONV
" libjconv"
#endif
-#if USE_GPGME
- " GPGME"
-#endif
#if USE_OPENSSL
" OpenSSL"
#endif
#if HAVE_LIBCOMPFACE
" compface"
#endif
-#if USE_GPGME
- " GnuPG"
-#endif
#if USE_OPENSSL
" OpenSSL"
#endif
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 "
# include <gdk/gdkx.h>
#endif
-#if USE_GPGME
-# include <gpgme.h>
-# include "passphrase.h"
-#endif
-
#include "sylpheed.h"
#include "intl.h"
#include "main.h"
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");
}
+++ /dev/null
-/* 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 */
+++ /dev/null
-/* 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 */
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
#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>
#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"
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);
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));
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);
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);
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;
}
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) {
- 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);
}
-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
#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;
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);
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);
gpgme_data_release(sigdata);
gpgme_data_release(textdata);
- g_string_free(textstr, TRUE);
+ g_free(textstr);
fclose(fp);
return 0;
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);
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);
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);
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) {
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 */
pgpmime_is_encrypted, /* is_encrypted(MimeInfo *) */
pgpmime_decrypt, /* decrypt(MimeInfo *) */
+
+ TRUE,
+ pgpmime_sign,
+
+ TRUE,
+ pgpmime_get_encrypt_data,
+ pgpmime_encrypt,
};
void pgpmime_init()
#include "version.h"
#include "sgpgme.h"
#include "pgpmime.h"
+#include "prefs_gpg.h"
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();
}
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);
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);
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);
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"),
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);
}
-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;
}
#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)
{
struct passphrase_cb_info_s info;
GpgmeData plain;
GpgmeError err;
- GpgmeSigStat sigstat;
memset (&info, 0, sizeof info);
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) !=
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
"to be upgraded.\n"
"OpenPGP support disabled."), ALERT_WARNING);
if (val & G_ALERTDISABLE)
- prefs_common.gpg_warning = FALSE;
+ prefs_gpg.gpg_warning = FALSE;
}
}
void sgpgme_done()
{
gpgmegtk_free_passphrase();
+ gpgme_register_idle(NULL);
}
#endif /* USE_GPGME */
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 */
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 {
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);
&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,
{"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 */
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 */
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++);
compose.autoreplyto_entry = autoreplyto_entry;
}
-#if USE_GPGME
static void prefs_account_privacy_create(void)
{
GtkWidget *vbox1;
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
}
}
-#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;
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"
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;
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;
{"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},
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);
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();
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;
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);
+}
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 {
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;
}
{
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);
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)
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");
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;
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;
{NULL, 0},
};
-const gchar *procmime_get_type_str(MimeMediaType type)
+const gchar *procmime_get_media_type_str(MimeMediaType type)
{
struct TypeTable *type_table;
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.
*
{
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);
}
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);
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);
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] == '-' &&
fclose(fp);
}
-static void add_to_mimeinfo_parameters(gchar **parts, MimeInfo *mimeinfo)
+static void add_to_mimeinfo_parameters(gchar **parts, GHashTable *table)
{
gchar **strarray;
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]));
}
gchar **content_type_parts;
gchar **strarray;
gchar *str;
- struct TypeTable *typetablearray;
g_return_if_fail(content_type != NULL);
g_return_if_fail(mimeinfo != NULL);
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);
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);
}
/* 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);
} 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)
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;
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);
return mimeinfo;
}
-MimeInfo *procmime_scan_file(gchar *filename)
+MimeInfo *procmime_scan_file(const gchar *filename)
{
MimeInfo *mimeinfo;
return mimeinfo;
}
-MimeInfo *procmime_scan_queue_file(gchar *filename)
+MimeInfo *procmime_scan_queue_file(const gchar *filename)
{
FILE *fp;
MimeInfo *mimeinfo;
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;
+}
{
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>
struct _MimeInfo
{
/* Internal data */
- gchar *filename;
- gboolean tmpfile;
+ MimeContent content;
+ union
+ {
+ gchar *filename;
+ gchar *data;
+ };
+ gboolean tmp;
GNode *node;
MimeMediaType type;
gchar *subtype;
- GHashTable *parameters;
+ GHashTable *typeparameters;
/* Content-Transfer-Encoding */
EncodingType encoding_type;
/* Content-Disposition */
DispositionType disposition;
+ GHashTable *dispositionparameters;
/* Privacy */
PrivacyData *privacy;
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);
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 */
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)
{"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;
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;
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) {
}
fseek(fp, filepos, SEEK_SET);
- if (newsgroup_list && (newsval == 0)) {
+ if (newsgroup_list && (mailval == 0)) {
Folder *folder;
gchar *tmp = NULL;
FILE *tmpfp;
+++ /dev/null
-/*
- * 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 */
+++ /dev/null
-/*
- * 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__ */
+++ /dev/null
-/* 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*/
+++ /dev/null
-/* 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 */
gchar buf[BUFFSIZE];
GPtrArray *headers = NULL;
const gchar *name;
+ gchar *content_type;
gint charcount;
g_return_if_fail(mimeinfo != NULL);
}
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);