From 26277daf7daf3e384de945e1dc7302b9aaba6775 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Sat, 15 Oct 2016 13:45:45 +0200 Subject: [PATCH] Send MR_EVENT_MSGS_ADDED event. --- src/mrimap.c | 46 +++++++++++++++++++++++++++++++--------------- src/mrimfparser.c | 7 +++++-- src/mrimfparser.h | 4 ++-- src/mrmailbox.c | 24 ++++++++++++++++++++---- src/mrmailbox.h | 2 +- 5 files changed, 59 insertions(+), 24 deletions(-) diff --git a/src/mrimap.c b/src/mrimap.c index 360067b2..65b75051 100644 --- a/src/mrimap.c +++ b/src/mrimap.c @@ -148,10 +148,16 @@ static char* Mr_get_msg_att_msg_content(struct mailimap_msg_att* msg_att, size_t static int mrimap_fetch_single_msg(mrimap_t* ths, mrimapthreadval_t* threadval, const char* folder, /* only needed for statistical/debugging purposes, the correct folder is already selected when this function is called */ - uint32_t flocal_uid) + uint32_t flocal_uid, + size_t* created_db_entries) { - /* we're inside a working thread! - the function returns 0 if the caller should try over fetch message again, else 1. */ + /* the function returns: + 0 on errors; in this case, the caller should try over again later + or 1 if the messages should be treated as received (even if no database entries are returned) + + moreover, the function copies the nubmer or really created database entries to ret_created_database_entries. + + Finally, remember, we're inside a working thread! */ size_t msg_len; char* msg_content; FILE* f; @@ -187,7 +193,7 @@ static int mrimap_fetch_single_msg(mrimap_t* ths, mrimapthreadval_t* threadval, { clistiter* cur = clist_begin(fetch_result); if( cur == NULL ) { - mrlog_error("mrimap_fetch_single_msg(): Empty message."); + mrlog_warning("mrimap_fetch_single_msg(): Empty message."); return 1; /* error, however, do not try to fetch the message again */ } @@ -213,22 +219,22 @@ static int mrimap_fetch_single_msg(mrimap_t* ths, mrimapthreadval_t* threadval, } /* add to our respository */ - mrmailbox_receive_imf_(ths->m_mailbox, msg_content, msg_len); + *created_db_entries = mrmailbox_receive_imf_(ths->m_mailbox, msg_content, msg_len); mailimap_fetch_list_free(fetch_result); - return 1; /* success, message fetched */ + return 1; /* Success, messages fetched. However, the amount in created_db_entries may be 0. */ } -static void fetch_from_single_folder(mrimap_t* ths, mrimapthreadval_t* threadval, const char* folder) +static size_t fetch_from_single_folder(mrimap_t* ths, mrimapthreadval_t* threadval, const char* folder) { /* we're inside a working thread! */ int r; clist* fetch_result = NULL; uint32_t in_first_uid = 0; /* the first uid to fetch, if 0, get all */ uint32_t out_largetst_uid = 0; - int read_cnt = 0, read_errors = 0; + size_t read_cnt = 0, read_errors = 0, created_db_entries = 0; char* config_key = NULL; clistiter* cur; @@ -292,14 +298,19 @@ static void fetch_from_single_folder(mrimap_t* ths, mrimapthreadval_t* threadval uint32_t cur_uid = Mr_get_uid(msg_att); if( cur_uid && (in_first_uid==0 || cur_uid>in_first_uid) ) { + size_t temp_created_db_entries = 0; + if( cur_uid > out_largetst_uid ) { out_largetst_uid = cur_uid; } read_cnt++; - if( !mrimap_fetch_single_msg(ths, threadval, folder, cur_uid) ) { + if( mrimap_fetch_single_msg(ths, threadval, folder, cur_uid, &temp_created_db_entries) == 0 ) { read_errors++; } + else { + created_db_entries += temp_created_db_entries; /* may be 0 eg. for empty messages. This is NO error. */ + } } } @@ -315,7 +326,7 @@ static void fetch_from_single_folder(mrimap_t* ths, mrimapthreadval_t* threadval /* done */ FetchFromFolder_Done: { - char* temp = sqlite3_mprintf("%i mails read from \"%s\" with %i errors.", read_cnt, folder, read_errors); + char* temp = sqlite3_mprintf("%i mails read from \"%s\" with %i errors; %i messages created.", (int)read_cnt, folder, (int)read_errors, (int)created_db_entries); if( read_errors ) { mrlog_error(temp); } @@ -332,15 +343,18 @@ FetchFromFolder_Done: if( config_key ) { sqlite3_free(config_key); } + + return created_db_entries; } -static void fetch_from_all_folders(mrimap_t* ths, mrimapthreadval_t* threadval) +static size_t fetch_from_all_folders(mrimap_t* ths, mrimapthreadval_t* threadval) { /* we're inside a working thread! */ + size_t created_db_entries = 0; /* check INBOX */ - fetch_from_single_folder(ths, threadval, "INBOX"); + created_db_entries += fetch_from_single_folder(ths, threadval, "INBOX"); /* check other folders */ int r; @@ -365,7 +379,7 @@ static void fetch_from_all_folders(mrimap_t* ths, mrimapthreadval_t* threadval) { if( !Mr_ignore_folder(name_utf8) ) { - fetch_from_single_folder(ths, threadval, name_utf8); + created_db_entries += fetch_from_single_folder(ths, threadval, name_utf8); } else { @@ -378,7 +392,7 @@ static void fetch_from_all_folders(mrimap_t* ths, mrimapthreadval_t* threadval) } FetchFromAllFolders_Done: - ; + return created_db_entries; } @@ -435,7 +449,9 @@ static void mrimap_working_thread__(mrimap_t* ths) { case MR_THREAD_FETCH: mrlog_info("Received MR_THREAD_FETCH signal."); - fetch_from_all_folders(ths, &threadval); + if( fetch_from_all_folders(ths, &threadval) > 0 ) { + ths->m_mailbox->m_cb(ths->m_mailbox, MR_EVENT_MSGS_ADDED, 0, 0); + } break; case MR_THREAD_EXIT: diff --git a/src/mrimfparser.c b/src/mrimfparser.c index 9504846e..d695d0bb 100644 --- a/src/mrimfparser.c +++ b/src/mrimfparser.c @@ -216,8 +216,9 @@ static void mrimfparser_add_or_lookup_contacts_by_address_list(mrimfparser_t* th ******************************************************************************/ -int32_t mrimfparser_imf2msg_(mrimfparser_t* ths, const char* imf_raw_not_terminated, size_t imf_raw_bytes) +size_t mrimfparser_imf2msg_(mrimfparser_t* ths, const char* imf_raw_not_terminated, size_t imf_raw_bytes) { + /* the function returns the number of created messages in the database */ carray* contact_ids_from = NULL; carray* contact_ids_to = NULL; uint32_t contact_id_from = 0; /* 1=self */ @@ -233,6 +234,7 @@ int32_t mrimfparser_imf2msg_(mrimfparser_t* ths, const char* imf_raw_not_termina int db_locked = 0; int transaction_pending = 0; clistiter* cur1; + size_t created_db_entries = 0; /* create arrays that will hold from: and to: lists */ contact_ids_from = carray_new(16); @@ -401,6 +403,7 @@ int32_t mrimfparser_imf2msg_(mrimfparser_t* ths, const char* imf_raw_not_termina } dblocal_id = sqlite3_last_insert_rowid(ths->m_mailbox->m_sql->m_cobj); + created_db_entries++; if( contact_ids_to ) { s = mrsqlite3_predefine(ths->m_mailbox->m_sql, INSERT_INTO_msgs_to_mc, "INSERT INTO msgs_to (msg_id, contact_id) VALUES (?,?);"); @@ -446,5 +449,5 @@ Imf2Msg_Done: carray_free(contact_ids_to); } - return 0; + return created_db_entries; } diff --git a/src/mrimfparser.h b/src/mrimfparser.h index a43b9823..af1899c2 100644 --- a/src/mrimfparser.h +++ b/src/mrimfparser.h @@ -46,8 +46,8 @@ mrimfparser_t* mrimfparser_new_ (mrmailbox_t* mailbox); void mrimfparser_unref_ (mrimfparser_t*); /* Imf2Msg() takes an IMF, convers into one or more messages and stores them in the database. -the function returns the number of new created messages. */ -int32_t mrimfparser_imf2msg_(mrimfparser_t*, const char* imf_raw_not_terminated, size_t imf_raw_bytes); +the function returns the number of new created database message entries. */ +size_t mrimfparser_imf2msg_(mrimfparser_t*, const char* imf_raw_not_terminated, size_t imf_raw_bytes); #ifdef __cplusplus diff --git a/src/mrmailbox.c b/src/mrmailbox.c index 552d4373..3024abe1 100644 --- a/src/mrmailbox.c +++ b/src/mrmailbox.c @@ -49,6 +49,13 @@ ******************************************************************************/ +static uintptr_t cb_dummy(mrmailbox_t* mailbox, int event, uintptr_t data1, uintptr_t data2) +{ + mrlog_warning("Unhandled event: %i (%i, %i)", (int)event, (int)data1, (int)data2); + return 0; +} + + mrmailbox_t* mrmailbox_new(mrmailboxcb_t cb, void* userData) { mrmailbox_t* ths = NULL; @@ -61,7 +68,7 @@ mrmailbox_t* mrmailbox_new(mrmailboxcb_t cb, void* userData) ths->m_imap = mrimap_new(ths); ths->m_dbfile = NULL; ths->m_blobdir = NULL; - ths->m_cb = cb; + ths->m_cb = cb? cb : cb_dummy; /* avoid a NULL-pointer! */ ths->m_userData = userData; return ths; @@ -211,7 +218,9 @@ int mrmailbox_import_file(mrmailbox_t* ths, const char* filename) f = NULL; /* import `data` */ - mrmailbox_receive_imf_(ths, data, stat_info.st_size); + if( mrmailbox_receive_imf_(ths, data, stat_info.st_size) == 0 ) { + mrlog_warning("Import: No message could be created from \"%s\".", filename); + } /* success */ success = 1; @@ -292,6 +301,9 @@ int mrmailbox_import_spec(mrmailbox_t* ths, const char* spec) /* spec is a file, } mrlog_info("Import: %i mails read from \"%s\".", read_cnt, spec); + if( read_cnt > 0 ) { + ths->m_cb(ths, MR_EVENT_MSGS_ADDED, 0, 0); /* even if read_cnt>0, the number of messages added to the database may be 0. While we regard this issue using IMAP, we ignore it here. */ + } /* success */ success = 1; @@ -385,11 +397,13 @@ int mrmailbox_fetch(mrmailbox_t* ths) ******************************************************************************/ -void mrmailbox_receive_imf_(mrmailbox_t* ths, const char* imf_raw_not_terminated, size_t imf_raw_bytes) +size_t mrmailbox_receive_imf_(mrmailbox_t* ths, const char* imf_raw_not_terminated, size_t imf_raw_bytes) { + size_t created_db_entries = 0; mrimfparser_t* parser = mrimfparser_new_(ths); - if( !mrimfparser_imf2msg_(parser, imf_raw_not_terminated, imf_raw_bytes) ) { + created_db_entries = mrimfparser_imf2msg_(parser, imf_raw_not_terminated, imf_raw_bytes); + if( created_db_entries == 0 ) { goto ReceiveCleanup; /* error already logged */ } @@ -398,6 +412,8 @@ ReceiveCleanup: if( parser ) { mrimfparser_unref_(parser); } + + return created_db_entries; } diff --git a/src/mrmailbox.h b/src/mrmailbox.h index bfe704eb..e5301d13 100644 --- a/src/mrmailbox.h +++ b/src/mrmailbox.h @@ -139,7 +139,7 @@ char* mrmailbox_execute (mrmailbox_t*, const char* c /*** library-private **********************************************************/ -void mrmailbox_receive_imf_ (mrmailbox_t*, const char* imf, size_t imf_len); /* when fetching messages, this normally results in calls to ReceiveImf(). CAVE: ReceiveImf() may be called from within a working thread! */ +size_t mrmailbox_receive_imf_ (mrmailbox_t*, const char* imf, size_t imf_len); /* when fetching messages, this normally results in calls to ReceiveImf(). CAVE: ReceiveImf() may be called from within a working thread! Returns the number of created database message entries. */ #ifdef __cplusplus