Skip to content

Commit 8886fd4

Browse files
committed
exmdb: add write_message_v3 EXRPC
The deliver_message RPC has a "digest" parameter with which a process (gromox-delivery) can indicate to the Information Store (exmdb) that an RFC5322 Internet Mail file is logically linked to a newly-created MAPI message. The write_message RPC is the "not delivery, just placement" companion function, which is used by the import tools. Having a digest parameter is equally valuable. This commit adds the parameter and its handling. References: GXH-155, GXF-2229
1 parent 5f8dbb8 commit 8886fd4

File tree

13 files changed

+73
-52
lines changed

13 files changed

+73
-52
lines changed

exch/emsmdb/fastupctx_object.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,10 @@ fastupctx_object_write_message(fastupctx_object *pctx, uint64_t folder_id)
213213
return err;
214214
auto pinfo = emsmdb_interface_get_emsmdb_info();
215215
ec_error_t e_result = ecRpcFailed;
216+
uint64_t outmid = 0, outcn = 0;
216217
if (!exmdb_client->write_message(dir, pinfo->cpid, folder_id,
217-
pctx->m_content, &e_result) || e_result != ecSuccess)
218+
pctx->m_content, {}, &outmid, &outcn, &e_result) ||
219+
e_result != ecSuccess)
218220
return e_result;
219221
return ecSuccess;
220222
}

exch/ews/context.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,8 +499,11 @@ sItem EWSContext::create(const std::string& dir, const sFolderSpec& parent, cons
499499
auto messageId = content.proplist.get<const uint64_t>(PidTagMid);
500500
if (!messageId)
501501
throw DispatchError(E3112);
502+
if (!content.proplist.has(PidTagChangeNumber))
503+
throw EWSError::ItemSave(E3254);
504+
uint64_t outmid = 0, outcn = 0;
502505
if (!m_plugin.exmdb.write_message(dir.c_str(), CP_ACP, parent.folderId,
503-
&content, &error) || error != ecSuccess)
506+
&content, {}, &outmid, &outcn, &error) || error != ecSuccess)
504507
throw EWSError::ItemSave(E3254);
505508

506509
sShape retshape = sShape(tItemResponseShape());

