Compare commits

...

6 commits

Author SHA1 Message Date
gfgit 9af4ccb9ad PGPMime: return full decrypted message instead of first child 2023-08-26 20:03:23 +02:00
gfgit f3f7e7ad45 TextView: move header extraction to textview_process_headers()
Allow to extract headers from MULTIPART messages too
2023-08-26 20:02:20 +02:00
gfgit 40734845db Substitute Subject header when decrypting
- New procmsg_extract_subject() to get better subject from
  MIME child parts recursively
- Use it for HeaderView and SummaryView
2023-08-26 19:58:10 +02:00
gfgit 6710e0ec6b PGP/MIME: fix leak of MimeInfo if parsing fails 2023-08-26 19:48:03 +02:00
gfgit 9d0d7ecc8d CMake: enable GPGME plugin sources 2023-08-26 19:45:35 +02:00
gfgit 21d139a922 Add initial CMake project file 2023-08-19 17:45:14 +02:00
8 changed files with 247 additions and 34 deletions

101
CMakeLists.txt Normal file
View file

@ -0,0 +1,101 @@
cmake_minimum_required(VERSION 3.5)
project(ClawsMail LANGUAGES C)
## Dependencies ##
find_package(PkgConfig REQUIRED)
pkg_check_modules(GLib REQUIRED glib-2.0)
pkg_check_modules(GTK REQUIRED gtk+-3.0)
pkg_check_modules(GDK_PIXBUF REQUIRED gdk-pixbuf-2.0)
pkg_check_modules(libetpan REQUIRED libetpan)
pkg_check_modules(pgpme REQUIRED gpgme)
pkg_check_modules(gnutls REQUIRED gnutls)
## Source files ##
file(GLOB SOURCES
"config.h"
"src/*.h"
"src/*.c"
"src/common/*.h"
"src/common/*.c"
"src/etpan/*.h"
"src/etpan/*.c"
"src/gtk/*.h"
"src/gtk/*.c"
"src/plugins/pgpcore/*.h"
"src/plugins/pgpcore/*.c"
"src/plugins/pgpmime/*.h"
"src/plugins/pgpmime/*.c")
add_executable(ClawsMail)
target_sources(ClawsMail PRIVATE ${SOURCES})
target_include_directories(ClawsMail PRIVATE ${CMAKE_SOURCE_DIR})
target_include_directories(ClawsMail PRIVATE ${CMAKE_SOURCE_DIR}/src)
target_include_directories(ClawsMail PRIVATE ${CMAKE_SOURCE_DIR}/src/common)
target_include_directories(ClawsMail PRIVATE ${CMAKE_SOURCE_DIR}/src/etpan)
target_include_directories(ClawsMail PRIVATE ${CMAKE_SOURCE_DIR}/src/gtk)
target_compile_definitions(ClawsMail PRIVATE -DUSE_GPGME)
## GLib 2.0 ##
target_link_libraries(ClawsMail PRIVATE ${GLib_LIBRARIES})
target_compile_definitions(ClawsMail PRIVATE ${GLib_CFLAGS_OTHER})
target_include_directories(ClawsMail PRIVATE ${GLib_INCLUDE_DIRS})
target_link_directories(ClawsMail PRIVATE ${GLib_LIBRARY_DIRS})
## GTK 3.0 ##
target_link_libraries(ClawsMail PRIVATE ${GTK_LIBRARIES})
# Add other flags to the compiler
target_compile_definitions(ClawsMail PRIVATE ${GTK_CFLAGS_OTHER})
# Setup CMake to use GTK+, tell the compiler where to look for headers
# and to the linker where to look for libraries
target_include_directories(ClawsMail PRIVATE ${GTK_INCLUDE_DIRS})
target_link_directories(ClawsMail PRIVATE ${GTK_LIBRARY_DIRS})
## GdkPixbuf 2.0 ##
target_link_libraries(ClawsMail PRIVATE ${GdkPixbuf_LIBRARIES})
target_compile_definitions(ClawsMail PRIVATE ${GdkPixbuf_CFLAGS_OTHER})
target_include_directories(ClawsMail PRIVATE ${GdkPixbuf_INCLUDE_DIRS})
target_link_directories(ClawsMail PRIVATE ${GdkPixbuf_LIBRARY_DIRS})
## libetpan ##
target_link_libraries(ClawsMail PRIVATE ${libetpan_LIBRARIES})
target_compile_definitions(ClawsMail PRIVATE ${libetpan_CFLAGS_OTHER})
target_include_directories(ClawsMail PRIVATE ${libetpan_INCLUDE_DIRS})
target_link_directories(ClawsMail PRIVATE ${libetpan_LIBRARY_DIRS})
## GPGME ##
target_link_libraries(ClawsMail PRIVATE ${gpgme_LIBRARIES})
target_compile_definitions(ClawsMail PRIVATE ${gpgme_CFLAGS_OTHER})
target_include_directories(ClawsMail PRIVATE ${gpgme_INCLUDE_DIRS})
target_link_directories(ClawsMail PRIVATE ${gpgme_LIBRARY_DIRS})
## GnuTLS ##
target_link_libraries(ClawsMail PRIVATE ${gnutls_LIBRARIES})
target_compile_definitions(ClawsMail PRIVATE ${gnutls_CFLAGS_OTHER})
target_include_directories(ClawsMail PRIVATE ${gnutls_INCLUDE_DIRS})
target_link_directories(ClawsMail PRIVATE ${gnutls_LIBRARY_DIRS})
## Installation ##
install(TARGETS ClawsMail
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

View file

@ -1431,6 +1431,25 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
messageview_set_menu_sensitive(messageview);
messageview->msginfo = msginfo;
}
// Extract a better subject from encrypted content
gchar *alt_subject = procmsg_extract_subject(mimeinfo);
if(alt_subject) {
g_free(messageview->msginfo->subject);
messageview->msginfo->subject = alt_subject;
GtkCMCTreeNode *summary_node = summary_find_msg_by_msgnum(
messageview->mainwin->summaryview,
messageview->msginfo->msgnum);
GtkCMCTree *ctree = GTK_CMCTREE(messageview->mainwin->summaryview->ctree);
gtk_cmctree_node_set_pixtext(ctree,
summary_node,
ctree->tree_column,
alt_subject,
0, NULL);
}
if (prefs_common.display_header_pane)
headerview_show(messageview->headerview, messageview->msginfo);

