Skip to content

Commit c4d30fc

Browse files
committed
oxm2mt: add option to extract just an attachment embedded message
1 parent ac9ecd5 commit c4d30fc

File tree

4 files changed

+33
-1
lines changed

4 files changed

+33
-1
lines changed

doc/gromox-oxm2mt.8

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ the gromox-mt2exm(8gx) program. Optionally, oxm2mt can print a tree summary of
1010
the message.
1111
.SH Options
1212
.TP
13+
\fB\-\-decap\fP=\fIn\fP
14+
Select attachment number \fIn\fP's embedded message as the "top-level" message
15+
and discard the rest of the outer message. \fIn\fP is 1-based.
16+
.TP
1317
\fB\-p\fP
1418
Show properties in detail (enhances \fB\-t\fP).
1519
.TP

tools/genimport.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,3 +659,20 @@ void gi_shutdown()
659659
exmdb_client.reset();
660660
service_release("rules_execute", "system");
661661
}
662+
663+
/**
664+
* @idx: zero-based index for selecting attachment
665+
*/
666+
errno_t gi_decapsulate_attachment(message_content_ptr &ctnt, unsigned int idx)
667+
{
668+
auto &atxlist = *ctnt->children.pattachments;
669+
if (idx >= atxlist.count || atxlist.pplist[idx])
670+
return ENOENT;
671+
auto &ebptr = atxlist.pplist[idx]->pembedded;
672+
if (ebptr == nullptr)
673+
return ENOENT;
674+
auto embed = std::move(ebptr);
675+
ebptr = nullptr;
676+
ctnt.reset(embed);
677+
return 0;
678+
}

tools/genimport.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,4 @@ extern int gi_setup_from_dir(const char *);
109109
extern int gi_startup_client(unsigned int maxconn = 1);
110110
extern eid_t gi_lookup_eid_by_name(const char *dir, const char *name);
111111
extern void gi_shutdown();
112+
extern gromox::errno_t gi_decapsulate_attachment(message_content_ptr &, unsigned int);

tools/oxm2mt.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: AGPL-3.0-or-later
2-
// SPDX-FileCopyrightText: 2022-2024 grommunio GmbH
2+
// SPDX-FileCopyrightText: 2022-2025 grommunio GmbH
33
// This file is part of Gromox.
44
#include <cstdint>
55
#include <cstdio>
@@ -58,9 +58,12 @@ using bin_ptr = std::unique_ptr<BINARY, bin_del>;
5858

5959
}
6060

61+
static unsigned int g_attach_decap;
62+
6163
static constexpr HXoption g_options_table[] = {
6264
{nullptr, 'p', HXTYPE_NONE | HXOPT_INC, &g_show_props, nullptr, nullptr, 0, "Show properties in detail (if -t)"},
6365
{nullptr, 't', HXTYPE_NONE, &g_show_tree, nullptr, nullptr, 0, "Show tree-based analysis of the archive"},
66+
{"decap", 0, HXTYPE_UINT, &g_attach_decap, {}, {}, {}, "Decapsulate embedded message (1-based index)", "IDX"},
6467
HXOPT_AUTOHELP,
6568
HXOPT_TABLEEND,
6669
};
@@ -562,6 +565,13 @@ static errno_t do_file(const char *filename) try
562565
auto ret = do_message(root.get(), *ctnt, MAPI_FOLDER);
563566
if (ret != 0)
564567
return ret;
568+
if (g_attach_decap > 0) {
569+
ret = gi_decapsulate_attachment(ctnt, g_attach_decap - 1);
570+
if (ret == ENOENT)
571+
fprintf(stderr, "Attachment #%u is not an embedded message\n", g_attach_decap);
572+
if (ret != 0)
573+
return ret;
574+
}
565575

566576
if (HXio_fullwrite(STDOUT_FILENO, "GXMT0003", 8) < 0)
567577
throw YError("PG-1014: %s", strerror(errno));

0 commit comments

Comments
 (0)