#include "displayheader.h"
#include "account.h"
#include "mimeview.h"
+#include "alertpanel.h"
typedef struct _RemoteURI RemoteURI;
FILE *fp,
CodeConverter *conv);
static void textview_add_part (TextView *textview,
- MimeInfo *mimeinfo,
- FILE *fp);
+ MimeInfo *mimeinfo);
static void textview_add_parts (TextView *textview,
- MimeInfo *mimeinfo,
- FILE *fp);
+ MimeInfo *mimeinfo);
static void textview_write_body (TextView *textview,
MimeInfo *mimeinfo,
- FILE *fp,
const gchar *charset);
static void textview_show_html (TextView *textview,
FILE *fp,
charset = textview->messageview->forced_charset;
else if (prefs_common.force_charset)
charset = prefs_common.force_charset;
- else if (mimeinfo->charset)
- charset = mimeinfo->charset;
+ else
+ charset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
textview_set_font(textview, charset);
textview_clear(textview);
textview->body_pos = gtk_stext_get_length(text);
}
*/
- textview_add_parts(textview, mimeinfo, fp);
+ textview_add_parts(textview, mimeinfo);
gtk_stext_thaw(text);
if ((mimeinfo->type == MIMETYPE_MULTIPART) ||
((mimeinfo->type == MIMETYPE_MESSAGE) && !g_strcasecmp(mimeinfo->subtype, "rfc822"))) {
textview_clear(textview);
- textview_add_parts(textview, mimeinfo, fp);
+ textview_add_parts(textview, mimeinfo);
return;
}
charset = textview->messageview->forced_charset;
else if (prefs_common.force_charset)
charset = prefs_common.force_charset;
- else if (mimeinfo->charset)
- charset = mimeinfo->charset;
+ else
+ charset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
textview_set_font(textview, charset);
}
*/
if (mimeinfo->type == MIMETYPE_MULTIPART)
- textview_add_parts(textview, mimeinfo, fp);
+ textview_add_parts(textview, mimeinfo);
else
- textview_write_body(textview, mimeinfo, fp, charset);
+ textview_write_body(textview, mimeinfo, charset);
gtk_stext_thaw(text);
}
-static void textview_add_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
+static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
{
GtkSText *text = GTK_STEXT(textview->text);
gchar buf[BUFFSIZE];
GPtrArray *headers = NULL;
g_return_if_fail(mimeinfo != NULL);
- g_return_if_fail(fp != NULL);
if (mimeinfo->type == MIMETYPE_MULTIPART) return;
- if (fseek(fp, mimeinfo->offset, SEEK_SET) < 0) {
- perror("fseek");
- return;
- }
-
if ((mimeinfo->type == MIMETYPE_MESSAGE) && !g_strcasecmp(mimeinfo->subtype, "rfc822")) {
+ FILE *fp;
+
+ fp = fopen(mimeinfo->filename, "rb");
+ fseek(fp, mimeinfo->offset, SEEK_SET);
headers = textview_scan_header(textview, fp);
if (headers) {
gtk_stext_freeze(text);
procheader_header_array_destroy(headers);
gtk_stext_thaw(text);
}
+ fclose(fp);
return;
}
if (mimeinfo->type != MIMETYPE_TEXT) {
gtk_stext_insert(text, NULL, NULL, NULL, buf, -1);
} else {
- if (!mimeinfo->main &&
- mimeinfo->parent &&
- mimeinfo->parent->children != mimeinfo)
- gtk_stext_insert(text, NULL, NULL, NULL, buf, -1);
- else if (prefs_common.display_header && (gtk_stext_get_length(text) > 0))
+ if (prefs_common.display_header && (gtk_stext_get_length(text) > 0))
gtk_stext_insert(text, NULL, NULL, NULL, "\n", 1);
if (textview->messageview->forced_charset)
charset = textview->messageview->forced_charset;
else if (prefs_common.force_charset)
charset = prefs_common.force_charset;
- else if (mimeinfo->charset)
- charset = mimeinfo->charset;
- textview_write_body(textview, mimeinfo, fp, charset);
+ else
+ charset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
+
+ textview_write_body(textview, mimeinfo, charset);
}
gtk_stext_thaw(text);
}
-static void textview_add_parts_func(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
+#if 0
+static gboolean add_parts_func(GNode *node, gpointer data)
{
- g_return_if_fail(mimeinfo != NULL);
- g_return_if_fail(fp != NULL);
+ MimeInfo *mimeinfo = (MimeInfo *) node->data;
+ TextView *textview = (TextView *) data;
- while (mimeinfo) {
- textview_add_part(textview, mimeinfo, fp);
- if(mimeinfo->children)
- textview_add_parts_func(textview, mimeinfo->children, fp);
- mimeinfo = mimeinfo->next;
- }
+ g_return_val_if_fail(mimeinfo != NULL, FALSE);
+
+ textview_add_part(textview, mimeinfo);
+
+ return FALSE;
}
-static void textview_add_parts(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
+static void textview_add_parts(TextView *textview, MimeInfo *mimeinfo)
{
g_return_if_fail(mimeinfo != NULL);
- g_return_if_fail(fp != NULL);
- textview_add_part(textview, mimeinfo, fp);
- if(mimeinfo->children)
- textview_add_parts_func(textview, mimeinfo->children, fp);
+ g_node_traverse(mimeinfo->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, add_parts_func, textview);
+}
+#endif
+
+static void recursive_add_parts(TextView *textview, GNode *node)
+{
+ GNode * iter;
+ MimeInfo *mimeinfo;
+
+ mimeinfo = (MimeInfo *) node->data;
+
+ textview_add_part(textview, mimeinfo);
+
+ if ((mimeinfo->type != MIMETYPE_MULTIPART) &&
+ (mimeinfo->type != MIMETYPE_MESSAGE))
+ return;
+
+ if (strcasecmp(mimeinfo->subtype, "alternative") == 0) {
+ GNode * prefered_body;
+ int prefered_score;
+
+ /*
+ text/plain : score 3
+ text/ * : score 2
+ other : score 1
+ */
+ prefered_body = NULL;
+ prefered_score = 0;
+
+ for(iter = g_node_first_child(node) ; iter != NULL ;
+ iter = g_node_next_sibling(iter)) {
+ int score;
+ MimeInfo * submime;
+
+ score = 1;
+ submime = (MimeInfo *) iter->data;
+ if (submime->type == MIMETYPE_TEXT)
+ score = 2;
+
+ if (submime->subtype != NULL) {
+ if (strcasecmp(submime->subtype, "plain") == 0)
+ score = 3;
+ }
+
+ if (score > prefered_score) {
+ prefered_score = score;
+ prefered_body = iter;
+ }
+ }
+
+ if (prefered_body != NULL) {
+ recursive_add_parts(textview, prefered_body);
+ }
+ }
+ else {
+ for(iter = g_node_first_child(node) ; iter != NULL ;
+ iter = g_node_next_sibling(iter)) {
+ recursive_add_parts(textview, iter);
+ }
+ }
+}
+
+static void textview_add_parts(TextView *textview, MimeInfo *mimeinfo)
+{
+ g_return_if_fail(mimeinfo != NULL);
+
+ recursive_add_parts(textview, mimeinfo->node);
}
#define TEXT_INSERT(str) \
#undef TEXT_INSERT
static void textview_write_body(TextView *textview, MimeInfo *mimeinfo,
- FILE *fp, const gchar *charset)
+ const gchar *charset)
{
FILE *tmpfp;
gchar buf[BUFFSIZE];
mimeinfo->encoding_type != ENC_8BIT)
procmime_decode_content(mimeinfo);
-
if (!g_strcasecmp(mimeinfo->subtype, "html")) {
gchar *filename;
spacingfont = gdk_font_load("-*-*-medium-r-normal--6-*");
}
+void textview_set_text(TextView *textview, const gchar *text)
+{
+ GtkSText *stext;
+
+ g_return_if_fail(textview != NULL);
+ g_return_if_fail(text != NULL);
+
+ textview_clear(textview);
+
+ stext = GTK_STEXT(textview->text);
+ gtk_stext_freeze(stext);
+ gtk_stext_insert(stext, textview->msgfont, NULL, NULL, text, strlen(text));
+ gtk_stext_thaw(stext);
+}
+
enum
{
H_DATE = 0,
if (summaryview)
summary_pass_key_press_event(summaryview, event);
break;
- case GDK_n:
- case GDK_N:
- case GDK_p:
- case GDK_P:
case GDK_y:
case GDK_t:
case GDK_l:
- KEY_PRESS_EVENT_STOP();
- mimeview_pass_key_press_event(messageview->mimeview,
- event);
- /* fall through */
+ if ((event->state & (GDK_MOD1_MASK|GDK_CONTROL_MASK)) == 0) {
+ KEY_PRESS_EVENT_STOP();
+ mimeview_pass_key_press_event(messageview->mimeview,
+ event);
+ break;
+ }
+ /* possible fall through */
default:
if (summaryview &&
event->window != messageview->mainwin->window->window) {
return FALSE;
}
+/*!
+ *\brief Check to see if a web URL has been disguised as a different
+ * URL (possible with HTML email).
+ *
+ *\param uri The uri to check
+ *
+ *\param textview The TextView the URL is contained in
+ *
+ *\return gboolean TRUE if the URL is ok, or if the user chose to open
+ * it anyway, otherwise FALSE
+ */
+static gboolean uri_security_check(RemoteURI *uri, TextView *textview)
+{
+ gchar *clicked_str;
+ gboolean retval = TRUE;
+
+ if (g_strncasecmp(uri->uri, "http:", 5) &&
+ g_strncasecmp(uri->uri, "https:", 6) &&
+ g_strncasecmp(uri->uri, "www.", 4))
+ return retval;
+
+ clicked_str = gtk_editable_get_chars(GTK_EDITABLE(textview->text),
+ uri->start,
+ uri->end);
+
+ if (strcmp(clicked_str, uri->uri) &&
+ (!g_strncasecmp(clicked_str, "http:", 5) ||
+ !g_strncasecmp(clicked_str, "https:", 6) ||
+ !g_strncasecmp(clicked_str, "www.", 4))) {
+ retval = FALSE;
+
+ /* allow uri->uri == http://somewhere.com
+ and clicked_str == somewhere.com */
+ gchar *str = g_strconcat("http://", clicked_str, NULL);
+
+ if (!g_strcasecmp(str, uri->uri))
+ retval = TRUE;
+ g_free(str);
+ }
+
+ if (retval == FALSE) {
+ gchar *msg = NULL;
+ AlertValue resp;
+
+ msg = g_strdup_printf(_("The real URL (%s) is different from\n"
+ "the apparent URL (%s). \n"
+ "Open it anyway?"),
+ uri->uri, clicked_str);
+ resp = alertpanel(_("Warning"),
+ msg,
+ _("Yes"),
+ _("No"),
+ NULL);
+ g_free(msg);
+ if (resp == G_ALERTDEFAULT)
+ retval = TRUE;
+ }
+ g_free(clicked_str);
+ return retval;
+}
+
static gint textview_button_pressed(GtkWidget *widget, GdkEventButton *event,
TextView *textview)
{
compose_new(account, uri->uri + 7, NULL);
}
} else {
- open_uri(uri->uri,
- prefs_common.uri_cmd);
+ if (uri_security_check(uri, textview) == TRUE)
+ open_uri(uri->uri,
+ prefs_common.uri_cmd);
}
g_free(trimmed_uri);
}