Apply new patch from BUG 4426

See: https://www.thewildbeast.co.uk/claws-mail/bugzilla/show_bug.cgi?
id=4426

Fix conflict in AUTHORS file
This commit is contained in:
gfgit 2023-08-30 10:49:45 +02:00
parent cb1597e344
commit c687cee9d9
11 changed files with 462 additions and 195 deletions

View File

@ -348,3 +348,4 @@ contributors (in addition to the above; based on Changelog)
Sakaguchi Takayuki
Charles Huber
nycex
Holger Smolinski

View File

@ -1690,7 +1690,7 @@ static void mimeview_drag_data_get(GtkWidget *widget,
subst_for_filename(name);
}
}
procheader_header_array_destroy(headers);
g_ptr_array_free(headers, TRUE);
}
}
if (fp != NULL)

View File

@ -33,6 +33,7 @@
#include "utils.h"
#include "privacy.h"
#include "procmime.h"
#include "procheader.h"
#include "plugin.h"
#include "pgpmime.h"
@ -707,13 +708,62 @@ static PrivacySystem pgpmime_system = {
prefs_gpg_auto_check_signatures,
};
static MimeParser *protected_headers_parser = NULL;
static void pgpmime_add_header_no_content(void *header, void *data) {
Header *hdr = (Header *)header;
MimeInfo *mimeinfo = (MimeInfo *)data;
if (!procheader_headername_equal(hdr->name,"Content-Type")) {
procmime_mimeinfo_add_extra_header(mimeinfo, hdr);
}
}
static gboolean protected_headers_parse (MimeParser *parser, MimeInfo *mimeinfo) {
FILE *fp;
fp = claws_fopen(mimeinfo->data.filename, "rb");
if (!fp) {
FILE_OP_ERROR(mimeinfo->data.filename, "claws_fopen");
return FALSE;
}
if (fseek(fp, mimeinfo->offset, SEEK_SET) < 0) {
FILE_OP_ERROR(mimeinfo->data.filename, "fseek");
claws_fclose(fp);
return FALSE;
}
GPtrArray *protected_headers = procheader_get_header_array(fp);
if (protected_headers != NULL) {
g_ptr_array_foreach(protected_headers,
pgpmime_add_header_no_content, mimeinfo);
g_ptr_array_free(protected_headers, TRUE);
}
claws_fclose(fp);
return TRUE;
}
void pgpmime_init()
{
protected_headers_parser = g_new0(MimeParser, 1);
protected_headers_parser->type = MIMETYPE_TEXT;
protected_headers_parser->sub_type = "rfc822-headers";
protected_headers_parser->parse = protected_headers_parse;
procmime_mimeparser_register(protected_headers_parser);
privacy_register_system(&pgpmime_system);
}
void pgpmime_done()
{
if (protected_headers_parser != NULL) {
procmime_mimeparser_unregister(protected_headers_parser);
g_free(protected_headers_parser);
protected_headers_parser = NULL;
} else
g_warning("%s:%d protected_headers_parser not initialized",__FUNCTION__,__LINE__);
privacy_unregister_system(&pgpmime_system);
}

View File

@ -326,6 +326,10 @@ static gint decrypt(MimeInfo *mimeinfo, PrivacySystem *system)
procmime_mimeinfo_free_all(&mimeinfo);
if (decryptedinfo->protected_headers) {
parentinfo->protected_headers = decryptedinfo->protected_headers;
decryptedinfo->protected_headers = NULL;
}
g_node_insert(parentinfo->node, childnumber, decryptedinfo->node);
return 0;

View File

