1
0
Fork 0
mirror of https://github.com/deltachat/deltachat-core.git synced 2025-10-05 10:39:27 +02:00

refactor mimefactory, mimeparser, keyring, key, pgp, msg, chatlist, chat, lot and more

This commit is contained in:
B. Petersen 2018-06-25 02:41:01 +02:00
parent 9dce83089c
commit 54b34edec2
51 changed files with 1694 additions and 1694 deletions

View file

@ -48,34 +48,34 @@ int mrmailbox_reset_tables(mrmailbox_t* ths, int bits)
dc_log_info(ths, 0, "Resetting tables (%i)...", bits); dc_log_info(ths, 0, "Resetting tables (%i)...", bits);
mrsqlite3_lock(ths->m_sql); dc_sqlite3_lock(ths->m_sql);
if( bits & 1 ) { if( bits & 1 ) {
mrsqlite3_execute__(ths->m_sql, "DELETE FROM jobs;"); dc_sqlite3_execute__(ths->m_sql, "DELETE FROM jobs;");
dc_log_info(ths, 0, "(1) Jobs reset."); dc_log_info(ths, 0, "(1) Jobs reset.");
} }
if( bits & 2 ) { if( bits & 2 ) {
mrsqlite3_execute__(ths->m_sql, "DELETE FROM acpeerstates;"); dc_sqlite3_execute__(ths->m_sql, "DELETE FROM acpeerstates;");
dc_log_info(ths, 0, "(2) Peerstates reset."); dc_log_info(ths, 0, "(2) Peerstates reset.");
} }
if( bits & 4 ) { if( bits & 4 ) {
mrsqlite3_execute__(ths->m_sql, "DELETE FROM keypairs;"); dc_sqlite3_execute__(ths->m_sql, "DELETE FROM keypairs;");
dc_log_info(ths, 0, "(4) Private keypairs reset."); dc_log_info(ths, 0, "(4) Private keypairs reset.");
} }
if( bits & 8 ) { if( bits & 8 ) {
mrsqlite3_execute__(ths->m_sql, "DELETE FROM contacts WHERE id>" MR_STRINGIFY(MR_CONTACT_ID_LAST_SPECIAL) ";"); /* the other IDs are reserved - leave these rows to make sure, the IDs are not used by normal contacts*/ dc_sqlite3_execute__(ths->m_sql, "DELETE FROM contacts WHERE id>" MR_STRINGIFY(MR_CONTACT_ID_LAST_SPECIAL) ";"); /* the other IDs are reserved - leave these rows to make sure, the IDs are not used by normal contacts*/
mrsqlite3_execute__(ths->m_sql, "DELETE FROM chats WHERE id>" MR_STRINGIFY(MR_CHAT_ID_LAST_SPECIAL) ";"); dc_sqlite3_execute__(ths->m_sql, "DELETE FROM chats WHERE id>" MR_STRINGIFY(MR_CHAT_ID_LAST_SPECIAL) ";");
mrsqlite3_execute__(ths->m_sql, "DELETE FROM chats_contacts;"); dc_sqlite3_execute__(ths->m_sql, "DELETE FROM chats_contacts;");
mrsqlite3_execute__(ths->m_sql, "DELETE FROM msgs WHERE id>" MR_STRINGIFY(MR_MSG_ID_LAST_SPECIAL) ";"); dc_sqlite3_execute__(ths->m_sql, "DELETE FROM msgs WHERE id>" MR_STRINGIFY(MR_MSG_ID_LAST_SPECIAL) ";");
mrsqlite3_execute__(ths->m_sql, "DELETE FROM config WHERE keyname LIKE 'imap.%' OR keyname LIKE 'configured%';"); dc_sqlite3_execute__(ths->m_sql, "DELETE FROM config WHERE keyname LIKE 'imap.%' OR keyname LIKE 'configured%';");
mrsqlite3_execute__(ths->m_sql, "DELETE FROM leftgrps;"); dc_sqlite3_execute__(ths->m_sql, "DELETE FROM leftgrps;");
dc_log_info(ths, 0, "(8) Rest but server config reset."); dc_log_info(ths, 0, "(8) Rest but server config reset.");
} }
mrsqlite3_unlock(ths->m_sql); dc_sqlite3_unlock(ths->m_sql);
ths->m_cb(ths, MR_EVENT_MSGS_CHANGED, 0, 0); ths->m_cb(ths, MR_EVENT_MSGS_CHANGED, 0, 0);
@ -101,11 +101,11 @@ static int mrmailbox_cleanup_contacts(mrmailbox_t* ths)
dc_log_info(ths, 0, "Cleaning up contacts ..."); dc_log_info(ths, 0, "Cleaning up contacts ...");
mrsqlite3_lock(ths->m_sql); dc_sqlite3_lock(ths->m_sql);
mrsqlite3_execute__(ths->m_sql, "DELETE FROM contacts WHERE id>" MR_STRINGIFY(MR_CONTACT_ID_LAST_SPECIAL) " AND blocked=0 AND NOT EXISTS (SELECT contact_id FROM chats_contacts where contacts.id = chats_contacts.contact_id) AND NOT EXISTS (select from_id from msgs WHERE msgs.from_id = contacts.id);"); dc_sqlite3_execute__(ths->m_sql, "DELETE FROM contacts WHERE id>" MR_STRINGIFY(MR_CONTACT_ID_LAST_SPECIAL) " AND blocked=0 AND NOT EXISTS (SELECT contact_id FROM chats_contacts where contacts.id = chats_contacts.contact_id) AND NOT EXISTS (select from_id from msgs WHERE msgs.from_id = contacts.id);");
mrsqlite3_unlock(ths->m_sql); dc_sqlite3_unlock(ths->m_sql);
return 1; return 1;
} }
@ -150,14 +150,14 @@ static int poke_public_key(mrmailbox_t* mailbox, const char* addr, const char* p
/* create a fake autocrypt header */ /* create a fake autocrypt header */
header->m_addr = safe_strdup(addr); header->m_addr = safe_strdup(addr);
header->m_prefer_encrypt = MRA_PE_MUTUAL; header->m_prefer_encrypt = MRA_PE_MUTUAL;
if( !mrkey_set_from_file(header->m_public_key, public_key_file, mailbox) if( !dc_key_set_from_file(header->m_public_key, public_key_file, mailbox)
|| !mrpgp_is_valid_key(mailbox, header->m_public_key) ) { || !dc_pgp_is_valid_key(mailbox, header->m_public_key) ) {
dc_log_warning(mailbox, 0, "No valid key found in \"%s\".", public_key_file); dc_log_warning(mailbox, 0, "No valid key found in \"%s\".", public_key_file);
goto cleanup; goto cleanup;
} }
/* update/create peerstate */ /* update/create peerstate */
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
if( dc_apeerstate_load_by_addr__(peerstate, mailbox->m_sql, addr) ) { if( dc_apeerstate_load_by_addr__(peerstate, mailbox->m_sql, addr) ) {
@ -172,7 +172,7 @@ static int poke_public_key(mrmailbox_t* mailbox, const char* addr, const char* p
success = 1; success = 1;
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
dc_apeerstate_unref(peerstate); dc_apeerstate_unref(peerstate);
dc_aheader_unref(header); dc_aheader_unref(header);
return success; return success;
@ -206,7 +206,7 @@ static int poke_spec(mrmailbox_t* mailbox, const char* spec)
return 0; return 0;
} }
if( !mrsqlite3_is_open(mailbox->m_sql) ) { if( !dc_sqlite3_is_open(mailbox->m_sql) ) {
dc_log_error(mailbox, 0, "Import: Database not opened."); dc_log_error(mailbox, 0, "Import: Database not opened.");
goto cleanup; goto cleanup;
} }
@ -215,14 +215,14 @@ static int poke_spec(mrmailbox_t* mailbox, const char* spec)
if( spec ) if( spec )
{ {
real_spec = safe_strdup(spec); real_spec = safe_strdup(spec);
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
mrsqlite3_set_config__(mailbox->m_sql, "import_spec", real_spec); dc_sqlite3_set_config__(mailbox->m_sql, "import_spec", real_spec);
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
} }
else { else {
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
real_spec = mrsqlite3_get_config__(mailbox->m_sql, "import_spec", NULL); /* may still NULL */ real_spec = dc_sqlite3_get_config__(mailbox->m_sql, "import_spec", NULL); /* may still NULL */
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
if( real_spec == NULL ) { if( real_spec == NULL ) {
dc_log_error(mailbox, 0, "Import: No file or folder given."); dc_log_error(mailbox, 0, "Import: No file or folder given.");
goto cleanup; goto cleanup;
@ -284,20 +284,20 @@ cleanup:
} }
static void log_msglist(mrmailbox_t* mailbox, mrarray_t* msglist) static void log_msglist(mrmailbox_t* mailbox, dc_array_t* msglist)
{ {
int i, cnt = mrarray_get_cnt(msglist), lines_out = 0; int i, cnt = mrarray_get_cnt(msglist), lines_out = 0;
for( i = 0; i < cnt; i++ ) for( i = 0; i < cnt; i++ )
{ {
uint32_t msg_id = mrarray_get_id(msglist, i); uint32_t msg_id = dc_array_get_id(msglist, i);
if( msg_id == MR_MSG_ID_DAYMARKER ) { if( msg_id == MR_MSG_ID_DAYMARKER ) {
dc_log_info(mailbox, 0, "--------------------------------------------------------------------------------"); lines_out++; dc_log_info(mailbox, 0, "--------------------------------------------------------------------------------"); lines_out++;
} }
else if( msg_id > 0 ) { else if( msg_id > 0 ) {
if( lines_out==0 ) { dc_log_info(mailbox, 0, "--------------------------------------------------------------------------------"); lines_out++; } if( lines_out==0 ) { dc_log_info(mailbox, 0, "--------------------------------------------------------------------------------"); lines_out++; }
mrmsg_t* msg = mrmailbox_get_msg(mailbox, msg_id); dc_msg_t* msg = mrmailbox_get_msg(mailbox, msg_id);
mrcontact_t* contact = mrmailbox_get_contact(mailbox, mrmsg_get_from_id(msg)); dc_contact_t* contact = mrmailbox_get_contact(mailbox, mrmsg_get_from_id(msg));
char* contact_name = mrcontact_get_name(contact); char* contact_name = mrcontact_get_name(contact);
int contact_id = mrcontact_get_id(contact); int contact_id = mrcontact_get_id(contact);
@ -351,9 +351,9 @@ static void log_contactlist(mrmailbox_t* mailbox, mrarray_t* contacts)
int verified_state = mrcontact_is_verified(contact); int verified_state = mrcontact_is_verified(contact);
const char* verified_str = verified_state? (verified_state==2? " √√":""): ""; const char* verified_str = verified_state? (verified_state==2? " √√":""): "";
line = mr_mprintf("%s%s <%s>", (name&&name[0])? name : "<name unset>", verified_str, (addr&&addr[0])? addr : "addr unset"); line = mr_mprintf("%s%s <%s>", (name&&name[0])? name : "<name unset>", verified_str, (addr&&addr[0])? addr : "addr unset");
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
int peerstate_ok = dc_apeerstate_load_by_addr__(peerstate, mailbox->m_sql, addr); int peerstate_ok = dc_apeerstate_load_by_addr__(peerstate, mailbox->m_sql, addr);
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
if( peerstate_ok && contact_id != MR_CONTACT_ID_SELF ) { if( peerstate_ok && contact_id != MR_CONTACT_ID_SELF ) {
char* pe = NULL; char* pe = NULL;
switch( peerstate->m_prefer_encrypt ) { switch( peerstate->m_prefer_encrypt ) {

View file

@ -178,29 +178,29 @@ void stress_functions(mrmailbox_t* mailbox)
**************************************************************************/ **************************************************************************/
{ {
mrsimplify_t* simplify = mrsimplify_new(); dc_simplify_t* simplify = dc_simplify_new();
const char* html = "\r\r\nline1<br>\r\n\r\n\r\rline2\n\r"; /* check, that `<br>\ntext` does not result in `\n text` */ const char* html = "\r\r\nline1<br>\r\n\r\n\r\rline2\n\r"; /* check, that `<br>\ntext` does not result in `\n text` */
char* plain = mrsimplify_simplify(simplify, html, strlen(html), 1); char* plain = dc_simplify_simplify(simplify, html, strlen(html), 1);
assert( strcmp(plain, "line1\nline2")==0 ); assert( strcmp(plain, "line1\nline2")==0 );
free(plain); free(plain);
html = "<a href=url>text</a"; /* check unquoted attribute and unclosed end-tag */ html = "<a href=url>text</a"; /* check unquoted attribute and unclosed end-tag */
plain = mrsimplify_simplify(simplify, html, strlen(html), 1); plain = dc_simplify_simplify(simplify, html, strlen(html), 1);
assert( strcmp(plain, "[text](url)")==0 ); assert( strcmp(plain, "[text](url)")==0 );
free(plain); free(plain);
html = "<!DOCTYPE name [<!DOCTYPE ...>]><!-- comment -->text <b><?php echo ... ?>bold</b><![CDATA[<>]]>"; html = "<!DOCTYPE name [<!DOCTYPE ...>]><!-- comment -->text <b><?php echo ... ?>bold</b><![CDATA[<>]]>";
plain = mrsimplify_simplify(simplify, html, strlen(html), 1); plain = dc_simplify_simplify(simplify, html, strlen(html), 1);
assert( strcmp(plain, "text *bold*<>")==0 ); assert( strcmp(plain, "text *bold*<>")==0 );
free(plain); free(plain);
html = "&lt;&gt;&quot;&apos;&amp; &auml;&Auml;&ouml;&Ouml;&uuml;&Uuml;&szlig; foo&AElig;&ccedil;&Ccedil; &diams;&noent;&lrm;&rlm;&zwnj;&zwj;"; html = "&lt;&gt;&quot;&apos;&amp; &auml;&Auml;&ouml;&Ouml;&uuml;&Uuml;&szlig; foo&AElig;&ccedil;&Ccedil; &diams;&noent;&lrm;&rlm;&zwnj;&zwj;";
plain = mrsimplify_simplify(simplify, html, strlen(html), 1); plain = dc_simplify_simplify(simplify, html, strlen(html), 1);
assert( strcmp(plain, "<>\"'& äÄöÖüÜß fooÆçÇ ♦&noent;")==0 ); assert( strcmp(plain, "<>\"'& äÄöÖüÜß fooÆçÇ ♦&noent;")==0 );
free(plain); free(plain);
mrsimplify_unref(simplify); dc_simplify_unref(simplify);
} }
/* test mailmime /* test mailmime
@ -237,7 +237,7 @@ void stress_functions(mrmailbox_t* mailbox)
**************************************************************************/ **************************************************************************/
{ {
mrmimeparser_t* mimeparser = mrmimeparser_new(mailbox->m_blobdir, mailbox); dc_mimeparser_t* mimeparser = dc_mimeparser_new(mailbox->m_blobdir, mailbox);
const char* raw = const char* raw =
"Content-Type: multipart/mixed; boundary=\"==break==\";\n" "Content-Type: multipart/mixed; boundary=\"==break==\";\n"
@ -258,22 +258,22 @@ void stress_functions(mrmailbox_t* mailbox)
"--==break==--\n" "--==break==--\n"
"\n"; "\n";
mrmimeparser_parse(mimeparser, raw, strlen(raw)); dc_mimeparser_parse(mimeparser, raw, strlen(raw));
assert( strcmp(mimeparser->m_subject, "inner-subject")==0 ); assert( strcmp(mimeparser->m_subject, "inner-subject")==0 );
struct mailimf_optional_field* of = mrmimeparser_lookup_optional_field(mimeparser, "X-Special-A"); struct mailimf_optional_field* of = dc_mimeparser_lookup_optional_field(mimeparser, "X-Special-A");
assert( strcmp(of->fld_value, "special-a")==0 ); assert( strcmp(of->fld_value, "special-a")==0 );
of = mrmimeparser_lookup_optional_field(mimeparser, "Foo"); of = dc_mimeparser_lookup_optional_field(mimeparser, "Foo");
assert( strcmp(of->fld_value, "Bar")==0 ); /* completely unknown values are not overwritten */ assert( strcmp(of->fld_value, "Bar")==0 ); /* completely unknown values are not overwritten */
of = mrmimeparser_lookup_optional_field(mimeparser, "Chat-Version"); of = dc_mimeparser_lookup_optional_field(mimeparser, "Chat-Version");
assert( strcmp(of->fld_value, "1.0")==0 ); assert( strcmp(of->fld_value, "1.0")==0 );
assert( carray_count(mimeparser->m_parts) == 1 ); assert( carray_count(mimeparser->m_parts) == 1 );
mrmimeparser_unref(mimeparser); dc_mimeparser_unref(mimeparser);
} }
/* test message helpers /* test message helpers
@ -282,10 +282,10 @@ void stress_functions(mrmailbox_t* mailbox)
{ {
int type; int type;
char* mime; char* mime;
mrmsg_guess_msgtype_from_suffix("foo/bar-sth.mp3", NULL, NULL); dc_msg_guess_msgtype_from_suffix("foo/bar-sth.mp3", NULL, NULL);
mrmsg_guess_msgtype_from_suffix("foo/bar-sth.mp3", NULL, &mime); dc_msg_guess_msgtype_from_suffix("foo/bar-sth.mp3", NULL, &mime);
assert( strcmp(mime, "audio/mpeg")==0 ); assert( strcmp(mime, "audio/mpeg")==0 );
mrmsg_guess_msgtype_from_suffix("foo/bar-sth.mp3", &type, NULL); dc_msg_guess_msgtype_from_suffix("foo/bar-sth.mp3", &type, NULL);
assert( type == MR_MSG_AUDIO ); assert( type == MR_MSG_AUDIO );
free(mime); free(mime);
} }
@ -504,18 +504,18 @@ void stress_functions(mrmailbox_t* mailbox)
assert( mrarray_get_id(arr, TEST_CNT) == 0 ); /* test out-of-range access */ assert( mrarray_get_id(arr, TEST_CNT) == 0 ); /* test out-of-range access */
assert( mrarray_get_id(arr, TEST_CNT+1) == 0 ); /* test out-of-range access */ assert( mrarray_get_id(arr, TEST_CNT+1) == 0 ); /* test out-of-range access */
mrarray_empty(arr); dc_array_empty(arr);
assert( mrarray_get_cnt(arr) == 0 ); assert( dc_array_get_cnt(arr) == 0 );
mrarray_add_id(arr, 13); dc_array_add_id(arr, 13);
mrarray_add_id(arr, 7); dc_array_add_id(arr, 7);
mrarray_add_id(arr, 666); dc_array_add_id(arr, 666);
mrarray_add_id(arr, 0); dc_array_add_id(arr, 0);
mrarray_add_id(arr, 5000); dc_array_add_id(arr, 5000);
mrarray_sort_ids(arr); dc_array_sort_ids(arr);
assert( mrarray_get_id(arr, 0)==0 && mrarray_get_id(arr, 1)==7 && mrarray_get_id(arr, 2)==13 && mrarray_get_id(arr, 3)==666 ); assert( dc_array_get_id(arr, 0)==0 && dc_array_get_id(arr, 1)==7 && dc_array_get_id(arr, 2)==13 && dc_array_get_id(arr, 3)==666 );
char* str = mrarray_get_string(arr, "-"); char* str = dc_array_get_string(arr, "-");
assert( strcmp(str, "0-7-13-666-5000")==0 ); assert( strcmp(str, "0-7-13-666-5000")==0 );
free(str); free(str);
@ -525,17 +525,17 @@ void stress_functions(mrmailbox_t* mailbox)
free(str); free(str);
mrarray_empty(arr); mrarray_empty(arr);
mrarray_add_ptr(arr, "XX"); dc_array_add_ptr(arr, "XX");
mrarray_add_ptr(arr, "item1"); dc_array_add_ptr(arr, "item1");
mrarray_add_ptr(arr, "bbb"); dc_array_add_ptr(arr, "bbb");
mrarray_add_ptr(arr, "aaa"); dc_array_add_ptr(arr, "aaa");
mrarray_sort_strings(arr); dc_array_sort_strings(arr);
assert( strcmp("XX", (char*)mrarray_get_ptr(arr, 0))==0 ); assert( strcmp("XX", (char*)dc_array_get_ptr(arr, 0))==0 );
assert( strcmp("aaa", (char*)mrarray_get_ptr(arr, 1))==0 ); assert( strcmp("aaa", (char*)dc_array_get_ptr(arr, 1))==0 );
assert( strcmp("bbb", (char*)mrarray_get_ptr(arr, 2))==0 ); assert( strcmp("bbb", (char*)dc_array_get_ptr(arr, 2))==0 );
assert( strcmp("item1", (char*)mrarray_get_ptr(arr, 3))==0 ); assert( strcmp("item1", (char*)dc_array_get_ptr(arr, 3))==0 );
mrarray_unref(arr); dc_array_unref(arr);
} }
/* test mrparam /* test mrparam
@ -631,21 +631,21 @@ void stress_functions(mrmailbox_t* mailbox)
const char *headerline, *setupcodebegin, *preferencrypt, *base64; const char *headerline, *setupcodebegin, *preferencrypt, *base64;
buf = strdup("-----BEGIN PGP MESSAGE-----\nNoVal:\n\ndata\n-----END PGP MESSAGE-----"); buf = strdup("-----BEGIN PGP MESSAGE-----\nNoVal:\n\ndata\n-----END PGP MESSAGE-----");
ok = mr_split_armored_data(buf, &headerline, &setupcodebegin, NULL, &base64); ok = dc_split_armored_data(buf, &headerline, &setupcodebegin, NULL, &base64);
assert( ok == 1 ); assert( ok == 1 );
assert( headerline && strcmp(headerline, "-----BEGIN PGP MESSAGE-----")==0 ); assert( headerline && strcmp(headerline, "-----BEGIN PGP MESSAGE-----")==0 );
assert( base64 && strcmp(base64, "data") == 0 ); assert( base64 && strcmp(base64, "data") == 0 );
free(buf); free(buf);
buf = strdup("-----BEGIN PGP MESSAGE-----\n\ndat1\n-----END PGP MESSAGE-----\n-----BEGIN PGP MESSAGE-----\n\ndat2\n-----END PGP MESSAGE-----"); buf = strdup("-----BEGIN PGP MESSAGE-----\n\ndat1\n-----END PGP MESSAGE-----\n-----BEGIN PGP MESSAGE-----\n\ndat2\n-----END PGP MESSAGE-----");
ok = mr_split_armored_data(buf, &headerline, &setupcodebegin, NULL, &base64); ok = dc_split_armored_data(buf, &headerline, &setupcodebegin, NULL, &base64);
assert( ok == 1 ); assert( ok == 1 );
assert( headerline && strcmp(headerline, "-----BEGIN PGP MESSAGE-----")==0 ); assert( headerline && strcmp(headerline, "-----BEGIN PGP MESSAGE-----")==0 );
assert( base64 && strcmp(base64, "dat1") == 0 ); assert( base64 && strcmp(base64, "dat1") == 0 );
free(buf); free(buf);
buf = strdup("foo \n -----BEGIN PGP MESSAGE----- \n base64-123 \n -----END PGP MESSAGE-----"); buf = strdup("foo \n -----BEGIN PGP MESSAGE----- \n base64-123 \n -----END PGP MESSAGE-----");
ok = mr_split_armored_data(buf, &headerline, &setupcodebegin, NULL, &base64); ok = dc_split_armored_data(buf, &headerline, &setupcodebegin, NULL, &base64);
assert( ok == 1 ); assert( ok == 1 );
assert( headerline && strcmp(headerline, "-----BEGIN PGP MESSAGE-----")==0 ); assert( headerline && strcmp(headerline, "-----BEGIN PGP MESSAGE-----")==0 );
assert( setupcodebegin == NULL ); assert( setupcodebegin == NULL );
@ -653,12 +653,12 @@ void stress_functions(mrmailbox_t* mailbox)
free(buf); free(buf);
buf = strdup("foo-----BEGIN PGP MESSAGE-----"); buf = strdup("foo-----BEGIN PGP MESSAGE-----");
ok = mr_split_armored_data(buf, &headerline, &setupcodebegin, NULL, &base64); ok = dc_split_armored_data(buf, &headerline, &setupcodebegin, NULL, &base64);
assert( ok == 0 ); assert( ok == 0 );
free(buf); free(buf);
buf = strdup("foo \n -----BEGIN PGP MESSAGE-----\n Passphrase-BeGIN : 23 \n \n base64-567 \r\n abc \n -----END PGP MESSAGE-----\n\n\n"); buf = strdup("foo \n -----BEGIN PGP MESSAGE-----\n Passphrase-BeGIN : 23 \n \n base64-567 \r\n abc \n -----END PGP MESSAGE-----\n\n\n");
ok = mr_split_armored_data(buf, &headerline, &setupcodebegin, NULL, &base64); ok = dc_split_armored_data(buf, &headerline, &setupcodebegin, NULL, &base64);
assert( ok == 1 ); assert( ok == 1 );
assert( headerline && strcmp(headerline, "-----BEGIN PGP MESSAGE-----")==0 ); assert( headerline && strcmp(headerline, "-----BEGIN PGP MESSAGE-----")==0 );
assert( setupcodebegin && strcmp(setupcodebegin, "23")==0 ); assert( setupcodebegin && strcmp(setupcodebegin, "23")==0 );
@ -666,7 +666,7 @@ void stress_functions(mrmailbox_t* mailbox)
free(buf); free(buf);
buf = strdup("-----BEGIN PGP PRIVATE KEY BLOCK-----\n Autocrypt-Prefer-Encrypt : mutual \n\nbase64\n-----END PGP PRIVATE KEY BLOCK-----"); buf = strdup("-----BEGIN PGP PRIVATE KEY BLOCK-----\n Autocrypt-Prefer-Encrypt : mutual \n\nbase64\n-----END PGP PRIVATE KEY BLOCK-----");
ok = mr_split_armored_data(buf, &headerline, NULL, &preferencrypt, &base64); ok = dc_split_armored_data(buf, &headerline, NULL, &preferencrypt, &base64);
assert( ok == 1 ); assert( ok == 1 );
assert( headerline && strcmp(headerline, "-----BEGIN PGP PRIVATE KEY BLOCK-----")==0 ); assert( headerline && strcmp(headerline, "-----BEGIN PGP PRIVATE KEY BLOCK-----")==0 );
assert( preferencrypt && strcmp(preferencrypt, "mutual")==0 ); assert( preferencrypt && strcmp(preferencrypt, "mutual")==0 );
@ -692,14 +692,14 @@ void stress_functions(mrmailbox_t* mailbox)
const char *headerline = NULL, *setupcodebegin = NULL, *preferencrypt = NULL; const char *headerline = NULL, *setupcodebegin = NULL, *preferencrypt = NULL;
buf = strdup(s_em_setupfile); buf = strdup(s_em_setupfile);
assert( mr_split_armored_data(buf, &headerline, &setupcodebegin, &preferencrypt, NULL) ); assert( dc_split_armored_data(buf, &headerline, &setupcodebegin, &preferencrypt, NULL) );
assert( headerline && strcmp(headerline, "-----BEGIN PGP MESSAGE-----")==0 ); assert( headerline && strcmp(headerline, "-----BEGIN PGP MESSAGE-----")==0 );
assert( setupcodebegin && strlen(setupcodebegin)<strlen(s_em_setupcode) && strncmp(setupcodebegin, s_em_setupcode, strlen(setupcodebegin))==0 ); assert( setupcodebegin && strlen(setupcodebegin)<strlen(s_em_setupcode) && strncmp(setupcodebegin, s_em_setupcode, strlen(setupcodebegin))==0 );
assert( preferencrypt==NULL ); assert( preferencrypt==NULL );
free(buf); free(buf);
assert( (buf=mrmailbox_decrypt_setup_file(mailbox, s_em_setupcode, s_em_setupfile)) != NULL ); assert( (buf=mrmailbox_decrypt_setup_file(mailbox, s_em_setupcode, s_em_setupfile)) != NULL );
assert( mr_split_armored_data(buf, &headerline, &setupcodebegin, &preferencrypt, NULL) ); assert( dc_split_armored_data(buf, &headerline, &setupcodebegin, &preferencrypt, NULL) );
assert( headerline && strcmp(headerline, "-----BEGIN PGP PRIVATE KEY BLOCK-----")==0 ); assert( headerline && strcmp(headerline, "-----BEGIN PGP PRIVATE KEY BLOCK-----")==0 );
assert( setupcodebegin==NULL ); assert( setupcodebegin==NULL );
assert( preferencrypt && strcmp(preferencrypt, "mutual")==0 ); assert( preferencrypt && strcmp(preferencrypt, "mutual")==0 );
@ -719,7 +719,7 @@ void stress_functions(mrmailbox_t* mailbox)
{ {
char *buf = safe_strdup(setupfile); char *buf = safe_strdup(setupfile);
const char *headerline = NULL, *setupcodebegin = NULL; const char *headerline = NULL, *setupcodebegin = NULL;
assert( mr_split_armored_data(buf, &headerline, &setupcodebegin, NULL, NULL) ); assert( dc_split_armored_data(buf, &headerline, &setupcodebegin, NULL, NULL) );
assert( headerline && strcmp(headerline, "-----BEGIN PGP MESSAGE-----")==0 ); assert( headerline && strcmp(headerline, "-----BEGIN PGP MESSAGE-----")==0 );
assert( setupcodebegin && strlen(setupcodebegin)==2 && strncmp(setupcodebegin, setupcode, 2)==0 ); assert( setupcodebegin && strlen(setupcodebegin)==2 && strncmp(setupcodebegin, setupcode, 2)==0 );
free(buf); free(buf);
@ -729,7 +729,7 @@ void stress_functions(mrmailbox_t* mailbox)
char *payload = NULL; char *payload = NULL;
const char *headerline = NULL; const char *headerline = NULL;
assert( (payload=mrmailbox_decrypt_setup_file(mailbox, setupcode, setupfile))!=NULL ); assert( (payload=mrmailbox_decrypt_setup_file(mailbox, setupcode, setupfile))!=NULL );
assert( mr_split_armored_data(payload, &headerline, NULL, NULL, NULL) ); assert( dc_split_armored_data(payload, &headerline, NULL, NULL, NULL) );
assert( headerline && strcmp(headerline, "-----BEGIN PGP PRIVATE KEY BLOCK-----")==0 ); assert( headerline && strcmp(headerline, "-----BEGIN PGP PRIVATE KEY BLOCK-----")==0 );
free(payload); free(payload);
} }
@ -742,140 +742,140 @@ void stress_functions(mrmailbox_t* mailbox)
**************************************************************************/ **************************************************************************/
{ {
mrkey_t *bad_key = mrkey_new(); dc_key_t *bad_key = dc_key_new();
#define BAD_DATA_BYTES 4096 #define BAD_DATA_BYTES 4096
unsigned char bad_data[BAD_DATA_BYTES]; unsigned char bad_data[BAD_DATA_BYTES];
for( int i = 0; i < BAD_DATA_BYTES; i++ ) { for( int i = 0; i < BAD_DATA_BYTES; i++ ) {
bad_data[i] = (unsigned char)(i&0xFF); bad_data[i] = (unsigned char)(i&0xFF);
} }
for( int j = 0; j < BAD_DATA_BYTES/40; j++ ) { for( int j = 0; j < BAD_DATA_BYTES/40; j++ ) {
mrkey_set_from_binary(bad_key, &bad_data[j], BAD_DATA_BYTES/2 + j, (j&1)? MR_PUBLIC : MR_PRIVATE); dc_key_set_from_binary(bad_key, &bad_data[j], BAD_DATA_BYTES/2 + j, (j&1)? MR_PUBLIC : MR_PRIVATE);
assert( !mrpgp_is_valid_key(mailbox, bad_key) ); assert( !dc_pgp_is_valid_key(mailbox, bad_key) );
} }
mrkey_unref(bad_key); dc_key_unref(bad_key);
} }
{ {
mrkey_t *public_key = mrkey_new(), *private_key = mrkey_new(); dc_key_t *public_key = dc_key_new(), *private_key = dc_key_new();
mrpgp_create_keypair(mailbox, "foo@bar.de", public_key, private_key); dc_pgp_create_keypair(mailbox, "foo@bar.de", public_key, private_key);
assert( mrpgp_is_valid_key(mailbox, public_key) ); assert( dc_pgp_is_valid_key(mailbox, public_key) );
assert( mrpgp_is_valid_key(mailbox, private_key) ); assert( dc_pgp_is_valid_key(mailbox, private_key) );
//{char *t1=mrkey_render_asc(public_key); printf("%s",t1);mr_write_file("/home/bpetersen/temp/stress-public.asc", t1,strlen(t1),mailbox);mr_write_file("/home/bpetersen/temp/stress-public.der", public_key->m_binary, public_key->m_bytes, mailbox);free(t1);} //{char *t1=mrkey_render_asc(public_key); printf("%s",t1);mr_write_file("/home/bpetersen/temp/stress-public.asc", t1,strlen(t1),mailbox);mr_write_file("/home/bpetersen/temp/stress-public.der", public_key->m_binary, public_key->m_bytes, mailbox);free(t1);}
//{char *t1=mrkey_render_asc(private_key);printf("%s",t1);mr_write_file("/home/bpetersen/temp/stress-private.asc",t1,strlen(t1),mailbox);mr_write_file("/home/bpetersen/temp/stress-private.der",private_key->m_binary,private_key->m_bytes,mailbox);free(t1);} //{char *t1=mrkey_render_asc(private_key);printf("%s",t1);mr_write_file("/home/bpetersen/temp/stress-private.asc",t1,strlen(t1),mailbox);mr_write_file("/home/bpetersen/temp/stress-private.der",private_key->m_binary,private_key->m_bytes,mailbox);free(t1);}
{ {
mrkey_t *test_key = mrkey_new(); dc_key_t *test_key = dc_key_new();
assert( mrpgp_split_key(mailbox, private_key, test_key) ); assert( dc_pgp_split_key(mailbox, private_key, test_key) );
//assert( mrkey_equals(public_key, test_key) ); //assert( mrkey_equals(public_key, test_key) );
mrkey_unref(test_key); dc_key_unref(test_key);
} }
mrkey_t *public_key2 = mrkey_new(), *private_key2 = mrkey_new(); dc_key_t *public_key2 = dc_key_new(), *private_key2 = dc_key_new();
mrpgp_create_keypair(mailbox, "two@zwo.de", public_key2, private_key2); dc_pgp_create_keypair(mailbox, "two@zwo.de", public_key2, private_key2);
assert( !mrkey_equals(public_key, public_key2) ); assert( !dc_key_equals(public_key, public_key2) );
const char* original_text = "This is a test"; const char* original_text = "This is a test";
void *ctext_signed = NULL, *ctext_unsigned = NULL; void *ctext_signed = NULL, *ctext_unsigned = NULL;
size_t ctext_signed_bytes = 0, ctext_unsigned_bytes, plain_bytes = 0; size_t ctext_signed_bytes = 0, ctext_unsigned_bytes, plain_bytes = 0;
{ {
mrkeyring_t* keyring = mrkeyring_new(); dc_keyring_t* keyring = dc_keyring_new();
mrkeyring_add(keyring, public_key); dc_keyring_add(keyring, public_key);
mrkeyring_add(keyring, public_key2); dc_keyring_add(keyring, public_key2);
int ok = mrpgp_pk_encrypt(mailbox, original_text, strlen(original_text), keyring, private_key, 1, (void**)&ctext_signed, &ctext_signed_bytes); int ok = dc_pgp_pk_encrypt(mailbox, original_text, strlen(original_text), keyring, private_key, 1, (void**)&ctext_signed, &ctext_signed_bytes);
assert( ok && ctext_signed && ctext_signed_bytes>0 ); assert( ok && ctext_signed && ctext_signed_bytes>0 );
assert( strncmp((char*)ctext_signed, "-----BEGIN PGP MESSAGE-----", 27)==0 ); assert( strncmp((char*)ctext_signed, "-----BEGIN PGP MESSAGE-----", 27)==0 );
assert( ((char*)ctext_signed)[ctext_signed_bytes-1]!=0 ); /*armored strings are not null-terminated!*/ assert( ((char*)ctext_signed)[ctext_signed_bytes-1]!=0 ); /*armored strings are not null-terminated!*/
//{char* t3 = mr_null_terminate((char*)ctext,ctext_bytes);printf("\n%i ENCRYPTED BYTES: {\n%s\n}\n",(int)ctext_bytes,t3);free(t3);} //{char* t3 = mr_null_terminate((char*)ctext,ctext_bytes);printf("\n%i ENCRYPTED BYTES: {\n%s\n}\n",(int)ctext_bytes,t3);free(t3);}
ok = mrpgp_pk_encrypt(mailbox, original_text, strlen(original_text), keyring, NULL, 1, (void**)&ctext_unsigned, &ctext_unsigned_bytes); ok = dc_pgp_pk_encrypt(mailbox, original_text, strlen(original_text), keyring, NULL, 1, (void**)&ctext_unsigned, &ctext_unsigned_bytes);
assert( ok && ctext_unsigned && ctext_unsigned_bytes>0 ); assert( ok && ctext_unsigned && ctext_unsigned_bytes>0 );
assert( strncmp((char*)ctext_unsigned, "-----BEGIN PGP MESSAGE-----", 27)==0 ); assert( strncmp((char*)ctext_unsigned, "-----BEGIN PGP MESSAGE-----", 27)==0 );
assert( ctext_unsigned_bytes < ctext_signed_bytes ); assert( ctext_unsigned_bytes < ctext_signed_bytes );
mrkeyring_unref(keyring); dc_keyring_unref(keyring);
} }
{ {
mrkeyring_t* keyring = mrkeyring_new(); dc_keyring_t* keyring = dc_keyring_new();
mrkeyring_add(keyring, private_key); dc_keyring_add(keyring, private_key);
mrkeyring_t* public_keyring = mrkeyring_new(); dc_keyring_t* public_keyring = dc_keyring_new();
mrkeyring_add(public_keyring, public_key); dc_keyring_add(public_keyring, public_key);
mrkeyring_t* public_keyring2 = mrkeyring_new(); dc_keyring_t* public_keyring2 = dc_keyring_new();
mrkeyring_add(public_keyring2, public_key2); dc_keyring_add(public_keyring2, public_key2);
void* plain = NULL; void* plain = NULL;
mrhash_t valid_signatures; dc_hash_t valid_signatures;
mrhash_init(&valid_signatures, MRHASH_STRING, 1/*copy key*/); dc_hash_init(&valid_signatures, MRHASH_STRING, 1/*copy key*/);
int ok; int ok;
ok = mrpgp_pk_decrypt(mailbox, ctext_signed, ctext_signed_bytes, keyring, public_keyring/*for validate*/, 1, &plain, &plain_bytes, &valid_signatures); ok = dc_pgp_pk_decrypt(mailbox, ctext_signed, ctext_signed_bytes, keyring, public_keyring/*for validate*/, 1, &plain, &plain_bytes, &valid_signatures);
assert( ok && plain && plain_bytes>0 ); assert( ok && plain && plain_bytes>0 );
assert( strncmp((char*)plain, original_text, strlen(original_text))==0 ); assert( strncmp((char*)plain, original_text, strlen(original_text))==0 );
assert( mrhash_count(&valid_signatures) == 1 ); assert( dc_hash_count(&valid_signatures) == 1 );
free(plain); plain = NULL; free(plain); plain = NULL;
mrhash_clear(&valid_signatures); dc_hash_clear(&valid_signatures);
ok = mrpgp_pk_decrypt(mailbox, ctext_signed, ctext_signed_bytes, keyring, NULL/*for validate*/, 1, &plain, &plain_bytes, &valid_signatures); ok = dc_pgp_pk_decrypt(mailbox, ctext_signed, ctext_signed_bytes, keyring, NULL/*for validate*/, 1, &plain, &plain_bytes, &valid_signatures);
assert( ok && plain && plain_bytes>0 ); assert( ok && plain && plain_bytes>0 );
assert( strncmp((char*)plain, original_text, strlen(original_text))==0 ); assert( strncmp((char*)plain, original_text, strlen(original_text))==0 );
assert( mrhash_count(&valid_signatures) == 0 ); assert( dc_hash_count(&valid_signatures) == 0 );
free(plain); plain = NULL; free(plain); plain = NULL;
mrhash_clear(&valid_signatures); dc_hash_clear(&valid_signatures);
ok = mrpgp_pk_decrypt(mailbox, ctext_signed, ctext_signed_bytes, keyring, public_keyring2/*for validate*/, 1, &plain, &plain_bytes, &valid_signatures); ok = dc_pgp_pk_decrypt(mailbox, ctext_signed, ctext_signed_bytes, keyring, public_keyring2/*for validate*/, 1, &plain, &plain_bytes, &valid_signatures);
assert( ok && plain && plain_bytes>0 ); assert( ok && plain && plain_bytes>0 );
assert( strncmp((char*)plain, original_text, strlen(original_text))==0 ); assert( strncmp((char*)plain, original_text, strlen(original_text))==0 );
assert( mrhash_count(&valid_signatures) == 0 ); assert( dc_hash_count(&valid_signatures) == 0 );
free(plain); plain = NULL; free(plain); plain = NULL;
mrhash_clear(&valid_signatures); dc_hash_clear(&valid_signatures);
mrkeyring_add(public_keyring2, public_key); dc_keyring_add(public_keyring2, public_key);
ok = mrpgp_pk_decrypt(mailbox, ctext_signed, ctext_signed_bytes, keyring, public_keyring2/*for validate*/, 1, &plain, &plain_bytes, &valid_signatures); ok = dc_pgp_pk_decrypt(mailbox, ctext_signed, ctext_signed_bytes, keyring, public_keyring2/*for validate*/, 1, &plain, &plain_bytes, &valid_signatures);
assert( ok && plain && plain_bytes>0 ); assert( ok && plain && plain_bytes>0 );
assert( strncmp((char*)plain, original_text, strlen(original_text))==0 ); assert( strncmp((char*)plain, original_text, strlen(original_text))==0 );
assert( mrhash_count(&valid_signatures) == 1 ); assert( dc_hash_count(&valid_signatures) == 1 );
free(plain); plain = NULL; free(plain); plain = NULL;
mrhash_clear(&valid_signatures); dc_hash_clear(&valid_signatures);
ok = mrpgp_pk_decrypt(mailbox, ctext_unsigned, ctext_unsigned_bytes, keyring, public_keyring/*for validate*/, 1, &plain, &plain_bytes, &valid_signatures); ok = dc_pgp_pk_decrypt(mailbox, ctext_unsigned, ctext_unsigned_bytes, keyring, public_keyring/*for validate*/, 1, &plain, &plain_bytes, &valid_signatures);
assert( ok && plain && plain_bytes>0 ); assert( ok && plain && plain_bytes>0 );
assert( strncmp((char*)plain, original_text, strlen(original_text))==0 ); assert( strncmp((char*)plain, original_text, strlen(original_text))==0 );
assert( mrhash_count(&valid_signatures) == 0 ); assert( dc_hash_count(&valid_signatures) == 0 );
free(plain); plain = NULL; free(plain); plain = NULL;
mrhash_clear(&valid_signatures); dc_hash_clear(&valid_signatures);
mrkeyring_unref(keyring); dc_keyring_unref(keyring);
mrkeyring_unref(public_keyring); dc_keyring_unref(public_keyring);
mrkeyring_unref(public_keyring2); dc_keyring_unref(public_keyring2);
} }
{ {
mrkeyring_t* keyring = mrkeyring_new(); dc_keyring_t* keyring = dc_keyring_new();
mrkeyring_add(keyring, private_key2); dc_keyring_add(keyring, private_key2);
mrkeyring_t* public_keyring = mrkeyring_new(); dc_keyring_t* public_keyring = dc_keyring_new();
mrkeyring_add(public_keyring, public_key); dc_keyring_add(public_keyring, public_key);
void* plain = NULL; void* plain = NULL;
int ok = mrpgp_pk_decrypt(mailbox, ctext_signed, ctext_signed_bytes, keyring, public_keyring/*for validate*/, 1, &plain, &plain_bytes, NULL); int ok = dc_pgp_pk_decrypt(mailbox, ctext_signed, ctext_signed_bytes, keyring, public_keyring/*for validate*/, 1, &plain, &plain_bytes, NULL);
assert( ok && plain && plain_bytes>0 ); assert( ok && plain && plain_bytes>0 );
assert( strcmp(plain, original_text)==0 ); assert( strcmp(plain, original_text)==0 );
free(plain); free(plain);
mrkeyring_unref(keyring); dc_keyring_unref(keyring);
mrkeyring_unref(public_keyring); dc_keyring_unref(public_keyring);
} }
free(ctext_signed); free(ctext_signed);
free(ctext_unsigned); free(ctext_unsigned);
mrkey_unref(public_key2); dc_key_unref(public_key2);
mrkey_unref(private_key2); dc_key_unref(private_key2);
mrkey_unref(public_key); dc_key_unref(public_key);
mrkey_unref(private_key); dc_key_unref(private_key);
} }

View file

@ -48,8 +48,8 @@ void dc_aheader_empty(dc_aheader_t* ths)
ths->m_addr = NULL; ths->m_addr = NULL;
if( ths->m_public_key->m_binary ) { if( ths->m_public_key->m_binary ) {
mrkey_unref(ths->m_public_key); dc_key_unref(ths->m_public_key);
ths->m_public_key = mrkey_new(); ths->m_public_key = dc_key_new();
} }
} }
@ -85,7 +85,7 @@ char* dc_aheader_render(const dc_aheader_t* ths)
/* adds a whitespace every 78 characters, this allows libEtPan to wrap the lines according to RFC 5322 /* adds a whitespace every 78 characters, this allows libEtPan to wrap the lines according to RFC 5322
(which may insert a linebreak before every whitespace) */ (which may insert a linebreak before every whitespace) */
if( (keybase64_wrapped = mrkey_render_base64(ths->m_public_key, 78, " ", 0/*no checksum*/)) == NULL ) { if( (keybase64_wrapped = dc_key_render_base64(ths->m_public_key, 78, " ", 0/*no checksum*/)) == NULL ) {
goto cleanup; goto cleanup;
} }
@ -144,7 +144,7 @@ static int add_attribute(dc_aheader_t* ths, const char* name, const char* value
|| ths->m_public_key->m_binary || ths->m_public_key->m_bytes ) { || ths->m_public_key->m_binary || ths->m_public_key->m_bytes ) {
return 0; /* there is already a k*/ return 0; /* there is already a k*/
} }
return mrkey_set_from_base64(ths->m_public_key, value, MR_PUBLIC); return dc_key_set_from_base64(ths->m_public_key, value, MR_PUBLIC);
} }
else if( name[0]=='_' ) else if( name[0]=='_' )
{ {
@ -245,7 +245,7 @@ dc_aheader_t* dc_aheader_new()
exit(37); /* cannot allocate little memory, unrecoverable error */ exit(37); /* cannot allocate little memory, unrecoverable error */
} }
ths->m_public_key = mrkey_new(); ths->m_public_key = dc_key_new();
return ths; return ths;
} }
@ -261,7 +261,7 @@ void dc_aheader_unref(dc_aheader_t* ths)
} }
free(ths->m_addr); free(ths->m_addr);
mrkey_unref(ths->m_public_key); dc_key_unref(ths->m_public_key);
free(ths); free(ths);
} }

View file

@ -36,7 +36,7 @@ extern "C" {
typedef struct dc_aheader_t typedef struct dc_aheader_t
{ {
char* m_addr; char* m_addr;
mrkey_t* m_public_key; /* != NULL */ dc_key_t* m_public_key; /* != NULL */
int m_prefer_encrypt; /* YES, NO or NOPREFERENCE if attribute is missing */ int m_prefer_encrypt; /* YES, NO or NOPREFERENCE if attribute is missing */
} dc_aheader_t; } dc_aheader_t;

View file

@ -55,19 +55,19 @@ static void dc_apeerstate_empty(dc_apeerstate_t* ths)
ths->m_verified_key_fingerprint = NULL; ths->m_verified_key_fingerprint = NULL;
if( ths->m_public_key ) { if( ths->m_public_key ) {
mrkey_unref(ths->m_public_key); dc_key_unref(ths->m_public_key);
ths->m_public_key = NULL; ths->m_public_key = NULL;
} }
ths->m_gossip_timestamp = 0; ths->m_gossip_timestamp = 0;
if( ths->m_gossip_key ) { if( ths->m_gossip_key ) {
mrkey_unref(ths->m_gossip_key); dc_key_unref(ths->m_gossip_key);
ths->m_gossip_key = NULL; ths->m_gossip_key = NULL;
} }
if( ths->m_verified_key ) { if( ths->m_verified_key ) {
mrkey_unref(ths->m_verified_key); dc_key_unref(ths->m_verified_key);
ths->m_verified_key = NULL; ths->m_verified_key = NULL;
} }
@ -91,23 +91,23 @@ static void dc_apeerstate_set_from_stmt__(dc_apeerstate_t* peerstate, sqlite3_st
peerstate->m_verified_key_fingerprint = safe_strdup((char*)sqlite3_column_text(stmt, 10)); peerstate->m_verified_key_fingerprint = safe_strdup((char*)sqlite3_column_text(stmt, 10));
if( sqlite3_column_type(stmt, PUBLIC_KEY_COL)!=SQLITE_NULL ) { if( sqlite3_column_type(stmt, PUBLIC_KEY_COL)!=SQLITE_NULL ) {
peerstate->m_public_key = mrkey_new(); peerstate->m_public_key = dc_key_new();
mrkey_set_from_stmt(peerstate->m_public_key, stmt, PUBLIC_KEY_COL, MR_PUBLIC); dc_key_set_from_stmt(peerstate->m_public_key, stmt, PUBLIC_KEY_COL, MR_PUBLIC);
} }
if( sqlite3_column_type(stmt, GOSSIP_KEY_COL)!=SQLITE_NULL ) { if( sqlite3_column_type(stmt, GOSSIP_KEY_COL)!=SQLITE_NULL ) {
peerstate->m_gossip_key = mrkey_new(); peerstate->m_gossip_key = dc_key_new();
mrkey_set_from_stmt(peerstate->m_gossip_key, stmt, GOSSIP_KEY_COL, MR_PUBLIC); dc_key_set_from_stmt(peerstate->m_gossip_key, stmt, GOSSIP_KEY_COL, MR_PUBLIC);
} }
if( sqlite3_column_type(stmt, VERIFIED_KEY_COL)!=SQLITE_NULL ) { if( sqlite3_column_type(stmt, VERIFIED_KEY_COL)!=SQLITE_NULL ) {
peerstate->m_verified_key = mrkey_new(); peerstate->m_verified_key = dc_key_new();
mrkey_set_from_stmt(peerstate->m_verified_key, stmt, VERIFIED_KEY_COL, MR_PUBLIC); dc_key_set_from_stmt(peerstate->m_verified_key, stmt, VERIFIED_KEY_COL, MR_PUBLIC);
} }
} }
int dc_apeerstate_load_by_addr__(dc_apeerstate_t* peerstate, mrsqlite3_t* sql, const char* addr) int dc_apeerstate_load_by_addr__(dc_apeerstate_t* peerstate, dc_sqlite3_t* sql, const char* addr)
{ {
int success = 0; int success = 0;
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
@ -118,7 +118,7 @@ int dc_apeerstate_load_by_addr__(dc_apeerstate_t* peerstate, mrsqlite3_t* sql, c
dc_apeerstate_empty(peerstate); dc_apeerstate_empty(peerstate);
stmt = mrsqlite3_predefine__(sql, SELECT_fields_FROM_acpeerstates_WHERE_addr, stmt = dc_sqlite3_predefine__(sql, SELECT_fields_FROM_acpeerstates_WHERE_addr,
"SELECT " PEERSTATE_FIELDS "SELECT " PEERSTATE_FIELDS
" FROM acpeerstates " " FROM acpeerstates "
" WHERE addr=? COLLATE NOCASE;"); " WHERE addr=? COLLATE NOCASE;");
@ -135,7 +135,7 @@ cleanup:
} }
int dc_apeerstate_load_by_fingerprint__(dc_apeerstate_t* peerstate, mrsqlite3_t* sql, const char* fingerprint) int dc_apeerstate_load_by_fingerprint__(dc_apeerstate_t* peerstate, dc_sqlite3_t* sql, const char* fingerprint)
{ {
int success = 0; int success = 0;
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
@ -146,7 +146,7 @@ int dc_apeerstate_load_by_fingerprint__(dc_apeerstate_t* peerstate, mrsqlite3_t*
dc_apeerstate_empty(peerstate); dc_apeerstate_empty(peerstate);
stmt = mrsqlite3_predefine__(sql, SELECT_fields_FROM_acpeerstates_WHERE_fingerprint, stmt = dc_sqlite3_predefine__(sql, SELECT_fields_FROM_acpeerstates_WHERE_fingerprint,
"SELECT " PEERSTATE_FIELDS "SELECT " PEERSTATE_FIELDS
" FROM acpeerstates " " FROM acpeerstates "
" WHERE public_key_fingerprint=? COLLATE NOCASE " " WHERE public_key_fingerprint=? COLLATE NOCASE "
@ -167,7 +167,7 @@ cleanup:
} }
int dc_apeerstate_save_to_db__(const dc_apeerstate_t* ths, mrsqlite3_t* sql, int create) int dc_apeerstate_save_to_db__(const dc_apeerstate_t* ths, dc_sqlite3_t* sql, int create)
{ {
int success = 0; int success = 0;
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
@ -177,14 +177,14 @@ int dc_apeerstate_save_to_db__(const dc_apeerstate_t* ths, mrsqlite3_t* sql, int
} }
if( create ) { if( create ) {
stmt = mrsqlite3_predefine__(sql, INSERT_INTO_acpeerstates_a, "INSERT INTO acpeerstates (addr) VALUES(?);"); stmt = dc_sqlite3_predefine__(sql, INSERT_INTO_acpeerstates_a, "INSERT INTO acpeerstates (addr) VALUES(?);");
sqlite3_bind_text(stmt, 1, ths->m_addr, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 1, ths->m_addr, -1, SQLITE_STATIC);
sqlite3_step(stmt); sqlite3_step(stmt);
} }
if( (ths->m_to_save&MRA_SAVE_ALL) || create ) if( (ths->m_to_save&MRA_SAVE_ALL) || create )
{ {
stmt = mrsqlite3_predefine__(sql, UPDATE_acpeerstates_SET_lcpp_WHERE_a, stmt = dc_sqlite3_predefine__(sql, UPDATE_acpeerstates_SET_lcpp_WHERE_a,
"UPDATE acpeerstates " "UPDATE acpeerstates "
" SET last_seen=?, last_seen_autocrypt=?, prefer_encrypted=?, " " SET last_seen=?, last_seen_autocrypt=?, prefer_encrypted=?, "
" public_key=?, gossip_timestamp=?, gossip_key=?, public_key_fingerprint=?, gossip_key_fingerprint=?, verified_key=?, verified_key_fingerprint=? " " public_key=?, gossip_timestamp=?, gossip_key=?, public_key_fingerprint=?, gossip_key_fingerprint=?, verified_key=?, verified_key_fingerprint=? "
@ -206,7 +206,7 @@ int dc_apeerstate_save_to_db__(const dc_apeerstate_t* ths, mrsqlite3_t* sql, int
} }
else if( ths->m_to_save&MRA_SAVE_TIMESTAMPS ) else if( ths->m_to_save&MRA_SAVE_TIMESTAMPS )
{ {
stmt = mrsqlite3_predefine__(sql, UPDATE_acpeerstates_SET_l_WHERE_a, stmt = dc_sqlite3_predefine__(sql, UPDATE_acpeerstates_SET_l_WHERE_a,
"UPDATE acpeerstates SET last_seen=?, last_seen_autocrypt=?, gossip_timestamp=? WHERE addr=?;"); "UPDATE acpeerstates SET last_seen=?, last_seen_autocrypt=?, gossip_timestamp=? WHERE addr=?;");
sqlite3_bind_int64(stmt, 1, ths->m_last_seen); sqlite3_bind_int64(stmt, 1, ths->m_last_seen);
sqlite3_bind_int64(stmt, 2, ths->m_last_seen_autocrypt); sqlite3_bind_int64(stmt, 2, ths->m_last_seen_autocrypt);
@ -250,8 +250,8 @@ void dc_apeerstate_unref(dc_apeerstate_t* ths)
} }
free(ths->m_addr); free(ths->m_addr);
mrkey_unref(ths->m_public_key); dc_key_unref(ths->m_public_key);
mrkey_unref(ths->m_gossip_key); dc_key_unref(ths->m_gossip_key);
free(ths); free(ths);
} }
@ -279,7 +279,7 @@ char* dc_apeerstate_render_gossip_header(const dc_apeerstate_t* peerstate, int m
autocryptheader->m_prefer_encrypt = MRA_PE_NOPREFERENCE; /* the spec says, we SHOULD NOT gossip this flag */ autocryptheader->m_prefer_encrypt = MRA_PE_NOPREFERENCE; /* the spec says, we SHOULD NOT gossip this flag */
autocryptheader->m_addr = safe_strdup(peerstate->m_addr); autocryptheader->m_addr = safe_strdup(peerstate->m_addr);
autocryptheader->m_public_key = mrkey_ref(dc_apeerstate_peek_key(peerstate, min_verified)); /* may be NULL */ autocryptheader->m_public_key = dc_key_ref(dc_apeerstate_peek_key(peerstate, min_verified)); /* may be NULL */
ret = dc_aheader_render(autocryptheader); ret = dc_aheader_render(autocryptheader);
@ -307,7 +307,7 @@ cleanup:
* @return m_public_key or m_gossip_key, NULL if nothing is available. * @return m_public_key or m_gossip_key, NULL if nothing is available.
* the returned pointer MUST NOT be unref()'d. * the returned pointer MUST NOT be unref()'d.
*/ */
mrkey_t* dc_apeerstate_peek_key(const dc_apeerstate_t* peerstate, int min_verified) dc_key_t* dc_apeerstate_peek_key(const dc_apeerstate_t* peerstate, int min_verified)
{ {
if( peerstate == NULL if( peerstate == NULL
|| (peerstate->m_public_key && (peerstate->m_public_key->m_binary==NULL || peerstate->m_public_key->m_bytes<=0)) || (peerstate->m_public_key && (peerstate->m_public_key->m_binary==NULL || peerstate->m_public_key->m_bytes<=0))
@ -348,8 +348,8 @@ int dc_apeerstate_init_from_header(dc_apeerstate_t* ths, const dc_aheader_t* hea
ths->m_to_save = MRA_SAVE_ALL; ths->m_to_save = MRA_SAVE_ALL;
ths->m_prefer_encrypt = header->m_prefer_encrypt; ths->m_prefer_encrypt = header->m_prefer_encrypt;
ths->m_public_key = mrkey_new(); ths->m_public_key = dc_key_new();
mrkey_set_from_key(ths->m_public_key, header->m_public_key); dc_key_set_from_key(ths->m_public_key, header->m_public_key);
dc_apeerstate_recalc_fingerprint(ths); dc_apeerstate_recalc_fingerprint(ths);
return 1; return 1;
@ -367,8 +367,8 @@ int dc_apeerstate_init_from_gossip(dc_apeerstate_t* peerstate, const dc_aheader_
peerstate->m_gossip_timestamp = message_time; peerstate->m_gossip_timestamp = message_time;
peerstate->m_to_save = MRA_SAVE_ALL; peerstate->m_to_save = MRA_SAVE_ALL;
peerstate->m_gossip_key = mrkey_new(); peerstate->m_gossip_key = dc_key_new();
mrkey_set_from_key(peerstate->m_gossip_key, gossip_header->m_public_key); dc_key_set_from_key(peerstate->m_gossip_key, gossip_header->m_public_key);
dc_apeerstate_recalc_fingerprint(peerstate); dc_apeerstate_recalc_fingerprint(peerstate);
return 1; return 1;
@ -420,12 +420,12 @@ void dc_apeerstate_apply_header(dc_apeerstate_t* ths, const dc_aheader_t* header
} }
if( ths->m_public_key == NULL ) { if( ths->m_public_key == NULL ) {
ths->m_public_key = mrkey_new(); ths->m_public_key = dc_key_new();
} }
if( !mrkey_equals(ths->m_public_key, header->m_public_key) ) if( !dc_key_equals(ths->m_public_key, header->m_public_key) )
{ {
mrkey_set_from_key(ths->m_public_key, header->m_public_key); dc_key_set_from_key(ths->m_public_key, header->m_public_key);
dc_apeerstate_recalc_fingerprint(ths); dc_apeerstate_recalc_fingerprint(ths);
ths->m_to_save |= MRA_SAVE_ALL; ths->m_to_save |= MRA_SAVE_ALL;
} }
@ -448,12 +448,12 @@ void dc_apeerstate_apply_gossip(dc_apeerstate_t* peerstate, const dc_aheader_t*
peerstate->m_to_save |= MRA_SAVE_TIMESTAMPS; peerstate->m_to_save |= MRA_SAVE_TIMESTAMPS;
if( peerstate->m_gossip_key == NULL ) { if( peerstate->m_gossip_key == NULL ) {
peerstate->m_gossip_key = mrkey_new(); peerstate->m_gossip_key = dc_key_new();
} }
if( !mrkey_equals(peerstate->m_gossip_key, gossip_header->m_public_key) ) if( !dc_key_equals(peerstate->m_gossip_key, gossip_header->m_public_key) )
{ {
mrkey_set_from_key(peerstate->m_gossip_key, gossip_header->m_public_key); dc_key_set_from_key(peerstate->m_gossip_key, gossip_header->m_public_key);
dc_apeerstate_recalc_fingerprint(peerstate); dc_apeerstate_recalc_fingerprint(peerstate);
peerstate->m_to_save |= MRA_SAVE_ALL; peerstate->m_to_save |= MRA_SAVE_ALL;
} }
@ -482,7 +482,7 @@ int dc_apeerstate_recalc_fingerprint(dc_apeerstate_t* peerstate)
if( peerstate->m_public_key ) if( peerstate->m_public_key )
{ {
old_public_fingerprint = peerstate->m_public_key_fingerprint; old_public_fingerprint = peerstate->m_public_key_fingerprint;
peerstate->m_public_key_fingerprint = mrkey_get_fingerprint(peerstate->m_public_key); /* returns the empty string for errors, however, this should be saved as well as it represents an erroneous key */ peerstate->m_public_key_fingerprint = dc_key_get_fingerprint(peerstate->m_public_key); /* returns the empty string for errors, however, this should be saved as well as it represents an erroneous key */
if( old_public_fingerprint == NULL if( old_public_fingerprint == NULL
|| old_public_fingerprint[0] == 0 || old_public_fingerprint[0] == 0
@ -501,7 +501,7 @@ int dc_apeerstate_recalc_fingerprint(dc_apeerstate_t* peerstate)
if( peerstate->m_gossip_key ) if( peerstate->m_gossip_key )
{ {
old_gossip_fingerprint = peerstate->m_gossip_key_fingerprint; old_gossip_fingerprint = peerstate->m_gossip_key_fingerprint;
peerstate->m_gossip_key_fingerprint = mrkey_get_fingerprint(peerstate->m_gossip_key); /* returns the empty string for errors, however, this should be saved as well as it represents an erroneous key */ peerstate->m_gossip_key_fingerprint = dc_key_get_fingerprint(peerstate->m_gossip_key); /* returns the empty string for errors, however, this should be saved as well as it represents an erroneous key */
if( old_gossip_fingerprint == NULL if( old_gossip_fingerprint == NULL
|| old_gossip_fingerprint[0] == 0 || old_gossip_fingerprint[0] == 0
@ -563,7 +563,7 @@ int dc_apeerstate_set_verified(dc_apeerstate_t* peerstate, int which_key, const
&& strcasecmp(peerstate->m_public_key_fingerprint, fingerprint) == 0 ) && strcasecmp(peerstate->m_public_key_fingerprint, fingerprint) == 0 )
{ {
peerstate->m_to_save |= MRA_SAVE_ALL; peerstate->m_to_save |= MRA_SAVE_ALL;
peerstate->m_verified_key = mrkey_ref(peerstate->m_public_key); peerstate->m_verified_key = dc_key_ref(peerstate->m_public_key);
peerstate->m_verified_key_fingerprint = safe_strdup(peerstate->m_public_key_fingerprint); peerstate->m_verified_key_fingerprint = safe_strdup(peerstate->m_public_key_fingerprint);
success = 1; success = 1;
} }
@ -575,7 +575,7 @@ int dc_apeerstate_set_verified(dc_apeerstate_t* peerstate, int which_key, const
&& strcasecmp(peerstate->m_gossip_key_fingerprint, fingerprint) == 0 ) && strcasecmp(peerstate->m_gossip_key_fingerprint, fingerprint) == 0 )
{ {
peerstate->m_to_save |= MRA_SAVE_ALL; peerstate->m_to_save |= MRA_SAVE_ALL;
peerstate->m_verified_key = mrkey_ref(peerstate->m_gossip_key); peerstate->m_verified_key = dc_key_ref(peerstate->m_gossip_key);
peerstate->m_verified_key_fingerprint = safe_strdup(peerstate->m_gossip_key_fingerprint); peerstate->m_verified_key_fingerprint = safe_strdup(peerstate->m_gossip_key_fingerprint);
success = 1; success = 1;
} }
@ -585,7 +585,7 @@ cleanup:
} }
int dc_apeerstate_has_verified_key(const dc_apeerstate_t* peerstate, const mrhash_t* fingerprints) int dc_apeerstate_has_verified_key(const dc_apeerstate_t* peerstate, const dc_hash_t* fingerprints)
{ {
if( peerstate == NULL || fingerprints == NULL ) { if( peerstate == NULL || fingerprints == NULL ) {
return 0; return 0;
@ -593,7 +593,7 @@ int dc_apeerstate_has_verified_key(const dc_apeerstate_t* peerstate, const mrhas
if( peerstate->m_verified_key if( peerstate->m_verified_key
&& peerstate->m_verified_key_fingerprint && peerstate->m_verified_key_fingerprint
&& mrhash_find_str(fingerprints, peerstate->m_verified_key_fingerprint) ) { && dc_hash_find_str(fingerprints, peerstate->m_verified_key_fingerprint) ) {
return 1; return 1;
} }

View file

@ -55,14 +55,14 @@ typedef struct dc_apeerstate_t
#define MRV_NOT_VERIFIED 0 #define MRV_NOT_VERIFIED 0
#define MRV_BIDIRECTIONAL 2 #define MRV_BIDIRECTIONAL 2
mrkey_t* m_public_key; /* may be NULL, however, in the database, either public_key or gossip_key is set */ dc_key_t* m_public_key; /* may be NULL, however, in the database, either public_key or gossip_key is set */
char* m_public_key_fingerprint; char* m_public_key_fingerprint;
mrkey_t* m_gossip_key; /* may be NULL */ dc_key_t* m_gossip_key; /* may be NULL */
time_t m_gossip_timestamp; time_t m_gossip_timestamp;
char* m_gossip_key_fingerprint; char* m_gossip_key_fingerprint;
mrkey_t* m_verified_key; // may be NULL dc_key_t* m_verified_key; // may be NULL
char* m_verified_key_fingerprint; char* m_verified_key_fingerprint;
#define MRA_SAVE_TIMESTAMPS 0x01 #define MRA_SAVE_TIMESTAMPS 0x01
@ -89,7 +89,7 @@ void dc_apeerstate_apply_gossip (dc_apeerstate_t*, const dc_a
char* dc_apeerstate_render_gossip_header (const dc_apeerstate_t*, int min_verified); char* dc_apeerstate_render_gossip_header (const dc_apeerstate_t*, int min_verified);
mrkey_t* dc_apeerstate_peek_key (const dc_apeerstate_t*, int min_verified); dc_key_t* dc_apeerstate_peek_key (const dc_apeerstate_t*, int min_verified);
int dc_apeerstate_recalc_fingerprint (dc_apeerstate_t*); int dc_apeerstate_recalc_fingerprint (dc_apeerstate_t*);
@ -97,11 +97,11 @@ int dc_apeerstate_recalc_fingerprint (dc_apeerstate_t*);
#define MRA_PUBLIC_KEY 1 #define MRA_PUBLIC_KEY 1
int dc_apeerstate_set_verified (dc_apeerstate_t*, int which_key, const char* fingerprint, int verfied); int dc_apeerstate_set_verified (dc_apeerstate_t*, int which_key, const char* fingerprint, int verfied);
int dc_apeerstate_load_by_addr__ (dc_apeerstate_t*, mrsqlite3_t*, const char* addr); int dc_apeerstate_load_by_addr__ (dc_apeerstate_t*, dc_sqlite3_t*, const char* addr);
int dc_apeerstate_load_by_fingerprint__(dc_apeerstate_t*, mrsqlite3_t*, const char* fingerprint); int dc_apeerstate_load_by_fingerprint__(dc_apeerstate_t*, dc_sqlite3_t*, const char* fingerprint);
int dc_apeerstate_save_to_db__ (const dc_apeerstate_t*, mrsqlite3_t*, int create); int dc_apeerstate_save_to_db__ (const dc_apeerstate_t*, dc_sqlite3_t*, int create);
int dc_apeerstate_has_verified_key (const dc_apeerstate_t*, const mrhash_t* fingerprints); int dc_apeerstate_has_verified_key (const dc_apeerstate_t*, const dc_hash_t* fingerprints);
#ifdef __cplusplus #ifdef __cplusplus
} /* /extern "C" */ } /* /extern "C" */

View file

@ -38,9 +38,9 @@
*/ */
dc_array_t* dc_array_new(dc_context_t* mailbox, size_t initsize) dc_array_t* dc_array_new(dc_context_t* mailbox, size_t initsize)
{ {
mrarray_t* array; dc_array_t* array;
array = (mrarray_t*) malloc(sizeof(mrarray_t)); array = (dc_array_t*) malloc(sizeof(dc_array_t));
if( array==NULL ) { if( array==NULL ) {
exit(47); exit(47);
} }
@ -91,7 +91,7 @@ void dc_array_unref(dc_array_t* array)
* @return None. * @return None.
* *
*/ */
void mrarray_free_ptr(dc_array_t* array) void dc_array_free_ptr(dc_array_t* array)
{ {
size_t i; size_t i;
@ -117,15 +117,15 @@ void mrarray_free_ptr(dc_array_t* array)
* @return The duplicated array. * @return The duplicated array.
* *
*/ */
mrarray_t* mrarray_duplicate(const dc_array_t* array) dc_array_t* dc_array_duplicate(const dc_array_t* array)
{ {
mrarray_t* ret = NULL; dc_array_t* ret = NULL;
if( array==NULL || array->m_magic != MR_ARRAY_MAGIC ) { if( array==NULL || array->m_magic != MR_ARRAY_MAGIC ) {
return NULL; return NULL;
} }
ret = mrarray_new(array->m_mailbox, array->m_allocated); ret = dc_array_new(array->m_mailbox, array->m_allocated);
ret->m_count = array->m_count; ret->m_count = array->m_count;
memcpy(ret->m_array, array->m_array, array->m_count * sizeof(uintptr_t)); memcpy(ret->m_array, array->m_array, array->m_count * sizeof(uintptr_t));
@ -150,7 +150,7 @@ static int cmp_intptr_t(const void* p1, const void* p2)
* @return The duplicated array. * @return The duplicated array.
* *
*/ */
void mrarray_sort_ids(dc_array_t* array) void dc_array_sort_ids(dc_array_t* array)
{ {
if( array == NULL || array->m_magic != MR_ARRAY_MAGIC || array->m_count <= 1 ) { if( array == NULL || array->m_magic != MR_ARRAY_MAGIC || array->m_count <= 1 ) {
return; return;
@ -177,7 +177,7 @@ static int cmp_strings_t(const void* p1, const void* p2)
* @return The duplicated array. * @return The duplicated array.
* *
*/ */
void mrarray_sort_strings(dc_array_t* array) void dc_array_sort_strings(dc_array_t* array)
{ {
if( array == NULL || array->m_magic != MR_ARRAY_MAGIC || array->m_count <= 1 ) { if( array == NULL || array->m_magic != MR_ARRAY_MAGIC || array->m_count <= 1 ) {
return; return;
@ -248,7 +248,7 @@ void dc_array_add_uint(dc_array_t* array, uintptr_t item)
*/ */
void dc_array_add_id(dc_array_t* array, uint32_t item) void dc_array_add_id(dc_array_t* array, uint32_t item)
{ {
mrarray_add_uint(array, item); dc_array_add_uint(array, item);
} }
@ -265,7 +265,7 @@ void dc_array_add_id(dc_array_t* array, uint32_t item)
*/ */
void dc_array_add_ptr(dc_array_t* array, void* item) void dc_array_add_ptr(dc_array_t* array, void* item)
{ {
mrarray_add_uint(array, (uintptr_t)item); dc_array_add_uint(array, (uintptr_t)item);
} }
@ -431,7 +431,7 @@ char* mr_arr_to_string(const uint32_t* arr, int cnt)
} }
char* mrarray_get_string(const dc_array_t* array, const char* sep) char* dc_array_get_string(const dc_array_t* array, const char* sep)
{ {
char* ret = NULL; char* ret = NULL;

View file

@ -33,18 +33,18 @@ struct _dc_array
/** @privatesection */ /** @privatesection */
uint32_t m_magic; uint32_t m_magic;
mrmailbox_t* m_mailbox; /**< The mailbox the array belongs to. May be NULL when NULL is given to mrarray_new(). */ mrmailbox_t* m_mailbox; /**< The mailbox the array belongs to. May be NULL when NULL is given to dc_array_new(). */
size_t m_allocated; /**< The number of allocated items. Initially ~ 200. */ size_t m_allocated; /**< The number of allocated items. Initially ~ 200. */
size_t m_count; /**< The number of used items. Initially 0. */ size_t m_count; /**< The number of used items. Initially 0. */
uintptr_t* m_array; /**< The data items, can be used between m_data[0] and m_data[m_cnt-1]. Never NULL. */ uintptr_t* m_array; /**< The data items, can be used between m_data[0] and m_data[m_cnt-1]. Never NULL. */
}; };
void mrarray_free_ptr (mrarray_t*); void dc_array_free_ptr (dc_array_t*);
mrarray_t* mrarray_duplicate (const mrarray_t*); dc_array_t* dc_array_duplicate (const dc_array_t*);
void mrarray_sort_ids (mrarray_t*); void dc_array_sort_ids (dc_array_t*);
void mrarray_sort_strings (mrarray_t*); void dc_array_sort_strings (dc_array_t*);
char* mrarray_get_string (const mrarray_t*, const char* sep); char* dc_array_get_string (const dc_array_t*, const char* sep);
char* mr_arr_to_string (const uint32_t* arr, int cnt); char* mr_arr_to_string (const uint32_t* arr, int cnt);

View file

@ -71,7 +71,7 @@ void dc_chat_unref(dc_chat_t* chat)
return; return;
} }
mrchat_empty(chat); dc_chat_empty(chat);
mrparam_unref(chat->m_param); mrparam_unref(chat->m_param);
chat->m_magic = 0; chat->m_magic = 0;
free(chat); free(chat);
@ -228,9 +228,9 @@ char* dc_chat_get_subtitle(dc_chat_t* chat)
else if( chat->m_type == MR_CHAT_TYPE_SINGLE ) else if( chat->m_type == MR_CHAT_TYPE_SINGLE )
{ {
int r; int r;
mrsqlite3_lock(chat->m_mailbox->m_sql); dc_sqlite3_lock(chat->m_mailbox->m_sql);
stmt = mrsqlite3_predefine__(chat->m_mailbox->m_sql, SELECT_a_FROM_chats_contacts_WHERE_i, stmt = dc_sqlite3_predefine__(chat->m_mailbox->m_sql, SELECT_a_FROM_chats_contacts_WHERE_i,
"SELECT c.addr FROM chats_contacts cc " "SELECT c.addr FROM chats_contacts cc "
" LEFT JOIN contacts c ON c.id=cc.contact_id " " LEFT JOIN contacts c ON c.id=cc.contact_id "
" WHERE cc.chat_id=?;"); " WHERE cc.chat_id=?;");
@ -241,7 +241,7 @@ char* dc_chat_get_subtitle(dc_chat_t* chat)
ret = safe_strdup((const char*)sqlite3_column_text(stmt, 0)); ret = safe_strdup((const char*)sqlite3_column_text(stmt, 0));
} }
mrsqlite3_unlock(chat->m_mailbox->m_sql); dc_sqlite3_unlock(chat->m_mailbox->m_sql);
} }
else if( MR_CHAT_TYPE_IS_MULTI(chat->m_type) ) else if( MR_CHAT_TYPE_IS_MULTI(chat->m_type) )
{ {
@ -252,12 +252,12 @@ char* dc_chat_get_subtitle(dc_chat_t* chat)
} }
else else
{ {
mrsqlite3_lock(chat->m_mailbox->m_sql); dc_sqlite3_lock(chat->m_mailbox->m_sql);
cnt = mrmailbox_get_chat_contact_count__(chat->m_mailbox, chat->m_id); cnt = mrmailbox_get_chat_contact_count__(chat->m_mailbox, chat->m_id);
ret = mrstock_str_repl_pl(MR_STR_MEMBER, cnt /*SELF is included in group chats (if not removed)*/); ret = mrstock_str_repl_pl(MR_STR_MEMBER, cnt /*SELF is included in group chats (if not removed)*/);
mrsqlite3_unlock(chat->m_mailbox->m_sql); dc_sqlite3_unlock(chat->m_mailbox->m_sql);
} }
} }
@ -400,7 +400,7 @@ int dc_chat_is_verified(dc_chat_t* chat)
} }
int mrchat_are_all_members_verified__(dc_chat_t* chat) int dc_chat_are_all_members_verified__(dc_chat_t* chat)
{ {
int chat_verified = 0; int chat_verified = 0;
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
@ -413,7 +413,7 @@ int mrchat_are_all_members_verified__(dc_chat_t* chat)
goto cleanup; // deaddrop & co. are never verified goto cleanup; // deaddrop & co. are never verified
} }
stmt = mrsqlite3_predefine__(chat->m_mailbox->m_sql, SELECT_verified_FROM_chats_contacts_WHERE_chat_id, stmt = dc_sqlite3_predefine__(chat->m_mailbox->m_sql, SELECT_verified_FROM_chats_contacts_WHERE_chat_id,
"SELECT c.id, LENGTH(ps.verified_key_fingerprint) " "SELECT c.id, LENGTH(ps.verified_key_fingerprint) "
" FROM chats_contacts cc" " FROM chats_contacts cc"
" LEFT JOIN contacts c ON c.id=cc.contact_id" " LEFT JOIN contacts c ON c.id=cc.contact_id"
@ -462,10 +462,10 @@ int dc_chat_is_self_talk(dc_chat_t* chat)
******************************************************************************/ ******************************************************************************/
int mrchat_update_param__(dc_chat_t* ths) int dc_chat_update_param__(dc_chat_t* ths)
{ {
int success = 0; int success = 0;
sqlite3_stmt* stmt = mrsqlite3_prepare_v2_(ths->m_mailbox->m_sql, "UPDATE chats SET param=? WHERE id=?"); sqlite3_stmt* stmt = dc_sqlite3_prepare_v2_(ths->m_mailbox->m_sql, "UPDATE chats SET param=? WHERE id=?");
sqlite3_bind_text(stmt, 1, ths->m_param->m_packed, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 1, ths->m_param->m_packed, -1, SQLITE_STATIC);
sqlite3_bind_int (stmt, 2, ths->m_id); sqlite3_bind_int (stmt, 2, ths->m_id);
success = sqlite3_step(stmt)==SQLITE_DONE? 1 : 0; success = sqlite3_step(stmt)==SQLITE_DONE? 1 : 0;
@ -474,7 +474,7 @@ int mrchat_update_param__(dc_chat_t* ths)
} }
static int mrchat_set_from_stmt__(dc_chat_t* ths, sqlite3_stmt* row) static int dc_chat_set_from_stmt__(dc_chat_t* ths, sqlite3_stmt* row)
{ {
int row_offset = 0; int row_offset = 0;
const char* draft_text; const char* draft_text;
@ -483,7 +483,7 @@ static int mrchat_set_from_stmt__(dc_chat_t* ths, sqlite3_stmt* row)
return 0; return 0;
} }
mrchat_empty(ths); dc_chat_empty(ths);
#define MR_CHAT_FIELDS " c.id,c.type,c.name, c.draft_timestamp,c.draft_txt,c.grpid,c.param,c.archived, c.blocked " #define MR_CHAT_FIELDS " c.id,c.type,c.name, c.draft_timestamp,c.draft_txt,c.grpid,c.param,c.archived, c.blocked "
ths->m_id = sqlite3_column_int (row, row_offset++); /* the columns are defined in MR_CHAT_FIELDS */ ths->m_id = sqlite3_column_int (row, row_offset++); /* the columns are defined in MR_CHAT_FIELDS */
@ -543,7 +543,7 @@ static int mrchat_set_from_stmt__(dc_chat_t* ths, sqlite3_stmt* row)
* *
* @return 1=success, 0=error. * @return 1=success, 0=error.
*/ */
int mrchat_load_from_db__(dc_chat_t* chat, uint32_t chat_id) int dc_chat_load_from_db__(dc_chat_t* chat, uint32_t chat_id)
{ {
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
@ -551,9 +551,9 @@ int mrchat_load_from_db__(dc_chat_t* chat, uint32_t chat_id)
return 0; return 0;
} }
mrchat_empty(chat); dc_chat_empty(chat);
stmt = mrsqlite3_predefine__(chat->m_mailbox->m_sql, SELECT_itndd_FROM_chats_WHERE_i, stmt = dc_sqlite3_predefine__(chat->m_mailbox->m_sql, SELECT_itndd_FROM_chats_WHERE_i,
"SELECT " MR_CHAT_FIELDS " FROM chats c WHERE c.id=?;"); "SELECT " MR_CHAT_FIELDS " FROM chats c WHERE c.id=?;");
sqlite3_bind_int(stmt, 1, chat_id); sqlite3_bind_int(stmt, 1, chat_id);
@ -561,7 +561,7 @@ int mrchat_load_from_db__(dc_chat_t* chat, uint32_t chat_id)
return 0; return 0;
} }
if( !mrchat_set_from_stmt__(chat, stmt) ) { if( !dc_chat_set_from_stmt__(chat, stmt) ) {
return 0; return 0;
} }

View file

@ -33,17 +33,17 @@ extern "C" {
#define MR_CHAT_DEADDROP_BLOCKED 2 #define MR_CHAT_DEADDROP_BLOCKED 2
/** the structure behind mrchat_t */ /** the structure behind dc_chat_t */
struct _dc_chat struct _dc_chat
{ {
/** @privatesection */ /** @privatesection */
uint32_t m_magic; uint32_t m_magic;
uint32_t m_id; uint32_t m_id;
int m_type; /**< Chat type. Use mrchat_get_type() to access this field. */ int m_type; /**< Chat type. Use dc_chat_get_type() to access this field. */
char* m_name; /**< Name of the chat. Use mrchat_get_name() to access this field. NULL if unset. */ char* m_name; /**< Name of the chat. Use dc_chat_get_name() to access this field. NULL if unset. */
char* m_draft_text; /**< Draft text. NULL if there is no draft. */ char* m_draft_text; /**< Draft text. NULL if there is no draft. */
time_t m_draft_timestamp; /**< Timestamp of the draft. 0 if there is no draft. */ time_t m_draft_timestamp; /**< Timestamp of the draft. 0 if there is no draft. */
int m_archived; /**< Archived state. Better use mrchat_get_archived() to access this object. */ int m_archived; /**< Archived state. Better use dc_chat_get_archived() to access this object. */
mrmailbox_t* m_mailbox; /**< The mailbox object the chat belongs to. */ mrmailbox_t* m_mailbox; /**< The mailbox object the chat belongs to. */
char* m_grpid; /**< Group ID that is used by all clients. Only used if the chat is a group. NULL if unset */ char* m_grpid; /**< Group ID that is used by all clients. Only used if the chat is a group. NULL if unset */
int m_blocked; /**< One of MR_CHAT_*_BLOCKED */ int m_blocked; /**< One of MR_CHAT_*_BLOCKED */
@ -51,9 +51,9 @@ struct _dc_chat
}; };
int mrchat_load_from_db__ (mrchat_t*, uint32_t id); int dc_chat_load_from_db__ (dc_chat_t*, uint32_t id);
int mrchat_update_param__ (mrchat_t*); int dc_chat_update_param__ (dc_chat_t*);
int mrchat_are_all_members_verified__ (mrchat_t*); int dc_chat_are_all_members_verified__ (dc_chat_t*);
#define MR_CHAT_TYPE_IS_MULTI(a) ((a)==MR_CHAT_TYPE_GROUP || (a)==MR_CHAT_TYPE_VERIFIED_GROUP) #define MR_CHAT_TYPE_IS_MULTI(a) ((a)==MR_CHAT_TYPE_GROUP || (a)==MR_CHAT_TYPE_VERIFIED_GROUP)

View file

@ -45,7 +45,7 @@ dc_chatlist_t* dc_chatlist_new(dc_context_t* mailbox)
ths->m_magic = MR_CHATLIST_MAGIC; ths->m_magic = MR_CHATLIST_MAGIC;
ths->m_mailbox = mailbox; ths->m_mailbox = mailbox;
if( (ths->m_chatNlastmsg_ids=mrarray_new(mailbox, 128))==NULL ) { if( (ths->m_chatNlastmsg_ids=dc_array_new(mailbox, 128))==NULL ) {
exit(32); exit(32);
} }
@ -69,8 +69,8 @@ void dc_chatlist_unref(dc_chatlist_t* chatlist)
return; return;
} }
mrchatlist_empty(chatlist); dc_chatlist_empty(chatlist);
mrarray_unref(chatlist->m_chatNlastmsg_ids); dc_array_unref(chatlist->m_chatNlastmsg_ids);
chatlist->m_magic = 0; chatlist->m_magic = 0;
free(chatlist); free(chatlist);
} }
@ -92,7 +92,7 @@ void dc_chatlist_empty(dc_chatlist_t* chatlist)
} }
chatlist->m_cnt = 0; chatlist->m_cnt = 0;
mrarray_empty(chatlist->m_chatNlastmsg_ids); dc_array_empty(chatlist->m_chatNlastmsg_ids);
} }
@ -135,7 +135,7 @@ uint32_t dc_chatlist_get_chat_id(dc_chatlist_t* chatlist, size_t index)
return 0; return 0;
} }
return mrarray_get_id(chatlist->m_chatNlastmsg_ids, index*MR_CHATLIST_IDS_PER_RESULT); return dc_array_get_id(chatlist->m_chatNlastmsg_ids, index*MR_CHATLIST_IDS_PER_RESULT);
} }
@ -159,7 +159,7 @@ uint32_t dc_chatlist_get_msg_id(dc_chatlist_t* chatlist, size_t index)
return 0; return 0;
} }
return mrarray_get_id(chatlist->m_chatNlastmsg_ids, index*MR_CHATLIST_IDS_PER_RESULT+1); return dc_array_get_id(chatlist->m_chatNlastmsg_ids, index*MR_CHATLIST_IDS_PER_RESULT+1);
} }
@ -199,28 +199,28 @@ dc_lot_t* dc_chatlist_get_summary(dc_chatlist_t* chatlist, size_t index, dc_chat
Also, sth. as "No messages" would not work if the summary comes from a Also, sth. as "No messages" would not work if the summary comes from a
message. */ message. */
mrlot_t* ret = mrlot_new(); /* the function never returns NULL */ dc_lot_t* ret = dc_lot_new(); /* the function never returns NULL */
int locked = 0; int locked = 0;
uint32_t lastmsg_id = 0; uint32_t lastmsg_id = 0;
mrmsg_t* lastmsg = NULL; dc_msg_t* lastmsg = NULL;
mrcontact_t* lastcontact = NULL; dc_contact_t* lastcontact = NULL;
mrchat_t* chat_to_delete = NULL; dc_chat_t* chat_to_delete = NULL;
if( chatlist == NULL || chatlist->m_magic != MR_CHATLIST_MAGIC || index >= chatlist->m_cnt ) { if( chatlist == NULL || chatlist->m_magic != MR_CHATLIST_MAGIC || index >= chatlist->m_cnt ) {
ret->m_text2 = safe_strdup("ErrBadChatlistIndex"); ret->m_text2 = safe_strdup("ErrBadChatlistIndex");
goto cleanup; goto cleanup;
} }
lastmsg_id = mrarray_get_id(chatlist->m_chatNlastmsg_ids, index*MR_CHATLIST_IDS_PER_RESULT+1); lastmsg_id = dc_array_get_id(chatlist->m_chatNlastmsg_ids, index*MR_CHATLIST_IDS_PER_RESULT+1);
/* load data from database */ /* load data from database */
mrsqlite3_lock(chatlist->m_mailbox->m_sql); dc_sqlite3_lock(chatlist->m_mailbox->m_sql);
locked = 1; locked = 1;
if( chat==NULL ) { if( chat==NULL ) {
chat = mrchat_new(chatlist->m_mailbox); chat = dc_chat_new(chatlist->m_mailbox);
chat_to_delete = chat; chat_to_delete = chat;
if( !mrchat_load_from_db__(chat, mrarray_get_id(chatlist->m_chatNlastmsg_ids, index*MR_CHATLIST_IDS_PER_RESULT)) ) { if( !dc_chat_load_from_db__(chat, dc_array_get_id(chatlist->m_chatNlastmsg_ids, index*MR_CHATLIST_IDS_PER_RESULT)) ) {
ret->m_text2 = safe_strdup("ErrCannotReadChat"); ret->m_text2 = safe_strdup("ErrCannotReadChat");
goto cleanup; goto cleanup;
} }
@ -229,18 +229,18 @@ dc_lot_t* dc_chatlist_get_summary(dc_chatlist_t* chatlist, size_t index, dc_chat
if( lastmsg_id ) if( lastmsg_id )
{ {
lastmsg = mrmsg_new(); lastmsg = dc_msg_new();
mrmsg_load_from_db__(lastmsg, chatlist->m_mailbox, lastmsg_id); dc_msg_load_from_db__(lastmsg, chatlist->m_mailbox, lastmsg_id);
if( lastmsg->m_from_id != MR_CONTACT_ID_SELF && MR_CHAT_TYPE_IS_MULTI(chat->m_type) ) if( lastmsg->m_from_id != MR_CONTACT_ID_SELF && MR_CHAT_TYPE_IS_MULTI(chat->m_type) )
{ {
lastcontact = mrcontact_new(chatlist->m_mailbox); lastcontact = dc_contact_new(chatlist->m_mailbox);
mrcontact_load_from_db__(lastcontact, chatlist->m_mailbox->m_sql, lastmsg->m_from_id); dc_contact_load_from_db__(lastcontact, chatlist->m_mailbox->m_sql, lastmsg->m_from_id);
} }
} }
mrsqlite3_unlock(chatlist->m_mailbox->m_sql); dc_sqlite3_unlock(chatlist->m_mailbox->m_sql);
locked = 0; locked = 0;
if( chat->m_id == MR_CHAT_ID_ARCHIVED_LINK ) if( chat->m_id == MR_CHAT_ID_ARCHIVED_LINK )
@ -268,14 +268,14 @@ dc_lot_t* dc_chatlist_get_summary(dc_chatlist_t* chatlist, size_t index, dc_chat
else else
{ {
/* show the last message */ /* show the last message */
mrlot_fill(ret, lastmsg, chat, lastcontact); dc_lot_fill(ret, lastmsg, chat, lastcontact);
} }
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(chatlist->m_mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(chatlist->m_mailbox->m_sql); }
mrmsg_unref(lastmsg); dc_msg_unref(lastmsg);
mrcontact_unref(lastcontact); dc_contact_unref(lastcontact);
mrchat_unref(chat_to_delete); dc_chat_unref(chat_to_delete);
return ret; return ret;
} }
@ -305,7 +305,7 @@ dc_context_t* dc_chatlist_get_context(dc_chatlist_t* chatlist)
* *
* @private @memberof dc_chatlist_t * @private @memberof dc_chatlist_t
*/ */
int mrchatlist_load_from_db__(dc_chatlist_t* ths, int listflags, const char* query__, uint32_t query_contact_id) int dc_chatlist_load_from_db__(dc_chatlist_t* ths, int listflags, const char* query__, uint32_t query_contact_id)
{ {
//clock_t start = clock(); //clock_t start = clock();
@ -318,7 +318,7 @@ int mrchatlist_load_from_db__(dc_chatlist_t* ths, int listflags, const char* que
goto cleanup; goto cleanup;
} }
mrchatlist_empty(ths); dc_chatlist_empty(ths);
/* select example with left join and minimum: http://stackoverflow.com/questions/7588142/mysql-left-join-min */ /* select example with left join and minimum: http://stackoverflow.com/questions/7588142/mysql-left-join-min */
#define QUR1 "SELECT c.id, m.id FROM chats c " \ #define QUR1 "SELECT c.id, m.id FROM chats c " \
@ -336,14 +336,14 @@ int mrchatlist_load_from_db__(dc_chatlist_t* ths, int listflags, const char* que
if( query_contact_id ) if( query_contact_id )
{ {
// show chats shared with a given contact // show chats shared with a given contact
stmt = mrsqlite3_predefine__(ths->m_mailbox->m_sql, SELECT_ii_FROM_chats_LEFT_JOIN_msgs_WHERE_contact_id, stmt = dc_sqlite3_predefine__(ths->m_mailbox->m_sql, SELECT_ii_FROM_chats_LEFT_JOIN_msgs_WHERE_contact_id,
QUR1 " AND c.id IN(SELECT chat_id FROM chats_contacts WHERE contact_id=?) " QUR2); QUR1 " AND c.id IN(SELECT chat_id FROM chats_contacts WHERE contact_id=?) " QUR2);
sqlite3_bind_int(stmt, 1, query_contact_id); sqlite3_bind_int(stmt, 1, query_contact_id);
} }
else if( listflags & MR_GCL_ARCHIVED_ONLY ) else if( listflags & MR_GCL_ARCHIVED_ONLY )
{ {
/* show archived chats */ /* show archived chats */
stmt = mrsqlite3_predefine__(ths->m_mailbox->m_sql, SELECT_ii_FROM_chats_LEFT_JOIN_msgs_WHERE_archived, stmt = dc_sqlite3_predefine__(ths->m_mailbox->m_sql, SELECT_ii_FROM_chats_LEFT_JOIN_msgs_WHERE_archived,
QUR1 " AND c.archived=1 " QUR2); QUR1 " AND c.archived=1 " QUR2);
} }
else if( query__==NULL ) else if( query__==NULL )
@ -352,13 +352,13 @@ int mrchatlist_load_from_db__(dc_chatlist_t* ths, int listflags, const char* que
if( !(listflags & MR_GCL_NO_SPECIALS) ) { if( !(listflags & MR_GCL_NO_SPECIALS) ) {
uint32_t last_deaddrop_fresh_msg_id = mrmailbox_get_last_deaddrop_fresh_msg__(ths->m_mailbox); uint32_t last_deaddrop_fresh_msg_id = mrmailbox_get_last_deaddrop_fresh_msg__(ths->m_mailbox);
if( last_deaddrop_fresh_msg_id > 0 ) { if( last_deaddrop_fresh_msg_id > 0 ) {
mrarray_add_id(ths->m_chatNlastmsg_ids, MR_CHAT_ID_DEADDROP); /* show deaddrop with the last fresh message */ dc_array_add_id(ths->m_chatNlastmsg_ids, MR_CHAT_ID_DEADDROP); /* show deaddrop with the last fresh message */
mrarray_add_id(ths->m_chatNlastmsg_ids, last_deaddrop_fresh_msg_id); dc_array_add_id(ths->m_chatNlastmsg_ids, last_deaddrop_fresh_msg_id);
} }
add_archived_link_item = 1; add_archived_link_item = 1;
} }
stmt = mrsqlite3_predefine__(ths->m_mailbox->m_sql, SELECT_ii_FROM_chats_LEFT_JOIN_msgs_WHERE_unarchived, stmt = dc_sqlite3_predefine__(ths->m_mailbox->m_sql, SELECT_ii_FROM_chats_LEFT_JOIN_msgs_WHERE_unarchived,
QUR1 " AND c.archived=0 " QUR2); QUR1 " AND c.archived=0 " QUR2);
} }
else else
@ -371,24 +371,24 @@ int mrchatlist_load_from_db__(dc_chatlist_t* ths, int listflags, const char* que
goto cleanup; goto cleanup;
} }
strLikeCmd = mr_mprintf("%%%s%%", query); strLikeCmd = mr_mprintf("%%%s%%", query);
stmt = mrsqlite3_predefine__(ths->m_mailbox->m_sql, SELECT_ii_FROM_chats_LEFT_JOIN_msgs_WHERE_query, stmt = dc_sqlite3_predefine__(ths->m_mailbox->m_sql, SELECT_ii_FROM_chats_LEFT_JOIN_msgs_WHERE_query,
QUR1 " AND c.name LIKE ? " QUR2); QUR1 " AND c.name LIKE ? " QUR2);
sqlite3_bind_text(stmt, 1, strLikeCmd, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 1, strLikeCmd, -1, SQLITE_STATIC);
} }
while( sqlite3_step(stmt) == SQLITE_ROW ) while( sqlite3_step(stmt) == SQLITE_ROW )
{ {
mrarray_add_id(ths->m_chatNlastmsg_ids, sqlite3_column_int(stmt, 0)); dc_array_add_id(ths->m_chatNlastmsg_ids, sqlite3_column_int(stmt, 0));
mrarray_add_id(ths->m_chatNlastmsg_ids, sqlite3_column_int(stmt, 1)); dc_array_add_id(ths->m_chatNlastmsg_ids, sqlite3_column_int(stmt, 1));
} }
if( add_archived_link_item && mrmailbox_get_archived_count__(ths->m_mailbox)>0 ) if( add_archived_link_item && mrmailbox_get_archived_count__(ths->m_mailbox)>0 )
{ {
mrarray_add_id(ths->m_chatNlastmsg_ids, MR_CHAT_ID_ARCHIVED_LINK); dc_array_add_id(ths->m_chatNlastmsg_ids, MR_CHAT_ID_ARCHIVED_LINK);
mrarray_add_id(ths->m_chatNlastmsg_ids, 0); dc_array_add_id(ths->m_chatNlastmsg_ids, 0);
} }
ths->m_cnt = mrarray_get_cnt(ths->m_chatNlastmsg_ids)/MR_CHATLIST_IDS_PER_RESULT; ths->m_cnt = dc_array_get_cnt(ths->m_chatNlastmsg_ids)/MR_CHATLIST_IDS_PER_RESULT;
success = 1; success = 1;
cleanup: cleanup:

View file

@ -20,8 +20,8 @@
******************************************************************************/ ******************************************************************************/
#ifndef __MRCHATLIST_PRIVATE_H__ #ifndef __DC_CHATLIST_PRIVATE_H__
#define __MRCHATLIST_PRIVATE_H__ #define __DC_CHATLIST_PRIVATE_H__
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -35,14 +35,14 @@ struct _dc_chatlist
mrmailbox_t* m_mailbox; /**< The mailbox, the chatlist belongs to */ mrmailbox_t* m_mailbox; /**< The mailbox, the chatlist belongs to */
#define MR_CHATLIST_IDS_PER_RESULT 2 #define MR_CHATLIST_IDS_PER_RESULT 2
size_t m_cnt; size_t m_cnt;
mrarray_t* m_chatNlastmsg_ids; dc_array_t* m_chatNlastmsg_ids;
}; };
int mrchatlist_load_from_db__ (mrchatlist_t*, int listflags, const char* query, uint32_t query_contact_id); int dc_chatlist_load_from_db__ (dc_chatlist_t*, int listflags, const char* query, uint32_t query_contact_id);
#ifdef __cplusplus #ifdef __cplusplus
} /* /extern "C" */ } /* /extern "C" */
#endif #endif
#endif /* __MRCHATLIST_PRIVATE_H__ */ #endif /* __DC_CHATLIST_PRIVATE_H__ */

View file

@ -387,7 +387,7 @@ void dc_job_do_DC_JOB_CONFIGURE_IMAP(dc_context_t* mailbox, dc_job_t* job)
if( mr_shall_stop_ongoing ) { goto cleanup; } \ if( mr_shall_stop_ongoing ) { goto cleanup; } \
mailbox->m_cb(mailbox, DC_EVENT_CONFIGURE_PROGRESS, (p)<1? 1 : ((p)>999? 999 : (p)), 0); mailbox->m_cb(mailbox, DC_EVENT_CONFIGURE_PROGRESS, (p)<1? 1 : ((p)>999? 999 : (p)), 0);
if( !mrsqlite3_is_open(mailbox->m_sql) ) { if( !dc_sqlite3_is_open(mailbox->m_sql) ) {
dc_log_error(mailbox, 0, "Cannot configure, database not opened."); dc_log_error(mailbox, 0, "Cannot configure, database not opened.");
goto cleanup; goto cleanup;
} }
@ -397,14 +397,14 @@ void dc_job_do_DC_JOB_CONFIGURE_IMAP(dc_context_t* mailbox, dc_job_t* job)
dc_imap_disconnect(mailbox->m_imap); dc_imap_disconnect(mailbox->m_imap);
dc_smtp_disconnect(mailbox->m_smtp); dc_smtp_disconnect(mailbox->m_smtp);
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
//mrsqlite3_set_config_int__(mailbox->m_sql, "configured", 0); -- NO: we do _not_ reset this flag if it was set once; otherwise the user won't get back to his chats (as an alternative, we could change the UI). Moreover, and not changeable in the UI, we use this flag to check if we shall search for backups. //dc_sqlite3_set_config_int__(mailbox->m_sql, "configured", 0); -- NO: we do _not_ reset this flag if it was set once; otherwise the user won't get back to his chats (as an alternative, we could change the UI). Moreover, and not changeable in the UI, we use this flag to check if we shall search for backups.
mailbox->m_smtp->m_log_connect_errors = 1; mailbox->m_smtp->m_log_connect_errors = 1;
mailbox->m_imap->m_log_connect_errors = 1; mailbox->m_imap->m_log_connect_errors = 1;
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
dc_log_info(mailbox, 0, "Configure ..."); dc_log_info(mailbox, 0, "Configure ...");
@ -423,12 +423,12 @@ void dc_job_do_DC_JOB_CONFIGURE_IMAP(dc_context_t* mailbox, dc_job_t* job)
param = dc_loginparam_new(); param = dc_loginparam_new();
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
dc_loginparam_read__(param, mailbox->m_sql, ""); dc_loginparam_read__(param, mailbox->m_sql, "");
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
if( param->m_addr == NULL ) { if( param->m_addr == NULL ) {
@ -651,13 +651,13 @@ void dc_job_do_DC_JOB_CONFIGURE_IMAP(dc_context_t* mailbox, dc_job_t* job)
PROGRESS(900) PROGRESS(900)
/* configuration success - write back the configured parameters with the "configured_" prefix; also write the "configured"-flag */ /* configuration success - write back the configured parameters with the "configured_" prefix; also write the "configured"-flag */
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
dc_loginparam_write__(param, mailbox->m_sql, "configured_" /*the trailing underscore is correct*/); dc_loginparam_write__(param, mailbox->m_sql, "configured_" /*the trailing underscore is correct*/);
mrsqlite3_set_config_int__(mailbox->m_sql, "configured", 1); dc_sqlite3_set_config_int__(mailbox->m_sql, "configured", 1);
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
PROGRESS(920) PROGRESS(920)
@ -673,7 +673,7 @@ void dc_job_do_DC_JOB_CONFIGURE_IMAP(dc_context_t* mailbox, dc_job_t* job)
PROGRESS(940) PROGRESS(940)
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
mailbox->m_cb(mailbox, DC_EVENT_CONFIGURE_PROGRESS, 950, 0); mailbox->m_cb(mailbox, DC_EVENT_CONFIGURE_PROGRESS, 950, 0);
if( imap_connected_here ) { dc_imap_disconnect(mailbox->m_imap); } if( imap_connected_here ) { dc_imap_disconnect(mailbox->m_imap); }
@ -757,11 +757,11 @@ int dc_is_configured(dc_context_t* mailbox)
return 1; return 1;
} }
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
is_configured = mrsqlite3_get_config_int__(mailbox->m_sql, "configured", 0); is_configured = dc_sqlite3_get_config_int__(mailbox->m_sql, "configured", 0);
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
return is_configured? 1 : 0; return is_configured? 1 : 0;
} }

View file

@ -67,7 +67,7 @@ void dc_contact_unref(dc_contact_t* contact)
return; return;
} }
mrcontact_empty(contact); dc_contact_empty(contact);
contact->m_magic = 0; contact->m_magic = 0;
free(contact); free(contact);
} }
@ -275,7 +275,7 @@ int dc_contact_is_blocked(const dc_contact_t* contact)
} }
int mrcontact_is_verified__(const dc_contact_t* contact, const dc_apeerstate_t* peerstate) int dc_contact_is_verified__(const dc_contact_t* contact, const dc_apeerstate_t* peerstate)
{ {
int contact_verified = MRV_NOT_VERIFIED; int contact_verified = MRV_NOT_VERIFIED;
@ -320,17 +320,17 @@ int dc_contact_is_verified(const dc_contact_t* contact)
peerstate = dc_apeerstate_new(contact->m_mailbox); peerstate = dc_apeerstate_new(contact->m_mailbox);
mrsqlite3_lock(contact->m_mailbox->m_sql); dc_sqlite3_lock(contact->m_mailbox->m_sql);
locked = 1; locked = 1;
if( !dc_apeerstate_load_by_addr__(peerstate, contact->m_mailbox->m_sql, contact->m_addr) ) { if( !dc_apeerstate_load_by_addr__(peerstate, contact->m_mailbox->m_sql, contact->m_addr) ) {
goto cleanup; goto cleanup;
} }
contact_verified = mrcontact_is_verified__(contact, peerstate); contact_verified = dc_contact_is_verified__(contact, peerstate);
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(contact->m_mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(contact->m_mailbox->m_sql); }
dc_apeerstate_unref(peerstate); dc_apeerstate_unref(peerstate);
return contact_verified; return contact_verified;
} }
@ -459,7 +459,7 @@ char* mr_normalize_addr(const char* email_addr__)
* *
* @private @memberof dc_contact_t * @private @memberof dc_contact_t
*/ */
int mrcontact_load_from_db__(dc_contact_t* ths, mrsqlite3_t* sql, uint32_t contact_id) int dc_contact_load_from_db__(dc_contact_t* ths, dc_sqlite3_t* sql, uint32_t contact_id)
{ {
int success = 0; int success = 0;
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
@ -468,17 +468,17 @@ int mrcontact_load_from_db__(dc_contact_t* ths, mrsqlite3_t* sql, uint32_t conta
return 0; return 0;
} }
mrcontact_empty(ths); dc_contact_empty(ths);
if( contact_id == MR_CONTACT_ID_SELF ) if( contact_id == MR_CONTACT_ID_SELF )
{ {
ths->m_id = contact_id; ths->m_id = contact_id;
ths->m_name = mrstock_str(MR_STR_SELF); ths->m_name = mrstock_str(MR_STR_SELF);
ths->m_addr = mrsqlite3_get_config__(sql, "configured_addr", ""); ths->m_addr = dc_sqlite3_get_config__(sql, "configured_addr", "");
} }
else else
{ {
stmt = mrsqlite3_predefine__(sql, SELECT_naob_FROM_contacts_i, stmt = dc_sqlite3_predefine__(sql, SELECT_naob_FROM_contacts_i,
"SELECT c.name, c.addr, c.origin, c.blocked, c.authname " "SELECT c.name, c.addr, c.origin, c.blocked, c.authname "
" FROM contacts c " " FROM contacts c "
" WHERE c.id=?;"); " WHERE c.id=?;");

View file

@ -27,7 +27,7 @@ extern "C" {
#endif #endif
typedef struct mrsqlite3_t mrsqlite3_t; typedef struct dc_sqlite3_t dc_sqlite3_t;
typedef struct dc_apeerstate_t dc_apeerstate_t; typedef struct dc_apeerstate_t dc_apeerstate_t;
@ -48,10 +48,10 @@ struct _dc_contact
* Normal contact IDs are larger than these special ones (larger than MR_CONTACT_ID_LAST_SPECIAL). * Normal contact IDs are larger than these special ones (larger than MR_CONTACT_ID_LAST_SPECIAL).
*/ */
uint32_t m_id; uint32_t m_id;
char* m_name; /**< Contact name. It is recommended to use mrcontact_get_name(), mrcontact_get_display_name() or mrcontact_get_name_n_addr() to access this field. May be NULL or empty, initially set to #m_authname. */ char* m_name; /**< Contact name. It is recommended to use dc_contact_get_name(), dc_contact_get_display_name() or dc_contact_get_name_n_addr() to access this field. May be NULL or empty, initially set to #m_authname. */
char* m_authname; /**< Name authorized by the contact himself. Only this name may be spread to others, e.g. in To:-lists. May be NULL or empty. It is recommended to use mrcontact_get_name(), mrcontact_get_display_name() or mrcontact_get_name_n_addr() to access this field. */ char* m_authname; /**< Name authorized by the contact himself. Only this name may be spread to others, e.g. in To:-lists. May be NULL or empty. It is recommended to use dc_contact_get_name(), dc_contact_get_display_name() or dc_contact_get_name_n_addr() to access this field. */
char* m_addr; /**< E-Mail-Address of the contact. It is recommended to use mrcontact_get_addr() to access this field. May be NULL. */ char* m_addr; /**< E-Mail-Address of the contact. It is recommended to use dc_contact_get_addr() to access this field. May be NULL. */
int m_blocked; /**< Blocked state. Use mrcontact_is_blocked() to access this field. */ int m_blocked; /**< Blocked state. Use dc_contact_is_blocked() to access this field. */
int m_origin; /**< The origin/source of the contact. One of the MR_ORIGIN_* constants. */ int m_origin; /**< The origin/source of the contact. One of the MR_ORIGIN_* constants. */
}; };
@ -70,16 +70,16 @@ struct _dc_contact
#define MR_ORIGIN_OUTGOING_TO 0x4000 /* message sent by us */ #define MR_ORIGIN_OUTGOING_TO 0x4000 /* message sent by us */
#define MR_ORIGIN_INTERNAL 0x40000 /* internal use */ #define MR_ORIGIN_INTERNAL 0x40000 /* internal use */
#define MR_ORIGIN_ADRESS_BOOK 0x80000 /* address is in our address book */ #define MR_ORIGIN_ADRESS_BOOK 0x80000 /* address is in our address book */
#define MR_ORIGIN_SECUREJOIN_INVITED 0x1000000 /* set on Alice's side for contacts like Bob that have scanned the QR code offered by her. Only means the contact has once been established using the "securejoin" procedure in the past, getting the current key verification status requires calling mrcontact_is_verfied() ! */ #define MR_ORIGIN_SECUREJOIN_INVITED 0x1000000 /* set on Alice's side for contacts like Bob that have scanned the QR code offered by her. Only means the contact has once been established using the "securejoin" procedure in the past, getting the current key verification status requires calling dc_contact_is_verfied() ! */
#define MR_ORIGIN_SECUREJOIN_JOINED 0x2000000 /* set on Bob's side for contacts scanned and verified from a QR code. Only means the contact has once been established using the "securejoin" procedure in the past, getting the current key verification status requires calling mrcontact_is_verfied() ! */ #define MR_ORIGIN_SECUREJOIN_JOINED 0x2000000 /* set on Bob's side for contacts scanned and verified from a QR code. Only means the contact has once been established using the "securejoin" procedure in the past, getting the current key verification status requires calling dc_contact_is_verfied() ! */
#define MR_ORIGIN_MANUALLY_CREATED 0x4000000 /* contact added mannually by mrmailbox_create_contact(), this should be the largets origin as otherwise the user cannot modify the names */ #define MR_ORIGIN_MANUALLY_CREATED 0x4000000 /* contact added mannually by mrmailbox_create_contact(), this should be the largets origin as otherwise the user cannot modify the names */
#define MR_ORIGIN_MIN_CONTACT_LIST (MR_ORIGIN_INCOMING_REPLY_TO) /* contacts with at least this origin value are shown in the contact list */ #define MR_ORIGIN_MIN_CONTACT_LIST (MR_ORIGIN_INCOMING_REPLY_TO) /* contacts with at least this origin value are shown in the contact list */
#define MR_ORIGIN_MIN_VERIFIED (MR_ORIGIN_INCOMING_REPLY_TO) /* contacts with at least this origin value are verified and known not to be spam */ #define MR_ORIGIN_MIN_VERIFIED (MR_ORIGIN_INCOMING_REPLY_TO) /* contacts with at least this origin value are verified and known not to be spam */
#define MR_ORIGIN_MIN_START_NEW_NCHAT (0x7FFFFFFF) /* contacts with at least this origin value start a new "normal" chat, defaults to off */ #define MR_ORIGIN_MIN_START_NEW_NCHAT (0x7FFFFFFF) /* contacts with at least this origin value start a new "normal" chat, defaults to off */
int mrcontact_load_from_db__ (mrcontact_t*, mrsqlite3_t*, uint32_t contact_id); int dc_contact_load_from_db__ (dc_contact_t*, dc_sqlite3_t*, uint32_t contact_id);
int mrcontact_is_verified__ (const mrcontact_t*, const dc_apeerstate_t*); int dc_contact_is_verified__ (const dc_contact_t*, const dc_apeerstate_t*);
void mr_normalize_name (char* full_name); void mr_normalize_name (char* full_name);
char* mr_normalize_addr (const char* email_addr); char* mr_normalize_addr (const char* email_addr);
char* mr_get_first_name (const char* full_name); char* mr_get_first_name (const char* full_name);

File diff suppressed because it is too large Load diff

View file

@ -48,12 +48,12 @@ extern "C" {
#include "dc_contact.h" #include "dc_contact.h"
typedef struct dc_imap_t dc_imap_t; typedef struct dc_imap_t dc_imap_t;
typedef struct dc_smtp_t dc_smtp_t; typedef struct dc_smtp_t dc_smtp_t;
typedef struct mrsqlite3_t mrsqlite3_t; typedef struct dc_sqlite3_t dc_sqlite3_t;
typedef struct dc_job_t dc_job_t; typedef struct dc_job_t dc_job_t;
typedef struct mrmimeparser_t mrmimeparser_t; typedef struct dc_mimeparser_t dc_mimeparser_t;
typedef struct mrhash_t mrhash_t; typedef struct dc_hash_t dc_hash_t;
/** Structure behind dc_context_t */ /** Structure behind dc_context_t */
@ -68,7 +68,7 @@ struct _dc_context
char* m_dbfile; /**< The database file. This is the file given to mrmailbox_new(). */ char* m_dbfile; /**< The database file. This is the file given to mrmailbox_new(). */
char* m_blobdir; /**< Full path of the blob directory. This is the directory given to mrmailbox_new() or a directory in the same directory as mrmailbox_t::m_dbfile. */ char* m_blobdir; /**< Full path of the blob directory. This is the directory given to mrmailbox_new() or a directory in the same directory as mrmailbox_t::m_dbfile. */
mrsqlite3_t* m_sql; /**< Internal SQL object, never NULL */ dc_sqlite3_t* m_sql; /**< Internal SQL object, never NULL */
dc_imap_t* m_imap; /**< Internal IMAP object, never NULL */ dc_imap_t* m_imap; /**< Internal IMAP object, never NULL */
pthread_mutex_t m_imapidle_condmutex; pthread_mutex_t m_imapidle_condmutex;
@ -112,7 +112,7 @@ void dc_log_info (dc_context_t*, int code, const char* msg,
/* misc.*/ /* misc.*/
void mrmailbox_receive_imf (mrmailbox_t*, const char* imf_raw_not_terminated, size_t imf_raw_bytes, const char* server_folder, uint32_t server_uid, uint32_t flags); void mrmailbox_receive_imf (mrmailbox_t*, const char* imf_raw_not_terminated, size_t imf_raw_bytes, const char* server_folder, uint32_t server_uid, uint32_t flags);
uint32_t mrmailbox_send_msg_object (mrmailbox_t*, uint32_t chat_id, mrmsg_t*); uint32_t mrmailbox_send_msg_object (mrmailbox_t*, uint32_t chat_id, dc_msg_t*);
int mrmailbox_get_archived_count__ (mrmailbox_t*); int mrmailbox_get_archived_count__ (mrmailbox_t*);
size_t mrmailbox_get_real_contact_cnt__ (mrmailbox_t*); size_t mrmailbox_get_real_contact_cnt__ (mrmailbox_t*);
uint32_t mrmailbox_add_or_lookup_contact__ (mrmailbox_t*, const char* display_name /*can be NULL*/, const char* addr_spec, int origin, int* sth_modified); uint32_t mrmailbox_add_or_lookup_contact__ (mrmailbox_t*, const char* display_name /*can be NULL*/, const char* addr_spec, int origin, int* sth_modified);
@ -167,8 +167,8 @@ typedef struct mrmailbox_e2ee_helper_t {
// decryption // decryption
int m_encrypted; // encrypted without problems int m_encrypted; // encrypted without problems
mrhash_t* m_signatures; // fingerprints of valid signatures dc_hash_t* m_signatures; // fingerprints of valid signatures
mrhash_t* m_gossipped_addr; dc_hash_t* m_gossipped_addr;
} mrmailbox_e2ee_helper_t; } mrmailbox_e2ee_helper_t;
@ -192,7 +192,7 @@ void mrmailbox_free_ongoing (mrmailbox_t*);
/* library private: secure-join */ /* library private: secure-join */
#define MR_IS_HANDSHAKE_CONTINUE_NORMAL_PROCESSING 1 #define MR_IS_HANDSHAKE_CONTINUE_NORMAL_PROCESSING 1
#define MR_IS_HANDSHAKE_STOP_NORMAL_PROCESSING 2 #define MR_IS_HANDSHAKE_STOP_NORMAL_PROCESSING 2
int mrmailbox_handle_securejoin_handshake(mrmailbox_t*, mrmimeparser_t*, uint32_t contact_id); int mrmailbox_handle_securejoin_handshake(mrmailbox_t*, dc_mimeparser_t*, uint32_t contact_id);
void mrmailbox_handle_degrade_event (mrmailbox_t*, dc_apeerstate_t*); void mrmailbox_handle_degrade_event (mrmailbox_t*, dc_apeerstate_t*);

View file

@ -153,7 +153,7 @@ static void dehtml_endtag_cb(void* userdata, const char* tag)
} }
char* mr_dehtml(char* buf_terminated) char* dc_dehtml(char* buf_terminated)
{ {
mr_trim(buf_terminated); mr_trim(buf_terminated);
if( buf_terminated[0] == 0 ) { if( buf_terminated[0] == 0 ) {

View file

@ -20,8 +20,8 @@
******************************************************************************/ ******************************************************************************/
#ifndef __MRDEHTML_H__ #ifndef __DC_DEHTML_H__
#define __MRDEHTML_H__ #define __DC_DEHTML_H__
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -29,11 +29,11 @@ extern "C" {
/*** library-internal *********************************************************/ /*** library-internal *********************************************************/
char* mr_dehtml(char* buf_terminated); /* mr_dehtml() returns way too many lineends; however, an optimisation on this issue is not needed as the lineends are typically remove in further processing by the caller */ char* dc_dehtml(char* buf_terminated); /* dc_dehtml() returns way too many lineends; however, an optimisation on this issue is not needed as the lineends are typically remove in further processing by the caller */
#ifdef __cplusplus #ifdef __cplusplus
} /* /extern "C" */ } /* /extern "C" */
#endif #endif
#endif /* __MRDEHTML_H__ */ #endif /* __DC_DEHTML_H__ */

View file

@ -191,7 +191,7 @@ static int contains_report(struct mailmime* mime)
******************************************************************************/ ******************************************************************************/
static int load_or_generate_self_public_key__(mrmailbox_t* mailbox, mrkey_t* public_key, const char* self_addr, static int load_or_generate_self_public_key__(mrmailbox_t* mailbox, dc_key_t* public_key, const char* self_addr,
struct mailmime* random_data_mime /*for an extra-seed of the random generator. For speed reasons, only give _available_ pointers here, do not create any data - in very most cases, the key is not generated!*/) struct mailmime* random_data_mime /*for an extra-seed of the random generator. For speed reasons, only give _available_ pointers here, do not create any data - in very most cases, the key is not generated!*/)
{ {
static int s_in_key_creation = 0; /* avoid double creation (we unlock the database during creation) */ static int s_in_key_creation = 0; /* avoid double creation (we unlock the database during creation) */
@ -202,7 +202,7 @@ static int load_or_generate_self_public_key__(mrmailbox_t* mailbox, mrkey_t* pub
goto cleanup; goto cleanup;
} }
if( !mrkey_load_self_public__(public_key, self_addr, mailbox->m_sql) ) if( !dc_key_load_self_public__(public_key, self_addr, mailbox->m_sql) )
{ {
/* create the keypair - this may take a moment, however, as this is in a thread, this is no big deal */ /* create the keypair - this may take a moment, however, as this is in a thread, this is no big deal */
if( s_in_key_creation ) { goto cleanup; } if( s_in_key_creation ) { goto cleanup; }
@ -216,7 +216,7 @@ static int load_or_generate_self_public_key__(mrmailbox_t* mailbox, mrkey_t* pub
seed[1] = (uintptr_t)seed; /* stack */ seed[1] = (uintptr_t)seed; /* stack */
seed[2] = (uintptr_t)public_key; /* heap */ seed[2] = (uintptr_t)public_key; /* heap */
seed[3] = (uintptr_t)pthread_self(); /* thread ID */ seed[3] = (uintptr_t)pthread_self(); /* thread ID */
mrpgp_rand_seed(mailbox, seed, sizeof(seed)); dc_pgp_rand_seed(mailbox, seed, sizeof(seed));
if( random_data_mime ) { if( random_data_mime ) {
MMAPString* random_data_mmap = NULL; MMAPString* random_data_mmap = NULL;
@ -225,17 +225,17 @@ static int load_or_generate_self_public_key__(mrmailbox_t* mailbox, mrkey_t* pub
goto cleanup; goto cleanup;
} }
mailmime_write_mem(random_data_mmap, &col, random_data_mime); mailmime_write_mem(random_data_mmap, &col, random_data_mime);
mrpgp_rand_seed(mailbox, random_data_mmap->str, random_data_mmap->len); dc_pgp_rand_seed(mailbox, random_data_mmap->str, random_data_mmap->len);
mmap_string_free(random_data_mmap); mmap_string_free(random_data_mmap);
} }
} }
{ {
mrkey_t* private_key = mrkey_new(); dc_key_t* private_key = dc_key_new();
dc_log_info(mailbox, 0, "Generating keypair ..."); dc_log_info(mailbox, 0, "Generating keypair ...");
mrsqlite3_unlock(mailbox->m_sql); /* SIC! unlock database during creation - otherwise the GUI may hang */ dc_sqlite3_unlock(mailbox->m_sql); /* SIC! unlock database during creation - otherwise the GUI may hang */
/* The public key must contain the following: /* The public key must contain the following:
- a signing-capable primary key Kp - a signing-capable primary key Kp
@ -244,29 +244,29 @@ static int load_or_generate_self_public_key__(mrmailbox_t* mailbox, mrkey_t* pub
- an encryption-capable subkey Ke - an encryption-capable subkey Ke
- a binding signature over Ke by Kp - a binding signature over Ke by Kp
(see https://autocrypt.readthedocs.io/en/latest/level0.html#type-p-openpgp-based-key-data )*/ (see https://autocrypt.readthedocs.io/en/latest/level0.html#type-p-openpgp-based-key-data )*/
key_created = mrpgp_create_keypair(mailbox, self_addr, public_key, private_key); key_created = dc_pgp_create_keypair(mailbox, self_addr, public_key, private_key);
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
if( !key_created ) { if( !key_created ) {
dc_log_warning(mailbox, 0, "Cannot create keypair."); dc_log_warning(mailbox, 0, "Cannot create keypair.");
goto cleanup; goto cleanup;
} }
if( !mrpgp_is_valid_key(mailbox, public_key) if( !dc_pgp_is_valid_key(mailbox, public_key)
|| !mrpgp_is_valid_key(mailbox, private_key) ) { || !dc_pgp_is_valid_key(mailbox, private_key) ) {
dc_log_warning(mailbox, 0, "Generated keys are not valid."); dc_log_warning(mailbox, 0, "Generated keys are not valid.");
goto cleanup; goto cleanup;
} }
if( !mrkey_save_self_keypair__(public_key, private_key, self_addr, 1/*set default*/, mailbox->m_sql) ) { if( !dc_key_save_self_keypair__(public_key, private_key, self_addr, 1/*set default*/, mailbox->m_sql) ) {
dc_log_warning(mailbox, 0, "Cannot save keypair."); dc_log_warning(mailbox, 0, "Cannot save keypair.");
goto cleanup; goto cleanup;
} }
dc_log_info(mailbox, 0, "Keypair generated."); dc_log_info(mailbox, 0, "Keypair generated.");
mrkey_unref(private_key); dc_key_unref(private_key);
} }
} }
@ -283,17 +283,17 @@ int mrmailbox_ensure_secret_key_exists(mrmailbox_t* mailbox)
/* normally, the key is generated as soon as the first mail is send /* normally, the key is generated as soon as the first mail is send
(this is to gain some extra-random-seed by the message content and the timespan between program start and message sending) */ (this is to gain some extra-random-seed by the message content and the timespan between program start and message sending) */
int success = 0, locked = 0; int success = 0, locked = 0;
mrkey_t* public_key = mrkey_new(); dc_key_t* public_key = dc_key_new();
char* self_addr = NULL; char* self_addr = NULL;
if( mailbox==NULL || mailbox->m_magic != MR_MAILBOX_MAGIC || public_key==NULL ) { if( mailbox==NULL || mailbox->m_magic != MR_MAILBOX_MAGIC || public_key==NULL ) {
goto cleanup; goto cleanup;
} }
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
if( (self_addr=mrsqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL))==NULL ) { if( (self_addr=dc_sqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL))==NULL ) {
dc_log_warning(mailbox, 0, "Cannot ensure secret key if mailbox is not configured."); dc_log_warning(mailbox, 0, "Cannot ensure secret key if mailbox is not configured.");
goto cleanup; goto cleanup;
} }
@ -305,8 +305,8 @@ int mrmailbox_ensure_secret_key_exists(mrmailbox_t* mailbox)
success = 1; success = 1;
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
mrkey_unref(public_key); dc_key_unref(public_key);
free(self_addr); free(self_addr);
return success; return success;
} }
@ -326,12 +326,12 @@ void mrmailbox_e2ee_encrypt(mrmailbox_t* mailbox, const clist* recipients_addr,
int locked = 0, col = 0, do_encrypt = 0; int locked = 0, col = 0, do_encrypt = 0;
dc_aheader_t* autocryptheader = dc_aheader_new(); dc_aheader_t* autocryptheader = dc_aheader_new();
struct mailimf_fields* imffields_unprotected = NULL; /*just a pointer into mailmime structure, must not be freed*/ struct mailimf_fields* imffields_unprotected = NULL; /*just a pointer into mailmime structure, must not be freed*/
mrkeyring_t* keyring = mrkeyring_new(); dc_keyring_t* keyring = dc_keyring_new();
mrkey_t* sign_key = mrkey_new(); dc_key_t* sign_key = dc_key_new();
MMAPString* plain = mmap_string_new(""); MMAPString* plain = mmap_string_new("");
char* ctext = NULL; char* ctext = NULL;
size_t ctext_bytes = 0; size_t ctext_bytes = 0;
mrarray_t* peerstates = mrarray_new(NULL, 10); dc_array_t* peerstates = dc_array_new(NULL, 10);
if( helper ) { memset(helper, 0, sizeof(mrmailbox_e2ee_helper_t)); } if( helper ) { memset(helper, 0, sizeof(mrmailbox_e2ee_helper_t)); }
@ -341,7 +341,7 @@ void mrmailbox_e2ee_encrypt(mrmailbox_t* mailbox, const clist* recipients_addr,
goto cleanup; goto cleanup;
} }
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
/* init autocrypt header from db */ /* init autocrypt header from db */
@ -350,7 +350,7 @@ void mrmailbox_e2ee_encrypt(mrmailbox_t* mailbox, const clist* recipients_addr,
autocryptheader->m_prefer_encrypt = MRA_PE_MUTUAL; autocryptheader->m_prefer_encrypt = MRA_PE_MUTUAL;
} }
autocryptheader->m_addr = mrsqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL); autocryptheader->m_addr = dc_sqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL);
if( autocryptheader->m_addr == NULL ) { if( autocryptheader->m_addr == NULL ) {
goto cleanup; goto cleanup;
} }
@ -367,7 +367,7 @@ void mrmailbox_e2ee_encrypt(mrmailbox_t* mailbox, const clist* recipients_addr,
for( iter1 = clist_begin(recipients_addr); iter1!=NULL ; iter1=clist_next(iter1) ) { for( iter1 = clist_begin(recipients_addr); iter1!=NULL ; iter1=clist_next(iter1) ) {
const char* recipient_addr = clist_content(iter1); const char* recipient_addr = clist_content(iter1);
dc_apeerstate_t* peerstate = dc_apeerstate_new(mailbox); dc_apeerstate_t* peerstate = dc_apeerstate_new(mailbox);
mrkey_t* key_to_use = NULL; dc_key_t* key_to_use = NULL;
if( strcasecmp(recipient_addr, autocryptheader->m_addr) == 0 ) if( strcasecmp(recipient_addr, autocryptheader->m_addr) == 0 )
{ {
; // encrypt to SELF, this key is added below ; // encrypt to SELF, this key is added below
@ -376,8 +376,8 @@ void mrmailbox_e2ee_encrypt(mrmailbox_t* mailbox, const clist* recipients_addr,
&& (key_to_use=dc_apeerstate_peek_key(peerstate, min_verified)) != NULL && (key_to_use=dc_apeerstate_peek_key(peerstate, min_verified)) != NULL
&& (peerstate->m_prefer_encrypt==MRA_PE_MUTUAL || e2ee_guaranteed) ) && (peerstate->m_prefer_encrypt==MRA_PE_MUTUAL || e2ee_guaranteed) )
{ {
mrkeyring_add(keyring, key_to_use); /* we always add all recipients (even on IMAP upload) as otherwise forwarding may fail */ dc_keyring_add(keyring, key_to_use); /* we always add all recipients (even on IMAP upload) as otherwise forwarding may fail */
mrarray_add_ptr(peerstates, peerstate); dc_array_add_ptr(peerstates, peerstate);
} }
else else
{ {
@ -389,8 +389,8 @@ void mrmailbox_e2ee_encrypt(mrmailbox_t* mailbox, const clist* recipients_addr,
} }
if( do_encrypt ) { if( do_encrypt ) {
mrkeyring_add(keyring, autocryptheader->m_public_key); /* we always add ourself as otherwise forwarded messages are not readable */ dc_keyring_add(keyring, autocryptheader->m_public_key); /* we always add ourself as otherwise forwarded messages are not readable */
if( !mrkey_load_self_private__(sign_key, autocryptheader->m_addr, mailbox->m_sql) ) { if( !dc_key_load_self_private__(sign_key, autocryptheader->m_addr, mailbox->m_sql) ) {
do_encrypt = 0; do_encrypt = 0;
} }
} }
@ -399,7 +399,7 @@ void mrmailbox_e2ee_encrypt(mrmailbox_t* mailbox, const clist* recipients_addr,
do_encrypt = 0; do_encrypt = 0;
} }
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
if( (imffields_unprotected=mailmime_find_mailimf_fields(in_out_message))==NULL ) { if( (imffields_unprotected=mailmime_find_mailimf_fields(in_out_message))==NULL ) {
@ -419,10 +419,10 @@ void mrmailbox_e2ee_encrypt(mrmailbox_t* mailbox, const clist* recipients_addr,
mailmime_get_content_message(), NULL, NULL, NULL, NULL, imffields_encrypted, part_to_encrypt); mailmime_get_content_message(), NULL, NULL, NULL, NULL, imffields_encrypted, part_to_encrypt);
/* gossip keys */ /* gossip keys */
int iCnt = mrarray_get_cnt(peerstates); int iCnt = dc_array_get_cnt(peerstates);
if( iCnt > 1 ) { if( iCnt > 1 ) {
for( int i = 0; i < iCnt; i++ ) { for( int i = 0; i < iCnt; i++ ) {
char* p = dc_apeerstate_render_gossip_header((dc_apeerstate_t*)mrarray_get_ptr(peerstates, i), min_verified); char* p = dc_apeerstate_render_gossip_header((dc_apeerstate_t*)dc_array_get_ptr(peerstates, i), min_verified);
if( p ) { if( p ) {
mailimf_fields_add(imffields_encrypted, mailimf_field_new_custom(strdup("Autocrypt-Gossip"), p/*takes ownership*/)); mailimf_fields_add(imffields_encrypted, mailimf_field_new_custom(strdup("Autocrypt-Gossip"), p/*takes ownership*/));
} }
@ -473,7 +473,7 @@ void mrmailbox_e2ee_encrypt(mrmailbox_t* mailbox, const clist* recipients_addr,
} }
//char* t1=mr_null_terminate(plain->str,plain->len);printf("PLAIN:\n%s\n",t1);free(t1); // DEBUG OUTPUT //char* t1=mr_null_terminate(plain->str,plain->len);printf("PLAIN:\n%s\n",t1);free(t1); // DEBUG OUTPUT
if( !mrpgp_pk_encrypt(mailbox, plain->str, plain->len, keyring, sign_key, 1/*use_armor*/, (void**)&ctext, &ctext_bytes) ) { if( !dc_pgp_pk_encrypt(mailbox, plain->str, plain->len, keyring, sign_key, 1/*use_armor*/, (void**)&ctext, &ctext_bytes) ) {
goto cleanup; goto cleanup;
} }
helper->m_cdata_to_free = ctext; helper->m_cdata_to_free = ctext;
@ -508,14 +508,14 @@ void mrmailbox_e2ee_encrypt(mrmailbox_t* mailbox, const clist* recipients_addr,
mailimf_fields_add(imffields_unprotected, mailimf_field_new_custom(strdup("Autocrypt"), p/*takes ownership of pointer*/)); mailimf_fields_add(imffields_unprotected, mailimf_field_new_custom(strdup("Autocrypt"), p/*takes ownership of pointer*/));
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
dc_aheader_unref(autocryptheader); dc_aheader_unref(autocryptheader);
mrkeyring_unref(keyring); dc_keyring_unref(keyring);
mrkey_unref(sign_key); dc_key_unref(sign_key);
if( plain ) { mmap_string_free(plain); } if( plain ) { mmap_string_free(plain); }
for( int i=mrarray_get_cnt(peerstates)-1; i>=0; i-- ) { dc_apeerstate_unref((dc_apeerstate_t*)mrarray_get_ptr(peerstates, i)); } for( int i=dc_array_get_cnt(peerstates)-1; i>=0; i-- ) { dc_apeerstate_unref((dc_apeerstate_t*)dc_array_get_ptr(peerstates, i)); }
mrarray_unref(peerstates); dc_array_unref(peerstates);
} }
@ -530,14 +530,14 @@ void mrmailbox_e2ee_thanks(mrmailbox_e2ee_helper_t* helper)
if( helper->m_gossipped_addr ) if( helper->m_gossipped_addr )
{ {
mrhash_clear(helper->m_gossipped_addr); dc_hash_clear(helper->m_gossipped_addr);
free(helper->m_gossipped_addr); free(helper->m_gossipped_addr);
helper->m_gossipped_addr = NULL; helper->m_gossipped_addr = NULL;
} }
if( helper->m_signatures ) if( helper->m_signatures )
{ {
mrhash_clear(helper->m_signatures); dc_hash_clear(helper->m_signatures);
free(helper->m_signatures); free(helper->m_signatures);
helper->m_signatures = NULL; helper->m_signatures = NULL;
} }
@ -568,9 +568,9 @@ static int has_decrypted_pgp_armor(const char* str__, int str_bytes)
static int decrypt_part(mrmailbox_t* mailbox, static int decrypt_part(mrmailbox_t* mailbox,
struct mailmime* mime, struct mailmime* mime,
const mrkeyring_t* private_keyring, const dc_keyring_t* private_keyring,
const mrkeyring_t* public_keyring_for_validate, /*may be NULL*/ const dc_keyring_t* public_keyring_for_validate, /*may be NULL*/
mrhash_t* ret_valid_signatures, dc_hash_t* ret_valid_signatures,
struct mailmime** ret_decrypted_mime) struct mailmime** ret_decrypted_mime)
{ {
struct mailmime_data* mime_data; struct mailmime_data* mime_data;
@ -634,10 +634,10 @@ static int decrypt_part(mrmailbox_t* mailbox,
goto cleanup; goto cleanup;
} }
mrhash_t* add_signatures = mrhash_count(ret_valid_signatures)<=0? dc_hash_t* add_signatures = dc_hash_count(ret_valid_signatures)<=0?
ret_valid_signatures : NULL; /*if we already have fingerprints, do not add more; this ensures, only the fingerprints from the outer-most part are collected */ ret_valid_signatures : NULL; /*if we already have fingerprints, do not add more; this ensures, only the fingerprints from the outer-most part are collected */
if( !mrpgp_pk_decrypt(mailbox, decoded_data, decoded_data_bytes, private_keyring, public_keyring_for_validate, 1, &plain_buf, &plain_bytes, add_signatures) if( !dc_pgp_pk_decrypt(mailbox, decoded_data, decoded_data_bytes, private_keyring, public_keyring_for_validate, 1, &plain_buf, &plain_bytes, add_signatures)
|| plain_buf==NULL || plain_bytes<=0 ) { || plain_buf==NULL || plain_bytes<=0 ) {
goto cleanup; goto cleanup;
} }
@ -672,9 +672,9 @@ cleanup:
static int decrypt_recursive(mrmailbox_t* mailbox, static int decrypt_recursive(mrmailbox_t* mailbox,
struct mailmime* mime, struct mailmime* mime,
const mrkeyring_t* private_keyring, const dc_keyring_t* private_keyring,
const mrkeyring_t* public_keyring_for_validate, const dc_keyring_t* public_keyring_for_validate,
mrhash_t* ret_valid_signatures, dc_hash_t* ret_valid_signatures,
struct mailimf_fields** ret_gossip_headers, struct mailimf_fields** ret_gossip_headers,
int* ret_has_unencrypted_parts ) int* ret_has_unencrypted_parts )
{ {
@ -697,7 +697,7 @@ static int decrypt_recursive(mrmailbox_t* mailbox,
{ {
/* remember the header containing potentially Autocrypt-Gossip */ /* remember the header containing potentially Autocrypt-Gossip */
if( *ret_gossip_headers == NULL /* use the outermost decrypted part */ if( *ret_gossip_headers == NULL /* use the outermost decrypted part */
&& mrhash_count(ret_valid_signatures) > 0 /* do not trust the gossipped keys when the message cannot be validated eg. due to a bad signature */ ) && dc_hash_count(ret_valid_signatures) > 0 /* do not trust the gossipped keys when the message cannot be validated eg. due to a bad signature */ )
{ {
size_t dummy = 0; size_t dummy = 0;
struct mailimf_fields* test = NULL; struct mailimf_fields* test = NULL;
@ -738,11 +738,11 @@ static int decrypt_recursive(mrmailbox_t* mailbox,
} }
static mrhash_t* update_gossip_peerstates(mrmailbox_t* mailbox, time_t message_time, struct mailimf_fields* imffields, const struct mailimf_fields* gossip_headers) static dc_hash_t* update_gossip_peerstates(mrmailbox_t* mailbox, time_t message_time, struct mailimf_fields* imffields, const struct mailimf_fields* gossip_headers)
{ {
clistiter* cur1; clistiter* cur1;
mrhash_t* recipients = NULL; dc_hash_t* recipients = NULL;
mrhash_t* gossipped_addr = NULL; dc_hash_t* gossipped_addr = NULL;
for( cur1 = clist_begin(gossip_headers->fld_list); cur1!=NULL ; cur1=clist_next(cur1) ) for( cur1 = clist_begin(gossip_headers->fld_list); cur1!=NULL ; cur1=clist_next(cur1) )
{ {
@ -754,18 +754,18 @@ static mrhash_t* update_gossip_peerstates(mrmailbox_t* mailbox, time_t message_t
{ {
dc_aheader_t* gossip_header = dc_aheader_new(); dc_aheader_t* gossip_header = dc_aheader_new();
if( dc_aheader_set_from_string(gossip_header, optional_field->fld_value) if( dc_aheader_set_from_string(gossip_header, optional_field->fld_value)
&& mrpgp_is_valid_key(mailbox, gossip_header->m_public_key) ) && dc_pgp_is_valid_key(mailbox, gossip_header->m_public_key) )
{ {
/* found an Autocrypt-Gossip entry, create recipents list and check if addr matches */ /* found an Autocrypt-Gossip entry, create recipents list and check if addr matches */
if( recipients == NULL ) { if( recipients == NULL ) {
recipients = mailimf_get_recipients(imffields); recipients = mailimf_get_recipients(imffields);
} }
if( mrhash_find(recipients, gossip_header->m_addr, strlen(gossip_header->m_addr)) ) if( dc_hash_find(recipients, gossip_header->m_addr, strlen(gossip_header->m_addr)) )
{ {
/* valid recipient: update peerstate */ /* valid recipient: update peerstate */
dc_apeerstate_t* peerstate = dc_apeerstate_new(mailbox); dc_apeerstate_t* peerstate = dc_apeerstate_new(mailbox);
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
if( !dc_apeerstate_load_by_addr__(peerstate, mailbox->m_sql, gossip_header->m_addr) ) { if( !dc_apeerstate_load_by_addr__(peerstate, mailbox->m_sql, gossip_header->m_addr) ) {
dc_apeerstate_init_from_gossip(peerstate, gossip_header, message_time); dc_apeerstate_init_from_gossip(peerstate, gossip_header, message_time);
dc_apeerstate_save_to_db__(peerstate, mailbox->m_sql, 1/*create*/); dc_apeerstate_save_to_db__(peerstate, mailbox->m_sql, 1/*create*/);
@ -774,7 +774,7 @@ static mrhash_t* update_gossip_peerstates(mrmailbox_t* mailbox, time_t message_t
dc_apeerstate_apply_gossip(peerstate, gossip_header, message_time); dc_apeerstate_apply_gossip(peerstate, gossip_header, message_time);
dc_apeerstate_save_to_db__(peerstate, mailbox->m_sql, 0/*do not create*/); dc_apeerstate_save_to_db__(peerstate, mailbox->m_sql, 0/*do not create*/);
} }
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
if( peerstate->m_degrade_event ) { if( peerstate->m_degrade_event ) {
mrmailbox_handle_degrade_event(mailbox, peerstate); mrmailbox_handle_degrade_event(mailbox, peerstate);
@ -785,10 +785,10 @@ static mrhash_t* update_gossip_peerstates(mrmailbox_t* mailbox, time_t message_t
// collect all gossipped addresses; we need them later to mark them as being // collect all gossipped addresses; we need them later to mark them as being
// verified when used in a verified group by a verified sender // verified when used in a verified group by a verified sender
if( gossipped_addr == NULL ) { if( gossipped_addr == NULL ) {
gossipped_addr = malloc(sizeof(mrhash_t)); gossipped_addr = malloc(sizeof(dc_hash_t));
mrhash_init(gossipped_addr, MRHASH_STRING, 1/*copy key*/); dc_hash_init(gossipped_addr, MRHASH_STRING, 1/*copy key*/);
} }
mrhash_insert(gossipped_addr, gossip_header->m_addr, strlen(gossip_header->m_addr), (void*)1); dc_hash_insert(gossipped_addr, gossip_header->m_addr, strlen(gossip_header->m_addr), (void*)1);
} }
else else
{ {
@ -801,7 +801,7 @@ static mrhash_t* update_gossip_peerstates(mrmailbox_t* mailbox, time_t message_t
} }
if( recipients ) { if( recipients ) {
mrhash_clear(recipients); dc_hash_clear(recipients);
free(recipients); free(recipients);
} }
@ -820,8 +820,8 @@ void mrmailbox_e2ee_decrypt(mrmailbox_t* mailbox, struct mailmime* in_out_messag
dc_apeerstate_t* peerstate = dc_apeerstate_new(mailbox); dc_apeerstate_t* peerstate = dc_apeerstate_new(mailbox);
int locked = 0; int locked = 0;
char* from = NULL, *self_addr = NULL; char* from = NULL, *self_addr = NULL;
mrkeyring_t* private_keyring = mrkeyring_new(); dc_keyring_t* private_keyring = dc_keyring_new();
mrkeyring_t* public_keyring_for_validate = mrkeyring_new(); dc_keyring_t* public_keyring_for_validate = dc_keyring_new();
struct mailimf_fields* gossip_headers = NULL; struct mailimf_fields* gossip_headers = NULL;
if( helper ) { memset(helper, 0, sizeof(mrmailbox_e2ee_helper_t)); } if( helper ) { memset(helper, 0, sizeof(mrmailbox_e2ee_helper_t)); }
@ -856,14 +856,14 @@ void mrmailbox_e2ee_decrypt(mrmailbox_t* mailbox, struct mailmime* in_out_messag
autocryptheader = dc_aheader_new_from_imffields(from, imffields); autocryptheader = dc_aheader_new_from_imffields(from, imffields);
if( autocryptheader ) { if( autocryptheader ) {
if( !mrpgp_is_valid_key(mailbox, autocryptheader->m_public_key) ) { if( !dc_pgp_is_valid_key(mailbox, autocryptheader->m_public_key) ) {
dc_aheader_unref(autocryptheader); dc_aheader_unref(autocryptheader);
autocryptheader = NULL; autocryptheader = NULL;
} }
} }
/* modify the peerstate (eg. if there is a peer but not autocrypt header, stop encryption) */ /* modify the peerstate (eg. if there is a peer but not autocrypt header, stop encryption) */
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
/* apply Autocrypt:-header */ /* apply Autocrypt:-header */
@ -890,11 +890,11 @@ void mrmailbox_e2ee_decrypt(mrmailbox_t* mailbox, struct mailmime* in_out_messag
} }
/* load private key for decryption */ /* load private key for decryption */
if( (self_addr=mrsqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL))==NULL ) { if( (self_addr=dc_sqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL))==NULL ) {
goto cleanup; goto cleanup;
} }
if( !mrkeyring_load_self_private_for_decrypting__(private_keyring, self_addr, mailbox->m_sql) ) { if( !dc_keyring_load_self_private_for_decrypting__(private_keyring, self_addr, mailbox->m_sql) ) {
goto cleanup; goto cleanup;
} }
@ -903,7 +903,7 @@ void mrmailbox_e2ee_decrypt(mrmailbox_t* mailbox, struct mailmime* in_out_messag
dc_apeerstate_load_by_addr__(peerstate, mailbox->m_sql, from); dc_apeerstate_load_by_addr__(peerstate, mailbox->m_sql, from);
} }
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
if( peerstate->m_degrade_event ) { if( peerstate->m_degrade_event ) {
@ -912,12 +912,12 @@ void mrmailbox_e2ee_decrypt(mrmailbox_t* mailbox, struct mailmime* in_out_messag
// offer both, gossip and public, for signature validation. // offer both, gossip and public, for signature validation.
// the caller may check the signature fingerprints as needed later. // the caller may check the signature fingerprints as needed later.
mrkeyring_add(public_keyring_for_validate, peerstate->m_gossip_key); dc_keyring_add(public_keyring_for_validate, peerstate->m_gossip_key);
mrkeyring_add(public_keyring_for_validate, peerstate->m_public_key); dc_keyring_add(public_keyring_for_validate, peerstate->m_public_key);
/* finally, decrypt. If sth. was decrypted, decrypt_recursive() returns "true" and we start over to decrypt maybe just added parts. */ /* finally, decrypt. If sth. was decrypted, decrypt_recursive() returns "true" and we start over to decrypt maybe just added parts. */
helper->m_signatures = malloc(sizeof(mrhash_t)); helper->m_signatures = malloc(sizeof(dc_hash_t));
mrhash_init(helper->m_signatures, MRHASH_STRING, 1/*copy key*/); dc_hash_init(helper->m_signatures, MRHASH_STRING, 1/*copy key*/);
int iterations = 0; int iterations = 0;
while( iterations < 10 ) { while( iterations < 10 ) {
@ -947,12 +947,12 @@ void mrmailbox_e2ee_decrypt(mrmailbox_t* mailbox, struct mailmime* in_out_messag
//mailmime_print(in_out_message); //mailmime_print(in_out_message);
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
if( gossip_headers ) { mailimf_fields_free(gossip_headers); } if( gossip_headers ) { mailimf_fields_free(gossip_headers); }
dc_aheader_unref(autocryptheader); dc_aheader_unref(autocryptheader);
dc_apeerstate_unref(peerstate); dc_apeerstate_unref(peerstate);
mrkeyring_unref(private_keyring); dc_keyring_unref(private_keyring);
mrkeyring_unref(public_keyring_for_validate); dc_keyring_unref(public_keyring_for_validate);
free(from); free(from);
free(self_addr); free(self_addr);
} }

View file

@ -110,7 +110,7 @@ static int sjhashNoCase(const char *z, int n)
* sense for SJHASH_STRING and SJHASH_BINARY and is ignored * sense for SJHASH_STRING and SJHASH_BINARY and is ignored
* for other key classes. * for other key classes.
*/ */
void mrhash_init(mrhash_t *pNew, int keyClass, int copyKey) void dc_hash_init(dc_hash_t *pNew, int keyClass, int copyKey)
{ {
assert( pNew!=0 ); assert( pNew!=0 );
assert( keyClass>=MRHASH_INT && keyClass<=MRHASH_BINARY ); assert( keyClass>=MRHASH_INT && keyClass<=MRHASH_BINARY );
@ -131,7 +131,7 @@ void mrhash_init(mrhash_t *pNew, int keyClass, int copyKey)
* Call this routine to delete a hash table or to reset a hash table * Call this routine to delete a hash table or to reset a hash table
* to the empty state. * to the empty state.
*/ */
void mrhash_clear(mrhash_t *pH) void dc_hash_clear(dc_hash_t *pH)
{ {
mrhashelem_t *elem; /* For looping over all elements of the table */ mrhashelem_t *elem; /* For looping over all elements of the table */
@ -269,7 +269,7 @@ static int (*compareFunction(int keyClass))(const void*,int,const void*,int)
/* Link an element into the hash table /* Link an element into the hash table
*/ */
static void insertElement(mrhash_t *pH, /* The complete hash table */ static void insertElement(dc_hash_t *pH, /* The complete hash table */
struct _ht *pEntry, /* The entry into which pNew is inserted */ struct _ht *pEntry, /* The entry into which pNew is inserted */
mrhashelem_t *pNew) /* The element to be inserted */ mrhashelem_t *pNew) /* The element to be inserted */
{ {
@ -300,7 +300,7 @@ static void insertElement(mrhash_t *pH, /* The complete hash table */
* "new_size" must be a power of 2. The hash table might fail * "new_size" must be a power of 2. The hash table might fail
* to resize if sjhashMalloc() fails. * to resize if sjhashMalloc() fails.
*/ */
static void rehash(mrhash_t *pH, int new_size) static void rehash(dc_hash_t *pH, int new_size)
{ {
struct _ht *new_ht; /* The new hash table */ struct _ht *new_ht; /* The new hash table */
mrhashelem_t *elem, *next_elem; /* For looping over existing elements */ mrhashelem_t *elem, *next_elem; /* For looping over existing elements */
@ -327,7 +327,7 @@ static void rehash(mrhash_t *pH, int new_size)
* hash table that matches the given key. The hash for this key has * hash table that matches the given key. The hash for this key has
* already been computed and is passed as the 4th parameter. * already been computed and is passed as the 4th parameter.
*/ */
static mrhashelem_t *findElementGivenHash(const mrhash_t *pH, /* The pH to be searched */ static mrhashelem_t *findElementGivenHash(const dc_hash_t *pH, /* The pH to be searched */
const void *pKey, /* The key we are searching for */ const void *pKey, /* The key we are searching for */
int nKey, int nKey,
int h) /* The hash for this key. */ int h) /* The hash for this key. */
@ -359,7 +359,7 @@ static mrhashelem_t *findElementGivenHash(const mrhash_t *pH, /* The pH to be
/* Remove a single entry from the hash table given a pointer to that /* Remove a single entry from the hash table given a pointer to that
* element and a hash on the element's key. * element and a hash on the element's key.
*/ */
static void removeElementGivenHash(mrhash_t *pH, /* The pH containing "elem" */ static void removeElementGivenHash(dc_hash_t *pH, /* The pH containing "elem" */
mrhashelem_t* elem, /* The element to be removed from the pH */ mrhashelem_t* elem, /* The element to be removed from the pH */
int h) /* Hash value for the element */ int h) /* Hash value for the element */
{ {
@ -408,7 +408,7 @@ static void removeElementGivenHash(mrhash_t *pH, /* The pH containing "e
* that matches pKey,nKey. Return the data for this element if it is * that matches pKey,nKey. Return the data for this element if it is
* found, or NULL if there is no match. * found, or NULL if there is no match.
*/ */
void* mrhash_find(const mrhash_t *pH, const void *pKey, int nKey) void* dc_hash_find(const dc_hash_t *pH, const void *pKey, int nKey)
{ {
int h; /* A hash on key */ int h; /* A hash on key */
mrhashelem_t *elem; /* The element that matches key */ mrhashelem_t *elem; /* The element that matches key */
@ -440,7 +440,7 @@ void* mrhash_find(const mrhash_t *pH, const void *pKey, int nKey)
* If the "data" parameter to this function is NULL, then the * If the "data" parameter to this function is NULL, then the
* element corresponding to "key" is removed from the hash table. * element corresponding to "key" is removed from the hash table.
*/ */
void* mrhash_insert(mrhash_t *pH, const void *pKey, int nKey, void *data) void* dc_hash_insert(dc_hash_t *pH, const void *pKey, int nKey, void *data)
{ {
int hraw; /* Raw hash value of the key */ int hraw; /* Raw hash value of the key */
int h; /* the hash of the key modulo hash table size */ int h; /* the hash of the key modulo hash table size */

View file

@ -41,7 +41,7 @@ typedef struct mrhashelem_t mrhashelem_t;
* accessing this structure are really macros, so we can't really make * accessing this structure are really macros, so we can't really make
* this structure opaque. * this structure opaque.
*/ */
typedef struct mrhash_t typedef struct dc_hash_t
{ {
char keyClass; /* SJHASH_INT, _POINTER, _STRING, _BINARY */ char keyClass; /* SJHASH_INT, _POINTER, _STRING, _BINARY */
char copyKey; /* True if copy of key made on insert */ char copyKey; /* True if copy of key made on insert */
@ -53,7 +53,7 @@ typedef struct mrhash_t
int count; /* Number of entries with this hash */ int count; /* Number of entries with this hash */
mrhashelem_t* chain; /* Pointer to first entry with this hash */ mrhashelem_t* chain; /* Pointer to first entry with this hash */
} *ht; } *ht;
} mrhash_t; } dc_hash_t;
/* Each element in the hash table is an instance of the following /* Each element in the hash table is an instance of the following
@ -86,7 +86,7 @@ typedef struct mrhashelem_t
* memcmp() is used to compare keys. * memcmp() is used to compare keys.
* *
* A copy of the key is made for MRHASH_STRING and MRHASH_BINARY * A copy of the key is made for MRHASH_STRING and MRHASH_BINARY
* if the copyKey parameter to mrhash_init() is 1. * if the copyKey parameter to dc_hash_init() is 1.
*/ */
#define MRHASH_INT 1 #define MRHASH_INT 1
#define MRHASH_POINTER 2 #define MRHASH_POINTER 2
@ -97,12 +97,12 @@ typedef struct mrhashelem_t
/* /*
* Access routines. To delete an element, insert a NULL pointer. * Access routines. To delete an element, insert a NULL pointer.
*/ */
void mrhash_init (mrhash_t*, int keytype, int copyKey); void dc_hash_init (dc_hash_t*, int keytype, int copyKey);
void* mrhash_insert (mrhash_t*, const void *pKey, int nKey, void *pData); void* dc_hash_insert (dc_hash_t*, const void *pKey, int nKey, void *pData);
void* mrhash_find (const mrhash_t*, const void *pKey, int nKey); void* dc_hash_find (const dc_hash_t*, const void *pKey, int nKey);
void mrhash_clear (mrhash_t*); void dc_hash_clear (dc_hash_t*);
#define mrhash_find_str(H, s) mrhash_find((H), (s), strlen((s))) #define dc_hash_find_str(H, s) dc_hash_find((H), (s), strlen((s)))
/* /*
@ -112,22 +112,22 @@ void mrhash_clear (mrhash_t*);
* SjHash h; * SjHash h;
* SjHashElem *p; * SjHashElem *p;
* ... * ...
* for(p=mrhash_first(&h); p; p=mrhash_next(p)){ * for(p=dc_hash_first(&h); p; p=dc_hash_next(p)){
* SomeStructure *pData = mrhash_data(p); * SomeStructure *pData = dc_hash_data(p);
* // do something with pData * // do something with pData
* } * }
*/ */
#define mrhash_first(H) ((H)->first) #define dc_hash_first(H) ((H)->first)
#define mrhash_next(E) ((E)->next) #define dc_hash_next(E) ((E)->next)
#define mrhash_data(E) ((E)->data) #define dc_hash_data(E) ((E)->data)
#define mrhash_key(E) ((E)->pKey) #define dc_hash_key(E) ((E)->pKey)
#define mrhash_keysize(E) ((E)->nKey) #define dc_hash_keysize(E) ((E)->nKey)
/* /*
* Number of entries in a hash table * Number of entries in a hash table
*/ */
#define mrhash_count(H) ((H)->count) #define dc_hash_count(H) ((H)->count)
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -104,7 +104,7 @@ char* mrmailbox_render_setup_file(dc_context_t* mailbox, const char* passphrase)
int locked = 0; int locked = 0;
sqlite3_stmt* stmt = NULL; sqlite3_stmt* stmt = NULL;
char* self_addr = NULL; char* self_addr = NULL;
mrkey_t* curr_private_key = mrkey_new(); dc_key_t* curr_private_key = dc_key_new();
char passphrase_begin[8]; char passphrase_begin[8];
uint8_t salt[PGP_SALT_SIZE]; uint8_t salt[PGP_SALT_SIZE];
@ -135,18 +135,18 @@ char* mrmailbox_render_setup_file(dc_context_t* mailbox, const char* passphrase)
} }
{ {
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
self_addr = mrsqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL); self_addr = dc_sqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL);
mrkey_load_self_private__(curr_private_key, self_addr, mailbox->m_sql); dc_key_load_self_private__(curr_private_key, self_addr, mailbox->m_sql);
char* payload_key_asc = mrkey_render_asc(curr_private_key, mailbox->m_e2ee_enabled? "Autocrypt-Prefer-Encrypt: mutual\r\n" : NULL); char* payload_key_asc = dc_key_render_asc(curr_private_key, mailbox->m_e2ee_enabled? "Autocrypt-Prefer-Encrypt: mutual\r\n" : NULL);
if( payload_key_asc == NULL ) { if( payload_key_asc == NULL ) {
goto cleanup; goto cleanup;
} }
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
//printf("\n~~~~~~~~~~~~~~~~~~~~SETUP-PAYLOAD~~~~~~~~~~~~~~~~~~~~\n%s~~~~~~~~~~~~~~~~~~~~/SETUP-PAYLOAD~~~~~~~~~~~~~~~~~~~~\n",key_asc); // DEBUG OUTPUT //printf("\n~~~~~~~~~~~~~~~~~~~~SETUP-PAYLOAD~~~~~~~~~~~~~~~~~~~~\n%s~~~~~~~~~~~~~~~~~~~~/SETUP-PAYLOAD~~~~~~~~~~~~~~~~~~~~\n",key_asc); // DEBUG OUTPUT
@ -276,7 +276,7 @@ char* mrmailbox_render_setup_file(dc_context_t* mailbox, const char* passphrase)
cleanup: cleanup:
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
if( payload_output ) { pgp_output_delete(payload_output); } if( payload_output ) { pgp_output_delete(payload_output); }
if( payload_mem ) { pgp_memory_free(payload_mem); } if( payload_mem ) { pgp_memory_free(payload_mem); }
@ -284,7 +284,7 @@ cleanup:
if( encr_output ) { pgp_output_delete(encr_output); } if( encr_output ) { pgp_output_delete(encr_output); }
if( encr_mem ) { pgp_memory_free(encr_mem); } if( encr_mem ) { pgp_memory_free(encr_mem); }
mrkey_unref(curr_private_key); dc_key_unref(curr_private_key);
free(encr_string); free(encr_string);
free(self_addr); free(self_addr);
@ -307,7 +307,7 @@ cleanup:
* May be created by mrmailbox_render_setup_code() on another device or by * May be created by mrmailbox_render_setup_code() on another device or by
* a completely different app as Thunderbird/Enigmail or K-9. * a completely different app as Thunderbird/Enigmail or K-9.
* @return The decrypted private key as armored-ascii-data or NULL on errors. * @return The decrypted private key as armored-ascii-data or NULL on errors.
* Must be mrkey_unref()'d. * Must be dc_key_unref()'d.
*/ */
char* mrmailbox_decrypt_setup_file(dc_context_t* mailbox, const char* passphrase, const char* filecontent) char* mrmailbox_decrypt_setup_file(dc_context_t* mailbox, const char* passphrase, const char* filecontent)
{ {
@ -321,7 +321,7 @@ char* mrmailbox_decrypt_setup_file(dc_context_t* mailbox, const char* passphrase
/* extract base64 from filecontent */ /* extract base64 from filecontent */
fc_buf = safe_strdup(filecontent); fc_buf = safe_strdup(filecontent);
if( !mr_split_armored_data(fc_buf, &fc_headerline, NULL, NULL, &fc_base64) if( !dc_split_armored_data(fc_buf, &fc_headerline, NULL, NULL, &fc_base64)
|| fc_headerline==NULL || strcmp(fc_headerline, "-----BEGIN PGP MESSAGE-----")!=0 || fc_base64==NULL ) { || fc_headerline==NULL || strcmp(fc_headerline, "-----BEGIN PGP MESSAGE-----")!=0 || fc_base64==NULL ) {
goto cleanup; goto cleanup;
} }
@ -477,7 +477,7 @@ char* dc_initiate_key_transfer(dc_context_t* mailbox)
char* setup_file_content = NULL; char* setup_file_content = NULL;
char* setup_file_name = NULL; char* setup_file_name = NULL;
uint32_t chat_id = 0; uint32_t chat_id = 0;
mrmsg_t* msg = NULL; dc_msg_t* msg = NULL;
uint32_t msg_id = 0; uint32_t msg_id = 0;
if( !mrmailbox_alloc_ongoing(mailbox) ) { if( !mrmailbox_alloc_ongoing(mailbox) ) {
@ -506,7 +506,7 @@ char* dc_initiate_key_transfer(dc_context_t* mailbox)
goto cleanup; goto cleanup;
} }
msg = mrmsg_new(); msg = dc_msg_new();
msg->m_type = MR_MSG_FILE; msg->m_type = MR_MSG_FILE;
mrparam_set (msg->m_param, MRP_FILE, setup_file_name); mrparam_set (msg->m_param, MRP_FILE, setup_file_name);
mrparam_set (msg->m_param, MRP_MIMETYPE, "application/autocrypt-setup"); mrparam_set (msg->m_param, MRP_MIMETYPE, "application/autocrypt-setup");
@ -519,7 +519,7 @@ char* dc_initiate_key_transfer(dc_context_t* mailbox)
goto cleanup; goto cleanup;
} }
mrmsg_unref(msg); dc_msg_unref(msg);
msg = NULL; msg = NULL;
/* wait until the message is really sent */ /* wait until the message is really sent */
@ -532,10 +532,10 @@ char* dc_initiate_key_transfer(dc_context_t* mailbox)
sleep(1); sleep(1);
msg = mrmailbox_get_msg(mailbox, msg_id); msg = mrmailbox_get_msg(mailbox, msg_id);
if( mrmsg_is_sent(msg) ) { if( dc_msg_is_sent(msg) ) {
break; break;
} }
mrmsg_unref(msg); dc_msg_unref(msg);
msg = NULL; msg = NULL;
} }
@ -547,7 +547,7 @@ cleanup:
if( !success ) { free(setup_code); setup_code = NULL; } if( !success ) { free(setup_code); setup_code = NULL; }
free(setup_file_name); free(setup_file_name);
free(setup_file_content); free(setup_file_content);
mrmsg_unref(msg); dc_msg_unref(msg);
mrmailbox_free_ongoing(mailbox); mrmailbox_free_ongoing(mailbox);
return setup_code; return setup_code;
} }
@ -559,30 +559,30 @@ static int set_self_key(mrmailbox_t* mailbox, const char* armored, int set_defau
int locked = 0; int locked = 0;
char* buf = NULL; char* buf = NULL;
const char* buf_headerline, *buf_preferencrypt, *buf_base64; // pointers inside buf, MUST NOT be free()'d const char* buf_headerline, *buf_preferencrypt, *buf_base64; // pointers inside buf, MUST NOT be free()'d
mrkey_t* private_key = mrkey_new(); dc_key_t* private_key = dc_key_new();
mrkey_t* public_key = mrkey_new(); dc_key_t* public_key = dc_key_new();
sqlite3_stmt* stmt = NULL; sqlite3_stmt* stmt = NULL;
char* self_addr = NULL; char* self_addr = NULL;
buf = safe_strdup(armored); buf = safe_strdup(armored);
if( !mr_split_armored_data(buf, &buf_headerline, NULL, &buf_preferencrypt, &buf_base64) if( !dc_split_armored_data(buf, &buf_headerline, NULL, &buf_preferencrypt, &buf_base64)
|| strcmp(buf_headerline, "-----BEGIN PGP PRIVATE KEY BLOCK-----")!=0 || buf_base64 == NULL ) { || strcmp(buf_headerline, "-----BEGIN PGP PRIVATE KEY BLOCK-----")!=0 || buf_base64 == NULL ) {
dc_log_warning(mailbox, 0, "File does not contain a private key."); /* do not log as error - this is quite normal after entering the bad setup code */ dc_log_warning(mailbox, 0, "File does not contain a private key."); /* do not log as error - this is quite normal after entering the bad setup code */
goto cleanup; goto cleanup;
} }
if( !mrkey_set_from_base64(private_key, buf_base64, MR_PRIVATE) if( !dc_key_set_from_base64(private_key, buf_base64, MR_PRIVATE)
|| !mrpgp_is_valid_key(mailbox, private_key) || !dc_pgp_is_valid_key(mailbox, private_key)
|| !mrpgp_split_key(mailbox, private_key, public_key) ) { || !dc_pgp_split_key(mailbox, private_key, public_key) ) {
dc_log_error(mailbox, 0, "File does not contain a valid private key."); dc_log_error(mailbox, 0, "File does not contain a valid private key.");
goto cleanup; goto cleanup;
} }
/* add keypair; before this, delete other keypairs with the same binary key and reset defaults */ /* add keypair; before this, delete other keypairs with the same binary key and reset defaults */
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, "DELETE FROM keypairs WHERE public_key=? OR private_key=?;"); stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql, "DELETE FROM keypairs WHERE public_key=? OR private_key=?;");
sqlite3_bind_blob (stmt, 1, public_key->m_binary, public_key->m_bytes, SQLITE_STATIC); sqlite3_bind_blob (stmt, 1, public_key->m_binary, public_key->m_bytes, SQLITE_STATIC);
sqlite3_bind_blob (stmt, 2, private_key->m_binary, private_key->m_bytes, SQLITE_STATIC); sqlite3_bind_blob (stmt, 2, private_key->m_binary, private_key->m_bytes, SQLITE_STATIC);
sqlite3_step(stmt); sqlite3_step(stmt);
@ -590,16 +590,16 @@ static int set_self_key(mrmailbox_t* mailbox, const char* armored, int set_defau
stmt = NULL; stmt = NULL;
if( set_default ) { if( set_default ) {
mrsqlite3_execute__(mailbox->m_sql, "UPDATE keypairs SET is_default=0;"); /* if the new key should be the default key, all other should not */ dc_sqlite3_execute__(mailbox->m_sql, "UPDATE keypairs SET is_default=0;"); /* if the new key should be the default key, all other should not */
} }
self_addr = mrsqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL); self_addr = dc_sqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL);
if( !mrkey_save_self_keypair__(public_key, private_key, self_addr, set_default, mailbox->m_sql) ) { if( !dc_key_save_self_keypair__(public_key, private_key, self_addr, set_default, mailbox->m_sql) ) {
dc_log_error(mailbox, 0, "Cannot save keypair."); dc_log_error(mailbox, 0, "Cannot save keypair.");
goto cleanup; goto cleanup;
} }
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
/* if we also received an Autocrypt-Prefer-Encrypt header, handle this */ /* if we also received an Autocrypt-Prefer-Encrypt header, handle this */
@ -615,12 +615,12 @@ static int set_self_key(mrmailbox_t* mailbox, const char* armored, int set_defau
success = 1; success = 1;
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
free(buf); free(buf);
free(self_addr); free(self_addr);
mrkey_unref(private_key); dc_key_unref(private_key);
mrkey_unref(public_key); dc_key_unref(public_key);
return success; return success;
} }
@ -650,7 +650,7 @@ cleanup:
int dc_continue_key_transfer(dc_context_t* mailbox, uint32_t msg_id, const char* setup_code) int dc_continue_key_transfer(dc_context_t* mailbox, uint32_t msg_id, const char* setup_code)
{ {
int success = 0; int success = 0;
mrmsg_t* msg = NULL; dc_msg_t* msg = NULL;
char* filename = NULL; char* filename = NULL;
char* filecontent = NULL; char* filecontent = NULL;
size_t filebytes = 0; size_t filebytes = 0;
@ -661,8 +661,8 @@ int dc_continue_key_transfer(dc_context_t* mailbox, uint32_t msg_id, const char*
goto cleanup; goto cleanup;
} }
if( (msg=mrmailbox_get_msg(mailbox, msg_id))==NULL || !mrmsg_is_setupmessage(msg) if( (msg=mrmailbox_get_msg(mailbox, msg_id))==NULL || !dc_msg_is_setupmessage(msg)
|| (filename=mrmsg_get_file(msg))==NULL || filename[0]==0 ) { || (filename=dc_msg_get_file(msg))==NULL || filename[0]==0 ) {
dc_log_error(mailbox, 0, "Message is no Autocrypt Setup Message."); dc_log_error(mailbox, 0, "Message is no Autocrypt Setup Message.");
goto cleanup; goto cleanup;
} }
@ -692,7 +692,7 @@ cleanup:
free(armored_key); free(armored_key);
free(filecontent); free(filecontent);
free(filename); free(filename);
mrmsg_unref(msg); dc_msg_unref(msg);
free(norm_sc); free(norm_sc);
return success; return success;
} }
@ -703,7 +703,7 @@ cleanup:
******************************************************************************/ ******************************************************************************/
static void export_key_to_asc_file(mrmailbox_t* mailbox, const char* dir, int id, const mrkey_t* key, int is_default) static void export_key_to_asc_file(mrmailbox_t* mailbox, const char* dir, int id, const dc_key_t* key, int is_default)
{ {
char* file_name; char* file_name;
if( is_default ) { if( is_default ) {
@ -714,7 +714,7 @@ static void export_key_to_asc_file(mrmailbox_t* mailbox, const char* dir, int id
} }
dc_log_info(mailbox, 0, "Exporting key %s", file_name); dc_log_info(mailbox, 0, "Exporting key %s", file_name);
mr_delete_file(file_name, mailbox); mr_delete_file(file_name, mailbox);
if( mrkey_render_asc_to_file(key, file_name, mailbox) ) { if( dc_key_render_asc_to_file(key, file_name, mailbox) ) {
mailbox->m_cb(mailbox, DC_EVENT_IMEX_FILE_WRITTEN, (uintptr_t)file_name, 0); mailbox->m_cb(mailbox, DC_EVENT_IMEX_FILE_WRITTEN, (uintptr_t)file_name, 0);
dc_log_error(mailbox, 0, "Cannot write key to %s", file_name); dc_log_error(mailbox, 0, "Cannot write key to %s", file_name);
} }
@ -727,21 +727,21 @@ static int export_self_keys(mrmailbox_t* mailbox, const char* dir)
int success = 0; int success = 0;
sqlite3_stmt* stmt = NULL; sqlite3_stmt* stmt = NULL;
int id = 0, is_default = 0; int id = 0, is_default = 0;
mrkey_t* public_key = mrkey_new(); dc_key_t* public_key = dc_key_new();
mrkey_t* private_key = mrkey_new(); dc_key_t* private_key = dc_key_new();
int locked = 0; int locked = 0;
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
if( (stmt=mrsqlite3_prepare_v2_(mailbox->m_sql, "SELECT id, public_key, private_key, is_default FROM keypairs;"))==NULL ) { if( (stmt=dc_sqlite3_prepare_v2_(mailbox->m_sql, "SELECT id, public_key, private_key, is_default FROM keypairs;"))==NULL ) {
goto cleanup; goto cleanup;
} }
while( sqlite3_step(stmt)==SQLITE_ROW ) { while( sqlite3_step(stmt)==SQLITE_ROW ) {
id = sqlite3_column_int( stmt, 0 ); id = sqlite3_column_int( stmt, 0 );
mrkey_set_from_stmt(public_key, stmt, 1, MR_PUBLIC); dc_key_set_from_stmt(public_key, stmt, 1, MR_PUBLIC);
mrkey_set_from_stmt(private_key, stmt, 2, MR_PRIVATE); dc_key_set_from_stmt(private_key, stmt, 2, MR_PRIVATE);
is_default = sqlite3_column_int( stmt, 3 ); is_default = sqlite3_column_int( stmt, 3 );
export_key_to_asc_file(mailbox, dir, id, public_key, is_default); export_key_to_asc_file(mailbox, dir, id, public_key, is_default);
export_key_to_asc_file(mailbox, dir, id, private_key, is_default); export_key_to_asc_file(mailbox, dir, id, private_key, is_default);
@ -750,10 +750,10 @@ static int export_self_keys(mrmailbox_t* mailbox, const char* dir)
success = 1; success = 1;
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
mrkey_unref(public_key); dc_key_unref(public_key);
mrkey_unref(private_key); dc_key_unref(private_key);
return success; return success;
} }
@ -814,7 +814,7 @@ static int import_self_keys(mrmailbox_t* mailbox, const char* dir_name)
free(buf2); free(buf2);
buf2 = safe_strdup(buf); buf2 = safe_strdup(buf);
if( mr_split_armored_data(buf2, &buf2_headerline, NULL, NULL, NULL) if( dc_split_armored_data(buf2, &buf2_headerline, NULL, NULL, NULL)
&& strcmp(buf2_headerline, "-----BEGIN PGP PUBLIC KEY BLOCK-----")==0 ) { && strcmp(buf2_headerline, "-----BEGIN PGP PUBLIC KEY BLOCK-----")==0 ) {
/* This file starts with a Public Key. /* This file starts with a Public Key.
* However some programs (Thunderbird/Enigmail) put public and private key * However some programs (Thunderbird/Enigmail) put public and private key
@ -872,7 +872,7 @@ static int export_backup(mrmailbox_t* mailbox, const char* dir)
{ {
int success = 0, locked = 0, closed = 0; int success = 0, locked = 0, closed = 0;
char* dest_pathNfilename = NULL; char* dest_pathNfilename = NULL;
mrsqlite3_t* dest_sql = NULL; dc_sqlite3_t* dest_sql = NULL;
time_t now = time(NULL); time_t now = time(NULL);
DIR* dir_handle = NULL; DIR* dir_handle = NULL;
struct dirent* dir_entry; struct dirent* dir_entry;
@ -899,9 +899,9 @@ static int export_backup(mrmailbox_t* mailbox, const char* dir)
} }
/* temporary lock and close the source (we just make a copy of the whole file, this is the fastest and easiest approach) */ /* temporary lock and close the source (we just make a copy of the whole file, this is the fastest and easiest approach) */
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
mrsqlite3_close__(mailbox->m_sql); dc_sqlite3_close__(mailbox->m_sql);
closed = 1; closed = 1;
/* copy file to backup directory */ /* copy file to backup directory */
@ -911,19 +911,19 @@ static int export_backup(mrmailbox_t* mailbox, const char* dir)
} }
/* unlock and re-open the source and make it availabe again for the normal use */ /* unlock and re-open the source and make it availabe again for the normal use */
mrsqlite3_open__(mailbox->m_sql, mailbox->m_dbfile, 0); dc_sqlite3_open__(mailbox->m_sql, mailbox->m_dbfile, 0);
closed = 0; closed = 0;
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
/* add all files as blobs to the database copy (this does not require the source to be locked, neigher the destination as it is used only here) */ /* add all files as blobs to the database copy (this does not require the source to be locked, neigher the destination as it is used only here) */
if( (dest_sql=mrsqlite3_new(mailbox/*for logging only*/))==NULL if( (dest_sql=dc_sqlite3_new(mailbox/*for logging only*/))==NULL
|| !mrsqlite3_open__(dest_sql, dest_pathNfilename, 0) ) { || !dc_sqlite3_open__(dest_sql, dest_pathNfilename, 0) ) {
goto cleanup; /* error already logged */ goto cleanup; /* error already logged */
} }
if( !mrsqlite3_table_exists__(dest_sql, "backup_blobs") ) { if( !dc_sqlite3_table_exists__(dest_sql, "backup_blobs") ) {
if( !mrsqlite3_execute__(dest_sql, "CREATE TABLE backup_blobs (id INTEGER PRIMARY KEY, file_name, file_content);") ) { if( !dc_sqlite3_execute__(dest_sql, "CREATE TABLE backup_blobs (id INTEGER PRIMARY KEY, file_name, file_content);") ) {
goto cleanup; /* error already logged */ goto cleanup; /* error already logged */
} }
} }
@ -950,7 +950,7 @@ static int export_backup(mrmailbox_t* mailbox, const char* dir)
goto cleanup; goto cleanup;
} }
stmt = mrsqlite3_prepare_v2_(dest_sql, "INSERT INTO backup_blobs (file_name, file_content) VALUES (?, ?);"); stmt = dc_sqlite3_prepare_v2_(dest_sql, "INSERT INTO backup_blobs (file_name, file_content) VALUES (?, ?);");
while( (dir_entry=readdir(dir_handle))!=NULL ) while( (dir_entry=readdir(dir_handle))!=NULL )
{ {
if( mr_shall_stop_ongoing ) { if( mr_shall_stop_ongoing ) {
@ -992,20 +992,20 @@ static int export_backup(mrmailbox_t* mailbox, const char* dir)
} }
/* done - set some special config values (do this last to avoid importing crashed backups) */ /* done - set some special config values (do this last to avoid importing crashed backups) */
mrsqlite3_set_config_int__(dest_sql, "backup_time", now); dc_sqlite3_set_config_int__(dest_sql, "backup_time", now);
mrsqlite3_set_config__ (dest_sql, "backup_for", mailbox->m_blobdir); dc_sqlite3_set_config__ (dest_sql, "backup_for", mailbox->m_blobdir);
mailbox->m_cb(mailbox, DC_EVENT_IMEX_FILE_WRITTEN, (uintptr_t)dest_pathNfilename, 0); mailbox->m_cb(mailbox, DC_EVENT_IMEX_FILE_WRITTEN, (uintptr_t)dest_pathNfilename, 0);
success = 1; success = 1;
cleanup: cleanup:
if( dir_handle ) { closedir(dir_handle); } if( dir_handle ) { closedir(dir_handle); }
if( closed ) { mrsqlite3_open__(mailbox->m_sql, mailbox->m_dbfile, 0); } if( closed ) { dc_sqlite3_open__(mailbox->m_sql, mailbox->m_dbfile, 0); }
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
mrsqlite3_close__(dest_sql); dc_sqlite3_close__(dest_sql);
mrsqlite3_unref(dest_sql); dc_sqlite3_unref(dest_sql);
if( delete_dest_file ) { mr_delete_file(dest_pathNfilename, mailbox); } if( delete_dest_file ) { mr_delete_file(dest_pathNfilename, mailbox); }
free(dest_pathNfilename); free(dest_pathNfilename);
@ -1054,11 +1054,11 @@ static int import_backup(mrmailbox_t* mailbox, const char* backup_to_import)
} }
/* close and delete the original file - FIXME: we should import to a .bak file and rename it on success. however, currently it is not clear it the import exists in the long run (may be replaced by a restore-from-imap) */ /* close and delete the original file - FIXME: we should import to a .bak file and rename it on success. however, currently it is not clear it the import exists in the long run (may be replaced by a restore-from-imap) */
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
if( mrsqlite3_is_open(mailbox->m_sql) ) { if( dc_sqlite3_is_open(mailbox->m_sql) ) {
mrsqlite3_close__(mailbox->m_sql); dc_sqlite3_close__(mailbox->m_sql);
} }
mr_delete_file(mailbox->m_dbfile, mailbox); mr_delete_file(mailbox->m_dbfile, mailbox);
@ -1074,18 +1074,18 @@ static int import_backup(mrmailbox_t* mailbox, const char* backup_to_import)
} }
/* re-open copied database file */ /* re-open copied database file */
if( !mrsqlite3_open__(mailbox->m_sql, mailbox->m_dbfile, 0) ) { if( !dc_sqlite3_open__(mailbox->m_sql, mailbox->m_dbfile, 0) ) {
goto cleanup; goto cleanup;
} }
/* copy all blobs to files */ /* copy all blobs to files */
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, "SELECT COUNT(*) FROM backup_blobs;"); stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql, "SELECT COUNT(*) FROM backup_blobs;");
sqlite3_step(stmt); sqlite3_step(stmt);
total_files_count = sqlite3_column_int(stmt, 0); total_files_count = sqlite3_column_int(stmt, 0);
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
stmt = NULL; stmt = NULL;
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, "SELECT file_name, file_content FROM backup_blobs ORDER BY id;"); stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql, "SELECT file_name, file_content FROM backup_blobs ORDER BY id;");
while( sqlite3_step(stmt) == SQLITE_ROW ) while( sqlite3_step(stmt) == SQLITE_ROW )
{ {
if( mr_shall_stop_ongoing ) { if( mr_shall_stop_ongoing ) {
@ -1111,13 +1111,13 @@ static int import_backup(mrmailbox_t* mailbox, const char* backup_to_import)
/* finalize/reset all statements - otherwise the table cannot be DROPped below */ /* finalize/reset all statements - otherwise the table cannot be DROPped below */
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
stmt = 0; stmt = 0;
mrsqlite3_reset_all_predefinitions(mailbox->m_sql); dc_sqlite3_reset_all_predefinitions(mailbox->m_sql);
mrsqlite3_execute__(mailbox->m_sql, "DROP TABLE backup_blobs;"); dc_sqlite3_execute__(mailbox->m_sql, "DROP TABLE backup_blobs;");
mrsqlite3_execute__(mailbox->m_sql, "VACUUM;"); dc_sqlite3_execute__(mailbox->m_sql, "VACUUM;");
/* rewrite references to the blobs */ /* rewrite references to the blobs */
repl_from = mrsqlite3_get_config__(mailbox->m_sql, "backup_for", NULL); repl_from = dc_sqlite3_get_config__(mailbox->m_sql, "backup_for", NULL);
if( repl_from && strlen(repl_from)>1 && mailbox->m_blobdir && strlen(mailbox->m_blobdir)>1 ) if( repl_from && strlen(repl_from)>1 && mailbox->m_blobdir && strlen(mailbox->m_blobdir)>1 )
{ {
ensure_no_slash(repl_from); ensure_no_slash(repl_from);
@ -1130,15 +1130,15 @@ static int import_backup(mrmailbox_t* mailbox, const char* backup_to_import)
assert( 'i' == MRP_PROFILE_IMAGE ); assert( 'i' == MRP_PROFILE_IMAGE );
char* q3 = sqlite3_mprintf("UPDATE msgs SET param=replace(param, 'f=%q/', 'f=%q/');", repl_from, repl_to); /* cannot use mr_mprintf() because of "%q" */ char* q3 = sqlite3_mprintf("UPDATE msgs SET param=replace(param, 'f=%q/', 'f=%q/');", repl_from, repl_to); /* cannot use mr_mprintf() because of "%q" */
mrsqlite3_execute__(mailbox->m_sql, q3); dc_sqlite3_execute__(mailbox->m_sql, q3);
sqlite3_free(q3); sqlite3_free(q3);
q3 = sqlite3_mprintf("UPDATE chats SET param=replace(param, 'i=%q/', 'i=%q/');", repl_from, repl_to); q3 = sqlite3_mprintf("UPDATE chats SET param=replace(param, 'i=%q/', 'i=%q/');", repl_from, repl_to);
mrsqlite3_execute__(mailbox->m_sql, q3); dc_sqlite3_execute__(mailbox->m_sql, q3);
sqlite3_free(q3); sqlite3_free(q3);
q3 = sqlite3_mprintf("UPDATE contacts SET param=replace(param, 'i=%q/', 'i=%q/');", repl_from, repl_to); q3 = sqlite3_mprintf("UPDATE contacts SET param=replace(param, 'i=%q/', 'i=%q/');", repl_from, repl_to);
mrsqlite3_execute__(mailbox->m_sql, q3); dc_sqlite3_execute__(mailbox->m_sql, q3);
sqlite3_free(q3); sqlite3_free(q3);
} }
@ -1149,7 +1149,7 @@ cleanup:
free(repl_from); free(repl_from);
free(repl_to); free(repl_to);
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
return success; return success;
} }
@ -1223,7 +1223,7 @@ int dc_imex(dc_context_t* mailbox, int what, const char* param1, const char* par
dc_log_info(mailbox, 0, "Import/export process started."); dc_log_info(mailbox, 0, "Import/export process started.");
mailbox->m_cb(mailbox, DC_EVENT_IMEX_PROGRESS, 0, 0); mailbox->m_cb(mailbox, DC_EVENT_IMEX_PROGRESS, 0, 0);
if( !mrsqlite3_is_open(mailbox->m_sql) ) { if( !dc_sqlite3_is_open(mailbox->m_sql) ) {
dc_log_error(mailbox, 0, "Import/export: Database not opened."); dc_log_error(mailbox, 0, "Import/export: Database not opened.");
goto cleanup; goto cleanup;
} }
@ -1338,7 +1338,7 @@ char* dc_imex_has_backup(dc_context_t* mailbox, const char* dir_name)
int prefix_len = strlen(DC_BAK_PREFIX); int prefix_len = strlen(DC_BAK_PREFIX);
int suffix_len = strlen(DC_BAK_SUFFIX); int suffix_len = strlen(DC_BAK_SUFFIX);
char* curr_pathNfilename = NULL; char* curr_pathNfilename = NULL;
mrsqlite3_t* test_sql = NULL; dc_sqlite3_t* test_sql = NULL;
if( mailbox == NULL || mailbox->m_magic != MR_MAILBOX_MAGIC ) { if( mailbox == NULL || mailbox->m_magic != MR_MAILBOX_MAGIC ) {
return NULL; return NULL;
@ -1358,11 +1358,11 @@ char* dc_imex_has_backup(dc_context_t* mailbox, const char* dir_name)
free(curr_pathNfilename); free(curr_pathNfilename);
curr_pathNfilename = mr_mprintf("%s/%s", dir_name, name); curr_pathNfilename = mr_mprintf("%s/%s", dir_name, name);
mrsqlite3_unref(test_sql); dc_sqlite3_unref(test_sql);
if( (test_sql=mrsqlite3_new(mailbox/*for logging only*/))!=NULL if( (test_sql=dc_sqlite3_new(mailbox/*for logging only*/))!=NULL
&& mrsqlite3_open__(test_sql, curr_pathNfilename, MR_OPEN_READONLY) ) && dc_sqlite3_open__(test_sql, curr_pathNfilename, MR_OPEN_READONLY) )
{ {
time_t curr_backup_time = mrsqlite3_get_config_int__(test_sql, "backup_time", 0); /* reading the backup time also checks if the database is readable and the table `config` exists */ time_t curr_backup_time = dc_sqlite3_get_config_int__(test_sql, "backup_time", 0); /* reading the backup time also checks if the database is readable and the table `config` exists */
if( curr_backup_time > 0 if( curr_backup_time > 0
&& curr_backup_time > ret_backup_time/*use the newest if there are multiple backup*/ ) && curr_backup_time > ret_backup_time/*use the newest if there are multiple backup*/ )
{ {
@ -1379,7 +1379,7 @@ char* dc_imex_has_backup(dc_context_t* mailbox, const char* dir_name)
cleanup: cleanup:
if( dir_handle ) { closedir(dir_handle); } if( dir_handle ) { closedir(dir_handle); }
free(curr_pathNfilename); free(curr_pathNfilename);
mrsqlite3_unref(test_sql); dc_sqlite3_unref(test_sql);
return ret; return ret;
} }
@ -1407,11 +1407,11 @@ int dc_check_password(dc_context_t* mailbox, const char* test_pw)
goto cleanup; goto cleanup;
} }
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
dc_loginparam_read__(loginparam, mailbox->m_sql, "configured_"); dc_loginparam_read__(loginparam, mailbox->m_sql, "configured_");
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
if( (loginparam->m_mail_pw==NULL || loginparam->m_mail_pw[0]==0) && (test_pw==NULL || test_pw[0]==0) ) { if( (loginparam->m_mail_pw==NULL || loginparam->m_mail_pw[0]==0) && (test_pw==NULL || test_pw[0]==0) ) {
/* both empty or unset */ /* both empty or unset */

View file

@ -54,17 +54,17 @@ static int connect_to_imap(mrmailbox_t* mailbox, dc_job_t* job /*may be NULL if
goto cleanup; goto cleanup;
} }
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
is_locked = 1; is_locked = 1;
if( mrsqlite3_get_config_int__(mailbox->m_sql, "configured", 0) == 0 ) { if( dc_sqlite3_get_config_int__(mailbox->m_sql, "configured", 0) == 0 ) {
dc_log_warning(mailbox, 0, "Not configured, cannot connect."); // this is no error, connect() is called eg. when the screen is switched on, it's okay if the caller does not check all circumstances here dc_log_warning(mailbox, 0, "Not configured, cannot connect."); // this is no error, connect() is called eg. when the screen is switched on, it's okay if the caller does not check all circumstances here
goto cleanup; goto cleanup;
} }
dc_loginparam_read__(param, mailbox->m_sql, "configured_" /*the trailing underscore is correct*/); dc_loginparam_read__(param, mailbox->m_sql, "configured_" /*the trailing underscore is correct*/);
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
is_locked = 0; is_locked = 0;
if( !dc_imap_connect(mailbox->m_imap, param) ) { if( !dc_imap_connect(mailbox->m_imap, param) ) {
@ -75,7 +75,7 @@ static int connect_to_imap(mrmailbox_t* mailbox, dc_job_t* job /*may be NULL if
ret_connected = JUST_CONNECTED; ret_connected = JUST_CONNECTED;
cleanup: cleanup:
if( is_locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( is_locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
dc_loginparam_unref(param); dc_loginparam_unref(param);
return ret_connected; return ret_connected;
} }
@ -83,11 +83,11 @@ cleanup:
static void dc_job_do_DC_JOB_SEND_MSG_TO_IMAP(mrmailbox_t* mailbox, dc_job_t* job) static void dc_job_do_DC_JOB_SEND_MSG_TO_IMAP(mrmailbox_t* mailbox, dc_job_t* job)
{ {
mrmimefactory_t mimefactory; dc_mimefactory_t mimefactory;
char* server_folder = NULL; char* server_folder = NULL;
uint32_t server_uid = 0; uint32_t server_uid = 0;
mrmimefactory_init(&mimefactory, mailbox); dc_mimefactory_init(&mimefactory, mailbox);
/* connect to IMAP-server */ /* connect to IMAP-server */
if( !dc_imap_is_connected(mailbox->m_imap) ) { if( !dc_imap_is_connected(mailbox->m_imap) ) {
@ -99,12 +99,12 @@ static void dc_job_do_DC_JOB_SEND_MSG_TO_IMAP(mrmailbox_t* mailbox, dc_job_t* jo
} }
/* create message */ /* create message */
if( mrmimefactory_load_msg(&mimefactory, job->m_foreign_id)==0 if( dc_mimefactory_load_msg(&mimefactory, job->m_foreign_id)==0
|| mimefactory.m_from_addr == NULL ) { || mimefactory.m_from_addr == NULL ) {
goto cleanup; /* should not happen as we've sent the message to the SMTP server before */ goto cleanup; /* should not happen as we've sent the message to the SMTP server before */
} }
if( !mrmimefactory_render(&mimefactory) ) { if( !dc_mimefactory_render(&mimefactory) ) {
goto cleanup; /* should not happen as we've sent the message to the SMTP server before */ goto cleanup; /* should not happen as we've sent the message to the SMTP server before */
} }
@ -113,13 +113,13 @@ static void dc_job_do_DC_JOB_SEND_MSG_TO_IMAP(mrmailbox_t* mailbox, dc_job_t* jo
goto cleanup; goto cleanup;
} }
else { else {
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
mrmailbox_update_server_uid__(mailbox, mimefactory.m_msg->m_rfc724_mid, server_folder, server_uid); mrmailbox_update_server_uid__(mailbox, mimefactory.m_msg->m_rfc724_mid, server_folder, server_uid);
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
} }
cleanup: cleanup:
mrmimefactory_empty(&mimefactory); dc_mimefactory_empty(&mimefactory);
free(server_folder); free(server_folder);
} }
@ -127,12 +127,12 @@ cleanup:
static void dc_job_do_DC_JOB_DELETE_MSG_ON_IMAP(mrmailbox_t* mailbox, dc_job_t* job) static void dc_job_do_DC_JOB_DELETE_MSG_ON_IMAP(mrmailbox_t* mailbox, dc_job_t* job)
{ {
int locked = 0, delete_from_server = 1; int locked = 0, delete_from_server = 1;
mrmsg_t* msg = mrmsg_new(); dc_msg_t* msg = dc_msg_new();
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
if( !mrmsg_load_from_db__(msg, mailbox, job->m_foreign_id) if( !dc_msg_load_from_db__(msg, mailbox, job->m_foreign_id)
|| msg->m_rfc724_mid == NULL || msg->m_rfc724_mid[0] == 0 /* eg. device messages have no Message-ID */ ) { || msg->m_rfc724_mid == NULL || msg->m_rfc724_mid[0] == 0 /* eg. device messages have no Message-ID */ ) {
goto cleanup; goto cleanup;
} }
@ -142,7 +142,7 @@ static void dc_job_do_DC_JOB_DELETE_MSG_ON_IMAP(mrmailbox_t* mailbox, dc_job_t*
delete_from_server = 0; delete_from_server = 0;
} }
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
/* if this is the last existing part of the message, we delete the message from the server */ /* if this is the last existing part of the message, we delete the message from the server */
@ -167,15 +167,15 @@ static void dc_job_do_DC_JOB_DELETE_MSG_ON_IMAP(mrmailbox_t* mailbox, dc_job_t*
- if the message is successfully removed from the server - if the message is successfully removed from the server
- or if there are other parts of the message in the database (in this case we have not deleted if from the server) - or if there are other parts of the message in the database (in this case we have not deleted if from the server)
(As long as the message is not removed from the IMAP-server, we need at least one database entry to avoid a re-download) */ (As long as the message is not removed from the IMAP-server, we need at least one database entry to avoid a re-download) */
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
sqlite3_stmt* stmt = mrsqlite3_predefine__(mailbox->m_sql, DELETE_FROM_msgs_WHERE_id, sqlite3_stmt* stmt = dc_sqlite3_predefine__(mailbox->m_sql, DELETE_FROM_msgs_WHERE_id,
"DELETE FROM msgs WHERE id=?;"); "DELETE FROM msgs WHERE id=?;");
sqlite3_bind_int(stmt, 1, msg->m_id); sqlite3_bind_int(stmt, 1, msg->m_id);
sqlite3_step(stmt); sqlite3_step(stmt);
stmt = mrsqlite3_predefine__(mailbox->m_sql, DELETE_FROM_msgs_mdns_WHERE_m, stmt = dc_sqlite3_predefine__(mailbox->m_sql, DELETE_FROM_msgs_mdns_WHERE_m,
"DELETE FROM msgs_mdns WHERE msg_id=?;"); "DELETE FROM msgs_mdns WHERE msg_id=?;");
sqlite3_bind_int(stmt, 1, msg->m_id); sqlite3_bind_int(stmt, 1, msg->m_id);
sqlite3_step(stmt); sqlite3_step(stmt);
@ -185,7 +185,7 @@ static void dc_job_do_DC_JOB_DELETE_MSG_ON_IMAP(mrmailbox_t* mailbox, dc_job_t*
if( strncmp(mailbox->m_blobdir, pathNfilename, strlen(mailbox->m_blobdir))==0 ) if( strncmp(mailbox->m_blobdir, pathNfilename, strlen(mailbox->m_blobdir))==0 )
{ {
char* strLikeFilename = mr_mprintf("%%f=%s%%", pathNfilename); char* strLikeFilename = mr_mprintf("%%f=%s%%", pathNfilename);
sqlite3_stmt* stmt2 = mrsqlite3_prepare_v2_(mailbox->m_sql, "SELECT id FROM msgs WHERE type!=? AND param LIKE ?;"); /* if this gets too slow, an index over "type" should help. */ sqlite3_stmt* stmt2 = dc_sqlite3_prepare_v2_(mailbox->m_sql, "SELECT id FROM msgs WHERE type!=? AND param LIKE ?;"); /* if this gets too slow, an index over "type" should help. */
sqlite3_bind_int (stmt2, 1, MR_MSG_TEXT); sqlite3_bind_int (stmt2, 1, MR_MSG_TEXT);
sqlite3_bind_text(stmt2, 2, strLikeFilename, -1, SQLITE_STATIC); sqlite3_bind_text(stmt2, 2, strLikeFilename, -1, SQLITE_STATIC);
int file_used_by_other_msgs = (sqlite3_step(stmt2)==SQLITE_ROW)? 1 : 0; int file_used_by_other_msgs = (sqlite3_step(stmt2)==SQLITE_ROW)? 1 : 0;
@ -217,19 +217,19 @@ static void dc_job_do_DC_JOB_DELETE_MSG_ON_IMAP(mrmailbox_t* mailbox, dc_job_t*
free(pathNfilename); free(pathNfilename);
} }
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
mrmsg_unref(msg); dc_msg_unref(msg);
} }
static void dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(mrmailbox_t* mailbox, dc_job_t* job) static void dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(mrmailbox_t* mailbox, dc_job_t* job)
{ {
int locked = 0; int locked = 0;
mrmsg_t* msg = mrmsg_new(); dc_msg_t* msg = dc_msg_new();
char* new_server_folder = NULL; char* new_server_folder = NULL;
uint32_t new_server_uid = 0; uint32_t new_server_uid = 0;
int in_ms_flags = 0, out_ms_flags = 0; int in_ms_flags = 0, out_ms_flags = 0;
@ -242,20 +242,20 @@ static void dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(mrmailbox_t* mailbox, dc_job_t
} }
} }
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
if( !mrmsg_load_from_db__(msg, mailbox, job->m_foreign_id) ) { if( !dc_msg_load_from_db__(msg, mailbox, job->m_foreign_id) ) {
goto cleanup; goto cleanup;
} }
/* add an additional job for sending the MDN (here in a thread for fast ui resonses) (an extra job as the MDN has a lower priority) */ /* add an additional job for sending the MDN (here in a thread for fast ui resonses) (an extra job as the MDN has a lower priority) */
if( mrparam_get_int(msg->m_param, MRP_WANTS_MDN, 0) /* MRP_WANTS_MDN is set only for one part of a multipart-message */ if( mrparam_get_int(msg->m_param, MRP_WANTS_MDN, 0) /* MRP_WANTS_MDN is set only for one part of a multipart-message */
&& mrsqlite3_get_config_int__(mailbox->m_sql, "mdns_enabled", MR_MDNS_DEFAULT_ENABLED) ) { && dc_sqlite3_get_config_int__(mailbox->m_sql, "mdns_enabled", MR_MDNS_DEFAULT_ENABLED) ) {
in_ms_flags |= MR_MS_SET_MDNSent_FLAG; in_ms_flags |= MR_MS_SET_MDNSent_FLAG;
} }
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
if( msg->m_is_msgrmsg ) { if( msg->m_is_msgrmsg ) {
@ -267,7 +267,7 @@ static void dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(mrmailbox_t* mailbox, dc_job_t
{ {
if( (new_server_folder && new_server_uid) || out_ms_flags&MR_MS_MDNSent_JUST_SET ) if( (new_server_folder && new_server_uid) || out_ms_flags&MR_MS_MDNSent_JUST_SET )
{ {
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
if( new_server_folder && new_server_uid ) if( new_server_folder && new_server_uid )
@ -280,7 +280,7 @@ static void dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(mrmailbox_t* mailbox, dc_job_t
dc_job_add(mailbox, DC_JOB_SEND_MDN, msg->m_id, NULL, 0); dc_job_add(mailbox, DC_JOB_SEND_MDN, msg->m_id, NULL, 0);
} }
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
} }
} }
@ -290,8 +290,8 @@ static void dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(mrmailbox_t* mailbox, dc_job_t
} }
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
mrmsg_unref(msg); dc_msg_unref(msg);
free(new_server_folder); free(new_server_folder);
} }
@ -327,31 +327,31 @@ cleanup:
******************************************************************************/ ******************************************************************************/
static void mark_as_error(mrmailbox_t* mailbox, mrmsg_t* msg) static void mark_as_error(mrmailbox_t* mailbox, dc_msg_t* msg)
{ {
if( mailbox==NULL || msg==NULL ) { if( mailbox==NULL || msg==NULL ) {
return; return;
} }
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
mrmailbox_update_msg_state__(mailbox, msg->m_id, MR_STATE_OUT_ERROR); mrmailbox_update_msg_state__(mailbox, msg->m_id, MR_STATE_OUT_ERROR);
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
mailbox->m_cb(mailbox, DC_EVENT_MSGS_CHANGED, msg->m_chat_id, 0); mailbox->m_cb(mailbox, DC_EVENT_MSGS_CHANGED, msg->m_chat_id, 0);
} }
static void dc_job_do_DC_JOB_SEND_MSG_TO_SMTP(mrmailbox_t* mailbox, dc_job_t* job) static void dc_job_do_DC_JOB_SEND_MSG_TO_SMTP(mrmailbox_t* mailbox, dc_job_t* job)
{ {
mrmimefactory_t mimefactory; dc_mimefactory_t mimefactory;
mrmimefactory_init(&mimefactory, mailbox); dc_mimefactory_init(&mimefactory, mailbox);
/* connect to SMTP server, if not yet done */ /* connect to SMTP server, if not yet done */
if( !dc_smtp_is_connected(mailbox->m_smtp) ) { if( !dc_smtp_is_connected(mailbox->m_smtp) ) {
dc_loginparam_t* loginparam = dc_loginparam_new(); dc_loginparam_t* loginparam = dc_loginparam_new();
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
dc_loginparam_read__(loginparam, mailbox->m_sql, "configured_"); dc_loginparam_read__(loginparam, mailbox->m_sql, "configured_");
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
int connected = dc_smtp_connect(mailbox->m_smtp, loginparam); int connected = dc_smtp_connect(mailbox->m_smtp, loginparam);
dc_loginparam_unref(loginparam); dc_loginparam_unref(loginparam);
if( !connected ) { if( !connected ) {
@ -361,7 +361,7 @@ static void dc_job_do_DC_JOB_SEND_MSG_TO_SMTP(mrmailbox_t* mailbox, dc_job_t* jo
} }
/* load message data */ /* load message data */
if( !mrmimefactory_load_msg(&mimefactory, job->m_foreign_id) if( !dc_mimefactory_load_msg(&mimefactory, job->m_foreign_id)
|| mimefactory.m_from_addr == NULL ) { || mimefactory.m_from_addr == NULL ) {
dc_log_warning(mailbox, 0, "Cannot load data to send, maybe the message is deleted in between."); dc_log_warning(mailbox, 0, "Cannot load data to send, maybe the message is deleted in between.");
goto cleanup; /* no redo, no IMAP - there won't be more recipients next time (as the data does not exist, there is no need in calling mark_as_error()) */ goto cleanup; /* no redo, no IMAP - there won't be more recipients next time (as the data does not exist, there is no need in calling mark_as_error()) */
@ -376,7 +376,7 @@ static void dc_job_do_DC_JOB_SEND_MSG_TO_SMTP(mrmailbox_t* mailbox, dc_job_t* jo
/* send message - it's okay if there are no recipients, this is a group with only OURSELF; we only upload to IMAP in this case */ /* send message - it's okay if there are no recipients, this is a group with only OURSELF; we only upload to IMAP in this case */
if( clist_count(mimefactory.m_recipients_addr) > 0 ) { if( clist_count(mimefactory.m_recipients_addr) > 0 ) {
if( !mrmimefactory_render(&mimefactory) ) { if( !dc_mimefactory_render(&mimefactory) ) {
mark_as_error(mailbox, mimefactory.m_msg); mark_as_error(mailbox, mimefactory.m_msg);
dc_log_error(mailbox, 0, "Empty message."); /* should not happen */ dc_log_error(mailbox, 0, "Empty message."); /* should not happen */
goto cleanup; /* no redo, no IMAP - there won't be more recipients next time. */ goto cleanup; /* no redo, no IMAP - there won't be more recipients next time. */
@ -397,11 +397,11 @@ static void dc_job_do_DC_JOB_SEND_MSG_TO_SMTP(mrmailbox_t* mailbox, dc_job_t* jo
} }
/* done */ /* done */
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
mrsqlite3_begin_transaction__(mailbox->m_sql); dc_sqlite3_begin_transaction__(mailbox->m_sql);
/* debug print? */ /* debug print? */
if( mrsqlite3_get_config_int__(mailbox->m_sql, "save_eml", 0) ) { if( dc_sqlite3_get_config_int__(mailbox->m_sql, "save_eml", 0) ) {
char* emlname = mr_mprintf("%s/to-smtp-%i.eml", mailbox->m_blobdir, (int)mimefactory.m_msg->m_id); char* emlname = mr_mprintf("%s/to-smtp-%i.eml", mailbox->m_blobdir, (int)mimefactory.m_msg->m_id);
FILE* emlfileob = fopen(emlname, "w"); FILE* emlfileob = fopen(emlname, "w");
if( emlfileob ) { if( emlfileob ) {
@ -416,7 +416,7 @@ static void dc_job_do_DC_JOB_SEND_MSG_TO_SMTP(mrmailbox_t* mailbox, dc_job_t* jo
mrmailbox_update_msg_state__(mailbox, mimefactory.m_msg->m_id, MR_STATE_OUT_DELIVERED); mrmailbox_update_msg_state__(mailbox, mimefactory.m_msg->m_id, MR_STATE_OUT_DELIVERED);
if( mimefactory.m_out_encrypted && mrparam_get_int(mimefactory.m_msg->m_param, MRP_GUARANTEE_E2EE, 0)==0 ) { if( mimefactory.m_out_encrypted && mrparam_get_int(mimefactory.m_msg->m_param, MRP_GUARANTEE_E2EE, 0)==0 ) {
mrparam_set_int(mimefactory.m_msg->m_param, MRP_GUARANTEE_E2EE, 1); /* can upgrade to E2EE - fine! */ mrparam_set_int(mimefactory.m_msg->m_param, MRP_GUARANTEE_E2EE, 1); /* can upgrade to E2EE - fine! */
mrmsg_save_param_to_disk__(mimefactory.m_msg); dc_msg_save_param_to_disk__(mimefactory.m_msg);
} }
if( (mailbox->m_imap->m_server_flags&MR_NO_EXTRA_IMAP_UPLOAD)==0 if( (mailbox->m_imap->m_server_flags&MR_NO_EXTRA_IMAP_UPLOAD)==0
@ -428,20 +428,20 @@ static void dc_job_do_DC_JOB_SEND_MSG_TO_SMTP(mrmailbox_t* mailbox, dc_job_t* jo
// TODO: add to keyhistory // TODO: add to keyhistory
mrmailbox_add_to_keyhistory__(mailbox, NULL, 0, NULL, NULL); mrmailbox_add_to_keyhistory__(mailbox, NULL, 0, NULL, NULL);
mrsqlite3_commit__(mailbox->m_sql); dc_sqlite3_commit__(mailbox->m_sql);
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
mailbox->m_cb(mailbox, DC_EVENT_MSG_DELIVERED, mimefactory.m_msg->m_chat_id, mimefactory.m_msg->m_id); mailbox->m_cb(mailbox, DC_EVENT_MSG_DELIVERED, mimefactory.m_msg->m_chat_id, mimefactory.m_msg->m_id);
cleanup: cleanup:
mrmimefactory_empty(&mimefactory); dc_mimefactory_empty(&mimefactory);
} }
static void dc_job_do_DC_JOB_SEND_MDN(mrmailbox_t* mailbox, dc_job_t* job) static void dc_job_do_DC_JOB_SEND_MDN(mrmailbox_t* mailbox, dc_job_t* job)
{ {
mrmimefactory_t mimefactory; dc_mimefactory_t mimefactory;
mrmimefactory_init(&mimefactory, mailbox); dc_mimefactory_init(&mimefactory, mailbox);
if( mailbox == NULL || mailbox->m_magic != MR_MAILBOX_MAGIC || job == NULL ) { if( mailbox == NULL || mailbox->m_magic != MR_MAILBOX_MAGIC || job == NULL ) {
return; return;
@ -451,9 +451,9 @@ static void dc_job_do_DC_JOB_SEND_MDN(mrmailbox_t* mailbox, dc_job_t* job)
if( !dc_smtp_is_connected(mailbox->m_smtp) ) if( !dc_smtp_is_connected(mailbox->m_smtp) )
{ {
dc_loginparam_t* loginparam = dc_loginparam_new(); dc_loginparam_t* loginparam = dc_loginparam_new();
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
dc_loginparam_read__(loginparam, mailbox->m_sql, "configured_"); dc_loginparam_read__(loginparam, mailbox->m_sql, "configured_");
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
int connected = dc_smtp_connect(mailbox->m_smtp, loginparam); int connected = dc_smtp_connect(mailbox->m_smtp, loginparam);
dc_loginparam_unref(loginparam); dc_loginparam_unref(loginparam);
if( !connected ) { if( !connected ) {
@ -462,8 +462,8 @@ static void dc_job_do_DC_JOB_SEND_MDN(mrmailbox_t* mailbox, dc_job_t* job)
} }
} }
if( !mrmimefactory_load_mdn(&mimefactory, job->m_foreign_id) if( !dc_mimefactory_load_mdn(&mimefactory, job->m_foreign_id)
|| !mrmimefactory_render(&mimefactory) ) { || !dc_mimefactory_render(&mimefactory) ) {
goto cleanup; goto cleanup;
} }
@ -476,7 +476,7 @@ static void dc_job_do_DC_JOB_SEND_MDN(mrmailbox_t* mailbox, dc_job_t* job)
} }
cleanup: cleanup:
mrmimefactory_empty(&mimefactory); dc_mimefactory_empty(&mimefactory);
} }
@ -526,7 +526,7 @@ void dc_job_add(mrmailbox_t* mailbox, int action, int foreign_id, const char* pa
return; return;
} }
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql,
"INSERT INTO jobs (added_timestamp, thread, action, foreign_id, param, desired_timestamp) VALUES (?,?,?,?,?,?);"); "INSERT INTO jobs (added_timestamp, thread, action, foreign_id, param, desired_timestamp) VALUES (?,?,?,?,?,?);");
sqlite3_bind_int64(stmt, 1, timestamp); sqlite3_bind_int64(stmt, 1, timestamp);
sqlite3_bind_int (stmt, 2, thread); sqlite3_bind_int (stmt, 2, thread);
@ -562,7 +562,7 @@ void dc_job_kill_actions(mrmailbox_t* mailbox, int action1, int action2)
return; return;
} }
sqlite3_stmt* stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, sqlite3_stmt* stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql,
"DELETE FROM jobs WHERE action=? OR action=?;"); "DELETE FROM jobs WHERE action=? OR action=?;");
sqlite3_bind_int(stmt, 1, action1); sqlite3_bind_int(stmt, 1, action1);
sqlite3_bind_int(stmt, 2, action2); sqlite3_bind_int(stmt, 2, action2);
@ -584,7 +584,7 @@ static void dc_job_perform(mrmailbox_t* mailbox, int thread)
goto cleanup; goto cleanup;
} }
select_stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, select_stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql,
"SELECT id, action, foreign_id, param FROM jobs WHERE thread=? AND desired_timestamp<=? ORDER BY action DESC, added_timestamp;"); "SELECT id, action, foreign_id, param FROM jobs WHERE thread=? AND desired_timestamp<=? ORDER BY action DESC, added_timestamp;");
sqlite3_bind_int64(select_stmt, 1, thread); sqlite3_bind_int64(select_stmt, 1, thread);
sqlite3_bind_int64(select_stmt, 2, time(NULL)); sqlite3_bind_int64(select_stmt, 2, time(NULL));
@ -627,7 +627,7 @@ static void dc_job_perform(mrmailbox_t* mailbox, int thread)
int tries = mrparam_get_int(job.m_param, MRP_TIMES, 0) + 1; int tries = mrparam_get_int(job.m_param, MRP_TIMES, 0) + 1;
mrparam_set_int(job.m_param, MRP_TIMES, tries); mrparam_set_int(job.m_param, MRP_TIMES, tries);
sqlite3_stmt* update_stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, sqlite3_stmt* update_stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql,
"UPDATE jobs SET desired_timestamp=0, param=? WHERE id=?;"); "UPDATE jobs SET desired_timestamp=0, param=? WHERE id=?;");
sqlite3_bind_text (update_stmt, 1, job.m_param->m_packed, -1, SQLITE_STATIC); sqlite3_bind_text (update_stmt, 1, job.m_param->m_packed, -1, SQLITE_STATIC);
sqlite3_bind_int (update_stmt, 2, job.m_job_id); sqlite3_bind_int (update_stmt, 2, job.m_job_id);
@ -648,7 +648,7 @@ static void dc_job_perform(mrmailbox_t* mailbox, int thread)
} }
else else
{ {
sqlite3_stmt* delete_stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, sqlite3_stmt* delete_stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql,
"DELETE FROM jobs WHERE id=?;"); "DELETE FROM jobs WHERE id=?;");
sqlite3_bind_int(delete_stmt, 1, job.m_job_id); sqlite3_bind_int(delete_stmt, 1, job.m_job_id);
sqlite3_step(delete_stmt); sqlite3_step(delete_stmt);

View file

@ -44,7 +44,7 @@ void mr_wipe_secret_mem(void* buf, size_t buf_bytes)
} }
static void mrkey_empty(mrkey_t* ths) /* only use before calling setters; take care when using this function together with reference counting, prefer new objects instead */ static void dc_key_empty(dc_key_t* ths) /* only use before calling setters; take care when using this function together with reference counting, prefer new objects instead */
{ {
if( ths == NULL ) { if( ths == NULL ) {
return; return;
@ -61,11 +61,11 @@ static void mrkey_empty(mrkey_t* ths) /* only use before calling setters; take c
} }
mrkey_t* mrkey_new() dc_key_t* dc_key_new()
{ {
mrkey_t* ths; dc_key_t* ths;
if( (ths=calloc(1, sizeof(mrkey_t)))==NULL ) { if( (ths=calloc(1, sizeof(dc_key_t)))==NULL ) {
exit(44); /* cannot allocate little memory, unrecoverable error */ exit(44); /* cannot allocate little memory, unrecoverable error */
} }
ths->_m_heap_refcnt = 1; ths->_m_heap_refcnt = 1;
@ -73,7 +73,7 @@ mrkey_t* mrkey_new()
} }
mrkey_t* mrkey_ref(mrkey_t* ths) dc_key_t* dc_key_ref(dc_key_t* ths)
{ {
if( ths==NULL ) { if( ths==NULL ) {
return NULL; return NULL;
@ -83,7 +83,7 @@ mrkey_t* mrkey_ref(mrkey_t* ths)
} }
void mrkey_unref(mrkey_t* ths) void dc_key_unref(dc_key_t* ths)
{ {
if( ths==NULL ) { if( ths==NULL ) {
return; return;
@ -94,14 +94,14 @@ void mrkey_unref(mrkey_t* ths)
return; return;
} }
mrkey_empty(ths); dc_key_empty(ths);
free(ths); free(ths);
} }
int mrkey_set_from_binary(mrkey_t* ths, const void* data, int bytes, int type) int dc_key_set_from_binary(dc_key_t* ths, const void* data, int bytes, int type)
{ {
mrkey_empty(ths); dc_key_empty(ths);
if( ths==NULL || data==NULL || bytes <= 0 ) { if( ths==NULL || data==NULL || bytes <= 0 ) {
return 0; return 0;
} }
@ -116,32 +116,32 @@ int mrkey_set_from_binary(mrkey_t* ths, const void* data, int bytes, int type)
} }
int mrkey_set_from_key(mrkey_t* ths, const mrkey_t* o) int dc_key_set_from_key(dc_key_t* ths, const dc_key_t* o)
{ {
mrkey_empty(ths); dc_key_empty(ths);
if( ths==NULL || o==NULL ) { if( ths==NULL || o==NULL ) {
return 0; return 0;
} }
return mrkey_set_from_binary(ths, o->m_binary, o->m_bytes, o->m_type); return dc_key_set_from_binary(ths, o->m_binary, o->m_bytes, o->m_type);
} }
int mrkey_set_from_stmt(mrkey_t* ths, sqlite3_stmt* stmt, int index, int type) int dc_key_set_from_stmt(dc_key_t* ths, sqlite3_stmt* stmt, int index, int type)
{ {
mrkey_empty(ths); dc_key_empty(ths);
if( ths==NULL || stmt==NULL ) { if( ths==NULL || stmt==NULL ) {
return 0; return 0;
} }
return mrkey_set_from_binary(ths, (unsigned char*)sqlite3_column_blob(stmt, index), sqlite3_column_bytes(stmt, index), type); return dc_key_set_from_binary(ths, (unsigned char*)sqlite3_column_blob(stmt, index), sqlite3_column_bytes(stmt, index), type);
} }
int mrkey_set_from_base64(mrkey_t* ths, const char* base64, int type) int dc_key_set_from_base64(dc_key_t* ths, const char* base64, int type)
{ {
size_t indx = 0, result_len = 0; size_t indx = 0, result_len = 0;
char* result = NULL; char* result = NULL;
mrkey_empty(ths); dc_key_empty(ths);
if( ths==NULL || base64==NULL ) { if( ths==NULL || base64==NULL ) {
return 0; return 0;
@ -152,21 +152,21 @@ int mrkey_set_from_base64(mrkey_t* ths, const char* base64, int type)
return 0; /* bad key */ return 0; /* bad key */
} }
mrkey_set_from_binary(ths, result, result_len, type); dc_key_set_from_binary(ths, result, result_len, type);
mmap_string_unref(result); mmap_string_unref(result);
return 1; return 1;
} }
int mrkey_set_from_file(mrkey_t* ths, const char* pathNfilename, mrmailbox_t* mailbox) int dc_key_set_from_file(dc_key_t* ths, const char* pathNfilename, mrmailbox_t* mailbox)
{ {
char* buf = NULL; char* buf = NULL;
const char *headerline, *base64; // just pointers inside buf, must not be freed const char *headerline, *base64; // just pointers inside buf, must not be freed
size_t buf_bytes; size_t buf_bytes;
int type = -1, success = 0; int type = -1, success = 0;
mrkey_empty(ths); dc_key_empty(ths);
if( ths==NULL || pathNfilename==NULL ) { if( ths==NULL || pathNfilename==NULL ) {
goto cleanup; goto cleanup;
@ -177,7 +177,7 @@ int mrkey_set_from_file(mrkey_t* ths, const char* pathNfilename, mrmailbox_t* ma
goto cleanup; /* error is already loged */ goto cleanup; /* error is already loged */
} }
if( !mr_split_armored_data(buf, &headerline, NULL, NULL, &base64) if( !dc_split_armored_data(buf, &headerline, NULL, NULL, &base64)
|| headerline == NULL || base64 == NULL ) { || headerline == NULL || base64 == NULL ) {
goto cleanup; goto cleanup;
} }
@ -193,7 +193,7 @@ int mrkey_set_from_file(mrkey_t* ths, const char* pathNfilename, mrmailbox_t* ma
goto cleanup; goto cleanup;
} }
if( !mrkey_set_from_base64(ths, base64, type) ) { if( !dc_key_set_from_base64(ths, base64, type) ) {
dc_log_warning(mailbox, 0, "Bad data in key \"%s\".", pathNfilename); dc_log_warning(mailbox, 0, "Bad data in key \"%s\".", pathNfilename);
goto cleanup; goto cleanup;
} }
@ -206,7 +206,7 @@ cleanup:
} }
int mrkey_equals(const mrkey_t* ths, const mrkey_t* o) int dc_key_equals(const dc_key_t* ths, const dc_key_t* o)
{ {
if( ths==NULL || o==NULL if( ths==NULL || o==NULL
|| ths->m_binary==NULL || ths->m_bytes<=0 || o->m_binary==NULL || o->m_bytes<=0 ) { || ths->m_binary==NULL || ths->m_bytes<=0 || o->m_binary==NULL || o->m_bytes<=0 ) {
@ -230,7 +230,7 @@ int mrkey_equals(const mrkey_t* ths, const mrkey_t* o)
******************************************************************************/ ******************************************************************************/
int mrkey_save_self_keypair__(const mrkey_t* public_key, const mrkey_t* private_key, const char* addr, int is_default, mrsqlite3_t* sql) int dc_key_save_self_keypair__(const dc_key_t* public_key, const dc_key_t* private_key, const char* addr, int is_default, dc_sqlite3_t* sql)
{ {
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
@ -239,7 +239,7 @@ int mrkey_save_self_keypair__(const mrkey_t* public_key, const mrkey_t* private_
return 0; return 0;
} }
stmt = mrsqlite3_predefine__(sql, INSERT_INTO_keypairs_aippc, stmt = dc_sqlite3_predefine__(sql, INSERT_INTO_keypairs_aippc,
"INSERT INTO keypairs (addr, is_default, public_key, private_key, created) VALUES (?,?,?,?,?);"); "INSERT INTO keypairs (addr, is_default, public_key, private_key, created) VALUES (?,?,?,?,?);");
sqlite3_bind_text (stmt, 1, addr, -1, SQLITE_STATIC); sqlite3_bind_text (stmt, 1, addr, -1, SQLITE_STATIC);
sqlite3_bind_int (stmt, 2, is_default); sqlite3_bind_int (stmt, 2, is_default);
@ -254,7 +254,7 @@ int mrkey_save_self_keypair__(const mrkey_t* public_key, const mrkey_t* private_
} }
int mrkey_load_self_public__(mrkey_t* ths, const char* self_addr, mrsqlite3_t* sql) int dc_key_load_self_public__(dc_key_t* ths, const char* self_addr, dc_sqlite3_t* sql)
{ {
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
@ -262,19 +262,19 @@ int mrkey_load_self_public__(mrkey_t* ths, const char* self_addr, mrsqlite3_t* s
return 0; return 0;
} }
mrkey_empty(ths); dc_key_empty(ths);
stmt = mrsqlite3_predefine__(sql, SELECT_public_key_FROM_keypairs_WHERE_default, stmt = dc_sqlite3_predefine__(sql, SELECT_public_key_FROM_keypairs_WHERE_default,
"SELECT public_key FROM keypairs WHERE addr=? AND is_default=1;"); "SELECT public_key FROM keypairs WHERE addr=? AND is_default=1;");
sqlite3_bind_text (stmt, 1, self_addr, -1, SQLITE_STATIC); sqlite3_bind_text (stmt, 1, self_addr, -1, SQLITE_STATIC);
if( sqlite3_step(stmt) != SQLITE_ROW ) { if( sqlite3_step(stmt) != SQLITE_ROW ) {
return 0; return 0;
} }
mrkey_set_from_stmt(ths, stmt, 0, MR_PUBLIC); dc_key_set_from_stmt(ths, stmt, 0, MR_PUBLIC);
return 1; return 1;
} }
int mrkey_load_self_private__(mrkey_t* ths, const char* self_addr, mrsqlite3_t* sql) int dc_key_load_self_private__(dc_key_t* ths, const char* self_addr, dc_sqlite3_t* sql)
{ {
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
@ -282,14 +282,14 @@ int mrkey_load_self_private__(mrkey_t* ths, const char* self_addr, mrsqlite3_t*
return 0; return 0;
} }
mrkey_empty(ths); dc_key_empty(ths);
stmt = mrsqlite3_predefine__(sql, SELECT_private_key_FROM_keypairs_WHERE_default, stmt = dc_sqlite3_predefine__(sql, SELECT_private_key_FROM_keypairs_WHERE_default,
"SELECT private_key FROM keypairs WHERE addr=? AND is_default=1;"); "SELECT private_key FROM keypairs WHERE addr=? AND is_default=1;");
sqlite3_bind_text (stmt, 1, self_addr, -1, SQLITE_STATIC); sqlite3_bind_text (stmt, 1, self_addr, -1, SQLITE_STATIC);
if( sqlite3_step(stmt) != SQLITE_ROW ) { if( sqlite3_step(stmt) != SQLITE_ROW ) {
return 0; return 0;
} }
mrkey_set_from_stmt(ths, stmt, 0, MR_PRIVATE); dc_key_set_from_stmt(ths, stmt, 0, MR_PRIVATE);
return 1; return 1;
} }
@ -369,7 +369,7 @@ cleanup:
} }
char* mrkey_render_base64(const mrkey_t* ths, int break_every, const char* break_chars, int add_checksum) char* dc_key_render_base64(const dc_key_t* ths, int break_every, const char* break_chars, int add_checksum)
{ {
if( ths==NULL ) { if( ths==NULL ) {
return NULL; return NULL;
@ -378,7 +378,7 @@ char* mrkey_render_base64(const mrkey_t* ths, int break_every, const char* break
} }
char* mrkey_render_asc(const mrkey_t* ths, const char* add_header_lines /*must be terminated by \r\n*/) char* dc_key_render_asc(const dc_key_t* ths, const char* add_header_lines /*must be terminated by \r\n*/)
{ {
/* see RFC 4880, 6.2. Forming ASCII Armor, https://tools.ietf.org/html/rfc4880#section-6.2 */ /* see RFC 4880, 6.2. Forming ASCII Armor, https://tools.ietf.org/html/rfc4880#section-6.2 */
char *base64 = NULL, *ret = NULL; char *base64 = NULL, *ret = NULL;
@ -387,7 +387,7 @@ char* mrkey_render_asc(const mrkey_t* ths, const char* add_header_lines /*must b
goto cleanup; goto cleanup;
} }
if( (base64=mrkey_render_base64(ths, 76, "\r\n", 2/*checksum in new line*/))==NULL ) { /* RFC: The encoded output stream must be represented in lines of no more than 76 characters each. */ if( (base64=dc_key_render_base64(ths, 76, "\r\n", 2/*checksum in new line*/))==NULL ) { /* RFC: The encoded output stream must be represented in lines of no more than 76 characters each. */
goto cleanup; goto cleanup;
} }
@ -403,7 +403,7 @@ cleanup:
} }
int mrkey_render_asc_to_file(const mrkey_t* key, const char* file, mrmailbox_t* mailbox /* for logging only */) int dc_key_render_asc_to_file(const dc_key_t* key, const char* file, mrmailbox_t* mailbox /* for logging only */)
{ {
int success = 0; int success = 0;
char* file_content = NULL; char* file_content = NULL;
@ -412,7 +412,7 @@ int mrkey_render_asc_to_file(const mrkey_t* key, const char* file, mrmailbox_t*
goto cleanup; goto cleanup;
} }
file_content = mrkey_render_asc(key, NULL); file_content = dc_key_render_asc(key, NULL);
if( file_content == NULL ) { if( file_content == NULL ) {
goto cleanup; goto cleanup;
} }
@ -475,7 +475,7 @@ char* mr_normalize_fingerprint(const char* in)
} }
char* mrkey_get_fingerprint(const mrkey_t* key) char* dc_key_get_fingerprint(const dc_key_t* key)
{ {
uint8_t* fingerprint_buf = NULL; uint8_t* fingerprint_buf = NULL;
size_t fingerprint_bytes = 0; size_t fingerprint_bytes = 0;
@ -485,7 +485,7 @@ char* mrkey_get_fingerprint(const mrkey_t* key)
goto cleanup; goto cleanup;
} }
if( !mrpgp_calc_fingerprint(key, &fingerprint_buf, &fingerprint_bytes) ) { if( !dc_pgp_calc_fingerprint(key, &fingerprint_buf, &fingerprint_bytes) ) {
goto cleanup; goto cleanup;
} }
@ -497,9 +497,9 @@ cleanup:
} }
char* mrkey_get_formatted_fingerprint(const mrkey_t* key) char* dc_key_get_formatted_fingerprint(const dc_key_t* key)
{ {
char* rawhex = mrkey_get_fingerprint(key); char* rawhex = dc_key_get_fingerprint(key);
char* formatted = mr_format_fingerprint(rawhex); char* formatted = mr_format_fingerprint(rawhex);
free(rawhex); free(rawhex);
return formatted; return formatted;

View file

@ -37,42 +37,42 @@ typedef struct sqlite3_stmt sqlite3_stmt;
/** /**
* Library-internal. * Library-internal.
*/ */
typedef struct mrkey_t typedef struct dc_key_t
{ {
void* m_binary; void* m_binary;
int m_bytes; int m_bytes;
int m_type; int m_type;
/** @privatesection */ /** @privatesection */
int _m_heap_refcnt; /* !=0 for objects created with mrkey_new(), 0 for stack objects */ int _m_heap_refcnt; /* !=0 for objects created with dc_key_new(), 0 for stack objects */
} mrkey_t; } dc_key_t;
mrkey_t* mrkey_new (); dc_key_t* dc_key_new ();
mrkey_t* mrkey_ref (mrkey_t*); dc_key_t* dc_key_ref (dc_key_t*);
void mrkey_unref (mrkey_t*); void dc_key_unref (dc_key_t*);
int mrkey_set_from_binary (mrkey_t*, const void* data, int bytes, int type); int dc_key_set_from_binary (dc_key_t*, const void* data, int bytes, int type);
int mrkey_set_from_key (mrkey_t*, const mrkey_t*); int dc_key_set_from_key (dc_key_t*, const dc_key_t*);
int mrkey_set_from_stmt (mrkey_t*, sqlite3_stmt*, int index, int type); int dc_key_set_from_stmt (dc_key_t*, sqlite3_stmt*, int index, int type);
int mrkey_set_from_base64 (mrkey_t*, const char* base64, int type); int dc_key_set_from_base64 (dc_key_t*, const char* base64, int type);
int mrkey_set_from_file (mrkey_t*, const char* file, mrmailbox_t* mailbox); int dc_key_set_from_file (dc_key_t*, const char* file, mrmailbox_t* mailbox);
int mrkey_equals (const mrkey_t*, const mrkey_t*); int dc_key_equals (const dc_key_t*, const dc_key_t*);
int mrkey_save_self_keypair__(const mrkey_t* public_key, const mrkey_t* private_key, const char* addr, int is_default, mrsqlite3_t* sql); int dc_key_save_self_keypair__(const dc_key_t* public_key, const dc_key_t* private_key, const char* addr, int is_default, dc_sqlite3_t* sql);
int mrkey_load_self_public__ (mrkey_t*, const char* self_addr, mrsqlite3_t* sql); int dc_key_load_self_public__ (dc_key_t*, const char* self_addr, dc_sqlite3_t* sql);
int mrkey_load_self_private__(mrkey_t*, const char* self_addr, mrsqlite3_t* sql); int dc_key_load_self_private__(dc_key_t*, const char* self_addr, dc_sqlite3_t* sql);
char* mr_render_base64 (const void* buf, size_t buf_bytes, int break_every, const char* break_chars, int add_checksum); /* the result must be freed */ char* mr_render_base64 (const void* buf, size_t buf_bytes, int break_every, const char* break_chars, int add_checksum); /* the result must be freed */
char* mrkey_render_base64(const mrkey_t* ths, int break_every, const char* break_chars, int add_checksum); /* the result must be freed */ char* dc_key_render_base64(const dc_key_t* ths, int break_every, const char* break_chars, int add_checksum); /* the result must be freed */
char* mrkey_render_asc (const mrkey_t*, const char* add_header_lines); /* each header line must be terminated by \r\n, the result must be freed */ char* dc_key_render_asc (const dc_key_t*, const char* add_header_lines); /* each header line must be terminated by \r\n, the result must be freed */
int mrkey_render_asc_to_file(const mrkey_t*, const char* file, mrmailbox_t* mailbox); int dc_key_render_asc_to_file(const dc_key_t*, const char* file, mrmailbox_t* mailbox);
char* mr_format_fingerprint (const char*); char* mr_format_fingerprint (const char*);
char* mr_normalize_fingerprint (const char*); char* mr_normalize_fingerprint (const char*);
char* mrkey_get_fingerprint (const mrkey_t*); char* dc_key_get_fingerprint (const dc_key_t*);
char* mrkey_get_formatted_fingerprint(const mrkey_t*); char* dc_key_get_formatted_fingerprint(const dc_key_t*);
void mr_wipe_secret_mem(void* buf, size_t buf_bytes); void mr_wipe_secret_mem(void* buf, size_t buf_bytes);

View file

@ -32,18 +32,18 @@
******************************************************************************/ ******************************************************************************/
mrkeyring_t* mrkeyring_new() dc_keyring_t* dc_keyring_new()
{ {
mrkeyring_t* ths; dc_keyring_t* ths;
if( (ths=calloc(1, sizeof(mrkeyring_t)))==NULL ) { if( (ths=calloc(1, sizeof(dc_keyring_t)))==NULL ) {
exit(42); /* cannot allocate little memory, unrecoverable error */ exit(42); /* cannot allocate little memory, unrecoverable error */
} }
return ths; return ths;
} }
void mrkeyring_unref(mrkeyring_t* ths) void dc_keyring_unref(dc_keyring_t* ths)
{ {
int i; int i;
if( ths == NULL ) { if( ths == NULL ) {
@ -51,14 +51,14 @@ void mrkeyring_unref(mrkeyring_t* ths)
} }
for( i = 0; i < ths->m_count; i++ ) { for( i = 0; i < ths->m_count; i++ ) {
mrkey_unref(ths->m_keys[i]); dc_key_unref(ths->m_keys[i]);
} }
free(ths->m_keys); free(ths->m_keys);
free(ths); free(ths);
} }
void mrkeyring_add(mrkeyring_t* ths, mrkey_t* to_add) void dc_keyring_add(dc_keyring_t* ths, dc_key_t* to_add)
{ {
if( ths==NULL || to_add==NULL ) { if( ths==NULL || to_add==NULL ) {
return; return;
@ -67,35 +67,35 @@ void mrkeyring_add(mrkeyring_t* ths, mrkey_t* to_add)
/* expand array, if needed */ /* expand array, if needed */
if( ths->m_count == ths->m_allocated ) { if( ths->m_count == ths->m_allocated ) {
int newsize = (ths->m_allocated * 2) + 10; int newsize = (ths->m_allocated * 2) + 10;
if( (ths->m_keys=realloc(ths->m_keys, newsize*sizeof(mrkey_t*)))==NULL ) { if( (ths->m_keys=realloc(ths->m_keys, newsize*sizeof(dc_key_t*)))==NULL ) {
exit(41); exit(41);
} }
ths->m_allocated = newsize; ths->m_allocated = newsize;
} }
ths->m_keys[ths->m_count] = mrkey_ref(to_add); ths->m_keys[ths->m_count] = dc_key_ref(to_add);
ths->m_count++; ths->m_count++;
} }
int mrkeyring_load_self_private_for_decrypting__(mrkeyring_t* ths, const char* self_addr, mrsqlite3_t* sql) int dc_keyring_load_self_private_for_decrypting__(dc_keyring_t* ths, const char* self_addr, dc_sqlite3_t* sql)
{ {
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
mrkey_t* key; dc_key_t* key;
if( ths==NULL || self_addr==NULL || sql==NULL ) { if( ths==NULL || self_addr==NULL || sql==NULL ) {
return 0; return 0;
} }
stmt = mrsqlite3_predefine__(sql, SELECT_private_key_FROM_keypairs_ORDER_BY_default, stmt = dc_sqlite3_predefine__(sql, SELECT_private_key_FROM_keypairs_ORDER_BY_default,
"SELECT private_key FROM keypairs ORDER BY addr=? DESC, is_default DESC;"); "SELECT private_key FROM keypairs ORDER BY addr=? DESC, is_default DESC;");
sqlite3_bind_text (stmt, 1, self_addr, -1, SQLITE_STATIC); sqlite3_bind_text (stmt, 1, self_addr, -1, SQLITE_STATIC);
while( sqlite3_step(stmt) == SQLITE_ROW ) { while( sqlite3_step(stmt) == SQLITE_ROW ) {
key = mrkey_new(); key = dc_key_new();
if( mrkey_set_from_stmt(key, stmt, 0, MR_PRIVATE) ) { if( dc_key_set_from_stmt(key, stmt, 0, MR_PRIVATE) ) {
mrkeyring_add(ths, key); dc_keyring_add(ths, key);
} }
mrkey_unref(key); /* unref in any case, mrkeyring_add() adds its own reference */ dc_key_unref(key); /* unref in any case, dc_keyring_add() adds its own reference */
} }
return 1; return 1;

View file

@ -27,27 +27,27 @@ extern "C" {
#endif #endif
typedef struct mrkey_t mrkey_t; typedef struct dc_key_t dc_key_t;
/** /**
* Library-internal. * Library-internal.
*/ */
typedef struct mrkeyring_t typedef struct dc_keyring_t
{ {
/** @privatesection */ /** @privatesection */
mrkey_t** m_keys; /**< Keys in the keyring. Only pointers to keys, the caller is responsible for freeing them and should make sure, the pointers are valid as long as the keyring is valid. */ dc_key_t** m_keys; /**< Keys in the keyring. Only pointers to keys, the caller is responsible for freeing them and should make sure, the pointers are valid as long as the keyring is valid. */
int m_count; int m_count;
int m_allocated; int m_allocated;
} mrkeyring_t; } dc_keyring_t;
mrkeyring_t* mrkeyring_new (); dc_keyring_t* dc_keyring_new ();
void mrkeyring_unref(); void dc_keyring_unref();
void mrkeyring_add (mrkeyring_t*, mrkey_t*); /* the reference counter of the key is increased by one */ void dc_keyring_add (dc_keyring_t*, dc_key_t*); /* the reference counter of the key is increased by one */
int mrkeyring_load_self_private_for_decrypting__(mrkeyring_t*, const char* self_addr, mrsqlite3_t* sql); int dc_keyring_load_self_private_for_decrypting__(dc_keyring_t*, const char* self_addr, dc_sqlite3_t* sql);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -71,48 +71,48 @@ void dc_loginparam_empty(dc_loginparam_t* ths)
} }
void dc_loginparam_read__(dc_loginparam_t* ths, mrsqlite3_t* sql, const char* prefix) void dc_loginparam_read__(dc_loginparam_t* ths, dc_sqlite3_t* sql, const char* prefix)
{ {
char* key = NULL; char* key = NULL;
#define MR_PREFIX(a) sqlite3_free(key); key=sqlite3_mprintf("%s%s", prefix, (a)); #define MR_PREFIX(a) sqlite3_free(key); key=sqlite3_mprintf("%s%s", prefix, (a));
dc_loginparam_empty(ths); dc_loginparam_empty(ths);
MR_PREFIX("addr"); ths->m_addr = mrsqlite3_get_config__ (sql, key, NULL); MR_PREFIX("addr"); ths->m_addr = dc_sqlite3_get_config__ (sql, key, NULL);
MR_PREFIX("mail_server"); ths->m_mail_server = mrsqlite3_get_config__ (sql, key, NULL); MR_PREFIX("mail_server"); ths->m_mail_server = dc_sqlite3_get_config__ (sql, key, NULL);
MR_PREFIX("mail_port"); ths->m_mail_port = mrsqlite3_get_config_int__(sql, key, 0); MR_PREFIX("mail_port"); ths->m_mail_port = dc_sqlite3_get_config_int__(sql, key, 0);
MR_PREFIX("mail_user"); ths->m_mail_user = mrsqlite3_get_config__ (sql, key, NULL); MR_PREFIX("mail_user"); ths->m_mail_user = dc_sqlite3_get_config__ (sql, key, NULL);
MR_PREFIX("mail_pw"); ths->m_mail_pw = mrsqlite3_get_config__ (sql, key, NULL); MR_PREFIX("mail_pw"); ths->m_mail_pw = dc_sqlite3_get_config__ (sql, key, NULL);
MR_PREFIX("send_server"); ths->m_send_server = mrsqlite3_get_config__ (sql, key, NULL); MR_PREFIX("send_server"); ths->m_send_server = dc_sqlite3_get_config__ (sql, key, NULL);
MR_PREFIX("send_port"); ths->m_send_port = mrsqlite3_get_config_int__(sql, key, 0); MR_PREFIX("send_port"); ths->m_send_port = dc_sqlite3_get_config_int__(sql, key, 0);
MR_PREFIX("send_user"); ths->m_send_user = mrsqlite3_get_config__ (sql, key, NULL); MR_PREFIX("send_user"); ths->m_send_user = dc_sqlite3_get_config__ (sql, key, NULL);
MR_PREFIX("send_pw"); ths->m_send_pw = mrsqlite3_get_config__ (sql, key, NULL); MR_PREFIX("send_pw"); ths->m_send_pw = dc_sqlite3_get_config__ (sql, key, NULL);
MR_PREFIX("server_flags");ths->m_server_flags= mrsqlite3_get_config_int__(sql, key, 0); MR_PREFIX("server_flags");ths->m_server_flags= dc_sqlite3_get_config_int__(sql, key, 0);
sqlite3_free(key); sqlite3_free(key);
} }
void dc_loginparam_write__(const dc_loginparam_t* ths, mrsqlite3_t* sql, const char* prefix) void dc_loginparam_write__(const dc_loginparam_t* ths, dc_sqlite3_t* sql, const char* prefix)
{ {
char* key = NULL; char* key = NULL;
MR_PREFIX("addr"); mrsqlite3_set_config__ (sql, key, ths->m_addr); MR_PREFIX("addr"); dc_sqlite3_set_config__ (sql, key, ths->m_addr);
MR_PREFIX("mail_server"); mrsqlite3_set_config__ (sql, key, ths->m_mail_server); MR_PREFIX("mail_server"); dc_sqlite3_set_config__ (sql, key, ths->m_mail_server);
MR_PREFIX("mail_port"); mrsqlite3_set_config_int__(sql, key, ths->m_mail_port); MR_PREFIX("mail_port"); dc_sqlite3_set_config_int__(sql, key, ths->m_mail_port);
MR_PREFIX("mail_user"); mrsqlite3_set_config__ (sql, key, ths->m_mail_user); MR_PREFIX("mail_user"); dc_sqlite3_set_config__ (sql, key, ths->m_mail_user);
MR_PREFIX("mail_pw"); mrsqlite3_set_config__ (sql, key, ths->m_mail_pw); MR_PREFIX("mail_pw"); dc_sqlite3_set_config__ (sql, key, ths->m_mail_pw);
MR_PREFIX("send_server"); mrsqlite3_set_config__ (sql, key, ths->m_send_server); MR_PREFIX("send_server"); dc_sqlite3_set_config__ (sql, key, ths->m_send_server);
MR_PREFIX("send_port"); mrsqlite3_set_config_int__(sql, key, ths->m_send_port); MR_PREFIX("send_port"); dc_sqlite3_set_config_int__(sql, key, ths->m_send_port);
MR_PREFIX("send_user"); mrsqlite3_set_config__ (sql, key, ths->m_send_user); MR_PREFIX("send_user"); dc_sqlite3_set_config__ (sql, key, ths->m_send_user);
MR_PREFIX("send_pw"); mrsqlite3_set_config__ (sql, key, ths->m_send_pw); MR_PREFIX("send_pw"); dc_sqlite3_set_config__ (sql, key, ths->m_send_pw);
MR_PREFIX("server_flags"); mrsqlite3_set_config_int__(sql, key, ths->m_server_flags); MR_PREFIX("server_flags"); dc_sqlite3_set_config_int__(sql, key, ths->m_server_flags);
sqlite3_free(key); sqlite3_free(key);
} }

View file

@ -72,8 +72,8 @@ typedef struct dc_loginparam_t
dc_loginparam_t* dc_loginparam_new (); dc_loginparam_t* dc_loginparam_new ();
void dc_loginparam_unref (dc_loginparam_t*); void dc_loginparam_unref (dc_loginparam_t*);
void dc_loginparam_empty (dc_loginparam_t*); /* clears all data and frees its memory. All pointers are NULL after this function is called. */ void dc_loginparam_empty (dc_loginparam_t*); /* clears all data and frees its memory. All pointers are NULL after this function is called. */
void dc_loginparam_read__ (dc_loginparam_t*, mrsqlite3_t*, const char* prefix); void dc_loginparam_read__ (dc_loginparam_t*, dc_sqlite3_t*, const char* prefix);
void dc_loginparam_write__ (const dc_loginparam_t*, mrsqlite3_t*, const char* prefix); void dc_loginparam_write__ (const dc_loginparam_t*, dc_sqlite3_t*, const char* prefix);
char* dc_loginparam_get_readable (const dc_loginparam_t*); char* dc_loginparam_get_readable (const dc_loginparam_t*);

View file

@ -26,11 +26,11 @@
#define MR_LOT_MAGIC 0x00107107 #define MR_LOT_MAGIC 0x00107107
mrlot_t* mrlot_new() dc_lot_t* dc_lot_new()
{ {
mrlot_t* ths = NULL; dc_lot_t* ths = NULL;
if( (ths=calloc(1, sizeof(mrlot_t)))==NULL ) { if( (ths=calloc(1, sizeof(dc_lot_t)))==NULL ) {
exit(27); /* cannot allocate little memory, unrecoverable error */ exit(27); /* cannot allocate little memory, unrecoverable error */
} }
@ -59,13 +59,13 @@ void dc_lot_unref(dc_lot_t* set)
return; return;
} }
mrlot_empty(set); dc_lot_empty(set);
set->m_magic = 0; set->m_magic = 0;
free(set); free(set);
} }
void mrlot_empty(mrlot_t* ths) void dc_lot_empty(dc_lot_t* ths)
{ {
if( ths == NULL || ths->m_magic != MR_LOT_MAGIC ) { if( ths == NULL || ths->m_magic != MR_LOT_MAGIC ) {
return; return;
@ -203,7 +203,7 @@ time_t dc_lot_get_timestamp(dc_lot_t* lot)
} }
void mrlot_fill(mrlot_t* ths, const mrmsg_t* msg, const mrchat_t* chat, const mrcontact_t* contact) void dc_lot_fill(dc_lot_t* ths, const dc_msg_t* msg, const dc_chat_t* chat, const dc_contact_t* contact)
{ {
if( ths == NULL || ths->m_magic != MR_LOT_MAGIC || msg == NULL ) { if( ths == NULL || ths->m_magic != MR_LOT_MAGIC || msg == NULL ) {
return; return;
@ -211,7 +211,7 @@ void mrlot_fill(mrlot_t* ths, const mrmsg_t* msg, const mrchat_t* chat, const mr
if( msg->m_from_id == MR_CONTACT_ID_SELF ) if( msg->m_from_id == MR_CONTACT_ID_SELF )
{ {
if( mrmsg_is_info(msg) ) { if( dc_msg_is_info(msg) ) {
ths->m_text1 = NULL; ths->m_text1 = NULL;
ths->m_text1_meaning = 0; ths->m_text1_meaning = 0;
} }
@ -227,17 +227,17 @@ void mrlot_fill(mrlot_t* ths, const mrmsg_t* msg, const mrchat_t* chat, const mr
} }
else if( MR_CHAT_TYPE_IS_MULTI(chat->m_type) ) else if( MR_CHAT_TYPE_IS_MULTI(chat->m_type) )
{ {
if( mrmsg_is_info(msg) || contact==NULL ) { if( dc_msg_is_info(msg) || contact==NULL ) {
ths->m_text1 = NULL; ths->m_text1 = NULL;
ths->m_text1_meaning = 0; ths->m_text1_meaning = 0;
} }
else { else {
ths->m_text1 = mrcontact_get_first_name(contact); ths->m_text1 = dc_contact_get_first_name(contact);
ths->m_text1_meaning = MR_TEXT1_USERNAME; ths->m_text1_meaning = MR_TEXT1_USERNAME;
} }
} }
ths->m_text2 = mrmsg_get_summarytext_by_raw(msg->m_type, msg->m_text, msg->m_param, MR_SUMMARY_CHARACTERS); ths->m_text2 = dc_msg_get_summarytext_by_raw(msg->m_type, msg->m_text, msg->m_param, MR_SUMMARY_CHARACTERS);
ths->m_timestamp = mrmsg_get_timestamp(msg); ths->m_timestamp = dc_msg_get_timestamp(msg);
ths->m_state = msg->m_state; ths->m_state = msg->m_state;
} }

View file

@ -33,8 +33,8 @@ struct _dc_lot
/** @privatesection */ /** @privatesection */
uint32_t m_magic; /**< The magic is used to avoid passing structures of different types. */ uint32_t m_magic; /**< The magic is used to avoid passing structures of different types. */
int m_text1_meaning; /**< The meaning of this value is defined by the creator of the object. 0 if not applicable. */ int m_text1_meaning; /**< The meaning of this value is defined by the creator of the object. 0 if not applicable. */
char* m_text1; /**< The meaning of this string is defined by the creator of the object. The string is freed with mrlot_unref(). NULL if not applicable. */ char* m_text1; /**< The meaning of this string is defined by the creator of the object. The string is freed with dc_lot_unref(). NULL if not applicable. */
char* m_text2; /**< The meaning of this string is defined by the creator of the object. The string is freed with mrlot_unref(). NULL if not applicable. */ char* m_text2; /**< The meaning of this string is defined by the creator of the object. The string is freed with dc_lot_unref(). NULL if not applicable. */
time_t m_timestamp; /**< The meaning of this value is defined by the creator of the object. 0 if not applicable. */ time_t m_timestamp; /**< The meaning of this value is defined by the creator of the object. 0 if not applicable. */
int m_state; /**< The meaning of this value is defined by the creator of the object. 0 if not applicable. */ int m_state; /**< The meaning of this value is defined by the creator of the object. 0 if not applicable. */
@ -48,7 +48,7 @@ struct _dc_lot
/* library-internal */ /* library-internal */
#define MR_SUMMARY_CHARACTERS 160 /* in practice, the user additionally cuts the string himself pixel-accurate */ #define MR_SUMMARY_CHARACTERS 160 /* in practice, the user additionally cuts the string himself pixel-accurate */
void mrlot_fill (mrlot_t*, const mrmsg_t*, const mrchat_t*, const mrcontact_t*); void dc_lot_fill (dc_lot_t*, const dc_msg_t*, const dc_chat_t*, const dc_contact_t*);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -34,18 +34,18 @@
******************************************************************************/ ******************************************************************************/
void mrmimefactory_init(mrmimefactory_t* factory, mrmailbox_t* mailbox) void dc_mimefactory_init(dc_mimefactory_t* factory, mrmailbox_t* mailbox)
{ {
if( factory == NULL || mailbox == NULL ) { if( factory == NULL || mailbox == NULL ) {
return; return;
} }
memset(factory, 0, sizeof(mrmimefactory_t)); memset(factory, 0, sizeof(dc_mimefactory_t));
factory->m_mailbox = mailbox; factory->m_mailbox = mailbox;
} }
void mrmimefactory_empty(mrmimefactory_t* factory) void dc_mimefactory_empty(dc_mimefactory_t* factory)
{ {
if( factory == NULL ) { if( factory == NULL ) {
return; return;
@ -72,10 +72,10 @@ void mrmimefactory_empty(mrmimefactory_t* factory)
factory->m_recipients_addr = NULL; factory->m_recipients_addr = NULL;
} }
mrmsg_unref(factory->m_msg); dc_msg_unref(factory->m_msg);
factory->m_msg = NULL; factory->m_msg = NULL;
mrchat_unref(factory->m_chat); dc_chat_unref(factory->m_chat);
factory->m_chat = NULL; factory->m_chat = NULL;
if( factory->m_out ) { if( factory->m_out ) {
@ -89,19 +89,19 @@ void mrmimefactory_empty(mrmimefactory_t* factory)
} }
static void load_from__(mrmimefactory_t* factory) static void load_from__(dc_mimefactory_t* factory)
{ {
factory->m_from_addr = mrsqlite3_get_config__(factory->m_mailbox->m_sql, "configured_addr", NULL); factory->m_from_addr = dc_sqlite3_get_config__(factory->m_mailbox->m_sql, "configured_addr", NULL);
factory->m_from_displayname = mrsqlite3_get_config__(factory->m_mailbox->m_sql, "displayname", NULL); factory->m_from_displayname = dc_sqlite3_get_config__(factory->m_mailbox->m_sql, "displayname", NULL);
factory->m_selfstatus = mrsqlite3_get_config__(factory->m_mailbox->m_sql, "selfstatus", NULL); factory->m_selfstatus = dc_sqlite3_get_config__(factory->m_mailbox->m_sql, "selfstatus", NULL);
if( factory->m_selfstatus == NULL ) { if( factory->m_selfstatus == NULL ) {
factory->m_selfstatus = mrstock_str(MR_STR_STATUSLINE); factory->m_selfstatus = mrstock_str(MR_STR_STATUSLINE);
} }
} }
int mrmimefactory_load_msg(mrmimefactory_t* factory, uint32_t msg_id) int dc_mimefactory_load_msg(dc_mimefactory_t* factory, uint32_t msg_id)
{ {
int success = 0, locked = 0; int success = 0, locked = 0;
@ -115,27 +115,27 @@ int mrmimefactory_load_msg(mrmimefactory_t* factory, uint32_t msg_id)
factory->m_recipients_names = clist_new(); factory->m_recipients_names = clist_new();
factory->m_recipients_addr = clist_new(); factory->m_recipients_addr = clist_new();
factory->m_msg = mrmsg_new(); factory->m_msg = dc_msg_new();
factory->m_chat = mrchat_new(mailbox); factory->m_chat = dc_chat_new(mailbox);
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
if( mrmsg_load_from_db__(factory->m_msg, mailbox, msg_id) if( dc_msg_load_from_db__(factory->m_msg, mailbox, msg_id)
&& mrchat_load_from_db__(factory->m_chat, factory->m_msg->m_chat_id) ) && dc_chat_load_from_db__(factory->m_chat, factory->m_msg->m_chat_id) )
{ {
load_from__(factory); load_from__(factory);
factory->m_req_mdn = 0; factory->m_req_mdn = 0;
if( mrchat_is_self_talk(factory->m_chat) ) if( dc_chat_is_self_talk(factory->m_chat) )
{ {
clist_append(factory->m_recipients_names, (void*)strdup_keep_null(factory->m_from_displayname)); clist_append(factory->m_recipients_names, (void*)strdup_keep_null(factory->m_from_displayname));
clist_append(factory->m_recipients_addr, (void*)safe_strdup(factory->m_from_addr)); clist_append(factory->m_recipients_addr, (void*)safe_strdup(factory->m_from_addr));
} }
else else
{ {
sqlite3_stmt* stmt = mrsqlite3_predefine__(mailbox->m_sql, SELECT_na_FROM_chats_contacs_JOIN_contacts_WHERE_cc, sqlite3_stmt* stmt = dc_sqlite3_predefine__(mailbox->m_sql, SELECT_na_FROM_chats_contacs_JOIN_contacts_WHERE_cc,
"SELECT c.authname, c.addr " "SELECT c.authname, c.addr "
" FROM chats_contacts cc " " FROM chats_contacts cc "
" LEFT JOIN contacts c ON cc.contact_id=c.id " " LEFT JOIN contacts c ON cc.contact_id=c.id "
@ -155,7 +155,7 @@ int mrmimefactory_load_msg(mrmimefactory_t* factory, uint32_t msg_id)
int command = mrparam_get_int(factory->m_msg->m_param, MRP_CMD, 0); int command = mrparam_get_int(factory->m_msg->m_param, MRP_CMD, 0);
if( command==MR_CMD_MEMBER_REMOVED_FROM_GROUP /* for added members, the list is just fine */) { if( command==MR_CMD_MEMBER_REMOVED_FROM_GROUP /* for added members, the list is just fine */) {
char* email_to_remove = mrparam_get(factory->m_msg->m_param, MRP_CMD_PARAM, NULL); char* email_to_remove = mrparam_get(factory->m_msg->m_param, MRP_CMD_PARAM, NULL);
char* self_addr = mrsqlite3_get_config__(mailbox->m_sql, "configured_addr", ""); char* self_addr = dc_sqlite3_get_config__(mailbox->m_sql, "configured_addr", "");
if( email_to_remove && strcasecmp(email_to_remove, self_addr)!=0 ) if( email_to_remove && strcasecmp(email_to_remove, self_addr)!=0 )
{ {
if( clist_search_string_nocase(factory->m_recipients_addr, email_to_remove)==0 ) if( clist_search_string_nocase(factory->m_recipients_addr, email_to_remove)==0 )
@ -169,7 +169,7 @@ int mrmimefactory_load_msg(mrmimefactory_t* factory, uint32_t msg_id)
if( command!=MR_CMD_AUTOCRYPT_SETUP_MESSAGE if( command!=MR_CMD_AUTOCRYPT_SETUP_MESSAGE
&& command!=MR_CMD_SECUREJOIN_MESSAGE && command!=MR_CMD_SECUREJOIN_MESSAGE
&& mrsqlite3_get_config_int__(mailbox->m_sql, "mdns_enabled", MR_MDNS_DEFAULT_ENABLED) ) { && dc_sqlite3_get_config_int__(mailbox->m_sql, "mdns_enabled", MR_MDNS_DEFAULT_ENABLED) ) {
factory->m_req_mdn = 1; factory->m_req_mdn = 1;
} }
} }
@ -186,7 +186,7 @@ int mrmimefactory_load_msg(mrmimefactory_t* factory, uint32_t msg_id)
Finally, maybe the Predecessor/In-Reply-To header is not needed for all answers but only to the first ones - Finally, maybe the Predecessor/In-Reply-To header is not needed for all answers but only to the first ones -
or after the sender has changes its email address. */ or after the sender has changes its email address. */
sqlite3_stmt* stmt = mrsqlite3_predefine__(mailbox->m_sql, SELECT_rfc724_FROM_msgs_ORDER_BY_timestamp_LIMIT_1, sqlite3_stmt* stmt = dc_sqlite3_predefine__(mailbox->m_sql, SELECT_rfc724_FROM_msgs_ORDER_BY_timestamp_LIMIT_1,
"SELECT rfc724_mid FROM msgs WHERE timestamp=(SELECT max(timestamp) FROM msgs WHERE chat_id=? AND from_id!=?);"); "SELECT rfc724_mid FROM msgs WHERE timestamp=(SELECT max(timestamp) FROM msgs WHERE chat_id=? AND from_id!=?);");
sqlite3_bind_int (stmt, 1, factory->m_msg->m_chat_id); sqlite3_bind_int (stmt, 1, factory->m_msg->m_chat_id);
sqlite3_bind_int (stmt, 2, MR_CONTACT_ID_SELF); sqlite3_bind_int (stmt, 2, MR_CONTACT_ID_SELF);
@ -202,7 +202,7 @@ int mrmimefactory_load_msg(mrmimefactory_t* factory, uint32_t msg_id)
however one could also see this as a feature :) (there may be different contextes on different clients) however one could also see this as a feature :) (there may be different contextes on different clients)
(also, the References-header is not the most important thing, and, at least for now, we do not want to make things too complicated. */ (also, the References-header is not the most important thing, and, at least for now, we do not want to make things too complicated. */
time_t prev_msg_time = 0; time_t prev_msg_time = 0;
stmt = mrsqlite3_predefine__(mailbox->m_sql, SELECT_MAX_timestamp_FROM_msgs, stmt = dc_sqlite3_predefine__(mailbox->m_sql, SELECT_MAX_timestamp_FROM_msgs,
"SELECT max(timestamp) FROM msgs WHERE chat_id=? AND id!=?"); "SELECT max(timestamp) FROM msgs WHERE chat_id=? AND id!=?");
sqlite3_bind_int (stmt, 1, factory->m_msg->m_chat_id); sqlite3_bind_int (stmt, 1, factory->m_msg->m_chat_id);
sqlite3_bind_int (stmt, 2, factory->m_msg->m_id); sqlite3_bind_int (stmt, 2, factory->m_msg->m_id);
@ -218,7 +218,7 @@ int mrmimefactory_load_msg(mrmimefactory_t* factory, uint32_t msg_id)
if( factory->m_references == NULL ) { if( factory->m_references == NULL ) {
factory->m_references = mr_create_dummy_references_mid(); factory->m_references = mr_create_dummy_references_mid();
mrparam_set(factory->m_chat->m_param, MRP_REFERENCES, factory->m_references); mrparam_set(factory->m_chat->m_param, MRP_REFERENCES, factory->m_references);
mrchat_update_param__(factory->m_chat); dc_chat_update_param__(factory->m_chat);
} }
success = 1; success = 1;
@ -228,22 +228,22 @@ int mrmimefactory_load_msg(mrmimefactory_t* factory, uint32_t msg_id)
} }
if( success ) { if( success ) {
factory->m_increation = mrmsg_is_increation__(factory->m_msg); factory->m_increation = dc_msg_is_increation__(factory->m_msg);
} }
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
return success; return success;
} }
int mrmimefactory_load_mdn(mrmimefactory_t* factory, uint32_t msg_id) int dc_mimefactory_load_mdn(dc_mimefactory_t* factory, uint32_t msg_id)
{ {
int success = 0, locked = 0; int success = 0, locked = 0;
mrcontact_t* contact = mrcontact_new(factory->m_mailbox); dc_contact_t* contact = dc_contact_new(factory->m_mailbox);
if( factory == NULL ) { if( factory == NULL ) {
goto cleanup; goto cleanup;
@ -253,17 +253,17 @@ int mrmimefactory_load_mdn(mrmimefactory_t* factory, uint32_t msg_id)
factory->m_recipients_names = clist_new(); factory->m_recipients_names = clist_new();
factory->m_recipients_addr = clist_new(); factory->m_recipients_addr = clist_new();
factory->m_msg = mrmsg_new(); factory->m_msg = dc_msg_new();
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
if( !mrsqlite3_get_config_int__(mailbox->m_sql, "mdns_enabled", MR_MDNS_DEFAULT_ENABLED) ) { if( !dc_sqlite3_get_config_int__(mailbox->m_sql, "mdns_enabled", MR_MDNS_DEFAULT_ENABLED) ) {
goto cleanup; /* MDNs not enabled - check this is late, in the job. the use may have changed its choice while offline ... */ goto cleanup; /* MDNs not enabled - check this is late, in the job. the use may have changed its choice while offline ... */
} }
if( !mrmsg_load_from_db__(factory->m_msg, mailbox, msg_id) if( !dc_msg_load_from_db__(factory->m_msg, mailbox, msg_id)
|| !mrcontact_load_from_db__(contact, mailbox->m_sql, factory->m_msg->m_from_id) ) { || !dc_contact_load_from_db__(contact, mailbox->m_sql, factory->m_msg->m_from_id) ) {
goto cleanup; goto cleanup;
} }
@ -284,14 +284,14 @@ int mrmimefactory_load_mdn(mrmimefactory_t* factory, uint32_t msg_id)
factory->m_timestamp = mr_create_smeared_timestamp__(); factory->m_timestamp = mr_create_smeared_timestamp__();
factory->m_rfc724_mid = mr_create_outgoing_rfc724_mid(NULL, factory->m_from_addr); factory->m_rfc724_mid = mr_create_outgoing_rfc724_mid(NULL, factory->m_from_addr);
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
success = 1; success = 1;
factory->m_loaded = MR_MF_MDN_LOADED; factory->m_loaded = MR_MF_MDN_LOADED;
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
return success; return success;
} }
@ -319,7 +319,7 @@ static struct mailmime* build_body_text(char* text)
} }
static struct mailmime* build_body_file(const mrmsg_t* msg, const char* base_name, char** ret_file_name_as_sent) static struct mailmime* build_body_file(const dc_msg_t* msg, const char* base_name, char** ret_file_name_as_sent)
{ {
struct mailmime_fields* mime_fields; struct mailmime_fields* mime_fields;
struct mailmime* mime_sub = NULL; struct mailmime* mime_sub = NULL;
@ -440,9 +440,9 @@ cleanup:
} }
static char* get_subject(const mrchat_t* chat, const mrmsg_t* msg, int afwd_email) static char* get_subject(const dc_chat_t* chat, const dc_msg_t* msg, int afwd_email)
{ {
char *ret, *raw_subject = mrmsg_get_summarytext_by_raw(msg->m_type, msg->m_text, msg->m_param, APPROX_SUBJECT_CHARS); char *ret, *raw_subject = dc_msg_get_summarytext_by_raw(msg->m_type, msg->m_text, msg->m_param, APPROX_SUBJECT_CHARS);
const char* fwd = afwd_email? "Fwd: " : ""; const char* fwd = afwd_email? "Fwd: " : "";
if( mrparam_get_int(msg->m_param, MRP_CMD, 0) == MR_CMD_AUTOCRYPT_SETUP_MESSAGE ) if( mrparam_get_int(msg->m_param, MRP_CMD, 0) == MR_CMD_AUTOCRYPT_SETUP_MESSAGE )
@ -463,7 +463,7 @@ static char* get_subject(const mrchat_t* chat, const mrmsg_t* msg, int afwd_emai
} }
int mrmimefactory_render(mrmimefactory_t* factory) int dc_mimefactory_render(dc_mimefactory_t* factory)
{ {
if( factory == NULL if( factory == NULL
|| factory->m_loaded == MR_MF_NOTHING_LOADED || factory->m_loaded == MR_MF_NOTHING_LOADED
@ -544,8 +544,8 @@ int mrmimefactory_render(mrmimefactory_t* factory)
/* Render a normal message /* Render a normal message
*********************************************************************/ *********************************************************************/
mrchat_t* chat = factory->m_chat; dc_chat_t* chat = factory->m_chat;
mrmsg_t* msg = factory->m_msg; dc_msg_t* msg = factory->m_msg;
struct mailmime* meta_part = NULL; struct mailmime* meta_part = NULL;
char* placeholdertext = NULL; char* placeholdertext = NULL;
@ -640,14 +640,14 @@ int mrmimefactory_render(mrmimefactory_t* factory)
if( grpimage ) if( grpimage )
{ {
mrmsg_t* meta = mrmsg_new(); dc_msg_t* meta = dc_msg_new();
meta->m_type = MR_MSG_IMAGE; meta->m_type = MR_MSG_IMAGE;
mrparam_set(meta->m_param, MRP_FILE, grpimage); mrparam_set(meta->m_param, MRP_FILE, grpimage);
char* filename_as_sent = NULL; char* filename_as_sent = NULL;
if( (meta_part=build_body_file(meta, "group-image", &filename_as_sent))!=NULL ) { if( (meta_part=build_body_file(meta, "group-image", &filename_as_sent))!=NULL ) {
mailimf_fields_add(imf_fields, mailimf_field_new_custom(strdup("Chat-Group-Image"), filename_as_sent/*takes ownership*/)); mailimf_fields_add(imf_fields, mailimf_field_new_custom(strdup("Chat-Group-Image"), filename_as_sent/*takes ownership*/));
} }
mrmsg_unref(meta); dc_msg_unref(meta);
} }
if( msg->m_type == MR_MSG_VOICE || msg->m_type == MR_MSG_AUDIO || msg->m_type == MR_MSG_VIDEO ) if( msg->m_type == MR_MSG_VOICE || msg->m_type == MR_MSG_AUDIO || msg->m_type == MR_MSG_VIDEO )
@ -728,7 +728,7 @@ int mrmimefactory_render(mrmimefactory_t* factory)
p1 = mrstock_str(MR_STR_ENCRYPTEDMSG); /* we SHOULD NOT spread encrypted subjects, date etc. in potentially unencrypted MDNs */ p1 = mrstock_str(MR_STR_ENCRYPTEDMSG); /* we SHOULD NOT spread encrypted subjects, date etc. in potentially unencrypted MDNs */
} }
else { else {
p1 = mrmsg_get_summarytext(factory->m_msg, APPROX_SUBJECT_CHARS); p1 = dc_msg_get_summarytext(factory->m_msg, APPROX_SUBJECT_CHARS);
} }
p2 = mrstock_str_repl_string(MR_STR_READRCPT_MAILBODY, p1); p2 = mrstock_str_repl_string(MR_STR_READRCPT_MAILBODY, p1);
message_text = mr_mprintf("%s" LINEEND, p2); message_text = mr_mprintf("%s" LINEEND, p2);

View file

@ -40,17 +40,17 @@ typedef enum {
MR_MF_NOTHING_LOADED = 0, MR_MF_NOTHING_LOADED = 0,
MR_MF_MSG_LOADED, MR_MF_MSG_LOADED,
MR_MF_MDN_LOADED MR_MF_MDN_LOADED
} mrmimefactory_loaded_t; } dc_mimefactory_loaded_t;
/** /**
* Library-internal. * Library-internal.
*/ */
typedef struct mrmimefactory_t { typedef struct dc_mimefactory_t {
/** @privatesection */ /** @privatesection */
/* in: parameters, set eg. by mrmimefactory_load_msg() */ /* in: parameters, set eg. by dc_mimefactory_load_msg() */
char* m_from_addr; char* m_from_addr;
char* m_from_displayname; char* m_from_displayname;
char* m_selfstatus; char* m_selfstatus;
@ -60,30 +60,30 @@ typedef struct mrmimefactory_t {
char* m_rfc724_mid; char* m_rfc724_mid;
/* what is loaded? */ /* what is loaded? */
mrmimefactory_loaded_t m_loaded; dc_mimefactory_loaded_t m_loaded;
mrmsg_t* m_msg; dc_msg_t* m_msg;
mrchat_t* m_chat; dc_chat_t* m_chat;
int m_increation; int m_increation;
char* m_predecessor; char* m_predecessor;
char* m_references; char* m_references;
int m_req_mdn; int m_req_mdn;
/* out: after a successfull mrmimefactory_render(), here's the data */ /* out: after a successfull dc_mimefactory_render(), here's the data */
MMAPString* m_out; MMAPString* m_out;
int m_out_encrypted; int m_out_encrypted;
/* private */ /* private */
mrmailbox_t* m_mailbox; mrmailbox_t* m_mailbox;
} mrmimefactory_t; } dc_mimefactory_t;
void mrmimefactory_init (mrmimefactory_t*, mrmailbox_t*); void dc_mimefactory_init (dc_mimefactory_t*, mrmailbox_t*);
void mrmimefactory_empty (mrmimefactory_t*); void dc_mimefactory_empty (dc_mimefactory_t*);
int mrmimefactory_load_msg (mrmimefactory_t*, uint32_t msg_id); int dc_mimefactory_load_msg (dc_mimefactory_t*, uint32_t msg_id);
int mrmimefactory_load_mdn (mrmimefactory_t*, uint32_t msg_id); int dc_mimefactory_load_mdn (dc_mimefactory_t*, uint32_t msg_id);
int mrmimefactory_render (mrmimefactory_t*); int dc_mimefactory_render (dc_mimefactory_t*);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -411,22 +411,22 @@ void mailmime_print(struct mailmime* mime)
******************************************************************************/ ******************************************************************************/
static void mailimf_get_recipients__add_addr(mrhash_t* recipients, struct mailimf_mailbox* mb) static void mailimf_get_recipients__add_addr(dc_hash_t* recipients, struct mailimf_mailbox* mb)
{ {
/* only used internally by mailimf_get_recipients() */ /* only used internally by mailimf_get_recipients() */
if( mb ) { if( mb ) {
char* addr_norm = mr_normalize_addr(mb->mb_addr_spec); char* addr_norm = mr_normalize_addr(mb->mb_addr_spec);
mrhash_insert(recipients, addr_norm, strlen(addr_norm), (void*)1); dc_hash_insert(recipients, addr_norm, strlen(addr_norm), (void*)1);
free(addr_norm); free(addr_norm);
} }
} }
mrhash_t* mailimf_get_recipients(struct mailimf_fields* imffields) dc_hash_t* mailimf_get_recipients(struct mailimf_fields* imffields)
{ {
/* the returned value must be mrhash_clear()'d and free()'d. returned addresses are normalized. */ /* the returned value must be dc_hash_clear()'d and free()'d. returned addresses are normalized. */
mrhash_t* recipients = malloc(sizeof(mrhash_t)); dc_hash_t* recipients = malloc(sizeof(dc_hash_t));
mrhash_init(recipients, MRHASH_STRING, 1/*copy key*/); dc_hash_init(recipients, MRHASH_STRING, 1/*copy key*/);
clistiter* cur1; clistiter* cur1;
for( cur1 = clist_begin(imffields->fld_list); cur1!=NULL ; cur1=clist_next(cur1) ) for( cur1 = clist_begin(imffields->fld_list); cur1!=NULL ; cur1=clist_next(cur1) )
@ -828,18 +828,18 @@ static void mrmimepart_unref(mrmimepart_t* ths)
/** /**
* Create a new mime parser object. * Create a new mime parser object.
* *
* @private @memberof mrmimeparser_t * @private @memberof dc_mimeparser_t
* *
* @param blobdir Directrory to write attachments to. * @param blobdir Directrory to write attachments to.
* @param mailbox Mailbox object, used for logging only. * @param mailbox Mailbox object, used for logging only.
* *
* @return The MIME-parser object. * @return The MIME-parser object.
*/ */
mrmimeparser_t* mrmimeparser_new(const char* blobdir, mrmailbox_t* mailbox) dc_mimeparser_t* dc_mimeparser_new(const char* blobdir, mrmailbox_t* mailbox)
{ {
mrmimeparser_t* ths = NULL; dc_mimeparser_t* ths = NULL;
if( (ths=calloc(1, sizeof(mrmimeparser_t)))==NULL ) { if( (ths=calloc(1, sizeof(dc_mimeparser_t)))==NULL ) {
exit(30); exit(30);
} }
@ -849,7 +849,7 @@ mrmimeparser_t* mrmimeparser_new(const char* blobdir, mrmailbox_t* mailbox)
ths->m_reports = carray_new(16); ths->m_reports = carray_new(16);
ths->m_e2ee_helper = calloc(1, sizeof(mrmailbox_e2ee_helper_t)); ths->m_e2ee_helper = calloc(1, sizeof(mrmailbox_e2ee_helper_t));
mrhash_init(&ths->m_header, MRHASH_STRING, 0/* do not copy key */); dc_hash_init(&ths->m_header, MRHASH_STRING, 0/* do not copy key */);
return ths; return ths;
} }
@ -858,21 +858,21 @@ mrmimeparser_t* mrmimeparser_new(const char* blobdir, mrmailbox_t* mailbox)
/** /**
* Free a MIME-parser object. * Free a MIME-parser object.
* *
* Esp. all data allocated by mrmimeparser_parse() will be free()'d. * Esp. all data allocated by dc_mimeparser_parse() will be free()'d.
* *
* @private @memberof mrmimeparser_t * @private @memberof dc_mimeparser_t
* *
* @param ths The MIME-parser object. * @param ths The MIME-parser object.
* *
* @return None. * @return None.
*/ */
void mrmimeparser_unref(mrmimeparser_t* ths) void dc_mimeparser_unref(dc_mimeparser_t* ths)
{ {
if( ths == NULL ) { if( ths == NULL ) {
return; return;
} }
mrmimeparser_empty(ths); dc_mimeparser_empty(ths);
if( ths->m_parts ) { carray_free(ths->m_parts); } if( ths->m_parts ) { carray_free(ths->m_parts); }
if( ths->m_reports ) { carray_free(ths->m_reports); } if( ths->m_reports ) { carray_free(ths->m_reports); }
free(ths->m_e2ee_helper); free(ths->m_e2ee_helper);
@ -883,16 +883,16 @@ void mrmimeparser_unref(mrmimeparser_t* ths)
/** /**
* Empty all data in a MIME-parser object. * Empty all data in a MIME-parser object.
* *
* This function is called implicitly by mrmimeparser_parse() to free * This function is called implicitly by dc_mimeparser_parse() to free
* previously allocated data. * previously allocated data.
* *
* @private @memberof mrmimeparser_t * @private @memberof dc_mimeparser_t
* *
* @param ths The MIME-parser object. * @param ths The MIME-parser object.
* *
* @return None. * @return None.
*/ */
void mrmimeparser_empty(mrmimeparser_t* ths) void dc_mimeparser_empty(dc_mimeparser_t* ths)
{ {
if( ths == NULL ) { if( ths == NULL ) {
return; return;
@ -911,7 +911,7 @@ void mrmimeparser_empty(mrmimeparser_t* ths)
} }
ths->m_header_root = NULL; /* a pointer somewhere to the MIME data, must NOT be freed */ ths->m_header_root = NULL; /* a pointer somewhere to the MIME data, must NOT be freed */
mrhash_clear(&ths->m_header); dc_hash_clear(&ths->m_header);
if( ths->m_header_protected ) { if( ths->m_header_protected ) {
mailimf_fields_free(ths->m_header_protected); /* allocated as needed, MUST be freed */ mailimf_fields_free(ths->m_header_protected); /* allocated as needed, MUST be freed */
@ -942,10 +942,10 @@ void mrmimeparser_empty(mrmimeparser_t* ths)
} }
static void do_add_single_part(mrmimeparser_t* parser, mrmimepart_t* part) static void do_add_single_part(dc_mimeparser_t* parser, mrmimepart_t* part)
{ {
/* add a single part to the list of parts, the parser takes the ownership of the part, so you MUST NOT unref it after calling this function. */ /* add a single part to the list of parts, the parser takes the ownership of the part, so you MUST NOT unref it after calling this function. */
if( parser->m_e2ee_helper->m_encrypted && mrhash_count(parser->m_e2ee_helper->m_signatures)>0 ) { if( parser->m_e2ee_helper->m_encrypted && dc_hash_count(parser->m_e2ee_helper->m_signatures)>0 ) {
mrparam_set_int(part->m_param, MRP_GUARANTEE_E2EE, 1); mrparam_set_int(part->m_param, MRP_GUARANTEE_E2EE, 1);
} }
else if( parser->m_e2ee_helper->m_encrypted ) { else if( parser->m_e2ee_helper->m_encrypted ) {
@ -955,7 +955,7 @@ static void do_add_single_part(mrmimeparser_t* parser, mrmimepart_t* part)
} }
static void do_add_single_file_part(mrmimeparser_t* parser, int msg_type, int mime_type, static void do_add_single_file_part(dc_mimeparser_t* parser, int msg_type, int mime_type,
const char* decoded_data, size_t decoded_data_bytes, const char* decoded_data, size_t decoded_data_bytes,
const char* desired_filename) const char* desired_filename)
{ {
@ -995,7 +995,7 @@ static void do_add_single_file_part(mrmimeparser_t* parser, int msg_type, int mi
/* split author/title from the original filename (if we do it from the real filename, we'll also get numbers appended by mr_get_fine_pathNfilename()) */ /* split author/title from the original filename (if we do it from the real filename, we'll also get numbers appended by mr_get_fine_pathNfilename()) */
if( msg_type == MR_MSG_AUDIO ) { if( msg_type == MR_MSG_AUDIO ) {
char* author = NULL, *title = NULL; char* author = NULL, *title = NULL;
mrmsg_get_authorNtitle_from_filename(desired_filename, &author, &title); dc_msg_get_authorNtitle_from_filename(desired_filename, &author, &title);
mrparam_set(part->m_param, MRP_AUTHORNAME, author); mrparam_set(part->m_param, MRP_AUTHORNAME, author);
mrparam_set(part->m_param, MRP_TRACKNAME, title); mrparam_set(part->m_param, MRP_TRACKNAME, title);
free(author); free(author);
@ -1011,7 +1011,7 @@ cleanup:
} }
static int mrmimeparser_add_single_part_if_known(mrmimeparser_t* ths, struct mailmime* mime) static int dc_mimeparser_add_single_part_if_known(dc_mimeparser_t* ths, struct mailmime* mime)
{ {
mrmimepart_t* part = NULL; mrmimepart_t* part = NULL;
int old_part_count = carray_count(ths->m_parts); int old_part_count = carray_count(ths->m_parts);
@ -1025,7 +1025,7 @@ static int mrmimeparser_add_single_part_if_known(mrmimeparser_t* ths, struct mai
char* charset_buffer = NULL; /* charconv_buffer_free()'d if set (just calls mmap_string_unref()) */ char* charset_buffer = NULL; /* charconv_buffer_free()'d if set (just calls mmap_string_unref()) */
const char* decoded_data = NULL; /* must not be free()'d */ const char* decoded_data = NULL; /* must not be free()'d */
size_t decoded_data_bytes = 0; size_t decoded_data_bytes = 0;
mrsimplify_t* simplifier = NULL; dc_simplify_t* simplifier = NULL;
if( mime == NULL || mime->mm_data.mm_single == NULL ) { if( mime == NULL || mime->mm_data.mm_single == NULL ) {
goto cleanup; goto cleanup;
@ -1054,7 +1054,7 @@ static int mrmimeparser_add_single_part_if_known(mrmimeparser_t* ths, struct mai
case MR_MIMETYPE_TEXT_HTML: case MR_MIMETYPE_TEXT_HTML:
{ {
if( simplifier==NULL ) { if( simplifier==NULL ) {
simplifier = mrsimplify_new(); simplifier = dc_simplify_new();
if( simplifier==NULL ) { if( simplifier==NULL ) {
goto cleanup; goto cleanup;
} }
@ -1085,7 +1085,7 @@ static int mrmimeparser_add_single_part_if_known(mrmimeparser_t* ths, struct mai
int uu_msg_type = 0, added_uu_parts = 0; int uu_msg_type = 0, added_uu_parts = 0;
while( (new_txt=mruudecode_do(txt, &uu_blob, &uu_blob_bytes, &uu_filename)) != NULL ) while( (new_txt=mruudecode_do(txt, &uu_blob, &uu_blob_bytes, &uu_filename)) != NULL )
{ {
mrmsg_guess_msgtype_from_suffix(uu_filename, &uu_msg_type, NULL); dc_msg_guess_msgtype_from_suffix(uu_filename, &uu_msg_type, NULL);
if( uu_msg_type == 0 ) { if( uu_msg_type == 0 ) {
uu_msg_type = MR_MSG_FILE; uu_msg_type = MR_MSG_FILE;
} }
@ -1104,7 +1104,7 @@ static int mrmimeparser_add_single_part_if_known(mrmimeparser_t* ths, struct mai
} }
// add text as MR_MSG_TEXT part // add text as MR_MSG_TEXT part
char* simplified_txt = mrsimplify_simplify(simplifier, txt, strlen(txt), mime_type==MR_MIMETYPE_TEXT_HTML? 1 : 0); char* simplified_txt = dc_simplify_simplify(simplifier, txt, strlen(txt), mime_type==MR_MIMETYPE_TEXT_HTML? 1 : 0);
free(txt); free(txt);
txt = NULL; txt = NULL;
if( simplified_txt && simplified_txt[0] ) if( simplified_txt && simplified_txt[0] )
@ -1208,7 +1208,7 @@ static int mrmimeparser_add_single_part_if_known(mrmimeparser_t* ths, struct mai
/* add object? (we do not add all objetcs, eg. signatures etc. are ignored) */ /* add object? (we do not add all objetcs, eg. signatures etc. are ignored) */
cleanup: cleanup:
mrsimplify_unref(simplifier); dc_simplify_unref(simplifier);
if( charset_buffer ) { charconv_buffer_free(charset_buffer); } if( charset_buffer ) { charconv_buffer_free(charset_buffer); }
if( transfer_decoding_buffer ) { mmap_string_unref(transfer_decoding_buffer); } if( transfer_decoding_buffer ) { mmap_string_unref(transfer_decoding_buffer); }
free(file_suffix); free(file_suffix);
@ -1219,7 +1219,7 @@ cleanup:
} }
static int mrmimeparser_parse_mime_recursive(mrmimeparser_t* ths, struct mailmime* mime) static int dc_mimeparser_parse_mime_recursive(dc_mimeparser_t* ths, struct mailmime* mime)
{ {
int any_part_added = 0; int any_part_added = 0;
clistiter* cur; clistiter* cur;
@ -1254,7 +1254,7 @@ static int mrmimeparser_parse_mime_recursive(mrmimeparser_t* ths, struct mailmim
switch( mime->mm_type ) switch( mime->mm_type )
{ {
case MAILMIME_SINGLE: case MAILMIME_SINGLE:
any_part_added = mrmimeparser_add_single_part_if_known(ths, mime); any_part_added = dc_mimeparser_add_single_part_if_known(ths, mime);
break; break;
case MAILMIME_MULTIPLE: case MAILMIME_MULTIPLE:
@ -1266,7 +1266,7 @@ static int mrmimeparser_parse_mime_recursive(mrmimeparser_t* ths, struct mailmim
for( cur=clist_begin(mime->mm_data.mm_multipart.mm_mp_list); cur!=NULL; cur=clist_next(cur)) { for( cur=clist_begin(mime->mm_data.mm_multipart.mm_mp_list); cur!=NULL; cur=clist_next(cur)) {
struct mailmime* childmime = (struct mailmime*)clist_content(cur); struct mailmime* childmime = (struct mailmime*)clist_content(cur);
if( mailmime_get_mime_type(childmime, NULL) == MR_MIMETYPE_MP_MIXED ) { if( mailmime_get_mime_type(childmime, NULL) == MR_MIMETYPE_MP_MIXED ) {
any_part_added = mrmimeparser_parse_mime_recursive(ths, childmime); any_part_added = dc_mimeparser_parse_mime_recursive(ths, childmime);
break; break;
} }
} }
@ -1277,7 +1277,7 @@ static int mrmimeparser_parse_mime_recursive(mrmimeparser_t* ths, struct mailmim
for( cur=clist_begin(mime->mm_data.mm_multipart.mm_mp_list); cur!=NULL; cur=clist_next(cur)) { for( cur=clist_begin(mime->mm_data.mm_multipart.mm_mp_list); cur!=NULL; cur=clist_next(cur)) {
struct mailmime* childmime = (struct mailmime*)clist_content(cur); struct mailmime* childmime = (struct mailmime*)clist_content(cur);
if( mailmime_get_mime_type(childmime, NULL) == MR_MIMETYPE_TEXT_PLAIN ) { if( mailmime_get_mime_type(childmime, NULL) == MR_MIMETYPE_TEXT_PLAIN ) {
any_part_added = mrmimeparser_parse_mime_recursive(ths, childmime); any_part_added = dc_mimeparser_parse_mime_recursive(ths, childmime);
break; break;
} }
} }
@ -1285,7 +1285,7 @@ static int mrmimeparser_parse_mime_recursive(mrmimeparser_t* ths, struct mailmim
if( !any_part_added ) { /* `text/plain` not found - use the first part */ if( !any_part_added ) { /* `text/plain` not found - use the first part */
for( cur=clist_begin(mime->mm_data.mm_multipart.mm_mp_list); cur!=NULL; cur=clist_next(cur)) { for( cur=clist_begin(mime->mm_data.mm_multipart.mm_mp_list); cur!=NULL; cur=clist_next(cur)) {
if( mrmimeparser_parse_mime_recursive(ths, (struct mailmime*)clist_content(cur)) ) { if( dc_mimeparser_parse_mime_recursive(ths, (struct mailmime*)clist_content(cur)) ) {
any_part_added = 1; any_part_added = 1;
break; /* out of for() */ break; /* out of for() */
} }
@ -1297,7 +1297,7 @@ static int mrmimeparser_parse_mime_recursive(mrmimeparser_t* ths, struct mailmim
/* we assume he "root part" being the first one, which may not be always true ... however, most times it seems okay. */ /* we assume he "root part" being the first one, which may not be always true ... however, most times it seems okay. */
cur=clist_begin(mime->mm_data.mm_multipart.mm_mp_list); cur=clist_begin(mime->mm_data.mm_multipart.mm_mp_list);
if( cur ) { if( cur ) {
any_part_added = mrmimeparser_parse_mime_recursive(ths, (struct mailmime*)clist_content(cur)); any_part_added = dc_mimeparser_parse_mime_recursive(ths, (struct mailmime*)clist_content(cur));
} }
break; break;
@ -1324,7 +1324,7 @@ static int mrmimeparser_parse_mime_recursive(mrmimeparser_t* ths, struct mailmim
(see https://k9mail.github.io/2016/11/24/OpenPGP-Considerations-Part-I.html for background information why we use encrypted+signed) */ (see https://k9mail.github.io/2016/11/24/OpenPGP-Considerations-Part-I.html for background information why we use encrypted+signed) */
if( (cur=clist_begin(mime->mm_data.mm_multipart.mm_mp_list)) != NULL ) if( (cur=clist_begin(mime->mm_data.mm_multipart.mm_mp_list)) != NULL )
{ {
any_part_added = mrmimeparser_parse_mime_recursive(ths, (struct mailmime*)clist_content(cur)); any_part_added = dc_mimeparser_parse_mime_recursive(ths, (struct mailmime*)clist_content(cur));
} }
break; break;
@ -1340,7 +1340,7 @@ static int mrmimeparser_parse_mime_recursive(mrmimeparser_t* ths, struct mailmim
else else
{ {
/* eg. `report-type=delivery-status`; maybe we should show them as a little error icon */ /* eg. `report-type=delivery-status`; maybe we should show them as a little error icon */
any_part_added = mrmimeparser_parse_mime_recursive(ths, (struct mailmime*)clist_content(clist_begin(mime->mm_data.mm_multipart.mm_mp_list))); any_part_added = dc_mimeparser_parse_mime_recursive(ths, (struct mailmime*)clist_content(clist_begin(mime->mm_data.mm_multipart.mm_mp_list)));
} }
} }
break; break;
@ -1374,7 +1374,7 @@ static int mrmimeparser_parse_mime_recursive(mrmimeparser_t* ths, struct mailmim
for( cur=clist_begin(mime->mm_data.mm_multipart.mm_mp_list); cur!=NULL; cur=clist_next(cur)) { for( cur=clist_begin(mime->mm_data.mm_multipart.mm_mp_list); cur!=NULL; cur=clist_next(cur)) {
struct mailmime* childmime = (struct mailmime*)clist_content(cur); struct mailmime* childmime = (struct mailmime*)clist_content(cur);
if( childmime != skip_part ) { if( childmime != skip_part ) {
if( mrmimeparser_parse_mime_recursive(ths, childmime) ) { if( dc_mimeparser_parse_mime_recursive(ths, childmime) ) {
any_part_added = 1; any_part_added = 1;
} }
} }
@ -1392,7 +1392,7 @@ static int mrmimeparser_parse_mime_recursive(mrmimeparser_t* ths, struct mailmim
if( mime->mm_data.mm_message.mm_msg_mime ) if( mime->mm_data.mm_message.mm_msg_mime )
{ {
any_part_added = mrmimeparser_parse_mime_recursive(ths, mime->mm_data.mm_message.mm_msg_mime); any_part_added = dc_mimeparser_parse_mime_recursive(ths, mime->mm_data.mm_message.mm_msg_mime);
} }
break; break;
} }
@ -1401,7 +1401,7 @@ static int mrmimeparser_parse_mime_recursive(mrmimeparser_t* ths, struct mailmim
} }
static void hash_header(mrhash_t* out, const struct mailimf_fields* in, mrmailbox_t* mailbox) static void hash_header(dc_hash_t* out, const struct mailimf_fields* in, mrmailbox_t* mailbox)
{ {
if( in == NULL ) { if( in == NULL ) {
return; return;
@ -1440,20 +1440,20 @@ static void hash_header(mrhash_t* out, const struct mailimf_fields* in, mrmailbo
{ {
int key_len = strlen(key); int key_len = strlen(key);
if( mrhash_find(out, key, key_len) ) if( dc_hash_find(out, key, key_len) )
{ {
/* key already in hash, do only overwrite known types */ /* key already in hash, do only overwrite known types */
if( field->fld_type!=MAILIMF_FIELD_OPTIONAL_FIELD if( field->fld_type!=MAILIMF_FIELD_OPTIONAL_FIELD
|| (key_len>5 && strncasecmp(key, "Chat-", 5)==0) ) || (key_len>5 && strncasecmp(key, "Chat-", 5)==0) )
{ {
//dc_log_info(mailbox, 0, "Protected headers: Overwriting \"%s\".", key); //dc_log_info(mailbox, 0, "Protected headers: Overwriting \"%s\".", key);
mrhash_insert(out, key, key_len, field); dc_hash_insert(out, key, key_len, field);
} }
} }
else else
{ {
/* key not hashed before */ /* key not hashed before */
mrhash_insert(out, key, key_len, field); dc_hash_insert(out, key, key_len, field);
} }
} }
} }
@ -1464,12 +1464,12 @@ static void hash_header(mrhash_t* out, const struct mailimf_fields* in, mrmailbo
* Parse raw MIME-data into a MIME-object. * Parse raw MIME-data into a MIME-object.
* *
* You may call this function several times on the same object; old data are cleared using * You may call this function several times on the same object; old data are cleared using
* mrmimeparser_empty() before parsing is started. * dc_mimeparser_empty() before parsing is started.
* *
* After mrmimeparser_parse() is called successfully, all the functions to get information about the * After dc_mimeparser_parse() is called successfully, all the functions to get information about the
* MIME-structure will work. * MIME-structure will work.
* *
* @private @memberof mrmimeparser_t * @private @memberof dc_mimeparser_t
* *
* @param ths The MIME-parser object. * @param ths The MIME-parser object.
* @param body_not_terminated Plain text, no need to be null-terminated. * @param body_not_terminated Plain text, no need to be null-terminated.
@ -1478,12 +1478,12 @@ static void hash_header(mrhash_t* out, const struct mailimf_fields* in, mrmailbo
* *
* @return None. * @return None.
*/ */
void mrmimeparser_parse(mrmimeparser_t* ths, const char* body_not_terminated, size_t body_bytes) void dc_mimeparser_parse(dc_mimeparser_t* ths, const char* body_not_terminated, size_t body_bytes)
{ {
int r; int r;
size_t index = 0; size_t index = 0;
mrmimeparser_empty(ths); dc_mimeparser_empty(ths);
/* parse body */ /* parse body */
r = mailmime_parse(body_not_terminated, body_bytes, &index, &ths->m_mimeroot); r = mailmime_parse(body_not_terminated, body_bytes, &index, &ths->m_mimeroot);
@ -1500,7 +1500,7 @@ void mrmimeparser_parse(mrmimeparser_t* ths, const char* body_not_terminated, si
//printf("after decryption:\n"); mailmime_print(ths->m_mimeroot); //printf("after decryption:\n"); mailmime_print(ths->m_mimeroot);
/* recursively check, whats parsed, this also sets up m_header_old */ /* recursively check, whats parsed, this also sets up m_header_old */
mrmimeparser_parse_mime_recursive(ths, ths->m_mimeroot); dc_mimeparser_parse_mime_recursive(ths, ths->m_mimeroot);
// TOCHECK: text parts may be moved to the beginning of the list - either here or in do_add_single_part() // TOCHECK: text parts may be moved to the beginning of the list - either here or in do_add_single_part()
// usecase: eg. the Buchungsbestätigungen of Deutsch Bahn have the PDF before the explaining text. // usecase: eg. the Buchungsbestätigungen of Deutsch Bahn have the PDF before the explaining text.
@ -1512,17 +1512,17 @@ void mrmimeparser_parse(mrmimeparser_t* ths, const char* body_not_terminated, si
/* set some basic data */ /* set some basic data */
{ {
struct mailimf_field* field = mrmimeparser_lookup_field(ths, "Subject"); struct mailimf_field* field = dc_mimeparser_lookup_field(ths, "Subject");
if( field && field->fld_type == MAILIMF_FIELD_SUBJECT ) { if( field && field->fld_type == MAILIMF_FIELD_SUBJECT ) {
ths->m_subject = mr_decode_header_words(field->fld_data.fld_subject->sbj_value); ths->m_subject = mr_decode_header_words(field->fld_data.fld_subject->sbj_value);
} }
} }
if( mrmimeparser_lookup_optional_field2(ths, "Chat-Version", "X-MrMsg") ) { if( dc_mimeparser_lookup_optional_field2(ths, "Chat-Version", "X-MrMsg") ) {
ths->m_is_send_by_messenger = 1; ths->m_is_send_by_messenger = 1;
} }
if( mrmimeparser_lookup_field(ths, "Autocrypt-Setup-Message") ) { if( dc_mimeparser_lookup_field(ths, "Autocrypt-Setup-Message") ) {
/* Autocrypt-Setup-Message header found - check if there is an application/autocrypt-setup part */ /* Autocrypt-Setup-Message header found - check if there is an application/autocrypt-setup part */
int i, has_setup_file = 0; int i, has_setup_file = 0;
for( i = 0; i < carray_count(ths->m_parts); i++ ) { for( i = 0; i < carray_count(ths->m_parts); i++ ) {
@ -1601,7 +1601,7 @@ void mrmimeparser_parse(mrmimeparser_t* ths, const char* body_not_terminated, si
and read some additional parameters */ and read some additional parameters */
mrmimepart_t* part = (mrmimepart_t*)carray_get(ths->m_parts, 0); mrmimepart_t* part = (mrmimepart_t*)carray_get(ths->m_parts, 0);
if( part->m_type == MR_MSG_AUDIO ) { if( part->m_type == MR_MSG_AUDIO ) {
if( mrmimeparser_lookup_optional_field2(ths, "Chat-Voice-Message", "X-MrVoiceMessage") ) { if( dc_mimeparser_lookup_optional_field2(ths, "Chat-Voice-Message", "X-MrVoiceMessage") ) {
free(part->m_msg); free(part->m_msg);
part->m_msg = strdup("ogg"); /* MR_MSG_AUDIO adds sets the whole filename which is useless. however, the extension is useful. */ part->m_msg = strdup("ogg"); /* MR_MSG_AUDIO adds sets the whole filename which is useless. however, the extension is useful. */
part->m_type = MR_MSG_VOICE; part->m_type = MR_MSG_VOICE;
@ -1611,7 +1611,7 @@ void mrmimeparser_parse(mrmimeparser_t* ths, const char* body_not_terminated, si
} }
if( part->m_type == MR_MSG_AUDIO || part->m_type == MR_MSG_VOICE || part->m_type == MR_MSG_VIDEO ) { if( part->m_type == MR_MSG_AUDIO || part->m_type == MR_MSG_VOICE || part->m_type == MR_MSG_VIDEO ) {
const struct mailimf_optional_field* field = mrmimeparser_lookup_optional_field2(ths, "Chat-Duration", "X-MrDurationMs"); const struct mailimf_optional_field* field = dc_mimeparser_lookup_optional_field2(ths, "Chat-Duration", "X-MrDurationMs");
if( field ) { if( field ) {
int duration_ms = atoi(field->fld_value); int duration_ms = atoi(field->fld_value);
if( duration_ms > 0 && duration_ms < 24*60*60*1000 ) { if( duration_ms > 0 && duration_ms < 24*60*60*1000 ) {
@ -1622,7 +1622,7 @@ void mrmimeparser_parse(mrmimeparser_t* ths, const char* body_not_terminated, si
} }
/* some special system message? */ /* some special system message? */
if( mrmimeparser_lookup_field(ths, "Chat-Group-Image") if( dc_mimeparser_lookup_field(ths, "Chat-Group-Image")
&& carray_count(ths->m_parts)>=1 ) { && carray_count(ths->m_parts)>=1 ) {
mrmimepart_t* textpart = (mrmimepart_t*)carray_get(ths->m_parts, 0); mrmimepart_t* textpart = (mrmimepart_t*)carray_get(ths->m_parts, 0);
if( textpart->m_type == MR_MSG_TEXT ) { if( textpart->m_type == MR_MSG_TEXT ) {
@ -1639,8 +1639,8 @@ void mrmimeparser_parse(mrmimeparser_t* ths, const char* body_not_terminated, si
/* check, if the message asks for a MDN */ /* check, if the message asks for a MDN */
if( !ths->m_decrypting_failed ) if( !ths->m_decrypting_failed )
{ {
const struct mailimf_optional_field* dn_field = mrmimeparser_lookup_optional_field(ths, "Chat-Disposition-Notification-To"); /* we use "Chat-Disposition-Notification-To" as replies to "Disposition-Notification-To" are weired in many cases, are just freetext and/or do not follow any standard. */ const struct mailimf_optional_field* dn_field = dc_mimeparser_lookup_optional_field(ths, "Chat-Disposition-Notification-To"); /* we use "Chat-Disposition-Notification-To" as replies to "Disposition-Notification-To" are weired in many cases, are just freetext and/or do not follow any standard. */
if( dn_field && mrmimeparser_get_last_nonmeta(ths)/*just check if the mail is not empty*/ ) if( dn_field && dc_mimeparser_get_last_nonmeta(ths)/*just check if the mail is not empty*/ )
{ {
struct mailimf_mailbox_list* mb_list = NULL; struct mailimf_mailbox_list* mb_list = NULL;
size_t index = 0; size_t index = 0;
@ -1649,7 +1649,7 @@ void mrmimeparser_parse(mrmimeparser_t* ths, const char* body_not_terminated, si
char* dn_to_addr = mailimf_find_first_addr(mb_list); char* dn_to_addr = mailimf_find_first_addr(mb_list);
if( dn_to_addr ) if( dn_to_addr )
{ {
struct mailimf_field* from_field = mrmimeparser_lookup_field(ths, "From"); /* we need From: as this MUST match Disposition-Notification-To: */ struct mailimf_field* from_field = dc_mimeparser_lookup_field(ths, "From"); /* we need From: as this MUST match Disposition-Notification-To: */
if( from_field && from_field->fld_type==MAILIMF_FIELD_FROM && from_field->fld_data.fld_from ) if( from_field && from_field->fld_type==MAILIMF_FIELD_FROM && from_field->fld_data.fld_from )
{ {
char* from_addr = mailimf_find_first_addr(from_field->fld_data.fld_from->frm_mb_list); char* from_addr = mailimf_find_first_addr(from_field->fld_data.fld_from->frm_mb_list);
@ -1660,7 +1660,7 @@ void mrmimeparser_parse(mrmimeparser_t* ths, const char* body_not_terminated, si
/* we mark _only_ the _last_ part to send a MDN /* we mark _only_ the _last_ part to send a MDN
(this avoids trouble with multi-part-messages who should send only one MDN. (this avoids trouble with multi-part-messages who should send only one MDN.
Moreover the last one is handy as it is the one typically displayed if the message is larger) */ Moreover the last one is handy as it is the one typically displayed if the message is larger) */
mrmimepart_t* part = mrmimeparser_get_last_nonmeta(ths); mrmimepart_t* part = dc_mimeparser_get_last_nonmeta(ths);
if( part ) { if( part ) {
mrparam_set_int(part->m_param, MRP_WANTS_MDN, 1); mrparam_set_int(part->m_param, MRP_WANTS_MDN, 1);
} }
@ -1677,7 +1677,7 @@ void mrmimeparser_parse(mrmimeparser_t* ths, const char* body_not_terminated, si
/* Cleanup - and try to create at least an empty part if there are no parts yet */ /* Cleanup - and try to create at least an empty part if there are no parts yet */
cleanup: cleanup:
if( !mrmimeparser_has_nonmeta(ths) && carray_count(ths->m_reports)==0 ) { if( !dc_mimeparser_has_nonmeta(ths) && carray_count(ths->m_reports)==0 ) {
mrmimepart_t* part = mrmimepart_new(); mrmimepart_t* part = mrmimepart_new();
part->m_type = MR_MSG_TEXT; part->m_type = MR_MSG_TEXT;
part->m_msg = safe_strdup(ths->m_subject? ths->m_subject : "Empty message"); part->m_msg = safe_strdup(ths->m_subject? ths->m_subject : "Empty message");
@ -1691,7 +1691,7 @@ cleanup:
* *
* Typical names are `From`, `To`, `Subject` and so on. * Typical names are `From`, `To`, `Subject` and so on.
* *
* @private @memberof mrmimeparser_t * @private @memberof dc_mimeparser_t
* *
* @param mimparser The MIME-parser object. * @param mimparser The MIME-parser object.
* @param field_name The name of the field to look for. * @param field_name The name of the field to look for.
@ -1700,19 +1700,19 @@ cleanup:
* Before accessing the mailimf_field::fld_data, please always have a look at mailimf_field::fld_type! * Before accessing the mailimf_field::fld_data, please always have a look at mailimf_field::fld_type!
* If field_name could not be found, NULL is returned. * If field_name could not be found, NULL is returned.
*/ */
struct mailimf_field* mrmimeparser_lookup_field(mrmimeparser_t* mimeparser, const char* field_name) struct mailimf_field* dc_mimeparser_lookup_field(dc_mimeparser_t* mimeparser, const char* field_name)
{ {
return (struct mailimf_field*)mrhash_find_str(&mimeparser->m_header, field_name); return (struct mailimf_field*)dc_hash_find_str(&mimeparser->m_header, field_name);
} }
/** /**
* Lookup the given field name. * Lookup the given field name.
* *
* In addition to mrmimeparser_lookup_field, this function also checks the mailimf_field::fld_type * In addition to dc_mimeparser_lookup_field, this function also checks the mailimf_field::fld_type
* for being MAILIMF_FIELD_OPTIONAL_FIELD. * for being MAILIMF_FIELD_OPTIONAL_FIELD.
* *
* @private @memberof mrmimeparser_t * @private @memberof dc_mimeparser_t
* *
* @param mimparser The MIME-parser object. * @param mimparser The MIME-parser object.
* @param field_name The name of the field to look for. * @param field_name The name of the field to look for.
@ -1720,9 +1720,9 @@ struct mailimf_field* mrmimeparser_lookup_field(mrmimeparser_t* mimeparser, cons
* @return A pointer to a mailimf_optional_field structure. Must not be freed! * @return A pointer to a mailimf_optional_field structure. Must not be freed!
* If field_name could not be found or has another type, NULL is returned. * If field_name could not be found or has another type, NULL is returned.
*/ */
struct mailimf_optional_field* mrmimeparser_lookup_optional_field(mrmimeparser_t* mimeparser, const char* field_name) struct mailimf_optional_field* dc_mimeparser_lookup_optional_field(dc_mimeparser_t* mimeparser, const char* field_name)
{ {
struct mailimf_field* field = mrhash_find_str(&mimeparser->m_header, field_name); struct mailimf_field* field = dc_hash_find_str(&mimeparser->m_header, field_name);
if( field && field->fld_type == MAILIMF_FIELD_OPTIONAL_FIELD ) { if( field && field->fld_type == MAILIMF_FIELD_OPTIONAL_FIELD ) {
return field->fld_data.fld_optional_field; return field->fld_data.fld_optional_field;
} }
@ -1734,10 +1734,10 @@ struct mailimf_optional_field* mrmimeparser_lookup_optional_field(mrmimeparser_t
* Lookup the first name and return, if found. * Lookup the first name and return, if found.
* If not, try to lookup the second name. * If not, try to lookup the second name.
*/ */
struct mailimf_optional_field* mrmimeparser_lookup_optional_field2(mrmimeparser_t* mimeparser, const char* field_name, const char* or_field_name) struct mailimf_optional_field* dc_mimeparser_lookup_optional_field2(dc_mimeparser_t* mimeparser, const char* field_name, const char* or_field_name)
{ {
struct mailimf_optional_field* of = mrmimeparser_lookup_optional_field(mimeparser, field_name); struct mailimf_optional_field* of = dc_mimeparser_lookup_optional_field(mimeparser, field_name);
return of? of : mrmimeparser_lookup_optional_field(mimeparser, or_field_name); return of? of : dc_mimeparser_lookup_optional_field(mimeparser, or_field_name);
} }
@ -1745,16 +1745,16 @@ struct mailimf_optional_field* mrmimeparser_lookup_optional_field2(mrmimeparser_
* Gets the _last_ part _not_ flagged with m_is_meta. * Gets the _last_ part _not_ flagged with m_is_meta.
* *
* If you just want to check if there is a non-meta part preset, you can also * If you just want to check if there is a non-meta part preset, you can also
* use the macro mrmimeparser_has_nonmeta(). * use the macro dc_mimeparser_has_nonmeta().
* *
* @private @memberof mrmimeparser_t * @private @memberof dc_mimeparser_t
* *
* @param ths The MIME-parser object. * @param ths The MIME-parser object.
* *
* @return The last part that is not flagged with m_is_meta. The returned value * @return The last part that is not flagged with m_is_meta. The returned value
* must not be freed. If there is no such part, NULL is returned. * must not be freed. If there is no such part, NULL is returned.
*/ */
mrmimepart_t* mrmimeparser_get_last_nonmeta(mrmimeparser_t* ths) mrmimepart_t* dc_mimeparser_get_last_nonmeta(dc_mimeparser_t* ths)
{ {
if( ths && ths->m_parts ) { if( ths && ths->m_parts ) {
int i, icnt = carray_count(ths->m_parts); int i, icnt = carray_count(ths->m_parts);
@ -1772,7 +1772,7 @@ mrmimepart_t* mrmimeparser_get_last_nonmeta(mrmimeparser_t* ths)
/** /**
* Checks, if the header of the mail looks as if it is a message from a mailing list. * Checks, if the header of the mail looks as if it is a message from a mailing list.
* *
* @private @memberof mrmimeparser_t * @private @memberof dc_mimeparser_t
* *
* @param ths The MIME-parser object. * @param ths The MIME-parser object.
* *
@ -1817,17 +1817,17 @@ mrmimepart_t* mrmimeparser_get_last_nonmeta(mrmimeparser_t* ths)
* (NB: typical mailing list header: `From: sender@gmx.net To: list@address.net) * (NB: typical mailing list header: `From: sender@gmx.net To: list@address.net)
* *
*/ */
int mrmimeparser_is_mailinglist_message(mrmimeparser_t* ths) int dc_mimeparser_is_mailinglist_message(dc_mimeparser_t* ths)
{ {
if( ths == NULL ) { if( ths == NULL ) {
return 0; return 0;
} }
if( mrmimeparser_lookup_field(ths, "List-Id") != NULL ) { if( dc_mimeparser_lookup_field(ths, "List-Id") != NULL ) {
return 1; /* mailing list identified by the presence of `List-ID` from RFC 2919 */ return 1; /* mailing list identified by the presence of `List-ID` from RFC 2919 */
} }
struct mailimf_optional_field* precedence = mrmimeparser_lookup_optional_field(ths, "Precedence"); struct mailimf_optional_field* precedence = dc_mimeparser_lookup_optional_field(ths, "Precedence");
if( precedence != NULL ) { if( precedence != NULL ) {
if( strcasecmp(precedence->fld_value, "list")==0 if( strcasecmp(precedence->fld_value, "list")==0
|| strcasecmp(precedence->fld_value, "bulk")==0 ) { || strcasecmp(precedence->fld_value, "bulk")==0 ) {
@ -1849,21 +1849,21 @@ int mrmimeparser_is_mailinglist_message(mrmimeparser_t* ths)
* only that mailimf_get_recipients() was already there - and does not respect * only that mailimf_get_recipients() was already there - and does not respect
* memoryhole as used on a lower level before memoryhole is calculated) * memoryhole as used on a lower level before memoryhole is calculated)
* *
* @private @memberof mrmimeparser_t * @private @memberof dc_mimeparser_t
* *
* @param mimeparser The MIME-parser object. * @param mimeparser The MIME-parser object.
* *
* @return 1=Sender matches recipient * @return 1=Sender matches recipient
* 0=Sender does not match recipient or there are more than one recipients * 0=Sender does not match recipient or there are more than one recipients
*/ */
int mrmimeparser_sender_equals_recipient(mrmimeparser_t* mimeparser) int dc_mimeparser_sender_equals_recipient(dc_mimeparser_t* mimeparser)
{ {
int sender_equals_recipient = 0; int sender_equals_recipient = 0;
const struct mailimf_field* fld; const struct mailimf_field* fld;
const struct mailimf_from* fld_from; const struct mailimf_from* fld_from;
struct mailimf_mailbox* mb; struct mailimf_mailbox* mb;
char* from_addr_norm = NULL; char* from_addr_norm = NULL;
mrhash_t* recipients = NULL; dc_hash_t* recipients = NULL;
if( mimeparser == NULL || mimeparser->m_header_root == NULL ) { if( mimeparser == NULL || mimeparser->m_header_root == NULL ) {
goto cleanup; goto cleanup;
@ -1887,17 +1887,17 @@ int mrmimeparser_sender_equals_recipient(mrmimeparser_t* mimeparser)
/* get To:/Cc: and check there is exactly one recipent */ /* get To:/Cc: and check there is exactly one recipent */
recipients = mailimf_get_recipients(mimeparser->m_header_root); recipients = mailimf_get_recipients(mimeparser->m_header_root);
if( mrhash_count(recipients) != 1 ) { if( dc_hash_count(recipients) != 1 ) {
goto cleanup; goto cleanup;
} }
/* check if From: == To:/Cc: */ /* check if From: == To:/Cc: */
if( mrhash_find_str(recipients, from_addr_norm) ) { if( dc_hash_find_str(recipients, from_addr_norm) ) {
sender_equals_recipient = 1; sender_equals_recipient = 1;
} }
cleanup: cleanup:
mrhash_clear(recipients); dc_hash_clear(recipients);
free(recipients); free(recipients);
free(from_addr_norm); free(from_addr_norm);
return sender_equals_recipient; return sender_equals_recipient;

View file

@ -21,7 +21,7 @@
/* Parse MIME body; this is the text part of an IMF, see https://tools.ietf.org/html/rfc5322 /* Parse MIME body; this is the text part of an IMF, see https://tools.ietf.org/html/rfc5322
mrmimeparser_t has no deep dependencies to mrmailbox_t or to the database dc_mimeparser_t has no deep dependencies to mrmailbox_t or to the database
(mrmailbox_t is used for logging only). */ (mrmailbox_t is used for logging only). */
@ -53,15 +53,15 @@ typedef struct mrmimepart_t
} mrmimepart_t; } mrmimepart_t;
typedef struct mrmimeparser_t typedef struct dc_mimeparser_t
{ {
/** @privatesection */ /** @privatesection */
/* data, read-only, must not be free()'d (it is free()'d when the mrmimeparser_t object gets destructed) */ /* data, read-only, must not be free()'d (it is free()'d when the dc_mimeparser_t object gets destructed) */
carray* m_parts; /* array of mrmimepart_t objects */ carray* m_parts; /* array of mrmimepart_t objects */
struct mailmime* m_mimeroot; struct mailmime* m_mimeroot;
mrhash_t m_header; /* memoryhole-compliant header */ dc_hash_t m_header; /* memoryhole-compliant header */
struct mailimf_fields* m_header_root; /* must NOT be freed, do not use for query, merged into m_header, a pointer somewhere to the MIME data*/ struct mailimf_fields* m_header_root; /* must NOT be freed, do not use for query, merged into m_header, a pointer somewhere to the MIME data*/
struct mailimf_fields* m_header_protected; /* MUST be freed, do not use for query, merged into m_header */ struct mailimf_fields* m_header_protected; /* MUST be freed, do not use for query, merged into m_header */
@ -82,24 +82,24 @@ typedef struct mrmimeparser_t
int m_is_system_message; int m_is_system_message;
} mrmimeparser_t; } dc_mimeparser_t;
mrmimeparser_t* mrmimeparser_new (const char* blobdir, mrmailbox_t*); dc_mimeparser_t* dc_mimeparser_new (const char* blobdir, mrmailbox_t*);
void mrmimeparser_unref (mrmimeparser_t*); void dc_mimeparser_unref (dc_mimeparser_t*);
void mrmimeparser_empty (mrmimeparser_t*); void dc_mimeparser_empty (dc_mimeparser_t*);
void mrmimeparser_parse (mrmimeparser_t*, const char* body_not_terminated, size_t body_bytes); void dc_mimeparser_parse (dc_mimeparser_t*, const char* body_not_terminated, size_t body_bytes);
/* the following functions can be used only after a call to mrmimeparser_parse() */ /* the following functions can be used only after a call to dc_mimeparser_parse() */
struct mailimf_field* mrmimeparser_lookup_field (mrmimeparser_t*, const char* field_name); struct mailimf_field* dc_mimeparser_lookup_field (dc_mimeparser_t*, const char* field_name);
struct mailimf_optional_field* mrmimeparser_lookup_optional_field (mrmimeparser_t*, const char* field_name); struct mailimf_optional_field* dc_mimeparser_lookup_optional_field (dc_mimeparser_t*, const char* field_name);
struct mailimf_optional_field* mrmimeparser_lookup_optional_field2 (mrmimeparser_t*, const char* field_name, const char* or_field_name); struct mailimf_optional_field* dc_mimeparser_lookup_optional_field2 (dc_mimeparser_t*, const char* field_name, const char* or_field_name);
mrmimepart_t* mrmimeparser_get_last_nonmeta (mrmimeparser_t*); mrmimepart_t* dc_mimeparser_get_last_nonmeta (dc_mimeparser_t*);
#define mrmimeparser_has_nonmeta(a) (mrmimeparser_get_last_nonmeta((a))!=NULL) #define dc_mimeparser_has_nonmeta(a) (dc_mimeparser_get_last_nonmeta((a))!=NULL)
int mrmimeparser_is_mailinglist_message (mrmimeparser_t*); int dc_mimeparser_is_mailinglist_message (dc_mimeparser_t*);
int mrmimeparser_sender_equals_recipient(mrmimeparser_t*); int dc_mimeparser_sender_equals_recipient(dc_mimeparser_t*);
@ -113,7 +113,7 @@ struct mailimf_fields* mailmime_find_mailimf_fields (struct mailmime*);
char* mailimf_find_first_addr (const struct mailimf_mailbox_list*); /*the result must be freed*/ char* mailimf_find_first_addr (const struct mailimf_mailbox_list*); /*the result must be freed*/
struct mailimf_field* mailimf_find_field (struct mailimf_fields*, int wanted_fld_type); /*the result is a pointer to mime, must not be freed*/ struct mailimf_field* mailimf_find_field (struct mailimf_fields*, int wanted_fld_type); /*the result is a pointer to mime, must not be freed*/
struct mailimf_optional_field* mailimf_find_optional_field (struct mailimf_fields*, const char* wanted_fld_name); struct mailimf_optional_field* mailimf_find_optional_field (struct mailimf_fields*, const char* wanted_fld_name);
mrhash_t* mailimf_get_recipients (struct mailimf_fields*); dc_hash_t* mailimf_get_recipients (struct mailimf_fields*);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -72,7 +72,7 @@ void dc_msg_unref(dc_msg_t* msg)
return; return;
} }
mrmsg_empty(msg); dc_msg_empty(msg);
mrparam_unref(msg->m_param); mrparam_unref(msg->m_param);
msg->m_magic = 0; msg->m_magic = 0;
free(msg); free(msg);
@ -384,7 +384,7 @@ char* dc_msg_get_filemime(const dc_msg_t* msg)
if( file == NULL ) { if( file == NULL ) {
goto cleanup; goto cleanup;
} }
mrmsg_guess_msgtype_from_suffix(file, NULL, &ret); dc_msg_guess_msgtype_from_suffix(file, NULL, &ret);
if( ret == NULL ) { if( ret == NULL ) {
ret = safe_strdup("application/octet-stream"); ret = safe_strdup("application/octet-stream");
@ -453,9 +453,9 @@ cleanup:
*/ */
dc_lot_t* dc_msg_get_mediainfo(const dc_msg_t* msg) dc_lot_t* dc_msg_get_mediainfo(const dc_msg_t* msg)
{ {
mrlot_t* ret = mrlot_new(); dc_lot_t* ret = dc_lot_new();
char* pathNfilename = NULL; char* pathNfilename = NULL;
mrcontact_t* contact = NULL; dc_contact_t* contact = NULL;
if( msg == NULL || msg->m_magic != MR_MSG_MAGIC || msg->m_mailbox == NULL ) { if( msg == NULL || msg->m_magic != MR_MSG_MAGIC || msg->m_mailbox == NULL ) {
goto cleanup; goto cleanup;
@ -483,7 +483,7 @@ dc_lot_t* dc_msg_get_mediainfo(const dc_msg_t* msg)
if( pathNfilename == NULL ) { if( pathNfilename == NULL ) {
goto cleanup; goto cleanup;
} }
mrmsg_get_authorNtitle_from_filename(pathNfilename, &ret->m_text1, &ret->m_text2); dc_msg_get_authorNtitle_from_filename(pathNfilename, &ret->m_text1, &ret->m_text2);
if( ret->m_text1 == NULL && ret->m_text2 != NULL ) { if( ret->m_text1 == NULL && ret->m_text2 != NULL ) {
ret->m_text1 = mrstock_str(MR_STR_AUDIO); ret->m_text1 = mrstock_str(MR_STR_AUDIO);
} }
@ -491,7 +491,7 @@ dc_lot_t* dc_msg_get_mediainfo(const dc_msg_t* msg)
cleanup: cleanup:
free(pathNfilename); free(pathNfilename);
mrcontact_unref(contact); dc_contact_unref(contact);
return ret; return ret;
} }
@ -590,9 +590,9 @@ int dc_msg_get_showpadlock(const dc_msg_t* msg)
show_encryption_state = 1; show_encryption_state = 1;
} }
else { else {
mrchat_t* chat = mrmailbox_get_chat(msg->m_mailbox, msg->m_chat_id); dc_chat_t* chat = mrmailbox_get_chat(msg->m_mailbox, msg->m_chat_id);
show_encryption_state = mrchat_is_verified(chat); show_encryption_state = dc_chat_is_verified(chat);
mrchat_unref(chat); dc_chat_unref(chat);
} }
if( show_encryption_state ) { if( show_encryption_state ) {
@ -636,9 +636,9 @@ int dc_msg_get_showpadlock(const dc_msg_t* msg)
*/ */
dc_lot_t* dc_msg_get_summary(const dc_msg_t* msg, const dc_chat_t* chat) dc_lot_t* dc_msg_get_summary(const dc_msg_t* msg, const dc_chat_t* chat)
{ {
mrlot_t* ret = mrlot_new(); dc_lot_t* ret = dc_lot_new();
mrcontact_t* contact = NULL; dc_contact_t* contact = NULL;
mrchat_t* chat_to_delete = NULL; dc_chat_t* chat_to_delete = NULL;
if( msg==NULL || msg->m_magic != MR_MSG_MAGIC ) { if( msg==NULL || msg->m_magic != MR_MSG_MAGIC ) {
goto cleanup; goto cleanup;
@ -655,11 +655,11 @@ dc_lot_t* dc_msg_get_summary(const dc_msg_t* msg, const dc_chat_t* chat)
contact = mrmailbox_get_contact(chat->m_mailbox, msg->m_from_id); contact = mrmailbox_get_contact(chat->m_mailbox, msg->m_from_id);
} }
mrlot_fill(ret, msg, chat, contact); dc_lot_fill(ret, msg, chat, contact);
cleanup: cleanup:
mrcontact_unref(contact); dc_contact_unref(contact);
mrchat_unref(chat_to_delete); dc_chat_unref(chat_to_delete);
return ret; return ret;
} }
@ -683,7 +683,7 @@ char* dc_msg_get_summarytext(const dc_msg_t* msg, int approx_characters)
return safe_strdup(NULL); return safe_strdup(NULL);
} }
return mrmsg_get_summarytext_by_raw(msg->m_type, msg->m_text, msg->m_param, approx_characters); return dc_msg_get_summarytext_by_raw(msg->m_type, msg->m_text, msg->m_param, approx_characters);
} }
@ -845,11 +845,11 @@ char* dc_msg_get_setupcodebegin(const dc_msg_t* msg)
const char* buf_setupcodebegin = NULL; // just a pointer inside buf, MUST NOT be free()'d const char* buf_setupcodebegin = NULL; // just a pointer inside buf, MUST NOT be free()'d
char* ret = NULL; char* ret = NULL;
if( !mrmsg_is_setupmessage(msg) ) { if( !dc_msg_is_setupmessage(msg) ) {
goto cleanup; goto cleanup;
} }
if( (filename=mrmsg_get_file(msg))==NULL || filename[0]==0 ) { if( (filename=dc_msg_get_file(msg))==NULL || filename[0]==0 ) {
goto cleanup; goto cleanup;
} }
@ -857,7 +857,7 @@ char* dc_msg_get_setupcodebegin(const dc_msg_t* msg)
goto cleanup; goto cleanup;
} }
if( !mr_split_armored_data(buf, &buf_headerline, &buf_setupcodebegin, NULL, NULL) if( !dc_split_armored_data(buf, &buf_headerline, &buf_setupcodebegin, NULL, NULL)
|| strcmp(buf_headerline, "-----BEGIN PGP MESSAGE-----")!=0 || buf_setupcodebegin==NULL ) { || strcmp(buf_headerline, "-----BEGIN PGP MESSAGE-----")!=0 || buf_setupcodebegin==NULL ) {
goto cleanup; goto cleanup;
} }
@ -881,9 +881,9 @@ cleanup:
" m.param,m.starred,m.hidden,c.blocked " " m.param,m.starred,m.hidden,c.blocked "
static int mrmsg_set_from_stmt__(dc_msg_t* ths, sqlite3_stmt* row, int row_offset) /* field order must be MR_MSG_FIELDS */ static int dc_msg_set_from_stmt__(dc_msg_t* ths, sqlite3_stmt* row, int row_offset) /* field order must be MR_MSG_FIELDS */
{ {
mrmsg_empty(ths); dc_msg_empty(ths);
ths->m_id = (uint32_t)sqlite3_column_int (row, row_offset++); ths->m_id = (uint32_t)sqlite3_column_int (row, row_offset++);
ths->m_rfc724_mid = safe_strdup((char*)sqlite3_column_text (row, row_offset++)); ths->m_rfc724_mid = safe_strdup((char*)sqlite3_column_text (row, row_offset++));
@ -923,7 +923,7 @@ static int mrmsg_set_from_stmt__(dc_msg_t* ths, sqlite3_stmt* row, int row_offse
* *
* @private @memberof dc_msg_t * @private @memberof dc_msg_t
*/ */
int mrmsg_load_from_db__(dc_msg_t* ths, mrmailbox_t* mailbox, uint32_t id) int dc_msg_load_from_db__(dc_msg_t* ths, mrmailbox_t* mailbox, uint32_t id)
{ {
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
@ -931,7 +931,7 @@ int mrmsg_load_from_db__(dc_msg_t* ths, mrmailbox_t* mailbox, uint32_t id)
return 0; return 0;
} }
stmt = mrsqlite3_predefine__(mailbox->m_sql, SELECT_ircftttstpb_FROM_msg_WHERE_i, stmt = dc_sqlite3_predefine__(mailbox->m_sql, SELECT_ircftttstpb_FROM_msg_WHERE_i,
"SELECT " MR_MSG_FIELDS "SELECT " MR_MSG_FIELDS
" FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id" " FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id"
" WHERE m.id=?;"); " WHERE m.id=?;");
@ -941,7 +941,7 @@ int mrmsg_load_from_db__(dc_msg_t* ths, mrmailbox_t* mailbox, uint32_t id)
return 0; return 0;
} }
if( !mrmsg_set_from_stmt__(ths, stmt, 0) ) { /* also calls mrmsg_empty() */ if( !dc_msg_set_from_stmt__(ths, stmt, 0) ) { /* also calls dc_msg_empty() */
return 0; return 0;
} }
@ -965,7 +965,7 @@ int mrmsg_load_from_db__(dc_msg_t* ths, mrmailbox_t* mailbox, uint32_t id)
* *
* @return None. But there are output parameters. * @return None. But there are output parameters.
*/ */
void mrmsg_guess_msgtype_from_suffix(const char* pathNfilename, int* ret_msgtype, char** ret_mime) void dc_msg_guess_msgtype_from_suffix(const char* pathNfilename, int* ret_msgtype, char** ret_mime)
{ {
char* suffix = NULL; char* suffix = NULL;
int dummy_msgtype = 0; int dummy_msgtype = 0;
@ -1013,7 +1013,7 @@ cleanup:
} }
void mrmsg_get_authorNtitle_from_filename(const char* pathNfilename, char** ret_author, char** ret_title) void dc_msg_get_authorNtitle_from_filename(const char* pathNfilename, char** ret_author, char** ret_title)
{ {
/* function extracts AUTHOR and TITLE from a path given as `/path/other folder/AUTHOR - TITLE.mp3` /* function extracts AUTHOR and TITLE from a path given as `/path/other folder/AUTHOR - TITLE.mp3`
if the mark ` - ` is not preset, the whole name (without suffix) is used as the title and the author is NULL. */ if the mark ` - ` is not preset, the whole name (without suffix) is used as the title and the author is NULL. */
@ -1031,7 +1031,7 @@ void mrmsg_get_authorNtitle_from_filename(const char* pathNfilename, char** ret_
} }
char* mrmsg_get_summarytext_by_raw(int type, const char* text, mrparam_t* param, int approx_characters) char* dc_msg_get_summarytext_by_raw(int type, const char* text, mrparam_t* param, int approx_characters)
{ {
/* get a summary text, result must be free()'d, never returns NULL. */ /* get a summary text, result must be free()'d, never returns NULL. */
char* ret = NULL; char* ret = NULL;
@ -1057,7 +1057,7 @@ char* mrmsg_get_summarytext_by_raw(int type, const char* text, mrparam_t* param,
case MR_MSG_AUDIO: case MR_MSG_AUDIO:
if( (value=mrparam_get(param, MRP_TRACKNAME, NULL))==NULL ) { /* although we send files with "author - title" in the filename, existing files may follow other conventions, so this lookup is neccessary */ if( (value=mrparam_get(param, MRP_TRACKNAME, NULL))==NULL ) { /* although we send files with "author - title" in the filename, existing files may follow other conventions, so this lookup is neccessary */
pathNfilename = mrparam_get(param, MRP_FILE, "ErrFilename"); pathNfilename = mrparam_get(param, MRP_FILE, "ErrFilename");
mrmsg_get_authorNtitle_from_filename(pathNfilename, NULL, &value); dc_msg_get_authorNtitle_from_filename(pathNfilename, NULL, &value);
} }
label = mrstock_str(MR_STR_AUDIO); label = mrstock_str(MR_STR_AUDIO);
ret = mr_mprintf("%s: %s", label, value); ret = mr_mprintf("%s: %s", label, value);
@ -1094,7 +1094,7 @@ char* mrmsg_get_summarytext_by_raw(int type, const char* text, mrparam_t* param,
} }
int mrmsg_is_increation__(const dc_msg_t* msg) int dc_msg_is_increation__(const dc_msg_t* msg)
{ {
int is_increation = 0; int is_increation = 0;
if( MR_MSG_NEEDS_ATTACHMENT(msg->m_type) ) if( MR_MSG_NEEDS_ATTACHMENT(msg->m_type) )
@ -1131,7 +1131,7 @@ int mrmsg_is_increation__(const dc_msg_t* msg)
*/ */
int dc_msg_is_increation(const dc_msg_t* msg) int dc_msg_is_increation(const dc_msg_t* msg)
{ {
/* surrounds mrmsg_is_increation__() with locking and error checking */ /* surrounds dc_msg_is_increation__() with locking and error checking */
int is_increation = 0; int is_increation = 0;
if( msg == NULL || msg->m_magic != MR_MSG_MAGIC ) { if( msg == NULL || msg->m_magic != MR_MSG_MAGIC ) {
@ -1140,24 +1140,24 @@ int dc_msg_is_increation(const dc_msg_t* msg)
if( msg->m_mailbox && MR_MSG_NEEDS_ATTACHMENT(msg->m_type) /*additional check for speed reasons*/ ) if( msg->m_mailbox && MR_MSG_NEEDS_ATTACHMENT(msg->m_type) /*additional check for speed reasons*/ )
{ {
mrsqlite3_lock(msg->m_mailbox->m_sql); dc_sqlite3_lock(msg->m_mailbox->m_sql);
is_increation = mrmsg_is_increation__(msg); is_increation = dc_msg_is_increation__(msg);
mrsqlite3_unlock(msg->m_mailbox->m_sql); dc_sqlite3_unlock(msg->m_mailbox->m_sql);
} }
return is_increation; return is_increation;
} }
void mrmsg_save_param_to_disk__(dc_msg_t* msg) void dc_msg_save_param_to_disk__(dc_msg_t* msg)
{ {
if( msg == NULL || msg->m_magic != MR_MSG_MAGIC || msg->m_mailbox == NULL || msg->m_mailbox->m_sql == NULL ) { if( msg == NULL || msg->m_magic != MR_MSG_MAGIC || msg->m_mailbox == NULL || msg->m_mailbox->m_sql == NULL ) {
return; return;
} }
sqlite3_stmt* stmt = mrsqlite3_predefine__(msg->m_mailbox->m_sql, UPDATE_msgs_SET_param_WHERE_id, sqlite3_stmt* stmt = dc_sqlite3_predefine__(msg->m_mailbox->m_sql, UPDATE_msgs_SET_param_WHERE_id,
"UPDATE msgs SET param=? WHERE id=?;"); "UPDATE msgs SET param=? WHERE id=?;");
sqlite3_bind_text(stmt, 1, msg->m_param->m_packed, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 1, msg->m_param->m_packed, -1, SQLITE_STATIC);
sqlite3_bind_int (stmt, 2, msg->m_id); sqlite3_bind_int (stmt, 2, msg->m_id);
@ -1199,7 +1199,7 @@ void dc_msg_latefiling_mediasize(dc_msg_t* msg, int width, int height, int durat
goto cleanup; goto cleanup;
} }
mrsqlite3_lock(msg->m_mailbox->m_sql); dc_sqlite3_lock(msg->m_mailbox->m_sql);
locked = 1; locked = 1;
if( width > 0 ) { if( width > 0 ) {
@ -1214,11 +1214,11 @@ void dc_msg_latefiling_mediasize(dc_msg_t* msg, int width, int height, int durat
mrparam_set_int(msg->m_param, MRP_DURATION, duration); mrparam_set_int(msg->m_param, MRP_DURATION, duration);
} }
mrmsg_save_param_to_disk__(msg); dc_msg_save_param_to_disk__(msg);
mrsqlite3_unlock(msg->m_mailbox->m_sql); dc_sqlite3_unlock(msg->m_mailbox->m_sql);
locked = 0; locked = 0;
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(msg->m_mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(msg->m_mailbox->m_sql); }
} }

View file

@ -45,21 +45,21 @@ struct _dc_msg
/** /**
* Contact ID of the sender. Never 0. See mrcontact_t::m_id for special IDs. * Contact ID of the sender. Never 0. See dc_contact_t::m_id for special IDs.
* Use mrmailbox_get_contact() to load details about this contact. * Use mrmailbox_get_contact() to load details about this contact.
*/ */
uint32_t m_from_id; uint32_t m_from_id;
/** /**
* Contact ID of the recipient. Never 0. See mrcontact_t::m_id for special IDs. * Contact ID of the recipient. Never 0. See dc_contact_t::m_id for special IDs.
* Use mrmailbox_get_contact() to load details about this contact. * Use mrmailbox_get_contact() to load details about this contact.
*/ */
uint32_t m_to_id; uint32_t m_to_id;
/** /**
* Chat ID the message belongs to. Never 0. See mrchat_t::m_id for special IDs. * Chat ID the message belongs to. Never 0. See dc_chat_t::m_id for special IDs.
* Use mrmailbox_get_chat() to load details about the chat. * Use mrmailbox_get_chat() to load details about the chat.
*/ */
uint32_t m_chat_id; uint32_t m_chat_id;
@ -71,9 +71,9 @@ struct _dc_msg
//mrmailbox_t* m_mailbox; //mrmailbox_t* m_mailbox;
int m_type; /**< Message type. It is recommended to use mrmsg_set_type() and mrmsg_get_type() to access this field. */ int m_type; /**< Message type. It is recommended to use dc_msg_set_type() and dc_msg_get_type() to access this field. */
int m_state; /**< Message state. It is recommended to use mrmsg_get_state() to access this field. */ int m_state; /**< Message state. It is recommended to use dc_msg_get_state() to access this field. */
int m_hidden; /**< Used eg. for handshaking messages. */ int m_hidden; /**< Used eg. for handshaking messages. */
@ -81,7 +81,7 @@ struct _dc_msg
time_t m_timestamp_sent; /**< Unix time the message was sent. 0 if unset. */ time_t m_timestamp_sent; /**< Unix time the message was sent. 0 if unset. */
time_t m_timestamp_rcvd; /**< Unix time the message was recveived. 0 if unset. */ time_t m_timestamp_rcvd; /**< Unix time the message was recveived. 0 if unset. */
char* m_text; /**< Message text. NULL if unset. It is recommended to use mrmsg_set_text() and mrmsg_get_text() to access this field. */ char* m_text; /**< Message text. NULL if unset. It is recommended to use dc_msg_set_text() and dc_msg_get_text() to access this field. */
mrmailbox_t* m_mailbox; /**< may be NULL, set on loading from database and on sending */ mrmailbox_t* m_mailbox; /**< may be NULL, set on loading from database and on sending */
char* m_rfc724_mid; /**< The RFC-742 Message-ID */ char* m_rfc724_mid; /**< The RFC-742 Message-ID */
@ -94,12 +94,12 @@ struct _dc_msg
}; };
int mrmsg_load_from_db__ (mrmsg_t*, mrmailbox_t*, uint32_t id); int dc_msg_load_from_db__ (dc_msg_t*, mrmailbox_t*, uint32_t id);
int mrmsg_is_increation__ (const mrmsg_t*); int dc_msg_is_increation__ (const dc_msg_t*);
char* mrmsg_get_summarytext_by_raw (int type, const char* text, mrparam_t*, int approx_bytes); /* the returned value must be free()'d */ char* dc_msg_get_summarytext_by_raw (int type, const char* text, mrparam_t*, int approx_bytes); /* the returned value must be free()'d */
void mrmsg_save_param_to_disk__ (mrmsg_t*); void dc_msg_save_param_to_disk__ (dc_msg_t*);
void mrmsg_guess_msgtype_from_suffix (const char* pathNfilename, int* ret_msgtype, char** ret_mime); void dc_msg_guess_msgtype_from_suffix (const char* pathNfilename, int* ret_msgtype, char** ret_mime);
void mrmsg_get_authorNtitle_from_filename (const char* pathNfilename, char** ret_author, char** ret_title); void dc_msg_get_authorNtitle_from_filename (const char* pathNfilename, char** ret_author, char** ret_title);
#define MR_MSG_NEEDS_ATTACHMENT(a) ((a)==MR_MSG_IMAGE || (a)==MR_MSG_GIF || (a)==MR_MSG_AUDIO || (a)==MR_MSG_VOICE || (a)==MR_MSG_VIDEO || (a)==MR_MSG_FILE) #define MR_MSG_NEEDS_ATTACHMENT(a) ((a)==MR_MSG_IMAGE || (a)==MR_MSG_GIF || (a)==MR_MSG_AUDIO || (a)==MR_MSG_VOICE || (a)==MR_MSG_VIDEO || (a)==MR_MSG_FILE)
#define MR_MSG_MAKE_FILENAME_SEARCHABLE(a) ((a)==MR_MSG_AUDIO || (a)==MR_MSG_FILE || (a)==MR_MSG_VIDEO ) /* add filename.ext (without path) to m_text? this is needed for the fulltext search. The extension is useful to get all PDF, all MP3 etc. */ #define MR_MSG_MAKE_FILENAME_SEARCHABLE(a) ((a)==MR_MSG_AUDIO || (a)==MR_MSG_FILE || (a)==MR_MSG_VIDEO ) /* add filename.ext (without path) to m_text? this is needed for the fulltext search. The extension is useful to get all PDF, all MP3 etc. */

View file

@ -31,7 +31,7 @@ extern "C" {
* An object for handling key=value parameter lists; for the key, curently only * An object for handling key=value parameter lists; for the key, curently only
* a single character is allowed. * a single character is allowed.
* *
* The object is used eg. by mrchat_t or mrmsg_t, for readable paramter names, * The object is used eg. by dc_chat_t or dc_msg_t, for readable paramter names,
* these classes define some MRP_* constantats. * these classes define some MRP_* constantats.
* *
* Only for library-internal use. * Only for library-internal use.

View file

@ -51,7 +51,7 @@ one :-) */
static pgp_io_t s_io; static pgp_io_t s_io;
void mrpgp_init(mrmailbox_t* mailbox) void dc_pgp_init(mrmailbox_t* mailbox)
{ {
#ifdef __APPLE__ #ifdef __APPLE__
OPENSSL_init(); OPENSSL_init();
@ -70,12 +70,12 @@ void mrpgp_init(mrmailbox_t* mailbox)
} }
void mrpgp_exit(mrmailbox_t* mailbox) void dc_pgp_exit(mrmailbox_t* mailbox)
{ {
} }
void mrpgp_rand_seed(mrmailbox_t* mailbox, const void* buf, size_t bytes) void dc_pgp_rand_seed(mrmailbox_t* mailbox, const void* buf, size_t bytes)
{ {
if( buf == NULL || bytes <= 0 ) { if( buf == NULL || bytes <= 0 ) {
return; return;
@ -89,7 +89,7 @@ void mrpgp_rand_seed(mrmailbox_t* mailbox, const void* buf, size_t bytes)
The given buffer is modified and the returned pointers are just point inside the modified buffer, The given buffer is modified and the returned pointers are just point inside the modified buffer,
no additional data to free therefore. no additional data to free therefore.
(NB: netpgp allows only parsing of Version, Comment, MessageID, Hash and Charset) */ (NB: netpgp allows only parsing of Version, Comment, MessageID, Hash and Charset) */
int mr_split_armored_data(char* buf, const char** ret_headerline, const char** ret_setupcodebegin, const char** ret_preferencrypt, const char** ret_base64) int dc_split_armored_data(char* buf, const char** ret_headerline, const char** ret_setupcodebegin, const char** ret_preferencrypt, const char** ret_base64)
{ {
int success = 0; int success = 0;
size_t line_chars = 0; size_t line_chars = 0;
@ -296,7 +296,7 @@ static void add_subkey_binding_signature(pgp_subkeysig_t* p, pgp_key_t* primaryk
} }
int mrpgp_create_keypair(mrmailbox_t* mailbox, const char* addr, mrkey_t* ret_public_key, mrkey_t* ret_private_key) int dc_pgp_create_keypair(mrmailbox_t* mailbox, const char* addr, dc_key_t* ret_public_key, dc_key_t* ret_private_key)
{ {
int success = 0; int success = 0;
pgp_key_t seckey, pubkey, subkey; pgp_key_t seckey, pubkey, subkey;
@ -388,8 +388,8 @@ int mrpgp_create_keypair(mrmailbox_t* mailbox, const char* addr, mrkey_t* ret_pu
goto cleanup; goto cleanup;
} }
mrkey_set_from_binary(ret_public_key, pubmem->buf, pubmem->length, MR_PUBLIC); dc_key_set_from_binary(ret_public_key, pubmem->buf, pubmem->length, MR_PUBLIC);
mrkey_set_from_binary(ret_private_key, secmem->buf, secmem->length, MR_PRIVATE); dc_key_set_from_binary(ret_private_key, secmem->buf, secmem->length, MR_PRIVATE);
success = 1; success = 1;
@ -411,7 +411,7 @@ cleanup:
******************************************************************************/ ******************************************************************************/
int mrpgp_is_valid_key(mrmailbox_t* mailbox, const mrkey_t* raw_key) int dc_pgp_is_valid_key(mrmailbox_t* mailbox, const dc_key_t* raw_key)
{ {
int key_is_valid = 0; int key_is_valid = 0;
pgp_keyring_t* public_keys = calloc(1, sizeof(pgp_keyring_t)); pgp_keyring_t* public_keys = calloc(1, sizeof(pgp_keyring_t));
@ -442,7 +442,7 @@ cleanup:
} }
int mrpgp_calc_fingerprint(const mrkey_t* raw_key, uint8_t** ret_fingerprint, size_t* ret_fingerprint_bytes) int dc_pgp_calc_fingerprint(const dc_key_t* raw_key, uint8_t** ret_fingerprint, size_t* ret_fingerprint_bytes)
{ {
int success = 0; int success = 0;
pgp_keyring_t* public_keys = calloc(1, sizeof(pgp_keyring_t)); pgp_keyring_t* public_keys = calloc(1, sizeof(pgp_keyring_t));
@ -482,7 +482,7 @@ cleanup:
} }
int mrpgp_split_key(mrmailbox_t* mailbox, const mrkey_t* private_in, mrkey_t* ret_public_key) int dc_pgp_split_key(mrmailbox_t* mailbox, const dc_key_t* private_in, dc_key_t* ret_public_key)
{ {
int success = 0; int success = 0;
pgp_keyring_t* public_keys = calloc(1, sizeof(pgp_keyring_t)); pgp_keyring_t* public_keys = calloc(1, sizeof(pgp_keyring_t));
@ -515,7 +515,7 @@ int mrpgp_split_key(mrmailbox_t* mailbox, const mrkey_t* private_in, mrkey_t* re
goto cleanup; goto cleanup;
} }
mrkey_set_from_binary(ret_public_key, pubmem->buf, pubmem->length, MR_PUBLIC); dc_key_set_from_binary(ret_public_key, pubmem->buf, pubmem->length, MR_PUBLIC);
success = 1; success = 1;
@ -534,11 +534,11 @@ cleanup:
******************************************************************************/ ******************************************************************************/
int mrpgp_pk_encrypt( mrmailbox_t* mailbox, int dc_pgp_pk_encrypt( mrmailbox_t* mailbox,
const void* plain_text, const void* plain_text,
size_t plain_bytes, size_t plain_bytes,
const mrkeyring_t* raw_public_keys_for_encryption, const dc_keyring_t* raw_public_keys_for_encryption,
const mrkey_t* raw_private_key_for_signing, const dc_key_t* raw_private_key_for_signing,
int use_armor, int use_armor,
void** ret_ctext, void** ret_ctext,
size_t* ret_ctext_bytes) size_t* ret_ctext_bytes)
@ -625,15 +625,15 @@ cleanup:
} }
int mrpgp_pk_decrypt( mrmailbox_t* mailbox, int dc_pgp_pk_decrypt( mrmailbox_t* mailbox,
const void* ctext, const void* ctext,
size_t ctext_bytes, size_t ctext_bytes,
const mrkeyring_t* raw_private_keys_for_decryption, const dc_keyring_t* raw_private_keys_for_decryption,
const mrkeyring_t* raw_public_keys_for_validation, const dc_keyring_t* raw_public_keys_for_validation,
int use_armor, int use_armor,
void** ret_plain, void** ret_plain,
size_t* ret_plain_bytes, size_t* ret_plain_bytes,
mrhash_t* ret_signature_fingerprints) dc_hash_t* ret_signature_fingerprints)
{ {
pgp_keyring_t* public_keys = calloc(1, sizeof(pgp_keyring_t)); /*should be 0 after parsing*/ pgp_keyring_t* public_keys = calloc(1, sizeof(pgp_keyring_t)); /*should be 0 after parsing*/
pgp_keyring_t* private_keys = calloc(1, sizeof(pgp_keyring_t)); pgp_keyring_t* private_keys = calloc(1, sizeof(pgp_keyring_t));
@ -700,7 +700,7 @@ int mrpgp_pk_decrypt( mrmailbox_t* mailbox,
char* fingerprint_hex = mr_binary_to_uc_hex(key0->pubkeyfpr.fingerprint, key0->pubkeyfpr.length); char* fingerprint_hex = mr_binary_to_uc_hex(key0->pubkeyfpr.fingerprint, key0->pubkeyfpr.length);
if( fingerprint_hex ) { if( fingerprint_hex ) {
mrhash_insert(ret_signature_fingerprints, fingerprint_hex, strlen(fingerprint_hex), (void*)1); dc_hash_insert(ret_signature_fingerprints, fingerprint_hex, strlen(fingerprint_hex), (void*)1);
} }
free(fingerprint_hex); free(fingerprint_hex);
} }

View file

@ -20,8 +20,8 @@
******************************************************************************/ ******************************************************************************/
#ifndef __MRPGP_H__ #ifndef __DC_PGP_H__
#define __MRPGP_H__ #define __DC_PGP_H__
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -29,30 +29,30 @@ extern "C" {
/*** library-private **********************************************************/ /*** library-private **********************************************************/
typedef struct mrkey_t mrkey_t; typedef struct dc_key_t dc_key_t;
typedef struct mrkeyring_t mrkeyring_t; typedef struct dc_keyring_t dc_keyring_t;
/* validation errors */ /* validation errors */
#define MRE2EE_NO_VALID_SIGNATURE 0x02 #define MRE2EE_NO_VALID_SIGNATURE 0x02
/* misc. */ /* misc. */
void mrpgp_init (mrmailbox_t*); void dc_pgp_init (mrmailbox_t*);
void mrpgp_exit (mrmailbox_t*); void dc_pgp_exit (mrmailbox_t*);
void mrpgp_rand_seed (mrmailbox_t*, const void* buf, size_t bytes); void dc_pgp_rand_seed (mrmailbox_t*, const void* buf, size_t bytes);
int mr_split_armored_data (char* buf, const char** ret_headerline, const char** ret_setupcodebegin, const char** ret_preferencrypt, const char** ret_base64); int dc_split_armored_data (char* buf, const char** ret_headerline, const char** ret_setupcodebegin, const char** ret_preferencrypt, const char** ret_base64);
/* public key encryption */ /* public key encryption */
int mrpgp_create_keypair (mrmailbox_t*, const char* addr, mrkey_t* public_key, mrkey_t* private_key); int dc_pgp_create_keypair (mrmailbox_t*, const char* addr, dc_key_t* public_key, dc_key_t* private_key);
int mrpgp_is_valid_key (mrmailbox_t*, const mrkey_t*); int dc_pgp_is_valid_key (mrmailbox_t*, const dc_key_t*);
int mrpgp_calc_fingerprint (const mrkey_t*, uint8_t** fingerprint, size_t* fingerprint_bytes); int dc_pgp_calc_fingerprint (const dc_key_t*, uint8_t** fingerprint, size_t* fingerprint_bytes);
int mrpgp_split_key (mrmailbox_t*, const mrkey_t* private_in, mrkey_t* public_out); int dc_pgp_split_key (mrmailbox_t*, const dc_key_t* private_in, dc_key_t* public_out);
int mrpgp_pk_encrypt (mrmailbox_t*, const void* plain, size_t plain_bytes, const mrkeyring_t*, const mrkey_t* sign_key, int use_armor, void** ret_ctext, size_t* ret_ctext_bytes); int dc_pgp_pk_encrypt (mrmailbox_t*, const void* plain, size_t plain_bytes, const dc_keyring_t*, const dc_key_t* sign_key, int use_armor, void** ret_ctext, size_t* ret_ctext_bytes);
int mrpgp_pk_decrypt (mrmailbox_t*, const void* ctext, size_t ctext_bytes, const mrkeyring_t*, const mrkeyring_t* validate_keys, int use_armor, void** plain, size_t* plain_bytes, mrhash_t* ret_signature_fingerprints); int dc_pgp_pk_decrypt (mrmailbox_t*, const void* ctext, size_t ctext_bytes, const dc_keyring_t*, const dc_keyring_t* validate_keys, int use_armor, void** plain, size_t* plain_bytes, dc_hash_t* ret_signature_fingerprints);
#ifdef __cplusplus #ifdef __cplusplus
} /* /extern "C" */ } /* /extern "C" */
#endif #endif
#endif /* __MRPGP_H__ */ #endif // __DC_PGP_H__

View file

@ -54,7 +54,7 @@ dc_lot_t* dc_check_qr(dc_context_t* mailbox, const char* qr)
char* invitenumber = NULL; char* invitenumber = NULL;
char* auth = NULL; char* auth = NULL;
dc_apeerstate_t* peerstate = dc_apeerstate_new(mailbox); dc_apeerstate_t* peerstate = dc_apeerstate_new(mailbox);
mrlot_t* qr_parsed = mrlot_new(); dc_lot_t* qr_parsed = dc_lot_new();
uint32_t chat_id = 0; uint32_t chat_id = 0;
char* device_msg = NULL; char* device_msg = NULL;
char* grpid = NULL; char* grpid = NULL;
@ -207,7 +207,7 @@ dc_lot_t* dc_check_qr(dc_context_t* mailbox, const char* qr)
{ {
// _only_ fingerprint set ... // _only_ fingerprint set ...
// (we could also do this before/instead of a secure-join, however, this may require complicated questions in the ui) // (we could also do this before/instead of a secure-join, however, this may require complicated questions in the ui)
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
if( dc_apeerstate_load_by_fingerprint__(peerstate, mailbox->m_sql, fingerprint) ) { if( dc_apeerstate_load_by_fingerprint__(peerstate, mailbox->m_sql, fingerprint) ) {
@ -222,7 +222,7 @@ dc_lot_t* dc_check_qr(dc_context_t* mailbox, const char* qr)
qr_parsed->m_state = MR_QR_FPR_WITHOUT_ADDR; qr_parsed->m_state = MR_QR_FPR_WITHOUT_ADDR;
} }
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
} }
else else
@ -230,7 +230,7 @@ dc_lot_t* dc_check_qr(dc_context_t* mailbox, const char* qr)
// fingerprint + addr set, secure-join requested // fingerprint + addr set, secure-join requested
// do not comapre the fingerprint already - it may have changed - errors are catched later more proberly. // do not comapre the fingerprint already - it may have changed - errors are catched later more proberly.
// (theroretically, there is also the state "addr=set, fingerprint=set, invitenumber=0", however, currently, we won't get into this state) // (theroretically, there is also the state "addr=set, fingerprint=set, invitenumber=0", however, currently, we won't get into this state)
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
if( grpid && grpname ) { if( grpid && grpname ) {
@ -248,7 +248,7 @@ dc_lot_t* dc_check_qr(dc_context_t* mailbox, const char* qr)
qr_parsed->m_auth = safe_strdup(auth); qr_parsed->m_auth = safe_strdup(auth);
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
} }
} }
@ -273,7 +273,7 @@ dc_lot_t* dc_check_qr(dc_context_t* mailbox, const char* qr)
} }
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
free(addr); free(addr);
free(fingerprint); free(fingerprint);
dc_apeerstate_unref(peerstate); dc_apeerstate_unref(peerstate);

View file

@ -36,7 +36,7 @@
******************************************************************************/ ******************************************************************************/
static void add_or_lookup_contact_by_addr__(mrmailbox_t* mailbox, const char* display_name_enc, const char* addr_spec, int origin, mrarray_t* ids, int* check_self) static void add_or_lookup_contact_by_addr__(mrmailbox_t* mailbox, const char* display_name_enc, const char* addr_spec, int origin, dc_array_t* ids, int* check_self)
{ {
/* is addr_spec equal to SELF? */ /* is addr_spec equal to SELF? */
int dummy; int dummy;
@ -48,7 +48,7 @@ static void add_or_lookup_contact_by_addr__(mrmailbox_t* mailbox, const char* di
*check_self = 0; *check_self = 0;
char* self_addr = mrsqlite3_get_config__(mailbox->m_sql, "configured_addr", ""); char* self_addr = dc_sqlite3_get_config__(mailbox->m_sql, "configured_addr", "");
if( strcasecmp(self_addr, addr_spec)==0 ) { if( strcasecmp(self_addr, addr_spec)==0 ) {
*check_self = 1; *check_self = 1;
} }
@ -70,14 +70,14 @@ static void add_or_lookup_contact_by_addr__(mrmailbox_t* mailbox, const char* di
free(display_name_dec); free(display_name_dec);
if( row_id ) { if( row_id ) {
if( !mrarray_search_id(ids, row_id, NULL) ) { if( !dc_array_search_id(ids, row_id, NULL) ) {
mrarray_add_id(ids, row_id); dc_array_add_id(ids, row_id);
} }
} }
} }
static void mrmailbox_add_or_lookup_contacts_by_mailbox_list__(mrmailbox_t* mailbox, const struct mailimf_mailbox_list* mb_list, int origin, mrarray_t* ids, int* check_self) static void mrmailbox_add_or_lookup_contacts_by_mailbox_list__(mrmailbox_t* mailbox, const struct mailimf_mailbox_list* mb_list, int origin, dc_array_t* ids, int* check_self)
{ {
clistiter* cur; clistiter* cur;
@ -94,7 +94,7 @@ static void mrmailbox_add_or_lookup_contacts_by_mailbox_list__(mrmailbox_t* mail
} }
static void mrmailbox_add_or_lookup_contacts_by_address_list__(mrmailbox_t* mailbox, const struct mailimf_address_list* adr_list, int origin, mrarray_t* ids, int* check_self) static void mrmailbox_add_or_lookup_contacts_by_address_list__(mrmailbox_t* mailbox, const struct mailimf_address_list* adr_list, int origin, dc_array_t* ids, int* check_self)
{ {
clistiter* cur; clistiter* cur;
@ -130,7 +130,7 @@ static void mrmailbox_add_or_lookup_contacts_by_address_list__(mrmailbox_t* mail
static int is_known_rfc724_mid__(mrmailbox_t* mailbox, const char* rfc724_mid) static int is_known_rfc724_mid__(mrmailbox_t* mailbox, const char* rfc724_mid)
{ {
if( rfc724_mid ) { if( rfc724_mid ) {
sqlite3_stmt* stmt = mrsqlite3_predefine__(mailbox->m_sql, SELECT_id_FROM_msgs_WHERE_cm, sqlite3_stmt* stmt = dc_sqlite3_predefine__(mailbox->m_sql, SELECT_id_FROM_msgs_WHERE_cm,
"SELECT m.id FROM msgs m " "SELECT m.id FROM msgs m "
" LEFT JOIN chats c ON m.chat_id=c.id " " LEFT JOIN chats c ON m.chat_id=c.id "
" WHERE m.rfc724_mid=? " " WHERE m.rfc724_mid=? "
@ -160,13 +160,13 @@ static int is_known_rfc724_mid_in_list__(mrmailbox_t* mailbox, const clist* mid_
} }
static int mrmailbox_is_reply_to_known_message__(mrmailbox_t* mailbox, mrmimeparser_t* mime_parser) static int mrmailbox_is_reply_to_known_message__(mrmailbox_t* mailbox, dc_mimeparser_t* mime_parser)
{ {
/* check if the message is a reply to a known message; the replies are identified by the Message-ID from /* check if the message is a reply to a known message; the replies are identified by the Message-ID from
`In-Reply-To`/`References:` (to support non-Delta-Clients) or from `Chat-Predecessor:` (Delta clients, see comment in mrchat.c) */ `In-Reply-To`/`References:` (to support non-Delta-Clients) or from `Chat-Predecessor:` (Delta clients, see comment in mrchat.c) */
struct mailimf_optional_field* optional_field; struct mailimf_optional_field* optional_field;
if( (optional_field=mrmimeparser_lookup_optional_field2(mime_parser, "Chat-Predecessor", "X-MrPredecessor")) != NULL ) if( (optional_field=dc_mimeparser_lookup_optional_field2(mime_parser, "Chat-Predecessor", "X-MrPredecessor")) != NULL )
{ {
if( is_known_rfc724_mid__(mailbox, optional_field->fld_value) ) { if( is_known_rfc724_mid__(mailbox, optional_field->fld_value) ) {
return 1; return 1;
@ -174,7 +174,7 @@ static int mrmailbox_is_reply_to_known_message__(mrmailbox_t* mailbox, mrmimepar
} }
struct mailimf_field* field; struct mailimf_field* field;
if( (field=mrmimeparser_lookup_field(mime_parser, "In-Reply-To"))!=NULL if( (field=dc_mimeparser_lookup_field(mime_parser, "In-Reply-To"))!=NULL
&& field->fld_type == MAILIMF_FIELD_IN_REPLY_TO ) && field->fld_type == MAILIMF_FIELD_IN_REPLY_TO )
{ {
struct mailimf_in_reply_to* fld_in_reply_to = field->fld_data.fld_in_reply_to; struct mailimf_in_reply_to* fld_in_reply_to = field->fld_data.fld_in_reply_to;
@ -185,7 +185,7 @@ static int mrmailbox_is_reply_to_known_message__(mrmailbox_t* mailbox, mrmimepar
} }
} }
if( (field=mrmimeparser_lookup_field(mime_parser, "References"))!=NULL if( (field=dc_mimeparser_lookup_field(mime_parser, "References"))!=NULL
&& field->fld_type == MAILIMF_FIELD_REFERENCES ) && field->fld_type == MAILIMF_FIELD_REFERENCES )
{ {
struct mailimf_references* fld_references = field->fld_data.fld_references; struct mailimf_references* fld_references = field->fld_data.fld_references;
@ -208,7 +208,7 @@ static int mrmailbox_is_reply_to_known_message__(mrmailbox_t* mailbox, mrmimepar
static int is_msgrmsg_rfc724_mid__(mrmailbox_t* mailbox, const char* rfc724_mid) static int is_msgrmsg_rfc724_mid__(mrmailbox_t* mailbox, const char* rfc724_mid)
{ {
if( rfc724_mid ) { if( rfc724_mid ) {
sqlite3_stmt* stmt = mrsqlite3_predefine__(mailbox->m_sql, SELECT_id_FROM_msgs_WHERE_mcm, sqlite3_stmt* stmt = dc_sqlite3_predefine__(mailbox->m_sql, SELECT_id_FROM_msgs_WHERE_mcm,
"SELECT id FROM msgs " "SELECT id FROM msgs "
" WHERE rfc724_mid=? " " WHERE rfc724_mid=? "
" AND msgrmsg!=0 " " AND msgrmsg!=0 "
@ -237,7 +237,7 @@ static int is_msgrmsg_rfc724_mid_in_list__(mrmailbox_t* mailbox, const clist* mi
} }
static int mrmailbox_is_reply_to_messenger_message__(mrmailbox_t* mailbox, mrmimeparser_t* mime_parser) static int mrmailbox_is_reply_to_messenger_message__(mrmailbox_t* mailbox, dc_mimeparser_t* mime_parser)
{ {
/* function checks, if the message defined by mime_parser references a message send by us from Delta Chat. /* function checks, if the message defined by mime_parser references a message send by us from Delta Chat.
@ -247,7 +247,7 @@ static int mrmailbox_is_reply_to_messenger_message__(mrmailbox_t* mailbox, mrmim
- no check for the Chat-* headers (function is only called if it is no messenger message itself) */ - no check for the Chat-* headers (function is only called if it is no messenger message itself) */
struct mailimf_field* field; struct mailimf_field* field;
if( (field=mrmimeparser_lookup_field(mime_parser, "In-Reply-To"))!=NULL if( (field=dc_mimeparser_lookup_field(mime_parser, "In-Reply-To"))!=NULL
&& field->fld_type==MAILIMF_FIELD_IN_REPLY_TO ) && field->fld_type==MAILIMF_FIELD_IN_REPLY_TO )
{ {
struct mailimf_in_reply_to* fld_in_reply_to = field->fld_data.fld_in_reply_to; struct mailimf_in_reply_to* fld_in_reply_to = field->fld_data.fld_in_reply_to;
@ -258,7 +258,7 @@ static int mrmailbox_is_reply_to_messenger_message__(mrmailbox_t* mailbox, mrmim
} }
} }
if( (field=mrmimeparser_lookup_field(mime_parser, "References"))!=NULL if( (field=dc_mimeparser_lookup_field(mime_parser, "References"))!=NULL
&& field->fld_type==MAILIMF_FIELD_REFERENCES ) && field->fld_type==MAILIMF_FIELD_REFERENCES )
{ {
struct mailimf_references* fld_references = field->fld_data.fld_references; struct mailimf_references* fld_references = field->fld_data.fld_references;
@ -298,7 +298,7 @@ static void mrmailbox_calc_timestamps__(mrmailbox_t* mailbox, uint32_t chat_id,
(we do this check only for fresh messages, other messages may pop up whereever, this may happen eg. when restoring old messages or synchronizing different clients) */ (we do this check only for fresh messages, other messages may pop up whereever, this may happen eg. when restoring old messages or synchronizing different clients) */
if( is_fresh_msg ) if( is_fresh_msg )
{ {
sqlite3_stmt* stmt = mrsqlite3_predefine__(mailbox->m_sql, SELECT_timestamp_FROM_msgs_WHERE_timestamp, sqlite3_stmt* stmt = dc_sqlite3_predefine__(mailbox->m_sql, SELECT_timestamp_FROM_msgs_WHERE_timestamp,
"SELECT MAX(timestamp) FROM msgs WHERE chat_id=? and from_id!=? AND timestamp>=?"); "SELECT MAX(timestamp) FROM msgs WHERE chat_id=? and from_id!=? AND timestamp>=?");
sqlite3_bind_int (stmt, 1, chat_id); sqlite3_bind_int (stmt, 1, chat_id);
sqlite3_bind_int (stmt, 2, from_id); sqlite3_bind_int (stmt, 2, from_id);
@ -323,13 +323,13 @@ static void mrmailbox_calc_timestamps__(mrmailbox_t* mailbox, uint32_t chat_id,
} }
static mrarray_t* search_chat_ids_by_contact_ids(mrmailbox_t* mailbox, const mrarray_t* unsorted_contact_ids) static dc_array_t* search_chat_ids_by_contact_ids(mrmailbox_t* mailbox, const dc_array_t* unsorted_contact_ids)
{ {
/* searches chat_id's by the given contact IDs, may return zero, one or more chat_id's */ /* searches chat_id's by the given contact IDs, may return zero, one or more chat_id's */
sqlite3_stmt* stmt = NULL; sqlite3_stmt* stmt = NULL;
mrarray_t* contact_ids = mrarray_new(mailbox, 23); dc_array_t* contact_ids = dc_array_new(mailbox, 23);
char* contact_ids_str = NULL, *q3 = NULL; char* contact_ids_str = NULL, *q3 = NULL;
mrarray_t* chat_ids = mrarray_new(mailbox, 23); dc_array_t* chat_ids = dc_array_new(mailbox, 23);
if( mailbox == NULL || mailbox->m_magic != MR_MAILBOX_MAGIC ) { if( mailbox == NULL || mailbox->m_magic != MR_MAILBOX_MAGIC ) {
goto cleanup; goto cleanup;
@ -337,27 +337,27 @@ static mrarray_t* search_chat_ids_by_contact_ids(mrmailbox_t* mailbox, const mra
/* copy array, remove duplicates and SELF, sort by ID */ /* copy array, remove duplicates and SELF, sort by ID */
{ {
int i, iCnt = mrarray_get_cnt(unsorted_contact_ids); int i, iCnt = dc_array_get_cnt(unsorted_contact_ids);
if( iCnt <= 0 ) { if( iCnt <= 0 ) {
goto cleanup; goto cleanup;
} }
for( i = 0; i < iCnt; i++ ) { for( i = 0; i < iCnt; i++ ) {
uint32_t curr_id = mrarray_get_id(unsorted_contact_ids, i); uint32_t curr_id = dc_array_get_id(unsorted_contact_ids, i);
if( curr_id != MR_CONTACT_ID_SELF && !mrarray_search_id(contact_ids, curr_id, NULL) ) { if( curr_id != MR_CONTACT_ID_SELF && !dc_array_search_id(contact_ids, curr_id, NULL) ) {
mrarray_add_id(contact_ids, curr_id); dc_array_add_id(contact_ids, curr_id);
} }
} }
if( mrarray_get_cnt(contact_ids)==0 ) { if( dc_array_get_cnt(contact_ids)==0 ) {
goto cleanup; goto cleanup;
} }
mrarray_sort_ids(contact_ids); /* for easy comparison, we also sort the sql result below */ dc_array_sort_ids(contact_ids); /* for easy comparison, we also sort the sql result below */
} }
/* collect all possible chats with the contact count as the data (as contact_ids have no doubles, this is sufficient) */ /* collect all possible chats with the contact count as the data (as contact_ids have no doubles, this is sufficient) */
contact_ids_str = mrarray_get_string(contact_ids, ","); contact_ids_str = dc_array_get_string(contact_ids, ",");
q3 = sqlite3_mprintf("SELECT DISTINCT cc.chat_id, cc.contact_id " q3 = sqlite3_mprintf("SELECT DISTINCT cc.chat_id, cc.contact_id "
" FROM chats_contacts cc " " FROM chats_contacts cc "
" LEFT JOIN chats c ON c.id=cc.chat_id " " LEFT JOIN chats c ON c.id=cc.chat_id "
@ -366,7 +366,7 @@ static mrarray_t* search_chat_ids_by_contact_ids(mrmailbox_t* mailbox, const mra
" AND cc.contact_id!=" MR_STRINGIFY(MR_CONTACT_ID_SELF) /* ignore SELF, we've also removed it above - if the user has left the group, it is still the same group */ " AND cc.contact_id!=" MR_STRINGIFY(MR_CONTACT_ID_SELF) /* ignore SELF, we've also removed it above - if the user has left the group, it is still the same group */
" ORDER BY cc.chat_id, cc.contact_id;", " ORDER BY cc.chat_id, cc.contact_id;",
contact_ids_str); contact_ids_str);
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, q3); stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql, q3);
{ {
uint32_t last_chat_id = 0, matches = 0, mismatches = 0; uint32_t last_chat_id = 0, matches = 0, mismatches = 0;
@ -376,15 +376,15 @@ static mrarray_t* search_chat_ids_by_contact_ids(mrmailbox_t* mailbox, const mra
uint32_t contact_id = sqlite3_column_int(stmt, 1); uint32_t contact_id = sqlite3_column_int(stmt, 1);
if( chat_id != last_chat_id ) { if( chat_id != last_chat_id ) {
if( matches == mrarray_get_cnt(contact_ids) && mismatches == 0 ) { if( matches == dc_array_get_cnt(contact_ids) && mismatches == 0 ) {
mrarray_add_id(chat_ids, last_chat_id); dc_array_add_id(chat_ids, last_chat_id);
} }
last_chat_id = chat_id; last_chat_id = chat_id;
matches = 0; matches = 0;
mismatches = 0; mismatches = 0;
} }
if( contact_id == mrarray_get_id(contact_ids, matches) ) { if( contact_id == dc_array_get_id(contact_ids, matches) ) {
matches++; matches++;
} }
else { else {
@ -392,21 +392,21 @@ static mrarray_t* search_chat_ids_by_contact_ids(mrmailbox_t* mailbox, const mra
} }
} }
if( matches == mrarray_get_cnt(contact_ids) && mismatches == 0 ) { if( matches == dc_array_get_cnt(contact_ids) && mismatches == 0 ) {
mrarray_add_id(chat_ids, last_chat_id); dc_array_add_id(chat_ids, last_chat_id);
} }
} }
cleanup: cleanup:
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
free(contact_ids_str); free(contact_ids_str);
mrarray_unref(contact_ids); dc_array_unref(contact_ids);
sqlite3_free(q3); sqlite3_free(q3);
return chat_ids; return chat_ids;
} }
static char* create_adhoc_grp_id__(mrmailbox_t* mailbox, mrarray_t* member_ids /*including SELF*/) static char* create_adhoc_grp_id__(mrmailbox_t* mailbox, dc_array_t* member_ids /*including SELF*/)
{ {
/* algorithm: /* algorithm:
- sort normalized, lowercased, e-mail addresses alphabetically - sort normalized, lowercased, e-mail addresses alphabetically
@ -414,8 +414,8 @@ static char* create_adhoc_grp_id__(mrmailbox_t* mailbox, mrarray_t* member_ids /
- sha-256 this string (without possibly terminating null-characters) - sha-256 this string (without possibly terminating null-characters)
- encode the first 64 bits of the sha-256 output as lowercase hex (results in 16 characters from the set [0-9a-f]) - encode the first 64 bits of the sha-256 output as lowercase hex (results in 16 characters from the set [0-9a-f])
*/ */
mrarray_t* member_addrs = mrarray_new(mailbox, 23); dc_array_t* member_addrs = dc_array_new(mailbox, 23);
char* member_ids_str = mrarray_get_string(member_ids, ","); char* member_ids_str = dc_array_get_string(member_ids, ",");
mrstrbuilder_t member_cs; mrstrbuilder_t member_cs;
sqlite3_stmt* stmt = NULL; sqlite3_stmt* stmt = NULL;
char* q3 = NULL, *addr; char* q3 = NULL, *addr;
@ -427,22 +427,22 @@ static char* create_adhoc_grp_id__(mrmailbox_t* mailbox, mrarray_t* member_ids /
/* collect all addresses and sort them */ /* collect all addresses and sort them */
q3 = sqlite3_mprintf("SELECT addr FROM contacts WHERE id IN(%s) AND id!=" MR_STRINGIFY(MR_CONTACT_ID_SELF), member_ids_str); q3 = sqlite3_mprintf("SELECT addr FROM contacts WHERE id IN(%s) AND id!=" MR_STRINGIFY(MR_CONTACT_ID_SELF), member_ids_str);
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, q3); stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql, q3);
addr = mrsqlite3_get_config__(mailbox->m_sql, "configured_addr", "no-self"); addr = dc_sqlite3_get_config__(mailbox->m_sql, "configured_addr", "no-self");
mr_strlower_in_place(addr); mr_strlower_in_place(addr);
mrarray_add_ptr(member_addrs, addr); dc_array_add_ptr(member_addrs, addr);
while( sqlite3_step(stmt)==SQLITE_ROW ) { while( sqlite3_step(stmt)==SQLITE_ROW ) {
addr = safe_strdup((const char*)sqlite3_column_text(stmt, 0)); addr = safe_strdup((const char*)sqlite3_column_text(stmt, 0));
mr_strlower_in_place(addr); mr_strlower_in_place(addr);
mrarray_add_ptr(member_addrs, addr); dc_array_add_ptr(member_addrs, addr);
} }
mrarray_sort_strings(member_addrs); dc_array_sort_strings(member_addrs);
/* build a single, comma-separated (cs) string from all addresses */ /* build a single, comma-separated (cs) string from all addresses */
iCnt = mrarray_get_cnt(member_addrs); iCnt = dc_array_get_cnt(member_addrs);
for( i = 0; i < iCnt; i++ ) { for( i = 0; i < iCnt; i++ ) {
if( i ) { mrstrbuilder_cat(&member_cs, ","); } if( i ) { mrstrbuilder_cat(&member_cs, ","); }
mrstrbuilder_cat(&member_cs, (const char*)mrarray_get_ptr(member_addrs, i)); mrstrbuilder_cat(&member_cs, (const char*)dc_array_get_ptr(member_addrs, i));
} }
/* make sha-256 from the string */ /* make sha-256 from the string */
@ -462,8 +462,8 @@ static char* create_adhoc_grp_id__(mrmailbox_t* mailbox, mrarray_t* member_ids /
} }
/* cleanup */ /* cleanup */
mrarray_free_ptr(member_addrs); dc_array_free_ptr(member_addrs);
mrarray_unref(member_addrs); dc_array_unref(member_addrs);
free(member_ids_str); free(member_ids_str);
free(binary_hash); free(binary_hash);
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
@ -478,7 +478,7 @@ static uint32_t create_group_record__(mrmailbox_t* mailbox, const char* grpid, c
uint32_t chat_id = 0; uint32_t chat_id = 0;
sqlite3_stmt* stmt = NULL; sqlite3_stmt* stmt = NULL;
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql,
"INSERT INTO chats (type, name, grpid, blocked) VALUES(?, ?, ?, ?);"); "INSERT INTO chats (type, name, grpid, blocked) VALUES(?, ?, ?, ?);");
sqlite3_bind_int (stmt, 1, create_verified? MR_CHAT_TYPE_VERIFIED_GROUP : MR_CHAT_TYPE_GROUP); sqlite3_bind_int (stmt, 1, create_verified? MR_CHAT_TYPE_VERIFIED_GROUP : MR_CHAT_TYPE_GROUP);
sqlite3_bind_text(stmt, 2, grpname, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 2, grpname, -1, SQLITE_STATIC);
@ -500,36 +500,36 @@ cleanup:
******************************************************************************/ ******************************************************************************/
static void create_or_lookup_adhoc_group__(mrmailbox_t* mailbox, mrmimeparser_t* mime_parser, int create_blocked, static void create_or_lookup_adhoc_group__(mrmailbox_t* mailbox, dc_mimeparser_t* mime_parser, int create_blocked,
int32_t from_id, const mrarray_t* to_ids,/*does not contain SELF*/ int32_t from_id, const dc_array_t* to_ids,/*does not contain SELF*/
uint32_t* ret_chat_id, int* ret_chat_id_blocked) uint32_t* ret_chat_id, int* ret_chat_id_blocked)
{ {
/* if we're here, no grpid was found, check there is an existing ad-hoc /* if we're here, no grpid was found, check there is an existing ad-hoc
group matching the to-list or if we can create one */ group matching the to-list or if we can create one */
mrarray_t* member_ids = NULL; dc_array_t* member_ids = NULL;
uint32_t chat_id = 0; uint32_t chat_id = 0;
int chat_id_blocked = 0, i; int chat_id_blocked = 0, i;
mrarray_t* chat_ids = NULL; dc_array_t* chat_ids = NULL;
char* chat_ids_str = NULL, *q3 = NULL; char* chat_ids_str = NULL, *q3 = NULL;
sqlite3_stmt* stmt = NULL; sqlite3_stmt* stmt = NULL;
char* grpid = NULL; char* grpid = NULL;
char* grpname = NULL; char* grpname = NULL;
/* build member list from the given ids */ /* build member list from the given ids */
if( mrarray_get_cnt(to_ids)==0 || mrmimeparser_is_mailinglist_message(mime_parser) ) { if( dc_array_get_cnt(to_ids)==0 || dc_mimeparser_is_mailinglist_message(mime_parser) ) {
goto cleanup; /* too few contacts or a mailinglist */ goto cleanup; /* too few contacts or a mailinglist */
} }
member_ids = mrarray_duplicate(to_ids); member_ids = dc_array_duplicate(to_ids);
if( !mrarray_search_id(member_ids, from_id, NULL) ) { mrarray_add_id(member_ids, from_id); } if( !dc_array_search_id(member_ids, from_id, NULL) ) { dc_array_add_id(member_ids, from_id); }
if( !mrarray_search_id(member_ids, MR_CONTACT_ID_SELF, NULL) ) { mrarray_add_id(member_ids, MR_CONTACT_ID_SELF); } if( !dc_array_search_id(member_ids, MR_CONTACT_ID_SELF, NULL) ) { dc_array_add_id(member_ids, MR_CONTACT_ID_SELF); }
if( mrarray_get_cnt(member_ids) < 3 ) { if( dc_array_get_cnt(member_ids) < 3 ) {
goto cleanup; /* too few contacts given */ goto cleanup; /* too few contacts given */
} }
/* check if the member list matches other chats, if so, choose the one with the most recent activity */ /* check if the member list matches other chats, if so, choose the one with the most recent activity */
chat_ids = search_chat_ids_by_contact_ids(mailbox, member_ids); chat_ids = search_chat_ids_by_contact_ids(mailbox, member_ids);
if( mrarray_get_cnt(chat_ids)>0 ) { if( dc_array_get_cnt(chat_ids)>0 ) {
chat_ids_str = mrarray_get_string(chat_ids, ","); chat_ids_str = dc_array_get_string(chat_ids, ",");
q3 = sqlite3_mprintf("SELECT c.id, c.blocked " q3 = sqlite3_mprintf("SELECT c.id, c.blocked "
" FROM chats c " " FROM chats c "
" LEFT JOIN msgs m ON m.chat_id=c.id " " LEFT JOIN msgs m ON m.chat_id=c.id "
@ -537,7 +537,7 @@ static void create_or_lookup_adhoc_group__(mrmailbox_t* mailbox, mrmimeparser_t*
" ORDER BY m.timestamp DESC, m.id DESC " " ORDER BY m.timestamp DESC, m.id DESC "
" LIMIT 1;", " LIMIT 1;",
chat_ids_str); chat_ids_str);
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, q3); stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql, q3);
if( sqlite3_step(stmt)==SQLITE_ROW ) { if( sqlite3_step(stmt)==SQLITE_ROW ) {
chat_id = sqlite3_column_int(stmt, 0); chat_id = sqlite3_column_int(stmt, 0);
chat_id_blocked = sqlite3_column_int(stmt, 1); chat_id_blocked = sqlite3_column_int(stmt, 1);
@ -559,21 +559,21 @@ static void create_or_lookup_adhoc_group__(mrmailbox_t* mailbox, mrmimeparser_t*
grpname = safe_strdup(mime_parser->m_subject); grpname = safe_strdup(mime_parser->m_subject);
} }
else { else {
grpname = mrstock_str_repl_pl(MR_STR_MEMBER, mrarray_get_cnt(member_ids)); grpname = mrstock_str_repl_pl(MR_STR_MEMBER, dc_array_get_cnt(member_ids));
} }
/* create group record */ /* create group record */
chat_id = create_group_record__(mailbox, grpid, grpname, create_blocked, 0); chat_id = create_group_record__(mailbox, grpid, grpname, create_blocked, 0);
chat_id_blocked = create_blocked; chat_id_blocked = create_blocked;
for( i = 0; i < mrarray_get_cnt(member_ids); i++ ) { for( i = 0; i < dc_array_get_cnt(member_ids); i++ ) {
mrmailbox_add_to_chat_contacts_table__(mailbox, chat_id, mrarray_get_id(member_ids, i)); mrmailbox_add_to_chat_contacts_table__(mailbox, chat_id, dc_array_get_id(member_ids, i));
} }
mailbox->m_cb(mailbox, DC_EVENT_CHAT_MODIFIED, chat_id, 0); mailbox->m_cb(mailbox, DC_EVENT_CHAT_MODIFIED, chat_id, 0);
cleanup: cleanup:
mrarray_unref(member_ids); dc_array_unref(member_ids);
mrarray_unref(chat_ids); dc_array_unref(chat_ids);
free(chat_ids_str); free(chat_ids_str);
free(grpid); free(grpid);
free(grpname); free(grpname);
@ -584,20 +584,20 @@ cleanup:
} }
static int check_verified_properties__(mrmailbox_t* mailbox, mrmimeparser_t* mimeparser, static int check_verified_properties__(mrmailbox_t* mailbox, dc_mimeparser_t* mimeparser,
uint32_t from_id, const mrarray_t* to_ids) uint32_t from_id, const dc_array_t* to_ids)
{ {
int everythings_okay = 0; int everythings_okay = 0;
mrcontact_t* contact = mrcontact_new(mailbox); dc_contact_t* contact = dc_contact_new(mailbox);
dc_apeerstate_t* peerstate = dc_apeerstate_new(mailbox); dc_apeerstate_t* peerstate = dc_apeerstate_new(mailbox);
char* to_ids_str = NULL; char* to_ids_str = NULL;
char* q3 = NULL; char* q3 = NULL;
sqlite3_stmt* stmt = NULL; sqlite3_stmt* stmt = NULL;
// ensure, the contact is verified // ensure, the contact is verified
if( !mrcontact_load_from_db__(contact, mailbox->m_sql, from_id) if( !dc_contact_load_from_db__(contact, mailbox->m_sql, from_id)
|| !dc_apeerstate_load_by_addr__(peerstate, mailbox->m_sql, contact->m_addr) || !dc_apeerstate_load_by_addr__(peerstate, mailbox->m_sql, contact->m_addr)
|| mrcontact_is_verified__(contact, peerstate) < MRV_BIDIRECTIONAL ) { || dc_contact_is_verified__(contact, peerstate) < MRV_BIDIRECTIONAL ) {
dc_log_warning(mailbox, 0, "Cannot verifiy group; sender is not verified."); dc_log_warning(mailbox, 0, "Cannot verifiy group; sender is not verified.");
goto cleanup; goto cleanup;
} }
@ -616,19 +616,19 @@ static int check_verified_properties__(mrmailbox_t* mailbox, mrmimeparser_t* mim
// check that all members are verified. // check that all members are verified.
// if a verification is missing, check if this was just gossiped - as we've verified the sender, we verify the member then. // if a verification is missing, check if this was just gossiped - as we've verified the sender, we verify the member then.
to_ids_str = mrarray_get_string(to_ids, ","); to_ids_str = dc_array_get_string(to_ids, ",");
q3 = sqlite3_mprintf("SELECT c.addr, LENGTH(ps.verified_key_fingerprint) " q3 = sqlite3_mprintf("SELECT c.addr, LENGTH(ps.verified_key_fingerprint) "
" FROM contacts c " " FROM contacts c "
" LEFT JOIN acpeerstates ps ON c.addr=ps.addr " " LEFT JOIN acpeerstates ps ON c.addr=ps.addr "
" WHERE c.id IN(%s) ", " WHERE c.id IN(%s) ",
to_ids_str); to_ids_str);
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, q3); stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql, q3);
while( sqlite3_step(stmt)==SQLITE_ROW ) while( sqlite3_step(stmt)==SQLITE_ROW )
{ {
const char* to_addr = (const char*)sqlite3_column_text(stmt, 0); const char* to_addr = (const char*)sqlite3_column_text(stmt, 0);
int is_verified = sqlite3_column_int (stmt, 1); int is_verified = sqlite3_column_int (stmt, 1);
if( mrhash_find_str(mimeparser->m_e2ee_helper->m_gossipped_addr, to_addr) if( dc_hash_find_str(mimeparser->m_e2ee_helper->m_gossipped_addr, to_addr)
&& dc_apeerstate_load_by_addr__(peerstate, mailbox->m_sql, to_addr) ) && dc_apeerstate_load_by_addr__(peerstate, mailbox->m_sql, to_addr) )
{ {
// if we're here, we know the gossip key is verified: // if we're here, we know the gossip key is verified:
@ -660,7 +660,7 @@ static int check_verified_properties__(mrmailbox_t* mailbox, mrmimeparser_t* mim
cleanup: cleanup:
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
mrcontact_unref(contact); dc_contact_unref(contact);
dc_apeerstate_unref(peerstate); dc_apeerstate_unref(peerstate);
free(to_ids_str); free(to_ids_str);
sqlite3_free(q3); sqlite3_free(q3);
@ -680,8 +680,8 @@ which tries to create or find out the chat_id by:
So when the function returns, the caller has the group id matching the current So when the function returns, the caller has the group id matching the current
state of the group. */ state of the group. */
static void create_or_lookup_group__(mrmailbox_t* mailbox, mrmimeparser_t* mime_parser, int create_blocked, static void create_or_lookup_group__(mrmailbox_t* mailbox, dc_mimeparser_t* mime_parser, int create_blocked,
int32_t from_id, const mrarray_t* to_ids, int32_t from_id, const dc_array_t* to_ids,
uint32_t* ret_chat_id, int* ret_chat_id_blocked) uint32_t* ret_chat_id, int* ret_chat_id_blocked)
{ {
uint32_t chat_id = 0; uint32_t chat_id = 0;
@ -690,7 +690,7 @@ static void create_or_lookup_group__(mrmailbox_t* mailbox, mrmimeparser_t* mime_
char* grpid = NULL; char* grpid = NULL;
char* grpname = NULL; char* grpname = NULL;
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
int i, to_ids_cnt = mrarray_get_cnt(to_ids); int i, to_ids_cnt = dc_array_get_cnt(to_ids);
char* self_addr = NULL; char* self_addr = NULL;
int recreate_member_list = 0; int recreate_member_list = 0;
int send_EVENT_CHAT_MODIFIED = 0; int send_EVENT_CHAT_MODIFIED = 0;
@ -705,13 +705,13 @@ static void create_or_lookup_group__(mrmailbox_t* mailbox, mrmimeparser_t* mime_
struct mailimf_field* field = NULL; struct mailimf_field* field = NULL;
struct mailimf_optional_field* optional_field = NULL; struct mailimf_optional_field* optional_field = NULL;
if( (optional_field=mrmimeparser_lookup_optional_field2(mime_parser, "Chat-Group-ID", "X-MrGrpId"))!=NULL ) { if( (optional_field=dc_mimeparser_lookup_optional_field2(mime_parser, "Chat-Group-ID", "X-MrGrpId"))!=NULL ) {
grpid = safe_strdup(optional_field->fld_value); grpid = safe_strdup(optional_field->fld_value);
} }
if( grpid == NULL ) if( grpid == NULL )
{ {
if( (field=mrmimeparser_lookup_field(mime_parser, "Message-ID"))!=NULL && field->fld_type==MAILIMF_FIELD_MESSAGE_ID ) { if( (field=dc_mimeparser_lookup_field(mime_parser, "Message-ID"))!=NULL && field->fld_type==MAILIMF_FIELD_MESSAGE_ID ) {
struct mailimf_message_id* fld_message_id = field->fld_data.fld_message_id; struct mailimf_message_id* fld_message_id = field->fld_data.fld_message_id;
if( fld_message_id ) { if( fld_message_id ) {
grpid = mr_extract_grpid_from_rfc724_mid(fld_message_id->mid_value); grpid = mr_extract_grpid_from_rfc724_mid(fld_message_id->mid_value);
@ -720,7 +720,7 @@ static void create_or_lookup_group__(mrmailbox_t* mailbox, mrmimeparser_t* mime_
if( grpid == NULL ) if( grpid == NULL )
{ {
if( (field=mrmimeparser_lookup_field(mime_parser, "In-Reply-To"))!=NULL && field->fld_type==MAILIMF_FIELD_IN_REPLY_TO ) { if( (field=dc_mimeparser_lookup_field(mime_parser, "In-Reply-To"))!=NULL && field->fld_type==MAILIMF_FIELD_IN_REPLY_TO ) {
struct mailimf_in_reply_to* fld_in_reply_to = field->fld_data.fld_in_reply_to; struct mailimf_in_reply_to* fld_in_reply_to = field->fld_data.fld_in_reply_to;
if( fld_in_reply_to ) { if( fld_in_reply_to ) {
grpid = mr_extract_grpid_from_rfc724_mid_list(fld_in_reply_to->mid_list); grpid = mr_extract_grpid_from_rfc724_mid_list(fld_in_reply_to->mid_list);
@ -729,7 +729,7 @@ static void create_or_lookup_group__(mrmailbox_t* mailbox, mrmimeparser_t* mime_
if( grpid == NULL ) if( grpid == NULL )
{ {
if( (field=mrmimeparser_lookup_field(mime_parser, "References"))!=NULL && field->fld_type==MAILIMF_FIELD_REFERENCES ) { if( (field=dc_mimeparser_lookup_field(mime_parser, "References"))!=NULL && field->fld_type==MAILIMF_FIELD_REFERENCES ) {
struct mailimf_references* fld_references = field->fld_data.fld_references; struct mailimf_references* fld_references = field->fld_data.fld_references;
if( fld_references ) { if( fld_references ) {
grpid = mr_extract_grpid_from_rfc724_mid_list(fld_references->mid_list); grpid = mr_extract_grpid_from_rfc724_mid_list(fld_references->mid_list);
@ -745,23 +745,23 @@ static void create_or_lookup_group__(mrmailbox_t* mailbox, mrmimeparser_t* mime_
} }
} }
if( (optional_field=mrmimeparser_lookup_optional_field2(mime_parser, "Chat-Group-Name", "X-MrGrpName"))!=NULL ) { if( (optional_field=dc_mimeparser_lookup_optional_field2(mime_parser, "Chat-Group-Name", "X-MrGrpName"))!=NULL ) {
grpname = mr_decode_header_words(optional_field->fld_value); /* this is no changed groupname message */ grpname = mr_decode_header_words(optional_field->fld_value); /* this is no changed groupname message */
} }
if( (optional_field=mrmimeparser_lookup_optional_field2(mime_parser, "Chat-Group-Member-Removed", "X-MrRemoveFromGrp"))!=NULL ) { if( (optional_field=dc_mimeparser_lookup_optional_field2(mime_parser, "Chat-Group-Member-Removed", "X-MrRemoveFromGrp"))!=NULL ) {
X_MrRemoveFromGrp = optional_field->fld_value; X_MrRemoveFromGrp = optional_field->fld_value;
mime_parser->m_is_system_message = MR_CMD_MEMBER_REMOVED_FROM_GROUP; mime_parser->m_is_system_message = MR_CMD_MEMBER_REMOVED_FROM_GROUP;
} }
else if( (optional_field=mrmimeparser_lookup_optional_field2(mime_parser, "Chat-Group-Member-Added", "X-MrAddToGrp"))!=NULL ) { else if( (optional_field=dc_mimeparser_lookup_optional_field2(mime_parser, "Chat-Group-Member-Added", "X-MrAddToGrp"))!=NULL ) {
X_MrAddToGrp = optional_field->fld_value; X_MrAddToGrp = optional_field->fld_value;
mime_parser->m_is_system_message = MR_CMD_MEMBER_ADDED_TO_GROUP; mime_parser->m_is_system_message = MR_CMD_MEMBER_ADDED_TO_GROUP;
} }
else if( (optional_field=mrmimeparser_lookup_optional_field2(mime_parser, "Chat-Group-Name-Changed", "X-MrGrpNameChanged"))!=NULL ) { else if( (optional_field=dc_mimeparser_lookup_optional_field2(mime_parser, "Chat-Group-Name-Changed", "X-MrGrpNameChanged"))!=NULL ) {
X_MrGrpNameChanged = 1; X_MrGrpNameChanged = 1;
mime_parser->m_is_system_message = MR_CMD_GROUPNAME_CHANGED; mime_parser->m_is_system_message = MR_CMD_GROUPNAME_CHANGED;
} }
else if( (optional_field=mrmimeparser_lookup_optional_field(mime_parser, "Chat-Group-Image"))!=NULL ) { else if( (optional_field=dc_mimeparser_lookup_optional_field(mime_parser, "Chat-Group-Image"))!=NULL ) {
X_MrGrpImageChanged = 1; X_MrGrpImageChanged = 1;
mime_parser->m_is_system_message = MR_CMD_GROUPIMAGE_CHANGED; mime_parser->m_is_system_message = MR_CMD_GROUPIMAGE_CHANGED;
} }
@ -792,9 +792,9 @@ static void create_or_lookup_group__(mrmailbox_t* mailbox, mrmimeparser_t* mime_
/* check if the group does not exist but should be created */ /* check if the group does not exist but should be created */
int group_explicitly_left = mrmailbox_is_group_explicitly_left__(mailbox, grpid); int group_explicitly_left = mrmailbox_is_group_explicitly_left__(mailbox, grpid);
self_addr = mrsqlite3_get_config__(mailbox->m_sql, "configured_addr", ""); self_addr = dc_sqlite3_get_config__(mailbox->m_sql, "configured_addr", "");
if( chat_id == 0 if( chat_id == 0
&& !mrmimeparser_is_mailinglist_message(mime_parser) && !dc_mimeparser_is_mailinglist_message(mime_parser)
&& grpid && grpid
&& grpname && grpname
&& X_MrRemoveFromGrp==NULL /*otherwise, a pending "quit" message may pop up*/ && X_MrRemoveFromGrp==NULL /*otherwise, a pending "quit" message may pop up*/
@ -802,7 +802,7 @@ static void create_or_lookup_group__(mrmailbox_t* mailbox, mrmimeparser_t* mime_
) )
{ {
int create_verified = 0; int create_verified = 0;
if( mrmimeparser_lookup_field(mime_parser, "Chat-Verified") ) { if( dc_mimeparser_lookup_field(mime_parser, "Chat-Verified") ) {
if( check_verified_properties__(mailbox, mime_parser, from_id, to_ids) ) { if( check_verified_properties__(mailbox, mime_parser, from_id, to_ids) ) {
create_verified = 1; create_verified = 1;
} }
@ -833,7 +833,7 @@ static void create_or_lookup_group__(mrmailbox_t* mailbox, mrmimeparser_t* mime_
} }
else if( X_MrGrpNameChanged && grpname && strlen(grpname) < 200 ) else if( X_MrGrpNameChanged && grpname && strlen(grpname) < 200 )
{ {
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, "UPDATE chats SET name=? WHERE id=?;"); stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql, "UPDATE chats SET name=? WHERE id=?;");
sqlite3_bind_text(stmt, 1, grpname, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 1, grpname, -1, SQLITE_STATIC);
sqlite3_bind_int (stmt, 2, chat_id); sqlite3_bind_int (stmt, 2, chat_id);
sqlite3_step(stmt); sqlite3_step(stmt);
@ -862,12 +862,12 @@ static void create_or_lookup_group__(mrmailbox_t* mailbox, mrmimeparser_t* mime_
} }
if( ok ) { if( ok ) {
mrchat_t* chat = mrchat_new(mailbox); dc_chat_t* chat = dc_chat_new(mailbox);
dc_log_info(mailbox, 0, "New group image set to %s.", grpimage? "DELETED" : grpimage); dc_log_info(mailbox, 0, "New group image set to %s.", grpimage? "DELETED" : grpimage);
mrchat_load_from_db__(chat, chat_id); dc_chat_load_from_db__(chat, chat_id);
mrparam_set(chat->m_param, MRP_PROFILE_IMAGE, grpimage/*may be NULL*/); mrparam_set(chat->m_param, MRP_PROFILE_IMAGE, grpimage/*may be NULL*/);
mrchat_update_param__(chat); dc_chat_update_param__(chat);
mrchat_unref(chat); dc_chat_unref(chat);
free(grpimage); free(grpimage);
send_EVENT_CHAT_MODIFIED = 1; send_EVENT_CHAT_MODIFIED = 1;
} }
@ -879,7 +879,7 @@ static void create_or_lookup_group__(mrmailbox_t* mailbox, mrmimeparser_t* mime_
{ {
const char* skip = X_MrRemoveFromGrp? X_MrRemoveFromGrp : NULL; const char* skip = X_MrRemoveFromGrp? X_MrRemoveFromGrp : NULL;
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, "DELETE FROM chats_contacts WHERE chat_id=?;"); stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql, "DELETE FROM chats_contacts WHERE chat_id=?;");
sqlite3_bind_int (stmt, 1, chat_id); sqlite3_bind_int (stmt, 1, chat_id);
sqlite3_step(stmt); sqlite3_step(stmt);
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
@ -897,7 +897,7 @@ static void create_or_lookup_group__(mrmailbox_t* mailbox, mrmimeparser_t* mime_
for( i = 0; i < to_ids_cnt; i++ ) for( i = 0; i < to_ids_cnt; i++ )
{ {
uint32_t to_id = mrarray_get_id(to_ids, i); /* to_id is only once in to_ids and is non-special */ uint32_t to_id = dc_array_get_id(to_ids, i); /* to_id is only once in to_ids and is non-special */
if( mrmailbox_contact_addr_equals__(mailbox, to_id, self_addr)==0 if( mrmailbox_contact_addr_equals__(mailbox, to_id, self_addr)==0
&& (skip==NULL || mrmailbox_contact_addr_equals__(mailbox, to_id, skip)==0) ) { && (skip==NULL || mrmailbox_contact_addr_equals__(mailbox, to_id, skip)==0) ) {
mrmailbox_add_to_chat_contacts_table__(mailbox, chat_id, to_id); mrmailbox_add_to_chat_contacts_table__(mailbox, chat_id, to_id);
@ -943,7 +943,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
int incoming_origin = 0; int incoming_origin = 0;
#define outgoing (!incoming) #define outgoing (!incoming)
mrarray_t* to_ids = NULL; dc_array_t* to_ids = NULL;
int to_self = 0; int to_self = 0;
uint32_t from_id = 0; uint32_t from_id = 0;
@ -961,7 +961,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
time_t sort_timestamp = MR_INVALID_TIMESTAMP; time_t sort_timestamp = MR_INVALID_TIMESTAMP;
time_t sent_timestamp = MR_INVALID_TIMESTAMP; time_t sent_timestamp = MR_INVALID_TIMESTAMP;
time_t rcvd_timestamp = MR_INVALID_TIMESTAMP; time_t rcvd_timestamp = MR_INVALID_TIMESTAMP;
mrmimeparser_t* mime_parser = mrmimeparser_new(mailbox->m_blobdir, mailbox); dc_mimeparser_t* mime_parser = dc_mimeparser_new(mailbox->m_blobdir, mailbox);
int db_locked = 0; int db_locked = 0;
int transaction_pending = 0; int transaction_pending = 0;
const struct mailimf_field* field; const struct mailimf_field* field;
@ -975,7 +975,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
dc_log_info(mailbox, 0, "Receiving message %s/%lu...", server_folder? server_folder:"?", server_uid); dc_log_info(mailbox, 0, "Receiving message %s/%lu...", server_folder? server_folder:"?", server_uid);
to_ids = mrarray_new(mailbox, 16); to_ids = dc_array_new(mailbox, 16);
if( to_ids==NULL || created_db_entries==NULL || rr_event_to_send==NULL || mime_parser == NULL ) { if( to_ids==NULL || created_db_entries==NULL || rr_event_to_send==NULL || mime_parser == NULL ) {
dc_log_info(mailbox, 0, "Bad param."); dc_log_info(mailbox, 0, "Bad param.");
goto cleanup; goto cleanup;
@ -993,8 +993,8 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
normally, this is done by mailimf_message_parse(), however, as we also need the MIME data, normally, this is done by mailimf_message_parse(), however, as we also need the MIME data,
we use mailmime_parse() through MrMimeParser (both call mailimf_struct_multiple_parse() somewhen, I did not found out anything we use mailmime_parse() through MrMimeParser (both call mailimf_struct_multiple_parse() somewhen, I did not found out anything
that speaks against this approach yet) */ that speaks against this approach yet) */
mrmimeparser_parse(mime_parser, imf_raw_not_terminated, imf_raw_bytes); dc_mimeparser_parse(mime_parser, imf_raw_not_terminated, imf_raw_bytes);
if( mrhash_count(&mime_parser->m_header)==0 ) { if( dc_hash_count(&mime_parser->m_header)==0 ) {
dc_log_info(mailbox, 0, "No header."); dc_log_info(mailbox, 0, "No header.");
goto cleanup; /* Error - even adding an empty record won't help as we do not know the message ID */ goto cleanup; /* Error - even adding an empty record won't help as we do not know the message ID */
} }
@ -1004,57 +1004,57 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
as it may even be confusing when _own_ messages sent from other devices with other e-mail-adresses appear as being sent from SELF as it may even be confusing when _own_ messages sent from other devices with other e-mail-adresses appear as being sent from SELF
we disabled this check for now */ we disabled this check for now */
#if 0 #if 0
if( !mrmimeparser_lookup_field(mime_parser, "Return-Path") ) { if( !dc_mimeparser_lookup_field(mime_parser, "Return-Path") ) {
incoming = 0; incoming = 0;
} }
#endif #endif
if( (field=mrmimeparser_lookup_field(mime_parser, "Date"))!=NULL && field->fld_type==MAILIMF_FIELD_ORIG_DATE ) { if( (field=dc_mimeparser_lookup_field(mime_parser, "Date"))!=NULL && field->fld_type==MAILIMF_FIELD_ORIG_DATE ) {
struct mailimf_orig_date* orig_date = field->fld_data.fld_orig_date; struct mailimf_orig_date* orig_date = field->fld_data.fld_orig_date;
if( orig_date ) { if( orig_date ) {
sent_timestamp = mr_timestamp_from_date(orig_date->dt_date_time); // is not yet checked against bad times! we do this later if we have the database information. sent_timestamp = mr_timestamp_from_date(orig_date->dt_date_time); // is not yet checked against bad times! we do this later if we have the database information.
} }
} }
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
db_locked = 1; db_locked = 1;
mrsqlite3_begin_transaction__(mailbox->m_sql); dc_sqlite3_begin_transaction__(mailbox->m_sql);
transaction_pending = 1; transaction_pending = 1;
/* get From: and check if it is known (for known From:'s we add the other To:/Cc: in the 3rd pass) /* get From: and check if it is known (for known From:'s we add the other To:/Cc: in the 3rd pass)
or if From: is equal to SELF (in this case, it is any outgoing messages, we do not check Return-Path any more as this is unreliable, see issue #150 */ or if From: is equal to SELF (in this case, it is any outgoing messages, we do not check Return-Path any more as this is unreliable, see issue #150 */
if( (field=mrmimeparser_lookup_field(mime_parser, "From"))!=NULL if( (field=dc_mimeparser_lookup_field(mime_parser, "From"))!=NULL
&& field->fld_type==MAILIMF_FIELD_FROM) && field->fld_type==MAILIMF_FIELD_FROM)
{ {
struct mailimf_from* fld_from = field->fld_data.fld_from; struct mailimf_from* fld_from = field->fld_data.fld_from;
if( fld_from ) if( fld_from )
{ {
int check_self; int check_self;
mrarray_t* from_list = mrarray_new(mailbox, 16); dc_array_t* from_list = dc_array_new(mailbox, 16);
mrmailbox_add_or_lookup_contacts_by_mailbox_list__(mailbox, fld_from->frm_mb_list, MR_ORIGIN_INCOMING_UNKNOWN_FROM, from_list, &check_self); mrmailbox_add_or_lookup_contacts_by_mailbox_list__(mailbox, fld_from->frm_mb_list, MR_ORIGIN_INCOMING_UNKNOWN_FROM, from_list, &check_self);
if( check_self ) if( check_self )
{ {
incoming = 0; incoming = 0;
if( mrmimeparser_sender_equals_recipient(mime_parser) ) if( dc_mimeparser_sender_equals_recipient(mime_parser) )
{ {
from_id = MR_CONTACT_ID_SELF; from_id = MR_CONTACT_ID_SELF;
} }
} }
else else
{ {
if( mrarray_get_cnt(from_list)>=1 ) /* if there is no from given, from_id stays 0 which is just fine. These messages are very rare, however, we have to add them to the database (they go to the "deaddrop" chat) to avoid a re-download from the server. See also [**] */ if( dc_array_get_cnt(from_list)>=1 ) /* if there is no from given, from_id stays 0 which is just fine. These messages are very rare, however, we have to add them to the database (they go to the "deaddrop" chat) to avoid a re-download from the server. See also [**] */
{ {
from_id = mrarray_get_id(from_list, 0); from_id = dc_array_get_id(from_list, 0);
incoming_origin = mrmailbox_get_contact_origin__(mailbox, from_id, &from_id_blocked); incoming_origin = mrmailbox_get_contact_origin__(mailbox, from_id, &from_id_blocked);
} }
} }
mrarray_unref(from_list); dc_array_unref(from_list);
} }
} }
/* Make sure, to_ids starts with the first To:-address (Cc: is added in the loop below pass) */ /* Make sure, to_ids starts with the first To:-address (Cc: is added in the loop below pass) */
if( (field=mrmimeparser_lookup_field(mime_parser, "To"))!=NULL if( (field=dc_mimeparser_lookup_field(mime_parser, "To"))!=NULL
&& field->fld_type==MAILIMF_FIELD_TO ) && field->fld_type==MAILIMF_FIELD_TO )
{ {
struct mailimf_to* fld_to = field->fld_data.fld_to; /* can be NULL */ struct mailimf_to* fld_to = field->fld_data.fld_to; /* can be NULL */
@ -1065,7 +1065,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
} }
} }
if( mrmimeparser_has_nonmeta(mime_parser) ) if( dc_mimeparser_has_nonmeta(mime_parser) )
{ {
/********************************************************************** /**********************************************************************
@ -1075,7 +1075,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
/* collect the rest information, CC: is added to the to-list, BCC: is ignored /* collect the rest information, CC: is added to the to-list, BCC: is ignored
(we should not add BCC to groups as this would split groups. We could add them as "known contacts", (we should not add BCC to groups as this would split groups. We could add them as "known contacts",
however, the benefit is very small and this may leak data that is expected to be hidden) */ however, the benefit is very small and this may leak data that is expected to be hidden) */
if( (field=mrmimeparser_lookup_field(mime_parser, "Cc"))!=NULL && field->fld_type==MAILIMF_FIELD_CC ) if( (field=dc_mimeparser_lookup_field(mime_parser, "Cc"))!=NULL && field->fld_type==MAILIMF_FIELD_CC )
{ {
struct mailimf_cc* fld_cc = field->fld_data.fld_cc; struct mailimf_cc* fld_cc = field->fld_data.fld_cc;
if( fld_cc ) { if( fld_cc ) {
@ -1087,7 +1087,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
/* get Message-ID; if the header is lacking one, generate one based on fields that do never change. /* get Message-ID; if the header is lacking one, generate one based on fields that do never change.
(missing Message-IDs may come if the mail was set from this account with another client that relies in the SMTP server to generate one. (missing Message-IDs may come if the mail was set from this account with another client that relies in the SMTP server to generate one.
true eg. for the Webmailer used in all-inkl-KAS) */ true eg. for the Webmailer used in all-inkl-KAS) */
if( (field=mrmimeparser_lookup_field(mime_parser, "Message-ID"))!=NULL && field->fld_type==MAILIMF_FIELD_MESSAGE_ID ) { if( (field=dc_mimeparser_lookup_field(mime_parser, "Message-ID"))!=NULL && field->fld_type==MAILIMF_FIELD_MESSAGE_ID ) {
struct mailimf_message_id* fld_message_id = field->fld_data.fld_message_id; struct mailimf_message_id* fld_message_id = field->fld_data.fld_message_id;
if( fld_message_id ) { if( fld_message_id ) {
rfc724_mid = safe_strdup(fld_message_id->mid_value); rfc724_mid = safe_strdup(fld_message_id->mid_value);
@ -1109,7 +1109,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
uint32_t old_server_uid = 0; uint32_t old_server_uid = 0;
if( mrmailbox_rfc724_mid_exists__(mailbox, rfc724_mid, &old_server_folder, &old_server_uid) ) { if( mrmailbox_rfc724_mid_exists__(mailbox, rfc724_mid, &old_server_folder, &old_server_uid) ) {
if( strcmp(old_server_folder, server_folder)!=0 || old_server_uid!=server_uid ) { if( strcmp(old_server_folder, server_folder)!=0 || old_server_uid!=server_uid ) {
mrsqlite3_rollback__(mailbox->m_sql); dc_sqlite3_rollback__(mailbox->m_sql);
transaction_pending = 0; transaction_pending = 0;
mrmailbox_update_server_uid__(mailbox, rfc724_mid, server_folder, server_uid); mrmailbox_update_server_uid__(mailbox, rfc724_mid, server_folder, server_uid);
} }
@ -1130,15 +1130,15 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
// handshake messages must be processed before chats are crated (eg. contacs may be marked as verified) // handshake messages must be processed before chats are crated (eg. contacs may be marked as verified)
assert( chat_id == 0 ); assert( chat_id == 0 );
if( mrmimeparser_lookup_field(mime_parser, "Secure-Join") ) { if( dc_mimeparser_lookup_field(mime_parser, "Secure-Join") ) {
mrsqlite3_commit__(mailbox->m_sql); dc_sqlite3_commit__(mailbox->m_sql);
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
if( mrmailbox_handle_securejoin_handshake(mailbox, mime_parser, from_id) == MR_IS_HANDSHAKE_STOP_NORMAL_PROCESSING ) { if( mrmailbox_handle_securejoin_handshake(mailbox, mime_parser, from_id) == MR_IS_HANDSHAKE_STOP_NORMAL_PROCESSING ) {
hidden = 1; hidden = 1;
state = MR_STATE_IN_SEEN; state = MR_STATE_IN_SEEN;
} }
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
mrsqlite3_begin_transaction__(mailbox->m_sql); dc_sqlite3_begin_transaction__(mailbox->m_sql);
} }
/* test if there is a normal chat with the sender - if so, this allows us to create groups in the next step */ /* test if there is a normal chat with the sender - if so, this allows us to create groups in the next step */
@ -1163,7 +1163,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
if( chat_id == 0 ) if( chat_id == 0 )
{ {
/* check if the message belongs to a mailing list */ /* check if the message belongs to a mailing list */
if( mrmimeparser_is_mailinglist_message(mime_parser) ) { if( dc_mimeparser_is_mailinglist_message(mime_parser) ) {
chat_id = MR_CHAT_ID_TRASH; chat_id = MR_CHAT_ID_TRASH;
dc_log_info(mailbox, 0, "Message belongs to a mailing list and is ignored."); dc_log_info(mailbox, 0, "Message belongs to a mailing list and is ignored.");
} }
@ -1213,8 +1213,8 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
{ {
state = MR_STATE_OUT_DELIVERED; /* the mail is on the IMAP server, probably it is also delivered. We cannot recreate other states (read, error). */ state = MR_STATE_OUT_DELIVERED; /* the mail is on the IMAP server, probably it is also delivered. We cannot recreate other states (read, error). */
from_id = MR_CONTACT_ID_SELF; from_id = MR_CONTACT_ID_SELF;
if( mrarray_get_cnt(to_ids) >= 1 ) { if( dc_array_get_cnt(to_ids) >= 1 ) {
to_id = mrarray_get_id(to_ids, 0); to_id = dc_array_get_id(to_ids, 0);
if( chat_id == 0 ) if( chat_id == 0 )
{ {
@ -1237,7 +1237,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
} }
if( chat_id == 0 ) { if( chat_id == 0 ) {
if( mrarray_get_cnt(to_ids) == 0 && to_self ) { if( dc_array_get_cnt(to_ids) == 0 && to_self ) {
/* from_id == to_id == MR_CONTACT_ID_SELF - this is a self-sent messages, maybe an Autocrypt Setup Message */ /* from_id == to_id == MR_CONTACT_ID_SELF - this is a self-sent messages, maybe an Autocrypt Setup Message */
mrmailbox_create_or_lookup_nchat_by_contact_id__(mailbox, MR_CONTACT_ID_SELF, MR_CHAT_NOT_BLOCKED, &chat_id, &chat_id_blocked); mrmailbox_create_or_lookup_nchat_by_contact_id__(mailbox, MR_CONTACT_ID_SELF, MR_CHAT_NOT_BLOCKED, &chat_id, &chat_id_blocked);
if( chat_id && chat_id_blocked ) { if( chat_id && chat_id_blocked ) {
@ -1295,7 +1295,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
mrparam_set_int(part->m_param, MRP_CMD, mime_parser->m_is_system_message); mrparam_set_int(part->m_param, MRP_CMD, mime_parser->m_is_system_message);
} }
stmt = mrsqlite3_predefine__(mailbox->m_sql, INSERT_INTO_msgs_msscftttsmttpb, stmt = dc_sqlite3_predefine__(mailbox->m_sql, INSERT_INTO_msgs_msscftttsmttpb,
"INSERT INTO msgs (rfc724_mid,server_folder,server_uid,chat_id,from_id, to_id,timestamp,timestamp_sent,timestamp_rcvd,type, state,msgrmsg,txt,txt_raw,param, bytes,hidden)" "INSERT INTO msgs (rfc724_mid,server_folder,server_uid,chat_id,from_id, to_id,timestamp,timestamp_sent,timestamp_rcvd,type, state,msgrmsg,txt,txt_raw,param, bytes,hidden)"
" VALUES (?,?,?,?,?, ?,?,?,?,?, ?,?,?,?,?, ?,?);"); " VALUES (?,?,?,?,?, ?,?,?,?,?, ?,?,?,?,?, ?,?);");
sqlite3_bind_text (stmt, 1, rfc724_mid, -1, SQLITE_STATIC); sqlite3_bind_text (stmt, 1, rfc724_mid, -1, SQLITE_STATIC);
@ -1345,7 +1345,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
} }
else if( chat_id_blocked ) { else if( chat_id_blocked ) {
create_event_to_send = DC_EVENT_MSGS_CHANGED; create_event_to_send = DC_EVENT_MSGS_CHANGED;
/*if( mrsqlite3_get_config_int__(mailbox->m_sql, "show_deaddrop", 0)!=0 ) { /*if( dc_sqlite3_get_config_int__(mailbox->m_sql, "show_deaddrop", 0)!=0 ) {
create_event_to_send = DC_EVENT_INCOMING_MSG; create_event_to_send = DC_EVENT_INCOMING_MSG;
}*/ }*/
} }
@ -1369,7 +1369,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
* Handle reports (mainly MDNs) * Handle reports (mainly MDNs)
*****************************************************************/ *****************************************************************/
int mdns_enabled = mrsqlite3_get_config_int__(mailbox->m_sql, "mdns_enabled", MR_MDNS_DEFAULT_ENABLED); int mdns_enabled = dc_sqlite3_get_config_int__(mailbox->m_sql, "mdns_enabled", MR_MDNS_DEFAULT_ENABLED);
icnt = carray_count(mime_parser->m_reports); icnt = carray_count(mime_parser->m_reports);
for( i = 0; i < icnt; i++ ) for( i = 0; i < icnt; i++ )
{ {
@ -1454,7 +1454,7 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
} }
/* debug print? */ /* debug print? */
if( mrsqlite3_get_config_int__(mailbox->m_sql, "save_eml", 0) ) { if( dc_sqlite3_get_config_int__(mailbox->m_sql, "save_eml", 0) ) {
char* emlname = mr_mprintf("%s/%s-%i.eml", mailbox->m_blobdir, server_folder, (int)first_dblocal_id /*may be 0 for MDNs*/); char* emlname = mr_mprintf("%s/%s-%i.eml", mailbox->m_blobdir, server_folder, (int)first_dblocal_id /*may be 0 for MDNs*/);
FILE* emlfileob = fopen(emlname, "w"); FILE* emlfileob = fopen(emlname, "w");
if( emlfileob ) { if( emlfileob ) {
@ -1465,16 +1465,16 @@ void mrmailbox_receive_imf(mrmailbox_t* mailbox, const char* imf_raw_not_termina
} }
mrsqlite3_commit__(mailbox->m_sql); dc_sqlite3_commit__(mailbox->m_sql);
transaction_pending = 0; transaction_pending = 0;
cleanup: cleanup:
if( transaction_pending ) { mrsqlite3_rollback__(mailbox->m_sql); } if( transaction_pending ) { dc_sqlite3_rollback__(mailbox->m_sql); }
if( db_locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( db_locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
mrmimeparser_unref(mime_parser); dc_mimeparser_unref(mime_parser);
free(rfc724_mid); free(rfc724_mid);
mrarray_unref(to_ids); dc_array_unref(to_ids);
if( created_db_entries ) { if( created_db_entries ) {
if( create_event_to_send ) { if( create_event_to_send ) {

View file

@ -31,8 +31,8 @@
#include "dc_token.h" #include "dc_token.h"
#define LOCK { mrsqlite3_lock (mailbox->m_sql); locked = 1; } #define LOCK { dc_sqlite3_lock (mailbox->m_sql); locked = 1; }
#define UNLOCK if( locked ) { mrsqlite3_unlock(mailbox->m_sql); locked = 0; } #define UNLOCK if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); locked = 0; }
/******************************************************************************* /*******************************************************************************
@ -61,7 +61,7 @@ void mrmailbox_handle_degrade_event(mrmailbox_t* mailbox, dc_apeerstate_t* peers
{ {
LOCK LOCK
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, "SELECT id FROM contacts WHERE addr=?;"); stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql, "SELECT id FROM contacts WHERE addr=?;");
sqlite3_bind_text(stmt, 1, peerstate->m_addr, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 1, peerstate->m_addr, -1, SQLITE_STATIC);
sqlite3_step(stmt); sqlite3_step(stmt);
contact_id = sqlite3_column_int(stmt, 0); contact_id = sqlite3_column_int(stmt, 0);
@ -91,14 +91,14 @@ cleanup:
******************************************************************************/ ******************************************************************************/
static int encrypted_and_signed(mrmimeparser_t* mimeparser, const char* expected_fingerprint) static int encrypted_and_signed(dc_mimeparser_t* mimeparser, const char* expected_fingerprint)
{ {
if( !mimeparser->m_e2ee_helper->m_encrypted ) { if( !mimeparser->m_e2ee_helper->m_encrypted ) {
dc_log_warning(mimeparser->m_mailbox, 0, "Message not encrypted."); dc_log_warning(mimeparser->m_mailbox, 0, "Message not encrypted.");
return 0; return 0;
} }
if( mrhash_count(mimeparser->m_e2ee_helper->m_signatures)<=0 ) { if( dc_hash_count(mimeparser->m_e2ee_helper->m_signatures)<=0 ) {
dc_log_warning(mimeparser->m_mailbox, 0, "Message not signed."); dc_log_warning(mimeparser->m_mailbox, 0, "Message not signed.");
return 0; return 0;
} }
@ -108,7 +108,7 @@ static int encrypted_and_signed(mrmimeparser_t* mimeparser, const char* expected
return 0; return 0;
} }
if( mrhash_find_str(mimeparser->m_e2ee_helper->m_signatures, expected_fingerprint) == NULL ) { if( dc_hash_find_str(mimeparser->m_e2ee_helper->m_signatures, expected_fingerprint) == NULL ) {
dc_log_warning(mimeparser->m_mailbox, 0, "Message does not match expected fingerprint %s.", expected_fingerprint); dc_log_warning(mimeparser->m_mailbox, 0, "Message does not match expected fingerprint %s.", expected_fingerprint);
return 0; return 0;
} }
@ -121,28 +121,28 @@ static char* get_self_fingerprint(mrmailbox_t* mailbox)
{ {
int locked = 0; int locked = 0;
char* self_addr = NULL; char* self_addr = NULL;
mrkey_t* self_key = mrkey_new(); dc_key_t* self_key = dc_key_new();
char* fingerprint = NULL; char* fingerprint = NULL;
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
if( (self_addr = mrsqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL)) == NULL if( (self_addr = dc_sqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL)) == NULL
|| !mrkey_load_self_public__(self_key, self_addr, mailbox->m_sql) ) { || !dc_key_load_self_public__(self_key, self_addr, mailbox->m_sql) ) {
goto cleanup; goto cleanup;
} }
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
if( (fingerprint=mrkey_get_fingerprint(self_key)) == NULL ) { if( (fingerprint=dc_key_get_fingerprint(self_key)) == NULL ) {
goto cleanup; goto cleanup;
} }
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
free(self_addr); free(self_addr);
mrkey_unref(self_key); dc_key_unref(self_key);
return fingerprint; return fingerprint;
} }
@ -150,16 +150,16 @@ cleanup:
static uint32_t chat_id_2_contact_id(mrmailbox_t* mailbox, uint32_t contact_chat_id) static uint32_t chat_id_2_contact_id(mrmailbox_t* mailbox, uint32_t contact_chat_id)
{ {
uint32_t contact_id = 0; uint32_t contact_id = 0;
mrarray_t* contacts = mrmailbox_get_chat_contacts(mailbox, contact_chat_id); dc_array_t* contacts = mrmailbox_get_chat_contacts(mailbox, contact_chat_id);
if( mrarray_get_cnt(contacts) != 1 ) { if( dc_array_get_cnt(contacts) != 1 ) {
goto cleanup; goto cleanup;
} }
contact_id = mrarray_get_id(contacts, 0); contact_id = dc_array_get_id(contacts, 0);
cleanup: cleanup:
mrarray_unref(contacts); dc_array_unref(contacts);
return contact_id; return contact_id;
} }
@ -168,24 +168,24 @@ static int fingerprint_equals_sender(mrmailbox_t* mailbox, const char* fingerpri
{ {
int fingerprint_equal = 0; int fingerprint_equal = 0;
int locked = 0; int locked = 0;
mrarray_t* contacts = mrmailbox_get_chat_contacts(mailbox, contact_chat_id); dc_array_t* contacts = mrmailbox_get_chat_contacts(mailbox, contact_chat_id);
mrcontact_t* contact = mrcontact_new(mailbox); dc_contact_t* contact = dc_contact_new(mailbox);
dc_apeerstate_t* peerstate = dc_apeerstate_new(mailbox); dc_apeerstate_t* peerstate = dc_apeerstate_new(mailbox);
char* fingerprint_normalized = NULL; char* fingerprint_normalized = NULL;
if( mrarray_get_cnt(contacts) != 1 ) { if( dc_array_get_cnt(contacts) != 1 ) {
goto cleanup; goto cleanup;
} }
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
if( !mrcontact_load_from_db__(contact, mailbox->m_sql, mrarray_get_id(contacts, 0)) if( !dc_contact_load_from_db__(contact, mailbox->m_sql, dc_array_get_id(contacts, 0))
|| !dc_apeerstate_load_by_addr__(peerstate, mailbox->m_sql, contact->m_addr) ) { || !dc_apeerstate_load_by_addr__(peerstate, mailbox->m_sql, contact->m_addr) ) {
goto cleanup; goto cleanup;
} }
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
fingerprint_normalized = mr_normalize_fingerprint(fingerprint); fingerprint_normalized = mr_normalize_fingerprint(fingerprint);
@ -195,10 +195,10 @@ static int fingerprint_equals_sender(mrmailbox_t* mailbox, const char* fingerpri
} }
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
free(fingerprint_normalized); free(fingerprint_normalized);
mrcontact_unref(contact); dc_contact_unref(contact);
mrarray_unref(contacts); dc_array_unref(contacts);
return fingerprint_equal; return fingerprint_equal;
} }
@ -231,10 +231,10 @@ cleanup:
} }
static const char* lookup_field(mrmimeparser_t* mimeparser, const char* key) static const char* lookup_field(dc_mimeparser_t* mimeparser, const char* key)
{ {
const char* value = NULL; const char* value = NULL;
struct mailimf_field* field = mrmimeparser_lookup_field(mimeparser, key); struct mailimf_field* field = dc_mimeparser_lookup_field(mimeparser, key);
if( field == NULL || field->fld_type != MAILIMF_FIELD_OPTIONAL_FIELD if( field == NULL || field->fld_type != MAILIMF_FIELD_OPTIONAL_FIELD
|| field->fld_data.fld_optional_field == NULL || (value=field->fld_data.fld_optional_field->fld_value) == NULL ) { || field->fld_data.fld_optional_field == NULL || (value=field->fld_data.fld_optional_field->fld_value) == NULL ) {
return NULL; return NULL;
@ -245,7 +245,7 @@ static const char* lookup_field(mrmimeparser_t* mimeparser, const char* key)
static void send_handshake_msg(mrmailbox_t* mailbox, uint32_t contact_chat_id, const char* step, const char* param2, const char* fingerprint, const char* grpid) static void send_handshake_msg(mrmailbox_t* mailbox, uint32_t contact_chat_id, const char* step, const char* param2, const char* fingerprint, const char* grpid)
{ {
mrmsg_t* msg = mrmsg_new(); dc_msg_t* msg = dc_msg_new();
msg->m_type = MR_MSG_TEXT; msg->m_type = MR_MSG_TEXT;
msg->m_text = mr_mprintf("Secure-Join: %s", step); msg->m_text = mr_mprintf("Secure-Join: %s", step);
@ -274,14 +274,14 @@ static void send_handshake_msg(mrmailbox_t* mailbox, uint32_t contact_chat_id, c
mrmailbox_send_msg_object(mailbox, contact_chat_id, msg); mrmailbox_send_msg_object(mailbox, contact_chat_id, msg);
mrmsg_unref(msg); dc_msg_unref(msg);
} }
static void could_not_establish_secure_connection(mrmailbox_t* mailbox, uint32_t contact_chat_id, const char* details) static void could_not_establish_secure_connection(mrmailbox_t* mailbox, uint32_t contact_chat_id, const char* details)
{ {
uint32_t contact_id = chat_id_2_contact_id(mailbox, contact_chat_id); uint32_t contact_id = chat_id_2_contact_id(mailbox, contact_chat_id);
mrcontact_t* contact = mrmailbox_get_contact(mailbox, contact_id); dc_contact_t* contact = mrmailbox_get_contact(mailbox, contact_id);
char* msg = mr_mprintf("Could not establish secure connection to %s.", contact? contact->m_addr : "?"); char* msg = mr_mprintf("Could not establish secure connection to %s.", contact? contact->m_addr : "?");
mrmailbox_add_device_msg(mailbox, contact_chat_id, msg); mrmailbox_add_device_msg(mailbox, contact_chat_id, msg);
@ -289,14 +289,14 @@ static void could_not_establish_secure_connection(mrmailbox_t* mailbox, uint32_t
dc_log_error(mailbox, 0, "%s (%s)", msg, details); // additionaly raise an error; this typically results in a toast (inviter side) or a dialog (joiner side) dc_log_error(mailbox, 0, "%s (%s)", msg, details); // additionaly raise an error; this typically results in a toast (inviter side) or a dialog (joiner side)
free(msg); free(msg);
mrcontact_unref(contact); dc_contact_unref(contact);
} }
static void secure_connection_established(mrmailbox_t* mailbox, uint32_t contact_chat_id) static void secure_connection_established(mrmailbox_t* mailbox, uint32_t contact_chat_id)
{ {
uint32_t contact_id = chat_id_2_contact_id(mailbox, contact_chat_id); uint32_t contact_id = chat_id_2_contact_id(mailbox, contact_chat_id);
mrcontact_t* contact = mrmailbox_get_contact(mailbox, contact_id); dc_contact_t* contact = mrmailbox_get_contact(mailbox, contact_id);
char* msg = mr_mprintf("Secure connection to %s established.", contact? contact->m_addr : "?"); char* msg = mr_mprintf("Secure connection to %s established.", contact? contact->m_addr : "?");
mrmailbox_add_device_msg(mailbox, contact_chat_id, msg); mrmailbox_add_device_msg(mailbox, contact_chat_id, msg);
@ -305,7 +305,7 @@ static void secure_connection_established(mrmailbox_t* mailbox, uint32_t contact
mailbox->m_cb(mailbox, DC_EVENT_CHAT_MODIFIED, contact_chat_id, 0); mailbox->m_cb(mailbox, DC_EVENT_CHAT_MODIFIED, contact_chat_id, 0);
free(msg); free(msg);
mrcontact_unref(contact); dc_contact_unref(contact);
} }
@ -313,7 +313,7 @@ static void secure_connection_established(mrmailbox_t* mailbox, uint32_t contact
#define VC_CONTACT_CONFIRM 6 #define VC_CONTACT_CONFIRM 6
static int s_bob_expects = 0; static int s_bob_expects = 0;
static mrlot_t* s_bobs_qr_scan = NULL; // should be surround eg. by mrsqlite3_lock/unlock static dc_lot_t* s_bobs_qr_scan = NULL; // should be surround eg. by dc_sqlite3_lock/unlock
#define BOB_ERROR 0 #define BOB_ERROR 0
#define BOB_SUCCESS 1 #define BOB_SUCCESS 1
@ -367,7 +367,7 @@ char* dc_get_securejoin_qr(dc_context_t* mailbox, uint32_t group_chat_id)
char* fingerprint = NULL; char* fingerprint = NULL;
char* invitenumber = NULL; char* invitenumber = NULL;
char* auth = NULL; char* auth = NULL;
mrchat_t* chat = NULL; dc_chat_t* chat = NULL;
char* group_name = NULL; char* group_name = NULL;
char* group_name_urlencoded= NULL; char* group_name_urlencoded= NULL;
@ -377,7 +377,7 @@ char* dc_get_securejoin_qr(dc_context_t* mailbox, uint32_t group_chat_id)
mrmailbox_ensure_secret_key_exists(mailbox); mrmailbox_ensure_secret_key_exists(mailbox);
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
// invitenumber will be used to allow starting the handshake, auth will be used to verify the fingerprint // invitenumber will be used to allow starting the handshake, auth will be used to verify the fingerprint
@ -393,14 +393,14 @@ char* dc_get_securejoin_qr(dc_context_t* mailbox, uint32_t group_chat_id)
mrtoken_save__(mailbox, MRT_AUTH, group_chat_id, auth); mrtoken_save__(mailbox, MRT_AUTH, group_chat_id, auth);
} }
if( (self_addr = mrsqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL)) == NULL ) { if( (self_addr = dc_sqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL)) == NULL ) {
dc_log_error(mailbox, 0, "Not configured, cannot generate QR code."); dc_log_error(mailbox, 0, "Not configured, cannot generate QR code.");
goto cleanup; goto cleanup;
} }
self_name = mrsqlite3_get_config__(mailbox->m_sql, "displayname", ""); self_name = dc_sqlite3_get_config__(mailbox->m_sql, "displayname", "");
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
if( (fingerprint=get_self_fingerprint(mailbox)) == NULL ) { if( (fingerprint=get_self_fingerprint(mailbox)) == NULL ) {
@ -418,7 +418,7 @@ char* dc_get_securejoin_qr(dc_context_t* mailbox, uint32_t group_chat_id)
dc_log_error(mailbox, 0, "Secure join is only available for verified groups."); dc_log_error(mailbox, 0, "Secure join is only available for verified groups.");
goto cleanup; goto cleanup;
} }
group_name = mrchat_get_name(chat); group_name = dc_chat_get_name(chat);
group_name_urlencoded = mr_urlencode(group_name); group_name_urlencoded = mr_urlencode(group_name);
qr = mr_mprintf(OPENPGP4FPR_SCHEME "%s#a=%s&g=%s&x=%s&i=%s&s=%s", fingerprint, self_addr_urlencoded, group_name_urlencoded, chat->m_grpid, invitenumber, auth); qr = mr_mprintf(OPENPGP4FPR_SCHEME "%s#a=%s&g=%s&x=%s&i=%s&s=%s", fingerprint, self_addr_urlencoded, group_name_urlencoded, chat->m_grpid, invitenumber, auth);
} }
@ -429,7 +429,7 @@ char* dc_get_securejoin_qr(dc_context_t* mailbox, uint32_t group_chat_id)
} }
cleanup: cleanup:
if( locked ) { mrsqlite3_unlock(mailbox->m_sql); } if( locked ) { dc_sqlite3_unlock(mailbox->m_sql); }
free(self_addr_urlencoded); free(self_addr_urlencoded);
free(self_addr); free(self_addr);
free(self_name); free(self_name);
@ -437,7 +437,7 @@ cleanup:
free(fingerprint); free(fingerprint);
free(invitenumber); free(invitenumber);
free(auth); free(auth);
mrchat_unref(chat); dc_chat_unref(chat);
free(group_name); free(group_name);
free(group_name_urlencoded); free(group_name_urlencoded);
return qr? qr : safe_strdup(NULL); return qr? qr : safe_strdup(NULL);
@ -480,7 +480,7 @@ uint32_t dc_join_securejoin(dc_context_t* mailbox, const char* qr)
int ongoing_allocated = 0; int ongoing_allocated = 0;
#define CHECK_EXIT if( mr_shall_stop_ongoing ) { goto cleanup; } #define CHECK_EXIT if( mr_shall_stop_ongoing ) { goto cleanup; }
uint32_t contact_chat_id = 0; uint32_t contact_chat_id = 0;
mrlot_t* qr_scan = NULL; dc_lot_t* qr_scan = NULL;
int join_vg = 0; int join_vg = 0;
dc_log_info(mailbox, 0, "Requesting secure-join ..."); dc_log_info(mailbox, 0, "Requesting secure-join ...");
@ -514,9 +514,9 @@ uint32_t dc_join_securejoin(dc_context_t* mailbox, const char* qr)
join_vg = (qr_scan->m_state==MR_QR_ASK_VERIFYGROUP); join_vg = (qr_scan->m_state==MR_QR_ASK_VERIFYGROUP);
s_bobs_status = 0; s_bobs_status = 0;
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
s_bobs_qr_scan = qr_scan; s_bobs_qr_scan = qr_scan;
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
if( fingerprint_equals_sender(mailbox, qr_scan->m_fingerprint, contact_chat_id) ) { if( fingerprint_equals_sender(mailbox, qr_scan->m_fingerprint, contact_chat_id) ) {
// the scanned fingerprint matches Alice's key, we can proceed to step 4b) directly and save two mails // the scanned fingerprint matches Alice's key, we can proceed to step 4b) directly and save two mails
@ -545,27 +545,27 @@ cleanup:
if( s_bobs_status == BOB_SUCCESS ) { if( s_bobs_status == BOB_SUCCESS ) {
if( join_vg ) { if( join_vg ) {
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
ret_chat_id = mrmailbox_get_chat_id_by_grpid__(mailbox, qr_scan->m_text2, NULL, NULL); ret_chat_id = mrmailbox_get_chat_id_by_grpid__(mailbox, qr_scan->m_text2, NULL, NULL);
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
} }
else { else {
ret_chat_id = contact_chat_id; ret_chat_id = contact_chat_id;
} }
} }
mrsqlite3_lock(mailbox->m_sql); dc_sqlite3_lock(mailbox->m_sql);
s_bobs_qr_scan = NULL; s_bobs_qr_scan = NULL;
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
mrlot_unref(qr_scan); dc_lot_unref(qr_scan);
if( ongoing_allocated ) { mrmailbox_free_ongoing(mailbox); } if( ongoing_allocated ) { mrmailbox_free_ongoing(mailbox); }
return ret_chat_id; return ret_chat_id;
} }
int mrmailbox_handle_securejoin_handshake(mrmailbox_t* mailbox, mrmimeparser_t* mimeparser, uint32_t contact_id) int mrmailbox_handle_securejoin_handshake(mrmailbox_t* mailbox, dc_mimeparser_t* mimeparser, uint32_t contact_id)
{ {
int locked = 0; int locked = 0;
const char* step = NULL; const char* step = NULL;
@ -710,14 +710,14 @@ int mrmailbox_handle_securejoin_handshake(mrmailbox_t* mailbox, mrmimeparser_t*
LOCK LOCK
if( mrtoken_exists__(mailbox, MRT_AUTH, auth) == 0 ) { if( mrtoken_exists__(mailbox, MRT_AUTH, auth) == 0 ) {
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
could_not_establish_secure_connection(mailbox, contact_chat_id, "Auth invalid."); could_not_establish_secure_connection(mailbox, contact_chat_id, "Auth invalid.");
goto cleanup; goto cleanup;
} }
if( !mark_peer_as_verified__(mailbox, fingerprint) ) { if( !mark_peer_as_verified__(mailbox, fingerprint) ) {
mrsqlite3_unlock(mailbox->m_sql); dc_sqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
could_not_establish_secure_connection(mailbox, contact_chat_id, "Fingerprint mismatch on inviter-side."); // should not happen, we've compared the fingerprint some lines above could_not_establish_secure_connection(mailbox, contact_chat_id, "Fingerprint mismatch on inviter-side."); // should not happen, we've compared the fingerprint some lines above
goto cleanup; goto cleanup;
@ -811,7 +811,7 @@ int mrmailbox_handle_securejoin_handshake(mrmailbox_t* mailbox, mrmimeparser_t*
// for errors, we do not the corresponding message at all, it may come eg. from another device or may be useful to find out what was going wrong. // for errors, we do not the corresponding message at all, it may come eg. from another device or may be useful to find out what was going wrong.
if( ret == MR_IS_HANDSHAKE_STOP_NORMAL_PROCESSING ) { if( ret == MR_IS_HANDSHAKE_STOP_NORMAL_PROCESSING ) {
struct mailimf_field* field; struct mailimf_field* field;
if( (field=mrmimeparser_lookup_field(mimeparser, "Message-ID"))!=NULL && field->fld_type==MAILIMF_FIELD_MESSAGE_ID ) { if( (field=dc_mimeparser_lookup_field(mimeparser, "Message-ID"))!=NULL && field->fld_type==MAILIMF_FIELD_MESSAGE_ID ) {
struct mailimf_message_id* fld_message_id = field->fld_data.fld_message_id; struct mailimf_message_id* fld_message_id = field->fld_data.fld_message_id;
if( fld_message_id && fld_message_id->mid_value ) { if( fld_message_id && fld_message_id->mid_value ) {
dc_job_add(mailbox, DC_JOB_DELETE_MSG_ON_IMAP, mrmailbox_rfc724_mid_exists__(mailbox, fld_message_id->mid_value, NULL, NULL), NULL, 0); dc_job_add(mailbox, DC_JOB_DELETE_MSG_ON_IMAP, mrmailbox_rfc724_mid_exists__(mailbox, fld_message_id->mid_value, NULL, NULL), NULL, 0);

View file

@ -85,11 +85,11 @@ static int mr_is_quoted_headline(const char* buf)
******************************************************************************/ ******************************************************************************/
mrsimplify_t* mrsimplify_new() dc_simplify_t* dc_simplify_new()
{ {
mrsimplify_t* ths = NULL; dc_simplify_t* ths = NULL;
if( (ths=calloc(1, sizeof(mrsimplify_t)))==NULL ) { if( (ths=calloc(1, sizeof(dc_simplify_t)))==NULL ) {
exit(31); exit(31);
} }
@ -97,7 +97,7 @@ mrsimplify_t* mrsimplify_new()
} }
void mrsimplify_unref(mrsimplify_t* ths) void dc_simplify_unref(dc_simplify_t* ths)
{ {
if( ths == NULL ) { if( ths == NULL ) {
return; return;
@ -112,7 +112,7 @@ void mrsimplify_unref(mrsimplify_t* ths)
******************************************************************************/ ******************************************************************************/
static char* mrsimplify_simplify_plain_text(mrsimplify_t* ths, const char* buf_terminated) static char* dc_simplify_simplify_plain_text(dc_simplify_t* ths, const char* buf_terminated)
{ {
/* This function ... /* This function ...
... removes all text after the line `-- ` (footer mark) ... removes all text after the line `-- ` (footer mark)
@ -300,7 +300,7 @@ static char* mrsimplify_simplify_plain_text(mrsimplify_t* ths, const char* buf_t
******************************************************************************/ ******************************************************************************/
char* mrsimplify_simplify(mrsimplify_t* ths, const char* in_unterminated, int in_bytes, int is_html) char* dc_simplify_simplify(dc_simplify_t* ths, const char* in_unterminated, int in_bytes, int is_html)
{ {
/* create a copy of the given buffer */ /* create a copy of the given buffer */
char* out = NULL, *temp = NULL; char* out = NULL, *temp = NULL;
@ -320,7 +320,7 @@ char* mrsimplify_simplify(mrsimplify_t* ths, const char* in_unterminated, int in
/* convert HTML to text, if needed */ /* convert HTML to text, if needed */
if( is_html ) { if( is_html ) {
if( (temp = mr_dehtml(out)) != NULL ) { /* mr_dehtml() returns way too much lineends, however they're removed in the simplification below */ if( (temp = dc_dehtml(out)) != NULL ) { /* mr_dehtml() returns way too much lineends, however they're removed in the simplification below */
free(out); free(out);
out = temp; out = temp;
} }
@ -328,7 +328,7 @@ char* mrsimplify_simplify(mrsimplify_t* ths, const char* in_unterminated, int in
/* simplify the text in the buffer (characters to remove may be marked by `\r`) */ /* simplify the text in the buffer (characters to remove may be marked by `\r`) */
mr_remove_cr_chars(out); /* make comparisons easier, eg. for line `-- ` */ mr_remove_cr_chars(out); /* make comparisons easier, eg. for line `-- ` */
if( (temp = mrsimplify_simplify_plain_text(ths, out)) != NULL ) { if( (temp = dc_simplify_simplify_plain_text(ths, out)) != NULL ) {
free(out); free(out);
out = temp; out = temp;
} }

View file

@ -29,21 +29,21 @@ extern "C" {
/*** library-private **********************************************************/ /*** library-private **********************************************************/
typedef struct mrsimplify_t typedef struct dc_simplify_t
{ {
int m_is_forwarded; int m_is_forwarded;
int m_is_cut_at_begin; int m_is_cut_at_begin;
int m_is_cut_at_end; int m_is_cut_at_end;
} mrsimplify_t; } dc_simplify_t;
mrsimplify_t* mrsimplify_new (); dc_simplify_t* dc_simplify_new ();
void mrsimplify_unref (mrsimplify_t*); void dc_simplify_unref (dc_simplify_t*);
/* Simplify and normalise text: Remove quotes, signatures, unnecessary /* Simplify and normalise text: Remove quotes, signatures, unnecessary
lineends etc. lineends etc.
The data returned from Simplify() must be free()'d when no longer used, private */ The data returned from Simplify() must be free()'d when no longer used, private */
char* mrsimplify_simplify (mrsimplify_t*, const char* txt_unterminated, int txt_bytes, int is_html); char* dc_simplify_simplify (dc_simplify_t*, const char* txt_unterminated, int txt_bytes, int is_html);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -45,7 +45,7 @@
******************************************************************************/ ******************************************************************************/
void mrsqlite3_log_error(mrsqlite3_t* ths, const char* msg_format, ...) void dc_sqlite3_log_error(dc_sqlite3_t* ths, const char* msg_format, ...)
{ {
char* msg; char* msg;
const char* notSetUp = "SQLite object not set up."; const char* notSetUp = "SQLite object not set up.";
@ -59,7 +59,7 @@ void mrsqlite3_log_error(mrsqlite3_t* ths, const char* msg_format, ...)
} }
sqlite3_stmt* mrsqlite3_prepare_v2_(mrsqlite3_t* ths, const char* querystr) sqlite3_stmt* dc_sqlite3_prepare_v2_(dc_sqlite3_t* ths, const char* querystr)
{ {
sqlite3_stmt* retStmt = NULL; sqlite3_stmt* retStmt = NULL;
@ -72,7 +72,7 @@ sqlite3_stmt* mrsqlite3_prepare_v2_(mrsqlite3_t* ths, const char* querystr)
&retStmt, &retStmt,
NULL /*tail not interesting, we use only single statements*/) != SQLITE_OK ) NULL /*tail not interesting, we use only single statements*/) != SQLITE_OK )
{ {
mrsqlite3_log_error(ths, "Query failed: %s", querystr); dc_sqlite3_log_error(ths, "Query failed: %s", querystr);
return NULL; return NULL;
} }
@ -81,20 +81,20 @@ sqlite3_stmt* mrsqlite3_prepare_v2_(mrsqlite3_t* ths, const char* querystr)
} }
int mrsqlite3_execute__(mrsqlite3_t* ths, const char* querystr) int dc_sqlite3_execute__(dc_sqlite3_t* ths, const char* querystr)
{ {
int success = 0; int success = 0;
sqlite3_stmt* stmt = NULL; sqlite3_stmt* stmt = NULL;
int sqlState; int sqlState;
stmt = mrsqlite3_prepare_v2_(ths, querystr); stmt = dc_sqlite3_prepare_v2_(ths, querystr);
if( stmt == NULL ) { if( stmt == NULL ) {
goto cleanup; goto cleanup;
} }
sqlState = sqlite3_step(stmt); sqlState = sqlite3_step(stmt);
if( sqlState != SQLITE_DONE && sqlState != SQLITE_ROW ) { if( sqlState != SQLITE_DONE && sqlState != SQLITE_ROW ) {
mrsqlite3_log_error(ths, "Cannot excecute \"%s\".", querystr); dc_sqlite3_log_error(ths, "Cannot excecute \"%s\".", querystr);
goto cleanup; goto cleanup;
} }
@ -113,12 +113,12 @@ cleanup:
******************************************************************************/ ******************************************************************************/
mrsqlite3_t* mrsqlite3_new(mrmailbox_t* mailbox) dc_sqlite3_t* dc_sqlite3_new(mrmailbox_t* mailbox)
{ {
mrsqlite3_t* ths = NULL; dc_sqlite3_t* ths = NULL;
int i; int i;
if( (ths=calloc(1, sizeof(mrsqlite3_t)))==NULL ) { if( (ths=calloc(1, sizeof(dc_sqlite3_t)))==NULL ) {
exit(24); /* cannot allocate little memory, unrecoverable error */ exit(24); /* cannot allocate little memory, unrecoverable error */
} }
@ -134,7 +134,7 @@ mrsqlite3_t* mrsqlite3_new(mrmailbox_t* mailbox)
} }
void mrsqlite3_unref(mrsqlite3_t* ths) void dc_sqlite3_unref(dc_sqlite3_t* ths)
{ {
if( ths == NULL ) { if( ths == NULL ) {
return; return;
@ -142,7 +142,7 @@ void mrsqlite3_unref(mrsqlite3_t* ths)
if( ths->m_cobj ) { if( ths->m_cobj ) {
pthread_mutex_lock(&ths->m_critical_); /* as a very exeception, we do the locking inside the mrsqlite3-class - normally, this should be done by the caller! */ pthread_mutex_lock(&ths->m_critical_); /* as a very exeception, we do the locking inside the mrsqlite3-class - normally, this should be done by the caller! */
mrsqlite3_close__(ths); dc_sqlite3_close__(ths);
pthread_mutex_unlock(&ths->m_critical_); pthread_mutex_unlock(&ths->m_critical_);
} }
@ -151,7 +151,7 @@ void mrsqlite3_unref(mrsqlite3_t* ths)
} }
int mrsqlite3_open__(mrsqlite3_t* ths, const char* dbfile, int flags) int dc_sqlite3_open__(dc_sqlite3_t* ths, const char* dbfile, int flags)
{ {
if( ths == NULL || dbfile == NULL ) { if( ths == NULL || dbfile == NULL ) {
goto cleanup; goto cleanup;
@ -168,13 +168,13 @@ int mrsqlite3_open__(mrsqlite3_t* ths, const char* dbfile, int flags)
} }
// Force serialized mode (SQLITE_OPEN_FULLMUTEX) explicitly. // Force serialized mode (SQLITE_OPEN_FULLMUTEX) explicitly.
// So, most of the explicit lock/unlocks on mrsqlite3_t object are no longer needed. // So, most of the explicit lock/unlocks on dc_sqlite3_t object are no longer needed.
// However, locking is _also_ used for mrmailbox_t which _is_ still needed, so, we // However, locking is _also_ used for mrmailbox_t which _is_ still needed, so, we
// should remove locks only if we're really sure. // should remove locks only if we're really sure.
if( sqlite3_open_v2(dbfile, &ths->m_cobj, if( sqlite3_open_v2(dbfile, &ths->m_cobj,
SQLITE_OPEN_FULLMUTEX | ((flags&MR_OPEN_READONLY)? SQLITE_OPEN_READONLY : (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)), SQLITE_OPEN_FULLMUTEX | ((flags&MR_OPEN_READONLY)? SQLITE_OPEN_READONLY : (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)),
NULL) != SQLITE_OK ) { NULL) != SQLITE_OK ) {
mrsqlite3_log_error(ths, "Cannot open database \"%s\".", dbfile); /* ususally, even for errors, the pointer is set up (if not, this is also checked by mrsqlite3_log_error()) */ dc_sqlite3_log_error(ths, "Cannot open database \"%s\".", dbfile); /* ususally, even for errors, the pointer is set up (if not, this is also checked by dc_sqlite3_log_error()) */
goto cleanup; goto cleanup;
} }
@ -190,28 +190,28 @@ int mrsqlite3_open__(mrsqlite3_t* ths, const char* dbfile, int flags)
int dbversion_before_update = 0; int dbversion_before_update = 0;
/* Init tables to dbversion=0 */ /* Init tables to dbversion=0 */
if( !mrsqlite3_table_exists__(ths, "config") ) if( !dc_sqlite3_table_exists__(ths, "config") )
{ {
dc_log_info(ths->m_mailbox, 0, "First time init: creating tables in \"%s\".", dbfile); dc_log_info(ths->m_mailbox, 0, "First time init: creating tables in \"%s\".", dbfile);
mrsqlite3_execute__(ths, "CREATE TABLE config (id INTEGER PRIMARY KEY, keyname TEXT, value TEXT);"); dc_sqlite3_execute__(ths, "CREATE TABLE config (id INTEGER PRIMARY KEY, keyname TEXT, value TEXT);");
mrsqlite3_execute__(ths, "CREATE INDEX config_index1 ON config (keyname);"); dc_sqlite3_execute__(ths, "CREATE INDEX config_index1 ON config (keyname);");
mrsqlite3_execute__(ths, "CREATE TABLE contacts (id INTEGER PRIMARY KEY," dc_sqlite3_execute__(ths, "CREATE TABLE contacts (id INTEGER PRIMARY KEY,"
" name TEXT DEFAULT ''," " name TEXT DEFAULT '',"
" addr TEXT DEFAULT '' COLLATE NOCASE," " addr TEXT DEFAULT '' COLLATE NOCASE,"
" origin INTEGER DEFAULT 0," " origin INTEGER DEFAULT 0,"
" blocked INTEGER DEFAULT 0," " blocked INTEGER DEFAULT 0,"
" last_seen INTEGER DEFAULT 0," /* last_seen is for future use */ " last_seen INTEGER DEFAULT 0," /* last_seen is for future use */
" param TEXT DEFAULT '');"); /* param is for future use, eg. for the status */ " param TEXT DEFAULT '');"); /* param is for future use, eg. for the status */
mrsqlite3_execute__(ths, "CREATE INDEX contacts_index1 ON contacts (name COLLATE NOCASE);"); /* needed for query contacts */ dc_sqlite3_execute__(ths, "CREATE INDEX contacts_index1 ON contacts (name COLLATE NOCASE);"); /* needed for query contacts */
mrsqlite3_execute__(ths, "CREATE INDEX contacts_index2 ON contacts (addr COLLATE NOCASE);"); /* needed for query and on receiving mails */ dc_sqlite3_execute__(ths, "CREATE INDEX contacts_index2 ON contacts (addr COLLATE NOCASE);"); /* needed for query and on receiving mails */
mrsqlite3_execute__(ths, "INSERT INTO contacts (id,name,origin) VALUES (1,'self',262144), (2,'device',262144), (3,'rsvd',262144), (4,'rsvd',262144), (5,'rsvd',262144), (6,'rsvd',262144), (7,'rsvd',262144), (8,'rsvd',262144), (9,'rsvd',262144);"); dc_sqlite3_execute__(ths, "INSERT INTO contacts (id,name,origin) VALUES (1,'self',262144), (2,'device',262144), (3,'rsvd',262144), (4,'rsvd',262144), (5,'rsvd',262144), (6,'rsvd',262144), (7,'rsvd',262144), (8,'rsvd',262144), (9,'rsvd',262144);");
#if !defined(MR_ORIGIN_INTERNAL) || MR_ORIGIN_INTERNAL!=262144 #if !defined(MR_ORIGIN_INTERNAL) || MR_ORIGIN_INTERNAL!=262144
#error #error
#endif #endif
mrsqlite3_execute__(ths, "CREATE TABLE chats (id INTEGER PRIMARY KEY, " dc_sqlite3_execute__(ths, "CREATE TABLE chats (id INTEGER PRIMARY KEY, "
" type INTEGER DEFAULT 0," " type INTEGER DEFAULT 0,"
" name TEXT DEFAULT ''," " name TEXT DEFAULT '',"
" draft_timestamp INTEGER DEFAULT 0," " draft_timestamp INTEGER DEFAULT 0,"
@ -219,10 +219,10 @@ int mrsqlite3_open__(mrsqlite3_t* ths, const char* dbfile, int flags)
" blocked INTEGER DEFAULT 0," " blocked INTEGER DEFAULT 0,"
" grpid TEXT DEFAULT ''," /* contacts-global unique group-ID, see mrchat.c for details */ " grpid TEXT DEFAULT ''," /* contacts-global unique group-ID, see mrchat.c for details */
" param TEXT DEFAULT '');"); " param TEXT DEFAULT '');");
mrsqlite3_execute__(ths, "CREATE INDEX chats_index1 ON chats (grpid);"); dc_sqlite3_execute__(ths, "CREATE INDEX chats_index1 ON chats (grpid);");
mrsqlite3_execute__(ths, "CREATE TABLE chats_contacts (chat_id INTEGER, contact_id INTEGER);"); dc_sqlite3_execute__(ths, "CREATE TABLE chats_contacts (chat_id INTEGER, contact_id INTEGER);");
mrsqlite3_execute__(ths, "CREATE INDEX chats_contacts_index1 ON chats_contacts (chat_id);"); dc_sqlite3_execute__(ths, "CREATE INDEX chats_contacts_index1 ON chats_contacts (chat_id);");
mrsqlite3_execute__(ths, "INSERT INTO chats (id,type,name) VALUES (1,120,'deaddrop'), (2,120,'rsvd'), (3,120,'trash'), (4,120,'msgs_in_creation'), (5,120,'starred'), (6,120,'archivedlink'), (7,100,'rsvd'), (8,100,'rsvd'), (9,100,'rsvd');"); dc_sqlite3_execute__(ths, "INSERT INTO chats (id,type,name) VALUES (1,120,'deaddrop'), (2,120,'rsvd'), (3,120,'trash'), (4,120,'msgs_in_creation'), (5,120,'starred'), (6,120,'archivedlink'), (7,100,'rsvd'), (8,100,'rsvd'), (9,100,'rsvd');");
#if !defined(MR_CHAT_TYPE_SINGLE) || MR_CHAT_TYPE_SINGLE!=100 || MR_CHAT_TYPE_GROUP!=120 || \ #if !defined(MR_CHAT_TYPE_SINGLE) || MR_CHAT_TYPE_SINGLE!=100 || MR_CHAT_TYPE_GROUP!=120 || \
MR_CHAT_ID_DEADDROP!=1 || MR_CHAT_ID_TRASH!=3 || \ MR_CHAT_ID_DEADDROP!=1 || MR_CHAT_ID_TRASH!=3 || \
MR_CHAT_ID_MSGS_IN_CREATION!=4 || MR_CHAT_ID_STARRED!=5 || MR_CHAT_ID_ARCHIVED_LINK!=6 || \ MR_CHAT_ID_MSGS_IN_CREATION!=4 || MR_CHAT_ID_STARRED!=5 || MR_CHAT_ID_ARCHIVED_LINK!=6 || \
@ -230,7 +230,7 @@ int mrsqlite3_open__(mrsqlite3_t* ths, const char* dbfile, int flags)
#error #error
#endif #endif
mrsqlite3_execute__(ths, "CREATE TABLE msgs (id INTEGER PRIMARY KEY," dc_sqlite3_execute__(ths, "CREATE TABLE msgs (id INTEGER PRIMARY KEY,"
" rfc724_mid TEXT DEFAULT ''," /* forever-global-unique Message-ID-string, unfortunately, this cannot be easily used to communicate via IMAP */ " rfc724_mid TEXT DEFAULT ''," /* forever-global-unique Message-ID-string, unfortunately, this cannot be easily used to communicate via IMAP */
" server_folder TEXT DEFAULT ''," /* folder as used on the server, the folder will change when messages are moved around. */ " server_folder TEXT DEFAULT ''," /* folder as used on the server, the folder will change when messages are moved around. */
" server_uid INTEGER DEFAULT 0," /* UID as used on the server, the UID will change when messages are moved around, unique together with validity, see RFC 3501; the validity may differ from folder to folder. We use the server_uid for "markseen" and to delete messages as we check against the message-id, we ignore the validity for these commands. */ " server_uid INTEGER DEFAULT 0," /* UID as used on the server, the UID will change when messages are moved around, unique together with validity, see RFC 3501; the validity may differ from folder to folder. We use the server_uid for "markseen" and to delete messages as we check against the message-id, we ignore the validity for these commands. */
@ -245,33 +245,33 @@ int mrsqlite3_open__(mrsqlite3_t* ths, const char* dbfile, int flags)
" txt TEXT DEFAULT ''," /* as this is also used for (fulltext) searching, nothing but normal, plain text should go here */ " txt TEXT DEFAULT ''," /* as this is also used for (fulltext) searching, nothing but normal, plain text should go here */
" txt_raw TEXT DEFAULT ''," " txt_raw TEXT DEFAULT '',"
" param TEXT DEFAULT '');"); " param TEXT DEFAULT '');");
mrsqlite3_execute__(ths, "CREATE INDEX msgs_index1 ON msgs (rfc724_mid);"); /* in our database, one email may be split up to several messages (eg. one per image), so the email-Message-ID may be used for several records; id is always unique */ dc_sqlite3_execute__(ths, "CREATE INDEX msgs_index1 ON msgs (rfc724_mid);"); /* in our database, one email may be split up to several messages (eg. one per image), so the email-Message-ID may be used for several records; id is always unique */
mrsqlite3_execute__(ths, "CREATE INDEX msgs_index2 ON msgs (chat_id);"); dc_sqlite3_execute__(ths, "CREATE INDEX msgs_index2 ON msgs (chat_id);");
mrsqlite3_execute__(ths, "CREATE INDEX msgs_index3 ON msgs (timestamp);"); /* for sorting */ dc_sqlite3_execute__(ths, "CREATE INDEX msgs_index3 ON msgs (timestamp);"); /* for sorting */
mrsqlite3_execute__(ths, "CREATE INDEX msgs_index4 ON msgs (state);"); /* for selecting the count of fresh messages (as there are normally only few unread messages, an index over the chat_id is not required for _this_ purpose */ dc_sqlite3_execute__(ths, "CREATE INDEX msgs_index4 ON msgs (state);"); /* for selecting the count of fresh messages (as there are normally only few unread messages, an index over the chat_id is not required for _this_ purpose */
mrsqlite3_execute__(ths, "INSERT INTO msgs (id,msgrmsg,txt) VALUES (1,0,'marker1'), (2,0,'rsvd'), (3,0,'rsvd'), (4,0,'rsvd'), (5,0,'rsvd'), (6,0,'rsvd'), (7,0,'rsvd'), (8,0,'rsvd'), (9,0,'daymarker');"); /* make sure, the reserved IDs are not used */ dc_sqlite3_execute__(ths, "INSERT INTO msgs (id,msgrmsg,txt) VALUES (1,0,'marker1'), (2,0,'rsvd'), (3,0,'rsvd'), (4,0,'rsvd'), (5,0,'rsvd'), (6,0,'rsvd'), (7,0,'rsvd'), (8,0,'rsvd'), (9,0,'daymarker');"); /* make sure, the reserved IDs are not used */
mrsqlite3_execute__(ths, "CREATE TABLE jobs (id INTEGER PRIMARY KEY," dc_sqlite3_execute__(ths, "CREATE TABLE jobs (id INTEGER PRIMARY KEY,"
" added_timestamp INTEGER," " added_timestamp INTEGER,"
" desired_timestamp INTEGER DEFAULT 0," " desired_timestamp INTEGER DEFAULT 0,"
" action INTEGER," " action INTEGER,"
" foreign_id INTEGER," " foreign_id INTEGER,"
" param TEXT DEFAULT '');"); " param TEXT DEFAULT '');");
mrsqlite3_execute__(ths, "CREATE INDEX jobs_index1 ON jobs (desired_timestamp);"); dc_sqlite3_execute__(ths, "CREATE INDEX jobs_index1 ON jobs (desired_timestamp);");
if( !mrsqlite3_table_exists__(ths, "config") || !mrsqlite3_table_exists__(ths, "contacts") if( !dc_sqlite3_table_exists__(ths, "config") || !dc_sqlite3_table_exists__(ths, "contacts")
|| !mrsqlite3_table_exists__(ths, "chats") || !mrsqlite3_table_exists__(ths, "chats_contacts") || !dc_sqlite3_table_exists__(ths, "chats") || !dc_sqlite3_table_exists__(ths, "chats_contacts")
|| !mrsqlite3_table_exists__(ths, "msgs") || !mrsqlite3_table_exists__(ths, "jobs") ) || !dc_sqlite3_table_exists__(ths, "msgs") || !dc_sqlite3_table_exists__(ths, "jobs") )
{ {
mrsqlite3_log_error(ths, "Cannot create tables in new database \"%s\".", dbfile); dc_sqlite3_log_error(ths, "Cannot create tables in new database \"%s\".", dbfile);
goto cleanup; /* cannot create the tables - maybe we cannot write? */ goto cleanup; /* cannot create the tables - maybe we cannot write? */
} }
mrsqlite3_set_config_int__(ths, "dbversion", 0); dc_sqlite3_set_config_int__(ths, "dbversion", 0);
} }
else else
{ {
dbversion_before_update = mrsqlite3_get_config_int__(ths, "dbversion", 0); dbversion_before_update = dc_sqlite3_get_config_int__(ths, "dbversion", 0);
} }
// (1) update low-level database structure. // (1) update low-level database structure.
@ -282,30 +282,30 @@ int mrsqlite3_open__(mrsqlite3_t* ths, const char* dbfile, int flags)
#define NEW_DB_VERSION 1 #define NEW_DB_VERSION 1
if( dbversion < NEW_DB_VERSION ) if( dbversion < NEW_DB_VERSION )
{ {
mrsqlite3_execute__(ths, "CREATE TABLE leftgrps (" dc_sqlite3_execute__(ths, "CREATE TABLE leftgrps ("
" id INTEGER PRIMARY KEY," " id INTEGER PRIMARY KEY,"
" grpid TEXT DEFAULT '');"); " grpid TEXT DEFAULT '');");
mrsqlite3_execute__(ths, "CREATE INDEX leftgrps_index1 ON leftgrps (grpid);"); dc_sqlite3_execute__(ths, "CREATE INDEX leftgrps_index1 ON leftgrps (grpid);");
dbversion = NEW_DB_VERSION; dbversion = NEW_DB_VERSION;
mrsqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION); dc_sqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION);
} }
#undef NEW_DB_VERSION #undef NEW_DB_VERSION
#define NEW_DB_VERSION 2 #define NEW_DB_VERSION 2
if( dbversion < NEW_DB_VERSION ) if( dbversion < NEW_DB_VERSION )
{ {
mrsqlite3_execute__(ths, "ALTER TABLE contacts ADD COLUMN authname TEXT DEFAULT '';"); dc_sqlite3_execute__(ths, "ALTER TABLE contacts ADD COLUMN authname TEXT DEFAULT '';");
dbversion = NEW_DB_VERSION; dbversion = NEW_DB_VERSION;
mrsqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION); dc_sqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION);
} }
#undef NEW_DB_VERSION #undef NEW_DB_VERSION
#define NEW_DB_VERSION 7 #define NEW_DB_VERSION 7
if( dbversion < NEW_DB_VERSION ) if( dbversion < NEW_DB_VERSION )
{ {
mrsqlite3_execute__(ths, "CREATE TABLE keypairs (" dc_sqlite3_execute__(ths, "CREATE TABLE keypairs ("
" id INTEGER PRIMARY KEY," " id INTEGER PRIMARY KEY,"
" addr TEXT DEFAULT '' COLLATE NOCASE," " addr TEXT DEFAULT '' COLLATE NOCASE,"
" is_default INTEGER DEFAULT 0," " is_default INTEGER DEFAULT 0,"
@ -314,134 +314,134 @@ int mrsqlite3_open__(mrsqlite3_t* ths, const char* dbfile, int flags)
" created INTEGER DEFAULT 0);"); " created INTEGER DEFAULT 0);");
dbversion = NEW_DB_VERSION; dbversion = NEW_DB_VERSION;
mrsqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION); dc_sqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION);
} }
#undef NEW_DB_VERSION #undef NEW_DB_VERSION
#define NEW_DB_VERSION 10 #define NEW_DB_VERSION 10
if( dbversion < NEW_DB_VERSION ) if( dbversion < NEW_DB_VERSION )
{ {
mrsqlite3_execute__(ths, "CREATE TABLE acpeerstates (" dc_sqlite3_execute__(ths, "CREATE TABLE acpeerstates ("
" id INTEGER PRIMARY KEY," " id INTEGER PRIMARY KEY,"
" addr TEXT DEFAULT '' COLLATE NOCASE," /* no UNIQUE here, Autocrypt: requires the index above mail+type (type however, is not used at the moment, but to be future-proof, we do not use an index. instead we just check ourself if there is a record or not)*/ " addr TEXT DEFAULT '' COLLATE NOCASE," /* no UNIQUE here, Autocrypt: requires the index above mail+type (type however, is not used at the moment, but to be future-proof, we do not use an index. instead we just check ourself if there is a record or not)*/
" last_seen INTEGER DEFAULT 0," " last_seen INTEGER DEFAULT 0,"
" last_seen_autocrypt INTEGER DEFAULT 0," " last_seen_autocrypt INTEGER DEFAULT 0,"
" public_key," " public_key,"
" prefer_encrypted INTEGER DEFAULT 0);"); " prefer_encrypted INTEGER DEFAULT 0);");
mrsqlite3_execute__(ths, "CREATE INDEX acpeerstates_index1 ON acpeerstates (addr);"); dc_sqlite3_execute__(ths, "CREATE INDEX acpeerstates_index1 ON acpeerstates (addr);");
dbversion = NEW_DB_VERSION; dbversion = NEW_DB_VERSION;
mrsqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION); dc_sqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION);
} }
#undef NEW_DB_VERSION #undef NEW_DB_VERSION
#define NEW_DB_VERSION 12 #define NEW_DB_VERSION 12
if( dbversion < NEW_DB_VERSION ) if( dbversion < NEW_DB_VERSION )
{ {
mrsqlite3_execute__(ths, "CREATE TABLE msgs_mdns (" dc_sqlite3_execute__(ths, "CREATE TABLE msgs_mdns ("
" msg_id INTEGER, " " msg_id INTEGER, "
" contact_id INTEGER);"); " contact_id INTEGER);");
mrsqlite3_execute__(ths, "CREATE INDEX msgs_mdns_index1 ON msgs_mdns (msg_id);"); dc_sqlite3_execute__(ths, "CREATE INDEX msgs_mdns_index1 ON msgs_mdns (msg_id);");
dbversion = NEW_DB_VERSION; dbversion = NEW_DB_VERSION;
mrsqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION); dc_sqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION);
} }
#undef NEW_DB_VERSION #undef NEW_DB_VERSION
#define NEW_DB_VERSION 17 #define NEW_DB_VERSION 17
if( dbversion < NEW_DB_VERSION ) if( dbversion < NEW_DB_VERSION )
{ {
mrsqlite3_execute__(ths, "ALTER TABLE chats ADD COLUMN archived INTEGER DEFAULT 0;"); dc_sqlite3_execute__(ths, "ALTER TABLE chats ADD COLUMN archived INTEGER DEFAULT 0;");
mrsqlite3_execute__(ths, "CREATE INDEX chats_index2 ON chats (archived);"); dc_sqlite3_execute__(ths, "CREATE INDEX chats_index2 ON chats (archived);");
mrsqlite3_execute__(ths, "ALTER TABLE msgs ADD COLUMN starred INTEGER DEFAULT 0;"); dc_sqlite3_execute__(ths, "ALTER TABLE msgs ADD COLUMN starred INTEGER DEFAULT 0;");
mrsqlite3_execute__(ths, "CREATE INDEX msgs_index5 ON msgs (starred);"); dc_sqlite3_execute__(ths, "CREATE INDEX msgs_index5 ON msgs (starred);");
dbversion = NEW_DB_VERSION; dbversion = NEW_DB_VERSION;
mrsqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION); dc_sqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION);
} }
#undef NEW_DB_VERSION #undef NEW_DB_VERSION
#define NEW_DB_VERSION 18 #define NEW_DB_VERSION 18
if( dbversion < NEW_DB_VERSION ) if( dbversion < NEW_DB_VERSION )
{ {
mrsqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN gossip_timestamp INTEGER DEFAULT 0;"); dc_sqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN gossip_timestamp INTEGER DEFAULT 0;");
mrsqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN gossip_key;"); dc_sqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN gossip_key;");
dbversion = NEW_DB_VERSION; dbversion = NEW_DB_VERSION;
mrsqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION); dc_sqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION);
} }
#undef NEW_DB_VERSION #undef NEW_DB_VERSION
#define NEW_DB_VERSION 27 #define NEW_DB_VERSION 27
if( dbversion < NEW_DB_VERSION ) if( dbversion < NEW_DB_VERSION )
{ {
mrsqlite3_execute__(ths, "DELETE FROM msgs WHERE chat_id=1 OR chat_id=2;"); /* chat.id=1 and chat.id=2 are the old deaddrops, the current ones are defined by chats.blocked=2 */ dc_sqlite3_execute__(ths, "DELETE FROM msgs WHERE chat_id=1 OR chat_id=2;"); /* chat.id=1 and chat.id=2 are the old deaddrops, the current ones are defined by chats.blocked=2 */
mrsqlite3_execute__(ths, "CREATE INDEX chats_contacts_index2 ON chats_contacts (contact_id);"); /* needed to find chat by contact list */ dc_sqlite3_execute__(ths, "CREATE INDEX chats_contacts_index2 ON chats_contacts (contact_id);"); /* needed to find chat by contact list */
mrsqlite3_execute__(ths, "ALTER TABLE msgs ADD COLUMN timestamp_sent INTEGER DEFAULT 0;"); dc_sqlite3_execute__(ths, "ALTER TABLE msgs ADD COLUMN timestamp_sent INTEGER DEFAULT 0;");
mrsqlite3_execute__(ths, "ALTER TABLE msgs ADD COLUMN timestamp_rcvd INTEGER DEFAULT 0;"); dc_sqlite3_execute__(ths, "ALTER TABLE msgs ADD COLUMN timestamp_rcvd INTEGER DEFAULT 0;");
dbversion = NEW_DB_VERSION; dbversion = NEW_DB_VERSION;
mrsqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION); dc_sqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION);
} }
#undef NEW_DB_VERSION #undef NEW_DB_VERSION
#define NEW_DB_VERSION 34 #define NEW_DB_VERSION 34
if( dbversion < NEW_DB_VERSION ) if( dbversion < NEW_DB_VERSION )
{ {
mrsqlite3_execute__(ths, "ALTER TABLE msgs ADD COLUMN hidden INTEGER DEFAULT 0;"); dc_sqlite3_execute__(ths, "ALTER TABLE msgs ADD COLUMN hidden INTEGER DEFAULT 0;");
mrsqlite3_execute__(ths, "ALTER TABLE msgs_mdns ADD COLUMN timestamp_sent INTEGER DEFAULT 0;"); dc_sqlite3_execute__(ths, "ALTER TABLE msgs_mdns ADD COLUMN timestamp_sent INTEGER DEFAULT 0;");
mrsqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN public_key_fingerprint TEXT DEFAULT '';"); /* do not add `COLLATE NOCASE` case-insensivity is not needed as we force uppercase on store - otoh case-sensivity may be neeed for other/upcoming fingerprint formats */ dc_sqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN public_key_fingerprint TEXT DEFAULT '';"); /* do not add `COLLATE NOCASE` case-insensivity is not needed as we force uppercase on store - otoh case-sensivity may be neeed for other/upcoming fingerprint formats */
mrsqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN gossip_key_fingerprint TEXT DEFAULT '';"); /* do not add `COLLATE NOCASE` case-insensivity is not needed as we force uppercase on store - otoh case-sensivity may be neeed for other/upcoming fingerprint formats */ dc_sqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN gossip_key_fingerprint TEXT DEFAULT '';"); /* do not add `COLLATE NOCASE` case-insensivity is not needed as we force uppercase on store - otoh case-sensivity may be neeed for other/upcoming fingerprint formats */
mrsqlite3_execute__(ths, "CREATE INDEX acpeerstates_index3 ON acpeerstates (public_key_fingerprint);"); dc_sqlite3_execute__(ths, "CREATE INDEX acpeerstates_index3 ON acpeerstates (public_key_fingerprint);");
mrsqlite3_execute__(ths, "CREATE INDEX acpeerstates_index4 ON acpeerstates (gossip_key_fingerprint);"); dc_sqlite3_execute__(ths, "CREATE INDEX acpeerstates_index4 ON acpeerstates (gossip_key_fingerprint);");
recalc_fingerprints = 1; recalc_fingerprints = 1;
dbversion = NEW_DB_VERSION; dbversion = NEW_DB_VERSION;
mrsqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION); dc_sqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION);
} }
#undef NEW_DB_VERSION #undef NEW_DB_VERSION
#define NEW_DB_VERSION 39 #define NEW_DB_VERSION 39
if( dbversion < NEW_DB_VERSION ) if( dbversion < NEW_DB_VERSION )
{ {
mrsqlite3_execute__(ths, "CREATE TABLE tokens (" dc_sqlite3_execute__(ths, "CREATE TABLE tokens ("
" id INTEGER PRIMARY KEY," " id INTEGER PRIMARY KEY,"
" namespc INTEGER DEFAULT 0," " namespc INTEGER DEFAULT 0,"
" foreign_id INTEGER DEFAULT 0," " foreign_id INTEGER DEFAULT 0,"
" token TEXT DEFAULT ''," " token TEXT DEFAULT '',"
" timestamp INTEGER DEFAULT 0);"); " timestamp INTEGER DEFAULT 0);");
mrsqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN verified_key;"); dc_sqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN verified_key;");
mrsqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN verified_key_fingerprint TEXT DEFAULT '';"); /* do not add `COLLATE NOCASE` case-insensivity is not needed as we force uppercase on store - otoh case-sensivity may be neeed for other/upcoming fingerprint formats */ dc_sqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN verified_key_fingerprint TEXT DEFAULT '';"); /* do not add `COLLATE NOCASE` case-insensivity is not needed as we force uppercase on store - otoh case-sensivity may be neeed for other/upcoming fingerprint formats */
mrsqlite3_execute__(ths, "CREATE INDEX acpeerstates_index5 ON acpeerstates (verified_key_fingerprint);"); dc_sqlite3_execute__(ths, "CREATE INDEX acpeerstates_index5 ON acpeerstates (verified_key_fingerprint);");
if( dbversion_before_update == 34 ) if( dbversion_before_update == 34 )
{ {
// migrate database from the use of verified-flags to verified_key, // migrate database from the use of verified-flags to verified_key,
// _only_ version 34 (0.17.0) has the fields public_key_verified and gossip_key_verified // _only_ version 34 (0.17.0) has the fields public_key_verified and gossip_key_verified
// this block can be deleted in half a year or so (created 5/2018) // this block can be deleted in half a year or so (created 5/2018)
mrsqlite3_execute__(ths, "UPDATE acpeerstates SET verified_key=gossip_key, verified_key_fingerprint=gossip_key_fingerprint WHERE gossip_key_verified=2;"); dc_sqlite3_execute__(ths, "UPDATE acpeerstates SET verified_key=gossip_key, verified_key_fingerprint=gossip_key_fingerprint WHERE gossip_key_verified=2;");
mrsqlite3_execute__(ths, "UPDATE acpeerstates SET verified_key=public_key, verified_key_fingerprint=public_key_fingerprint WHERE public_key_verified=2;"); dc_sqlite3_execute__(ths, "UPDATE acpeerstates SET verified_key=public_key, verified_key_fingerprint=public_key_fingerprint WHERE public_key_verified=2;");
} }
dbversion = NEW_DB_VERSION; dbversion = NEW_DB_VERSION;
mrsqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION); dc_sqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION);
} }
#undef NEW_DB_VERSION #undef NEW_DB_VERSION
#define NEW_DB_VERSION 40 #define NEW_DB_VERSION 40
if( dbversion < NEW_DB_VERSION ) if( dbversion < NEW_DB_VERSION )
{ {
mrsqlite3_execute__(ths, "ALTER TABLE jobs ADD COLUMN thread INTEGER DEFAULT 0;"); dc_sqlite3_execute__(ths, "ALTER TABLE jobs ADD COLUMN thread INTEGER DEFAULT 0;");
dbversion = NEW_DB_VERSION; dbversion = NEW_DB_VERSION;
mrsqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION); dc_sqlite3_set_config_int__(ths, "dbversion", NEW_DB_VERSION);
} }
#undef NEW_DB_VERSION #undef NEW_DB_VERSION
// (2) updates that require high-level objects (the structure is complete now and all objects are usable) // (2) updates that require high-level objects (the structure is complete now and all objects are usable)
if( recalc_fingerprints ) if( recalc_fingerprints )
{ {
sqlite3_stmt* stmt = mrsqlite3_prepare_v2_(ths, "SELECT addr FROM acpeerstates;"); sqlite3_stmt* stmt = dc_sqlite3_prepare_v2_(ths, "SELECT addr FROM acpeerstates;");
while( sqlite3_step(stmt) == SQLITE_ROW ) { while( sqlite3_step(stmt) == SQLITE_ROW ) {
dc_apeerstate_t* peerstate = dc_apeerstate_new(ths->m_mailbox); dc_apeerstate_t* peerstate = dc_apeerstate_new(ths->m_mailbox);
if( dc_apeerstate_load_by_addr__(peerstate, ths, (const char*)sqlite3_column_text(stmt, 0)) if( dc_apeerstate_load_by_addr__(peerstate, ths, (const char*)sqlite3_column_text(stmt, 0))
@ -458,12 +458,12 @@ int mrsqlite3_open__(mrsqlite3_t* ths, const char* dbfile, int flags)
return 1; return 1;
cleanup: cleanup:
mrsqlite3_close__(ths); dc_sqlite3_close__(ths);
return 0; return 0;
} }
void mrsqlite3_close__(mrsqlite3_t* ths) void dc_sqlite3_close__(dc_sqlite3_t* ths)
{ {
int i; int i;
@ -488,7 +488,7 @@ void mrsqlite3_close__(mrsqlite3_t* ths)
} }
int mrsqlite3_is_open(const mrsqlite3_t* ths) int dc_sqlite3_is_open(const dc_sqlite3_t* ths)
{ {
if( ths == NULL || ths->m_cobj == NULL ) { if( ths == NULL || ths->m_cobj == NULL ) {
return 0; return 0;
@ -497,7 +497,7 @@ int mrsqlite3_is_open(const mrsqlite3_t* ths)
} }
sqlite3_stmt* mrsqlite3_predefine__(mrsqlite3_t* ths, size_t idx, const char* querystr) sqlite3_stmt* dc_sqlite3_predefine__(dc_sqlite3_t* ths, size_t idx, const char* querystr)
{ {
/* Predefines a statement or resets and reuses a statement. /* Predefines a statement or resets and reuses a statement.
@ -523,7 +523,7 @@ sqlite3_stmt* mrsqlite3_predefine__(mrsqlite3_t* ths, size_t idx, const char* qu
&ths->m_pd[idx], &ths->m_pd[idx],
NULL /*tail not interesing, we use only single statements*/) != SQLITE_OK ) NULL /*tail not interesing, we use only single statements*/) != SQLITE_OK )
{ {
mrsqlite3_log_error(ths, "Preparing statement \"%s\" failed.", querystr); dc_sqlite3_log_error(ths, "Preparing statement \"%s\" failed.", querystr);
return NULL; return NULL;
} }
@ -531,7 +531,7 @@ sqlite3_stmt* mrsqlite3_predefine__(mrsqlite3_t* ths, size_t idx, const char* qu
} }
void mrsqlite3_reset_all_predefinitions(mrsqlite3_t* ths) void dc_sqlite3_reset_all_predefinitions(dc_sqlite3_t* ths)
{ {
int i; int i;
for( i = 0; i < PREDEFINED_CNT; i++ ) { for( i = 0; i < PREDEFINED_CNT; i++ ) {
@ -542,7 +542,7 @@ void mrsqlite3_reset_all_predefinitions(mrsqlite3_t* ths)
} }
int mrsqlite3_table_exists__(mrsqlite3_t* ths, const char* name) int dc_sqlite3_table_exists__(dc_sqlite3_t* ths, const char* name)
{ {
int ret = 0; int ret = 0;
char* querystr = NULL; char* querystr = NULL;
@ -550,11 +550,11 @@ int mrsqlite3_table_exists__(mrsqlite3_t* ths, const char* name)
int sqlState; int sqlState;
if( (querystr=sqlite3_mprintf("PRAGMA table_info(%s)", name)) == NULL ) { /* this statement cannot be used with binded variables */ if( (querystr=sqlite3_mprintf("PRAGMA table_info(%s)", name)) == NULL ) { /* this statement cannot be used with binded variables */
dc_log_error(ths->m_mailbox, 0, "mrsqlite3_table_exists_(): Out of memory."); dc_log_error(ths->m_mailbox, 0, "dc_sqlite3_table_exists_(): Out of memory.");
goto cleanup; goto cleanup;
} }
if( (stmt=mrsqlite3_prepare_v2_(ths, querystr)) == NULL ) { if( (stmt=dc_sqlite3_prepare_v2_(ths, querystr)) == NULL ) {
goto cleanup; goto cleanup;
} }
@ -585,18 +585,18 @@ cleanup:
******************************************************************************/ ******************************************************************************/
int mrsqlite3_set_config__(mrsqlite3_t* ths, const char* key, const char* value) int dc_sqlite3_set_config__(dc_sqlite3_t* ths, const char* key, const char* value)
{ {
int state; int state;
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
if( key == NULL ) { if( key == NULL ) {
dc_log_error(ths->m_mailbox, 0, "mrsqlite3_set_config(): Bad parameter."); dc_log_error(ths->m_mailbox, 0, "dc_sqlite3_set_config(): Bad parameter.");
return 0; return 0;
} }
if( !mrsqlite3_is_open(ths) ) { if( !dc_sqlite3_is_open(ths) ) {
dc_log_error(ths->m_mailbox, 0, "mrsqlite3_set_config(): Database not ready."); dc_log_error(ths->m_mailbox, 0, "dc_sqlite3_set_config(): Database not ready.");
return 0; return 0;
} }
@ -604,37 +604,37 @@ int mrsqlite3_set_config__(mrsqlite3_t* ths, const char* key, const char* value)
{ {
/* insert/update key=value */ /* insert/update key=value */
#define SELECT_v_FROM_config_k_STATEMENT "SELECT value FROM config WHERE keyname=?;" #define SELECT_v_FROM_config_k_STATEMENT "SELECT value FROM config WHERE keyname=?;"
stmt = mrsqlite3_predefine__(ths, SELECT_v_FROM_config_k, SELECT_v_FROM_config_k_STATEMENT); stmt = dc_sqlite3_predefine__(ths, SELECT_v_FROM_config_k, SELECT_v_FROM_config_k_STATEMENT);
sqlite3_bind_text (stmt, 1, key, -1, SQLITE_STATIC); sqlite3_bind_text (stmt, 1, key, -1, SQLITE_STATIC);
state=sqlite3_step(stmt); state=sqlite3_step(stmt);
if( state == SQLITE_DONE ) { if( state == SQLITE_DONE ) {
stmt = mrsqlite3_predefine__(ths, INSERT_INTO_config_kv, "INSERT INTO config (keyname, value) VALUES (?, ?);"); stmt = dc_sqlite3_predefine__(ths, INSERT_INTO_config_kv, "INSERT INTO config (keyname, value) VALUES (?, ?);");
sqlite3_bind_text (stmt, 1, key, -1, SQLITE_STATIC); sqlite3_bind_text (stmt, 1, key, -1, SQLITE_STATIC);
sqlite3_bind_text (stmt, 2, value, -1, SQLITE_STATIC); sqlite3_bind_text (stmt, 2, value, -1, SQLITE_STATIC);
state=sqlite3_step(stmt); state=sqlite3_step(stmt);
} }
else if( state == SQLITE_ROW ) { else if( state == SQLITE_ROW ) {
stmt = mrsqlite3_predefine__(ths, UPDATE_config_vk, "UPDATE config SET value=? WHERE keyname=?;"); stmt = dc_sqlite3_predefine__(ths, UPDATE_config_vk, "UPDATE config SET value=? WHERE keyname=?;");
sqlite3_bind_text (stmt, 1, value, -1, SQLITE_STATIC); sqlite3_bind_text (stmt, 1, value, -1, SQLITE_STATIC);
sqlite3_bind_text (stmt, 2, key, -1, SQLITE_STATIC); sqlite3_bind_text (stmt, 2, key, -1, SQLITE_STATIC);
state=sqlite3_step(stmt); state=sqlite3_step(stmt);
} }
else { else {
dc_log_error(ths->m_mailbox, 0, "mrsqlite3_set_config(): Cannot read value."); dc_log_error(ths->m_mailbox, 0, "dc_sqlite3_set_config(): Cannot read value.");
return 0; return 0;
} }
} }
else else
{ {
/* delete key */ /* delete key */
stmt = mrsqlite3_predefine__(ths, DELETE_FROM_config_k, "DELETE FROM config WHERE keyname=?;"); stmt = dc_sqlite3_predefine__(ths, DELETE_FROM_config_k, "DELETE FROM config WHERE keyname=?;");
sqlite3_bind_text (stmt, 1, key, -1, SQLITE_STATIC); sqlite3_bind_text (stmt, 1, key, -1, SQLITE_STATIC);
state=sqlite3_step(stmt); state=sqlite3_step(stmt);
} }
if( state != SQLITE_DONE ) { if( state != SQLITE_DONE ) {
dc_log_error(ths->m_mailbox, 0, "mrsqlite3_set_config(): Cannot change value."); dc_log_error(ths->m_mailbox, 0, "dc_sqlite3_set_config(): Cannot change value.");
return 0; return 0;
} }
@ -642,15 +642,15 @@ int mrsqlite3_set_config__(mrsqlite3_t* ths, const char* key, const char* value)
} }
char* mrsqlite3_get_config__(mrsqlite3_t* ths, const char* key, const char* def) /* the returned string must be free()'d, NULL is only returned if def is NULL */ char* dc_sqlite3_get_config__(dc_sqlite3_t* ths, const char* key, const char* def) /* the returned string must be free()'d, NULL is only returned if def is NULL */
{ {
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
if( !mrsqlite3_is_open(ths) || key == NULL ) { if( !dc_sqlite3_is_open(ths) || key == NULL ) {
return strdup_keep_null(def); return strdup_keep_null(def);
} }
stmt = mrsqlite3_predefine__(ths, SELECT_v_FROM_config_k, SELECT_v_FROM_config_k_STATEMENT); stmt = dc_sqlite3_predefine__(ths, SELECT_v_FROM_config_k, SELECT_v_FROM_config_k_STATEMENT);
sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC);
if( sqlite3_step(stmt) == SQLITE_ROW ) if( sqlite3_step(stmt) == SQLITE_ROW )
{ {
@ -667,9 +667,9 @@ char* mrsqlite3_get_config__(mrsqlite3_t* ths, const char* key, const char* def)
} }
int32_t mrsqlite3_get_config_int__(mrsqlite3_t* ths, const char* key, int32_t def) int32_t dc_sqlite3_get_config_int__(dc_sqlite3_t* ths, const char* key, int32_t def)
{ {
char* str = mrsqlite3_get_config__(ths, key, NULL); char* str = dc_sqlite3_get_config__(ths, key, NULL);
if( str == NULL ) { if( str == NULL ) {
return def; return def;
} }
@ -679,13 +679,13 @@ int32_t mrsqlite3_get_config_int__(mrsqlite3_t* ths, const char* key, int32_t de
} }
int mrsqlite3_set_config_int__(mrsqlite3_t* ths, const char* key, int32_t value) int dc_sqlite3_set_config_int__(dc_sqlite3_t* ths, const char* key, int32_t value)
{ {
char* value_str = mr_mprintf("%i", (int)value); char* value_str = mr_mprintf("%i", (int)value);
if( value_str == NULL ) { if( value_str == NULL ) {
return 0; return 0;
} }
int ret = mrsqlite3_set_config__(ths, key, value_str); int ret = dc_sqlite3_set_config__(ths, key, value_str);
free(value_str); free(value_str);
return ret; return ret;
} }
@ -697,9 +697,9 @@ int mrsqlite3_set_config_int__(mrsqlite3_t* ths, const char* key, int32_t value)
#ifdef MR_USE_LOCK_DEBUG #ifdef MR_USE_LOCK_DEBUG
void mrsqlite3_lockNdebug(mrsqlite3_t* ths, const char* filename, int linenum) /* wait and lock */ void dc_sqlite3_lockNdebug(dc_sqlite3_t* ths, const char* filename, int linenum) /* wait and lock */
#else #else
void mrsqlite3_lock(mrsqlite3_t* ths) /* wait and lock */ void dc_sqlite3_lock(dc_sqlite3_t* ths) /* wait and lock */
#endif #endif
{ {
#ifdef MR_USE_LOCK_DEBUG #ifdef MR_USE_LOCK_DEBUG
@ -716,9 +716,9 @@ void mrsqlite3_lock(mrsqlite3_t* ths) /* wait and lock */
#ifdef MR_USE_LOCK_DEBUG #ifdef MR_USE_LOCK_DEBUG
void mrsqlite3_unlockNdebug(mrsqlite3_t* ths, const char* filename, int linenum) void dc_sqlite3_unlockNdebug(dc_sqlite3_t* ths, const char* filename, int linenum)
#else #else
void mrsqlite3_unlock(mrsqlite3_t* ths) void dc_sqlite3_unlock(dc_sqlite3_t* ths)
#endif #endif
{ {
#ifdef MR_USE_LOCK_DEBUG #ifdef MR_USE_LOCK_DEBUG
@ -734,7 +734,7 @@ void mrsqlite3_unlock(mrsqlite3_t* ths)
******************************************************************************/ ******************************************************************************/
void mrsqlite3_begin_transaction__(mrsqlite3_t* ths) void dc_sqlite3_begin_transaction__(dc_sqlite3_t* ths)
{ {
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
@ -742,15 +742,15 @@ void mrsqlite3_begin_transaction__(mrsqlite3_t* ths)
if( ths->m_transactionCount == 1 ) if( ths->m_transactionCount == 1 )
{ {
stmt = mrsqlite3_predefine__(ths, BEGIN_transaction, "BEGIN;"); stmt = dc_sqlite3_predefine__(ths, BEGIN_transaction, "BEGIN;");
if( sqlite3_step(stmt) != SQLITE_DONE ) { if( sqlite3_step(stmt) != SQLITE_DONE ) {
mrsqlite3_log_error(ths, "Cannot begin transaction."); dc_sqlite3_log_error(ths, "Cannot begin transaction.");
} }
} }
} }
void mrsqlite3_rollback__(mrsqlite3_t* ths) void dc_sqlite3_rollback__(dc_sqlite3_t* ths)
{ {
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
@ -758,9 +758,9 @@ void mrsqlite3_rollback__(mrsqlite3_t* ths)
{ {
if( ths->m_transactionCount == 1 ) if( ths->m_transactionCount == 1 )
{ {
stmt = mrsqlite3_predefine__(ths, ROLLBACK_transaction, "ROLLBACK;"); stmt = dc_sqlite3_predefine__(ths, ROLLBACK_transaction, "ROLLBACK;");
if( sqlite3_step(stmt) != SQLITE_DONE ) { if( sqlite3_step(stmt) != SQLITE_DONE ) {
mrsqlite3_log_error(ths, "Cannot rollback transaction."); dc_sqlite3_log_error(ths, "Cannot rollback transaction.");
} }
} }
@ -769,7 +769,7 @@ void mrsqlite3_rollback__(mrsqlite3_t* ths)
} }
void mrsqlite3_commit__(mrsqlite3_t* ths) void dc_sqlite3_commit__(dc_sqlite3_t* ths)
{ {
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
@ -777,9 +777,9 @@ void mrsqlite3_commit__(mrsqlite3_t* ths)
{ {
if( ths->m_transactionCount == 1 ) if( ths->m_transactionCount == 1 )
{ {
stmt = mrsqlite3_predefine__(ths, COMMIT_transaction, "COMMIT;"); stmt = dc_sqlite3_predefine__(ths, COMMIT_transaction, "COMMIT;");
if( sqlite3_step(stmt) != SQLITE_DONE ) { if( sqlite3_step(stmt) != SQLITE_DONE ) {
mrsqlite3_log_error(ths, "Cannot commit transaction."); dc_sqlite3_log_error(ths, "Cannot commit transaction.");
} }
} }

View file

@ -155,61 +155,61 @@ enum
* database is locked as needed. Of course, the same is true if you call any * database is locked as needed. Of course, the same is true if you call any
* sqlite3-function directly. * sqlite3-function directly.
*/ */
typedef struct mrsqlite3_t typedef struct dc_sqlite3_t
{ {
/** @privatesection */ /** @privatesection */
sqlite3_stmt* m_pd[PREDEFINED_CNT]; /**< prepared statements - this is the favourite way for the caller to use SQLite */ sqlite3_stmt* m_pd[PREDEFINED_CNT]; /**< prepared statements - this is the favourite way for the caller to use SQLite */
sqlite3* m_cobj; /**< is the database given as dbfile to Open() */ sqlite3* m_cobj; /**< is the database given as dbfile to Open() */
int m_transactionCount; /**< helper for transactions */ int m_transactionCount; /**< helper for transactions */
mrmailbox_t* m_mailbox; /**< used for logging and to acquire wakelocks, there may be N mrsqlite3_t objects per mrmailbox! In practise, we use 2 on backup, 1 otherwise. */ mrmailbox_t* m_mailbox; /**< used for logging and to acquire wakelocks, there may be N dc_sqlite3_t objects per mrmailbox! In practise, we use 2 on backup, 1 otherwise. */
pthread_mutex_t m_critical_; /**< the user must make sure, only one thread uses sqlite at the same time! for this purpose, all calls must be enclosed by a locked m_critical; use mrsqlite3_lock() for this purpose */ pthread_mutex_t m_critical_; /**< the user must make sure, only one thread uses sqlite at the same time! for this purpose, all calls must be enclosed by a locked m_critical; use dc_sqlite3_lock() for this purpose */
} mrsqlite3_t; } dc_sqlite3_t;
mrsqlite3_t* mrsqlite3_new (mrmailbox_t*); dc_sqlite3_t* dc_sqlite3_new (mrmailbox_t*);
void mrsqlite3_unref (mrsqlite3_t*); void dc_sqlite3_unref (dc_sqlite3_t*);
#define MR_OPEN_READONLY 0x01 #define MR_OPEN_READONLY 0x01
int mrsqlite3_open__ (mrsqlite3_t*, const char* dbfile, int flags); int dc_sqlite3_open__ (dc_sqlite3_t*, const char* dbfile, int flags);
void mrsqlite3_close__ (mrsqlite3_t*); void dc_sqlite3_close__ (dc_sqlite3_t*);
int mrsqlite3_is_open (const mrsqlite3_t*); int dc_sqlite3_is_open (const dc_sqlite3_t*);
/* handle configurations, private */ /* handle configurations, private */
int mrsqlite3_set_config__ (mrsqlite3_t*, const char* key, const char* value); int dc_sqlite3_set_config__ (dc_sqlite3_t*, const char* key, const char* value);
int mrsqlite3_set_config_int__ (mrsqlite3_t*, const char* key, int32_t value); int dc_sqlite3_set_config_int__ (dc_sqlite3_t*, const char* key, int32_t value);
char* mrsqlite3_get_config__ (mrsqlite3_t*, const char* key, const char* def); /* the returned string must be free()'d, returns NULL on errors */ char* dc_sqlite3_get_config__ (dc_sqlite3_t*, const char* key, const char* def); /* the returned string must be free()'d, returns NULL on errors */
int32_t mrsqlite3_get_config_int__ (mrsqlite3_t*, const char* key, int32_t def); int32_t dc_sqlite3_get_config_int__ (dc_sqlite3_t*, const char* key, int32_t def);
/* tools, these functions are compatible to the corresponding sqlite3_* functions */ /* tools, these functions are compatible to the corresponding sqlite3_* functions */
sqlite3_stmt* mrsqlite3_predefine__ (mrsqlite3_t*, size_t idx, const char* sql); /*the result is resetted as needed and must not be freed. CAVE: you must not call this function with different strings for the same index!*/ sqlite3_stmt* dc_sqlite3_predefine__ (dc_sqlite3_t*, size_t idx, const char* sql); /*the result is resetted as needed and must not be freed. CAVE: you must not call this function with different strings for the same index!*/
sqlite3_stmt* mrsqlite3_prepare_v2_ (mrsqlite3_t*, const char* sql); /* the result mus be freed using sqlite3_finalize() */ sqlite3_stmt* dc_sqlite3_prepare_v2_ (dc_sqlite3_t*, const char* sql); /* the result mus be freed using sqlite3_finalize() */
int mrsqlite3_execute__ (mrsqlite3_t*, const char* sql); int dc_sqlite3_execute__ (dc_sqlite3_t*, const char* sql);
int mrsqlite3_table_exists__ (mrsqlite3_t*, const char* name); int dc_sqlite3_table_exists__ (dc_sqlite3_t*, const char* name);
void mrsqlite3_log_error (mrsqlite3_t*, const char* msg, ...); void dc_sqlite3_log_error (dc_sqlite3_t*, const char* msg, ...);
/* reset all predefined statements, this is needed only in very rare cases, eg. when dropping a table and there are pending statements */ /* reset all predefined statements, this is needed only in very rare cases, eg. when dropping a table and there are pending statements */
void mrsqlite3_reset_all_predefinitions(mrsqlite3_t*); void dc_sqlite3_reset_all_predefinitions(dc_sqlite3_t*);
/* tools for locking, may be called nested, see also m_critical_ above. /* tools for locking, may be called nested, see also m_critical_ above.
the user of MrSqlite3 must make sure that the MrSqlite3-object is only used by one thread at the same time. the user of MrSqlite3 must make sure that the MrSqlite3-object is only used by one thread at the same time.
In general, we will lock the hightest level as possible - this avoids deadlocks and massive on/off lockings. In general, we will lock the hightest level as possible - this avoids deadlocks and massive on/off lockings.
Low-level-functions, eg. the MrSqlite3-methods, do not lock. */ Low-level-functions, eg. the MrSqlite3-methods, do not lock. */
#ifdef MR_USE_LOCK_DEBUG #ifdef MR_USE_LOCK_DEBUG
#define mrsqlite3_lock(a) mrsqlite3_lockNdebug((a), __FILE__, __LINE__) #define dc_sqlite3_lock(a) dc_sqlite3_lockNdebug((a), __FILE__, __LINE__)
#define mrsqlite3_unlock(a) mrsqlite3_unlockNdebug((a), __FILE__, __LINE__) #define dc_sqlite3_unlock(a) dc_sqlite3_unlockNdebug((a), __FILE__, __LINE__)
void mrsqlite3_lockNdebug (mrsqlite3_t*, const char* filename, int line); void dc_sqlite3_lockNdebug (dc_sqlite3_t*, const char* filename, int line);
void mrsqlite3_unlockNdebug (mrsqlite3_t*, const char* filename, int line); void dc_sqlite3_unlockNdebug (dc_sqlite3_t*, const char* filename, int line);
#else #else
void mrsqlite3_lock (mrsqlite3_t*); /* lock or wait; these calls must not be nested in a single thread */ void dc_sqlite3_lock (dc_sqlite3_t*); /* lock or wait; these calls must not be nested in a single thread */
void mrsqlite3_unlock (mrsqlite3_t*); void dc_sqlite3_unlock (dc_sqlite3_t*);
#endif #endif
/* nestable transactions, only the outest is really used */ /* nestable transactions, only the outest is really used */
void mrsqlite3_begin_transaction__(mrsqlite3_t*); void dc_sqlite3_begin_transaction__(dc_sqlite3_t*);
void mrsqlite3_commit__ (mrsqlite3_t*); void dc_sqlite3_commit__ (dc_sqlite3_t*);
void mrsqlite3_rollback__ (mrsqlite3_t*); void dc_sqlite3_rollback__ (dc_sqlite3_t*);
#ifdef __cplusplus #ifdef __cplusplus
} /* /extern "C" */ } /* /extern "C" */

View file

@ -32,7 +32,7 @@ void mrtoken_save__(mrmailbox_t* mailbox, mrtokennamespc_t namespc, uint32_t for
goto cleanup; goto cleanup;
} }
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql,
"INSERT INTO tokens (namespc, foreign_id, token, timestamp) VALUES (?, ?, ?, ?);"); "INSERT INTO tokens (namespc, foreign_id, token, timestamp) VALUES (?, ?, ?, ?);");
sqlite3_bind_int (stmt, 1, (int)namespc); sqlite3_bind_int (stmt, 1, (int)namespc);
sqlite3_bind_int (stmt, 2, (int)foreign_id); sqlite3_bind_int (stmt, 2, (int)foreign_id);
@ -54,7 +54,7 @@ char* mrtoken_lookup__(mrmailbox_t* mailbox, mrtokennamespc_t namespc, uint32_t
goto cleanup; goto cleanup;
} }
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql,
"SELECT token FROM tokens WHERE namespc=? AND foreign_id=?;"); "SELECT token FROM tokens WHERE namespc=? AND foreign_id=?;");
sqlite3_bind_int (stmt, 1, (int)namespc); sqlite3_bind_int (stmt, 1, (int)namespc);
sqlite3_bind_int (stmt, 2, (int)foreign_id); sqlite3_bind_int (stmt, 2, (int)foreign_id);
@ -77,7 +77,7 @@ int mrtoken_exists__(mrmailbox_t* mailbox, mrtokennamespc_t namespc, const char*
goto cleanup; goto cleanup;
} }
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, stmt = dc_sqlite3_prepare_v2_(mailbox->m_sql,
"SELECT id FROM tokens WHERE namespc=? AND token=?;"); "SELECT id FROM tokens WHERE namespc=? AND token=?;");
sqlite3_bind_int (stmt, 1, (int)namespc); sqlite3_bind_int (stmt, 1, (int)namespc);
sqlite3_bind_text(stmt, 2, token, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 2, token, -1, SQLITE_STATIC);

View file

@ -894,7 +894,7 @@ char* mr_create_outgoing_rfc724_mid(const char* grpid, const char* from_addr)
} }
char* mr_create_incoming_rfc724_mid(time_t message_timestamp, uint32_t contact_id_from, mrarray_t* contact_ids_to) char* mr_create_incoming_rfc724_mid(time_t message_timestamp, uint32_t contact_id_from, dc_array_t* contact_ids_to)
{ {
/* Function generates a Message-ID for incoming messages that lacks one. /* Function generates a Message-ID for incoming messages that lacks one.
- normally, this function is not needed as incoming messages already have an ID - normally, this function is not needed as incoming messages already have an ID
@ -902,15 +902,15 @@ char* mr_create_incoming_rfc724_mid(time_t message_timestamp, uint32_t contact_i
- when fetching the same message again, this function should generate the same Message-ID - when fetching the same message again, this function should generate the same Message-ID
*/ */
if( message_timestamp == MR_INVALID_TIMESTAMP || contact_ids_to == NULL || mrarray_get_cnt(contact_ids_to)==0 ) { if( message_timestamp == MR_INVALID_TIMESTAMP || contact_ids_to == NULL || dc_array_get_cnt(contact_ids_to)==0 ) {
return NULL; return NULL;
} }
/* find out the largest receiver ID (we could also take the smallest, but it should be unique) */ /* find out the largest receiver ID (we could also take the smallest, but it should be unique) */
size_t i, icnt = mrarray_get_cnt(contact_ids_to); size_t i, icnt = dc_array_get_cnt(contact_ids_to);
uint32_t largest_id_to = 0; uint32_t largest_id_to = 0;
for( i = 0; i < icnt; i++ ) { for( i = 0; i < icnt; i++ ) {
uint32_t cur_id = mrarray_get_id(contact_ids_to, i); uint32_t cur_id = dc_array_get_id(contact_ids_to, i);
if( cur_id > largest_id_to ) { if( cur_id > largest_id_to ) {
largest_id_to = cur_id; largest_id_to = cur_id;
} }

View file

@ -87,7 +87,7 @@ time_t mr_create_smeared_timestamps__(int count);
#define MR_CREATE_ID_LEN 11 #define MR_CREATE_ID_LEN 11
char* mr_create_id (void); char* mr_create_id (void);
char* mr_create_dummy_references_mid (void); char* mr_create_dummy_references_mid (void);
char* mr_create_incoming_rfc724_mid (time_t message_timestamp, uint32_t contact_id_from, mrarray_t* contact_ids_to); char* mr_create_incoming_rfc724_mid (time_t message_timestamp, uint32_t contact_id_from, dc_array_t* contact_ids_to);
char* mr_create_outgoing_rfc724_mid (const char* grpid, const char* addr); char* mr_create_outgoing_rfc724_mid (const char* grpid, const char* addr);
char* mr_extract_grpid_from_rfc724_mid (const char* rfc724_mid); char* mr_extract_grpid_from_rfc724_mid (const char* rfc724_mid);
char* mr_extract_grpid_from_rfc724_mid_list(const clist* rfc724_mid_list); char* mr_extract_grpid_from_rfc724_mid_list(const clist* rfc724_mid_list);