View file

@ -316,17 +316,22 @@ static MimeInfo *pgpmime_decrypt(MimeInfo *mimeinfo)
privacy_free_signature_data(sig_data);
return NULL;
}
/*
decinfo = g_node_first_child(parseinfo->node) != NULL ?
g_node_first_child(parseinfo->node)->data : NULL;
if (decinfo == NULL) {
privacy_set_error(_("Couldn't parse decrypted file parts."));
if (sig_data)
privacy_free_signature_data(sig_data);
procmime_mimeinfo_free_all(&parseinfo);
return NULL;
}
g_node_unlink(decinfo->node);
procmime_mimeinfo_free_all(&parseinfo);
*/
decinfo = parseinfo;
decinfo->tmp = TRUE;

View file

@ -2582,3 +2582,83 @@ void procmsg_msginfo_clear_tags(MsgInfo *msginfo)
folder_item_commit_tags(msginfo->folder, msginfo, NULL, unset);
g_slist_free(unset);
}
static GPtrArray *extract_headers(FILE *fp)
{
gchar buf[BUFFSIZE];
GPtrArray *headers, *sorted_headers;
Header *header;
gint i;
cm_return_val_if_fail(fp != NULL, NULL);
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;
}
static gchar *extract_subject(MimeInfo *mimeinfo)
{
GPtrArray *headers = NULL;
FILE *fp;
gchar *subject = NULL;
Header *header;
gint i;
if (mimeinfo->content == MIMECONTENT_MEM)
fp = str_open_as_stream(mimeinfo->data.mem);
else
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;
}
headers = extract_headers(fp);
if (headers) {
for (i = 0; i < headers->len; i++) {
header = g_ptr_array_index(headers, i);
if (!strcmp(header->name, "Subject:")) {
subject = g_strdup(header->body);
break;
}
}
procheader_header_array_destroy(headers);
}
claws_fclose(fp);
if(subject)
unfold_line(subject);
return subject;
}
gchar *procmsg_extract_subject(MimeInfo *mimeinfo)
{
GNode *iter;
gchar *subject = extract_subject(mimeinfo);
if(subject && strcmp(subject, "...") != 0)
return subject;
g_free(subject);
for (iter = g_node_first_child(mimeinfo->node) ; iter != NULL ;
iter = g_node_next_sibling(iter)) {
subject = procmsg_extract_subject((MimeInfo *) iter->data);
if(subject && strcmp(subject, "...") != 0)
return subject;
g_free(subject);
}
return NULL;
}

