Skip to content

Commit 9c01fc2

Browse files
committed
midb: synchronize \Flagged between MAPI and IMAP
References: GXH-122
1 parent b76ebf8 commit 9c01fc2

File tree

4 files changed

+58
-15
lines changed

4 files changed

+58
-15
lines changed

exch/midb/mail_engine.cpp

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +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;
105106
};
106107

107108
using syncfolder_list = std::unordered_map<uint64_t /* folder_id */, syncfolder_entry>;
@@ -1479,6 +1480,7 @@ static void me_insert_message(xstmt &stm_insert, uint32_t *puidnext,
14791480
stm_insert.bind_text(9, rcpt);
14801481
stm_insert.bind_int64(10, size);
14811482
stm_insert.bind_int64(11, e.recv_time);
1483+
stm_insert.bind_int64(12, e.flagged);
14821484
if (stm_insert.step() != SQLITE_DONE)
14831485
mlog(LV_ERR, "E-2075: sqlite_step not finished");
14841486
} catch (const std::bad_alloc &) {
@@ -1533,7 +1535,7 @@ static BOOL me_sync_contents(IDB_ITEM *pidb, uint64_t folder_id) try
15331535
auto cl_0 = make_scope_exit([&]() { exmdb_client::unload_table(dir, table_id); });
15341536
static constexpr uint32_t proptags_0[] = {
15351537
PidTagMid, PR_MESSAGE_FLAGS, PR_LAST_MODIFICATION_TIME,
1536-
PR_MESSAGE_DELIVERY_TIME, PidTagMidString,
1538+
PR_MESSAGE_DELIVERY_TIME, PidTagMidString, PR_FLAG_STATUS,
15371539
};
15381540
static constexpr PROPTAG_ARRAY proptags_1 = {std::size(proptags_0), deconst(proptags_0)};
15391541
if (!exmdb_client::query_table(dir, nullptr, CP_ACP, table_id,
@@ -1554,10 +1556,10 @@ static BOOL me_sync_contents(IDB_ITEM *pidb, uint64_t folder_id) try
15541556

15551557
syncmessage_list syncmessagelist;
15561558
for (size_t i = 0; i < rows.count; ++i) {
1557-
auto num = rows.pparray[i]->get<const uint64_t>(PidTagMid);
1558-
if (num == nullptr)
1559+
auto lnum = rows.pparray[i]->get<const uint64_t>(PidTagMid);
1560+
if (lnum == nullptr)
15591561
continue;
1560-
auto message_id = rop_util_get_gc_value(*num);
1562+
auto message_id = rop_util_get_gc_value(*lnum);
15611563
auto flags = rows.pparray[i]->get<uint32_t>(PR_MESSAGE_FLAGS);
15621564
if (flags == nullptr)
15631565
continue;
@@ -1566,10 +1568,12 @@ static BOOL me_sync_contents(IDB_ITEM *pidb, uint64_t folder_id) try
15661568
auto mod_time = rows.pparray[i]->get<uint64_t>(PR_LAST_MODIFICATION_TIME);
15671569
auto recv_time = rows.pparray[i]->get<uint64_t>(PR_MESSAGE_DELIVERY_TIME);
15681570
auto midstr = rows.pparray[i]->get<const char>(PidTagMidString);
1571+
auto num = rows.pparray[i]->get<const uint32_t>(PR_FLAG_STATUS);
1572+
bool flagged = num != nullptr && *num == followupFlagged;
15691573
syncmessagelist.emplace(message_id, syncmessage_entry{
15701574
mod_time != nullptr ? *mod_time : 0,
15711575
recv_time != nullptr ? *recv_time : 0,
1572-
*flags, znul(midstr)
1576+
*flags, znul(midstr), flagged
15731577
});
15741578
}
15751579

@@ -1580,8 +1584,8 @@ static BOOL me_sync_contents(IDB_ITEM *pidb, uint64_t folder_id) try
15801584
return FALSE;
15811585
snprintf(sql_string, std::size(sql_string), "INSERT INTO messages (message_id, "
15821586
"folder_id, mid_string, mod_time, uid, unsent, read, subject,"
1583-
" sender, rcpt, size, received) VALUES (?, %llu, ?, ?, ?, ?, "
1584-
"?, ?, ?, ?, ?, ?)", LLU{folder_id});
1587+
" sender, rcpt, size, received, flagged) VALUES (?, %llu, ?, ?, ?, ?, "
1588+
"?, ?, ?, ?, ?, ?, ?)", LLU{folder_id});
15851589
auto stm_insert_msg = gx_sql_prep(pidb->psqlite, sql_string);
15861590
if (stm_insert_msg == nullptr)
15871591
return FALSE;
@@ -3130,9 +3134,20 @@ static int me_psflg(int argc, char **argv, int sockd)
31303134
}
31313135
}
31323136
if (strchr(argv[4], midb_flag::flagged) != nullptr) {
3137+
static constexpr uint32_t val = followupFlagged, icon = olRedFlagIcon;
3138+
static constexpr TAGGED_PROPVAL tp[] = {
3139+
{PR_FLAG_STATUS, deconst(&val)},
3140+
{PR_FOLLOWUP_ICON, deconst(&icon)},
3141+
};
3142+
static constexpr TPROPVAL_ARRAY ta = {std::size(tp), deconst(tp)};
3143+
if (!exmdb_client::set_message_properties(argv[1],
3144+
nullptr, CP_ACP, rop_util_make_eid_ex(1, message_id),
3145+
&ta, &problems))
3146+
return MIDB_E_MDB_SETMSGPROPS;
31333147
snprintf(sql_string, std::size(sql_string), "UPDATE messages SET flagged=1"
31343148
" WHERE message_id=%llu", LLU{message_id});
31353149
gx_sql_exec(pidb->psqlite, sql_string);
3150+
/* The backnotification (msg_modified) comes a bit too late for comfort */
31363151
}
31373152
if (strchr(argv[4], midb_flag::forwarded) != nullptr) {
31383153
snprintf(sql_string, std::size(sql_string), "UPDATE messages SET forwarded=1"
@@ -3212,6 +3227,13 @@ static int me_prflg(int argc, char **argv, int sockd)
32123227
}
32133228
}
32143229
if (strchr(argv[4], midb_flag::flagged) != nullptr) {
3230+
static constexpr proptag_t tags[] = {
3231+
PR_FLAG_STATUS, PR_FOLLOWUP_ICON, PR_TODO_ITEM_FLAGS,
3232+
};
3233+
static constexpr PROPTAG_ARRAY ta = {std::size(tags), deconst(tags)};
3234+
if (!exmdb_client::remove_message_properties(argv[1], CP_ACP,
3235+
rop_util_make_eid_ex(1, message_id), &ta))
3236+
return MIDB_E_MDB_SETMSGPROPS;
32153237
snprintf(sql_string, std::size(sql_string), "UPDATE messages SET flagged=0"
32163238
" WHERE message_id=%llu", LLU{message_id});
32173239
gx_sql_exec(pidb->psqlite, sql_string);
@@ -3509,7 +3531,7 @@ static void notif_msg_added(IDB_ITEM *pidb,
35093531
{
35103532
static constexpr proptag_t tmp_proptags[] =
35113533
{PR_MESSAGE_DELIVERY_TIME, PR_LAST_MODIFICATION_TIME,
3512-
PidTagMidString, PR_MESSAGE_FLAGS};
3534+
PidTagMidString, PR_MESSAGE_FLAGS, PR_FLAG_STATUS};
35133535
static constexpr PROPTAG_ARRAY proptags = {std::size(tmp_proptags), deconst(tmp_proptags)};
35143536
TPROPVAL_ARRAY propvals;
35153537
if (!exmdb_client::get_message_properties(cu_get_maildir(),
@@ -3523,6 +3545,8 @@ static void notif_msg_added(IDB_ITEM *pidb,
35233545
auto received_time = lnum != nullptr ? *lnum : 0;
35243546
auto num = propvals.get<const uint32_t>(PR_MESSAGE_FLAGS);
35253547
auto message_flags = num != nullptr ? *num : 0;
3548+
num = propvals.get<const uint32_t>(PR_FLAG_STATUS);
3549+
bool b_flagged = num != nullptr && *num == followupFlagged;
35263550

35273551
std::string flags_buff;
35283552
char mid_string[128];
@@ -3559,13 +3583,14 @@ static void notif_msg_added(IDB_ITEM *pidb,
35593583
return;
35603584
qstr = fmt::format("INSERT INTO messages ("
35613585
"message_id, folder_id, mid_string, mod_time, uid, "
3562-
"unsent, read, subject, sender, rcpt, size, received)"
3563-
" VALUES (?, {}, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", folder_id);
3586+
"unsent, read, subject, sender, rcpt, size, received, flagged)"
3587+
" VALUES (?, {}, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", folder_id);
35643588
pstmt = gx_sql_prep(pidb->psqlite, qstr.c_str());
35653589
if (pstmt == nullptr)
35663590
return;
35673591
me_insert_message(pstmt, &uidnext, message_id,
3568-
syncmessage_entry{mod_time, received_time, message_flags, str});
3592+
syncmessage_entry{mod_time, received_time, message_flags,
3593+
str, b_flagged});
35693594
pstmt.finalize();
35703595
if (flags_buff.find(midb_flag::flagged) != flags_buff.npos) {
35713596
qstr = fmt::format("UPDATE messages SET "
@@ -3828,21 +3853,26 @@ static void notif_msg_modified(IDB_ITEM *pidb,
38283853
uint64_t folder_id, uint64_t message_id) try
38293854
{
38303855
TPROPVAL_ARRAY propvals;
3831-
static constexpr proptag_t tmp_proptags[] = {PR_MESSAGE_FLAGS, PR_LAST_MODIFICATION_TIME, PidTagMidString};
3856+
static constexpr proptag_t tmp_proptags[] = {
3857+
PR_MESSAGE_FLAGS, PR_LAST_MODIFICATION_TIME, PidTagMidString,
3858+
PR_FLAG_STATUS,
3859+
};
38323860
static constexpr PROPTAG_ARRAY proptags = {std::size(tmp_proptags), deconst(tmp_proptags)};
38333861
if (!exmdb_client::get_message_properties(cu_get_maildir(),
38343862
nullptr, CP_ACP, rop_util_make_eid_ex(1, message_id),
38353863
&proptags, &propvals))
38363864
return;
38373865
auto num = propvals.get<const uint32_t>(PR_MESSAGE_FLAGS);
38383866
auto message_flags = num != nullptr ? *num : 0;
3867+
num = propvals.get<const uint32_t>(PR_FLAG_STATUS);
3868+
bool b_flagged = num != nullptr && *num == followupFlagged;
38393869
auto str = propvals.get<const char>(PidTagMidString);
38403870
if (str != nullptr) {
38413871
UPDATE_MESSAGE_FLAGS:
38423872
auto b_unsent = !!(message_flags & MSGFLAG_UNSENT);
38433873
auto b_read = !!(message_flags & MSGFLAG_READ);
3844-
auto qstr = fmt::format("UPDATE messages SET read={}, unsent={}"
3845-
" WHERE message_id={}", b_read, b_unsent, message_id);
3874+
auto qstr = fmt::format("UPDATE messages SET read={}, unsent={}, flagged={}"
3875+
" WHERE message_id={}", b_read, b_unsent, b_flagged, message_id);
38463876
gx_sql_exec(pidb->psqlite, qstr.c_str());
38473877
return;
38483878
}

include/gromox/mapidefs.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,16 @@ enum { /* for PR_FLAG_STATUS */
308308
followupFlagged = 0x2U,
309309
};
310310

311+
enum { /* for PR_FOLLOWUP_ICON */
312+
olNoFlagIcon = 0,
313+
olPurpleFlagIcon,
314+
olOrangeFlagIcon,
315+
olGreenFlagIcon,
316+
olYellowFlagIcon,
317+
olBlueFlagIcon,
318+
olRedFlagIcon,
319+
};
320+
311321
enum mapi_importance {
312322
IMPORTANCE_LOW = 0,
313323
IMPORTANCE_NORMAL = 1,

include/gromox/mapitags.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ enum {
355355
// PR_LAST_VERB_EXECUTION_TIME = PROP_TAG(PT_SYSTIME, 0x1082), /* PidTagLastVerbExecutionTime */
356356
PR_FLAG_STATUS = PROP_TAG(PT_LONG, 0x1090), /* PidTagFlagStatus */
357357
PR_FLAG_COMPLETE_TIME = PROP_TAG(PT_SYSTIME, 0x1091), /* PidTagFlagCompleteTime */
358-
// PR_FOLLOWUP_ICON = PROP_TAG(PT_LONG, 0x1095), /* PidTagFollowupIcon */
358+
PR_FOLLOWUP_ICON = PROP_TAG(PT_LONG, 0x1095), /* PidTagFollowupIcon */
359359
// PR_BLOCK_STATUS = PROP_TAG(PT_LONG, 0x1096), /* PidTagBlockStatus */
360360
// PR_ITEM_TMPFLAGS = PROP_TAG(PT_LONG, 0x1097), /* PidTagItemTemporaryflags */
361361
// PR_CONFLICT_ITEMS = PROP_TAG(PT_MV_BINARY, 0x1098), /* PidTagConflictItems */

lib/exmdb_client.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,9 @@ static remote_conn_ref exmdb_client_get_connection(const char *dir)
466466
[&](const remote_svr &s) { return strncmp(dir, s.prefix.c_str(), s.prefix.size()) == 0; });
467467
if (i == mdcl_server_list.end()) {
468468
mlog(LV_ERR, "exmdb_client: cannot find remote server for %s", dir);
469+
volatile bool y = 1;
470+
while (y)
471+
;
469472
return fc;
470473
}
471474
while (i->conn_list.size() > 0) {

0 commit comments

Comments
 (0)