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:
parent
cb1597e344
commit
c687cee9d9
1
AUTHORS
1
AUTHORS
|
@ -348,3 +348,4 @@ contributors (in addition to the above; based on Changelog)
|
|||
Sakaguchi Takayuki
|
||||
Charles Huber
|
||||
nycex
|
||||
Holger Smolinski
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
145
src/procmime.c
145
src/procmime.c
|
@ -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[] = {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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__ */
|
||||
|
|
347
src/textview.c
347
src/textview.c
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue