Skip to content

Commit a8f06ae

Browse files
committed
midb: synchronize Answered & Forwarded flag between MAPI and IMAP
References: DESK-2269, DESK-2501, GXL-519
1 parent 9df775f commit a8f06ae

File tree

2 files changed

+56
-18
lines changed

2 files changed

+56
-18
lines changed

exch/midb/mail_engine.cpp

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ struct syncmessage_entry {
102102
uint64_t mod_time = 0, recv_time = 0;
103103
uint32_t msg_flags = 0;
104104
std::string midstr;
105-
bool flagged = false;
105+
bool answered = false, forwarded = false, flagged = false;
106106
};
107107

108108
using syncfolder_list = std::unordered_map<uint64_t /* folder_id */, syncfolder_entry>;
@@ -1483,8 +1483,12 @@ static void me_insert_message(xstmt &stm_insert, uint32_t *puidnext,
14831483
stm_insert.bind_int64(11, e.recv_time);
14841484
if (stm_insert.step() != SQLITE_DONE)
14851485
mlog(LV_ERR, "E-2075: sqlite_step not finished");
1486-
auto qstr = "UPDATE messages SET flagged=" + std::to_string(e.flagged) +
1487-
" WHERE message_id=" + std::to_string(message_id);
1486+
auto qstr = "UPDATE messages SET flagged=" + std::to_string(e.flagged);
1487+
if (e.answered)
1488+
qstr += ", replied=1";
1489+
if (e.forwarded)
1490+
qstr += ", forwarded=1";
1491+
qstr += " WHERE message_id=" + std::to_string(message_id);
14881492
gx_sql_exec(db, qstr.c_str());
14891493
} catch (const std::bad_alloc &) {
14901494
mlog(LV_ERR, "E-1137: ENOMEM");
@@ -1539,6 +1543,7 @@ static BOOL me_sync_contents(IDB_ITEM *pidb, uint64_t folder_id) try
15391543
static constexpr uint32_t proptags_0[] = {
15401544
PidTagMid, PR_MESSAGE_FLAGS, PR_LAST_MODIFICATION_TIME,
15411545
PR_MESSAGE_DELIVERY_TIME, PidTagMidString, PR_FLAG_STATUS,
1546+
PR_ICON_INDEX,
15421547
};
15431548
static constexpr PROPTAG_ARRAY proptags_1 = {std::size(proptags_0), deconst(proptags_0)};
15441549
if (!exmdb_client::query_table(dir, nullptr, CP_ACP, table_id,
@@ -1573,10 +1578,13 @@ static BOOL me_sync_contents(IDB_ITEM *pidb, uint64_t folder_id) try
15731578
auto midstr = rows.pparray[i]->get<const char>(PidTagMidString);
15741579
auto num = rows.pparray[i]->get<const uint32_t>(PR_FLAG_STATUS);
15751580
bool flagged = num != nullptr && *num == followupFlagged;
1581+
num = rows.pparray[i]->get<const uint32_t>(PR_ICON_INDEX);
1582+
bool answered = num != nullptr && *num == MAIL_ICON_REPLIED;
1583+
bool forwarded = num != nullptr && *num == MAIL_ICON_FORWARDED;
15761584
syncmessagelist.emplace(message_id, syncmessage_entry{
15771585
mod_time != nullptr ? *mod_time : 0,
15781586
recv_time != nullptr ? *recv_time : 0,
1579-
*flags, znul(midstr), flagged});
1587+
*flags, znul(midstr), answered, forwarded, flagged});
15801588
}
15811589

