1818#include < unordered_map>
1919#include < utility>
2020#include < vector>
21+ #include < fmt/format.h>
22+ #include < json/value.h>
2123#include < libHX/endian.h>
2224#include < libHX/io.h>
2325#include < libHX/scope.hpp>
2729#include < gromox/exmdb_rpc.hpp>
2830#include < gromox/ext_buffer.hpp>
2931#include < gromox/fileio.h>
32+ #include < gromox/json.hpp>
3033#include < gromox/list_file.hpp>
3134#include < gromox/mapidefs.h>
3235#include < gromox/paths.h>
@@ -309,9 +312,9 @@ int exm_permissions(eid_t fid, const std::vector<PERMISSION_DATA> &perms)
309312 return 0 ;
310313}
311314
312- int exm_deliver_msg (const char *target, MESSAGE_CONTENT *ct, unsigned int mode)
315+ int exm_deliver_msg (const char *target, MESSAGE_CONTENT *ct,
316+ const std::string &im_repr, Json::Value &&digest, unsigned int mode)
313317{
314- ct->proplist .erase (PidTagChangeNumber);
315318 auto ts = rop_util_current_nttime ();
316319 auto ret = ct->proplist .set (PR_MESSAGE_DELIVERY_TIME, &ts);
317320 if (ret != ecSuccess)
@@ -320,12 +323,31 @@ int exm_deliver_msg(const char *target, MESSAGE_CONTENT *ct, unsigned int mode)
320323 uint32_t r32 = 0 ;
321324 if (mode & DELIVERY_TWOSTEP)
322325 mode &= ~(DELIVERY_DO_RULES | DELIVERY_DO_NOTIF);
326+ uint64_t change_num = 0 ;
327+ if (!exmdb_client->allocate_cn (g_storedir, &change_num)) {
328+ fprintf (stderr, " exm: allocate_cn(msg)[delivery] RPC failed\n " );
329+ return -EIO;
330+ }
331+ auto iret = exm_set_change_keys (&ct->proplist , change_num);
332+ if (iret != 0 ) {
333+ fprintf (stderr, " exm: tpropval: %s\n " , strerror (-iret));
334+ return iret;
335+ }
336+ auto midstr = fmt::format (" {}.cn{}" , time (nullptr ), rop_util_get_gc_value (change_num));
337+ digest[" file" ] = midstr;
338+ if (!exmdb_client->imapfile_write (g_storedir, " eml" ,
339+ midstr.c_str (), im_repr.c_str ())) {
340+ fprintf (stderr, " exm: imapfile_write RPC failed\n " );
341+ return -EIO;
342+ }
343+ auto djson = json_to_str (digest);
323344 if (!exmdb_client->deliver_message (g_storedir, ENVELOPE_FROM_NULL,
324- target, CP_ACP, mode, ct, " " , &folder_id, &msg_id, &r32)) {
345+ target, CP_ACP, mode, ct, djson. c_str () , &folder_id, &msg_id, &r32)) {
325346 fprintf (stderr, " exm: deliver_message RPC failed: code %u\n " ,
326347 r32);
327348 return -EIO;
328349 }
350+
329351 auto dm_status = static_cast <deliver_message_result>(r32);
330352 switch (dm_status) {
331353 case deliver_message_result::result_ok:
@@ -367,7 +389,8 @@ int exm_deliver_msg(const char *target, MESSAGE_CONTENT *ct, unsigned int mode)
367389 return EXIT_SUCCESS;
368390}
369391
370- int exm_create_msg (uint64_t parent_fld, MESSAGE_CONTENT *ctnt)
392+ int exm_create_msg (uint64_t parent_fld, MESSAGE_CONTENT *ctnt,
393+ const std::string &im_repr, Json::Value &&digest)
371394{
372395 uint64_t msg_id = 0 , change_num = 0 ;
373396 if (!exmdb_client->allocate_message_id (g_storedir, parent_fld, &msg_id)) {
@@ -387,10 +410,18 @@ int exm_create_msg(uint64_t parent_fld, MESSAGE_CONTENT *ctnt)
387410 fprintf (stderr, " exm: tpropval: %s\n " , strerror (-iret));
388411 return iret;
389412 }
413+ auto midstr = fmt::format (" {}.cn{}" , time (nullptr ), rop_util_get_gc_value (change_num));
414+ digest[" file" ] = midstr;
415+ if (!exmdb_client->imapfile_write (g_storedir, " eml" ,
416+ midstr.c_str (), im_repr.c_str ())) {
417+ fprintf (stderr, " exm: imapfile_write RPC failed\n " );
418+ return -EIO;
419+ }
420+ auto djson = json_to_str (digest);
390421
391422 uint64_t outmid = 0 , outcn = 0 ;
392423 if (!exmdb_client->write_message (g_storedir, CP_UTF8, parent_fld,
393- ctnt, {} , &outmid, &outcn, &ret)) {
424+ ctnt, djson. c_str () , &outmid, &outcn, &ret)) {
394425 fprintf (stderr, " exm: write_message RPC failed\n " );
395426 return -EIO;
396427 } else if (ret != ecSuccess) {
0 commit comments