@ -265,6 +265,18 @@ gint procheader_get_one_field_asis(gchar **buf, FILE *fp)
FALSE);
}
inline
void procheader_header_free(gpointer ptr)
{
Header *header = (Header*) ptr;
if (!header) return;
g_free(header->name);
g_free(header->body);
g_free(header);
}
GPtrArray *procheader_get_header_array(FILE *fp)
{
gchar *buf = NULL;
@ -273,7 +285,7 @@ GPtrArray *procheader_get_header_array(FILE *fp)
cm_return_val_if_fail(fp != NULL, NULL);
headers = g_ptr_array_new();
headers = g_ptr_array_new_with_free_func(procheader_header_free);
while (procheader_get_one_field(&buf, fp, NULL) != -1) {
if ((header = procheader_parse_header(buf)) != NULL)
@ -285,30 +297,6 @@ GPtrArray *procheader_get_header_array(FILE *fp)
return headers;
}
void procheader_header_array_destroy(GPtrArray *harray)
{
gint i;
Header *header;
cm_return_if_fail(harray != NULL);
for (i = 0; i < harray->len; i++) {
header = g_ptr_array_index(harray, i);
procheader_header_free(header);
}
g_ptr_array_free(harray, TRUE);
}
void procheader_header_free(Header *header)
{
if (!header) return;
g_free(header->name);
g_free(header->body);
g_free(header);
}
/*
tests whether two headers' names are equal
remove the trailing ':' or ' ' before comparing
@ -387,6 +375,41 @@ Header * procheader_parse_header(gchar * buf)
return NULL;
}
static inline void update_hentry(HeaderEntry *hep, gchar *p)
{
while (*p == ' ' || *p == '\t')
p++;
if (hep->body == NULL)
hep->body = g_strdup(p);
else if (procheader_headername_equal(hep->name, "To")
|| procheader_headername_equal(hep->name, "Cc")) {
gchar *tp = hep->body;
hep->body = g_strconcat(tp, ", ", p, NULL);
g_free(tp);
}
}
void procheader_get_all_header_fields(FILE *fp, HeaderEntry hentry[],
GPtrArray *headers) {
char *buf = NULL;
while (procheader_get_one_field_asis(&buf, fp) != -1) {
HeaderEntry *hep = &hentry[0];
while( hep->name != NULL
&& g_ascii_strncasecmp(hep->name, buf, strlen(hep->name)))
hep++;
if (hep->name != NULL) {
gchar *p = buf + strlen(hep->name);
update_hentry(hep, p);
} else {
Header *header = procheader_parse_header(buf);
g_ptr_array_add(headers, header);
}
g_free(buf);
buf = NULL;
}
}
void procheader_get_header_fields(FILE *fp, HeaderEntry hentry[])
{
gchar *buf = NULL;
@ -400,16 +423,8 @@ void procheader_get_header_fields(FILE *fp, HeaderEntry hentry[])
hp = hentry + hnum;
p = buf + strlen(hp->name);
while (*p == ' ' || *p == '\t') p++;
if (hp->body == NULL)
hp->body = g_strdup(p);
else if (procheader_headername_equal(hp->name, "To") ||
procheader_headername_equal(hp->name, "Cc")) {
gchar *tp = hp->body;
hp->body = g_strconcat(tp, ", ", p, NULL);
g_free(tp);
}
update_hentry(hp, p);
g_free(buf);
buf = NULL;
}

View File

@ -48,11 +48,11 @@ gint procheader_get_one_field_asis (gchar **buf,
FILE *fp);
GPtrArray *procheader_get_header_array (FILE *fp);
void procheader_header_array_destroy (GPtrArray *harray);
void procheader_header_free (Header *header);
void procheader_header_free (gpointer header);
gboolean procheader_skip_headers(FILE *fp);
void procheader_get_all_header_fields(FILE *fp, HeaderEntry hentry[], GPtrArray *_headers);
void procheader_get_header_fields (FILE *fp,
HeaderEntry hentry[]);
MsgInfo *procheader_parse_file (const gchar *file,
@ -83,7 +83,6 @@ void procheader_date_get_localtime (gchar *dest,
Header * procheader_parse_header (gchar * buf);
gboolean procheader_headername_equal (char * hdr1, char * hdr2);
void procheader_header_free (Header * header);
gint procheader_get_header_from_msginfo (MsgInfo *msginfo,
gchar **buf,

View File

@ -149,6 +149,9 @@ static gboolean free_func(GNode *node, gpointer data)
if (mimeinfo->sig_data)
privacy_free_signature_data(mimeinfo->sig_data);
if (mimeinfo->protected_headers) {
g_ptr_array_free(mimeinfo->protected_headers, TRUE);
}
g_free(mimeinfo);
return FALSE;
@ -289,6 +292,20 @@ const gchar *procmime_mimeinfo_get_parameter(MimeInfo *mimeinfo, const gchar *na
strcpy(lastline, buf); \
}
void procmime_mimeinfo_add_extra_header (MimeInfo *mimeinfo, Header *header)
{
if (mimeinfo->protected_headers == NULL)
mimeinfo->protected_headers = g_ptr_array_new();
if (mimeinfo->protected_headers != NULL) {
Header *hdr = g_malloc0(sizeof(*hdr));
hdr->name = g_strdup(header->name);
hdr->body = g_strdup(header->body);
g_ptr_array_add(mimeinfo->protected_headers, hdr);
} else
g_warning("%s:%d(%s) failed to add mimeinfo->protected_headers",__FILE__,__LINE__,__FUNCTION__);
}
gboolean procmime_decode_content(MimeInfo *mimeinfo)
{
gchar buf[BUFFSIZE];
@ -1449,7 +1466,22 @@ gchar *procmime_get_content_type_str(MimeMediaType type,
return g_strdup_printf("%s/%s", type_str, subtype);
}
static int procmime_parse_mimepart(MimeInfo *parent,
static MimeInfo * procmime_parse_mimehdrs(MimeInfo *parent,
gchar *content_type,
gchar *content_encoding,
gchar *content_description,
gchar *content_id,
gchar *content_disposition,
gchar *content_location,
const gchar *filename,
guint offset,
guint length);
static gint procmime_parse_mimecontent(MimeInfo *mimeinfo,
const gchar *original_msgid,
const gchar *disposition_notification_hdr,
gboolean short_scan);
static inline gint procmime_parse_mimepart(MimeInfo *parent,
gchar *content_type,
gchar *content_encoding,
gchar *content_description,
@ -1461,7 +1493,20 @@ static int procmime_parse_mimepart(MimeInfo *parent,
const gchar *filename,
guint offset,
guint length,
gboolean short_scan);
gboolean short_scan)
{
gint result = 0;
MimeInfo *childinfo = procmime_parse_mimehdrs(parent,
content_type, content_encoding,
content_description, content_id,
content_disposition, content_location,
filename, offset, length);
result = procmime_parse_mimecontent(childinfo,
original_msgid, disposition_notification_hdr,
short_scan);
return result;
}
static void procmime_parse_message_rfc822(MimeInfo *mimeinfo, gboolean short_scan)
{
@ -1487,6 +1532,7 @@ static void procmime_parse_message_rfc822(MimeInfo *mimeinfo, gboolean short_sca
FILE *fp;
gchar *tmp;
gint len = 0;
GPtrArray *additional_headers = g_ptr_array_new_with_free_func(procheader_header_free);
procmime_decode_content(mimeinfo);
@ -1500,7 +1546,8 @@ static void procmime_parse_message_rfc822(MimeInfo *mimeinfo, gboolean short_sca
claws_fclose(fp);
return;
}
procheader_get_header_fields(fp, hentry);
procheader_get_all_header_fields(fp, hentry, additional_headers);
if (hentry[0].body != NULL) {
tmp = conv_unmime_header(hentry[0].body, NULL, FALSE);
g_free(hentry[0].body);
@ -1538,13 +1585,23 @@ static void procmime_parse_message_rfc822(MimeInfo *mimeinfo, gboolean short_sca
len = mimeinfo->length - (content_start - mimeinfo->offset);
if (len < 0)
len = 0;
procmime_parse_mimepart(mimeinfo,
MimeInfo *childinfo = procmime_parse_mimehdrs(mimeinfo,
hentry[0].body, hentry[1].body,
hentry[2].body, hentry[3].body,
hentry[4].body, hentry[5].body,
hentry[7].body, hentry[8].body,
mimeinfo->data.filename, content_start,
len, short_scan);
len);
if (g_hash_table_lookup(childinfo->typeparameters, "protected-headers")) {
for (int i = 0; i < additional_headers->len; i ++ ) {
Header *hdr = g_ptr_array_index(additional_headers,i);
procmime_mimeinfo_add_extra_header(childinfo, hdr);
}
}
procmime_parse_mimecontent(childinfo,
hentry[7].body, hentry[8].body,
short_scan);
g_ptr_array_free(additional_headers,TRUE);
for (i = 0; i < (sizeof hentry / sizeof hentry[0]); i++) {
g_free(hentry[i].body);
@ -1628,8 +1685,8 @@ bail:
}
}
#define GET_HEADERS() { \
procheader_get_header_fields(fp, hentry); \
#define FILL_HEADERS() { \
gchar *tmp; \
if (hentry[0].body != NULL) { \
tmp = conv_unmime_header(hentry[0].body, NULL, FALSE); \
g_free(hentry[0].body); \
@ -1680,14 +1737,14 @@ static void procmime_parse_multipart(MimeInfo *mimeinfo, gboolean short_scan)
{"Disposition:",
NULL, TRUE},
{NULL, NULL, FALSE}};
gchar *tmp;
gchar *boundary;
gint boundary_len = 0, lastoffset = -1, i;
gint boundary_len = 0, lastoffset = -1;
gchar buf[BUFFSIZE];
FILE *fp;
int result = 0;
gboolean start_found = FALSE;
gboolean end_found = FALSE;
GPtrArray *additional_headers = g_ptr_array_new();
boundary = g_hash_table_lookup(mimeinfo->typeparameters, "boundary");
if (!boundary)
@ -1719,16 +1776,29 @@ static void procmime_parse_multipart(MimeInfo *mimeinfo, gboolean short_scan)
gint len = (ftell(fp) - strlen(buf)) - lastoffset - 1;
if (len < 0)
len = 0;
result = procmime_parse_mimepart(mimeinfo,
MimeInfo *childinfo = procmime_parse_mimehdrs(mimeinfo,
hentry[0].body, hentry[1].body,
hentry[2].body, hentry[3].body,
hentry[4].body, hentry[5].body,
hentry[6].body, hentry[7].body,
mimeinfo->data.filename, lastoffset,
len, short_scan);
len);
if (g_hash_table_lookup(childinfo->typeparameters, "protected-headers")) {
for (int i = 0; i < additional_headers->len; i ++ ) {
Header *hdr = g_ptr_array_index(additional_headers,i);
procmime_mimeinfo_add_extra_header(childinfo, hdr);
}
g_ptr_array_free(additional_headers, TRUE);
}
result = procmime_parse_mimecontent(childinfo,
hentry[6].body, hentry[7].body,
short_scan);
MimeInfo *last_child = g_node_last_child(mimeinfo->node)->data;
if (last_child && last_child->protected_headers) {
mimeinfo->protected_headers = last_child->protected_headers;
last_child->protected_headers = NULL;
}
if (result == 1 && short_scan)
break;
}
if (buf[2 + boundary_len] == '-' &&
@ -1736,15 +1806,16 @@ static void procmime_parse_multipart(MimeInfo *mimeinfo, gboolean short_scan)
end_found = TRUE;
break;
}
for (i = 0; i < (sizeof hentry / sizeof hentry[0]) ; i++) {
g_free(hentry[i].body);
hentry[i].body = NULL;
for (HeaderEntry *curheader = &hentry[0]; curheader->name != NULL; curheader++) {
g_free(curheader->body);
curheader->body = NULL;
}
GET_HEADERS();
additional_headers = g_ptr_array_new();
procheader_get_all_header_fields(fp, hentry, additional_headers);
FILL_HEADERS();
lastoffset = ftell(fp);
}
}
if (start_found && !end_found && lastoffset != -1) {
gint len = (ftell(fp) - strlen(buf)) - lastoffset - 1;
@ -1756,13 +1827,18 @@ static void procmime_parse_multipart(MimeInfo *mimeinfo, gboolean short_scan)
hentry[6].body, hentry[7].body,
mimeinfo->data.filename, lastoffset,
len, short_scan);
MimeInfo *last_child = g_node_last_child(mimeinfo->node)->data;
if (last_child && last_child->protected_headers) {
mimeinfo->protected_headers = last_child->protected_headers;
last_child->protected_headers = NULL;
}
}
mimeinfo->broken = TRUE;
}
for (i = 0; i < (sizeof hentry / sizeof hentry[0]); i++) {
g_free(hentry[i].body);
hentry[i].body = NULL;
for (HeaderEntry *curheader = &hentry[0]; curheader->name != NULL; curheader++) {
g_free(curheader->body);
curheader->body = NULL;
}
claws_fclose(fp);
}
@ -2045,24 +2121,18 @@ static gboolean procmime_mimeparser_parse(MimeParser *parser, MimeInfo *mimeinfo
return parser->parse(parser, mimeinfo);
}
static int procmime_parse_mimepart(MimeInfo *parent,
static MimeInfo *procmime_parse_mimehdrs(MimeInfo *parent,
gchar *content_type,
gchar *content_encoding,
gchar *content_description,
gchar *content_id,
gchar *content_disposition,
gchar *content_location,
const gchar *original_msgid,
const gchar *disposition_notification_hdr,
const gchar *filename,
guint offset,
guint length,
gboolean short_scan)
guint length)
{
MimeInfo *mimeinfo;
MimeParser *parser = NULL;
gboolean parsed = FALSE;
int result = 0;
/* Create MimeInfo */
mimeinfo = procmime_mimeinfo_new();
@ -2075,7 +2145,7 @@ static int procmime_parse_mimepart(MimeInfo *parent,
* with enormous messages
*/
procmime_mimeinfo_free_all(&mimeinfo);
return -1;
return NULL;
}
g_node_append(parent->node, mimeinfo->node);
}
@ -2126,6 +2196,16 @@ static int procmime_parse_mimepart(MimeInfo *parent,
} else
mimeinfo->disposition = DISPOSITIONTYPE_UNKNOWN;
return mimeinfo;
}
static gint procmime_parse_mimecontent(MimeInfo *mimeinfo,
const gchar *original_msgid,
const gchar *disposition_notification_hdr,
gboolean short_scan)
{
MimeParser *parser = NULL;
gboolean parsed = FALSE;
/* Call parser for mime type */
if ((parser = procmime_get_mimeparser_for_type(mimeinfo->type, mimeinfo->subtype)) != NULL) {
parsed = procmime_mimeparser_parse(parser, mimeinfo);
@ -2164,8 +2244,7 @@ static int procmime_parse_mimepart(MimeInfo *parent,
break;
}
}
return result;
return 0;
}
static gchar *typenames[] = {

View File

@ -156,6 +156,8 @@ struct _MimeInfo
SignatureData *sig_data;
gboolean broken;
GPtrArray *protected_headers;
};
#define IS_BOUNDARY(s, bnd, len) \
@ -199,6 +201,8 @@ void procmime_scan_content_description (MimeInfo *mimeinfo,
void procmime_scan_subject (MimeInfo *mimeinfo,
const gchar *subject);
MimeInfo *procmime_scan_mime_header (FILE *fp);
void procmime_mimeinfo_add_extra_header (MimeInfo *mimeinfo,
Header *header);
gboolean procmime_decode_content (MimeInfo *mimeinfo);
gboolean procmime_encode_content (MimeInfo *mimeinfo, EncodingType encoding);

View File

@ -864,6 +864,21 @@ MsgInfo *procmsg_get_msginfo_from_identifier(const gchar *id)
return msginfo;
}
void helper (gpointer data, gpointer user_data) {
MsgInfo * msginfo = (MsgInfo *)user_data;
Header * header = (Header *)data;
if ( procheader_headername_equal(header->name, "Subject") ) {
g_message("Updating msginfo from protected header %s -> %s", header->name, header->body);
if ( msginfo->subject )
g_free(msginfo->subject);
msginfo->subject=g_strdup(header->body);
}
}
void procmsg_update_msginfo_headers(MsgInfo * msginfo, GPtrArray *protected_headers){
g_ptr_array_foreach(protected_headers, helper, msginfo);
}
static GSList *procmsg_list_sort_by_account(FolderItem *queue, GSList *list)
{
GSList *result = NULL;

View File

@ -405,4 +405,5 @@ gchar *procmsg_msginfo_get_identifier(MsgInfo *msginfo);
gchar *procmsg_msginfo_get_avatar(MsgInfo *msginfo, gint type);
void procmsg_msginfo_add_avatar(MsgInfo *msginfo, gint type, const gchar *data);
void procmsg_update_msginfo_headers(MsgInfo * msginfo, GPtrArray *protected_headers);
#endif /* __PROCMSG_H__ */

View File

@ -71,6 +71,12 @@
#include "avatars.h"
#include "file-utils.h"
static GdkRGBA header_bgcolors[3] = {
{1, 1, 1, 1},
{0.5, 1, 0.5, 1},
{1, 1, 0.5, 1}
};
static GdkRGBA quote_colors[3] = {
{0, 0, 0, 1},
{0, 0, 0, 1},
@ -167,7 +173,13 @@ static void textview_write_link (TextView *textview,
static GPtrArray *textview_scan_header (TextView *textview,
FILE *fp);
static void textview_show_header (TextView *textview,
GPtrArray *headers);
GPtrArray *headers,
GPtrArray *protected_headers);
static void textview_sort_headers (GPtrArray *headers,
GPtrArray *target);
static void textview_append_single_header (TextView *textview,
Header *header,
gint verified);
static void textview_zoom(GtkWidget *widget, gboolean zoom_in);
static void textview_zoom_in(GtkWidget *widget, gpointer data);
@ -438,10 +450,34 @@ static void textview_create_tags(GtkTextView *text, TextView *textview)
"font-desc", font_desc,
"left-margin", 3,
"left-margin-set", TRUE,
"background-rgba", &header_bgcolors[0],
NULL);
gtk_text_buffer_create_tag(buffer, "header_verified",
"pixels-above-lines", 0,
"pixels-above-lines-set", TRUE,
"pixels-below-lines", 0,
"pixels-below-lines-set", TRUE,
"font-desc", font_desc,
"left-margin", 3,
"left-margin-set", TRUE,
"background-rgba", &header_bgcolors[1],
NULL);
gtk_text_buffer_create_tag(buffer, "header_modified",
"pixels-above-lines", 0,
"pixels-above-lines-set", TRUE,
"pixels-below-lines", 0,
"pixels-below-lines-set", TRUE,
"font-desc", font_desc,
"left-margin", 3,
"left-margin-set", TRUE,
"background-rgba", &header_bgcolors[2],
NULL);
gtk_text_buffer_create_tag(buffer, "header_title",
"font-desc", bold_font_desc,
NULL);
gtk_text_buffer_create_tag(buffer, "header_title_original",
"font-desc", font_desc,
NULL);
tag = gtk_text_buffer_create_tag(buffer, "hlink",
"pixels-above-lines", 0,
"pixels-above-lines-set", TRUE,
@ -685,14 +721,30 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
}
headers = textview_scan_header(textview, fp);
if (headers) {
if (fseek(fp, mimeinfo->offset, SEEK_SET) < 0) {
FILE_OP_ERROR(mimeinfo->data.filename, "fseek");
claws_fclose(fp);
END_TIMING();
return;
}
if (charcount > 0)
gtk_text_buffer_insert(buffer, &iter, "\n", 1);
if (procmime_mimeinfo_parent(mimeinfo) == NULL &&
!prefs_common.display_header_pane)
textview_show_tags(textview);
textview_show_header(textview, headers);
procheader_header_array_destroy(headers);
if (mimeinfo->protected_headers) {
MsgInfo * msginfo = textview->messageview->msginfo;
GPtrArray *protected_headers = g_ptr_array_new();
textview_sort_headers(mimeinfo->protected_headers, protected_headers);
procmsg_update_msginfo_headers(msginfo, protected_headers);
textview_show_header(textview, headers, protected_headers);
g_ptr_array_free(protected_headers, TRUE);
g_ptr_array_free(mimeinfo->protected_headers, TRUE);
mimeinfo->protected_headers = NULL;
} else
textview_show_header(textview, headers, NULL);
g_ptr_array_free(headers, TRUE);
}
claws_fclose(fp);
END_TIMING();
@ -775,6 +827,8 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
END_TIMING();
GTK_EVENTS_FLUSH();
}
} else if (mimeinfo->type == MIMETYPE_TEXT &&
!g_ascii_strcasecmp(mimeinfo->subtype, "rfc822-headers")) {
} else if (mimeinfo->type == MIMETYPE_TEXT) {
if (prefs_common.display_header && (charcount > 0))
gtk_text_buffer_insert(buffer, &iter, "\n", 1);
@ -1915,31 +1969,48 @@ void textview_set_position(TextView *textview, gint pos)
gtkut_text_view_set_position(text, pos);
}
static void textview_copy_headers_without_internal(GPtrArray *headers, GPtrArray *target) {
while(headers->len) {
Header *header = g_ptr_array_steal_index(headers, 0);
if (!procheader_header_is_internal(header->name))
g_ptr_array_add(target, header);
else
procheader_header_free(header);
}
}
static void textview_sort_headers(GPtrArray *headers, GPtrArray *sorted_headers) {
GSList *disphdr_list;
for (disphdr_list = prefs_common.disphdr_list; disphdr_list != NULL;
disphdr_list = disphdr_list->next) {
DisplayHeaderProp *dp =
(DisplayHeaderProp *)disphdr_list->data;
gint i;
for (i = 0; i < headers->len; i++) {
Header *header;
header = g_ptr_array_index(headers, i);
if (procheader_headername_equal(header->name,
dp->name)) {
header = g_ptr_array_steal_index(headers, i);
if (dp->hidden)
procheader_header_free(header);
else
g_ptr_array_add(sorted_headers, header);
i--;
}
}
}
}
static GPtrArray *textview_scan_header(TextView *textview, FILE *fp)
{
gchar buf[BUFFSIZE];
GPtrArray *headers, *sorted_headers;
GSList *disphdr_list;
Header *header;
gint i;
cm_return_val_if_fail(fp != NULL, NULL);
if (prefs_common.show_all_headers) {
headers = procheader_get_header_array(fp);
sorted_headers = g_ptr_array_new();
for (i = 0; i < headers->len; i++) {
header = g_ptr_array_index(headers, i);
if (!procheader_header_is_internal(header->name))
g_ptr_array_add(sorted_headers, header);
else
procheader_header_free(header);
}
g_ptr_array_free(headers, TRUE);
return sorted_headers;
}
if (!prefs_common.display_header) {
gchar buf[BUFFSIZE];
while (claws_fgets(buf, sizeof(buf), fp) != NULL)
if (buf[0] == '\r' || buf[0] == '\n') break;
return NULL;
@ -1947,43 +2018,13 @@ static GPtrArray *textview_scan_header(TextView *textview, FILE *fp)
headers = procheader_get_header_array(fp);
sorted_headers = g_ptr_array_new();
for (disphdr_list = prefs_common.disphdr_list; disphdr_list != NULL;
disphdr_list = disphdr_list->next) {
DisplayHeaderProp *dp =
(DisplayHeaderProp *)disphdr_list->data;
for (i = 0; i < headers->len; i++) {
header = g_ptr_array_index(headers, i);
if (procheader_headername_equal(header->name,
dp->name)) {
if (dp->hidden)
procheader_header_free(header);
else
g_ptr_array_add(sorted_headers, header);
g_ptr_array_remove_index(headers, i);
i--;
}
}
}
if (prefs_common.show_other_header) {
for (i = 0; i < headers->len; i++) {
header = g_ptr_array_index(headers, i);
unfold_line(header->body);
if (!procheader_header_is_internal(header->name)) {
g_ptr_array_add(sorted_headers, header);
} else {
procheader_header_free(header);
}
}
g_ptr_array_free(headers, TRUE);
} else
procheader_header_array_destroy(headers);
sorted_headers = g_ptr_array_new_with_free_func(procheader_header_free);
if (prefs_common.show_all_headers || prefs_common.show_other_header)
textview_copy_headers_without_internal(headers, sorted_headers);
else
textview_sort_headers(headers, sorted_headers);
g_ptr_array_free(headers, TRUE);
return sorted_headers;
}
@ -2257,85 +2298,62 @@ static void textview_show_tags(TextView *textview)
"header", "tags", NULL);
}
static void textview_show_header(TextView *textview, GPtrArray *headers)
#define HEADER_NOT_VERIFIABLE 0
#define HEADER_NOT_VERIFIED -(i+1)
#define HEADER_VERIFIED (i+1)
static gint textview_verify_protected_header(Header *header, GPtrArray *protected_headers)
{
GtkTextView *text = GTK_TEXT_VIEW(textview->text);
GtkTextBuffer *buffer = gtk_text_view_get_buffer(text);
GtkTextIter iter;
Header *header;
gint verified = HEADER_NOT_VERIFIABLE;
gint i;
if (protected_headers != NULL) {
for (i=0; i<protected_headers->len; i++) {
Header *hdr = (Header *)g_ptr_array_index(protected_headers,i);
if (!procheader_headername_equal(header->name, hdr->name))
continue;
verified = -(i+1);
if (g_ascii_strncasecmp(hdr->body,header->body,
strlen(hdr->body) < strlen(header->body) ?
strlen(hdr->body) : strlen(header->body)) == 0) {
verified = -verified;
break;
}
}
}
return verified;
}
static void textview_show_header(TextView *textview, GPtrArray *headers , GPtrArray *protected_headers)
{
Header *header, *phdr;
gint i;
gint verified,display;
cm_return_if_fail(headers != NULL);
for (i = 0; i < headers->len; i++) {
header = g_ptr_array_index(headers, i);
cm_return_if_fail(header->name != NULL);
gtk_text_buffer_get_end_iter (buffer, &iter);
if(prefs_common.trans_hdr == TRUE) {
gchar *hdr = g_strndup(header->name, strlen(header->name) - 1);
gchar *trans_hdr = gettext(hdr);
gtk_text_buffer_insert_with_tags_by_name(buffer,
&iter, trans_hdr, -1,
"header_title", "header", NULL);
gtk_text_buffer_insert_with_tags_by_name(buffer,
&iter, ":", 1, "header_title", "header", NULL);
g_free(hdr);
} else {
gtk_text_buffer_insert_with_tags_by_name(buffer,
&iter, header->name,
-1, "header_title", "header", NULL);
verified = textview_verify_protected_header(header, protected_headers);
if (verified != HEADER_NOT_VERIFIABLE) {
phdr = g_ptr_array_index(protected_headers, abs(verified) - 1);
if (verified < 0)
textview_append_single_header(textview,phdr,1);
procheader_header_free(phdr);
g_ptr_array_remove_index(protected_headers, abs(verified) - 1);
}
if (header->name[strlen(header->name) - 1] != ' ')
gtk_text_buffer_insert_with_tags_by_name
(buffer, &iter, " ", 1,
"header_title", "header", NULL);
if (procheader_headername_equal(header->name, "Subject") ||
procheader_headername_equal(header->name, "From") ||
procheader_headername_equal(header->name, "To") ||
procheader_headername_equal(header->name, "Cc") ||
procheader_headername_equal(header->name, "Bcc") ||
procheader_headername_equal(header->name, "Reply-To") ||
procheader_headername_equal(header->name, "Sender") ||
procheader_headername_equal(header->name, "Resent-From") ||
procheader_headername_equal(header->name, "Resent-To"))
unfold_line(header->body);
if (procheader_headername_equal(header->name, "Date") &&
prefs_common.msgview_date_format) {
gchar hbody[80];
procheader_date_parse(hbody, header->body, sizeof(hbody));
gtk_text_buffer_get_end_iter (buffer, &iter);
gtk_text_buffer_insert_with_tags_by_name
(buffer, &iter, hbody, -1, "header", NULL);
} else if ((procheader_headername_equal(header->name, "X-Mailer") ||
procheader_headername_equal(header->name,
"X-Newsreader")) &&
(strstr(header->body, "Claws Mail") != NULL ||
strstr(header->body, "Sylpheed-Claws") != NULL)) {
gtk_text_buffer_get_end_iter (buffer, &iter);
gtk_text_buffer_insert_with_tags_by_name
(buffer, &iter, header->body, -1,
"header", "emphasis", NULL);
} else {
gboolean hdr =
procheader_headername_equal(header->name, "From") ||
procheader_headername_equal(header->name, "To") ||
procheader_headername_equal(header->name, "Cc") ||
procheader_headername_equal(header->name, "Bcc") ||
procheader_headername_equal(header->name, "Reply-To") ||
procheader_headername_equal(header->name, "Sender") ||
procheader_headername_equal(header->name, "Resent-From") ||
procheader_headername_equal(header->name, "Resent-To");
textview_make_clickable_parts(textview, "header",
"hlink", header->body,
hdr);
display = (verified > 0) ? 1 : (verified < 0) ? -1 : 0;
textview_append_single_header(textview, header, display);
}
if (protected_headers) {
for (i = 0; i < protected_headers->len; i++) {
textview_append_single_header(textview,
g_ptr_array_index(protected_headers, i),
i+1);
}
gtk_text_buffer_get_end_iter (buffer, &iter);
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "\n", 1,
"header", NULL);
}
textview_show_avatar(textview);
@ -2344,6 +2362,87 @@ static void textview_show_header(TextView *textview, GPtrArray *headers)
textview_show_contact_pic(textview);
}
static void textview_append_single_header(TextView *textview, Header *header, gint verified)
{
GtkTextView *text = GTK_TEXT_VIEW(textview->text);
GtkTextBuffer *buffer = gtk_text_view_get_buffer(text);
GtkTextIter iter;
gchar *header_tag;
if (verified > 0)
header_tag = "header_verified";
else if (verified < 0)
header_tag = "header_modified";
else
header_tag = "header";
gtk_text_buffer_get_end_iter (buffer, &iter);
if(prefs_common.trans_hdr == TRUE) {
gchar *hdr = g_strndup(header->name, strlen(header->name) - 1);
gchar *trans_hdr = gettext(hdr);
gtk_text_buffer_insert_with_tags_by_name(buffer,
&iter, trans_hdr, -1,
"header_title", header_tag, NULL);
gtk_text_buffer_insert_with_tags_by_name(buffer,
&iter, ":", 1, "header_title", header_tag, NULL);
g_free(hdr);
} else {
gtk_text_buffer_insert_with_tags_by_name(buffer,
&iter, header->name,
-1, "header_title", header_tag, NULL);
}
if (header->name[strlen(header->name) - 1] != ' ')
gtk_text_buffer_insert_with_tags_by_name
(buffer, &iter, " ", 1,
"header_title", header_tag, NULL);
if (procheader_headername_equal(header->name, "Subject") ||
procheader_headername_equal(header->name, "From") ||
procheader_headername_equal(header->name, "To") ||
procheader_headername_equal(header->name, "Cc") ||
procheader_headername_equal(header->name, "Bcc") ||
procheader_headername_equal(header->name, "Reply-To") ||
procheader_headername_equal(header->name, "Sender") ||
procheader_headername_equal(header->name, "Resent-From") ||
procheader_headername_equal(header->name, "Resent-To"))
unfold_line(header->body);
if (procheader_headername_equal(header->name, "Date") &&
prefs_common.msgview_date_format) {
gchar hbody[80];
procheader_date_parse(hbody, header->body, sizeof(hbody));
gtk_text_buffer_get_end_iter (buffer, &iter);
gtk_text_buffer_insert_with_tags_by_name
(buffer, &iter, hbody, -1, header_tag, NULL);
} else if ((procheader_headername_equal(header->name, "X-Mailer") ||
procheader_headername_equal(header->name,
"X-Newsreader")) &&
(strstr(header->body, "Claws Mail") != NULL ||
strstr(header->body, "Sylpheed-Claws") != NULL)) {
gtk_text_buffer_get_end_iter (buffer, &iter);
gtk_text_buffer_insert_with_tags_by_name
(buffer, &iter, header->body, -1,
header_tag, "emphasis", NULL);
} else {
gboolean hdr =
procheader_headername_equal(header->name, "From") ||
procheader_headername_equal(header->name, "To") ||
procheader_headername_equal(header->name, "Cc") ||
procheader_headername_equal(header->name, "Bcc") ||
procheader_headername_equal(header->name, "Reply-To") ||
procheader_headername_equal(header->name, "Sender") ||
procheader_headername_equal(header->name, "Resent-From") ||
procheader_headername_equal(header->name, "Resent-To");
textview_make_clickable_parts(textview, header_tag,
"hlink", header->body,
hdr);
}
gtk_text_buffer_get_end_iter (buffer, &iter);
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "\n", 1,
header_tag, NULL);
}
gboolean textview_search_string(TextView *textview, const gchar *str,
gboolean case_sens)
{