15821590
size_t totalmsgs = syncmessagelist.size(), procmsgs = 0;
@@ -3176,6 +3184,15 @@ static int me_psflg(int argc, char **argv, int sockd) try
31763184
return MIDB_E_MDB_SETMSGPROPS;
31773185
}
31783186
}
3187+
if (set_answered || set_forwarded) {
3188+
const uint32_t val = set_answered ? MAIL_ICON_REPLIED : MAIL_ICON_FORWARDED;
3189+
const TAGGED_PROPVAL tp[] = {{PR_ICON_INDEX, deconst(&val)}};
3190+
const TPROPVAL_ARRAY ta = {std::size(tp), deconst(tp)};
3191+
if (!exmdb_client::set_message_properties(argv[1],
3192+
nullptr, CP_ACP, rop_util_make_eid_ex(1, message_id),
3193+
&ta, &problems))
3194+
return MIDB_E_MDB_SETMSGPROPS;
3195+
}
31793196
if (set_flagged) {
31803197
static constexpr uint32_t val = followupFlagged, icon = olRedFlagIcon;
31813198
static constexpr TAGGED_PROPVAL tp[] = {
@@ -3269,6 +3286,21 @@ static int me_prflg(int argc, char **argv, int sockd) try
32693286
return MIDB_E_MDB_SETMSGPROPS;
32703287
}
32713288
}
3289+
if (set_answered || set_forwarded) {
3290+
static constexpr proptag_t proptags_1[] = {PR_ICON_INDEX};
3291+
static constexpr PROPTAG_ARRAY proptags = {std::size(proptags_1), deconst(proptags_1)};
3292+
TPROPVAL_ARRAY propvals{};
3293+
if (exmdb_client::get_message_properties(argv[1], nullptr,
3294+
CP_ACP, rop_util_make_eid_ex(1, message_id),
3295+
&proptags, &propvals)) {
3296+
uint32_t testfor = set_answered ? MAIL_ICON_REPLIED : MAIL_ICON_FORWARDED;
3297+
auto icon = propvals.get<const uint32_t>(PR_ICON_INDEX);
3298+
if (icon != nullptr && *icon == testfor)
3299+
if (!exmdb_client::remove_message_properties(argv[1], CP_ACP,
3300+
rop_util_make_eid_ex(1, message_id), &proptags))
3301+
/* ignore */;
3302+
}
3303+
}
32723304
if (set_flagged) {
32733305
static constexpr proptag_t tags[] = {
32743306
PR_FLAG_STATUS, PR_FOLLOWUP_ICON, PR_TODO_ITEM_FLAGS,
@@ -3575,6 +3607,9 @@ static void notif_msg_added(IDB_ITEM *pidb,
35753607
auto message_flags = num != nullptr ? *num : 0;
35763608
num = propvals.get<const uint32_t>(PR_FLAG_STATUS);
35773609
bool b_flagged = num != nullptr && *num == followupFlagged;
3610+
num = propvals.get<const uint32_t>(PR_ICON_INDEX);
3611+
bool set_answered = num != nullptr && *num == MAIL_ICON_REPLIED;
3612+
bool set_forwarded = num != nullptr && *num == MAIL_ICON_FORWARDED;
35783613

35793614
std::string flags_buff;
35803615
char mid_string[128];
@@ -3618,18 +3653,8 @@ static void notif_msg_added(IDB_ITEM *pidb,
36183653
return;
36193654
me_insert_message(pstmt, &uidnext, message_id, pidb->psqlite,
36203655
syncmessage_entry{mod_time, received_time, message_flags,
3621-
znul(str), b_flagged});
3656+
znul(str), set_answered, set_forwarded, b_flagged});
36223657
pstmt.finalize();
3623-
if (flags_buff.find(midb_flag::answered) != flags_buff.npos) {
3624-
qstr = fmt::format("UPDATE messages SET "
3625-
"replied=1 WHERE message_id={}", message_id);
3626-
gx_sql_exec(pidb->psqlite, qstr.c_str());
3627-
}
3628-
if (flags_buff.find(midb_flag::forwarded) != flags_buff.npos) {
3629-
qstr = fmt::format("UPDATE messages SET "
3630-
"forwarded=1 WHERE message_id={}", message_id);
3631-
gx_sql_exec(pidb->psqlite, qstr.c_str());
3632-
}
36333658
} catch (const std::bad_alloc &) {
36343659
mlog(LV_ERR, "E-2418: ENOMEM");
36353660
}
@@ -3878,7 +3903,7 @@ static void notif_msg_modified(IDB_ITEM *pidb,
38783903
TPROPVAL_ARRAY propvals;
38793904
static constexpr proptag_t tmp_proptags[] = {
38803905
PR_MESSAGE_FLAGS, PR_LAST_MODIFICATION_TIME, PidTagMidString,
3881-
PR_FLAG_STATUS,
3906+
PR_FLAG_STATUS, PR_ICON_INDEX,
38823907
};
38833908
static constexpr PROPTAG_ARRAY proptags = {std::size(tmp_proptags), deconst(tmp_proptags)};
38843909
if (!exmdb_client::get_message_properties(cu_get_maildir(),
@@ -3889,13 +3914,21 @@ static void notif_msg_modified(IDB_ITEM *pidb,
38893914
auto message_flags = num != nullptr ? *num : 0;
38903915
num = propvals.get<const uint32_t>(PR_FLAG_STATUS);
38913916
bool b_flagged = num != nullptr && *num == followupFlagged;
3917+
num = propvals.get<const uint32_t>(PR_ICON_INDEX);
3918+
bool set_answered = num != nullptr && *num == MAIL_ICON_REPLIED;
3919+
bool set_forwarded = num != nullptr && *num == MAIL_ICON_FORWARDED;
38923920
auto str = propvals.get<const char>(PidTagMidString);
38933921
if (str != nullptr) {
38943922
UPDATE_MESSAGE_FLAGS:
38953923
auto b_unsent = !!(message_flags & MSGFLAG_UNSENT);
38963924
auto b_read = !!(message_flags & MSGFLAG_READ);
3897-
auto qstr = fmt::format("UPDATE messages SET read={}, unsent={}, flagged={}"
3898-
" WHERE message_id={}", b_read, b_unsent, b_flagged, message_id);
3925+
auto qstr = fmt::format("UPDATE messages SET read={}, unsent={}, flagged={}",
3926+
b_read, b_unsent, b_flagged);
3927+
if (set_answered)
3928+
qstr += ", replied=1";
3929+
if (set_forwarded)
3930+
qstr += ", forwarded=1";
3931+
qstr += " WHERE message_id=" + std::to_string(message_id);
38993932
gx_sql_exec(pidb->psqlite, qstr.c_str());
39003933
return;
39013934
}

include/gromox/mapidefs.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,11 @@ enum { /* for PR_FOLLOWUP_ICON */
318318
olRedFlagIcon,
319319
};
320320

321+
enum { /* for PR_ICON_INDEX */
322+
MAIL_ICON_REPLIED = 0x105,
323+
MAIL_ICON_FORWARDED = 0x106,
324+
};
325+
321326
enum mapi_importance {
322327
IMPORTANCE_LOW = 0,
323328
IMPORTANCE_NORMAL = 1,

0 commit comments

Comments
 (0)