View file

@ -405,4 +405,6 @@ 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);
gchar *procmsg_extract_subject(MimeInfo *mimeinfo);
#endif /* __PROCMSG_H__ */

View file

@ -150,10 +150,6 @@ static GtkCMCTreeNode *summary_find_next_flagged_msg
MsgPermFlags flags,
gboolean start_from_next);
static GtkCMCTreeNode *summary_find_msg_by_msgnum
(SummaryView *summaryview,
guint msgnum);
static void summary_update_status (SummaryView *summaryview);
/* display functions */
@ -2473,7 +2469,7 @@ static GtkCMCTreeNode *summary_find_next_flagged_msg(SummaryView *summaryview,
return node;
}
static GtkCMCTreeNode *summary_find_msg_by_msgnum(SummaryView *summaryview,
GtkCMCTreeNode *summary_find_msg_by_msgnum(SummaryView *summaryview,
guint msgnum)
{
GtkCMCTree *ctree = GTK_CMCTREE(summaryview->ctree);

View file

@ -338,4 +338,8 @@ gboolean summary_is_list(SummaryView *summaryview);
gboolean summaryview_search_root_progress(gpointer data, guint at, guint matched, guint total);
gboolean summary_is_opened_message_selected(SummaryView *summaryview);
gboolean summary_has_opened_message(SummaryView *summaryview);
GtkCMCTreeNode *summary_find_msg_by_msgnum
(SummaryView *summaryview,
guint msgnum);
#endif /* __SUMMARY_H__ */

View file

@ -636,6 +636,39 @@ void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
END_TIMING();
}
static gboolean textview_process_headers(TextView *textview, MimeInfo *mimeinfo,
gint charcount, GtkTextBuffer *buffer, GtkTextIter iter)
{
GPtrArray *headers = NULL;
FILE *fp;
if (mimeinfo->content == MIMECONTENT_MEM)
fp = str_open_as_stream(mimeinfo->data.mem);
else
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;
}
headers = textview_scan_header(textview, fp);
if (headers) {
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);
}
claws_fclose(fp);
return TRUE;
}
static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
{
GtkAllocation allocation;
@ -643,7 +676,6 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
GtkTextBuffer *buffer;
GtkTextIter iter, start_iter;
gchar buf[BUFFSIZE];
GPtrArray *headers = NULL;
const gchar *name;
gchar *content_type;
gint charcount;
@ -660,6 +692,7 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
return;
}
if (mimeinfo->type == MIMETYPE_MULTIPART) {
textview_process_headers(textview, mimeinfo, charcount, buffer, iter);
END_TIMING();
return;
}
@ -667,34 +700,7 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo)
textview->prev_quote_level = -1;
if ((mimeinfo->type == MIMETYPE_MESSAGE) && !g_ascii_strcasecmp(mimeinfo->subtype, "rfc822")) {
FILE *fp;
if (mimeinfo->content == MIMECONTENT_MEM)
fp = str_open_as_stream(mimeinfo->data.mem);
else
fp = claws_fopen(mimeinfo->data.filename, "rb");
if (!fp) {
FILE_OP_ERROR(mimeinfo->data.filename, "claws_fopen");
END_TIMING();
return;
}
if (fseek(fp, mimeinfo->offset, SEEK_SET) < 0) {
FILE_OP_ERROR(mimeinfo->data.filename, "fseek");
claws_fclose(fp);
END_TIMING();
return;
}
headers = textview_scan_header(textview, fp);
if (headers) {
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);
}
claws_fclose(fp);
textview_process_headers(textview, mimeinfo, charcount, buffer, iter);
END_TIMING();
return;
}