mirror of
https://github.com/chatmail/core.git
synced 2026-05-19 23:06:32 +03:00
fix various bugs
This commit is contained in:
153
src/dc_chat.rs
153
src/dc_chat.rs
@@ -113,71 +113,79 @@ pub fn dc_chat_load_from_db(chat: *mut Chat, chat_id: u32) -> bool {
|
|||||||
if chat.is_null() || unsafe { (*chat).magic != 0xc4a7c4a7u32 } {
|
if chat.is_null() || unsafe { (*chat).magic != 0xc4a7c4a7u32 } {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe { dc_chat_empty(chat) };
|
unsafe { dc_chat_empty(chat) };
|
||||||
|
|
||||||
let context = unsafe { (*chat).context };
|
let context = unsafe { (*chat).context };
|
||||||
|
info!(context, 0, "loading chat {}", chat_id);
|
||||||
|
|
||||||
context
|
let res = context.sql.query_row(
|
||||||
.sql
|
"SELECT c.id,c.type,c.name, c.grpid,c.param,c.archived, \
|
||||||
.query_row(
|
c.blocked, c.gossiped_timestamp, c.locations_send_until \
|
||||||
"SELECT c.id,c.type,c.name, c.grpid,c.param,c.archived, \
|
FROM chats c WHERE c.id=?;",
|
||||||
c.blocked, c.gossiped_timestamp, c.locations_send_until \
|
params![chat_id as i32],
|
||||||
FROM chats c WHERE c.id=?;",
|
|row| {
|
||||||
params![chat_id as i32],
|
let c = unsafe { &mut *chat };
|
||||||
|row| {
|
|
||||||
let c = unsafe { &mut *chat };
|
|
||||||
|
|
||||||
c.id = row.get(0)?;
|
c.id = row.get(0)?;
|
||||||
c.type_0 = row.get(1)?;
|
c.type_0 = row.get(1)?;
|
||||||
c.name = {
|
c.name = {
|
||||||
let raw: String = row.get(2)?;
|
let raw: String = row.get(2)?;
|
||||||
unsafe { strdup(to_cstring(raw).as_ptr()) }
|
unsafe { strdup(to_cstring(raw).as_ptr()) }
|
||||||
};
|
};
|
||||||
c.grpid = {
|
c.grpid = {
|
||||||
let raw: String = row.get(3)?;
|
let raw: String = row.get(3)?;
|
||||||
unsafe { strdup(to_cstring(raw).as_ptr()) }
|
unsafe { strdup(to_cstring(raw).as_ptr()) }
|
||||||
};
|
};
|
||||||
|
|
||||||
let packed: String = row.get(4)?;
|
let packed: String = row.get(4)?;
|
||||||
unsafe { dc_param_set_packed((*chat).param, to_cstring(&packed).as_ptr()) };
|
unsafe { dc_param_set_packed((*chat).param, to_cstring(&packed).as_ptr()) };
|
||||||
c.archived = row.get(5)?;
|
c.archived = row.get(5)?;
|
||||||
c.blocked = row.get(6)?;
|
c.blocked = row.get(6)?;
|
||||||
c.gossiped_timestamp = row.get(7)?;
|
c.gossiped_timestamp = row.get(7)?;
|
||||||
c.is_sending_locations = row.get(8)?;
|
c.is_sending_locations = row.get(8)?;
|
||||||
|
|
||||||
match c.id {
|
match c.id {
|
||||||
1 => unsafe {
|
1 => unsafe {
|
||||||
free((*chat).name as *mut libc::c_void);
|
free((*chat).name as *mut libc::c_void);
|
||||||
(*chat).name = dc_stock_str((*chat).context, 8);
|
(*chat).name = dc_stock_str((*chat).context, 8);
|
||||||
},
|
},
|
||||||
6 => unsafe {
|
6 => unsafe {
|
||||||
free((*chat).name as *mut libc::c_void);
|
free((*chat).name as *mut libc::c_void);
|
||||||
let tempname: *mut libc::c_char = dc_stock_str((*chat).context, 40);
|
let tempname: *mut libc::c_char = dc_stock_str((*chat).context, 40);
|
||||||
(*chat).name = dc_mprintf(
|
(*chat).name = dc_mprintf(
|
||||||
b"%s (%i)\x00" as *const u8 as *const libc::c_char,
|
b"%s (%i)\x00" as *const u8 as *const libc::c_char,
|
||||||
tempname,
|
tempname,
|
||||||
dc_get_archived_cnt((*chat).context),
|
dc_get_archived_cnt((*chat).context),
|
||||||
);
|
);
|
||||||
free(tempname as *mut libc::c_void);
|
free(tempname as *mut libc::c_void);
|
||||||
},
|
},
|
||||||
5 => unsafe {
|
5 => unsafe {
|
||||||
free((*chat).name as *mut libc::c_void);
|
free((*chat).name as *mut libc::c_void);
|
||||||
(*chat).name = dc_stock_str((*chat).context, 41);
|
(*chat).name = dc_stock_str((*chat).context, 41);
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
if 0 != unsafe { dc_param_exists((*chat).param, 'K' as i32) } {
|
if 0 != unsafe { dc_param_exists((*chat).param, 'K' as i32) } {
|
||||||
unsafe {
|
unsafe {
|
||||||
free((*chat).name as *mut libc::c_void);
|
free((*chat).name as *mut libc::c_void);
|
||||||
(*chat).name = dc_stock_str((*chat).context, 2);
|
(*chat).name = dc_stock_str((*chat).context, 2);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
}
|
||||||
},
|
Ok(())
|
||||||
)
|
},
|
||||||
.is_ok()
|
);
|
||||||
|
|
||||||
|
match res {
|
||||||
|
Ok(_) => true,
|
||||||
|
Err(err) => {
|
||||||
|
error!(
|
||||||
|
context,
|
||||||
|
0, "chat: failed to load from db {}: {:?}", chat_id, err
|
||||||
|
);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_create_chat_by_contact_id(context: &Context, contact_id: uint32_t) -> uint32_t {
|
pub unsafe fn dc_create_chat_by_contact_id(context: &Context, contact_id: uint32_t) -> uint32_t {
|
||||||
@@ -696,6 +704,7 @@ unsafe fn prepare_msg_raw(
|
|||||||
"rfc724_mid",
|
"rfc724_mid",
|
||||||
as_str(new_rfc724_mid),
|
as_str(new_rfc724_mid),
|
||||||
);
|
);
|
||||||
|
info!(context, 0, "got msg_id {}", msg_id);
|
||||||
} else {
|
} else {
|
||||||
error!(
|
error!(
|
||||||
context,
|
context,
|
||||||
@@ -858,20 +867,21 @@ pub unsafe fn dc_send_msg<'a>(
|
|||||||
msg: *mut dc_msg_t<'a>,
|
msg: *mut dc_msg_t<'a>,
|
||||||
) -> uint32_t {
|
) -> uint32_t {
|
||||||
if msg.is_null() {
|
if msg.is_null() {
|
||||||
return 0i32 as uint32_t;
|
return 0;
|
||||||
}
|
}
|
||||||
if (*msg).state != 18i32 {
|
|
||||||
|
if (*msg).state != 18 {
|
||||||
if 0 == prepare_msg_common(context, chat_id, msg) {
|
if 0 == prepare_msg_common(context, chat_id, msg) {
|
||||||
return 0i32 as uint32_t;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if chat_id != 0i32 as libc::c_uint && chat_id != (*msg).chat_id {
|
if chat_id != 0 && chat_id != (*msg).chat_id {
|
||||||
return 0i32 as uint32_t;
|
return 0;
|
||||||
}
|
}
|
||||||
dc_update_msg_state(context, (*msg).id, 20i32);
|
dc_update_msg_state(context, (*msg).id, 20);
|
||||||
}
|
}
|
||||||
if 0 == dc_job_send_msg(context, (*msg).id) {
|
if 0 == dc_job_send_msg(context, (*msg).id) {
|
||||||
return 0i32 as uint32_t;
|
return 0;
|
||||||
}
|
}
|
||||||
context.call_cb(
|
context.call_cb(
|
||||||
Event::MSGS_CHANGED,
|
Event::MSGS_CHANGED,
|
||||||
@@ -884,19 +894,18 @@ pub unsafe fn dc_send_msg<'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if 0 == chat_id {
|
if 0 == chat_id {
|
||||||
let forwards: *mut libc::c_char =
|
let forwards = dc_param_get((*msg).param, 'P' as i32, 0 as *const libc::c_char);
|
||||||
dc_param_get((*msg).param, 'P' as i32, 0 as *const libc::c_char);
|
|
||||||
if !forwards.is_null() {
|
if !forwards.is_null() {
|
||||||
let mut p: *mut libc::c_char = forwards;
|
let mut p = forwards;
|
||||||
while 0 != *p {
|
while 0 != *p {
|
||||||
let id: int32_t = strtol(p, &mut p, 10i32) as int32_t;
|
let id = strtol(p, &mut p, 10) as int32_t;
|
||||||
if 0 == id {
|
if 0 == id {
|
||||||
// avoid hanging if user tampers with db
|
// avoid hanging if user tampers with db
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
let copy: *mut dc_msg_t = dc_get_msg(context, id as uint32_t);
|
let copy = dc_get_msg(context, id as uint32_t);
|
||||||
if !copy.is_null() {
|
if !copy.is_null() {
|
||||||
dc_send_msg(context, 0i32 as uint32_t, copy);
|
dc_send_msg(context, 0 as uint32_t, copy);
|
||||||
}
|
}
|
||||||
dc_msg_unref(copy);
|
dc_msg_unref(copy);
|
||||||
}
|
}
|
||||||
@@ -915,11 +924,11 @@ pub unsafe fn dc_send_text_msg(
|
|||||||
chat_id: uint32_t,
|
chat_id: uint32_t,
|
||||||
text_to_send: *const libc::c_char,
|
text_to_send: *const libc::c_char,
|
||||||
) -> uint32_t {
|
) -> uint32_t {
|
||||||
let mut msg: *mut dc_msg_t = dc_msg_new(context, 10i32);
|
let mut msg = dc_msg_new(context, 10);
|
||||||
let mut ret: uint32_t = 0i32 as uint32_t;
|
let mut ret = 0;
|
||||||
if !(chat_id <= 9i32 as libc::c_uint || text_to_send.is_null()) {
|
if !(chat_id <= 9 || text_to_send.is_null()) {
|
||||||
(*msg).text = dc_strdup(text_to_send);
|
(*msg).text = dc_strdup(text_to_send);
|
||||||
ret = dc_send_msg(context, chat_id, msg)
|
ret = dc_send_msg(context, chat_id, msg);
|
||||||
}
|
}
|
||||||
dc_msg_unref(msg);
|
dc_msg_unref(msg);
|
||||||
ret
|
ret
|
||||||
|
|||||||
@@ -135,14 +135,20 @@ unsafe fn dc_chatlist_load_from_db(
|
|||||||
// for the deaddrop, however, they should really be hidden, however, _currently_ the deaddrop is not
|
// for the deaddrop, however, they should really be hidden, however, _currently_ the deaddrop is not
|
||||||
// shown at all permanent in the chatlist.
|
// shown at all permanent in the chatlist.
|
||||||
|
|
||||||
let process_row = |row: &rusqlite::Row| Ok((row.get(0)?, row.get(1)?));
|
let process_row = |row: &rusqlite::Row| {
|
||||||
|
let chat_id: i32 = row.get(0)?;
|
||||||
|
// TODO: verify that it is okay for this to be Null
|
||||||
|
let msg_id: i32 = row.get(1).unwrap_or_default();
|
||||||
|
|
||||||
|
Ok((chat_id, msg_id))
|
||||||
|
};
|
||||||
|
|
||||||
let process_rows = |rows: rusqlite::MappedRows<_>| {
|
let process_rows = |rows: rusqlite::MappedRows<_>| {
|
||||||
for row in rows {
|
for row in rows {
|
||||||
let (id1, id2) = row?;
|
let (id1, id2) = row?;
|
||||||
|
|
||||||
dc_array_add_id((*chatlist).chatNlastmsg_ids, id1);
|
dc_array_add_id((*chatlist).chatNlastmsg_ids, id1 as u32);
|
||||||
dc_array_add_id((*chatlist).chatNlastmsg_ids, id2);
|
dc_array_add_id((*chatlist).chatNlastmsg_ids, id2 as u32);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
@@ -228,11 +234,11 @@ unsafe fn dc_chatlist_load_from_db(
|
|||||||
|
|
||||||
if 0 != add_archived_link_item && dc_get_archived_cnt((*chatlist).context) > 0 {
|
if 0 != add_archived_link_item && dc_get_archived_cnt((*chatlist).context) > 0 {
|
||||||
if dc_array_get_cnt((*chatlist).chatNlastmsg_ids) == 0 && 0 != listflags & 0x4 {
|
if dc_array_get_cnt((*chatlist).chatNlastmsg_ids) == 0 && 0 != listflags & 0x4 {
|
||||||
dc_array_add_id((*chatlist).chatNlastmsg_ids, 7 as uint32_t);
|
dc_array_add_id((*chatlist).chatNlastmsg_ids, 7);
|
||||||
dc_array_add_id((*chatlist).chatNlastmsg_ids, 0 as uint32_t);
|
dc_array_add_id((*chatlist).chatNlastmsg_ids, 0);
|
||||||
}
|
}
|
||||||
dc_array_add_id((*chatlist).chatNlastmsg_ids, 6 as uint32_t);
|
dc_array_add_id((*chatlist).chatNlastmsg_ids, 6);
|
||||||
dc_array_add_id((*chatlist).chatNlastmsg_ids, 0 as uint32_t);
|
dc_array_add_id((*chatlist).chatNlastmsg_ids, 0);
|
||||||
}
|
}
|
||||||
(*chatlist).cnt = dc_array_get_cnt((*chatlist).chatNlastmsg_ids) / 2;
|
(*chatlist).cnt = dc_array_get_cnt((*chatlist).chatNlastmsg_ids) / 2;
|
||||||
|
|
||||||
|
|||||||
@@ -1095,7 +1095,7 @@ pub fn dc_job_action_exists(context: &Context, action: libc::c_int) -> bool {
|
|||||||
|
|
||||||
/* special case for DC_JOB_SEND_MSG_TO_SMTP */
|
/* special case for DC_JOB_SEND_MSG_TO_SMTP */
|
||||||
pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_int {
|
pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_int {
|
||||||
let mut success: libc::c_int = 0i32;
|
let mut success = 0;
|
||||||
let mut mimefactory = dc_mimefactory_t {
|
let mut mimefactory = dc_mimefactory_t {
|
||||||
from_addr: 0 as *mut libc::c_char,
|
from_addr: 0 as *mut libc::c_char,
|
||||||
from_displayname: 0 as *mut libc::c_char,
|
from_displayname: 0 as *mut libc::c_char,
|
||||||
@@ -1232,9 +1232,10 @@ pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_in
|
|||||||
0 as *const libc::c_char,
|
0 as *const libc::c_char,
|
||||||
0 as *const libc::c_char,
|
0 as *const libc::c_char,
|
||||||
);
|
);
|
||||||
success = dc_add_smtp_job(context, 5901i32, &mut mimefactory)
|
success = dc_add_smtp_job(context, 5901i32, &mut mimefactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dc_mimefactory_empty(&mut mimefactory);
|
dc_mimefactory_empty(&mut mimefactory);
|
||||||
return success;
|
|
||||||
|
success
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ pub unsafe fn dc_mimefactory_load_msg(
|
|||||||
msg_id: uint32_t,
|
msg_id: uint32_t,
|
||||||
) -> libc::c_int {
|
) -> libc::c_int {
|
||||||
if factory.is_null() || msg_id <= 9 || !(*factory).msg.is_null() {
|
if factory.is_null() || msg_id <= 9 || !(*factory).msg.is_null() {
|
||||||
|
info!((*factory).context, 0, "mimefactory: null");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,9 +126,12 @@ pub unsafe fn dc_mimefactory_load_msg(
|
|||||||
if dc_msg_load_from_db((*factory).msg, context, msg_id)
|
if dc_msg_load_from_db((*factory).msg, context, msg_id)
|
||||||
&& dc_chat_load_from_db((*factory).chat, (*(*factory).msg).chat_id)
|
&& dc_chat_load_from_db((*factory).chat, (*(*factory).msg).chat_id)
|
||||||
{
|
{
|
||||||
|
info!(context, 0, "mimefactory: loaded msg and chat",);
|
||||||
load_from(factory);
|
load_from(factory);
|
||||||
(*factory).req_mdn = 0;
|
(*factory).req_mdn = 0;
|
||||||
if 0 != dc_chat_is_self_talk((*factory).chat) {
|
if 0 != dc_chat_is_self_talk((*factory).chat) {
|
||||||
|
info!(context, 0, "mimefactory: selftalk");
|
||||||
|
|
||||||
clist_insert_after(
|
clist_insert_after(
|
||||||
(*factory).recipients_names,
|
(*factory).recipients_names,
|
||||||
(*(*factory).recipients_names).last,
|
(*(*factory).recipients_names).last,
|
||||||
@@ -139,6 +143,7 @@ pub unsafe fn dc_mimefactory_load_msg(
|
|||||||
dc_strdup((*factory).from_addr) as *mut libc::c_void,
|
dc_strdup((*factory).from_addr) as *mut libc::c_void,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
info!(context, 0, "mimefactory: query map");
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.query_map(
|
.query_map(
|
||||||
@@ -153,6 +158,7 @@ pub unsafe fn dc_mimefactory_load_msg(
|
|||||||
Ok((authname, addr))
|
Ok((authname, addr))
|
||||||
},
|
},
|
||||||
|rows| {
|
|rows| {
|
||||||
|
info!(context, 0, "mimefactory: processing rows");
|
||||||
for row in rows {
|
for row in rows {
|
||||||
let (authname, addr) = row?;
|
let (authname, addr) = row?;
|
||||||
let addr_c = to_cstring(addr);
|
let addr_c = to_cstring(addr);
|
||||||
@@ -217,6 +223,7 @@ pub unsafe fn dc_mimefactory_load_msg(
|
|||||||
(*factory).req_mdn = 1
|
(*factory).req_mdn = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
info!(context, 0, "mimefactory: loading in reply to");
|
||||||
|
|
||||||
let row = context.sql.query_row(
|
let row = context.sql.query_row(
|
||||||
"SELECT mime_in_reply_to, mime_references FROM msgs WHERE id=?",
|
"SELECT mime_in_reply_to, mime_references FROM msgs WHERE id=?",
|
||||||
@@ -228,9 +235,17 @@ pub unsafe fn dc_mimefactory_load_msg(
|
|||||||
Ok((in_reply_to, references))
|
Ok((in_reply_to, references))
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if let Ok((in_reply_to, references)) = row {
|
match row {
|
||||||
(*factory).in_reply_to = dc_strdup(to_cstring(in_reply_to).as_ptr());
|
Ok((in_reply_to, references)) => {
|
||||||
(*factory).references = dc_strdup(to_cstring(references).as_ptr());
|
(*factory).in_reply_to = dc_strdup(to_cstring(in_reply_to).as_ptr());
|
||||||
|
(*factory).references = dc_strdup(to_cstring(references).as_ptr());
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
error!(
|
||||||
|
context,
|
||||||
|
0, "mimefactory: failed to load mime_in_reply_to: {:?}", err
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
success = 1;
|
success = 1;
|
||||||
|
|||||||
@@ -432,7 +432,7 @@ pub fn dc_msg_load_from_db<'a>(msg: *mut dc_msg_t<'a>, context: &'a Context, id:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.sql.query_row(
|
let res = context.sql.query_row(
|
||||||
"SELECT \
|
"SELECT \
|
||||||
m.id,rfc724_mid,m.mime_in_reply_to,m.server_folder,m.server_uid,m.move_state,m.chat_id, \
|
m.id,rfc724_mid,m.mime_in_reply_to,m.server_folder,m.server_uid,m.move_state,m.chat_id, \
|
||||||
m.from_id,m.to_id,m.timestamp,m.timestamp_sent,m.timestamp_rcvd, m.type,m.state,m.msgrmsg,m.txt, \
|
m.from_id,m.to_id,m.timestamp,m.timestamp_sent,m.timestamp_rcvd, m.type,m.state,m.msgrmsg,m.txt, \
|
||||||
@@ -460,7 +460,7 @@ pub fn dc_msg_load_from_db<'a>(msg: *mut dc_msg_t<'a>, context: &'a Context, id:
|
|||||||
(*msg).type_0 = row.get(12)?;
|
(*msg).type_0 = row.get(12)?;
|
||||||
(*msg).state = row.get(13)?;
|
(*msg).state = row.get(13)?;
|
||||||
(*msg).is_dc_message = row.get(14)?;
|
(*msg).is_dc_message = row.get(14)?;
|
||||||
(*msg).text = dc_strdup(to_cstring(row.get::<_, String>(15)?).as_ptr());
|
(*msg).text = dc_strdup(to_cstring(row.get::<_, String>(15).unwrap_or_default()).as_ptr());
|
||||||
dc_param_set_packed(
|
dc_param_set_packed(
|
||||||
(*msg).param,
|
(*msg).param,
|
||||||
to_cstring(row.get::<_, String>(16)?).as_ptr()
|
to_cstring(row.get::<_, String>(16)?).as_ptr()
|
||||||
@@ -475,7 +475,15 @@ pub fn dc_msg_load_from_db<'a>(msg: *mut dc_msg_t<'a>, context: &'a Context, id:
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
).is_ok()
|
);
|
||||||
|
|
||||||
|
match res {
|
||||||
|
Ok(_) => true,
|
||||||
|
Err(err) => {
|
||||||
|
error!(context, 0, "msg: load from db failed: {:?}", err);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_get_mime_headers(context: &Context, msg_id: uint32_t) -> *mut libc::c_char {
|
pub unsafe fn dc_get_mime_headers(context: &Context, msg_id: uint32_t) -> *mut libc::c_char {
|
||||||
|
|||||||
Reference in New Issue
Block a user