exch/ews/requests.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1644,9 +1644,12 @@ void process(mUpdateItemRequest&& request, XMLElement* response, const EWSContex
16441644
auto error = content->proplist.set(PidTagMid, EWSContext::construct<uint64_t>(rop_util_make_eid(1, mid.message_global_counter)));
16451645
if (error == ecServerOOM)
16461646
throw EWSError::ItemSave(E3035);
1647+
if (!content->proplist.has(PidTagChangeNumber))
1648+
throw EWSError::ItemSave(E3255);
1649+
uint64_t outmid = 0, outcn = 0;
16471650
if (!ctx.plugin().exmdb.write_message(dir.c_str(),
1648-
CP_ACP, parentFolder.folderId, content.get(),
1649-
&error) || error != ecSuccess)
1651+
CP_ACP, parentFolder.folderId, content.get(), {},
1652+
&outmid, &outcn, &error) || error != ecSuccess)
16501653
throw EWSError::ItemSave(E3255);
16511654
} else {
16521655
TPROPVAL_ARRAY props = shape.write();

exch/exmdb/instance.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,8 +1513,9 @@ BOOL exmdb_server::flush_instance(const char *dir, uint32_t instance_id,
15131513
dbase.reset();
15141514
pdb.reset();
15151515
g_inside_flush_instance = true;
1516-
BOOL b_result = exmdb_server::write_message(dir, CP_ACP,
1517-
folder_id, pmsgctnt, pe_result);
1516+
uint64_t outmid = 0, outcn = 0;
1517+
BOOL b_result = exmdb_server::write_message(dir, CP_ACP, folder_id,
1518+
pmsgctnt, {}, &outmid, &outcn, pe_result);
15181519
g_inside_flush_instance = false;
15191520
exmdb_server::set_public_username(nullptr);
15201521
return b_result;

exch/exmdb/message.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3822,8 +3822,9 @@ BOOL exmdb_server::deliver_message(const char *dir, const char *from_address,
38223822
* replaced.
38233823
* - If PR_LAST_MODIFICATION_TIME is not present, it will be set to now().
38243824
*/
3825-
BOOL exmdb_server::write_message_v2(const char *dir, cpid_t cpid,
3825+
BOOL exmdb_server::write_message(const char *dir, cpid_t cpid,
38263826
uint64_t folder_id, const MESSAGE_CONTENT *pmsgctnt,
3827+
const std::string &digest_stream,
38273828
uint64_t *outmid, uint64_t *outcn, ec_error_t *pe_result)
38283829
{
38293830
BOOL b_exist = false;
@@ -3868,6 +3869,26 @@ BOOL exmdb_server::write_message_v2(const char *dir, cpid_t cpid,
38683869
return false;
38693870
}
38703871

3872+
if (digest_stream.size() > 0) {
3873+
Json::Value digest;
3874+
std::string mid_string;
3875+
if (json_from_str(digest_stream, digest) &&
3876+
digest["file"].asString().size() > 0) {
3877+
std::string ext_file = exmdb_server::get_dir() + "/ext/"s + digest["file"].asString();
3878+
wrapfd fd = open(ext_file.c_str(), O_CREAT | O_TRUNC | O_WRONLY, FMODE_PRIVATE);
3879+
if (fd.get() >= 0) {
3880+
if (HXio_fullwrite(fd.get(), digest_stream.c_str(), digest_stream.size()) < 0 ||
3881+
fd.close_wr() != 0) {
3882+
mlog(LV_ERR, "E-1319: write %s: %s", ext_file.c_str(), strerror(errno));
3883+
return false;
3884+
}
3885+
if (!common_util_set_mid_string(pdb->psqlite,
3886+
*outmid, digest["file"].asCString()))
3887+
return false;
3888+
}
3889+
}
3890+
}
3891+
38713892
auto dbase = pdb->lock_base_wr();
38723893
db_conn::NOTIFQ notifq;
38733894
if (b_exist) {
@@ -3886,18 +3907,6 @@ BOOL exmdb_server::write_message_v2(const char *dir, cpid_t cpid,
38863907
return TRUE;
38873908
}
38883909

3889-
BOOL exmdb_server::write_message(const char *dir, cpid_t cpid,
3890-
uint64_t folder_id, const MESSAGE_CONTENT *ctnt, ec_error_t *e_result)
3891-
{
3892-
if (!ctnt->proplist.has(PidTagChangeNumber)) {
3893-
*e_result = ecRpcFailed;
3894-
return TRUE;
3895-
}
3896-
uint64_t outmid = 0, outcn = 0;
3897-
return write_message_v2(dir, cpid, folder_id, ctnt,
3898-
&outmid, &outcn, e_result);
3899-
}
3900-
39013910
/**
39023911
* @username: Used for adjusting public store readstates
39033912
*/

exch/exmdb/names.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ static constexpr const char *exmdb_rpc_names[] = {
119119
E(empty_folder_rule),
120120
E(update_folder_rule),
121121
"deliver_message_v1",
122-
E(write_message),
122+
"write_message_v1",
123123
E(read_message),
124124
E(get_content_sync),
125125
E(get_hierarchy_sync),
@@ -150,11 +150,12 @@ static constexpr const char *exmdb_rpc_names[] = {
150150
E(recalc_store_size),
151151
E(movecopy_folder),
152152
E(create_folder),
153-
E(write_message_v2),
153+
"write_message_v2",
154154
E(imapfile_read),
155155
E(imapfile_write),
156156
E(imapfile_delete),
157157
E(cgkreset),
158+
E(write_message),
158159
};
159160
#undef E
160161

@@ -163,7 +164,7 @@ namespace exmdb {
163164
const char *exmdb_rpc_idtoname(exmdb_callid i)
164165
{
165166
auto j = static_cast<uint8_t>(i);
166-
static_assert(std::size(exmdb_rpc_names) == static_cast<uint8_t>(exmdb_callid::cgkreset) + 1);
167+
static_assert(std::size(exmdb_rpc_names) == static_cast<uint8_t>(exmdb_callid::write_message) + 1);
167168
auto s = j < std::size(exmdb_rpc_names) ? exmdb_rpc_names[j] : nullptr;
168169
return znul(s);
169170
}

exch/midb/mail_engine.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2239,9 +2239,10 @@ static int me_minst(int argc, char **argv, int sockd) try
22392239
if (cpid == CP_ACP)
22402240
cpid = static_cast<cpid_t>(1252);
22412241
ec_error_t e_result = ecRpcFailed;
2242+
uint64_t outmid = 0, outcn = 0;
22422243
if (!exmdb_client->write_message(argv[1], cpid,
2243-
rop_util_make_eid_ex(1, folder_id), pmsgctnt, &e_result) ||
2244-
e_result != ecSuccess)
2244+
rop_util_make_eid_ex(1, folder_id), pmsgctnt, {},
2245+
&outmid, &outcn, &e_result) || e_result != ecSuccess)
22452246
return MIDB_E_MDB_WRITEMESSAGE;
22462247
return cmd_write(sockd, "TRUE\r\n");
22472248
} catch (const std::bad_alloc &) {

exch/zcore/common_util.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1502,8 +1502,10 @@ ec_error_t cu_remote_copy_message(store_object *src_store, uint64_t message_id,
15021502
if (err != ecSuccess)
15031503
return err;
15041504
err = ecError;
1505+
uint64_t outmid = 0, outcn = 0;
15051506
if (!exmdb_client->write_message(dst_store->get_dir(), pinfo->cpid,
1506-
folder_id1, pmsgctnt, &err) || err != ecSuccess)
1507+
folder_id1, pmsgctnt, {}, &outmid, &outcn, &err) ||
1508+
err != ecSuccess)
15071509
return err;
15081510
return ecSuccess;
15091511
}

include/gromox/exmdb_idef.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,7 @@ EXMIDL(update_folder_permission, (const char *dir, uint64_t folder_id, BOOL b_fr
117117
EXMIDL(empty_folder_rule, (const char *dir, uint64_t folder_id))
118118
EXMIDL(update_folder_rule, (const char *dir, uint64_t folder_id, uint16_t count, const RULE_DATA *prow, IDLOUT BOOL *b_exceed))
119119
EXMIDL(deliver_message, (const char *dir, const char *from_address, const char *account, cpid_t cpid, uint32_t dlflags, const MESSAGE_CONTENT *pmsg, const char *pdigest, IDLOUT uint64_t *folder_id, uint64_t *message_id, uint32_t *result))
120-
EXMIDL(write_message, (const char *dir, cpid_t cpid, uint64_t folder_id, const MESSAGE_CONTENT *pmsgctnt, IDLOUT ec_error_t *e_result))
121-
EXMIDL(write_message_v2, (const char *dir, cpid_t cpid, uint64_t folder_id, const MESSAGE_CONTENT *pmsgctnt, IDLOUT uint64_t *outmid, uint64_t *outcn, ec_error_t *e_result))
120+
EXMIDL(write_message, (const char *dir, cpid_t cpid, uint64_t folder_id, const MESSAGE_CONTENT *pmsgctnt, const std::string &digest, IDLOUT uint64_t *outmid, uint64_t *outcn, ec_error_t *e_result))
122121
EXMIDL(read_message, (const char *dir, const char *username, cpid_t cpid, uint64_t message_id, IDLOUT MESSAGE_CONTENT **pmsgctnt))
123122
EXMIDL(get_content_sync, (const char *dir, uint64_t folder_id, const char *username, const idset *pgiven, const idset *pseen, const idset *pseen_fai, const idset *pread, cpid_t cpid, const RESTRICTION *prestriction, BOOL b_ordered, IDLOUT uint32_t *fai_count, uint64_t *fai_total, uint32_t *normal_count, uint64_t *normal_total, EID_ARRAY *updated_mids, EID_ARRAY *chg_mids, uint64_t *last_cn, EID_ARRAY *given_mids, EID_ARRAY *deleted_mids, EID_ARRAY *nolonger_mids, EID_ARRAY *read_mids, EID_ARRAY *unread_mids, uint64_t *last_readcn))
124123
EXMIDL(get_hierarchy_sync, (const char *dir, uint64_t folder_id, const char *username, const idset *pgiven, const idset *pseen, IDLOUT FOLDER_CHANGES *fldchgs, uint64_t *last_cn, EID_ARRAY *given_fids, EID_ARRAY *deleted_fids))

include/gromox/exmdb_rpc.hpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ enum class exmdb_callid : uint8_t {
135135
empty_folder_rule = 0x6b,
136136
update_folder_rule = 0x6c,
137137
// deliver_message_v1 = 0x6d,
138-
write_message = 0x6e,
138+
// write_message_v1 = 0x6e,
139139
read_message = 0x6f,
140140
get_content_sync = 0x70,
141141
get_hierarchy_sync = 0x71,
@@ -166,11 +166,12 @@ enum class exmdb_callid : uint8_t {
166166
recalc_store_size = 0x8a,
167167
movecopy_folder = 0x8b,
168168
create_folder = 0x8c,
169-
write_message_v2 = 0x8d,
169+
// write_message_v2 = 0x8d,
170170
imapfile_read = 0x8e,
171171
imapfile_write = 0x8f,
172172
imapfile_delete = 0x90,
173173
cgkreset = 0x91,
174+
write_message /* v3 */ = 0x92,
174175
/* update exch/exmdb/names.cpp:exmdb_rpc_idtoname! */
175176
};
176177

@@ -770,11 +771,11 @@ struct exreq_deliver_message final : public exreq {
770771
};
771772

772773
struct exreq_write_message final : public exreq {
773-
cpid_t cpid;
774-
uint64_t folder_id;
775-
MESSAGE_CONTENT *pmsgctnt;
774+
cpid_t cpid{};
775+
uint64_t folder_id = 0;
776+
MESSAGE_CONTENT *pmsgctnt = nullptr;
777+
std::string digest;
776778
};
777-
using exreq_write_message_v2 = exreq_write_message;
778779

779780
struct exreq_read_message final : public exreq {
780781
char *username;
@@ -1316,7 +1317,7 @@ struct exresp_autoreply_tsquery final : public exresp {
13161317
uint64_t tdiff = 0;
13171318
};
13181319

1319-
struct exresp_write_message_v2 final : public exresp {
1320+
struct exresp_write_message final : public exresp {
13201321
uint64_t outmid = 0, outcn = 0;
13211322
ec_error_t e_result{};
13221323
};
@@ -1367,7 +1368,6 @@ using exresp_purge_datafiles = exresp;
13671368
using exresp_autoreply_tsupdate = exresp;
13681369
using exresp_recalc_store_size = exresp;
13691370
using exresp_flush_instance = exresp_error;
1370-
using exresp_write_message = exresp_error;
13711371
using exresp_movecopy_folder = exresp_error;
13721372
using exresp_imapfile_write = exresp;
13731373
using exresp_imapfile_delete = exresp;

0 commit comments

Comments
 (0)