Skip to content

Commit dde284b

Browse files
committed
mbop: multi-action support
1 parent 470cc9a commit dde284b

File tree

2 files changed

+53
-6
lines changed

2 files changed

+53
-6
lines changed

doc/gromox-mbop.8

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ store of a domain, leave out the local part, i.e. use
2121
\fB@\fP\fIexample.com\fP.)
2222
.SH Commands
2323
.IP \(bu 4
24+
\fB(\fP command1 c1args \fB) (\fP command2 c2args \fB)\fP: command
25+
concatenation
26+
.IP \(bu 4
2427
clear\-photo: delete user picture
2528
.IP \(bu 4
2629
clear\-profile: delete user's PHP-MAPI profile
@@ -182,6 +185,10 @@ external tools like parallel(1) or make(1) for guaranteed parallelization.
182185
Default: \fI1\fP
183186
.SS Description
184187
Pseudoaction for running one of the other subcommand (e.g. ping, unload.)
188+
.SS Examples
189+
.IP \(bu 4
190+
Command concatenation: gromox\-mbop for\-all\-users \\( purge\-softdelete -r /
191+
\\) \\( purge\-datafiles \\)
185192
.SH get\-freebusy
186193
.SS Synopsis
187194
\fBget\-freebusy\fP [\fB\-a\fP \fIstart_time\fP] [\fB\-b\fP \fIend_time\fP]

tools/mbop_main.cpp

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ static constexpr HXoption g_options_table[] = {
544544
HXOPT_TABLEEND,
545545
};
546546

547-
static int main2(int, char **);
547+
static int cmd_parser(int, char **);
548548

549549
static void command_overview()
550550
{
@@ -735,11 +735,11 @@ static int main(int argc, char **argv)
735735
}
736736
} else {
737737
for (auto &&[username, maildir] : ul) {
738-
// main2 is not thread-safe (global state), can't parallelize
738+
/* cmd_parser is not thread-safe (global state), cannot parallelize */
739739
g_dstuser = std::move(username);
740740
g_storedir_s = std::move(maildir);
741741
g_storedir = g_storedir_s.c_str();
742-
ret = global::main2(argc, argv);
742+
ret = global::cmd_parser(argc, argv);
743743
if (ret == EXIT_PARAM)
744744
return ret;
745745
else if (ret != EXIT_SUCCESS && !global::g_continuous_mode)
@@ -964,7 +964,7 @@ static int single_user_wrap(int argc, char **argv)
964964

965965
auto ret = gi_startup_client();
966966
if (ret == EXIT_SUCCESS)
967-
ret = main2(argc, argv);
967+
ret = cmd_parser(argc, argv);
968968
gi_shutdown();
969969
return ret;
970970
}
@@ -988,9 +988,49 @@ int main(int argc, char **argv)
988988

989989
namespace global {
990990

991-
static int main2(int argc, char **argv)
991+
static int parens_parser(int argc, char **argv)
992992
{
993-
if (strcmp(argv[0], "delmsg") == 0)
993+
unsigned int qcount = 0;
994+
int start = 0;
995+
996+
for (int scanpos = 0; scanpos < argc; ++scanpos) {
997+
if (strcmp(argv[scanpos], "(") == 0) {
998+
++qcount;
999+
if (start == 0)
1000+
start = scanpos + 1;
1001+
} else if (strcmp(argv[scanpos], ")") == 0) {
1002+
if (qcount == 0) {
1003+
fprintf(stderr, "Unbalanced parenthesis\n");
1004+
return EXIT_FAILURE;
1005+
}
1006+
--qcount;
1007+
if (qcount == 0) {
1008+
std::vector<char *> args(&argv[start], &argv[scanpos]);
1009+
args.push_back(nullptr);
1010+
auto ret = cmd_parser(std::min(static_cast<size_t>(INT_MAX), args.size() - 1), &args[0]);
1011+
if (ret != EXIT_SUCCESS && !g_continuous_mode)
1012+
return ret;
1013+
start = 0;
1014+
}
1015+
} else if (qcount == 0) {
1016+
fprintf(stderr, "Expected parenthesis; got \"%s\"\n", argv[scanpos]);
1017+
return EXIT_FAILURE;
1018+
}
1019+
}
1020+
if (qcount != 0) {
1021+
fprintf(stderr, "Unbalanced parenthesis\n");
1022+
return EXIT_FAILURE;
1023+
}
1024+
return EXIT_SUCCESS;
1025+
}
1026+
1027+
static int cmd_parser(int argc, char **argv)
1028+
{
1029+
if (argc == 0)
1030+
return EXIT_FAILURE;
1031+
if (strcmp(argv[0], "(") == 0)
1032+
return parens_parser(argc, argv);
1033+
else if (strcmp(argv[0], "delmsg") == 0)
9941034
return delmsg::main(argc, argv);
9951035
else if (strcmp(argv[0], "emptyfld") == 0)
9961036
return emptyfld::main(argc, argv);

0 commit comments

Comments
 (0)