Browse Source

update core

Jonas Reinsch 7 years ago
parent
commit
94f4ccbf30

+ 0 - 1
deltachat-ios/deltachat-ios-Bridging-Header.h

@@ -4,4 +4,3 @@
 
 #include "mrmailbox.h"
 #include "wrapper.h"
-#include "mrmailbox_internal.h"

+ 12 - 11
deltachat-ios/libraries/deltachat-core/cmdline/cmdline.c

@@ -167,7 +167,6 @@ char* mrmailbox_cmdline(mrmailbox_t* mailbox, const char* cmdline)
 			"configurecancel\n"
 			"connect\n"
 			"disconnect\n"
-			"fetch\n"
 			"restore <days>\n"
 
 			"\nChat commands:\n"
@@ -365,10 +364,6 @@ char* mrmailbox_cmdline(mrmailbox_t* mailbox, const char* cmdline)
 		mrmailbox_disconnect(mailbox);
 		ret = COMMAND_SUCCEEDED;
 	}
-	else if( strcmp(cmd, "fetch")==0 )
-	{
-		ret = mrmailbox_fetch(mailbox)? COMMAND_SUCCEEDED : COMMAND_FAILED;
-	}
 	else if( strcmp(cmd, "restore")==0 )
 	{
 		if( arg1 ) {
@@ -659,7 +654,8 @@ char* mrmailbox_cmdline(mrmailbox_t* mailbox, const char* cmdline)
 	{
 		if( arg1 ) {
 			int chat_id = atoi(arg1);
-			ret = mrmailbox_archive_chat(mailbox, chat_id, strcmp(cmd, "archive")==0? 1 : 0)!=0? COMMAND_SUCCEEDED : COMMAND_FAILED;
+			mrmailbox_archive_chat(mailbox, chat_id, strcmp(cmd, "archive")==0? 1 : 0);
+			ret = COMMAND_SUCCEEDED;
 		}
 		else {
 			ret = safe_strdup("ERROR: Argument <chat-id> missing.");
@@ -669,7 +665,8 @@ char* mrmailbox_cmdline(mrmailbox_t* mailbox, const char* cmdline)
 	{
 		if( arg1 ) {
 			int chat_id = atoi(arg1);
-			ret = mrmailbox_delete_chat(mailbox, chat_id)!=0? COMMAND_SUCCEEDED : COMMAND_FAILED;
+			mrmailbox_delete_chat(mailbox, chat_id);
+			ret = COMMAND_SUCCEEDED;
 		}
 		else {
 			ret = safe_strdup("ERROR: Argument <chat-id> missing.");
@@ -708,7 +705,8 @@ char* mrmailbox_cmdline(mrmailbox_t* mailbox, const char* cmdline)
 			*arg2 = 0; arg2++;
 			uint32_t msg_ids[1], chat_id = atoi(arg2);
 			msg_ids[0] = atoi(arg1);
-			ret = mrmailbox_forward_msgs(mailbox, msg_ids, 1, chat_id)? COMMAND_SUCCEEDED : COMMAND_FAILED;
+			mrmailbox_forward_msgs(mailbox, msg_ids, 1, chat_id);
+			ret = COMMAND_SUCCEEDED;
 		}
 		else {
 			ret = safe_strdup("ERROR: Arguments <msg-id> <chat-id> expected.");
@@ -719,7 +717,8 @@ char* mrmailbox_cmdline(mrmailbox_t* mailbox, const char* cmdline)
 		if( arg1 ) {
 			uint32_t msg_ids[1];
 			msg_ids[0] = atoi(arg1);
-			ret = mrmailbox_markseen_msgs(mailbox, msg_ids, 1)? COMMAND_SUCCEEDED : COMMAND_FAILED;
+			mrmailbox_markseen_msgs(mailbox, msg_ids, 1);
+			ret = COMMAND_SUCCEEDED;
 		}
 		else {
 			ret = safe_strdup("ERROR: Argument <msg-id> missing.");
@@ -730,7 +729,8 @@ char* mrmailbox_cmdline(mrmailbox_t* mailbox, const char* cmdline)
 		if( arg1 ) {
 			uint32_t msg_ids[1];
 			msg_ids[0] = atoi(arg1);
-			ret = mrmailbox_star_msgs(mailbox, msg_ids, 1, strcmp(cmd, "star")==0? 1 : 0)? COMMAND_SUCCEEDED : COMMAND_FAILED;
+			mrmailbox_star_msgs(mailbox, msg_ids, 1, strcmp(cmd, "star")==0? 1 : 0);
+			ret = COMMAND_SUCCEEDED;
 		}
 		else {
 			ret = safe_strdup("ERROR: Argument <msg-id> missing.");
@@ -741,7 +741,8 @@ char* mrmailbox_cmdline(mrmailbox_t* mailbox, const char* cmdline)
 		if( arg1 ) {
 			uint32_t ids[1];
 			ids[0] = atoi(arg1);
-			ret = mrmailbox_delete_msgs(mailbox, ids, 1)? COMMAND_SUCCEEDED : COMMAND_FAILED;
+			mrmailbox_delete_msgs(mailbox, ids, 1);
+			ret = COMMAND_SUCCEEDED;
 		}
 		else {
 			ret = safe_strdup("ERROR: Argument <msg-id> missing.");

+ 2 - 2
deltachat-ios/libraries/deltachat-core/doxygen.config

@@ -771,7 +771,7 @@ WARN_LOGFILE           =
 # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = src/mrmailbox.h
+INPUT                  = src/mrmailbox.h src/mrmailbox.c src/mrmailbox_configure.c src/mrmsg.c src/mrcontact.c src/mrchat.c src/mrchatlist.c src/mrpoortext.c
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -2152,7 +2152,7 @@ HIDE_UNDOC_RELATIONS   = YES
 # set to NO
 # The default value is: YES.
 
-HAVE_DOT               = YES
+HAVE_DOT               = NO
 
 # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
 # to run in parallel. When set to 0 doxygen will base this on the number of

+ 247 - 14
deltachat-ios/libraries/deltachat-core/src/mrchat.c

@@ -317,13 +317,35 @@ int mrchat_load_from_db__(mrchat_t* ths, uint32_t id)
  ******************************************************************************/
 
 
-mrchatlist_t* mrmailbox_get_chatlist(mrmailbox_t* ths, int listflags, const char* query)
+/**
+ * Get a list of chats.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned by mrmailbox_new()
+ *
+ * @param listflags A combination of flags:
+ *     - if the flag MR_GCL_ARCHIVED_ONLY is set, only archived chats are returned.
+ *       if MR_GCL_ARCHIVED_ONLY is not set, only unarchived chats are returned and
+ *       the pseudo-chat MR_CHAT_ID_ARCHIVED_LINK is added if there are _any_ archived
+ *       chats
+ *     - if the flag MR_GCL_NO_SPECIALS is set, deaddrop and archive link are not added
+ *       to the list (may be used eg. for selecting chats on forwarding, the flag is
+ *      F not needed when MR_GCL_ARCHIVED_ONLY is already set)
+
+ * @param query An optional query for filtering the list.  Only chats matching this query
+ *     are returned.  Give NULL for no filtering.
+ *
+ * @return A chatlist as an mrchatlist_t object. Must be freed using
+ *     mrchatlist_unref() when no longer used
+ */
+mrchatlist_t* mrmailbox_get_chatlist(mrmailbox_t* mailbox, int listflags, const char* query)
 {
 	int success = 0;
 	int db_locked = 0;
-	mrchatlist_t* obj = mrchatlist_new(ths);
+	mrchatlist_t* obj = mrchatlist_new(mailbox);
 
-	mrsqlite3_lock(ths->m_sql);
+	mrsqlite3_lock(mailbox->m_sql);
 	db_locked = 1;
 
 	if( !mrchatlist_load_from_db__(obj, listflags, query) ) {
@@ -337,7 +359,7 @@ mrchatlist_t* mrmailbox_get_chatlist(mrmailbox_t* ths, int listflags, const char
 	/* cleanup */
 cleanup:
 	if( db_locked ) {
-		mrsqlite3_unlock(ths->m_sql);
+		mrsqlite3_unlock(mailbox->m_sql);
 	}
 
 	if( success ) {
@@ -350,7 +372,20 @@ cleanup:
 }
 
 
-mrchat_t* mrmailbox_get_chat(mrmailbox_t* ths, uint32_t id)
+/**
+ * Get a chat object of type mrchat_t by a chat_id.
+ * To access the mrchat_t object, see mrchat.h
+ * The result must be unref'd using mrchat_unref().
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ *
+ * @param chat_id The ID of the chat to get the chat object for.
+ *
+ * @return A chat object, must be freed using mrchat_unref() when done.
+ */
+mrchat_t* mrmailbox_get_chat(mrmailbox_t* ths, uint32_t chat_id)
 {
 	int success = 0;
 	int db_locked = 0;
@@ -359,7 +394,7 @@ mrchat_t* mrmailbox_get_chat(mrmailbox_t* ths, uint32_t id)
 	mrsqlite3_lock(ths->m_sql);
 	db_locked = 1;
 
-	if( !mrchat_load_from_db__(obj, id) ) {
+	if( !mrchat_load_from_db__(obj, chat_id) ) {
 		goto cleanup;
 	}
 
@@ -382,6 +417,16 @@ cleanup:
 }
 
 
+/**
+ * mrmailbox_marknoticed_chat() marks all message in a whole chat as NOTICED.
+ * NOTICED messages are no longer FRESH and do not count as being unseen.
+ * IMAP/MDNs is not done for noticed messages.  See also mrmailbox_marknoticed_contact()
+ * and mrmailbox_markseen_msgs()
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ */
 int mrmailbox_marknoticed_chat(mrmailbox_t* ths, uint32_t chat_id)
 {
 	/* marking a chat as "seen" is done by marking all fresh chat messages as "noticed" -
@@ -405,6 +450,15 @@ int mrmailbox_marknoticed_chat(mrmailbox_t* ths, uint32_t chat_id)
 }
 
 
+/**
+ * If there is a normal chat with the given contact_id, this chat_id is
+ * retunred.  If there is no normal chat with the contact_id, the function
+ * returns 0
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ */
 uint32_t mrmailbox_get_chat_id_by_contact_id(mrmailbox_t* mailbox, uint32_t contact_id)
 {
 	uint32_t chat_id = 0;
@@ -419,6 +473,14 @@ uint32_t mrmailbox_get_chat_id_by_contact_id(mrmailbox_t* mailbox, uint32_t cont
 }
 
 
+/**
+ * Create a normal chat with a single user.  To create group chats,
+ * see mrmailbox_create_group_chat()
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ */
 uint32_t mrmailbox_create_chat_by_contact_id(mrmailbox_t* ths, uint32_t contact_id)
 {
 	uint32_t      chat_id = 0;
@@ -482,6 +544,14 @@ static carray* mrmailbox_get_chat_media__(mrmailbox_t* mailbox, uint32_t chat_id
 }
 
 
+/**
+ * Returns all message IDs of the given types in a chat.  Typically used to show
+ * a gallery.  The result must be carray_free()'d
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ */
 carray* mrmailbox_get_chat_media(mrmailbox_t* mailbox, uint32_t chat_id, int msg_type, int or_msg_type)
 {
 	carray* ret = NULL;
@@ -496,6 +566,14 @@ carray* mrmailbox_get_chat_media(mrmailbox_t* mailbox, uint32_t chat_id, int msg
 }
 
 
+/**
+ * Returns all message IDs of the given types in a chat.  Typically used to show
+ * a gallery.  The result must be carray_free()'d
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ */
 uint32_t mrmailbox_get_next_media(mrmailbox_t* mailbox, uint32_t curr_msg_id, int dir)
 {
 	uint32_t ret_msg_id = 0;
@@ -551,6 +629,24 @@ cleanup:
 }
 
 
+/**
+ * mrmailbox_get_chat_contacts() returns contact IDs, the result must be
+ * carray_free()'d.
+ *
+ * - for normal chats, the function always returns exactly one contact
+ *   MR_CONTACT_ID_SELF is _not_ returned.
+ *
+ * - for group chats all members are returned, MR_CONTACT_ID_SELF is returned
+ *   explicitly as it may happen that oneself gets removed from a still existing
+ *   group
+ *
+ * - for the deaddrop, all contacts are returned, MR_CONTACT_ID_SELF is not
+ *   added
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ */
 carray* mrmailbox_get_chat_contacts(mrmailbox_t* mailbox, uint32_t chat_id)
 {
 	/* Normal chats do not include SELF.  Group chats do (as it may happen that one is deleted from a
@@ -607,6 +703,11 @@ mrchat_t* mrchat_new(mrmailbox_t* mailbox)
 }
 
 
+/**
+ * Frees a mrchat_t object created eg. by mrmailbox_get_chat().
+ *
+ * @memberof mrchat_t
+ */
 void mrchat_unref(mrchat_t* ths)
 {
 	if( ths==NULL ) {
@@ -643,6 +744,14 @@ void mrchat_empty(mrchat_t* ths)
 }
 
 
+/**
+ * Returns message IDs of fresh messages, Typically used for implementing
+ * notification summaries.  The result must be free()'d.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ */
 carray* mrmailbox_get_fresh_msgs(mrmailbox_t* mailbox)
 {
 	int           show_deaddrop, success = 0, locked = 0;
@@ -692,6 +801,22 @@ cleanup:
 }
 
 
+/**
+ * mrmailbox_get_chat_msgs() returns a view on a chat.
+ * The function returns an array of message IDs, which must be carray_free()'d by
+ * the caller.  Optionally, some special markers added to the ID-array may help to
+ * implement virtual lists:
+ *
+ * - If you add the flag MR_GCM_ADD_DAY_MARKER, the marker MR_MSG_ID_DAYMARKER will
+ *   be added before each day (regarding the local timezone)
+ *
+ * - If you specify marker1before, the id MR_MSG_ID_MARKER1 will be added just
+ *   before the given ID.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ */
 carray* mrmailbox_get_chat_msgs(mrmailbox_t* mailbox, uint32_t chat_id, uint32_t flags, uint32_t marker1before)
 {
 	int           success = 0, locked = 0;
@@ -775,6 +900,24 @@ cleanup:
 }
 
 
+/**
+ * Search messages containing the given query string.
+ * Searching can be done globally (chat_id=0) or in a specified chat only (chat_id
+ * set).
+ *
+ * - The function returns an array of messages IDs which must be carray_free()'d
+ *   by the caller.
+ *
+ * - If nothing can be found, the function returns NULL.
+ *
+ * Global chat results are typically displayed using mrmsg_get_summary(), chat
+ * search results may just hilite the corresponding messages and present a
+ * prev/next button.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ */
 carray* mrmailbox_search_msgs(mrmailbox_t* mailbox, uint32_t chat_id, const char* query__)
 {
 	int           success = 0, locked = 0;
@@ -910,6 +1053,15 @@ cleanup:
 }
 
 
+/**
+ * save message in database and send it, the given message object is not unref'd
+ * by the function but some fields are set up! Sends the event
+ * MR_EVENT_MSGS_CHANGED on succcess.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ */
 void mrmailbox_set_draft(mrmailbox_t* mailbox, uint32_t chat_id, const char* msg)
 {
 	set_draft_int(mailbox, NULL, chat_id, msg);
@@ -923,6 +1075,12 @@ int mrchat_set_draft(mrchat_t* chat, const char* msg) /* deprecated */
 }
 
 
+/**
+ * either the email-address or the number of group members, the result must be
+ * free()'d!
+ *
+ * @memberof mrchat_t
+ */
 char* mrchat_get_subtitle(mrchat_t* ths)
 {
 	/* returns either the address or the number of chat members */
@@ -983,6 +1141,13 @@ char* mrchat_get_subtitle(mrchat_t* ths)
 }
 
 
+/**
+ * Returns the total number of messages in a chat.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ */
 int mrmailbox_get_total_msg_count(mrmailbox_t* mailbox, uint32_t chat_id)
 {
 	int ret;
@@ -999,6 +1164,14 @@ int mrmailbox_get_total_msg_count(mrmailbox_t* mailbox, uint32_t chat_id)
 }
 
 
+/**
+ * Returns the number of fresh messages in a chat.  Typically used to implement
+ * a badge with a number in the chatlist.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ */
 int mrmailbox_get_fresh_msg_count(mrmailbox_t* mailbox, uint32_t chat_id)
 {
 	int ret;
@@ -1015,10 +1188,28 @@ int mrmailbox_get_fresh_msg_count(mrmailbox_t* mailbox, uint32_t chat_id)
 }
 
 
-int mrmailbox_archive_chat(mrmailbox_t* mailbox, uint32_t chat_id, int archive)
+/**
+ * Archiv or unarchive a chat by setting the last paramter to 0 (unarchive) or
+ * 1 (archive).  Archived chats are not returned in the default chatlist returned
+ * by mrmailbox_get_chatlist(0, NULL).  Instead, if there are _any_ archived chats,
+ * the pseudo-chat with the chat_id MR_CHAT_ID_ARCHIVED_LINK will be added the the
+ * end of the chatlist.
+ * To get a list of archived chats, use mrmailbox_get_chatlist(MR_GCL_ARCHIVED_ONLY, NULL).
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ *
+ * @param chat_id The ID of the chat to archive or unarchive.
+ *
+ * @param archive 1=archive chat, 0=unarchive chat
+ *
+ * @return None
+ */
+void mrmailbox_archive_chat(mrmailbox_t* mailbox, uint32_t chat_id, int archive)
 {
 	if( mailbox == NULL || chat_id <= MR_CHAT_ID_LAST_SPECIAL || (archive!=0 && archive!=1) ) {
-		return 0;
+		return;
 	}
 
 	mrsqlite3_lock(mailbox->m_sql);
@@ -1028,8 +1219,6 @@ int mrmailbox_archive_chat(mrmailbox_t* mailbox, uint32_t chat_id, int archive)
 		sqlite3_step(stmt);
 		sqlite3_finalize(stmt);
 	mrsqlite3_unlock(mailbox->m_sql);
-
-	return 1;
 }
 
 
@@ -1108,9 +1297,38 @@ cleanup:
 }
 
 
-int mrmailbox_delete_chat(mrmailbox_t* mailbox, uint32_t chat_id)
+/**
+ * Delete a chat:
+ *
+ * - messages are deleted from the device and the chat database entry is deleted
+ *
+ * - messages are _not_ deleted from the server
+ *
+ * - the chat is not blocked, so new messages from the user/the group may appear
+ *   and the user may create the chat again
+ *
+ * - this is also one of the reasons, why groups are _not left_ -  this would
+ *   be unexpected as deleting a normal chat also does not prevent new mails
+ *
+ * - moreover, there may be valid reasons only to leave a group and only to
+ *   delete a group
+ *
+ * - another argument is, that leaving a group requires sending a message to
+ *   all group members - esp. for groups not used for a longer time, this is
+ *   really unexpected
+ *
+ * - to leave a chat, use mrmailbox_remove_contact_from_chat(mailbox, chat_id, MR_CONTACT_ID_SELF)
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ *
+ * @param chat_id The ID of the chat to delete.
+ *
+ * @return None
+ */
+void mrmailbox_delete_chat(mrmailbox_t* mailbox, uint32_t chat_id)
 {
-	int          success = 0;
 	mrchat_t*    chat = mrmailbox_get_chat(mailbox, chat_id);
 	mrcontact_t* contact = NULL;
 	mrmsg_t*     msg = mrmsg_new();
@@ -1154,13 +1372,11 @@ int mrmailbox_delete_chat(mrmailbox_t* mailbox, uint32_t chat_id)
 	}
 
 	mailbox->m_cb(mailbox, MR_EVENT_MSGS_CHANGED, 0, 0);
-	success = 1;
 
 cleanup:
 	mrchat_unref(chat);
 	mrcontact_unref(contact);
 	mrmsg_unref(msg);
-	return success;
 }
 
 
@@ -1420,6 +1636,14 @@ cleanup:
 }
 
 
+/**
+ * send a simple text message to the given chat.
+ * Sends the event MR_EVENT_MSGS_CHANGED on succcess
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ */
 uint32_t mrmailbox_send_text_msg(mrmailbox_t* mailbox, uint32_t chat_id, const char* text_to_send)
 {
 	mrmsg_t* msg = mrmsg_new();
@@ -1440,6 +1664,15 @@ cleanup:
 }
 
 
+/**
+ * save message in database and send it, the given message object is not unref'd
+ * by the function but some fields are set up! Sends the event
+ * MR_EVENT_MSGS_CHANGED on succcess.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as returned from mrmailbox_new().
+ */
 uint32_t mrmailbox_send_msg(mrmailbox_t* mailbox, uint32_t chat_id, mrmsg_t* msg)
 {
 	char* pathNfilename = NULL;

+ 73 - 8
deltachat-ios/libraries/deltachat-core/src/mrchatlist.c

@@ -129,15 +129,25 @@ mrchatlist_t* mrchatlist_new(mrmailbox_t* mailbox)
 }
 
 
-void mrchatlist_unref(mrchatlist_t* ths)
+/**
+ * Free a mrchatlist_t object as created eg. by mrmailbox_get_chatlist().
+ *
+ * @memberof mrchatlist_t
+ *
+ * @param chatlist The chatlist object to free.
+ *
+ * @return None.
+ *
+ */
+void mrchatlist_unref(mrchatlist_t* chatlist)
 {
-	if( ths==NULL ) {
+	if( chatlist==NULL ) {
 		return;
 	}
 
-	mrchatlist_empty(ths);
-	carray_free(ths->m_chatNlastmsg_ids);
-	free(ths);
+	mrchatlist_empty(chatlist);
+	carray_free(chatlist->m_chatNlastmsg_ids);
+	free(chatlist);
 }
 
 
@@ -150,16 +160,35 @@ void mrchatlist_empty(mrchatlist_t* ths)
 }
 
 
-size_t mrchatlist_get_cnt(mrchatlist_t* ths)
+/**
+ * Find out the number of chats in a chatlist.
+ *
+ * @memberof mrchatlist_t
+ *
+ * @param chatlist The chatlist object as created eg. by mrmailbox_get_chatlist().
+ *
+ * @return Returns the number of items in a mrchatlist_t object. 0 on errors or if the list is empty.
+ */
+size_t mrchatlist_get_cnt(mrchatlist_t* chatlist)
 {
-	if( ths == NULL ) {
+	if( chatlist == NULL ) {
 		return 0;
 	}
 
-	return ths->m_cnt;
+	return chatlist->m_cnt;
 }
 
 
+/**
+ * Get a single chat ID of a chatlist.
+ *
+ * @memberof mrchatlist_t
+ *
+ * @param chatlist The chatlist object as created eg. by mrmailbox_get_chatlist().
+ *
+ * @return Returns the chat_id of the item at the given index.  Index must be between
+ *     0 and mrchatlist_get_cnt()-1.
+ */
 uint32_t mrchatlist_get_chat_id(mrchatlist_t* ths, size_t index)
 {
 	if( ths == NULL || ths->m_chatNlastmsg_ids == NULL || index >= ths->m_cnt ) {
@@ -180,6 +209,16 @@ mrchat_t* mrchatlist_get_chat_by_index(mrchatlist_t* ths, size_t index) /* depre
 }
 
 
+/**
+ * Get a single message ID of a chatlist.
+ *
+ * @memberof mrchatlist_t
+ *
+ * @param chatlist The chatlist object as created eg. by mrmailbox_get_chatlist().
+ *
+ * @return Returns the message_id of the item at the given index.  Index must be between
+ *     0 and mrchatlist_get_cnt()-1.  If there is no message at the given index (eg. the chat may be empty), 0 is returned.
+ */
 uint32_t mrchatlist_get_msg_id(mrchatlist_t* ths, size_t index)
 {
 	if( ths == NULL || ths->m_chatNlastmsg_ids == NULL || index >= ths->m_cnt ) {
@@ -200,6 +239,32 @@ mrmsg_t* mrchatlist_get_msg_by_index(mrchatlist_t* ths, size_t index) /* depreca
 }
 
 
+/**
+ * Get a summary for a chatlist index.
+ *
+ * The summary is returned by a mrpoortext_t object with the following fields:
+ *
+ * - m_text1: contains the username or the strings "Me", "Draft" and so on.
+ *   The string may be colored by having a look at m_text1_meaning.
+ *   If there is no such name, the element is NULL (eg. for "No messages")
+ *
+ * - m_text1_meaning: one of the MR_TEXT1_* constants
+ *
+ * - m_text2: contains an excerpt of the message text or strings as
+ *   "No messages".  may be NULL of there is no such text (eg. for the archive)
+ *
+ * - m_timestamp: the timestamp of the message.  May be 0 if there is no message
+ *
+ * - m_state: the state of the message as one of the MR_STATE_* identifiers.  0 if there is no message.
+ *
+ * @memberof mrchatlist_t
+ *
+ * @param chat  Giving the correct chat object here, this this will speed up
+ *     things a little.  If the chat object is not available by you, it is faster to pass
+ *     NULL here.
+ *
+ * @return The result must be freed using mrpoortext_unref().  The function never returns NULL.
+ */
 mrpoortext_t* mrchatlist_get_summary(mrchatlist_t* chatlist, size_t index, mrchat_t* chat /*may be NULL*/)
 {
 	/* The summary is created by the chat, not by the last message.

+ 15 - 3
deltachat-ios/libraries/deltachat-core/src/mrcontact.c

@@ -552,15 +552,27 @@ static void marknoticed_contact__(mrmailbox_t* mailbox, uint32_t contact_id)
 }
 
 
-int mrmailbox_marknoticed_contact(mrmailbox_t* mailbox, uint32_t contact_id)
+/**
+ * Mark all messages send by the given contact
+ * as _noticed_.  See also mrmailbox_marknoticed_chat() and
+ * mrmailbox_markseen_msgs()
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as created by mrmmailbox_new()
+ *
+ * @param contact_id The contact ID of which all messages should be marked as noticed.
+ *
+ * @return none
+ */
+void mrmailbox_marknoticed_contact(mrmailbox_t* mailbox, uint32_t contact_id)
 {
     if( mailbox == NULL ) {
-		return 0;
+		return;
     }
     mrsqlite3_lock(mailbox->m_sql);
 		marknoticed_contact__(mailbox, contact_id);
     mrsqlite3_unlock(mailbox->m_sql);
-    return 1;
 }
 
 

+ 202 - 50
deltachat-ios/libraries/deltachat-core/src/mrmailbox.c

@@ -867,6 +867,32 @@ static void cb_receive_imf(mrimap_t* imap, const char* imf_raw_not_terminated, s
 }
 
 
+/**
+ * mrmailbox_new() creates a new mailbox object.  After creation it is usually
+ * opened, connected and mails are fetched.
+ * After usage, the object should be deleted using mrmailbox_unref().
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param cb a callback function that is called for events (update,
+ *     state changes etc.) and to get some information form the client (eg. translation
+ *     for a given string)
+ *     - The callback MAY be called from _any_ thread, not only the main/GUI thread!
+ *     - The callback MUST NOT call any mrmailbox_* and related functions unless stated
+ *       otherwise!
+ *     - The callback SHOULD return _fast_, for GUI updates etc. you should
+ *       post yourself an asynchronous message to your GUI thread, if needed.
+ *     - If not mentioned otherweise, the callback should return 0.
+ *
+ * @param userdata can be used by the client for any purpuse.  He finds it
+ *     later in mrmailbox_get_userdata().
+ *
+ * @param os_name is only for decorative use and is shown eg. in the X-Mailer header
+ *     in the form "Delta Chat <version> for <osName>"
+ *
+ * @return a mailbox object with some public members the object must be passed to the other mailbox functions
+ *     and the object must be freed using mrmailbox_unref() after usage.
+ */
 mrmailbox_t* mrmailbox_new(mrmailboxcb_t cb, void* userdata, const char* os_name)
 {
 	mrmailbox_get_thread_index(); /* make sure, the main thread has the index #1, only for a nicer look of the logs */
@@ -914,6 +940,16 @@ mrmailbox_t* mrmailbox_new(mrmailboxcb_t cb, void* userdata, const char* os_name
 }
 
 
+/**
+ * After usage, the mailbox object should be freed using mrmailbox_unref().
+ * If app runs can only be terminated by a forced kill, this may be superfluous.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox the mailbox object as created by mrmailbox_new()
+ *
+ * @return none
+ */
 void mrmailbox_unref(mrmailbox_t* ths)
 {
 	if( ths==NULL ) {
@@ -955,6 +991,21 @@ static void update_config_cache__(mrmailbox_t* ths, const char* key)
 }
 
 
+/**
+ * Open mailbox database.  If the given file does not exist, it is
+ * created and can be set up using mrmailbox_set_config() afterwards.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox: the mailbox object as created by mrmailbox_new
+ *
+ * @param dbfile the file to use to store the database, sth. like "~/file" won't work on all systems, if in doubt, use absolute paths
+ *
+ * @param blobdir a directory to store the blobs in, the trailing slash is added by us, so if you want to
+ * avoid double slashes, do not add one. If you give NULL as blobdir, `dbfile-blobs` is used in the same directory as _dbfile_ will be created in.
+ *
+ * @return 1 on success, 0 on failure
+ */
 int mrmailbox_open(mrmailbox_t* ths, const char* dbfile, const char* blobdir)
 {
 	int success = 0;
@@ -1011,6 +1062,15 @@ cleanup:
 }
 
 
+/**
+ * Close mailbox database.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox the mailbox object as created by mrmailbox_new()
+ *
+ * @return none
+ */
 void mrmailbox_close(mrmailbox_t* ths)
 {
 	if( ths == NULL ) {
@@ -1036,6 +1096,15 @@ void mrmailbox_close(mrmailbox_t* ths)
 }
 
 
+/**
+ * Check if a given mailbox database is open.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox the mailbox object as created by mrmailbox_new
+ *
+ * @return 0=mailbox is not open, 1=mailbox is open
+ */
 int mrmailbox_is_open(const mrmailbox_t* ths)
 {
 	if( ths == NULL ) {
@@ -1076,6 +1145,33 @@ cleanup:
  ******************************************************************************/
 
 
+/**
+ * Configure the mailbox.  The configuration is handled by key=value pairs. Typical configuration options are:
+ *
+ * - addr         = address to display (needed)
+ * - mail_server  = IMAP-server, guessed if left out
+ * - mail_user    = IMAP-username, guessed if left out
+ * - mail_pw      = IMAP-password (needed)
+ * - mail_port    = IMAP-port, guessed if left out
+ * - send_server  = SMTP-server, guessed if left out
+ * - send_user    = SMTP-user, guessed if left out
+ * - send_pw      = SMTP-password, guessed if left out
+ * - send_port    = SMTP-port, guessed if left out
+ * - server_flags = IMAP-/SMTP-flags, guessed if left out
+ * - displayname  = Own name to use when sending messages.  MUAs are allowed to spread this way eg. using CC, defaults to empty
+ * - selfstatus   = Own status to display eg. in email footers, defaults to a standard text
+ * - e2ee_enabled = 0=no e2ee, 1=prefer encryption (default)
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param ths the mailbox object
+ *
+ * @param key the option to change, typically one of the strings listed above
+ *
+ * @param value the value to save for "key"
+ *
+ * @return 0=failure, 1=success
+ */
 int mrmailbox_set_config(mrmailbox_t* ths, const char* key, const char* value)
 {
 	int ret;
@@ -1093,6 +1189,20 @@ int mrmailbox_set_config(mrmailbox_t* ths, const char* key, const char* value)
 }
 
 
+/**
+ * Get a configuration option set by mrmailbox_set_config()
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param ths the mailbox object as created by mrmmailbox_new()
+ *
+ * @param key the key to query
+ *
+ * @param def default value to return if "key" is unset
+ *
+ * @return Returns current value of "key", if "key" is unset, "def" is returned (which may be NULL)
+ *     If the returned values is not NULL, the return value must be free()'d,
+ */
 char* mrmailbox_get_config(mrmailbox_t* ths, const char* key, const char* def)
 {
 	char* ret;
@@ -1109,6 +1219,12 @@ char* mrmailbox_get_config(mrmailbox_t* ths, const char* key, const char* def)
 }
 
 
+/**
+ * Similar to mrmailbox_set_config() but sets an integer instead of a string.
+ * If there is already a key with a string set, this is overwritten by the given integer value.
+ *
+ * @memberof mrmailbox_t
+ */
 int mrmailbox_set_config_int(mrmailbox_t* ths, const char* key, int32_t value)
 {
 	int ret;
@@ -1126,6 +1242,11 @@ int mrmailbox_set_config_int(mrmailbox_t* ths, const char* key, int32_t value)
 }
 
 
+/**
+ * Similar as mrmailbox_get_config() but gets the value as an integer instead of a string.
+ *
+ * @memberof mrmailbox_t
+ */
 int32_t mrmailbox_get_config_int(mrmailbox_t* ths, const char* key, int32_t def)
 {
 	int32_t ret;
@@ -1142,19 +1263,33 @@ int32_t mrmailbox_get_config_int(mrmailbox_t* ths, const char* key, int32_t def)
 }
 
 
+/**
+ * Get the blob directory.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox Mailbox object as returned by mrmailbox_new().
+ *
+ * @return String which must be free()'d after usage.
+ */
 char* mrmailbox_get_blobdir(mrmailbox_t* mailbox)
 {
 	return safe_strdup(mailbox? mailbox->m_blobdir : NULL);
 }
 
 
-void* mrmailbox_get_userdata(mrmailbox_t* mailbox)
-{
-	return mailbox? mailbox->m_userdata : NULL;
-}
-
-
-char* mrmailbox_get_info(mrmailbox_t* ths)
+/**
+ * mrmailbox_get_info() returns a multi-line output about the current
+ * configuration and the last log entries. the returned string must be free()'d,
+ * returns NULL on errors.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox Mailbox object as returned by mrmailbox_new().
+ *
+ * @return String which must be free()'d after usage.
+ */
+char* mrmailbox_get_info(mrmailbox_t* mailbox)
 {
 	const char* unset = "0";
 	char *displayname = NULL, *temp = NULL, *l_readable_str = NULL, *l2_readable_str = NULL, *fingerprint_str = NULL;
@@ -1165,7 +1300,7 @@ char* mrmailbox_get_info(mrmailbox_t* ths)
 	mrstrbuilder_t  ret;
 	mrstrbuilder_init(&ret);
 
-	if( ths == NULL ) {
+	if( mailbox == NULL ) {
 		return safe_strdup("ErrBadPtr");
 	}
 
@@ -1173,44 +1308,44 @@ char* mrmailbox_get_info(mrmailbox_t* ths)
 	l = mrloginparam_new();
 	l2 = mrloginparam_new();
 
-	mrsqlite3_lock(ths->m_sql);
+	mrsqlite3_lock(mailbox->m_sql);
 
-		mrloginparam_read__(l, ths->m_sql, "");
-		mrloginparam_read__(l2, ths->m_sql, "configured_" /*the trailing underscore is correct*/);
+		mrloginparam_read__(l, mailbox->m_sql, "");
+		mrloginparam_read__(l2, mailbox->m_sql, "configured_" /*the trailing underscore is correct*/);
 
-		displayname     = mrsqlite3_get_config__(ths->m_sql, "displayname", NULL);
+		displayname     = mrsqlite3_get_config__(mailbox->m_sql, "displayname", NULL);
 
-		chats           = mrmailbox_get_chat_cnt__(ths);
-		real_msgs       = mrmailbox_get_real_msg_cnt__(ths);
-		deaddrop_msgs   = mrmailbox_get_deaddrop_msg_cnt__(ths);
-		contacts        = mrmailbox_get_real_contact_cnt__(ths);
+		chats           = mrmailbox_get_chat_cnt__(mailbox);
+		real_msgs       = mrmailbox_get_real_msg_cnt__(mailbox);
+		deaddrop_msgs   = mrmailbox_get_deaddrop_msg_cnt__(mailbox);
+		contacts        = mrmailbox_get_real_contact_cnt__(mailbox);
 
-		is_configured   = mrsqlite3_get_config_int__(ths->m_sql, "configured", 0);
+		is_configured   = mrsqlite3_get_config_int__(mailbox->m_sql, "configured", 0);
 
-		dbversion       = mrsqlite3_get_config_int__(ths->m_sql, "dbversion", 0);
+		dbversion       = mrsqlite3_get_config_int__(mailbox->m_sql, "dbversion", 0);
 
-		e2ee_enabled    = ths->m_e2ee_enabled;
+		e2ee_enabled    = mailbox->m_e2ee_enabled;
 
-		mdns_enabled    = mrsqlite3_get_config_int__(ths->m_sql, "mdns_enabled", MR_MDNS_DEFAULT_ENABLED);
+		mdns_enabled    = mrsqlite3_get_config_int__(mailbox->m_sql, "mdns_enabled", MR_MDNS_DEFAULT_ENABLED);
 
-		sqlite3_stmt* stmt = mrsqlite3_prepare_v2_(ths->m_sql, "SELECT COUNT(*) FROM keypairs;");
+		sqlite3_stmt* stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, "SELECT COUNT(*) FROM keypairs;");
 		sqlite3_step(stmt);
 		prv_key_count = sqlite3_column_int(stmt, 0);
 		sqlite3_finalize(stmt);
 
-		stmt = mrsqlite3_prepare_v2_(ths->m_sql, "SELECT COUNT(*) FROM acpeerstates;");
+		stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, "SELECT COUNT(*) FROM acpeerstates;");
 		sqlite3_step(stmt);
 		pub_key_count = sqlite3_column_int(stmt, 0);
 		sqlite3_finalize(stmt);
 
-		if( mrkey_load_self_public__(self_public, l2->m_addr, ths->m_sql) ) {
-			fingerprint_str = mrkey_render_fingerprint(self_public, ths);
+		if( mrkey_load_self_public__(self_public, l2->m_addr, mailbox->m_sql) ) {
+			fingerprint_str = mrkey_render_fingerprint(self_public, mailbox);
 		}
 		else {
 			fingerprint_str = safe_strdup("<Not yet calculated>");
 		}
 
-	mrsqlite3_unlock(ths->m_sql);
+	mrsqlite3_unlock(mailbox->m_sql);
 
 	l_readable_str = mrloginparam_get_readable(l);
 	l2_readable_str = mrloginparam_get_readable(l2);
@@ -1241,7 +1376,7 @@ char* mrmailbox_get_info(mrmailbox_t* ths)
 		/* In the frontends, additional software hints may follow here. */
 
 		, chats, real_msgs, deaddrop_msgs, contacts
-		, ths->m_dbfile? ths->m_dbfile : unset,   dbversion,   ths->m_blobdir? ths->m_blobdir : unset
+		, mailbox->m_dbfile? mailbox->m_dbfile : unset,   dbversion,   mailbox->m_blobdir? mailbox->m_blobdir : unset
 
         , displayname? displayname : unset
 		, is_configured
@@ -1263,19 +1398,19 @@ char* mrmailbox_get_info(mrmailbox_t* ths)
 	free(temp);
 
 	/* add log excerpt */
-	pthread_mutex_lock(&ths->m_log_ringbuf_critical); /*take care not to log here! */
+	pthread_mutex_lock(&mailbox->m_log_ringbuf_critical); /*take care not to log here! */
 		for( int i = 0; i < MR_LOG_RINGBUF_SIZE; i++ ) {
-			int j = (ths->m_log_ringbuf_pos+i) % MR_LOG_RINGBUF_SIZE;
-			if( ths->m_log_ringbuf[j] ) {
+			int j = (mailbox->m_log_ringbuf_pos+i) % MR_LOG_RINGBUF_SIZE;
+			if( mailbox->m_log_ringbuf[j] ) {
 				struct tm wanted_struct;
-				memcpy(&wanted_struct, localtime(&ths->m_log_ringbuf_times[j]), sizeof(struct tm));
+				memcpy(&wanted_struct, localtime(&mailbox->m_log_ringbuf_times[j]), sizeof(struct tm));
 				temp = mr_mprintf("\n%02i:%02i:%02i ", (int)wanted_struct.tm_hour, (int)wanted_struct.tm_min, (int)wanted_struct.tm_sec);
 					mrstrbuilder_cat(&ret, temp);
-					mrstrbuilder_cat(&ret, ths->m_log_ringbuf[j]);
+					mrstrbuilder_cat(&ret, mailbox->m_log_ringbuf[j]);
 				free(temp);
 			}
 		}
-	pthread_mutex_unlock(&ths->m_log_ringbuf_critical);
+	pthread_mutex_unlock(&mailbox->m_log_ringbuf_critical);
 
 	/* free data */
 	mrloginparam_unref(l);
@@ -1345,6 +1480,13 @@ int mrmailbox_reset_tables(mrmailbox_t* ths, int bits)
 }
 
 
+/**
+ * Use mrmailbox_get_version_str() to find out the version of the Delta Chat core library.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @return String with version number as `major.minor.revision`. The return value must be free()'d.
+ */
 char* mrmailbox_get_version_str(void)
 {
 	return mr_mprintf("%i.%i.%i", (int)MR_VERSION_MAJOR, (int)MR_VERSION_MINOR, (int)MR_VERSION_REVISION);
@@ -1423,24 +1565,43 @@ cleanup:
 }
 
 
-void mrmailbox_connect(mrmailbox_t* ths)
+/**
+ * Connect to the mailbox using the configured settings.  We connect using IMAP-IDLE or, if this is not possible,
+ * a using pull algorithm.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as created by mrmailbox_new()
+ *
+ * @return None
+ */
+void mrmailbox_connect(mrmailbox_t* mailbox)
 {
-	if( ths == NULL ) {
+	if( mailbox == NULL ) {
 		return;
 	}
 
-	mrsqlite3_lock(ths->m_sql);
+	mrsqlite3_lock(mailbox->m_sql);
 
-		ths->m_smtp->m_log_connect_errors = 1;
-		ths->m_imap->m_log_connect_errors = 1;
+		mailbox->m_smtp->m_log_connect_errors = 1;
+		mailbox->m_imap->m_log_connect_errors = 1;
 
-		mrjob_kill_action__(ths, MRJ_CONNECT_TO_IMAP);
-		mrjob_add__(ths, MRJ_CONNECT_TO_IMAP, 0, NULL);
+		mrjob_kill_action__(mailbox, MRJ_CONNECT_TO_IMAP);
+		mrjob_add__(mailbox, MRJ_CONNECT_TO_IMAP, 0, NULL);
 
-	mrsqlite3_unlock(ths->m_sql);
+	mrsqlite3_unlock(mailbox->m_sql);
 }
 
 
+/**
+ * Disonnect the mailbox from the server.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as created by mrmailbox_new()
+ *
+ * @return None
+ */
 void mrmailbox_disconnect(mrmailbox_t* ths)
 {
 	if( ths == NULL ) {
@@ -1456,16 +1617,7 @@ void mrmailbox_disconnect(mrmailbox_t* ths)
 }
 
 
-int mrmailbox_fetch(mrmailbox_t* ths)
-{
-	if( ths == NULL ) {
-		return 0;
-	}
-
-	return mrimap_fetch(ths->m_imap);
-}
-
-
+/* restore old data from the IMAP server, not really implemented. */
 int mrmailbox_restore(mrmailbox_t* ths, time_t seconds_to_restore)
 {
 	if( ths == NULL ) {

+ 140 - 385
deltachat-ios/libraries/deltachat-core/src/mrmailbox.h

@@ -27,6 +27,11 @@ extern "C" {
 #endif
 
 
+#define MR_VERSION_MAJOR    0
+#define MR_VERSION_MINOR    9
+#define MR_VERSION_REVISION 7
+
+
 #include <libetpan/libetpan.h> /* defines uint16_t etc. */
 
 typedef struct mrmailbox_t  mrmailbox_t;
@@ -36,246 +41,158 @@ typedef struct mrmsg_t      mrmsg_t;
 typedef struct mrcontact_t  mrcontact_t;
 typedef struct mrpoortext_t mrpoortext_t;
 typedef struct mrparam_t    mrparam_t;
-
-#define MR_VERSION_MAJOR    0
-#define MR_VERSION_MINOR    9
-#define MR_VERSION_REVISION 7
-
-
-/**
- * Use mrmailbox_get_version_str() to find out the version of the Delta Chat core library.
- *
- * Returns: String with version number as `major.minor.revision`. The return value must be free()'d.
- */
-char* mrmailbox_get_version_str (void);
+typedef struct mrimap_t     mrimap_t;
+typedef struct mrsmtp_t     mrsmtp_t;
+typedef struct mrsqlite3_t  mrsqlite3_t;
 
 
 /**
  * Callback function that should be given to mrmailbox_new().
  *
- * @mailbox: the mailbox object as created by mrmailbox_new
+ * @memberof mrmailbox_t
  *
- * @event: one of the MR_EVENT_* constants
+ * @param mailbox the mailbox object as created by mrmailbox_new
  *
- * @data1: depends on the event parameter
+ * @param event one of the MR_EVENT_* constants
  *
- * @data2: depends on the event parameter
+ * @param data1 depends on the event parameter
  *
- * Returns: return 0 unless stated otherwise in the event parameter documentation
+ * @param data2 depends on the event parameter
+ *
+ * @return return 0 unless stated otherwise in the event parameter documentation
  */
 typedef uintptr_t (*mrmailboxcb_t) (mrmailbox_t*, int event, uintptr_t data1, uintptr_t data2);
 
 
 /**
- * mrmailbox_new() creates a new mailbox object.  After creation it is usually
- * opened, connected and mails are fetched.
- * After usage, the object should be deleted using mrmailbox_unref().
- *
- * @cb a callback function that is called for events (update,
- * state changes etc.) and to get some information form the client (eg. translation
- * for a given string)
- * - The callback MAY be called from _any_ thread, not only the main/GUI thread!
- * - The callback MUST NOT call any mrmailbox_* and related functions unless stated
- *   otherwise!
- * - The callback SHOULD return _fast_, for GUI updates etc. you should
- *   post yourself an asynchronous message to your GUI thread, if needed.
- * - If not mentioned otherweise, the callback should return 0.
- *
- * @userdata can be used by the client for any purpuse.  He finds it
- * later in mrmailbox_get_userdata().
- *
- * @os_name is only for decorative use and is shown eg. in the X-Mailer header
- * in the form "Delta Chat <version> for <osName>"
+ * mrmailbox_t represents a single mailbox, normally, typically only one
+ * instance of this class is present.
+ * Each mailbox is linked to an IMAP/POP3 account and uses a separate
+ * SQLite database for offline functionality and for mailbox-related
+ * settings.
  */
-mrmailbox_t* mrmailbox_new (mrmailboxcb_t, void* userdata, const char* os_name);
+typedef struct mrmailbox_t
+{
+	void*            m_userdata; /**< the same pointer as given to mrmailbox_new(), may be used by the caller for any purpose */
+	char*            m_dbfile;   /**< the database file in file. */
+	char*            m_blobdir;  /**< full path of the blob directory in use. */
 
+	/** @privatesection */
+	mrsqlite3_t*     m_sql;      /* != NULL */
 
-/**
- * After usage, the mailbox object should be freed using mrmailbox_unref().
- * If app runs can only be terminated by a forced kill, this may be superfluous.
- *
- * @mailbox: the mailbox object as created by mrmailbox_new
- */
-void mrmailbox_unref (mrmailbox_t*);
+	mrimap_t*        m_imap;     /* != NULL */
+	mrsmtp_t*        m_smtp;     /* != NULL */
 
+	pthread_t        m_job_thread;
+	pthread_cond_t   m_job_cond;
+	pthread_mutex_t  m_job_condmutex;
+	int              m_job_condflag;
+	int              m_job_do_exit;
 
-/**
- * Open mailbox database.  If the given file does not exist, it is
- * created and can be set up using mrmailbox_set_config() afterwards.
- *
- * @mailbox: the mailbox object as created by mrmailbox_new
- *
- * @dbfile the file to use to store the database, sth. like "~/file" won't work on all systems, if in doubt, use absolute paths
- *
- * @blobdir a directory to store the blobs in, the trailing slash is added by us, so if you want to
- * avoid double slashes, do not add one. If you give NULL as blobdir "dbfile-blobs" is used in the same directory as @dbfile will be created in.
- *
- * Returns: 1 on success, 0 on failure
- */
-int             mrmailbox_open              (mrmailbox_t*, const char* dbfile, const char* blobdir);
+	mrmailboxcb_t    m_cb;
 
+	char*            m_os_name;
 
-/**
- * Close mailbox database.
- *
- * @mailbox: the mailbox object as created by mrmailbox_new
- */
-void            mrmailbox_close             (mrmailbox_t*);
+	uint32_t         m_cmdline_sel_chat_id;
 
+	int              m_wake_lock;
+	pthread_mutex_t  m_wake_lock_critical;
 
-/**
- * Check if a given mailbox database is open.
- *
- * @mailbox: the mailbox object as created by mrmailbox_new
- */
+	int              m_e2ee_enabled;
+
+	#define          MR_LOG_RINGBUF_SIZE 200
+	pthread_mutex_t  m_log_ringbuf_critical;
+	char*            m_log_ringbuf[MR_LOG_RINGBUF_SIZE];
+	time_t           m_log_ringbuf_times[MR_LOG_RINGBUF_SIZE];
+	int              m_log_ringbuf_pos; /* the oldest position resp. the position that is overwritten next */
+
+} mrmailbox_t;
+
+
+mrmailbox_t*    mrmailbox_new               (mrmailboxcb_t, void* userdata, const char* os_name);
+void            mrmailbox_unref             (mrmailbox_t*);
+
+
+int             mrmailbox_open              (mrmailbox_t*, const char* dbfile, const char* blobdir);
+void            mrmailbox_close             (mrmailbox_t*);
 int             mrmailbox_is_open           (const mrmailbox_t*);
 
 
-/* The mailbox configuration is handled by key=value pairs which are accessed
-using the following functins.  Typical configuration options are:
-addr         = [needed] address to display
-mail_server  =          IMAP-server, guessed if left out
-mail_user    =          IMAP-username, guessed if left out
-mail_pw      = [needed] IMAP-password
-mail_port    =          IMAP-port, guessed if left out
-send_server  =          SMTP-server, guessed if left out
-send_user    =          SMTP-user, guessed if left out
-send_pw      =          SMTP-password, guessed if left out
-send_port    =          SMTP-port, guessed if left out
-server_flags =          IMAP-/SMTP-flags, guessed if left out
-displayname  =          Own name to use when sending messages.  MUAs are allowed
-                        to spread this way eg. using CC, defaults to empty
-selfstatus   =          Own status to display eg. in email footers, defaults to
-                        standard text
-e2ee_enabled =          0=no e2ee, 1=prefer encryption (default) */
 int             mrmailbox_set_config        (mrmailbox_t*, const char* key, const char* value);
 char*           mrmailbox_get_config        (mrmailbox_t*, const char* key, const char* def);
 int             mrmailbox_set_config_int    (mrmailbox_t*, const char* key, int32_t value);
 int32_t         mrmailbox_get_config_int    (mrmailbox_t*, const char* key, int32_t def);
+char*           mrmailbox_get_blobdir       (mrmailbox_t*);
+char*           mrmailbox_get_version_str   (void);
 
 
-/* mrmailbox_configure_and_connect() configures and connects a mailbox.
-- Before your call this function, you should set at least `addr` and `mail_pw`
-  using mrmailbox_set_config().
-- mrmailbox_configure_and_connect() returns immediately, configuration is done
-  in another thread; when done, the event MR_EVENT_CONFIGURE_ENDED ist posted
-- There is no need to call this every program start, the result is saved in the
-  database.
-- mrmailbox_configure_and_connect() should be called after any settings
-  change. */
 void            mrmailbox_configure_and_connect(mrmailbox_t*);
 void            mrmailbox_configure_cancel  (mrmailbox_t*);
 int             mrmailbox_is_configured     (mrmailbox_t*);
 
 
-/* Connect to the mailbox using the configured settings. normally, there is no
-need to call mrmailbox_fetch() manually as we get push events from the IMAP
-server; if this fails, we fallback to a smart pull-mode. */
 void            mrmailbox_connect           (mrmailbox_t*);
 void            mrmailbox_disconnect        (mrmailbox_t*);
-int             mrmailbox_fetch             (mrmailbox_t*);
-
 
-/* restore old data from the IMAP server, not really implemented. */
-int             mrmailbox_restore           (mrmailbox_t*, time_t seconds_to_restore);
 
-
-/* mrmailbox_get_info() returns a multi-line output about the current
-configuration and the last log entries. the returned string must be free()'d,
-returns NULL on errors */
+int             mrmailbox_restore           (mrmailbox_t*, time_t seconds_to_restore); /* not really implemented */
 char*           mrmailbox_get_info          (mrmailbox_t*);
 
 
-/* returns the same pointer as given to mrmailbox_new().  If you have passed
-NULL there, this function also returns NULL.  The result is normally not freed
-or unref'd in any way. */
-void*           mrmailbox_get_userdata      (mrmailbox_t*);
-
-
-/* returns the current blob directory in use.  This is the directory given to
-mrmailbox_new() or a subdirectory in the path where the database file is placed.
-The returned values must be free()'d */
-char*           mrmailbox_get_blobdir       (mrmailbox_t*);
-
-
 /*******************************************************************************
  * Handle chatlists
  ******************************************************************************/
 
 
-/* Get a list of chats.  The result must be unref'd.
-The second parameter is a combination of flags:
-- if the flag MR_GCL_ARCHIVED_ONLY is set, only archived chats are returned.
-  if MR_GCL_ARCHIVED_ONLY is not set, only unarchived chats are returned and
-  the pseudo-chat MR_CHAT_ID_ARCHIVED_LINK is added if there are _any_ archived
-  chats
-- if the flag MR_GCL_NO_SPECIALS is set, deaddrop and archive link are not added
-  to the list (may be used eg. for selecting chats on forwarding, the flag is
-  not needed when MR_GCL_ARCHIVED_ONLY is already set)
-The last parameter is a query to search for */
+/**
+ * Chatlist objects contain a chat IDs and, if possible, message IDs belonging to them.
+ * Chatlist objects are created eg. using mrmailbox_get_chatlist().
+ * The chatlist object is not updated.  If you want an update, you have to recreate
+ * the object.
+ */
+typedef struct mrchatlist_t
+{
+	mrmailbox_t*    m_mailbox; /**< The mailbox, the chatlist belongs to */
+
+	/** @privatesection */
+	size_t          m_cnt;
+	carray*         m_chatNlastmsg_ids;
+} mrchatlist_t;
+
+
 #define         MR_GCL_ARCHIVED_ONLY        0x01
 #define         MR_GCL_NO_SPECIALS          0x02
 mrchatlist_t*   mrmailbox_get_chatlist      (mrmailbox_t*, int flags, const char* query);
 
 
-/* Free a mrchatlist_t object as created eg. by mrmailbox_get_chatlist(). */
 void            mrchatlist_unref            (mrchatlist_t*);
-
-
-/* Returns the number of items in a mrchatlist_t object. */
 size_t          mrchatlist_get_cnt          (mrchatlist_t*);
-
-
-/* Returns the chat_id of the item at the given index.  Index must be between
-0 and mrchatlist_get_cnt()-1. */
 uint32_t        mrchatlist_get_chat_id      (mrchatlist_t*, size_t index);
-
-
-/* Returns the msg_id of the item at the given index.  Index must be between
-0 and mrchatlist_get_cnt()-1. */
 uint32_t        mrchatlist_get_msg_id       (mrchatlist_t*, size_t index);
-
-
-/* Get a summary for a chatlist index. The last parameter can be set to speed up
-things if the chat object is already available; if not, it is faster to pass
-NULL here.  The result must be freed using mrpoortext_unref().  The returned
-summary has the following format:
-- m_text1:         contains the username or the strings "Me", "Draft" and so on.
-                   the string may be colored by having a look at m_text1_meaning.
-                   If there is no such name, the element is NULL (eg. for
-                   "No messages")
-- m_text1_meaning: one of the
-- m_text2          contains an excerpt of the message text or strings as
-                  "No messages".
-                   may be NULL of there is no such text (eg. for the archive)
-- m_timestamp      the timestamp of the message.  May be 0 if there is no
-                   message
-- m_state          the state of the message as one of the MR_STATE_*
-                   identifiers.  0 if there is no message.
-The function never returns NULL. */
 mrpoortext_t*   mrchatlist_get_summary      (mrchatlist_t*, size_t index, mrchat_t*);
 
 
-/* the poortext object and some function accessing it.  A poortext object
-contains some strings together with their meaning and some attributes.  The
-object is mainly used for summary returns of chats and chatlists */
+/**
+ * the poortext object and some function accessing it.  A poortext object
+ * contains some strings together with their meaning and some attributes.  The
+ * object is mainly used for summary returns of chats and chatlists
+ */
 typedef struct mrpoortext_t
 {
-	#define         MR_TEXT1_NORMAL    0
-	#define         MR_TEXT1_DRAFT     1
-	#define         MR_TEXT1_USERNAME  2
-	#define         MR_TEXT1_SELF      3
-	int             m_text1_meaning;
-
-	char*           m_text1;           /* may be NULL */
-	char*           m_text2;           /* may be NULL */
-	time_t          m_timestamp;       /* may be 0 */
-	int             m_state;           /* may be 0 */
+	int             m_text1_meaning;   /**< One of MR_TEXT1_NORMAL, MR_TEXT1_DRAFT, MR_TEXT1_USERNAME or MR_TEXT1_SELF */
+	char*           m_text1;           /**< may be NULL */
+	char*           m_text2;           /**< may be NULL */
+	time_t          m_timestamp;       /**< may be 0 */
+	int             m_state;           /**< may be 0 */
 } mrpoortext_t;
 
 
-/* Frees a mrpoortext_t object created eg. by mrchatlist_get_summary() or by
-mrmsg_eget_summary().  This also frees the strings objects. */
+#define         MR_TEXT1_NORMAL    0 /**< @memberof mrpoortext_t */
+#define         MR_TEXT1_DRAFT     1 /**< @memberof mrpoortext_t */
+#define         MR_TEXT1_USERNAME  2 /**< @memberof mrpoortext_t */
+#define         MR_TEXT1_SELF      3 /**< @memberof mrpoortext_t */
+
+
 void            mrpoortext_unref            (mrpoortext_t*);
 
 
@@ -284,136 +201,38 @@ void            mrpoortext_unref            (mrpoortext_t*);
  ******************************************************************************/
 
 
-/* Create a normal chat with a single user.  To create group chats,
-see mrmailbox_create_group_chat() */
 uint32_t        mrmailbox_create_chat_by_contact_id (mrmailbox_t*, uint32_t contact_id);
-
-
-/* If there is a normal chat with the given contact_id, this chat_id is
-retunred.  If there is no normal chat with the contact_id, the function
-returns 0 */
 uint32_t        mrmailbox_get_chat_id_by_contact_id (mrmailbox_t*, uint32_t contact_id);
 
 
-/* send a simple text message to the given chat.
-Sends the event MR_EVENT_MSGS_CHANGED on succcess */
 uint32_t        mrmailbox_send_text_msg     (mrmailbox_t*, uint32_t chat_id, const char* text_to_send);
-
-
-/* save message in database and send it, the given message object is not unref'd
-by the function but some fields are set up! Sends the event
-MR_EVENT_MSGS_CHANGED on succcess. */
 uint32_t        mrmailbox_send_msg          (mrmailbox_t*, uint32_t chat_id, mrmsg_t*);
-
-
-/* Save draft for a chat.  May result in "MR_EVENT_MSGS_CHANGED". The draft may
-be read later using mrmailbox_get_chat() and is also shown in
-mrchatlist_get_summary(). */
 void            mrmailbox_set_draft         (mrmailbox_t*, uint32_t chat_id, const char*);
 
 
-/* mrmailbox_get_chat_msgs() returns a view on a chat.
-The function returns an array of message IDs, which must be carray_free()'d by
-the caller.  Optionally, some special markers added to the ID-array may help to
-implement virtual lists:
-- If you add the flag MR_GCM_ADD_DAY_MARKER, the marker MR_MSG_ID_DAYMARKER will
-  be added before each day (regarding the local timezone)
-- If you specify marker1before, the id MR_MSG_ID_MARKER1 will be added just
-before the given ID.*/
 #define         MR_GCM_ADDDAYMARKER         0x01
 carray*         mrmailbox_get_chat_msgs     (mrmailbox_t*, uint32_t chat_id, uint32_t flags, uint32_t marker1before);
-
-
-/* Returns the total number of messages in a chat. */
 int             mrmailbox_get_total_msg_count (mrmailbox_t*, uint32_t chat_id);
-
-
-/* Returns the number of fresh messages in a chat.  Typically used to implement
-a badge with a number in the chatlist. */
 int             mrmailbox_get_fresh_msg_count (mrmailbox_t*, uint32_t chat_id);
-
-
-/* Returns message IDs of fresh messages, Typically used for implementing
-notification summaries.  The result must be free()'d. */
 carray*         mrmailbox_get_fresh_msgs    (mrmailbox_t*);
-
-
-/* mrmailbox_marknoticed_chat() marks all message in a whole chat as NOTICED.
-NOTICED messages are no longer FRESH and do not count as being unseen.
-IMAP/MDNs is not done for noticed messages.  See also mrmailbox_marknoticed_contact()
-and mrmailbox_markseen_msgs() */
 int             mrmailbox_marknoticed_chat  (mrmailbox_t*, uint32_t chat_id);
-
-
-/* Returns all message IDs of the given types in a chat.  Typically used to show
-a gallery.  The result must be carray_free()'d */
 carray*         mrmailbox_get_chat_media    (mrmailbox_t*, uint32_t chat_id, int msg_type, int or_msg_type);
-
-
-/* Get previous (dir=-1) or next media (dir=1) of a given media message.
-Typically used in a media player that plays eg. an voice message and should
-play the next when done.  If there is no previous/next media, 0 is returned. */
 uint32_t        mrmailbox_get_next_media    (mrmailbox_t*, uint32_t curr_msg_id, int dir);
 
+void            mrmailbox_archive_chat      (mrmailbox_t*, uint32_t chat_id, int archive);
+void            mrmailbox_delete_chat       (mrmailbox_t*, uint32_t chat_id);
 
-/* Archiv or unarchive a chat by setting the last paramter to 0 (unarchive) or
-1 (archive).  Archived chats are not returned in the default chatlist returned
-by mrmailbox_get_chatlist(0, NULL).  Instead, if there are _any_ archived chats,
-the pseudo-chat with the chat_id MR_CHAT_ID_ARCHIVED_LINK will be added the the
-end of the chatlist.
-To get a list of archived chats, use mrmailbox_get_chatlist(MR_GCL_ARCHIVED_ONLY, NULL). */
-int             mrmailbox_archive_chat      (mrmailbox_t*, uint32_t chat_id, int archive);
-
-
-/* Delete a chat:
-- messages are deleted from the device and the chat database entry is deleted
-- messages are _not_ deleted from the server
-- the chat is not blocked, so new messages from the user/the group may appear
-  and the user may create the chat again
-	- this is also one of the reasons, why groups are _not left_ -  this would
-	  be unexpected as deleting a normal chat also does not prevent new mails
-	- moreover, there may be valid reasons only to leave a group and only to
-	  delete a group
-	- another argument is, that leaving a group requires sending a message to
-	  all group members - esp. for groups not used for a longer time, this is
-	  really unexpected
-- to leave a chat, use mrmailbox_remove_contact_from_chat(mailbox, chat_id, MR_CONTACT_ID_SELF) */
-int             mrmailbox_delete_chat       (mrmailbox_t*, uint32_t chat_id);
-
-
-/* mrmailbox_get_chat_contacts() returns contact IDs, the result must be
-carray_free()'d.
-- for normal chats, the function always returns exactly one contact
-  MR_CONTACT_ID_SELF is _not_ returned.
-- for group chats all members are returned, MR_CONTACT_ID_SELF is returned
-  explicitly as it may happen that oneself gets removed from a still existing
-  group
-- for the deaddrop, all contacts are returned, MR_CONTACT_ID_SELF is not
-  added */
 carray*         mrmailbox_get_chat_contacts (mrmailbox_t*, uint32_t chat_id);
-
-
-/* Search messages containing the given query string.
-Searching can be done globally (chat_id=0) or in a specified chat only (chat_id
-set).
-- The function returns an array of messages IDs which must be carray_free()'d
-  by the caller.
-- If nothing can be found, the function returns NULL.
-Global chat results are typically displayed using mrmsg_get_summary(), chat
-search results may just hilite the corresponding messages and present a
-prev/next button. */
 carray*         mrmailbox_search_msgs       (mrmailbox_t*, uint32_t chat_id, const char* query);
 
-
-/* Get a chat object of type mrchat_t by a chat_id.
-To access the mrchat_t object, see mrchat.h
-The result must be unref'd using mrchat_unref(). */
 mrchat_t*       mrmailbox_get_chat          (mrmailbox_t*, uint32_t chat_id);
 
 
-/* The chat object and some function for helping accessing it.
-The chat object is not updated.  If you want an update, you have to recreate the
-object. */
+/**
+ * Chat objects are created using eg. mrmailbox_get_chat().
+ * The chat object is not updated.  If you want an update, you have to recreate the
+ * object.
+ */
 typedef struct mrchat_t
 {
 	#define         MR_CHAT_ID_DEADDROP         1 /* messages send from unknown/unwanted users to us, chats_contacts is not set up. This group may be shown normally. */
@@ -430,22 +249,19 @@ typedef struct mrchat_t
 	#define         MR_CHAT_TYPE_GROUP        120 /* a group chat, chats_contacts conain all group members, incl. MR_CONTACT_ID_SELF */
 	int             m_type;
 
-	char*           m_name;                       /* NULL if unset */
-	time_t          m_draft_timestamp;            /* 0 if there is no draft */
-	char*           m_draft_text;                 /* NULL if unset */
-	mrmailbox_t*    m_mailbox;                    /* != NULL */
+	char*           m_name;                       /**< NULL if unset */
+	time_t          m_draft_timestamp;            /**< 0 if there is no draft */
+	char*           m_draft_text;                 /**< NULL if unset */
+	mrmailbox_t*    m_mailbox;                    /**< != NULL */
+	int             m_archived;                   /**< 1=chat archived, this state should always be shown the UI, eg. the search will also return archived chats */
+	mrparam_t*      m_param;                      /**< != NULL */
+
+	/** @privatesection */
 	char*           m_grpid;                      /* NULL if unset */
-	int             m_archived;                   /* 1=chat archived, this state should always be shown the UI, eg. the search will also return archived chats */
-	mrparam_t*      m_param;                      /* != NULL */
 } mrchat_t;
 
 
-/* Frees a mrchat_t object created eg. by mrmailbox_get_chat(). */
 void            mrchat_unref                (mrchat_t*);
-
-
-/* either the email-address or the number of group members, the result must be
-free()'d! */
 char*           mrchat_get_subtitle         (mrchat_t*);
 
 
@@ -487,83 +303,58 @@ int             mrmailbox_set_chat_image    (mrmailbox_t*, uint32_t chat_id, con
  ******************************************************************************/
 
 
-/* Get an informational text for a single message. the text is multiline and may
-contain eg. the raw text of the message. The result must be unref'd using free(). */
 char*           mrmailbox_get_msg_info      (mrmailbox_t*, uint32_t msg_id);
-
-
-/* Delete a list of messages. The messages are deleted on the current device and
-on the IMAP server. */
-int             mrmailbox_delete_msgs       (mrmailbox_t*, const uint32_t* msg_ids, int msg_cnt);
-
-
-/* Forward a list of messages to another chat. */
-int             mrmailbox_forward_msgs      (mrmailbox_t*, const uint32_t* msg_ids, int msg_cnt, uint32_t chat_id);
-
-
-/* mrmailbox_marknoticed_contact() marks all messages send by the given contact
-as NOTICED.  See also mrmailbox_marknoticed_chat() and
-mrmailbox_markseen_msgs() */
-int             mrmailbox_marknoticed_contact (mrmailbox_t*, uint32_t contact_id);
-
-
-/* mrmailbox_markseen_msgs() marks a message as SEEN, updates the IMAP state and
-sends MDNs. if the message is not in a real chat (eg. a contact request), the
-message is only marked as NOTICED and no IMAP/MDNs is done.  See also
-mrmailbox_marknoticed_chat() and mrmailbox_marknoticed_contact() */
-int             mrmailbox_markseen_msgs     (mrmailbox_t*, const uint32_t* msg_ids, int msg_cnt);
-
-
-/* Star/unstar messages by setting the last parameter to 0 (unstar) or 1(star).
-Starred messages are collected in a virtual chat that can be shown using
-mrmailbox_get_chat_msgs(.., MR_CHAT_ID_STARRED, ..) */
-int             mrmailbox_star_msgs         (mrmailbox_t*, const uint32_t* msg_ids, int msg_cnt, int star);
-
-
-/* Get a single message object of the type mrmsg_t - for a list, see mrmailbox_get_chatlist() */
+void            mrmailbox_delete_msgs       (mrmailbox_t*, const uint32_t* msg_ids, int msg_cnt);
+void            mrmailbox_forward_msgs      (mrmailbox_t*, const uint32_t* msg_ids, int msg_cnt, uint32_t chat_id);
+void            mrmailbox_marknoticed_contact (mrmailbox_t*, uint32_t contact_id);
+void            mrmailbox_markseen_msgs     (mrmailbox_t*, const uint32_t* msg_ids, int msg_cnt);
+void            mrmailbox_star_msgs         (mrmailbox_t*, const uint32_t* msg_ids, int msg_cnt, int star);
 mrmsg_t*        mrmailbox_get_msg           (mrmailbox_t*, uint32_t msg_id);
 
 
-/* The message object and some function for helping accessing it.  The message
-object is not updated.  If you want an update, you have to recreate the
-object. */
+/**
+ * The message object and some function for helping accessing it.  The message
+ * object is not updated.  If you want an update, you have to recreate the
+ * object.
+ */
 typedef struct mrmsg_t
 {
-	#define         MR_MSG_ID_MARKER1       1 /* any user-defined marker */
-	#define         MR_MSG_ID_DAYMARKER     9 /* in a list, the next message is on a new day, useful to show headlines */
+	#define         MR_MSG_ID_MARKER1       1 /**< any user-defined marker */
+	#define         MR_MSG_ID_DAYMARKER     9 /**< in a list, the next message is on a new day, useful to show headlines */
 	#define         MR_MSG_ID_LAST_SPECIAL  9
 	uint32_t        m_id;
 
-	uint32_t        m_from_id;                /* contact, 0=unset, 1=self .. >9=real contacts */
-	uint32_t        m_to_id;                  /* contact, 0=unset, 1=self .. >9=real contacts */
-	uint32_t        m_chat_id;                /* the chat, the message belongs to: 0=unset, 1=unknwon sender .. >9=real chats */
-	time_t          m_timestamp;              /* unix time the message was sended */
+	uint32_t        m_from_id;                /**< contact, 0=unset, 1=self .. >9=real contacts */
+	uint32_t        m_to_id;                  /**< contact, 0=unset, 1=self .. >9=real contacts */
+	uint32_t        m_chat_id;                /**< the chat, the message belongs to: 0=unset, 1=unknwon sender .. >9=real chats */
+	time_t          m_timestamp;              /**< unix time the message was sended */
 
 	#define         MR_MSG_UNDEFINED        0
 	#define         MR_MSG_TEXT            10
-	#define         MR_MSG_IMAGE           20 /* param: MRP_FILE, MRP_WIDTH, MRP_HEIGHT */
-	#define         MR_MSG_GIF             21 /* param: MRP_FILE, MRP_WIDTH, MRP_HEIGHT */
-	#define         MR_MSG_AUDIO           40 /* param: MRP_FILE, MRP_DURATION */
-	#define         MR_MSG_VOICE           41 /* param: MRP_FILE, MRP_DURATION */
-	#define         MR_MSG_VIDEO           50 /* param: MRP_FILE, MRP_WIDTH, MRP_HEIGHT, MRP_DURATION */
-	#define         MR_MSG_FILE            60 /* param: MRP_FILE */
+	#define         MR_MSG_IMAGE           20 /**< param: MRP_FILE, MRP_WIDTH, MRP_HEIGHT */
+	#define         MR_MSG_GIF             21 /**< param: MRP_FILE, MRP_WIDTH, MRP_HEIGHT */
+	#define         MR_MSG_AUDIO           40 /**< param: MRP_FILE, MRP_DURATION */
+	#define         MR_MSG_VOICE           41 /**< param: MRP_FILE, MRP_DURATION */
+	#define         MR_MSG_VIDEO           50 /**< param: MRP_FILE, MRP_WIDTH, MRP_HEIGHT, MRP_DURATION */
+	#define         MR_MSG_FILE            60 /**< param: MRP_FILE */
 	int             m_type;
 
 	#define         MR_STATE_UNDEFINED      0
-	#define         MR_STATE_IN_FRESH      10 /* incoming message, not noticed nor seen */
-	#define         MR_STATE_IN_NOTICED    13 /* incoming message noticed (eg. chat opened but message not yet read - noticed messages are not counted as unread but did not marked as read nor resulted in MDNs) */
-	#define         MR_STATE_IN_SEEN       16 /* incoming message marked as read on IMAP and MDN may be send */
-	#define         MR_STATE_OUT_PENDING   20 /* hit "send" button - but the message is pending in some way, maybe we're offline (no checkmark) */
-	#define         MR_STATE_OUT_ERROR     24 /* unrecoverable error (recoverable errors result in pending messages) */
-	#define         MR_STATE_OUT_DELIVERED 26 /* outgoing message successfully delivered to server (one checkmark) */
-	#define         MR_STATE_OUT_MDN_RCVD  28 /* outgoing message read (two checkmarks; this requires goodwill on the receiver's side) */
+	#define         MR_STATE_IN_FRESH      10 /**< incoming message, not noticed nor seen */
+	#define         MR_STATE_IN_NOTICED    13 /**< incoming message noticed (eg. chat opened but message not yet read - noticed messages are not counted as unread but did not marked as read nor resulted in MDNs) */
+	#define         MR_STATE_IN_SEEN       16 /**< incoming message marked as read on IMAP and MDN may be send */
+	#define         MR_STATE_OUT_PENDING   20 /**< hit "send" button - but the message is pending in some way, maybe we're offline (no checkmark) */
+	#define         MR_STATE_OUT_ERROR     24 /**< unrecoverable error (recoverable errors result in pending messages) */
+	#define         MR_STATE_OUT_DELIVERED 26 /**< outgoing message successfully delivered to server (one checkmark) */
+	#define         MR_STATE_OUT_MDN_RCVD  28 /**< outgoing message read (two checkmarks; this requires goodwill on the receiver's side) */
 	int             m_state;
 
-	char*           m_text;                   /* message text or NULL if unset */
-	mrparam_t*      m_param;                  /* MRP_FILE, MRP_WIDTH, MRP_HEIGHT etc. depends on the type, != NULL */
+	char*           m_text;                   /**< message text or NULL if unset */
+	mrparam_t*      m_param;                  /**< MRP_FILE, MRP_WIDTH, MRP_HEIGHT etc. depends on the type, != NULL */
 	int             m_starred;
-	int             m_is_msgrmsg;
 
+	/** @privatesection */
+	int             m_is_msgrmsg;
 	mrmailbox_t*    m_mailbox;                /* may be NULL, set on loading from database and on sending */
 	char*           m_rfc724_mid;
 	char*           m_server_folder;
@@ -571,52 +362,16 @@ typedef struct mrmsg_t
 } mrmsg_t;
 
 
-/* Create new mrmsg_t object as needed for sending messages using
-mrmailbox_send_msg(). */
 mrmsg_t*        mrmsg_new                   ();
-
-
-/* Free an mrmsg_t object created eg. by mrmsg_new() or mrmailbox_get_msg().
-This also free()s all strings; so if you set up the object yourself, make sure
-to use strdup()! */
 void            mrmsg_unref                 (mrmsg_t*);
 void            mrmsg_empty                 (mrmsg_t*);
-
-
-/* Get a summary for a message. The last parameter can be set to speed up
-things if the chat object is already available; if not, it is faster to pass
-NULL here.  The result must be freed using mrpoortext_unref().
-Typically used to display a search result.
-The returned summary is similar to mrchatlist_get_summary(), however, without
-"draft", "no messages" and so on. */
 mrpoortext_t*   mrmsg_get_summary           (mrmsg_t*, mrchat_t*);
-
-
-/* Get a message summary as a single line of text.  Typically used for
-notifications.  The returned value must be free()'d. */
 char*           mrmsg_get_summarytext       (mrmsg_t*, int approx_characters);
-
-
-/* Check if a padlock should be shown beside the message. */
 int             mrmsg_show_padlock          (mrmsg_t*);
-
-
-/* Returns base file name without part, if appropriate.  The returned value must
-be free()'d */
+char*           mrmsg_get_fullpath          (mrmsg_t*);
 char*           mrmsg_get_filename          (mrmsg_t*);
-
-
-/* Returns real author (as text1, this is not always the sender, NULL if
-unknown) and title (text2, NULL if unknown) */
 mrpoortext_t*   mrmsg_get_mediainfo         (mrmsg_t*);
-
-
-/* check if a message is still in creation. */
 int             mrmsg_is_increation         (mrmsg_t*);
-
-
-/* can be used to add some additional, persistent information to a messages
-record */
 void            mrmsg_save_param_to_disk    (mrmsg_t*);
 
 

+ 37 - 0
deltachat-ios/libraries/deltachat-core/src/mrmailbox_configure.c

@@ -644,6 +644,24 @@ exit_:
  ******************************************************************************/
 
 
+/**
+ * mrmailbox_configure_and_connect() configures and connects a mailbox.
+ *
+ * - Before your call this function, you should set at least `addr` and `mail_pw`
+ *   using mrmailbox_set_config().
+ * - mrmailbox_configure_and_connect() returns immediately, configuration is done
+ *   in another thread; when done, the event MR_EVENT_CONFIGURE_ENDED ist posted
+ * - There is no need to call this every program start, the result is saved in the
+ *   database.
+ * - mrmailbox_configure_and_connect() should be called after any settings
+ *   change.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox the mailbox object as created by mrmailbox_new()
+ *
+ * @return none
+ */
 void mrmailbox_configure_and_connect(mrmailbox_t* mailbox)
 {
 	if( mailbox == NULL ) {
@@ -679,6 +697,15 @@ void mrmailbox_configure_and_connect(mrmailbox_t* mailbox)
 }
 
 
+/**
+ * Cancel an configuration started by mrmailbox_configure_and_connect().
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as created by mrmailbox_new()
+ *
+ * @return None
+ */
 void mrmailbox_configure_cancel(mrmailbox_t* mailbox)
 {
 	if( mailbox == NULL ) {
@@ -695,6 +722,16 @@ void mrmailbox_configure_cancel(mrmailbox_t* mailbox)
 }
 
 
+/**
+ * Check if the mailbox is already configured.  Typically, for unconfigured mailboxes, the user is prompeted for
+ * to enter some settings and mrmailbox_configure_and_connect() is called with them.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as created by mrmailbox_new()
+ *
+ * @return None
+ */
 int mrmailbox_is_configured(mrmailbox_t* mailbox)
 {
 	int is_configured;

+ 1 - 57
deltachat-ios/libraries/deltachat-core/src/mrmailbox_internal.h

@@ -35,11 +35,8 @@ extern "C" {
 #include "mrsqlite3.h"
 #include "mrtools.h"
 
-typedef struct mrjob_t mrjob_t;
-typedef struct mrimap_t mrimap_t;
-typedef struct mrsmtp_t mrsmtp_t;
 typedef struct mrmimeparser_t mrmimeparser_t;
-typedef struct mrsqlite3_t mrsqlite3_t;
+typedef struct mrjob_t      mrjob_t;
 
 
 /*******************************************************************************
@@ -47,48 +44,6 @@ typedef struct mrsqlite3_t mrsqlite3_t;
  ******************************************************************************/
 
 
-/* mrmailbox_t represents a single mailbox, normally, typically only one
-instance of this class is present.
-Each mailbox is linked to an IMAP/POP3 account and uses a separate
-SQLite database for offline functionality and for mailbox-related
-settings. */
-typedef struct mrmailbox_t
-{
-	void*            m_userdata;
-
-	mrsqlite3_t*     m_sql;      /* != NULL */
-	char*            m_dbfile;
-	char*            m_blobdir;
-
-	mrimap_t*        m_imap;     /* != NULL */
-	mrsmtp_t*        m_smtp;     /* != NULL */
-
-	pthread_t        m_job_thread;
-	pthread_cond_t   m_job_cond;
-	pthread_mutex_t  m_job_condmutex;
-	int              m_job_condflag;
-	int              m_job_do_exit;
-
-	mrmailboxcb_t    m_cb;
-
-	char*            m_os_name;
-
-	uint32_t         m_cmdline_sel_chat_id;
-
-	int              m_wake_lock;
-	pthread_mutex_t  m_wake_lock_critical;
-
-	int              m_e2ee_enabled;
-
-	#define          MR_LOG_RINGBUF_SIZE 200
-	pthread_mutex_t  m_log_ringbuf_critical;
-	char*            m_log_ringbuf[MR_LOG_RINGBUF_SIZE];
-	time_t           m_log_ringbuf_times[MR_LOG_RINGBUF_SIZE];
-	int              m_log_ringbuf_pos; /* the oldest position resp. the position that is overwritten next */
-
-} mrmailbox_t;
-
-
 #define MR_E2EE_DEFAULT_ENABLED  1
 #define MR_MDNS_DEFAULT_ENABLED  1
 
@@ -138,17 +93,6 @@ int    mrmailbox_get_archived_count__                    (mrmailbox_t*);
  ******************************************************************************/
 
 
-/* The chatlist object and some function for helping accessing it.
-The chatlist object is not updated.  If you want an update, you have to recreate
-the object. */
-typedef struct mrchatlist_t
-{
-	size_t          m_cnt;
-	carray*         m_chatNlastmsg_ids;
-	mrmailbox_t*    m_mailbox;
-} mrchatlist_t;
-
-
 mrchatlist_t* mrchatlist_new                 (mrmailbox_t*);
 void          mrchatlist_empty               (mrchatlist_t*);
 int           mrchatlist_load_from_db__    (mrchatlist_t*, int listflags, const char* query);

+ 210 - 33
deltachat-ios/libraries/deltachat-core/src/mrmsg.c

@@ -28,6 +28,11 @@
 #include "mrmimefactory.h"
 
 
+/**
+ * Foobar
+ */
+
+
 /*******************************************************************************
  * Tools
  ******************************************************************************/
@@ -163,10 +168,10 @@ int mrmailbox_rfc724_mid_cnt__(mrmailbox_t* mailbox, const char* rfc724_mid)
 }
 
 
+/* check, if the given Message-ID exists in the database (if not, the message is normally downloaded from the server and parsed,
+so, we should even keep unuseful messages in the database (we can leave the other fields empty to safe space) */
 int mrmailbox_rfc724_mid_exists__(mrmailbox_t* mailbox, const char* rfc724_mid, char** ret_server_folder, uint32_t* ret_server_uid)
 {
-	/* check, if the given Message-ID exists in the database (if not, the message is normally downloaded from the server and parsed,
-	so, we should even keep unuseful messages in the database (we can leave the other fields empty to safe space) */
 	sqlite3_stmt* stmt = mrsqlite3_predefine__(mailbox->m_sql, SELECT_ss_FROM_msgs_WHERE_m,
 		"SELECT server_folder, server_uid FROM msgs WHERE rfc724_mid=?;");
 	sqlite3_bind_text(stmt, 1, rfc724_mid, -1, SQLITE_STATIC);
@@ -238,6 +243,12 @@ cleanup:
  ******************************************************************************/
 
 
+ /**
+ * Create new mrmsg_t object as needed for sending messages using
+ * mrmailbox_send_msg().
+ *
+ * @memberof mrmsg_t
+ */
 mrmsg_t* mrmsg_new()
 {
 	mrmsg_t* ths = NULL;
@@ -254,6 +265,15 @@ mrmsg_t* mrmsg_new()
 }
 
 
+/**
+ * Free an mrmsg_t object created eg. by mrmsg_new() or mrmailbox_get_msg().
+ * This also free()s all strings; so if you set up the object yourself, make sure
+ * to use strdup()!
+ *
+ * @memberof mrmsg_t
+ *
+ * @param msg The message object to free.
+ */
 void mrmsg_unref(mrmsg_t* ths)
 {
 	if( ths==NULL ) {
@@ -287,16 +307,29 @@ void mrmsg_empty(mrmsg_t* ths)
 }
 
 
-mrmsg_t* mrmailbox_get_msg(mrmailbox_t* ths, uint32_t id)
+/**
+ * Get a single message object of the type mrmsg_t.
+ * For a list of messages in a chat, see mrmailbox_get_chat_msgs()
+ * For a list or chats, see mrmailbox_get_chatlist()
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox Mailbox object as created by mrmailbox_new()
+ *
+ * @param msg_id The message ID for which the message object should be created.
+ *
+ * @return A mrmsg_t message object. When done, the object must be freed using mrmsg_unref()
+ */
+mrmsg_t* mrmailbox_get_msg(mrmailbox_t* mailbox, uint32_t msg_id)
 {
 	int success = 0;
 	int db_locked = 0;
 	mrmsg_t* obj = mrmsg_new();
 
-	mrsqlite3_lock(ths->m_sql);
+	mrsqlite3_lock(mailbox->m_sql);
 	db_locked = 1;
 
-		if( !mrmsg_load_from_db__(obj, ths, id) ) {
+		if( !mrmsg_load_from_db__(obj, mailbox, msg_id) ) {
 			goto cleanup;
 		}
 
@@ -304,7 +337,7 @@ mrmsg_t* mrmailbox_get_msg(mrmailbox_t* ths, uint32_t id)
 
 cleanup:
 	if( db_locked ) {
-		mrsqlite3_unlock(ths->m_sql);
+		mrsqlite3_unlock(mailbox->m_sql);
 	}
 
 	if( success ) {
@@ -328,6 +361,18 @@ void mrmsg_set_text(mrmsg_t* msg, const char* text)
 }
 
 
+/**
+ * Get an informational text for a single message. the text is multiline and may
+ * contain eg. the raw text of the message.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox the mailbox object as created by mrmailbox_new()
+ *
+ * @param msg_id the message id for which information should be generated
+ *
+ * @return text string, must be free()'d after usage
+ */
 char* mrmailbox_get_msg_info(mrmailbox_t* mailbox, uint32_t msg_id)
 {
 	mrstrbuilder_t ret;
@@ -438,6 +483,17 @@ cleanup:
 }
 
 
+/**
+ * Get a summary for a message. The last parameter can be set to speed up
+ * things if the chat object is already available; if not, it is faster to pass
+ * NULL here.  The result must be freed using mrpoortext_unref().
+ * Typically used to display a search result.
+ *
+ * @memberof mrmsg_t
+ *
+ * @return  The returned summary is similar to mrchatlist_get_summary(), however, without
+ *     "draft", "no messages" and so on.
+ */
 mrpoortext_t* mrmsg_get_summary(mrmsg_t* msg, mrchat_t* chat)
 {
 	mrpoortext_t* ret = mrpoortext_new();
@@ -467,7 +523,11 @@ cleanup:
 	return ret;
 }
 
-
+/**
+ * Check if a padlock should be shown beside the message.
+ *
+ * @memberof mrmsg_t
+ */
 int mrmsg_show_padlock(mrmsg_t* msg)
 {
 	/* a padlock guarantees that the message is e2ee _and_ answers will be as well */
@@ -500,6 +560,12 @@ void mr_get_authorNtitle_from_filename(const char* pathNfilename, char** ret_aut
 }
 
 
+/**
+ * Get a message summary as a single line of text.  Typically used for
+ * notifications.  The returned value must be free()'d.
+ *
+ * @memberof mrmsg_t
+ */
 char* mrmsg_get_summarytext(mrmsg_t* msg, int approx_characters)
 {
 	if( msg==NULL ) {
@@ -567,6 +633,41 @@ char* mrmsg_get_summarytext_by_raw(int type, const char* text, mrparam_t* param,
 }
 
 
+/**
+ * Find out full path, file name and extension of the file associated with a
+ * message.
+ *
+ * @param msg the message object
+ *
+ * @return full path, file name and extension of the file associated with the
+ *     message.  If there is no file associated with the message, an emtpy
+ *     string is returned.  The returned value must be free()'d.
+ */
+char* mrmsg_get_fullpath(mrmsg_t* msg)
+{
+	char* ret = NULL;
+
+	if( msg == NULL ) {
+		goto cleanup;
+	}
+
+	ret = mrparam_get(msg->m_param, MRP_FILE, NULL);
+
+cleanup:
+	return ret? ret : safe_strdup(NULL);
+}
+
+
+/**
+ * Find out the base file name and extension of the file associated with a
+ * message.
+ *
+ * @param msg the message object
+ *
+ * @return base file name plus extension without part.  If there is no file
+ *     associated with the message, an empty string is returned.  The returned
+ *     value must be free()'d.
+ */
 char* mrmsg_get_filename(mrmsg_t* msg)
 {
 	char* ret = NULL, *pathNfilename = NULL;
@@ -588,16 +689,23 @@ cleanup:
 }
 
 
+/**
+ * Returns real author (as return.text1, this is not always the sender, NULL if
+ * unknown) and title (return.text2, NULL if unknown) of a message.
+ *
+ * For voice messages, the author the sender and the trackname is the sending time
+ * For music messages, we read the information from the filename
+ * We do not read ID3 and such at this stage, the needed libraries may be buggy
+ * and the whole stuff is way to complicated.
+ * However, this is not a great disadvantage, as the sender usually sets the filename in a way we expect it -
+ * if not, we simply print the whole filename as we do it for documents.  All fine in any case :-)
+ *
+ * @param msg the message object
+ *
+ * @return poortext object that must be unref'd using mrpoortext_unref() when no longer used.
+ */
 mrpoortext_t* mrmsg_get_mediainfo(mrmsg_t* msg)
 {
-	/* Get authorname and trackname of a message.
-	- for voice messages, the author the sender and the trackname is the sending time
-	- for music messages,
-	  - read the information from the filename
-	  - for security reasons, we DO NOT read ID3 and such at this stage, the needed libraries may be buggy
-		and the whole stuff is way to complicated.
-		However, this is not a great disadvantage, as the sender usually sets the filename in a way we expect it -
-		if not, we simply print the whole filename as we do it for documents.  All fine in any case :-) */
 	mrpoortext_t* ret = mrpoortext_new();
 	char *pathNfilename = NULL;
 	mrcontact_t* contact = NULL;
@@ -660,8 +768,20 @@ int mrmsg_is_increation__(const mrmsg_t* msg)
 }
 
 
-int mrmsg_is_increation(mrmsg_t* msg) /* surrounds mrmsg_is_increation__() with locking and error checking */
+/**
+ * Check if a message is still in creation.  The user can mark files as being
+ * in creation by simply creating a file `<filename>.increation`. If
+ * `<filename>` is created then, the user should just delete
+ * `<filename>.increation`
+ *
+ * @param msg the message object
+ *
+ * @return 1=message is still in creation (`<filename>.increation` exists),
+ *     0=message no longer in creation
+ */
+int mrmsg_is_increation(mrmsg_t* msg)
 {
+	/* surrounds mrmsg_is_increation__() with locking and error checking */
 	int is_increation = 0;
 	if( msg && msg->m_mailbox && MR_MSG_NEEDS_ATTACHMENT(msg->m_type) /*additional check for speed reasons*/ )
 	{
@@ -673,6 +793,7 @@ int mrmsg_is_increation(mrmsg_t* msg) /* surrounds mrmsg_is_increation__() with
 }
 
 
+/* Internal function similar to mrmsg_save_param_to_disk() but without locking. */
 void mrmsg_save_param_to_disk__(mrmsg_t* msg)
 {
 	if( msg == NULL || msg->m_mailbox == NULL || msg->m_mailbox->m_sql == NULL ) {
@@ -687,6 +808,12 @@ void mrmsg_save_param_to_disk__(mrmsg_t* msg)
 }
 
 
+/**
+ * can be used to add some additional, persistent information to a messages
+ * record.
+ *
+ * @memberof mrmsg_t
+ */
 void mrmsg_save_param_to_disk(mrmsg_t* msg)
 {
 	if( msg == NULL || msg->m_mailbox == NULL || msg->m_mailbox->m_sql == NULL ) {
@@ -704,6 +831,7 @@ void mrmsg_save_param_to_disk(mrmsg_t* msg)
  ******************************************************************************/
 
 
+/* internal function */
 void mrmailbox_delete_msg_on_imap(mrmailbox_t* mailbox, mrjob_t* job)
 {
 	int      locked = 0, delete_from_server = 1;
@@ -801,12 +929,26 @@ cleanup:
 }
 
 
-int mrmailbox_delete_msgs(mrmailbox_t* ths, const uint32_t* msg_ids, int msg_cnt)
+/**
+ * Delete a list of messages. The messages are deleted on the current device and
+ * on the IMAP server.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox the mailbox object as created by mrmailbox_new()
+ *
+ * @param msg_ids an array of uint32_t containing all message IDs that should be deleted
+ *
+ * @param msg_cnt the number of messages IDs in the msg_ids array
+ *
+ * @return none
+ */
+void mrmailbox_delete_msgs(mrmailbox_t* ths, const uint32_t* msg_ids, int msg_cnt)
 {
 	int i;
 
 	if( ths == NULL || msg_ids == NULL || msg_cnt <= 0 ) {
-		return 0;
+		return;
 	}
 
 	mrsqlite3_lock(ths->m_sql);
@@ -820,17 +962,28 @@ int mrmailbox_delete_msgs(mrmailbox_t* ths, const uint32_t* msg_ids, int msg_cnt
 
 	mrsqlite3_commit__(ths->m_sql);
 	mrsqlite3_unlock(ths->m_sql);
-
-	return 1;
 }
 
 
-int mrmailbox_forward_msgs(mrmailbox_t* mailbox, const uint32_t* msg_ids_unsorted, int msg_cnt, uint32_t chat_id)
+/**
+ * Forward a list of messages to another chat.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox the mailbox object as created by mrmailbox_new()
+ *
+ * @param msg_ids an array of uint32_t containing all message IDs that should be forwarded
+ *
+ * @param msg_cnt the number of messages IDs in the msg_ids array
+ *
+ * @return none
+ */
+void mrmailbox_forward_msgs(mrmailbox_t* mailbox, const uint32_t* msg_ids_unsorted, int msg_cnt, uint32_t chat_id)
 {
 	mrmsg_t*      msg = mrmsg_new();
 	mrchat_t*     chat = mrchat_new(mailbox);
 	mrcontact_t*  contact = mrcontact_new();
-	int           success = 0, locked = 0, transaction_pending = 0;
+	int           locked = 0, transaction_pending = 0;
 	carray*       created_db_entries = carray_new(16);
 	char*         idsstr = NULL, *q3 = NULL;
 	sqlite3_stmt* stmt = NULL;
@@ -875,8 +1028,6 @@ int mrmailbox_forward_msgs(mrmailbox_t* mailbox, const uint32_t* msg_ids_unsorte
 	mrsqlite3_commit__(mailbox->m_sql);
 	transaction_pending = 0;
 
-	success = 1;
-
 cleanup:
 	if( transaction_pending ) { mrsqlite3_rollback__(mailbox->m_sql); }
 	if( locked ) { mrsqlite3_unlock(mailbox->m_sql); }
@@ -893,16 +1044,32 @@ cleanup:
 	if( stmt ) { sqlite3_finalize(stmt); }
 	free(idsstr);
 	if( q3 ) { sqlite3_free(q3); }
-	return success;
 }
 
 
-int mrmailbox_star_msgs(mrmailbox_t* mailbox, const uint32_t* msg_ids, int msg_cnt, int star)
+/**
+ * Star/unstar messages by setting the last parameter to 0 (unstar) or 1(star).
+ * Starred messages are collected in a virtual chat that can be shown using
+ * mrmailbox_get_chat_msgs() using the chat_id MR_CHAT_ID_STARRED.
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param mailbox The mailbox object as created by mrmailbox_new()
+ *
+ * @param msg_ids An array of uint32_t message IDs defining the messages to star or unstar
+ *
+ * @param msg_cnt The number of IDs in msg_ids
+ *
+ * @param star 0=unstar the messages in msg_ids, 1=star them
+ *
+ * @return none
+ */
+void mrmailbox_star_msgs(mrmailbox_t* mailbox, const uint32_t* msg_ids, int msg_cnt, int star)
 {
 	int i;
 
 	if( mailbox == NULL || msg_ids == NULL || msg_cnt <= 0 || (star!=0 && star!=1) ) {
-		return 0;
+		return;
 	}
 
 	mrsqlite3_lock(mailbox->m_sql);
@@ -919,8 +1086,6 @@ int mrmailbox_star_msgs(mrmailbox_t* mailbox, const uint32_t* msg_ids, int msg_c
 
 	mrsqlite3_commit__(mailbox->m_sql);
 	mrsqlite3_unlock(mailbox->m_sql);
-
-	return 1;
 }
 
 
@@ -1027,12 +1192,26 @@ cleanup:
 }
 
 
-int mrmailbox_markseen_msgs(mrmailbox_t* mailbox, const uint32_t* msg_ids, int msg_cnt)
+/**
+ * Mark a message as _seen_, updates the IMAP state and
+ * sends MDNs. if the message is not in a real chat (eg. a contact request), the
+ * message is only marked as NOTICED and no IMAP/MDNs is done.  See also
+ * mrmailbox_marknoticed_chat() and mrmailbox_marknoticed_contact()
+ *
+ * @memberof mrmailbox_t
+ *
+ * @param msg_ids an array of uint32_t containing all the messages IDs that should be marked as seen
+ *
+ * @param msg_cnt the number of message IDs in msg_ids
+ *
+ * @return none
+ */
+void mrmailbox_markseen_msgs(mrmailbox_t* mailbox, const uint32_t* msg_ids, int msg_cnt)
 {
 	int i, send_event = 0;
 
 	if( mailbox == NULL || msg_ids == NULL || msg_cnt <= 0 ) {
-		return 0;
+		return;
 	}
 
 	mrsqlite3_lock(mailbox->m_sql);
@@ -1072,8 +1251,6 @@ int mrmailbox_markseen_msgs(mrmailbox_t* mailbox, const uint32_t* msg_ids, int m
 	if( send_event ) {
 		mailbox->m_cb(mailbox, MR_EVENT_MSGS_CHANGED, 0, 0);
 	}
-
-	return 1;
 }
 
 

+ 14 - 4
deltachat-ios/libraries/deltachat-core/src/mrpoortext.c

@@ -42,14 +42,24 @@ mrpoortext_t* mrpoortext_new()
 }
 
 
-void mrpoortext_unref(mrpoortext_t* ths)
+/**
+ * Frees a mrpoortext_t object created eg. by mrchatlist_get_summary() or by
+ * mrmsg_eget_summary().  This also frees the strings objects.
+ *
+ * @memberof mrpoortext_t
+ *
+ * @param poortext The mrpoortext_t object to free.
+ *
+ * @return None
+ */
+void mrpoortext_unref(mrpoortext_t* poortext)
 {
-	if( ths==NULL ) {
+	if( poortext==NULL ) {
 		return;
 	}
 
-	mrpoortext_empty(ths);
-	free(ths);
+	mrpoortext_empty(poortext);
+	free(poortext);
 }